""" Auto Publisher — Analytics collector endpoint. Lightweight Flask app that runs on each site CT to collect pageview data. """ from flask import Flask, request, jsonify import sqlite3 import json import hashlib import time from datetime import datetime, timedelta from pathlib import Path app = Flask(__name__) DB_PATH = "/var/lib/auto-publisher/analytics.db" def get_db(): Path(DB_PATH).parent.mkdir(parents=True, exist_ok=True) db = sqlite3.connect(DB_PATH) db.execute(""" CREATE TABLE IF NOT EXISTS pageviews ( id INTEGER PRIMARY KEY AUTOINCREMENT, path TEXT NOT NULL, vertical TEXT NOT NULL, referrer TEXT DEFAULT '', user_agent TEXT DEFAULT '', ip_hash TEXT DEFAULT '', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) """) db.execute(""" CREATE INDEX IF NOT EXISTS idx_pageviews_path ON pageviews(path); """) db.execute(""" CREATE INDEX IF NOT EXISTS idx_pageviews_created ON pageviews(created_at); """) db.commit() return db @app.route("/a/collect", methods=["POST", "GET"]) def collect(): """Collect a pageview ping.""" path = request.args.get("p", "/") vertical = request.args.get("v", "unknown") ref = request.args.get("r", "") ua = request.headers.get("User-Agent", "")[:200] ip = request.remote_addr or "" ip_hash = hashlib.sha256(ip.encode()).hexdigest()[:16] if ip else "" db = get_db() db.execute( "INSERT INTO pageviews (path, vertical, referrer, user_agent, ip_hash) VALUES (?, ?, ?, ?, ?)", (path, vertical, ref, ua, ip_hash) ) db.commit() db.close() # Return a 1x1 transparent GIF return b"\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x80\x00\x00\xff\xff\xff\x00\x00\x00\x21\xf9\x04\x01\x00\x00\x00\x00\x2c\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02\x44\x01\x00\x3b", 200, { "Content-Type": "image/gif", "Cache-Control": "no-cache, no-store, must-revalidate", } @app.route("/a/stats") def stats(): """Get site analytics summary.""" db = get_db() db.row_factory = sqlite3.Row today = datetime.now().strftime("%Y-%m-%d") total = db.execute("SELECT COUNT(*) as c FROM pageviews").fetchone()["c"] today_views = db.execute( "SELECT COUNT(*) as c FROM pageviews WHERE created_at >= ?", (today,) ).fetchone()["c"] top_pages = db.execute(""" SELECT path, COUNT(*) as c FROM pageviews WHERE created_at >= date('now', '-30 days') GROUP BY path ORDER BY c DESC LIMIT 10 """).fetchall() db.close() return jsonify({ "total_views": total, "today_views": today_views, "top_pages": [{"path": r["path"], "views": r["c"]} for r in top_pages], }) @app.route("/health") def health(): return jsonify({"status": "ok"}) if __name__ == "__main__": app.run(host="0.0.0.0", port=5199, debug=False)