summaryrefslogtreecommitdiff
path: root/src/SMAPI.Web
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI.Web')
-rw-r--r--src/SMAPI.Web/Controllers/JsonValidatorController.cs8
-rw-r--r--src/SMAPI.Web/Controllers/LogParserController.cs5
-rw-r--r--src/SMAPI.Web/Framework/Storage/IStorageProvider.cs3
-rw-r--r--src/SMAPI.Web/Framework/Storage/StorageProvider.cs53
-rw-r--r--src/SMAPI.Web/Views/JsonValidator/Index.cshtml2
-rw-r--r--src/SMAPI.Web/Views/LogParser/Index.cshtml2
6 files changed, 44 insertions, 29 deletions
diff --git a/src/SMAPI.Web/Controllers/JsonValidatorController.cs b/src/SMAPI.Web/Controllers/JsonValidatorController.cs
index 6ba97749..c77a3036 100644
--- a/src/SMAPI.Web/Controllers/JsonValidatorController.cs
+++ b/src/SMAPI.Web/Controllers/JsonValidatorController.cs
@@ -58,7 +58,7 @@ namespace StardewModdingAPI.Web.Controllers
/// <summary>Render the schema validator UI.</summary>
/// <param name="schemaName">The schema name with which to validate the JSON, or 'edit' to return to the edit screen.</param>
/// <param name="id">The stored file ID.</param>
- /// <param name="operation">The operation to perform for the selected log ID. This can be 'edit', or any other value to view.</param>
+ /// <param name="operation">The operation to perform for the selected log ID. This can be 'edit', 'renew', or any other value to view.</param>
[HttpGet]
[Route("json")]
[Route("json/{schemaName}")]
@@ -68,8 +68,10 @@ namespace StardewModdingAPI.Web.Controllers
{
// parse arguments
schemaName = this.NormalizeSchemaName(schemaName);
+ operation = operation?.Trim().ToLower();
bool hasId = !string.IsNullOrWhiteSpace(id);
- bool isEditView = !hasId || operation?.Trim().ToLower() == "edit";
+ bool isEditView = !hasId || operation == "edit";
+ bool renew = operation == "renew";
// build result model
var result = this.GetModel(id, schemaName, isEditView);
@@ -77,7 +79,7 @@ namespace StardewModdingAPI.Web.Controllers
return this.View("Index", result);
// fetch raw JSON
- StoredFileInfo file = await this.Storage.GetAsync(id);
+ StoredFileInfo file = await this.Storage.GetAsync(id, renew);
if (string.IsNullOrWhiteSpace(file.Content))
return this.View("Index", result.SetUploadError("The JSON file seems to be empty."));
result.SetContent(file.Content, expiry: file.Expiry, uploadWarning: file.Warning);
diff --git a/src/SMAPI.Web/Controllers/LogParserController.cs b/src/SMAPI.Web/Controllers/LogParserController.cs
index 97c419d9..39de4b5d 100644
--- a/src/SMAPI.Web/Controllers/LogParserController.cs
+++ b/src/SMAPI.Web/Controllers/LogParserController.cs
@@ -40,17 +40,18 @@ namespace StardewModdingAPI.Web.Controllers
/// <summary>Render the log parser UI.</summary>
/// <param name="id">The stored file ID.</param>
/// <param name="raw">Whether to display the raw unparsed log.</param>
+ /// <param name="renew">Whether to reset the log expiry.</param>
[HttpGet]
[Route("log")]
[Route("log/{id}")]
- public async Task<ViewResult> Index(string id = null, bool raw = false)
+ public async Task<ViewResult> Index(string id = null, bool raw = false, bool renew = false)
{
// fresh page
if (string.IsNullOrWhiteSpace(id))
return this.View("Index", this.GetModel(id));
// log page
- StoredFileInfo file = await this.Storage.GetAsync(id);
+ StoredFileInfo file = await this.Storage.GetAsync(id, renew);
ParsedLog log = file.Success
? new LogParser().Parse(file.Content)
: new ParsedLog { IsValid = false, Error = file.Error };
diff --git a/src/SMAPI.Web/Framework/Storage/IStorageProvider.cs b/src/SMAPI.Web/Framework/Storage/IStorageProvider.cs
index 96a34fbb..dfc1fb47 100644
--- a/src/SMAPI.Web/Framework/Storage/IStorageProvider.cs
+++ b/src/SMAPI.Web/Framework/Storage/IStorageProvider.cs
@@ -13,6 +13,7 @@ namespace StardewModdingAPI.Web.Framework.Storage
/// <summary>Fetch raw text from storage.</summary>
/// <param name="id">The storage ID returned by <see cref="SaveAsync"/>.</param>
- Task<StoredFileInfo> GetAsync(string id);
+ /// <param name="renew">Whether to reset the file expiry.</param>
+ Task<StoredFileInfo> GetAsync(string id, bool renew);
}
}
diff --git a/src/SMAPI.Web/Framework/Storage/StorageProvider.cs b/src/SMAPI.Web/Framework/Storage/StorageProvider.cs
index 35538443..c6f8bac1 100644
--- a/src/SMAPI.Web/Framework/Storage/StorageProvider.cs
+++ b/src/SMAPI.Web/Framework/Storage/StorageProvider.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
@@ -48,10 +49,7 @@ namespace StardewModdingAPI.Web.Framework.Storage
this.GzipHelper = gzipHelper;
}
- /// <summary>Save a text file to storage.</summary>
- /// <param name="content">The content to upload.</param>
- /// <param name="compress">Whether to gzip the text.</param>
- /// <returns>Returns metadata about the save attempt.</returns>
+ /// <inheritdoc />
public async Task<UploadResult> SaveAsync(string content, bool compress = true)
{
string id = Guid.NewGuid().ToString("N");
@@ -84,9 +82,8 @@ namespace StardewModdingAPI.Web.Framework.Storage
}
}
- /// <summary>Fetch raw text from storage.</summary>
- /// <param name="id">The storage ID returned by <see cref="SaveAsync"/>.</param>
- public async Task<StoredFileInfo> GetAsync(string id)
+ /// <inheritdoc />
+ public async Task<StoredFileInfo> GetAsync(string id, bool renew)
{
// fetch from blob storage
if (Guid.TryParseExact(id, "N", out Guid _))
@@ -96,14 +93,21 @@ namespace StardewModdingAPI.Web.Framework.Storage
{
try
{
+ // get client
BlobClient blob = this.GetAzureBlobClient(id);
+
+ // extend expiry
+ if (renew)
+ await blob.SetMetadataAsync(new Dictionary<string, string> { ["expiryRenewed"] = DateTime.UtcNow.ToString("O") }); // change the blob's last-modified date (the specific property set doesn't matter)
+
+ // fetch file
Response<BlobDownloadInfo> response = await blob.DownloadAsync();
using BlobDownloadInfo result = response.Value;
-
using StreamReader reader = new StreamReader(result.Content);
DateTimeOffset expiry = result.Details.LastModified + TimeSpan.FromDays(this.ExpiryDays);
string content = this.GzipHelper.DecompressString(reader.ReadToEnd());
+ // build model
return new StoredFileInfo
{
Success = true,
@@ -125,25 +129,32 @@ namespace StardewModdingAPI.Web.Framework.Storage
// local filesystem for testing
else
{
+ // get file
FileInfo file = new FileInfo(this.GetDevFilePath(id));
- if (file.Exists)
+ if (file.Exists && file.LastWriteTimeUtc.AddDays(this.ExpiryDays) < DateTime.UtcNow) // expired
+ file.Delete();
+ if (!file.Exists)
{
- if (file.LastWriteTimeUtc.AddDays(this.ExpiryDays) < DateTime.UtcNow)
- file.Delete();
- else
+ return new StoredFileInfo
{
- return new StoredFileInfo
- {
- Success = true,
- Content = File.ReadAllText(file.FullName),
- Expiry = DateTime.UtcNow.AddDays(this.ExpiryDays),
- Warning = "This file was saved temporarily to the local computer. This should only happen in a local development environment."
- };
- }
+ Error = "There's no file with that ID."
+ };
}
+
+ // renew
+ if (renew)
+ {
+ File.SetLastWriteTimeUtc(file.FullName, DateTime.UtcNow);
+ file.Refresh();
+ }
+
+ // build model
return new StoredFileInfo
{
- Error = "There's no file with that ID."
+ Success = true,
+ Content = File.ReadAllText(file.FullName),
+ Expiry = DateTime.UtcNow.AddDays(this.ExpiryDays),
+ Warning = "This file was saved temporarily to the local computer. This should only happen in a local development environment."
};
}
}
diff --git a/src/SMAPI.Web/Views/JsonValidator/Index.cshtml b/src/SMAPI.Web/Views/JsonValidator/Index.cshtml
index 7b89a23d..1db79857 100644
--- a/src/SMAPI.Web/Views/JsonValidator/Index.cshtml
+++ b/src/SMAPI.Web/Views/JsonValidator/Index.cshtml
@@ -76,7 +76,7 @@ else if (!Model.IsEditView && Model.PasteID != null)
<div class="save-metadata" v-pre>
@if (Model.Expiry != null)
{
- <text>This JSON file will expire in @((DateTime.UtcNow - Model.Expiry.Value).Humanize()). </text>
+ <text>This JSON file will expire in @((DateTime.UtcNow - Model.Expiry.Value).Humanize()) (<a href="@(this.Url.PlainAction("Index", "JsonValidator", new { schemaName = this.Model.SchemaName, id = this.Model.PasteID, operation = "renew" }))">renew</a>).</text>
}
<!--@Model.UploadWarning-->
</div>
diff --git a/src/SMAPI.Web/Views/LogParser/Index.cshtml b/src/SMAPI.Web/Views/LogParser/Index.cshtml
index 71e12d47..d4ff4f10 100644
--- a/src/SMAPI.Web/Views/LogParser/Index.cshtml
+++ b/src/SMAPI.Web/Views/LogParser/Index.cshtml
@@ -78,7 +78,7 @@ else if (Model.ParsedLog?.IsValid == true)
<div class="save-metadata" v-pre>
@if (Model.Expiry != null)
{
- <text>This log will expire in @((DateTime.UtcNow - Model.Expiry.Value).Humanize()).</text>
+ <text>This log will expire in @((DateTime.UtcNow - Model.Expiry.Value).Humanize()) (<a href="@(this.Url.PlainAction("Index", "LogParser", new { id = this.Model.PasteID, renew = true }))">renew</a>).</text>
}
</div>
}