[cleanup] Fix some flake8 errors
and drop upper bound of copyright along the way.
autoform module is not added to flake8-ok-files since there are some remaining
errors to be handled, but that's still a start.
--- a/cubicweb/schema.py Fri Oct 06 11:45:52 2017 +0200
+++ b/cubicweb/schema.py Fri Oct 06 14:24:35 2017 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2016 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -19,9 +19,8 @@
from __future__ import print_function
-import pkgutil
import re
-from os.path import join, basename
+from os.path import join
from hashlib import md5
from logging import getLogger
from warnings import warn
@@ -29,7 +28,6 @@
from six import PY2, text_type, string_types, add_metaclass
from six.moves import range
-from logilab.common import tempattr
from logilab.common.decorators import cached, clear_cache, monkeypatch, cachedproperty
from logilab.common.logging_ext import set_log_methods
from logilab.common.deprecation import deprecated
@@ -44,14 +42,15 @@
cstr_json_dumps, cstr_json_loads)
from yams.reader import (CONSTRAINTS, PyFileReader, SchemaLoader,
cleanup_sys_modules, fill_schema_from_namespace)
+from yams.buildobjs import _add_relation as yams_add_relation
-from rql import parse, nodes, RQLSyntaxError, TypeResolverException
+from rql import parse, nodes, stmts, RQLSyntaxError, TypeResolverException
from rql.analyze import ETypeResolver
import cubicweb
+from cubicweb import server
from cubicweb import ETYPE_NAME_MAP, ValidationError, Unauthorized, _
-from cubicweb import server
PURE_VIRTUAL_RTYPES = set(('identity', 'has_text',))
VIRTUAL_RTYPES = set(('eid', 'identity', 'has_text',))
@@ -602,6 +601,8 @@
a given form
"""
return display_name(req, self.type, form, context)
+
+
ERSchema.display_name = ERSchema_display_name
@@ -621,6 +622,8 @@
return frozenset(g for g in self.permissions[action] if isinstance(g, string_types))
except KeyError:
return ()
+
+
PermissionMixIn.get_groups = get_groups
@@ -640,6 +643,8 @@
return tuple(g for g in self.permissions[action] if not isinstance(g, string_types))
except KeyError:
return ()
+
+
PermissionMixIn.get_rqlexprs = get_rqlexprs
@@ -656,6 +661,8 @@
orig_set_action_permissions(self, action, tuple(permissions))
clear_cache(self, 'get_rqlexprs')
clear_cache(self, 'get_groups')
+
+
orig_set_action_permissions = PermissionMixIn.set_action_permissions
PermissionMixIn.set_action_permissions = set_action_permissions
@@ -673,6 +680,8 @@
if action in ('update', 'delete'):
return 'owners' in self.get_groups(action)
return False
+
+
PermissionMixIn.has_local_role = has_local_role
@@ -681,6 +690,8 @@
self.has_perm(req, 'read')):
return False
return self.has_local_role(action) or self.has_perm(req, action)
+
+
PermissionMixIn.may_have_permission = may_have_permission
@@ -691,6 +702,8 @@
return True
except Unauthorized:
return False
+
+
PermissionMixIn.has_perm = has_perm
@@ -734,6 +747,8 @@
for rqlexpr in self.get_rqlexprs(action)):
return
raise Unauthorized(action, str(self))
+
+
PermissionMixIn.check_perm = check_perm
@@ -818,7 +833,7 @@
"""convenience method that returns the *main* (i.e. the first non meta)
attribute defined in the entity schema
"""
- for rschema, _ in self.attribute_definitions():
+ for rschema, __ in self.attribute_definitions():
if not (rschema in META_RTYPES
or self.is_metadata(rschema)):
return rschema
@@ -1262,7 +1277,7 @@
#
# possible enhancement: check entity being created, it's probably
# the main eid unless this is a composite relation
- if eidto is None or 'S' in self.mainvars or not 'O' in self.mainvars:
+ if eidto is None or 'S' in self.mainvars or 'O' not in self.mainvars:
maineid = eidfrom
qname = role_name(rtype, 'subject')
else:
@@ -1272,7 +1287,7 @@
msg = session._(self.msg)
else:
msg = '%(constraint)s %(expression)s failed' % {
- 'constraint': session._(self.type()),
+ 'constraint': session._(self.type()),
'expression': self.expression}
raise ValidationError(maineid, {qname: msg})
@@ -1320,9 +1335,6 @@
# workflow extensions #########################################################
-from yams.buildobjs import _add_relation as yams_add_relation
-
-
class workflowable_definition(ybo.metadefinition):
"""extends default EntityType's metaclass to add workflow relations
(i.e. in_state, wf_info_for and custom_workflow). This is the default
@@ -1409,7 +1421,8 @@
"""
self.info('loading %s schemas', ', '.join(config.cubes()))
try:
- return super(CubicWebSchemaLoader, self).load(config, config.schema_modnames(), **kwargs)
+ return super(CubicWebSchemaLoader, self).load(
+ config, config.schema_modnames(), **kwargs)
finally:
# we've to cleanup modules imported from cubicweb.schemas as well
cleanup_sys_modules([join(cubicweb.CW_SOFTWARE_ROOT, 'schemas')])
@@ -1448,29 +1461,36 @@
return self.regular_formats + tuple(NEED_PERM_FORMATS)
return self.regular_formats
+
# XXX itou for some Statement methods
-from rql import stmts
-
def bw_get_etype(self, name):
return orig_get_etype(self, bw_normalize_etype(name))
+
+
orig_get_etype = stmts.ScopeNode.get_etype
stmts.ScopeNode.get_etype = bw_get_etype
def bw_add_main_variable_delete(self, etype, vref):
return orig_add_main_variable_delete(self, bw_normalize_etype(etype), vref)
+
+
orig_add_main_variable_delete = stmts.Delete.add_main_variable
stmts.Delete.add_main_variable = bw_add_main_variable_delete
def bw_add_main_variable_insert(self, etype, vref):
return orig_add_main_variable_insert(self, bw_normalize_etype(etype), vref)
+
+
orig_add_main_variable_insert = stmts.Insert.add_main_variable
stmts.Insert.add_main_variable = bw_add_main_variable_insert
def bw_set_statement_type(self, etype):
return orig_set_statement_type(self, bw_normalize_etype(etype))
+
+
orig_set_statement_type = stmts.Select.set_statement_type
stmts.Select.set_statement_type = bw_set_statement_type
--- a/cubicweb/web/test/unittest_uicfg.py Fri Oct 06 11:45:52 2017 +0200
+++ b/cubicweb/web/test/unittest_uicfg.py Fri Oct 06 14:24:35 2017 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -15,6 +15,7 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
+
import copy
import warnings
@@ -25,13 +26,13 @@
abaa = uicfg.actionbox_appearsin_addmenu
+
class UICFGTC(CubicWebTC):
def test_default_actionbox_appearsin_addmenu_config(self):
self.assertFalse(abaa.etype_get('TrInfo', 'wf_info_for', 'object', 'CWUser'))
-
class DefinitionOrderTC(CubicWebTC):
"""This test check that when multiple definition could match a key, only
the more accurate apply"""
@@ -41,19 +42,19 @@
for rtag in (uicfg.autoform_section, uicfg.autoform_field_kwargs):
rtag._old_tagdefs = copy.deepcopy(rtag._tagdefs)
new_def = (
- (('*', 'login', '*'),
- {'formtype':'main', 'section':'hidden'}),
- (('*', 'login', '*'),
- {'formtype':'muledit', 'section':'hidden'}),
- (('CWUser', 'login', '*'),
- {'formtype':'main', 'section':'attributes'}),
- (('CWUser', 'login', '*'),
- {'formtype':'muledit', 'section':'attributes'}),
- (('CWUser', 'login', 'String'),
- {'formtype':'main', 'section':'inlined'}),
- (('CWUser', 'login', 'String'),
- {'formtype':'inlined', 'section':'attributes'}),
- )
+ (('*', 'login', '*'),
+ {'formtype': 'main', 'section': 'hidden'}),
+ (('*', 'login', '*'),
+ {'formtype': 'muledit', 'section': 'hidden'}),
+ (('CWUser', 'login', '*'),
+ {'formtype': 'main', 'section': 'attributes'}),
+ (('CWUser', 'login', '*'),
+ {'formtype': 'muledit', 'section': 'attributes'}),
+ (('CWUser', 'login', 'String'),
+ {'formtype': 'main', 'section': 'inlined'}),
+ (('CWUser', 'login', 'String'),
+ {'formtype': 'inlined', 'section': 'attributes'}),
+ )
for key, kwargs in new_def:
uicfg.autoform_section.tag_subject_of(key, **kwargs)
@@ -120,10 +121,12 @@
@tag('uihelper', 'hidden', 'formconfig')
def test_uihelper_formconfig(self):
afk_get = uicfg.autoform_field_kwargs.get
+
class CWUserFormConfig(uihelper.FormConfig):
etype = 'CWUser'
hidden = ('in_group',)
fields_order = ('login', 'firstname')
+
section_conf = uicfg.autoform_section.get('CWUser', 'in_group', '*', 'subject')
self.assertCountEqual(section_conf, ['main_hidden', 'muledit_attributes'])
self.assertEqual(afk_get('CWUser', 'firstname', 'String', 'subject'), {'order': 1})
--- a/cubicweb/web/views/autoform.py Fri Oct 06 11:45:52 2017 +0200
+++ b/cubicweb/web/views/autoform.py Fri Oct 06 14:24:35 2017 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -118,16 +118,10 @@
.. Controlling the generic relation fields
"""
-
-from cubicweb import _
-
-from warnings import warn
-
from six.moves import range
from logilab.mtconverter import xml_escape
from logilab.common.decorators import iclassmethod, cached
-from logilab.common.deprecation import deprecated
from logilab.common.registry import NoSelectableObject
from cubicweb import neg_role, uilib
@@ -185,7 +179,7 @@
return False
def process_posted(self, form):
- pass # handled by the subform
+ pass # handled by the subform
class InlineEntityEditionFormView(f.FormViewMixIn, EntityView):
@@ -237,7 +231,7 @@
**self.cw_extra_kwargs)
if self.pform is None:
form.restore_previous_post(form.session_key())
- #assert form.parent_form
+ # assert form.parent_form
self.add_hiddens(form, entity)
return form
@@ -261,7 +255,7 @@
entity = self._entity()
rdef = entity.e_schema.rdef(self.rtype, neg_role(self.role), self.petype)
card = rdef.role_cardinality(self.role)
- if card == '1': # don't display remove link
+ if card == '1': # don't display remove link
return None
# if cardinality is 1..n (+), dont display link to remove an inlined form for the first form
# allowing to edit the relation. To detect so:
@@ -294,7 +288,7 @@
except KeyError:
self._cw.data[countkey] = 1
self.form.render(w=self.w, divid=divid, title=title, removejs=removejs,
- i18nctx=i18nctx, counter=self._cw.data[countkey] ,
+ i18nctx=i18nctx, counter=self._cw.data[countkey],
**kwargs)
def form_title(self, entity, i18nctx):
@@ -374,21 +368,21 @@
& specified_etype_implements('Any'))
_select_attrs = InlineEntityCreationFormView._select_attrs + ('card',)
- card = None # make pylint happy
- form = None # no actual form wrapped
+ card = None # make pylint happy
+ form = None # no actual form wrapped
def call(self, i18nctx, **kwargs):
self._cw.set_varmaker()
divid = "addNew%s%s%s:%s" % (self.etype, self.rtype, self.role, self.peid)
self.w(u'<div class="inlinedform" id="%s" cubicweb:limit="true">'
- % divid)
+ % divid)
js = "addInlineCreationForm('%s', '%s', '%s', '%s', '%s', '%s')" % (
self.peid, self.petype, self.etype, self.rtype, self.role, i18nctx)
if self.pform.should_hide_add_new_relation_link(self.rtype, self.card):
js = "toggleVisibility('%s'); %s" % (divid, js)
__ = self._cw.pgettext
self.w(u'<a class="addEntity" id="add%s:%slink" href="javascript: %s" >+ %s.</a>'
- % (self.rtype, self.peid, js, __(i18nctx, 'add a %s' % self.etype)))
+ % (self.rtype, self.peid, js, __(i18nctx, 'add a %s' % self.etype)))
self.w(u'</div>')
@@ -400,6 +394,7 @@
return u'%s:%s:%s' % (eid, rtype, reid)
return u'%s:%s:%s' % (reid, rtype, eid)
+
def toggleable_relation_link(eid, nodeid, label='x'):
"""return javascript snippet to delete/undelete a relation between two
entities
@@ -420,6 +415,7 @@
return ['%s:%s:%s' % (subj, rel, obj) for subj, rel, obj in pending
if eid is None or eid in (subj, obj)]
+
def get_pending_deletes(req, eid=None):
"""shortcut to access req's pending_delete entry
@@ -430,6 +426,7 @@
return ['%s:%s:%s' % (subj, rel, obj) for subj, rel, obj in pending
if eid is None or eid in (subj, obj)]
+
def parse_relations_descr(rdescr):
"""parse a string describing some relations, in the form
subjeids:rtype:objeids
@@ -443,6 +440,7 @@
for obj in objs.split('_'):
yield int(subj), rtype, int(obj)
+
def delete_relations(req, rdefs):
"""delete relations from the repository"""
# FIXME convert to using the syntax subject:relation:eids
@@ -452,6 +450,7 @@
execute(rql, {'x': subj, 'y': obj})
req.set_message(req._('relations deleted'))
+
def insert_relations(req, rdefs):
"""insert relations into the repository"""
execute = req.execute
@@ -468,10 +467,12 @@
peid=peid, petype=petype)
return self._call_view(view, i18nctx=i18nctx)
+
@ajaxfunc(output_type='json')
def validate_form(self, action, names, values):
return self.validate_form(action, names, values)
+
@ajaxfunc
def cancel_edition(self, errorurl):
"""cancelling edition from javascript
@@ -491,6 +492,7 @@
pendings.append(value)
req.session.data[key] = pendings
+
def _remove_pending(req, eidfrom, rel, eidto, kind):
key = 'pending_%s' % kind
pendings = req.session.data[key]
@@ -499,21 +501,25 @@
pendings.remove(value)
req.session.data[key] = pendings
+
@ajaxfunc(output_type='json')
def remove_pending_insert(self, args):
eidfrom, rel, eidto = args
_remove_pending(self._cw, eidfrom, rel, eidto, 'insert')
+
@ajaxfunc(output_type='json')
def add_pending_inserts(self, tripletlist):
for eidfrom, rel, eidto in tripletlist:
_add_pending(self._cw, eidfrom, rel, eidto, 'insert')
+
@ajaxfunc(output_type='json')
def remove_pending_delete(self, args):
eidfrom, rel, eidto = args
_remove_pending(self._cw, eidfrom, rel, eidto, 'delete')
+
@ajaxfunc(output_type='json')
def add_pending_delete(self, args):
eidfrom, rel, eidto = args
@@ -527,7 +533,6 @@
w = stream.append
req = form._cw
_ = req._
- __ = _
eid = form.edited_entity.eid
w(u'<table id="relatedEntities">')
for rschema, role, related in field.relations_table(form):
@@ -541,9 +546,9 @@
w(u'<li>%s<span id="span%s" class="%s">%s</span></li>'
% (viewparams[1], viewparams[0], viewparams[2], viewparams[3]))
if not form.force_display and form.maxrelitems < len(related):
- link = (u'<span>'
- '[<a href="javascript: window.location.href+=\'&__force_display=1\'">%s</a>]'
- '</span>' % _('view all'))
+ link = (u'<span>[<a '
+ 'href="javascript: window.location.href+=\'&__force_display=1\'"'
+ '>%s</a>]</span>' % _('view all'))
w(u'<li>%s</li>' % link)
w(u'</ul>')
w(u'</td>')
@@ -619,7 +624,8 @@
if rschema.has_perm(form._cw, 'delete', **haspermkwargs):
toggleable_rel_link_func = toggleable_relation_link
else:
- toggleable_rel_link_func = lambda x, y, z: u''
+ def toggleable_rel_link_func(x, y, z):
+ return u''
for row in range(rset.rowcount):
nodeid = relation_id(entity.eid, rschema, role,
rset[row][0])
@@ -641,7 +647,7 @@
for pendingid in pending_inserts:
eidfrom, rtype, eidto = pendingid.split(':')
pendingid = 'id' + pendingid
- if int(eidfrom) == entity.eid: # subject
+ if int(eidfrom) == entity.eid: # subject
label = display_name(form._cw, rtype, 'subject',
entity.cw_etype)
reid = eidto
@@ -687,13 +693,14 @@
relname, role = self._cw.form.get('relation').rsplit('_', 1)
return u"""\
<div class="%s" id="%s">
- <select id="%s" onchange="javascript: addPendingInsert(this.options[this.selectedIndex], %s, %s, '%s');">
+ <select id="%s"
+ onchange="javascript: addPendingInsert(this.options[this.selectedIndex], %s, %s, '%s');">
%s
</select>
</div>
""" % (hidden and 'hidden' or '', divid, selectid,
- xml_escape(json_dumps(entity.eid)), is_cell and 'true' or 'null', relname,
- '\n'.join(options))
+ xml_escape(json_dumps(entity.eid)), is_cell and 'true' or 'null',
+ relname, '\n'.join(options))
def _get_select_options(self, entity, rschema, role):
"""add options to search among all entities of each possible type"""
@@ -706,7 +713,7 @@
# NOTE: expect 'limit' arg on choices method of relation field
for eview, reid in field.vocabulary(form, limit=limit):
if reid is None:
- if eview: # skip blank value
+ if eview: # skip blank value
options.append('<option class="separator">-- %s --</option>'
% xml_escape(eview))
elif reid != ff.INTERNAL_FIELD_VALUE:
@@ -724,7 +731,7 @@
for eschema in targettypes:
mode = '%s:%s:%s:%s' % (role, entity.eid, rschema.type, eschema)
url = self._cw.build_url(entity.rest_path(), vid='search-associate',
- __mode=mode)
+ __mode=mode)
options.append((eschema.display_name(self._cw),
'<option value="%s">%s %s</option>' % (
xml_escape(url), _('Search for'), eschema.display_name(self._cw))))
@@ -784,7 +791,7 @@
for rtype, role in self.editable_attributes():
try:
self.field_by_name(str(rtype), role)
- continue # explicitly specified
+ continue # explicitly specified
except f.FieldNotFound:
# has to be guessed
try:
@@ -803,7 +810,7 @@
for formview in self.inlined_form_views():
field = self._inlined_form_view_field(formview)
self.fields.append(field)
- if not field.fieldset in fsio:
+ if field.fieldset not in fsio:
fsio.append(field.fieldset)
if self.formtype == 'main':
# add the generic relation field if necessary
@@ -817,7 +824,7 @@
pass
else:
self.fields.append(field)
- if not field.fieldset in fsio:
+ if field.fieldset not in fsio:
fsio.append(field.fieldset)
self.maxrelitems = self._cw.property_value('navigation.related-limit')
self.force_display = bool(self._cw.form.get('__force_display'))
@@ -949,7 +956,7 @@
relation.
"""
return (self.should_display_add_new_relation_link(
- rschema, existing, card) and
+ rschema, existing, card) and
self.check_inlined_rdef_permissions(
rschema, role, tschema, ttype))
@@ -968,7 +975,6 @@
return rdef.has_perm(self._cw, 'add', **rdefkwargs)
return rdef.may_have_permission('add', self._cw)
-
def should_hide_add_new_relation_link(self, rschema, card):
"""return true if once an inlined creation form is added, the 'add new'
link should be hidden
@@ -1009,7 +1015,7 @@
pass
-## default form ui configuration ##############################################
+# default form ui configuration ##############################################
_AFS = uicfg.autoform_section
# use primary and not generated for eid since it has to be an hidden
@@ -1049,6 +1055,7 @@
_AFFK.tag_subject_of(('TrInfo', 'wf_info_for', '*'),
{'widget': fw.HiddenInput})
+
def registration_callback(vreg):
global etype_relation_field
--- a/cubicweb/web/views/cwuser.py Fri Oct 06 11:45:52 2017 +0200
+++ b/cubicweb/web/views/cwuser.py Fri Oct 06 14:24:35 2017 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -20,7 +20,7 @@
from cubicweb import _
-from hashlib import sha1 # pylint: disable=E0611
+from hashlib import sha1 # pylint: disable=E0611
from six import text_type
from six.moves import range
@@ -28,7 +28,6 @@
from logilab.mtconverter import xml_escape
from cubicweb import tags
-from cubicweb.schema import display_name
from cubicweb.predicates import one_line_rset, is_instance, match_user_groups
from cubicweb.view import EntityView, StartupView
from cubicweb.web import action, formwidgets
@@ -39,7 +38,8 @@
_affk = uicfg.autoform_field_kwargs
_affk.tag_subject_of(('CWUser', 'in_group', 'CWGroup'),
- {'widget': formwidgets.InOutWidget})
+ {'widget': formwidgets.InOutWidget})
+
class UserPreferencesEntityAction(action.Action):
__regid__ = 'prefs'
@@ -66,7 +66,7 @@
self.w(u'''<?xml version="1.0" encoding="%s"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3org/2000/01/rdf-schema#"
- xmlns:foaf="http://xmlns.com/foaf/0.1/"> '''% self._cw.encoding)
+ xmlns:foaf="http://xmlns.com/foaf/0.1/"> ''' % self._cw.encoding)
for i in range(self.cw_rset.rowcount):
self.cell_call(i, 0)
self.w(u'</rdf:RDF>\n')
@@ -121,6 +121,7 @@
'U last_login_time LL, G eid %(x)s', {'x': entity.eid})
self.wview('cwgroup.users', rset, 'null')
+
class CWGroupUsersTable(tableview.RsetTableView):
__regid__ = 'cwgroup.users'
__select__ = is_instance('CWUser')
@@ -135,9 +136,7 @@
__select__ = is_instance('CWGroup')
def entity_call(self, entity):
- self._cw.add_css(('cubicweb.schema.css','cubicweb.acl.css'))
- access_types = ('read', 'delete', 'add', 'update')
- w = self.w
+ self._cw.add_css(('cubicweb.schema.css', 'cubicweb.acl.css'))
objtype_access = {'CWEType': ('read', 'delete', 'add', 'update'),
'CWRelation': ('add', 'delete')}
rql_cwetype = 'DISTINCT Any X WHERE X %s_permission CWG, X is CWEType, ' \
@@ -170,7 +169,7 @@
# user / groups management views ###############################################
class ManageUsersAction(actions.ManagersAction):
- __regid__ = 'cwuser' # see rewrite rule /cwuser
+ __regid__ = 'cwuser' # see rewrite rule /cwuser
title = _('users and groups')
category = 'manage'
@@ -179,7 +178,7 @@
__regid__ = 'cw.users-and-groups-management'
__select__ = StartupView.__select__ & match_user_groups('managers')
title = _('Users and groups management')
- tabs = [_('cw.users-management'), _('cw.groups-management'),]
+ tabs = [_('cw.users-management'), _('cw.groups-management')]
default_tab = 'cw.users-management'
def call(self, **kwargs):
@@ -191,7 +190,7 @@
class CWUserManagementView(StartupView):
__regid__ = 'cw.users-management'
__select__ = StartupView.__select__ & match_user_groups('managers')
- cache_max_age = 0 # disable caching
+ cache_max_age = 0 # disable caching
# XXX one could wish to display for instance only user's firstname/surname
# for non managers but filtering out NULL caused crash with an ldapuser
# source. The ldapuser source has been dropped and this code can be updated.
@@ -217,24 +216,24 @@
column_renderers = {
'user': tableview.EntityTableColRenderer(
- renderfunc=lambda w,x: w(tags.a(x.login, href=x.absolute_url())),
+ renderfunc=lambda w, x: w(tags.a(x.login, href=x.absolute_url())),
sortfunc=lambda x: x.login),
'in_state': tableview.EntityTableColRenderer(
- renderfunc=lambda w,x: w(x.cw_adapt_to('IWorkflowable').printable_state),
+ renderfunc=lambda w, x: w(x.cw_adapt_to('IWorkflowable').printable_state),
sortfunc=lambda x: x.cw_adapt_to('IWorkflowable').printable_state),
'in_group': tableview.EntityTableColRenderer(
- renderfunc=lambda w,x: x.view('reledit', rtype='in_group', role='subject', w=w)),
+ renderfunc=lambda w, x: x.view('reledit', rtype='in_group', role='subject', w=w)),
'primary_email': tableview.RelatedEntityColRenderer(
- getrelated=lambda x:x.primary_email and x.primary_email[0] or None),
+ getrelated=lambda x: x.primary_email and x.primary_email[0] or None),
'cw_source': tableview.RelatedEntityColRenderer(
getrelated=lambda x: x.cw_source[0]),
- }
+ }
class CWGroupsManagementView(StartupView):
__regid__ = 'cw.groups-management'
__select__ = StartupView.__select__ & match_user_groups('managers')
- cache_max_age = 0 # disable caching
+ cache_max_age = 0 # disable caching
rql = ('Any G,GN ORDERBY GN WHERE G is CWGroup, G name GN, NOT G name "owners"')
def call(self, **kwargs):
@@ -253,6 +252,6 @@
'group': tableview.MainEntityColRenderer(),
'nb_users': tableview.EntityTableColRenderer(
header=_('num. users'),
- renderfunc=lambda w,x: w(text_type(x.num_users())),
+ renderfunc=lambda w, x: w(text_type(x.num_users())),
sortfunc=lambda x: x.num_users()),
- }
+ }
--- a/cubicweb/web/views/uicfg.py Fri Oct 06 11:45:52 2017 +0200
+++ b/cubicweb/web/views/uicfg.py Fri Oct 06 14:24:35 2017 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
--- a/cubicweb/web/views/workflow.py Fri Oct 06 11:45:52 2017 +0200
+++ b/cubicweb/web/views/workflow.py Fri Oct 06 14:24:35 2017 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -25,24 +25,21 @@
from cubicweb import _
import os
-from warnings import warn
from six import add_metaclass
from logilab.mtconverter import xml_escape
-from logilab.common.graph import escape
from logilab.common.deprecation import class_deprecated
from cubicweb import Unauthorized
-from cubicweb.predicates import (has_related_entities, one_line_rset,
- relation_possible, match_form_params,
- score_entity, is_instance, adaptable)
+from cubicweb.predicates import (one_line_rset,
+ relation_possible, match_form_params,
+ score_entity, is_instance, adaptable)
from cubicweb.view import EntityView
-from cubicweb.schema import display_name
-from cubicweb.web import stdmsgs, action, component, form, action
-from cubicweb.web import formfields as ff, formwidgets as fwdgs
+from cubicweb.web import stdmsgs, action, component, form
+from cubicweb.web import formwidgets as fwdgs
from cubicweb.web.views import TmpFileViewMixin
-from cubicweb.web.views import uicfg, forms, primary, ibreadcrumbs
+from cubicweb.web.views import uicfg, forms, ibreadcrumbs
from cubicweb.web.views.tabs import TabbedPrimaryView, PrimaryTab
from cubicweb.web.views.dotgraphview import DotGraphView, DotPropsHandler
@@ -77,6 +74,7 @@
_afs = uicfg.autoform_section
_affk = uicfg.autoform_field_kwargs
+
# IWorkflowable views #########################################################
class ChangeStateForm(forms.CompositeEntityForm):
@@ -84,7 +82,7 @@
# session_key() implementation)
__regid__ = domid = 'changestate'
- form_renderer_id = 'base' # don't want EntityFormRenderer
+ form_renderer_id = 'base' # don't want EntityFormRenderer
form_buttons = [fwdgs.SubmitButton(),
fwdgs.Button(stdmsgs.BUTTON_CANCEL,
{'class': fwdgs.Button.css_class + ' cwjs-edition-cancel'})]
@@ -132,8 +130,8 @@
class WFHistoryView(EntityView):
__regid__ = 'wfhistory'
- __select__ = relation_possible('wf_info_for', role='object') & \
- score_entity(lambda x: x.cw_adapt_to('IWorkflowable').workflow_history)
+ __select__ = (relation_possible('wf_info_for', role='object')
+ & score_entity(lambda x: x.cw_adapt_to('IWorkflowable').workflow_history))
title = _('Workflow history')
@@ -180,6 +178,7 @@
"""display incontext view for an entity as well as its current state"""
__regid__ = 'incontext-state'
__select__ = adaptable('IWorkflowable')
+
def entity_call(self, entity):
iwf = entity.cw_adapt_to('IWorkflowable')
self.w(u'%s [%s]' % (entity.view('incontext'), iwf.printable_state))
@@ -238,9 +237,10 @@
_abaa.tag_object_of(('Transition', 'transition_of', 'Workflow'), True)
_abaa.tag_object_of(('WorkflowTransition', 'transition_of', 'Workflow'), True)
+
class WorkflowPrimaryView(TabbedPrimaryView):
__select__ = is_instance('Workflow')
- tabs = [ _('wf_tab_info'), _('wfgraph'),]
+ tabs = [_('wf_tab_info'), _('wfgraph')]
default_tab = 'wf_tab_info'
@@ -253,6 +253,7 @@
self.w(xml_escape(self._cw.view('textincontext', self.cw_rset,
row=row, col=col)))
+
class WorkflowTabTextView(PrimaryTab):
__regid__ = 'wf_tab_info'
__select__ = PrimaryTab.__select__ & one_line_rset() & is_instance('Workflow')
@@ -262,7 +263,7 @@
self.w(u'<div>%s</div>' % (entity.printable_value('description')))
self.w(u'<span>%s%s</span>' % (_("workflow_of").capitalize(), _(" :")))
html = []
- for e in entity.workflow_of:
+ for e in entity.workflow_of:
view = e.view('outofcontext')
if entity.eid == e.default_workflow[0].eid:
view += u' <span>[%s]</span>' % _('default_workflow')
@@ -273,10 +274,9 @@
'Any T,T,DS,T,TT ORDERBY TN WHERE T transition_of WF, WF eid %(x)s,'
'T type TT, T name TN, T destination_state DS?', {'x': entity.eid})
self.wview('table', rset, 'null',
- cellvids={ 1: 'trfromstates', 2: 'outofcontext', 3:'trsecurity',},
- headers = (_('Transition'), _('from_state'),
- _('to_state'), _('permissions'), _('type') ),
- )
+ cellvids={1: 'trfromstates', 2: 'outofcontext', 3: 'trsecurity'},
+ headers=(_('Transition'), _('from_state'),
+ _('to_state'), _('permissions'), _('type')))
class TransitionSecurityTextView(EntityView):
@@ -293,9 +293,9 @@
in entity.require_group))))
if entity.condition:
self.w(u'<div>%s%s %s</div>' %
- ( _('conditions'), _(" :"),
- u'<br/>'.join((e.dc_title() for e
- in entity.condition))))
+ (_('conditions'), _(" :"),
+ u'<br/>'.join((e.dc_title() for e in entity.condition))))
+
class TransitionAllowedTextView(EntityView):
__regid__ = 'trfromstates'
@@ -317,11 +317,13 @@
for e in getattr(wf, 'reverse_%s' % wfrelation)
if rschema.has_perm(req, 'add', **{param: e.eid}))
+
# TrInfo
_afs.tag_subject_of(('TrInfo', 'to_state', '*'), 'main', 'hidden')
_afs.tag_subject_of(('TrInfo', 'from_state', '*'), 'main', 'hidden')
_afs.tag_attribute(('TrInfo', 'tr_count'), 'main', 'hidden')
+
# BaseTransition
# XXX * allowed_transition BaseTransition
# XXX BaseTransition destination_state *
@@ -337,12 +339,14 @@
wfeid = eids[0]
return _wf_items_for_relation(form._cw, wfeid, 'state_of', field)
+
_afs.tag_subject_of(('*', 'destination_state', '*'), 'main', 'attributes')
_affk.tag_subject_of(('*', 'destination_state', '*'),
{'choices': transition_states_vocabulary})
_afs.tag_object_of(('*', 'allowed_transition', '*'), 'main', 'attributes')
_affk.tag_object_of(('*', 'allowed_transition', '*'),
- {'choices': transition_states_vocabulary})
+ {'choices': transition_states_vocabulary})
+
# State
@@ -350,13 +354,14 @@
entity = form.edited_entity
if entity.has_eid():
wfeid = entity.state_of[0].eid
- else :
+ else:
eids = form.linked_to.get(('state_of', 'subject'))
if not eids:
return []
wfeid = eids[0]
return _wf_items_for_relation(form._cw, wfeid, 'transition_of', field)
+
_afs.tag_subject_of(('State', 'allowed_transition', '*'), 'main', 'attributes')
_affk.tag_subject_of(('State', 'allowed_transition', '*'),
{'choices': state_transitions_vocabulary})
@@ -366,22 +371,29 @@
class WorkflowIBreadCrumbsAdapter(ibreadcrumbs.IBreadCrumbsAdapter):
__select__ = is_instance('Workflow')
+
# XXX what if workflow of multiple types?
def parent_entity(self):
return self.entity.workflow_of and self.entity.workflow_of[0] or None
+
class WorkflowItemIBreadCrumbsAdapter(ibreadcrumbs.IBreadCrumbsAdapter):
__select__ = is_instance('BaseTransition', 'State')
+
def parent_entity(self):
return self.entity.workflow
+
class TransitionItemIBreadCrumbsAdapter(ibreadcrumbs.IBreadCrumbsAdapter):
__select__ = is_instance('SubWorkflowExitPoint')
+
def parent_entity(self):
return self.entity.reverse_subworkflow_exit[0]
+
class TrInfoIBreadCrumbsAdapter(ibreadcrumbs.IBreadCrumbsAdapter):
__select__ = is_instance('TrInfo')
+
def parent_entity(self):
return self.entity.for_entity
@@ -422,6 +434,7 @@
for outgoingstate in transition.potential_destinations():
yield transition.eid, outgoingstate.eid, transition
+
class WorkflowGraphView(DotGraphView):
__regid__ = 'wfgraph'
__select__ = EntityView.__select__ & one_line_rset() & is_instance('Workflow')
--- a/flake8-ok-files.txt Fri Oct 06 11:45:52 2017 +0200
+++ b/flake8-ok-files.txt Fri Oct 06 14:24:35 2017 +0200
@@ -60,6 +60,7 @@
cubicweb/server/test/unittest_session.py
cubicweb/server/test/unittest_rqlannotation.py
cubicweb/server/test/unittest_utils.py
+cubicweb/schema.py
cubicweb/sobjects/notification.py
cubicweb/sobjects/services.py
cubicweb/sobjects/test/unittest_notification.py
@@ -103,14 +104,17 @@
cubicweb/web/test/data/entities.py
cubicweb/web/test/unittest_application.py
cubicweb/web/test/unittest_http_headers.py
+cubicweb/web/test/unittest_uicfg.py
cubicweb/web/test/unittest_views_basetemplates.py
cubicweb/web/test/unittest_views_cwsources.py
cubicweb/web/test/unittest_views_json.py
cubicweb/web/views/authentication.py
+cubicweb/web/views/cwuser.py
cubicweb/web/views/editcontroller.py
cubicweb/web/views/json.py
cubicweb/web/views/searchrestriction.py
cubicweb/web/views/staticcontrollers.py
+cubicweb/web/views/workflow.py
cubicweb/web/views/uicfg.py
cubicweb/xy.py
cubicweb/pyramid/auth.py