devtools/devctl.py
branchtls-sprint
changeset 1451 982e8616d9a2
parent 1415 98b8e5c627b8
child 1470 fbdf66a08fbb
equal deleted inserted replaced
1450:8edb0806dde4 1451:982e8616d9a2
    38         else:
    38         else:
    39             self._cubes = self.expand_cubes(self.my_cubes(cube))
    39             self._cubes = self.expand_cubes(self.my_cubes(cube))
    40 
    40 
    41     def my_cubes(self, cube):
    41     def my_cubes(self, cube):
    42         return (cube,) + self.cube_dependencies(cube) + self.cube_recommends(cube)
    42         return (cube,) + self.cube_dependencies(cube) + self.cube_recommends(cube)
    43     
    43 
    44     @property
    44     @property
    45     def apphome(self):
    45     def apphome(self):
    46         return None
    46         return None
    47     def main_config_file(self):
    47     def main_config_file(self):
    48         return None
    48         return None
    75             continue
    75             continue
    76         for path in config.vregistry_path():
    76         for path in config.vregistry_path():
    77             if mod.__file__.startswith(path):
    77             if mod.__file__.startswith(path):
    78                 del sys.modules[name]
    78                 del sys.modules[name]
    79                 break
    79                 break
    80     
    80 
    81 def generate_schema_pot(w, cubedir=None):
    81 def generate_schema_pot(w, cubedir=None):
    82     """generate a pot file with schema specific i18n messages
    82     """generate a pot file with schema specific i18n messages
    83 
    83 
    84     notice that relation definitions description and static vocabulary
    84     notice that relation definitions description and static vocabulary
    85     should be marked using '_' and extracted using xgettext
    85     should be marked using '_' and extracted using xgettext
    99     vreg = CubicWebRegistry(config)
    99     vreg = CubicWebRegistry(config)
   100     # set_schema triggers objects registrations
   100     # set_schema triggers objects registrations
   101     vreg.set_schema(schema)
   101     vreg.set_schema(schema)
   102     w(DEFAULT_POT_HEAD)
   102     w(DEFAULT_POT_HEAD)
   103     _generate_schema_pot(w, vreg, schema, libschema=libschema, cube=cube)
   103     _generate_schema_pot(w, vreg, schema, libschema=libschema, cube=cube)
   104                 
   104 
       
   105 
   105 def _generate_schema_pot(w, vreg, schema, libschema=None, cube=None):
   106 def _generate_schema_pot(w, vreg, schema, libschema=None, cube=None):
   106     from cubicweb.common.i18n import add_msg
   107     from cubicweb.common.i18n import add_msg
   107     w('# schema pot file, generated on %s\n' % datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
   108     w('# schema pot file, generated on %s\n' % datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
   108     w('# \n')
   109     w('# \n')
   109     w('# singular and plural forms for each entity type\n')
   110     w('# singular and plural forms for each entity type\n')
   145     w('\n')
   146     w('\n')
   146     actionbox = vreg['boxes']['edit_box'][0]
   147     actionbox = vreg['boxes']['edit_box'][0]
   147     for eschema in schema.entities():
   148     for eschema in schema.entities():
   148         if eschema.is_final():
   149         if eschema.is_final():
   149             continue
   150             continue
   150         for x, rschemas in (('subject', eschema.subject_relations()),
   151         for role, rschemas in (('subject', eschema.subject_relations()),
   151                             ('object', eschema.object_relations())):
   152                             ('object', eschema.object_relations())):
   152             for rschema in rschemas:
   153             for rschema in rschemas:
   153                 if rschema.is_final():
   154                 if rschema.is_final():
   154                     continue
   155                     continue
   155                 for teschema in rschema.targets(eschema, x):
   156                 for teschema in rschema.targets(eschema, role):
   156                     if defined_in_library(libschema, eschema, rschema, teschema, x):
   157                     if defined_in_library(libschema, eschema, rschema,
       
   158                                           teschema, role):
   157                         continue
   159                         continue
   158                     if actionbox.relation_mode(rschema.type, teschema.type, x) == 'create':
   160                     if actionbox.relation_mode(rschema, eschema, teschema, role) == 'create':
   159                         if x == 'subject':
   161                         if role == 'subject':
   160                             label = 'add %s %s %s %s' % (eschema, rschema, teschema, x)
   162                             label = 'add %s %s %s %s' % (eschema, rschema,
   161                             label2 = "creating %s (%s %%(linkto)s %s %s)" % (teschema, eschema, rschema, teschema)
   163                                                          teschema, role)
       
   164                             label2 = "creating %s (%s %%(linkto)s %s %s)" % (
       
   165                                 teschema, eschema, rschema, teschema)
   162                         else:
   166                         else:
   163                             label = 'add %s %s %s %s' % (teschema, rschema, eschema, x)
   167                             label = 'add %s %s %s %s' % (teschema, rschema,
   164                             label2 = "creating %s (%s %s %s %%(linkto)s)" % (teschema, teschema, rschema, eschema)
   168                                                          eschema, role)
       
   169                             label2 = "creating %s (%s %s %s %%(linkto)s)" % (
       
   170                                 teschema, teschema, rschema, eschema)
   165                         add_msg(w, label)
   171                         add_msg(w, label)
   166                         add_msg(w, label2)
   172                         add_msg(w, label2)
   167     cube = (cube and 'cubes.%s.' % cube or 'cubicweb.')
   173     cube = (cube and 'cubes.%s.' % cube or 'cubicweb.')
   168     done = set()
   174     done = set()
   169     for reg, objdict in vreg.items():
   175     for reg, objdict in vreg.items():
   175                 if obj.__module__.startswith(cube) and obj.property_defs:
   181                 if obj.__module__.startswith(cube) and obj.property_defs:
   176                     add_msg(w, '%s_description' % objid)
   182                     add_msg(w, '%s_description' % objid)
   177                     add_msg(w, objid)
   183                     add_msg(w, objid)
   178                     done.add(objid)
   184                     done.add(objid)
   179 
   185 
   180                     
   186 
   181 def defined_in_library(libschema, etype, rtype, tetype, x):
   187 def defined_in_library(libschema, etype, rtype, tetype, role):
   182     """return true if the given relation definition exists in cubicweb's library"""
   188     """return true if the given relation definition exists in cubicweb's library
       
   189     """
   183     if libschema is None:
   190     if libschema is None:
   184         return False
   191         return False
   185     if x == 'subject':
   192     if role == 'subject':
   186         subjtype, objtype = etype, tetype
   193         subjtype, objtype = etype, tetype
   187     else:
   194     else:
   188         subjtype, objtype = tetype, etype
   195         subjtype, objtype = tetype, etype
   189     try:
   196     try:
   190         return libschema.rschema(rtype).has_rdef(subjtype, objtype)
   197         return libschema.rschema(rtype).has_rdef(subjtype, objtype)
   209 ''' % cubicwebversion
   216 ''' % cubicwebversion
   210 
   217 
   211 
   218 
   212 class UpdateCubicWebCatalogCommand(Command):
   219 class UpdateCubicWebCatalogCommand(Command):
   213     """Update i18n catalogs for cubicweb library.
   220     """Update i18n catalogs for cubicweb library.
   214     
   221 
   215     It will regenerate cubicweb/i18n/xx.po files. You'll have then to edit those
   222     It will regenerate cubicweb/i18n/xx.po files. You'll have then to edit those
   216     files to add translations of newly added messages.
   223     files to add translations of newly added messages.
   217     """
   224     """
   218     name = 'i18nlibupdate'
   225     name = 'i18nlibupdate'
   219 
   226 
   279     """Update i18n catalogs for cubes. If no cube is specified, update
   286     """Update i18n catalogs for cubes. If no cube is specified, update
   280     catalogs of all registered cubes.
   287     catalogs of all registered cubes.
   281     """
   288     """
   282     name = 'i18nupdate'
   289     name = 'i18nupdate'
   283     arguments = '[<cube>...]'
   290     arguments = '[<cube>...]'
   284     
   291 
   285     def run(self, args):
   292     def run(self, args):
   286         """run the command with its specific arguments"""
   293         """run the command with its specific arguments"""
   287         if args:
   294         if args:
   288             cubes = [DevCubeConfiguration.cube_dir(cube) for cube in args]
   295             cubes = [DevCubeConfiguration.cube_dir(cube) for cube in args]
   289         else:
   296         else:
   326         if jsfiles:
   333         if jsfiles:
   327             tmppotfile = join(tempdir, 'js.pot')
   334             tmppotfile = join(tempdir, 'js.pot')
   328             execute('xgettext --no-location --omit-header -k_ -L java --from-code=utf-8 -o %s %s'
   335             execute('xgettext --no-location --omit-header -k_ -L java --from-code=utf-8 -o %s %s'
   329                     % (tmppotfile, ' '.join(jsfiles)))
   336                     % (tmppotfile, ' '.join(jsfiles)))
   330             # no pot file created if there are no string to translate
   337             # no pot file created if there are no string to translate
   331             if exists(tmppotfile): 
   338             if exists(tmppotfile):
   332                 potfiles.append(tmppotfile)
   339                 potfiles.append(tmppotfile)
   333         print '******** create cube specific catalog'
   340         print '******** create cube specific catalog'
   334         tmppotfile = join(tempdir, 'generated.pot')
   341         tmppotfile = join(tempdir, 'generated.pot')
   335         cubefiles = find('.', '.py', blacklist=STD_BLACKLIST+('test',))
   342         cubefiles = find('.', '.py', blacklist=STD_BLACKLIST+('test',))
   336         cubefiles.append(tali18nfile)
   343         cubefiles.append(tali18nfile)
   365     """Run a server from within a cube directory.
   372     """Run a server from within a cube directory.
   366     """
   373     """
   367     name = 'live-server'
   374     name = 'live-server'
   368     arguments = ''
   375     arguments = ''
   369     options = ()
   376     options = ()
   370     
   377 
   371     def run(self, args):
   378     def run(self, args):
   372         """run the command with its specific arguments"""
   379         """run the command with its specific arguments"""
   373         from cubicweb.devtools.livetest import runserver
   380         from cubicweb.devtools.livetest import runserver
   374         runserver()
   381         runserver()
   375 
   382 
   413           'help': 'cube author\'s web site',
   420           'help': 'cube author\'s web site',
   414           }
   421           }
   415          ),
   422          ),
   416         )
   423         )
   417 
   424 
   418     
   425 
   419     def run(self, args):
   426     def run(self, args):
   420         if len(args) != 1:
   427         if len(args) != 1:
   421             raise BadCommandUsage("exactly one argument (cube name) is expected")
   428             raise BadCommandUsage("exactly one argument (cube name) is expected")
   422         cubename, = args
   429         cubename, = args
   423         #if ServerConfiguration.mode != "dev":
   430         #if ServerConfiguration.mode != "dev":
   447             elif not distname.startswith('cubicweb-'):
   454             elif not distname.startswith('cubicweb-'):
   448                 if confirm('do you mean cubicweb-%s ?' % distname):
   455                 if confirm('do you mean cubicweb-%s ?' % distname):
   449                     distname = 'cubicweb-' + distname
   456                     distname = 'cubicweb-' + distname
   450         else:
   457         else:
   451             distname = 'cubicweb-%s' % cubename.lower()
   458             distname = 'cubicweb-%s' % cubename.lower()
   452         
   459 
   453         longdesc = shortdesc = raw_input('Enter a short description for your cube: ')
   460         longdesc = shortdesc = raw_input('Enter a short description for your cube: ')
   454         if verbose:
   461         if verbose:
   455             longdesc = raw_input('Enter a long description (or nothing if you want to reuse the short one): ')
   462             longdesc = raw_input('Enter a long description (or nothing if you want to reuse the short one): ')
   456         if verbose:
   463         if verbose:
   457             includes = self._ask_for_dependancies()
   464             includes = self._ask_for_dependancies()
   485                 includes = get_csv(raw_input('type dependancies: '))
   492                 includes = get_csv(raw_input('type dependancies: '))
   486                 break
   493                 break
   487             elif ans == 's':
   494             elif ans == 's':
   488                 break
   495                 break
   489         return includes
   496         return includes
   490     
   497 
   491 
   498 
   492 class ExamineLogCommand(Command):
   499 class ExamineLogCommand(Command):
   493     """Examine a rql log file.
   500     """Examine a rql log file.
   494 
   501 
   495     usage: python exlog.py < rql.log
   502     usage: python exlog.py < rql.log
   504     the higher benefit after optimisation. Start there.
   511     the higher benefit after optimisation. Start there.
   505     """
   512     """
   506     name = 'exlog'
   513     name = 'exlog'
   507     options = (
   514     options = (
   508         )
   515         )
   509     
   516 
   510     def run(self, args):
   517     def run(self, args):
   511         if args:
   518         if args:
   512             raise BadCommandUsage("no argument expected")
   519             raise BadCommandUsage("no argument expected")
   513         import re
   520         import re
   514         requests = {}
   521         requests = {}
   538 
   545 
   539         total_time = sum(time for time, occ, rql in stat)*0.01
   546         total_time = sum(time for time, occ, rql in stat)*0.01
   540         print 'Percentage;Cumulative Time;Occurences;Query'
   547         print 'Percentage;Cumulative Time;Occurences;Query'
   541         for time, occ, rql in stat:
   548         for time, occ, rql in stat:
   542             print '%.2f;%.2f;%s;%s' % (time/total_time, time, occ, rql)
   549             print '%.2f;%.2f;%s;%s' % (time/total_time, time, occ, rql)
   543         
   550 
   544 register_commands((UpdateCubicWebCatalogCommand,
   551 register_commands((UpdateCubicWebCatalogCommand,
   545                    UpdateTemplateCatalogCommand,
   552                    UpdateTemplateCatalogCommand,
   546                    LiveServerCommand,
   553                    LiveServerCommand,
   547                    NewCubeCommand,
   554                    NewCubeCommand,
   548                    ExamineLogCommand,
   555                    ExamineLogCommand,