Skip to content
This repository has been archived by the owner on Dec 2, 2024. It is now read-only.

Commit

Permalink
Pushing source files with no matching resource now creates the corres…
Browse files Browse the repository at this point in the history
…ponding resource first.
  • Loading branch information
why-not-try-calmer committed Feb 15, 2023
1 parent 634f59f commit 99ed7d0
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test_pytx.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Test Pytx
name: test pytransifex

on:
pull_request:
Expand Down
41 changes: 34 additions & 7 deletions pytransifex/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ def update_source_translation(
"Unable to fetch resource for this organization; define an 'organization slug' first."
)

logging.info(
f"Updating source translation for resource {resource_slug} from file {path_to_file} (project: {project_slug})."
)

if project := self.get_project(project_slug=project_slug):
if resources := project.fetch("resources"):
if resource := resources.get(slug=resource_slug):
Expand Down Expand Up @@ -267,36 +271,59 @@ def pull(
language_codes: list[str],
output_dir: Path,
):
"""Pull resources from project."""
args = []
for l_code in language_codes:
for slug in resource_slugs:
args.append(tuple([project_slug, slug, l_code, output_dir]))
logging.info("ARGS", args)
concurrently(

res = concurrently(
fn=self.get_translation,
args=args,
)

logging.info(f"Pulled {args} for {len(res)} results).")

@ensure_login
def push(
self, project_slug: str, resource_slugs: list[str], path_to_files: list[Path]
):
"""Push resources with files under project."""
if len(resource_slugs) != len(path_to_files):
raise Exception(
raise ValueError(
f"Resources slugs ({len(resource_slugs)}) and Path to files ({len(path_to_files)}) must be equal in size!"
)

resource_zipped_with_path = list(zip(resource_slugs, path_to_files))
resources = self.list_resources(project_slug)
logging.info(
f"Found {len(resources)} resource(s) for {project_slug}. Checking for missing resources and creating where necessary."
)
created_when_missing_resource = []

for slug, path in resource_zipped_with_path:
logging.info(f"Slug: {slug}. Resources: {resources}.")
if not slug in resources:
logging.info(
f"{project_slug} is missing {slug}. Created it from {path}."
)
self.create_resource(
project_slug=project_slug, path_to_file=path, resource_slug=slug
)
created_when_missing_resource.append(slug)

args = [
tuple([project_slug, res, path])
for res, path in zip(resource_slugs, path_to_files)
tuple([project_slug, slug, path])
for slug, path in resource_zipped_with_path
if not slug in created_when_missing_resource
]

concurrently(
res = concurrently(
fn=self.update_source_translation,
args=args,
)

logging.info(f"Pushes some {len(resource_slugs)} files!")
logging.info(f"Pushed {args} for {len(res)} results.")


class Transifex:
Expand Down
20 changes: 13 additions & 7 deletions pytransifex/cli.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import logging
import traceback
from os import mkdir, rmdir
from pathlib import Path

Expand All @@ -19,7 +21,7 @@ def extract_files(input_dir: Path) -> tuple[list[Path], list[str], str]:
files = list(Path.iterdir(input_dir))
slugs = path_to_slug(files)
files_status_report = "\n".join(
(f"file:{file} => slug:{slug}" for slug, file in zip(slugs, files))
(f"file: {file} => slug: {slug}" for slug, file in zip(slugs, files))
)
return (files, slugs, files_status_report)

Expand Down Expand Up @@ -54,7 +56,9 @@ def init(**opts):
reply += f"WARNING: You will need to declare an input directory if you plan on using 'pytx push', as in 'pytx push --input-directory <PATH/TO/DIRECTORY>'."

except Exception as error:
reply += f"Failed to initialize the CLI, this error occurred: {error} "
reply += (
f"cli:init > Failed to initialize the CLI, this error occurred: {error}."
)

if has_to_create_dir:
rmdir(settings.output_directory)
Expand All @@ -78,22 +82,23 @@ def push(input_directory: str | None):
)

if not input_dir:
raise Exception(
"To use this 'push', you need to initialize the project with a valid path to the directory containing the files to push; alternatively, you can call this commend with 'pytx push --input-directory <PATH/TO/DIRECTORY>'."
raise FileExistsError(
"cli:push > To use this 'push', you need to initialize the project with a valid path to the directory containing the files to push; alternatively, you can call this commend with 'pytx push --input-directory <PATH/TO/DIRECTORY>'."
)

try:
files, slugs, files_status_report = extract_files(input_dir)
click.echo(
f"Pushing {files_status_report} to Transifex under project {settings.project_slug}..."
f"cli:push > Pushing {files_status_report} to Transifex under project {settings.project_slug}."
)
client.push(
project_slug=settings.project_slug,
resource_slugs=slugs,
path_to_files=files,
)
except Exception as error:
reply += f"cli:push failed because of this error: {error}"
reply += f"cli:push > Failed because of this error: {error}"
logging.error(f"traceback: {traceback.print_exc()}")
finally:
click.echo(reply)
settings.to_disk()
Expand Down Expand Up @@ -125,7 +130,8 @@ def pull(output_directory: str | Path | None, only_lang: str | None):
output_dir=output_directory,
)
except Exception as error:
reply += f"cli:pull failed because of this error: {error}"
reply += f"cli:pull > failed because of this error: {error}"
logging.error(f"traceback: {traceback.print_exc()}")
finally:
click.echo(reply)
settings.to_disk()
11 changes: 8 additions & 3 deletions pytransifex/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from concurrent.futures import ThreadPoolExecutor, as_completed
from functools import wraps
from typing import Any, Callable, Iterable
from typing import Any, Callable


def ensure_login(f):
Expand All @@ -16,9 +16,14 @@ def capture_args(instance, *args, **kwargs):
def concurrently(
*,
fn: Callable | None = None,
args: Iterable[Any] | None = None,
partials: Iterable[Any] | None = None,
args: list[Any] | None = None,
partials: list[Any] | None = None,
) -> list[Any]:
if args and len(args) == 0:
return []
if partials and len(partials) == 0:
return []

with ThreadPoolExecutor() as pool:
if partials:
futures = [pool.submit(p) for p in partials]
Expand Down

0 comments on commit 99ed7d0

Please sign in to comment.