--- a/appobject.py Fri Sep 23 09:17:37 2011 +0200
+++ b/appobject.py Fri Sep 23 14:18:13 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -241,7 +241,7 @@
for selector in selectors:
try:
selector = _instantiate_selector(selector)
- except:
+ except Exception:
pass
#assert isinstance(selector, Selector), selector
if isinstance(selector, cls):
--- a/cwconfig.py Fri Sep 23 09:17:37 2011 +0200
+++ b/cwconfig.py Fri Sep 23 14:18:13 2011 +0200
@@ -144,7 +144,8 @@
from threading import Lock
from os.path import (exists, join, expanduser, abspath, normpath,
basename, isdir, dirname, splitext)
-from warnings import warn
+from warnings import warn, filterwarnings
+
from logilab.common.decorators import cached, classproperty
from logilab.common.deprecation import deprecated
from logilab.common.logging_ext import set_log_methods, init_log
@@ -618,7 +619,7 @@
try:
__import__('cubes.%s.ccplugin' % cube)
cls.info('loaded cubicweb-ctl plugin from %s', cube)
- except:
+ except Exception:
cls.exception('while loading plugin %s', pluginfile)
elif exists(oldpluginfile):
warn('[3.6] %s: ecplugin module should be renamed to ccplugin' % cube,
@@ -626,12 +627,12 @@
try:
__import__('cubes.%s.ecplugin' % cube)
cls.info('loaded cubicweb-ctl plugin from %s', cube)
- except:
+ except Exception:
cls.exception('while loading plugin %s', oldpluginfile)
elif exists(initfile):
try:
__import__('cubes.%s' % cube)
- except:
+ except Exception:
cls.exception('while loading cube %s', cube)
else:
cls.warning('no __init__ file in cube %s', cube)
@@ -696,6 +697,9 @@
return vregpath
def __init__(self, debugmode=False):
+ if debugmode:
+ # in python 2.7, DeprecationWarning are not shown anymore by default
+ filterwarnings('default', category=DeprecationWarning)
register_stored_procedures()
self._cubes = None
super(CubicWebNoAppConfiguration, self).__init__()
--- a/cwctl.py Fri Sep 23 09:17:37 2011 +0200
+++ b/cwctl.py Fri Sep 23 14:18:13 2011 +0200
@@ -554,7 +554,7 @@
pid = int(open(pidf).read().strip())
try:
kill(pid, signal.SIGTERM)
- except:
+ except Exception:
print >> sys.stderr, "process %s seems already dead." % pid
else:
try:
@@ -564,7 +564,7 @@
print >> sys.stderr, 'trying SIGKILL'
try:
kill(pid, signal.SIGKILL)
- except:
+ except Exception:
# probably dead now
pass
wait_process_end(pid)
--- a/dataimport.py Fri Sep 23 09:17:37 2011 +0200
+++ b/dataimport.py Fri Sep 23 14:18:13 2011 +0200
@@ -554,7 +554,7 @@
self.tell("Run import function '%s'..." % func_name)
try:
func(self)
- except:
+ except Exception:
if self.catcherrors:
self.record_error(func_name, 'While calling %s' % func.__name__)
else:
--- a/dbapi.py Fri Sep 23 09:17:37 2011 +0200
+++ b/dbapi.py Fri Sep 23 14:18:13 2011 +0200
@@ -301,7 +301,7 @@
def set_default_language(self, vreg):
try:
self.lang = vreg.property_value('ui.language')
- except: # property may not be registered
+ except Exception: # property may not be registered
self.lang = 'en'
# use req.__ to translate a message without registering it to the catalog
try:
@@ -532,7 +532,7 @@
if self._closed is None and self._close_on_del:
try:
self.close()
- except:
+ except Exception:
pass
# connection initialization methods ########################################
--- a/devtools/__init__.py Fri Sep 23 09:17:37 2011 +0200
+++ b/devtools/__init__.py Fri Sep 23 14:18:13 2011 +0200
@@ -577,7 +577,7 @@
templcursor.close()
cnx.close()
init_repository(self.config, interactive=False)
- except:
+ except BaseException:
if self.dbcnx is not None:
self.dbcnx.rollback()
print >> sys.stderr, 'building', self.dbname, 'failed'
@@ -752,13 +752,13 @@
value = value.rsplit('.', 1)[0]
try:
row[cellindex] = strptime(value, '%Y-%m-%d %H:%M:%S')
- except:
+ except Exception:
row[cellindex] = strptime(value, '%Y-%m-%d')
if vtype == 'Time' and type(value) is unicode:
found_date = True
try:
row[cellindex] = strptime(value, '%H:%M:%S')
- except:
+ except Exception:
# DateTime used as Time?
row[cellindex] = strptime(value, '%Y-%m-%d %H:%M:%S')
if vtype == 'Interval' and type(value) is int:
--- a/devtools/fill.py Fri Sep 23 09:17:37 2011 +0200
+++ b/devtools/fill.py Fri Sep 23 14:18:13 2011 +0200
@@ -352,7 +352,7 @@
if objtype:
rql += ', %s is %s' % (selectvar, objtype)
rset = cursor.execute(rql)
- except:
+ except Exception:
print "could restrict eid_list with given constraints (%r)" % constraints
return []
return set(eid for eid, in rset.rows)
--- a/devtools/stresstester.py Fri Sep 23 09:17:37 2011 +0200
+++ b/devtools/stresstester.py Fri Sep 23 14:18:13 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -38,7 +38,7 @@
-o / --report-output <filename>
Write profiler report into <filename> rather than on stdout
-Copyright (c) 2003-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
+Copyright (c) 2003-2011 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
http://www.logilab.fr/ -- mailto:contact@logilab.fr
"""
@@ -73,9 +73,7 @@
start = clock()
try:
cursor.execute(query)
- except KeyboardInterrupt:
- raise
- except:
+ except Exception:
TB_LOCK.acquire()
traceback.print_exc()
TB_LOCK.release()
--- a/devtools/testlib.py Fri Sep 23 09:17:37 2011 +0200
+++ b/devtools/testlib.py Fri Sep 23 14:18:13 2011 +0200
@@ -233,7 +233,7 @@
# web resources
try:
config.global_set_option('embed-allowed', re.compile('.*'))
- except: # not in server only configuration
+ except Exception: # not in server only configuration
pass
#XXX this doesn't need to a be classmethod anymore
@@ -787,15 +787,13 @@
"""
try:
output = viewfunc(**kwargs)
- except (SystemExit, KeyboardInterrupt):
- raise
- except:
+ except Exception:
# hijack exception: generative tests stop when the exception
# is not an AssertionError
klass, exc, tcbk = sys.exc_info()
try:
msg = '[%s in %s] %s' % (klass, view.__regid__, exc)
- except:
+ except Exception:
msg = '[%s in %s] undisplayable exception' % (klass, view.__regid__)
raise AssertionError, msg, tcbk
return self._check_html(output, view, template)
@@ -837,9 +835,7 @@
def assertWellFormed(self, validator, content, context=None):
try:
return validator.parse_string(content)
- except (SystemExit, KeyboardInterrupt):
- raise
- except:
+ except Exception:
# hijack exception: generative tests stop when the exception
# is not an AssertionError
klass, exc, tcbk = sys.exc_info()
@@ -851,7 +847,7 @@
try:
str_exc = str(exc)
- except:
+ except Exception:
str_exc = 'undisplayable exception'
msg += str_exc
if content is not None:
@@ -1154,7 +1150,7 @@
reg._selected = {}
try:
orig_select_best = reg.__class__.__orig_select_best
- except:
+ except Exception:
orig_select_best = reg.__class__._select_best
def instr_select_best(self, *args, **kwargs):
selected = orig_select_best(self, *args, **kwargs)
--- a/doc/book/en/admin/pyro.rst Fri Sep 23 09:17:37 2011 +0200
+++ b/doc/book/en/admin/pyro.rst Fri Sep 23 14:18:13 2011 +0200
@@ -1,14 +1,19 @@
Working with a distributed client (using Pyro)
==============================================
+.. _UsingPyro:
+
In some circumstances, it is practical to split the repository and
-web-client parts of the application, for load-balancing reasons. Or
+web-client parts of the application for load-balancing reasons. Or
one wants to access the repository from independant scripts to consult
or update the database.
+Prerequisites
+-------------
+
For this to work, several steps have to be taken in order.
-You must first ensure that the apropriate software is installed and
+You must first ensure that the appropriate software is installed and
running (see ref:`setup`)::
pyro-nsd -x -p 6969
@@ -21,19 +26,40 @@
pyro-instance-id=myinstancename
-Finally, the client (for instance in the case of a script) must
-connect specifically, as in the following example code:
+Connect to the CubicWeb repository from a python script
+-------------------------------------------------------
+
+Assuming pyro-nsd is running and your instance is configured with ``pyro-server=yes``,
+you will be able to use :mod:`cubicweb.dbapi` api to initiate the connection.
+
+.. note::
+ Regardless of whether your instance is pyro activated or not, you can still
+ achieve this by using cubicweb-ctl shell scripts in a simpler way, as by default
+ it creates a repository 'in-memory' instead of connecting through pyro. That
+ also means you've to be on the host where the instance is running.
+
+Finally, the client (for instance a python script) must connect specifically
+as in the following example code:
.. sourcecode:: python
from cubicweb import dbapi
- def pyro_connect(instname, login, password, pyro_ns_host):
- cnx = dbapi.connect(instname, login, password, pyro_ns_host)
- cnx.load_appobjects()
- return cnx
+ cnx = dbapi.connect(database='instance-id', user='admin', password='admin')
+ cnx.load_appobjects()
+ cur = cnx.cursor()
+ for name in (u'Personal', u'Professional', u'Computers'):
+ cur.execute('INSERT Tag T: T name %(n)s', {'n': name})
+ cnx.commit()
-The 'cnx.load_appobjects()' line is optional. Without it you will get
-data through the connection roughly as you would from a DBAPI
-connection. With it, provided the cubicweb-client part is installed
-and accessible, you get the ORM goodies.
+Calling :meth:`cubicweb.dbapi.load_appobjects`, will populates The `cubicweb
+registries`_ with the application objects installed on the host where the script
+runs. You'll then be allowed to use the ORM goodies and custom entity methods and
+views. Of course this is optional, without it you can still get the repository
+data through the connection but in a roughly way: only RQL cursors will be
+available, e.g. you can't even build entity objects from the result set.
+
+
+
+.. _cubicweb registries: VRegistryIntro_
+
--- a/doc/book/en/annexes/faq.rst Fri Sep 23 09:17:37 2011 +0200
+++ b/doc/book/en/annexes/faq.rst Fri Sep 23 14:18:13 2011 +0200
@@ -148,25 +148,12 @@
to anonymous user, which will automatically execute what is
decribed above.
-How to load data from a script ?
---------------------------------
-
-The following script aims at loading data within a script assuming pyro-nsd is
-running and your instance is configured with ``pyro-server=yes``, otherwise
-you would not be able to use dbapi.
-
-.. sourcecode:: python
+How to load data from a python script ?
+---------------------------------------
+Please, refer to the `Pyro chapter`_.
- from cubicweb import dbapi
+.. _`Pyro chapter`: UsingPyro_
- cnx = dbapi.connect(database='instance-id', user='admin', password='admin')
- cur = cnx.cursor()
- for name in (u'Personal', u'Professional', u'Computers'):
- cur.execute('INSERT Tag T: T name %(n)s', {'n': name})
- cnx.commit()
-
-Wether your instance as pyro activated or not, you can still acheive this by
-using cubicweb-ctl shell scripts.
How to format an entity date attribute ?
----------------------------------------
--- a/doc/book/en/devweb/views/baseviews.rst Fri Sep 23 09:17:37 2011 +0200
+++ b/doc/book/en/devweb/views/baseviews.rst Fri Sep 23 14:18:13 2011 +0200
@@ -1,137 +1,17 @@
-.. -*- coding: utf-8 -*-
-
Base views
----------
-*CubicWeb* provides a lot of standard views, that can be found in
+|cubicweb| provides a lot of standard views, that can be found in
:mod:`cubicweb.web.views` sub-modules.
A certain number of views are used to build the web interface, which apply to one
-or more entities. As other appobject, Their identifier is what distinguish them
+or more entities. As other appobjects, their identifier is what distinguish them
from each others. The most generic ones, found in
:mod:`cubicweb.web.views.baseviews`, are described below.
-HTML views
-~~~~~~~~~~
-
-Special views
-`````````````
-
-*noresult*
- This view is the default view used when no result has been found
- (e.g. empty result set).
-
-*final*
- Display the value of a cell without trasnformation (in case of a non final
- entity, we see the eid). Applicable on any result set.
-
-.. note::
-
- `final` entities are merely attributes.
-
-*null*
- This view is the default view used when nothing needs to be rendered.
- It is always applicable.
-
-
-Entity views
-````````````
-
-*incontext, outofcontext*
-
- Those are used to display a link to an entity, whose label depends on the
- entity having to be displayed in or out of context (of another entity): some
- entities make sense in the context of another entity. For instance, the
- `Version` of a `Project` in forge. So one may expect that 'incontext' will
- be called when display a version from within the context of a project, while
- 'outofcontext"' will be called in other cases. In our example, the
- 'incontext' view of the version would be something like '0.1.2', while the
- 'outofcontext' view would include the project name, e.g. 'baz 0.1.2' (since
- only a version number without the associated project doesn't make sense if
- you don't know yet that you're talking about the famous 'baz' project. |cubicweb|
- tries to make guess and call 'incontext'/'outofcontext' nicely. When it can't
- know, the 'oneline' view should be used.
-
- By default it respectively produces the result of `textincontext` and
- `textoutofcontext` wrapped in a link leading to the primary view of the
- entity.
-
-
-*oneline*
-
- This view is used when we can't tell if the entity should be considered as
- displayed in or out of context. By default it produces the result of `text`
- in a link leading to the primary view of the entity.
+You'll probably want to customize one or more of the described views which are
+default, generic, implementations.
-List
-`````
-
-*list*
-
- This view displays a list of entities by creating a HTML list (`<ul>`) and
- call the view `listitem` for each entity of the result set. The 'list' view
- will generate html like:
-
- .. sourcecode:: html
-
- <ul class="section">
- <li>"result of 'subvid' view for a row</li>
- ...
- </ul>
-
-
-*simplelist*
-
- This view is not 'ul' based, and rely on div behaviour to separate items. html
- will look like
-
- .. sourcecode:: html
-
- <div class="section">"result of 'subvid' view for a row</div>
- ...
-
-
- It relies on base :class:`~cubicweb.view.View` class implementation of the
- :meth:`call` method to insert those <div>.
-
-
-*sameetypelist*
+.. automodule:: cubicweb.web.views.baseviews
- This view displays a list of entities of the same type, in HTML section
- (`<div>`) and call the view `sameetypelistitem` for each entity of the result
- set. It's designed to get a more adapted global list when displayed entities
- are all of the same type.
-
-
-*csv*
-
- This view displays each entity in a coma separated list. It is NOT related to
- the well-known text file format.
-
-
-Those list view can be given a 'subvid' arguments, telling the view to use of
-each item in the list. When not specified, the value of the 'redirect_vid'
-attribute of :class:`ListItemView` (for 'listview') or of :class:`SimpleListView`
-will be used. This default to 'outofcontext' for 'list' / 'incontext' for
-'simplelist'
-
-
-Text entity views
-~~~~~~~~~~~~~~~~~
-
-Basic html view have some variantsto be used when generating raw text, not html
-(for notifications for instance).
-
-*text*
-
- This is the simplest text view for an entity. By default it returns the
- result of the `.dc_title` method, which is cut to fit the
- `navigation.short-line-size` property if necessary.
-
-*textincontext, textoutofcontext*
-
- Similar to the `text` view, but called when an entity is considered out or in
- context (see description of incontext/outofcontext html views for more
- information on this). By default it returns respectively the result of the
- methods `.dc_title()` and `.dc_long_title()` of the entity.
--- a/doc/book/en/devweb/views/primary.rst Fri Sep 23 09:17:37 2011 +0200
+++ b/doc/book/en/devweb/views/primary.rst Fri Sep 23 14:18:13 2011 +0200
@@ -10,11 +10,11 @@
It is automatically selected on a one line result set containing an
entity.
-This view is supposed to render a maximum of informations about the
+It lives in the :mod:`cubicweb.web.views.primary` module.
+
+The *primary* view is supposed to render a maximum of informations about the
entity.
-It lives in the :mod:`cubicweb.web.views.primary` module.
-
.. _primary_view_layout:
Layout
@@ -139,8 +139,6 @@
that can't be done using rql for instance.
-
-
.. sourcecode:: python
pv_section = uicfg.primaryview_section
@@ -163,62 +161,8 @@
``tag_subject_of``. To avoid warnings during execution, they should be set to
``'*'``.
-Rendering methods and attributes
-````````````````````````````````
-The basic layout of a primary view is as in the
-:ref:`primary_view_layout` section. This layout is actually drawn by
-the `render_entity` method.
-
-The methods you may want to modify while customizing a ``PrimaryView``
-are:
-
-*render_entity_title(self, entity)*
- Renders the entity title, by default using entity's :meth:`dc_title()` method.
-
-*render_entity_attributes(self, entity)*
- Renders all attributes and relations in the 'attributes' section . The
- :attr:`skip_none` attribute controls the display of `None` valued attributes.
-
-*render_entity_relations(self, entity)*
- Renders all relations in the 'relations' section.
-
-*render_side_boxes(self, entity, boxes)*
- Renders side boxes on the right side of the content. This will generate a box
- for each relation in the 'sidebox' section, as well as explicit box
- appobjects selectable in this context.
-
-The placement of relations in the relations section or in side boxes
-can be controlled through the :ref:`primary_view_configuration` mechanism.
-
-*content_navigation_components(self, context)*
- This method is applicable only for entity type implementing the interface
- `IPrevNext`. This interface is for entities which can be linked to a previous
- and/or next entity. This method will render the navigation links between
- entities of this type, either at the top or at the bottom of the page
- given the context (navcontent{top|bottom}).
-
-Also, please note that by setting the following attributes in your
-subclass, you can already customize some of the rendering:
-
-*show_attr_label*
- Renders the attribute label next to the attribute value if set to `True`.
- Otherwise, does only display the attribute value.
-
-*show_rel_label*
- Renders the relation label next to the relation value if set to `True`.
- Otherwise, does only display the relation value.
-
-*skip_none*
- Does not render an attribute value that is None if set to `True`.
-
-*main_related_section*
- Renders the relations of the entity if set to `True`.
-
-A good practice is for you to identify the content of your entity type for which
-the default rendering does not answer your need so that you can focus on the specific
-method (from the list above) that needs to be modified. We do not advise you to
-overwrite ``render_entity`` unless you want a completely different layout.
+.. automodule:: cubicweb.web.views.primary
Example of customization and creation
@@ -329,3 +273,4 @@
.. image:: ../../images/lax-book_10-blog-with-two-entries_en.png
:alt: a blog and all its entries
+
--- a/doc/tools/pyjsrest.py Fri Sep 23 09:17:37 2011 +0200
+++ b/doc/tools/pyjsrest.py Fri Sep 23 14:18:13 2011 +0200
@@ -102,7 +102,7 @@
for fileid in INDEX_IN_ORDER:
try:
index.remove(fileid)
- except:
+ except Exception:
raise Exception(
'Bad file id %s referenced in INDEX_IN_ORDER in %s, '
'fix this please' % (fileid, __file__))
--- a/entities/adapters.py Fri Sep 23 09:17:37 2011 +0200
+++ b/entities/adapters.py Fri Sep 23 14:18:13 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2010-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -137,7 +137,7 @@
value = entity.printable_value(rschema, format='text/plain')
except TransformError:
continue
- except:
+ except Exception:
self.exception("can't add value of %s to text index for entity %s",
rschema, entity.eid)
continue
--- a/entities/authobjs.py Fri Sep 23 09:17:37 2011 +0200
+++ b/entities/authobjs.py Fri Sep 23 14:18:13 2011 +0200
@@ -82,7 +82,7 @@
prop = self._cw.execute(
'CWProperty X WHERE X pkey %(k)s, X for_user U, U eid %(u)s',
{'k': pkey, 'u': self.eid}).get_entity(0, 0)
- except:
+ except Exception:
kwargs = dict(pkey=unicode(pkey), value=value)
if self.is_in_group('managers'):
kwargs['for_user'] = self
--- a/etwist/server.py Fri Sep 23 09:17:37 2011 +0200
+++ b/etwist/server.py Fri Sep 23 14:18:13 2011 +0200
@@ -308,7 +308,7 @@
# so we deferred that part to the cubicweb thread
request.process_multipart()
return self._render_request(request)
- except:
+ except Exception:
errorstream = StringIO()
traceback.print_exc(file=errorstream)
return HTTPResponse(stream='<pre>%s</pre>' % errorstream.getvalue(),
--- a/ext/rest.py Fri Sep 23 09:17:37 2011 +0200
+++ b/ext/rest.py Fri Sep 23 14:18:13 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -71,7 +71,7 @@
try:
try:
eid_num, rest = text.split(u':', 1)
- except:
+ except ValueError:
eid_num, rest = text, '#'+text
eid_num = int(eid_num)
if eid_num < 0:
--- a/hooks/notification.py Fri Sep 23 09:17:37 2011 +0200
+++ b/hooks/notification.py Fri Sep 23 14:18:13 2011 +0200
@@ -191,7 +191,7 @@
def _call(self):
try:
title = self.entity.dc_title()
- except:
+ except Exception:
# may raise an error during deletion process, for instance due to
# missing required relation
title = '#%s' % self.entity.eid
--- a/hooks/syncschema.py Fri Sep 23 09:17:37 2011 +0200
+++ b/hooks/syncschema.py Fri Sep 23 14:18:13 2011 +0200
@@ -87,7 +87,7 @@
session.system_sql(str('ALTER TABLE %s ADD %s integer'
% (table, column)), rollback_on_failure=False)
session.info('added column %s to table %s', column, table)
- except:
+ except Exception:
# silent exception here, if this error has not been raised because the
# column already exists, index creation will fail anyway
session.exception('error while adding column %s to table %s',
@@ -221,8 +221,8 @@
cwuser_cls = self.session.vreg['etypes'].etype_class('CWUser')
for session in repo._sessions.values():
session.user.__class__ = cwuser_cls
- except:
- self.critical('error while setting schmea', exc_info=True)
+ except Exception:
+ self.critical('error while setting schema', exc_info=True)
def rollback_event(self):
self.precommit_event()
--- a/hooks/test/unittest_syncschema.py Fri Sep 23 09:17:37 2011 +0200
+++ b/hooks/test/unittest_syncschema.py Fri Sep 23 14:18:13 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -182,7 +182,7 @@
self.assertFalse(self.index_exists('State', 'state_of'))
rset = self.execute('Any X, Y WHERE X state_of Y')
self.assertEqual(len(rset), 2) # user states
- except:
+ except Exception:
import traceback
traceback.print_exc()
finally:
--- a/mail.py Fri Sep 23 09:17:37 2011 +0200
+++ b/mail.py Fri Sep 23 14:18:13 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -67,7 +67,7 @@
values = b64decode(str(values + '='*padding), '.-')
values = dict(v.split('=') for v in values.split('&'))
fromappid, host = qualif.split('.', 1)
- except:
+ except Exception:
return None
if appid != fromappid or host != gethostname():
return None
--- a/migration.py Fri Sep 23 09:17:37 2011 +0200
+++ b/migration.py Fri Sep 23 14:18:13 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -488,7 +488,7 @@
try:
oper, version = constraint.split()
self.reverse_dependencies[name].add( (oper, version, cube) )
- except:
+ except Exception:
self.warnings.append(
'cube %s depends on %s but constraint badly '
'formatted: %s' % (cube, name, constraint))
--- a/misc/cwdesklets/rqlsensor/__init__.py Fri Sep 23 09:17:37 2011 +0200
+++ b/misc/cwdesklets/rqlsensor/__init__.py Fri Sep 23 14:18:13 2011 +0200
@@ -15,9 +15,6 @@
#
# 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 webbrowser
reload(webbrowser)
@@ -89,7 +86,7 @@
cursor = cnx.cursor()
try:
rset = cursor.execute(rql)
- except:
+ except Exception:
del self._v_cnx
raise
self._urls = []
@@ -101,7 +98,7 @@
output.set('resultbg[%s]' % i, 'black')
try:
self._urls.append(base % 'Any X WHERE X eid %s' % line[0])
- except:
+ except Exception:
self._urls.append('')
i += 1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/migration/3.13.6_Any.py Fri Sep 23 14:18:13 2011 +0200
@@ -0,0 +1,1 @@
+sync_schema_props_perms('CWSourceSchemaConfig')
--- a/req.py Fri Sep 23 09:17:37 2011 +0200
+++ b/req.py Fri Sep 23 14:18:13 2011 +0200
@@ -66,7 +66,7 @@
self.vreg = vreg
try:
encoding = vreg.property_value('ui.encoding')
- except: # no vreg or property not registered
+ except Exception: # no vreg or property not registered
encoding = 'utf-8'
self.encoding = encoding
# cache result of execution for (rql expr / eids),
--- a/rqlrewrite.py Fri Sep 23 09:17:37 2011 +0200
+++ b/rqlrewrite.py Fri Sep 23 14:18:13 2011 +0200
@@ -337,43 +337,58 @@
"""introduce the given snippet in a subquery"""
subselect = stmts.Select()
snippetrqlst = n.Exists(transformedsnippet.copy(subselect))
+ get_rschema = self.schema.rschema
aliases = []
- rels_done = set()
- for i, (selectvar, snippetvar) in enumerate(varmap):
+ done = set()
+ for i, (selectvar, _) in enumerate(varmap):
+ need_null_test = False
subselectvar = subselect.get_variable(selectvar)
subselect.append_selected(n.VariableRef(subselectvar))
aliases.append(selectvar)
- vi = self.varinfos[i]
- need_null_test = False
- stinfo = vi['stinfo']
- for rel in stinfo['relations']:
- if rel in rels_done:
- continue
- rels_done.add(rel)
- rschema = self.schema.rschema(rel.r_type)
- if rschema.final or (rschema.inlined and
- not rel in stinfo['rhsrelations']):
- rel.children[0].name = selectvar # XXX explain why
- subselect.add_restriction(rel.copy(subselect))
- for vref in rel.children[1].iget_nodes(n.VariableRef):
- if isinstance(vref.variable, n.ColumnAlias):
- # XXX could probably be handled by generating the
- # subquery into the detected subquery
- raise BadSchemaDefinition(
- "cant insert security because of usage two inlined "
- "relations in this query. You should probably at "
- "least uninline %s" % rel.r_type)
- subselect.append_selected(vref.copy(subselect))
- aliases.append(vref.name)
- self.select.remove_node(rel)
- # when some inlined relation has to be copied in the
- # subquery, we need to test that either value is NULL or
- # that the snippet condition is satisfied
- if rschema.inlined and rel.optional:
- need_null_test = True
+ todo = [(selectvar, self.varinfos[i]['stinfo'])]
+ while todo:
+ varname, stinfo = todo.pop()
+ done.add(varname)
+ for rel in stinfo['relations'] - stinfo['rhsrelations']:
+ if rel in done:
+ continue
+ done.add(rel)
+ rschema = get_rschema(rel.r_type)
+ if rschema.final or rschema.inlined:
+ rel.children[0].name = varname # XXX explain why
+ subselect.add_restriction(rel.copy(subselect))
+ for vref in rel.children[1].iget_nodes(n.VariableRef):
+ if isinstance(vref.variable, n.ColumnAlias):
+ # XXX could probably be handled by generating the
+ # subquery into the detected subquery
+ raise BadSchemaDefinition(
+ "cant insert security because of usage two inlined "
+ "relations in this query. You should probably at "
+ "least uninline %s" % rel.r_type)
+ subselect.append_selected(vref.copy(subselect))
+ aliases.append(vref.name)
+ self.select.remove_node(rel)
+ # when some inlined relation has to be copied in the
+ # subquery and that relation is optional, we need to
+ # test that either value is NULL or that the snippet
+ # condition is satisfied
+ if varname == selectvar and rel.optional and rschema.inlined:
+ need_null_test = True
+ # also, if some attributes or inlined relation of the
+ # object variable are accessed, we need to get all those
+ # from the subquery as well
+ if vref.name not in done and rschema.inlined:
+ # we can use vref here define in above for loop
+ ostinfo = vref.variable.stinfo
+ for orel in ostinfo['relations'] - ostinfo['rhsrelations']:
+ orschema = get_rschema(orel.r_type)
+ if orschema.final or orschema.inlined:
+ todo.append( (vref.name, ostinfo) )
+ break
if need_null_test:
snippetrqlst = n.Or(
- n.make_relation(subselectvar, 'is', (None, None), n.Constant,
+ n.make_relation(subselect.get_variable(selectvar), 'is',
+ (None, None), n.Constant,
operator='='),
snippetrqlst)
subselect.add_restriction(snippetrqlst)
--- a/schemas/base.py Fri Sep 23 09:17:37 2011 +0200
+++ b/schemas/base.py Fri Sep 23 14:18:13 2011 +0200
@@ -306,7 +306,6 @@
class CWSourceSchemaConfig(EntityType):
__permissions__ = ENTITY_MANAGERS_PERMISSIONS
- __unique_together__ = [('cw_for_source', 'cw_schema')]
cw_for_source = SubjectRelation(
'CWSource', inlined=True, cardinality='1*', composite='object',
__permissions__=RELATION_MANAGERS_PERMISSIONS)
--- a/server/checkintegrity.py Fri Sep 23 09:17:37 2011 +0200
+++ b/server/checkintegrity.py Fri Sep 23 14:18:13 2011 +0200
@@ -47,7 +47,7 @@
sqlcursor.execute('SELECT type, source FROM entities WHERE eid=%s' % eid)
try:
etype, source = sqlcursor.fetchone()
- except:
+ except Exception:
eids[eid] = False
return False
if source and source != 'system':
@@ -58,7 +58,7 @@
{'x': eid}):
eids[eid] = True
return True
- except: # TypeResolverError, Unauthorized...
+ except Exception: # TypeResolverError, Unauthorized...
pass
eids[eid] = False
return False
--- a/server/migractions.py Fri Sep 23 09:17:37 2011 +0200
+++ b/server/migractions.py Fri Sep 23 14:18:13 2011 +0200
@@ -161,7 +161,7 @@
migrscript, funcname, *args, **kwargs)
except ExecutionError, err:
print >> sys.stderr, "-> %s" % err
- except:
+ except BaseException:
self.rollback()
raise
@@ -1374,7 +1374,7 @@
prop = self.rqlexec(
'CWProperty X WHERE X pkey %(k)s, NOT X for_user U',
{'k': pkey}, ask_confirm=False).get_entity(0, 0)
- except:
+ except Exception:
self.cmd_create_entity('CWProperty', pkey=unicode(pkey), value=value)
else:
prop.set_attributes(value=value)
@@ -1492,14 +1492,14 @@
if not ask_confirm or self.confirm('Execute sql: %s ?' % sql):
try:
cu = self.session.system_sql(sql, args)
- except:
+ except Exception:
ex = sys.exc_info()[1]
if self.confirm('Error: %s\nabort?' % ex, pdb=True):
raise
return
try:
return cu.fetchall()
- except:
+ except Exception:
# no result to fetch
return
--- a/server/msplanner.py Fri Sep 23 09:17:37 2011 +0200
+++ b/server/msplanner.py Fri Sep 23 14:18:13 2011 +0200
@@ -1640,7 +1640,7 @@
self._pending_vrefs = []
try:
res = self.visit_default(node, newroot, terms)[0]
- except:
+ except Exception:
# when a relation isn't supported, we should dereference potentially
# introduced variable refs
for vref in self._pending_vrefs:
--- a/server/pool.py Fri Sep 23 09:17:37 2011 +0200
+++ b/server/pool.py Fri Sep 23 14:18:13 2011 +0200
@@ -73,7 +73,7 @@
# catch exceptions, rollback other sources anyway
try:
cnx.rollback()
- except:
+ except Exception:
source.critical('rollback error', exc_info=sys.exc_info())
# error on rollback, the connection is much probably in a really
# bad state. Replace it by a new one.
@@ -86,12 +86,12 @@
for cu in self._cursors.values():
try:
cu.close()
- except:
+ except Exception:
continue
for _, cnx in self.source_cnxs.values():
try:
cnx.close()
- except:
+ except Exception:
continue
# internals ###############################################################
@@ -135,7 +135,7 @@
try:
# properly close existing connection if any
self.source_cnxs[source.uri][1].close()
- except:
+ except Exception:
pass
source.info('trying to reconnect')
self.source_cnxs[source.uri] = (source, source.get_connection())
--- a/server/repository.py Fri Sep 23 09:17:37 2011 +0200
+++ b/server/repository.py Fri Sep 23 14:18:13 2011 +0200
@@ -343,7 +343,7 @@
self.looping_task(cleanup_session_interval, self.clean_sessions)
assert isinstance(self._looping_tasks, list), 'already started'
for i, (interval, func, args) in enumerate(self._looping_tasks):
- self._looping_tasks[i] = task = utils.LoopTask(interval, func, args)
+ self._looping_tasks[i] = task = utils.LoopTask(self, interval, func, args)
self.info('starting task %s with interval %.2fs', task.name,
interval)
task.start()
@@ -412,7 +412,7 @@
cnxset = self._cnxsets_pool.get_nowait()
try:
cnxset.close(True)
- except:
+ except Exception:
self.exception('error while closing %s' % cnxset)
continue
if self.pyro_registered:
@@ -791,7 +791,7 @@
return session.commit()
except (ValidationError, Unauthorized):
raise
- except:
+ except Exception:
self.exception('unexpected error')
raise
@@ -802,7 +802,7 @@
session = self._get_session(sessionid)
session.set_tx_data(txid)
session.rollback()
- except:
+ except Exception:
self.exception('unexpected error')
raise
@@ -905,7 +905,7 @@
for sessionid in self._sessions.keys():
try:
self.close(sessionid, checkshuttingdown=False)
- except:
+ except Exception: # XXX BaseException?
self.exception('error while closing session %s' % sessionid)
def clean_sessions(self):
--- a/server/schemaserial.py Fri Sep 23 09:17:37 2011 +0200
+++ b/server/schemaserial.py Fri Sep 23 14:18:13 2011 +0200
@@ -135,7 +135,7 @@
try:
sqlexec('UPDATE deleted_entities SET type=%(n)s WHERE type=%(x)s',
{'x': etype, 'n': netype})
- except:
+ except Exception:
pass
tocleanup = [eid]
tocleanup += (eid for eid, cached in repo._type_source_cache.iteritems()
--- a/server/serverctl.py Fri Sep 23 09:17:37 2011 +0200
+++ b/server/serverctl.py Fri Sep 23 14:18:13 2011 +0200
@@ -248,7 +248,7 @@
cursor.execute, 'DROP USER %s' % user) is not ERROR:
print '-> user %s dropped.' % user
cnx.commit()
- except:
+ except BaseException:
cnx.rollback()
raise
@@ -363,7 +363,7 @@
createdb(helper, source, dbcnx, cursor)
dbcnx.commit()
print '-> database %s created.' % dbname
- except:
+ except BaseException:
dbcnx.rollback()
raise
cnx = system_source_cnx(source, special_privs='CREATE LANGUAGE',
--- a/server/session.py Fri Sep 23 09:17:37 2011 +0200
+++ b/server/session.py Fri Sep 23 14:18:13 2011 +0200
@@ -574,7 +574,7 @@
return self.DEFAULT_SECURITY
try:
return txstore.write_security
- except:
+ except AttributeError:
txstore.write_security = self.DEFAULT_SECURITY
return txstore.write_security
@@ -776,7 +776,7 @@
self._threaddata.ctx_count += 1
try:
cnxset.cnxset_set()
- except:
+ except Exception:
self._threaddata.cnxset = None
self.repo._free_cnxset(cnxset)
raise
@@ -970,7 +970,7 @@
operation.handle_event('precommit_event')
self.pending_operations[:] = processed
self.debug('precommit session %s done', self.id)
- except:
+ except BaseException:
# if error on [pre]commit:
#
# * set .failed = True on the operation causing the failure
@@ -985,7 +985,7 @@
for operation in reversed(processed):
try:
operation.handle_event('revertprecommit_event')
- except:
+ except BaseException:
self.critical('error while reverting precommit',
exc_info=True)
# XXX use slice notation since self.pending_operations is a
@@ -1000,7 +1000,7 @@
operation.processed = 'postcommit'
try:
operation.handle_event('postcommit_event')
- except:
+ except BaseException:
self.critical('error while postcommit',
exc_info=sys.exc_info())
self.debug('postcommit session %s done', self.id)
@@ -1031,7 +1031,7 @@
try:
operation = self.pending_operations.pop(0)
operation.handle_event('rollback_event')
- except:
+ except BaseException:
self.critical('rollback error', exc_info=sys.exc_info())
continue
cnxset.rollback()
--- a/server/sources/__init__.py Fri Sep 23 09:17:37 2011 +0200
+++ b/server/sources/__init__.py Fri Sep 23 14:18:13 2011 +0200
@@ -177,7 +177,7 @@
# cw < 3.10 bw compat
try:
processed['adapter'] = confdict['adapter']
- except:
+ except KeyError:
pass
# check for unknown options
if confdict and not confdict.keys() == ['adapter']:
--- a/server/sources/extlite.py Fri Sep 23 09:17:37 2011 +0200
+++ b/server/sources/extlite.py Fri Sep 23 14:18:13 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -296,7 +296,7 @@
try:
session.cnxset.connection(self.uri).rollback()
self.critical('transaction has been rollbacked')
- except:
+ except Exception:
pass
raise
return cursor
--- a/server/sources/ldapuser.py Fri Sep 23 09:17:37 2011 +0200
+++ b/server/sources/ldapuser.py Fri Sep 23 14:18:13 2011 +0200
@@ -273,7 +273,7 @@
if self._conn is None:
try:
self._connect()
- except:
+ except Exception:
self.exception('unable to connect to ldap:')
return ConnectionWrapper(self._conn)
@@ -570,7 +570,7 @@
try:
for i in range(len(value)):
value[i] = unicode(value[i], 'utf8')
- except:
+ except Exception:
pass
if isinstance(value, list) and len(value) == 1:
rec_dict[key] = value = value[0]
--- a/server/sources/native.py Fri Sep 23 09:17:37 2011 +0200
+++ b/server/sources/native.py Fri Sep 23 14:18:13 2011 +0200
@@ -413,7 +413,8 @@
self.init_creating(source_entity._cw.cnxset)
try:
# test if 'asource' column exists
- source_entity._cw.system_sql('SELECT asource FROM entities LIMIT 1')
+ query = self.dbhelper.sql_add_limit_offset('SELECT asource FROM entities', 1)
+ source_entity._cw.system_sql(query)
except Exception, ex:
self.eid_type_source = self.eid_type_source_pre_131
--- a/server/sources/pyrorql.py Fri Sep 23 09:17:37 2011 +0200
+++ b/server/sources/pyrorql.py Fri Sep 23 14:18:13 2011 +0200
@@ -226,7 +226,7 @@
self.cross_relations.remove(ertype)
else:
self.dont_cross_relations.remove(ertype)
- except:
+ except Exception:
self.error('while updating mapping consequently to removal of %s',
schemacfg)
@@ -275,7 +275,7 @@
entity = rset.get_entity(0, 0)
entity.complete(entity.e_schema.indexable_attributes())
source.index_entity(session, entity)
- except:
+ except Exception:
self.exception('while updating %s with external id %s of source %s',
etype, extid, self.uri)
continue
@@ -288,7 +288,7 @@
entity = session.entity_from_eid(eid, etype)
repo.delete_info(session, entity, self.uri, extid,
scleanup=self.eid)
- except:
+ except Exception:
self.exception('while updating %s with external id %s of source %s',
etype, extid, self.uri)
continue
@@ -667,7 +667,7 @@
value = const.eval(self.kwargs)
try:
return None, self._const_var[value]
- except:
+ except Exception:
var = self._varmaker.next()
self.need_translation = True
restr = '%s eid %s' % (var, self.visit_constant(const))
--- a/server/test/data/site_cubicweb.py Fri Sep 23 09:17:37 2011 +0200
+++ b/server/test/data/site_cubicweb.py Fri Sep 23 14:18:13 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -20,14 +20,10 @@
from logilab.database.sqlite import register_sqlite_pyfunc
from rql.utils import register_function
-try:
- class DUMB_SORT(FunctionDescr):
- pass
+class DUMB_SORT(FunctionDescr):
+ pass
- register_function(DUMB_SORT)
- def dumb_sort(something):
- return something
- register_sqlite_pyfunc(dumb_sort)
-except:
- # already registered
- pass
+register_function(DUMB_SORT)
+def dumb_sort(something):
+ return something
+register_sqlite_pyfunc(dumb_sort)
--- a/server/utils.py Fri Sep 23 09:17:37 2011 +0200
+++ b/server/utils.py Fri Sep 23 14:18:13 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -16,6 +16,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/>.
"""Some utilities for the CubicWeb server."""
+
__docformat__ = "restructuredtext en"
import sys
@@ -121,11 +122,12 @@
class LoopTask(object):
"""threaded task restarting itself once executed"""
- def __init__(self, interval, func, args):
+ def __init__(self, repo, interval, func, args):
if interval <= 0:
raise ValueError('Loop task interval must be > 0 '
'(current value: %f for %s)' % \
(interval, func_name(func)))
+ self.repo = repo
self.interval = interval
def auto_restart_func(self=self, func=func, args=args):
restart = True
@@ -138,7 +140,7 @@
except BaseException:
restart = False
finally:
- if restart:
+ if restart and not self.repo.shutting_down:
self.start()
self.func = auto_restart_func
self.name = func_name(func)
@@ -167,7 +169,7 @@
def auto_remove_func(self=self, func=target):
try:
func()
- except:
+ except Exception:
logger = logging.getLogger('cubicweb.repository')
logger.exception('Unhandled exception in RepoThread %s', self._name)
raise
--- a/sobjects/textparsers.py Fri Sep 23 09:17:37 2011 +0200
+++ b/sobjects/textparsers.py Fri Sep 23 14:18:13 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -83,7 +83,7 @@
trinfo = iworkflowable.fire_transition(tr)
caller.fire_event('state-changed', {'trinfo': trinfo,
'entity': entity})
- except:
+ except Exception:
self.exception('while changing state of %s', entity)
else:
self.error("can't pass transition %s on entity %s",
--- a/test/data/rewrite/schema.py Fri Sep 23 09:17:37 2011 +0200
+++ b/test/data/rewrite/schema.py Fri Sep 23 14:18:13 2011 +0200
@@ -63,3 +63,15 @@
object = 'Card'
inlined = True
cardinality = '?*'
+
+class inlined_note(RelationDefinition):
+ subject = 'Card'
+ object = 'Note'
+ inlined = True
+ cardinality = '?*'
+
+class inlined_affaire(RelationDefinition):
+ subject = 'Note'
+ object = 'Affaire'
+ inlined = True
+ cardinality = '?*'
--- a/test/unittest_rqlrewrite.py Fri Sep 23 09:17:37 2011 +0200
+++ b/test/unittest_rqlrewrite.py Fri Sep 23 14:18:13 2011 +0200
@@ -236,6 +236,18 @@
('A2', 'X'): (c2,),
}, {})
+ def test_optional_var_inlined_linked(self):
+ c1 = ('X require_permission P')
+ c2 = ('X inlined_card O, O require_permission P')
+ rqlst = parse('Any A,W WHERE A inlined_card C?, C inlined_note N, '
+ 'N inlined_affaire W')
+ rewrite(rqlst, {('C', 'X'): (c1,)}, {})
+ self.failUnlessEqual(rqlst.as_string(),
+ 'Any A,W WHERE A inlined_card C?, A is Affaire '
+ 'WITH C,N,W BEING (Any C,N,W WHERE C inlined_note N, '
+ 'N inlined_affaire W, EXISTS(C require_permission B), '
+ 'C is Card, N is Note, W is Affaire)')
+
def test_relation_optimization_1_lhs(self):
# since Card in_state State as monovalued cardinality, the in_state
# relation used in the rql expression can be ignored and S replaced by
@@ -246,6 +258,7 @@
self.assertEqual(rqlst.as_string(),
"Any C WHERE C in_state STATE, C is Card, "
"EXISTS(STATE name 'hop'), STATE is State")
+
def test_relation_optimization_1_rhs(self):
snippet = ('TW subworkflow_exit X, TW name "hop"')
rqlst = parse('WorkflowTransition C WHERE C subworkflow_exit EXIT')
--- a/uilib.py Fri Sep 23 09:17:37 2011 +0200
+++ b/uilib.py Fri Sep 23 14:18:13 2011 +0200
@@ -406,10 +406,10 @@
def exc_message(ex, encoding):
try:
return unicode(ex)
- except:
+ except Exception:
try:
return unicode(str(ex), encoding, 'replace')
- except:
+ except Exception:
return unicode(repr(ex), encoding, 'replace')
@@ -423,7 +423,7 @@
res.append(u'\n')
try:
res.append(u'\t Error: %s\n' % exception)
- except:
+ except Exception:
pass
return u'\n'.join(res)
--- a/view.py Fri Sep 23 09:17:37 2011 +0200
+++ b/view.py Fri Sep 23 14:18:13 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -174,7 +174,7 @@
stream = self.set_stream(w)
try:
view_func(**context)
- except:
+ except Exception:
self.debug('view call %s failed (context=%s)', view_func, context)
raise
# return stream content if we have created it
@@ -375,7 +375,19 @@
def call(self, **kwargs):
if self.cw_rset is None:
- self.entity_call(self.cw_extra_kwargs.pop('entity'))
+ # * cw_extra_kwargs is the place where extra selection arguments are
+ # stored
+ # * when calling req.view('somevid', entity=entity), 'entity' ends
+ # up in cw_extra_kwargs and kwargs
+ #
+ # handle that to avoid a TypeError with a sanity check
+ #
+ # Notice that could probably be avoided by handling entity_call in
+ # .render
+ entity = self.cw_extra_kwargs.pop('entity')
+ if 'entity' in kwargs:
+ assert kwargs.pop('entity') is entity
+ self.entity_call(entity, **kwargs)
else:
super(EntityView, self).call(**kwargs)
--- a/web/application.py Fri Sep 23 09:17:37 2011 +0200
+++ b/web/application.py Fri Sep 23 14:18:13 2011 +0200
@@ -423,7 +423,7 @@
if req.cnx and not commited:
try:
req.cnx.rollback()
- except:
+ except Exception:
pass # ignore rollback error at this point
self.info('query %s executed in %s sec', req.relative_path(), clock() - tstart)
return result
@@ -460,7 +460,7 @@
errview = self.vreg['views'].select('error', req)
template = self.main_template_id(req)
content = self.vreg['views'].main_template(req, template, view=errview)
- except:
+ except Exception:
content = self.vreg['views'].main_template(req, 'error-template')
raise StatusResponse(code, content)
--- a/web/captcha.py Fri Sep 23 09:17:37 2011 +0200
+++ b/web/captcha.py Fri Sep 23 14:18:13 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -17,8 +17,8 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""Simple captcha library, based on PIL. Monkey patch functions in this module
if you want something better...
+"""
-"""
__docformat__ = "restructuredtext en"
from random import randint, choice
--- a/web/data/cubicweb.ajax.js Fri Sep 23 09:17:37 2011 +0200
+++ b/web/data/cubicweb.ajax.js Fri Sep 23 14:18:13 2011 +0200
@@ -705,7 +705,7 @@
function setTab(tabname, cookiename) {
// set appropriate cookie
- loadRemote('json', ajaxFuncArgs('set_cookie', null, cookiename, tabname));
+ jQuery.cookie(cookiename, tabname, {path: '/'});
// trigger show + tabname event
triggerLoad(tabname);
}
--- a/web/data/cubicweb.js Fri Sep 23 09:17:37 2011 +0200
+++ b/web/data/cubicweb.js Fri Sep 23 14:18:13 2011 +0200
@@ -53,7 +53,13 @@
},
evalJSON: function (json) { // trust source
- return eval("(" + json + ")");
+ try {
+ return eval("(" + json + ")");
+ } catch(e) {
+ cw.log(e);
+ cw.log('The faulty json source was', json);
+ throw (e);
+ }
},
urlEncode: function (str) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/data/jquery.cookie.js Fri Sep 23 14:18:13 2011 +0200
@@ -0,0 +1,41 @@
+/**
+ * jQuery Cookie plugin
+ *
+ * Copyright (c) 2010 Klaus Hartl (stilbuero.de)
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ */
+jQuery.cookie = function (key, value, options) {
+
+ // key and at least value given, set cookie...
+ if (arguments.length > 1 && String(value) !== "[object Object]") {
+ options = jQuery.extend({}, options);
+
+ if (value === null || value === undefined) {
+ options.expires = -1;
+ }
+
+ if (typeof options.expires === 'number') {
+ var days = options.expires, t = options.expires = new Date();
+ t.setDate(t.getDate() + days);
+ }
+
+ value = String(value);
+
+ return (document.cookie = [
+ encodeURIComponent(key), '=',
+ options.raw ? value : encodeURIComponent(value),
+ options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
+ options.path ? '; path=' + options.path : '',
+ options.domain ? '; domain=' + options.domain : '',
+ options.secure ? '; secure' : ''
+ ].join(''));
+ }
+
+ // key and possibly options given, get cookie...
+ options = value || {};
+ var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent;
+ return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null;
+};
--- a/web/test/unittest_session.py Fri Sep 23 09:17:37 2011 +0200
+++ b/web/test/unittest_session.py Fri Sep 23 14:18:13 2011 +0200
@@ -2,7 +2,7 @@
"""unit tests for cubicweb.web.application
:organization: Logilab
-:copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
+:copyright: 2001-2011 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
--- a/web/test/unittest_viewselector.py Fri Sep 23 09:17:37 2011 +0200
+++ b/web/test/unittest_viewselector.py Fri Sep 23 14:18:13 2011 +0200
@@ -76,7 +76,7 @@
return
try:
self.assertSetEqual(content.keys(), expected)
- except:
+ except Exception:
print registry, sorted(expected), sorted(content.keys())
print 'no more', [v for v in expected if not v in content.keys()]
print 'missing', [v for v in content.keys() if not v in expected]
@@ -126,7 +126,6 @@
('rsetxml', xmlrss.XMLRsetView),
('rss', xmlrss.RSSView),
('sameetypelist', baseviews.SameETypeListView),
- ('secondary', baseviews.SecondaryView),
('security', management.SecurityManagementView),
('table', tableview.TableView),
('text', baseviews.TextView),
@@ -150,7 +149,6 @@
('rsetxml', xmlrss.XMLRsetView),
('rss', xmlrss.RSSView),
('sameetypelist', baseviews.SameETypeListView),
- ('secondary', baseviews.SecondaryView),
('security', management.SecurityManagementView),
('table', tableview.TableView),
('text', baseviews.TextView),
@@ -204,7 +202,6 @@
('primary', primary.PrimaryView),] + RDFVIEWS + [
('rsetxml', xmlrss.XMLRsetView),
('rss', xmlrss.RSSView),
- ('secondary', baseviews.SecondaryView),
('security', management.SecurityManagementView),
('table', tableview.TableView),
('text', baseviews.TextView),
@@ -240,7 +237,6 @@
('rsetxml', xmlrss.XMLRsetView),
('rss', xmlrss.RSSView),
('sameetypelist', baseviews.SameETypeListView),
- ('secondary', baseviews.SecondaryView),
('security', management.SecurityManagementView),
('table', tableview.TableView),
('text', baseviews.TextView),
@@ -468,7 +464,7 @@
try:
obj = self.vreg['views'].select(vid, req, rset=rset, **args)
return obj.render(**args)
- except:
+ except Exception:
print vid, rset, args
raise
--- a/web/uicfg.py Fri Sep 23 09:17:37 2011 +0200
+++ b/web/uicfg.py Fri Sep 23 14:18:13 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
--- a/web/views/autoform.py Fri Sep 23 09:17:37 2011 +0200
+++ b/web/views/autoform.py Fri Sep 23 14:18:13 2011 +0200
@@ -325,7 +325,7 @@
def _entity(self):
try:
cls = self._cw.vreg['etypes'].etype_class(self.etype)
- except:
+ except Exception:
self.w(self._cw._('no such entity type %s') % self.etype)
return
entity = cls(self._cw)
--- a/web/views/basecontrollers.py Fri Sep 23 09:17:37 2011 +0200
+++ b/web/views/basecontrollers.py Fri Sep 23 14:18:13 2011 +0200
@@ -23,6 +23,7 @@
_ = unicode
from logilab.common.date import strptime
+from logilab.common.deprecation import deprecated
from cubicweb import (NoSelectableObject, ObjectNotFound, ValidationError,
AuthenticationError, typed_eid)
@@ -546,8 +547,8 @@
self._cw.set_cookie(cookies, statename)
@jsonize
+ @deprecated("[3.13] use jQuery.cookie(cookiename, cookievalue, {path: '/'}) in js land instead")
def js_set_cookie(self, cookiename, cookievalue):
- # XXX we should consider jQuery.Cookie
cookiename, cookievalue = str(cookiename), str(cookievalue)
cookies = self._cw.get_cookie()
cookies[cookiename] = cookievalue
--- a/web/views/baseviews.py Fri Sep 23 09:17:37 2011 +0200
+++ b/web/views/baseviews.py Fri Sep 23 14:18:13 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -15,12 +15,64 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""Set of HTML generic base views:
+"""
+HTML views
+~~~~~~~~~~
+
+Special views
+`````````````
+
+.. autoclass:: NullView
+.. autoclass:: NoResultView
+.. autoclass:: FinalView
+
+
+Base entity views
+`````````````````
+
+.. autoclass:: InContextView
+.. autoclass:: OutOfContextView
+.. autoclass:: OneLineView
-* noresult, final
-* primary, sidebox
-* oneline, incontext, outofcontext, text
-* list
+Those are used to display a link to an entity, whose label depends on the entity
+having to be displayed in or out of context (of another entity): some entities
+make sense in the context of another entity. For instance, the `Version` of a
+`Project` in forge. So one may expect that 'incontext' will be called when
+display a version from within the context of a project, while 'outofcontext"'
+will be called in other cases. In our example, the 'incontext' view of the
+version would be something like '0.1.2', while the 'outofcontext' view would
+include the project name, e.g. 'baz 0.1.2' (since only a version number without
+the associated project doesn't make sense if you don't know yet that you're
+talking about the famous 'baz' project. |cubicweb| tries to make guess and call
+'incontext'/'outofcontext' nicely. When it can't know, the 'oneline' view should
+be used.
+
+
+List entity views
+`````````````````
+
+.. autoclass:: ListView
+.. autoclass:: SimpleListView
+.. autoclass:: SameETypeListView
+.. autoclass:: CSVView
+
+Those list views can be given a 'subvid' arguments, telling the view to use of
+each item in the list. When not specified, the value of the 'redirect_vid'
+attribute of :class:`ListItemView` (for 'listview') or of
+:class:`SimpleListView` will be used. This default to 'outofcontext' for 'list'
+/ 'incontext' for 'simplelist'
+
+
+Text entity views
+~~~~~~~~~~~~~~~~~
+
+Basic HTML view have some variants to be used when generating raw text, not HTML
+(for notifications for instance). Also, as explained above, some of the HTML
+views use those text views as a basis.
+
+.. autoclass:: TextView
+.. autoclass:: InContextTextView
+.. autoclass:: OutOfContextView
"""
__docformat__ = "restructuredtext en"
@@ -42,7 +94,12 @@
class NullView(AnyRsetView):
- """default view when no result has been found"""
+ """:__regid__: *null*
+
+ This view is the default view used when nothing needs to be rendered. It is
+ always applicable and is usually used as fallback view when calling
+ :meth:`_cw.view` to display nothing if the result set is empty.
+ """
__regid__ = 'null'
__select__ = yes()
def call(self, **kwargs):
@@ -51,9 +108,16 @@
class NoResultView(View):
- """default view when no result has been found"""
+ """:__regid__: *noresult*
+
+ This view is the default view to be used when no result has been found
+ (i.e. empty result set).
+
+ It's usually used as fallback view when calling :meth:`_cw.view` to display
+ "no results" if the result set is empty.
+ """
+ __regid__ = 'noresult'
__select__ = empty_rset()
- __regid__ = 'noresult'
def call(self, **kwargs):
self.w(u'<div class="searchMessage"><strong>%s</strong></div>\n'
@@ -61,8 +125,11 @@
class FinalView(AnyRsetView):
- """display values without any transformation (i.e. get a number for
- entities)
+ """:__regid__: *final*
+
+ Display the value of a result set cell with minimal transformations
+ (i.e. you'll get a number for entities). It is applicable on any result set,
+ though usually dedicated for cells containing an attribute's value.
"""
__regid__ = 'final'
# record generated i18n catalog messages
@@ -126,21 +193,51 @@
self.wdata(printable_value(self._cw, etype, value, props))
-# XXX deprecated
-class SecondaryView(EntityView):
- __regid__ = 'secondary'
- title = _('secondary')
+class InContextView(EntityView):
+ """:__regid__: *incontext*
+
+ This view is used whenthe entity should be considered as displayed in its
+ context. By default it produces the result of `textincontext` wrapped in a
+ link leading to the primary view of the entity.
+ """
+ __regid__ = 'incontext'
+
+ def cell_call(self, row, col):
+ entity = self.cw_rset.get_entity(row, col)
+ desc = cut(entity.dc_description(), 50)
+ self.w(u'<a href="%s" title="%s">' % (
+ xml_escape(entity.absolute_url()), xml_escape(desc)))
+ self.w(xml_escape(self._cw.view('textincontext', self.cw_rset,
+ row=row, col=col)))
+ self.w(u'</a>')
- def cell_call(self, row, col, **kwargs):
- """the secondary view for an entity
- secondary = icon + view(oneline)
- """
+
+class OutOfContextView(EntityView):
+ """:__regid__: *outofcontext*
+
+ This view is used whenthe entity should be considered as displayed out of
+ its context. By default it produces the result of `textoutofcontext` wrapped
+ in a link leading to the primary view of the entity.
+ """
+ __regid__ = 'outofcontext'
+
+ def cell_call(self, row, col):
entity = self.cw_rset.get_entity(row, col)
- self.w(u' ')
- self.wview('oneline', self.cw_rset, row=row, col=col)
+ desc = cut(entity.dc_description(), 50)
+ self.w(u'<a href="%s" title="%s">' % (
+ xml_escape(entity.absolute_url()), xml_escape(desc)))
+ self.w(xml_escape(self._cw.view('textoutofcontext', self.cw_rset,
+ row=row, col=col)))
+ self.w(u'</a>')
class OneLineView(EntityView):
+ """:__regid__: *oneline*
+
+ This view is used when we can't tell if the entity should be considered as
+ displayed in or out of context. By default it produces the result of the
+ `text` view in a link leading to the primary view of the entity.
+ """
__regid__ = 'oneline'
title = _('oneline')
@@ -153,18 +250,25 @@
self.w(u'</a>')
+# text views ###################################################################
+
class TextView(EntityView):
- """the simplest text view for an entity"""
+ """:__regid__: *text*
+
+ This is the simplest text view for an entity. By default it returns the
+ result of the entity's `dc_title()` method, which is cut to fit the
+ `navigation.short-line-size` property if necessary.
+ """
__regid__ = 'text'
title = _('text')
content_type = 'text/plain'
def call(self, **kwargs):
- """the view is called for an entire result set, by default loop
- other rows of the result set and call the same view on the
- particular row
+ """The view is called for an entire result set, by default loop other
+ rows of the result set and call the same view on the particular row.
- Views applicable on None result sets have to override this method
+ Subclasses views that are applicable on None result sets will have to
+ override this method.
"""
rset = self.cw_rset
if rset is None:
@@ -180,40 +284,14 @@
self._cw.property_value('navigation.short-line-size')))
-class MetaDataView(EntityView):
- """paragraph view of some metadata"""
- __regid__ = 'metadata'
- show_eid = True
+class InContextTextView(TextView):
+ """:__regid__: *textincontext*
- def cell_call(self, row, col):
- _ = self._cw._
- entity = self.cw_rset.get_entity(row, col)
- self.w(u'<div>')
- if self.show_eid:
- self.w(u'%s #%s - ' % (entity.dc_type(), entity.eid))
- if entity.modification_date != entity.creation_date:
- self.w(u'<span>%s</span> ' % _('latest update on'))
- self.w(u'<span class="value">%s</span>, '
- % self._cw.format_date(entity.modification_date))
- # entities from external source may not have a creation date (eg ldap)
- if entity.creation_date:
- self.w(u'<span>%s</span> ' % _('created on'))
- self.w(u'<span class="value">%s</span>'
- % self._cw.format_date(entity.creation_date))
- if entity.creator:
- if entity.creation_date:
- self.w(u' <span>%s</span> ' % _('by'))
- else:
- self.w(u' <span>%s</span> ' % _('created_by'))
- self.w(u'<span class="value">%s</span>' % entity.creator.name())
- meta = entity.cw_metainformation()
- if meta['source']['uri'] != 'system':
- self.w(u' (<span>%s</span>' % _('cw_source'))
- self.w(u' <span class="value">%s</span>)' % meta['source']['uri'])
- self.w(u'</div>')
-
-
-class InContextTextView(TextView):
+ Similar to the `text` view, but called when an entity is considered in
+ context (see description of incontext HTML view for more information on
+ this). By default it displays what's returned by the `dc_title()` method of
+ the entity.
+ """
__regid__ = 'textincontext'
title = None # not listed as a possible view
def cell_call(self, row, col):
@@ -222,6 +300,13 @@
class OutOfContextTextView(InContextTextView):
+ """:__regid__: *textoutofcontext*
+
+ Similar to the `text` view, but called when an entity is considered out of
+ context (see description of outofcontext HTML view for more information on
+ this). By default it displays what's returned by the `dc_long_title()`
+ method of the entity.
+ """
__regid__ = 'textoutofcontext'
def cell_call(self, row, col):
@@ -229,35 +314,26 @@
self.w(entity.dc_long_title())
-class InContextView(EntityView):
- __regid__ = 'incontext'
-
- def cell_call(self, row, col):
- entity = self.cw_rset.get_entity(row, col)
- desc = cut(entity.dc_description(), 50)
- self.w(u'<a href="%s" title="%s">' % (
- xml_escape(entity.absolute_url()), xml_escape(desc)))
- self.w(xml_escape(self._cw.view('textincontext', self.cw_rset,
- row=row, col=col)))
- self.w(u'</a>')
-
-
-class OutOfContextView(EntityView):
- __regid__ = 'outofcontext'
-
- def cell_call(self, row, col):
- entity = self.cw_rset.get_entity(row, col)
- desc = cut(entity.dc_description(), 50)
- self.w(u'<a href="%s" title="%s">' % (
- xml_escape(entity.absolute_url()), xml_escape(desc)))
- self.w(xml_escape(self._cw.view('textoutofcontext', self.cw_rset,
- row=row, col=col)))
- self.w(u'</a>')
-
-
# list views ##################################################################
class ListView(EntityView):
+ """:__regid__: *list*
+
+ This view displays a list of entities by creating a HTML list (`<ul>`) and
+ call the view `listitem` for each entity of the result set. The 'list' view
+ will generate HTML like:
+
+ .. sourcecode:: html
+
+ <ul class="section">
+ <li>"result of 'subvid' view for a row</li>
+ ...
+ </ul>
+
+ If you wish to use a different view for each entity, either subclass and
+ change the :attr:`item_vid` class attribute or specify a `subvid` argument
+ when calling this view.
+ """
__regid__ = 'list'
title = _('list')
item_vid = 'listitem'
@@ -312,7 +388,21 @@
class SimpleListView(ListItemView):
- """list without bullets"""
+ """:__regid__: *simplelist*
+
+ Similar to :class:~cubicweb.web.views.baseviews.ListView but using '<div>'
+ instead of '<ul>'. It rely on '<div>' behaviour to separate items. HTML will
+ look like
+
+ .. sourcecode:: html
+
+ <div class="section">"result of 'subvid' view for a row</div>
+ ...
+
+
+ It relies on base :class:`~cubicweb.view.View` class implementation of the
+ :meth:`call` method to insert those <div>.
+ """
__regid__ = 'simplelist'
redirect_vid = 'incontext'
@@ -330,8 +420,13 @@
class SameETypeListView(EntityView):
- """list of entities of the same type, when asked explicitly for same etype list
- view (for instance, display gallery if only images)
+ """:__regid__: *sameetypelist*
+
+ This view displays a list of entities of the same type, in HTML section
+ ('<div>') and call the view `sameetypelistitem` for each entity of the
+ result set. It's designed to get a more adapted global list when displayed
+ entities are all of the same type (for instance, display gallery if there
+ are only images entities).
"""
__regid__ = 'sameetypelist'
__select__ = EntityView.__select__ & one_etype_rset()
@@ -361,6 +456,11 @@
class CSVView(SimpleListView):
+ """:__regid__: *csv*
+
+ This view displays each entity in a coma separated list. It is NOT related
+ to the well-known text file format.
+ """
__regid__ = 'csv'
redirect_vid = 'incontext'
@@ -377,12 +477,48 @@
self.w(u", ")
+# XXX to be documented views ###################################################
+
+class MetaDataView(EntityView):
+ """paragraph view of some metadata"""
+ __regid__ = 'metadata'
+ show_eid = True
+
+ def cell_call(self, row, col):
+ _ = self._cw._
+ entity = self.cw_rset.get_entity(row, col)
+ self.w(u'<div>')
+ if self.show_eid:
+ self.w(u'%s #%s - ' % (entity.dc_type(), entity.eid))
+ if entity.modification_date != entity.creation_date:
+ self.w(u'<span>%s</span> ' % _('latest update on'))
+ self.w(u'<span class="value">%s</span>, '
+ % self._cw.format_date(entity.modification_date))
+ # entities from external source may not have a creation date (eg ldap)
+ if entity.creation_date:
+ self.w(u'<span>%s</span> ' % _('created on'))
+ self.w(u'<span class="value">%s</span>'
+ % self._cw.format_date(entity.creation_date))
+ if entity.creator:
+ if entity.creation_date:
+ self.w(u' <span>%s</span> ' % _('by'))
+ else:
+ self.w(u' <span>%s</span> ' % _('created_by'))
+ self.w(u'<span class="value">%s</span>' % entity.creator.name())
+ meta = entity.cw_metainformation()
+ if meta['source']['uri'] != 'system':
+ self.w(u' (<span>%s</span>' % _('cw_source'))
+ self.w(u' <span class="value">%s</span>)' % meta['source']['uri'])
+ self.w(u'</div>')
+
+
class TreeItemView(ListItemView):
__regid__ = 'treeitem'
def cell_call(self, row, col):
self.wview('incontext', self.cw_rset, row=row, col=col)
+
class TextSearchResultView(EntityView):
"""this view is used to display full-text search
@@ -405,7 +541,7 @@
value = xml_escape(entity.printable_value(attr, format='text/plain').lower())
except TransformError, ex:
continue
- except:
+ except Exception:
continue
if searched in value:
contexts = []
@@ -425,26 +561,6 @@
self.wview('oneline', self.cw_rset, row=row, col=col)
-# XXX bw compat
-
-from logilab.common.deprecation import class_moved
-
-try:
- from cubicweb.web.views.tableview import TableView
- TableView = class_moved(TableView)
-except ImportError:
- pass # gae has no tableview module (yet)
-
-from cubicweb.web.views import boxes, xmlrss, primary
-PrimaryView = class_moved(primary.PrimaryView)
-SideBoxView = class_moved(boxes.SideBoxView)
-XmlView = class_moved(xmlrss.XMLView)
-XmlItemView = class_moved(xmlrss.XMLItemView)
-XmlRsetView = class_moved(xmlrss.XMLRsetView)
-RssView = class_moved(xmlrss.RSSView)
-RssItemView = class_moved(xmlrss.RSSItemView)
-
-
class GroupByView(EntityView):
"""grouped view of a result set. The `group_key` method return the group
key of an entities (a string or tuple of string).
@@ -452,7 +568,7 @@
For each group, display a link to entities of this group by generating url
like <basepath>/<key> or <basepath>/<key item 1>/<key item 2>.
"""
- __abstrack__ = True
+ __abstract__ = True
__select__ = EntityView.__select__ & match_kwargs('basepath')
entity_attribute = None
reversed = False
@@ -550,3 +666,29 @@
url = self.index_url(basepath, key, vtitle=vtitle)
title = self._cw._('archive for %(author)s') % {'author': key}
return tags.a(label, href=url, title=title)
+
+
+# bw compat ####################################################################
+
+from logilab.common.deprecation import class_moved, class_deprecated
+
+from cubicweb.web.views import boxes, xmlrss, primary, tableview
+PrimaryView = class_moved(primary.PrimaryView)
+SideBoxView = class_moved(boxes.SideBoxView)
+XmlView = class_moved(xmlrss.XMLView)
+XmlItemView = class_moved(xmlrss.XMLItemView)
+XmlRsetView = class_moved(xmlrss.XMLRsetView)
+RssView = class_moved(xmlrss.RSSView)
+RssItemView = class_moved(xmlrss.RSSItemView)
+TableView = class_moved(tableview.TableView)
+
+
+class SecondaryView(EntityView):
+ __metaclass__ = class_deprecated
+ __deprecation_warning__ = '[3.9] the secondary view is deprecated, use one of oneline/incontext/outofcontext'
+ __regid__ = 'secondary'
+
+ def cell_call(self, row, col, **kwargs):
+ entity = self.cw_rset.get_entity(row, col)
+ self.w(u' ')
+ self.wview('oneline', self.cw_rset, row=row, col=col)
--- a/web/views/cwsources.py Fri Sep 23 09:17:37 2011 +0200
+++ b/web/views/cwsources.py Fri Sep 23 14:18:13 2011 +0200
@@ -24,27 +24,41 @@
from itertools import repeat, chain
+from cubicweb import Unauthorized
from cubicweb.selectors import is_instance, score_entity, match_user_groups
from cubicweb.view import EntityView, StartupView
from cubicweb.schema import META_RTYPES, VIRTUAL_RTYPES, display_name
from cubicweb.web import uicfg, formwidgets as wdgs
-from cubicweb.web.views import tabs, actions, add_etype_button
+from cubicweb.web.views import tabs, actions, ibreadcrumbs, add_etype_button
_abaa = uicfg.actionbox_appearsin_addmenu
+# there are explicit 'add' buttons for those
_abaa.tag_object_of(('CWSourceSchemaConfig', 'cw_schema', '*'), False)
_abaa.tag_object_of(('CWSourceSchemaConfig', 'cw_for_source', '*'), False)
+_abaa.tag_object_of(('CWSourceSchemaConfig', 'cw_host_config_of', '*'), False)
_afs = uicfg.autoform_section
_afs.tag_attribute(('CWSource', 'synchronizing'), 'main', 'hidden')
_afs.tag_object_of(('*', 'cw_for_source', 'CWSource'), 'main', 'hidden')
+
_affk = uicfg.autoform_field_kwargs
_affk.tag_attribute(('CWSource', 'parser'), {'widget': wdgs.TextInput})
# source primary views #########################################################
_pvs = uicfg.primaryview_section
+_pvs.tag_attribute(('CWSource', 'name'), 'hidden')
_pvs.tag_object_of(('*', 'cw_for_source', 'CWSource'), 'hidden')
+_pvs.tag_object_of(('*', 'cw_host_config_of', 'CWSource'), 'hidden')
+
+_pvdc = uicfg.primaryview_display_ctrl
+_pvdc.tag_attribute(('CWSource', 'type'), {'vid': 'attribute'})# disable reledit
+
+_rc = uicfg.reledit_ctrl
+_rc.tag_attribute(('CWSource', 'config'), {'rvid': 'verbatim'})
+_rc.tag_attribute(('CWSourceHostConfig', 'config'), {'rvid': 'verbatim'})
+_rc.tag_attribute(('CWSourceSchemaConfig', 'options'), {'rvid': 'verbatim'})
class CWSourcePrimaryView(tabs.TabbedPrimaryView):
@@ -57,6 +71,23 @@
__regid__ = 'cwsource-main'
__select__ = tabs.PrimaryTab.__select__ & is_instance('CWSource')
+ def render_entity_attributes(self, entity):
+ super(CWSourceMainTab, self).render_entity_attributes(entity)
+ self.w(add_etype_button(self._cw, 'CWSourceHostConfig',
+ __linkto='cw_host_config_of:%s:subject' % entity.eid,
+ __redirectpath=entity.rest_path()))
+ try:
+ hostconfig = self._cw.execute(
+ 'Any X, XC, XH WHERE X cw_host_config_of S, S eid %(s)s, '
+ 'X config XC, X match_host XH', {'s': entity.eid})
+ except Unauthorized:
+ pass
+ else:
+ if hostconfig:
+ self.w(u'<h3>%s</h3>' % self._cw._('CWSourceHostConfig_plural'))
+ self._cw.view('editable-table', hostconfig,
+ displaycols=range(2), w=self.w)
+
MAPPED_SOURCE_TYPES = set( ('pyrorql', 'datafeed') )
@@ -239,3 +270,11 @@
self._cw._('add a CWSource')))
self.w(u'<div class="clear"></div>')
self.wview('table', self._cw.execute(self.rql), displaycols=range(4))
+
+
+# breadcrumbs configuration ####################################################
+
+class CWsourceConfigIBreadCrumbsAdapter(ibreadcrumbs.IBreadCrumbsAdapter):
+ __select__ = is_instance('CWSourceHostConfig', 'CWSourceSchemaConfig')
+ def parent_entity(self):
+ return self.entity.cwsource
--- a/web/views/facets.py Fri Sep 23 09:17:37 2011 +0200
+++ b/web/views/facets.py Fri Sep 23 14:18:13 2011 +0200
@@ -207,6 +207,7 @@
__regid__ = 'facet.filtertable'
__select__ = has_facets()
wdg_stack_size = 8
+ compact_layout_threshold = 5
def call(self, vid, divid, vidargs, cssclass=''):
self.generate_form(self.w, self.cw_rset, divid, vid, vidargs,
@@ -214,10 +215,23 @@
# divid=divid XXX
)
+ def _simple_horizontal_layout(self, w, wdgs):
+ w(u'<table class="filter">\n')
+ w(u'<tr>\n')
+ for wdg in wdgs:
+ w(u'<td>')
+ wdg.render(w=w)
+ w(u'</td>')
+ w(u'</tr>\n')
+ w(u'</table>\n')
+
def layout_widgets(self, w, wdgs):
"""layout widgets: put them in a table where each column should have
sum(wdg.height()) < wdg_stack_size.
"""
+ if len(wdgs) < self.compact_layout_threshold:
+ self._simple_horizontal_layout(w, wdgs)
+ return
w(u'<table class="filter">\n')
widget_queue = []
queue_height = 0
--- a/web/views/forms.py Fri Sep 23 09:17:37 2011 +0200
+++ b/web/views/forms.py Fri Sep 23 14:18:13 2011 +0200
@@ -277,7 +277,7 @@
for editedfield in splitstrip(editedfields):
try:
name, role = editedfield.split('-')
- except:
+ except Exception:
name = editedfield
role = None
if entityform:
--- a/web/views/idownloadable.py Fri Sep 23 09:17:37 2011 +0200
+++ b/web/views/idownloadable.py Fri Sep 23 14:18:13 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -75,7 +75,7 @@
class DownloadView(EntityView):
"""download view
-
+
this view is replacing the deprecated 'download' controller and allow
downloading of entities providing the necessary interface
"""
--- a/web/views/magicsearch.py Fri Sep 23 09:17:37 2011 +0200
+++ b/web/views/magicsearch.py Fri Sep 23 14:18:13 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -387,7 +387,7 @@
procname, query = uquery.split(':', 1)
proc = self.by_name[procname.strip().lower()]
uquery = query.strip()
- except:
+ except Exception:
# use processor chain
unauthorized = None
for proc in self.processors:
--- a/web/views/primary.py Fri Sep 23 09:17:37 2011 +0200
+++ b/web/views/primary.py Fri Sep 23 14:18:13 2011 +0200
@@ -15,7 +15,26 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""The default primary view"""
+"""
+Public API of the PrimaryView class
+````````````````````````````````````
+.. autoclass:: cubicweb.web.views.primary.PrimaryView
+
+Views that may be used to display an entity's attribute or relation
+```````````````````````````````````````````````````````````````````
+
+Yoy may easily the display of an attribute or relation by simply configuring the
+view using one of `primaryview_display_ctrl` or `reledit_ctrl` to use one of the
+views describled below. For instance:
+
+.. sourcecode:: python
+
+ primaryview_display_ctrl.tag_attribute(('Foo', 'bar'), {'vid': 'attribute'})
+
+
+.. autoclass:: AttributeView
+.. autoclass:: URLAttributeView
+"""
__docformat__ = "restructuredtext en"
_ = unicode
@@ -34,7 +53,47 @@
class PrimaryView(EntityView):
- """the full view of an non final entity"""
+ """
+ The basic layout of a primary view is as in the :ref:`primary_view_layout`
+ section. This layout is actually drawn by the `render_entity` method.
+
+ The methods you may want to modify while customizing a ``PrimaryView``
+ are:
+
+ .. automethod:: cubicweb.web.views.primary.PrimaryView.render_entity_title
+ .. automethod:: cubicweb.web.views.primary.PrimaryView.render_entity_attributes
+ .. automethod:: cubicweb.web.views.primary.PrimaryView.render_entity_relations
+ .. automethod:: cubicweb.web.views.primary.PrimaryView.render_side_boxes
+
+ The placement of relations in the relations section or in side boxes
+ can be controlled through the :ref:`primary_view_configuration` mechanism.
+
+ .. automethod:: cubicweb.web.views.primary.PrimaryView.content_navigation_components
+
+ Also, please note that by setting the following attributes in your
+ subclass, you can already customize some of the rendering:
+
+ :attr:`show_attr_label`
+ Renders the attribute label next to the attribute value if set to `True`.
+ Otherwise, does only display the attribute value.
+
+ :attr:`show_rel_label`
+ Renders the relation label next to the relation value if set to `True`.
+ Otherwise, does only display the relation value.
+
+ :attr:`skip_none`
+ Does not render an attribute value that is None if set to `True`.
+
+ :attr:`main_related_section`
+ Renders the relations of the entity if set to `True`.
+
+ A good practice is for you to identify the content of your entity type for
+ which the default rendering does not answer your need so that you can focus
+ on the specific method (from the list above) that needs to be modified. We
+ do not advise you to overwrite ``render_entity`` unless you want a
+ completely different layout.
+ """
+
__regid__ = 'primary'
title = _('primary')
show_attr_label = True
@@ -95,6 +154,12 @@
self.w(u'</td></tr></table>')
def content_navigation_components(self, context):
+ """This method is applicable only for entity type implementing the
+ interface `IPrevNext`. This interface is for entities which can be
+ linked to a previous and/or next entity. This method will render the
+ navigation links between entities of this type, either at the top or at
+ the bottom of the page given the context (navcontent{top|bottom}).
+ """
self.w(u'<div class="%s">' % context)
for comp in self._cw.vreg['ctxcomponents'].poss_visible_objects(
self._cw, rset=self.cw_rset, view=self, context=context):
@@ -106,7 +171,9 @@
self.w(u'</div>')
def render_entity_title(self, entity):
- """default implementation return dc_title"""
+ """Renders the entity title, by default using entity's
+ :meth:`dc_title()` method.
+ """
title = xml_escape(entity.dc_title())
if title:
if self.is_primary():
@@ -128,6 +195,10 @@
return u''
def render_entity_attributes(self, entity):
+ """Renders all attributes and relations in the 'attributes' section. The
+ :attr:`skip_none` attribute controls the display of `None` valued
+ attributes.
+ """
display_attributes = []
for rschema, _, role, dispctrl in self._section_def(entity, 'attributes'):
vid = dispctrl.get('vid', 'reledit')
@@ -165,6 +236,7 @@
self.field(label, value, tr=False, table=table)
def render_entity_relations(self, entity):
+ """Renders all relations in the 'relations' section."""
for rschema, tschemas, role, dispctrl in self._section_def(entity, 'relations'):
if rschema.final or dispctrl.get('rtypevid'):
vid = dispctrl.get('vid', 'reledit')
@@ -212,8 +284,9 @@
self.w(u'</div>')
def render_side_boxes(self, boxes):
- """display side related relations:
- non-meta in a first step, meta in a second step
+ """Renders side boxes on the right side of the content. This will
+ generate a box for each relation in the 'sidebox' section, as well as
+ explicit box appobjects selectable in this context.
"""
for box in boxes:
if isinstance(box, tuple):
@@ -305,6 +378,8 @@
It will try to display nicely according to the number of items in the result
set.
+
+ XXX include me in the doc
"""
__regid__ = 'autolimited'
@@ -347,31 +422,29 @@
class URLAttributeView(EntityView):
- """use this view for attributes whose value is an url and that you want
- to display as clickable link
+ """:__regid__: *urlattr*
+
+ This view will wrap an attribute value (hence expect a string) into an '<a>'
+ HTML tag to display a clickable link.
"""
__regid__ = 'urlattr'
__select__ = EntityView.__select__ & match_kwargs('rtype')
- def cell_call(self, row, col, rtype, **kwargs):
- entity = self.cw_rset.get_entity(row, col)
+ def entity_call(self, entity, rtype, **kwargs):
url = entity.printable_value(rtype)
if url:
self.w(u'<a href="%s">%s</a>' % (url, url))
class AttributeView(EntityView):
- """use this view on an entity as an alternative to more sophisticated
- views such as reledit.
+ """:__regid__: *attribute*
- Ex. usage:
-
- uicfg.primaryview_display_ctrl.tag_attribute(('Foo', 'bar'), {'vid': 'attribute'})
+ This view is generally used to disable the *reledit* feature. It works on
+ both relations and attributes.
"""
__regid__ = 'attribute'
__select__ = EntityView.__select__ & match_kwargs('rtype')
- def cell_call(self, row, col, rtype, role, **kwargs):
- entity = self.cw_rset.get_entity(row, col)
+ def entity_call(self, entity, rtype, **kwargs):
if self._cw.vreg.schema.rschema(rtype).final:
self.w(entity.printable_value(rtype))
else:
@@ -384,12 +457,14 @@
class ToolbarLayout(component.Layout):
+ # XXX include me in the doc
__select__ = match_context('ctxtoolbar')
def render(self, w):
if self.init_rendering():
self.cw_extra_kwargs['view'].render_body(w)
+
## default primary ui configuration ###########################################
_pvs = uicfg.primaryview_section
--- a/web/views/reledit.py Fri Sep 23 09:17:37 2011 +0200
+++ b/web/views/reledit.py Fri Sep 23 14:18:13 2011 +0200
@@ -104,7 +104,11 @@
self._handle_relation(rschema, role, divid, reload, formid, action)
def _handle_attribute(self, rschema, role, divid, reload, action):
- value = self.entity.printable_value(rschema.type)
+ rvid = self._rules.get('rvid', None)
+ if rvid is not None:
+ value = self._cw.view(rvid, entity=self.entity, rtype=rschema.type)
+ else:
+ value = self.entity.printable_value(rschema.type)
if not self._should_edit_attribute(rschema):
self.w(value)
return
--- a/web/views/schema.py Fri Sep 23 09:17:37 2011 +0200
+++ b/web/views/schema.py Fri Sep 23 14:18:13 2011 +0200
@@ -102,7 +102,7 @@
# XXX get group entity and call it's incontext view
groups = [u'<a class="%s" href="%s">%s</a>' % (
group, self._cw.build_url('cwgroup/%s' % group), label)
- for group, label in sorted((_(g), g) for g in groups)]
+ for label, group in sorted((_(g), g) for g in groups)]
w(u'<br/>'.join(groups))
w(u'</td><td>')
w(u'<br/>'.join(rqlexprs))
--- a/web/views/sessions.py Fri Sep 23 09:17:37 2011 +0200
+++ b/web/views/sessions.py Fri Sep 23 14:18:13 2011 +0200
@@ -21,7 +21,8 @@
__docformat__ = "restructuredtext en"
-from cubicweb import RepositoryError, Unauthorized, AuthenticationError
+from cubicweb import (RepositoryError, Unauthorized, AuthenticationError,
+ BadConnectionId)
from cubicweb.web import InvalidSession, Redirect
from cubicweb.web.application import AbstractSessionManager
from cubicweb.dbapi import DBAPISession
@@ -119,7 +120,7 @@
req.cnx.commit()
except (RepositoryError, Unauthorized):
req.cnx.rollback()
- except:
+ except Exception:
req.cnx.rollback()
raise
@@ -132,8 +133,6 @@
if session.cnx:
try:
session.cnx.close()
- except:
- # already closed, may occur if the repository session expired
- # but not the web session
+ except BadConnectionId: # expired on the repository side
pass
session.cnx = None
--- a/web/views/tableview.py Fri Sep 23 09:17:37 2011 +0200
+++ b/web/views/tableview.py Fri Sep 23 14:18:13 2011 +0200
@@ -42,6 +42,9 @@
title = _('table')
finalview = 'final'
+ table_widget_class = TableWidget
+ table_column_class = TableColumn
+
def form_filter(self, divid, displaycols, displayactions, displayfilter,
paginate, hidden=True):
try:
@@ -144,7 +147,7 @@
if paginate:
self.divid = divid # XXX iirk (see usage in page_navigation_url)
self.paginate(page_size=page_size, show_all_option=False)
- table = TableWidget(self)
+ table = self.table_widget_class(self)
for column in self.get_columns(computed_labels, displaycols, headers,
subvid, cellvids, cellattrs, mainindex):
table.append_column(column)
@@ -197,7 +200,7 @@
label = _label
if colindex == mainindex and label is not None:
label += ' (%s)' % self.cw_rset.rowcount
- column = TableColumn(label, colindex)
+ column = self.table_column_class(label, colindex)
coltype = self.cw_rset.description[0][colindex]
# compute column cell view (if coltype is None, it's a left outer
# join, use the default non final subvid)
@@ -259,14 +262,17 @@
:param cellvid: cell view (defaults to 'outofcontext')
"""
etype, val = self.cw_rset.description[row][col], self.cw_rset[row][col]
- if val is not None and etype is not None and not self._cw.vreg.schema.eschema(etype).final:
- self.wview(cellvid or 'outofcontext', self.cw_rset, row=row, col=col)
- elif val is None:
- # This is usually caused by a left outer join and in that case,
- # regular views will most certainly fail if they don't have
- # a real eid
- self.wview('final', self.cw_rset, row=row, col=col)
+ if etype is None or not self._cw.vreg.schema.eschema(etype).final:
+ if val is None:
+ # This is usually caused by a left outer join and in that case,
+ # regular views will most certainly fail if they don't have
+ # a real eid
+ # XXX if cellvid is e.g. reledit, we may wanna call it anyway
+ self.w(u' ')
+ else:
+ self.wview(cellvid or 'outofcontext', self.cw_rset, row=row, col=col)
else:
+ # XXX why do we need a fallback view here?
self.wview(cellvid or 'final', self.cw_rset, 'null', row=row, col=col)
--- a/web/views/tabs.py Fri Sep 23 09:17:37 2011 +0200
+++ b/web/views/tabs.py Fri Sep 23 14:18:13 2011 +0200
@@ -128,7 +128,7 @@
entity.view(default, w=self.w)
return
self._cw.add_css('jquery.ui.css')
- self._cw.add_js(('jquery.ui.js', 'cubicweb.ajax.js'))
+ self._cw.add_js(('jquery.ui.js', 'cubicweb.ajax.js', 'jquery.cookie.js'))
# prune tabs : not all are to be shown
tabs, active_tab = self.prune_tabs(tabs, default)
# build the html structure
@@ -140,9 +140,7 @@
for i, (tabid, domid, tabkwargs) in enumerate(tabs):
w(u'<li>')
w(u'<a href="#%s">' % domid)
- w(u'<span onclick="%s">' % xml_escape(unicode(uilib.js.setTab(domid, self.cookie_name))))
w(tabkwargs.pop('label', self._cw._(tabid)))
- w(u'</span>')
w(u'</a>')
w(u'</li>')
if domid == active_tab:
@@ -160,7 +158,12 @@
# because the callback binding needs to be done before
# XXX make work history: true
self._cw.add_onload(u"""
- jQuery('#entity-tabs-%(eeid)s').tabs( { selected: %(tabindex)s });
+ jQuery('#entity-tabs-%(eeid)s').tabs(
+ { selected: %(tabindex)s,
+ select: function(event, ui) {
+ setTab(ui.panel.id, '%(cookiename)s');
+ }
+ });
setTab('%(domid)s', '%(cookiename)s');
""" % {'tabindex' : active_tab_idx,
'domid' : active_tab,
--- a/wsgi/__init__.py Fri Sep 23 09:17:37 2011 +0200
+++ b/wsgi/__init__.py Fri Sep 23 14:18:13 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -37,7 +37,7 @@
"""pretty prints `obj` if possible"""
try:
return _pformat(obj)
- except:
+ except Exception:
return u'<could not parse>'
def qs2dict(qs):