Exemplo n.º 1
0
    def create_locale_directory(self, locale, path):
        if not self.db_project.has_multi_locale_repositories:
            source_directory = self.source_directory_path()
            parent_directory = os.path.abspath(os.path.join(source_directory, os.pardir))
            locale_directory = os.path.join(parent_directory, locale.code.replace('-', '_'))

            # For asymmetric formats, create empty folder
            if is_asymmetric_resource(path):
                os.makedirs(locale_directory)

            # For other formats, copy resources from source directory
            else:
                shutil.copytree(source_directory, locale_directory)

                for root, dirnames, filenames in os.walk(locale_directory):
                    for filename in filenames:
                        path = os.path.join(root, filename)
                        if is_resource(filename):
                            os.rename(path, source_to_locale_path(path))
                        else:
                            os.remove(path)

            return locale_directory

        else:
            raise MissingLocaleDirectoryError(
                'Directory for locale `{0}` not found'.format(locale.code)
            )
Exemplo n.º 2
0
    def locale_directory_paths(self):
        """
        A map of locale codes and their absolute directory paths.
        Create locale directory, if not in repository yet.
        """
        locale_directory_paths = {}
        parent_directories = set()

        for locale in self.locales:
            try:
                if self.configuration:
                    locale_directory_paths[locale.code] = self.configuration.l10n_base
                else:
                    locale_directory_paths[locale.code] = locale_directory_path(
                        self.checkout_path, locale.code, parent_directories,
                    )
                parent_directory = get_parent_directory(
                    locale_directory_paths[locale.code]
                )

            except IOError:
                if not self.db_project.has_multi_locale_repositories:
                    source_directory = self.source_directory_path
                    parent_directory = get_parent_directory(source_directory)

                    locale_code = locale.code
                    if uses_undercore_as_separator(parent_directory):
                        locale_code = locale_code.replace("-", "_")

                    locale_directory = os.path.join(parent_directory, locale_code)

                    # For asymmetric formats, create empty folder
                    if is_asymmetric_resource(next(self.relative_resource_paths())):
                        os.makedirs(locale_directory)

                    # For other formats, copy resources from source directory
                    else:
                        shutil.copytree(source_directory, locale_directory)

                        for root, dirnames, filenames in scandir.walk(locale_directory):
                            for filename in filenames:
                                path = os.path.join(root, filename)
                                if is_resource(filename):
                                    os.rename(path, source_to_locale_path(path))
                                else:
                                    os.remove(path)

                    locale_directory_paths[locale.code] = locale_directory

                else:
                    raise MissingLocaleDirectoryError(
                        "Directory for locale `{0}` not found".format(locale.code)
                    )

            parent_directories.add(parent_directory)

        return locale_directory_paths
Exemplo n.º 3
0
    def locale_directory_paths(self):
        """
        A map of locale codes and their absolute directory paths.
        Create locale directory, if not in repository yet.
        """
        locale_directory_paths = {}
        parent_directories = set()

        for locale in self.locales:
            try:
                if self.configuration:
                    locale_directory_paths[locale.code] = self.configuration.l10n_base
                else:
                    locale_directory_paths[locale.code] = locale_directory_path(
                        self.checkout_path,
                        locale.code,
                        parent_directories,
                    )
                parent_directory = get_parent_directory(locale_directory_paths[locale.code])

            except IOError:
                if not self.db_project.has_multi_locale_repositories:
                    source_directory = self.source_directory_path
                    parent_directory = get_parent_directory(source_directory)

                    locale_code = locale.code
                    if uses_undercore_as_separator(parent_directory):
                        locale_code = locale_code.replace('-', '_')

                    locale_directory = os.path.join(parent_directory, locale_code)

                    # For asymmetric formats, create empty folder
                    if is_asymmetric_resource(next(self.relative_resource_paths())):
                        os.makedirs(locale_directory)

                    # For other formats, copy resources from source directory
                    else:
                        shutil.copytree(source_directory, locale_directory)

                        for root, dirnames, filenames in scandir.walk(locale_directory):
                            for filename in filenames:
                                path = os.path.join(root, filename)
                                if is_resource(filename):
                                    os.rename(path, source_to_locale_path(path))
                                else:
                                    os.remove(path)

                    locale_directory_paths[locale.code] = locale_directory

                else:
                    raise MissingLocaleDirectoryError(
                        'Directory for locale `{0}` not found'.format(locale.code)
                    )

            parent_directories.add(parent_directory)

        return locale_directory_paths
Exemplo n.º 4
0
    def relative_resource_paths(self):
        """
        List of paths relative to the locale directories returned by
        self.source_directory_path for each resource in this project.
        """
        path = self.source_directory_path
        for absolute_path in self.resources_for_path(path):
            absolute_path = source_to_locale_path(absolute_path)

            yield os.path.relpath(absolute_path, path)
Exemplo n.º 5
0
    def relative_resource_paths(self):
        """
        List of paths relative to the locale directories returned by
        self.source_directory_path for each resource in this project.
        """
        path = self.source_directory_path
        for absolute_path in self.resources_for_path(path):
            absolute_path = source_to_locale_path(absolute_path)

            yield os.path.relpath(absolute_path, path)
Exemplo n.º 6
0
    def relative_resource_paths(self):
        """
        List of all source resource paths, relative to source_directory_path.
        """
        if self.configuration:
            paths = self.resource_paths_with_config()
        else:
            paths = self.resource_paths_without_config()

        for path in paths:
            path = source_to_locale_path(path)
            yield os.path.relpath(path, self.source_directory_path)
Exemplo n.º 7
0
    def relative_resource_paths(self):
        """
        List of all source resource paths, relative to source_directory_path.
        """
        if self.configuration:
            paths = self.resource_paths_with_config()
        else:
            paths = self.resource_paths_without_config()

        for path in paths:
            path = source_to_locale_path(path)
            yield os.path.relpath(path, self.source_directory_path)
Exemplo n.º 8
0
def get_download_content(slug, code, part):
    """
    Get content of the file to be downloaded.

    :arg str slug: Project slug.
    :arg str code: Locale code.
    :arg str part: Resource path or Subpage name.
    """
    # Avoid circular import; someday we should refactor to avoid.
    from pontoon.sync import formats
    from pontoon.sync.utils import source_to_locale_path
    from pontoon.sync.vcs.models import VCSProject
    from pontoon.base.models import Entity, Locale, Project, Resource

    project = get_object_or_404(Project, slug=slug)
    locale = get_object_or_404(Locale, code=code)
    vcs_project = VCSProject(project, locales=[locale])

    # Download a ZIP of all files if project has > 1 and < 10 resources
    resources = Resource.objects.filter(project=project,
                                        translatedresources__locale=locale)
    isZipable = 1 < len(resources) < 10
    if isZipable:
        s = io.BytesIO()
        zf = zipfile.ZipFile(s, "w")

    # Download a single file if project has 1 or >= 10 resources
    else:
        relative_path = _get_relative_path_from_part(slug, part)
        resources = [
            get_object_or_404(Resource, project__slug=slug, path=relative_path)
        ]

    locale_prefixes = project.repositories

    if not project.configuration_file:
        locale_prefixes = locale_prefixes.filter(
            permalink_prefix__contains="{locale_code}")

    locale_prefixes = locale_prefixes.values_list("permalink_prefix",
                                                  flat=True).distinct()

    source_prefixes = project.repositories.values_list("permalink_prefix",
                                                       flat=True).distinct()

    for resource in resources:
        # Get locale file
        dirnames = set([locale.code, locale.code.replace("-", "_")])
        locale_path = _download_file(locale_prefixes, dirnames, vcs_project,
                                     resource.path)
        if not locale_path and not resource.is_asymmetric:
            return None, None

        # Get source file if needed
        source_path = None
        if resource.is_asymmetric:
            dirnames = VCSProject.SOURCE_DIR_NAMES
            source_path = _download_file(source_prefixes, dirnames,
                                         vcs_project, resource.path)
            if not source_path:
                return None, None

            # If locale file doesn't exist, create it
            if not locale_path:
                extension = os.path.splitext(resource.path)[1]
                with tempfile.NamedTemporaryFile(
                        prefix="strings" if extension == ".xml" else "",
                        suffix=extension,
                        delete=False,
                ) as temp:
                    temp.flush()
                locale_path = temp.name

        # Update file from database
        resource_file = formats.parse(locale_path, source_path)
        entities_dict = {}
        entities_qs = Entity.objects.filter(
            changedentitylocale__locale=locale,
            resource__project=project,
            resource__path=resource.path,
            obsolete=False,
        )

        for e in entities_qs:
            entities_dict[e.key] = e.translation_set.filter(approved=True,
                                                            locale=locale)

        for vcs_translation in resource_file.translations:
            key = vcs_translation.key
            if key in entities_dict:
                entity = entities_dict[key]
                vcs_translation.update_from_db(entity)

        resource_file.save(locale)

        if not locale_path:
            return None, None

        if isZipable:
            zf.write(locale_path, source_to_locale_path(resource.path))
        else:
            with codecs.open(locale_path, "r", "utf-8") as f:
                content = f.read()
            filename = os.path.basename(source_to_locale_path(resource.path))

        # Remove temporary files
        os.remove(locale_path)
        if source_path:
            os.remove(source_path)

    if isZipable:
        zf.close()
        content = s.getvalue()
        filename = project.slug + ".zip"

    return content, filename