Commit Graph
125 Commits
Author SHA1 Message Date
LeoVasanko 8b1bb6f994 Avoid column break right after heading. 2026-08-25 22:31:52 +00:00
LeoVasanko 3173a113b6 Improved theme banner consistency across themes. 2026-08-25 22:29:28 +00:00
LeoVasanko a21f919601 More robust admin check, only adding edit pens after probe completes. 2026-08-24 21:51:35 +00:00
LeoVasanko 158b5f1961 Editor panel layout fixes, use body scroll and bidirectional sync with editor. v0.4.6 2026-08-24 21:41:33 +00:00
LeoVasanko f9ce0a4f3b Smarter initial analytics page when there is no visitor data yet. 2026-08-24 21:13:20 +00:00
LeoVasanko 2d595f8c15 Reduce #brand to actual size, avoid clicks on empty banner space touching it. v0.4.5 2026-08-24 20:58:50 +00:00
LeoVasanko b1fc8e24d7 Eyes banner follows taps not just mouse. 2026-08-24 20:54:50 +00:00
LeoVasanko c5cf799f68 Better nav layout for portrait phones. 2026-08-24 20:43:18 +00:00
LeoVasanko a5edc7b3b6 Fix crawler misclassification from /_a and orphan counts on visit scrub
Two analytics corrections verified against the production capture:

- pagerite.js suppressed pings with fr == '/_a', but fetch-navigation
  away from the analytics page had already GET-ed the target without the
  preload header; the orphaned pending hit then flushed to the crawler
  list, classifying a real user as a crawler. Navigations away from /_a
  now ping normally (the server rejects /_a as a target regardless, and
  admin noise is already handled by hide=1).

- _remove_visit only reversed the visit's creation counts, leaving
  views/transitions from later pings behind as orphans on the graph with
  no matching row in the visitor table. An in-memory per-visit count log
  now tracks every count event, so an admin hide=1 scrub reverses the
  visit completely.
2026-08-24 20:18:13 +00:00
LeoVasanko 09ebc63690 Record response status per path; mark 404 trails red in the viewer
Document GETs now stash their status (200/404) in a pending table,
consumed by the matching ping: visits gain a per-path statuses map and
crawler hits a status field. Trail links with a 404 status render in
red with the status code in the tooltip, alongside the read time.
v0.4.4
2026-08-24 19:43:23 +00:00
LeoVasanko 2868843028 Fix inverted client filter in admin hide ping
The hide=1 branch kept the admin's own pending crawler hits (==) instead
of discarding them (!=), so an admin's document GETs flushed to the
crawler list 10s later while every other client's pending hits were
wrongly dropped. This is why ordinary admin browsers showed up as
crawlers.
2026-08-24 19:40:12 +00:00
LeoVasanko 6fcebaea3f Transition map: svg-scaled fonts, border-clipped pill text, tight crop
- Fonts scale with the svg instead of the --u constant-screen-size
  compensation (ResizeObserver machinery removed)
- Larger node text (slug 19px, count 15px)
- Pill labels no longer ellipsis-truncated: text is clipped at the pill
  border via per-node clipPaths; captions center when they fit and anchor
  left on overflow so the title's beginning survives; count lines stay
  centered
- Bounding box crops to pill half extents plus the ribbon halo instead of
  the diagonal radius, removing the large top/bottom margins
2026-08-24 18:35:36 +00:00
LeoVasanko 4a48d08a19 Analytics layout: larger charts with natural-width cap, one-line totals
- Charts grow to a larger intrinsic size (1052x174) and never upscale
  past it; centered with equal side margins above the cap, full width
  below, svg always within page bounds; overflow visible so wider fonts
  don't clip at the viewBox edge
- Totals row aligns its left edge with the charts and shrinks (gap first,
  then font) via container units to always stay on one line
2026-08-24 18:21:58 +00:00
LeoVasanko e3e29251ca Transition map: cull invisible connectors, stable beads, lane labels
- Cull connections whose thin middle would render below ~0.8px
  (MIN_WMID); drop external source/exit nodes whose connectors are
  all culled, while site page nodes always stay
- Bead simulation persists across data reloads: emitters keyed per edge
  direction, beads tracked by progress, so unrelated count changes no
  longer reshuffle bead positions
- Bead speed relative to span length: constant 1.5s traversal per edge
- Top lane labeled with a house icon; all lane labels left-aligned just
  past the source pill (half height on near-vertical branch lanes), with
  guides running to the lane end so long slugs are never truncated
2026-08-24 17:58:02 +00:00
LeoVasanko 8affc41289 Tighter analytics chart chrome
- Unified chart text at 11px system-ui; fixed size independent of theme font
- Day view y axis reads "visits / 5 min" / "views / 5 min"
- Left margin and y tick spacing tightened (MARGIN_L 56 -> 40)
- Gap between visits and views charts removed
- Legend repositioned for the larger font
2026-08-24 17:26:30 +00:00
LeoVasanko 2de4717230 Fix week overlay alignment, in-plot ISO week legend, shorter charts
- weeklySeries shifts overlaid weeks onto the current week's time axis so
  they overlay inside the plot instead of overflowing left; oldest weeks
  paint first, current week on top
- Legend moved inside the visits chart's top right: current ISO week in
  accent, past weeks as a single muted "Week M" / "Week M–N" specimen
- Past week curves use the muted color instead of faded accent
- Chart height reduced ~30% (180 -> 126)
2026-08-24 17:03:49 +00:00
LeoVasanko 563e8fcaf2 Rework analytics chart scaling; self-contained SVG charts
- Charts render as single SVGs with axis labels inside the viewBox,
  replacing the stretched plot + HTML overlay labels
- Rolling ranges end at now, t0 aligned to UTC day; bucket size follows
  the window (6h up to 31 days) so "all" at its 30-day minimum renders
  identically to "month"
- X labels always centered on their true position; no edge-align shifting
- rangeWindow simplified to rolling spans ending at now
- TransitionGraph "all" visual scale floored at the 30-day plot minimum
2026-08-24 12:31:25 +00:00
LeoVasanko 921a5484a2 Fixed-sigma smoothing of traffic history plots. 2026-08-24 05:54:43 +00:00
LeoVasanko 0e2e52fa45 Use last 24h/7d/30d/365d/all analytics data. Previously some fields were unfiltered and weekly view was based on calendar weeks. 2026-08-24 05:42:32 +00:00
LeoVasanko 075848f782 Crawlers should include all sorts of spiders along with bots and googleother. 2026-08-24 05:28:05 +00:00
LeoVasanko 7b8899af92 Transition map: bounded node scaling, concentric branch lanes, exit row at bottom 2026-08-24 04:47:06 +00:00
LeoVasanko 6d2ae104d7 Fix analytics classification: ignore bot-UA pings, skip preload GETs.
JS-running crawlers (Googlebot, GoogleOther, Applebot) execute pagerite.js
and send navigation pings, registering as visitors. Pings whose User-Agent
matches _is_bot_ua (any "bot" token plus listed exceptions) are now
ignored, so their document GETs flush to the crawler list as intended. No
source verification: a spoofed bot UA merely lands in the crawler stats,
and path-based abuse classification catches scanners regardless.

Idle-time link preloads from pagerite.js were queued as pending crawler
hits and flushed to the crawler list whenever the user navigated more than
10s later, so real visitors' subpage loads showed up as crawler hits.
Preload fetches now carry an x-pagerite-preload header and the document
GET handler skips tracking for them; the ping sent on actual navigation
does the counting.
v0.4.3
2026-08-22 18:23:38 +00:00
LeoVasanko b7fc543a83 Transition graph layout follows navigation. 2026-08-22 18:10:44 +00:00
LeoVasanko b868033ddc Pill shaped nodes 2026-08-22 15:48:33 +00:00
LeoVasanko 8aad64cced Analytics layout update, larger, consistent text sizing. 2026-08-22 14:45:56 +00:00
LeoVasanko 319163ee7e Page caching and zstd compression. Avoid useless fetching. Mobile layouts of navigation menus improved. 2026-08-22 14:05:12 +00:00
LeoVasanko 87b16b7144 Implement /robots.txt and /sitemap.xml. Update dev proxy to all-by-default. 2026-08-22 12:13:17 +00:00
LeoVasanko 20ae6501f2 Add dynamic /sitemap.xml and /robots.txt endpoints 2026-08-22 12:01:18 +00:00
LeoVasanko a16fe88114 Auto select day if less than 24h data for new sites. 2026-08-22 01:51:36 +00:00
LeoVasanko c77598adc7 Fine tuning date formatting. 2026-08-22 00:09:57 +00:00
LeoVasanko 29f8fac013 Slightly prettier analytics URL v0.4.2 2026-08-21 23:58:00 +00:00
LeoVasanko 6199e5a69e Support for UTM tags in transition graph as source sites. 2026-08-21 23:50:01 +00:00
LeoVasanko 375b4b6bdb analytics: unify visitor cell across visits, crawlers and abuse tables 2026-08-21 23:32:46 +00:00
LeoVasanko fdb3e42d6f analytics: shared Client struct, grouped abuse paths, unified visitor cell 2026-08-21 23:16:15 +00:00
LeoVasanko 51a6a16221 Neater abuse table formatting. 2026-08-21 22:31:37 +00:00
LeoVasanko 0798e24d24 Desaturated house emojis 2026-08-21 22:03:55 +00:00
LeoVasanko 3be2d08ac9 SI formatting of large visitor numbers. 2026-08-21 21:36:57 +00:00
LeoVasanko b7d5b23ae6 Cleaner formatting of utm tags in visitor table. 2026-08-21 21:22:16 +00:00
LeoVasanko 6eaa1c1a8b analytics: 24h day view with bar chart for precise realtime stats. Tables redesigned with cleaner layout. Tracking article read times. Adjust connection graph visualizations by time range. Other cleanup and supporting systems. 2026-08-21 20:14:04 +00:00
LeoVasanko f341d22aa0 Improved fake traffic generation with abuse bots, utm tags etc. 2026-08-21 20:10:41 +00:00
LeoVasanko 1a479ceb24 Add --dbip CLI flag to auto-download/update the DB-IP MMDB database.
Downloads the latest dbip-city-lite-YYYY-MM.mmdb.gz before starting the
server, skipping when the local database is current, falling back to the
previous month on 404, and removing older databases after an update.
Promotes httpx to a runtime dependency.
v0.4.1
2026-08-21 03:09:04 +00:00
LeoVasanko ff553d018a Default scheme, host and port for fake_traffic script. 2026-08-21 02:52:53 +00:00
LeoVasanko c807d48a13 Add more external content in seed data. 2026-08-21 02:50:36 +00:00
LeoVasanko 9c383c1c8b Change default port mapping to 8100/8200/8210 (prod/vite/dev). Vite gets different port to avoid caching problems when switching between it and prod. 2026-08-21 02:49:18 +00:00
LeoVasanko 462e995adc Add external link (referer/outgoing) display on connection graph. 2026-08-21 02:44:54 +00:00
LeoVasanko ea069b98da Fix analytics app not mounting on fetch-navigation to /_a
load() queried the live document for the pagerite:analytics-src meta,
but the swap never touches <head> — the meta only exists in the fetched
doc, so the app never mounted unless /_a was loaded directly. Also cache
the fetched HTML so the post-swap preload doesn't re-GET the page we
just navigated to.
2026-08-21 01:53:39 +00:00
LeoVasanko deb5419c47 analytics improvements:
- keep visitor charts y-axis minimum range at 10
- keep 'all' chart x-axis minimum span at 30 days
- group crawler hits by (ip, ua) and list top pages visited, show crawler page load counts as N× prefix
- store and display geoip city, keep geoip country overwrite
- stream live updates over WebSocket /_api/ws/analytics
- include family ring arcs in transition map crop bounds
- remove top UA summary, limit crawlers to 10 and visits to 20
- human-readable relative timestamps with UTC tooltip
2026-08-21 01:36:58 +00:00
LeoVasanko 242b62784c Add fake traffic generator script
Uses Playwright to drive Chromium through real internal link clicks,
so pagerite.js analytics pings create normal visits. Also fires HTTP
GETs with crawler user-agents to record crawler hits.

Features:
- script-local deps via uv add --script (playwright, httpx)
- rotating pool of real public IPs via X-Forwarded-For
- Poisson inter-arrival delays between sessions/hits
- configurable browsers, crawlers, clicks, and dwell time
v0.4.0
2026-08-20 23:37:02 +00:00
LeoVasanko f78229bd30 Refactor analytics to /_a instead of under article pages. 2026-08-20 23:16:51 +00:00
LeoVasanko 7f4bc8efa4 Ignore devserver health probe in analytics tracking
The devserver polls /?from=devserver.py to check backend readiness.
Without this exclusion each poll is recorded as a crawler hit. Only
exclude the exact case: front page, that query string, and 127.0.0.1,
so remote visitors cannot hide traffic by copying the parameter.
2026-08-20 22:16:11 +00:00