From 2baf4173fdfe044319252a618aa47dfda6cb3159 Mon Sep 17 00:00:00 2001 From: Gregory Soutade Date: Thu, 8 Jan 2015 21:01:33 +0100 Subject: [PATCH] Add Browsers post analysis and display --- plugins/display/browsers.py | 124 ++++++++++++++++++++++++++++++ plugins/post_analysis/browsers.py | 103 +++++++++++++++++++++++++ 2 files changed, 227 insertions(+) create mode 100644 plugins/display/browsers.py create mode 100644 plugins/post_analysis/browsers.py diff --git a/plugins/display/browsers.py b/plugins/display/browsers.py new file mode 100644 index 0000000..95b70cd --- /dev/null +++ b/plugins/display/browsers.py @@ -0,0 +1,124 @@ +# -*- coding: utf-8 -*- +# +# Copyright Grégory Soutadé 2015 + +# This file is part of iwla + +# iwla is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# iwla is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with iwla. If not, see . +# + +from iwla import IWLA +from iplugin import IPlugin +from display import * + +import awstats_data + +""" +Display hook + +Create browsers page + +Plugin requirements : + post_analysis/browsers + +Conf values needed : + max_browsers_displayed* + create_browsers_page* + +Output files : + OUTPUT_ROOT/year/month/browsers.html + OUTPUT_ROOT/year/month/index.html + +Statistics creation : + None + +Statistics update : + None + +Statistics deletion : + None +""" + +class IWLADisplayBrowsers(IPlugin): + def __init__(self, iwla): + super(IWLADisplayBrowsers, self).__init__(iwla) + self.API_VERSION = 1 + self.requires = ['IWLAPostAnalysisBrowsers'] + + def load(self): + self.icon_path = self.iwla.getConfValue('icon_path', '/') + self.max_browsers = self.iwla.getConfValue('max_browsers_displayed', 0) + self.create_browsers = self.iwla.getConfValue('create_browsers_page', True) + self.icon_names = {v:k for (k, v) in awstats_data.browsers_hashid.items()} + + return True + + def hook(self): + display = self.iwla.getDisplay() + browsers = self.iwla.getMonthStats()['browsers'] + browsers = sorted(browsers.items(), key=lambda t: t[1], reverse=True) + + # All in a file + if self.create_browsers: + title = createCurTitle(self.iwla, u'Browsers') + filename = 'browsers.html' + path = self.iwla.getCurDisplayPath(filename) + + page = display.createPage(title, path, self.iwla.getConfValue('css_path', [])) + table = display.createBlock(DisplayHTMLBlockTable, self.iwla._(u'Browsers'), ['', self.iwla._(u'Browser'), self.iwla._(u'Entrance')]) + table.setColsCSSClass(['', '', 'iwla_hit']) + total_browsers = [0]*3 + new_list = self.max_browsers and browsers[:self.max_browsers] or browsers + for (browser, entrance) in new_list: + if browser != 'unknown': + icon = '' % (self.icon_path, awstats_data.browsers_icons[self.icon_names[browser]]) + else: + icon = '' % (self.icon_path) + browser = 'Unknown' + table.appendRow([icon, browser, entrance]) + total_browsers[1] += entrance + if self.max_browsers: + others = 0 + for (browser, entrance) in browsers[self.max_browsers:]: + others += entrance + table.appendRow(['', self.iwla._(u'Others'), others]) + table.setCellCSSClass(table.getNbRows()-1, 0, 'iwla_others') + + page.appendBlock(table) + + display.addPage(page) + + title = 'Top Browsers' + if self.create_browsers: + link = '%s' % (filename, self.iwla._(u'All Browsers')) + title = '%s - %s' % (title, link) + + # Top in index + index = self.iwla.getDisplayIndex() + + table = display.createBlock(DisplayHTMLBlockTable, title, ['', self.iwla._(u'Browser'), self.iwla._(u'Entrance')]) + table.setColsCSSClass(['', '', 'iwla_hit']) + for (browser, entrance) in browsers[:10]: + if browser != 'unknown': + icon = '' % (self.icon_path, awstats_data.browsers_icons[self.icon_names[browser]]) + else: + icon = '' % (self.icon_path) + browser = 'Unknown' + table.appendRow([icon, browser, entrance]) + total_browsers[1] -= entrance + if total_browsers[1]: + total_browsers[0] = self.iwla._(u'Others') + table.appendRow(total_browsers) + table.setCellCSSClass(table.getNbRows()-1, 0, 'iwla_others') + index.appendBlock(table) diff --git a/plugins/post_analysis/browsers.py b/plugins/post_analysis/browsers.py new file mode 100644 index 0000000..2bb7b37 --- /dev/null +++ b/plugins/post_analysis/browsers.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- +# +# Copyright Grégory Soutadé 2015 + +# This file is part of iwla + +# iwla is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# iwla is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with iwla. If not, see . +# + +import re + +from iwla import IWLA +from iplugin import IPlugin + +import awstats_data + +""" +Post analysis hook + +Detect browser information from requests + +Plugin requirements : + None + +Conf values needed : + None + +Output files : + None + +Statistics creation : +visits : + remote_addr => + browser + +month_stats : + browsers => + browser => count + +Statistics update : + None + +Statistics deletion : + None +""" + +class IWLAPostAnalysisBrowsers(IPlugin): + def __init__(self, iwla): + super(IWLAPostAnalysisBrowsers, self).__init__(iwla) + self.API_VERSION = 1 + + def load(self): + self.browsers = [] + + for hashid in awstats_data.browsers: + hashid_re = re.compile(r'.*%s.*' % (hashid), re.IGNORECASE) + + if hashid in awstats_data.browsers_hashid.keys(): + self.browsers.append((hashid_re, awstats_data.browsers_hashid[hashid])) + + return True + + def hook(self): + stats = self.iwla.getValidVisitors() + month_stats = self.iwla.getMonthStats() + + browsers = month_stats.get('browsers', {}) + + browsers_stats = {} + + for (k, super_hit) in stats.items(): + if not 'browser' in super_hit: + for r in super_hit['requests'][::-1]: + user_agent = r['http_user_agent'] + if not user_agent: continue + + browser_name = 'unknown' + for (hashid_re, browser) in self.browsers: + if hashid_re.match(user_agent): + browser_name = browser + break + super_hit['browser'] = browser_name + break + else: + browser_name = super_hit['browser'] + + if not browser_name in browsers_stats.keys(): + browsers_stats[browser_name] = 1 + else: + browsers_stats[browser_name] += 1 + + month_stats['browsers'] = browsers_stats