Browse Source

First version of the tracker

Johann Schmitz 4 years ago
Signed by: Johann Schmitz <> GPG Key ID: A084064277C501ED
1 changed files with 151 additions and 1 deletions
  1. 151

+ 151
- 1
src/pypiwik/ View File

@@ -1,8 +1,158 @@
# -*- coding: utf-8 -*-
from _md5 import md5
import logging
import os
import datetime
import requests
import simplejson

# required parameters
'url': 'url', # The full URL for the current action.

# recommended parameters
'action_name': 'action_name', # The title of the action being tracked.
'referrer': 'urlref', # The full HTTP Referrer URL.
'visit_custom_vars': '_cvar', # Visit scope custom variables.
'visit_count': '_idvc', # The current count of visits for this visitor.
'view_timestamp': '_viewts', # The UNIX timestamp of this visitor's previous visit.
'first_visit_timestamp': '_idts', # The UNIX timestamp of this visitor's first visit.
'campaign_name': '_rcn', # The Campaign name (see Tracking Campaigns).
'campaign_keywords': '_rck', # The Campaign Keyword (see Tracking Campaigns).
'resolution': 'res', # The resolution of the device the visitor is using, eg 1280x1024.
'hour': 'h', # The current hour (local time).
'minute': 'm', # The current minute (local time).
'second': 's', # The current second (local time).
'flash': 'fla', # Flash,
'java': 'java', # Java
'director': 'dir', # Director,
'quicktime': 'qt', # Quicktime,
'real_player': 'realp', # Real Player,
'pdf': 'pdf', # PDF
'wma': 'wma', # Windows Media
'gears': 'gears', # Gears
'silverlight': 'ag', # Silverlight
'cookie': 'cookie', # when set to 1, the visitor's client is known to support cookies.
'user_agent': 'ua', # An override value for the User-Agent HTTP header field.
'lang': 'lang', # An override value for the Accept-Language HTTP header field. This value is used to detect the visitor's country if GeoIP is not enabled.
'user_id': 'uid', # defines the User ID for this request. User ID is any non empty unique string identifying the user (such as an email address or a username).
'visitor_id': 'cid', # defines the visitor ID for this request.
'new_visit': 'new_visit', # If set to 1, will force a new visit to be created for this action. This feature is also available in Javascript.

# 'Optional Action info (measure Page view, Outlink, Download, Site search)',
'page_custom_vars': 'cvar', # Page scope custom variables.
'link': 'link', # An external URL the user has opened. Used for tracking outlink clicks. We recommend to also set the url parameter to this same value.
'download': 'download', # URL of a file the user has downloaded. Used for tracking downloads. We recommend to also set the url parameter to this same value.
'search_keyword': 'search', # The Site Search keyword. When specified, the request will not be tracked as a normal pageview but will instead be tracked as a Site Search request.
'search_category': 'search_cat', # when search is specified, you can optionally specify a search category with this parameter.
'search_count': 'search_count', # when search is specified, we also recommend to set the search_count to the number of search results displayed on the results page.

'goal_id': 'idgoal', # If specified, the tracking request will trigger a conversion for the goal of the website being tracked with this ID.
'revenue': 'revenue', # A monetary value that was generated as revenue by this goal conversion. Only used if idgoal is specified in the request.
'gt_ms': 'gt_ms', # The amount of time it took the server to generate this action, in milliseconds.
'charset': 'cs', # The charset of the page being tracked. Specify the charset if the data you send to Piwik is encoded in a different character set than the default utf-8.

# Optional Event Tracking info
'event_category': 'e_c', # The event category. Must not be empty. (eg. Videos, Music, Games...)
'event_action': 'e_a', # The event action. Must not be empty. (eg. Play, Pause, Duration, Add Playlist, Downloaded, Clicked...)
'event_name': 'e_n', # The event name. (eg. a Movie name, or Song name, or File name...)
'event_value': 'e_v', # The event value. Must be a float or integer value (numeric), not a string.

# Optional Content Tracking info
'content_name': 'c_n', # The name of the content. For instance 'Ad Foo Bar'
'content_piece': 'c_p', # The actual content piece. For instance the path to an image, video, audio, any text
'content_target': 'c_t', # The target of the content. For instance the URL of a landing page
'content_interaction': 'c_i', # The name of the interaction with the content. For instance a 'click'

'token_auth': 'token_auth', # 32 character authorization key used to authenticate the API request.
'client_ip': 'cip', # Override value for the visitor IP (both IPv4 and IPv6 notations supported).
'client_dt': 'cdt', # Override for the datetime of the request (normally the current time is used).
'country': 'country', # An override value for the country. Should be set to the two letter country code of the visitor (lowercase), eg fr, de, us.
'region': 'region', # An override value for the region. Should be set to the two letter region code as defined by MaxMind's GeoIP databases.
'city': 'city', # An override value for the city. The name of the city the visitor is located in, eg, Tokyo.
'lat': 'lat', # An override value for the visitor's latitude, eg 22.456.
'long': 'long', # An override value for the visitor's longitude, eg 22.456.

class PiwikTracker(object):

def __init__(self, piwik_url, site_id):
super(PiwikTracker, self).__init__()
self.piwik_url = piwik_url
self.idsite = site_id
self.idsite = site_id

for property_name in PARAMETERS.keys():
setattr(self, property_name, None)

self.visit_custom_vars = {}
self.page_custom_vars = {}

self.spoof_request = True

self.request_headers = {}
self.requests_arguments = {
'timeout': 3

def _build_cvars(self, value):
if not value:
return None

d = {}

for i, item in enumerate(value.items(), start=1):
d[i] = list(item)

return simplejson.dumps(d)

def _build_parameters(self, **kwargs):
d = {
'idsite': self.idsite,
'rec': '1',
'apiv': PiwikTracker.API_VERSION,

for property_name, parameter_name in PARAMETERS.items():
value = kwargs.get(property_name, None) or getattr(self, property_name, None)

if value is None:

if isinstance(value, bool):
value = 1 if value else 0
elif isinstance(value, datetime.datetime):
if not value.tzinfo:
logging.warning("Passing a naive datetime may result in wrong data. Make sure you pass a datetime object with UTC timezone")
value = value.strftime('%Y-%m-%d %H:%M:%S')

if property_name in ('page_custom_vars', 'visit_custom_vars'):
value = self._build_cvars(value)

d[parameter_name] = value

return d

def build_request_headers(self, params):
headers = {
'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate',

if self.spoof_request:
for p, h in (('user_agent', 'User-Agent'), ('lang', 'Accept-Language')):
if p in params:
headers[h] = params[p]
del params[p]

return headers

def track_page_view(self, **kwargs):
params = self._build_parameters(**kwargs)
if '_id' not in params:
params['_id'] = md5(os.urandom(16)).hexdigest()[:16]

headers = self.build_request_headers(params)

requests.get(self.piwik_url, data=params, headers=headers, **self.requests_arguments)