From 6257fdf57def0f07a7970f9fb232879ed4c524f6 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 28 Apr 2018 22:39:29 -0400 Subject: update wiki links --- src/SMAPI.Web/Views/LogParser/Index.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/SMAPI.Web/Views/LogParser/Index.cshtml') diff --git a/src/SMAPI.Web/Views/LogParser/Index.cshtml b/src/SMAPI.Web/Views/LogParser/Index.cshtml index 2d1c1b44..d051026f 100644 --- a/src/SMAPI.Web/Views/LogParser/Index.cshtml +++ b/src/SMAPI.Web/Views/LogParser/Index.cshtml @@ -177,7 +177,7 @@ else if (Model.ParsedLog?.IsValid == false)

Upload log file

    -
  1. Find your SMAPI log file (not the console text).
  2. +
  3. Find your SMAPI log file (not the console text).
  4. Drag the file onto the textbox below (or paste the text in).
  5. Click Parse.
-- cgit From a463a05607c89922af7e908b39aa897b8d23bfbf Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 3 Jun 2018 13:54:26 -0400 Subject: redesign log parser upload page This makes the instructions much more clear and prominent, so it should be more intuitive for players. The previous design often confused users because they saw the big textbox and ignored the little instructions above it. --- docs/release-notes.md | 1 + src/SMAPI.Web/Controllers/LogParserController.cs | 31 +++-- src/SMAPI.Web/ViewModels/LogParserModel.cs | 38 ++++++ src/SMAPI.Web/Views/LogParser/Index.cshtml | 153 +++++++++++++---------- src/SMAPI.Web/wwwroot/Content/css/log-parser.css | 110 +++------------- src/SMAPI.Web/wwwroot/Content/js/log-parser.js | 90 ++++--------- 6 files changed, 193 insertions(+), 230 deletions(-) (limited to 'src/SMAPI.Web/Views/LogParser/Index.cshtml') diff --git a/docs/release-notes.md b/docs/release-notes.md index 8824c0fb..7668dc57 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -51,6 +51,7 @@ * Fixed `world_settime` sometimes breaking NPC schedules (e.g. so they stay in bed). * For the log parser: + * Redesigned upload page to make it more intuitive for new players. * Fixed issue parsing content packs with no description. * For SMAPI developers: diff --git a/src/SMAPI.Web/Controllers/LogParserController.cs b/src/SMAPI.Web/Controllers/LogParserController.cs index 62547deb..2bff1392 100644 --- a/src/SMAPI.Web/Controllers/LogParserController.cs +++ b/src/SMAPI.Web/Controllers/LogParserController.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.IO.Compression; +using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; @@ -72,13 +73,27 @@ namespace StardewModdingAPI.Web.Controllers ** JSON ***/ /// Save raw log data. - /// The log content to save. - [HttpPost, Produces("application/json"), AllowLargePosts] - [Route("log/save")] - public async Task PostAsync([FromBody] string content) + [HttpPost, AllowLargePosts] + [Route("log")] + public async Task PostAsync() { - content = this.CompressString(content); - return await this.Pastebin.PostAsync(content); + // get raw log text + string input = this.Request.Form["input"].FirstOrDefault(); + if (string.IsNullOrWhiteSpace(input)) + return this.View("Index", new LogParserModel(this.Config.LogParserUrl, null, null) { UploadError = "The log file seems to be empty." }); + + // upload log + input = this.CompressString(input); + SavePasteResult result = await this.Pastebin.PostAsync(input); + + // handle errors + if (!result.Success) + return this.View("Index", new LogParserModel(this.Config.LogParserUrl, result.ID, null) { UploadError = $"Pastebin error: {result.Error ?? "unknown error"}" }); + + // redirect to view + UriBuilder uri = new UriBuilder(new Uri(this.Config.LogParserUrl)); + uri.Path = uri.Path.TrimEnd('/') + '/' + result.ID; + return this.Redirect(uri.Uri.ToString()); } @@ -115,7 +130,7 @@ namespace StardewModdingAPI.Web.Controllers } // prefix length - var zipBuffer = new byte[compressedData.Length + 4]; + byte[] zipBuffer = new byte[compressedData.Length + 4]; Buffer.BlockCopy(compressedData, 0, zipBuffer, 4, compressedData.Length); Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, zipBuffer, 0, 4); @@ -151,7 +166,7 @@ namespace StardewModdingAPI.Web.Controllers memoryStream.Write(zipBuffer, 4, zipBuffer.Length - 4); // read data - var buffer = new byte[dataLength]; + byte[] buffer = new byte[dataLength]; memoryStream.Position = 0; using (GZipStream gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress)) gZipStream.Read(buffer, 0, buffer.Length); diff --git a/src/SMAPI.Web/ViewModels/LogParserModel.cs b/src/SMAPI.Web/ViewModels/LogParserModel.cs index 8c026536..0fbd8ad5 100644 --- a/src/SMAPI.Web/ViewModels/LogParserModel.cs +++ b/src/SMAPI.Web/ViewModels/LogParserModel.cs @@ -1,3 +1,6 @@ +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; using StardewModdingAPI.Web.Framework.LogParsing.Models; namespace StardewModdingAPI.Web.ViewModels @@ -5,6 +8,13 @@ namespace StardewModdingAPI.Web.ViewModels /// The view model for the log parser page. public class LogParserModel { + /********* + ** Properties + *********/ + /// A regex pattern matching characters to remove from a mod name to create the slug ID. + private readonly Regex SlugInvalidCharPattern = new Regex("[^a-z0-9]", RegexOptions.Compiled | RegexOptions.IgnoreCase); + + /********* ** Accessors *********/ @@ -17,6 +27,12 @@ namespace StardewModdingAPI.Web.ViewModels /// The parsed log info. public ParsedLog ParsedLog { get; set; } + /// An error which occurred while uploading the log to Pastebin. + public string UploadError { get; set; } + + /// An error which occurred while parsing the log file. + public string ParseError => this.ParsedLog?.Error; + /********* ** Public methods @@ -34,5 +50,27 @@ namespace StardewModdingAPI.Web.ViewModels this.PasteID = pasteID; this.ParsedLog = parsedLog; } + + /// Get all content packs in the log grouped by the mod they're for. + public IDictionary GetContentPacksByMod() + { + // get all mods & content packs + LogModInfo[] mods = this.ParsedLog?.Mods; + if (mods == null || !mods.Any()) + return new Dictionary(); + + // group by mod + return mods + .Where(mod => mod.ContentPackFor != null) + .GroupBy(mod => mod.ContentPackFor) + .ToDictionary(group => group.Key, group => group.ToArray()); + } + + /// Get a sanitised mod name that's safe to use in anchors, attributes, and URLs. + /// The mod name. + public string GetSlug(string modName) + { + return this.SlugInvalidCharPattern.Replace(modName, ""); + } } } diff --git a/src/SMAPI.Web/Views/LogParser/Index.cshtml b/src/SMAPI.Web/Views/LogParser/Index.cshtml index d051026f..79cd7a2b 100644 --- a/src/SMAPI.Web/Views/LogParser/Index.cshtml +++ b/src/SMAPI.Web/Views/LogParser/Index.cshtml @@ -1,23 +1,14 @@ -@{ - ViewData["Title"] = "SMAPI log parser"; - - IDictionary contentPacks = Model.ParsedLog?.Mods - ?.GroupBy(mod => mod.ContentPackFor) - .Where(group => group.Key != null) - .ToDictionary(group => group.Key, group => group.ToArray()); - - Regex slugInvalidCharPattern = new Regex("[^a-z0-9]", RegexOptions.Compiled | RegexOptions.IgnoreCase); - string GetSlug(string modName) - { - return slugInvalidCharPattern.Replace(modName, ""); - } -} -@using System.Text.RegularExpressions @using Newtonsoft.Json @using StardewModdingAPI.Web.Framework.LogParsing.Models @model StardewModdingAPI.Web.ViewModels.LogParserModel + +@{ + ViewData["Title"] = "SMAPI log parser"; + IDictionary contentPacks = Model.GetContentPacksByMod(); +} + @section Head { - + @@ -26,51 +17,104 @@ smapi.logParser({ logStarted: new Date(@Json.Serialize(Model.ParsedLog?.Timestamp)), showPopup: @Json.Serialize(Model.ParsedLog == null), - showMods: @Json.Serialize(Model.ParsedLog?.Mods?.Select(p => GetSlug(p.Name)).Distinct().ToDictionary(slug => slug, slug => true), new JsonSerializerSettings { Formatting = Formatting.None }), + showMods: @Json.Serialize(Model.ParsedLog?.Mods?.Select(p => Model.GetSlug(p.Name)).Distinct().ToDictionary(slug => slug, slug => true), new JsonSerializerSettings { Formatting = Formatting.None }), showLevels: { - trace: false, - debug: false, - info: true, - alert: true, - warn: true, - error: true + @LogLevel.Trace.ToString().ToLower(): false, + @LogLevel.Debug.ToString().ToLower(): false, + @LogLevel.Info.ToString().ToLower(): true, + @LogLevel.Alert.ToString().ToLower(): true, + @LogLevel.Warn.ToString().ToLower(): true, + @LogLevel.Error.ToString().ToLower(): true } }, '@Model.SectionUrl'); }); } -@********* -** Intro -*********@ +@* intro and upload result banner *@

This page lets you upload, view, and share a SMAPI log to help troubleshoot mod issues.

- -@if (Model.ParsedLog?.IsValid == true) +@if (Model.UploadError != null) { - } else if (Model.ParsedLog?.IsValid == false) diff --git a/src/SMAPI.Web/wwwroot/Content/css/log-parser.css b/src/SMAPI.Web/wwwroot/Content/css/log-parser.css index 09bb97f5..1fcd1bff 100644 --- a/src/SMAPI.Web/wwwroot/Content/css/log-parser.css +++ b/src/SMAPI.Web/wwwroot/Content/css/log-parser.css @@ -79,6 +79,10 @@ table#metadata, table#mods { cursor: pointer; } +#mods.filters-disabled tr { + cursor: default; +} + #metadata tr, #mods tr { background: #eee diff --git a/src/SMAPI.Web/wwwroot/Content/js/log-parser.js b/src/SMAPI.Web/wwwroot/Content/js/log-parser.js index 44c3ad5d..0c654205 100644 --- a/src/SMAPI.Web/wwwroot/Content/js/log-parser.js +++ b/src/SMAPI.Web/wwwroot/Content/js/log-parser.js @@ -39,11 +39,17 @@ smapi.logParser = function (data, sectionUrl) { } }, methods: { - toggleLevel: function(id) { + toggleLevel: function (id) { + if (!data.enableFilters) + return; + this.showLevels[id] = !this.showLevels[id]; }, toggleMod: function (id) { + if (!data.enableFilters) + return; + var curShown = this.showMods[id]; // first filter: only show this by default @@ -64,6 +70,9 @@ smapi.logParser = function (data, sectionUrl) { }, showAllMods: function () { + if (!data.enableFilters) + return; + for (var key in this.showMods) { if (this.showMods.hasOwnProperty(key)) { this.showMods[key] = true; @@ -73,6 +82,9 @@ smapi.logParser = function (data, sectionUrl) { }, hideAllMods: function () { + if (!data.enableFilters) + return; + for (var key in this.showMods) { if (this.showMods.hasOwnProperty(key)) { this.showMods[key] = false; -- cgit From 52cf953f685c65b2b6814e375ec9a5ffa03c440a Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 1 Aug 2018 06:01:53 -0400 Subject: mention SMAPI-crash.txt in log parser instructions --- src/SMAPI.Web/Views/LogParser/Index.cshtml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/SMAPI.Web/Views/LogParser/Index.cshtml') diff --git a/src/SMAPI.Web/Views/LogParser/Index.cshtml b/src/SMAPI.Web/Views/LogParser/Index.cshtml index f5501fed..e735e8f3 100644 --- a/src/SMAPI.Web/Views/LogParser/Index.cshtml +++ b/src/SMAPI.Web/Views/LogParser/Index.cshtml @@ -77,7 +77,7 @@ else if (Model.ParsedLog?.IsValid == true)
  • Click the options menu (might be labeled Go or ).
  • Choose Enter Location.
  • Enter this exact text:
    ~/.config/StardewValley/ErrorLogs
  • -
  • The log file is SMAPI-latest.txt.
  • +
  • The log file is SMAPI-crash.txt if it exists, otherwise SMAPI-latest.txt.
  • @@ -86,7 +86,7 @@ else if (Model.ParsedLog?.IsValid == true)
  • Open the Finder app.
  • Click Go at the top, then Enter Location.
  • Enter this exact text:
    ~/.config/StardewValley/ErrorLogs
  • -
  • The log file is SMAPI-latest.txt.
  • +
  • The log file is SMAPI-crash.txt if it exists, otherwise SMAPI-latest.txt.
  • @@ -94,7 +94,7 @@ else if (Model.ParsedLog?.IsValid == true)
    1. Press the Windows and R buttons at the same time.
    2. In the 'run' box that appears, enter this exact text:
      %appdata%\StardewValley\ErrorLogs
    3. -
    4. The log file is SMAPI-latest.txt.
    5. +
    6. The log file is SMAPI-crash.txt if it exists, otherwise SMAPI-latest.txt.
    -- cgit