Source code for api.google_analytics_provider

from .config import CannotLoadConfiguration
import uuid
import unicodedata
import urllib.parse
import re
from flask_babel import lazy_gettext as _
from core.util.http import HTTP
from core.model import (
    ConfigurationSetting,
    ExternalIntegration,
    Session,
    get_one,
)

[docs]class GoogleAnalyticsProvider(object): NAME = _("Google Analytics") DESCRIPTION = _("How to Configure a Google Analytics Integration") INSTRUCTIONS = _("<p>In order to track usage statistics, you can configure the Circulation Manager " + "to connect to Google Analytics.</p>" + "<p>Create a <a href='https://analytics.google.com/analytics/web/provision/?authuser=0#/provision' " + "rel='noopener' rel='noreferer' target='_blank'>Google Analytics</a> account, " + "or sign into your existing one.</p>" + "<p>To capture data from the Library Simplified Circulation Manager in your Google Analytics account, " + "you must set up a property in Google Analytics for Library Simplified. In your Google Analytics " + "account, on the administration page for the property, go to Custom Definitions > Custom Dimensions, " + "and add the following dimensions, in this order: <ol>" + "<li>time</li>" + "<li>identifier</li>" + "<li>identifier_type</li>" + "<li>title</li>" + "<li>author</li>" + "<li>fiction</li>" + "<li>audience</li>" + "<li>target_age</li>" + "<li>publisher</li>" + "<li>language</li>" + "<li>genre</li>" + "<li>open_access</li>" + "<li>distributor</li>" + "<li>medium</li>" + "<li>library</li>" + "</ol></p>" + "<p>Each dimension should have the scope set to 'Hit' and the 'Active' box checked.</p>" + "<p>Then go to Tracking Info and get the tracking id for the property. Select your " + "library from the dropdown below, and enter the tracking id into the form.</p>") TRACKING_ID = "tracking_id" DEFAULT_URL = "http://www.google-analytics.com/collect" SETTINGS = [ { "key": ExternalIntegration.URL, "label": _("URL"), "default": DEFAULT_URL, "required": True, "format": "url" }, ] LIBRARY_SETTINGS = [ { "key": TRACKING_ID, "label": _("Tracking ID"), "required": True }, ] def __init__(self, integration, library=None): _db = Session.object_session(integration) if not library: raise CannotLoadConfiguration("Google Analytics can't be configured without a library.") url_setting = ConfigurationSetting.for_externalintegration(ExternalIntegration.URL, integration) self.url = url_setting.value or self.DEFAULT_URL self.tracking_id = ConfigurationSetting.for_library_and_externalintegration( _db, self.TRACKING_ID, library, integration, ).value if not self.tracking_id: raise CannotLoadConfiguration("Missing tracking id for library %s" % library.short_name)
[docs] def collect_event(self, library, license_pool, event_type, time, **kwargs): # Explicitly destroy any neighborhood information -- we don't # want to send this to third-party sources. kwargs.pop("neighborhood", None) client_id = uuid.uuid4() fields = { 'v': 1, 'tid': self.tracking_id, 'cid': client_id, 'aip': 1, # anonymize IP 'ds': "Circulation Manager", 't': 'event', 'ec': 'circulation', 'ea': event_type, 'cd1': time, } if license_pool: fields.update({ 'cd2': license_pool.identifier.identifier, 'cd3': license_pool.identifier.type }) work = license_pool.work edition = license_pool.presentation_edition if work and edition: fields.update({ 'cd4': edition.title, 'cd5': edition.author, 'cd6': "fiction" if work.fiction else "nonfiction", 'cd7': work.audience, 'cd8': work.target_age_string, 'cd9': edition.publisher, 'cd10': edition.language, 'cd11': work.top_genre(), 'cd12': "true" if license_pool.open_access else "false", }) # Backwards compatibility requires that new dimensions be # added to the end of the list. For the sake of # consistency, this code that sets values for those new # dimensions runs after the original implementation. fields.update({'cd13' : license_pool.data_source.name}) if work and edition: fields.update({'cd14' : edition.medium}) if library: fields.update({'cd15' : library.short_name}) # urlencode doesn't like unicode strings so we convert them to utf8 fields = {k: unicodedata.normalize("NFKD", str(v)).encode("utf8") for k, v in list(fields.items())} params = re.sub(r"=None(&?)", r"=\1", urllib.parse.urlencode(fields)) self.post(self.url, params)
[docs] def post(self, url, params): response = HTTP.post_with_timeout(url, params)
Provider = GoogleAnalyticsProvider