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 */}
+ } />
+ } />
+