Actualizar berretin.py

This commit is contained in:
nix 2025-11-07 19:54:37 +00:00
parent 5b2d5b1d16
commit 0c1014ebe1

View File

@ -4,45 +4,68 @@ import json
import requests import requests
import subprocess import subprocess
from datetime import datetime, timedelta from datetime import datetime, timedelta
from flask import Flask, jsonify, Response, request from flask import Flask, jsonify, Response, request, abort
BASE_API = "https://ws1.smn.gob.ar" BASE_API = "https://ws1.smn.gob.ar"
CACHE_DIR = "json.api.cache" CACHE_DIR = "json.api.cache"
CACHE_TTL = timedelta(minutes=30) CACHE_TTL = timedelta(minutes=60)
SMN_TOKEN_FILE = "token.txt" SMN_TOKEN_FILE = "token.txt"
ACCESS_TOKEN = "i.hate.smn" ACCESS_TOKEN = "i.hate.smn"
TIMEOUT = 10
app = Flask(__name__) app = Flask(__name__)
app.config["JSONIFY_PRETTYPRINT_REGULAR"] = False
@app.after_request
def remove_server_header(response):
response.headers["Server"] = ""
response.headers["X-Powered-By"] = ""
return response
def get_cache_filename(url: str) -> str: def get_cache_filename(url: str) -> str:
h = hashlib.sha256(url.encode()).hexdigest() h = hashlib.sha256(url.encode()).hexdigest()
return os.path.join(CACHE_DIR, f"{h}.json") return os.path.join(CACHE_DIR, f"{h}.json")
def load_cache(url: str): def load_cache(url: str):
path = get_cache_filename(url) try:
if not os.path.exists(path): path = get_cache_filename(url)
if not os.path.exists(path):
return None
mtime = datetime.fromtimestamp(os.path.getmtime(path))
if datetime.now() - mtime > CACHE_TTL:
return None
with open(path, "r", encoding="utf-8") as f:
return json.load(f)
except Exception:
return None return None
mtime = datetime.fromtimestamp(os.path.getmtime(path))
if datetime.now() - mtime > CACHE_TTL:
return None
with open(path, "r", encoding="utf-8") as f:
return json.load(f)
def save_cache(url: str, data: dict): def save_cache(url: str, data: dict):
os.makedirs(CACHE_DIR, exist_ok=True) try:
path = get_cache_filename(url) os.makedirs(CACHE_DIR, exist_ok=True)
with open(path, "w", encoding="utf-8") as f: path = get_cache_filename(url)
json.dump(data, f, indent=2, ensure_ascii=False) with open(path, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False)
except Exception as e:
print(f"[CACHE] Failed to save cache: {e}")
def load_smn_token(): def load_smn_token():
with open(SMN_TOKEN_FILE, "r") as f: try:
return f.read().strip() with open(SMN_TOKEN_FILE, "r", encoding="utf-8") as f:
token = f.read().strip()
if not token:
raise ValueError("Empty token file.")
return token
except Exception as e:
print(f"[TOKEN] Error loading token: {e}")
return ""
def refresh_smn_token(): def refresh_smn_token():
print("[TOKEN] Refreshing SMN token...") print("[TOKEN] Refreshing SMN token...")
try: try:
result = subprocess.run( result = subprocess.run(
["python3", "tokenext.py"], # cheap as fuck, fixing later ["python3", "tokenext.py"],
capture_output=True, capture_output=True,
text=True, text=True,
timeout=60 timeout=60
@ -50,13 +73,16 @@ def refresh_smn_token():
if result.returncode == 0: if result.returncode == 0:
print("[TOKEN] Token refreshed successfully.") print("[TOKEN] Token refreshed successfully.")
else: else:
print("[TOKEN] Failed to refresh token:", result.stderr) print(f"[TOKEN] Refresh failed: {result.stderr.strip()}")
except Exception as e: except Exception as e:
print("[TOKEN] Error running tokenext.py:", e) print(f"[TOKEN] Error running tokenext.py: {e}")
def check_access_token(): def check_access_token():
header_token = request.headers.get("Authorization", "").strip() header_token = request.headers.get("Authorization", "").strip()
return header_token == ACCESS_TOKEN if not header_token or header_token != ACCESS_TOKEN:
abort(401) # immediately reject unauthorized access
def fetch_from_smn(url: str, retry: bool = True): def fetch_from_smn(url: str, retry: bool = True):
token = load_smn_token() token = load_smn_token()
@ -66,23 +92,27 @@ def fetch_from_smn(url: str, retry: bool = True):
"User-Agent": "Mozilla/5.0" "User-Agent": "Mozilla/5.0"
} }
resp = requests.get(url, headers=headers) try:
resp = requests.get(url, headers=headers, timeout=TIMEOUT)
except requests.RequestException as e:
print(f"[ERROR] Request failed: {e}")
return None
if resp.status_code == 401 and retry: if resp.status_code == 401 and retry:
print("[AUTH] SMN token expired, trying to refresh...") print("[AUTH] SMN token expired, refreshing...")
refresh_smn_token() refresh_smn_token()
return fetch_from_smn(url, retry=False) return fetch_from_smn(url, retry=False)
return resp return resp
@app.route("/smn/<path:subpath>") @app.route("/smn/<path:subpath>")
def smn_proxy(subpath): def smn_proxy(subpath):
if not check_access_token(): check_access_token()
return jsonify({"error": "Unauthorized"}), 401
url = f"{BASE_API}/{subpath}" url = f"{BASE_API}/{subpath}"
# Check cache # Cache check
cached = load_cache(url) cached = load_cache(url)
if cached: if cached:
print(f"[CACHE] Loaded {subpath}") print(f"[CACHE] Loaded {subpath}")
@ -90,18 +120,23 @@ def smn_proxy(subpath):
print(f"[FETCH] {url}") print(f"[FETCH] {url}")
resp = fetch_from_smn(url) resp = fetch_from_smn(url)
if not resp:
return Response("", status=502)
if resp.status_code != 200: if resp.status_code >= 400:
return Response( print(f"[WARN] {resp.status_code} for {url}")
resp.text, return Response("", status=resp.status_code)
status=resp.status_code,
content_type=resp.headers.get("Content-Type", "text/plain") try:
) data = resp.json()
except Exception:
print("[ERROR] Invalid JSON response.")
return Response("", status=502)
data = resp.json()
save_cache(url, data) save_cache(url, data)
return jsonify(data) return jsonify(data)
if __name__ == "__main__": if __name__ == "__main__":
os.makedirs(CACHE_DIR, exist_ok=True) os.makedirs(CACHE_DIR, exist_ok=True)
app.run(host="0.0.0.0", port=6942, debug=False) app.run(host="0.0.0.0", port=6942, debug=False, use_reloader=False)