Ejemplo n.º 1
0
def test_templates():
    d = getEmptyDeck()
    m = d.models.current(); mm = d.models
    t = mm.newTemplate("Reverse")
    t['qfmt'] = "{{Back}}"
    t['afmt'] = "{{Front}}"
    mm.addTemplate(m, t)
    mm.save(m)
    f = d.newNote()
    f['Front'] = u'1'
    f['Back'] = u'2'
    d.addNote(f)
    assert d.cardCount() == 2
    (c, c2) = f.cards()
    # first card should have first ord
    assert c.ord == 0
    assert c2.ord == 1
    # switch templates
    d.models.moveTemplate(m, c.template(), 1)
    c.load(); c2.load()
    assert c.ord == 1
    assert c2.ord == 0
    # removing a template should delete its cards
    assert d.models.remTemplate(m, m['tmpls'][0])
    assert d.cardCount() == 1
    # and should have updated the other cards' ordinals
    c = f.cards()[0]
    assert c.ord == 0
    stripHTML(c.q()) == "2"
    # it shouldn't be possible to orphan notes by removing templates
    assert not d.models.remTemplate(m, m['tmpls'][0])
Ejemplo n.º 2
0
def test_templates():
    d = getEmptyDeck()
    m = d.models.current()
    mm = d.models
    t = mm.newTemplate("Reverse")
    t['qfmt'] = "{{Back}}"
    t['afmt'] = "{{Front}}"
    mm.addTemplate(m, t)
    mm.save(m)
    f = d.newNote()
    f['Front'] = u'1'
    f['Back'] = u'2'
    d.addNote(f)
    assert d.cardCount() == 2
    (c, c2) = f.cards()
    # first card should have first ord
    assert c.ord == 0
    assert c2.ord == 1
    # switch templates
    d.models.moveTemplate(m, c.template(), 1)
    c.load()
    c2.load()
    assert c.ord == 1
    assert c2.ord == 0
    # removing a template should delete its cards
    assert d.models.remTemplate(m, m['tmpls'][0])
    assert d.cardCount() == 1
    # and should have updated the other cards' ordinals
    c = f.cards()[0]
    assert c.ord == 0
    stripHTML(c.q()) == "2"
    # it shouldn't be possible to orphan notes by removing templates
    assert not d.models.remTemplate(m, m['tmpls'][0])
Ejemplo n.º 3
0
 def drawLastCard(self):
     "Show the last card if not the current one, and next time."
     if self.main.lastCard:
         if self.main.config["showLastCardContent"]:
             if self.state == "deckFinished" or self.main.currentCard.id != self.main.lastCard.id:
                 q = self.main.lastCard.question.replace("<br>", "  ")
                 q = stripHTML(q)
                 if len(q) > 50:
                     q = q[:50] + "..."
                 a = self.main.lastCard.answer.replace("<br>", "  ")
                 a = stripHTML(a)
                 if len(a) > 50:
                     a = a[:50] + "..."
                 s = "%s<br>%s" % (q, a)
                 s = stripLatex(s)
                 self.write('<span class="lastCard">%s</span><br>' % s)
         if self.main.config["showLastCardInterval"]:
             if self.main.lastQuality > 1:
                 msg = _("Well done! This card will appear again in " "<b>%(next)s</b>.") % {
                     "next": self.main.lastScheduledTime
                 }
             else:
                 msg = _("This card will appear again later.")
             self.write(msg)
         self.write("<br>")
Ejemplo n.º 4
0
def new_name_base(old_base):
    """
    Get the base of a new file name

    Look at the information on the card and use the data to create
    a base new name.
    """

    # Several tries. First, look through the list.
    name, value = find_field(note, old_base)
    if value and not old_base in value:
        return value
    # Still here, next try the sort field.
    name, value = note.items()[mw.col.models.sortIdx(note.model())]
    value = stripHTML(value)
    if value and not old_base in value:
        return value
    for name, value in note.items():
        # Last resort: go through the fields and grab the first
        # non-empty one, except the one with the file.
        value = stripHTML(value)
        if value and not old_base in value:
            return value
    # Well, shoot. Looks like the only field with anything interesting
    # is the one with the file. (Almost reasonable. One-side cards to
    # just listen to something and decide without further info if you
    # recoginze that.)
    raise ValueError(_(u'No data for new name found'))
Ejemplo n.º 5
0
def external_file_link(card, model):
    field_for_filename = ""
    field_for_page = ""
    # import user settings for field names from other add-on
    try:
        field_for_filename = __import__(
            "1994996371").open_in_external.field_for_filename
        field_for_page = __import__(
            "1994996371").open_in_external.field_for_page
    except:
        return ""
    if all([field_for_filename, field_for_page]):
        note = mw.col.getNote(card.nid)
        for i, f in enumerate(note.model()['flds']):
            if f['name'] == field_for_filename:
                file = note.fields[i]
            if f['name'] == field_for_page:
                page = note.fields[i]
        try:
            file
            page
        except:
            return ""
        f = stripHTML(file)
        p = stripHTML(page)
        pycmd = f"open_external_filesüöäüöä{f}üöäüöä{p}"
        if p:
            text = f"{f} , {p}"
        else:
            text = f"{f}"
        out = f"""<a href='javascript:pycmd("{pycmd}");'>{text}</a>"""
        return out
Ejemplo n.º 6
0
def JxAffectFields(Card,Types):
        # we now try to affect relevant fields for each type (first try fields with the name similar to the type)
        List=[]
        for (Type,TypeList) in JxType:
                if Type in Types:
                        for Field in Card.fact.model.fieldModels:
                                if Field.name in TypeList:
                                        List.append((Type,Field.name,stripHTML(Card.fact[Field.name]))) 
                                        break

        if len(List)<len(Types):
                # there are still missing fields for the types, we could try the "Expression" field next and update the List
                if len(List)>0:
                        (Done,Field) = zip(*List)
                else : 
                        Done=[]
                TempList=[]
                for (Type,TypeList) in JxType:
                        if Type in Types and Type in Done:
                                TempList.append(List.pop(0))
                        elif Type in Types:
                                for Field in Card.fact.model.fieldModels:
                                        if Field.name == u"Expression":
                                                TempList.append((Type,Field.name,stripHTML(Card.fact[Field.name]))) 
                                                break 
                List = TempList
        if len(List)<len(Types):
                # field names and "Expression" have failed, we could still try to guess with the fields content
                # but for the time being, we will pass because I don't know how to choose between two fields that might only have kanas (maybee query other cards to decide between the fields, might be doable for sentences (ponctuation helps) and Kanji (only 1 Kanji character))
                pass
   
        return List
Ejemplo n.º 7
0
def test_templates():
    d = getEmptyDeck()
    m = d.currentModel()
    m.templates[1]['actv'] = True
    m.flush()
    f = d.newFact()
    f['Front'] = u'1'
    f['Back'] = u'2'
    d.addFact(f)
    assert d.cardCount() == 2
    (c, c2) = f.cards()
    # first card should have first ord
    assert c.ord == 0
    assert c2.ord == 1
    # switch templates
    m.moveTemplate(c.template(), 1)
    c.load(); c2.load()
    assert c.ord == 1
    assert c2.ord == 0
    # removing a template should delete its cards
    m.delTemplate(m.templates[0])
    assert d.cardCount() == 1
    # and should have updated the other cards' ordinals
    c = f.cards()[0]
    assert c.ord == 0
    stripHTML(c.q()) == "2"
Ejemplo n.º 8
0
 def _processHtml(self, mime):
     html = mime.html()
     newMime = QMimeData()
     if self.strip and not html.startswith("<!--anki-->"):
         # special case for google images: if after stripping there's no text
         # and there are image links, we'll paste those as html instead
         if not stripHTML(html).strip():
             newHtml = ""
             mid = self.editor.note.mid
             for url in self.editor.mw.col.media.filesInStr(
                 mid, html, includeRemote=True):
                 newHtml += self.editor.urlToLink(url)
             if not newHtml and mime.hasImage():
                 return self._processImage(mime)
             newMime.setHtml(newHtml)
         else:
             # use .text() if available so newlines are preserved; otherwise strip
             if mime.hasText():
                 return self._processText(mime)
             else:
                 newMime.setText(stripHTML(mime.text()))
     else:
         if html.startswith("<!--anki-->"):
             html = html[11:]
         # no html stripping
         html = self.editor._filterHTML(html, localize=True)
         newMime.setHtml(html)
     return newMime
Ejemplo n.º 9
0
def test_modelChange():
    deck = DeckStorage.Deck()
    m = Model(u"Japanese")
    m1 = m
    f = FieldModel(u'Expression', True, True)
    m.addFieldModel(f)
    m.addFieldModel(FieldModel(u'Meaning', False, False))
    f = FieldModel(u'Reading', False, False)
    m.addFieldModel(f)
    m.addCardModel(
        CardModel(u"Recognition", u"%(Expression)s",
                  u"%(Reading)s<br>%(Meaning)s"))
    m.addCardModel(
        CardModel(u"Recall",
                  u"%(Meaning)s",
                  u"%(Expression)s<br>%(Reading)s",
                  active=False))
    m.tags = u"Japanese"
    m1.cardModels[1].active = True
    deck.addModel(m1)
    f = deck.newFact()
    f['Expression'] = u'e'
    f['Meaning'] = u'm'
    f['Reading'] = u'r'
    f = deck.addFact(f)
    f2 = deck.newFact()
    f2['Expression'] = u'e2'
    f2['Meaning'] = u'm2'
    f2['Reading'] = u'r2'
    deck.addFact(f2)
    m2 = BasicModel()
    m2.cardModels[1].active = True
    deck.addModel(m2)
    # convert to basic
    assert deck.modelUseCount(m1) == 2
    assert deck.modelUseCount(m2) == 0
    assert deck.cardCount == 4
    assert deck.factCount == 2
    fmap = {
        m1.fieldModels[0]: m2.fieldModels[0],
        m1.fieldModels[1]: None,
        m1.fieldModels[2]: m2.fieldModels[1]
    }
    cmap = {m1.cardModels[0]: m2.cardModels[0], m1.cardModels[1]: None}
    deck.changeModel([f.id], m2, fmap, cmap)
    assert deck.modelUseCount(m1) == 1
    assert deck.modelUseCount(m2) == 1
    assert deck.cardCount == 3
    assert deck.factCount == 2
    (q, a) = deck.s.first("""
select question, answer from cards where factId = :id""",
                          id=f.id)
    assert stripHTML(q) == u"e"
    assert stripHTML(a) == u"r"
Ejemplo n.º 10
0
def test_modelChange():
    deck = DeckStorage.Deck()
    m = Model(u"Japanese")
    m1 = m
    f = FieldModel(u'Expression', True, True)
    m.addFieldModel(f)
    m.addFieldModel(FieldModel(u'Meaning', False, False))
    f = FieldModel(u'Reading', False, False)
    m.addFieldModel(f)
    m.addCardModel(CardModel(u"Recognition",
                             u"%(Expression)s",
                             u"%(Reading)s<br>%(Meaning)s"))
    m.addCardModel(CardModel(u"Recall",
                             u"%(Meaning)s",
                             u"%(Expression)s<br>%(Reading)s",
                             active=False))
    m.tags = u"Japanese"
    m1.cardModels[1].active = True
    deck.addModel(m1)
    f = deck.newFact()
    f['Expression'] = u'e'
    f['Meaning'] = u'm'
    f['Reading'] = u'r'
    f = deck.addFact(f)
    f2 = deck.newFact()
    f2['Expression'] = u'e2'
    f2['Meaning'] = u'm2'
    f2['Reading'] = u'r2'
    deck.addFact(f2)
    m2 = BasicModel()
    m2.cardModels[1].active = True
    deck.addModel(m2)
    # convert to basic
    assert deck.modelUseCount(m1) == 2
    assert deck.modelUseCount(m2) == 0
    assert deck.cardCount == 4
    assert deck.factCount == 2
    fmap = {m1.fieldModels[0]: m2.fieldModels[0],
            m1.fieldModels[1]: None,
            m1.fieldModels[2]: m2.fieldModels[1]}
    cmap = {m1.cardModels[0]: m2.cardModels[0],
            m1.cardModels[1]: None}
    deck.changeModel([f.id], m2, fmap, cmap)
    deck.reset()
    assert deck.modelUseCount(m1) == 1
    assert deck.modelUseCount(m2) == 1
    assert deck.cardCount == 3
    assert deck.factCount == 2
    (q, a) = deck.s.first("""
select question, answer from cards where factId = :id""",
                          id=f.id)
    assert stripHTML(q) == u"e"
    assert stripHTML(a) == u"r"
Ejemplo n.º 11
0
	def alertUser(self):
		text ='%d new card(s) added. %d card(s) were duplicates' % (
																	len(self.added),
																	len(self.duplicates))
		text += '\n\nNEW CARDS:\n==========\n'
		for card in self.added:
			text += stripHTML(card.front) + '\n'
		
		text += '\nDUPLICATES:\n===========\n'
		for card in self.duplicates:
			text += stripHTML(card.front) + '\n'
			
		showText(text)
Ejemplo n.º 12
0
 def dupeOrEmpty(self):
     "1 if first is empty; 2 if first is a duplicate, False otherwise."
     val = self.fields[0]
     if not val.strip():
         return 1
     csum = fieldChecksum(val)
     # find any matching csums and compare
     for flds in self.col.db.list(
         "select flds from notes where csum = ? and id != ? and mid = ?",
         csum, self.id or 0, self.mid):
         if stripHTML(splitFields(flds)[0]) == stripHTML(self.fields[0]):
             return 2
     return False
Ejemplo n.º 13
0
 def _updateListItems(self):
     cardInfo = self._getCardInfo(self.did)
     self.cardListWidget.clear()
     posWidth = len(str(len(cardInfo) + 1))
     for i, card in enumerate(cardInfo, start=1):
         if self.settings['prioEnabled']:
             text = '          {} \t{}'.format(card['priority'],
                                               stripHTML(card['title']))
         else:
             text = '❰ {} ❱\t{}'.format(
                 str(i).zfill(posWidth), stripHTML(card['title']))
         item = QListWidgetItem(text)
         item.setData(Qt.UserRole, card)
         self.cardListWidget.addItem(item)
Ejemplo n.º 14
0
def new_name_base(old_base, note):
    """
    Get the base of a new file name

    Look at the information on the card and use the data to create
    a base new name.
    """
    def find_field(note, old_base):
        """
        Compare the  candidate fields and the notes fields.

        Look through the two lists, name_source_fields and the
        note’s items, to find the field we should use. Put in
        function so we can break out of nested loops.

        """
        for sf in name_source_fields:
            for name, value in note.items():
                if name == sf:
                    value = stripHTML(value)
                    # Check here if we have something left. So we
                    # can keep on looking when we have a candidate
                    # field but it’s empty.
                    if value and not old_base in value:
                        # Avoid the field we got the name from
                        # (i.e. the audio, image field).
                        return name, value
        # We got here: no match.
        return None, None

    # Several tries. First, look through the list.
    name, value = find_field(note, old_base)
    if value and not old_base in value:
        return value
    # Still here, next try the sort field.
    name, value = note.items()[mw.col.models.sortIdx(note.model())]
    value = stripHTML(value)
    if value and not old_base in value:
        return value
    for name, value in note.items():
        # Last resort: go through the fields and grab the first
        # non-empty one, except the one with the file.
        value = stripHTML(value)
        if value and not old_base in value:
            return value
    # Well, shoot. Looks like the only field with anything interesting
    # is the one with the file. (Almost reasonable. One-side cards to
    # just listen to something and decide without further info if you
    # recoginze that.)
    raise ValueError(_(u'No data for new name found'))
Ejemplo n.º 15
0
def doNote(note):
    changed = 0
    try:

        #This should be the dictionary form of the word
        srcTxt = stripHTML(note[expField])
        #strip any readings
        srcTxt = re.sub('(\[.*\])', '', srcTxt)

        #wtfdowedo
        qjapR, ajapR, engR = find_examples(srcTxt)
        if len(qjapR) < 1:
            return False

        Examples = '<br>'.join(ajapR)
        Questions = '<br>'.join(qjapR)
        English = '<br>'.join(engR)

        if (note['Tatoeba Examples'] != Examples
                or note['Tatoeba English'] != English
                or note['Tatoeba Questions'] != Questions):
            note['Tatoeba Examples'] = Examples
            note['Tatoeba English'] = English
            note['Tatoeba Questions'] = Questions
            return True
        return False
    except KeyError:
        return False
Ejemplo n.º 16
0
def hanzi_context(txt, extra, context, tag, fullname):
    '''
    For use on a Hanzi field.
    Return a list of all the other Hanzi synonyms, with the common characters hidden,
    to allow the user to identify the correct hanzi from a note.
    '''
    other_hanzi = []
    for k, v in context.iteritems():
        if re.match(r'Hanzi.*', k, flags=re.IGNORECASE) and v != txt:
            other_hanzi += [k]
    if len(other_hanzi) < 1:
        return ""
    other_hanzi.sort()
    other_hanzi_values = []
    for v in other_hanzi:
        value = stripHTML(re.sub(r, r'\1', no_sound(context[v])))
        if len(value) > 0:
            other_hanzi_values += [value]
    if len(other_hanzi_values) < 1:
        return ""

    def concat(a, b):
        return a + " / " + b

    context_string = reduce(concat, other_hanzi_values)
    for h in txt:
        if h >= u'\u4e00' and h <= u'\u9fff':
            context_string = re.sub(h, " _ ", context_string)
    context_string = re.sub("  ", " ", context_string)
    return context_string
Ejemplo n.º 17
0
def per(st, n):
    notecfg = getFilter(n)
    if notecfg is None:
        return

    changed = False
    proper_nouns_known = cfg('Option_ProperNounsAlreadyKnown')

    morphemizer = getMorphemizerByName(notecfg['Morphemizer'])
    for f in notecfg['Fields']:
        ms = getMorphemes(morphemizer, stripHTML(n[f]), n.tags)

        for m in sorted(ms, key=lambda x: len(x.inflected),
                        reverse=True):  # largest subs first
            locs = allDb().getMatchingLocs(m)
            mat = max(loc.maturity for loc in locs) if locs else 0

            if (proper_nouns_known
                    and m.isProperNoun()) or (mat >= cfg('threshold_known')):
                continue

            n[f] = nonSpanSub('(%s)' % m.inflected, '<b>\\1</b>', n[f])
            changed = True
    if changed:
        n.flush()

    return st
Ejemplo n.º 18
0
def TTS_record_old(text, language):
    text = re.sub("\[sound:.*?\]", "",
                  stripHTML(text.replace("\n", "")).encode('utf-8'))
    address = TTS_ADDRESS + '?tl=' + language + '&q=' + quote_plus(text)

    file = util.generateFileName(text, 'g',
                                 slanguages[get_language_id(language)][2])
    if subprocess.mswindows:
        subprocess.Popen([
            'mplayer.exe', '-ao', 'win32', '-slave', '-user-agent',
            "'Mozilla/5.0'", address, '-dumpstream', '-dumpfile', file
        ],
                         startupinfo=util.si,
                         stdin=PIPE,
                         stdout=PIPE,
                         stderr=STDOUT).wait()
        if not config.quote_mp3:
            return file.decode(slanguages[get_language_id(language)][2])
    else:
        subprocess.Popen([
            'mplayer', '-slave', '-user-agent', "'Mozilla/5.0'", address,
            '-dumpstream', '-dumpfile', file
        ],
                         stdin=PIPE,
                         stdout=PIPE,
                         stderr=STDOUT).wait()
    return file.decode('utf-8')
Ejemplo n.º 19
0
def TTS_read(text, language=TTS_language):

    text = stripHTML(text.replace("\n", "")).encode("utf-8")

    text = text.replace(chr(194), " ")

    # 	address = TTS_ADDRESS+'?tl='+language+'&q='+ quote_plus(text)
    address = (
        "http://api.ispeech.org/api/rest?apikey=8d1e2e5d3909929860aede288d6b974e&Speed=-3&format=mp3&action=convert&text="
        + quote_plus(text)
    )

    if subprocess.mswindows:
        if speech_engine == "Akapela":
            param = ["SayStatic.exe", text]
        else:
            param = ["1.bat", quote_plus(text)]
        if subprocessing:
            subprocess.Popen(param, startupinfo=si, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
        else:
            subprocess.Popen(param, startupinfo=si, stdin=PIPE, stdout=PIPE, stderr=STDOUT).communicate()
    else:
        if speech_engine == "Akapela":
            param = ["SayStatic.exe", text]
        else:
            param = ["1.bat", quote_plus(text)]
        if subprocessing:
            subprocess.Popen(param, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
        else:
            subprocess.Popen(param, stdin=PIPE, stdout=PIPE, stderr=STDOUT).communicate()
Ejemplo n.º 20
0
Archivo: models.py Proyecto: zw/libanki
def formatQA(cid, mid, fact, tags, cm):
    "Return a dict of {id, question, answer}"
    d = {'id': cid}
    fields = {}
    for (k, v) in fact.items():
        fields["text:"+k] = stripHTML(v[1])
        if v[1]:
            fields[k] = '<span class="fm%s">%s</span>' % (
                hexifyID(v[0]), v[1])
        else:
            fields[k] = u""
    fields['tags'] = tags[0]
    fields['Tags'] = tags[0]
    fields['modelTags'] = tags[1]
    fields['cardModel'] = tags[2]
    # render q & a
    ret = []
    for (type, format) in (("question", cm.qformat),
                           ("answer", cm.aformat)):
        try:
            html = format % fields
        except (KeyError, TypeError, ValueError):
            html = _("[invalid question/answer format]")
        d[type] = runFilter("formatQA", html, type, cid, mid, fact, tags, cm)
    return d
Ejemplo n.º 21
0
def hanzi_context(txt, extra, context, tag, fullname):
    '''
    For use on a Hanzi field.
    Return a list of all the other Hanzi synonyms, with the common characters hidden,
    to allow the user to identify the correct hanzi from a note.
    '''
    other_hanzi = []
    for k, v in context.iteritems():
        if re.match(r'Hanzi.*', k, flags=re.IGNORECASE) and v != txt :
            other_hanzi += [k]
    if len(other_hanzi)<1:
        return ""
    other_hanzi.sort()
    other_hanzi_values = []
    for v in other_hanzi:
        value = stripHTML(re.sub(r, r'\1', no_sound(context[v]))) 
        if len(value)>0:
            other_hanzi_values += [value]
    if len(other_hanzi_values)<1:
        return ""
    def concat(a, b):
        return a + " / " + b
    context_string = reduce(concat, other_hanzi_values)
    for h in txt:
        if  h >= u'\u4e00' and h <= u'\u9fff':
            context_string = re.sub(h, " _ ", context_string)
    context_string = re.sub("  ", " ", context_string)
    return context_string
Ejemplo n.º 22
0
 def playOSXsayTTS(text, voice):
     text = re.sub("\[sound:.*?\]", "",
                   stripHTML(text.replace("\n", "")).encode('utf-8'))
     subprocess.Popen(['say', '-v', voice, text],
                      stdin=PIPE,
                      stdout=PIPE,
                      stderr=STDOUT).communicate()
Ejemplo n.º 23
0
def playEkhoTTS(text, language):
    text = re.sub("\[sound:.*?\]", "",
                  stripHTML(text.replace("\n", "")).encode('utf-8'))
    subprocess.Popen(['ekho', '-v', language, text],
                     stdin=PIPE,
                     stdout=PIPE,
                     stderr=STDOUT).communicate()
Ejemplo n.º 24
0
def formatQA(cid, mid, fact, tags, cm, deck,  build=False):
    "Return a dict of {id, question, answer}"
    d = {'id': cid}
    fields = {}
    for (k, v) in fact.items():
        fields["text:"+k] = stripHTML(v[1])
        if v[1]:
            fields[k] = '<span class="fm%s">%s</span>' % (
                hexifyID(v[0]), v[1])
        else:
            fields[k] = u""
    fields['tags'] = tags[0]
    fields['Tags'] = tags[0]
    fields['modelTags'] = tags[1]
    fields['cardModel'] = tags[2]
    # render q & a
    ret = []
    for (type, format) in (("question", cm.qformat),
                           ("answer", cm.aformat)):
        # convert old style
        format = re.sub("%\((.+?)\)s", "{{\\1}}", format)
        # allow custom rendering functions & info
        fields = runFilter("prepareFields", fields, cid, mid, fact, tags, cm, deck)
        html = render(format, fields)
        d[type] = runFilter("formatQA", html, type, cid, mid, fact, tags, cm, deck,  build)
    return d
Ejemplo n.º 25
0
    def typeAnsAnswerFilter(self, buf):
        if not self.typeCorrect:
            return re.sub(self.typeAnsPat, "", buf)
        # tell webview to call us back with the input content
        self.web.eval("_getTypedText();")
        # munge correct value
        parser = HTMLParser.HTMLParser()
        cor = stripHTML(self.mw.col.media.strip(self.typeCorrect))
        cor = parser.unescape(cor)
        given = self.typedAnswer
        # compare with typed answer
        res = self.correct(cor, given)
        if cor != given:
            # Wrap the extra text in an id-ed span.
            res += u"<span id=rightanswer><br> {0} <br> {1} </span>".format(
                _(u"Correct answer was:"), cor)
        # and update the type answer area
        def repl(match):
            # can't pass a string in directly, and can't use re.escape as it
            # escapes too much
            return """
<span style="font-family: '%s'; font-size: %spx">%s</span>""" % (
                self.typeFont, self.typeSize, res)

        return re.sub(self.typeAnsPat, repl, buf)
def historyRestore(self, mode, sorted_res, model):
    n = self.currentField
    field = model['flds'][n]['name']
    last_val = {}
    keys = []
    for nid in sorted_res[:100]:
        oldNote = self.note.col.getNote(nid)
        if field in oldNote:
            html = oldNote[field]
        else:
            try:
                html = oldNote.fields[n]
            except IndexError:
                pass
        if html.strip():
            text = stripHTML(html)
        else:
            text = None
        if text and text not in last_val:
            keys.append(text)
            last_val[text] = html
    if not last_val:
        tooltip("No prior entries for this field found.")
        return False
    txt = "Set field to:"
    (text, ret) = myGetField(self.parentWindow, 
            txt, keys, title="Field History")
    if not ret or not text.strip() or text not in last_val:
        return False
    self.note[field] = last_val[text]
Ejemplo n.º 27
0
 def _processHtml(self, mime):
     html = mime.html()
     if self.strip:
         html = stripHTML(html)
     mime = QMimeData()
     mime.setHtml(html)
     return mime
Ejemplo n.º 28
0
def doNote(note, isBulk=0):
    try:

        #Strip out any annoying HTML
        srcTxt = stripHTML(note[expField])
        
        #get list of results and cancel if none
        results = getMeaning(srcTxt, isBulk)
        reading = ''
        if not results:
            return False
        
        
        #Insert results
        if results[1]:
            reading = "[" + results[1] + "]"
        
        if note[definitionField] != results[2] \
        or (note[dictionaryForm] != results[0] + reading):
            
            note[definitionField] = results[2]
            note[dictionaryForm] = results[0] + reading
            
            #return True for a refresh
            return True
        
        #if no changed were made, return false so no refresh happens
        return False
    except KeyError:
        return False
Ejemplo n.º 29
0
Archivo: find.py Proyecto: ChYi/libanki
    def _findField(self, token, isNeg):
        field = value = ''
        parts = token.split(':', 1);
        field = parts[0].lower()
        value = "%" + parts[1].replace("*", "%") + "%"
        # find models that have that field
        mods = {}
        for m in self.deck.models().values():
            for f in m.fields:
                if f['name'].lower() == field:
                    mods[m.id] = (m, f['ord'])
        if not mods:
            # nothing has that field
            self.lims['valid'] = False
            return
        # gather fids
        regex = value.replace("%", ".*")
        fids = []
        for (id,mid,flds) in self.deck.db.execute("""
select id, mid, flds from facts
where mid in %s and flds like ? escape '\\'""" % (
                         ids2str(mods.keys())),
                         "%" if self.full else value):
            flds = splitFields(flds)
            ord = mods[mid][1]
            str = flds[ord]
            if self.full:
                str = stripHTML(str)
            if re.search(regex, str):
                fids.append(id)
        extra = "not" if isNeg else ""
        self.lims['fact'].append("id %s in %s" % (extra, ids2str(fids)))
Ejemplo n.º 30
0
    def typeAnsAnswerFilter(self, buf):
        # tell webview to call us back with the input content
        self.web.eval("_getTypedText();")
        if not self.typeCorrect or not self.typedAnswer:
            return re.sub(self.typeAnsPat, "", buf)
        origSize = len(buf)
        buf = buf.replace("<hr id=answer>", "")
        hadHR = len(buf) != origSize
        # munge correct value
        parser = HTMLParser.HTMLParser()
        cor = stripHTML(self.mw.col.media.strip(self.typeCorrect))
        cor = parser.unescape(cor)
        given = self.typedAnswer
        # compare with typed answer
        res = self.correct(given, cor, showBad=False)

        # and update the type answer area
        def repl(match):
            # can't pass a string in directly, and can't use re.escape as it
            # escapes too much
            s = """
<span style="font-family: '%s'; font-size: %spx">%s</span>""" % (
                self.typeFont, self.typeSize, res)
            if hadHR:
                # a hack to ensure the q/a separator falls before the answer
                # comparison when user is using {{FrontSide}}
                s = "<hr id=answer>" + s
            return s

        return re.sub(self.typeAnsPat, repl, buf)
Ejemplo n.º 31
0
    def return_data(idx):
        """
        Return a cleaned-up version of the field content.

        Get the text, remove html, and return the field name, the
        clean text, and what we got when we tried to split into kanji
        and kana, when different from the text.
        """
        text = note[field_names[idx]]
        # This is taken from aqt/browser.py.
        text = text.replace(u'<br>', u' ')
        text = text.replace(u'<br />', u' ')
        if strip_interpunct:
            text = text.replace(u'・', u'')
        text = stripHTML(text)
        text = stripSounds(text)
        # Reformat so we have exactly one space between words.
        text = u' '.join(text.split())
        if not text and not get_empty:
            raise ValueError('Source field empty')
        # We pass the reading/plain on to the update dialog. We don't
        # look at the texts any more to decide what to do. So don't
        # set anything to empty here. Rather do the split even if it
        # is pointless.
        base = furigana.kanji(text)
        ruby = furigana.kana(text)
        return field_names[idx], fname, text, base, ruby, readings
Ejemplo n.º 32
0
def doNote(note):
    
    try:
        changed = 0
        # Strip out any annoying HTML
        srcTxt = stripHTML(note[expField])
        
        # add splits of 6
        kanjis = re.findall(ur'[\u4e00-\u9fbf]', srcTxt)
        
        
        note['Kanji Removed All'] = re.sub(ur'[\u4e00-\u9fbf]', '_', srcTxt)
        
        # clear all the kanji fields
        for i in range(1, 7):
            if len(kanjis) >= i:
                if (note['Kanji Removed ' + str(i)] != re.sub(kanjis[i - 1], '_', srcTxt)):
                    note['Kanji Removed ' + str(i)] = re.sub(kanjis[i - 1], '_', srcTxt)
                    changed = 1
            else:
                if (note['Kanji Removed ' + str(i)] != ''):
                    note['Kanji Removed ' + str(i)] = ''
                    changed = 1
        
    except KeyError:
        raise    
    
    if changed == 1:
        return True
    else:
        return False
Ejemplo n.º 33
0
def sel_to_external_editor(note, selected, block=False, lang=None):
    # if not selected:
    #     tooltip("no text selected.")
    #     return
    selected = selected.replace(" ", " ")  # remove nbsp;
    if not lang:
        fldname = gc("file extension from field")
        if not fldname:
            tooltip("value missing from config")
            return
        for fname, fcont in note.items():
            if fname == fldname:
                lang = stripHTML(fcont)
        if not lang:
            for t in note.tags:
                for k, v in gc("tags to file ending", {}).items():
                    for l in v:
                        if t == l:
                            lang = k
                            break
    if lang is None:
        tooltip("no language set. no relevant field or tag found.")
        return
    fn = gc("custom_files_for_langs", {}).get(lang)
    suf = "Irrelevant" if fn else f".{lang}"
    try:
        text = edit_string_externally_and_return_mod(selected,
                                                     filename=fn,
                                                     block=block,
                                                     suffix=suf)
    except RuntimeError:
        tooltip('Error when trying to edit externally')
        return
    if block:
        return text
Ejemplo n.º 34
0
    def _findField(self, token, isNeg):
        field = value = ''
        parts = token.split(':', 1);
        field = parts[0].lower()
        value = "%" + parts[1].replace("*", "%") + "%"
        # find models that have that field
        mods = {}
        for m in self.col.models.all():
            for f in m['flds']:
                if f['name'].lower() == field:
                    mods[str(m['id'])] = (m, f['ord'])
        if not mods:
            # nothing has that field
            self.lims['valid'] = False
            return
        # gather nids
        regex = value.replace("_", ".").replace("%", ".*")
        nids = []
        for (id,mid,flds) in self.col.db.execute("""
select id, mid, flds from notes
where mid in %s and flds like ? escape '\\'""" % (
                         ids2str(mods.keys())),
                         "%" if self.full else value):
            flds = splitFields(flds)
            ord = mods[str(mid)][1]
            strg = flds[ord]
            if self.full:
                strg = stripHTML(strg)
            if re.search(regex, strg):
                nids.append(id)
        extra = "not" if isNeg else ""
        self.lims['preds'].append("""
n.mid in %s and n.id %s in %s""" % (
    ids2str(mods.keys()), extra, ids2str(nids)))
Ejemplo n.º 35
0
    def return_data(idx):
        """
        Return a cleaned-up version of the field content.

        Get the text, remove html, and return the field name, the
        clean text, and what we got when we tried to split into kanji
        and kana, when different from the text.
        """
        text = note[field_names[idx]]
        # This is taken from aqt/browser.py.
        text = text.replace('<br>', ' ')
        text = text.replace('<br />', ' ')
        if strip_interpunct:
            text = text.replace('・', '')
        text = stripHTML(text)
        text = stripSounds(text)
        # Reformat so we have exactly one space between words.
        text = ' '.join(text.split())
        if not text and not get_empty:
            raise ValueError('Source field empty')
        # We pass the reading/plain on to the update dialog. We don't
        # look at the texts any more to decide what to do. So don't
        # set anything to empty here. Rather do the split even if it
        # is pointless.
        base = kanji_filter(text)
        ruby = kana_filter(text)
        return field_names[idx], fname, text, base, ruby, readings
Ejemplo n.º 36
0
def doNote(note):

    try:
        changed = 0
        # Strip out any annoying HTML
        srcTxt = stripHTML(note[expField])

        # add splits of 6
        kanjis = re.findall(ur"[\u4e00-\u9fbf]", srcTxt)

        note["Kanji Removed All"] = re.sub(ur"[\u4e00-\u9fbf]", "_", srcTxt)

        # clear all the kanji fields
        for i in range(1, 7):
            if len(kanjis) >= i:
                if note["Kanji Removed " + str(i)] != re.sub(kanjis[i - 1], "_", srcTxt):
                    note["Kanji Removed " + str(i)] = re.sub(kanjis[i - 1], "_", srcTxt)
                    changed = 1
            else:
                if note["Kanji Removed " + str(i)] != "":
                    note["Kanji Removed " + str(i)] = ""
                    changed = 1

    except KeyError:
        raise

    if changed == 1:
        return True
    else:
        return False
Ejemplo n.º 37
0
def playGoogleTTS(text, language):
    text = re.sub("\[sound:.*?\]", "",
                  stripHTML(text.replace("\n", "")).encode('utf-8'))
    address = TTS_ADDRESS + '?tl=' + language + '&q=' + quote_plus(text)

    if subprocess.mswindows:
        param = [
            'mplayer.exe', '-ao', 'win32', '-slave', '-user-agent',
            "'Mozilla/5.0'", address
        ]
        if config.subprocessing:
            subprocess.Popen(param,
                             startupinfo=util.si,
                             stdin=PIPE,
                             stdout=PIPE,
                             stderr=STDOUT)
        else:
            subprocess.Popen(param,
                             startupinfo=util.si,
                             stdin=PIPE,
                             stdout=PIPE,
                             stderr=STDOUT).communicate()
    else:
        param = ['mplayer', '-slave', '-user-agent', "'Mozilla/5.0'", address]
        if config.subprocessing:
            subprocess.Popen(param, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
        else:
            subprocess.Popen(param, stdin=PIPE, stdout=PIPE,
                             stderr=STDOUT).communicate()
Ejemplo n.º 38
0
 def _processHtml(self, mime):
     html = mime.html()
     if self.strip:
         html = stripHTML(html)
     mime = QMimeData()
     mime.setHtml(html)
     return mime
Ejemplo n.º 39
0
                def parse_text(loc_corpus, text):
                    parsed_morphs = getMorphemes(morphemizer, stripHTML(text))
                    if len(parsed_morphs) == 0:
                        return

                    loc_corpus.add_line_morphs(
                        [m.deinflected() for m in parsed_morphs])
Ejemplo n.º 40
0
    def typeAnsAnswerFilter(self, buf):
        if not self.typeCorrect:
            return re.sub(self.typeAnsPat, "", buf)
        origSize = len(buf)
        buf = buf.replace("<hr id=answer>", "")
        hadHR = len(buf) != origSize
        # munge correct value
        parser = html.parser.HTMLParser()
        cor = self.mw.col.media.strip(self.typeCorrect)
        cor = re.sub("(\n|<br ?/?>|</?div>)+", " ", cor)
        cor = stripHTML(cor)
        # ensure we don't chomp multiple whitespace
        cor = cor.replace(" ", "&nbsp;")
        cor = parser.unescape(cor)
        cor = cor.replace("\xa0", " ")
        cor = cor.strip()
        given = self.typedAnswer
        # compare with typed answer
        res = self.correct(given, cor, showBad=False)
        # and update the type answer area
        def repl(match):
            # can't pass a string in directly, and can't use re.escape as it
            # escapes too much
            s = """
<span style="font-family: '%s'; font-size: %spx">%s</span>""" % (
                self.typeFont, self.typeSize, res)
            if hadHR:
                # a hack to ensure the q/a separator falls before the answer
                # comparison when user is using {{FrontSide}}
                s = "<hr id=answer>" + s
            return s
        return re.sub(self.typeAnsPat, repl, buf)
Ejemplo n.º 41
0
    def _get_definition(self, word):
        # Sanitize string
        word = stripHTML(word)
        start_token = '<section class="word__defination--2q7ZH">'
        end_token = '</section>'
        context = ssl._create_unverified_context()
        url = 'https://www.etymonline.com/word/{}'.format(word)
        try:
            response = urllib.request.urlopen(url, context=context)
        except Exception:
            return 'No etymology entry found.'

        html = response.read().decode('utf-8')
        start = html.index(start_token) + len(start_token)
        end = html.index(end_token)
        return stripHTML(html[start:end])
Ejemplo n.º 42
0
	def playsapi5TTS(text, voice):
		text = re.sub("\[sound:.*?\]", "", stripHTML(text.replace("\n", "")))
		param = [vbs_launcher, sapi5_path,'-hex', '-voice', util.dumpUnicodeStr(voice), util.dumpUnicodeStr(text)]
		if config.subprocessing:
			subprocess.Popen(param, startupinfo=util.si, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
		else:
			subprocess.Popen(param, startupinfo=util.si, stdin=PIPE, stdout=PIPE, stderr=STDOUT).communicate()
Ejemplo n.º 43
0
def free_media_name(base, end):
    """
    Return a useful media name.

    Return a name that can be used for the media file. That is one
    that based on the base name and end, but doesn't exist, nor does
    it clash with another file different only in upper/lower case.
    """
    base = stripHTML(base)
    # Basically stripping the 'invalidFilenameChars'. (Not tested too much).
    base = re.sub("[\\/:\*?'\"<>\|]", "", base)
    if normalize_file_names_on_cards and isMac:
        base = unicodedata.normalize("NFD", base)
    mdir = mw.col.media.dir()
    if not exists_lc(mdir, base + end):
        return os.path.join(mdir, base + end), base + end
    for i in range(1, 10000):
        # Don't be silly. Give up after 9999 tries (by falling out of
        # this loop).
        long_name = u"{0}_{1}{2}".format(base, i, end)
        if not exists_lc(mdir, long_name):
            # New: return both full path and the file name (with ending).
            return os.path.join(mdir, long_name), long_name
    # The only way we can have arrived here is by unsuccessfully
    # trying the 10000 names.
    raise ValueError("Could not find free name.")
Ejemplo n.º 44
0
def doNote(note, expF=None , kanjiDField=None):
    
    #If no fields were given then use the defaults
    if expF==None:
        global expressionField
    else:
        expressionField = expF
        
    if kanjiDField==None:
        global kanjiDstField
    else:
        kanjiDstField = kanjiDField
        
    #Strip out any annoying HTML
    srcTxt = stripHTML(note[expField])
    
    
    changed = 0
    
    #Add the data to the dst field
    result = joinseparator.join(lookupKanjiInfo(srcTxt, 'keyword'))
    if result and note[kanjiDstField] != result:
        changed = 1
        note[kanjiDstField] = result 
    
    
   
    
    if changed == 1:
        return True
    else:
        return False
Ejemplo n.º 45
0
def free_media_name(base, end):
    u"""Return a useful media name

    Return a pair of a file name that can be used for the media file,
    and the whole file path. The name is based on the base name and
    end, but doesn’t exist, nor does it clash with another file
    different only in upper/lower case.
    If no name can be found, a ValueError is raised.
    """
    base = stripHTML(base)
    # Strip the ‘invalidFilenameChars’ by hand.
    base = re.sub(ur'[\\/:\*?\'"<>\|]', '', base)
    base = unicodedata.normalize('NFC', base)
    # Looks like the normalization issue has finally been
    # solved. Always use NFC versions of file names now.
    mdir = mw.col.media.dir()
    if not exists_lc(mdir, base + end):
        return os.path.join(mdir, base + end), base + end
    for i in range(1, 10000):
        # Don't be silly. Give up after 9999 tries (by falling out of
        # this loop).
        long_name = u'{0}_{1}{2}'.format(base, i, end)
        if not exists_lc(mdir, long_name):
            return os.path.join(mdir, long_name), long_name
    # The only way we can have arrived here is by unsuccessfully
    # trying the 10000 names.
    raise ValueError('Could not find free name.')
Ejemplo n.º 46
0
def doNote(note, isBulk=0):
    try:

        #Strip out any annoying HTML
        srcTxt = stripHTML(note[expField])

        #get list of results and cancel if none
        results = getMeaning(srcTxt, isBulk)
        reading = ''
        if not results:
            return False

        #Insert results
        if results[1]:
            reading = "[" + results[1] + "]"


        if note[definitionField] != results[2] \
        or (note[dictionaryForm] != results[0] + reading) \
        or (note[expField] != results[0]):
            note[expField] = results[0]
            note[definitionField] = results[2]
            note[dictionaryForm] = results[0] + reading

            #return True for a refresh
            return True

        #if no changed were made, return false so no refresh happens
        return False
    except KeyError:
        return False
Ejemplo n.º 47
0
Archivo: reviewer.py Proyecto: bqv/anki
    def typeAnsAnswerFilter(self, buf):
        if not self.typeCorrect:
            return re.sub(self.typeAnsPat, "", buf)
        # tell webview to call us back with the input content
        self.web.eval("_getTypedText();")
        # munge correct value
        parser = HTMLParser.HTMLParser()
        cor = stripHTML(self.mw.col.media.strip(self.typeCorrect))
        cor = parser.unescape(cor)
        given = self.typedAnswer
        # compare with typed answer
        res = self.correct(cor, given)
        if cor != given:
            # Wrap the extra text in an id-ed span.
            res += u"<span id=rightanswer><br> {0} <br> {1} </span>".format(_(u"Correct answer was:"), cor)
        # and update the type answer area
        def repl(match):
            # can't pass a string in directly, and can't use re.escape as it
            # escapes too much
            return """
<span style="font-family: '%s'; font-size: %spx">%s</span>""" % (
                self.typeFont,
                self.typeSize,
                res,
            )

        return re.sub(self.typeAnsPat, repl, buf)
Ejemplo n.º 48
0
def doNote(note):
        changed = 0
        try:
            
            #This should be the dictionary form of the word
            srcTxt = stripHTML(note[expField])
            #strip any readings
            srcTxt = re.sub('(\[.*\])', '', srcTxt)
            
            
            #wtfdowedo
            qjapR, ajapR, engR = find_examples(srcTxt)
            if len(qjapR) <1:
                return False
            
            Examples = '<br>'.join(ajapR)
            Questions = '<br>'.join(qjapR)
            English = '<br>'.join(engR)
            
            
            if(note['Tatoeba Examples'] != Examples or
            note['Tatoeba English'] != English or
            note['Tatoeba Questions'] != Questions):
                note['Tatoeba Examples'] = Examples
                note['Tatoeba English'] = English
                note['Tatoeba Questions'] = Questions
                return True
            return False
        except KeyError:
            return False
Ejemplo n.º 49
0
def kana_type_ans_answer_filter(self, buf):
    # Redo bits of typeQuesAnswerFilter to get the field name typed in
    # and most of the old typeAnsAnswerFilter.
    m = re.search(self.typeAnsPat, buf)
    if not self.typeCorrect:
        return re.sub(self.typeAnsPat, "", buf)
    # tell webview to call us back with the input content
    # Copy-and-pasted. I guess it’s harmless
    self.web.eval("_getTypedText();")
    # munge correct value
    model_name = self.card.model()[u'name']
    # Cascade of tests
    if m:
        fld = m.group(1)
        # if not fld.startswith("cq:") and reading_field in fld.lower():
        if not fld.startswith("cq:") and reading_field in fld.lower() \
                and japanese_model in model_name.lower():
            cor = self.mw.col.media.strip(stripHTML(self.typeCorrect))
            # The extra kana(...) here is the whole point of this plugin.
            res = self.correct(kana(cor), self.typedAnswer)
            return re.sub(self.typeAnsPat, """
<span id=coranskana style="font-family: '%s'; font-size: %spx">%s</span>""" %
                          (self.typeFont, self.typeSize, res), buf)
    # Still here: we failed one of our tests. So do it the old way.
    return old_type_ans_answer_filter(self, buf)
Ejemplo n.º 50
0
def _deHTML(content):
	# replace HTML-symbols
	# NOTE: not sure if this is correct
	lines = content.replace('&nbsp;', ' ')
	lines = re.sub('<br( /)?>|<div>|\r\n|\r', '\n', lines)
	#return anki.utils.stripHTML(lines).split('\n')[1:]
	return stripHTML(lines)[1:]
Ejemplo n.º 51
0
    def typeAnsAnswerFilter(self, buf):
        # tell webview to call us back with the input content
        self.web.eval("_getTypedText();")
        if not self.typeCorrect:
            return re.sub(self.typeAnsPat, "", buf)
        origSize = len(buf)
        buf = buf.replace("<hr id=answer>", "")
        hadHR = len(buf) != origSize
        # munge correct value
        parser = HTMLParser.HTMLParser()
        cor = stripHTML(self.mw.col.media.strip(self.typeCorrect))
        # ensure we don't chomp multiple whitespace
        cor = cor.replace(" ", "&nbsp;")
        cor = parser.unescape(cor)
        cor = cor.replace(u"\xa0", " ")
        given = self.typedAnswer
        # compare with typed answer
        res = self.correct(given, cor, showBad=False)
        # and update the type answer area
        def repl(match):
            # can't pass a string in directly, and can't use re.escape as it
            # escapes too much
            s = """
<span style="font-family: '%s'; font-size: %spx">%s</span>""" % (
                self.typeFont, self.typeSize, res)
            if hadHR:
                # a hack to ensure the q/a separator falls before the answer
                # comparison when user is using {{FrontSide}}
                s = "<hr id=answer>" + s
            return s
        return re.sub(self.typeAnsPat, repl, buf)
Ejemplo n.º 52
0
def historyRestore(self, mode, results, model, fld):
    field = model['flds'][fld]['name']
    last_val = {}
    keys = []
    for nid in results[:100]:
        oldNote = self.note.col.getNote(nid)
        if field in oldNote:
            html = oldNote[field]
        else:
            try:
                html = oldNote.fields[fld]
            except IndexError:
                pass
        if html.strip():
            text = stripHTML(html)
        else:
            text = None
        if text and text not in last_val:
            keys.append(text)
            last_val[text] = html
    if not last_val:
        tooltip("No prior entries for this field found.")
        return False
    txt = "Set field to:"
    (text, ret) = myGetField(self.parentWindow,
                             txt,
                             keys,
                             title="Field History")
    if not ret or not text.strip() or text not in last_val:
        return False
    self.note[field] = last_val[text]
Ejemplo n.º 53
0
def historyRestore(self, mode, sorted_res, model):
    n = self.currentField
    field = model['flds'][n]['name']
    last_val = {}
    for nid in sorted_res[:100]:
        oldNote = self.note.col.getNote(nid)
        if field in oldNote:
            html = oldNote[field]
        else:
            try:
                html = oldNote.fields[n]
            except IndexError:
                pass
        if html.strip():
            text = stripHTML(html)
        else:
            text = None
        if text and text not in last_val:
            last_val[text] = html
    if not last_val:
        tooltip("No prior entries for this field found.")
        return False
    txt = "Set field to:"
    (text, ret) = myGetField(self.parentWindow,
                             txt,
                             last_val.keys(),
                             title="Field History")
    if not ret or not text.strip() or text not in last_val:
        return False
    self.note[field] = last_val[text]
Ejemplo n.º 54
0
def __editor_helper(self, saveback):
    lang = gc("editor field content and save back file extension"
              ) if saveback else None
    if saveback:
        fieldcontent = self.note.fields[thefield]
        if fieldcontent.count(unique_before) > 1 or fieldcontent.count(
                unique_after) > 1:
            tooltip("Aborting. helper strings too often in text field.")
            set_field_to_text(self, thefield,
                              oldcontent)  # restore old content
            return
        before, rest = fieldcontent.split(unique_before)
        selection, after = rest.split(unique_after)
        stripped = stripHTML(selection)
    else:
        stripped = self.web.selectedText()
    out = sel_to_external_editor(self.note,
                                 stripped,
                                 block=saveback,
                                 lang=lang)
    if saveback:
        if out:
            new = before + adjust_text_to_html(out) + after
        else:  # restore old content, remove temporary insertion
            new = oldcontent
        set_field_to_text(self, thefield, new)
Ejemplo n.º 55
0
def _get_character(card: Card, config: DeckConfig) -> str:
    """ Extracts the character to write from `card`.

    Returns:
        character (str): The character contained in field `config.field` of `card`.
    
    Raises:
        MaobiException: 
            - If there is no field called `deck.field` in `card`.
            - If the field called `config.field` is empty.
            - If the field called `config.field` contains more than one character.

    """

    # Check that the character field is really there
    note = card.note()
    note_type = note.model()["name"]
    field_name = config.field

    if field_name not in note:
        raise MaobiException(
            f"There is no field '{field_name}' in note type {note_type}!")

    # Check that the character is really exactly one character
    character = note[field_name]
    character = stripHTML(character)

    if len(character) == 0:
        raise MaobiException(f"Field '{field_name}' was empty!")

    if len(character) > 1:
        raise MaobiException(
            f"Expected a single character, but was '{character}'!")

    return character
Ejemplo n.º 56
0
    def _findField(self, token, isNeg):
        field = value = ''
        parts = token.split(':', 1);
        field = parts[0].lower()
        value = "%" + parts[1].replace("*", "%") + "%"
        # find models that have that field
        mods = {}
        for m in self.col.models.all():
            for f in m['flds']:
                if f['name'].lower() == field:
                    mods[str(m['id'])] = (m, f['ord'])
        if not mods:
            # nothing has that field
            self.lims['valid'] = False
            return
        # gather nids
        regex = value.replace("%", ".*")
        nids = []
        for (id,mid,flds) in self.col.db.execute("""
select id, mid, flds from notes
where mid in %s and flds like ? escape '\\'""" % (
                         ids2str(mods.keys())),
                         "%" if self.full else value):
            flds = splitFields(flds)
            ord = mods[str(mid)][1]
            strg = flds[ord]
            if self.full:
                strg = stripHTML(strg)
            if re.search(regex, strg):
                nids.append(id)
        extra = "not" if isNeg else ""
        self.lims['preds'].append("n.id %s in %s" % (extra, ids2str(nids)))