You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

254 lines
8.8 KiB

9 years ago
10 years ago
  1. # -*- coding: utf-8 -*-
  2. ##############################################################################
  3. #
  4. # Adapted by Nicolas Bessi. Copyright Camptocamp SA
  5. # Based on Florent Xicluna original code. Copyright Wingo SA
  6. #
  7. # This program is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation, either version 3 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. #
  20. ##############################################################################
  21. import logging
  22. import os
  23. import ConfigParser
  24. from lxml import etree
  25. from itertools import chain
  26. from openerp import models, fields
  27. from openerp.tools.config import config as system_base_config
  28. from .system_info import get_server_environment
  29. _logger = logging.getLogger(__name__)
  30. # Same dict as RawConfigParser._boolean_states
  31. _boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True,
  32. '0': False, 'no': False, 'false': False, 'off': False}
  33. try:
  34. from openerp.addons import server_environment_files
  35. _dir = os.path.dirname(server_environment_files.__file__)
  36. if not system_base_config.get('running_env', False):
  37. raise Exception(
  38. "The parameter 'running_env' has not be set neither in base "
  39. "config file option -c or in openerprc.\n"
  40. "We strongly recommend against using the rc file but instead use "
  41. "an explicit config file with this content:\n"
  42. "[options]\nrunning_env = dev"
  43. )
  44. ck_path = os.path.join(_dir, system_base_config['running_env'])
  45. if not os.path.exists(ck_path):
  46. raise Exception(
  47. "Provided server environment does not exist, "
  48. "please add a folder %s" % ck_path
  49. )
  50. except ImportError:
  51. _logger.info("ImportError raised while loading module.")
  52. _logger.debug("ImportError details:", exc_info=True)
  53. server_environment_files = False
  54. def setboolean(obj, attr, _bool=None):
  55. """Replace the attribute with a boolean."""
  56. if _bool is None:
  57. _bool = dict(_boolean_states)
  58. res = _bool[getattr(obj, attr).lower()]
  59. setattr(obj, attr, res)
  60. return res
  61. # Borrowed from MarkupSafe
  62. def _escape(s):
  63. """Convert the characters &<>'" in string s to HTML-safe sequences."""
  64. return (str(s).replace('&', '&amp;')
  65. .replace('>', '&gt;')
  66. .replace('<', '&lt;')
  67. .replace("'", '&#39;')
  68. .replace('"', '&#34;'))
  69. def _listconf(env_path):
  70. """List configuration files in a folder."""
  71. files = [os.path.join(env_path, name)
  72. for name in sorted(os.listdir(env_path))
  73. if name.endswith('.conf')]
  74. return files
  75. def _load_config():
  76. """Load the configuration and return a ConfigParser instance."""
  77. default = os.path.join(_dir, 'default')
  78. running_env = os.path.join(_dir,
  79. system_base_config['running_env'])
  80. if os.path.isdir(default):
  81. conf_files = _listconf(default) + _listconf(running_env)
  82. else:
  83. conf_files = _listconf(running_env)
  84. config_p = ConfigParser.SafeConfigParser()
  85. # options are case-sensitive
  86. config_p.optionxform = str
  87. try:
  88. config_p.read(conf_files)
  89. except Exception as e:
  90. raise Exception('Cannot read config files "%s": %s' % (conf_files, e))
  91. return config_p
  92. if server_environment_files:
  93. serv_config = _load_config()
  94. class _Defaults(dict):
  95. __slots__ = ()
  96. def __setitem__(self, key, value):
  97. def func(*a):
  98. return str(value)
  99. return dict.__setitem__(self, key, func)
  100. class ServerConfiguration(models.TransientModel):
  101. """Display server configuration."""
  102. _name = 'server.config'
  103. _conf_defaults = _Defaults()
  104. def __init__(self, pool, cr):
  105. """Add columns to model dynamically
  106. and init some properties
  107. """
  108. self._add_columns()
  109. super(ServerConfiguration, self).__init__(pool, cr)
  110. self.running_env = system_base_config['running_env']
  111. # Only show passwords in development
  112. self.show_passwords = self.running_env in ('dev',)
  113. self._arch = None
  114. self._build_osv()
  115. def _format_key(self, section, key):
  116. return '%s | %s' % (section, key)
  117. def _add_columns(self):
  118. """Add columns to model dynamically"""
  119. cols = chain(
  120. self._get_base_cols().items(),
  121. self._get_env_cols().items(),
  122. self._get_system_cols().items()
  123. )
  124. for col, value in cols:
  125. col_name = col.replace('.', '_')
  126. setattr(ServerConfiguration,
  127. col_name,
  128. fields.Char(string=col, readonly=True))
  129. self._conf_defaults[col_name] = value
  130. def _get_base_cols(self):
  131. """ Compute base fields"""
  132. res = {}
  133. for col, item in system_base_config.options.items():
  134. key = self._format_key('openerp', col)
  135. res[key] = item
  136. return res
  137. def _get_env_cols(self, sections=None):
  138. """ Compute base fields"""
  139. res = {}
  140. sections = sections if sections else serv_config.sections()
  141. for section in sections:
  142. for col, item in serv_config.items(section):
  143. key = self._format_key(section, col)
  144. res[key] = item
  145. return res
  146. def _get_system_cols(self):
  147. """ Compute system fields"""
  148. res = {}
  149. for col, item in get_server_environment():
  150. key = self._format_key('system', col)
  151. res[key] = item
  152. return res
  153. def _group(self, items):
  154. """Return an XML chunk which represents a group of fields."""
  155. names = []
  156. for key in sorted(items):
  157. names.append(key.replace('.', '_'))
  158. return ('<group col="2" colspan="4">' +
  159. ''.join(['<field name="%s" readonly="1"/>' %
  160. _escape(name) for name in names]) +
  161. '</group>')
  162. def _build_osv(self):
  163. """Build the view for the current configuration."""
  164. arch = ('<?xml version="1.0" encoding="utf-8"?>'
  165. '<form string="Configuration Form">'
  166. '<notebook colspan="4">')
  167. # OpenERP server configuration
  168. rcfile = system_base_config.rcfile
  169. items = self._get_base_cols()
  170. arch += '<page string="OpenERP">'
  171. arch += '<separator string="%s" colspan="4"/>' % _escape(rcfile)
  172. arch += self._group(items)
  173. arch += '<separator colspan="4"/></page>'
  174. arch += '<page string="Environment based configurations">'
  175. for section in sorted(serv_config.sections()):
  176. items = self._get_env_cols(sections=[section])
  177. arch += '<separator string="[%s]" colspan="4"/>' % _escape(section)
  178. arch += self._group(items)
  179. arch += '<separator colspan="4"/></page>'
  180. # System information
  181. arch += '<page string="System">'
  182. arch += '<separator string="Server Environment" colspan="4"/>'
  183. arch += self._group(self._get_system_cols())
  184. arch += '<separator colspan="4"/></page>'
  185. arch += '</notebook></form>'
  186. self._arch = etree.fromstring(arch)
  187. def fields_view_get(self, cr, uid, view_id=None, view_type='form',
  188. context=None, toolbar=False, submenu=False):
  189. """Overwrite the default method to render the custom view."""
  190. res = super(ServerConfiguration, self).fields_view_get(cr, uid,
  191. view_id,
  192. view_type,
  193. context,
  194. toolbar)
  195. if view_type == 'form':
  196. arch_node = self._arch
  197. xarch, xfields = self._view_look_dom_arch(cr, uid,
  198. arch_node,
  199. view_id,
  200. context=context)
  201. res['arch'] = xarch
  202. res['fields'] = xfields
  203. return res
  204. def default_get(self, cr, uid, fields_list, context=None):
  205. res = {}
  206. for key in self._conf_defaults:
  207. if 'passw' in key and not self.show_passwords:
  208. res[key] = '**********'
  209. else:
  210. res[key] = self._conf_defaults[key]()
  211. return res