# HG changeset patch # User sylvain.thenault@logilab.fr # Date 1240495890 -7200 # Node ID 982e8616d9a273df4c28b11b913916863c6f6af3 # Parent 8edb0806dde4790f6b9cf26633d92a4352a02eaa delete-trailing-whitespaces diff -r 8edb0806dde4 -r 982e8616d9a2 common/mixins.py --- a/common/mixins.py Thu Apr 23 16:10:17 2009 +0200 +++ b/common/mixins.py Thu Apr 23 16:11:30 2009 +0200 @@ -26,10 +26,10 @@ # XXX misnamed parent_target = 'subject' children_target = 'object' - + def different_type_children(self, entities=True): """return children entities of different type as this entity. - + according to the `entities` parameter, return entity objects or the equivalent result set """ @@ -41,7 +41,7 @@ def same_type_children(self, entities=True): """return children entities of the same type as this entity. - + according to the `entities` parameter, return entity objects or the equivalent result set """ @@ -50,7 +50,7 @@ if entities: return [e for e in res if e.e_schema == self.e_schema] return res.filtered_rset(lambda x: x.e_schema == self.e_schema, self.col) - + def iterchildren(self, _done=None): if _done is None: _done = set() @@ -74,7 +74,7 @@ yield entity except AttributeError: pass - + @cached def path(self): """returns the list of eids from the root object to this object""" @@ -96,7 +96,7 @@ path.reverse() return path - + def iterparents(self): def _uptoroot(self): curr = self @@ -110,7 +110,7 @@ def notification_references(self, view): """used to control References field of email send on notification for this entity. `view` is the notification view. - + Should return a list of eids which can be used to generate message ids of previously sent email """ @@ -142,7 +142,7 @@ def children_rql(self): return self.related_rql(self.tree_attribute, self.children_target) - + def __iter__(self): return self.iterchildren() @@ -163,7 +163,7 @@ relation (which implies supporting 'wf_info_for' as well) """ __implements__ = (IWorkflowable,) - + @property def state(self): try: @@ -171,7 +171,7 @@ except IndexError: self.warning('entity %s has no state', self) return None - + @property def displayable_state(self): return self.req._(self.state) @@ -182,7 +182,7 @@ if rset: return rset.get_entity(0, 0) return None - + def wf_transition(self, trname): rset = self.req.execute('Any T, TN WHERE T name TN, T name %(n)s, T transition_of E, E name %(e)s', {'n': trname, 'e': str(self.e_schema)}) @@ -201,7 +201,7 @@ self.req.set_shared_data('trcommentformat', trcommentformat) self.req.execute('SET X in_state S WHERE X eid %(x)s, S eid %(s)s', {'x': self.eid, 's': stateeid}, 'x') - + def can_pass_transition(self, trname): """return the Transition instance if the current user can pass the transition with the given name, else None @@ -215,13 +215,13 @@ for tr in rset.entities(): if tr.may_be_passed(self.eid, stateeid): return tr - + def latest_trinfo(self): """return the latest transition information for this entity""" return self.reverse_wf_info_for[-1] - + # __method methods ######################################################## - + def set_state(self, params=None): """change the entity's state according to a state defined in given parameters, used to be called using __method controler facility @@ -231,9 +231,9 @@ params.get('trcomment'), params.get('trcommentformat')) self.req.set_message(self.req._('__msg state changed')) - + # specific vocabulary methods ############################################# - + @obsolete('use EntityFieldsForm.subject_in_state_vocabulary') def subject_in_state_vocabulary(self, rschema, limit=None): from cubicweb.web.form import EntityFieldsForm @@ -249,7 +249,7 @@ primary_email / use_email scheme """ __implements__ = (IEmailable,) - + def get_email(self): if getattr(self, 'primary_email', None): return self.primary_email[0].address @@ -271,14 +271,14 @@ def as_email_context(self): """returns the dictionary as used by the sendmail controller to build email bodies. - + NOTE: the dictionary keys should match the list returned by the `allowed_massmail_keys` method. """ return dict( (attr, getattr(self, attr)) for attr in self.allowed_massmail_keys() ) - + MI_REL_TRIGGERS = { ('in_state', 'subject'): WorkflowableMixIn, ('primary_email', 'subject'): EmailableMixIn, @@ -312,7 +312,7 @@ if done is None: done = set() super(TreeViewMixIn, self).call(done=done, **kwargs) - + def cell_call(self, row, col=0, vid=None, done=None, **kwargs): done, entity = _done_init(done, self, row, col) if done is None: @@ -341,7 +341,7 @@ self.w(u'
') super(TreePathMixIn, self).call(**kwargs) self.w(u'
') - + def cell_call(self, row, col=0, vid=None, done=None, **kwargs): done, entity = _done_init(done, self, row, col) if done is None: @@ -383,7 +383,7 @@ def in_progress(self): raise NotImplementedError() - + def progress(self): try: return 100. * self.done / self.revised_cost diff -r 8edb0806dde4 -r 982e8616d9a2 devtools/devctl.py --- a/devtools/devctl.py Thu Apr 23 16:10:17 2009 +0200 +++ b/devtools/devctl.py Thu Apr 23 16:11:30 2009 +0200 @@ -40,7 +40,7 @@ def my_cubes(self, cube): return (cube,) + self.cube_dependencies(cube) + self.cube_recommends(cube) - + @property def apphome(self): return None @@ -77,7 +77,7 @@ if mod.__file__.startswith(path): del sys.modules[name] break - + def generate_schema_pot(w, cubedir=None): """generate a pot file with schema specific i18n messages @@ -101,7 +101,8 @@ vreg.set_schema(schema) w(DEFAULT_POT_HEAD) _generate_schema_pot(w, vreg, schema, libschema=libschema, cube=cube) - + + def _generate_schema_pot(w, vreg, schema, libschema=None, cube=None): from cubicweb.common.i18n import add_msg w('# schema pot file, generated on %s\n' % datetime.now().strftime('%Y-%m-%d %H:%M:%S')) @@ -147,21 +148,26 @@ for eschema in schema.entities(): if eschema.is_final(): continue - for x, rschemas in (('subject', eschema.subject_relations()), + for role, rschemas in (('subject', eschema.subject_relations()), ('object', eschema.object_relations())): for rschema in rschemas: if rschema.is_final(): continue - for teschema in rschema.targets(eschema, x): - if defined_in_library(libschema, eschema, rschema, teschema, x): + for teschema in rschema.targets(eschema, role): + if defined_in_library(libschema, eschema, rschema, + teschema, role): continue - if actionbox.relation_mode(rschema.type, teschema.type, x) == 'create': - if x == 'subject': - label = 'add %s %s %s %s' % (eschema, rschema, teschema, x) - label2 = "creating %s (%s %%(linkto)s %s %s)" % (teschema, eschema, rschema, teschema) + if actionbox.relation_mode(rschema, eschema, teschema, role) == 'create': + if role == 'subject': + label = 'add %s %s %s %s' % (eschema, rschema, + teschema, role) + label2 = "creating %s (%s %%(linkto)s %s %s)" % ( + teschema, eschema, rschema, teschema) else: - label = 'add %s %s %s %s' % (teschema, rschema, eschema, x) - label2 = "creating %s (%s %s %s %%(linkto)s)" % (teschema, teschema, rschema, eschema) + label = 'add %s %s %s %s' % (teschema, rschema, + eschema, role) + label2 = "creating %s (%s %s %s %%(linkto)s)" % ( + teschema, teschema, rschema, eschema) add_msg(w, label) add_msg(w, label2) cube = (cube and 'cubes.%s.' % cube or 'cubicweb.') @@ -177,12 +183,13 @@ add_msg(w, objid) done.add(objid) - -def defined_in_library(libschema, etype, rtype, tetype, x): - """return true if the given relation definition exists in cubicweb's library""" + +def defined_in_library(libschema, etype, rtype, tetype, role): + """return true if the given relation definition exists in cubicweb's library + """ if libschema is None: return False - if x == 'subject': + if role == 'subject': subjtype, objtype = etype, tetype else: subjtype, objtype = tetype, etype @@ -211,7 +218,7 @@ class UpdateCubicWebCatalogCommand(Command): """Update i18n catalogs for cubicweb library. - + It will regenerate cubicweb/i18n/xx.po files. You'll have then to edit those files to add translations of newly added messages. """ @@ -281,7 +288,7 @@ """ name = 'i18nupdate' arguments = '[...]' - + def run(self, args): """run the command with its specific arguments""" if args: @@ -328,7 +335,7 @@ execute('xgettext --no-location --omit-header -k_ -L java --from-code=utf-8 -o %s %s' % (tmppotfile, ' '.join(jsfiles))) # no pot file created if there are no string to translate - if exists(tmppotfile): + if exists(tmppotfile): potfiles.append(tmppotfile) print '******** create cube specific catalog' tmppotfile = join(tempdir, 'generated.pot') @@ -367,7 +374,7 @@ name = 'live-server' arguments = '' options = () - + def run(self, args): """run the command with its specific arguments""" from cubicweb.devtools.livetest import runserver @@ -415,7 +422,7 @@ ), ) - + def run(self, args): if len(args) != 1: raise BadCommandUsage("exactly one argument (cube name) is expected") @@ -449,7 +456,7 @@ distname = 'cubicweb-' + distname else: distname = 'cubicweb-%s' % cubename.lower() - + longdesc = shortdesc = raw_input('Enter a short description for your cube: ') if verbose: longdesc = raw_input('Enter a long description (or nothing if you want to reuse the short one): ') @@ -487,7 +494,7 @@ elif ans == 's': break return includes - + class ExamineLogCommand(Command): """Examine a rql log file. @@ -506,7 +513,7 @@ name = 'exlog' options = ( ) - + def run(self, args): if args: raise BadCommandUsage("no argument expected") @@ -540,7 +547,7 @@ print 'Percentage;Cumulative Time;Occurences;Query' for time, occ, rql in stat: print '%.2f;%.2f;%s;%s' % (time/total_time, time, occ, rql) - + register_commands((UpdateCubicWebCatalogCommand, UpdateTemplateCatalogCommand, LiveServerCommand, diff -r 8edb0806dde4 -r 982e8616d9a2 rtags.py --- a/rtags.py Thu Apr 23 16:10:17 2009 +0200 +++ b/rtags.py Thu Apr 23 16:11:30 2009 +0200 @@ -17,21 +17,21 @@ should use rtags / etype_rtags / add_rtag api. Otherwise, a single tag is associated to each key, and you should use rtag / etype_rtag / set_rtag api. """ - + def __init__(self, use_set=False): self.use_set = use_set self._tagdefs = {} - + def set_rtag(self, tag, rtype, role, stype='*', otype='*'): assert not self.use_set assert role in ('subject', 'object'), role self._tagdefs[(str(rtype), role, str(stype), str(otype))] = tag - + def del_rtag(self, rtype, role, stype='*', otype='*'): assert not self.use_set assert role in ('subject', 'object'), role del self._tagdefs[(str(rtype), role, str(stype), str(otype))] - + def rtag(self, rtype, role, stype='*', otype='*'): assert not self.use_set for key in reversed(self._get_keys(rtype, role, stype, otype)): @@ -40,18 +40,18 @@ except KeyError: continue return None - + def etype_rtag(self, etype, rtype, role, ttype='*'): if role == 'subject': return self.rtag(rtype, role, etype, ttype) return self.rtag(rtype, role, ttype, etype) - + def add_rtag(self, tag, rtype, role, stype='*', otype='*'): assert self.use_set assert role in ('subject', 'object'), role rtags = self._tagdefs.setdefault((rtype, role, stype, otype), set()) rtags.add(tag) - + def rtags(self, rtype, role, stype='*', otype='*'): assert self.use_set rtags = set() @@ -61,13 +61,13 @@ except KeyError: continue return rtags - + def etype_rtags(self, etype, rtype, role, ttype='*'): if role == 'subject': return self.rtags(rtype, role, etype, ttype) return self.rtags(rtype, role, ttype, etype) - def _get_keys(self, rtype, role, stype, otype): + def _get_keys(self, rtype, role, stype, otype): assert role in ('subject', 'object'), role keys = [(rtype, role, '*', '*'), (rtype, role, '*', otype), @@ -78,9 +78,9 @@ if stype == '*': keys.remove((rtype, role, '*', otype)) if otype == '*': - keys.remove((rtype, role, stype, '*')) + keys.remove((rtype, role, stype, '*')) return keys - + # dict compat def __getitem__(self, key): if isinstance(key, basestring): diff -r 8edb0806dde4 -r 982e8616d9a2 schema.py --- a/schema.py Thu Apr 23 16:10:17 2009 +0200 +++ b/schema.py Thu Apr 23 16:11:30 2009 +0200 @@ -27,7 +27,7 @@ # XXX <3.2 bw compat from yams import schema schema.use_py_datetime() -nodes.use_py_datetime() +nodes.use_py_datetime() _ = unicode @@ -43,7 +43,7 @@ def bw_normalize_etype(etype): if etype in ETYPE_NAME_MAP: msg = '%s has been renamed to %s, please update your code' % ( - etype, ETYPE_NAME_MAP[etype]) + etype, ETYPE_NAME_MAP[etype]) warn(msg, DeprecationWarning, stacklevel=4) etype = ETYPE_NAME_MAP[etype] return etype @@ -78,12 +78,12 @@ class RichString(ybo.String): """Convenience RichString attribute type The follwing declaration:: - + class Card(EntityType): content = RichString(fulltextindexed=True, default_format='text/rest') - + is equivalent to:: - + class Card(EntityType): content_format = String(meta=True, internationalizable=True, default='text/rest', constraints=[format_constraint]) @@ -106,7 +106,7 @@ constraints=rdef.format_constraints) yams_add_relation(relations, format_attrdef, name+'_format', insertidx) yams_add_relation(relations, rdef, name, insertidx) - + def display_name(req, key, form=''): """return a internationalized string for the key (schema entity or relation name) in a given form @@ -258,19 +258,19 @@ eid = getattr(edef, 'eid', None) self.eid = eid # take care: no _groups attribute when deep-copying - if getattr(self, '_groups', None): + if getattr(self, '_groups', None): for groups in self._groups.itervalues(): for group_or_rqlexpr in groups: if isinstance(group_or_rqlexpr, RRQLExpression): msg = "can't use RRQLExpression on an entity type, use an ERQLExpression (%s)" raise BadSchemaDefinition(msg % self.type) - + def attribute_definitions(self): """return an iterator on attribute definitions - + attribute relations are a subset of subject relations where the object's type is a final entity - + an attribute definition is a 2-uple : * name of the relation * schema of the destination entity type @@ -280,7 +280,7 @@ if rschema.type == 'has_text': continue yield rschema, attrschema - + def add_subject_relation(self, rschema): """register the relation schema as possible subject relation""" super(CubicWebEntitySchema, self).add_subject_relation(rschema) @@ -289,7 +289,7 @@ def del_subject_relation(self, rtype): super(CubicWebEntitySchema, self).del_subject_relation(rtype) self._update_has_text(False) - + def _update_has_text(self, need_has_text=None): may_need_has_text, has_has_text = False, False for rschema in self.subject_relations(): @@ -317,11 +317,11 @@ self.schema.add_relation_def(rdef) elif not need_has_text and has_has_text: self.schema.del_relation_def(self.type, 'has_text', 'String') - + def schema_entity(self): """return True if this entity type is used to build the schema""" return self.type in self.schema.schema_entity_types() - + def check_perm(self, session, action, eid=None): # NB: session may be a server session or a request object user = session.user @@ -337,17 +337,17 @@ # else if there is some rql expressions, check them if any(rqlexpr.check(session, eid) for rqlexpr in self.get_rqlexprs(action)): - return + return raise Unauthorized(action, str(self)) def rql_expression(self, expression, mainvars=None, eid=None): """rql expression factory""" return ERQLExpression(expression, mainvars, eid) - + class CubicWebRelationSchema(RelationSchema): RelationSchema._RPROPERTIES['eid'] = None _perms_checked = False - + def __init__(self, schema=None, rdef=None, eid=None, **kwargs): if rdef is not None: # if this relation is inlined @@ -356,8 +356,8 @@ if eid is None and rdef is not None: eid = getattr(rdef, 'eid', None) self.eid = eid - - + + def update(self, subjschema, objschema, rdef): super(CubicWebRelationSchema, self).update(subjschema, objschema, rdef) if not self._perms_checked and self._groups: @@ -377,7 +377,7 @@ newrqlexprs.append(ERQLExpression(rqlexpr.expression, rqlexpr.mainvars, rqlexpr.eid)) - self.set_rqlexprs(action, newrqlexprs) + self.set_rqlexprs(action, newrqlexprs) else: msg = "can't use RRQLExpression on a final relation "\ "type (eg attribute relation), use an ERQLExpression (%s)" @@ -388,16 +388,16 @@ "a RRQLExpression (%s)" raise BadSchemaDefinition(msg % self.type) self._perms_checked = True - + def cardinality(self, subjtype, objtype, target): card = self.rproperty(subjtype, objtype, 'cardinality') return (target == 'subject' and card[0]) or \ (target == 'object' and card[1]) - + def schema_relation(self): return self.type in ('relation_type', 'from_entity', 'to_entity', 'constrained_by', 'cstrtype') - + def physical_mode(self): """return an appropriate mode for physical storage of this relation type: * 'subjectinline' if every possible subject cardinalities are 1 or ? @@ -413,7 +413,7 @@ # in an allowed group, if so that's enough internal sessions should # always stop there if session.user.matching_groups(self.get_groups(action)): - return + return # else if there is some rql expressions, check them if any(rqlexpr.check(session, *args, **kwargs) for rqlexpr in self.get_rqlexprs(action)): @@ -426,7 +426,7 @@ return ERQLExpression(expression, mainvars, eid) return RRQLExpression(expression, mainvars, eid) - + class CubicWebSchema(Schema): """set of entities and relations schema defining the possible data sets used in an application @@ -434,11 +434,11 @@ :type name: str :ivar name: name of the schema, usually the application identifier - + :type base: str :ivar base: path of the directory where the schema is defined """ - reading_from_database = False + reading_from_database = False entity_class = CubicWebEntitySchema relation_class = CubicWebRelationSchema @@ -455,7 +455,7 @@ rschema = self.add_relation_type(ybo.RelationType('identity', meta=True)) rschema.final = False rschema.set_default_groups() - + def schema_entity_types(self): """return the list of entity types used to build the schema""" return frozenset(('CWEType', 'CWRType', 'CWAttribute', 'CWRelation', @@ -463,7 +463,7 @@ # XXX those are not really "schema" entity types # but we usually don't want them as @* targets 'CWProperty', 'CWPermission', 'State', 'Transition')) - + def add_entity_type(self, edef): edef.name = edef.name.encode() edef.name = bw_normalize_etype(edef.name) @@ -478,13 +478,13 @@ self.add_relation_def(rdef) self._eid_index[eschema.eid] = eschema return eschema - + def add_relation_type(self, rdef): rdef.name = rdef.name.lower().encode() rschema = super(CubicWebSchema, self).add_relation_type(rdef) self._eid_index[rschema.eid] = rschema return rschema - + def add_relation_def(self, rdef): """build a part of a relation schema (i.e. add a relation between two specific entity's types) @@ -511,18 +511,18 @@ self.eschema(rdef.object)) except AttributeError: pass # not a serialized schema - + def del_relation_type(self, rtype): rschema = self.rschema(rtype) self._eid_index.pop(rschema.eid, None) super(CubicWebSchema, self).del_relation_type(rtype) - + def del_relation_def(self, subjtype, rtype, objtype): for k, v in self._eid_index.items(): if v == (subjtype, rtype, objtype): del self._eid_index[k] super(CubicWebSchema, self).del_relation_def(subjtype, rtype, objtype) - + def del_entity_type(self, etype): eschema = self.eschema(etype) self._eid_index.pop(eschema.eid, None) @@ -531,7 +531,7 @@ if 'has_text' in eschema.subject_relations(): self.del_relation_def(etype, 'has_text', 'String') super(CubicWebSchema, self).del_entity_type(etype) - + def schema_by_eid(self, eid): return self._eid_index[eid] @@ -543,22 +543,22 @@ limit the proposed values to a set of entities returned by a rql query, but this is not enforced at the repository level - + restriction is additional rql restriction that will be added to a predefined query, where the S and O variables respectivly represent the subject and the object of the relation """ - + def __init__(self, restriction): self.restriction = restriction def serialize(self): return self.restriction - + def deserialize(cls, value): return cls(value) deserialize = classmethod(deserialize) - + def check(self, entity, rtype, value): """return true if the value satisfy the constraint, else false""" # implemented as a hook in the repository @@ -568,7 +568,7 @@ """raise ValidationError if the relation doesn't satisfy the constraint """ pass # this is a vocabulary constraint, not enforce - + def __str__(self): return self.restriction @@ -586,7 +586,7 @@ ('s', 'o'), build_descr=False) def error(self, eid, rtype, msg): raise ValidationError(eid, {rtype: msg}) - + def repo_check(self, session, eidfrom, rtype, eidto): """raise ValidationError if the relation doesn't satisfy the constraint """ @@ -608,12 +608,12 @@ # eidfrom or eidto (from user interface point of view) self.error(eidfrom, rtype, 'unique constraint %s failed' % self) - + def split_expression(rqlstring): for expr in rqlstring.split(','): for word in expr.split(): yield word - + def normalize_expression(rqlstring): """normalize an rql expression to ease schema synchronization (avoid suppressing and reinserting an expression if only a space has been added/removed @@ -637,19 +637,19 @@ if len(self.rqlst.defined_vars[mainvar].references()) <= 2: LOGGER.warn('You did not use the %s variable in your RQL expression %s', mainvar, self) - + def __str__(self): return self.full_rql def __repr__(self): return '%s(%s)' % (self.__class__.__name__, self.full_rql) - + def __deepcopy__(self, memo): return self.__class__(self.expression, self.mainvars) def __getstate__(self): return (self.expression, self.mainvars) def __setstate__(self, state): self.__init__(*state) - + @cached def transform_has_permission(self): found = None @@ -693,7 +693,7 @@ rqlst.recover() return rql, found, keyarg return rqlst.as_string(), None, None - + def _check(self, session, **kwargs): """return True if the rql expression is matching the given relation between fromeid and toeid @@ -753,7 +753,7 @@ if self.eid is not None: session.local_perm_cache[key] = False return False - + @property def minimal_rql(self): return 'Any %s WHERE %s' % (self.mainvars, self.expression) @@ -778,16 +778,16 @@ if 'U' in defined: rql += ', U eid %(u)s' return rql - + def check(self, session, eid=None): if 'X' in self.rqlst.defined_vars: if eid is None: return False return self._check(session, x=eid) return self._check(session) - + PyFileReader.context['ERQLExpression'] = ERQLExpression - + class RRQLExpression(RQLExpression): def __init__(self, expression, mainvars=None, eid=None): if mainvars is None: @@ -817,7 +817,7 @@ if 'U' in defined: rql += ', U eid %(u)s' return rql - + def check(self, session, fromeid=None, toeid=None): kwargs = {} if 'S' in self.rqlst.defined_vars: @@ -829,7 +829,7 @@ return False kwargs['o'] = toeid return self._check(session, **kwargs) - + PyFileReader.context['RRQLExpression'] = RRQLExpression # workflow extensions ######################################################### @@ -857,7 +857,7 @@ class WorkflowableEntityType(ybo.EntityType): __metaclass__ = workflowable_definition abstract = True - + PyFileReader.context['WorkflowableEntityType'] = WorkflowableEntityType # schema loading ############################################################## @@ -866,7 +866,7 @@ """cubicweb specific relation file reader, handling additional RQL constraints on a relation definition """ - + def handle_constraint(self, rdef, constraint_text): """arbitrary constraint is an rql expression for cubicweb""" if not rdef.constraints: @@ -878,7 +878,7 @@ rdef.inlined = True RelationFileReader.process_properties(self, rdef, relation_def) - + CONSTRAINTS['RQLConstraint'] = RQLConstraint CONSTRAINTS['RQLUniqueConstraint'] = RQLUniqueConstraint CONSTRAINTS['RQLVocabularyConstraint'] = RQLVocabularyConstraint @@ -900,13 +900,13 @@ self.lib_directory = config.schemas_lib_dir() return super(BootstrapSchemaLoader, self).load( path, config.appid, register_base_types=False, **kwargs) - + def _load_definition_files(self, cubes=None): # bootstraping, ignore cubes for filepath in self.include_schema_files('bootstrap'): self.info('loading %s', filepath) self.handle_file(filepath) - + def unhandled_file(self, filepath): """called when a file without handler associated has been found""" self.warning('ignoring file %r', filepath) @@ -948,14 +948,14 @@ class FormatConstraint(StaticVocabularyConstraint): need_perm_formats = [_('text/cubicweb-page-template')] - + regular_formats = (_('text/rest'), _('text/html'), _('text/plain'), ) def __init__(self): pass - + def serialize(self): """called to make persistent valuable data of a constraint""" return None @@ -966,18 +966,18 @@ a `cls` instance """ return cls() - + def vocabulary(self, entity=None, req=None): if req is None and entity is not None: req = entity.req if req is not None and req.user.has_permission(PERM_USE_TEMPLATE_FORMAT): return self.regular_formats + tuple(self.need_perm_formats) return self.regular_formats - + def __str__(self): return 'value in (%s)' % u', '.join(repr(unicode(word)) for word in self.vocabulary()) - - + + format_constraint = FormatConstraint() CONSTRAINTS['FormatConstraint'] = FormatConstraint PyFileReader.context['format_constraint'] = format_constraint @@ -992,7 +992,7 @@ def bw_import_erschema(self, ertype, schemamod=None, instantiate=True): return orig_import_erschema(self, bw_normalize_etype(ertype), schemamod, instantiate) PyFileReader.import_erschema = bw_import_erschema - + # XXX itou for some Statement methods from rql import stmts orig_get_etype = stmts.ScopeNode.get_etype diff -r 8edb0806dde4 -r 982e8616d9a2 schemas/base.py --- a/schemas/base.py Thu Apr 23 16:10:17 2009 +0200 +++ b/schemas/base.py Thu Apr 23 16:11:30 2009 +0200 @@ -6,8 +6,6 @@ """ __docformat__ = "restructuredtext en" -from cubicweb.schema import format_constraint - class CWUser(WorkflowableEntityType): """define a CubicWeb user""" @@ -26,7 +24,7 @@ surname = String(maxsize=64) last_login_time = Datetime(description=_('last connection date')) # allowing an email to be the primary email of multiple entities is necessary for - # test at least :-/ + # test at least :-/ primary_email = SubjectRelation('EmailAddress', cardinality='??', description=_('email address to use for notification')) use_email = SubjectRelation('EmailAddress', cardinality='*?', composite='subject') @@ -44,9 +42,9 @@ 'delete': ('managers', 'owners', ERQLExpression('P use_email X, U has_update_permission P')), 'update': ('managers', 'owners', ERQLExpression('P use_email X, U has_update_permission P')), } - + alias = String(fulltextindexed=True, maxsize=56) - address = String(required=True, fulltextindexed=True, + address = String(required=True, fulltextindexed=True, indexed=True, unique=True, maxsize=128) canonical = Boolean(default=False, description=_('when multiple addresses are equivalent \ @@ -66,7 +64,7 @@ class primary_email(RelationType): """the prefered email""" permissions = use_email.permissions - + class identical_to(RelationType): """identical_to""" symetric = True @@ -85,14 +83,14 @@ class in_group(MetaRelationType): """core relation indicating a user's groups""" meta = False - + class owned_by(MetaRelationType): """core relation indicating owners of an entity. This relation implicitly put the owner into the owners group for the entity """ permissions = { 'read': ('managers', 'users', 'guests'), - 'add': ('managers', RRQLExpression('S owned_by U'),), + 'add': ('managers', RRQLExpression('S owned_by U'),), 'delete': ('managers', RRQLExpression('S owned_by U'),), } # 0..n cardinality for entities created by internal session (no attached user) @@ -100,7 +98,7 @@ cardinality = '**' subject = '**' object = 'CWUser' - + class created_by(MetaRelationType): """core relation indicating the original creator of an entity""" permissions = { @@ -110,11 +108,11 @@ } # 0..1 cardinality for entities created by internal session (no attached user) # and to support later deletion of a user which has created some entities - cardinality = '?*' + cardinality = '?*' subject = '**' object = 'CWUser' - + class creation_date(MetaAttributeRelationType): """creation time of an entity""" cardinality = '11' @@ -126,7 +124,7 @@ cardinality = '11' subject = '**' object = 'Datetime' - + class CWProperty(EntityType): """used for cubicweb configuration. Once a property has been created you can't change the key. @@ -144,7 +142,7 @@ 'You must select this first to be able to set ' 'value')) value = String(internationalizable=True, maxsize=256) - + for_user = SubjectRelation('CWUser', cardinality='?*', composite='object', description=_('user for which this property is ' 'applying. If this relation is not ' @@ -171,7 +169,7 @@ description=_('name or identifier of the permission')) label = String(required=True, internationalizable=True, maxsize=100, description=_('distinct label to distinguate between other permission entity of the same name')) - require_group = SubjectRelation('CWGroup', + require_group = SubjectRelation('CWGroup', description=_('groups to which the permission is granted')) # explicitly add X require_permission CWPermission for each entity that should have @@ -185,7 +183,7 @@ 'add': ('managers',), 'delete': ('managers',), } - + class require_group(MetaRelationType): """used to grant a permission to a group""" permissions = { @@ -194,7 +192,7 @@ 'delete': ('managers',), } - + class see_also(RelationType): """generic relation to link one entity to another""" symetric = True @@ -215,6 +213,6 @@ 'delete': ('managers',), } - name = String(required=True, unique=True, indexed=True, + name = String(required=True, unique=True, indexed=True, description=_('name of the cache')) timestamp = Datetime(default='NOW') diff -r 8edb0806dde4 -r 982e8616d9a2 schemas/bootstrap.py --- a/schemas/bootstrap.py Thu Apr 23 16:10:17 2009 +0200 +++ b/schemas/bootstrap.py Thu Apr 23 16:11:30 2009 +0200 @@ -14,7 +14,7 @@ """define an entity type, used to build the application schema""" name = String(required=True, indexed=True, internationalizable=True, unique=True, maxsize=64) - description = RichString(internationalizable=True, + description = RichString(internationalizable=True, description=_('semantic description of this entity type')) meta = Boolean(description=_('is it an application entity type or not ?')) # necessary to filter using RQL @@ -41,7 +41,7 @@ class CWAttribute(MetaEntityType): """define a final relation: link a final relation type from a non final - entity to a final entity type. + entity to a final entity type. used to build the application schema """ @@ -55,31 +55,31 @@ constraints=[RQLConstraint('O final TRUE')], composite='object') constrained_by = SubjectRelation('CWConstraint', cardinality='*1', composite='subject') - + cardinality = String(maxsize=2, internationalizable=True, - vocabulary=[_('?1'), _('11'), _('??'), _('1?')], + vocabulary=[_('?1'), _('11'), _('??'), _('1?')], description=_('subject/object cardinality')) ordernum = Int(description=('control subject entity\'s relations order'), default=0) - + indexed = Boolean(description=_('create an index for quick search on this attribute')) fulltextindexed = Boolean(description=_('index this attribute\'s value in the plain text index')) internationalizable = Boolean(description=_('is this attribute\'s value translatable')) defaultval = String(maxsize=256) - + description_format = String(meta=True, internationalizable=True, maxsize=50, default='text/plain', constraints=[format_constraint]) description = String(internationalizable=True, description=_('semantic description of this attribute')) - + -CARDINALITY_VOCAB = [_('?*'), _('1*'), _('+*'), _('**'), - _('?+'), _('1+'), _('++'), _('*+'), +CARDINALITY_VOCAB = [_('?*'), _('1*'), _('+*'), _('**'), + _('?+'), _('1+'), _('++'), _('*+'), _('?1'), _('11'), _('+1'), _('*1'), _('??'), _('1?'), _('+?'), _('*?')] class CWRelation(MetaEntityType): """define a non final relation: link a non final relation type from a non - final entity to a non final entity type. + final entity to a non final entity type. used to build the application schema """ @@ -93,7 +93,7 @@ constraints=[RQLConstraint('O final FALSE')], composite='object') constrained_by = SubjectRelation('CWConstraint', cardinality='*1', composite='subject') - + cardinality = String(maxsize=2, internationalizable=True, vocabulary=CARDINALITY_VOCAB, description=_('subject/object cardinality')) @@ -105,12 +105,12 @@ 'deleted.'), vocabulary=('', _('subject'), _('object')), maxsize=8, default=None) - + description_format = String(meta=True, internationalizable=True, maxsize=50, default='text/plain', constraints=[format_constraint]) description = String(internationalizable=True, description=_('semantic description of this relation')) - + # not restricted since it has to be read when checking allowed transitions class RQLExpression(MetaEntityType): @@ -120,7 +120,7 @@ description=_('name of the main variables which should be ' 'used in the selection if necessary (comma ' 'separated)')) - expression = String(required=True, + expression = String(required=True, description=_('restriction part of a rql query. ' 'For entity rql expression, X and U are ' 'predefined respectivly to the current object and to ' @@ -137,7 +137,7 @@ description=_('rql expression allowing to delete entities/relations of this type')) update_permission = ObjectRelation('CWEType', cardinality='*?', composite='subject', description=_('rql expression allowing to update entities of this type')) - + class CWConstraint(MetaEntityType): """define a schema constraint""" @@ -165,9 +165,9 @@ description=_('groups allowed to delete entities/relations of this type')) update_permission = ObjectRelation('CWEType', description=_('groups allowed to update entities of this type')) - - - + + + class relation_type(MetaRelationType): """link a relation definition to its relation type""" inlined = True @@ -179,7 +179,7 @@ inlined = True class constrained_by(MetaRelationType): """constraints applying on this relation""" - + class cstrtype(MetaRelationType): """constraint factory""" inlined = True diff -r 8edb0806dde4 -r 982e8616d9a2 web/form.py --- a/web/form.py Thu Apr 23 16:10:17 2009 +0200 +++ b/web/form.py Thu Apr 23 16:11:30 2009 +0200 @@ -608,7 +608,7 @@ """ entity = self.edited_entity if isinstance(rtype, basestring): - rtype = entity.schema.rschema(rtype) + rtype = self.schema.rschema(rtype) done = None assert not rtype.is_final(), rtype if entity.has_eid(): @@ -630,7 +630,7 @@ """ entity = self.edited_entity if isinstance(rtype, basestring): - rtype = entity.schema.rschema(rtype) + rtype = self.schema.rschema(rtype) done = None if entity.has_eid(): done = set(e.eid for e in getattr(entity, 'reverse_%s' % rtype)) @@ -645,7 +645,7 @@ break return result - def subject_in_state_vocabulary(self, rschema, limit=None): + def subject_in_state_vocabulary(self, rtype, limit=None): """vocabulary method for the in_state relation, looking for relation's object entities (i.e. self is the subject) according to initial_state, state_of and next_state relation diff -r 8edb0806dde4 -r 982e8616d9a2 web/views/baseviews.py --- a/web/views/baseviews.py Thu Apr 23 16:10:17 2009 +0200 +++ b/web/views/baseviews.py Thu Apr 23 16:11:30 2009 +0200 @@ -40,7 +40,7 @@ """default view when no result has been found""" __select__ = empty_rset() id = 'noresult' - + def call(self, **kwargs): self.w(u'
%s
\n' % self.req._('No result matching query')) @@ -48,7 +48,7 @@ class FinalView(AnyRsetView): """display values without any transformation (i.e. get a number for - entities) + entities) """ id = 'final' # record generated i18n catalog messages @@ -66,7 +66,7 @@ _('%d hours') _('%d minutes') _('%d seconds') - + def cell_call(self, row, col, props=None, displaytime=False, format='text/html'): etype = self.rset.description[row][col] value = self.rset.rows[row][col] @@ -77,7 +77,7 @@ self.w(entity.printable_value(rtype, value, format=format)) return if etype in ('Time', 'Interval'): - # value is DateTimeDelta but we have no idea about what is the + # value is DateTimeDelta but we have no idea about what is the # reference date here, so we can only approximate years and months if format == 'text/html': space = ' ' @@ -100,9 +100,9 @@ return self.wdata(printable_value(self.req, etype, value, props, displaytime=displaytime)) - + PRIMARY_SKIP_RELS = set(['is', 'is_instance_of', 'identity', - 'owned_by', 'created_by', + 'owned_by', 'created_by', 'in_state', 'wf_info_for', 'require_permission', 'from_entity', 'to_entity', 'see_also']) @@ -125,12 +125,12 @@ by default primary views are indexed """ return [] - - def cell_call(self, row, col): + + def cell_call(self, row, col): self.row = row # XXX move render_entity implementation here self.render_entity(self.complete_entity(row, col)) - + def render_entity(self, entity): """return html to display the given entity""" siderelations = [] @@ -150,7 +150,7 @@ self.w(u'
') self.render_side_related(entity, siderelations) self.w(u'
') - self.w(u'
') + self.w(u'
') self.content_navigation_components('navcontentbottom') def content_navigation_components(self, context): @@ -165,13 +165,13 @@ % comp.__class__, DeprecationWarning) comp.dispatch(w=self.w, view=self) self.w(u'') - + def iter_attributes(self, entity): for rschema, targetschema in entity.e_schema.attribute_definitions(): if rschema.type in self.skip_attrs: continue yield rschema, targetschema - + def iter_relations(self, entity): skip = set(self.skip_rels) skip.update(PRIMARY_SKIP_RELS) @@ -185,21 +185,21 @@ if title: self.w(u'

%s %s

' % (entity.dc_type().capitalize(), title)) - + def content_title(self, entity): """default implementation return an empty string""" return u'' - + def render_entity_metadata(self, entity): entity.view('metadata', w=self.w) summary = self.summary(entity) # deprecate summary? if summary: self.w(u'
%s
' % summary) - + def summary(self, entity): """default implementation return an empty string""" - return u'' - + return u'' + def render_entity_attributes(self, entity, siderelations): for rschema, targetschema in self.iter_attributes(entity): attr = rschema.type @@ -263,8 +263,8 @@ except NotImplementedError: # much probably a context insensitive box, which only implements # .call() and not cell_call() - box.dispatch(w=self.w) - + box.dispatch(w=self.w) + def is_side_related(self, rschema, eschema): return rschema.meta and \ not rschema.schema_relation() == eschema.schema_entity() @@ -298,11 +298,11 @@ label = display_name(self.req, rschema.type, role) self.field(label, value, show_label=show_label, w=self.w, tr=False) - + class SecondaryView(EntityView): id = 'secondary' title = _('secondary') - + def cell_call(self, row, col): """the secondary view for an entity secondary = icon + view(oneline) @@ -314,7 +314,7 @@ class OneLineView(EntityView): id = 'oneline' - title = _('oneline') + title = _('oneline') def cell_call(self, row, col): """the one line view for an entity: linked text view @@ -345,7 +345,7 @@ self.wview(self.id, rset, row=i, **kwargs) if len(rset) > 1: self.w(u"\n") - + def cell_call(self, row, col=0, **kwargs): entity = self.entity(row, col) self.w(cut(entity.dc_title(), @@ -356,7 +356,7 @@ """paragraph view of some metadata""" id = 'metadata' show_eid = True - + def cell_call(self, row, col): _ = self.req._ entity = self.entity(row, col) @@ -368,7 +368,7 @@ self.w(u'%s, ' % self.format_date(entity.modification_date)) # entities from external source may not have a creation date (eg ldap) - if entity.creation_date: + if entity.creation_date: self.w(u'%s ' % _('created on')) self.w(u'%s' % self.format_date(entity.creation_date)) @@ -408,7 +408,7 @@ self.w(html_escape(self.view('textincontext', self.rset, row=row, col=col))) self.w(u'') - + class OutOfContextView(EntityView): id = 'outofcontext' @@ -417,17 +417,17 @@ self.w(html_escape(self.view('textoutofcontext', self.rset, row=row, col=col))) self.w(u'') - + # list views ################################################################## - + class ListView(EntityView): id = 'list' title = _('list') item_vid = 'listitem' - + def call(self, klass=None, title=None, subvid=None, listid=None, **kwargs): """display a list of entities by calling their view - + :param listid: the DOM id to use for the root element """ if subvid is None and 'subvid' in self.req.form: @@ -474,16 +474,16 @@ return self.build_url(entity.rest_path(), vid=self.id) return self.build_url(rql=self.rset.printable_rql(), vid=self.id) - + class ListItemView(EntityView): id = 'listitem' - + @property def redirect_vid(self): if self.req.search_state[0] == 'normal': return 'outofcontext' return 'outofcontext-search' - + def cell_call(self, row, col, vid=None, **kwargs): if not vid: vid = self.redirect_vid @@ -504,7 +504,7 @@ class CSVView(SimpleListView): id = 'csv' redirect_vid = 'incontext' - + def call(self, **kwargs): rset = self.rset for i in xrange(len(rset)): @@ -515,7 +515,7 @@ class TreeItemView(ListItemView): id = 'treeitem' - + def cell_call(self, row, col): self.wview('incontext', self.rset, row=row, col=col) @@ -552,7 +552,7 @@ else: contexts.append(ctx) value = u'\n' + highlighted.join(contexts) - self.w(value.replace('\n', '
')) + self.w(value.replace('\n', '
')) class TooltipView(EntityView): @@ -579,4 +579,4 @@ XmlRsetView = class_moved(xmlrss.XmlRsetView) RssView = class_moved(xmlrss.RssView) RssItemView = class_moved(xmlrss.RssItemView) - +