# HG changeset patch # User Adrien Di Mascio # Date 1248355983 -7200 # Node ID 4d114865098f1ded6e3f1ea37cc185dcc74357b4 # Parent d0f31e11993602ce828b378674a220866bcbd90a# Parent 986718a355fafea8d0480225eb870136d2932c80 backport stable branch into default diff -r d0f31e119936 -r 4d114865098f .hgtags --- 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 diff -r d0f31e119936 -r 4d114865098f __init__.py --- 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)) + diff -r d0f31e119936 -r 4d114865098f __pkginfo__.py --- 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 diff -r d0f31e119936 -r 4d114865098f common/i18n.py --- 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') diff -r d0f31e119936 -r 4d114865098f common/uilib.py diff -r d0f31e119936 -r 4d114865098f cwctl.py --- 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() diff -r d0f31e119936 -r 4d114865098f debian/changelog --- 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 Tue, 21 Jul 2009 23:09:03 +0200 + +cubicweb (3.3.4-1) unstable; urgency=low + + * new upstream release + + -- Sylvain Thénault 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 diff -r d0f31e119936 -r 4d114865098f debian/control diff -r d0f31e119936 -r 4d114865098f debian/cubicweb-dev.install.in --- 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/ diff -r d0f31e119936 -r 4d114865098f debian/rules --- 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 diff -r d0f31e119936 -r 4d114865098f devtools/devctl.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) diff -r d0f31e119936 -r 4d114865098f doc/book/en/B000-development.en.txt --- 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 ===================== diff -r d0f31e119936 -r 4d114865098f doc/book/en/admin/setup.rst --- 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 ````````````````````` diff -r d0f31e119936 -r 4d114865098f doc/book/en/annexes/depends.rst --- /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. diff -r d0f31e119936 -r 4d114865098f doc/book/en/annexes/index.rst --- 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 ----------------------- diff -r d0f31e119936 -r 4d114865098f doc/book/en/development/datamodel/index.rst --- 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 diff -r d0f31e119936 -r 4d114865098f doc/book/en/development/datamodel/inheritance.rst --- 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 diff -r d0f31e119936 -r 4d114865098f etwist/twctl.py --- 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) diff -r d0f31e119936 -r 4d114865098f hercule.py --- 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() diff -r d0f31e119936 -r 4d114865098f misc/cwdesklets/rqlsensor/__init__.py --- 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 diff -r d0f31e119936 -r 4d114865098f server/__init__.py --- 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'): diff -r d0f31e119936 -r 4d114865098f server/schemaserial.py --- 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: diff -r d0f31e119936 -r 4d114865098f server/serverctl.py --- 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) diff -r d0f31e119936 -r 4d114865098f server/sqlutils.py --- 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: diff -r d0f31e119936 -r 4d114865098f toolsutils.py --- 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) diff -r d0f31e119936 -r 4d114865098f web/data/cubicweb.edition.js --- 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); }); diff -r d0f31e119936 -r 4d114865098f web/data/goa.js --- 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 + '"'; } diff -r d0f31e119936 -r 4d114865098f web/test/unittest_viewselector.py --- 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), diff -r d0f31e119936 -r 4d114865098f web/views/basecontrollers.py --- 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): diff -r d0f31e119936 -r 4d114865098f web/views/cwproperties.py --- 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') diff -r d0f31e119936 -r 4d114865098f web/views/cwuser.py --- 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): diff -r d0f31e119936 -r 4d114865098f web/views/editforms.py diff -r d0f31e119936 -r 4d114865098f web/webctl.py --- 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')