Actualizar berretin.py
This commit is contained in:
parent
5b2d5b1d16
commit
0c1014ebe1
99
berretin.py
99
berretin.py
@ -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)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user