Example #1
0
def sync_collection(username, password, full_sync="upload"):
    from anki.sync import Syncer, RemoteServer, FullSyncer, MediaSyncer, RemoteMediaServer

    collection = open_or_create_collection(username)

    server = RemoteServer(None)
    app.logger.info("u: %s,pass: %s" % (username, password))
    hkey = server.hostKey(username, password)
    syncer = Syncer(collection, server)
    ret = syncer.sync()
    app.logger.info("syncer return: %s" % ret)

    if (ret == "fullSync"):
        # app.logger.info("trying to do fullSync - upload - Not tested")
        client = FullSyncer(collection, hkey, server.client)
        if full_sync == "download":
            client.download()
        else:
            client.upload()

    if ret not in ("noChanges", "fullSync", "success"):
        collection.close()
        return False

    mediaserver = RemoteMediaServer(collection, hkey, server.client)
    mediaclient = MediaSyncer(collection, mediaserver)
    mediaret = mediaclient.sync()
    app.logger.info("mediasync returned: %s" % mediaret)
    collection.save()
    collection.close()

    return True
Example #2
0
 def _syncMedia(self):
     if not self.media:
         return
     self.server = RemoteMediaServer(self.hkey, self.server.con)
     self.client = MediaSyncer(self.col, self.server)
     ret = self.client.sync(self.mediaUsn)
     if ret == "noChanges":
         self.fireEvent("noMediaChanges")
     else:
         self.fireEvent("mediaSuccess")
Example #3
0
def _sync_anki(col_path, anki_hkey):
    try:
        col = Collection(col_path)

        server = RemoteServer(anki_hkey)
        client = FullSyncer(col, anki_hkey, server.client)
        client.download()
        col = Collection(col_path) # reload collection

        media_server = RemoteMediaServer(col, anki_hkey, server.client)
        media_client = MediaSyncer(col, media_server)
        media_client.sync()
        col.close(save=True)
    except:
        return traceback.format_exc()
Example #4
0
File: sync.py Project: dae/anki
 def _fullSync(self):
     # tell the calling thread we need a decision on sync direction, and
     # wait for a reply
     self.fullSyncChoice = False
     self.localIsEmpty = self.col.isEmpty()
     self.fireEvent("fullSync")
     while not self.fullSyncChoice:
         time.sleep(0.1)
     f = self.fullSyncChoice
     if f == "cancel":
         return
     self.client = FullSyncer(self.col, self.hkey, self.server.client,
                              hostNum=self.hostNum)
     try:
         if f == "upload":
             if not self.client.upload():
                 self.fireEvent("upbad")
         else:
             ret = self.client.download()
             if ret == "downloadClobber":
                 self.fireEvent(ret)
                 return
     except Exception as e:
         if "sync cancelled" in str(e):
             return
         raise
     # reopen db and move on to media sync
     self.col.reopen()
     self._syncMedia()
 def create_client_syncer(collection, hkey, server_test_app):
     mock_remote_server = MockRemoteMediaServer(col=collection,
                                                hkey=hkey,
                                                server_test_app=server_test_app)
     media_syncer = MediaSyncer(col=collection,
                                server=mock_remote_server)
     return media_syncer
Example #6
0
 def _fullSync(self):
     # tell the calling thread we need a decision on sync direction, and
     # wait for a reply
     self.fullSyncChoice = False
     self.localIsEmpty = self.col.isEmpty()
     self.fireEvent("fullSync")
     while not self.fullSyncChoice:
         time.sleep(0.1)
     f = self.fullSyncChoice
     if f == "cancel":
         return
     self.client = FullSyncer(self.col,
                              self.hkey,
                              self.server.client,
                              hostNum=self.hostNum)
     try:
         if f == "upload":
             if not self.client.upload():
                 self.fireEvent("upbad")
         else:
             self.client.download()
     except Exception as e:
         if "sync cancelled" in str(e):
             return
         raise
     # reopen db and move on to media sync
     self.col.reopen()
     self._syncMedia()
Example #7
0
 def _syncMedia(self):
     if not self.media:
         return
     self.server = RemoteMediaServer(self.col, self.hkey, self.server.client)
     self.client = MediaSyncer(self.col, self.server)
     try:
         ret = self.client.sync()
     except Exception as e:
         if "sync cancelled" in str(e):
             return
         raise
     if ret == "noChanges":
         self.fireEvent("noMediaChanges")
     elif ret == "sanityCheckFailed" or ret == "corruptMediaDB":
         self.fireEvent("mediaSanity")
     else:
         self.fireEvent("mediaSuccess")
Example #8
0
    def run(self):
        # init this first so an early crash doesn't cause an error
        # in the main thread
        self.syncMsg = ""
        self.uname = ""
        try:
            self.col = Collection(self.path, log=True)
        except:
            self.fireEvent("corrupt")
            return
        self.server = RemoteServer(self.hkey)
        self.client = Syncer(self.col, self.server)
        self.sentTotal = 0
        self.recvTotal = 0
        # throttle updates; qt doesn't handle lots of posted events well
        self.byteUpdate = time.time()

        def syncEvent(type):
            self.fireEvent("sync", type)

        def syncMsg(msg):
            self.fireEvent("syncMsg", msg)

        def canPost():
            if (time.time() - self.byteUpdate) > 0.1:
                self.byteUpdate = time.time()
                return True

        def sendEvent(bytes):
            self.sentTotal += bytes
            if canPost():
                self.fireEvent("send", str(self.sentTotal))

        def recvEvent(bytes):
            self.recvTotal += bytes
            if canPost():
                self.fireEvent("recv", str(self.recvTotal))

        addHook("sync", syncEvent)
        addHook("syncMsg", syncMsg)
        addHook("httpSend", sendEvent)
        addHook("httpRecv", recvEvent)
        # run sync and catch any errors
        try:
            self._sync()
        except:
            err = traceback.format_exc()
            self.fireEvent("error", err)
        finally:
            # don't bump mod time unless we explicitly save
            self.col.close(save=False)
            remHook("sync", syncEvent)
            remHook("syncMsg", syncMsg)
            remHook("httpSend", sendEvent)
            remHook("httpRecv", recvEvent)
Example #9
0
    def run(self):
        # init this first so an early crash doesn't cause an error
        # in the main thread
        self.syncMsg = ""
        self.uname = ""
        try:
            self.col = Collection(self.path, log=True)
        except:
            self.fireEvent("corrupt")
            return
        self.server = RemoteServer(self.hkey, hostNum=self.hostNum)
        self.client = Syncer(self.col, self.server)
        self.sentTotal = 0
        self.recvTotal = 0

        def syncEvent(type):
            self.fireEvent("sync", type)

        def syncMsg(msg):
            self.fireEvent("syncMsg", msg)

        def sendEvent(bytes):
            if not self._abort:
                self.sentTotal += bytes
                self.fireEvent("send", str(self.sentTotal))
            elif self._abort == 1:
                self._abort = 2
                raise Exception("sync cancelled")

        def recvEvent(bytes):
            if not self._abort:
                self.recvTotal += bytes
                self.fireEvent("recv", str(self.recvTotal))
            elif self._abort == 1:
                self._abort = 2
                raise Exception("sync cancelled")

        addHook("sync", syncEvent)
        addHook("syncMsg", syncMsg)
        addHook("httpSend", sendEvent)
        addHook("httpRecv", recvEvent)
        # run sync and catch any errors
        try:
            self._sync()
        except:
            err = traceback.format_exc()
            self.fireEvent("error", err)
        finally:
            # don't bump mod time unless we explicitly save
            self.col.close(save=False)
            remHook("sync", syncEvent)
            remHook("syncMsg", syncMsg)
            remHook("httpSend", sendEvent)
            remHook("httpRecv", recvEvent)
Example #10
0
File: sync.py Project: Stvad/anki
 def run(self):
     # init this first so an early crash doesn't cause an error
     # in the main thread
     self.syncMsg = ""
     self.uname = ""
     try:
         self.col = Collection(self.path, log=True)
     except:
         self.fireEvent("corrupt")
         return
     self.server = RemoteServer(self.hkey)
     self.client = Syncer(self.col, self.server)
     self.sentTotal = 0
     self.recvTotal = 0
     # throttle updates; qt doesn't handle lots of posted events well
     self.byteUpdate = time.time()
     def syncEvent(type):
         self.fireEvent("sync", type)
     def syncMsg(msg):
         self.fireEvent("syncMsg", msg)
     def canPost():
         if (time.time() - self.byteUpdate) > 0.1:
             self.byteUpdate = time.time()
             return True
     def sendEvent(bytes):
         self.sentTotal += bytes
         if canPost():
             self.fireEvent("send", str(self.sentTotal))
     def recvEvent(bytes):
         self.recvTotal += bytes
         if canPost():
             self.fireEvent("recv", str(self.recvTotal))
     addHook("sync", syncEvent)
     addHook("syncMsg", syncMsg)
     addHook("httpSend", sendEvent)
     addHook("httpRecv", recvEvent)
     # run sync and catch any errors
     try:
         self._sync()
     except:
         err = traceback.format_exc()
         self.fireEvent("error", err)
     finally:
         # don't bump mod time unless we explicitly save
         self.col.close(save=False)
         remHook("sync", syncEvent)
         remHook("syncMsg", syncMsg)
         remHook("httpSend", sendEvent)
         remHook("httpRecv", recvEvent)
Example #11
0
File: sync.py Project: dae/anki
 def run(self):
     # init this first so an early crash doesn't cause an error
     # in the main thread
     self.syncMsg = ""
     self.uname = ""
     try:
         self.col = Collection(self.path, log=True)
     except:
         self.fireEvent("corrupt")
         return
     self.server = RemoteServer(self.hkey, hostNum=self.hostNum)
     self.client = Syncer(self.col, self.server)
     self.sentTotal = 0
     self.recvTotal = 0
     def syncEvent(type):
         self.fireEvent("sync", type)
     def syncMsg(msg):
         self.fireEvent("syncMsg", msg)
     def sendEvent(bytes):
         if not self._abort:
             self.sentTotal += bytes
             self.fireEvent("send", str(self.sentTotal))
         elif self._abort == 1:
             self._abort = 2
             raise Exception("sync cancelled")
     def recvEvent(bytes):
         if not self._abort:
             self.recvTotal += bytes
             self.fireEvent("recv", str(self.recvTotal))
         elif self._abort == 1:
             self._abort = 2
             raise Exception("sync cancelled")
     addHook("sync", syncEvent)
     addHook("syncMsg", syncMsg)
     addHook("httpSend", sendEvent)
     addHook("httpRecv", recvEvent)
     # run sync and catch any errors
     try:
         self._sync()
     except:
         err = traceback.format_exc()
         self.fireEvent("error", err)
     finally:
         # don't bump mod time unless we explicitly save
         self.col.close(save=False)
         remHook("sync", syncEvent)
         remHook("syncMsg", syncMsg)
         remHook("httpSend", sendEvent)
         remHook("httpRecv", recvEvent)
Example #12
0
 def _syncMedia(self):
     if not self.media:
         return
     self.server = RemoteMediaServer(self.col, self.hkey, self.server.client)
     self.client = MediaSyncer(self.col, self.server)
     try:
         ret = self.client.sync()
     except Exception as e:
         if "sync cancelled" in str(e):
             return
         raise
     if ret == "noChanges":
         self.fireEvent("noMediaChanges")
     elif ret == "sanityCheckFailed":
         self.fireEvent("mediaSanity")
     else:
         self.fireEvent("mediaSuccess")
Example #13
0
    def run(self):
        # init this first so an early crash doesn't cause an error
        # in the main thread
        self.syncMsg = ""
        self.uname = ""
        try:
            self.col = Collection(self.path, log=True)
        except:
            self.fireEvent("corrupt")
            return
        self.server = RemoteServer(self.hkey, hostNum=self.hostNum)
        self.client = Syncer(self.col, self.server)
        self.sentTotal = 0
        self.recvTotal = 0

        def syncEvent(type):
            self.fireEvent("sync", type)

        def syncMsg(msg):
            self.fireEvent("syncMsg", msg)

        def http_progress(upload: int, download: int) -> None:
            if not self._abort:
                self.sentTotal += upload
                self.recvTotal += download
                self.progress_event.emit(self.sentTotal, self.recvTotal)  # type: ignore
            elif self._abort == 1:
                self._abort = 2
                raise Exception("sync cancelled")

        self.server.client.progress_hook = http_progress

        hooks.sync_stage_did_change.append(syncEvent)
        hooks.sync_progress_did_change.append(syncMsg)
        # run sync and catch any errors
        try:
            self._sync()
        except:
            err = traceback.format_exc()
            self.fireEvent("error", err)
        finally:
            # don't bump mod time unless we explicitly save
            self.col.close(save=False)
            hooks.sync_stage_did_change.remove(syncEvent)
            hooks.sync_progress_did_change.remove(syncMsg)
Example #14
0
 def _fullSync(self):
     # tell the calling thread we need a decision on sync direction, and
     # wait for a reply
     self.fullSyncChoice = False
     self.fireEvent("fullSync")
     while not self.fullSyncChoice:
         time.sleep(0.1)
     f = self.fullSyncChoice
     if f == "cancel":
         return
     self.client = FullSyncer(self.col, self.hkey, self.server.con)
     if f == "upload":
         self.client.upload()
     else:
         self.client.download()
     # reopen db and move on to media sync
     self.col.reopen()
     self._syncMedia()
Example #15
0
 def run(self):
     self.col = Collection(self.path)
     self.server = RemoteServer(self.hkey)
     self.client = Syncer(self.col, self.server)
     self.sentTotal = 0
     self.recvTotal = 0
     # throttle updates; qt doesn't handle lots of posted events well
     self.byteUpdate = time.time()
     def syncEvent(type):
         self.fireEvent("sync", type)
     def canPost():
         if (time.time() - self.byteUpdate) > 0.1:
             self.byteUpdate = time.time()
             return True
     def sendEvent(bytes):
         self.sentTotal += bytes
         if canPost():
             self.fireEvent("send", self.sentTotal)
     def recvEvent(bytes):
         self.recvTotal += bytes
         if canPost():
             self.fireEvent("recv", self.recvTotal)
     addHook("sync", syncEvent)
     addHook("httpSend", sendEvent)
     addHook("httpRecv", recvEvent)
     # run sync and catch any errors
     try:
         self._sync()
     except:
         err = traceback.format_exc()
         print err
         self.fireEvent("error", err)
     finally:
         # don't bump mod time unless we explicitly save
         self.col.close(save=False)
         remHook("sync", syncEvent)
         remHook("httpSend", sendEvent)
         remHook("httpRecv", recvEvent)
Example #16
0
File: sync.py Project: Stvad/anki
 def _fullSync(self):
     # if the local deck is empty, assume user is trying to download
     if self.col.isEmpty():
         f = "download"
     else:
         # tell the calling thread we need a decision on sync direction, and
         # wait for a reply
         self.fullSyncChoice = False
         self.fireEvent("fullSync")
         while not self.fullSyncChoice:
             time.sleep(0.1)
         f = self.fullSyncChoice
     if f == "cancel":
         return
     self.client = FullSyncer(self.col, self.hkey, self.server.con)
     if f == "upload":
         if not self.client.upload():
             self.fireEvent("upbad")
     else:
         self.client.download()
     # reopen db and move on to media sync
     self.col.reopen()
     self._syncMedia()
Example #17
0
 def _fullSync(self):
     # if the local deck is empty, assume user is trying to download
     if self.col.isEmpty():
         f = "download"
     else:
         # tell the calling thread we need a decision on sync direction, and
         # wait for a reply
         self.fullSyncChoice = False
         self.fireEvent("fullSync")
         while not self.fullSyncChoice:
             time.sleep(0.1)
         f = self.fullSyncChoice
     if f == "cancel":
         return
     self.client = FullSyncer(self.col, self.hkey, self.server.con)
     if f == "upload":
         if not self.client.upload():
             self.fireEvent("upbad")
     else:
         self.client.download()
     # reopen db and move on to media sync
     self.col.reopen()
     self._syncMedia()
Example #18
0
    def sync(self):
        """Sync collection to AnkiWeb"""
        if self.pm is None:
            return

        import click

        if not self.pm.profile['syncKey']:
            click.echo('No sync auth registered in profile')
            return

        from anki.sync import (Syncer, MediaSyncer, RemoteServer,
                               RemoteMediaServer)

        # Initialize servers and sync clients
        hkey = self.pm.profile['syncKey']
        hostNum = self.pm.profile.get('hostNum')
        server = RemoteServer(hkey, hostNum=hostNum)
        main_client = Syncer(self.col, server)
        media_client = MediaSyncer(
            self.col,
            RemoteMediaServer(self.col, hkey, server.client, hostNum=hostNum))

        # Perform main sync
        try:
            click.echo('Syncing deck ... ', nl=False)
            ret = main_client.sync()
        except Exception as e:
            if 'sync cancelled' in str(e):
                server.abort()
            click.secho('Error during sync!', fg='red')
            click.echo(e)
            raise click.Abort()

        # Parse return value
        if ret == "noChanges":
            click.echo('done (no changes)!')
        elif ret == "success":
            click.echo('done!')
        elif ret == "serverAbort":
            click.echo('aborted!')
            return
        elif ret == "fullSync":
            click.echo('aborted!')
            click.secho('Full sync required!', fg='red')
            return
        else:
            click.echo('failed!')
            click.echo(f'Message: {ret}')
            return

        # Perform media sync
        try:
            click.echo('Syncing media ... ', nl=False)
            save_cwd = os.getcwd()
            os.chdir(self.col.media.dir())
            ret = media_client.sync()
            os.chdir(save_cwd)
        except Exception as e:
            if "sync cancelled" in str(e):
                return
            raise

        if ret == "noChanges":
            click.echo('done (no changes)!')
        elif ret in ("sanityCheckFailed", "corruptMediaDB"):
            click.echo('failed!')
        else:
            click.echo('done!')
Example #19
0
class SyncThread(QThread):

    event = pyqtSignal(str, str)

    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):
        self._abort = 1

    def run(self):
        # init this first so an early crash doesn't cause an error
        # in the main thread
        self.syncMsg = ""
        self.uname = ""
        try:
            self.col = Collection(self.path, log=True)
        except:
            self.fireEvent("corrupt")
            return
        self.server = RemoteServer(self.hkey, hostNum=self.hostNum)
        self.client = Syncer(self.col, self.server)
        self.sentTotal = 0
        self.recvTotal = 0

        def syncEvent(type):
            self.fireEvent("sync", type)

        def syncMsg(msg):
            self.fireEvent("syncMsg", msg)

        def sendEvent(bytes):
            if not self._abort:
                self.sentTotal += bytes
                self.fireEvent("send", str(self.sentTotal))
            elif self._abort == 1:
                self._abort = 2
                raise Exception("sync cancelled")

        def recvEvent(bytes):
            if not self._abort:
                self.recvTotal += bytes
                self.fireEvent("recv", str(self.recvTotal))
            elif self._abort == 1:
                self._abort = 2
                raise Exception("sync cancelled")

        addHook("sync", syncEvent)
        addHook("syncMsg", syncMsg)
        addHook("httpSend", sendEvent)
        addHook("httpRecv", recvEvent)
        # run sync and catch any errors
        try:
            self._sync()
        except:
            err = traceback.format_exc()
            self.fireEvent("error", err)
        finally:
            # don't bump mod time unless we explicitly save
            self.col.close(save=False)
            remHook("sync", syncEvent)
            remHook("syncMsg", syncMsg)
            remHook("httpSend", sendEvent)
            remHook("httpRecv", recvEvent)

    def _abortingSync(self):
        try:
            return self.client.sync()
        except Exception as e:
            if "sync cancelled" in str(e):
                self.server.abort()
                raise
            else:
                raise

    def _sync(self):
        if self.auth:
            # need to authenticate and obtain host key
            self.hkey = self.server.hostKey(*self.auth)
            if not self.hkey:
                # provided details were invalid
                return self.fireEvent("badAuth")
            else:
                # write new details and tell calling thread to save
                self.fireEvent("newKey", self.hkey)
        # run sync and check state
        try:
            ret = self._abortingSync()
        except Exception as e:
            log = traceback.format_exc()
            err = repr(str(e))
            if ("Unable to find the server" in err or "Errno 2" in err
                    or "getaddrinfo" in err):
                self.fireEvent("offline")
            elif "sync cancelled" in err:
                pass
            else:
                self.fireEvent("error", log)
            return
        if ret == "badAuth":
            return self.fireEvent("badAuth")
        elif ret == "clockOff":
            return self.fireEvent("clockOff")
        elif ret == "basicCheckFailed" or ret == "sanityCheckFailed":
            return self.fireEvent("checkFailed")
        # full sync?
        if ret == "fullSync":
            return self._fullSync()
        # save and note success state
        if ret == "noChanges":
            self.fireEvent("noChanges")
        elif ret == "success":
            self.fireEvent("success")
        elif ret == "serverAbort":
            pass
        else:
            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()

    def _fullSync(self):
        # tell the calling thread we need a decision on sync direction, and
        # wait for a reply
        self.fullSyncChoice = False
        self.localIsEmpty = self.col.isEmpty()
        self.fireEvent("fullSync")
        while not self.fullSyncChoice:
            time.sleep(0.1)
        f = self.fullSyncChoice
        if f == "cancel":
            return
        self.client = FullSyncer(self.col,
                                 self.hkey,
                                 self.server.client,
                                 hostNum=self.hostNum)
        try:
            if f == "upload":
                if not self.client.upload():
                    self.fireEvent("upbad")
            else:
                self.client.download()
        except Exception as e:
            if "sync cancelled" in str(e):
                return
            raise
        # reopen db and move on to media sync
        self.col.reopen()
        self._syncMedia()

    def _syncMedia(self):
        if not self.media:
            return
        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()
        except Exception as e:
            if "sync cancelled" in str(e):
                return
            raise
        if ret == "noChanges":
            self.fireEvent("noMediaChanges")
        elif ret == "sanityCheckFailed" or ret == "corruptMediaDB":
            self.fireEvent("mediaSanity")
        else:
            self.fireEvent("mediaSuccess")

    def fireEvent(self, cmd, arg=""):
        self.event.emit(cmd, arg)
Example #20
0
File: sync.py Project: dae/anki
class SyncThread(QThread):

    event = pyqtSignal(str, str)

    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):
        self._abort = 1

    def run(self):
        # init this first so an early crash doesn't cause an error
        # in the main thread
        self.syncMsg = ""
        self.uname = ""
        try:
            self.col = Collection(self.path, log=True)
        except:
            self.fireEvent("corrupt")
            return
        self.server = RemoteServer(self.hkey, hostNum=self.hostNum)
        self.client = Syncer(self.col, self.server)
        self.sentTotal = 0
        self.recvTotal = 0
        def syncEvent(type):
            self.fireEvent("sync", type)
        def syncMsg(msg):
            self.fireEvent("syncMsg", msg)
        def sendEvent(bytes):
            if not self._abort:
                self.sentTotal += bytes
                self.fireEvent("send", str(self.sentTotal))
            elif self._abort == 1:
                self._abort = 2
                raise Exception("sync cancelled")
        def recvEvent(bytes):
            if not self._abort:
                self.recvTotal += bytes
                self.fireEvent("recv", str(self.recvTotal))
            elif self._abort == 1:
                self._abort = 2
                raise Exception("sync cancelled")
        addHook("sync", syncEvent)
        addHook("syncMsg", syncMsg)
        addHook("httpSend", sendEvent)
        addHook("httpRecv", recvEvent)
        # run sync and catch any errors
        try:
            self._sync()
        except:
            err = traceback.format_exc()
            self.fireEvent("error", err)
        finally:
            # don't bump mod time unless we explicitly save
            self.col.close(save=False)
            remHook("sync", syncEvent)
            remHook("syncMsg", syncMsg)
            remHook("httpSend", sendEvent)
            remHook("httpRecv", recvEvent)

    def _abortingSync(self):
        try:
            return self.client.sync()
        except Exception as e:
            if "sync cancelled" in str(e):
                self.server.abort()
                raise
            else:
                raise

    def _sync(self):
        if self.auth:
            # need to authenticate and obtain host key
            self.hkey = self.server.hostKey(*self.auth)
            if not self.hkey:
                # provided details were invalid
                return self.fireEvent("badAuth")
            else:
                # write new details and tell calling thread to save
                self.fireEvent("newKey", self.hkey)
        # run sync and check state
        try:
            ret = self._abortingSync()
        except Exception as e:
            log = traceback.format_exc()
            err = repr(str(e))
            if ("Unable to find the server" in err or
                "Errno 2" in err or "getaddrinfo" in err):
                self.fireEvent("offline")
            elif "sync cancelled" in err:
                pass
            else:
                self.fireEvent("error", log)
            return
        if ret == "badAuth":
            return self.fireEvent("badAuth")
        elif ret == "clockOff":
            return self.fireEvent("clockOff")
        elif ret == "basicCheckFailed" or ret == "sanityCheckFailed":
            return self.fireEvent("checkFailed")
        # full sync?
        if ret == "fullSync":
            return self._fullSync()
        # save and note success state
        if ret == "noChanges":
            self.fireEvent("noChanges")
        elif ret == "success":
            self.fireEvent("success")
        elif ret == "serverAbort":
            self.syncMsg = self.client.syncMsg
            return
        else:
            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()

    def _fullSync(self):
        # tell the calling thread we need a decision on sync direction, and
        # wait for a reply
        self.fullSyncChoice = False
        self.localIsEmpty = self.col.isEmpty()
        self.fireEvent("fullSync")
        while not self.fullSyncChoice:
            time.sleep(0.1)
        f = self.fullSyncChoice
        if f == "cancel":
            return
        self.client = FullSyncer(self.col, self.hkey, self.server.client,
                                 hostNum=self.hostNum)
        try:
            if f == "upload":
                if not self.client.upload():
                    self.fireEvent("upbad")
            else:
                ret = self.client.download()
                if ret == "downloadClobber":
                    self.fireEvent(ret)
                    return
        except Exception as e:
            if "sync cancelled" in str(e):
                return
            raise
        # reopen db and move on to media sync
        self.col.reopen()
        self._syncMedia()

    def _syncMedia(self):
        if not self.media:
            return
        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()
        except Exception as e:
            if "sync cancelled" in str(e):
                return
            raise
        if ret == "noChanges":
            self.fireEvent("noMediaChanges")
        elif ret == "sanityCheckFailed" or ret == "corruptMediaDB":
            self.fireEvent("mediaSanity")
        else:
            self.fireEvent("mediaSuccess")

    def fireEvent(self, cmd, arg=""):
        self.event.emit(cmd, arg)
Example #21
0
 def remove(self, fnames, minUsn):
     rrem = MediaSyncer.remove(self, fnames, minUsn)
     # increment the USN for each file removed
     #self.col.media.setUsn(self.col.media.usn() + len(rrem))
     return rrem
Example #22
0
 def __init__(self, col):
     MediaSyncer.__init__(self, col)
Example #23
0
def setup_remoteMedia():
    setup_basic()
    con = httpCon()
    ts.server = RemoteMediaServer(TEST_HKEY, con)
    ts.server2 = RemoteServer(TEST_HKEY)
    ts.client = MediaSyncer(ts.deck1, ts.server)
Example #24
0
 def remove(self, fnames, minUsn):
     rrem = MediaSyncer.remove(self, fnames, minUsn)
     # increment the USN for each file removed
     #self.col.media.setUsn(self.col.media.usn() + len(rrem))
     return rrem
Example #25
0
 def __init__(self, col):
     MediaSyncer.__init__(self, col)
Example #26
0
class SyncThread(QThread):

    def __init__(self, path, hkey, auth=None, media=True):
        QThread.__init__(self)
        self.path = path
        self.hkey = hkey
        self.auth = auth
        self.media = media

    def run(self):
        self.col = Collection(self.path)
        self.server = RemoteServer(self.hkey)
        self.client = Syncer(self.col, self.server)
        self.sentTotal = 0
        self.recvTotal = 0
        # throttle updates; qt doesn't handle lots of posted events well
        self.byteUpdate = time.time()
        def syncEvent(type):
            self.fireEvent("sync", type)
        def canPost():
            if (time.time() - self.byteUpdate) > 0.1:
                self.byteUpdate = time.time()
                return True
        def sendEvent(bytes):
            self.sentTotal += bytes
            if canPost():
                self.fireEvent("send", self.sentTotal)
        def recvEvent(bytes):
            self.recvTotal += bytes
            if canPost():
                self.fireEvent("recv", self.recvTotal)
        addHook("sync", syncEvent)
        addHook("httpSend", sendEvent)
        addHook("httpRecv", recvEvent)
        # run sync and catch any errors
        try:
            self._sync()
        except:
            err = traceback.format_exc()
            print err
            self.fireEvent("error", err)
        finally:
            # don't bump mod time unless we explicitly save
            self.col.close(save=False)
            remHook("sync", syncEvent)
            remHook("httpSend", sendEvent)
            remHook("httpRecv", recvEvent)

    def _sync(self):
        if self.auth:
            # need to authenticate and obtain host key
            self.hkey = self.server.hostKey(*self.auth)
            if not self.hkey:
                # provided details were invalid
                return self.fireEvent("badAuth")
            else:
                # write new details and tell calling thread to save
                self.fireEvent("newKey", self.hkey)
        # run sync and check state
        ret = self.client.sync()
        if ret == "badAuth":
            return self.fireEvent("badAuth")
        elif ret == "clockOff":
            return self.fireEvent("clockOff")
        # note mediaUSN for later
        self.mediaUsn = self.client.mediaUsn
        # full sync?
        if ret == "fullSync":
            return self._fullSync()
        # save and note success state
        self.col.save()
        if ret == "noChanges":
            self.fireEvent("noChanges")
        else:
            self.fireEvent("success")
        # then move on to media sync
        self._syncMedia()

    def _fullSync(self):
        # tell the calling thread we need a decision on sync direction, and
        # wait for a reply
        self.fullSyncChoice = False
        self.fireEvent("fullSync")
        while not self.fullSyncChoice:
            time.sleep(0.1)
        f = self.fullSyncChoice
        if f == "cancel":
            return
        self.client = FullSyncer(self.col, self.hkey, self.server.con)
        if f == "upload":
            self.client.upload()
        else:
            self.client.download()
        # reopen db and move on to media sync
        self.col.reopen()
        self._syncMedia()

    def _syncMedia(self):
        if not self.media:
            return
        self.server = RemoteMediaServer(self.hkey, self.server.con)
        self.client = MediaSyncer(self.col, self.server)
        ret = self.client.sync(self.mediaUsn)
        if ret == "noChanges":
            self.fireEvent("noMediaChanges")
        else:
            self.fireEvent("mediaSuccess")

    def fireEvent(self, *args):
        self.emit(SIGNAL("event"), *args)