300 import tempfile |
300 import tempfile |
301 import yams |
301 import yams |
302 from logilab.common.fileutils import ensure_fs_mode |
302 from logilab.common.fileutils import ensure_fs_mode |
303 from logilab.common.shellutils import globfind, find, rm |
303 from logilab.common.shellutils import globfind, find, rm |
304 from logilab.common.modutils import get_module_files |
304 from logilab.common.modutils import get_module_files |
305 from cubicweb.i18n import extract_from_tal, execute |
305 from cubicweb.i18n import extract_from_tal, execute2 |
306 tempdir = tempfile.mkdtemp(prefix='cw-') |
306 tempdir = tempfile.mkdtemp(prefix='cw-') |
307 cwi18ndir = WebConfiguration.i18n_lib_dir() |
307 cwi18ndir = WebConfiguration.i18n_lib_dir() |
308 print '-> extract schema messages.' |
308 print '-> extract messages:', |
|
309 print 'schema', |
309 schemapot = osp.join(tempdir, 'schema.pot') |
310 schemapot = osp.join(tempdir, 'schema.pot') |
310 potfiles = [schemapot] |
311 potfiles = [schemapot] |
311 potfiles.append(schemapot) |
312 potfiles.append(schemapot) |
312 # explicit close necessary else the file may not be yet flushed when |
313 # explicit close necessary else the file may not be yet flushed when |
313 # we'll using it below |
314 # we'll using it below |
314 schemapotstream = file(schemapot, 'w') |
315 schemapotstream = file(schemapot, 'w') |
315 generate_schema_pot(schemapotstream.write, cubedir=None) |
316 generate_schema_pot(schemapotstream.write, cubedir=None) |
316 schemapotstream.close() |
317 schemapotstream.close() |
317 print '-> extract TAL messages.' |
318 print 'TAL', |
318 tali18nfile = osp.join(tempdir, 'tali18n.py') |
319 tali18nfile = osp.join(tempdir, 'tali18n.py') |
319 extract_from_tal(find(osp.join(BASEDIR, 'web'), ('.py', '.pt')), |
320 extract_from_tal(find(osp.join(BASEDIR, 'web'), ('.py', '.pt')), |
320 tali18nfile) |
321 tali18nfile) |
321 print '-> generate .pot files.' |
322 print '-> generate .pot files.' |
322 pyfiles = get_module_files(BASEDIR) |
323 pyfiles = get_module_files(BASEDIR) |
327 ('schemadescr', schemafiles, None), |
328 ('schemadescr', schemafiles, None), |
328 ('yams', get_module_files(yams.__path__[0]), None), |
329 ('yams', get_module_files(yams.__path__[0]), None), |
329 ('tal', [tali18nfile], None), |
330 ('tal', [tali18nfile], None), |
330 ('js', jsfiles, 'java'), |
331 ('js', jsfiles, 'java'), |
331 ]: |
332 ]: |
332 cmd = 'xgettext --no-location --omit-header -k_ -o %s %s' |
333 potfile = osp.join(tempdir, '%s.pot' % id) |
|
334 cmd = ['xgettext', '--no-location', '--omit-header', '-k_'] |
333 if lang is not None: |
335 if lang is not None: |
334 cmd += ' -L %s' % lang |
336 cmd.extend(['-L', lang]) |
335 potfile = osp.join(tempdir, '%s.pot' % id) |
337 cmd.extend(['-o', potfile]) |
336 execute(cmd % (potfile, ' '.join('"%s"' % f for f in files))) |
338 cmd.extend(files) |
|
339 execute2(cmd) |
337 if osp.exists(potfile): |
340 if osp.exists(potfile): |
338 potfiles.append(potfile) |
341 potfiles.append(potfile) |
339 else: |
342 else: |
340 print '-> WARNING: %s file was not generated' % potfile |
343 print '-> WARNING: %s file was not generated' % potfile |
341 print '-> merging %i .pot files' % len(potfiles) |
344 print '-> merging %i .pot files' % len(potfiles) |
342 cubicwebpot = osp.join(tempdir, 'cubicweb.pot') |
345 cubicwebpot = osp.join(tempdir, 'cubicweb.pot') |
343 execute('msgcat -o %s %s' |
346 cmd = ['msgcat', '-o', cubicwebpot] + potfiles |
344 % (cubicwebpot, ' '.join('"%s"' % f for f in potfiles))) |
347 execute2(cmd) |
345 print '-> merging main pot file with existing translations.' |
348 print '-> merging main pot file with existing translations.' |
346 chdir(cwi18ndir) |
349 chdir(cwi18ndir) |
347 toedit = [] |
350 toedit = [] |
348 for lang in CubicWebNoAppConfiguration.cw_languages(): |
351 for lang in CubicWebNoAppConfiguration.cw_languages(): |
349 target = '%s.po' % lang |
352 target = '%s.po' % lang |
350 execute('msgmerge -N --sort-output -o "%snew" "%s" "%s"' |
353 cmd = ['msgmerge', '-N', '--sort-output', '-o', |
351 % (target, target, cubicwebpot)) |
354 target+'new', target, cubicwebpot] |
|
355 execute2(cmd) |
352 ensure_fs_mode(target) |
356 ensure_fs_mode(target) |
353 shutil.move('%snew' % target, target) |
357 shutil.move('%snew' % target, target) |
354 toedit.append(osp.abspath(target)) |
358 toedit.append(osp.abspath(target)) |
355 # cleanup |
359 # cleanup |
356 rm(tempdir) |
360 rm(tempdir) |
380 if not update_cubes_catalogs(cubes): |
384 if not update_cubes_catalogs(cubes): |
381 raise ExecutionError("update cubes i18n catalog failed") |
385 raise ExecutionError("update cubes i18n catalog failed") |
382 |
386 |
383 |
387 |
384 def update_cubes_catalogs(cubes): |
388 def update_cubes_catalogs(cubes): |
|
389 from subprocess import CalledProcessError |
385 for cubedir in cubes: |
390 for cubedir in cubes: |
386 if not osp.isdir(cubedir): |
391 if not osp.isdir(cubedir): |
387 print '-> ignoring %s that is not a directory.' % cubedir |
392 print '-> ignoring %s that is not a directory.' % cubedir |
388 continue |
393 continue |
389 try: |
394 try: |
390 toedit = update_cube_catalogs(cubedir) |
395 toedit = update_cube_catalogs(cubedir) |
|
396 except CalledProcessError, exc: |
|
397 print '\n*** error while updating catalogs for cube', cubedir |
|
398 print 'cmd:\n%s' % exc.cmd |
|
399 print 'stdout:\n%s\nstderr:\n%s' % exc.data |
391 except Exception: |
400 except Exception: |
392 import traceback |
401 import traceback |
393 traceback.print_exc() |
402 traceback.print_exc() |
394 print '-> error while updating catalogs for cube', cubedir |
403 print '*** error while updating catalogs for cube', cubedir |
395 return False |
404 return False |
396 else: |
405 else: |
397 # instructions pour la suite |
406 # instructions pour la suite |
398 if toedit: |
407 if toedit: |
399 print '-> regenerated .po catalogs for cube %s.' % cubedir |
408 print '-> regenerated .po catalogs for cube %s.' % cubedir |
419 potfiles = [osp.join('i18n', 'entities.pot')] |
428 potfiles = [osp.join('i18n', 'entities.pot')] |
420 elif osp.exists(osp.join('i18n', 'static-messages.pot')): |
429 elif osp.exists(osp.join('i18n', 'static-messages.pot')): |
421 potfiles = [osp.join('i18n', 'static-messages.pot')] |
430 potfiles = [osp.join('i18n', 'static-messages.pot')] |
422 else: |
431 else: |
423 potfiles = [] |
432 potfiles = [] |
424 print '-> extract schema messages' |
433 print '-> extracting messages:', |
|
434 print 'schema', |
425 schemapot = osp.join(tempdir, 'schema.pot') |
435 schemapot = osp.join(tempdir, 'schema.pot') |
426 potfiles.append(schemapot) |
436 potfiles.append(schemapot) |
427 # explicit close necessary else the file may not be yet flushed when |
437 # explicit close necessary else the file may not be yet flushed when |
428 # we'll using it below |
438 # we'll using it below |
429 schemapotstream = file(schemapot, 'w') |
439 schemapotstream = file(schemapot, 'w') |
430 generate_schema_pot(schemapotstream.write, cubedir) |
440 generate_schema_pot(schemapotstream.write, cubedir) |
431 schemapotstream.close() |
441 schemapotstream.close() |
432 print '-> extract TAL messages' |
442 print 'TAL', |
433 tali18nfile = osp.join(tempdir, 'tali18n.py') |
443 tali18nfile = osp.join(tempdir, 'tali18n.py') |
434 ptfiles = find('.', ('.py', '.pt'), blacklist=STD_BLACKLIST+('test',)) |
444 ptfiles = find('.', ('.py', '.pt'), blacklist=STD_BLACKLIST+('test',)) |
435 extract_from_tal(ptfiles, tali18nfile) |
445 extract_from_tal(ptfiles, tali18nfile) |
436 print '-> extract Javascript messages' |
446 print 'Javascript' |
437 jsfiles = [jsfile for jsfile in find('.', '.js') |
447 jsfiles = [jsfile for jsfile in find('.', '.js') |
438 if osp.basename(jsfile).startswith('cub')] |
448 if osp.basename(jsfile).startswith('cub')] |
439 if jsfiles: |
449 if jsfiles: |
440 tmppotfile = osp.join(tempdir, 'js.pot') |
450 tmppotfile = osp.join(tempdir, 'js.pot') |
441 execute('xgettext --no-location --omit-header -k_ -L java ' |
451 cmd = ['xgettext', '--no-location', '--omit-header', '-k_', '-L', 'java', |
442 '--from-code=utf-8 -o %s %s' % (tmppotfile, ' '.join(jsfiles))) |
452 '--from-code=utf-8', '-o', tmppotfile] + jsfiles |
|
453 execute2(cmd) |
443 # no pot file created if there are no string to translate |
454 # no pot file created if there are no string to translate |
444 if osp.exists(tmppotfile): |
455 if osp.exists(tmppotfile): |
445 potfiles.append(tmppotfile) |
456 potfiles.append(tmppotfile) |
446 print '-> create cube-specific catalog' |
457 print '-> creating cube-specific catalog' |
447 tmppotfile = osp.join(tempdir, 'generated.pot') |
458 tmppotfile = osp.join(tempdir, 'generated.pot') |
448 cubefiles = find('.', '.py', blacklist=STD_BLACKLIST+('test',)) |
459 cubefiles = find('.', '.py', blacklist=STD_BLACKLIST+('test',)) |
449 cubefiles.append(tali18nfile) |
460 cubefiles.append(tali18nfile) |
450 execute('xgettext --no-location --omit-header -k_ -o %s %s' |
461 cmd = ['xgettext', '--no-location', '--omit-header', '-k_', '-o', tmppotfile] |
451 % (tmppotfile, ' '.join('"%s"' % f for f in cubefiles))) |
462 cmd.extend(cubefiles) |
|
463 execute2(cmd) |
452 if osp.exists(tmppotfile): # doesn't exists of no translation string found |
464 if osp.exists(tmppotfile): # doesn't exists of no translation string found |
453 potfiles.append(tmppotfile) |
465 potfiles.append(tmppotfile) |
454 potfile = osp.join(tempdir, 'cube.pot') |
466 potfile = osp.join(tempdir, 'cube.pot') |
455 print '-> merging %i .pot files:' % len(potfiles) |
467 print '-> merging %i .pot files' % len(potfiles) |
456 execute('msgcat -o %s %s' % (potfile, |
468 cmd = ['msgcat', '-o', potfile] |
457 ' '.join('"%s"' % f for f in potfiles))) |
469 cmd.extend(potfiles) |
|
470 execute2(cmd) |
458 if not osp.exists(potfile): |
471 if not osp.exists(potfile): |
459 print 'no message catalog for cube', cube, 'nothing to translate' |
472 print 'no message catalog for cube', cube, 'nothing to translate' |
460 # cleanup |
473 # cleanup |
461 rm(tempdir) |
474 rm(tempdir) |
462 return () |
475 return () |
463 print '-> merging main pot file with existing translations:' |
476 print '-> merging main pot file with existing translations:', |
464 chdir('i18n') |
477 chdir('i18n') |
465 toedit = [] |
478 toedit = [] |
466 for lang in CubicWebNoAppConfiguration.cw_languages(): |
479 for lang in CubicWebNoAppConfiguration.cw_languages(): |
467 print '-> language', lang |
480 print lang, |
468 cubepo = '%s.po' % lang |
481 cubepo = '%s.po' % lang |
469 if not osp.exists(cubepo): |
482 if not osp.exists(cubepo): |
470 shutil.copy(potfile, cubepo) |
483 shutil.copy(potfile, cubepo) |
471 else: |
484 else: |
472 execute('msgmerge -N -s -o %snew %s %s' % (cubepo, cubepo, potfile)) |
485 cmd = ['msgmerge','-N','-s','-o', cubepo+'new', cubepo, potfile] |
|
486 execute2(cmd) |
473 ensure_fs_mode(cubepo) |
487 ensure_fs_mode(cubepo) |
474 shutil.move('%snew' % cubepo, cubepo) |
488 shutil.move('%snew' % cubepo, cubepo) |
475 toedit.append(osp.abspath(cubepo)) |
489 toedit.append(osp.abspath(cubepo)) |
|
490 print |
476 # cleanup |
491 # cleanup |
477 rm(tempdir) |
492 rm(tempdir) |
478 return toedit |
493 return toedit |
479 |
494 |
480 |
495 |