Commit 5b6146fc authored by Arthur Lutz's avatar Arthur Lutz
Browse files

Startup views bugfixes, refactoring, by day, etc.

parent 472ac0644907
......@@ -34,19 +34,26 @@ from cubicweb.web import formwidgets as fwdgs, httpcache
from cubes.awstats.utils import SECTIONSPEC, SECTIONLABELS, \
extract_stats_dict, ORIGIN_LABELS
def extract_available_months(form, **attrs):
""" extract available months from list of awstats files """
months = []
def extract_available_time_periods(form, **attrs):
""" extract available time periods from list of awstats files """
periods = []
selected_domain = form._cw.form.get('domain', '')
awstats_dir = form._cw.vreg.config['awstats-dir']
periodicity = form._cw.vreg.config['awstats-periodicity']
size = {
'hour':10,
'day':8,
'month':6,
}
for filename in os.listdir(awstats_dir):
match = re.search('awstats(\d{6})\.?%s.txt' % selected_domain, filename)
match = re.search('awstats(\d{%s})\.?%s.txt' % (size[periodicity], selected_domain),
filename)
if match:
months.append(match.group(1))
months.sort()
return months
periods.append((specific_format('time_period', match.group(1)),
match.group(1)))
periods.sort()
return periods
# TODO - rename extract_available_time_periods (from awstats-periodicity)
def extract_available_domains(form, **attrs):
""" extract available domains from list of awstats files """
domains = []
......@@ -72,6 +79,13 @@ def specific_format(header, value):
return
elif header == 'bandwidth':
return convert_to_bytes(int(value))
elif header == 'time_period' and len(value) in (6,8,10):
if len(value) == 8: # day
return datetime.strptime(value, '%m%Y%d').strftime('%Y/%m/%d')
elif len(value) == 6: # month
return datetime.strptime(value, '%m%Y').strftime('%Y/%m')
elif len(value) == 10: # hour
return datetime.strptime(value, '%m%Y%d%H').strftime('%Y/%m/%d %H:00')
elif value and value.startswith('http://'):
return '<a href="%s">%s</a>' % (value, value)
elif re.search('^\d{14}$', value):
......@@ -94,14 +108,13 @@ def convert_to_bytes(value):
class AwstatsRefreshForm(forms.FieldsForm):
"""Form to filter and select what stats are being displayed"""
__regid__ = 'select-awstats'
#FIXME def action cf below
action = '/?vid=awstats'
domain = StringField(widget=fwdgs.Select(attrs={'onchange':'this.form.submit()'}),
label=_('Domain:'),
choices=extract_available_domains)
month = StringField(widget=fwdgs.Select(attrs={'onchange':'this.form.submit()'}),
# TODO - use calendar widget
time_period = StringField(widget=fwdgs.Select(attrs={'onchange':'this.form.submit()'}),
label=_('Period:'),
choices=extract_available_months)
choices=extract_available_time_periods)
limit = StringField(widget=fwdgs.Select(attrs={'onchange':'this.form.submit()'}),
label=_('Number of results :'),
choices=[u'%s' % i for i in (10,25,50,100)])
......@@ -110,6 +123,9 @@ class AwstatsRefreshForm(forms.FieldsForm):
choices=[('',''),]+[(label, value) for value, label in SECTIONLABELS.items()])
form_buttons = [fwdgs.SubmitButton(label=_('Apply'))]
@property
def action(self):
return self._cw.build_url('', vid='awstats')
class AwstatsView(StartupView):
""" Simple HTML export of the stats in awstats files """
......@@ -117,28 +133,30 @@ class AwstatsView(StartupView):
def call(self):
""" main call """
_ = self._cw._
req = self._cw
form = self._cw.vreg['forms'].select('select-awstats', self._cw)
form.render(w=self.w)
domain = req.form.get('domain', '')
month = req.form.get('month', extract_available_months(form)[0])
time_period = req.form.get('time_period', extract_available_time_periods(form)[0][1])
limit = int(req.form.get('limit', 10))
filename = 'awstats%s%s.txt' % (month, domain and '.%s' % domain)
filename = 'awstats%s%s.txt' % (time_period, domain and '.%s' % domain)
awstats_dir = self._cw.vreg.config['awstats-dir']
try:
stats_dict = extract_stats_dict(osp.join(awstats_dir, filename))
except IOError:
filename = 'awstats%s%s.txt' % (extract_available_months(form)[0],
fallback_time_period = extract_available_time_periods(form)[0][1]
filename = 'awstats%s%s.txt' % (fallback_time_period,
domain and '.%s' % domain)
stats_dict = extract_stats_dict(osp.join(awstats_dir, filename))
self.w(u'<div id="awstats">')
self.w(u'<h1>%s : %s</h1>' % (_('Domain'), domain or 'default'))
self.w(u'<h2>%s : %s</h2>' % (_('Time period'),
'%s/%s' % (month[:2], month[2:]) ))
specific_format('time_period', time_period)))
if req.form.get('section'):
self.generic_table(req.form.get('section'), stats_dict, limit)
else:
......@@ -149,20 +167,22 @@ class AwstatsView(StartupView):
def render_navigation(self, stats_dict):
""" render navigation according to which sections are present """
_ = self._cw._
self.w(u'<div>')
self.w(u'<table id="navigation">')
for key in SECTIONSPEC.keys():
if key in stats_dict.keys() and stats_dict[key].values():
self.w(u'<tr><td><a href="#%s">%s</a></td></tr>' % (key, SECTIONLABELS[key]))
self.w(u'<tr><td><a href="#%s">%s</a></td></tr>' % (key, _(SECTIONLABELS[key])))
self.w(u'</table>')
self.w(u'</div>')
def generic_table(self, section_name, stats_dict, limit):
""" generic table from a section in awstats """
_ = self._cw._
if section_name not in stats_dict.keys() or not stats_dict[section_name].values():
return
self.w(u'<a name="%s"/>' % section_name)
self.w(u'<h3>%s</h3>' % SECTIONLABELS[section_name])
self.w(u'<h3>%s</h3>' % _(SECTIONLABELS[section_name]))
self.w(u'<div><table class="listing">')
self.w(u'<tr class="header">')
for header in SECTIONSPEC[section_name]:
......@@ -216,12 +236,20 @@ class WebStatsRefreshForm(forms.FieldsForm):
return self._cw.build_url('', vid='webstats')
class StatPeriodsView(StartupView):
""" Web stats view - build from StatPeriods and Hits in cubicweb """
""" Web stats view - build from StatPeriods and Hits in cubicweb
`column_types_aggr` enables you to combine results by type
For example BlogEntry and MicroBlogEntries in one table and Cards in separate table :
column_types_aggr = (('MicroBlogEntry', 'BlogEntry'),
('Card'))
"""
__regid__ = 'webstats'
column_types = None
column_types_aggr = None
http_cache_manager = httpcache.NoHTTPCacheManager
def call(self):
_ = self._cw._
req = self._cw
self.w(u'<div id="statperiod">')
......@@ -241,8 +269,7 @@ class StatPeriodsView(StartupView):
'stop': stop,
'duration':duration.days}))
self.description()
# TODO - plus gros
self.w(u'<a href="%s">%s</a>' % (self._cw.build_url(rql='Any X ORDERBY S WHERE X is StatPeriod, X start S, X stop E HAVING E-S >= 20'),
self.w(u'<h3><a href="%s">%s</a></h3>' % (self._cw.build_url(rql='Any X ORDERBY S WHERE X is StatPeriod, X start S, X stop E HAVING E-S >= 20'),
_('Navigate previous statistics by month')))
rset = self._cw.execute('DISTINCT Any T WHERE X is Hits, X hit_type T')
for index, hit_type in enumerate(rset):
......@@ -254,13 +281,13 @@ class StatPeriodsView(StartupView):
'start': start,
'stop': stop,
}
if self.column_types:
if self.column_types_aggr:
self.w(u'<table class="webstats"><tr>')
for etype in self.column_types:
for etypes in self.column_types_aggr:
self.w(u'<td class="webstats">')
typedrql = rql + ', X is in (%s)' % ','.join(etype)
typedrql = rql + ', X is in (%s)' % ','.join(etypes)
rset = self._cw.execute(typedrql)
self.generate_table_form(rset, etype)
self.generate_table_form(rset, etypes)
nolimit_rql = typedrql.replace('LIMIT %s' % limit, '')
self.w(u'<a href="%s">Export CSV</a>' % self._cw.build_url(rql=nolimit_rql,
vid='csvexport'))
......@@ -275,7 +302,7 @@ class StatPeriodsView(StartupView):
self.w(u'</div>')
def generate_table_form(self, rset, etype):
def generate_table_form(self, rset, etypes=None):
self.w(self._cw.view('table', rset, 'null'))
def description(self):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment