merge:upstream

This commit is contained in:
Comfy-Mittens 2026-01-14 01:04:10 +00:00
commit 6c5733d841
No known key found for this signature in database
23 changed files with 231 additions and 188 deletions

View File

@ -17,7 +17,7 @@ namespace OF_DL.Entities.Archived
public Counters counters { get; set; } public Counters counters { get; set; }
public class Author public class Author
{ {
public int id { get; set; } public long id { get; set; }
public string _view { get; set; } public string _view { get; set; }
} }
@ -64,7 +64,7 @@ namespace OF_DL.Entities.Archived
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
public List<object> sources { get; set; } public List<object> sources { get; set; }
} }
@ -73,7 +73,7 @@ namespace OF_DL.Entities.Archived
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
} }
public class Thumb public class Thumb
@ -81,7 +81,7 @@ namespace OF_DL.Entities.Archived
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
} }
public class Hls public class Hls
@ -105,7 +105,7 @@ namespace OF_DL.Entities.Archived
public class LinkedPost public class LinkedPost
{ {
public string responseType { get; set; } public string responseType { get; set; }
public int? id { get; set; } public long? id { get; set; }
public DateTime? postedAt { get; set; } public DateTime? postedAt { get; set; }
public string postedAtPrecise { get; set; } public string postedAtPrecise { get; set; }
public object expiredAt { get; set; } public object expiredAt { get; set; }

View File

@ -9,10 +9,10 @@ namespace OF_DL.Entities.Highlights
{ {
public class HighlightMedia public class HighlightMedia
{ {
public int id { get; set; } public long id { get; set; }
public int userId { get; set; } public long userId { get; set; }
public string title { get; set; } public string title { get; set; }
public int coverStoryId { get; set; } public long coverStoryId { get; set; }
public string cover { get; set; } public string cover { get; set; }
public int storiesCount { get; set; } public int storiesCount { get; set; }
public DateTime? createdAt { get; set; } public DateTime? createdAt { get; set; }
@ -30,7 +30,7 @@ namespace OF_DL.Entities.Highlights
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
public List<object> sources { get; set; } public List<object> sources { get; set; }
} }
@ -50,7 +50,7 @@ namespace OF_DL.Entities.Highlights
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
public Sources sources { get; set; } public Sources sources { get; set; }
} }
@ -60,7 +60,7 @@ namespace OF_DL.Entities.Highlights
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int duration { get; set; } public int duration { get; set; }
public int size { get; set; } public long size { get; set; }
public Sources sources { get; set; } public Sources sources { get; set; }
} }
@ -80,14 +80,14 @@ namespace OF_DL.Entities.Highlights
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
public Sources sources { get; set; } public Sources sources { get; set; }
} }
public class Story public class Story
{ {
public int id { get; set; } public long id { get; set; }
public int userId { get; set; } public long userId { get; set; }
public bool isWatched { get; set; } public bool isWatched { get; set; }
public bool isReady { get; set; } public bool isReady { get; set; }
public List<Medium> media { get; set; } public List<Medium> media { get; set; }
@ -102,7 +102,7 @@ namespace OF_DL.Entities.Highlights
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
} }
} }
} }

View File

@ -12,10 +12,10 @@ namespace OF_DL.Entities.Highlights
public bool hasMore { get; set; } public bool hasMore { get; set; }
public class List public class List
{ {
public int id { get; set; } public long id { get; set; }
public int userId { get; set; } public long userId { get; set; }
public string title { get; set; } public string title { get; set; }
public int coverStoryId { get; set; } public long coverStoryId { get; set; }
public string cover { get; set; } public string cover { get; set; }
public int storiesCount { get; set; } public int storiesCount { get; set; }
public DateTime? createdAt { get; set; } public DateTime? createdAt { get; set; }

View File

@ -34,7 +34,7 @@ namespace OF_DL.Entities.Lists
public class User public class User
{ {
public int? id { get; set; } public long? id { get; set; }
public string _view { get; set; } public string _view { get; set; }
} }
} }

View File

@ -14,7 +14,7 @@ namespace OF_DL.Entities.Lists
public string header { get; set; } public string header { get; set; }
public HeaderSize headerSize { get; set; } public HeaderSize headerSize { get; set; }
public HeaderThumbs headerThumbs { get; set; } public HeaderThumbs headerThumbs { get; set; }
public int? id { get; set; } public long? id { get; set; }
public string name { get; set; } public string name { get; set; }
public string username { get; set; } public string username { get; set; }
public bool? canLookStory { get; set; } public bool? canLookStory { get; set; }
@ -92,7 +92,7 @@ namespace OF_DL.Entities.Lists
public class Subscribe public class Subscribe
{ {
public object id { get; set; } public object id { get; set; }
public int? userId { get; set; } public long? userId { get; set; }
public int? subscriberId { get; set; } public int? subscriberId { get; set; }
public DateTime? date { get; set; } public DateTime? date { get; set; }
public int? duration { get; set; } public int? duration { get; set; }
@ -160,7 +160,7 @@ namespace OF_DL.Entities.Lists
public class SubscriptionBundle public class SubscriptionBundle
{ {
public int? id { get; set; } public long? id { get; set; }
public string? discount { get; set; } public string? discount { get; set; }
public string? duration { get; set; } public string? duration { get; set; }
public string? price { get; set; } public string? price { get; set; }

View File

@ -43,7 +43,7 @@ namespace OF_DL.Entities.Messages
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
public List<object> sources { get; set; } public List<object> sources { get; set; }
} }
@ -52,7 +52,7 @@ namespace OF_DL.Entities.Messages
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
} }
public class Thumb public class Thumb
@ -60,12 +60,12 @@ namespace OF_DL.Entities.Messages
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
} }
public class FromUser public class FromUser
{ {
public int? id { get; set; } public long? id { get; set; }
public string _view { get; set; } public string _view { get; set; }
} }

View File

@ -17,7 +17,7 @@ namespace OF_DL.Entities.Messages
public string header { get; set; } public string header { get; set; }
public HeaderSize headerSize { get; set; } public HeaderSize headerSize { get; set; }
public HeaderThumbs headerThumbs { get; set; } public HeaderThumbs headerThumbs { get; set; }
public int? id { get; set; } public long? id { get; set; }
public string name { get; set; } public string name { get; set; }
public string username { get; set; } public string username { get; set; }
public bool canLookStory { get; set; } public bool canLookStory { get; set; }
@ -81,7 +81,7 @@ namespace OF_DL.Entities.Messages
{ {
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
} }
public class SingleMessage public class SingleMessage

View File

@ -20,7 +20,7 @@ public class Post
public string tailMarker { get; set; } public string tailMarker { get; set; }
public class Author public class Author
{ {
public int id { get; set; } public long id { get; set; }
public string _view { get; set; } public string _view { get; set; }
} }
@ -56,7 +56,7 @@ public class Post
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
public List<object> sources { get; set; } public List<object> sources { get; set; }
} }
@ -65,7 +65,7 @@ public class Post
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
} }
public class Thumb public class Thumb
@ -73,7 +73,7 @@ public class Post
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
} }
public class Hls public class Hls

View File

@ -12,7 +12,7 @@ namespace OF_DL.Entities.Post
public class SinglePost public class SinglePost
{ {
public string responseType { get; set; } public string responseType { get; set; }
public int id { get; set; } public long id { get; set; }
public DateTime postedAt { get; set; } public DateTime postedAt { get; set; }
public string postedAtPrecise { get; set; } public string postedAtPrecise { get; set; }
public object expiredAt { get; set; } public object expiredAt { get; set; }
@ -67,7 +67,7 @@ namespace OF_DL.Entities.Post
public List<object> preview { get; set; } public List<object> preview { get; set; }
public class Author public class Author
{ {
public int id { get; set; } public long id { get; set; }
public string _view { get; set; } public string _view { get; set; }
} }
@ -85,7 +85,7 @@ namespace OF_DL.Entities.Post
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
public List<object> sources { get; set; } public List<object> sources { get; set; }
} }
@ -94,7 +94,7 @@ namespace OF_DL.Entities.Post
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
} }
public class Thumb public class Thumb
@ -102,7 +102,7 @@ namespace OF_DL.Entities.Post
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
} }
public class Info public class Info
@ -134,7 +134,7 @@ namespace OF_DL.Entities.Post
{ {
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
public string url { get; set; } public string url { get; set; }
} }
@ -143,7 +143,7 @@ namespace OF_DL.Entities.Post
public string source { get; set; } public string source { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
public int duration { get; set; } public int duration { get; set; }
} }

View File

@ -13,17 +13,14 @@ namespace OF_DL.Entities.Purchased
public List<List> list { get; set; } public List<List> list { get; set; }
public bool hasMore { get; set; } public bool hasMore { get; set; }
public class FromUser public class FromUser
{ {
public int id { get; set; } public long id { get; set; }
public string _view { get; set; } public string _view { get; set; }
} }
public class Author public class Author
{ {
public int id { get; set; } public long id { get; set; }
public string _view { get; set; } public string _view { get; set; }
} }
@ -81,10 +78,5 @@ namespace OF_DL.Entities.Purchased
public string hls { get; set; } public string hls { get; set; }
public string dash { get; set; } public string dash { get; set; }
} }
} }
} }

View File

@ -9,8 +9,8 @@ namespace OF_DL.Entities.Stories
{ {
public class Stories public class Stories
{ {
public int id { get; set; } public long id { get; set; }
public int userId { get; set; } public long userId { get; set; }
public bool isWatched { get; set; } public bool isWatched { get; set; }
public bool isReady { get; set; } public bool isReady { get; set; }
public List<Medium> media { get; set; } public List<Medium> media { get; set; }
@ -31,7 +31,7 @@ namespace OF_DL.Entities.Stories
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
public List<object> sources { get; set; } public List<object> sources { get; set; }
} }
@ -51,7 +51,7 @@ namespace OF_DL.Entities.Stories
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
public Sources sources { get; set; } public Sources sources { get; set; }
} }
@ -61,7 +61,7 @@ namespace OF_DL.Entities.Stories
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int duration { get; set; } public int duration { get; set; }
public int size { get; set; } public long size { get; set; }
public Sources sources { get; set; } public Sources sources { get; set; }
} }
@ -81,7 +81,7 @@ namespace OF_DL.Entities.Stories
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
public Sources sources { get; set; } public Sources sources { get; set; }
} }
@ -90,7 +90,7 @@ namespace OF_DL.Entities.Stories
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
} }
} }
} }

View File

@ -17,7 +17,7 @@ namespace OF_DL.Entities.Streams
public Counters counters { get; set; } public Counters counters { get; set; }
public class Author public class Author
{ {
public int id { get; set; } public long id { get; set; }
public string _view { get; set; } public string _view { get; set; }
} }
@ -46,7 +46,7 @@ namespace OF_DL.Entities.Streams
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
public List<object> sources { get; set; } public List<object> sources { get; set; }
} }
@ -55,7 +55,7 @@ namespace OF_DL.Entities.Streams
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
} }
public class Thumb public class Thumb
@ -63,7 +63,7 @@ namespace OF_DL.Entities.Streams
public string url { get; set; } public string url { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
} }
public class Info public class Info
@ -154,7 +154,7 @@ namespace OF_DL.Entities.Streams
{ {
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
public string url { get; set; } public string url { get; set; }
} }
@ -163,7 +163,7 @@ namespace OF_DL.Entities.Streams
public string source { get; set; } public string source { get; set; }
public int width { get; set; } public int width { get; set; }
public int height { get; set; } public int height { get; set; }
public int size { get; set; } public long size { get; set; }
public int duration { get; set; } public int duration { get; set; }
} }

View File

@ -36,7 +36,7 @@ namespace OF_DL.Entities
public string header { get; set; } public string header { get; set; }
public HeaderSize headerSize { get; set; } public HeaderSize headerSize { get; set; }
public HeaderThumbs headerThumbs { get; set; } public HeaderThumbs headerThumbs { get; set; }
public int id { get; set; } public long id { get; set; }
public string name { get; set; } public string name { get; set; }
public string username { get; set; } public string username { get; set; }
public bool? canLookStory { get; set; } public bool? canLookStory { get; set; }
@ -96,7 +96,7 @@ namespace OF_DL.Entities
public class Subscribe public class Subscribe
{ {
public object id { get; set; } public object id { get; set; }
public int? userId { get; set; } public long? userId { get; set; }
public int? subscriberId { get; set; } public int? subscriberId { get; set; }
public DateTime? date { get; set; } public DateTime? date { get; set; }
public int? duration { get; set; } public int? duration { get; set; }

View File

@ -14,7 +14,7 @@ namespace OF_DL.Entities
public string? header { get; set; } public string? header { get; set; }
public HeaderSize headerSize { get; set; } public HeaderSize headerSize { get; set; }
public HeaderThumbs headerThumbs { get; set; } public HeaderThumbs headerThumbs { get; set; }
public int? id { get; set; } public long? id { get; set; }
public string name { get; set; } public string name { get; set; }
public string username { get; set; } public string username { get; set; }
public bool? canLookStory { get; set; } public bool? canLookStory { get; set; }
@ -124,7 +124,7 @@ namespace OF_DL.Entities
public class Subscribe public class Subscribe
{ {
public long? id { get; set; } public long? id { get; set; }
public int? userId { get; set; } public long? userId { get; set; }
public int? subscriberId { get; set; } public int? subscriberId { get; set; }
public DateTime? date { get; set; } public DateTime? date { get; set; }
public int? duration { get; set; } public int? duration { get; set; }

View File

@ -295,11 +295,11 @@ public class APIHelper : IAPIHelper
} }
public async Task<Dictionary<string, int>?> GetAllSubscriptions(Dictionary<string, string> getParams, string endpoint, bool includeRestricted, IDownloadConfig config) public async Task<Dictionary<string, long>?> GetAllSubscriptions(Dictionary<string, string> getParams, string endpoint, bool includeRestricted, IDownloadConfig config)
{ {
try try
{ {
Dictionary<string, int> users = new(); Dictionary<string, long> users = new();
Subscriptions subscriptions = new(); Subscriptions subscriptions = new();
Log.Debug("Calling GetAllSubscrptions"); Log.Debug("Calling GetAllSubscrptions");
@ -359,7 +359,7 @@ public class APIHelper : IAPIHelper
return null; return null;
} }
public async Task<Dictionary<string, int>?> GetActiveSubscriptions(string endpoint, bool includeRestricted, IDownloadConfig config) public async Task<Dictionary<string, long>?> GetActiveSubscriptions(string endpoint, bool includeRestricted, IDownloadConfig config)
{ {
Dictionary<string, string> getParams = new() Dictionary<string, string> getParams = new()
{ {
@ -373,7 +373,7 @@ public class APIHelper : IAPIHelper
} }
public async Task<Dictionary<string, int>?> GetExpiredSubscriptions(string endpoint, bool includeRestricted, IDownloadConfig config) public async Task<Dictionary<string, long>?> GetExpiredSubscriptions(string endpoint, bool includeRestricted, IDownloadConfig config)
{ {
Dictionary<string, string> getParams = new() Dictionary<string, string> getParams = new()
@ -390,7 +390,7 @@ public class APIHelper : IAPIHelper
} }
public async Task<Dictionary<string, int>> GetLists(string endpoint, IDownloadConfig config) public async Task<Dictionary<string, long>> GetLists(string endpoint, IDownloadConfig config)
{ {
Log.Debug("Calling GetLists"); Log.Debug("Calling GetLists");
@ -404,7 +404,7 @@ public class APIHelper : IAPIHelper
{ "limit", "50" }, { "limit", "50" },
{ "format", "infinite" } { "format", "infinite" }
}; };
Dictionary<string, int> lists = new(); Dictionary<string, long> lists = new();
while (true) while (true)
{ {
string? body = await BuildHeaderAndExecuteRequests(getParams, endpoint, new HttpClient()); string? body = await BuildHeaderAndExecuteRequests(getParams, endpoint, new HttpClient());
@ -2067,13 +2067,13 @@ public class APIHelper : IAPIHelper
return null; return null;
} }
public async Task<Dictionary<string, int>> GetPurchasedTabUsers(string endpoint, IDownloadConfig config, Dictionary<string, int> users) public async Task<Dictionary<string, long>> GetPurchasedTabUsers(string endpoint, IDownloadConfig config, Dictionary<string, long> users)
{ {
Log.Debug($"Calling GetPurchasedTabUsers - {endpoint}"); Log.Debug($"Calling GetPurchasedTabUsers - {endpoint}");
try try
{ {
Dictionary<string, int> purchasedTabUsers = new(); Dictionary<string, long> purchasedTabUsers = new();
Purchased purchased = new(); Purchased purchased = new();
int post_limit = 50; int post_limit = 50;
Dictionary<string, string> getParams = new() Dictionary<string, string> getParams = new()
@ -2240,7 +2240,7 @@ public class APIHelper : IAPIHelper
return null; return null;
} }
public async Task<List<PurchasedTabCollection>> GetPurchasedTab(string endpoint, string folder, IDownloadConfig config, Dictionary<string, int> users) public async Task<List<PurchasedTabCollection>> GetPurchasedTab(string endpoint, string folder, IDownloadConfig config, Dictionary<string, long> users)
{ {
Log.Debug($"Calling GetPurchasedTab - {endpoint}"); Log.Debug($"Calling GetPurchasedTab - {endpoint}");

View File

@ -135,7 +135,7 @@ namespace OF_DL.Helpers
} }
} }
public async Task CreateUsersDB(Dictionary<string, int> users) public async Task CreateUsersDB(Dictionary<string, long> users)
{ {
try try
{ {
@ -150,7 +150,7 @@ namespace OF_DL.Helpers
} }
Log.Debug("Adding missing creators"); Log.Debug("Adding missing creators");
foreach (KeyValuePair<string, int> user in users) foreach (KeyValuePair<string, long> user in users)
{ {
using (SqliteCommand checkCmd = new($"SELECT user_id, username FROM users WHERE user_id = @userId;", connection)) using (SqliteCommand checkCmd = new($"SELECT user_id, username FROM users WHERE user_id = @userId;", connection))
{ {
@ -190,7 +190,7 @@ namespace OF_DL.Helpers
} }
} }
public async Task CheckUsername(KeyValuePair<string, int> user, string path) public async Task CheckUsername(KeyValuePair<string, long> user, string path)
{ {
try try
{ {
@ -243,7 +243,7 @@ namespace OF_DL.Helpers
} }
} }
public async Task AddMessage(string folder, long post_id, string message_text, string price, bool is_paid, bool is_archived, DateTime created_at, int user_id) public async Task AddMessage(string folder, long post_id, string message_text, string price, bool is_paid, bool is_archived, DateTime created_at, long user_id)
{ {
try try
{ {
@ -495,7 +495,7 @@ namespace OF_DL.Helpers
FROM posts AS P FROM posts AS P
INNER JOIN medias AS m INNER JOIN medias AS m
ON P.post_id = m.post_id ON P.post_id = m.post_id
WHERE m.downloaded = 0 WHERE m.downloaded = 0
)", connection); )", connection);
var scalarValue = await cmd.ExecuteScalarAsync(); var scalarValue = await cmd.ExecuteScalarAsync();
if(scalarValue != null && scalarValue != DBNull.Value) if(scalarValue != null && scalarValue != DBNull.Value)

View File

@ -77,9 +77,9 @@ public class DownloadHelper : IDownloadHelper
try try
{ {
string customFileName = string.Empty; string customFileName = string.Empty;
if (!Directory.Exists(folder + path)) if (!Directory.Exists(folder + path))
{ {
Directory.CreateDirectory(folder + path); Directory.CreateDirectory(folder + path);
} }
string extension = Path.GetExtension(url.Split("?")[0]); string extension = Path.GetExtension(url.Split("?")[0]);
@ -164,7 +164,7 @@ public class DownloadHelper : IDownloadHelper
object? postMedia, object? postMedia,
object? author, object? author,
string username, string username,
Dictionary<string, int> users, Dictionary<string, long> users,
IFileNameHelper fileNameHelper, IFileNameHelper fileNameHelper,
CustomFileNameOption option) CustomFileNameOption option)
{ {
@ -628,9 +628,38 @@ public class DownloadHelper : IDownloadHelper
// default: // default:
// tempFilename = $"{folder}{path}/{filename}_source.mp4"; // tempFilename = $"{folder}{path}/{filename}_source.mp4";
// break; // break;
//} //}
string parameters = $"-cenc_decryption_key {decKey} -headers \"Cookie:CloudFront-Policy={policy}; CloudFront-Signature={signature}; CloudFront-Key-Pair-Id={kvp}; {sess} Origin: https://onlyfans.com Referer: https://onlyfans.com User-Agent: {user_agent}\" -y -i \"{url}\" -map 0:v:{streamIndex} -map 0:a? -codec copy \"{tempFilename}\""; // Configure ffmpeg log level and optional report file location
bool ffmpegDebugLogging = Log.IsEnabled(Serilog.Events.LogEventLevel.Debug);
string logLevelArgs = ffmpegDebugLogging || downloadConfig.LoggingLevel is LoggingLevel.Verbose or LoggingLevel.Debug
? "-loglevel debug -report"
: downloadConfig.LoggingLevel switch
{
LoggingLevel.Information => "-loglevel info",
LoggingLevel.Warning => "-loglevel warning",
LoggingLevel.Error => "-loglevel error",
LoggingLevel.Fatal => "-loglevel fatal",
_ => string.Empty
};
if (logLevelArgs.Contains("-report", StringComparison.OrdinalIgnoreCase))
{
// Direct ffmpeg report files into the same logs directory Serilog uses (relative to current working directory)
string logDir = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, "logs"));
Directory.CreateDirectory(logDir);
string ffReportPath = Path.Combine(logDir, "ffmpeg-%p-%t.log"); // ffmpeg will replace %p/%t
Environment.SetEnvironmentVariable("FFREPORT", $"file={ffReportPath}:level=32");
Log.Debug("FFREPORT enabled at: {FFREPORT} (cwd: {Cwd})", Environment.GetEnvironmentVariable("FFREPORT"), Environment.CurrentDirectory);
}
else
{
Environment.SetEnvironmentVariable("FFREPORT", null);
Log.Debug("FFREPORT disabled (cwd: {Cwd})", Environment.CurrentDirectory);
}
string parameters = $"{logLevelArgs} -cenc_decryption_key {decKey} -headers \"Cookie:CloudFront-Policy={policy}; CloudFront-Signature={signature}; CloudFront-Key-Pair-Id={kvp}; {sess} Origin: https://onlyfans.com Referer: https://onlyfans.com User-Agent: {user_agent}\" -y -i \"{url}\" -map 0:v:{streamIndex} -map 0:a? -codec copy \"{tempFilename}\"".Trim();
Log.Debug($"Calling FFMPEG with Parameters: {parameters}"); Log.Debug($"Calling FFMPEG with Parameters: {parameters}");
@ -661,7 +690,7 @@ public class DownloadHelper : IDownloadHelper
#endregion #endregion
#region normal posts #region normal posts
public async Task<bool> DownloadPostMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, Post.List? postInfo, Post.Medium? postMedia, Post.Author? author, Dictionary<string, int> users) public async Task<bool> DownloadPostMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, Post.List? postInfo, Post.Medium? postMedia, Post.Author? author, Dictionary<string, long> users)
{ {
string path; string path;
if (downloadConfig.FolderPerPost && postInfo != null && postInfo?.id is not null && postInfo?.postedAt is not null) if (downloadConfig.FolderPerPost && postInfo != null && postInfo?.id is not null && postInfo?.postedAt is not null)
@ -679,7 +708,7 @@ public class DownloadHelper : IDownloadHelper
return await CreateDirectoriesAndDownloadMedia(path, url, folder, media_id, api_type, task, filename, resolvedFilename); return await CreateDirectoriesAndDownloadMedia(path, url, folder, media_id, api_type, task, filename, resolvedFilename);
} }
public async Task<bool> DownloadPostMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, SinglePost? postInfo, SinglePost.Medium? postMedia, SinglePost.Author? author, Dictionary<string, int> users) public async Task<bool> DownloadPostMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, SinglePost? postInfo, SinglePost.Medium? postMedia, SinglePost.Author? author, Dictionary<string, long> users)
{ {
string path; string path;
if (downloadConfig.FolderPerPost && postInfo != null && postInfo?.id is not null && postInfo?.postedAt is not null) if (downloadConfig.FolderPerPost && postInfo != null && postInfo?.id is not null && postInfo?.postedAt is not null)
@ -697,7 +726,7 @@ public class DownloadHelper : IDownloadHelper
return await CreateDirectoriesAndDownloadMedia(path, url, folder, media_id, api_type, task, filename, resolvedFilename); return await CreateDirectoriesAndDownloadMedia(path, url, folder, media_id, api_type, task, filename, resolvedFilename);
} }
public async Task<bool> DownloadStreamMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, Streams.List? streamInfo, Streams.Medium? streamMedia, Streams.Author? author, Dictionary<string, int> users) public async Task<bool> DownloadStreamMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, Streams.List? streamInfo, Streams.Medium? streamMedia, Streams.Author? author, Dictionary<string, long> users)
{ {
string path; string path;
if (downloadConfig.FolderPerPost && streamInfo != null && streamInfo?.id is not null && streamInfo?.postedAt is not null) if (downloadConfig.FolderPerPost && streamInfo != null && streamInfo?.id is not null && streamInfo?.postedAt is not null)
@ -717,7 +746,7 @@ public class DownloadHelper : IDownloadHelper
} }
public async Task<bool> DownloadMessageMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, Messages.List? messageInfo, Messages.Medium? messageMedia, Messages.FromUser? fromUser, Dictionary<string, int> users) public async Task<bool> DownloadMessageMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, Messages.List? messageInfo, Messages.Medium? messageMedia, Messages.FromUser? fromUser, Dictionary<string, long> users)
{ {
string path; string path;
if (downloadConfig.FolderPerMessage && messageInfo != null && messageInfo?.id is not null && messageInfo?.createdAt is not null) if (downloadConfig.FolderPerMessage && messageInfo != null && messageInfo?.id is not null && messageInfo?.createdAt is not null)
@ -735,7 +764,7 @@ public class DownloadHelper : IDownloadHelper
} }
public async Task<bool> DownloadArchivedMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, Archived.List? messageInfo, Archived.Medium? messageMedia, Archived.Author? author, Dictionary<string, int> users) public async Task<bool> DownloadArchivedMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, Archived.List? messageInfo, Archived.Medium? messageMedia, Archived.Author? author, Dictionary<string, long> users)
{ {
string path = "/Archived/Posts/Free"; string path = "/Archived/Posts/Free";
Uri uri = new(url); Uri uri = new(url);
@ -754,7 +783,7 @@ public class DownloadHelper : IDownloadHelper
return await CreateDirectoriesAndDownloadMedia(path, url, folder, media_id, api_type, task, filename, filename); return await CreateDirectoriesAndDownloadMedia(path, url, folder, media_id, api_type, task, filename, filename);
} }
public async Task<bool> DownloadPurchasedMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, Purchased.List? messageInfo, Medium? messageMedia, Purchased.FromUser? fromUser, Dictionary<string, int> users) public async Task<bool> DownloadPurchasedMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, Purchased.List? messageInfo, Medium? messageMedia, Purchased.FromUser? fromUser, Dictionary<string, long> users)
{ {
string path; string path;
if (downloadConfig.FolderPerPaidMessage && messageInfo != null && messageInfo?.id is not null && messageInfo?.createdAt is not null) if (downloadConfig.FolderPerPaidMessage && messageInfo != null && messageInfo?.id is not null && messageInfo?.createdAt is not null)
@ -771,7 +800,7 @@ public class DownloadHelper : IDownloadHelper
return await CreateDirectoriesAndDownloadMedia(path, url, folder, media_id, api_type, task, filename, resolvedFilename); return await CreateDirectoriesAndDownloadMedia(path, url, folder, media_id, api_type, task, filename, resolvedFilename);
} }
public async Task<bool> DownloadSinglePurchasedMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, SingleMessage? messageInfo, Medium? messageMedia, Entities.Messages.FromUser? fromUser, Dictionary<string, int> users) public async Task<bool> DownloadSinglePurchasedMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, SingleMessage? messageInfo, Medium? messageMedia, Entities.Messages.FromUser? fromUser, Dictionary<string, long> users)
{ {
string path; string path;
if (downloadConfig.FolderPerPaidMessage && messageInfo != null && messageInfo?.id is not null && messageInfo?.createdAt is not null) if (downloadConfig.FolderPerPaidMessage && messageInfo != null && messageInfo?.id is not null && messageInfo?.createdAt is not null)
@ -797,7 +826,7 @@ public class DownloadHelper : IDownloadHelper
Purchased.List? messageInfo, Purchased.List? messageInfo,
Medium? messageMedia, Medium? messageMedia,
Purchased.FromUser? fromUser, Purchased.FromUser? fromUser,
Dictionary<string, int> users) Dictionary<string, long> users)
{ {
string path; string path;
if (downloadConfig.FolderPerPaidPost && messageInfo != null && messageInfo?.id is not null && messageInfo?.postedAt is not null) if (downloadConfig.FolderPerPaidPost && messageInfo != null && messageInfo?.id is not null && messageInfo?.postedAt is not null)
@ -819,19 +848,19 @@ public class DownloadHelper : IDownloadHelper
{ {
try try
{ {
string path = $"/Profile"; string path = $"/Profile";
if (!Directory.Exists(folder + path)) if (!Directory.Exists(folder + path))
{ {
Directory.CreateDirectory(folder + path); Directory.CreateDirectory(folder + path);
} }
if (!string.IsNullOrEmpty(avatarUrl)) if (!string.IsNullOrEmpty(avatarUrl))
{ {
string avatarpath = $"{path}/Avatars"; string avatarpath = $"{path}/Avatars";
if (!Directory.Exists(folder + avatarpath)) if (!Directory.Exists(folder + avatarpath))
{ {
Directory.CreateDirectory(folder + avatarpath); Directory.CreateDirectory(folder + avatarpath);
} }
List<string> avatarMD5Hashes = WidevineClient.Utils.CalculateFolderMD5(folder + avatarpath); List<string> avatarMD5Hashes = WidevineClient.Utils.CalculateFolderMD5(folder + avatarpath);
@ -872,9 +901,9 @@ public class DownloadHelper : IDownloadHelper
if (!string.IsNullOrEmpty(headerUrl)) if (!string.IsNullOrEmpty(headerUrl))
{ {
string headerpath = $"{path}/Headers"; string headerpath = $"{path}/Headers";
if (!Directory.Exists(folder + headerpath)) if (!Directory.Exists(folder + headerpath))
{ {
Directory.CreateDirectory(folder + headerpath); Directory.CreateDirectory(folder + headerpath);
} }
List<string> headerMD5Hashes = WidevineClient.Utils.CalculateFolderMD5(folder + headerpath); List<string> headerMD5Hashes = WidevineClient.Utils.CalculateFolderMD5(folder + headerpath);
@ -965,12 +994,22 @@ public class DownloadHelper : IDownloadHelper
private void OnError(object sender, ConversionErrorEventArgs e) private void OnError(object sender, ConversionErrorEventArgs e)
{ {
Log.Debug("[{0} => {1}]: Error: {2}\n{3}", e.Input.Name, e.Output.Name, e.Exception.ExitCode, e.Exception.InnerException); // Guard all fields to avoid NullReference exceptions from FFmpeg.NET
var input = e?.Input?.Name ?? "<none>";
var output = e?.Output?.Name ?? "<none>";
var exitCode = e?.Exception?.ExitCode.ToString() ?? "<unknown>";
var message = e?.Exception?.Message ?? "<no message>";
var inner = e?.Exception?.InnerException?.Message ?? "<no inner>";
Log.Error("FFmpeg failed. Input={Input} Output={Output} ExitCode={ExitCode} Message={Message} Inner={Inner}",
input, output, exitCode, message, inner);
_completionSource?.TrySetResult(false); _completionSource?.TrySetResult(false);
} }
#region drm posts #region drm posts
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, ProgressTask task, string? filenameFormat, Messages.List? messageInfo, Messages.Medium? messageMedia, Messages.FromUser? fromUser, Dictionary<string, int> users) 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, ProgressTask task, string? filenameFormat, Messages.List? messageInfo, Messages.Medium? messageMedia, Messages.FromUser? fromUser, Dictionary<string, long> users)
{ {
try try
{ {
@ -986,9 +1025,9 @@ public class DownloadHelper : IDownloadHelper
{ {
path = "/Messages/Free/Videos"; path = "/Messages/Free/Videos";
} }
if (!Directory.Exists(folder + path)) if (!Directory.Exists(folder + path))
{ {
Directory.CreateDirectory(folder + path); Directory.CreateDirectory(folder + path);
} }
@ -1078,7 +1117,7 @@ public class DownloadHelper : IDownloadHelper
} }
public async Task<bool> DownloadPurchasedMessageDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, ProgressTask task, string? filenameFormat, Purchased.List? messageInfo, Medium? messageMedia, Purchased.FromUser? fromUser, Dictionary<string, int> users) public async Task<bool> DownloadPurchasedMessageDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, ProgressTask task, string? filenameFormat, Purchased.List? messageInfo, Medium? messageMedia, Purchased.FromUser? fromUser, Dictionary<string, long> users)
{ {
try try
{ {
@ -1094,9 +1133,9 @@ public class DownloadHelper : IDownloadHelper
{ {
path = "/Messages/Paid/Videos"; path = "/Messages/Paid/Videos";
} }
if (!Directory.Exists(folder + path)) if (!Directory.Exists(folder + path))
{ {
Directory.CreateDirectory(folder + path); Directory.CreateDirectory(folder + path);
} }
if (!string.IsNullOrEmpty(filenameFormat) && messageInfo != null && messageMedia != null) if (!string.IsNullOrEmpty(filenameFormat) && messageInfo != null && messageMedia != null)
@ -1184,7 +1223,7 @@ public class DownloadHelper : IDownloadHelper
return false; return false;
} }
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, ProgressTask task, string? filenameFormat, SingleMessage? messageInfo, Medium? messageMedia, Entities.Messages.FromUser? fromUser, Dictionary<string, int> users) 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, ProgressTask task, string? filenameFormat, SingleMessage? messageInfo, Medium? messageMedia, Entities.Messages.FromUser? fromUser, Dictionary<string, long> users)
{ {
try try
{ {
@ -1291,7 +1330,7 @@ public class DownloadHelper : IDownloadHelper
} }
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, ProgressTask task, string? filenameFormat, Post.List? postInfo, Post.Medium? postMedia, Post.Author? author, Dictionary<string, int> users) 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, ProgressTask task, string? filenameFormat, Post.List? postInfo, Post.Medium? postMedia, Post.Author? author, Dictionary<string, long> users)
{ {
try try
{ {
@ -1307,9 +1346,9 @@ public class DownloadHelper : IDownloadHelper
{ {
path = "/Posts/Free/Videos"; path = "/Posts/Free/Videos";
} }
if (!Directory.Exists(folder + path)) if (!Directory.Exists(folder + path))
{ {
Directory.CreateDirectory(folder + path); Directory.CreateDirectory(folder + path);
} }
if (!string.IsNullOrEmpty(filenameFormat) && postInfo != null && postMedia != null) if (!string.IsNullOrEmpty(filenameFormat) && postInfo != null && postMedia != null)
@ -1396,7 +1435,7 @@ public class DownloadHelper : IDownloadHelper
} }
return false; return false;
} }
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, ProgressTask task, string filenameFormat, SinglePost postInfo, SinglePost.Medium postMedia, SinglePost.Author author, Dictionary<string, int> users) 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, ProgressTask task, string filenameFormat, SinglePost postInfo, SinglePost.Medium postMedia, SinglePost.Author author, Dictionary<string, long> users)
{ {
try try
{ {
@ -1412,9 +1451,9 @@ public class DownloadHelper : IDownloadHelper
{ {
path = "/Posts/Free/Videos"; path = "/Posts/Free/Videos";
} }
if (!Directory.Exists(folder + path)) if (!Directory.Exists(folder + path))
{ {
Directory.CreateDirectory(folder + path); Directory.CreateDirectory(folder + path);
} }
if (!string.IsNullOrEmpty(filenameFormat) && postInfo != null && postMedia != null) if (!string.IsNullOrEmpty(filenameFormat) && postInfo != null && postMedia != null)
@ -1475,7 +1514,7 @@ public class DownloadHelper : IDownloadHelper
await m_DBHelper.UpdateMedia(folder, media_id, api_type, folder + path, customFileName + ".mp4", size, true, lastModified); await m_DBHelper.UpdateMedia(folder, media_id, api_type, folder + path, customFileName + ".mp4", size, true, lastModified);
} }
} }
if (downloadConfig.ShowScrapeSize) if (downloadConfig.ShowScrapeSize)
{ {
long size = await m_DBHelper.GetStoredFileSize(folder, media_id, api_type); long size = await m_DBHelper.GetStoredFileSize(folder, media_id, api_type);
@ -1501,7 +1540,7 @@ public class DownloadHelper : IDownloadHelper
} }
return false; return false;
} }
public async Task<bool> DownloadStreamsDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, ProgressTask task, string? filenameFormat, Streams.List? streamInfo, Streams.Medium? streamMedia, Streams.Author? author, Dictionary<string, int> users) public async Task<bool> DownloadStreamsDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, ProgressTask task, string? filenameFormat, Streams.List? streamInfo, Streams.Medium? streamMedia, Streams.Author? author, Dictionary<string, long> users)
{ {
try try
{ {
@ -1607,7 +1646,7 @@ public class DownloadHelper : IDownloadHelper
return false; return false;
} }
public async Task<bool> DownloadPurchasedPostDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, ProgressTask task, string? filenameFormat, Purchased.List? postInfo, Medium? postMedia, Purchased.FromUser? fromUser, Dictionary<string, int> users) public async Task<bool> DownloadPurchasedPostDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, ProgressTask task, string? filenameFormat, Purchased.List? postInfo, Medium? postMedia, Purchased.FromUser? fromUser, Dictionary<string, long> users)
{ {
try try
{ {
@ -1623,9 +1662,9 @@ public class DownloadHelper : IDownloadHelper
{ {
path = "/Posts/Paid/Videos"; path = "/Posts/Paid/Videos";
} }
if (!Directory.Exists(folder + path)) if (!Directory.Exists(folder + path))
{ {
Directory.CreateDirectory(folder + path); Directory.CreateDirectory(folder + path);
} }
@ -1715,7 +1754,7 @@ public class DownloadHelper : IDownloadHelper
} }
public async Task<bool> DownloadArchivedPostDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, ProgressTask task, string? filenameFormat, Archived.List? postInfo, Archived.Medium? postMedia, Archived.Author? author, Dictionary<string, int> users) public async Task<bool> DownloadArchivedPostDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, ProgressTask task, string? filenameFormat, Archived.List? postInfo, Archived.Medium? postMedia, Archived.Author? author, Dictionary<string, long> users)
{ {
try try
{ {
@ -1723,9 +1762,9 @@ public class DownloadHelper : IDownloadHelper
Uri uri = new(url); Uri uri = new(url);
string filename = System.IO.Path.GetFileName(uri.LocalPath).Split(".")[0]; string filename = System.IO.Path.GetFileName(uri.LocalPath).Split(".")[0];
string path = "/Archived/Posts/Free/Videos"; string path = "/Archived/Posts/Free/Videos";
if (!Directory.Exists(folder + path)) if (!Directory.Exists(folder + path))
{ {
Directory.CreateDirectory(folder + path); Directory.CreateDirectory(folder + path);
} }
if (!string.IsNullOrEmpty(filenameFormat) && postInfo != null && postMedia != null) if (!string.IsNullOrEmpty(filenameFormat) && postInfo != null && postMedia != null)

View File

@ -18,7 +18,7 @@ namespace OF_DL.Helpers
this.auth = auth; this.auth = auth;
} }
public async Task<Dictionary<string, string>> GetFilename(object obj1, object obj2, object obj3, List<string> selectedProperties, string username, Dictionary<string, int> users = null) public async Task<Dictionary<string, string>> GetFilename(object obj1, object obj2, object obj3, List<string> selectedProperties, string username, Dictionary<string, long> users = null)
{ {
Dictionary<string, string> values = new(); Dictionary<string, string> values = new();
Type type1 = obj1.GetType(); Type type1 = obj1.GetType();
@ -36,7 +36,7 @@ namespace OF_DL.Helpers
{ {
drmProperty = GetNestedPropertyValue(obj2, "files.drm"); drmProperty = GetNestedPropertyValue(obj2, "files.drm");
} }
if(fileProperty != null && drmProperty != null && propertyName == "mediaCreatedAt") if(fileProperty != null && drmProperty != null && propertyName == "mediaCreatedAt")
{ {
object mpdurl = GetNestedPropertyValue(obj2, "files.drm.manifest.dash"); object mpdurl = GetNestedPropertyValue(obj2, "files.drm.manifest.dash");
@ -66,7 +66,7 @@ namespace OF_DL.Helpers
continue; continue;
} }
} }
} }
PropertyInfo? property = Array.Find(properties2, p => p.Name.Equals(propertyName.Replace("media", ""), StringComparison.OrdinalIgnoreCase)); PropertyInfo? property = Array.Find(properties2, p => p.Name.Equals(propertyName.Replace("media", ""), StringComparison.OrdinalIgnoreCase));
if (property != null) if (property != null)

View File

@ -16,7 +16,7 @@ namespace OF_DL.Helpers
Task<string> GetDecryptionKeyCDM(Dictionary<string, string> drmHeaders, string licenceURL, string pssh); Task<string> GetDecryptionKeyCDM(Dictionary<string, string> drmHeaders, string licenceURL, string pssh);
Task<DateTime> GetDRMMPDLastModified(string mpdUrl, string policy, string signature, string kvp); Task<DateTime> GetDRMMPDLastModified(string mpdUrl, string policy, string signature, string kvp);
Task<string> GetDRMMPDPSSH(string mpdUrl, string policy, string signature, string kvp); Task<string> GetDRMMPDPSSH(string mpdUrl, string policy, string signature, string kvp);
Task<Dictionary<string, int>> GetLists(string endpoint, IDownloadConfig config); Task<Dictionary<string, long>> GetLists(string endpoint, IDownloadConfig config);
Task<List<string>> GetListUsers(string endpoint, IDownloadConfig config); Task<List<string>> GetListUsers(string endpoint, IDownloadConfig config);
Task<Dictionary<long, string>> GetMedia(MediaType mediatype, string endpoint, string? username, string folder, IDownloadConfig config, List<long> paid_post_ids); Task<Dictionary<long, string>> GetMedia(MediaType mediatype, string endpoint, string? username, string folder, IDownloadConfig config, List<long> paid_post_ids);
Task<PaidPostCollection> GetPaidPosts(string endpoint, string folder, string username, IDownloadConfig config, List<long> paid_post_ids, StatusContext ctx); Task<PaidPostCollection> GetPaidPosts(string endpoint, string folder, string username, IDownloadConfig config, List<long> paid_post_ids, StatusContext ctx);
@ -26,13 +26,13 @@ namespace OF_DL.Helpers
Task<ArchivedCollection> GetArchived(string endpoint, string folder, IDownloadConfig config, StatusContext ctx); Task<ArchivedCollection> GetArchived(string endpoint, string folder, IDownloadConfig config, StatusContext ctx);
Task<MessageCollection> GetMessages(string endpoint, string folder, IDownloadConfig config, StatusContext ctx); Task<MessageCollection> GetMessages(string endpoint, string folder, IDownloadConfig config, StatusContext ctx);
Task<PaidMessageCollection> GetPaidMessages(string endpoint, string folder, string username, IDownloadConfig config, StatusContext ctx); Task<PaidMessageCollection> GetPaidMessages(string endpoint, string folder, string username, IDownloadConfig config, StatusContext ctx);
Task<Dictionary<string, int>> GetPurchasedTabUsers(string endpoint, IDownloadConfig config, Dictionary<string, int> users); Task<Dictionary<string, long>> GetPurchasedTabUsers(string endpoint, IDownloadConfig config, Dictionary<string, long> users);
Task<List<PurchasedTabCollection>> GetPurchasedTab(string endpoint, string folder, IDownloadConfig config, Dictionary<string, int> users); Task<List<PurchasedTabCollection>> GetPurchasedTab(string endpoint, string folder, IDownloadConfig config, Dictionary<string, long> users);
Task<User> GetUserInfo(string endpoint); Task<User> GetUserInfo(string endpoint);
Task<JObject> GetUserInfoById(string endpoint); Task<JObject> GetUserInfoById(string endpoint);
Dictionary<string, string> GetDynamicHeaders(string path, string queryParam); Dictionary<string, string> GetDynamicHeaders(string path, string queryParam);
Task<Dictionary<string, int>> GetActiveSubscriptions(string endpoint, bool includeRestrictedSubscriptions, IDownloadConfig config); Task<Dictionary<string, long>> GetActiveSubscriptions(string endpoint, bool includeRestrictedSubscriptions, IDownloadConfig config);
Task<Dictionary<string, int>> GetExpiredSubscriptions(string endpoint, bool includeRestrictedSubscriptions, IDownloadConfig config); Task<Dictionary<string, long>> GetExpiredSubscriptions(string endpoint, bool includeRestrictedSubscriptions, IDownloadConfig config);
Task<string> GetDecryptionKeyOFDL(Dictionary<string, string> drmHeaders, string licenceURL, string pssh); Task<string> GetDecryptionKeyOFDL(Dictionary<string, string> drmHeaders, string licenceURL, string pssh);
} }
} }

View File

@ -2,12 +2,12 @@ namespace OF_DL.Helpers
{ {
public interface IDBHelper public interface IDBHelper
{ {
Task AddMessage(string folder, long post_id, string message_text, string price, bool is_paid, bool is_archived, DateTime created_at, int user_id); Task AddMessage(string folder, long post_id, string message_text, string price, bool is_paid, bool is_archived, DateTime created_at, long user_id);
Task AddPost(string folder, long post_id, string message_text, string price, bool is_paid, bool is_archived, DateTime created_at); Task AddPost(string folder, long post_id, string message_text, string price, bool is_paid, bool is_archived, DateTime created_at);
Task AddStory(string folder, long post_id, string message_text, string price, bool is_paid, bool is_archived, DateTime created_at); Task AddStory(string folder, long post_id, string message_text, string price, bool is_paid, bool is_archived, DateTime created_at);
Task CreateDB(string folder); Task CreateDB(string folder);
Task CreateUsersDB(Dictionary<string, int> users); Task CreateUsersDB(Dictionary<string, long> users);
Task CheckUsername(KeyValuePair<string, int> user, string path); Task CheckUsername(KeyValuePair<string, long> user, string path);
Task AddMedia(string folder, long media_id, long post_id, string link, string? directory, string? filename, long? size, string api_type, string media_type, bool preview, bool downloaded, DateTime? created_at); Task AddMedia(string folder, long media_id, long post_id, string link, string? directory, string? filename, long? size, string api_type, string media_type, bool preview, bool downloaded, DateTime? created_at);
Task UpdateMedia(string folder, long media_id, string api_type, string directory, string filename, long size, bool downloaded, DateTime created_at); Task UpdateMedia(string folder, long media_id, string api_type, string directory, string filename, long size, bool downloaded, DateTime created_at);
Task<long> GetStoredFileSize(string folder, long media_id, string api_type); Task<long> GetStoredFileSize(string folder, long media_id, string api_type);

View File

@ -12,25 +12,25 @@ namespace OF_DL.Helpers
public interface IDownloadHelper public interface IDownloadHelper
{ {
Task<long> CalculateTotalFileSize(List<string> urls); Task<long> CalculateTotalFileSize(List<string> urls);
Task<bool> DownloadArchivedMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string filenameFormat, Archived.List messageInfo, Archived.Medium messageMedia, Archived.Author author, Dictionary<string, int> users); Task<bool> DownloadArchivedMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string filenameFormat, Archived.List messageInfo, Archived.Medium messageMedia, Archived.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, ProgressTask task, string filenameFormat, Archived.List postInfo, Archived.Medium postMedia, Archived.Author author, Dictionary<string, int> users); Task<bool> DownloadArchivedPostDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, ProgressTask task, string filenameFormat, Archived.List postInfo, Archived.Medium postMedia, Archived.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, ProgressTask task, string filenameFormat, SinglePost postInfo, SinglePost.Medium postMedia, SinglePost.Author author, Dictionary<string, int> users); Task<bool> DownloadPostDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, ProgressTask task, string filenameFormat, SinglePost postInfo, SinglePost.Medium postMedia, SinglePost.Author author, Dictionary<string, long> users);
Task DownloadAvatarHeader(string? avatarUrl, string? headerUrl, string folder, string username); Task DownloadAvatarHeader(string? avatarUrl, string? headerUrl, string folder, string username);
Task<bool> DownloadMessageDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, ProgressTask task, string filenameFormat, Messages.List messageInfo, Messages.Medium messageMedia, Messages.FromUser fromUser, Dictionary<string, int> users); Task<bool> DownloadMessageDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, ProgressTask task, string filenameFormat, Messages.List messageInfo, Messages.Medium messageMedia, Messages.FromUser fromUser, Dictionary<string, long> users);
Task<bool> DownloadMessageMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string filenameFormat, Messages.List messageInfo, Messages.Medium messageMedia, Messages.FromUser fromUser, Dictionary<string, int> users); Task<bool> DownloadMessageMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string filenameFormat, Messages.List messageInfo, Messages.Medium messageMedia, Messages.FromUser fromUser, 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, ProgressTask task, string filenameFormat, Post.List postInfo, Post.Medium postMedia, Post.Author author, Dictionary<string, int> users); Task<bool> DownloadPostDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, ProgressTask task, string filenameFormat, Post.List postInfo, Post.Medium postMedia, Post.Author author, Dictionary<string, long> users);
Task<bool> DownloadPostMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, Post.List? postInfo, Post.Medium? postMedia, Post.Author? author, Dictionary<string, int> users); Task<bool> DownloadPostMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, Post.List? postInfo, Post.Medium? postMedia, Post.Author? author, Dictionary<string, long> users);
Task<bool> DownloadPostMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, SinglePost? postInfo, SinglePost.Medium? postMedia, SinglePost.Author? author, Dictionary<string, int> users); Task<bool> DownloadPostMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, SinglePost? postInfo, SinglePost.Medium? postMedia, SinglePost.Author? author, Dictionary<string, long> users);
Task<bool> DownloadPurchasedMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string filenameFormat, Purchased.List messageInfo, Medium messageMedia, Purchased.FromUser fromUser, Dictionary<string, int> users); Task<bool> DownloadPurchasedMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string filenameFormat, Purchased.List messageInfo, Medium messageMedia, Purchased.FromUser fromUser, Dictionary<string, long> users);
Task<bool> DownloadSinglePurchasedMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, SingleMessage? messageInfo, Medium? messageMedia, Entities.Messages.FromUser? fromUser, Dictionary<string, int> users); Task<bool> DownloadSinglePurchasedMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, SingleMessage? messageInfo, Medium? messageMedia, Entities.Messages.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, ProgressTask task, string filenameFormat, Purchased.List messageInfo, Medium messageMedia, Purchased.FromUser fromUser, Dictionary<string, int> users); Task<bool> DownloadPurchasedMessageDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, ProgressTask task, string filenameFormat, Purchased.List messageInfo, Medium messageMedia, Purchased.FromUser fromUser, Dictionary<string, long> users);
Task<bool> DownloadSinglePurchasedMessageDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, ProgressTask task, string? filenameFormat, SingleMessage? messageInfo, Medium? messageMedia, Entities.Messages.FromUser? fromUser, Dictionary<string, int> users); Task<bool> DownloadSinglePurchasedMessageDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, ProgressTask task, string? filenameFormat, SingleMessage? messageInfo, Medium? messageMedia, Entities.Messages.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, ProgressTask task, string filenameFormat, Purchased.List postInfo, Medium postMedia, Purchased.FromUser fromUser, Dictionary<string, int> users); Task<bool> DownloadPurchasedPostDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, ProgressTask task, string filenameFormat, Purchased.List postInfo, Medium postMedia, Purchased.FromUser fromUser, Dictionary<string, long> users);
Task<bool> DownloadPurchasedPostMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string filenameFormat, Purchased.List messageInfo, Medium messageMedia, Purchased.FromUser fromUser, Dictionary<string, int> users); Task<bool> DownloadPurchasedPostMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string filenameFormat, Purchased.List messageInfo, Medium messageMedia, Purchased.FromUser fromUser, Dictionary<string, long> users);
Task<bool> DownloadStoryMedia(string url, string folder, long media_id, string api_type, ProgressTask task); Task<bool> DownloadStoryMedia(string url, string folder, long media_id, string api_type, ProgressTask task);
Task<bool> DownloadStreamMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, Streams.List? streamInfo, Streams.Medium? streamMedia, Streams.Author? author, Dictionary<string, int> users); Task<bool> DownloadStreamMedia(string url, string folder, long media_id, string api_type, ProgressTask task, string? filenameFormat, Streams.List? streamInfo, Streams.Medium? streamMedia, Streams.Author? author, Dictionary<string, long> users);
Task<bool> DownloadStreamsDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, ProgressTask task, string filenameFormat, Streams.List streamInfo, Streams.Medium streamMedia, Streams.Author author, Dictionary<string, int> users); Task<bool> DownloadStreamsDRMVideo(string policy, string signature, string kvp, string url, string decryptionKey, string folder, DateTime lastModified, long media_id, string api_type, ProgressTask task, string filenameFormat, Streams.List streamInfo, Streams.Medium streamMedia, Streams.Author author, Dictionary<string, long> users);
} }
} }

View File

@ -3,6 +3,6 @@ namespace OF_DL.Helpers
public interface IFileNameHelper public interface IFileNameHelper
{ {
Task<string> BuildFilename(string fileFormat, Dictionary<string, string> values); Task<string> BuildFilename(string fileFormat, Dictionary<string, string> values);
Task<Dictionary<string, string>> GetFilename(object obj1, object obj2, object obj3, List<string> selectedProperties, string username, Dictionary<string, int> users = null); Task<Dictionary<string, string>> GetFilename(object obj1, object obj2, object obj3, List<string> selectedProperties, string username, Dictionary<string, long> users = null);
} }
} }

View File

@ -116,6 +116,8 @@ public class Program
.CreateLogger(); .CreateLogger();
AnsiConsole.Write(new FigletText("Welcome to OF-DL").Color(Color.Red)); AnsiConsole.Write(new FigletText("Welcome to OF-DL").Color(Color.Red));
AnsiConsole.Markup("Documentation: [link]https://docs.ofdl.tools/[/]\n");
AnsiConsole.Markup("Discord server: [link]https://discord.com/invite/6bUW8EJ53j[/]\n\n");
//Remove config.json and convert to config.conf //Remove config.json and convert to config.conf
if (File.Exists("config.json")) if (File.Exists("config.json"))
@ -129,6 +131,10 @@ public class Program
if (jsonConfig != null) if (jsonConfig != null)
{ {
var hoconConfig = new StringBuilder(); var hoconConfig = new StringBuilder();
hoconConfig.AppendLine("# Auth");
hoconConfig.AppendLine("Auth {");
hoconConfig.AppendLine($" DisableBrowserAuth = \"{jsonConfig.DisableBrowserAuth.ToString().ToLower()}\"");
hoconConfig.AppendLine("}");
hoconConfig.AppendLine("# External Tools"); hoconConfig.AppendLine("# External Tools");
hoconConfig.AppendLine("External {"); hoconConfig.AppendLine("External {");
hoconConfig.AppendLine($" FFmpegPath = \"{jsonConfig.FFmpegPath}\""); hoconConfig.AppendLine($" FFmpegPath = \"{jsonConfig.FFmpegPath}\"");
@ -253,7 +259,7 @@ public class Program
config = new Entities.Config config = new Entities.Config
{ {
//Auth //Auth
DisableBrowserAuth = hoconConfig.GetBoolean("DisableBrowserAuth"), DisableBrowserAuth = hoconConfig.GetBoolean("Auth.DisableBrowserAuth"),
// FFmpeg Settings // FFmpeg Settings
FFmpegPath = hoconConfig.GetString("External.FFmpegPath"), FFmpegPath = hoconConfig.GetString("External.FFmpegPath"),
@ -373,7 +379,9 @@ public class Program
Entities.Config jsonConfig = new Entities.Config(); Entities.Config jsonConfig = new Entities.Config();
var hoconConfig = new StringBuilder(); var hoconConfig = new StringBuilder();
hoconConfig.AppendLine("# Auth"); hoconConfig.AppendLine("# Auth");
hoconConfig.AppendLine($"DisableBrowserAuth = {jsonConfig.DisableBrowserAuth.ToString().ToLower()}"); hoconConfig.AppendLine("Auth {");
hoconConfig.AppendLine($" DisableBrowserAuth = \"{jsonConfig.DisableBrowserAuth.ToString().ToLower()}\"");
hoconConfig.AppendLine("}");
hoconConfig.AppendLine("# External Tools"); hoconConfig.AppendLine("# External Tools");
hoconConfig.AppendLine("External {"); hoconConfig.AppendLine("External {");
hoconConfig.AppendLine($" FFmpegPath = \"{jsonConfig.FFmpegPath}\""); hoconConfig.AppendLine($" FFmpegPath = \"{jsonConfig.FFmpegPath}\"");
@ -919,7 +927,7 @@ public class Program
do do
{ {
DateTime startTime = DateTime.Now; DateTime startTime = DateTime.Now;
Dictionary<string, int> users = new(); Dictionary<string, long> users = new();
var activeSubbed = await m_ApiHelper.GetActiveSubscribed("/subscriptions/subscribes", Config.IncludeRestrictedSubscriptions, Config); var activeSubbed = await m_ApiHelper.GetActiveSubscribed("/subscriptions/subscribes", Config.IncludeRestrictedSubscriptions, Config);
var activeSubs = activeSubbed?.ToDictionary(e => e.Key, e => e.Value.id); var activeSubs = activeSubbed?.ToDictionary(e => e.Key, e => e.Value.id);
{ {
@ -932,7 +940,7 @@ public class Program
} }
Log.Debug("Subscriptions: "); Log.Debug("Subscriptions: ");
foreach (KeyValuePair<string, int> activeSub in activeSubs) foreach (KeyValuePair<string, long> activeSub in activeSubs)
{ {
if (!users.ContainsKey(activeSub.Key)) if (!users.ContainsKey(activeSub.Key))
{ {
@ -944,8 +952,8 @@ public class Program
{ {
Log.Debug("Inactive Subscriptions: "); Log.Debug("Inactive Subscriptions: ");
Dictionary<string, int> expiredSubs = await m_ApiHelper.GetExpiredSubscriptions("/subscriptions/subscribes", Config.IncludeRestrictedSubscriptions, Config); Dictionary<string, long> expiredSubs = await m_ApiHelper.GetExpiredSubscriptions("/subscriptions/subscribes", Config.IncludeRestrictedSubscriptions, Config);
foreach (KeyValuePair<string, int> expiredSub in expiredSubs) foreach (KeyValuePair<string, long> expiredSub in expiredSubs)
{ {
if (!users.ContainsKey(expiredSub.Key)) if (!users.ContainsKey(expiredSub.Key))
{ {
@ -955,7 +963,7 @@ public class Program
} }
} }
Dictionary<string, int> lists = await m_ApiHelper.GetLists("/lists", Config); Dictionary<string, long> lists = await m_ApiHelper.GetLists("/lists", Config);
// Remove users from the list if they are in the ignored list // Remove users from the list if they are in the ignored list
if (!string.IsNullOrEmpty(Config.IgnoredUsersListName)) if (!string.IsNullOrEmpty(Config.IgnoredUsersListName))
@ -973,28 +981,28 @@ public class Program
} }
await dBHelper.CreateUsersDB(users); await dBHelper.CreateUsersDB(users);
KeyValuePair<bool, Dictionary<string, int>> hasSelectedUsersKVP; KeyValuePair<bool, Dictionary<string, long>> hasSelectedUsersKVP;
if(Config.NonInteractiveMode && Config.NonInteractiveModePurchasedTab) if(Config.NonInteractiveMode && Config.NonInteractiveModePurchasedTab)
{ {
hasSelectedUsersKVP = new KeyValuePair<bool, Dictionary<string, int>>(true, new Dictionary<string, int> { { "PurchasedTab", 0 } }); hasSelectedUsersKVP = new KeyValuePair<bool, Dictionary<string, long>>(true, new Dictionary<string, long> { { "PurchasedTab", 0 } });
} }
else if (Config.NonInteractiveMode && string.IsNullOrEmpty(Config.NonInteractiveModeListName)) else if (Config.NonInteractiveMode && string.IsNullOrEmpty(Config.NonInteractiveModeListName))
{ {
hasSelectedUsersKVP = new KeyValuePair<bool, Dictionary<string, int>>(true, users); hasSelectedUsersKVP = new KeyValuePair<bool, Dictionary<string, long>>(true, users);
} }
else if (Config.NonInteractiveMode && !string.IsNullOrEmpty(Config.NonInteractiveModeListName)) else if (Config.NonInteractiveMode && !string.IsNullOrEmpty(Config.NonInteractiveModeListName))
{ {
var listId = lists[Config.NonInteractiveModeListName]; var listId = lists[Config.NonInteractiveModeListName];
var listUsernames = await m_ApiHelper.GetListUsers($"/lists/{listId}/users", Config) ?? []; var listUsernames = await m_ApiHelper.GetListUsers($"/lists/{listId}/users", Config) ?? [];
var selectedUsers = users.Where(x => listUsernames.Contains(x.Key)).Distinct().ToDictionary(x => x.Key, x => x.Value); var selectedUsers = users.Where(x => listUsernames.Contains(x.Key)).Distinct().ToDictionary(x => x.Key, x => x.Value);
hasSelectedUsersKVP = new KeyValuePair<bool, Dictionary<string, int>>(true, selectedUsers); hasSelectedUsersKVP = new KeyValuePair<bool, Dictionary<string, long>>(true, selectedUsers);
} }
else else
{ {
var userSelectionResult = await HandleUserSelection(m_ApiHelper, Config, users, lists); var userSelectionResult = await HandleUserSelection(m_ApiHelper, Config, users, lists);
Config = userSelectionResult.updatedConfig; Config = userSelectionResult.updatedConfig;
hasSelectedUsersKVP = new KeyValuePair<bool, Dictionary<string, int>>(userSelectionResult.IsExit, userSelectionResult.selectedUsers); hasSelectedUsersKVP = new KeyValuePair<bool, Dictionary<string, long>>(userSelectionResult.IsExit, userSelectionResult.selectedUsers);
} }
if (hasSelectedUsersKVP.Key && hasSelectedUsersKVP.Value != null && hasSelectedUsersKVP.Value.ContainsKey("SinglePost")) if (hasSelectedUsersKVP.Key && hasSelectedUsersKVP.Value != null && hasSelectedUsersKVP.Value.ContainsKey("SinglePost"))
@ -1060,9 +1068,9 @@ public class Program
} }
else if (hasSelectedUsersKVP.Key && hasSelectedUsersKVP.Value != null && hasSelectedUsersKVP.Value.ContainsKey("PurchasedTab")) else if (hasSelectedUsersKVP.Key && hasSelectedUsersKVP.Value != null && hasSelectedUsersKVP.Value.ContainsKey("PurchasedTab"))
{ {
Dictionary<string, int> purchasedTabUsers = await m_ApiHelper.GetPurchasedTabUsers("/posts/paid/all", Config, users); Dictionary<string, long> purchasedTabUsers = await m_ApiHelper.GetPurchasedTabUsers("/posts/paid/all", Config, users);
AnsiConsole.Markup($"[red]Checking folders for Users in Purchased Tab\n[/]"); AnsiConsole.Markup($"[red]Checking folders for Users in Purchased Tab\n[/]");
foreach (KeyValuePair<string, int> user in purchasedTabUsers) foreach (KeyValuePair<string, long> user in purchasedTabUsers)
{ {
string path = ""; string path = "";
if (!string.IsNullOrEmpty(Config.DownloadPath)) if (!string.IsNullOrEmpty(Config.DownloadPath))
@ -1220,7 +1228,7 @@ public class Program
else if (hasSelectedUsersKVP.Key && !hasSelectedUsersKVP.Value.ContainsKey("ConfigChanged")) else if (hasSelectedUsersKVP.Key && !hasSelectedUsersKVP.Value.ContainsKey("ConfigChanged"))
{ {
//Iterate over each user in the list of users //Iterate over each user in the list of users
foreach (KeyValuePair<string, int> user in hasSelectedUsersKVP.Value) foreach (KeyValuePair<string, long> user in hasSelectedUsersKVP.Value)
{ {
int paidPostCount = 0; int paidPostCount = 0;
int postCount = 0; int postCount = 0;
@ -1378,7 +1386,7 @@ public class Program
return combinedConfig; return combinedConfig;
} }
private static async Task<int> DownloadPaidMessages(IDownloadContext downloadContext, KeyValuePair<bool, Dictionary<string, int>> hasSelectedUsersKVP, KeyValuePair<string, int> user, int paidMessagesCount, string path) private static async Task<int> DownloadPaidMessages(IDownloadContext downloadContext, KeyValuePair<bool, Dictionary<string, long>> hasSelectedUsersKVP, KeyValuePair<string, long> user, int paidMessagesCount, string path)
{ {
Log.Debug($"Calling DownloadPaidMessages - {user.Key}"); Log.Debug($"Calling DownloadPaidMessages - {user.Key}");
@ -1511,7 +1519,7 @@ public class Program
return paidMessagesCount; return paidMessagesCount;
} }
private static async Task<int> DownloadMessages(IDownloadContext downloadContext, KeyValuePair<bool, Dictionary<string, int>> hasSelectedUsersKVP, KeyValuePair<string, int> user, int messagesCount, string path) private static async Task<int> DownloadMessages(IDownloadContext downloadContext, KeyValuePair<bool, Dictionary<string, long>> hasSelectedUsersKVP, KeyValuePair<string, long> user, int messagesCount, string path)
{ {
Log.Debug($"Calling DownloadMessages - {user.Key}"); Log.Debug($"Calling DownloadMessages - {user.Key}");
@ -1644,7 +1652,7 @@ public class Program
return messagesCount; return messagesCount;
} }
private static async Task<int> DownloadHighlights(IDownloadContext downloadContext, KeyValuePair<string, int> user, int highlightsCount, string path) private static async Task<int> DownloadHighlights(IDownloadContext downloadContext, KeyValuePair<string, long> user, int highlightsCount, string path)
{ {
Log.Debug($"Calling DownloadHighlights - {user.Key}"); Log.Debug($"Calling DownloadHighlights - {user.Key}");
@ -1701,7 +1709,7 @@ public class Program
return highlightsCount; return highlightsCount;
} }
private static async Task<int> DownloadStories(IDownloadContext downloadContext, KeyValuePair<string, int> user, int storiesCount, string path) private static async Task<int> DownloadStories(IDownloadContext downloadContext, KeyValuePair<string, long> user, int storiesCount, string path)
{ {
Log.Debug($"Calling DownloadStories - {user.Key}"); Log.Debug($"Calling DownloadStories - {user.Key}");
@ -1758,7 +1766,7 @@ public class Program
return storiesCount; return storiesCount;
} }
private static async Task<int> DownloadArchived(IDownloadContext downloadContext, KeyValuePair<bool, Dictionary<string, int>> hasSelectedUsersKVP, KeyValuePair<string, int> user, int archivedCount, string path) private static async Task<int> DownloadArchived(IDownloadContext downloadContext, KeyValuePair<bool, Dictionary<string, long>> hasSelectedUsersKVP, KeyValuePair<string, long> user, int archivedCount, string path)
{ {
Log.Debug($"Calling DownloadArchived - {user.Key}"); Log.Debug($"Calling DownloadArchived - {user.Key}");
@ -1891,7 +1899,7 @@ public class Program
return archivedCount; return archivedCount;
} }
private static async Task<int> DownloadFreePosts(IDownloadContext downloadContext, KeyValuePair<bool, Dictionary<string, int>> hasSelectedUsersKVP, KeyValuePair<string, int> user, int postCount, string path) private static async Task<int> DownloadFreePosts(IDownloadContext downloadContext, KeyValuePair<bool, Dictionary<string, long>> hasSelectedUsersKVP, KeyValuePair<string, long> user, int postCount, string path)
{ {
Log.Debug($"Calling DownloadFreePosts - {user.Key}"); Log.Debug($"Calling DownloadFreePosts - {user.Key}");
@ -2031,7 +2039,7 @@ public class Program
return postCount; return postCount;
} }
private static async Task<int> DownloadPaidPosts(IDownloadContext downloadContext, KeyValuePair<bool, Dictionary<string, int>> hasSelectedUsersKVP, KeyValuePair<string, int> user, int paidPostCount, string path) private static async Task<int> DownloadPaidPosts(IDownloadContext downloadContext, KeyValuePair<bool, Dictionary<string, long>> hasSelectedUsersKVP, KeyValuePair<string, long> user, int paidPostCount, string path)
{ {
Log.Debug($"Calling DownloadPaidPosts - {user.Key}"); Log.Debug($"Calling DownloadPaidPosts - {user.Key}");
@ -2164,7 +2172,7 @@ public class Program
return paidPostCount; return paidPostCount;
} }
private static async Task<int> DownloadPaidPostsPurchasedTab(IDownloadContext downloadContext, PaidPostCollection purchasedPosts, KeyValuePair<string, int> user, int paidPostCount, string path, Dictionary<string, int> users) private static async Task<int> DownloadPaidPostsPurchasedTab(IDownloadContext downloadContext, PaidPostCollection purchasedPosts, KeyValuePair<string, long> user, int paidPostCount, string path, Dictionary<string, long> users)
{ {
int oldPaidPostCount = 0; int oldPaidPostCount = 0;
int newPaidPostCount = 0; int newPaidPostCount = 0;
@ -2288,7 +2296,7 @@ public class Program
return paidPostCount; return paidPostCount;
} }
private static async Task<int> DownloadPaidMessagesPurchasedTab(IDownloadContext downloadContext, PaidMessageCollection paidMessageCollection, KeyValuePair<string, int> user, int paidMessagesCount, string path, Dictionary<string, int> users) private static async Task<int> DownloadPaidMessagesPurchasedTab(IDownloadContext downloadContext, PaidMessageCollection paidMessageCollection, KeyValuePair<string, long> user, int paidMessagesCount, string path, Dictionary<string, long> users)
{ {
int oldPaidMessagesCount = 0; int oldPaidMessagesCount = 0;
int newPaidMessagesCount = 0; int newPaidMessagesCount = 0;
@ -2413,7 +2421,7 @@ public class Program
return paidMessagesCount; return paidMessagesCount;
} }
private static async Task<int> DownloadStreams(IDownloadContext downloadContext, KeyValuePair<bool, Dictionary<string, int>> hasSelectedUsersKVP, KeyValuePair<string, int> user, int streamsCount, string path) private static async Task<int> DownloadStreams(IDownloadContext downloadContext, KeyValuePair<bool, Dictionary<string, long>> hasSelectedUsersKVP, KeyValuePair<string, long> user, int streamsCount, string path)
{ {
Log.Debug($"Calling DownloadStreams - {user.Key}"); Log.Debug($"Calling DownloadStreams - {user.Key}");
@ -2552,7 +2560,7 @@ public class Program
return streamsCount; return streamsCount;
} }
private static async Task<int> DownloadPaidMessage(IDownloadContext downloadContext, KeyValuePair<bool, Dictionary<string, int>> hasSelectedUsersKVP, string username, int paidMessagesCount, string path, long message_id) private static async Task<int> DownloadPaidMessage(IDownloadContext downloadContext, KeyValuePair<bool, Dictionary<string, long>> hasSelectedUsersKVP, string username, int paidMessagesCount, string path, long message_id)
{ {
Log.Debug($"Calling DownloadPaidMessage - {username}"); Log.Debug($"Calling DownloadPaidMessage - {username}");
@ -2682,7 +2690,7 @@ public class Program
return paidMessagesCount; return paidMessagesCount;
} }
private static async Task DownloadSinglePost(IDownloadContext downloadContext, long post_id, string path, Dictionary<string, int> users) private static async Task DownloadSinglePost(IDownloadContext downloadContext, long post_id, string path, Dictionary<string, long> users)
{ {
Log.Debug($"Calling DownloadSinglePost - {post_id.ToString()}"); Log.Debug($"Calling DownloadSinglePost - {post_id.ToString()}");
@ -2800,10 +2808,10 @@ public class Program
} }
} }
public static async Task<(bool IsExit, Dictionary<string, int>? selectedUsers, Entities.Config? updatedConfig)> HandleUserSelection(APIHelper apiHelper, Entities.Config currentConfig, Dictionary<string, int> users, Dictionary<string, int> lists) public static async Task<(bool IsExit, Dictionary<string, long>? selectedUsers, Entities.Config? updatedConfig)> HandleUserSelection(APIHelper apiHelper, Entities.Config currentConfig, Dictionary<string, long> users, Dictionary<string, long> lists)
{ {
bool hasSelectedUsers = false; bool hasSelectedUsers = false;
Dictionary<string, int> selectedUsers = new Dictionary<string, int>(); Dictionary<string, long> selectedUsers = new Dictionary<string, long>();
while (!hasSelectedUsers) while (!hasSelectedUsers)
{ {
@ -2844,7 +2852,7 @@ public class Program
List<string> listUsernames = new(); List<string> listUsernames = new();
foreach (var item in listSelection) foreach (var item in listSelection)
{ {
int listId = lists[item.Replace("[red]", "").Replace("[/]", "")]; long listId = lists[item.Replace("[red]", "").Replace("[/]", "")];
List<string> usernames = await apiHelper.GetListUsers($"/lists/{listId}/users", config); List<string> usernames = await apiHelper.GetListUsers($"/lists/{listId}/users", config);
foreach (string user in usernames) foreach (string user in usernames)
{ {
@ -2884,11 +2892,11 @@ public class Program
} }
break; break;
case "[red]Download Single Post[/]": case "[red]Download Single Post[/]":
return (true, new Dictionary<string, int> { { "SinglePost", 0 } }, currentConfig); return (true, new Dictionary<string, long> { { "SinglePost", 0 } }, currentConfig);
case "[red]Download Single Paid Message[/]": case "[red]Download Single Paid Message[/]":
return (true, new Dictionary<string, int> { { "SingleMessage", 0 } }, currentConfig); return (true, new Dictionary<string, long> { { "SingleMessage", 0 } }, currentConfig);
case "[red]Download Purchased Tab[/]": case "[red]Download Purchased Tab[/]":
return (true, new Dictionary<string, int> { { "PurchasedTab", 0 } }, currentConfig); return (true, new Dictionary<string, long> { { "PurchasedTab", 0 } }, currentConfig);
case "[red]Edit config.conf[/]": case "[red]Edit config.conf[/]":
while (true) while (true)
{ {
@ -2956,7 +2964,9 @@ public class Program
var hoconConfig = new StringBuilder(); var hoconConfig = new StringBuilder();
hoconConfig.AppendLine("# Auth"); hoconConfig.AppendLine("# Auth");
hoconConfig.AppendLine($"DisableBrowserAuth = {newConfig.DisableBrowserAuth.ToString().ToLower()}"); hoconConfig.AppendLine("Auth {");
hoconConfig.AppendLine($" DisableBrowserAuth = \"{newConfig.DisableBrowserAuth.ToString().ToLower()}\"");
hoconConfig.AppendLine("}");
hoconConfig.AppendLine("# External Tools"); hoconConfig.AppendLine("# External Tools");
hoconConfig.AppendLine("External {"); hoconConfig.AppendLine("External {");
hoconConfig.AppendLine($" FFmpegPath = \"{newConfig.FFmpegPath}\""); hoconConfig.AppendLine($" FFmpegPath = \"{newConfig.FFmpegPath}\"");
@ -3058,7 +3068,7 @@ public class Program
currentConfig = newConfig; currentConfig = newConfig;
if (configChanged) if (configChanged)
{ {
return (true, new Dictionary<string, int> { { "ConfigChanged", 0 } }, currentConfig); return (true, new Dictionary<string, long> { { "ConfigChanged", 0 } }, currentConfig);
} }
break; break;
} }
@ -3116,7 +3126,9 @@ public class Program
var hoconConfig = new StringBuilder(); var hoconConfig = new StringBuilder();
hoconConfig.AppendLine("# Auth"); hoconConfig.AppendLine("# Auth");
hoconConfig.AppendLine($"DisableBrowserAuth = {newConfig.DisableBrowserAuth.ToString().ToLower()}"); hoconConfig.AppendLine("Auth {");
hoconConfig.AppendLine($" DisableBrowserAuth = \"{newConfig.DisableBrowserAuth.ToString().ToLower()}\"");
hoconConfig.AppendLine("}");
hoconConfig.AppendLine("# External Tools"); hoconConfig.AppendLine("# External Tools");
hoconConfig.AppendLine("External {"); hoconConfig.AppendLine("External {");
hoconConfig.AppendLine($" FFmpegPath = \"{newConfig.FFmpegPath}\""); hoconConfig.AppendLine($" FFmpegPath = \"{newConfig.FFmpegPath}\"");
@ -3212,7 +3224,7 @@ public class Program
if (configChanged) if (configChanged)
{ {
return (true, new Dictionary<string, int> { { "ConfigChanged", 0 } }, currentConfig); return (true, new Dictionary<string, long> { { "ConfigChanged", 0 } }, currentConfig);
} }
break; break;
@ -3238,7 +3250,7 @@ public class Program
return (true, selectedUsers, currentConfig); // Return true to indicate selected users return (true, selectedUsers, currentConfig); // Return true to indicate selected users
} }
public static List<string> GetMainMenuOptions(Dictionary<string, int> users, Dictionary<string, int> lists) public static List<string> GetMainMenuOptions(Dictionary<string, long> users, Dictionary<string, long> lists)
{ {
if (lists.Count > 0) if (lists.Count > 0)
{ {