# HG changeset patch # User Katia Saurfelt # Date 1247054362 -7200 # Node ID 00b7045359848dd578b221a95b217b155954685a # Parent 3f7c7fbae94e22b83808d6ad09c8855efabdc88e# Parent 05ae71d9a0694c71acd5e3e8f9aefb49d07fa95a merge diff -r 3f7c7fbae94e -r 00b704535984 common/uilib.py --- a/common/uilib.py Wed Jul 08 13:58:37 2009 +0200 +++ b/common/uilib.py Wed Jul 08 13:59:22 2009 +0200 @@ -15,7 +15,7 @@ from urllib import quote as urlquote from StringIO import StringIO -from logilab.mtconverter import html_escape, html_unescape +from logilab.mtconverter import xml_escape, html_unescape from cubicweb.utils import ustrftime @@ -66,7 +66,7 @@ except ImportError: def rest_publish(entity, data): """default behaviour if docutils was not found""" - return html_escape(data) + return xml_escape(data) TAG_PROG = re.compile(r'', re.U) def remove_html_tags(text): @@ -108,7 +108,7 @@ if len(text_nohtml) <= length: return text # else if un-tagged text is too long, cut it - return html_escape(text_nohtml[:length] + u'...') + return xml_escape(text_nohtml[:length] + u'...') fallback_safe_cut = safe_cut @@ -220,12 +220,12 @@ attrs['class'] = attrs.pop('klass') except KeyError: pass - value += u' ' + u' '.join(u'%s="%s"' % (attr, html_escape(unicode(value))) + value += u' ' + u' '.join(u'%s="%s"' % (attr, xml_escape(unicode(value))) for attr, value in sorted(attrs.items()) if value is not None) if content: if escapecontent: - content = html_escape(unicode(content)) + content = xml_escape(unicode(content)) value += u'>%s' % (content, tag) else: value += u'/>' @@ -406,9 +406,9 @@ strings.append(body) strings.append(u'') if title: - strings.append(u'

%s

'% html_escape(title)) + strings.append(u'

%s

'% xml_escape(title)) try: - strings.append(u'

%s

' % html_escape(str(exception)).replace("\n","
")) + strings.append(u'

%s

' % xml_escape(str(exception)).replace("\n","
")) except UnicodeError: pass strings.append(u'
') @@ -416,9 +416,9 @@ strings.append(u'File %s, line ' u'%s, function ' u'%s:
'%( - html_escape(stackentry[0]), stackentry[1], html_escape(stackentry[2]))) + xml_escape(stackentry[0]), stackentry[1], xml_escape(stackentry[2]))) if stackentry[3]: - string = html_escape(stackentry[3]).decode('utf-8', 'replace') + string = xml_escape(stackentry[3]).decode('utf-8', 'replace') strings.append(u'  %s
\n' % (string)) # add locals info for each entry try: @@ -426,7 +426,7 @@ html_info = [] chars = 0 for name, value in local_context.iteritems(): - value = html_escape(repr(value)) + value = xml_escape(repr(value)) info = u'%s=%s, ' % (name, value) line_length = len(name) + len(value) chars += line_length @@ -491,5 +491,5 @@ def newfunc(*args, **kwargs): ret = function(*args, **kwargs) assert isinstance(ret, basestring) - return html_escape(ret) + return xml_escape(ret) return newfunc diff -r 3f7c7fbae94e -r 00b704535984 cwctl.py --- a/cwctl.py Wed Jul 08 13:58:37 2009 +0200 +++ b/cwctl.py Wed Jul 08 13:59:22 2009 +0200 @@ -733,7 +733,7 @@ mih = config.migration_handler() if args: for arg in args: - mih.process_script(script) + mih.process_script(arg) else: mih.interactive_shell() mih.shutdown() diff -r 3f7c7fbae94e -r 00b704535984 doc/book/en/development/datamodel/define-workflows.rst --- a/doc/book/en/development/datamodel/define-workflows.rst Wed Jul 08 13:58:37 2009 +0200 +++ b/doc/book/en/development/datamodel/define-workflows.rst Wed Jul 08 13:59:22 2009 +0200 @@ -118,7 +118,7 @@ * `%(seid)s`, the object's current state eid -.. image:: images/lax-book.03-transitions-view.en.png +.. image:: ../../images/lax-book.03-transitions-view.en.png You can notice that in the action box of a BlogEntry, the state is now listed as well as the possible transitions defined by the workflow. diff -r 3f7c7fbae94e -r 00b704535984 entity.py --- a/entity.py Wed Jul 08 13:58:37 2009 +0200 +++ b/entity.py Wed Jul 08 13:59:22 2009 +0200 @@ -13,7 +13,7 @@ from logilab.common.compat import all from logilab.common.decorators import cached from logilab.common.deprecation import obsolete -from logilab.mtconverter import TransformData, TransformError, html_escape +from logilab.mtconverter import TransformData, TransformError, xml_escape from rql.utils import rqlvar_maker @@ -456,7 +456,7 @@ return u'' value = printable_value(self.req, attrtype, value, props, displaytime) if format == 'text/html': - value = html_escape(value) + value = xml_escape(value) return value def mtc_transform(self, data, format, target_format, encoding, @@ -659,6 +659,7 @@ self.critical("can't get value for attribute %s of entity with eid %s", name, self.eid) if self.e_schema.destination(name) == 'String': + # XXX (syt) imo emtpy string is better self[name] = value = self.req._('unaccessible') else: self[name] = value = None diff -r 3f7c7fbae94e -r 00b704535984 ext/html4zope.py --- a/ext/html4zope.py Wed Jul 08 13:58:37 2009 +0200 +++ b/ext/html4zope.py Wed Jul 08 13:59:22 2009 +0200 @@ -24,7 +24,7 @@ __docformat__ = 'reStructuredText' -from logilab.mtconverter import html_escape +from logilab.mtconverter import xml_escape from docutils import nodes from docutils.writers.html4css1 import Writer as CSS1Writer @@ -154,7 +154,7 @@ error = u'System Message: %s%s/%s%s (%s %s)%s

\n' % ( a_start, node['type'], node['level'], a_end, self.encode(node['source']), line, backref_text) - self.body.append(u'
ReST / HTML errors:%s
' % html_escape(error)) + self.body.append(u'
ReST / HTML errors:%s
' % xml_escape(error)) def depart_system_message(self, node): pass diff -r 3f7c7fbae94e -r 00b704535984 ext/rest.py --- a/ext/rest.py Wed Jul 08 13:58:37 2009 +0200 +++ b/ext/rest.py Wed Jul 08 13:59:22 2009 +0200 @@ -29,7 +29,7 @@ from docutils.parsers.rst import Parser, states, directives from docutils.parsers.rst.roles import register_canonical_role, set_classes -from logilab.mtconverter import html_escape +from logilab.mtconverter import ESC_UCAR_TABLE, ESC_CAR_TABLE, xml_escape from cubicweb.ext.html4zope import Writer @@ -207,8 +207,12 @@ req = context.req if isinstance(data, unicode): encoding = 'unicode' + # remove unprintable characters unauthorized in xml + data = data.translate(ESC_UCAR_TABLE) else: encoding = req.encoding + # remove unprintable characters unauthorized in xml + data = data.translate(ESC_CAR_TABLE) settings = {'input_encoding': encoding, 'output_encoding': 'unicode', 'warning_stream': StringIO(), 'context': context, # dunno what's the max, severe is 4, and we never want a crash @@ -232,5 +236,5 @@ LOGGER.exception('error while publishing ReST text') if not isinstance(data, unicode): data = unicode(data, encoding, 'replace') - return html_escape(req._('error while publishing ReST text') + return xml_escape(req._('error while publishing ReST text') + '\n\n' + data) diff -r 3f7c7fbae94e -r 00b704535984 goa/appobjects/components.py --- a/goa/appobjects/components.py Wed Jul 08 13:58:37 2009 +0200 +++ b/goa/appobjects/components.py Wed Jul 08 13:59:22 2009 +0200 @@ -7,7 +7,7 @@ """ __docformat__ = "restructuredtext en" -from logilab.mtconverter import html_escape +from logilab.mtconverter import xml_escape from cubicweb import typed_eid from cubicweb.selectors import one_line_rset, match_search_state, accept @@ -74,7 +74,7 @@ label = display_name(req, etype, 'plural') view = self.vreg.select_view('list', req, req.etype_rset(etype)) url = view.url() - etypelink = u' %s' % (html_escape(url), label) + etypelink = u' %s' % (xml_escape(url), label) yield (label, etypelink, self.add_entity_link(eschema, req)) ManageView.entity_types = entity_types_no_count diff -r 3f7c7fbae94e -r 00b704535984 goa/appobjects/dbmgmt.py --- a/goa/appobjects/dbmgmt.py Wed Jul 08 13:58:37 2009 +0200 +++ b/goa/appobjects/dbmgmt.py Wed Jul 08 13:59:22 2009 +0200 @@ -12,7 +12,7 @@ from pickle import loads, dumps from logilab.common.decorators import cached -from logilab.mtconverter import html_escape +from logilab.mtconverter import xml_escape from cubicweb.selectors import none_rset, match_user_groups from cubicweb.common.view import StartupView @@ -54,7 +54,7 @@ break values.append('__session=%s' % cookie['__session'].value) self.w(u"

pass this flag to the client: --cookie='%s'

" - % html_escape('; '.join(values))) + % xml_escape('; '.join(values))) @@ -148,7 +148,7 @@ % cpath) self.w(u'
click here to ' 'delete all datastore content so process can be ' - 'reinitialized
' % html_escape(self.req.base_url())) + 'reinitialized
' % xml_escape(self.req.base_url())) Put(status) @property @@ -159,11 +159,11 @@ repo=self.config.repository()) def msg(self, msg): - self.w(u'
%s
' % html_escape(msg)) + self.w(u'
%s
' % xml_escape(msg)) def redirect(self, msg): raise Redirect(self.req.build_url('', msg)) def continue_link(self): - self.w(u'continue
' % html_escape(self.req.url())) + self.w(u'continue
' % xml_escape(self.req.url())) class ContentClear(StartupView): diff -r 3f7c7fbae94e -r 00b704535984 selectors.py --- a/selectors.py Wed Jul 08 13:58:37 2009 +0200 +++ b/selectors.py Wed Jul 08 13:59:22 2009 +0200 @@ -79,7 +79,7 @@ ret = selector(cls, *args, **kwargs) if TRACED_OIDS == 'all' or oid in TRACED_OIDS: #SELECTOR_LOGGER.warning('selector %s returned %s for %s', selname, ret, cls) - print 'selector %s returned %s for %s' % (selname, ret, vobj) + print '%s -> %s for %s' % (selname, ret, vobj) return ret traced.__name__ = selector.__name__ return traced diff -r 3f7c7fbae94e -r 00b704535984 server/__init__.py --- a/server/__init__.py Wed Jul 08 13:58:37 2009 +0200 +++ b/server/__init__.py Wed Jul 08 13:59:22 2009 +0200 @@ -50,8 +50,7 @@ driver = source['db-driver'] sqlcnx = repo.system_source.get_connection() sqlcursor = sqlcnx.cursor() - def execute(sql, args=None): - repo.system_source.doexec(sqlcursor, sql, args) + execute = sqlcursor.execute if drop: dropsql = sqldropschema(schema, driver) try: diff -r 3f7c7fbae94e -r 00b704535984 server/session.py --- a/server/session.py Wed Jul 08 13:58:37 2009 +0200 +++ b/server/session.py Wed Jul 08 13:59:22 2009 +0200 @@ -88,9 +88,7 @@ """return a sql cursor on the system database""" if not sql.split(None, 1)[0].upper() == 'SELECT': self.mode = 'write' - cursor = self.pool['system'] - self.pool.source('system').doexec(cursor, sql, args) - return cursor + return self.pool.source('system').doexec(self, sql, args) def set_language(self, language): """i18n configuration for translation""" @@ -137,24 +135,27 @@ raise Exception('try to set pool on a closed session') if self.pool is None: # get pool first to avoid race-condition - self._threaddata.pool = self.repo._get_pool() + self._threaddata.pool = pool = self.repo._get_pool() try: - self._threaddata.pool.pool_set() + pool.pool_set() except: self._threaddata.pool = None - self.repo._free_pool(self.pool) + self.repo._free_pool(pool) raise self._threads_in_transaction.add(threading.currentThread()) return self._threaddata.pool def reset_pool(self): - """the session has no longer using its pool, at least for some time""" + """the session is no longer using its pool, at least for some time""" # pool may be none if no operation has been done since last commit # or rollback if self.pool is not None and self.mode == 'read': # even in read mode, we must release the current transaction pool = self.pool - self._threads_in_transaction.remove(threading.currentThread()) + try: + self._threads_in_transaction.remove(threading.currentThread()) + except KeyError: + pass pool.pool_reset() self._threaddata.pool = None # free pool once everything is done to avoid race-condition diff -r 3f7c7fbae94e -r 00b704535984 server/sources/extlite.py --- a/server/sources/extlite.py Wed Jul 08 13:58:37 2009 +0200 +++ b/server/sources/extlite.py Wed Jul 08 13:59:22 2009 +0200 @@ -174,9 +174,7 @@ if server.DEBUG: print self.uri, 'SOURCE RQL', union.as_string() args = self.sqladapter.merge_args(args, query_args) - cursor = session.pool[self.uri] - self.doexec(cursor, sql, args) - res = self.sqladapter.process_result(cursor) + res = self.sqladapter.process_result(self.doexec(session, sql, args)) if server.DEBUG: print '------>', res return res @@ -190,7 +188,7 @@ """ attrs = self.sqladapter.preprocess_entity(entity) sql = self.sqladapter.sqlgen.insert(SQL_PREFIX + str(entity.e_schema), attrs) - self.doexec(session.pool[self.uri], sql, attrs) + self.doexec(session, sql, attrs) def add_entity(self, session, entity): """add a new entity to the source""" @@ -207,7 +205,7 @@ attrs = self.sqladapter.preprocess_entity(entity) sql = self.sqladapter.sqlgen.update(SQL_PREFIX + str(entity.e_schema), attrs, [SQL_PREFIX + 'eid']) - self.doexec(session.pool[self.uri], sql, attrs) + self.doexec(session, sql, attrs) def update_entity(self, session, entity): """update an entity in the source""" @@ -222,7 +220,7 @@ """ attrs = {SQL_PREFIX + 'eid': eid} sql = self.sqladapter.sqlgen.delete(SQL_PREFIX + etype, attrs) - self.doexec(session.pool[self.uri], sql, attrs) + self.doexec(session, sql, attrs) def local_add_relation(self, session, subject, rtype, object): """add a relation to the source @@ -233,7 +231,7 @@ """ attrs = {'eid_from': subject, 'eid_to': object} sql = self.sqladapter.sqlgen.insert('%s_relation' % rtype, attrs) - self.doexec(session.pool[self.uri], sql, attrs) + self.doexec(session, sql, attrs) def add_relation(self, session, subject, rtype, object): """add a relation to the source""" @@ -252,21 +250,25 @@ else: attrs = {'eid_from': subject, 'eid_to': object} sql = self.sqladapter.sqlgen.delete('%s_relation' % rtype, attrs) - self.doexec(session.pool[self.uri], sql, attrs) + self.doexec(session, sql, attrs) - def doexec(self, cursor, query, args=None): + def doexec(self, session, query, args=None): """Execute a query. it's a function just so that it shows up in profiling """ - #t1 = time() if server.DEBUG: print 'exec', query, args - #import sys - #sys.stdout.flush() - # str(query) to avoid error if it's an unicode string + cursor = session.pool[self.uri] try: + # str(query) to avoid error if it's an unicode string cursor.execute(str(query), args) except Exception, ex: self.critical("sql: %r\n args: %s\ndbms message: %r", query, args, ex.args[0]) + try: + session.pool.connection(self.uri).rollback() + self.critical('transaction has been rollbacked') + except: + pass raise + return cursor diff -r 3f7c7fbae94e -r 00b704535984 server/sources/native.py --- a/server/sources/native.py Wed Jul 08 13:58:37 2009 +0200 +++ b/server/sources/native.py Wed Jul 08 13:59:22 2009 +0200 @@ -185,9 +185,7 @@ def sqlexec(self, session, sql, args=None): """execute the query and return its result""" - cursor = session.pool[self.uri] - self.doexec(cursor, sql, args) - return self.process_result(cursor) + return self.process_result(self.doexec(session, sql, args)) def init_creating(self): pool = self.repo._get_pool() @@ -305,17 +303,15 @@ sql, query_args = self._rql_sqlgen.generate(union, args, varmap) self._cache[cachekey] = sql, query_args args = self.merge_args(args, query_args) - cursor = session.pool[self.uri] assert isinstance(sql, basestring), repr(sql) try: - self.doexec(cursor, sql, args) + cursor = self.doexec(session, sql, args) except (self.dbapi_module.OperationalError, self.dbapi_module.InterfaceError): # FIXME: better detection of deconnection pb self.info("request failed '%s' ... retry with a new cursor", sql) session.pool.reconnect(self) - cursor = session.pool[self.uri] - self.doexec(cursor, sql, args) + cursor = self.doexec(session, sql, args) res = self.process_result(cursor) if server.DEBUG: print '------>', res @@ -337,8 +333,7 @@ # generate sql queries if we are able to do so sql, query_args = self._rql_sqlgen.generate(union, args, varmap) query = 'INSERT INTO %s %s' % (table, sql.encode(self.encoding)) - self.doexec(session.pool[self.uri], query, - self.merge_args(args, query_args)) + self.doexec(session, query, self.merge_args(args, query_args)) else: super(NativeSQLSource, self).flying_insert(table, session, union, args, varmap) @@ -358,15 +353,14 @@ cell = self.binary(cell.getvalue()) kwargs[str(index)] = cell kwargs_list.append(kwargs) - self.doexecmany(session.pool[self.uri], query, kwargs_list) + self.doexecmany(session, query, kwargs_list) def clean_temp_data(self, session, temptables): """remove temporary data, usually associated to temporary tables""" if temptables: - cursor = session.pool[self.uri] for table in temptables: try: - self.doexec(cursor,'DROP TABLE %s' % table) + self.doexec(session,'DROP TABLE %s' % table) except: pass try: @@ -378,25 +372,25 @@ """add a new entity to the source""" attrs = self.preprocess_entity(entity) sql = self.sqlgen.insert(SQL_PREFIX + str(entity.e_schema), attrs) - self.doexec(session.pool[self.uri], sql, attrs) + self.doexec(session, sql, attrs) def update_entity(self, session, entity): """replace an entity in the source""" attrs = self.preprocess_entity(entity) sql = self.sqlgen.update(SQL_PREFIX + str(entity.e_schema), attrs, [SQL_PREFIX + 'eid']) - self.doexec(session.pool[self.uri], sql, attrs) + self.doexec(session, sql, attrs) def delete_entity(self, session, etype, eid): """delete an entity from the source""" attrs = {SQL_PREFIX + 'eid': eid} sql = self.sqlgen.delete(SQL_PREFIX + etype, attrs) - self.doexec(session.pool[self.uri], sql, attrs) + self.doexec(session, sql, attrs) def add_relation(self, session, subject, rtype, object): """add a relation to the source""" attrs = {'eid_from': subject, 'eid_to': object} sql = self.sqlgen.insert('%s_relation' % rtype, attrs) - self.doexec(session.pool[self.uri], sql, attrs) + self.doexec(session, sql, attrs) def delete_relation(self, session, subject, rtype, object): """delete a relation from the source""" @@ -410,39 +404,47 @@ else: attrs = {'eid_from': subject, 'eid_to': object} sql = self.sqlgen.delete('%s_relation' % rtype, attrs) - self.doexec(session.pool[self.uri], sql, attrs) + self.doexec(session, sql, attrs) - def doexec(self, cursor, query, args=None): + def doexec(self, session, query, args=None): """Execute a query. it's a function just so that it shows up in profiling """ - #t1 = time() if server.DEBUG: print 'exec', query, args - #import sys - #sys.stdout.flush() - # str(query) to avoid error if it's an unicode string + cursor = session.pool[self.uri] try: + # str(query) to avoid error if it's an unicode string cursor.execute(str(query), args) except Exception, ex: self.critical("sql: %r\n args: %s\ndbms message: %r", query, args, ex.args[0]) + try: + session.pool.connection(self.uri).rollback() + self.critical('transaction has been rollbacked') + except: + pass raise + return cursor - def doexecmany(self, cursor, query, args): + def doexecmany(self, session, query, args): """Execute a query. it's a function just so that it shows up in profiling """ - #t1 = time() if server.DEBUG: print 'execmany', query, 'with', len(args), 'arguments' - #import sys - #sys.stdout.flush() - # str(query) to avoid error if it's an unicode string + cursor = session.pool[self.uri] try: + # str(query) to avoid error if it's an unicode string cursor.executemany(str(query), args) - except: - self.critical("sql many: %r\n args: %s", query, args) + except Exception, ex: + self.critical("sql many: %r\n args: %s\ndbms message: %r", + query, args, ex.args[0]) + try: + session.pool.connection(self.uri).rollback() + self.critical('transaction has been rollbacked') + except: + pass raise # short cut to method requiring advanced db helper usage ################## @@ -498,14 +500,13 @@ # running with an ldap source, and table will be deleted manually any way # on commit sql = self.dbhelper.sql_temporary_table(table, schema, False) - self.doexec(session.pool[self.uri], sql) + self.doexec(session, sql) def create_eid(self, session): self._eid_creation_lock.acquire() try: - cursor = session.pool[self.uri] for sql in self.dbhelper.sqls_increment_sequence('entities_id_seq'): - self.doexec(cursor, sql) + cursor = self.doexec(session, sql) return cursor.fetchone()[0] finally: self._eid_creation_lock.release() diff -r 3f7c7fbae94e -r 00b704535984 view.py --- a/view.py Wed Jul 08 13:58:37 2009 +0200 +++ b/view.py Wed Jul 08 13:59:22 2009 +0200 @@ -12,7 +12,7 @@ from cStringIO import StringIO from logilab.common.deprecation import obsolete -from logilab.mtconverter import html_escape +from logilab.mtconverter import xml_escape from cubicweb import NotAnEntity from cubicweb.selectors import yes, non_final_entity, nonempty_rset, none_rset @@ -219,7 +219,7 @@ def wdata(self, data): """simple helper that escapes `data` and writes into `self.w`""" - self.w(html_escape(data)) + self.w(xml_escape(data)) def html_headers(self): """return a list of html headers (eg something to be inserted between @@ -440,10 +440,10 @@ def cb(*args): _cb(*args) cbname = self.req.register_onetime_callback(cb, *args) - return self.build_js(cbname, html_escape(msg or '')) + return self.build_js(cbname, xml_escape(msg or '')) def build_update_js_call(self, cbname, msg): - rql = html_escape(self.rset.printable_rql()) + rql = xml_escape(self.rset.printable_rql()) return "javascript:userCallbackThenUpdateUI('%s', '%s', '%s', '%s', '%s', '%s')" % ( cbname, self.id, rql, msg, self.__registry__, self.div_id()) diff -r 3f7c7fbae94e -r 00b704535984 vregistry.py --- a/vregistry.py Wed Jul 08 13:58:37 2009 +0200 +++ b/vregistry.py Wed Jul 08 13:59:22 2009 +0200 @@ -1,10 +1,10 @@ """ -* the vregistry handle various type of objects interacting - together. The vregistry handle registration of dynamically loaded - objects and provide a convenient api access to those objects +* the vregistry handles various types of objects interacting + together. The vregistry handles registration of dynamically loaded + objects and provides a convenient api to access those objects according to a context -* to interact with the vregistry, object should inherit from the +* to interact with the vregistry, objects should inherit from the VObject abstract class * the selection procedure has been generalized by delegating to a @@ -188,9 +188,6 @@ # 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: diff -r 3f7c7fbae94e -r 00b704535984 web/box.py --- a/web/box.py Wed Jul 08 13:58:37 2009 +0200 +++ b/web/box.py Wed Jul 08 13:59:22 2009 +0200 @@ -8,7 +8,7 @@ __docformat__ = "restructuredtext en" _ = unicode -from logilab.mtconverter import html_escape +from logilab.mtconverter import xml_escape from cubicweb import Unauthorized, role as get_role, target as get_target from cubicweb.selectors import (one_line_rset, primary_view, @@ -74,7 +74,7 @@ .format_actions method """ if escape: - title = html_escape(title) + title = xml_escape(title) return self.box_action(self._action(title, path, **kwargs)) def _action(self, title, path, **kwargs): diff -r 3f7c7fbae94e -r 00b704535984 web/component.py --- a/web/component.py Wed Jul 08 13:58:37 2009 +0200 +++ b/web/component.py Wed Jul 08 13:59:22 2009 +0200 @@ -9,7 +9,7 @@ _ = unicode from logilab.common.deprecation import class_renamed -from logilab.mtconverter import html_escape +from logilab.mtconverter import xml_escape from cubicweb import role from cubicweb.utils import merge_dicts @@ -117,7 +117,7 @@ def page_link(self, path, params, start, stop, content): url = self.build_url(path, **merge_dicts(params, {self.start_param : start, self.stop_param : stop,})) - url = html_escape(url) + url = xml_escape(url) if start == self.starting_from: return self.selected_page_link_templ % (url, content, content) return self.page_link_templ % (url, content, content) @@ -130,7 +130,7 @@ stop = start + self.page_size - 1 url = self.build_url(**merge_dicts(params, {self.start_param : start, self.stop_param : stop,})) - url = html_escape(url) + url = xml_escape(url) return self.previous_page_link_templ % (url, title, content) def next_link(self, params, content='>>', title=_('next_results')): @@ -140,7 +140,7 @@ stop = start + self.page_size - 1 url = self.build_url(**merge_dicts(params, {self.start_param : start, self.stop_param : stop,})) - url = html_escape(url) + url = xml_escape(url) return self.next_page_link_templ % (url, title, content) diff -r 3f7c7fbae94e -r 00b704535984 web/controller.py --- a/web/controller.py Wed Jul 08 13:58:37 2009 +0200 +++ b/web/controller.py Wed Jul 08 13:59:22 2009 +0200 @@ -182,11 +182,9 @@ elif '__redirectpath' in self.req.form: # if redirect path was explicitly specified in the form, use it path = self.req.form['__redirectpath'] - if self._edited_entity: - msg = newparams.get('__message', '') - msg += ' (%s)' % ( - self._edited_entity.absolute_url(), - self.req._('click here to see created entity')) + if self._edited_entity and path != self._edited_entity.rest_path(): + # XXX may be here on modification? if yes the message should be + # modified where __createdpath is detected (cw.web.request) newparams['__createdpath'] = self._edited_entity.rest_path() elif self._after_deletion_path: # else it should have been set during form processing diff -r 3f7c7fbae94e -r 00b704535984 web/data/cubicweb.formfilter.js --- a/web/data/cubicweb.formfilter.js Wed Jul 08 13:58:37 2009 +0200 +++ b/web/data/cubicweb.formfilter.js Wed Jul 08 13:59:22 2009 +0200 @@ -135,7 +135,7 @@ } else{ this.setAttribute('src', UNSELECTED_IMG); - this.setAttribute('alt', (_('not selected'))); + this.setAttribute('alt', (_('not selected'))); } }); var index = parseInt($this.attr('cubicweb:idx')); @@ -149,8 +149,7 @@ if ( ! ($insertAfter.length == 1 && shift == 0) ) { // only rearrange element if necessary $insertAfter.after(this); - }else{ - } + } } else { var lastSelected = facet.find('.facetValueSelected:last'); if (lastSelected.length) { @@ -160,10 +159,8 @@ jQuery(parent).prepend(this); } jQuery(this).addClass('facetValueSelected'); - var img = jQuery(this).find('img'); - img.attr('src', SELECTED_IMG); - img.attr('alt', (_('selected'))); - + var $img = jQuery(this).find('img'); + $img.attr('src', SELECTED_IMG).attr('alt', (_('selected'))); } buildRQL.apply(null, evalJSON(form.attr('cubicweb:facetargs'))); facet.find('.facetBody').animate({scrollTop: 0}, ''); diff -r 3f7c7fbae94e -r 00b704535984 web/facet.py --- a/web/facet.py Wed Jul 08 13:58:37 2009 +0200 +++ b/web/facet.py Wed Jul 08 13:59:22 2009 +0200 @@ -12,7 +12,7 @@ from copy import deepcopy from datetime import date, datetime, timedelta -from logilab.mtconverter import html_escape +from logilab.mtconverter import xml_escape from logilab.common.graph import has_path from logilab.common.decorators import cached @@ -21,6 +21,7 @@ from rql import parse, nodes from cubicweb import Unauthorized, typed_eid +from cubicweb.schema import display_name from cubicweb.utils import datetime2ticks, make_uid, ustrftime from cubicweb.selectors import match_context_prop, partial_relation_possible from cubicweb.appobject import AppRsetObject @@ -70,7 +71,7 @@ def filter_hiddens(w, **kwargs): for key, val in kwargs.items(): w(u'' % ( - key, html_escape(val))) + key, xml_escape(val))) def _may_be_removed(rel, schema, mainvar): @@ -586,11 +587,11 @@ self.items.append(item) def _render(self): - title = html_escape(self.facet.title) - facetid = html_escape(self.facet.id) + title = xml_escape(self.facet.title) + facetid = xml_escape(self.facet.id) self.w(u'
\n' % facetid) self.w(u'
%s
\n' % - (html_escape(facetid), title)) + (xml_escape(facetid), title)) if self.facet.support_and(): _ = self.facet.req._ self.w(u''' ''' % (not self.propval('visible') and 'hidden' or '', - self.build_url('view'), html_escape(rql), req._('full text or RQL query'), req.next_tabindex(), + self.build_url('view'), xml_escape(rql), req._('full text or RQL query'), req.next_tabindex(), req.next_tabindex())) if self.req.search_state[0] != 'normal': self.w(u'' @@ -202,7 +203,7 @@ url = self.build_url(rql=newrql, __restrrql=restrrql, __restrtype=etype, __restrtypes=','.join(restrtypes)) html.append(u'%s' % ( - html_escape(url), elabel)) + xml_escape(url), elabel)) rqlst.recover() if on_etype: url = self.build_url(rql=restrrql) diff -r 3f7c7fbae94e -r 00b704535984 web/views/basecontrollers.py --- a/web/views/basecontrollers.py Wed Jul 08 13:58:37 2009 +0200 +++ b/web/views/basecontrollers.py Wed Jul 08 13:59:22 2009 +0200 @@ -15,7 +15,7 @@ import simplejson from logilab.common.decorators import cached -from logilab.mtconverter import html_escape +from logilab.mtconverter import xml_escape from cubicweb import NoSelectableObject, ValidationError, ObjectNotFound, typed_eid from cubicweb.utils import strptime @@ -411,7 +411,7 @@ if rset: output = self.view(vid, rset) if vid == 'textoutofcontext': - output = html_escape(output) + output = xml_escape(output) else: output = default return (success, args, output) diff -r 3f7c7fbae94e -r 00b704535984 web/views/baseforms.py --- a/web/views/baseforms.py Wed Jul 08 13:58:37 2009 +0200 +++ b/web/views/baseforms.py Wed Jul 08 13:59:22 2009 +0200 @@ -12,7 +12,7 @@ from simplejson import dumps -from logilab.mtconverter import html_escape +from logilab.mtconverter import xml_escape from logilab.common.decorators import cached from cubicweb.selectors import (specified_etype_implements, accepts_etype_compat, @@ -148,7 +148,7 @@ output = [] for name, value, iid in self._hiddens: if isinstance(value, basestring): - value = html_escape(value) + value = xml_escape(value) if iid: output.append(u'' % (iid, name, value)) @@ -249,14 +249,14 @@ w(u'[x]' % (_('cancel this insert'), row[2])) w(u'%s' - % (row[1], row[4], html_escape(row[5]))) + % (row[1], row[4], xml_escape(row[5]))) w(u'') w(u'') w(u'' % eid) w(u'') w(u'%s' % _('add relation')) w(u'
""" % (hidden and 'hidden' or '', divid, selectid, - html_escape(dumps(entity.eid)), is_cell and 'true' or 'null', relname, + xml_escape(dumps(entity.eid)), is_cell and 'true' or 'null', relname, '\n'.join(options)) def _get_select_options(self, entity, rschema, target): @@ -127,13 +127,13 @@ for eview, reid in form.form_field_vocabulary(field, limit): if reid is None: options.append('' - % html_escape(eview)) + % xml_escape(eview)) else: optionid = relation_id(eid, rtype, target, reid) if optionid not in pending_inserts: # prefix option's id with letters to make valid XHTML wise options.append('' % - (optionid, reid, html_escape(eview))) + (optionid, reid, xml_escape(eview))) return options def _get_search_options(self, entity, rschema, target, targettypes): @@ -146,7 +146,7 @@ __mode=mode) options.append((eschema.display_name(self.req), '' % ( - html_escape(url), _('Search for'), eschema.display_name(self.req)))) + xml_escape(url), _('Search for'), eschema.display_name(self.req)))) return [o for l, o in sorted(options)] def _get_basket_options(self, entity, rschema, target, targettypes): @@ -157,7 +157,7 @@ target, targettypes): optionid = relation_id(entity.eid, rtype, target, basketeid) options.append('' % ( - optionid, basketeid, _('link to each item in'), html_escape(basketname))) + optionid, basketeid, _('link to each item in'), xml_escape(basketname))) return options def _get_basket_links(self, ueid, target, targettypes): diff -r 3f7c7fbae94e -r 00b704535984 web/views/emailaddress.py --- a/web/views/emailaddress.py Wed Jul 08 13:58:37 2009 +0200 +++ b/web/views/emailaddress.py Wed Jul 08 13:59:22 2009 +0200 @@ -7,8 +7,9 @@ """ __docformat__ = "restructuredtext en" -from logilab.mtconverter import html_escape +from logilab.mtconverter import xml_escape +from cubicweb.schema import display_name from cubicweb.selectors import implements from cubicweb.common import Unauthorized from cubicweb.web.views import baseviews, primary @@ -79,9 +80,9 @@ if entity.reverse_primary_email: self.w(u'') if entity.alias: - self.w(u'%s <' % html_escape(entity.alias)) - self.w('%s' % (html_escape(entity.absolute_url()), - html_escape(entity.display_address()))) + self.w(u'%s <' % xml_escape(entity.alias)) + self.w('%s' % (xml_escape(entity.absolute_url()), + xml_escape(entity.display_address()))) if entity.alias: self.w(u'>\n') if entity.reverse_primary_email: @@ -108,8 +109,8 @@ mailto = "mailto:%s <%s>" % (alias, entity.display_address()) else: mailto = "mailto:%s" % entity.display_address() - self.w(u'%s' % (html_escape(mailto), - html_escape(entity.display_address()))) + self.w(u'%s' % (xml_escape(mailto), + xml_escape(entity.display_address()))) if entity.reverse_primary_email: self.w(u'') diff -r 3f7c7fbae94e -r 00b704535984 web/views/facets.py --- a/web/views/facets.py Wed Jul 08 13:58:37 2009 +0200 +++ b/web/views/facets.py Wed Jul 08 13:59:22 2009 +0200 @@ -9,7 +9,7 @@ from simplejson import dumps -from logilab.mtconverter import html_escape +from logilab.mtconverter import xml_escape from cubicweb.vregistry import objectify_selector from cubicweb.selectors import (non_final_entity, two_lines_rset, @@ -42,7 +42,7 @@ needs_css = 'cubicweb.facets.css' needs_js = ('cubicweb.ajax.js', 'cubicweb.formfilter.js') - bkLinkBox_template = u'
%s
' + bk_linkbox_template = u'
%s
' def facetargs(self): """this method returns the list of extra arguments that should @@ -83,11 +83,11 @@ widgets.append(wdg) if not widgets: return - if self.bkLinkBox_template: - self.displayBookmarkLink(rset) + if self.bk_linkbox_template: + self.display_bookmark_link(rset) w = self.w w(u'
' % ( - divid, html_escape(dumps([divid, vid, paginate, self.facetargs()])))) + divid, xml_escape(dumps([divid, vid, paginate, self.facetargs()])))) w(u'
') hiddens = {'facets': ','.join(wdg.facet.id for wdg in widgets), 'baserql': baserql} @@ -103,7 +103,7 @@ import cubicweb cubicweb.info('after facets with rql: %s' % repr(rqlst)) - def displayBookmarkLink(self, rset): + def display_bookmark_link(self, rset): eschema = self.schema.eschema('Bookmark') if eschema.has_perm(self.req, 'add'): bk_path = 'view?rql=%s' % rset.printable_rql() @@ -112,10 +112,10 @@ bk_add_url = self.build_url('add/Bookmark', path=bk_path, title=bk_title, __linkto=linkto) bk_base_url = self.build_url('add/Bookmark', title=bk_title, __linkto=linkto) bk_link = u'%s' % ( - html_escape(bk_base_url), - html_escape(bk_add_url), + xml_escape(bk_base_url), + xml_escape(bk_add_url), self.req._('bookmark this search')) - self.w(self.bkLinkBox_template % bk_link) + self.w(self.bk_linkbox_template % bk_link) def get_facets(self, rset, mainvar): return self.vreg.possible_vobjects('facets', self.req, rset, diff -r 3f7c7fbae94e -r 00b704535984 web/views/formrenderers.py --- a/web/views/formrenderers.py Wed Jul 08 13:58:37 2009 +0200 +++ b/web/views/formrenderers.py Wed Jul 08 13:59:22 2009 +0200 @@ -8,7 +8,7 @@ __docformat__ = "restructuredtext en" from logilab.common import dictattr -from logilab.mtconverter import html_escape +from logilab.mtconverter import xml_escape from simplejson import dumps @@ -144,17 +144,17 @@ else: action = form.action tag = ('' def display_field(self, form, field): @@ -298,7 +298,7 @@ entity = form.edited_entity values = form.form_previous_values qeid = eid_param('eid', entity.eid) - cbsetstate = "setCheckboxesState2('eid', %s, 'checked')" % html_escape(dumps(entity.eid)) + cbsetstate = "setCheckboxesState2('eid', %s, 'checked')" % xml_escape(dumps(entity.eid)) w(u'' % (entity.row % 2 and u'even' or u'odd')) # XXX turn this into a widget used on the eid field w(u'%s' % checkbox('eid', entity.eid, checked=qeid in values)) @@ -411,7 +411,7 @@ w(u'[x]' % (_('cancel this insert'), row[2])) w(u'%s' - % (row[1], row[4], html_escape(row[5]))) + % (row[1], row[4], xml_escape(row[5]))) w(u'') w(u'') w(u'' % eid) @@ -419,7 +419,7 @@ w(u'%s' % _('add relation')) w(u'' % divid) filter_hiddens(self.w, facets=','.join(wdg.facet.id for wdg in fwidgets), baserql=baserql) @@ -178,7 +178,7 @@ box = MenuWidget('', 'tableActionsBox', _class='', islist=False) label = '%s' % ( self.req.datadir_url + 'liveclipboard-icon.png', - html_escape(self.req._('action(s) on this selection'))) + xml_escape(self.req._('action(s) on this selection'))) menu = PopupBoxMenu(label, isitem=False, link_class='actionsBox', ident='%sActions' % divid) box.append(menu) diff -r 3f7c7fbae94e -r 00b704535984 web/views/tabs.py --- a/web/views/tabs.py Wed Jul 08 13:58:37 2009 +0200 +++ b/web/views/tabs.py Wed Jul 08 13:59:22 2009 +0200 @@ -8,7 +8,7 @@ __docformat__ = "restructuredtext en" -from logilab.mtconverter import html_escape +from logilab.mtconverter import xml_escape from cubicweb import NoSelectableObject, role from cubicweb.selectors import partial_has_related_entities @@ -47,7 +47,7 @@ elif rset: urlparams['rql'] = rset.printable_rql() w(u'
' % ( - vid, html_escape(self.build_url('json', **urlparams)))) + vid, xml_escape(self.build_url('json', **urlparams)))) if show_spinbox: w(u'%s' % (vid, self.req._('loading'))) diff -r 3f7c7fbae94e -r 00b704535984 web/views/timeline.py --- a/web/views/timeline.py Wed Jul 08 13:58:37 2009 +0200 +++ b/web/views/timeline.py Wed Jul 08 13:59:22 2009 +0200 @@ -11,7 +11,7 @@ import simplejson -from logilab.mtconverter import html_escape +from logilab.mtconverter import xml_escape from cubicweb.interfaces import ICalendarable from cubicweb.selectors import implements @@ -68,7 +68,7 @@ if start is None and stop is None: return None event_data = {'start': start.strftime(self.date_fmt), - 'title': html_escape(entity.dc_title()), + 'title': xml_escape(entity.dc_title()), 'description': entity.dc_description(format='text/html'), 'link': entity.absolute_url(), } @@ -95,7 +95,7 @@ additional = u'' self.w(u'
' % - (self.widget_class, html_escape(loadurl), + (self.widget_class, xml_escape(loadurl), additional)) self.w(u'
') diff -r 3f7c7fbae94e -r 00b704535984 web/views/timetable.py --- a/web/views/timetable.py Wed Jul 08 13:58:37 2009 +0200 +++ b/web/views/timetable.py Wed Jul 08 13:59:22 2009 +0200 @@ -6,7 +6,7 @@ :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses """ -from logilab.mtconverter import html_escape +from logilab.mtconverter import xml_escape from cubicweb.interfaces import ITimetableViews from cubicweb.selectors import implements @@ -190,7 +190,7 @@ if value: task_descr, first_row = value if first_row: - url = html_escape(task_descr.task.absolute_url(vid="edition")) + url = xml_escape(task_descr.task.absolute_url(vid="edition")) self.w(u' 
' % ( task_descr.lines, task_descr.color, filled_klasses[kj], url)) task_descr.task.view('tooltip', w=self.w) diff -r 3f7c7fbae94e -r 00b704535984 web/views/treeview.py --- a/web/views/treeview.py Wed Jul 08 13:58:37 2009 +0200 +++ b/web/views/treeview.py Wed Jul 08 13:59:22 2009 +0200 @@ -8,7 +8,7 @@ __docformat__ = "restructuredtext en" from logilab.common.decorators import monkeypatch -from logilab.mtconverter import html_escape +from logilab.mtconverter import xml_escape from cubicweb.utils import make_uid from cubicweb.interfaces import ITree @@ -113,7 +113,7 @@ w(u'
  • ' % u' '.join(liclasses)) else: rql = entity.children_rql() % {'x': entity.eid} - url = html_escape(self.build_url('json', rql=rql, vid=parentvid, + url = xml_escape(self.build_url('json', rql=rql, vid=parentvid, pageid=self.req.pageid, treeid=treeid, fname='view', diff -r 3f7c7fbae94e -r 00b704535984 web/views/workflow.py --- a/web/views/workflow.py Wed Jul 08 13:58:37 2009 +0200 +++ b/web/views/workflow.py Wed Jul 08 13:59:22 2009 +0200 @@ -11,7 +11,7 @@ __docformat__ = "restructuredtext en" _ = unicode -from logilab.mtconverter import html_escape +from logilab.mtconverter import xml_escape from logilab.common.graph import escape, GraphGenerator, DotBackend from cubicweb import Unauthorized, view @@ -119,7 +119,7 @@ __select__ = implements('State') def cell_call(self, row, col): - self.w(html_escape(self.view('textincontext', self.rset, + self.w(xml_escape(self.view('textincontext', self.rset, row=row, col=col))) @@ -146,8 +146,8 @@ self.w(u'

    %s

    ' % (self.req._('workflow for %s') % display_name(self.req, entity.name))) self.w(u'%s' % ( - html_escape(entity.absolute_url(vid='ewfgraph')), - html_escape(self.req._('graphical workflow for %s') % entity.name))) + xml_escape(entity.absolute_url(vid='ewfgraph')), + xml_escape(self.req._('graphical workflow for %s') % entity.name))) class WorkflowDotPropsHandler(object): diff -r 3f7c7fbae94e -r 00b704535984 web/views/xbel.py --- a/web/views/xbel.py Wed Jul 08 13:58:37 2009 +0200 +++ b/web/views/xbel.py Wed Jul 08 13:59:22 2009 +0200 @@ -8,7 +8,7 @@ __docformat__ = "restructuredtext en" _ = unicode -from logilab.mtconverter import html_escape +from logilab.mtconverter import xml_escape from cubicweb.selectors import implements from cubicweb.view import EntityView @@ -42,8 +42,8 @@ def cell_call(self, row, col): entity = self.complete_entity(row, col) - self.w(u'' % html_escape(self.url(entity))) - self.w(u' %s' % html_escape(entity.dc_title())) + self.w(u'' % xml_escape(self.url(entity))) + self.w(u' %s' % xml_escape(entity.dc_title())) self.w(u'') def url(self, entity): diff -r 3f7c7fbae94e -r 00b704535984 web/widgets.py --- a/web/widgets.py Wed Jul 08 13:58:37 2009 +0200 +++ b/web/widgets.py Wed Jul 08 13:59:22 2009 +0200 @@ -12,7 +12,7 @@ from datetime import datetime -from logilab.mtconverter import html_escape +from logilab.mtconverter import xml_escape from yams.constraints import SizeConstraint, StaticVocabularyConstraint @@ -247,9 +247,9 @@ value = self.current_value(entity) dvalue = self.current_display_value(entity) if isinstance(value, basestring): - value = html_escape(value) + value = xml_escape(value) if isinstance(dvalue, basestring): - dvalue = html_escape(dvalue) + dvalue = xml_escape(dvalue) return u'%s' % ( self.hidden_input(entity, value), self.input_type, self.rname, dvalue, self.format_attrs()) @@ -323,9 +323,9 @@ value = self.current_value(entity) dvalue = self.current_display_value(entity) if isinstance(value, basestring): - value = html_escape(value) + value = xml_escape(value) if isinstance(dvalue, basestring): - dvalue = html_escape(dvalue) + dvalue = xml_escape(dvalue) iid = self.attrs.pop('id') if self.required(entity): cssclass = u' required' @@ -337,7 +337,7 @@ 'iid': iid, 'hidden': self.hidden_input(entity, value), 'wdgtype': self.wdgtype, - 'url': html_escape(dataurl), + 'url': xml_escape(dataurl), 'tabindex': self.attrs.pop('tabindex'), 'value': dvalue, 'attrs': self.format_attrs(), @@ -398,7 +398,7 @@ editor = self._edit_render_textarea(entity, with_format) value = self.current_value(entity) if isinstance(value, basestring): - value = html_escape(value) + value = xml_escape(value) return u'%s%s' % (self.hidden_input(entity, value), editor) def _edit_render_textarea(self, entity, with_format): @@ -406,7 +406,7 @@ self.attrs.setdefault('rows', 20) dvalue = self.current_display_value(entity) if isinstance(dvalue, basestring): - dvalue = html_escape(dvalue) + dvalue = xml_escape(dvalue) if entity.use_fckeditor(self.name): entity.req.fckeditor_config() if with_format: @@ -472,9 +472,9 @@ or entity.e_schema.has_metadata(self.name, 'encoding')): divid = '%s-%s-advanced' % (self.name, entity.eid) wdgs.append(u'%s' % - (html_escape(toggle_action(divid)), + (xml_escape(toggle_action(divid)), req._('show advanced fields'), - html_escape(req.build_url('data/puce_down.png')), + xml_escape(req.build_url('data/puce_down.png')), req._('show advanced fields'))) wdgs.append(u'