start testing cloud service implementation

This commit is contained in:
Вячеслав 2026-02-03 01:54:19 +05:00
parent 3c08d93bc5
commit 2c3f19d7ce
5 changed files with 328 additions and 0 deletions

View file

@ -0,0 +1,116 @@
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<List<CloudObject>> GetObjects(string webLink)
{
var dto = await GetFromPublicApi<CloudObjectsResponse>(
path: "/api/v4/public/list",
query: new Dictionary<string, string?>
{
["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<CloudObject>(dto.List.Count);
foreach (var entry in dto.List)
result.Add(Map(entry));
return result;
}
public async Task<string?> GetDownloadLink(IEnumerable<string> webLinks, string outputFileName = "archive")
{
var result = await PostToPublicApi<ZipWebLinkResponse>(
path: "/api/v3/zip/weblink",
query: new Dictionary<string, string?>(),
new ZipWebLinkRequest
{
XEmail = "anonym",
WeblinkList = webLinks.ToList(),
Name = outputFileName
}
);
return result?.Key;
}
private async Task<TResponse?> GetFromPublicApi<TResponse>(string path, IReadOnlyDictionary<string, string?> 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<TResponse>(json, JsonOptions);
}
private async Task<TResponse?> PostToPublicApi<TResponse>(string path, IReadOnlyDictionary<string, string?> 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<TResponse>(json, JsonOptions);
}
private static Uri BuildUri(string path, IReadOnlyDictionary<string, string?> 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
};
}
}