예제 #1
0
 def clean(self, init_locale, source_paths):
     print(
         colored(self.whoami, 'blue') +
         f': searching for resource snapshots by initialization locale "{init_locale}"...'
     )
     resources = ResourceFileHandler.find_resources_in_source_paths(
         init_locale, source_paths)
     snapshots = []
     for resource in resources:
         snapshot = resource + '.snapshot'
         if os.path.exists(snapshot):
             snapshots.append(snapshot)
     if len(snapshots) > 0:
         reply = Utilities.confirm(
             colored(self.whoami, 'green') +
             f': Found "{len(snapshots)}" ' +
             'snapshots to clear; delete ' + colored('[a]', 'green') +
             'll or ' + colored('[c]', 'green') + 'onfirm each?',
             ['a', 'c'])
         for snapshot in snapshots:
             if reply == 's':
                 break
             if reply != 'a':
                 reply = Utilities.confirm(
                     colored(self.whoami, 'green') +
                     ': Delete snapshot: "' + snapshot + '" ' +
                     colored('[y]', 'green') + 'es, ' +
                     colored('[n]', 'green') + 'o, ' +
                     colored('[a]', 'green') + 'll, or ' +
                     colored('[s]', 'green') + 'top?', ['y', 'n', 'a', 's'])
             if reply == 'y' or reply == 'a':
                 os.remove(snapshot)
예제 #2
0
    def process_response(self, manifest):
        import_manifest = {}
        new_messages = {}
        missing = manifest.data.get('missing')
        new = manifest.data.get('new')
        translations = XlsTranslationsProcessor.get_inbound_translations(
            self.package, self.default_locale, self.expected_locales)
        if self.options.dump:
            Utilities.write_to_json_file(
                Constants.DUMP_PATH + 'translations-raw', translations)

        if missing:
            for resource in missing:
                for path, messages in resource.items():
                    locale = Utilities.get_locale_from_path(
                        path, self.supported_locales)
                    inbound_locale = self.determine_inbound_locale(locale)
                    locale_translations = translations.get(inbound_locale)
                    if locale_translations is not None:
                        for key, message in messages.items():
                            translation = locale_translations.get(message)
                            if path not in import_manifest:
                                import_manifest[path] = {}
                            import_manifest[path][key] = translation
        if new:
            for resource in new:
                for source_path, messages in resource.items():
                    source_locale = Utilities.get_locale_from_path(
                        source_path, [self.default_locale])
                    if source_locale:
                        for locale in self.supported_locales:
                            inbound_locale = self.determine_inbound_locale(
                                locale)
                            locale_translations = translations.get(
                                inbound_locale)
                            if locale_translations is not None:
                                locale_resources_path = Utilities.replace_locale_in_path(
                                    source_path, source_locale, locale)
                                for key, message in messages.items():
                                    translation = locale_translations.get(
                                        message)
                                    # Update the import manifest with translations
                                    if locale_resources_path not in import_manifest:
                                        import_manifest[
                                            locale_resources_path] = {}
                                    import_manifest[locale_resources_path][
                                        key] = translation
                                    # Update new messages
                                    if source_path not in new_messages:
                                        new_messages[source_path] = {}
                                    new_messages[source_path][key] = message

        if self.options.dump:
            Utilities.write_to_json_file(
                Constants.DUMP_PATH + 'translations-manifest', import_manifest)
            Utilities.write_to_json_file(
                Constants.DUMP_PATH + 'translations-new-messages',
                new_messages)
        return import_manifest, new_messages
예제 #3
0
    def get_inbound_translations(package, source_locale, locales):
        translations = {}
        try:
            with zipfile.ZipFile(package + '.zip', 'r') as zip_ref:
                zip_ref.extractall(IOConstants.IN_PATH)
        except:
            sys.exit(f'Translations ZIP package "{package}.zip" not found')

        files = glob.glob(IOConstants.IN_PATH + '**/*.xls', recursive=True) + \
                glob.glob(IOConstants.IN_PATH + '**/*.xlsx', recursive=True)
        for file in files:
            locale = Utilities.get_locale_from_path(file, locales)
            if locale:
                print(
                    colored(XlsTranslationsProcessor.__qualname__, 'blue') +
                    f': Processing translations for {locale}, from {source_locale}, in file {file}'
                )
                translations_data = pd.read_excel(file)
                # Validate
                if source_locale not in translations_data:
                    print(
                        f'Translations in "{file}" does not have a dedicated column for source locale "{source_locale}'
                    )
                if locale not in translations_data:
                    print(
                        f'Translations in "{file}" does not have a dedicated column for locale "{locale}'
                    )

                if locale not in translations:
                    translations[locale] = {}
                for i in translations_data.index:
                    message = translations_data[source_locale][i]
                    translation = translations_data[locale][i]
                    translations[locale][message] = translation
            else:
                print(
                    colored(XlsTranslationsProcessor.__qualname__, 'red') +
                    f': Could not determine locale for translation file: {file}'
                )

        return translations
예제 #4
0
    def __init__(self, config, options):
        if not options.package:
            sys.exit(
                colored(self.whoami, 'red') +
                ': Please provide the export package name by adding option "--package=<name>"'
            )
        self.package = options.package

        self.default_locale = config.get_value(('locales', 'default'))
        self.supported_locales = config.get_value(('locales', 'supported'))
        self.export_mapping = config.get_value(('exporter', 'mapping'))
        self.options = options
        Utilities.init_dir(IOConstants.DEFAULT_TRANSL_XLS_PATH)
        Utilities.init_dir(IOConstants.OUT_PATH)
        Utilities.init_dir(IOConstants.IN_PATH)
예제 #5
0
 def update(self, manifest, new_messages):
     new = manifest.get_new()
     if new:
         for resource in new:
             for source_path, messages in resource.items():
                 if source_path in new_messages.keys():
                     source_new_messages = new_messages[source_path]
                     snapshot_path = source_path + '.snapshot'
                     snapshot = ResourceFileHandler.read_snapshot(
                         snapshot_path)
                     for key, message in source_new_messages.items():
                         snapshot[key] = message
                     ResourceFileHandler.write_snapshot(
                         snapshot_path, snapshot)
                     for copy_to_locale in self.copy_to_locales:
                         print(
                             colored(self.whoami, 'blue') +
                             f': Copying snapshot "{snapshot_path}" content to locale {copy_to_locale}\'s resource.'
                         )
                         ResourceFileHandler.write(
                             Utilities.replace_locale_in_path(
                                 source_path, self.default_locale,
                                 copy_to_locale), snapshot)
예제 #6
0
 def write(resource_path, messages):
     with open(resource_path, encoding='utf-8', mode='w') as outfile:
         for key in messages.keys():
             line = key + '=' + Utilities.get_unicode_markup(messages[key])
             outfile.write(line)
             outfile.write('\n')
예제 #7
0
    def main(self, args=sys.argv[1:], prog=program):
        options = self.parse_args(args, prog)
        config = Config()
        if options.command == 'version':
            # ToDo: Improve
            sys.exit(colored(self.whoami, 'blue') + ': Version = 1.0.0')
        elif options.command == 'init':
            if not options.init_locale:
                sys.exit(
                    f'{self.whoami}: cannot initialize if initialization locale is not provided'
                )
            config.init(options.init_locale, options.source_paths)
        elif options.command == 'clean':
            if not options.init_locale:
                sys.exit(
                    colored(self.whoami, 'red') +
                    f': cannot clean resource snapshots if initialization locale is not provided'
                )
            config.clean(options.init_locale, options.source_paths)
        else:
            config.load_config()
            config.validate()
            all_bundles = Bundler().gather(config)
            manifest = ManifestGenerator.generate(all_bundles, config, options)

            if options.command == 'view':
                print(colored(self.whoami, 'blue') + ': ' + str(manifest))
                if options.dump:
                    Utilities.write_to_json_file(
                        Constants.DUMP_PATH + 'translations-manifest',
                        manifest.data)
            elif options.command == 'export':
                exporter = self.instantiate_exporter(config, options)
                if exporter:
                    exporter.generate_request(manifest)
                else:
                    print(
                        colored(self.whoami, 'red') +
                        ': Failed to process exporter')
            elif options.command == 'import':
                importer = self.instantiate_importer(config, options)
                if importer:
                    translation_updates, new_messages = importer.process_response(
                        manifest)
                    TranslationUpdater.update(translation_updates)
                    SnapshotUpdater(config).update(manifest, new_messages)
                    if self.options.dump:
                        Utilities.write_to_json_file(
                            Constants.DUMP_PATH + 'translations-manifest',
                            manifest.data)
                        Utilities.write_to_json_file(
                            Constants.DUMP_PATH + 'translations-updates',
                            translation_updates)
                else:
                    print(
                        colored(self.whoami, 'red') +
                        ': Failed to process importer')
            elif options.command == 'reconcile':
                Reconciliator(options, all_bundles).reconcile()
            else:
                sys.exit(
                    colored(self.whoami, 'red') +
                    f': command "{options.command}" currently not supported.')
예제 #8
0
 def __init__(self):
     Utilities.init_dir(Constants.WORKING_DIR)
     Utilities.init_dir(Constants.DUMP_PATH)
예제 #9
0
    def generate_request(self, manifest):
        target_translations = {}
        for locale in self.supported_locales:
            locale_out_target = self.get_locale_out_target(locale)
            if locale_out_target:
                print(
                    colored(self.whoami, 'blue') +
                    f': Processing added messages for locale "{locale}" to be included on export "{locale_out_target}"'
                )
                if locale_out_target in target_translations:
                    translations = target_translations[locale_out_target]
                else:
                    translations = []

                for bundles in manifest.get_new():
                    for bundle_path in bundles:
                        messages = bundles[bundle_path]
                        for message in messages.values():
                            if message not in translations:
                                translations.append(message)
                target_translations[locale_out_target] = translations
            else:
                print(
                    colored(self.whoami, 'yellow') +
                    f': Processing added messages for locale "{locale}" was ignored'
                )

        for resources in manifest.get_missing():
            for resource_path in resources:
                locale = Utilities.get_locale_from_path(
                    resource_path, self.supported_locales)
                locale_out_target = self.get_locale_out_target(locale)
                if locale_out_target:
                    print(
                        colored(self.whoami, 'blue') +
                        f': Processing missing messages in locale "{locale}" to be included on export "{locale_out_target}"'
                    )
                    if locale_out_target in target_translations:
                        translations = target_translations[locale_out_target]
                    else:
                        translations = []
                    messages = resources[resource_path]
                    for message in messages.values():
                        if message not in translations:
                            translations.append(message)
                    target_translations[locale_out_target] = translations
                else:
                    print(
                        colored(self.whoami, 'yellow') +
                        f': Processing missing messages for locale "{locale}" was ignored'
                    )

        for target in target_translations:
            print(
                colored(self.whoami, 'blue') +
                f': Writing locale "{target}" with "{len(target_translations[target])}" translations'
            )
            self.write_xls(target, target_translations[target])

        print(
            colored(self.whoami, 'blue') +
            f': Starting packaging: Using translations XLS in path "{IOConstants.DEFAULT_TRANSL_XLS_PATH}"'
        )
        file_name = shutil.make_archive(IOConstants.OUT_PATH + self.package,
                                        'zip',
                                        IOConstants.DEFAULT_TRANSL_XLS_PATH)
        print(
            colored(self.whoami, 'blue') +
            f': Package generated in "{file_name}"')