Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add diffstat info to whitelisted beatmaps and filter/sort query #10

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
115 changes: 104 additions & 11 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,27 @@ function convertURIregex(input) {
return input;
}

function getComparisonText(comparison) {
switch (comparison) {
case "<":
return "$lt";
case "<=":
return "$lte";
case ">":
return "$gt";
case ">=":
return "$gte";
default:
return "$eq";
}
}

function getComparisonObject(comparison, value) {
const comparisonString = getComparisonText(comparison);

return Object.defineProperty({}, comparisonString, {value, writable: true, configurable: true, enumerable: true});
}

top_pp_list = [];

clientdb.connect( function(err, db) {
Expand Down Expand Up @@ -107,18 +128,90 @@ function makeBoard() {
});

app.get('/whitelist', (req, res) => {
var page = parseInt(req.url.split('?page=')[1]);
var query = req.url.split('?query=')[1]
var mapquery;
if (!page) {page = 1;}
if (!query) {mapquery = {}; query = '';}
else {
var regexquery = new RegExp(convertURIregex(query), 'i');
mapquery = {mapname: regexquery};
const page = parseInt(req.url.split('?page=')[1]) || 1;
const query = convertURI(req.url.split('?query=')[1] || "").toLowerCase();
const mapquery = {};
const sort = {};
if (query) {
let mapNameQuery = "";
const comparisonRegex = /[<=>]{1,2}/;
const finalQueries = query.split(/\s+/g);
for (const finalQuery of finalQueries) {
let [key, value] = finalQuery.split(comparisonRegex, 2);
const comparison = (comparisonRegex.exec(finalQuery) ?? ["="])[0];
switch (key) {
case "cs":
case "ar":
case "od":
case "hp":
case "sr":
case "bpm":
const propertyName = `diffstat.${key}`;
if (mapquery.hasOwnProperty(propertyName)) {
mapquery[propertyName][getComparisonText(comparison)] = parseFloat(value);
} else {
mapquery[propertyName] = getComparisonObject(comparison, parseFloat(value));
}
break;
case "star":
case "stars":
if (mapquery.hasOwnProperty("diffstat.sr")) {
mapquery["diffstat.sr"][getComparisonText(comparison)] = parseFloat(value);
} else {
mapquery["diffstat.sr"] = getComparisonObject(comparison, parseFloat(value));
}
break;
case "sort":
const isDescendSort = value.startsWith("-");
if (isDescendSort) {
value = value.substring(1);
}
switch (value) {
case "beatmapid":
case "mapid":
case "id":
sort.mapid = isDescendSort ? -1 : 1;
break;
case "beatmapname":
case "mapname":
case "name":
sort.mapname = isDescendSort ? -1 : 1;
break;
case "cs":
case "ar":
case "od":
case "hp":
case "bpm":
sort[`diffstat.${value}`] = isDescendSort ? -1 : 1;
break;
case "sr":
case "star":
case "stars":
sort["diffstat.sr"] = isDescendSort ? -1 : 1;
break;
default:
mapNameQuery += finalQuery + " ";
}
break;
default:
mapNameQuery += finalQuery + " ";
}
}
if (mapNameQuery) {
const regexQuery = mapNameQuery.trim().split(/\s+/g).map(v => {
return {mapname: new RegExp(convertURIregex(v), "i")};
});
mapquery.$and = regexQuery;
}
}
if (!sort.hasOwnProperty("mapname")) {
sort.mapname = 1;
}
// Allow SR and BPM sort to override beatmap title sort
if (sort.hasOwnProperty("diffstat.sr") || sort.hasOwnProperty("diffstat.bpm")) {
delete sort.mapname;
}
var mapsort = { mapname: 1 };
whitelistdb.find(mapquery, {projection: {_id: 0}}).sort(mapsort).skip((page-1)*30).limit(30).toArray(function(err, resarr) {
//console.log(resarr);
whitelistdb.find(mapquery, {projection: {_id: 0, mapid: 1, mapname: 1, diffstat: 1}}).sort(sort).skip((page-1)*30).limit(30).toArray(function(err, resarr) {
var title = 'Map Whitelisting Board'
res.render('whitelist', {
title: title,
Expand Down
5 changes: 5 additions & 0 deletions views/default.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,8 @@ h5 {
font: 16px Exo;
font-weight: 350;
}

h7 {
font: 14px Exo;
font-weight: 150;
}
68 changes: 65 additions & 3 deletions views/whitelist.pug
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ h3
div(class="queryall")
h5(class="queryshow")= "Current query: " + query
form
input(type="text", name="query", id='rcorners', hint="Search")
input(type="text", name="query", value=query, id='rcorners', hint="Search")
input(type="submit", id='rcorners2', value="Search")

hr
Expand All @@ -41,13 +41,25 @@ hr

table(border="0", width="100%")
tbody
th(width="10%")= "Map ID"
th(width="80%")= "Map Name"
th(width="7.5%")= "Map ID"
th(width="67.5%")= "Map Name"
th(width="2.5%")= "CS"
th(width="2.5%")= "AR"
th(width="2.5%")= "OD"
th(width="2.5%")= "HP"
th(width="2.5%")= "SR"
th(width="2.5%")= "BPM"
th(width="10%")= "osu! redirect"
each val in list
tr
td= val.mapid
td= val.mapname
td= val.diffstat.cs
td= val.diffstat.ar
td= val.diffstat.od
td= val.diffstat.hp
td= val.diffstat.sr
td= val.diffstat.bpm
td
a(href='https://osu.ppy.sh/b/'+val.mapid)= "Link"

Expand All @@ -62,4 +74,54 @@ div
li(class="nav")
a(href='/whitelist?page=' + (page+1) + (query ? '?query='+query : ''), class="pagenav")= "Next Page >>>"

hr

div
h3 Search Query Guide
h7
strong Available filter option:
| CS, AR, OD, HP, SR, BPM
br
strong Available sorting option:
| CS, AR, OD, HP, SR, BPM, mapid, mapname (you can put "-" in front to use descend sort instead of ascend)
br
br
strong Equality symbols for filter option:
|
ul
li <= (less than or equal to)
li < (less than)
li = (equal to)
li > (more than)
li >= (more than or equal to)
| All filter and sort options are case insensitive, with each of them separated by space.
br
br
| By default, there is no filter, and the sort option is set to beatmap name.
br
br
| Using SR and/or BPM sort option will override beatmap name sort option.
br
br
| Anything that doesn't fall into any of the filter or sort option will be treated as searching beatmap name.
br
br
strong Examples:
ul
li
strong: i cs>=4.2 cs<=5 sort=cs
| will search for beatmaps with CS between 4.2 (inclusive) and 5 (inclusive) and sort them based on CS ascendingly
li
strong: i od>=5 od<9 ar>7 ar<=9.7 sort=-ar
| will search for beatmaps with AR between 7 (exclusive) and 9.7 (inclusive) and OD between 5 (inclusive) and 9 (exclusive), and then
| sorting the search result by AR descendingly
li
strong: i od>=7 bpm>=180
| will search for beatmaps with OD above 7 (inclusive) and BPM above 180 (inclusive) and sort them based on BPM ascendingly
li
strong: i cs>=4.2 ar>9.3 od>=8 hp>=5 sort=-sr logic boi is the best
| will search for beatmaps with CS above 4.2 (inclusive), AR above 9.3 (exclusive), OD above 8 (inclusive),
| HP above 5 (inclusive), and matches the keyword "logic boi is the best" (much like osu! search function),
| and then sorting the search result by star rating descendingly

hr