Experimental placeholder video functionality

This commit is contained in:
MMaker 2025-02-27 15:15:11 -05:00
parent d8ffe43857
commit 5d5588f4f5
Signed by: mmaker
GPG Key ID: CCE79B8FEDA40FB2

40
app.py
View File

@ -3,8 +3,9 @@ import http.cookiejar
import json import json
import requests import requests
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from flask import Flask, Response, request, jsonify from flask import Flask, Response, request, jsonify, send_file, make_response
from diskcache import Cache from diskcache import Cache
from io import BytesIO
import logging import logging
import threading import threading
@ -36,6 +37,17 @@ CACHE_EXPIRATION_HTML = 60 * 60 # 1 hour
CACHE_EXPIRATION_CDN = 60 * 60 * 24 * 7 # 1 week CACHE_EXPIRATION_CDN = 60 * 60 * 24 * 7 # 1 week
CACHE_SIZE_LIMIT = 100 * 1024 * 1024 # 100 MB CACHE_SIZE_LIMIT = 100 * 1024 * 1024 # 100 MB
placeholder_video = None
PLACEHOLDER_VIDEO_PATH = os.environ.get('NICONICOGAY_PLACEHOLDER_VIDEO', 'placeholder.mp4')
try:
with open(PLACEHOLDER_VIDEO_PATH, 'rb') as f:
placeholder_video = BytesIO(f.read())
logger.debug("Loaded placeholder video")
except FileNotFoundError:
logger.warning(f"Placeholder video file '{PLACEHOLDER_VIDEO_PATH}' not found")
except Exception as e:
logger.error(f"Error loading placeholder video: {e}")
cache = None cache = None
if os.environ.get('NICONICOGAY_DISABLE_CACHE', '') != '1': if os.environ.get('NICONICOGAY_DISABLE_CACHE', '') != '1':
cache = Cache("disk_cache", size_limit=CACHE_SIZE_LIMIT) cache = Cache("disk_cache", size_limit=CACHE_SIZE_LIMIT)
@ -273,6 +285,29 @@ def get_oembed_url(params):
return oembed_url return oembed_url
@app.route("/cdn/<video_id>.mp4")
def cdn_redirect(video_id):
"""
Checks if a video exists in CDN and redirects accordingly.
Returns CDN URL if video exists, otherwise returns a placeholder video URL.
Only responds to requests from Discord bots.
"""
logger.info(f"{video_id}: CDN redirect request received")
request_user_agent = request.headers.get('User-Agent', '').lower()
if 'discordbot' not in request_user_agent:
logger.info(f"{video_id}: Video CDN redirect ignored due to user agent ({request_user_agent})")
return Response("Video not found", status=404)
if placeholder_video is None or is_video_in_cdn(video_id):
cdn_url = get_cdn_url(video_id)
logger.info(f"{video_id}: Redirecting to CDN URL: {cdn_url}")
return Response("", status=302, headers={"Location": cdn_url})
logger.info(f"{video_id}: Video not found in CDN, returning placeholder")
response = make_response(send_file(placeholder_video, mimetype="video/mp4"))
response.headers['Content-Length'] = str(placeholder_video.getbuffer().nbytes)
return response
@app.route("/watch/<video_id>") @app.route("/watch/<video_id>")
def proxy(video_id): def proxy(video_id):
@ -329,7 +364,7 @@ def proxy(video_id):
download_queue.append((video_id, real_url, video_quality)) download_queue.append((video_id, real_url, video_quality))
logger.info(f"{video_id}: Queued for download") logger.info(f"{video_id}: Queued for download")
cdn_video_url = get_cdn_url(video_id) cdn_video_url = f"{HOST}/cdn/{video_id}.mp4" if placeholder_video else get_cdn_url(video_id)
og_tags = soup.find_all("meta", attrs={"property": True}) og_tags = soup.find_all("meta", attrs={"property": True})
for tag in og_tags: for tag in og_tags:
# Remove attribute(s) added by niconico # Remove attribute(s) added by niconico
@ -372,6 +407,7 @@ if you want to download videos, please consider using a tool like nndownload: ht
logger.info(f"{video_id}: Returning response") logger.info(f"{video_id}: Returning response")
return Response(html_response, mimetype="text/html") return Response(html_response, mimetype="text/html")
@app.route("/owoembed") @app.route("/owoembed")
def owoembed(): def owoembed():
""" """