Beispiel #1
0
def getRows():
    finder = Finder(mw.col)
    #all notes
    cids = finder.findCards("")
    for cid in cids:
        card = mw.col.getCard(cid)
        deck = mw.col.decks.get(card.did)
        deckName = deck["name"]
        note = card.note()
        model = note._model
        modelName = model["name"]
        try:
            template = model["tmpls"][card.ord]
        except IndexError:
            print(
                f"""Card {cid} has ord {card.ord} and model {modelName}, which have only {len(model["tmpls"])} cards.""",
                file=sys.stderr)
            continue
        templateName = template["name"]
        try:
            yield (card.id, card.nid, deckName, templateName, card.mod,
                   card.usn, card.type, card.queue, card.due, card.ivl,
                   card.factor, card.reps, card.lapses, card.odue, card.odid)
        except:
            raise
Beispiel #2
0
def runBulkFill(mw, config, notifier, updaters, field, updatehow, notification):
    if mw.web.key == "deckBrowser":
        return showInfo(u"No deck selected 同志!")

    log.info("User triggered missing information fill for %s" % field)
    
    queryStr = "deck:current "
    for tag in config.getmodeltagslist():
        queryStr += " or note:*" + tag + "* "
    notes = Finder(mw.col).findNotes(queryStr)

    for noteId in notes:
        note = mw.col.getNote(noteId)
        # Need a fact proxy because the updater works on dictionary-like objects
        factproxy = pinyin.factproxy.FactProxy(config.candidateFieldNamesByKey, note)
        if field not in factproxy:
            continue
        
        getattr(updaters[field], updatehow)(factproxy, factproxy[field])
        
        # NB: very important to mark the fact as modified (see #105) because otherwise
        # the HTML etc won't be regenerated by Anki, so users may not e.g. get working
        # sounds that have just been filled in by the updater.
        note.flush()
    
    # For good measure, mark the deck as modified as well (see #105)
    mw.col.setMod()

    # DEBUG consider future feature to add missing measure words cards after doing so (not now)
    notifier.info(notification)
Beispiel #3
0
def bulk_fill_all():
    prompt = (
        '<div>This will update <i>all</i> non-audio fields in the current deck.</div>'
        '<div>Please back up your Anki collection first!</div>'
        '<div><b>Continue?</b></div>')

    if not askUser(prompt):
        return

    note_ids = Finder(mw.col).findNotes('deck:current')
    mw.progress.start(immediate=True, min=0, max=len(note_ids))
    n_updated = 0
    n_failed = 0  # FIXME
    exclude = config.get_fields(['sound', 'mandarinSound', 'cantoneseSound'])

    for i, nid in enumerate(note_ids):
        note = mw.col.getNote(nid)
        fields = [
            f for f in mw.col.models.fieldNames(note.model())
            if f not in exclude
        ]
        n_updated += update_fields(note, 'Hanzi', fields)
        msg = PROGRESS_TEMPLATE % {
            'hanzi': get_hanzi(dict(note)),
            'n_processed': i,
            'n_updated': n_updated,
            'n_failed': n_failed,
        }

        mw.progress.update(label=msg, value=i)
        note.flush()

    mw.progress.finish()
    showInfo('<b>Bulk filling complete</b><br>'
             '<b>Processed:</b> {}<br>'.format(len(note_ids)))
Beispiel #4
0
def bulk_fill_transcript():
    prompt = PROMPT_TEMPLATE.format(
        field_names='<i>transcription</i> and <i>ruby</i>', extra_info='')

    field_groups = [
        'transcription',
        'pinyin',
        'pinyinTaiwan',
        'cantonese',
        'bopomofo',
    ]

    if not askUser(prompt):
        return

    d_has_fields = 0
    d_added_pinyin = 0
    d_updated = 0

    note_ids = Finder(mw.col).findNotes('deck:current')
    mw.progress.start(immediate=True, min=0, max=len(note_ids))

    for i, nid in enumerate(note_ids):
        note = mw.col.getNote(nid)
        copy = dict(note)

        if has_any_field(copy, field_groups) and has_field(
                config['fields']['hanzi'], copy):
            d_has_fields += 1

            msg = '''
            <b>Processing:</b> %(hanzi)s<br>
            <b>Filled pinyin:</b> %(pinyin)d notes<br>
            <b>Updated: </b>%(updated)d fields''' % {
                'hanzi': get_hanzi(copy),
                'pinyin': d_added_pinyin,
                'updated': d_updated,
            }
            mw.progress.update(label=msg, value=i)

            hanzi = get_first(config['fields']['hanzi'], copy)
            results = fill_transcript(hanzi, copy)
            results += fill_bopomofo(hanzi, copy)

            if results > 0:
                d_added_pinyin += 1

            fill_all_rubies(hanzi, copy)
            save_note(note, copy)

    mw.progress.finish()
    msg = '''
    <b>Processing:</b> %(hanzi)s<br>
    <b>Filled pinyin:</b> %(pinyin)d notes<br>
    <b>Updated: </b>%(updated)d fields''' % {
        'hanzi': get_hanzi(copy),
        'pinyin': d_added_pinyin,
        'updated': d_updated,
    }
    showInfo(msg)
def getRows():
    finder = Finder(mw.col)
    #all notes
    nids = finder.findNotes("")
    models = mw.col.models.models
    for nid in nids:
        note = mw.col.getNote(nid)
        mid = note.mid
        model = note._model
        if model is None:
            print(f"Note {nid}'s model {mid}({type(mid)}) is not a model.")
        modelName = model["name"]
        try:
            yield (note.id, note.guid, note.mod, modelName, note.usn)
        except:
            raise
Beispiel #6
0
def bulk_fill_hanzi():
    prompt = '''
    <div>This will update the <i>Simplified</i> and <i>Traditional</i> fields
    in the current deck, if they exist and are empty.</div>
    <div>Please back-up your Anki deck first!</div>
    <div><b>Continue?</b></div>
    '''

    if not askUser(prompt):
        return

    query_str = 'deck:current'
    d_scanned = 0
    d_has_fields = 0
    d_success = 0
    notes = Finder(mw.col).findNotes(query_str)
    mw.progress.start(immediate=True, min=0, max=len(notes))
    for noteId in notes:
        d_scanned += 1
        note = mw.col.getNote(noteId)
        note_dict = dict(note)
        if (has_field(config['fields']['simplified'], note_dict) or has_field(
                config['fields']['traditional'], note_dict)) and has_field(
                    config['fields']['hanzi'], note_dict):
            d_has_fields += 1

            msg = '''
            <b>Processing:</b> %(hanzi)s<br>
            <b>Updated:</b> %(filled)d''' % {
                'hanzi': sanitize_hanzi(note_dict),
                'filled': d_success,
            }
            mw.progress.update(label=msg, value=d_scanned)

            hanzi = get_first(config['fields']['hanzi'], note_dict)

            fill_simp(hanzi, note_dict)
            fill_trad(hanzi, note_dict)

            for f in config['fields']['traditional']:
                if f in note_dict and note_dict[f] != note[f]:
                    note[f] = note_dict[f]
                    d_success += 1

            for f in config['fields']['simplified']:
                if f in note_dict and note_dict[f] != note[f]:
                    note[f] = note_dict[f]
                    d_success += 1

            note.flush()

    msg = '''
    <b>Update complete!</b> %(hanzi)s<br>
    <b>Updated:</b> %(filled)d notes''' % {
        'hanzi': sanitize_hanzi(note_dict),
        'filled': d_success,
    }
    mw.progress.finish()
    showInfo(msg)
Beispiel #7
0
def fill_simp_trad(collection, view_key):
    if view_key == "deckBrowser":
        return showInfo(u"First select one of your decks")
    if not (askUser(
            "<div>This will update the <i>Simplified</i> and <i>Traditional</i> fields in the current deck, if they exist and are empty.</div>\n\n<div>Please back-up your Anki deck first!</div>\n\n<div><b>Continue?</b></div>"
    )):
        return False

    query_str = "deck:current"
    d_scanned = 0
    d_has_fields = 0
    d_success = 0
    d_failed = 0
    notes = Finder(collection).findNotes(query_str)
    mw.progress.start(immediate=True, min=0, max=len(notes))
    for noteId in notes:
        d_scanned += 1
        note = collection.getNote(noteId)
        note_dict = dict(note)  # edit_function routines require a dict
        if (has_field(Simplified_fields, note_dict)
                or has_field(Traditional_fields, note_dict)) and has_field(
                    Hanzi_fields, note_dict):
            d_has_fields += 1

            msg_string = "<b>Processing:</b> %(hanzi)s<br><b>Updated:</b> %(filled)d" % {
                "hanzi": cleanup(no_html(get_any(Hanzi_fields, note_dict))),
                "filled": d_success
            }
            mw.progress.update(label=msg_string, value=d_scanned)

            #Update simplified/traditional fields
            #If it's the same, leave empty,
            #so as to make this feature unobtrusive to simplified chinese users
            hanzi = get_any(Hanzi_fields, note_dict)

            update_Simplified_fields(hanzi, note_dict)
            update_Traditional_fields(hanzi, note_dict)

            # write back to note from dict and flush
            for f in Traditional_fields:
                if note_dict.has_key(f) and note_dict[
                        f] is not None and note_dict[f] <> note[f]:
                    note[f] = note_dict[f]
                    d_success += 1
            for f in Simplified_fields:
                if note_dict.has_key(f) and note_dict[
                        f] is not None and note_dict[f] <> note[f]:
                    note[f] = note_dict[f]
                    d_success += 1
            note.flush()

    msg_string = "<b>Update complete!</b> %(hanzi)s<br><b>Updated:</b> %(filled)d notes" % {
        "hanzi": cleanup(no_html(get_any(Hanzi_fields, note_dict))),
        "filled": d_success
    }
    mw.progress.finish()
    showInfo(msg_string)
Beispiel #8
0
def fill_silhouette():
    if not (askUser(
            "<div>This will update the <i>Silhouette</i> fields in the "
            "current deck.</div>\n\n"
            "<div>Please back-up your Anki deck first!</div>\n\n"
            "<div><b>Continue?</b></div>")):
        return False

    query_str = "deck:current"
    d_scanned = 0
    d_has_fields = 0
    d_success = 0
    notes = Finder(mw.col).findNotes(query_str)
    mw.progress.start(immediate=True, min=0, max=len(notes))
    for noteId in notes:
        d_scanned += 1
        note = mw.col.getNote(noteId)
        note_dict = dict(note)  # edit_function routines require a dict
        if has_field(config.options["fields"]["silhouette"], note_dict):
            d_has_fields += 1

            msg_string = ("<b>Processing:</b> {hangul:s}<br>"
                          "<b>Updated:</b> {filled:d}").format(
                              hangul=cleanup(
                                  no_html(
                                      get_any(
                                          config.options["fields"]["hangul"],
                                          note_dict))),
                              filled=d_success,
                          )
            mw.progress.update(label=msg_string, value=d_scanned)

            hangul = get_any(config.options["fields"]["hangul"], note_dict)

            # Update Silhouette
            update_Silhouette_fields(hangul, note_dict)

            # write back to note from dict and flush
            for f in config.options["fields"]["silhouette"]:
                if f in note_dict and note_dict[f] != note[f]:
                    note[f] = note_dict[f]
                    d_success += 1
            note.flush()

    msg_string = ("<b>Update complete!</b> {hangul:s}<br>"
                  "<b>Updated:</b> {filled:d}").format(
                      hangul=cleanup(
                          no_html(
                              get_any(config.options["fields"]["hangul"],
                                      note_dict))),
                      filled=d_success,
                  )
    mw.progress.finish()
    showInfo(msg_string)
Beispiel #9
0
def fill_silhouette(collection, view_key):
    if view_key == "deckBrowser":
        return showInfo(u"First select one of your decks")
    if not (askUser(
            "<div>This will update the <i>Silhouette</i> fields in the current deck.</div>\n\n<div>Please back-up your Anki deck first!</div>\n\n<div><b>Continue?</b></div>"
    )):
        return False

    query_str = "deck:current"
    d_scanned = 0
    d_has_fields = 0
    d_success = 0
    d_failed = 0
    notes = Finder(collection).findNotes(query_str)
    mw.progress.start(immediate=True, min=0, max=len(notes))
    for noteId in notes:
        d_scanned += 1
        note = collection.getNote(noteId)
        note_dict = dict(note)  # edit_function routines require a dict
        if has_field(Silhouette_fields, note_dict):
            d_has_fields += 1

            msg_string = "<b>Processing:</b> %(hanzi)s<br><b>Updated:</b> %(filled)d" % {
                "hanzi": cleanup(no_html(get_any(Hanzi_fields, note_dict))),
                "filled": d_success
            }
            mw.progress.update(label=msg_string, value=d_scanned)

            hanzi = get_any(Hanzi_fields, note_dict)

            #Update Silhouette
            update_Silhouette_fields(hanzi, note_dict)

            # write back to note from dict and flush
            for f in Silhouette_fields:
                if note_dict.has_key(f) and note_dict[
                        f] is not None and note_dict[f] <> note[f]:
                    note[f] = note_dict[f]
                    d_success += 1
            note.flush()

    msg_string = "<b>Update complete!</b> %(hanzi)s<br><b>Updated:</b> %(filled)d notes" % {
        "hanzi": cleanup(no_html(get_any(Hanzi_fields, note_dict))),
        "filled": d_success
    }
    mw.progress.finish()
    showInfo(msg_string)
Beispiel #10
0
def fill_silhouette():
    prompt = '''
    <div>This will update the <i>Silhouette</i> fields in the current deck.</div>
    <div>Please back-up your Anki deck first!</div>
    <div><b>Continue?</b></div>
    '''

    if not askUser(prompt):
        return

    query_str = 'deck:current'
    d_scanned = 0
    d_has_fields = 0
    d_success = 0
    notes = Finder(mw.col).findNotes(query_str)
    mw.progress.start(immediate=True, min=0, max=len(notes))
    for noteId in notes:
        d_scanned += 1
        note = mw.col.getNote(noteId)
        note_dict = dict(note)
        if has_field(config['fields']['silhouette'], note_dict):
            d_has_fields += 1
            msg = '''
            <b>Processing:</b> %(hanzi)s<br>
            <b>Updated:</b> %(filled)d''' % {
                'hanzi': sanitize_hanzi(note_dict),
                'filled': d_success
            }
            mw.progress.update(label=msg, value=d_scanned)
            hanzi = get_first(config['fields']['hanzi'], note_dict)
            update_Silhouette_fields(hanzi, note_dict)

            # write back to note from dict and flush
            for f in config['fields']['silhouette']:
                if f in note_dict and note_dict[f] != note[f]:
                    note[f] = note_dict[f]
                    d_success += 1
            note.flush()

    msg = '''
    <b>Update complete!</b> %(hanzi)s<br>
    <b>Updated:</b> %(filled)d notes''' % {
        'hanzi': sanitize_hanzi(note_dict),
        'filled': d_success
    }
    mw.progress.finish()
    showInfo(msg)
Beispiel #11
0
def fill_missing():
    notes = Finder(mw.col).findNotes("deck:current")
    mw.progress.start(immediate=True, min=0, max=len(notes))
    scanned = 0
    for noteId in notes:
        scanned += 1
        note = mw.col.getNote(noteId)
        note_dict = dict(note)

        if "Korean" in note_dict:
            korean = cleanup(note_dict["Korean"])

            if "English" in note_dict and cleanup(note_dict["English"]) == "":
                mw.progress.update(label=f"[{korean}] Translating...", value=scanned)
                english = cleanup(note_dict["English"])
                if korean != "" and english == "":
                    translation = lookup(korean)
                    note_dict["Korean"] = korean
                    note_dict["English"] = translation

            if "Hanja" in note_dict and cleanup(note_dict["Hanja"]) == "":
                mw.progress.update(
                    label=f"[{korean}] Looking up Hanja...", value=scanned
                )
                found = hanja.lookup(korean)
                if found is not None:
                    note_dict["Hanja"] = found["hanja"]

            if "Silhouette" in note_dict and cleanup(note_dict["Silhouette"]) == "":
                mw.progress.update(
                    label=f"[{korean}] Processing silhouette...", value=scanned
                )
                note_dict["Silhouette"] = silhouette(korean)

            if "Sound" in note_dict and cleanup(note_dict["Sound"]) == "":
                mw.progress.update(
                    label=f"[{korean}] Looking up sound...", value=scanned
                )
                note_dict["Sound"] = tts(korean)

            write_back(
                note, note_dict, ["Korean", "English", "Hanja", "Silhouette", "Sound"]
            )

        print(note_dict)

    mw.progress.finish()
Beispiel #12
0
def bulk_fill_classifiers():
    prompt = PROMPT_TEMPLATE.format(field_names='<i>classifier</i>',
                                    extra_info='')

    field_groups = ['classifier']

    if not askUser(prompt):
        return

    n_targets = 0
    d_success = 0
    d_failed = 0

    note_ids = Finder(mw.col).findNotes('deck:current')
    mw.progress.start(immediate=True, min=0, max=len(note_ids))

    for i, nid in enumerate(note_ids):
        note = mw.col.getNote(nid)
        copy = dict(note)
        hanzi = get_hanzi(copy)

        if has_any_field(copy, field_groups) and hanzi:
            n_targets += 1

            if all_fields_empty(copy, field_groups):
                if fill_classifier(hanzi, copy):
                    d_success += 1
                else:
                    d_failed += 1

            msg = PROGRESS_TEMPLATE % {
                'hanzi': hanzi,
                'has_fields': n_targets,
                'filled': d_success,
                'failed': d_failed,
            }
            mw.progress.update(label=msg, value=i)

            save_note(note, copy)

    mw.progress.finish()
    showInfo(END_TEMPLATE % {
        'has_fields': n_targets,
        'filled': d_success,
        'failed': d_failed
    })
Beispiel #13
0
    def get_resource(username):
        logging.debug("Getting resource.")
        collection_path = os.path.join(config["data_root"], username,
                                       "collection.anki2")

        col = collection_manager.get_collection(collection_path, None)
        real_col = col.wrapper._get_collection()

        data_by_deck = {}
        finder = Finder(real_col)
        for deck in real_col.decks.all():
            data_by_deck[deck["name"]] = group_cards_for_deck(finder, deck)
        data_for_all = group_cards_for_deck(finder)
        finder = None
        real_col.close()

        data = {"all": data_for_all, "by_deck": data_by_deck}
        return data
Beispiel #14
0
def bulk_fill_hanzi():
    prompt = PROMPT_TEMPLATE.format(field_names='<i>hanzi</i>', extra_info='')
    field_groups = ['traditional', 'simplified']

    if not askUser(prompt):
        return

    d_has_fields = 0
    d_success = 0

    note_ids = Finder(mw.col).findNotes('deck:current')
    mw.progress.start(immediate=True, min=0, max=len(note_ids))

    for i, nid in enumerate(note_ids):
        note = mw.col.getNote(nid)
        copy = dict(note)

        if has_any_field(copy, field_groups) and has_field(
            config['fields']['hanzi'], copy
        ):
            d_has_fields += 1

            msg = '''
            <b>Processing:</b> %(hanzi)s<br>
            <b>Updated:</b> %(filled)d''' % {
                'hanzi': get_hanzi(copy),
                'filled': d_success,
            }
            mw.progress.update(label=msg, value=i)

            hanzi = get_first(config['fields']['hanzi'], copy)
            fill_simp(hanzi, copy)
            fill_trad(hanzi, copy)
            fill_color(hanzi, copy)
            d_success = save_note(note, copy)

    msg = '''
    <b>Update complete!</b> %(hanzi)s<br>
    <b>Updated:</b> %(filled)d notes''' % {
        'hanzi': get_hanzi(copy),
        'filled': d_success,
    }
    mw.progress.finish()
    showInfo(msg)
Beispiel #15
0
def bulk_fill_defs():
    prompt = PROMPT_TEMPLATE.format(
        field_names='<i>definition</i> and <i>alternative</i>',
        extra_info='',
    )

    progress_msg_template = '''
            <b>Processing:</b> %(hanzi)s<br>
            <b>Chinese notes:</b> %(has_fields)d<br>
            <b>Translated:</b> %(filled)d<br>
            <b>Failed:</b> %(failed)d'''

    field_groups = ['meaning', 'english', 'german', 'french']

    if not askUser(prompt):
        return

    n_targets = 0
    d_success = 0
    d_failed = 0
    failed_hanzi = []

    note_ids = Finder(mw.col).findNotes('deck:current')
    mw.progress.start(immediate=True, min=0, max=len(note_ids))

    for i, nid in enumerate(note_ids):
        note = mw.col.getNote(nid)
        copy = dict(note)
        hanzi = get_hanzi(copy)

        if has_any_field(copy, field_groups) and hanzi:
            n_targets += 1

            if all_fields_empty(copy, field_groups):
                result = fill_all_defs(hanzi, copy)
                if result:
                    d_success += 1
                else:
                    d_failed += 1
                    if d_failed < 20:
                        failed_hanzi += [hanzi]

            msg = progress_msg_template % {
                'hanzi': hanzi,
                'has_fields': n_targets,
                'filled': d_success,
                'failed': d_failed,
            }
            mw.progress.update(label=msg, value=i)

            save_note(note, copy)

    msg = '''
    <b>Translation complete</b><br>
    <b>Chinese notes:</b> %(has_fields)d<br>
    <b>Translated:</b> %(filled)d<br>
    <b>Failed:</b> %(failed)d''' % {
        'has_fields': n_targets,
        'filled': d_success,
        'failed': d_failed,
    }
    if d_failed > 0:
        msg += (
            '<div>Translation failures may come either from connection issues '
            "(if you're using an online translation service), or because some "
            'words are not it the dictionary (for local dictionaries).</div>'
            '<div>The following notes failed: ' + ', '.join(failed_hanzi) +
            '</div>')
    mw.progress.finish()
    showInfo(msg)
Beispiel #16
0
def fill_translation():
    if not (askUser(
            "<div>This will update the <i>Meaning</i> field in the current "
            "deck, if they exist and are empty.</div>"
            "<b>Learning tip:</b><div>Automatic dictionary lookup tends to "
            "produce very long text, often with multiple translations.</div>"
            "\n\n"
            "<div>For more effective memorization, it's highly "
            "recommended to trim them down to just a few words, only one "
            "meaning, and possibly add some mnemonics.</div>\n\n"
            "<div>Dictionary lookup is simply meant as a way to save you time "
            "when typing; please consider editing each definition by hand when"
            " you're done.</div>\n\n"
            "<div>Please back-up your Anki deck first!</div>\n\n"
            "<div><b>Continue?</b></div>")):
        return False

    query_str = "deck:current"
    d_scanned = 0
    d_has_fields = 0
    d_success = 0
    d_failed = 0
    failed_hangul = []
    notes = Finder(mw.col).findNotes(query_str)
    mw.progress.start(immediate=True, min=0, max=len(notes))
    for noteId in notes:
        d_scanned += 1
        note = mw.col.getNote(noteId)
        note_dict = dict(note)  # edit_function routines require a dict

        if has_field(config.options["fields"]["meaning"],
                     note_dict) and has_field(
                         config.options["fields"]["hangul"], note_dict):
            d_has_fields += 1

            msg_string = ("<b>Processing:</b> {hangul:s}<br>"
                          "<b>Korean notes:</b> {has_fields:d}<br>"
                          "<b>Translated:</b> {filled:d}<br>"
                          "<b>Failed:</b> {failed:d}").format(
                              hangul=cleanup(
                                  no_html(
                                      get_any(
                                          config.options["fields"]["hangul"],
                                          note_dict))),
                              has_fields=d_has_fields,
                              filled=d_success,
                              failed=d_failed,
                          )
            mw.progress.update(label=msg_string, value=d_scanned)

            hangul = get_any(config.options["fields"]["hangul"], note_dict)
            empty = len(get_any(config.options["fields"]["meaning"],
                                note_dict))
            if not (empty):
                result = update_Meaning_fields(hangul, note_dict)

                if result == 0:
                    d_failed += 1
                    if d_failed < 20:
                        failed_hangul += [
                            cleanup(
                                no_html(
                                    get_any(config.options["fields"]["hangul"],
                                            note_dict)))
                        ]
                else:
                    d_success += 1

            def write_back(fields):
                for f in fields:
                    if f in note_dict and note_dict[f] != note[f]:
                        note[f] = note_dict[f]
                return

            # write back to note from dict and flush
            write_back(config.options["fields"]["meaning"])
            note.flush()

    msg_string = ("<b>Translation complete</b> <br>"
                  "<b>Korean notes:</b> {has_fields:d}<br>"
                  "<b>Translated:</b> {filled:d}<br>"
                  "<b>Failed:</b> {failed:d}").format(has_fields=d_has_fields,
                                                      filled=d_success,
                                                      failed=d_failed)
    if d_failed > 0:
        msg_string += ("\n\n<div>Translation failures may come either from "
                       "connection issues (if you're using an on-line "
                       "translation service), or because some words are not in"
                       " the dictionary (for local dictionaries).</div>")
        msg_string += "<div>The following notes failed: {}</div>".format(
            ", ".join(failed_hangul))
    mw.progress.finish()

    showInfo(msg_string)
def _build_index(index_up_to_date):
    """
    Builds the index. Result is stored in global var searchIndex.
    The index.type is either "Whoosh"/"SQLite FTS3"/"SQLite FTS4"/"SQLite FTS5"
    """
    start = time.time()
    config = mw.addonManager.getConfig(__name__)
    try:
        useFTS = config['useFTS']
    except KeyError:
        useFTS = False
    searchIndex = None
    corpus = get_corpus()
    #fts4 based sqlite reversed index
    if config["disableNonNativeSearching"] or useFTS:
        searchIndex = FTSIndex(corpus, config["disableNonNativeSearching"],
                               index_up_to_date)
        end = time.time()
        initializationTime = round(end - start)
    #whoosh index
    else:
        searchIndex = WhooshSearchIndex(corpus,
                                        config["disableNonNativeSearching"],
                                        index_up_to_date)
        end = time.time()
        initializationTime = round(end - start)

    searchIndex.finder = Finder(mw.col)
    searchIndex.output.stopwords = searchIndex.stopWords
    searchIndex.output.remove_divs = config["removeDivsFromOutput"]
    searchIndex.output.gridView = config["gridView"]
    searchIndex.output.scale = config["noteScale"]
    searchIndex.output.fields_to_hide_in_results = config[
        "fieldsToHideInResults"]
    searchIndex.selectedDecks = ["-1"]
    searchIndex.lastSearch = None
    searchIndex.lastResDict = None
    searchIndex.tagSearch = True
    searchIndex.tagSelect = False
    searchIndex.topToggled = True
    searchIndex.output.edited = {}
    searchIndex.initializationTime = initializationTime
    searchIndex.synonyms = loadSynonyms()
    searchIndex.tagSearch = config["searchOnTagEntry"]
    searchIndex.logging = config["logging"]
    searchIndex.searchbar_mode = "Add-on"
    try:
        limit = config['numberOfResults']
        if limit <= 0:
            limit = 1
        elif limit > 5000:
            limit = 5000
    except KeyError:
        limit = 500
    searchIndex.limit = limit

    try:
        showRetentionScores = config["showRetentionScores"]
    except KeyError:
        showRetentionScores = True
    searchIndex.output.showRetentionScores = showRetentionScores
    try:
        hideSidebar = config["hideSidebar"]
    except KeyError:
        hideSidebar = False
    searchIndex.output.hideSidebar = hideSidebar

    if searchIndex.logging:
        log("\n--------------------\nInitialized searchIndex:")
        log("""Type: %s\n# Stopwords: %s \n# Synonyms: %s \nLimit: %s \n""" %
            (searchIndex.type, len(
                searchIndex.stopWords), len(searchIndex.synonyms), limit))

    editor = aqt.mw.app.activeWindow().editor if hasattr(
        aqt.mw.app.activeWindow(), "editor") else None
    if editor is not None and editor.addMode:
        searchIndex.output.editor = editor
    set_index(searchIndex)
    editor = editor if editor is not None else get_edit()
    showSearchResultArea(editor, initializationTime=initializationTime)
    printStartingInfo(editor)
Beispiel #18
0
def getNidsFromRelations(relations):
    finder = Finder(mw.col)
    nids = set(finder.findNotes(queryRelated(relations)))
    debug(f"from relations {relations} we get nids {nids}")
    return nids
Beispiel #19
0
def bulk_fill_sound():
    prompt = '''
    <div>This will update the <i>Sound</i> fields in the current
    deck, if they exist and are empty, using the selected speech
    engine.</div>
    <div>Please back-up your Anki deck first!</div>
    <div>(Please also note that there will be a 5 second delay
    between each sound request, to reduce burden on the server.
    This may therefore take a while.)</div>
    <div><b>Continue?</b></div>
    '''

    if not askUser(prompt):
        return

    query_str = 'deck:current'
    d_scanned = 0
    d_has_fields = 0
    d_already_had_sound = 0
    d_success = 0
    d_failed = 0

    note_ids = Finder(mw.col).findNotes(query_str)
    mw.progress.start(immediate=True, min=0, max=len(note_ids))
    for nid in note_ids:
        d_scanned += 1
        orig = mw.col.getNote(nid)
        copy = dict(orig)

        _hf_s = has_field(config['fields']['sound'], copy)
        _hf_sm = has_field(config['fields']['mandarinSound'], copy)
        _hf_sc = has_field(config['fields']['cantoneseSound'], copy)

        if (_hf_s or _hf_sm or _hf_sc) and has_field(config['fields']['hanzi'],
                                                     copy):
            d_has_fields += 1

            hanzi = get_first(config['fields']['hanzi'], copy)

            if (get_first(config['fields']['sound'], copy)
                    or get_first(config['fields']['mandarinSound'], copy)
                    or get_first(config['fields']['cantoneseSound'], copy)):
                d_already_had_sound += 1
            else:
                msg = '''
                <b>Processing:</b> %(hanzi)s<br>
                <b>Updated:</b> %(d_success)d notes<br>
                <b>Failed:</b> %(d_failed)d notes''' % {
                    'hanzi': sanitize_hanzi(copy),
                    'd_success': d_success,
                    'd_failed': d_failed,
                }
                mw.progress.update(label=msg, value=d_scanned)
                s, f = fill_sound(hanzi, copy)
                d_success += s
                d_failed += f
                save_note(orig, copy)
                sleep(5)

    mw.progress.finish()
    msg = '''
%(d_success)d new pronunciations downloaded

%(d_failed)d downloads failed

%(have)d/%(d_has_fields)d notes now have pronunciation''' % {
        'd_success': d_success,
        'd_failed': d_failed,
        'have': d_already_had_sound + d_success,
        'd_has_fields': d_has_fields,
    }
    if d_failed > 0:
        msg += ('TTS is taken from an online source. '
                'It may not always be fully responsive. '
                'Please check your network connexion, or retry later.')
    showInfo(msg)
def _build_index(index_up_to_date):
    """
    Builds the index. Result is stored in global var index.
    The index.type is either "Whoosh"/"SQLite FTS3"/"SQLite FTS4"/"SQLite FTS5"
    """
    start = time.time()
    config = mw.addonManager.getConfig(__name__)

    corpus = get_corpus()

    index = FTSIndex(corpus, index_up_to_date)
    end = time.time()
    initializationTime = round(end - start)

    index.finder = Finder(mw.col)
    index.ui.stopwords = index.stopWords
    index.ui.remove_divs = config["removeDivsFromOutput"]
    index.ui.gridView = config["gridView"]
    index.ui.scale = config["noteScale"]
    index.ui.fields_to_hide_in_results = config["fieldsToHideInResults"]
    index.selectedDecks = ["-1"]
    index.lastSearch = None
    index.lastResDict = None
    index.topToggled = True
    index.ui.edited = {}
    index.initializationTime = initializationTime
    index.synonyms = loadSynonyms()
    index.logging = config["logging"]
    index.searchbar_mode = "Add-on"
    try:
        limit = config['numberOfResults']
        if limit <= 0:
            limit = 1
        elif limit > 5000:
            limit = 5000
    except KeyError:
        limit = 500
    index.limit = limit

    try:
        showRetentionScores = config["showRetentionScores"]
    except KeyError:
        showRetentionScores = True
    index.ui.showRetentionScores = showRetentionScores
    try:
        hideSidebar = config["hideSidebar"]
    except KeyError:
        hideSidebar = False
    index.ui.hideSidebar = hideSidebar

    if index.logging:
        log("\n--------------------\nInitialized index:")
        log("""Type: %s\n# Stopwords: %s \n# Synonyms: %s \nLimit: %s \n""" %
            (index.type, len(index.stopWords), len(index.synonyms), limit))

    editor = aqt.mw.app.activeWindow().editor if hasattr(
        aqt.mw.app.activeWindow(), "editor") else None
    if editor is not None and editor.addMode:
        index.ui.set_editor(editor)
    set_index(index)
    editor = editor if editor is not None else get_edit()
    setup_ui_after_index_built(editor, index)
    # showSearchResultArea(editor, initializationTime=initializationTime)
    fillDeckSelect(editor)
    printStartingInfo(editor)
Beispiel #21
0
def getReviewCards():
    finder = Finder(mw.col)
    cids = finder.findCards("is:review")
    return cids
Beispiel #22
0
def fill_sounds():
    prompt = """<div>This will update the <i>Sound</i> fields in the current
                deck, if they exist and are empty, using the selected speech
                engine.</div>
                <div>Please back-up your Anki deck first!</div>
                <div>(Please also note that there will be a 5 second delay
                between each sound request, to reduce burden on the server.
                This may therefore take a while.)</div>
                <div><b>Continue?</b></div>"""

    if not askUser(prompt):
        return False

    query_str = "deck:current"
    d_scanned = 0
    d_has_fields = 0
    d_already_had_sound = 0
    d_success = 0
    d_failed = 0

    notes = Finder(mw.col).findNotes(query_str)
    mw.progress.start(immediate=True, min=0, max=len(notes))
    for noteId in notes:
        d_scanned += 1
        note = mw.col.getNote(noteId)
        note_dict = dict(note)  # edit_function routines require a dict

        if has_field(config.options["fields"]["sound"],
                     note_dict) and has_field(
                         config.options["fields"]["hangul"], note_dict):
            d_has_fields += 1

            hangul = get_any(config.options["fields"]["hangul"], note_dict)

            if get_any(config.options["fields"]["sound"], note_dict):
                d_already_had_sound += 1
            else:
                msg_string = (
                    "<b>Processing:</b> {hangul:s}<br>"
                    "<b>Updated:</b> {d_success:d} notes<br>"
                    "<b>Failed:</b> {d_failed:d} notes").format(
                        hangul=cleanup(
                            no_html(
                                get_any(config.options["fields"]["hangul"],
                                        note_dict))),
                        d_success=d_success,
                        d_failed=d_failed,
                    )
                mw.progress.update(label=msg_string, value=d_scanned)
                s, f = update_Sound_fields(hangul, note_dict)
                d_success += s
                d_failed += f

                # write back to note from dict and flush
                for f in config.options["fields"]["sound"]:
                    if f in note_dict and note_dict[f] != note[f]:
                        note[f] = note_dict[f]
                note.flush()
                sleep(5)

    mw.progress.finish()
    msg_string = """
{d_success:d} new pronunciations downloaded

{d_failed:d} downloads failed

{have:d}/{d_has_fields:d} notes now have pronunciation
""".format(
        d_success=d_success,
        d_failed=d_failed,
        have=d_already_had_sound + d_success,
        d_has_fields=d_has_fields,
    )
    if d_failed > 0:
        msg_string = msg_string + ("\n\nTTS is taken from an on-line source. "
                                   "It may not always be fully responsive. "
                                   "Please check your network connexion, "
                                   "or retry later.\n\nIf failures persist, "
                                   "please set Korean Support to debug mode "
                                   "and submit a bug report from the help "
                                   "menu.")
    showInfo(msg_string)
Beispiel #23
0
def fill_translation(collection, view_key):
    if view_key == "deckBrowser":
        return showInfo(u"First select one of your decks")

    if not (askUser(
            "<div>This will update the <i>Meaning</i>, <i>Mean Word</i>, and <i>Also Written</i> fields in the current deck, if they exist and are empty.</div><b>Learning tip:</b><div>Automatic dictionary lookup tends to produce very long text, often with multiple translations.</div>\n\n<div>For more effective memorization, it's highly recommended to trim them down to just a few words, only one meaning, and possibly add some mnemonics.</div>\n\n<div>Dictionary lookup is simply meant as a way to save you time when typing; please consider editing each definition by hand when you're done.</div>\n\n<div>Please back-up your Anki deck first!</div>\n\n<div><b>Continue?</b></div>"
    )):
        return False

    query_str = "deck:current"
    d_scanned = 0
    d_has_fields = 0
    d_success = 0
    d_failed = 0
    failed_hanzi = []
    notes = Finder(collection).findNotes(query_str)
    mw.progress.start(immediate=True, min=0, max=len(notes))
    for noteId in notes:
        d_scanned += 1
        note = collection.getNote(noteId)
        note_dict = dict(note)  # edit_function routines require a dict

        _hf_m = has_field(Meaning_fields, note_dict)
        _hf_e = has_field(English_fields, note_dict)
        _hf_g = has_field(German_fields, note_dict)
        _hf_f = has_field(French_fields, note_dict)

        if (_hf_m or _hf_e or _hf_g or _hf_f) and has_field(
                Hanzi_fields, note_dict):
            d_has_fields += 1

            msg_string = "<b>Processing:</b> %(hanzi)s<br><b>Chinese notes:</b> %(has_fields)d<br><b>Translated:</b> %(filled)d<br><b>Failed:</b> %(failed)d" % {
                "hanzi": cleanup(no_html(get_any(Hanzi_fields, note_dict))),
                "has_fields": d_has_fields,
                "filled": d_success,
                "failed": d_failed
            }
            mw.progress.update(label=msg_string, value=d_scanned)

            hanzi = get_any(Hanzi_fields, note_dict)
            empty = len(get_any(Meaning_fields, note_dict))
            empty += len(get_any(English_fields, note_dict))
            empty += len(get_any(German_fields, note_dict))
            empty += len(get_any(French_fields, note_dict))
            if not (empty):
                result = 0
                if _hf_m:
                    result += update_Meaning_fields(hanzi, note_dict)
                if _hf_e:
                    result += update_English_fields(hanzi, note_dict)
                if _hf_g:
                    result += update_German_fields(hanzi, note_dict)
                if _hf_f:
                    result += update_French_fields(hanzi, note_dict)

                if result == 0:
                    d_failed += 1
                    if d_failed < 20:
                        failed_hanzi += [
                            cleanup(no_html(get_any(Hanzi_fields, note_dict)))
                        ]
                else:
                    d_success += 1

            def write_back(fields):
                for f in fields:
                    if note_dict.has_key(f) and note_dict[
                            f] is not None and note_dict[f] <> note[f]:
                        note[f] = note_dict[f]
                return

            # write back to note from dict and flush
            write_back(Meaning_fields)
            write_back(English_fields)
            write_back(German_fields)
            write_back(French_fields)
            write_back(Mean_Word_fields)
            write_back(Alternate_fields)
            note.flush()

    msg_string = "<b>Translation complete</b> <br><b>Chinese notes:</b> %(has_fields)d<br><b>Translated:</b> %(filled)d<br><b>Failed:</b> %(failed)d" % {
        "has_fields": d_has_fields,
        "filled": d_success,
        "failed": d_failed
    }
    if d_failed > 0:
        msg_string += "\n\n<div>Translation failures may come either from connection issues (if you're using an on-line translation service), or because some words are not it the dictionary (for local dictionaries).</div>"
        msg_string += "<div>The following notes failed: " + ", ".join(
            failed_hanzi) + "</div>"
    mw.progress.finish()

    showInfo(msg_string)
Beispiel #24
0
def fill_sounds(collection, view_key):
    if view_key == "deckBrowser":
        return showInfo(u"Please first select one of your decks.")
    if not (askUser(
            "<div>This will update the <i>Sound</i> fields in the current deck, if they exist and are empty, using the selected speech engine.</div>\n\n<div>Please back-up your Anki deck first!</div>\n\n<div><b>Continue?</b></div>"
    )):
        return False

    query_str = "deck:current"
    d_scanned = 0
    d_has_fields = 0
    d_already_had_sound = 0
    d_success = 0
    d_failed = 0

    notes = Finder(collection).findNotes(query_str)
    mw.progress.start(immediate=True, min=0, max=len(notes))
    for noteId in notes:
        d_scanned += 1
        note = collection.getNote(noteId)
        note_dict = dict(note)  # edit_function routines require a dict

        _hf_s = has_field(Sound_fields, note_dict)
        _hf_sm = has_field(Sound_Mandarin_fields, note_dict)
        _hf_sc = has_field(Sound_Cantonese_fields, note_dict)

        if (_hf_s or _hf_sm or _hf_sc) and has_field(Hanzi_fields, note_dict):
            d_has_fields += 1

            hanzi = get_any(Hanzi_fields, note_dict)

            if get_any(Sound_fields, note_dict) or get_any(
                    Sound_Mandarin_fields, note_dict) or get_any(
                        Sound_Cantonese_fields, note_dict):
                d_already_had_sound += 1
            else:
                msg_string = "<b>Processing:</b> %(hanzi)s<br><b>Updated:</b> %(d_success)d notes<br><b>Failed:</b> %(d_failed)d notes" % {
                    "hanzi": cleanup(no_html(get_any(Hanzi_fields,
                                                     note_dict))),
                    "d_success": d_success,
                    "d_failed": d_failed
                }
                mw.progress.update(label=msg_string, value=d_scanned)
                s, f = update_all_Sound_fields(hanzi, note_dict)
                d_success += s
                d_failed += f

                # write back to note from dict and flush
                for f in Sound_fields + Sound_Mandarin_fields + Sound_Cantonese_fields:
                    if note_dict.has_key(f) and note_dict[
                            f] is not None and note_dict[f] <> note[f]:
                        note[f] = note_dict[f]
                note.flush()
    mw.progress.finish()
    msg_string = '''
%(d_success)d new pronunciations downloaded

%(d_failed)d downloads failed

%(have)d/%(d_has_fields)d notes now have pronunciation
''' % {
        "d_success": d_success,
        "d_failed": d_failed,
        "have": d_already_had_sound + d_success,
        "d_has_fields": d_has_fields
    }
    if d_failed > 0:
        msg_string = msg_string + "\n\nTTS is taken from an on-line source. It may not always be fully responsive. Please check your network connexion, or retry later."
    showInfo(msg_string)
Beispiel #25
0
def test_parse():
    f = Finder(None)
    assert f._tokenize("hello world") == ["hello", "world"]
    assert f._tokenize("hello  world") == ["hello", "world"]
    assert f._tokenize("one -two") == ["one", "-", "two"]
    assert f._tokenize("one --two") == ["one", "-", "two"]
    assert f._tokenize("one - two") == ["one", "-", "two"]
    assert f._tokenize("one or -two") == ["one", "or", "-", "two"]
    assert f._tokenize("'hello \"world\"'") == ["hello \"world\""]
    assert f._tokenize('"hello world"') == ["hello world"]
    assert f._tokenize("one (two or ( three or four))") == [
        "one", "(", "two", "or", "(", "three", "or", "four",
        ")", ")"]
    assert f._tokenize("embedded'string") == ["embedded'string"]
    assert f._tokenize("deck:'two words'") == ["deck:two words"]
Beispiel #26
0
def test_parse():
    f = Finder(None)
    assert f._tokenize("hello world") == ["hello", "world"]
    assert f._tokenize("hello  world") == ["hello", "world"]
    assert f._tokenize("one -two") == ["one", "not", "two"]
    assert f._tokenize("one --two") == ["one", "not", "two"]
    assert f._tokenize("one or -two") == ["one", "or", "not", "two"]
    assert f._tokenize("'hello \"world\"'") == ["hello \"world\""]
    assert f._tokenize('"hello world"') == ["hello world"]
    assert f._tokenize("one (two or ( three or four))") == [
        "one", "(", "two", "or", "(", "three", "or", "four", ")", ")"
    ]
    assert f._tokenize("embedded'string") == ["embedded'string"]
    assert f._tokenize("deck:'two words'") == ["deck:two words"]
Beispiel #27
0
def bulk_fill_pinyin():
    prompt = '''
    <div>This will update the <i>Pinyin</i> (or <i>Transcription</i>),
    <i>Color</i> and <i>Ruby</i> fields in the current deck, if they exist.</div>
    <div><i>Pinyin</i> and <i>Transcription</i> will be filled if empty.
    Otherwise, their colorization and accentuation will be refreshed as needed.</div>
    <div>Please back-up your Anki deck first!</div>
    <div><b>Continue?</b></div>
    '''

    if not askUser(prompt):
        return

    query_str = 'deck:current'
    d_scanned = 0
    d_has_fields = 0
    d_added_pinyin = 0
    d_updated = 0

    notes = Finder(mw.col).findNotes(query_str)
    mw.progress.start(immediate=True, min=0, max=len(notes))
    for noteId in notes:
        d_scanned += 1
        note = mw.col.getNote(noteId)
        note_dict = dict(note)

        _hf_t = has_field(config['fields']['transcription'], note_dict)
        _hf_py = has_field(config['fields']['pinyin'], note_dict)
        _hf_pytw = has_field(config['fields']['pinyinTaiwan'], note_dict)
        _hf_cant = has_field(config['fields']['cantonese'], note_dict)
        _hf_bpmf = has_field(config['fields']['bopomofo'], note_dict)

        if (_hf_t or _hf_py or _hf_pytw or _hf_cant or _hf_bpmf) and has_field(
                config['fields']['hanzi'], note_dict):
            d_has_fields += 1

            msg = '''
            <b>Processing:</b> %(hanzi)s<br>
            <b>Filled pinyin:</b> %(pinyin)d notes<br>
            <b>Updated: </b>%(updated)d fields''' % {
                'hanzi': sanitize_hanzi(note_dict),
                'pinyin': d_added_pinyin,
                'updated': d_updated,
            }
            mw.progress.update(label=msg, value=d_scanned)

            hanzi = get_first(config['fields']['hanzi'], note_dict)
            results = 0

            if _hf_t:
                results += fill_transcription(hanzi, note_dict)
            if _hf_py:
                results += bulk_fill_pinyin(hanzi, note_dict)
            if _hf_pytw:
                results += fill_taiwan_pinyin(hanzi, note_dict)
            if _hf_cant:
                results += fill_cantonese(hanzi, note_dict)
            if _hf_bpmf:
                results += fill_bopomofo(hanzi, note_dict)

            if results != 0:
                d_added_pinyin += 1

            fill_color(hanzi, note_dict)
            fill_all_rubies(hanzi, note_dict)

            def write_back(fields):
                num_updated = 0
                for f in fields:
                    if f in note_dict and note_dict[f] != note[f]:
                        note[f] = note_dict[f]
                        num_updated += 1
                return num_updated

            d_updated += write_back(config['fields']['transcription'])
            d_updated += write_back(config['fields']['pinyin'])
            d_updated += write_back(config['fields']['pinyinTaiwan'])
            d_updated += write_back(config['fields']['cantonese'])
            d_updated += write_back(config['fields']['bopomofo'])
            d_updated += write_back(config['fields']['color'])
            d_updated += write_back(config['fields']['colorPinyin'])
            d_updated += write_back(config['fields']['colorPinyinTaiwan'])
            d_updated += write_back(config['fields']['colorCantonese'])
            d_updated += write_back(config['fields']['colorBopomofo'])
            d_updated += write_back(config['fields']['ruby'])
            d_updated += write_back(config['fields']['rubyPinyin'])
            d_updated += write_back(config['fields']['rubyPinyinTaiwan'])
            d_updated += write_back(config['fields']['rubyCantonese'])
            d_updated += write_back(config['fields']['rubyBopomofo'])
            note.flush()

    mw.progress.finish()
    msg = '''
    <b>Processing:</b> %(hanzi)s<br>
    <b>Filled pinyin:</b> %(pinyin)d notes<br>
    <b>Updated: </b>%(updated)d fields''' % {
        'hanzi': sanitize_hanzi(note_dict),
        'pinyin': d_added_pinyin,
        'updated': d_updated,
    }
    showInfo(msg)
Beispiel #28
0
def bulk_fill_usage():
    prompt = PROMPT_TEMPLATE.format(field_names='<i>usage</i>', extra_info='')

    progress_msg_template = '''
            <b>Processing:</b> %(hanzi)s<br>
            <b>Chinese notes:</b> %(has_fields)d<br>
            <b>Cards with Sentences added:</b> %(filled)d<br>
            <b>Cards with no Sentences added:</b> %(not_filled)d<br>
            <b>Failed:</b> %(failed)d'''

    fields = config.get_fields(['usage'])

    if not askUser(prompt):
        return

    n_processed = 0
    n_updated = 0
    n_failed = 0
    n_notfilled = 0
    failed_hanzi = []

    note_ids = Finder(mw.col).findNotes('deck:current')
    mw.progress.start(immediate=True, min=0, max=len(note_ids))

    for i, note_id in enumerate(note_ids):
        note = mw.col.getNote(note_id)
        copy = dict(note)
        hanzi = get_hanzi(copy)

        if has_any_field(copy, fields) and hanzi:
            n_processed += 1

            try:
                if all_fields_empty(copy, fields):
                    result = fill_usage(hanzi, copy)
                    if result:
                        n_updated += 1
                    else:
                        n_notfilled += 1
            except:
                n_failed += 1
                failed_hanzi.append(hanzi)

            msg = progress_msg_template % {
                'hanzi': hanzi,
                'has_fields': n_processed,
                'filled': n_updated,
                'not_filled': n_notfilled,
                'failed': n_failed,
            }
            mw.progress.update(label=msg, value=i)

            save_note(note, copy)

    msg = '''
    <b>Usage Additions Complete</b><br>
    <b>Chinese Notes:</b> %(has_fields)d<br>
    <b>Usage Fields Filled:</b> %(filled)d<br>
    <b>Usage Fields Not Filled:</b> %(not_filled)d<br>
    <b>Failed:</b> %(failed)d''' % {
        'has_fields': n_processed,
        'filled': n_updated,
        'not_filled': n_notfilled,
        'failed': n_failed,
    }
    if n_failed > 0:
        failed_msg = (
            'Usages may not be available in the database\'s data set. '
            'Custom data can be added to the english_usage column in the'
            'chinese.db database.\n'
            'The following notes failed: \n\n' + ', '.join(failed_hanzi))
        showText(failed_msg, copyBtn=True)
    mw.progress.finish()
    showInfo(msg)
Beispiel #29
0
def fill_pinyin(collection, view_key):
    if view_key == "deckBrowser":
        return showInfo(u"Please first select one of your decks.")
    if not (askUser(
            "<div>This will update the <i>Pinyin</i> (or <i>Transcription</i>), <i>Color</i> and <i>Ruby</i> fields in the current deck, if they exist.</div>\n\n<div><i>Pinyin</i> and <i>Transcription</i> will be filled if empty. Otherwise, their colorization and accentuation will be refreshed as needed.</div>\n\n<div>Please back-up your Anki deck first!</div>\n\n<div><b>Continue?</b></div>"
    )):
        return False

    query_str = "deck:current"
    d_scanned = 0
    d_has_fields = 0
    d_failed = 0
    d_added_pinyin = 0
    d_updated = 0

    notes = Finder(collection).findNotes(query_str)
    mw.progress.start(immediate=True, min=0, max=len(notes))
    for noteId in notes:
        d_scanned += 1
        note = collection.getNote(noteId)
        note_dict = dict(note)  # edit_function routines require a dict

        _hf_t = has_field(Transcription_fields, note_dict)
        _hf_py = has_field(Pinyin_fields, note_dict)
        _hf_pytw = has_field(PinyinTW_fields, note_dict)
        _hf_cant = has_field(Cantonese_fields, note_dict)
        _hf_bpmf = has_field(Bopomofo_fields, note_dict)

        if (_hf_t or _hf_py or _hf_pytw or _hf_cant or _hf_bpmf) and has_field(
                Hanzi_fields, note_dict):
            d_has_fields += 1

            msg_string = "<b>Processing:</b> %(hanzi)s<br><b>Filled pinyin:</b> %(pinyin)d notes<br><b>Updated: </b>%(updated)d fields" % {
                "hanzi": cleanup(no_html(get_any(Hanzi_fields, note_dict))),
                "pinyin": d_added_pinyin,
                "updated": d_updated
            }
            mw.progress.update(label=msg_string, value=d_scanned)

            hanzi = get_any(Hanzi_fields, note_dict)
            results = 0

            if _hf_t:
                results += update_Transcription_fields(hanzi, note_dict)
            if _hf_py:
                results += update_Pinyin_fields(hanzi, note_dict)
            if _hf_pytw:
                results += update_PinyinTW_fields(hanzi, note_dict)
            if _hf_cant:
                results += update_Cantonese_fields(hanzi, note_dict)
            if _hf_bpmf:
                results += update_Bopomofo_fields(hanzi, note_dict)

            if results != 0:
                d_added_pinyin += 1

            #Always overwrite, as in the default edit_behavior
            update_all_Color_fields(hanzi, note_dict)

            #Update ruby field
            update_all_Ruby_fields(hanzi, note_dict)

            def write_back(fields):
                num_updated = 0
                for f in fields:
                    if note_dict.has_key(f) and note_dict[
                            f] is not None and note_dict[f] <> note[f]:
                        note[f] = note_dict[f]
                        num_updated += 1
                return num_updated

            # write back to note from dict and flush
            d_updated += write_back(Transcription_fields)
            d_updated += write_back(Pinyin_fields)
            d_updated += write_back(PinyinTW_fields)
            d_updated += write_back(Cantonese_fields)
            d_updated += write_back(Bopomofo_fields)
            d_updated += write_back(Color_fields)
            d_updated += write_back(ColorPY_fields)
            d_updated += write_back(ColorPYTW_fields)
            d_updated += write_back(ColorCANT_fields)
            d_updated += write_back(ColorBPMF_fields)
            d_updated += write_back(Ruby_fields)
            d_updated += write_back(RubyPY_fields)
            d_updated += write_back(RubyPYTW_fields)
            d_updated += write_back(RubyCANT_fields)
            d_updated += write_back(RubyBPMF_fields)
            note.flush()

    mw.progress.finish()
    msg_string = "<b>Processing:</b> %(hanzi)s<br><b>Filled pinyin:</b> %(pinyin)d notes<br><b>Updated: </b>%(updated)d fields" % {
        "hanzi": cleanup(no_html(get_any(Hanzi_fields, note_dict))),
        "pinyin": d_added_pinyin,
        "updated": d_updated
    }
    showInfo(msg_string)
Beispiel #30
0
def bulk_fill_sound():
    prompt = PROMPT_TEMPLATE.format(
        field_names='<i>Sound</i>',
        extra_info=(
            '<div>There will be a 5 second delay between each sound request,'
            ' so this may take a while.</div>'),
    )

    if not askUser(prompt):
        return

    d_has_fields = 0
    d_already_had_sound = 0
    d_success = 0
    d_failed = 0

    note_ids = Finder(mw.col).findNotes('deck:current')
    mw.progress.start(immediate=True, min=0, max=len(note_ids))

    for i, nid in enumerate(note_ids):
        orig = mw.col.getNote(nid)
        copy = dict(orig)

        if has_any_field(copy, ['sound', 'mandarinSound',
                                'cantoneseSound']) and has_field(
                                    config['fields']['hanzi'], copy):
            d_has_fields += 1
            hanzi = get_first(config['fields']['hanzi'], copy)

            if all_fields_empty(copy,
                                ['sound', 'mandarinSound', 'cantoneseSound']):
                msg = '''
                <b>Processing:</b> %(hanzi)s<br>
                <b>Updated:</b> %(d_success)d notes<br>
                <b>Failed:</b> %(d_failed)d notes''' % {
                    'hanzi': get_hanzi(copy),
                    'd_success': d_success,
                    'd_failed': d_failed,
                }
                mw.progress.update(label=msg, value=i)
                s, f = fill_sound(hanzi, copy)
                d_success += s
                d_failed += f
                save_note(orig, copy)
                sleep(5)
            else:
                d_already_had_sound += 1

    mw.progress.finish()
    msg = '''
%(d_success)d new pronunciations downloaded

%(d_failed)d downloads failed

%(have)d/%(d_has_fields)d notes now have pronunciation''' % {
        'd_success': d_success,
        'd_failed': d_failed,
        'have': d_already_had_sound + d_success,
        'd_has_fields': d_has_fields,
    }
    if d_failed > 0:
        msg += ('TTS is taken from an online source. '
                'It may not always be fully responsive. '
                'Please check your network connexion, or retry later.')
    showInfo(msg)
Beispiel #31
0
def bulk_fill_defs():
    prompt = '''
    <div>This will update the <i>Meaning</i>, <i>Classifier</i>, and <i>Also
    Written</i> fields in the current deck, if they exist and are empty.</div>
    <div>Please back-up your Anki deck first!</div>
    <div><b>Continue?</b></div>
    '''

    if not askUser(prompt):
        return

    query_str = 'deck:current'
    d_scanned = 0
    d_has_fields = 0
    d_success = 0
    d_failed = 0
    failed_hanzi = []
    notes = Finder(mw.col).findNotes(query_str)
    mw.progress.start(immediate=True, min=0, max=len(notes))
    for noteId in notes:
        d_scanned += 1
        note = mw.col.getNote(noteId)
        note_dict = dict(note)

        _hf_m = has_field(config['fields']['meaning'], note_dict)
        _hf_e = has_field(config['fields']['english'], note_dict)
        _hf_g = has_field(config['fields']['german'], note_dict)
        _hf_f = has_field(config['fields']['french'], note_dict)

        if (_hf_m or _hf_e or _hf_g or _hf_f) and has_field(
                config['fields']['hanzi'], note_dict):
            d_has_fields += 1

            msg = '''
            <b>Processing:</b> %(hanzi)s<br>
            <b>Chinese notes:</b> %(has_fields)d<br>
            <b>Translated:</b> %(filled)d<br>
            <b>Failed:</b> %(failed)d''' % {
                'hanzi': sanitize_hanzi(note_dict),
                'has_fields': d_has_fields,
                'filled': d_success,
                'failed': d_failed,
            }
            mw.progress.update(label=msg, value=d_scanned)

            hanzi = get_first(config['fields']['hanzi'], note_dict)
            empty = len(get_first(config['fields']['meaning'], note_dict))
            empty += len(get_first(config['fields']['english'], note_dict))
            empty += len(get_first(config['fields']['german'], note_dict))
            empty += len(get_first(config['fields']['french'], note_dict))

            if not empty:
                result = fill_all_defs(hanzi, note_dict)

                if result:
                    d_success += 1
                else:
                    d_failed += 1
                    if d_failed < 20:
                        failed_hanzi += [sanitize_hanzi(note_dict)]

            def write_back(fields):
                for f in fields:
                    if f in note_dict and note_dict[f] != note[f]:
                        note[f] = note_dict[f]

            write_back(config['fields']['meaning'])
            write_back(config['fields']['english'])
            write_back(config['fields']['german'])
            write_back(config['fields']['french'])
            write_back(config['fields']['classifier'])
            write_back(config['fields']['alternative'])
            note.flush()

    msg = '''
    <b>Translation complete</b><br>
    <b>Chinese notes:</b> %(has_fields)d<br>
    <b>Translated:</b> %(filled)d<br>
    <b>Failed:</b> %(failed)d''' % {
        'has_fields': d_has_fields,
        'filled': d_success,
        'failed': d_failed,
    }
    if d_failed > 0:
        msg += (
            '<div>Translation failures may come either from connection issues '
            "(if you're using an online translation service), or because some "
            'words are not it the dictionary (for local dictionaries).</div>'
            '<div>The following notes failed: ' + ', '.join(failed_hanzi) +
            '</div>')
    mw.progress.finish()
    showInfo(msg)