diff --git a/anki/consts.py b/anki/consts.py index f77ef872f..642686c4c 100644 --- a/anki/consts.py +++ b/anki/consts.py @@ -50,8 +50,7 @@ STARTING_FACTOR = 2500 SCHEMA_VERSION = 11 SYNC_ZIP_SIZE = int(2.5*1024*1024) SYNC_ZIP_COUNT = 25 -SYNC_BASE = "https://sync.ankiweb.net/" -SYNC_MEDIA_BASE = "https://sync.ankiweb.net/msync/" +SYNC_BASE = "https://sync%s.ankiweb.net/" SYNC_VER = 9 HELP_SITE="http://ankisrs.net/docs/manual.html" diff --git a/anki/sync.py b/anki/sync.py index 9c92b0b59..b585f5bc2 100644 --- a/anki/sync.py +++ b/anki/sync.py @@ -55,6 +55,7 @@ class Syncer: self.rmod = meta['mod'] self.maxUsn = meta['usn'] self.uname = meta.get("uname", "") + self.hostNum = meta.get("hostNum") meta = self.meta() self.col.log("lmeta", meta) self.lmod = meta['mod'] @@ -472,11 +473,20 @@ class _MonitoringFile(io.BufferedReader): class HttpSyncer: - def __init__(self, hkey=None, client=None): + def __init__(self, hkey=None, client=None, hostNum=None): self.hkey = hkey self.skey = checksum(str(random.random()))[:8] self.client = client or AnkiRequestsClient() self.postVars = {} + self.hostNum = hostNum + self.prefix = "sync/" + + def syncURL(self): + if devMode: + url = "https://l1sync.ankiweb.net/" + else: + url = SYNC_BASE % (self.hostNum or "") + return url + self.prefix def assertOk(self, resp): # not using raise_for_status() as aqt expects this error msg @@ -552,13 +562,8 @@ Content-Type: application/octet-stream\r\n\r\n""") class RemoteServer(HttpSyncer): - def __init__(self, hkey): - HttpSyncer.__init__(self, hkey) - - def syncURL(self): - if devMode: - return "https://l1sync.ankiweb.net/sync/" - return SYNC_BASE + "sync/" + def __init__(self, hkey, hostNum): + HttpSyncer.__init__(self, hkey, hostNum=hostNum) def hostKey(self, user, pw): "Returns hkey or none if user/pw incorrect." @@ -619,19 +624,14 @@ class RemoteServer(HttpSyncer): class FullSyncer(HttpSyncer): - def __init__(self, col, hkey, client): - HttpSyncer.__init__(self, hkey, client) + def __init__(self, col, hkey, client, hostNum): + HttpSyncer.__init__(self, hkey, client, hostNum=hostNum) self.postVars = dict( k=self.hkey, v="ankidesktop,%s,%s"%(anki.version, platDesc()), ) self.col = col - def syncURL(self): - if devMode: - return "https://l1.ankiweb.net/sync/" - return SYNC_BASE + "sync/" - def download(self): runHook("sync", "download") self.col.close() @@ -810,14 +810,10 @@ class MediaSyncer: class RemoteMediaServer(HttpSyncer): - def __init__(self, col, hkey, client): + def __init__(self, col, hkey, client, hostNum): self.col = col - HttpSyncer.__init__(self, hkey, client) - - def syncURL(self): - if devMode: - return "https://l1.ankiweb.net/msync/" - return SYNC_MEDIA_BASE + HttpSyncer.__init__(self, hkey, client, hostNum=hostNum) + self.prefix = "msync/" def begin(self): self.postVars = dict( diff --git a/aqt/sync.py b/aqt/sync.py index 91f527f88..28dde3225 100644 --- a/aqt/sync.py +++ b/aqt/sync.py @@ -43,7 +43,9 @@ class SyncManager(QObject): # create the thread, setup signals and start running t = self.thread = SyncThread( self.pm.collectionPath(), self.pm.profile['syncKey'], - auth=auth, media=self.pm.profile['syncMedia']) + auth=auth, media=self.pm.profile['syncMedia'], + hostNum=self.pm.profile.get("hostNum"), + ) t.event.connect(self.onEvent) self.label = _("Connecting...") prog = self.mw.progress.start(immediate=True, label=self.label) @@ -64,6 +66,7 @@ class SyncManager(QObject): showText(self.thread.syncMsg) if self.thread.uname: self.pm.profile['syncUser'] = self.thread.uname + self.pm.profile['hostNum'] = self.thread.hostNum def delayedInfo(): if self._didFullUp and not self._didError: showInfo(_("""\ @@ -290,12 +293,13 @@ class SyncThread(QThread): event = pyqtSignal(str, str) - def __init__(self, path, hkey, auth=None, media=True): + def __init__(self, path, hkey, auth=None, media=True, hostNum=None): QThread.__init__(self) self.path = path self.hkey = hkey self.auth = auth self.media = media + self.hostNum = hostNum self._abort = 0 # 1=flagged, 2=aborting def flagAbort(self): @@ -311,7 +315,7 @@ class SyncThread(QThread): except: self.fireEvent("corrupt") return - self.server = RemoteServer(self.hkey) + self.server = RemoteServer(self.hkey, hostNum=self.hostNum) self.client = Syncer(self.col, self.server) self.sentTotal = 0 self.recvTotal = 0 @@ -405,6 +409,7 @@ class SyncThread(QThread): self.fireEvent("error", "Unknown sync return code.") self.syncMsg = self.client.syncMsg self.uname = self.client.uname + self.hostNum = self.client.hostNum # then move on to media sync self._syncMedia() @@ -419,7 +424,8 @@ class SyncThread(QThread): f = self.fullSyncChoice if f == "cancel": return - self.client = FullSyncer(self.col, self.hkey, self.server.client) + self.client = FullSyncer(self.col, self.hkey, self.server.client, + hostNum=self.hostNum) try: if f == "upload": if not self.client.upload(): @@ -437,7 +443,8 @@ class SyncThread(QThread): def _syncMedia(self): if not self.media: return - self.server = RemoteMediaServer(self.col, self.hkey, self.server.client) + self.server = RemoteMediaServer(self.col, self.hkey, self.server.client, + hostNum=self.hostNum) self.client = MediaSyncer(self.col, self.server) try: ret = self.client.sync()