update
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -47,3 +47,4 @@ venv.bak/
|
||||
config/
|
||||
downloads/
|
||||
*.log
|
||||
music/
|
||||
@@ -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}")
|
||||
|
||||
|
||||
@@ -14,13 +14,11 @@
|
||||
|
||||
<div class="card">
|
||||
<h2>Search</h2>
|
||||
<input type="text" id="query" placeholder="Search for tracks, albums..." onkeypress="handleEnter(event)">
|
||||
<input type="text" id="query" placeholder="Search for artists, albums..." onkeypress="handleEnter(event)">
|
||||
<select id="type"
|
||||
style="padding: 10px; background: #2d2d2d; color: white; border: 1px solid #333; border-radius: 4px;">
|
||||
<option value="track">Track</option>
|
||||
<option value="album">Album</option>
|
||||
<option value="artist">Artist</option>
|
||||
<option value="playlist">Playlist</option>
|
||||
<option value="album">Album</option>
|
||||
</select>
|
||||
<button onclick="search()">Search</button>
|
||||
</div>
|
||||
|
||||
35
docker-compose.local.yml
Normal file
35
docker-compose.local.yml
Normal file
@@ -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
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user