From 92ff4af75a2e0defd8989e6b29e39196f790d16c Mon Sep 17 00:00:00 2001 From: Marcin Koziej Date: Wed, 12 Oct 2011 11:15:17 +0200 Subject: [PATCH] fix for missing IP in stats + stats for /api/ --- apps/api/handlers.py | 10 +++++++ apps/opds/utils.py | 52 -------------------------------- apps/opds/views.py | 2 +- apps/stats/utils.py | 70 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 53 deletions(-) delete mode 100644 apps/opds/utils.py create mode 100644 apps/stats/utils.py diff --git a/apps/api/handlers.py b/apps/api/handlers.py index 9bb89005c..41b5ac6f9 100644 --- a/apps/api/handlers.py +++ b/apps/api/handlers.py @@ -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 index 1cfcdd9a2..000000000 --- a/apps/opds/utils.py +++ /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 diff --git a/apps/opds/views.py b/apps/opds/views.py index 52335709b..c7d38284b 100644 --- a/apps/opds/views.py +++ b/apps/opds/views.py @@ -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 index 000000000..7ee4cfdbe --- /dev/null +++ b/apps/stats/utils.py @@ -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 -- 2.20.1