potodo/potodo/potodo.py

170 lines
5.4 KiB
Python

#!/bin/python3
import sys
import argparse
import statistics
from pathlib import Path
try:
import polib
import requests
except ImportError:
print("You need to install polib and requests to be able to run potodo.")
sys.exit(1)
def get_gh_issue_reservation(repo: str):
"""
TODO: Try except if repo unvalid
Will query given repo and get all issues and return a list of reservations
:param repo: The repository to query on the API
:return: Returns a dict containing all issues with `title:login`
"""
issues = requests.get(
"https://api.github.com/repos/" + repo + "/issues"
).json()
reservations = {
issue["title"].split()[-1].lower(): issue["user"]["login"] for issue in issues
}
return reservations
def get_po_files_from_path(path: str):
"""
TODO: Try except if path unvalid
Will get all po files from given path
:param path: The path to search `po` files for
:return: Returns a dict will the folder and the po files in it
"""
po_files = [file for file in Path(path).glob("**/*.po") if ".git/" not in str(file)]
po_files_per_directory = {
path.parent.name: set(path.parent.glob("*.po")) for path in po_files
}
return po_files_per_directory
def exec_potodo(path: str, above: int, below: int, repo: str):
"""
Will run everything based on the given parameters
:param path: The path to search into
:param above: The above threshold
:param below: The below threshold
:param repo: The repository to query for issues
"""
if not above and below:
is_all = False
is_above = False
is_below = True
elif not below and above:
is_all = False
is_above = True
is_below = False
elif not below and not above:
is_all = True
is_above = False
is_below = False
else:
raise ValueError("Unexpected error occuped when processing values for above and below.")
if repo:
issue_reservations = get_gh_issue_reservation(repo)
else:
issue_reservations = None
po_files_per_directory = get_po_files_from_path(path)
for directory, po_files in sorted(po_files_per_directory.items()):
buffer = []
folder_stats = []
printed_list = []
for po_file in sorted(po_files):
po_file_stats = polib.pofile(po_file)
po_file_stat_percent = po_file_stats.percent_translated()
if po_file_stat_percent == 100:
folder_stats.append(po_file_stat_percent)
printed_list.append(False)
continue
if not is_all:
if is_above:
if int(po_file_stat_percent) < above:
folder_stats.append(po_file_stat_percent)
printed_list.append(False)
continue
elif is_below:
if int(po_file_stat_percent) > below:
folder_stats.append(po_file_stat_percent)
printed_list.append(False)
continue
else:
raise ValueError("Unexpected error: is_above/is_below values shouldn't be like this")
t = str(po_file).split('/')[-2:]
po_file_name = t[0] + '/' + t[1]
buffer.append(
f"- {po_file.name:<30} "
+ f"{len(po_file_stats.translated_entries()):3d} / {len(po_file_stats):3d} "
+ f"({po_file_stat_percent:5.1f}% translated)"
+ (
f", {len(po_file_stats.fuzzy_entries())} fuzzy"
if po_file_stats.fuzzy_entries()
else ""
)
+ (
f", réservé par {issue_reservations[po_file_name.lower()]}"
if po_file_name.lower() in issue_reservations
else ""
)
)
folder_stats.append(po_file_stat_percent)
printed_list.append(True)
if True in printed_list:
print(f"\n\n# {directory} ({statistics.mean(folder_stats):.2f}% done)\n")
print("\n".join(buffer))
def main():
"""
TODO: Add variable to skip github issues
TODO: Remove requirement of -r and fetch the repo name manually
TODO: Add json output possibility
TODO: -l for path line by line --matching-files
TODO: classify ?
TODO: Make it so you can specify both: list todos above 50 but below 60 (between 50 and 60)
"""
parser = argparse.ArgumentParser(
prog="potodo",
description="List and prettify the po files left to translate",
)
parser.add_argument("-p", "--path", type=str,
help="REQUIRED: Execute Potodo in the given path", required=True)
parser.add_argument("-r", "--repo", type=str,
help="REQUIRED: Repo in the form of ORG/REPO to display if translation is reserved in issues", required=True)
group = parser.add_mutually_exclusive_group()
group.add_argument('-a', '--above', type=int, help="Will list all TODOs ABOVE given INT%% completion")
group.add_argument('-b', '--below', type=int, help="Will list all TODOs BELOW given INT%% completion")
args = parser.parse_args()
if not args.path:
path = '.'
else:
path = str(args.path)
exec_potodo(path, args.above, args.below, args.repo)