Addon Help Needed (or Interesting in Taking Over an Addon?)

Dear Anki Addon Community,

I hope that some generous person might be willing to help me with an addon problem, or even just take over the addon.

I am not a coder or programmer, just an avid Anki user and promoter for over ten years. About 6 years ago, a friendly addon writer helped me develop a simple addon (only 8 lines of code) that has been very helpful for me, my children, and many of my friends who use Anki.

However, that addon broke around version 2.1.18 or 2.1.19, and I have not been able to figure out how to fix it. Thus, we haven’t been able to update to any Anki release since then.

The addon is a simple concept. Some cards are are just more difficult to learn than others. And everyone is going to have some problematic or difficult cards. I don’t like to just suspend these difficult cards, and even sometimes after reformulating a card, it might still require special attention to learn accurately.

For these cards, we created a small addon that plays a small “ding,” “chime” or “notification” sound when such a card comes up. This sound notifies the user to pay extra attention before answering the card. This has helped us learn troublesome cards more efficiently.

The addon (pasted at bottom of post) was very simple. It was triggered based on tags. So, you could tag a card with any word you wanted (such as “hard”) and when a card came up for review with that tag, the sound would play. You could even trigger different or multiple sounds based on tags (such as “hard” and “veryhard”). You could even just use Anki’s built in tags of “marked” and “leech” and just trigger a small sound with those.

In addition to the addon itself, a person had to add the sound file(s) into their media folder (something like “_marked.mp3” or _leech.mp3) and also had to add a line like this in the card template:

{{ring(marked):_marked.mp3}}{{ring(leech):_leech.mp3}

If someone wanted to make the line not noticeable, they could also wrap it in a span like this:

{{ring(marked):_marked.mp3}}{{ring(leech):_leech.mp3}}

All that to say, we are all still running older versions of Anki to keep the addon working, but I’d love to update the addon to work with current versions. Unfortunately, with my very weak coding knowledge, I have not been able to get the addon working.

Any help in getting it working again would be greatly appreciated. And if you like the idea of the addon, you are welcome to even create/update/post the addon as your own. I think that many others in the Anki community would also find it helpful.

Thanks in advance for any help.

All the Best,
mnhende2

I can’t seem to attach the addon to this post, so here is the add one code:


Addon for audio dubbing of tag

Key-expression format: {{ring(my_tag):file.mp3}}

from anki.hooks import addHook

def addModifier(txt, my_tag, fields, fname, full):
if my_tag in fields[‘Tags’]:
txt = ‘[sound:’+fname+’]’
else:
txt = ‘’
return txt

addHook(‘fmod_ring’, addModifier)

I think this can be done via javascript in the template i.e. no add.on needed. Let me carry some tests. I’ll update once I am done

Thanks Guillem! Much appreciation.

Best,

mnhende2


from os.path import dirname
from aqt.reviewer import Reviewer
from anki.hooks import wrap
from anki.sound import play


addon_path = dirname(__file__)
audiopath = addon_path + "/No.ogg"
something = addon_path + "/something.ogg"

def play_sound(self):
    tags = [tag.lower() for tag in self.card.note().tags]
    if "test" in tags:
        play(audiopath)
    if "test2" in tags:
        play(something)

Reviewer.nextCard = wrap(Reviewer.nextCard, play_sound, 'after')

this is what i came up with.
put the audio files in add-on folder.
you can add more 'if’s to to play different sounds according to different tags.

feel free to ask question if you don’t know how to modify it.

2 Likes

Indeed the javascript I tried did not work. The strings were generated but not the playing. Actually I use this solution with CSS styling fir leeches etc, never tried audio.

@mmdj2 solution is working indeed, but the audio that may be played at the card is not playing. For instance a audio file in the Front field of Basic template.

just tested that. for me it plays the audio that’s on the front first, then plays the audio that add-on plays. :thinking:

@mmdj2 and @guillempalausalva Thanks a bunch to each of you for helping.

@mmdj2 I haven’t had a chance to test what you posted yet, but I look forward to trying. You mentioned the card audio plays before the add-on audio. Any idea of how I could get the add-on audio to play first?

In the old add-on, I had to put the {{ring(marked):_marked.mp3}}{{ring(leech):_leech.mp3} line at the top if the card to get it to play first.

2.1.29 on Windows, l checked again. If I remove the tag the front audio plays. I am using a file recorded my own voice, if that makes a difference

edit: {{tts en_US:Front}} also is not playing.

edit: I also have the autoplay settings enabled.

You don’t need to add anything now.

I just tested and the add-on works on 2.1.28.

tested that too, still plays. weird :thinking:
on 2.1.29 stable

from os.path import dirname
from aqt.reviewer import Reviewer
from anki.hooks import wrap
from anki.sound import play, AVPlayer


addon_path = dirname(__file__)
audiopath = addon_path + "/No.ogg"
audiopath2 = addon_path + "/something.ogg"

def _play_tags(self, tags):
    self._enqueued = tags[:]
    if self.interrupt_current_audio and False:
        self._stop_if_playing()
    self._play_next_if_idle()

AVPlayer.play_tags = _play_tags

def play_sound(self):
    tags = [tag.lower() for tag in self.card.note().tags]
    if "test" in tags:
        play(audiopath)
    if "test2" in tags:
        play(audiopath2)

Reviewer._showQuestion = wrap(Reviewer._showQuestion, play_sound, 'before')

this plays the add-on audio first.

side effect: the audio doesn’t stop when you press show answer, even when you go to the next card. so basically you’ll have to listen to the full audio :expressionless:
don’t know any other way of doing this.

2 Likes

Monkey-patching _showQuestion seems to work:

from os.path import dirname
import json

from aqt import gui_hooks
from aqt.sound import av_player

from aqt.reviewer import Reviewer
from anki.sound import SoundOrVideoTag
from aqt.theme import theme_manager


addon_path = dirname(__file__)
audiopath = addon_path + "/something.ogg"

def my_showQuestion(self) -> None:
    self._reps += 1
    self.state = "question"
    self.typedAnswer: str = None
    c = self.card
    # grab the question and play audio
    q = c.q()

    # play audio?
    if c.autoplay():
        question_av_tags = c.question_av_tags()
        tags = [tag.lower() for tag in c.note().tags]
        if "test" in tags:
            question_av_tags = [SoundOrVideoTag(filename=audiopath)] + question_av_tags
        av_player.play_tags(question_av_tags)
    else:
        av_player.clear_queue_and_maybe_interrupt()
        av_player.play_file(audiopath)
    # render & update bottom
    q = self._mungeQA(q)
    q = gui_hooks.card_will_show(q, c, "reviewQuestion")

    bodyclass = theme_manager.body_classes_for_card_ord(c.ord)

    self.web.eval("_showQuestion(%s,'%s');" % (json.dumps(q), bodyclass))
    self._drawFlag()
    self._drawMark()
    self._showAnswerButton()
    # if we have a type answer field, focus main web
    if self.typeCorrect:
        self.mw.web.setFocus()
    # user hook
    gui_hooks.reviewer_did_show_question(c)

Reviewer._showQuestion = my_showQuestion

1 Like

WIll be worth sharing the add-on in ankiweb? Maybe other users may find it useful.

2 Likes

Certainly. Though it needs some work, like reading the tag names and audio paths from a configuration file?

I just joined the forums - I don’t know if this particular spot is the best place to ask, but I’m interested in helping with some add-ons. Not sure if they’re already claimed, or if I should offer to take them over, but before I did - what’s the best resources you all would recommend for getting up and running on Anki Add-ons?

If there are some good resources or active Discord channels and it doesn’t make it look to be a ton of work, I’d even be happy to take over this particular addon and getting it working!

Maybe something like this:

from os.path import dirname
import json

from aqt import gui_hooks
from aqt.sound import av_player

from aqt.reviewer import Reviewer
from anki.sound import SoundOrVideoTag
from aqt.theme import theme_manager
from aqt import mw


def get_sounds(config, card):
    sounds = []
    tags = [tag.lower() for tag in card.note().tags]
    for tag in config.keys():
        if tag in tags:
            sounds.append(SoundOrVideoTag(filename=config[tag]))
    return sounds

def my_showQuestion(self) -> None:
    self._reps += 1
    self.state = "question"
    self.typedAnswer: str = None
    c = self.card
    # grab the question and play audio
    q = c.q()

    # play audio?
    added_sounds = get_sounds(mw.addonManager.getConfig(__name__), c)
    question_av_tags = c.question_av_tags()
    if c.autoplay():
        av_player.play_tags(added_sounds + question_av_tags)
    else:
        av_player.clear_queue_and_maybe_interrupt()
        av_player.play_tags(added_sounds)
    # render & update bottom
    q = self._mungeQA(q)
    q = gui_hooks.card_will_show(q, c, "reviewQuestion")

    bodyclass = theme_manager.body_classes_for_card_ord(c.ord)

    self.web.eval("_showQuestion(%s,'%s');" % (json.dumps(q), bodyclass))
    self._drawFlag()
    self._drawMark()
    self._showAnswerButton()
    # if we have a type answer field, focus main web
    if self.typeCorrect:
        self.mw.web.setFocus()
    # user hook
    gui_hooks.reviewer_did_show_question(c)

Reviewer._showQuestion = my_showQuestion

With a config file like this:

{
  "tag1": "sound1.ogg",
  "tag2": "sound2.ogg"
}

1 Like

@towan-unmet Here is a helpful guide that can help with writing Add-ons for Anki. https://addon-docs.ankiweb.net/#/

There are often new ideas or requests for add-ons on this forum. As an example, an idea that I have had, but never posted is for an add-on called “Enhanced Timebox”

Anki has a nice “Timebox” feature built in, but the notification is very basic. It just shows the number of cards studied and the amount of time. But it could be enhanced to include more stats such as something like this.
Capture

It could be further enhanced to show some type of reward message like, “A lot of cards!” or “Excellent accuracy.” or “You’re on a fast streak, keep it up!.” The user could set the # of reviews or % of accuracy to trigger a message.

Anyhow, wish you well in developing add-ons. Thanks for being willing to contribute. Many will appreciate it.

Hey, thanks! That link to the docs is quite helpful.

I’d love to build some add-ons. Where would you suggest I go look to see what sort of needs/requests Anki users are making?

I’d love to see about building some things that are useful for the community.

Anki subreddit https://www.reddit.com/r/Anki

1 Like