Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Deck Configurations #45

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions genanki/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from .model import Model
from .note import Note
from .package import Package
from .deck_conf import DeckConf

from .util import guid_for

Expand Down
9 changes: 7 additions & 2 deletions genanki/deck.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import json

class Deck:
def __init__(self, deck_id=None, name=None, description=''):
def __init__(self, deck_id=None, name=None, description='', conf=None):
self.deck_id = deck_id
self.name = name
self.description = description
self.conf = conf
self.notes = []
self.models = {} # map of model id to model

Expand All @@ -15,9 +16,10 @@ def add_model(self, model):
self.models[model.model_id] = model

def to_json(self):
conf = 1 if self.conf is None else self.conf.deck_conf_id
return {
"collapsed": False,
"conf": 1,
"conf": conf,
"desc": self.description,
"dyn": 0,
"extendNew": 0,
Expand Down Expand Up @@ -55,6 +57,9 @@ def write_to_db(self, cursor, timestamp: float, id_gen):
decks.update({str(self.deck_id): self.to_json()})
cursor.execute('UPDATE col SET decks = ?', (json.dumps(decks),))

if self.conf is not None:
self.conf.write_to_db(cursor, timestamp)

models_json_str, = cursor.execute('SELECT models from col').fetchone()
models = json.loads(models_json_str)
for note in self.notes:
Expand Down
68 changes: 68 additions & 0 deletions genanki/deck_conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@

import copy
import json


DEFAULT_CONF = {
"autoplay": True,
"id": 1,
"lapse": {
"delays": [
10
],
"leechAction": 0,
"leechFails": 8,
"minInt": 1,
"mult": 0
},
"maxTaken": 60,
"mod": 0,
"name": "Default",
"new": {
"bury": True,
"delays": [
1,
10
],
"initialFactor": 2500,
"ints": [
1,
4,
7
],
"order": 1,
"perDay": 20,
"separate": True
},
"replayq": True,
"rev": {
"bury": True,
"ease4": 1.3,
"fuzz": 0.05,
"ivlFct": 1,
"maxIvl": 36500,
"minSpace": 1,
"perDay": 100
},
"timer": 0,
"usn": 0
}


class DeckConf:
def __init__(self, deck_conf_id, name, conf=None):
self.deck_conf_id = deck_conf_id
self.name = name
conf = copy.deepcopy(DEFAULT_CONF) if conf is None else conf
conf["name"] = self.name
conf["id"] = self.deck_conf_id
self.conf = conf

def to_json(self):
return self.conf

def write_to_db(self, cursor, timestamp):
conf_json_str, = cursor.execute('SELECT dconf FROM col').fetchone()
confs = json.loads(conf_json_str)
confs.update({str(self.deck_conf_id): self.to_json()})
cursor.execute('UPDATE col SET dconf = ?', (json.dumps(confs),))
41 changes: 41 additions & 0 deletions tests/test_genanki.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,3 +447,44 @@ def test_notes_with_due2(self):
# Next card changes to "Capital of Oregon", because it has lower
# due value.
assert next_note.fields == ['Capital of Oregon', 'Salem']

def test_deck_with_config(self):
conf = genanki.DeckConf(666, 'MyConf')
# Changing default initialFactor from 2500 to 4500
conf.conf['new']['initialFactor'] = 4500
deck = genanki.Deck(112233, 'foodeck', conf=conf)
# The Anki importer need at least one card to import the config.
# See related discussion:
# https://anki.tenderapp.com/discussions/ankidesktop/38114-importing-apkg-does-not-update-deck-config-fields
note = genanki.Note(TEST_MODEL, ['a', 'b'])
deck.add_note(note)

self.import_package(genanki.Package(deck))

all_confs = self.col.decks.allConf()
assert len(all_confs) == 2 # default conf and MyConf
imported_deck = all_confs[1]

assert imported_deck['new']['initialFactor'] == 4500

def test_deck_with_2_config(self):
conf = genanki.DeckConf(666, 'MyConf')
conf.conf['new']['initialFactor'] = 4500
deck = genanki.Deck(112233, 'foodeck', conf=conf)
note = genanki.Note(TEST_MODEL, ['a', 'b'])
deck.add_note(note)

self.import_package(genanki.Package(deck))
conf = genanki.DeckConf(6666, 'MyConf2')
conf.conf['new']['initialFactor'] = 5500
deck = genanki.Deck(11223344, 'boodeck', conf=conf)
note = genanki.Note(TEST_MODEL, ['a', 'b'])
deck.add_note(note)

self.import_package(genanki.Package(deck))

all_confs = self.col.decks.allConf()
assert len(all_confs) == 2 # default conf and MyConf
imported_deck = all_confs[1]

assert imported_deck['new']['initialFactor'] == 4500