From 6562188ae828f68247df834d7aeb9bd43f799996 Mon Sep 17 00:00:00 2001 From: Andreas Klauer Date: Sun, 24 Feb 2013 02:09:03 +0100 Subject: [PATCH 1/4] Support combined file extensions (*.pau.gz instead of just *.gz) --- aqt/importing.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/aqt/importing.py b/aqt/importing.py index 2e7d6d0cc..3410f4c63 100644 --- a/aqt/importing.py +++ b/aqt/importing.py @@ -255,14 +255,13 @@ def onImport(mw): importFile(mw, file) def importFile(mw, file): - ext = os.path.splitext(file)[1] importer = None done = False for i in importing.Importers: if done: break for mext in re.findall("[( ]?\*\.(.+?)[) ]", i[0]): - if ext == "." + mext: + if file.endswith("." + mext): importer = i[1] done = True break From a78c4d6c31bd989900818ec815cfa2e659c2c92d Mon Sep 17 00:00:00 2001 From: Andreas Klauer Date: Sun, 24 Feb 2013 02:10:50 +0100 Subject: [PATCH 2/4] add Pauker Lesson Importer --- anki/importing/__init__.py | 2 ++ anki/importing/pauker.py | 69 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 anki/importing/pauker.py diff --git a/anki/importing/__init__.py b/anki/importing/__init__.py index a2259c592..4ac509448 100644 --- a/anki/importing/__init__.py +++ b/anki/importing/__init__.py @@ -8,6 +8,7 @@ from anki.importing.anki2 import Anki2Importer from anki.importing.anki1 import Anki1Importer from anki.importing.supermemo_xml import SupermemoXmlImporter from anki.importing.mnemo import MnemosyneImporter +from anki.importing.pauker import PaukerImporter from anki.lang import _ Importers = ( @@ -16,4 +17,5 @@ Importers = ( (_("Anki 1.2 Deck (*.anki)"), Anki1Importer), (_("Mnemosyne 2.0 Deck (*.db)"), MnemosyneImporter), (_("Supermemo XML export (*.xml)"), SupermemoXmlImporter), + (_("Pauker 1.8 Lesson (*.pau.gz)"), PaukerImporter), ) diff --git a/anki/importing/pauker.py b/anki/importing/pauker.py new file mode 100644 index 000000000..6bf22a1f3 --- /dev/null +++ b/anki/importing/pauker.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +# Copyright: Andreas Klauer +# License: BSD-3 + +import gzip, math, random +import xml.etree.ElementTree as ET +from anki.importing.noteimp import NoteImporter, ForeignNote, ForeignCard +from anki.stdmodels import addBasicModel + +class PaukerImporter(NoteImporter): + '''Import Pauker 1.8 Lesson (*.pau.gz)''' + + def fields(self): + '''Pauker is Front/Back''' + print "pauker", "fields", self + return 2 + + def foreignNotes(self): + '''Build and return a list of notes.''' + print "pauker", "foreignNotes", self + notes = [] + + try: + f = gzip.open(self.file) + tree = ET.parse(f) + lesson = tree.getroot() + assert lesson.tag == "Lesson" + finally: + f.close() + + index = -4 + ivlmax = -1 + + for batch in lesson.findall('./Batch'): + index += 1 + + if index >= 0: + ivlmin = ivlmax+1 + ivlmax = int(math.exp(index)) + + for card in batch.findall('./Card'): + front = card.findtext('./FrontSide/Text') + back = card.findtext('./ReverseSide/Text') + note = ForeignNote() + note.fields = [x.strip().replace('\n','
') for x in [front, back]] + note.tags.append("Pauker%+d" % (index,)) + notes.append(note) + + if index == -3: + # new cards + continue + + for tmpl in self.model['tmpls']: + fc = ForeignCard() + if index >= 0: + # due cards + fc.ivl = random.randint(ivlmin,ivlmax) + fc.due = self.col.sched.today+random.randint(ivlmin,ivlmax) + fc.factor = 2500 * fc.ivl / ivlmax + fc.reps = index * fc.ivl / ivlmax + else: + # shortterm cards + fc.ivl = 0 + fc.due = self.col.sched.today + fc.factor = random.randint(2000, 2500) + fc.reps = random.randint(0,3) + note.cards[tmpl['ord']] = fc + + return notes From b6c9253034183d0483552072bcbc5b3d585c8501 Mon Sep 17 00:00:00 2001 From: Andreas Klauer Date: Sun, 24 Feb 2013 23:39:36 +0100 Subject: [PATCH 3/4] support LearnedTimestamps and flipped cards --- anki/importing/pauker.py | 62 ++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/anki/importing/pauker.py b/anki/importing/pauker.py index 6bf22a1f3..a10ed76ba 100644 --- a/anki/importing/pauker.py +++ b/anki/importing/pauker.py @@ -2,22 +2,33 @@ # Copyright: Andreas Klauer # License: BSD-3 -import gzip, math, random +import gzip, math, random, time import xml.etree.ElementTree as ET from anki.importing.noteimp import NoteImporter, ForeignNote, ForeignCard -from anki.stdmodels import addBasicModel +from anki.stdmodels import addForwardReverse + +ONE_DAY = 60*60*24 class PaukerImporter(NoteImporter): '''Import Pauker 1.8 Lesson (*.pau.gz)''' + needMapper = False + + def run(self): + model = addForwardReverse(self.col) + model['name'] = "Pauker" + self.col.models.save(model) + self.col.models.setCurrent(model) + self.model = model + self.initMapping() + NoteImporter.run(self) + def fields(self): '''Pauker is Front/Back''' - print "pauker", "fields", self return 2 def foreignNotes(self): '''Build and return a list of notes.''' - print "pauker", "foreignNotes", self notes = [] try: @@ -29,41 +40,36 @@ class PaukerImporter(NoteImporter): f.close() index = -4 - ivlmax = -1 for batch in lesson.findall('./Batch'): index += 1 - if index >= 0: - ivlmin = ivlmax+1 - ivlmax = int(math.exp(index)) - for card in batch.findall('./Card'): + # Create a note for this card. front = card.findtext('./FrontSide/Text') back = card.findtext('./ReverseSide/Text') note = ForeignNote() note.fields = [x.strip().replace('\n','
') for x in [front, back]] - note.tags.append("Pauker%+d" % (index,)) notes.append(note) - if index == -3: - # new cards - continue + # Determine due date for cards. + frontdue = card.find('./FrontSide[@LearnedTimestamp]') + backdue = card.find('./ReverseSide[@Batch][@LearnedTimestamp]') - for tmpl in self.model['tmpls']: - fc = ForeignCard() - if index >= 0: - # due cards - fc.ivl = random.randint(ivlmin,ivlmax) - fc.due = self.col.sched.today+random.randint(ivlmin,ivlmax) - fc.factor = 2500 * fc.ivl / ivlmax - fc.reps = index * fc.ivl / ivlmax - else: - # shortterm cards - fc.ivl = 0 - fc.due = self.col.sched.today - fc.factor = random.randint(2000, 2500) - fc.reps = random.randint(0,3) - note.cards[tmpl['ord']] = fc + if frontdue is not None: + note.cards[0] = self._learnedCard(index, int(frontdue.attrib['LearnedTimestamp'])) + + if backdue is not None: + note.cards[1] = self._learnedCard(int(backdue.attrib['Batch']), int(backdue.attrib['LearnedTimestamp'])) return notes + + def _learnedCard(self, batch, timestamp): + ivl = math.exp(batch) + now = time.time() + due = ivl - (now - timestamp/1000.0)/ONE_DAY + fc = ForeignCard() + fc.due = self.col.sched.today + int(due+0.5) + fc.ivl = random.randint(int(ivl*0.90), int(ivl+0.5)) + fc.factor = random.randint(1500,2500) + return fc From fcd3bd5eee54fd5f5fd3cb2b7c5ab4248099c64b Mon Sep 17 00:00:00 2001 From: Andreas Klauer Date: Mon, 25 Feb 2013 13:41:00 +0100 Subject: [PATCH 4/4] fix HTML in cards --- anki/importing/pauker.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/anki/importing/pauker.py b/anki/importing/pauker.py index a10ed76ba..c5f7d45f8 100644 --- a/anki/importing/pauker.py +++ b/anki/importing/pauker.py @@ -2,7 +2,7 @@ # Copyright: Andreas Klauer # License: BSD-3 -import gzip, math, random, time +import gzip, math, random, time, cgi import xml.etree.ElementTree as ET from anki.importing.noteimp import NoteImporter, ForeignNote, ForeignCard from anki.stdmodels import addForwardReverse @@ -13,6 +13,7 @@ class PaukerImporter(NoteImporter): '''Import Pauker 1.8 Lesson (*.pau.gz)''' needMapper = False + allowHTML = True def run(self): model = addForwardReverse(self.col) @@ -49,7 +50,7 @@ class PaukerImporter(NoteImporter): front = card.findtext('./FrontSide/Text') back = card.findtext('./ReverseSide/Text') note = ForeignNote() - note.fields = [x.strip().replace('\n','
') for x in [front, back]] + note.fields = [cgi.escape(x.strip()).replace('\n','
').replace(' ','  ') for x in [front,back]] notes.append(note) # Determine due date for cards.