using System.Text; using System.Text.Json; using System.Web; using MetaforceInstaller.Cloud.Implementations.MailRu.DTO; using MetaforceInstaller.Cloud.Models; namespace MetaforceInstaller.Cloud.Implementations.MailRu; public class MailRuCloudService : ICloudService { private const string BaseUrl = "https://cloud.mail.ru"; private static readonly JsonSerializerOptions JsonOptions = new() { PropertyNameCaseInsensitive = true }; private readonly HttpClient _httpClient; public MailRuCloudService(HttpClient httpClient) { _httpClient = httpClient; } public async Task> GetObjects(string webLink) { var dto = await GetFromPublicApi( path: "/api/v4/public/list", query: new Dictionary { ["weblink"] = webLink, ["sort"] = "name", ["order"] = "asc", ["offset"] = "0", ["limit"] = "500", ["version"] = "4" }).ConfigureAwait(false); if (dto?.List is null || dto.List.Count == 0) return []; var result = new List(dto.List.Count); foreach (var entry in dto.List) result.Add(Map(entry)); return result; } public async Task GetDownloadLink(IEnumerable webLinks, string outputFileName = "archive") { var result = await PostToPublicApi( path: "/api/v3/zip/weblink", query: new Dictionary(), new ZipWebLinkRequest { XEmail = "anonym", WeblinkList = webLinks.ToList(), Name = outputFileName } ); return result?.Key; } private async Task GetFromPublicApi(string path, IReadOnlyDictionary query) { var uri = BuildUri(path, query); using var response = await _httpClient.GetAsync(uri).ConfigureAwait(false); response.EnsureSuccessStatusCode(); var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false); return JsonSerializer.Deserialize(json, JsonOptions); } private async Task PostToPublicApi(string path, IReadOnlyDictionary query, object body) { var uri = BuildUri(path, query); var jsonBody = JsonSerializer.Serialize(body, JsonOptions); using var content = new StringContent(jsonBody, Encoding.UTF8, "application/json"); using var response = await _httpClient.PostAsync(uri, content).ConfigureAwait(false); response.EnsureSuccessStatusCode(); var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false); return JsonSerializer.Deserialize(json, JsonOptions); } private static Uri BuildUri(string path, IReadOnlyDictionary query) { var builder = new UriBuilder(BaseUrl) { Port = -1, Path = path }; var qs = HttpUtility.ParseQueryString(builder.Query); foreach (var (key, value) in query) qs[key] = value; builder.Query = qs.ToString(); return builder.Uri; } private static CloudObject Map(CloudObjectBase entry) { return new CloudObject { Name = entry.Name, WebLink = entry.WebLink, Type = entry.Type == "folder" ? CloudObjectType.Folder : CloudObjectType.File }; } }