Major refactor #141

Merged
sim0n00ps merged 55 commits from whimsical-c4lic0/OF-DL:refactor-architecture into master 2026-02-13 00:21:58 +00:00
26 changed files with 821 additions and 648 deletions
Showing only changes of commit 3c307bf7de - Show all commits

View File

@ -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();
}

View File

@ -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<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

@ -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();
}

View File

@ -0,0 +1,14 @@
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

@ -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<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

@ -4,5 +4,7 @@ public class Files
{
public Full? Full { get; set; }
public Preview? Preview { get; set; }
public Drm? Drm { get; set; }
}

View File

@ -0,0 +1,6 @@
namespace OF_DL.Models.Entities.Common;
public class Preview
{
public string? Url { get; set; }
}

View File

@ -0,0 +1,8 @@
namespace OF_DL.Models.Entities.Common;
public class VideoSources
{
public string? _720 { get; set; }
public string? _240 { get; set; }
}

View File

@ -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<Medium>? Media { get; set; }
public List<object>? Preview { get; set; }
}

View File

@ -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; }
}

View File

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

View File

@ -0,0 +1,10 @@
namespace OF_DL.Models.Entities.Posts;
public class PostCollection
{
public List<Medium> PostMedia { get; set; } = [];
public List<ListItem> PostObjects { get; set; } = [];
public Dictionary<long, string> Posts { get; set; } = new();
}

View File

@ -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<Medium>? Media { get; set; }
public List<object>? Preview { get; set; }
}

View File

@ -0,0 +1,10 @@
namespace OF_DL.Models.Entities.Posts;
public class SinglePostCollection
{
public List<Medium> SinglePostMedia { get; set; } = [];
public List<SinglePost> SinglePostObjects { get; set; } = [];
public Dictionary<long, string> SinglePosts { get; set; } = new();
}

View File

@ -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)
{

View File

@ -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 };

View File

@ -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<Medium>? MapMedia(List<MediumDto>? 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<Medium>? MapSingleMedia(List<MediumDto>? 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 };
}

View File

@ -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> 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<object> 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<object> mentionedUsers { get; set; }
public List<object> linkedUsers { get; set; }
public bool? canVote { get; set; }
public List<Medium> media { get; set; }
public bool? canViewMedia { get; set; }
public List<object> 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
}

View File

@ -1,8 +0,0 @@
namespace OF_DL.Models.Post;
public class PostCollection
{
public List<Post.Medium> PostMedia = new();
public List<Post.List> PostObjects = new();
public Dictionary<long, string> Posts = new();
}

View File

@ -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<object> mentionedUsers { get; set; }
public List<object> linkedUsers { get; set; }
public string tipsAmount { get; set; }
public string tipsAmountRaw { get; set; }
public List<Medium> media { get; set; }
public bool canViewMedia { get; set; }
public List<object> 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<object> 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; }
}
}

View File

@ -1,8 +0,0 @@
namespace OF_DL.Models.Post;
public class SinglePostCollection
{
public List<SinglePost.Medium> SinglePostMedia = new();
public List<SinglePost> SinglePostObjects = new();
public Dictionary<long, string> SinglePosts = new();
}

View File

@ -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<IAuthService>();
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

View File

@ -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<PostCollection> GetPosts(string endpoint, string folder, List<long> paid_post_ids,
public async Task<PostEntities.PostCollection> GetPosts(string endpoint, string folder, List<long> 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<string, string> 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<Post>(body, m_JsonSerializerSettings);
PostDtos.PostDto? postsDto =
JsonConvert.DeserializeObject<PostDtos.PostDto>(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<Post>(loopbody, m_JsonSerializerSettings);
PostDtos.PostDto? newPostsDto =
JsonConvert.DeserializeObject<PostDtos.PostDto>(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<long> 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<string, string> getParams = new() { { "skip_users", "all" } };
string? body = await BuildHeaderAndExecuteRequests(getParams, endpoint, new HttpClient());
singlePost = JsonConvert.DeserializeObject<SinglePost>(body, m_JsonSerializerSettings);
PostDtos.SinglePostDto? singlePostDto =
JsonConvert.DeserializeObject<PostDtos.SinglePostDto>(body, m_JsonSerializerSettings);
singlePost = PostMapper.FromDto(singlePostDto);
if (singlePost != null)
if (singlePostDto != null)
{
List<long> 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);
}
}

View File

@ -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<bool> 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<string, long> users)
IProgressReporter progressReporter, string? filenameFormat, PostEntities.ListItem? postInfo,
PostEntities.Medium? postMedia,
CommonEntities.Author? author, Dictionary<string, long> 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<bool> DownloadPostMedia(string url, string folder, long media_id, string api_type,
IProgressReporter progressReporter, string? filenameFormat, SinglePost? postInfo, SinglePost.Medium? postMedia,
SinglePost.Author? author, Dictionary<string, long> users)
IProgressReporter progressReporter, string? filenameFormat, PostEntities.SinglePost? postInfo,
PostEntities.Medium? postMedia,
CommonEntities.Author? author, Dictionary<string, long> 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<bool> DownloadMessageMedia(string url, string folder, long media_id, string api_type,
IProgressReporter progressReporter, string? filenameFormat, MessageEntities.ListItem? messageInfo,
MessageEntities.Medium? messageMedia, FromUser? fromUser, Dictionary<string, long> users)
MessageEntities.Medium? messageMedia, CommonEntities.FromUser? fromUser, Dictionary<string, long> users)
{
string path;
if (configService.CurrentConfig.FolderPerMessage && messageInfo != null && messageInfo?.Id is not null &&
@ -1059,7 +1061,7 @@ public class DownloadService(
public async Task<bool> DownloadMessagePreviewMedia(string url, string folder, long media_id, string api_type,
IProgressReporter progressReporter, string? filenameFormat, MessageEntities.SingleMessage? messageInfo,
MessageEntities.Medium? messageMedia, FromUser? fromUser, Dictionary<string, long> users)
MessageEntities.Medium? messageMedia, CommonEntities.FromUser? fromUser, Dictionary<string, long> users)
{
string path;
if (configService.CurrentConfig.FolderPerMessage && messageInfo != null && messageInfo?.Id is not null &&
@ -1083,7 +1085,7 @@ public class DownloadService(
public async Task<bool> 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<string, long> users)
{
string path = "/Archived/Posts/Free";
@ -1132,7 +1134,7 @@ public class DownloadService(
public async Task<bool> DownloadSinglePurchasedMedia(string url, string folder, long media_id, string api_type,
IProgressReporter progressReporter, string? filenameFormat, MessageEntities.SingleMessage? messageInfo,
MessageEntities.Medium? messageMedia, FromUser? fromUser, Dictionary<string, long> users)
MessageEntities.Medium? messageMedia, CommonEntities.FromUser? fromUser, Dictionary<string, long> users)
{
string path;
if (configService.CurrentConfig.FolderPerPaidMessage && messageInfo != null && messageInfo?.Id is not null &&
@ -1191,7 +1193,7 @@ public class DownloadService(
public async Task<bool> 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<string, long> users)
MessageEntities.Medium? messageMedia, CommonEntities.FromUser? fromUser, Dictionary<string, long> users)
{
try
{
@ -1320,7 +1322,7 @@ public class DownloadService(
public async Task<bool> 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<string, long> users)
MessageEntities.Medium? messageMedia, CommonEntities.FromUser? fromUser, Dictionary<string, long> users)
{
try
{
@ -1579,7 +1581,7 @@ public class DownloadService(
public async Task<bool> 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<string, long> users)
MessageEntities.Medium? messageMedia, CommonEntities.FromUser? fromUser, Dictionary<string, long> users)
{
try
{
@ -1707,8 +1709,9 @@ public class DownloadService(
public async Task<bool> 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<string, long> users)
IProgressReporter progressReporter, string? filenameFormat, PostEntities.ListItem? postInfo,
PostEntities.Medium? postMedia,
CommonEntities.Author? author, Dictionary<string, long> 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<bool> 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<string, long> users)
IProgressReporter progressReporter, string filenameFormat, PostEntities.SinglePost postInfo,
PostEntities.Medium postMedia,
CommonEntities.Author author, Dictionary<string, long> 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<string, long> users)
CommonEntities.Author? author, Dictionary<string, long> users)
{
try
{
@ -2896,7 +2900,8 @@ public class DownloadService(
// Add these methods to DownloadService.cs before the #endregion line
public async Task<DownloadResult> DownloadFreePosts(string username, long userId, string path,
Dictionary<string, long> users, bool clientIdBlobMissing, bool devicePrivateKeyMissing, PostCollection posts,
Dictionary<string, long> 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)

View File

@ -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<PaidPostCollection> GetPaidPosts(string endpoint, string folder, string username, List<long> paid_post_ids,
StatusContext ctx);
Task<PostCollection> GetPosts(string endpoint, string folder, List<long> paid_post_ids, StatusContext ctx);
Task<SinglePostCollection> GetPost(string endpoint, string folder);
Task<PostEntities.PostCollection> GetPosts(string endpoint, string folder, List<long> paid_post_ids,
StatusContext ctx);
Task<PostEntities.SinglePostCollection> GetPost(string endpoint, string folder);
Task<StreamsCollection> GetStreams(string endpoint, string folder, List<long> paid_post_ids, StatusContext ctx);
Task<ArchivedEntities.ArchivedCollection> GetArchived(string endpoint, string folder, StatusContext ctx);
Task<MessageEntities.MessageCollection> GetMessages(string endpoint, string folder, StatusContext ctx);

View File

@ -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<bool> 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<string, long> users);
Task<bool> 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<string, long> users);
CommonEntities.Author? author, Dictionary<string, long> users);
Task<bool> 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<string, long> users);
Task<bool> 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<string, long> users);
Task DownloadAvatarHeader(string? avatarUrl, string? headerUrl, string folder, string username);
@ -41,20 +43,22 @@ public interface IDownloadService
Task<bool> 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<string, long> users);
Task<bool> DownloadMessageMedia(string url, string folder, long media_id, string api_type,
IProgressReporter progressReporter, string? filenameFormat, MessageEntities.ListItem? messageInfo,
MessageEntities.Medium? messageMedia, FromUser? fromUser, Dictionary<string, long> users);
MessageEntities.Medium? messageMedia, CommonEntities.FromUser? fromUser, Dictionary<string, long> users);
Task<bool> 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<string, long> users);
IProgressReporter progressReporter, string? filenameFormat, PostEntities.ListItem? postInfo,
PostEntities.Medium? postMedia,
CommonEntities.Author? author, Dictionary<string, long> users);
Task<bool> DownloadPostMedia(string url, string folder, long media_id, string api_type,
IProgressReporter progressReporter, string? filenameFormat, SinglePost? postInfo, SinglePost.Medium? postMedia,
SinglePost.Author? author, Dictionary<string, long> users);
IProgressReporter progressReporter, string? filenameFormat, PostEntities.SinglePost? postInfo,
PostEntities.Medium? postMedia,
CommonEntities.Author? author, Dictionary<string, long> users);
Task<bool> 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<bool> DownloadSinglePurchasedMedia(string url, string folder, long media_id, string api_type,
IProgressReporter progressReporter, string? filenameFormat, MessageEntities.SingleMessage? messageInfo,
MessageEntities.Medium? messageMedia, FromUser? fromUser, Dictionary<string, long> users);
MessageEntities.Medium? messageMedia, CommonEntities.FromUser? fromUser, Dictionary<string, long> users);
Task<bool> 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<bool> 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<string, long> users);
MessageEntities.Medium? messageMedia, CommonEntities.FromUser? fromUser, Dictionary<string, long> users);
Task<bool> 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<bool> 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<string, long> users);
MessageEntities.Medium? messageMedia, CommonEntities.FromUser? fromUser, Dictionary<string, long> users);
Task<bool> DownloadMessagePreviewMedia(string url, string folder, long media_id, string api_type,
IProgressReporter progressReporter, string? filenameFormat, MessageEntities.SingleMessage? messageInfo,
MessageEntities.Medium? messageMedia, FromUser? fromUser, Dictionary<string, long> users);
MessageEntities.Medium? messageMedia, CommonEntities.FromUser? fromUser, Dictionary<string, long> users);
Task<DownloadResult> DownloadHighlights(string username, long userId, string path, HashSet<long> paidPostIds,
IProgressReporter progressReporter);
@ -131,7 +135,7 @@ public interface IDownloadService
IProgressReporter progressReporter);
Task<DownloadResult> DownloadFreePosts(string username, long userId, string path, Dictionary<string, long> users,
bool clientIdBlobMissing, bool devicePrivateKeyMissing, PostCollection posts,
bool clientIdBlobMissing, bool devicePrivateKeyMissing, PostEntities.PostCollection posts,
IProgressReporter progressReporter);
Task<DownloadResult> DownloadPaidPosts(string username, long userId, string path, Dictionary<string, long> users,