Add report and default timeout.
This commit is contained in:
parent
a96b86dc10
commit
245db09e54
|
@ -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
45
babi.py
|
@ -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()
|
||||
|
||||
|
||||
|
|
17
babi.xml
17
babi.xml
|
@ -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>
|
||||
|
|
|
@ -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)')
|
|
@ -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>
|
|
@ -5,3 +5,4 @@ depends:
|
|||
res
|
||||
xml:
|
||||
babi.xml
|
||||
configuration.xml
|
||||
|
|
|
@ -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>
|
|
@ -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"/>
|
||||
|
|
Loading…
Reference in New Issue