-
Notifications
You must be signed in to change notification settings - Fork 5
/
dbcore.py
217 lines (160 loc) · 6.33 KB
/
dbcore.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine, Column, Integer, String, DateTime, Boolean
import time
engine = create_engine('sqlite:///iqmeta.db', echo=False)
Session = sessionmaker(bind=engine)
Base = declarative_base()
class ActionQueue(object):
def __init__(self, actions=[]):
super(ActionQueue, self).__init__()
self.session = Session()
self.clear()
for action in actions:
self.add(action)
def __len__(self):
return self.session.query(FileAction).count()
def __getitem__(self, key):
return self.session.query(FileAction).all()[key]
def __iter__(self):
return self.session.query(FileAction).__iter__()
def __contains__(self, action):
return session.query(FileAction).filter(path=action.path).count() > 1
def remove(self, action):
self.session.delete(action)
self.session.commit()
def clear(self):
didClear = True
try:
self.session.query(FileAction).delete()
self.session.commit()
except OperationalError:
didClear = False
if not didClear:
print "IO error. Could be from computer suspend, shutdown or hibernate. Waiting 6s to retry."
time.sleep(6)
self.session.query(FileAction).delete()
self.session.commit()
def add(self, action):
# Looking for previous actions over the same path
print 'Adding action: %s' % action
prev_action = self.session.query(FileAction).filter_by(path=action.path).first()
if prev_action is not None:
# If there is an action over the same path, update it
prev_action.action = action.action
prev_action.location = action.location
else:
self.session.add(action)
self.session.commit()
def next(self):
nextaction = self.session.query(FileAction).first()
return nextaction
def __repr__(self):
return self.session.query(FileAction).all().__repr__()
class FileAction(Base):
__tablename__ = 'actions'
id = Column(Integer, primary_key=True)
path = Column(String)
action = Column(String)
location = Column(String)
UPLOAD = 'upload'
DOWNLOAD = 'download'
DELETE = 'delete'
SERVER = 'server'
LOCAL = 'local'
def __init__(self, path, action, location):
self.path = path
self.action = action
self.location = location
def __repr__(self):
return '<FileAction in %s ("%s" "%s" to "%s")>' % (
self.__tablename__, self.action, self.path, self.location)
class File(Base):
__tablename__ = 'files'
id = Column(Integer, primary_key=True)
path = Column(String, unique=True)
localmdate = Column(DateTime)
servermdate = Column(DateTime)
last_checked_local = Column(DateTime)
last_checked_server = Column(DateTime)
inserver = Column(Boolean)
inlocal = Column(Boolean)
def __init__(
self, path='', localmdate=None, servermdate=None,
last_checked_local=None, last_checked_server=None,
inserver=False, inlocal=False):
self.path = path
self.localmdate = localmdate
self.servermdate = servermdate
self.last_checked_local = last_checked_local
self.last_checked_server = last_checked_server
self.inserver = inserver
self.inlocal = inlocal
def __repr__(self):
return '<File in %s ("%s", Local: "%s", Server: "%s")>' % (
self.__tablename__, self.path, self.inlocal, self.inserver)
def __enter__(self):
return self
def __exit__(self, *args):
self.session.commit()
def timeDiff(self):
return (self.localmdate - self.servermdate).total_seconds()
@classmethod
def fromPath(cls, path):
"""
Returns a `File` instance by fetching it from the database
using the `path` parameter, if such entry doesn't exist, this
function adds it to the database and returns the added instance.
:param path: `path` attribute of the `File` instance that will be fetched.
"""
session = Session()
try:
newfile = session.query(cls).filter_by(path=path).one()
newfile.session = session
return newfile
except MultipleResultsFound:
print 'More than one result for "%s", database might be corrupted' % path
return None
except NoResultFound:
newfile = File(path)
session.add(newfile)
newfile.session = session
return newfile
def empty_db():
session = Session()
return session.query(File).count() == 0
Base.metadata.create_all(engine)
if __name__ == '__main__':
session = Session()
action_queue = ActionQueue()
action = FileAction('/some/path', FileAction.UPLOAD, FileAction.SERVER)
action_queue.add(action)
print action_queue
print action_queue[0]
print action_queue.next()
for action_ in action_queue:
print action_
print session.query(File).filter(File.inserver != File.inlocal).all()
action_queue.clear()
print 'Actions', len(action_queue)
for action_ in action_queue:
print 'Deleted', action_
session.commit()
raise SystemExit()
localfile = File.fromPath('Public/Something')
print localfile.inserver
localfile.inserver = True
myfile = File.fromPath('Public/New')
print myfile.last_checked_local, myfile.last_checked_server, myfile.inlocal, myfile.inserver
serverfile = File.fromPath('Public/Something/Else')
print serverfile.inlocal
serverfile.inlocal = True
otherfile = File.fromPath('Public/Other/File')
print otherfile
otherfile.inlocal = True
otherfile.inserver = True
print otherfile.inlocal, otherfile.inserver
for file_ in session.query(File):
print file_
print dir(session.query())