diff options
author | Donald Stufft <donald@stufft.io> | 2013-06-26 23:36:50 -0400 |
---|---|---|
committer | Donald Stufft <donald@stufft.io> | 2013-06-26 23:36:50 -0400 |
commit | 471874691f8cf8011b39ad1092688ceea03beebc (patch) | |
tree | 022c9414da89dd9da096390b08f138fbfaec3703 | |
parent | 02197b38e0f854f88ec4a52ee3fe3ad5db471b99 (diff) | |
download | decorator-471874691f8cf8011b39ad1092688ceea03beebc.tar.gz |
Enable (hidden) download counts
-rw-r--r-- | config.ini.template | 1 | ||||
-rw-r--r-- | config.py | 2 | ||||
-rw-r--r-- | requirements.txt | 1 | ||||
-rw-r--r-- | templates/display.pt | 14 | ||||
-rw-r--r-- | webui.py | 42 |
5 files changed, 59 insertions, 1 deletions
diff --git a/config.ini.template b/config.ini.template index 318bab5..de40a66 100644 --- a/config.ini.template +++ b/config.ini.template @@ -7,6 +7,7 @@ user = pypi files_dir = /MacDev/svn.python.org/pypi-pep345/files docs_dir = /MacDev/svn.python.org/pypi-pep345/docs package_docs_url = http://pythonhosted.org/ +redis_url = redis://localhost:6379/0 [webui] mailhost = mail.python.org @@ -71,6 +71,8 @@ class Config: self.fromaddr = c.get('logging', 'fromaddr') self.toaddrs = c.get('logging', 'toaddrs').split(',') + self.redis_url = c.get('database', 'redis_url') + self.sentry_dsn = c.get('sentry', 'dsn') self.passlib = CryptContext( diff --git a/requirements.txt b/requirements.txt index 9760e5d..2397c62 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,6 +10,7 @@ py-bcrypt==0.3 python-openid==2.2.5 pytz==2013b raven==3.3.7 +redis==2.7.6 requests==1.2.3 six==1.3.0 transaction==1.4.1 diff --git a/templates/display.pt b/templates/display.pt index d930e1d..466e0be 100644 --- a/templates/display.pt +++ b/templates/display.pt @@ -99,6 +99,20 @@ <tr><td id="last" colspan="6"></td></tr> </table> +<ul style="display: none;" class="nodot" tal:condition="data/download_counts | nothing"> + <li><strong>Downloads:</strong></li> + <li> + <span tal:content="data/download_counts/day" /> downloads in the last day + </li> + <!-- will be displayed when we have enough data --> + <li style="display: none;"> + <span tal:content="data/download_counts/day" /> downloads in the last week + </li> + <li style="display: none;"> + <span tal:content="data/download_counts/day" /> downloads in the last month + </li> +</ul> + <ul class="nodot"> <li tal:condition="data/release/author | nothing"> <strong>Author:</strong> @@ -7,11 +7,13 @@ defusedxml.xmlrpc.monkey_patch() import sys, os, urllib, cStringIO, traceback, cgi, binascii, gzip import time, random, smtplib, base64, email, types, urlparse import re, zipfile, logging, shutil, Cookie, subprocess, hashlib +import datetime from zope.pagetemplate.pagetemplatefile import PageTemplateFile from distutils.util import rfc822_escape from distutils2.metadata import Metadata from xml.etree import cElementTree import itsdangerous +import redis try: import json @@ -51,6 +53,15 @@ esq = lambda x: cgi.escape(x, True) def enumerate(sequence): return [(i, sequence[i]) for i in range(len(sequence))] +PRECISIONS = [ + ("hour", "%y-%m-%d-%H"), + ("daily", "%y-%m-%d"), +] +def make_key(precision, datetime, key): + return "downloads:%s:%s:%s:*" % ( + precision[0], datetime.strftime(precision[1]), key) + + # Requires: # - ASCII letters # - ASCII digits @@ -227,6 +238,10 @@ class WebUI: self.sentry_client = None if self.config.sentry_dsn: self.sentry_client = raven.Client(self.config.sentry_dsn) + if self.config.redis_url: + self.redis = redis.Redis.from_url(self.config.redis_url) + else: + self.redis = None self.env = env self.nav_current = None self.privkey = None @@ -1568,6 +1583,30 @@ class WebUI: docs = self.store.docs_url(name) files = self.store.list_files(name, version) + # Download Counts from redis + download_counts = {} + if self.redis is not None: + # Get the current utc time + current = datetime.datetime.utcnow() + + # Get the download count for the last 24 hours (roughly) + keys = [make_key(PRECISIONS[0], current - datetime.timedelta(hours=x), name) for x in xrange(25)] + last_1 = sum([int(x) for x in self.redis.mget(*keys) if x is not None]) + + # Get the download count for the last 7 days (roughly) + keys = [make_key(PRECISIONS[1], current - datetime.timedelta(days=x), name) for x in xrange(8)] + last_7 = sum([int(x) for x in self.redis.mget(*keys) if x is not None]) + + # Get the download count for the last month (roughly) + keys = [make_key(PRECISIONS[1], current - datetime.timedelta(days=x), name) for x in xrange(31)] + last_30 = sum([int(x) for x in self.redis.mget(*keys) if x is not None]) + + download_counts = { + "day": last_1, + "week": last_7, + "month": last_30, + } + self.write_template('display.pt', name=name, version=version, release=release, description=release.get('summary') or name, @@ -1591,7 +1630,8 @@ class WebUI: obsoletes_dist=obsoletes_dist, requires_external=requires_external, project_url=project_url, - bugtrack_url = bugtrack_url, + download_counts=download_counts, + bugtrack_url=bugtrack_url, requires_python=release.get('requires_python', '')) def index(self, nav_current='index', releases=None): |