This commit is contained in:
dvirlabs 2025-07-10 21:27:41 +03:00
commit ceed189dc3
6 changed files with 50 additions and 44 deletions

View File

@ -37,6 +37,7 @@ steps:
- apk add --no-cache git yq - apk add --no-cache git yq
- git config --global user.name "woodpecker-bot" - git config --global user.name "woodpecker-bot"
- git config --global user.email "ci@dvirlabs.com" - git config --global user.email "ci@dvirlabs.com"
- git clone "https://$${GIT_USERNAME}:$${GIT_TOKEN}@git.dvirlabs.com/dvirlabs/my-apps.git"
- cd my-apps - cd my-apps
- | - |
TAG="${CI_COMMIT_BRANCH}-${CI_COMMIT_SHA:0:7}" TAG="${CI_COMMIT_BRANCH}-${CI_COMMIT_SHA:0:7}"

View File

@ -6,6 +6,7 @@ RUN apt update && apt install -y curl ffmpeg && \
WORKDIR /app WORKDIR /app
COPY . . COPY . .
RUN pip install --no-cache-dir -r requirements.txt RUN pip install --no-cache-dir -r requirements.txt
ENV MUSIC_DIR=/music ENV MUSIC_DIR=/music

View File

@ -1,11 +1,12 @@
import os from pydantic_settings import BaseSettings
from pydantic import BaseSettings from pydantic import Field
class Settings(BaseSettings): class Settings(BaseSettings):
MUSIC_DIR: str = "/music" MUSIC_DIR: str = Field(default="/music", description="Path where songs are saved")
NAVIDROME_SCAN_URL: str = "" NAVIDROME_SCAN_URL: str = Field(default="", description="URL to trigger Navidrome rescan")
class Config: class Config:
env_file = ".env" env_file = ".env"
env_file_encoding = "utf-8"
settings = Settings() settings = Settings()

37
backend/downloader.py Normal file
View File

@ -0,0 +1,37 @@
import subprocess
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")
command = [
"yt-dlp",
f"ytsearch1:{query}",
"--extract-audio",
"--audio-format", "mp3",
"--output", output_template,
"--no-playlist",
"--quiet"
]
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)
res.raise_for_status()
except Exception as e:
print(f"⚠️ Failed to trigger Navidrome rescan: {e}")
return {
"status": "success",
"query": query,
"log": result.stdout + "\n" + result.stderr
}

View File

@ -14,40 +14,5 @@ def download(query: str = Query(..., description="Song name or YouTube search te
except Exception as e: except Exception as e:
raise HTTPException(status_code=500, detail=str(e)) raise HTTPException(status_code=500, detail=str(e))
# downloader.py
import subprocess
import os
from config import settings
import uuid
import requests
def download_song(query: str):
output_template = os.path.join(settings.MUSIC_DIR, "%(title)s.%(ext)s")
command = [
"yt-dlp",
f"ytsearch1:{query}",
"--extract-audio",
"--audio-format", "mp3",
"--output", output_template
]
result = subprocess.run(command, capture_output=True, text=True)
if result.returncode != 0:
raise Exception(f"Download failed: {result.stderr}")
# Optional: trigger navidrome scan
if settings.NAVIDROME_SCAN_URL:
try:
requests.post(settings.NAVIDROME_SCAN_URL, timeout=5)
except Exception as e:
pass # non-critical
return {
"query": query,
"log": result.stdout
}
if __name__ == "__main__": if __name__ == "__main__":
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True) uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)

View File

@ -1,4 +1,5 @@
fastapi fastapi
uvicorn uvicorn
pydantic
requests requests
pydantic>=2.0
pydantic-settings>=2.0