Пример #1
0
 def read_csv(self, path, locale=utils.SENTINEL):
     return utils.get_rows_from_csv(pod=self, path=path, locale=locale)
Пример #2
0
 def read_csv(self, path, locale=utils.SENTINEL):
     with self.profile.timer('Pod.read_csv',
                             label=path,
                             meta={'path': path}):
         return utils.get_rows_from_csv(pod=self, path=path, locale=locale)
Пример #3
0
def csv(path, locale=_no_locale, _pod=None):
  return utils.get_rows_from_csv(pod=_pod, path=path, locale=locale)
Пример #4
0
Файл: pods.py Проект: grow/grow
 def read_csv(self, path, locale=utils.SENTINEL):
     with self.profile.timer('Pod.read_csv', label=path, meta={'path': path}):
         return utils.get_rows_from_csv(pod=self, path=path, locale=locale)
Пример #5
0
 def read_csv(self, path, locale=utils.SENTINEL):
     return utils.get_rows_from_csv(pod=self, path=path, locale=locale)
Пример #6
0
    def extract(self, include_obsolete=False, localized=False, paths=None,
                include_header=False, locales=None, use_fuzzy_matching=False):
        env = self.pod.get_jinja_env()

        all_locales = set(list(self.pod.list_locales()))
        message_ids_to_messages = {}
        paths_to_messages = collections.defaultdict(set)
        paths_to_locales = collections.defaultdict(set)

        comment_tags = [
            ':',
        ]
        options = {
            'extensions': ','.join(env.extensions.keys()),
            'silent': 'false',
        }

        # Extract from content files.
        def callback(doc, item, key, unused_node):
            # Verify that the fields we're extracting are fields for a document
            # that's in the default locale. If not, skip the document.
            _handle_field(doc.pod_path, item, key, unused_node)

        def _add_existing_message(msgid, locations, auto_comments=None,
                                  context=None, path=None):
            existing_message = message_ids_to_messages.get(msgid)
            auto_comments = [] if auto_comments is None else auto_comments
            if existing_message:
                message_ids_to_messages[msgid].locations.extend(locations)
                paths_to_messages[path].add(existing_message)
            else:
                message = catalog.Message(
                    msgid,
                    None,
                    auto_comments=auto_comments,
                    context=context,
                    locations=locations)
                paths_to_messages[path].add(message)
                message_ids_to_messages[message.id] = message

        def _handle_field(path, item, key, node):
            if (not key
                    or not isinstance(item, basestring)
                    or not isinstance(key, basestring)
                    or not key.endswith('@')):
                return
            # Support gettext "extracted comments" on tagged fields. This is
            # consistent with extracted comments in templates, which follow
            # the format "{#: Extracted comment. #}". An example:
            #   field@: Message.
            #   field@#: Extracted comment for field@.
            auto_comments = []
            if isinstance(node, dict):
                auto_comment = node.get('{}#'.format(key))
                if auto_comment:
                    auto_comments.append(auto_comment)
            locations = [(path, 0)]
            _add_existing_message(
                msgid=item,
                auto_comments=auto_comments,
                locations=locations,
                path=path)

        for collection in self.pod.list_collections():
            text = 'Extracting collection: {}'.format(collection.pod_path)
            self.pod.logger.info(text)
            # Extract from blueprint.
            utils.walk(collection.tagged_fields, lambda *args: callback(collection, *args))
            # Extract from docs in collection.
            for doc in collection.docs(include_hidden=True):
                if not self._should_extract_as_babel(paths, doc.pod_path):
                    continue
                tagged_fields = doc.get_tagged_fields()
                utils.walk(tagged_fields, lambda *args: callback(doc, *args))
                paths_to_locales[doc.pod_path].update(doc.locales)
                all_locales.update(doc.locales)

        # Extract from podspec.
        config = self.pod.get_podspec().get_config()
        podspec_path = '/podspec.yaml'
        if self._should_extract_as_babel(paths, podspec_path):
            self.pod.logger.info('Extracting podspec: {}'.format(podspec_path))
            utils.walk(config, lambda *args: _handle_field(podspec_path, *args))

        # Extract from content and views.
        pod_files = [os.path.join('/views', path)
                     for path in self.pod.list_dir('/views/')]
        pod_files += [os.path.join('/content', path)
                      for path in self.pod.list_dir('/content/')]
        pod_files += [os.path.join('/data', path)
                      for path in self.pod.list_dir('/data/')]
        for pod_path in pod_files:
            if self._should_extract_as_csv(paths, pod_path):
                rows = utils.get_rows_from_csv(self.pod, pod_path)
                self.pod.logger.info('Extracting: {}'.format(pod_path))
                for row in rows:
                    for i, parts in enumerate(row.iteritems()):
                        key, val = parts
                        if key.endswith('@'):
                            locations = [(pod_path, i)]
                            _add_existing_message(
                                msgid=val,
                                locations=locations,
                                path=pod_path)
            elif self._should_extract_as_babel(paths, pod_path):
                if pod_path.startswith('/data') and pod_path.endswith(('.yaml', '.yml')):
                    self.pod.logger.info('Extracting: {}'.format(pod_path))
                    content = self.pod.read_file(pod_path)
                    fields = utils.load_yaml(content, pod=self.pod)
                    utils.walk(fields, lambda *args: _handle_field(pod_path, *args))
                    continue

                pod_locales = paths_to_locales.get(pod_path)
                if pod_locales:
                    text = 'Extracting: {} ({} locales)'
                    text = text.format(pod_path, len(pod_locales))
                    self.pod.logger.info(text)
                else:
                    self.pod.logger.info('Extracting: {}'.format(pod_path))
                fp = self.pod.open_file(pod_path)
                try:
                    all_parts = extract.extract(
                        'jinja2.ext.babel_extract', fp, options=options,
                        comment_tags=comment_tags)
                    for parts in all_parts:
                        lineno, string, comments, context = parts
                        locations = [(pod_path, lineno)]
                        _add_existing_message(
                            msgid=string,
                            auto_comments=comments,
                            context=context,
                            locations=locations,
                            path=pod_path)
                except tokenize.TokenError:
                    self.pod.logger.error('Problem extracting: {}'.format(pod_path))
                    raise

        # Localized message catalogs.
        if localized:
            for locale in all_locales:
                if locales and locale not in locales:
                    continue
                localized_catalog = self.get(locale)
                if not include_obsolete:
                    localized_catalog.obsolete = babel_util.odict()
                    for message in list(localized_catalog):
                        if message.id not in message_ids_to_messages:
                            localized_catalog.delete(message.id, context=message.context)

                catalog_to_merge = catalog.Catalog()
                for path, message_items in paths_to_messages.iteritems():
                    locales_with_this_path = paths_to_locales.get(path)
                    if locales_with_this_path and locale not in locales_with_this_path:
                        continue
                    for message in message_items:
                        translation = None
                        existing_message = localized_catalog.get(message.id)
                        if existing_message:
                            translation = existing_message.string
                        catalog_to_merge.add(
                            message.id, translation, locations=message.locations,
                            auto_comments=message.auto_comments, flags=message.flags,
                            user_comments=message.user_comments, context=message.context,
                            lineno=message.lineno, previous_id=message.previous_id)

                localized_catalog.update_using_catalog(
                    catalog_to_merge, use_fuzzy_matching=use_fuzzy_matching)
                localized_catalog.save(include_header=include_header)
                missing = localized_catalog.list_untranslated()
                num_messages = len(localized_catalog)
                num_translated = num_messages - len(missing)
                text = 'Saved: /{path} ({num_translated}/{num_messages})'
                self.pod.logger.info(
                    text.format(path=localized_catalog.pod_path,
                                num_translated=num_translated,
                                num_messages=num_messages))
            return

        # Global (or missing, specified by -o) message catalog.
        template_path = self.template_path
        catalog_obj, _ = self._get_or_create_catalog(template_path)
        if not include_obsolete:
            catalog_obj.obsolete = babel_util.odict()
            for message in list(catalog_obj):
                catalog_obj.delete(message.id, context=message.context)
        for message in message_ids_to_messages.itervalues():
            if message.id:
                catalog_obj.add(message.id, None, locations=message.locations,
                                auto_comments=message.auto_comments)
        return self.write_template(
            template_path, catalog_obj, include_obsolete=include_obsolete,
            include_header=include_header)