# HG changeset patch # User sylvain.thenault@logilab.fr # Date 1240595207 -7200 # Node ID 183da3addf0ee58acd2dea98ab3cf0b476b8b4c3 # Parent 1367efbcd6a5a14e719d92f7c56cb84eed31b708# Parent b7494ff85e16aed16d6081d96dbf9310bbdaba9f remerge diff -r b7494ff85e16 -r 183da3addf0e __init__.py --- a/__init__.py Wed Apr 22 09:45:54 2009 +0200 +++ b/__init__.py Fri Apr 24 19:46:47 2009 +0200 @@ -212,16 +212,29 @@ # XXX 2.45 is allowing nicer entity type names, use this map for bw compat -ETYPE_NAME_MAP = {'Eetype': 'EEType', - 'Ertype': 'ERType', - 'Efrdef': 'EFRDef', - 'Enfrdef': 'ENFRDef', - 'Econstraint': 'EConstraint', - 'Econstrainttype': 'EConstraintType', - 'Epermission': 'EPermission', - 'Egroup': 'EGroup', - 'Euser': 'EUser', - 'Eproperty': 'EProperty', +ETYPE_NAME_MAP = {# 3.2 migration + 'ECache': 'CWCache', + 'EUser': 'CWUser', + 'EGroup': 'CWGroup', + 'EProperty': 'CWProperty', + 'EFRDef': 'CWAttribute', + 'ENFRDef': 'CWRelation', + 'ERType': 'CWRType', + 'EEType': 'CWEType', + 'EConstraintType': 'CWConstraintType', + 'EConstraint': 'CWConstraint', + 'EPermission': 'CWPermission', + # 2.45 migration + 'Eetype': 'CWEType', + 'Ertype': 'CWRType', + 'Efrdef': 'CWAttribute', + 'Enfrdef': 'CWRelation', + 'Econstraint': 'CWConstraint', + 'Econstrainttype': 'CWConstraintType', + 'Epermission': 'CWPermission', + 'Egroup': 'CWGroup', + 'Euser': 'CWUser', + 'Eproperty': 'CWProperty', 'Emailaddress': 'EmailAddress', 'Rqlexpression': 'RQLExpression', 'Trinfo': 'TrInfo', @@ -269,11 +282,6 @@ 'agueol': 'agueol', 'docaster': 'docaster', 'asteretud': 'asteretud', - - # XXX temp - 'keywords': 'keyword', - 'folders': 'folder', - 'tags': 'tag', } def neg_role(role): diff -r b7494ff85e16 -r 183da3addf0e __pkginfo__.py --- a/__pkginfo__.py Wed Apr 22 09:45:54 2009 +0200 +++ b/__pkginfo__.py Fri Apr 24 19:46:47 2009 +0200 @@ -6,7 +6,7 @@ distname = "cubicweb" modname = "cubicweb" -numversion = (3, 1, 4) +numversion = (3, 2, 0) version = '.'.join(str(num) for num in numversion) license = 'LGPL v2' diff -r b7494ff85e16 -r 183da3addf0e appobject.py --- a/appobject.py Wed Apr 22 09:45:54 2009 +0200 +++ b/appobject.py Fri Apr 24 19:46:47 2009 +0200 @@ -77,7 +77,7 @@ return cls(*args, **kwargs) # Eproperties definition: - # key: id of the property (the actual EProperty key is build using + # key: id of the property (the actual CWProperty key is build using # .. # value: tuple (property type, vocabfunc, default value, property description) # possible types are those used by `logilab.common.configuration` @@ -132,7 +132,7 @@ CACHE_REGISTRY[cachename] = cache _now = datetime.now() if _now > cache.latest_cache_lookup + ONESECOND: - ecache = self.req.execute('Any C,T WHERE C is ECache, C name %(name)s, C timestamp T', + ecache = self.req.execute('Any C,T WHERE C is CWCache, C name %(name)s, C timestamp T', {'name':cachename}).get_entity(0,0) cache.latest_cache_lookup = _now if not ecache.valid(cache.cache_creation_date): diff -r b7494ff85e16 -r 183da3addf0e common/mixins.py --- a/common/mixins.py Wed Apr 22 09:45:54 2009 +0200 +++ b/common/mixins.py Fri Apr 24 19:46:47 2009 +0200 @@ -26,10 +26,10 @@ # XXX misnamed parent_target = 'subject' children_target = 'object' - + def different_type_children(self, entities=True): """return children entities of different type as this entity. - + according to the `entities` parameter, return entity objects or the equivalent result set """ @@ -41,7 +41,7 @@ def same_type_children(self, entities=True): """return children entities of the same type as this entity. - + according to the `entities` parameter, return entity objects or the equivalent result set """ @@ -50,7 +50,7 @@ if entities: return [e for e in res if e.e_schema == self.e_schema] return res.filtered_rset(lambda x: x.e_schema == self.e_schema, self.col) - + def iterchildren(self, _done=None): if _done is None: _done = set() @@ -74,7 +74,7 @@ yield entity except AttributeError: pass - + @cached def path(self): """returns the list of eids from the root object to this object""" @@ -96,7 +96,7 @@ path.reverse() return path - + def iterparents(self): def _uptoroot(self): curr = self @@ -110,7 +110,7 @@ def notification_references(self, view): """used to control References field of email send on notification for this entity. `view` is the notification view. - + Should return a list of eids which can be used to generate message ids of previously sent email """ @@ -142,7 +142,7 @@ def children_rql(self): return self.related_rql(self.tree_attribute, self.children_target) - + def __iter__(self): return self.iterchildren() @@ -163,7 +163,7 @@ relation (which implies supporting 'wf_info_for' as well) """ __implements__ = (IWorkflowable,) - + @property def state(self): try: @@ -171,7 +171,7 @@ except IndexError: self.warning('entity %s has no state', self) return None - + @property def displayable_state(self): return self.req._(self.state) @@ -182,7 +182,7 @@ if rset: return rset.get_entity(0, 0) return None - + def wf_transition(self, trname): rset = self.req.execute('Any T, TN WHERE T name TN, T name %(n)s, T transition_of E, E name %(e)s', {'n': trname, 'e': str(self.e_schema)}) @@ -201,7 +201,7 @@ self.req.set_shared_data('trcommentformat', trcommentformat) self.req.execute('SET X in_state S WHERE X eid %(x)s, S eid %(s)s', {'x': self.eid, 's': stateeid}, 'x') - + def can_pass_transition(self, trname): """return the Transition instance if the current user can pass the transition with the given name, else None @@ -215,13 +215,13 @@ for tr in rset.entities(): if tr.may_be_passed(self.eid, stateeid): return tr - + def latest_trinfo(self): """return the latest transition information for this entity""" return self.reverse_wf_info_for[-1] - + # __method methods ######################################################## - + def set_state(self, params=None): """change the entity's state according to a state defined in given parameters, used to be called using __method controler facility @@ -231,9 +231,9 @@ params.get('trcomment'), params.get('trcommentformat')) self.req.set_message(self.req._('__msg state changed')) - + # specific vocabulary methods ############################################# - + @obsolete('use EntityFieldsForm.subject_in_state_vocabulary') def subject_in_state_vocabulary(self, rschema, limit=None): from cubicweb.web.form import EntityFieldsForm @@ -249,7 +249,7 @@ primary_email / use_email scheme """ __implements__ = (IEmailable,) - + def get_email(self): if getattr(self, 'primary_email', None): return self.primary_email[0].address @@ -271,14 +271,14 @@ def as_email_context(self): """returns the dictionary as used by the sendmail controller to build email bodies. - + NOTE: the dictionary keys should match the list returned by the `allowed_massmail_keys` method. """ return dict( (attr, getattr(self, attr)) for attr in self.allowed_massmail_keys() ) - + MI_REL_TRIGGERS = { ('in_state', 'subject'): WorkflowableMixIn, ('primary_email', 'subject'): EmailableMixIn, @@ -312,7 +312,7 @@ if done is None: done = set() super(TreeViewMixIn, self).call(done=done, **kwargs) - + def cell_call(self, row, col=0, vid=None, done=None, **kwargs): done, entity = _done_init(done, self, row, col) if done is None: @@ -341,7 +341,7 @@ self.w(u'
') super(TreePathMixIn, self).call(**kwargs) self.w(u'
') - + def cell_call(self, row, col=0, vid=None, done=None, **kwargs): done, entity = _done_init(done, self, row, col) if done is None: @@ -383,7 +383,7 @@ def in_progress(self): raise NotImplementedError() - + def progress(self): try: return 100. * self.done / self.revised_cost diff -r b7494ff85e16 -r 183da3addf0e common/registerers.py --- a/common/registerers.py Wed Apr 22 09:45:54 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,92 +0,0 @@ -"""This file contains some basic registerers required by application objects -registry to handle registration at startup time. - -A registerer is responsible to tell if an object should be registered according -to the application's schema or to already registered object - -:organization: Logilab -:copyright: 2006-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved. -:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr -""" -__docformat__ = "restructuredtext en" - -from cubicweb.vregistry import registerer, yes_registerer -from cubicweb.cwvreg import use_interfaces - -class priority_registerer(registerer): - """systematically kick previous registered class and register the - wrapped class (based on the fact that directory containing vobjects - are loaded from the most generic to the most specific). - - This is usually for templates or startup views where we want to - keep only the latest in the load path - """ - def do_it_yourself(self, registered): - if registered: - if len(registered) > 1: - self.warning('priority_registerer found more than one registered objects ' - '(registerer monkey patch ?)') - for regobj in registered[:]: - self.kick(registered, regobj) - return self.vobject - - def remove_equivalents(self, registered): - for _obj in registered[:]: - if self.equivalent(_obj): - self.kick(registered, _obj) - break - - def remove_all_equivalents(self, registered): - for _obj in registered[:]: - if _obj is self.vobject: - continue - if self.equivalent(_obj): - self.kick(registered, _obj) - - def equivalent(self, other): - raise NotImplementedError(self, self.vobject) - - -class accepts_registerer(priority_registerer): - """register according to the .accepts attribute of the wrapped - class, which should be a tuple refering some entity's types - - * if no type is defined the application'schema, skip the wrapped - class - * if the class defines a requires attribute, each entity type defined - in the requires list must be in the schema - * if an object previously registered has equivalent .accepts - attribute, kick it out - * register - """ - def do_it_yourself(self, registered): - # if object is accepting interface, we have register it now and - # remove it later if no object is implementing accepted interfaces - if use_interfaces(self.vobject): - return self.vobject - self.remove_equivalents(registered) - return self.vobject - - def equivalent(self, other): - if use_interfaces(self.vobject) != use_interfaces(other): - return False - if getattr(self.vobject, 'require_groups', ()) != getattr(other, 'require_groups', ()): - return False - try: - newaccepts = list(other.accepts) - for etype in self.vobject.accepts: - try: - newaccepts.remove(etype) - except ValueError: - continue - if newaccepts: - other.accepts = tuple(newaccepts) - return False - return True - except AttributeError: - return False - - -__all__ = [cls.__name__ for cls in globals().values() - if isinstance(cls, type) and issubclass(cls, registerer) - and not cls is registerer] diff -r b7494ff85e16 -r 183da3addf0e common/test/unittest_mixins.py --- a/common/test/unittest_mixins.py Wed Apr 22 09:45:54 2009 +0200 +++ b/common/test/unittest_mixins.py Fri Apr 24 19:46:47 2009 +0200 @@ -7,14 +7,14 @@ self.execute('SET X state_of ET WHERE ET name "Bookmark", X eid %(x)s', {'x': s.eid}) es = self.user().wf_state('activated') - self.assertEquals(es.state_of[0].name, 'EUser') + self.assertEquals(es.state_of[0].name, 'CWUser') def test_wf_transition(self): t = self.add_entity('Transition', name=u'deactivate') self.execute('SET X transition_of ET WHERE ET name "Bookmark", X eid %(x)s', {'x': t.eid}) et = self.user().wf_transition('deactivate') - self.assertEquals(et.transition_of[0].name, 'EUser') + self.assertEquals(et.transition_of[0].name, 'CWUser') def test_change_state(self): user = self.user() diff -r b7494ff85e16 -r 183da3addf0e common/test/unittest_rest.py --- a/common/test/unittest_rest.py Wed Apr 22 09:45:54 2009 +0200 +++ b/common/test/unittest_rest.py Fri Apr 24 19:46:47 2009 +0200 @@ -5,7 +5,7 @@ class RestTC(EnvBasedTC): def context(self): - return self.execute('EUser X WHERE X login "admin"').get_entity(0, 0) + return self.execute('CWUser X WHERE X login "admin"').get_entity(0, 0) def test_eid_role(self): context = self.context() diff -r b7494ff85e16 -r 183da3addf0e cwconfig.py --- a/cwconfig.py Wed Apr 22 09:45:54 2009 +0200 +++ b/cwconfig.py Fri Apr 24 19:46:47 2009 +0200 @@ -64,44 +64,44 @@ 'default': 'UTF-8', 'help': _('user interface encoding'), 'group': 'ui', 'sitewide': True, - }), + }), ('language', {'type' : 'string', 'default': 'en', 'vocabulary': Method('available_languages'), 'help': _('language of the user interface'), - 'group': 'ui', + 'group': 'ui', }), ('date-format', {'type' : 'string', 'default': '%Y/%m/%d', 'help': _('how to format date in the ui ("man strftime" for format description)'), - 'group': 'ui', + 'group': 'ui', }), ('datetime-format', {'type' : 'string', 'default': '%Y/%m/%d %H:%M', 'help': _('how to format date and time in the ui ("man strftime" for format description)'), - 'group': 'ui', + 'group': 'ui', }), ('time-format', {'type' : 'string', 'default': '%H:%M', 'help': _('how to format time in the ui ("man strftime" for format description)'), - 'group': 'ui', + 'group': 'ui', }), ('float-format', {'type' : 'string', 'default': '%.3f', 'help': _('how to format float numbers in the ui'), - 'group': 'ui', + 'group': 'ui', }), ('default-text-format', {'type' : 'choice', 'choices': ('text/plain', 'text/rest', 'text/html'), 'default': 'text/html', # use fckeditor in the web ui 'help': _('default text format for rich text fields.'), - 'group': 'ui', + 'group': 'ui', }), ('short-line-size', {'type' : 'int', @@ -114,7 +114,7 @@ def register_persistent_options(options): global PERSISTENT_OPTIONS PERSISTENT_OPTIONS = merge_options(PERSISTENT_OPTIONS + options) - + CFGTYPE2ETYPE_MAP = { 'string': 'String', 'choice': 'String', @@ -122,7 +122,7 @@ 'int': 'Int', 'float' : 'Float', } - + class CubicWebNoAppConfiguration(ConfigurationMixIn): """base class for cubicweb configuration without a specific instance directory """ @@ -198,7 +198,7 @@ }), ) # static and class methods used to get application independant resources ## - + @staticmethod def cubicweb_version(): """return installed cubicweb version""" @@ -207,7 +207,7 @@ version = __pkginfo__.numversion assert len(version) == 3, version return Version(version) - + @staticmethod def persistent_options_configuration(): return Configuration(options=PERSISTENT_OPTIONS) @@ -220,7 +220,7 @@ if cls.mode in ('dev', 'test') and not os.environ.get('APYCOT_ROOT'): return join(CW_SOFTWARE_ROOT, 'web') return cls.cube_dir('shared') - + @classmethod def i18n_lib_dir(cls): """return application's i18n directory""" @@ -236,7 +236,7 @@ if isdir(join(directory, cube)) and not cube in ('CVS', '.svn', 'shared', '.hg'): cubes.add(cube) return sorted(cubes) - + @classmethod def cubes_search_path(cls): """return the path of directories where cubes should be searched""" @@ -251,7 +251,7 @@ if not cls.CUBES_DIR in path: path.append(cls.CUBES_DIR) return path - + @classmethod def cube_dir(cls, cube): """return the cube directory for the given cube id, @@ -267,7 +267,7 @@ def cube_migration_scripts_dir(cls, cube): """cube migration scripts directory""" return join(cls.cube_dir(cube), 'migration') - + @classmethod def cube_pkginfo(cls, cube): """return the information module for the given cube""" @@ -280,7 +280,7 @@ @classmethod def cube_version(cls, cube): - """return the version of the cube located in the given directory + """return the version of the cube located in the given directory """ from logilab.common.changelog import Version version = cls.cube_pkginfo(cube).numversion @@ -343,7 +343,7 @@ except KeyError: continue return tuple(reversed(cubes)) - + @classmethod def cls_adjust_sys_path(cls): """update python path if necessary""" @@ -381,7 +381,7 @@ except: cls.exception('while loading cube %s', cube) else: - cls.warning('no __init__ file in cube %s', cube) + cls.warning('no __init__ file in cube %s', cube) @classmethod def init_available_cubes(cls): @@ -393,7 +393,7 @@ __import__('cubes.%s' % cube) except Exception, ex: cls.warning("can't init cube %s: %s", cube, ex) - + cubicweb_vobject_path = set(['entities']) cube_vobject_path = set(['entities']) @@ -441,17 +441,17 @@ elif exists(path + '.py'): vregpath.append(path + '.py') return vregpath - + def __init__(self): ConfigurationMixIn.__init__(self) self.adjust_sys_path() self.load_defaults() - self.translations = {} + self.translations = {} def adjust_sys_path(self): self.cls_adjust_sys_path() - - def init_log(self, logthreshold=None, debug=False, + + def init_log(self, logthreshold=None, debug=False, logfile=None, syslog=False): """init the log service""" if logthreshold is None: @@ -468,7 +468,7 @@ for application objects. By default return nothing in NoApp config. """ return [] - + def eproperty_definitions(self): cfg = self.persistent_options_configuration() for section, options in cfg.options_by_section(): @@ -481,7 +481,7 @@ 'help': optdict['help'], 'sitewide': optdict.get('sitewide', False)} yield key, pdef - + def map_option(self, optdict): try: vocab = optdict['choices'] @@ -491,10 +491,10 @@ vocab = getattr(self, vocab.method, ()) return CFGTYPE2ETYPE_MAP[optdict['type']], vocab - + class CubicWebConfiguration(CubicWebNoAppConfiguration): """base class for cubicweb server and web configurations""" - + INSTANCE_DATA_DIR = None if CubicWebNoAppConfiguration.mode == 'test': root = os.environ['APYCOT_ROOT'] @@ -517,7 +517,7 @@ set_language = True # set this to true to avoid false error message while creating an application creating = False - + options = CubicWebNoAppConfiguration.options + ( ('log-file', {'type' : 'string', @@ -540,7 +540,7 @@ }), ('sender-name', {'type' : 'string', - 'default': Method('default_application_id'), + 'default': Method('default_application_id'), 'help': 'name used as HELO name for outgoing emails from the \ repository.', 'group': 'email', 'inputlevel': 2, @@ -558,7 +558,7 @@ def runtime_dir(cls): """run time directory for pid file...""" return env_path('CW_RUNTIME', cls.RUNTIME_DIR, 'run time') - + @classmethod def registry_dir(cls): """return the control directory""" @@ -570,7 +570,7 @@ return env_path('CW_INSTANCE_DATA', cls.INSTANCE_DATA_DIR or cls.REGISTRY_DIR, 'additional data') - + @classmethod def migration_scripts_dir(cls): """cubicweb migration scripts directory""" @@ -583,7 +583,7 @@ config = config or guess_configuration(cls.application_home(appid)) configcls = configuration_cls(config) return configcls(appid) - + @classmethod def possible_configurations(cls, appid): """return the name of possible configurations for the given @@ -591,7 +591,7 @@ """ home = cls.application_home(appid) return possible_configurations(home) - + @classmethod def application_home(cls, appid): """return the home directory of the application with the given @@ -610,9 +610,9 @@ def accept_mode(cls, mode): #assert mode in cls.MODES, mode return mode in cls.MCOMPAT[cls.name] - + # default configuration methods ########################################### - + def default_application_id(self): """return the application identifier, useful for option which need this as default value @@ -634,13 +634,13 @@ i += 1 return path return '/var/log/cubicweb/%s-%s.log' % (self.appid, self.name) - + def default_pid_file(self): """return default path to the pid file of the application'server""" return join(self.runtime_dir(), '%s-%s.pid' % (self.appid, self.name)) - + # instance methods used to get application specific resources ############# - + def __init__(self, appid): self.appid = appid CubicWebNoAppConfiguration.__init__(self) @@ -658,11 +658,11 @@ @property def apphome(self): return join(self.registry_dir(), self.appid) - + @property def appdatahome(self): return join(self.instance_data_dir(), self.appid) - + def init_cubes(self, cubes): assert self._cubes is None self._cubes = self.reorder_cubes(cubes) @@ -675,7 +675,7 @@ self.load_file_configuration(self.main_config_file()) # configuration initialization hook self.load_configuration() - + def cubes(self): """return the list of cubes used by this instance @@ -684,7 +684,7 @@ """ assert self._cubes is not None return self._cubes - + def cubes_path(self): """return the list of path to cubes used by this instance, from outer most to inner most cubes @@ -696,11 +696,11 @@ if not isinstance(cubes, list): cubes = list(cubes) self._cubes = self.reorder_cubes(list(self._cubes) + cubes) - + def main_config_file(self): """return application's control configuration file""" return join(self.apphome, '%s.conf' % self.name) - + def save(self): """write down current configuration""" self.generate_config(open(self.main_config_file(), 'w')) @@ -713,7 +713,7 @@ version = self.cube_version(pkg) infos.append('%s-%s' % (pkg, version)) return md5.new(';'.join(infos)).hexdigest() - + def load_site_cubicweb(self): """load (web?) application's specific site_cubicweb file""" for path in reversed([self.apphome] + self.cubes_path()): @@ -727,7 +727,7 @@ self._load_site_cubicweb(sitefile) self._site_loaded.add(sitefile) self.warning('site_erudi.py is deprecated, should be renamed to site_cubicweb.py') - + def _load_site_cubicweb(self, sitefile): context = {} execfile(sitefile, context, context) @@ -736,14 +736,14 @@ if context.get('options'): self.register_options(context['options']) self.load_defaults() - + def load_configuration(self): """load application's configuration files""" super(CubicWebConfiguration, self).load_configuration() if self.apphome and self.set_language: # init gettext self._set_language() - + def init_log(self, logthreshold=None, debug=False, force=False): """init the log service""" if not force and hasattr(self, '_logging_initialized'): @@ -769,7 +769,7 @@ lang = path.split(os.sep)[-3] if lang != 'en': yield lang - + def _set_language(self): """set language for gettext""" from gettext import translation @@ -781,8 +781,8 @@ self.translations[language] = tr.ugettext except (ImportError, AttributeError, IOError): self.exception('localisation support error for language %s', - language) - + language) + def vregistry_path(self): """return a list of files or directories where the registry will look for application objects @@ -796,7 +796,7 @@ if not 'all' in sources: print 'warning: ignoring specified sources, requires a repository '\ 'configuration' - + def migration_handler(self): """return a migration handler instance""" from cubicweb.common.migration import MigrationHelper @@ -814,7 +814,7 @@ return i18n.compile_i18n_catalogs(sourcedirs, i18ndir, langs) set_log_methods(CubicWebConfiguration, logging.getLogger('cubicweb.configuration')) - + # alias to get a configuration instance from an application id -application_configuration = CubicWebConfiguration.config_for +application_configuration = CubicWebConfiguration.config_for diff -r b7494ff85e16 -r 183da3addf0e cwctl.py --- a/cwctl.py Wed Apr 22 09:45:54 2009 +0200 +++ b/cwctl.py Fri Apr 24 19:46:47 2009 +0200 @@ -1,6 +1,6 @@ """%%prog %s [options] %s -CubicWeb main applications controller. +CubicWeb main applications controller. %s""" import sys @@ -12,7 +12,7 @@ from cubicweb import ConfigurationError, ExecutionError, BadCommandUsage from cubicweb.cwconfig import CubicWebConfiguration as cwcfg, CONFIGURATIONS from cubicweb.toolsutils import Command, main_run, rm, create_dir, confirm - + def wait_process_end(pid, maxtry=10, waittime=1): """wait for a process to actually die""" import signal @@ -42,13 +42,13 @@ modes.append('web ui') break return modes - - + + class ApplicationCommand(Command): """base class for command taking 0 to n application id as arguments (0 meaning all registered applications) """ - arguments = '[...]' + arguments = '[...]' options = ( ("force", {'short': 'f', 'action' : 'store_true', @@ -58,7 +58,7 @@ ), ) actionverb = None - + def ordered_instances(self): """return instances in the order in which they should be started, considering $REGISTRY_DIR/startorder file if it exists (useful when @@ -81,7 +81,7 @@ else: allinstances = _allinstances return allinstances - + def run(self, args): """run the _method on each argument (a list of application identifiers) @@ -96,7 +96,7 @@ else: askconfirm = False self.run_args(args, askconfirm) - + def run_args(self, args, askconfirm): for appid in args: if askconfirm: @@ -104,7 +104,7 @@ if not confirm('%s application %r ?' % (self.name, appid)): continue self.run_arg(appid) - + def run_arg(self, appid): cmdmeth = getattr(self, '%s_application' % self.name) try: @@ -143,7 +143,7 @@ sys.exit(status) else: self.run_arg(appid) - + # base commands ############################################################### class ListCommand(Command): @@ -155,10 +155,10 @@ name = 'list' options = ( ('verbose', - {'short': 'v', 'action' : 'store_true', - 'help': "display more information."}), + {'short': 'v', 'action' : 'store_true', + 'help': "display more information."}), ) - + def run(self, args): """run the command with its specific arguments""" if args: @@ -174,7 +174,7 @@ if not line: continue print ' ', line - print + print try: cubesdir = pathsep.join(cwcfg.cubes_search_path()) namesize = max(len(x) for x in cwcfg.available_cubes()) @@ -219,7 +219,7 @@ print '* %s (%s)' % (appid, ', '.join(modes)) try: config = cwcfg.config_for(appid, modes[0]) - except Exception, exc: + except Exception, exc: print ' (BROKEN application, %s)' % exc continue else: @@ -261,7 +261,7 @@ } ), ) - + def run(self, args): """run the command with its specific arguments""" from logilab.common.textutils import get_csv @@ -323,14 +323,14 @@ print helper.postcreate() - + class DeleteApplicationCommand(Command): """Delete an application. Will remove application's files and unregister it. """ name = 'delete' arguments = '' - + options = () def run(self, args): @@ -361,7 +361,7 @@ class StartApplicationCommand(ApplicationCommand): """Start the given applications. If no application is given, start them all. - + ... identifiers of the applications to start. If no application is given, start them all. @@ -414,19 +414,19 @@ class StopApplicationCommand(ApplicationCommand): """Stop the given applications. - + ... identifiers of the applications to stop. If no application is given, stop them all. """ name = 'stop' actionverb = 'stopped' - + def ordered_instances(self): instances = super(StopApplicationCommand, self).ordered_instances() instances.reverse() return instances - + def stop_application(self, appid): """stop the application's server""" config = cwcfg.config_for(appid) @@ -460,12 +460,12 @@ # already removed by twistd pass print 'application %s stopped' % appid - + class RestartApplicationCommand(StartApplicationCommand, StopApplicationCommand): """Restart the given applications. - + ... identifiers of the applications to restart. If no application is given, restart them all. @@ -497,30 +497,30 @@ status = system('%s %s' % (forkcmd, appid)) if status: sys.exit(status) - + def restart_application(self, appid): self.stop_application(appid) if self.start_application(appid): print 'application %s %s' % (appid, self.actionverb) - + class ReloadConfigurationCommand(RestartApplicationCommand): """Reload the given applications. This command is equivalent to a restart for now. - + ... identifiers of the applications to reload. If no application is given, reload them all. """ name = 'reload' - + def reload_application(self, appid): self.restart_application(appid) - + class StatusCommand(ApplicationCommand): """Display status information about the given applications. - + ... identifiers of the applications to status. If no application is given, get status information about all registered applications. @@ -576,7 +576,7 @@ {'short': 'e', 'type' : 'string', 'metavar': 'X.Y.Z', 'default': None, 'help': 'force migration from the indicated cubicweb version.'}), - + ('fs-only', {'short': 's', 'action' : 'store_true', 'default': False, @@ -586,13 +586,13 @@ {'short': 'n', 'action' : 'store_true', 'default': False, 'help': 'don\'t try to stop application before migration and to restart it after.'}), - + ('verbosity', {'short': 'v', 'type' : 'int', 'metavar': '<0..2>', 'default': 1, 'help': "0: no confirmation, 1: only main commands confirmed, 2 ask \ for everything."}), - + ('backup-db', {'short': 'b', 'type' : 'yn', 'metavar': '', 'default': None, @@ -613,11 +613,9 @@ def ordered_instances(self): # need this since mro return StopApplicationCommand implementation return ApplicationCommand.ordered_instances(self) - + def upgrade_application(self, appid): from logilab.common.changelog import Version - if not (cwcfg.mode == 'dev' or self.config.nostartstop): - self.stop_application(appid) config = cwcfg.config_for(appid) config.creating = True # notice we're not starting the server config.verbosity = self.config.verbosity @@ -648,7 +646,7 @@ continue if installedversion > applversion: toupgrade.append( (cube, applversion, installedversion) ) - cubicwebversion = config.cubicweb_version() + cubicwebversion = config.cubicweb_version() if self.config.force_cubicweb_version: applcubicwebversion = Version(self.config.force_cubicweb_version) vcconf['cubicweb'] = applcubicwebversion @@ -661,6 +659,9 @@ return for cube, fromversion, toversion in toupgrade: print '**** %s migration %s -> %s' % (cube, fromversion, toversion) + # only stop once we're sure we have something to do + if not (cwcfg.mode == 'dev' or self.config.nostartstop): + self.stop_application(appid) # run cubicweb/componants migration scripts mih.migrate(vcconf, reversed(toupgrade), self.config) # rewrite main configuration file @@ -706,7 +707,7 @@ 'help': 'only connect to the system source when the instance is ' 'using multiple sources. You can\'t use this option and the ' '--ext-sources option at the same time.'}), - + ('ext-sources', {'short': 'E', 'type' : 'csv', 'metavar': '', 'default': None, @@ -715,7 +716,7 @@ will connect to all defined sources. If 'migration' is given, appropriate \ sources for migration will be automatically selected.", }), - + ) def run(self, args): appid = pop_arg(args, 99, msg="No application specified !") @@ -733,12 +734,12 @@ mih.scripts_session(args) else: mih.interactive_shell() - mih.shutdown() + mih.shutdown() class RecompileApplicationCatalogsCommand(ApplicationCommand): """Recompile i18n catalogs for applications. - + ... identifiers of the applications to consider. If no application is given, recompile for all registered applications. @@ -772,7 +773,7 @@ """list available instances, useful for bash completion.""" name = 'listinstances' hidden = True - + def run(self, args): """run the command with its specific arguments""" regdir = cwcfg.registry_dir() @@ -784,7 +785,7 @@ """list available componants, useful for bash completion.""" name = 'listcubes' hidden = True - + def run(self, args): """run the command with its specific arguments""" for cube in cwcfg.available_cubes(): @@ -804,7 +805,7 @@ ListInstancesCommand, ListCubesCommand, )) - + def run(args): """command line tool""" cwcfg.load_cwctl_plugins() diff -r b7494ff85e16 -r 183da3addf0e cwvreg.py --- a/cwvreg.py Wed Apr 22 09:45:54 2009 +0200 +++ b/cwvreg.py Fri Apr 24 19:46:47 2009 +0200 @@ -7,7 +7,6 @@ __docformat__ = "restructuredtext en" from logilab.common.decorators import cached, clear_cache -from logilab.common.interface import extend from rql import RQLHelper @@ -23,7 +22,7 @@ from cubicweb.selectors import implements try: # XXX deprecated - return sorted(obj.accepts_interfaces) + return sorted(obj.accepts_interfaces) except AttributeError: try: impl = obj.__select__.search_selector(implements) @@ -39,7 +38,7 @@ class CubicWebRegistry(VRegistry): """extend the generic VRegistry with some cubicweb specific stuff""" - + def __init__(self, config, debug=None, initlog=True): if initlog: # first init log service @@ -48,7 +47,7 @@ self.schema = None self.reset() self.initialized = False - + def items(self): return [item for item in self._registries.items() if not item[0] in ('propertydefs', 'propertyvalues')] @@ -56,7 +55,7 @@ def values(self): return [value for key, value in self._registries.items() if not key in ('propertydefs', 'propertyvalues')] - + def reset(self): self._registries = {} self._lastmodifs = {} @@ -68,14 +67,14 @@ self._registries['propertyvalues'] = self.eprop_values = {} for key, propdef in self.config.eproperty_definitions(): self.register_property(key, **propdef) - + def set_schema(self, schema): """set application'schema and load application objects""" self.schema = schema clear_cache(self, 'rqlhelper') # now we can load application's web objects self.register_objects(self.config.vregistry_path()) - + def update_schema(self, schema): """update .schema attribute on registered objects, necessary for some tests @@ -110,7 +109,7 @@ ifaces = use_interfaces(obj) if ifaces: self._needs_iface[obj] = ifaces - + def register_objects(self, path, force_reload=None): """overriden to remove objects requiring a missing interface""" if super(CubicWebRegistry, self).register_objects(path, force_reload): @@ -147,7 +146,7 @@ for appobjects in objects.itervalues(): for appobject in appobjects: appobject.vreg_initialization_completed() - + @cached def etype_class(self, etype): """return an entity class for the given entity type. @@ -172,19 +171,14 @@ # no entity class for any of the ancestors, fallback to the default # one cls = self.select(self.registry_objects('etypes', 'Any'), etype) - # add class itself to the list of implemented interfaces, as well as the - # Any entity class so we can select according to class using the - # `implements` selector - extend(cls, cls) - extend(cls, self.etype_class('Any')) return cls - + def render(self, registry, oid, req, **context): """select an object in a given registry and render it - registry: the registry's name - oid : the view to call - - req : the HTTP request + - req : the HTTP request """ objclss = self.registry_objects(registry, oid) try: @@ -193,7 +187,7 @@ rset = None selected = self.select(objclss, req, rset, **context) return selected.dispatch(**context) - + def main_template(self, req, oid='main-template', **context): """display query by calling the given template (default to main), and returning the output as a string instead of requiring the [w]rite @@ -213,17 +207,17 @@ return [x for x in sorted(self.possible_objects(registry, *args, **kwargs), key=lambda x: x.propval('order')) if x.propval('visible')] - + def possible_actions(self, req, rset, **kwargs): if rset is None: - actions = self.possible_vobjects('actions', req, rset) + actions = self.possible_vobjects('actions', req, rset, **kwargs) else: - actions = rset.possible_actions() # cached implementation + actions = rset.possible_actions(**kwargs) # cached implementation result = {} for action in actions: result.setdefault(action.category, []).append(action) return result - + def possible_views(self, req, rset, **kwargs): """return an iterator on possible views for this result set @@ -241,7 +235,7 @@ except Exception: self.exception('error while trying to list possible %s views for %s', vid, rset) - + def select_box(self, oid, *args, **kwargs): """return the most specific view according to the result set""" try: @@ -255,7 +249,7 @@ return self.select_object('actions', oid, *args, **kwargs) except NoSelectableObject: return - + def select_component(self, cid, *args, **kwargs): """return the most specific component according to the result set""" try: @@ -268,7 +262,7 @@ views = self.registry_objects('views', __vid) return self.select(views, req, rset, **kwargs) - + # properties handling ##################################################### def user_property_keys(self, withsitewide=False): @@ -282,7 +276,7 @@ """register a given property""" properties = self._registries['propertydefs'] assert type in YAMS_TO_PY - properties[key] = {'type': type, 'vocabulary': vocabulary, + properties[key] = {'type': type, 'vocabulary': vocabulary, 'default': default, 'help': help, 'sitewide': sitewide} @@ -300,7 +294,7 @@ 'default': None, 'vocabulary': None, 'help': _('%s software version of the database') % soft} raise UnknownProperty('unregistered property %r' % key) - + def property_value(self, key): try: return self._registries['propertyvalues'][key] @@ -323,7 +317,7 @@ if not value in vocab: raise ValueError(_('unauthorized value')) return value - + def init_properties(self, propvalues): """init the property values registry using the given set of couple (key, value) """ @@ -383,7 +377,7 @@ vobject.schema = self.schema vobject.config = self.config return super(MulCnxCubicWebRegistry, self).select(vobjects, *args, **kwargs) - + from datetime import datetime, date, time, timedelta YAMS_TO_PY = { diff -r b7494ff85e16 -r 183da3addf0e dbapi.py --- a/dbapi.py Wed Apr 22 09:45:54 2009 +0200 +++ b/dbapi.py Fri Apr 24 19:46:47 2009 +0200 @@ -430,9 +430,9 @@ eid, login, groups, properties = self._repo.user_info(self.sessionid, props) if req is None: req = self.request() - rset = req.eid_rset(eid, 'EUser') - user = self.vreg.etype_class('EUser')(req, rset, row=0, groups=groups, - properties=properties) + rset = req.eid_rset(eid, 'CWUser') + user = self.vreg.etype_class('CWUser')(req, rset, row=0, groups=groups, + properties=properties) user['login'] = login # cache login return user diff -r b7494ff85e16 -r 183da3addf0e debian.hardy/compat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/debian.hardy/compat Fri Apr 24 19:46:47 2009 +0200 @@ -0,0 +1,1 @@ +5 diff -r b7494ff85e16 -r 183da3addf0e debian.hardy/control --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/debian.hardy/control Fri Apr 24 19:46:47 2009 +0200 @@ -0,0 +1,131 @@ +Source: cubicweb +Section: web +Priority: optional +Maintainer: Logilab S.A. +Uploaders: Sylvain Thenault , + Julien Jehannet , + Aurélien Campéas +Build-Depends: debhelper (>= 5), python-dev (>=2.4), python-central (>= 0.5) +Standards-Version: 3.8.0 +Homepage: http://www.cubicweb.org +XS-Python-Version: >= 2.4, << 2.6 + + +Package: cubicweb +Architecture: all +XB-Python-Version: ${python:Versions} +Depends: ${python:Depends}, cubicweb-server (= ${source:Version}), cubicweb-twisted (= ${source:Version}), cubicweb-client (= ${source:Version}) +XB-Recommends: (postgresql, postgresql-plpython, postgresql-contrib) | mysql | sqlite3 +Recommends: postgresql | mysql | sqlite3 +Description: the complete CubicWeb framework + CubicWeb is a semantic web application framework. + . + This package will install all the components you need to run cubicweb on + a single machine. You can also deploy cubicweb by running the different + process on different computers, in which case you need to install the + corresponding packages on the different hosts. + + +Package: cubicweb-server +Architecture: all +XB-Python-Version: ${python:Versions} +Conflicts: cubicweb-multisources +Replaces: cubicweb-multisources +Provides: cubicweb-multisources +Depends: ${python:Depends}, cubicweb-common (= ${source:Version}), cubicweb-ctl (= ${source:Version}), python-indexer (>= 0.6.1), python-psycopg2 | python-mysqldb | python-pysqlite2 +Recommends: pyro, cubicweb-documentation (= ${source:Version}) +Description: server part of the CubicWeb framework + CubicWeb is a semantic web application framework. + . + This package provides the repository server part of the system. + . + This package provides the repository server part of the library and + necessary shared data files such as the schema library. + + +Package: cubicweb-twisted +Architecture: all +XB-Python-Version: ${python:Versions} +Provides: cubicweb-web-frontend +Depends: ${python:Depends}, cubicweb-web (= ${source:Version}), cubicweb-ctl (= ${source:Version}), python-twisted-web2 +Recommends: pyro, cubicweb-documentation (= ${source:Version}) +Description: twisted-based web interface for the CubicWeb framework + CubicWeb is a semantic web application framework. + . + This package provides a twisted based HTTP server to serve + the adaptative web interface (see cubicweb-web package). + . + This package provides only the twisted server part of the library. + + +Package: cubicweb-web +Architecture: all +XB-Python-Version: ${python:Versions} +Depends: ${python:Depends}, cubicweb-common (= ${source:Version}), python-docutils, python-vobject, python-elementtree +Recommends: fckeditor +Description: web interface library for the CubicWeb framework + CubicWeb is a semantic web application framework. + . + This package provides an adaptative web interface to the CubicWeb server. + Install the cubicweb-twisted package to serve this interface via HTTP. + . + This package provides the web interface part of the library and + necessary shared data files such as defaut views, images... + + +Package: cubicweb-common +Architecture: all +XB-Python-Version: ${python:Versions} +Depends: ${python:Depends}, python-logilab-mtconverter (>= 0.6.0), python-simpletal (>= 4.0), graphviz, gettext, python-lxml, python-logilab-common (>= 0.38.1), python-yams (>= 0.20.2), python-rql (>= 0.20.2), python-simplejson (>= 1.3) +Recommends: python-psyco +Conflicts: cubicweb-core +Replaces: cubicweb-core +Description: common library for the CubicWeb framework + CubicWeb is a semantic web application framework. + . + This package provides the common parts of the library used by both server + code and web application code. + + +Package: cubicweb-ctl +Architecture: all +XB-Python-Version: ${python:Versions} +Depends: ${python:Depends}, cubicweb-common (= ${source:Version}) +Description: tool to manage the CubicWeb framework + CubicWeb is a semantic web application framework. + . + This package provides a control script to manage (create, upgrade, start, + stop, etc) CubicWeb applications. It also include the init.d script + to automatically start and stop CubicWeb applications on boot or shutdown. + + +Package: cubicweb-client +Architecture: all +XB-Python-Version: ${python:Versions} +Depends: ${python:Depends}, cubicweb-ctl (= ${source:Version}), pyro +Description: RQL command line client for the CubicWeb framework + CubicWeb is a semantic web application framework. + . + This package provides a RQL (Relation Query Language) command line client using + pyro to connect to a repository server. + + +Package: cubicweb-dev +Architecture: all +XB-Python-Version: ${python:Versions} +Depends: ${python:Depends}, cubicweb-server (= ${source:Version}), cubicweb-web (= ${source:Version}), python-pysqlite2 +Suggests: w3c-dtd-xhtml +Description: tests suite and development tools for the CubicWeb framework + CubicWeb is a semantic web application framework. + . + This package provides the CubicWeb tests suite and some development tools + helping in the creation of application. + + +Package: cubicweb-documentation +Architecture: all +Recommends: doc-base +Description: documentation for the CubicWeb framework + CubicWeb is a semantic web application framework. + . + This package provides the system's documentation. diff -r b7494ff85e16 -r 183da3addf0e debian.hardy/rules --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/debian.hardy/rules Fri Apr 24 19:46:47 2009 +0200 @@ -0,0 +1,78 @@ +#!/usr/bin/make -f +# Sample debian/rules that uses debhelper. +# GNU copyright 1997 to 1999 by Joey Hess. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +PY_VERSION:=$(shell pyversions -d) + +build: build-stamp +build-stamp: + dh_testdir + # XXX doesn't work if logilab-doctools, logilab-xml are not in build depends + # and I can't get pbuilder find them in its chroot :( + # cd doc && make + # FIXME cleanup and use sphinx-build as build-depends ? + python setup.py build + touch build-stamp + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + rm -rf build + #rm -rf debian/cubicweb-*/ + find . -name "*.pyc" -delete + rm -f $(basename $(wildcard debian/*.in)) + dh_clean + +install: build $(basename $(wildcard debian/*.in)) + dh_testdir + dh_testroot + dh_clean + dh_installdirs + + #python setup.py install_lib --no-compile --install-dir=debian/cubicweb-common/usr/lib/python2.4/site-packages/ + python setup.py -q install --no-compile --prefix=debian/tmp/usr + + # Put all the python library and data in cubicweb-common + # and scripts in cubicweb-server + dh_install -vi + #dh_lintian XXX not before debhelper 7 + + # Remove unittests directory (should be available in cubicweb-dev only) + rm -rf debian/cubicweb-server/usr/lib/${PY_VERSION}/site-packages/cubicweb/server/test + rm -rf debian/cubicweb-server/usr/lib/${PY_VERSION}/site-packages/cubicweb/sobjects/test + rm -rf debian/cubicweb-web/usr/lib/${PY_VERSION}/site-packages/cubicweb/web/test + rm -rf debian/cubicweb-common/usr/lib/${PY_VERSION}/site-packages/cubicweb/common/test + + # cubes directory must be managed as a valid python module + touch debian/cubicweb-common/usr/share/cubicweb/cubes/__init__.py + +%: %.in + sed "s/PY_VERSION/${PY_VERSION}/g" < $< > $@ + +# Build architecture-independent files here. +binary-indep: build install + dh_testdir + dh_testroot -i + dh_pycentral -i + dh_installinit -i -n --name cubicweb -u"defaults 99" + dh_installlogrotate -i + dh_installdocs -i -A README + dh_installman -i + dh_installchangelogs -i + dh_link -i + dh_compress -i -X.py -X.ini -X.xml + dh_fixperms -i + dh_installdeb -i + dh_gencontrol -i + dh_md5sums -i + dh_builddeb -i + +binary-arch: + +binary: binary-indep +.PHONY: build clean binary binary-indep binary-arch + diff -r b7494ff85e16 -r 183da3addf0e debian/cubicweb-ctl.postinst --- a/debian/cubicweb-ctl.postinst Wed Apr 22 09:45:54 2009 +0200 +++ b/debian/cubicweb-ctl.postinst Fri Apr 24 19:46:47 2009 +0200 @@ -13,25 +13,29 @@ if [ "$1" = configure ]; then # XXX bw compat: erudi -> cubicweb migration if [ -e "/etc/erudi.d/" ]; then - mv /etc/erudi.d/* /etc/cubicweb.d/ - echo 'moved /etc/erudi.d/* to /etc/cubicweb.d/' - sed -i s/ginco/cubicweb/g /etc/*/*.py - sed -i s/erudi/cubicweb/ */*.conf + mv /etc/erudi.d/* /etc/cubicweb.d/ && ( + echo 'moved /etc/erudi.d/* to /etc/cubicweb.d/' + sed -i s/ginco/cubicweb/g /etc/*/*.py + sed -i s/erudi/cubicweb/ */*.conf + ) || true # empty dir fi if [ -e "/var/log/erudi/" ]; then - mv /var/log/erudi/* /var/log/cubicweb/ - echo 'moved /var/log/erudi/* to /var/log/cubicweb/' + mv /var/log/erudi/* /var/log/cubicweb/ && ( + echo 'moved /var/log/erudi/* to /var/log/cubicweb/' + ) || true # empty dir fi if [ -e "/var/lib/erudi/backup" ]; then - mv /var/lib/erudi/backup/* /var/lib/cubicweb/backup/ - echo 'moved /var/lib/erudi/backup/* to /var/lib/cubicweb/backup/' + mv /var/lib/erudi/backup/* /var/lib/cubicweb/backup/ && ( + echo 'moved /var/lib/erudi/backup/* to /var/lib/cubicweb/backup/' + ) || true # empty dir fi if [ -e "/var/lib/erudi/instances" ]; then - mv /var/lib/erudi/instances/* /var/lib/cubicweb/instances/ - echo 'moved /var/lib/erudi/instances/* to /var/lib/cubicweb/instances/' + mv /var/lib/erudi/instances/* /var/lib/cubicweb/instances/ && ( + echo 'moved /var/lib/erudi/instances/* to /var/lib/cubicweb/instances/' + ) || true # empty dir fi fi - + #DEBHELPER# - + exit 0 diff -r b7494ff85e16 -r 183da3addf0e devtools/_apptest.py --- a/devtools/_apptest.py Wed Apr 22 09:45:54 2009 +0200 +++ b/devtools/_apptest.py Fri Apr 24 19:46:47 2009 +0200 @@ -21,10 +21,10 @@ from cubicweb.devtools import ApptestConfiguration, init_test_database from cubicweb.devtools.fake import FakeRequest -SYSTEM_ENTITIES = ('EGroup', 'EUser', - 'EFRDef', 'ENFRDef', - 'EConstraint', 'EConstraintType', 'EProperty', - 'EEType', 'ERType', +SYSTEM_ENTITIES = ('CWGroup', 'CWUser', + 'CWAttribute', 'CWRelation', + 'CWConstraint', 'CWConstraintType', 'CWProperty', + 'CWEType', 'CWRType', 'State', 'Transition', 'TrInfo', 'RQLExpression', ) @@ -50,7 +50,7 @@ ) def unprotected_entities(app_schema, strict=False): - """returned a Set of each non final entity type, excluding EGroup, and EUser... + """returned a Set of each non final entity type, excluding CWGroup, and CWUser... """ if strict: protected_entities = yams.schema.BASE_TYPES @@ -90,7 +90,7 @@ schema = self.vreg.schema # else we may run into problems since email address are ususally share in app tests # XXX should not be necessary anymore - schema.rschema('primary_email').set_rproperty('EUser', 'EmailAddress', 'composite', False) + schema.rschema('primary_email').set_rproperty('CWUser', 'EmailAddress', 'composite', False) self.deletable_entities = unprotected_entities(schema) def restore_database(self): @@ -119,7 +119,7 @@ def create_user(self, login, groups=('users',), req=None): req = req or self.create_request() cursor = self._orig_cnx.cursor(req) - rset = cursor.execute('INSERT EUser X: X login %(login)s, X upassword %(passwd)s,' + rset = cursor.execute('INSERT CWUser X: X login %(login)s, X upassword %(passwd)s,' 'X in_state S WHERE S name "activated"', {'login': unicode(login), 'passwd': login.encode('utf8')}) user = rset.get_entity(0, 0) diff -r b7494ff85e16 -r 183da3addf0e devtools/apptest.py --- a/devtools/apptest.py Wed Apr 22 09:45:54 2009 +0200 +++ b/devtools/apptest.py Fri Apr 24 19:46:47 2009 +0200 @@ -14,6 +14,8 @@ from logilab.common.pytest import nocoverage from logilab.common.umessage import message_from_string +from logilab.common.deprecation import deprecated_function + from cubicweb.devtools import init_test_database, TestServerConfiguration, ApptestConfiguration from cubicweb.devtools._apptest import TestEnvironment from cubicweb.devtools.fake import FakeRequest @@ -218,6 +220,13 @@ def pactions(self, req, rset, skipcategories=('addrelated', 'siteactions', 'useractions')): return [(a.id, a.__class__) for a in self.vreg.possible_vobjects('actions', req, rset) if a.category not in skipcategories] + + def pactions_by_cats(self, req, rset, categories=('addrelated',)): + return [(a.id, a.__class__) for a in self.vreg.possible_vobjects('actions', req, rset) + if a.category in categories] + + paddrelactions = deprecated_function(pactions_by_cats) + def pactionsdict(self, req, rset, skipcategories=('addrelated', 'siteactions', 'useractions')): res = {} for a in self.vreg.possible_vobjects('actions', req, rset): @@ -225,10 +234,7 @@ res.setdefault(a.category, []).append(a.__class__) return res - def paddrelactions(self, req, rset): - return [(a.id, a.__class__) for a in self.vreg.possible_vobjects('actions', req, rset) - if a.category == 'addrelated'] - + def remote_call(self, fname, *args): """remote call simulation""" dump = simplejson.dumps @@ -355,7 +361,7 @@ def create_user(self, user, groups=('users',), password=None, commit=True): if password is None: password = user - eid = self.execute('INSERT EUser X: X login %(x)s, X upassword %(p)s,' + eid = self.execute('INSERT CWUser X: X login %(x)s, X upassword %(p)s,' 'X in_state S WHERE S name "activated"', {'x': unicode(user), 'p': password})[0][0] groups = ','.join(repr(group) for group in groups) diff -r b7494ff85e16 -r 183da3addf0e devtools/devctl.py --- a/devtools/devctl.py Wed Apr 22 09:45:54 2009 +0200 +++ b/devtools/devctl.py Fri Apr 24 19:46:47 2009 +0200 @@ -9,7 +9,7 @@ import sys from datetime import datetime -from os import mkdir, chdir, listdir +from os import mkdir, chdir from os.path import join, exists, abspath, basename, normpath, split, isdir @@ -40,7 +40,7 @@ def my_cubes(self, cube): return (cube,) + self.cube_dependencies(cube) + self.cube_recommends(cube) - + @property def apphome(self): return None @@ -77,7 +77,7 @@ if mod.__file__.startswith(path): del sys.modules[name] break - + def generate_schema_pot(w, cubedir=None): """generate a pot file with schema specific i18n messages @@ -86,29 +86,31 @@ """ from cubicweb.cwvreg import CubicWebRegistry cube = cubedir and split(cubedir)[-1] - config = DevDepConfiguration(cube) - cleanup_sys_modules(config) + libconfig = DevDepConfiguration(cube) + libconfig.cleanup_interface_sobjects = False + cleanup_sys_modules(libconfig) if cubedir: - libschema = config.load_schema() config = DevCubeConfiguration(cube) schema = config.load_schema() else: schema = config.load_schema() - libschema = None - config.cleanup_interface_sobjects = False + config = libconfig + libconfig = None vreg = CubicWebRegistry(config) # set_schema triggers objects registrations vreg.set_schema(schema) w(DEFAULT_POT_HEAD) - _generate_schema_pot(w, vreg, schema, libschema=libschema, cube=cube) - -def _generate_schema_pot(w, vreg, schema, libschema=None, cube=None): + _generate_schema_pot(w, vreg, schema, libconfig=libconfig, cube=cube) + + +def _generate_schema_pot(w, vreg, schema, libconfig=None, cube=None): from cubicweb.common.i18n import add_msg w('# schema pot file, generated on %s\n' % datetime.now().strftime('%Y-%m-%d %H:%M:%S')) w('# \n') w('# singular and plural forms for each entity type\n') w('\n') - if libschema is not None: + if libconfig is not None: + libschema = libconfig.load_schema() entities = [e for e in schema.entities() if not e in libschema] else: entities = schema.entities() @@ -143,46 +145,64 @@ add_msg(w, rschema.description) w('# add related box generated message\n') w('\n') - actionbox = self.vreg['actions']['edit_box'][0] + actionbox = vreg['boxes']['edit_box'][0] for eschema in schema.entities(): if eschema.is_final(): continue - for x, rschemas in (('subject', eschema.subject_relations()), + for role, rschemas in (('subject', eschema.subject_relations()), ('object', eschema.object_relations())): for rschema in rschemas: if rschema.is_final(): continue - for teschema in rschema.targets(eschema, x): - if defined_in_library(libschema, eschema, rschema, teschema, x): + for teschema in rschema.targets(eschema, role): + if defined_in_library(libschema, eschema, rschema, + teschema, role): continue - if actionbox.relation_mode(rschema.type, teschema.type, x) == 'create': - if x == 'subject': - label = 'add %s %s %s %s' % (eschema, rschema, teschema, x) - label2 = "creating %s (%s %%(linkto)s %s %s)" % (teschema, eschema, rschema, teschema) + if actionbox.relation_mode(rschema, eschema, teschema, role) == 'create': + if role == 'subject': + label = 'add %s %s %s %s' % (eschema, rschema, + teschema, role) + label2 = "creating %s (%s %%(linkto)s %s %s)" % ( + teschema, eschema, rschema, teschema) else: - label = 'add %s %s %s %s' % (teschema, rschema, eschema, x) - label2 = "creating %s (%s %s %s %%(linkto)s)" % (teschema, teschema, rschema, eschema) + label = 'add %s %s %s %s' % (teschema, rschema, + eschema, role) + label2 = "creating %s (%s %s %s %%(linkto)s)" % ( + teschema, teschema, rschema, eschema) add_msg(w, label) add_msg(w, label2) - cube = (cube and 'cubes.%s.' % cube or 'cubicweb.') + #cube = (cube and 'cubes.%s.' % cube or 'cubicweb.') done = set() + if libconfig is not None: + from cubicweb.cwvreg import CubicWebRegistry + libvreg = CubicWebRegistry(libconfig) + libvreg.set_schema(libschema) # trigger objects registration + # prefill done set + list(_iter_vreg_objids(libvreg, done)) + print 'done', done + for objid in _iter_vreg_objids(vreg, done): + add_msg(w, '%s_description' % objid) + add_msg(w, objid) + +def _iter_vreg_objids(vreg, done, prefix=None): for reg, objdict in vreg.items(): for objects in objdict.values(): for obj in objects: objid = '%s_%s' % (reg, obj.id) if objid in done: - continue - if obj.__module__.startswith(cube) and obj.property_defs: - add_msg(w, '%s_description' % objid) - add_msg(w, objid) + break + if obj.property_defs: + yield objid done.add(objid) + break - -def defined_in_library(libschema, etype, rtype, tetype, x): - """return true if the given relation definition exists in cubicweb's library""" + +def defined_in_library(libschema, etype, rtype, tetype, role): + """return true if the given relation definition exists in cubicweb's library + """ if libschema is None: return False - if x == 'subject': + if role == 'subject': subjtype, objtype = etype, tetype else: subjtype, objtype = tetype, etype @@ -211,7 +231,7 @@ class UpdateCubicWebCatalogCommand(Command): """Update i18n catalogs for cubicweb library. - + It will regenerate cubicweb/i18n/xx.po files. You'll have then to edit those files to add translations of newly added messages. """ @@ -281,7 +301,7 @@ """ name = 'i18nupdate' arguments = '[...]' - + def run(self, args): """run the command with its specific arguments""" if args: @@ -328,7 +348,7 @@ execute('xgettext --no-location --omit-header -k_ -L java --from-code=utf-8 -o %s %s' % (tmppotfile, ' '.join(jsfiles))) # no pot file created if there are no string to translate - if exists(tmppotfile): + if exists(tmppotfile): potfiles.append(tmppotfile) print '******** create cube specific catalog' tmppotfile = join(tempdir, 'generated.pot') @@ -367,7 +387,7 @@ name = 'live-server' arguments = '' options = () - + def run(self, args): """run the command with its specific arguments""" from cubicweb.devtools.livetest import runserver @@ -415,7 +435,7 @@ ), ) - + def run(self, args): if len(args) != 1: raise BadCommandUsage("exactly one argument (cube name) is expected") @@ -449,7 +469,7 @@ distname = 'cubicweb-' + distname else: distname = 'cubicweb-%s' % cubename.lower() - + longdesc = shortdesc = raw_input('Enter a short description for your cube: ') if verbose: longdesc = raw_input('Enter a long description (or nothing if you want to reuse the short one): ') @@ -487,7 +507,7 @@ elif ans == 's': break return includes - + class ExamineLogCommand(Command): """Examine a rql log file. @@ -506,7 +526,7 @@ name = 'exlog' options = ( ) - + def run(self, args): if args: raise BadCommandUsage("no argument expected") @@ -540,7 +560,7 @@ print 'Percentage;Cumulative Time;Occurences;Query' for time, occ, rql in stat: print '%.2f;%.2f;%s;%s' % (time/total_time, time, occ, rql) - + register_commands((UpdateCubicWebCatalogCommand, UpdateTemplateCatalogCommand, LiveServerCommand, diff -r b7494ff85e16 -r 183da3addf0e devtools/fake.py --- a/devtools/fake.py Wed Apr 22 09:45:54 2009 +0200 +++ b/devtools/fake.py Fri Apr 24 19:46:47 2009 +0200 @@ -24,13 +24,13 @@ self.apphome = apphome self._cubes = cubes self['auth-mode'] = 'cookie' - self['uid'] = None + self['uid'] = None self['base-url'] = BASE_URL self['rql-cache-size'] = 100 - + def cubes(self, expand=False): return self._cubes - + def sources(self): return {} @@ -41,7 +41,7 @@ self.properties = {'ui.encoding': 'UTF8', 'ui.language': 'en', } - + def property_value(self, key): return self.properties[key] @@ -51,10 +51,10 @@ 'views' : [Mock(id='primary'), Mock(id='secondary'), Mock(id='oneline'), Mock(id='list')], } - + def registry_objects(self, name, oid=None): return self._registries[name] - + def etype_class(self, etype): class Entity(dict): e_schema = self.schema[etype] @@ -112,15 +112,15 @@ def set_header(self, header, value): """set an output HTTP header""" pass - + def add_header(self, header, value): """set an output HTTP header""" pass - + def remove_header(self, header): """remove an output HTTP header""" pass - + def get_header(self, header, default=None): """return the value associated with the given input header, raise KeyError if the header is not set @@ -169,7 +169,7 @@ self.is_internal_session = False self.is_super_session = self.user.eid == -1 self._query_data = {} - + def execute(self, *args): pass def commit(self, *args): @@ -186,7 +186,7 @@ def set_entity_cache(self, entity): pass - + class FakeRepo(object): querier = None def __init__(self, schema, vreg=None, config=None): @@ -199,8 +199,9 @@ def internal_session(self): return FakeSession(self) - - def extid2eid(self, source, extid, etype, session, insert=True): + + def extid2eid(self, source, extid, etype, session, insert=True, + recreate=False): try: return self.extids[extid] except KeyError: @@ -213,7 +214,7 @@ self.eids[eid] = extid source.after_entity_insertion(session, extid, entity) return eid - + def eid2extid(self, source, eid, session=None): return self.eids[eid] @@ -228,7 +229,7 @@ def __init__(self, uri): self.uri = uri - + class FakePool(object): def source(self, uri): return FakeSource(uri) diff -r b7494ff85e16 -r 183da3addf0e devtools/fill.py --- a/devtools/fill.py Wed Apr 22 09:45:54 2009 +0200 +++ b/devtools/fill.py Fri Apr 24 19:46:47 2009 +0200 @@ -236,7 +236,7 @@ returns acceptable values for this attribute """ # XXX HACK, remove or fix asap - if etype in (('String', 'Int', 'Float', 'Boolean', 'Date', 'EGroup', 'EUser')): + if etype in (('String', 'Int', 'Float', 'Boolean', 'Date', 'CWGroup', 'CWUser')): return [] queries = [] for index in xrange(entity_num): diff -r b7494ff85e16 -r 183da3addf0e devtools/htmlparser.py --- a/devtools/htmlparser.py Wed Apr 22 09:45:54 2009 +0200 +++ b/devtools/htmlparser.py Fri Apr 24 19:46:47 2009 +0200 @@ -4,10 +4,7 @@ from lxml import etree -from cubicweb.view import STRICT_DOCTYPE, TRANSITIONAL_DOCTYPE, CW_XHTML_EXTENSIONS - -STRICT_DOCTYPE = str(STRICT_DOCTYPE % CW_XHTML_EXTENSIONS).strip() -TRANSITIONAL_DOCTYPE = str(TRANSITIONAL_DOCTYPE % CW_XHTML_EXTENSIONS).strip() +from cubicweb.view import STRICT_DOCTYPE, TRANSITIONAL_DOCTYPE ERR_COUNT = 0 @@ -35,10 +32,10 @@ def preprocess_data(self, data): """used to fix potential blockquote mess generated by docutils""" - if STRICT_DOCTYPE not in data: + if str(STRICT_DOCTYPE) not in data: return data # parse using transitional DTD - data = data.replace(STRICT_DOCTYPE, TRANSITIONAL_DOCTYPE) + data = data.replace(str(STRICT_DOCTYPE), str(TRANSITIONAL_DOCTYPE)) tree = etree.fromstring(data, self.parser) namespace = tree.nsmap.get(None) # this is the list of authorized child tags for
nodes @@ -54,7 +51,7 @@ parent = blockquote.getparent() parent.remove(blockquote) data = etree.tostring(tree) - return '%s\n%s' % (STRICT_DOCTYPE, data) + return '%s\n%s' % (str(STRICT_DOCTYPE), data) class SaxOnlyValidator(Validator): diff -r b7494ff85e16 -r 183da3addf0e devtools/test/data/schema/relations.rel --- a/devtools/test/data/schema/relations.rel Wed Apr 22 09:45:54 2009 +0200 +++ b/devtools/test/data/schema/relations.rel Fri Apr 24 19:46:47 2009 +0200 @@ -23,11 +23,11 @@ Project uses Project Version version_of Project inline -Version todo_by EUser +Version todo_by CWUser Comment about Bug inline Comment about Story inline Comment about Comment inline -EUser interested_in Project +CWUser interested_in Project diff -r b7494ff85e16 -r 183da3addf0e devtools/test/unittest_testlib.py --- a/devtools/test/unittest_testlib.py Wed Apr 22 09:45:54 2009 +0200 +++ b/devtools/test/unittest_testlib.py Fri Apr 24 19:46:47 2009 +0200 @@ -24,7 +24,7 @@ self.view('raising', self.execute('Bug B'), template=None) def test_correct_view(self): - self.view('primary', self.execute('EUser U'), template=None) + self.view('primary', self.execute('CWUser U'), template=None) tests = [MyWebTest('test_error_view'), MyWebTest('test_correct_view')] result = self.runner.run(TestSuite(tests)) diff -r b7494ff85e16 -r 183da3addf0e doc/book/en/A020-tutorial.en.txt --- a/doc/book/en/A020-tutorial.en.txt Wed Apr 22 09:45:54 2009 +0200 +++ b/doc/book/en/A020-tutorial.en.txt Fri Apr 24 19:46:47 2009 +0200 @@ -1,9 +1,9 @@ .. -*- coding: utf-8 -*- -.. _Overview: +.. _Tutorial: -Quick overview of `CubicWeb` -============================ +Tutorial +======== `CubicWeb` is a semantic web application framework that favors reuse and object-oriented design. @@ -17,6 +17,7 @@ An `instance` is a specific installation of an application and includes configuration files. + This tutorial will show how to create a `cube` and how to use it as an application to run an `instance`. diff -r b7494ff85e16 -r 183da3addf0e doc/book/en/A02a-create-cube.en.txt --- a/doc/book/en/A02a-create-cube.en.txt Wed Apr 22 09:45:54 2009 +0200 +++ b/doc/book/en/A02a-create-cube.en.txt Fri Apr 24 19:46:47 2009 +0200 @@ -24,8 +24,6 @@ :: - from cubicweb.schema import format_constraint - class Blog(EntityType): title = String(maxsize=50, required=True) description = String() @@ -63,9 +61,7 @@ cubicweb-ctl create blog blogdemo -This command will create a directory ``~/etc/cubicweb.d/blogdemo`` -which will contain all the configuration files required to start -you web application. +This command will create the corresponding database and initialize it. Welcome to your web application ------------------------------- diff -r b7494ff85e16 -r 183da3addf0e doc/book/en/A02b-components.en.txt --- a/doc/book/en/A02b-components.en.txt Wed Apr 22 09:45:54 2009 +0200 +++ b/doc/book/en/A02b-components.en.txt Fri Apr 24 19:46:47 2009 +0200 @@ -68,7 +68,7 @@ Once you modified your data model, you need to synchronize the database with your model. For this purpose, `CubicWeb` provides -a very usefull command ``cubicweb-ctl shell blogdemo`` which +a very useful command ``cubicweb-ctl shell blogdemo`` which launches an interactive migration Python shell. (see :ref:`cubicweb-ctl-shell` for more details)) As you modified a relation from the `BlogEntry` schema, diff -r b7494ff85e16 -r 183da3addf0e doc/book/en/A03a-concepts.en.txt --- a/doc/book/en/A03a-concepts.en.txt Wed Apr 22 09:45:54 2009 +0200 +++ b/doc/book/en/A03a-concepts.en.txt Fri Apr 24 19:46:47 2009 +0200 @@ -267,7 +267,7 @@ * `set_header(header, value)`, adds an arbitrary header in the response * `cursor()` returns a RQL cursor on the session * `execute(*args, **kwargs)`, shortcut to ``.cursor().execute()`` - * `property_value(key)`, properties management (`EProperty`) + * `property_value(key)`, properties management (`CWProperty`) * dictionary `data` to store data to share informations between components *while a request is executed* diff -r b7494ff85e16 -r 183da3addf0e doc/book/en/B0011-schema-stdlib.en.txt --- a/doc/book/en/B0011-schema-stdlib.en.txt Wed Apr 22 09:45:54 2009 +0200 +++ b/doc/book/en/B0011-schema-stdlib.en.txt Fri Apr 24 19:46:47 2009 +0200 @@ -12,10 +12,10 @@ `````````````` The available system entities are: -* `EUser`, system users -* `EGroup`, users groups -* `EEType`, entity type -* `ERType`, relation type +* `CWUser`, system users +* `CWGroup`, users groups +* `CWEType`, entity type +* `CWRType`, relation type * `State`, workflow state * `Transition`, workflow transition @@ -24,8 +24,8 @@ * `EmailAddress`, email address, used by the system to send notifications to the users and also used by others optionnals schemas -* `EProperty`, used to configure the application -* `EPermission`, used to configure the security of the application +* `CWProperty`, used to configure the application +* `CWPermission`, used to configure the security of the application * `Card`, generic documenting card * `Bookmark`, an entity type used to allow a user to customize his links within diff -r b7494ff85e16 -r 183da3addf0e doc/book/en/B0012-schema-definition.en.txt --- a/doc/book/en/B0012-schema-definition.en.txt Wed Apr 22 09:45:54 2009 +0200 +++ b/doc/book/en/B0012-schema-definition.en.txt Fri Apr 24 19:46:47 2009 +0200 @@ -6,7 +6,9 @@ An entity type is defined by a Python class which inherits from `EntityType`. The class definition contains the description of attributes and relations for the defined entity type. -The class name corresponds to the entity type name. +The class name corresponds to the entity type name. It is exepected to be +defined in the module ``mycube.schema``. + For example :: @@ -21,14 +23,36 @@ works_for = SubjectRelation('Company', cardinality='?*') -* the name of the Python attribute corresponds to the name of the attribute - or the relation in `CubicWeb` application. +The entity described above defines three attributes of type String, +last_name, first_name and title, an attribute of type Date for the date of +birth and a relation that connects a `Person` to another entity of type +`Company` through the semantic `works_for`. + +The name of the Python attribute corresponds to the name of the attribute +or the relation in `CubicWeb` application. + +Built-in types for attributes +````````````````````````````` -* all `CubicWeb` built-in types are available : `String`, `Int`, `Float`, - `Boolean`, `Date`, `Datetime`, `Time`, `Byte`; they are and implicitely - imported (as well as the special the function "_"). +All `CubicWeb` built-in types are available : `String`, `Int`, `Float`, +`Decimal`, `Boolean`, `Date`, `Datetime`, `Time`, `Interval`, `Byte` +and `Password`. +They are implicitely imported (as well as the special the function "_" +for translation :ref:`internationalization`). + +An attribute is defined in the schema as follows:: + + attr_name = attr_type(properties*) -* each entity type has at least the following meta-relations : +where `attr_type` is one of the type listed above and `properties` is +a list of the attribute needs to statisfy (see :ref:`properties` +for more details). + + +Meta-data +````````` + +Each entity type has at least the following meta-relations : - `eid` (`Int`) @@ -36,12 +60,12 @@ - `modification_date` (`Datetime`) - - `created_by` (`EUser`) (which user created the entity) + - `created_by` (`CWUser`) (which user created the entity) - - `owned_by` (`EUser`) (to whom the entity belongs; by default the + - `owned_by` (`CWUser`) (to whom the entity belongs; by default the creator but not necessary, and it could have multiple owners) - - `is` (`EEType`) + - `is` (`CWEType`) (of which type the entity is) * relations can be defined by using `ObjectRelation` or `SubjectRelation`. @@ -62,6 +86,11 @@ * it is possible to use the attribute `meta` to flag an entity type as a `meta` (e.g. used to describe/categorize other entities) +Optionnal properties +```````````````````` +.. _properties: + + * optional properties for attributes and relations : - `description` : a string describing an attribute or a relation. By default @@ -95,7 +124,7 @@ or not within all entities of the same type (false by default) - `indexed` : boolean indicating if an index needs to be created for this - attribute in the database (false by default). This is usefull only if + attribute in the database (false by default). This is useful only if you know that you will have to run numerous searches on the value of this attribute. @@ -165,7 +194,7 @@ inlined = True cardinality = '?*' subject = '*' - object = 'EUser' + object = 'CWUser' In addition to the permissions, the properties of the relation types (shared also by all definition of relation of this type) are : @@ -290,15 +319,15 @@ - the permissions `add` and `delete` are equivalent. Only `add`/`read` are actually taken in consideration. -In addition to that the entity type `EPermission` from the standard library +In addition to that the entity type `CWPermission` from the standard library allow to build very complex and dynamic security architecture. The schema of this entity type is as follow : :: - class EPermission(MetaEntityType): + class CWPermission(MetaEntityType): """entity type that may be used to construct some advanced security configuration """ name = String(required=True, indexed=True, internationalizable=True, maxsize=100) - require_group = SubjectRelation('EGroup', cardinality='+*', + require_group = SubjectRelation('CWGroup', cardinality='+*', description=_('groups to which the permission is granted')) require_state = SubjectRelation('State', description=_("entity'state in which the permission is applyable")) @@ -338,14 +367,14 @@ } inlined = True -This configuration indicates that an entity `EPermission` named +This configuration indicates that an entity `CWPermission` named "add_version" can be associated to a project and provides rights to create new versions on this project to specific groups. It is important to notice that : * in such case, we have to protect both the entity type "Version" and the relation associating a version to a project ("version_of") -* because of the genricity of the entity type `EPermission`, we have to execute +* because of the genricity of the entity type `CWPermission`, we have to execute a unification with the groups and/or the states if necessary in the expression ("U in_group G, P require_group G" in the above example) diff -r b7494ff85e16 -r 183da3addf0e doc/book/en/B0020-define-workflows.en.txt --- a/doc/book/en/B0020-define-workflows.en.txt Wed Apr 22 09:45:54 2009 +0200 +++ b/doc/book/en/B0020-define-workflows.en.txt Fri Apr 24 19:46:47 2009 +0200 @@ -69,7 +69,7 @@ _ = unicode - moderators = add_entity('EGroup', name=u"moderators") + moderators = add_entity('CWGroup', name=u"moderators") This adds the `moderators` user group. diff -r b7494ff85e16 -r 183da3addf0e doc/book/en/B0030-data-as-objects.en.txt --- a/doc/book/en/B0030-data-as-objects.en.txt Wed Apr 22 09:45:54 2009 +0200 +++ b/doc/book/en/B0030-data-as-objects.en.txt Fri Apr 24 19:46:47 2009 +0200 @@ -7,12 +7,12 @@ In this chapter, we will introduce the objects that are used to handle the data stored in the database. -Classes `Entity` and `AnyEntity` --------------------------------- +Class `Entity` and `AnyEntity` +------------------------------ To provide a specific behavior for each entity, we have to define a class inheriting from `cubicweb.entities.AnyEntity`. In general, we -define this class in a module of `entities` package of an application +define this class in a module of `mycube.entities` package of an application so that it will be available on both server and client side. The class `AnyEntity` is loaded dynamically from the class `Entity` @@ -114,6 +114,105 @@ * `relation_vocabulary(rtype, targettype, x, limit=None)`, called internally by `subject_relation_vocabulary` and `object_relation_vocabulary` +Class `TreeMixIn` +----------------- + +This class provides a tree interface. This mixin has to be inherited +explicitly and configured using the tree_attribute, parent_target and +children_target class attribute to benefit from this default implementation. + +This class provides the following methods: + + * `different_type_children(entities=True)`, returns children entities + of different type as this entity. According to the `entities` parameter, + returns entity objects (if entity=True) or the equivalent result set. + + * `same_type_children(entities=True)`, returns children entities of + the same type as this entity. According to the `entities` parameter, + return entity objects (if entity=True) or the equivalent result set. + + * `iterchildren( _done=None)`, iters on the children of the entity. + + * `prefixiter( _done=None)` + + * `path()`, returns the list of eids from the root object to this object. + + * `iterparents()`, iters on the parents of the entity. + + * `notification_references(view)`, used to control References field + of email send on notification for this entity. `view` is the notification view. + Should return a list of eids which can be used to generate message ids + of previously sent email. + +`TreeMixIn` implements also the ITree interface (``cubicweb.interfaces``): + + * `parent()`, returns the parent entity if any, else None (e.g. if we are on the + root) + + * `children(entities=True, sametype=False)`, returns children entities + according to the `entities` parameter, return entity objects or the + equivalent result set. + + * `children_rql()`, returns the RQL query corresponding to the children + of the entity. + + * `is_leaf()`, returns True if the entity does not have any children. + + * `is_root()`, returns True if the entity does not have any parent. + + * `root()`, returns the root object of the tree representation of + the entity and its related entities. + +Example of use +`````````````` + +Imagine you defined three types of entities in your schema, and they +relates to each others as follows in ``schema.py``:: + + class Entity1(EntityType): + title = String() + is_related_to = SubjectRelation('Entity2', 'subject') + + class Entity2(EntityType): + title = String() + belongs_to = SubjectRelation('Entity3', 'subject') + + class Entity3(EntityType): + name = String() + +You would like to create a view that applies to both entity types +`Entity1` and `Entity2` and which lists the entities they are related to. +That means when you view `Entity1` you want to list all `Entity2`, and +when you view `Entity2` you want to list all `Entity3`. + +In ``entities.py``:: + + class Entity1(TreeMixIn, AnyEntity): + id = 'Entity1' + __implements__ = AnyEntity.__implements__ + (ITree,) + __rtags__ = {('is_related_to', 'Entity2', 'object'): 'link'} + tree_attribute = 'is_related_to' + + def children(self, entities=True): + return self.different_type_children(entities) + + class Entity2(TreeMixIn, AnyEntity): + id = 'Entity2' + __implements__ = AnyEntity.__implements__ + (ITree,) + __rtags__ = {('belongs_to', 'Entity3', 'object'): 'link'} + tree_attribute = 'belongs_to' + + def children(self, entities=True): + return self.different_type_children(entities) + +Once this is done, you can define your common view as follows:: + + class E1E2CommonView(baseviews.PrimaryView): + accepts = ('Entity11, 'Entity2') + + def render_entity_relations(self, entity, siderelations): + self.wview('list', entity.children(entities=False)) + *rtags* ------- diff -r b7494ff85e16 -r 183da3addf0e doc/book/en/B0031-define-entities.en.txt --- a/doc/book/en/B0031-define-entities.en.txt Wed Apr 22 09:45:54 2009 +0200 +++ b/doc/book/en/B0031-define-entities.en.txt Fri Apr 24 19:46:47 2009 +0200 @@ -133,7 +133,7 @@ The method ``filterform_vocabulary(rtype, x, var, rqlst, args, cachekey)`` takes the name of a relation and the target as parameters, [XXX what does it mean ?] - which indicates of the +which indicates of the entity on which we apply the method is subject or object of the relation. It has to return: diff -r b7494ff85e16 -r 183da3addf0e doc/book/en/B0040-migration.en.txt --- a/doc/book/en/B0040-migration.en.txt Wed Apr 22 09:45:54 2009 +0200 +++ b/doc/book/en/B0040-migration.en.txt Fri Apr 24 19:46:47 2009 +0200 @@ -208,3 +208,6 @@ * `add_entity_type_table(etype, commit=True)` * `add_relation_type_table(rtype, commit=True)` * `uninline_relation(rtype, commit=True)` + + +[FIXME] Add explanation on how to use cubicweb-ctl shell diff -r b7494ff85e16 -r 183da3addf0e doc/book/en/B1020-define-views.en.txt --- a/doc/book/en/B1020-define-views.en.txt Wed Apr 22 09:45:54 2009 +0200 +++ b/doc/book/en/B1020-define-views.en.txt Fri Apr 24 19:46:47 2009 +0200 @@ -13,6 +13,8 @@ understanding of the classes and methods available, then detail the view selection principle which makes `CubicWeb` web interface very flexible. +A `View` is an object applied to another object such as an entity. + Basic class for views --------------------- @@ -72,6 +74,7 @@ * `AnyRsetView`, view applied to any result set * `EmptyRsetView`, view applied to an empty result set + The selection view principle ---------------------------- @@ -96,6 +99,9 @@ Registerer `````````` +[Registerers are deprecated: they will soon disappear for explicite +registration...] + A view is also customizable through its attribute ``__registerer__``. This is used at the time the application is launched to manage how objects (views, graphic components, actions, etc.) @@ -110,9 +116,6 @@ when they are selected for display. -`CubicWeb` provides a lot of standard views for the default class -`EntityType`. You can find them in ``cubicweb/web/views/``. - .. include:: B1022-views-stdlib.en.txt @@ -150,12 +153,122 @@ search_states = ('linksearch',) +Rendering methods and attributes for ``PrimaryView`` +---------------------------------------------------- +By default, `CubicWeb` provides a primary view for each new entity type +you create. The first view you might be interested in modifying. +Let's have a quick look at the EntityView ``PrimaryView`` as well as +its rendering method:: + + class PrimaryView(EntityView): + """the full view of an non final entity""" + id = 'primary' + title = _('primary') + show_attr_label = True + show_rel_label = True + skip_none = True + skip_attrs = ('eid', 'creation_date', 'modification_date') + skip_rels = () + main_related_section = True + + ... + + def cell_call(self, row, col): + self.row = row + self.render_entity(self.complete_entity(row, col)) + + def render_entity(self, entity): + """return html to display the given entity""" + siderelations = [] + self.render_entity_title(entity) + self.render_entity_metadata(entity) + # entity's attributes and relations, excluding meta data + # if the entity isn't meta itself + self.w(u'
') + self.w(u'
') + self.render_entity_attributes(entity, siderelations) + self.w(u'
') + self.content_navigation_components('navcontenttop') + if self.main_related_section: + self.render_entity_relations(entity, siderelations) + self.w(u'
') + # side boxes + self.w(u'
') + self.render_side_related(entity, siderelations) + self.w(u'
') + self.w(u'
') + self.content_navigation_components('navcontentbottom') + + ... + +``cell_call`` is executed for each entity of a result set and apply ``render_entity``. + +The methods you want to modify while customizing a ``PrimaryView`` are: + +*render_entity_title(self, entity)* + Renders the entity title based on the assumption that the method + ``def content_title(self)`` is implemented for the given entity type. + +*render_entity_metadata(self, entity)* + Renders the entity metadata based on the assumption that the method + ``def summary(self)`` is implemented for the given entity type. + +*render_entity_attributes(self, entity, siderelations)* + Renders all the attribute of an entity with the exception of attribute + of type `Password` and `Bytes`. + +*content_navigation_components(self, context)* + This method is applicable only for entity type implementing the interface + `IPrevNext`. This interface is for entities which can be linked to a previous + and/or next entity. This methods will render the navigation links between + entities of this type, either at the top or at the bottom of the page + given the context (navcontent{top|bottom}). + +*render_entity_relations(self, entity, siderelations)* + Renders all the relations of the entity in the main section of the page. + +*render_side_related(self, entity, siderelations)* + Renders all the relations of the entity in a side box. This is equivalent + to *render_entity_relations* in addition to render the relations + in a box. + +Also, please note that by setting the following attributes in you class, +you can already customize some of the rendering: + +*show_attr_label* + Renders the attribute label next to the attribute value if set to True. + Otherwise, does only display the attribute value. + +*show_rel_label* + Renders the relation label next to the relation value if set to True. + Otherwise, does only display the relation value. + +*skip_none* + Does not render an attribute value that is None if set to True. + +*skip_attrs* + Given a list of attributes name, does not render the value of the attributes listed. + +*skip_rels* + Given a list of relations name, does not render the relations listed. + +*main_related_section* + Renders the relations of the entity if set to True. + +A good practice is for you to identify the content of your entity type for which +the default rendering does not answer your need so that you can focus on the specific +method (from the list above) that needs to be modified. We do not recommand you to +overwrite ``render_entity`` as you might potentially loose the benefits of the side +boxes handling. Example of a view customization ------------------------------- +[FIXME] XXX Example needs to be rewritten as it shows how to modify cell_call which +contredicts our advise of not modifying it. + We'll show you now an example of a ``primary`` view and how to customize it. If you want to change the way a ``BlogEntry`` is displayed, just override diff -r b7494ff85e16 -r 183da3addf0e doc/book/en/B1022-views-stdlib.en.txt --- a/doc/book/en/B1022-views-stdlib.en.txt Wed Apr 22 09:45:54 2009 +0200 +++ b/doc/book/en/B1022-views-stdlib.en.txt Fri Apr 24 19:46:47 2009 +0200 @@ -2,6 +2,10 @@ Predefined views in the library ``````````````````````````````` + +`CubicWeb` provides a lot of standard views. You can find them in +``cubicweb/web/views/``. + A certain number of views are used to build the web interface, which apply to one or more entities. Their identifier is what distinguish them from each others and the main ones are: @@ -56,7 +60,8 @@ This view displays usually a side box of some related entities in a primary view. -Start view: + +Start view (e.g. views that don't apply to a result set): *index* This view defines the home page of your application. It does not require diff -r b7494ff85e16 -r 183da3addf0e doc/book/en/B1070-ui-components.en.txt --- a/doc/book/en/B1070-ui-components.en.txt Wed Apr 22 09:45:54 2009 +0200 +++ b/doc/book/en/B1070-ui-components.en.txt Fri Apr 24 19:46:47 2009 +0200 @@ -9,6 +9,6 @@ --------------------- XXXFILLME -EProperty +CWProperty --------- XXXFILLME diff -r b7494ff85e16 -r 183da3addf0e doc/book/en/B1090-internationalization.en.txt --- a/doc/book/en/B1090-internationalization.en.txt Wed Apr 22 09:45:54 2009 +0200 +++ b/doc/book/en/B1090-internationalization.en.txt Fri Apr 24 19:46:47 2009 +0200 @@ -1,9 +1,9 @@ .. -*- coding: utf-8 -*- -.. _internationalization: +.. _internationalisation: -Internationalization +Internationalisation ==================== Cubicweb fully supports the internalization of it's content and interface. diff -r b7494ff85e16 -r 183da3addf0e doc/book/en/C000-administration.en.txt --- a/doc/book/en/C000-administration.en.txt Wed Apr 22 09:45:54 2009 +0200 +++ b/doc/book/en/C000-administration.en.txt Fri Apr 24 19:46:47 2009 +0200 @@ -13,7 +13,8 @@ :maxdepth: 1 C010-setup.en.txt - C020-site-config.en.txt - C030-instance-config.en.txt - C040-rql.en.txt + C020-create-instance.en.txt + C030-site-config.en.txt + C040-instance-config.en.txt + C050-rql.en.txt diff -r b7494ff85e16 -r 183da3addf0e doc/book/en/C010-setup.en.txt --- a/doc/book/en/C010-setup.en.txt Wed Apr 22 09:45:54 2009 +0200 +++ b/doc/book/en/C010-setup.en.txt Fri Apr 24 19:46:47 2009 +0200 @@ -6,7 +6,202 @@ Installation and set-up of a `CubicWeb` environment =================================================== -.. include:: C011-installation.en.txt -.. include:: C012-create-instance.en.txt -.. include:: C013-cubicweb-ctl.en.txt +Installation of `Cubicweb` and its dependencies +----------------------------------------------- + +`CubicWeb` is packaged for Debian and Ubuntu, but can be installed from source +using a tarball or the Mercurial version control system. + +.. _DebianInstallation: + +Debian and Ubuntu packages +``````````````````````````` + +Depending on the distribution you are using, add the appropriate line to your list +of sources (for example by editing ``/etc/apt/sources.list``). + +For Debian Lenny:: + + deb http://ftp.logilab.org/dists/ lenny/ + +For Debian Sid:: + + deb http://ftp.logilab.org/dists/ sid/ + +For Ubuntu Hardy:: + + deb http://ftp.logilab.org/dists/ hardy/ + + +You can now install the required packages with the following command:: + + apt-get update + apt-get install cubicweb cubicweb-dev + +`cubicweb` installs the framework itself, allowing you to create +new applications. + +`cubicweb-dev` installs the development environment allowing you to +develop new cubes. + +There is also a wide variety of cubes listed on http://www.cubicweb.org/Project available as debian packages and tarball. + + +Install from source +``````````````````` + +You can download the archive containing the sources from our `ftp site`_ at:: + + http://ftp.logilab.org/pub/cubicweb/ + +.. _`ftp site`: http://ftp.logilab.org/pub/cubicweb/ + +or keep up to date with on-going development by using Mercurial and its forest +extension:: + + hg fclone http://www.logilab.org/hg/forests/cubicweb + +See :ref:`MercurialPresentation` for more details about Mercurial. + +Postgres installation +````````````````````` + +Please refer to the `Postgresql project online documentation`_. + +.. _`Postgresql project online documentation`: http://www.postgresql.org/ + +You need to install the three following packages: `postgres-8.3`, +`postgres-contrib-8.3` and `postgresql-plpython-8.3`. + + +Then you can install: + +* `pyro` if you wish the repository to be accessible through Pyro + or if the client and the server are not running on the same machine + (in which case the packages will have to be installed on both + machines) + +* `python-ldap` if you plan to use a LDAP source on the server + +.. _ConfigurationEnv: + +Environment configuration +------------------------- + +If you installed `CubicWeb` by cloning the Mercurial forest, then you +will need to update the environment variable PYTHONPATH by adding +the path to the forest ``cubicweb``: + +Add the following lines to either `.bashrc` or `.bash_profile` to configure +your development environment :: + + export PYTHONPATH=/full/path/to/cubicweb-forest + +If you installed the debian packages, no configuration is required. +Your new cubes will be placed in `/usr/share/cubicweb/cubes` and +your applications will be placed in `/etc/cubicweb.d`. + +To use others directories then you will have to configure the +following environment variables as follows:: + export CW_CUBES_PATH=~/lib/cubes + export CW_REGISTRY=~/etc/cubicweb.d/ + export CW_INSTANCE_DATA=$CW_REGISTRY + export CW_RUNTIME=/tmp + +.. note:: + The values given above are our suggestions but of course + can be different. + + +Databases configuration +----------------------- + + + +.. _ConfigurationPostgres: + +Postgres configuration +`````````````````````` + +.. note:: + If you already have an existing cluster and postgres server + running, you do not need to execute the initilization step + of your Postgres database. + +* First, initialize the database Postgres with the command ``initdb``. + :: + + $ initdb -D /path/to/pgsql + + Once initialized, start the database server Postgres + with the command:: + + $ postgres -D /path/to/psql + + If you cannot execute this command due to permission issues, please + make sure that your username has write access on the database. + :: + + $ chown username /path/to/pgsql + +* The database authentication can be either set to `ident sameuser` + or `md5`. + If set to `md5`, make sure to use an existing user + of your database. + If set to `ident sameuser`, make sure that your + client's operating system user name has a matching user in + the database. If not, please do as follow to create a user:: + + $ su + $ su - postgres + $ createuser -s -P username + + The option `-P` (for password prompt), will encrypt the password with + the method set in the configuration file ``pg_hba.conf``. + If you do not use this option `-P`, then the default value will be null + and you will need to set it with:: + + $ su postgres -c "echo ALTER USER username WITH PASSWORD 'userpasswd' | psql" + + This login/password will be requested when you will create an + instance with `cubicweb-ctl create` to initialize the database of + your application. + +.. note:: + The authentication method can be configured in ``pg_hba.conf``. + + +.. FIXME Are these steps really necessary? It seemed to work without. + +* Installation of plain-text index extension :: + + cat /usr/share/postgresql/8.3/contrib/tsearch2.sql | psql -U username template1 + +* Installation of plpythonu language by default :: + + createlang -U pgadmin plpythonu template1 + +MySql configuration +``````````````````` +Yout must add the following lines in /etc/mysql/my.cnf file:: + + transaction-isolation = READ-COMMITTED + default-storage-engine=INNODB + default-character-set=utf8 + max_allowed_packet = 128M + +Pyro configuration +------------------ + +If you use Pyro, it is required to have a name server Pyro running on your +network (by default it is detected by a broadcast request). + +To do so, you need to : + +* launch the server manually before starting cubicweb as a server with + `pyro-nsd start` + +* edit the file ``/etc/default/pyro-nsd`` so that the name server pyro + will be launched automatically when the machine fire up + diff -r b7494ff85e16 -r 183da3addf0e doc/book/en/C011-installation.en.txt --- a/doc/book/en/C011-installation.en.txt Wed Apr 22 09:45:54 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,201 +0,0 @@ -.. -*- coding: utf-8 -*- - -.. _CubicWebInstallation: - -Installation -============ - -Installation of `Cubicweb` and its dependencies ------------------------------------------------ - -`CubicWeb` is packaged for Debian and Ubuntu, but can be installed from source -using a tarball or the Mercurial version control system. - -Debian and Ubuntu packages -``````````````````````````` -Depending on the distribution you are using, add the appropriate line to your list -of sources (for example by editing ``/etc/apt/sources.list``). - -For Debian Lenny:: - - deb http://ftp.logilab.org/dists/ lenny/ - -For Debian Sid:: - - deb http://ftp.logilab.org/dists/ sid/ - -For Ubuntu Hardy:: - - deb http://ftp.logilab.org/dists/ hardy/ - - -You can now install the required packages with the following command:: - - apt-get update - apt-get install cubicweb - apt-get install cubicweb-dev - -`cubicweb` installs the framework itself, allowing you to create -new applications. - -`cubicweb-dev` installs the development environment allowing you to -develop new cubes. - -There is also a wide variety of cubes listed on http://www.cubicweb.org/Project available as debian packages and tarball. - - -Install from source -``````````````````` - -You can download the archive containing the sources from our `ftp site`_ at:: - - http://ftp.logilab.org/pub/cubicweb/ - -.. _`ftp site`: http://ftp.logilab.org/pub/cubicweb/ - -or keep up to date with on-going development by using Mercurial and its forest -extension:: - - hg fclone http://www.logilab.org/hg/forests/cubicweb - -See :ref:`MercurialPresentation` for more details about Mercurial. - -Postgres installation -````````````````````` - -Please refer to the `Postgresql project online documentation`_. - -.. _`Postgresql project online documentation`: http://www.postgresql.org/ - -You need to install the three following packages: `postgres-8.3`, -`postgres-contrib-8.3` and `postgresql-plpython-8.3`. - - -Then you can install: - -* `pyro` if you wish the repository to be accessible through Pyro - or if the client and the server are not running on the same machine - (in which case the packages will have to be installed on both - machines) - -* `python-ldap` if you plan to use a LDAP source on the server - -.. _ConfigurationEnv: - -Environment configuration -------------------------- - -If you installed `CubicWeb` by cloning the Mercurial forest, then you -will need to update the environment variable PYTHONPATH by adding -the path to the forest ``cubicweb``: - -Add the following lines to either `.bashrc` or `.bash_profile` to configure -your development environment :: - - export PYTHONPATH=/full/path/to/cubicweb-forest - -If you installed the debian packages, no configuration is required. -Your new cubes will be placed in `/usr/share/cubicweb/cubes` and -your applications will be placed in `/etc/cubicweb.d`. - -To use others directories then you will have to configure the -following environment variables as follows:: - - export CW_CUBES_PATH=~/lib/cubes - export CW_REGISTRY=~/etc/cubicweb.d/ - export CW_INSTANCE_DATA=$CW_REGISTRY - export CW_RUNTIME=/tmp - -.. note:: - The values given above are our suggestions but of course - can be different. - -.. _ConfigurationPostgres: - -Postgres configuration ----------------------- - -.. note:: - If you already have an existing cluster and postgres server - running, you do not require to execute the initilization step - of your Postgres database. - -* First you have to initialize the database Postgres with the command ``initdb``. - :: - - $ initdb -D /path/to/pgsql - - Once initialized, you can launch the database server Postgres - with the command:: - - $ postgres -D /path/to/psql - - If you cannot execute this command due to permission issues, please - make sure that your username has write access on the database. - :: - - $ chown username /path/to/pgsql - -* The database authentication can be either set to `ident sameuser` - or `md5`. - If set to `md5`, make sure to use an existing user - of your database. - If set to `ident sameuser`, make sure that your - client's operating system user name has a matching user in - the database. If not, please do as follow to create a user:: - - $ su - $ su - postgres - $ createuser -s username - - If created with the options -P (for password prompt, - ``createuser -s -P username``), the password will be encrypted with - the method set in the configuration file ``pg_hba.conf``. - If you do not use this option, then the default value will be null - and this require to set the password in the database itself. - To do so: :: - - $ su - $ su - postgres - $ psql - - And then execute de following query:: - - ALTER USER username WITH PASSWORD `password` - - This login/password will be requested when you will create an - instance with `cubicweb-ctl create` to initialize the database of - your application. - -.. note:: - The authentication method can be configured in ``pg_hba.conf``. - - -.. FIXME Are these steps really necessary? It seemed to work without. - -* Installation of plain-text index extension :: - - cat /usr/share/postgresql/8.3/contrib/tsearch2.sql | psql -U username template1 - -* Installation of plpythonu language by default :: - - createlang -U pgadmin plpythonu template1 - - -Pyro configuration ------------------- - -If you use Pyro, it is required to have a name server Pyro running on your -network (by default it is identified by a broadcast request). - -To do so, you need to : - -* launch the server manually before starting cubicweb with `pyro-ns` - -* launch the server manually before starting cubicweb as a server with - `pyro-nsd start` - -* edit the file ``/etc/default/pyro-nsd`` so that the name server pyro - will be launched automatically when the machine fire up - - diff -r b7494ff85e16 -r 183da3addf0e doc/book/en/C012-create-instance.en.txt --- a/doc/book/en/C012-create-instance.en.txt Wed Apr 22 09:45:54 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,132 +0,0 @@ -.. -*- coding: utf-8 -*- - -Creation of your first instance -=============================== - -What is an instance? --------------------- - -A `CubicWeb` instance is a directory in ``~/etc/cubicweb.d`` -which enables us to run a web application. An instance is based on -one or more cubes. - -An instance is a container that refers to cubes and configuration -parameters for your web application. - -We recommand not to define schema, entities or views in the instance -file system itself but in the cube, in order to maintain re-usability of -entities and their views. We strongly recommand to develop cubes which -could be used in other instances (modular approach). - - -What is a cube? ---------------- - -A cube defines entities, their views, their schemas and workflows -in an independant directory located in ``/path/to/forest/cubicweb/cubes/`` -for a Mercurial installation or in ``/usr/share/cubicweb/cubes`` for -a debian package installation. - -When an instance is created, you list one or more cubes that your instance -will use. Using a cube means having the entities defined in your cube's schema -available in your instance as well as their views and workflows. - -.. note:: - The commands used below are more detailled in the section dedicated to - :ref:`cubicweb-ctl`. - - -Create a cube -------------- - -Let's start by creating the cube environment in which we will develop :: - - cd ~/hg - - cubicweb-ctl newcube mycube - - # answer questions - hg init moncube - cd mycube - hg add . - hg ci - -If all went well, you should see the cube you just create in the list -returned by `cubicweb-ctl list` in the section *Available components*, -and if it is not the case please refer to :ref:`ConfigurationEnv`. - -To use a cube, you have to list it in the variable ``__use__`` -of the file ``__pkginfo__.py`` of the instance. -This variable is used for the instance packaging (dependencies -handled by system utility tools such as APT) and the usable cubes -at the time the base is created (import_erschema('MyCube') will -not properly work otherwise). - -.. note:: - Please note that if you do not wish to use default directory - for your cubes library, then you want to use the option - --directory to specify where you would like to place - the source code of your cube: - ``cubicweb-ctl newcube --directory=/path/to/cubes/library cube_name`` - -Instance creation ------------------ - -Now that we created our cube, we can create an instance to view our -application in a web browser. To do so we will use a `all-in-on` -configuration to simplify things :: - - cubicweb-ctl create -c all-in-one mycube myinstance - -.. note:: - Please note that we created a new cube for a demo purpose but - you could have use an existing cube available in our standard library - such as blog or person for example. - -A serie of questions will be prompted to you, the default answer is usually -sufficient. You can anyway modify the configuration later on by editing -configuration files. When a user/psswd is requested to access the database -please use the login you create at the time you configured the database -(:ref:`ConfigurationPostgres`). - -It is important to distinguish here the user used to access the database and -the user used to login to the cubicweb application. When a `CubicWeb` application -starts, it uses the login/psswd for the database to get the schema and handle -low level transaction. But, when ``cubicweb-ctl create`` asks for -a manager login/psswd of `CubicWeb`, it refers to an application user you will -use during the development to administrate your web application. It will be -possible, later on, to create others users for your final web application. - -When this command is completed, the definition of your instance is -located in *~/etc/cubicweb.d/myinstance/*. To launch it, you just type :: - - cubicweb-ctl start -D myinstance - -The option `-D` specify the *debug mode* : the instance is not running in -server mode and does not disconnect from the termnial, which simplifies debugging -in case the instance is not properly launched. You can see how it looks by -visiting the URL `http://localhost:8080` (the port number depends of your -configuration). To login, please use the cubicweb administrator login/psswd you -defined when you created the instance. - -To shutdown the instance, Crtl-C in the terminal window is enough. -If you did not use the option `-D`, then type :: - - cubicweb-ctl stop myinstance - -This is it! All is settled down to start developping your data model... - - -Usage of `cubicweb-liveserver` -`````````````````````````````` - -To quickly test a new cube, you can also use the script `cubicweb-liveserver` -which allows to create an application in memory (use of SQLite database by -default) and make it accessible through a web server :: - - cubicweb-ctl live-server mycube - -or by using an existing database (SQLite or Postgres):: - - cubicweb-ctl live-server -s myfile_sources mycube - diff -r b7494ff85e16 -r 183da3addf0e doc/book/en/C013-cubicweb-ctl.en.txt --- a/doc/book/en/C013-cubicweb-ctl.en.txt Wed Apr 22 09:45:54 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ -.. -*- coding: utf-8 -*- - -.. _cubicweb-ctl: - -``cubicweb-ctl`` tool -===================== - -`cubicweb-ctl` is the swiss knife to manage `CubicWeb` instances. -The general syntax is :: - - cubicweb-ctl [options command] - -To view available commands :: - - cubicweb-ctl - cubicweb-ctl --help - -Please note that the commands available depends on the `CubicWeb` packages -and cubes that have been installed. - -To view the help menu on specific command :: - - cubicweb-ctl --help - -Command to create a cube ------------------------- - -* ``newcube``, create a new cube on the file system based on the name - given in the parameters. This command create a cube from an application - skeleton that includes default files required for debian packaging. - - -Command to create an instance ------------------------------ -* ``create``, creates the files for the instance configuration -* ``db-create``, creates the system database of an instance (tables and - extensions only) -* ``db-init``, initializes the system database of an instance - (schema, groups, users, workflows...) - -By default, those three commandes are encapsulated in ``create`` so -that they can be executed consecutively. - -Command to create an instance for Google AppEngine datastore source -------------------------------------------------------------------- -* ``newgapp``, creates the configuration files for an instance - -This command needs to be followed by the commands responsible for -the database initialization. As those are specific to the `datastore`, -specific Google AppEgine database, they are not available for now -in cubicweb-ctl, but they are available in the instance created. - -For more details, please see :ref:`gaecontents` . - -Commands to launch instance ---------------------------- -* ``start``, starts one or more or all instances -* ``stop``, stops one or more or all instances -* ``restart``, restarts one or more or all instances -* ``status``, returns the status of the instance - -Commands to maintain instances ------------------------------- -* ``upgrade``, launches the existing instances migration when a new version - of `CubicWeb` or the cubes installed is available -* ``shell``, opens a migration shell for manual maintenance of the instance - (see :ref:`cubicweb-ctl-shell` for more details) -* ``db-dump``, creates a dump of the system database -* ``db-restore``, restores a dump of the system database -* ``db-check``, checks data integrity of an instance. If the automatic correction - is activated, it is recommanded to create a dump before this operation. -* ``schema-sync``, synchronizes the persistent schema of an instance with - the application schema. It is recommanded to create a dump before this operation. - -Commands to maintain i18n catalogs ----------------------------------- -* ``i18nlibupdate``, regenerates messages catalogs of the `CubicWeb` library -* ``i18nupdate``, regenerates the messages catalogs of a cube -* ``i18ncompile``, recompiles the messages catalogs of an instance. - This is automatically done while upgrading. - -Cf :ref:`Internationalisation`. - -Other commands --------------- -* ``list``, provides a list of the available configuration, cubes - and instances. -* ``delete``, deletes an instance (configuration files and database) - - -.. _cubicweb-ctl-shell: - -``cubicweb-ctl shell`` addon ----------------------------- - -This migration shell provides an interactive interface to all -the migrations functions described in the chapter :ref:`migration`. - -Usage -````` -:: - - ``cubicweb-ctl shell myapp`` - -Examples --------- - -Create an instance from an existing cube -```````````````````````````````````````` - -To create an instance from an existing cube, execute the following -command :: - - cubicweb-ctl create - -This command will create the configuration files of an instance in -``~/etc/cubicweb.d/``. -The tool ``cubicweb-ctl`` allows you to execute the command ``db-create`` -and ``db-init`` when you run ``create`` so that you can complete an -instance creation in a single command. - -If you decide not to execut those commands while ``cubicweb-ctl create``, -then you will have to execute them seperately(``cubicweb-ctl db-create``, -``cubicweb-ctl db-init`` ) otherwise your installation will not be complete -and you will not be able to launch your instance. - - -Creation of an instance from a new cube -``````````````````````````````````````` - -Create first your new cube cube :: - - cubicweb-ctl newcube - -This will create a new cube in ``/path/to/forest/cubicweb/cubes/`` -for a Mercurial forest installation, or in ``/usr/share/cubicweb/cubes`` -for a debian packages installation, and then create an instance as -explained just above. - - diff -r b7494ff85e16 -r 183da3addf0e doc/book/en/C020-create-instance.en.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/book/en/C020-create-instance.en.txt Fri Apr 24 19:46:47 2009 +0200 @@ -0,0 +1,132 @@ +.. -*- coding: utf-8 -*- + +Creation of your first instance +=============================== + +What is an instance? +-------------------- + +A `CubicWeb` instance is a directory in ``~/etc/cubicweb.d`` +which enables us to run a web application. An instance is based on +a cube. + +An instance is a container that refers to cubes and configuration +parameters for your web application. + +We recommand not to define schema, entities or views in the instance +file system itself but in the cube, in order to maintain re-usability of +entities and their views. We strongly recommand to develop cubes which +could be used in other instances (modular approach). + + +What is a cube? +--------------- + +A cube defines entities, their views, their schemas and workflows +in an independant directory located in ``/path/to/forest/cubicweb/cubes/`` +for a Mercurial installation or in ``/usr/share/cubicweb/cubes`` for +a debian package installation. + +When an instance is created, you list one or more cubes that your instance +will use. Using a cube means having the entities defined in your cube's schema +available in your instance as well as their views and workflows. + +.. note:: + The commands used below are more detailled in the section dedicated to + :ref:`cubicweb-ctl`. + + +Create a cube +------------- + +Let's start by creating the cube environment in which we will develop :: + + cd ~/hg + + cubicweb-ctl newcube mycube + + # answer questions + hg init moncube + cd mycube + hg add . + hg ci + +If all went well, you should see the cube you just create in the list +returned by `cubicweb-ctl list` in the section *Available components*, +and if it is not the case please refer to :ref:`ConfigurationEnv`. + +To use a cube, you have to list it in the variable ``__use__`` +of the file ``__pkginfo__.py`` of the instance. +This variable is used for the instance packaging (dependencies +handled by system utility tools such as APT) and the usable cubes +at the time the base is created (import_erschema('MyCube') will +not properly work otherwise). + +.. note:: + Please note that if you do not wish to use default directory + for your cubes library, then you want to use the option + --directory to specify where you would like to place + the source code of your cube: + ``cubicweb-ctl newcube --directory=/path/to/cubes/library cube_name`` + +Instance creation +----------------- + +Now that we created our cube, we can create an instance to view our +application in a web browser. To do so we will use a `all-in-on` +configuration to simplify things :: + + cubicweb-ctl create -c all-in-one mycube myinstance + +.. note:: + Please note that we created a new cube for a demo purpose but + you could have use an existing cube available in our standard library + such as blog or person for example. + +A serie of questions will be prompted to you, the default answer is usually +sufficient. You can anyway modify the configuration later on by editing +configuration files. When a user/psswd is requested to access the database +please use the login you create at the time you configured the database +(:ref:`ConfigurationPostgres`). + +It is important to distinguish here the user used to access the database and +the user used to login to the cubicweb application. When a `CubicWeb` application +starts, it uses the login/psswd for the database to get the schema and handle +low level transaction. But, when ``cubicweb-ctl create`` asks for +a manager login/psswd of `CubicWeb`, it refers to an application user you will +use during the development to administrate your web application. It will be +possible, later on, to create others users for your final web application. + +When this command is completed, the definition of your instance is +located in *~/etc/cubicweb.d/myinstance/*. To launch it, you just type :: + + cubicweb-ctl start -D myinstance + +The option `-D` specify the *debug mode* : the instance is not running in +server mode and does not disconnect from the termnial, which simplifies debugging +in case the instance is not properly launched. You can see how it looks by +visiting the URL `http://localhost:8080` (the port number depends of your +configuration). To login, please use the cubicweb administrator login/psswd you +defined when you created the instance. + +To shutdown the instance, Crtl-C in the terminal window is enough. +If you did not use the option `-D`, then type :: + + cubicweb-ctl stop myinstance + +This is it! All is settled down to start developping your data model... + + +Usage of `cubicweb-liveserver` +`````````````````````````````` + +To quickly test a new cube, you can also use the script `cubicweb-liveserver` +which allows to create an application in memory (use of SQLite database by +default) and make it accessible through a web server :: + + cubicweb-ctl live-server mycube + +or by using an existing database (SQLite or Postgres):: + + cubicweb-ctl live-server -s myfile_sources mycube + diff -r b7494ff85e16 -r 183da3addf0e doc/book/en/C020-site-config.en.txt --- a/doc/book/en/C020-site-config.en.txt Wed Apr 22 09:45:54 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -.. -*- coding: utf-8 -*- - -User interface for web site configuration -========================================= - -.. image:: images/lax-book.03-site-config-panel.en.png - -This panel allows you to configure the appearance of your application site. -Six menus are available and we will go through each of them to explain how -to use them. - -Navigation -~~~~~~~~~~ -This menu provides you a way to adjust some navigation options depending on -your needs, such as the number of entities to display by page of results. -Follows the detailled list of available options : - -* navigation.combobox-limit : maximum number of entities to display in related - combo box (sample format: 23) -* navigation.page-size : maximum number of objects displayed by page of results - (sample format: 23) -* navigation.related-limit : maximum number of related entities to display in - the primary view (sample format: 23) -* navigation.short-line-size : maximum number of characters in short description - (sample format: 23) - -UI -~~ -This menu provides you a way to customize the user interface settings such as -date format or encoding in the produced html. -Follows the detailled list of available options : - -* ui.date-format : how to format date in the ui ("man strftime" for format description) -* ui.datetime-format : how to format date and time in the ui ("man strftime" for format - description) -* ui.default-text-format : default text format for rich text fields. -* ui.encoding : user interface encoding -* ui.fckeditor :should html fields being edited using fckeditor (a HTML WYSIWYG editor). - You should also select text/html as default text format to actually get fckeditor. -* ui.float-format : how to format float numbers in the ui -* ui.language : language of the user interface -* ui.main-template : id of main template used to render pages -* ui.site-title : site title, which is displayed right next to the logo in the header -* ui.time-format : how to format time in the ui ("man strftime" for format description) - - -Actions -~~~~~~~ -This menu provides a way to configure the context in which you expect the actions -to be displayed to the user and if you want the action to be visible or not. -You must have notice that when you view a list of entities, an action box is -available on the left column which display some actions as well as a drop-down -menu for more actions. - -The context available are : - -* mainactions : actions listed in the left box -* moreactions : actions listed in the `more` menu of the left box -* addrelated : add actions listed in the left box -* useractions : actions listed in the first section of drop-down menu - accessible from the right corner user login link -* siteactions : actions listed in the second section of drop-down menu - accessible from the right corner user login link -* hidden : select this to hide the specific action - -Boxes -~~~~~ -The application has already a pre-defined set of boxes you can use right away. -This configuration section allows you to place those boxes where you want in the -application interface to customize it. - -The available boxes are : - -* actions box : box listing the applicable actions on the displayed data - -* boxes_blog_archives_box : box listing the blog archives - -* possible views box : box listing the possible views for the displayed data - -* rss box : RSS icon to get displayed data as a RSS thread - -* search box : search box - -* startup views box : box listing the configuration options available for - the application site, such as `Preferences` and `Site Configuration` - -Components -~~~~~~~~~~ -[WRITE ME] - -Contextual components -~~~~~~~~~~~~~~~~~~~~~ -[WRITE ME] - diff -r b7494ff85e16 -r 183da3addf0e doc/book/en/C030-instance-config.en.txt --- a/doc/book/en/C030-instance-config.en.txt Wed Apr 22 09:45:54 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,163 +0,0 @@ -.. -*- coding: utf-8 -*- - - -Configure an instance -===================== - -While creating an instance, a configuration file is generated in:: - - $ (CW_REGISTRY) / / .conf - -For example:: - - /etc/cubicweb.d/JPL/all-in-one.conf - -It is a simple text file format INI. In the following description, -each option name is prefixed with its own section and followed by its -default value if necessary, e.g. "`
.