~kris/dots

srice

ref: e9b48d06a8541f3eda5c4db90382ab3c77183afb srice/.local/bin/dmenu/dedit -rwxr-xr-x 5.2 KiB
e9b48d06 — Kris Yotam xprofile: systemd-aware pipewire start + blueman-applet; sb-internet: tolerate missing /proc/net/wireless 2 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/usr/bin/env bash
set -euo pipefail

###############################################################################
# DEDIT — dmenu metadata editor for krisyotam.com
#
# Maintainer:   Kris Yotam <krisyotam@pm.me>
# License:      MIT
# Created:      2026-02-15
# Description:  Edit content metadata via dmenu. Select type, entry, field,
#               and new value through dmenu prompts.
###############################################################################

DB="/home/krisyotam/dev/krisyotam.com/public/data/content.db"

declare -A TYPE_ICONS=(
    [blog]="󰬞" [diary]="󰃮" [essays]="󰬝" [fiction]="󰂺"
    [news]="󰎕" [notes]="󰏪" [ocs]="󰏫" [papers]="󰈙"
    [progymnasmata]="󰑴" [reviews]="󰓥" [verse]="󱗝"
)

CONTENT_TYPES=(blog diary essays fiction news notes ocs papers progymnasmata reviews verse)

sql() { sqlite3 "$DB" "$1"; }

notify() { notify-send "dedit" "$1" 2>/dev/null || true; }

# Select content type
select_type() {
    local entries=""
    for t in "${CONTENT_TYPES[@]}"; do
        entries+="${TYPE_ICONS[$t]:-󰈙}  $t"$'\n'
    done
    echo "$entries" | dmenu -i -l 11 -p "edit:" | awk '{print $2}'
}

# Select entry from type
select_entry() {
    local type="$1"
    sql "SELECT title || '  [' || slug || ']' FROM $type ORDER BY title" |
        dmenu -i -l 20 -p "$type:" |
        sed 's/.*\[\(.*\)\]/\1/'
}

# Select field to edit
select_field() {
    local type="$1"
    local fields="title
preview
category_slug
tags
state"

    if [[ "$type" != "diary" ]]; then
        fields+="
status
confidence
importance"
    fi

    echo "$fields" | dmenu -i -l 10 -p "field:"
}

# Edit a field
edit_field() {
    local type="$1" slug="$2" field="$3"
    local current new_value

    case "$field" in
        title|preview)
            current="$(sql "SELECT $field FROM $type WHERE slug='$slug'")"
            new_value="$(echo "$current" | dmenu -p "$field:")"
            [[ -z "$new_value" ]] && return
            new_value="${new_value//\'/\'\'}"
            sql "UPDATE $type SET $field='$new_value', updated_at=datetime('now') WHERE slug='$slug'"
            notify "Updated $field"
            ;;
        category_slug)
            new_value="$(sql "SELECT slug FROM categories ORDER BY slug" | dmenu -i -l 15 -p "category:")"
            [[ -z "$new_value" ]] && return
            sql "UPDATE $type SET category_slug='$new_value', updated_at=datetime('now') WHERE slug='$slug'"
            notify "Category: $new_value"
            ;;
        tags)
            local id
            id="$(sql "SELECT id FROM $type WHERE slug='$slug'")"
            local action
            action="$(printf "add\nremove" | dmenu -i -p "tags:")"
            [[ -z "$action" ]] && return

            if [[ "$action" == "add" ]]; then
                local tag
                tag="$(sql "SELECT slug FROM tags ORDER BY slug" | dmenu -i -l 20 -p "add tag:")"
                [[ -z "$tag" ]] && return
                local tag_id
                tag_id="$(sql "SELECT id FROM tags WHERE slug='$tag'")"
                [[ -z "$tag_id" ]] && return
                sql "INSERT OR IGNORE INTO content_tags (content_type, content_id, tag_id) VALUES ('$type', $id, $tag_id)"
                notify "Added tag: $tag"
            else
                local tag
                tag="$(sql "SELECT t.slug FROM tags t JOIN content_tags ct ON ct.tag_id=t.id WHERE ct.content_type='$type' AND ct.content_id=$id ORDER BY t.slug" | dmenu -i -l 10 -p "remove:")"
                [[ -z "$tag" ]] && return
                sql "DELETE FROM content_tags WHERE content_type='$type' AND content_id=$id AND tag_id=(SELECT id FROM tags WHERE slug='$tag')"
                notify "Removed tag: $tag"
            fi
            ;;
        status)
            new_value="$(printf "Notes\nDraft\nIn Progress\nFinished\nAbandoned" | dmenu -i -l 5 -p "status:")"
            [[ -z "$new_value" ]] && return
            sql "UPDATE $type SET status='$new_value', updated_at=datetime('now') WHERE slug='$slug'"
            notify "Status: $new_value"
            ;;
        confidence)
            new_value="$(printf "certain\nhighly likely\nlikely\npossible\nunlikely\nhighly unlikely\nremote\nimpossible" | dmenu -i -l 8 -p "confidence:")"
            [[ -z "$new_value" ]] && return
            sql "UPDATE $type SET confidence='$new_value', updated_at=datetime('now') WHERE slug='$slug'"
            notify "Confidence: $new_value"
            ;;
        importance)
            new_value="$(seq 1 10 | dmenu -i -l 10 -p "importance:")"
            [[ -z "$new_value" ]] && return
            sql "UPDATE $type SET importance=$new_value, updated_at=datetime('now') WHERE slug='$slug'"
            notify "Importance: $new_value"
            ;;
        state)
            new_value="$(printf "active\nhidden" | dmenu -i -l 2 -p "state:")"
            [[ -z "$new_value" ]] && return
            sql "UPDATE $type SET state='$new_value', updated_at=datetime('now') WHERE slug='$slug'"
            notify "State: $new_value"
            ;;
    esac
}

# Main loop — keep editing until user cancels
type="$(select_type)"
[[ -z "$type" ]] && exit 0

slug="$(select_entry "$type")"
[[ -z "$slug" ]] && exit 0

while true; do
    field="$(select_field "$type")"
    [[ -z "$field" ]] && break
    edit_field "$type" "$slug" "$field"
done