From 65361fa85167193414ea0e8c07cdd8df5b15a628 Mon Sep 17 00:00:00 2001 From: Adrian Moennich Date: Thu, 8 Apr 2021 15:15:08 +0200 Subject: [PATCH] Piwik: Remove unreliable/broken download tracking --- piwik/indico_piwik/client/index.js | 80 -------------------- piwik/indico_piwik/client/main.css | 48 ------------ piwik/indico_piwik/controllers.py | 17 +---- piwik/indico_piwik/forms.py | 1 - piwik/indico_piwik/plugin.py | 25 +----- piwik/indico_piwik/queries/metrics.py | 38 ---------- piwik/indico_piwik/queries/tracking.py | 38 ---------- piwik/indico_piwik/reports.py | 39 +--------- piwik/indico_piwik/templates/statistics.html | 28 ------- piwik/package.json | 19 ----- 10 files changed, 5 insertions(+), 328 deletions(-) delete mode 100644 piwik/indico_piwik/queries/tracking.py delete mode 100644 piwik/package.json diff --git a/piwik/indico_piwik/client/index.js b/piwik/indico_piwik/client/index.js index ae4b6fd..99d11ac 100644 --- a/piwik/indico_piwik/client/index.js +++ b/piwik/indico_piwik/client/index.js @@ -5,14 +5,12 @@ // them and/or modify them under the terms of the MIT License; // see the LICENSE file for more details. -import 'jqtree'; import 'jquery'; import './main.css'; import 'indico/jquery/compat/jqplot'; $(function() { const $t = $T.domain('piwik'); - const treeDOMTarget = '#materialTree'; /** * Clears the DOM element for the graph and then initiates a jqPlot render @@ -75,26 +73,6 @@ $(function() { } }; - /** - * Draw a customized jqTree - */ - const draw_jqTree = function(treeData) { - $(treeDOMTarget).tree({ - data: treeData, - autoOpen: 0, - saveState: true, - onCanSelectNode(node) { - // Leaf node (material) can be selected - return node.children.length === 0; - }, - onCreateLi(node, $li) { - if (node.id !== undefined) { - $li.find('.title').addClass('selectableNode'); - } - }, - }); - }; - /** * Get base values for API requests */ @@ -146,56 +124,6 @@ $(function() { return output; }; - /** - * Load material downloads data via AJAX and draw its graph - */ - const load_material_graph = function(uri, replot) { - replot = typeof replot !== 'undefined' ? replot : false; - const DOMTarget = 'materialDownloadChart'; - const graph_params = get_api_params(); - graph_params.download_url = uri; - - $.ajax({ - url: build_url(PiwikPlugin.urls.data_downloads, graph_params), - type: 'POST', - dataType: 'json', - success(data) { - if (handleAjaxError(data)) { - return; - } - const materialHits = [ - get_jqplot_array_values(data.metrics.downloads.individual, 'total'), - get_jqplot_array_values(data.metrics.downloads.individual, 'unique'), - ]; - draw_jqplot_graph(materialHits, DOMTarget, replot); - $('#materialTotalDownloads').html(data.metrics.downloads.cumulative.total); - }, - }); - }; - - /** - * Load the material files data and draw its jqTree - */ - const load_material_tree = function() { - $(treeDOMTarget).html(progressIndicator(true, true).dom); - - $.ajax({ - url: build_url(PiwikPlugin.urls.material, get_api_params()), - type: 'POST', - dataType: 'json', - success(data) { - if (handleAjaxError(data)) { - return; - } - if (data.material.tree !== null) { - draw_jqTree(data.material.tree); - } else { - $(treeDOMTarget).html($t.gettext('No material found')); - } - }, - }); - }; - /** * Loads visits data and draw its graph */ @@ -273,13 +201,6 @@ $(function() { window.location.href = url; }); - // Event handler for clicking 'selectable' elements from the jqTree. - $(treeDOMTarget).bind('tree.click', function(event) { - $('#materialTitle').html(event.node.name); - $('#materialDownloadChart').html(progressIndicator(true, true).dom); - load_material_graph(event.node.id, true); - }); - // jQuery UI Dialog if no data is received via AJAX (timeout) $('#dialogNoGraphData').dialog({ modal: true, @@ -294,7 +215,6 @@ $(function() { load_graphs(); load_visits_graph(); - load_material_tree(); }; init(); diff --git a/piwik/indico_piwik/client/main.css b/piwik/indico_piwik/client/main.css index a73dcd8..8b6f30d 100644 --- a/piwik/indico_piwik/client/main.css +++ b/piwik/indico_piwik/client/main.css @@ -116,54 +116,6 @@ div#statsGenerated { padding-top: 10px; } -div#materialTree { - display: block; - width: 190px; - height: 80%; - overflow: auto; - float: left; - padding: 15px 10px 10px 10px; -} - -div#materialContainer { - display: block; - width: 510px; - float: left; - padding-left: 10px; - height: 90%; -} - -/* jqTree Formatting */ - -div#materialTree ul { - margin: 0; - padding: 0 0 0 10px; - line-height: 1.5em; -} - -div#marginTree ul ul { - padding-left: 5px; -} - -span.selectableNode { - color: #0b63a5 !important; - font-size: 0.9em; - display: block; - width: auto; - border-bottom: 1px solid #efefef; -} - -ul.tree .title { - color: #444; -} - -/* jqPlot Formatting */ - -div#materialDownloadChart { - width: auto; - height: 250px; -} - div#visitorChart { margin-left: 15px; width: 95%; diff --git a/piwik/indico_piwik/controllers.py b/piwik/indico_piwik/controllers.py index 9f88202..d898edb 100644 --- a/piwik/indico_piwik/controllers.py +++ b/piwik/indico_piwik/controllers.py @@ -11,8 +11,7 @@ from werkzeug.exceptions import NotFound from indico.modules.events.management.controllers import RHManageEventBase -from indico_piwik.reports import (ReportCountries, ReportDevices, ReportDownloads, ReportGeneral, ReportMaterial, - ReportVisitsPerDay) +from indico_piwik.reports import ReportCountries, ReportDevices, ReportGeneral, ReportVisitsPerDay from indico_piwik.views import WPStatistics @@ -58,15 +57,6 @@ class RHApiEventBase(RHApiBase): self._report_params['contrib_id'] = request.args.get('contrib_id') -class RHApiDownloads(RHApiEventBase): - def _process_args(self): - RHApiEventBase._process_args(self) - self._report_params['download_url'] = request.args['download_url'] - - def _process(self): - return jsonify(ReportDownloads.get(**self._report_params)) - - class RHApiEventVisitsPerDay(RHApiEventBase): def _process(self): return jsonify(ReportVisitsPerDay.get(**self._report_params)) @@ -80,8 +70,3 @@ class RHApiEventGraphCountries(RHApiEventBase): class RHApiEventGraphDevices(RHApiEventBase): def _process(self): return jsonify(ReportDevices.get(**self._report_params)) - - -class RHApiMaterial(RHApiEventBase): - def _process(self): - return jsonify(ReportMaterial.get(**self._report_params)) diff --git a/piwik/indico_piwik/forms.py b/piwik/indico_piwik/forms.py index adee529..3b1c388 100644 --- a/piwik/indico_piwik/forms.py +++ b/piwik/indico_piwik/forms.py @@ -17,7 +17,6 @@ from indico_piwik import _ class SettingsForm(IndicoForm): enabled = BooleanField(_("Track global visits"), widget=SwitchWidget()) enabled_for_events = BooleanField(_("Track events"), widget=SwitchWidget()) - enabled_for_downloads = BooleanField(_("Track downloads"), widget=SwitchWidget()) cache_enabled = BooleanField(_("Cache results"), widget=SwitchWidget()) server_url = StringField(_("Piwik server URL")) server_api_url = StringField(_("Piwik API server URL"), diff --git a/piwik/indico_piwik/plugin.py b/piwik/indico_piwik/plugin.py index ca3aa2a..7157bf1 100644 --- a/piwik/indico_piwik/plugin.py +++ b/piwik/indico_piwik/plugin.py @@ -12,15 +12,13 @@ from flask_pluginengine import render_plugin_template from indico.core import signals from indico.core.plugins import IndicoPlugin, IndicoPluginBlueprint, plugin_url_rule_to_js, url_for_plugin -from indico.modules.attachments.models.attachments import AttachmentType from indico.modules.events.contributions import Contribution from indico.web.menu import SideMenuItem from indico_piwik import _ -from indico_piwik.controllers import (RHApiDownloads, RHApiEventGraphCountries, RHApiEventGraphDevices, - RHApiEventVisitsPerDay, RHApiMaterial, RHStatistics) +from indico_piwik.controllers import (RHApiEventGraphCountries, RHApiEventGraphDevices, RHApiEventVisitsPerDay, + RHStatistics) from indico_piwik.forms import SettingsForm -from indico_piwik.queries.tracking import track_download_request class PiwikPlugin(IndicoPlugin): @@ -36,7 +34,6 @@ class PiwikPlugin(IndicoPlugin): default_settings = { 'enabled': False, 'enabled_for_events': True, - 'enabled_for_downloads': True, 'cache_enabled': True, 'server_url': '//127.0.0.1/piwik/', 'server_api_url': '//127.0.0.1/piwik/', @@ -50,7 +47,6 @@ class PiwikPlugin(IndicoPlugin): def init(self): super().init() self.connect(signals.menu.items, self.add_sidemenu_item, sender='event-management-sidemenu') - self.connect(signals.attachments.attachment_accessed, self.track_download) self.template_hook('html-head', self.inject_tracking) def inject_tracking(self, **kwargs): @@ -73,23 +69,10 @@ class PiwikPlugin(IndicoPlugin): return blueprint def get_vars_js(self): - return {'urls': {'material': plugin_url_rule_to_js('piwik.material'), - 'data_downloads': plugin_url_rule_to_js('piwik.data_downloads'), - 'data_visits': plugin_url_rule_to_js('piwik.data_visits'), + return {'urls': {'data_visits': plugin_url_rule_to_js('piwik.data_visits'), 'graph_countries': plugin_url_rule_to_js('piwik.graph_countries'), 'graph_devices': plugin_url_rule_to_js('piwik.graph_devices')}} - def track_download(self, attachment, from_preview, **kwargs): - if from_preview or not self.settings.get('enabled_for_downloads'): - return - if attachment.type == AttachmentType.link: - resource_url = attachment.link_url - resource_title = f'Link - {attachment.title}' - else: - resource_url = request.base_url - resource_title = f'Download - {attachment.title}' - track_download_request.delay(resource_url, resource_title) - def _get_event_tracking_params(self): site_id_events = PiwikPlugin.settings.get('site_id_events') if not self.settings.get('enabled_for_events') or not site_id_events: @@ -115,8 +98,6 @@ class PiwikPlugin(IndicoPlugin): blueprint = IndicoPluginBlueprint('piwik', __name__, url_prefix='/event//manage/statistics') blueprint.add_url_rule('/', 'view', RHStatistics) -blueprint.add_url_rule('/material', 'material', RHApiMaterial, methods=('GET', 'POST')) -blueprint.add_url_rule('/data/downloads', 'data_downloads', RHApiDownloads, methods=('GET', 'POST')) blueprint.add_url_rule('/data/visits', 'data_visits', RHApiEventVisitsPerDay, methods=('GET', 'POST')) blueprint.add_url_rule('/graph/countries', 'graph_countries', RHApiEventGraphCountries, methods=('GET', 'POST')) blueprint.add_url_rule('/graph/devices', 'graph_devices', RHApiEventGraphDevices, methods=('GET', 'POST')) diff --git a/piwik/indico_piwik/queries/metrics.py b/piwik/indico_piwik/queries/metrics.py index f650a72..e8d1a5c 100644 --- a/piwik/indico_piwik/queries/metrics.py +++ b/piwik/indico_piwik/queries/metrics.py @@ -6,7 +6,6 @@ # see the LICENSE file for more details. from operator import itemgetter -from urllib.parse import quote from indico_piwik.queries.base import PiwikQueryReportEventBase from indico_piwik.queries.utils import get_json_from_remote_server, reduce_json, stringify_seconds @@ -30,43 +29,6 @@ class PiwikQueryReportEventMetricVisitsBase(PiwikQueryReportEventMetricBase): return result if result else {} -class PiwikQueryReportEventMetricDownloads(PiwikQueryReportEventMetricBase): - def call(self, download_url, **query_params): - return super().call(method='Actions.getDownload', downloadUrl=quote(download_url), **query_params) - - def get_result(self, download_url): - result = get_json_from_remote_server(self.call, download_url=download_url, segmentation_enabled=False) - return {'cumulative': self._get_cumulative_results(result), - 'individual': self._get_per_day_results(result)} - - def _get_per_day_results(self, results): - hits_calendar = {} - - for date, hits in results.items(): - day_hits = {'total': 0, 'unique': 0} - if hits: - for metrics in hits: - day_hits['total'] += metrics['nb_hits'] - day_hits['unique'] += metrics['nb_uniq_visitors'] - hits_calendar[date] = day_hits - - return hits_calendar - - def _get_cumulative_results(self, results): - """ - Returns a dictionary of {'total': x, 'unique': y} for the - date range. - """ - hits = {'total': 0, 'unique': 0} - - day_hits = list(hits[0] for hits in results.values() if hits) - for metrics in day_hits: - hits['total'] += metrics['nb_hits'] - hits['unique'] += metrics['nb_uniq_visitors'] - - return hits - - class PiwikQueryReportEventMetricReferrers(PiwikQueryReportEventMetricBase): def call(self, **query_params): return super().call(method='Referrers.getReferrerType', period='range', **query_params) diff --git a/piwik/indico_piwik/queries/tracking.py b/piwik/indico_piwik/queries/tracking.py deleted file mode 100644 index ccfc6bb..0000000 --- a/piwik/indico_piwik/queries/tracking.py +++ /dev/null @@ -1,38 +0,0 @@ -# This file is part of the Indico plugins. -# Copyright (C) 2002 - 2021 CERN -# -# The Indico plugins are free software; you can redistribute -# them and/or modify them under the terms of the MIT License; -# see the LICENSE file for more details. - -from datetime import datetime -from urllib.parse import quote - -from indico.core.celery import celery - -from indico_piwik.piwik import PiwikRequest - - -@celery.task -def track_download_request(download_url, download_title): - """Track a download in Piwik""" - from indico_piwik.plugin import PiwikPlugin - - if not download_url: - raise ValueError("download_url can't be empty") - if not download_title: - raise ValueError("download_title can't be empty") - - request = PiwikRequest(server_url=PiwikPlugin.settings.get('server_api_url'), - site_id=PiwikPlugin.settings.get('site_id_events'), - api_token=PiwikPlugin.settings.get('server_token'), - query_script=PiwikPlugin.track_script) - - action_url = quote(download_url) - dt = datetime.now() - request.call(idsite=request.site_id, - rec=1, - action_name=quote(download_title), - url=action_url, - download=action_url, - h=dt.hour, m=dt.minute, s=dt.second) diff --git a/piwik/indico_piwik/reports.py b/piwik/indico_piwik/reports.py index bed5f8b..8804d72 100644 --- a/piwik/indico_piwik/reports.py +++ b/piwik/indico_piwik/reports.py @@ -11,15 +11,13 @@ from datetime import timedelta from sqlalchemy.orm import joinedload from indico.core.cache import make_scoped_cache -from indico.modules.attachments.util import get_nested_attached_items from indico.modules.events import Event from indico.modules.events.contributions import Contribution from indico.util.date_time import format_time, now_utc, utc_to_server from indico.util.serializer import Serializer from indico_piwik.queries.graphs import PiwikQueryReportEventGraphCountries, PiwikQueryReportEventGraphDevices -from indico_piwik.queries.metrics import (PiwikQueryReportEventMetricDownloads, - PiwikQueryReportEventMetricPeakDateAndVisitors, +from indico_piwik.queries.metrics import (PiwikQueryReportEventMetricPeakDateAndVisitors, PiwikQueryReportEventMetricReferrers, PiwikQueryReportEventMetricUniqueVisits, PiwikQueryReportEventMetricVisitDuration, PiwikQueryReportEventMetricVisits) @@ -92,13 +90,6 @@ class ReportDevices(ReportBase): self.graphs = {'devices': PiwikQueryReportEventGraphDevices(**self.params).get_result()} -class ReportDownloads(ReportBase): - __public__ = ['metrics'] - - def _build_report(self, download_url): - self.metrics = {'downloads': PiwikQueryReportEventMetricDownloads(**self.params).get_result(download_url)} - - class ReportGeneral(ReportBase): __public__ = ['event_id', 'contrib_id', 'start_date', 'end_date', 'metrics', 'contributions', 'timestamp'] @@ -132,34 +123,6 @@ class ReportGeneral(ReportBase): self.contributions[key] = '{} ({})'.format(contribution.title, format_time(contribution.start_dt)) -class ReportMaterial(ReportBase): - __public__ = ['material'] - - def _build_report(self): - event = Event.get_or_404(self.params['event_id'], is_deleted=False) - new_material = get_nested_attached_items(event) - self.material = {'tree': [self._format_data(new_material)]} - - def _format_data(self, raw_node): - if 'object' not in raw_node: - return None - node = {'label': raw_node['object'].title, - 'children': []} - if 'files' in raw_node: - node['children'] += self._format_data_files(raw_node['files']) - if 'folders' in raw_node: - for folder in raw_node['folders']: - node['children'] += [{'label': folder.title, 'children': self._format_data_files(folder.attachments)}] - if 'children' in raw_node: - node['children'] += [self._format_data(child) for child in raw_node['children']] - if not node['children']: - return None - return node - - def _format_data_files(self, files): - return [{'id': f.absolute_download_url, 'label': f.title} for f in files] - - class ReportVisitsPerDay(ReportBase): __public__ = ['metrics'] diff --git a/piwik/indico_piwik/templates/statistics.html b/piwik/indico_piwik/templates/statistics.html index a0315d8..ccb4faa 100644 --- a/piwik/indico_piwik/templates/statistics.html +++ b/piwik/indico_piwik/templates/statistics.html @@ -179,34 +179,6 @@ -
- - -
-
- {% trans %}Material Downloads{% endtrans %} -
-
-
-
-
- {% trans %}Downloads for{% endtrans %}: - - — - - ({% trans %}Total{% endtrans %}: 0) -
-
-
- {% trans %}No material selected{% endtrans %} -
-
-
-
-
- -
-
{% trans dt=report.timestamp | format_datetime('long') -%} This report was generated at: {{ dt }} diff --git a/piwik/package.json b/piwik/package.json deleted file mode 100644 index 24875f8..0000000 --- a/piwik/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "indico-plugin-piwik", - "version": "1.0.0", - "description": "", - "main": "indico_piwik/client/index.js", - "repository": { - "type": "git", - "url": "git+https://github.com/indico/indico-plugins.git" - }, - "author": "Indico Team ", - "license": "MIT", - "bugs": { - "url": "https://github.com/indico/indico-plugins/issues" - }, - "homepage": "https://github.com/indico/indico-plugins#readme", - "dependencies": { - "jqtree": "^1.4.4" - } -}