tagpic (3046B)
1 #!/bin/sh 2 3 # Copyright (c) 2026 Andrew Kloet <andrew@kloet.net> 4 # 5 # Permission to use, copy, modify, and distribute this software for any 6 # purpose with or without fee is hereby granted, provided that the above 7 # copyright notice and this permission notice appear in all copies. 8 # 9 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 17 set -e # errexit 18 19 IMGDIR="${TAGPIC_IMGDIR:-$HOME/imgdir}" 20 21 usage() 22 { 23 echo "Usage: tagpic <command> [args...]" >&2 24 echo "Commands:" >&2 25 echo " i, insert <path/to/file> [tag1 tag2 ...]" >&2 26 echo " d, delete <filename>" >&2 27 echo " m, modify [-a|--append] <filename> [tag1 tag2 ...]" >&2 28 echo " l, lookup <filename>" >&2 29 exit 1 30 } 31 32 assert_file_exists() 33 { 34 [ -f "$1" ] || { echo "${0##*/}: File '$1' not found." >&2; exit 1; } 35 } 36 37 delete_symlinks() 38 { 39 _filename="$1" 40 _meta_dir="$IMGDIR/meta/$_filename" 41 42 if [ -d "$_meta_dir" ]; then 43 for _tag_link in "$_meta_dir"/*; do 44 [ -L "$_tag_link" ] || continue 45 _tag="${_tag_link##*/}" 46 rm -f "$IMGDIR/$_tag/$_filename" 47 done 48 rm -rf "$_meta_dir" 49 fi 50 } 51 52 cmd_insert() 53 { 54 [ "$#" -lt 1 ] && usage 55 56 _filepath="$1" 57 shift 58 59 assert_file_exists "$_filepath" 60 mkdir -p "$IMGDIR/all" 61 62 _ext="${_filepath##*.}" 63 _unixtime=$(date +%s) 64 _filename="${_unixtime}.${_ext}" 65 66 cp "$_filepath" "$IMGDIR/all/$_filename" 67 mkdir -p "$IMGDIR/meta/$_filename" 68 69 for _tag do 70 mkdir -p "$IMGDIR/$_tag" 71 ln -s "../all/$_filename" "$IMGDIR/$_tag/$_filename" 72 ln -s "$IMGDIR/$_tag" "$IMGDIR/meta/$_filename/$_tag" 73 done 74 } 75 76 cmd_delete() 77 { 78 [ "$#" -ne 1 ] && usage 79 _filename="$1" 80 81 assert_file_exists "$IMGDIR/all/$_filename" 82 83 delete_symlinks "$_filename" 84 rm -f "$IMGDIR/all/$_filename" 85 } 86 87 cmd_modify() 88 { 89 _append=0 90 if [ "$1" = "-a" ] || [ "$1" = "--append" ]; then 91 _append=1 92 shift 93 fi 94 95 [ "$#" -lt 1 ] && usage 96 97 _filename="$1" 98 shift 99 100 assert_file_exists "$IMGDIR/all/$_filename" 101 102 [ "$_append" -eq 0 ] && delete_symlinks "$_filename" 103 mkdir -p "$IMGDIR/meta/$_filename" 104 105 for _tag do 106 mkdir -p "$IMGDIR/$_tag" 107 ln -s "../all/$_filename" "$IMGDIR/$_tag/$_filename" 108 ln -s "$IMGDIR/$_tag" "$IMGDIR/meta/$_filename/$_tag" 109 done 110 } 111 112 cmd_lookup() 113 { 114 [ "$#" -ne 1 ] && usage 115 _filename="$1" 116 117 assert_file_exists "$IMGDIR/all/$_filename" 118 119 _meta_dir="$IMGDIR/meta/$_filename" 120 if [ -d "$_meta_dir" ]; then 121 for _tag_link in "$_meta_dir"/*; do 122 [ -L "$_tag_link" ] || continue 123 printf '%s\n' "${_tag_link##*/}" 124 done 125 fi 126 } 127 128 case "$1" in 129 i|insert) shift; cmd_insert "$@" ;; 130 d|delete) shift; cmd_delete "$@" ;; 131 m|modify) shift; cmd_modify "$@" ;; 132 l|lookup) shift; cmd_lookup "$@" ;; 133 *) usage ;; 134 esac