Add seed-fetching service
This commit is contained in:
57
ALttPRandomizer/Azure/AzureStorage.cs
Normal file
57
ALttPRandomizer/Azure/AzureStorage.cs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
namespace ALttPRandomizer.Azure {
|
||||||
|
using global::Azure.Storage.Blobs;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
public class AzureStorage {
|
||||||
|
public AzureStorage(BlobContainerClient blobClient, ILogger<AzureStorage> logger) {
|
||||||
|
this.BlobClient = blobClient;
|
||||||
|
this.Logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ILogger<AzureStorage> Logger { get; }
|
||||||
|
private BlobContainerClient BlobClient { get; }
|
||||||
|
|
||||||
|
public async Task UploadFile(string name, Stream data) {
|
||||||
|
await BlobClient.UploadBlobAsync(name, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UploadFileAndDelete(string name, string filepath) {
|
||||||
|
using (var stream = new FileStream(filepath, FileMode.Open, FileAccess.Read)) {
|
||||||
|
this.Logger.LogDebug("Uploading file {filepath} -> {name}", filepath, name);
|
||||||
|
await this.UploadFile(name, stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Logger.LogDebug("Deleting file {filepath}", filepath);
|
||||||
|
File.Delete(filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Dictionary<string, BinaryData>> GetFiles(string seedId) {
|
||||||
|
var prefix = seedId + "/";
|
||||||
|
var blobs = this.BlobClient.GetBlobsAsync(prefix: prefix);
|
||||||
|
|
||||||
|
var data = new Dictionary<string, BinaryData>();
|
||||||
|
|
||||||
|
await foreach (var blob in blobs) {
|
||||||
|
var result = await this.BlobClient.GetBlobClient(blob.Name).DownloadContentAsync();
|
||||||
|
if (result.Value.Details.ContentLength == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!blob.Name.StartsWith(prefix)) {
|
||||||
|
this.Logger.LogWarning("Found prefix mismatch for seed id {seedId}, blob name {blobName}", seedId, blob.Name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var suffix = blob.Name.Substring(prefix.Length);
|
||||||
|
|
||||||
|
data[suffix] = result.Value.Content;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,19 +1,30 @@
|
|||||||
namespace ALttPRandomizer {
|
namespace ALttPRandomizer {
|
||||||
using ALttPRandomizer.Model;
|
using ALttPRandomizer.Model;
|
||||||
|
using ALttPRandomizer.Service;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
public class GenerateController : Controller {
|
public class GenerateController : Controller {
|
||||||
public GenerateController(Randomizer randomizer) {
|
public GenerateController(Randomizer randomizer, SeedService seedService) {
|
||||||
this.Randomizer = randomizer;
|
this.Randomizer = randomizer;
|
||||||
|
this.SeedService = seedService;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Randomizer Randomizer { get; }
|
private Randomizer Randomizer { get; }
|
||||||
|
private SeedService SeedService { get; }
|
||||||
|
|
||||||
[Route("/generate")]
|
[Route("/generate")]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public ActionResult Generate(SeedSettings settings) {
|
public ActionResult Generate(SeedSettings settings) {
|
||||||
var result = this.Randomizer.Randomize();
|
var result = this.Randomizer.Randomize();
|
||||||
return Content(result);
|
return Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Route("/seed/{id}")]
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<ActionResult> GetSeed(string id) {
|
||||||
|
var result = await this.SeedService.GetSeed(id);
|
||||||
|
return Ok(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
public class IdGenerator {
|
public class IdGenerator {
|
||||||
private const string chars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789";
|
private const string chars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789";
|
||||||
private const int length = 10;
|
private const int length = 10;
|
||||||
private static Random random = new Random();
|
private static readonly Random random = new Random();
|
||||||
|
|
||||||
public string GenerateId() {
|
public string GenerateId() {
|
||||||
var str = new char[length];
|
var str = new char[length];
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
namespace ALttPRandomizer
|
namespace ALttPRandomizer
|
||||||
{
|
{
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
using ALttPRandomizer.Azure;
|
||||||
using ALttPRandomizer.Options;
|
using ALttPRandomizer.Options;
|
||||||
using Azure.Identity;
|
using ALttPRandomizer.Service;
|
||||||
using Azure.Storage.Blobs;
|
using global::Azure.Identity;
|
||||||
|
using global::Azure.Storage.Blobs;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
@@ -36,8 +38,10 @@
|
|||||||
var seedClient = new BlobContainerClient(settings.AzureSettings.BlobstoreEndpoint, token);
|
var seedClient = new BlobContainerClient(settings.AzureSettings.BlobstoreEndpoint, token);
|
||||||
|
|
||||||
builder.Services.AddSingleton(seedClient);
|
builder.Services.AddSingleton(seedClient);
|
||||||
builder.Services.AddScoped<Randomizer, Randomizer>();
|
builder.Services.AddSingleton<AzureStorage>();
|
||||||
builder.Services.AddScoped<IdGenerator, IdGenerator>();
|
builder.Services.AddScoped<Randomizer>();
|
||||||
|
builder.Services.AddScoped<SeedService>();
|
||||||
|
builder.Services.AddScoped<IdGenerator>();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
|||||||
9
ALttPRandomizer/Properties/launchSettings.json
Normal file
9
ALttPRandomizer/Properties/launchSettings.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"profiles": {
|
||||||
|
"https": {
|
||||||
|
"applicationUrl": "localhost:5000/swagger",
|
||||||
|
"commandName": "Project",
|
||||||
|
"launchBrowser": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,26 +1,25 @@
|
|||||||
namespace ALttPRandomizer {
|
namespace ALttPRandomizer {
|
||||||
|
using ALttPRandomizer.Azure;
|
||||||
using ALttPRandomizer.Options;
|
using ALttPRandomizer.Options;
|
||||||
using Azure.Storage.Blobs;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
public class Randomizer {
|
public class Randomizer {
|
||||||
public Randomizer(
|
public Randomizer(
|
||||||
IdGenerator idGenerator,
|
IdGenerator idGenerator,
|
||||||
BlobContainerClient seedClient,
|
AzureStorage azureStorage,
|
||||||
IOptionsMonitor<ServiceOptions> optionsMonitor,
|
IOptionsMonitor<ServiceOptions> optionsMonitor,
|
||||||
ILogger<Randomizer> logger) {
|
ILogger<Randomizer> logger) {
|
||||||
this.IdGenerator = idGenerator;
|
this.IdGenerator = idGenerator;
|
||||||
this.SeedClient = seedClient;
|
this.AzureStorage = azureStorage;
|
||||||
this.OptionsMonitor = optionsMonitor;
|
this.OptionsMonitor = optionsMonitor;
|
||||||
this.Logger = logger;
|
this.Logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BlobContainerClient SeedClient { get; }
|
private AzureStorage AzureStorage { get; }
|
||||||
private IOptionsMonitor<ServiceOptions> OptionsMonitor { get; }
|
private IOptionsMonitor<ServiceOptions> OptionsMonitor { get; }
|
||||||
private IdGenerator IdGenerator { get; }
|
private IdGenerator IdGenerator { get; }
|
||||||
private ILogger<Randomizer> Logger { get; }
|
private ILogger<Randomizer> Logger { get; }
|
||||||
@@ -81,26 +80,17 @@
|
|||||||
var spoilerIn = Path.Join(Path.GetTempPath(), string.Format("DR_{0}_Spoiler.txt", id));
|
var spoilerIn = Path.Join(Path.GetTempPath(), string.Format("DR_{0}_Spoiler.txt", id));
|
||||||
var spoilerOut = string.Format("{0}/spoiler.txt", id);
|
var spoilerOut = string.Format("{0}/spoiler.txt", id);
|
||||||
|
|
||||||
var uploadPatch = UploadFile(bpsOut, bpsIn);
|
var uploadPatch = this.AzureStorage.UploadFileAndDelete(bpsOut, bpsIn);
|
||||||
var uploadSpoiler = UploadFile(spoilerOut, spoilerIn);
|
var uploadSpoiler = this.AzureStorage.UploadFileAndDelete(spoilerOut, spoilerIn);
|
||||||
|
|
||||||
await Task.WhenAll(uploadPatch, uploadSpoiler);
|
await Task.WhenAll(uploadPatch, uploadSpoiler);
|
||||||
|
|
||||||
|
this.Logger.LogDebug("Deleting file {filepath}", rom);
|
||||||
File.Delete(rom);
|
File.Delete(rom);
|
||||||
|
|
||||||
this.Logger.LogDebug("Finished uploading seed id {id}", id);
|
this.Logger.LogDebug("Finished uploading seed id {id}", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task UploadFile(string name, string filepath) {
|
|
||||||
using (var stream = new FileStream(filepath, FileMode.Open, FileAccess.Read)) {
|
|
||||||
this.Logger.LogDebug("Uploading file {filepath} -> {name}", filepath, name);
|
|
||||||
await this.SeedClient.UploadBlobAsync(name, stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.Logger.LogDebug("Deleting file {filepath}", filepath);
|
|
||||||
File.Delete(filepath);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GenerationFailed(string id, int exitcode) {
|
private void GenerationFailed(string id, int exitcode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
25
ALttPRandomizer/Service/SeedService.cs
Normal file
25
ALttPRandomizer/Service/SeedService.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
namespace ALttPRandomizer.Service {
|
||||||
|
using ALttPRandomizer.Azure;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
public class SeedService {
|
||||||
|
public SeedService(AzureStorage azureStorage) {
|
||||||
|
this.AzureStorage = azureStorage;
|
||||||
|
}
|
||||||
|
|
||||||
|
private AzureStorage AzureStorage { get; }
|
||||||
|
|
||||||
|
public async Task<IDictionary<string, string>> GetSeed(string seedId) {
|
||||||
|
var files = await this.AzureStorage.GetFiles(seedId);
|
||||||
|
|
||||||
|
var result = new Dictionary<string, string>();
|
||||||
|
foreach (var file in files) {
|
||||||
|
result[file.Key] = Convert.ToBase64String(file.Value.ToMemory().ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user