diff --git a/backend/Dockerfile b/backend/Dockerfile index be4318a..4ba5499 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -2,6 +2,7 @@ FROM python:3.12-slim WORKDIR /app +# Install system dependencies including Node.js for yt-dlp JavaScript runtime RUN apt update && apt install -y \ weasyprint \ libcairo2 \ @@ -9,7 +10,13 @@ RUN apt update && apt install -y \ libpango-1.0-0 \ libgobject-2.0-0 \ ffmpeg \ - ca-certificates + ca-certificates \ + curl \ + && curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \ + && apt install -y nodejs \ + && update-ca-certificates \ + && apt clean \ + && rm -rf /var/lib/apt/lists/* COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt diff --git a/backend/thirdparty/downloader/views.py b/backend/thirdparty/downloader/views.py index b12bae0..404305d 100644 --- a/backend/thirdparty/downloader/views.py +++ b/backend/thirdparty/downloader/views.py @@ -6,6 +6,8 @@ import tempfile import os import shutil import mimetypes +import base64 +import urllib.request from rest_framework import serializers from rest_framework.views import APIView @@ -95,12 +97,13 @@ class Downloader(APIView): ydl_options = { "quiet": True, + "no_check_certificates": True, # Bypass SSL verification in Docker } try: with yt_dlp.YoutubeDL(ydl_options) as ydl: info = ydl.extract_info(url, download=False) - except Exception: - return Response({"error": "Failed to retrieve video info"}, status=400) + except Exception as e: + return Response({"error": f"Failed to retrieve video info: {str(e)}"}, status=400) formats = info.get("formats", []) or [] @@ -128,11 +131,24 @@ class Downloader(APIView): audio_resolutions = [f"{b}kbps" for b in sorted(bitrates, reverse=True)] + # Convert thumbnail to data URL to avoid mixed content issues (HTTPS thumbnail on HTTP site) + thumbnail_url = info.get("thumbnail") + thumbnail_data_url = None + if thumbnail_url: + try: + with urllib.request.urlopen(thumbnail_url, timeout=10) as response: + image_data = response.read() + content_type = response.headers.get('Content-Type', 'image/jpeg') + thumbnail_data_url = f"data:{content_type};base64,{base64.b64encode(image_data).decode('utf-8')}" + except Exception: + # If thumbnail fetch fails, just use the original URL + thumbnail_data_url = thumbnail_url + return Response( { "title": info.get("title"), "duration": info.get("duration"), - "thumbnail": info.get("thumbnail"), + "thumbnail": thumbnail_data_url, "video_resolutions": video_resolutions, "audio_resolutions": audio_resolutions, }, @@ -305,6 +321,7 @@ class Downloader(APIView): "merge_output_format": ext, # container "outtmpl": outtmpl, # temp dir "quiet": True, + "no_check_certificates": True, # Bypass SSL verification in Docker "max_filesize": settings.DOWNLOADER_MAX_SIZE_BYTES, "socket_timeout": settings.DOWNLOADER_TIMEOUT, "postprocessors": [], diff --git a/frontend/Dockerfile.prod b/frontend/Dockerfile.prod index feba5c3..1c32c6b 100644 --- a/frontend/Dockerfile.prod +++ b/frontend/Dockerfile.prod @@ -1,13 +1,26 @@ # Step 1: Build React (Vite) app FROM node:22-alpine AS build WORKDIR /app + +# Copy package files COPY package*.json ./ -# If package-lock.json exists, npm ci is faster and reproducible -RUN npm ci || npm install + +# Clean install with force flag to bypass cache issues +#RUN rm -rf node_modules package-lock.json && \ +# npm cache clean --force && \ +# npm install --legacy-peer-deps + +# install +RUN npm install --legacy-peer-deps + +# Copy source files COPY . . + ENV NODE_ENV=production # Skip Orval - use pre-generated files committed to git ENV SKIP_ORVAL=true + +# Build the app RUN npm run build # Step 2: Nginx runtime diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 0fb556f..72a74f2 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -3,6 +3,8 @@ import Home from "./pages/home/home"; import HomeLayout from "./layouts/HomeLayout"; import Downloader from "./pages/downloader/Downloader"; import PrivateRoute from "./routes/PrivateRoute"; +import DroneServisSection from "./pages/home/components/Services/droneServis"; + //import { UserContextProvider } from "./context/UserContext"; // Pages @@ -24,6 +26,11 @@ export default function App() { {/* APPS */} } /> + + {/* SERVICES */} + } /> + } /> +