diff --git a/modules/yt-dlp.nix b/modules/yt-dlp.nix
index d013955..125673d 100644
--- a/modules/yt-dlp.nix
+++ b/modules/yt-dlp.nix
@@ -117,6 +117,92 @@ in
return 1
}
+ # Generate Jellyfin-compatible NFO files from yt-dlp metadata
+ _generate_jellyfin_nfo() {
+ local filepath="$1"
+ [[ -z "$filepath" ]] && return 1
+
+ local dir=$(dirname "$filepath")
+ local basename=$(basename "$filepath")
+ local name_noext="''${basename%.*}"
+ local season_dir="$dir"
+ local series_dir=$(dirname "$season_dir")
+ local json_file="$dir/$name_noext.info.json"
+
+ [[ ! -f "$json_file" ]] && return 1
+
+ local title=$(jq -r '.title // "Unknown"' "$json_file")
+ local description=$(jq -r '.description // ""' "$json_file" | head -c 2000)
+ local upload_date=$(jq -r '.upload_date // ""' "$json_file")
+ local uploader=$(jq -r '.uploader // "Unknown"' "$json_file")
+
+ local season_num=""
+ local episode_num=""
+ local aired_date=""
+ if [[ ''${#upload_date} -eq 8 ]]; then
+ season_num="''${upload_date:0:4}"
+ episode_num="''${upload_date:4:4}"
+ aired_date="''${upload_date:0:4}-''${upload_date:4:2}-''${upload_date:6:2}"
+ fi
+
+ description=$(echo "$description" | sed 's/&/\&/g; s/\</g; s/>/\>/g')
+ title=$(echo "$title" | sed 's/&/\&/g; s/\</g; s/>/\>/g')
+ uploader=$(echo "$uploader" | sed 's/&/\&/g; s/\</g; s/>/\>/g')
+
+ local nfo_file="$dir/$name_noext.nfo"
+ cat > "$nfo_file" << EPISODENFO
+
+
+ $title
+ $season_num
+ $episode_num
+ ''${aired_date:-}
+ $description
+
+EPISODENFO
+
+ if [[ ! -f "$series_dir/tvshow.nfo" ]]; then
+ cat > "$series_dir/tvshow.nfo" << TVSHOWNFO
+
+
+ $uploader
+ Videos from $uploader
+
+TVSHOWNFO
+ fi
+
+ if [[ ! -f "$season_dir/season.nfo" ]] && [[ -n "$season_num" ]]; then
+ cat > "$season_dir/season.nfo" << SEASONNFO
+
+
+ Season $season_num
+ $season_num
+
+SEASONNFO
+ fi
+
+ local thumb_file=""
+ for ext in jpg webp png; do
+ if [[ -f "$dir/$name_noext.$ext" ]]; then
+ thumb_file="$dir/$name_noext.$ext"
+ break
+ fi
+ done
+
+ if [[ -n "$thumb_file" ]]; then
+ local thumb_ext="''${thumb_file##*.}"
+ mv "$thumb_file" "$dir/$name_noext-thumb.$thumb_ext" 2>/dev/null
+
+ if [[ ! -f "$series_dir/poster.jpg" ]] && [[ ! -f "$series_dir/poster.webp" ]] && [[ ! -f "$series_dir/poster.png" ]]; then
+ cp "$dir/$name_noext-thumb.$thumb_ext" "$series_dir/poster.$thumb_ext"
+ fi
+
+ if [[ ! -f "$season_dir/poster.jpg" ]] && [[ ! -f "$season_dir/poster.webp" ]] && [[ ! -f "$season_dir/poster.png" ]]; then
+ cp "$dir/$name_noext-thumb.$thumb_ext" "$season_dir/poster.$thumb_ext"
+ fi
+ fi
+ }
+
# Unified video download function
dlv() {
local platform=""
@@ -249,12 +335,12 @@ in
match_filter="--match-filter \"$combined_filter\""
fi
- # Build output template based on playlist mode
+ # Build output template based on playlist mode (Jellyfin TV show format)
local output_template
if [[ "$playlist_mode" == true ]]; then
- output_template="$DOWNLOAD_DIR/$platform_name/%(uploader|)s-%(playlist|)s/%(upload_date>%Y%m%d|)s-%(title)s.%(ext)s"
+ output_template="$DOWNLOAD_DIR/$platform_name/%(uploader|Unknown)s-%(playlist|)s/Season %(upload_date>%Y|0000)s/S%(upload_date>%Y|0000)sE%(upload_date>%m%d|0000)s - %(title)s.%(ext)s"
else
- output_template="$DOWNLOAD_DIR/$platform_name/%(uploader|)s/%(upload_date>%Y%m%d|)s-%(title)s.%(ext)s"
+ output_template="$DOWNLOAD_DIR/$platform_name/%(uploader|Unknown)s/Season %(upload_date>%Y|0000)s/S%(upload_date>%Y|0000)sE%(upload_date>%m%d|0000)s - %(title)s.%(ext)s"
fi
local archive_file="$DOWNLOAD_DIR/.archive.txt"
@@ -271,7 +357,7 @@ in
echo "Output directory: $DOWNLOAD_DIR/$platform_name"
# Build command
- local cmd="yt-dlp $platform_flags $match_filter"
+ local cmd="yt-dlp $platform_flags $match_filter --no-write-playlist-metafiles"
if [[ "$playlist_mode" == true ]]; then
cmd="$cmd --yes-playlist"
fi
@@ -282,6 +368,18 @@ in
# Execute download with retry
if _retry_download "$cmd"; then
+ # Generate NFO files for any videos missing them
+ local series_base="$DOWNLOAD_DIR/$platform_name"
+ find "$series_base" -name "*.info.json" 2>/dev/null | while read -r json_file; do
+ local base="''${json_file%.info.json}"
+ local nfo_file="$base.nfo"
+ if [[ ! -f "$nfo_file" ]]; then
+ for ext in mp4 mkv webm; do
+ [[ -f "$base.$ext" ]] && _generate_jellyfin_nfo "$base.$ext" && break
+ done
+ fi
+ done
+
# Build success message
local success_msg="$platform_name download completed"
[[ "$playlist_mode" == true ]] && success_msg="$platform_name playlist download completed"