Compare commits

..

No commits in common. "master" and "master" have entirely different histories.

299 changed files with 13783 additions and 19735 deletions

View File

@ -1,186 +1,9 @@
# editorconfig.org
# top-most EditorConfig file
# Editor configuration, see https://editorconfig.org
root = true
# Default settings:
# A newline ending every file
# Use 4 spaces as indentation
[*]
charset = utf-8
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true
[project.json]
indent_size = 2
# Generated code
[*{_AssemblyInfo.cs,.notsupported.cs}]
generated_code = true
# C# files
[*.cs]
# New line preferences
csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_between_query_expression_clauses = true
# Indentation preferences
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_switch_labels = true
csharp_indent_labels = one_less_than_current
# Modifier preferences
csharp_preferred_modifier_order = public, private, protected, internal, static, extern, new, virtual, abstract, sealed, override, readonly, unsafe, volatile, async:suggestion
# avoid this. unless absolutely necessary
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_event = false:suggestion
# Types: use keywords instead of BCL types, and permit var only when the type is clear
csharp_style_var_for_built_in_types = false:suggestion
csharp_style_var_when_type_is_apparent = false:none
csharp_style_var_elsewhere = false:suggestion
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
# name all constant fields using PascalCase
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
dotnet_naming_symbols.constant_fields.applicable_kinds = field
dotnet_naming_symbols.constant_fields.required_modifiers = const
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
# static fields should have s_ prefix
dotnet_naming_rule.static_fields_should_have_prefix.severity = suggestion
dotnet_naming_rule.static_fields_should_have_prefix.symbols = static_fields
dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style
dotnet_naming_symbols.static_fields.applicable_kinds = field
dotnet_naming_symbols.static_fields.required_modifiers = static
dotnet_naming_symbols.static_fields.applicable_accessibilities = private, internal, private_protected
dotnet_naming_style.static_prefix_style.required_prefix = s_
dotnet_naming_style.static_prefix_style.capitalization = camel_case
# internal and private fields should be _camelCase
dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion
dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields
dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style
dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
dotnet_naming_style.camel_case_underscore_style.required_prefix = _
dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
# Code style defaults
csharp_using_directive_placement = outside_namespace:suggestion
dotnet_sort_system_directives_first = true
csharp_prefer_braces = true:silent
csharp_preserve_single_line_blocks = true:none
csharp_preserve_single_line_statements = false:none
csharp_prefer_static_local_function = true:suggestion
csharp_prefer_simple_using_statement = false:none
csharp_style_prefer_switch_expression = true:suggestion
dotnet_style_readonly_field = true:suggestion
# Expression-level preferences
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_auto_properties = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
csharp_prefer_simple_default_expression = true:suggestion
# Expression-bodied members
csharp_style_expression_bodied_methods = true:silent
csharp_style_expression_bodied_constructors = true:silent
csharp_style_expression_bodied_operators = true:silent
csharp_style_expression_bodied_properties = true:silent
csharp_style_expression_bodied_indexers = true:silent
csharp_style_expression_bodied_accessors = true:silent
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_expression_bodied_local_functions = true:silent
# Pattern matching
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
# Null checking preferences
csharp_style_throw_expression = true:suggestion
csharp_style_conditional_delegate_call = true:suggestion
# Other features
csharp_style_prefer_index_operator = false:none
csharp_style_prefer_range_operator = false:none
csharp_style_pattern_local_over_anonymous_function = false:none
# Space preferences
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = do_not_ignore
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
# Xml project files
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}]
indent_size = 2
[*.{csproj,vbproj,proj,nativeproj,locproj}]
charset = utf-8
# Xml build files
[*.builds]
indent_size = 2
# Xml files
[*.{xml,stylecop,resx,ruleset}]
indent_size = 2
# Xml config files
[*.{props,targets,config,nuspec}]
indent_size = 2
# YAML config files
[*.{yml,yaml}]
indent_size = 2
# Shell scripts
[*.sh]
end_of_line = lf
[*.{cmd,bat}]
end_of_line = crlf

5
.gitattributes vendored
View File

@ -3,11 +3,6 @@
###############################################################################
* text=auto
###############################################################################
# Shell scripts should use LF line endings (avoid /bin/sh^M issues in containers)
###############################################################################
*.sh text eol=lf
###############################################################################
# Set default behavior for command prompt diff.
#

View File

@ -29,12 +29,12 @@ jobs:
- name: Build for Windows and Linux
run: |
dotnet publish "OF DL/OF DL.csproj" -p:Version=${{ steps.version.outputs.version }} \
dotnet publish -p:Version=${{ steps.version.outputs.version }} \
-p:PackageVersion=${{ steps.version.outputs.version }} \
-p:WarningLevel=0 -c Release -r win-x86 \
--self-contained true -p:PublishSingleFile=true -o outwin
dotnet publish "OF DL/OF DL.csproj" -p:Version=${{ steps.version.outputs.version }} \
dotnet publish -p:Version=${{ steps.version.outputs.version }} \
-p:PackageVersion=${{ steps.version.outputs.version }} \
-p:WarningLevel=0 -c Release -r linux-x64 \
--self-contained true -p:PublishSingleFile=true -o outlin
@ -52,13 +52,12 @@ jobs:
echo "➤ Creating folder for CDM"
mkdir -p cdm/devices/chrome_1610
echo "➤ Copying ffmpeg and ffprobe from user folder"
echo "➤ Copying ffmpeg from user folder"
cp /home/rhys/ffmpeg/ffmpeg-7.1.1-essentials_build/bin/ffmpeg.exe .
cp /home/rhys/ffmpeg/ffmpeg-7.1.1-essentials_build/bin/ffprobe.exe .
cp /home/rhys/ffmpeg/ffmpeg-7.1.1-essentials_build/LICENSE LICENSE.ffmpeg
echo "➤ Creating release zip"
zip ../OFDLV${{ steps.version.outputs.version }}.zip OF\ DL.exe e_sqlite3.dll rules.json config.conf cdm chromium-scripts ffmpeg.exe ffprobe.exe LICENSE.ffmpeg
zip ../OFDLV${{ steps.version.outputs.version }}.zip OF\ DL.exe e_sqlite3.dll rules.json config.conf cdm ffmpeg.exe LICENSE.ffmpeg
cd ..
- name: Create release and upload artifact
@ -71,4 +70,4 @@ jobs:
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
GITEA_REPOSITORY: ${{ gitea.repository }}
GITEA_SERVER_URL: ${{ gitea.server_url }}
GITEA_SERVER_URL: ${{ gitea.server_url }}

5
.gitignore vendored
View File

@ -370,7 +370,4 @@ FodyWeavers.xsd
!.gitea-actions/**/node_modules/
# venv
venv/
# Generated docs
/site
venv/

238
AGENTS.md
View File

@ -1,238 +0,0 @@
# AGENTS.md
Note: Keep AGENTS.md updated as project structure, key services, or workflows change.
This repo is **OF DL** (also known as OF-DL), a C# console app that downloads media from a user's OnlyFans account(s).
This document is for AI agents helping developers modify the project. It focuses on architecture, data flow, and the
most important change points.
## Quick 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.
3. `StartupService.ValidateEnvironmentAsync` validates OS, FFmpeg, `rules.json`, and Widevine device files.
4. `AuthService` loads `auth.json` or opens a browser login (PuppeteerSharp) and persists auth data.
5. `ApiService` signs every API request with dynamic rules and the current auth.
6. `DownloadOrchestrationService` selects creators, prepares folders/DBs, and calls `DownloadService` per media type.
7. `DownloadService` downloads media, handles DRM, and records metadata in SQLite.
## Project Layout
- `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.Core/Services/` contains application services (API, auth, download, config, DB, startup, logging, filenames).
- `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/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.
- `site/` is generated MkDocs output and should not be edited by hand.
- `docker/` contains container entrypoint and supervisor configuration.
## Key Services
- `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.
- `AuthService` (`OF DL.Core/Services/AuthService.cs`) loads `auth.json` or performs browser-based login with
PuppeteerSharp,
then persists auth. It also normalizes cookies.
- `ConfigService` (`OF DL.Core/Services/ConfigService.cs`) loads `config.conf` (HOCON), migrates legacy `config.json`,
and
updates global settings (logging, text sanitization).
- `DownloadService` (`OF DL.Core/Services/DownloadService.cs`) downloads all media (images, video, audio) and handles
DRM
video decryption and FFmpeg execution.
- `DownloadOrchestrationService` (`OF DL.Core/Services/DownloadOrchestrationService.cs`) coordinates user selection,
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.
- `StartupService` (`OF DL.Core/Services/StartupService.cs`) validates FFmpeg, rules.json, Widevine device files, and
performs release version checks.
- `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.
## Models
- 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.
- 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/OfdlApi/`, `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
- Primary config file is `config.conf` (HOCON). `ConfigService` migrates legacy `config.json` if found and creates a
default `config.conf` if missing.
- `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
sanitization).
- CLI flag `--non-interactive` forces non-interactive mode; `ConfigService.IsCliNonInteractive` and
`Config.NonInteractiveMode` both gate prompts.
- FFmpeg path is read from `config.conf`, `auth.json`, or auto-detected from PATH/current directory.
## Runtime Files (relative to the 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
directory.
- `users.db` is stored at the working directory root.
## Execution and Testing
- .NET SDK: 8.x (`net8.0` for all projects).
- Build from the repo root:
```bash
dotnet build OF DL.sln
```
- Run from source (runtime files are read from the current working directory):
```bash
dotnet run --project "OF DL/OF DL.csproj"
```
- If you want a local `rules.json` fallback, run from `OF DL/` or copy `OF DL/rules.json` into your working directory.
- Run tests:
```bash
dotnet test "OF DL.Tests/OF DL.Tests.csproj"
```
- Optional coverage (coverlet collector):
```bash
dotnet test "OF DL.Tests/OF DL.Tests.csproj" --collect:"XPlat Code Coverage"
```
## Authentication Flow
- 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
`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
trailing `;`.
- `AuthService` uses `chrome-data/` as its user data directory; `Logout` deletes `chrome-data` and `auth.json`.
Environment variables used by auth:
- `OFDL_DOCKER=true` toggles Docker-specific instructions and browser flags.
- `OFDL_PUPPETEER_EXECUTABLE_PATH` overrides the Chromium path for PuppeteerSharp.
## Dynamic Rules and Signature Headers
- 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
fallback to local `rules.json` in the current working directory. The repo ships `OF DL/rules.json` as the default
rules file.
- Cache durations: 15 minutes for remote rules, 5 minutes for local rules.
- `DynamicRules` shape is defined in `OF DL.Core/Models/OfdlApi/DynamicRules.cs` and includes `app-token`,
`static_param`,
`prefix`, `suffix`, `checksum_constant`, and `checksum_indexes`.
Signature algorithm in `GetDynamicHeaders`:
- `input = "{static_param}\n{timestamp_ms}\n{path+query}\n{user_id}"`
- `hash = SHA1(input)` lower-case hex string
- `checksum = sum(hashString[index] char values) + checksum_constant`
- `sign = "{prefix}:{hash}:{checksum_hex}:{suffix}"`
Headers included in signed requests:
- `app-token`, `sign`, `time`, `user-id`, `user-agent`, `x-bc`, `cookie`.
## Widevine CDM and DRM Decryption
- 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
`OF DL.Core/Widevine/Constants.cs` and validated in `StartupService`.
DRM flow is primarily in `DownloadService.GetDecryptionInfo` and `ApiService` DRM helpers:
- `ApiService.GetDRMMPDPSSH` downloads the MPD manifest and extracts the `cenc:pssh` value.
- `ApiService.GetDRMMPDLastModified` uses CloudFront signed cookies and returns MPD `Last-Modified`.
- `DownloadService.GetDecryptionInfo` builds DRM headers (via `GetDynamicHeaders`) and hits the license endpoint.
Two decryption paths exist:
- If CDM device files exist, `ApiService.GetDecryptionKeyCDM` uses `Widevine/CDMApi`.
- If missing, `ApiService.GetDecryptionKeyOFDL` calls `https://ofdl.tools/WV` as a fallback.
`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.
## Download Paths, Data, and Logs
- Default download root is `__user_data__/sites/OnlyFans/{username}` when `DownloadPath` is blank. This is computed in
`DownloadOrchestrationService.ResolveDownloadPath`.
- Each creator folder gets a `Metadata/user_data.db` (SQLite) managed by `DBService`.
- A global `users.db` in the working directory tracks subscribed creators and user IDs.
- Logs are written to `logs/OFDL.txt` (rolling daily); FFmpeg report files are also written under `logs/` when debug
logging is enabled.
## Docs (MkDocs)
- Docs source lives under `docs/` and configuration is in `mkdocs.yml`.
- Build the site with `mkdocs build --clean` (outputs to `site/`).
- Preview locally with `mkdocs serve`.
## 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-docker.yml` builds multi-arch Docker images on `OFDLV*` tags and pushes to the Gitea
registry.
- `/.gitea/workflows/publish-release.yml` publishes Windows and Linux builds on `OFDLV*` tags and creates a draft
release.
## Docker Image
- 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}`.
- Build args include `VERSION` (tag name with `OFDLV` stripped).
- Platforms: `linux/amd64` and `linux/arm64`.
- 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`.
## Release Checklist
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.
3. Verify the draft release artifact and publish the release in Gitea.
## Coding Style (from .editorconfig)
- Indentation: 4 spaces by default, 2 spaces for XML/YAML/project files. No tabs.
- Line endings: LF for `*.sh`, CRLF for `*.cmd`/`*.bat`.
- C# braces on new lines (`csharp_new_line_before_open_brace = all`).
- Prefer predefined types (`int`, `string`) and avoid `var` except when type is apparent.
- `using` directives go outside the namespace and `System` namespaces are sorted first.
- Private/internal fields use `_camelCase`; private/internal static fields use `s_` prefix.
- `const` fields should be PascalCase.
- Prefer braces for control blocks and expression-bodied members (silent preferences).
## Where to Look First
- `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/DownloadService.cs` for downloads and DRM handling.
- `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/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.
- `docs/` for public documentation; update docs whenever user-facing behavior or configuration changes.
## Documentation updates for common changes:
- 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
tokens or formats are affected.
- Authentication flow changes (browser login, legacy methods, required fields): update `docs/config/auth.md`.
- CLI/menu flow or download workflow changes: update `docs/running-the-program.md`.
- Docker runtime or container flags/paths change: update `docs/installation/docker.md`.

View File

@ -1,16 +1,18 @@
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
FROM alpine:3.20 AS build
ARG VERSION
RUN apk --no-cache --repository community add \
dotnet8-sdk
# Copy source code
COPY ["OF DL.sln", "/src/OF DL.sln"]
COPY ["OF DL", "/src/OF DL"]
COPY ["OF DL.Core", "/src/OF DL.Core"]
WORKDIR "/src"
# Build release
RUN dotnet publish "OF DL/OF DL.csproj" -p:WarningLevel=0 -p:Version=$VERSION -c Release -o out
RUN dotnet publish -p:WarningLevel=0 -p:Version=$VERSION -c Release --self-contained true -p:PublishSingleFile=true -o out
# Generate default config.conf files
RUN /src/out/OF\ DL --non-interactive || true && \
@ -19,24 +21,21 @@ RUN /src/out/OF\ DL --non-interactive || true && \
mv /src/updated_config.conf /src/config.conf
FROM mcr.microsoft.com/dotnet/runtime:10.0 AS final
FROM alpine:3.20 AS final
# Install dependencies
RUN apt-get update \
&& apt-get install -y \
RUN apk --no-cache --repository community add \
bash \
tini \
dotnet8-runtime \
ffmpeg \
udev \
ttf-freefont \
chromium \
supervisor \
xvfb \
x11vnc \
novnc \
npm \
&& rm -rf /var/lib/apt/lists/*
RUN npx playwright install-deps
RUN apt-get remove --purge -y npm \
&& apt-get autoremove -y
novnc
# Redirect webroot to vnc.html instead of displaying directory listing
RUN echo "<!DOCTYPE html><html><head><meta http-equiv=\"Refresh\" content=\"0; url='vnc.html'\" /></head><body></body></html>" > /usr/share/novnc/index.html
@ -55,14 +54,13 @@ COPY docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY docker/entrypoint.sh /app/entrypoint.sh
RUN chmod +x /app/entrypoint.sh
ENV DEBIAN_FRONTEND="noninteractive" \
DISPLAY=:0.0 \
DISPLAY_WIDTH=1366 \
ENV DISPLAY=:0.0 \
DISPLAY_WIDTH=1024 \
DISPLAY_HEIGHT=768 \
OFDL_DOCKER=true \
PLAYWRIGHT_BROWSERS_PATH=/config/chromium
OFDL_PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium \
OFDL_DOCKER=true
EXPOSE 8080
WORKDIR /config
ENTRYPOINT ["/usr/bin/tini", "--"]
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["/app/entrypoint.sh"]

View File

@ -1,29 +0,0 @@
using System.Security.Cryptography;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Macs;
using Org.BouncyCastle.Crypto.Parameters;
namespace OF_DL.Crypto;
public class CryptoUtils
{
public static byte[] GetHMACSHA256Digest(byte[] data, byte[] key) => new HMACSHA256(key).ComputeHash(data);
public static byte[] GetCMACDigest(byte[] data, byte[] key)
{
IBlockCipher cipher = new AesEngine();
IMac mac = new CMac(cipher, 128);
KeyParameter keyParam = new(key);
mac.Init(keyParam);
mac.BlockUpdate(data, 0, data.Length);
byte[] outBytes = new byte[16];
mac.DoFinal(outBytes, 0);
return outBytes;
}
}

View File

@ -1,127 +0,0 @@
using System.Security.Cryptography;
namespace OF_DL.Crypto;
public class Padding
{
public static byte[] AddPKCS7Padding(byte[] data, int k)
{
int m = k - data.Length % k;
byte[] padding = new byte[m];
Array.Fill(padding, (byte)m);
byte[] paddedBytes = new byte[data.Length + padding.Length];
Buffer.BlockCopy(data, 0, paddedBytes, 0, data.Length);
Buffer.BlockCopy(padding, 0, paddedBytes, data.Length, padding.Length);
return paddedBytes;
}
public static byte[] RemovePKCS7Padding(byte[] paddedByteArray)
{
byte last = paddedByteArray[^1];
if (paddedByteArray.Length <= last)
{
return paddedByteArray;
}
return SubArray(paddedByteArray, 0, paddedByteArray.Length - last);
}
public static T[] SubArray<T>(T[] arr, int start, int length)
{
T[] result = new T[length];
Buffer.BlockCopy(arr, start, result, 0, length);
return result;
}
public static byte[] AddPssPadding(byte[] hash)
{
int modBits = 2048;
int hLen = 20;
int emLen = 256;
int lmask = 0;
for (int i = 0; i < 8 * emLen - (modBits - 1); i++)
{
lmask = (lmask >> 1) | 0x80;
}
// Commented out since the condition will always be false while emLen = 256 and hLen = 20
// if (emLen < hLen + hLen + 2)
// {
// return null;
// }
byte[] salt = new byte[hLen];
new Random().NextBytes(salt);
byte[] m_prime = Enumerable.Repeat((byte)0, 8).ToArray().Concat(hash).Concat(salt).ToArray();
byte[] h = SHA1.Create().ComputeHash(m_prime);
byte[] ps = Enumerable.Repeat((byte)0, emLen - hLen - hLen - 2).ToArray();
byte[] db = ps.Concat(new byte[] { 0x01 }).Concat(salt).ToArray();
byte[] dbMask = MGF1(h, emLen - hLen - 1);
byte[] maskedDb = new byte[dbMask.Length];
for (int i = 0; i < dbMask.Length; i++)
{
maskedDb[i] = (byte)(db[i] ^ dbMask[i]);
}
maskedDb[0] = (byte)(maskedDb[0] & ~lmask);
byte[] padded = maskedDb.Concat(h).Concat(new byte[] { 0xBC }).ToArray();
return padded;
}
public static byte[] RemoveOAEPPadding(byte[] data)
{
int k = 256;
int hLen = 20;
byte[] maskedSeed = data[1..(hLen + 1)];
byte[] maskedDB = data[(hLen + 1)..];
byte[] seedMask = MGF1(maskedDB, hLen);
byte[] seed = new byte[maskedSeed.Length];
for (int i = 0; i < maskedSeed.Length; i++)
{
seed[i] = (byte)(maskedSeed[i] ^ seedMask[i]);
}
byte[] dbMask = MGF1(seed, k - hLen - 1);
byte[] db = new byte[maskedDB.Length];
for (int i = 0; i < maskedDB.Length; i++)
{
db[i] = (byte)(maskedDB[i] ^ dbMask[i]);
}
int onePos = BitConverter.ToString(db[hLen..]).Replace("-", "").IndexOf("01", StringComparison.Ordinal) / 2;
byte[] unpadded = db[(hLen + onePos + 1)..];
return unpadded;
}
private static byte[] MGF1(byte[] seed, int maskLen)
{
SHA1 hobj = SHA1.Create();
int hLen = hobj.HashSize / 8;
List<byte> T = new();
for (int i = 0; i < (int)Math.Ceiling(maskLen / (double)hLen); i++)
{
byte[] c = BitConverter.GetBytes(i);
Array.Reverse(c);
byte[] digest = hobj.ComputeHash(seed.Concat(c).ToArray());
T.AddRange(digest);
}
return T.GetRange(0, maskLen).ToArray();
}
}

View File

@ -1,7 +0,0 @@
namespace OF_DL.Enumerations;
public enum CustomFileNameOption
{
ReturnOriginal,
ReturnEmpty
}

View File

@ -1,7 +0,0 @@
namespace OF_DL.Enumerations;
public enum DownloadDateSelection
{
before,
after
}

View File

@ -1,34 +0,0 @@
namespace OF_DL.Enumerations;
public enum LoggingLevel
{
//
// Summary:
// Anything and everything you might want to know about a running block of code.
Verbose,
//
// Summary:
// Internal system events that aren't necessarily observable from the outside.
Debug,
//
// Summary:
// The lifeblood of operational intelligence - things happen.
Information,
//
// Summary:
// Service is degraded or endangered.
Warning,
//
// Summary:
// Functionality is unavailable, invariants are broken or data is lost.
Error,
//
// Summary:
// If you have a pager, it goes off when one of these occurs.
Fatal
}

View File

@ -1,12 +0,0 @@
namespace OF_DL.Enumerations;
public enum MediaType
{
PaidPosts = 10,
Posts = 20,
Archived = 30,
Stories = 40,
Highlights = 50,
Messages = 60,
PaidMessages = 70
}

View File

@ -1,8 +0,0 @@
namespace OF_DL.Enumerations;
public enum VideoResolution
{
_240,
_720,
source
}

View File

@ -1,14 +0,0 @@
namespace OF_DL.Helpers;
public static class Constants
{
public const string ApiUrl = "https://onlyfans.com/api2/v2";
public const int ApiPageSize = 50;
public const int WidevineRetryDelay = 10;
public const int WidevineMaxRetries = 3;
public const int DrmDownloadMaxRetries = 3;
}

View File

@ -1,26 +0,0 @@
using Serilog;
namespace OF_DL.Helpers;
internal static class ExceptionLoggerHelper
{
/// <summary>
/// Logs an exception to the console and Serilog with inner exception details.
/// </summary>
/// <param name="ex">The exception to log.</param>
public static void LogException(Exception ex)
{
Console.WriteLine("Exception caught: {0}\n\nStackTrace: {1}", ex.Message, ex.StackTrace);
Log.Error("Exception caught: {0}\n\nStackTrace: {1}", ex.Message, ex.StackTrace);
if (ex.InnerException == null)
{
return;
}
Console.WriteLine("\nInner Exception:");
Console.WriteLine("Exception caught: {0}\n\nStackTrace: {1}", ex.InnerException.Message,
ex.InnerException.StackTrace);
Log.Error("Inner Exception: {0}\n\nStackTrace: {1}", ex.InnerException.Message,
ex.InnerException.StackTrace);
}
}

View File

@ -1,60 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.OfdlApi;
using Serilog;
namespace OF_DL.Helpers;
public static class VersionHelper
{
private const string Url = "https://git.ofdl.tools/api/v1/repos/sim0n00ps/OF-DL/releases/latest";
private static readonly HttpClient s_httpClient = new();
public static async Task<string?> GetLatestReleaseTag(CancellationToken cancellationToken = default)
{
Log.Debug("Calling GetLatestReleaseTag");
try
{
HttpResponseMessage response = await s_httpClient.GetAsync(Url, cancellationToken);
if (!response.IsSuccessStatusCode)
{
Log.Debug("GetLatestReleaseTag did not return a Success Status Code");
return null;
}
string body = await response.Content.ReadAsStringAsync(cancellationToken);
Log.Debug("GetLatestReleaseTag API Response: {Body}", body);
LatestReleaseApiResponse? versionCheckResponse =
JsonConvert.DeserializeObject<LatestReleaseApiResponse>(body);
if (versionCheckResponse != null && versionCheckResponse.TagName != "")
{
return versionCheckResponse.TagName;
}
Log.Debug("GetLatestReleaseTag did not return a valid tag name");
return null;
}
catch (OperationCanceledException)
{
throw; // Rethrow timeout exceptions to be handled by the caller
}
catch (Exception ex)
{
Console.WriteLine("Exception caught: {0}\n\nStackTrace: {1}", ex.Message, ex.StackTrace);
Log.Error("Exception caught: {0}\n\nStackTrace: {1}", ex.Message, ex.StackTrace);
if (ex.InnerException != null)
{
Console.WriteLine("\nInner Exception:");
Console.WriteLine("Exception caught: {0}\n\nStackTrace: {1}", ex.InnerException.Message,
ex.InnerException.StackTrace);
Log.Error("Inner Exception: {0}\n\nStackTrace: {1}", ex.InnerException.Message,
ex.InnerException.StackTrace);
}
}
return null;
}
}

View File

@ -1,21 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models;
public class Auth
{
[JsonProperty(PropertyName = "USER_ID")]
public string? UserId { get; set; } = "";
[JsonProperty(PropertyName = "USER_AGENT")]
public string? UserAgent { get; set; } = "";
[JsonProperty(PropertyName = "X_BC")] public string? XBc { get; set; } = "";
[JsonProperty(PropertyName = "COOKIE")]
public string? Cookie { get; set; } = "";
[JsonIgnore]
[JsonProperty(PropertyName = "FFMPEG_PATH")]
public string? FfmpegPath { get; set; } = "";
}

View File

@ -1,158 +0,0 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using OF_DL.Enumerations;
using Serilog;
namespace OF_DL.Models.Config;
public class Config : IFileNameFormatConfig
{
[ToggleableConfig] public bool DownloadAvatarHeaderPhoto { get; set; } = true;
[ToggleableConfig] public bool DownloadPaidPosts { get; set; } = true;
[ToggleableConfig] public bool DownloadPosts { get; set; } = true;
[ToggleableConfig] public bool DownloadArchived { get; set; } = true;
[ToggleableConfig] public bool DownloadStreams { get; set; } = true;
[ToggleableConfig] public bool DownloadStories { get; set; } = true;
[ToggleableConfig] public bool DownloadHighlights { get; set; } = true;
[ToggleableConfig] public bool DownloadMessages { get; set; } = true;
[ToggleableConfig] public bool DownloadPaidMessages { get; set; } = true;
[ToggleableConfig] public bool DownloadImages { get; set; } = true;
[ToggleableConfig] public bool DownloadVideos { get; set; } = true;
[ToggleableConfig] public bool DownloadAudios { get; set; } = true;
[ToggleableConfig] public bool IncludeExpiredSubscriptions { get; set; }
[ToggleableConfig] public bool IncludeRestrictedSubscriptions { get; set; }
[ToggleableConfig] public bool SkipAds { get; set; }
public string? DownloadPath { get; set; } = "";
[ToggleableConfig] public bool RenameExistingFilesWhenCustomFormatIsSelected { get; set; }
public int? Timeout { get; set; } = -1;
[ToggleableConfig] public bool FolderPerPaidPost { get; set; }
[ToggleableConfig] public bool FolderPerPost { get; set; }
[ToggleableConfig] public bool FolderPerPaidMessage { get; set; }
[ToggleableConfig] public bool FolderPerMessage { get; set; }
[ToggleableConfig] public bool LimitDownloadRate { get; set; }
public int DownloadLimitInMbPerSec { get; set; } = 4;
// Indicates if you want to download only on specific dates.
[ToggleableConfig] public bool DownloadOnlySpecificDates { get; set; }
// This enum will define if we want data from before or after the CustomDate.
[JsonConverter(typeof(StringEnumConverter))]
public DownloadDateSelection DownloadDateSelection { get; set; } = DownloadDateSelection.before;
// This is the specific date used in combination with the above enum.
[JsonConverter(typeof(ShortDateConverter))]
public DateTime? CustomDate { get; set; } = null;
[ToggleableConfig] public bool ShowScrapeSize { get; set; }
[ToggleableConfig] public bool DownloadPostsIncrementally { get; set; }
public bool NonInteractiveMode { get; set; }
public string NonInteractiveModeListName { get; set; } = "";
[ToggleableConfig] public bool NonInteractiveModePurchasedTab { get; set; }
public string? FFmpegPath { get; set; } = "";
public string? FFprobePath { get; set; } = "";
[ToggleableConfig] public bool BypassContentForCreatorsWhoNoLongerExist { get; set; }
public Dictionary<string, CreatorConfig> CreatorConfigs { get; set; } = new();
[ToggleableConfig] public bool DownloadDuplicatedMedia { get; set; }
public string IgnoredUsersListName { get; set; } = "";
[JsonConverter(typeof(StringEnumConverter))]
public LoggingLevel LoggingLevel { get; set; } = LoggingLevel.Error;
[ToggleableConfig] public bool IgnoreOwnMessages { get; set; }
[ToggleableConfig] public bool DisableBrowserAuth { get; set; }
[JsonConverter(typeof(StringEnumConverter))]
public VideoResolution DownloadVideoResolution { get; set; } = VideoResolution.source;
public double DrmVideoDurationMatchThreshold { get; set; } = 0.98;
// When enabled, post/message text is stored as-is without XML stripping.
[ToggleableConfig] public bool DisableTextSanitization { get; set; }
public string? PaidPostFileNameFormat { get; set; } = "";
public string? PostFileNameFormat { get; set; } = "";
public string? PaidMessageFileNameFormat { get; set; } = "";
public string? MessageFileNameFormat { get; set; } = "";
public IFileNameFormatConfig GetCreatorFileNameFormatConfig(string username)
{
FileNameFormatConfig combinedFilenameFormatConfig = new()
{
PaidPostFileNameFormat = PaidPostFileNameFormat,
PostFileNameFormat = PostFileNameFormat,
PaidMessageFileNameFormat = PaidMessageFileNameFormat,
MessageFileNameFormat = MessageFileNameFormat
};
if (CreatorConfigs.TryGetValue(username, out CreatorConfig? creatorConfig))
{
if (!string.IsNullOrEmpty(creatorConfig.PaidPostFileNameFormat))
{
combinedFilenameFormatConfig.PaidPostFileNameFormat = creatorConfig.PaidPostFileNameFormat;
}
if (!string.IsNullOrEmpty(creatorConfig.PostFileNameFormat))
{
combinedFilenameFormatConfig.PostFileNameFormat = creatorConfig.PostFileNameFormat;
}
if (!string.IsNullOrEmpty(creatorConfig.PaidMessageFileNameFormat))
{
combinedFilenameFormatConfig.PaidMessageFileNameFormat = creatorConfig.PaidMessageFileNameFormat;
}
if (!string.IsNullOrEmpty(creatorConfig.MessageFileNameFormat))
{
combinedFilenameFormatConfig.MessageFileNameFormat = creatorConfig.MessageFileNameFormat;
}
}
Log.Debug("PaidMessageFilenameFormat: {CombinedConfigPaidMessageFileNameFormat}",
combinedFilenameFormatConfig.PaidMessageFileNameFormat);
Log.Debug("PostFileNameFormat: {CombinedConfigPostFileNameFormat}",
combinedFilenameFormatConfig.PostFileNameFormat);
Log.Debug("MessageFileNameFormat: {CombinedConfigMessageFileNameFormat}",
combinedFilenameFormatConfig.MessageFileNameFormat);
Log.Debug("PaidPostFileNameFormat: {CombinedConfigPaidPostFileNameFormat}",
combinedFilenameFormatConfig.PaidPostFileNameFormat);
return combinedFilenameFormatConfig;
}
private class ShortDateConverter : IsoDateTimeConverter
{
public ShortDateConverter() => DateTimeFormat = "yyyy-MM-dd";
}
}

View File

@ -1,12 +0,0 @@
namespace OF_DL.Models.Config;
public class CreatorConfig : IFileNameFormatConfig
{
public string? PaidPostFileNameFormat { get; set; }
public string? PostFileNameFormat { get; set; }
public string? PaidMessageFileNameFormat { get; set; }
public string? MessageFileNameFormat { get; set; }
}

View File

@ -1,12 +0,0 @@
namespace OF_DL.Models.Config;
public class FileNameFormatConfig : IFileNameFormatConfig
{
public string? PaidPostFileNameFormat { get; set; }
public string? PostFileNameFormat { get; set; }
public string? PaidMessageFileNameFormat { get; set; }
public string? MessageFileNameFormat { get; set; }
}

View File

@ -1,12 +0,0 @@
namespace OF_DL.Models.Config;
public interface IFileNameFormatConfig
{
string? PaidPostFileNameFormat { get; set; }
string? PostFileNameFormat { get; set; }
string? PaidMessageFileNameFormat { get; set; }
string? MessageFileNameFormat { get; set; }
}

View File

@ -1,4 +0,0 @@
namespace OF_DL.Models.Config;
[AttributeUsage(AttributeTargets.Property)]
internal class ToggleableConfigAttribute : Attribute;

View File

@ -1,29 +0,0 @@
namespace OF_DL.Models.Downloads;
public class CreatorDownloadResult
{
public int PaidPostCount { get; set; }
public int PostCount { get; set; }
public int ArchivedCount { get; set; }
public int StreamsCount { get; set; }
public int StoriesCount { get; set; }
public int HighlightsCount { get; set; }
public int MessagesCount { get; set; }
public int PaidMessagesCount { get; set; }
}
public class UserListResult
{
public Dictionary<string, long> Users { get; set; } = new();
public Dictionary<string, long> Lists { get; set; } = new();
public string? IgnoredListError { get; set; }
}

View File

@ -1,37 +0,0 @@
namespace OF_DL.Models.Downloads;
/// <summary>
/// Represents the result of a download operation.
/// </summary>
public class DownloadResult
{
/// <summary>
/// Total number of media items processed.
/// </summary>
public int TotalCount { get; set; }
/// <summary>
/// Number of newly downloaded media items.
/// </summary>
public int NewDownloads { get; set; }
/// <summary>
/// Number of media items that were already downloaded.
/// </summary>
public int ExistingDownloads { get; set; }
/// <summary>
/// The type of media downloaded (e.g., "Posts", "Messages", "Stories", etc.).
/// </summary>
public string MediaType { get; set; } = string.Empty;
/// <summary>
/// Indicates whether the download operation was successful.
/// </summary>
public bool Success { get; set; } = true;
/// <summary>
/// Optional error message if the download failed.
/// </summary>
public string? ErrorMessage { get; set; }
}

View File

@ -1,17 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Common;
namespace OF_DL.Models.Dtos.Archived;
public class ArchivedDto
{
[JsonProperty("list")] public List<ListItemDto> List { get; set; } = [];
[JsonProperty("hasMore")] public bool HasMore { get; set; }
[JsonProperty("headMarker")] public string HeadMarker { get; set; } = "";
[JsonProperty("tailMarker")] public string TailMarker { get; set; } = "";
[JsonProperty("counters")] public CountersDto Counters { get; set; } = new();
}

View File

@ -1,11 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Common;
namespace OF_DL.Models.Dtos.Archived;
public class InfoDto
{
[JsonProperty("source")] public SourceDto Source { get; set; } = new();
[JsonProperty("preview")] public PreviewDto Preview { get; set; } = new();
}

View File

@ -1,96 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Common;
using OF_DL.Utils;
namespace OF_DL.Models.Dtos.Archived;
public class LinkedPostDto
{
private string _rawText = "";
[JsonProperty("responseType")] public string ResponseType { get; set; } = "";
[JsonProperty("id")] public long? Id { get; set; }
[JsonProperty("postedAt")] public DateTime? PostedAt { get; set; }
[JsonProperty("postedAtPrecise")] public string PostedAtPrecise { get; set; } = "";
[JsonProperty("expiredAt")] public object ExpiredAt { get; set; } = new();
[JsonProperty("author")] public AuthorDto Author { get; set; } = new();
[JsonProperty("text")] public string Text { get; set; } = "";
[JsonProperty("rawText")]
public string RawText
{
get
{
if (string.IsNullOrEmpty(_rawText))
{
_rawText = XmlUtils.EvaluateInnerText(Text);
}
return _rawText;
}
set => _rawText = value;
}
[JsonProperty("lockedText")] public bool? LockedText { get; set; }
[JsonProperty("isFavorite")] public bool? IsFavorite { get; set; }
[JsonProperty("canReport")] public bool? CanReport { get; set; }
[JsonProperty("canDelete")] public bool? CanDelete { get; set; }
[JsonProperty("canComment")] public bool? CanComment { get; set; }
[JsonProperty("canEdit")] public bool? CanEdit { get; set; }
[JsonProperty("isPinned")] public bool? IsPinned { get; set; }
[JsonProperty("favoritesCount")] public int? FavoritesCount { get; set; }
[JsonProperty("mediaCount")] public int? MediaCount { get; set; }
[JsonProperty("isMediaReady")] public bool? IsMediaReady { get; set; }
[JsonProperty("voting")] public object Voting { get; set; } = new();
[JsonProperty("isOpened")] public bool? IsOpened { get; set; }
[JsonProperty("canToggleFavorite")] public bool? CanToggleFavorite { get; set; }
[JsonProperty("streamId")] public object StreamId { get; set; } = new();
[JsonProperty("price")] public string? Price { get; set; }
[JsonProperty("hasVoting")] public bool? HasVoting { get; set; }
[JsonProperty("isAddedToBookmarks")] public bool? IsAddedToBookmarks { get; set; }
[JsonProperty("isArchived")] public bool? IsArchived { get; set; }
[JsonProperty("isPrivateArchived")] public bool? IsPrivateArchived { get; set; }
[JsonProperty("isDeleted")] public bool? IsDeleted { get; set; }
[JsonProperty("hasUrl")] public bool? HasUrl { get; set; }
[JsonProperty("isCouplePeopleMedia")] public bool? IsCouplePeopleMedia { get; set; }
[JsonProperty("cantCommentReason")] public string CantCommentReason { get; set; } = "";
[JsonProperty("commentsCount")] public int? CommentsCount { get; set; }
[JsonProperty("mentionedUsers")] public List<object> MentionedUsers { get; set; } = [];
[JsonProperty("linkedUsers")] public List<object> LinkedUsers { get; set; } = [];
[JsonProperty("media")] public List<MediumDto> Media { get; set; } = [];
[JsonProperty("canViewMedia")] public bool? CanViewMedia { get; set; }
[JsonProperty("preview")] public List<object> Preview { get; set; } = [];
}

View File

@ -1,97 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Common;
using OF_DL.Utils;
namespace OF_DL.Models.Dtos.Archived;
public class ListItemDto
{
private string _rawText = "";
[JsonProperty("responseType")] public string ResponseType { get; set; } = "";
[JsonProperty("id")] public long Id { get; set; }
[JsonProperty("postedAt")] public DateTime PostedAt { get; set; }
[JsonProperty("postedAtPrecise")] public string PostedAtPrecise { get; set; } = "";
[JsonProperty("expiredAt")] public object ExpiredAt { get; set; } = new();
[JsonProperty("author")] public AuthorDto Author { get; set; } = new();
[JsonProperty("text")] public string Text { get; set; } = "";
[JsonProperty("rawText")]
public string RawText
{
get
{
if (string.IsNullOrEmpty(_rawText))
{
_rawText = XmlUtils.EvaluateInnerText(Text);
}
return _rawText;
}
set => _rawText = value;
}
[JsonProperty("lockedText")] public bool? LockedText { get; set; }
[JsonProperty("isFavorite")] public bool? IsFavorite { get; set; }
[JsonProperty("canReport")] public bool? CanReport { get; set; }
[JsonProperty("canDelete")] public bool? CanDelete { get; set; }
[JsonProperty("canComment")] public bool? CanComment { get; set; }
[JsonProperty("canEdit")] public bool? CanEdit { get; set; }
[JsonProperty("isPinned")] public bool? IsPinned { get; set; }
[JsonProperty("favoritesCount")] public int? FavoritesCount { get; set; }
[JsonProperty("mediaCount")] public int? MediaCount { get; set; }
[JsonProperty("isMediaReady")] public bool? IsMediaReady { get; set; }
[JsonProperty("voting")] public object Voting { get; set; } = new();
[JsonProperty("isOpened")] public bool IsOpened { get; set; }
[JsonProperty("canToggleFavorite")] public bool? CanToggleFavorite { get; set; }
[JsonProperty("streamId")] public object StreamId { get; set; } = new();
[JsonProperty("price")] public string Price { get; set; } = "";
[JsonProperty("hasVoting")] public bool? HasVoting { get; set; }
[JsonProperty("isAddedToBookmarks")] public bool? IsAddedToBookmarks { get; set; }
[JsonProperty("isArchived")] public bool IsArchived { get; set; }
[JsonProperty("isPrivateArchived")] public bool? IsPrivateArchived { get; set; }
[JsonProperty("isDeleted")] public bool? IsDeleted { get; set; }
[JsonProperty("hasUrl")] public bool? HasUrl { get; set; }
[JsonProperty("isCouplePeopleMedia")] public bool? IsCouplePeopleMedia { get; set; }
[JsonProperty("commentsCount")] public int? CommentsCount { get; set; }
[JsonProperty("mentionedUsers")] public List<object> MentionedUsers { get; set; } = [];
[JsonProperty("linkedUsers")] public List<object> LinkedUsers { get; set; } = [];
[JsonProperty("media")] public List<MediumDto> Media { get; set; } = [];
[JsonProperty("canViewMedia")] public bool? CanViewMedia { get; set; }
[JsonProperty("preview")] public List<object> Preview { get; set; } = [];
[JsonProperty("cantCommentReason")] public string CantCommentReason { get; set; } = "";
}

View File

@ -1,35 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Common;
namespace OF_DL.Models.Dtos.Archived;
public class MediumDto
{
[JsonProperty("id")] public long Id { get; set; }
[JsonProperty("type")] public string Type { get; set; } = "";
[JsonProperty("convertedToVideo")] public bool? ConvertedToVideo { get; set; }
[JsonProperty("canView")] public bool CanView { get; set; }
[JsonProperty("hasError")] public bool? HasError { get; set; }
[JsonProperty("createdAt")] public DateTime? CreatedAt { get; set; } = new();
[JsonProperty("info")] public InfoDto Info { get; set; } = new();
[JsonProperty("source")] public SourceDto Source { get; set; } = new();
[JsonProperty("squarePreview")] public string SquarePreview { get; set; } = "";
[JsonProperty("full")] public string Full { get; set; } = "";
[JsonProperty("preview")] public string Preview { get; set; } = "";
[JsonProperty("thumb")] public string Thumb { get; set; } = "";
[JsonProperty("files")] public FilesDto Files { get; set; } = new();
[JsonProperty("videoSources")] public VideoSourcesDto VideoSources { get; set; } = new();
}

View File

@ -1,10 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Common;
public class AuthorDto
{
[JsonProperty("id")] public long Id { get; set; }
[JsonProperty("_view")] public string View { get; set; } = "";
}

View File

@ -1,10 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Common;
public class AvatarThumbsDto
{
[JsonProperty("c50")] public string C50 { get; set; } = "";
[JsonProperty("c144")] public string C144 { get; set; } = "";
}

View File

@ -1,20 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Common;
public class CountersDto
{
[JsonProperty("audiosCount")] public int? AudiosCount { get; set; }
[JsonProperty("photosCount")] public int? PhotosCount { get; set; }
[JsonProperty("videosCount")] public int? VideosCount { get; set; }
[JsonProperty("mediasCount")] public int? MediasCount { get; set; }
[JsonProperty("postsCount")] public int? PostsCount { get; set; }
[JsonProperty("streamsCount")] public int? StreamsCount { get; set; }
[JsonProperty("archivedPostsCount")] public int? ArchivedPostsCount { get; set; }
}

View File

@ -1,13 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Common;
public class DashDto
{
[JsonProperty("CloudFront-Policy")] public string CloudFrontPolicy { get; set; } = "";
[JsonProperty("CloudFront-Signature")] public string CloudFrontSignature { get; set; } = "";
[JsonProperty("CloudFront-Key-Pair-Id")]
public string CloudFrontKeyPairId { get; set; } = "";
}

View File

@ -1,10 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Common;
public class DrmDto
{
[JsonProperty("manifest")] public ManifestDto Manifest { get; set; } = new();
[JsonProperty("signature")] public SignatureDto Signature { get; set; } = new();
}

View File

@ -1,17 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Common;
public class FilesDto
{
[JsonProperty("full")] public FullDto Full { get; set; } = new();
[JsonProperty("thumb")] public ThumbDto Thumb { get; set; } = new();
[JsonProperty("preview")] public PreviewDto Preview { get; set; } = new();
[JsonProperty("squarePreview")] public SquarePreviewDto SquarePreview { get; set; } = new();
[JsonProperty("drm")] public DrmDto? Drm { get; set; }
}

View File

@ -1,16 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Common;
public class FullDto
{
[JsonProperty("url")] public string Url { get; set; } = "";
[JsonProperty("width")] public int Width { get; set; }
[JsonProperty("height")] public int Height { get; set; }
[JsonProperty("size")] public long Size { get; set; }
[JsonProperty("sources")] public List<object> Sources { get; set; } = [];
}

View File

@ -1,10 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Common;
public class HeaderSizeDto
{
[JsonProperty("width")] public int Width { get; set; }
[JsonProperty("height")] public int Height { get; set; }
}

View File

@ -1,10 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Common;
public class HeaderThumbsDto
{
[JsonProperty("w480")] public string W480 { get; set; } = "";
[JsonProperty("w760")] public string W760 { get; set; } = "";
}

View File

@ -1,13 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Common;
public class HlsDto
{
[JsonProperty("CloudFront-Policy")] public string CloudFrontPolicy { get; set; } = "";
[JsonProperty("CloudFront-Signature")] public string CloudFrontSignature { get; set; } = "";
[JsonProperty("CloudFront-Key-Pair-Id")]
public string CloudFrontKeyPairId { get; set; } = "";
}

View File

@ -1,10 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Common;
public class ManifestDto
{
[JsonProperty("hls")] public string Hls { get; set; } = "";
[JsonProperty("dash")] public string Dash { get; set; } = "";
}

View File

@ -1,16 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Common;
public class PreviewDto
{
[JsonProperty("width")] public int? Width { get; set; }
[JsonProperty("height")] public int? Height { get; set; }
[JsonProperty("size")] public int? Size { get; set; }
[JsonProperty("url")] public string Url { get; set; } = "";
[JsonProperty("sources")] public SourcesDto Sources { get; set; } = new();
}

View File

@ -1,10 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Common;
public class SignatureDto
{
[JsonProperty("hls")] public HlsDto Hls { get; set; } = new();
[JsonProperty("dash")] public DashDto Dash { get; set; } = new();
}

View File

@ -1,18 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Common;
public class SourceDto
{
[JsonProperty("url")] public string Url { get; set; } = "";
[JsonProperty("width")] public int Width { get; set; }
[JsonProperty("height")] public int Height { get; set; }
[JsonProperty("duration")] public int Duration { get; set; }
[JsonProperty("size")] public long Size { get; set; }
[JsonProperty("sources")] public SourcesDto Sources { get; set; } = new();
}

View File

@ -1,14 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Common;
public class SourcesDto
{
[JsonProperty("720")] public string _720 { get; set; } = "";
[JsonProperty("240")] public string _240 { get; set; } = "";
[JsonProperty("w150")] public string W150 { get; set; } = "";
[JsonProperty("w480")] public string W480 { get; set; } = "";
}

View File

@ -1,16 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Common;
public class SquarePreviewDto
{
[JsonProperty("url")] public string Url { get; set; } = "";
[JsonProperty("width")] public int Width { get; set; }
[JsonProperty("height")] public int Height { get; set; }
[JsonProperty("size")] public long Size { get; set; }
[JsonProperty("sources")] public SourcesDto Sources { get; set; } = new();
}

View File

@ -1,44 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Subscriptions;
namespace OF_DL.Models.Dtos.Common;
public class SubscribedByDataDto
{
[JsonProperty("price")] public string? Price { get; set; }
[JsonProperty("newPrice")] public string? NewPrice { get; set; }
[JsonProperty("regularPrice")] public string? RegularPrice { get; set; }
[JsonProperty("subscribePrice")] public string? SubscribePrice { get; set; }
[JsonProperty("discountPercent")] public int? DiscountPercent { get; set; }
[JsonProperty("discountPeriod")] public int? DiscountPeriod { get; set; }
[JsonProperty("subscribeAt")] public DateTime? SubscribeAt { get; set; }
[JsonProperty("expiredAt")] public DateTime? ExpiredAt { get; set; }
[JsonProperty("renewedAt")] public DateTime? RenewedAt { get; set; }
[JsonProperty("discountFinishedAt")] public object? DiscountFinishedAt { get; set; } = new();
[JsonProperty("discountStartedAt")] public object? DiscountStartedAt { get; set; } = new();
[JsonProperty("status")] public string Status { get; set; } = "";
[JsonProperty("isMuted")] public bool? IsMuted { get; set; }
[JsonProperty("unsubscribeReason")] public string UnsubscribeReason { get; set; } = "";
[JsonProperty("duration")] public string Duration { get; set; } = "";
[JsonProperty("showPostsInFeed")] public bool? ShowPostsInFeed { get; set; }
[JsonProperty("subscribes")] public List<SubscribeDto> Subscribes { get; set; } = [];
[JsonProperty("hasActivePaidSubscriptions")]
public bool? HasActivePaidSubscriptions { get; set; }
}

View File

@ -1,54 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Subscriptions;
namespace OF_DL.Models.Dtos.Common;
public class SubscribedOnDataDto
{
[JsonProperty("price")] public string? Price { get; set; }
[JsonProperty("newPrice")] public string? NewPrice { get; set; }
[JsonProperty("regularPrice")] public string? RegularPrice { get; set; }
[JsonProperty("subscribePrice")] public string? SubscribePrice { get; set; }
[JsonProperty("discountPercent")] public int? DiscountPercent { get; set; }
[JsonProperty("discountPeriod")] public int? DiscountPeriod { get; set; }
[JsonProperty("subscribeAt")] public DateTime? SubscribeAt { get; set; }
[JsonProperty("expiredAt")] public DateTime? ExpiredAt { get; set; }
[JsonProperty("renewedAt")] public DateTime? RenewedAt { get; set; }
[JsonProperty("discountFinishedAt")] public object? DiscountFinishedAt { get; set; } = new();
[JsonProperty("discountStartedAt")] public object? DiscountStartedAt { get; set; } = new();
[JsonProperty("status")] public object? Status { get; set; }
[JsonProperty("isMuted")] public bool? IsMuted { get; set; }
[JsonProperty("unsubscribeReason")] public string? UnsubscribeReason { get; set; } = "";
[JsonProperty("duration")] public string Duration { get; set; } = "";
[JsonProperty("tipsSumm")] public string? TipsSumm { get; set; }
[JsonProperty("subscribesSumm")] public string? SubscribesSumm { get; set; }
[JsonProperty("messagesSumm")] public string? MessagesSumm { get; set; }
[JsonProperty("postsSumm")] public string? PostsSumm { get; set; }
[JsonProperty("streamsSumm")] public string? StreamsSumm { get; set; }
[JsonProperty("totalSumm")] public string? TotalSumm { get; set; }
[JsonProperty("subscribes")] public List<SubscribeDto> Subscribes { get; set; } = [];
[JsonProperty("hasActivePaidSubscriptions")]
public bool? HasActivePaidSubscriptions { get; set; }
}

View File

@ -1,14 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Common;
public class ThumbDto
{
[JsonProperty("url")] public string Url { get; set; } = "";
[JsonProperty("width")] public int Width { get; set; }
[JsonProperty("height")] public int Height { get; set; }
[JsonProperty("size")] public long Size { get; set; }
}

View File

@ -1,8 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Common;
public class VideoDto
{
[JsonProperty("mp4")] public string Mp4 { get; set; } = "";
}

View File

@ -1,10 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Common;
public class VideoSourcesDto
{
[JsonProperty("720")] public string _720 { get; set; } = "";
[JsonProperty("240")] public string _240 { get; set; } = "";
}

View File

@ -1,22 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Highlights;
public class HighlightMediaDto
{
[JsonProperty("id")] public long Id { get; set; }
[JsonProperty("userId")] public long UserId { get; set; }
[JsonProperty("title")] public string Title { get; set; } = "";
[JsonProperty("coverStoryId")] public long CoverStoryId { get; set; }
[JsonProperty("cover")] public string Cover { get; set; } = "";
[JsonProperty("storiesCount")] public int StoriesCount { get; set; }
[JsonProperty("createdAt")] public DateTime? CreatedAt { get; set; }
[JsonProperty("stories")] public List<StoryDto> Stories { get; set; } = [];
}

View File

@ -1,10 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Highlights;
public class HighlightsDto
{
[JsonProperty("list")] public List<ListItemDto> List { get; set; } = [];
[JsonProperty("hasMore")] public bool HasMore { get; set; }
}

View File

@ -1,20 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Highlights;
public class ListItemDto
{
[JsonProperty("id")] public long Id { get; set; }
[JsonProperty("userId")] public long UserId { get; set; }
[JsonProperty("title")] public string Title { get; set; } = "";
[JsonProperty("coverStoryId")] public long CoverStoryId { get; set; }
[JsonProperty("cover")] public string Cover { get; set; } = "";
[JsonProperty("storiesCount")] public int StoriesCount { get; set; }
[JsonProperty("createdAt")] public DateTime? CreatedAt { get; set; }
}

View File

@ -1,21 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Common;
namespace OF_DL.Models.Dtos.Highlights;
public class MediumDto
{
[JsonProperty("id")] public long Id { get; set; }
[JsonProperty("type")] public string Type { get; set; } = "";
[JsonProperty("convertedToVideo")] public bool ConvertedToVideo { get; set; }
[JsonProperty("canView")] public bool CanView { get; set; }
[JsonProperty("hasError")] public bool HasError { get; set; }
[JsonProperty("createdAt")] public DateTime? CreatedAt { get; set; }
[JsonProperty("files")] public FilesDto Files { get; set; } = new();
}

View File

@ -1,24 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Highlights;
public class StoryDto
{
[JsonProperty("id")] public long Id { get; set; }
[JsonProperty("userId")] public long UserId { get; set; }
[JsonProperty("isWatched")] public bool IsWatched { get; set; }
[JsonProperty("isReady")] public bool IsReady { get; set; }
[JsonProperty("media")] public List<MediumDto> Media { get; set; } = [];
[JsonProperty("createdAt")] public DateTime? CreatedAt { get; set; }
[JsonProperty("question")] public object Question { get; set; } = new();
[JsonProperty("canLike")] public bool CanLike { get; set; }
[JsonProperty("isLiked")] public bool IsLiked { get; set; }
}

View File

@ -1,10 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Lists;
public class HeaderSizeDto
{
[JsonProperty("width")] public int? Width { get; set; }
[JsonProperty("height")] public int? Height { get; set; }
}

View File

@ -1,10 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Lists;
public class HeaderThumbsDto
{
[JsonProperty("w480")] public string W480 { get; set; } = "";
[JsonProperty("w760")] public string W760 { get; set; } = "";
}

View File

@ -1,16 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Lists;
public class ListsStateDto
{
[JsonProperty("id")] public string Id { get; set; } = "";
[JsonProperty("type")] public string Type { get; set; } = "";
[JsonProperty("name")] public string Name { get; set; } = "";
[JsonProperty("hasUser")] public bool HasUser { get; set; }
[JsonProperty("canAddUser")] public bool CanAddUser { get; set; }
}

View File

@ -1,38 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Lists;
public class SubscribeDto
{
[JsonProperty("id")] public object Id { get; set; } = new();
[JsonProperty("userId")] public long? UserId { get; set; }
[JsonProperty("subscriberId")] public int? SubscriberId { get; set; }
[JsonProperty("date")] public DateTime? Date { get; set; }
[JsonProperty("duration")] public int? Duration { get; set; }
[JsonProperty("startDate")] public DateTime? StartDate { get; set; }
[JsonProperty("expireDate")] public DateTime? ExpireDate { get; set; }
[JsonProperty("cancelDate")] public object CancelDate { get; set; } = new();
[JsonProperty("price")] public string? Price { get; set; }
[JsonProperty("regularPrice")] public string? RegularPrice { get; set; }
[JsonProperty("discount")] public string? Discount { get; set; }
[JsonProperty("action")] public string Action { get; set; } = "";
[JsonProperty("type")] public string Type { get; set; } = "";
[JsonProperty("offerStart")] public object OfferStart { get; set; } = new();
[JsonProperty("offerEnd")] public object OfferEnd { get; set; } = new();
[JsonProperty("isCurrent")] public bool? IsCurrent { get; set; }
}

View File

@ -1,40 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Lists;
public class SubscribedByDataDto
{
[JsonProperty("price")] public string? Price { get; set; }
[JsonProperty("newPrice")] public string? NewPrice { get; set; }
[JsonProperty("regularPrice")] public string? RegularPrice { get; set; }
[JsonProperty("subscribePrice")] public string? SubscribePrice { get; set; }
[JsonProperty("discountPercent")] public string? DiscountPercent { get; set; }
[JsonProperty("discountPeriod")] public string? DiscountPeriod { get; set; }
[JsonProperty("subscribeAt")] public DateTime? SubscribeAt { get; set; }
[JsonProperty("expiredAt")] public DateTime? ExpiredAt { get; set; }
[JsonProperty("renewedAt")] public object RenewedAt { get; set; } = new();
[JsonProperty("discountFinishedAt")] public object DiscountFinishedAt { get; set; } = new();
[JsonProperty("discountStartedAt")] public object DiscountStartedAt { get; set; } = new();
[JsonProperty("status")] public string Status { get; set; } = "";
[JsonProperty("isMuted")] public bool? IsMuted { get; set; }
[JsonProperty("unsubscribeReason")] public string UnsubscribeReason { get; set; } = "";
[JsonProperty("duration")] public string Duration { get; set; } = "";
[JsonProperty("showPostsInFeed")] public bool? ShowPostsInFeed { get; set; }
[JsonProperty("subscribes")] public List<SubscribeDto> Subscribes { get; set; } = [];
}

View File

@ -1,54 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Lists;
public class SubscribedOnDataDto
{
[JsonProperty("price")] public string? Price { get; set; }
[JsonProperty("newPrice")] public string? NewPrice { get; set; }
[JsonProperty("regularPrice")] public string? RegularPrice { get; set; }
[JsonProperty("subscribePrice")] public string? SubscribePrice { get; set; }
[JsonProperty("discountPercent")] public string? DiscountPercent { get; set; }
[JsonProperty("discountPeriod")] public string? DiscountPeriod { get; set; }
[JsonProperty("subscribeAt")] public DateTime? SubscribeAt { get; set; }
[JsonProperty("expiredAt")] public DateTime? ExpiredAt { get; set; }
[JsonProperty("renewedAt")] public object RenewedAt { get; set; } = new();
[JsonProperty("discountFinishedAt")] public object DiscountFinishedAt { get; set; } = new();
[JsonProperty("discountStartedAt")] public object DiscountStartedAt { get; set; } = new();
[JsonProperty("status")] public object Status { get; set; } = new();
[JsonProperty("isMuted")] public bool? IsMuted { get; set; }
[JsonProperty("unsubscribeReason")] public string UnsubscribeReason { get; set; } = "";
[JsonProperty("duration")] public string Duration { get; set; } = "";
[JsonProperty("tipsSumm")] public string? TipsSumm { get; set; }
[JsonProperty("subscribesSumm")] public string? SubscribesSumm { get; set; }
[JsonProperty("messagesSumm")] public string? MessagesSumm { get; set; }
[JsonProperty("postsSumm")] public string? PostsSumm { get; set; }
[JsonProperty("streamsSumm")] public string? StreamsSumm { get; set; }
[JsonProperty("totalSumm")] public string? TotalSumm { get; set; }
[JsonProperty("lastActivity")] public DateTime? LastActivity { get; set; }
[JsonProperty("recommendations")] public int? Recommendations { get; set; }
[JsonProperty("subscribes")] public List<object> Subscribes { get; set; } = [];
}

View File

@ -1,16 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Lists;
public class SubscriptionBundleDto
{
[JsonProperty("id")] public long? Id { get; set; }
[JsonProperty("discount")] public string? Discount { get; set; }
[JsonProperty("duration")] public string? Duration { get; set; }
[JsonProperty("price")] public string? Price { get; set; }
[JsonProperty("canBuy")] public bool? CanBuy { get; set; }
}

View File

@ -1,10 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Lists;
public class UserListDto
{
[JsonProperty("list")] public List<UserListItemDto> List { get; set; } = [];
[JsonProperty("hasMore")] public bool? HasMore { get; set; }
}

View File

@ -1,42 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Lists;
public class UserListItemDto
{
[JsonProperty("id")] public string Id { get; set; } = "";
[JsonProperty("type")] public string Type { get; set; } = "";
[JsonProperty("name")] public string Name { get; set; } = "";
[JsonProperty("usersCount")] public int? UsersCount { get; set; }
[JsonProperty("postsCount")] public int? PostsCount { get; set; }
[JsonProperty("canUpdate")] public bool? CanUpdate { get; set; }
[JsonProperty("canDelete")] public bool? CanDelete { get; set; }
[JsonProperty("canManageUsers")] public bool? CanManageUsers { get; set; }
[JsonProperty("canAddUsers")] public bool? CanAddUsers { get; set; }
[JsonProperty("canPinnedToFeed")] public bool? CanPinnedToFeed { get; set; }
[JsonProperty("isPinnedToFeed")] public bool? IsPinnedToFeed { get; set; }
[JsonProperty("canPinnedToChat")] public bool? CanPinnedToChat { get; set; }
[JsonProperty("isPinnedToChat")] public bool? IsPinnedToChat { get; set; }
[JsonProperty("order")] public string Order { get; set; } = "";
[JsonProperty("direction")] public string Direction { get; set; } = "";
[JsonProperty("users")] public List<UserListUserDto> Users { get; set; } = [];
[JsonProperty("customOrderUsersIds")] public List<object> CustomOrderUsersIds { get; set; } = [];
[JsonProperty("posts")] public List<object> Posts { get; set; } = [];
}

View File

@ -1,10 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Lists;
public class UserListUserDto
{
[JsonProperty("id")] public long? Id { get; set; }
[JsonProperty("_view")] public string View { get; set; } = "";
}

View File

@ -1,121 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Common;
namespace OF_DL.Models.Dtos.Lists;
public class UsersListDto
{
[JsonProperty("view")] public string View { get; set; } = "";
[JsonProperty("avatar")] public string Avatar { get; set; } = "";
[JsonProperty("avatarThumbs")] public AvatarThumbsDto AvatarThumbs { get; set; } = new();
[JsonProperty("header")] public string Header { get; set; } = "";
[JsonProperty("headerSize")] public HeaderSizeDto HeaderSize { get; set; } = new();
[JsonProperty("headerThumbs")] public HeaderThumbsDto HeaderThumbs { get; set; } = new();
[JsonProperty("id")] public long? Id { get; set; }
[JsonProperty("name")] public string Name { get; set; } = "";
[JsonProperty("username")] public string Username { get; set; } = "";
[JsonProperty("canLookStory")] public bool? CanLookStory { get; set; }
[JsonProperty("canCommentStory")] public bool? CanCommentStory { get; set; }
[JsonProperty("hasNotViewedStory")] public bool? HasNotViewedStory { get; set; }
[JsonProperty("isVerified")] public bool? IsVerified { get; set; }
[JsonProperty("canPayInternal")] public bool? CanPayInternal { get; set; }
[JsonProperty("hasScheduledStream")] public bool? HasScheduledStream { get; set; }
[JsonProperty("hasStream")] public bool? HasStream { get; set; }
[JsonProperty("hasStories")] public bool? HasStories { get; set; }
[JsonProperty("tipsEnabled")] public bool? TipsEnabled { get; set; }
[JsonProperty("tipsTextEnabled")] public bool? TipsTextEnabled { get; set; }
[JsonProperty("tipsMin")] public int? TipsMin { get; set; }
[JsonProperty("tipsMinInternal")] public int? TipsMinInternal { get; set; }
[JsonProperty("tipsMax")] public int? TipsMax { get; set; }
[JsonProperty("canEarn")] public bool? CanEarn { get; set; }
[JsonProperty("canAddSubscriber")] public bool? CanAddSubscriber { get; set; }
[JsonProperty("subscribePrice")] public string? SubscribePrice { get; set; }
[JsonProperty("subscriptionBundles")] public List<SubscriptionBundleDto> SubscriptionBundles { get; set; } = [];
[JsonProperty("displayName")] public string DisplayName { get; set; } = "";
[JsonProperty("notice")] public string Notice { get; set; } = "";
[JsonProperty("isPaywallRequired")] public bool? IsPaywallRequired { get; set; }
[JsonProperty("unprofitable")] public bool? Unprofitable { get; set; }
[JsonProperty("listsStates")] public List<ListsStateDto> ListsStates { get; set; } = [];
[JsonProperty("isMuted")] public bool? IsMuted { get; set; }
[JsonProperty("isRestricted")] public bool? IsRestricted { get; set; }
[JsonProperty("canRestrict")] public bool? CanRestrict { get; set; }
[JsonProperty("subscribedBy")] public bool? SubscribedBy { get; set; }
[JsonProperty("subscribedByExpire")] public bool? SubscribedByExpire { get; set; }
[JsonProperty("subscribedByExpireDate")]
public DateTime? SubscribedByExpireDate { get; set; }
[JsonProperty("subscribedByAutoprolong")]
public bool? SubscribedByAutoprolong { get; set; }
[JsonProperty("subscribedIsExpiredNow")]
public bool? SubscribedIsExpiredNow { get; set; }
[JsonProperty("currentSubscribePrice")]
public string? CurrentSubscribePrice { get; set; }
[JsonProperty("subscribedOn")] public bool? SubscribedOn { get; set; }
[JsonProperty("subscribedOnExpiredNow")]
public bool? SubscribedOnExpiredNow { get; set; }
[JsonProperty("subscribedOnDuration")] public string SubscribedOnDuration { get; set; } = "";
[JsonProperty("canReport")] public bool? CanReport { get; set; }
[JsonProperty("canReceiveChatMessage")]
public bool? CanReceiveChatMessage { get; set; }
[JsonProperty("hideChat")] public bool? HideChat { get; set; }
[JsonProperty("lastSeen")] public DateTime? LastSeen { get; set; }
[JsonProperty("isPerformer")] public bool? IsPerformer { get; set; }
[JsonProperty("isRealPerformer")] public bool? IsRealPerformer { get; set; }
[JsonProperty("subscribedByData")] public SubscribedByDataDto SubscribedByData { get; set; } = new();
[JsonProperty("subscribedOnData")] public SubscribedOnDataDto SubscribedOnData { get; set; } = new();
[JsonProperty("canTrialSend")] public bool? CanTrialSend { get; set; }
[JsonProperty("isBlocked")] public bool? IsBlocked { get; set; }
[JsonProperty("promoOffers")] public List<object> PromoOffers { get; set; } = [];
}

View File

@ -1,98 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Common;
namespace OF_DL.Models.Dtos.Messages;
public class FromUserDto
{
[JsonProperty("_view")] public string ViewRaw { get; set; } = "";
[JsonProperty("view")] public string View { get; set; } = "";
[JsonProperty("avatar")] public string Avatar { get; set; } = "";
[JsonProperty("avatarThumbs")] public AvatarThumbsDto AvatarThumbs { get; set; } = new();
[JsonProperty("header")] public string Header { get; set; } = "";
[JsonProperty("headerSize")] public HeaderSizeDto HeaderSize { get; set; } = new();
[JsonProperty("headerThumbs")] public HeaderThumbsDto HeaderThumbs { get; set; } = new();
[JsonProperty("id")] public long? Id { get; set; }
[JsonProperty("name")] public string Name { get; set; } = "";
[JsonProperty("username")] public string Username { get; set; } = "";
[JsonProperty("canLookStory")] public bool CanLookStory { get; set; }
[JsonProperty("canCommentStory")] public bool CanCommentStory { get; set; }
[JsonProperty("hasNotViewedStory")] public bool HasNotViewedStory { get; set; }
[JsonProperty("isVerified")] public bool IsVerified { get; set; }
[JsonProperty("canPayInternal")] public bool CanPayInternal { get; set; }
[JsonProperty("hasScheduledStream")] public bool HasScheduledStream { get; set; }
[JsonProperty("hasStream")] public bool HasStream { get; set; }
[JsonProperty("hasStories")] public bool HasStories { get; set; }
[JsonProperty("tipsEnabled")] public bool TipsEnabled { get; set; }
[JsonProperty("tipsTextEnabled")] public bool TipsTextEnabled { get; set; }
[JsonProperty("tipsMin")] public int TipsMin { get; set; }
[JsonProperty("tipsMinInternal")] public int TipsMinInternal { get; set; }
[JsonProperty("tipsMax")] public int TipsMax { get; set; }
[JsonProperty("canEarn")] public bool CanEarn { get; set; }
[JsonProperty("canAddSubscriber")] public bool CanAddSubscriber { get; set; }
[JsonProperty("subscribePrice")] public string SubscribePrice { get; set; } = "";
[JsonProperty("subscriptionBundles")] public List<object> SubscriptionBundles { get; set; } = [];
[JsonProperty("isPaywallRequired")] public bool IsPaywallRequired { get; set; }
[JsonProperty("listsStates")] public List<ListsStateDto> ListsStates { get; set; } = [];
[JsonProperty("isRestricted")] public bool IsRestricted { get; set; }
[JsonProperty("canRestrict")] public bool CanRestrict { get; set; }
[JsonProperty("subscribedBy")] public object SubscribedBy { get; set; } = new();
[JsonProperty("subscribedByExpire")] public object SubscribedByExpire { get; set; } = new();
[JsonProperty("subscribedByExpireDate")]
public DateTime? SubscribedByExpireDate { get; set; }
[JsonProperty("subscribedByAutoprolong")]
public object SubscribedByAutoprolong { get; set; } = new();
[JsonProperty("subscribedIsExpiredNow")]
public bool SubscribedIsExpiredNow { get; set; }
[JsonProperty("currentSubscribePrice")]
public object CurrentSubscribePrice { get; set; } = new();
[JsonProperty("subscribedOn")] public object SubscribedOn { get; set; } = new();
[JsonProperty("subscribedOnExpiredNow")]
public object SubscribedOnExpiredNow { get; set; } = new();
[JsonProperty("subscribedOnDuration")] public object SubscribedOnDuration { get; set; } = new();
[JsonProperty("callPrice")] public int CallPrice { get; set; }
[JsonProperty("lastSeen")] public DateTime? LastSeen { get; set; }
[JsonProperty("canReport")] public bool CanReport { get; set; }
}

View File

@ -1,11 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Common;
namespace OF_DL.Models.Dtos.Messages;
public class InfoDto
{
[JsonProperty("source")] public SourceDto Source { get; set; } = new();
[JsonProperty("preview")] public PreviewDto Preview { get; set; } = new();
}

View File

@ -1,66 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Messages;
public class ListItemDto
{
[JsonProperty("responseType")] public string ResponseType { get; set; } = "";
[JsonProperty("text")] public string Text { get; set; } = "";
[JsonProperty("giphyId")] public object GiphyId { get; set; } = new();
[JsonProperty("lockedText")] public bool? LockedText { get; set; }
[JsonProperty("isFree")] public bool? IsFree { get; set; }
[JsonProperty("price")] public string Price { get; set; } = "";
[JsonProperty("isMediaReady")] public bool? IsMediaReady { get; set; }
[JsonProperty("mediaCount")] public int? MediaCount { get; set; }
[JsonProperty("media")] public List<MediumDto> Media { get; set; } = [];
[JsonProperty("previews")] public List<object> Previews { get; set; } = [];
[JsonProperty("isTip")] public bool? IsTip { get; set; }
[JsonProperty("isReportedByMe")] public bool? IsReportedByMe { get; set; }
[JsonProperty("isCouplePeopleMedia")] public bool? IsCouplePeopleMedia { get; set; }
[JsonProperty("queueId")] public object QueueId { get; set; } = new();
[JsonProperty("fromUser")] public FromUserDto FromUser { get; set; } = new();
[JsonProperty("isFromQueue")] public bool? IsFromQueue { get; set; }
[JsonProperty("canUnsendQueue")] public bool? CanUnsendQueue { get; set; }
[JsonProperty("unsendSecondsQueue")] public int? UnsendSecondsQueue { get; set; }
[JsonProperty("id")] public long Id { get; set; }
[JsonProperty("isOpened")] public bool? IsOpened { get; set; }
[JsonProperty("isNew")] public bool? IsNew { get; set; }
[JsonProperty("createdAt")] public DateTime? CreatedAt { get; set; }
[JsonProperty("changedAt")] public DateTime? ChangedAt { get; set; }
[JsonProperty("cancelSeconds")] public int? CancelSeconds { get; set; }
[JsonProperty("isLiked")] public bool? IsLiked { get; set; }
[JsonProperty("canPurchase")] public bool? CanPurchase { get; set; }
[JsonProperty("canPurchaseReason")] public string CanPurchaseReason { get; set; } = "";
[JsonProperty("canReport")] public bool? CanReport { get; set; }
[JsonProperty("canBePinned")] public bool? CanBePinned { get; set; }
[JsonProperty("isPinned")] public bool? IsPinned { get; set; }
}

View File

@ -1,18 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Messages;
public class ListsStateDto
{
[JsonProperty("id")] public string Id { get; set; } = "";
[JsonProperty("type")] public string Type { get; set; } = "";
[JsonProperty("name")] public string Name { get; set; } = "";
[JsonProperty("hasUser")] public bool HasUser { get; set; }
[JsonProperty("canAddUser")] public bool CanAddUser { get; set; }
[JsonProperty("cannotAddUserReason")] public string CannotAddUserReason { get; set; } = "";
}

View File

@ -1,37 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Common;
namespace OF_DL.Models.Dtos.Messages;
public class MediumDto
{
[JsonProperty("id")] public long Id { get; set; }
[JsonProperty("canView")] public bool CanView { get; set; }
[JsonProperty("type")] public string Type { get; set; } = "";
[JsonProperty("src")] public string Src { get; set; } = "";
[JsonProperty("preview")] public string Preview { get; set; } = "";
[JsonProperty("thumb")] public string Thumb { get; set; } = "";
[JsonProperty("locked")] public object Locked { get; set; } = new();
[JsonProperty("duration")] public int? Duration { get; set; }
[JsonProperty("hasError")] public bool? HasError { get; set; }
[JsonProperty("squarePreview")] public string SquarePreview { get; set; } = "";
[JsonProperty("video")] public VideoDto Video { get; set; } = new();
[JsonProperty("videoSources")] public VideoSourcesDto VideoSources { get; set; } = new();
[JsonProperty("source")] public SourceDto Source { get; set; } = new();
[JsonProperty("info")] public InfoDto Info { get; set; } = new();
[JsonProperty("files")] public FilesDto Files { get; set; } = new();
}

View File

@ -1,10 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Messages;
public class MessagesDto
{
[JsonProperty("list")] public List<ListItemDto> List { get; set; } = [];
[JsonProperty("hasMore")] public bool HasMore { get; set; }
}

View File

@ -1,60 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Messages;
public class SingleMessageDto
{
[JsonProperty("responseType")] public string ResponseType { get; set; } = "";
[JsonProperty("text")] public string Text { get; set; } = "";
[JsonProperty("giphyId")] public object GiphyId { get; set; } = new();
[JsonProperty("lockedText")] public bool LockedText { get; set; }
[JsonProperty("isFree")] public bool IsFree { get; set; }
[JsonProperty("price")] public double Price { get; set; }
[JsonProperty("isMediaReady")] public bool IsMediaReady { get; set; }
[JsonProperty("mediaCount")] public int MediaCount { get; set; }
[JsonProperty("media")] public List<MediumDto> Media { get; set; } = [];
[JsonProperty("previews")] public List<object> Previews { get; set; } = [];
[JsonProperty("isTip")] public bool IsTip { get; set; }
[JsonProperty("isReportedByMe")] public bool IsReportedByMe { get; set; }
[JsonProperty("isCouplePeopleMedia")] public bool IsCouplePeopleMedia { get; set; }
[JsonProperty("queueId")] public long QueueId { get; set; }
[JsonProperty("fromUser")] public FromUserDto FromUser { get; set; } = new();
[JsonProperty("isFromQueue")] public bool IsFromQueue { get; set; }
[JsonProperty("canUnsendQueue")] public bool CanUnsendQueue { get; set; }
[JsonProperty("unsendSecondsQueue")] public int UnsendSecondsQueue { get; set; }
[JsonProperty("id")] public long Id { get; set; }
[JsonProperty("isOpened")] public bool IsOpened { get; set; }
[JsonProperty("isNew")] public bool IsNew { get; set; }
[JsonProperty("createdAt")] public DateTime? CreatedAt { get; set; }
[JsonProperty("changedAt")] public DateTime? ChangedAt { get; set; }
[JsonProperty("cancelSeconds")] public int CancelSeconds { get; set; }
[JsonProperty("isLiked")] public bool IsLiked { get; set; }
[JsonProperty("canPurchase")] public bool CanPurchase { get; set; }
[JsonProperty("canReport")] public bool CanReport { get; set; }
}

View File

@ -1,11 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Common;
namespace OF_DL.Models.Dtos.Posts;
public class InfoDto
{
[JsonProperty("source")] public SourceDto Source { get; set; } = new();
[JsonProperty("preview")] public PreviewDto Preview { get; set; } = new();
}

View File

@ -1,101 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Common;
using OF_DL.Utils;
namespace OF_DL.Models.Dtos.Posts;
public class ListItemDto
{
private string _rawText = "";
[JsonProperty("responseType")] public string ResponseType { get; set; } = "";
[JsonProperty("id")] public long Id { get; set; }
[JsonProperty("postedAt")] public DateTime PostedAt { get; set; }
[JsonProperty("postedAtPrecise")] public string PostedAtPrecise { get; set; } = "";
[JsonProperty("expiredAt")] public object ExpiredAt { get; set; } = new();
[JsonProperty("author")] public AuthorDto Author { get; set; } = new();
[JsonProperty("text")] public string Text { get; set; } = "";
[JsonProperty("rawText")]
public string RawText
{
get
{
if (string.IsNullOrEmpty(_rawText))
{
_rawText = XmlUtils.EvaluateInnerText(Text);
}
return _rawText;
}
set => _rawText = value;
}
[JsonProperty("lockedText")] public bool? LockedText { get; set; }
[JsonProperty("isFavorite")] public bool? IsFavorite { get; set; }
[JsonProperty("canReport")] public bool? CanReport { get; set; }
[JsonProperty("canDelete")] public bool? CanDelete { get; set; }
[JsonProperty("canComment")] public bool? CanComment { get; set; }
[JsonProperty("canEdit")] public bool? CanEdit { get; set; }
[JsonProperty("isPinned")] public bool? IsPinned { get; set; }
[JsonProperty("favoritesCount")] public int? FavoritesCount { get; set; }
[JsonProperty("mediaCount")] public int? MediaCount { get; set; }
[JsonProperty("isMediaReady")] public bool? IsMediaReady { get; set; }
[JsonProperty("voting")] public object Voting { get; set; } = new();
[JsonProperty("isOpened")] public bool IsOpened { get; set; }
[JsonProperty("canToggleFavorite")] public bool? CanToggleFavorite { get; set; }
[JsonProperty("streamId")] public object StreamId { get; set; } = new();
[JsonProperty("price")] public string? Price { get; set; }
[JsonProperty("hasVoting")] public bool? HasVoting { get; set; }
[JsonProperty("isAddedToBookmarks")] public bool? IsAddedToBookmarks { get; set; }
[JsonProperty("isArchived")] public bool IsArchived { get; set; }
[JsonProperty("isPrivateArchived")] public bool? IsPrivateArchived { get; set; }
[JsonProperty("isDeleted")] public bool? IsDeleted { get; set; }
[JsonProperty("hasUrl")] public bool? HasUrl { get; set; }
[JsonProperty("isCouplePeopleMedia")] public bool? IsCouplePeopleMedia { get; set; }
[JsonProperty("cantCommentReason")] public string CantCommentReason { get; set; } = "";
[JsonProperty("votingType")] public int? VotingType { get; set; }
[JsonProperty("commentsCount")] public int? CommentsCount { get; set; }
[JsonProperty("mentionedUsers")] public List<object> MentionedUsers { get; set; } = [];
[JsonProperty("linkedUsers")] public List<object> LinkedUsers { get; set; } = [];
[JsonProperty("canVote")] public bool? CanVote { get; set; }
[JsonProperty("media")] public List<MediumDto> Media { get; set; } = [];
[JsonProperty("canViewMedia")] public bool? CanViewMedia { get; set; }
[JsonProperty("preview")] public List<object> Preview { get; set; } = [];
}

View File

@ -1,37 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Common;
namespace OF_DL.Models.Dtos.Posts;
public class MediumDto
{
[JsonProperty("id")] public long Id { get; set; }
[JsonProperty("type")] public string Type { get; set; } = "";
[JsonProperty("convertedToVideo")] public bool? ConvertedToVideo { get; set; }
[JsonProperty("canView")] public bool CanView { get; set; }
[JsonProperty("hasError")] public bool? HasError { get; set; }
[JsonProperty("createdAt")] public DateTime? CreatedAt { get; set; }
[JsonProperty("info")] public InfoDto? Info { get; set; }
[JsonProperty("source")] public SourceDto? Source { get; set; }
[JsonProperty("squarePreview")] public string? SquarePreview { get; set; }
[JsonProperty("full")] public string? Full { get; set; }
[JsonProperty("preview")] public string? Preview { get; set; }
[JsonProperty("thumb")] public string? Thumb { get; set; }
[JsonProperty("hasCustomPreview")] public bool? HasCustomPreview { get; set; }
[JsonProperty("files")] public FilesDto Files { get; set; } = new();
[JsonProperty("videoSources")] public VideoSourcesDto VideoSources { get; set; } = new();
}

View File

@ -1,14 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Posts;
public class PostDto
{
[JsonProperty("list")] public List<ListItemDto> List { get; set; } = [];
[JsonProperty("hasMore")] public bool HasMore { get; set; }
[JsonProperty("headMarker")] public string HeadMarker { get; set; } = "";
[JsonProperty("tailMarker")] public string TailMarker { get; set; } = "";
}

View File

@ -1,99 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Common;
using OF_DL.Utils;
namespace OF_DL.Models.Dtos.Posts;
public class SinglePostDto
{
private string _rawText = "";
[JsonProperty("responseType")] public string ResponseType { get; set; } = "";
[JsonProperty("id")] public long Id { get; set; }
[JsonProperty("postedAt")] public DateTime PostedAt { get; set; }
[JsonProperty("postedAtPrecise")] public string PostedAtPrecise { get; set; } = "";
[JsonProperty("expiredAt")] public object ExpiredAt { get; set; } = new();
[JsonProperty("author")] public AuthorDto Author { get; set; } = new();
[JsonProperty("text")] public string Text { get; set; } = "";
[JsonProperty("rawText")]
public string RawText
{
get
{
if (string.IsNullOrEmpty(_rawText))
{
_rawText = XmlUtils.EvaluateInnerText(Text);
}
return _rawText;
}
set => _rawText = value;
}
[JsonProperty("lockedText")] public bool LockedText { get; set; }
[JsonProperty("isFavorite")] public bool IsFavorite { get; set; }
[JsonProperty("canReport")] public bool CanReport { get; set; }
[JsonProperty("canDelete")] public bool CanDelete { get; set; }
[JsonProperty("canComment")] public bool CanComment { get; set; }
[JsonProperty("canEdit")] public bool CanEdit { get; set; }
[JsonProperty("isPinned")] public bool IsPinned { get; set; }
[JsonProperty("favoritesCount")] public int FavoritesCount { get; set; }
[JsonProperty("mediaCount")] public int MediaCount { get; set; }
[JsonProperty("isMediaReady")] public bool IsMediaReady { get; set; }
[JsonProperty("voting")] public object Voting { get; set; } = new();
[JsonProperty("isOpened")] public bool IsOpened { get; set; }
[JsonProperty("canToggleFavorite")] public bool CanToggleFavorite { get; set; }
[JsonProperty("streamId")] public string StreamId { get; set; } = "";
[JsonProperty("price")] public string? Price { get; set; }
[JsonProperty("hasVoting")] public bool HasVoting { get; set; }
[JsonProperty("isAddedToBookmarks")] public bool IsAddedToBookmarks { get; set; }
[JsonProperty("isArchived")] public bool IsArchived { get; set; }
[JsonProperty("isPrivateArchived")] public bool IsPrivateArchived { get; set; }
[JsonProperty("isDeleted")] public bool IsDeleted { get; set; }
[JsonProperty("hasUrl")] public bool HasUrl { get; set; }
[JsonProperty("isCouplePeopleMedia")] public bool IsCouplePeopleMedia { get; set; }
[JsonProperty("commentsCount")] public int CommentsCount { get; set; }
[JsonProperty("mentionedUsers")] public List<object> MentionedUsers { get; set; } = [];
[JsonProperty("linkedUsers")] public List<object> LinkedUsers { get; set; } = [];
[JsonProperty("tipsAmount")] public string TipsAmount { get; set; } = "";
[JsonProperty("tipsAmountRaw")] public string TipsAmountRaw { get; set; } = "";
[JsonProperty("media")] public List<MediumDto> Media { get; set; } = [];
[JsonProperty("canViewMedia")] public bool CanViewMedia { get; set; }
[JsonProperty("preview")] public List<object> Preview { get; set; } = [];
}

View File

@ -1,10 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Purchased;
public class FromUserDto
{
[JsonProperty("id")] public long Id { get; set; }
[JsonProperty("_view")] public string View { get; set; } = "";
}

View File

@ -1,72 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Common;
using MessageDtos = OF_DL.Models.Dtos.Messages;
namespace OF_DL.Models.Dtos.Purchased;
public class ListItemDto
{
[JsonProperty("responseType")] public string ResponseType { get; set; } = "";
[JsonProperty("text")] public string Text { get; set; } = "";
[JsonProperty("giphyId")] public object GiphyId { get; set; } = new();
[JsonProperty("lockedText")] public bool? LockedText { get; set; }
[JsonProperty("isFree")] public bool? IsFree { get; set; }
[JsonProperty("price")] public string? Price { get; set; }
[JsonProperty("isMediaReady")] public bool? IsMediaReady { get; set; }
[JsonProperty("mediaCount")] public int? MediaCount { get; set; }
[JsonProperty("media")] public List<MessageDtos.MediumDto>? Media { get; set; }
[JsonProperty("previews")] public List<object>? Previews { get; set; }
[JsonProperty("preview")] public List<object>? Preview { get; set; }
[JsonProperty("isTip")] public bool? IsTip { get; set; }
[JsonProperty("isReportedByMe")] public bool? IsReportedByMe { get; set; }
[JsonProperty("isCouplePeopleMedia")] public bool? IsCouplePeopleMedia { get; set; }
[JsonProperty("queueId")] public object QueueId { get; set; } = new();
[JsonProperty("fromUser")] public FromUserDto? FromUser { get; set; }
[JsonProperty("author")] public AuthorDto? Author { get; set; }
[JsonProperty("isFromQueue")] public bool? IsFromQueue { get; set; }
[JsonProperty("canUnsendQueue")] public bool? CanUnsendQueue { get; set; }
[JsonProperty("unsendSecondsQueue")] public int? UnsendSecondsQueue { get; set; }
[JsonProperty("id")] public long Id { get; set; }
[JsonProperty("isOpened")] public bool IsOpened { get; set; }
[JsonProperty("isNew")] public bool? IsNew { get; set; }
[JsonProperty("createdAt")] public DateTime? CreatedAt { get; set; }
[JsonProperty("postedAt")] public DateTime? PostedAt { get; set; }
[JsonProperty("changedAt")] public DateTime? ChangedAt { get; set; }
[JsonProperty("cancelSeconds")] public int? CancelSeconds { get; set; }
[JsonProperty("isLiked")] public bool? IsLiked { get; set; }
[JsonProperty("canPurchase")] public bool? CanPurchase { get; set; }
[JsonProperty("canReport")] public bool? CanReport { get; set; }
[JsonProperty("isCanceled")] public bool? IsCanceled { get; set; }
[JsonProperty("isArchived")] public bool? IsArchived { get; set; }
}

View File

@ -1,10 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Purchased;
public class PurchasedDto
{
[JsonProperty("list")] public List<ListItemDto> List { get; set; } = [];
[JsonProperty("hasMore")] public bool HasMore { get; set; }
}

View File

@ -1,21 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Common;
namespace OF_DL.Models.Dtos.Stories;
public class MediumDto
{
[JsonProperty("id")] public long Id { get; set; }
[JsonProperty("type")] public string Type { get; set; } = "";
[JsonProperty("convertedToVideo")] public bool ConvertedToVideo { get; set; }
[JsonProperty("canView")] public bool CanView { get; set; }
[JsonProperty("hasError")] public bool HasError { get; set; }
[JsonProperty("createdAt")] public DateTime? CreatedAt { get; set; }
[JsonProperty("files")] public FilesDto Files { get; set; } = new();
}

View File

@ -1,24 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Stories;
public class StoryDto
{
[JsonProperty("id")] public long Id { get; set; }
[JsonProperty("userId")] public long UserId { get; set; }
[JsonProperty("isWatched")] public bool IsWatched { get; set; }
[JsonProperty("isReady")] public bool IsReady { get; set; }
[JsonProperty("media")] public List<MediumDto> Media { get; set; } = [];
[JsonProperty("createdAt")] public DateTime? CreatedAt { get; set; }
[JsonProperty("question")] public object Question { get; set; } = new();
[JsonProperty("canLike")] public bool CanLike { get; set; }
[JsonProperty("isLiked")] public bool IsLiked { get; set; }
}

View File

@ -1,11 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Common;
namespace OF_DL.Models.Dtos.Streams;
public class InfoDto
{
[JsonProperty("source")] public SourceDto Source { get; set; } = new();
[JsonProperty("preview")] public PreviewDto Preview { get; set; } = new();
}

View File

@ -1,101 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Common;
using OF_DL.Utils;
namespace OF_DL.Models.Dtos.Streams;
public class ListItemDto
{
private string _rawText = "";
[JsonProperty("responseType")] public string ResponseType { get; set; } = "";
[JsonProperty("id")] public long Id { get; set; }
[JsonProperty("postedAt")] public DateTime PostedAt { get; set; }
[JsonProperty("postedAtPrecise")] public string PostedAtPrecise { get; set; } = "";
[JsonProperty("expiredAt")] public object ExpiredAt { get; set; } = new();
[JsonProperty("author")] public AuthorDto Author { get; set; } = new();
[JsonProperty("text")] public string Text { get; set; } = "";
[JsonProperty("rawText")]
public string RawText
{
get
{
if (string.IsNullOrEmpty(_rawText))
{
_rawText = XmlUtils.EvaluateInnerText(Text);
}
return _rawText;
}
set => _rawText = value;
}
[JsonProperty("lockedText")] public bool? LockedText { get; set; }
[JsonProperty("isFavorite")] public bool? IsFavorite { get; set; }
[JsonProperty("canReport")] public bool? CanReport { get; set; }
[JsonProperty("canDelete")] public bool? CanDelete { get; set; }
[JsonProperty("canComment")] public bool? CanComment { get; set; }
[JsonProperty("canEdit")] public bool? CanEdit { get; set; }
[JsonProperty("isPinned")] public bool? IsPinned { get; set; }
[JsonProperty("favoritesCount")] public int? FavoritesCount { get; set; }
[JsonProperty("mediaCount")] public int? MediaCount { get; set; }
[JsonProperty("isMediaReady")] public bool? IsMediaReady { get; set; }
[JsonProperty("voting")] public object Voting { get; set; } = new();
[JsonProperty("isOpened")] public bool? IsOpened { get; set; }
[JsonProperty("canToggleFavorite")] public bool? CanToggleFavorite { get; set; }
[JsonProperty("streamId")] public int? StreamId { get; set; }
[JsonProperty("price")] public string? Price { get; set; }
[JsonProperty("hasVoting")] public bool? HasVoting { get; set; }
[JsonProperty("isAddedToBookmarks")] public bool? IsAddedToBookmarks { get; set; }
[JsonProperty("isArchived")] public bool? IsArchived { get; set; }
[JsonProperty("isPrivateArchived")] public bool? IsPrivateArchived { get; set; }
[JsonProperty("isDeleted")] public bool? IsDeleted { get; set; }
[JsonProperty("hasUrl")] public bool? HasUrl { get; set; }
[JsonProperty("isCouplePeopleMedia")] public bool? IsCouplePeopleMedia { get; set; }
[JsonProperty("cantCommentReason")] public string CantCommentReason { get; set; } = "";
[JsonProperty("commentsCount")] public int? CommentsCount { get; set; }
[JsonProperty("mentionedUsers")] public List<object> MentionedUsers { get; set; } = [];
[JsonProperty("linkedUsers")] public List<object> LinkedUsers { get; set; } = [];
[JsonProperty("tipsAmount")] public string TipsAmount { get; set; } = "";
[JsonProperty("tipsAmountRaw")] public string TipsAmountRaw { get; set; } = "";
[JsonProperty("media")] public List<MediumDto> Media { get; set; } = [];
[JsonProperty("canViewMedia")] public bool? CanViewMedia { get; set; }
[JsonProperty("preview")] public List<object> Preview { get; set; } = [];
}

View File

@ -1,37 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Common;
namespace OF_DL.Models.Dtos.Streams;
public class MediumDto
{
[JsonProperty("id")] public long Id { get; set; }
[JsonProperty("type")] public string Type { get; set; } = "";
[JsonProperty("convertedToVideo")] public bool ConvertedToVideo { get; set; }
[JsonProperty("canView")] public bool CanView { get; set; }
[JsonProperty("hasError")] public bool HasError { get; set; }
[JsonProperty("createdAt")] public DateTime? CreatedAt { get; set; }
[JsonProperty("info")] public InfoDto Info { get; set; } = new();
[JsonProperty("source")] public SourceDto Source { get; set; } = new();
[JsonProperty("squarePreview")] public string SquarePreview { get; set; } = "";
[JsonProperty("full")] public string Full { get; set; } = "";
[JsonProperty("preview")] public string Preview { get; set; } = "";
[JsonProperty("thumb")] public string Thumb { get; set; } = "";
[JsonProperty("hasCustomPreview")] public bool HasCustomPreview { get; set; }
[JsonProperty("files")] public FilesDto Files { get; set; } = new();
[JsonProperty("videoSources")] public VideoSourcesDto VideoSources { get; set; } = new();
}

View File

@ -1,17 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Common;
namespace OF_DL.Models.Dtos.Streams;
public class StreamsDto
{
[JsonProperty("list")] public List<ListItemDto> List { get; set; } = [];
[JsonProperty("hasMore")] public bool HasMore { get; set; }
[JsonProperty("headMarker")] public string HeadMarker { get; set; } = "";
[JsonProperty("tailMarker")] public string TailMarker { get; set; } = "";
[JsonProperty("counters")] public CountersDto Counters { get; set; } = new();
}

View File

@ -1,111 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Common;
namespace OF_DL.Models.Dtos.Subscriptions;
public class ListItemDto
{
[JsonProperty("view")] public string View { get; set; } = "";
[JsonProperty("avatar")] public string? Avatar { get; set; }
[JsonProperty("avatarThumbs")] public AvatarThumbsDto AvatarThumbs { get; set; } = new();
[JsonProperty("header")] public string? Header { get; set; }
[JsonProperty("headerSize")] public HeaderSizeDto HeaderSize { get; set; } = new();
[JsonProperty("headerThumbs")] public HeaderThumbsDto HeaderThumbs { get; set; } = new();
[JsonProperty("id")] public long Id { get; set; }
[JsonProperty("name")] public string Name { get; set; } = "";
[JsonProperty("username")] public string? Username { get; set; }
[JsonProperty("canLookStory")] public bool? CanLookStory { get; set; }
[JsonProperty("canCommentStory")] public bool? CanCommentStory { get; set; }
[JsonProperty("hasNotViewedStory")] public bool? HasNotViewedStory { get; set; }
[JsonProperty("isVerified")] public bool? IsVerified { get; set; }
[JsonProperty("canPayInternal")] public bool? CanPayInternal { get; set; }
[JsonProperty("hasScheduledStream")] public bool? HasScheduledStream { get; set; }
[JsonProperty("hasStream")] public bool? HasStream { get; set; }
[JsonProperty("hasStories")] public bool? HasStories { get; set; }
[JsonProperty("tipsEnabled")] public bool? TipsEnabled { get; set; }
[JsonProperty("tipsTextEnabled")] public bool? TipsTextEnabled { get; set; }
[JsonProperty("tipsMin")] public int? TipsMin { get; set; }
[JsonProperty("tipsMinInternal")] public int? TipsMinInternal { get; set; }
[JsonProperty("tipsMax")] public int? TipsMax { get; set; }
[JsonProperty("canEarn")] public bool? CanEarn { get; set; }
[JsonProperty("canAddSubscriber")] public bool? CanAddSubscriber { get; set; }
[JsonProperty("subscribePrice")] public string? SubscribePrice { get; set; }
[JsonProperty("isPaywallRequired")] public bool? IsPaywallRequired { get; set; }
[JsonProperty("unprofitable")] public bool? Unprofitable { get; set; }
[JsonProperty("listsStates")] public List<ListsStateDto> ListsStates { get; set; } = [];
[JsonProperty("isMuted")] public bool? IsMuted { get; set; }
[JsonProperty("isRestricted")] public bool? IsRestricted { get; set; }
[JsonProperty("canRestrict")] public bool? CanRestrict { get; set; }
[JsonProperty("subscribedBy")] public bool? SubscribedBy { get; set; }
[JsonProperty("subscribedByExpire")] public bool? SubscribedByExpire { get; set; }
[JsonProperty("subscribedByExpireDate")] public DateTime? SubscribedByExpireDate { get; set; }
[JsonProperty("subscribedByAutoprolong")] public bool? SubscribedByAutoprolong { get; set; }
[JsonProperty("subscribedIsExpiredNow")] public bool? SubscribedIsExpiredNow { get; set; }
[JsonProperty("currentSubscribePrice")] public string? CurrentSubscribePrice { get; set; }
[JsonProperty("subscribedOn")] public bool? SubscribedOn { get; set; }
[JsonProperty("subscribedOnExpiredNow")] public bool? SubscribedOnExpiredNow { get; set; }
[JsonProperty("subscribedOnDuration")] public string SubscribedOnDuration { get; set; } = "";
[JsonProperty("canReport")] public bool? CanReport { get; set; }
[JsonProperty("canReceiveChatMessage")] public bool? CanReceiveChatMessage { get; set; }
[JsonProperty("hideChat")] public bool? HideChat { get; set; }
[JsonProperty("lastSeen")] public DateTime? LastSeen { get; set; }
[JsonProperty("isPerformer")] public bool? IsPerformer { get; set; }
[JsonProperty("isRealPerformer")] public bool? IsRealPerformer { get; set; }
[JsonProperty("subscribedByData")] public SubscribedByDataDto SubscribedByData { get; set; } = new();
[JsonProperty("subscribedOnData")] public SubscribedOnDataDto SubscribedOnData { get; set; } = new();
[JsonProperty("canTrialSend")] public bool? CanTrialSend { get; set; }
[JsonProperty("isBlocked")] public bool? IsBlocked { get; set; }
[JsonProperty("displayName")] public string DisplayName { get; set; } = "";
[JsonProperty("notice")] public string Notice { get; set; } = "";
}

View File

@ -1,16 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Subscriptions;
public class ListsStateDto
{
[JsonProperty("id")] public object Id { get; set; } = new();
[JsonProperty("type")] public string Type { get; set; } = "";
[JsonProperty("name")] public string Name { get; set; } = "";
[JsonProperty("hasUser")] public bool? HasUser { get; set; }
[JsonProperty("canAddUser")] public bool? CanAddUser { get; set; }
}

View File

@ -1,38 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Subscriptions;
public class SubscribeDto
{
[JsonProperty("id")] public object Id { get; set; } = new();
[JsonProperty("userId")] public long? UserId { get; set; }
[JsonProperty("subscriberId")] public int? SubscriberId { get; set; }
[JsonProperty("date")] public DateTime? Date { get; set; }
[JsonProperty("duration")] public int? Duration { get; set; }
[JsonProperty("startDate")] public DateTime? StartDate { get; set; }
[JsonProperty("expireDate")] public DateTime? ExpireDate { get; set; }
[JsonProperty("cancelDate")] public object CancelDate { get; set; } = new();
[JsonProperty("price")] public string? Price { get; set; }
[JsonProperty("regularPrice")] public string? RegularPrice { get; set; }
[JsonProperty("discount")] public string? Discount { get; set; }
[JsonProperty("action")] public string Action { get; set; } = "";
[JsonProperty("type")] public string Type { get; set; } = "";
[JsonProperty("offerStart")] public object OfferStart { get; set; } = new();
[JsonProperty("offerEnd")] public object OfferEnd { get; set; } = new();
[JsonProperty("isCurrent")] public bool? IsCurrent { get; set; }
}

View File

@ -1,10 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Subscriptions;
public class SubscriptionsDto
{
[JsonProperty("list")] public List<ListItemDto> List { get; set; } = [];
[JsonProperty("hasMore")] public bool HasMore { get; set; }
}

View File

@ -1,16 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Users;
public class ListsStateDto
{
[JsonProperty("id")] public string Id { get; set; } = "";
[JsonProperty("type")] public string Type { get; set; } = "";
[JsonProperty("name")] public string Name { get; set; } = "";
[JsonProperty("hasUser")] public bool HasUser { get; set; }
[JsonProperty("canAddUser")] public bool CanAddUser { get; set; }
}

View File

@ -1,38 +0,0 @@
using Newtonsoft.Json;
namespace OF_DL.Models.Dtos.Users;
public class SubscribeDto
{
[JsonProperty("id")] public long? Id { get; set; }
[JsonProperty("userId")] public long? UserId { get; set; }
[JsonProperty("subscriberId")] public int? SubscriberId { get; set; }
[JsonProperty("date")] public DateTime? Date { get; set; }
[JsonProperty("duration")] public int? Duration { get; set; }
[JsonProperty("startDate")] public DateTime? StartDate { get; set; }
[JsonProperty("expireDate")] public DateTime? ExpireDate { get; set; }
[JsonProperty("cancelDate")] public object CancelDate { get; set; } = new();
[JsonProperty("price")] public string? Price { get; set; }
[JsonProperty("regularPrice")] public string? RegularPrice { get; set; }
[JsonProperty("discount")] public int? Discount { get; set; }
[JsonProperty("action")] public string Action { get; set; } = "";
[JsonProperty("type")] public string Type { get; set; } = "";
[JsonProperty("offerStart")] public object OfferStart { get; set; } = new();
[JsonProperty("offerEnd")] public object OfferEnd { get; set; } = new();
[JsonProperty("isCurrent")] public bool? IsCurrent { get; set; }
}

View File

@ -1,179 +0,0 @@
using Newtonsoft.Json;
using OF_DL.Models.Dtos.Common;
namespace OF_DL.Models.Dtos.Users;
public class UserDto
{
[JsonProperty("view")] public string View { get; set; } = "";
[JsonProperty("avatar")] public string? Avatar { get; set; }
[JsonProperty("avatarThumbs")] public AvatarThumbsDto AvatarThumbs { get; set; } = new();
[JsonProperty("header")] public string? Header { get; set; }
[JsonProperty("headerSize")] public HeaderSizeDto HeaderSize { get; set; } = new();
[JsonProperty("headerThumbs")] public HeaderThumbsDto HeaderThumbs { get; set; } = new();
[JsonProperty("id")] public long? Id { get; set; }
[JsonProperty("name")] public string? Name { get; set; }
[JsonProperty("username")] public string? Username { get; set; }
[JsonProperty("canLookStory")] public bool? CanLookStory { get; set; }
[JsonProperty("canCommentStory")] public bool? CanCommentStory { get; set; }
[JsonProperty("hasNotViewedStory")] public bool? HasNotViewedStory { get; set; }
[JsonProperty("isVerified")] public bool? IsVerified { get; set; }
[JsonProperty("canPayInternal")] public bool? CanPayInternal { get; set; }
[JsonProperty("hasScheduledStream")] public bool? HasScheduledStream { get; set; }
[JsonProperty("hasStream")] public bool? HasStream { get; set; }
[JsonProperty("hasStories")] public bool? HasStories { get; set; }
[JsonProperty("tipsEnabled")] public bool? TipsEnabled { get; set; }
[JsonProperty("tipsTextEnabled")] public bool? TipsTextEnabled { get; set; }
[JsonProperty("tipsMin")] public int? TipsMin { get; set; }
[JsonProperty("tipsMinInternal")] public int? TipsMinInternal { get; set; }
[JsonProperty("tipsMax")] public int? TipsMax { get; set; }
[JsonProperty("canEarn")] public bool? CanEarn { get; set; }
[JsonProperty("canAddSubscriber")] public bool? CanAddSubscriber { get; set; }
[JsonProperty("subscribePrice")] public string? SubscribePrice { get; set; }
[JsonProperty("displayName")] public string DisplayName { get; set; } = "";
[JsonProperty("notice")] public string Notice { get; set; } = "";
[JsonProperty("isPaywallRequired")] public bool? IsPaywallRequired { get; set; }
[JsonProperty("unprofitable")] public bool? Unprofitable { get; set; }
[JsonProperty("listsStates")] public List<ListsStateDto> ListsStates { get; set; } = [];
[JsonProperty("isMuted")] public bool? IsMuted { get; set; }
[JsonProperty("isRestricted")] public bool? IsRestricted { get; set; }
[JsonProperty("canRestrict")] public bool? CanRestrict { get; set; }
[JsonProperty("subscribedBy")] public bool? SubscribedBy { get; set; }
[JsonProperty("subscribedByExpire")] public bool? SubscribedByExpire { get; set; }
[JsonProperty("subscribedByExpireDate")] public DateTime? SubscribedByExpireDate { get; set; }
[JsonProperty("subscribedByAutoprolong")] public bool? SubscribedByAutoprolong { get; set; }
[JsonProperty("subscribedIsExpiredNow")] public bool? SubscribedIsExpiredNow { get; set; }
[JsonProperty("currentSubscribePrice")] public string? CurrentSubscribePrice { get; set; }
[JsonProperty("subscribedOn")] public bool? SubscribedOn { get; set; }
[JsonProperty("subscribedOnExpiredNow")] public bool? SubscribedOnExpiredNow { get; set; }
[JsonProperty("subscribedOnDuration")] public string SubscribedOnDuration { get; set; } = "";
[JsonProperty("joinDate")] public DateTime? JoinDate { get; set; }
[JsonProperty("isReferrerAllowed")] public bool? IsReferrerAllowed { get; set; }
[JsonProperty("about")] public string About { get; set; } = "";
[JsonProperty("rawAbout")] public string RawAbout { get; set; } = "";
[JsonProperty("website")] public object Website { get; set; } = new();
[JsonProperty("wishlist")] public object Wishlist { get; set; } = new();
[JsonProperty("location")] public object Location { get; set; } = new();
[JsonProperty("postsCount")] public int? PostsCount { get; set; }
[JsonProperty("archivedPostsCount")] public int? ArchivedPostsCount { get; set; }
[JsonProperty("privateArchivedPostsCount")] public int? PrivateArchivedPostsCount { get; set; }
[JsonProperty("photosCount")] public int? PhotosCount { get; set; }
[JsonProperty("videosCount")] public int? VideosCount { get; set; }
[JsonProperty("audiosCount")] public int? AudiosCount { get; set; }
[JsonProperty("mediasCount")] public int? MediasCount { get; set; }
[JsonProperty("lastSeen")] public DateTime? LastSeen { get; set; }
[JsonProperty("favoritesCount")] public int? FavoritesCount { get; set; }
[JsonProperty("favoritedCount")] public int? FavoritedCount { get; set; }
[JsonProperty("showPostsInFeed")] public bool? ShowPostsInFeed { get; set; }
[JsonProperty("canReceiveChatMessage")] public bool? CanReceiveChatMessage { get; set; }
[JsonProperty("isPerformer")] public bool? IsPerformer { get; set; }
[JsonProperty("isRealPerformer")] public bool? IsRealPerformer { get; set; }
[JsonProperty("isSpotifyConnected")] public bool? IsSpotifyConnected { get; set; }
[JsonProperty("subscribersCount")] public int? SubscribersCount { get; set; }
[JsonProperty("hasPinnedPosts")] public bool? HasPinnedPosts { get; set; }
[JsonProperty("hasLabels")] public bool? HasLabels { get; set; }
[JsonProperty("canChat")] public bool? CanChat { get; set; }
[JsonProperty("callPrice")] public string? CallPrice { get; set; }
[JsonProperty("isPrivateRestriction")] public bool? IsPrivateRestriction { get; set; }
[JsonProperty("showSubscribersCount")] public bool? ShowSubscribersCount { get; set; }
[JsonProperty("showMediaCount")] public bool? ShowMediaCount { get; set; }
[JsonProperty("subscribedByData")] public SubscribedByDataDto SubscribedByData { get; set; } = new();
[JsonProperty("subscribedOnData")] public SubscribedOnDataDto SubscribedOnData { get; set; } = new();
[JsonProperty("canPromotion")] public bool? CanPromotion { get; set; }
[JsonProperty("canCreatePromotion")] public bool? CanCreatePromotion { get; set; }
[JsonProperty("canCreateTrial")] public bool? CanCreateTrial { get; set; }
[JsonProperty("isAdultContent")] public bool? IsAdultContent { get; set; }
[JsonProperty("canTrialSend")] public bool? CanTrialSend { get; set; }
[JsonProperty("hadEnoughLastPhotos")] public bool? HadEnoughLastPhotos { get; set; }
[JsonProperty("hasLinks")] public bool? HasLinks { get; set; }
[JsonProperty("firstPublishedPostDate")] public DateTime? FirstPublishedPostDate { get; set; }
[JsonProperty("isSpringConnected")] public bool? IsSpringConnected { get; set; }
[JsonProperty("isFriend")] public bool? IsFriend { get; set; }
[JsonProperty("isBlocked")] public bool? IsBlocked { get; set; }
[JsonProperty("canReport")] public bool? CanReport { get; set; }
}

View File

@ -1,10 +0,0 @@
namespace OF_DL.Models.Entities.Archived;
public class Archived
{
public List<ListItem> List { get; set; } = [];
public bool HasMore { get; set; }
public string? TailMarker { get; set; }
}

View File

@ -1,10 +0,0 @@
namespace OF_DL.Models.Entities.Archived;
public class ArchivedCollection
{
public List<Medium> ArchivedPostMedia { get; set; } = [];
public List<ListItem> ArchivedPostObjects { get; set; } = [];
public Dictionary<long, string> ArchivedPosts { get; set; } = new();
}

View File

@ -1,24 +0,0 @@
using OF_DL.Models.Entities.Common;
namespace OF_DL.Models.Entities.Archived;
public class ListItem
{
public long Id { get; set; }
public DateTime PostedAt { get; set; }
public Author? Author { get; set; }
public string? Text { get; set; }
public string? Price { get; set; }
public bool IsOpened { get; set; }
public bool IsArchived { get; set; }
public List<Medium>? Media { get; set; }
public List<object>? Preview { get; set; }
}

View File

@ -1,16 +0,0 @@
using OF_DL.Models.Entities.Common;
namespace OF_DL.Models.Entities.Archived;
public class Medium
{
public long Id { get; set; }
public string? Type { get; set; }
public bool CanView { get; set; }
public Files? Files { get; set; }
public string? Preview { get; set; }
}

View File

@ -1,6 +0,0 @@
namespace OF_DL.Models.Entities.Common;
public class Author
{
public long Id { get; set; }
}

View File

@ -1,10 +0,0 @@
namespace OF_DL.Models.Entities.Common;
public class Dash
{
public string? CloudFrontPolicy { get; set; }
public string? CloudFrontSignature { get; set; }
public string? CloudFrontKeyPairId { get; set; }
}

Some files were not shown because too many files have changed in this diff Show More