# HG changeset patch # User sylvain.thenault@logilab.fr # Date 1237826310 -3600 # Node ID 544609e83317b243fa513b79e713e8d5f8d5e710 # Parent 17ff4d4bfbd076e1829028b639ed6a2a93b4fbc7 pylint cleanup, no more need for mx datetime conversion diff -r 17ff4d4bfbd0 -r 544609e83317 goa/__init__.py --- a/goa/__init__.py Mon Mar 23 13:07:26 2009 +0100 +++ b/goa/__init__.py Mon Mar 23 17:38:30 2009 +0100 @@ -1,69 +1,12 @@ """cubicweb on google appengine :organization: Logilab -:copyright: 2001-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved. :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr """ __docformat__ = "restructuredtext en" -from datetime import datetime, time, date -from mx.DateTime import DateTime, Date, Time - -def mx2datetime(mxobj, yamstype): - """converts a mx date object (DateTime, Date or Time) into a - regular python datetime object - """ - #if yamstype == 'Datetime': - # don't use date, db model doesn't actually support it, only datetime - return datetime(mxobj.year, mxobj.month, mxobj.day, - mxobj.hour, mxobj.minute, int(mxobj.second)) -# elif yamstype == 'Date': -# return date(mxobj.year, mxobj.month, mxobj.day) -# # XXX don't support time either, what should we do here ? -# return time(mxobj.hour, mxobj.minute, int(mxobj.second)) - -def datetime2mx(datetimeobj, yamstype=None): - """converts a mx date object (DateTime, Date or Time) into a - regular python datetime object - """ - if yamstype is None: - yamstype = guess_yamstype_for_date(datetimeobj) - assert yamstype is not None - if yamstype == 'Datetime': - # don't use date, db model doesn't actually support it, only datetime - return DateTime(datetimeobj.year, datetimeobj.month, datetimeobj.day, - datetimeobj.hour, datetimeobj.minute, int(datetimeobj.second)) - elif yamstype == 'Date': - return Date(datetimeobj.year, datetimeobj.month, datetimeobj.day) - # XXX don't support time either, what should we do here ? - return Time(datetimeobj.hour, datetimeobj.minute, int(datetimeobj.second)) - - -def guess_yamstype_for_date(datetimeobj): - """guesses yams correct type according to `datetimeobj`'s type""" - if isinstance(datetimeobj, datetime): - return 'Datetime' - elif isinstance(datetimeobj, date): - return 'Date' - elif isinstance(datetimeobj, time): - return 'Time' - return None - - -def use_mx_for_dates(func): - """decorator to convert func's return value into mx objects - instead of datetime objects - """ - def wrapper(*args, **kwargs): - value = func(*args, **kwargs) - yamstype = guess_yamstype_for_date(value) - if yamstype is None: - return value - return datetime2mx(value, yamstype) - return wrapper - - try: # WARNING: do not import the google's db module here since it will take # precedence over our own db submodule diff -r 17ff4d4bfbd0 -r 544609e83317 goa/appobjects/components.py --- a/goa/appobjects/components.py Mon Mar 23 13:07:26 2009 +0100 +++ b/goa/appobjects/components.py Mon Mar 23 17:38:30 2009 +0100 @@ -6,8 +6,6 @@ """ __docformat__ = "restructuredtext en" -from os.path import join - from logilab.mtconverter import html_escape from logilab.common.decorators import cached @@ -17,11 +15,8 @@ from cubicweb.common.view import StartupView, EntityView from cubicweb.web import Redirect from cubicweb.web.views import vid_from_rset -from cubicweb.goa.db import rset_from_objs -from google.appengine.api import datastore, mail - -from main import APPLROOT +from google.appengine.api import mail class SearchForAssociationView(EntityView): diff -r 17ff4d4bfbd0 -r 544609e83317 goa/appobjects/sessions.py --- a/goa/appobjects/sessions.py Mon Mar 23 13:07:26 2009 +0100 +++ b/goa/appobjects/sessions.py Mon Mar 23 17:38:30 2009 +0100 @@ -15,7 +15,7 @@ from logilab.common.decorators import cached, clear_cache -from cubicweb import UnknownEid, BadConnectionId +from cubicweb import BadConnectionId from cubicweb.dbapi import Connection, ConnectionProperties, repo_connect from cubicweb.selectors import none_rset, match_user_groups from cubicweb.server.session import Session diff -r 17ff4d4bfbd0 -r 544609e83317 goa/db.py --- a/goa/db.py Mon Mar 23 13:07:26 2009 +0100 +++ b/goa/db.py Mon Mar 23 17:38:30 2009 +0100 @@ -30,7 +30,6 @@ """ __docformat__ = "restructuredtext en" -from datetime import datetime from copy import deepcopy from logilab.common.decorators import cached, iclassmethod @@ -39,7 +38,7 @@ from cubicweb.rset import ResultSet from cubicweb.entity import metaentity from cubicweb.server.utils import crypt_password -from cubicweb.goa import use_mx_for_dates, mx2datetime, MODE +from cubicweb.goa import MODE from cubicweb.goa.dbinit import init_relations from google.appengine.api.datastore import Get, Put, Key, Entity, Query @@ -174,15 +173,11 @@ return '' % ( self.e_schema, self.eid, self.keys(), id(self)) - __getattribute__ = use_mx_for_dates(entities.AnyEntity.__getattribute__) - def _cubicweb_to_datastore(self, attr, value): attr = attr[2:] # remove 's_' / 'o_' prefix if attr in self._attributes: tschema = self.e_schema.destination(attr) - if tschema in ('Datetime', 'Date', 'Time'): - value = mx2datetime(value, tschema) - elif tschema == 'String': + if tschema == 'String': if len(value) > 500: value = Text(value) elif tschema == 'Password': @@ -288,7 +283,6 @@ return 'eid', False return mainattr, needcheck - @use_mx_for_dates def get_value(self, name): try: value = self[name] diff -r 17ff4d4bfbd0 -r 544609e83317 goa/rqlinterpreter.py --- a/goa/rqlinterpreter.py Mon Mar 23 13:07:26 2009 +0100 +++ b/goa/rqlinterpreter.py Mon Mar 23 17:38:30 2009 +0100 @@ -14,7 +14,6 @@ from cubicweb import Binary from cubicweb.rset import ResultSet -from cubicweb.goa import mx2datetime, datetime2mx from cubicweb.server import SQL_CONNECT_HOOKS from google.appengine.api.datastore import Key, Get, Query, Entity @@ -250,9 +249,6 @@ def __init__(self, rel, kwargs): RelationRestriction.__init__(self, rel, None) value = self.rhs.eval(kwargs) - if isinstance(value, (DateTimeType, DateTimeDeltaType)): - #yamstype = self.schema.rschema(self.rtype).objects()[0] - value = mx2datetime(value, 'Datetime') self.value = value if self.operator == 'ILIKE': if value.startswith('%'): @@ -294,11 +290,7 @@ RelationRestriction.__init__(self, rel, None) values = [] for c in self.rel.children[1].iget_nodes(nodes.Constant): - value = c.eval(kwargs) - if isinstance(value, (DateTimeType, DateTimeDeltaType)): - #yamstype = self.schema.rschema(self.rtype).objects()[0] - value = mx2datetime(value, 'Datetime') - values.append(value) + values.append(c.eval(kwargs)) self.value = values @property @@ -322,9 +314,7 @@ def append_result(res, descr, i, j, value, etype): if value is not None: - if etype in ('Date', 'Datetime', 'Time'): - value = datetime2mx(value, etype) - elif isinstance(value, Text): + if isinstance(value, Text): value = unicode(value) elif isinstance(value, Blob): value = Binary(str(value)) diff -r 17ff4d4bfbd0 -r 544609e83317 goa/tools/i18n.py --- a/goa/tools/i18n.py Mon Mar 23 13:07:26 2009 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,282 +0,0 @@ -#!/usr/bin/env python -"""This script is just a thin wrapper around ``msgcat`` and ``msgfmt`` -to generate ``.mo`` files -""" - -import sys -import os -import os.path as osp -import shutil -from tempfile import mktemp -from glob import glob -from mx.DateTime import now - -from logilab.common.fileutils import ensure_fs_mode -from logilab.common.shellutils import find, rm - -from yams import BASE_TYPES - -from cubicweb import CW_SOFTWARE_ROOT -# from cubicweb.__pkginfo__ import version as cubicwebversion -cubicwebversion = '2.48.2' - -DEFAULT_POT_HEAD = r'''# LAX application po file - -msgid "" -msgstr "" -"Project-Id-Version: cubicweb %s\n" -"PO-Revision-Date: 2008-03-28 18:14+0100\n" -"Last-Translator: Logilab Team \n" -"Language-Team: fr \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: cubicweb-devtools\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" - -''' % cubicwebversion - - -STDLIB_ERTYPES = BASE_TYPES | set( ('EUser', 'EProperty', 'Card', 'identity', 'for_user') ) - -def create_dir(directory): - """create a directory if it doesn't exist yet""" - try: - os.makedirs(directory) - print 'created directory', directory - except OSError, ex: - import errno - if ex.errno != errno.EEXIST: - raise - print 'directory %s already exists' % directory - -def execute(cmd): - """display the command, execute it and raise an Exception if returned - status != 0 - """ - print cmd.replace(os.getcwd() + os.sep, '') - status = os.system(cmd) - if status != 0: - raise Exception() - -def add_msg(w, msgid): - """write an empty pot msgid definition""" - if isinstance(msgid, unicode): - msgid = msgid.encode('utf-8') - msgid = msgid.replace('"', r'\"').splitlines() - if len(msgid) > 1: - w('msgid ""\n') - for line in msgid: - w('"%s"' % line.replace('"', r'\"')) - else: - w('msgid "%s"\n' % msgid[0]) - w('msgstr ""\n\n') - - -def generate_schema_pot(w, vreg, tmpldir): - """generate a pot file with schema specific i18n messages - - notice that relation definitions description and static vocabulary - should be marked using '_' and extracted using xgettext - """ - cube = tmpldir and osp.split(tmpldir)[-1] - config = vreg.config - vreg.register_objects(config.vregistry_path()) - w(DEFAULT_POT_HEAD) - _generate_schema_pot(w, vreg, vreg.schema, libschema=None, # no libschema for now - cube=cube) - - -def _generate_schema_pot(w, vreg, schema, libschema=None, cube=None): - w('# schema pot file, generated on %s\n' % now().strftime('%Y-%m-%d %H:%M:%S')) - w('# \n') - w('# singular and plural forms for each entity type\n') - w('\n') - # XXX hard-coded list of stdlib's entity schemas - libschema = libschema or STDLIB_ERTYPES - entities = [e for e in schema.entities() if not e in libschema] - done = set() - for eschema in sorted(entities): - etype = eschema.type - add_msg(w, etype) - add_msg(w, '%s_plural' % etype) - if not eschema.is_final(): - add_msg(w, 'This %s' % etype) - add_msg(w, 'New %s' % etype) - add_msg(w, 'add a %s' % etype) - add_msg(w, 'remove this %s' % etype) - if eschema.description and not eschema.description in done: - done.add(eschema.description) - add_msg(w, eschema.description) - w('# subject and object forms for each relation type\n') - w('# (no object form for final relation types)\n') - w('\n') - if libschema is not None: - relations = [r for r in schema.relations() if not r in libschema] - else: - relations = schema.relations() - for rschema in sorted(set(relations)): - rtype = rschema.type - add_msg(w, rtype) - if not (schema.rschema(rtype).is_final() or rschema.symetric): - add_msg(w, '%s_object' % rtype) - if rschema.description and rschema.description not in done: - done.add(rschema.description) - add_msg(w, rschema.description) - w('# add related box generated message\n') - w('\n') - for eschema in schema.entities(): - if eschema.is_final(): - continue - entity = vreg.etype_class(eschema)(None, None) - for x, rschemas in (('subject', eschema.subject_relations()), - ('object', eschema.object_relations())): - for rschema in rschemas: - if rschema.is_final(): - continue - for teschema in rschema.targets(eschema, x): - if defined_in_library(libschema, eschema, rschema, teschema, x): - continue - if entity.relation_mode(rschema.type, teschema.type, x) == 'create': - if x == 'subject': - label = 'add %s %s %s %s' % (eschema, rschema, teschema, x) - label2 = "creating %s (%s %%(linkto)s %s %s)" % (teschema, eschema, rschema, teschema) - else: - label = 'add %s %s %s %s' % (teschema, rschema, eschema, x) - label2 = "creating %s (%s %s %s %%(linkto)s)" % (teschema, teschema, rschema, eschema) - add_msg(w, label) - add_msg(w, label2) - cube = (cube or 'cubicweb') + '.' - done = set() - for reg, objdict in vreg.items(): - for objects in objdict.values(): - for obj in objects: - objid = '%s_%s' % (reg, obj.id) - if objid in done: - continue - if obj.__module__.startswith(cube) and obj.property_defs: - add_msg(w, '%s_description' % objid) - add_msg(w, objid) - done.add(objid) - -def defined_in_library(libschema, etype, rtype, tetype, x): - """return true if the given relation definition exists in cubicweb's library""" - if libschema is None: - return False - if x == 'subject': - subjtype, objtype = etype, tetype - else: - subjtype, objtype = tetype, etype - try: - return libschema.rschema(rtype).has_rdef(subjtype, objtype) - except (KeyError, AttributeError): - # if libschema is a simple list of entity types (lax specific) - # or if the relation could not be found - return False - - - -# XXX check if this is a pure duplication of the original -# `cubicweb.common.i18n` function -def compile_i18n_catalogs(sourcedirs, destdir, langs): - """generate .mo files for a set of languages into the `destdir` i18n directory - """ - print 'compiling %s catalogs...' % destdir - errors = [] - for lang in langs: - langdir = osp.join(destdir, lang, 'LC_MESSAGES') - if not osp.exists(langdir): - create_dir(langdir) - pofiles = [osp.join(path, '%s.po' % lang) for path in sourcedirs] - pofiles = [pof for pof in pofiles if osp.exists(pof)] - mergedpo = osp.join(destdir, '%s_merged.po' % lang) - try: - # merge application messages' catalog with the stdlib's one - execute('msgcat --use-first --sort-output --strict %s > %s' - % (' '.join(pofiles), mergedpo)) - # make sure the .mo file is writeable and compile with *msgfmt* - applmo = osp.join(destdir, lang, 'LC_MESSAGES', 'cubicweb.mo') - try: - ensure_fs_mode(applmo) - except OSError: - pass # suppose not osp.exists - execute('msgfmt %s -o %s' % (mergedpo, applmo)) - except Exception, ex: - errors.append('while handling language %s: %s' % (lang, ex)) - try: - # clean everything - os.unlink(mergedpo) - except Exception: - continue - return errors - - -def update_cubes_catalog(vreg, appdirectory, langs): - toedit = [] - tmpl = osp.basename(osp.normpath(appdirectory)) - tempdir = mktemp() - os.mkdir(tempdir) - print '*' * 72 - print 'updating %s cube...' % tmpl - os.chdir(appdirectory) - potfiles = [] - if osp.exists(osp.join('i18n', 'entities.pot')): - potfiles = potfiles.append( osp.join('i18n', 'entities.pot') ) - print '******** extract schema messages' - schemapot = osp.join(tempdir, 'schema.pot') - potfiles.append(schemapot) - # XXX - generate_schema_pot(open(schemapot, 'w').write, vreg, appdirectory) - print '******** extract Javascript messages' - jsfiles = find('.', '.js') - if jsfiles: - tmppotfile = osp.join(tempdir, 'js.pot') - execute('xgettext --no-location --omit-header -k_ -L java --from-code=utf-8 -o %s %s' - % (tmppotfile, ' '.join(jsfiles))) - # no pot file created if there are no string to translate - if osp.exists(tmppotfile): - potfiles.append(tmppotfile) - print '******** create cube specific catalog' - tmppotfile = osp.join(tempdir, 'generated.pot') - execute('xgettext --no-location --omit-header -k_ -o %s %s' - % (tmppotfile, ' '.join(glob('*.py')))) - if osp.exists(tmppotfile): # doesn't exists of no translation string found - potfiles.append(tmppotfile) - potfile = osp.join(tempdir, 'cube.pot') - print '******** merging .pot files' - execute('msgcat %s > %s' % (' '.join(potfiles), potfile)) - print '******** merging main pot file with existing translations' - os.chdir('i18n') - for lang in langs: - print '****', lang - tmplpo = '%s.po' % lang - if not osp.exists(tmplpo): - shutil.copy(potfile, tmplpo) - else: - execute('msgmerge -N -s %s %s > %snew' % (tmplpo, potfile, tmplpo)) - ensure_fs_mode(tmplpo) - shutil.move('%snew' % tmplpo, tmplpo) - toedit.append(osp.abspath(tmplpo)) - # cleanup - rm(tempdir) - # instructions pour la suite - print '*' * 72 - print 'you can now edit the following files:' - print '* ' + '\n* '.join(toedit) - - -def getlangs(i18ndir): - return [fname[:-3] for fname in os.listdir(i18ndir) - if fname.endswith('.po')] - - -def get_i18n_directory(appdirectory): - if not osp.isdir(appdirectory): - print '%s is not an application directory' % appdirectory - sys.exit(2) - i18ndir = osp.join(appdirectory, 'i18n') - if not osp.isdir(i18ndir): - print '%s is not an application directory ' \ - '(i18n subdirectory missing)' % appdirectory - sys.exit(2) - return i18ndir diff -r 17ff4d4bfbd0 -r 544609e83317 goa/tools/laxctl.py --- a/goa/tools/laxctl.py Mon Mar 23 13:07:26 2009 +0100 +++ b/goa/tools/laxctl.py Mon Mar 23 17:38:30 2009 +0100 @@ -1,7 +1,7 @@ """provides all lax instances management commands into a single utility script :organization: Logilab -:copyright: 2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +:copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved. :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr """ __docformat__ = "restructuredtext en" @@ -17,14 +17,9 @@ from logilab.common.clcommands import Command, register_commands, main_run -from cubicweb import CW_SOFTWARE_ROOT from cubicweb.common.uilib import remove_html_tags - APPLROOT = osp.abspath(osp.join(osp.dirname(osp.abspath(__file__)), '..')) -# XXX import custom? - -from tools import i18n def initialize_vregistry(applroot): # apply monkey patches first @@ -51,33 +46,6 @@ def run(self, args): self.vreg = initialize_vregistry(APPLROOT) self._run(args) - - -class I18nUpdateCommand(LaxCommand): - """updates i18n catalogs""" - name = 'i18nupdate' - - def _run(self, args): - assert not args, 'no argument expected' - i18ndir = i18n.get_i18n_directory(APPLROOT) - i18n.update_cubes_catalog(self.vreg, APPLROOT, - langs=i18n.getlangs(i18ndir)) - - -class I18nCompileCommand(LaxCommand): - """compiles i18n catalogs""" - name = 'i18ncompile' - min_args = max_args = 0 - - def _run(self, args): - assert not args, 'no argument expected' - i18ndir = i18n.get_i18n_directory(APPLROOT) - langs = i18n.getlangs(i18ndir) - print 'generating .mo files for langs', ', '.join(langs) - cubicweb_i18ndir = osp.join(APPLROOT, 'cubes', 'shared') - paths = self.vreg.config.cubes_path() + [cubicweb_i18ndir] - sourcedirs = [i18ndir] + [osp.join(path, 'i18n') for path in paths] - i18n.compile_i18n_catalogs(sourcedirs, i18ndir, langs=langs) class GenerateSchemaCommand(LaxCommand): @@ -274,9 +242,7 @@ self.extract_message(data) -register_commands([I18nUpdateCommand, - I18nCompileCommand, - GenerateSchemaCommand, +register_commands([GenerateSchemaCommand, PopulateDataDirCommand, DSInitCommand, CleanSessionsCommand,