mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 16:56:36 -04:00
update supermemo importer; fix factor
This commit is contained in:
parent
beef571d95
commit
972526d265
4 changed files with 41 additions and 59 deletions
|
@ -62,7 +62,7 @@ acq_reps+ret_reps, lapses from cards"""):
|
|||
continue
|
||||
# add the card
|
||||
c = ForeignCard()
|
||||
c.factor = row[5]
|
||||
c.factor = int(row[5]*1000)
|
||||
c.reps = row[6]
|
||||
c.lapses = row[7]
|
||||
# ivl is inferred in mnemosyne
|
||||
|
|
|
@ -24,7 +24,7 @@ class ForeignCard(object):
|
|||
def __init__(self):
|
||||
self.due = 0
|
||||
self.ivl = 1
|
||||
self.factor = 2.5
|
||||
self.factor = 2500
|
||||
self.reps = 0
|
||||
self.lapses = 0
|
||||
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
import sys
|
||||
|
||||
from anki.importing.noteimp import NoteImporter, ForeignNote
|
||||
from anki.stdmodels import addBasicModel
|
||||
from anki.importing.noteimp import NoteImporter, ForeignNote, ForeignCard
|
||||
from anki.lang import _
|
||||
from anki.errors import *
|
||||
|
||||
|
@ -12,10 +13,6 @@ from xml.dom import minidom, Node
|
|||
from types import DictType, InstanceType
|
||||
from string import capwords, maketrans
|
||||
import re, unicodedata, time
|
||||
#import chardet
|
||||
|
||||
|
||||
#from anki import Deck
|
||||
|
||||
class SmartDict(dict):
|
||||
"""
|
||||
|
@ -81,8 +78,12 @@ class SupermemoXmlImporter(NoteImporter):
|
|||
def __init__(self, *args):
|
||||
"""Initialize internal varables.
|
||||
Pameters to be exposed to GUI are stored in self.META"""
|
||||
NoteImporter.__init__(self, *args)
|
||||
m = addBasicModel(self.col)
|
||||
m['name'] = "Supermemo"
|
||||
self.col.models.save(m)
|
||||
self.initMapping()
|
||||
|
||||
Importer.__init__(self, *args)
|
||||
self.lines = None
|
||||
self.numFields=int(2)
|
||||
|
||||
|
@ -110,7 +111,7 @@ class SupermemoXmlImporter(NoteImporter):
|
|||
self.META.tagMemorizedItems = True # implemented
|
||||
self.META.logToStdOutput = False # implemented
|
||||
|
||||
self.cards = []
|
||||
self.notes = []
|
||||
|
||||
## TOOLS
|
||||
|
||||
|
@ -197,7 +198,7 @@ class SupermemoXmlImporter(NoteImporter):
|
|||
|
||||
## DEFAULT IMPORTER METHODS
|
||||
|
||||
def foreignCards(self):
|
||||
def foreignNotes(self):
|
||||
|
||||
# Load file and parse it by minidom
|
||||
self.loadSource(self.file)
|
||||
|
@ -209,7 +210,7 @@ class SupermemoXmlImporter(NoteImporter):
|
|||
self.logger(u'Parsing done.')
|
||||
|
||||
# Return imported cards
|
||||
return self.cards
|
||||
return self.notes
|
||||
|
||||
def fields(self):
|
||||
return 2
|
||||
|
@ -220,38 +221,28 @@ class SupermemoXmlImporter(NoteImporter):
|
|||
"This method actually do conversion"
|
||||
|
||||
# new anki card
|
||||
card = ForeignCard()
|
||||
note = ForeignNote()
|
||||
|
||||
# clean Q and A
|
||||
card.fields.append(self._fudgeText(self._decode_htmlescapes(item.Question)))
|
||||
card.fields.append(self._fudgeText(self._decode_htmlescapes(item.Answer)))
|
||||
card.tags = u""
|
||||
note.fields.append(self._fudgeText(self._decode_htmlescapes(item.Question)))
|
||||
note.fields.append(self._fudgeText(self._decode_htmlescapes(item.Answer)))
|
||||
note.tags = []
|
||||
|
||||
# pre-process scheduling data
|
||||
tLastrep = time.mktime(time.strptime(item.LastRepetition, '%d.%m.%Y'))
|
||||
tToday = time.time()
|
||||
|
||||
# convert learning data
|
||||
if not self.META.resetLearningData:
|
||||
if not self.META.resetLearningData and item.Interval >= 1:
|
||||
# migration of LearningData algorithm
|
||||
card.interval = item.Interval
|
||||
card.successive = item.Repetitions
|
||||
##card.due = tToday + (float(item.Interval) * 86400.0) - tLastrep
|
||||
card.due = tLastrep + (float(item.Interval) * 86400.0)
|
||||
card.lastDue = 0
|
||||
|
||||
card.factor = float(item.AFactor.replace(',','.'))
|
||||
card.lastFactor = float(item.AFactor.replace(',','.'))
|
||||
|
||||
# SM is not exporting all the information Anki keeps track off, so it
|
||||
# needs to be fudged
|
||||
card.youngEase0 = item.Lapses
|
||||
card.youngEase3 = item.Repetitions + item.Lapses
|
||||
card.yesCount = item.Repetitions
|
||||
card.noCount = item.Lapses
|
||||
card.reps = card.yesCount + card.noCount
|
||||
card.spaceUntil = card.due
|
||||
card.combinedDue = card.due
|
||||
tLastrep = time.mktime(time.strptime(item.LastRepetition, '%d.%m.%Y'))
|
||||
tToday = time.time()
|
||||
card = ForeignCard()
|
||||
card.ivl = int(item.Interval)
|
||||
card.lapses = int(item.Lapses)
|
||||
card.reps = int(item.Repetitions) + int(item.Lapses)
|
||||
nextDue = tLastrep + (float(item.Interval) * 86400.0)
|
||||
remDays = max(0, int((nextDue - time.time())/86400))
|
||||
card.due = self.col.sched.today+remDays
|
||||
card.factor = int(float(item.AFactor.replace(',','.'))*1000)
|
||||
note.cards[0] = card
|
||||
|
||||
# categories & tags
|
||||
# it's worth to have every theme (tree structure of sm collection) stored in tags, but sometimes not
|
||||
|
@ -275,14 +266,14 @@ class SupermemoXmlImporter(NoteImporter):
|
|||
tmp = list(set([ capwords(i).replace(' ','') for i in tmp ]))
|
||||
tags = [ j[0].lower() + j[1:] for j in tmp if j.strip() <> '']
|
||||
|
||||
card.tags += u" ".join(tags)
|
||||
note.tags += tags
|
||||
|
||||
if self.META.tagMemorizedItems and item.Interval >0:
|
||||
card.tags += " Memorized"
|
||||
note.tags.append("Memorized")
|
||||
|
||||
self.logger(u'Element tags\t- ' + card.tags, level=3)
|
||||
self.logger(u'Element tags\t- ' + `note.tags`, level=3)
|
||||
|
||||
self.cards.append(card)
|
||||
self.notes.append(note)
|
||||
|
||||
def logger(self,text,level=1):
|
||||
"Wrapper for Anki logger"
|
||||
|
@ -323,7 +314,7 @@ class SupermemoXmlImporter(NoteImporter):
|
|||
"""Load source file and parse with xml.dom.minidom"""
|
||||
self.source = source
|
||||
self.logger(u'Load started...')
|
||||
sock = self.openAnything(self.source)
|
||||
sock = open(self.source)
|
||||
self.xmldoc = minidom.parse(sock).documentElement
|
||||
sock.close()
|
||||
self.logger(u'Load done.')
|
||||
|
|
|
@ -96,27 +96,17 @@ def test_csv():
|
|||
assert i.total == 0
|
||||
deck.close()
|
||||
|
||||
def test_csv_tags():
|
||||
print "disabled"; return
|
||||
deck = getEmptyDeck()
|
||||
file = unicode(os.path.join(testDir, "support/text-tags.txt"))
|
||||
i = TextImporter(deck, file)
|
||||
i.run()
|
||||
notes = deck.db.query(Note).all()
|
||||
assert len(notes) == 2
|
||||
assert notes[0].tags == "baz qux" or notes[1].tags == "baz qux"
|
||||
deck.close()
|
||||
|
||||
def test_supermemo_xml_01_unicode():
|
||||
print "disabled"; return
|
||||
deck = Deck()
|
||||
deck.addModel(BasicModel())
|
||||
file = unicode(os.path.join(testDir, "importing/supermemo1.xml"))
|
||||
i = supermemo_xml.SupermemoXmlImporter(deck, file)
|
||||
deck = getEmptyDeck()
|
||||
file = unicode(os.path.join(testDir, "support/supermemo1.xml"))
|
||||
i = SupermemoXmlImporter(deck, file)
|
||||
#i.META.logToStdOutput = True
|
||||
i.run()
|
||||
# only returning top-level elements?
|
||||
assert i.total == 1
|
||||
cid = deck.db.scalar("select id from cards")
|
||||
c = deck.getCard(cid)
|
||||
assert c.factor == 5701
|
||||
assert c.reps == 7
|
||||
deck.close()
|
||||
|
||||
def test_mnemo():
|
||||
|
@ -127,3 +117,4 @@ def test_mnemo():
|
|||
assert deck.cardCount() == 7
|
||||
assert "a_longer_tag" in deck.tags.all()
|
||||
assert deck.db.scalar("select count() from cards where type = 0") == 1
|
||||
deck.close()
|
||||
|
|
Loading…
Reference in a new issue