Update AGENTS.md with updated models namespaces

This commit is contained in:
whimsical-c4lic0 2026-02-10 00:19:21 -06:00
parent ed06a5e514
commit f7f1fad92d

View File

@ -6,7 +6,7 @@ This repo is **OF DL** (also known as OF-DL), a C# console app that downloads me
This document is for AI agents helping developers modify the project. It focuses on architecture, data flow, and the This document is for AI agents helping developers modify the project. It focuses on architecture, data flow, and the
most important change points. most important change points.
**Quick Flow** ## Quick Flow
1. `Program.Main` builds DI, loads `config.conf`, and runs the interactive flow. 1. `Program.Main` builds DI, loads `config.conf`, and runs the interactive flow.
2. `StartupService.CheckVersionAsync` checks the latest release tag (`OFDLV*`) from `git.ofdl.tools` when not in DEBUG. 2. `StartupService.CheckVersionAsync` checks the latest release tag (`OFDLV*`) from `git.ofdl.tools` when not in DEBUG.
@ -16,64 +16,77 @@ most important change points.
6. `DownloadOrchestrationService` selects creators, prepares folders/DBs, and calls `DownloadService` per media type. 6. `DownloadOrchestrationService` selects creators, prepares folders/DBs, and calls `DownloadService` per media type.
7. `DownloadService` downloads media, handles DRM, and records metadata in SQLite. 7. `DownloadService` downloads media, handles DRM, and records metadata in SQLite.
**Project Layout** ## Project Layout
- `OF DL/Program.cs` orchestrates startup, config/auth loading, and the interactive flow (CLI entrypoint). - `OF DL/Program.cs` orchestrates startup, config/auth loading, and the interactive flow (CLI entrypoint).
- `OF DL/CLI/` contains Spectre.Console UI helpers and progress reporting (CLI-only). - `OF DL/CLI/` contains Spectre.Console UI helpers and progress reporting (CLI-only).
- `OF DL.Core/Services/` contains application services (API, auth, download, config, DB, startup, logging, filenames). - `OF DL.Core/Services/` contains application services (API, auth, download, config, DB, startup, logging, filenames).
- `OF DL.Core/Models/` holds configuration, auth, DTOs, entities, and mapping helpers. - `OF DL.Core/Models/` holds configuration, auth, API request/response models, downloads/startup results, DTOs,
entities, and mapping helpers.
- `OF DL.Core/Widevine/` implements Widevine CDM handling and key derivation. - `OF DL.Core/Widevine/` implements Widevine CDM handling and key derivation.
- `OF DL.Core/Helpers/`, `OF DL.Core/Utils/`, `OF DL.Core/Crypto/`, `OF DL.Core/Enumerations/` contain shared core logic. - `OF DL.Core/Helpers/`, `OF DL.Core/Utils/`, `OF DL.Core/Crypto/`, `OF DL.Core/Enumerations/` contain shared core
logic.
- `docs/` and `mkdocs.yml` define the documentation site. - `docs/` and `mkdocs.yml` define the documentation site.
- `site/` is generated MkDocs output and should not be edited by hand. - `site/` is generated MkDocs output and should not be edited by hand.
- `docker/` contains container entrypoint and supervisor configuration. - `docker/` contains container entrypoint and supervisor configuration.
**Key Services** ## Key Services
- `ApiService` (`OF DL.Core/Services/ApiService.cs`) builds signed headers, performs HTTP requests, and maps DTOs to - `ApiService` (`OF DL.Core/Services/ApiService.cs`) builds signed headers, performs HTTP requests, and maps DTOs to
entities. It also handles DRM-related calls like MPD/PSSH extraction and license requests. entities. It also handles DRM-related calls like MPD/PSSH extraction and license requests.
- `AuthService` (`OF DL.Core/Services/AuthService.cs`) loads `auth.json` or performs browser-based login with PuppeteerSharp, - `AuthService` (`OF DL.Core/Services/AuthService.cs`) loads `auth.json` or performs browser-based login with
PuppeteerSharp,
then persists auth. It also normalizes cookies. then persists auth. It also normalizes cookies.
- `ConfigService` (`OF DL.Core/Services/ConfigService.cs`) loads `config.conf` (HOCON), migrates legacy `config.json`, and - `ConfigService` (`OF DL.Core/Services/ConfigService.cs`) loads `config.conf` (HOCON), migrates legacy `config.json`,
and
updates global settings (logging, text sanitization). updates global settings (logging, text sanitization).
- `DownloadService` (`OF DL.Core/Services/DownloadService.cs`) downloads all media (images, video, audio) and handles DRM - `DownloadService` (`OF DL.Core/Services/DownloadService.cs`) downloads all media (images, video, audio) and handles
DRM
video decryption and FFmpeg execution. video decryption and FFmpeg execution.
- `DownloadOrchestrationService` (`OF DL.Core/Services/DownloadOrchestrationService.cs`) coordinates user selection, - `DownloadOrchestrationService` (`OF DL.Core/Services/DownloadOrchestrationService.cs`) coordinates user selection,
subscription lists, per-user folder prep, and per-media-type download execution. subscription lists, per-user folder prep, and per-media-type download execution.
- `DBService` (`OF DL.Core/Services/DBService.cs`) manages SQLite metadata DBs for downloaded media and a `users.db` index. - `DBService` (`OF DL.Core/Services/DBService.cs`) manages SQLite metadata DBs for downloaded media and a `users.db`
index.
- `StartupService` (`OF DL.Core/Services/StartupService.cs`) validates FFmpeg, rules.json, Widevine device files, and - `StartupService` (`OF DL.Core/Services/StartupService.cs`) validates FFmpeg, rules.json, Widevine device files, and
performs release version checks. performs release version checks.
- `LoggingService` (`OF DL.Core/Services/LoggingService.cs`) writes logs to `logs/OFDL.txt` and updates log level based on - `LoggingService` (`OF DL.Core/Services/LoggingService.cs`) writes logs to `logs/OFDL.txt` and updates log level based
on
config.
- `FileNameService` (`OF DL.Core/Services/FileNameService.cs`) formats filenames using the custom format rules from
config. config.
- `FileNameService` (`OF DL.Core/Services/FileNameService.cs`) formats filenames using the custom format rules from config.
**Models: DTOs vs Entities** ## Models
- DTOs live under `OF DL.Core/Models/Dtos/` and mirror API response JSON. - DTOs live under `OF DL.Core/Models/Dtos/` and mirror API response JSON.
- Entities live under `OF DL.Core/Models/Entities/` and represent the internal domain used by download logic. - Entities live under `OF DL.Core/Models/Entities/` and represent the internal domain used by download logic.
- Mappers in `OF DL.Core/Models/Mappers/` convert DTOs into entities to isolate API changes from downstream logic. - Mappers in `OF DL.Core/Models/Mappers/` convert DTOs into entities to isolate API changes from downstream logic.
- Non-DTO/Entity models are grouped by concern under `OF DL.Core/Models/Api/`, `Auth/`, `Config/`, `Downloads/`,
and `Startup/`.
- Classes in `OF DL.Core/Models/OfdlApi/` mirror request and response JOSN OF DL APIs (custom and gitea)
- Classes in `OF DL.Core/Models/Config/` are used for reading and storing application configuration
- Classes in `OF DL.Core/Models/Downloads/` contain counts and application state for downloads
**Configuration** ## Configuration
- Primary config file is `config.conf` (HOCON). `ConfigService` migrates legacy `config.json` if found and creates a - Primary config file is `config.conf` (HOCON). `ConfigService` migrates legacy `config.json` if found and creates a
default `config.conf` if missing. default `config.conf` if missing.
- `Config` lives in `OF DL.Core/Models/Config.cs` and is populated by `ConfigService.LoadConfigFromFileAsync`. - `Config` lives in `OF DL.Core/Models/Config/Config.cs` and is populated by `ConfigService.LoadConfigFromFileAsync`.
- `ConfigService.UpdateConfig` is the central place where runtime config changes are applied (logging level and text - `ConfigService.UpdateConfig` is the central place where runtime config changes are applied (logging level and text
sanitization). sanitization).
- CLI flag `--non-interactive` forces non-interactive mode; `ConfigService.IsCliNonInteractive` and - CLI flag `--non-interactive` forces non-interactive mode; `ConfigService.IsCliNonInteractive` and
`Config.NonInteractiveMode` both gate prompts. `Config.NonInteractiveMode` both gate prompts.
- FFmpeg path is read from `config.conf`, `auth.json`, or auto-detected from PATH/current directory. - FFmpeg path is read from `config.conf`, `auth.json`, or auto-detected from PATH/current directory.
**Runtime Files (relative to the working directory)** ## Runtime Files (relative to the working directory)
- `config.conf`, `auth.json`, and `rules.json` are loaded from the current working directory. - `config.conf`, `auth.json`, and `rules.json` are loaded from the current working directory.
- `cdm/` (Widevine device files), `chrome-data/` (Puppeteer profile), and `logs/` are created under the working - `cdm/` (Widevine device files), `chrome-data/` (Puppeteer profile), and `logs/` are created under the working
directory. directory.
- `users.db` is stored at the working directory root. - `users.db` is stored at the working directory root.
**Authentication Flow** ## Authentication Flow
- Auth data is stored in `auth.json` using the `Auth` model in `OF DL.Core/Models/Auth.cs`. - Auth data is stored in `auth.json` using the `Auth` model in `OF DL.Core/Models/Auth/Auth.cs`.
- `AuthService.LoadFromBrowserAsync` launches Chrome via PuppeteerSharp, waits for login, then extracts `auth_id` and - `AuthService.LoadFromBrowserAsync` launches Chrome via PuppeteerSharp, waits for login, then extracts `auth_id` and
`sess` cookies, `bcTokenSha` from localStorage (used as `X_BC`), and `USER_AGENT` from the browser. `sess` cookies, `bcTokenSha` from localStorage (used as `X_BC`), and `USER_AGENT` from the browser.
- `AuthService.ValidateCookieString` rewrites the cookie string so it contains only `auth_id` and `sess` and ensures a - `AuthService.ValidateCookieString` rewrites the cookie string so it contains only `auth_id` and `sess` and ensures a
@ -85,15 +98,15 @@ Environment variables used by auth:
- `OFDL_DOCKER=true` toggles Docker-specific instructions and browser flags. - `OFDL_DOCKER=true` toggles Docker-specific instructions and browser flags.
- `OFDL_PUPPETEER_EXECUTABLE_PATH` overrides the Chromium path for PuppeteerSharp. - `OFDL_PUPPETEER_EXECUTABLE_PATH` overrides the Chromium path for PuppeteerSharp.
**Dynamic Rules and Signature Headers** ## Dynamic Rules and Signature Headers
- All OnlyFans API requests use dynamic headers from `ApiService.GetDynamicHeaders`. - All OnlyFans API requests use dynamic headers from `ApiService.GetDynamicHeaders`.
- Dynamic rules are fetched from `https://git.ofdl.tools/sim0n00ps/dynamic-rules/raw/branch/main/rules.json` with - Dynamic rules are fetched from `https://git.ofdl.tools/sim0n00ps/dynamic-rules/raw/branch/main/rules.json` with
fallback to local `rules.json` in the current working directory. The repo ships `OF DL/rules.json` as the default fallback to local `rules.json` in the current working directory. The repo ships `OF DL/rules.json` as the default
rules file. rules file.
- Cache durations: 15 minutes for remote rules, 5 minutes for local rules. - Cache durations: 15 minutes for remote rules, 5 minutes for local rules.
- `DynamicRules` shape is defined in `OF DL.Core/Models/DynamicRules.cs` and includes `app-token`, `static_param`, `prefix`, - `DynamicRules` shape is defined in `OF DL.Core/Models/Api/DynamicRules.cs` and includes `app-token`, `static_param`,
`suffix`, `checksum_constant`, and `checksum_indexes`. `prefix`, `suffix`, `checksum_constant`, and `checksum_indexes`.
Signature algorithm in `GetDynamicHeaders`: Signature algorithm in `GetDynamicHeaders`:
@ -106,7 +119,7 @@ Headers included in signed requests:
- `app-token`, `sign`, `time`, `user-id`, `user-agent`, `x-bc`, `cookie`. - `app-token`, `sign`, `time`, `user-id`, `user-agent`, `x-bc`, `cookie`.
**Widevine CDM and DRM Decryption** ## Widevine CDM and DRM Decryption
- Runtime Widevine device files are expected at `cdm/devices/chrome_1610/device_client_id_blob` and - Runtime Widevine device files are expected at `cdm/devices/chrome_1610/device_client_id_blob` and
`cdm/devices/chrome_1610/device_private_key` (relative to the working directory). Paths are defined in `cdm/devices/chrome_1610/device_private_key` (relative to the working directory). Paths are defined in
@ -126,7 +139,7 @@ Two decryption paths exist:
`DownloadService.DownloadDrmMedia` runs FFmpeg with `-cenc_decryption_key`, CloudFront cookies, and auth `DownloadService.DownloadDrmMedia` runs FFmpeg with `-cenc_decryption_key`, CloudFront cookies, and auth
cookies/user-agent. Output is written to `{filename}_source.mp4`, then moved and recorded in SQLite. cookies/user-agent. Output is written to `{filename}_source.mp4`, then moved and recorded in SQLite.
**Download Paths, Data, and Logs** ## Download Paths, Data, and Logs
- Default download root is `__user_data__/sites/OnlyFans/{username}` when `DownloadPath` is blank. This is computed in - Default download root is `__user_data__/sites/OnlyFans/{username}` when `DownloadPath` is blank. This is computed in
`DownloadOrchestrationService.ResolveDownloadPath`. `DownloadOrchestrationService.ResolveDownloadPath`.
@ -135,13 +148,13 @@ cookies/user-agent. Output is written to `{filename}_source.mp4`, then moved and
- Logs are written to `logs/OFDL.txt` (rolling daily); FFmpeg report files are also written under `logs/` when debug - Logs are written to `logs/OFDL.txt` (rolling daily); FFmpeg report files are also written under `logs/` when debug
logging is enabled. logging is enabled.
**Docs (MkDocs)** ## Docs (MkDocs)
- Docs source lives under `docs/` and configuration is in `mkdocs.yml`. - Docs source lives under `docs/` and configuration is in `mkdocs.yml`.
- Build the site with `mkdocs build --clean` (outputs to `site/`). - Build the site with `mkdocs build --clean` (outputs to `site/`).
- Preview locally with `mkdocs serve`. - Preview locally with `mkdocs serve`.
**CI/CD (Gitea Workflows)** ## CI/CD (Gitea Workflows)
- `/.gitea/workflows/publish-docs.yml` builds and deploys docs on tag pushes matching `OFDLV*` and on manual dispatch. - `/.gitea/workflows/publish-docs.yml` builds and deploys docs on tag pushes matching `OFDLV*` and on manual dispatch.
- `/.gitea/workflows/publish-docker.yml` builds multi-arch Docker images on `OFDLV*` tags and pushes to the Gitea - `/.gitea/workflows/publish-docker.yml` builds multi-arch Docker images on `OFDLV*` tags and pushes to the Gitea
@ -149,7 +162,7 @@ cookies/user-agent. Output is written to `{filename}_source.mp4`, then moved and
- `/.gitea/workflows/publish-release.yml` publishes Windows and Linux builds on `OFDLV*` tags and creates a draft - `/.gitea/workflows/publish-release.yml` publishes Windows and Linux builds on `OFDLV*` tags and creates a draft
release. release.
**Docker Image** ## Docker Image
- Built via `/.gitea/workflows/publish-docker.yml` on tag pushes `OFDLV*`. - Built via `/.gitea/workflows/publish-docker.yml` on tag pushes `OFDLV*`.
- Image tags: `git.ofdl.tools/sim0n00ps/of-dl:latest` and `git.ofdl.tools/sim0n00ps/of-dl:{version}`. - Image tags: `git.ofdl.tools/sim0n00ps/of-dl:latest` and `git.ofdl.tools/sim0n00ps/of-dl:{version}`.
@ -158,13 +171,13 @@ cookies/user-agent. Output is written to `{filename}_source.mp4`, then moved and
- Runtime uses `/config` as the working directory and `/data` for downloads; `docker/entrypoint.sh` seeds - Runtime uses `/config` as the working directory and `/data` for downloads; `docker/entrypoint.sh` seeds
`/config/config.conf` and `/config/rules.json` from `/default-config`. `/config/config.conf` and `/config/rules.json` from `/default-config`.
**Release Checklist** ## Release Checklist
1. Update docs under `docs/` and verify locally with `mkdocs build --clean` or `mkdocs serve`. 1. Update docs under `docs/` and verify locally with `mkdocs build --clean` or `mkdocs serve`.
2. Tag the release as `OFDLV{version}` and push the tag. 2. Tag the release as `OFDLV{version}` and push the tag.
3. Verify the draft release artifact and publish the release in Gitea. 3. Verify the draft release artifact and publish the release in Gitea.
**Coding Style (from .editorconfig)** ## Coding Style (from .editorconfig)
- Indentation: 4 spaces by default, 2 spaces for XML/YAML/project files. No tabs. - Indentation: 4 spaces by default, 2 spaces for XML/YAML/project files. No tabs.
- Line endings: LF for `*.sh`, CRLF for `*.cmd`/`*.bat`. - Line endings: LF for `*.sh`, CRLF for `*.cmd`/`*.bat`.
@ -175,18 +188,18 @@ cookies/user-agent. Output is written to `{filename}_source.mp4`, then moved and
- `const` fields should be PascalCase. - `const` fields should be PascalCase.
- Prefer braces for control blocks and expression-bodied members (silent preferences). - Prefer braces for control blocks and expression-bodied members (silent preferences).
**Where to Look First** ## Where to Look First
- `OF DL/Program.cs` for the execution path and menu flow. - `OF DL/Program.cs` for the execution path and menu flow.
- `OF DL.Core/Services/ApiService.cs` for OF API calls and header signing. - `OF DL.Core/Services/ApiService.cs` for OF API calls and header signing.
- `OF DL.Core/Services/DownloadService.cs` for downloads and DRM handling. - `OF DL.Core/Services/DownloadService.cs` for downloads and DRM handling.
- `OF DL.Core/Services/DownloadOrchestrationService.cs` for creator selection and flow control. - `OF DL.Core/Services/DownloadOrchestrationService.cs` for creator selection and flow control.
- `OF DL.Core/Widevine/` for CDM key generation and license parsing. - `OF DL.Core/Widevine/` for CDM key generation and license parsing.
- `OF DL.Core/Models/Config.cs` and `OF DL.Core/Services/ConfigService.cs` for config shape and parsing. - `OF DL.Core/Models/Config/Config.cs` and `OF DL.Core/Services/ConfigService.cs` for config shape and parsing.
- `OF DL.Core/Services/AuthService.cs` for user-facing authentication behavior and browser login flow. - `OF DL.Core/Services/AuthService.cs` for user-facing authentication behavior and browser login flow.
- `docs/` for public documentation; update docs whenever user-facing behavior or configuration changes. - `docs/` for public documentation; update docs whenever user-facing behavior or configuration changes.
Documentation updates for common changes: ## Documentation updates for common changes:
- Config option added/removed/changed in `Config` or `config.conf`: update `docs/config/all-configuration-options.md` ( - Config option added/removed/changed in `Config` or `config.conf`: update `docs/config/all-configuration-options.md` (
full spec), `docs/config/configuration.md` (organized list), and `docs/config/custom-filename-formats.md` if filename full spec), `docs/config/configuration.md` (organized list), and `docs/config/custom-filename-formats.md` if filename