automatically resync media, and don't send media server already has (#583)

This commit is contained in:
Damien Elmes 2013-05-27 14:25:30 +09:00
parent 1a06402f53
commit 0a81df60dc
2 changed files with 28 additions and 1 deletions

View file

@ -466,3 +466,17 @@ create table log (fname text primary key, type int);
assert not self.db.scalar("select count() from log")
cnt = self.db.scalar("select count() from media")
return cnt
def forceResync(self):
self.db.execute("delete from media")
self.db.execute("delete from log")
self.db.execute("update meta set usn = 0, dirMod = 0")
self.db.commit()
def removeExisting(self, files):
"Remove files from list of files to sync."
# add temporary index
self.db.execute("create index if not exists ix_fname_tmp on log(fname)")
self.db.executemany("delete from log where fname=?", ((f,) for f in files))
self.db.execute("drop index ix_fname_tmp")
self.db.commit()

View file

@ -656,10 +656,17 @@ class MediaSyncer(object):
def sync(self, mediaUsn):
# step 1: check if there have been any changes
runHook("sync", "findMedia")
self.col.media.findChanges()
lusn = self.col.media.usn()
# if first sync or resync, clear list of files we think we've sent
if not lusn:
self.col.media.forceResync()
self.col.media.findChanges()
if lusn == mediaUsn and not self.col.media.hasChanged():
return "noChanges"
# step 1.5: if resyncing, we need to get the list of files the server
# has and remove them from our local list of files to sync
files = self.server.mediaList()
self.col.media.removeExisting(files)
# step 2: send/recv deletions
runHook("sync", "removeMedia")
lrem = self.removed()
@ -691,6 +698,8 @@ class MediaSyncer(object):
s = self.server.mediaSanity()
c = self.mediaSanity()
if c != s:
# if the sanity check failed, force a resync
self.col.media.forceResync()
raise Exception("""\
Media sanity check failed. Please copy and paste the text below:\n%s\n%s""" %
(c, s))
@ -739,6 +748,10 @@ class RemoteMediaServer(HttpSyncer):
return json.loads(
self.req("mediaSanity"))
def mediaList(self):
return json.loads(
self.req("mediaList"))
# only for unit tests
def mediatest(self, n):
return json.loads(