metadata scripts
album from folder: create album from foldername read: read and display author, album, grouping of every folder remove author before title: remove "name - " when matching author
This commit is contained in:
1 parent
408566b6ea
commit
7c2e0db615
11 files changed
+114
-18
No files matched your search
+32
@@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
cd $1
|
||||||
|
for d in */; do
|
||||||
|
album="${d%/}"
|
||||||
|
|
||||||
|
# Remove leading numbering: "001 - "
|
||||||
|
album=$(echo "$album" | sed -E 's/^[0-9]+[[:space:]]*-[[:space:]]*//')
|
||||||
|
album=$(echo "$album" | sed -E 's/^\([^)]*\)[[:space:]]*//; s/[[:space:]]*\([^)]*\)$//')
|
||||||
|
# Remove all (...) groups
|
||||||
|
album=$(echo "$album" | sed -E 's/$$[^)]*$$//g')
|
||||||
|
|
||||||
|
# Remove all [...] groups
|
||||||
|
album=$(echo "$album" | sed -E 's/$$[^]]*$$//g')
|
||||||
|
|
||||||
|
# Remove standalone years
|
||||||
|
album=$(echo "$album" | sed -E 's/[[:space:]]+[12][0-9]{3}//g')
|
||||||
|
|
||||||
|
# Collapse multiple spaces and trim
|
||||||
|
album=$(echo "$album" | sed -E 's/[[:space:]]+/ /g; s/^ //; s/ $//')
|
||||||
|
|
||||||
|
echo "Setting album: $album"
|
||||||
|
|
||||||
|
cd "$d" || continue
|
||||||
|
|
||||||
|
for x in *; do
|
||||||
|
[ -f "$x" ] || continue
|
||||||
|
kid3-cli -c "set album \"$album\"" -c save "$x"
|
||||||
|
done
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
done
|
||||||
|
|
||||||
@@ -18,12 +18,13 @@ for d in */; do
|
|||||||
else
|
else
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
echo $d $num
|
echo Folder: $d, Number: $num
|
||||||
/home/lucas/scripts/.venv/bin/python \
|
/home/lucas/scripts/.venv/bin/python \
|
||||||
/home/lucas/scripts/ffmpeg_handling.py \
|
/home/lucas/scripts/ffmpeg_handling.py \
|
||||||
ms "$name" \
|
ms "$name" \
|
||||||
--override \
|
--override \
|
||||||
-k grouping \
|
-k grouping \
|
||||||
-v "$series #$num" \
|
-v "$series #$num" \
|
||||||
"$@"
|
"$@" > /home/lucas/metadata_set.log
|
||||||
|
# --kidflag \
|
||||||
done
|
done
|
||||||
Regular → Executable
File mode changed.
Regular → Executable
+6
-6
@@ -55,7 +55,7 @@ def get_tag(path, tag):
|
|||||||
|
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def tag_file(path: Path, rank: int, year: str, dry_run: bool, replace_pattern: str=r"Top 100 SciFi Books" )
|
def tag_file(path: Path, rank: int, year: str, dry_run: bool, replace_pattern: str=r"Top 100 SciFi Books" ):
|
||||||
work = get_tag(path, "work")
|
work = get_tag(path, "work")
|
||||||
grouping = get_tag(path, "grouping")
|
grouping = get_tag(path, "grouping")
|
||||||
existing_year = get_tag(path, "year")
|
existing_year = get_tag(path, "year")
|
||||||
@@ -69,26 +69,26 @@ def tag_file(path: Path, rank: int, year: str, dry_run: bool, replace_pattern: s
|
|||||||
else:
|
else:
|
||||||
tag = "grouping"
|
tag = "grouping"
|
||||||
existing = ""
|
existing = ""
|
||||||
pattern = f"{replace_pattern} #\d+(?:\.\d+)?"
|
pattern = rf"{replace_pattern} #\d+(?:\.\d+)?"
|
||||||
|
|
||||||
if existing:
|
if existing:
|
||||||
if re.search(pattern, existing):
|
if re.search(pattern, existing):
|
||||||
new_group = re.sub(
|
new_group = re.sub(
|
||||||
pattern,
|
pattern,
|
||||||
f"{replace} #{rank};",
|
f"{replace_pattern} #{rank};",
|
||||||
existing,
|
existing,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
new_group = f"{existing}; {replace} #{rank};"
|
new_group = f"{existing}; {replace_pattern} #{rank};"
|
||||||
else:
|
else:
|
||||||
new_group = f"{replace} #{rank};"
|
new_group = f"{replace_pattern} #{rank};"
|
||||||
|
|
||||||
new_group = re.sub(r";+", ";", new_group)
|
new_group = re.sub(r";+", ";", new_group)
|
||||||
# Skip if nothing changes
|
# Skip if nothing changes
|
||||||
if existing == new_group and existing_year == str(year):
|
if existing == new_group and existing_year == str(year):
|
||||||
print("Skipping (already tagged)")
|
print("Skipping (already tagged)")
|
||||||
return "skip"
|
return "skip"
|
||||||
print(f"Would tag {path.name}: {new_group} {year}")
|
print(f"New tag {path.name}: {new_group}, Year: {year}")
|
||||||
|
|
||||||
if dry_run:
|
if dry_run:
|
||||||
return
|
return
|
||||||
|
|||||||
Executable
+27
@@ -0,0 +1,27 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
ROOT="${1:-.}"
|
||||||
|
|
||||||
|
find "$ROOT" -type d | while read -r dir; do
|
||||||
|
first_file=$(
|
||||||
|
find "$dir" -maxdepth 1 -type f \
|
||||||
|
\( -iname "*.m4b" -o -iname "*.m4a" -o -iname "*.mp3" \
|
||||||
|
-o -iname "*.flac" -o -iname "*.ogg" \) |
|
||||||
|
sort |
|
||||||
|
head -n1
|
||||||
|
)
|
||||||
|
|
||||||
|
[[ -z "$first_file" ]] && continue
|
||||||
|
|
||||||
|
artist=$(kid3-cli -c "get artist" "$first_file" 2>/dev/null)
|
||||||
|
album=$(kid3-cli -c "get album" "$first_file" 2>/dev/null)
|
||||||
|
composer=$(kid3-cli -c "get composer" "$first_file" 2>/dev/null)
|
||||||
|
comment=$(kid3-cli -c "get comment" "$first_file" 2>/dev/null)
|
||||||
|
echo "====≠==============================="
|
||||||
|
echo "Folder: $(basename "$dir")"
|
||||||
|
echo "Album: $album"
|
||||||
|
echo "Artist: $artist"
|
||||||
|
echo "Narrator: $composer"
|
||||||
|
echo "Comment: $comment"
|
||||||
|
done
|
||||||
|
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
WORKDIR="${1:-.}"
|
||||||
|
|
||||||
|
cd "$WORKDIR"
|
||||||
|
|
||||||
|
# Use $2 if provided, otherwise use current directory name
|
||||||
|
AUTHOR="${2:-$(basename "$PWD")}"
|
||||||
|
|
||||||
|
for d in "$AUTHOR - "*; do
|
||||||
|
[[ -d "$d" ]] || continue
|
||||||
|
|
||||||
|
new_name="${d#"$AUTHOR - "}"
|
||||||
|
|
||||||
|
echo "Renaming: $d -> $new_name"
|
||||||
|
mv -- "$d" "$new_name"
|
||||||
|
done
|
||||||
|
|
||||||
Regular → Executable
+4
-1
@@ -41,8 +41,11 @@ for file in "${FILES[@]}"; do
|
|||||||
[[ -z "$genre" ]] && continue
|
[[ -z "$genre" ]] && continue
|
||||||
cleaned=$(printf '%s\n' "$genre" | sed -E '
|
cleaned=$(printf '%s\n' "$genre" | sed -E '
|
||||||
s/[Aa]udio[[:space:]]*[Bb]ooks?//g
|
s/[Aa]udio[[:space:]]*[Bb]ooks?//g
|
||||||
s/\b(Hörbücher?|Hoerbücher?|Hoerbuecher?|Hörspiele?|Hoerspiele?)\b//Ig
|
s/\b(Hörb(uch|ücher)|Hoerb(uch|uecher)|Hörspiel(e)?|Hoerspiel(e)?)\b//Ig
|
||||||
|
|
||||||
|
s/[Gg]esprochene[[:space:]]*[Ii]nhalte//g
|
||||||
|
s/[Ss]poken[[:space:]]*[Ww]ord//g
|
||||||
|
s/[Ss]peech//g
|
||||||
# Normalize genre names
|
# Normalize genre names
|
||||||
s/\b(Sci[ -]?Fi|Science Fiction|SF)\b/SciFi/Ig
|
s/\b(Sci[ -]?Fi|Science Fiction|SF)\b/SciFi/Ig
|
||||||
s/\bnonfiction\b/NonFiction/Ig
|
s/\bnonfiction\b/NonFiction/Ig
|
||||||
|
|||||||
Regular → Executable
File mode changed.
@@ -15,13 +15,12 @@ while IFS= read -r -d '' f; do
|
|||||||
-show_entries format_tags=description \
|
-show_entries format_tags=description \
|
||||||
-of default=nw=1:nk=1 \
|
-of default=nw=1:nk=1 \
|
||||||
-- "$f")
|
-- "$f")
|
||||||
|
|
||||||
# trim comment
|
# trim comment
|
||||||
comment="${comment#"${comment%%[![:space:]]*}"}"
|
comment="${comment#"${comment%%[![:space:]]*}"}"
|
||||||
comment="${comment%"${comment##*[![:space:]]}"}"
|
comment="${comment%"${comment##*[![:space:]]}"}"
|
||||||
|
|
||||||
# ---- DELETE MODE ----
|
# ---- DELETE MODE ----
|
||||||
if [[ "$mode" == "del" && -n "$comment" && ${#comment} -lt $THRESHOLD ]]; then
|
if [[ "$mode" == "--delete" && -n "$comment" && ${#comment} -lt $THRESHOLD ]]; then
|
||||||
tmp=$(mktemp -p "$(dirname -- "$f")" ".fftmp.XXXXXX.${f##*.}") || continue
|
tmp=$(mktemp -p "$(dirname -- "$f")" ".fftmp.XXXXXX.${f##*.}") || continue
|
||||||
|
|
||||||
echo "Removing short comment: $f"
|
echo "Removing short comment: $f"
|
||||||
|
|||||||
@@ -1,19 +1,33 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
root="${1:-.}"
|
LIBRARY="${1:-.}"
|
||||||
find "$root" \( -iname '*.mp3' -o -iname '*.m4a' -o -iname '*.m4b' \) -print0 |
|
mapfile -t FILES < <(
|
||||||
while IFS= read -r -d '' f; do
|
find "$LIBRARY" -type f \( \
|
||||||
|
-iname "*.mp3" -o \
|
||||||
|
-iname "*.m4b" -o \
|
||||||
|
-iname "*.m4a" \
|
||||||
|
\)
|
||||||
|
)
|
||||||
|
TOTAL=${#FILES[@]}
|
||||||
|
PROCESSED=0
|
||||||
|
for f in "${FILES[@]}"; do
|
||||||
|
((PROCESSED++))
|
||||||
|
if (( PROCESSED % 100 == 0 )); then
|
||||||
|
echo "Progress: $PROCESSED/$TOTAL files processed"
|
||||||
|
fi
|
||||||
|
|
||||||
comment=$(ffprobe -v error \
|
comment=$(ffprobe -v error \
|
||||||
-show_entries format_tags=comment \
|
-show_entries format_tags=comment \
|
||||||
-of default=nw=1:nk=1 \
|
-of default=nw=1:nk=1 \
|
||||||
-- "$f")
|
-- "$f")
|
||||||
|
shopt -s nocasematch
|
||||||
|
|
||||||
[[ $comment =~ ^[Rr]ead[[:space:]]+[Bb]y[[:space:]]+(.+) ]] || continue
|
[[ $comment =~ (read[[:space:]]+by|spoken[[:space:]]+by|narrated[[:space:]]+by|gesprochen[[:space:]]+von|gelesen[[:space:]]+von)[[:space:]]+([^.$'\n']*) ]] || continue
|
||||||
|
|
||||||
composer="${BASH_REMATCH[1]}"
|
composer="${BASH_REMATCH[2]}"
|
||||||
echo "Updating: $f"
|
composer="${composer%"${composer##*[!.,[:space:]]}"}"
|
||||||
echo " Composer: $composer"
|
printf '[%d/%d] [%s] %s | OLD="%s" | NEW="%s
|
||||||
|
"\n' "$PROCESSED" "$TOTAL" "Update" "$f" "$comment" "$composer"
|
||||||
|
|
||||||
dir=$(dirname -- "$f")
|
dir=$(dirname -- "$f")
|
||||||
base=$(basename -- "$f")
|
base=$(basename -- "$f")
|
||||||
|
|||||||
Regular → Executable
File mode changed.
Reference in new issue
Block a user