Update to 4.7

This commit is contained in:
C?dric Krier 2018-01-16 18:11:34 +01:00
parent 11943c59f8
commit 3bea3dfc7b
10 changed files with 184 additions and 89 deletions

49
.drone.yml Normal file
View file

@ -0,0 +1,49 @@
clone:
hg:
image: plugins/hg
pipeline:
tox:
image: ${IMAGE}
environment:
- CFLAGS=-O0
- DB_CACHE=/cache
- TOX_TESTENV_PASSENV=CFLAGS DB_CACHE
- POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
commands:
- pip install tox
- tox -e "${TOXENV}-${DATABASE}"
services:
postgresql:
image: postgres
when:
matrix:
DATABASE: postgresql
matrix:
include:
- IMAGE: python:2.7
TOXENV: py27
DATABASE: sqlite
- IMAGE: python:2.7
TOXENV: py27
DATABASE: postgresql
- IMAGE: python:3.4
TOXENV: py34
DATABASE: sqlite
- IMAGE: python:3.4
TOXENV: py34
DATABASE: postgresql
- IMAGE: python:3.5
TOXENV: py35
DATABASE: sqlite
- IMAGE: python:3.5
TOXENV: py35
DATABASE: postgresql
- IMAGE: python:3.6
TOXENV: py36
DATABASE: sqlite
- IMAGE: python:3.6
TOXENV: py36
DATABASE: postgresql

View file

@ -1,44 +1,43 @@
# The COPYRIGHT file at the top level of this repository contains the full # The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms. # copyright notices and license terms.
from trytond.pool import Pool from trytond.pool import Pool
from .configuration import * from . import configuration
from .cron import * from . import cron
from .babi import * from . import babi
from .test_model import * from . import test_model
def register(): def register():
Pool.register( Pool.register(
Configuration, configuration.Configuration,
Filter, babi.Filter,
FilterParameter, babi.FilterParameter,
Expression, babi.Expression,
Report, babi.Report,
ReportExecution, babi.ReportExecution,
ReportGroup, babi.ReportGroup,
Dimension, babi.Dimension,
DimensionColumn, babi.DimensionColumn,
Measure, babi.Measure,
InternalMeasure, babi.InternalMeasure,
Order, babi.Order,
ActWindow, babi.ActWindow,
Menu, babi.Menu,
Keyword, babi.Keyword,
Model, babi.Model,
Cron, cron.Cron,
OpenChartStart, babi.OpenChartStart,
OpenExecutionSelect, babi.OpenExecutionSelect,
UpdateDataWizardStart, babi.UpdateDataWizardStart,
UpdateDataWizardUpdated, babi.UpdateDataWizardUpdated,
CleanExecutionsStart, babi.CleanExecutionsStart,
TestBabiModel, test_model.TestBabiModel,
module='babi', type_='model') module='babi', type_='model')
Pool.register( Pool.register(
OpenChart, babi.OpenChart,
OpenExecution, babi.OpenExecution,
UpdateDataWizard, babi.CleanExecutions,
CleanExecutions,
module='babi', type_='wizard') module='babi', type_='wizard')
Pool.register( Pool.register(
BabiHTMLReport, babi.BabiHTMLReport,
module='babi', type_='report') module='babi', type_='report')

53
babi.py
View file

@ -21,7 +21,8 @@ from trytond.wizard import Wizard, StateView, StateAction, StateTransition, \
from trytond.model import ModelSQL, ModelView, fields, Unique, Check, \ from trytond.model import ModelSQL, ModelView, fields, Unique, Check, \
sequence_ordered sequence_ordered
from trytond.model.fields import depends from trytond.model.fields import depends
from trytond.pyson import If, Eval, Bool, PYSONEncoder, Id, In, Not, PYSONDecoder from trytond.pyson import If, Eval, Bool, PYSONEncoder, Id, In, Not, \
PYSONDecoder
from trytond.pool import Pool, PoolMeta from trytond.pool import Pool, PoolMeta
from trytond.transaction import Transaction from trytond.transaction import Transaction
from trytond.tools import grouped_slice from trytond.tools import grouped_slice
@ -36,7 +37,7 @@ __all__ = ['Filter', 'Expression', 'Report', 'ReportGroup', 'Dimension',
'DimensionColumn', 'Measure', 'InternalMeasure', 'Order', 'ActWindow', 'DimensionColumn', 'Measure', 'InternalMeasure', 'Order', 'ActWindow',
'Menu', 'Keyword', 'Model', 'OpenChartStart', 'OpenChart', 'Menu', 'Keyword', 'Model', 'OpenChartStart', 'OpenChart',
'ReportExecution', 'OpenExecutionSelect', 'OpenExecution', 'ReportExecution', 'OpenExecutionSelect', 'OpenExecution',
'UpdateDataWizardStart', 'UpdateDataWizardUpdated', 'UpdateDataWizard', 'UpdateDataWizardStart', 'UpdateDataWizardUpdated',
'FilterParameter', 'CleanExecutionsStart', 'CleanExecutions', 'FilterParameter', 'CleanExecutionsStart', 'CleanExecutions',
'BabiHTMLReport'] 'BabiHTMLReport']
@ -66,12 +67,10 @@ BABI_RETENTION_DAYS = config_.getint('babi', 'retention_days', default=30)
BABI_CELERY_TASK = config_.get('babi', 'celery_task', BABI_CELERY_TASK = config_.get('babi', 'celery_task',
default='trytond.modules.babi.tasks.calculate_execution') default='trytond.modules.babi.tasks.calculate_execution')
CELERY_AVAILABLE = False
try: try:
import celery import celery
CELERY_AVAILABLE = True
except ImportError: except ImportError:
pass celery = None
except AttributeError: except AttributeError:
# If run from within frepple we will get # If run from within frepple we will get
# AttributeError: 'module' object has no attribute 'argv' # AttributeError: 'module' object has no attribute 'argv'
@ -468,9 +467,9 @@ class FilterParameter(ModelSQL, ModelView):
def check_parameter_in_filter(self): def check_parameter_in_filter(self):
placeholder = '{%s}' % self.name placeholder = '{%s}' % self.name
if ((self.filter.domain and placeholder not in self.filter.domain) and if ((self.filter.domain and placeholder not in self.filter.domain)
(self.filter.python_expression and placeholder not in and (self.filter.python_expression
self.filter.python_expression)): and placeholder not in self.filter.python_expression)):
self.raise_user_warning('babi_check_parameter_in_filter.{}'.format( self.raise_user_warning('babi_check_parameter_in_filter.{}'.format(
self.name), 'parameter_not_found', { self.name), 'parameter_not_found', {
'parameter': self.rec_name, 'parameter': self.rec_name,
@ -869,15 +868,17 @@ class Report(ModelSQL, ModelView):
logger.info('Babi execution %s (report "%s")' % ( logger.info('Babi execution %s (report "%s")' % (
execution.id, self.rec_name)) execution.id, self.rec_name))
if CELERY_AVAILABLE and BABI_CELERY: if celery and BABI_CELERY:
os.system('%s/celery call %s --broker=%s --args=[%d,%d] --config="%s" --queue=%s' % ( os.system(
os.path.dirname(sys.executable), '%s/celery call %s '
BABI_CELERY_TASK, '--broker=%s --args=[%d,%d] --config="%s" --queue=%s' % (
CELERY_BROKER, os.path.dirname(sys.executable),
execution.id, BABI_CELERY_TASK,
user, CELERY_BROKER,
CELERY_CONFIG, execution.id,
database_name)) user,
CELERY_CONFIG,
database_name))
else: else:
# Fallback to synchronous mode if celery is not available # Fallback to synchronous mode if celery is not available
Execution.calculate([execution]) Execution.calculate([execution])
@ -1057,7 +1058,6 @@ class ReportExecution(ModelSQL, ModelView):
# The model may not be registered on the pool # The model may not be registered on the pool
continue continue
@classmethod @classmethod
def remove_keywords(cls, executions): def remove_keywords(cls, executions):
pool = Pool() pool = Pool()
@ -1186,7 +1186,8 @@ class ReportExecution(ModelSQL, ModelView):
def get_python_filter(self): def get_python_filter(self):
if self.report.filter and self.report.filter.python_expression: if self.report.filter and self.report.filter.python_expression:
return self.replace_parameters(self.report.filter.python_expression) return self.replace_parameters(
self.report.filter.python_expression)
def get_domain_filter(self): def get_domain_filter(self):
domain = '[]' domain = '[]'
@ -1719,8 +1720,6 @@ class OpenExecutionFiltered(StateView):
parameter2report[key] = [report.id] parameter2report[key] = [report.id]
report_definition['domain'] = ['id', 'in', [r.id for r in reports]] report_definition['domain'] = ['id', 'in', [r.id for r in reports]]
if not parameters:
self.raise_user_error('no_filter_parameter', model.model)
parameters_to_remove = [] parameters_to_remove = []
for parameter in parameters: for parameter in parameters:
if not parameter.check_parameter_in_filter(): if not parameter.check_parameter_in_filter():
@ -1822,11 +1821,6 @@ class UpdateDataWizardUpdated(ModelView):
__name__ = 'babi.update_data.wizard.done' __name__ = 'babi.update_data.wizard.done'
class UpdateDataWizard(Wizard):
"Update Data Wizard"
__name__ = 'babi.update_data.wizard'
class OpenExecution(Wizard): class OpenExecution(Wizard):
'Open Report Execution' 'Open Report Execution'
__name__ = 'babi.report.execution.open' __name__ = 'babi.report.execution.open'
@ -1860,9 +1854,6 @@ class OpenExecution(Wizard):
'no_report': ('No report found for current execution'), 'no_report': ('No report found for current execution'),
'no_execution': ('No execution found for current record. ' 'no_execution': ('No execution found for current record. '
'Execute the update data wizard in order to create one.'), 'Execute the update data wizard in order to create one.'),
'no_filter_parameter': ('No parameter found for model %s.'
'In order to view filtered data, parameter should be'
' defined on the report filter.'),
}) })
def __getattribute__(self, name): def __getattribute__(self, name):
@ -2022,7 +2013,7 @@ class DimensionMixin:
@staticmethod @staticmethod
def order_sequence(tables): def order_sequence(tables):
table, _ = tables[None] table, _ = tables[None]
return [table.sequence == None, table.sequence] return [table.sequence == Null, table.sequence]
@staticmethod @staticmethod
def default_group_by(): def default_group_by():
@ -2156,7 +2147,7 @@ class Measure(ModelSQL, ModelView):
@staticmethod @staticmethod
def order_sequence(tables): def order_sequence(tables):
table, _ = tables[None] table, _ = tables[None]
return [table.sequence == None, table.sequence] return [table.sequence == Null, table.sequence]
@staticmethod @staticmethod
def default_aggregate(): def default_aggregate():

View file

@ -9,6 +9,6 @@ TRYTON_CONFIG = os.environ.get('TRYTON_CONFIG')
CELERY_ALWAYS_EAGER = False CELERY_ALWAYS_EAGER = False
CELERY_EAGER_PROPAGATES_EXCEPTIONS = False CELERY_EAGER_PROPAGATES_EXCEPTIONS = False
CELERY_TASK_TIME_LIMIT = 7200 CELERY_TASK_TIME_LIMIT = 7200
CELERYD_TASK_SOFT_TIME_LIMIT = 7200 CELERYD_TASK_SOFT_TIME_LIMIT = 7200
CELERY_MAX_TASKS_PER_CHILD = 2 CELERY_MAX_TASKS_PER_CHILD = 2
CELERY_ACCEPT_CONTENT = ['json'] CELERY_ACCEPT_CONTENT = ['json']

View file

@ -6,43 +6,72 @@
from setuptools import setup from setuptools import setup
import re import re
import os import os
import ConfigParser import io
try:
from configparser import ConfigParser
except ImportError:
from ConfigParser import ConfigParser
MODULE = 'babi' MODULE = 'babi'
PREFIX = 'nantic' PREFIX = 'nantic'
MODULE2PREFIX = { MODULE2PREFIX = {
'html_report': 'trytonspain', 'html_report': 'trytonspain',
} }
def read(fname): def read(fname):
return open(os.path.join(os.path.dirname(__file__), fname)).read() return io.open(
os.path.join(os.path.dirname(__file__), fname),
'r', encoding='utf-8').read()
config = ConfigParser.ConfigParser()
def get_require_version(name):
if minor_version % 2:
require = '%s >= %s.%s.dev0, < %s.%s'
else:
require = '%s >= %s.%s, < %s.%s'
require %= (name, major_version, minor_version,
major_version, minor_version + 1)
return require
config = ConfigParser()
config.readfp(open('tryton.cfg')) config.readfp(open('tryton.cfg'))
info = dict(config.items('tryton')) info = dict(config.items('tryton'))
for key in ('depends', 'extras_depend', 'xml'): for key in ('depends', 'extras_depend', 'xml'):
if key in info: if key in info:
info[key] = info[key].strip().splitlines() info[key] = info[key].strip().splitlines()
major_version, minor_version, _ = info.get('version', '0.0.1').split('.', 2) version = info.get('version', '0.0.1')
major_version, minor_version, _ = version.split('.', 2)
major_version = int(major_version) major_version = int(major_version)
minor_version = int(minor_version) minor_version = int(minor_version)
requires = ['celery_tryton'] requires = []
for dep in info.get('depends', []): for dep in info.get('depends', []):
if not re.match(r'(ir|res|webdav)(\W|$)', dep): if not re.match(r'(ir|res)(\W|$)', dep):
prefix = MODULE2PREFIX.get(dep, 'trytond') prefix = MODULE2PREFIX.get(dep, 'trytond')
requires.append('%s_%s >= %s.%s, < %s.%s' % requires.append(get_require_version('%s_%s' % (prefix, dep)))
(prefix, dep, major_version, minor_version, requires.append(get_require_version('trytond'))
major_version, minor_version + 1))
requires.append('trytond >= %s.%s, < %s.%s' %
(major_version, minor_version, major_version, minor_version + 1))
tests_require = ['proteus >= %s.%s, < %s.%s' % tests_require = ['pytz']
(major_version, minor_version, major_version, minor_version + 1)] series = '%s.%s' % (major_version, minor_version)
if minor_version % 2:
branch = 'default'
else:
branch = series
dependency_links = [
('hg+https://bitbucket.org/trytonspain/'
'trytond-html_report@%(branch)s'
'#egg=trytonspain-html_report-%(series)s' % {
'branch': branch,
'series': series,
}),
]
if minor_version % 2:
# Add development index for testing with proteus
dependency_links.append('https://trydevpi.tryton.org/')
setup(name='%s_%s' % (PREFIX, MODULE), setup(name='%s_%s' % (PREFIX, MODULE),
version=info.get('version', '0.0.1'), version=version,
description='Business Inteligence module for tryton', description='Business Inteligence module for tryton',
long_description=read('README'), long_description=read('README'),
author='NaN-tic', author='NaN-tic',
@ -55,7 +84,7 @@ setup(name='%s_%s' % (PREFIX, MODULE),
], ],
package_data={ package_data={
'trytond.modules.%s' % MODULE: (info.get('xml', []) 'trytond.modules.%s' % MODULE: (info.get('xml', [])
+ ['tryton.cfg', 'locale/*.po', 'view/*.xml', 'tests/*.rst']), + ['tryton.cfg', 'view/*.xml', 'locale/*.po']),
}, },
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
@ -75,12 +104,17 @@ setup(name='%s_%s' % (PREFIX, MODULE),
'Natural Language :: Russian', 'Natural Language :: Russian',
'Natural Language :: Spanish', 'Natural Language :: Spanish',
'Operating System :: OS Independent', 'Operating System :: OS Independent',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Office/Business', 'Topic :: Office/Business',
], ],
license='GPL-3', license='GPL-3',
install_requires=requires, install_requires=requires,
dependency_links=dependency_links,
zip_safe=False, zip_safe=False,
entry_points=""" entry_points="""
[trytond.modules] [trytond.modules]

View file

@ -3,6 +3,7 @@
from trytond.pool import Pool from trytond.pool import Pool
from trytond.transaction import Transaction from trytond.transaction import Transaction
def calculate_execution(execution_id, user_id=None): def calculate_execution(execution_id, user_id=None):
'Calculates exectuion data passed by parameters' 'Calculates exectuion data passed by parameters'
pool = Pool() pool = Pool()

View file

@ -1,4 +1,8 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of # This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms. # this repository contains the full copyright notices and license terms.
try:
from trytond.modules.babi.tests.test_babi import suite
except ImportError:
from .test_babi import suite
from .test_babi import suite __all__ = ['suite']

View file

@ -111,7 +111,6 @@ class BaBITestCase(ModuleTestCase):
Report = pool.get('babi.report') Report = pool.get('babi.report')
Expression = pool.get('babi.expression') Expression = pool.get('babi.expression')
Dimension = pool.get('babi.dimension') Dimension = pool.get('babi.dimension')
Expression = pool.get('babi.expression')
Measure = pool.get('babi.measure') Measure = pool.get('babi.measure')
company = create_company() company = create_company()
@ -488,8 +487,8 @@ class BaBITestCase(ModuleTestCase):
evens = ReportModel.search([(category.internal_name, '=', 'even')]) evens = ReportModel.search([(category.internal_name, '=', 'even')])
self.assertEqual(len(evens), 0) self.assertEqual(len(evens), 0)
#Test with datetime fields as they are JSONEncoded on saved # Test with datetime fields as they are JSONEncoded
#searches # on saved searches
date_filter, = Filter.search([('name', '=', 'Date')]) date_filter, = Filter.search([('name', '=', 'Date')])
report, = Report.create([{ report, = Report.create([{
'name': 'Date filter Report', 'name': 'Date filter Report',

18
tox.ini Normal file
View file

@ -0,0 +1,18 @@
[tox]
envlist = {py27,py34,py35,py36}-{sqlite,postgresql,mysql},pypy-{sqlite,postgresql}
[testenv]
commands = {envpython} setup.py test
deps =
{py27,py34,py35,py36}-postgresql: psycopg2 >= 2.5
pypy-postgresql: psycopg2cffi >= 2.5
mysql: MySQL-python
sqlite: sqlitebck
setenv =
sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
mysql: TRYTOND_DATABASE_URI={env:MYSQL_URI:mysql://}
sqlite: DB_NAME={env:SQLITE_NAME::memory:}
postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
mysql: DB_NAME={env:MYSQL_NAME:test}
install_command = pip install --pre --process-dependency-links {opts} {packages}

View file

@ -1,5 +1,5 @@
[tryton] [tryton]
version=4.3.0 version=4.7.0
depends: depends:
ir ir
res res