6
6
import os, types, socket, time, traceback
9
from anki.sync import SyncClient, HttpSyncServerProxy, BulkMediaSyncerProxy
10
from anki.sync import BulkMediaSyncer
9
from anki.sync import SyncClient, HttpSyncServerProxy, copyLocalMedia
10
from anki.sync import SYNC_HOST, SYNC_PORT
11
11
from anki.errors import *
12
12
from anki import DeckStorage
13
13
import ankiqt.forms
14
from anki.hooks import addHook, removeHook
15
16
# Synchronising a deck with a public server
16
17
##########################################################################
29
30
self.onlyMerge = onlyMerge
30
31
self.sourcesToCheck = sourcesToCheck
32
addHook('fullSyncStarted', self.fullSyncStarted)
33
addHook('fullSyncFinished', self.fullSyncFinished)
34
addHook('fullSyncProgress', self.fullSyncProgress)
32
36
def setStatus(self, msg, timeout=5000):
33
37
self.emit(SIGNAL("setStatus"), msg, timeout)
41
removeHook('fullSyncStarted', self.fullSyncStarted)
42
removeHook('fullSyncFinished', self.fullSyncFinished)
43
removeHook('fullSyncProgress', self.fullSyncProgress)
45
def fullSyncStarted(self, max):
46
self.emit(SIGNAL("fullSyncStarted"), max)
48
def fullSyncFinished(self):
49
self.emit(SIGNAL("fullSyncFinished"))
51
def fullSyncProgress(self, type, val):
52
self.emit(SIGNAL("fullSyncProgress"), type, val)
38
54
def error(self, error):
55
if getattr(error, 'data', None) is None:
39
57
if error.data.get('type') == 'noResponse':
40
58
self.emit(SIGNAL("noSyncResponse"))
50
68
def getErrorMessage(self, error):
51
69
if error.data.get('status') == "invalidUserPass":
52
70
msg=_("Please double-check your username/password.")
71
self.emit(SIGNAL("badUserPass"))
53
72
elif error.data.get('status') == "oldVersion":
54
73
msg=_("The sync protocol has changed. Please upgrade.")
56
msg=_("Unknown error: %s" % `getattr(error, 'data')`)
75
msg=_("Unknown error: %s" % traceback.format_exc())
59
78
def connect(self, *args):
86
105
self.emit(SIGNAL("syncClockOff"), timediff)
90
self.deck = DeckStorage.Deck(self.parent.deckPath, backup=False)
110
self.deck = DeckStorage.Deck(self.parent.deckPath)
91
111
client = SyncClient(self.deck)
92
112
client.setServer(proxy)
93
113
proxy.deckName = self.parent.syncName
99
119
self.setStatus(_("Fetching summary from server..."), 0)
100
120
sums = client.summaries()
102
self.setStatus(_("Determining differences..."), 0)
103
payload = client.genPayload(sums)
105
pr = client.payloadChangeReport(payload)
106
self.setStatus("<br>" + pr + "<br>", 0)
107
self.setStatus(_("Transferring payload..."), 0)
108
res = client.server.applyPayload(payload)
110
self.setStatus(_("Applying reply..."), 0)
111
client.applyPayloadReply(res)
112
if client.mediaSyncPending:
113
self.doBulkDownload(proxy.deckName)
114
# finished. save deck, preserving mod time
115
self.setStatus(_("Sync complete."))
116
self.deck.lastLoaded = self.deck.modified
121
if client.needFullSync(sums):
122
self.setStatus(_("Preparing full sync..."), 0)
123
ret = client.prepareFullSync()
124
if ret[0] == "fromLocal":
125
self.setStatus(_("Uploading..."), 0)
126
client.fullSyncFromLocal(ret[1], ret[2])
128
self.setStatus(_("Downloading..."), 0)
129
client.fullSyncFromServer(ret[1], ret[2])
130
self.setStatus(_("Sync complete."), 0)
131
# reopen the deck in case we have sources
132
self.deck = DeckStorage.Deck(self.parent.deckPath)
133
client.deck = self.deck
136
self.setStatus(_("Determining differences..."), 0)
137
payload = client.genPayload(sums)
139
pr = client.payloadChangeReport(payload)
140
self.setStatus("<br>" + pr + "<br>", 0)
141
self.setStatus(_("Transferring payload..."), 0)
142
res = client.server.applyPayload(payload)
144
self.setStatus(_("Applying reply..."), 0)
145
client.applyPayloadReply(res)
146
# finished. save deck, preserving mod time
147
self.setStatus(_("Sync complete."))
148
self.deck.lastLoaded = self.deck.modified
121
153
self.setStatus(_("No changes found."))
156
186
except Exception, e:
158
188
#traceback.print_exc()
160
191
# cheap hack to ensure message is displayed
161
192
err = `getattr(e, 'data', None) or e`
162
193
self.setStatus(_("Syncing failed: %(a)s") % {
166
def doBulkDownload(self, deckname):
167
self.emit(SIGNAL("openSyncProgress"))
168
client = BulkMediaSyncer(self.deck)
169
client.server = BulkMediaSyncerProxy(self.user, self.pwd)
170
client.server.deckName = deckname
171
client.progressCallback = self.bulkCallback
175
self.emit(SIGNAL("bulkSyncFailed"))
177
self.emit(SIGNAL("closeSyncProgress"))
179
def bulkCallback(self, *args):
180
self.emit(SIGNAL("updateSyncProgress"), args)
182
197
# Choosing a deck to sync to
183
198
##########################################################################