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

Add deck and note options. #12

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Add per-note options and a deck creation time.
* A correct deck creation time is necessary since card due dates are
  defined relative to it.
  • Loading branch information
holocronweaver committed Aug 18, 2017
commit eab7246ee80a67512067a0cda73433609d290514
61 changes: 39 additions & 22 deletions genanki/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from cached_property import cached_property
from copy import copy
import json
from datetime import datetime
import hashlib
import json
import os
import pystache
import sqlite3
Expand Down Expand Up @@ -155,25 +156,30 @@ class Card:
def __init__(self, ord_):
self.ord = ord_

def write_to_db(self, cursor, now_ts, deck_id, note_id):
self.interval = 0

def write_to_db(self, cursor, now_ts, deck_id, note_id,
level, due, interval, ease, reps_til_grad):
cursor.execute('INSERT INTO cards VALUES(null,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);', (
note_id, # nid
deck_id, # did
self.ord, # ord
now_ts, # mod
-1, # usn
0, # type (=0 for non-Cloze)
0, # queue
0, # due
0, # ivl
0, # factor
0, # reps
0, # lapses
0, # left
0, # odue
0, # odid
0, # flags
"", # data
note_id, # nid - note ID
deck_id, # did - deck ID
self.ord, # ord - which card template it corresponds
now_ts, # mod - modification time as epoch seconds
-1, # usn - value of -1 indicates need to push to server
level, # type - 0=new, 1=learning, 2=review
level, # queue - same as type unless buried
due, # due - new: unused
# learning: due time as integer seconds since epoch
# review: integer days relative to deck creation
interval, # ivl - positive days, negative seconds
ease, # factor - integer ease factor used by SRS, 2500 = 250%
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think all these properties should be attributes of the Card object, not the Note object, since you can set them per-card.

So the user would do something like this:

my_note = Note(...)
...
my_note.cards[0].queue = -1

If you have a use case for setting attributes on all cards, you can add a helper function like this:

def set_attributes_on_call_cards(self, **kwargs):
    for card in self.cards:
        for k, v in kwargs.items():
             setattr(card, k, v)

Note: you can skip adding ease, ivl, etc as keyword arguments to Card.__init__. Unlike Note and Deck, the user generally doesn't directly initialize Card instances; instead, they're implicitly initialized when the user creates the Note. So it doesn't make sense to set Card attributes via keyword arguments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okydoke! I actually planned for and forgot to do this, heh.

0, # reps - number of reviews
0, # lapses - # times card went from "answered correctly" to "answered incorrectly"
reps_til_grad, # left - reps left until graduation
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto here. This should be called left. If you want to, you can add a @property that aliases reps_til_grad to left. But the main name of the property should be left.

0, # odue - only used when card is in filtered deck
0, # odid - only used when card is in filtered deck
0, # flags - currently unused
"", # data - currently unused
))


Expand All @@ -189,6 +195,12 @@ def __init__(self, model=None, fields=None, sort_field=None, tags=None, guid=Non
# guid was defined as a property
pass

self.level = 0
self.due = 0
self.interval = 0
self.ease = 1000
self.reps_til_grad = 0

@property
def sort_field(self):
return self._sort_field or self.fields[0]
Expand Down Expand Up @@ -234,7 +246,9 @@ def write_to_db(self, cursor, now_ts, deck_id):

note_id = cursor.lastrowid
for card in self.cards:
card.write_to_db(cursor, now_ts, deck_id, note_id)
card.write_to_db(cursor, now_ts, deck_id, note_id,
self.level, self.due, self.interval,
self.ease, self.reps_til_grad)

def _format_fields(self):
return '\x1f'.join(self.fields)
Expand All @@ -249,7 +263,7 @@ def __init__(self, options_id=1, name='Default'):
self.options_group_name = name
# General.
self.max_time_per_answer = 60
self.show_timer = False # 'false'
self.show_timer = False
self.autoplay_audio = True
self.replay_audio_for_answer = True
# New.
Expand All @@ -259,7 +273,7 @@ def __init__(self, options_id=1, name='Default'):
self.graduating_interval = 1
self.easy_interval = 4
self.starting_ease = 2500
self.new_bury_related_cards = True # 'true'
self.new_bury_related_cards = True
# Reviews.
self.max_reviews_per_day = 100
self.easy_bonus = 1.3
Expand Down Expand Up @@ -302,6 +316,7 @@ def __init__(self, deck_id=None, name=None, options=None):
self.models = {} # map of model id to model
self.description = ''
self.options = options
self.creation_time = datetime.now()

def add_note(self, note):
self.notes.append(note)
Expand All @@ -317,6 +332,8 @@ def write_to_db(self, cursor, now_ts):
params = self.options._format_fields()

params.update({
'creation_time': self.creation_time.timestamp(),
'modification_time': self.creation_time.timestamp() * 1000,
'name': self.name,
'deck_id': self.deck_id,
'models': json.dumps(models),
Expand Down
8 changes: 4 additions & 4 deletions genanki/apkg_col.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
APKG_COL = r'''
INSERT INTO col VALUES(
null,
1411124400,
1425279151694,
1425279151690,
:creation_time,
:modification_time,
:modification_time,
11,
0,
0,
Expand All @@ -15,7 +15,7 @@
"addToCur": true,
"collapseTime": 1200,
"curDeck": 1,
"curModel": "1425279151691",
"curModel": "' || :modification_time || '",
"dueCounts": true,
"estTimes": true,
"newBury": true,
Expand Down