add log parser option to view raw log
This commit is contained in:
parent
cf37285627
commit
3e5c109df1
|
@ -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.
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -79,6 +79,10 @@ table#metadata, table#mods {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
#mods.filters-disabled tr {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
#metadata tr,
|
||||
#mods tr {
|
||||
background: #eee
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue