Updated subscription lookup to match OF website.

This commit is contained in:
Casper Sparre 2025-03-08 15:14:27 +01:00
parent a21fe01a0c
commit a4af7f27da
2 changed files with 76 additions and 64 deletions

View File

@ -25,6 +25,9 @@ namespace OF_DL.Helpers;
public class APIHelper : IAPIHelper public class APIHelper : IAPIHelper
{ {
private const int MAX_RETRIES = 10;
private const int DELAY_BEFORE_RETRY = 1000;
private static readonly JsonSerializerSettings m_JsonSerializerSettings; private static readonly JsonSerializerSettings m_JsonSerializerSettings;
private readonly IDBHelper m_DBHelper; private readonly IDBHelper m_DBHelper;
private readonly IDownloadConfig downloadConfig; private readonly IDownloadConfig downloadConfig;
@ -118,11 +121,13 @@ public class APIHelper : IAPIHelper
} }
private async Task<string?> BuildHeaderAndExecuteRequests(Dictionary<string, string> getParams, string endpoint, HttpClient client) private async Task<string?> BuildHeaderAndExecuteRequests(Dictionary<string, string> getParams, string endpoint, HttpClient client, HttpMethod? method = null, int retryCount = 0)
{ {
Log.Debug("Calling BuildHeaderAndExecuteRequests"); Log.Debug("Calling BuildHeaderAndExecuteRequests -- Attempt number: {AttemptNumber}", retryCount + 1);
HttpRequestMessage request = await BuildHttpRequestMessage(getParams, endpoint); try
{
HttpRequestMessage request = await BuildHttpRequestMessage(getParams, endpoint, method);
using var response = await client.SendAsync(request); using var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
string body = await response.Content.ReadAsStringAsync(); string body = await response.Content.ReadAsStringAsync();
@ -131,6 +136,17 @@ public class APIHelper : IAPIHelper
return body; return body;
} }
catch (HttpRequestException ex)
{
if (ex.StatusCode == System.Net.HttpStatusCode.TooManyRequests && retryCount < MAX_RETRIES)
{
await Task.Delay(DELAY_BEFORE_RETRY);
return await BuildHeaderAndExecuteRequests(getParams, endpoint, client, method, ++retryCount);
}
throw;
}
}
private async Task<HttpRequestMessage> BuildHttpRequestMessage(Dictionary<string, string> getParams, string endpoint) private async Task<HttpRequestMessage> BuildHttpRequestMessage(Dictionary<string, string> getParams, string endpoint)
@ -298,47 +314,44 @@ public class APIHelper : IAPIHelper
try try
{ {
Dictionary<string, int> users = new(); Dictionary<string, int> users = new();
Subscriptions subscriptions = new();
int limit = 25;
int offset = 0;
getParams["limit"] = limit.ToString();
getParams["offset"] = offset.ToString();
Log.Debug("Calling GetAllSubscrptions"); Log.Debug("Calling GetAllSubscrptions");
string? body = await BuildHeaderAndExecuteRequests(getParams, endpoint, httpClient);
subscriptions = JsonConvert.DeserializeObject<Subscriptions>(body);
if (subscriptions != null && subscriptions.hasMore)
{
getParams["offset"] = subscriptions.list.Count.ToString();
while (true) while (true)
{ {
Subscriptions newSubscriptions = new(); string? body = await BuildHeaderAndExecuteRequests(getParams, endpoint, httpClient);
string? loopbody = await BuildHeaderAndExecuteRequests(getParams, endpoint, httpClient);
if (!string.IsNullOrEmpty(loopbody) && (!loopbody.Contains("[]") || loopbody.Trim() != "[]")) if (string.IsNullOrWhiteSpace(body))
{
newSubscriptions = JsonConvert.DeserializeObject<Subscriptions>(loopbody, m_JsonSerializerSettings);
}
else
{
break; break;
}
subscriptions.list.AddRange(newSubscriptions.list); Subscriptions? subscriptions = JsonConvert.DeserializeObject<Subscriptions>(body, m_JsonSerializerSettings);
if (!newSubscriptions.hasMore)
{ if (subscriptions?.list is null)
break; break;
}
getParams["offset"] = subscriptions.list.Count.ToString(); foreach (Subscriptions.List item in subscriptions.list)
} {
if (users.ContainsKey(item.username))
continue;
bool isRestricted = item.isRestricted ?? false;
bool isRestrictedButAllowed = isRestricted && includeRestricted;
if (!isRestricted || isRestrictedButAllowed)
users.Add(item.username, item.id);
} }
foreach (Subscriptions.List subscription in subscriptions.list) if (!subscriptions.hasMore)
{ break;
if ((!(subscription.isRestricted ?? false) || ((subscription.isRestricted ?? false) && includeRestricted))
&& !users.ContainsKey(subscription.username)) offset += limit;
{ getParams["offset"] = offset.ToString();
users.Add(subscription.username, subscription.id);
}
} }
return users; return users;
@ -361,12 +374,12 @@ public class APIHelper : IAPIHelper
{ {
Dictionary<string, string> getParams = new() Dictionary<string, string> getParams = new()
{ {
{ "offset", "0" },
{ "limit", "50" },
{ "type", "active" }, { "type", "active" },
{ "format", "infinite"} { "format", "infinite"}
}; };
Log.Debug("Calling GetActiveSubscriptions");
return await GetAllSubscriptions(getParams, endpoint, includeRestricted, config); return await GetAllSubscriptions(getParams, endpoint, includeRestricted, config);
} }
@ -375,8 +388,6 @@ public class APIHelper : IAPIHelper
{ {
Dictionary<string, string> getParams = new() Dictionary<string, string> getParams = new()
{ {
{ "offset", "0" },
{ "limit", "50" },
{ "type", "expired" }, { "type", "expired" },
{ "format", "infinite"} { "format", "infinite"}
}; };
@ -390,8 +401,6 @@ public class APIHelper : IAPIHelper
{ {
Dictionary<string, string> getParams = new() Dictionary<string, string> getParams = new()
{ {
{ "offset", "0" },
{ "limit", "50" },
{ "type", "expired" }, { "type", "expired" },
{ "format", "infinite"} { "format", "infinite"}
}; };
@ -1163,7 +1172,7 @@ public class APIHelper : IAPIHelper
} }
break; break;
case VideoResolution._240: case VideoResolution._240:
if(medium.videoSources != null) if (medium.videoSources != null)
{ {
if (!string.IsNullOrEmpty(medium.videoSources._240)) if (!string.IsNullOrEmpty(medium.videoSources._240))
{ {

View File

@ -892,19 +892,15 @@ public class Program
{ {
const string OUTPUT_FILE = "blocked-users.json"; const string OUTPUT_FILE = "blocked-users.json";
Log.Debug($"Calling GetBlockedUsers");
AnsiConsole.Markup($"[red]Getting Blocked Users\n[/]");
Dictionary<string, int>? blockedUsers = await m_ApiHelper.GetBlockedUsers("/users/blocked", Config); Dictionary<string, int>? blockedUsers = await m_ApiHelper.GetBlockedUsers("/users/blocked", Config);
if (blockedUsers is null || blockedUsers.Count == 0) if (blockedUsers is null || blockedUsers.Count == 0)
{ {
AnsiConsole.Markup($"[red]No Blocked Users found.\n[/]"); AnsiConsole.Markup($"[green]No Blocked Users found.\n[/]");
} }
else else
{ {
AnsiConsole.Markup($"[red]Found {blockedUsers.Count} Blocked Users, saving to '{OUTPUT_FILE}'\n[/]"); AnsiConsole.Markup($"[green]Found {blockedUsers.Count} Blocked Users, saving to '{OUTPUT_FILE}'\n[/]");
string json = JsonConvert.SerializeObject(blockedUsers, Formatting.Indented); string json = JsonConvert.SerializeObject(blockedUsers, Formatting.Indented);
await File.WriteAllTextAsync(OUTPUT_FILE, json); await File.WriteAllTextAsync(OUTPUT_FILE, json);
} }
@ -920,11 +916,12 @@ public class Program
{ {
DateTime startTime = DateTime.Now; DateTime startTime = DateTime.Now;
Dictionary<string, int> users = new(); Dictionary<string, int> users = new();
Dictionary<string, int> activeSubs = await m_ApiHelper.GetActiveSubscriptions("/subscriptions/subscribes", Config.IncludeRestrictedSubscriptions, Config);
AnsiConsole.Markup($"[green]Getting Active Subscriptions (Include Restricted: {Config.IncludeRestrictedSubscriptions})\n[/]");
Dictionary<string, int> subsActive = await m_ApiHelper.GetActiveSubscriptions("/subscriptions/subscribes", Config.IncludeRestrictedSubscriptions, Config) ?? [];
Log.Debug("Subscriptions: "); Log.Debug("Subscriptions: ");
foreach (KeyValuePair<string, int> activeSub in subsActive)
foreach (KeyValuePair<string, int> activeSub in activeSubs)
{ {
if (!users.ContainsKey(activeSub.Key)) if (!users.ContainsKey(activeSub.Key))
{ {
@ -932,12 +929,15 @@ public class Program
Log.Debug($"Name: {activeSub.Key} ID: {activeSub.Value}"); Log.Debug($"Name: {activeSub.Key} ID: {activeSub.Value}");
} }
} }
if (Config!.IncludeExpiredSubscriptions) if (Config!.IncludeExpiredSubscriptions)
{ {
Log.Debug("Inactive Subscriptions: "); Log.Debug("Inactive Subscriptions: ");
Dictionary<string, int> expiredSubs = await m_ApiHelper.GetExpiredSubscriptions("/subscriptions/subscribes", Config.IncludeRestrictedSubscriptions, Config); AnsiConsole.Markup($"[green]Getting Expired Subscriptions (Include Restricted: {Config.IncludeRestrictedSubscriptions})\n[/]");
foreach (KeyValuePair<string, int> expiredSub in expiredSubs) Dictionary<string, int> subsExpired = await m_ApiHelper.GetExpiredSubscriptions("/subscriptions/subscribes", Config.IncludeRestrictedSubscriptions, Config) ?? [];
foreach (KeyValuePair<string, int> expiredSub in subsExpired)
{ {
if (!users.ContainsKey(expiredSub.Key)) if (!users.ContainsKey(expiredSub.Key))
{ {
@ -964,6 +964,9 @@ public class Program
} }
} }
if (users.Count <= 0)
throw new InvalidOperationException("No users found!");
await dBHelper.CreateUsersDB(users); await dBHelper.CreateUsersDB(users);
KeyValuePair<bool, Dictionary<string, int>> hasSelectedUsersKVP; KeyValuePair<bool, Dictionary<string, int>> hasSelectedUsersKVP;
if(Config.NonInteractiveMode && Config.NonInteractiveModePurchasedTab) if(Config.NonInteractiveMode && Config.NonInteractiveModePurchasedTab)