Merge branch 'develop' into cadence-experiment

This commit is contained in:
zkldi
2022-05-31 14:33:57 +01:00
committed by GitHub
4 changed files with 115 additions and 3 deletions
+2 -2
View File
@@ -5,9 +5,9 @@
FROM node:16 as build
WORKDIR /app
COPY --chown=node:node . /app
RUN npm install --silent -g pnpm && groupmod -g 1003 node && chown node:node /app
RUN npm install --silent -g pnpm@6 && groupmod -g 1003 node && chown node:node /app
USER node
RUN pnpm install --silent && pnpm build && pnpm prune --silent --production && pnpm store prune --silent
RUN pnpm install --silent --frozen-lockfile && pnpm build && pnpm prune --silent --production && pnpm store prune --silent
HEALTHCHECK --interval=15s --timeout=5s CMD curl -f http://localhost:8080/api/v1/status || exit 1
ENV NODE_PATH=js/
CMD ["node", "js/main.js"]
@@ -103,6 +103,43 @@ t.test("#ParseSolidStateXML", (t) => {
t.end();
});
t.test("Should parse S3 XML on the chart .59", (t) => {
const res = ParseSolidStateXML(
MockMulterFile(GetKTDataBuffer("./s3/point-five-nine.xml"), "point-five-nine.xml"),
{},
logger
);
t.hasStrict(
res.iterable,
[
{
id: 187,
diff: 7,
songname: ".59",
styles: "3rd",
exscore: 100,
scorebreakdown: {
justgreats: 50,
greats: 50,
good: 0,
bad: 0,
poor: 4,
},
mods: {},
cleartype: "perfect",
date: "2010-10-19 04:54:22",
},
],
"Should return the right score in the iterable."
);
t.equal(res.game, "iidx", "Should return IIDX as the game.");
t.equal(res.classHandler, null, "Should return no class handler.");
t.strictSame(res.context, {}, "Should return no context.");
t.end();
});
t.test("Should reject S3 XML with no scores", (t) => {
t.throws(
() =>
@@ -20,7 +20,19 @@ const PR_SOLID_STATE: PrudenceSchema = {
{
id: p.isPositiveInteger,
diff: p.isIn("L7", 7, "A", "B", 5, "L14", 14, "A14", "B14"),
songname: "string",
// https://github.com/TNG-dev/tachi-server/issues/718
// The song title '.59' is automatically coerced into a float
// by our XML parser. Despite the fact that it's in a CData field.
// Regardless of the mess that is XML, we need to accept numbers in
// this field, and then convert them back to strings later.
//
// Making a proper solution for this isn't possible, as the bowels
// of the XML parser are inaccessible to us.
// I *hate* XML.
//
// What a disaster.
songname: p.or("string", p.is(0.59)),
styles: "string",
exscore: p.isPositiveInteger,
@@ -53,6 +65,9 @@ const PR_SOLID_STATE: PrudenceSchema = {
const xmlParser = new XMLParser();
// .59 is a song that is interpreted as a float by our XML parser.
type PreStringifiedS3Score = Omit<S3Score, "songname"> & { songname: 0.59 | string };
export function ParseSolidStateXML(
fileData: Express.Multer.File,
body: Record<string, unknown>,
@@ -102,6 +117,19 @@ export function ParseSolidStateXML(
throw new ScoreImportFatalError(400, FormatPrError(err, "Invalid S3 XML."));
}
let scoreData = parsedXML.s3data.scoredata.song as PreStringifiedS3Score[];
scoreData = scoreData.map((e) => ({
...e,
// Songnames here are either numbers or strings due to a disgusting hack
// @see #718
// We forcibly convert all these back to strings.
// Note that we can't even use the generic solution .toString, because the
// song title is .59, not 0.59.
// This is genuinely horrific.
songname: e.songname === 0.59 ? ".59" : e.songname,
}));
return {
classHandler: null,
context: {},
@@ -0,0 +1,47 @@
<s3data version="0.1" xmlns="http://iidx.solidstatesquad.com/xml/ns#">
<userdata>
<id>3</id>
<login>
<![CDATA[zkldi]]>
</login>
<djname>
<![CDATA[ZKLDI]]>
</djname>
</userdata>
<scoredata>
<song>
<id>187</id>
<diff>7</diff>
<songname>
<![CDATA[.59]]>
</songname>
<artist>
<![CDATA[TAKA]]>
</artist>
<genre>
<![CDATA[CHILL OUT]]>
</genre>
<bpm>174</bpm>
<styles>3rd</styles>
<rating>1</rating>
<notes>137</notes>
<exscore>100</exscore>
<grade>AA</grade>
<djpoints>9</djpoints>
<scorebreakdown>
<justgreats>50</justgreats>
<greats>50</greats>
<good>0</good>
<bad>0</bad>
<poor>4</poor>
</scorebreakdown>
<mods>
<highspeed>2</highspeed>
<hidsud>T</hidsud>
<ranmir>B</ranmir>
</mods>
<cleartype>perfect</cleartype>
<date>2010-10-19 04:54:22</date>
</song>
</scoredata>
</s3data>