forked from sim0n00ps/OF-DL
Compare commits
3 Commits
ab0de376c9
...
d7fd5faedd
| Author | SHA1 | Date | |
|---|---|---|---|
| d7fd5faedd | |||
| cdfe83b8dd | |||
| 6a9c48bf3e |
@ -1,4 +1,5 @@
|
||||
global using Newtonsoft.Json;
|
||||
global using Serilog;
|
||||
global using Spectre.Console;
|
||||
global using OF_DL;
|
||||
global using OF_DL.CLI;
|
||||
global using OF_DL.Enumerations;
|
||||
@ -6,13 +7,5 @@ global using OF_DL.Exceptions;
|
||||
global using OF_DL.Helpers;
|
||||
global using OF_DL.Models;
|
||||
global using OF_DL.Models.Config;
|
||||
global using OF_DL.Models.Downloads;
|
||||
global using OF_DL.Services;
|
||||
global using Serilog;
|
||||
global using Serilog.Context;
|
||||
global using Spectre.Console;
|
||||
global using MessageDtos = OF_DL.Models.Dtos.Messages;
|
||||
global using MessageEntities = OF_DL.Models.Entities.Messages;
|
||||
global using SubscriptionDtos = OF_DL.Models.Dtos.Subscriptions;
|
||||
global using UserDtos = OF_DL.Models.Dtos.Users;
|
||||
global using UserEntities = OF_DL.Models.Entities.Users;
|
||||
global using Newtonsoft.Json;
|
||||
|
||||
@ -1,3 +1,8 @@
|
||||
using MessageDtos = OF_DL.Models.Dtos.Messages;
|
||||
using MessageEntities = OF_DL.Models.Entities.Messages;
|
||||
using UserDtos = OF_DL.Models.Dtos.Users;
|
||||
using UserEntities = OF_DL.Models.Entities.Users;
|
||||
|
||||
namespace OF_DL.Services;
|
||||
|
||||
public class CajetanApiService(IAuthService authService, IConfigService configService, ICajetanDbService dbService, ICajetanDownloadEventHandler eventHandler)
|
||||
@ -7,7 +12,7 @@ public class CajetanApiService(IAuthService authService, IConfigService configSe
|
||||
|
||||
public new async Task<UserEntities.User?> GetUserInfo(string endpoint)
|
||||
{
|
||||
UserEntities.UserInfo? userInfo = await GetDetailedUserInfoAsync(endpoint);
|
||||
UserEntities.UserInfo? userInfo = await GetDetailedUserInfo(endpoint);
|
||||
|
||||
if (userInfo is not null && !endpoint.EndsWith("/me"))
|
||||
await dbService.UpdateUserInfoAsync(userInfo);
|
||||
@ -15,7 +20,7 @@ public class CajetanApiService(IAuthService authService, IConfigService configSe
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
public async Task<UserEntities.UserInfo?> GetDetailedUserInfoAsync(string endpoint)
|
||||
public async Task<UserEntities.UserInfo?> GetDetailedUserInfo(string endpoint)
|
||||
{
|
||||
Log.Debug($"Calling GetDetailedUserInfo: {endpoint}");
|
||||
|
||||
@ -52,91 +57,6 @@ public class CajetanApiService(IAuthService authService, IConfigService configSe
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<Dictionary<string, long>> GetUsersWithProgressAsync(string typeDisplay, string endpoint, string? typeParam, bool offsetByCount)
|
||||
{
|
||||
Dictionary<string, long> usersOfType = await _eventHandler.WithStatusAsync(
|
||||
statusMessage: $"Getting {typeDisplay} Users",
|
||||
work: FetchAsync
|
||||
);
|
||||
|
||||
return usersOfType;
|
||||
|
||||
async Task<Dictionary<string, long>> FetchAsync(IStatusReporter statusReporter)
|
||||
{
|
||||
Dictionary<string, long> users = [];
|
||||
|
||||
int limit = 50;
|
||||
int offset = 0;
|
||||
bool includeRestricted = true;
|
||||
|
||||
Dictionary<string, string> getParams = new()
|
||||
{
|
||||
["format"] = "infinite",
|
||||
["limit"] = limit.ToString(),
|
||||
["offset"] = offset.ToString()
|
||||
};
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(typeParam))
|
||||
getParams["type"] = typeParam;
|
||||
|
||||
try
|
||||
{
|
||||
Log.Debug("Calling GetUsersWithProgress");
|
||||
|
||||
HttpClient client = GetHttpClient();
|
||||
|
||||
bool isLastLoop = false;
|
||||
while (true)
|
||||
{
|
||||
string? body = await BuildHeaderAndExecuteRequests(getParams, endpoint, client);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(body))
|
||||
break;
|
||||
|
||||
SubscriptionDtos.SubscriptionsDto? subscriptions = DeserializeJson<SubscriptionDtos.SubscriptionsDto>(body, s_mJsonSerializerSettings);
|
||||
|
||||
if (subscriptions?.List is null)
|
||||
break;
|
||||
|
||||
foreach (SubscriptionDtos.ListItemDto item in subscriptions.List)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(item?.Username))
|
||||
continue;
|
||||
|
||||
if (users.ContainsKey(item.Username))
|
||||
continue;
|
||||
|
||||
bool isRestricted = item.IsRestricted ?? false;
|
||||
bool isRestrictedButAllowed = isRestricted && includeRestricted;
|
||||
|
||||
if (!isRestricted || isRestrictedButAllowed)
|
||||
users.Add(item.Username, item.Id);
|
||||
}
|
||||
|
||||
statusReporter.ReportStatus($"[blue]Getting {typeDisplay} Users\n[/] [blue]Found {users.Count}[/]");
|
||||
|
||||
if (isLastLoop)
|
||||
break;
|
||||
|
||||
if (!subscriptions.HasMore || subscriptions.List.Count == 0)
|
||||
isLastLoop = true;
|
||||
|
||||
offset += offsetByCount
|
||||
? subscriptions.List.Count
|
||||
: limit;
|
||||
|
||||
getParams["offset"] = offset.ToString();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ExceptionLoggerHelper.LogException(ex);
|
||||
}
|
||||
|
||||
return users;
|
||||
}
|
||||
}
|
||||
|
||||
public new async Task<MessageEntities.MessageCollection> GetMessages(string endpoint, string folder, IStatusReporter statusReporter)
|
||||
{
|
||||
(bool couldExtract, long userId) = ExtractUserId(endpoint);
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Microsoft.Data.Sqlite;
|
||||
using OF_DL.Models.Entities.Users;
|
||||
|
||||
namespace OF_DL.Services;
|
||||
|
||||
@ -42,7 +43,7 @@ public class CajetanDbService(IConfigService configService)
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task UpdateUserInfoAsync(UserEntities.UserInfo? userInfo)
|
||||
public async Task UpdateUserInfoAsync(UserInfo? userInfo)
|
||||
{
|
||||
if (userInfo?.Id is null || userInfo?.Username is null)
|
||||
return;
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
using UserEntities = OF_DL.Models.Entities.Users;
|
||||
|
||||
namespace OF_DL.Services;
|
||||
|
||||
public interface ICajetanApiService : IApiService
|
||||
{
|
||||
Task<UserEntities.UserInfo?> GetDetailedUserInfoAsync(string endpoint);
|
||||
Task<Dictionary<string, long>> GetUsersWithProgressAsync(string typeDisplay, string endpoint, string? typeParam, bool offsetByCount);
|
||||
Task<UserEntities.UserInfo?> GetDetailedUserInfo(string endpoint);
|
||||
|
||||
Task<HashSet<long>> GetUsersWithUnreadMessagesAsync();
|
||||
Task MarkAsUnreadAsync(string endpoint);
|
||||
}
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
|
||||
using OF_DL.Models.Entities.Users;
|
||||
|
||||
namespace OF_DL.Services;
|
||||
|
||||
public interface ICajetanDbService : IDbService
|
||||
@ -5,5 +8,5 @@ public interface ICajetanDbService : IDbService
|
||||
Task InitializeUserInfoTablesAsync();
|
||||
|
||||
Task<Dictionary<string, long>> GetUsersAsync();
|
||||
Task UpdateUserInfoAsync(UserEntities.UserInfo? userInfo);
|
||||
Task UpdateUserInfoAsync(UserInfo? userInfo);
|
||||
}
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using OF_DL.Models.Downloads;
|
||||
using OF_DL.Models.Entities.Users;
|
||||
|
||||
namespace OF_DL;
|
||||
|
||||
@ -113,7 +115,7 @@ internal class Worker(IServiceProvider serviceProvider)
|
||||
// Validate cookie string
|
||||
_authService.ValidateCookieString();
|
||||
|
||||
UserEntities.User? user = await _authService.ValidateAuthAsync();
|
||||
User? user = await _authService.ValidateAuthAsync();
|
||||
if (user is null || (user.Name is null && user.Username is null))
|
||||
{
|
||||
Log.Error("Auth failed");
|
||||
@ -225,88 +227,12 @@ internal class Worker(IServiceProvider serviceProvider)
|
||||
|
||||
private async Task OutputBlockedUsersAsync()
|
||||
{
|
||||
const string OUTPUT_FILE_BLOCKED = "blocked-users.json";
|
||||
const string OUTPUT_FILE_EXPIRED = "expired-users.json";
|
||||
|
||||
await GetUsersAsync("Blocked", "/users/blocked", OUTPUT_FILE_BLOCKED);
|
||||
await GetUsersAsync("Expired", "/subscriptions/subscribes", OUTPUT_FILE_EXPIRED, typeParam: "expired", offsetByCount: false);
|
||||
|
||||
async Task GetUsersAsync(string typeDisplay, string uri, string outputFile, string? typeParam = null, bool offsetByCount = true)
|
||||
{
|
||||
Dictionary<string, long> users = await _apiService.GetUsersWithProgressAsync(typeDisplay, uri, typeParam, offsetByCount);
|
||||
|
||||
Console.WriteLine();
|
||||
|
||||
if (users is null || users.Count == 0)
|
||||
{
|
||||
AnsiConsole.Markup($"[green]No {typeDisplay} Users found.\n[/]");
|
||||
}
|
||||
else
|
||||
{
|
||||
AnsiConsole.Markup($"[green]Found {users.Count} {typeDisplay} Users, saving to '{outputFile}'\n[/]");
|
||||
string json = JsonConvert.SerializeObject(users, Formatting.Indented);
|
||||
await File.WriteAllTextAsync(outputFile, json);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task UpdateUserInfoAsync()
|
||||
{
|
||||
await _dbService.CreateUsersDb([]);
|
||||
await _dbService.InitializeUserInfoTablesAsync();
|
||||
|
||||
Dictionary<string, long> users = await _dbService.GetUsersAsync();
|
||||
Console.WriteLine();
|
||||
|
||||
Log.Information("Updating User Info for '{UserCount}' users", users.Count);
|
||||
AnsiConsole.Markup($"[green]Updating User Info for '{users.Count}' users\n[/]");
|
||||
|
||||
await AnsiConsole.Progress()
|
||||
.Columns(new ProgressBarColumn(), new PercentageColumn(), new TaskDescriptionColumn { Alignment = Justify.Left })
|
||||
.StartAsync(RunUpdateAsync);
|
||||
|
||||
async Task RunUpdateAsync(ProgressContext context)
|
||||
{
|
||||
ProgressTask? updateTask = null;
|
||||
|
||||
int maxUsernameLength = users.Keys.Max(s => s.Length);
|
||||
|
||||
foreach ((string username, long userId) in users)
|
||||
{
|
||||
string description = $"Updating '{username}'".PadRight(11 + maxUsernameLength);
|
||||
double prevValue = updateTask?.Value ?? 0;
|
||||
|
||||
updateTask = context.AddTask(description, true, users.Count);
|
||||
updateTask.Value = prevValue;
|
||||
|
||||
using (LogContext.PushProperty("Username", username))
|
||||
using (LogContext.PushProperty("UserId", userId))
|
||||
using (LogContext.PushProperty("UserNum", prevValue + 1))
|
||||
using (LogContext.PushProperty("UserTotal", users.Count))
|
||||
{
|
||||
try
|
||||
{
|
||||
Log.Information("[{UserNum:0} of {UserTotal}] Updating User Info for for: {Username:l}");
|
||||
UserEntities.UserInfo? userInfo = await _apiService.GetDetailedUserInfoAsync($"/users/{username}");
|
||||
await _dbService.UpdateUserInfoAsync(userInfo);
|
||||
|
||||
updateTask.Description = $"{description} - COMPLETE";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Warning(ex, "[{UserNum:0} of {UserTotal}] Failed to update User Info for: {Username:l}");
|
||||
AnsiConsole.Markup($"[red]Failed to update User Info for '{username}'\n[/]");
|
||||
|
||||
updateTask.Description = $"{description} - FAILED: {ex.Message}";
|
||||
}
|
||||
finally
|
||||
{
|
||||
updateTask.Increment(1);
|
||||
updateTask.StopTask();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<Dictionary<string, long>> GetUsersFromSpecificListsAsync(UserListResult allUsersAndLists, string[] listNames)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user