Refactor of trytond.config to add cache
This removes the need to store configuration in global variable and so make it easier to update for example for testing. Closes #14249
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.model import fields
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.pyson import Bool, Eval
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
from sql import Table
|
||||
from sql.operators import Concat
|
||||
|
||||
from trytond import backend
|
||||
from trytond.config import config
|
||||
from trytond import backend, config
|
||||
from trytond.model import fields
|
||||
from trytond.pool import PoolMeta
|
||||
from trytond.pyson import Eval
|
||||
|
||||
@@ -9,7 +9,7 @@ from zeep import Client
|
||||
from zeep.exceptions import Error as ZeepError
|
||||
from zeep.transports import Transport
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import Index, ModelSQL, ModelView, Unique, Workflow, fields
|
||||
from trytond.model.exceptions import AccessError
|
||||
@@ -21,9 +21,6 @@ from trytond.transaction import Transaction
|
||||
|
||||
from .exceptions import ESSIIPostedInvoicesError
|
||||
|
||||
CERT = (
|
||||
config.get('account_es_sii', 'certificate'),
|
||||
config.get('account_es_sii', 'privatekey'))
|
||||
SEND_SIZE = 10000
|
||||
|
||||
|
||||
@@ -79,15 +76,19 @@ class CredentialSII(ModelSQL, CompanyValueMixin):
|
||||
def get_client(cls, endpoint, **pattern):
|
||||
pool = Pool()
|
||||
Configuration = pool.get('account.configuration')
|
||||
config = Configuration(1)
|
||||
url = WS_URL.get(config.get_multivalue('es_sii_url', **pattern), '')
|
||||
configuration = Configuration(1)
|
||||
url = WS_URL.get(
|
||||
configuration.get_multivalue('es_sii_url', **pattern), '')
|
||||
if not url:
|
||||
raise AccessError(
|
||||
gettext('account_es_sii.msg_missing_sii_url'))
|
||||
service = endpoint
|
||||
environment = config.get_multivalue('es_sii_environment', **pattern)
|
||||
environment = configuration.get_multivalue(
|
||||
'es_sii_environment', **pattern)
|
||||
session = Session()
|
||||
session.cert = CERT
|
||||
session.cert = (
|
||||
config.get('account_es_sii', 'certificate'),
|
||||
config.get('account_es_sii', 'privatekey'))
|
||||
transport = Transport(session=session)
|
||||
client = Client(url + endpoint + '.wsdl', transport=transport)
|
||||
if environment == 'staging':
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import ModelSQL, ModelView, Workflow, fields
|
||||
from trytond.model.exceptions import AccessError
|
||||
|
||||
@@ -7,18 +7,13 @@ from sql import Table
|
||||
from sql.aggregate import Sum
|
||||
from sql.conditionals import Coalesce
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.model import ModelStorage, ModelView, fields
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.pyson import Eval
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.wizard import Button, StateTransition, StateView, Wizard
|
||||
|
||||
OPENING_CODE = config.get('account_fr', 'fec_opening_code', default="OUV")
|
||||
OPENING_NAME = config.get(
|
||||
'account_fr', 'fec_opening_name', default="Balance Initiale")
|
||||
OPENING_NUMBER = config.get('account_fr', 'fec_opening_number', default="0")
|
||||
|
||||
|
||||
class AccountTemplate(metaclass=PoolMeta):
|
||||
__name__ = 'account.account.template'
|
||||
@@ -215,9 +210,15 @@ class FrFEC(Wizard):
|
||||
else:
|
||||
debit, credit = 0, -balance
|
||||
yield [
|
||||
OPENING_CODE,
|
||||
OPENING_NAME,
|
||||
OPENING_NUMBER,
|
||||
config.get(
|
||||
'account_fr', 'fec_opening_code',
|
||||
default="OUV"),
|
||||
config.get(
|
||||
'account_fr', 'fec_opening_name',
|
||||
default="Balance Initiale"),
|
||||
config.get(
|
||||
'account_fr', 'fec_opening_number',
|
||||
default="0"),
|
||||
format_date(self.start.fiscalyear.start_date),
|
||||
code,
|
||||
name,
|
||||
|
||||
@@ -10,7 +10,7 @@ from oauthlib.oauth2 import BackendApplicationClient, TokenExpiredError
|
||||
from requests_oauthlib import OAuth2Session
|
||||
from sql.functions import CharLength
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import ModelSQL, ModelView, Unique, Workflow, fields
|
||||
from trytond.model.exceptions import AccessError
|
||||
@@ -35,7 +35,6 @@ EDOC2SYNTAX = {
|
||||
EDOC2FILENAME = {
|
||||
'edocument.uncefact.invoice': 'UNCEFACT-%s.xml',
|
||||
}
|
||||
TIMEOUT = config.getfloat('account_fr_chorus', 'requests_timeout', default=300)
|
||||
if config.getboolean('account_fr_chorus', 'filestore', default=False):
|
||||
file_id = 'data_file_id'
|
||||
store_prefix = config.get(
|
||||
@@ -150,15 +149,17 @@ class CredentialChorus(ModelSQL, CompanyValueMixin):
|
||||
headers = {
|
||||
'cpro-account': base64.b64encode(account.encode('utf-8')),
|
||||
}
|
||||
timeout = config.getfloat(
|
||||
'account_fr_chorus', 'requests_timeout', default=300)
|
||||
try:
|
||||
resp = session.post(
|
||||
url, headers=headers, json=payload,
|
||||
verify=True, timeout=TIMEOUT)
|
||||
verify=True, timeout=timeout)
|
||||
except TokenExpiredError:
|
||||
cls._get_token(session)
|
||||
resp = session.post(
|
||||
url, headers=headers, json=payload,
|
||||
verify=True, timeout=TIMEOUT)
|
||||
verify=True, timeout=timeout)
|
||||
resp.raise_for_status()
|
||||
return resp.json()
|
||||
|
||||
|
||||
@@ -12,8 +12,7 @@ from sql.conditionals import Coalesce
|
||||
from sql.functions import CharLength, Round
|
||||
from sql.operators import Exists
|
||||
|
||||
from trytond import backend
|
||||
from trytond.config import config
|
||||
from trytond import backend, config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import (
|
||||
DeactivableMixin, Index, ModelSQL, ModelView, Unique, Workflow, dualmethod,
|
||||
|
||||
@@ -14,8 +14,8 @@ except ImportError:
|
||||
class GatewayTimeoutError(Exception):
|
||||
pass
|
||||
|
||||
import trytond.config as config
|
||||
from trytond.cache import Cache
|
||||
from trytond.config import config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import (
|
||||
DeactivableMixin, Index, ModelSQL, ModelView, Workflow, fields)
|
||||
|
||||
@@ -15,7 +15,7 @@ from genshi.template.astutil import ASTCodeGenerator, ASTTransformer
|
||||
from lxml import etree
|
||||
from sql import Literal, Null
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import (
|
||||
Index, ModelSQL, ModelView, Unique, Workflow, dualmethod, fields)
|
||||
|
||||
@@ -10,8 +10,8 @@ from operator import attrgetter
|
||||
|
||||
import stripe
|
||||
|
||||
import trytond.config as config
|
||||
from trytond.cache import Cache
|
||||
from trytond.config import config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import (
|
||||
DeactivableMixin, Index, ModelSQL, ModelView, Unique, Workflow, dualmethod,
|
||||
|
||||
@@ -10,7 +10,7 @@ from sql.conditionals import Coalesce
|
||||
from sql.functions import CharLength
|
||||
from sql.operators import Concat
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import (
|
||||
Check, DictSchemaMixin, Index, ModelSQL, ModelView, Workflow, fields,
|
||||
|
||||
@@ -13,7 +13,7 @@ import saml2
|
||||
import saml2.client
|
||||
import saml2.config
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.protocols.dispatcher import register_authentication_service
|
||||
from trytond.protocols.wrappers import (
|
||||
Response, abort, allow_null_origin, exceptions, redirect, with_pool,
|
||||
|
||||
@@ -4,7 +4,7 @@ import datetime
|
||||
import logging
|
||||
import random
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.exceptions import LoginException
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import Index, ModelSQL, fields
|
||||
@@ -15,11 +15,10 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def send_sms(text, to):
|
||||
if config.has_option('authentication_sms', 'function'):
|
||||
func = resolve(config.get('authentication_sms', 'function'))
|
||||
if func:
|
||||
from_ = config.get('authentication_sms', 'from', default=None)
|
||||
return func(text, to, from_)
|
||||
if func := config.get('authentication_sms', 'function', default=None):
|
||||
func = resolve(func)
|
||||
from_ = config.get('authentication_sms', 'from', default=None)
|
||||
return func(text, to, from_)
|
||||
logger.error('Could not send SMS to %s: "%s"', to, text)
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
import datetime
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.exceptions import LoginException
|
||||
from trytond.pool import Pool
|
||||
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
|
||||
|
||||
@@ -11,7 +11,7 @@ try:
|
||||
except ImportError:
|
||||
PIL = None
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import (
|
||||
MatchMixin, ModelSQL, ModelView, Unique, fields, sequence_ordered)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
from trytond.config import config
|
||||
|
||||
import trytond.config as config
|
||||
from trytond.model import fields
|
||||
from trytond.pool import PoolMeta
|
||||
|
||||
|
||||
@@ -6,14 +6,13 @@ from decimal import Decimal
|
||||
import requests
|
||||
from lxml import etree
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.modules.currency.currency import CronFetchError
|
||||
from trytond.pool import PoolMeta
|
||||
from trytond.pyson import Eval, If
|
||||
|
||||
URL_10DAYS = 'https://bnr.ro/nbrfxrates10days.xml'
|
||||
URL_YEAR = 'https://bnr.ro/files/xml/years/nbrfxrates%s.xml'
|
||||
TIMEOUT = config.getfloat('currency_ro', 'requests_timeout', default=300)
|
||||
|
||||
|
||||
class Cron(metaclass=PoolMeta):
|
||||
@@ -35,8 +34,10 @@ class Cron(metaclass=PoolMeta):
|
||||
url = URL_10DAYS
|
||||
else:
|
||||
url = URL_YEAR % date.year
|
||||
timeout = config.getfloat(
|
||||
'currency_ro', 'requests_timeout', default=300)
|
||||
try:
|
||||
response = requests.get(url, timeout=TIMEOUT)
|
||||
response = requests.get(url, timeout=timeout)
|
||||
except requests.HTTPError as e:
|
||||
raise CronFetchError() from e
|
||||
tree = etree.fromstring(response.content)
|
||||
|
||||
@@ -6,8 +6,8 @@ from lxml import objectify
|
||||
from zeep import Client, Transport
|
||||
from zeep.exceptions import Error
|
||||
|
||||
import trytond.config as config
|
||||
from trytond.cache import Cache
|
||||
from trytond.config import config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import fields
|
||||
from trytond.modules.currency.currency import CronFetchError
|
||||
@@ -19,11 +19,11 @@ from .exceptions import RSCredentialWarning
|
||||
URL = (
|
||||
'https://webservices.nbs.rs/CommunicationOfficeService1_0/'
|
||||
'ExchangeRateXmlService.asmx?WSDL')
|
||||
TIMEOUT = config.getfloat('currency_rs', 'requests_timeout', default=300)
|
||||
|
||||
|
||||
def get_client(username, password, license_id):
|
||||
client = Client(URL, transport=Transport(operation_timeout=TIMEOUT))
|
||||
timeout = config.getfloat('currency_rs', 'requests_timeout', default=300)
|
||||
client = Client(URL, transport=Transport(operation_timeout=timeout))
|
||||
client.set_default_soapheaders({
|
||||
'AuthenticationHeader': {
|
||||
'UserName': username,
|
||||
|
||||
@@ -7,7 +7,7 @@ from io import BytesIO
|
||||
|
||||
from pypdf import PdfReader, PdfWriter
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import (
|
||||
DeactivableMixin, ModelSingleton, ModelSQL, ModelView, Workflow, fields)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import base64
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.protocols.wrappers import (
|
||||
HTTPStatus, Response, abort, set_max_request_size, user_application,
|
||||
with_pool, with_transaction)
|
||||
|
||||
@@ -11,7 +11,7 @@ from email.policy import default as email_policy_default
|
||||
from email.utils import getaddresses
|
||||
from functools import partial
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.model import (
|
||||
ModelSQL, ModelStorage, ModelView, fields, sequence_ordered)
|
||||
from trytond.pool import Pool
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import json
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.protocols.wrappers import (
|
||||
HTTPStatus, Response, abort, set_max_request_size, with_pool,
|
||||
with_transaction)
|
||||
|
||||
@@ -7,7 +7,7 @@ import urllib.parse
|
||||
import ldap3
|
||||
from ldap3.core.exceptions import LDAPException
|
||||
|
||||
from trytond.config import config, parse_uri
|
||||
import trytond.config as config
|
||||
from trytond.exceptions import LoginException
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model.exceptions import AccessError
|
||||
@@ -24,7 +24,7 @@ if 'ldap' not in urllib.parse.uses_query:
|
||||
|
||||
def parse_ldap_url(uri):
|
||||
unquote = urllib.parse.unquote
|
||||
uri = parse_uri(uri)
|
||||
uri = config.parse_uri(uri)
|
||||
dn = unquote(uri.path)[1:]
|
||||
attributes, scope, filter_, extensions = (
|
||||
uri.query.split('?') + [''] * 4)[:4]
|
||||
|
||||
@@ -7,7 +7,7 @@ from unittest.mock import ANY, MagicMock, Mock, patch
|
||||
|
||||
import ldap3
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.modules.ldap_authentication.res import ldap_server, parse_ldap_url
|
||||
from trytond.pool import Pool
|
||||
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
|
||||
|
||||
@@ -24,7 +24,7 @@ from genshi.template import TextTemplate
|
||||
from sql import Literal
|
||||
from sql.aggregate import Count
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import (
|
||||
EvalEnvironment, Index, ModelSQL, ModelView, Unique, Workflow, dualmethod,
|
||||
@@ -43,9 +43,6 @@ from trytond.wsgi import Base64Converter
|
||||
from .exceptions import ConditionError, DomainError, TemplateError
|
||||
from .mixin import MarketingAutomationMixin
|
||||
|
||||
USE_SSL = bool(config.get('ssl', 'certificate'))
|
||||
URL_BASE = config.get('marketing', 'automation_base', default=http_host())
|
||||
URL_OPEN = urljoin(URL_BASE, '/m/empty.gif')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -646,6 +643,9 @@ class Activity(
|
||||
WebShortener = pool.get('web.shortened_url')
|
||||
Email = pool.get('ir.email')
|
||||
record = record_activity.record
|
||||
url_base = config.get(
|
||||
'marketing', 'automation_base', default=http_host())
|
||||
url_open = urljoin(url_base, '/m/empty.gif')
|
||||
|
||||
with Transaction().set_context(language=record.language):
|
||||
record = record.__class__(record.id)
|
||||
@@ -655,7 +655,7 @@ class Activity(
|
||||
|
||||
def unsubscribe(redirect):
|
||||
parts = urlsplit(urljoin(
|
||||
URL_BASE, quote('/m/%(database)s/unsubscribe' % {
|
||||
url_base, quote('/m/%(database)s/unsubscribe' % {
|
||||
'database': Base64Converter(None).to_url(
|
||||
Transaction().database.name),
|
||||
})))
|
||||
@@ -691,7 +691,7 @@ class Activity(
|
||||
elif kind is END and data == 'body':
|
||||
yield START, (QName('img'), Attrs([
|
||||
(QName('src'), short(
|
||||
URL_OPEN, 'on_email_opened')),
|
||||
url_open, 'on_email_opened')),
|
||||
(QName('height'), '1'),
|
||||
(QName('width'), '1'),
|
||||
])), pos
|
||||
|
||||
@@ -19,7 +19,7 @@ try:
|
||||
except ImportError:
|
||||
html2text = None
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.ir.session import token_hex
|
||||
from trytond.model import (
|
||||
@@ -38,9 +38,6 @@ from trytond.wizard import Button, StateTransition, StateView, Wizard
|
||||
|
||||
from .exceptions import EMailValidationError, TemplateError
|
||||
|
||||
URL_BASE = config.get('marketing', 'email_base', default=http_host())
|
||||
URL_OPEN = urljoin(URL_BASE, '/m/empty.gif')
|
||||
|
||||
|
||||
def _add_params(url, **params):
|
||||
parts = urlsplit(url)
|
||||
@@ -434,6 +431,9 @@ class Message(Workflow, ModelSQL, ModelView):
|
||||
spy_pixel = config.getboolean(
|
||||
'marketing', 'email_spy_pixel', default=False)
|
||||
|
||||
url_base = config.get('marketing', 'email_base', default=http_host())
|
||||
url_open = urljoin(url_base, '/m/empty.gif')
|
||||
|
||||
@lru_cache(None)
|
||||
def short(url, record):
|
||||
url = WebShortener(
|
||||
@@ -456,7 +456,7 @@ class Message(Workflow, ModelSQL, ModelView):
|
||||
elif kind is END and data == 'body' and spy_pixel:
|
||||
yield START, (QName('img'), Attrs([
|
||||
(QName('src'), short(
|
||||
URL_OPEN, str(message))),
|
||||
url_open, str(message))),
|
||||
(QName('height'), '1'),
|
||||
(QName('width'), '1'),
|
||||
])), pos
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
from unittest.mock import ANY, Mock, patch
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.modules.marketing_email import marketing as marketing_module
|
||||
from trytond.pool import Pool
|
||||
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
|
||||
@@ -26,21 +26,19 @@ class MarketingEmailTestCase(ModuleTestCase):
|
||||
'marketing', 'email_subscribe_url', default='')
|
||||
config.set('marketing', 'email_subscribe_url', SUBSCRIBE_URL)
|
||||
self.addCleanup(
|
||||
lambda: config.set(
|
||||
'marketing', 'email_subscribe_url', subscribe_url))
|
||||
config.set, 'marketing', 'email_subscribe_url', subscribe_url)
|
||||
unsubscribe_url = config.get(
|
||||
'marketing', 'email_unsubscribe_url', default='')
|
||||
config.set('marketing', 'email_unsubscribe_url', UNSUBSCRIBE_URL)
|
||||
self.addCleanup(
|
||||
lambda: config.set(
|
||||
'marketing', 'email_unsubscribe_url', unsubscribe_url))
|
||||
config.set, 'marketing', 'email_unsubscribe_url', unsubscribe_url)
|
||||
spy_pixel = config.get('marketing', 'email_spy_pixel', default='')
|
||||
config.set('marketing', 'email_spy_pixel', 'true')
|
||||
self.addCleanup(
|
||||
lambda: config.set('marketing', 'email_spy_pixel', spy_pixel))
|
||||
config.set, 'marketing', 'email_spy_pixel', spy_pixel)
|
||||
from_ = config.get('email', 'from', default='')
|
||||
config.set('email', 'from', FROM)
|
||||
self.addCleanup(lambda: config.set('email', 'from', from_))
|
||||
self.addCleanup(config.set, 'email', 'from', from_)
|
||||
|
||||
@with_transaction()
|
||||
def test_subscribe(self):
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
|
||||
from sql import Table
|
||||
|
||||
from trytond import backend
|
||||
from trytond.config import config
|
||||
from trytond import backend, config
|
||||
from trytond.model import fields
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.pyson import Eval
|
||||
|
||||
@@ -5,7 +5,7 @@ from email.utils import getaddresses
|
||||
|
||||
from genshi.template import TextTemplate
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import ModelSQL, ModelView, fields
|
||||
from trytond.pool import Pool
|
||||
|
||||
@@ -5,7 +5,7 @@ import sys
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
|
||||
try:
|
||||
from trytond.modules.company.tests import CompanyTestMixin
|
||||
|
||||
@@ -8,14 +8,13 @@ from sql import As, Column, Literal, Null, Union, With
|
||||
from sql.aggregate import Min
|
||||
from sql.conditionals import Coalesce
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.model import Index, ModelSQL, ModelView, convert_from, fields
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.pyson import Eval, If
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
dumps = partial(json.dumps, separators=(',', ':'), sort_keys=True)
|
||||
default_depth = config.getint('party_relationship', 'depth', default=7)
|
||||
|
||||
|
||||
class RelationType(ModelSQL, ModelView):
|
||||
@@ -286,7 +285,9 @@ class Party(metaclass=PoolMeta):
|
||||
if party is None:
|
||||
party = context.get('related_party')
|
||||
if depth is None:
|
||||
depth = context.get('depth', default_depth)
|
||||
depth = context.get(
|
||||
'depth',
|
||||
config.getint('party_relationship', 'depth', default=7))
|
||||
|
||||
if not party:
|
||||
return query
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
from trytond.config import config
|
||||
|
||||
import trytond.config as config
|
||||
from trytond.model import fields
|
||||
from trytond.pool import PoolMeta
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
from decimal import Decimal
|
||||
from math import ceil, floor, log10
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import (
|
||||
Check, DeactivableMixin, DigitsMixin, ModelSQL, ModelView, SymbolMixin,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import datetime as dt
|
||||
from decimal import Decimal
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.modules.product import round_price
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ from urllib.parse import quote, urlencode, urljoin
|
||||
import PIL
|
||||
import PIL.Image
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import (
|
||||
MatchMixin, ModelSQL, ModelView, Unique, fields, sequence_ordered)
|
||||
@@ -27,8 +27,6 @@ else:
|
||||
file_id = None
|
||||
store_prefix = None
|
||||
SIZE_MAX = config.getint('product', 'image_size_max', default=2048)
|
||||
URL_BASE = config.get('product', 'image_base', default='')
|
||||
URL_EXTERNAL_BASE = config.get('product', 'image_base', default=http_host())
|
||||
|
||||
|
||||
class ImageURLMixin:
|
||||
@@ -68,8 +66,12 @@ class ImageURLMixin:
|
||||
return url
|
||||
|
||||
def get_image_url(self, _external=False, **args):
|
||||
url_base = config.get(
|
||||
'product', 'image_base', default='')
|
||||
url_external_base = config.get(
|
||||
'product', 'image_base', default=http_host())
|
||||
return self._image_url(
|
||||
URL_EXTERNAL_BASE if _external else URL_BASE, **args)
|
||||
url_external_base if _external else url_base, **args)
|
||||
|
||||
@property
|
||||
def images_used(self):
|
||||
|
||||
@@ -2,13 +2,11 @@
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
from urllib.parse import unquote
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.protocols.wrappers import (
|
||||
HTTPStatus, Response, abort, with_pool, with_transaction)
|
||||
from trytond.wsgi import app
|
||||
|
||||
TIMEOUT = config.getint('product', 'image_timeout', default=365 * 24 * 60 * 60)
|
||||
|
||||
|
||||
@app.route(
|
||||
'/product/image/<code>/<base64:database_name>',
|
||||
@@ -92,6 +90,7 @@ def _image(request, pool, record):
|
||||
|
||||
response = Response(image.get((width, height)), mimetype='image/jpeg')
|
||||
response.headers['Cache-Control'] = (
|
||||
'max-age=%s, public' % TIMEOUT)
|
||||
'max-age=%s, public' % config.getint(
|
||||
'product', 'image_timeout', default=365 * 24 * 60 * 60))
|
||||
response.add_etag()
|
||||
return response
|
||||
|
||||
@@ -3,15 +3,12 @@
|
||||
|
||||
import datetime as dt
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.model import ModelView, fields
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.pyson import Date, Eval, If, PYSONDecoder, PYSONEncoder
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
_cache_days = config.getint(
|
||||
'product_price_list_dates', 'cache_days', default=2)
|
||||
|
||||
|
||||
class PriceList(metaclass=PoolMeta):
|
||||
__name__ = 'product.price_list'
|
||||
@@ -63,7 +60,8 @@ class PriceListCache(metaclass=PoolMeta):
|
||||
for pattern in super().patterns(price_list, product):
|
||||
if pattern is None:
|
||||
pattern = {}
|
||||
for days in range(_cache_days):
|
||||
for days in range(config.getint(
|
||||
'product_price_list_dates', 'cache_days', default=2)):
|
||||
pattern['date'] = today + dt.timedelta(days=days)
|
||||
yield pattern
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ from sql import Null
|
||||
from sql.functions import CharLength
|
||||
from sql.operators import Equal
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import Exclude, ModelSQL, ModelView, Workflow, fields
|
||||
from trytond.modules.company.model import CompanyValueMixin
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
import mimetypes
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import ModelView, Workflow, fields
|
||||
from trytond.model.exceptions import AccessError
|
||||
|
||||
@@ -5,7 +5,7 @@ from urllib.parse import urljoin
|
||||
from zeep import Client
|
||||
from zeep.transports import Transport
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
|
||||
SERVER_URLS = {
|
||||
'testing': 'https://public-ws-stage.dpd.com/services/',
|
||||
@@ -14,17 +14,17 @@ SERVER_URLS = {
|
||||
|
||||
LOGIN_SERVICE = 'LoginService/V2_0/?wsdl'
|
||||
SHIPMENT_SERVICE = 'ShipmentService/V3_2/?wsdl'
|
||||
TIMEOUT = config.get(
|
||||
'stock_package_shipping_dpd', 'requests_timeout', default=300)
|
||||
|
||||
|
||||
def get_client(server, service):
|
||||
api_base_url = config.get('stock_package_shipping_dpd',
|
||||
server, default=SERVER_URLS[server])
|
||||
url = urljoin(api_base_url, service)
|
||||
timeout = config.get(
|
||||
'stock_package_shipping_dpd', 'requests_timeout', default=300)
|
||||
# Disable the cache for testing because zeep's bug
|
||||
# https://github.com/mvantellingen/python-zeep/issues/48
|
||||
# which makes testing environments fail
|
||||
transport = (Transport(cache=None, operation_timeout=TIMEOUT)
|
||||
transport = (Transport(cache=None, operation_timeout=timeout)
|
||||
if url.startswith(SERVER_URLS['testing']) else None)
|
||||
return Client(url, transport=transport)
|
||||
|
||||
@@ -5,14 +5,12 @@ import hashlib
|
||||
from zeep import Client
|
||||
from zeep.transports import Transport
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
|
||||
URLS = {
|
||||
'testing': 'https://api.test.mygls.%(country)s/%(service)s.svc?singleWsdl',
|
||||
'production': 'https://api.mygls.%(country)s/%(service)s.svc?singleWsdl',
|
||||
}
|
||||
TIMEOUT = config.get(
|
||||
'stock_package_shipping_mygls', 'requests_timeout', default=300)
|
||||
|
||||
|
||||
def get_client(credential, service):
|
||||
@@ -20,7 +18,9 @@ def get_client(credential, service):
|
||||
'country': credential.country,
|
||||
'service': service,
|
||||
}
|
||||
return Client(url, transport=Transport(operation_timeout=TIMEOUT))
|
||||
timeout = config.get(
|
||||
'stock_package_shipping_mygls', 'requests_timeout', default=300)
|
||||
return Client(url, transport=Transport(operation_timeout=timeout))
|
||||
|
||||
|
||||
def get_request(credential, name, **kwargs):
|
||||
|
||||
@@ -5,8 +5,8 @@ from functools import wraps
|
||||
|
||||
import requests
|
||||
|
||||
import trytond.config as config
|
||||
from trytond.cache import Cache
|
||||
from trytond.config import config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import (
|
||||
MatchMixin, ModelSQL, ModelView, fields, sequence_ordered)
|
||||
@@ -17,8 +17,6 @@ from trytond.pyson import Eval, If
|
||||
from .exceptions import SendcloudCredentialWarning, SendcloudError
|
||||
|
||||
SENDCLOUD_API_URL = 'https://panel.sendcloud.sc/api/v2/'
|
||||
TIMEOUT = config.getfloat(
|
||||
'stock_package_shipping_sendcloud', 'requests_timeout', default=300)
|
||||
HEADERS = {
|
||||
'Sendcloud-Partner-Id': '03c1facb-63da-4bb1-889c-192fc91ec4e6',
|
||||
}
|
||||
@@ -88,9 +86,12 @@ class CredentialSendcloud(sequence_ordered(), ModelSQL, ModelView, MatchMixin):
|
||||
addresses = self._addresses_sender_cache.get(self.id)
|
||||
if addresses is not None:
|
||||
return addresses
|
||||
timeout = config.getfloat(
|
||||
'stock_package_shipping_sendcloud', 'requests_timeout',
|
||||
default=300)
|
||||
response = requests.get(
|
||||
SENDCLOUD_API_URL + 'user/addresses/sender',
|
||||
auth=self.auth, timeout=TIMEOUT, headers=HEADERS)
|
||||
auth=self.auth, timeout=timeout, headers=HEADERS)
|
||||
response.raise_for_status()
|
||||
addresses = response.json()['sender_addresses']
|
||||
self._addresses_sender_cache.set(self.id, addresses)
|
||||
@@ -122,9 +123,12 @@ class CredentialSendcloud(sequence_ordered(), ModelSQL, ModelView, MatchMixin):
|
||||
params['service_point'] = service_point
|
||||
if is_return:
|
||||
params['is_return'] = is_return
|
||||
timeout = config.getfloat(
|
||||
'stock_package_shipping_sendcloud', 'requests_timeout',
|
||||
default=300)
|
||||
response = requests.get(
|
||||
SENDCLOUD_API_URL + 'shipping_methods', params=params,
|
||||
auth=self.auth, timeout=TIMEOUT, headers=HEADERS)
|
||||
auth=self.auth, timeout=timeout, headers=HEADERS)
|
||||
response.raise_for_status()
|
||||
methods = response.json()['shipping_methods']
|
||||
self._shiping_methods_cache.set(key, methods)
|
||||
@@ -159,17 +163,23 @@ class CredentialSendcloud(sequence_ordered(), ModelSQL, ModelView, MatchMixin):
|
||||
|
||||
@sendcloud_api
|
||||
def get_parcel(self, id):
|
||||
timeout = config.getfloat(
|
||||
'stock_package_shipping_sendcloud', 'requests_timeout',
|
||||
default=300)
|
||||
response = requests.get(
|
||||
SENDCLOUD_API_URL + 'parcels/%s' % id,
|
||||
auth=self.auth, timeout=TIMEOUT, headers=HEADERS)
|
||||
auth=self.auth, timeout=timeout, headers=HEADERS)
|
||||
response.raise_for_status()
|
||||
return response.json()['parcel']
|
||||
|
||||
@sendcloud_api
|
||||
def create_parcels(self, parcels):
|
||||
timeout = config.getfloat(
|
||||
'stock_package_shipping_sendcloud', 'requests_timeout',
|
||||
default=300)
|
||||
response = requests.post(
|
||||
SENDCLOUD_API_URL + 'parcels', json={'parcels': parcels},
|
||||
auth=self.auth, timeout=TIMEOUT, headers=HEADERS)
|
||||
auth=self.auth, timeout=timeout, headers=HEADERS)
|
||||
if response.status_code == 400:
|
||||
msg = response.json()['error']['message']
|
||||
raise requests.HTTPError(msg, response=response)
|
||||
@@ -178,8 +188,11 @@ class CredentialSendcloud(sequence_ordered(), ModelSQL, ModelView, MatchMixin):
|
||||
|
||||
@sendcloud_api
|
||||
def get_label(self, url):
|
||||
timeout = config.getfloat(
|
||||
'stock_package_shipping_sendcloud', 'requests_timeout',
|
||||
default=300)
|
||||
response = requests.get(
|
||||
url, auth=self.auth, timeout=TIMEOUT, headers=HEADERS)
|
||||
url, auth=self.auth, timeout=timeout, headers=HEADERS)
|
||||
response.raise_for_status()
|
||||
return response.content
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ from math import ceil
|
||||
|
||||
import requests
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import fields
|
||||
from trytond.model.exceptions import AccessError
|
||||
@@ -23,8 +23,6 @@ from trytond.wizard import StateAction, StateTransition, Wizard
|
||||
from .exceptions import UPSError
|
||||
|
||||
TRACKING_URL = 'https://www.ups.com/track'
|
||||
TIMEOUT = config.getfloat(
|
||||
'stock_package_shipping_ups', 'requests_timeout', default=300)
|
||||
|
||||
|
||||
class PackageType(metaclass=PoolMeta):
|
||||
@@ -166,12 +164,14 @@ class CreateShippingUPS(Wizard):
|
||||
}
|
||||
nb_tries, response = 0, None
|
||||
error_message = ''
|
||||
timeout = config.getfloat(
|
||||
'stock_package_shipping_ups', 'requests_timeout', default=300)
|
||||
try:
|
||||
while nb_tries < 5 and response is None:
|
||||
try:
|
||||
response = requests.post(
|
||||
api_url, json=shipment_request, headers=headers,
|
||||
timeout=TIMEOUT)
|
||||
timeout=timeout)
|
||||
except ssl.SSLError as e:
|
||||
error_message = e.reason
|
||||
nb_tries += 1
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
from decimal import Decimal
|
||||
|
||||
import trytond.config as config
|
||||
from trytond.cache import Cache
|
||||
from trytond.config import config
|
||||
from trytond.model import Index, ModelSQL, ModelView, Unique, fields
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
@@ -10,7 +10,7 @@ import time
|
||||
from functools import wraps
|
||||
from string import Template
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.model import fields
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.transaction import Transaction
|
||||
@@ -82,6 +82,8 @@ class Shop(metaclass=PoolMeta):
|
||||
shops = cls.search([])
|
||||
|
||||
directory = _get_directory()
|
||||
duration = config.getint(
|
||||
'web_shop', 'product_data_feed_cache', default=60 * 60 * 24)
|
||||
for shop in shops:
|
||||
for name in fnmatch.filter(
|
||||
os.listdir(directory),
|
||||
@@ -92,13 +94,16 @@ class Shop(metaclass=PoolMeta):
|
||||
else:
|
||||
format, language = name, None
|
||||
shop.product_data_feed_csv(
|
||||
format, language=language, duration=_duration / 2)
|
||||
format, language=language, duration=duration / 2)
|
||||
|
||||
def product_data_feed_csv(self, format, language=None, duration=_duration):
|
||||
def product_data_feed_csv(self, format, language=None, duration=None):
|
||||
pool = Pool()
|
||||
Lang = pool.get('ir.lang')
|
||||
transaction = Transaction()
|
||||
directory = _get_directory()
|
||||
if duration is None:
|
||||
duration = config.getint(
|
||||
'web_shop', 'product_data_feed_cache', default=60 * 60 * 24)
|
||||
if language:
|
||||
filename = f'{self.name}-{self.id}-{format}-{language}.csv'
|
||||
else:
|
||||
|
||||
@@ -10,8 +10,8 @@ import pyactiveresource
|
||||
import shopify
|
||||
from shopify.api_version import ApiVersion
|
||||
|
||||
import trytond.config as config
|
||||
from trytond.cache import Cache
|
||||
from trytond.config import config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import (
|
||||
MatchMixin, ModelSQL, ModelView, Unique, fields, sequence_ordered)
|
||||
|
||||
@@ -7,7 +7,7 @@ from urllib.parse import quote, urljoin
|
||||
|
||||
from sql.aggregate import Count
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.model import ModelSQL, ModelView, fields
|
||||
from trytond.pool import Pool
|
||||
from trytond.tools import grouped_slice, reduce_ids
|
||||
@@ -16,7 +16,6 @@ from trytond.url import http_host
|
||||
from trytond.wsgi import Base64Converter
|
||||
|
||||
ALPHABET = string.digits + string.ascii_lowercase
|
||||
URL_BASE = config.get('web', 'shortener_base', default=http_host())
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -38,10 +37,11 @@ class ShortenedURL(ModelSQL, ModelView):
|
||||
'database': Base64Converter(None).to_url(
|
||||
Transaction().database.name),
|
||||
}
|
||||
url_base = config.get('web', 'shortener_base', default=http_host())
|
||||
for shortened in shortened_urls:
|
||||
url_parts['short_id'] = cls._shorten(shortened.id)
|
||||
urls[shortened.id] = urljoin(
|
||||
URL_BASE, quote('/s/%(database)s$%(short_id)s' % url_parts))
|
||||
url_base, quote('/s/%(database)s$%(short_id)s' % url_parts))
|
||||
return urls
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.modules.party.tests import PartyCheckEraseMixin
|
||||
from trytond.modules.web_user import user as user_module
|
||||
from trytond.pool import Pool
|
||||
|
||||
@@ -20,7 +20,7 @@ from sql.conditionals import Coalesce
|
||||
from sql.functions import CurrentTimestamp
|
||||
from sql.operators import Equal
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.exceptions import RateLimitException
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import (
|
||||
|
||||
@@ -264,7 +264,7 @@ class TrytondConfig(Config):
|
||||
os.environ['TRYTOND_DATABASE_URI'] = database
|
||||
if not config_file:
|
||||
config_file = os.environ.get('TRYTOND_CONFIG')
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
config.update_etc(config_file)
|
||||
from trytond.pool import Pool
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# This file is part of trytond_gis. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
|
||||
from .const import WGS_84
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
import logging
|
||||
|
||||
import trytond.config as config
|
||||
from trytond.backend.postgresql.table import TableHandler as PGTableHandler
|
||||
from trytond.config import config
|
||||
from trytond.transaction import Transaction
|
||||
from trytond_gis.const import GIS_SQL_TYPE_RE, WGS_84
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
* Refactor of trytond.config to add cache
|
||||
* Handle URL host of the bus on login
|
||||
* Restrict sessions to the client's IP address
|
||||
* Use ``tryton.cfg`` to register in the Pool
|
||||
|
||||
+2
-2
@@ -19,7 +19,7 @@ if os.path.isdir(DIR):
|
||||
sys.path.insert(0, os.path.dirname(DIR))
|
||||
|
||||
import trytond.commandline as commandline
|
||||
from trytond.config import config, split_netloc
|
||||
import trytond.config as config
|
||||
|
||||
parser = commandline.get_parser_daemon()
|
||||
if argcomplete:
|
||||
@@ -47,7 +47,7 @@ with commandline.pidfile(options):
|
||||
threads.append(thread)
|
||||
for thread in threads:
|
||||
thread.join()
|
||||
hostname, port = split_netloc(config.get('web', 'listen'))
|
||||
hostname, port = config.split_netloc(config.get('web', 'listen'))
|
||||
certificate = config.get('ssl', 'certificate')
|
||||
try:
|
||||
if config.getboolean('ssl', 'certificate'):
|
||||
|
||||
@@ -16,7 +16,7 @@ if os.path.isdir(DIR):
|
||||
sys.path.insert(0, os.path.dirname(DIR))
|
||||
|
||||
import trytond.commandline as commandline
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
|
||||
parser = commandline.get_parser_admin()
|
||||
if argcomplete:
|
||||
|
||||
@@ -16,7 +16,7 @@ if os.path.isdir(DIR):
|
||||
sys.path.insert(0, os.path.dirname(DIR))
|
||||
|
||||
import trytond.commandline as commandline
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
|
||||
parser = commandline.get_parser_console()
|
||||
if argcomplete:
|
||||
|
||||
@@ -16,7 +16,7 @@ if os.path.isdir(DIR):
|
||||
sys.path.insert(0, os.path.dirname(DIR))
|
||||
|
||||
import trytond.commandline as commandline
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
|
||||
parser = commandline.get_parser_cron()
|
||||
if argcomplete:
|
||||
|
||||
@@ -20,7 +20,7 @@ if os.path.isdir(DIR):
|
||||
sys.path.insert(0, os.path.dirname(DIR))
|
||||
|
||||
import trytond.commandline as commandline
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
|
||||
parser = commandline.get_parser_stat()
|
||||
if argcomplete:
|
||||
|
||||
@@ -16,7 +16,7 @@ if os.path.isdir(DIR):
|
||||
sys.path.insert(0, os.path.dirname(DIR))
|
||||
|
||||
import trytond.commandline as commandline
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
|
||||
parser = commandline.get_parser_worker()
|
||||
if argcomplete:
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
.. _ref-config:
|
||||
.. module:: trytond.config
|
||||
|
||||
======
|
||||
Config
|
||||
======
|
||||
|
||||
The config gives access to the configuration.
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:backlinks: entry
|
||||
:depth: 1
|
||||
|
||||
.. function:: get_hostname(netloc)
|
||||
|
||||
Returns the hostname from the network location/authority of :abbr:`URI
|
||||
(Uniform Resource Identifier)`.
|
||||
|
||||
.. function:: get_port(netloc)
|
||||
|
||||
Returns the port from the network location/authority of :abbr:`URI (Uniform
|
||||
Resource Identifier)`.
|
||||
|
||||
.. function:: split_netloc(netloc)
|
||||
|
||||
Returns the couple hostname and port from the network location/authority of
|
||||
:abbr:`URI (Uniform Resource Identifier)`.
|
||||
|
||||
.. function:: parse_listen(value)
|
||||
|
||||
Yields couples of hostname and port from the comma separated list of network
|
||||
location/authority of :abbr:`URI (Uniform Resource Identifier)`.
|
||||
|
||||
.. function:: parse_uri(uri)
|
||||
|
||||
Parses a :abbr:`URI (Uniform Resource Identifier)`, returning a namedtuple.
|
||||
|
||||
.. function:: update_etc([configfile])
|
||||
|
||||
Tries to update the configuration with the file or list of files and returns
|
||||
the filenames which were successfully parsed.
|
||||
|
||||
.. function:: has_section(section)
|
||||
|
||||
Indicates whether the named section is present in the configuration.
|
||||
|
||||
.. function:: add_section(section)
|
||||
|
||||
Adds the named section.
|
||||
|
||||
.. function:: remove_section(section)
|
||||
|
||||
Removes the named section.
|
||||
|
||||
.. function:: set(section, option[, value])
|
||||
|
||||
Set the given option to the specified value.
|
||||
|
||||
.. function:: get(section, option[, default])
|
||||
|
||||
Get an option value for the named section. If the key is not found the
|
||||
default value is provided.
|
||||
|
||||
.. function:: getint(section, option[, default])
|
||||
|
||||
A convenience method which coerces the option in the specified section to an
|
||||
:py:class:`int`.
|
||||
See :func:`get`.
|
||||
|
||||
.. function:: getfloat(section, option[, default])
|
||||
|
||||
A convenience method which coerces the option in the specified section to a
|
||||
:py:class:`float`.
|
||||
See :func:`get`.
|
||||
|
||||
.. function:: getboolean(section, option[, default])
|
||||
|
||||
A convenience method which coerces the option in the specified section to a
|
||||
:py:class:`bool`.
|
||||
See :func:`get`.
|
||||
@@ -9,6 +9,7 @@ Reference of the ``trytond`` API:
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
config
|
||||
models
|
||||
fields
|
||||
wizard
|
||||
|
||||
@@ -8,8 +8,7 @@ from getpass import getpass
|
||||
|
||||
from sql import Literal, Table
|
||||
|
||||
from trytond import __series__, backend
|
||||
from trytond.config import config
|
||||
from trytond import __series__, backend, config
|
||||
from trytond.pool import Pool
|
||||
from trytond.sendmail import send_test_email
|
||||
from trytond.tools import file_open, find_path
|
||||
|
||||
@@ -8,7 +8,7 @@ try:
|
||||
except ImportError:
|
||||
from importlib.metadata import entry_points
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
|
||||
__all__ = [
|
||||
'name', 'Database', 'TableHandler',
|
||||
|
||||
@@ -36,9 +36,8 @@ from sql.conditionals import Coalesce
|
||||
from sql.functions import Function
|
||||
from sql.operators import BinaryOperator, Concat
|
||||
|
||||
from trytond import __series__
|
||||
from trytond import __series__, config
|
||||
from trytond.backend.database import DatabaseInterface, SQLType
|
||||
from trytond.config import config, parse_uri
|
||||
from trytond.sql.operators import RangeOperator
|
||||
from trytond.tools import grouped_slice, reduce_ids
|
||||
from trytond.tools.gevent import is_gevent_monkey_patched
|
||||
@@ -53,9 +52,6 @@ __all__ = [
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
os.environ['PGTZ'] = os.environ.get('TZ', '')
|
||||
_timeout = config.getint('database', 'timeout')
|
||||
_minconn = config.getint('database', 'minconn', default=1)
|
||||
_maxconn = config.getint('database', 'maxconn', default=64)
|
||||
_default_name = config.get('database', 'default_name', default='template1')
|
||||
|
||||
|
||||
@@ -224,8 +220,9 @@ class Database(DatabaseInterface):
|
||||
with cls._lock:
|
||||
now = datetime.now()
|
||||
databases = cls._databases[os.getpid()]
|
||||
timeout = config.getint('database', 'timeout')
|
||||
for database in list(databases.values()):
|
||||
if ((now - database._last_use).total_seconds() > _timeout
|
||||
if ((now - database._last_use).total_seconds() > timeout
|
||||
and database.name != name
|
||||
and not database._connpool._used):
|
||||
database.close()
|
||||
@@ -233,9 +230,11 @@ class Database(DatabaseInterface):
|
||||
inst = databases[name]
|
||||
else:
|
||||
inst = DatabaseInterface.__new__(cls, name=name)
|
||||
minconn = config.getint('database', 'minconn', default=1)
|
||||
maxconn = config.getint('database', 'maxconn', default=64)
|
||||
try:
|
||||
inst._connpool = ThreadedConnectionPool(
|
||||
_minconn, _maxconn, **cls._connection_params(name),
|
||||
minconn, maxconn, **cls._connection_params(name),
|
||||
cursor_factory=LoggingCursor)
|
||||
except Exception:
|
||||
logger.error(
|
||||
@@ -252,7 +251,7 @@ class Database(DatabaseInterface):
|
||||
|
||||
@classmethod
|
||||
def _connection_params(cls, name):
|
||||
uri = parse_uri(config.get('database', 'uri'))
|
||||
uri = config.parse_uri(config.get('database', 'uri'))
|
||||
if uri.path and uri.path != '/':
|
||||
warnings.warn("The path specified in the URI will be overridden")
|
||||
params = {
|
||||
@@ -267,7 +266,9 @@ class Database(DatabaseInterface):
|
||||
|
||||
def get_connection(
|
||||
self, autocommit=False, readonly=False, statement_timeout=None):
|
||||
retry = max(config.getint('database', 'retry'), _maxconn)
|
||||
retry = max(
|
||||
config.getint('database', 'retry'),
|
||||
config.getint('database', 'maxconn', default=64))
|
||||
for count in range(retry, -1, -1):
|
||||
try:
|
||||
conn = self._connpool.getconn()
|
||||
|
||||
@@ -24,9 +24,8 @@ from sql.functions import (
|
||||
Substring, Trim)
|
||||
from sql.operators import Equal
|
||||
|
||||
from trytond import __series__
|
||||
from trytond import __series__, config
|
||||
from trytond.backend.database import DatabaseInterface, SQLType
|
||||
from trytond.config import config, parse_uri
|
||||
from trytond.tools import safe_join
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
@@ -539,7 +538,7 @@ class Database(DatabaseInterface):
|
||||
|
||||
def _make_uri(self):
|
||||
uri = config.get('database', 'uri')
|
||||
base_uri = parse_uri(uri)
|
||||
base_uri = config.parse_uri(uri)
|
||||
if base_uri.path and base_uri.path != '/':
|
||||
warnings.warn("The path specified in the URI will be overridden")
|
||||
|
||||
|
||||
+11
-15
@@ -10,8 +10,8 @@ import threading
|
||||
import time
|
||||
import uuid
|
||||
|
||||
import trytond.config as config
|
||||
from trytond import backend
|
||||
from trytond.config import config
|
||||
from trytond.protocols.jsonrpc import JSONDecoder, JSONEncoder
|
||||
from trytond.protocols.wrappers import HTTPStatus, Response, abort, exceptions
|
||||
from trytond.tools import resolve
|
||||
@@ -20,14 +20,6 @@ from trytond.wsgi import app
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
_db_timeout = config.getint('database', 'timeout')
|
||||
_cache_timeout = config.getint('bus', 'cache_timeout')
|
||||
_select_timeout = config.getint('bus', 'select_timeout')
|
||||
_long_polling_timeout = config.getint('bus', 'long_polling_timeout')
|
||||
_allow_subscribe = config.getboolean('bus', 'allow_subscribe')
|
||||
_url_host = config.get('bus', 'url_host')
|
||||
_web_cache_timeout = config.getint('web', 'cache_timeout')
|
||||
|
||||
|
||||
class _MessageQueue:
|
||||
|
||||
@@ -84,7 +76,8 @@ class LongPollingBus:
|
||||
pid = os.getpid()
|
||||
with cls._queues_lock[pid]:
|
||||
start_listener = (pid, database) not in cls._queues
|
||||
cls._queues[pid, database]['timeout'] = time.time() + _db_timeout
|
||||
cls._queues[pid, database]['timeout'] = (
|
||||
time.time() + config.getint('database', 'timeout'))
|
||||
if start_listener:
|
||||
listener = threading.Thread(
|
||||
target=cls._listen, args=(database,), daemon=True)
|
||||
@@ -106,7 +99,8 @@ class LongPollingBus:
|
||||
'events'][channel]
|
||||
event_channel.append(event)
|
||||
|
||||
triggered = event.wait(_long_polling_timeout)
|
||||
triggered = event.wait(
|
||||
config.getint('bus', 'long_polling_timeout'))
|
||||
if not triggered:
|
||||
response = cls.create_response(None, None)
|
||||
else:
|
||||
@@ -153,12 +147,13 @@ class LongPollingBus:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute('LISTEN "%s"' % cls._channel)
|
||||
|
||||
cls._messages[database] = messages = _MessageQueue(_cache_timeout)
|
||||
cls._messages[database] = messages = _MessageQueue(
|
||||
config.getint('bus', 'cache_timeout'))
|
||||
|
||||
now = time.time()
|
||||
selector.register(conn, selectors.EVENT_READ)
|
||||
while cls._queues[pid, database]['timeout'] > now:
|
||||
selector.select(timeout=_select_timeout)
|
||||
selector.select(timeout=config.getint('bus', 'select_timeout'))
|
||||
conn.poll()
|
||||
while conn.notifies:
|
||||
notification = conn.notifies.pop()
|
||||
@@ -226,9 +221,10 @@ else:
|
||||
@app.route('/<string:database_name>/bus', methods=['POST'])
|
||||
@app.session_valid
|
||||
def subscribe(request, database_name):
|
||||
if not _allow_subscribe:
|
||||
if not config.getboolean('bus', 'allow_subscribe'):
|
||||
raise exceptions.NotImplemented
|
||||
if _url_host and _url_host != request.host_url:
|
||||
url_host = config.get('bus', 'url_host')
|
||||
if url_host and url_host != request.host_url:
|
||||
abort(HTTPStatus.UNAUTHORIZED)
|
||||
user = request.authorization.get('userid')
|
||||
channels = request.parsed_data.get('channels', [])
|
||||
|
||||
+11
-11
@@ -14,17 +14,13 @@ from sql import Conflict, Table
|
||||
from sql.aggregate import Max
|
||||
from sql.functions import CurrentTimestamp, Function
|
||||
|
||||
from trytond import backend
|
||||
from trytond.config import config
|
||||
from trytond import backend, config
|
||||
from trytond.pool import Pool
|
||||
from trytond.tools import grouped_slice, resolve
|
||||
from trytond.tools.multiprocessing import local
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
__all__ = ['BaseCache', 'Cache', 'LRUDict', 'LRUDictTransaction']
|
||||
_clean_timeout = config.getint('cache', 'clean_timeout')
|
||||
_select_timeout = config.getint('cache', 'select_timeout')
|
||||
_default_size_limit = config.getint('cache', 'default')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
REFRESH_POOL_MSG = "refresh pool"
|
||||
@@ -90,7 +86,7 @@ class BaseCache(object):
|
||||
f" in regards to context ({context}).")
|
||||
self._name = name
|
||||
self.size_limit = config.getint(
|
||||
'cache', name, default=_default_size_limit)
|
||||
'cache', name, default=config.getint('cache', 'default'))
|
||||
self.context = context
|
||||
self.context_ignored_keys = set()
|
||||
if context and context_ignored_keys:
|
||||
@@ -247,7 +243,8 @@ class MemoryCache(BaseCache):
|
||||
|
||||
database = transaction.database
|
||||
dbname = database.name
|
||||
if not _clean_timeout and database.has_channel():
|
||||
clean_timeout = config.getint('cache', 'clean_timeout')
|
||||
if not clean_timeout and database.has_channel():
|
||||
with cls._local.listener_lock:
|
||||
if dbname not in cls._local.listeners:
|
||||
listener = threading.Thread(
|
||||
@@ -256,7 +253,7 @@ class MemoryCache(BaseCache):
|
||||
listener.start()
|
||||
return
|
||||
last_clean = (dt.datetime.now() - cls._clean_last).total_seconds()
|
||||
if last_clean < _clean_timeout:
|
||||
if last_clean < clean_timeout:
|
||||
return
|
||||
connection = database.get_connection(readonly=True, autocommit=True)
|
||||
try:
|
||||
@@ -292,7 +289,8 @@ class MemoryCache(BaseCache):
|
||||
return
|
||||
database = transaction.database
|
||||
dbname = database.name
|
||||
if not _clean_timeout and transaction.database.has_channel():
|
||||
clean_timeout = config.getint('cache', 'clean_timeout')
|
||||
if not clean_timeout and transaction.database.has_channel():
|
||||
with transaction.connection.cursor() as cursor:
|
||||
# The count computed as
|
||||
# 8000 (max notify size) / 64 (max name data len)
|
||||
@@ -379,7 +377,8 @@ class MemoryCache(BaseCache):
|
||||
def refresh_pool(cls, transaction):
|
||||
database = transaction.database
|
||||
dbname = database.name
|
||||
if not _clean_timeout and database.has_channel():
|
||||
clean_timeout = config.getint('cache', 'clean_timeout')
|
||||
if not clean_timeout and database.has_channel():
|
||||
database = backend.Database(dbname)
|
||||
conn = database.get_connection()
|
||||
process_id = cls._local.portable_id
|
||||
@@ -415,7 +414,8 @@ class MemoryCache(BaseCache):
|
||||
|
||||
selector.register(conn, selectors.EVENT_READ)
|
||||
while cls._local.listeners.get(dbname) == current_thread:
|
||||
selector.select(timeout=_select_timeout)
|
||||
selector.select(
|
||||
timeout=config.getint('cache', 'select_timeout'))
|
||||
conn.poll()
|
||||
while conn.notifies:
|
||||
notification = conn.notifies.pop()
|
||||
|
||||
@@ -16,7 +16,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def database_completer(parsed_args, **kwargs):
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.transaction import Transaction
|
||||
config.update_etc(parsed_args.configfile)
|
||||
with Transaction().start(
|
||||
|
||||
+63
-36
@@ -3,11 +3,17 @@
|
||||
import configparser
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import urllib.parse
|
||||
import warnings
|
||||
from functools import cache
|
||||
from getpass import getuser
|
||||
|
||||
__all__ = ['config', 'get_hostname', 'get_port', 'split_netloc',
|
||||
'parse_listen', 'parse_uri']
|
||||
__all__ = [
|
||||
'get_hostname', 'get_port', 'split_netloc',
|
||||
'parse_listen', 'parse_uri',
|
||||
'update_etc', 'has_section', 'add_section', 'remove_section',
|
||||
'set', 'get', 'getint', 'getfloat', 'getboolean']
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Needed so urlunsplit to always set netloc
|
||||
@@ -135,40 +141,61 @@ class TrytonConfigParser(configparser.ConfigParser):
|
||||
','.join(set(configfile) - set(read_files)))
|
||||
return configfile
|
||||
|
||||
def get(self, section, option, *args, **kwargs):
|
||||
default = kwargs.pop('default', None)
|
||||
try:
|
||||
return configparser.RawConfigParser.get(self, section, option,
|
||||
*args, **kwargs)
|
||||
except (configparser.NoOptionError, configparser.NoSectionError):
|
||||
return default
|
||||
|
||||
def getint(self, section, option, *args, **kwargs):
|
||||
default = kwargs.pop('default', None)
|
||||
try:
|
||||
return configparser.RawConfigParser.getint(self, section, option,
|
||||
*args, **kwargs)
|
||||
except (configparser.NoOptionError, configparser.NoSectionError,
|
||||
TypeError):
|
||||
return default
|
||||
|
||||
def getfloat(self, section, option, *args, **kwargs):
|
||||
default = kwargs.pop('default', None)
|
||||
try:
|
||||
return configparser.RawConfigParser.getfloat(self, section, option,
|
||||
*args, **kwargs)
|
||||
except (configparser.NoOptionError, configparser.NoSectionError,
|
||||
TypeError):
|
||||
return default
|
||||
|
||||
def getboolean(self, section, option, *args, **kwargs):
|
||||
default = kwargs.pop('default', None)
|
||||
try:
|
||||
return configparser.RawConfigParser.getboolean(
|
||||
self, section, option, *args, **kwargs)
|
||||
except (configparser.NoOptionError, configparser.NoSectionError,
|
||||
AttributeError):
|
||||
return default
|
||||
_config = TrytonConfigParser()
|
||||
|
||||
|
||||
config = TrytonConfigParser()
|
||||
def update_etc(configfile=os.environ.get('TRYTOND_CONFIG')):
|
||||
configfile = _config.update_etc(configfile=configfile)
|
||||
_cache_clear()
|
||||
return configfile
|
||||
|
||||
|
||||
has_section = _config.has_section
|
||||
add_section = _config.add_section
|
||||
remove_section = _config.remove_section
|
||||
|
||||
|
||||
def set(section, option, value=None):
|
||||
_config.set(section, option, value=value)
|
||||
_cache_clear()
|
||||
|
||||
|
||||
@cache
|
||||
def get(section, option, default=None):
|
||||
return configparser.RawConfigParser.get(
|
||||
_config, section, option, fallback=default)
|
||||
|
||||
|
||||
def _cache_clear():
|
||||
get.cache_clear()
|
||||
getint.cache_clear()
|
||||
getfloat.cache_clear()
|
||||
getboolean.cache_clear()
|
||||
|
||||
|
||||
@cache
|
||||
def getint(section, option, default=None):
|
||||
return configparser.RawConfigParser.getint(
|
||||
_config, section, option, fallback=default)
|
||||
|
||||
|
||||
@cache
|
||||
def getfloat(section, option, default=None):
|
||||
return configparser.RawConfigParser.getfloat(
|
||||
_config, section, option, fallback=default)
|
||||
|
||||
|
||||
@cache
|
||||
def getboolean(section, option, default=None):
|
||||
return configparser.RawConfigParser.getboolean(
|
||||
_config, section, option, fallback=default)
|
||||
|
||||
|
||||
def __getattr__(name):
|
||||
if name == 'config':
|
||||
warnings.warn(
|
||||
"trytond.config.config is deprecated, "
|
||||
"use trytond.config", DeprecationWarning, stacklevel=2)
|
||||
return sys.modules[__name__]
|
||||
raise AttributeError(f"module {__name__} has no attribute {name}")
|
||||
|
||||
@@ -2,13 +2,17 @@
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
import hashlib
|
||||
import os
|
||||
from functools import cache
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.tools import resolve
|
||||
|
||||
__all__ = ['filestore']
|
||||
|
||||
PATH = os.path.normpath(config.get('database', 'path'))
|
||||
|
||||
@cache
|
||||
def _normpath(path):
|
||||
return os.path.normpath(path)
|
||||
|
||||
|
||||
class FileStore(object):
|
||||
@@ -52,10 +56,15 @@ class FileStore(object):
|
||||
def setmany(self, data, prefix=''):
|
||||
return [self.set(d, prefix) for d in data]
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
return _normpath(config.get('database', 'path'))
|
||||
|
||||
def _filename(self, id, prefix):
|
||||
filename = os.path.join(PATH, prefix, id[0:2], id[2:4], id)
|
||||
path = self.path
|
||||
filename = os.path.join(path, prefix, id[0:2], id[2:4], id)
|
||||
filename = os.path.normpath(filename)
|
||||
if not filename.startswith(PATH):
|
||||
if not filename.startswith(path):
|
||||
raise ValueError('Bad prefix')
|
||||
return filename
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
from trytond.config import config
|
||||
|
||||
import trytond.config as config
|
||||
from trytond.i18n import lazy_gettext
|
||||
from trytond.model import ModelSQL, ModelView, fields
|
||||
from trytond.pool import Pool
|
||||
|
||||
@@ -13,7 +13,7 @@ try:
|
||||
except ImportError:
|
||||
PIL = None
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import ModelSQL, Unique, fields
|
||||
from trytond.model.exceptions import ValidationError
|
||||
@@ -29,7 +29,6 @@ if config.getboolean('database', 'avatar_filestore', default=False):
|
||||
else:
|
||||
file_id = None
|
||||
store_prefix = None
|
||||
URL_BASE = config.get('web', 'avatar_base', default='')
|
||||
FONT = os.path.join(os.path.dirname(__file__), 'fonts', 'karla.ttf')
|
||||
|
||||
|
||||
@@ -89,8 +88,9 @@ class Avatar(ImageMixin, ResourceMixin, ModelSQL):
|
||||
@property
|
||||
def url(self):
|
||||
if self.image_id or self.image:
|
||||
url_base = config.get('web', 'avatar_base', default='')
|
||||
return urljoin(
|
||||
URL_BASE, quote('/avatar/%(database)s/%(uuid)s' % {
|
||||
url_base, quote('/avatar/%(database)s/%(uuid)s' % {
|
||||
'database': Base64Converter(None).to_url(
|
||||
Transaction().database.name),
|
||||
'uuid': self.uuid,
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
|
||||
import trytond.config as config
|
||||
from trytond.cache import Cache
|
||||
from trytond.config import config
|
||||
from trytond.model import ModelSingleton, ModelSQL, fields
|
||||
|
||||
|
||||
|
||||
@@ -11,8 +11,7 @@ from dateutil.relativedelta import relativedelta
|
||||
from sql import Literal
|
||||
from sql.conditionals import Coalesce
|
||||
|
||||
from trytond import backend
|
||||
from trytond.config import config
|
||||
from trytond import backend, config
|
||||
from trytond.exceptions import UserError, UserWarning
|
||||
from trytond.model import (
|
||||
DeactivableMixin, Index, ModelSQL, ModelView, dualmethod, fields)
|
||||
@@ -24,7 +23,6 @@ from trytond.tools import timezone as tz
|
||||
from trytond.transaction import Transaction, TransactionError
|
||||
from trytond.worker import run_task
|
||||
|
||||
clean_days = config.getint('cron', 'clean_days', default=30)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -315,6 +313,7 @@ class Log(ModelSQL, ModelView):
|
||||
@classmethod
|
||||
def clean(cls, date=None):
|
||||
if date is None:
|
||||
clean_days = config.getint('cron', 'clean_days', default=30)
|
||||
date = (
|
||||
datetime.datetime.now() - datetime.timedelta(days=clean_days))
|
||||
logs = cls.search([('create_date', '<', date)])
|
||||
|
||||
@@ -12,7 +12,7 @@ except ImportError:
|
||||
html2text = None
|
||||
from genshi.template import TextTemplate
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import EvalEnvironment, ModelSQL, ModelView, fields
|
||||
from trytond.model.exceptions import AccessError, ValidationError
|
||||
|
||||
@@ -5,7 +5,7 @@ import functools
|
||||
import logging
|
||||
import warnings
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.exceptions import UserError, UserWarning
|
||||
from trytond.model import (
|
||||
Index, ModelSQL, ModelView, Workflow, dualmethod, fields)
|
||||
@@ -15,7 +15,6 @@ from trytond.tools import firstline
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
clean_days = config.getint('error', 'clean_days', default=90)
|
||||
|
||||
|
||||
def set_user(field):
|
||||
@@ -159,6 +158,7 @@ class Error(Workflow, ModelView, ModelSQL):
|
||||
@classmethod
|
||||
def clean(cls, date=None):
|
||||
if date is None:
|
||||
clean_days = config.getint('error', 'clean_days', default=90)
|
||||
date = (
|
||||
dt.datetime.now() - dt.timedelta(days=clean_days))
|
||||
errors = cls.search([('create_date', '<', date)])
|
||||
|
||||
@@ -12,8 +12,8 @@ from sql.aggregate import Max
|
||||
from sql.conditionals import Case
|
||||
from sql.operators import Equal
|
||||
|
||||
import trytond.config as config
|
||||
from trytond.cache import Cache
|
||||
from trytond.config import config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import (
|
||||
DeactivableMixin, EvalEnvironment, Exclude, Index, ModelSingleton,
|
||||
@@ -32,7 +32,6 @@ from trytond.wizard import Button, StateAction, StateView, Wizard
|
||||
from .resource import ResourceAccessMixin
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
_request_timeout = config.getint('request', 'timeout', default=0)
|
||||
|
||||
|
||||
class ConditionError(ValidationError):
|
||||
@@ -76,7 +75,8 @@ class Model(
|
||||
'list_history': RPC(),
|
||||
'get_notification': RPC(),
|
||||
'get_names': RPC(),
|
||||
'global_search': RPC(timeout=_request_timeout),
|
||||
'global_search': RPC(
|
||||
timeout=config.getint('request', 'timeout', default=0)),
|
||||
})
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -6,17 +6,13 @@ from sql import Literal, Null, With
|
||||
from sql.aggregate import Min
|
||||
from sql.functions import CurrentTimestamp, Extract
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.model import Index, ModelSQL, fields
|
||||
from trytond.pool import Pool
|
||||
from trytond.tools import grouped_slice
|
||||
from trytond.transaction import (
|
||||
Transaction, inactive_records, without_check_access)
|
||||
|
||||
has_worker = config.getboolean('queue', 'worker', default=False)
|
||||
clean_days = config.getint('queue', 'clean_days', default=30)
|
||||
batch_size = config.getint('queue', 'batch_size', default=20)
|
||||
|
||||
|
||||
class Queue(ModelSQL):
|
||||
__name__ = 'ir.queue'
|
||||
@@ -75,7 +71,7 @@ class Queue(ModelSQL):
|
||||
}])
|
||||
if database.has_channel():
|
||||
cursor.execute('NOTIFY "%s"', (cls.__name__,))
|
||||
if not has_worker:
|
||||
if not config.getboolean('queue', 'worker', default=False):
|
||||
transaction.tasks.append(record.id)
|
||||
return record.id
|
||||
|
||||
@@ -185,7 +181,8 @@ class Queue(ModelSQL):
|
||||
def clean(cls, date=None):
|
||||
if date is None:
|
||||
date = (
|
||||
datetime.datetime.now() - datetime.timedelta(days=clean_days))
|
||||
datetime.datetime.now() - datetime.timedelta(
|
||||
days=config.getint('queue', 'clean_days', default=30)))
|
||||
tasks = cls.search(['OR',
|
||||
('dequeued_at', '<', date),
|
||||
('finished_at', '<', date),
|
||||
@@ -215,6 +212,7 @@ class _Method(object):
|
||||
def __call__(self, instances, *args, **kwargs):
|
||||
transaction = Transaction()
|
||||
context = transaction.context.copy()
|
||||
has_worker = config.getboolean('queue', 'worker', default=False)
|
||||
name = context.pop('queue_name', 'default')
|
||||
now = datetime.datetime.now()
|
||||
scheduled_at = context.pop('queue_scheduled_at', None)
|
||||
@@ -248,7 +246,7 @@ class _Method(object):
|
||||
if isinstance(instances, list):
|
||||
if has_worker and queue_batch:
|
||||
if isinstance(queue_batch, bool):
|
||||
count = batch_size
|
||||
count = config.getint('queue', 'batch_size', default=20)
|
||||
else:
|
||||
count = int(queue_batch)
|
||||
else:
|
||||
|
||||
@@ -6,7 +6,7 @@ import io
|
||||
import json
|
||||
from numbers import Number
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.i18n import gettext
|
||||
from trytond.protocols.jsonrpc import JSONDecoder
|
||||
from trytond.protocols.wrappers import (
|
||||
@@ -15,14 +15,6 @@ from trytond.tools import slugify
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.wsgi import app
|
||||
|
||||
SOURCE = config.get(
|
||||
'html', 'src',
|
||||
default='https://cdn.tiny.cloud/1/no-api-key/tinymce/7/tinymce.min.js')
|
||||
LICENSE_KEY = config.get('html', 'license_key', default='gpl')
|
||||
AVATAR_TIMEOUT = config.getint(
|
||||
'web', 'avatar_timeout', default=7 * 24 * 60 * 60)
|
||||
_request_timeout = config.getint('request', 'timeout', default=0)
|
||||
|
||||
|
||||
def get_token(record):
|
||||
return str((record.write_date or record.create_date).timestamp())
|
||||
@@ -84,10 +76,14 @@ def html_editor(request, pool, model, record, field):
|
||||
'field': field.string,
|
||||
'title': request.args.get('title', "Tryton"),
|
||||
}
|
||||
|
||||
source = config.get(
|
||||
'html', 'src',
|
||||
default='https://cdn.tiny.cloud'
|
||||
'/1/no-api-key/tinymce/7/tinymce.min.js')
|
||||
license_key = config.get('html', 'license_key', default='gpl')
|
||||
return Response(TEMPLATE % {
|
||||
'source': SOURCE,
|
||||
'license_key': LICENSE_KEY,
|
||||
'source': source,
|
||||
'license_key': license_key,
|
||||
'plugins': get_config(
|
||||
['plugins', model, field.name], default=''),
|
||||
'css': get_config(
|
||||
@@ -190,7 +186,8 @@ TEMPLATE = '''<!DOCTYPE html>
|
||||
@app.auth_required
|
||||
@with_pool
|
||||
@with_transaction(
|
||||
user='request', context=dict(_check_access=True), timeout=_request_timeout)
|
||||
user='request', context=dict(_check_access=True),
|
||||
timeout=config.getint('request', 'timeout', default=0))
|
||||
def data(request, pool, model):
|
||||
User = pool.get('res.user')
|
||||
Lang = pool.get('ir.lang')
|
||||
@@ -297,6 +294,7 @@ def avatar(request, pool, uuid):
|
||||
abort(HTTPStatus.BAD_REQUEST)
|
||||
response = Response(avatar.get(size), mimetype='image/jpeg')
|
||||
response.headers['Cache-Control'] = (
|
||||
'max-age=%s, public' % AVATAR_TIMEOUT)
|
||||
'max-age=%s, public' % config.getint(
|
||||
'web', 'avatar_timeout', default=7 * 24 * 60 * 60))
|
||||
response.add_etag()
|
||||
return response
|
||||
|
||||
@@ -4,15 +4,11 @@ import datetime
|
||||
import json
|
||||
from secrets import compare_digest, token_hex
|
||||
|
||||
import trytond.config as config
|
||||
from trytond.cache import Cache
|
||||
from trytond.config import config
|
||||
from trytond.model import Index, ModelSQL, fields
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
_session_timeout = datetime.timedelta(
|
||||
seconds=config.getint('session', 'timeout'))
|
||||
_reset_interval = _session_timeout // 10
|
||||
|
||||
|
||||
class Session(ModelSQL):
|
||||
__name__ = 'ir.session'
|
||||
@@ -135,8 +131,11 @@ class Session(ModelSQL):
|
||||
"Reset key session timestamp"
|
||||
now = datetime.datetime.now()
|
||||
last_reset = cls._session_reset_cache.get(key)
|
||||
if last_reset is None or (now - _reset_interval) > last_reset:
|
||||
timestamp = now - _session_timeout
|
||||
session_timeout = datetime.timedelta(
|
||||
seconds=config.getint('session', 'timeout'))
|
||||
reset_interval = session_timeout // 10
|
||||
if last_reset is None or (now - reset_interval) > last_reset:
|
||||
timestamp = now - session_timeout
|
||||
sessions = cls.search([
|
||||
('key', '=', key),
|
||||
['OR',
|
||||
|
||||
@@ -15,8 +15,8 @@ from sql.aggregate import Max
|
||||
from sql.conditionals import Case
|
||||
from sql.functions import Position, Substring
|
||||
|
||||
import trytond.config as config
|
||||
from trytond.cache import Cache
|
||||
from trytond.config import config
|
||||
from trytond.exceptions import UserError
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import Index, ModelSQL, ModelView, fields
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
import json
|
||||
from collections import OrderedDict
|
||||
|
||||
import trytond.config as config
|
||||
from trytond.cache import Cache
|
||||
from trytond.config import config
|
||||
from trytond.i18n import gettext, lazy_gettext
|
||||
from trytond.model import fields
|
||||
from trytond.model.exceptions import ValidationError
|
||||
@@ -14,9 +14,6 @@ from trytond.rpc import RPC
|
||||
from trytond.tools import slugify
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
_request_timeout = config.getint('request', 'timeout', default=0)
|
||||
_request_records_limit = config.getint('request', 'records_limit')
|
||||
|
||||
|
||||
class DomainError(ValidationError):
|
||||
pass
|
||||
@@ -97,13 +94,13 @@ class DictSchemaMixin(object):
|
||||
'get_keys': RPC(
|
||||
instantiate=0,
|
||||
size_limits={
|
||||
0: _request_records_limit,
|
||||
0: config.getint('request', 'records_limit'),
|
||||
}),
|
||||
'search_get_keys': RPC(
|
||||
size_limits={
|
||||
1: _request_records_limit,
|
||||
1: config.getint('request', 'records_limit'),
|
||||
},
|
||||
timeout=_request_timeout),
|
||||
timeout=config.getint('request', 'timeout', default=0)),
|
||||
})
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -10,7 +10,7 @@ from sql.conditionals import Coalesce
|
||||
from sql.functions import CharLength
|
||||
from sql.operators import Exists, Or
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.pool import Pool
|
||||
from trytond.pyson import PYSONEncoder
|
||||
from trytond.tools import cached_property, reduce_ids
|
||||
@@ -20,8 +20,6 @@ from .field import (
|
||||
Field, context_validate, domain_method, instantiate_context, order_method,
|
||||
search_order_validate)
|
||||
|
||||
_subquery_threshold = config.getint('database', 'subquery_threshold')
|
||||
|
||||
|
||||
class Many2One(Field):
|
||||
_type = 'many2one'
|
||||
@@ -225,7 +223,8 @@ class Many2One(Field):
|
||||
pool = Pool()
|
||||
Rule = pool.get('ir.rule')
|
||||
Target = self.get_target()
|
||||
use_subquery = Target.estimated_count() < _subquery_threshold
|
||||
subquery_threshold = config.getint('database', 'subquery_threshold')
|
||||
use_subquery = Target.estimated_count() < subquery_threshold
|
||||
|
||||
table, _ = tables[None]
|
||||
name, operator, value = domain[:3]
|
||||
|
||||
@@ -8,7 +8,7 @@ from sql import Literal
|
||||
from sql.conditionals import Coalesce
|
||||
from sql.operators import Exists
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.pool import Pool
|
||||
from trytond.pyson import PYSONEncoder
|
||||
from trytond.tools import cached_property, grouped_slice
|
||||
@@ -19,8 +19,6 @@ from .field import (
|
||||
instanciate_values, instantiate_context, search_order_validate,
|
||||
size_validate)
|
||||
|
||||
_subquery_threshold = config.getint('database', 'subquery_threshold')
|
||||
|
||||
|
||||
class One2Many(Field):
|
||||
_type = 'one2many'
|
||||
@@ -347,7 +345,8 @@ class One2Many(Field):
|
||||
origin_where = origin.like(Model.__name__ + ',%')
|
||||
origin = origin_field.sql_id(origin, Target)
|
||||
|
||||
use_in = Target.estimated_count() < _subquery_threshold
|
||||
subquery_threshold = config.getint('database', 'subquery_threshold')
|
||||
use_in = Target.estimated_count() < subquery_threshold
|
||||
if '.' not in name:
|
||||
if value is None:
|
||||
if use_in:
|
||||
|
||||
@@ -13,9 +13,8 @@ from sql.conditionals import Coalesce
|
||||
from sql.functions import CurrentTimestamp, Extract, RowNumber, Substring
|
||||
from sql.operators import And, Concat, Equal, Exists, Operator, Or
|
||||
|
||||
from trytond import backend
|
||||
from trytond import backend, config
|
||||
from trytond.cache import freeze
|
||||
from trytond.config import config
|
||||
from trytond.exceptions import ConcurrencyException
|
||||
from trytond.i18n import gettext
|
||||
from trytond.pool import Pool
|
||||
@@ -34,8 +33,6 @@ from .modelstorage import (
|
||||
ValidationError, is_leaf)
|
||||
from .modelview import ModelView
|
||||
|
||||
_request_records_limit = config.getint('request', 'records_limit')
|
||||
|
||||
|
||||
class ForeignKeyError(ValidationError):
|
||||
pass
|
||||
@@ -356,7 +353,7 @@ class ModelSQL(ModelStorage):
|
||||
cls.__rpc__.update({
|
||||
'history_revisions': RPC(
|
||||
size_limits={
|
||||
0: _request_records_limit,
|
||||
0: config.getint('request', 'records_limit'),
|
||||
}),
|
||||
})
|
||||
if cls._history:
|
||||
|
||||
@@ -16,8 +16,8 @@ from io import StringIO
|
||||
from itertools import chain, groupby, islice
|
||||
from operator import itemgetter
|
||||
|
||||
import trytond.config as config
|
||||
from trytond.cache import Cache, LRUDictTransaction, freeze, unfreeze
|
||||
from trytond.config import config
|
||||
from trytond.const import OPERATORS
|
||||
from trytond.exceptions import UserError
|
||||
from trytond.i18n import gettext, lazy_gettext
|
||||
@@ -36,13 +36,6 @@ from .descriptors import dualmethod
|
||||
from .model import Model
|
||||
|
||||
__all__ = ['ModelStorage', 'EvalEnvironment']
|
||||
_cache_field = config.getint('cache', 'field')
|
||||
_cache_count_timeout = config.getint(
|
||||
'cache', 'count_timeout', default=60 * 60 * 24)
|
||||
_cache_count_clear = config.getint(
|
||||
'cache', 'count_clear', default=1000)
|
||||
_request_timeout = config.getint('request', 'timeout', default=0)
|
||||
_request_records_limit = config.getint('request', 'records_limit')
|
||||
|
||||
|
||||
def local_cache(Model, transaction=None):
|
||||
@@ -125,7 +118,10 @@ class ModelStorage(Model):
|
||||
xml_id = fields.Function(
|
||||
fields.Char(lazy_gettext('ir.msg_xml_id')), 'get_xml_id')
|
||||
_count_cache = Cache(
|
||||
'modelstorage.count', duration=_cache_count_timeout, context=False)
|
||||
'modelstorage.count',
|
||||
duration=config.getint(
|
||||
'cache', 'count_timeout', default=60 * 60 * 24),
|
||||
context=False)
|
||||
_log = None
|
||||
|
||||
@classmethod
|
||||
@@ -133,74 +129,76 @@ class ModelStorage(Model):
|
||||
from .modelview import ModelView
|
||||
super().__setup__()
|
||||
if issubclass(cls, ModelView):
|
||||
request_timeout = config.getint('request', 'timeout', default=0)
|
||||
request_records_limit = config.getint('request', 'records_limit')
|
||||
cls.__rpc__.update({
|
||||
'create': RPC(
|
||||
readonly=False,
|
||||
size_limits={
|
||||
0: _request_records_limit,
|
||||
0: request_records_limit,
|
||||
},
|
||||
result=lambda r: list(map(int, r))),
|
||||
'read': RPC(
|
||||
timeout=_request_timeout,
|
||||
timeout=request_timeout,
|
||||
size_limits={
|
||||
0: _request_records_limit,
|
||||
0: request_records_limit,
|
||||
}),
|
||||
'write': RPC(
|
||||
readonly=False,
|
||||
instantiate=slice(0, None, 2),
|
||||
size_limits={
|
||||
(0, None, 2): _request_records_limit,
|
||||
(0, None, 2): request_records_limit,
|
||||
}),
|
||||
'delete': RPC(
|
||||
readonly=False,
|
||||
instantiate=0,
|
||||
size_limits={
|
||||
(0, None, 2): _request_records_limit,
|
||||
(0, None, 2): request_records_limit,
|
||||
}),
|
||||
'copy': RPC(
|
||||
readonly=False,
|
||||
instantiate=0,
|
||||
unique=False,
|
||||
size_limits={
|
||||
0: _request_records_limit,
|
||||
0: request_records_limit,
|
||||
},
|
||||
result=lambda r: list(map(int, r))),
|
||||
'search': RPC(
|
||||
result=lambda r: list(map(int, r)),
|
||||
size_limits={
|
||||
2: _request_records_limit,
|
||||
2: request_records_limit,
|
||||
},
|
||||
timeout=_request_timeout),
|
||||
timeout=request_timeout),
|
||||
'search_count': RPC(
|
||||
timeout=_request_timeout,
|
||||
timeout=request_timeout,
|
||||
size_limits={
|
||||
2: _request_records_limit,
|
||||
2: request_records_limit,
|
||||
}),
|
||||
'search_read': RPC(
|
||||
timeout=_request_timeout,
|
||||
timeout=request_timeout,
|
||||
size_limits={
|
||||
2: _request_records_limit,
|
||||
2: request_records_limit,
|
||||
}),
|
||||
'resources': RPC(
|
||||
instantiate=0,
|
||||
unique=False,
|
||||
timeout=_request_timeout),
|
||||
timeout=request_timeout),
|
||||
'export_data_domain': RPC(
|
||||
timeout=_request_timeout,
|
||||
timeout=request_timeout,
|
||||
size_limits={
|
||||
4: _request_records_limit,
|
||||
4: request_records_limit,
|
||||
}),
|
||||
'export_data': RPC(
|
||||
instantiate=0,
|
||||
unique=False,
|
||||
size_limits={
|
||||
0: _request_records_limit,
|
||||
0: request_records_limit,
|
||||
},
|
||||
timeout=_request_timeout),
|
||||
timeout=request_timeout),
|
||||
'import_data': RPC(
|
||||
readonly=False,
|
||||
size_limits={
|
||||
1: _request_records_limit,
|
||||
1: request_records_limit,
|
||||
}),
|
||||
})
|
||||
if cls._log is None:
|
||||
@@ -267,7 +265,8 @@ class ModelStorage(Model):
|
||||
|
||||
count = cls._count_cache.get(cls.__name__)
|
||||
if count is not None:
|
||||
if random.random() < 1 / _cache_count_clear:
|
||||
if random.random() < 1 / config.getint(
|
||||
'cache', 'count_clear', default=1000):
|
||||
cls._count_cache.set(cls.__name__, None)
|
||||
else:
|
||||
cls._count_cache.set(cls.__name__, count + len(vlist))
|
||||
@@ -464,7 +463,8 @@ class ModelStorage(Model):
|
||||
|
||||
count = cls._count_cache.get(cls.__name__)
|
||||
if count is not None:
|
||||
if random.random() < 1 / _cache_count_clear:
|
||||
if random.random() < 1 / config.getint(
|
||||
'cache', 'count_clear', default=1000):
|
||||
cls._count_cache.set(cls.__name__, None)
|
||||
else:
|
||||
cls._count_cache.set(cls.__name__, count - len(records))
|
||||
@@ -1889,7 +1889,7 @@ class ModelStorage(Model):
|
||||
ifields = filter(to_load,
|
||||
filter(not_cached,
|
||||
iter(self._fields.items())))
|
||||
ifields = islice(ifields, 0, _cache_field)
|
||||
ifields = islice(ifields, 0, config.getint('cache', 'field'))
|
||||
ffields.update(ifields)
|
||||
|
||||
# add datetime_field
|
||||
|
||||
@@ -5,8 +5,8 @@ from functools import wraps
|
||||
|
||||
from lxml import etree
|
||||
|
||||
import trytond.config as config
|
||||
from trytond.cache import Cache
|
||||
from trytond.config import config
|
||||
from trytond.exceptions import UserError
|
||||
from trytond.i18n import gettext
|
||||
from trytond.pool import Pool
|
||||
@@ -21,7 +21,6 @@ from .fields.field import _set_value
|
||||
from .model import Model
|
||||
|
||||
__all__ = ['ModelView']
|
||||
_request_records_limit = config.getint('request', 'records_limit')
|
||||
|
||||
|
||||
class AccessButtonError(UserError):
|
||||
@@ -102,7 +101,7 @@ class ModelView(Model):
|
||||
instantiate=0, result=on_change_result),
|
||||
'autocomplete': RPC(
|
||||
size_limits={
|
||||
2: _request_records_limit,
|
||||
2: config.getint('request', 'records_limit'),
|
||||
}),
|
||||
})
|
||||
cls._buttons = {}
|
||||
|
||||
@@ -13,10 +13,7 @@ from glob import iglob
|
||||
from sql import Table
|
||||
from sql.functions import CurrentTimestamp
|
||||
|
||||
import trytond.convert as convert
|
||||
import trytond.tools as tools
|
||||
from trytond import __series__
|
||||
from trytond.config import config
|
||||
from trytond import __series__, config, convert, tools
|
||||
from trytond.const import MODULES_GROUP
|
||||
from trytond.exceptions import MissingDependenciesException
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
@@ -7,8 +7,7 @@ import time
|
||||
|
||||
from sql import Table
|
||||
|
||||
from trytond import __series__, backend, security
|
||||
from trytond.config import config, get_hostname
|
||||
from trytond import __series__, backend, config, security
|
||||
from trytond.exceptions import (
|
||||
ConcurrencyException, LoginException, RateLimitException, UserError,
|
||||
UserWarning)
|
||||
@@ -122,7 +121,7 @@ def db_list(request, *args):
|
||||
if not config.getboolean('database', 'list'):
|
||||
abort(HTTPStatus.FORBIDDEN)
|
||||
context = {'_request': request.context}
|
||||
hostname = get_hostname(request.host)
|
||||
hostname = config.get_hostname(request.host)
|
||||
with Transaction().start(
|
||||
None, 0, context=context, readonly=True, close=True,
|
||||
) as transaction:
|
||||
|
||||
@@ -18,8 +18,7 @@ from werkzeug.utils import redirect, send_file
|
||||
from werkzeug.wrappers import Request as _Request
|
||||
from werkzeug.wrappers import Response
|
||||
|
||||
from trytond import backend, security
|
||||
from trytond.config import config, get_hostname
|
||||
from trytond import backend, config, security
|
||||
from trytond.exceptions import RateLimitException, UserError, UserWarning
|
||||
from trytond.pool import Pool
|
||||
from trytond.tools import cached_property
|
||||
@@ -193,7 +192,7 @@ def with_pool(func):
|
||||
database_list = Pool.database_list()
|
||||
if database_name not in database_list:
|
||||
with Transaction().start(None, 0, readonly=True) as transaction:
|
||||
hostname = get_hostname(request.host)
|
||||
hostname = config.get_hostname(request.host)
|
||||
db_list = transaction.database.list(hostname=hostname)
|
||||
if database_name not in db_list:
|
||||
abort(HTTPStatus.NOT_FOUND)
|
||||
|
||||
@@ -35,7 +35,7 @@ except ImportError:
|
||||
from genshi.filters import Translator
|
||||
from genshi.template.text import TextTemplate
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.i18n import gettext, ngettext
|
||||
from trytond.model.exceptions import AccessError
|
||||
from trytond.pool import Pool, PoolBase
|
||||
@@ -115,13 +115,6 @@ NO_BREAKING_SPACE = '\u00A0'
|
||||
# round it to 100.
|
||||
REPORT_NAME_MAX_LENGTH = 100
|
||||
|
||||
CONVERT_COMMAND = config.get(
|
||||
'report', 'convert_command',
|
||||
default='soffice --headless --nolockcheck --nodefault --norestore '
|
||||
'--convert-to "%(output_extension)s" '
|
||||
'--outdir "%(directory)s" '
|
||||
'"%(input_path)s"')
|
||||
|
||||
|
||||
class TranslateFactory:
|
||||
|
||||
@@ -434,7 +427,14 @@ class Report(URLMixin, PoolBase):
|
||||
with open(input_path, mode) as fp:
|
||||
fp.write(data)
|
||||
try:
|
||||
cmd = CONVERT_COMMAND % {
|
||||
cmd = config.get(
|
||||
'report', 'convert_command',
|
||||
default='soffice --headless '
|
||||
'--nolockcheck --nodefault --norestore '
|
||||
'--convert-to "%(output_extension)s" '
|
||||
'--outdir "%(directory)s" '
|
||||
'"%(input_path)s"')
|
||||
cmd %= {
|
||||
'directory': directory,
|
||||
'input_format': input_format,
|
||||
'input_extension': input_extension,
|
||||
|
||||
@@ -4,7 +4,7 @@ import logging
|
||||
import random
|
||||
import time
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.protocols.wrappers import (
|
||||
abort, allow_null_origin, with_pool, with_transaction)
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
@@ -30,8 +30,8 @@ from sql.aggregate import Count
|
||||
from sql.conditionals import Case
|
||||
from sql.functions import CurrentTimestamp
|
||||
|
||||
import trytond.config as config
|
||||
from trytond.cache import Cache
|
||||
from trytond.config import config
|
||||
from trytond.exceptions import LoginException, RateLimitException, UserError
|
||||
from trytond.i18n import gettext, ngettext
|
||||
from trytond.model import (
|
||||
|
||||
@@ -16,8 +16,7 @@ from sql import Table
|
||||
from sql.conditionals import Coalesce
|
||||
from werkzeug.exceptions import abort
|
||||
|
||||
from trytond import backend
|
||||
from trytond.config import config
|
||||
from trytond import backend, config
|
||||
from trytond.exceptions import LoginException, RateLimitException
|
||||
from trytond.pool import Pool
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
@@ -8,7 +8,7 @@ from email.message import EmailMessage, Message
|
||||
from email.utils import formatdate, make_msgid
|
||||
from urllib.parse import parse_qs, unquote_plus
|
||||
|
||||
from trytond.config import config, parse_uri
|
||||
import trytond.config as config
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.url import host
|
||||
|
||||
@@ -17,7 +17,6 @@ __all__ = [
|
||||
'send_message_transactional', 'send_message',
|
||||
'SMTPDataManager']
|
||||
logger = logging.getLogger(__name__)
|
||||
retry = config.getint('email', 'retry', default=5)
|
||||
|
||||
|
||||
def sendmail_transactional(
|
||||
@@ -59,6 +58,7 @@ def send_message(
|
||||
quit = False
|
||||
if 'Date' not in msg:
|
||||
msg['Date'] = formatdate()
|
||||
retry = config.getint('email', 'retry', default=5)
|
||||
for count in range(retry, -1, -1):
|
||||
if count != retry:
|
||||
time.sleep(0.02 * (retry - count))
|
||||
@@ -110,7 +110,7 @@ def get_smtp_server(uri=None, strict=False):
|
||||
if uri is None:
|
||||
uri = config.get('email', 'uri')
|
||||
ini_uri = uri
|
||||
uri = parse_uri(uri)
|
||||
uri = config.parse_uri(uri)
|
||||
extra = {}
|
||||
if uri.query:
|
||||
cast = {'timeout': int}
|
||||
|
||||
@@ -10,7 +10,7 @@ import time
|
||||
from collections import namedtuple
|
||||
from contextlib import contextmanager
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
|
||||
status = dict()
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -5,7 +5,7 @@ import time
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from trytond import backend, bus
|
||||
from trytond import backend, config
|
||||
from trytond.bus import Bus, _MessageQueue, notify
|
||||
from trytond.tests.test_tryton import (
|
||||
DB_NAME, TestCase, activate_module, with_transaction)
|
||||
@@ -85,15 +85,15 @@ class BusTestCase(TestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
reset_polling_timeout = bus._long_polling_timeout
|
||||
bus._long_polling_timeout = 1
|
||||
polling_timeout = config.get('bus', 'long_polling_timeout')
|
||||
config.set('bus', 'long_polling_timeout', '1')
|
||||
self.addCleanup(
|
||||
setattr, bus, '_long_polling_timeout', reset_polling_timeout)
|
||||
config.set, 'bus', 'long_polling_timeout', polling_timeout)
|
||||
|
||||
reset_select_timeout = bus._select_timeout
|
||||
bus._select_timeout = 1
|
||||
select_timeout = config.get('bus', 'select_timeout')
|
||||
config.set('bus', 'select_timeout', '1')
|
||||
self.addCleanup(
|
||||
setattr, bus, '_select_timeout', reset_select_timeout)
|
||||
config.set, 'bus', 'select_timeout', select_timeout)
|
||||
|
||||
def tearDown(self):
|
||||
pid = os.getpid()
|
||||
|
||||
@@ -6,8 +6,7 @@ import time
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from trytond import backend
|
||||
from trytond import cache as cache_mod
|
||||
from trytond import backend, config
|
||||
from trytond.cache import (
|
||||
LRUDict, LRUDictTransaction, MemoryCache, freeze, unfreeze)
|
||||
from trytond.tests.test_tryton import (
|
||||
@@ -106,10 +105,10 @@ class MemoryCacheTestCase(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
clear_timeout = cache_mod._clean_timeout
|
||||
cache_mod._clean_timeout = 1
|
||||
clean_timeout = config.get('cache', 'clean_timeout')
|
||||
config.set('cache', 'clean_timeout', '1')
|
||||
self.addCleanup(
|
||||
setattr, cache_mod, '_clean_timeout', clear_timeout)
|
||||
config.set, 'cache', 'clean_timeout', clean_timeout)
|
||||
|
||||
def tearDown(self):
|
||||
MemoryCache.drop(DB_NAME)
|
||||
@@ -176,7 +175,7 @@ class MemoryCacheTestCase(TestCase):
|
||||
with Transaction().start(DB_NAME, USER):
|
||||
cache.clear()
|
||||
# Ensure sync is performed on start
|
||||
time.sleep(cache_mod._clean_timeout)
|
||||
time.sleep(config.getint('cache', 'clean_timeout'))
|
||||
|
||||
with Transaction().start(DB_NAME, USER) as transaction1:
|
||||
cache.clear()
|
||||
@@ -187,7 +186,7 @@ class MemoryCacheTestCase(TestCase):
|
||||
"Test MemoryCache synchronisation"
|
||||
with Transaction().start(DB_NAME, USER):
|
||||
cache.clear()
|
||||
time.sleep(cache_mod._clean_timeout)
|
||||
time.sleep(config.getint('cache', 'clean_timeout'))
|
||||
last = cache._clean_last
|
||||
|
||||
with Transaction().start(DB_NAME, USER):
|
||||
@@ -243,10 +242,10 @@ class MemoryCacheChannelTestCase(MemoryCacheTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
clear_timeout = cache_mod._clean_timeout
|
||||
cache_mod._clean_timeout = 0
|
||||
clean_timeout = config.get('cache', 'clean_timeout')
|
||||
config.set('cache', 'clean_timeout', '0')
|
||||
self.addCleanup(
|
||||
setattr, cache_mod, '_clean_timeout', clear_timeout)
|
||||
config.set, 'cache', 'clean_timeout', clean_timeout)
|
||||
|
||||
def wait_cache_sync(self, after=None):
|
||||
if after is None:
|
||||
|
||||
@@ -5,7 +5,7 @@ import tempfile
|
||||
|
||||
from sql import Literal
|
||||
|
||||
from trytond import filestore
|
||||
from trytond import config
|
||||
from trytond.model import fields
|
||||
from trytond.model.exceptions import (
|
||||
RequiredValidationError, SQLConstraintError)
|
||||
@@ -27,10 +27,10 @@ class FieldBinaryTestCase(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
path = filestore.PATH
|
||||
path = config.get('database', 'path')
|
||||
dtemp = tempfile.mkdtemp()
|
||||
filestore.PATH = dtemp
|
||||
self.addCleanup(setattr, filestore, 'PATH', path)
|
||||
config.set('database', 'path', dtemp)
|
||||
self.addCleanup(config.set, 'database', 'path', path)
|
||||
self.addCleanup(shutil.rmtree, dtemp)
|
||||
|
||||
@with_transaction()
|
||||
|
||||
@@ -5,7 +5,7 @@ from unittest.mock import patch
|
||||
|
||||
from sql import Join, Table
|
||||
|
||||
from trytond.config import config
|
||||
import trytond.config as config
|
||||
from trytond.model.exceptions import DomainValidationError
|
||||
from trytond.pool import Pool
|
||||
from trytond.tests.test_tryton import (
|
||||
@@ -354,12 +354,10 @@ class FieldMany2OneExistsTestCase(
|
||||
activate_module('tests')
|
||||
|
||||
def setUp(self):
|
||||
from trytond.model.fields import many2one
|
||||
super().setUp()
|
||||
previous = int(
|
||||
config.get('database', 'subquery_threshold', default='1_000'))
|
||||
many2one._subquery_threshold = 0
|
||||
self.addCleanup(setattr, many2one, '_subquery_threshold', previous)
|
||||
previous = config.get('database', 'subquery_threshold')
|
||||
config.set('database', 'subquery_threshold', '0')
|
||||
self.addCleanup(config.set, 'database', 'subquery_threshold', previous)
|
||||
|
||||
|
||||
class FieldMany2OneTreeTestCase(TestCase):
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user