# markpekun/getcourse-downloader architecture

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

- Interactive diagram: https://gitdiagram.com/markpekun/getcourse-downloader
- Repository: https://github.com/markpekun/getcourse-downloader

## Overview

GetCourse Downloader is a Windows desktop app for discovering accessible courses and downloading selected lessons as organized MP4 files. The main flow is URL entry and course discovery, lesson/quality selection, then download with progress and completion feedback. The README documents Flet/CLI entry points and ports-and-adapters architecture; source excerpts and the SOURCE INDEX support several internal calls, but not every adapter wiring detail, so uncertain relationships are omitted or marked dashed.

Main entry points: [`src/getcourse_downloader/infrastructure/getcourse/downloader.py`](https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/infrastructure/getcourse/downloader.py) (GetCourse downloader), [`src/getcourse_downloader/presentation/flet/screens/courses/view.py`](https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/presentation/flet/screens/courses/view.py) (Lesson selection screen), [`src/getcourse_downloader/application/use_cases/download_lessons.py`](https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/application/use_cases/download_lessons.py) (Download lessons), [`src/getcourse_downloader/bootstrap.py`](https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/bootstrap.py) (Dependency assembly)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_presentation["User interface"]
  node_desktop["Flet desktop app<br/>[app.py]"]
  node_start["Course discovery screen"]
  node_courses["Lesson selection screen<br/>[view.py]"]
  node_cli["CLI interface"]
end

subgraph group_application["Application and domain"]
  node_discover_uc["Discover courses"]
  node_download_uc["Download lessons"]
  node_domain["Course and download models<br/>[models.py]"]
  node_events["Download events<br/>[events.py]"]
  node_bootstrap["Dependency assembly<br/>[bootstrap.py]"]
end

subgraph group_getcourse["GetCourse integration"]
  node_browser["Playwright browser and profile"]
  node_discovery_adapter["GetCourse discovery<br/>[discovery.py]"]
  node_lesson_adapter["Lesson and player extraction"]
  node_download_adapter["GetCourse downloader<br/>[downloader.py]"]
end

subgraph group_media["Media and persistence"]
  node_hls["HLS fetch and decryption<br/>[hls.py]"]
  node_ffmpeg["MP4 muxing<br/>[ffmpeg.py]"]
  node_storage[("Course and settings storage")]
  node_catalog[("Download catalog")]
  node_diagnostics["Download diagnostics<br/>[reports.py]"]
end

node_user(("User"))
node_getcourse_service{{"GetCourse website"}}
node_local_files[("Local files")]

node_user -->|"uses"| node_desktop
node_desktop -->|"shows"| node_start
node_desktop -->|"shows"| node_courses
node_start -->|"invokes"| node_discover_uc
node_courses -->|"invokes"| node_download_uc
node_discover_uc -->|"uses models"| node_domain
node_download_uc -.->|"uses models"| node_domain
node_bootstrap -->|"assembles"| node_discover_uc
node_bootstrap -->|"assembles"| node_download_uc
node_bootstrap -->|"assembles"| node_discovery_adapter
node_bootstrap -->|"assembles"| node_browser
node_start -->|"returns discovered courses"| node_courses
node_discovery_adapter -.->|"reads courses"| node_getcourse_service
node_browser -->|"authenticates"| node_getcourse_service
node_download_adapter -->|"extracts lesson video"| node_lesson_adapter
node_download_adapter -->|"uses browser"| node_browser
node_download_adapter -->|"downloads streams"| node_hls
node_download_adapter -->|"checks existing downloads"| node_catalog
node_download_adapter -->|"writes lesson files"| node_local_files
node_hls -->|"muxes media"| node_ffmpeg
node_ffmpeg -->|"writes MP4"| node_local_files
node_storage -.->|"persists settings"| node_local_files
node_courses -->|"renders progress"| node_events
node_download_uc -.->|"emits progress"| node_events
node_courses -->|"loads reports"| node_diagnostics
node_cli -->|"invokes worker flow"| node_download_uc

click node_desktop "https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/presentation/flet/app.py"
click node_start "https://github.com/markpekun/getcourse-downloader/tree/main/src/getcourse_downloader/presentation/flet/screens/start"
click node_courses "https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/presentation/flet/screens/courses/view.py"
click node_cli "https://github.com/markpekun/getcourse-downloader/tree/main/src/getcourse_downloader/presentation/cli"
click node_discover_uc "https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/application/use_cases/discover_courses.py"
click node_download_uc "https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/application/use_cases/download_lessons.py"
click node_domain "https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/domain/models.py"
click node_events "https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/domain/events.py"
click node_bootstrap "https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/bootstrap.py"
click node_browser "https://github.com/markpekun/getcourse-downloader/tree/main/src/getcourse_downloader/infrastructure/browser"
click node_discovery_adapter "https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/infrastructure/getcourse/discovery.py"
click node_lesson_adapter "https://github.com/markpekun/getcourse-downloader/tree/main/src/getcourse_downloader/infrastructure/getcourse"
click node_download_adapter "https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/infrastructure/getcourse/downloader.py"
click node_hls "https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/infrastructure/media/hls.py"
click node_ffmpeg "https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/infrastructure/media/ffmpeg.py"
click node_storage "https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/infrastructure/storage/json_repositories.py"
click node_catalog "https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/infrastructure/storage/download_catalog.py"
click node_diagnostics "https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/infrastructure/diagnostics/reports.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_desktop,node_start,node_courses,node_cli,node_user toneBlue
class node_discover_uc,node_download_uc,node_domain,node_events,node_bootstrap,node_local_files toneAmber
class node_browser,node_discovery_adapter,node_lesson_adapter,node_download_adapter toneMint
class node_hls,node_ffmpeg,node_storage,node_catalog,node_diagnostics toneRose
class node_getcourse_service toneIndigo
```

## Components

### User interface

- [Flet desktop app](https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/presentation/flet/app.py): `src/getcourse_downloader/presentation/flet/app.py`
- [Course discovery screen](https://github.com/markpekun/getcourse-downloader/tree/main/src/getcourse_downloader/presentation/flet/screens/start): `src/getcourse_downloader/presentation/flet/screens/start`
- [Lesson selection screen](https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/presentation/flet/screens/courses/view.py): `src/getcourse_downloader/presentation/flet/screens/courses/view.py`
- [CLI interface](https://github.com/markpekun/getcourse-downloader/tree/main/src/getcourse_downloader/presentation/cli): `src/getcourse_downloader/presentation/cli`

### Application and domain

- [Discover courses](https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/application/use_cases/discover_courses.py): `src/getcourse_downloader/application/use_cases/discover_courses.py`
- [Download lessons](https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/application/use_cases/download_lessons.py): `src/getcourse_downloader/application/use_cases/download_lessons.py`
- [Course and download models](https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/domain/models.py): `src/getcourse_downloader/domain/models.py`
- [Download events](https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/domain/events.py): `src/getcourse_downloader/domain/events.py`
- [Dependency assembly](https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/bootstrap.py): `src/getcourse_downloader/bootstrap.py`

### GetCourse integration

- [Playwright browser and profile](https://github.com/markpekun/getcourse-downloader/tree/main/src/getcourse_downloader/infrastructure/browser): `src/getcourse_downloader/infrastructure/browser`
- [GetCourse discovery](https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/infrastructure/getcourse/discovery.py): `src/getcourse_downloader/infrastructure/getcourse/discovery.py`
- [Lesson and player extraction](https://github.com/markpekun/getcourse-downloader/tree/main/src/getcourse_downloader/infrastructure/getcourse): `src/getcourse_downloader/infrastructure/getcourse`
- [GetCourse downloader](https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/infrastructure/getcourse/downloader.py): `src/getcourse_downloader/infrastructure/getcourse/downloader.py`

### Media and persistence

- [HLS fetch and decryption](https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/infrastructure/media/hls.py): `src/getcourse_downloader/infrastructure/media/hls.py`
- [MP4 muxing](https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/infrastructure/media/ffmpeg.py): `src/getcourse_downloader/infrastructure/media/ffmpeg.py`
- [Course and settings storage](https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/infrastructure/storage/json_repositories.py): `src/getcourse_downloader/infrastructure/storage/json_repositories.py`
- [Download catalog](https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/infrastructure/storage/download_catalog.py): `src/getcourse_downloader/infrastructure/storage/download_catalog.py`
- [Download diagnostics](https://github.com/markpekun/getcourse-downloader/blob/main/src/getcourse_downloader/infrastructure/diagnostics/reports.py): `src/getcourse_downloader/infrastructure/diagnostics/reports.py`

### Other components

- **User**
- **GetCourse website**
- **Local files**

## Connections

- User → Flet desktop app: uses (evidence: `README.md`)
- Flet desktop app → Course discovery screen: shows (evidence: `src/getcourse_downloader/presentation/flet/app.py`)
- Flet desktop app → Lesson selection screen: shows (evidence: `src/getcourse_downloader/presentation/flet/app.py`)
- Course discovery screen → Discover courses: invokes (evidence: `src/getcourse_downloader/presentation/flet/screens/start/controller.py`)
- Lesson selection screen → Download lessons: invokes
- Discover courses → Course and download models: uses models (evidence: `src/getcourse_downloader/application/use_cases/discover_courses.py`)
- Download lessons → Course and download models: uses models (evidence: `src/getcourse_downloader/application/use_cases/download_lessons.py`)
- Dependency assembly → Discover courses: assembles (evidence: `src/getcourse_downloader/bootstrap.py`)
- Dependency assembly → Download lessons: assembles (evidence: `src/getcourse_downloader/bootstrap.py`)
- Dependency assembly → GetCourse discovery: assembles (evidence: `src/getcourse_downloader/bootstrap.py`)
- Dependency assembly → Playwright browser and profile: assembles (evidence: `src/getcourse_downloader/bootstrap.py`)
- Course discovery screen → Lesson selection screen: returns discovered courses (evidence: `README.md`)
- GetCourse discovery → GetCourse website: reads courses
- Playwright browser and profile → GetCourse website: authenticates (evidence: `README.md`)
- GetCourse downloader → Lesson and player extraction: extracts lesson video (evidence: `src/getcourse_downloader/infrastructure/getcourse/downloader.py`)
- GetCourse downloader → Playwright browser and profile: uses browser (evidence: `src/getcourse_downloader/infrastructure/getcourse/downloader.py`)
- GetCourse downloader → HLS fetch and decryption: downloads streams (evidence: `src/getcourse_downloader/infrastructure/getcourse/downloader.py`)
- GetCourse downloader → Download catalog: checks existing downloads (evidence: `src/getcourse_downloader/infrastructure/getcourse/downloader.py`)
- GetCourse downloader → Local files: writes lesson files (evidence: `README.md`)
- HLS fetch and decryption → MP4 muxing: muxes media (evidence: `src/getcourse_downloader/infrastructure/media/hls.py`)
- MP4 muxing → Local files: writes MP4 (evidence: `README.md`)
- Course and settings storage → Local files: persists settings
- Lesson selection screen → Download events: renders progress (evidence: `src/getcourse_downloader/presentation/flet/screens/courses/view.py`)
- Download lessons → Download events: emits progress
- Lesson selection screen → Download diagnostics: loads reports
- CLI interface → Download lessons: invokes worker flow (evidence: `src/getcourse_downloader/presentation/cli/worker.py`)
