fix for missing IP in stats + stats for /api/
authorMarcin Koziej <marcin.koziej@nowoczesnapolska.org.pl>
Wed, 12 Oct 2011 09:15:17 +0000 (11:15 +0200)
committerMarcin Koziej <marcin.koziej@nowoczesnapolska.org.pl>
Wed, 12 Oct 2011 09:17:18 +0000 (11:17 +0200)
apps/api/handlers.py
apps/opds/utils.py [deleted file]
apps/opds/views.py
apps/stats/utils.py [new file with mode: 0644]

index 9bb8900..41b5ac6 100644 (file)
@@ -16,6 +16,7 @@ from api.models import Deleted
 from catalogue.forms import BookImportForm
 from catalogue.models import Book, Tag, BookMedia, Fragment
 
+from stats.utils import piwik_track
 
 API_BASE = WL_BASE = MEDIA_BASE = 'http://' + Site.objects.get_current().domain
 
@@ -96,6 +97,7 @@ class BookDetailHandler(BaseHandler):
         'xml', 'html', 'pdf', 'epub', 'txt',
         'media', 'url'] + category_singular.keys()
 
+    @piwik_track
     def read(self, request, slug):
         """ Returns details of a book, identified by a slug. """
 
@@ -129,6 +131,7 @@ class AnonymousBooksHandler(AnonymousBaseHandler):
 
         return WL_BASE + book.get_absolute_url()
 
+    @piwik_track
     def read(self, request, tags, top_level=False):
         """ Lists all books with given tags.
 
@@ -209,6 +212,7 @@ class TagDetailHandler(BaseHandler):
 
     fields = ['name', 'sort_key', 'description']
 
+    @piwik_track
     def read(self, request, category, slug):
         """ Returns details of a tag, identified by category and slug. """
 
@@ -234,6 +238,7 @@ class TagsHandler(BaseHandler):
     model = Tag
     fields = ['name', 'href']
 
+    @piwik_track
     def read(self, request, category):
         """ Lists all tags in the category (eg. all themes). """
 
@@ -260,6 +265,7 @@ class TagsHandler(BaseHandler):
 class FragmentDetailHandler(BaseHandler):
     fields = ['book', 'anchor', 'text', 'url', 'themes']
 
+    @piwik_track
     def read(self, request, slug, anchor):
         """ Returns details of a fragment, identified by book slug and anchor. """
 
@@ -282,6 +288,7 @@ class FragmentsHandler(BaseHandler):
 
     categories = set(['author', 'epoch', 'kind', 'genre', 'book', 'theme'])
 
+    @piwik_track
     def read(self, request, tags):
         """ Lists all fragments with given book, tags, themes.
 
@@ -547,6 +554,7 @@ class CatalogueHandler(BaseHandler):
 class BookChangesHandler(CatalogueHandler):
     allowed_methods = ('GET',)
 
+    @piwik_track
     def read(self, request, since):
         return self.book_changes(request, since)
 
@@ -554,6 +562,7 @@ class BookChangesHandler(CatalogueHandler):
 class TagChangesHandler(CatalogueHandler):
     allowed_methods = ('GET',)
 
+    @piwik_track
     def read(self, request, since):
         return self.tag_changes(request, since)
 
@@ -561,5 +570,6 @@ class TagChangesHandler(CatalogueHandler):
 class ChangesHandler(CatalogueHandler):
     allowed_methods = ('GET',)
 
+    @piwik_track
     def read(self, request, since):
         return self.changes(request, since)
diff --git a/apps/opds/utils.py b/apps/opds/utils.py
deleted file mode 100644 (file)
index 1cfcdd9..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-
-from django.contrib.sites.models import Site
-from piwik.django.models import PiwikSite
-from django.conf import settings
-import logging
-from functools import update_wrapper
-import httplib
-import urlparse
-from random import random
-
-logging.basicConfig(level=logging.WARN)
-logger = logging.getLogger(__name__)
-
-
-def piwik_url(**kw):
-    url = settings.PIWIK_URL + u"/piwik.php?"
-    url += u'&'.join([k + u"=" + str(v) for k, v in kw.items()])
-    return url
-
-PIWIK_API_VERSION = 1
-
-
-def piwik_track(klass):
-    current_site = Site.objects.get_current()
-    piwik_site = PiwikSite.objects.filter(site=current_site.id)
-
-    if len(piwik_site) == 0:
-        logger.warn("No PiwikSite is configured for Site " + current_site.name)
-        return klass
-
-    id_piwik = piwik_site[0].id_site
-    call_func = klass.__call__
-    host = urlparse.urlsplit(settings.PIWIK_URL).netloc
-
-    def wrap(self, request, *args, **kw):
-        conn = httplib.HTTPConnection(host)
-        conn.request('GET', piwik_url(
-            rec=1,
-            apiv=PIWIK_API_VERSION,
-            rand=int(random() * 0x10000),
-            cip=request.META['REMOTE_ADDR'],
-            url='http://' + request.META['HTTP_HOST'] + request.path,
-            urlref=request.META['HTTP_REFERER'] if 'HTTP_REFERER' in request.META else '',
-            idsite=id_piwik))
-
-        conn.close()
-        return call_func(self, request, *args, **kw)
-
-    update_wrapper(wrap, call_func)
-    klass.__call__ = wrap
-
-    return klass
index 5233570..c7d3828 100644 (file)
@@ -18,7 +18,7 @@ from basicauth import logged_in_or_basicauth, factory_decorator
 from catalogue.models import Book, Tag
 from catalogue.views import books_starting_with
 
-from opds.utils import piwik_track
+from stats.utils import piwik_track
 
 _root_feeds = (
     {
diff --git a/apps/stats/utils.py b/apps/stats/utils.py
new file mode 100644 (file)
index 0000000..7ee4cfd
--- /dev/null
@@ -0,0 +1,70 @@
+
+from django.contrib.sites.models import Site
+from piwik.django.models import PiwikSite
+from django.conf import settings
+import logging
+from functools import update_wrapper
+import httplib
+import urlparse
+import urllib
+from random import random
+from inspect import isclass
+
+logger = logging.getLogger(__name__)
+
+
+def piwik_url(**kw):
+    url = settings.PIWIK_URL + u"/piwik.php?"
+    url += u'&'.join([k + u"=" + str(v) for k, v in kw.items()])
+    logger.info("piwik url: %s" % url)
+    return url
+
+PIWIK_API_VERSION = 1
+
+
+def piwik_track(klass_or_method):
+    """Track decorated class or method using Piwik (according to configuration in settings and django-piwik)
+    Works for handler classes (executed by __call__) or handler methods. Expects request to be the first parameter
+    """
+    # Retrieve piwik information
+    current_site = Site.objects.get_current()
+    piwik_site = PiwikSite.objects.filter(site=current_site.id)
+
+    if len(piwik_site) == 0:
+        logger.debug("No PiwikSite is configured for Site " + current_site.name)
+        return klass_or_method
+
+    id_piwik = piwik_site[0].id_site
+    host = urlparse.urlsplit(settings.PIWIK_URL).netloc
+
+    # get target method
+    if isclass(klass_or_method):
+        klass = klass_or_method
+        call_func = klass.__call__
+    else:
+        call_func = klass_or_method
+
+    def wrap(self, request, *args, **kw):
+        conn = httplib.HTTPConnection(host)
+        conn.request('GET', piwik_url(
+            rec=1,
+            apiv=PIWIK_API_VERSION,
+            rand=int(random() * 0x10000),
+            token_auth=urllib.quote(settings.PIWIK_TOKEN),
+            cip=urllib.quote(request.META['REMOTE_ADDR']),
+            url=urllib.quote('http://' + request.META['HTTP_HOST'] + request.path),
+            urlref=urllib.quote(request.META['HTTP_REFERER']) if 'HTTP_REFERER' in request.META else '',
+            idsite=id_piwik))
+
+        conn.close()
+        return call_func(self, request, *args, **kw)
+
+    # and wrap it
+    update_wrapper(wrap, call_func)
+
+    if isclass(klass_or_method):
+        klass.__call__ = wrap
+        return klass
+    else:
+        print klass_or_method
+        return wrap