Skip to content

Commit d291f0e

Browse files
Merge pull request #20 from himanshusaxenagithub/cursor/site-activity-one-total-0636
Show one Site visitors total, not Opens and Users
2 parents 254a49e + 8e57d33 commit d291f0e

6 files changed

Lines changed: 36 additions & 33 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# Changelog
22

3+
## v0.7.5 — 2026-09-13
4+
5+
### Changed — one Site activity number
6+
7+
- The start page shows a single **Site visitors** figure: people who
8+
opened this website, per GoatCounter’s public counter. The Opens /
9+
Users pair is gone. That number is not “users” of the scanner.
10+
- Short note: approximate public total; not DoD adoption; not a count of
11+
people who downloaded or ran the scanner. A muted link points at the
12+
public GoatCounter page.
13+
314
## v0.7.4 — 2026-09-13
415

516
### Fixed — Site activity no longer trusts stale TOTAL.json

‎README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,12 @@ The [Used this?](docs/used.html) page stays as the optional public-note / GitHub
105105

106106
### GoatCounter (site activity)
107107

108-
The start page **Site activity** block shows approximate public GoatCounter totals: opens / pageviews and users / unique visitors. Those are website visits, not DoD adoption figures.
108+
The start page **Site activity** block shows one number, labeled **Site visitors**: people who opened this website, per GoatCounter’s public counter. That is not DoD adoption, and not a count of people who downloaded or ran the scanner. The public widget does not separate raw pageviews from unique visitors.
109109

110110
Set the site code in **one** place: `docs/site-config.js` → `goatcounterCode`. The committed code is `stig-hsaxena` (https://stig-hsaxena.goatcounter.com). `docs/site-chrome.js` then:
111111

112112
1. Injects `https://gc.zgo.at/count.js` with `data-goatcounter="https://stig-hsaxena.goatcounter.com/count"` on every page that includes the two scripts.
113-
2. Fills the landing totals from GoatCounter’s public site widget: parse `#gcvc-views` on `https://stig-hsaxena.goatcounter.com/counter/TOTAL.html`. `TOTAL.json` is a fallback, but that file can stay at 0 while the widget is correct. If both fail or JSON is 0, the page sums the public per-path JSON counters for `/`, `/index.html`, `/reviews.html`, `/demo.html`, `/evidence.html`, `/used.html`, and `/review-thanks.html`. GoatCounter publishes one visitor total — opens and users both show that number. If nothing works, the numbers stay `—`. Nothing is invented.
113+
2. Fills that one **Site visitors** figure from GoatCounter’s public site widget: parse `#gcvc-views` on `https://stig-hsaxena.goatcounter.com/counter/TOTAL.html`. `TOTAL.json` is a fallback, but that file can stay at 0 while the widget is correct. If both fail or JSON is 0, the page sums the public per-path JSON counters for `/`, `/index.html`, `/reviews.html`, `/demo.html`, `/evidence.html`, `/used.html`, and `/review-thanks.html`. If nothing works, the number stays `—`. Nothing is invented.
114114

115115
In GoatCounter settings, enable **Allow adding visitor counts on your website** (defaults to off). Making the dashboard public is optional; the JSON counter needs that visitor-counter flag.
116116

‎docs/evidence.html‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ <h2>What we do not claim</h2>
104104
<ul>
105105
<li>This project is <b>not</b> a Department of Defense or DISA product. Those organisations have not endorsed it. STIGs are public checklists DISA publishes; using the identifiers does not imply a relationship.</li>
106106
<li>GitHub stars, forks, watchers or traffic are <b>not</b> evidence of organisational adoption.</li>
107-
<li>The start page may show approximate public GoatCounter site activity (opens and users). Those are website visits, not DoD adoption, customer counts, or organisational use. We do not publish customer logos. Moderated <a href="reviews.html">reviews</a> appear only after manual approval; email addresses are never published. Optional notes can still go through <a href="used.html">Used this?</a>. This page invents none.</li>
107+
<li>The start page may show one approximate public GoatCounter <b>site visitors</b> total — people who opened pages on this website. That is not DoD adoption, and not a count of people who downloaded or ran the scanner. We do not publish customer logos. Moderated <a href="reviews.html">reviews</a> appear only after manual approval; email addresses are never published. Optional notes can still go through <a href="used.html">Used this?</a>. This page invents none.</li>
108108
<li>Sample or example-run figures labeled as sample data are <b>not</b> real clinic, school or company results.</li>
109109
<li>Selecting CAT I, or finishing a first scan, is <b>not</b> a claim that a system is “STIG compliant,” accredited, or safe.</li>
110110
<li>The tool finds configuration gaps. That is not a claim about hacking, exploits, or active attacks.</li>

‎docs/index.html‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -280,12 +280,11 @@ <h2>Which computer are you securing?</h2>
280280

281281
<div class="activity" id="site-activity">
282282
<h3>Site activity</h3>
283-
<p class="sub">Approximate public GoatCounter stats for this website. These are not Department of Defense adoption figures, customer counts, or organisational use.</p>
284283
<div class="stats">
285-
<div class="stat"><b data-stat="opens">—</b><span>Opens / pageviews — GoatCounter’s public visitor total</span></div>
286-
<div class="stat"><b data-stat="users">—</b><span>Users / unique visitors — same total, not a second metric</span></div>
284+
<div class="stat"><b data-stat="visitors">—</b><span>Site visitors</span></div>
287285
</div>
288-
<p class="muted" data-stat="note">Loading public stats…</p>
286+
<p class="sub">People who opened this site (GoatCounter).</p>
287+
<p class="muted" data-stat="note">Approximate public GoatCounter total. Not Department of Defense adoption, and not a count of people who downloaded or ran the scanner. A fuller path breakdown is on the <a href="https://stig-hsaxena.goatcounter.com">public GoatCounter page</a> if that site is viewable.</p>
289288
</div>
290289

291290
<details class="tech" id="tech-notes">

‎docs/site-chrome.js‎

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,10 @@
113113
async function fillSiteActivity() {
114114
const root = document.getElementById("site-activity");
115115
if (!root) return;
116-
const opensEl = root.querySelector("[data-stat=opens]");
117-
const usersEl = root.querySelector("[data-stat=users]");
116+
const visitorsEl = root.querySelector("[data-stat=visitors]");
118117
const noteEl = root.querySelector("[data-stat=note]");
119118
const dash = function () {
120-
if (opensEl) opensEl.textContent = "—";
121-
if (usersEl) usersEl.textContent = "—";
119+
if (visitorsEl) visitorsEl.textContent = "—";
122120
};
123121

124122
if (!goatConfigured()) {
@@ -135,20 +133,7 @@
135133
try {
136134
const got = await publicGoatTotal();
137135
if (!got) throw new Error("no public total");
138-
const shown = formatCount(got.n);
139-
if (opensEl) opensEl.textContent = shown;
140-
if (usersEl) usersEl.textContent = shown;
141-
if (noteEl) {
142-
const how = got.source === "html"
143-
? "from GoatCounter’s public site widget (#gcvc-views on TOTAL.html)"
144-
: got.source === "json"
145-
? "from GoatCounter’s TOTAL.json"
146-
: "from a sum of public per-page counters (TOTAL.json was 0 or unavailable)";
147-
noteEl.textContent =
148-
"Approximate public GoatCounter visitor total (" + how + "). " +
149-
"GoatCounter’s widget is one visitor figure — opens and users both show that number, " +
150-
"not two different metrics. Not DoD adoption figures.";
151-
}
136+
if (visitorsEl) visitorsEl.textContent = formatCount(got.n);
152137
} catch (e) {
153138
dash();
154139
if (noteEl) {

‎tests/test_site.py‎

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -454,10 +454,20 @@ def test_chrome_installs_goatcounter_and_fetches_public_totals(self):
454454
match = re.search(r'id=["\']gcvc-views["\'][^>]*>([^<]*)', snippet)
455455
self.assertEqual(match.group(1).strip(), "13")
456456

457-
def test_landing_labels_one_goatcounter_visitor_total(self):
457+
def test_landing_shows_one_visitor_total(self):
458458
html = (ROOT / "docs" / "index.html").read_text(encoding="utf-8")
459-
self.assertIn("same total, not a second metric", html)
460-
self.assertIn("GoatCounter’s public visitor total", html)
459+
landing = html.split('id="site-activity"', 1)[1].split('id="tech-notes"', 1)[0]
460+
self.assertIn('data-stat="visitors"', landing)
461+
self.assertIn("Site visitors", landing)
462+
self.assertIn("People who opened this site (GoatCounter).", landing)
463+
self.assertIn("not a count of people who downloaded or ran the scanner", landing)
464+
self.assertIn("https://stig-hsaxena.goatcounter.com", landing)
465+
self.assertNotIn("data-stat=\"opens\"", landing)
466+
self.assertNotIn("data-stat=\"users\"", landing)
467+
self.assertNotIn("same total, not a second metric", landing)
468+
self.assertNotIn("Opens / pageviews", landing)
469+
self.assertNotIn("Users / unique visitors", landing)
470+
self.assertNotIn("Visitors/Users", landing)
461471

462472
def test_docs_pages_include_the_shared_goatcounter_config(self):
463473
for name in CONTACT_PAGES:
@@ -469,11 +479,9 @@ def test_landing_has_honest_site_activity_section(self):
469479
html = (ROOT / "docs" / "index.html").read_text(encoding="utf-8")
470480
self.assertIn('id="site-activity"', html)
471481
self.assertIn("Site activity", html)
472-
self.assertIn("data-stat=\"opens\"", html)
473-
self.assertIn("data-stat=\"users\"", html)
474-
self.assertIn("pageviews", html.lower())
475-
self.assertIn("unique visitors", html.lower())
476-
self.assertIn("not Department of Defense adoption", html)
482+
self.assertIn("data-stat=\"visitors\"", html)
483+
self.assertIn("Site visitors", html)
484+
self.assertIn("Not Department of Defense adoption", html)
477485
self.assertIn("—", html)
478486
self.assertNotIn("countapi", html.lower())
479487

0 commit comments

Comments
 (0)