forked from sim0n00ps/OF-DL
301 lines
10 KiB
C#
301 lines
10 KiB
C#
namespace OF_DL.Services;
|
|
|
|
public class CajetanApiService(IAuthService authService, IConfigService configService, ICajetanDbService dbService, ICajetanDownloadEventHandler eventHandler)
|
|
: ApiService(authService, configService, dbService), ICajetanApiService
|
|
{
|
|
private readonly ICajetanDownloadEventHandler _eventHandler = eventHandler;
|
|
|
|
public new async Task<UserEntities.User?> GetUserInfo(string endpoint)
|
|
{
|
|
UserEntities.UserInfo? userInfo = await GetDetailedUserInfoAsync(endpoint);
|
|
|
|
if (userInfo is not null && !endpoint.EndsWith("/me"))
|
|
await dbService.UpdateUserInfoAsync(userInfo);
|
|
|
|
return userInfo;
|
|
}
|
|
|
|
public async Task<UserEntities.UserInfo?> GetDetailedUserInfoAsync(string endpoint)
|
|
{
|
|
Log.Debug($"Calling GetDetailedUserInfo: {endpoint}");
|
|
|
|
if (!HasSignedRequestAuth())
|
|
return null;
|
|
|
|
try
|
|
{
|
|
UserEntities.UserInfo userInfo = new();
|
|
Dictionary<string, string> getParams = new()
|
|
{
|
|
{ "limit", Constants.ApiPageSize.ToString() }, { "order", "publish_date_asc" }
|
|
};
|
|
|
|
HttpClient client = new();
|
|
HttpRequestMessage request = await BuildHttpRequestMessage(getParams, endpoint);
|
|
|
|
using HttpResponseMessage response = await client.SendAsync(request);
|
|
|
|
if (!response.IsSuccessStatusCode)
|
|
return userInfo;
|
|
|
|
response.EnsureSuccessStatusCode();
|
|
string body = await response.Content.ReadAsStringAsync();
|
|
UserDtos.UserDto? userDto = JsonConvert.DeserializeObject<UserDtos.UserDto>(body, s_mJsonSerializerSettings);
|
|
userInfo = FromDto(userDto);
|
|
return userInfo;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ExceptionLoggerHelper.LogException(ex);
|
|
}
|
|
|
|
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);
|
|
|
|
_eventHandler.OnMessage("Getting Unread Chats", "grey");
|
|
HashSet<long> usersWithUnread = couldExtract ? await GetUsersWithUnreadMessagesAsync() : [];
|
|
|
|
MessageEntities.MessageCollection messages = await base.GetMessages(endpoint, folder, statusReporter);
|
|
|
|
if (usersWithUnread.Contains(userId))
|
|
{
|
|
_eventHandler.OnMessage("Restoring unread state", "grey");
|
|
await MarkAsUnreadAsync($"/chats/{userId}/mark-as-read");
|
|
}
|
|
|
|
return messages;
|
|
|
|
static (bool couldExtract, long userId) ExtractUserId(string endpoint)
|
|
{
|
|
string withoutChatsAndMessages = endpoint
|
|
.Replace("chats", "", StringComparison.OrdinalIgnoreCase)
|
|
.Replace("messages", "", StringComparison.OrdinalIgnoreCase);
|
|
string trimmed = withoutChatsAndMessages.Trim(' ', '/', '\\');
|
|
|
|
if (long.TryParse(trimmed, out long userId))
|
|
return (true, userId);
|
|
|
|
return (false, default);
|
|
}
|
|
}
|
|
|
|
public async Task<HashSet<long>> GetUsersWithUnreadMessagesAsync()
|
|
{
|
|
MessageDtos.ChatsDto unreadChats = await GetChatsAsync("/chats", onlyUnread: true);
|
|
HashSet<long> userWithUnread = [];
|
|
|
|
foreach (MessageDtos.ChatItemDto chatItem in unreadChats.List)
|
|
{
|
|
if (chatItem?.WithUser?.Id is null)
|
|
continue;
|
|
|
|
if (chatItem.UnreadMessagesCount <= 0)
|
|
continue;
|
|
|
|
userWithUnread.Add(chatItem.WithUser.Id);
|
|
}
|
|
|
|
return userWithUnread;
|
|
}
|
|
|
|
public async Task MarkAsUnreadAsync(string endpoint)
|
|
{
|
|
Log.Debug($"Calling MarkAsUnread - {endpoint}");
|
|
|
|
try
|
|
{
|
|
var result = new { success = false };
|
|
|
|
string? body = await BuildHeaderAndExecuteRequests([], endpoint, GetHttpClient(), HttpMethod.Delete);
|
|
|
|
if (!string.IsNullOrWhiteSpace(body))
|
|
result = JsonConvert.DeserializeAnonymousType(body, result);
|
|
|
|
if (result?.success != true)
|
|
_eventHandler.OnMessage($"Failed to mark chat as unread! Endpoint: {endpoint}", "yellow");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ExceptionLoggerHelper.LogException(ex);
|
|
}
|
|
}
|
|
|
|
private async Task<MessageDtos.ChatsDto> GetChatsAsync(string endpoint, bool onlyUnread)
|
|
{
|
|
Log.Debug($"Calling GetChats - {endpoint}");
|
|
|
|
MessageDtos.ChatsDto allChats = new();
|
|
|
|
try
|
|
{
|
|
const int limit = 60;
|
|
int offset = 0;
|
|
|
|
Dictionary<string, string> getParams = new()
|
|
{
|
|
["order"] = "recent",
|
|
["skip_users"] = "all",
|
|
["filter"] = "unread",
|
|
["limit"] = $"{limit}",
|
|
};
|
|
|
|
if (onlyUnread is false)
|
|
getParams.Remove("filter");
|
|
|
|
while (true)
|
|
{
|
|
getParams["offset"] = $"{offset}";
|
|
|
|
string? body = await BuildHeaderAndExecuteRequests(getParams, endpoint, GetHttpClient());
|
|
|
|
if (string.IsNullOrWhiteSpace(body))
|
|
break;
|
|
|
|
MessageDtos.ChatsDto? chats = DeserializeJson<MessageDtos.ChatsDto>(body, s_mJsonSerializerSettings);
|
|
|
|
if (chats?.List is null)
|
|
break;
|
|
|
|
allChats.List.AddRange(chats.List);
|
|
|
|
if (chats.HasMore is false)
|
|
break;
|
|
|
|
offset = chats.NextOffset;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ExceptionLoggerHelper.LogException(ex);
|
|
}
|
|
|
|
return allChats;
|
|
}
|
|
|
|
private static UserEntities.UserInfo FromDto(UserDtos.UserDto? userDto)
|
|
{
|
|
if (userDto is null)
|
|
return new();
|
|
|
|
return new()
|
|
{
|
|
Id = userDto.Id,
|
|
|
|
Avatar = userDto.Avatar,
|
|
Header = userDto.Header,
|
|
Name = userDto.Name,
|
|
Username = userDto.Username,
|
|
|
|
SubscribePrice = userDto.SubscribePrice,
|
|
CurrentSubscribePrice = userDto.CurrentSubscribePrice,
|
|
IsPaywallRequired = userDto.IsPaywallRequired,
|
|
IsRestricted = userDto.IsRestricted,
|
|
SubscribedBy = userDto.SubscribedBy,
|
|
SubscribedByExpire = userDto.SubscribedByExpire,
|
|
SubscribedByExpireDate = userDto.SubscribedByExpireDate,
|
|
SubscribedByAutoprolong = userDto.SubscribedByAutoprolong,
|
|
SubscribedIsExpiredNow = userDto.SubscribedIsExpiredNow,
|
|
SubscribedOn = userDto.SubscribedOn,
|
|
SubscribedOnExpiredNow = userDto.SubscribedOnExpiredNow,
|
|
SubscribedOnDuration = userDto.SubscribedOnDuration,
|
|
About = userDto.About,
|
|
PostsCount = userDto.PostsCount,
|
|
ArchivedPostsCount = userDto.ArchivedPostsCount,
|
|
PrivateArchivedPostsCount = userDto.PrivateArchivedPostsCount,
|
|
PhotosCount = userDto.PhotosCount,
|
|
VideosCount = userDto.VideosCount,
|
|
AudiosCount = userDto.AudiosCount,
|
|
MediasCount = userDto.MediasCount,
|
|
};
|
|
}
|
|
}
|