From e6e13c10b0f0b761e4f5e1dffcd0abcd6facc6e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Kucharczyk?= Date: Sat, 12 Nov 2022 23:01:20 +0100 Subject: [PATCH] Add new features New command-line options: import, autoimport, init Improve adding of tags and files --- tag.sh | 205 ++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 144 insertions(+), 61 deletions(-) diff --git a/tag.sh b/tag.sh index 36770f0..bccb51f 100755 --- a/tag.sh +++ b/tag.sh @@ -2,6 +2,10 @@ set -ueo pipefail # usage: # - init - create an empty database +# - import - import $FILE or import $DIR, both can be multiple values +# - autoimport ($REGEX|video) $FOLDER - will import all files in $FOLDER with a $REGEX filter, +# or one of the preset filters: +# - video # - add (tag|filename) $VALUE - adds a new tag or filename of $VALUE # - list (tags|files) - lists all the values in a table # - bytag $TAG - list all files by tag label @@ -10,6 +14,11 @@ set -ueo pipefail DB_FILE="tags.db" DB_SCHEMA="database.sql" +declare -A FILTERS +FILTERS[video]="avi|flv|mkv|mov|mp4|mpg|ogv|webm|wmv" +# LIST_RECURSIVE_FILES_CMD="find ${FOLDER} -type f -regextype posix-extended -iregex \"${REGEX}\"" + +[ "${DEBUG:-0}" = "1" ] && set -x fail() { echo "$1" >&2; @@ -20,8 +29,23 @@ log() { echo "$1" } +init() { + [ -f "$DB_FILE" ] && fail "Database file \"$DB_FILE\" already exists. Aborting." + cat "$DB_SCHEMA" | sqlite3 "$DB_FILE" + log "Empty database file \"$DB_FILE\" created." +} + +enumerate_positional_parameters() { + log "Positional parameters in $FUNCNAME:" + CNT=0 + for VALUE in "$@"; do + let CNT++ || true + echo "${CNT}: $VALUE" + done +} + listtags() { - # $FILENAME $LIMIT + # $FILENAME $LIMIT=ALL [ -z "$1" ] && fail "No filename supplied." FILENAME="$1" shift @@ -30,77 +54,136 @@ listtags() { ADDITIONAL_QUERY="" [ $LIMIT -gt 0 ] && ADDITIONAL_QUERY="LIMIT $LIMIT" - sqlite3 -table "$DB_FILE" \ + sqlite_query \ "SELECT filename, label from files \ - INNER JOIN tags_ties ON tags_ties.fid = files.fid \ - INNER JOIN tags ON tags.tid = tags_ties.tid \ + INNER JOIN tags_ties ON tags_ties.id = files.id \ + INNER JOIN tags ON tags.id = tags_ties.id \ WHERE filename = \"$FILENAME\"\ $ADDITIONAL_QUERY" } -if [[ "$1" = "init" ]]; then - [ -f "$DB_FILE" ] && fail "Database file \"$DB_FILE\" already exists. Aborting." - cat "$DB_SCHEMA" | sqlite3 "$DB_FILE" - log "Empty database file \"$DB_FILE\" created." +add() { + # $TYPE(tag|path|hash) $VALUE1..$VALUEN + [ "$1" = "tag" ] && shift && add_tag "$@" && exit 0 + [ "$1" = "path" ] && shift && add_path "$@" && exit 0 + [ "$1" = "hash" ] && fail "Adding hashes is not implemented yet." && TABLE="hashes" && COLUMN="md5,filename" exit 0 -fi +} -if [[ "$1" = "add" ]]; then - shift - [ "$1" = "tag" ] && TABLE="tags" && COLUMN="label" - [ "$1" = "file" ] && TABLE="files" && COLUMN="filename" - # TODO: refactor the add function to allow adding hashes - # [ "$1" = "hash" ] && TABLE="hashes" && COLUMN="md5,filename" - shift - [ -z "$1" ] && fail "No value supplied." - COUNTER=0 - while true; do - NEW_TAG="$1" +sqlite_query() { + # $QUERY + sqlite3 -table "$DB_FILE" "$1" +} + +sqlite_lastrows() { + # $TABLE $LIMIT + sqlite_query "SELECT * FROM \"$1\" ORDER BY id DESC LIMIT ${2}" +} + +sqlite_insert() { + # $TABLE $COLUMN $VALUES + # $VALUES can be comma-delimited + [ -z "$1" ] && fail "No table specified." + TABLE="$1" + [ -z "$2" ] && fail "No column(s) supplied." + COLUMN="$2" + [ -z "$3" ] && fail "No column values supplied." + shift 2 + VALUES="(\"$1\")" + if [[ ! -z "${2:-}" ]]; then + while true; do + shift + [ -z "${1:-}" ] && break + VALUES+=",(\"$1\")" + done + fi + QUERY="INSERT INTO $TABLE ($COLUMN) VALUES ${VALUES} RETURNING *;" + sqlite_query "$QUERY" +} + +add_tag() { + # $TAG1...$TAGN + TABLE="tags" + COLUMN="label" + sqlite_insert "$TABLE" "$COLUMN" "$@" +} + +add_path() { + # $PATH1..$PATHN + TABLE="files" + COLUMN="filename" + sqlite_insert "$TABLE" "$COLUMN" "$@" +} + +add_path_auto() { + # $REGEX $FOLDER + find "${2}" -type f -regextype posix-extended -iregex "$1" -exec "$0" import "{}" + +} + +main() { + if [[ "$1" = "init" ]]; then + init + exit 0 + fi + + if [[ "$1" = "import" ]]; then shift - sqlite3 -table "$DB_FILE" "INSERT INTO $TABLE ($COLUMN) VALUES (\"${NEW_TAG}\")" - COUNTER=$((COUNTER++)) - [ -z "${1:-}" ] && break - done - sqlite3 -table "$DB_FILE" "SELECT * FROM \"$TABLE\" LIMIT $COUNTER" - exit 0 -fi + add "path" "$@" + fi -if [[ "$1" = "list" ]]; then - [ -z "$2" ] && fail "No table supplied." - TABLE_NAME="$2" - sqlite3 -table "$DB_FILE" "SELECT * FROM \"${TABLE_NAME}\"" - exit 0 -fi - -if [[ "$1" = "bytag" ]]; then - [ -z "$2" ] && fail "No tag supplied." - TAG_NAME="$2" - sqlite3 -table "$DB_FILE" "SELECT filename FROM files WHERE fid = (SELECT fid FROM tags_ties WHERE tid = (SELECT tid FROM tags WHERE label = \"${TAG_NAME}\"))" - exit 0 -fi - -if [[ "$1" = "tag" ]]; then - shift - [ -z "$1" ] && fail "No filename supplied." - FILENAME="$1" - shift - [ -z "$1" ] && fail "No tag supplied." - COUNTER=0 - while true; do - LABEL="$1" + if [[ "$1" = "autoimport" ]]; then shift - sqlite3 -table "$DB_FILE" "INSERT INTO tags_ties (fid, tid) VALUES ((SELECT fid FROM files WHERE filename = \"$FILENAME\"),(SELECT tid FROM tags WHERE label = \"$LABEL\"))" - COUNTER=$((COUNTER++)) - [ -z "${1:-}" ] && break - done - listtags "$FILENAME" "$COUNTER" - exit 0 -fi + if [[ "${1:-}" =~ "${!FILTERS[@]}" ]]; then + add_path_auto ".*(${FILTERS[$1]})" "$2" + else + add_path_auto "$1" "$2" + fi + fi -if [[ "$1" = "listtags" ]]; then - listtags "$2" - exit 0 -fi + if [[ "$1" = "add" ]]; then + shift + add "$@" + fi + + if [[ "$1" = "list" ]]; then + [ -z "$2" ] && fail "No table supplied." + TABLE_NAME="$2" + sqlite3 -table "$DB_FILE" "SELECT * FROM \"${TABLE_NAME}\"" + exit 0 + fi + + if [[ "$1" = "bytag" ]]; then + [ -z "$2" ] && fail "No tag supplied." + TAG_NAME="$2" + sqlite3 -table "$DB_FILE" "SELECT filename FROM files WHERE id = (SELECT id FROM tags_ties WHERE id = (SELECT id FROM tags WHERE label = \"${TAG_NAME}\"))" + exit 0 + fi + + if [[ "$1" = "tag" ]]; then + shift + [ -z "$1" ] && fail "No filename supplied." + FILENAME="$1" + shift + [ -z "$1" ] && fail "No tag supplied." + COUNTER=0 + while true; do + LABEL="$1" + shift + sqlite3 -table "$DB_FILE" "INSERT INTO tags_ties (id, id) VALUES ((SELECT id FROM files WHERE filename = \"$FILENAME\"),(SELECT id FROM tags WHERE label = \"$LABEL\"))" + COUNTER=$((COUNTER++)) + [ -z "${1:-}" ] && break + done + listtags "$FILENAME" "$COUNTER" + exit 0 + fi + + if [[ "$1" = "listtags" ]]; then + listtags "$2" + exit 0 + fi +} + +main "$@"