cwconfig.py
brancholdstable
changeset 4985 02b52bf9f5f8
parent 4936 a4b772a0d801
child 4938 b1a4fe480de5
--- a/cwconfig.py	Fri Feb 12 15:18:00 2010 +0100
+++ b/cwconfig.py	Wed Mar 24 10:23:31 2010 +0100
@@ -78,12 +78,13 @@
 import sys
 import os
 import logging
+import tempfile
 from smtplib import SMTP
 from threading import Lock
 from os.path import exists, join, expanduser, abspath, normpath, basename, isdir
-import tempfile
+from warnings import warn
 
-from logilab.common.decorators import cached
+from logilab.common.decorators import cached, classproperty
 from logilab.common.deprecation import deprecated
 from logilab.common.logging_ext import set_log_methods, init_log
 from logilab.common.configuration import (Configuration, Method,
@@ -114,7 +115,7 @@
 
 def possible_configurations(directory):
     """return a list of installed configurations in a directory
-    according to *-ctl files
+    according to \*-ctl files
     """
     return [name for name in ('repository', 'twisted', 'all-in-one')
             if exists(join(directory, '%s.conf' % name))]
@@ -216,7 +217,9 @@
 
     if os.environ.get('APYCOT_ROOT'):
         mode = 'test'
-        if CWDEV:
+        # allow to test cubes within apycot using cubicweb not installed by
+        # apycot
+        if __file__.startswith(os.environ['APYCOT_ROOT']):
             CUBES_DIR = '%(APYCOT_ROOT)s/local/share/cubicweb/cubes/' % os.environ
             # create __init__ file
             file(join(CUBES_DIR, '__init__.py'), 'w').close()
@@ -235,7 +238,7 @@
     options = (
        ('log-threshold',
          {'type' : 'string', # XXX use a dedicated type?
-          'default': 'ERROR',
+          'default': 'WARNING',
           'help': 'server\'s log level',
           'group': 'main', 'inputlevel': 1,
           }),
@@ -290,11 +293,6 @@
 this option is set to yes",
           'group': 'email', 'inputlevel': 2,
           }),
-        ('disable-appobjects',
-         {'type' : 'csv', 'default': (),
-          'help': 'comma separated list of identifiers of application objects (<registry>.<oid>) to disable',
-          'group': 'appobjects', 'inputlevel': 2,
-          }),
         )
     # static and class methods used to get instance independant resources ##
 
@@ -332,7 +330,7 @@
         cubes = set()
         for directory in cls.cubes_search_path():
             if not os.path.exists(directory):
-                self.error('unexistant directory in cubes search path: %s'
+                cls.error('unexistant directory in cubes search path: %s'
                            % directory)
                 continue
             for cube in os.listdir(directory):
@@ -351,10 +349,18 @@
                     path.append(directory)
         except KeyError:
             pass
-        if not cls.CUBES_DIR in path:
+        if not cls.CUBES_DIR in path and exists(cls.CUBES_DIR):
             path.append(cls.CUBES_DIR)
         return path
 
+    @classproperty
+    def extrapath(cls):
+        extrapath = {}
+        for cubesdir in cls.cubes_search_path():
+            if cubesdir != cls.CUBES_DIR:
+                extrapath[cubesdir] = 'cubes'
+        return extrapath
+
     @classmethod
     def cube_dir(cls, cube):
         """return the cube directory for the given cube id,
@@ -470,7 +476,7 @@
         from logilab.common.modutils import load_module_from_file
         cls.cls_adjust_sys_path()
         for ctlfile in ('web/webctl.py',  'etwist/twctl.py',
-                        'server/serverctl.py', 'hercule.py',
+                        'server/serverctl.py',
                         'devtools/devctl.py', 'goa/goactl.py'):
             if exists(join(CW_SOFTWARE_ROOT, ctlfile)):
                 try:
@@ -480,14 +486,23 @@
                                 (ctlfile, err))
                 cls.info('loaded cubicweb-ctl plugin %s', ctlfile)
         for cube in cls.available_cubes():
-            pluginfile = join(cls.cube_dir(cube), 'ecplugin.py')
+            oldpluginfile = join(cls.cube_dir(cube), 'ecplugin.py')
+            pluginfile = join(cls.cube_dir(cube), 'ccplugin.py')
             initfile = join(cls.cube_dir(cube), '__init__.py')
             if exists(pluginfile):
                 try:
+                    __import__('cubes.%s.ccplugin' % cube)
+                    cls.info('loaded cubicweb-ctl plugin from %s', cube)
+                except:
+                    cls.exception('while loading plugin %s', pluginfile)
+            elif exists(oldpluginfile):
+                warn('[3.6] %s: ecplugin module should be renamed to ccplugin' % cube,
+                     DeprecationWarning)
+                try:
                     __import__('cubes.%s.ecplugin' % cube)
                     cls.info('loaded cubicweb-ctl plugin from %s', cube)
                 except:
-                    cls.exception('while loading plugin %s', pluginfile)
+                    cls.exception('while loading plugin %s', oldpluginfile)
             elif exists(initfile):
                 try:
                     __import__('cubes.%s' % cube)
@@ -556,6 +571,7 @@
         return vregpath
 
     def __init__(self):
+        register_stored_procedures()
         ConfigurationMixIn.__init__(self)
         self.adjust_sys_path()
         self.load_defaults()
@@ -624,16 +640,18 @@
     """base class for cubicweb server and web configurations"""
 
     INSTANCES_DATA_DIR = None
-    if CubicWebNoAppConfiguration.mode == 'test':
+    if os.environ.get('APYCOT_ROOT'):
         root = os.environ['APYCOT_ROOT']
         REGISTRY_DIR = '%s/etc/cubicweb.d/' % root
+        if not exists(REGISTRY_DIR):
+            os.makedirs(REGISTRY_DIR)
         RUNTIME_DIR = tempfile.gettempdir()
-        if CWDEV:
+        # allow to test cubes within apycot using cubicweb not installed by
+        # apycot
+        if __file__.startswith(os.environ['APYCOT_ROOT']):
             MIGRATION_DIR = '%s/local/share/cubicweb/migration/' % root
         else:
             MIGRATION_DIR = '/usr/share/cubicweb/migration/'
-        if not exists(REGISTRY_DIR):
-            os.makedirs(REGISTRY_DIR)
     else:
         if CubicWebNoAppConfiguration.mode == 'user':
             REGISTRY_DIR = expanduser('~/etc/cubicweb.d/')
@@ -862,11 +880,15 @@
                 if exists(sitefile) and not sitefile in self._site_loaded:
                     self._load_site_cubicweb(sitefile)
                     self._site_loaded.add(sitefile)
-                    self.warning('site_erudi.py is deprecated, should be renamed to site_cubicweb.py')
+                    self.warning('[3.5] site_erudi.py is deprecated, should be renamed to site_cubicweb.py')
 
     def _load_site_cubicweb(self, sitefile):
-        from logilab.common.modutils import load_module_from_file
-        module = load_module_from_file(sitefile)
+        # XXX extrapath argument to load_module_from_file only in lgc > 0.46
+        from logilab.common.modutils import load_module_from_modpath, modpath_from_file
+        def load_module_from_file(filepath, path=None, use_sys=1, extrapath=None):
+            return load_module_from_modpath(modpath_from_file(filepath, extrapath),
+                                            path, use_sys)
+        module = load_module_from_file(sitefile, extrapath=self.extrapath)
         self.info('%s loaded', sitefile)
         # cube specific options
         if getattr(module, 'options', None):
@@ -896,7 +918,7 @@
         """return available translation for an instance, by looking for
         compiled catalog
 
-        take *args to be usable as a vocabulary method
+        take \*args to be usable as a vocabulary method
         """
         from glob import glob
         yield 'en' # ensure 'en' is yielded even if no .mo found
@@ -935,11 +957,11 @@
 
     def migration_handler(self):
         """return a migration handler instance"""
-        from cubicweb.common.migration import MigrationHelper
+        from cubicweb.migration import MigrationHelper
         return MigrationHelper(self, verbosity=self.verbosity)
 
     def i18ncompile(self, langs=None):
-        from cubicweb.common import i18n
+        from cubicweb import i18n
         if langs is None:
             langs = self.available_languages()
         i18ndir = join(self.apphome, 'i18n')
@@ -976,3 +998,61 @@
 # alias to get a configuration instance from an instance id
 instance_configuration = CubicWebConfiguration.config_for
 application_configuration = deprecated('use instance_configuration')(instance_configuration)
+
+
+_EXT_REGISTERED = False
+def register_stored_procedures():
+    from logilab.common.adbh import FunctionDescr
+    from rql.utils import register_function, iter_funcnode_variables
+
+    global _EXT_REGISTERED
+    if _EXT_REGISTERED:
+        return
+    _EXT_REGISTERED = True
+
+    class COMMA_JOIN(FunctionDescr):
+        supported_backends = ('postgres', 'sqlite',)
+        rtype = 'String'
+
+        @classmethod
+        def st_description(cls, funcnode, mainindex, tr):
+            return ', '.join(sorted(term.get_description(mainindex, tr)
+                                    for term in iter_funcnode_variables(funcnode)))
+
+    register_function(COMMA_JOIN)  # XXX do not expose?
+
+
+    class CONCAT_STRINGS(COMMA_JOIN):
+        aggregat = True
+
+    register_function(CONCAT_STRINGS) # XXX bw compat
+
+    class GROUP_CONCAT(CONCAT_STRINGS):
+        supported_backends = ('mysql', 'postgres', 'sqlite',)
+
+    register_function(GROUP_CONCAT)
+
+
+    class LIMIT_SIZE(FunctionDescr):
+        supported_backends = ('postgres', 'sqlite',)
+        rtype = 'String'
+
+        @classmethod
+        def st_description(cls, funcnode, mainindex, tr):
+            return funcnode.children[0].get_description(mainindex, tr)
+
+    register_function(LIMIT_SIZE)
+
+
+    class TEXT_LIMIT_SIZE(LIMIT_SIZE):
+        supported_backends = ('mysql', 'postgres', 'sqlite',)
+
+    register_function(TEXT_LIMIT_SIZE)
+
+
+
+    class FSPATH(FunctionDescr):
+        supported_backends = ('postgres', 'sqlite',)
+        rtype = 'Bytes'
+
+    register_function(FSPATH)