#!/bin/sh set -e anki_connect="localhost:8765" afield="sent_a" aext="ogg" ifield="img" iext="avif" sfield="sent" rfield="sent_r" : ${TMPDIR:=/tmp} lock="$TMPDIR/ankiupdatelock" log() { notify-send "anki-update: $1" printf "\e[33m%s\e[0m\n" "$1" } fail() { log "$1" bell exit 1 } anki() { curl -s "$anki_connect" -X POST -d "$(printf '{"action":"%s","version":6,"params":%s}' "$1" "$2")" } stop_record() { kill "$pid2" inotifywait -e close_write "$audio" -qq } screenshot() { window="$(xprop -root | sed -n 's/^_NET_ACTIVE_WINDOW(WINDOW): window id # //p')" maim -u -i "$window" | ffmpeg -loglevel error -i - -vf scale=-1:200 "$image" tag="$(xprop -id "$window" | sed -n 's/^WM_NAME(STRING) = "\(.*\)"$/\1/p' | tr ' ' _)" echo "* tag: $tag" } get_latest() { id="$(anki findNotes '{"query":"added:1"}')" || fail "anki connect unreachable" id="$(echo "$id" | jq .result[-1])" if [ "$id" = "null" ]; then fail "no note to update" fi } get_note_field() { note="$(anki notesInfo "$(printf '{"notes":[%d]}' "$id")")" old_sent="$(echo "$note" | jq -r .result[0].fields.['"'"$sfield"'"'].value)" echo "* old sentence: $old_sent" old_term="${old_sent%%*}" old_term="${old_term##*}" echo "* old term: $old_term" } get_name() { date="$(date +%Y_%m_%d-%H_%M_%S)" aname="$tag-$date.$aext" iname="$tag-$date.$iext" } get_reading() { sent="$(xclip -o -sel clip)" echo "* clipboard: $sent" case "$sent" in *"$old_term"*) ;; *) fail "clipboard does not contain term" ;; esac reading="$(furigana "$sent")" sent="$(echo $sent | a="$old_term" pyp -b 's=os.environ["a"]' 'x.replace(s, "%s"%s)')" echo "* new sentence: $sent" echo "* reading: $sent" } update() { anki updateNote "$(printf '{"note":{ "id":%d, "tags":"%s", "fields":{"%s":"%s","%s":"%s"}, "picture":{ "filename":"%s", "path":"%s", "fields":["%s"] }%s }}' "$id" "$tag" "$sfield" "$sent" "$rfield" "$reading" "$iname" "$image" "$ifield" "$1")" log "updated note $id" } if [ "$1" = "-s" ]; then image="$TMPDIR/img-$$.$iext" trap "rm '$image'" EXIT get_latest screenshot get_note_field get_name get_reading update elif [ "$1" = "-x" ]; then [ -e "$lock" ] || fail "not running" IFS=, read pid1 pid2 id < "$lock" kill "$pid2" audio="$TMPDIR/aud-$pid1.$aext" rm "$audio" "$lock" log "cancelled anki update" elif ! [ -e "$lock" ]; then get_latest log 'recording started' record-audio \ -af silenceremove=1:0:-50dB \ "$TMPDIR/aud-$$.$aext" & echo "$$,$!,$id" > "$lock" else IFS=, read pid1 pid2 id < "$lock" audio="$TMPDIR/aud-$pid1.$aext" image="$TMPDIR/img-$pid1.$iext" trap "rm '$audio' '$image' '$lock'" EXIT log "stopping recording" stop_record screenshot get_note_field get_name get_reading update "$(printf ', "audio":{ "filename":"%s", "path":"%s", "fields":["%s"] }' "$aname" "$audio" "$afield")" fi