Compare commits

..

3 Commits

Author SHA1 Message Date
Lukáš Kucharczyk 82351fb5d9
.gitignore: add .mp4 2022-11-12 23:04:11 +01:00
Lukáš Kucharczyk e6e13c10b0
Add new features
New command-line options: import, autoimport, init
Improve adding of tags and files
2022-11-12 23:01:20 +01:00
Lukáš Kucharczyk c71d3af0a2
SQL: standardize id names 2022-11-12 22:59:44 +01:00
3 changed files with 153 additions and 69 deletions

3
.gitignore vendored
View File

@ -1 +1,2 @@
*.db
*.db
*.mp4

View File

@ -1,27 +1,27 @@
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "tags" (
"tid" INTEGER,
"id" INTEGER,
"label" text,
PRIMARY KEY("tid" AUTOINCREMENT)
PRIMARY KEY("id" AUTOINCREMENT)
);
CREATE TABLE IF NOT EXISTS "files" (
"fid" INTEGER,
"id" INTEGER,
"filename" text,
PRIMARY KEY("fid" AUTOINCREMENT)
PRIMARY KEY("id" AUTOINCREMENT)
);
CREATE TABLE IF NOT EXISTS "tags_ties" (
"id" INTEGER,
"tid" INTEGER,
"fid" INTEGER,
PRIMARY KEY("id" AUTOINCREMENT),
FOREIGN KEY("tid") REFERENCES "tags_ties"("tid"),
FOREIGN KEY("fid") REFERENCES "files"("fid")
FOREIGN KEY("tid") REFERENCES "tags"("id"),
FOREIGN KEY("fid") REFERENCES "files"("id")
);
CREATE TABLE IF NOT EXISTS "hashes" (
"id" INTEGER,
"md5" text,
"fid" int,
PRIMARY KEY("id" AUTOINCREMENT),
FOREIGN KEY("fid") REFERENCES "files"("fid")
FOREIGN KEY("fid") REFERENCES "files"("id")
);
COMMIT;

205
tag.sh
View File

@ -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 "$@"