Update AGENTS.md with updated models namespaces
This commit is contained in:
parent
ed06a5e514
commit
f7f1fad92d
73
AGENTS.md
73
AGENTS.md
@ -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
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user