diff --git a/anki/sync.py b/anki/sync.py index df46ee761..ddcdada73 100644 --- a/anki/sync.py +++ b/anki/sync.py @@ -98,8 +98,11 @@ class SyncTools(object): "Sync two decks locally. Reimplement this for finer control." if not self.prepareSync(0): return - sums = self.summaries() - payload = self.genPayload(sums) + lsum = self.summary(self.deck.lastSync) + rsum = self.server.summary(self.deck.lastSync) + if not lsum or not rsum: + raise Exception("full sync required") + payload = self.genPayload((lsum, rsum)) res = self.server.applyPayload(payload) self.applyPayloadReply(res) self.deck.reset() @@ -111,15 +114,11 @@ class SyncTools(object): if self.localTime == self.remoteTime: return False l = self._lastSync(); r = self.server._lastSync() - # set lastSync to the lower of the two sides, and account for slow - # clocks & assume it took up to 10 seconds for the reply to arrive - self.deck.lastSync = min(l, r) - timediff - 10 + # set lastSync to the lower of the two sides, account for slow clocks, + # and assume it took up to 10 seconds for the reply to arrive + self.deck.lastSync = max(0, min(l, r) - timediff - 10) return True - def summaries(self): - return (self.summary(self.deck.lastSync), - self.server.summary(self.deck.lastSync)) - def genPayload(self, summaries): (lsum, rsum) = summaries self.preSyncRefresh() @@ -219,10 +218,11 @@ class SyncTools(object): def summary(self, lastSync): "Generate a full summary of modtimes for two-way syncing." - # client may have selected an earlier sync time + # if client may have selected an earlier sync time self.deck.lastSync = lastSync - # ensure we're flushed first - self.deck.s.flush() + # return early if there's been a schema change + if self.deck.getFloat("schemaMod") > lastSync: + return None return { # cards "cards": self.realLists(self.deck.s.all( diff --git a/tests/test_sync.py b/tests/test_sync.py index e852a71e9..3ed501b8f 100644 --- a/tests/test_sync.py +++ b/tests/test_sync.py @@ -133,7 +133,7 @@ def test_localsync_models(): assert deck1.currentModel.cardModels[1].active == True deck2.currentModel.cardModels[1].active = False deck2.currentModel.setModified() - deck2.setModified() + deck2.flushMod() client.sync() assert deck1.currentModel.cardModels[1].active == False # remove a card model @@ -144,25 +144,8 @@ def test_localsync_models(): assert len(deck1.currentModel.cardModels) == 1 client.sync() assert len(deck2.currentModel.cardModels) == 1 - # add a field - c = deck1.getCard() - deck1.addFieldModel(c.fact.model, FieldModel(u"yo")) - deck1.s.refresh(c.fact) - assert len(c.fact.fields) == 3 - assert c.fact['yo'] == u"" - client.sync() - c2 = deck2.s.query(Card).get(c.id) - deck2.s.refresh(c2.fact) - assert c2.fact['yo'] == u"" - # remove the field - assert "yo" in c2.fact.keys() - deck2.deleteFieldModel(c2.fact.model, c2.fact.model.fieldModels[2]) - deck2.s.refresh(c2.fact) - assert "yo" not in c2.fact.keys() - client.sync() - deck1.s.refresh(c.fact) - assert "yo" not in c.fact.keys() # rename a field + c = deck1.getCard() assert u"Front" in c.fact.keys() deck1.renameFieldModel(deck1.currentModel, deck1.currentModel.fieldModels[0], @@ -257,28 +240,6 @@ def test_localsync_media(): assert deck1.s.scalar("select count(1) from media") == 3 assert deck2.s.scalar("select count(1) from media") == 3 -# One way syncing -########################################################################## - -@nose.with_setup(setup_local, teardown) -def test_oneway_simple(): - assert deck1.s.scalar("select count(1) from cards") == 2 - assert deck2.s.scalar("select count(1) from cards") == 2 - assert deck1.cardCount == 2 - assert deck2.cardCount == 2 - assert deck1.s.scalar("select id from tags where tag = 'foo'") - assert not deck1.s.scalar("select id from tags where tag = 'bar'") - server.deckName = "dummy" - client.syncOneWay(0) - assert deck1.s.scalar("select count(1) from cards") == 4 - assert deck2.s.scalar("select count(1) from cards") == 2 - assert deck1.cardCount == 4 - assert deck2.cardCount == 2 - assert deck1.s.scalar("select id from tags where tag = 'foo'") - assert deck1.s.scalar("select id from tags where tag = 'bar'") - # should be a noop - client.syncOneWay(0) - # Remote tests ##########################################################################