Compare commits
No commits in common. "eb22176b2a2fde426b6384af361a87d8179c1f28" and "8ab6a334c47f9ea14dc3141660e1ea907a85676f" have entirely different histories.
eb22176b2a
...
8ab6a334c4
|
|
@ -1,125 +0,0 @@
|
||||||
#!/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%%</b>*}"
|
|
||||||
old_term="${old_term##*<b>}"
|
|
||||||
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, "<b>%s</b>"%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
|
|
||||||
|
|
@ -16,14 +16,6 @@ in {
|
||||||
bell = [pipewire libnotify];
|
bell = [pipewire libnotify];
|
||||||
nsxiv-rifle = [nsxiv];
|
nsxiv-rifle = [nsxiv];
|
||||||
screenshot = [maim xclip];
|
screenshot = [maim xclip];
|
||||||
record-audio = [pulseaudio ffmpeg jq];
|
|
||||||
}
|
|
||||||
// lib.optionalAttrs config.u.has.jp {
|
|
||||||
anki-update = [libnotify inotify-tools pulseaudio ffmpeg jq pyp
|
|
||||||
(writers.writePython3Bin "furigana" {
|
|
||||||
libraries = [python312Packages.fugashi python312Packages.unidic-lite];
|
|
||||||
} (builtins.readFile ./furigana))
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
home.file = builtins.listToAttrs (
|
home.file = builtins.listToAttrs (
|
||||||
map
|
map
|
||||||
|
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
"""
|
|
||||||
ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろわをんーゎゐゑゕゖゔゝゞ・「」。、
|
|
||||||
ァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロワヲンーヮヰヱヵヶヴヽヾ・「」。、
|
|
||||||
"""
|
|
||||||
|
|
||||||
import fugashi
|
|
||||||
import sys
|
|
||||||
|
|
||||||
if len(sys.argv) != 2:
|
|
||||||
print('usage: furigana <word>')
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
H, K = __doc__.strip().split('\n')
|
|
||||||
t = {ord(a): ord(b) for a, b in zip(K, H)}
|
|
||||||
|
|
||||||
r = []
|
|
||||||
for x in fugashi.Tagger().parseToNodeList(sys.argv[1]):
|
|
||||||
if all(c in H + K for c in x.surface) or not x.feature.kana:
|
|
||||||
r.append(x.surface)
|
|
||||||
else:
|
|
||||||
r.append(f" {x.surface}[{x.feature.kana.translate(t)}]")
|
|
||||||
print(''.join(r).strip())
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
monitor="$(pactl -f json info | jq -r '.default_sink_name + ".monitor"')"
|
|
||||||
exec ffmpeg \
|
|
||||||
-f pulse \
|
|
||||||
-i "$monitor" \
|
|
||||||
-loglevel error \
|
|
||||||
-ac 2 \
|
|
||||||
"${@:-a.mp3}"
|
|
||||||
|
|
@ -377,8 +377,6 @@ globalkeys = gears.table.join(
|
||||||
awful.key({ modkey }, "p", function() menubar.show() end,
|
awful.key({ modkey }, "p", function() menubar.show() end,
|
||||||
{description = "show the menubar", group = "launcher"}),
|
{description = "show the menubar", group = "launcher"}),
|
||||||
|
|
||||||
awful.key({ modkey }, "a", function() awful.spawn("anki-update") end, {description = "anki update"}),
|
|
||||||
awful.key({ modkey, "Shift" }, "a", function() awful.spawn("anki-update -s") end, {description = "anki update screenshot"}),
|
|
||||||
awful.key({ modkey }, "r", function() awful.spawn(run) end, {description = "run prompt"}),
|
awful.key({ modkey }, "r", function() awful.spawn(run) end, {description = "run prompt"}),
|
||||||
awful.key({ modkey }, "b", function() awful.spawn(browser) end, {description = "open browser"}),
|
awful.key({ modkey }, "b", function() awful.spawn(browser) end, {description = "open browser"}),
|
||||||
awful.key({ modkey }, "t", function() awful.spawn(file_manager) end, {description = "open file manager"}),
|
awful.key({ modkey }, "t", function() awful.spawn(file_manager) end, {description = "open file manager"}),
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,6 @@ vim.opt.cursorline = true
|
||||||
|
|
||||||
vim.opt.scrolloff = 8
|
vim.opt.scrolloff = 8
|
||||||
|
|
||||||
vim.opt.fileencodings = {"ucs-bom", "utf-8", "default", "sjis"}
|
|
||||||
|
|
||||||
vim.api.nvim_create_autocmd('TextYankPost', {
|
vim.api.nvim_create_autocmd('TextYankPost', {
|
||||||
desc = 'Highlight when yanking (copying) text',
|
desc = 'Highlight when yanking (copying) text',
|
||||||
group = vim.api.nvim_create_augroup('u-highlight-yank', { clear = true }),
|
group = vim.api.nvim_create_augroup('u-highlight-yank', { clear = true }),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue