diff --git a/.gitea/workflows/docker-build.yml b/.gitea/workflows/docker-build.yml new file mode 100644 index 0000000..42684e1 --- /dev/null +++ b/.gitea/workflows/docker-build.yml @@ -0,0 +1,36 @@ +name: Build and Push Docker Image + +on: + push: + branches: + - main + +jobs: + build-and-push: + runs-on: self-hosted + + steps: + # --- Installa Node.js nel contesto del workflow --- + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: '20' + + # --- Checkout del repository (richiede Node) --- + - name: Checkout repository + uses: actions/checkout@v3 + + # --- Login al Gitea Container Registry --- + - name: Login to Gitea Container Registry + run: | + echo "${{ secrets.REGISTRY_TOKEN }}" | docker login gitea.enrilinux.ovh -u "${{ secrets.REGISTRY_USER }}" --password-stdin + + # --- Build della Docker image della tua app --- + - name: Build Docker image + run: | + docker build -t gitea.enrilinux.ovh/${{ secrets.REGISTRY_USER }}/streamvault:latest . + + # --- Push della Docker image al registry --- + - name: Push Docker image + run: | + docker push gitea.enrilinux.ovh/${{ secrets.REGISTRY_USER }}/streamvault:latest diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..74c85e2 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +FROM python:3.11 + +WORKDIR /app + +RUN apt-get update && apt-get install -y ffmpeg + +COPY requirements.txt . + +RUN pip install -r requirements.txt + +RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ + && apt-get install -y nodejs + +COPY app ./app +RUN mkdir downloads + +CMD ["uvicorn","app.main:app","--host","0.0.0.0","--port","8000"] diff --git a/app/downloader.py b/app/downloader.py new file mode 100644 index 0000000..59ff17d --- /dev/null +++ b/app/downloader.py @@ -0,0 +1,46 @@ +import yt_dlp +import glob +import re +import os + +DOWNLOAD_DIR = "downloads" + +def sanitize_filename(name): + """Rimuove caratteri non validi dai nomi dei file""" + return re.sub(r'[\\/*?:"<>|]', '', name) + +def download_video(url, mode): + # Template che usa il titolo e l'ID + template = f"{DOWNLOAD_DIR}/%(title)s - %(id)s.%(ext)s" + + if mode == "audio": + opts = { + "format": "bestaudio/best", + "outtmpl": template, + "postprocessors": [{ + "key": "FFmpegExtractAudio", + "preferredcodec": "mp3", + "preferredquality": "192", + }] + } + else: + opts = { + "format": "bestvideo+bestaudio/best", + "merge_output_format": "mp4", + "outtmpl": template + } + + with yt_dlp.YoutubeDL(opts) as ydl: + info = ydl.extract_info(url, download=True) + + # Prende il file scaricato e lo rinomina in modo sicuro + downloaded_files = glob.glob(f"{DOWNLOAD_DIR}/*{info['id']}*") + final_path = downloaded_files[0] + safe_path = os.path.join( + DOWNLOAD_DIR, + sanitize_filename(os.path.basename(final_path)) + ) + if safe_path != final_path: + os.rename(final_path, safe_path) + + return safe_path \ No newline at end of file diff --git a/app/main.py b/app/main.py new file mode 100644 index 0000000..165d677 --- /dev/null +++ b/app/main.py @@ -0,0 +1,30 @@ +from fastapi import FastAPI, Request, Form +from fastapi.responses import HTMLResponse, FileResponse +from fastapi.templating import Jinja2Templates +import os +import uuid + +from app.downloader import download_video + +app = FastAPI() + +templates = Jinja2Templates(directory="app/templates") + +DOWNLOAD_DIR = "downloads" +os.makedirs(DOWNLOAD_DIR, exist_ok=True) + + +@app.get("/", response_class=HTMLResponse) +async def home(request: Request): + return templates.TemplateResponse("index.html", {"request": request}) + + +@app.post("/download") +async def download(url: str = Form(...), mode: str = Form(...)): + path = download_video(url, mode) + return {"path": path} + + +@app.get("/file") +async def file(path: str): + return FileResponse(path) diff --git a/app/templates/index.html b/app/templates/index.html new file mode 100644 index 0000000..3f1cd13 --- /dev/null +++ b/app/templates/index.html @@ -0,0 +1,84 @@ + + + +
+