kosmosandvhaudiquet 6d8cc3d817 Add config onboarding wizard and aggregated report
- `weekly-activity config`: interactive wizard writing
  ~/.config/weekly-activity.toml (XDG-aware, --config override), one
  section per source, 0600 permissions, tokens never echoed; re-runs show
  current settings and pre-fill defaults
- `weekly-activity report` (and bare invocation): loads enabled sources,
  collects each independently, joins blocks under one header; a failing
  source renders as [skipped: <source> — error] without aborting
- config.py: typed schema, tomllib reader with strict validation,
  hand-formatted TOML writer (stdlib-only, no new dependency)
- aggregate.py: source spec building + failure-isolated collection +
  combined rendering
- README: document config/report usage and config schema
- tests/: 16 stdlib-unittest cases (config round-trip/escaping/validation,
  aggregation mapping/isolation)
2026-08-26 20:18:41 +00:00
2026-08-25 20:36:54 +02:00

weekly-activity

Aggregate weekly activity across development platforms (Launchpad, GitHub, GitLab, Debian BTS) into a single text report.

Usage

# Interactive setup: pick sources, store identities/tokens once
uv run weekly-activity config

# Aggregated report across every configured source
uv run weekly-activity report      # bare `weekly-activity` does the same

Single sources (ad-hoc, no config needed)

# Launchpad (uses system keyring for OAuth; --anonymous for public data only)
uv run weekly-activity launchpad <username>
uv run weekly-activity launchpad --anonymous <username>

# GitHub (uses GITHUB_TOKEN env var or `gh auth token`; anonymous works but rate-limited)
uv run weekly-activity github <username>
uv run weekly-activity github --token ghp_xxx <username>

# GitLab (gitlab.com by default; any self-hosted instance via --url, e.g. Debian Salsa;
# uses GITLAB_TOKEN / SALSA_TOKEN env vars, anonymous works but rate-limited)
uv run weekly-activity gitlab <username>
uv run weekly-activity gitlab --url https://salsa.debian.org <username>
uv run weekly-activity gitlab --url https://salsa.debian.org --token glpat-xxx <username>

# Debian BTS (bugs.debian.org; identify by the email used on bugs)
uv run weekly-activity bts <email>

# Custom date range (ISO dates, UTC)
uv run weekly-activity launchpad --since 2025-08-01 --until 2025-08-15 <username>
uv run weekly-activity github --since 2025-08-01 --until 2025-08-15 <username>
uv run weekly-activity gitlab --since 2025-08-01 --until 2025-08-15 <username>
uv run weekly-activity bts --since 2025-08-01 --until 2025-08-15 <email>

GitLab instances

Any GitLab instance works via --url. Token discovery order:

  1. --token flag
  2. env var named by --token-env
  3. <HOST>_TOKEN derived from the instance host (e.g. SALSA_TOKEN for salsa.debian.org)
  4. GITLAB_TOKEN

What it reports

Section Launchpad GitHub GitLab Debian BTS
Merge proposals / PRs authored getMergeProposals (created in range) /search/issues (author: + type:pr) /merge_requests (author_id, created range)
Review requests received getRequestedReviews (filtered by date_review_requested) /search/issues (reviewed-by: + type:pr)
Reviews performed getRequestedReviews (filtered by date_reviewed) (same query) events (action=approved)
Issues / Bugs searchTasks (reporter, commenter, assignee) /search/issues (author, commenter, assignee) /issues (author_id, assignee_id) get_bugs (submitter) + get_status (created in range)
Bugs owned, updated get_bugs (owner) + get_status (log_modified)
Repositories modified git_repositories.getRepositories (modified_since_date) /users/{user}/repos (filtered by pushed_at) — (covered by push events)
Commits pushed — (not in Launchpad REST API) /repos/{owner}/{repo}/commits (per active repo) events (action=pushed)

Default time window

Rolling 7 days ending today (inclusive). Override with --since / --until (ISO dates, UTC).

Configuration

weekly-activity config walks through each known source and writes a TOML file. Tokens are stored as provided (plaintext), but the file is created with owner-only permissions (0600) and secrets are never echoed back. Use --config <path> (also accepted by report) to keep configs elsewhere.

Default location: ${XDG_CONFIG_HOME:-~/.config}/weekly-activity.toml.

[github]
username = "octocat"
token = ""            # empty -> fall back to $GITHUB_TOKEN / `gh auth token`

[launchpad]
username = "jane"
mode = "credentials"  # "anonymous" (public data only) | "credentials"
credentials_file = "" # empty -> system keyring; OAuth runs at report time

[gitlab]
url = "https://salsa.debian.org"
username = "jane"
token_env = "SALSA_TOKEN"

[bts]
email = "jane@example.org"

An absent [section] disables that source. Re-running weekly-activity config shows the current settings and offers to redo the wizard with the existing values as defaults.

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 | gitlab | bts | report | config)
  aggregate.py        collect_specs()/format_combined() — one text report across sources
  config.py           ActivityConfig schema + TOML load/save (tomllib read, hand-written)
  wizard.py           interactive `config` onboarding
  sources/
    __init__.py       ActivitySource protocol
    launchpad.py      LaunchpadSource (launchpadlib)
    github.py         GitHubSource (httpx)
    gitlab.py         GitLabSource (httpx, REST v4 — gitlab.com or self-hosted)
    debian_bts.py     DebianBtsSource (python-debianbts SOAP)

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

uv sync                    # install deps + dev tooling
uv run ruff format src     # format
uv run ruff check src      # lint
uv run ty check            # type check

CI / releases

Gitea Actions (.gitea/workflows/ci.yml) runs two jobs:

  • check — format, lint, and type check on every push to main
  • release — on v* tags: builds a standalone Linux executable with PyInstaller, smoke-tests it, creates a Gitea release, and uploads the binary as an asset

Cut a release with:

git tag vX.Y.Z && git push origin vX.Y.Z

Dependencies

  • launchpadlib — Launchpad REST API client
  • httpx — GitHub & GitLab REST API client
  • python-debianbts — Debian BTS SOAP client
  • ruff — format + lint (dev)
  • ty — type check (dev)
S
Description
No description provided
Readme
258 KiB
v0.3.0
Latest
2026-08-25 18:45:27 +00:00
Languages
Python 100%