- A room opened with Play now never loads /join: the API's answer to POST /api/rooms is counted as rooms opened here. - Link previews (Slack, Discord, Facebook, iMessage, WhatsApp and the rest) are reported as where the link was shared, since the people who click them arrive with no referrer. WhatsApp's fetcher is a bot now. - An address that asks for a scanner's paths, or keeps coming back without opening a game, is a bot's all day; so is a browser that loads pages at a steady interval from a new address each time, never playing. A declared bot is still judged request by request. - The site's own addresses, sslip.io included, are not referrers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
36 lines
1.7 KiB
Bash
Executable File
36 lines
1.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# The hall's visitors: who came in the last hour and today, where from, how
|
|
# many went on into each game here, and the last week from the rollup.
|
|
# Runs ON the shared host: gamehall-visitors.sh [YYYY-MM-DD] (default: today, UTC)
|
|
set -u
|
|
DAY="${1:-$(date -u +%F)}"
|
|
python3 - "$DAY" <<'PY'
|
|
import datetime, json, os, sys
|
|
sys.path.insert(0, "/usr/local/lib/gamehall")
|
|
import traffic
|
|
|
|
day = sys.argv[1]
|
|
now = datetime.datetime.now(datetime.timezone.utc)
|
|
print("as of %s UTC, day %s" % (now.strftime("%H:%M"), day))
|
|
|
|
if day == now.strftime("%F"):
|
|
h = traffic.scan(day, since=now.timestamp() - 3600)
|
|
print("last hour: %d people, %d page views" % (len(h["addresses"]), h["views"]))
|
|
|
|
t = traffic.scan(day)
|
|
print("today: %d people, %d page views, %d bot addresses (of them %d scanners, %d monitors)" % (len(t["addresses"]), t["views"], len(t["botAddresses"]), t["scanners"], t["monitors"]))
|
|
print("shared on: %s" % (dict(t["shared"].most_common()) or "none"))
|
|
print("referrers: %s" % (dict(t["referrers"].most_common()) or "none"))
|
|
print("campaigns: %s" % (dict(t["campaigns"].most_common()) or "none"))
|
|
print("went on to: %s (Wiz-War is on its own host; its digest shows the hall as a referrer)" % (", ".join("%s %d" % kv for kv in t["sent"].items())))
|
|
|
|
out = "/var/lib/gamehall/rollup.jsonl"
|
|
if os.path.exists(out):
|
|
rows = [json.loads(l) for l in open(out) if l.strip()][-7:]
|
|
if rows:
|
|
print("last %d days:" % len(rows))
|
|
for r in rows:
|
|
sent = ", ".join("%s %d" % kv for kv in r.get("sent", {}).items())
|
|
print(" %s %3d people %3d views refs %s on to %s" % (r["day"], r["people"], r["views"], r.get("referrers") or "-", sent or "-"))
|
|
PY
|