--- a/.hgtags Thu Jul 23 15:29:07 2009 +0200
+++ b/.hgtags Thu Jul 23 15:33:03 2009 +0200
@@ -48,3 +48,5 @@
1cf9e44e2f1f4415253b8892a0adfbd3b69e84fd cubicweb-version-3_3_3
47b5236774a0cf3b1cfe75f6d4bd2ec989644ace cubicweb-version-3_3_3
2ba27ce8ecd9828693ec53c517e1c8810cbbe33e cubicweb-debian-version-3_3_3-2
+d46363eac5d71bc1570d69337955154dfcd8fcc8 cubicweb-version-3.3.4
+7dc22caa7640bf70fcae55afb6d2326829dacced cubicweb-debian-version-3.3.4-1
--- a/__init__.py Thu Jul 23 15:29:07 2009 +0200
+++ b/__init__.py Thu Jul 23 15:33:03 2009 +0200
@@ -300,3 +300,6 @@
except AttributeError:
return neg_role(obj.role)
+def underline_title(title, car='-'):
+ return title+'\n'+(car*len(title))
+
--- a/__pkginfo__.py Thu Jul 23 15:29:07 2009 +0200
+++ b/__pkginfo__.py Thu Jul 23 15:33:03 2009 +0200
@@ -7,7 +7,7 @@
distname = "cubicweb"
modname = "cubicweb"
-numversion = (3, 3, 3)
+numversion = (3, 3, 4)
version = '.'.join(str(num) for num in numversion)
license = 'LGPL v2'
@@ -32,6 +32,13 @@
ftp = 'ftp://ftp.logilab.org/pub/cubicweb'
pyversions = ['2.4', '2.5']
+classifiers = [
+ 'Environment :: Web Environment',
+ 'Framework :: CubicWeb',
+ 'Programming Language :: Python',
+ 'Programming Language :: JavaScript',
+]
+
import sys
from os import listdir, environ
--- a/common/i18n.py Thu Jul 23 15:29:07 2009 +0200
+++ b/common/i18n.py Thu Jul 23 15:33:03 2009 +0200
@@ -63,7 +63,7 @@
"""generate .mo files for a set of languages into the `destdir` i18n directory
"""
from logilab.common.fileutils import ensure_fs_mode
- print 'compiling %s catalogs...' % destdir
+ print '-> compiling %s catalogs...' % destdir
errors = []
for lang in langs:
langdir = join(destdir, lang, 'LC_MESSAGES')
--- a/cwctl.py Thu Jul 23 15:29:07 2009 +0200
+++ b/cwctl.py Thu Jul 23 15:33:03 2009 +0200
@@ -10,7 +10,7 @@
from logilab.common.clcommands import register_commands, pop_arg
-from cubicweb import ConfigurationError, ExecutionError, BadCommandUsage
+from cubicweb import ConfigurationError, ExecutionError, BadCommandUsage, underline_title
from cubicweb.cwconfig import CubicWebConfiguration as cwcfg, CONFIGURATIONS
from cubicweb.toolsutils import Command, main_run, rm, create_dir, confirm
@@ -286,20 +286,22 @@
print ', '.join(cwcfg.available_cubes())
return
# create the registry directory for this application
+ print '\n'+underline_title('Creating the application %s' % appid)
create_dir(config.apphome)
# load site_cubicweb from the cubes dir (if any)
config.load_site_cubicweb()
# cubicweb-ctl configuration
- print '** application\'s %s configuration' % configname
- print '-' * 72
+ print '\n'+underline_title('Configuring the application (%s.conf)' % configname)
config.input_config('main', self.config.config_level)
# configuration'specific stuff
print
helper.bootstrap(cubes, self.config.config_level)
# write down configuration
config.save()
+ print '-> generated %s' % config.main_config_file()
# handle i18n files structure
# in the first cube given
+ print '-> preparing i18n catalogs'
from cubicweb.common import i18n
langs = [lang for lang, _ in i18n.available_catalogs(join(templdirs[0], 'i18n'))]
errors = config.i18ncompile(langs)
@@ -317,12 +319,7 @@
# this directory should be owned by the uid of the server process
print 'set %s as owner of the data directory' % config['uid']
chown(config.appdatahome, config['uid'])
- print
- print
- print '*' * 72
- print 'application %s (%s) created in %r' % (appid, configname,
- config.apphome)
- print
+ print '\n-> creation done for %r.\n' % config.apphome
helper.postcreate()
--- a/debian/changelog Thu Jul 23 15:29:07 2009 +0200
+++ b/debian/changelog Thu Jul 23 15:33:03 2009 +0200
@@ -1,3 +1,15 @@
+cubicweb (3.3.4-2) unstable; urgency=low
+
+ * fix conflicting test files
+
+ -- Sylvain Thénault <sylvain.thenault@logilab.fr> Tue, 21 Jul 2009 23:09:03 +0200
+
+cubicweb (3.3.4-1) unstable; urgency=low
+
+ * new upstream release
+
+ -- Sylvain Thénault <sylvain.thenault@logilab.fr> Tue, 21 Jul 2009 13:11:38 +0200
+
cubicweb (3.3.3-2) unstable; urgency=low
* re-release with "from __future__ import with_statement" commented out to
--- a/debian/cubicweb-dev.install.in Thu Jul 23 15:29:07 2009 +0200
+++ b/debian/cubicweb-dev.install.in Thu Jul 23 15:33:03 2009 +0200
@@ -1,2 +1,11 @@
debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/devtools/ usr/lib/PY_VERSION/site-packages/cubicweb/
debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/skeleton/ usr/lib/PY_VERSION/site-packages/cubicweb/
+debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/test usr/lib/PY_VERSION/site-packages/cubicweb/
+debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/common/test usr/lib/PY_VERSION/site-packages/cubicweb/common/
+debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/entities/test usr/lib/PY_VERSION/site-packages/cubicweb/entities/
+debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/ext/test usr/lib/PY_VERSION/site-packages/cubicweb/ext/
+debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/server/test usr/lib/PY_VERSION/site-packages/cubicweb/server/
+debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/sobjects/test usr/lib/PY_VERSION/site-packages/cubicweb/sobjects/
+debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/web/test usr/lib/PY_VERSION/site-packages/cubicweb/web/
+debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/etwist/test usr/lib/PY_VERSION/site-packages/cubicweb/etwist/
+debian/tmp/usr/lib/PY_VERSION/site-packages/cubicweb/goa/test usr/lib/PY_VERSION/site-packages/cubicweb/goa/
--- a/debian/rules Thu Jul 23 15:29:07 2009 +0200
+++ b/debian/rules Thu Jul 23 15:33:03 2009 +0200
@@ -47,12 +47,13 @@
dh_lintian
# Remove unittests directory (should be available in cubicweb-dev only)
- rm -rf debian/cubicweb-server/usr/share/pyshared/cubicweb/server/test
- rm -rf debian/cubicweb-server/usr/share/pyshared/cubicweb/sobjects/test
- rm -rf debian/cubicweb-dev/usr/share/pyshared/cubicweb/devtools/test
- rm -rf debian/cubicweb-web/usr/share/pyshared/cubicweb/web/test
- rm -rf debian/cubicweb-common/usr/share/pyshared/cubicweb/common/test
- rm -rf debian/cubicweb-common/usr/share/pyshared/cubicweb/entities/test
+ rm -rf debian/cubicweb-server/usr/lib/${PY_VERSION}/site-packages/cubicweb/server/test
+ rm -rf debian/cubicweb-server/usr/lib/${PY_VERSION}/site-packages/cubicweb/sobjects/test
+ rm -rf debian/cubicweb-web/usr/lib/${PY_VERSION}/site-packages/cubicweb/web/test
+ rm -rf debian/cubicweb-twisted/usr/lib/${PY_VERSION}/site-packages/cubicweb/etwist/test
+ rm -rf debian/cubicweb-common/usr/lib/${PY_VERSION}/site-packages/cubicweb/ext/test
+ rm -rf debian/cubicweb-common/usr/lib/${PY_VERSION}/site-packages/cubicweb/common/test
+ rm -rf debian/cubicweb-common/usr/lib/${PY_VERSION}/site-packages/cubicweb/entities/test
# cubes directory must be managed as a valid python module
touch debian/cubicweb-common/usr/share/cubicweb/cubes/__init__.py
--- a/devtools/devctl.py Thu Jul 23 15:29:07 2009 +0200
+++ b/devtools/devctl.py Thu Jul 23 15:33:03 2009 +0200
@@ -19,7 +19,7 @@
from logilab.common.textutils import get_csv
from logilab.common.clcommands import register_commands
-from cubicweb import CW_SOFTWARE_ROOT as BASEDIR, BadCommandUsage
+from cubicweb import CW_SOFTWARE_ROOT as BASEDIR, BadCommandUsage, underline_title
from cubicweb.__pkginfo__ import version as cubicwebversion
from cubicweb.toolsutils import Command, confirm, copy_skeleton
from cubicweb.web.webconfig import WebConfiguration
@@ -261,7 +261,7 @@
from cubicweb.common.i18n import extract_from_tal, execute
tempdir = tempdir.mkdtemp()
potfiles = [join(I18NDIR, 'entities.pot')]
- print '******** extract schema messages'
+ print '-> extract schema messages.'
schemapot = join(tempdir, 'schema.pot')
potfiles.append(schemapot)
# explicit close necessary else the file may not be yet flushed when
@@ -269,10 +269,10 @@
schemapotstream = file(schemapot, 'w')
generate_schema_pot(schemapotstream.write, cubedir=None)
schemapotstream.close()
- print '******** extract TAL messages'
+ print '-> extract TAL messages.'
tali18nfile = join(tempdir, 'tali18n.py')
extract_from_tal(find(join(BASEDIR, 'web'), ('.py', '.pt')), tali18nfile)
- print '******** .pot files generation'
+ print '-> generate .pot files.'
for id, files, lang in [('pycubicweb', get_module_files(BASEDIR) + list(globfind(join(BASEDIR, 'misc', 'migration'), '*.py')), None),
('schemadescr', globfind(join(BASEDIR, 'schemas'), '*.py'), None),
('yams', get_module_files(yams.__path__[0]), None),
@@ -287,11 +287,11 @@
if exists(potfile):
potfiles.append(potfile)
else:
- print 'WARNING: %s file not generated' % potfile
- print '******** merging .pot files'
+ print '-> WARNING: %s file was not generated' % potfile
+ print '-> merging %i .pot files' % len(potfiles)
cubicwebpot = join(tempdir, 'cubicweb.pot')
execute('msgcat %s > %s' % (' '.join(potfiles), cubicwebpot))
- print '******** merging main pot file with existing translations'
+ print '-> merging main pot file with existing translations.'
chdir(I18NDIR)
toedit = []
for lang in LANGS:
@@ -303,11 +303,10 @@
# cleanup
rm(tempdir)
# instructions pour la suite
- print '*' * 72
- print 'you can now edit the following files:'
+ print '-> regenerated CubicWeb\'s .po catalogs.'
+ print '\nYou can now edit the following files:'
print '* ' + '\n* '.join(toedit)
- print
- print "then you'll have to update cubes catalogs using the i18ncube command"
+ print 'when you are done, run "cubicweb-ctl i18ncube yourcube".'
class UpdateTemplateCatalogCommand(Command):
@@ -331,19 +330,19 @@
toedit = []
for cubedir in cubes:
if not isdir(cubedir):
- print 'not a directory', cubedir
+ print '-> ignoring %s that is not a directory.' % cubedir
continue
try:
toedit += update_cube_catalogs(cubedir)
except Exception:
import traceback
traceback.print_exc()
- print 'error while updating catalogs for', cubedir
+ print '-> Error while updating catalogs for cube', cubedir
# instructions pour la suite
- print '*' * 72
- print 'you can now edit the following files:'
+ print '-> regenerated this cube\'s .po catalogs.'
+ print '\nYou can now edit the following files:'
print '* ' + '\n* '.join(toedit)
-
+ print 'when you are done, run "cubicweb-ctl i18ninstance yourinstance".'
def update_cube_catalogs(cubedir):
import shutil
@@ -354,12 +353,11 @@
toedit = []
cube = basename(normpath(cubedir))
tempdir = tempfile.mkdtemp()
- print '*' * 72
- print 'updating %s cube...' % cube
+ print underline_title('Updating i18n catalogs for cube %s' % cube)
chdir(cubedir)
potfiles = [join('i18n', scfile) for scfile in ('entities.pot',)
if exists(join('i18n', scfile))]
- print '******** extract schema messages'
+ print '-> extract schema messages'
schemapot = join(tempdir, 'schema.pot')
potfiles.append(schemapot)
# explicit close necessary else the file may not be yet flushed when
@@ -367,10 +365,10 @@
schemapotstream = file(schemapot, 'w')
generate_schema_pot(schemapotstream.write, cubedir)
schemapotstream.close()
- print '******** extract TAL messages'
+ print '-> extract TAL messages'
tali18nfile = join(tempdir, 'tali18n.py')
extract_from_tal(find('.', ('.py', '.pt'), blacklist=STD_BLACKLIST+('test',)), tali18nfile)
- print '******** extract Javascript messages'
+ print '-> extract Javascript messages'
jsfiles = [jsfile for jsfile in find('.', '.js') if basename(jsfile).startswith('cub')]
if jsfiles:
tmppotfile = join(tempdir, 'js.pot')
@@ -379,7 +377,7 @@
# no pot file created if there are no string to translate
if exists(tmppotfile):
potfiles.append(tmppotfile)
- print '******** create cube specific catalog'
+ print '-> create cube-specific catalog'
tmppotfile = join(tempdir, 'generated.pot')
cubefiles = find('.', '.py', blacklist=STD_BLACKLIST+('test',))
cubefiles.append(tali18nfile)
@@ -388,12 +386,12 @@
if exists(tmppotfile): # doesn't exists of no translation string found
potfiles.append(tmppotfile)
potfile = join(tempdir, 'cube.pot')
- print '******** merging .pot files'
+ print '-> merging %i .pot files:' % len(potfiles)
execute('msgcat %s > %s' % (' '.join(potfiles), potfile))
- print '******** merging main pot file with existing translations'
+ print '-> merging main pot file with existing translations:'
chdir('i18n')
for lang in LANGS:
- print '****', lang
+ print '-> language', lang
cubepo = '%s.po' % lang
if not exists(cubepo):
shutil.copy(potfile, cubepo)
--- a/doc/book/en/B000-development.en.txt Thu Jul 23 15:29:07 2009 +0200
+++ b/doc/book/en/B000-development.en.txt Thu Jul 23 15:33:03 2009 +0200
@@ -1,7 +1,5 @@
.. -*- coding: utf-8 -*-
-.. _Part2:
-
=====================
Part II - Development
=====================
--- a/doc/book/en/admin/setup.rst Thu Jul 23 15:29:07 2009 +0200
+++ b/doc/book/en/admin/setup.rst Thu Jul 23 15:33:03 2009 +0200
@@ -52,7 +52,7 @@
3. run "apt-key add logilab-dists-key.asc"
4. re-run apt-get update (manually or through the package manager, whichever you prefer)
-.. `Logilab's gnupg key` _http://ftp.logilab.org/dists/logilab-dists-key.asc
+.. _`Logilab's gnupg key`: http://ftp.logilab.org/dists/logilab-dists-key.asc
Install from source
```````````````````
@@ -74,6 +74,9 @@
repositories are set to 'stable' (using `hg up stable` for each one)
if you do not intend to develop the framework itself.
+In both cases, make sure you have installed the dependencies (see appendixes for
+the list).
+
Postgres installation
`````````````````````
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/annexes/depends.rst Thu Jul 23 15:33:03 2009 +0200
@@ -0,0 +1,48 @@
+.. -*- coding: utf-8 -*-
+
+.. _dependencies:
+
+Dependencies
+============
+
+When you run CubicWeb from source, either by downloading the tarball or
+cloning the mercurial forest, here is the list of tools and libraries you need
+to have installed in order for CubicWeb to work:
+
+* mxDateTime - http://www.egenix.com/products/python/mxBase/mxDateTime/ - http://pypi.python.org/pypi/egenix-mx-base
+
+* pyro - http://pyro.sourceforge.net/ - http://pypi.python.org/pypi/Pyro
+
+* yapps - http://theory.stanford.edu/~amitp/yapps/ -
+ http://pypi.python.org/pypi/Yapps2
+
+* pygraphviz - http://networkx.lanl.gov/pygraphviz/ -
+ http://pypi.python.org/pypi/pygraphviz
+
+* simplejson - http://code.google.com/p/simplejson/ -
+ http://pypi.python.org/pypi/simplejson
+
+* lxml - http://codespeak.net/lxml - http://pypi.python.org/pypi/lxml
+
+* twisted - http://twistedmatrix.com/ - http://pypi.python.org/pypi/Twisted
+
+* logilab-common - http://www.logilab.org/project/logilab-common -
+ http://pypi.python.org/pypi/logilab-common/ - included in the forest
+
+* logilab-constraint - http://www.logilab.org/project/logilab-constraint -
+ http://pypi.python.org/pypi/constraint/ - included in the forest
+
+* logilab-mtconverter - http://www.logilab.org/project/logilab-mtconverter -
+ http://pypi.python.org/pypi/logilab-mtconverter - included in the forest
+
+* rql - http://www.logilab.org/project/rql - http://pypi.python.org/pypi/rql -
+ included in the forest
+
+* yams - http://www.logilab.org/project/yams - http://pypi.python.org/pypi/yams
+ - included in the forest
+
+* indexer - http://www.logilab.org/project/indexer -
+ http://pypi.python.org/pypi/indexer - included in the forest
+
+Any help with the packaging of CubicWeb for more than Debian/Ubuntu (including
+eggs, buildouts, etc) will be greatly appreciated.
--- a/doc/book/en/annexes/index.rst Thu Jul 23 15:29:07 2009 +0200
+++ b/doc/book/en/annexes/index.rst Thu Jul 23 15:33:03 2009 +0200
@@ -16,6 +16,7 @@
cubicweb-ctl
rql/index
mercurial
+ depends
(X)HTML tricks to apply
-----------------------
--- a/doc/book/en/development/datamodel/index.rst Thu Jul 23 15:29:07 2009 +0200
+++ b/doc/book/en/development/datamodel/index.rst Thu Jul 23 15:33:03 2009 +0200
@@ -9,6 +9,5 @@
definition
metadata
baseschema
-
-.. define-workflows
-.. inheritance
+ define-workflows
+ inheritance
--- a/doc/book/en/development/datamodel/inheritance.rst Thu Jul 23 15:29:07 2009 +0200
+++ b/doc/book/en/development/datamodel/inheritance.rst Thu Jul 23 15:33:03 2009 +0200
@@ -1,1 +1,5 @@
-XXX WRITME
\ No newline at end of file
+
+Inheritance
+-----------
+
+XXX WRITME
--- a/etwist/twctl.py Thu Jul 23 15:29:07 2009 +0200
+++ b/etwist/twctl.py Thu Jul 23 15:33:03 2009 +0200
@@ -8,6 +8,7 @@
import sys
+from cubicweb import underline_title
from cubicweb.toolsutils import CommandHandler
from cubicweb.web.webctl import WebCreateHandler
@@ -20,7 +21,7 @@
def bootstrap(self, cubes, inputlevel=0):
"""bootstrap this configuration"""
- print '** twisted configuration'
+ print '\n'+underline_title('Configuring Twisted')
mainpyfile = self.config.server_file()
mainpy = open(mainpyfile, 'w')
mainpy.write('''
@@ -28,7 +29,7 @@
application = server.main(%r, %r)
''' % (self.config.appid, self.config.name))
mainpy.close()
- print 'application\'s twisted file %s generated' % mainpyfile
+ print '-> generated %s' % mainpyfile
super(TWCreateHandler, self).bootstrap(cubes, inputlevel)
--- a/hercule.py Thu Jul 23 15:29:07 2009 +0200
+++ b/hercule.py Thu Jul 23 15:33:03 2009 +0200
@@ -106,7 +106,7 @@
password = getpass('password: ')
if self.cnx is not None:
self.cnx.close()
- self.cnx = connect(user=user, password=password, host=host,
+ self.cnx = connect(login=user, password=password, host=host,
database=application)
self.schema = self.cnx.get_schema()
self.cursor = self.cnx.cursor()
--- a/misc/cwdesklets/rqlsensor/__init__.py Thu Jul 23 15:29:07 2009 +0200
+++ b/misc/cwdesklets/rqlsensor/__init__.py Thu Jul 23 15:33:03 2009 +0200
@@ -65,7 +65,7 @@
return self._v_cnx
except AttributeError:
appid, user, passwd = self._get_config("appid"), self._get_config("user"), self._get_config("passwd")
- cnx = connect(database=appid, user=user, password=passwd)
+ cnx = connect(database=appid, login=user, password=passwd)
self._v_cnx = cnx
return cnx
--- a/server/__init__.py Thu Jul 23 15:29:07 2009 +0200
+++ b/server/__init__.py Thu Jul 23 15:33:03 2009 +0200
@@ -45,7 +45,8 @@
assert len(repo.sources) == 1, repo.sources
schema = repo.schema
sourcescfg = config.sources()
- print 'creating necessary tables into the system source'
+ _title = '-> creating tables '
+ print _title,
source = sourcescfg['system']
driver = source['db-driver']
sqlcnx = repo.system_source.get_connection()
@@ -56,7 +57,7 @@
try:
sqlexec(dropsql, execute)
except Exception, ex:
- print 'drop failed, skipped (%s)' % ex
+ print '-> drop failed, skipped (%s).' % ex
sqlcnx.rollback()
# schema entities and relations tables
# can't skip entities table even if system source doesn't support them,
@@ -68,14 +69,14 @@
schemasql = sqlschema(schema, driver)
#skip_entities=[str(e) for e in schema.entities()
# if not repo.system_source.support_entity(str(e))])
- sqlexec(schemasql, execute)
+ sqlexec(schemasql, execute, pbtitle=_title)
# install additional driver specific sql files
for fpath in glob(join(config.schemas_lib_dir(), '*.sql.%s' % driver)):
- print 'install', fpath
+ print '-> installing', fpath
sqlexec(open(fpath).read(), execute, False, delimiter=';;')
for directory in config.cubes_path():
for fpath in glob(join(directory, 'schema', '*.sql.%s' % driver)):
- print 'install', fpath
+ print '-> installing', fpath
sqlexec(open(fpath).read(), execute, False, delimiter=';;')
sqlcursor.close()
sqlcnx.commit()
@@ -90,7 +91,7 @@
login, pwd = manager_userpasswd(msg=msg, confirm=True)
else:
login, pwd = unicode(source['db-user']), source['db-password']
- print 'inserting default user and groups'
+ print '-> inserting default user and default groups.'
needisfix = []
for group in BASE_GROUPS:
rset = session.execute('INSERT CWGroup X: X name %(name)s',
@@ -140,7 +141,7 @@
config.bootstrap_schema = bootstrap_schema
config.consider_user_state = True
config.set_language = True
- print 'application %s initialized' % config.appid
+ print '-> database for application %s initialized.' % config.appid
def initialize_schema(config, schema, mhandler, event='create'):
--- a/server/schemaserial.py Thu Jul 23 15:29:07 2009 +0200
+++ b/server/schemaserial.py Thu Jul 23 15:33:03 2009 +0200
@@ -277,12 +277,13 @@
"""synchronize schema and permissions in the database according to
current schema
"""
- print 'serializing the schema, this may take some time'
+ _title = '-> storing the schema in the database '
+ print _title,
eschemas = schema.entities()
aller = eschemas + schema.relations()
if not verbose:
pb_size = len(aller) + len(CONSTRAINTS) + len([x for x in eschemas if x.specializes()])
- pb = ProgressBar(pb_size)
+ pb = ProgressBar(pb_size, title=_title)
for cstrtype in CONSTRAINTS:
rql = 'INSERT CWConstraintType X: X name "%s"' % cstrtype
if verbose:
--- a/server/serverctl.py Thu Jul 23 15:29:07 2009 +0200
+++ b/server/serverctl.py Thu Jul 23 15:33:03 2009 +0200
@@ -13,13 +13,12 @@
from logilab.common.configuration import Configuration
from logilab.common.clcommands import register_commands, cmd_run, pop_arg
-from cubicweb import AuthenticationError, ExecutionError, ConfigurationError
+from cubicweb import AuthenticationError, ExecutionError, ConfigurationError, underline_title
from cubicweb.toolsutils import Command, CommandHandler, confirm
from cubicweb.server import SOURCE_TYPES
from cubicweb.server.utils import ask_source_config
from cubicweb.server.serverconfig import USER_OPTIONS, ServerConfiguration
-
# utility functions ###########################################################
def source_cnx(source, dbname=None, special_privs=False, verbose=True):
@@ -32,7 +31,7 @@
if dbname is None:
dbname = source['db-name']
driver = source['db-driver']
- print '**** connecting to %s database %s@%s' % (driver, dbname, dbhost),
+ print '-> connecting to %s database %s@%s' % (driver, dbname, dbhost or 'localhost'),
if not verbose or (not special_privs and source.get('db-user')):
user = source['db-user']
print 'as', user
@@ -48,7 +47,7 @@
print special_privs
print
default_user = source.get('db-user', os.environ.get('USER', ''))
- user = raw_input('user (%r by default): ' % default_user)
+ user = raw_input('Connect as user ? [%r]: ' % default_user)
user = user or default_user
if user == source.get('db-user') and source.get('db-password'):
password = source['db-password']
@@ -108,7 +107,7 @@
try:
return in_memory_cnx(config, login, pwd)
except AuthenticationError:
- print 'wrong user/password'
+ print '-> Error: wrong user/password.'
# reset cubes else we'll have an assertion error on next retry
config._cubes = None
login, pwd = manager_userpasswd()
@@ -124,14 +123,11 @@
asking information necessary to build required configuration files
"""
config = self.config
- print 'application\'s repository configuration'
- print '-' * 72
+ print underline_title('Configuring the repository')
config.input_config('email', inputlevel)
if config.pyro_enabled():
config.input_config('pyro-server', inputlevel)
- print
- print 'repository sources configuration'
- print '-' * 72
+ print '\n'+underline_title('Configuring the sources')
sourcesfile = config.sources_file()
sconfig = Configuration(options=SOURCE_TYPES['native'].options)
sconfig.adapter = 'native'
@@ -142,19 +138,20 @@
# source to use the cube, so add it.
if cube in SOURCE_TYPES:
sourcescfg[cube] = ask_source_config(cube, inputlevel)
- while raw_input('enter another source [y/N]: ').strip().lower() == 'y':
+ print
+ while confirm('Enter another source ?', default_is_yes=False):
available = sorted(stype for stype in SOURCE_TYPES
if not stype in cubes)
while True:
sourcetype = raw_input('source type (%s): ' % ', '.join(available))
if sourcetype in available:
break
- print 'unknown source type, use one of the available type'
+ print '-> unknown source type, use one of the available types.'
while True:
sourceuri = raw_input('source uri: ').strip()
if sourceuri != 'admin' and sourceuri not in sourcescfg:
break
- print 'uri already used, choose another one'
+ print '-> uri already used, choose another one.'
sourcescfg[sourceuri] = ask_source_config(sourcetype)
sourcemodule = SOURCE_TYPES[sourcetype].module
if not sourcemodule.startswith('cubicweb.'):
@@ -172,11 +169,12 @@
config.write_bootstrap_cubes_file(cubes)
def postcreate(self):
- if confirm('do you want to create repository\'s system database?'):
+ if confirm('Do you want to run db-create to create the "system database" ?'):
verbosity = (self.config.mode == 'installed') and 'y' or 'n'
cmd_run('db-create', self.config.appid, '--verbose=%s' % verbosity)
else:
- print 'nevermind, you can do it later using the db-create command'
+ print ('-> nevermind, you can do it later with '
+ '"cubicweb-ctl db-create %s".' % self.config.appid)
class RepositoryDeleteHandler(CommandHandler):
@@ -189,18 +187,18 @@
source = self.config.sources()['system']
dbname = source['db-name']
helper = get_adv_func_helper(source['db-driver'])
- if confirm('delete database %s ?' % dbname):
+ if confirm('Delete database %s ?' % dbname):
user = source['db-user'] or None
cnx = _db_sys_cnx(source, 'DROP DATABASE', user=user)
cursor = cnx.cursor()
try:
cursor.execute('DROP DATABASE %s' % dbname)
- print 'database %s dropped' % dbname
+ print '-> database %s dropped.' % dbname
# XXX should check we are not connected as user
if user and helper.users_support and \
- confirm('delete user %s ?' % user, default_is_yes=False):
+ confirm('Delete user %s ?' % user, default_is_yes=False):
cursor.execute('DROP USER %s' % user)
- print 'user %s dropped' % user
+ print '-> user %s dropped.' % user
cnx.commit()
except:
cnx.rollback()
@@ -271,6 +269,7 @@
driver = source['db-driver']
helper = get_adv_func_helper(driver)
if create_db:
+ print '\n'+underline_title('Creating the "system database"')
# connect on the dbms system base to create our base
dbcnx = _db_sys_cnx(source, 'CREATE DATABASE and / or USER', verbose=verbose)
cursor = dbcnx.cursor()
@@ -278,12 +277,12 @@
if helper.users_support:
user = source['db-user']
if not helper.user_exists(cursor, user) and \
- confirm('create db user %s ?' % user, default_is_yes=False):
+ confirm('Create db user %s ?' % user, default_is_yes=False):
helper.create_user(source['db-user'], source['db-password'])
- print 'user %s created' % user
+ print '-> user %s created.' % user
dbname = source['db-name']
if dbname in helper.list_databases(cursor):
- if confirm('DB %s already exists -- do you want to drop it ?' % dbname):
+ if confirm('Database %s already exists -- do you want to drop it ?' % dbname):
cursor.execute('DROP DATABASE %s' % dbname)
else:
return
@@ -294,7 +293,7 @@
helper.create_database(cursor, dbname,
encoding=source['db-encoding'])
dbcnx.commit()
- print 'database %s created' % source['db-name']
+ print '-> database %s created.' % source['db-name']
except:
dbcnx.rollback()
raise
@@ -309,12 +308,13 @@
helper.create_language(cursor, extlang)
cursor.close()
cnx.commit()
- print 'database for application %s created and necessary extensions installed' % appid
+ print '-> database for application %s created and necessary extensions installed.' % appid
print
- if confirm('do you want to initialize the system database?'):
+ if confirm('Do you want to run db-init to initialize the "system database" ?'):
cmd_run('db-init', config.appid)
else:
- print 'nevermind, you can do it later using the db-init command'
+ print ('-> nevermind, you can do it later with '
+ '"cubicweb-ctl db-init %s".' % self.config.appid)
class InitApplicationCommand(Command):
@@ -339,6 +339,7 @@
)
def run(self, args):
+ print '\n'+underline_title('Initializing the "system database"')
from cubicweb.server import init_repository
appid = pop_arg(args, msg="No application specified !")
config = ServerConfiguration.config_for(appid)
@@ -381,10 +382,10 @@
cnx.rollback()
import traceback
traceback.print_exc()
- print 'An error occured:', ex
+ print '-> an error occured:', ex
else:
cnx.commit()
- print 'grants given to %s on application %s' % (appid, user)
+ print '-> rights granted to %s on application %s.' % (appid, user)
class ResetAdminPasswordCommand(Command):
"""Reset the administrator password.
@@ -405,7 +406,7 @@
try:
adminlogin = sourcescfg['admin']['login']
except KeyError:
- print 'could not get cubicweb administrator login'
+ print '-> Error: could not get cubicweb administrator login.'
sys.exit(1)
cnx = source_cnx(sourcescfg['system'])
cursor = cnx.cursor()
@@ -425,10 +426,10 @@
cnx.rollback()
import traceback
traceback.print_exc()
- print 'An error occured:', ex
+ print '-> an error occured:', ex
else:
cnx.commit()
- print 'password reset, sources file regenerated'
+ print '-> password reset, sources file regenerated.'
class StartRepositoryCommand(Command):
@@ -490,7 +491,7 @@
rmcmd = 'ssh -t %s "rm -f /tmp/%s.dump"' % (host, appid)
print rmcmd
if os.system(rmcmd) and not confirm(
- 'an error occured while deleting remote dump. Continue anyway?'):
+ 'An error occured while deleting remote dump. Continue anyway?'):
raise ExecutionError('Error while deleting remote dump')
def _local_dump(appid, output):
@@ -541,12 +542,12 @@
try:
softversion = config.cube_version(cube)
except ConfigurationError:
- print "no cube version information for %s, is the cube installed?" % cube
+ print "-> Error: no cube version information for %s, please check that the cube is installed." % cube
continue
try:
applversion = vcconf[cube]
except KeyError:
- print "no cube version information for %s in version configuration" % cube
+ print "-> Error: no cube version information for %s in version configuration." % cube
continue
if softversion == applversion:
continue
@@ -657,7 +658,7 @@
_local_dump(srcappid, output)
_local_restore(destappid, output, not self.config.no_drop)
if self.config.keep_dump:
- print 'you can get the dump file at', output
+ print '-> you can get the dump file at', output
else:
os.remove(output)
--- a/server/sqlutils.py Thu Jul 23 15:29:07 2009 +0200
+++ b/server/sqlutils.py Thu Jul 23 15:33:03 2009 +0200
@@ -29,7 +29,7 @@
SQL_PREFIX = 'cw_'
-def sqlexec(sqlstmts, cursor_or_execute, withpb=True, delimiter=';'):
+def sqlexec(sqlstmts, cursor_or_execute, withpb=True, pbtitle='', delimiter=';'):
"""execute sql statements ignoring DROP/ CREATE GROUP or USER statements
error. If a cnx is given, commit at each statement
"""
@@ -39,7 +39,7 @@
execute = cursor_or_execute
sqlstmts = sqlstmts.split(delimiter)
if withpb:
- pb = ProgressBar(len(sqlstmts))
+ pb = ProgressBar(len(sqlstmts), title=pbtitle)
for sql in sqlstmts:
sql = sql.strip()
if withpb:
--- a/toolsutils.py Thu Jul 23 15:29:07 2009 +0200
+++ b/toolsutils.py Thu Jul 23 15:33:03 2009 +0200
@@ -7,6 +7,8 @@
"""
__docformat__ = "restructuredtext en"
+# XXX move most of this in logilab.common (shellutils ?)
+
import os, sys
from os import listdir, makedirs, symlink, environ, chmod, walk, remove
from os.path import exists, join, abspath, normpath
@@ -14,6 +16,7 @@
from logilab.common.clcommands import Command as BaseCommand, \
main_run as base_main_run
from logilab.common.compat import any
+from logilab.common.shellutils import confirm
from cubicweb import warning
from cubicweb import ConfigurationError, ExecutionError
@@ -34,12 +37,12 @@
"""create a directory if it doesn't exist yet"""
try:
makedirs(directory)
- print 'created directory', directory
+ print '-> created directory %s.' % directory
except OSError, ex:
import errno
if ex.errno != errno.EEXIST:
raise
- print 'directory %s already exists' % directory
+ print '-> directory %s already exists, no need to create it.' % directory
def create_symlink(source, target):
"""create a symbolic link"""
@@ -56,7 +59,7 @@
def rm(whatever):
import shutil
shutil.rmtree(whatever)
- print 'removed %s' % whatever
+ print '-> removed %s' % whatever
def show_diffs(appl_file, ref_file, askconfirm=True):
"""interactivly replace the old file with the new file according to
@@ -133,24 +136,9 @@
if log:
log('set %s permissions to 0600', filepath)
else:
- print 'set %s permissions to 0600' % filepath
+ print '-> set %s permissions to 0600' % filepath
chmod(filepath, 0600)
-def confirm(question, default_is_yes=True):
- """ask for confirmation and return true on positive answer"""
- if default_is_yes:
- input_str = '%s [Y/n]: '
- else:
- input_str = '%s [y/N]: '
- answer = raw_input(input_str % (question)).strip().lower()
- if default_is_yes:
- if answer in ('n', 'no'):
- return False
- return True
- if answer in ('y', 'yes'):
- return True
- return False
-
def read_config(config_file):
"""read the application configuration from a file and return it as a
dictionnary
@@ -289,5 +277,5 @@
password = optconfig.password
if not password:
password = getpass('password: ')
- return connect(user=user, password=password, host=optconfig.host, database=appid)
+ return connect(login=user, password=password, host=optconfig.host, database=appid)
--- a/web/data/cubicweb.edition.js Thu Jul 23 15:29:07 2009 +0200
+++ b/web/data/cubicweb.edition.js Thu Jul 23 15:33:03 2009 +0200
@@ -512,7 +512,7 @@
document.location.href = result[1];
} else {
if (result[0]) {
- var d = asyncRemoteExec('reledit_form', eid, rtype, role, lzone);
+ var d = asyncRemoteExec('reledit_form', eid, rtype, role, default_value, lzone);
d.addCallback(function (result) {
jQuery('#'+divid+'-reledit').replaceWith(result);
});
--- a/web/data/goa.js Thu Jul 23 15:29:07 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-/*
- * functions specific to ginco on google appengine
- *
- * :organization: Logilab
- * :copyright: 2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
- * :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
- */
-
-/* overrides rql_for_eid function from htmlhelpers.hs */
-function rql_for_eid(eid) { return 'Any X WHERE X eid "' + eid + '"'; }
--- a/web/test/unittest_viewselector.py Thu Jul 23 15:29:07 2009 +0200
+++ b/web/test/unittest_viewselector.py Thu Jul 23 15:33:03 2009 +0200
@@ -1,4 +1,4 @@
-# -*- coding: iso-8859-1 -*-
+# -*- coding: utf-8 -*-
"""XXX rename, split, reorganize this
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
@@ -60,6 +60,9 @@
print 'missing', [v for v in content.keys() if not v in expected]
raise
+ def setUp(self):
+ super(VRegistryTC, self).setUp()
+ assert self.vreg['views']['propertiesform']
def test_possible_views_none_rset(self):
req = self.request()
@@ -123,6 +126,31 @@
('xml', xmlrss.XMLView),
])
+ def test_propertiesform_admin(self):
+ assert self.vreg['views']['propertiesform']
+ rset1, req1 = self.env.get_rset_and_req('CWUser X WHERE X login "admin"')
+ rset2, req2 = self.env.get_rset_and_req('CWUser X WHERE X login "anon"')
+ self.failUnless(self.vreg.select_object('views', 'propertiesform', req1, rset=None))
+ self.failUnless(self.vreg.select_object('views', 'propertiesform', req1, rset=rset1))
+ self.failUnless(self.vreg.select_object('views', 'propertiesform', req2, rset=rset2))
+
+ def test_propertiesform_anon(self):
+ self.login('anon')
+ rset1, req1 = self.env.get_rset_and_req('CWUser X WHERE X login "admin"')
+ rset2, req2 = self.env.get_rset_and_req('CWUser X WHERE X login "anon"')
+ self.assertRaises(NoSelectableObject, self.vreg.select_object, 'views', 'propertiesform', req1, rset=None)
+ self.assertRaises(NoSelectableObject, self.vreg.select_object, 'views', 'propertiesform', req1, rset=rset1)
+ self.assertRaises(NoSelectableObject, self.vreg.select_object, 'views', 'propertiesform', req1, rset=rset2)
+
+ def test_propertiesform_jdoe(self):
+ self.create_user('jdoe')
+ self.login('jdoe')
+ rset1, req1 = self.env.get_rset_and_req('CWUser X WHERE X login "admin"')
+ rset2, req2 = self.env.get_rset_and_req('CWUser X WHERE X login "jdoe"')
+ self.failUnless(self.vreg.select_object('views', 'propertiesform', req1, rset=None))
+ self.assertRaises(NoSelectableObject, self.vreg.select_object, 'views', 'propertiesform', req1, rset=rset1)
+ self.failUnless(self.vreg.select_object('views', 'propertiesform', req2, rset=rset2))
+
def test_possible_views_multiple_different_types(self):
rset, req = self.env.get_rset_and_req('Any X')
self.assertListEqual(self.pviews(req, rset),
--- a/web/views/basecontrollers.py Thu Jul 23 15:29:07 2009 +0200
+++ b/web/views/basecontrollers.py Thu Jul 23 15:33:03 2009 +0200
@@ -400,10 +400,11 @@
return (success, args, None)
@jsonize
- def js_reledit_form(self, eid, rtype, role, lzone):
+ def js_reledit_form(self, eid, rtype, role, default, lzone):
+ """XXX we should get rid of this and use loadxhtml"""
entity = self.req.eid_rset(eid).get_entity(0, 0)
return entity.view('reledit', rtype=rtype, role=role,
- landing_zone=lzone)
+ default=default, landing_zone=lzone)
@jsonize
def js_i18n(self, msgids):
--- a/web/views/cwproperties.py Thu Jul 23 15:29:07 2009 +0200
+++ b/web/views/cwproperties.py Thu Jul 23 15:33:03 2009 +0200
@@ -228,10 +228,9 @@
class CWPropertiesForm(SystemCWPropertiesForm):
id = 'propertiesform'
__select__ = (
- # we don't want guests to be able to come here
- match_user_groups('users', 'managers') &
- (none_rset() | ((one_line_rset() & is_user_prefs()) &
- (one_line_rset() & match_user_groups('managers'))))
+ (none_rset() & match_user_groups('users','managers'))
+ | (one_line_rset() & match_user_groups('users') & is_user_prefs())
+ | (one_line_rset() & match_user_groups('managers') & implements('CWUser'))
)
title = _('preferences')
--- a/web/views/cwuser.py Thu Jul 23 15:29:07 2009 +0200
+++ b/web/views/cwuser.py Thu Jul 23 15:33:03 2009 +0200
@@ -25,7 +25,7 @@
def url(self):
login = self.rset.get_entity(self.row or 0, self.col or 0).login
- return self.build_url('cwuser/%s'%login, vid='epropertiesform')
+ return self.build_url('cwuser/%s'%login, vid='propertiesform')
class FoafView(EntityView):
--- a/web/webctl.py Thu Jul 23 15:29:07 2009 +0200
+++ b/web/webctl.py Thu Jul 23 15:33:03 2009 +0200
@@ -8,6 +8,7 @@
"""
__docformat__ = "restructuredtext en"
+from cubicweb import underline_title
from cubicweb.toolsutils import CommandHandler, confirm
@@ -16,14 +17,12 @@
def bootstrap(self, cubes, inputlevel=0):
"""bootstrap this configuration"""
- print '** generic web configuration'
+ print '\n'+underline_title('Generic web configuration')
config = self.config
if config.repo_method == 'pyro':
- print
- print '** repository server configuration'
- print '-' * 72
+ print '\n'+underline_title('Repository server configuration')
config.input_config('pyro-client', inputlevel)
- if confirm('allow anonymous access', False):
+ if confirm('Allow anonymous access ?', False):
config.global_set_option('anonymous-user', 'anon')
config.global_set_option('anonymous-password', 'anon')