diff --git a/potodo/_cache.py b/potodo/_cache.py index 97fe66a..5e12f5a 100644 --- a/potodo/_cache.py +++ b/potodo/_cache.py @@ -1,10 +1,9 @@ import os import pickle -from datetime import datetime -from datetime import timedelta -from typing import Optional from typing import Mapping +from typing import Optional from typing import Sequence + from potodo._po_file import PoFileStats @@ -17,15 +16,7 @@ def _get_cache_file_content( except FileNotFoundError: return None else: - content: Optional[Mapping[str, Sequence[PoFileStats]]] = data["data"] - dt_expiry = data["dt_expiry"] - if content: - if dt_expiry < datetime.utcnow(): - return None - else: - return content - else: - return None + return data def _set_cache_content( @@ -33,7 +24,5 @@ def _set_cache_content( ) -> None: os.makedirs(os.path.dirname(path), exist_ok=True) - to_dump = {"dt_expiry": datetime.utcnow() + timedelta(weeks=1), "data": obj} - with open(path, "wb") as handle: - pickle.dump(to_dump, handle) + pickle.dump(obj, handle) diff --git a/potodo/_po_file.py b/potodo/_po_file.py index e2950c5..3462b72 100644 --- a/potodo/_po_file.py +++ b/potodo/_po_file.py @@ -1,4 +1,5 @@ import itertools +import os from pathlib import Path from typing import Dict from typing import Iterable @@ -61,10 +62,15 @@ def is_within(file: Path, excluded: Path) -> bool: return excluded in file.parents or file == excluded -def get_po_stats_from_repo( - repo_path: Path, exclude: Iterable[Path] +from potodo._cache import _get_cache_file_content # noqa +from potodo._cache import _set_cache_content # noqa + + +def get_po_stats_from_repo_or_cache( + repo_path: Path, exclude: Iterable[Path], no_cache: bool = False ) -> Mapping[str, Sequence[PoFileStats]]: - """Gets all the po files recursively from 'repo_path', excluding those in + """Gets all the po files recursively from 'repo_path' + and cache if no_cache is set to False, excluding those in 'exclude'. Return a dict with all directories and PoFile instances of `.po` files in those directories. """ @@ -88,10 +94,39 @@ def get_po_stats_from_repo( ) } - # Turn paths into stat objects - po_stats_per_directory: Dict[str, Sequence[PoFileStats]] = { - directory: [PoFileStats(po_file) for po_file in po_files] - for directory, po_files in po_files_per_directory.items() - } + if no_cache: + # Turn paths into stat objects + po_stats_per_directory: Dict[str, Sequence[PoFileStats]] = { + directory: [PoFileStats(po_file) for po_file in po_files] + for directory, po_files in po_files_per_directory.items() + } + else: + cached_files = _get_cache_file_content( + str(repo_path.resolve()) + "/.potodo/cache.pickle" + ) + if not cached_files: + cached_files = {} + po_stats_per_directory = dict() + for directory, po_files in po_files_per_directory.items(): + po_stats_per_directory[directory] = [] + for po_file in po_files: + cached_pofile = cached_files.get(po_file.resolve()) + if ( + cached_pofile + and os.path.getmtime(po_file.resolve()) == cached_pofile["mtime"] + ): + po_stats_per_directory[directory].append( + cached_files[po_file.resolve()]["pofile"] + ) + else: + po_object = PoFileStats(po_file) + cached_files[po_file.resolve()] = { + "pofile": po_object, + "mtime": os.path.getmtime(po_file), + } + po_stats_per_directory[directory].append(po_object) + _set_cache_content( + cached_files, path=str(repo_path.resolve()) + "/.potodo/cache.pickle" + ) return po_stats_per_directory diff --git a/potodo/potodo.py b/potodo/potodo.py index ac731b8..8e3e4cd 100644 --- a/potodo/potodo.py +++ b/potodo/potodo.py @@ -13,10 +13,8 @@ from typing import Sequence from typing import Tuple from potodo import __version__ -from potodo._cache import _get_cache_file_content -from potodo._cache import _set_cache_content from potodo._github import get_reservation_list -from potodo._po_file import get_po_stats_from_repo +from potodo._po_file import get_po_stats_from_repo_or_cache from potodo._po_file import PoFileStats # TODO: Sort the functions (maybe in different files ? @@ -127,17 +125,7 @@ def exec_potodo( # Initialize the arguments issue_reservations = get_issue_reservations(offline, hide_reserved, path) - if ( - no_cache - or check_output(["git", "status", "--porcelain"], encoding="utf-8") != "" - ): - po_files_and_dirs = None - else: - po_files_and_dirs = _get_cache_file_content() - - if not po_files_and_dirs: - po_files_and_dirs = get_po_stats_from_repo(path, exclude) - _set_cache_content(po_files_and_dirs) + po_files_and_dirs = get_po_stats_from_repo_or_cache(path, exclude, no_cache) dir_stats: List[Any] = [] for directory_name, po_files in sorted(po_files_and_dirs.items()): @@ -284,15 +272,11 @@ def buffer_add( def main() -> None: parser = argparse.ArgumentParser( - prog="potodo", - description="List and prettify the po files left to translate.", + prog="potodo", description="List and prettify the po files left to translate.", ) parser.add_argument( - "-p", - "--path", - help="execute Potodo in path", - metavar="path", + "-p", "--path", help="execute Potodo in path", metavar="path", ) parser.add_argument(