Beispiel #1
0
def test_graphs():
    from anki import Deck
    d = Deck(os.path.expanduser("~/test.anki"))
    g = d.stats()
    rep = g.report()
    open(os.path.expanduser("~/test.html"), "w").write(rep)
    return
Beispiel #2
0
def test_localsync_threeway():
    # deck1 (client) <-> deck2 (server) <-> deck3 (client)
    deck3 = Deck()
    client2 = SyncClient(deck3)
    server2 = SyncServer(deck2)
    client2.setServer(server2)
    client.sync()
    client2.sync()
    # add a new question
    f = deck1.newFact()
    f['Front'] = u"a"; f['Back'] = u"b"
    f = deck1.addFact(f)
    card = f.cards[0]
    client.sync()
    assert deck1.cardCount() == 6
    assert deck2.cardCount() == 6
    # check it propagates from server to deck3
    client2.sync()
    assert deck3.cardCount() == 6
    # delete a card on deck1
    deck1.deleteCard(card.id)
    client.sync()
    deck1.reset(); deck2.reset()
    assert deck1.cardCount() == 5
    assert deck2.cardCount() == 5
    # make sure the delete is now propagated from the server to deck3
    client2.sync()
    assert deck3.cardCount() == 5
Beispiel #3
0
def test_graphs():
    from anki import Deck
    d = Deck(os.path.expanduser("~/test.anki"))
    g = d.stats()
    rep = g.report()
    open(os.path.expanduser("~/test.html"), "w").write(rep)
    return
Beispiel #4
0
def test_localsync_threeway():
    # deck1 (client) <-> deck2 (server) <-> deck3 (client)
    deck3 = Deck()
    client2 = SyncClient(deck3)
    server2 = SyncServer(deck2)
    client2.setServer(server2)
    client.sync()
    client2.sync()
    # add a new question
    f = deck1.newFact()
    f['Front'] = u"a"
    f['Back'] = u"b"
    f = deck1.addFact(f)
    card = f.cards[0]
    client.sync()
    assert deck1.cardCount() == 6
    assert deck2.cardCount() == 6
    # check it propagates from server to deck3
    client2.sync()
    assert deck3.cardCount() == 6
    # delete a card on deck1
    deck1.deleteCard(card.id)
    client.sync()
    deck1.reset()
    deck2.reset()
    assert deck1.cardCount() == 5
    assert deck2.cardCount() == 5
    # make sure the delete is now propagated from the server to deck3
    client2.sync()
    assert deck3.cardCount() == 5
Beispiel #5
0
def test_mnemosyne10():
    deck = Deck()
    deck.addModel(BasicModel())
    file = unicode(os.path.join(testDir, "importing/test.mem"))
    i = mnemosyne10.Mnemosyne10Importer(deck, file)
    i.doImport()
    assert i.total == 5
    deck.close()
Beispiel #6
0
def test_openReadOnly():
    # non-writeable dir
    assertException(Exception, lambda: Deck("/attachroot"))
    # reuse tmp file from before, test non-writeable file
    os.chmod(newPath, 0)
    assertException(Exception, lambda: Deck(newPath))
    os.chmod(newPath, 0666)
    os.unlink(newPath)
Beispiel #7
0
def test_supermemo_xml_01_unicode():
    deck = Deck()
    deck.addModel(BasicModel())
    file = unicode(os.path.join(testDir, "importing/supermemo1.xml"))
    i = supermemo_xml.SupermemoXmlImporter(deck, file)
    #i.META.logToStdOutput = True
    i.doImport()
    # only returning top-level elements?
    assert i.total == 1
    deck.close()
Beispiel #8
0
def test_csv_tags():
    deck = Deck()
    deck.addModel(BasicModel())
    file = unicode(os.path.join(testDir, "importing/text-tags.txt"))
    i = csvfile.TextImporter(deck, file)
    i.doImport()
    facts = deck.db.query(Fact).all()
    assert len(facts) == 2
    assert facts[0].tags == "baz qux" or facts[1].tags == "baz qux"
    deck.close()
Beispiel #9
0
def test_csv():
    deck = Deck()
    deck.addModel(BasicModel())
    file = unicode(os.path.join(testDir, "importing/text-2fields.txt"))
    i = csvfile.TextImporter(deck, file)
    i.doImport()
    # four problems - missing front, dupe front, wrong num of fields
    assert len(i.log) == 4
    assert i.total == 5
    deck.close()
Beispiel #10
0
def setup1():
    global deck
    deck = Deck()
    deck.addModel(BasicModel())
    deck.currentModel.cardModels[1].active = True
    f = deck.newFact()
    f['Front'] = u"foo"; f['Back'] = u"bar"; f.tags = u"tag, tag2"
    deck.addFact(f)
    f = deck.newFact()
    f['Front'] = u"baz"; f['Back'] = u"qux"
    deck.addFact(f)
Beispiel #11
0
 def _checkDecks(self):
     self._decks = []
     decks = self.mw.config.recentDecks()
     if not decks:
         return
     tx = time.time()
     self.mw.progress.start(max=len(decks))
     for c, d in enumerate(decks):
         self.mw.progress.update(
             _("Checking deck %(x)d of %(y)d...") % {
                 'x': c + 1,
                 'y': len(decks)
             })
         base = os.path.basename(d)
         if not os.path.exists(d):
             self._decks.append({
                 'name': base,
                 'state': 'missing',
                 'path': d
             })
             continue
         try:
             mod = os.stat(d)[stat.ST_MTIME]
             t = time.time()
             deck = Deck(d, queue=False, lock=False)
             counts = deck.sched.selCounts()
             dtime = deck.sched.timeToday()
             dreps = deck.sched.repsToday()
             self._decks.append({
                 'path': d,
                 'state': 'ok',
                 'name': deck.name(),
                 'due': counts[1] + counts[2],
                 'new': counts[0],
                 'mod': deck.mod,
                 # these multiply deck check time by a factor of 6
                 'time': dtime,
                 'reps': dreps
             })
             deck.close(save=False)
             # reset modification time for the sake of backup systems
             try:
                 os.utime(d, (mod, mod))
             except:
                 # some misbehaving filesystems may fail here
                 pass
         except Exception, e:
             if "locked" in unicode(e):
                 state = "in use"
             else:
                 state = "corrupt"
             self._decks.append({'name': base, 'state': state, 'path': d})
Beispiel #12
0
def test_create():
    global newPath, newMod
    path = "/tmp/test_attachNew.anki"
    try:
        os.unlink(path)
    except OSError:
        pass
    deck = Deck(path)
    # for open()
    newPath = deck.path
    deck.save()
    newMod = deck.mod
    deck.close()
    del deck
Beispiel #13
0
def test_upgrade():
    import tempfile, shutil
    src = os.path.join(testDir, "support", "anki12.anki")
    (fd, dst) = tempfile.mkstemp(suffix=".anki")
    print "upgrade to", dst
    shutil.copy(src, dst)
    deck = Deck(dst)
    # creation time should have been adjusted
    d = datetime.datetime.fromtimestamp(deck.crt)
    assert d.hour == 4 and d.minute == 0
    # 3 new, 2 failed, 1 due
    assert deck.sched.counts() == (3, 2, 1)
    # now's a good time to test the integrity check too
    deck.fixIntegrity()
Beispiel #14
0
def test_upgrade():
    import tempfile, shutil
    src = os.path.join(testDir, "support", "anki12.anki")
    (fd, dst) = tempfile.mkstemp(suffix=".anki")
    print "upgrade to", dst
    shutil.copy(src, dst)
    deck = Deck(dst)
    # creation time should have been adjusted
    d = datetime.datetime.fromtimestamp(deck.crt)
    assert d.hour == 4 and d.minute == 0
    # 3 new, 2 failed, 1 due
    assert deck.sched.counts() == (3,2,1)
    # now's a good time to test the integrity check too
    deck.fixIntegrity()
Beispiel #15
0
 def _checkDecks(self):
     self._decks = []
     decks = self.mw.config.recentDecks()
     if not decks:
         return
     tx = time.time()
     self.mw.progress.start(max=len(decks))
     for c, d in enumerate(decks):
         self.mw.progress.update(_("Checking deck %(x)d of %(y)d...") % {
             'x': c+1, 'y': len(decks)})
         base = os.path.basename(d)
         if not os.path.exists(d):
             self._decks.append({'name': base, 'state': 'missing', 'path':d})
             continue
         try:
             mod = os.stat(d)[stat.ST_MTIME]
             t = time.time()
             deck = Deck(d, queue=False, lock=False)
             counts = deck.sched.selCounts()
             dtime = deck.sched.timeToday()
             dreps = deck.sched.repsToday()
             self._decks.append({
                 'path': d,
                 'state': 'ok',
                 'name': deck.name(),
                 'due': counts[1]+counts[2],
                 'new': counts[0],
                 'mod': deck.mod,
                 # these multiply deck check time by a factor of 6
                 'time': dtime,
                 'reps': dreps
                 })
             deck.close(save=False)
             # reset modification time for the sake of backup systems
             try:
                 os.utime(d, (mod, mod))
             except:
                 # some misbehaving filesystems may fail here
                 pass
         except Exception, e:
             if "locked" in unicode(e):
                 state = "in use"
             else:
                 state = "corrupt"
             self._decks.append({'name': base, 'state':state, 'path':d})
Beispiel #16
0
def test_dingsbums():
    deck = Deck()
    deck.addModel(BasicModel())
    startNumberOfFacts = deck.factCount()
    file = unicode(os.path.join(testDir, "importing/dingsbums.xml"))
    i = dingsbums.DingsBumsImporter(deck, file)
    i.doImport()
    assert 7 == i.total
    deck.close()
Beispiel #17
0
def test_updating():
    # get the standard csv deck first
    deck = Deck()
    deck.addModel(BasicModel())
    file = unicode(os.path.join(testDir, "importing/text-2fields.txt"))
    i = csvfile.TextImporter(deck, file)
    i.doImport()
    # now update
    file = unicode(os.path.join(testDir, "importing/text-update.txt"))
    i = csvfile.TextImporter(deck, file)
    # first field
    i.updateKey = (0, deck.currentModel.fieldModels[0].id)
    i.multipleCardsAllowed = False
    i.doImport()
    ans = deck.db.scalar(
        u"select answer from cards where question like '%食べる%'")
    assert "to ate" in ans
    # try again with tags
    i.updateKey = (0, deck.currentModel.fieldModels[0].id)
    i.mapping[1] = 0
    i.doImport()
    deck.close()
Beispiel #18
0
def test_anki10():
    # though these are not modified, sqlite updates the mtime, so copy to tmp
    # first
    file_ = unicode(os.path.join(testDir, "importing/test10.anki"))
    file = "/tmp/test10.anki"
    shutil.copy(file_, file)
    file2_ = unicode(os.path.join(testDir, "importing/test10-2.anki"))
    file2 = "/tmp/test10-2.anki"
    shutil.copy(file2_, file2)
    deck = Deck()
    i = anki10.Anki10Importer(deck, file)
    i.doImport()
    assert i.total == 2
    deck.db.rollback()
    deck.close()
    # import a deck into itself - 10-2 is the same as test10, but with one
    # card answered and another deleted. nothing should be synced to client
    deck = Deck(file, backup=False)
    i = anki10.Anki10Importer(deck, file2)
    i.doImport()
    assert i.total == 0
    deck.db.rollback()
Beispiel #19
0
def test_mnemosyne10():
    deck = Deck()
    deck.addModel(BasicModel())
    file = unicode(os.path.join(testDir, "importing/test.mem"))
    i = mnemosyne10.Mnemosyne10Importer(deck, file)
    i.doImport()
    assert i.total == 5
    deck.close()
Beispiel #20
0
def test_dingsbums():
    deck = Deck()
    deck.addModel(BasicModel())
    startNumberOfFacts = deck.factCount()
    file = unicode(os.path.join(testDir, "importing/dingsbums.xml"))
    i = dingsbums.DingsBumsImporter(deck, file)
    i.doImport()
    assert 7 == i.total
    deck.close()
Beispiel #21
0
def test_supermemo_xml_01_unicode():
    deck = Deck()
    deck.addModel(BasicModel())
    file = unicode(os.path.join(testDir, "importing/supermemo1.xml"))
    i = supermemo_xml.SupermemoXmlImporter(deck, file)
    #i.META.logToStdOutput = True
    i.doImport()
    # only returning top-level elements?
    assert i.total == 1
    deck.close()
Beispiel #22
0
def test_csv():
    deck = Deck()
    deck.addModel(BasicModel())
    file = unicode(os.path.join(testDir, "importing/text-2fields.txt"))
    i = csvfile.TextImporter(deck, file)
    i.doImport()
    # four problems - missing front, dupe front, wrong num of fields
    assert len(i.log) == 4
    assert i.total == 5
    deck.close()
Beispiel #23
0
def test_csv_tags():
    deck = Deck()
    deck.addModel(BasicModel())
    file = unicode(os.path.join(testDir, "importing/text-tags.txt"))
    i = csvfile.TextImporter(deck, file)
    i.doImport()
    facts = deck.db.query(Fact).all()
    assert len(facts) == 2
    assert facts[0].tags == "baz qux" or facts[1].tags == "baz qux"
    deck.close()
Beispiel #24
0
def test_create():
    global newPath, newMod
    path = "/tmp/test_attachNew.anki"
    try:
        os.unlink(path)
    except OSError:
        pass
    deck = Deck(path)
    # for open()
    newPath = deck.path
    deck.save()
    newMod = deck.mod
    deck.close()
    del deck
Beispiel #25
0
def test_export_anki():
    oldTime = deck.modified
    e = AnkiExporter(deck)
    newname = unicode(tempfile.mkstemp(prefix="ankitest")[1])
    os.unlink(newname)
    e.exportInto(newname)
    assert deck.modified == oldTime
    # connect to new deck
    d2 = Deck(newname, backup=False)
    assert d2.cardCount() == 4
    # try again, limited to a tag
    newname = unicode(tempfile.mkstemp(prefix="ankitest")[1])
    os.unlink(newname)
    e.limitTags = ['tag']
    e.exportInto(newname)
    d2 = Deck(newname, backup=False)
    assert d2.cardCount() == 2
Beispiel #26
0
def test_anki10():
    # though these are not modified, sqlite updates the mtime, so copy to tmp
    # first
    file_ = unicode(os.path.join(testDir, "importing/test10.anki"))
    file = "/tmp/test10.anki"
    shutil.copy(file_, file)
    file2_ = unicode(os.path.join(testDir, "importing/test10-2.anki"))
    file2 = "/tmp/test10-2.anki"
    shutil.copy(file2_, file2)
    deck = Deck()
    i = anki10.Anki10Importer(deck, file)
    i.doImport()
    assert i.total == 2
    deck.db.rollback()
    deck.close()
    # import a deck into itself - 10-2 is the same as test10, but with one
    # card answered and another deleted. nothing should be synced to client
    deck = Deck(file, backup=False)
    i = anki10.Anki10Importer(deck, file2)
    i.doImport()
    assert i.total == 0
    deck.db.rollback()
Beispiel #27
0
def test_updating():
    # get the standard csv deck first
    deck = Deck()
    deck.addModel(BasicModel())
    file = unicode(os.path.join(testDir, "importing/text-2fields.txt"))
    i = csvfile.TextImporter(deck, file)
    i.doImport()
    # now update
    file = unicode(os.path.join(testDir, "importing/text-update.txt"))
    i = csvfile.TextImporter(deck, file)
    # first field
    i.updateKey = (0, deck.currentModel.fieldModels[0].id)
    i.multipleCardsAllowed = False
    i.doImport()
    ans = deck.db.scalar(
        u"select answer from cards where question like '%食べる%'")
    assert "to ate" in ans
    # try again with tags
    i.updateKey = (0, deck.currentModel.fieldModels[0].id)
    i.mapping[1] = 0
    i.doImport()
    deck.close()
Beispiel #28
0
def test_anki10_modtime():
    deck1 = Deck()
    deck2 = Deck()
    client = SyncClient(deck1)
    server = SyncServer(deck2)
    client.setServer(server)
    deck1.addModel(BasicModel())
    f = deck1.newFact()
    f['Front'] = u"foo"
    f['Back'] = u"bar"
    deck1.addFact(f)
    assert deck1.cardCount() == 1
    assert deck2.cardCount() == 0
    client.sync()
    assert deck1.cardCount() == 1
    assert deck2.cardCount() == 1
    file_ = unicode(os.path.join(testDir, "importing/test10-3.anki"))
    file = "/tmp/test10-3.anki"
    shutil.copy(file_, file)
    i = anki10.Anki10Importer(deck1, file)
    i.doImport()
    client.sync()
    assert i.total == 1
    assert deck2.db.scalar("select count(*) from cards") == 2
    assert deck2.db.scalar("select count(*) from facts") == 2
    assert deck2.db.scalar("select count(*) from models") == 2
Beispiel #29
0
def test_anki10_modtime():
    deck1 = Deck()
    deck2 = Deck()
    client = SyncClient(deck1)
    server = SyncServer(deck2)
    client.setServer(server)
    deck1.addModel(BasicModel())
    f = deck1.newFact()
    f['Front'] = u"foo"; f['Back'] = u"bar"
    deck1.addFact(f)
    assert deck1.cardCount() == 1
    assert deck2.cardCount() == 0
    client.sync()
    assert deck1.cardCount() == 1
    assert deck2.cardCount() == 1
    file_ = unicode(os.path.join(testDir, "importing/test10-3.anki"))
    file = "/tmp/test10-3.anki"
    shutil.copy(file_, file)
    i = anki10.Anki10Importer(deck1, file)
    i.doImport()
    client.sync()
    assert i.total == 1
    assert deck2.db.scalar("select count(*) from cards") == 2
    assert deck2.db.scalar("select count(*) from facts") == 2
    assert deck2.db.scalar("select count(*) from models") == 2
Beispiel #30
0
def setup_local(loadDecks=None):
    global deck1, deck2, client, server
    if loadDecks:
        deck1 = Deck(loadDecks[0], backup=False)
        deck2 = Deck(loadDecks[1], backup=False)
    else:
        deck1 = Deck()
        deck1.addModel(BasicModel())
        deck1.currentModel.cardModels[1].active = True
        deck1.newCardOrder = 1
        f = deck1.newFact()
        f['Front'] = u"foo"; f['Back'] = u"bar"; f.tags = u"foo"
        deck1.addFact(f)
        deck2 = Deck()
        deck2.addModel(BasicModel())
        deck2.currentModel.cardModels[1].active = True
        f = deck2.newFact()
        f['Front'] = u"baz"; f['Back'] = u"qux"; f.tags = u"bar"
        deck2.addFact(f)
        deck2.newCardOrder = 1
    # normally such syncs would trigger a conflict, but we ignore it
    deck1.setVar("schemaMod", 0)
    deck2.setVar("schemaMod", 0)
    client = SyncClient(deck1)
    server = SyncServer(deck2)
    client.setServer(server)
Beispiel #31
0
def getEmptyDeck():
    (fd, nam) = tempfile.mkstemp(suffix=".anki")
    os.unlink(nam)
    return Deck(nam)
Beispiel #32
0
def setup_local(loadDecks=None):
    global deck1, deck2, client, server
    if loadDecks:
        deck1 = Deck(loadDecks[0], backup=False)
        deck2 = Deck(loadDecks[1], backup=False)
    else:
        deck1 = Deck()
        deck1.addModel(BasicModel())
        deck1.currentModel.cardModels[1].active = True
        deck1.newCardOrder = 1
        f = deck1.newFact()
        f['Front'] = u"foo"
        f['Back'] = u"bar"
        f.tags = u"foo"
        deck1.addFact(f)
        deck2 = Deck()
        deck2.addModel(BasicModel())
        deck2.currentModel.cardModels[1].active = True
        f = deck2.newFact()
        f['Front'] = u"baz"
        f['Back'] = u"qux"
        f.tags = u"bar"
        deck2.addFact(f)
        deck2.newCardOrder = 1
    # normally such syncs would trigger a conflict, but we ignore it
    deck1.setVar("schemaMod", 0)
    deck2.setVar("schemaMod", 0)
    client = SyncClient(deck1)
    server = SyncServer(deck2)
    client.setServer(server)
Beispiel #33
0
def test_open():
    deck = Deck(newPath)
    assert deck.mod == newMod
    deck.close()
Beispiel #34
0
def test_open():
    deck = Deck(newPath)
    assert deck.mod == newMod
    deck.close()
Beispiel #35
0
def setup_local(loadDecks=None):
    global deck1, deck2, client, server
    if loadDecks:
        deck1 = Deck(loadDecks[0], backup=False)
        deck2 = Deck(loadDecks[1], backup=False)
    else:
        deck1 = getEmptyDeck()
        f = deck1.newFact()
        f['Front'] = u"foo"; f['Back'] = u"bar"; f.tags = [u"foo"]
        deck1.addFact(f)
        deck1.syncName = "abc"
        deck2 = getEmptyDeck()
        f = deck2.newFact()
        f['Front'] = u"foo"; f['Back'] = u"bar"; f.tags = [u"foo"]
        deck2.addFact(f)
        deck2.syncName = "abc"
        deck1.lastSync = deck2.lastSync = intTime()
        deck1.scm = deck2.scm = 0
        time.sleep(1)
        # now add another fact to deck1 that hasn't been synced yet
        f = deck1.newFact()
        f['Front'] = u"bar"; f['Back'] = u"baz"
        deck1.addFact(f)
        # and another to deck2
        f = deck2.newFact()
        f['Front'] = u"qux"; f['Back'] = u"baz"
        deck2.addFact(f)
        deck2.reset()
        c = deck2.sched.getCard()
        deck2.sched.answerCard(c, 3)
        # change deck1's model
        deck1.currentModel().flush()
        deck1.save(); deck2.save()
    client = SyncClient(deck1)
    server = SyncServer(deck2)
    print "deck1", client.deck.db.all("select * from facts")
    print "deck2", server.deck.db.all("select * from facts")
    client.setServer(server)