--- 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):
--- 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):
--- 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': '<log level>',
+ '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
--- 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:
--- 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()
--- 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'
--- 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 <modname>: <modpath> 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 <modname> 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'))
--- 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 <action>_on_new on relations. <action> 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)
--- 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)
--- 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)
--- 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'[<a href="%s">%s</a>]' % (self.build_url(rql=rql),
self.req._('see them all')))
self.w(u'</div>')
+
+## 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')