{ "info": { "author": "Aron Griffis", "author_email": "aron@scampersand.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6" ], "description": "================\nDjango Souvenirs\n================\n\n|PyPI| |Build Status| |Coverage Report|\n\nHow active are users on your Django site? Django can tell you when users\nregistered (``User.date_joined``) and when they signed in (``User.last_login``).\nBut sessions are long-lived so this doesn't really answer the question.\n\nSouvenirs is a Django app for efficiently measuring user activity over time, and\nmaking that information available through an API.\n\n|Souvenirs Album Cover|\n\nInstallation\n------------\n\nGet the latest stable release from PyPI_\n\n.. code-block:: bash\n\n pip install django-souvenirs\n\nOr the latest commit from GitHub\n\n.. code-block:: bash\n\n pip install -e git+git://github.com/appsembler/django-souvenirs.git#egg=souvenirs\n\nAdd to ``settings.py``\n\n.. code-block:: python\n\n INSTALLED_APPS += [\n 'souvenirs',\n ]\n MIDDLEWARE_CLASSES += [\n 'souvenirs.middleware.SouvenirsMiddleware',\n ]\n\nMigrate your database\n\n.. code-block:: bash\n\n ./manage.py migrate souvenirs\n\nUsage\n-----\n\nThere are two core API calls: ``souvenez`` (\"remember\") and\n``count_active_users``.\n\nYou can call ``souvenez(user)`` as often per user as you'd like, by default it\nwill rate-limit DB entries to once per hour. If you use the provided middleware,\nthen ``souvenez`` will be called automatically on each request.\n\nCall ``count_active_users`` to find the number of unique users active for a\ngiven time period. For example::\n\n >>> from souvenirs.control import count_active_users\n >>> from django.utils import timezone\n >>> from datetime import timedelta\n >>> now = timezone.now()\n >>> count_active_users(start=now - timedelta(days=1), end=now)\n 42\n\nEither ``start`` or ``end`` can be omitted, which makes the query unbounded in\nthat direction. The above call is effectively the same as omitting ``end``::\n\n >>> count_active_users(start=timezone.now() - timedelta(days=1))\n 42\n\nand this counts the total number of users active for all time, or at least since\nyou installed the middleware::\n\n >>> count_active_users()\n 1012\n\nReports\n-------\n\nSouvenirs provides some functions for reporting registered users and activity\nover a period of time. For example, to see activity per calendar month for 2016::\n\n >>> from datetime import datetime\n >>> from django.utils import timezone\n >>> from souvenirs.reports import calendar_monthly_usage\n >>> start = datetime(2016, 1, 1) # inclusive\n >>> end = datetime(2017, 1, 1) # exclusive\n >>> for d in calendar_monthly_usage(start=timezone.make_aware(start),\n end=timezone.make_aware(end)):\n ... print(d['labels']['calendar_year_month'],\n d['usage']['registered_users'],\n d['usage']['activated_users'], # User.is_active\n d['usage']['active_users'])\n 2016-01 12 10 9\n 2016-02 20 13 11\n 2016-03 38 16 10\n 2016-04 38 28 14\n 2016-05 38 29 20\n 2016-06 57 46 37\n 2016-07 62 58 43\n 2016-08 117 80 49\n 2016-09 175 300 75\n 2016-10 280 333 89\n 2016-11 420 360 99\n 2016-12 588 540 151\n\nSee `reports.py`_ for additional reporting functions, especially for starting\nsubscriptions on arbitrary days (instead of calendar months).\n\n.. _reports.py: https://github.com/appsembler/django-souvenirs/blob/master/souvenirs/reports.py\n\nSettings\n--------\n\nSouvenirs uses hopefully sane defaults for all settings. Here's what you can\noverride if you want:\n\n``SOUVENIRS_RATELIMIT_SECONDS``: how often to record an active user in the DB,\ndefault ``3600``\n\n``SOUVENIRS_CACHE_NAME``: which cache to use for rate-limiting,\ndefault ``'default'``\n\n``SOUVENIRS_CACHE_PREFIX``: how to prefix rate-limiting cache entries,\ndefault ``'souvenirs.'``\n\n``SOUVENIRS_USAGE_REPORTS_FUNCTION``: all the reporting functions call a\nlow-level function ``usage_for_periods``. This can be overridden (probably\nwrapped) if you'd like to use the souvenirs reporting functions to generate\nricher data, for example incorporating some other data per time period.\n\nContributing\n------------\n\nTo contribute to this project, fork to your own github user, make your changes\non a branch, run the tests and open a pull request. If you have hub_ and tox_\ninstalled, it's like this:\n\n.. code-block:: bash\n\n hub clone appsembler/django-souvenirs\n cd django-souvenirs\n git checkout -b my-awesome-feature\n # hack hack hack!\n tox --skip-missing-interpreters\n git commit -am \"my awesome commit\"\n hub fork # for example agriffis/django-souvenirs\n git push --set-upstream agriffis # insert your github user here\n hub pull-request\n\nLegal\n-----\n\nCopyright 2017 `NodeRabbit Inc., d.b.a. Appsembler `_\n\nReleased under the `MIT license `_\n\n.. _PyPI: https://pypi.python.org/pypi/django-souvenirs\n\n.. |Build Status| image:: https://img.shields.io/travis/appsembler/django-souvenirs/master.svg?style=plastic\n :target: https://travis-ci.org/appsembler/django-souvenirs?branch=master\n\n.. |Coverage Report| image:: https://img.shields.io/codecov/c/github/appsembler/django-souvenirs/master.svg?style=plastic\n :target: https://codecov.io/gh/appsembler/django-souvenirs/branch/master\n\n.. |PyPI| image:: https://img.shields.io/pypi/v/django-souvenirs.svg?style=plastic\n :target: PyPI_\n\n.. |Souvenirs Album Cover| image:: https://images-na.ssl-images-amazon.com/images/I/51UhpUAIRaL._SS500.jpg\n :target: https://www.amazon.com/Souvenirs-Reinhardt-Quintet-St%C3%A9phane-Grappelli/dp/B000VWONGE\n\n.. _hub: https://hub.github.com/\n\n.. _tox: https://pypi.python.org/pypi/tox\n", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/appsembler/django-souvenirs", "keywords": "django", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "django-souvenirs", "package_url": "https://pypi.org/project/django-souvenirs/", "platform": "OS Independent", "project_url": "https://pypi.org/project/django-souvenirs/", "project_urls": { "Homepage": "https://github.com/appsembler/django-souvenirs" }, "release_url": "https://pypi.org/project/django-souvenirs/1.0.2/", "requires_dist": null, "requires_python": "", "summary": "Django app for efficiently measuring usage", "version": "1.0.2" }, "last_serial": 2754797, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "7215ff1eb287fa07ded553b9adceba76", "sha256": "38766855c503e548915bdd6741149677be75fb165b19439b40a7245c0e52ebb8" }, "downloads": -1, "filename": "django-souvenirs-0.1.tar.gz", "has_sig": false, "md5_digest": "7215ff1eb287fa07ded553b9adceba76", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16304, "upload_time": "2017-04-04T11:59:16", "url": "https://files.pythonhosted.org/packages/44/89/c961e6ab58910cd58d2a7cbd255a813b991157a42ff92d96dc29c51f0c23/django-souvenirs-0.1.tar.gz" } ], "1.0.0": [ { "comment_text": "", "digests": { "md5": "16224113e9b3ff5f2a6781beaefcb95d", "sha256": "ce5bd206b43814bd39b594f73a90d41ee83532a4860bf5ec5d641369e970fc14" }, "downloads": -1, "filename": "django-souvenirs-1.0.0.tar.gz", "has_sig": false, "md5_digest": "16224113e9b3ff5f2a6781beaefcb95d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16305, "upload_time": "2017-04-04T12:00:26", "url": "https://files.pythonhosted.org/packages/e9/b2/8914f13df79b97697cd2639ede4f23cbd40c0773d9981d88f7cc50ecf691/django-souvenirs-1.0.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "04b3384f3df4dffff84ba72f398227b6", "sha256": "0801ba292990027fc91f33ebc09b548bf41e9a8dadb9c6ddec46e76426e6d0aa" }, "downloads": -1, "filename": "django-souvenirs-1.0.1.tar.gz", "has_sig": false, "md5_digest": "04b3384f3df4dffff84ba72f398227b6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16330, "upload_time": "2017-04-04T15:34:55", "url": "https://files.pythonhosted.org/packages/9a/8a/5c2836db7ddc4cd4dfd60a2ac5cf44f482de6a94d21d8164a2ec4bac6288/django-souvenirs-1.0.1.tar.gz" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "0ce18f016bb18864aeddc12c9989da43", "sha256": "bdb6102008fe9887acb6f70abe36e5b780500e5d679600ca43959eb4136998d5" }, "downloads": -1, "filename": "django-souvenirs-1.0.2.tar.gz", "has_sig": false, "md5_digest": "0ce18f016bb18864aeddc12c9989da43", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16324, "upload_time": "2017-04-05T12:18:47", "url": "https://files.pythonhosted.org/packages/f2/26/05c1ae6aed3c39cfcaf9f4f8d9f1e365822cf709d542d7a6303457cd53b3/django-souvenirs-1.0.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "0ce18f016bb18864aeddc12c9989da43", "sha256": "bdb6102008fe9887acb6f70abe36e5b780500e5d679600ca43959eb4136998d5" }, "downloads": -1, "filename": "django-souvenirs-1.0.2.tar.gz", "has_sig": false, "md5_digest": "0ce18f016bb18864aeddc12c9989da43", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16324, "upload_time": "2017-04-05T12:18:47", "url": "https://files.pythonhosted.org/packages/f2/26/05c1ae6aed3c39cfcaf9f4f8d9f1e365822cf709d542d7a6303457cd53b3/django-souvenirs-1.0.2.tar.gz" } ] }