From 65f0fa625575592639a24a9b39330e4a6b500f22 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 27 Oct 2017 19:36:31 -0400 Subject: add scaffolding for web UI (#358) --- src/SMAPI.Web/wwwroot/Content/main.css | 107 +++++++++++++++++++++++++++ src/SMAPI.Web/wwwroot/Content/sidebar-bg.gif | Bin 0 -> 1104 bytes src/SMAPI.Web/wwwroot/favicon.ico | Bin 0 -> 15086 bytes 3 files changed, 107 insertions(+) create mode 100644 src/SMAPI.Web/wwwroot/Content/main.css create mode 100644 src/SMAPI.Web/wwwroot/Content/sidebar-bg.gif create mode 100644 src/SMAPI.Web/wwwroot/favicon.ico (limited to 'src/SMAPI.Web/wwwroot') diff --git a/src/SMAPI.Web/wwwroot/Content/main.css b/src/SMAPI.Web/wwwroot/Content/main.css new file mode 100644 index 00000000..c8ce8d33 --- /dev/null +++ b/src/SMAPI.Web/wwwroot/Content/main.css @@ -0,0 +1,107 @@ +/* tags */ +html { + height: 100%; +} + +body { + height: 100%; + font-family: sans-serif; +} + +h1, h2, h3 { + font-weight: bold; + margin: 0.2em 0 0.1em 0; + padding-top: .5em; +} + +h1 { + font-size: 1.5em; + color: #888; + margin-bottom: 0; +} + +h2 { + font-size: 1.5em; + border-bottom: 1px solid #AAA; +} + +h3 { + font-size: 1.2em; + border-bottom: 1px solid #AAA; + width: 50%; +} + +a { + color: #006; +} + +/* content */ +#content-column { + position: absolute; + top: 1em; + left: 10em; +} + +#content { + min-height: 140px; + padding: 0 1em 1em 1em; + border-left: 1px solid #CCC; + background: #FFF; + font-size: 0.9em; +} + +#content p { + max-width: 55em; +} + +.section { + border: 1px solid #CCC; + padding: 0.5em; + margin-bottom: 1em; +} + +/* sidebar */ +#sidebar { + margin-top: 3em; + min-height: 75%; + width: 12em; + background: url("sidebar-bg.gif") no-repeat top right; + color: #666; +} + +#sidebar h4 { + margin: 0 0 0.2em 0; + width: 10em; + border-bottom: 1px solid #CCC; + font-size: 0.8em; + font-weight: normal; +} + +#sidebar a { + color: #77B; + border: 0; +} + +#sidebar ul, #sidebar li { + margin: 0; + padding: 0; + list-style: none none; + font-size: 0.9em; + color: #888; +} + +#sidebar li { + margin-left: 1em; +} + +/* footer */ +#footer { + margin: 1em; + padding: 1em; + font-size: 0.6em; + color: gray; +} + +#footer a { + color: #669; +} diff --git a/src/SMAPI.Web/wwwroot/Content/sidebar-bg.gif b/src/SMAPI.Web/wwwroot/Content/sidebar-bg.gif new file mode 100644 index 00000000..48e9af5a Binary files /dev/null and b/src/SMAPI.Web/wwwroot/Content/sidebar-bg.gif differ diff --git a/src/SMAPI.Web/wwwroot/favicon.ico b/src/SMAPI.Web/wwwroot/favicon.ico new file mode 100644 index 00000000..587a6e74 Binary files /dev/null and b/src/SMAPI.Web/wwwroot/favicon.ico differ -- cgit From 9f5af37391ac196fe183122f57496846843335cd Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 27 Oct 2017 19:38:13 -0400 Subject: move log parser CSS/JS out of HTML (#358) --- src/SMAPI.Web/wwwroot/Content/css/log-parser.css | 374 +++++++++++++++++++++ src/SMAPI.Web/wwwroot/Content/css/main.css | 107 ++++++ .../wwwroot/Content/images/sidebar-bg.gif | Bin 0 -> 1104 bytes src/SMAPI.Web/wwwroot/Content/js/log-parser.js | 287 ++++++++++++++++ src/SMAPI.Web/wwwroot/Content/main.css | 107 ------ src/SMAPI.Web/wwwroot/Content/sidebar-bg.gif | Bin 1104 -> 0 bytes 6 files changed, 768 insertions(+), 107 deletions(-) create mode 100644 src/SMAPI.Web/wwwroot/Content/css/log-parser.css create mode 100644 src/SMAPI.Web/wwwroot/Content/css/main.css create mode 100644 src/SMAPI.Web/wwwroot/Content/images/sidebar-bg.gif create mode 100644 src/SMAPI.Web/wwwroot/Content/js/log-parser.js delete mode 100644 src/SMAPI.Web/wwwroot/Content/main.css delete mode 100644 src/SMAPI.Web/wwwroot/Content/sidebar-bg.gif (limited to 'src/SMAPI.Web/wwwroot') diff --git a/src/SMAPI.Web/wwwroot/Content/css/log-parser.css b/src/SMAPI.Web/wwwroot/Content/css/log-parser.css new file mode 100644 index 00000000..0aff5b81 --- /dev/null +++ b/src/SMAPI.Web/wwwroot/Content/css/log-parser.css @@ -0,0 +1,374 @@ +body { + font-size: 10pt; + background: #fff; +} + +.mod-repeat { + font-size: 8pt; +} + +input[type="button"] { + cursor: pointer; +} + +.template { + display: none; +} + +.popup, #uploader { + position: fixed; + top: 0px; + left: 0px; + right: 0px; + bottom: 0; + background-color: rgba(0, 0, 0, .33); + z-index: 2; + display: none; + padding: 5px; +} + +#uploader:after { + content: attr(data-text); + display: block; + width: 100px; + height: 24px; + line-height: 25px; + border: 1px solid #000; + background: #fff; + position: absolute; + top: 50%; + left: 50%; + margin: -12px -50px 0 0; + font-size: 18px; + font-weight: bold; + text-align: center; + border-radius: 5px; +} + +.popup h1 { + position: absolute; + top: 10%; + left: 50%; + margin-left: -150px; + text-align: center; + width: 300px; + border: 1px solid #008; + border-radius: 5px; + background: #fff; + font-family: sans-serif; + font-size: 40px; + margin-top: -25px; +} + +.frame { + margin: auto; + margin-top: 25px; + position: absolute; + top: 10%; + left: 10%; + right: 10%; + bottom: 10%; + padding-bottom: 30px; +} + +.buttons { + position: absolute; + display: inline-block; + bottom: -10px; + right: 0px; + padding: 5px; + border: 1px solid #008; + border-radius: 5px; + background: #fff; +} + +#cancel, #closeraw { + font-size: 20px; + border-radius: 5px; + border: 1px solid #880000; + background-color: #fcc; + outline: none; + box-shadow: inset 0px 0px 1px 1px rgba(0, 0, 0, .2); +} + +#cancel:hover, #closeraw:hover { + background-color: #fee; +} + +#submit { + font-size: 20px; + border-radius: 5px; + border: 1px solid #008800; + background-color: #cfc; + outline: none; + box-shadow: inset 0px 0px 1px 1px rgba(0, 0, 0, .2); +} + +#submit:hover { + background-color: #efe; +} + +#input, #dataraw { + width: 100%; + height: 100%; + max-width: 100%; + max-height: 100%; + margin: auto; + box-sizing: border-box; + border-radius: 5px; + border: 1px solid #000088; + outline: none; + box-shadow: inset 0px 0px 1px 1px rgba(0, 0, 192, .2); +} + +.color-red { + color: red; +} + +.color-green { + color: green; +} + +#tabs { + top: 0px; + left: 0px; + right: 0px; + border-bottom: 0; + display: block; + position: fixed; + margin: 0; + padding: 0; + background: linear-gradient(to bottom, rgba(255, 255, 255, 1) 0%, rgba(210, 235, 249, 1) 100%); +} + +#tabs li { + margin: 5px 1px 0 0; + height: 25px; + float: left; + display: inline-block; + width: 75px; + border: 1px solid #000000; + border-bottom: 0; + border-radius: 5px 5px 0 0; + text-align: center; + font-family: monospace; + font-size: 18px; + cursor: pointer; + font-weight: bold; + color: #000; + text-shadow: 0px 0px 2px #fff; + border-color: #880000; + background-color: #fcc; + box-shadow: inset 0px 0px 1px 1px rgba(0, 0, 0, .2); +} + +#tabs li:hover { + background-color: #fee; +} + +#tabs li:first-child { + margin-left: 5px; +} + +#tabs li.active { + background: #cfc; + border-color: #008800; +} + +#tabs li.active:hover { + background: #efe; +} + +#tabs li.upload { + float: right; + background: #ccf; + border-color: #000088; + margin-right: 5px; +} + +#tabs li.upload:hover { + background: #eef; +} + +#tabs li.notice { + color: #000000; + background: transparent; + border: 0; + padding-top: 1px; + font-size: 13px; + font-weight: normal; + width: auto; + margin-left: 5px; + cursor: default; + box-shadow: none; + font-style: italic; +} + +#output { + border-top: 1px solid #888; + position: fixed; + top: 30px; + left: 0px; + right: 0px; + bottom: 0px; + padding: 10px; + overflow: auto; + font-family: monospace; +} + +#output > * { + display: block; +} + +#output.trace .trace, +#output.debug .debug, +#output.info .info, +#output.alert .alert, +#output.warn .warn, +#output.error .error { + display: none; +} + +#output .trace { + color: #999; +} + +#output .debug { + color: #595959; +} + +#output .info { + color: #000 +} + +#output .alert { + color: #b0b; +} + +#output .warn { + color: #f80 +} + +#output .error { + color: #f00 +} + +#output .always { + font-weight: bold; + border-bottom: 1px dashed #888888; + padding-bottom: 10px; + margin-bottom: 5px; +} + +caption { + text-align: left; + padding-top: 2px; +} + +#log { + border-spacing: 0; +} + +#log tr { + background: #fff; +} + +#log td { + padding: 0 1px; + background: inherit; + border-bottom: 1px dotted #ccc; + border-top: 2px solid #fff; + vertical-align: top; +} + +#log td:not(:last-child) { + max-width: 175px; + padding: 0 4px; + overflow: hidden; + white-space: nowrap; +} + +#log td[data-title]:hover { + font-size: 1px; + overflow: inherit; + position: relative; +} + +#log td:nth-child(3):hover:after { + content: attr(data-title); + display: block; + position: absolute; + border-radius: 4px; + box-shadow: 1px 1px 2px #ccc; + background: inherit; + border: 1px solid #ccc; + background: #efefef; + padding: 1px 1px 0 1px; + font-size: 10pt; + top: -2px; + left: 2px; + color: #000; +} + +#log td:last-child { + width: 100%; +} + +table#gameinfo, +table#modslist { + border: 1px solid #000000; + background: #ffffff; + border-radius: 5px; + border-spacing: 1px; + overflow: hidden; + cursor: default; + box-shadow: 1px 1px 1px 1px #dddddd; +} + +#modslist { + min-width: 400px; +} + +#gameinfo td:first-child { + padding-right: 5px; +} + +#gameinfo tr, +#modslist tr { + background: #eee +} + +#gameinfo tr:nth-child(even), +#modslist tr:nth-child(even) { + background: #fff +} + +#modslist tr { + cursor: pointer; +} + +span.notice { + font-weight: normal; + font-size: 11px; + position: relative; + top: -1px; + display: none; +} + +span.notice.btn { + cursor: pointer; + border: 1px solid #000; + border-radius: 5px; + position: relative; + top: -1px; + padding: 0 2px; + background: #eee; +} + +#output:not(.modfilter) span.notice.txt { + display: inline-block; +} + +#output.modfilter span.notice.btn { + display: inline-block; +} diff --git a/src/SMAPI.Web/wwwroot/Content/css/main.css b/src/SMAPI.Web/wwwroot/Content/css/main.css new file mode 100644 index 00000000..d1fa49e0 --- /dev/null +++ b/src/SMAPI.Web/wwwroot/Content/css/main.css @@ -0,0 +1,107 @@ +/* tags */ +html { + height: 100%; +} + +body { + height: 100%; + font-family: sans-serif; +} + +h1, h2, h3 { + font-weight: bold; + margin: 0.2em 0 0.1em 0; + padding-top: .5em; +} + +h1 { + font-size: 1.5em; + color: #888; + margin-bottom: 0; +} + +h2 { + font-size: 1.5em; + border-bottom: 1px solid #AAA; +} + +h3 { + font-size: 1.2em; + border-bottom: 1px solid #AAA; + width: 50%; +} + +a { + color: #006; +} + +/* content */ +#content-column { + position: absolute; + top: 1em; + left: 10em; +} + +#content { + min-height: 140px; + padding: 0 1em 1em 1em; + border-left: 1px solid #CCC; + background: #FFF; + font-size: 0.9em; +} + +#content p { + max-width: 55em; +} + +.section { + border: 1px solid #CCC; + padding: 0.5em; + margin-bottom: 1em; +} + +/* sidebar */ +#sidebar { + margin-top: 3em; + min-height: 75%; + width: 12em; + background: url("../images/sidebar-bg.gif") no-repeat top right; + color: #666; +} + +#sidebar h4 { + margin: 0 0 0.2em 0; + width: 10em; + border-bottom: 1px solid #CCC; + font-size: 0.8em; + font-weight: normal; +} + +#sidebar a { + color: #77B; + border: 0; +} + +#sidebar ul, #sidebar li { + margin: 0; + padding: 0; + list-style: none none; + font-size: 0.9em; + color: #888; +} + +#sidebar li { + margin-left: 1em; +} + +/* footer */ +#footer { + margin: 1em; + padding: 1em; + font-size: 0.6em; + color: gray; +} + +#footer a { + color: #669; +} diff --git a/src/SMAPI.Web/wwwroot/Content/images/sidebar-bg.gif b/src/SMAPI.Web/wwwroot/Content/images/sidebar-bg.gif new file mode 100644 index 00000000..48e9af5a Binary files /dev/null and b/src/SMAPI.Web/wwwroot/Content/images/sidebar-bg.gif differ diff --git a/src/SMAPI.Web/wwwroot/Content/js/log-parser.js b/src/SMAPI.Web/wwwroot/Content/js/log-parser.js new file mode 100644 index 00000000..2d095787 --- /dev/null +++ b/src/SMAPI.Web/wwwroot/Content/js/log-parser.js @@ -0,0 +1,287 @@ +$(function() { + function modClicked(evt) { + var id = $(evt.currentTarget).attr("id").split('-')[1], + cls = "mod-" + id;; + if (output.hasClass(cls)) + filters--; + else + filters++; + output.toggleClass(cls); + if (filters == 0) { + output.removeClass("modfilter"); + } else { + output.addClass("modfilter"); + } + } + + function removeFilter() { + for (var c = 0; c < modInfo.length; c++) { + output.removeClass("mod-" + c); + } + filters = 0; + output.removeClass("modfilter"); + } + + function selectAll() { + for (var c = 0; c < modInfo.length; c++) { + output.addClass("mod-" + c); + } + filters = modInfo.length; + output.addClass("modfilter"); + } + + function parseData() { + Stage = "parseData.pre"; + var data = $("#input").val(); + if (!data) { + Stage = "parseData.checkNullData"; + throw new Error("Field `data` is null"); + + } + var dataInfo = regexInfo.exec(data) || regexInfo.exec(data) || regexInfo.exec(data), + dataMods = regexMods.exec(data) || regexMods.exec(data) || regexMods.exec(data), + dataDate = regexDate.exec(data) || regexDate.exec(data) || regexDate.exec(data), + dataPath = regexPath.exec(data) || regexPath.exec(data) || regexPath.exec(data), + match; + console.log("dataInfo:", dataInfo); + console.log("dataMods:", dataMods); + console.log("dataDate:", dataDate); + console.log("dataPath:", dataPath); + Stage = "parseData.doNullCheck"; + if (!dataInfo) + throw new Error("Field `dataInfo` is null"); + if (!dataMods) + throw new Error("Field `dataMods` is null"); + if (!dataPath) + throw new Error("Field `dataPath` is null"); + dataMods = dataMods[0]; + Stage = "parseData.setupDefaults"; + modMap = { + "SMAPI": 0 + }; + modErrors = { + "SMAPI": 0, + "Console.Out": 0 + }; + logInfo = []; + modInfo = [ + ["SMAPI", dataInfo[1], "Zoryn, CLxS & Pathoschild"] + ]; + Stage = "parseData.parseInfo"; + if (dataDate) + var date = new Date(dataDate[1] + "Z"); + versionInfo = [dataInfo[1], dataInfo[2], dataInfo[3], dataDate ? date.getFullYear() + "-" + ("0" + date.getMonth().toString()).substr(-2) + "-" + ("0" + date.getDay().toString()).substr(-2) + " at " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds() + " " + date.toLocaleTimeString('en-us', { timeZoneName: 'short' }).split(' ')[2] : "No timestamp found", dataPath[1]]; + Stage = "parseData.parseMods"; + while (match = regexMod.exec(dataMods)) { + modErrors[match[1]] = 0; + modMap[match[1]] = modInfo.length; + modInfo.push([match[1], match[2], match[3] ? ("by " + match[3]) : "Unknown author"]); + } + Stage = "parseData.parseLog"; + while (match = regexLog.exec(data)) { + if (match[2] == "ERROR") + modErrors[match[3]]++; + logInfo.push([match[1], match[2], match[3], match[4]]); + } + Stage = "parseData.post"; + modMap["Console.Out"] = modInfo.length; + modInfo.push(["Console.Out", "", ""]); + } + + function renderData() { + Stage = "renderData.pre"; + output.html(prepare(templateBody, versionInfo)); + var modslist = $("#modslist"), log = $("#log"), modCache = [], y = 0 + for (; y < modInfo.length; y++) { + var errors = modErrors[modInfo[y][0]], + err, cls = "color-red"; + if (errors == 0) { + err = "No Errors"; + cls = "color-green"; + } else if (errors == 1) + err = "1 Error"; + else + err = errors + " Errors"; + modCache.push(prepare(templateModentry, [y, modInfo[y][0], modInfo[y][1], modInfo[y][2], cls, err])); + } + modslist.append(modCache.join("")); + for (var z = 0; z < modInfo.length; z++) + $("#modlink-" + z).on("click", modClicked); + var flagCache = []; + for (var c = 0; c < modInfo.length; c++) + flagCache.push(prepare(templateCss, [c])); + flags.html(flagCache.join("")); + var logCache = [], dupeCount = 0, dupeMemory = "|||"; + for (var x = 0; x < logInfo.length; x++) { + var dm = logInfo[x][1] + "|" + logInfo[x][2] + "|" + logInfo[x][3]; + if (dupeMemory != dm) { + if (dupeCount > 0) + logCache.push(prepare(templateLognotice, [logInfo[x - 1][1].toLowerCase(), modMap[logInfo[x - 1][2]], dupeCount])); + dupeCount = 0; + dupeMemory = dm; + logCache.push(prepare(templateLogentry, [logInfo[x][1].toLowerCase(), modMap[logInfo[x][2]], logInfo[x][0], logInfo[x][1], logInfo[x][2], logInfo[x][3].split(" ").join("  ").replace(//g, ">").replace(/\n/g, "
")])); + } + else + dupeCount++; + } + log.append(logCache.join("")); + $("#modlink-r").on("click", removeFilter); + $("#modlink-a").on("click", selectAll); + } + + function prepare(str, arr) { + var regex = /\{(\d)\}/g, + match; + while (match = regex.exec(str)) + str = str.replace(match[0], arr[match[1]]); + return str; + } + function loadData() { + try { + Stage = "loadData.Pre"; + var start = performance.now(); + parseData(); + renderData(); + var end = performance.now(); + $(".always").prepend('
Log processed in: ' + (Math.round((end - start) * 100) / 100) + ' ms (View raw)

'); + $("#viewraw").on("click", function() { + $("#dataraw").val($("#input").val()); + $("#popup-raw").fadeIn(); + }) + Stage = "loadData.Post"; + } + catch (err) { + $("#output").html('

Parsing failed!

Parsing of the log failed, details follow.
 

Stage: ' + Stage + '

' + err + '
'); + $("#rawlog").text($("#input").val()); + } + } + function getData() { + $("#uploader").attr("data-text", "Loading..."); + $("#uploader").fadeIn(); + $.get("https://cors-anywhere.herokuapp.com/pastebin.com/raw/" + location.search.substring(1) + "/?nocache=" + Math.random(), function(data, state, xhr) { + if (data.substring(0, 9) == "

Captcha required!

The pastebin server is asking for a captcha, but their API doesnt let us show it to you directly.
Instead, to finish saving the log, you need to solve the captcha in a new tab, once you have done so, reload this page.'); + } + else { + $("#input").val(LZString.decompressFromUTF16(data) || data); + loadData(); + } + $("#uploader").fadeOut(); + }); + } + var Stage, + flags = $("#modflags"), + output = $("#output"), + filters = 0, + memory = "", + versionInfo, + modInfo, + modMap, + modErrors, + logInfo, + templateBody = $("#template-body").text(), + templateModentry = $("#template-modentry").text(), + templateCss = $("#template-css").text(), + templateLogentry = $("#template-logentry").text(), + templateLognotice = $("#template-lognotice").text(), + regexInfo = /\[[\d\:]+ INFO SMAPI] SMAPI (.*?) with Stardew Valley (.*?) on (.*?)\n/g, + regexMods = /\[[^\]]+\] Loaded \d+ mods:(?:\n\[[^\]]+\] .+)+/g, + regexLog = /\[([\d\:]+) (TRACE|DEBUG|INFO|WARN|ALERT|ERROR) ? ([^\]]+)\] ?((?:\n|.)*?)(?=(?:\[\d\d:|$))/g, + regexMod = /\[(?:.*?)\] *(.*?) (\d+\.?(?:.*?))(?: by (.*?))? \|(?:.*?)$/gm, + regexDate = /\[\d{2}:\d{2}:\d{2} TRACE SMAPI\] Log started at (.*?) UTC/g, + regexPath = /\[\d{2}:\d{2}:\d{2} DEBUG SMAPI\] Mods go here: (.*?)(?:\n|$)/g + ; + $("#tabs li:not(.notice)").on("click", function(evt) { + var t = $(evt.currentTarget) + t.toggleClass("active"); + $("#output").toggleClass(t.text().toLowerCase()); + }) + $("#upload").on("click", function() { + memory = $("#input").val() || ""; + $("#input").val(""); + $("#popup-upload").fadeIn(); + }) + var proxies = [ + "https://cors-anywhere.herokuapp.com/", + "https://galvanize-cors-proxy.herokuapp.com/" + ]; + $('#popup-upload').on({ + 'dragover dragenter': function(e) { + e.preventDefault(); + e.stopPropagation(); + }, + 'drop': function(e) { + $("#uploader").attr("data-text", "Reading...") + $("#uploader").show(); + var dataTransfer = e.originalEvent.dataTransfer; + if (dataTransfer && dataTransfer.files.length) { + e.preventDefault(); + e.stopPropagation(); + var file = dataTransfer.files[0]; + var reader = new FileReader(); + reader.onload = $.proxy(function(file, $input, event) { + $input.val(event.target.result); + $("#uploader").fadeOut(); + $("#submit").click(); + }, this, file, $("#input")); + reader.readAsText(file); + } + } + }); + function logSize(id, str) { + console.log(id + ":", str.length * 2, "bytes", Math.round(str.length / 5.12) / 100, "kb"); + } + $("#submit").on("click", function() { + $("#popup-upload").fadeOut(); + if ($("#input").val()) { + memory = ""; + var raw = $("#input").val(); + var paste = LZString.compressToUTF16(raw); + logSize("Raw", raw); + logSize("Compressed", paste); + if (paste.length * 2 > 524288) { + $("#output").html('

Unable to save!

This log cannot be saved due to its size.
' + $("#input").val() + '
'); + return; + } + console.log("paste:", paste); + var packet = { + api_dev_key: "b8219d942109d1e60ebb14fbb45f06f9", + api_option: "paste", + api_paste_private: 1, + api_paste_code: paste, + api_paste_expire_date: "1W" + }; + $("#uploader").attr("data-text", "Saving..."); + $("#uploader").fadeIn(); + var uri = proxies[Math.floor(Math.random() * proxies.length)] + "pastebin.com/api/api_post.php"; + console.log(packet, uri); + $.post(uri, packet, function(data, state, xhr) { + $("#uploader").fadeOut(); + console.log("Result: ", data); + if (data.substring(0, 15) == "Bad API request") + $("#output").html('

Parsing failed!

Parsing of the log failed, details follow.
 

Stage: Upload

Error: ' + data + '
' + $("#input").val() + '
'); + else if (data) + location.href = "?" + data.split('/').pop(); + else + $("#output").html('

Parsing failed!

Parsing of the log failed, details follow.
 

Stage: Upload

Error: Received null response
' + $("#input").val() + '
'); + }) + } else { + alert("Unable to parse log, the input is empty!"); + $("#uploader").fadeOut(); + } + }) + $("#cancel").on("click", function() { + $("#popup-upload").fadeOut(400, function() { + $("#input").val(memory); + memory = ""; + }); + }); + $("#closeraw").on("click", function() { + $("#popup-raw").fadeOut(400); + }) + if (location.search) { + getData(); + } + else + $("#popup-upload").fadeIn(); +}) diff --git a/src/SMAPI.Web/wwwroot/Content/main.css b/src/SMAPI.Web/wwwroot/Content/main.css deleted file mode 100644 index c8ce8d33..00000000 --- a/src/SMAPI.Web/wwwroot/Content/main.css +++ /dev/null @@ -1,107 +0,0 @@ -/* tags */ -html { - height: 100%; -} - -body { - height: 100%; - font-family: sans-serif; -} - -h1, h2, h3 { - font-weight: bold; - margin: 0.2em 0 0.1em 0; - padding-top: .5em; -} - -h1 { - font-size: 1.5em; - color: #888; - margin-bottom: 0; -} - -h2 { - font-size: 1.5em; - border-bottom: 1px solid #AAA; -} - -h3 { - font-size: 1.2em; - border-bottom: 1px solid #AAA; - width: 50%; -} - -a { - color: #006; -} - -/* content */ -#content-column { - position: absolute; - top: 1em; - left: 10em; -} - -#content { - min-height: 140px; - padding: 0 1em 1em 1em; - border-left: 1px solid #CCC; - background: #FFF; - font-size: 0.9em; -} - -#content p { - max-width: 55em; -} - -.section { - border: 1px solid #CCC; - padding: 0.5em; - margin-bottom: 1em; -} - -/* sidebar */ -#sidebar { - margin-top: 3em; - min-height: 75%; - width: 12em; - background: url("sidebar-bg.gif") no-repeat top right; - color: #666; -} - -#sidebar h4 { - margin: 0 0 0.2em 0; - width: 10em; - border-bottom: 1px solid #CCC; - font-size: 0.8em; - font-weight: normal; -} - -#sidebar a { - color: #77B; - border: 0; -} - -#sidebar ul, #sidebar li { - margin: 0; - padding: 0; - list-style: none none; - font-size: 0.9em; - color: #888; -} - -#sidebar li { - margin-left: 1em; -} - -/* footer */ -#footer { - margin: 1em; - padding: 1em; - font-size: 0.6em; - color: gray; -} - -#footer a { - color: #669; -} diff --git a/src/SMAPI.Web/wwwroot/Content/sidebar-bg.gif b/src/SMAPI.Web/wwwroot/Content/sidebar-bg.gif deleted file mode 100644 index 48e9af5a..00000000 Binary files a/src/SMAPI.Web/wwwroot/Content/sidebar-bg.gif and /dev/null differ -- cgit From 467b9aa2df8532aa3cb94c84307c7012573d61d4 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 27 Oct 2017 19:38:37 -0400 Subject: integrate prototype into page layout (#358) --- src/SMAPI.Web/wwwroot/Content/css/log-parser.css | 77 ++++++++---------------- src/SMAPI.Web/wwwroot/Content/js/log-parser.js | 2 +- 2 files changed, 27 insertions(+), 52 deletions(-) (limited to 'src/SMAPI.Web/wwwroot') diff --git a/src/SMAPI.Web/wwwroot/Content/css/log-parser.css b/src/SMAPI.Web/wwwroot/Content/css/log-parser.css index 0aff5b81..afa79a65 100644 --- a/src/SMAPI.Web/wwwroot/Content/css/log-parser.css +++ b/src/SMAPI.Web/wwwroot/Content/css/log-parser.css @@ -1,16 +1,7 @@ -body { - font-size: 10pt; - background: #fff; -} - .mod-repeat { font-size: 8pt; } -input[type="button"] { - cursor: pointer; -} - .template { display: none; } @@ -27,6 +18,16 @@ input[type="button"] { padding: 5px; } +#upload-button { + background: #ccf; + border: 1px solid #000088; +} + +#upload-button { + background: #eef; +} + + #uploader:after { content: attr(data-text); display: block; @@ -58,50 +59,45 @@ input[type="button"] { font-family: sans-serif; font-size: 40px; margin-top: -25px; + z-index: 10; + border-bottom: 0; } .frame { margin: auto; margin-top: 25px; + padding: 2em; position: absolute; top: 10%; left: 10%; right: 10%; bottom: 10%; padding-bottom: 30px; -} - -.buttons { - position: absolute; - display: inline-block; - bottom: -10px; - right: 0px; - padding: 5px; - border: 1px solid #008; + background: #FFF; border-radius: 5px; - background: #fff; + border: 1px solid #008; } -#cancel, #closeraw { +input[type="button"] { font-size: 20px; border-radius: 5px; - border: 1px solid #880000; - background-color: #fcc; outline: none; box-shadow: inset 0px 0px 1px 1px rgba(0, 0, 0, .2); + cursor: pointer; } -#cancel:hover, #closeraw:hover { +#input[type="button"]:hover { background-color: #fee; } +#cancel, #closeraw { + border: 1px solid #880000; + background-color: #fcc; +} + #submit { - font-size: 20px; - border-radius: 5px; border: 1px solid #008800; background-color: #cfc; - outline: none; - box-shadow: inset 0px 0px 1px 1px rgba(0, 0, 0, .2); } #submit:hover { @@ -109,9 +105,9 @@ input[type="button"] { } #input, #dataraw { - width: 100%; - height: 100%; - max-width: 100%; + width: 80%; + height: 30em; + max-width: 80%; max-height: 100%; margin: auto; box-sizing: border-box; @@ -130,12 +126,8 @@ input[type="button"] { } #tabs { - top: 0px; - left: 0px; - right: 0px; border-bottom: 0; display: block; - position: fixed; margin: 0; padding: 0; background: linear-gradient(to bottom, rgba(255, 255, 255, 1) 0%, rgba(210, 235, 249, 1) 100%); @@ -144,7 +136,6 @@ input[type="button"] { #tabs li { margin: 5px 1px 0 0; height: 25px; - float: left; display: inline-block; width: 75px; border: 1px solid #000000; @@ -179,17 +170,6 @@ input[type="button"] { background: #efe; } -#tabs li.upload { - float: right; - background: #ccf; - border-color: #000088; - margin-right: 5px; -} - -#tabs li.upload:hover { - background: #eef; -} - #tabs li.notice { color: #000000; background: transparent; @@ -206,11 +186,6 @@ input[type="button"] { #output { border-top: 1px solid #888; - position: fixed; - top: 30px; - left: 0px; - right: 0px; - bottom: 0px; padding: 10px; overflow: auto; font-family: monospace; diff --git a/src/SMAPI.Web/wwwroot/Content/js/log-parser.js b/src/SMAPI.Web/wwwroot/Content/js/log-parser.js index 2d095787..a1d07a78 100644 --- a/src/SMAPI.Web/wwwroot/Content/js/log-parser.js +++ b/src/SMAPI.Web/wwwroot/Content/js/log-parser.js @@ -196,7 +196,7 @@ $(function() { t.toggleClass("active"); $("#output").toggleClass(t.text().toLowerCase()); }) - $("#upload").on("click", function() { + $("#upload-button").on("click", function() { memory = $("#input").val() || ""; $("#input").val(""); $("#popup-upload").fadeIn(); -- cgit From acbea9bfa33655048673a2292350aedb1d05a09a Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 27 Oct 2017 19:38:56 -0400 Subject: lint JS (#358) --- src/SMAPI.Web/wwwroot/Content/js/log-parser.js | 303 +++++++++++++------------ 1 file changed, 157 insertions(+), 146 deletions(-) (limited to 'src/SMAPI.Web/wwwroot') diff --git a/src/SMAPI.Web/wwwroot/Content/js/log-parser.js b/src/SMAPI.Web/wwwroot/Content/js/log-parser.js index a1d07a78..4597392c 100644 --- a/src/SMAPI.Web/wwwroot/Content/js/log-parser.js +++ b/src/SMAPI.Web/wwwroot/Content/js/log-parser.js @@ -1,13 +1,140 @@ +/* globals $, LZString */ + $(function() { + /********* + ** Initialisation + *********/ + var stage, + flags = $("#modflags"), + output = $("#output"), + filters = 0, + memory = "", + versionInfo, + modInfo, + modMap, + modErrors, + logInfo, + templateBody = $("#template-body").text(), + templateModentry = $("#template-modentry").text(), + templateCss = $("#template-css").text(), + templateLogentry = $("#template-logentry").text(), + templateLognotice = $("#template-lognotice").text(), + regexInfo = /\[[\d\:]+ INFO SMAPI] SMAPI (.*?) with Stardew Valley (.*?) on (.*?)\n/g, + regexMods = /\[[^\]]+\] Loaded \d+ mods:(?:\n\[[^\]]+\] .+)+/g, + regexLog = /\[([\d\:]+) (TRACE|DEBUG|INFO|WARN|ALERT|ERROR) ? ([^\]]+)\] ?((?:\n|.)*?)(?=(?:\[\d\d:|$))/g, + regexMod = /\[(?:.*?)\] *(.*?) (\d+\.?(?:.*?))(?: by (.*?))? \|(?:.*?)$/gm, + regexDate = /\[\d{2}:\d{2}:\d{2} TRACE SMAPI\] Log started at (.*?) UTC/g, + regexPath = /\[\d{2}:\d{2}:\d{2} DEBUG SMAPI\] Mods go here: (.*?)(?:\n|$)/g; + + $("#tabs li:not(.notice)").on("click", function(evt) { + var t = $(evt.currentTarget); + t.toggleClass("active"); + $("#output").toggleClass(t.text().toLowerCase()); + }); + $("#upload-button").on("click", function() { + memory = $("#input").val() || ""; + $("#input").val(""); + $("#popup-upload").fadeIn(); + }); + var proxies = [ + "https://cors-anywhere.herokuapp.com/", + "https://galvanize-cors-proxy.herokuapp.com/" + ]; + $("#popup-upload").on({ + 'dragover dragenter': function(e) { + e.preventDefault(); + e.stopPropagation(); + }, + 'drop': function(e) { + $("#uploader").attr("data-text", "Reading..."); + $("#uploader").show(); + var dataTransfer = e.originalEvent.dataTransfer; + if (dataTransfer && dataTransfer.files.length) { + e.preventDefault(); + e.stopPropagation(); + var file = dataTransfer.files[0]; + var reader = new FileReader(); + reader.onload = $.proxy(function(file, $input, event) { + $input.val(event.target.result); + $("#uploader").fadeOut(); + $("#submit").click(); + }, this, file, $("#input")); + reader.readAsText(file); + } + } + }); + + $("#submit").on("click", function() { + $("#popup-upload").fadeOut(); + if ($("#input").val()) { + memory = ""; + var raw = $("#input").val(); + var paste = LZString.compressToUTF16(raw); + logSize("Raw", raw); + logSize("Compressed", paste); + if (paste.length * 2 > 524288) { + $("#output").html('

Unable to save!

This log cannot be saved due to its size.
' + $("#input").val() + "
"); + return; + } + console.log("paste:", paste); + var packet = { + api_dev_key: "b8219d942109d1e60ebb14fbb45f06f9", + api_option: "paste", + api_paste_private: 1, + api_paste_code: paste, + api_paste_expire_date: "1W" + }; + $("#uploader").attr("data-text", "Saving..."); + $("#uploader").fadeIn(); + var uri = proxies[Math.floor(Math.random() * proxies.length)] + "pastebin.com/api/api_post.php"; + console.log(packet, uri); + $.post(uri, packet, function(data) { + $("#uploader").fadeOut(); + console.log("Result: ", data); + if (data.substring(0, 15) === "Bad API request") + $("#output").html('

Parsing failed!

Parsing of the log failed, details follow.
 

Stage: Upload

Error: ' + data + "
" + $("#input").val() + "
"); + else if (data) + location.href = "?" + data.split("/").pop(); + else + $("#output").html('

Parsing failed!

Parsing of the log failed, details follow.
 

Stage: Upload

Error: Received null response
' + $("#input").val() + "
"); + }); + } else { + alert("Unable to parse log, the input is empty!"); + $("#uploader").fadeOut(); + } + }); + $("#cancel").on("click", function() { + $("#popup-upload").fadeOut(400, function() { + $("#input").val(memory); + memory = ""; + }); + }); + $("#closeraw").on("click", function() { + $("#popup-raw").fadeOut(400); + }); + if (location.search) { + getData(); + } + else + $("#popup-upload").fadeIn(); + + + /********* + ** Helpers + *********/ + function logSize(id, str) { + console.log(id + ":", str.length * 2, "bytes", Math.round(str.length / 5.12) / 100, "kb"); + } + function modClicked(evt) { - var id = $(evt.currentTarget).attr("id").split('-')[1], - cls = "mod-" + id;; + var id = $(evt.currentTarget).attr("id").split("-")[1], + cls = "mod-" + id; if (output.hasClass(cls)) filters--; else filters++; output.toggleClass(cls); - if (filters == 0) { + if (filters === 0) { output.removeClass("modfilter"); } else { output.addClass("modfilter"); @@ -31,10 +158,10 @@ $(function() { } function parseData() { - Stage = "parseData.pre"; + stage = "parseData.pre"; var data = $("#input").val(); if (!data) { - Stage = "parseData.checkNullData"; + stage = "parseData.checkNullData"; throw new Error("Field `data` is null"); } @@ -47,7 +174,7 @@ $(function() { console.log("dataMods:", dataMods); console.log("dataDate:", dataDate); console.log("dataPath:", dataPath); - Stage = "parseData.doNullCheck"; + stage = "parseData.doNullCheck"; if (!dataInfo) throw new Error("Field `dataInfo` is null"); if (!dataMods) @@ -55,7 +182,7 @@ $(function() { if (!dataPath) throw new Error("Field `dataPath` is null"); dataMods = dataMods[0]; - Stage = "parseData.setupDefaults"; + stage = "parseData.setupDefaults"; modMap = { "SMAPI": 0 }; @@ -67,38 +194,37 @@ $(function() { modInfo = [ ["SMAPI", dataInfo[1], "Zoryn, CLxS & Pathoschild"] ]; - Stage = "parseData.parseInfo"; - if (dataDate) - var date = new Date(dataDate[1] + "Z"); - versionInfo = [dataInfo[1], dataInfo[2], dataInfo[3], dataDate ? date.getFullYear() + "-" + ("0" + date.getMonth().toString()).substr(-2) + "-" + ("0" + date.getDay().toString()).substr(-2) + " at " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds() + " " + date.toLocaleTimeString('en-us', { timeZoneName: 'short' }).split(' ')[2] : "No timestamp found", dataPath[1]]; - Stage = "parseData.parseMods"; - while (match = regexMod.exec(dataMods)) { + stage = "parseData.parseInfo"; + var date = dataDate ? new Date(dataDate[1] + "Z") : null; + versionInfo = [dataInfo[1], dataInfo[2], dataInfo[3], date ? date.getFullYear() + "-" + ("0" + date.getMonth().toString()).substr(-2) + "-" + ("0" + date.getDay().toString()).substr(-2) + " at " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds() + " " + date.toLocaleTimeString("en-us", { timeZoneName: "short" }).split(" ")[2] : "No timestamp found", dataPath[1]]; + stage = "parseData.parseMods"; + while ((match = regexMod.exec(dataMods))) { modErrors[match[1]] = 0; modMap[match[1]] = modInfo.length; modInfo.push([match[1], match[2], match[3] ? ("by " + match[3]) : "Unknown author"]); } - Stage = "parseData.parseLog"; - while (match = regexLog.exec(data)) { - if (match[2] == "ERROR") + stage = "parseData.parseLog"; + while ((match = regexLog.exec(data))) { + if (match[2] === "ERROR") modErrors[match[3]]++; logInfo.push([match[1], match[2], match[3], match[4]]); } - Stage = "parseData.post"; + stage = "parseData.post"; modMap["Console.Out"] = modInfo.length; modInfo.push(["Console.Out", "", ""]); } function renderData() { - Stage = "renderData.pre"; + stage = "renderData.pre"; output.html(prepare(templateBody, versionInfo)); - var modslist = $("#modslist"), log = $("#log"), modCache = [], y = 0 + var modslist = $("#modslist"), log = $("#log"), modCache = [], y = 0; for (; y < modInfo.length; y++) { var errors = modErrors[modInfo[y][0]], err, cls = "color-red"; - if (errors == 0) { + if (errors === 0) { err = "No Errors"; cls = "color-green"; - } else if (errors == 1) + } else if (errors === 1) err = "1 Error"; else err = errors + " Errors"; @@ -114,7 +240,7 @@ $(function() { var logCache = [], dupeCount = 0, dupeMemory = "|||"; for (var x = 0; x < logInfo.length; x++) { var dm = logInfo[x][1] + "|" + logInfo[x][2] + "|" + logInfo[x][3]; - if (dupeMemory != dm) { + if (dupeMemory !== dm) { if (dupeCount > 0) logCache.push(prepare(templateLognotice, [logInfo[x - 1][1].toLowerCase(), modMap[logInfo[x - 1][2]], dupeCount])); dupeCount = 0; @@ -132,34 +258,34 @@ $(function() { function prepare(str, arr) { var regex = /\{(\d)\}/g, match; - while (match = regex.exec(str)) + while ((match = regex.exec(str))) str = str.replace(match[0], arr[match[1]]); return str; } function loadData() { try { - Stage = "loadData.Pre"; + stage = "loadData.Pre"; var start = performance.now(); parseData(); renderData(); var end = performance.now(); - $(".always").prepend('
Log processed in: ' + (Math.round((end - start) * 100) / 100) + ' ms (View raw)

'); + $(".always").prepend("
Log processed in: " + (Math.round((end - start) * 100) / 100) + ' ms (View raw)

'); $("#viewraw").on("click", function() { $("#dataraw").val($("#input").val()); $("#popup-raw").fadeIn(); - }) - Stage = "loadData.Post"; + }); + stage = "loadData.Post"; } catch (err) { - $("#output").html('

Parsing failed!

Parsing of the log failed, details follow.
 

Stage: ' + Stage + '

' + err + '
'); + $("#output").html('

Parsing failed!

Parsing of the log failed, details follow.
 

Stage: ' + stage + "

" + err + '
'); $("#rawlog").text($("#input").val()); } } function getData() { $("#uploader").attr("data-text", "Loading..."); $("#uploader").fadeIn(); - $.get("https://cors-anywhere.herokuapp.com/pastebin.com/raw/" + location.search.substring(1) + "/?nocache=" + Math.random(), function(data, state, xhr) { - if (data.substring(0, 9) == "

Captcha required!

The pastebin server is asking for a captcha, but their API doesnt let us show it to you directly.
Instead, to finish saving the log, you need to solve the captcha in a new tab, once you have done so, reload this page.'); } else { @@ -169,119 +295,4 @@ $(function() { $("#uploader").fadeOut(); }); } - var Stage, - flags = $("#modflags"), - output = $("#output"), - filters = 0, - memory = "", - versionInfo, - modInfo, - modMap, - modErrors, - logInfo, - templateBody = $("#template-body").text(), - templateModentry = $("#template-modentry").text(), - templateCss = $("#template-css").text(), - templateLogentry = $("#template-logentry").text(), - templateLognotice = $("#template-lognotice").text(), - regexInfo = /\[[\d\:]+ INFO SMAPI] SMAPI (.*?) with Stardew Valley (.*?) on (.*?)\n/g, - regexMods = /\[[^\]]+\] Loaded \d+ mods:(?:\n\[[^\]]+\] .+)+/g, - regexLog = /\[([\d\:]+) (TRACE|DEBUG|INFO|WARN|ALERT|ERROR) ? ([^\]]+)\] ?((?:\n|.)*?)(?=(?:\[\d\d:|$))/g, - regexMod = /\[(?:.*?)\] *(.*?) (\d+\.?(?:.*?))(?: by (.*?))? \|(?:.*?)$/gm, - regexDate = /\[\d{2}:\d{2}:\d{2} TRACE SMAPI\] Log started at (.*?) UTC/g, - regexPath = /\[\d{2}:\d{2}:\d{2} DEBUG SMAPI\] Mods go here: (.*?)(?:\n|$)/g - ; - $("#tabs li:not(.notice)").on("click", function(evt) { - var t = $(evt.currentTarget) - t.toggleClass("active"); - $("#output").toggleClass(t.text().toLowerCase()); - }) - $("#upload-button").on("click", function() { - memory = $("#input").val() || ""; - $("#input").val(""); - $("#popup-upload").fadeIn(); - }) - var proxies = [ - "https://cors-anywhere.herokuapp.com/", - "https://galvanize-cors-proxy.herokuapp.com/" - ]; - $('#popup-upload').on({ - 'dragover dragenter': function(e) { - e.preventDefault(); - e.stopPropagation(); - }, - 'drop': function(e) { - $("#uploader").attr("data-text", "Reading...") - $("#uploader").show(); - var dataTransfer = e.originalEvent.dataTransfer; - if (dataTransfer && dataTransfer.files.length) { - e.preventDefault(); - e.stopPropagation(); - var file = dataTransfer.files[0]; - var reader = new FileReader(); - reader.onload = $.proxy(function(file, $input, event) { - $input.val(event.target.result); - $("#uploader").fadeOut(); - $("#submit").click(); - }, this, file, $("#input")); - reader.readAsText(file); - } - } - }); - function logSize(id, str) { - console.log(id + ":", str.length * 2, "bytes", Math.round(str.length / 5.12) / 100, "kb"); - } - $("#submit").on("click", function() { - $("#popup-upload").fadeOut(); - if ($("#input").val()) { - memory = ""; - var raw = $("#input").val(); - var paste = LZString.compressToUTF16(raw); - logSize("Raw", raw); - logSize("Compressed", paste); - if (paste.length * 2 > 524288) { - $("#output").html('

Unable to save!

This log cannot be saved due to its size.
' + $("#input").val() + '
'); - return; - } - console.log("paste:", paste); - var packet = { - api_dev_key: "b8219d942109d1e60ebb14fbb45f06f9", - api_option: "paste", - api_paste_private: 1, - api_paste_code: paste, - api_paste_expire_date: "1W" - }; - $("#uploader").attr("data-text", "Saving..."); - $("#uploader").fadeIn(); - var uri = proxies[Math.floor(Math.random() * proxies.length)] + "pastebin.com/api/api_post.php"; - console.log(packet, uri); - $.post(uri, packet, function(data, state, xhr) { - $("#uploader").fadeOut(); - console.log("Result: ", data); - if (data.substring(0, 15) == "Bad API request") - $("#output").html('

Parsing failed!

Parsing of the log failed, details follow.
 

Stage: Upload

Error: ' + data + '
' + $("#input").val() + '
'); - else if (data) - location.href = "?" + data.split('/').pop(); - else - $("#output").html('

Parsing failed!

Parsing of the log failed, details follow.
 

Stage: Upload

Error: Received null response
' + $("#input").val() + '
'); - }) - } else { - alert("Unable to parse log, the input is empty!"); - $("#uploader").fadeOut(); - } - }) - $("#cancel").on("click", function() { - $("#popup-upload").fadeOut(400, function() { - $("#input").val(memory); - memory = ""; - }); - }); - $("#closeraw").on("click", function() { - $("#popup-raw").fadeOut(400); - }) - if (location.search) { - getData(); - } - else - $("#popup-upload").fadeIn(); -}) +}); -- cgit From ad5bb5b49af49c4668fd30fb2a0e606dcefe4ec0 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 27 Oct 2017 19:39:13 -0400 Subject: proxy Pastebin requests through our API instead of third parties, improve error-handling (#358) --- src/SMAPI.Web/wwwroot/Content/js/log-parser.js | 65 +++++++++++--------------- 1 file changed, 27 insertions(+), 38 deletions(-) (limited to 'src/SMAPI.Web/wwwroot') diff --git a/src/SMAPI.Web/wwwroot/Content/js/log-parser.js b/src/SMAPI.Web/wwwroot/Content/js/log-parser.js index 4597392c..b1f8f5c6 100644 --- a/src/SMAPI.Web/wwwroot/Content/js/log-parser.js +++ b/src/SMAPI.Web/wwwroot/Content/js/log-parser.js @@ -36,10 +36,6 @@ $(function() { $("#input").val(""); $("#popup-upload").fadeIn(); }); - var proxies = [ - "https://cors-anywhere.herokuapp.com/", - "https://galvanize-cors-proxy.herokuapp.com/" - ]; $("#popup-upload").on({ 'dragover dragenter': function(e) { e.preventDefault(); @@ -66,38 +62,35 @@ $(function() { $("#submit").on("click", function() { $("#popup-upload").fadeOut(); - if ($("#input").val()) { + var raw = $("#input").val(); + if (raw) { memory = ""; - var raw = $("#input").val(); var paste = LZString.compressToUTF16(raw); - logSize("Raw", raw); - logSize("Compressed", paste); if (paste.length * 2 > 524288) { $("#output").html('

Unable to save!

This log cannot be saved due to its size.
' + $("#input").val() + "
"); return; } - console.log("paste:", paste); - var packet = { - api_dev_key: "b8219d942109d1e60ebb14fbb45f06f9", - api_option: "paste", - api_paste_private: 1, - api_paste_code: paste, - api_paste_expire_date: "1W" - }; $("#uploader").attr("data-text", "Saving..."); $("#uploader").fadeIn(); - var uri = proxies[Math.floor(Math.random() * proxies.length)] + "pastebin.com/api/api_post.php"; - console.log(packet, uri); - $.post(uri, packet, function(data) { - $("#uploader").fadeOut(); - console.log("Result: ", data); - if (data.substring(0, 15) === "Bad API request") - $("#output").html('

Parsing failed!

Parsing of the log failed, details follow.
 

Stage: Upload

Error: ' + data + "
" + $("#input").val() + "
"); - else if (data) - location.href = "?" + data.split("/").pop(); - else - $("#output").html('

Parsing failed!

Parsing of the log failed, details follow.
 

Stage: Upload

Error: Received null response
' + $("#input").val() + "
"); - }); + $ + .ajax({ + type: "POST", + url: "/log/save", + data: JSON.stringify(paste), + contentType: "application/json" // sent to API + }) + .fail(function(xhr, textStatus) { + $("#uploader").fadeOut(); + $("#output").html('

Parsing failed!

Parsing of the log failed, details follow.
 

Stage: Upload

Error: ' + textStatus + ': ' + xhr.responseText + "
" + $("#input").val() + "
"); + }) + .then(function(data) { + $("#uploader").fadeOut(); + console.log("Result: ", data); + if (!data.success) + $("#output").html('

Parsing failed!

Parsing of the log failed, details follow.
 

Stage: Upload

Error: ' + data.error + "
" + $("#input").val() + "
"); + else + location.href = "?" + data.id; + }); } else { alert("Unable to parse log, the input is empty!"); $("#uploader").fadeOut(); @@ -122,10 +115,6 @@ $(function() { /********* ** Helpers *********/ - function logSize(id, str) { - console.log(id + ":", str.length * 2, "bytes", Math.round(str.length / 5.12) / 100, "kb"); - } - function modClicked(evt) { var id = $(evt.currentTarget).attr("id").split("-")[1], cls = "mod-" + id; @@ -284,13 +273,13 @@ $(function() { function getData() { $("#uploader").attr("data-text", "Loading..."); $("#uploader").fadeIn(); - $.get("https://cors-anywhere.herokuapp.com/pastebin.com/raw/" + location.search.substring(1) + "/?nocache=" + Math.random(), function(data) { - if (data.substring(0, 9) === "

Captcha required!

The pastebin server is asking for a captcha, but their API doesnt let us show it to you directly.
Instead, to finish saving the log, you need to solve the captcha in a new tab, once you have done so, reload this page.'); - } - else { - $("#input").val(LZString.decompressFromUTF16(data) || data); + $.get("/log/fetch/" + location.search.substring(1), function(data) { + if (data.success) { + $("#input").val(LZString.decompressFromUTF16(data.content) || data.content); loadData(); + } else { + $("#output").html('

Fetching the log failed!

' + data.error + '

'); + $("#rawlog").text($("#input").val()); } $("#uploader").fadeOut(); }); -- cgit From 3f43ebcc0e31db523fa82a163374cebf2f577cde Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 27 Oct 2017 21:10:36 -0400 Subject: fix issues with subdomain routing in log UI (#358) --- src/SMAPI.Web/wwwroot/Content/js/log-parser.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/SMAPI.Web/wwwroot') diff --git a/src/SMAPI.Web/wwwroot/Content/js/log-parser.js b/src/SMAPI.Web/wwwroot/Content/js/log-parser.js index b1f8f5c6..3949fabe 100644 --- a/src/SMAPI.Web/wwwroot/Content/js/log-parser.js +++ b/src/SMAPI.Web/wwwroot/Content/js/log-parser.js @@ -1,6 +1,7 @@ /* globals $, LZString */ -$(function() { +var smapi = smapi || {}; +smapi.logParser = function(sectionUrl) { /********* ** Initialisation *********/ @@ -75,7 +76,7 @@ $(function() { $ .ajax({ type: "POST", - url: "/log/save", + url: sectionUrl + "/save", data: JSON.stringify(paste), contentType: "application/json" // sent to API }) @@ -273,7 +274,7 @@ $(function() { function getData() { $("#uploader").attr("data-text", "Loading..."); $("#uploader").fadeIn(); - $.get("/log/fetch/" + location.search.substring(1), function(data) { + $.get(sectionUrl + "/fetch/" + location.search.substring(1), function(data) { if (data.success) { $("#input").val(LZString.decompressFromUTF16(data.content) || data.content); loadData(); @@ -284,4 +285,4 @@ $(function() { $("#uploader").fadeOut(); }); } -}); +}; -- cgit From fe5b2f62da27ac0e2ddf60240f2b19cf2a404f69 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 28 Oct 2017 12:38:30 -0400 Subject: prettify log URL, read paste ID serverside (#358) --- src/SMAPI.Web/wwwroot/Content/js/log-parser.js | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) (limited to 'src/SMAPI.Web/wwwroot') diff --git a/src/SMAPI.Web/wwwroot/Content/js/log-parser.js b/src/SMAPI.Web/wwwroot/Content/js/log-parser.js index 3949fabe..904ca691 100644 --- a/src/SMAPI.Web/wwwroot/Content/js/log-parser.js +++ b/src/SMAPI.Web/wwwroot/Content/js/log-parser.js @@ -1,7 +1,7 @@ /* globals $, LZString */ var smapi = smapi || {}; -smapi.logParser = function(sectionUrl) { +smapi.logParser = function(sectionUrl, pasteID) { /********* ** Initialisation *********/ @@ -86,11 +86,10 @@ smapi.logParser = function(sectionUrl) { }) .then(function(data) { $("#uploader").fadeOut(); - console.log("Result: ", data); if (!data.success) $("#output").html('

Parsing failed!

Parsing of the log failed, details follow.
 

Stage: Upload

Error: ' + data.error + "
" + $("#input").val() + "
"); else - location.href = "?" + data.id; + location.href = (sectionUrl.replace(/\/$/, "") + "/" + data.id); }); } else { alert("Unable to parse log, the input is empty!"); @@ -106,8 +105,8 @@ smapi.logParser = function(sectionUrl) { $("#closeraw").on("click", function() { $("#popup-raw").fadeOut(400); }); - if (location.search) { - getData(); + if (pasteID) { + getData(pasteID); } else $("#popup-upload").fadeIn(); @@ -160,10 +159,6 @@ smapi.logParser = function(sectionUrl) { dataDate = regexDate.exec(data) || regexDate.exec(data) || regexDate.exec(data), dataPath = regexPath.exec(data) || regexPath.exec(data) || regexPath.exec(data), match; - console.log("dataInfo:", dataInfo); - console.log("dataMods:", dataMods); - console.log("dataDate:", dataDate); - console.log("dataPath:", dataPath); stage = "parseData.doNullCheck"; if (!dataInfo) throw new Error("Field `dataInfo` is null"); @@ -267,19 +262,19 @@ smapi.logParser = function(sectionUrl) { stage = "loadData.Post"; } catch (err) { - $("#output").html('

Parsing failed!

Parsing of the log failed, details follow.
 

Stage: ' + stage + "

" + err + '
'); + $("#output").html('

Parsing failed!

Parsing of the log failed, details follow.
 

Stage: ' + stage + "

" + err + '
'); $("#rawlog").text($("#input").val()); } } - function getData() { + function getData(pasteID) { $("#uploader").attr("data-text", "Loading..."); $("#uploader").fadeIn(); - $.get(sectionUrl + "/fetch/" + location.search.substring(1), function(data) { + $.get(sectionUrl + "/fetch/" + pasteID, function(data) { if (data.success) { $("#input").val(LZString.decompressFromUTF16(data.content) || data.content); loadData(); } else { - $("#output").html('

Fetching the log failed!

' + data.error + '

'); + $("#output").html('

Fetching the log failed!

' + data.error + '

'); $("#rawlog").text($("#input").val()); } $("#uploader").fadeOut(); -- cgit From 0f08980d45ca7a6ea820d2b7acd453087da0371c Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 29 Oct 2017 13:23:08 -0400 Subject: fix error log format (#358) --- src/SMAPI.Web/wwwroot/Content/js/log-parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/SMAPI.Web/wwwroot') diff --git a/src/SMAPI.Web/wwwroot/Content/js/log-parser.js b/src/SMAPI.Web/wwwroot/Content/js/log-parser.js index 904ca691..498fb335 100644 --- a/src/SMAPI.Web/wwwroot/Content/js/log-parser.js +++ b/src/SMAPI.Web/wwwroot/Content/js/log-parser.js @@ -82,7 +82,7 @@ smapi.logParser = function(sectionUrl, pasteID) { }) .fail(function(xhr, textStatus) { $("#uploader").fadeOut(); - $("#output").html('

Parsing failed!

Parsing of the log failed, details follow.
 

Stage: Upload

Error: ' + textStatus + ': ' + xhr.responseText + "
" + $("#input").val() + "
"); + $("#output").html('

Parsing failed!

Parsing of the log failed, details follow.
 

Stage: Upload

Error: ' + textStatus + ': ' + xhr.responseText + "
" + $("#input").val() + "
"); }) .then(function(data) { $("#uploader").fadeOut(); -- cgit From 7ed1fbf0aac5a3b777e3ed5b8f104bd27ce4bf0c Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 29 Oct 2017 15:28:07 -0400 Subject: defer log compression to backend and significantly improve compression (#358) --- src/SMAPI.Web/wwwroot/Content/js/log-parser.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'src/SMAPI.Web/wwwroot') diff --git a/src/SMAPI.Web/wwwroot/Content/js/log-parser.js b/src/SMAPI.Web/wwwroot/Content/js/log-parser.js index 498fb335..8e30ae12 100644 --- a/src/SMAPI.Web/wwwroot/Content/js/log-parser.js +++ b/src/SMAPI.Web/wwwroot/Content/js/log-parser.js @@ -1,4 +1,4 @@ -/* globals $, LZString */ +/* globals $ */ var smapi = smapi || {}; smapi.logParser = function(sectionUrl, pasteID) { @@ -63,14 +63,9 @@ smapi.logParser = function(sectionUrl, pasteID) { $("#submit").on("click", function() { $("#popup-upload").fadeOut(); - var raw = $("#input").val(); - if (raw) { + var paste = $("#input").val(); + if (paste) {