diff --git a/app.py b/app.py
index c52f8bb..bb1567a 100644
--- a/app.py
+++ b/app.py
@@ -781,18 +781,48 @@ def api_track_upload():
"email_html": f"{SITE}/t/{token}/html",
"note": "attach/email the HTML version — every view fires the pixel and lands in the inbox"})
+def _geo_cache():
+ con = db()
+ con.execute("CREATE TABLE IF NOT EXISTS geo_cache(ip TEXT PRIMARY KEY, geo TEXT, ts INTEGER)")
+ return con
+
+def enrich_ip(ip):
+ """geo/ISP/ASN for an IP, cached 24h."""
+ if not ip or ip == "created" or ip.startswith(("10.30.20.", "127.", "172.17.")): return {}
+ con = _geo_cache()
+ r = con.execute("SELECT geo FROM geo_cache WHERE ip=? AND ts > ?", (ip, int(time.time())-86400)).fetchone()
+ if r: return json.loads(r["geo"])
+ st, b = http(f"http://ip-api.com/json/{ip}?fields=66846719")
+ d = jf(b) or {}
+ geo = {k: d.get(k) for k in ("country","countryCode","regionName","city","zip","lat","lon","timezone","isp","org","as","asname","mobile","proxy","hosting","reverse","query") if d.get(k) is not None}
+ con.execute("INSERT OR REPLACE INTO geo_cache(ip,geo,ts) VALUES(?,?,?)", (ip, json.dumps(geo), int(time.time())))
+ con.commit()
+ return geo
+
+def _log_open(t, extra=""):
+ con = db()
+ ip = request.headers.get("X-Real-IP") or request.remote_addr or "?"
+ ua = request.headers.get("User-Agent","")
+ lang = request.headers.get("Accept-Language","")
+ ref = request.headers.get("Referer","")
+ geo = enrich_ip(ip)
+ where = ""
+ if geo: where = f" — {geo.get('city','')}, {geo.get('regionName','')} {geo.get('countryCode','')} · {geo.get('isp','')} · tz {geo.get('timezone','')}"
+ if geo.get("proxy"): where += " · VPN/proxy ⚠"
+ con.execute("INSERT INTO track_events(trackable_id,ts,ip,ua) VALUES(?,?,?,?)",
+ (t["id"], int(time.time()), ip + (" " + json.dumps(geo) if geo else ""), ua[:200] + (f" | lang={lang}" if lang else "") + (f" | ref={ref[:100]}" if ref else "")))
+ uid = t["user_id"]
+ if uid:
+ con.execute("INSERT INTO messages(user_id,sender,body,created) VALUES(?,?,?,?)",
+ (uid, "operator-bot", f"👁 '{esc(t['filename'])}' just opened{extra} — IP {esc(ip)}{esc(where)}
device: {esc(ua[:100])}{'
lang: ' + esc(lang) if lang else ''}{'
from: ' + esc(ref[:120]) if ref else ''}", int(time.time())))
+ con.commit()
+
@app.route("/t/")
def tracked_download(token):
con = db()
t = con.execute("SELECT * FROM trackables WHERE token=?", (token,)).fetchone()
if not t or not t["paid"]: return "not found", 404
- con.execute("INSERT INTO track_events(trackable_id,ts,ip,ua) VALUES(?,?,?,?)",
- (t["id"], int(time.time()), request.headers.get("X-Real-IP") or request.remote_addr, request.headers.get("User-Agent","")))
- uid = t["user_id"]
- if uid:
- con.execute("INSERT INTO messages(user_id,sender,body,created) VALUES(?,?,?,?)",
- (uid, "operator-bot", f"👁 your tracked file '{esc(t['filename'])}' was just opened — IP {esc(request.headers.get('X-Real-IP') or request.remote_addr)}, device: {esc(request.headers.get('User-Agent','')[:80])}", int(time.time())))
- con.commit()
+ _log_open(t, " (link)")
path = os.path.join(UPLOAD_DIR, token + ".bin")
if not os.path.exists(path): return "file gone", 404
return send_file(path, as_attachment=True, download_name=t["filename"])
@@ -802,13 +832,7 @@ def tracked_pixel(token):
con = db()
t = con.execute("SELECT * FROM trackables WHERE token=?", (token,)).fetchone()
if t and t["paid"]:
- con.execute("INSERT INTO track_events(trackable_id,ts,ip,ua) VALUES(?,?,?,?)",
- (t["id"], int(time.time()), request.headers.get("X-Real-IP") or request.remote_addr, request.headers.get("User-Agent","")))
- uid = t["user_id"]
- if uid:
- con.execute("INSERT INTO messages(user_id,sender,body,created) VALUES(?,?,?,?)",
- (uid, "operator-bot", f"👁 '{esc(t['filename'])}' was just viewed (email/pixel) — IP {esc(request.headers.get('X-Real-IP') or request.remote_addr)}", int(time.time())))
- con.commit()
+ _log_open(t, " (email/pixel)")
px = base64.b64decode("R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")
return Response(px, mimetype="image/gif", headers={"Cache-Control": "no-store"})