194 lines
4.8 KiB
Bash
Executable File
194 lines
4.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -ueo pipefail
|
|
[ "${DEBUG:-0}" = "1" ] && set -x
|
|
# 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
|
|
# - tag $FILENAME $TAG - tag $FILENAME with $TAG, $TAG can be repeated
|
|
# - listtags $FILENAME - list all tags for $FILENAME
|
|
|
|
# TODO: when tagging, check if tags exist
|
|
# TODO: when tagging, allow more than one tag
|
|
# FIXME: adding tags doesn't work
|
|
|
|
DB_FILE="tags.db"
|
|
DB_SCHEMA="database.sql"
|
|
declare -A FILTERS
|
|
FILTERS[video]="avi|flv|mkv|mov|mp4|mpg|ogv|webm|wmv"
|
|
|
|
[ "${DEBUG:-0}" = "1" ] && set -x
|
|
|
|
fail() {
|
|
echo "$1" >&2;
|
|
exit 1
|
|
}
|
|
|
|
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=ALL
|
|
[ -z "$1" ] && fail "No filename supplied."
|
|
FILENAME="$1"
|
|
shift
|
|
LIMIT="${1:-0}"
|
|
|
|
ADDITIONAL_QUERY=""
|
|
[ $LIMIT -gt 0 ] && ADDITIONAL_QUERY="LIMIT $LIMIT"
|
|
|
|
sqlite_query \
|
|
"SELECT filename, label from files \
|
|
INNER JOIN tags_ties ON tags_ties.id = files.id \
|
|
INNER JOIN tags ON tags.id = tags_ties.id \
|
|
WHERE filename = \"$FILENAME\"\
|
|
$ADDITIONAL_QUERY"
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
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
|
|
add "path" "$@"
|
|
fi
|
|
|
|
if [[ "$1" = "autoimport" ]]; then
|
|
shift
|
|
if [[ "${1:-}" =~ "${!FILTERS[@]}" ]]; then
|
|
add_path_auto ".*(${FILTERS[$1]})" "$2"
|
|
else
|
|
add_path_auto "$1" "$2"
|
|
fi
|
|
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 "$@"
|
|
|
|
|
|
|