krz/hutch-stats

Server-side utility for calculating contributions for sourcehut users. contributions server sourcehut stats

Commit e59328fc7a

e59328fc7aad5869b2c3f0fc23dd1d8f39dad15c

parent: 0b70db10e2

Unsigned

cmc <hello@cleberg.net> · 2026-08-31 22:39 UTC

Convert README.nfo to README.org (!1)

Section headings become org headings, indented command blocks become
src blocks, and column-aligned content stays in example blocks.

Layout: unified · split

README.nfo deleted −86
@@ -1,86 +0,0 @@
1┌──────────────────────────────────────────────────────────────┐
2│ H U T C H - S T A T S [ KRZ ] krz.sh │
3└──────────────────────────────────────────────────────────────┘
4
5WHAT
6 srht-contrib. python service. polls sourcehut activity, normalizes
7 it into one event model, stores it in sqlite, and serves a
8 contribution-calendar json api an ios app renders directly.
9
10 v1 scope:
11 - fastapi json api
12 - sqlite persistence
13 - polling ingestion
14 - full todo.sr.ht path
15 - git.sr.ht commit ingestion with repo auto-discovery
16 - public read-only endpoints, api-key auth for mutating routes
17 - alembic migrations
18
19DOES
20 collects activity from sr.ht graphql services, aggregates by day,
21 and returns zero-filled ranges so the client never patches missing
22 dates. polls incrementally, backfills the last 365 days for new
23 actors, prunes older activity.
24
25SERVICES
26 implemented: todo.sr.ht, git.sr.ht.
27 event types: ticket_created, ticket_comment, ticket_closed, commit.
28
29ENV
30 API_KEY=replace-me
31 ENABLE_SCHEDULER=false
32 SRHT_TOKEN=replace-me
33 TODO_SRHT_ENDPOINT=https://todo.sr.ht/query
34 GIT_SRHT_ENDPOINT=https://git.sr.ht/query
35 DATABASE_URL=sqlite:///./srht_contrib.db
36 DEFAULT_ACTOR=~your-user
37 POLL_INTERVAL_SECONDS=300
38
39 more knobs (discovery batch size, repoll and backoff intervals,
40 actor aliases, tracked repositories) live in config.py.
41
42RUN
43 uv venv
44 source .venv/bin/activate
45 uv pip install -e ".[dev]"
46 cp .env.example .env
47 alembic upgrade head
48 uvicorn srht_contrib.main:app --reload
49
50POLL
51 manual poll:
52
53 curl -X POST \
54 "http://127.0.0.1:8000/api/contributions/poll?actor=~your-user" \
55 -H "X-API-Key: replace-me"
56
57 scheduled polling runs only when ENABLE_SCHEDULER=true. it drains
58 due actors in batches, indexes fast, then backfills a year in
59 bounded passes.
60
61 bulk queue without immediate indexing:
62
63 srht-enqueue-actors srht_usernames.txt --stagger-seconds 60
64
65ENDPOINTS
66 calendar by year, calendar by date range, stats, and repository
67 crud. full request and response shapes are in API.txt.
68
69WEIGHTS
70 commit 1.0, ticket_created 1.0, ticket_comment 0.5,
71 ticket_closed 0.75, build_started 0.25, build_passed 0.25.
72
73TESTS
74 pytest
75
76LIMITS
77 - git polling assumes repos are discoverable via graphql
78 - the scheduler runs in-process, not distributed
79 - new actors index asynchronously; the first read may be empty
80 - rolling one-year window; older activity is not kept
81 - alias management is config-driven, no crud api yet
82 - trusted-operator v1, not a public multi-tenant service
83
84┌──────────────────────────────────────────────────────────────┐
85│ krz.sh │
86└──────────────────────────────────────────────────────────────┘
README.org added +90
@@ -0,0 +1,90 @@
1#+title: hutch-stats
2
3* what
4srht-contrib. python service. polls sourcehut activity, normalizes
5it into one event model, stores it in sqlite, and serves a
6contribution-calendar json api an ios app renders directly.
7
8v1 scope:
9- fastapi json api
10- sqlite persistence
11- polling ingestion
12- full todo.sr.ht path
13- git.sr.ht commit ingestion with repo auto-discovery
14- public read-only endpoints, api-key auth for mutating routes
15- alembic migrations
16
17* does
18collects activity from sr.ht graphql services, aggregates by day,
19and returns zero-filled ranges so the client never patches missing
20dates. polls incrementally, backfills the last 365 days for new
21actors, prunes older activity.
22
23* services
24implemented: todo.sr.ht, git.sr.ht.
25event types: ticket_created, ticket_comment, ticket_closed, commit.
26
27* env
28#+begin_src conf
29API_KEY=replace-me
30ENABLE_SCHEDULER=false
31SRHT_TOKEN=replace-me
32TODO_SRHT_ENDPOINT=https://todo.sr.ht/query
33GIT_SRHT_ENDPOINT=https://git.sr.ht/query
34DATABASE_URL=sqlite:///./srht_contrib.db
35DEFAULT_ACTOR=~your-user
36POLL_INTERVAL_SECONDS=300
37#+end_src
38
39more knobs (discovery batch size, repoll and backoff intervals,
40actor aliases, tracked repositories) live in config.py.
41
42* run
43#+begin_src sh
44uv venv
45source .venv/bin/activate
46uv pip install -e ".[dev]"
47cp .env.example .env
48alembic upgrade head
49uvicorn srht_contrib.main:app --reload
50#+end_src
51
52* poll
53manual poll:
54
55#+begin_src sh
56curl -X POST \
57 "http://127.0.0.1:8000/api/contributions/poll?actor=~your-user" \
58 -H "X-API-Key: replace-me"
59#+end_src
60
61scheduled polling runs only when ENABLE_SCHEDULER=true. it drains
62due actors in batches, indexes fast, then backfills a year in
63bounded passes.
64
65bulk queue without immediate indexing:
66
67#+begin_src sh
68srht-enqueue-actors srht_usernames.txt --stagger-seconds 60
69#+end_src
70
71* endpoints
72calendar by year, calendar by date range, stats, and repository
73crud. full request and response shapes are in API.txt.
74
75* weights
76commit 1.0, ticket_created 1.0, ticket_comment 0.5,
77ticket_closed 0.75, build_started 0.25, build_passed 0.25.
78
79* tests
80#+begin_src sh
81pytest
82#+end_src
83
84* limits
85- git polling assumes repos are discoverable via graphql
86- the scheduler runs in-process, not distributed
87- new actors index asynchronously; the first read may be empty
88- rolling one-year window; older activity is not kept
89- alias management is config-driven, no crud api yet
90- trusted-operator v1, not a public multi-tenant service