mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
85 lines
3.6 KiB
C#
85 lines
3.6 KiB
C#
using System.IO.Compression;
|
|
using System.Net.Http.Headers;
|
|
using Artemis.Core;
|
|
using Artemis.UI.Shared.Utilities;
|
|
using Artemis.WebClient.Workshop.Entities;
|
|
using Artemis.WebClient.Workshop.Exceptions;
|
|
using Newtonsoft.Json;
|
|
using RGB.NET.Layout;
|
|
|
|
namespace Artemis.WebClient.Workshop.Handlers.UploadHandlers;
|
|
|
|
public class LayoutEntryUploadHandler : IEntryUploadHandler
|
|
{
|
|
private readonly IHttpClientFactory _httpClientFactory;
|
|
|
|
public LayoutEntryUploadHandler(IHttpClientFactory httpClientFactory)
|
|
{
|
|
_httpClientFactory = httpClientFactory;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<EntryUploadResult> CreateReleaseAsync(long entryId, IEntrySource entrySource, CancellationToken cancellationToken)
|
|
{
|
|
if (entrySource is not LayoutEntrySource source)
|
|
throw new InvalidOperationException("Can only create releases for layouts");
|
|
|
|
using MemoryStream archiveStream = new();
|
|
using MemoryStream layoutStream = new();
|
|
|
|
source.Layout.RgbLayout.Save(layoutStream);
|
|
layoutStream.Seek(0, SeekOrigin.Begin);
|
|
|
|
// Create an archive
|
|
string? layoutPath = Path.GetDirectoryName(source.Layout.FilePath);
|
|
if (layoutPath == null)
|
|
throw new ArtemisWorkshopException($"Could not determine directory of {source.Layout.FilePath}");
|
|
|
|
using (ZipArchive archive = new(archiveStream, ZipArchiveMode.Create, true))
|
|
{
|
|
// Add the layout to the archive
|
|
ZipArchiveEntry archiveEntry = archive.CreateEntry("layout.xml");
|
|
await using (Stream layoutArchiveStream = archiveEntry.Open())
|
|
await layoutStream.CopyToAsync(layoutArchiveStream, cancellationToken);
|
|
|
|
// Add the layout image to the archive
|
|
CopyImage(layoutPath, source.Layout.LayoutCustomDeviceData.DeviceImage, archive);
|
|
|
|
// Add the LED images to the archive
|
|
foreach (ArtemisLedLayout ledLayout in source.Layout.Leds)
|
|
{
|
|
if (ledLayout.LayoutCustomLedData.LogicalLayouts == null)
|
|
continue;
|
|
foreach (LayoutCustomLedDataLogicalLayout customData in ledLayout.LayoutCustomLedData.LogicalLayouts)
|
|
CopyImage(layoutPath, customData.Image, archive);
|
|
}
|
|
}
|
|
archiveStream.Seek(0, SeekOrigin.Begin);
|
|
|
|
// Submit the archive
|
|
HttpClient client = _httpClientFactory.CreateClient(WorkshopConstants.WORKSHOP_CLIENT_NAME);
|
|
|
|
// Construct the request
|
|
MultipartFormDataContent content = new();
|
|
StreamContent streamContent = new(archiveStream);
|
|
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/zip");
|
|
content.Add(streamContent, "file", "file.zip");
|
|
|
|
// Submit
|
|
HttpResponseMessage response = await client.PostAsync("releases/upload/" + entryId, content, cancellationToken);
|
|
if (!response.IsSuccessStatusCode)
|
|
return EntryUploadResult.FromFailure($"{response.StatusCode} - {await response.Content.ReadAsStringAsync(cancellationToken)}");
|
|
|
|
Release? release = JsonConvert.DeserializeObject<Release>(await response.Content.ReadAsStringAsync(cancellationToken));
|
|
return release != null ? EntryUploadResult.FromSuccess(release) : EntryUploadResult.FromFailure("Failed to deserialize response");
|
|
}
|
|
|
|
private static void CopyImage(string layoutPath, string? imagePath, ZipArchive archive)
|
|
{
|
|
if (imagePath == null)
|
|
return;
|
|
|
|
string fullPath = Path.Combine(layoutPath, imagePath);
|
|
archive.CreateEntryFromFile(fullPath, imagePath);
|
|
}
|
|
} |