parser working. meta display partial-working

master
Avril 4 years ago
parent 6493f70816
commit fc7782a11b
Signed by: flanchan
GPG Key ID: 284488987C31F630

2
.gitignore vendored

@ -1 +1,3 @@
node_modules/
package-lock.json
git_modules/

@ -0,0 +1,5 @@
npm install line-navigator --save
mkdir git_modules
cd git_modules
git clone https://github.com/brillout/forge-sha256/

@ -116,4 +116,36 @@ blockquote {
right: 5px;
white-space: nowrap;
position: fixed;
overflow-y: auto;
z-index: 100;
}
.warning {
color: yellow !important;
}
.warning:before {
content: "!";
color: red;
margin-right: 5px;
font-weight: bolder;
transition: color 1s;
}
.warning:hover:before {
color: white;
}
.metadata {
color: white;
}
.metadata .overlap {
color: orange !important;
text-decoration: underline;
}
.meta-dupe {
color: orange !important;
}

@ -1,43 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="41.756px" height="41.756px" viewBox="0 0 41.756 41.756" style="enable-background:new 0 0 41.756 41.756;"
xml:space="preserve">
<g>
<path d="M27.948,20.878L40.291,8.536c1.953-1.953,1.953-5.119,0-7.071c-1.951-1.952-5.119-1.952-7.07,0L20.878,13.809L8.535,1.465
c-1.951-1.952-5.119-1.952-7.07,0c-1.953,1.953-1.953,5.119,0,7.071l12.342,12.342L1.465,33.22c-1.953,1.953-1.953,5.119,0,7.071
C2.44,41.268,3.721,41.755,5,41.755c1.278,0,2.56-0.487,3.535-1.464l12.343-12.342l12.343,12.343
c0.976,0.977,2.256,1.464,3.535,1.464s2.56-0.487,3.535-1.464c1.953-1.953,1.953-5.119,0-7.071L27.948,20.878z"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

@ -3,6 +3,7 @@
<link rel='stylesheet' type='text/css' href='css/main.css'></link>
<script src='js/vendor/file-wrapper.min.js'></script>
<script src='js/vendor/line-navigator.min.js'></script>
<script src='js/vendor/forge-sha256.min.js'></script>
<script src='js/stage.js'></script>
<script src='js/util.js'></script>
@ -21,10 +22,10 @@
<div class='page'>
<b>Select .osu files</b>
<div id='selector'>
<div id='_file1' data-index='0' class='osufile' onclick='_removeFile("_file1")'>test</div>
<div id='_file2' data-index='0' class='osufile' onclick='_removeFile("_file2")'>test2</div>
<!-- <div id='_file1' data-index='0' class='osufile warning' title='Warning: Already added!' onclick='_removeFile("_file1")'>test</div>
<div id='_file2' data-index='0' class='osufile' onclick='_removeFile("_file2")'>test2</div> -->
</div>
Upload file: <input type='file' accept='text/plain' onchange='_readfile(event)'></input>
Upload file: <input type='file' onchange='_readfile(event)'></input>
</div>
<div class='page' id='metadata'>
<div style='display:inline-block; width: 100%;'>
@ -56,7 +57,7 @@
</header>
<blockquote>
<div>Title: <span class='metadata' id='meta-title'></span></div>
<div>Title (Raomanised): <span class='metadata' id='meta-title-ascii'></span></div>
<div>Title (Romanised): <span class='metadata' id='meta-title-ascii'></span></div>
<div>Artist: <span class='metadata' id='meta-artist'></span></div>
<div>Artist (Romanised): <span class='metadata' id='meta-artist-ascii'></span></div>
<div>Mapper: <span class='metadata' id='meta-mapper'></span></div>
@ -67,9 +68,32 @@
<div>Set ID: <span class='metadata' id='meta-beatmap-set-id'></span></div>
</blockquote>
</article>
<article>
<header>
<span class='collapse'></span>
Difficulty
</header>
<blockquote>
<div>HP: <span class='metadata' id='meta-diff-hp'></span></div>
<div>CS: <span class='metadata' id='meta-diff-cs'></span></div>
<div>OD: <span class='metadata' id='meta-diff-od'></span></div>
<div>AR: <span class='metadata' id='meta-diff-ar'></span></div>
<div>SV: <span class='metadata' id='meta-diff-sv'></span></div>
<div>TR: <span class='metadata' id='meta-diff-tr'></span></div>
</blockquote>
</article>
<article>
<header>
<span class='collapse'></span>
Events
</header>
<blockquote>
<div>Background Image: <span class='metadata' id='meta-background'></span></div>
</blockquote>
</article>
Viewing:
<select>
<option value='Aggregate'>Aggregate</option>
<select id='meta-selector'>
<option value='all'>Aggregate</option>
</select>
</div>
</div>

@ -10,8 +10,9 @@ function _removeFile(id) {
if(file_id!==undefined && OSU_FILES[file_id])
{
global.signal("FILE_REMOVE", {id: file_id, osu: OSU_FILES[file_id]});
const osu = OSU_FILES[file_id];
OSU_FILES[file_id] = null;
global.signal("FILE_REMOVE", {id: file_id, osu: osu});
}
}
@ -28,7 +29,7 @@ function _readfile(event) {
osu.LoadString(reader.result).then(result => {
console.log("Read version "+osu.version);
if(osu.okay()) {
//TODO: Push to read osu files
//Push to read osu files
OSU_FILES.push(osu);
global.signal("FILE_ADD", {id: OSU_FILES.length-1, osu: osu});
@ -45,6 +46,98 @@ function _readfile(event) {
}
}
var SIDEBAR_VIEWING = null;
function get_aggregate()
{
return OSU_FILES.where(x=> x)[0];
}
function clear_sidebar() {
for(const elem of document.getElementsByClassName("metadata")) {
elem.innerText="";
removeClass(elem, "meta-dupe");
}
}
function populate_sidebar(osu) {
const meta = (id, value_name, transform) => {
transform = transform || ((value) => value);
const elem = document.getElementById("meta-"+id);
const value = transform(path(osu, value_name));
elem.innerText = value;
if(OSU_FILES.where(x=> x && transform(path(x, value_name)) == value).length != OSU_FILES.where(x=> x).length)
{
//Is a not-dupe.
addClass(elem, "meta-dupe");
}
else removeClass(elem, "meta-dupe");
};
if(!osu) {
if(OSU_FILES.where(x=> x).length<1) clear_sidebar();
else {
//Is aggregate.
populate_sidebar(get_aggregate());
SIDEBAR_VIEWING = null;
}
} else {
//Is single
//General
meta("audio-filename", "data.General.AudioFilename");
meta("audio-lead-in", "data.General.AudioLeadIn");
meta("preview-time", "data.General.PreviewTime");
meta("countdown", "data.General.Countdown");
meta("sample-set", "data.General.SampleSet");
meta("stacking", "data.General.StackLeniency");
meta("mode", "data.General.Mode");
meta("letterbox", "data.General.LetterboxInBreaks");
meta("widescreen", "data.General.WidescreenStoryboard");
//Metadata
meta("title", "data.Metadata.TitleUnicode");
meta("title-ascii", "data.Metadata.Title");
meta("artist", "data.Metadata.ArtistUnicode");
meta("artist-ascii", "data.Metadata.Artist");
meta("mapper", "data.Metadata.Creator");
meta("difficulty", "data.Metadata.Version");
meta("source", "data.Metadata.Source");
meta("tags", "data.Metadata.Tags", tags=> tags.join(", "));
meta("beatmap-id", "data.Metadata.BeatmapID");
meta("beatmap-set-id", "data.Metadata.BeatmapSetID");
//Diff
meta("diff-hp", "data.Difficulty.HPDrainRate");
meta("diff-cs", "data.Difficulty.CircleSize");
meta("diff-od", "data.Difficulty.OverallDifficulty");
meta("diff-ar", "data.Difficulty.ApproachRate");
meta("diff-sv", "data.Difficulty.SliderMultiplier");
meta("diff-tr", "data.Difficulty.SliderTickRate");
//Background
meta("background", "spec.Background");
SIDEBAR_VIEWING = osu;
}
}
function repopulate_sidebar(get_sel) {
if(get_sel) {
const elem = document.getElementById("meta-selector");
if(elem.selectedIndex==0)
populate_sidebar();
else
populate_sidebar(OSU_FILES[elem.value]);
}
else
populate_sidebar(SIDEBAR_VIEWING);
}
function _onload() {
@ -69,4 +162,112 @@ function _onload() {
}, false);
}
// --- End collapsers --- //
// --- Selector change -- //
const metadataSelector = document.getElementById('meta-selector');
metadataSelector.addEventListener("change", function(event) {
if(this.selectedIndex==0) {
populate_sidebar();
} else {
const osu = OSU_FILES[this.value];
if(osu) {
populate_sidebar(osu);
}
}
});
}
const OSUFILE_DOM_PRE = "O_file";
function setWarn(elem, on, str) {
if(!elem) return;
if(on) {
addClass(elem, "warning");
elem.setAttribute("title", "Warning"+ (str?": "+str:""));
} else if(hasClass(elem,"warning")) {
removeClass(elem, "warning");
elem.removeAttribute("title");
}
}
/// --- HOOKS --- ///
//Create DOM elem for file.
global.hook("FILE_ADD", function(arg) {
const id = arg.id;
const osu = arg.osu;
//A new file has been added.
//<div id='_file1' data-index='0' class='osufile' onclick='_removeFile("_file1")'>test</div>
var elem = document.createElement("div");
elem.setAttribute("id", OSUFILE_DOM_PRE+id);
elem.setAttribute("class", "osufile");
elem.innerText = osu.Fullname();
elem.addEventListener("click", function() {
_removeFile(OSUFILE_DOM_PRE+id);
});
elem.dataset.index = id;
console.log(OSU_FILES.where(x=> x && osu.equals(x)).length);
console.log(OSU_FILES.where(x=> x && x.equals(new OsuFile())||true));
console.log(OSU_FILES);
if(OSU_FILES.where(x=> x && x.equals(osu)).length > 1) {
setWarn(elem, true, "File already added!");
}
document.getElementById("selector").appendChild(elem);
repopulate_sidebar();
});
//Add to Metadata Selector
global.hook("FILE_ADD", function(arg) {
const osu = arg.osu;
const id = arg.id;
var elem = document.createElement("option");
elem.setAttribute("value", id);
elem.setAttribute("id", "meta-sel-"+id);
elem.innerText = osu.Shortname();
var sel = document.getElementById("meta-selector");
sel.appendChild(elem);
if(!SIDEBAR_VIEWING) {
repopulate_sidebar();
}
});
//Remove Metadata selector
global.hook("FILE_REMOVE", function(arg) {
const osu = arg.osu;
const id = arg.id;
document.getElementById("meta-sel-"+id).remove();
repopulate_sidebar(true);
});
//Recalc dupe warnings
global.hook("FILE_REMOVE", function(arg) {
const osu = arg.osu;
const id = arg.id;
for(let i =OSU_FILES.length-1;i>=0;i--) {
if(!OSU_FILES[i]) continue;
let setwarn = false;
for(let j = 0;j<i;j++) {
if(!OSU_FILES[j]) continue;
if(OSU_FILES[j].equals(OSU_FILES[i]))
{
setwarn = true;
break;
}
}
console.log(i+" "+setwarn);
if(setwarn) setWarn(document.getElementById(OSUFILE_DOM_PRE+i), true, "File already added!");
else setWarn(document.getElementById(OSUFILE_DOM_PRE+i), false);
}
});

@ -37,6 +37,7 @@ OSU.LoadTokens = async function(tokens) {
this.errors = [];
this.data = {};
this.spec = {};
this.futsuu(stages["General"]);
this.han(stages["Editor"]);
@ -88,7 +89,7 @@ OSU.LoadTokens = async function(tokens) {
stages[key].forceClose();
}
console.log(this.data);
this.specialise();
return this.errors;
};
@ -180,6 +181,7 @@ OSU.jiken = async function(tokens) {
while(tok = await tokens.take()) {
var match = tok.match(/^(\w+|\d+),.+$/i);
if(match && match[0])
{
//convenience?
@ -309,8 +311,25 @@ OSU.maru = async function(tokens) {
}
};
OSU.specialise = function() {
this.spec.Background = this.data.Events[0].params[0];
};
/// --- End parsers --- ///
/// --- Begin Helpers --- ///
OSU.Fullname = function() {
return this.data.Metadata.ArtistUnicode + " - "+this.data.Metadata.TitleUnicode+" ["+this.data.Metadata.Version+"]";
};
OSU.Shortname = function() {
return this.data.Metadata.Version;
};
/// --- End helpers --- ///
OSU.okay = function() {
return !!this.version && this.errors.length<1;
};
@ -321,8 +340,13 @@ OsuFile.Unserialise = (json) => {
var osu = new OsuFile();
osu.errors = [];
osu.spec = {};
osu.version = json.version;
osu.data = json.data;
osu.specialise();
return osu;
};
OSU.serialise = function() {
@ -332,3 +356,15 @@ OSU.serialise = function() {
OSU.toString = function() {
return JSON.stringify(this.serialise());
};
OSU.hash = function() {
if(this._hash) return this._hash;
else
return this._hash = forge_sha256(this.toString());
};
OSU.equals = function(...osu) {
const hash = this.hash();
console.log(hash);
return osu.where(x=> x && x.hash() === hash).length == osu.length;
};

@ -13,7 +13,7 @@ function addGlobalStyle(text)
function hasClass(ele, cls)
{
return !!ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
return ele && !!ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
}
function addClass(ele, cls)
@ -22,9 +22,13 @@ function addClass(ele, cls)
}
Array.prototype.where = function(predicate) {
output = [];
for(const elem of this) {
if(predicate(elem)) output.push(elem);
var output = [];
const ar = this;
for(let i=0;i<ar.length;i++) {
const elem = ar[i];
if(predicate(elem)) {
output.push(elem);
}
}
return output;
};
@ -74,7 +78,7 @@ Dispatcher.prototype.hook = function(name, value) {
Dispatcher.prototype.signal = function(name,value) {
if(this.hooks[name]) {
for(const hook of this.hooks[name])i
for(const hook of this.hooks[name])
if(hook)
hook(value);
}
@ -91,3 +95,14 @@ Dispatcher.prototype.clear = function(name) {
if(name) this.hooks[name] = null;
else this.hooks = {};
};
function path(_obj, string) {
const spl = string.split(/\./);
let obj = _obj;
for(let i=0;i<spl.length;i++)
{
if(!obj) return obj;
obj = obj[spl[i]];
}
return obj;
}

@ -0,0 +1 @@
../../../git_modules/forge-sha256/build/forge-sha256.min.js
Loading…
Cancel
Save