Ejemplo n.º 1
0
def test_upgrade2():
    p = "/tmp/alpha-upgrade.anki2"
    if os.path.exists(p):
        os.unlink(p)
    shutil.copy2(os.path.join(testDir, "support/anki2-alpha.anki2"), p)
    col = Collection(p)
    assert col.db.scalar("select ver from col") == SCHEMA_VERSION
Ejemplo n.º 2
0
def ReadCollectionCounts(path, deckName):
    col = Collection(path)
    col.sched._checkDay()

    deckIds = {}
    for key, value in col.decks.decks.items():
        #print("Deck id -> " + value["name"])
        if value["name"] == deckName or value["name"].startswith(
                deckName):  #::
            deckIds[value["name"]] = value["id"]
            print(value["name"])
    #for value in deckIds.values():
    #    ()

#print(value)
    stat = col.stats()
    counts = 0
    cardsRes = []
    for name, deckId in deckIds.items():
        cardsRes = stat.col.db.all("""
            SELECT :today,due,* FROM cards 
            WHERE due < :today 
            AND did = :id
            AND reps != 0
            AND queue >= 0
            """ % (),
                                   today=stat.col.sched.today,
                                   id=deckId)
        #stat.col.db.all(""" PRAGMA table_info(cards);""")
        text = "count: %s - today: %s - name: %s" % (
            len(cardsRes), stat.col.sched.today, name)
        print(text)
        WriteToLog(text)
        counts = len(cardsRes) + counts
    return counts
Ejemplo n.º 3
0
def get_collection():
    col = getattr(g, '_collection', None)
    if col is None:
        username = session['current_user']['username']
        collection_path = data_root + '/' + username + '/collection.anki2'
        col = g._collection = Collection(collection_path, lock=True)
    return col
Ejemplo n.º 4
0
    def loadCollection(self):
        cpath = self.pm.collectionPath()
        try:
            self.col = Collection(cpath, log=True)
        except anki.db.DBError:
            # warn user
            showWarning(_("""\
Your collection is corrupt. Please create a new profile, then \
see the manual for how to restore from an automatic backup.

Debug info:
""")+traceback.format_exc())
            self.unloadProfile()
        except Exception as e:
            # the custom exception handler won't catch these if we immediately
            # unload, so we have to manually handle it
            if "invalidColVersion" == str(e):
                showWarning("""\
This profile requires a newer version of Anki to open. Did you forget to use the Downgrade button prior to switching Anki versions?""")
                sys.exit(1)
            if "invalidTempFolder" in repr(str(e)):
                showWarning(self.errorHandler.tempFolderMsg())
                self.unloadProfile()
                return
            self.unloadProfile()
            raise
        self.progress.setupDB(self.col.db)
        self.col.db._db.create_function(
            "filterTxtSearch", 1, noOpTxtSearch
        )
        self.maybeEnableUndo()
        self.moveToState("deckBrowser")
Ejemplo n.º 5
0
def serve() -> None:
    global col

    col = Collection(col_path(), server=True)
    # don't hold an outer transaction open
    col.db.rollback()
    host = os.getenv("HOST", "0.0.0.0")
    port = int(os.getenv("PORT", "8080"))

    server = create_server(
        app,
        host=host,
        port=port,
        clear_untrusted_proxy_headers=True,
    )

    effective_port = server.effective_port  # type: ignore
    print(f"Sync server listening on http://{host}:{effective_port}/sync/")
    if host == "0.0.0.0":
        ip = socket.gethostbyname(socket.gethostname())
        print(f"Replace 0.0.0.0 with your machine's IP address (perhaps {ip})")
    print(
        "For more info, see https://github.com/ankitects/anki/blob/master/docs/syncserver.md"
    )
    server.run()
Ejemplo n.º 6
0
def main():

    collection_path = "collection.anki2"
    collection = Collection(collection_path)

    # get ordering of languages in the model
    ord_lang = {
        field['name']: field['ord']
        for field in collection.models.all()[1]['flds']
    }

    for note_id in collection.findNotes('*'):

        note = collection.getNote(note_id)
        langs, word_fr = parse_FR(note.fields[ord_lang['FR']])

        note.fields[ord_lang['FR']] = word_fr

        if langs:
            words = parse_EN(note.fields[ord_lang['EN']], langs)
            if len(words) == len(langs):
                for idl, lang in enumerate(langs):
                    note.fields[ord_lang[lang]] = words[idl]
                logging.info('Updated %s', word_fr)
            else:
                logging.error('Error with note %s', str(note.fields))
        else:
            logging.debug('Not updated: %s', note.fields[ord_lang['FR']])
        note.flush()

    collection.close()
Ejemplo n.º 7
0
    def loadCollection(self):
        cpath = self.pm.collectionPath()
        try:
            self.col = Collection(cpath, log=True)
        except anki.db.Error:
            # warn user
            showWarning(
                _("""\
Your collection is corrupt. Please create a new profile, then \
see the manual for how to restore from an automatic backup.

Debug info:
""") + traceback.format_exc())
            self.unloadProfile()
        except Exception as e:
            # the custom exception handler won't catch this if we immediately
            # unload, so we have to manually handle it
            if "invalidTempFolder" in repr(str(e)):
                showWarning(self.errorHandler.tempFolderMsg())
                self.unloadProfile()
                return
            self.unloadProfile()
            raise
        self.progress.setupDB(self.col.db)
        self.maybeEnableUndo()
        self.moveToState("deckBrowser")
Ejemplo n.º 8
0
def get_collection(username):
    col = getattr(g, '_collection', None)
    if col is None:
        collection_path = data_root + '/' + username + '/collection.anki2'
        # col = g._collection = Collection(collection_path, lock=True)
        col = g._collection = Collection(collection_path, server=True)
    return col
Ejemplo n.º 9
0
def open_or_create_collection(ankiweb_username):
    from anki import Collection
    base_path = get_base_path(ankiweb_username)
    app.logger.info(base_path)
    if not os.path.exists(base_path):
        os.makedirs(base_path)
    collection = Collection(base_path + "/collection.anki2", log=True)
    return collection
Ejemplo n.º 10
0
def test_upgrade2():
    fd, p = tempfile.mkstemp(suffix=".anki2", prefix="alpha-upgrade")
    if os.path.exists(p):
        os.close(fd)
        os.unlink(p)
    shutil.copy2(os.path.join(testDir, "support/anki2-alpha.anki2"), p)
    col = Collection(p)
    assert col.db.scalar("select ver from col") == SCHEMA_VERSION
Ejemplo n.º 11
0
Archivo: api.py Proyecto: zohl/ScRead
def col():
    try:
        from aqt import mw
        return mw.col
    except:
        (fd, name) = tempfile.mkstemp(suffix=".anki2")
        os.close(fd)
        os.unlink(name)
        return Collection(name)
Ejemplo n.º 12
0
def listitems(args):
    col = Collection(args._path)
    idlist = col.findCards(args.query)
    print len(idlist)
    for id_ in idlist:
        card = col.getCard(id_)
        note = card.note()
        print note.items()
    col.close()
Ejemplo n.º 13
0
    def _loadCollection(self):
        cpath = self.pm.collectionPath()

        self.col = Collection(cpath, log=True)

        self.setEnabled(True)
        self.progress.setupDB(self.col.db)
        self.maybeEnableUndo()
        self.moveToState("deckBrowser")
        return True
Ejemplo n.º 14
0
 def setup():
     # create collection 1 with a single note
     c1 = getEmptyCol()
     f = c1.newNote()
     f['Front'] = "startingpoint"
     nid = f.id
     c1.addNote(f)
     cid = f.cards()[0].id
     c1.beforeUpload()
     # start both clients and server off in this state
     s1path = c1.path.replace(".anki2", "-s1.anki2")
     c2path = c1.path.replace(".anki2", "-c2.anki2")
     shutil.copy2(c1.path, s1path)
     shutil.copy2(c1.path, c2path)
     # open them
     c1 = Collection(c1.path)
     c2 = Collection(c2path)
     s1 = Collection(s1path, server=True)
     return c1, c2, s1, nid, cid
Ejemplo n.º 15
0
def duestat(args):
    col = Collection(args._path)
    idlist = col.findCards(args.query)
    lbllist = ("new", "learning", "due")
    cnt = Counter({0: 0, 1: 0, 2: 0})
    for id_ in idlist:
        card = col.getCard(id_)
        cnt[card.type] += 1
    for index, lbl in enumerate(lbllist):
        print "{1:5}: {0}".format(lbl, cnt[index])
Ejemplo n.º 16
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)
Ejemplo n.º 17
0
def migrate_users_decks(src, dst):
    # Create the new Anki2 collection
    os.mkdir(dst)
    col = Collection(os.path.join(dst, 'collection.anki2'))

    # loop over all the Anki1 decks, importing them
    for deck_path in glob.glob(os.path.join(src, '*.anki')):
        importer = Anki1Importer(col, deck_path.decode('utf-8'))
        importer.run()

    col.close()
Ejemplo n.º 18
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)
Ejemplo n.º 19
0
    def _addDummyCollection(self, zip):
        path = namedtmp("dummy.anki2")
        c = Collection(path)
        n = c.newNote()
        n[_('Front')] = "This file requires a newer version of Anki."
        c.addNote(n)
        c.save()
        c.close()

        zip.write(path, "collection.anki2")
        os.unlink(path)
Ejemplo n.º 20
0
def get_collection():
    """Not used"""
    col = Collection(COLLECTION)
    ids = col.findCards(QUERY)
    print(ids)
    for id in ids:
        card = col.getCard(id)
        print(card)
        note = col.getNote(card.nid)
        print(note['Word'])
    return col
Ejemplo n.º 21
0
    def __create_master_col(self):
        """
        Creates an empty master anki db that will be copied on each request
        for a new db. This is more efficient than initializing a new db each
        time.
        """

        file_path = os.path.join(self.tempdir, "collection.anki2")
        master_col = Collection(file_path)
        master_col.db.close()
        self.master_db_path = file_path
Ejemplo n.º 22
0
def clean(collection_path=None, profile=None):
    collection_path = create_check_collection_path(collection_path, profile)
    # Create collection.
    col = Collection(collection_path)
    # Get notes to remove.
    notes = col.db.list(QUERY)
    # Remove non-updated notes.
    print("Removing old cards with IDs:", notes)
    col.remNotes(notes)
    # Close collection.
    col.close()
Ejemplo n.º 23
0
def gen_test_collection(new_dir) -> Collection:
    """Generates a test collection for us in tests, by copying a template collection"""
    # col_dir = Path(tmp_path_factory, "Collection")
    # col_dir.mkdir()
    shutil.copytree(TEMPLATE_COLLECTION_PTH.parent,
                    new_dir,
                    dirs_exist_ok=True)
    test_col_pth = Path(new_dir, TEMPLATE_COLLECTION_PTH.name)
    assert test_col_pth
    test_col = Collection(path=str(test_col_pth))
    print(f"Test collection created at {test_col_pth}")
    return test_col
Ejemplo n.º 24
0
def openCollection(colPath):
    while(True):
        try: 
            col = Collection(colPath)
            return col
        except DBError:
            print("Collection could not be read. Is Anki running?")
            inp = input("Enter a new collection path, or leave blank to try again.")
            if inp:
                colPath = inp
        except AssertionError:
            colPath = input("Invalid collection file. Please input a new path: ")
Ejemplo n.º 25
0
    def _prepareFiles(self):
        importingV2 = self.file.endswith(".anki21")
        self.mustResetLearning = False

        self.dst = self.col
        self.src = Collection(self.file)

        if not importingV2 and self.col.schedVer() != 1:
            # any scheduling included?
            if self.src.db.scalar(
                    "select 1 from cards where queue != 0 limit 1"):
                self.mustResetLearning = True
Ejemplo n.º 26
0
def import_command(apkgs, collection_path=None, profile=None):
    collection_path = create_check_collection_path(collection_path, profile)
    # I need to do this because creating a collection changes the current path.
    # Anki should fix that I think...
    apkgs = [os.path.abspath(i) for i in apkgs]
    # Create collection.
    col = Collection(collection_path)
    # Import collection.
    for a in apkgs:
        AnkiPackageImporter(col, a).run()
    # Close collection.
    col.close()
Ejemplo n.º 27
0
Archivo: main.py Proyecto: jdeut/ankiqt
    def loadCollection(self):
        self.hideSchemaMsg = True
        try:
            self.col = Collection(self.pm.collectionPath())
        except:
            # move back to profile manager
            showWarning("""\
Your collection is corrupt. Please see the manual for \
how to restore from a backup.""")
            return self.unloadProfile()
        self.hideSchemaMsg = False
        self.progress.setupDB(self.col.db)
        self.moveToState("deckBrowser")
Ejemplo n.º 28
0
    def _prepareFiles(self):
        importingV2 = self.file.endswith(".anki21")
        if importingV2 and self.col.schedVer() == 1:
            raise Exception("V2 scheduler must be enabled to import this file.")

        self.dst = self.col
        self.src = Collection(self.file)

        if not importingV2 and self.col.schedVer() != 1:
            # if v2 scheduler enabled, can't import v1 decks that include scheduling
            if self.src.db.scalar("select 1 from cards where queue != 0 limit 1"):
                self.src.close(save=False)
                raise Exception("V2 scheduler can not import V1 decks with scheduling included.")
Ejemplo n.º 29
0
 def run(self):
     # open profile deck
     self.col = Collection(self.colpath)
     # loop through paths
     while True:
         path = self.paths.pop()
         self.name = os.path.basename(path)
         self.upgrade(path)
         # abort if finished
         if not self.paths:
             break
         self.current += 1
     self.col.close()
     self.finished = True
Ejemplo n.º 30
0
def col_tuple(tmpdir):
    """
    Get a test Anki collection.

    Anki irritatingly changes the working directory to the media directory, so
    also return our old working directory.
    """
    old_cwd = os.getcwd()
    my_col = Collection(tmpdir / "collection.anki2")
    col_obj = TestCollection(my_col, old_cwd)
    try:
        yield col_obj
    finally:
        my_col.close()