From fbc4f8f92852e538feaf34dd621b21d8e0f82b17 Mon Sep 17 00:00:00 2001 From: Guewen Baconnier Date: Thu, 19 Jul 2018 15:57:58 +0200 Subject: [PATCH] Add a server environment mixin To automatically convert fields into fields reading values from the environment. Until now, every module reimplements the same computed field. --- server_environment/__init__.py | 1 + server_environment/models/__init__.py | 1 + server_environment/models/server_env_mixin.py | 112 ++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 server_environment/models/__init__.py create mode 100644 server_environment/models/server_env_mixin.py diff --git a/server_environment/__init__.py b/server_environment/__init__.py index 8e7cc35..3824827 100644 --- a/server_environment/__init__.py +++ b/server_environment/__init__.py @@ -17,4 +17,5 @@ # along with this program. If not, see . # ############################################################################## +from . import models from .serv_config import serv_config, setboolean diff --git a/server_environment/models/__init__.py b/server_environment/models/__init__.py new file mode 100644 index 0000000..6bd869a --- /dev/null +++ b/server_environment/models/__init__.py @@ -0,0 +1 @@ +from . import server_env_mixin diff --git a/server_environment/models/server_env_mixin.py b/server_environment/models/server_env_mixin.py new file mode 100644 index 0000000..c6770f9 --- /dev/null +++ b/server_environment/models/server_env_mixin.py @@ -0,0 +1,112 @@ +# Copyright 2018 Camptocamp (https://www.camptocamp.com). +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import logging + +from odoo import api, models +from ..serv_config import serv_config + +_logger = logging.getLogger(__name__) + + +class ServerEnvMixin(models.AbstractModel): + """Mixin to add server environment in existing models + + Usage:: + + class StorageBackend(models.Model): + _name = "storage.backend" + _inherit = ["storage.backend", "server.env.mixin"] + + @property + def _server_env_fields(self): + return {"directory_path": 'get'} + + With the snippet above, the "storage.backend" model will now use a server + environment configuration for the field ``directory_path``. + + Under the hood, this mixin will automatically replaces the original field + by a computed field that reads from the configuration files. + + By default, it will look for the configuration in a section named + ``[model_name.Record Name]`` where ``model_name`` is the ``_name`` of the + model with ``.`` replaced by ``_``. It can be customized by overriding the + method :meth:`~server_env_section_name`. + """ + _name = 'server.env.mixin' + + @property + def _server_env_fields(self): + """Dict of fields to replace by fields computed from env + + To override in models. The dictionary is: + {'name_of_the_field': 'name_of_the_configparser_getter'} + + The configparser getter can be one of: get, getbool, getint + + Example:: + + @property + def _server_env_fields(self): + base_fields = super()._server_env_fields + sftp_fields = { + "sftp_server": "get", + "sftp_port": "getint", + "sftp_login": "get", + "sftp_password": "get", + } + sftp_fields.update(base_fields) + return sftp_fields + """ + return {} + + @api.multi + def _server_env_section_name(self): + """Name of the section in the configuration files + + Can be customized in your model + """ + self.ensure_one() + return ".".join( + (self._name.replace(".", "_"), self.name) + ) + + @api.multi + def _server_env_read_from_config(self, section_name, field_name, + config_getter): + self.ensure_one() + try: + getter = getattr(serv_config, config_getter) + value = getter(section_name, field_name) + except: + _logger.exception( + "error trying to read field %s in section %s", + field_name, + section_name, + ) + return False + return value + + @api.multi + def _compute_server_env(self): + for record in self: + for field_name, getter_name in self._server_env_fields.items(): + section_name = self._server_env_section_name() + value = self._server_env_read_from_config( + section_name, field_name, getter_name + ) + record[field_name] = value + + def _server_env_transform_field_to_read_from_env(self, field): + """Transform the original field in a computed field""" + field.compute = '_compute_server_env' + field.store = False + field.copy = False + field.sparse = None + + @api.model + def _setup_base(self): + super()._setup_base() + for fieldname in self._server_env_fields: + field = self._fields[fieldname] + self._server_env_transform_field_to_read_from_env(field)