def test_create_open(): (fd, path) = tempfile.mkstemp(suffix=".anki2", prefix="test_attachNew") try: os.close(fd) os.unlink(path) except OSError: pass deck = aopen(path) # for open() newPath = deck.path deck.close() newMod = deck.mod del deck # reopen deck = aopen(newPath) assert deck.mod == newMod deck.close() # non-writeable dir if isWin: dir = "c:\root.anki2" else: dir = "/attachroot.anki2" assertException(Exception, lambda: aopen(dir)) # reuse tmp file from before, test non-writeable file os.chmod(newPath, 0) assertException(Exception, lambda: aopen(newPath)) os.chmod(newPath, 0o666) os.unlink(newPath)
def test_export_anki(): # create a new deck with its own conf to test conf copying did = deck.decks.id("test") dobj = deck.decks.get(did) confId = deck.decks.confId("newconf") conf = deck.decks.getConf(confId) conf['new']['perDay'] = 5 deck.decks.save(conf) deck.decks.setConf(dobj, confId) # export e = AnkiExporter(deck) newname = unicode(tempfile.mkstemp(prefix="ankitest", suffix=".anki2")[1]) os.unlink(newname) e.exportInto(newname) # exporting should not have changed conf for original deck conf = deck.decks.confForDid(did) assert conf['id'] != 1 # connect to new deck d2 = aopen(newname) assert d2.cardCount() == 2 # as scheduling was reset, should also revert decks to default conf did = d2.decks.id("test", create=False) assert did conf2 = d2.decks.confForDid(did) assert conf2['new']['perDay'] == 20 dobj = d2.decks.get(did) # conf should be 1 assert dobj['conf'] == 1 # try again, limited to a deck newname = unicode(tempfile.mkstemp(prefix="ankitest", suffix=".anki2")[1]) os.unlink(newname) e.did = 1 e.exportInto(newname) d2 = aopen(newname) assert d2.cardCount() == 1
def test_create_open(): global newPath, newMod (fd, path) = tempfile.mkstemp(suffix=".anki2", prefix="test_attachNew") try: os.close(fd) os.unlink(path) except OSError: pass deck = aopen(path) # for open() newPath = deck.path deck.close() newMod = deck.mod del deck # reopen deck = aopen(newPath) assert deck.mod == newMod deck.close() # non-writeable dir assertException(Exception, lambda: aopen("/attachroot.anki2")) # reuse tmp file from before, test non-writeable file os.chmod(newPath, 0) assertException(Exception, lambda: aopen(newPath)) os.chmod(newPath, 0o666) os.unlink(newPath)
def test_openReadOnly(): # non-writeable dir assertException(Exception, lambda: aopen("/attachroot.anki2")) # reuse tmp file from before, test non-writeable file os.chmod(newPath, 0) assertException(Exception, lambda: aopen(newPath)) os.chmod(newPath, 0666) os.unlink(newPath)
def getEmptyDeck(): if len(getEmptyDeck.master) == 0: (fd, nam) = tempfile.mkstemp(suffix=".anki2") os.unlink(nam) col = aopen(nam) col.db.close() getEmptyDeck.master = nam (fd, nam) = tempfile.mkstemp(suffix=".anki2") shutil.copy(getEmptyDeck.master, nam) return aopen(nam)
def getEmptyCol(): if len(getEmptyCol.master) == 0: (fd, nam) = tempfile.mkstemp(suffix=".anki2") os.close(fd) os.unlink(nam) col = aopen(nam) col.close(downgrade=False) getEmptyCol.master = nam (fd, nam) = tempfile.mkstemp(suffix=".anki2") shutil.copy(getEmptyCol.master, nam) col = aopen(nam) return col
def getEmptyCol(schedVer=1): if len(getEmptyCol.master) == 0: (fd, nam) = tempfile.mkstemp(suffix=".anki2") os.close(fd) os.unlink(nam) col = aopen(nam) col.db.close() getEmptyCol.master = nam (fd, nam) = tempfile.mkstemp(suffix=".anki2") shutil.copy(getEmptyCol.master, nam) from anki.collection import _Collection _Collection.defaultSchedulerVersion = schedVer col = aopen(nam) _Collection.defaultSchedulerVersion = 1 return col
def test_export_anki(): e = AnkiExporter(deck) newname = unicode(tempfile.mkstemp(prefix="ankitest", suffix=".anki2")[1]) os.unlink(newname) e.exportInto(newname) # connect to new deck d2 = aopen(newname) assert d2.cardCount() == 2 # try again, limited to a deck newname = unicode(tempfile.mkstemp(prefix="ankitest", suffix=".anki2")[1]) os.unlink(newname) e.did = 1 e.exportInto(newname) d2 = aopen(newname) assert d2.cardCount() == 1
def test_graphs(): from anki import Collection as aopen d = aopen(os.path.expanduser("~/test.anki2")) g = d.stats() rep = g.report() open(os.path.expanduser("~/test.html"), "w").write(rep) return
def make_cards(card_front, card_back, SUBSECTION): col = aopen(aPATH) mm = col.models dm = col.decks col.media.addFile(card_front.decode('utf-8')) col.media.addFile(card_back.decode('utf-8')) mname = 'AnkiFlash' dname = 'Flashcards' + '::' + 'Pathophysiology of Disease::{}'.format(SUBSECTION) did = dm.id(dname) dm.select(did) model = mm.byName(mname) if model is None: model = flash_theme(mname, mm) model['did'] = did mm.save(model) mm.setCurrent(model) card = col.newNote() card['Note ID'] = str(card.id) card['Front'] = u'<img src="%s">' % os.path.basename(card_front) card['Back'] = u'<img src="%s">' % os.path.basename(card_back) card.tags = [SUBSECTION.replace(' ', '-')] col.addNote(card) col.save() col.close()
def test_threeway(): test_sync() deck1.close(save=False) d3path = deck1.path.replace(".anki", "2.anki") shutil.copy2(deck1.path, d3path) deck1.reopen() deck3 = aopen(d3path) client2 = Syncer(deck3, server) assert client2.sync() == "noChanges" # client 1 adds a card at time 1 time.sleep(1) f = deck1.newNote() f['Front'] = "1" deck1.addNote(f) deck1.save() # at time 2, client 2 syncs to server time.sleep(1) deck3.setMod() deck3.save() assert client2.sync() == "success" # at time 3, client 1 syncs, adding the older note time.sleep(1) assert client.sync() == "success" assert deck1.noteCount() == deck2.noteCount() # syncing client2 should pick it up assert client2.sync() == "success" assert deck1.noteCount() == deck2.noteCount() == deck3.noteCount()
def make_cards(deck_title, front, back): a_coll = aopen(coll_path) deck_name = 'Quizlet' + '::' + deck_title deck_id = a_coll.decks.id(deck_name) a_coll.decks.select(deck_id) model = a_coll.models.byName(card_type) model['did'] = deck_id a_coll.models.save(model) a_coll.models.setCurrent(model) card = a_coll.newNote() if 'http' not in front: card['Front'] = front else: img_path = get_img(front) a_coll.media.addFile(img_path.decode('utf-8')) card['Front'] = u'<img src="%s">' % ntpath.basename(img_path) os.remove(img_path) card['Back'] = back card.tags = tags a_coll.addNote(card) a_coll.save() a_coll.close()
def test_threeway(): test_sync() deck1.close(save=False) d3path = deck1.path.replace(".anki", "2.anki") shutil.copy2(deck1.path, d3path) deck1.reopen() deck3 = aopen(d3path) client2 = Syncer(deck3, server) assert client2.sync() == "noChanges" # client 1 adds a card at time 1 time.sleep(1) f = deck1.newNote() f['Front'] = u"1"; deck1.addNote(f) deck1.save() # at time 2, client 2 syncs to server time.sleep(1) deck3.setMod() deck3.save() assert client2.sync() == "success" # at time 3, client 1 syncs, adding the older note time.sleep(1) assert client.sync() == "success" assert deck1.noteCount() == deck2.noteCount() # syncing client2 should pick it up assert client2.sync() == "success" assert deck1.noteCount() == deck2.noteCount() == deck3.noteCount()
def make_cards(card_front, card_back, img, rx_tags): fpath = img.decode('utf-8') fname = ntpath.basename(fpath).decode('utf-8') a_coll = aopen(coll_path) a_coll.media.addFile(fpath) card_type = 'Basic' deck_name = 'USMLErx' deck_id = a_coll.decks.id(deck_name) a_coll.decks.select(deck_id) model = a_coll.models.byName(card_type) model['did'] = deck_id a_coll.models.save(model) a_coll.models.setCurrent(model) card = a_coll.newNote() card['Front'] = card_front.decode('utf-8') card['Back'] = card_back.decode('utf-8') card['Back Image'] = u'<img src="%s">' % fname card.tags = rx_tags a_coll.addNote(card) a_coll.save() a_coll.close()
def make_cards(card_front, card_back): col = aopen(aPATH) mm = col.models dm = col.decks col.media.addFile(card_front.decode('utf-8')) col.media.addFile(card_back.decode('utf-8')) mname = 'AnkiFlash' dname = 'Flashcards' + '::' + DECK_NAME did = dm.id(dname) dm.select(did) model = mm.byName(mname) if model is None: model = flash_theme(mname, mm) model['did'] = did mm.save(model) mm.setCurrent(model) card = col.newNote() card['Front'] = u'<img src="%s">' % os.path.basename(card_front) card['Back'] = u'<img src="%s">' % os.path.basename(card_back) col.addNote(card) col.save() col.close()
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 = aopen(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 = aopen(newname, backup=False) assert d2.cardCount() == 2
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 = aopen(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 = aopen(newname, backup=False) assert d2.cardCount() == 2
def test_graphs(): from anki import Collection as aopen dir = tempfile.gettempdir() d = aopen(os.path.join(dir, "test.anki2")) g = d.stats() rep = g.report() with open(os.path.join(dir, "test.html"), "w") as f: f.write(rep) return
def setup1(): global deck deck = aopen() deck.addModel(BasicModel()) deck.currentModel.cardModels[1].active = True f = deck.newNote() f['Front'] = u"foo"; f['Back'] = u"bar"; f.tags = u"tag, tag2" deck.addNote(f) f = deck.newNote() f['Front'] = u"baz"; f['Back'] = u"qux" deck.addNote(f)
def app(cwd, theme, ankiFilePath): fdeck = lambda: aopen(ankiFilePath) d = {'appPath': cwd, 'themePath': '%s/themes/%s/base.html' % (cwd, theme), 'fdeck': fdeck} return tornado.web.Application([ (r'/anki/decks/*/', IndexHandler, d), (r'/anki/decks/([^/]+)/study', StudyHandler, d), (r'/anki/decks/([^/]+)/reset', ResetHandler, {**d, **{'redirectUrl': '/anki/decks/%s/study'}}) ], debug = True, template_path = '%s/themes/%s/' % (cwd, theme), static_path = '%s/themes/%s/static' % (cwd, theme) )
def test_export_anki(): setup1() # create a new deck with its own conf to test conf copying did = deck.decks.id("test") dobj = deck.decks.get(did) confId = deck.decks.add_config_returning_id("newconf") conf = deck.decks.get_config(confId) conf["new"]["perDay"] = 5 deck.decks.save(conf) deck.decks.setConf(dobj, confId) # export e = AnkiExporter(deck) fd, newname = tempfile.mkstemp(prefix="ankitest", suffix=".anki2") newname = str(newname) os.close(fd) os.unlink(newname) e.exportInto(newname) # exporting should not have changed conf for original deck conf = deck.decks.confForDid(did) assert conf["id"] != 1 # connect to new deck d2 = aopen(newname) assert d2.cardCount() == 2 # as scheduling was reset, should also revert decks to default conf did = d2.decks.id("test", create=False) assert did conf2 = d2.decks.confForDid(did) assert conf2["new"]["perDay"] == 20 dobj = d2.decks.get(did) # conf should be 1 assert dobj["conf"] == 1 # try again, limited to a deck fd, newname = tempfile.mkstemp(prefix="ankitest", suffix=".anki2") newname = str(newname) os.close(fd) os.unlink(newname) e.did = 1 e.exportInto(newname) d2 = aopen(newname) assert d2.cardCount() == 1
def test_create(): global newPath, newMod path = "/tmp/test_attachNew.anki2" try: os.unlink(path) except OSError: pass deck = aopen(path) # for open() newPath = deck.path deck.close() newMod = deck.mod del deck
def setup1(): global deck deck = aopen() deck.addModel(BasicModel()) deck.currentModel.cardModels[1].active = True f = deck.newNote() f["Front"] = u"foo" f["Back"] = u"bar" f.tags = u"tag, tag2" deck.addNote(f) f = deck.newNote() f["Front"] = u"baz" f["Back"] = u"qux" deck.addNote(f)
def initAnkiModule(data, collection, card_type): if bool(collection) == False or "deck" not in data: print('Collection or deck is not found!') return None deck = aopen(collection) deckId = deck.decks.id(data['deck']) deck.decks.select(deckId) model = deck.models.byName(card_type.GetCardType(deck.models)) if model is not None: model['did'] = deckId deck.models.save(model) deck.models.setCurrent(model) return deck
def test_create(): global newPath, newMod (fd, path) = tempfile.mkstemp(suffix=".anki2", prefix="test_attachNew") try: os.close(fd) os.unlink(path) except OSError: pass deck = aopen(path) # for open() newPath = deck.path deck.close() newMod = deck.mod del deck
def writeSeries(year, winner, loser, mvp, sport): deck = aopen(path) deck_id = deck.decks.id('Sports') deck.decks.select(deck_id) model = deck.models.byName('Basic') model['did'] = deck_id deck.models.save(model) deck.models.setCurrent(model) fact = deck.newNote() fact['Front'] = frontDict[sport].format(year) fact['Back'] = '{} > {}<br><br>MVP:<br>{}'.format(winner, loser, mvp) deck.addNote(fact) deck.save() deck.close()
def get_cards_from_deck(deck_name): # copied from $HOME/.local/share/Anki2/anki-code path = '%s/data/profile/collection.anki2' % os.getcwd() collection = aopen(path) # linux deck_id = collection.decks.id(deck_name) collection.decks.select(deck_id) card = collection.sched.getCard() # next in schedule note = card.note() return { 'card': card, 'note': note, }
def getEmptyCol(scheduler='anki.sched.Scheduler'): from anki.collection import _Collection import anki.sched import anki.schedv2 import anki.schedv3 # TODO: Not create a file every time (fd, nam) = tempfile.mkstemp(suffix=".anki2") os.close(fd) os.unlink(nam) anki.collection.defaultConf['usedScheduler'] = scheduler _Collection.defaultScheduler = (scheduler) col = aopen(nam) return col
def run_tests(): col_filename = os.path.join(os.path.dirname(__file__), 'test_collection.anki2') tmp_filename = os.path.join(os.path.dirname(__file__), 'tmp.anki2') shutil.copy(col_filename, tmp_filename) col = aopen(tmp_filename) rbd = db.RememberberryDatabase('rb.db', col, completed_hsk_lvl=4) t0 = time() rbd.init(['all::chinese'], ['SpoonFedChinese']) t1 = time() print('Initialization took %f s' % (t1 - t0)) # Find an nid with several items which links to it rbd.attach() c = rbd._get_cursor() c.execute(''' SELECT nid, from_hash, to_hash, COUNT(*) FROM rb.item_links JOIN rb.note_links ON to_hash=hash GROUP BY to_hash HAVING COUNT(*) > 1 ''') res = c.fetchone() nid, form_hash, to_hash, count = res # Update the reps parameter c.execute(''' UPDATE cards SET reps=reps+1 WHERE nid=? ''', (nid, )) # Update the rememberberry database t0 = time() new, changed, parents = rbd.update(['all::chinese']) t1 = time() print('Update took %f s' % (t1 - t0)) # Make sure the item corresponding to the card was updated, and all sentences assert new == 0 assert changed == 1 assert parents == count results = rbd.search(limit=10, num_unknown=1) for i in range(10): print(results[i][0]) print('------------') for w in results[i][1]: print(w) print('=================')
def make_cards(self, section, subsection, cards): from anki import Collection as aopen try: #print [(card[0].encode('UTF-8'), card[1].encode('UTF-8')) for card in cards] for card in cards: print 'SECTION: {}\nSUBSECTION: {}'.format(section, subsection) col = aopen('/Users/drlulz/Documents/Anki/DrLulz/collection.anki2') mm = col.models dm = col.decks # col.media.addFile(card_front.decode('utf-8')) mname = 'AnkiFlash-IME' dname = 'Flashcards' + '::' + 'IM Essentials::{}::{}'.format(section, subsection) did = dm.id(dname) dm.select(did) model = mm.byName(mname) if model is None: model = self.flash_theme(mname, mm) model['did'] = did mm.save(model) mm.setCurrent(model) FRONT = u''.join(unicode(i) for i in card[0]) BACK = u''.join(unicode(i) for i in card[1]) card = col.newNote() card['Note ID'] = str(card.id) card['Front'] = FRONT card['Back'] = BACK card.tags = [subsection.replace(' ', '-')] col.addNote(card) col.save() col.close() except: self.error()
def _test_speed(): t = time.time() deck1 = aopen(os.path.expanduser("~/rapid.anki")) for tbl in "revlog", "cards", "notes", "graves": deck1.db.execute("update %s set usn = -1 where usn != -1"%tbl) for m in deck1.models.all(): m['usn'] = -1 for tx in deck1.tags.all(): deck1.tags.tags[tx] = -1 deck1._usn = -1 deck1.save() deck2 = getEmptyDeck(server=True) deck1.scm = deck2.scm = 0 server = LocalServer(deck2) client = Syncer(deck1, server) print "load %d" % ((time.time() - t)*1000); t = time.time() assert client.sync() == "success" print "sync %d" % ((time.time() - t)*1000); t = time.time()
def main(): config.init() x = aopen(config.db_path()) mode.init(x) while True: try: card = mode.make_card() card.input() card.output() if yes_no_p('Save card?'): card.save(x) else: clear_staged_images() print_subdued('Card dropped!', nl=2) except EOFError: clear_staged_images() print() except KeyboardInterrupt: x.close() sys.exit()
def make_cards(cards): qas = get_cards(cards) card_type = 'Basic' deck_name = 'iknow_200' for qa in qas: card_front = itemgetter(0)(qa) card_back = itemgetter(1)(qa) card_pos = itemgetter(2)(qa) deck = aopen(anki_coll) deck_id = deck.decks.id(deck_name) deck.decks.select(deck_id) model = deck.models.byName(card_type) model['did'] = deck_id deck.models.save(model) deck.models.setCurrent(model) fact = deck.newNote() fact['Front'] = card_front.decode('utf-8') fact['Back'] = card_back.decode('utf-8') #fact['Desc'] = card_pos.decode('utf-8') deck.addNote(fact) deck.save() deck.close()
def make_card(FRONT_IMG, ANSWER, ANS_IMG, BACK_IMG): col = aopen(aPATH) mm = col.models dm = col.decks col.media.addFile(FRONT_IMG.decode('utf-8')) col.media.addFile(ANS_IMG.decode('utf-8')) if BACK_IMG: col.media.addFile(BACK_IMG.decode('utf-8')) mname = 'EM-Atlas' dname = DECK_NAME did = dm.id(dname) dm.select(did) model = mm.byName(mname) if model is None: model = flash_theme(mname, mm) model['did'] = did mm.save(model) mm.setCurrent(model) card = col.newNote() card['Note ID'] = str(card.id) card['Front'] = u'<img src="%s">' % os.path.basename(FRONT_IMG) if BACK_IMG: card['Back']= u'<span class="highlight" style="font-weight: bold; color:#FFFFFF"> ' + ANSWER + u' </span>' + u'<img src="%s">' % os.path.basename(BACK_IMG) else: card['Back']= u'<span class="highlight" style="font-weight: bold; color:#FFFFFF"> ' + ANSWER + u' </span>' card['B Note'] = u'<img src="%s">' % os.path.basename(ANS_IMG) card.tags = [ANSWER.replace(' ', '-')] col.addNote(card) col.save() col.close()
def create(self, card_front, card_back): logging.info("Get Collection/Deck '" + self.coll_file + "/" + self.deck_name + "'") deck = aopen(self.coll_file) deckId = deck.decks.id(self.deck_name) deck.decks.select(deckId) basic_model = deck.models.byName('Basic') basic_model['did'] = deckId deck.models.save(basic_model) deck.models.setCurrent(basic_model) # todo I don't see any other ways to prevent creating a new Deck if deck.cardCount == 0: sys.exit("ERROR: Collection/Deck '" + coll_file + "/" + deck_name + "' does not exist.") logging.info("Deck has " + str(deck.cardCount()) + " cards") logging.info("Make a new Card for: " + card_front) fact = deck.newNote() fact['Front'] = card_front fact['Back'] = card_back # Add Card to the Deck try: deck.addNote(fact) except: if hasattr(e, "data"): sys.exit("ERROR: Could not add '" + e.data['field'] + "': " + e.data['type']) else: sys.exit(e) # Done. logging.info("Save the Deck") deck.save() deck.close()
def test_remoteSync(): if not TEST_REMOTE: return # not yet associated, so will require a full sync assert ts.client.sync() == "fullSync" # upload f = FullSyncer(ts.client.col, TEST_HKEY, ts.server.con) f.upload() ts.client.col.reopen() # should report no changes assert ts.client.sync() == "noChanges" # bump local col ts.client.col.setMod() ts.client.col.save() assert ts.client.sync() == "success" # again, no changes assert ts.client.sync() == "noChanges" # downloading the remote col should give us the same mod lmod = ts.client.col.mod f = FullSyncer(ts.client.col, TEST_HKEY, ts.server.con) f.download() d = aopen(ts.client.col.path) assert d.mod == lmod
def getEmptyDeckWith(**kwargs): (fd, nam) = tempfile.mkstemp(suffix=".anki2") os.close(fd) os.unlink(nam) return aopen(nam, **kwargs)
def __init__(self, apath): from anki import Collection as aopen self.col = aopen(apath) self.dm = self.col.decks self.mm = self.col.models
from anki import Collection as aopen if __name__ != '__main__' or len(sys.argv) < 5: sys.exit("Usage: "+sys.argv[0]+" '<collection path>' '<deck name>' '<card front>' '<card back>'") # Mung arguments coll_file = sys.argv[1] deck_name = sys.argv[2] card_front = sys.argv[3] card_back = sys.argv[4] # todo Not even this works. It refuses to embed the newlines in the Card card_back = re.sub(r"\\n", "\n", card_back) # All Decks are in a single Collection print("Get Collection/Deck '"+coll_file+"/"+deck_name+"'") deck = aopen( coll_file ); deckId = deck.decks.id( deck_name ) # todo Not sure why a simple 'select' doesnt do the model stuff for me... deck.decks.select( deckId ) basic_model = deck.models.byName('Basic') basic_model['did'] = deckId deck.models.save( basic_model ) deck.models.setCurrent( basic_model ) # todo I don't see any other ways to prevent creating a new Deck if deck.cardCount == 0: sys.exit("ERROR: Collection/Deck '"+coll_file+"/"+deck_name+"' does not exist.") print("Deck has "+str(deck.cardCount())+" cards")
def test_open(): deck = aopen(newPath) assert deck.mod == newMod deck.close()