diff --git a/proxy/rss_proxy.py b/proxy/rss_proxy.py index c80b32a..d06bd1a 100755 --- a/proxy/rss_proxy.py +++ b/proxy/rss_proxy.py @@ -1,30 +1,64 @@ import urllib.parse -from flask import request, Response -import requests import os +import requests +import redis +import xml.etree.ElementTree as ET +from flask import Flask, request, Response + +app = Flask(__name__) PROXY_URL = os.getenv("PROXY_URL") +REDIS_URL = os.getenv("REDIS_URL", "redis://localhost:6379/0") +CACHE_TTL = int(os.getenv("CACHE_TTL", 3600)) # По умолчанию 1 час + +rdb = redis.from_url(REDIS_URL) -def init_proxy(app): - @app.route("/proxy") - def proxy(): - """Proxy RSS feed with forced re-encoding to UTF-8""" - raw_query = request.query_string.decode() - if raw_query.startswith("url="): - url = urllib.parse.unquote(raw_query[4:]) - else: - return "Missing URL", 400 +@app.route("/proxy") +def proxy(): + """Proxy RSS feed with per-item caching.""" + raw_query = request.query_string.decode() + if raw_query.startswith("url="): + url = urllib.parse.unquote(raw_query[4:]) + else: + return "Missing URL", 400 - try: - proxies = {"http": PROXY_URL, "https": PROXY_URL} if PROXY_URL else None - r = requests.get(url, timeout=10, proxies=proxies) + try: + # Получаем ленту + proxies = {"http": PROXY_URL, "https": PROXY_URL} if PROXY_URL else None + r = requests.get(url, timeout=10, proxies=proxies) + r.encoding = "windows-1251" if "windows-1251" in r.headers.get("content-type", "").lower() else r.apparent_encoding + xml_data = r.text.replace('', '') - r.encoding = "windows-1251" if "windows-1251" in r.headers.get("content-type", - "").lower() else r.apparent_encoding - response_text = r.text.replace('', - '') + # Разбираем XML + root = ET.fromstring(xml_data) + items = root.findall(".//item") - return Response(response_text, content_type="application/xml; charset=utf-8") - except Exception as e: - return f"Error: {e}", 500 + cached_items = [] + new_items = [] + + for item in items: + guid = item.find("guid").text if item.find("guid") is not None else None + if guid: + cache_key = f"rss:item:{guid}" + cached_item = rdb.get(cache_key) + + if cached_item: + cached_items.append(cached_item.decode()) + else: + item_str = ET.tostring(item, encoding="unicode") + rdb.setex(cache_key, CACHE_TTL, item_str) + new_items.append(item_str) + + # Собираем финальный RSS + final_items = cached_items + new_items + response_xml = f'{"".join(final_items)}' + + return Response(response_xml, content_type="application/xml; charset=utf-8") + + except Exception as e: + return f"Error: {e}", 500 + + +if __name__ == "__main__": + app.run(host="0.0.0.0", port=5050)