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 ...@@ -34,19 +34,26 @@ from cubicweb.web import formwidgets as fwdgs, httpcache
from cubes.awstats.utils import SECTIONSPEC, SECTIONLABELS, \ from cubes.awstats.utils import SECTIONSPEC, SECTIONLABELS, \
extract_stats_dict, ORIGIN_LABELS extract_stats_dict, ORIGIN_LABELS
def extract_available_months(form, **attrs): def extract_available_time_periods(form, **attrs):
""" extract available months from list of awstats files """ """ extract available time periods from list of awstats files """
months = [] periods = []
selected_domain = form._cw.form.get('domain', '') selected_domain = form._cw.form.get('domain', '')
awstats_dir = form._cw.vreg.config['awstats-dir'] 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): 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: if match:
months.append(match.group(1)) periods.append((specific_format('time_period', match.group(1)),
months.sort() match.group(1)))
return months periods.sort()
return periods
# TODO - rename extract_available_time_periods (from awstats-periodicity)
def extract_available_domains(form, **attrs): def extract_available_domains(form, **attrs):
""" extract available domains from list of awstats files """ """ extract available domains from list of awstats files """
domains = [] domains = []
...@@ -72,6 +79,13 @@ def specific_format(header, value): ...@@ -72,6 +79,13 @@ def specific_format(header, value):
return return
elif header == 'bandwidth': elif header == 'bandwidth':
return convert_to_bytes(int(value)) 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://'): elif value and value.startswith('http://'):
return '<a href="%s">%s</a>' % (value, value) return '<a href="%s">%s</a>' % (value, value)
elif re.search('^\d{14}$', value): elif re.search('^\d{14}$', value):
...@@ -94,14 +108,13 @@ def convert_to_bytes(value): ...@@ -94,14 +108,13 @@ def convert_to_bytes(value):
class AwstatsRefreshForm(forms.FieldsForm): class AwstatsRefreshForm(forms.FieldsForm):
"""Form to filter and select what stats are being displayed""" """Form to filter and select what stats are being displayed"""
__regid__ = 'select-awstats' __regid__ = 'select-awstats'
#FIXME def action cf below
action = '/?vid=awstats'
domain = StringField(widget=fwdgs.Select(attrs={'onchange':'this.form.submit()'}), domain = StringField(widget=fwdgs.Select(attrs={'onchange':'this.form.submit()'}),
label=_('Domain:'), label=_('Domain:'),
choices=extract_available_domains) 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:'), label=_('Period:'),
choices=extract_available_months) choices=extract_available_time_periods)
limit = StringField(widget=fwdgs.Select(attrs={'onchange':'this.form.submit()'}), limit = StringField(widget=fwdgs.Select(attrs={'onchange':'this.form.submit()'}),
label=_('Number of results :'), label=_('Number of results :'),
choices=[u'%s' % i for i in (10,25,50,100)]) choices=[u'%s' % i for i in (10,25,50,100)])
...@@ -110,6 +123,9 @@ class AwstatsRefreshForm(forms.FieldsForm): ...@@ -110,6 +123,9 @@ class AwstatsRefreshForm(forms.FieldsForm):
choices=[('',''),]+[(label, value) for value, label in SECTIONLABELS.items()]) choices=[('',''),]+[(label, value) for value, label in SECTIONLABELS.items()])
form_buttons = [fwdgs.SubmitButton(label=_('Apply'))] form_buttons = [fwdgs.SubmitButton(label=_('Apply'))]
@property
def action(self):
return self._cw.build_url('', vid='awstats')
class AwstatsView(StartupView): class AwstatsView(StartupView):
""" Simple HTML export of the stats in awstats files """ """ Simple HTML export of the stats in awstats files """
...@@ -117,28 +133,30 @@ class AwstatsView(StartupView): ...@@ -117,28 +133,30 @@ class AwstatsView(StartupView):
def call(self): def call(self):
""" main call """ """ main call """
_ = self._cw._
req = self._cw req = self._cw
form = self._cw.vreg['forms'].select('select-awstats', self._cw) form = self._cw.vreg['forms'].select('select-awstats', self._cw)
form.render(w=self.w) form.render(w=self.w)
domain = req.form.get('domain', '') 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)) 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'] awstats_dir = self._cw.vreg.config['awstats-dir']
try: try:
stats_dict = extract_stats_dict(osp.join(awstats_dir, filename)) stats_dict = extract_stats_dict(osp.join(awstats_dir, filename))
except IOError: 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) domain and '.%s' % domain)
stats_dict = extract_stats_dict(osp.join(awstats_dir, filename)) stats_dict = extract_stats_dict(osp.join(awstats_dir, filename))
self.w(u'<div id="awstats">') self.w(u'<div id="awstats">')
self.w(u'<h1>%s : %s</h1>' % (_('Domain'), domain or 'default')) self.w(u'<h1>%s : %s</h1>' % (_('Domain'), domain or 'default'))
self.w(u'<h2>%s : %s</h2>' % (_('Time period'), 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'): if req.form.get('section'):
self.generic_table(req.form.get('section'), stats_dict, limit) self.generic_table(req.form.get('section'), stats_dict, limit)
else: else:
...@@ -149,20 +167,22 @@ class AwstatsView(StartupView): ...@@ -149,20 +167,22 @@ class AwstatsView(StartupView):
def render_navigation(self, stats_dict): def render_navigation(self, stats_dict):
""" render navigation according to which sections are present """ """ render navigation according to which sections are present """
_ = self._cw._
self.w(u'<div>') self.w(u'<div>')
self.w(u'<table id="navigation">') self.w(u'<table id="navigation">')
for key in SECTIONSPEC.keys(): for key in SECTIONSPEC.keys():
if key in stats_dict.keys() and stats_dict[key].values(): 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'</table>')
self.w(u'</div>') self.w(u'</div>')
def generic_table(self, section_name, stats_dict, limit): def generic_table(self, section_name, stats_dict, limit):
""" generic table from a section in awstats """ """ generic table from a section in awstats """
_ = self._cw._
if section_name not in stats_dict.keys() or not stats_dict[section_name].values(): if section_name not in stats_dict.keys() or not stats_dict[section_name].values():
return return
self.w(u'<a name="%s"/>' % section_name) 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'<div><table class="listing">')
self.w(u'<tr class="header">') self.w(u'<tr class="header">')
for header in SECTIONSPEC[section_name]: for header in SECTIONSPEC[section_name]:
...@@ -216,12 +236,20 @@ class WebStatsRefreshForm(forms.FieldsForm): ...@@ -216,12 +236,20 @@ class WebStatsRefreshForm(forms.FieldsForm):
return self._cw.build_url('', vid='webstats') return self._cw.build_url('', vid='webstats')
class StatPeriodsView(StartupView): 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' __regid__ = 'webstats'
column_types = None column_types_aggr = None
http_cache_manager = httpcache.NoHTTPCacheManager http_cache_manager = httpcache.NoHTTPCacheManager
def call(self): def call(self):
_ = self._cw._
req = self._cw req = self._cw
self.w(u'<div id="statperiod">') self.w(u'<div id="statperiod">')
...@@ -241,8 +269,7 @@ class StatPeriodsView(StartupView): ...@@ -241,8 +269,7 @@ class StatPeriodsView(StartupView):
'stop': stop, 'stop': stop,
'duration':duration.days})) 'duration':duration.days}))
self.description() self.description()
# TODO - plus gros 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'),
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'),
_('Navigate previous statistics by month'))) _('Navigate previous statistics by month')))
rset = self._cw.execute('DISTINCT Any T WHERE X is Hits, X hit_type T') rset = self._cw.execute('DISTINCT Any T WHERE X is Hits, X hit_type T')
for index, hit_type in enumerate(rset): for index, hit_type in enumerate(rset):
...@@ -254,13 +281,13 @@ class StatPeriodsView(StartupView): ...@@ -254,13 +281,13 @@ class StatPeriodsView(StartupView):
'start': start, 'start': start,
'stop': stop, 'stop': stop,
} }
if self.column_types: if self.column_types_aggr:
self.w(u'<table class="webstats"><tr>') 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">') 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) rset = self._cw.execute(typedrql)
self.generate_table_form(rset, etype) self.generate_table_form(rset, etypes)
nolimit_rql = typedrql.replace('LIMIT %s' % limit, '') nolimit_rql = typedrql.replace('LIMIT %s' % limit, '')
self.w(u'<a href="%s">Export CSV</a>' % self._cw.build_url(rql=nolimit_rql, self.w(u'<a href="%s">Export CSV</a>' % self._cw.build_url(rql=nolimit_rql,
vid='csvexport')) vid='csvexport'))
...@@ -275,7 +302,7 @@ class StatPeriodsView(StartupView): ...@@ -275,7 +302,7 @@ class StatPeriodsView(StartupView):
self.w(u'</div>') 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')) self.w(self._cw.view('table', rset, 'null'))
def description(self): 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