Add Umami analytics beacon (per-vertical tracking)
This commit is contained in:
@@ -6,10 +6,8 @@ import os
|
|||||||
import json
|
import json
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import hashlib
|
import hashlib
|
||||||
import time
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime
|
||||||
from functools import wraps
|
|
||||||
from flask import Flask, request, jsonify, render_template_string, g, abort, Response
|
from flask import Flask, request, jsonify, render_template_string, g, abort, Response
|
||||||
|
|
||||||
# ─── Config ────────────────────────────────────────────────────────
|
# ─── Config ────────────────────────────────────────────────────────
|
||||||
@@ -18,6 +16,19 @@ DOMAIN = f"{VERTICAL}.thetempleofdoom.com"
|
|||||||
DB_PATH = Path(f"/var/lib/publisher/{VERTICAL}.db")
|
DB_PATH = Path(f"/var/lib/publisher/{VERTICAL}.db")
|
||||||
SECRET = os.environ.get("PUBLISHER_SECRET", "auto-publish-2026")
|
SECRET = os.environ.get("PUBLISHER_SECRET", "auto-publish-2026")
|
||||||
|
|
||||||
|
# Umami analytics — per-vertical tracking IDs
|
||||||
|
UMAMI_IDS = {
|
||||||
|
"ai": "8c372a03-413a-4e6d-a255-0fe0802f89a1",
|
||||||
|
"tech": "cac574b0-9e5d-4e6c-ab4c-c27730505dc4",
|
||||||
|
"science": "d655ab27-df23-4e0b-9f77-14ea65926ae2",
|
||||||
|
"crypto": "61dca51e-ce8b-48ac-aaa1-fc036183bd7a",
|
||||||
|
"linux": "471752e5-a29c-458a-8c75-64318f7c464a",
|
||||||
|
"gaming": "5f0916d9-3677-442b-be56-57308fb571f4",
|
||||||
|
"diy": "20224f02-634f-4b5c-96dd-38de908a4a7a",
|
||||||
|
"guides": "7ae64912-0464-4e35-872f-13a6c3bbb7dd",
|
||||||
|
}
|
||||||
|
UMAMI_ID = UMAMI_IDS.get(VERTICAL, "")
|
||||||
|
|
||||||
# Per-vertical identity
|
# Per-vertical identity
|
||||||
IDENTITIES = {
|
IDENTITIES = {
|
||||||
"ai": {
|
"ai": {
|
||||||
@@ -146,6 +157,7 @@ NETWORK_SITES = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
IDENTITY = IDENTITIES.get(VERTICAL, IDENTITIES["guides"])
|
IDENTITY = IDENTITIES.get(VERTICAL, IDENTITIES["guides"])
|
||||||
|
IDENTITY = {**IDENTITY, "umami_id": UMAMI_ID}
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
@@ -453,6 +465,17 @@ def sitemap():
|
|||||||
return Response(build_sitemap_xml(), mimetype="application/xml")
|
return Response(build_sitemap_xml(), mimetype="application/xml")
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/robots.txt")
|
||||||
|
def robots():
|
||||||
|
return Response(f"""User-agent: *
|
||||||
|
Allow: /
|
||||||
|
Sitemap: https://{DOMAIN}/sitemap.xml
|
||||||
|
|
||||||
|
User-agent: GPTBot
|
||||||
|
Disallow: /
|
||||||
|
""", mimetype="text/plain")
|
||||||
|
|
||||||
|
|
||||||
@app.route("/tag/<tag>")
|
@app.route("/tag/<tag>")
|
||||||
def tag_page(tag):
|
def tag_page(tag):
|
||||||
"""Aggregate all articles with a given tag."""
|
"""Aggregate all articles with a given tag."""
|
||||||
@@ -794,6 +817,7 @@ HOME_TEMPLATE = """<!DOCTYPE html>
|
|||||||
.hero-stats{flex-wrap:wrap;gap:0.75rem}
|
.hero-stats{flex-wrap:wrap;gap:0.75rem}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<script async src="https://analytics.thetempleofdoom.com/script.js" data-website-id="{{ umami_id }}"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
@@ -1058,6 +1082,7 @@ ARTICLE_TEMPLATE = """<!DOCTYPE html>
|
|||||||
.subscribe-form input{flex:1;padding:0.6rem 0.75rem;background:var(--bg);border:1px solid var(--border);border-radius:6px;color:var(--text);font-size:0.9rem}
|
.subscribe-form input{flex:1;padding:0.6rem 0.75rem;background:var(--bg);border:1px solid var(--border);border-radius:6px;color:var(--text);font-size:0.9rem}
|
||||||
.subscribe-form button{background:var(--gradient);color:white;border:none;padding:0.6rem 1.25rem;border-radius:6px;cursor:pointer;font-weight:600;font-size:0.9rem}
|
.subscribe-form button{background:var(--gradient);color:white;border:none;padding:0.6rem 1.25rem;border-radius:6px;cursor:pointer;font-weight:600;font-size:0.9rem}
|
||||||
</style>
|
</style>
|
||||||
|
<script async src="https://analytics.thetempleofdoom.com/script.js" data-website-id="{{ umami_id }}"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
@@ -1257,6 +1282,7 @@ SEARCH_TEMPLATE = """<!DOCTYPE html>
|
|||||||
.result p{color:var(--text-muted);font-size:0.88rem}
|
.result p{color:var(--text-muted);font-size:0.88rem}
|
||||||
footer{border-top:1px solid var(--border);padding:2rem 1.5rem;text-align:center;color:var(--text-muted);font-size:0.8rem}
|
footer{border-top:1px solid var(--border);padding:2rem 1.5rem;text-align:center;color:var(--text-muted);font-size:0.8rem}
|
||||||
</style>
|
</style>
|
||||||
|
<script async src="https://analytics.thetempleofdoom.com/script.js" data-website-id="{{ umami_id }}"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
@@ -1311,6 +1337,7 @@ TAG_TEMPLATE = """<!DOCTYPE html>
|
|||||||
footer{border-top:1px solid var(--border);padding:2rem 1.5rem;text-align:center;color:var(--text-muted);font-size:0.8rem}
|
footer{border-top:1px solid var(--border);padding:2rem 1.5rem;text-align:center;color:var(--text-muted);font-size:0.8rem}
|
||||||
a{color:var(--accent)}
|
a{color:var(--accent)}
|
||||||
</style>
|
</style>
|
||||||
|
<script async src="https://analytics.thetempleofdoom.com/script.js" data-website-id="{{ umami_id }}"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header><nav><a href="/" class="logo">{{ name }}</a></nav></header>
|
<header><nav><a href="/" class="logo">{{ name }}</a></nav></header>
|
||||||
@@ -1344,6 +1371,7 @@ NOT_FOUND_TEMPLATE = """<!DOCTYPE html>
|
|||||||
p{color:var(--text-muted);margin:1rem 0}
|
p{color:var(--text-muted);margin:1rem 0}
|
||||||
a{color:var(--primary)}
|
a{color:var(--primary)}
|
||||||
</style>
|
</style>
|
||||||
|
<script async src="https://analytics.thetempleofdoom.com/script.js" data-website-id="{{ umami_id }}"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
Reference in New Issue
Block a user