diff --git a/README.md b/README.md new file mode 100644 index 0000000..09c0c03 --- /dev/null +++ b/README.md @@ -0,0 +1,67 @@ +# weekly-activity + +Aggregate weekly activity across development platforms (Launchpad, GitHub) into a single text report. + +## Usage + +```bash +# Launchpad (uses system keyring for OAuth; --anonymous for public data only) +uv run weekly-activity launchpad +uv run weekly-activity launchpad --anonymous + +# GitHub (uses GITHUB_TOKEN env var or `gh auth token`; anonymous works but rate-limited) +uv run weekly-activity github +uv run weekly-activity github --token ghp_xxx + +# Custom date range (ISO dates, UTC) +uv run weekly-activity launchpad --since 2025-08-01 --until 2025-08-15 +uv run weekly-activity github --since 2025-08-01 --until 2025-08-15 +``` + +## What it reports + +| Section | Launchpad | GitHub | +|---|---|---| +| Merge proposals / PRs authored | `getMergeProposals` (created in range) | `/search/issues` (`author:` + `type:pr`) | +| Review requests received | `getRequestedReviews` (filtered by `date_review_requested`) | `/search/issues` (`reviewed-by:` + `type:pr`) | +| Reviews performed | `getRequestedReviews` (filtered by `date_reviewed`) | (same query) | +| Issues / Bugs | `searchTasks` (reporter, commenter, assignee) | `/search/issues` (author, commenter, assignee) | +| Repositories modified | `git_repositories.getRepositories` (`modified_since_date`) | `/users/{user}/repos` (filtered by `pushed_at`) | +| Commits pushed | — (not in Launchpad REST API) | `/repos/{owner}/{repo}/commits` (per active repo) | + +### Default time window + +Rolling 7 days ending today (inclusive). Override with `--since` / `--until` (ISO dates, UTC). + +## Architecture + +``` +src/weekly_activity/ + model.py ActivityReport, Section, last_week_window + report.py format_report() — source-agnostic text renderer + cli.py subcommand dispatch (launchpad | github) + sources/ + __init__.py ActivitySource protocol + launchpad.py LaunchpadSource (launchpadlib) + github.py GitHubSource (httpx) +``` + +Each source implements `ActivitySource` — a `name` and a `collect(username, since, until) -> ActivityReport` method. Sources keep their own dataclasses internally; the shared contract is `Section` (title + pre-formatted lines) and `ActivityReport` (metadata + sections + warnings). The report formatter (`report.py`) is source-agnostic. + +Per-query failures (rate limits, server timeouts) are caught per-section — a failing endpoint records a warning and degrades to an empty section rather than killing the whole report. + +## Development + +```bash +uv sync # install deps + dev tooling +uv run ruff format src # format +uv run ruff check src # lint +uv run ty check # type check +``` + +## Dependencies + +- **launchpadlib** — Launchpad REST API client +- **httpx** — GitHub REST API client +- **ruff** — format + lint (dev) +- **ty** — type check (dev)