import datetime import logging from collections.abc import Iterator from pathlib import Path import git from personal_data.activity import HIDDEN_LABEL_CATEGORY, ActivitySample, Label logger = logging.getLogger(__name__) def determine_default_branch(repo: git.Repo): try: repo.commit('main') return 'main' except: return 'master' def determine_project_name(repo: git.Repo) -> str: remotes = repo.remotes if len(remotes) > 0: return remotes.origin.url.removeprefix('git@gitfub.space:') return Path(repo.working_tree_dir).name def get_samples_from_project(repo: git.Repo) -> Iterator[ActivitySample]: project_name = determine_project_name(repo) assert project_name is not None # TODO: Branch on main or master or default repo.commit() for commit in repo.iter_commits(determine_default_branch(repo)): labels = [Label(HIDDEN_LABEL_CATEGORY, 'total')] labels.append(Label('project', project_name)) labels.append(Label('author', commit.author.email)) authored_date = datetime.datetime.fromtimestamp( commit.authored_date, tz=datetime.UTC, ) committed_date = datetime.datetime.fromtimestamp( commit.committed_date, tz=datetime.UTC, ) yield ActivitySample( labels=tuple(labels), start_at=None, end_at=authored_date, ) if authored_date != committed_date: yield ActivitySample( labels=tuple(labels), start_at=None, end_at=committed_date, ) del labels def iterate_samples_from_git_repository(repo_path: Path) -> Iterator[ActivitySample]: try: yield from get_samples_from_project(git.Repo(repo_path)) except git.exc.InvalidGitRepositoryError: logger.warning('Ignoring non-repo %s', repo_path)