mirror of
https://github.com/zkldi/Tachi.git
synced 2026-10-01 03:18:06 +03:00
Merge pull request #666 from TNG-dev/release/v2.1.9
This commit is contained in:
@@ -15,6 +15,16 @@ not generally be shown to end users.
|
||||
|
||||
# Changelog
|
||||
|
||||
# 2.1.9
|
||||
|
||||
- [ENH] Add an endpoint on UGPT/folder/:folderID/stats. This returns lamp and grade distributions for this ugpt:folder combo.
|
||||
- [ENH] The UGPT Folder timeline endpoint now also returns the folder it worked on.
|
||||
|
||||
*****
|
||||
|
||||
- [BUG] OAuth2 tokens are now properly expired.
|
||||
- [BUG] ForceStaticImport is no longer always on, even if off.
|
||||
|
||||
# 2.1.4
|
||||
|
||||
- [BUG] IIDX, BMS and PMS scores can no longer get an invalid grade if they are exactly 77.7777...%
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "tachi-server",
|
||||
"version": "2.1.8",
|
||||
"version": "2.1.9",
|
||||
"description": "A score tracking server.",
|
||||
"main": "js/index.js",
|
||||
"private": true,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
const MAJOR = 2;
|
||||
const MINOR = 1;
|
||||
const PATCH = 8;
|
||||
const PATCH = 9;
|
||||
|
||||
// As is with all front-facing zkldi projects, the version names for tachi-server
|
||||
// are from an album I like. In this case, the album is Portishead - Dummy.
|
||||
@@ -34,6 +34,4 @@ export const VERSION_INFO = {
|
||||
|
||||
export const VERSION_STR = `${MAJOR}.${MINOR}.${PATCH}`;
|
||||
|
||||
export function FormatVersion() {
|
||||
return `v${VERSION_STR} (${VERSION_INFO.name})`;
|
||||
}
|
||||
export const VERSION_PRETTY = `v${VERSION_STR} (${VERSION_INFO.name})`;
|
||||
|
||||
+2
-2
@@ -10,6 +10,7 @@ import fs from "fs";
|
||||
import http from "http";
|
||||
import https from "https";
|
||||
import { LoadDefaultClients } from "lib/builtin-clients/builtin-clients";
|
||||
import { VERSION_PRETTY } from "lib/constants/version";
|
||||
import { HandleSIGTERMGracefully } from "lib/handlers/sigterm";
|
||||
import CreateLogCtx from "lib/logger/logger";
|
||||
import { Environment, ServerConfig, TachiConfig } from "lib/setup/config";
|
||||
@@ -17,11 +18,10 @@ import path from "path";
|
||||
import server from "server/server";
|
||||
import fetch from "utils/fetch";
|
||||
import { InitaliseFolderChartLookup } from "utils/folder";
|
||||
import { FormatVersion } from "./lib/constants/version";
|
||||
|
||||
const logger = CreateLogCtx(__filename);
|
||||
|
||||
logger.info(`Booting ${TachiConfig.NAME} - ${FormatVersion()} [ENV: ${Environment.nodeEnv}]`, {
|
||||
logger.info(`Booting ${TachiConfig.NAME} - ${VERSION_PRETTY} [ENV: ${Environment.nodeEnv}]`, {
|
||||
bootInfo: true,
|
||||
});
|
||||
logger.info(`Log level is set to ${ServerConfig.LOGGER_CONFIG.LOG_LEVEL}.`, { bootInfo: true });
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { FormatVersion } from "lib/constants/version";
|
||||
import { VERSION_PRETTY } from "lib/constants/version";
|
||||
import { CreateFakeAuthCookie } from "test-utils/fake-auth";
|
||||
import mockApi from "test-utils/mock-api";
|
||||
import t from "tap";
|
||||
@@ -16,7 +16,7 @@ t.test("GET /api/v1/status", async (t) => {
|
||||
"Should be roughly the current time (5 seconds lenience)"
|
||||
);
|
||||
t.type(res.body.body.startTime, "number", "Should return a number for startTime.");
|
||||
t.equal(res.body.body.version, FormatVersion());
|
||||
t.equal(res.body.body.version, VERSION_PRETTY);
|
||||
t.equal(res.body.body.whoami, 1);
|
||||
|
||||
t.end();
|
||||
@@ -33,7 +33,7 @@ t.test("GET /api/v1/status", async (t) => {
|
||||
"Should be roughly the current time (5 seconds lenience)"
|
||||
);
|
||||
t.type(res.body.body.startTime, "number", "Should return a number for startTime.");
|
||||
t.equal(res.body.body.version, FormatVersion());
|
||||
t.equal(res.body.body.version, VERSION_PRETTY);
|
||||
t.equal(res.body.body.whoami, 1);
|
||||
|
||||
t.end();
|
||||
@@ -54,7 +54,7 @@ t.test("POST /api/v1/status", async (t) => {
|
||||
Math.abs(Date.now() - res.body.body.serverTime) < 5_000,
|
||||
"Should be roughly the current time (5 seconds lenience)"
|
||||
);
|
||||
t.equal(res.body.body.version, FormatVersion());
|
||||
t.equal(res.body.body.version, VERSION_PRETTY);
|
||||
t.equal(res.body.body.whoami, 1);
|
||||
t.type(res.body.body.startTime, "number", "Should return a number for startTime.");
|
||||
|
||||
@@ -73,7 +73,7 @@ t.test("POST /api/v1/status", async (t) => {
|
||||
Math.abs(Date.now() - res.body.body.serverTime) < 5_000,
|
||||
"Should be roughly the current time (5 seconds lenience)"
|
||||
);
|
||||
t.equal(res.body.body.version, FormatVersion());
|
||||
t.equal(res.body.body.version, VERSION_PRETTY);
|
||||
t.equal(res.body.body.whoami, 1);
|
||||
t.type(res.body.body.startTime, "number", "Should return a number for startTime.");
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Router } from "express";
|
||||
import { SYMBOL_TachiAPIAuth } from "lib/constants/tachi";
|
||||
import { FormatVersion } from "lib/constants/version";
|
||||
import { VERSION_PRETTY } from "lib/constants/version";
|
||||
|
||||
const router: Router = Router({ mergeParams: true });
|
||||
|
||||
@@ -23,7 +23,7 @@ router.get("/", (req, res) => {
|
||||
body: {
|
||||
serverTime: Date.now(),
|
||||
startTime,
|
||||
version: FormatVersion(),
|
||||
version: VERSION_PRETTY,
|
||||
whoami: req[SYMBOL_TachiAPIAuth].userID,
|
||||
// converts {foo: true, bar: false, baz: true} into [foo, baz]
|
||||
permissions: Object.entries(req[SYMBOL_TachiAPIAuth].permissions)
|
||||
@@ -52,7 +52,7 @@ router.post("/", (req, res) => {
|
||||
body: {
|
||||
serverTime: Date.now(),
|
||||
startTime,
|
||||
version: FormatVersion(),
|
||||
version: VERSION_PRETTY,
|
||||
whoami: req[SYMBOL_TachiAPIAuth].userID,
|
||||
// converts {foo: true, bar: false, baz: true} into [foo, baz]
|
||||
permissions: Object.entries(req[SYMBOL_TachiAPIAuth].permissions)
|
||||
|
||||
+23
-1
@@ -3,7 +3,7 @@ import db from "external/mongo/db";
|
||||
import { SYMBOL_TachiData } from "lib/constants/tachi";
|
||||
import { FilterQuery } from "mongodb";
|
||||
import { GetGamePTConfig, ScoreDocument } from "tachi-common";
|
||||
import { GetFolderCharts, GetPBsOnFolder } from "utils/folder";
|
||||
import { GetFolderCharts, GetGradeLampDistributionForFolder, GetPBsOnFolder } from "utils/folder";
|
||||
import { ParseStrPositiveInt } from "utils/string-checks";
|
||||
import { GetFolderFromParam } from "../../../../../../../games/_game/_playtype/folders/middleware";
|
||||
import { RequireSelfRequestFromUser } from "../../../../../middleware";
|
||||
@@ -35,6 +35,27 @@ router.get("/", async (req, res) => {
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns a users stats on this folder.
|
||||
*
|
||||
* @name GET /api/v1/users/:userID/games/:game/:playtype/folders/:folderID/stats
|
||||
*/
|
||||
router.get("/stats", async (req, res) => {
|
||||
const folder = req[SYMBOL_TachiData]!.folderDoc!;
|
||||
const user = req[SYMBOL_TachiData]!.requestedUser!;
|
||||
|
||||
const stats = await GetGradeLampDistributionForFolder(user.id, folder);
|
||||
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
description: `Returned statistics for ${folder.title}.`,
|
||||
body: {
|
||||
folder,
|
||||
stats,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Add a folder to the list of recently-viewed folders. This can only
|
||||
* be performed by a session-level token, to stop rogue API keys from causing
|
||||
@@ -162,6 +183,7 @@ router.get("/timeline", async (req, res) => {
|
||||
songs,
|
||||
charts,
|
||||
scores,
|
||||
folder,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user