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..c5f7d45f8 --- /dev/null +++ b/anki/importing/pauker.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- +# Copyright: Andreas Klauer +# License: BSD-3 + +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 + +ONE_DAY = 60*60*24 + +class PaukerImporter(NoteImporter): + '''Import Pauker 1.8 Lesson (*.pau.gz)''' + + needMapper = False + allowHTML = True + + 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''' + return 2 + + def foreignNotes(self): + '''Build and return a list of notes.''' + notes = [] + + try: + f = gzip.open(self.file) + tree = ET.parse(f) + lesson = tree.getroot() + assert lesson.tag == "Lesson" + finally: + f.close() + + index = -4 + + for batch in lesson.findall('./Batch'): + index += 1 + + 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 = [cgi.escape(x.strip()).replace('\n','
').replace(' ','  ') for x in [front,back]] + notes.append(note) + + # Determine due date for cards. + frontdue = card.find('./FrontSide[@LearnedTimestamp]') + backdue = card.find('./ReverseSide[@Batch][@LearnedTimestamp]') + + 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 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