summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonald Stufft <donald@stufft.io>2013-06-26 23:36:50 -0400
committerDonald Stufft <donald@stufft.io>2013-06-26 23:36:50 -0400
commit471874691f8cf8011b39ad1092688ceea03beebc (patch)
tree022c9414da89dd9da096390b08f138fbfaec3703
parent02197b38e0f854f88ec4a52ee3fe3ad5db471b99 (diff)
downloaddecorator-471874691f8cf8011b39ad1092688ceea03beebc.tar.gz
Enable (hidden) download counts
-rw-r--r--config.ini.template1
-rw-r--r--config.py2
-rw-r--r--requirements.txt1
-rw-r--r--templates/display.pt14
-rw-r--r--webui.py42
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
diff --git a/config.py b/config.py
index 54ec3b8..beea662 100644
--- a/config.py
+++ b/config.py
@@ -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>
diff --git a/webui.py b/webui.py
index de2c7b7..84c9cdc 100644
--- a/webui.py
+++ b/webui.py
@@ -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):