# HG changeset patch # User Sylvain Thénault # Date 1244207360 -7200 # Node ID 7ef12c03447cd337f08eafb48b58f1391755c8a3 # Parent 0a0cbccafcb530c839191cd066c60273e1d45a29 nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors) diff -r 0a0cbccafcb5 -r 7ef12c03447c appobject.py --- a/appobject.py Fri Jun 05 15:06:55 2009 +0200 +++ b/appobject.py Fri Jun 05 15:09:20 2009 +0200 @@ -151,7 +151,8 @@ # try to get page boundaries from the navigation component # XXX we should probably not have a ref to this component here (eg in # cubicweb.common) - nav = self.vreg.select_component('navigation', self.req, self.rset) + nav = self.vreg.select_object('components', 'navigation', self.req, + rset=self.rset) if nav: start, stop = nav.page_boundaries() rql = self._limit_offset_rql(stop - start, start) @@ -189,7 +190,8 @@ def view(self, __vid, rset=None, __fallback_vid=None, **kwargs): """shortcut to self.vreg.view method avoiding to pass self.req""" - return self.vreg.view(__vid, self.req, rset, __fallback_vid, **kwargs) + return self.vreg.render(__vid, self.req, __fallback_vid, rset=rset, + **kwargs) def initialize_varmaker(self): varmaker = self.req.get_page_data('rql_varmaker') diff -r 0a0cbccafcb5 -r 7ef12c03447c common/mixins.py --- a/common/mixins.py Fri Jun 05 15:06:55 2009 +0200 +++ b/common/mixins.py Fri Jun 05 15:09:20 2009 +0200 @@ -237,7 +237,7 @@ @obsolete('use EntityFieldsForm.subject_in_state_vocabulary') def subject_in_state_vocabulary(self, rschema, limit=None): - form = self.vreg.select_object('forms', 'edition', self.req, entity=self) + form = self.vreg.select('forms', 'edition', self.req, entity=self) return form.subject_in_state_vocabulary(rschema, limit) diff -r 0a0cbccafcb5 -r 7ef12c03447c cwvreg.py --- a/cwvreg.py Fri Jun 05 15:06:55 2009 +0200 +++ b/cwvreg.py Fri Jun 05 15:09:20 2009 +0200 @@ -9,6 +9,7 @@ _ = unicode from logilab.common.decorators import cached, clear_cache +from logilab.common.deprecation import obsolete from rql import RQLHelper @@ -39,7 +40,26 @@ class CubicWebRegistry(VRegistry): - """extend the generic VRegistry with some cubicweb specific stuff""" + """Central registry for the cubicweb application, extending the generic + VRegistry with some cubicweb specific stuff. + + This is one of the central object in cubicweb application, coupling + dynamically loaded objects with the schema and the configuration objects. + + It specializes the VRegistry by adding some convenience methods to access to + stored objects. Currently we have the following registries of objects known + by the web application (library may use some others additional registries): + + * etypes + * views + * components + * actions + * forms + * formrenderers + * controllers, which are directly plugged into the application + object to handle request publishing XXX to merge with views + * contentnavigation XXX to merge with components? to kill? + """ def __init__(self, config, debug=None, initlog=True): if initlog: @@ -170,7 +190,7 @@ """ etype = str(etype) if etype == 'Any': - return self.select(self.registry_objects('etypes', 'Any'), 'Any') + return self.select('etypes', 'Any', 'Any') eschema = self.schema.eschema(etype) baseschemas = [eschema] + eschema.ancestors() # browse ancestors from most specific to most generic and @@ -181,42 +201,47 @@ except KeyError: btype = str(baseschema) try: - cls = self.select(self.registry_objects('etypes', btype), etype) + cls = self.select('etypes', btype, etype) break except ObjectNotFound: pass else: # no entity class for any of the ancestors, fallback to the default # one - cls = self.select(self.registry_objects('etypes', 'Any'), etype) + cls = self.select('etypes', 'Any', etype) 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 + def render(self, __oid, req, __fallback_oid=None, __registry='views', + rset=None, **kwargs): + """select object, or fallback object if specified and the first one + isn't selectable, then render it """ - objclss = self.registry_objects(registry, oid) try: - rset = context.pop('rset') - except KeyError: - rset = None - selected = self.select(objclss, req, rset, **context) - return selected.render(**context) + obj = self.select(__registry, __oid, req, rset=rset, **kwargs) + except NoSelectableObject: + if __fallback_oid is None: + raise + obj = self.select(__registry, __fallback_oid, req, rset=rset, + **kwargs) + return obj.render(**kwargs) 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 method as argument """ - res = self.render('views', oid, req, **context) + res = self.render(oid, req, **context) if isinstance(res, unicode): return res.encode(req.encoding) assert isinstance(res, str) return res + def select_vobject(self, registry, oid, *args, **kwargs): + selected = self.select_object(registry, oid, *args, **kwargs) + if selected and selected.propval('visible'): + return selected + return None + def possible_vobjects(self, registry, *args, **kwargs): """return an ordered list of possible app objects in a given registry, supposing they support the 'visible' and 'order' properties (as most @@ -226,9 +251,9 @@ key=lambda x: x.propval('order')) if x.propval('visible')] - def possible_actions(self, req, rset, **kwargs): + def possible_actions(self, req, rset=None, **kwargs): if rset is None: - actions = self.possible_vobjects('actions', req, rset, **kwargs) + actions = self.possible_vobjects('actions', req, rset=rset, **kwargs) else: actions = rset.possible_actions(**kwargs) # cached implementation result = {} @@ -236,7 +261,7 @@ result.setdefault(action.category, []).append(action) return result - def possible_views(self, req, rset, **kwargs): + def possible_views(self, req, rset=None, **kwargs): """return an iterator on possible views for this result set views returned are classes, not instances @@ -245,50 +270,34 @@ if vid[0] == '_': continue try: - view = self.select(views, req, rset, **kwargs) + view = self.select_best(views, req, rset=rset, **kwargs) if view.linkable(): yield view except NoSelectableObject: continue except Exception: - self.exception('error while trying to list possible %s views for %s', + self.exception('error while trying to select %s view for %s', vid, rset) - def view(self, __vid, req, rset=None, __fallback_vid=None, **kwargs): - """shortcut to self.vreg.render method avoiding to pass self.req""" - try: - view = self.select_view(__vid, req, rset, **kwargs) - except NoSelectableObject: - if __fallback_vid is None: - raise - view = self.select_view(__fallback_vid, req, rset, **kwargs) - return view.render(**kwargs) - + @obsolete("use .select_object('boxes', ...)") def select_box(self, oid, *args, **kwargs): """return the most specific view according to the result set""" - try: - return self.select_object('boxes', oid, *args, **kwargs) - except NoSelectableObject: - return + return self.select_object('boxes', oid, *args, **kwargs) + @obsolete("use .select_object('components', ...)") + def select_component(self, cid, *args, **kwargs): + """return the most specific component according to the result set""" + return self.select_object('components', cid, *args, **kwargs) + + @obsolete("use .select_object('actions', ...)") def select_action(self, oid, *args, **kwargs): """return the most specific view according to the result set""" - try: - return self.select_object('actions', oid, *args, **kwargs) - except NoSelectableObject: - return + return self.select_object('actions', oid, *args, **kwargs) - def select_component(self, cid, *args, **kwargs): - """return the most specific component according to the result set""" - try: - return self.select_object('components', cid, *args, **kwargs) - except (NoSelectableObject, ObjectNotFound): - return - + @obsolete("use .select('views', ...)") def select_view(self, __vid, req, rset=None, **kwargs): """return the most specific view according to the result set""" - views = self.registry_objects('views', __vid) - return self.select(views, req, rset, **kwargs) + return self.select('views', __vid, req, rset=rset, **kwargs) # properties handling ##################################################### @@ -382,7 +391,7 @@ """special registry to be used when an application has to deal with connections to differents repository. This class add some additional wrapper trying to hide buggy class attributes since classes are not designed to be - shared. + shared among multiple registries. """ def etype_class(self, etype): """return an entity class for the given entity type. @@ -395,25 +404,27 @@ usercls.e_schema = self.schema.eschema(etype) return usercls - def select(self, vobjects, *args, **kwargs): + def select_best(self, vobjects, *args, **kwargs): """return an instance of the most specific object according to parameters raise NoSelectableObject if not object apply """ - for vobject in vobjects: - vobject.vreg = self - vobject.schema = self.schema - vobject.config = self.config - selected = super(MulCnxCubicWebRegistry, self).select(vobjects, *args, - **kwargs) + for vobjectcls in vobjects: + self._fix_cls_attrs(vobjectcls) + selected = super(MulCnxCubicWebRegistry, self).select_best( + vobjects, *args, **kwargs) # redo the same thing on the instance so it won't use equivalent class # attributes (which may change) - selected.vreg = self - selected.schema = self.schema - selected.config = self.config + self._fix_cls_attrs(selected) return selected + def _fix_cls_attrs(self, vobject): + vobject.vreg = self + vobject.schema = self.schema + vobject.config = self.config + + from datetime import datetime, date, time, timedelta YAMS_TO_PY = { diff -r 0a0cbccafcb5 -r 7ef12c03447c devtools/_apptest.py --- a/devtools/_apptest.py Fri Jun 05 15:06:55 2009 +0200 +++ b/devtools/_apptest.py Fri Jun 05 15:09:20 2009 +0200 @@ -177,7 +177,7 @@ self.create_request(rql=rql, **optional_args or {})) def check_view(self, rql, vid, optional_args, template='main'): - """checks if vreg.view() raises an exception in this environment + """checks if rendering view raises an exception in this environment If any exception is raised in this method, it will be considered as a TestFailure @@ -186,7 +186,6 @@ template=template, optional_args=optional_args) def call_view(self, vid, rql, template='main', optional_args=None): - """shortcut for self.vreg.view()""" assert template if optional_args is None: optional_args = {} @@ -196,7 +195,7 @@ def call_edit(self, req): """shortcut for self.app.edit()""" - controller = self.app.select_controller('edit', req) + controller = self.vreg.select('controllers', 'edit', req) try: controller.publish() except Redirect: @@ -224,7 +223,7 @@ def iter_possible_actions(self, req, rset): """returns a list of possible vids for """ - for action in self.vreg.possible_vobjects('actions', req, rset): + for action in self.vreg.possible_vobjects('actions', req, rset=rset): yield action class ExistingTestEnvironment(TestEnvironment): diff -r 0a0cbccafcb5 -r 7ef12c03447c devtools/apptest.py --- a/devtools/apptest.py Fri Jun 05 15:06:55 2009 +0200 +++ b/devtools/apptest.py Fri Jun 05 15:09:20 2009 +0200 @@ -219,18 +219,18 @@ return sorted((a.id, a.__class__) for a in self.vreg.possible_views(req, rset)) def pactions(self, req, rset, skipcategories=('addrelated', 'siteactions', 'useractions')): - return [(a.id, a.__class__) for a in self.vreg.possible_vobjects('actions', req, rset) + return [(a.id, a.__class__) for a in self.vreg.possible_vobjects('actions', req, rset=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) + return [(a.id, a.__class__) for a in self.vreg.possible_vobjects('actions', req, rset=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): + for a in self.vreg.possible_vobjects('actions', req, rset=rset): if a.category not in skipcategories: res.setdefault(a.category, []).append(a.__class__) return res @@ -241,7 +241,7 @@ dump = simplejson.dumps args = [dump(arg) for arg in args] req = self.request(fname=fname, pageid='123', arg=args) - ctrl = self.env.app.select_controller('json', req) + ctrl = self.vreg.select('controllers', 'json', req) return ctrl.publish(), req # default test setup and teardown ######################################### @@ -286,7 +286,7 @@ def setUp(self): super(ControllerTC, self).setUp() self.req = self.request() - self.ctrl = self.env.app.select_controller('edit', self.req) + self.ctrl = self.vreg.select('controllers', 'edit', self.req) def publish(self, req): assert req is self.ctrl.req @@ -300,7 +300,7 @@ def expect_redirect_publish(self, req=None): if req is not None: - self.ctrl = self.env.app.select_controller('edit', req) + self.ctrl = self.vreg.select('controllers', 'edit', req) else: req = self.req try: diff -r 0a0cbccafcb5 -r 7ef12c03447c devtools/fake.py --- a/devtools/fake.py Fri Jun 05 15:06:55 2009 +0200 +++ b/devtools/fake.py Fri Jun 05 15:09:20 2009 +0200 @@ -154,6 +154,25 @@ return self.execute(*args, **kwargs) +# class FakeRequestNoCnx(FakeRequest): +# def get_session_data(self, key, default=None, pop=False): +# """return value associated to `key` in session data""" +# if pop: +# return self._session_data.pop(key, default) +# else: +# return self._session_data.get(key, default) + +# def set_session_data(self, key, value): +# """set value associated to `key` in session data""" +# self._session_data[key] = value + +# def del_session_data(self, key): +# try: +# del self._session_data[key] +# except KeyError: +# pass + + class FakeUser(object): login = 'toto' eid = 0 diff -r 0a0cbccafcb5 -r 7ef12c03447c devtools/testlib.py --- a/devtools/testlib.py Fri Jun 05 15:06:55 2009 +0200 +++ b/devtools/testlib.py Fri Jun 05 15:09:20 2009 +0200 @@ -172,7 +172,8 @@ return validator.parse_string(output.strip()) - def view(self, vid, rset, req=None, template='main-template', **kwargs): + def view(self, vid, rset=None, req=None, template='main-template', + **kwargs): """This method tests the view `vid` on `rset` using `template` If no error occured while rendering the view, the HTML is analyzed @@ -182,24 +183,24 @@ encapsulation the generated HTML """ req = req or rset and rset.req or self.request() - # print "testing ", vid, - # if rset: - # print rset, len(rset), id(rset) - # else: - # print req.form['vid'] = vid - view = self.vreg.select_view(vid, req, rset, **kwargs) + kwargs['rset'] = rset + view = self.vreg.select('views', vid, req, **kwargs) # set explicit test description if rset is not None: - self.set_description("testing %s, mod=%s (%s)" % (vid, view.__module__, rset.printable_rql())) + self.set_description("testing %s, mod=%s (%s)" % ( + vid, view.__module__, rset.printable_rql())) else: - self.set_description("testing %s, mod=%s (no rset)" % (vid, view.__module__)) + self.set_description("testing %s, mod=%s (no rset)" % ( + vid, view.__module__)) if template is None: # raw view testing, no template viewfunc = view.render else: - templateview = self.vreg.select_view(template, req, rset, view=view, **kwargs) kwargs['view'] = view - viewfunc = lambda **k: self.vreg.main_template(req, template, **kwargs) + templateview = self.vreg.select('views', template, req, **kwargs) + viewfunc = lambda **k: self.vreg.main_template(req, template, + **kwargs) + kwargs.pop('rset') return self._test_view(viewfunc, view, template, kwargs) @@ -279,7 +280,7 @@ and not issubclass(view, NotificationView)] if views: try: - view = self.vreg.select(views, req, rset) + view = self.vreg.select_best(views, req, rset=rset) if view.linkable(): yield view else: @@ -292,13 +293,13 @@ def list_actions_for(self, rset): """returns the list of actions that can be applied on `rset`""" req = rset.req - for action in self.vreg.possible_objects('actions', req, rset): + for action in self.vreg.possible_objects('actions', req, rset=rset): yield action def list_boxes_for(self, rset): """returns the list of boxes that can be applied on `rset`""" req = rset.req - for box in self.vreg.possible_objects('boxes', req, rset): + for box in self.vreg.possible_objects('boxes', req, rset=rset): yield box def list_startup_views(self): @@ -384,8 +385,8 @@ requestcls=testclass.requestcls) vreg = env.vreg vreg._selected = {} - orig_select = vreg.__class__.select - def instr_select(self, *args, **kwargs): + orig_select_best = vreg.__class__.select_best + def instr_select_best(self, *args, **kwargs): selected = orig_select(self, *args, **kwargs) try: self._selected[selected.__class__] += 1 @@ -394,7 +395,7 @@ except AttributeError: pass # occurs on vreg used to restore database return selected - vreg.__class__.select = instr_select + vreg.__class__.select_best = instr_select_best def print_untested_objects(testclass, skipregs=('hooks', 'etypes')): vreg = testclass._env.vreg diff -r 0a0cbccafcb5 -r 7ef12c03447c entities/__init__.py --- a/entities/__init__.py Fri Jun 05 15:06:55 2009 +0200 +++ b/entities/__init__.py Fri Jun 05 15:09:20 2009 +0200 @@ -242,12 +242,12 @@ @obsolete('use EntityFieldsForm.subject_relation_vocabulary') def subject_relation_vocabulary(self, rtype, limit): - form = self.vreg.select_object('forms', 'edition', self.req, entity=self) + form = self.vreg.select('forms', 'edition', self.req, entity=self) return form.subject_relation_vocabulary(rtype, limit) @obsolete('use EntityFieldsForm.object_relation_vocabulary') def object_relation_vocabulary(self, rtype, limit): - form = self.vreg.select_object('forms', 'edition', self.req, entity=self) + form = self.vreg.select('forms', 'edition', self.req, entity=self) return form.object_relation_vocabulary(rtype, limit) @obsolete('use AutomaticEntityForm.[e]relations_by_category') diff -r 0a0cbccafcb5 -r 7ef12c03447c entity.py --- a/entity.py Fri Jun 05 15:06:55 2009 +0200 +++ b/entity.py Fri Jun 05 15:09:20 2009 +0200 @@ -368,9 +368,9 @@ def has_perm(self, action): return self.e_schema.has_perm(self.req, action, self.eid) - def view(self, vid, __registry='views', **kwargs): + def view(self, vid, **kwargs): """shortcut to apply a view on this entity""" - return self.vreg.render(__registry, vid, self.req, rset=self.rset, + return self.vreg.render(vid, self.req, rset=self.rset, row=self.row, col=self.col, **kwargs) def absolute_url(self, method=None, **kwargs): @@ -725,7 +725,7 @@ interpreted as a separator in case vocabulary results are grouped """ from logilab.common.testlib import mock_object - form = self.vreg.select_object('forms', 'edition', self.req, entity=self) + form = self.vreg.select('forms', 'edition', self.req, entity=self) field = mock_object(name=rtype, role=role) return form.form_field_vocabulary(field, limit) diff -r 0a0cbccafcb5 -r 7ef12c03447c etwist/server.py --- a/etwist/server.py Fri Jun 05 15:06:55 2009 +0200 +++ b/etwist/server.py Fri Jun 05 15:09:20 2009 +0200 @@ -106,10 +106,7 @@ self.pyro_listen_timeout = 0.02 start_task(1, self.pyro_loop_event) self.appli.repo.start_looping_tasks() - try: - self.url_rewriter = self.appli.vreg.select_component('urlrewriter') - except ObjectNotFound: - self.url_rewriter = None + self.url_rewriter = self.appli.vreg.select_object('components', 'urlrewriter') interval = min(config['cleanup-session-time'] or 120, config['cleanup-anonymous-session-time'] or 720) / 2. start_task(interval, self.appli.session_handler.clean_sessions) diff -r 0a0cbccafcb5 -r 7ef12c03447c goa/appobjects/components.py --- a/goa/appobjects/components.py Fri Jun 05 15:06:55 2009 +0200 +++ b/goa/appobjects/components.py Fri Jun 05 15:09:20 2009 +0200 @@ -72,7 +72,7 @@ continue etype = eschema.type label = display_name(req, etype, 'plural') - view = self.vreg.select_view('list', req, req.etype_rset(etype)) + view = self.vreg.select('views', 'list', req, req.etype_rset(etype)) url = view.url() etypelink = u' %s' % (html_escape(url), label) yield (label, etypelink, self.add_entity_link(eschema, req)) diff -r 0a0cbccafcb5 -r 7ef12c03447c goa/test/unittest_editcontroller.py --- a/goa/test/unittest_editcontroller.py Fri Jun 05 15:06:55 2009 +0200 +++ b/goa/test/unittest_editcontroller.py Fri Jun 05 15:09:20 2009 +0200 @@ -37,8 +37,7 @@ self.ctrl = self.get_ctrl(self.req) def get_ctrl(self, req): - return self.vreg.select(self.vreg.registry_objects('controllers', 'edit'), - req=req, appli=self) + return self.vreg.select('controllers', 'edit', req=req, appli=self) def publish(self, req): assert req is self.ctrl.req diff -r 0a0cbccafcb5 -r 7ef12c03447c goa/testlib.py --- a/goa/testlib.py Fri Jun 05 15:06:55 2009 +0200 +++ b/goa/testlib.py Fri Jun 05 15:09:20 2009 +0200 @@ -131,7 +131,7 @@ self.vreg.load_module(module) for cls in self.MODEL_CLASSES: self.vreg.load_object(cls) - self.session_manager = self.vreg.select_component('sessionmanager') + self.session_manager = self.vreg.select('components', 'sessionmanager') if need_ds_init: # create default groups and create entities according to the schema create_groups() diff -r 0a0cbccafcb5 -r 7ef12c03447c rset.py --- a/rset.py Fri Jun 05 15:06:55 2009 +0200 +++ b/rset.py Fri Jun 05 15:09:20 2009 +0200 @@ -83,7 +83,8 @@ try: return self._rsetactions[key] except KeyError: - actions = self.vreg.possible_vobjects('actions', self.req, self, **kwargs) + actions = self.vreg.possible_vobjects('actions', self.req, + rset=self, **kwargs) self._rsetactions[key] = actions return actions diff -r 0a0cbccafcb5 -r 7ef12c03447c sobjects/notification.py --- a/sobjects/notification.py Fri Jun 05 15:06:55 2009 +0200 +++ b/sobjects/notification.py Fri Jun 05 15:09:20 2009 +0200 @@ -6,6 +6,7 @@ :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses """ __docformat__ = "restructuredtext en" +_ = unicode from base64 import b64encode, b64decode from itertools import repeat @@ -13,7 +14,7 @@ try: from socket import gethostname except ImportError: - def gethostname(): + def gethostname(): # gae return 'XXX' from logilab.common.textutils import normalize_text @@ -28,7 +29,6 @@ from cubicweb.server.hookhelper import SendMailOp from cubicweb.server.hooksmanager import Hook -_ = unicode class RecipientsFinder(Component): """this component is responsible to find recipients of a notification @@ -76,7 +76,7 @@ return rset = entity.related('wf_info_for') try: - view = session.vreg.select_view('notif_status_change', + view = session.vreg.select('views', 'notif_status_change', session, rset, row=0) except RegistryException: return @@ -100,7 +100,7 @@ rset = session.eid_rset(fromeid) vid = 'notif_%s_%s' % (self.event, rtype) try: - view = session.vreg.select_view(vid, session, rset, row=0) + view = session.vreg.select('views', vid, session, rset, row=0) except RegistryException: return RenderAndSendNotificationView(session, view=view) @@ -117,7 +117,7 @@ rset = entity.as_rset() vid = 'notif_%s' % self.event try: - view = session.vreg.select_view(vid, session, rset, row=0) + view = session.vreg.select('views', vid, session, rset, row=0) except RegistryException: return RenderAndSendNotificationView(session, view=view) @@ -136,7 +136,8 @@ msgid_timestamp = True def recipients(self): - finder = self.vreg.select_component('recipients_finder', self.req, self.rset) + finder = self.vreg.select('components', 'recipients_finder', self.req, + rset=self.rset) return finder.recipients() def subject(self): diff -r 0a0cbccafcb5 -r 7ef12c03447c sobjects/supervising.py --- a/sobjects/supervising.py Fri Jun 05 15:06:55 2009 +0200 +++ b/sobjects/supervising.py Fri Jun 05 15:09:20 2009 +0200 @@ -218,8 +218,8 @@ of changes """ def _get_view(self): - return self.session.vreg.select_component('supervision_notif', - self.session, None) + return self.session.vreg.select('components', 'supervision_notif', + self.session) def _prepare_email(self): session = self.session diff -r 0a0cbccafcb5 -r 7ef12c03447c sobjects/test/unittest_notification.py --- a/sobjects/test/unittest_notification.py Fri Jun 05 15:06:55 2009 +0200 +++ b/sobjects/test/unittest_notification.py Fri Jun 05 15:09:20 2009 +0200 @@ -56,7 +56,8 @@ self.execute('INSERT CWProperty X: X pkey "ui.language", X value "fr", X for_user U ' 'WHERE U eid %(x)s', {'x': urset[0][0]}) self.commit() # commit so that admin get its properties updated - finder = self.vreg.select_component('recipients_finder', self.request(), urset) + finder = self.vreg.select('components', 'recipients_finder', self.request(), + rset=urset) self.set_option('default-recipients-mode', 'none') self.assertEquals(finder.recipients(), []) self.set_option('default-recipients-mode', 'users') @@ -73,7 +74,7 @@ u = self.create_user('toto', req=req) assert u.req self.execute('SET X in_state S WHERE X eid %s, S name "deactivated"' % u.eid) - v = self.vreg.select_view('notif_status_change', req, u.rset, row=0) + v = self.vreg.select('views', 'notif_status_change', req, u.rset, row=0) content = v.render(row=0, comment='yeah', previous_state='activated', current_state='deactivated') diff -r 0a0cbccafcb5 -r 7ef12c03447c vregistry.py --- a/vregistry.py Fri Jun 05 15:06:55 2009 +0200 +++ b/vregistry.py Fri Jun 05 15:09:20 2009 +0200 @@ -169,28 +169,91 @@ If no oid is given, return all objects in this registry """ registry = self.registry(name) - if oid: + if oid is not None: try: return registry[oid] except KeyError: raise ObjectNotFound(oid), None, sys.exc_info()[-1] - else: - result = [] - for objs in registry.values(): - result += objs - return result + result = [] + for objs in registry.values(): + result += objs + return result + + # dynamic selection methods ################################################ - def object_by_id(self, registry, cid, *args, **kwargs): - """return the most specific component according to the resultset""" - objects = self[registry][cid] + def object_by_id(self, registry, oid, *args, **kwargs): + """return object in . + + raise `ObjectNotFound` if not object with id in + raise `AssertionError` if there is more than one object there + """ + objects = self.registry_objects(registry, oid) assert len(objects) == 1, objects return objects[0].selected(*args, **kwargs) + def select(self, registry, oid, *args, **kwargs): + """return the most specific object in . according to + the given context + + raise `ObjectNotFound` if not object with id in + raise `NoSelectableObject` if not object apply + """ + return self.select_best(self.registry_objects(registry, oid), + *args, **kwargs) + + def select_object(self, registry, oid, *args, **kwargs): + """return the most specific object in . according to + the given context, or None if no object apply + """ + try: + return self.select(registry, oid, *args, **kwargs) + except (NoSelectableObject, ObjectNotFound): + return None + + def possible_objects(self, registry, *args, **kwargs): + """return an iterator on possible objects in for the given + context + """ + for vobjects in self.registry(registry).itervalues(): + try: + yield self.select_best(vobjects, *args, **kwargs) + except NoSelectableObject: + continue + + def select_best(self, vobjects, *args, **kwargs): + """return an instance of the most specific object according + to parameters + + raise `NoSelectableObject` if not object apply + """ + score, winners = 0, [] + for vobject in vobjects: + vobjectscore = vobject.__select__(vobject, *args, **kwargs) + if vobjectscore > score: + score, winners = vobjectscore, [vobject] + elif vobjectscore > 0 and vobjectscore == score: + winners.append(vobject) + if not winners: + raise NoSelectableObject('args: %s\nkwargs: %s %s' + % (args, kwargs.keys(), + [repr(v) for v in vobjects])) + if len(winners) > 1: + if self.config.mode == 'installed': + self.error('select ambiguity, args: %s\nkwargs: %s %s', + args, kwargs.keys(), [repr(v) for v in winners]) + else: + raise Exception('select ambiguity, args: %s\nkwargs: %s %s' + % (args, kwargs.keys(), + [repr(v) for v in winners])) + # return the result of the .selected method of the vobject + return winners[0].selected(*args, **kwargs) + # methods for explicit (un)registration ################################### # def clear(self, key): # regname, oid = key.split('.') # self[regname].pop(oid, None) + def register_all(self, objects, modname, butclasses=()): for obj in objects: try: @@ -266,52 +329,6 @@ replaced, obj) self.register(obj, registryname=registryname) - # dynamic selection methods ############################################### - - def select(self, vobjects, *args, **kwargs): - """return an instance of the most specific object according - to parameters - - raise NoSelectableObject if not object apply - """ - score, winners = 0, [] - for vobject in vobjects: - vobjectscore = vobject.__select__(vobject, *args, **kwargs) - if vobjectscore > score: - score, winners = vobjectscore, [vobject] - elif vobjectscore > 0 and vobjectscore == score: - winners.append(vobject) - if not winners: - raise NoSelectableObject('args: %s\nkwargs: %s %s' - % (args, kwargs.keys(), - [repr(v) for v in vobjects])) - if len(winners) > 1: - if self.config.mode == 'installed': - self.error('select ambiguity, args: %s\nkwargs: %s %s', - args, kwargs.keys(), [repr(v) for v in winners]) - else: - raise Exception('select ambiguity, args: %s\nkwargs: %s %s' - % (args, kwargs.keys(), - [repr(v) for v in winners])) - winner = winners[0] - # return the result of the .selected method of the vobject - return winner.selected(*args, **kwargs) - - def possible_objects(self, registry, *args, **kwargs): - """return an iterator on possible objects in a registry for this result set - - actions returned are classes, not instances - """ - for vobjects in self.registry(registry).values(): - try: - yield self.select(vobjects, *args, **kwargs) - except NoSelectableObject: - continue - - def select_object(self, registry, cid, *args, **kwargs): - """return the most specific component according to the resultset""" - return self.select(self.registry_objects(registry, cid), *args, **kwargs) - # intialization methods ################################################### def init_registration(self, path, extrapath=None): diff -r 0a0cbccafcb5 -r 7ef12c03447c web/application.py --- a/web/application.py Fri Jun 05 15:06:55 2009 +0200 +++ b/web/application.py Fri Jun 05 15:09:20 2009 +0200 @@ -10,21 +10,25 @@ import sys from time import clock, time +from logilab.common.deprecation import obsolete + from rql import BadRQLQuery -from cubicweb import set_log_methods -from cubicweb import (ValidationError, Unauthorized, AuthenticationError, - NoSelectableObject, RepositoryError) -from cubicweb.cwvreg import CubicWebRegistry -from cubicweb.web import (LOGGER, StatusResponse, DirectResponse, Redirect, NotFound, - RemoteCallFailed, ExplicitLogin, InvalidSession) +from cubicweb import set_log_methods, cwvreg +from cubicweb import ( + ValidationError, Unauthorized, AuthenticationError, NoSelectableObject, + RepositoryError) +from cubicweb.web import LOGGER, component +from cubicweb.web import ( + StatusResponse, DirectResponse, Redirect, NotFound, + RemoteCallFailed, ExplicitLogin, InvalidSession) from cubicweb.web.component import Component # make session manager available through a global variable so the debug view can # print information about web session SESSION_MANAGER = None -class AbstractSessionManager(Component): +class AbstractSessionManager(component.Component): """manage session data associated to a session identifier""" id = 'sessionmanager' @@ -38,8 +42,7 @@ if self.session_time: assert self.cleanup_session_time < self.session_time assert self.cleanup_anon_session_time < self.session_time - self.authmanager = self.vreg.select_component('authmanager') - assert self.authmanager, 'no authentication manager found' + self.authmanager = self.vreg.select('components', 'authmanager') def clean_sessions(self): """cleanup sessions which has not been unused since a given amount of @@ -87,7 +90,7 @@ raise NotImplementedError() -class AbstractAuthenticationManager(Component): +class AbstractAuthenticationManager(component.Component): """authenticate user associated to a request and check session validity""" id = 'authmanager' @@ -110,8 +113,7 @@ SESSION_VAR = '__session' def __init__(self, appli): - self.session_manager = appli.vreg.select_component('sessionmanager') - assert self.session_manager, 'no session manager found' + self.session_manager = appli.vreg.select('components', 'sessionmanager') global SESSION_MANAGER SESSION_MANAGER = self.session_manager if not 'last_login_time' in appli.vreg.schema: @@ -209,20 +211,8 @@ class CubicWebPublisher(object): - """Central registry for the web application. This is one of the central - object in the web application, coupling dynamically loaded objects with - the application's schema and the application's configuration objects. - - It specializes the VRegistry by adding some convenience methods to - access to stored objects. Currently we have the following registries - of objects known by the web application (library may use some others - additional registries): - * controllers, which are directly plugged into the application - object to handle request publishing - * views - * templates - * components - * actions + """the publisher is a singleton hold by the web frontend, and is responsible + to publish HTTP request. """ def __init__(self, config, debug=None, @@ -231,7 +221,7 @@ super(CubicWebPublisher, self).__init__() # connect to the repository and get application's schema if vreg is None: - vreg = CubicWebRegistry(config, debug=debug) + vreg = cwvreg.CubicWebRegistry(config, debug=debug) self.vreg = vreg self.info('starting web application from %s', config.apphome) self.repo = config.repository(vreg) @@ -250,7 +240,7 @@ self.publish = self.main_publish # instantiate session and url resolving helpers self.session_handler = session_handler_fact(self) - self.url_resolver = vreg.select_component('urlpublisher') + self.url_resolver = vreg.select('components', 'urlpublisher') def connect(self, req): """return a connection for a logged user object according to existing @@ -259,15 +249,6 @@ """ self.session_handler.set_session(req) - def select_controller(self, oid, req): - """return the most specific view according to the resultset""" - vreg = self.vreg - try: - return vreg.select(vreg.registry_objects('controllers', oid), - req=req, appli=self) - except NoSelectableObject: - raise Unauthorized(req._('not authorized')) - # publish methods ######################################################### def log_publish(self, path, req): @@ -292,6 +273,14 @@ finally: self._logfile_lock.release() + @obsolete("use vreg.select('controllers', ...)") + def select_controller(self, oid, req): + try: + controller = self.vreg.select('controllers', oid, req=req, + appli=self) + except NoSelectableObject: + raise Unauthorized(req._('not authorized')) + def main_publish(self, path, req): """method called by the main publisher to process @@ -316,7 +305,11 @@ try: try: ctrlid, rset = self.url_resolver.process(req, path) - controller = self.select_controller(ctrlid, req) + try: + controller = self.vreg.select('controllers', ctrlid, req, + appli=self) + except NoSelectableObject: + raise Unauthorized(req._('not authorized')) req.update_search_state() result = controller.publish(rset=rset) if req.cnx is not None: @@ -384,7 +377,7 @@ if tb: req.data['excinfo'] = excinfo req.form['vid'] = 'error' - errview = self.vreg.select_view('error', req, None) + errview = self.vreg.select('views', 'error', req) template = self.main_template_id(req) content = self.vreg.main_template(req, template, view=errview) except: @@ -399,7 +392,7 @@ def notfound_content(self, req): req.form['vid'] = '404' - view = self.vreg.select_view('404', req, None) + view = self.vreg.select('views', '404', req) template = self.main_template_id(req) return self.vreg.main_template(req, template, view=view) diff -r 0a0cbccafcb5 -r 7ef12c03447c web/box.py --- a/web/box.py Fri Jun 05 15:06:55 2009 +0200 +++ b/web/box.py Fri Jun 05 15:09:20 2009 +0200 @@ -6,6 +6,7 @@ :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses """ __docformat__ = "restructuredtext en" +_ = unicode from logilab.mtconverter import html_escape @@ -20,8 +21,6 @@ RawBoxItem, BoxSeparator) from cubicweb.web.action import UnregisteredAction -_ = unicode - class BoxTemplate(View): """base template for boxes, usually a (contextual) list of possible @@ -220,8 +219,8 @@ return entity.unrelated(self.rtype, self.etype, get_role(self)).entities() # in other cases, use vocabulary functions entities = [] - form = self.vreg.select_object('forms', 'edition', self.req, self.rset, - row=self.row or 0) + form = self.vreg.select('forms', 'edition', self.req, rset=self.rset, + row=self.row or 0) field = form.field_by_name(self.rtype, get_role(self), entity.e_schema) for _, eid in form.form_field_vocabulary(field): if eid is not None: diff -r 0a0cbccafcb5 -r 7ef12c03447c web/component.py --- a/web/component.py Fri Jun 05 15:06:55 2009 +0200 +++ b/web/component.py Fri Jun 05 15:09:20 2009 +0200 @@ -6,6 +6,7 @@ :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses """ __docformat__ = "restructuredtext en" +_ = unicode from logilab.common.deprecation import class_renamed from logilab.mtconverter import html_escape @@ -18,7 +19,6 @@ partial_has_related_entities, condition_compat, accepts_compat, has_relation_compat) -_ = unicode class EntityVComponent(Component): """abstract base class for additinal components displayed in content diff -r 0a0cbccafcb5 -r 7ef12c03447c web/controller.py --- a/web/controller.py Fri Jun 05 15:06:55 2009 +0200 +++ b/web/controller.py Fri Jun 05 15:09:20 2009 +0200 @@ -86,14 +86,16 @@ def process_rql(self, rql): """execute rql if specified""" + # XXX assigning to self really necessary? + self.rset = None if rql: self.ensure_ro_rql(rql) if not isinstance(rql, unicode): rql = unicode(rql, self.req.encoding) - pp = self.vreg.select_component('magicsearch', self.req) - self.rset = pp.process_query(rql, self.req) - return self.rset - return None + pp = self.vreg.select_object('components', 'magicsearch', self.req) + if pp is not None: + self.rset = pp.process_query(rql, self.req) + return self.rset def check_expected_params(self, params): """check that the given list of parameters are specified in the form diff -r 0a0cbccafcb5 -r 7ef12c03447c web/test/unittest_form.py --- a/web/test/unittest_form.py Fri Jun 05 15:06:55 2009 +0200 +++ b/web/test/unittest_form.py Fri Jun 05 15:09:20 2009 +0200 @@ -88,7 +88,7 @@ e.req = self.req geid = self.execute('CWGroup X WHERE X name "users"')[0][0] self.req.form['__linkto'] = 'in_group:%s:subject' % geid - form = self.vreg.select_object('forms', 'edition', self.req, None, entity=e) + form = self.vreg.select('forms', 'edition', self.req, entity=e) form.content_type = 'text/html' pageinfo = self._check_html(form.form_render(), form, template=None) inputs = pageinfo.find_tag('select', False) diff -r 0a0cbccafcb5 -r 7ef12c03447c web/test/unittest_magicsearch.py --- a/web/test/unittest_magicsearch.py Fri Jun 05 15:06:55 2009 +0200 +++ b/web/test/unittest_magicsearch.py Fri Jun 05 15:09:20 2009 +0200 @@ -44,7 +44,7 @@ super(QueryTranslatorTC, self).setUp() self.req = self.env.create_request() self.vreg.config.translations = {'en': _translate} - proc = self.vreg.select_component('magicsearch', self.req) + proc = self.vreg.select('components', 'magicsearch', self.req) self.proc = [p for p in proc.processors if isinstance(p, QueryTranslator)][0] def test_basic_translations(self): @@ -69,7 +69,7 @@ super(QSPreProcessorTC, self).setUp() self.vreg.config.translations = {'en': _translate} self.req = self.request() - proc = self.vreg.select_component('magicsearch', self.req) + proc = self.vreg.select('components', 'magicsearch', self.req) self.proc = [p for p in proc.processors if isinstance(p, QSPreProcessor)][0] self.proc.req = self.req @@ -191,7 +191,7 @@ super(ProcessorChainTC, self).setUp() self.vreg.config.translations = {'en': _translate} self.req = self.request() - self.proc = self.vreg.select_component('magicsearch', self.req) + self.proc = self.vreg.select('components', 'magicsearch', self.req) def test_main_preprocessor_chain(self): """tests QUERY_PROCESSOR""" diff -r 0a0cbccafcb5 -r 7ef12c03447c web/test/unittest_views_actions.py --- a/web/test/unittest_views_actions.py Fri Jun 05 15:06:55 2009 +0200 +++ b/web/test/unittest_views_actions.py Fri Jun 05 15:09:20 2009 +0200 @@ -13,19 +13,19 @@ def test_view_action(self): req = self.request(__message='bla bla bla', vid='rss', rql='CWUser X') rset = self.execute('CWUser X') - vaction = [action for action in self.vreg.possible_vobjects('actions', req, rset) + vaction = [action for action in self.vreg.possible_vobjects('actions', req, rset=rset) if action.id == 'view'][0] self.assertEquals(vaction.url(), 'http://testing.fr/cubicweb/view?rql=CWUser%20X') def test_sendmail_action(self): req = self.request() rset = self.execute('Any X WHERE X login "admin"', req=req) - self.failUnless([action for action in self.vreg.possible_vobjects('actions', req, rset) + self.failUnless([action for action in self.vreg.possible_vobjects('actions', req, rset=rset) if action.id == 'sendemail']) self.login('anon') req = self.request() rset = self.execute('Any X WHERE X login "anon"', req=req) - self.failIf([action for action in self.vreg.possible_vobjects('actions', req, rset) + self.failIf([action for action in self.vreg.possible_vobjects('actions', req, rset=rset) if action.id == 'sendemail']) if __name__ == '__main__': diff -r 0a0cbccafcb5 -r 7ef12c03447c web/test/unittest_views_basecontrollers.py --- a/web/test/unittest_views_basecontrollers.py Fri Jun 05 15:06:55 2009 +0200 +++ b/web/test/unittest_views_basecontrollers.py Fri Jun 05 15:09:20 2009 +0200 @@ -499,7 +499,7 @@ # updated (which is what happened before this test) req = self.request() req.form['url'] = 'http://intranet.logilab.fr/' - controller = self.env.app.select_controller('embed', req) + controller = self.vreg.select('controllers', 'embed', req) result = controller.publish(rset=None) @@ -507,7 +507,7 @@ def test_usable_by_guets(self): req = self.request() - self.env.app.select_controller('reportbug', req) + self.vreg.select('controllers', 'reportbug', req) class SendMailControllerTC(EnvBasedTC): @@ -523,7 +523,7 @@ def ctrl(self, req=None): req = req or self.request(url='http://whatever.fr/') - return self.env.app.select_controller('json', req) + return self.vreg.select('controllers', 'json', req) def setup_database(self): self.pytag = self.add_entity('Tag', name=u'python') diff -r 0a0cbccafcb5 -r 7ef12c03447c web/test/unittest_views_baseviews.py --- a/web/test/unittest_views_baseviews.py Fri Jun 05 15:06:55 2009 +0200 +++ b/web/test/unittest_views_baseviews.py Fri Jun 05 15:09:20 2009 +0200 @@ -86,7 +86,7 @@ rset = self.execute('Any X, D, CD, NOW - CD WHERE X is State, X description D, X creation_date CD, X eid %(x)s', {'x': e.eid}, 'x') req = self.request() - view = self.vreg.select_view('table', req, rset) + view = self.vreg.select('views', 'table', req, rset) return e, rset, view def test_headers(self): diff -r 0a0cbccafcb5 -r 7ef12c03447c web/test/unittest_views_editforms.py --- a/web/test/unittest_views_editforms.py Fri Jun 05 15:06:55 2009 +0200 +++ b/web/test/unittest_views_editforms.py Fri Jun 05 15:09:20 2009 +0200 @@ -18,8 +18,8 @@ def test_custom_widget(self): AEF.rfields_kwargs.tag_subject_of(('CWUser', 'login', '*'), {'widget':AutoCompletionWidget}) - form = self.vreg.select_object('forms', 'edition', self.request(), None, - entity=self.user()) + form = self.vreg.select('forms', 'edition', self.request(), + entity=self.user()) field = form.field_by_name('login') self.assertIsInstance(field.widget, AutoCompletionWidget) AEF.rfields_kwargs.del_rtag('CWUser', 'login', '*', 'subject') @@ -114,11 +114,11 @@ def test_edition_form(self): rset = self.execute('CWUser X LIMIT 1') - form = self.vreg.select_object('forms', 'edition', rset.req, rset, - row=0, col=0) + form = self.vreg.select('forms', 'edition', rset.req, rset=rset, + row=0, col=0) # should be also selectable by specifying entity - self.vreg.select_object('forms', 'edition', self.request(), None, - entity=rset.get_entity(0, 0)) + self.vreg.select('forms', 'edition', rset.req, + entity=rset.get_entity(0, 0)) self.failIf(any(f for f in form.fields if f is None)) diff -r 0a0cbccafcb5 -r 7ef12c03447c web/test/unittest_views_navigation.py --- a/web/test/unittest_views_navigation.py Fri Jun 05 15:06:55 2009 +0200 +++ b/web/test/unittest_views_navigation.py Fri Jun 05 15:09:20 2009 +0200 @@ -19,31 +19,31 @@ def test_navigation_selection(self): rset = self.execute('Any X,N WHERE X name N') req = self.request() - navcomp = self.vreg.select_component('navigation', req, rset) + navcomp = self.vreg.select('components', 'navigation', req, rset=rset) self.assertIsInstance(navcomp, PageNavigation) req.set_search_state('W:X:Y:Z') - navcomp = self.vreg.select_component('navigation', req, rset) + navcomp = self.vreg.select('components', 'navigation', req, rset=rset) self.assertIsInstance(navcomp, PageNavigation) req.set_search_state('normal') rset = self.execute('Any X,N ORDERBY N WHERE X name N') - navcomp = self.vreg.select_component('navigation', req, rset) + navcomp = self.vreg.select('components', 'navigation', req, rset=rset) self.assertIsInstance(navcomp, SortedNavigation) req.set_search_state('W:X:Y:Z') - navcomp = self.vreg.select_component('navigation', req, rset) + navcomp = self.vreg.select('components', 'navigation', req, rset=rset) self.assertIsInstance(navcomp, SortedNavigation) req.set_search_state('normal') rset = self.execute('Any X,N LIMIT 10 WHERE X name N') - navcomp = self.vreg.select_component('navigation', req, rset) + navcomp = self.vreg.select_object('components', 'navigation', req, rset=rset) self.assertEquals(navcomp, None) req.set_search_state('W:X:Y:Z') - navcomp = self.vreg.select_component('navigation', req, rset) + navcomp = self.vreg.select_object('components', 'navigation', req, rset=rset) self.assertEquals(navcomp, None) req.set_search_state('normal') rset = self.execute('Any N, COUNT(RDEF) GROUPBY N ORDERBY N WHERE RDEF relation_type RT, RT name N') - navcomp = self.vreg.select_component('navigation', req, rset) + navcomp = self.vreg.select('components', 'navigation', req, rset=rset) self.assertIsInstance(navcomp, SortedNavigation) req.set_search_state('W:X:Y:Z') - navcomp = self.vreg.select_component('navigation', req, rset) + navcomp = self.vreg.select('components', 'navigation', req, rset=rset) self.assertIsInstance(navcomp, SortedNavigation) @@ -51,22 +51,22 @@ rset = self.execute('Any X,N ORDERBY N WHERE X name N') req = self.request() req.set_search_state('W:X:Y:Z') - navcomp = self.vreg.select_component('navigation', rset.req, rset) + navcomp = self.vreg.select('components', 'navigation', rset.req, rset=rset) html = navcomp.render() rset = self.execute('Any RDEF ORDERBY RT WHERE RDEF relation_type RT') - navcomp = self.vreg.select_component('navigation', req, rset) + navcomp = self.vreg.select('components', 'navigation', req, rset=rset) html = navcomp.render() rset = self.execute('Any RDEF ORDERBY RDEF WHERE RDEF relation_type RT') - navcomp = self.vreg.select_component('navigation', req, rset) + navcomp = self.vreg.select('components', 'navigation', req, rset=rset) html = navcomp.render() rset = self.execute('CWAttribute RDEF ORDERBY RDEF') - navcomp = self.vreg.select_component('navigation', req, rset) + navcomp = self.vreg.select('components', 'navigation', req, rset=rset) html = navcomp.render() rset = self.execute('Any RDEF ORDERBY N WHERE RDEF relation_type RT, RT name N') - navcomp = self.vreg.select_component('navigation', req, rset) + navcomp = self.vreg.select('components', 'navigation', req, rset=rset) html = navcomp.render() rset = self.execute('Any N, COUNT(RDEF) GROUPBY N ORDERBY N WHERE RDEF relation_type RT, RT name N') - navcomp = self.vreg.select_component('navigation', rset.req, rset) + navcomp = self.vreg.select('components', 'navigation', rset.req, rset=rset) html = navcomp.render() @@ -77,12 +77,12 @@ view = mock_object(is_primary=lambda x: True) rset = self.execute('CWUser X LIMIT 1') req = self.request() - objs = self.vreg.possible_vobjects('contentnavigation', req, rset, + objs = self.vreg.possible_vobjects('contentnavigation', req, rset=rset, view=view, context='navtop') # breadcrumbs should be in headers by default clsids = set(obj.id for obj in objs) self.failUnless('breadcrumbs' in clsids) - objs = self.vreg.possible_vobjects('contentnavigation', req, rset, + objs = self.vreg.possible_vobjects('contentnavigation', req, rset=rset, view=view, context='navbottom') # breadcrumbs should _NOT_ be in footers by default clsids = set(obj.id for obj in objs) @@ -91,12 +91,12 @@ 'P value "navbottom"') # breadcrumbs should now be in footers req.cnx.commit() - objs = self.vreg.possible_vobjects('contentnavigation', req, rset, + objs = self.vreg.possible_vobjects('contentnavigation', req, rset=rset, view=view, context='navbottom') clsids = [obj.id for obj in objs] self.failUnless('breadcrumbs' in clsids) - objs = self.vreg.possible_vobjects('contentnavigation', req, rset, + objs = self.vreg.possible_vobjects('contentnavigation', req, rset=rset, view=view, context='navtop') clsids = [obj.id for obj in objs] diff -r 0a0cbccafcb5 -r 7ef12c03447c web/test/unittest_views_pyviews.py --- a/web/test/unittest_views_pyviews.py Fri Jun 05 15:06:55 2009 +0200 +++ b/web/test/unittest_views_pyviews.py Fri Jun 05 15:09:20 2009 +0200 @@ -4,9 +4,9 @@ class PyViewsTC(EnvBasedTC): def test_pyvaltable(self): - content = self.vreg.view('pyvaltable', self.request(), - pyvalue=[[1, 'a'], [2, 'b']], - headers=['num', 'char']) + content = self.vreg.render('pyvaltable', self.request(), + pyvalue=[[1, 'a'], [2, 'b']], + headers=['num', 'char']) self.assertEquals(content.strip(), ''' @@ -14,8 +14,8 @@
numchar
1a
''') def test_pyvallist(self): - content = self.vreg.view('pyvallist', self.request(), - pyvalue=[1, 'a']) + content = self.vreg.render('pyvallist', self.request(), + pyvalue=[1, 'a']) self.assertEquals(content.strip(), '''
  • 1
  • a
  • diff -r 0a0cbccafcb5 -r 7ef12c03447c web/test/unittest_viewselector.py --- a/web/test/unittest_viewselector.py Fri Jun 05 15:06:55 2009 +0200 +++ b/web/test/unittest_viewselector.py Fri Jun 05 15:09:20 2009 +0200 @@ -234,7 +234,7 @@ req = self.request() # creation form req.form['etype'] = 'CWGroup' - self.assertIsInstance(self.vreg.select_view('creation', req, rset), + self.assertIsInstance(self.vreg.select('views', 'creation', req, rset=rset), editforms.CreationFormView) del req.form['etype'] # custom creation form @@ -243,94 +243,94 @@ self.vreg._loadedmods[__name__] = {} self.vreg.register_vobject_class(CWUserCreationForm) req.form['etype'] = 'CWUser' - self.assertIsInstance(self.vreg.select_view('creation', req, rset), + self.assertIsInstance(self.vreg.select('views', 'creation', req, rset=rset), CWUserCreationForm) def test_select_view(self): # no entity rset = None req = self.request() - self.assertIsInstance(self.vreg.select_view('index', req, rset), + self.assertIsInstance(self.vreg.select('views', 'index', req, rset=rset), startup.IndexView) self.failUnlessRaises(NoSelectableObject, - self.vreg.select_view, 'primary', req, rset) + self.vreg.select, 'views', 'primary', req, rset=rset) self.failUnlessRaises(NoSelectableObject, - self.vreg.select_view, 'table', req, rset) + self.vreg.select, 'views', 'table', req, rset=rset) # no entity rset, req = self.env.get_rset_and_req('Any X WHERE X eid 999999') self.failUnlessRaises(NoSelectableObject, - self.vreg.select_view, 'index', req, rset) + self.vreg.select, 'views', 'index', req, rset=rset) self.failUnlessRaises(NoSelectableObject, - self.vreg.select_view, 'creation', req, rset) + self.vreg.select, 'views', 'creation', req, rset=rset) self.failUnlessRaises(NoSelectableObject, - self.vreg.select_view, 'primary', req, rset) + self.vreg.select, 'views', 'primary', req, rset=rset) self.failUnlessRaises(NoSelectableObject, - self.vreg.select_view, 'table', req, rset) + self.vreg.select, 'views', 'table', req, rset=rset) # one entity rset, req = self.env.get_rset_and_req('CWGroup X WHERE X name "managers"') - self.assertIsInstance(self.vreg.select_view('primary', req, rset), + self.assertIsInstance(self.vreg.select('views', 'primary', req, rset=rset), primary.PrimaryView) - self.assertIsInstance(self.vreg.select_view('list', req, rset), + self.assertIsInstance(self.vreg.select('views', 'list', req, rset=rset), baseviews.ListView) - self.assertIsInstance(self.vreg.select_view('edition', req, rset), + self.assertIsInstance(self.vreg.select('views', 'edition', req, rset=rset), editforms.EditionFormView) - self.assertIsInstance(self.vreg.select_view('table', req, rset), + self.assertIsInstance(self.vreg.select('views', 'table', req, rset=rset), tableview.TableView) self.failUnlessRaises(NoSelectableObject, - self.vreg.select_view, 'creation', req, rset) + self.vreg.select, 'views', 'creation', req, rset=rset) self.failUnlessRaises(NoSelectableObject, - self.vreg.select_view, 'index', req, rset) + self.vreg.select, 'views', 'index', req, rset=rset) # list of entities of the same type rset, req = self.env.get_rset_and_req('CWGroup X') - self.assertIsInstance(self.vreg.select_view('primary', req, rset), + self.assertIsInstance(self.vreg.select('views', 'primary', req, rset=rset), primary.PrimaryView) - self.assertIsInstance(self.vreg.select_view('list', req, rset), + self.assertIsInstance(self.vreg.select('views', 'list', req, rset=rset), baseviews.ListView) - self.assertIsInstance(self.vreg.select_view('table', req, rset), + self.assertIsInstance(self.vreg.select('views', 'table', req, rset=rset), tableview.TableView) self.failUnlessRaises(NoSelectableObject, - self.vreg.select_view, 'creation', req, rset) + self.vreg.select, 'views', 'creation', req, rset=rset) # list of entities of different types rset, req = self.env.get_rset_and_req('Any X') - self.assertIsInstance(self.vreg.select_view('primary', req, rset), + self.assertIsInstance(self.vreg.select('views', 'primary', req, rset=rset), primary.PrimaryView) - self.assertIsInstance(self.vreg.select_view('list', req, rset), + self.assertIsInstance(self.vreg.select('views', 'list', req, rset=rset), baseviews.ListView) - self.assertIsInstance(self.vreg.select_view('table', req, rset), + self.assertIsInstance(self.vreg.select('views', 'table', req, rset=rset), tableview.TableView) self.failUnlessRaises(NoSelectableObject, - self.vreg.select_view, 'creation', req, rset) + self.vreg.select, 'views', 'creation', req, rset=rset) self.failUnlessRaises(NoSelectableObject, - self.vreg.select_view, 'index', req, rset) + self.vreg.select, 'views', 'index', req, rset=rset) # whatever rset, req = self.env.get_rset_and_req('Any N, X WHERE X in_group Y, Y name N') - self.assertIsInstance(self.vreg.select_view('table', req, rset), + self.assertIsInstance(self.vreg.select('views', 'table', req, rset=rset), tableview.TableView) self.failUnlessRaises(NoSelectableObject, - self.vreg.select_view, 'index', req, rset) + self.vreg.select, 'views', 'index', req, rset=rset) self.failUnlessRaises(NoSelectableObject, - self.vreg.select_view, 'creation', req, rset) + self.vreg.select, 'views', 'creation', req, rset=rset) self.failUnlessRaises(NoSelectableObject, - self.vreg.select_view, 'primary', req, rset) + self.vreg.select, 'views', 'primary', req, rset=rset) self.failUnlessRaises(NoSelectableObject, - self.vreg.select_view, 'list', req, rset) + self.vreg.select, 'views', 'list', req, rset=rset) self.failUnlessRaises(NoSelectableObject, - self.vreg.select_view, 'edition', req, rset) + self.vreg.select, 'views', 'edition', req, rset=rset) # mixed query rset, req = self.env.get_rset_and_req('Any U,G WHERE U is CWUser, G is CWGroup') self.failUnlessRaises(NoSelectableObject, - self.vreg.select_view, 'edition', req, rset) + self.vreg.select, 'views', 'edition', req, rset=rset) self.failUnlessRaises(NoSelectableObject, - self.vreg.select_view, 'creation', req, rset) - self.assertIsInstance(self.vreg.select_view('table', req, rset), + self.vreg.select, 'views', 'creation', req, rset=rset) + self.assertIsInstance(self.vreg.select('views', 'table', req, rset=rset), tableview.TableView) def test_interface_selector(self): image = self.add_entity('Image', name=u'bim.png', data=Binary('bim')) # image primary view priority rset, req = self.env.get_rset_and_req('Image X WHERE X name "bim.png"') - self.assertIsInstance(self.vreg.select_view('primary', req, rset), + self.assertIsInstance(self.vreg.select('views', 'primary', req, rset=rset), idownloadable.IDownloadablePrimaryView) @@ -338,12 +338,12 @@ image = self.add_entity('Image', name=u'bim.png', data=Binary('bim')) # image primary view priority rset, req = self.env.get_rset_and_req('Image X WHERE X name "bim.png"') - self.assertIsInstance(self.vreg.select_view('image', req, rset), + self.assertIsInstance(self.vreg.select('views', 'image', req, rset=rset), idownloadable.ImageView) fileobj = self.add_entity('File', name=u'bim.txt', data=Binary('bim')) # image primary view priority rset, req = self.env.get_rset_and_req('File X WHERE X name "bim.txt"') - self.assertRaises(NoSelectableObject, self.vreg.select_view, 'image', req, rset) + self.assertRaises(NoSelectableObject, self.vreg.select, 'views', 'image', req, rset=rset) @@ -354,7 +354,7 @@ else: rset, req = self.env.get_rset_and_req(rql) try: - self.vreg.render('views', vid, req, rset=rset, **args) + self.vreg.render(vid, req, rset=rset, **args) except: print vid, rset, args raise diff -r 0a0cbccafcb5 -r 7ef12c03447c web/views/basecomponents.py --- a/web/views/basecomponents.py Fri Jun 05 15:06:55 2009 +0200 +++ b/web/views/basecomponents.py Fri Jun 05 15:09:20 2009 +0200 @@ -45,7 +45,7 @@ -''' % (not self.propval('visible') and 'hidden' or '', +''' % (not self.propval('visible') and 'hidden' or '', self.build_url('view'), html_escape(rql), req._('full text or RQL query'), req.next_tabindex(), req.next_tabindex())) if self.req.search_state[0] != 'normal': diff -r 0a0cbccafcb5 -r 7ef12c03447c web/views/basecontrollers.py --- a/web/views/basecontrollers.py Fri Jun 05 15:06:55 2009 +0200 +++ b/web/views/basecontrollers.py Fri Jun 05 15:09:20 2009 +0200 @@ -128,12 +128,12 @@ req.set_message(req._("error while handling __method: %s") % req._(ex)) vid = req.form.get('vid') or vid_from_rset(req, rset, self.schema) try: - view = self.vreg.select_view(vid, req, rset) + view = self.vreg.select('views', vid, req, rset=rset) except ObjectNotFound: self.warning("the view %s could not be found", vid) req.set_message(req._("The view %s could not be found") % vid) vid = vid_from_rset(req, rset, self.schema) - view = self.vreg.select_view(vid, req, rset) + view = self.vreg.select('views', vid, req, rset=rset) except NoSelectableObject: if rset: req.set_message(req._("The view %s can not be applied to this query") % vid) @@ -141,7 +141,7 @@ req.set_message(req._("You have no access to this view or it's not applyable to current data")) self.warning("the view %s can not be applied to this query", vid) vid = vid_from_rset(req, rset, self.schema) - view = self.vreg.select_view(vid, req, rset) + view = self.vreg.select('views', vid, req, rset=rset) return view, rset def add_to_breadcrumbs(self, view): @@ -184,8 +184,8 @@ def publish(self, rset=None): vreg = self.vreg try: - ctrl = vreg.select(vreg.registry_objects('controllers', 'edit'), - req=self.req, appli=self.appli) + ctrl = vreg.select('controllers', 'edit', self.req, + appli=self.appli) except NoSelectableObject: status, args = (False, {None: self.req._('not authorized')}) else: @@ -254,6 +254,8 @@ except RemoteCallFailed: raise except Exception, ex: + import traceback + traceback.print_exc() self.exception('an exception occured while calling js_%s(%s): %s', fname, args, ex) raise RemoteCallFailed(repr(ex)) @@ -306,10 +308,10 @@ rset = None vid = req.form.get('vid') or vid_from_rset(req, rset, self.schema) try: - view = self.vreg.select_view(vid, req, rset) + view = self.vreg.select('views', vid, req, rset=rset) except NoSelectableObject: vid = req.form.get('fallbackvid', 'noresult') - view = self.vreg.select_view(vid, req, rset) + view = self.vreg.select('views', vid, req, rset=rset) divid = req.form.get('divid', 'pageContent') # we need to call pagination before with the stream set stream = view.set_stream() @@ -339,8 +341,7 @@ entity = self.vreg.etype_class('CWProperty')(self.req, None, None) entity.eid = varname entity['pkey'] = propkey - form = self.vreg.select_object('forms', 'edition', self.req, None, - entity=entity) + form = self.vreg.select('forms', 'edition', self.req, entity=entity) form.form_build_context() vfield = form.field_by_name('value') renderer = FormRenderer(self.req) @@ -353,7 +354,7 @@ rset = self._exec(rql) else: rset = None - comp = self.vreg.select_object(registry, compid, self.req, rset) + comp = self.vreg.select(registry, compid, self.req, rset=rset) if extraargs is None: extraargs = {} else: # we receive unicode keys which is not supported by the **syntax @@ -365,9 +366,8 @@ @check_pageid @xhtmlize def js_inline_creation_form(self, peid, ttype, rtype, role): - view = self.vreg.select_view('inline-creation', self.req, None, - etype=ttype, peid=peid, rtype=rtype, - role=role) + view = self.vreg.select('views', 'inline-creation', self.req, + etype=ttype, peid=peid, rtype=rtype, role=role) return view.render(etype=ttype, peid=peid, rtype=rtype, role=role) @jsonize @@ -380,8 +380,7 @@ self.req.form = self._rebuild_posted_form(names, values, action) vreg = self.vreg try: - ctrl = vreg.select(vreg.registry_objects('controllers', 'edit'), - req=self.req) + ctrl = vreg.select('controllers', 'edit', self.req) except NoSelectableObject: return (False, {None: self.req._('not authorized')}) try: diff -r 0a0cbccafcb5 -r 7ef12c03447c web/views/basetemplates.py --- a/web/views/basetemplates.py Fri Jun 05 15:06:55 2009 +0200 +++ b/web/views/basetemplates.py Fri Jun 05 15:09:20 2009 +0200 @@ -112,9 +112,9 @@ if vtitle: w(u'

    %s

    \n' % html_escape(vtitle)) # display entity type restriction component - etypefilter = self.vreg.select_component('etypenavigation', - self.req, self.rset) - if etypefilter and etypefilter.propval('visible'): + etypefilter = self.vreg.select_vobject('components', 'etypenavigation', + self.req, rset=self.rset) + if etypefilter: etypefilter.render(w=w) self.nav_html = UStringIO() if view and view.need_navigation: @@ -152,10 +152,12 @@ w(u'
    \n') self.nav_column(view, 'left') w(u'
    \n') - rqlcomp = self.vreg.select_component('rqlinput', self.req, self.rset) + rqlcomp = self.vreg.select_object('components', 'rqlinput', self.req, + rset=self.rset) if rqlcomp: rqlcomp.render(w=self.w, view=view) - msgcomp = self.vreg.select_component('applmessages', self.req, self.rset) + msgcomp = self.vreg.select_object('components', 'applmessages', + self.req, rset=self.rset) if msgcomp: msgcomp.render(w=self.w) self.content_header(view) @@ -169,7 +171,7 @@ self.w(u'') def nav_column(self, view, context): - boxes = list(self.vreg.possible_vobjects('boxes', self.req, self.rset, + boxes = list(self.vreg.possible_vobjects('boxes', self.req, rset=self.rset, view=view, context=context)) if boxes: self.w(u'