mirror of
https://github.com/ksyasuda/dotfiles.git
synced 2025-12-07 22:48:00 -08:00
update
This commit is contained in:
@@ -139,3 +139,5 @@ bind = $mainMod, code:112, submap, reset
|
||||
submap = reset
|
||||
|
||||
bind = SUPER, l, exec, hyprlock
|
||||
|
||||
bind = $mainMod SHIFT, a, exec, ~/.config/rofi/scripts/rofi-anki-script.sh
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/rofi-menu-helpers.sh"
|
||||
|
||||
BROWSER=/usr/bin/zen-browser
|
||||
OPTIONS=(
|
||||
"Arch Linux (btw)"
|
||||
"Hyprland"
|
||||
DOC_GROUPS=(
|
||||
"Arch Linux (btw)|ARCH"
|
||||
"Hyprland|HYPRLAND"
|
||||
)
|
||||
ARCH=(
|
||||
"Archlinux Wiki|https://wiki.archlinux.org/title/Main_page"
|
||||
@@ -13,56 +16,37 @@ HYPRLAND=(
|
||||
"Hyprland Window Rules|https://wiki.hypr.land/Configuring/Window-Rules/"
|
||||
)
|
||||
|
||||
get_url() {
|
||||
urls=("$@")
|
||||
display_urls=()
|
||||
declare -A url_map
|
||||
for url in "${urls[@]}"; do
|
||||
display_urls+=("${url%%|*}")
|
||||
label="${url%%|*}"
|
||||
url_map["$label"]="${url##*|}"
|
||||
done
|
||||
display_urls+=("Back")
|
||||
url_map["Back"]="Back"
|
||||
|
||||
selection="$(printf "%s\n" "${display_urls[@]}" | rofi -theme-str 'window {width: 25%;} listview {columns: 1; lines: 10;}' -theme ~/.config/rofi/launchers/type-2/style-2.rasi -dmenu -l 5 -i -p "Select Documentation")"
|
||||
url="${url_map[$selection]}"
|
||||
|
||||
if [ -z "$url" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
printf "%s\n" "$url"
|
||||
select_group() {
|
||||
rofi_select_label_value "Select Documentation Group" DOC_GROUPS
|
||||
}
|
||||
|
||||
get_docs_list() {
|
||||
selection="$(printf "%s\n" "${OPTIONS[@]}" | rofi -theme-str 'window {width: 25%;} listview {columns: 1; lines: 10;}' -theme ~/.config/rofi/launchers/type-2/style-2.rasi -dmenu -l 5 -i -p "Select Documentation Group")"
|
||||
case "$selection" in
|
||||
"Arch Linux (btw)")
|
||||
urls=("${ARCH[@]}")
|
||||
select_url() {
|
||||
local urls_array="$1"
|
||||
rofi_select_label_value "Select Documentation" "$urls_array" "Back"
|
||||
}
|
||||
|
||||
main() {
|
||||
while true; do
|
||||
group_key="$(select_group)" || exit 0
|
||||
case "$group_key" in
|
||||
ARCH)
|
||||
urls_ref=ARCH
|
||||
;;
|
||||
"Hyprland")
|
||||
urls=("${HYPRLAND[@]}")
|
||||
HYPRLAND)
|
||||
urls_ref=HYPRLAND
|
||||
;;
|
||||
*)
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
printf "%s\n" "${urls[@]}"
|
||||
}
|
||||
|
||||
main() {
|
||||
mapfile -t urls < <(get_docs_list)
|
||||
url="$(get_url "${urls[@]}")"
|
||||
if [ -z "$url" ]; then
|
||||
printf "No URL selected.\n"
|
||||
exit 0
|
||||
elif [ "$url" == "Back" ]; then
|
||||
main
|
||||
exit 0
|
||||
selection="$(select_url "$urls_ref")" || exit 0
|
||||
if [[ "$selection" == "Back" ]]; then
|
||||
continue
|
||||
fi
|
||||
$BROWSER "$url" &>/dev/null &
|
||||
$BROWSER "$selection" &>/dev/null &
|
||||
exit 0
|
||||
done
|
||||
}
|
||||
|
||||
main
|
||||
|
||||
68
.config/rofi/scripts/rofi-menu-helpers.sh
Normal file
68
.config/rofi/scripts/rofi-menu-helpers.sh
Normal file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Lightweight helpers to build rofi menus with label/value pairs.
|
||||
# Intended to be sourced from other scripts.
|
||||
|
||||
# Allow callers to override theme/args without touching code.
|
||||
: "${ROFI_THEME:=$HOME/.config/rofi/launchers/type-2/style-2.rasi}"
|
||||
: "${ROFI_THEME_STR:="window {width: 25%;} listview {columns: 1; lines: 10;}"}"
|
||||
: "${ROFI_DMENU_ARGS:=-i -l 5}"
|
||||
|
||||
# rofi_menu prompt option...
|
||||
# Prints the selected option to stdout and propagates the rofi exit code
|
||||
# (1 when the user cancels).
|
||||
rofi_menu() {
|
||||
local prompt="$1"
|
||||
shift
|
||||
local -a options=("$@")
|
||||
|
||||
local selection
|
||||
selection="$(printf "%s\n" "${options[@]}" | rofi -dmenu $ROFI_DMENU_ARGS \
|
||||
${ROFI_THEME:+-theme "$ROFI_THEME"} \
|
||||
${ROFI_THEME_STR:+-theme-str "$ROFI_THEME_STR"} \
|
||||
-p "$prompt")"
|
||||
local status=$?
|
||||
[[ $status -ne 0 ]] && return "$status"
|
||||
printf "%s\n" "$selection"
|
||||
}
|
||||
|
||||
# rofi_select_label_value prompt array_name [back_label]
|
||||
# array_name should contain entries shaped as "Label|Value".
|
||||
# Prints the mapped value (or the back label when chosen). Returns 1 on cancel.
|
||||
rofi_select_label_value() {
|
||||
local prompt="$1"
|
||||
local array_name="$2"
|
||||
local back_label="${3:-}"
|
||||
|
||||
# Access caller's array by name
|
||||
local -n kv_source="$array_name"
|
||||
local -A kv_map=()
|
||||
local -a display=()
|
||||
|
||||
for entry in "${kv_source[@]}"; do
|
||||
local label="${entry%%|*}"
|
||||
local value="${entry#*|}"
|
||||
kv_map["$label"]="$value"
|
||||
display+=("$label")
|
||||
done
|
||||
|
||||
if [[ -n "$back_label" ]]; then
|
||||
kv_map["$back_label"]="$back_label"
|
||||
display+=("$back_label")
|
||||
fi
|
||||
|
||||
local selection
|
||||
selection="$(rofi_menu "$prompt" "${display[@]}")" || return "$?"
|
||||
[[ -z "$selection" ]] && return 1
|
||||
printf "%s\n" "${kv_map[$selection]}"
|
||||
}
|
||||
|
||||
# rofi_select_list prompt array_name
|
||||
# Convenience wrapper for plain lists (no label/value mapping).
|
||||
rofi_select_list() {
|
||||
local prompt="$1"
|
||||
local array_name="$2"
|
||||
local -n list_source="$array_name"
|
||||
rofi_menu "$prompt" "${list_source[@]}"
|
||||
}
|
||||
|
||||
202
projects/scripts/record-audio.sh
Normal file → Executable file
202
projects/scripts/record-audio.sh
Normal file → Executable file
@@ -1,93 +1,145 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Version 1.2
|
||||
# shoutout to https://gist.github.com/Cephian/f849e326e3522be9a4386b60b85f2f23 for the original script,
|
||||
# https://github.com/xythh/ added the ankiConnect functionality
|
||||
# toggle record computer audio (run once to start, run again to stop)
|
||||
# dependencies: ffmpeg, pulseaudio, curl
|
||||
# Toggle desktop audio recording and attach the result to the newest Anki note
|
||||
# (as tagged by Yomichan). Run once to start recording, run again to stop.
|
||||
# Dependencies: jq, curl, ffmpeg/ffprobe, pulseaudio (parec+pactl), bc, notify-send
|
||||
|
||||
# where recording gets saved, gets deleted after being imported to anki
|
||||
DIRECTORY="$HOME/.cache/"
|
||||
FORMAT="mp3" # ogg or mp3
|
||||
# cut file since it glitches a bit at the end sometimes
|
||||
CUT_DURATION="0.1"
|
||||
#port used by ankiconnect
|
||||
ankiConnectPort="8765"
|
||||
# gets the newest created card, so make sure to create the card first with yomichan
|
||||
newestNoteId=$(curl -s localhost:$ankiConnectPort -X POST -d '{"action": "findNotes", "version": 6, "params": { "query": "is:new"}}' | jq '.result[-1]')
|
||||
#Audio field name
|
||||
audioFieldName="SentenceAudio"
|
||||
set -euo pipefail
|
||||
|
||||
#if there is no newest note, you either have a complete empty anki or ankiconnect isn't running
|
||||
if [ "$newestNoteId" = "" ]; then
|
||||
notify-send "anki connect not found"
|
||||
ANKI_CONNECT_PORT="${ANKI_CONNECT_PORT:-8765}"
|
||||
AUDIO_FIELD_NAME="${AUDIO_FIELD_NAME:-SentenceAudio}"
|
||||
FORMAT="${FORMAT:-mp3}" # mp3 or ogg
|
||||
CUT_DURATION="${CUT_DURATION:-0.1}"
|
||||
CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/record-audio"
|
||||
RECORD_TIMEOUT="${RECORD_TIMEOUT:-60}"
|
||||
ANKI_URL="http://localhost:${ANKI_CONNECT_PORT}"
|
||||
|
||||
require_cmd() {
|
||||
command -v "$1" >/dev/null 2>&1 || {
|
||||
echo "Missing dependency: $1" >&2
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
notify() {
|
||||
# Best-effort notification; keep script running if notify-send is missing.
|
||||
if command -v notify-send >/dev/null 2>&1; then
|
||||
notify-send -t 1000 "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
get_active_sink() {
|
||||
pactl list sinks short 2>/dev/null | awk '$6=="RUNNING"{print $1; exit 0}'
|
||||
}
|
||||
|
||||
get_newest_note_id() {
|
||||
local response
|
||||
response=$(curl -sS "$ANKI_URL" -X POST -H 'Content-Type: application/json' \
|
||||
-d '{"action":"findNotes","version":6,"params":{"query":"is:new"}}')
|
||||
jq -r '.result[-1] // empty' <<<"$response"
|
||||
}
|
||||
|
||||
update_anki_note() {
|
||||
local note_id="$1" audio_path="$2" filename="$3"
|
||||
|
||||
local payload
|
||||
payload=$(jq -n --argjson noteId "$note_id" --arg field "$AUDIO_FIELD_NAME" \
|
||||
--arg path "$audio_path" --arg filename "$filename" '
|
||||
{action:"updateNoteFields",version:6,
|
||||
params:{note:{id:$noteId,fields:{($field):""},
|
||||
audio:[{path:$path,filename:$filename,fields:[$field]}]}}}')
|
||||
|
||||
curl -sS "$ANKI_URL" -X POST -H 'Content-Type: application/json' -d "$payload" >/dev/null
|
||||
}
|
||||
|
||||
open_note_in_browser() {
|
||||
local note_id="$1"
|
||||
local payload
|
||||
payload=$(jq -n --argjson noteId "$note_id" '
|
||||
{action:"guiBrowse",version:6,params:{query:("nid:" + ($noteId|tostring))}}')
|
||||
curl -sS "$ANKI_URL" -X POST -H 'Content-Type: application/json' -d "$payload" >/dev/null
|
||||
}
|
||||
|
||||
record_audio() {
|
||||
local note_id="$1"
|
||||
local sink
|
||||
sink=$(get_active_sink) || true
|
||||
|
||||
if [[ -z "$sink" ]]; then
|
||||
notify "Record Error" "No running PulseAudio sink found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if pgrep -f "parec"; then
|
||||
pkill -f "parec"
|
||||
else
|
||||
time=$(date +%s)
|
||||
name="$DIRECTORY/$time"
|
||||
wav_file="$name.wav"
|
||||
out_file="$name.$FORMAT"
|
||||
mkdir -p "$CACHE_DIR"
|
||||
|
||||
if ! [ -d "$DIRECTORY" ]; then
|
||||
mkdir "$DIRECTORY"
|
||||
fi
|
||||
notify-send -t 1000 "Audio recording started"
|
||||
#timeout 1m arecord -t wav -f cd "$wav_file"
|
||||
local timestamp wav_file out_file
|
||||
timestamp=$(date +%s)
|
||||
wav_file="$CACHE_DIR/$timestamp.wav"
|
||||
out_file="$CACHE_DIR/$timestamp.$FORMAT"
|
||||
|
||||
# just grabs last running source... may not always work if your pulseaudio setup is complicated
|
||||
if ! timeout 1m parec -d"$(pactl list sinks | grep -B1 'State: RUNNING' | sed -nE 's/Sink #(.*)/\1/p' | tail -n 1)" --file-format=wav "$wav_file"; then
|
||||
notify "Audio recording started"
|
||||
|
||||
notify-send "Error recording " "most likely no audio playing"
|
||||
rm "$wav_file"
|
||||
if ! timeout "$RECORD_TIMEOUT" parec -d"$sink" --file-format=wav "$wav_file"; then
|
||||
notify "Record Error" "No audio captured (timeout or sink issue)"
|
||||
rm -f "$wav_file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
input_duration=$(ffprobe -v error -select_streams a:0 -show_entries stream=duration -of default=noprint_wrappers=1:nokey=1 "$wav_file")
|
||||
output_duration=$(echo "$input_duration"-"$CUT_DURATION" | bc)
|
||||
local input_duration output_duration
|
||||
input_duration=$(ffprobe -v error -select_streams a:0 \
|
||||
-show_entries stream=duration -of default=noprint_wrappers=1:nokey=1 "$wav_file")
|
||||
output_duration=$(echo "$input_duration - $CUT_DURATION" | bc -l)
|
||||
|
||||
# encode file and delete OG
|
||||
if [ $FORMAT = "ogg" ]; then
|
||||
ffmpeg -i "$wav_file" -vn -codec:a libvorbis -b:a 64k -t "$output_duration" "$out_file"
|
||||
elif [ $FORMAT = "mp3" ]; then
|
||||
ffmpeg -i "$wav_file" -vn -codec:a libmp3lame -qscale:a 1 -t "$output_duration" "$out_file"
|
||||
else
|
||||
notify-send "Record Error" "Unknown format $FORMAT"
|
||||
# Guard against negative durations
|
||||
if [[ $(echo "$output_duration < 0" | bc -l) -eq 1 ]]; then
|
||||
output_duration="0"
|
||||
fi
|
||||
rm "$wav_file"
|
||||
|
||||
# Update newest note with recorded audio
|
||||
curl -s localhost:$ankiConnectPort -X POST -d '{
|
||||
case "$FORMAT" in
|
||||
ogg)
|
||||
ffmpeg -nostdin -y -i "$wav_file" -vn -codec:a libvorbis -b:a 64k \
|
||||
-t "$output_duration" "$out_file"
|
||||
;;
|
||||
mp3)
|
||||
ffmpeg -nostdin -y -i "$wav_file" -vn -codec:a libmp3lame -qscale:a 1 \
|
||||
-t "$output_duration" "$out_file"
|
||||
;;
|
||||
*)
|
||||
notify "Record Error" "Unknown format: $FORMAT"
|
||||
rm -f "$wav_file"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
"action": "updateNoteFields",
|
||||
"version": 6,
|
||||
"params": {
|
||||
"note": {
|
||||
"id": '"$newestNoteId"',
|
||||
"fields": {
|
||||
"'$audioFieldName'": ""
|
||||
},
|
||||
"audio": [{
|
||||
"path": "'"$out_file"'",
|
||||
"filename": "'"$time"'.'$FORMAT'",
|
||||
"fields": [
|
||||
"'$audioFieldName'"
|
||||
]
|
||||
}]
|
||||
rm -f "$wav_file"
|
||||
|
||||
update_anki_note "$note_id" "$out_file" "$timestamp.$FORMAT"
|
||||
open_note_in_browser "$note_id"
|
||||
|
||||
notify "Audio recording copied"
|
||||
rm -f "$out_file"
|
||||
}
|
||||
}
|
||||
}'
|
||||
# opens changed note, comment if you don't want it.
|
||||
curl -s localhost:$ankiConnectPort -X POST -d '{
|
||||
"action": "guiBrowse",
|
||||
"version": 6,
|
||||
"params": {
|
||||
"query": "nid:'"$newestNoteId"'"
|
||||
}
|
||||
}'
|
||||
notify-send -t 1000 "Audio recording copied"
|
||||
rm "$out_file"
|
||||
|
||||
main() {
|
||||
for cmd in curl jq ffmpeg ffprobe parec pactl bc; do
|
||||
require_cmd "$cmd"
|
||||
done
|
||||
|
||||
if pgrep -x parec >/dev/null 2>&1; then
|
||||
pkill -x parec
|
||||
notify "Audio recording stopped"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
local newest_note
|
||||
newest_note=$(get_newest_note_id)
|
||||
|
||||
if [[ -z "$newest_note" ]]; then
|
||||
notify "Anki Connect" "No new notes found or AnkiConnect unavailable"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
record_audio "$newest_note"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
163
projects/scripts/screenshot-anki.sh
Normal file → Executable file
163
projects/scripts/screenshot-anki.sh
Normal file → Executable file
@@ -1,75 +1,112 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Version 1.2
|
||||
# click and drag to screenshot dragged portion
|
||||
# click on specific window to screenshot window area
|
||||
# dependencies: imagemagick, xclip,curl maybe xdotool (see comment below)
|
||||
# shoutout to https://gist.github.com/Cephian/f849e326e3522be9a4386b60b85f2f23 for the original script,
|
||||
# https://github.com/xythh/ added the ankiConnect functionality
|
||||
# if anki is running the image is added to your latest note as a jpg, if anki is not running it's added to your clipboard as a png
|
||||
time=$(date +%s)
|
||||
tmp_file="$HOME/.cache/$time"
|
||||
ankiConnectPort="8765"
|
||||
pictureField="Picture"
|
||||
quality="90"
|
||||
# Capture a region with slurp+grim. If AnkiConnect is available, attach the
|
||||
# JPEG to the newest note; otherwise copy a PNG to the clipboard.
|
||||
|
||||
# This gets your notes marked as new and returns the newest one.
|
||||
newestNoteId=$(curl -s localhost:$ankiConnectPort -X POST -d '{"action": "findNotes", "version": 6, "params": { "query": "is:new"}}' | jq '.result[-1]')
|
||||
set -euo pipefail
|
||||
|
||||
# you can remove these two lines if you don't have software which
|
||||
# makes your mouse disappear when you use the keyboard (e.g. xbanish, unclutter)
|
||||
# https://github.com/ImageMagick/ImageMagick/issues/1745#issuecomment-777747494
|
||||
ANKI_CONNECT_PORT="${ANKI_CONNECT_PORT:-8765}"
|
||||
PICTURE_FIELD="${PICTURE_FIELD:-Picture}"
|
||||
QUALITY="${QUALITY:-90}"
|
||||
CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/screenshot-anki"
|
||||
ANKI_URL="http://localhost:${ANKI_CONNECT_PORT}"
|
||||
REQUIREMENTS=(slurp grim wl-copy xdotool curl jq)
|
||||
|
||||
notify() {
|
||||
if command -v notify-send >/dev/null 2>&1; then
|
||||
notify-send "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
require_cmd() {
|
||||
command -v "$1" >/dev/null 2>&1 || {
|
||||
notify "Missing dependency" "$1 is required"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
wiggle_mouse() {
|
||||
# Avoid disappearing cursor on some compositors
|
||||
xdotool mousemove_relative 1 1
|
||||
xdotool mousemove_relative -- -1 -1
|
||||
}
|
||||
|
||||
# if anki connect is running it will return your latest note id, and the following code will run, if anki connect is not running nothing is return.
|
||||
if [ "$newestNoteId" != "" ]; then
|
||||
if ! import -quality $quality "$tmp_file.jpg"; then
|
||||
# most likley reason this returns a error, is for fullscreen applications that take full control which does not allowing imagemagick to select the area, use windowed fullscreen or if running wine use a virtual desktop to avoid this.
|
||||
notify-send "Error screenshoting " "most likely unable to find selection"
|
||||
capture_region() {
|
||||
local fmt="$1" quality="$2" output="$3"
|
||||
local geometry
|
||||
geometry=$(slurp)
|
||||
if [[ -z "$geometry" ]]; then
|
||||
notify "Screenshot cancelled" "No region selected"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
curl -s localhost:$ankiConnectPort -X POST -d '{
|
||||
"action": "updateNoteFields",
|
||||
"version": 6,
|
||||
"params": {
|
||||
"note": {
|
||||
"id": '"$newestNoteId"',
|
||||
"fields": {
|
||||
"'$pictureField'": ""
|
||||
},
|
||||
"picture": [{
|
||||
"path": "'"$tmp_file"'.jpg",
|
||||
"filename": "paste-'"$time"'.jpg",
|
||||
"fields": [
|
||||
"'$pictureField'"
|
||||
]
|
||||
}]
|
||||
}
|
||||
}
|
||||
}'
|
||||
|
||||
#remove if you don't want anki to show you the card you just edited
|
||||
curl -s localhost:$ankiConnectPort -X POST -d '{
|
||||
"action": "guiBrowse",
|
||||
"version": 6,
|
||||
"params": {
|
||||
"query": "nid:'"$newestNoteId"'"
|
||||
}
|
||||
}'
|
||||
|
||||
#you can comment this if you do not use notifcations.
|
||||
notify-send "Screenshot Taken" "Added to note"
|
||||
rm "$tmp_file.jpg"
|
||||
if [[ "$fmt" == "jpeg" ]]; then
|
||||
grim -g "$geometry" -t jpeg -q "$quality" "$output"
|
||||
else
|
||||
if ! import -quality $quality "$tmp_file.png"; then
|
||||
notify-send "Error screenshoting " "most likely unable to find selection"
|
||||
grim -g "$geometry" -t png "$output"
|
||||
fi
|
||||
}
|
||||
|
||||
copy_to_clipboard() {
|
||||
local file="$1"
|
||||
if ! wl-copy <"$file"; then
|
||||
notify "Error copying screenshot" "wl-copy failed"
|
||||
exit 1
|
||||
fi
|
||||
# we use pngs when copying to clipboard because they have greater support when pasting.
|
||||
xclip -selection clipboard -target image/png -i "$tmp_file.png"
|
||||
rm "$tmp_file.png"
|
||||
#you can comment this if you do not use notifcations.
|
||||
notify-send "Screenshot Taken" "Copied to clipboard"
|
||||
}
|
||||
|
||||
get_newest_note_id() {
|
||||
local response
|
||||
response=$(curl -sS "$ANKI_URL" -X POST -H 'Content-Type: application/json' \
|
||||
-d '{"action":"findNotes","version":6,"params":{"query":"is:new"}}')
|
||||
jq -r '.result[-1] // empty' <<<"$response"
|
||||
}
|
||||
|
||||
update_note_with_image() {
|
||||
local note_id="$1" image_path="$2" filename="$3"
|
||||
local payload
|
||||
payload=$(jq -n --argjson noteId "$note_id" --arg field "$PICTURE_FIELD" \
|
||||
--arg path "$image_path" --arg filename "$filename" '
|
||||
{action:"updateNoteFields",version:6,
|
||||
params:{note:{id:$noteId,fields:{($field):""},
|
||||
picture:[{path:$path,filename:$filename,fields:[$field]}]}}}')
|
||||
curl -sS "$ANKI_URL" -X POST -H 'Content-Type: application/json' -d "$payload" >/dev/null
|
||||
}
|
||||
|
||||
open_note_in_browser() {
|
||||
local note_id="$1"
|
||||
local payload
|
||||
payload=$(jq -n --argjson noteId "$note_id" '
|
||||
{action:"guiBrowse",version:6,params:{query:("nid:" + ($noteId|tostring))}}')
|
||||
curl -sS "$ANKI_URL" -X POST -H 'Content-Type: application/json' -d "$payload" >/dev/null
|
||||
}
|
||||
|
||||
main() {
|
||||
for cmd in "${REQUIREMENTS[@]}"; do
|
||||
require_cmd "$cmd"
|
||||
done
|
||||
|
||||
mkdir -p "$CACHE_DIR"
|
||||
local timestamp base newest_note image_path
|
||||
timestamp=$(date +%s)
|
||||
base="$CACHE_DIR/$timestamp"
|
||||
|
||||
wiggle_mouse
|
||||
newest_note=$(get_newest_note_id)
|
||||
|
||||
if [[ -n "$newest_note" ]]; then
|
||||
image_path="$base.jpg"
|
||||
capture_region "jpeg" "$QUALITY" "$image_path"
|
||||
update_note_with_image "$newest_note" "$image_path" "paste-$timestamp.jpg"
|
||||
open_note_in_browser "$newest_note"
|
||||
notify -i "$image_path" "Screenshot Taken" "Added to Anki note"
|
||||
rm -f "$image_path"
|
||||
else
|
||||
image_path="$base.png"
|
||||
capture_region "png" "" "$image_path"
|
||||
copy_to_clipboard "$image_path"
|
||||
notify -i "$image_path" "Screenshot Taken" "Copied to clipboard"
|
||||
rm -f "$image_path"
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
Reference in New Issue
Block a user