summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/release-notes.md1
-rw-r--r--src/SMAPI.Web/Controllers/LogParserController.cs11
-rw-r--r--src/SMAPI.Web/ViewModels/LogParserModel.cs19
-rw-r--r--src/SMAPI.Web/Views/LogParser/Index.cshtml79
-rw-r--r--src/SMAPI.Web/wwwroot/Content/css/log-parser.css4
-rw-r--r--src/SMAPI.Web/wwwroot/Content/js/log-parser.js14
6 files changed, 88 insertions, 40 deletions
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 5a9e4e92..329ea3ad 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -65,6 +65,7 @@
* Redesigned UI to be more mobile-friendly.
* Added option to download from Nexus.
* Changed log parser filters to show `DEBUG` messages by default.
+ * Added log parser option to view raw log.
* Fixed log parser issue when content packs have no description.
* Fixed log parser mangling crossplatform paths in some cases.
diff --git a/src/SMAPI.Web/Controllers/LogParserController.cs b/src/SMAPI.Web/Controllers/LogParserController.cs
index 2bff1392..354bdb06 100644
--- a/src/SMAPI.Web/Controllers/LogParserController.cs
+++ b/src/SMAPI.Web/Controllers/LogParserController.cs
@@ -52,21 +52,22 @@ namespace StardewModdingAPI.Web.Controllers
***/
/// <summary>Render the log parser UI.</summary>
/// <param name="id">The paste ID.</param>
+ /// <param name="raw">Whether to display the raw unparsed log.</param>
[HttpGet]
[Route("log")]
[Route("log/{id}")]
- public async Task<ViewResult> Index(string id = null)
+ public async Task<ViewResult> Index(string id = null, bool raw = false)
{
// fresh page
if (string.IsNullOrWhiteSpace(id))
- return this.View("Index", new LogParserModel(this.Config.LogParserUrl, id, null));
+ return this.View("Index", new LogParserModel(this.Config.LogParserUrl, id));
// log page
PasteInfo paste = await this.GetAsync(id);
ParsedLog log = paste.Success
? new LogParser().Parse(paste.Content)
: new ParsedLog { IsValid = false, Error = "Pastebin error: " + paste.Error };
- return this.View("Index", new LogParserModel(this.Config.LogParserUrl, id, log));
+ return this.View("Index", new LogParserModel(this.Config.LogParserUrl, id, log, raw));
}
/***
@@ -80,7 +81,7 @@ namespace StardewModdingAPI.Web.Controllers
// 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." });
+ return this.View("Index", new LogParserModel(this.Config.LogParserUrl, null) { UploadError = "The log file seems to be empty." });
// upload log
input = this.CompressString(input);
@@ -88,7 +89,7 @@ namespace StardewModdingAPI.Web.Controllers
// handle errors
if (!result.Success)
- return this.View("Index", new LogParserModel(this.Config.LogParserUrl, result.ID, null) { UploadError = $"Pastebin error: {result.Error ?? "unknown error"}" });
+ return this.View("Index", new LogParserModel(this.Config.LogParserUrl, result.ID) { UploadError = $"Pastebin error: {result.Error ?? "unknown error"}" });
// redirect to view
UriBuilder uri = new UriBuilder(new Uri(this.Config.LogParserUrl));
diff --git a/src/SMAPI.Web/ViewModels/LogParserModel.cs b/src/SMAPI.Web/ViewModels/LogParserModel.cs
index 0fbd8ad5..df36ca73 100644
--- a/src/SMAPI.Web/ViewModels/LogParserModel.cs
+++ b/src/SMAPI.Web/ViewModels/LogParserModel.cs
@@ -27,6 +27,9 @@ namespace StardewModdingAPI.Web.ViewModels
/// <summary>The parsed log info.</summary>
public ParsedLog ParsedLog { get; set; }
+ /// <summary>Whether to show the raw unparsed log.</summary>
+ public bool ShowRaw { get; set; }
+
/// <summary>An error which occurred while uploading the log to Pastebin.</summary>
public string UploadError { get; set; }
@@ -43,12 +46,24 @@ namespace StardewModdingAPI.Web.ViewModels
/// <summary>Construct an instance.</summary>
/// <param name="sectionUrl">The root URL for the log parser controller.</param>
/// <param name="pasteID">The paste ID.</param>
- /// <param name="parsedLog">The parsed log info.</param>
- public LogParserModel(string sectionUrl, string pasteID, ParsedLog parsedLog)
+ public LogParserModel(string sectionUrl, string pasteID)
{
this.SectionUrl = sectionUrl;
this.PasteID = pasteID;
+ this.ParsedLog = null;
+ this.ShowRaw = false;
+ }
+
+ /// <summary>Construct an instance.</summary>
+ /// <param name="sectionUrl">The root URL for the log parser controller.</param>
+ /// <param name="pasteID">The paste ID.</param>
+ /// <param name="parsedLog">The parsed log info.</param>
+ /// <param name="showRaw">Whether to show the raw unparsed log.</param>
+ public LogParserModel(string sectionUrl, string pasteID, ParsedLog parsedLog, bool showRaw)
+ : this(sectionUrl, pasteID)
+ {
this.ParsedLog = parsedLog;
+ this.ShowRaw = showRaw;
}
/// <summary>Get all content packs in the log grouped by the mod they're for.</summary>
diff --git a/src/SMAPI.Web/Views/LogParser/Index.cshtml b/src/SMAPI.Web/Views/LogParser/Index.cshtml
index 8151c502..f5501fed 100644
--- a/src/SMAPI.Web/Views/LogParser/Index.cshtml
+++ b/src/SMAPI.Web/Views/LogParser/Index.cshtml
@@ -17,17 +17,18 @@
{
<meta name="robots" content="noindex" />
}
- <link rel="stylesheet" href="~/Content/css/log-parser.css?r=20180611" />
+ <link rel="stylesheet" href="~/Content/css/log-parser.css?r=20180627" />
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js" crossorigin="anonymous"></script>
- <script src="~/Content/js/log-parser.js?r=20180611"></script>
+ <script src="~/Content/js/log-parser.js?r=20180627"></script>
<script>
$(function() {
smapi.logParser({
logStarted: new Date(@Json.Serialize(Model.ParsedLog?.Timestamp)),
showPopup: @Json.Serialize(Model.ParsedLog == null),
showMods: @Json.Serialize(Model.ParsedLog?.Mods?.Select(p => Model.GetSlug(p.Name)).Distinct().ToDictionary(slug => slug, slug => true), noFormatting),
- showLevels: @Json.Serialize(defaultFilters, noFormatting)
+ showLevels: @Json.Serialize(defaultFilters, noFormatting),
+ enableFilters: @Json.Serialize(!Model.ShowRaw)
}, '@Model.SectionUrl');
});
</script>
@@ -138,12 +139,15 @@ else if (Model.ParsedLog?.IsValid == true)
</tr>
</table>
<br />
- <table id="mods">
+ <table id="mods" class="@(Model.ShowRaw ? "filters-disabled" : null)">
<caption>
Installed mods:
- <span class="notice txt"><i>click any mod to filter</i></span>
- <span class="notice btn txt" v-on:click="showAllMods" v-show="stats.modsHidden > 0">show all</span>
- <span class="notice btn txt" v-on:click="hideAllMods" v-show="stats.modsShown > 0 && stats.modsHidden > 0">hide all</span>
+ @if (!Model.ShowRaw)
+ {
+ <span class="notice txt"><i>click any mod to filter</i></span>
+ <span class="notice btn txt" v-on:click="showAllMods" v-show="stats.modsHidden > 0">show all</span>
+ <span class="notice btn txt" v-on:click="hideAllMods" v-show="stats.modsShown > 0 && stats.modsHidden > 0">hide all</span>
+ }
</caption>
@foreach (var mod in Model.ParsedLog.Mods.Where(p => p.ContentPackFor == null))
{
@@ -177,36 +181,47 @@ else if (Model.ParsedLog?.IsValid == true)
</tr>
}
</table>
- <div id="filters">
- Filter messages:
- <span v-bind:class="{ active: showLevels['trace'] }" v-on:click="toggleLevel('trace')">TRACE</span> |
- <span v-bind:class="{ active: showLevels['debug'] }" v-on:click="toggleLevel('debug')">DEBUG</span> |
- <span v-bind:class="{ active: showLevels['info'] }" v-on:click="toggleLevel('info')">INFO</span> |
- <span v-bind:class="{ active: showLevels['alert'] }" v-on:click="toggleLevel('alert')">ALERT</span> |
- <span v-bind:class="{ active: showLevels['warn'] }" v-on:click="toggleLevel('warn')">WARN</span> |
- <span v-bind:class="{ active: showLevels['error'] }" v-on:click="toggleLevel('error')">ERROR</span>
- </div>
- <table id="log">
- @foreach (var message in Model.ParsedLog.Messages)
- {
- string levelStr = message.Level.ToString().ToLower();
+ @if (!Model.ShowRaw)
+ {
+ <div id="filters">
+ Filter messages:
+ <span v-bind:class="{ active: showLevels['trace'] }" v-on:click="toggleLevel('trace')">TRACE</span> |
+ <span v-bind:class="{ active: showLevels['debug'] }" v-on:click="toggleLevel('debug')">DEBUG</span> |
+ <span v-bind:class="{ active: showLevels['info'] }" v-on:click="toggleLevel('info')">INFO</span> |
+ <span v-bind:class="{ active: showLevels['alert'] }" v-on:click="toggleLevel('alert')">ALERT</span> |
+ <span v-bind:class="{ active: showLevels['warn'] }" v-on:click="toggleLevel('warn')">WARN</span> |
+ <span v-bind:class="{ active: showLevels['error'] }" v-on:click="toggleLevel('error')">ERROR</span>
+ </div>
- <tr class="@levelStr mod" v-show="filtersAllow('@Model.GetSlug(message.Mod)', '@levelStr')">
- <td v-pre>@message.Time</td>
- <td v-pre>@message.Level.ToString().ToUpper()</td>
- <td v-pre data-title="@message.Mod">@message.Mod</td>
- <td v-pre>@message.Text</td>
- </tr>
- if (message.Repeated > 0)
+ <table id="log">
+ @foreach (var message in Model.ParsedLog.Messages)
{
- <tr class="@levelStr mod mod-repeat" v-show="filtersAllow('@Model.GetSlug(message.Mod)', '@levelStr')">
- <td colspan="3"></td>
- <td v-pre><i>repeats [@message.Repeated] times.</i></td>
+ string levelStr = message.Level.ToString().ToLower();
+
+ <tr class="@levelStr mod" v-show="filtersAllow('@Model.GetSlug(message.Mod)', '@levelStr')">
+ <td v-pre>@message.Time</td>
+ <td v-pre>@message.Level.ToString().ToUpper()</td>
+ <td v-pre data-title="@message.Mod">@message.Mod</td>
+ <td v-pre>@message.Text</td>
</tr>
+ if (message.Repeated > 0)
+ {
+ <tr class="@levelStr mod mod-repeat" v-show="filtersAllow('@Model.GetSlug(message.Mod)', '@levelStr')">
+ <td colspan="3"></td>
+ <td v-pre><i>repeats [@message.Repeated] times.</i></td>
+ </tr>
+ }
}
- }
- </table>
+ </table>
+
+ <small><a href="@(new Uri(new Uri(Model.SectionUrl), Model.PasteID))?raw=true">view raw log</a></small>
+ }
+ else
+ {
+ <pre v-pre>@Model.ParsedLog.RawText</pre>
+ <small><a href="@(new Uri(new Uri(Model.SectionUrl), Model.PasteID))">view parsed log</a></small>
+ }
</div>
}
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;