traffic_tracking.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import logging
  2. import os
  3. import pickle
  4. import threading
  5. import time
  6. from typing import Dict, Set
  7. from starlette.requests import Request
  8. from nicegui import ui
  9. VISITS_FILE = 'traffic_data/visits.pickle'
  10. SESSIONS_FILE = 'traffic_data/sessions.pickle'
  11. page_visits: Dict[int, int] = {}
  12. page_sessions: Dict[int, Set[str]] = {}
  13. def add_chart() -> ui.chart:
  14. def on_connect(request: Request):
  15. factor = 60 * 24
  16. today = int(time.time() / factor)
  17. page_visits[today] = page_visits.get(today, 0) + 1
  18. traffic_chart.options.series[0].data[:] = [[day * factor * 1000, count] for day, count in page_visits.items()]
  19. if not today in page_sessions:
  20. page_sessions[today] = set()
  21. page_sessions[today].add(request.session_id)
  22. traffic_chart.options.series[1].data[:] = [[day * factor * 1000, len(s)] for day, s in page_sessions.items()]
  23. traffic_chart.update()
  24. ui.on_connect(on_connect)
  25. ui.timer(10, save)
  26. load()
  27. traffic_chart = ui.chart({
  28. 'title': {'text': 'Traffic'},
  29. 'navigation': {'buttonOptions': {'enabled': False}},
  30. 'chart': {'type': 'line'},
  31. 'yAxis': {'title': False},
  32. 'xAxis': {
  33. 'type': 'datetime',
  34. 'labels': {'format': '{value:%e. %b}', },
  35. },
  36. 'series': [
  37. {'name': 'Views', 'data': []},
  38. {'name': 'Sessions', 'data': []},
  39. ],
  40. })
  41. traffic_chart.visible = len(page_visits.keys()) > 2 and len(page_sessions.keys()) > 2
  42. return traffic_chart
  43. def load() -> None:
  44. global page_visits, page_sessions
  45. os.makedirs(os.path.dirname(VISITS_FILE), exist_ok=True)
  46. os.makedirs(os.path.dirname(SESSIONS_FILE), exist_ok=True)
  47. try:
  48. with open(VISITS_FILE, 'rb') as f:
  49. page_visits = pickle.load(f)
  50. with open(SESSIONS_FILE, 'rb') as f:
  51. page_sessions = pickle.load(f)
  52. except FileNotFoundError:
  53. pass
  54. except:
  55. logging.exception("Error loading traffic data")
  56. def save() -> None:
  57. def _save():
  58. try:
  59. with open(VISITS_FILE, 'wb') as f:
  60. pickle.dump(page_visits, f)
  61. with open(SESSIONS_FILE, 'wb') as f:
  62. pickle.dump(page_sessions, f)
  63. except:
  64. logging.exception("Error saving traffic data")
  65. t = threading.Thread(target=_save, name="Save Traffic Data")
  66. t.start()