# hadanice/fudan_icourse_subscriber architecture

> Architecture diagram of the GitHub repository hadanice/fudan_icourse_subscriber, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/hadanice/fudan_icourse_subscriber
- Repository: https://github.com/hadanice/fudan_icourse_subscriber

## Overview

iCourse Subscriber monitors selected Fudan courses, processes new lecture recordings into transcripts, PPT-derived context, and AI summaries, then emails a batch of notes. The backend authenticates through WebVPN, enumerates lectures, and uses a per-lecture runner alongside a scheduler for audio and image work. A separate browser viewer decrypts and browses the sharded database, supports catalog search and subscription editing, and can trigger PDF export. The README documents persistence, export, and provider capabilities beyond the sampled excerpts; those links are shown only where their ownership is clear.

Main entry points: [`src/pipeline/lecture_runner.py`](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/pipeline/lecture_runner.py) (Lecture runner), [`main.py`](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/main.py) (Run orchestrator), [`src/pipeline/ppt_pipeline.py`](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/pipeline/ppt_pipeline.py) (PPT pipeline), [`src/data/sharder.py`](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/data/sharder.py) (Database shards)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_monitor["Monitoring"]
  node_main["Run orchestrator<br/>[main.py]"]
  node_vpn["WebVPN login<br/>[webvpn.py]"]
  node_icourse["iCourse client<br/>[icourse.py]"]
end

subgraph group_processing["Lecture processing"]
  node_runner["Lecture runner<br/>[lecture_runner.py]"]
  node_scheduler["Work scheduler<br/>[scheduler.py]"]
  node_ppt["PPT pipeline<br/>[ppt_pipeline.py]"]
  node_ocr["PPT OCR<br/>[ocr.py]"]
  node_bucketer["PPT bucketing<br/>[bucketer.py]"]
  node_transcriber["Speech transcription<br/>[transcriber.py]"]
  node_summarizer["AI summarizer<br/>[summarizer.py]"]
end

subgraph group_storage["Encrypted data"]
  node_database[("Lecture database<br/>[database.py]")]
  node_crypto["Database encryption<br/>[crypto_box.py]"]
  node_sharder["Database shards<br/>[sharder.py]"]
end

subgraph group_viewer["Browser viewer"]
  node_frontend["Viewer application<br/>[app.js]"]
  node_browserdb["Browser SQL<br/>[db.js]"]
  node_browsercrypto["Browser decryption<br/>[crypto.js]"]
  node_browsergithub["GitHub client<br/>[github.js]"]
  node_render["Content renderer<br/>[render.js]"]
end

subgraph group_delivery["Notes delivery"]
  node_emailer["Email sender<br/>[emailer.py]"]
end

node_student(("Subscriber"))
node_platform["iCourse platform"]
node_llms["LLM providers"]
node_github["GitHub services"]
node_mail["SMTP service"]
node_reader(("Note recipient"))

node_student -->|"configures and triggers"| node_main
node_main -->|"authenticates via"| node_vpn
node_vpn -->|"logs in through"| node_platform
node_main -->|"enumerates courses"| node_icourse
node_icourse -->|"requests course data"| node_platform
node_main -->|"processes lectures with"| node_runner
node_runner -->|"fetches lecture media"| node_icourse
node_runner -->|"schedules downloads"| node_scheduler
node_runner -->|"submits PPT work"| node_ppt
node_ppt -->|"fetches PPT images"| node_icourse
node_ppt -->|"uses worker pools"| node_scheduler
node_ppt -->|"submits pages for OCR"| node_ocr
node_ppt -->|"records page state"| node_database
node_runner -->|"transcribes audio"| node_transcriber
node_runner -->|"generates lecture notes"| node_summarizer
node_runner -->|"uses PPT context"| node_bucketer
node_summarizer -.->|"requests summaries"| node_llms
node_runner -->|"reads and saves results"| node_database
node_main -->|"sends summary batch"| node_emailer
node_emailer -->|"delivers email"| node_mail
node_mail -->|"delivers notes"| node_reader
node_main -->|"prepares persisted shards"| node_sharder
node_sharder -->|"reads database"| node_database
node_sharder -->|"encrypts shards"| node_crypto
node_sharder -->|"persists shard data"| node_github
node_student -->|"opens and configures"| node_frontend
node_frontend -->|"loads shards and triggers export"| node_browsergithub
node_browsergithub -->|"fetches blobs and dispatches"| node_github
node_frontend -->|"decrypts downloaded data"| node_browsercrypto
node_frontend -->|"loads and queries data"| node_browserdb
node_browserdb -->|"provides view data"| node_render
node_render -->|"displays notes"| node_reader

click node_main "https://github.com/hadanice/fudan_icourse_subscriber/blob/main/main.py"
click node_vpn "https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/api/webvpn.py"
click node_icourse "https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/api/icourse.py"
click node_runner "https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/pipeline/lecture_runner.py"
click node_scheduler "https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/runtime/scheduler.py"
click node_ppt "https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/pipeline/ppt_pipeline.py"
click node_ocr "https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/ai/ocr.py"
click node_bucketer "https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/ai/bucketer.py"
click node_transcriber "https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/ai/transcriber.py"
click node_summarizer "https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/ai/summarizer.py"
click node_database "https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/data/database.py"
click node_crypto "https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/data/crypto_box.py"
click node_sharder "https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/data/sharder.py"
click node_frontend "https://github.com/hadanice/fudan_icourse_subscriber/blob/main/frontend/js/app.js"
click node_browserdb "https://github.com/hadanice/fudan_icourse_subscriber/blob/main/frontend/js/db.js"
click node_browsercrypto "https://github.com/hadanice/fudan_icourse_subscriber/blob/main/frontend/js/crypto.js"
click node_browsergithub "https://github.com/hadanice/fudan_icourse_subscriber/blob/main/frontend/js/github.js"
click node_render "https://github.com/hadanice/fudan_icourse_subscriber/blob/main/frontend/js/render.js"
click node_emailer "https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/api/emailer.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_main,node_vpn,node_icourse toneBlue
class node_runner,node_scheduler,node_ppt,node_ocr,node_bucketer,node_transcriber,node_summarizer toneAmber
class node_database,node_crypto,node_sharder toneMint
class node_frontend,node_browserdb,node_browsercrypto,node_browsergithub,node_render toneRose
class node_emailer,node_student,node_platform,node_llms,node_github,node_mail,node_reader toneIndigo
```

## Components

### Monitoring

- [Run orchestrator](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/main.py): `main.py`
- [WebVPN login](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/api/webvpn.py): `src/api/webvpn.py`
- [iCourse client](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/api/icourse.py): `src/api/icourse.py`

### Lecture processing

- [Lecture runner](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/pipeline/lecture_runner.py): `src/pipeline/lecture_runner.py`
- [Work scheduler](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/runtime/scheduler.py): `src/runtime/scheduler.py`
- [PPT pipeline](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/pipeline/ppt_pipeline.py): `src/pipeline/ppt_pipeline.py`
- [PPT OCR](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/ai/ocr.py): `src/ai/ocr.py`
- [PPT bucketing](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/ai/bucketer.py): `src/ai/bucketer.py`
- [Speech transcription](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/ai/transcriber.py): `src/ai/transcriber.py`
- [AI summarizer](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/ai/summarizer.py): `src/ai/summarizer.py`

### Encrypted data

- [Lecture database](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/data/database.py): `src/data/database.py`
- [Database encryption](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/data/crypto_box.py): `src/data/crypto_box.py`
- [Database shards](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/data/sharder.py): `src/data/sharder.py`

### Browser viewer

- [Viewer application](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/frontend/js/app.js): `frontend/js/app.js`
- [Browser SQL](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/frontend/js/db.js): `frontend/js/db.js`
- [Browser decryption](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/frontend/js/crypto.js): `frontend/js/crypto.js`
- [GitHub client](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/frontend/js/github.js): `frontend/js/github.js`
- [Content renderer](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/frontend/js/render.js): `frontend/js/render.js`

### Notes delivery

- [Email sender](https://github.com/hadanice/fudan_icourse_subscriber/blob/main/src/api/emailer.py): `src/api/emailer.py`

### Other components

- **Subscriber**
- **iCourse platform**
- **LLM providers**
- **GitHub services**
- **SMTP service**
- **Note recipient**

## Connections

- Subscriber → Run orchestrator: configures and triggers
- Run orchestrator → WebVPN login: authenticates via
- WebVPN login → iCourse platform: logs in through
- Run orchestrator → iCourse client: enumerates courses
- iCourse client → iCourse platform: requests course data
- Run orchestrator → Lecture runner: processes lectures with
- Lecture runner → iCourse client: fetches lecture media
- Lecture runner → Work scheduler: schedules downloads
- Lecture runner → PPT pipeline: submits PPT work
- PPT pipeline → iCourse client: fetches PPT images
- PPT pipeline → Work scheduler: uses worker pools
- PPT pipeline → PPT OCR: submits pages for OCR
- PPT pipeline → Lecture database: records page state
- Lecture runner → Speech transcription: transcribes audio
- Lecture runner → AI summarizer: generates lecture notes
- Lecture runner → PPT bucketing: uses PPT context
- AI summarizer → LLM providers: requests summaries
- Lecture runner → Lecture database: reads and saves results
- Run orchestrator → Email sender: sends summary batch
- Email sender → SMTP service: delivers email
- SMTP service → Note recipient: delivers notes
- Run orchestrator → Database shards: prepares persisted shards
- Database shards → Lecture database: reads database
- Database shards → Database encryption: encrypts shards
- Database shards → GitHub services: persists shard data
- Subscriber → Viewer application: opens and configures
- Viewer application → GitHub client: loads shards and triggers export
- GitHub client → GitHub services: fetches blobs and dispatches
- Viewer application → Browser decryption: decrypts downloaded data
- Viewer application → Browser SQL: loads and queries data
- Browser SQL → Content renderer: provides view data
- Content renderer → Note recipient: displays notes
