diff --git a/.gitignore b/.gitignore index 8c2abe8..f18c04c 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,4 @@ venv.bak/ config/ downloads/ *.log +music/ \ No newline at end of file diff --git a/app/services/download_manager.py b/app/services/download_manager.py index af59011..0fcb4e5 100644 --- a/app/services/download_manager.py +++ b/app/services/download_manager.py @@ -2,6 +2,9 @@ import threading import queue import logging import sys +import os +import shutil +import pathlib from typing import Dict, List from tidal_dl_ng.download import Download from tidal_dl_ng.config import Settings, Tidal @@ -175,6 +178,10 @@ class DownloadManager: if not tidal.session.check_login(): raise Exception("Not logged in") + # Move any existing albums to destination before starting new download + if task["type"] in ["album", "artist"]: + self._move_albums_to_destination() + # Use environment variable for download path, default to /app/downloads import os settings.data.download_base_path = os.getenv("DOWNLOAD_PATH", "/app/downloads") @@ -249,7 +256,7 @@ class DownloadManager: task["current_item"] = track.name downloader.item( - file_template=settings.data.format_track, + file_template=settings.data.format_album, media=track, quality_audio=settings.data.quality_audio, is_parent_album=True, @@ -298,12 +305,53 @@ class DownloadManager: task["current_item"] = track.name downloader.item( - file_template=settings.data.format_track, + file_template=settings.data.format_album, media=track, quality_audio=settings.data.quality_audio, is_parent_album=True, # Treat as album tracks to keep folder structure list_position=track.track_num, # Use original track num list_total=track.album.num_tracks ) - + # Move albums to destination after download completes + if task["type"] in ["album", "artist"]: + self._move_albums_to_destination() + + def _move_albums_to_destination(self): + """Move all albums from downloads/Albums/ to destination path.""" + dest_base = os.getenv("ALBUM_DESTINATION_PATH") + if not dest_base: + return + + download_base = os.getenv("DOWNLOAD_PATH", "/app/downloads") + albums_path = pathlib.Path(download_base) / "Albums" + + if not albums_path.exists(): + return + + try: + moved_count = 0 + # Move all album folders to destination + for album_dir in albums_path.iterdir(): + if not album_dir.is_dir(): + continue + + # Destination path: [ALBUM_DESTINATION_PATH]/[Album folder name] + dest_album_path = pathlib.Path(dest_base) / album_dir.name + + logger.info(f"Moving {album_dir.name} to {dest_album_path}") + + # Remove destination if it exists + if dest_album_path.exists(): + shutil.rmtree(dest_album_path) + + # Move the album + shutil.move(str(album_dir), str(dest_album_path)) + moved_count += 1 + + if moved_count > 0: + logger.info(f"Successfully moved {moved_count} album(s) to {dest_base}") + + except Exception as e: + logger.error(f"Failed to move albums: {e}") + diff --git a/app/templates/index.html b/app/templates/index.html index 272e9bc..b54bb35 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -14,13 +14,11 @@

Search

- +
diff --git a/docker-compose.local.yml b/docker-compose.local.yml new file mode 100644 index 0000000..8c50d0e --- /dev/null +++ b/docker-compose.local.yml @@ -0,0 +1,35 @@ +services: + gluetun: + image: qmcgaw/gluetun + container_name: gluetun + cap_add: + - NET_ADMIN + env_file: + - .env + ports: + - "8002:8080" # Expose tidal-dl-web port via gluetun + restart: always + web: + build: . + container_name: tidal-dl-web + network_mode: "service:gluetun" + volumes: + - ./downloads:/app/downloads + - ./config:/app/config + - ./music:/app/music + # Mount source for development + - ./app:/app/app + command: uvicorn app.main:app --host 0.0.0.0 --port 8080 --reload + environment: + - PYTHONUNBUFFERED=1 + - DOWNLOAD_PATH=/app/downloads + - XDG_CONFIG_HOME=/app/config + - ALBUM_DESTINATION_PATH=${ALBUM_DESTINATION_PATH:-} + restart: unless-stopped + depends_on: + gluetun: + condition: service_healthy + +networks: + proxy: + external: true diff --git a/docker-compose.yml b/docker-compose.yml index ac274c9..5e9da16 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -33,6 +33,7 @@ services: volumes: - ./downloads:/app/downloads - ./config:/app/config + - ./music:/app/music # Mount source for development - ./app:/app/app command: uvicorn app.main:app --host 0.0.0.0 --port 8080 --reload @@ -40,6 +41,7 @@ services: - PYTHONUNBUFFERED=1 - DOWNLOAD_PATH=/app/downloads - XDG_CONFIG_HOME=/app/config + - ALBUM_DESTINATION_PATH=${ALBUM_DESTINATION_PATH:-} restart: unless-stopped depends_on: gluetun: