--- a/__init__.py Fri May 29 16:11:49 2009 +0200
+++ b/__init__.py Fri May 29 20:22:39 2009 +0200
@@ -2,7 +2,7 @@
relations between entitites.
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
:license: Library General Public License version 2 - http://www.gnu.org/licenses
"""
--- a/__pkginfo__.py Fri May 29 16:11:49 2009 +0200
+++ b/__pkginfo__.py Fri May 29 20:22:39 2009 +0200
@@ -1,6 +1,7 @@
# pylint: disable-msg=W0622,C0103
"""cubicweb global packaging information for the cubicweb knowledge management
software
+:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
distname = "cubicweb"
--- a/_exceptions.py Fri May 29 16:11:49 2009 +0200
+++ b/_exceptions.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/appobject.py Fri May 29 16:11:49 2009 +0200
+++ b/appobject.py Fri May 29 20:22:39 2009 +0200
@@ -1,12 +1,13 @@
"""Base class for dynamically loaded objects manipulated in the web interface
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
-from datetime import datetime, timedelta
+from datetime import datetime, timedelta, time
from logilab.common.decorators import classproperty
from logilab.common.deprecation import obsolete
@@ -17,7 +18,7 @@
from cubicweb import Unauthorized, NoSelectableObject
from cubicweb.vregistry import VObject, AndSelector
from cubicweb.selectors import yes
-from cubicweb.utils import UStringIO, ustrftime
+from cubicweb.utils import UStringIO, ustrftime, strptime, todate, todatetime
ONESECOND = timedelta(0, 1, 0)
@@ -187,14 +188,8 @@
return rql
def view(self, __vid, rset=None, __fallback_vid=None, **kwargs):
- """shortcut to self.vreg.render method avoiding to pass self.req"""
- try:
- view = self.vreg.select_view(__vid, self.req, rset, **kwargs)
- except NoSelectableObject:
- if __fallback_vid is None:
- raise
- view = self.vreg.select_view(__fallback_vid, self.req, rset, **kwargs)
- return view.render(**kwargs)
+ """shortcut to self.vreg.view method avoiding to pass self.req"""
+ return self.vreg.view(__vid, self.req, rset, __fallback_vid, **kwargs)
def initialize_varmaker(self):
varmaker = self.req.get_page_data('rql_varmaker')
@@ -300,6 +295,35 @@
return self.req.property_value('ui.float-format') % num
return u''
+ def parse_datetime(self, value, etype='Datetime'):
+ """get a datetime or time from a string (according to etype)
+ Datetime formatted as Date are accepted
+ """
+ assert etype in ('Datetime', 'Date', 'Time'), etype
+ # XXX raise proper validation error
+ if etype == 'Datetime':
+ format = self.req.property_value('ui.datetime-format')
+ try:
+ return todatetime(strptime(value, format))
+ except ValueError:
+ pass
+ elif etype == 'Time':
+ format = self.req.property_value('ui.time-format')
+ try:
+ # (adim) I can't find a way to parse a Time with a custom format
+ date = strptime(value, format) # this returns a DateTime
+ return time(date.hour, date.minute, date.second)
+ except ValueError:
+ raise ValueError('can\'t parse %r (expected %s)' % (value, format))
+ try:
+ format = self.req.property_value('ui.date-format')
+ dt = strptime(value, format)
+ if etype == 'Datetime':
+ return todatetime(dt)
+ return todate(dt)
+ except ValueError:
+ raise ValueError('can\'t parse %r (expected %s)' % (value, format))
+
# security related methods ################################################
def ensure_ro_rql(self, rql):
--- a/common/__init__.py Fri May 29 16:11:49 2009 +0200
+++ b/common/__init__.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
hg stserver side and on the client side
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
from logilab.common.adbh import FunctionDescr
--- a/common/appobject.py Fri May 29 16:11:49 2009 +0200
+++ b/common/appobject.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""pre 3.2 bw compat"""
+"""pre 3.2 bw compat
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
# pylint: disable-msg=W0614,W0401
from warnings import warn
warn('moved to cubicweb.appobject', DeprecationWarning, stacklevel=2)
--- a/common/entity.py Fri May 29 16:11:49 2009 +0200
+++ b/common/entity.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""pre 3.2 bw compat"""
+"""pre 3.2 bw compat
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
# pylint: disable-msg=W0614,W0401
from warnings import warn
warn('moved to cubicweb.entity', DeprecationWarning, stacklevel=2)
--- a/common/i18n.py Fri May 29 16:11:49 2009 +0200
+++ b/common/i18n.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Some i18n/gettext utilities.
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/common/mail.py Fri May 29 16:11:49 2009 +0200
+++ b/common/mail.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Common utilies to format / semd emails.
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/common/migration.py Fri May 29 16:11:49 2009 +0200
+++ b/common/migration.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
version
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/common/mixins.py Fri May 29 16:11:49 2009 +0200
+++ b/common/mixins.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
@@ -236,8 +237,8 @@
@obsolete('use EntityFieldsForm.subject_in_state_vocabulary')
def subject_in_state_vocabulary(self, rschema, limit=None):
- from cubicweb.web.form import EntityFieldsForm
- return EntityFieldsForm(self.req, None, entity=self).subject_in_state_vocabulary(rschema, limit)
+ form = self.vreg.select_object('forms', 'edition', self.req, entity=self)
+ return form.subject_in_state_vocabulary(rschema, limit)
--- a/common/mttransforms.py Fri May 29 16:11:49 2009 +0200
+++ b/common/mttransforms.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""mime type transformation engine for cubicweb, based on mtconverter
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/common/schema.py Fri May 29 16:11:49 2009 +0200
+++ b/common/schema.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""pre 3.0 bw compat"""
+"""pre 3.0 bw compat
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
# pylint: disable-msg=W0614,W0401
from warnings import warn
warn('moved to cubicweb.schema', DeprecationWarning, stacklevel=2)
--- a/common/selectors.py Fri May 29 16:11:49 2009 +0200
+++ b/common/selectors.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""pre 3.2 bw compat"""
+"""pre 3.2 bw compat
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
# pylint: disable-msg=W0614,W0401
from warnings import warn
warn('moved to cubicweb.selectors', DeprecationWarning, stacklevel=2)
--- a/common/tags.py Fri May 29 16:11:49 2009 +0200
+++ b/common/tags.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""helper classes to generate simple (X)HTML tags
:organization: Logilab
-:copyright: 2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2009 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
"""
__docformat__ = "restructuredtext en"
--- a/common/test/data/migration/0.0.3_Any.py Fri May 29 16:11:49 2009 +0200
+++ b/common/test/data/migration/0.0.3_Any.py Fri May 29 20:22:39 2009 +0200
@@ -1,1 +1,8 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
coucou
--- a/common/test/data/migration/0.0.4_Any.py Fri May 29 16:11:49 2009 +0200
+++ b/common/test/data/migration/0.0.4_Any.py Fri May 29 20:22:39 2009 +0200
@@ -1,1 +1,8 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
coucou
--- a/common/test/data/migration/0.1.0_Any.py Fri May 29 16:11:49 2009 +0200
+++ b/common/test/data/migration/0.1.0_Any.py Fri May 29 20:22:39 2009 +0200
@@ -1,1 +1,8 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
coucou
--- a/common/test/data/migration/0.1.0_common.py Fri May 29 16:11:49 2009 +0200
+++ b/common/test/data/migration/0.1.0_common.py Fri May 29 20:22:39 2009 +0200
@@ -1,1 +1,7 @@
-"""common to all configuration"""
+"""common to all configuration
+
+:organization: Logilab
+:copyright: 2001-2009 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/common/test/data/migration/0.1.0_repository.py Fri May 29 16:11:49 2009 +0200
+++ b/common/test/data/migration/0.1.0_repository.py Fri May 29 20:22:39 2009 +0200
@@ -1,1 +1,7 @@
-"""repository specific"""
+"""repository specific
+
+:organization: Logilab
+:copyright: 2001-2009 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/common/test/data/migration/0.1.0_web.py Fri May 29 16:11:49 2009 +0200
+++ b/common/test/data/migration/0.1.0_web.py Fri May 29 20:22:39 2009 +0200
@@ -1,1 +1,7 @@
-"""web only"""
+"""web only
+
+:organization: Logilab
+:copyright: 2001-2009 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/common/test/data/migration/0.1.2_Any.py Fri May 29 16:11:49 2009 +0200
+++ b/common/test/data/migration/0.1.2_Any.py Fri May 29 20:22:39 2009 +0200
@@ -1,1 +1,8 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
coucou
--- a/common/test/data/server_migration/bootstrapmigration_repository.py Fri May 29 16:11:49 2009 +0200
+++ b/common/test/data/server_migration/bootstrapmigration_repository.py Fri May 29 20:22:39 2009 +0200
@@ -1,1 +1,7 @@
-"""allways executed before all others in server migration"""
+"""allways executed before all others in server migration
+
+:organization: Logilab
+:copyright: 2001-2009 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/common/test/unittest_mail.py Fri May 29 16:11:49 2009 +0200
+++ b/common/test/unittest_mail.py Fri May 29 20:22:39 2009 +0200
@@ -1,5 +1,11 @@
# -*- coding: utf-8 -*-
-"""unit tests for module cubicweb.common.mail"""
+"""unit tests for module cubicweb.common.mail
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
import os
import pwd
--- a/common/test/unittest_migration.py Fri May 29 16:11:49 2009 +0200
+++ b/common/test/unittest_migration.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""cubicweb.common.migration unit tests"""
+"""cubicweb.common.migration unit tests
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from os.path import abspath
from logilab.common.testlib import TestCase, unittest_main
--- a/common/test/unittest_mixins.py Fri May 29 16:11:49 2009 +0200
+++ b/common/test/unittest_mixins.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import unittest_main
from cubicweb.devtools.apptest import EnvBasedTC
--- a/common/test/unittest_uilib.py Fri May 29 16:11:49 2009 +0200
+++ b/common/test/unittest_uilib.py Fri May 29 20:22:39 2009 +0200
@@ -1,5 +1,11 @@
# -*- coding: utf-8 -*-
-"""unittests for cubicweb.common.uilib"""
+"""unittests for cubicweb.common.uilib
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
__docformat__ = "restructuredtext en"
--- a/common/uilib.py Fri May 29 16:11:49 2009 +0200
+++ b/common/uilib.py Fri May 29 20:22:39 2009 +0200
@@ -4,8 +4,9 @@
contains some functions designed to help implementation of cubicweb user interface
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/common/utils.py Fri May 29 16:11:49 2009 +0200
+++ b/common/utils.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""pre 3.2 bw compat"""
+"""pre 3.2 bw compat
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
# pylint: disable-msg=W0614,W0401
from warnings import warn
warn('moved to cubicweb.utils', DeprecationWarning, stacklevel=2)
--- a/common/view.py Fri May 29 16:11:49 2009 +0200
+++ b/common/view.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""pre 3.2 bw compat"""
+"""pre 3.2 bw compat
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
# pylint: disable-msg=W0614,W0401
from warnings import warn
warn('moved to cubicweb.view', DeprecationWarning, stacklevel=2)
--- a/cwconfig.py Fri May 29 16:11:49 2009 +0200
+++ b/cwconfig.py Fri May 29 20:22:39 2009 +0200
@@ -2,13 +2,14 @@
"""common configuration utilities for cubicweb
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
.. envvar:: CW_CUBES_PATH
Augments the default search path for cubes
+:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
__docformat__ = "restructuredtext en"
_ = unicode
--- a/cwctl.py Fri May 29 16:11:49 2009 +0200
+++ b/cwctl.py Fri May 29 20:22:39 2009 +0200
@@ -1,6 +1,7 @@
"""%%prog %s [options] %s
CubicWeb main applications controller.
+:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
%s"""
import sys
--- a/cwvreg.py Fri May 29 16:11:49 2009 +0200
+++ b/cwvreg.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""extend the generic VRegistry with some cubicweb specific stuff
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
_ = unicode
@@ -248,6 +249,16 @@
self.exception('error while trying to list possible %s views for %s',
vid, rset)
+ def view(self, __vid, req, rset=None, __fallback_vid=None, **kwargs):
+ """shortcut to self.vreg.render method avoiding to pass self.req"""
+ try:
+ view = self.select_view(__vid, req, rset, **kwargs)
+ except NoSelectableObject:
+ if __fallback_vid is None:
+ raise
+ view = self.select_view(__fallback_vid, req, rset, **kwargs)
+ return view.render(**kwargs)
+
def select_box(self, oid, *args, **kwargs):
"""return the most specific view according to the result set"""
try:
@@ -269,12 +280,11 @@
except (NoSelectableObject, ObjectNotFound):
return
- def select_view(self, __vid, req, rset, **kwargs):
+ def select_view(self, __vid, req, rset=None, **kwargs):
"""return the most specific view according to the result set"""
views = self.registry_objects('views', __vid)
return self.select(views, req, rset, **kwargs)
-
# properties handling #####################################################
def user_property_keys(self, withsitewide=False):
--- a/dbapi.py Fri May 29 16:11:49 2009 +0200
+++ b/dbapi.py Fri May 29 20:22:39 2009 +0200
@@ -5,8 +5,9 @@
(most parts of this document are reported here in docstrings)
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/devtools/__init__.py Fri May 29 16:11:49 2009 +0200
+++ b/devtools/__init__.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Test tools for cubicweb
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
@@ -328,7 +329,7 @@
pass
if removecube:
try:
- os.remove('%s-cube' % dbfile)
+ os.remove('%s-template' % dbfile)
except OSError:
pass
@@ -338,11 +339,11 @@
# remove database file if it exists (actually I know driver == 'sqlite' :)
dbfile = source['system']['db-name']
cleanup_sqlite(dbfile)
- cube = '%s-cube' % dbfile
- if exists(cube):
- shutil.copy(cube, dbfile)
+ template = '%s-template' % dbfile
+ if exists(template):
+ shutil.copy(template, dbfile)
else:
# initialize the database
from cubicweb.server import init_repository
init_repository(config, interactive=False, vreg=vreg)
- shutil.copy(dbfile, cube)
+ shutil.copy(dbfile, template)
--- a/devtools/_apptest.py Fri May 29 16:11:49 2009 +0200
+++ b/devtools/_apptest.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Hidden internals for the devtools.apptest module
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/devtools/apptest.py Fri May 29 16:11:49 2009 +0200
+++ b/devtools/apptest.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""This module provides misc utilities to test applications
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/devtools/cwtwill.py Fri May 29 16:11:49 2009 +0200
+++ b/devtools/cwtwill.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""cubicweb extensions for twill
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
import re
--- a/devtools/devctl.py Fri May 29 16:11:49 2009 +0200
+++ b/devtools/devctl.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
cubes development
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/devtools/fake.py Fri May 29 16:11:49 2009 +0200
+++ b/devtools/fake.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Fake objects to ease testing of cubicweb without a fully working environment
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/devtools/fill.py Fri May 29 16:11:49 2009 +0200
+++ b/devtools/fill.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
"""This modules defines func / methods for creating test repositories
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/devtools/htmlparser.py Fri May 29 16:11:49 2009 +0200
+++ b/devtools/htmlparser.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""defines a validating HTML parser used in web application tests"""
+"""defines a validating HTML parser used in web application tests
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
import re
--- a/devtools/livetest.py Fri May 29 16:11:49 2009 +0200
+++ b/devtools/livetest.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""provide utilies for web (live) unit testing
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
import socket
--- a/devtools/migrtest.py Fri May 29 16:11:49 2009 +0200
+++ b/devtools/migrtest.py Fri May 29 20:22:39 2009 +0200
@@ -27,11 +27,12 @@
The permissions on .pgpass must disallow any access to world or group;
achieve this by the command chmod 0600 ~/.pgpass. If the permissions
-are less strict than this, the file will be ignored.
+are less strict than this, the file will be ignored.
:organization: Logilab
-:copyright: 2001-2006 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/devtools/pkginfo.py Fri May 29 16:11:49 2009 +0200
+++ b/devtools/pkginfo.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""distutils / __pkginfo__ helpers for cubicweb applications"""
+"""distutils / __pkginfo__ helpers for cubicweb applications
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
import os
from os.path import isdir, join
--- a/devtools/repotest.py Fri May 29 16:11:49 2009 +0200
+++ b/devtools/repotest.py Fri May 29 20:22:39 2009 +0200
@@ -3,8 +3,9 @@
This module contains functions to initialize a new repository.
:organization: Logilab
-:copyright: 2003-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2003-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/devtools/stresstester.py Fri May 29 16:11:49 2009 +0200
+++ b/devtools/stresstester.py Fri May 29 20:22:39 2009 +0200
@@ -21,8 +21,9 @@
-o / --report-output <filename>
Write profiler report into <filename> rather than on stdout
-Copyright (c) 2003-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+Copyright (c) 2003-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
http://www.logilab.fr/ -- mailto:contact@logilab.fr
+:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
__revision__ = "$Id: stresstester.py,v 1.3 2006-03-05 14:35:27 syt Exp $"
--- a/devtools/test/data/schema/custom.py Fri May 29 16:11:49 2009 +0200
+++ b/devtools/test/data/schema/custom.py Fri May 29 20:22:39 2009 +0200
@@ -1,2 +1,9 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
Person = import_erschema('Person')
Person.add_relation(Date(), 'birthday')
--- a/devtools/test/data/views/bug.py Fri May 29 16:11:49 2009 +0200
+++ b/devtools/test/data/views/bug.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""only for unit tests !"""
+"""only for unit tests !
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb.view import EntityView
from cubicweb.selectors import implements
--- a/devtools/test/unittest_dbfill.py Fri May 29 16:11:49 2009 +0200
+++ b/devtools/test/unittest_dbfill.py Fri May 29 20:22:39 2009 +0200
@@ -1,5 +1,11 @@
# -*- coding: iso-8859-1 -*-
-"""unit tests for database value generator"""
+"""unit tests for database value generator
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
import os.path as osp
import re
--- a/devtools/test/unittest_fill.py Fri May 29 16:11:49 2009 +0200
+++ b/devtools/test/unittest_fill.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""unit tests for cubicweb.devtools.fill module"""
+"""unit tests for cubicweb.devtools.fill module
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import TestCase, unittest_main
--- a/devtools/test/unittest_testlib.py Fri May 29 16:11:49 2009 +0200
+++ b/devtools/test/unittest_testlib.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""unittests for gct.apptest module"""
+"""unittests for gct.apptest module
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cStringIO import StringIO
from unittest import TestSuite
--- a/devtools/testlib.py Fri May 29 16:11:49 2009 +0200
+++ b/devtools/testlib.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""this module contains base classes for web tests
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/doc/book/en/conf.py Fri May 29 16:11:49 2009 +0200
+++ b/doc/book/en/conf.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,11 @@
# -*- coding: utf-8 -*-
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
#
# Cubicweb documentation build configuration file, created by
# sphinx-quickstart on Fri Oct 31 09:10:36 2008.
--- a/doc/book/fr/conf.py Fri May 29 16:11:49 2009 +0200
+++ b/doc/book/fr/conf.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,11 @@
# -*- coding: utf-8 -*-
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
#
# Cubicweb documentation build configuration file, created by
# sphinx-quickstart on Fri Oct 31 09:10:36 2008.
--- a/doc/book/mode_plan.py Fri May 29 16:11:49 2009 +0200
+++ b/doc/book/mode_plan.py Fri May 29 20:22:39 2009 +0200
@@ -5,6 +5,7 @@
>>> ren('A01','A03')
rename A010-joe.en.txt to A030-joe.en.txt
accept [y/N]?
+:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
def ren(a,b):
--- a/doc/tools/generate_modules.py Fri May 29 16:11:49 2009 +0200
+++ b/doc/tools/generate_modules.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""generate list of modules for sphinx doc"""
+"""generate list of modules for sphinx doc
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
import sys
--- a/entities/__init__.py Fri May 29 16:11:49 2009 +0200
+++ b/entities/__init__.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""base application's entities class implementation: `AnyEntity`
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
@@ -241,13 +242,13 @@
@obsolete('use EntityFieldsForm.subject_relation_vocabulary')
def subject_relation_vocabulary(self, rtype, limit):
- from cubicweb.web.form import EntityFieldsForm
- return EntityFieldsForm(self.req, None, entity=self).subject_relation_vocabulary(rtype, limit)
+ form = self.vreg.select_object('forms', 'edition', self.req, entity=self)
+ return form.subject_relation_vocabulary(rtype, limit)
@obsolete('use EntityFieldsForm.object_relation_vocabulary')
def object_relation_vocabulary(self, rtype, limit):
- from cubicweb.web.form import EntityFieldsForm
- return EntityFieldsForm(self.req, None, entity=self).object_relation_vocabulary(rtype, limit)
+ form = self.vreg.select_object('forms', 'edition', self.req, entity=self)
+ return form.object_relation_vocabulary(rtype, limit)
@obsolete('use AutomaticEntityForm.[e]relations_by_category')
def relations_by_category(self, categories=None, permission=None):
--- a/entities/authobjs.py Fri May 29 16:11:49 2009 +0200
+++ b/entities/authobjs.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""entity classes user and group entities
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/entities/lib.py Fri May 29 16:11:49 2009 +0200
+++ b/entities/lib.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""entity classes for optional library entities
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/entities/schemaobjs.py Fri May 29 16:11:49 2009 +0200
+++ b/entities/schemaobjs.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""schema definition related entities
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
@@ -19,7 +20,7 @@
fetch_attrs, fetch_order = fetch_config(['name'])
def dc_title(self):
- return self.req._(self.name)
+ return u'%s (%s)' % (self.name, self.req._(self.name))
def dc_long_title(self):
stereotypes = []
@@ -42,7 +43,7 @@
fetch_attrs, fetch_order = fetch_config(['name'])
def dc_title(self):
- return self.req._(self.name)
+ return u'%s (%s)' % (self.name, self.req._(self.name))
def dc_long_title(self):
stereotypes = []
--- a/entities/test/data/schema.py Fri May 29 16:11:49 2009 +0200
+++ b/entities/test/data/schema.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
class Company(EntityType):
name = String()
--- a/entities/test/unittest_base.py Fri May 29 16:11:49 2009 +0200
+++ b/entities/test/unittest_base.py Fri May 29 20:22:39 2009 +0200
@@ -1,5 +1,11 @@
# -*- coding: utf-8 -*-
-"""unit tests for cubicweb.entities.base module"""
+"""unit tests for cubicweb.entities.base module
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import unittest_main
from logilab.common.decorators import clear_cache
--- a/entities/wfobjs.py Fri May 29 16:11:49 2009 +0200
+++ b/entities/wfobjs.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""workflow definition and history related entities
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/entity.py Fri May 29 16:11:49 2009 +0200
+++ b/entity.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Base class for entity objects manipulated in clients
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
@@ -723,9 +724,8 @@
If `eid` is None in one of these couples, it should be
interpreted as a separator in case vocabulary results are grouped
"""
- from cubicweb.web.form import EntityFieldsForm
from logilab.common.testlib import mock_object
- form = EntityFieldsForm(self.req, entity=self)
+ form = self.vreg.select_object('forms', 'edition', self.req, entity=self)
field = mock_object(name=rtype, role=role)
return form.form_field_vocabulary(field, limit)
--- a/etwist/__init__.py Fri May 29 16:11:49 2009 +0200
+++ b/etwist/__init__.py Fri May 29 20:22:39 2009 +0200
@@ -1,2 +1,8 @@
-""" CW - nevow/twisted client """
+""" CW - nevow/twisted client
+:organization: Logilab
+:copyright: 2001-2009 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/etwist/request.py Fri May 29 16:11:49 2009 +0200
+++ b/etwist/request.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Twisted request handler for CubicWeb
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/etwist/server.py Fri May 29 16:11:49 2009 +0200
+++ b/etwist/server.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""twisted server for CubicWeb web applications
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
@@ -196,7 +197,7 @@
if self.url_rewriter is not None:
# XXX should occur before authentication?
try:
- path = self.url_rewriter.rewrite(host, origpath)
+ path = self.url_rewriter.rewrite(host, origpath, req)
except Redirect, ex:
return self.redirect(req, ex.location)
request.uri.replace(origpath, path, 1)
--- a/etwist/test/unittest_server.py Fri May 29 16:11:49 2009 +0200
+++ b/etwist/test/unittest_server.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb.devtools.apptest import EnvBasedTC
from cubicweb.etwist.server import host_prefixed_baseurl
--- a/etwist/twconfig.py Fri May 29 16:11:49 2009 +0200
+++ b/etwist/twconfig.py Fri May 29 20:22:39 2009 +0200
@@ -8,8 +8,9 @@
if the repository part of the software is installed
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/etwist/twctl.py Fri May 29 16:11:49 2009 +0200
+++ b/etwist/twctl.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""cubicweb-clt handlers for twisted
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
import sys
--- a/ext/html4zope.py Fri May 29 16:11:49 2009 +0200
+++ b/ext/html4zope.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,11 @@
# Author: David Goodger
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
# Contact: goodger@users.sourceforge.net
# Revision: $Revision: 1.2 $
# Date: $Date: 2005-07-04 16:36:50 $
--- a/ext/rest.py Fri May 29 16:11:49 2009 +0200
+++ b/ext/rest.py Fri May 29 20:22:39 2009 +0200
@@ -13,8 +13,9 @@
* `sourcecode` (if pygments is installed), source code colorization
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/ext/tal.py Fri May 29 16:11:49 2009 +0200
+++ b/ext/tal.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""provides simpleTAL extensions for CubicWeb
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/ext/test/unittest_rest.py Fri May 29 16:11:49 2009 +0200
+++ b/ext/test/unittest_rest.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import unittest_main
from cubicweb.devtools.apptest import EnvBasedTC
--- a/gettext.py Fri May 29 16:11:49 2009 +0200
+++ b/gettext.py Fri May 29 20:22:39 2009 +0200
@@ -8,6 +8,7 @@
languages. L10N refers to the adaptation of your program, once
internationalized, to the local language and cultural habits.
+:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
# This module represents the integration of work, contributions, feedback, and
--- a/goa/__init__.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/__init__.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""cubicweb on google appengine
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/goa/appobjects/components.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/appobjects/components.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""overrides some base views for cubicweb on google appengine
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/goa/appobjects/dbmgmt.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/appobjects/dbmgmt.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
restoration).
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/goa/appobjects/gauthservice.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/appobjects/gauthservice.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""authentication using google authentication service
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/goa/appobjects/sessions.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/appobjects/sessions.py Fri May 29 20:22:39 2009 +0200
@@ -1,12 +1,13 @@
"""persistent sessions stored in big table
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
XXX TODO:
* cleanup persistent session
* use user as ancestor?
+:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
__docformat__ = "restructuredtext en"
--- a/goa/db.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/db.py Fri May 29 20:22:39 2009 +0200
@@ -25,8 +25,9 @@
* XXX ListProperty
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/goa/dbinit.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/dbinit.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""some utility functions for datastore initialization.
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/goa/dbmyams.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/dbmyams.py Fri May 29 20:22:39 2009 +0200
@@ -6,8 +6,9 @@
XXX proprify this knowing we'll use goa.db
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
from os.path import join
--- a/goa/gaesource.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/gaesource.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Adapter for google appengine source.
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/goa/goaconfig.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/goaconfig.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""google appengine configuration
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/goa/goactl.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/goactl.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""cubicweb on appengine plugins for cubicweb-ctl
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/goa/goavreg.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/goavreg.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""goa specific registry
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/goa/overrides/__init__.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/overrides/__init__.py Fri May 29 20:22:39 2009 +0200
@@ -1,1 +1,8 @@
# server.__init__
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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/goa/overrides/mttransforms.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/overrides/mttransforms.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""mime type transformation engine for cubicweb, based on mtconverter
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/goa/overrides/rqlannotation.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/overrides/rqlannotation.py Fri May 29 20:22:39 2009 +0200
@@ -1,7 +1,8 @@
"""
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/goa/overrides/server__init__.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/overrides/server__init__.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,11 @@
# server debugging flag
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
DEBUG = False
# sqlite'stored procedures have to be registered at connexion opening time
--- a/goa/overrides/server_utils.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/overrides/server_utils.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
class RepoThread(object):
def __init__(self, *args):
--- a/goa/overrides/toolsutils.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/overrides/toolsutils.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
import sys
from cubicweb import warning
--- a/goa/rqlinterpreter.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/rqlinterpreter.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""provide a minimal RQL support for google appengine dbmodel
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/goa/skel/custom.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/skel/custom.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
def postinit(vreg):
"""this callback is called at the end of initialization process
and can be used to load explicit modules (views or entities).
--- a/goa/skel/loader.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/skel/loader.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
if __name__ == '__main__':
from os.path import dirname, abspath
--- a/goa/skel/main.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/skel/main.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
to change anything here.
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/goa/skel/schema.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/skel/schema.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb.schema import format_constraint
class Blog(EntityType):
--- a/goa/skel/views.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/skel/views.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,11 @@
# custom application views
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from datetime import date
from cubicweb.utils import last_day
--- a/goa/test/data/__init__.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/test/data/__init__.py Fri May 29 20:22:39 2009 +0200
@@ -1,1 +1,7 @@
-"""zou"""
+"""zou
+
+:organization: Logilab
+:copyright: 2001-2009 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/goa/test/data/schema.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/test/data/schema.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
class YamsEntity(EntityType):
--- a/goa/test/data/settings.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/test/data/settings.py Fri May 29 20:22:39 2009 +0200
@@ -1,1 +1,8 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
TEMPLATE_DEBUG = False
--- a/goa/test/data/views.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/test/data/views.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,11 @@
# -*- coding: utf-8 -*-
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
import os
os.environ["DJANGO_SETTINGS_MODULE"] = 'data.settings'
--- a/goa/test/pytestconf.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/test/pytestconf.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,5 @@
"""this pytestconf automatically adds the mx's python version in the PYTHONPATH
+:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
import sys
import os.path as osp
--- a/goa/test/unittest_db.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/test/unittest_db.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,11 @@
# -*- coding: utf-8 -*-
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb.goa.testlib import *
from cubicweb import Binary
--- a/goa/test/unittest_editcontroller.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/test/unittest_editcontroller.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb.goa.testlib import *
from urllib import unquote
--- a/goa/test/unittest_metadata.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/test/unittest_metadata.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb.goa.testlib import *
import time
--- a/goa/test/unittest_rql.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/test/unittest_rql.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb.goa.testlib import *
from cubicweb import Binary
--- a/goa/test/unittest_schema.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/test/unittest_schema.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb.goa.testlib import *
class Article(db.Model):
--- a/goa/test/unittest_views.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/test/unittest_views.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb.goa.testlib import *
from cubicweb.interfaces import ICalendarable
--- a/goa/testlib.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/testlib.py Fri May 29 20:22:39 2009 +0200
@@ -1,7 +1,8 @@
"""
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/goa/tools/__init__.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/tools/__init__.py Fri May 29 20:22:39 2009 +0200
@@ -1,1 +1,7 @@
-"""lax tools cube"""
+"""lax tools cube
+
+:organization: Logilab
+:copyright: 2001-2009 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/goa/tools/generate_schema_img.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/tools/generate_schema_img.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
import sys
from os.path import dirname, abspath, join
from yams import schema2dot
--- a/goa/tools/laxctl.py Fri May 29 16:11:49 2009 +0200
+++ b/goa/tools/laxctl.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""provides all lax instances management commands into a single utility script
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/hercule.py Fri May 29 16:11:49 2009 +0200
+++ b/hercule.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""RQL client for cubicweb, connecting to application using pyro
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/interfaces.py Fri May 29 16:11:49 2009 +0200
+++ b/interfaces.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Specific views for entities implementing IDownloadable
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/md5crypt.py Fri May 29 16:11:49 2009 +0200
+++ b/md5crypt.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,11 @@
#########################################################
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
# md5crypt.py
#
# 0423.2000 by michal wallace http://www.sabren.com/
--- a/misc/cwdesklets/rqlsensor/__init__.py Fri May 29 16:11:49 2009 +0200
+++ b/misc/cwdesklets/rqlsensor/__init__.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
import webbrowser
reload(webbrowser)
--- a/misc/cwfs/cwfs.py Fri May 29 16:11:49 2009 +0200
+++ b/misc/cwfs/cwfs.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
class Schema :
def __init__(self, schema) :
--- a/misc/cwfs/cwfs_test.py Fri May 29 16:11:49 2009 +0200
+++ b/misc/cwfs/cwfs_test.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import TestCase, unittest_main
import cubicwebfs
--- a/misc/cwzope/cwzope.py Fri May 29 16:11:49 2009 +0200
+++ b/misc/cwzope/cwzope.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from AccessControl import getSecurityManager
from cubicweb.dbapi import connect, Connection, Cursor
--- a/misc/migration/2.42.0_Any.py Fri May 29 16:11:49 2009 +0200
+++ b/misc/migration/2.42.0_Any.py Fri May 29 20:22:39 2009 +0200
@@ -1,2 +1,9 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
synchronize_rschema('created_by')
synchronize_rschema('owned_by')
--- a/misc/migration/2.42.1_Any.py Fri May 29 16:11:49 2009 +0200
+++ b/misc/migration/2.42.1_Any.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
if confirm('remove deprecated database constraints?'):
execute = session.system_sql
session.set_pool()
--- a/misc/migration/2.43.0_Any.py Fri May 29 16:11:49 2009 +0200
+++ b/misc/migration/2.43.0_Any.py Fri May 29 20:22:39 2009 +0200
@@ -1,1 +1,8 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
synchronize_permissions('EmailAddress')
--- a/misc/migration/2.44.0_Any.py Fri May 29 16:11:49 2009 +0200
+++ b/misc/migration/2.44.0_Any.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
change_relation_props('CWAttribute', 'cardinality', 'String', internationalizable=True)
change_relation_props('CWRelation', 'cardinality', 'String', internationalizable=True)
--- a/misc/migration/2.45.0_Any.py Fri May 29 16:11:49 2009 +0200
+++ b/misc/migration/2.45.0_Any.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,11 @@
# following functions have been renamed, but keep old definition for bw compat
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
sql('''CREATE AGGREGATE group_concat (
basetype = anyelement,
sfunc = array_append,
--- a/misc/migration/2.46.0_Any.py Fri May 29 16:11:49 2009 +0200
+++ b/misc/migration/2.46.0_Any.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
rql('SET X value "navtop" WHERE X pkey ~= "contentnavigation.%.context", X value "header"')
--- a/misc/migration/2.47.0_Any.py Fri May 29 16:11:49 2009 +0200
+++ b/misc/migration/2.47.0_Any.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
synchronize_permissions('primary_email')
synchronize_rschema('wf_info_for')
synchronize_rschema('use_email')
--- a/misc/migration/2.48.8_Any.py Fri May 29 16:11:49 2009 +0200
+++ b/misc/migration/2.48.8_Any.py Fri May 29 20:22:39 2009 +0200
@@ -1,2 +1,9 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
for etype in ('CWRType', 'CWAttribute', 'CWRelation', 'CWConstraint', 'CWConstraintType'):
synchronize_permissions(etype)
--- a/misc/migration/2.49.3_Any.py Fri May 29 16:11:49 2009 +0200
+++ b/misc/migration/2.49.3_Any.py Fri May 29 20:22:39 2009 +0200
@@ -1,1 +1,8 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
add_entity_type('Decimal')
--- a/misc/migration/2.50.0_Any.py Fri May 29 16:11:49 2009 +0200
+++ b/misc/migration/2.50.0_Any.py Fri May 29 20:22:39 2009 +0200
@@ -1,1 +1,8 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
add_relation_type('specializes')
--- a/misc/migration/2.99.0_Any.py Fri May 29 16:11:49 2009 +0200
+++ b/misc/migration/2.99.0_Any.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb import CW_MIGRATION_MAP
for pk, in rql('Any K WHERE X is CWProperty, X pkey IN (%s), X pkey K'
--- a/misc/migration/3.1.5_Any.py Fri May 29 16:11:49 2009 +0200
+++ b/misc/migration/3.1.5_Any.py Fri May 29 20:22:39 2009 +0200
@@ -1,1 +1,8 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
synchronize_permissions('condition')
--- a/misc/migration/3.2.0_Any.py Fri May 29 16:11:49 2009 +0200
+++ b/misc/migration/3.2.0_Any.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
rql('SET X value "main-template" WHERE X is CWProperty, '
'X pkey "ui.main-template", X value "main"')
checkpoint()
--- a/misc/migration/bootstrapmigration_repository.py Fri May 29 16:11:49 2009 +0200
+++ b/misc/migration/bootstrapmigration_repository.py Fri May 29 20:22:39 2009 +0200
@@ -3,8 +3,9 @@
it should only include low level schema changes
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
if applcubicwebversion < (3, 2, 2) and cubicwebversion >= (3, 2, 1):
--- a/misc/migration/postcreate.py Fri May 29 16:11:49 2009 +0200
+++ b/misc/migration/postcreate.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""cubicweb post creation script, set user's workflow"""
+"""cubicweb post creation script, set user's workflow
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
activatedeid = add_state(_('activated'), 'CWUser', initial=True)
deactivatedeid = add_state(_('deactivated'), 'CWUser')
--- a/rset.py Fri May 29 16:11:49 2009 +0200
+++ b/rset.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""The `ResultSet` class which is returned as result of a rql query
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/rtags.py Fri May 29 16:11:49 2009 +0200
+++ b/rtags.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""relation tags store
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/schema.py Fri May 29 16:11:49 2009 +0200
+++ b/schema.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""classes to define schemas for CubicWeb
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/schemas/Bookmark.py Fri May 29 16:11:49 2009 +0200
+++ b/schemas/Bookmark.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
class Bookmark(MetaUserEntityType):
"""define an entity type, used to build the application schema"""
--- a/schemas/base.py Fri May 29 16:11:49 2009 +0200
+++ b/schemas/base.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""core CubicWeb schema, but not necessary at bootstrap time
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/schemas/bootstrap.py Fri May 29 16:11:49 2009 +0200
+++ b/schemas/bootstrap.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""core CubicWeb schema necessary for bootstrapping the actual application's schema
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
from cubicweb.schema import format_constraint
@@ -57,7 +58,7 @@
constrained_by = SubjectRelation('CWConstraint', cardinality='*1', composite='subject')
cardinality = String(maxsize=2, internationalizable=True,
- vocabulary=[_('?1'), _('11'), _('??'), _('1?')],
+ vocabulary=[_('?1'), _('11')],
description=_('subject/object cardinality'))
ordernum = Int(description=('control subject entity\'s relations order'), default=0)
--- a/schemas/workflow.py Fri May 29 16:11:49 2009 +0200
+++ b/schemas/workflow.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""workflow related schemas
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
class State(MetaEntityType):
--- a/schemaviewer.py Fri May 29 16:11:49 2009 +0200
+++ b/schemaviewer.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""an helper class to display CubicWeb schema using ureports
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
@@ -93,10 +94,10 @@
return data
def eschema_link_url(self, eschema):
- return self.req.build_url('cwetype/%s?vid=eschema' % eschema)
+ return self.req.build_url('cwetype/%s' % eschema)
def rschema_link_url(self, rschema):
- return self.req.build_url('cwrtype/%s?vid=eschema' % rschema)
+ return self.req.build_url('cwrtype/%s' % rschema)
def possible_views(self, etype):
rset = self.req.etype_rset(etype)
--- a/selectors.py Fri May 29 16:11:49 2009 +0200
+++ b/selectors.py Fri May 29 20:22:39 2009 +0200
@@ -36,10 +36,10 @@
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
-
__docformat__ = "restructuredtext en"
import logging
@@ -245,6 +245,7 @@
if kwargs.get('entity'):
score = self.score_entity(kwargs['entity'])
elif row is None:
+ col = col or 0
for row, rowvalue in enumerate(rset.rows):
if rowvalue[col] is None: # outer join
continue
@@ -255,6 +256,7 @@
return escore
score += escore
else:
+ col = col or 0
etype = rset.description[row][col]
if etype is not None: # outer join
score = self.score(req, rset, row, col)
@@ -273,9 +275,13 @@
# very basic selectors ########################################################
class yes(Selector):
- """return arbitrary score"""
- def __init__(self, score=1):
+ """return arbitrary score
+
+ default score of 0.5 so any other selector take precedence
+ """
+ def __init__(self, score=0.5):
self.score = score
+
def __call__(self, *args, **kwargs):
return self.score
--- a/server/__init__.py Fri May 29 16:11:49 2009 +0200
+++ b/server/__init__.py Fri May 29 20:22:39 2009 +0200
@@ -4,8 +4,9 @@
This module contains functions to initialize a new repository.
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/checkintegrity.py Fri May 29 16:11:49 2009 +0200
+++ b/server/checkintegrity.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
is checked.
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/hookhelper.py Fri May 29 16:11:49 2009 +0200
+++ b/server/hookhelper.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""helper functions for application hooks
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/hooks.py Fri May 29 16:11:49 2009 +0200
+++ b/server/hooks.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
entities...
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/hooksmanager.py Fri May 29 16:11:49 2009 +0200
+++ b/server/hooksmanager.py Fri May 29 20:22:39 2009 +0200
@@ -23,8 +23,9 @@
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/migractions.py Fri May 29 16:11:49 2009 +0200
+++ b/server/migractions.py Fri May 29 20:22:39 2009 +0200
@@ -11,8 +11,9 @@
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/msplanner.py Fri May 29 16:11:49 2009 +0200
+++ b/server/msplanner.py Fri May 29 20:22:39 2009 +0200
@@ -70,8 +70,9 @@
:organization: Logilab
-:copyright: 2003-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2003-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/mssteps.py Fri May 29 16:11:49 2009 +0200
+++ b/server/mssteps.py Fri May 29 20:22:39 2009 +0200
@@ -6,8 +6,9 @@
for now)
:organization: Logilab
-:copyright: 2003-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2003-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/pool.py Fri May 29 16:11:49 2009 +0200
+++ b/server/pool.py Fri May 29 20:22:39 2009 +0200
@@ -11,8 +11,9 @@
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/querier.py Fri May 29 16:11:49 2009 +0200
+++ b/server/querier.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
security checking and data aggregation.
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/repository.py Fri May 29 16:11:49 2009 +0200
+++ b/server/repository.py Fri May 29 20:22:39 2009 +0200
@@ -11,8 +11,9 @@
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/rqlannotation.py Fri May 29 16:11:49 2009 +0200
+++ b/server/rqlannotation.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
code generation.
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/rqlrewrite.py Fri May 29 16:11:49 2009 +0200
+++ b/server/rqlrewrite.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""RQL rewriting utilities, used for read security checking
:organization: Logilab
-:copyright: 2007-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2007-2009 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
"""
from rql import nodes, stmts, TypeResolverException
--- a/server/schemaserial.py Fri May 29 16:11:49 2009 +0200
+++ b/server/schemaserial.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""functions for schema / permissions (de)serialization using RQL
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/securityhooks.py Fri May 29 16:11:49 2009 +0200
+++ b/server/securityhooks.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
the user connected to a session
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/server.py Fri May 29 16:11:49 2009 +0200
+++ b/server/server.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Pyro RQL server
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/serverconfig.py Fri May 29 16:11:49 2009 +0200
+++ b/server/serverconfig.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""server.serverconfig definition
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/serverctl.py Fri May 29 16:11:49 2009 +0200
+++ b/server/serverctl.py Fri May 29 20:22:39 2009 +0200
@@ -1,11 +1,13 @@
"""cubicweb-ctl commands and command handlers specific to the server.serverconfig
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
+import sys
import os
from logilab.common.configuration import REQUIRED, Configuration, ini_format_section
@@ -117,7 +119,7 @@
_sconfig.set_option(attr, val)
sconfig = _sconfig
optsbysect = list(sconfig.options_by_section())
- assert len(optsbysect) == 1
+ assert len(optsbysect) == 1, 'all options for a source should be in the same group'
ini_format_section(stream, uri, optsbysect[0][1])
if hasattr(sconfig, 'adapter'):
print >> stream
@@ -418,6 +420,51 @@
cnx.commit()
print 'grants given to %s on application %s' % (appid, user)
+class ResetAdminPasswordCommand(Command):
+ """Reset the administrator password.
+
+ <application>
+ the identifier of the application
+ """
+ name = 'reset-admin-pwd'
+ arguments = '<application>'
+
+ def run(self, args):
+ """run the command with its specific arguments"""
+ from cubicweb.server.sqlutils import sqlexec, SQL_PREFIX
+ from cubicweb.server.utils import crypt_password, manager_userpasswd
+ appid = pop_arg(args, 1, msg="No application specified !")
+ config = ServerConfiguration.config_for(appid)
+ sourcescfg = config.sources()
+ try:
+ adminlogin = sourcescfg['admin']['login']
+ except KeyError:
+ print 'could not get cubicweb administrator login'
+ sys.exit(1)
+ cnx = source_cnx(sourcescfg['system'])
+ cursor = cnx.cursor()
+ _, passwd = manager_userpasswd(adminlogin, confirm=True,
+ passwdmsg='new password for %s' % adminlogin)
+ try:
+ sqlexec("UPDATE %(sp)sCWUser SET %(sp)supassword='%(p)s' WHERE %(sp)slogin='%(l)s'"
+ % {'sp': SQL_PREFIX,
+ 'p': crypt_password(passwd), 'l': adminlogin},
+ cursor, withpb=False)
+ sconfig = Configuration(options=USER_OPTIONS)
+ sconfig['login'] = adminlogin
+ sconfig['password'] = passwd
+ sourcescfg['admin'] = sconfig
+ sourcesfile = config.sources_file()
+ generate_sources_file(sourcesfile, sourcescfg)
+ restrict_perms_to_user(sourcesfile)
+ except Exception, ex:
+ cnx.rollback()
+ import traceback
+ traceback.print_exc()
+ print 'An error occured:', ex
+ else:
+ cnx.commit()
+ print 'password reset, sources file regenerated'
class StartRepositoryCommand(Command):
@@ -735,6 +782,7 @@
register_commands( (CreateApplicationDBCommand,
InitApplicationCommand,
GrantUserOnApplicationCommand,
+ ResetAdminPasswordCommand,
StartRepositoryCommand,
DBDumpCommand,
DBRestoreCommand,
--- a/server/session.py Fri May 29 16:11:49 2009 +0200
+++ b/server/session.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Repository users' and internal' sessions.
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/sources/__init__.py Fri May 29 16:11:49 2009 +0200
+++ b/server/sources/__init__.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""cubicweb server sources support
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/sources/extlite.py Fri May 29 16:11:49 2009 +0200
+++ b/server/sources/extlite.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""provide an abstract class for external sources using a sqlite database helper
:organization: Logilab
-:copyright: 2007-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2007-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/sources/ldapuser.py Fri May 29 16:11:49 2009 +0200
+++ b/server/sources/ldapuser.py Fri May 29 20:22:39 2009 +0200
@@ -3,7 +3,7 @@
this source is for now limited to a read-only CWUser source
:organization: Logilab
-:copyright: 2003-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2003-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
@@ -18,6 +18,7 @@
WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
FOR A PARTICULAR PURPOSE.
+:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
from base64 import b64decode
--- a/server/sources/native.py Fri May 29 16:11:49 2009 +0200
+++ b/server/sources/native.py Fri May 29 20:22:39 2009 +0200
@@ -7,8 +7,9 @@
it for fast querying.
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/sources/pyrorql.py Fri May 29 16:11:49 2009 +0200
+++ b/server/sources/pyrorql.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Source to query another RQL repository using pyro
:organization: Logilab
-:copyright: 2007-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2007-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/sources/rql2sql.py Fri May 29 16:11:49 2009 +0200
+++ b/server/sources/rql2sql.py Fri May 29 20:22:39 2009 +0200
@@ -25,8 +25,9 @@
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/sqlutils.py Fri May 29 16:11:49 2009 +0200
+++ b/server/sqlutils.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""SQL utilities functions and classes.
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/ssplanner.py Fri May 29 16:11:49 2009 +0200
+++ b/server/ssplanner.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""plan execution of rql queries on a single source
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/server/test/data/config1/application_hooks.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/data/config1/application_hooks.py Fri May 29 20:22:39 2009 +0200
@@ -2,6 +2,7 @@
Copyright (c) 2003-2007 LOGILAB S.A. (Paris, FRANCE).
http://www.logilab.fr/ -- mailto:contact@logilab.fr
+:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
HOOKS = {"after_add_relation" : {"concerned_by" : [lambda: None]}}
--- a/server/test/data/config2/application_hooks.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/data/config2/application_hooks.py Fri May 29 20:22:39 2009 +0200
@@ -2,6 +2,7 @@
Copyright (c) 2003-2007 LOGILAB S.A. (Paris, FRANCE).
http://www.logilab.fr/ -- mailto:contact@logilab.fr
+:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
HOOKS = {"after_delete_relation" : {"todo_by" : [lambda: 1]}}
--- a/server/test/data/extern_mapping.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/data/extern_mapping.py Fri May 29 20:22:39 2009 +0200
@@ -1,2 +1,9 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
support_entities = {'Card': True, 'Affaire': True, 'State': True}
support_relations = {'in_state': True, 'documented_by': True, 'multisource_inlined_rel': True}
--- a/server/test/data/hooks.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/data/hooks.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb.server.hooksmanager import SystemHook
CALLED_EVENTS = {}
--- a/server/test/data/migration/postcreate.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/data/migration/postcreate.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""cubicweb post creation script, set note's workflow"""
+"""cubicweb post creation script, set note's workflow
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
todoeid = add_state(u'todo', 'Note', initial=True)
doneeid = add_state(u'done', 'Note')
--- a/server/test/data/migrschema/Affaire.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/data/migrschema/Affaire.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
class Affaire(EntityType):
permissions = {
--- a/server/test/data/migrschema/Folder2.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/data/migrschema/Folder2.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb.schema import format_constraint
class Folder2(MetaUserEntityType):
--- a/server/test/data/migrschema/Note.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/data/migrschema/Note.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
class Note(EntityType):
permissions = {'read': ('managers', 'users', 'guests',),
--- a/server/test/data/schema/Affaire.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/data/schema/Affaire.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb.schema import format_constraint
class Affaire(WorkflowableEntityType):
--- a/server/test/data/schema/Societe.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/data/schema/Societe.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
class Societe(EntityType):
permissions = {
'read': ('managers', 'users', 'guests'),
--- a/server/test/data/schema/custom.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/data/schema/custom.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
class test(AttributeRelationType):
--- a/server/test/data/schema/note.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/data/schema/note.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
class para(AttributeRelationType):
permissions = {
--- a/server/test/data/site_erudi.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/data/site_erudi.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.adbh import FunctionDescr
from rql.utils import register_function
--- a/server/test/unittest_checkintegrity.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/unittest_checkintegrity.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
import sys
from StringIO import StringIO
from logilab.common.testlib import TestCase, unittest_main
--- a/server/test/unittest_config.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/unittest_config.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""tests for server config"""
+"""tests for server config
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from os.path import join, dirname
--- a/server/test/unittest_hookhelper.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/unittest_hookhelper.py Fri May 29 20:22:39 2009 +0200
@@ -1,5 +1,11 @@
# -*- coding: utf-8 -*-
-"""unit/functional tests for cubicweb.server.hookhelper"""
+"""unit/functional tests for cubicweb.server.hookhelper
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import unittest_main
from cubicweb.devtools.apptest import RepositoryBasedTC
--- a/server/test/unittest_hooksmanager.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/unittest_hooksmanager.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,5 @@
"""unit tests for the hooks manager
+:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
from logilab.common.testlib import TestCase, unittest_main
--- a/server/test/unittest_ldapuser.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/unittest_ldapuser.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""cubicweb.server.sources.ldapusers unit and functional tests"""
+"""cubicweb.server.sources.ldapusers unit and functional tests
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import TestCase, unittest_main, mock_object
from cubicweb.devtools import init_test_database, TestServerConfiguration
--- a/server/test/unittest_migractions.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/unittest_migractions.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,5 @@
"""unit tests for module cubicweb.server.migractions
+:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
from datetime import date
--- a/server/test/unittest_msplanner.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/unittest_msplanner.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.decorators import clear_cache
from cubicweb.devtools import init_test_database
from cubicweb.devtools.repotest import BasePlannerTC, do_monkey_patch, undo_monkey_patch, test_plan
--- a/server/test/unittest_multisources.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/unittest_multisources.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from os.path import dirname, join, abspath
from datetime import datetime, timedelta
--- a/server/test/unittest_querier.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/unittest_querier.py Fri May 29 20:22:39 2009 +0200
@@ -1,5 +1,6 @@
# -*- coding: iso-8859-1 -*-
"""unit tests for modules cubicweb.server.querier and cubicweb.server.querier_steps
+:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
from datetime import date, datetime
--- a/server/test/unittest_repository.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/unittest_repository.py Fri May 29 20:22:39 2009 +0200
@@ -1,5 +1,11 @@
# -*- coding: iso-8859-1 -*-
-"""unit tests for module cubicweb.server.repository"""
+"""unit tests for module cubicweb.server.repository
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
import os
import sys
--- a/server/test/unittest_rql2sql.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/unittest_rql2sql.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
"""unit tests for module cubicweb.server.sources.rql2sql"""
--- a/server/test/unittest_rqlannotation.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/unittest_rqlannotation.py Fri May 29 20:22:39 2009 +0200
@@ -1,5 +1,6 @@
# -*- coding: iso-8859-1 -*-
"""unit tests for modules cubicweb.server.rqlannotation
+:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
from cubicweb.devtools import init_test_database
--- a/server/test/unittest_rqlrewrite.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/unittest_rqlrewrite.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import unittest_main, TestCase
from logilab.common.testlib import mock_object
--- a/server/test/unittest_schemaserial.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/unittest_schemaserial.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,5 @@
"""unit tests for schema rql (de)serialization
+:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
import sys
--- a/server/test/unittest_security.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/unittest_security.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,5 @@
"""functional tests for server'security
+:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
import sys
--- a/server/test/unittest_session.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/unittest_session.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import TestCase, unittest_main, mock_object
from cubicweb.server.session import _make_description
--- a/server/test/unittest_sqlutils.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/unittest_sqlutils.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,5 @@
"""unit tests for module cubicweb.server.sqlutils
+:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
import sys
--- a/server/test/unittest_ssplanner.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/unittest_ssplanner.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb.devtools import init_test_database
from cubicweb.devtools.repotest import BasePlannerTC, test_plan
from cubicweb.server.ssplanner import SSPlanner
--- a/server/test/unittest_tools.py Fri May 29 16:11:49 2009 +0200
+++ b/server/test/unittest_tools.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import TestCase, unittest_main
class ImportTC(TestCase):
--- a/server/utils.py Fri May 29 16:11:49 2009 +0200
+++ b/server/utils.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Some utilities for the CubicWeb server.
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
@@ -63,23 +64,21 @@
DEFAULT_MSG = 'we need a manager connection on the repository \
(the server doesn\'t have to run, even should better not)'
-def manager_userpasswd(user=None, passwd=None, msg=DEFAULT_MSG, confirm=False):
+def manager_userpasswd(user=None, msg=DEFAULT_MSG, confirm=False,
+ passwdmsg='password'):
if not user:
print msg
while not user:
user = raw_input('login: ')
- passwd = getpass('password: ')
- if confirm:
- while True:
- passwd2 = getpass('confirm password: ')
- if passwd == passwd2:
- break
- print 'password doesn\'t match'
- passwd = getpass('password: ')
user = unicode(user, sys.stdin.encoding)
- elif not passwd:
- assert not confirm
- passwd = getpass('password for %s: ' % user)
+ passwd = getpass('%s: ' % passwdmsg)
+ if confirm:
+ while True:
+ passwd2 = getpass('confirm password: ')
+ if passwd == passwd2:
+ break
+ print 'password doesn\'t match'
+ passwd = getpass('password: ')
# XXX decode password using stdin encoding then encode it using appl'encoding
return user, passwd
--- a/setup.py Fri May 29 16:11:49 2009 +0200
+++ b/setup.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,11 @@
#!/usr/bin/env python
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
# pylint: disable-msg=W0142,W0403,W0404,W0613,W0622,W0622,W0704,R0904,C0103,E0611
#
# Copyright (c) 2003-2009 LOGILAB S.A. (Paris, FRANCE).
--- a/skeleton/entities.py Fri May 29 16:11:49 2009 +0200
+++ b/skeleton/entities.py Fri May 29 20:22:39 2009 +0200
@@ -1,1 +1,7 @@
-"""this contains the cube-specific entities' classes"""
+"""this contains the cube-specific entities' classes
+
+:organization: Logilab
+:copyright: 2001-2009 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/skeleton/migration/postcreate.py Fri May 29 16:11:49 2009 +0200
+++ b/skeleton/migration/postcreate.py Fri May 29 20:22:39 2009 +0200
@@ -1,2 +1,9 @@
# postcreate script. You could setup a workflow here for example
+"""
+:organization: Logilab
+:copyright: 2001-2009 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/skeleton/migration/precreate.py Fri May 29 16:11:49 2009 +0200
+++ b/skeleton/migration/precreate.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
# Instructions here will be read before reading the schema
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
# You could create your own groups here, like in :
# add_entity('CWGroup', name=u'mygroup')
--- a/skeleton/schema.py Fri May 29 16:11:49 2009 +0200
+++ b/skeleton/schema.py Fri May 29 20:22:39 2009 +0200
@@ -1,1 +1,8 @@
# cube's specific schema
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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/skeleton/setup.py Fri May 29 16:11:49 2009 +0200
+++ b/skeleton/setup.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,11 @@
#!/usr/bin/env python
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
# pylint: disable-msg=W0404,W0622,W0704,W0613,W0152
# Copyright (c) 2003-2009 LOGILAB S.A. (Paris, FRANCE).
# http://www.logilab.fr/ -- mailto:contact@logilab.fr
--- a/skeleton/test/pytestconf.py Fri May 29 16:11:49 2009 +0200
+++ b/skeleton/test/pytestconf.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
import os
import pwd
--- a/skeleton/test/realdb_test_CUBENAME.py Fri May 29 16:11:49 2009 +0200
+++ b/skeleton/test/realdb_test_CUBENAME.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb.devtools import buildconfig, loadconfig
from cubicweb.devtools.testlib import RealDBTest
--- a/skeleton/test/test_CUBENAME.py Fri May 29 16:11:49 2009 +0200
+++ b/skeleton/test/test_CUBENAME.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""template automatic tests"""
+"""template automatic tests
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import TestCase, unittest_main
--- a/skeleton/views.py Fri May 29 16:11:49 2009 +0200
+++ b/skeleton/views.py Fri May 29 20:22:39 2009 +0200
@@ -1,1 +1,7 @@
-"""cube-specific forms/views/actions/components"""
+"""cube-specific forms/views/actions/components
+
+:organization: Logilab
+:copyright: 2001-2009 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/sobjects/__init__.py Fri May 29 16:11:49 2009 +0200
+++ b/sobjects/__init__.py Fri May 29 20:22:39 2009 +0200
@@ -1,1 +1,7 @@
-"""server side objects"""
+"""server side objects
+
+:organization: Logilab
+:copyright: 2001-2009 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/sobjects/email.py Fri May 29 16:11:49 2009 +0200
+++ b/sobjects/email.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""hooks to ensure use_email / primary_email relations consistency
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/sobjects/hooks.py Fri May 29 16:11:49 2009 +0200
+++ b/sobjects/hooks.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""various library content hooks
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/sobjects/notification.py Fri May 29 16:11:49 2009 +0200
+++ b/sobjects/notification.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""some hooks and views to handle notification on entity's changes
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/sobjects/supervising.py Fri May 29 16:11:49 2009 +0200
+++ b/sobjects/supervising.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/sobjects/test/data/schema.py Fri May 29 16:11:49 2009 +0200
+++ b/sobjects/test/data/schema.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
class comments(RelationDefinition):
subject = 'Comment'
object = 'Card'
--- a/sobjects/test/data/sobjects/__init__.py Fri May 29 16:11:49 2009 +0200
+++ b/sobjects/test/data/sobjects/__init__.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb.selectors import implements
from cubicweb.sobjects.notification import StatusChangeMixIn, NotificationView
--- a/sobjects/test/unittest_email.py Fri May 29 16:11:49 2009 +0200
+++ b/sobjects/test/unittest_email.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb.devtools.apptest import EnvBasedTC
class EmailAddressHooksTC(EnvBasedTC):
--- a/sobjects/test/unittest_hooks.py Fri May 29 16:11:49 2009 +0200
+++ b/sobjects/test/unittest_hooks.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import unittest_main
from cubicweb.devtools.apptest import EnvBasedTC
--- a/sobjects/test/unittest_notification.py Fri May 29 16:11:49 2009 +0200
+++ b/sobjects/test/unittest_notification.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,11 @@
# -*- coding: iso-8859-1 -*-
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from socket import gethostname
from logilab.common.testlib import unittest_main, TestCase
--- a/sobjects/test/unittest_supervising.py Fri May 29 16:11:49 2009 +0200
+++ b/sobjects/test/unittest_supervising.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,11 @@
# -*- coding: iso-8859-1 -*-
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
import re
from logilab.common.testlib import unittest_main
--- a/test/data/cubes/file/__pkginfo__.py Fri May 29 16:11:49 2009 +0200
+++ b/test/data/cubes/file/__pkginfo__.py Fri May 29 20:22:39 2009 +0200
@@ -1,5 +1,11 @@
# pylint: disable-msg=W0622
-"""cubicweb-file packaging information"""
+"""cubicweb-file packaging information
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
distname = "cubicweb-file"
modname = distname.split('-', 1)[1]
--- a/test/data/cubes/mycube/__init__.py Fri May 29 16:11:49 2009 +0200
+++ b/test/data/cubes/mycube/__init__.py Fri May 29 20:22:39 2009 +0200
@@ -1,1 +1,7 @@
-"""mycube's __init__"""
+"""mycube's __init__
+
+:organization: Logilab
+:copyright: 2001-2009 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/test/data/cubes/mycube/__pkginfo__.py Fri May 29 16:11:49 2009 +0200
+++ b/test/data/cubes/mycube/__pkginfo__.py Fri May 29 20:22:39 2009 +0200
@@ -1,1 +1,8 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
distname = 'cubicweb-mycube'
--- a/test/data/entities.py Fri May 29 16:11:49 2009 +0200
+++ b/test/data/entities.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb.entities import AnyEntity, fetch_config
class Societe(AnyEntity):
--- a/test/data/erqlexpr_on_ertype.py Fri May 29 16:11:49 2009 +0200
+++ b/test/data/erqlexpr_on_ertype.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
class ToTo(EntityType):
permissions = {
'read': ('managers',),
--- a/test/data/rqlexpr_on_ertype_read.py Fri May 29 16:11:49 2009 +0200
+++ b/test/data/rqlexpr_on_ertype_read.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
class ToTo(EntityType):
permissions = {
'read': ('managers',),
--- a/test/data/rrqlexpr_on_attr.py Fri May 29 16:11:49 2009 +0200
+++ b/test/data/rrqlexpr_on_attr.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
class ToTo(EntityType):
permissions = {
'read': ('managers',),
--- a/test/data/rrqlexpr_on_eetype.py Fri May 29 16:11:49 2009 +0200
+++ b/test/data/rrqlexpr_on_eetype.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
class ToTo(EntityType):
permissions = {
'read': ('managers', RRQLExpression('S bla Y'),),
--- a/test/data/schema.py Fri May 29 16:11:49 2009 +0200
+++ b/test/data/schema.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
class Personne(EntityType):
nom = String(required=True)
prenom = String()
--- a/test/unittest_cwconfig.py Fri May 29 16:11:49 2009 +0200
+++ b/test/unittest_cwconfig.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
import sys
import os
from os.path import dirname, join, abspath
--- a/test/unittest_cwctl.py Fri May 29 16:11:49 2009 +0200
+++ b/test/unittest_cwctl.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
import sys
import os
from cStringIO import StringIO
--- a/test/unittest_dbapi.py Fri May 29 16:11:49 2009 +0200
+++ b/test/unittest_dbapi.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb import ConnectionError
from cubicweb.dbapi import ProgrammingError
from cubicweb.devtools.apptest import EnvBasedTC
--- a/test/unittest_entity.py Fri May 29 16:11:49 2009 +0200
+++ b/test/unittest_entity.py Fri May 29 20:22:39 2009 +0200
@@ -1,5 +1,11 @@
# -*- coding: utf-8 -*-
-"""unit tests for cubicweb.web.views.entities module"""
+"""unit tests for cubicweb.web.views.entities module
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from datetime import datetime
--- a/test/unittest_rset.py Fri May 29 16:11:49 2009 +0200
+++ b/test/unittest_rset.py Fri May 29 20:22:39 2009 +0200
@@ -1,5 +1,11 @@
# coding: utf-8
-"""unit tests for module cubicweb.common.utils"""
+"""unit tests for module cubicweb.common.utils
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from __future__ import with_statement
from logilab.common.testlib import TestCase, unittest_main
--- a/test/unittest_rtags.py Fri May 29 16:11:49 2009 +0200
+++ b/test/unittest_rtags.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import TestCase, unittest_main
from cubicweb.rtags import RelationTags, RelationTagsSet
--- a/test/unittest_schema.py Fri May 29 16:11:49 2009 +0200
+++ b/test/unittest_schema.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""unit tests for module cubicweb.schema"""
+"""unit tests for module cubicweb.schema
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
import sys
from os.path import join, isabs, basename, dirname
--- a/test/unittest_selectors.py Fri May 29 16:11:49 2009 +0200
+++ b/test/unittest_selectors.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""unit tests for selectors mechanism
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
from logilab.common.testlib import TestCase, unittest_main
--- a/test/unittest_utils.py Fri May 29 16:11:49 2009 +0200
+++ b/test/unittest_utils.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""unit tests for module cubicweb.common.utils"""
+"""unit tests for module cubicweb.common.utils
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import TestCase, unittest_main
--- a/test/unittest_vregistry.py Fri May 29 16:11:49 2009 +0200
+++ b/test/unittest_vregistry.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import unittest_main, TestCase
from os.path import join
--- a/toolsutils.py Fri May 29 16:11:49 2009 +0200
+++ b/toolsutils.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""some utilities for cubicweb tools
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/utils.py Fri May 29 16:11:49 2009 +0200
+++ b/utils.py Fri May 29 20:22:39 2009 +0200
@@ -1,15 +1,16 @@
"""Some utilities for CubicWeb server/clients.
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
import locale
from md5 import md5
from datetime import datetime, timedelta, date
-from time import time
+from time import time, mktime
from random import randint, seed
from calendar import monthrange
@@ -37,6 +38,9 @@
assert isinstance(somedate, date), repr(somedate)
return datetime(somedate.year, somedate.month, somedate.day)
+def datetime2ticks(date):
+ return mktime(date.timetuple()) * 1000
+
ONEDAY = timedelta(days=1)
ONEWEEK = timedelta(days=7)
@@ -99,7 +103,7 @@
def make_uid(key):
"""forge a unique identifier"""
- msg = str(key) + "%.10f"%time() + str(randint(0, 1000000))
+ msg = str(key) + "%.10f" % time() + str(randint(0, 1000000))
return md5(msg).hexdigest()
--- a/view.py Fri May 29 16:11:49 2009 +0200
+++ b/view.py Fri May 29 20:22:39 2009 +0200
@@ -2,10 +2,12 @@
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
+_ = unicode
from cStringIO import StringIO
@@ -18,8 +20,6 @@
from cubicweb.appobject import AppRsetObject
from cubicweb.utils import UStringIO, HTMLStream
-_ = unicode
-
# robots control
NOINDEX = u'<meta name="ROBOTS" content="NOINDEX" />'
@@ -206,7 +206,7 @@
# view utilities ##########################################################
- def wview(self, __vid, rset, __fallback_vid=None, **kwargs):
+ def wview(self, __vid, rset=None, __fallback_vid=None, **kwargs):
"""shortcut to self.view method automatically passing self.w as argument
"""
self.view(__vid, rset, __fallback_vid, w=self.w, **kwargs)
@@ -221,21 +221,6 @@
"""simple helper that escapes `data` and writes into `self.w`"""
self.w(html_escape(data))
- def action(self, actionid, row=0):
- """shortcut to get action object with id `actionid`"""
- return self.vreg.select_action(actionid, self.req, self.rset,
- row=row)
-
- def action_url(self, actionid, label=None, row=0):
- """simple method to be able to display `actionid` as a link anywhere
- """
- action = self.vreg.select_action(actionid, self.req, self.rset,
- row=row)
- if action:
- label = label or self.req._(action.title)
- return u'<a href="%s">%s</a>' % (html_escape(action.url()), label)
- return u''
-
def html_headers(self):
"""return a list of html headers (eg something to be inserted between
<head> and </head> of the returned page
--- a/vregistry.py Fri May 29 16:11:49 2009 +0200
+++ b/vregistry.py Fri May 29 20:22:39 2009 +0200
@@ -15,8 +15,9 @@
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/__init__.py Fri May 29 16:11:49 2009 +0200
+++ b/web/__init__.py Fri May 29 20:22:39 2009 +0200
@@ -3,8 +3,9 @@
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
_ = unicode
--- a/web/_exceptions.py Fri May 29 16:11:49 2009 +0200
+++ b/web/_exceptions.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
"""exceptions used in the core of the CubicWeb web application
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/action.py Fri May 29 16:11:49 2009 +0200
+++ b/web/action.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""abstract action classes for CubicWeb web client
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/application.py Fri May 29 16:11:49 2009 +0200
+++ b/web/application.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""CubicWeb web client application object
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/box.py Fri May 29 16:11:49 2009 +0200
+++ b/web/box.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""abstract box classes for CubicWeb web client
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/component.py Fri May 29 16:11:49 2009 +0200
+++ b/web/component.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""abstract component class and base components definition for CubicWeb web client
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/controller.py Fri May 29 16:11:49 2009 +0200
+++ b/web/controller.py Fri May 29 20:22:39 2009 +0200
@@ -2,15 +2,15 @@
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
import datetime
from cubicweb import typed_eid
-from cubicweb.utils import strptime, todate, todatetime
from cubicweb.selectors import yes, require_group_compat
from cubicweb.appobject import AppObject
from cubicweb.web import LOGGER, Redirect, RequestError
@@ -107,35 +107,6 @@
raise RequestError('missing required parameter(s): %s'
% ','.join(missing))
- def parse_datetime(self, value, etype='Datetime'):
- """get a datetime or time from a string (according to etype)
- Datetime formatted as Date are accepted
- """
- assert etype in ('Datetime', 'Date', 'Time'), etype
- # XXX raise proper validation error
- if etype == 'Datetime':
- format = self.req.property_value('ui.datetime-format')
- try:
- return todatetime(strptime(value, format))
- except:
- pass
- elif etype == 'Time':
- format = self.req.property_value('ui.time-format')
- try:
- # (adim) I can't find a way to parse a Time with a custom format
- date = strptime(value, format) # this returns a DateTime
- return datetime.time(date.hour, date.minute, date.second)
- except:
- raise ValueError('can\'t parse %r (expected %s)' % (value, format))
- try:
- format = self.req.property_value('ui.date-format')
- dt = strptime(value, format)
- if etype == 'Datetime':
- return todatetime(dt)
- return todate(dt)
- except:
- raise ValueError('can\'t parse %r (expected %s)' % (value, format))
-
def notify_edited(self, entity):
"""called by edit_entity() to notify which entity is edited"""
--- a/web/data/cubicweb.calendar.css Fri May 29 16:11:49 2009 +0200
+++ b/web/data/cubicweb.calendar.css Fri May 29 20:22:39 2009 +0200
@@ -1,7 +1,7 @@
/* styles for the calendar views
*
* :organization: Logilab
- * :copyright: 2003-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+ * :copyright: 2003-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
* :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
*/
@@ -74,7 +74,7 @@
}
table.omcalendar tr td {
- padding: 3px 0.5em 1em;
+ padding: 3px 0.5em 1em;
}
table.omcalendar tr td div.task {
@@ -82,11 +82,11 @@
height: 2.5ex;
}
-table.omcalendar tr td div.task div.tooltip {
- display: none;
+table.omcalendar tr td div.task div.tooltip {
+ display: none;
}
-table.omcalendar tr td:hover div.task:hover div.tooltip {
+table.omcalendar tr td:hover div.task:hover div.tooltip {
font-style: normal;
display: block;
position: absolute;
@@ -101,6 +101,7 @@
table.omcalendar tr td.outOfRange { background-color: #ddd; }
+table.omcalendar tr td.today { border: 2px solid #2952A3; }
table.omcalendar div.col0 { background-color: #FFB117; }
@@ -138,7 +139,7 @@
min-height: 600px;
width: 100%;
table-layout: auto;
-
+
}
@@ -209,10 +210,10 @@
/******************************************************************************/
table.calendarPageHeader,
-table.smallCalendars,
+table.smallCalendars,
table.bigCalendars {
width: 90%;
- border-collapse:separate;
+ border-collapse:separate;
margin: 0px 1em;
}
@@ -232,20 +233,20 @@
background: #cfceb7;
}
-.calendar th.month a{
+.calendar th.month a{
font: bold 110% Georgia, Verdana;
color : #fff;
}
-table.weekCalendar{
+table.weekCalendar{
}
-table.weekCalendar th{
+table.weekCalendar th{
text-align : left;
padding: 0.6em 0.4em;
}
-table.weekCalendar td{
+table.weekCalendar td{
padding: 0.2em 0.4em }
.semesterCalendar .amCell, .semesterCalendar .amCellEmpty{
@@ -254,7 +255,7 @@
border-right:thin dotted;
}
-table.semesterCalendar th{
+table.semesterCalendar th{
padding: 0.6em 0.4em;
}
@@ -263,25 +264,25 @@
border-left:1px dotted #ccc;
}
-.weeknum{
+.weeknum{
width:10%
}
-.cell, .cellEmpty{
+.cell, .cellEmpty{
border:1px solid #ccc;
padding: 3px 0.5em 2em;
width:10%;
}
-.cellDay{
+.cellDay{
border:1px solid #ccc;
border-bottom : none;
- padding: 3px 0.5em 3px;
+ padding: 3px 0.5em 3px;
width:10%;}
.amCell, .pmCell,
.amCellEmpty, .pmCellEmpty{
- padding: 3px 0.5em 3px;
+ padding: 3px 0.5em 3px;
border:1px solid #ccc;
border-top:none;
width:10%;
@@ -309,22 +310,22 @@
.cell span.cellTitle,
.cellEmpty span.cellTitle {
- background-color:transparent;
+ background-color:transparent;
}
-div.cellContent{
+div.cellContent{
padding: 0.1em;
font-size:90%;
}
-.weeknum, th.weekday{
+.weeknum, th.weekday{
padding:0.2em 0.4em;
color : #666;
font-size:90%;}
-div.event{
+div.event{
padding : 0.1em 0px;
- margin:0.2em 0px;
+ margin:0.2em 0px;
background: #eee;
}
--- a/web/data/cubicweb.python.js Fri May 29 16:11:49 2009 +0200
+++ b/web/data/cubicweb.python.js Fri May 29 20:22:39 2009 +0200
@@ -21,23 +21,23 @@
var res = new Date()
res.setTime(this.getTime() + (days * ONE_DAY))
return res
-}
+};
Date.prototype.sub = function(days) {
return this.add(-days);
-}
+};
Date.prototype.iadd = function(days) {
// in-place add
this.setTime(this.getTime() + (days * ONE_DAY))
// avoid strange rounding problems !!
this.setHours(12);
-}
+};
Date.prototype.isub = function(days) {
// in-place sub
this.setTime(this.getTime() - (days * ONE_DAY))
-}
+};
/*
* returns the first day of the next month
@@ -50,7 +50,7 @@
var d2 = new Date(this.getFullYear(), this.getMonth()+1, 1);
return d2;
}
-}
+};
/*
* returns the day of week, 0 being monday, 6 being sunday
@@ -58,8 +58,15 @@
Date.prototype.getRealDay = function() {
// getDay() returns 0 for Sunday ==> 6 for Saturday
return (this.getDay()+6) % 7;
-}
+};
+Date.prototype.strftime = function(fmt) {
+ if (this.toLocaleFormat !== undefined) { // browser dependent
+ return this.toLocaleFormat(fmt);
+ }
+ // XXX implement at least a decent fallback implementation
+ return this.getFullYear() + '/' + (this.getMonth()+1) + '/' + this.getDate();
+};
var _DATE_FORMAT_REGXES = {
'Y': new RegExp('^-?[0-9]+'),
--- a/web/facet.py Fri May 29 16:11:49 2009 +0200
+++ b/web/facet.py Fri May 29 20:22:39 2009 +0200
@@ -2,13 +2,15 @@
a search
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"
from itertools import chain
from copy import deepcopy
+from datetime import date
from logilab.mtconverter import html_escape
@@ -19,7 +21,7 @@
from rql import parse, nodes
from cubicweb import Unauthorized, typed_eid
-from cubicweb.utils import make_uid
+from cubicweb.utils import datetime2ticks, make_uid, ustrftime
from cubicweb.selectors import match_context_prop, partial_relation_possible
from cubicweb.appobject import AppRsetObject
from cubicweb.web.htmlwidgets import HTMLWidget
@@ -475,29 +477,6 @@
self.attrtype, self.comparator)
-class RangeFacet(AttributeFacet):
-
- def get_widget(self):
- """return the widget instance to use to display this facet
- """
- values = set(value for _, value in self.vocabulary() if value is not None)
- return FacetRangeWidget(self, min(values), max(values))
-
- def add_rql_restrictions(self):
- infvalue = self.req.form.get('%s_inf' % self.id)
- if not infvalue:
- return
- supvalue = self.req.form.get('%s_sup' % self.id)
- self.rqlst.add_constant_restriction(self.filtered_variable,
- self.rtype,
- u'%s' % infvalue,
- 'Float', '>=')
- self.rqlst.add_constant_restriction(self.filtered_variable,
- self.rtype,
- u'%s' % supvalue,
- 'Float', '<=')
-
-
class FilterRQLBuilder(object):
"""called by javascript to get a rql string from filter form"""
@@ -518,6 +497,54 @@
return select.as_string(), toupdate
+class RangeFacet(AttributeFacet):
+ attrtype = 'Float' # only numerical types are supported
+
+ @property
+ def wdgclass(self):
+ return FacetRangeWidget
+
+ def get_widget(self):
+ """return the widget instance to use to display this facet
+ """
+ values = set(value for _, value in self.vocabulary() if value is not None)
+ return self.wdgclass(self, min(values), max(values))
+
+ def infvalue(self):
+ return self.req.form.get('%s_inf' % self.id)
+
+ def supvalue(self):
+ return self.req.form.get('%s_sup' % self.id)
+
+ def formatvalue(self, value):
+ return unicode(value)
+
+ def add_rql_restrictions(self):
+ infvalue = self.infvalue()
+ if infvalue is None: # nothing sent
+ return
+ supvalue = self.supvalue()
+ self.rqlst.add_constant_restriction(self.filtered_variable,
+ self.rtype,
+ self.formatvalue(infvalue),
+ self.attrtype, '>=')
+ self.rqlst.add_constant_restriction(self.filtered_variable,
+ self.rtype,
+ self.formatvalue(supvalue),
+ self.attrtype, '<=')
+
+class DateRangeFacet(RangeFacet):
+ attrtype = 'Date' # only date types are supported
+
+ @property
+ def wdgclass(self):
+ fmt = self.req.property_value('ui.date-format')
+ self.req.html_headers.define_var('DATE_FMT', fmt)
+ return DateFacetRangeWidget
+
+ def formatvalue(self, value):
+ return '"%s"' % date.fromtimestamp(float(value) / 1000).strftime('%Y/%m/%d')
+
## html widets ################################################################
class FacetVocabularyWidget(HTMLWidget):
@@ -549,7 +576,7 @@
cssclass += ' overflowed'
self.w(u'<div class="facetBody%s">\n' % cssclass)
for item in self.items:
- item.render(self.w)
+ item.render(w=self.w)
self.w(u'</div>\n')
self.w(u'</div>\n')
@@ -576,11 +603,15 @@
min: %(minvalue)s,
max: %(maxvalue)s,
values: [%(minvalue)s, %(maxvalue)s],
+ stop: function(event, ui) { // submit when the user stops sliding
+ var form = $('#%(sliderid)s').closest('form');
+ buildRQL.apply(null, evalJSON(form.attr('cubicweb:facetargs')));
+ },
slide: function(event, ui) {
- $('#%(sliderid)s_inf').html(ui.values[0]);
- $('#%(sliderid)s_sup').html(ui.values[1]);
- $('input[name=%(facetid)s_inf]').val(ui.values[0]);
- $('input[name=%(facetid)s_sup]').val(ui.values[1]);
+ $('#%(sliderid)s_inf').html(ui.values[0]);
+ $('#%(sliderid)s_sup').html(ui.values[1]);
+ $('input[name=%(facetid)s_inf]').val(ui.values[0]);
+ $('input[name=%(facetid)s_sup]').val(ui.values[1]);
}
});
'''
@@ -589,6 +620,9 @@
self.minvalue = minvalue
self.maxvalue = maxvalue
+ def formatvalue(self, value):
+ return value
+
def _render(self):
facet = self.facet
facet.req.add_js('ui.slider.js')
@@ -606,7 +640,8 @@
self.w(u'<div class="facetTitle" cubicweb:facetName="%s">%s</div>\n' %
(facetid, title))
self.w(u'<span id="%s_inf">%s</span> - <span id="%s_sup">%s</span>'
- % (sliderid, self.minvalue, sliderid, self.maxvalue))
+ % (sliderid, self.formatvalue(self.minvalue),
+ sliderid, self.formatvalue(self.maxvalue)))
self.w(u'<input type="hidden" name="%s_inf" value="%s" />'
% (facetid, self.minvalue))
self.w(u'<input type="hidden" name="%s_sup" value="%s" />'
@@ -615,6 +650,35 @@
self.w(u'</div>\n')
+class DateFacetRangeWidget(FacetRangeWidget):
+ onload = u'''
+ jQuery("#%(sliderid)s").slider({
+ range: true,
+ min: %(minvalue)s,
+ max: %(maxvalue)s,
+ values: [%(minvalue)s, %(maxvalue)s],
+ stop: function(event, ui) { // submit when the user stops sliding
+UI = ui;
+ var form = $('#%(sliderid)s').closest('form');
+ buildRQL.apply(null, evalJSON(form.attr('cubicweb:facetargs')));
+ },
+ slide: function(event, ui) {
+ $('#%(sliderid)s_inf').html( (new Date(ui.values[0])).strftime(DATE_FMT));
+ $('#%(sliderid)s_sup').html( (new Date(ui.values[1])).strftime(DATE_FMT));
+ $('input[name=%(facetid)s_inf]').val(ui.values[0]);
+ $('input[name=%(facetid)s_sup]').val(ui.values[1]);
+ }
+ });
+'''
+ def __init__(self, facet, minvalue, maxvalue):
+ super(DateFacetRangeWidget, self).__init__(facet,
+ datetime2ticks(minvalue),
+ datetime2ticks(maxvalue))
+ def formatvalue(self, value):
+ datefmt = self.facet.req.property_value('ui.date-format')
+ return ustrftime(date.fromtimestamp(float(value) / 1000), datefmt)
+
+
class FacetItem(HTMLWidget):
selected_img = "black-check.png"
@@ -648,4 +712,3 @@
def _render(self):
pass
-
--- a/web/form.py Fri May 29 16:11:49 2009 +0200
+++ b/web/form.py Fri May 29 20:22:39 2009 +0200
@@ -1,33 +1,23 @@
"""abstract form classes for CubicWeb web client
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
-from warnings import warn
-
-from logilab.common.compat import any
-from logilab.common.decorators import iclassmethod
-
from cubicweb.appobject import AppRsetObject
-from cubicweb.selectors import yes, non_final_entity, match_kwargs, one_line_rset
from cubicweb.view import NOINDEX, NOFOLLOW
from cubicweb.common import tags
-from cubicweb.web import INTERNAL_FIELD_VALUE, eid_param, stdmsgs
-from cubicweb.web.httpcache import NoHTTPCacheManager
-from cubicweb.web.controller import NAV_FORM_PARAMETERS
-from cubicweb.web.formfields import (Field, StringField, RelationField,
- HiddenInitialValueField)
-from cubicweb.web import formrenderers
-from cubicweb.web import formwidgets as fwdgs
+from cubicweb.web import stdmsgs, httpcache, formfields
+
class FormViewMixIn(object):
"""abstract form view mix-in"""
category = 'form'
controller = 'edit'
- http_cache_manager = NoHTTPCacheManager
+ http_cache_manager = httpcache.NoHTTPCacheManager
add_to_breadcrumbs = False
def html_headers(self):
@@ -90,7 +80,7 @@
domid = 'entityForm'
category = 'form'
controller = 'edit'
- http_cache_manager = NoHTTPCacheManager
+ http_cache_manager = httpcache.NoHTTPCacheManager
add_to_breadcrumbs = False
def html_headers(self):
@@ -198,7 +188,7 @@
if hasattr(base, '_fields_'):
allfields += base._fields_
clsfields = (item for item in classdict.items()
- if isinstance(item[1], Field))
+ if isinstance(item[1], formfields.Field))
for fieldname, field in sorted(clsfields, key=lambda x: x[1].creation_rank):
if not field.name:
field.set_name(fieldname)
@@ -212,491 +202,6 @@
found
"""
-class FieldsForm(FormMixIn, AppRsetObject):
+class Form(FormMixIn, AppRsetObject):
__metaclass__ = metafieldsform
__registry__ = 'forms'
- __select__ = yes()
-
- renderer_cls = formrenderers.FormRenderer
- is_subform = False
-
- # attributes overrideable through __init__
- internal_fields = ('__errorurl',) + NAV_FORM_PARAMETERS
- needs_js = ('cubicweb.ajax.js', 'cubicweb.edition.js',)
- needs_css = ('cubicweb.form.css',)
- domid = 'form'
- title = None
- action = None
- onsubmit = "return freezeFormButtons('%(domid)s');"
- cssclass = None
- cssstyle = None
- cwtarget = None
- redirect_path = None
- set_error_url = True
- copy_nav_params = False
- form_buttons = None # form buttons (button widgets instances)
-
- def __init__(self, req, rset=None, row=None, col=None, submitmsg=None,
- **kwargs):
- super(FieldsForm, self).__init__(req, rset, row=row, col=col)
- self.fields = list(self.__class__._fields_)
- for key, val in kwargs.items():
- if key in NAV_FORM_PARAMETERS:
- self.form_add_hidden(key, val)
- else:
- assert hasattr(self.__class__, key) and not key[0] == '_', key
- setattr(self, key, val)
- if self.set_error_url:
- self.form_add_hidden('__errorurl', self.session_key())
- if self.copy_nav_params:
- for param in NAV_FORM_PARAMETERS:
- if not param in kwargs:
- value = req.form.get(param)
- if value:
- self.form_add_hidden(param, value)
- if submitmsg is not None:
- self.form_add_hidden('__message', submitmsg)
- self.context = None
- if 'domid' in kwargs:# session key changed
- self.restore_previous_post(self.session_key())
-
- @iclassmethod
- def field_by_name(cls_or_self, name, role='subject'):
- """return field with the given name and role.
- Raise FieldNotFound if the field can't be found.
- """
- if isinstance(cls_or_self, type):
- fields = cls_or_self._fields_
- else:
- fields = cls_or_self.fields
- for field in fields:
- if field.name == name and field.role == role:
- return field
- raise FieldNotFound(name)
-
- @iclassmethod
- def fields_by_name(cls_or_self, name, role='subject'):
- """return a list of fields with the given name and role"""
- if isinstance(cls_or_self, type):
- fields = cls_or_self._fields_
- else:
- fields = cls_or_self.fields
- return [field for field in fields
- if field.name == name and field.role == role]
-
- @iclassmethod
- def remove_field(cls_or_self, field):
- """remove a field from form class or instance"""
- if isinstance(cls_or_self, type):
- fields = cls_or_self._fields_
- else:
- fields = cls_or_self.fields
- fields.remove(field)
-
- @iclassmethod
- def append_field(cls_or_self, field):
- """append a field to form class or instance"""
- if isinstance(cls_or_self, type):
- fields = cls_or_self._fields_
- else:
- fields = cls_or_self.fields
- fields.append(field)
-
- @property
- def form_needs_multipart(self):
- """true if the form needs enctype=multipart/form-data"""
- return any(field.needs_multipart for field in self.fields)
-
- def form_add_hidden(self, name, value=None, **kwargs):
- """add an hidden field to the form"""
- field = StringField(name=name, widget=fwdgs.HiddenInput, initial=value,
- **kwargs)
- if 'id' in kwargs:
- # by default, hidden input don't set id attribute. If one is
- # explicitly specified, ensure it will be set
- field.widget.setdomid = True
- self.append_field(field)
- return field
-
- def add_media(self):
- """adds media (CSS & JS) required by this widget"""
- if self.needs_js:
- self.req.add_js(self.needs_js)
- if self.needs_css:
- self.req.add_css(self.needs_css)
-
- def form_render(self, **values):
- """render this form, using the renderer given in args or the default
- FormRenderer()
- """
- renderer = values.pop('renderer', self.renderer_cls())
- return renderer.render(self, values)
-
- def form_build_context(self, rendervalues=None):
- """build form context values (the .context attribute which is a
- dictionary with field instance as key associated to a dictionary
- containing field 'name' (qualified), 'id', 'value' (for display, always
- a string).
-
- rendervalues is an optional dictionary containing extra kwargs given to
- form_render()
- """
- self.context = context = {}
- # ensure rendervalues is a dict
- if rendervalues is None:
- rendervalues = {}
- # use a copy in case fields are modified while context is build (eg
- # __linkto handling for instance)
- for field in self.fields[:]:
- for field in field.actual_fields(self):
- field.form_init(self)
- value = self.form_field_display_value(field, rendervalues)
- context[field] = {'value': value,
- 'name': self.form_field_name(field),
- 'id': self.form_field_id(field),
- }
-
- def form_field_display_value(self, field, rendervalues, load_bytes=False):
- """return field's *string* value to use for display
-
- looks in
- 1. previously submitted form values if any (eg on validation error)
- 2. req.form
- 3. extra kw args given to render_form
- 4. field's typed value
-
- values found in 1. and 2. are expected te be already some 'display'
- value while those found in 3. and 4. are expected to be correctly typed.
- """
- value = self._req_display_value(field)
- if value is None:
- if field.name in rendervalues:
- value = rendervalues[field.name]
- else:
- value = self.form_field_value(field, load_bytes)
- if callable(value):
- value = value(self)
- if value != INTERNAL_FIELD_VALUE:
- value = field.format_value(self.req, value)
- return value
-
- def _req_display_value(self, field):
- qname = self.form_field_name(field)
- if qname in self.form_previous_values:
- return self.form_previous_values[qname]
- if qname in self.req.form:
- return self.req.form[qname]
- if field.name in self.req.form:
- return self.req.form[field.name]
- return None
-
- def form_field_value(self, field, load_bytes=False):
- """return field's *typed* value"""
- myattr = '%s_%s_default' % (field.role, field.name)
- if hasattr(self, myattr):
- return getattr(self, myattr)()
- value = field.initial
- if callable(value):
- value = value(self)
- return value
-
- def form_field_error(self, field):
- """return validation error for widget's field, if any"""
- if self._field_has_error(field):
- self.form_displayed_errors.add(field.name)
- return u'<span class="error">%s</span>' % self.form_valerror.errors[field.name]
- return u''
-
- def form_field_format(self, field):
- """return MIME type used for the given (text or bytes) field"""
- return self.req.property_value('ui.default-text-format')
-
- def form_field_encoding(self, field):
- """return encoding used for the given (text) field"""
- return self.req.encoding
-
- def form_field_name(self, field):
- """return qualified name for the given field"""
- return field.name
-
- def form_field_id(self, field):
- """return dom id for the given field"""
- return field.id
-
- def form_field_vocabulary(self, field, limit=None):
- """return vocabulary for the given field. Should be overriden in
- specific forms using fields which requires some vocabulary
- """
- raise NotImplementedError
-
- def _field_has_error(self, field):
- """return true if the field has some error in given validation exception
- """
- return self.form_valerror and field.name in self.form_valerror.errors
-
-
-class EntityFieldsForm(FieldsForm):
- __select__ = (match_kwargs('entity') | (one_line_rset & non_final_entity()))
-
- internal_fields = FieldsForm.internal_fields + ('__type', 'eid', '__maineid')
- domid = 'entityForm'
-
- def __init__(self, *args, **kwargs):
- self.edited_entity = kwargs.pop('entity', None)
- msg = kwargs.pop('submitmsg', None)
- super(EntityFieldsForm, self).__init__(*args, **kwargs)
- if self.edited_entity is None:
- self.edited_entity = self.complete_entity(self.row or 0, self.col or 0)
- self.form_add_hidden('__type', eidparam=True)
- self.form_add_hidden('eid')
- if msg:
- # If we need to directly attach the new object to another one
- self.form_add_hidden('__message', msg)
- if not self.is_subform:
- for linkto in self.req.list_form_param('__linkto'):
- self.form_add_hidden('__linkto', linkto)
- msg = '%s %s' % (msg, self.req._('and linked'))
- # in case of direct instanciation
- self.schema = self.edited_entity.schema
- self.vreg = self.edited_entity.vreg
-
- def _field_has_error(self, field):
- """return true if the field has some error in given validation exception
- """
- return super(EntityFieldsForm, self)._field_has_error(field) \
- and self.form_valerror.eid == self.edited_entity.eid
-
- def _relation_vocabulary(self, rtype, targettype, role,
- limit=None, done=None):
- """return unrelated entities for a given relation and target entity type
- for use in vocabulary
- """
- if done is None:
- done = set()
- rset = self.edited_entity.unrelated(rtype, targettype, role, limit)
- res = []
- for entity in rset.entities():
- if entity.eid in done:
- continue
- done.add(entity.eid)
- res.append((entity.view('combobox'), entity.eid))
- return res
-
- def _req_display_value(self, field):
- value = super(EntityFieldsForm, self)._req_display_value(field)
- if value is None:
- value = self.edited_entity.linked_to(field.name, field.role)
- if value:
- searchedvalues = ['%s:%s:%s' % (field.name, eid, field.role)
- for eid in value]
- # remove associated __linkto hidden fields
- for field in self.fields_by_name('__linkto'):
- if field.initial in searchedvalues:
- self.remove_field(field)
- else:
- value = None
- return value
-
- def _form_field_default_value(self, field, load_bytes):
- defaultattr = 'default_%s' % field.name
- if hasattr(self.edited_entity, defaultattr):
- # XXX bw compat, default_<field name> on the entity
- warn('found %s on %s, should be set on a specific form'
- % (defaultattr, self.edited_entity.id), DeprecationWarning)
- value = getattr(self.edited_entity, defaultattr)
- if callable(value):
- value = value()
- else:
- value = super(EntityFieldsForm, self).form_field_value(field,
- load_bytes)
- return value
-
- def form_build_context(self, values=None):
- """overriden to add edit[s|o] hidden fields and to ensure schema fields
- have eidparam set to True
-
- edit[s|o] hidden fields are used to indicate the value for the
- associated field before the (potential) modification made when
- submitting the form.
- """
- eschema = self.edited_entity.e_schema
- for field in self.fields[:]:
- for field in field.actual_fields(self):
- fieldname = field.name
- if fieldname != 'eid' and (
- (eschema.has_subject_relation(fieldname) or
- eschema.has_object_relation(fieldname))):
- field.eidparam = True
- self.fields.append(HiddenInitialValueField(field))
- return super(EntityFieldsForm, self).form_build_context(values)
-
- def form_field_value(self, field, load_bytes=False):
- """return field's *typed* value
-
- overriden to deal with
- * special eid / __type / edits- / edito- fields
- * lookup for values on edited entities
- """
- attr = field.name
- entity = self.edited_entity
- if attr == 'eid':
- return entity.eid
- if not field.eidparam:
- return super(EntityFieldsForm, self).form_field_value(field, load_bytes)
- if attr.startswith('edits-') or attr.startswith('edito-'):
- # edit[s|o]- fieds must have the actual value stored on the entity
- assert hasattr(field, 'visible_field')
- vfield = field.visible_field
- assert vfield.eidparam
- if entity.has_eid():
- return self.form_field_value(vfield)
- return INTERNAL_FIELD_VALUE
- if attr == '__type':
- return entity.id
- if self.schema.rschema(attr).is_final():
- attrtype = entity.e_schema.destination(attr)
- if attrtype == 'Password':
- return entity.has_eid() and INTERNAL_FIELD_VALUE or ''
- if attrtype == 'Bytes':
- if entity.has_eid():
- if load_bytes:
- return getattr(entity, attr)
- # XXX value should reflect if some file is already attached
- return True
- return False
- if entity.has_eid() or attr in entity:
- value = getattr(entity, attr)
- else:
- value = self._form_field_default_value(field, load_bytes)
- return value
- # non final relation field
- if entity.has_eid() or entity.relation_cached(attr, field.role):
- value = [r[0] for r in entity.related(attr, field.role)]
- else:
- value = self._form_field_default_value(field, load_bytes)
- return value
-
- def form_field_format(self, field):
- """return MIME type used for the given (text or bytes) field"""
- entity = self.edited_entity
- if field.eidparam and entity.e_schema.has_metadata(field.name, 'format') and (
- entity.has_eid() or '%s_format' % field.name in entity):
- return self.edited_entity.attr_metadata(field.name, 'format')
- return self.req.property_value('ui.default-text-format')
-
- def form_field_encoding(self, field):
- """return encoding used for the given (text) field"""
- entity = self.edited_entity
- if field.eidparam and entity.e_schema.has_metadata(field.name, 'encoding') and (
- entity.has_eid() or '%s_encoding' % field.name in entity):
- return self.edited_entity.attr_metadata(field.name, 'encoding')
- return super(EntityFieldsForm, self).form_field_encoding(field)
-
- def form_field_name(self, field):
- """return qualified name for the given field"""
- if field.eidparam:
- return eid_param(field.name, self.edited_entity.eid)
- return field.name
-
- def form_field_id(self, field):
- """return dom id for the given field"""
- if field.eidparam:
- return eid_param(field.id, self.edited_entity.eid)
- return field.id
-
- def form_field_vocabulary(self, field, limit=None):
- """return vocabulary for the given field"""
- role, rtype = field.role, field.name
- method = '%s_%s_vocabulary' % (role, rtype)
- try:
- vocabfunc = getattr(self, method)
- except AttributeError:
- try:
- # XXX bw compat, <role>_<rtype>_vocabulary on the entity
- vocabfunc = getattr(self.edited_entity, method)
- except AttributeError:
- vocabfunc = getattr(self, '%s_relation_vocabulary' % role)
- else:
- warn('found %s on %s, should be set on a specific form'
- % (method, self.edited_entity.id), DeprecationWarning)
- # NOTE: it is the responsibility of `vocabfunc` to sort the result
- # (direclty through RQL or via a python sort). This is also
- # important because `vocabfunc` might return a list with
- # couples (label, None) which act as separators. In these
- # cases, it doesn't make sense to sort results afterwards.
- return vocabfunc(rtype, limit)
-
- def subject_relation_vocabulary(self, rtype, limit=None):
- """defaut vocabulary method for the given relation, looking for
- relation's object entities (i.e. self is the subject)
- """
- entity = self.edited_entity
- if isinstance(rtype, basestring):
- rtype = entity.schema.rschema(rtype)
- done = None
- assert not rtype.is_final(), rtype
- if entity.has_eid():
- done = set(e.eid for e in getattr(entity, str(rtype)))
- result = []
- rsetsize = None
- for objtype in rtype.objects(entity.e_schema):
- if limit is not None:
- rsetsize = limit - len(result)
- result += self._relation_vocabulary(rtype, objtype, 'subject',
- rsetsize, done)
- if limit is not None and len(result) >= limit:
- break
- return result
-
- def object_relation_vocabulary(self, rtype, limit=None):
- """defaut vocabulary method for the given relation, looking for
- relation's subject entities (i.e. self is the object)
- """
- entity = self.edited_entity
- if isinstance(rtype, basestring):
- rtype = entity.schema.rschema(rtype)
- done = None
- if entity.has_eid():
- done = set(e.eid for e in getattr(entity, 'reverse_%s' % rtype))
- result = []
- rsetsize = None
- for subjtype in rtype.subjects(entity.e_schema):
- if limit is not None:
- rsetsize = limit - len(result)
- result += self._relation_vocabulary(rtype, subjtype, 'object',
- rsetsize, done)
- if limit is not None and len(result) >= limit:
- break
- return result
-
- def subject_in_state_vocabulary(self, rtype, limit=None):
- """vocabulary method for the in_state relation, looking for relation's
- object entities (i.e. self is the subject) according to initial_state,
- state_of and next_state relation
- """
- entity = self.edited_entity
- if not entity.has_eid() or not entity.in_state:
- # get the initial state
- rql = 'Any S where S state_of ET, ET name %(etype)s, ET initial_state S'
- rset = self.req.execute(rql, {'etype': str(entity.e_schema)})
- if rset:
- return [(rset.get_entity(0, 0).view('combobox'), rset[0][0])]
- return []
- results = []
- for tr in entity.in_state[0].transitions(entity):
- state = tr.destination_state[0]
- results.append((state.view('combobox'), state.eid))
- return sorted(results)
-
-
-class CompositeForm(FieldsForm):
- """form composed for sub-forms"""
-
- def __init__(self, *args, **kwargs):
- super(CompositeForm, self).__init__(*args, **kwargs)
- self.forms = []
-
- def form_add_subform(self, subform):
- """mark given form as a subform and append it"""
- subform.is_subform = True
- self.forms.append(subform)
--- a/web/formfields.py Fri May 29 16:11:49 2009 +0200
+++ b/web/formfields.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""field classes for form construction
:organization: Logilab
-:copyright: 2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2009 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
"""
__docformat__ = "restructuredtext en"
@@ -19,6 +20,7 @@
HiddenInput, TextInput, FileInput, PasswordInput, TextArea, FCKEditor,
Radio, Select, DateTimePicker)
+
class Field(object):
"""field class is introduced to control what's displayed in forms. It makes
the link between something to edit and its display in the form. Actual
@@ -79,16 +81,13 @@
self.label = label or name
self.help = help
self.required = required
- if widget is not None:
- self.widget = widget
- if isinstance(self.widget, type):
- self.widget = self.widget()
self.initial = initial
self.choices = choices
self.sort = sort
self.internationalizable = internationalizable
self.eidparam = eidparam
self.role = role
+ self.init_widget(widget)
# ordering number for this field instance
self.creation_rank = Field.__creation_rank
Field.__creation_rank += 1
@@ -101,6 +100,14 @@
def __repr__(self):
return self.__unicode__().encode('utf-8')
+ def init_widget(self, widget):
+ if widget is None and self.choices:
+ widget = Select()
+ if widget is not None:
+ self.widget = widget
+ if isinstance(self.widget, type):
+ self.widget = self.widget()
+
def set_name(self, name):
"""automatically set .id and .label when name is set"""
assert name
@@ -176,10 +183,21 @@
"""
pass
+
class StringField(Field):
+ widget = TextArea
+
def __init__(self, max_length=None, **kwargs):
+ self.max_length = max_length # must be set before super call
super(StringField, self).__init__(**kwargs)
- self.max_length = max_length
+
+ def init_widget(self, widget):
+ if widget is None:
+ if self.choices:
+ widget = Select()
+ elif self.max_length and self.max_length < 257:
+ widget = TextInput()
+ super(StringField, self).init_widget(widget)
if isinstance(self.widget, TextArea):
self.init_text_area(self.widget)
@@ -222,7 +240,6 @@
else:
# else we want a format selector
fkwargs['widget'] = Select()
- fkwargs['widget'].attrs['size'] = 1
fcstr = FormatConstraint()
fkwargs['choices'] = fcstr.vocabulary(req=req)
fkwargs['internationalizable'] = True
@@ -341,6 +358,7 @@
self.widget.attrs.setdefault('size', 5)
self.widget.attrs.setdefault('maxlength', 15)
+
class BooleanField(Field):
widget = Radio
@@ -380,6 +398,7 @@
format_prop = 'ui.datetime-format'
widget = TextInput
+
class HiddenInitialValueField(Field):
def __init__(self, visible_field):
name = 'edit%s-%s' % (visible_field.role[0], visible_field.name)
@@ -469,18 +488,11 @@
# init StringField parameters according to constraints
for cstr in constraints:
if isinstance(cstr, StaticVocabularyConstraint):
- kwargs.setdefault('widget', Select())
kwargs.setdefault('choices', cstr.vocabulary)
- if card in '?1':
- if isinstance(kwargs['widget'], type):
- kwargs['widget'] = kwargs['widget']()
- kwargs['widget'].attrs.setdefault('size', 1)
+ break
for cstr in constraints:
if isinstance(cstr, SizeConstraint) and cstr.max is not None:
- if cstr.max < 257:
- kwargs.setdefault('widget', TextInput())
kwargs['max_length'] = cstr.max
- kwargs.setdefault('widget', TextArea())
return StringField(**kwargs)
if fieldclass is FileField:
for metadata in ('format', 'encoding'):
@@ -492,6 +504,7 @@
kwargs['role'] = role
return RelationField.fromcardinality(card, **kwargs)
+
FIELDS = {
'Boolean': BooleanField,
'Bytes': FileField,
--- a/web/formrenderers.py Fri May 29 16:11:49 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,479 +0,0 @@
-"""form renderers, responsible to layout a form to html
-
-:organization: Logilab
-:copyright: 2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
-"""
-__docformat__ = "restructuredtext en"
-
-from logilab.common import dictattr
-from logilab.mtconverter import html_escape
-
-from simplejson import dumps
-
-from cubicweb.common import tags
-from cubicweb.web import eid_param
-from cubicweb.web import formwidgets as fwdgs
-from cubicweb.web.widgets import checkbox
-from cubicweb.web.formfields import HiddenInitialValueField
-
-
-class FormRenderer(object):
- """basic renderer displaying fields in a two columns table label | value
-
- +--------------+--------------+
- | field1 label | field1 input |
- +--------------+--------------+
- | field1 label | field2 input |
- +--------------+--------------+
- +---------+
- | buttons |
- +---------+
- """
- _options = ('display_fields', 'display_label', 'display_help',
- 'display_progress_div', 'table_class', 'button_bar_class')
- display_fields = None # None -> all fields
- display_label = True
- display_help = True
- display_progress_div = True
- table_class = u'attributeForm'
- button_bar_class = u'formButtonBar'
-
- def __init__(self, **kwargs):
- if self._set_options(kwargs):
- raise ValueError('unconsumed arguments %s' % kwargs)
-
- def _set_options(self, kwargs):
- for key in self._options:
- try:
- setattr(self, key, kwargs.pop(key))
- except KeyError:
- continue
- return kwargs
-
- # renderer interface ######################################################
-
- def render(self, form, values):
- self._set_options(values)
- form.add_media()
- data = []
- w = data.append
- w(self.open_form(form, values))
- if self.display_progress_div:
- w(u'<div id="progress">%s</div>' % form.req._('validating...'))
- w(u'<fieldset>')
- w(tags.input(type=u'hidden', name=u'__form_id',
- value=values.get('formvid', form.id)))
- if form.redirect_path:
- w(tags.input(type='hidden', name='__redirectpath', value=form.redirect_path))
- self.render_fields(w, form, values)
- self.render_buttons(w, form)
- w(u'</fieldset>')
- w(u'</form>')
- errormsg = self.error_message(form)
- if errormsg:
- data.insert(0, errormsg)
- return '\n'.join(data)
-
- def render_label(self, form, field):
- label = form.req._(field.label)
- attrs = {'for': form.context[field]['id']}
- if field.required:
- attrs['class'] = 'required'
- return tags.label(label, **attrs)
-
- def render_help(self, form, field):
- help = []
- descr = field.help
- if descr:
- help.append('<div class="helper">%s</div>' % form.req._(descr))
- example = field.example_format(form.req)
- if example:
- help.append('<div class="helper">(%s: %s)</div>'
- % (form.req._('sample format'), example))
- return u' '.join(help)
-
- # specific methods (mostly to ease overriding) #############################
-
- def error_message(self, form):
- """return formatted error message
-
- This method should be called once inlined field errors has been consumed
- """
- req = form.req
- errex = form.form_valerror
- # get extra errors
- if errex is not None:
- errormsg = req._('please correct the following errors:')
- displayed = form.form_displayed_errors
- errors = sorted((field, err) for field, err in errex.errors.items()
- if not field in displayed)
- if errors:
- if len(errors) > 1:
- templstr = '<li>%s</li>\n'
- else:
- templstr = ' %s\n'
- for field, err in errors:
- if field is None:
- errormsg += templstr % err
- else:
- errormsg += templstr % '%s: %s' % (req._(field), err)
- if len(errors) > 1:
- errormsg = '<ul>%s</ul>' % errormsg
- return u'<div class="errorMessage">%s</div>' % errormsg
- return u''
-
- def open_form(self, form, values):
- if form.form_needs_multipart:
- enctype = 'multipart/form-data'
- else:
- enctype = 'application/x-www-form-urlencoded'
- if form.action is None:
- action = form.req.build_url('edit')
- else:
- action = form.action
- tag = ('<form action="%s" method="post" enctype="%s"' % (
- html_escape(action or '#'), enctype))
- if form.domid:
- tag += ' id="%s"' % form.domid
- if form.onsubmit:
- tag += ' onsubmit="%s"' % html_escape(form.onsubmit % dictattr(form))
- if form.cssstyle:
- tag += ' style="%s"' % html_escape(form.cssstyle)
- if form.cssclass:
- tag += ' class="%s"' % html_escape(form.cssclass)
- if form.cwtarget:
- tag += ' cubicweb:target="%s"' % html_escape(form.cwtarget)
- return tag + '>'
-
- def display_field(self, form, field):
- if isinstance(field, HiddenInitialValueField):
- field = field.visible_field
- return (self.display_fields is None
- or field.name in form.internal_fields
- or (field.name, field.role) in self.display_fields
- or (field.name, field.role) in form.internal_fields)
-
- def render_fields(self, w, form, values):
- form.form_build_context(values)
- fields = self._render_hidden_fields(w, form)
- if fields:
- self._render_fields(fields, w, form)
- self.render_child_forms(w, form, values)
-
- def render_child_forms(self, w, form, values):
- # render
- for childform in getattr(form, 'forms', []):
- self.render_fields(w, childform, values)
-
- def _render_hidden_fields(self, w, form):
- fields = form.fields[:]
- for field in form.fields:
- if not self.display_field(form, field):
- fields.remove(field)
- elif not field.is_visible():
- w(field.render(form, self))
- fields.remove(field)
- return fields
-
- def _render_fields(self, fields, w, form):
- w(u'<table class="%s">' % self.table_class)
- for field in fields:
- w(u'<tr>')
- if self.display_label:
- w(u'<th class="labelCol">%s</th>' % self.render_label(form, field))
- error = form.form_field_error(field)
- if error:
- w(u'<td class="error">')
- w(error)
- else:
- w(u'<td>')
- w(field.render(form, self))
- if self.display_help:
- w(self.render_help(form, field))
- w(u'</td></tr>')
- w(u'</table>')
-
- def render_buttons(self, w, form):
- w(u'<table class="%s">\n<tr>\n' % self.button_bar_class)
- for button in form.form_buttons:
- w(u'<td>%s</td>\n' % button.render(form))
- w(u'</tr></table>')
-
-
-class HTableFormRenderer(FormRenderer):
- """display fields horizontally in a table
-
- +--------------+--------------+---------+
- | field1 label | field2 label | |
- +--------------+--------------+---------+
- | field1 input | field2 input | buttons
- +--------------+--------------+---------+
- """
- display_help = False
- def _render_fields(self, fields, w, form):
- w(u'<table border="0">')
- w(u'<tr>')
- for field in fields:
- if self.display_label:
- w(u'<th class="labelCol">%s</th>' % self.render_label(form, field))
- if self.display_help:
- w(self.render_help(form, field))
- # empty slot for buttons
- w(u'<th class="labelCol"> </th>')
- w(u'</tr>')
- w(u'<tr>')
- for field in fields:
- error = form.form_field_error(field)
- if error:
- w(u'<td class="error">')
- w(error)
- else:
- w(u'<td>')
- w(field.render(form, self))
- w(u'</td>')
- w(u'<td>')
- for button in form.form_buttons:
- w(button.render(form))
- w(u'</td>')
- w(u'</tr>')
- w(u'</table>')
-
- def render_buttons(self, w, form):
- pass
-
-
-class EntityCompositeFormRenderer(FormRenderer):
- """specific renderer for multiple entities edition form (muledit)"""
-
- def render_fields(self, w, form, values):
- if not form.is_subform:
- w(u'<table class="listing">')
- super(EntityCompositeFormRenderer, self).render_fields(w, form, values)
- if not form.is_subform:
- w(u'</table>')
-
- def _render_fields(self, fields, w, form):
- if form.is_subform:
- 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))
- w(u'<tr class="%s">' % (entity.row % 2 and u'even' or u'odd'))
- # XXX turn this into a widget used on the eid field
- w(u'<td>%s</td>' % checkbox('eid', entity.eid, checked=qeid in values))
- for field in fields:
- error = form.form_field_error(field)
- if error:
- w(u'<td class="error">')
- w(error)
- else:
- w(u'<td>')
- if isinstance(field.widget, (fwdgs.Select, fwdgs.CheckBox, fwdgs.Radio)):
- field.widget.attrs['onchange'] = cbsetstate
- elif isinstance(field.widget, fwdgs.Input):
- field.widget.attrs['onkeypress'] = cbsetstate
- w(u'<div>%s</div>' % field.render(form, self))
- w(u'</td>')
- else:
- # main form, display table headers
- w(u'<tr class="header">')
- w(u'<th align="left">%s</th>'
- % tags.input(type='checkbox', title=form.req._('toggle check boxes'),
- onclick="setCheckboxesState('eid', this.checked)"))
- for field in self.forms[0].fields:
- if self.display_field(form, field) and field.is_visible():
- w(u'<th>%s</th>' % form.req._(field.label))
- w(u'</tr>')
-
-
-
-class EntityFormRenderer(FormRenderer):
- """specific renderer for entity edition form (edition)"""
- _options = FormRenderer._options + ('display_relations_form',)
- display_relations_form = True
-
- def render(self, form, values):
- rendered = super(EntityFormRenderer, self).render(form, values)
- return rendered + u'</div>' # close extra div introducted by open_form
-
- def open_form(self, form, values):
- attrs_fs_label = ('<div class="iformTitle"><span>%s</span></div>'
- % form.req._('main informations'))
- attrs_fs_label += '<div class="formBody">'
- return attrs_fs_label + super(EntityFormRenderer, self).open_form(form, values)
-
- def render_fields(self, w, form, values):
- super(EntityFormRenderer, self).render_fields(w, form, values)
- self.inline_entities_form(w, form)
- if form.edited_entity.has_eid() and self.display_relations_form:
- self.relations_form(w, form)
-
- def _render_fields(self, fields, w, form):
- if not form.edited_entity.has_eid() or form.edited_entity.has_perm('update'):
- super(EntityFormRenderer, self)._render_fields(fields, w, form)
-
- def render_buttons(self, w, form):
- if len(form.form_buttons) == 3:
- w("""<table width="100%%">
- <tbody>
- <tr><td align="center">
- %s
- </td><td style="align: right; width: 50%%;">
- %s
- %s
- </td></tr>
- </tbody>
- </table>""" % tuple(button.render(form) for button in form.form_buttons))
- else:
- super(EntityFormRenderer, self).render_buttons(w, form)
-
- def relations_form(self, w, form):
- srels_by_cat = form.srelations_by_category('generic', 'add')
- if not srels_by_cat:
- return u''
- req = form.req
- _ = req._
- label = u'%s :' % _('This %s' % form.edited_entity.e_schema).capitalize()
- eid = form.edited_entity.eid
- w(u'<fieldset class="subentity">')
- w(u'<legend class="iformTitle">%s</legend>' % label)
- w(u'<table id="relatedEntities">')
- for rschema, target, related in form.relations_table():
- # already linked entities
- if related:
- w(u'<tr><th class="labelCol">%s</th>' % rschema.display_name(req, target))
- w(u'<td>')
- w(u'<ul>')
- for viewparams in related:
- w(u'<li class="invisible">%s<div id="span%s" class="%s">%s</div></li>'
- % (viewparams[1], viewparams[0], viewparams[2], viewparams[3]))
- if not form.force_display and form.maxrelitems < len(related):
- link = (u'<span class="invisible">'
- '[<a href="javascript: window.location.href+=\'&__force_display=1\'">%s</a>]'
- '</span>' % form.req._('view all'))
- w(u'<li class="invisible">%s</li>' % link)
- w(u'</ul>')
- w(u'</td>')
- w(u'</tr>')
- pendings = list(form.restore_pending_inserts())
- if not pendings:
- w(u'<tr><th> </th><td> </td></tr>')
- else:
- for row in pendings:
- # soon to be linked to entities
- w(u'<tr id="tr%s">' % row[1])
- w(u'<th>%s</th>' % row[3])
- w(u'<td>')
- w(u'<a class="handle" title="%s" href="%s">[x]</a>' %
- (_('cancel this insert'), row[2]))
- w(u'<a id="a%s" class="editionPending" href="%s">%s</a>'
- % (row[1], row[4], html_escape(row[5])))
- w(u'</td>')
- w(u'</tr>')
- w(u'<tr id="relationSelectorRow_%s" class="separator">' % eid)
- w(u'<th class="labelCol">')
- w(u'<span>%s</span>' % _('add relation'))
- w(u'<select id="relationSelector_%s" tabindex="%s" '
- 'onchange="javascript:showMatchingSelect(this.options[this.selectedIndex].value,%s);">'
- % (eid, req.next_tabindex(), html_escape(dumps(eid))))
- w(u'<option value="">%s</option>' % _('select a relation'))
- for i18nrtype, rschema, target in srels_by_cat:
- # more entities to link to
- w(u'<option value="%s_%s">%s</option>' % (rschema, target, i18nrtype))
- w(u'</select>')
- w(u'</th>')
- w(u'<td id="unrelatedDivs_%s"></td>' % eid)
- w(u'</tr>')
- w(u'</table>')
- w(u'</fieldset>')
-
- def inline_entities_form(self, w, form):
- """create a form to edit entity's inlined relations"""
- if not hasattr(form, 'inlined_relations'):
- return
- entity = form.edited_entity
- __ = form.req.__
- for rschema, targettypes, role in form.inlined_relations():
- # show inline forms only if there's one possible target type
- # for rschema
- if len(targettypes) != 1:
- self.warning('entity related by the %s relation should have '
- 'inlined form but there is multiple target types, '
- 'dunno what to do', rschema)
- continue
- targettype = targettypes[0].type
- if form.should_inline_relation_form(rschema, targettype, role):
- w(u'<div id="inline%sslot">' % rschema)
- existant = entity.has_eid() and entity.related(rschema)
- if existant:
- # display inline-edition view for all existing related entities
- w(form.view('inline-edition', existant, rtype=rschema, role=role,
- ptype=entity.e_schema, peid=entity.eid))
- if role == 'subject':
- card = rschema.rproperty(entity.e_schema, targettype, 'cardinality')[0]
- else:
- card = rschema.rproperty(targettype, entity.e_schema, 'cardinality')[1]
- # there is no related entity and we need at least one: we need to
- # display one explicit inline-creation view
- if form.should_display_inline_creation_form(rschema, existant, card):
- w(form.view('inline-creation', None, etype=targettype,
- peid=entity.eid, ptype=entity.e_schema,
- rtype=rschema, role=role))
- # we can create more than one related entity, we thus display a link
- # to add new related entities
- if form.should_display_add_new_relation_link(rschema, existant, card):
- divid = "addNew%s%s%s:%s" % (targettype, rschema, role, entity.eid)
- w(u'<div class="inlinedform" id="%s" cubicweb:limit="true">'
- % divid)
- js = "addInlineCreationForm('%s', '%s', '%s', '%s')" % (
- entity.eid, targettype, rschema, role)
- if card in '1?':
- js = "toggleVisibility('%s'); %s" % (divid, js)
- w(u'<a class="addEntity" id="add%s:%slink" href="javascript: %s" >+ %s.</a>'
- % (rschema, entity.eid, js, __('add a %s' % targettype)))
- w(u'</div>')
- w(u'<div class="trame_grise"> </div>')
- w(u'</div>')
-
-
-class EntityInlinedFormRenderer(EntityFormRenderer):
- """specific renderer for entity inlined edition form
- (inline-[creation|edition])
- """
- def render(self, form, values):
- form.add_media()
- data = []
- w = data.append
- try:
- w(u'<div id="div-%(divid)s" onclick="%(divonclick)s">' % values)
- except KeyError:
- w(u'<div id="div-%(divid)s">' % values)
- else:
- w(u'<div id="notice-%s" class="notice">%s</div>' % (
- values['divid'], form.req._('click on the box to cancel the deletion')))
- w(u'<div class="iformBody">')
- values['removemsg'] = form.req.__('remove this %s' % form.edited_entity.e_schema)
- w(u'<div class="iformTitle"><span>%(title)s</span> '
- '#<span class="icounter">1</span> '
- '[<a href="javascript: %(removejs)s;noop();">%(removemsg)s</a>]</div>'
- % values)
- # cleanup values
- for key in ('title', 'removejs', 'removemsg'):
- values.pop(key)
- self.render_fields(w, form, values)
- w(u'</div></div>')
- return '\n'.join(data)
-
- def render_fields(self, w, form, values):
- form.form_build_context(values)
- w(u'<fieldset id="fs-%(divid)s">' % values)
- fields = self._render_hidden_fields(w, form)
- w(u'</fieldset>')
- w(u'<fieldset class="subentity">')
- if fields:
- self._render_fields(fields, w, form)
- self.render_child_forms(w, form, values)
- self.inline_entities_form(w, form)
- w(u'</fieldset>')
-
--- a/web/formwidgets.py Fri May 29 16:11:49 2009 +0200
+++ b/web/formwidgets.py Fri May 29 20:22:39 2009 +0200
@@ -1,12 +1,14 @@
"""widget classes for form construction
:organization: Logilab
-:copyright: 2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2009 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
"""
__docformat__ = "restructuredtext en"
from datetime import date
+from warnings import warn
from cubicweb.common import tags
from cubicweb.web import stdmsgs, INTERNAL_FIELD_VALUE
@@ -109,6 +111,11 @@
return u'\n'.join(inputs)
+class PasswordSingleInput(Input):
+ """<input type='password'> without a confirmation field"""
+ type = 'password'
+
+
class FileInput(Input):
"""<input type='file'>"""
type = 'file'
@@ -170,8 +177,8 @@
def render(self, form, field):
name, curvalues, attrs = self._render_attrs(form, field)
- if not 'size' in attrs and self._multiple:
- attrs['size'] = '5'
+ if not 'size' in attrs:
+ attrs['size'] = self._multiple and '5' or '1'
options = []
optgroup_opened = False
for label, value in field.vocabulary(form):
@@ -299,6 +306,17 @@
wdgtype = 'SuggestField'
loadtype = 'auto'
+ def __init__(self, *args, **kwargs):
+ try:
+ self.autocomplete_initfunc = kwargs.pop('autocomplete_initfunc')
+ except KeyError:
+ warn('use autocomplete_initfunc argument of %s constructor '
+ 'instead of relying on autocomplete_initfuncs dictionary on '
+ 'the entity class' % self.__class__.__name__,
+ DeprecationWarning)
+ self.autocomplete_initfunc = None
+ super(AutoCompletionWidget, self).__init__(*args, **kwargs)
+
def _render_attrs(self, form, field):
name, values, attrs = super(AutoCompletionWidget, self)._render_attrs(form, field)
init_ajax_attributes(attrs, self.wdgtype, self.loadtype)
@@ -307,7 +325,11 @@
return name, values, attrs
def _get_url(self, entity, field):
- fname = entity.autocomplete_initfuncs[field.name]
+ if self.autocomplete_initfunc is None:
+ # XXX for bw compat
+ fname = entity.autocomplete_initfuncs[field.name]
+ else:
+ fname = self.autocomplete_initfunc
return entity.req.build_url('json', fname=fname, mode='remote',
pageid=entity.req.pageid)
@@ -317,7 +339,12 @@
wdgtype = 'StaticFileSuggestField'
def _get_url(self, entity, field):
- return entity.req.datadir_url + entity.autocomplete_initfuncs[field.name]
+ if self.autocomplete_initfunc is None:
+ # XXX for bw compat
+ fname = entity.autocomplete_initfuncs[field.name]
+ else:
+ fname = self.autocomplete_initfunc
+ return entity.req.datadir_url + fname
class RestrictedAutoCompletionWidget(AutoCompletionWidget):
--- a/web/htmlwidgets.py Fri May 29 16:11:49 2009 +0200
+++ b/web/htmlwidgets.py Fri May 29 20:22:39 2009 +0200
@@ -4,8 +4,9 @@
serialization time
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
from logilab.mtconverter import html_escape
--- a/web/httpcache.py Fri May 29 16:11:49 2009 +0200
+++ b/web/httpcache.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/request.py Fri May 29 16:11:49 2009 +0200
+++ b/web/request.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""abstract class for http request
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/test/data/schema/testschema.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/data/schema/testschema.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
class Salesterm(EntityType):
described_by_test = SubjectRelation('File', cardinality='1*', composite='subject')
amount = Int(constraints=[IntervalBoundConstraint(0, 100)])
--- a/web/test/data/views.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/data/views.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb.web import Redirect
from cubicweb.web.application import CubicWebPublisher
--- a/web/test/test_views.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/test_views.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""automatic tests"""
+"""automatic tests
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb.devtools.testlib import WebTest, AutomaticWebTest
from cubicweb.view import AnyRsetView
--- a/web/test/unittest_application.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/unittest_application.py Fri May 29 20:22:39 2009 +0200
@@ -1,5 +1,11 @@
# -*- coding: iso-8859-1 -*-
-"""unit tests for cubicweb.web.application"""
+"""unit tests for cubicweb.web.application
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import TestCase, unittest_main
import base64, Cookie
--- a/web/test/unittest_controller.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/unittest_controller.py Fri May 29 20:22:39 2009 +0200
@@ -1,5 +1,6 @@
"""cubicweb.web.controller unit tests
+:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
from datetime import datetime, date, time
--- a/web/test/unittest_form.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/unittest_form.py Fri May 29 20:22:39 2009 +0200
@@ -1,13 +1,22 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
+
from logilab.common.testlib import unittest_main, mock_object
+
from cubicweb import Binary
from cubicweb.devtools.testlib import WebTest
-from cubicweb.web.form import EntityFieldsForm, FieldsForm
-from cubicweb.web.formrenderers import FormRenderer
from cubicweb.web.formfields import (IntField, StringField, RichTextField,
DateTimeField, DateTimePicker,
FileField, EditableFileField)
from cubicweb.web.formwidgets import PasswordInput
+from cubicweb.web.views.forms import EntityFieldsForm, FieldsForm
from cubicweb.web.views.workflow import ChangeStateForm
+from cubicweb.web.views.formrenderers import FormRenderer
class FieldsFormTC(WebTest):
@@ -26,7 +35,6 @@
super(EntityFieldsFormTC, self).setUp()
self.req = self.request()
self.entity = self.user(self.req)
- self.renderer = FormRenderer()
def test_form_field_vocabulary_unrelated(self):
b = self.add_entity('BlogEntry', title=u'di mascii code', content=u'a best-seller')
@@ -116,7 +124,8 @@
def _render_entity_field(self, name, form):
form.form_build_context({})
- return form.field_by_name(name).render(form, self.renderer)
+ renderer = FormRenderer(self.req)
+ return form.field_by_name(name).render(form, renderer)
def _test_richtextfield(self, expected):
class RTFForm(EntityFieldsForm):
@@ -146,8 +155,8 @@
def test_filefield(self):
class FFForm(EntityFieldsForm):
- data = FileField(format_field=StringField(name='data_format'),
- encoding_field=StringField(name='data_encoding'))
+ data = FileField(format_field=StringField(name='data_format', max_length=50),
+ encoding_field=StringField(name='data_encoding', max_length=20))
file = self.add_entity('File', name=u"pouet.txt", data_encoding=u'UTF-8',
data=Binary('new widgets system'))
form = FFForm(self.req, redirect_path='perdu.com', entity=file)
@@ -155,8 +164,8 @@
'''<input id="data:%(eid)s" name="data:%(eid)s" tabindex="0" type="file" value=""/>
<a href="javascript: toggleVisibility('data:%(eid)s-advanced')" title="show advanced fields"><img src="http://testing.fr/cubicweb/data/puce_down.png" alt="show advanced fields"/></a>
<div id="data:%(eid)s-advanced" class="hidden">
-<label for="data_format:%(eid)s">data_format</label><input id="data_format:%(eid)s" name="data_format:%(eid)s" tabindex="1" type="text" value="text/plain"/><br/><br/>
-<label for="data_encoding:%(eid)s">data_encoding</label><input id="data_encoding:%(eid)s" name="data_encoding:%(eid)s" tabindex="2" type="text" value="UTF-8"/><br/><br/>
+<label for="data_format:%(eid)s">data_format</label><input id="data_format:%(eid)s" name="data_format:%(eid)s" tabindex="1" type="text" value="text/plain"/><br/>
+<label for="data_encoding:%(eid)s">data_encoding</label><input id="data_encoding:%(eid)s" name="data_encoding:%(eid)s" tabindex="2" type="text" value="UTF-8"/><br/>
</div>
<br/>
<input name="data:%(eid)s__detach" type="checkbox"/>
@@ -166,8 +175,8 @@
def test_editablefilefield(self):
class EFFForm(EntityFieldsForm):
- data = EditableFileField(format_field=StringField(name='data_format'),
- encoding_field=StringField(name='data_encoding'))
+ data = EditableFileField(format_field=StringField(name='data_format', max_length=50),
+ encoding_field=StringField(name='data_encoding', max_length=20))
def form_field_encoding(self, field):
return 'ascii'
def form_field_format(self, field):
@@ -179,8 +188,8 @@
'''<input id="data:%(eid)s" name="data:%(eid)s" tabindex="0" type="file" value=""/>
<a href="javascript: toggleVisibility('data:%(eid)s-advanced')" title="show advanced fields"><img src="http://testing.fr/cubicweb/data/puce_down.png" alt="show advanced fields"/></a>
<div id="data:%(eid)s-advanced" class="hidden">
-<label for="data_format:%(eid)s">data_format</label><input id="data_format:%(eid)s" name="data_format:%(eid)s" tabindex="1" type="text" value="text/plain"/><br/><br/>
-<label for="data_encoding:%(eid)s">data_encoding</label><input id="data_encoding:%(eid)s" name="data_encoding:%(eid)s" tabindex="2" type="text" value="UTF-8"/><br/><br/>
+<label for="data_format:%(eid)s">data_format</label><input id="data_format:%(eid)s" name="data_format:%(eid)s" tabindex="1" type="text" value="text/plain"/><br/>
+<label for="data_encoding:%(eid)s">data_encoding</label><input id="data_encoding:%(eid)s" name="data_encoding:%(eid)s" tabindex="2" type="text" value="UTF-8"/><br/>
</div>
<br/>
<input name="data:%(eid)s__detach" type="checkbox"/>
--- a/web/test/unittest_formfields.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/unittest_formfields.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""unittests for cw.web.formfields"""
+"""unittests for cw.web.formfields
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import TestCase, unittest_main
@@ -6,9 +12,9 @@
from cubicweb.devtools import TestServerConfiguration
from cubicweb.devtools.testlib import EnvBasedTC
-from cubicweb.web.form import EntityFieldsForm
from cubicweb.web.formwidgets import PasswordInput, TextArea, Select
from cubicweb.web.formfields import *
+from cubicweb.web.views.forms import EntityFieldsForm
from cubes.file.entities import File
--- a/web/test/unittest_magicsearch.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/unittest_magicsearch.py Fri May 29 20:22:39 2009 +0200
@@ -1,5 +1,11 @@
# -*- coding: utf-8 -*-
-"""Unit tests for magic_search service"""
+"""Unit tests for magic_search service
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
import sys
--- a/web/test/unittest_urlpublisher.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/unittest_urlpublisher.py Fri May 29 20:22:39 2009 +0200
@@ -1,5 +1,11 @@
# -*- coding: utf-8 -*-
-"""Unit tests for url publishing service"""
+"""Unit tests for url publishing service
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
import re
--- a/web/test/unittest_urlrewrite.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/unittest_urlrewrite.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import TestCase, unittest_main
from cubicweb.devtools._apptest import FakeRequest
--- a/web/test/unittest_views_actions.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/unittest_views_actions.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import unittest_main
from cubicweb.devtools.apptest import EnvBasedTC
--- a/web/test/unittest_views_apacherewrite.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/unittest_views_apacherewrite.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import TestCase, unittest_main
from cubicweb.web.views.apacherewrite import *
@@ -16,22 +23,23 @@
rules=[('/(.*)', r'/m_%(cat)s/\1')]),
]
urlrewriter = MyAppRules()
+ req = None # not used in the above rules, so keep a simple TestCase here
try:
- urlrewriter.rewrite('logilab.fr', '/whatever')
+ urlrewriter.rewrite('logilab.fr', '/whatever', req)
self.fail('redirect exception expected')
except Redirect, ex:
self.assertEquals(ex.location, 'http://www.logilab.fr/whatever')
- self.assertEquals(urlrewriter.rewrite('www.logilab.fr', '/whatever'),
+ self.assertEquals(urlrewriter.rewrite('www.logilab.fr', '/whatever', req),
'/whatever')
- self.assertEquals(urlrewriter.rewrite('www.logilab.fr', '/json/bla'),
+ self.assertEquals(urlrewriter.rewrite('www.logilab.fr', '/json/bla', req),
'/json/bla')
- self.assertEquals(urlrewriter.rewrite('abcd.logilab.fr', '/json/bla'),
+ self.assertEquals(urlrewriter.rewrite('abcd.logilab.fr', '/json/bla', req),
'/json/bla')
- self.assertEquals(urlrewriter.rewrite('abcd.logilab.fr', '/data/bla'),
+ self.assertEquals(urlrewriter.rewrite('abcd.logilab.fr', '/data/bla', req),
'/data/bla')
- self.assertEquals(urlrewriter.rewrite('abcd.logilab.fr', '/whatever'),
+ self.assertEquals(urlrewriter.rewrite('abcd.logilab.fr', '/whatever', req),
'/m_abcd/whatever')
- self.assertEquals(urlrewriter.rewrite('abcd.fr', '/whatever'),
+ self.assertEquals(urlrewriter.rewrite('abcd.fr', '/whatever', req),
'/whatever')
--- a/web/test/unittest_views_basecontrollers.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/unittest_views_basecontrollers.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""cubicweb.web.views.basecontrollers unit tests"""
+"""cubicweb.web.views.basecontrollers unit tests
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
import simplejson
from logilab.common.testlib import unittest_main, mock_object
--- a/web/test/unittest_views_baseforms.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/unittest_views_baseforms.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""cubicweb.web.views.baseforms unit tests"""
+"""cubicweb.web.views.baseforms unit tests
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from StringIO import StringIO
from datetime import date
--- a/web/test/unittest_views_basetemplates.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/unittest_views_basetemplates.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb.devtools.testlib import WebTest
from cubicweb.devtools.htmlparser import DTDValidator
--- a/web/test/unittest_views_baseviews.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/unittest_views_baseviews.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from simplejson import loads
from logilab.common.testlib import unittest_main
--- a/web/test/unittest_views_editforms.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/unittest_views_editforms.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import unittest_main
from cubicweb.devtools.apptest import EnvBasedTC
from cubicweb.devtools.testlib import WebTest
--- a/web/test/unittest_views_embeding.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/unittest_views_embeding.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import TestCase, unittest_main
--- a/web/test/unittest_views_navigation.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/unittest_views_navigation.py Fri May 29 20:22:39 2009 +0200
@@ -1,4 +1,10 @@
-"""cubicweb.web.views.navigation unit tests"""
+"""cubicweb.web.views.navigation unit tests
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import unittest_main, mock_object
from cubicweb.devtools.apptest import EnvBasedTC
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/test/unittest_views_pyviews.py Fri May 29 20:22:39 2009 +0200
@@ -0,0 +1,25 @@
+from logilab.common.testlib import unittest_main
+from cubicweb.devtools.apptest import EnvBasedTC
+
+class PyViewsTC(EnvBasedTC):
+
+ def test_pyvaltable(self):
+ content = self.vreg.view('pyvaltable', self.request(),
+ pyvalue=[[1, 'a'], [2, 'b']],
+ headers=['num', 'char'])
+ self.assertEquals(content.strip(), '''<table class="listing">
+<tr><th>num</th><th>char</th></tr>
+<tr><td>1</td><td>a</td></tr>
+<tr><td>2</td><td>b</td></tr>
+</table>''')
+
+ def test_pyvallist(self):
+ content = self.vreg.view('pyvallist', self.request(),
+ pyvalue=[1, 'a'])
+ self.assertEquals(content.strip(), '''<ul>
+<li>1</li>
+<li>a</li>
+</ul>''')
+
+if __name__ == '__main__':
+ unittest_main()
--- a/web/test/unittest_views_searchrestriction.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/unittest_views_searchrestriction.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from cubicweb.devtools.apptest import EnvBasedTC
from cubicweb.web.facet import insert_attr_select_relation, prepare_facets_rqlst
--- a/web/test/unittest_viewselector.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/unittest_viewselector.py Fri May 29 20:22:39 2009 +0200
@@ -1,5 +1,6 @@
# -*- coding: iso-8859-1 -*-
"""XXX rename, split, reorganize this
+:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
from logilab.common.testlib import unittest_main
--- a/web/test/unittest_web.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/unittest_web.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
from logilab.common.testlib import TestCase, unittest_main
from cubicweb.web import ajax_replace_url as arurl
class AjaxReplaceUrlTC(TestCase):
--- a/web/test/unittest_webconfig.py Fri May 29 16:11:49 2009 +0200
+++ b/web/test/unittest_webconfig.py Fri May 29 20:22:39 2009 +0200
@@ -1,3 +1,10 @@
+"""
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
import os
from logilab.common.testlib import TestCase, unittest_main
--- a/web/test/unittest_widgets.py Fri May 29 16:11:49 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,369 +0,0 @@
-"""cubicweb.common.widget unit tests"""
-
-from datetime import datetime
-NOW = datetime.now()
-
-from logilab.common.testlib import unittest_main
-from cubicweb.devtools.apptest import EnvBasedTC
-
-from cubicweb.common.mttransforms import HAS_TAL
-from cubicweb.web.widgets import widget, AutoCompletionWidget
-
-
-class WidgetsTC(EnvBasedTC):
-
- def get_widget(self, etype, rname, rtype):
- rschema = self.schema[rname]
- return widget(self.vreg, etype, rschema, rtype, role='subject')
-
-
- def test_hidden_widget(self):
- w = self.get_widget('State', 'eid', 'Int')
- self.assertEquals(w.name, 'eid')
- self.assertEquals(w.render_example(self.request()), '')
- self.assertDictEquals(w.attrs, {})
- entity = self.etype_instance('State')
- entity.eid = 'X'
- self.assertEquals(w.required(entity), True)
- self.assertEquals(w.render(entity), '')
- self.assertEquals(w.edit_render(entity),
- u'<input type="hidden" name="eid" value="X" />')
-
- def test_textarea_widget(self):
- self.add_entity('CWProperty', pkey=u'ui.fckeditor', value=u'')
- self.commit()
- w = self.get_widget('State', 'description', 'String')
- self.assertEquals(w.name, 'description')
- self.assertEquals(w.render_example(self.request()), '')
- self.assertDictEquals(w.attrs, {'accesskey': 'd'})
- entity = self.etype_instance('State')
- entity.eid = 'X'
- entity
- self.assertEquals(w.required(entity), False)
- self.assertEquals(w.render(entity), '')
- if HAS_TAL:
- tal_format = u'\n<option value="text/cubicweb-page-template" >text/cubicweb-page-template</option>'
- else:
- tal_format = u''
- self.assertTextEquals(w.edit_render(entity),
- u'''<input type="hidden" name="edits-description:X" value="__cubicweb_internal_field__"/>
-<input type="hidden" name="edits-description_format:X" value="__cubicweb_internal_field__"/>
-
-<select name="description_format:X" id="description_format:X" tabindex="0">
-<option value="text/rest" >text/rest</option>
-<option value="text/html" selected="selected">text/html</option>
-<option value="text/plain" >text/plain</option>%s
-</select><br/><textarea onkeypress="autogrow(this)" name="description:X" accesskey="d" cols="80" id="description:X" rows="20" tabindex="1"></textarea>''' % tal_format)
-
- def test_textarea_widget_previous_value(self):
- self.add_entity('CWProperty', pkey=u'ui.fckeditor', value=u'')
- self.commit()
- w = self.get_widget('State', 'description', 'String')
- req = self.request()
- req.data['formvalues'] = {'description:X': 'a description'}
- entity = self.etype_instance('State', req)
- entity.eid = 'X'
- self.assertEquals(w.required(entity), False)
- self.assertEquals(w.render(entity), '')
- if HAS_TAL:
- tal_format = u'\n<option value="text/cubicweb-page-template" >text/cubicweb-page-template</option>'
- else:
- tal_format = u''
- self.assertTextEquals(w.edit_render(entity),
- u'''<input type="hidden" name="edits-description:X" value="__cubicweb_internal_field__"/>
-<input type="hidden" name="edits-description_format:X" value="__cubicweb_internal_field__"/>
-
-<select name="description_format:X" id="description_format:X" tabindex="0">
-<option value="text/rest" >text/rest</option>
-<option value="text/html" selected="selected">text/html</option>
-<option value="text/plain" >text/plain</option>%s
-</select><br/><textarea onkeypress="autogrow(this)" name="description:X" accesskey="d" cols="80" id="description:X" rows="20" tabindex="1">a description</textarea>''' % tal_format)
-
- def test_fckeditor_widget(self):
- w = self.get_widget('State', 'description', 'String')
- req = self.request()
- entity = self.etype_instance('State', req)
- entity.eid = 'X'
- self.assertEquals(w.required(entity), False)
- self.assertEquals(w.render(entity), '')
- self.assertTextEquals(w.edit_render(entity),
- u'''<input type="hidden" name="edits-description:X" value="__cubicweb_internal_field__"/>
-<input type="hidden" name="edits-description_format:X" value=""/>
-<input type="hidden" name="description_format:X" value="text/html"/>
-<textarea cubicweb:type="wysiwyg" onkeypress="autogrow(this)" name="description:X" accesskey="d" cols="80" id="description:X" rows="20" tabindex="0"></textarea>''')
-
- def test_string_widget(self):
- w = self.get_widget('Personne', 'nom', 'String')
- self.assertEquals(w.name, 'nom')
- self.assertEquals(w.render_example(self.request()), '')
- self.assertDictEquals(w.attrs, {'accesskey': 'n', 'maxlength': 64, 'size': 40})
- entity = self.etype_instance('Personne')
- entity.eid = 'X'
- self.assertEquals(w.required(entity), True)
- self.assertEquals(w.render(entity), '')
- self.assertEquals(w.edit_render(entity),
- u'<input type="hidden" name="edits-nom:X" value="__cubicweb_internal_field__"/>\n'
- '<input type="text" name="nom:X" value="" accesskey="n" id="nom:X" maxlength="64" size="40" tabindex="0"/>')
-
- def test_string_widget_previous_value(self):
- w = self.get_widget('Personne', 'nom', 'String')
- self.assertEquals(w.name, 'nom')
- self.assertEquals(w.render_example(self.request()), '')
- self.assertDictEquals(w.attrs, {'accesskey': 'n', 'maxlength': 64, 'size': 40})
- req = self.request()
- req.data['formvalues'] = {'nom:X': 'a name'}
- entity = self.etype_instance('Personne', req)
- entity.eid = 'X'
- self.assertEquals(w.required(entity), True)
- self.assertEquals(w.render(entity), '')
- self.assertEquals(w.edit_render(entity),
- u'<input type="hidden" name="edits-nom:X" value="__cubicweb_internal_field__"/>\n'
- '<input type="text" name="nom:X" value="a name" accesskey="n" id="nom:X" maxlength="64" size="40" tabindex="0"/>')
-
- def test_static_combo_widget(self):
- w = self.get_widget('Personne', 'promo', 'String')
- self.assertEquals(w.name, 'promo')
- self.assertEquals(w.render_example(self.request()), '')
- self.assertDictEquals(w.attrs, {})
- entity = self.etype_instance('Personne')
- entity.eid = 'X'
- self.assertEquals(w.required(entity), False)
- self.assertEquals(w.render(entity), '')
- self.assertTextEquals(w.edit_render(entity),
- u'<input type="hidden" name="edits-promo:X" value="__cubicweb_internal_field__"/>\n\n'
- '<select name="promo:X" id="promo:X" tabindex="0">\n'
- '<option value="bon" >bon</option>\n'
- '<option value="pasbon" >pasbon</option>\n'
- '</select>')
-
- def test_static_combo_widget_previous_value(self):
- w = self.get_widget('Personne', 'promo', 'String')
- self.assertEquals(w.name, 'promo')
- self.assertEquals(w.render_example(self.request()), '')
- self.assertDictEquals(w.attrs, {})
- req = self.request()
- req.data['formvalues'] = {'promo:X': 'pasbon'}
- entity = self.etype_instance('Personne', req)
- entity.eid = 'X'
- self.assertEquals(w.required(entity), False)
- self.assertEquals(w.render(entity), '')
- self.assertTextEquals(w.edit_render(entity),
- u'<input type="hidden" name="edits-promo:X" value="__cubicweb_internal_field__"/>\n\n'
- '<select name="promo:X" id="promo:X" tabindex="0">\n'
- '<option value="bon" >bon</option>\n'
- '<option value="pasbon" selected="selected">pasbon</option>\n'
- '</select>')
-
- def test_integer_widget(self):
- w = self.get_widget('Personne', 'tel', 'Int')
- self.assertEquals(w.name, 'tel')
- self.assertEquals(w.render_example(self.request()), '23')
- self.assertDictEquals(w.attrs, {'accesskey': 't', 'maxlength': 15, 'size': 5})
- entity = self.etype_instance('Personne')
- entity.eid = 'X'
- self.assertEquals(w.required(entity), False)
- self.assertEquals(w.render(entity), '')
- self.assertEquals(w.edit_render(entity),
- u'<input type="hidden" name="edits-tel:X" value="__cubicweb_internal_field__"/>\n'
- '<input type="text" name="tel:X" value="" accesskey="t" id="tel:X" maxlength="15" size="5" tabindex="0"/>')
-
- def test_integer_widget_previous_value(self):
- w = self.get_widget('Personne', 'tel', 'Int')
- self.assertEquals(w.name, 'tel')
- self.assertEquals(w.render_example(self.request()), '23')
- self.assertDictEquals(w.attrs, {'accesskey': 't', 'maxlength': 15, 'size': 5})
- req = self.request()
- req.data['formvalues'] = {'tel:X': '0123456789'}
- entity = self.etype_instance('Personne', req)
- entity.eid = 'X'
- self.assertEquals(w.required(entity), False)
- self.assertEquals(w.render(entity), '')
- self.assertEquals(w.edit_render(entity),
- u'<input type="hidden" name="edits-tel:X" value="__cubicweb_internal_field__"/>\n'
- '<input type="text" name="tel:X" value="0123456789" accesskey="t" id="tel:X" maxlength="15" size="5" tabindex="0"/>')
-
- def test_datetime_widget(self):
- w = self.get_widget('Personne', 'datenaiss', 'Datetime')
- self.assertEquals(w.name, 'datenaiss')
- example = '%s, or without time: %s' % (
- NOW.strftime(self.vreg.property_value('ui.datetime-format')),
- NOW.strftime(self.vreg.property_value('ui.date-format')))
- self.assertEquals(w.render_example(self.request()), example)
- self.assertDictEquals(w.attrs, {'accesskey': 'd', 'maxlength': 16, 'size': 16})
- entity = self.etype_instance('Personne')
- entity.eid = 'X'
- self.assertEquals(w.required(entity), False)
- self.assertEquals(w.render(entity), '')
- self.assertEquals(w.edit_render(entity),
- u'<input type="hidden" name="edits-datenaiss:X" value="__cubicweb_internal_field__"/>\n'
- '<input type="text" name="datenaiss:X" value="" accesskey="d" id="datenaiss:X" maxlength="16" size="16" tabindex="0"/>'
- '<a onclick="toggleCalendar(\'datenaiss:Xhelper\', \'datenaiss:X\', %s, %s);" class="calhelper">\n<img src="http://testing.fr/cubicweb/data/calendar.gif" title="calendar" alt="" /></a><div class="calpopup hidden" id="datenaiss:Xhelper"></div>' % (NOW.year, NOW.month))
-
- def test_datetime_widget_previous_value(self):
- w = self.get_widget('Personne', 'datenaiss', 'Datetime')
- self.assertEquals(w.name, 'datenaiss')
- self.assertDictEquals(w.attrs, {'accesskey': 'd', 'maxlength': 16, 'size': 16})
- req = self.request()
- req.data['formvalues'] = {'datenaiss:X': '2000/01/01'}
- entity = self.etype_instance('Personne', req)
- entity.eid = 'X'
- self.assertEquals(w.required(entity), False)
- self.assertEquals(w.render(entity), '')
- self.assertEquals(w.edit_render(entity),
- u'<input type="hidden" name="edits-datenaiss:X" value="__cubicweb_internal_field__"/>\n'
- '<input type="text" name="datenaiss:X" value="2000/01/01" accesskey="d" id="datenaiss:X" maxlength="16" size="16" tabindex="0"/>'
- '<a onclick="toggleCalendar(\'datenaiss:Xhelper\', \'datenaiss:X\', %s, %s);" class="calhelper">\n<img src="http://testing.fr/cubicweb/data/calendar.gif" title="calendar" alt="" /></a><div class="calpopup hidden" id="datenaiss:Xhelper"></div>' % (NOW.year, NOW.month))
-
-
-
- def test_float_widget(self):
- w = self.get_widget('Personne', 'salary', 'Float')
- self.assertEquals(w.name, 'salary')
- format = self.vreg.property_value('ui.float-format')
- self.assertEquals(w.render_example(self.request()), format % 1.23)
- self.assertDictEquals(w.attrs, {'accesskey': 's', 'maxlength': 15, 'size': 5})
- entity = self.etype_instance('Personne')
- entity.eid = 'X'
- self.assertEquals(w.required(entity), False)
- self.assertEquals(w.render(entity), '')
- self.assertEquals(w.edit_render(entity),
- u'<input type="hidden" name="edits-salary:X" value="__cubicweb_internal_field__"/>\n'
- '<input type="text" name="salary:X" value="" accesskey="s" id="salary:X" maxlength="15" size="5" tabindex="0"/>')
-
-
- def test_float_widget_previous_value(self):
- w = self.get_widget('Personne', 'salary', 'Float')
- self.assertEquals(w.name, 'salary')
- format = self.vreg.property_value('ui.float-format')
- self.assertEquals(w.render_example(self.request()), format % 1.23)
- self.assertDictEquals(w.attrs, {'accesskey': 's', 'maxlength': 15, 'size': 5})
- req = self.request()
- req.data['formvalues'] = {'salary:X': 7.89}
- entity = self.etype_instance('Personne', req)
- entity.eid = 'X'
- self.assertEquals(w.required(entity), False)
- self.assertEquals(w.render(entity), '')
- self.assertEquals(w.edit_render(entity),
- u'<input type="hidden" name="edits-salary:X" value="__cubicweb_internal_field__"/>\n'
- '<input type="text" name="salary:X" value="7.89" accesskey="s" id="salary:X" maxlength="15" size="5" tabindex="0"/>')
-
-
- def test_bool_widget(self):
- w = self.get_widget('Personne', 'test', 'Boolean')
- self.assertEquals(w.name, 'test')
- self.assertEquals(w.render_example(self.request()), '')
- self.assertDictEquals(w.attrs, {'accesskey': 't'})
- entity = self.etype_instance('Personne')
- entity.eid = 'X'
- self.assertEquals(w.required(entity), False)
- self.assertEquals(w.render(entity), '')
- self.assertEquals(w.edit_render(entity),
- u'''<input type="hidden" name="edits-test:X" value="__cubicweb_internal_field__"/>
-
-<input type="radio" name="test:X" value="1" accesskey="t" id="test:X" tabindex="0"/>yes<br/>
-<input type="radio" name="test:X" value="" accesskey="t" tabindex="0" checked="checked"/>no<br/>''')
-
- def test_bool_widget_previous_value(self):
- w = self.get_widget('Personne', 'test', 'Boolean')
- self.assertEquals(w.name, 'test')
- self.assertEquals(w.render_example(self.request()), '')
- self.assertDictEquals(w.attrs, {'accesskey': 't'})
- req = self.request()
- req.data['formvalues'] = {'test:X': 'checked'}
- entity = self.etype_instance('Personne', req)
- entity.eid = 'X'
- self.assertEquals(w.required(entity), False)
- self.assertEquals(w.render(entity), '')
- self.assertEquals(w.edit_render(entity),
- u'''<input type="hidden" name="edits-test:X" value="__cubicweb_internal_field__"/>
-
-<input type="radio" name="test:X" value="1" accesskey="t" id="test:X" tabindex="0" checked="checked"/>yes<br/>
-<input type="radio" name="test:X" value="" accesskey="t" tabindex="0"/>no<br/>''')
-
-
- def test_password_widget(self):
- w = self.get_widget('CWUser', 'upassword', 'Password')
- self.assertEquals(w.name, 'upassword')
- self.assertEquals(w.render_example(self.request()), '')
- self.assertDictEquals(w.attrs, {'accesskey': 'u'})
- entity = self.etype_instance('CWUser')
- entity.eid = 'X'
- self.assertEquals(w.required(entity), True)
- self.assertEquals(w.render(entity), '')
- self.assertEquals(w.edit_render(entity),
- u'<input type="hidden" name="edits-upassword:X" value="__cubicweb_internal_field__"/>\n'
- '<input type="password" name="upassword:X" value="" accesskey="u" id="upassword:X" tabindex="0"/><br/>\n'
- '<input type="password" name="upassword-confirm:X" id="upassword-confirm:X" tabindex="1"/> <span class="emphasis">(confirm password)</span>')
-
- def test_autocompletion_widget(self):
- entity = self.etype_instance('Personne')
- entity.widgets['nom'] = 'AutoCompletionWidget'
- entity.autocomplete_initfuncs = {'nom' : 'getnames'}
- try:
- w = self.get_widget(entity, 'nom', 'String')
- self.failUnless(isinstance(w, AutoCompletionWidget))
- self.assertEquals(w.name, 'nom')
- self.assertEquals(w.render_example(self.request()), '')
- self.assertDictEquals(w.attrs, {'accesskey': 'n', 'maxlength': 64, 'size': 40})
- entity.eid = 'X'
- self.assertEquals(w.required(entity), True)
- self.assertEquals(w.render(entity), '')
-
- self.assertTextEquals(w.edit_render(entity),
- u'<input type="hidden" name="edits-nom:X" value="__cubicweb_internal_field__"/>\n'
- u'<input type="text" name="nom:X" value="" cubicweb:dataurl="http://testing.fr/cubicweb/json?pageid=None&mode=remote&fname=getnames" class="widget required" id="nom:X" tabindex="0" cubicweb:loadtype="auto" cubicweb:wdgtype="SuggestField" cubicweb:accesskey="n" cubicweb:maxlength="64" cubicweb:size="40" />')
-
- finally:
- del entity.widgets['nom']
-
-
- def test_autocompletion_widget_previous_value(self):
- req = self.request()
- req.data['formvalues'] = {'nom:X': 'a name'}
- entity = self.etype_instance('Personne', req)
- entity.widgets['nom'] = 'AutoCompletionWidget'
- entity.autocomplete_initfuncs = {'nom' : 'getnames'}
- try:
- w = self.get_widget(entity, 'nom', 'String')
- self.failUnless(isinstance(w, AutoCompletionWidget))
- self.assertEquals(w.name, 'nom')
- self.assertEquals(w.render_example(self.request()), '')
- self.assertDictEquals(w.attrs, {'accesskey': 'n', 'maxlength': 64, 'size': 40})
- entity.eid = 'X'
- self.assertEquals(w.required(entity), True)
- self.assertEquals(w.render(entity), '')
- self.assertTextEquals(w.edit_render(entity),
- u'<input type="hidden" name="edits-nom:X" value="__cubicweb_internal_field__"/>\n'
- u'<input type="text" name="nom:X" value="a name" cubicweb:dataurl="http://testing.fr/cubicweb/json?pageid=None&mode=remote&fname=getnames" class="widget required" id="nom:X" tabindex="0" cubicweb:loadtype="auto" cubicweb:wdgtype="SuggestField" cubicweb:accesskey="n" cubicweb:maxlength="64" cubicweb:size="40" />')
-
- finally:
- del entity.widgets['nom']
-
-
- def test_nonregr_float_widget_with_none(self):
- w = self.get_widget('Personne', 'salary', 'Float')
- self.assertEquals(w.name, 'salary')
- format = self.vreg.property_value('ui.float-format')
- self.assertEquals(w.render_example(self.request()), format % 1.23)
- self.assertDictEquals(w.attrs, {'accesskey': 's', 'maxlength': 15, 'size': 5})
- req = self.request()
- entity = self.etype_instance('Personne', req)
- entity.eid = 'X'
- entity.salary = None
- self.assertEquals(w.required(entity), False)
- self.assertEquals(w.render(entity), '')
- self.assertEquals(w.edit_render(entity),
- u'<input type="hidden" name="edits-salary:X" value="__cubicweb_internal_field__"/>\n'
- '<input type="text" name="salary:X" value="" accesskey="s" id="salary:X" maxlength="15" size="5" tabindex="0"/>')
-
-
- def test_custom_widget_for_non_final_relation(self):
- entity = self.etype_instance('Personne', self.request())
- entity.widgets['travaille'] = 'AutoCompletionWidget'
- entity.autocomplete_initfuncs = {'nom' : 'getnames'}
- w = self.get_widget(entity, 'travaille', 'Societe')
- self.failUnless(isinstance(w, AutoCompletionWidget))
-
-
-if __name__ == '__main__':
- unittest_main()
--- a/web/uicfg.py Fri May 29 16:11:49 2009 +0200
+++ b/web/uicfg.py Fri May 29 20:22:39 2009 +0200
@@ -1,6 +1,3 @@
-# :organization: Logilab
-# :copyright: 2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
"""This module regroups a set of structures that may be used to configure
various places of the generated web interface.
@@ -63,6 +60,10 @@
Automatic form configuration
````````````````````````````
+:organization: Logilab
+:copyright: 2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/__init__.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/__init__.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Views, forms, actions... for the CubicWeb web client
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/actions.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/actions.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Set of HTML base actions
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/ajaxedit.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/ajaxedit.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Set of views allowing edition of entities/relations using ajax
:organization: Logilab
-:copyright: 2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/apacherewrite.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/apacherewrite.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
are much more limited for the moment)
:organization: Logilab
-:copyright: 2007-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2007-2009 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
"""
__docformat__ = "restructuredtext en"
@@ -87,8 +88,11 @@
id = 'urlrewriter'
rules = []
- def rewrite(self, host, path):
- for cond in self.rules:
+ def get_rules(self, req):
+ return self.rules
+
+ def rewrite(self, host, path, req):
+ for cond in self.get_rules(req):
if cond.match(host=host, path=path):
return cond.process(path)
return path
--- a/web/views/authentication.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/authentication.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""user authentication component
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/autoform.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/autoform.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""The automatic entity form.
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
_ = unicode
@@ -11,13 +12,13 @@
from cubicweb import typed_eid
from cubicweb.web import stdmsgs, uicfg
-from cubicweb.web.form import FieldNotFound, EntityFieldsForm
+from cubicweb.web.form import FieldNotFound
from cubicweb.web.formfields import guess_field
from cubicweb.web.formwidgets import Button, SubmitButton
-from cubicweb.web.views.editforms import toggleable_relation_link, relation_id
+from cubicweb.web.views import forms, editforms
-class AutomaticEntityForm(EntityFieldsForm):
+class AutomaticEntityForm(forms.EntityFieldsForm):
"""base automatic form to edit any entity.
Designed to be fully generated from schema but highly configurable through:
@@ -32,7 +33,7 @@
cwtarget = 'eformframe'
cssclass = 'entityForm'
copy_nav_params = True
- form_buttons = [SubmitButton(stdmsgs.BUTTON_OK),
+ form_buttons = [SubmitButton(),
Button(stdmsgs.BUTTON_APPLY, cwaction='apply'),
Button(stdmsgs.BUTTON_CANCEL, cwaction='cancel')]
attrcategories = ('primary', 'secondary')
@@ -234,13 +235,13 @@
for label, rschema, role in self.srelations_by_category('generic', 'add'):
relatedrset = entity.related(rschema, role, limit=self.related_limit)
if rschema.has_perm(self.req, 'delete'):
- toggleable_rel_link_func = toggleable_relation_link
+ toggleable_rel_link_func = editforms.toggleable_relation_link
else:
toggleable_rel_link_func = lambda x, y, z: u''
related = []
for row in xrange(relatedrset.rowcount):
- nodeid = relation_id(entity.eid, rschema, role,
- relatedrset[row][0])
+ nodeid = editforms.relation_id(entity.eid, rschema, role,
+ relatedrset[row][0])
if nodeid in pending_deletes:
status = u'pendingDelete'
label = '+'
--- a/web/views/basecomponents.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/basecomponents.py Fri May 29 20:22:39 2009 +0200
@@ -4,8 +4,9 @@
* the logged user link
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
_ = unicode
--- a/web/views/basecontrollers.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/basecontrollers.py Fri May 29 20:22:39 2009 +0200
@@ -4,8 +4,9 @@
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
@@ -22,9 +23,9 @@
from cubicweb.view import STRICT_DOCTYPE, STRICT_DOCTYPE_NOEXT
from cubicweb.common.mail import format_mail
from cubicweb.web import ExplicitLogin, Redirect, RemoteCallFailed, json_dumps
-from cubicweb.web.formrenderers import FormRenderer
from cubicweb.web.controller import Controller
from cubicweb.web.views import vid_from_rset
+from cubicweb.web.views.formrenderers import FormRenderer
try:
from cubicweb.web.facet import (FilterRQLBuilder, get_facet,
prepare_facets_rqlst)
@@ -340,7 +341,7 @@
entity=entity)
form.form_build_context()
vfield = form.field_by_name('value')
- renderer = FormRenderer()
+ renderer = FormRenderer(self.req)
return vfield.render(form, renderer, tabindex=tabindex) \
+ renderer.render_help(form, vfield)
--- a/web/views/baseforms.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/baseforms.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
or a list of entities of the same type
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/basetemplates.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/basetemplates.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
"""default templates for CubicWeb web client
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/baseviews.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/baseviews.py Fri May 29 20:22:39 2009 +0200
@@ -7,8 +7,9 @@
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
#from __future__ import with_statement
__docformat__ = "restructuredtext en"
--- a/web/views/bookmark.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/bookmark.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Primary view for bookmarks + user's bookmarks box
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/boxes.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/boxes.py Fri May 29 20:22:39 2009 +0200
@@ -9,8 +9,9 @@
* startup views box
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
_ = unicode
--- a/web/views/calendar.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/calendar.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""html calendar views
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
_ = unicode
@@ -527,4 +528,3 @@
year=nextdate.year,
week=nextdate.isocalendar()[1])
return prevlink, nextlink
-
--- a/web/views/csvexport.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/csvexport.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""csv export views
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/cwproperties.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/cwproperties.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Specific views for CWProperty
:organization: Logilab
-:copyright: 2007-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2007-2009 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
"""
__docformat__ = "restructuredtext en"
_ = unicode
@@ -16,11 +17,10 @@
match_user_groups)
from cubicweb.view import StartupView
from cubicweb.web import uicfg, stdmsgs
-from cubicweb.web.form import CompositeForm, EntityFieldsForm, FormViewMixIn
-from cubicweb.web.formrenderers import FormRenderer
+from cubicweb.web.form import FormViewMixIn
from cubicweb.web.formfields import FIELDS, StringField
from cubicweb.web.formwidgets import Select, Button, SubmitButton
-from cubicweb.web.views import primary
+from cubicweb.web.views import primary, formrenderers
# some string we want to be internationalizable for nicer display of property
@@ -189,10 +189,11 @@
def form(self, formid, keys, splitlabel=False):
buttons = [SubmitButton()]
- form = CompositeForm(self.req, domid=formid, action=self.build_url(),
- form_buttons=buttons,
- onsubmit="return validatePrefsForm('%s')" % formid,
- submitmsg=self.req._('changes applied'))
+ form = self.vreg.select_object('forms', 'composite', self.req,
+ domid=formid, action=self.build_url(),
+ form_buttons=buttons,
+ onsubmit="return validatePrefsForm('%s')" % formid,
+ submitmsg=self.req._('changes applied'))
path = self.req.relative_path()
if '?' in path:
path, params = path.split('?', 1)
@@ -200,9 +201,9 @@
form.form_add_hidden('__redirectpath', path)
for key in keys:
self.form_row(form, key, splitlabel)
- renderer = CWPropertiesFormRenderer()
- return form.form_render(display_progress_div=False,
- renderer=renderer)
+ renderer = self.vreg.select_object('formrenderers', 'cwproperties', self.req,
+ display_progress_div=False)
+ return form.form_render(renderer=renderer)
def form_row(self, form, key, splitlabel):
entity = self.entity_for_key(key)
@@ -210,8 +211,8 @@
label = key.split('.')[-1]
else:
label = key
- subform = EntityFieldsForm(self.req, entity=entity, set_error_url=False)
-
+ subform = self.vreg.select_object('forms', 'base', self.req, entity=entity,
+ set_error_url=False)
subform.append_field(PropertyValueField(name='value', label=label,
eidparam=True))
subform.vreg = self.vreg
@@ -358,8 +359,9 @@
uicfg.autoform_field.tag_attribute(('CWProperty', 'value'), PropertyValueField)
-class CWPropertiesFormRenderer(FormRenderer):
+class CWPropertiesFormRenderer(formrenderers.FormRenderer):
"""specific renderer for properties"""
+ id = 'cwproperties'
def open_form(self, form, values):
err = '<div class="formsg"></div>'
--- a/web/views/cwuser.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/cwuser.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Specific views for users
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/debug.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/debug.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/editcontroller.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/editcontroller.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""The edit controller, handling form submitting.
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/editforms.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/editforms.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
or a list of entities of the same type
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
_ = unicode
@@ -20,12 +21,10 @@
from cubicweb.view import EntityView
from cubicweb.common import tags
from cubicweb.web import INTERNAL_FIELD_VALUE, stdmsgs, eid_param
-from cubicweb.web.form import CompositeForm, EntityFieldsForm, FormViewMixIn
+from cubicweb.web.form import FormViewMixIn
from cubicweb.web.formfields import RelationField
from cubicweb.web.formwidgets import Button, SubmitButton, ResetButton, Select
-from cubicweb.web.formrenderers import (FormRenderer, EntityFormRenderer,
- EntityCompositeFormRenderer,
- EntityInlinedFormRenderer)
+from cubicweb.web.views import forms
def relation_id(eid, rtype, role, reid):
@@ -60,17 +59,19 @@
% _('this action is not reversible!'))
# XXX above message should have style of a warning
w(u'<h4>%s</h4>\n' % _('Do you want to delete the following element(s) ?'))
- form = CompositeForm(req, domid='deleteconf', copy_nav_params=True,
- action=self.build_url('edit'), onsubmit=onsubmit,
- form_buttons=[Button(stdmsgs.YES, cwaction='delete'),
- Button(stdmsgs.NO, cwaction='cancel')])
+ form = self.vreg.select_object('forms', 'composite', req, domid='deleteconf',
+ copy_nav_params=True,
+ action=self.build_url('edit'), onsubmit=onsubmit,
+ form_buttons=[Button(stdmsgs.YES, cwaction='delete'),
+ Button(stdmsgs.NO, cwaction='cancel')])
done = set()
w(u'<ul>\n')
for entity in self.rset.entities():
if entity.eid in done:
continue
done.add(entity.eid)
- subform = EntityFieldsForm(req, entity=entity, set_error_url=False)
+ subform = self.vreg.select_object('forms', 'base', req, entity=entity,
+ set_error_url=False)
form.form_add_subform(subform)
# don't use outofcontext view or any other that may contain inline edition form
w(u'<li>%s</li>' % tags.a(entity.view('textoutofcontext'),
@@ -113,14 +114,18 @@
self.w(value)
return
if rschema.is_final():
- form = self._build_attribute_form(entity, value, rtype, role, reload, row, col, default)
+ form = self._build_attribute_form(entity, value, rtype, role,
+ reload, row, col, default)
else:
- form = self._build_relation_form(entity, value, rtype, role, row, col, vid, default)
+ form = self._build_relation_form(entity, value, rtype, role,
+ row, col, vid, default)
form.form_add_hidden(u'__maineid', entity.eid)
- renderer = FormRenderer(display_label=False, display_help=False,
- display_fields=[(rtype, role)],
- table_class='', button_bar_class='buttonbar',
- display_progress_div=False)
+ renderer = self.vreg.select_object('formrenderers', 'base', self.req,
+ entity=entity,
+ display_label=False, display_help=False,
+ display_fields=[(rtype, role)],
+ table_class='', button_bar_class='buttonbar',
+ display_progress_div=False)
self.w(form.form_render(renderer=renderer))
def _build_relation_form(self, entity, value, rtype, role, row, col, vid, default):
@@ -128,16 +133,17 @@
divid = 'd%s' % make_uid('%s-%s' % (rtype, entity.eid))
event_data = {'divid' : divid, 'eid' : entity.eid, 'rtype' : rtype, 'vid' : vid,
'default' : default, 'role' : role}
- form = EntityFieldsForm(self.req, None, entity=entity, action='#',
- domid='%s-form' % divid,
- cssstyle='display: none',
- onsubmit=("return inlineValidateRelationForm('%(divid)s-form', '%(rtype)s', "
- "'%(role)s', '%(eid)s', '%(divid)s', '%(vid)s', '%(default)s');" %
- event_data),
- form_buttons=[SubmitButton(),
- Button(stdmsgs.BUTTON_CANCEL,
- onclick="cancelInlineEdit(%s,\'%s\',\'%s\')" %\
- (entity.eid, rtype, divid))])
+ onsubmit = ("return inlineValidateRelationForm('%(divid)s-form', '%(rtype)s', "
+ "'%(role)s', '%(eid)s', '%(divid)s', '%(vid)s', '%(default)s');"
+ % event_data)
+ cancelclick = "cancelInlineEdit(%s,\'%s\',\'%s\')" % (
+ entity.eid, rtype, divid)
+ form = self.vreg.select_object('forms', 'base', self.req, entity=entity,
+ domid='%s-form' % divid, cssstyle='display: none',
+ onsubmit=onsubmit, action='#',
+ form_buttons=[SubmitButton(),
+ Button(stdmsgs.BUTTON_CANCEL,
+ onclick=cancelclick)])
form.append_field(RelationField(name=rtype, role=role, sort=True,
widget=Select(),
label=u' '))
@@ -172,7 +178,6 @@
__select__ = one_line_rset() & non_final_entity() & yes()
title = _('edition')
- renderer = EntityFormRenderer()
def cell_call(self, row, col, **kwargs):
entity = self.complete_entity(row, col)
@@ -185,7 +190,7 @@
row=entity.row, col=entity.col, entity=entity,
submitmsg=self.submited_message())
self.init_form(form, entity)
- self.w(form.form_render(renderer=self.renderer, formvid=u'edition'))
+ self.w(form.form_render(formvid=u'edition'))
def init_form(self, form, entity):
"""customize your form before rendering here"""
@@ -289,7 +294,7 @@
return self.req._('entity copied')
-class TableEditForm(CompositeForm):
+class TableEditForm(forms.CompositeForm):
id = 'muledit'
domid = 'entityForm'
onsubmit = "return validateForm('%s', null);" % domid
@@ -319,7 +324,7 @@
"""
#self.form_title(entity)
form = self.vreg.select_object('forms', self.id, self.req, self.rset)
- self.w(form.form_render(renderer=EntityCompositeFormRenderer()))
+ self.w(form.form_render())
class InlineEntityEditionFormView(FormViewMixIn, EntityView):
@@ -350,14 +355,15 @@
def render_form(self, entity, peid, rtype, role, **kwargs):
"""fetch and render the form"""
form = self.vreg.select_object('forms', 'edition', self.req, None,
- entity=entity, set_error_url=False,
+ entity=entity, form_renderer_id='inline',
+ set_error_url=False,
copy_nav_params=False)
self.add_hiddens(form, entity, peid, rtype, role)
divid = '%s-%s-%s' % (peid, rtype, entity.eid)
title = self.schema.rschema(rtype).display_name(self.req, role)
removejs = self.removejs % (peid, rtype,entity.eid)
- self.w(form.form_render(renderer=EntityInlinedFormRenderer(), divid=divid,
- title=title, removejs=removejs,**kwargs))
+ self.w(form.form_render(divid=divid, title=title, removejs=removejs,
+ **kwargs))
def add_hiddens(self, form, entity, peid, rtype, role):
# to ease overriding (see cubes.vcsfile.views.forms for instance)
--- a/web/views/editviews.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/editviews.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Some views used to help to the edition process
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/emailaddress.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/emailaddress.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Specific views for email addresses entities
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/embedding.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/embedding.py Fri May 29 20:22:39 2009 +0200
@@ -3,8 +3,9 @@
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/error.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/error.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
as startup views and are used for standard error pages (404, 500, etc.)
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/facets.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/facets.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""the facets box and some basic facets
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/views/formrenderers.py Fri May 29 20:22:39 2009 +0200
@@ -0,0 +1,501 @@
+"""form renderers, responsible to layout a form to html
+
+:organization: Logilab
+:copyright: 2009 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
+"""
+__docformat__ = "restructuredtext en"
+
+from logilab.common import dictattr
+from logilab.mtconverter import html_escape
+
+from simplejson import dumps
+
+from cubicweb.common import tags
+from cubicweb.appobject import AppRsetObject
+from cubicweb.selectors import entity_implements, yes
+from cubicweb.web import eid_param
+from cubicweb.web import formwidgets as fwdgs
+from cubicweb.web.widgets import checkbox
+from cubicweb.web.formfields import HiddenInitialValueField
+
+
+class FormRenderer(AppRsetObject):
+ """basic renderer displaying fields in a two columns table label | value
+
+ +--------------+--------------+
+ | field1 label | field1 input |
+ +--------------+--------------+
+ | field1 label | field2 input |
+ +--------------+--------------+
+ +---------+
+ | buttons |
+ +---------+
+ """
+ __registry__ = 'formrenderers'
+ id = 'default'
+
+ _options = ('display_fields', 'display_label', 'display_help',
+ 'display_progress_div', 'table_class', 'button_bar_class',
+ # add entity since it may be given to select the renderer
+ 'entity')
+ display_fields = None # None -> all fields
+ display_label = True
+ display_help = True
+ display_progress_div = True
+ table_class = u'attributeForm'
+ button_bar_class = u'formButtonBar'
+
+ def __init__(self, req=None, rset=None, row=None, col=None, **kwargs):
+ super(FormRenderer, self).__init__(req, rset, row, col)
+ if self._set_options(kwargs):
+ raise ValueError('unconsumed arguments %s' % kwargs)
+
+ def _set_options(self, kwargs):
+ for key in self._options:
+ try:
+ setattr(self, key, kwargs.pop(key))
+ except KeyError:
+ continue
+ return kwargs
+
+ # renderer interface ######################################################
+
+ def render(self, form, values):
+ self._set_options(values)
+ form.add_media()
+ data = []
+ w = data.append
+ w(self.open_form(form, values))
+ if self.display_progress_div:
+ w(u'<div id="progress">%s</div>' % self.req._('validating...'))
+ w(u'<fieldset>')
+ w(tags.input(type=u'hidden', name=u'__form_id',
+ value=values.get('formvid', form.id)))
+ if form.redirect_path:
+ w(tags.input(type='hidden', name='__redirectpath', value=form.redirect_path))
+ self.render_fields(w, form, values)
+ self.render_buttons(w, form)
+ w(u'</fieldset>')
+ w(u'</form>')
+ errormsg = self.error_message(form)
+ if errormsg:
+ data.insert(0, errormsg)
+ return '\n'.join(data)
+
+ def render_label(self, form, field):
+ label = self.req._(field.label)
+ attrs = {'for': form.context[field]['id']}
+ if field.required:
+ attrs['class'] = 'required'
+ return tags.label(label, **attrs)
+
+ def render_help(self, form, field):
+ help = []
+ descr = field.help
+ if descr:
+ help.append('<div class="helper">%s</div>' % self.req._(descr))
+ example = field.example_format(self.req)
+ if example:
+ help.append('<div class="helper">(%s: %s)</div>'
+ % (self.req._('sample format'), example))
+ return u' '.join(help)
+
+ # specific methods (mostly to ease overriding) #############################
+
+ def error_message(self, form):
+ """return formatted error message
+
+ This method should be called once inlined field errors has been consumed
+ """
+ req = self.req
+ errex = form.form_valerror
+ # get extra errors
+ if errex is not None:
+ errormsg = req._('please correct the following errors:')
+ displayed = form.form_displayed_errors
+ errors = sorted((field, err) for field, err in errex.errors.items()
+ if not field in displayed)
+ if errors:
+ if len(errors) > 1:
+ templstr = '<li>%s</li>\n'
+ else:
+ templstr = ' %s\n'
+ for field, err in errors:
+ if field is None:
+ errormsg += templstr % err
+ else:
+ errormsg += templstr % '%s: %s' % (req._(field), err)
+ if len(errors) > 1:
+ errormsg = '<ul>%s</ul>' % errormsg
+ return u'<div class="errorMessage">%s</div>' % errormsg
+ return u''
+
+ def open_form(self, form, values):
+ if form.form_needs_multipart:
+ enctype = 'multipart/form-data'
+ else:
+ enctype = 'application/x-www-form-urlencoded'
+ if form.action is None:
+ action = self.req.build_url('edit')
+ else:
+ action = form.action
+ tag = ('<form action="%s" method="post" enctype="%s"' % (
+ html_escape(action or '#'), enctype))
+ if form.domid:
+ tag += ' id="%s"' % form.domid
+ if form.onsubmit:
+ tag += ' onsubmit="%s"' % html_escape(form.onsubmit % dictattr(form))
+ if form.cssstyle:
+ tag += ' style="%s"' % html_escape(form.cssstyle)
+ if form.cssclass:
+ tag += ' class="%s"' % html_escape(form.cssclass)
+ if form.cwtarget:
+ tag += ' cubicweb:target="%s"' % html_escape(form.cwtarget)
+ return tag + '>'
+
+ def display_field(self, form, field):
+ if isinstance(field, HiddenInitialValueField):
+ field = field.visible_field
+ return (self.display_fields is None
+ or field.name in form.internal_fields
+ or (field.name, field.role) in self.display_fields
+ or (field.name, field.role) in form.internal_fields)
+
+ def render_fields(self, w, form, values):
+ form.form_build_context(values)
+ fields = self._render_hidden_fields(w, form)
+ if fields:
+ self._render_fields(fields, w, form)
+ self.render_child_forms(w, form, values)
+
+ def render_child_forms(self, w, form, values):
+ # render
+ for childform in getattr(form, 'forms', []):
+ self.render_fields(w, childform, values)
+
+ def _render_hidden_fields(self, w, form):
+ fields = form.fields[:]
+ for field in form.fields:
+ if not self.display_field(form, field):
+ fields.remove(field)
+ elif not field.is_visible():
+ w(field.render(form, self))
+ fields.remove(field)
+ return fields
+
+ def _render_fields(self, fields, w, form):
+ w(u'<table class="%s">' % self.table_class)
+ for field in fields:
+ w(u'<tr>')
+ if self.display_label:
+ w(u'<th class="labelCol">%s</th>' % self.render_label(form, field))
+ error = form.form_field_error(field)
+ if error:
+ w(u'<td class="error">')
+ w(error)
+ else:
+ w(u'<td>')
+ w(field.render(form, self))
+ if self.display_help:
+ w(self.render_help(form, field))
+ w(u'</td></tr>')
+ w(u'</table>')
+
+ def render_buttons(self, w, form):
+ w(u'<table class="%s">\n<tr>\n' % self.button_bar_class)
+ for button in form.form_buttons:
+ w(u'<td>%s</td>\n' % button.render(form))
+ w(u'</tr></table>')
+
+
+class BaseFormRenderer(FormRenderer):
+ """use form_renderer_id = 'base' if you want base FormRenderer without
+ adaptation by selection
+ """
+ id = 'base'
+
+
+class HTableFormRenderer(FormRenderer):
+ """display fields horizontally in a table
+
+ +--------------+--------------+---------+
+ | field1 label | field2 label | |
+ +--------------+--------------+---------+
+ | field1 input | field2 input | buttons
+ +--------------+--------------+---------+
+ """
+ id = 'htable'
+
+ display_help = False
+ def _render_fields(self, fields, w, form):
+ w(u'<table border="0">')
+ w(u'<tr>')
+ for field in fields:
+ if self.display_label:
+ w(u'<th class="labelCol">%s</th>' % self.render_label(form, field))
+ if self.display_help:
+ w(self.render_help(form, field))
+ # empty slot for buttons
+ w(u'<th class="labelCol"> </th>')
+ w(u'</tr>')
+ w(u'<tr>')
+ for field in fields:
+ error = form.form_field_error(field)
+ if error:
+ w(u'<td class="error">')
+ w(error)
+ else:
+ w(u'<td>')
+ w(field.render(form, self))
+ w(u'</td>')
+ w(u'<td>')
+ for button in form.form_buttons:
+ w(button.render(form))
+ w(u'</td>')
+ w(u'</tr>')
+ w(u'</table>')
+
+ def render_buttons(self, w, form):
+ pass
+
+
+class EntityCompositeFormRenderer(FormRenderer):
+ """specific renderer for multiple entities edition form (muledit)"""
+ id = 'composite'
+
+ def render_fields(self, w, form, values):
+ if not form.is_subform:
+ w(u'<table class="listing">')
+ super(EntityCompositeFormRenderer, self).render_fields(w, form, values)
+ if not form.is_subform:
+ w(u'</table>')
+
+ def _render_fields(self, fields, w, form):
+ if form.is_subform:
+ 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))
+ w(u'<tr class="%s">' % (entity.row % 2 and u'even' or u'odd'))
+ # XXX turn this into a widget used on the eid field
+ w(u'<td>%s</td>' % checkbox('eid', entity.eid, checked=qeid in values))
+ for field in fields:
+ error = form.form_field_error(field)
+ if error:
+ w(u'<td class="error">')
+ w(error)
+ else:
+ w(u'<td>')
+ if isinstance(field.widget, (fwdgs.Select, fwdgs.CheckBox, fwdgs.Radio)):
+ field.widget.attrs['onchange'] = cbsetstate
+ elif isinstance(field.widget, fwdgs.Input):
+ field.widget.attrs['onkeypress'] = cbsetstate
+ w(u'<div>%s</div>' % field.render(form, self))
+ w(u'</td>')
+ else:
+ # main form, display table headers
+ w(u'<tr class="header">')
+ w(u'<th align="left">%s</th>'
+ % tags.input(type='checkbox', title=self.req._('toggle check boxes'),
+ onclick="setCheckboxesState('eid', this.checked)"))
+ for field in self.forms[0].fields:
+ if self.display_field(form, field) and field.is_visible():
+ w(u'<th>%s</th>' % self.req._(field.label))
+ w(u'</tr>')
+
+
+class EntityFormRenderer(FormRenderer):
+ """specific renderer for entity edition form (edition)"""
+ __select__ = entity_implements('Any') & yes()
+
+ _options = FormRenderer._options + ('display_relations_form',)
+ display_relations_form = True
+
+ def render(self, form, values):
+ rendered = super(EntityFormRenderer, self).render(form, values)
+ return rendered + u'</div>' # close extra div introducted by open_form
+
+ def open_form(self, form, values):
+ attrs_fs_label = ('<div class="iformTitle"><span>%s</span></div>'
+ % self.req._('main informations'))
+ attrs_fs_label += '<div class="formBody">'
+ return attrs_fs_label + super(EntityFormRenderer, self).open_form(form, values)
+
+ def render_fields(self, w, form, values):
+ super(EntityFormRenderer, self).render_fields(w, form, values)
+ self.inline_entities_form(w, form)
+ if form.edited_entity.has_eid() and self.display_relations_form:
+ self.relations_form(w, form)
+
+ def _render_fields(self, fields, w, form):
+ if not form.edited_entity.has_eid() or form.edited_entity.has_perm('update'):
+ super(EntityFormRenderer, self)._render_fields(fields, w, form)
+
+ def render_buttons(self, w, form):
+ if len(form.form_buttons) == 3:
+ w("""<table width="100%%">
+ <tbody>
+ <tr><td align="center">
+ %s
+ </td><td style="align: right; width: 50%%;">
+ %s
+ %s
+ </td></tr>
+ </tbody>
+ </table>""" % tuple(button.render(form) for button in form.form_buttons))
+ else:
+ super(EntityFormRenderer, self).render_buttons(w, form)
+
+ def relations_form(self, w, form):
+ srels_by_cat = form.srelations_by_category('generic', 'add')
+ if not srels_by_cat:
+ return u''
+ req = self.req
+ _ = req._
+ label = u'%s :' % _('This %s' % form.edited_entity.e_schema).capitalize()
+ eid = form.edited_entity.eid
+ w(u'<fieldset class="subentity">')
+ w(u'<legend class="iformTitle">%s</legend>' % label)
+ w(u'<table id="relatedEntities">')
+ for rschema, target, related in form.relations_table():
+ # already linked entities
+ if related:
+ w(u'<tr><th class="labelCol">%s</th>' % rschema.display_name(req, target))
+ w(u'<td>')
+ w(u'<ul>')
+ for viewparams in related:
+ w(u'<li class="invisible">%s<div id="span%s" class="%s">%s</div></li>'
+ % (viewparams[1], viewparams[0], viewparams[2], viewparams[3]))
+ if not form.force_display and form.maxrelitems < len(related):
+ link = (u'<span class="invisible">'
+ '[<a href="javascript: window.location.href+=\'&__force_display=1\'">%s</a>]'
+ '</span>' % self.req._('view all'))
+ w(u'<li class="invisible">%s</li>' % link)
+ w(u'</ul>')
+ w(u'</td>')
+ w(u'</tr>')
+ pendings = list(form.restore_pending_inserts())
+ if not pendings:
+ w(u'<tr><th> </th><td> </td></tr>')
+ else:
+ for row in pendings:
+ # soon to be linked to entities
+ w(u'<tr id="tr%s">' % row[1])
+ w(u'<th>%s</th>' % row[3])
+ w(u'<td>')
+ w(u'<a class="handle" title="%s" href="%s">[x]</a>' %
+ (_('cancel this insert'), row[2]))
+ w(u'<a id="a%s" class="editionPending" href="%s">%s</a>'
+ % (row[1], row[4], html_escape(row[5])))
+ w(u'</td>')
+ w(u'</tr>')
+ w(u'<tr id="relationSelectorRow_%s" class="separator">' % eid)
+ w(u'<th class="labelCol">')
+ w(u'<span>%s</span>' % _('add relation'))
+ w(u'<select id="relationSelector_%s" tabindex="%s" '
+ 'onchange="javascript:showMatchingSelect(this.options[this.selectedIndex].value,%s);">'
+ % (eid, req.next_tabindex(), html_escape(dumps(eid))))
+ w(u'<option value="">%s</option>' % _('select a relation'))
+ for i18nrtype, rschema, target in srels_by_cat:
+ # more entities to link to
+ w(u'<option value="%s_%s">%s</option>' % (rschema, target, i18nrtype))
+ w(u'</select>')
+ w(u'</th>')
+ w(u'<td id="unrelatedDivs_%s"></td>' % eid)
+ w(u'</tr>')
+ w(u'</table>')
+ w(u'</fieldset>')
+
+ def inline_entities_form(self, w, form):
+ """create a form to edit entity's inlined relations"""
+ if not hasattr(form, 'inlined_relations'):
+ return
+ entity = form.edited_entity
+ __ = self.req.__
+ for rschema, targettypes, role in form.inlined_relations():
+ # show inline forms only if there's one possible target type
+ # for rschema
+ if len(targettypes) != 1:
+ self.warning('entity related by the %s relation should have '
+ 'inlined form but there is multiple target types, '
+ 'dunno what to do', rschema)
+ continue
+ targettype = targettypes[0].type
+ if form.should_inline_relation_form(rschema, targettype, role):
+ w(u'<div id="inline%sslot">' % rschema)
+ existant = entity.has_eid() and entity.related(rschema)
+ if existant:
+ # display inline-edition view for all existing related entities
+ w(form.view('inline-edition', existant, rtype=rschema, role=role,
+ ptype=entity.e_schema, peid=entity.eid))
+ if role == 'subject':
+ card = rschema.rproperty(entity.e_schema, targettype, 'cardinality')[0]
+ else:
+ card = rschema.rproperty(targettype, entity.e_schema, 'cardinality')[1]
+ # there is no related entity and we need at least one: we need to
+ # display one explicit inline-creation view
+ if form.should_display_inline_creation_form(rschema, existant, card):
+ w(form.view('inline-creation', None, etype=targettype,
+ peid=entity.eid, ptype=entity.e_schema,
+ rtype=rschema, role=role))
+ # we can create more than one related entity, we thus display a link
+ # to add new related entities
+ if form.should_display_add_new_relation_link(rschema, existant, card):
+ divid = "addNew%s%s%s:%s" % (targettype, rschema, role, entity.eid)
+ w(u'<div class="inlinedform" id="%s" cubicweb:limit="true">'
+ % divid)
+ js = "addInlineCreationForm('%s', '%s', '%s', '%s')" % (
+ entity.eid, targettype, rschema, role)
+ if card in '1?':
+ js = "toggleVisibility('%s'); %s" % (divid, js)
+ w(u'<a class="addEntity" id="add%s:%slink" href="javascript: %s" >+ %s.</a>'
+ % (rschema, entity.eid, js, __('add a %s' % targettype)))
+ w(u'</div>')
+ w(u'<div class="trame_grise"> </div>')
+ w(u'</div>')
+
+
+class EntityInlinedFormRenderer(EntityFormRenderer):
+ """specific renderer for entity inlined edition form
+ (inline-[creation|edition])
+ """
+ id = 'inline'
+
+ def render(self, form, values):
+ form.add_media()
+ data = []
+ w = data.append
+ try:
+ w(u'<div id="div-%(divid)s" onclick="%(divonclick)s">' % values)
+ except KeyError:
+ w(u'<div id="div-%(divid)s">' % values)
+ else:
+ w(u'<div id="notice-%s" class="notice">%s</div>' % (
+ values['divid'], self.req._('click on the box to cancel the deletion')))
+ w(u'<div class="iformBody">')
+ values['removemsg'] = self.req.__('remove this %s' % form.edited_entity.e_schema)
+ w(u'<div class="iformTitle"><span>%(title)s</span> '
+ '#<span class="icounter">1</span> '
+ '[<a href="javascript: %(removejs)s;noop();">%(removemsg)s</a>]</div>'
+ % values)
+ # cleanup values
+ for key in ('title', 'removejs', 'removemsg'):
+ values.pop(key)
+ self.render_fields(w, form, values)
+ w(u'</div></div>')
+ return '\n'.join(data)
+
+ def render_fields(self, w, form, values):
+ form.form_build_context(values)
+ w(u'<fieldset id="fs-%(divid)s">' % values)
+ fields = self._render_hidden_fields(w, form)
+ w(u'</fieldset>')
+ w(u'<fieldset class="subentity">')
+ if fields:
+ self._render_fields(fields, w, form)
+ self.render_child_forms(w, form, values)
+ self.inline_entities_form(w, form)
+ w(u'</fieldset>')
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/views/forms.py Fri May 29 20:22:39 2009 +0200
@@ -0,0 +1,524 @@
+"""some base form classes for CubicWeb web client
+
+:organization: Logilab
+:copyright: 2001-2009 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
+"""
+__docformat__ = "restructuredtext en"
+
+from warnings import warn
+
+from logilab.common.compat import any
+from logilab.common.decorators import iclassmethod
+
+from cubicweb.selectors import non_final_entity, match_kwargs, one_line_rset
+from cubicweb.web import INTERNAL_FIELD_VALUE, eid_param
+from cubicweb.web import form, formwidgets as fwdgs
+from cubicweb.web.controller import NAV_FORM_PARAMETERS
+from cubicweb.web.formfields import HiddenInitialValueField, StringField
+
+
+class FieldsForm(form.Form):
+ id = 'base'
+
+ is_subform = False
+
+ # attributes overrideable through __init__
+ internal_fields = ('__errorurl',) + NAV_FORM_PARAMETERS
+ needs_js = ('cubicweb.ajax.js', 'cubicweb.edition.js',)
+ needs_css = ('cubicweb.form.css',)
+ domid = 'form'
+ title = None
+ action = None
+ onsubmit = "return freezeFormButtons('%(domid)s');"
+ cssclass = None
+ cssstyle = None
+ cwtarget = None
+ redirect_path = None
+ set_error_url = True
+ copy_nav_params = False
+ form_buttons = None # form buttons (button widgets instances)
+ form_renderer_id = 'default'
+
+ def __init__(self, req, rset=None, row=None, col=None, submitmsg=None,
+ **kwargs):
+ super(FieldsForm, self).__init__(req, rset, row=row, col=col)
+ self.fields = list(self.__class__._fields_)
+ for key, val in kwargs.items():
+ if key in NAV_FORM_PARAMETERS:
+ self.form_add_hidden(key, val)
+ else:
+ assert hasattr(self.__class__, key) and not key[0] == '_', key
+ setattr(self, key, val)
+ if self.set_error_url:
+ self.form_add_hidden('__errorurl', self.session_key())
+ if self.copy_nav_params:
+ for param in NAV_FORM_PARAMETERS:
+ if not param in kwargs:
+ value = req.form.get(param)
+ if value:
+ self.form_add_hidden(param, value)
+ if submitmsg is not None:
+ self.form_add_hidden('__message', submitmsg)
+ self.context = None
+ if 'domid' in kwargs:# session key changed
+ self.restore_previous_post(self.session_key())
+
+ @iclassmethod
+ def _fieldsattr(cls_or_self):
+ if isinstance(cls_or_self, type):
+ fields = cls_or_self._fields_
+ else:
+ fields = cls_or_self.fields
+ return fields
+
+ @iclassmethod
+ def field_by_name(cls_or_self, name, role='subject'):
+ """return field with the given name and role.
+ Raise FieldNotFound if the field can't be found.
+ """
+ for field in cls_or_self._fieldsattr():
+ if field.name == name and field.role == role:
+ return field
+ raise form.FieldNotFound(name)
+
+ @iclassmethod
+ def fields_by_name(cls_or_self, name, role='subject'):
+ """return a list of fields with the given name and role"""
+ return [field for field in cls_or_self._fieldsattr()
+ if field.name == name and field.role == role]
+
+ @iclassmethod
+ def remove_field(cls_or_self, field):
+ """remove a field from form class or instance"""
+ cls_or_self._fieldsattr().remove(field)
+
+ @iclassmethod
+ def append_field(cls_or_self, field):
+ """append a field to form class or instance"""
+ cls_or_self._fieldsattr().append(field)
+
+ @iclassmethod
+ def insert_field_before(cls_or_self, new_field, name, role='subject'):
+ field = cls_or_self.field_by_name(name, role)
+ fields = cls_or_self._fieldsattr()
+ fields.insert(fields.index(field), new_field)
+
+ @iclassmethod
+ def insert_field_after(cls_or_self, new_field, name, role='subject'):
+ field = cls_or_self.field_by_name(name, role)
+ fields = cls_or_self._fieldsattr()
+ fields.insert(fields.index(field)+1, new_field)
+
+ @property
+ def form_needs_multipart(self):
+ """true if the form needs enctype=multipart/form-data"""
+ return any(field.needs_multipart for field in self.fields)
+
+ def form_add_hidden(self, name, value=None, **kwargs):
+ """add an hidden field to the form"""
+ field = StringField(name=name, widget=fwdgs.HiddenInput, initial=value,
+ **kwargs)
+ if 'id' in kwargs:
+ # by default, hidden input don't set id attribute. If one is
+ # explicitly specified, ensure it will be set
+ field.widget.setdomid = True
+ self.append_field(field)
+ return field
+
+ def add_media(self):
+ """adds media (CSS & JS) required by this widget"""
+ if self.needs_js:
+ self.req.add_js(self.needs_js)
+ if self.needs_css:
+ self.req.add_css(self.needs_css)
+
+ def form_render(self, **values):
+ """render this form, using the renderer given in args or the default
+ FormRenderer()
+ """
+ renderer = values.pop('renderer', None)
+ if renderer is None:
+ renderer = self.form_default_renderer()
+ return renderer.render(self, values)
+
+ def form_default_renderer(self):
+ return self.vreg.select_object('formrenderers', self.form_renderer_id,
+ self.req, self.rset,
+ row=self.row, col=self.col)
+
+ def form_build_context(self, rendervalues=None):
+ """build form context values (the .context attribute which is a
+ dictionary with field instance as key associated to a dictionary
+ containing field 'name' (qualified), 'id', 'value' (for display, always
+ a string).
+
+ rendervalues is an optional dictionary containing extra kwargs given to
+ form_render()
+ """
+ self.context = context = {}
+ # ensure rendervalues is a dict
+ if rendervalues is None:
+ rendervalues = {}
+ # use a copy in case fields are modified while context is build (eg
+ # __linkto handling for instance)
+ for field in self.fields[:]:
+ for field in field.actual_fields(self):
+ field.form_init(self)
+ value = self.form_field_display_value(field, rendervalues)
+ context[field] = {'value': value,
+ 'name': self.form_field_name(field),
+ 'id': self.form_field_id(field),
+ }
+
+ def form_field_display_value(self, field, rendervalues, load_bytes=False):
+ """return field's *string* value to use for display
+
+ looks in
+ 1. previously submitted form values if any (eg on validation error)
+ 2. req.form
+ 3. extra kw args given to render_form
+ 4. field's typed value
+
+ values found in 1. and 2. are expected te be already some 'display'
+ value while those found in 3. and 4. are expected to be correctly typed.
+ """
+ value = self._req_display_value(field)
+ if value is None:
+ if field.name in rendervalues:
+ value = rendervalues[field.name]
+ else:
+ value = self.form_field_value(field, load_bytes)
+ if callable(value):
+ value = value(self)
+ if value != INTERNAL_FIELD_VALUE:
+ value = field.format_value(self.req, value)
+ return value
+
+ def _req_display_value(self, field):
+ qname = self.form_field_name(field)
+ if qname in self.form_previous_values:
+ return self.form_previous_values[qname]
+ if qname in self.req.form:
+ return self.req.form[qname]
+ if field.name in self.req.form:
+ return self.req.form[field.name]
+ return None
+
+ def form_field_value(self, field, load_bytes=False):
+ """return field's *typed* value"""
+ myattr = '%s_%s_default' % (field.role, field.name)
+ if hasattr(self, myattr):
+ return getattr(self, myattr)()
+ value = field.initial
+ if callable(value):
+ value = value(self)
+ return value
+
+ def form_field_error(self, field):
+ """return validation error for widget's field, if any"""
+ if self._field_has_error(field):
+ self.form_displayed_errors.add(field.name)
+ return u'<span class="error">%s</span>' % self.form_valerror.errors[field.name]
+ return u''
+
+ def form_field_format(self, field):
+ """return MIME type used for the given (text or bytes) field"""
+ return self.req.property_value('ui.default-text-format')
+
+ def form_field_encoding(self, field):
+ """return encoding used for the given (text) field"""
+ return self.req.encoding
+
+ def form_field_name(self, field):
+ """return qualified name for the given field"""
+ return field.name
+
+ def form_field_id(self, field):
+ """return dom id for the given field"""
+ return field.id
+
+ def form_field_vocabulary(self, field, limit=None):
+ """return vocabulary for the given field. Should be overriden in
+ specific forms using fields which requires some vocabulary
+ """
+ raise NotImplementedError
+
+ def _field_has_error(self, field):
+ """return true if the field has some error in given validation exception
+ """
+ return self.form_valerror and field.name in self.form_valerror.errors
+
+
+class EntityFieldsForm(FieldsForm):
+ id = 'base'
+ __select__ = (match_kwargs('entity') | (one_line_rset & non_final_entity()))
+
+ internal_fields = FieldsForm.internal_fields + ('__type', 'eid', '__maineid')
+ domid = 'entityForm'
+
+ def __init__(self, *args, **kwargs):
+ self.edited_entity = kwargs.pop('entity', None)
+ msg = kwargs.pop('submitmsg', None)
+ super(EntityFieldsForm, self).__init__(*args, **kwargs)
+ if self.edited_entity is None:
+ self.edited_entity = self.complete_entity(self.row or 0, self.col or 0)
+ self.form_add_hidden('__type', eidparam=True)
+ self.form_add_hidden('eid')
+ if msg:
+ # If we need to directly attach the new object to another one
+ self.form_add_hidden('__message', msg)
+ if not self.is_subform:
+ for linkto in self.req.list_form_param('__linkto'):
+ self.form_add_hidden('__linkto', linkto)
+ msg = '%s %s' % (msg, self.req._('and linked'))
+
+ def _field_has_error(self, field):
+ """return true if the field has some error in given validation exception
+ """
+ return super(EntityFieldsForm, self)._field_has_error(field) \
+ and self.form_valerror.eid == self.edited_entity.eid
+
+ def _relation_vocabulary(self, rtype, targettype, role,
+ limit=None, done=None):
+ """return unrelated entities for a given relation and target entity type
+ for use in vocabulary
+ """
+ if done is None:
+ done = set()
+ rset = self.edited_entity.unrelated(rtype, targettype, role, limit)
+ res = []
+ for entity in rset.entities():
+ if entity.eid in done:
+ continue
+ done.add(entity.eid)
+ res.append((entity.view('combobox'), entity.eid))
+ return res
+
+ def _req_display_value(self, field):
+ value = super(EntityFieldsForm, self)._req_display_value(field)
+ if value is None:
+ value = self.edited_entity.linked_to(field.name, field.role)
+ if value:
+ searchedvalues = ['%s:%s:%s' % (field.name, eid, field.role)
+ for eid in value]
+ # remove associated __linkto hidden fields
+ for field in self.fields_by_name('__linkto'):
+ if field.initial in searchedvalues:
+ self.remove_field(field)
+ else:
+ value = None
+ return value
+
+ def _form_field_default_value(self, field, load_bytes):
+ defaultattr = 'default_%s' % field.name
+ if hasattr(self.edited_entity, defaultattr):
+ # XXX bw compat, default_<field name> on the entity
+ warn('found %s on %s, should be set on a specific form'
+ % (defaultattr, self.edited_entity.id), DeprecationWarning)
+ value = getattr(self.edited_entity, defaultattr)
+ if callable(value):
+ value = value()
+ else:
+ value = super(EntityFieldsForm, self).form_field_value(field,
+ load_bytes)
+ return value
+
+ def form_default_renderer(self):
+ return self.vreg.select_object('formrenderers', self.form_renderer_id,
+ self.req, self.rset,
+ row=self.row, col=self.col,
+ entity=self.edited_entity)
+
+ def form_build_context(self, values=None):
+ """overriden to add edit[s|o] hidden fields and to ensure schema fields
+ have eidparam set to True
+
+ edit[s|o] hidden fields are used to indicate the value for the
+ associated field before the (potential) modification made when
+ submitting the form.
+ """
+ eschema = self.edited_entity.e_schema
+ for field in self.fields[:]:
+ for field in field.actual_fields(self):
+ fieldname = field.name
+ if fieldname != 'eid' and (
+ (eschema.has_subject_relation(fieldname) or
+ eschema.has_object_relation(fieldname))):
+ field.eidparam = True
+ self.fields.append(HiddenInitialValueField(field))
+ return super(EntityFieldsForm, self).form_build_context(values)
+
+ def form_field_value(self, field, load_bytes=False):
+ """return field's *typed* value
+
+ overriden to deal with
+ * special eid / __type / edits- / edito- fields
+ * lookup for values on edited entities
+ """
+ attr = field.name
+ entity = self.edited_entity
+ if attr == 'eid':
+ return entity.eid
+ if not field.eidparam:
+ return super(EntityFieldsForm, self).form_field_value(field, load_bytes)
+ if attr.startswith('edits-') or attr.startswith('edito-'):
+ # edit[s|o]- fieds must have the actual value stored on the entity
+ assert hasattr(field, 'visible_field')
+ vfield = field.visible_field
+ assert vfield.eidparam
+ if entity.has_eid():
+ return self.form_field_value(vfield)
+ return INTERNAL_FIELD_VALUE
+ if attr == '__type':
+ return entity.id
+ if self.schema.rschema(attr).is_final():
+ attrtype = entity.e_schema.destination(attr)
+ if attrtype == 'Password':
+ return entity.has_eid() and INTERNAL_FIELD_VALUE or ''
+ if attrtype == 'Bytes':
+ if entity.has_eid():
+ if load_bytes:
+ return getattr(entity, attr)
+ # XXX value should reflect if some file is already attached
+ return True
+ return False
+ if entity.has_eid() or attr in entity:
+ value = getattr(entity, attr)
+ else:
+ value = self._form_field_default_value(field, load_bytes)
+ return value
+ # non final relation field
+ if entity.has_eid() or entity.relation_cached(attr, field.role):
+ value = [r[0] for r in entity.related(attr, field.role)]
+ else:
+ value = self._form_field_default_value(field, load_bytes)
+ return value
+
+ def form_field_format(self, field):
+ """return MIME type used for the given (text or bytes) field"""
+ entity = self.edited_entity
+ if field.eidparam and entity.e_schema.has_metadata(field.name, 'format') and (
+ entity.has_eid() or '%s_format' % field.name in entity):
+ return self.edited_entity.attr_metadata(field.name, 'format')
+ return self.req.property_value('ui.default-text-format')
+
+ def form_field_encoding(self, field):
+ """return encoding used for the given (text) field"""
+ entity = self.edited_entity
+ if field.eidparam and entity.e_schema.has_metadata(field.name, 'encoding') and (
+ entity.has_eid() or '%s_encoding' % field.name in entity):
+ return self.edited_entity.attr_metadata(field.name, 'encoding')
+ return super(EntityFieldsForm, self).form_field_encoding(field)
+
+ def form_field_name(self, field):
+ """return qualified name for the given field"""
+ if field.eidparam:
+ return eid_param(field.name, self.edited_entity.eid)
+ return field.name
+
+ def form_field_id(self, field):
+ """return dom id for the given field"""
+ if field.eidparam:
+ return eid_param(field.id, self.edited_entity.eid)
+ return field.id
+
+ def form_field_vocabulary(self, field, limit=None):
+ """return vocabulary for the given field"""
+ role, rtype = field.role, field.name
+ method = '%s_%s_vocabulary' % (role, rtype)
+ try:
+ vocabfunc = getattr(self, method)
+ except AttributeError:
+ try:
+ # XXX bw compat, <role>_<rtype>_vocabulary on the entity
+ vocabfunc = getattr(self.edited_entity, method)
+ except AttributeError:
+ vocabfunc = getattr(self, '%s_relation_vocabulary' % role)
+ else:
+ warn('found %s on %s, should be set on a specific form'
+ % (method, self.edited_entity.id), DeprecationWarning)
+ # NOTE: it is the responsibility of `vocabfunc` to sort the result
+ # (direclty through RQL or via a python sort). This is also
+ # important because `vocabfunc` might return a list with
+ # couples (label, None) which act as separators. In these
+ # cases, it doesn't make sense to sort results afterwards.
+ return vocabfunc(rtype, limit)
+
+ def subject_relation_vocabulary(self, rtype, limit=None):
+ """defaut vocabulary method for the given relation, looking for
+ relation's object entities (i.e. self is the subject)
+ """
+ entity = self.edited_entity
+ if isinstance(rtype, basestring):
+ rtype = entity.schema.rschema(rtype)
+ done = None
+ assert not rtype.is_final(), rtype
+ if entity.has_eid():
+ done = set(e.eid for e in getattr(entity, str(rtype)))
+ result = []
+ rsetsize = None
+ for objtype in rtype.objects(entity.e_schema):
+ if limit is not None:
+ rsetsize = limit - len(result)
+ result += self._relation_vocabulary(rtype, objtype, 'subject',
+ rsetsize, done)
+ if limit is not None and len(result) >= limit:
+ break
+ return result
+
+ def object_relation_vocabulary(self, rtype, limit=None):
+ """defaut vocabulary method for the given relation, looking for
+ relation's subject entities (i.e. self is the object)
+ """
+ entity = self.edited_entity
+ if isinstance(rtype, basestring):
+ rtype = entity.schema.rschema(rtype)
+ done = None
+ if entity.has_eid():
+ done = set(e.eid for e in getattr(entity, 'reverse_%s' % rtype))
+ result = []
+ rsetsize = None
+ for subjtype in rtype.subjects(entity.e_schema):
+ if limit is not None:
+ rsetsize = limit - len(result)
+ result += self._relation_vocabulary(rtype, subjtype, 'object',
+ rsetsize, done)
+ if limit is not None and len(result) >= limit:
+ break
+ return result
+
+ def subject_in_state_vocabulary(self, rtype, limit=None):
+ """vocabulary method for the in_state relation, looking for relation's
+ object entities (i.e. self is the subject) according to initial_state,
+ state_of and next_state relation
+ """
+ entity = self.edited_entity
+ if not entity.has_eid() or not entity.in_state:
+ # get the initial state
+ rql = 'Any S where S state_of ET, ET name %(etype)s, ET initial_state S'
+ rset = self.req.execute(rql, {'etype': str(entity.e_schema)})
+ if rset:
+ return [(rset.get_entity(0, 0).view('combobox'), rset[0][0])]
+ return []
+ results = []
+ for tr in entity.in_state[0].transitions(entity):
+ state = tr.destination_state[0]
+ results.append((state.view('combobox'), state.eid))
+ return sorted(results)
+
+
+class CompositeForm(FieldsForm):
+ """form composed for sub-forms"""
+ id = 'composite'
+ form_renderer_id = id
+
+ def __init__(self, *args, **kwargs):
+ super(CompositeForm, self).__init__(*args, **kwargs)
+ self.forms = []
+
+ def form_add_subform(self, subform):
+ """mark given form as a subform and append it"""
+ subform.is_subform = True
+ self.forms.append(subform)
--- a/web/views/ibreadcrumbs.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/ibreadcrumbs.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""navigation components definition for CubicWeb web client
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
_ = unicode
--- a/web/views/idownloadable.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/idownloadable.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Specific views for entities implementing IDownloadable
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
_ = unicode
--- a/web/views/igeocodable.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/igeocodable.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Specific views for entities implementing IGeocodable
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/iprogress.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/iprogress.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Specific views for entities implementing IProgress
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/isioc.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/isioc.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Specific views for SIOC interfaces
:organization: Logilab
-:copyright: 2003-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2003-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/magicsearch.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/magicsearch.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/management.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/management.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
_ = unicode
@@ -14,13 +15,12 @@
from cubicweb.view import AnyRsetView, StartupView, EntityView
from cubicweb.common.uilib import html_traceback, rest_traceback
from cubicweb.web import formwidgets
-from cubicweb.web.form import FieldsForm, EntityFieldsForm
from cubicweb.web.formfields import guess_field
-from cubicweb.web.formrenderers import HTableFormRenderer
SUBMIT_MSGID = _('Submit bug report')
MAIL_SUBMIT_MSGID = _('Submit bug report by mail')
+
class SecurityViewMixIn(object):
"""display security information for a given schema """
@@ -105,11 +105,13 @@
def owned_by_edit_form(self, entity):
self.w('<h3>%s</h3>' % self.req._('ownership'))
msg = self.req._('ownerships have been changed')
- form = EntityFieldsForm(self.req, None, entity=entity, submitmsg=msg,
- form_buttons=[formwidgets.SubmitButton()],
- domid='ownership%s' % entity.eid,
- __redirectvid='security',
- __redirectpath=entity.rest_path())
+ form = self.vreg.select_object('forms', 'base', self.req, entity=entity,
+ form_renderer_id='base',
+ submitmsg=msg,
+ form_buttons=[formwidgets.SubmitButton()],
+ domid='ownership%s' % entity.eid,
+ __redirectvid='security',
+ __redirectpath=entity.rest_path())
field = guess_field(entity.e_schema, self.schema.rschema('owned_by'))
form.append_field(field)
self.w(form.form_render(display_progress_div=False))
@@ -162,11 +164,11 @@
newperm = self.vreg.etype_class('CWPermission')(self.req, None)
newperm.eid = self.req.varmaker.next()
w(u'<p>%s</p>' % _('add a new permission'))
- form = EntityFieldsForm(self.req, None, entity=newperm,
- form_buttons=[formwidgets.SubmitButton()],
- domid='reqperm%s' % entity.eid,
- __redirectvid='security',
- __redirectpath=entity.rest_path())
+ form = self.vreg.select_object('forms', 'base', self.req, entity=newperm,
+ form_buttons=[formwidgets.SubmitButton()],
+ domid='reqperm%s' % entity.eid,
+ __redirectvid='security',
+ __redirectpath=entity.rest_path())
form.form_add_hidden('require_permission', entity.eid, role='object',
eidparam=True)
permnames = getattr(entity, '__permissions__', None)
@@ -182,7 +184,9 @@
form.append_field(field)
field = guess_field(cwpermschema, self.schema.rschema('require_group'))
form.append_field(field)
- self.w(form.form_render(renderer=HTableFormRenderer(display_progress_div=False)))
+ renderer = self.select_object('formrenderers', 'htable', self.req,
+ display_progress_div=False)
+ self.w(form.form_render(renderer=renderer))
class ErrorView(AnyRsetView):
@@ -238,7 +242,7 @@
submiturl = self.config['submit-url']
submitmail = self.config['submit-mail']
if submiturl or submitmail:
- form = FieldsForm(self.req, set_error_url=False)
+ form = self.select_object('forms', 'base', self.req, set_error_url=False)
binfo = text_error_description(ex, excinfo, req, eversion, cversions)
form.form_add_hidden('description', binfo)
form.form_add_hidden('__bugreporting', '1')
--- a/web/views/massmailing.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/massmailing.py Fri May 29 20:22:39 2009 +0200
@@ -1,10 +1,12 @@
"""Mass mailing form views
:organization: Logilab
-:copyright: 2007-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2007-2009 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
"""
__docformat__ = "restructuredtext en"
+_ = unicode
import operator
@@ -13,12 +15,11 @@
from cubicweb.view import EntityView
from cubicweb.web import stdmsgs
from cubicweb.web.action import Action
-from cubicweb.web.form import FieldsForm, FormViewMixIn
-from cubicweb.web.formrenderers import FormRenderer
+from cubicweb.web.form import FormViewMixIn
from cubicweb.web.formfields import StringField
from cubicweb.web.formwidgets import CheckBox, TextInput, AjaxWidget, ImgButton
+from cubicweb.web.views import forms, formrenderers
-_ = unicode
class SendEmailAction(Action):
id = 'sendemail'
@@ -36,18 +37,20 @@
**params)
-class MassMailingForm(FieldsForm):
+class MassMailingForm(forms.FieldsForm):
id = 'massmailing'
sender = StringField(widget=TextInput({'disabled': 'disabled'}), label=_('From:'))
recipient = StringField(widget=CheckBox(), label=_('Recipients:'))
- subject = StringField(label=_('Subject:'))
+ subject = StringField(label=_('Subject:'), max_length=256)
mailbody = StringField(widget=AjaxWidget(wdgtype='TemplateTextField',
inputid='mailbody'))
+
form_buttons = [ImgButton('sendbutton', "javascript: $('#sendmail').submit()",
_('send email'), 'SEND_EMAIL_ICON'),
ImgButton('cancelbutton', "javascript: history.back()",
stdmsgs.BUTTON_CANCEL, 'CANCEL_EMAIL_ICON')]
+ form_renderer_id = id
def form_field_vocabulary(self, field):
if field.name == 'recipient':
@@ -78,7 +81,8 @@
helpmsg, u'\n'.join(substs))
-class MassMailingFormRenderer(FormRenderer):
+class MassMailingFormRenderer(formrenderers.FormRenderer):
+ id = 'massmailing'
button_bar_class = u'toolbar'
def _render_fields(self, fields, w, form):
@@ -124,4 +128,4 @@
from_addr = '%s <%s>' % (req.user.dc_title(), req.user.get_email())
form = self.vreg.select_object('forms', 'massmailing', self.req, self.rset,
action='sendmail', domid='sendmail')
- self.w(form.form_render(sender=from_addr, renderer=MassMailingFormRenderer()))
+ self.w(form.form_render(sender=from_addr))
--- a/web/views/navigation.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/navigation.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""navigation components definition for CubicWeb web client
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/old_calendar.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/old_calendar.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""html calendar views
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
from datetime import date, time, timedelta
--- a/web/views/owl.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/owl.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""produces some Ontology Web Language schema and views
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/plots.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/plots.py Fri May 29 20:22:39 2009 +0200
@@ -3,6 +3,7 @@
:organization: Logilab
:copyright: 2007-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL.
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
+:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
__docformat__ = "restructuredtext en"
@@ -14,7 +15,7 @@
from logilab.common import flatten
from logilab.mtconverter import html_escape
-from cubicweb.utils import make_uid, UStringIO
+from cubicweb.utils import make_uid, UStringIO, datetime2ticks
from cubicweb.vregistry import objectify_selector
from cubicweb.web.views import baseviews
@@ -59,9 +60,6 @@
filtered.append( (x, y) )
return sorted(filtered)
-def datetime2ticks(date):
- return time.mktime(date.timetuple()) * 1000
-
class PlotWidget(object):
# XXX refactor with cubicweb.web.views.htmlwidgets.HtmlWidget
def _initialize_stream(self, w=None):
@@ -87,7 +85,7 @@
lines: {show: true},
grid: {hoverable: true},
xaxis: {mode: %(mode)s}});
-jQuery('#%(figid)s').bind('plothover', onPlotHover);
+jQuery("#%(figid)s").bind("plothover", onPlotHover);
'''
def __init__(self, labels, plots, timemode=False):
@@ -138,7 +136,7 @@
nbcols = len(self.rset.rows[0])
for col in xrange(1, nbcols):
data = [row[col] for row in self.rset]
- plots.append(filterout_nulls(abscissa, plot))
+ plots.append(filterout_nulls(abscissa, data))
plotwidget = FlotPlotWidget(varnames, plots, timemode=self.timemode)
plotwidget.render(self.req, width, height, w=self.w)
@@ -177,10 +175,22 @@
__select__ = at_least_two_columns() & second_column_is_number()
+ def _guess_vid(self, row):
+ etype = self.rset.description[row][0]
+ if self.schema.eschema(etype).is_final():
+ return 'final'
+ return 'textincontext'
+
def call(self, title=None, width=None, height=None):
- labels = ['%s: %s' % (row[0].encode(self.req.encoding), row[1])
- for row in self.rset]
- values = [(row[1] or 0) for row in self.rset]
+ labels = []
+ values = []
+ for rowidx, (_, value) in enumerate(self.rset):
+ if value is not None:
+ vid = self._guess_vid(rowidx)
+ label = '%s: %s' % (self.view(vid, self.rset, row=rowidx, col=0),
+ value)
+ labels.append(label.encode(self.req.encoding))
+ values.append(value)
pie = PieChartWidget(labels, values, pieclass=self.pieclass,
title=title)
if width is not None:
--- a/web/views/primary.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/primary.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""The default primary view
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
_ = unicode
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/views/pyviews.py Fri May 29 20:22:39 2009 +0200
@@ -0,0 +1,42 @@
+"""Views to display bare python values
+
+:organization: Logilab
+:copyright: 2009 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
+"""
+__docformat__ = "restructuredtext en"
+
+from cubicweb.view import View
+from cubicweb.selectors import match_kwargs
+
+class PyValTableView(View):
+ id = 'pyvaltable'
+ __select__ = match_kwargs('pyvalue')
+
+ def call(self, pyvalue, headers=None):
+ if headers is None:
+ headers = self.req.form.get('headers')
+ self.w(u'<table class="listing">\n')
+ if headers:
+ self.w(u'<tr>')
+ for header in headers:
+ self.w(u'<th>%s</th>' % header)
+ self.w(u'</tr>\n')
+ for row in pyvalue:
+ self.w(u'<tr>')
+ for cell in row:
+ self.w(u'<td>%s</td>' % cell)
+ self.w(u'</tr>\n')
+ self.w(u'</table>\n')
+
+
+class PyValListView(View):
+ id = 'pyvallist'
+ __select__ = match_kwargs('pyvalue')
+
+ def call(self, pyvalue):
+ self.w(u'<ul>\n')
+ for line in pyvalue:
+ self.w(u'<li>%s</li>\n' % line)
+ self.w(u'</ul>\n')
--- a/web/views/schema.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/schema.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Specific views for schema related entities
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
@@ -16,7 +17,8 @@
from cubicweb.view import EntityView, StartupView
from cubicweb.common import tags, uilib
from cubicweb.web import action
-from cubicweb.web.views import TmpFileViewMixin, primary, baseviews
+from cubicweb.web.views import TmpFileViewMixin, primary, baseviews, tabs
+from cubicweb.web.facet import AttributeFacet
class ViewSchemaAction(action.Action):
@@ -31,8 +33,6 @@
return self.build_url(self.id)
-# schema entity types views ###################################################
-
class CWRDEFPrimaryView(primary.PrimaryView):
__select__ = implements('CWAttribute', 'CWRelation')
cache_max_age = 60*60*2 # stay in http cache for 2 hours by default
@@ -42,6 +42,7 @@
% (entity.dc_type().capitalize(),
html_escape(entity.dc_long_title())))
+# CWEType ######################################################################
class CWETypeOneLineView(baseviews.OneLineView):
__select__ = implements('CWEType')
@@ -55,32 +56,118 @@
if final:
self.w(u'</em>')
-
-# in memory schema views (yams class instances) ###############################
SKIPPED_RELS = ('is', 'is_instance_of', 'identity', 'created_by', 'owned_by',
'has_text',)
-class CWETypeSchemaView(primary.PrimaryView):
- id = 'eschema'
+class CWETypePrimaryView(tabs.TabsMixin, primary.PrimaryView):
__select__ = implements('CWEType')
title = _('in memory entity schema')
main_related_section = False
skip_rels = SKIPPED_RELS
+ tabs = [_('cwetype-schema-text'), _('cwetype-schema-image'),
+ _('cwetype-schema-permissions'), _('cwetype-workflow')]
+ default_tab = 'cwetype-schema-text'
- def render_entity_attributes(self, entity):
- super(CWETypeSchemaView, self).render_entity_attributes(entity)
- eschema = self.vreg.schema.eschema(entity.name)
- viewer = SchemaViewer(self.req)
- layout = viewer.visit_entityschema(eschema, skiprels=self.skip_rels)
- self.w(uilib.ureport_as_html(layout))
- if not eschema.is_final():
- msg = self.req._('graphical schema for %s') % entity.name
- self.w(tags.img(src=entity.absolute_url(vid='eschemagraph'),
- alt=msg))
+ def render_entity(self, entity):
+ self.render_entity_title(entity)
+ self.w(u'<div>%s</div>' % entity.description)
+ self.render_tabs(self.tabs, self.default_tab, entity)
+
+
+class CWETypeSTextView(EntityView):
+ id = 'cwetype-schema-text'
+ __select__ = EntityView.__select__ & implements('CWEType')
+
+ def cell_call(self, row, col):
+ entity = self.entity(row, col)
+ self.w(u'<h2>%s</h2>' % _('Attributes'))
+ rset = self.req.execute('Any N,F,D,GROUP_CONCAT(C),I,J,DE,A '
+ 'GROUPBY N,F,D,AA,A,I,J,DE '
+ 'ORDERBY AA WHERE A is CWAttribute, '
+ 'A ordernum AA, A defaultval D, '
+ 'A constrained_by C?, A description DE, '
+ 'A fulltextindexed I, A internationalizable J, '
+ 'A relation_type R, R name N, '
+ 'A to_entity O, O name F, '
+ 'A from_entity S, S eid %(x)s',
+ {'x': entity.eid})
+ self.wview('editable-table', rset, 'null', displayfilter=True)
+ self.w(u'<h2>%s</h2>' % _('Relations'))
+ rset = self.req.execute('Any N,C,F,M,K,D,A ORDERBY N '
+ 'WITH N,C,F,M,D,K,A BEING ('
+ '(Any N,C,F,M,K,D,A '
+ 'ORDERBY N WHERE A is CWRelation, '
+ 'A description D, A composite K?, '
+ 'A relation_type R, R name N, '
+ 'A to_entity O, O name F, '
+ 'A cardinality C, O meta M, '
+ 'A from_entity S, S eid %(x)s)'
+ ' UNION '
+ '(Any N,C,F,M,K,D,A '
+ 'ORDERBY N WHERE A is CWRelation, '
+ 'A description D, A composite K?, '
+ 'A relation_type R, R name N, '
+ 'A from_entity S, S name F, '
+ 'A cardinality C, S meta M, '
+ 'A to_entity O, O eid %(x)s))'
+ ,{'x': entity.eid})
+ self.wview('editable-table', rset, 'null', displayfilter=True)
+class CWETypeSImageView(EntityView):
+ id = 'cwetype-schema-image'
+ __select__ = EntityView.__select__ & implements('CWEType')
+
+ def cell_call(self, row, col):
+ entity = self.entity(row, col)
+ url = entity.absolute_url(vid='schemagraph')
+ self.w(u'<img src="%s" alt="%s"/>' % (
+ html_escape(url),
+ html_escape(self.req._('graphical schema for %s') % entity.name)))
+
+class CWETypeSPermView(EntityView):
+ id = 'cwetype-schema-permissions'
+ __select__ = EntityView.__select__ & implements('CWEType')
+
+ def cell_call(self, row, col):
+ entity = self.entity(row, col)
+ self.w(u'<h2>%s</h2>' % _('Add permissions'))
+ rset = self.req.execute('Any P WHERE X add_permission P, '
+ 'X eid %(x)s',
+ {'x': entity.eid})
+ self.wview('outofcontext', rset, 'null')
+ self.w(u'<h2>%s</h2>' % _('Read permissions'))
+ rset = self.req.execute('Any P WHERE X read_permission P, '
+ 'X eid %(x)s',
+ {'x': entity.eid})
+ self.wview('outofcontext', rset, 'null')
+ self.w(u'<h2>%s</h2>' % _('Update permissions'))
+ rset = self.req.execute('Any P WHERE X update_permission P, '
+ 'X eid %(x)s',
+ {'x': entity.eid})
+ self.wview('outofcontext', rset, 'null')
+ self.w(u'<h2>%s</h2>' % _('Delete permissions'))
+ rset = self.req.execute('Any P WHERE X delete_permission P, '
+ 'X eid %(x)s',
+ {'x': entity.eid})
+ self.wview('outofcontext', rset, 'null')
+
+class CWETypeSWorkflowView(EntityView):
+ id = 'cwetype-workflow'
+ __select__ = EntityView.__select__ & implements('CWEType')
+
+ def cell_call(self, row, col):
+ entity = self.entity(row, col)
+ if entity.reverse_state_of:
+ self.w(u'<img src="%s" alt="%s"/>' % (
+ html_escape(entity.absolute_url(vid='ewfgraph')),
+ html_escape(self.req._('graphical workflow for %s') % entity.name)))
+ else:
+ self.w(u'<p>%s</p>' % _('There is no workflow defined for this entity.'))
+
+# CWRType ######################################################################
+
class CWRTypeSchemaView(primary.PrimaryView):
- id = 'eschema'
__select__ = implements('CWRType')
title = _('in memory relation schema')
main_related_section = False
@@ -93,25 +180,12 @@
self.w(uilib.ureport_as_html(layout))
if not rschema.is_final():
msg = self.req._('graphical schema for %s') % entity.name
- self.w(tags.img(src=entity.absolute_url(vid='eschemagraph'),
+ self.w(tags.img(src=entity.absolute_url(vid='schemagraph'),
alt=msg))
# schema images ###############################################################
-class ImageView(EntityView):
- __select__ = implements('CWEType')
- id = 'image'
- title = _('image')
-
- def cell_call(self, row, col):
- entity = self.entity(row, col)
- url = entity.absolute_url(vid='eschemagraph')
- self.w(u'<img src="%s" alt="%s"/>' % (
- html_escape(url),
- html_escape(self.req._('graphical schema for %s') % entity.name)))
-
-
class RestrictedSchemaDotPropsHandler(s2d.SchemaDotPropsHandler):
def __init__(self, req):
# FIXME: colors are arbitrary
@@ -187,7 +261,7 @@
prophdlr=RestrictedSchemaDotPropsHandler(self.req))
class CWETypeSchemaImageView(TmpFileViewMixin, EntityView):
- id = 'eschemagraph'
+ id = 'schemagraph'
__select__ = implements('CWEType')
content_type = 'image/png'
@@ -211,3 +285,15 @@
visitor = OneHopRSchemaVisitor(self.req, rschema)
s2d.schema2dot(outputfile=tmpfile, visitor=visitor,
prophdlr=RestrictedSchemaDotPropsHandler(self.req))
+
+### facets
+
+class CWMetaFacet(AttributeFacet):
+ id = 'cwmeta-facet'
+ __select__ = AttributeFacet.__select__ & implements('CWEType')
+ rtype = 'meta'
+
+class CWFinalFacet(AttributeFacet):
+ id = 'cwfinal-facet'
+ __select__ = AttributeFacet.__select__ & implements('CWEType')
+ rtype = 'final'
--- a/web/views/searchrestriction.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/searchrestriction.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
a search
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/sessions.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/sessions.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
object :/
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/startup.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/startup.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
apply to a result set.
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
_ = unicode
@@ -12,12 +13,12 @@
from logilab.mtconverter import html_escape
from cubicweb.view import StartupView
-from cubicweb.selectors import match_user_groups
+from cubicweb.selectors import match_user_groups, implements
from cubicweb.common.uilib import ureport_as_html
from cubicweb.web import ajax_replace_url, uicfg, httpcache
+from cubicweb.web.views import tabs
from cubicweb.web.views.management import SecurityViewMixIn
-
class ManageView(StartupView):
id = 'manage'
title = _('manage')
@@ -163,42 +164,44 @@
def display_folders(self):
return 'Folder' in self.schema and self.req.execute('Any COUNT(X) WHERE X is Folder')[0][0]
-
-
-class SchemaView(StartupView):
+class SchemaView(tabs.TabsMixin, StartupView):
id = 'schema'
title = _('application schema')
+ tabs = [_('schema-text'), _('schema-image')]
+ default_tab = 'schema-image'
def call(self):
"""display schema information"""
self.req.add_js('cubicweb.ajax.js')
self.req.add_css(('cubicweb.schema.css','cubicweb.acl.css'))
- withmeta = int(self.req.form.get('withmeta', 0))
- section = self.req.form.get('sec', '')
+ self.w(u'<h1>%s</h1>' % _('Schema of the data model'))
+ self.render_tabs(self.tabs, self.default_tab)
+
+class SchemaTabImageView(StartupView):
+ id = 'schema-image'
+
+ def call(self):
+ self.w(_(u'<div>This schema of the data model <em>excludes</em> the '
+ u'meta-data, but you can also display a <a href="%s">complete '
+ u'schema with meta-data</a>.</div>')
+ % html_escape(self.build_url('view', vid='schemagraph', withmeta=1)))
self.w(u'<img src="%s" alt="%s"/>\n' % (
- html_escape(self.req.build_url('view', vid='schemagraph', withmeta=withmeta)),
+ html_escape(self.req.build_url('view', vid='schemagraph', withmeta=0)),
self.req._("graphical representation of the application'schema")))
- if withmeta:
- self.w(u'<div><a href="%s">%s</a></div>' % (
- html_escape(self.build_url('schema', withmeta=0, sec=section)),
- self.req._('hide meta-data')))
- else:
- self.w(u'<div><a href="%s">%s</a></div>' % (
- html_escape(self.build_url('schema', withmeta=1, sec=section)),
- self.req._('show meta-data')))
- self.w(u'<a href="%s">%s</a><br/>' %
- (html_escape(ajax_replace_url('detailed_schema', '', 'schematext',
- skipmeta=int(not withmeta))),
- self.req._('detailed schema view')))
- if self.req.user.matching_groups('managers'):
- self.w(u'<a href="%s">%s</a>' %
- (html_escape(ajax_replace_url('detailed_schema', '', 'schema_security',
- skipmeta=int(not withmeta))),
- self.req._('security')))
- self.w(u'<div id="detailed_schema">')
- if section:
- self.wview(section, None)
- self.w(u'</div>')
+
+class SchemaTabTextView(StartupView):
+ id = 'schema-text'
+
+ def call(self):
+ self.w(u'<p>%s</p>' % _('This is the list of types defined in the data '
+ 'model ofin this application.'))
+ self.w(u'<p>%s</p>' % _('<em>meta</em> is True for types that are defined by the '
+ 'framework itself (e.g. User and Group). '
+ '<em>final</em> is True for types that can not be the '
+ 'subject of a relation (e.g. Int and String).'))
+ rset = self.req.execute('Any X,M,F ORDERBY N WHERE X is CWEType, X name N, '
+ 'X meta M, X final F')
+ self.wview('editable-table', rset, displayfilter=True)
class ManagerSchemaPermissionsView(StartupView, SecurityViewMixIn):
@@ -314,3 +317,4 @@
skipmeta=skipmeta)
self.w(ureport_as_html(layout))
+
--- a/web/views/tableview.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/tableview.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/tabs.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/tabs.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""base classes to handle tabbed views
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"
@@ -13,7 +14,7 @@
from cubicweb.selectors import partial_has_related_entities
from cubicweb.view import EntityView
from cubicweb.common import tags, uilib
-
+from cubicweb.utils import make_uid
class LazyViewMixin(object):
"""provides two convenience methods for the tab machinery
@@ -91,11 +92,11 @@
continue
return selected_tabs
- def render_tabs(self, tabs, default, entity):
+ def render_tabs(self, tabs, default, entity=None):
# tabbed views do no support concatenation
# hence we delegate to the default tab if there is more than on entity
# in the result set
- if len(self.rset) > 1:
+ if entity and len(self.rset) > 1:
entity.view(default, w=self.w)
return
# XXX (syt) fix below add been introduced at some point to fix something
@@ -117,7 +118,11 @@
active_tab = self.active_tab(tabs, default)
# build the html structure
w = self.w
- w(u'<div id="entity-tabs-%s">' % entity.eid)
+ if entity:
+ w(u'<div id="entity-tabs-%s">' % entity.eid)
+ else:
+ uid = make_uid('tab')
+ w(u'<div id="entity-tabs-%s">' % uid)
w(u'<ul>')
for tab in tabs:
w(u'<li>')
@@ -131,7 +136,10 @@
w(u'</div>')
for tab in tabs:
w(u'<div id="as-%s">' % tab)
- self.lazyview(tab, eid=entity.eid)
+ if entity:
+ self.lazyview(tab, eid=entity.eid)
+ else:
+ self.lazyview(tab, static=True)
w(u'</div>')
# call the set_tab() JS function *after* each tab is generated
# because the callback binding needs to be done before
@@ -140,7 +148,7 @@
set_tab('%(vid)s', '%(cookiename)s');
""" % {'tabindex' : tabs.index(active_tab),
'vid' : active_tab,
- 'eeid' : entity.eid,
+ 'eeid' : (entity and entity.eid or uid),
'cookiename' : self.cookie_name})
--- a/web/views/timeline.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/timeline.py Fri May 29 20:22:39 2009 +0200
@@ -3,8 +3,9 @@
cf. http://code.google.com/p/simile-widgets/
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/timetable.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/timetable.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""html calendar views
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
from logilab.mtconverter import html_escape
--- a/web/views/treeview.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/treeview.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Set of tree-building widgets, based on jQuery treeview plugin
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/urlpublishing.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/urlpublishing.py Fri May 29 20:22:39 2009 +0200
@@ -18,8 +18,9 @@
because of redirecting instead of direct traversal
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/urlrewrite.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/urlrewrite.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""Rules based url rewriter component, to get configurable RESTful urls
:organization: Logilab
-:copyright: 2007-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2007-2009 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
"""
import re
--- a/web/views/vcard.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/vcard.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""vcard import / export
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/wdoc.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/wdoc.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""inline help system, using ReST file in products `wdoc` directory
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/views/workflow.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/workflow.py Fri May 29 20:22:39 2009 +0200
@@ -4,8 +4,9 @@
* workflow entities views (State, Transition, TrInfo)
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
_ = unicode
@@ -21,21 +22,22 @@
from cubicweb.web.form import FormViewMixIn
from cubicweb.web.formfields import StringField, RichTextField
from cubicweb.web.formwidgets import HiddenInput, SubmitButton, Button
-from cubicweb.web.views import TmpFileViewMixin
-from cubicweb.web.views.boxes import EditBox
+from cubicweb.web.views import TmpFileViewMixin, forms
# IWorkflowable views #########################################################
-class ChangeStateForm(form.EntityFieldsForm):
+class ChangeStateForm(forms.EntityFieldsForm):
id = 'changestate'
+ form_renderer_id = 'base' # don't want EntityFormRenderer
+ form_buttons = [SubmitButton(stdmsgs.YES),
+ Button(stdmsgs.NO, cwaction='cancel')]
+
__method = StringField(name='__method', initial='set_state',
widget=HiddenInput)
state = StringField(eidparam=True, widget=HiddenInput)
trcomment = RichTextField(label=_('comment:'), eidparam=True)
- form_buttons = [SubmitButton(stdmsgs.YES),
- Button(stdmsgs.NO, cwaction='cancel')]
class ChangeStateFormView(FormViewMixIn, view.EntityView):
--- a/web/views/xbel.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/xbel.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""xbel views
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
_ = unicode
--- a/web/views/xmlrss.py Fri May 29 16:11:49 2009 +0200
+++ b/web/views/xmlrss.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""base xml and rss views
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
_ = unicode
--- a/web/webconfig.py Fri May 29 16:11:49 2009 +0200
+++ b/web/webconfig.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""common web configuration for twisted/modpython applications
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/webctl.py Fri May 29 16:11:49 2009 +0200
+++ b/web/webctl.py Fri May 29 20:22:39 2009 +0200
@@ -2,8 +2,9 @@
web configuration
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/web/widgets.py Fri May 29 16:11:49 2009 +0200
+++ b/web/widgets.py Fri May 29 20:22:39 2009 +0200
@@ -4,8 +4,9 @@
serialization time
:organization: Logilab
-:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2001-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/wsgi/__init__.py Fri May 29 16:11:49 2009 +0200
+++ b/wsgi/__init__.py Fri May 29 20:22:39 2009 +0200
@@ -7,8 +7,9 @@
WSGI corresponding PEP: http://www.python.org/dev/peps/pep-0333/
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/wsgi/handler.py Fri May 29 16:11:49 2009 +0200
+++ b/wsgi/handler.py Fri May 29 20:22:39 2009 +0200
@@ -1,8 +1,9 @@
"""WSGI request handler for cubicweb
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"
--- a/wsgi/request.py Fri May 29 16:11:49 2009 +0200
+++ b/wsgi/request.py Fri May 29 20:22:39 2009 +0200
@@ -5,8 +5,9 @@
http://www.djangoproject.com/
:organization: Logilab
-:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+:copyright: 2008-2009 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
"""
__docformat__ = "restructuredtext en"