Add report and default timeout.

This commit is contained in:
Albert Cervera i Areny 2013-10-29 23:33:11 +01:00
parent a96b86dc10
commit 245db09e54
8 changed files with 100 additions and 10 deletions

View File

@ -2,11 +2,13 @@
#repository contains the full copyright notices and license terms.
from trytond.pool import Pool
from .configuration import *
from .babi import *
def register():
Pool.register(
Configuration,
Filter,
Expression,
Report,

45
babi.py
View File

@ -55,6 +55,18 @@ def unaccent(text):
return unicodedata.normalize('NFKD', text).encode('ASCII', 'ignore')
class TimeoutChecker:
def __init__(self, timeout, callback):
self._timeout = timeout
self._callback = callback
self._start = datetime.now()
def check(self):
elapsed = (datetime.now() - self._start).seconds
if elapsed > self._timeout:
self._callback()
class DimensionIterator:
def __init__(self, values):
"""
@ -308,13 +320,18 @@ class Report(ModelSQL, ModelView):
help='Date & time of the last update.')
last_update_seconds = fields.Float('Last Update Duration (s)',
readonly=True, help='Number of seconds the last update took.')
timeout = fields.Integer('Timeout (s)', required=True, help='If report '
'calculation should take more than the specified timeout (in seconds) '
'the process will be stopped automatically.')
@classmethod
def __setup__(cls):
super(Report, cls).__setup__()
cls._error_messages.update({
'no_dimensions': ('Report "%s" has no dimensions. At least one '
'is needed.')
'is needed.'),
'timeout_exception': ('Report calculation exceeded timeout '
'limit.')
})
cls._buttons.update({
'calculate': {},
@ -322,6 +339,12 @@ class Report(ModelSQL, ModelView):
'remove_menus': {},
})
@staticmethod
def default_timeout():
Config = Pool().get('babi.configuration')
config = Config(1)
return config.default_timeout
def on_change_with_model_name(self, name=None):
return self.model.model if self.model else None
@ -713,6 +736,9 @@ class Report(ModelSQL, ModelView):
for report in reports:
report.single_update_data()
def timeout_exception(self):
self.raise_user_error('timeout_exception')
def single_update_data(self):
pool = Pool()
Model = pool.get(self.model.model)
@ -722,6 +748,8 @@ class Report(ModelSQL, ModelView):
BIModel = pool.get(self.babi_model.model)
Menu = pool.get('ir.ui.menu')
checker = TimeoutChecker(self.timeout, self.timeout_exception)
logger = logging.getLogger()
logger.info('Updating Data of report: %s' % self.rec_name)
update_start = time.time()
@ -767,6 +795,7 @@ class Report(ModelSQL, ModelView):
offset = 2000
index = 0
while index * offset < len(records):
checker.check()
logger.info('Calculated %s, %s records in %s seconds'
% (model, index * offset, datetime.today() - start))
@ -792,7 +821,7 @@ class Report(ModelSQL, ModelView):
columns=columns)
index += 1
self.update_measures()
self.update_measures(checker)
logger.info('Calc all %s records in %s seconds'
% (model, datetime.today() - start))
@ -813,7 +842,7 @@ class Report(ModelSQL, ModelView):
self.save()
logger.info('End Update Data of report: %s' % self.rec_name)
def update_measures(self):
def update_measures(self, checker):
logger = logging.getLogger(self.__name__)
def query_select(table_name, measures, group):
@ -913,6 +942,8 @@ class Report(ModelSQL, ModelView):
current_group = None
while group_by_iterator:
checker.check()
#Select
group = ['"%s"' % x for x in group_by_iterator]
measures = ['%s("%s") as %s' % (
@ -1256,13 +1287,17 @@ class Model(ModelSQL, ModelView):
# TODO: Consider using something smarter than __post_setup__()
# for the last model of the module
@classmethod
def __post_setup__(cls):
def __post_setup__7777(cls):
super(Model, cls).__post_setup__()
Report = Pool().get('babi.report')
cursor = Transaction().cursor
TableHandler = backend.get('TableHandler')
if TableHandler.table_exist(cursor, Report._table):
for report in Report.search([]):
# If new fields were added to babi.report and we're upgrading
# the module, search will probably fail with a
# psycopg2.ProgrammingError
reports = Report.search([])
for report in reports:
report.validate_model()

View File

@ -380,13 +380,20 @@
<!-- Menus -->
<menuitem id="menu_babi" name="Business Intelligence" sequence="1" />
<menuitem id="menu_babi_config" name="Configuration"
parent="menu_babi" sequence="10"/>
<menuitem id="menu_configuration" name="Configuration"
parent="menu_babi" sequence="10" icon="tryton-preferences"/>
<record model="ir.ui.menu-res.group"
id="menu_configuration_group_babi_admin">
<field name="menu" ref="menu_configuration"/>
<field name="group" ref="group_babi_admin"/>
</record>
<menuitem action="act_babi_expression" id="menu_babi_expression"
parent="menu_babi_config" sequence="10" name="Expression"/>
parent="menu_configuration" sequence="10" name="Expressions"/>
<menuitem action="act_babi_filter" id="menu_babi_filter"
parent="menu_babi_config" sequence="20" name="Filter"/>
parent="menu_configuration" sequence="20" name="Filters"/>
<menuitem action="act_babi_report" id="menu_babi_report"
parent="menu_babi" sequence="20" name="Report"/>
parent="menu_babi" sequence="20" name="Reports"/>
</data>
</tryton>

11
configuration.py Normal file
View File

@ -0,0 +1,11 @@
from trytond.model import ModelSQL, ModelView, fields, ModelSingleton
from trytond.pyson import Eval
__all__ = ['Configuration']
class Configuration(ModelSingleton, ModelSQL, ModelView):
'Business Intelligence Configuration'
__name__ = 'babi.configuration'
default_timeout = fields.Integer('Timeout (s)')

25
configuration.xml Normal file
View File

@ -0,0 +1,25 @@
<tryton>
<data>
<record model="ir.ui.view" id="babi_configuration_view_form">
<field name="model">babi.configuration</field>
<field name="type">form</field>
<field name="name">configuration_form</field>
</record>
<record model="ir.action.act_window" id="act_babi_configuration_form">
<field name="name">Business Intelligence Configuration</field>
<field name="res_model">babi.configuration</field>
</record>
<record model="ir.action.act_window.view"
id="act_babi_configuration_view1">
<field name="sequence" eval="1"/>
<field name="view" ref="babi_configuration_view_form"/>
<field name="act_window" ref="act_babi_configuration_form"/>
</record>
<menuitem string="Business Intelligence"
parent="menu_configuration"
action="act_babi_configuration_form"
id="menu_babi_configuration"
icon="tryton-list"
sequence="0"/>
</data>
</tryton>

View File

@ -5,3 +5,4 @@ depends:
res
xml:
babi.xml
configuration.xml

View File

@ -0,0 +1,7 @@
<?xml version="1.0"?>
<!--The COPYRIGHT file at the top level of this repository
contains the full copyright notices and license terms. -->
<form string="Business Intelligence Configuration">
<label name="default_timeout"/>
<field name="default_timeout"/>
</form>

View File

@ -36,6 +36,8 @@ contains the full copyright notices and license terms. -->
<field name="internal_name"/>
<label name="babi_model"/>
<field name="babi_model"/>
<label name="timeout"/>
<field name="timeout"/>
<group id="internal" colspan="4" col="2" yexpand="1" yfill="1">
<field name="actions"/>
<field name="keywords"/>