move group code into a registry like models

This commit is contained in:
Damien Elmes 2011-08-27 23:45:55 +09:00
parent d3a3edb707
commit 78600e8ed6
7 changed files with 89 additions and 65 deletions

View file

@ -11,12 +11,12 @@ from anki.hooks import runHook, runFilter
from anki.sched import Scheduler
from anki.models import ModelRegistry
from anki.media import MediaRegistry
from anki.groups import GroupRegistry
from anki.consts import *
from anki.errors import AnkiError
import anki.latex # sets up hook
import anki.cards, anki.facts, anki.template, anki.cram, \
anki.groups, anki.find
import anki.cards, anki.facts, anki.template, anki.cram, anki.find
# Settings related to queue building. These may be loaded without the rest of
# the config to check due counts faster on mobile clients.
@ -54,6 +54,7 @@ class _Deck(object):
self.clearUndo()
self.media = MediaRegistry(self)
self.models = ModelRegistry(self)
self.groups = GroupRegistry(self)
self.load()
if not self.crt:
d = datetime.datetime.today()
@ -88,15 +89,14 @@ class _Deck(object):
self.qconf,
self.conf,
models,
self.groups,
self.gconf) = self.db.first("""
groups,
gconf) = self.db.first("""
select crt, mod, scm, dty, syncName, lastSync,
qconf, conf, models, groups, gconf from deck""")
self.qconf = simplejson.loads(self.qconf)
self.conf = simplejson.loads(self.conf)
self.groups = simplejson.loads(self.groups)
self.gconf = simplejson.loads(self.gconf)
self.models.load(models)
self.groups.load(groups, gconf)
def flush(self, mod=None):
"Flush state to DB, updating mod time."
@ -104,14 +104,13 @@ qconf, conf, models, groups, gconf from deck""")
self.db.execute(
"""update deck set
crt=?, mod=?, scm=?, dty=?, syncName=?, lastSync=?,
qconf=?, conf=?, groups=?, gconf=?""",
qconf=?, conf=?""",
self.crt, self.mod, self.scm, self.dty,
self.syncName, self.lastSync,
simplejson.dumps(self.qconf),
simplejson.dumps(self.conf),
simplejson.dumps(self.groups),
simplejson.dumps(self.gconf))
simplejson.dumps(self.conf))
self.models.flush()
self.groups.flush()
def save(self, name=None, mod=None):
"Flush, commit DB, and take out another write lock."
@ -420,7 +419,7 @@ select id from facts where id in %s and id not in (select fid from cards)""" %
fields[name] = ""
fields['Tags'] = data[5]
fields['Model'] = model['name']
fields['Group'] = self.groupName(data[3])
fields['Group'] = self.groups.name(data[3])
template = model['tmpls'][data[4]]
fields['Template'] = template['name']
# render q & a
@ -504,43 +503,6 @@ update facts set tags = :t, mod = :n where id = :id""", [fix(row) for row in res
def delTags(self, ids, tags):
self.addTags(ids, tags, False)
# Groups
##########################################################################
# the id keys are strings because that's the way they're stored in json,
# but the anki code passes around integers
def groupID(self, name, create=True):
"Add a group with NAME. Reuse group if already exists. Return id."
for id, g in self.groups.items():
if g['name'].lower() == name.lower():
return int(id)
if not create:
return None
g = dict(name=name, conf=1, mod=intTime())
while 1:
id = intTime(1000)
if str(id) in self.groups:
continue
self.groups[str(id)] = g
return id
def groupName(self, gid):
return self.groups[str(gid)]['name']
def groupConf(self, gid):
return self.gconf[str(self.groups[str(gid)]['conf'])]
def delGroup(self, gid):
self.modSchema()
self.db.execute("update cards set gid = 1 where gid = ?", gid)
self.db.execute("update facts set gid = 1 where gid = ?", gid)
self.db.execute("delete from groups where id = ?", gid)
print "fixme: loop through models and update stale gid references"
def setGroup(self, cids, gid):
self.db.execute(
"update cards set gid = ? where id in "+ids2str(cids), gid)
# Tag-based selective study
##########################################################################

View file

@ -192,8 +192,8 @@ order by %s""" % (lim, sort)
def _findGroup(self, val, isNeg):
extra = "!" if isNeg else ""
id = self.deck.groupID(val, create=False) or 0
self.lims['card'].append("c.gid %s= %d" % (extra, id))
id = self.deck.groups.id(val, create=False) or 0
self.lims['card'].append("c.gid %s= %s" % (extra, id))
def _findTemplate(self, val, isNeg):
lims = []

View file

@ -39,3 +39,65 @@ defaultData = {
'activeTags': None,
'inactiveTags': None,
}
class GroupRegistry(object):
# Registry save/load
#############################################################
def __init__(self, deck):
self.deck = deck
def load(self, groups, gconf):
self.groups = simplejson.loads(groups)
self.gconf = simplejson.loads(gconf)
self.changed = False
def save(self, g):
g['mod'] = intTime()
self.changed = True
def flush(self):
if self.changed:
self.deck.db.execute("update deck set groups=?, gconf=?",
simplejson.dumps(self.groups),
simplejson.dumps(self.gconf))
# Group save/load
#############################################################
def id(self, name, create=True):
"Add a group with NAME. Reuse group if already exists. Return id as int."
for id, g in self.groups.items():
if g['name'].lower() == name.lower():
return int(id)
if not create:
return None
g = dict(name=name, conf=1, mod=intTime())
while 1:
id = str(intTime(1000))
if id in self.groups:
continue
self.groups[id] = g
self.save(g)
return int(id)
def del_(self, gid):
self.deck.modSchema()
self.deck.db.execute("update cards set gid = 1 where gid = ?", gid)
self.deck.db.execute("update facts set gid = 1 where gid = ?", gid)
self.deck.db.execute("delete from groups where id = ?", gid)
print "fixme: loop through models and update stale gid references"
# Utils
#############################################################
def name(self, gid):
return self.groups[str(gid)]['name']
def conf(self, gid):
return self.gconf[str(self.groups[str(gid)]['conf'])]
def setGroup(self, cids, gid):
self.db.execute(
"update cards set gid = ? where id in "+ids2str(cids), gid)

View file

@ -154,7 +154,7 @@ from cards group by gid""", self.today):
for (gid, grp) in self._orderedGroups()]
def _orderedGroups(self):
grps = self.deck.groups.items()
grps = self.deck.groups.groups.items()
def key(grp):
return grp[1]['name']
grps.sort(key=key)
@ -595,7 +595,7 @@ queue = 2 %s and due <= :lim order by %s limit %d""" % (
##########################################################################
def _cardConf(self, card):
return self.deck.groupConf(card.gid)
return self.deck.groups.conf(card.gid)
def _groupLimit(self):
l = self.deck.qconf['groups']

View file

@ -49,8 +49,8 @@ class CardStats(object):
self.addLine(_("Position"), c.due)
self.addLine(_("Model"), c.model()['name'])
self.addLine(_("Template"), c.template()['name'])
self.addLine(_("Current Group"), self.deck.groupName(c.gid))
self.addLine(_("Initial Group"), self.deck.groupName(c.fact().gid))
self.addLine(_("Current Group"), self.deck.groups.name(c.gid))
self.addLine(_("Home Group"), self.deck.groups.name(c.fact().gid))
self.txt += "</table>"
return self.txt

View file

@ -133,15 +133,15 @@ def test_upgrade():
def test_groups():
deck = getEmptyDeck()
# we start with a standard group
assert len(deck.groups) == 1
assert len(deck.groups.groups) == 1
# it should have an id of 1
assert deck.groups['1']
assert deck.groups.name(1)
# create a new group
ts = deck.groupID("new group")
assert ts
assert len(deck.groups) == 2
g = deck.groups.id("new group")
assert g
assert len(deck.groups.groups) == 2
# should get the same id
assert deck.groupID("new group") == ts
assert deck.groups.id("new group") == g
# by default, everything should be shown
assert not deck.qconf['groups']

View file

@ -581,7 +581,7 @@ def test_ordcycle():
def test_counts():
d = getEmptyDeck()
# add a second group
assert d.groupID("new group")
assert d.groups.id("new group")
# for each card type
for type in range(3):
# and each of the groups
@ -680,7 +680,7 @@ def test_groupCounts():
# and one that's a child
f = d.newFact()
f['Front'] = u"two"
default1 = f.gid = d.groupID("Default::1")
default1 = f.gid = d.groups.id("Default::1")
d.addFact(f)
# make it a review card
c = f.cards()[0]
@ -690,16 +690,16 @@ def test_groupCounts():
# add one more with a new group
f = d.newFact()
f['Front'] = u"two"
foobar = f.gid = d.groupID("foo::bar")
foobar = f.gid = d.groups.id("foo::bar")
d.addFact(f)
# and one that's a sibling
f = d.newFact()
f['Front'] = u"three"
foobaz = f.gid = d.groupID("foo::baz")
foobaz = f.gid = d.groups.id("foo::baz")
d.addFact(f)
d.reset()
assert d.sched.counts() == (3, 0, 1)
assert len(d.groups) == 4
assert len(d.groups.groups) == 4
cnts = d.sched.groupCounts()
assert cnts[0] == ["Default", 1, 1, 0, 1]
assert cnts[1] == ["Default::1", default1, 1, 1, 0]