Visitor counter #101

Open
opened 2026-01-15 20:05:53 +00:00 by ian · 1 comment
Owner

From S50U:

Would adding a simple counter to the footer pose any problems? Adding visitors.py below.

<p class="col-md-4 mb-0 text-body-secondary text-center small">

{{ unique_visits }} unique visits

</p>

import json
import time
import threading
import logging
from pathlib import Path

logger = logging.getLogger(name)

VISITS_FILE = Path("data/visits.json")
TIMER_VISIT = 300

try:
with open(VISITS_FILE) as f:
visits = json.load(f)
except (FileNotFoundError, json.JSONDecodeError):
visits = {}

def register_visit(ip: str):
visits[ip] = int(time.time())

def unique_visits_count() -> int:
return len(visits)

def save_visits():
VISITS_FILE.parent.mkdir(parents=True, exist_ok=True)
with open(VISITS_FILE, "w") as f:
json.dump(visits, f)
logger.info("Visits saved")

def schedule_save():
save_visits()
threading.Timer(TIMER_VISIT, schedule_save).start()

schedule_save()

From S50U: Would adding a simple counter to the footer pose any problems? Adding visitors.py below. &lt;p class="col-md-4 mb-0 text-body-secondary text-center small"&gt; <i class="fa-solid fa-users me-1"></i> <strong>{{ unique_visits }}</strong> unique visits &lt;/p&gt; import json import time import threading import logging from pathlib import Path logger = logging.getLogger(__name__) VISITS_FILE = Path("data/visits.json") TIMER_VISIT = 300 try: with open(VISITS_FILE) as f: visits = json.load(f) except (FileNotFoundError, json.JSONDecodeError): visits = {} def register_visit(ip: str): visits[ip] = int(time.time()) def unique_visits_count() -> int: return len(visits) def save_visits(): VISITS_FILE.parent.mkdir(parents=True, exist_ok=True) with open(VISITS_FILE, "w") as f: json.dump(visits, f) logger.info("Visits saved") def schedule_save(): save_visits() threading.Timer(TIMER_VISIT, schedule_save).start() schedule_save()
Author
Owner

Queried code example with S50U as it looks incomplete, e.g. the template snipped includes a variable called unique_visits but the code doesn't define it anywhere. Nevertheless, the general approach looks fine for the purpose.

Note that the Spothole privacy policy currently states "Spothole collects no data about you... There are no trackers". This would have to be weakened if this tracking code were implemented. I therefore suggest that this should be an option in config, and if enabled the privacy statement should be altered for that server.

Queried code example with S50U as it looks incomplete, e.g. the template snipped includes a variable called unique_visits but the code doesn't define it anywhere. Nevertheless, the general approach looks fine for the purpose. Note that the Spothole privacy policy currently states "Spothole collects no data about you... There are no trackers". This would have to be weakened if this tracking code were implemented. I therefore suggest that this should be an option in config, and if enabled the privacy statement should be altered for that server.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ian/spothole#101
No description provided.