def compile_user_manual_translations(self): self.info('Compiling user manual translations...') srcbase = self.j(self.d(self.SRC), 'translations', 'manual') destbase = self.j(self.d(self.SRC), 'manual', 'locale') complete = {} all_stats = defaultdict(lambda : {'translated': 0, 'untranslated': 0}) files = [] for x in os.listdir(srcbase): q = self.j(srcbase, x) if not os.path.isdir(q): continue dest = self.j(destbase, x, 'LC_MESSAGES') if os.path.exists(dest): shutil.rmtree(dest) os.makedirs(dest) for po in os.listdir(q): if not po.endswith('.po'): continue mofile = self.j(dest, po.rpartition('.')[0] + '.mo') files.append((self.j(q, po), mofile)) def handle_stats(src, nums): locale = self.b(self.d(src)) stats = all_stats[locale] stats['translated'] += nums[0] if len(nums) > 1: stats['untranslated'] += nums[1] self.compile_group(files, handle_stats=handle_stats) for locale, stats in iteritems(all_stats): dump_json(stats, self.j(srcbase, locale, 'stats.json')) total = stats['translated'] + stats['untranslated'] # Raise the 30% threshold in the future if total and (stats['translated'] / float(total)) > 0.3: complete[locale] = stats dump_json(complete, self.j(destbase, 'completed.json'))
def run(self, opts): from calibre.utils.serialize import msgpack_dumps scripts = {} for x in ('console', 'gui'): for name in basenames[x]: if name in ('calibre-complete', 'calibre_postinstall'): continue scripts[name] = x dest = self.j(self.RESOURCES, 'scripts.calibre_msgpack') if self.newer(dest, self.j(self.SRC, 'calibre', 'linux.py')): self.info('\tCreating ' + self.b(dest)) with open(dest, 'wb') as f: f.write(msgpack_dumps(scripts)) from calibre.web.feeds.recipes.collection import \ serialize_builtin_recipes, iterate_over_builtin_recipe_files files = [x[1] for x in iterate_over_builtin_recipe_files()] dest = self.j(self.RESOURCES, 'builtin_recipes.xml') if self.newer(dest, files): self.info('\tCreating builtin_recipes.xml') xml = serialize_builtin_recipes() with open(dest, 'wb') as f: f.write(xml) recipe_icon_dir = self.a( self.j(self.RESOURCES, '..', 'recipes', 'icons')) dest = os.path.splitext(dest)[0] + '.zip' files += glob.glob(self.j(recipe_icon_dir, '*.png')) if self.newer(dest, files): self.info('\tCreating builtin_recipes.zip') with zipfile.ZipFile(dest, 'w', zipfile.ZIP_STORED) as zf: for n in sorted(files, key=self.b): with open(n, 'rb') as f: zf.writestr(self.b(n), f.read()) dest = self.j(self.RESOURCES, 'ebook-convert-complete.calibre_msgpack') files = [] for x in os.walk(self.j(self.SRC, 'calibre')): for f in x[-1]: if f.endswith('.py'): files.append(self.j(x[0], f)) if self.newer(dest, files): self.info('\tCreating ' + self.b(dest)) complete = {} from calibre.ebooks.conversion.plumber import supported_input_formats complete['input_fmts'] = set(supported_input_formats()) from calibre.web.feeds.recipes.collection import get_builtin_recipe_titles complete['input_recipes'] = [ t + '.recipe ' for t in get_builtin_recipe_titles() ] from calibre.customize.ui import available_output_formats complete['output'] = set(available_output_formats()) from calibre.ebooks.conversion.cli import create_option_parser from calibre.utils.logging import Log log = Log() # log.outputs = [] for inf in supported_input_formats(): if inf in ('zip', 'rar', 'oebzip'): continue for ouf in available_output_formats(): of = ouf if ouf == 'oeb' else 'dummy.' + ouf p = create_option_parser(('ec', 'dummy1.' + inf, of, '-h'), log)[0] complete[(inf, ouf)] = [ x + ' ' for x in get_opts_from_parser(p) ] with open(dest, 'wb') as f: f.write(msgpack_dumps(only_unicode_recursive(complete))) self.info('\tCreating template-functions.json') dest = self.j(self.RESOURCES, 'template-functions.json') function_dict = {} import inspect from calibre.utils.formatter_functions import formatter_functions for obj in formatter_functions().get_builtins().values(): eval_func = inspect.getmembers( obj, lambda x: inspect.ismethod(x) and x.__name__ == 'evaluate') try: lines = [ l[4:] for l in inspect.getsourcelines(eval_func[0][1])[0] ] except: continue lines = ''.join(lines) function_dict[obj.name] = lines dump_json(function_dict, dest) self.info('\tCreating editor-functions.json') dest = self.j(self.RESOURCES, 'editor-functions.json') function_dict = {} from calibre.gui2.tweak_book.function_replace import builtin_functions for func in builtin_functions(): try: src = ''.join(inspect.getsourcelines(func)[0][1:]) except Exception: continue src = src.replace('def ' + func.__name__, 'def replace') imports = [ f'from {x.__module__} import {x.__name__}' for x in func.imports ] if imports: src = '\n'.join(imports) + '\n\n' + src function_dict[func.name] = src dump_json(function_dict, dest) self.info('\tCreating user-manual-translation-stats.json') d = {} for lc, stats in iteritems( json.load( open( self.j(self.d(self.SRC), 'manual', 'locale', 'completed.json')))): total = sum(itervalues(stats)) d[lc] = stats['translated'] / float(total) dump_json(d, self.j(self.RESOURCES, 'user-manual-translation-stats.json')) src = self.j(self.SRC, '..', 'Changelog.txt') dest = self.j(self.RESOURCES, 'changelog.json') if self.newer(dest, [src]): self.info('\tCreating changelog.json') from setup.changelog import parse with open(src, encoding='utf-8') as f: dump_json(parse(f.read(), parse_dates=False), dest)
def save_cache(self, cache): dump_json(cache, self.cache_file)