Files
Swarm/DysonNetwork.Common/Clients/FileServiceClient.cs

117 lines
4.6 KiB
C#

using System;
using System.IO;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
using DysonNetwork.Common.Interfaces;
using DysonNetwork.Common.Models;
using Microsoft.Extensions.Logging;
using NodaTime;
using NodaTime.Serialization.SystemTextJson;
namespace DysonNetwork.Common.Clients
{
public class FileServiceClient : IFileServiceClient, IDisposable
{
private readonly HttpClient _httpClient;
private readonly ILogger<FileServiceClient> _logger;
private readonly JsonSerializerOptions _jsonOptions;
public FileServiceClient(HttpClient httpClient, ILogger<FileServiceClient> logger)
{
_httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_jsonOptions = new JsonSerializerOptions().ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
_jsonOptions.PropertyNameCaseInsensitive = true;
}
public async Task<CloudFile> GetFileAsync(string fileId)
{
var response = await _httpClient.GetAsync($"api/files/{fileId}");
response.EnsureSuccessStatusCode();
await using var stream = await response.Content.ReadAsStreamAsync();
var file = await JsonSerializer.DeserializeAsync<CloudFile>(stream, _jsonOptions);
return file;
}
public async Task<Stream> GetFileStreamAsync(string fileId)
{
if (string.IsNullOrEmpty(fileId))
throw new ArgumentNullException(nameof(fileId));
var response = await _httpClient.GetAsync($"api/files/{fileId}/download");
response.EnsureSuccessStatusCode();
var stream = await response.Content.ReadAsStreamAsync();
if (stream == null)
throw new InvalidOperationException("Failed to read file stream from response.");
return stream;
}
public async Task<CloudFile> UploadFileAsync(Stream fileStream, string fileName, string? contentType = null)
{
using var content = new MultipartFormDataContent();
var fileContent = new StreamContent(fileStream);
if (!string.IsNullOrEmpty(contentType))
{
fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
}
content.Add(fileContent, "file", fileName);
var response = await _httpClient.PostAsync("api/files/upload", content);
response.EnsureSuccessStatusCode();
await using var responseStream = await response.Content.ReadAsStreamAsync();
var file = await JsonSerializer.DeserializeAsync<CloudFile>(responseStream, _jsonOptions);
return file;
}
public async Task<CloudFile> ProcessImageAsync(Stream imageStream, string fileName, string? contentType = null)
{
using var content = new MultipartFormDataContent();
var fileContent = new StreamContent(imageStream);
if (!string.IsNullOrEmpty(contentType))
{
fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
}
content.Add(fileContent, "image", fileName);
var response = await _httpClient.PostAsync("api/files/process-image", content);
response.EnsureSuccessStatusCode();
await using var responseStream = await response.Content.ReadAsStreamAsync();
var file = await JsonSerializer.DeserializeAsync<CloudFile>(responseStream, _jsonOptions);
return file;
}
public async Task<string> GetFileUrl(string fileId, bool useCdn = false)
{
var url = $"api/files/{fileId}/url";
if (useCdn)
{
url += "?useCdn=true";
}
var response = await _httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadAsStringAsync();
return result.Trim('"');
}
public async Task DeleteFileAsync(string fileId)
{
var response = await _httpClient.DeleteAsync($"api/files/{fileId}");
response.EnsureSuccessStatusCode();
}
public void Dispose()
{
_httpClient?.Dispose();
GC.SuppressFinalize(this);
}
}
}