From 3c307bf7de7dfb3a9af7607220b5534d14bdce59 Mon Sep 17 00:00:00 2001 From: whimsical-c4lic0 Date: Sun, 8 Feb 2026 21:04:09 -0600 Subject: [PATCH] Refactor Posts entities into DTOs and application entities with standardized naming conventions and default values --- OF DL/Models/Dtos/Posts/InfoDto.cs | 11 + OF DL/Models/Dtos/Posts/ListItemDto.cs | 101 +++++++ OF DL/Models/Dtos/Posts/MediumDto.cs | 37 +++ OF DL/Models/Dtos/Posts/PostDto.cs | 14 + OF DL/Models/Dtos/Posts/SinglePostDto.cs | 99 +++++++ OF DL/Models/Entities/Common/Files.cs | 2 + OF DL/Models/Entities/Common/Preview.cs | 6 + OF DL/Models/Entities/Common/VideoSources.cs | 8 + OF DL/Models/Entities/Posts/ListItem.cs | 41 +++ OF DL/Models/Entities/Posts/Medium.cs | 18 ++ OF DL/Models/Entities/Posts/Post.cs | 10 + OF DL/Models/Entities/Posts/PostCollection.cs | 10 + OF DL/Models/Entities/Posts/SinglePost.cs | 41 +++ .../Entities/Posts/SinglePostCollection.cs | 10 + OF DL/Models/Mappers/ArchivedMapper.cs | 33 +-- OF DL/Models/Mappers/MessagesMapper.cs | 23 +- OF DL/Models/Mappers/PostMapper.cs | 182 ++++++++++++ OF DL/Models/Post/Post.cs | 200 ------------- OF DL/Models/Post/PostCollection.cs | 8 - OF DL/Models/Post/SinglePost.cs | 188 ------------- OF DL/Models/Post/SinglePostCollection.cs | 8 - OF DL/Program.cs | 26 +- OF DL/Services/APIService.cs | 262 +++++++++--------- OF DL/Services/DownloadService.cs | 83 +++--- OF DL/Services/IAPIService.cs | 8 +- OF DL/Services/IDownloadService.cs | 40 +-- 26 files changed, 821 insertions(+), 648 deletions(-) create mode 100644 OF DL/Models/Dtos/Posts/InfoDto.cs create mode 100644 OF DL/Models/Dtos/Posts/ListItemDto.cs create mode 100644 OF DL/Models/Dtos/Posts/MediumDto.cs create mode 100644 OF DL/Models/Dtos/Posts/PostDto.cs create mode 100644 OF DL/Models/Dtos/Posts/SinglePostDto.cs create mode 100644 OF DL/Models/Entities/Common/Preview.cs create mode 100644 OF DL/Models/Entities/Common/VideoSources.cs create mode 100644 OF DL/Models/Entities/Posts/ListItem.cs create mode 100644 OF DL/Models/Entities/Posts/Medium.cs create mode 100644 OF DL/Models/Entities/Posts/Post.cs create mode 100644 OF DL/Models/Entities/Posts/PostCollection.cs create mode 100644 OF DL/Models/Entities/Posts/SinglePost.cs create mode 100644 OF DL/Models/Entities/Posts/SinglePostCollection.cs create mode 100644 OF DL/Models/Mappers/PostMapper.cs delete mode 100644 OF DL/Models/Post/Post.cs delete mode 100644 OF DL/Models/Post/PostCollection.cs delete mode 100644 OF DL/Models/Post/SinglePost.cs delete mode 100644 OF DL/Models/Post/SinglePostCollection.cs diff --git a/OF DL/Models/Dtos/Posts/InfoDto.cs b/OF DL/Models/Dtos/Posts/InfoDto.cs new file mode 100644 index 0000000..6a7bcf3 --- /dev/null +++ b/OF DL/Models/Dtos/Posts/InfoDto.cs @@ -0,0 +1,11 @@ +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(); +} diff --git a/OF DL/Models/Dtos/Posts/ListItemDto.cs b/OF DL/Models/Dtos/Posts/ListItemDto.cs new file mode 100644 index 0000000..d4196e8 --- /dev/null +++ b/OF DL/Models/Dtos/Posts/ListItemDto.cs @@ -0,0 +1,101 @@ +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 MentionedUsers { get; set; } = []; + + [JsonProperty("linkedUsers")] public List LinkedUsers { get; set; } = []; + + [JsonProperty("canVote")] public bool? CanVote { get; set; } + + [JsonProperty("media")] public List Media { get; set; } = []; + + [JsonProperty("canViewMedia")] public bool? CanViewMedia { get; set; } + + [JsonProperty("preview")] public List Preview { get; set; } = []; +} diff --git a/OF DL/Models/Dtos/Posts/MediumDto.cs b/OF DL/Models/Dtos/Posts/MediumDto.cs new file mode 100644 index 0000000..39d785c --- /dev/null +++ b/OF DL/Models/Dtos/Posts/MediumDto.cs @@ -0,0 +1,37 @@ +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(); +} diff --git a/OF DL/Models/Dtos/Posts/PostDto.cs b/OF DL/Models/Dtos/Posts/PostDto.cs new file mode 100644 index 0000000..8b7fbeb --- /dev/null +++ b/OF DL/Models/Dtos/Posts/PostDto.cs @@ -0,0 +1,14 @@ +using Newtonsoft.Json; + +namespace OF_DL.Models.Dtos.Posts; + +public class PostDto +{ + [JsonProperty("list")] public List List { get; set; } = []; + + [JsonProperty("hasMore")] public bool HasMore { get; set; } + + [JsonProperty("headMarker")] public string HeadMarker { get; set; } = ""; + + [JsonProperty("tailMarker")] public string TailMarker { get; set; } = ""; +} diff --git a/OF DL/Models/Dtos/Posts/SinglePostDto.cs b/OF DL/Models/Dtos/Posts/SinglePostDto.cs new file mode 100644 index 0000000..d37073e --- /dev/null +++ b/OF DL/Models/Dtos/Posts/SinglePostDto.cs @@ -0,0 +1,99 @@ +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 MentionedUsers { get; set; } = []; + + [JsonProperty("linkedUsers")] public List LinkedUsers { get; set; } = []; + + [JsonProperty("tipsAmount")] public string TipsAmount { get; set; } = ""; + + [JsonProperty("tipsAmountRaw")] public string TipsAmountRaw { get; set; } = ""; + + [JsonProperty("media")] public List Media { get; set; } = []; + + [JsonProperty("canViewMedia")] public bool CanViewMedia { get; set; } + + [JsonProperty("preview")] public List Preview { get; set; } = []; +} diff --git a/OF DL/Models/Entities/Common/Files.cs b/OF DL/Models/Entities/Common/Files.cs index 97bdadb..4f50965 100644 --- a/OF DL/Models/Entities/Common/Files.cs +++ b/OF DL/Models/Entities/Common/Files.cs @@ -4,5 +4,7 @@ public class Files { public Full? Full { get; set; } + public Preview? Preview { get; set; } + public Drm? Drm { get; set; } } diff --git a/OF DL/Models/Entities/Common/Preview.cs b/OF DL/Models/Entities/Common/Preview.cs new file mode 100644 index 0000000..a3d6edb --- /dev/null +++ b/OF DL/Models/Entities/Common/Preview.cs @@ -0,0 +1,6 @@ +namespace OF_DL.Models.Entities.Common; + +public class Preview +{ + public string? Url { get; set; } +} diff --git a/OF DL/Models/Entities/Common/VideoSources.cs b/OF DL/Models/Entities/Common/VideoSources.cs new file mode 100644 index 0000000..92422c0 --- /dev/null +++ b/OF DL/Models/Entities/Common/VideoSources.cs @@ -0,0 +1,8 @@ +namespace OF_DL.Models.Entities.Common; + +public class VideoSources +{ + public string? _720 { get; set; } + + public string? _240 { get; set; } +} diff --git a/OF DL/Models/Entities/Posts/ListItem.cs b/OF DL/Models/Entities/Posts/ListItem.cs new file mode 100644 index 0000000..e5a2f5b --- /dev/null +++ b/OF DL/Models/Entities/Posts/ListItem.cs @@ -0,0 +1,41 @@ +using OF_DL.Models.Entities.Common; +using OF_DL.Utils; + +namespace OF_DL.Models.Entities.Posts; + +public class ListItem +{ + private string _rawText = ""; + + public long Id { get; set; } + + public DateTime PostedAt { get; set; } + + public Author? Author { get; set; } + + public string Text { get; set; } = ""; + + public string RawText + { + get + { + if (string.IsNullOrEmpty(_rawText)) + { + _rawText = XmlUtils.EvaluateInnerText(Text); + } + + return _rawText; + } + set => _rawText = value; + } + + public bool IsOpened { get; set; } + + public string? Price { get; set; } + + public bool IsArchived { get; set; } + + public List? Media { get; set; } + + public List? Preview { get; set; } +} diff --git a/OF DL/Models/Entities/Posts/Medium.cs b/OF DL/Models/Entities/Posts/Medium.cs new file mode 100644 index 0000000..88eab10 --- /dev/null +++ b/OF DL/Models/Entities/Posts/Medium.cs @@ -0,0 +1,18 @@ +using OF_DL.Models.Entities.Common; + +namespace OF_DL.Models.Entities.Posts; + +public class Medium +{ + public long Id { get; set; } + + public string Type { get; set; } = ""; + + public bool CanView { get; set; } + + public string? Preview { get; set; } + + public Files? Files { get; set; } + + public VideoSources? VideoSources { get; set; } +} diff --git a/OF DL/Models/Entities/Posts/Post.cs b/OF DL/Models/Entities/Posts/Post.cs new file mode 100644 index 0000000..d914824 --- /dev/null +++ b/OF DL/Models/Entities/Posts/Post.cs @@ -0,0 +1,10 @@ +namespace OF_DL.Models.Entities.Posts; + +public class Post +{ + public List List { get; set; } = []; + + public bool HasMore { get; set; } + + public string? TailMarker { get; set; } +} diff --git a/OF DL/Models/Entities/Posts/PostCollection.cs b/OF DL/Models/Entities/Posts/PostCollection.cs new file mode 100644 index 0000000..c5cecba --- /dev/null +++ b/OF DL/Models/Entities/Posts/PostCollection.cs @@ -0,0 +1,10 @@ +namespace OF_DL.Models.Entities.Posts; + +public class PostCollection +{ + public List PostMedia { get; set; } = []; + + public List PostObjects { get; set; } = []; + + public Dictionary Posts { get; set; } = new(); +} diff --git a/OF DL/Models/Entities/Posts/SinglePost.cs b/OF DL/Models/Entities/Posts/SinglePost.cs new file mode 100644 index 0000000..9875864 --- /dev/null +++ b/OF DL/Models/Entities/Posts/SinglePost.cs @@ -0,0 +1,41 @@ +using OF_DL.Models.Entities.Common; +using OF_DL.Utils; + +namespace OF_DL.Models.Entities.Posts; + +public class SinglePost +{ + private string _rawText = ""; + + public long Id { get; set; } + + public DateTime PostedAt { get; set; } + + public Author? Author { get; set; } + + public string Text { get; set; } = ""; + + public string RawText + { + get + { + if (string.IsNullOrEmpty(_rawText)) + { + _rawText = XmlUtils.EvaluateInnerText(Text); + } + + return _rawText; + } + set => _rawText = value; + } + + public bool IsOpened { get; set; } + + public string? Price { get; set; } + + public bool IsArchived { get; set; } + + public List? Media { get; set; } + + public List? Preview { get; set; } +} diff --git a/OF DL/Models/Entities/Posts/SinglePostCollection.cs b/OF DL/Models/Entities/Posts/SinglePostCollection.cs new file mode 100644 index 0000000..9afc43c --- /dev/null +++ b/OF DL/Models/Entities/Posts/SinglePostCollection.cs @@ -0,0 +1,10 @@ +namespace OF_DL.Models.Entities.Posts; + +public class SinglePostCollection +{ + public List SinglePostMedia { get; set; } = []; + + public List SinglePostObjects { get; set; } = []; + + public Dictionary SinglePosts { get; set; } = new(); +} diff --git a/OF DL/Models/Mappers/ArchivedMapper.cs b/OF DL/Models/Mappers/ArchivedMapper.cs index 22666b8..2ef0d09 100644 --- a/OF DL/Models/Mappers/ArchivedMapper.cs +++ b/OF DL/Models/Mappers/ArchivedMapper.cs @@ -77,15 +77,8 @@ public static class ArchivedMapper return new Entities.Common.Files { Full = MapFull(dto.Full), Drm = MapDrm(dto.Drm) }; } - private static Entities.Common.Full? MapFull(FullDto? dto) - { - if (dto == null) - { - return null; - } - - return new Entities.Common.Full { Url = dto.Url }; - } + private static Entities.Common.Full? MapFull(FullDto? dto) => + dto == null ? null : new Entities.Common.Full { Url = dto.Url }; private static Entities.Common.Drm? MapDrm(DrmDto? dto) { @@ -100,25 +93,11 @@ public static class ArchivedMapper }; } - private static Entities.Common.Manifest? MapManifest(ManifestDto? dto) - { - if (dto == null) - { - return null; - } + private static Entities.Common.Manifest? MapManifest(ManifestDto? dto) => + dto == null ? null : new Entities.Common.Manifest { Dash = dto.Dash }; - return new Entities.Common.Manifest { Dash = dto.Dash }; - } - - private static Entities.Common.Signature? MapSignature(SignatureDto? dto) - { - if (dto == null) - { - return null; - } - - return new Entities.Common.Signature { Dash = MapDash(dto.Dash) }; - } + private static Entities.Common.Signature? MapSignature(SignatureDto? dto) => + dto == null ? null : new Entities.Common.Signature { Dash = MapDash(dto.Dash) }; private static Entities.Common.Dash? MapDash(DashDto? dto) { diff --git a/OF DL/Models/Mappers/MessagesMapper.cs b/OF DL/Models/Mappers/MessagesMapper.cs index bedf505..3f3f750 100644 --- a/OF DL/Models/Mappers/MessagesMapper.cs +++ b/OF DL/Models/Mappers/MessagesMapper.cs @@ -66,27 +66,14 @@ public static class MessagesMapper private static FromUser? MapFromUser(FromUserDto? dto) => dto == null ? null : new FromUser { Id = dto.Id }; - private static Files? MapFiles(FilesDto? dto) - { - if (dto == null) - { - return null; - } - - return new Files { Full = MapFull(dto.Full), Drm = MapDrm(dto.Drm) }; - } + private static Files? MapFiles(FilesDto? dto) => + dto == null ? null : new Files { Full = MapFull(dto.Full), Drm = MapDrm(dto.Drm) }; private static Full? MapFull(FullDto? dto) => dto == null ? null : new Full { Url = dto.Url }; - private static Drm? MapDrm(DrmDto? dto) - { - if (dto == null) - { - return null; - } - - return new Drm { Manifest = MapManifest(dto.Manifest), Signature = MapSignature(dto.Signature) }; - } + private static Drm? MapDrm(DrmDto? dto) => dto == null + ? null + : new Drm { Manifest = MapManifest(dto.Manifest), Signature = MapSignature(dto.Signature) }; private static Manifest? MapManifest(ManifestDto? dto) => dto == null ? null : new Manifest { Dash = dto.Dash }; diff --git a/OF DL/Models/Mappers/PostMapper.cs b/OF DL/Models/Mappers/PostMapper.cs new file mode 100644 index 0000000..00c1b8f --- /dev/null +++ b/OF DL/Models/Mappers/PostMapper.cs @@ -0,0 +1,182 @@ +using OF_DL.Models.Dtos.Common; +using OF_DL.Models.Dtos.Posts; +using OF_DL.Models.Entities.Common; +using OF_DL.Models.Entities.Posts; + + +namespace OF_DL.Models.Mappers; + +public static class PostMapper +{ + public static Post FromDto(PostDto? dto) + { + Post mapped = new() { HasMore = dto?.HasMore ?? false, TailMarker = dto?.TailMarker }; + + if (dto?.List == null) + { + return mapped; + } + + foreach (ListItemDto entry in dto.List) + { + mapped.List.Add(MapList(entry)); + } + + return mapped; + } + + public static SinglePost FromDto(SinglePostDto? dto) + { + SinglePost mapped = new(); + + if (dto == null) + { + return mapped; + } + + mapped.Id = dto.Id; + mapped.PostedAt = dto.PostedAt; + mapped.Author = MapSingleAuthor(dto.Author); + mapped.Text = dto.Text; + mapped.RawText = dto.RawText; + mapped.IsOpened = dto.IsOpened; + mapped.Price = dto.Price; + mapped.IsArchived = dto.IsArchived; + mapped.Media = MapSingleMedia(dto.Media); + mapped.Preview = dto.Preview; + + return mapped; + } + + private static ListItem MapList(ListItemDto dto) => + new() + { + Id = dto.Id, + PostedAt = dto.PostedAt, + Author = MapAuthor(dto.Author), + Text = dto.Text, + RawText = dto.RawText, + IsOpened = dto.IsOpened, + Price = dto.Price, + IsArchived = dto.IsArchived, + Media = MapMedia(dto.Media), + Preview = dto.Preview + }; + + private static Author? MapAuthor(AuthorDto? dto) => + dto == null ? null : new Author { Id = dto.Id }; + + private static Author? MapSingleAuthor(AuthorDto? dto) => + dto == null ? null : new Author { Id = dto.Id }; + + private static List? MapMedia(List? media) => + media?.Select(MapMedium).ToList(); + + private static Medium MapMedium(MediumDto dto) => + new() + { + Id = dto.Id, + Type = dto.Type, + CanView = dto.CanView, + Preview = dto.Preview, + Files = MapFiles(dto.Files) + }; + + private static Files? MapFiles(FilesDto? dto) => dto == null + ? null + : new Files { Full = MapFull(dto.Full), Preview = MapPreview(dto.Preview), Drm = MapDrm(dto.Drm) }; + + private static Full? MapFull(FullDto? dto) => + dto == null || string.IsNullOrEmpty(dto.Url) ? null : new Full { Url = dto.Url }; + + private static Preview? MapPreview(PreviewDto? dto) => + dto == null || string.IsNullOrEmpty(dto.Url) ? null : new Preview { Url = dto.Url }; + + private static Drm MapDrm(DrmDto? dto) => new() + { + Manifest = MapManifest(dto?.Manifest), Signature = MapSignature(dto?.Signature) + }; + + private static Manifest? MapManifest(ManifestDto? dto) => + dto == null ? null : new Manifest { Dash = dto.Dash }; + + private static Signature? MapSignature(SignatureDto? dto) => + dto == null ? null : new Signature { Dash = MapDash(dto.Dash) }; + + private static Dash? MapDash(DashDto? dto) + { + if (dto == null) + { + return null; + } + + return new Dash + { + CloudFrontPolicy = dto.CloudFrontPolicy, + CloudFrontSignature = dto.CloudFrontSignature, + CloudFrontKeyPairId = dto.CloudFrontKeyPairId + }; + } + + private static List? MapSingleMedia(List? media) => + media?.Select(MapSingleMedium).ToList(); + + private static Medium MapSingleMedium(MediumDto dto) => + new() + { + Id = dto.Id, + Type = dto.Type, + CanView = dto.CanView, + Preview = dto.Preview, + Files = MapSingleFiles(dto.Files), + VideoSources = MapVideoSources(dto.VideoSources) + }; + + private static Files? MapSingleFiles(FilesDto? dto) + { + if (dto == null) + { + return null; + } + + return new Files + { + Full = MapSingleFull(dto.Full), Preview = MapSinglePreview(dto.Preview), Drm = MapSingleDrm(dto.Drm) + }; + } + + private static Full? MapSingleFull(FullDto? dto) => + dto == null || string.IsNullOrEmpty(dto.Url) ? null : new Full { Url = dto.Url }; + + private static Preview? MapSinglePreview(PreviewDto? dto) => + dto == null || string.IsNullOrEmpty(dto.Url) ? null : new Preview { Url = dto.Url }; + + private static Drm? MapSingleDrm(DrmDto? dto) => dto == null + ? null + : new Drm { Manifest = MapSingleManifest(dto.Manifest), Signature = MapSingleSignature(dto.Signature) }; + + private static Manifest? MapSingleManifest(ManifestDto? dto) => + dto == null ? null : new Manifest { Dash = dto.Dash }; + + private static Signature? MapSingleSignature(SignatureDto? dto) => + dto == null ? null : new Signature { Dash = MapSingleDash(dto.Dash) }; + + private static Dash? MapSingleDash(DashDto? dto) + { + if (dto == null) + { + return null; + } + + return new Dash + { + CloudFrontPolicy = dto.CloudFrontPolicy, + CloudFrontSignature = dto.CloudFrontSignature, + CloudFrontKeyPairId = dto.CloudFrontKeyPairId + }; + } + + private static VideoSources? MapVideoSources(VideoSourcesDto? dto) => dto == null + ? null + : new VideoSources { _240 = dto._240, _720 = dto._720 }; +} diff --git a/OF DL/Models/Post/Post.cs b/OF DL/Models/Post/Post.cs deleted file mode 100644 index e61a48c..0000000 --- a/OF DL/Models/Post/Post.cs +++ /dev/null @@ -1,200 +0,0 @@ -using Newtonsoft.Json; -using OF_DL.Utils; - -namespace OF_DL.Models.Post; - -#pragma warning disable IDE1006 // Naming Styles -public class Post -{ - public List list { get; set; } - public bool hasMore { get; set; } - - public string headMarker { get; set; } - - public string tailMarker { get; set; } - - public class Author - { - public long id { get; set; } - public string _view { get; set; } - } - - public class Dash - { - [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; } - } - - public class Drm - { - public Manifest manifest { get; set; } - public Signature signature { get; set; } - } - - public class Files - { - public Full full { get; set; } - public Thumb thumb { get; set; } - public Preview preview { get; set; } - public SquarePreview squarePreview { get; set; } - public Drm drm { get; set; } - } - - public class Full - { - public string url { get; set; } - public int width { get; set; } - public int height { get; set; } - public long size { get; set; } - public List sources { get; set; } - } - - public class SquarePreview - { - public string url { get; set; } - public int width { get; set; } - public int height { get; set; } - public long size { get; set; } - } - - public class Thumb - { - public string url { get; set; } - public int width { get; set; } - public int height { get; set; } - public long size { get; set; } - } - - public class Hls - { - [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; } - } - - public class Info - { - public Source source { get; set; } - public Preview preview { get; set; } - } - - public class List - { - private string _rawText; - public string responseType { get; set; } - public long id { get; set; } - public DateTime postedAt { get; set; } - public string postedAtPrecise { get; set; } - public object expiredAt { get; set; } - public Author author { get; set; } - public string text { get; set; } - - public string rawText - { - get - { - if (string.IsNullOrEmpty(_rawText)) - { - _rawText = XmlUtils.EvaluateInnerText(text); - } - - return _rawText; - } - set => _rawText = value; - } - - public bool? lockedText { get; set; } - public bool? isFavorite { get; set; } - public bool? canReport { get; set; } - public bool? canDelete { get; set; } - public bool? canComment { get; set; } - public bool? canEdit { get; set; } - public bool? isPinned { get; set; } - public int? favoritesCount { get; set; } - public int? mediaCount { get; set; } - public bool? isMediaReady { get; set; } - public object voting { get; set; } - public bool isOpened { get; set; } - public bool? canToggleFavorite { get; set; } - public object streamId { get; set; } - public string? price { get; set; } - public bool? hasVoting { get; set; } - public bool? isAddedToBookmarks { get; set; } - public bool isArchived { get; set; } - public bool? isPrivateArchived { get; set; } - public bool? isDeleted { get; set; } - public bool? hasUrl { get; set; } - public bool? isCouplePeopleMedia { get; set; } - public string cantCommentReason { get; set; } - public int? votingType { get; set; } - public int? commentsCount { get; set; } - public List mentionedUsers { get; set; } - public List linkedUsers { get; set; } - public bool? canVote { get; set; } - public List media { get; set; } - public bool? canViewMedia { get; set; } - public List preview { get; set; } - } - - public class Manifest - { - public string? hls { get; set; } - public string? dash { get; set; } - } - - public class Medium - { - public long id { get; set; } - public string type { get; set; } - public bool? convertedToVideo { get; set; } - public bool canView { get; set; } - public bool? hasError { get; set; } - public DateTime? createdAt { get; set; } - public Info info { get; set; } - public Source source { get; set; } - public string squarePreview { get; set; } - public string full { get; set; } - public string preview { get; set; } - public string thumb { get; set; } - public Files files { get; set; } - public VideoSources videoSources { get; set; } - } - - public class Preview - { - public int? width { get; set; } - public int? height { get; set; } - public int? size { get; set; } - public string url { get; set; } - } - - public class Signature - { - public Hls hls { get; set; } - public Dash dash { get; set; } - } - - public class Source - { - public string? source { get; set; } - public int? width { get; set; } - public int? height { get; set; } - public int? size { get; set; } - public int? duration { get; set; } - } - - public class VideoSources - { - [JsonProperty("720")] public object _720 { get; set; } - - [JsonProperty("240")] public object _240 { get; set; } - } -#pragma warning restore IDE1006 // Naming Styles -} diff --git a/OF DL/Models/Post/PostCollection.cs b/OF DL/Models/Post/PostCollection.cs deleted file mode 100644 index 861a20c..0000000 --- a/OF DL/Models/Post/PostCollection.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace OF_DL.Models.Post; - -public class PostCollection -{ - public List PostMedia = new(); - public List PostObjects = new(); - public Dictionary Posts = new(); -} diff --git a/OF DL/Models/Post/SinglePost.cs b/OF DL/Models/Post/SinglePost.cs deleted file mode 100644 index d3b2fba..0000000 --- a/OF DL/Models/Post/SinglePost.cs +++ /dev/null @@ -1,188 +0,0 @@ -using Newtonsoft.Json; -using OF_DL.Utils; - -namespace OF_DL.Models.Post; - -public class SinglePost -{ - private string _rawText; - public string responseType { get; set; } - public long id { get; set; } - public DateTime postedAt { get; set; } - public string postedAtPrecise { get; set; } - public object expiredAt { get; set; } - public Author author { get; set; } - public string text { get; set; } - - public string rawText - { - get - { - if (string.IsNullOrEmpty(_rawText)) - { - _rawText = XmlUtils.EvaluateInnerText(text); - } - - return _rawText; - } - set => _rawText = value; - } - - public bool lockedText { get; set; } - public bool isFavorite { get; set; } - public bool canReport { get; set; } - public bool canDelete { get; set; } - public bool canComment { get; set; } - public bool canEdit { get; set; } - public bool isPinned { get; set; } - public int favoritesCount { get; set; } - public int mediaCount { get; set; } - public bool isMediaReady { get; set; } - public object voting { get; set; } - public bool isOpened { get; set; } - public bool canToggleFavorite { get; set; } - public string streamId { get; set; } - public string price { get; set; } - public bool hasVoting { get; set; } - public bool isAddedToBookmarks { get; set; } - public bool isArchived { get; set; } - public bool isPrivateArchived { get; set; } - public bool isDeleted { get; set; } - public bool hasUrl { get; set; } - public bool isCouplePeopleMedia { get; set; } - public int commentsCount { get; set; } - public List mentionedUsers { get; set; } - public List linkedUsers { get; set; } - public string tipsAmount { get; set; } - public string tipsAmountRaw { get; set; } - public List media { get; set; } - public bool canViewMedia { get; set; } - public List preview { get; set; } - - public class Author - { - public long id { get; set; } - public string _view { get; set; } - } - - public class Files - { - public Full full { get; set; } - public Thumb thumb { get; set; } - public Preview preview { get; set; } - public SquarePreview squarePreview { get; set; } - public Drm drm { get; set; } - } - - public class Full - { - public string url { get; set; } - public int width { get; set; } - public int height { get; set; } - public long size { get; set; } - public List sources { get; set; } - } - - public class SquarePreview - { - public string url { get; set; } - public int width { get; set; } - public int height { get; set; } - public long size { get; set; } - } - - public class Thumb - { - public string url { get; set; } - public int width { get; set; } - public int height { get; set; } - public long size { get; set; } - } - - public class Info - { - public Source source { get; set; } - public Preview preview { get; set; } - } - - public class Medium - { - public long id { get; set; } - public string type { get; set; } - public bool convertedToVideo { get; set; } - public bool canView { get; set; } - public bool hasError { get; set; } - public DateTime? createdAt { get; set; } - public Info info { get; set; } - public Source source { get; set; } - public string squarePreview { get; set; } - public string full { get; set; } - public string preview { get; set; } - public string thumb { get; set; } - public bool hasCustomPreview { get; set; } - public Files files { get; set; } - public VideoSources videoSources { get; set; } - } - - public class Preview - { - public int width { get; set; } - public int height { get; set; } - public long size { get; set; } - public string url { get; set; } - } - - public class Source - { - public string source { get; set; } - public int width { get; set; } - public int height { get; set; } - public long size { get; set; } - public int duration { get; set; } - } - - public class VideoSources - { - [JsonProperty("720")] public string _720 { get; set; } - - [JsonProperty("240")] public string _240 { get; set; } - } - - public class Dash - { - [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; } - } - - public class Drm - { - public Manifest manifest { get; set; } - public Signature signature { get; set; } - } - - public class Hls - { - [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; } - } - - public class Manifest - { - public string? hls { get; set; } - public string? dash { get; set; } - } - - public class Signature - { - public Hls hls { get; set; } - public Dash dash { get; set; } - } -} diff --git a/OF DL/Models/Post/SinglePostCollection.cs b/OF DL/Models/Post/SinglePostCollection.cs deleted file mode 100644 index d1992b8..0000000 --- a/OF DL/Models/Post/SinglePostCollection.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace OF_DL.Models.Post; - -public class SinglePostCollection -{ - public List SinglePostMedia = new(); - public List SinglePostObjects = new(); - public Dictionary SinglePosts = new(); -} diff --git a/OF DL/Program.cs b/OF DL/Program.cs index 287f50e..3f71c3e 100644 --- a/OF DL/Program.cs +++ b/OF DL/Program.cs @@ -7,13 +7,13 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OF_DL.CLI; using OF_DL.Models; -using OF_DL.Models.Post; using OF_DL.Models.Purchased; using OF_DL.Models.Streams; using OF_DL.Enumerations; using OF_DL.Helpers; using ArchivedEntities = OF_DL.Models.Entities.Archived; using MessageEntities = OF_DL.Models.Entities.Messages; +using PostEntities = OF_DL.Models.Entities.Posts; using OF_DL.Services; using Serilog; using Spectre.Console; @@ -33,7 +33,7 @@ public class Program(IServiceProvider serviceProvider) IAuthService authService = serviceProvider.GetRequiredService(); bool runningInDocker = Environment.GetEnvironmentVariable("OFDL_DOCKER") != null; - // Show initial message + // Show the initial message AnsiConsole.MarkupLine("[yellow]Downloading dependencies. Please wait ...[/]"); // Show instructions based on the environment @@ -1334,7 +1334,7 @@ public class Program(IServiceProvider serviceProvider) "[red]Getting Posts (this may take a long time, depending on the number of Posts the creator has)\n[/]"); Log.Debug($"Calling DownloadFreePosts - {user.Key}"); - PostCollection posts = new(); + PostEntities.PostCollection posts = new(); await AnsiConsole.Status() .StartAsync("[red]Getting Posts[/]", @@ -2131,7 +2131,7 @@ public class Program(IServiceProvider serviceProvider) Log.Debug($"Calling DownloadSinglePost - {post_id.ToString()}"); AnsiConsole.Markup("[red]Getting Post\n[/]"); - SinglePostCollection post = await apiService.GetPost($"/posts/{post_id.ToString()}", path); + PostEntities.SinglePostCollection post = await apiService.GetPost($"/posts/{post_id.ToString()}", path); if (post == null) { AnsiConsole.Markup("[red]Couldn't find post\n[/]"); @@ -2193,9 +2193,9 @@ public class Program(IServiceProvider serviceProvider) pssh); } - SinglePost.Medium mediaInfo = post.SinglePostMedia.FirstOrDefault(m => m.id == postKVP.Key); - SinglePost postInfo = - post.SinglePostObjects.FirstOrDefault(p => p?.media?.Contains(mediaInfo) == true); + PostEntities.Medium mediaInfo = post.SinglePostMedia.FirstOrDefault(m => m.Id == postKVP.Key); + PostEntities.SinglePost postInfo = + post.SinglePostObjects.FirstOrDefault(p => p?.Media?.Contains(mediaInfo) == true); isNew = await downloadService.DownloadPostDRMVideo( policy, @@ -2212,17 +2212,17 @@ public class Program(IServiceProvider serviceProvider) string.Empty, postInfo, mediaInfo, - postInfo?.author, + postInfo?.Author, users); } else { try { - SinglePost.Medium? mediaInfo = - post.SinglePostMedia.FirstOrDefault(m => m?.id == postKVP.Key); - SinglePost? postInfo = - post.SinglePostObjects.FirstOrDefault(p => p?.media?.Contains(mediaInfo) == true); + PostEntities.Medium? mediaInfo = + post.SinglePostMedia.FirstOrDefault(m => m.Id == postKVP.Key); + PostEntities.SinglePost? postInfo = + post.SinglePostObjects.FirstOrDefault(p => p?.Media?.Contains(mediaInfo) == true); isNew = await downloadService.DownloadPostMedia( postKVP.Value, @@ -2234,7 +2234,7 @@ public class Program(IServiceProvider serviceProvider) .PostFileNameFormat ?? string.Empty, postInfo, mediaInfo, - postInfo?.author, + postInfo?.Author, users); } catch diff --git a/OF DL/Services/APIService.cs b/OF DL/Services/APIService.cs index 576d06a..e48dc3c 100644 --- a/OF DL/Services/APIService.cs +++ b/OF DL/Services/APIService.cs @@ -6,12 +6,12 @@ using System.Xml.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OF_DL.Models; -using OF_DL.Models.Post; using OF_DL.Models.Purchased; using OF_DL.Models.Stories; using OF_DL.Models.Streams; using OF_DL.Enumerations; using ArchivedDtos = OF_DL.Models.Dtos.Archived; +using PostDtos = OF_DL.Models.Dtos.Posts; using MessageDtos = OF_DL.Models.Dtos.Messages; using ListDtos = OF_DL.Models.Dtos.Lists; using HighlightDtos = OF_DL.Models.Dtos.Highlights; @@ -19,12 +19,14 @@ using ArchivedEntities = OF_DL.Models.Entities.Archived; using HighlightEntities = OF_DL.Models.Entities.Highlights; using ListEntities = OF_DL.Models.Entities.Lists; using MessageEntities = OF_DL.Models.Entities.Messages; +using PostEntities = OF_DL.Models.Entities.Posts; using OF_DL.Models.Mappers; using OF_DL.Widevine; using Serilog; using Spectre.Console; using static OF_DL.Utils.HttpUtil; using Constants = OF_DL.Helpers.Constants; +using SinglePostCollection = OF_DL.Models.Entities.Posts.SinglePostCollection; namespace OF_DL.Services; @@ -795,15 +797,15 @@ public class APIService(IAuthService authService, IConfigService configService, } - public async Task GetPosts(string endpoint, string folder, List paid_post_ids, + public async Task GetPosts(string endpoint, string folder, List paid_post_ids, StatusContext ctx) { Log.Debug($"Calling GetPosts - {endpoint}"); try { - Post posts = new(); - PostCollection postCollection = new(); + PostEntities.Post posts = new(); + PostEntities.PostCollection postCollection = new(); int post_limit = 50; Dictionary getParams = new() { @@ -838,31 +840,35 @@ public class APIService(IAuthService authService, IConfigService configService, downloadAsOf); string? body = await BuildHeaderAndExecuteRequests(getParams, endpoint, new HttpClient()); - posts = JsonConvert.DeserializeObject(body, m_JsonSerializerSettings); + PostDtos.PostDto? postsDto = + JsonConvert.DeserializeObject(body, m_JsonSerializerSettings); + posts = PostMapper.FromDto(postsDto); ctx.Status( - $"[red]Getting Posts (this may take a long time, depending on the number of Posts the creator has)\n[/] [red]Found {posts.list.Count}[/]"); + $"[red]Getting Posts (this may take a long time, depending on the number of Posts the creator has)\n[/] [red]Found {posts.List.Count}[/]"); ctx.Spinner(Spinner.Known.Dots); ctx.SpinnerStyle(Style.Parse("blue")); - if (posts != null && posts.hasMore) + if (posts != null && posts.HasMore) { UpdateGetParamsForDateSelection( downloadDateSelection, ref getParams, - posts.tailMarker); + posts.TailMarker); while (true) { - Post newposts = new(); + PostEntities.Post newposts = new(); string? loopbody = await BuildHeaderAndExecuteRequests(getParams, endpoint, GetHttpClient()); - newposts = JsonConvert.DeserializeObject(loopbody, m_JsonSerializerSettings); + PostDtos.PostDto? newPostsDto = + JsonConvert.DeserializeObject(loopbody, m_JsonSerializerSettings); + newposts = PostMapper.FromDto(newPostsDto); - posts.list.AddRange(newposts.list); + posts.List.AddRange(newposts.List); ctx.Status( - $"[red]Getting Posts (this may take a long time, depending on the number of Posts the creator has)\n[/] [red]Found {posts.list.Count}[/]"); + $"[red]Getting Posts (this may take a long time, depending on the number of Posts the creator has)\n[/] [red]Found {posts.List.Count}[/]"); ctx.Spinner(Spinner.Known.Dots); ctx.SpinnerStyle(Style.Parse("blue")); - if (!newposts.hasMore) + if (!newposts.HasMore) { break; } @@ -870,33 +876,33 @@ public class APIService(IAuthService authService, IConfigService configService, UpdateGetParamsForDateSelection( downloadDateSelection, ref getParams, - newposts.tailMarker); + newposts.TailMarker); } } - foreach (Post.List post in posts.list) + foreach (PostEntities.ListItem post in posts.List) { if (configService.CurrentConfig.SkipAds) { - if (post.rawText != null && (post.rawText.Contains("#ad") || post.rawText.Contains("/trial/") || - post.rawText.Contains("#announcement"))) + if (post.RawText != null && (post.RawText.Contains("#ad") || post.RawText.Contains("/trial/") || + post.RawText.Contains("#announcement"))) { continue; } - if (post.text != null && (post.text.Contains("#ad") || post.text.Contains("/trial/") || - post.text.Contains("#announcement"))) + if (post.Text != null && (post.Text.Contains("#ad") || post.Text.Contains("/trial/") || + post.Text.Contains("#announcement"))) { continue; } } List postPreviewIds = new(); - if (post.preview != null && post.preview.Count > 0) + if (post.Preview != null && post.Preview.Count > 0) { - for (int i = 0; i < post.preview.Count; i++) + for (int i = 0; i < post.Preview.Count; i++) { - if (post.preview[i] is long previewId) + if (post.Preview[i] is long previewId) { if (!postPreviewIds.Contains(previewId)) { @@ -906,87 +912,87 @@ public class APIService(IAuthService authService, IConfigService configService, } } - await dbService.AddPost(folder, post.id, post.rawText != null ? post.rawText : string.Empty, - post.price != null ? post.price : "0", post.price != null && post.isOpened ? true : false, - post.isArchived, post.postedAt); + await dbService.AddPost(folder, post.Id, post.RawText != null ? post.RawText : string.Empty, + post.Price != null ? post.Price : "0", post.Price != null && post.IsOpened ? true : false, + post.IsArchived, post.PostedAt); postCollection.PostObjects.Add(post); - if (post.media != null && post.media.Count > 0) + if (post.Media != null && post.Media.Count > 0) { - foreach (Post.Medium medium in post.media) + foreach (PostEntities.Medium medium in post.Media) { - if (medium.type == "photo" && !configService.CurrentConfig.DownloadImages) + if (medium.Type == "photo" && !configService.CurrentConfig.DownloadImages) { continue; } - if (medium.type == "video" && !configService.CurrentConfig.DownloadVideos) + if (medium.Type == "video" && !configService.CurrentConfig.DownloadVideos) { continue; } - if (medium.type == "gif" && !configService.CurrentConfig.DownloadVideos) + if (medium.Type == "gif" && !configService.CurrentConfig.DownloadVideos) { continue; } - if (medium.type == "audio" && !configService.CurrentConfig.DownloadAudios) + if (medium.Type == "audio" && !configService.CurrentConfig.DownloadAudios) { continue; } - if (medium.canView && medium.files?.drm == null) + if (medium.CanView && medium.Files?.Drm == null) { - bool has = paid_post_ids.Any(cus => cus.Equals(medium.id)); - if (medium.files!.full != null && !string.IsNullOrEmpty(medium.files!.full.url)) + bool has = paid_post_ids.Any(cus => cus.Equals(medium.Id)); + if (medium.Files!.Full != null && !string.IsNullOrEmpty(medium.Files!.Full.Url)) { if (!has) { - if (!postCollection.Posts.ContainsKey(medium.id)) + if (!postCollection.Posts.ContainsKey(medium.Id)) { - await dbService.AddMedia(folder, medium.id, post.id, medium.files!.full.url, + await dbService.AddMedia(folder, medium.Id, post.Id, medium.Files!.Full.Url, null, null, null, "Posts", - medium.type == "photo" ? "Images" : - medium.type == "video" || medium.type == "gif" ? "Videos" : - medium.type == "audio" ? "Audios" : null, - postPreviewIds.Contains(medium.id) ? true : false, false, null); - postCollection.Posts.Add(medium.id, medium.files!.full.url); + medium.Type == "photo" ? "Images" : + medium.Type == "video" || medium.Type == "gif" ? "Videos" : + medium.Type == "audio" ? "Audios" : null, + postPreviewIds.Contains(medium.Id) ? true : false, false, null); + postCollection.Posts.Add(medium.Id, medium.Files!.Full.Url); postCollection.PostMedia.Add(medium); } } } - else if (medium.files.preview != null && medium.files!.full == null) + else if (medium.Files.Preview != null && medium.Files!.Full == null) { if (!has) { - if (!postCollection.Posts.ContainsKey(medium.id)) + if (!postCollection.Posts.ContainsKey(medium.Id)) { - await dbService.AddMedia(folder, medium.id, post.id, medium.files.preview.url, + await dbService.AddMedia(folder, medium.Id, post.Id, medium.Files.Preview.Url, null, null, null, "Posts", - medium.type == "photo" ? "Images" : - medium.type == "video" || medium.type == "gif" ? "Videos" : - medium.type == "audio" ? "Audios" : null, - postPreviewIds.Contains(medium.id) ? true : false, false, null); - postCollection.Posts.Add(medium.id, medium.files.preview.url); + medium.Type == "photo" ? "Images" : + medium.Type == "video" || medium.Type == "gif" ? "Videos" : + medium.Type == "audio" ? "Audios" : null, + postPreviewIds.Contains(medium.Id) ? true : false, false, null); + postCollection.Posts.Add(medium.Id, medium.Files.Preview.Url); postCollection.PostMedia.Add(medium); } } } } - else if (medium.canView && medium.files != null && medium.files.drm != null) + else if (medium.CanView && medium.Files != null && medium.Files.Drm != null) { - bool has = paid_post_ids.Any(cus => cus.Equals(medium.id)); - if (!has && medium.files != null && medium.files.drm != null) + bool has = paid_post_ids.Any(cus => cus.Equals(medium.Id)); + if (!has && medium.Files != null && medium.Files.Drm != null) { - if (!postCollection.Posts.ContainsKey(medium.id)) + if (!postCollection.Posts.ContainsKey(medium.Id)) { - await dbService.AddMedia(folder, medium.id, post.id, medium.files.drm.manifest.dash, + await dbService.AddMedia(folder, medium.Id, post.Id, medium.Files.Drm.Manifest.Dash, null, null, null, "Posts", - medium.type == "photo" ? "Images" : - medium.type == "video" || medium.type == "gif" ? "Videos" : - medium.type == "audio" ? "Audios" : null, - postPreviewIds.Contains(medium.id) ? true : false, false, null); - postCollection.Posts.Add(medium.id, - $"{medium.files.drm.manifest.dash},{medium.files.drm.signature.dash.CloudFrontPolicy},{medium.files.drm.signature.dash.CloudFrontSignature},{medium.files.drm.signature.dash.CloudFrontKeyPairId},{medium.id},{post.id}"); + medium.Type == "photo" ? "Images" : + medium.Type == "video" || medium.Type == "gif" ? "Videos" : + medium.Type == "audio" ? "Audios" : null, + postPreviewIds.Contains(medium.Id) ? true : false, false, null); + postCollection.Posts.Add(medium.Id, + $"{medium.Files.Drm.Manifest.Dash},{medium.Files.Drm.Signature.Dash.CloudFrontPolicy},{medium.Files.Drm.Signature.Dash.CloudFrontSignature},{medium.Files.Drm.Signature.Dash.CloudFrontKeyPairId},{medium.Id},{post.Id}"); postCollection.PostMedia.Add(medium); } } @@ -1020,21 +1026,23 @@ public class APIService(IAuthService authService, IConfigService configService, try { - SinglePost singlePost = new(); + PostEntities.SinglePost singlePost = new(); SinglePostCollection singlePostCollection = new(); Dictionary getParams = new() { { "skip_users", "all" } }; string? body = await BuildHeaderAndExecuteRequests(getParams, endpoint, new HttpClient()); - singlePost = JsonConvert.DeserializeObject(body, m_JsonSerializerSettings); + PostDtos.SinglePostDto? singlePostDto = + JsonConvert.DeserializeObject(body, m_JsonSerializerSettings); + singlePost = PostMapper.FromDto(singlePostDto); - if (singlePost != null) + if (singlePostDto != null) { List postPreviewIds = new(); - if (singlePost.preview != null && singlePost.preview.Count > 0) + if (singlePost.Preview != null && singlePost.Preview.Count > 0) { - for (int i = 0; i < singlePost.preview.Count; i++) + for (int i = 0; i < singlePost.Preview.Count; i++) { - if (singlePost.preview[i] is long previewId) + if (singlePost.Preview[i] is long previewId) { if (!postPreviewIds.Contains(previewId)) { @@ -1044,71 +1052,71 @@ public class APIService(IAuthService authService, IConfigService configService, } } - await dbService.AddPost(folder, singlePost.id, singlePost.text != null ? singlePost.text : string.Empty, - singlePost.price != null ? singlePost.price : "0", - singlePost.price != null && singlePost.isOpened ? true : false, singlePost.isArchived, - singlePost.postedAt); + await dbService.AddPost(folder, singlePost.Id, singlePost.Text != null ? singlePost.Text : string.Empty, + singlePost.Price != null ? singlePost.Price : "0", + singlePost.Price != null && singlePost.IsOpened ? true : false, singlePost.IsArchived, + singlePost.PostedAt); singlePostCollection.SinglePostObjects.Add(singlePost); - if (singlePost.media != null && singlePost.media.Count > 0) + if (singlePost.Media != null && singlePost.Media.Count > 0) { - foreach (SinglePost.Medium medium in singlePost.media) + foreach (PostEntities.Medium medium in singlePost.Media) { - if (medium.type == "photo" && !configService.CurrentConfig.DownloadImages) + if (medium.Type == "photo" && !configService.CurrentConfig.DownloadImages) { continue; } - if (medium.type == "video" && !configService.CurrentConfig.DownloadVideos) + if (medium.Type == "video" && !configService.CurrentConfig.DownloadVideos) { continue; } - if (medium.type == "gif" && !configService.CurrentConfig.DownloadVideos) + if (medium.Type == "gif" && !configService.CurrentConfig.DownloadVideos) { continue; } - if (medium.type == "audio" && !configService.CurrentConfig.DownloadAudios) + if (medium.Type == "audio" && !configService.CurrentConfig.DownloadAudios) { continue; } - if (medium.canView && medium.files?.drm == null) + if (medium.CanView && medium.Files?.Drm == null) { switch (configService.CurrentConfig.DownloadVideoResolution) { case VideoResolution.source: - if (medium.files!.full != null && !string.IsNullOrEmpty(medium.files!.full.url)) + if (medium.Files!.Full != null && !string.IsNullOrEmpty(medium.Files!.Full.Url)) { - if (!singlePostCollection.SinglePosts.ContainsKey(medium.id)) + if (!singlePostCollection.SinglePosts.ContainsKey(medium.Id)) { - await dbService.AddMedia(folder, medium.id, singlePost.id, - medium.files!.full.url, null, null, null, "Posts", - medium.type == "photo" ? "Images" : - medium.type == "video" || medium.type == "gif" ? "Videos" : - medium.type == "audio" ? "Audios" : null, - postPreviewIds.Contains(medium.id) ? true : false, false, null); - singlePostCollection.SinglePosts.Add(medium.id, medium.files!.full.url); + await dbService.AddMedia(folder, medium.Id, singlePost.Id, + medium.Files!.Full.Url, null, null, null, "Posts", + medium.Type == "photo" ? "Images" : + medium.Type == "video" || medium.Type == "gif" ? "Videos" : + medium.Type == "audio" ? "Audios" : null, + postPreviewIds.Contains(medium.Id) ? true : false, false, null); + singlePostCollection.SinglePosts.Add(medium.Id, medium.Files!.Full.Url); singlePostCollection.SinglePostMedia.Add(medium); } } break; case VideoResolution._240: - if (medium.videoSources != null) + if (medium.VideoSources != null) { - if (!string.IsNullOrEmpty(medium.videoSources._240)) + if (!string.IsNullOrEmpty(medium.VideoSources._240)) { - if (!singlePostCollection.SinglePosts.ContainsKey(medium.id)) + if (!singlePostCollection.SinglePosts.ContainsKey(medium.Id)) { - await dbService.AddMedia(folder, medium.id, singlePost.id, - medium.videoSources._240, null, null, null, "Posts", - medium.type == "photo" ? "Images" : - medium.type == "video" || medium.type == "gif" ? "Videos" : - medium.type == "audio" ? "Audios" : null, - postPreviewIds.Contains(medium.id) ? true : false, false, null); - singlePostCollection.SinglePosts.Add(medium.id, - medium.videoSources._240); + await dbService.AddMedia(folder, medium.Id, singlePost.Id, + medium.VideoSources._240, null, null, null, "Posts", + medium.Type == "photo" ? "Images" : + medium.Type == "video" || medium.Type == "gif" ? "Videos" : + medium.Type == "audio" ? "Audios" : null, + postPreviewIds.Contains(medium.Id) ? true : false, false, null); + singlePostCollection.SinglePosts.Add(medium.Id, + medium.VideoSources._240); singlePostCollection.SinglePostMedia.Add(medium); } } @@ -1116,20 +1124,20 @@ public class APIService(IAuthService authService, IConfigService configService, break; case VideoResolution._720: - if (medium.videoSources != null) + if (medium.VideoSources != null) { - if (!string.IsNullOrEmpty(medium.videoSources._720)) + if (!string.IsNullOrEmpty(medium.VideoSources._720)) { - if (!singlePostCollection.SinglePosts.ContainsKey(medium.id)) + if (!singlePostCollection.SinglePosts.ContainsKey(medium.Id)) { - await dbService.AddMedia(folder, medium.id, singlePost.id, - medium.videoSources._720, null, null, null, "Posts", - medium.type == "photo" ? "Images" : - medium.type == "video" || medium.type == "gif" ? "Videos" : - medium.type == "audio" ? "Audios" : null, - postPreviewIds.Contains(medium.id) ? true : false, false, null); - singlePostCollection.SinglePosts.Add(medium.id, - medium.videoSources._720); + await dbService.AddMedia(folder, medium.Id, singlePost.Id, + medium.VideoSources._720, null, null, null, "Posts", + medium.Type == "photo" ? "Images" : + medium.Type == "video" || medium.Type == "gif" ? "Videos" : + medium.Type == "audio" ? "Audios" : null, + postPreviewIds.Contains(medium.Id) ? true : false, false, null); + singlePostCollection.SinglePosts.Add(medium.Id, + medium.VideoSources._720); singlePostCollection.SinglePostMedia.Add(medium); } } @@ -1138,35 +1146,35 @@ public class APIService(IAuthService authService, IConfigService configService, break; } } - else if (medium.canView && medium.files != null && medium.files.drm != null) + else if (medium.CanView && medium.Files != null && medium.Files.Drm != null) { - if (medium.files != null && medium.files.drm != null) + if (medium.Files != null && medium.Files.Drm != null) { - if (!singlePostCollection.SinglePosts.ContainsKey(medium.id)) + if (!singlePostCollection.SinglePosts.ContainsKey(medium.Id)) { - await dbService.AddMedia(folder, medium.id, singlePost.id, - medium.files.drm.manifest.dash, null, null, null, "Posts", - medium.type == "photo" ? "Images" : - medium.type == "video" || medium.type == "gif" ? "Videos" : - medium.type == "audio" ? "Audios" : null, - postPreviewIds.Contains(medium.id) ? true : false, false, null); - singlePostCollection.SinglePosts.Add(medium.id, - $"{medium.files.drm.manifest.dash},{medium.files.drm.signature.dash.CloudFrontPolicy},{medium.files.drm.signature.dash.CloudFrontSignature},{medium.files.drm.signature.dash.CloudFrontKeyPairId},{medium.id},{singlePost.id}"); + await dbService.AddMedia(folder, medium.Id, singlePost.Id, + medium.Files.Drm.Manifest.Dash, null, null, null, "Posts", + medium.Type == "photo" ? "Images" : + medium.Type == "video" || medium.Type == "gif" ? "Videos" : + medium.Type == "audio" ? "Audios" : null, + postPreviewIds.Contains(medium.Id) ? true : false, false, null); + singlePostCollection.SinglePosts.Add(medium.Id, + $"{medium.Files.Drm.Manifest.Dash},{medium.Files.Drm.Signature.Dash.CloudFrontPolicy},{medium.Files.Drm.Signature.Dash.CloudFrontSignature},{medium.Files.Drm.Signature.Dash.CloudFrontKeyPairId},{medium.Id},{singlePost.Id}"); singlePostCollection.SinglePostMedia.Add(medium); } } } - else if (medium.files.preview != null && medium.files!.full == null) + else if (medium.Files.Preview != null && medium.Files!.Full == null) { - if (!singlePostCollection.SinglePosts.ContainsKey(medium.id)) + if (!singlePostCollection.SinglePosts.ContainsKey(medium.Id)) { - await dbService.AddMedia(folder, medium.id, singlePost.id, medium.files.preview.url, + await dbService.AddMedia(folder, medium.Id, singlePost.Id, medium.Files.Preview.Url, null, null, null, "Posts", - medium.type == "photo" ? "Images" : - medium.type == "video" || medium.type == "gif" ? "Videos" : - medium.type == "audio" ? "Audios" : null, - postPreviewIds.Contains(medium.id) ? true : false, false, null); - singlePostCollection.SinglePosts.Add(medium.id, medium.files.preview.url); + medium.Type == "photo" ? "Images" : + medium.Type == "video" || medium.Type == "gif" ? "Videos" : + medium.Type == "audio" ? "Audios" : null, + postPreviewIds.Contains(medium.Id) ? true : false, false, null); + singlePostCollection.SinglePosts.Add(medium.Id, medium.Files.Preview.Url); singlePostCollection.SinglePostMedia.Add(medium); } } diff --git a/OF DL/Services/DownloadService.cs b/OF DL/Services/DownloadService.cs index 577b4c2..b138344 100644 --- a/OF DL/Services/DownloadService.cs +++ b/OF DL/Services/DownloadService.cs @@ -4,16 +4,16 @@ using System.Xml.Linq; using FFmpeg.NET; using FFmpeg.NET.Events; using OF_DL.Models; -using OF_DL.Models.Post; using OF_DL.Models.Purchased; using OF_DL.Models.Streams; using OF_DL.Enumerations; -using OF_DL.Models.Entities.Common; using ArchivedEntities = OF_DL.Models.Entities.Archived; +using CommonEntities = OF_DL.Models.Entities.Common; +using MessageEntities = OF_DL.Models.Entities.Messages; +using PostEntities = OF_DL.Models.Entities.Posts; using OF_DL.Utils; using Serilog; using Serilog.Events; -using MessageEntities = OF_DL.Models.Entities.Messages; namespace OF_DL.Services; @@ -962,14 +962,15 @@ public class DownloadService( #region normal posts public async Task DownloadPostMedia(string url, string folder, long media_id, string api_type, - IProgressReporter progressReporter, string? filenameFormat, Post.List? postInfo, Post.Medium? postMedia, - Post.Author? author, Dictionary users) + IProgressReporter progressReporter, string? filenameFormat, PostEntities.ListItem? postInfo, + PostEntities.Medium? postMedia, + CommonEntities.Author? author, Dictionary users) { string path; - if (configService.CurrentConfig.FolderPerPost && postInfo != null && postInfo?.id is not null && - postInfo?.postedAt is not null) + if (configService.CurrentConfig.FolderPerPost && postInfo != null && postInfo?.Id is not null && + postInfo?.PostedAt is not null) { - path = $"/Posts/Free/{postInfo.id} {postInfo.postedAt:yyyy-MM-dd HH-mm-ss}"; + path = $"/Posts/Free/{postInfo.Id} {postInfo.PostedAt:yyyy-MM-dd HH-mm-ss}"; } else { @@ -986,14 +987,15 @@ public class DownloadService( } public async Task DownloadPostMedia(string url, string folder, long media_id, string api_type, - IProgressReporter progressReporter, string? filenameFormat, SinglePost? postInfo, SinglePost.Medium? postMedia, - SinglePost.Author? author, Dictionary users) + IProgressReporter progressReporter, string? filenameFormat, PostEntities.SinglePost? postInfo, + PostEntities.Medium? postMedia, + CommonEntities.Author? author, Dictionary users) { string path; - if (configService.CurrentConfig.FolderPerPost && postInfo != null && postInfo?.id is not null && - postInfo?.postedAt is not null) + if (configService.CurrentConfig.FolderPerPost && postInfo != null && postInfo?.Id is not null && + postInfo?.PostedAt is not null) { - path = $"/Posts/Free/{postInfo.id} {postInfo.postedAt:yyyy-MM-dd HH-mm-ss}"; + path = $"/Posts/Free/{postInfo.Id} {postInfo.PostedAt:yyyy-MM-dd HH-mm-ss}"; } else { @@ -1036,7 +1038,7 @@ public class DownloadService( public async Task DownloadMessageMedia(string url, string folder, long media_id, string api_type, IProgressReporter progressReporter, string? filenameFormat, MessageEntities.ListItem? messageInfo, - MessageEntities.Medium? messageMedia, FromUser? fromUser, Dictionary users) + MessageEntities.Medium? messageMedia, CommonEntities.FromUser? fromUser, Dictionary users) { string path; if (configService.CurrentConfig.FolderPerMessage && messageInfo != null && messageInfo?.Id is not null && @@ -1059,7 +1061,7 @@ public class DownloadService( public async Task DownloadMessagePreviewMedia(string url, string folder, long media_id, string api_type, IProgressReporter progressReporter, string? filenameFormat, MessageEntities.SingleMessage? messageInfo, - MessageEntities.Medium? messageMedia, FromUser? fromUser, Dictionary users) + MessageEntities.Medium? messageMedia, CommonEntities.FromUser? fromUser, Dictionary users) { string path; if (configService.CurrentConfig.FolderPerMessage && messageInfo != null && messageInfo?.Id is not null && @@ -1083,7 +1085,7 @@ public class DownloadService( public async Task DownloadArchivedMedia(string url, string folder, long media_id, string api_type, IProgressReporter progressReporter, string? filenameFormat, ArchivedEntities.ListItem? messageInfo, - ArchivedEntities.Medium? messageMedia, Author? author, + ArchivedEntities.Medium? messageMedia, CommonEntities.Author? author, Dictionary users) { string path = "/Archived/Posts/Free"; @@ -1132,7 +1134,7 @@ public class DownloadService( public async Task DownloadSinglePurchasedMedia(string url, string folder, long media_id, string api_type, IProgressReporter progressReporter, string? filenameFormat, MessageEntities.SingleMessage? messageInfo, - MessageEntities.Medium? messageMedia, FromUser? fromUser, Dictionary users) + MessageEntities.Medium? messageMedia, CommonEntities.FromUser? fromUser, Dictionary users) { string path; if (configService.CurrentConfig.FolderPerPaidMessage && messageInfo != null && messageInfo?.Id is not null && @@ -1191,7 +1193,7 @@ public class DownloadService( public async Task DownloadMessageDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, IProgressReporter progressReporter, string? filenameFormat, MessageEntities.ListItem? messageInfo, - MessageEntities.Medium? messageMedia, FromUser? fromUser, Dictionary users) + MessageEntities.Medium? messageMedia, CommonEntities.FromUser? fromUser, Dictionary users) { try { @@ -1320,7 +1322,7 @@ public class DownloadService( public async Task DownloadSingleMessagePreviewDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, IProgressReporter progressReporter, string? filenameFormat, MessageEntities.SingleMessage? messageInfo, - MessageEntities.Medium? messageMedia, FromUser? fromUser, Dictionary users) + MessageEntities.Medium? messageMedia, CommonEntities.FromUser? fromUser, Dictionary users) { try { @@ -1579,7 +1581,7 @@ public class DownloadService( public async Task DownloadSinglePurchasedMessageDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, IProgressReporter progressReporter, string? filenameFormat, MessageEntities.SingleMessage? messageInfo, - MessageEntities.Medium? messageMedia, FromUser? fromUser, Dictionary users) + MessageEntities.Medium? messageMedia, CommonEntities.FromUser? fromUser, Dictionary users) { try { @@ -1707,8 +1709,9 @@ public class DownloadService( public async Task DownloadPostDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, - IProgressReporter progressReporter, string? filenameFormat, Post.List? postInfo, Post.Medium? postMedia, - Post.Author? author, Dictionary users) + IProgressReporter progressReporter, string? filenameFormat, PostEntities.ListItem? postInfo, + PostEntities.Medium? postMedia, + CommonEntities.Author? author, Dictionary users) { try { @@ -1716,10 +1719,10 @@ public class DownloadService( string path; Uri uri = new(url); string filename = Path.GetFileName(uri.LocalPath).Split(".")[0]; - if (configService.CurrentConfig.FolderPerPost && postInfo != null && postInfo?.id is not null && - postInfo?.postedAt is not null) + if (configService.CurrentConfig.FolderPerPost && postInfo != null && postInfo?.Id is not null && + postInfo?.PostedAt is not null) { - path = $"/Posts/Free/{postInfo.id} {postInfo.postedAt:yyyy-MM-dd HH-mm-ss}/Videos"; + path = $"/Posts/Free/{postInfo.Id} {postInfo.PostedAt:yyyy-MM-dd HH-mm-ss}/Videos"; } else { @@ -1835,8 +1838,9 @@ public class DownloadService( public async Task DownloadPostDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, - IProgressReporter progressReporter, string filenameFormat, SinglePost postInfo, SinglePost.Medium postMedia, - SinglePost.Author author, Dictionary users) + IProgressReporter progressReporter, string filenameFormat, PostEntities.SinglePost postInfo, + PostEntities.Medium postMedia, + CommonEntities.Author author, Dictionary users) { try { @@ -1844,10 +1848,10 @@ public class DownloadService( string path; Uri uri = new(url); string filename = Path.GetFileName(uri.LocalPath).Split(".")[0]; - if (configService.CurrentConfig.FolderPerPost && postInfo != null && postInfo?.id is not null && - postInfo?.postedAt is not null) + if (configService.CurrentConfig.FolderPerPost && postInfo != null && postInfo?.Id is not null && + postInfo?.PostedAt is not null) { - path = $"/Posts/Free/{postInfo.id} {postInfo.postedAt:yyyy-MM-dd HH-mm-ss}/Videos"; + path = $"/Posts/Free/{postInfo.Id} {postInfo.PostedAt:yyyy-MM-dd HH-mm-ss}/Videos"; } else { @@ -2224,7 +2228,7 @@ public class DownloadService( string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, IProgressReporter progressReporter, string? filenameFormat, ArchivedEntities.ListItem? postInfo, ArchivedEntities.Medium? postMedia, - Author? author, Dictionary users) + CommonEntities.Author? author, Dictionary users) { try { @@ -2896,7 +2900,8 @@ public class DownloadService( // Add these methods to DownloadService.cs before the #endregion line public async Task DownloadFreePosts(string username, long userId, string path, - Dictionary users, bool clientIdBlobMissing, bool devicePrivateKeyMissing, PostCollection posts, + Dictionary users, bool clientIdBlobMissing, bool devicePrivateKeyMissing, + PostEntities.PostCollection posts, IProgressReporter progressReporter) { Log.Debug($"Calling DownloadFreePosts - {username}"); @@ -2940,13 +2945,14 @@ public class DownloadService( $"https://onlyfans.com/api2/v2/users/media/{parsed[4]}/drm/post/{parsed[5]}?type=widevine", pssh); - Post.Medium mediaInfo = posts.PostMedia.FirstOrDefault(m => m.id == postKVP.Key); - Post.List postInfo = posts.PostObjects.FirstOrDefault(p => p?.media?.Contains(mediaInfo) == true); + PostEntities.Medium mediaInfo = posts.PostMedia.FirstOrDefault(m => m.Id == postKVP.Key); + PostEntities.ListItem postInfo = + posts.PostObjects.FirstOrDefault(p => p?.Media?.Contains(mediaInfo) == true); isNew = await DownloadPostDRMVideo(parsed[1], parsed[2], parsed[3], parsed[0], decryptionKey, path, lastModified, postKVP.Key, "Posts", progressReporter, configService.CurrentConfig.GetCreatorFileNameFormatConfig(username).PostFileNameFormat ?? - string.Empty, postInfo, mediaInfo, postInfo?.author, users); + string.Empty, postInfo, mediaInfo, postInfo?.Author, users); } else { @@ -2955,11 +2961,12 @@ public class DownloadService( } else { - Post.Medium? mediaInfo = posts.PostMedia.FirstOrDefault(m => m?.id == postKVP.Key); - Post.List? postInfo = posts.PostObjects.FirstOrDefault(p => p?.media?.Contains(mediaInfo) == true); + PostEntities.Medium? mediaInfo = posts.PostMedia.FirstOrDefault(m => m?.Id == postKVP.Key); + PostEntities.ListItem? postInfo = + posts.PostObjects.FirstOrDefault(p => p?.Media?.Contains(mediaInfo) == true); isNew = await DownloadPostMedia(postKVP.Value, path, postKVP.Key, "Posts", progressReporter, configService.CurrentConfig.GetCreatorFileNameFormatConfig(username).PostFileNameFormat ?? - string.Empty, postInfo, mediaInfo, postInfo?.author, users); + string.Empty, postInfo, mediaInfo, postInfo?.Author, users); } if (isNew) diff --git a/OF DL/Services/IAPIService.cs b/OF DL/Services/IAPIService.cs index d8e7e52..1c77129 100644 --- a/OF DL/Services/IAPIService.cs +++ b/OF DL/Services/IAPIService.cs @@ -1,11 +1,11 @@ using Newtonsoft.Json.Linq; using OF_DL.Models; -using OF_DL.Models.Post; using OF_DL.Models.Purchased; using OF_DL.Models.Streams; using OF_DL.Enumerations; using ArchivedEntities = OF_DL.Models.Entities.Archived; using MessageEntities = OF_DL.Models.Entities.Messages; +using PostEntities = OF_DL.Models.Entities.Posts; using Spectre.Console; namespace OF_DL.Services; @@ -25,8 +25,10 @@ public interface IAPIService Task GetPaidPosts(string endpoint, string folder, string username, List paid_post_ids, StatusContext ctx); - Task GetPosts(string endpoint, string folder, List paid_post_ids, StatusContext ctx); - Task GetPost(string endpoint, string folder); + Task GetPosts(string endpoint, string folder, List paid_post_ids, + StatusContext ctx); + + Task GetPost(string endpoint, string folder); Task GetStreams(string endpoint, string folder, List paid_post_ids, StatusContext ctx); Task GetArchived(string endpoint, string folder, StatusContext ctx); Task GetMessages(string endpoint, string folder, StatusContext ctx); diff --git a/OF DL/Services/IDownloadService.cs b/OF DL/Services/IDownloadService.cs index 1f90736..b1ff68e 100644 --- a/OF DL/Services/IDownloadService.cs +++ b/OF DL/Services/IDownloadService.cs @@ -1,10 +1,10 @@ using OF_DL.Models; -using OF_DL.Models.Entities.Common; -using ArchivedEntities = OF_DL.Models.Entities.Archived; -using OF_DL.Models.Post; using OF_DL.Models.Purchased; using OF_DL.Models.Streams; +using ArchivedEntities = OF_DL.Models.Entities.Archived; +using CommonEntities = OF_DL.Models.Entities.Common; using MessageEntities = OF_DL.Models.Entities.Messages; +using PostEntities = OF_DL.Models.Entities.Posts; namespace OF_DL.Services; @@ -17,23 +17,25 @@ public interface IDownloadService Task DownloadArchivedMedia(string url, string folder, long media_id, string api_type, IProgressReporter progressReporter, string? filenameFormat, ArchivedEntities.ListItem? messageInfo, - ArchivedEntities.Medium? messageMedia, Author? author, + ArchivedEntities.Medium? messageMedia, CommonEntities.Author? author, Dictionary users); Task DownloadArchivedPostDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, IProgressReporter progressReporter, string? filenameFormat, ArchivedEntities.ListItem? postInfo, ArchivedEntities.Medium? postMedia, - Author? author, Dictionary users); + CommonEntities.Author? author, Dictionary users); Task DownloadPostDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, IProgressReporter progressReporter, - string filenameFormat, SinglePost postInfo, SinglePost.Medium postMedia, SinglePost.Author author, + string filenameFormat, PostEntities.SinglePost postInfo, PostEntities.Medium postMedia, + CommonEntities.Author author, Dictionary users); Task DownloadPostDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, IProgressReporter progressReporter, - string? filenameFormat, Post.List? postInfo, Post.Medium? postMedia, Post.Author? author, + string? filenameFormat, PostEntities.ListItem? postInfo, PostEntities.Medium? postMedia, + CommonEntities.Author? author, Dictionary users); Task DownloadAvatarHeader(string? avatarUrl, string? headerUrl, string folder, string username); @@ -41,20 +43,22 @@ public interface IDownloadService Task DownloadMessageDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, IProgressReporter progressReporter, string? filenameFormat, MessageEntities.ListItem? messageInfo, MessageEntities.Medium? messageMedia, - FromUser? fromUser, + CommonEntities.FromUser? fromUser, Dictionary users); Task DownloadMessageMedia(string url, string folder, long media_id, string api_type, IProgressReporter progressReporter, string? filenameFormat, MessageEntities.ListItem? messageInfo, - MessageEntities.Medium? messageMedia, FromUser? fromUser, Dictionary users); + MessageEntities.Medium? messageMedia, CommonEntities.FromUser? fromUser, Dictionary users); Task DownloadPostMedia(string url, string folder, long media_id, string api_type, - IProgressReporter progressReporter, string? filenameFormat, Post.List? postInfo, Post.Medium? postMedia, - Post.Author? author, Dictionary users); + IProgressReporter progressReporter, string? filenameFormat, PostEntities.ListItem? postInfo, + PostEntities.Medium? postMedia, + CommonEntities.Author? author, Dictionary users); Task DownloadPostMedia(string url, string folder, long media_id, string api_type, - IProgressReporter progressReporter, string? filenameFormat, SinglePost? postInfo, SinglePost.Medium? postMedia, - SinglePost.Author? author, Dictionary users); + IProgressReporter progressReporter, string? filenameFormat, PostEntities.SinglePost? postInfo, + PostEntities.Medium? postMedia, + CommonEntities.Author? author, Dictionary users); Task DownloadPurchasedMedia(string url, string folder, long media_id, string api_type, IProgressReporter progressReporter, string? filenameFormat, Purchased.List? messageInfo, @@ -63,7 +67,7 @@ public interface IDownloadService Task DownloadSinglePurchasedMedia(string url, string folder, long media_id, string api_type, IProgressReporter progressReporter, string? filenameFormat, MessageEntities.SingleMessage? messageInfo, - MessageEntities.Medium? messageMedia, FromUser? fromUser, Dictionary users); + MessageEntities.Medium? messageMedia, CommonEntities.FromUser? fromUser, Dictionary users); Task DownloadPurchasedMessageDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, @@ -74,7 +78,7 @@ public interface IDownloadService Task DownloadSinglePurchasedMessageDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, IProgressReporter progressReporter, string? filenameFormat, MessageEntities.SingleMessage? messageInfo, - MessageEntities.Medium? messageMedia, FromUser? fromUser, Dictionary users); + MessageEntities.Medium? messageMedia, CommonEntities.FromUser? fromUser, Dictionary users); Task DownloadPurchasedPostDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, @@ -102,11 +106,11 @@ public interface IDownloadService Task DownloadSingleMessagePreviewDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, IProgressReporter progressReporter, string? filenameFormat, MessageEntities.SingleMessage? messageInfo, - MessageEntities.Medium? messageMedia, FromUser? fromUser, Dictionary users); + MessageEntities.Medium? messageMedia, CommonEntities.FromUser? fromUser, Dictionary users); Task DownloadMessagePreviewMedia(string url, string folder, long media_id, string api_type, IProgressReporter progressReporter, string? filenameFormat, MessageEntities.SingleMessage? messageInfo, - MessageEntities.Medium? messageMedia, FromUser? fromUser, Dictionary users); + MessageEntities.Medium? messageMedia, CommonEntities.FromUser? fromUser, Dictionary users); Task DownloadHighlights(string username, long userId, string path, HashSet paidPostIds, IProgressReporter progressReporter); @@ -131,7 +135,7 @@ public interface IDownloadService IProgressReporter progressReporter); Task DownloadFreePosts(string username, long userId, string path, Dictionary users, - bool clientIdBlobMissing, bool devicePrivateKeyMissing, PostCollection posts, + bool clientIdBlobMissing, bool devicePrivateKeyMissing, PostEntities.PostCollection posts, IProgressReporter progressReporter); Task DownloadPaidPosts(string username, long userId, string path, Dictionary users,