This commit is contained in:
dvirlabs 2025-07-31 08:01:51 +03:00
parent ceed189dc3
commit 3438b1587c
7 changed files with 42 additions and 6 deletions

4
backend/.env Normal file
View File

@ -0,0 +1,4 @@
# MUSIC_DIR=/music
# NAVIDROME_SCAN_URL=http://navidrome:4533/api/rescan
MUSIC_DIR=./backend/music
NAVIDROME_SCAN_URL=

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,8 +1,10 @@
from pydantic_settings import BaseSettings
from pydantic import Field
import os
class Settings(BaseSettings):
MUSIC_DIR: str = Field(default="/music", description="Path where songs are saved")
BASE_DIR: str = os.path.dirname(os.path.abspath(__file__))
MUSIC_DIR: str = Field(default=os.path.join(BASE_DIR, "music"), description="Path where songs are saved")
NAVIDROME_SCAN_URL: str = Field(default="", description="URL to trigger Navidrome rescan")
class Config:

View File

@ -3,26 +3,52 @@ import os
from config import settings
import requests
def download_song(query: str):
output_template = os.path.join(settings.MUSIC_DIR, "%(artist)s/%(album)s/%(title)s.%(ext)s")
def detect_query_type(query: str):
if "youtube.com/playlist" in query or "list=" in query:
return "playlist"
elif "youtube.com/watch" in query or "youtu.be/" in query:
return "video"
else:
return "search"
def download_song(query: str):
output_template = os.path.join(settings.MUSIC_DIR, "%(uploader)s/%(title)s.%(ext)s")
query_type = detect_query_type(query)
if query_type == "video":
yt_query = query
playlist_flag = "--no-playlist"
extra_filters = []
elif query_type == "playlist":
yt_query = query
playlist_flag = None
extra_filters = []
else:
yt_query = f"ytsearch20:{query}"
playlist_flag = "--no-playlist"
filter_expr = f"'{query.lower()}' in uploader.lower()" # ✅ valid expression
extra_filters = ["--match-filter", filter_expr]
command = [
"yt-dlp",
f"ytsearch1:{query}",
yt_query,
"--extract-audio",
"--audio-format", "mp3",
"--output", output_template,
"--no-playlist",
"--quiet"
]
if playlist_flag:
command.append(playlist_flag)
if extra_filters:
command.extend(extra_filters)
result = subprocess.run(command, capture_output=True, text=True)
if result.returncode != 0:
raise Exception(f"❌ Download failed:\n{result.stderr}")
# Optional: trigger Navidrome rescan
if settings.NAVIDROME_SCAN_URL:
try:
res = requests.get(settings.NAVIDROME_SCAN_URL, timeout=5)

View File

@ -3,6 +3,10 @@ from fastapi.responses import JSONResponse
import uvicorn
from downloader import download_song
from config import settings
import os
# Make sure the music directory exists
os.makedirs(settings.MUSIC_DIR, exist_ok=True)
app = FastAPI(title="Tunedrop")