| 1 | # -*- coding: utf-8 -*- |
|---|
| 2 | ## |
|---|
| 3 | ## |
|---|
| 4 | ## This file is part of CDS Indico. |
|---|
| 5 | ## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 CERN. |
|---|
| 6 | ## |
|---|
| 7 | ## CDS Indico is free software; you can redistribute it and/or |
|---|
| 8 | ## modify it under the terms of the GNU General Public License as |
|---|
| 9 | ## published by the Free Software Foundation; either version 2 of the |
|---|
| 10 | ## License, or (at your option) any later version. |
|---|
| 11 | ## |
|---|
| 12 | ## CDS Indico is distributed in the hope that it will be useful, but |
|---|
| 13 | ## WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 14 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 15 | ## General Public License for more details. |
|---|
| 16 | ## |
|---|
| 17 | ## You should have received a copy of the GNU General Public License |
|---|
| 18 | ## along with CDS Indico; if not, write to the Free Software Foundation, Inc., |
|---|
| 19 | ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. |
|---|
| 20 | |
|---|
| 21 | import os |
|---|
| 22 | import zope.interface |
|---|
| 23 | |
|---|
| 24 | import indico.ext.statistics |
|---|
| 25 | |
|---|
| 26 | from indico.core.extpoint import Component |
|---|
| 27 | from indico.core.extpoint.events import INavigationContributor, IEventDisplayContributor |
|---|
| 28 | from indico.core.extpoint.plugins import IPluginSettingsContributor |
|---|
| 29 | from indico.ext.statistics.register import StatisticsRegister |
|---|
| 30 | from indico.web.rh import RHHtdocs |
|---|
| 31 | |
|---|
| 32 | from MaKaC.i18n import _ |
|---|
| 33 | from MaKaC.errors import PluginError |
|---|
| 34 | from MaKaC.plugins import PluginsHolder |
|---|
| 35 | from MaKaC.webinterface.rh.conferenceModif import RHConferenceModifBase |
|---|
| 36 | from MaKaC.webinterface.pages.conferences import WPConferenceModifBase |
|---|
| 37 | from MaKaC.webinterface.urlHandlers import URLHandler |
|---|
| 38 | from MaKaC.webinterface import wcomponents |
|---|
| 39 | |
|---|
| 40 | |
|---|
| 41 | class StatisticsSMContributor(Component): |
|---|
| 42 | |
|---|
| 43 | zope.interface.implements(INavigationContributor) |
|---|
| 44 | |
|---|
| 45 | @classmethod |
|---|
| 46 | def fillManagementSideMenu(cls, obj, params={}): |
|---|
| 47 | if obj._conf.canModify(obj._rh._aw): |
|---|
| 48 | params['Statistics'] = wcomponents.SideMenuItem(_('Statistics'), |
|---|
| 49 | UHConfModifStatistics.getURL(obj._conf)) |
|---|
| 50 | |
|---|
| 51 | |
|---|
| 52 | class StatisticsEFContributor(Component): |
|---|
| 53 | |
|---|
| 54 | zope.interface.implements(IEventDisplayContributor) |
|---|
| 55 | |
|---|
| 56 | @classmethod |
|---|
| 57 | def eventDetailFooter(cls, obj, vars): |
|---|
| 58 | """ |
|---|
| 59 | Add the footer extension for the statistics tracking. |
|---|
| 60 | """ |
|---|
| 61 | stats = PluginsHolder().getPluginType('statistics') |
|---|
| 62 | |
|---|
| 63 | if not stats.isActive(): |
|---|
| 64 | return False |
|---|
| 65 | |
|---|
| 66 | register = StatisticsRegister() |
|---|
| 67 | key = 'extraFooterContent' |
|---|
| 68 | extension = {} |
|---|
| 69 | tracking = {} |
|---|
| 70 | |
|---|
| 71 | tracking['trackingActive'] = True |
|---|
| 72 | tracking['trackingHooks'] = register.getAllPluginJSHooks(obj) |
|---|
| 73 | |
|---|
| 74 | # Build the extension object to be passed to the footer. |
|---|
| 75 | extension['path'] = register.getJSInjectionPath() |
|---|
| 76 | extension['args'] = tracking |
|---|
| 77 | |
|---|
| 78 | if key not in vars: |
|---|
| 79 | vars[key] = [extension] |
|---|
| 80 | else: |
|---|
| 81 | vars[key].append(extension) |
|---|
| 82 | |
|---|
| 83 | |
|---|
| 84 | class UHConfModifStatistics(URLHandler): |
|---|
| 85 | |
|---|
| 86 | _relativeURL = "statistics" |
|---|
| 87 | |
|---|
| 88 | |
|---|
| 89 | class RHStatisticsView(RHConferenceModifBase): |
|---|
| 90 | |
|---|
| 91 | _url = r"^/statistics/?$" |
|---|
| 92 | _register = StatisticsRegister() |
|---|
| 93 | |
|---|
| 94 | def _checkProtection(self): |
|---|
| 95 | if not PluginsHolder().hasPluginType("statistics"): |
|---|
| 96 | raise PluginError(_("Statistics plugin is not active.")) |
|---|
| 97 | |
|---|
| 98 | self._checkSessionUser() |
|---|
| 99 | |
|---|
| 100 | RHConferenceModifBase._checkProtection(self) |
|---|
| 101 | |
|---|
| 102 | def _checkParams(self, params): |
|---|
| 103 | RHConferenceModifBase._checkParams(self, params) |
|---|
| 104 | |
|---|
| 105 | self._activeTab = params.get("tab", 'Piwik') |
|---|
| 106 | self._confId = params.get("confId", None) |
|---|
| 107 | self._contribId = params.get("contribId", None) |
|---|
| 108 | self._startDate = params.get("startDate", None) |
|---|
| 109 | self._endDate = params.get("endDate", None) |
|---|
| 110 | |
|---|
| 111 | def _process(self): |
|---|
| 112 | return WPStatisticsView(self, WStatisticsView).display() |
|---|
| 113 | |
|---|
| 114 | |
|---|
| 115 | class RHStatisticsHtdocs(RHHtdocs): |
|---|
| 116 | |
|---|
| 117 | _url = r"^/statistics/(?P<filepath>.*)$" |
|---|
| 118 | _local_path = os.path.join(indico.ext.statistics.__path__[0], 'htdocs') |
|---|
| 119 | |
|---|
| 120 | |
|---|
| 121 | class WStatisticsView(wcomponents.WTemplated): |
|---|
| 122 | |
|---|
| 123 | def __init__(self, register, rh): |
|---|
| 124 | self._register = register |
|---|
| 125 | self._rh = rh |
|---|
| 126 | |
|---|
| 127 | def getVars(self): |
|---|
| 128 | """ |
|---|
| 129 | In this method it is expected that any implementations of statistics |
|---|
| 130 | have both a getContributionReport and getConferenceReport method |
|---|
| 131 | defined, the results of which are the data for the view. |
|---|
| 132 | """ |
|---|
| 133 | vars = wcomponents.WTemplated.getVars(self) |
|---|
| 134 | rh = self._rh |
|---|
| 135 | plugin = self._register.getPluginByName(rh._activeTab, instantiate=False) |
|---|
| 136 | |
|---|
| 137 | if rh._contribId is not None: |
|---|
| 138 | vars["report"] = plugin.getContributionReport(rh._startDate, rh._endDate, |
|---|
| 139 | rh._confId, rh._contribId) |
|---|
| 140 | elif rh._confId is not None: |
|---|
| 141 | vars["report"] = plugin.getConferenceReport(rh._startDate, rh._endDate, |
|---|
| 142 | rh._confId) |
|---|
| 143 | else: |
|---|
| 144 | raise Exception(_('Cannot instantiate reports view without ID.')) |
|---|
| 145 | |
|---|
| 146 | return vars |
|---|
| 147 | |
|---|
| 148 | |
|---|
| 149 | class PluginSettingsContributor(Component): |
|---|
| 150 | |
|---|
| 151 | zope.interface.implements(IPluginSettingsContributor) |
|---|
| 152 | |
|---|
| 153 | def hasPluginSettings(self, obj, ptype, plugin): |
|---|
| 154 | return (ptype == 'statistics' and plugin == None) |
|---|
| 155 | |
|---|
| 156 | def getPluginSettingsHTML(self, obj, ptype, plugin): |
|---|
| 157 | if ptype == 'statistics' and plugin == None: |
|---|
| 158 | return WPluginSettings.forModule(indico.ext.statistics).getHTML() |
|---|
| 159 | |
|---|
| 160 | |
|---|
| 161 | class WPluginSettings(wcomponents.WTemplated): |
|---|
| 162 | |
|---|
| 163 | def getVars(self): |
|---|
| 164 | """ |
|---|
| 165 | Extend here to add more information to the plugin settings page, hence |
|---|
| 166 | allowing admin only view. |
|---|
| 167 | """ |
|---|
| 168 | return wcomponents.WTemplated.getVars(self) |
|---|
| 169 | |
|---|
| 170 | |
|---|
| 171 | class WPStatisticsView(WPConferenceModifBase): |
|---|
| 172 | |
|---|
| 173 | def __init__(self, rh, templateClass): |
|---|
| 174 | self._rh = rh |
|---|
| 175 | self._conf = self._rh._conf |
|---|
| 176 | self._register = StatisticsRegister() |
|---|
| 177 | self._plugins = self._register.getAllPlugins() |
|---|
| 178 | self._templateClass = templateClass |
|---|
| 179 | self._extraJS = [] |
|---|
| 180 | self._activeTabName = rh._activeTab |
|---|
| 181 | self._tabs = [] |
|---|
| 182 | self._tabCtrl = wcomponents.TabControl() |
|---|
| 183 | |
|---|
| 184 | def _createTabCtrl(self): |
|---|
| 185 | for plugin in self._plugins: |
|---|
| 186 | self._tabs.append(self._tabCtrl.newTab(plugin.getName(), |
|---|
| 187 | plugin.getName(), UHConfModifStatistics.getURL(self._conf, |
|---|
| 188 | tab=plugin.getName()))) |
|---|
| 189 | |
|---|
| 190 | def _getTitle(self): |
|---|
| 191 | return WPConferenceModifBase._getTitle(self) + " - " + _("Statistics") |
|---|
| 192 | |
|---|
| 193 | def _getPageContent(self, params): |
|---|
| 194 | self._createTabCtrl() |
|---|
| 195 | plugin = self._register.getPluginByName(self._activeTabName) |
|---|
| 196 | |
|---|
| 197 | if not plugin: |
|---|
| 198 | raise Exception(_('There is no tab called %s available.') % \ |
|---|
| 199 | self._activeTabName) |
|---|
| 200 | |
|---|
| 201 | return wcomponents.WTabControl(self._tabCtrl, self._getAW()).getHTML( |
|---|
| 202 | self._templateClass.forModule(plugin.getImplementationPackage(), |
|---|
| 203 | self._register, self._rh).getHTML(params)) |
|---|
| 204 | |
|---|
| 205 | def getCSSFiles(self): |
|---|
| 206 | return WPConferenceModifBase.getCSSFiles(self) + \ |
|---|
| 207 | ['statistics/css/main.css'] |
|---|
| 208 | |
|---|
| 209 | def getJSFiles(self): |
|---|
| 210 | return WPConferenceModifBase.getJSFiles(self) + \ |
|---|
| 211 | ['statistics/js/statistics.js'] |
|---|
| 212 | |
|---|
| 213 | def _setActiveSideMenuItem(self): |
|---|
| 214 | if 'Statistics' in self._pluginsDictMenuItem: |
|---|
| 215 | self._pluginsDictMenuItem['Statistics'].setActive(True) |
|---|