{"id":18388187,"url":"https://github.com/ccnmtl/django-pagetimer","last_synced_at":"2025-04-12T04:23:11.811Z","repository":{"id":57421161,"uuid":"58394973","full_name":"ccnmtl/django-pagetimer","owner":"ccnmtl","description":"simple page timing","archived":false,"fork":false,"pushed_at":"2017-08-30T19:32:25.000Z","size":24,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-19T08:39:43.254Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ccnmtl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-05-09T17:25:37.000Z","updated_at":"2016-05-09T17:25:51.000Z","dependencies_parsed_at":"2022-08-28T16:20:29.434Z","dependency_job_id":null,"html_url":"https://github.com/ccnmtl/django-pagetimer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ccnmtl%2Fdjango-pagetimer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ccnmtl%2Fdjango-pagetimer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ccnmtl%2Fdjango-pagetimer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ccnmtl%2Fdjango-pagetimer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ccnmtl","download_url":"https://codeload.github.com/ccnmtl/django-pagetimer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248514668,"owners_count":21117005,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T01:32:12.869Z","updated_at":"2025-04-12T04:23:11.792Z","avatar_url":"https://github.com/ccnmtl.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/ccnmtl/django-pagetimer.svg?branch=master)](https://travis-ci.org/ccnmtl/django-pagetimer)\n[![Coverage Status](https://coveralls.io/repos/github/ccnmtl/django-pagetimer/badge.svg?branch=master)](https://coveralls.io/github/ccnmtl/django-pagetimer?branch=master)\n\n# django-pagetimer\n\nSimple but effective endpoint for tracking users' time spent on pages.\n\n## background\n\nOften, we have clients ask to see metrics on how long users spent on\neach page of the application. Tracking that *properly* in the wild is\nactually really difficult and comes with a lot of caveats (eg, we can\ntell if they have the browser open to the page, but not that someone\nis actually looking at it; they may have wandered off with the tab\nopen).\n\nThis library provides a django app that implements a simple, but\nsurprisingly effective approach to solving that problem in the general\ncase.\n\nAt its core, there's a templatetag that inserts a bit of JS (with no\ndependencies) that just does a heartbeat back to an endpoint once\nevery 60s (configurable). The backend endpoint stores an entry with\nusername, session id, ipaddress, path, and a timestamp. From there,\nreports can be generated and timelines reconstructed with a reasonable\naccuracy (commensurate with the amount of effort required to\nimplement).\n\nMuch more accurate and complex approaches can be taken, but in my\nexperience, this is good enough to drop in quickly and get started. It\ncreates one DB entry per user per minute by default, which is unlikely\nto blow up your database usage too quickly. The approach encourages\nyou to just pull down CSVs for offline processing. Once you've been\nusing something like this for a while, you may have a better idea of\nwhere you need more precision in your tracking, but this will help you\nget there.\n\n## installation\n\n```\n$ pip install django-pagetimer\n```\n\nThen add `pagetimer` to your `INSTALLED_APPS` and include\n`('pagetimer/', include('pagetimer.urls'))`, in you `urls.py`.\n\nNext, in your `base.html`, include `{% load pagetimertags %}` and,\npreferably near the end of the `\u003chead\u003e`, insert a `{% pagetimer %}`.\n\nNow, anytime a user is on any page of your site, their browser will\nping the pagetimer endpoint once every 60s and it will log it.\n\nYou can set `PAGETIMER_INTERVAL` to the number of seconds between\nheartbeats. Default is 60 seconds.\n\nBy default, all visits are kept until they are manually purged. This\nis probably a bad idea if you get much traffic and aren't actively\nmonitoring DB size. So pagetimer includes two different retention\npolicies that you can enable:\n\n`PAGETIMER_MAX_RETENTION_INTERVAL` can be set to a\n`datetime.timedelta`. Any entries further back than that will\nautomatically be dropped. Eg:\n\n```\nfrom datetime import timedelta\nPAGETIMER_MAX_RETENTION_INTERVAL = timedelta(days=7)\n```\n\nWill drop entries after a week.\n\n`PAGETIMER_MAX_RETENTION_COUNT` can be set to a maximum count of\nentries to keep. This is good as a last-ditch limit. You can set both\nof them.\n\n## features\n\n* simple admin dashboard to see recent visits\n* admin view for downloading CSV dumps\n* admin function for clearing out older entries (to free up disk space\nin the DB)\n\n## coming soon\n\n* js will only heartbeat to the endpoint if the tab is visible (via\n  [Page Visibility API](https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API))\n* admin view for downloading *anonymized* CSV dumps (with username,\nipaddress anonymized)\n* pluggable backend architecture. The existing DB model will be one\n  (and probably the default) model. A simple textfile appending\n  backend will be added and there will be a nice interface for\n  implementing, eg, an ElasticSearch backend.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fccnmtl%2Fdjango-pagetimer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fccnmtl%2Fdjango-pagetimer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fccnmtl%2Fdjango-pagetimer/lists"}