diff --git a/app.py b/app.py index ae321a6..bbae589 100644 --- a/app.py +++ b/app.py @@ -1,11 +1,16 @@ import http.cookiejar import json -from flask import Flask, Response import requests from bs4 import BeautifulSoup +from flask import Flask, Response +from diskcache import Cache app = Flask(__name__) +CACHE_EXPIRATION_SECONDS = 3600 # 1 hour +CACHE_SIZE_LIMIT = 100 * 1024 * 1024 # 100 MB +cache = Cache("disk_cache", size_limit=CACHE_SIZE_LIMIT) + cookie_jar = http.cookiejar.MozillaCookieJar('cookies.txt') try: cookie_jar.load(ignore_discard=True, ignore_expires=True) @@ -20,8 +25,12 @@ s.cookies = cookie_jar # type: ignore @app.route("/watch/") def proxy(video_id): - real_url = f"https://www.nicovideo.jp/watch/{video_id}" + cached_html = cache.get(video_id) + if cached_html is not None: + return Response(cached_html, mimetype="text/html") # type: ignore + # Not in cache or cache expired; fetch from nicovideo.jp + real_url = f"https://www.nicovideo.jp/watch/{video_id}" try: r = s.get(real_url, timeout=10) except requests.RequestException as e: @@ -30,35 +39,37 @@ def proxy(video_id): soup = BeautifulSoup(r.text, "html.parser") thumbnail_url = None try: - if soup.find("meta", {"name": "server-response"}): - params = json.loads(soup.find("meta", {"name": "server-response"})["content"])["data"]["response"] # type: ignore - thumbnail_url = ( # Use highest quality thumbnail available - params["video"]["thumbnail"]["ogp"] - or params["video"]["thumbnail"]["player"] - or params["video"]["thumbnail"]["largeUrl"] - or params["video"]["thumbnail"]["middleUrl"] - or params["video"]["thumbnail"]["url"] + server_response = soup.find("meta", {"name": "server-response"}) + if server_response: + params = json.loads(server_response["content"])["data"]["response"] # type: ignore + thumbnail_url = ( + params["video"]["thumbnail"].get("ogp") or + params["video"]["thumbnail"].get("player") or + params["video"]["thumbnail"].get("largeUrl") or + params["video"]["thumbnail"].get("middleUrl") or + params["video"]["thumbnail"].get("url") ) except (KeyError, json.JSONDecodeError): pass + og_tags = soup.find_all("meta", property=lambda x: x) # type: ignore for tag in og_tags: if tag.get("property") == "og:image" and thumbnail_url: tag["content"] = thumbnail_url + og_tags_str = "\n".join(str(tag) for tag in og_tags) html_response = f""" - - {og_tags_str} + + {og_tags_str} """ - return Response(html_response, mimetype="text/html") + cache.set(video_id, html_response, expire=CACHE_EXPIRATION_SECONDS) -if __name__ == "__main__": - app.run(host="127.0.0.1", port=2525, debug=False) + return Response(html_response, mimetype="text/html")