def foreignNotes(self):
        with open(self.file, 'r') as f:
            content = f.read().decode('utf-8')

        notes = []
        entries = json.loads(content)
        for entry in entries:
            row = []
            empty = True
            for f in self.mappingFields:
                value = entry.get(f)
                if value:
                    empty = False
                    if '.' in value:
                        ext = value[value.rfind('.') + 1:].lower()
                        if ext in MEDIA_EXTENSIONS:
                            path = os.path.join(self.fileDir, value)
                            if os.path.exists(path):
                                filename = self.col.media.addFile(os.path.join(self.fileDir, value))
                                if ext in AUDIO_EXTENSIONS:
                                    value = u'[sound:%s]' % filename
                                else:
                                    value = u'<img src="%s">' % filename

                row.append(value)

            if empty:  # empty entry
                continue

            note = ForeignNote()
            note.fields = row
            notes.append(note)

        return notes
Exemple #2
0
    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', '<br>').replace(
                        '  ', ' &nbsp;') 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
Exemple #3
0
 def _addCloze(self, notes):
     data = []
     notes = list(notes.values())
     for orig in notes:
         # create a foreign note object
         n = ForeignNote()
         n.fields = []
         fld = orig.get("text", "")
         fld = re.sub("\r?\n", "<br>", fld)
         state = dict(n=1)
         def repl(match):
             # replace [...] with cloze refs
             res = ("{{c%d::%s}}" % (state['n'], match.group(1)))
             state['n'] += 1
             return res
         fld = re.sub("\[(.+?)\]", repl, fld)
         fld = self._mungeField(fld)
         n.fields.append(fld)
         n.fields.append("") # extra
         n.tags = orig['tags']
         n.cards = orig.get('cards', {})
         data.append(n)
     # add cloze model
     model = addClozeModel(self.col)
     model['name'] = "Mnemosyne-Cloze"
     mm = self.col.models
     mm.save(model)
     mm.setCurrent(model)
     self.model = model
     self._fields = len(model['flds'])
     self.initMapping()
     self.importNotes(data)
Exemple #4
0
    def addItemToCards(self,item):
        "This method actually do conversion"

        # new anki card
        note = ForeignNote()

        # clean Q and A
        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
        # convert learning data
        if (not self.META.resetLearningData
            and int(item.Interval) >= 1
            and getattr(item, "LastRepetition", None)):
            # migration of LearningData algorithm
            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 = int((nextDue - time.time())/86400)
            card.due = self.col.sched.today+remDays
            card.factor = int(self._afactor2efactor(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
        # you can deceide if you are going to tag all toppics or just that containing some pattern
        tTaggTitle = False
        for pattern in self.META.pathsToBeTagged:
            if item.lTitle is not None and pattern.lower() in " ".join(item.lTitle).lower():
              tTaggTitle = True
              break
        if tTaggTitle or self.META.tagAllTopics:
          # normalize - remove diacritic punctuation from unicode chars to ascii
          item.lTitle = [ self._unicode2ascii(topic) for topic in item.lTitle]

          # Transfrom xyz / aaa / bbb / ccc on Title path to Tag  xyzAaaBbbCcc
          #  clean things like [999] or [111-2222] from title path, example: xyz / [1000-1200] zyx / xyz
          #  clean whitespaces
          #  set Capital letters for first char of the word
          tmp = list(set([ re.sub('(\[[0-9]+\])'   , ' ' , i ).replace('_',' ')  for i in item.lTitle ]))
          tmp = list(set([ re.sub('(\W)',' ', i )  for i in tmp ]))
          tmp = list(set([ re.sub( '^[0-9 ]+$','',i)  for i in tmp ]))
          tmp = list(set([ capwords(i).replace(' ','')  for i in tmp ]))
          tags = [ j[0].lower() + j[1:] for j in tmp if j.strip() != '']

          note.tags += tags

          if self.META.tagMemorizedItems and int(item.Interval) >0:
            note.tags.append("Memorized")

          self.logger('Element tags\t- ' + repr(note.tags), level=3)

        self.notes.append(note)
    def entriesToNotes(self, entries):
        notes = []
        for entry in entries:
            row = self._read_row(entry)
            if len(row) == 0:  # empty entry
                continue

            note = ForeignNote()
            note.fields = row
            notes.append(note)

        return notes
Exemple #6
0
    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 = [
                    html.escape(x.strip()).replace('\n', '<br>').replace(
                        '  ', ' &nbsp;') 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
Exemple #7
0
 def readData(self, mapping):
     from anki.importing.noteimp import ForeignNote
     if not self.hasOpenWorkbook():
         self._log.append("xlimport: Error reading data: no open worksheet.")
         return
     assert self._dataDim
     assert self._headerCells
     self._notes = []
     for row in tuple(self.worksheet.iter_rows(self._dataDim, row_offset = self._rowOffset)):
         flds = []
         isEmpty = True
         for c in xrange(0, len(mapping)):
             hdr = self._headerCells[c].value
             if hdr and hdr in mapping:
                 v = row[c].value if row[c].value else ''
                 isEmpty = False if row[c].value else isEmpty
                 flds.append(v if row[c].data_type == 's' else str(v))
         if not isEmpty:
             note = ForeignNote()
             note.fields = flds
             self._notes.append(note)
Exemple #8
0
 def _addFronts(self, notes, model=None, fields=("f", "b")):
     data = []
     for orig in notes:
         # create a foreign note object
         n = ForeignNote()
         n.fields = []
         for f in fields:
             n.fields.append(orig.get(f, ''))
         n.tags = orig['tags']
         n.cards = orig.get('cards', {})
         data.append(n)
     # add a basic model
     if not model:
         model = addBasicModel(self.col)
     model['name'] = "Mnemosyne-FrontOnly"
     mm = self.col.models
     mm.save(model)
     mm.setCurrent(model)
     self.model = model
     self._fields = len(model['flds'])
     self.initMapping()
     # import
     self.importNotes(data)
Exemple #9
0
 def _addFronts(self, notes, model=None, fields=("f", "b")):
     data = []
     for orig in notes:
         # create a foreign note object
         n = ForeignNote()
         n.fields = []
         for f in fields:
             n.fields.append(orig.get(f, ''))
         n.tags = orig['tags']
         n.cards = orig.get('cards', {})
         data.append(n)
     # add a basic model
     if not model:
         model = addBasicModel(self.col)
     model['name'] = "Mnemosyne-FrontOnly"
     mm = self.col.models
     mm.save(model)
     mm.setCurrent(model)
     self.model = model
     self._fields = len(model['flds'])
     self.initMapping()
     # import
     self.importNotes(data)
Exemple #10
0
 def _addFronts(self, notes, model=None, fields=("f", "b")):
     data = []
     for orig in notes:
         # create a foreign note object
         n = ForeignNote()
         n.fields = []
         for f in fields:
             fld = self._mungeField(orig.get(f, ""))
             n.fields.append(fld)
         n.tags = orig["tags"]
         n.cards = orig.get("cards", {})
         data.append(n)
     # add a basic model
     if not model:
         model = _legacy_add_basic_model(self.col)
         model["name"] = "Mnemosyne-FrontOnly"
     mm = self.col.models
     mm.save(model)
     mm.set_current(model)
     self.model = model
     self._fields = len(model["flds"])
     self.initMapping()
     # import
     self.importNotes(data)
Exemple #11
0
    def noteFromJson(self, jsonDict):
        note = None
        if (jsonDict[u'object'] == 'kanji'
                and jsonDict[u'id'] in self.availableIds):
            note = ForeignNote()

            # appending as a number anki throws an Exception
            note.fields.append('{}'.format(jsonDict[u'id']))

            # appending as a number anki throws an Exception
            note.fields.append('{}'.format(jsonDict[u'data'][u'level']))

            # appending as a number anki throws an Exception
            note.fields.append('{}'.format(
                jsonDict[u'data'][u'lesson_position']))

            note.fields.append(jsonDict[u'data'][u'characters'])

            note.fields.append(
                joinValues(jsonDict[u'data'][u'meanings'], u'meaning')[1])

            note.fields.append(jsonDict[u'data'][u'meaning_mnemonic'])

            opcount, onyomi = joinValues(jsonDict[u'data'][u'readings'],
                                         u'reading', u'onyomi')
            kpcount, kunyomi = joinValues(jsonDict[u'data'][u'readings'],
                                          u'reading', u'kunyomi')

            note.fields.append(onyomi)

            # if kanji has primary onyomi and kunyomi reading too, then reading mnemonic
            # is put both in onyomi and kunyomi reading mnemonic
            if (opcount > 0 and kpcount == 0) or (kpcount > 0 and opcount > 0):
                note.fields.append(jsonDict[u'data'][u'reading_mnemonic'])
            else:
                note.fields.append(u'')

            note.fields.append(kunyomi)

            # if kanji has primary onyomi and kunyomi reading too, then reading mnemonic
            # is put both in onyomi and kunyomi reading mnemonic
            if (kpcount > 0 and opcount == 0) or (kpcount > 0 and opcount > 0):
                note.fields.append(jsonDict[u'data'][u'reading_mnemonic'])
            else:
                note.fields.append(u'')

        return note
    def foreignNotes(self):
        notes = []

        for record in self.getRecords():
            note = ForeignNote()

            modelFields = self.model['flds']

            for field in modelFields:
                key = field['name']

                if key == 'Definition':
                    note.fields.append(record["definition"])
                elif key == 'Word':
                    note.fields.append(
                        f'<a href="{record["entryUrl"]}">{record["headword"]}</a>'
                    )

            notes.append(note)

        return notes
Exemple #13
0
    def foreignNotes(self):
        notes = []

        for record in self.getRecords():
            note = ForeignNote()

            fields = record["fields"]
            modelFields = self.model["flds"]

            for field in modelFields:
                key = field['name']

                # sys.stderr.write(key + "\n")

                if key in fields:
                    if isinstance(fields[key], list):
                        if len(fields[key]) == 0:
                            note.fields.append("")
                        elif isinstance(fields[key][0], dict):
                            note.fields.append(
                                self.downloadToCollection(fields[key]))
                        else:
                            strings = [str(e) for e in fields[key]]
                            note.fields.append(str(", ".join(strings)))
                    else:
                        if not isinstance(fields[key], str) and not isinstance(
                                fields[key], str):
                            fields[key] = str(fields[key])

                        asciiToHtml = fields[key].replace("\n", "<br/>")
                        note.fields.append(asciiToHtml)
                else:
                    note.fields.append("")

                # This has some encoding problems.
                # sys.stderr.write(key + " => " + note.fields[len(note.fields) - 1] + "\n")

            notes.append(note)

        return notes
 def noteFromFields(self, id, front, back, tags):
     note = ForeignNote()
     note.fields.extend([id, front, back, ""])
     note.tags.extend(tags + self.tagsToAdd)
     return note
Exemple #15
0
 def processNote(self, noteString, globalTags):
     newNote = ForeignNote()
     newNote.tags.extend(globalTags)
     fieldCommands = [{
         'beginfun':
         lambda string: self.findCommand(string, r"field"),
         'endfun':
         lambda string: self.findCommand(string, r"endfield"),
         'process':
         lambda string: self.processLatexField(string, newNote)
     }, {
         'beginfun':
         lambda string: self.findCommand(string, r"begin", r"field"),
         'endfun':
         lambda string: self.findCommand(
             string, r"end", r"field", warning=True),
         'process':
         lambda string: self.processLatexField(string, newNote)
     }, {
         'beginfun':
         lambda string: self.findCommand(string, r"xfield", r"?"),
         'endfun':
         self.findClosingBrace,
         'process':
         lambda string: self.processLatexField(string, newNote)
     }, {
         'beginfun':
         lambda string: self.findCommand(string, r"plain"),
         'endfun':
         lambda string: self.findCommand(string, r"endplain"),
         'process':
         lambda string: self.processPlainField(string, newNote)
     }, {
         'beginfun':
         lambda string: self.findCommand(string, r"begin", r"plain"),
         'endfun':
         lambda string: self.findCommand(
             string, r"end", r"plain", warning=True),
         'process':
         lambda string: self.processPlainField(string, newNote)
     }, {
         'beginfun':
         lambda string: self.findCommand(string, r"xplain", r"?"),
         'endfun':
         self.findClosingBrace,
         'process':
         lambda string: self.processPlainField(string, newNote)
     }, {
         'beginfun':
         lambda string: self.findCommand(string, r"tags", r"?"),
         'endfun':
         self.findClosingBrace,
         'process':
         lambda string: self.processTags(string, newNote)
     }]
     pieces, post = self.cutIntoPieces(noteString, fieldCommands)
     for pre, value, ci in pieces:
         self.rubbishList.append(pre)
         fieldCommands[ci]['process'](value)
     self.rubbishList.append(post)
     self.noteList.append(newNote)
Exemple #16
0
    def addItemToCards(self, item):
        "This method actually do conversion"

        # new anki card
        note = ForeignNote()

        # clean Q and A
        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
        # convert learning data
        if (not self.META.resetLearningData and item.Interval >= 1
                and getattr(item, "LastRepetition", None)):
            # migration of LearningData algorithm
            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 = 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
        # you can deceide if you are going to tag all toppics or just that containing some pattern
        tTaggTitle = False
        for pattern in self.META.pathsToBeTagged:
            if item.lTitle != None and pattern.lower() in u" ".join(
                    item.lTitle).lower():
                tTaggTitle = True
                break
        if tTaggTitle or self.META.tagAllTopics:
            # normalize - remove diacritic punctuation from unicode chars to ascii
            item.lTitle = [self._unicode2ascii(topic) for topic in item.lTitle]

            # Transfrom xyz / aaa / bbb / ccc on Title path to Tag  xyzAaaBbbCcc
            #  clean things like [999] or [111-2222] from title path, example: xyz / [1000-1200] zyx / xyz
            #  clean whitespaces
            #  set Capital letters for first char of the word
            tmp = list(
                set([
                    re.sub('(\[[0-9]+\])', ' ', i).replace('_', ' ')
                    for i in item.lTitle
                ]))
            tmp = list(set([re.sub('(\W)', ' ', i) for i in tmp]))
            tmp = list(set([re.sub('^[0-9 ]+$', '', i) for i in tmp]))
            tmp = list(set([capwords(i).replace(' ', '') for i in tmp]))
            tags = [j[0].lower() + j[1:] for j in tmp if j.strip() <> '']

            note.tags += tags

            if self.META.tagMemorizedItems and item.Interval > 0:
                note.tags.append("Memorized")

            self.logger(u'Element tags\t- ' + ` note.tags `, level=3)

        self.notes.append(note)
Exemple #17
0
 def noteFromFields(self, fields: List[str]) -> ForeignNote:
     note = ForeignNote()
     note.fields.extend([x for x in fields])
     note.tags.extend(self.tagsToAdd)
     return note
Exemple #18
0
 def noteFromFields(self, fields):
     note = ForeignNote()
     note.fields.extend([x.strip().replace("\n", "<br>") for x in fields])
     note.tags.extend(self.tagsToAdd)
     return note