2022-11-11 11:55:09 +00:00
#!/usr/bin/env bash
set -ueo pipefail
2022-11-15 21:01:29 +00:00
[ " ${ DEBUG :- 0 } " = "1" ] && set -x
2022-11-11 11:55:09 +00:00
# usage:
2022-11-12 11:46:34 +00:00
# - init - create an empty database
2022-11-12 22:01:20 +00:00
# - 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
2022-11-11 11:55:09 +00:00
# - 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
# - tag $FILENAME $TAG - tag $FILENAME with $TAG, $TAG can be repeated
# - listtags $FILENAME - list all tags for $FILENAME
2022-11-15 21:02:42 +00:00
# TODO: when tagging, check if tags exist
# TODO: when tagging, allow more than one tag
# FIXME: adding tags doesn't work
2022-11-15 21:03:38 +00:00
SCRIPT_DIR = $( dirname $( readlink " $0 " ) )
2022-11-16 07:00:00 +00:00
CURRENT_DIR = $( dirname " $PWD " )
SCRIPT_NAME = $( basename " $0 " )
DB_FILE = " ${ CURRENT_DIR } /tags.db "
[ " $1 " = "--db" ] && DB_FILE = " $2 " && shift 2
2022-11-15 21:03:38 +00:00
DB_SCHEMA = " ${ SCRIPT_DIR } /database.sql "
2022-11-12 22:01:20 +00:00
declare -A FILTERS
FILTERS[ video] = "avi|flv|mkv|mov|mp4|mpg|ogv|webm|wmv"
2022-11-11 11:55:09 +00:00
fail( ) {
echo " $1 " >& 2;
exit 1
}
2022-11-12 11:46:34 +00:00
log( ) {
echo " $1 "
}
2022-11-12 22:01:20 +00:00
init( ) {
2022-11-15 21:16:05 +00:00
# DB_NAME
[ -f " $1 " ] && fail " Database file \" $1 \" already exists. Aborting. "
cat " $DB_SCHEMA " | sqlite3 " $1 "
log " Empty database file \" $1 \" created. "
2022-11-12 22:01:20 +00:00
}
enumerate_positional_parameters( ) {
log " Positional parameters in $FUNCNAME : "
CNT = 0
for VALUE in " $@ " ; do
let CNT++ || true
echo " ${ CNT } : $VALUE "
done
}
2022-11-11 11:55:09 +00:00
listtags( ) {
2022-11-12 22:01:20 +00:00
# $FILENAME $LIMIT=ALL
2022-11-11 11:55:09 +00:00
[ -z " $1 " ] && fail "No filename supplied."
FILENAME = " $1 "
2022-11-11 12:20:11 +00:00
shift
LIMIT = " ${ 1 :- 0 } "
ADDITIONAL_QUERY = ""
[ $LIMIT -gt 0 ] && ADDITIONAL_QUERY = " LIMIT $LIMIT "
2022-11-12 22:01:20 +00:00
sqlite_query \
2022-11-11 12:20:11 +00:00
" SELECT filename, label from files \
2022-11-12 22:01:20 +00:00
INNER JOIN tags_ties ON tags_ties.id = files.id \
INNER JOIN tags ON tags.id = tags_ties.id \
2022-11-11 12:20:11 +00:00
WHERE filename = \" $FILENAME \" \
$ADDITIONAL_QUERY "
2022-11-11 11:55:09 +00:00
}
2022-11-12 22:01:20 +00:00
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"
2022-11-12 11:46:34 +00:00
exit 0
2022-11-12 22:01:20 +00:00
}
2022-11-12 11:46:34 +00:00
2022-11-12 22:01:20 +00:00
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
2022-11-15 21:16:05 +00:00
init " ${ 2 :- $DB_FILE } "
2022-11-12 22:01:20 +00:00
exit 0
fi
if [ [ " $1 " = "import" ] ] ; then
2022-11-11 11:55:09 +00:00
shift
2022-11-12 22:01:20 +00:00
add "path" " $@ "
fi
2022-11-11 11:55:09 +00:00
2022-11-12 22:01:20 +00:00
if [ [ " $1 " = "autoimport" ] ] ; then
shift
if [ [ " ${ 1 :- } " = ~ " ${ !FILTERS[@] } " ] ] ; then
add_path_auto " .*( ${ FILTERS [ $1 ] } ) " " $2 "
else
add_path_auto " $1 " " $2 "
fi
fi
2022-11-11 11:55:09 +00:00
2022-11-12 22:01:20 +00:00
if [ [ " $1 " = "add" ] ] ; then
shift
add " $@ "
fi
2022-11-11 11:55:09 +00:00
2022-11-12 22:01:20 +00:00
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
2022-11-11 11:55:09 +00:00
shift
2022-11-12 22:01:20 +00:00
[ -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
2022-11-11 11:55:09 +00:00
2022-11-12 22:01:20 +00:00
if [ [ " $1 " = "listtags" ] ] ; then
listtags " $2 "
exit 0
fi
}
main " $@ "
2022-11-11 11:55:09 +00:00