# HG changeset patch # User Sylvain Thénault # Date 1249289611 -7200 # Node ID 48cd71bdb5cdc6e00a5dc981046db1c519bc22f5 # Parent 18aec79ec3a32c5c80c5a28b78e12136a7e30b7f# Parent 6512522860aa2510d90ac87ec6fb8c01964cb059 merge diff -r 18aec79ec3a3 -r 48cd71bdb5cd _exceptions.py --- a/_exceptions.py Mon Aug 03 10:50:57 2009 +0200 +++ b/_exceptions.py Mon Aug 03 10:53:31 2009 +0200 @@ -129,6 +129,9 @@ class UnknownProperty(RegistryException): """property found in database but unknown in registry""" +class RegistryOutOfDate(RegistryException): + """raised when a source file modification is detected""" + # query exception ############################################################# class QueryError(CubicWebRuntimeError): diff -r 18aec79ec3a3 -r 48cd71bdb5cd cwconfig.py --- a/cwconfig.py Mon Aug 03 10:50:57 2009 +0200 +++ b/cwconfig.py Mon Aug 03 10:53:31 2009 +0200 @@ -777,7 +777,7 @@ return self._logging_initialized = True CubicWebNoAppConfiguration.init_log(self, logthreshold, debug, - logfile=self.get('log-file')) + logfile=self.get('log-file')) # read a config file if it exists logconfig = join(self.apphome, 'logging.conf') if exists(logconfig): diff -r 18aec79ec3a3 -r 48cd71bdb5cd cwctl.py --- a/cwctl.py Mon Aug 03 10:50:57 2009 +0200 +++ b/cwctl.py Mon Aug 03 10:53:31 2009 +0200 @@ -382,6 +382,11 @@ 'default': None, 'help': 'profile code and use the specified file to store stats', }), + ('loglevel', + {'short': 'l', 'type' : 'choice', 'metavar': '', + 'default': None, 'choices': ('debug', 'info', 'warning', 'error'), + 'help': 'debug if -D is set, error otherwise', + }), ) def start_instance(self, appid): @@ -390,7 +395,12 @@ # without all options defined debug = self.get('debug') force = self.get('force') + loglevel = self.get('loglevel') config = cwcfg.config_for(appid) + if loglevel is not None: + loglevel = 'LOG_%s' % loglevel.upper() + config.global_set_option('log-threshold', loglevel) + config.init_log(loglevel, debug=debug, force=True) if self.get('profile'): config.global_set_option('profile', self.config.profile) helper = self.config_helper(config, cmdname='start') @@ -399,16 +409,7 @@ msg = "%s seems to be running. Remove %s by hand if necessary or use \ the --force option." raise ExecutionError(msg % (appid, pidf)) - command = helper.start_command(config, debug) - if debug: - print "starting server with command :" - print command - if system(command): - print 'an error occured while starting the instance, not started' - print - return False - if not debug: - print '-> instance %s started.' % appid + helper.start_command(config, debug) return True diff -r 18aec79ec3a3 -r 48cd71bdb5cd cwvreg.py --- a/cwvreg.py Mon Aug 03 10:50:57 2009 +0200 +++ b/cwvreg.py Mon Aug 03 10:53:31 2009 +0200 @@ -14,7 +14,8 @@ from rql import RQLHelper from cubicweb import (ETYPE_NAME_MAP, Binary, UnknownProperty, UnknownEid, - ObjectNotFound, NoSelectableObject, RegistryNotFound) + ObjectNotFound, NoSelectableObject, RegistryNotFound, + RegistryOutOfDate) from cubicweb.vregistry import VRegistry, Registry from cubicweb.rtags import RTAGS @@ -279,6 +280,15 @@ def register_objects(self, path, force_reload=None): """overriden to remove objects requiring a missing interface""" + try: + self._register_objects(path, force_reload) + except RegistryOutOfDate: + # modification detected, reset and reload + self.reset() + self._register_objects(path, force_reload) + + def _register_objects(self, path, force_reload=None): + """overriden to remove objects requiring a missing interface""" extrapath = {} for cubesdir in self.config.cubes_search_path(): if cubesdir != self.config.CUBES_DIR: diff -r 18aec79ec3a3 -r 48cd71bdb5cd etwist/server.py --- a/etwist/server.py Mon Aug 03 10:50:57 2009 +0200 +++ b/etwist/server.py Mon Aug 03 10:53:31 2009 +0200 @@ -8,12 +8,15 @@ __docformat__ = "restructuredtext en" import sys +import os import select from time import mktime from datetime import date, timedelta from urlparse import urlsplit, urlunsplit +import hotshot from twisted.application import service, strports +from twisted.scripts._twistd_unix import daemonize from twisted.internet import reactor, task, threads from twisted.internet.defer import maybeDeferred from twisted.web2 import channel, http, server, iweb @@ -268,35 +271,6 @@ content = self.appli.need_login_content(req) return http.Response(code, req.headers_out, content) - -# This part gets run when you run this file via: "twistd -noy demo.py" -def main(appid, cfgname): - """Starts an cubicweb twisted server for an instance - - appid: instance's identifier - cfgname: name of the configuration to use (twisted or all-in-one) - """ - from cubicweb.cwconfig import CubicWebConfiguration - from cubicweb.etwist import twconfig # trigger configuration registration - config = CubicWebConfiguration.config_for(appid, cfgname) - # XXX why calling init_available_cubes here ? - config.init_available_cubes() - # create the site and application objects - if '-n' in sys.argv: # debug mode - cubicweb = CubicWebRootResource(config, debug=True) - else: - cubicweb = CubicWebRootResource(config) - #toplevel = vhost.VHostURIRewrite(base_url, cubicweb) - toplevel = cubicweb - website = server.Site(toplevel) - application = service.Application("cubicweb") - # serve it via standard HTTP on port set in the configuration - s = strports.service('tcp:%04d' % (config['port'] or 8080), - channel.HTTPFactory(website)) - s.setServiceParent(application) - return application - - from twisted.python import failure from twisted.internet import defer from twisted.web2 import fileupload @@ -378,3 +352,22 @@ ocount = sorted(ocount.items(), key=lambda x: x[1], reverse=True)[:20] pprint(ocount) print 'UNREACHABLE', gc.garbage + +def run(config, debug): + # create the site + root_resource = CubicWebRootResource(config, debug) + website = server.Site(root_resource) + # serve it via standard HTTP on port set in the configuration + port = config['port'] or 8080 + reactor.listenTCP(port, channel.HTTPFactory(website)) + baseurl = config['base-url'] or config.default_base_url() + print "-> Instance started on", baseurl + if not debug: + daemonize() + if config['pid-file']: + file(config['pid-file'], 'w').write(str(os.getpid())) + if config['profile']: + prof = hotshot.Profile(config['profile']) + prof.runcall(reactor.run) + else: + reactor.run() diff -r 18aec79ec3a3 -r 48cd71bdb5cd etwist/twctl.py --- a/etwist/twctl.py Mon Aug 03 10:50:57 2009 +0200 +++ b/etwist/twctl.py Mon Aug 03 10:53:31 2009 +0200 @@ -10,50 +10,17 @@ from cubicweb import underline_title from cubicweb.toolsutils import CommandHandler -from cubicweb.web.webctl import WebCreateHandler # trigger configuration registration import cubicweb.etwist.twconfig # pylint: disable-msg=W0611 - -class TWCreateHandler(WebCreateHandler): - cfgname = 'twisted' - - def bootstrap(self, cubes, inputlevel=0): - """bootstrap this configuration""" - print '\n'+underline_title('Configuring Twisted') - mainpyfile = self.config.server_file() - mainpy = open(mainpyfile, 'w') - mainpy.write(''' -from cubicweb.etwist import server -application = server.main(%r, %r) -''' % (self.config.appid, self.config.name)) - mainpy.close() - print '-> generated %s' % mainpyfile - super(TWCreateHandler, self).bootstrap(cubes, inputlevel) - - class TWStartHandler(CommandHandler): cmdname = 'start' cfgname = 'twisted' def start_command(self, config, debug): - command = ['%s `which twistd`' % sys.executable] - for ctl_opt, server_opt in (('pid-file', 'pidfile'), - ('uid', 'uid'), - ('log-file', 'logfile',)): - value = config[ctl_opt] - if not value or (debug and ctl_opt == 'log-file'): - continue - command.append('--%s %s' % (server_opt, value)) - if debug: - command.append('-n') - if config['profile']: - command.append('-p %s --savestats' % config['profile']) - command.append('-oy') - command.append(self.config.server_file()) - return ' '.join(command) - + from cubicweb.etwist import server + server.run(config, debug) class TWStopHandler(CommandHandler): cmdname = 'stop' @@ -63,7 +30,7 @@ try: from cubicweb.server import serverctl - class AllInOneCreateHandler(serverctl.RepositoryCreateHandler, TWCreateHandler): + class AllInOneCreateHandler(serverctl.RepositoryCreateHandler): """configuration to get an instance running in a twisted web server integrating a repository server in the same process """ @@ -72,7 +39,6 @@ def bootstrap(self, cubes, inputlevel=0): """bootstrap this configuration""" serverctl.RepositoryCreateHandler.bootstrap(self, cubes, inputlevel) - TWCreateHandler.bootstrap(self, cubes, inputlevel) class AllInOneStartHandler(TWStartHandler): cmdname = 'start' diff -r 18aec79ec3a3 -r 48cd71bdb5cd vregistry.py --- a/vregistry.py Mon Aug 03 10:50:57 2009 +0200 +++ b/vregistry.py Mon Aug 03 10:53:31 2009 +0200 @@ -31,8 +31,15 @@ from logilab.common.deprecation import deprecated from cubicweb import CW_SOFTWARE_ROOT, set_log_methods -from cubicweb import RegistryNotFound, ObjectNotFound, NoSelectableObject +from cubicweb import (RegistryNotFound, ObjectNotFound, NoSelectableObject, + RegistryOutOfDate) +# XXX depending on cubicweb.web is ugly, we should deal with uicfg +# reset with a good old event / callback system +try: + from cubicweb.web import uicfg +except ImportError: # cubicweb.web not installed + uicfg = None def _toload_info(path, extrapath, _toload=None): """return a dictionary of : and an ordered list of @@ -282,6 +289,8 @@ def reset(self): self.clear() self._lastmodifs = {} + if uicfg is not None: + reload(uicfg) def __getitem__(self, name): """return the registry (dictionary of class objects) associated to @@ -372,7 +381,6 @@ vname = obj.__class__.__name__ self.debug('registered vobject %s in registry %s with id %s', vname, registryname, oid) - # automatic reloading management self._loadedmods[obj.__module__]['%s.%s' % (obj.__module__, oid)] = obj def unregister(self, obj, registryname=None): @@ -386,6 +394,9 @@ def init_registration(self, path, extrapath=None): # compute list of all modules that have to be loaded self._toloadmods, filemods = _toload_info(path, extrapath) + # XXX is _loadedmods still necessary ? It seems like it's useful + # to avoid loading same module twice, especially with the + # _load_ancestors_then_object logic but this needs to be checked self._loadedmods = {} return filemods @@ -417,7 +428,7 @@ return change def load_file(self, filepath, modname, force_reload=False): - """load visual objects from a python file""" + """load app objects from a python file""" from logilab.common.modutils import load_module_from_name if modname in self._loadedmods: return @@ -433,22 +444,12 @@ # only load file if it was modified if modified_on <= self._lastmodifs[filepath]: return - # if it was modified, unregister all exisiting objects - # from this module, and keep track of what was unregistered - unregistered = self.unregister_module_vobjects(modname) - else: - unregistered = None + # if it was modified, raise RegistryOutOfDate to reload everything + self.info('File %s changed since last visit', filepath) + raise RegistryOutOfDate() # load the module module = load_module_from_name(modname, use_sys=not force_reload) self.load_module(module) - # if something was unregistered, we need to update places where it was - # referenced - if unregistered: - # oldnew_mapping = {} - registered = self._loadedmods[modname] - oldnew_mapping = dict((unregistered[name], registered[name]) - for name in unregistered if name in registered) - self.update_registered_subclasses(oldnew_mapping) self._lastmodifs[filepath] = modified_on return True @@ -510,68 +511,6 @@ return self.register(cls) - def unregister_module_vobjects(self, modname): - """removes registered objects coming from a given module - - returns a dictionnary classid/class of all classes that will need - to be updated after reload (i.e. vobjects referencing classes defined - in the module) - """ - unregistered = {} - # browse each registered object - for registry, objdict in self.items(): - for oid, objects in objdict.items(): - for obj in objects[:]: - objname = obj.classid() - # if the vobject is defined in this module, remove it - if objname.startswith(modname): - unregistered[objname] = obj - objects.remove(obj) - self.debug('unregistering %s in %s registry', - objname, registry) - # if not, check if the vobject can be found in baseclasses - # (because we also want subclasses to be updated) - else: - if not isinstance(obj, type): - obj = obj.__class__ - for baseclass in obj.__bases__: - if hasattr(baseclass, 'classid'): - baseclassid = baseclass.classid() - if baseclassid.startswith(modname): - unregistered[baseclassid] = baseclass - # update oid entry - if objects: - objdict[oid] = objects - else: - del objdict[oid] - return unregistered - - def update_registered_subclasses(self, oldnew_mapping): - """updates subclasses of re-registered vobjects - - if baseviews.PrimaryView is changed, baseviews.py will be reloaded - automatically and the new version of PrimaryView will be registered. - But all existing subclasses must also be notified of this change, and - that's what this method does - - :param oldnew_mapping: a dict mapping old version of a class to - the new version - """ - # browse each registered object - for objdict in self.values(): - for objects in objdict.values(): - for obj in objects: - if not isinstance(obj, type): - obj = obj.__class__ - # build new baseclasses tuple - newbases = tuple(oldnew_mapping.get(baseclass, baseclass) - for baseclass in obj.__bases__) - # update obj's baseclasses tuple (__bases__) if needed - if newbases != obj.__bases__: - self.debug('updating %s.%s base classes', - obj.__module__, obj.__name__) - obj.__bases__ = newbases - # init logging set_log_methods(VObject, getLogger('cubicweb.appobject')) set_log_methods(VRegistry, getLogger('cubicweb.vreg')) diff -r 18aec79ec3a3 -r 48cd71bdb5cd web/uicfg.py --- a/web/uicfg.py Mon Aug 03 10:50:57 2009 +0200 +++ b/web/uicfg.py Mon Aug 03 10:53:31 2009 +0200 @@ -102,21 +102,6 @@ init_primaryview_section, frozenset(('attributes', 'relations', 'sideboxes', 'hidden'))) -for rtype in ('eid', 'creation_date', 'modification_date', 'cwuri', - 'is', 'is_instance_of', 'identity', - 'owned_by', 'created_by', - 'in_state', 'wf_info_for', 'require_permission', - 'from_entity', 'to_entity', - 'see_also'): - primaryview_section.tag_subject_of(('*', rtype, '*'), 'hidden') - primaryview_section.tag_object_of(('*', rtype, '*'), 'hidden') -primaryview_section.tag_subject_of(('*', 'use_email', '*'), 'attributes') -primaryview_section.tag_subject_of(('*', 'primary_email', '*'), 'hidden') - -for attr in ('name', 'final'): - primaryview_section.tag_attribute(('CWEType', attr), 'hidden') -for attr in ('name', 'final', 'symetric', 'inlined'): - primaryview_section.tag_attribute(('CWRType', attr), 'hidden') class DisplayCtrlRelationTags(RelationTagsDict): @@ -201,62 +186,17 @@ autoform_section = RelationTags('autoform_section', init_autoform_section, set(('primary', 'secondary', 'generic', 'metadata', 'generated'))) -# use primary and not generated for eid since it has to be an hidden -autoform_section.tag_attribute(('*', 'eid'), 'primary') -autoform_section.tag_attribute(('*', 'description'), 'secondary') -autoform_section.tag_attribute(('*', 'creation_date'), 'metadata') -autoform_section.tag_attribute(('*', 'modification_date'), 'metadata') -autoform_section.tag_attribute(('*', 'cwuri'), 'metadata') -autoform_section.tag_attribute(('*', 'has_text'), 'generated') -autoform_section.tag_subject_of(('*', 'in_state', '*'), 'primary') -autoform_section.tag_subject_of(('*', 'owned_by', '*'), 'metadata') -autoform_section.tag_subject_of(('*', 'created_by', '*'), 'metadata') -autoform_section.tag_subject_of(('*', 'is', '*'), 'generated') -autoform_section.tag_object_of(('*', 'is', '*'), 'generated') -autoform_section.tag_subject_of(('*', 'is_instance_of', '*'), 'generated') -autoform_section.tag_object_of(('*', 'is_instance_of', '*'), 'generated') -autoform_section.tag_subject_of(('*', 'identity', '*'), 'generated') -autoform_section.tag_object_of(('*', 'identity', '*'), 'generated') -autoform_section.tag_subject_of(('*', 'require_permission', '*'), 'generated') -autoform_section.tag_subject_of(('*', 'wf_info_for', '*'), 'generated') -autoform_section.tag_object_of(('*', 'wf_info_for', '*'), 'generated') -autoform_section.tag_subject_of(('*', 'for_user', '*'), 'generated') -autoform_section.tag_object_of(('*', 'for_user', '*'), 'generated') -autoform_section.tag_subject_of(('CWPermission', 'require_group', '*'), 'primary') -autoform_section.tag_attribute(('CWEType', 'final'), 'generated') -autoform_section.tag_attribute(('CWRType', 'final'), 'generated') -autoform_section.tag_attribute(('CWUser', 'firstname'), 'secondary') -autoform_section.tag_attribute(('CWUser', 'surname'), 'secondary') -autoform_section.tag_attribute(('CWUser', 'last_login_time'), 'metadata') -autoform_section.tag_subject_of(('CWUser', 'in_group', '*'), 'primary') -autoform_section.tag_object_of(('*', 'owned_by', 'CWUser'), 'generated') -autoform_section.tag_object_of(('*', 'created_by', 'CWUser'), 'generated') -autoform_section.tag_object_of(('*', 'bookmarked_by', 'CWUser'), 'metadata') -autoform_section.tag_attribute(('Bookmark', 'path'), 'primary') -autoform_section.tag_subject_of(('*', 'use_email', '*'), 'generated') # inlined actually -autoform_section.tag_subject_of(('*', 'primary_email', '*'), 'generic') - # relations'field class autoform_field = RelationTags('autoform_field') # relations'field explicit kwargs (given to field's __init__) autoform_field_kwargs = RelationTagsDict() -autoform_field_kwargs.tag_attribute(('RQLExpression', 'expression'), - {'widget': formwidgets.TextInput}) -autoform_field_kwargs.tag_attribute(('Bookmark', 'path'), - {'widget': formwidgets.TextInput}) - - # inlined view flag for non final relations: when True for an entry, the # entity(ies) at the other end of the relation will be editable from the # form of the edited entity autoform_is_inlined = RelationTagsBool('autoform_is_inlined') -autoform_is_inlined.tag_subject_of(('*', 'use_email', '*'), True) -autoform_is_inlined.tag_subject_of(('CWRelation', 'relation_type', '*'), True) -autoform_is_inlined.tag_subject_of(('CWRelation', 'from_entity', '*'), True) -autoform_is_inlined.tag_subject_of(('CWRelation', 'to_entity', '*'), True) # set of tags of the form _on_new on relations. is a @@ -277,28 +217,4 @@ actionbox_appearsin_addmenu = RelationTagsBool('actionbox_appearsin_addmenu', init_actionbox_appearsin_addmenu) -actionbox_appearsin_addmenu.tag_subject_of(('*', 'is', '*'), False) -actionbox_appearsin_addmenu.tag_object_of(('*', 'is', '*'), False) -actionbox_appearsin_addmenu.tag_subject_of(('*', 'is_instance_of', '*'), False) -actionbox_appearsin_addmenu.tag_object_of(('*', 'is_instance_of', '*'), False) -actionbox_appearsin_addmenu.tag_subject_of(('*', 'identity', '*'), False) -actionbox_appearsin_addmenu.tag_object_of(('*', 'identity', '*'), False) -actionbox_appearsin_addmenu.tag_subject_of(('*', 'owned_by', '*'), False) -actionbox_appearsin_addmenu.tag_subject_of(('*', 'created_by', '*'), False) -actionbox_appearsin_addmenu.tag_subject_of(('*', 'require_permission', '*'), False) -actionbox_appearsin_addmenu.tag_subject_of(('*', 'wf_info_for', '*'), False) -actionbox_appearsin_addmenu.tag_object_of(('*', 'wf_info_for', '*'), False) -actionbox_appearsin_addmenu.tag_object_of(('*', 'state_of', 'CWEType'), True) -actionbox_appearsin_addmenu.tag_object_of(('*', 'transition_of', 'CWEType'), True) -actionbox_appearsin_addmenu.tag_object_of(('*', 'relation_type', 'CWRType'), True) -actionbox_appearsin_addmenu.tag_object_of(('*', 'from_entity', 'CWEType'), False) -actionbox_appearsin_addmenu.tag_object_of(('*', 'to_entity', 'CWEType'), False) -actionbox_appearsin_addmenu.tag_object_of(('*', 'in_group', 'CWGroup'), True) -actionbox_appearsin_addmenu.tag_object_of(('*', 'owned_by', 'CWUser'), False) -actionbox_appearsin_addmenu.tag_object_of(('*', 'created_by', 'CWUser'), False) -actionbox_appearsin_addmenu.tag_object_of(('*', 'bookmarked_by', 'CWUser'), True) -actionbox_appearsin_addmenu.tag_subject_of(('Transition', 'destination_state', '*'), True) -actionbox_appearsin_addmenu.tag_object_of(('*', 'allowed_transition', 'Transition'), True) -actionbox_appearsin_addmenu.tag_object_of(('*', 'destination_state', 'State'), True) -actionbox_appearsin_addmenu.tag_subject_of(('State', 'allowed_transition', '*'), True) diff -r 18aec79ec3a3 -r 48cd71bdb5cd web/views/actions.py --- a/web/views/actions.py Mon Aug 03 10:50:57 2009 +0200 +++ b/web/views/actions.py Mon Aug 03 10:53:31 2009 +0200 @@ -15,6 +15,7 @@ authenticated_user, match_user_groups, match_search_state, has_permission, has_add_permission, ) +from cubicweb.web import uicfg from cubicweb.web.action import Action from cubicweb.web.views import linksearch_select_url, vid_from_rset from cubicweb.web.views.autoform import AutomaticEntityForm @@ -297,3 +298,30 @@ from cubicweb.web.views.bookmark import FollowAction FollowAction = class_moved(FollowAction) +## default actions ui configuration ########################################### + +addmenu = uicfg.actionbox_appearsin_addmenu +addmenu.tag_subject_of(('*', 'is', '*'), False) +addmenu.tag_object_of(('*', 'is', '*'), False) +addmenu.tag_subject_of(('*', 'is_instance_of', '*'), False) +addmenu.tag_object_of(('*', 'is_instance_of', '*'), False) +addmenu.tag_subject_of(('*', 'identity', '*'), False) +addmenu.tag_object_of(('*', 'identity', '*'), False) +addmenu.tag_subject_of(('*', 'owned_by', '*'), False) +addmenu.tag_subject_of(('*', 'created_by', '*'), False) +addmenu.tag_subject_of(('*', 'require_permission', '*'), False) +addmenu.tag_subject_of(('*', 'wf_info_for', '*'), False) +addmenu.tag_object_of(('*', 'wf_info_for', '*'), False) +addmenu.tag_object_of(('*', 'state_of', 'CWEType'), True) +addmenu.tag_object_of(('*', 'transition_of', 'CWEType'), True) +addmenu.tag_object_of(('*', 'relation_type', 'CWRType'), True) +addmenu.tag_object_of(('*', 'from_entity', 'CWEType'), False) +addmenu.tag_object_of(('*', 'to_entity', 'CWEType'), False) +addmenu.tag_object_of(('*', 'in_group', 'CWGroup'), True) +addmenu.tag_object_of(('*', 'owned_by', 'CWUser'), False) +addmenu.tag_object_of(('*', 'created_by', 'CWUser'), False) +addmenu.tag_object_of(('*', 'bookmarked_by', 'CWUser'), True) +addmenu.tag_subject_of(('Transition', 'destination_state', '*'), True) +addmenu.tag_object_of(('*', 'allowed_transition', 'Transition'), True) +addmenu.tag_object_of(('*', 'destination_state', 'State'), True) +addmenu.tag_subject_of(('State', 'allowed_transition', '*'), True) diff -r 18aec79ec3a3 -r 48cd71bdb5cd web/views/autoform.py --- a/web/views/autoform.py Mon Aug 03 10:50:57 2009 +0200 +++ b/web/views/autoform.py Mon Aug 03 10:53:31 2009 +0200 @@ -14,7 +14,7 @@ from cubicweb.web import stdmsgs, uicfg from cubicweb.web.form import FieldNotFound from cubicweb.web.formfields import guess_field -from cubicweb.web.formwidgets import Button, SubmitButton +from cubicweb.web import formwidgets from cubicweb.web.views import forms, editforms @@ -33,9 +33,9 @@ cwtarget = 'eformframe' cssclass = 'entityForm' copy_nav_params = True - form_buttons = [SubmitButton(), - Button(stdmsgs.BUTTON_APPLY, cwaction='apply'), - Button(stdmsgs.BUTTON_CANCEL, cwaction='cancel')] + form_buttons = [formwidgets.SubmitButton(), + formwidgets.Button(stdmsgs.BUTTON_APPLY, cwaction='apply'), + formwidgets.Button(stdmsgs.BUTTON_CANCEL, cwaction='cancel')] attrcategories = ('primary', 'secondary') # class attributes below are actually stored in the uicfg module since we # don't want them to be reloaded @@ -307,3 +307,51 @@ def etype_relation_field(etype, rtype, role='subject'): eschema = AutomaticEntityForm.schema.eschema(etype) return AutomaticEntityForm.field_by_name(rtype, role, eschema) + + +## default form ui configuration ############################################## + +# use primary and not generated for eid since it has to be an hidden +uicfg.autoform_section.tag_attribute(('*', 'eid'), 'primary') +uicfg.autoform_section.tag_attribute(('*', 'description'), 'secondary') +uicfg.autoform_section.tag_attribute(('*', 'creation_date'), 'metadata') +uicfg.autoform_section.tag_attribute(('*', 'modification_date'), 'metadata') +uicfg.autoform_section.tag_attribute(('*', 'cwuri'), 'metadata') +uicfg.autoform_section.tag_attribute(('*', 'has_text'), 'generated') +uicfg.autoform_section.tag_subject_of(('*', 'in_state', '*'), 'primary') +uicfg.autoform_section.tag_subject_of(('*', 'owned_by', '*'), 'metadata') +uicfg.autoform_section.tag_subject_of(('*', 'created_by', '*'), 'metadata') +uicfg.autoform_section.tag_subject_of(('*', 'is', '*'), 'generated') +uicfg.autoform_section.tag_object_of(('*', 'is', '*'), 'generated') +uicfg.autoform_section.tag_subject_of(('*', 'is_instance_of', '*'), 'generated') +uicfg.autoform_section.tag_object_of(('*', 'is_instance_of', '*'), 'generated') +uicfg.autoform_section.tag_subject_of(('*', 'identity', '*'), 'generated') +uicfg.autoform_section.tag_object_of(('*', 'identity', '*'), 'generated') +uicfg.autoform_section.tag_subject_of(('*', 'require_permission', '*'), 'generated') +uicfg.autoform_section.tag_subject_of(('*', 'wf_info_for', '*'), 'generated') +uicfg.autoform_section.tag_object_of(('*', 'wf_info_for', '*'), 'generated') +uicfg.autoform_section.tag_subject_of(('*', 'for_user', '*'), 'generated') +uicfg.autoform_section.tag_object_of(('*', 'for_user', '*'), 'generated') +uicfg.autoform_section.tag_subject_of(('CWPermission', 'require_group', '*'), 'primary') +uicfg.autoform_section.tag_attribute(('CWEType', 'final'), 'generated') +uicfg.autoform_section.tag_attribute(('CWRType', 'final'), 'generated') +uicfg.autoform_section.tag_attribute(('CWUser', 'firstname'), 'secondary') +uicfg.autoform_section.tag_attribute(('CWUser', 'surname'), 'secondary') +uicfg.autoform_section.tag_attribute(('CWUser', 'last_login_time'), 'metadata') +uicfg.autoform_section.tag_subject_of(('CWUser', 'in_group', '*'), 'primary') +uicfg.autoform_section.tag_object_of(('*', 'owned_by', 'CWUser'), 'generated') +uicfg.autoform_section.tag_object_of(('*', 'created_by', 'CWUser'), 'generated') +uicfg.autoform_section.tag_object_of(('*', 'bookmarked_by', 'CWUser'), 'metadata') +uicfg.autoform_section.tag_attribute(('Bookmark', 'path'), 'primary') +uicfg.autoform_section.tag_subject_of(('*', 'use_email', '*'), 'generated') # inlined actually +uicfg.autoform_section.tag_subject_of(('*', 'primary_email', '*'), 'generic') + +uicfg.autoform_field_kwargs.tag_attribute(('RQLExpression', 'expression'), + {'widget': formwidgets.TextInput}) +uicfg.autoform_field_kwargs.tag_attribute(('Bookmark', 'path'), + {'widget': formwidgets.TextInput}) + +uicfg.autoform_is_inlined.tag_subject_of(('*', 'use_email', '*'), True) +uicfg.autoform_is_inlined.tag_subject_of(('CWRelation', 'relation_type', '*'), True) +uicfg.autoform_is_inlined.tag_subject_of(('CWRelation', 'from_entity', '*'), True) +uicfg.autoform_is_inlined.tag_subject_of(('CWRelation', 'to_entity', '*'), True) diff -r 18aec79ec3a3 -r 48cd71bdb5cd web/views/primary.py --- a/web/views/primary.py Mon Aug 03 10:50:57 2009 +0200 +++ b/web/views/primary.py Mon Aug 03 10:53:31 2009 +0200 @@ -224,3 +224,21 @@ self.w(u'[%s]' % (self.build_url(rql=rql), self.req._('see them all'))) self.w(u'') + +## default primary ui configuration ########################################### + +for rtype in ('eid', 'creation_date', 'modification_date', 'cwuri', + 'is', 'is_instance_of', 'identity', + 'owned_by', 'created_by', + 'in_state', 'wf_info_for', 'require_permission', + 'from_entity', 'to_entity', + 'see_also'): + uicfg.primaryview_section.tag_subject_of(('*', rtype, '*'), 'hidden') + uicfg.primaryview_section.tag_object_of(('*', rtype, '*'), 'hidden') +uicfg.primaryview_section.tag_subject_of(('*', 'use_email', '*'), 'attributes') +uicfg.primaryview_section.tag_subject_of(('*', 'primary_email', '*'), 'hidden') + +for attr in ('name', 'final'): + uicfg.primaryview_section.tag_attribute(('CWEType', attr), 'hidden') +for attr in ('name', 'final', 'symetric', 'inlined'): + uicfg.primaryview_section.tag_attribute(('CWRType', attr), 'hidden')