--- a/dbapi.py Tue May 19 11:50:15 2009 +0200
+++ b/dbapi.py Tue May 19 12:07:03 2009 +0200
@@ -325,6 +325,11 @@
self.vreg = None
# session's data
self.data = {}
+ # XXX < 3.2 bw compat
+ if 'EUser' in self._repo.get_schema():
+ self._user_etype = 'EUser'
+ else:
+ self._user_etype = 'CWUser'
def __repr__(self):
if self.anonymous_connection:
@@ -430,8 +435,8 @@
eid, login, groups, properties = self._repo.user_info(self.sessionid, props)
if req is None:
req = self.request()
- rset = req.eid_rset(eid, 'CWUser')
- user = self.vreg.etype_class('CWUser')(req, rset, row=0, groups=groups,
+ rset = req.eid_rset(eid, self._user_etype)
+ user = self.vreg.etype_class(self._user_etype)(req, rset, row=0, groups=groups,
properties=properties)
user['login'] = login # cache login
return user
--- a/devtools/devctl.py Tue May 19 11:50:15 2009 +0200
+++ b/devtools/devctl.py Tue May 19 12:07:03 2009 +0200
@@ -77,11 +77,11 @@
if mod.__file__.startswith(path):
del sys.modules[name]
break
- # fresh rtags
- from cubicweb import rtags
- from cubicweb.web import uicfg
- rtags.RTAGS[:] = []
- reload(uicfg)
+ # fresh rtags
+ from cubicweb import rtags
+ from cubicweb.web import uicfg
+ rtags.RTAGS[:] = []
+ reload(uicfg)
def generate_schema_pot(w, cubedir=None):
"""generate a pot file with schema specific i18n messages
--- a/devtools/fake.py Tue May 19 11:50:15 2009 +0200
+++ b/devtools/fake.py Tue May 19 12:07:03 2009 +0200
@@ -79,6 +79,11 @@
self._session_data = {}
self._headers = {}
+ def get_session_data(self, key, default=None, pop=False):
+ if pop:
+ return self._session_data.pop(key, default)
+ return self._session_data.get(key, default)
+
def header_accept_language(self):
"""returns an ordered list of preferred languages"""
return ('en',)
--- a/entities/__init__.py Tue May 19 11:50:15 2009 +0200
+++ b/entities/__init__.py Tue May 19 12:07:03 2009 +0200
@@ -57,16 +57,6 @@
return '%s DESC' % var
return None
- @classmethod
- def __initialize__(cls):
- super(ANYENTITY, cls).__initialize__() # XXX
- # set a default_ATTR method for rich text format fields
- # XXX move this away once the old widgets have been dropped!
- eschema = cls.e_schema
- for metaattr, (metadata, attr) in eschema.meta_attributes().iteritems():
- if metadata == 'format' and not hasattr(cls, 'default_%s' % metaattr):
- setattr(cls, 'default_%s' % metaattr, cls._default_format)
-
# meta data api ###########################################################
def dc_title(self):
@@ -269,9 +259,6 @@
from cubicweb.web.views.autoform import AutomaticEntityForm
return AutomaticEntityForm.esrelations_by_category(self, categories, permission)
- def _default_format(self):
- return self.req.property_value('ui.default-text-format')
-
def attribute_values(self, attrname):
if self.has_eid() or attrname in self:
try:
--- a/rtags.py Tue May 19 11:50:15 2009 +0200
+++ b/rtags.py Tue May 19 12:07:03 2009 +0200
@@ -24,7 +24,8 @@
This class associates a single tag to each key.
"""
_allowed_values = None
- def __init__(self, initfunc=None, allowed_values=None):
+ def __init__(self, name=None, initfunc=None, allowed_values=None):
+ self._name = name or '<unknown>'
self._tagdefs = {}
if allowed_values is not None:
self._allowed_values = allowed_values
@@ -32,7 +33,7 @@
register_rtag(self)
def __repr__(self):
- return repr(self._tagdefs)
+ return '%s: %s' % (self._name, repr(self._tagdefs))
# dict compat
def __getitem__(self, key):
@@ -95,7 +96,9 @@
#else:
stype, rtype, otype, tagged = [str(k) for k in key]
if self._allowed_values is not None:
- assert tag in self._allowed_values, '%r is not an allowed tag' % tag
+ assert tag in self._allowed_values, \
+ '%r is not an allowed tag (should be in %s)' % (
+ tag, self._allowed_values)
self._tagdefs[(rtype, tagged, stype, otype)] = tag
# rtag runtime api ########################################################
--- a/web/form.py Tue May 19 11:50:15 2009 +0200
+++ b/web/form.py Tue May 19 12:07:03 2009 +0200
@@ -372,10 +372,15 @@
return self.form_previous_values[qname]
if qname in self.req.form:
return self.req.form[qname]
+ if field.name in self.req.form:
+ return self.req.form[field.name]
return None
def form_field_value(self, field, load_bytes=False):
"""return field's *typed* value"""
+ myattr = '%s_%s_default' % (field.role, field.name)
+ if hasattr(self, myattr):
+ return getattr(self, myattr)()
value = field.initial
if callable(value):
value = value(self)
--- a/web/formfields.py Tue May 19 11:50:15 2009 +0200
+++ b/web/formfields.py Tue May 19 12:07:03 2009 +0200
@@ -213,20 +213,21 @@
try:
return req.data[self]
except KeyError:
+ fkwargs = {}
if self.use_fckeditor(form):
# if fckeditor is used and format field isn't explicitly
# deactivated, we want an hidden field for the format
- widget = HiddenInput()
- choices = None
+ fkwargs['widget'] = HiddenInput()
+ fkwargs['initial'] = 'text/html'
else:
# else we want a format selector
- # XXX compute vocabulary
- widget = Select()
+ fkwargs['widget'] = Select()
+ fkwargs['widget'].attrs['size'] = 1
fcstr = FormatConstraint()
- choices = [(req._(fmt), fmt) for fmt in fcstr.vocabulary(req=req)]
- widget.attrs['size'] = 1
- field = StringField(name=self.name + '_format', widget=widget,
- choices=choices)
+ fkwargs['choices'] = fcstr.vocabulary(req=req)
+ fkwargs['internationalizable'] = True
+ fkwargs['initial'] = lambda f: f.form_field_format(self)
+ field = StringField(name=self.name + '_format', **fkwargs)
req.data[self] = field
return field
--- a/web/test/unittest_form.py Tue May 19 11:50:15 2009 +0200
+++ b/web/test/unittest_form.py Tue May 19 12:07:03 2009 +0200
@@ -64,7 +64,14 @@
self.assertEquals(len(states), 1)
self.assertEquals(states[0][0], u'deactivated') # list of (combobox view, state eid)
-
+ def test_consider_req_form_params(self):
+ e = self.etype_instance('CWUser')
+ e.eid = 'A'
+ form = EntityFieldsForm(self.request(login=u'toto'), None, entity=e)
+ field = StringField(name='login', eidparam=True)
+ form.append_field(field)
+ form.form_build_context({})
+ self.assertEquals(form.form_field_display_value(field, {}), 'toto')
# form view tests #########################################################
--- a/web/test/unittest_formfields.py Tue May 19 11:50:15 2009 +0200
+++ b/web/test/unittest_formfields.py Tue May 19 12:07:03 2009 +0200
@@ -1,12 +1,15 @@
"""unittests for cw.web.formfields"""
+from logilab.common.testlib import TestCase, unittest_main
+
from yams.constraints import StaticVocabularyConstraint, SizeConstraint
-from logilab.common.testlib import TestCase, unittest_main
+
from cubicweb.devtools import TestServerConfiguration
+from cubicweb.devtools.testlib import EnvBasedTC
+from cubicweb.web.form import EntityFieldsForm
from cubicweb.web.formwidgets import PasswordInput, TextArea, Select
from cubicweb.web.formfields import *
-from cubicweb.entities.wfobjs import State
-from cubicweb.entities.authobjs import CWUser
+
from cubes.file.entities import File
config = TestServerConfiguration('data')
@@ -43,12 +46,13 @@
self.assertEquals(description_format_field.sort, True)
self.assertEquals(description_format_field.initial(None), 'text/rest')
+
# wikiid_field = guess_field(state_schema, schema['wikiid'])
# self.assertIsInstance(wikiid_field, StringField)
# self.assertEquals(wikiid_field.required, False)
- def test_euser_fields(self):
+ def test_cwuser_fields(self):
upassword_field = guess_field(cwuser_schema, schema['upassword'])
self.assertIsInstance(upassword_field, StringField)
self.assertIsInstance(upassword_field.widget, PasswordInput)
@@ -89,5 +93,21 @@
[SizeConstraint, StaticVocabularyConstraint])
self.assertIsInstance(salesterm_field.widget, Select)
+class MoreFieldsTC(EnvBasedTC):
+ def test_rtf_format_field(self):
+ req = self.request()
+ req.use_fckeditor = lambda: False
+ e = self.etype_instance('State')
+ form = EntityFieldsForm(req, entity=e)
+ description_field = guess_field(state_schema, schema['description'])
+ description_format_field = description_field.get_format_field(form)
+ self.assertEquals(description_format_field.internationalizable, True)
+ self.assertEquals(description_format_field.sort, True)
+ # unlike below, initial is bound to form.form_field_format
+ self.assertEquals(description_format_field.initial(form), 'text/html')
+ self.execute('INSERT CWProperty X: X pkey "ui.default-text-format", X value "text/rest", X for_user U WHERE U login "admin"')
+ self.commit()
+ self.assertEquals(description_format_field.initial(form), 'text/rest')
+
if __name__ == '__main__':
unittest_main()
--- a/web/uicfg.py Tue May 19 11:50:15 2009 +0200
+++ b/web/uicfg.py Tue May 19 12:07:03 2009 +0200
@@ -97,8 +97,9 @@
section = 'sideboxes'
rtag.tag_relation((sschema, rschema, oschema, role), section)
-primaryview_section = RelationTags(init_primaryview_section,
- frozenset(('attributes', 'relations',
+primaryview_section = RelationTags('primaryview_section',
+ init_primaryview_section,
+ frozenset(('attributes', 'relations',
'sideboxes', 'hidden')))
for rtype in ('eid', 'creation_date', 'modification_date',
'is', 'is_instance_of', 'identity',
@@ -140,7 +141,8 @@
rtag.tag_relation((sschema, rschema, oschema, role), displayinfo)
displayinfo.setdefault('label', label)
-primaryview_display_ctrl = DisplayCtrlRelationTags(init_primaryview_display_ctrl)
+primaryview_display_ctrl = DisplayCtrlRelationTags('primaryview_display_ctrl',
+ init_primaryview_display_ctrl)
# index view configuration ####################################################
@@ -178,7 +180,7 @@
section = 'generic'
rtag.tag_relation((sschema, rschema, oschema, role), section)
-autoform_section = RelationTags(init_autoform_section,
+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
@@ -217,7 +219,7 @@
# relations'field class
-autoform_field = RelationTags()
+autoform_field = RelationTags('autoform_field')
# relations'field explicit kwargs (given to field's __init__)
autoform_field_kwargs = RelationTags()
@@ -231,7 +233,7 @@
# 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 = 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)
@@ -241,7 +243,7 @@
# set of tags of the form <action>_on_new on relations. <action> is a
# schema action (add/update/delete/read), and when such a tag is found
# permissions checking is by-passed and supposed to be ok
-autoform_permissions_overrides = RelationTagsSet()
+autoform_permissions_overrides = RelationTagsSet('autoform_permissions_overrides')
# boxes.EditBox configuration #################################################
@@ -254,7 +256,8 @@
rschema.rproperty(sschema, oschema, 'composite') == role:
rtag.tag_relation((sschema, rschema, oschema, role), True)
-actionbox_appearsin_addmenu = RelationTagsBool(init_actionbox_appearsin_addmenu)
+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)
--- a/web/views/basecontrollers.py Tue May 19 11:50:15 2009 +0200
+++ b/web/views/basecontrollers.py Tue May 19 12:07:03 2009 +0200
@@ -382,11 +382,7 @@
ctrl.publish(None, fromjson=True)
except ValidationError, err:
self.req.cnx.rollback()
- if not err.entity or isinstance(err.entity, (long, int)):
- eid = err.entity
- else:
- eid = err.entity.eid
- return (False, (eid, err.errors))
+ return (False, (err.entity, err.errors))
except Redirect, redir:
return (True, redir.location)
except Exception, err:
@@ -487,6 +483,24 @@
rql = 'DELETE B bookmarked_by U WHERE B eid %(b)s, U eid %(u)s'
self.req.execute(rql, {'b': typed_eid(beid), 'u' : self.req.user.eid})
+ def js_node_clicked(self, treeid, nodeeid):
+ """add/remove eid in treestate cookie"""
+ from cubicweb.web.views.treeview import treecookiename
+ cookies = self.req.get_cookie()
+ statename = treecookiename(treeid)
+ treestate = cookies.get(statename)
+ if treestate is None:
+ cookies[statename] = nodeeid
+ self.req.set_cookie(cookies, statename)
+ else:
+ marked = set(filter(None, treestate.value.split(';')))
+ if nodeeid in marked:
+ marked.remove(nodeeid)
+ else:
+ marked.add(nodeeid)
+ cookies[statename] = ';'.join(marked)
+ self.req.set_cookie(cookies, statename)
+
def js_set_cookie(self, cookiename, cookievalue):
# XXX we should consider jQuery.Cookie
cookiename, cookievalue = str(cookiename), str(cookievalue)
--- a/web/views/basetemplates.py Tue May 19 11:50:15 2009 +0200
+++ b/web/views/basetemplates.py Tue May 19 12:07:03 2009 +0200
@@ -7,7 +7,6 @@
"""
__docformat__ = "restructuredtext en"
-
from logilab.mtconverter import html_escape
from cubicweb.vregistry import objectify_selector
--- a/web/views/boxes.py Tue May 19 11:50:15 2009 +0200
+++ b/web/views/boxes.py Tue May 19 12:07:03 2009 +0200
@@ -99,10 +99,10 @@
eschema = entity.e_schema
for rschema, teschema, x in self.add_related_schemas(entity):
if x == 'subject':
- label = '%s %s %s %s' % (eschema, rschema, teschema, x)
+ label = 'add %s %s %s %s' % (eschema, rschema, teschema, x)
url = self.linkto_url(entity, rschema, teschema, 'object')
else:
- label = '%s %s %s %s' % (teschema, rschema, eschema, x)
+ label = 'add %s %s %s %s' % (teschema, rschema, eschema, x)
url = self.linkto_url(entity, rschema, teschema, 'subject')
actions.append(self.mk_action(_(label), url))
return actions
--- a/web/views/editforms.py Tue May 19 11:50:15 2009 +0200
+++ b/web/views/editforms.py Tue May 19 12:07:03 2009 +0200
@@ -52,7 +52,7 @@
# else we will only delete the displayed page
need_navigation = False
- def call(self):
+ def call(self, onsubmit=None):
"""ask for confirmation before real deletion"""
req, w = self.req, self.w
_ = req._
@@ -61,7 +61,7 @@
# XXX above message should have style of a warning
w(u'<h4>%s</h4>\n' % _('Do you want to delete the following element(s) ?'))
form = CompositeForm(req, domid='deleteconf', copy_nav_params=True,
- action=self.build_url('edit'), onsubmit=None,
+ action=self.build_url('edit'), onsubmit=onsubmit,
form_buttons=[Button(stdmsgs.YES, cwaction='delete'),
Button(stdmsgs.NO, cwaction='cancel')])
done = set()
@@ -350,7 +350,8 @@
def render_form(self, entity, peid, rtype, role, **kwargs):
"""fetch and render the form"""
form = self.vreg.select_object('forms', 'edition', self.req, None,
- entity=entity, set_error_url=False)
+ entity=entity, set_error_url=False,
+ copy_nav_params=False)
self.add_hiddens(form, entity, peid, rtype, role)
divid = '%s-%s-%s' % (peid, rtype, entity.eid)
title = self.schema.rschema(rtype).display_name(self.req, role)
--- a/web/views/treeview.py Tue May 19 11:50:15 2009 +0200
+++ b/web/views/treeview.py Tue May 19 12:07:03 2009 +0200
@@ -13,7 +13,6 @@
from cubicweb.interfaces import ITree
from cubicweb.selectors import implements
from cubicweb.view import EntityView
-from cubicweb.web.views.basecontrollers import jsonize, JSonController
def treecookiename(treeid):
return str('treestate-%s' % treeid)
@@ -149,21 +148,3 @@
self.wview(parentvid, self.req.execute(rql), treeid=treeid, initial_load=False)
w(u'</li>')
-@monkeypatch(JSonController)
-@jsonize
-def js_node_clicked(self, treeid, nodeeid):
- """add/remove eid in treestate cookie"""
- cookies = self.req.get_cookie()
- statename = treecookiename(treeid)
- treestate = cookies.get(statename)
- if treestate is None:
- cookies[statename] = nodeeid
- self.req.set_cookie(cookies, statename)
- else:
- marked = set(filter(None, treestate.value.split(';')))
- if nodeeid in marked:
- marked.remove(nodeeid)
- else:
- marked.add(nodeeid)
- cookies[statename] = ';'.join(marked)
- self.req.set_cookie(cookies, statename)