mirror of
https://github.com/zkldi/Tachi.git
synced 2026-09-30 10:58:07 +03:00
Get stuff a user did in the last (16) hours
This commit is contained in:
@@ -24,7 +24,7 @@ t.test("#ConvertAPIArcIIDX", (t) => {
|
||||
game: "iidx",
|
||||
importType: "api/arc-iidx",
|
||||
timeAchieved: 1604784681894,
|
||||
service: "ARC IIDX27",
|
||||
service: "ARC IIDX28",
|
||||
scoreData: {
|
||||
grade: "A",
|
||||
score: 1200,
|
||||
|
||||
@@ -80,7 +80,7 @@ export const ConvertAPIArcIIDX: ConverterFunction<unknown, EmptyObject> = async
|
||||
game: "iidx",
|
||||
importType,
|
||||
timeAchieved,
|
||||
service: "ARC IIDX27",
|
||||
service: "ARC IIDX28",
|
||||
scoreData: {
|
||||
grade,
|
||||
percent,
|
||||
|
||||
@@ -1,21 +1,26 @@
|
||||
import { Router } from "express";
|
||||
import db from "external/mongo/db";
|
||||
import { SYMBOL_TachiData } from "lib/constants/tachi";
|
||||
import { GetUserFromParam, RequireSelfRequestFromUser } from "./middleware";
|
||||
import gamePTRouter from "./games/_game/_playtype/router";
|
||||
import bannerRouter from "./banner/router";
|
||||
import pfpRouter from "./pfp/router";
|
||||
import integrationsRouter from "./integrations/router";
|
||||
import settingsRouter from "./settings/router";
|
||||
import prValidate from "server/middleware/prudence-validate";
|
||||
import p from "prudence";
|
||||
import { optNull, optNullFluffStrField } from "utils/prudence";
|
||||
import { DeleteUndefinedProps, StripUrl } from "utils/misc";
|
||||
import { FormatUserDoc, GetAllRankings, GetUserWithID } from "utils/user";
|
||||
import { UserGameStats } from "tachi-common";
|
||||
import CreateLogCtx from "lib/logger/logger";
|
||||
import p from "prudence";
|
||||
import prValidate from "server/middleware/prudence-validate";
|
||||
import { UserGameStats } from "tachi-common";
|
||||
import { DeleteUndefinedProps, StripUrl } from "utils/misc";
|
||||
import { optNull, optNullFluffStrField } from "utils/prudence";
|
||||
import {
|
||||
GetRecentlyViewedFoldersAnyGPT,
|
||||
GetRecentPlaycount,
|
||||
GetRecentSessions,
|
||||
} from "utils/queries/summary";
|
||||
import { FormatUserDoc, GetAllRankings, GetUserWithID } from "utils/user";
|
||||
import apiTokensRouter from "./api-tokens/router";
|
||||
import bannerRouter from "./banner/router";
|
||||
import gamePTRouter from "./games/_game/_playtype/router";
|
||||
import integrationsRouter from "./integrations/router";
|
||||
import invitesRouter from "./invites/router";
|
||||
import { GetUserFromParam, RequireSelfRequestFromUser } from "./middleware";
|
||||
import pfpRouter from "./pfp/router";
|
||||
import settingsRouter from "./settings/router";
|
||||
|
||||
const logger = CreateLogCtx(__filename);
|
||||
|
||||
@@ -203,6 +208,33 @@ router.get("/game-stats", async (req, res) => {
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns a summary of what the user has achieved in the past 24 hours.
|
||||
* Used on the main dashboard page to give users quick links to sessions,
|
||||
* alongside other information.
|
||||
*
|
||||
* @name GET /api/v1/users/:userID/recent-summary
|
||||
*/
|
||||
router.get("/recent-summary", async (req, res) => {
|
||||
const user = req[SYMBOL_TachiData]!.requestedUser!;
|
||||
|
||||
const [recentPlaycount, recentSessions, recentFolders] = await Promise.all([
|
||||
GetRecentPlaycount(user.id),
|
||||
GetRecentSessions(user.id),
|
||||
GetRecentlyViewedFoldersAnyGPT(user.id),
|
||||
]);
|
||||
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
description: `Retrieved information about ${FormatUserDoc(user)}.`,
|
||||
body: {
|
||||
recentPlaycount,
|
||||
recentSessions,
|
||||
recentFolders,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns whether the user has verified their email or not.
|
||||
* Requires self-key level permissions.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import crypto from "crypto";
|
||||
import { ONE_HOUR } from "lib/constants/time";
|
||||
import { TachiConfig } from "lib/setup/config";
|
||||
import { Game, GamePTConfig, GetGameConfig, Playtypes } from "tachi-common";
|
||||
import { Game, GamePTConfig, GetGameConfig, Playtypes, integer } from "tachi-common";
|
||||
|
||||
// https://github.com/sindresorhus/escape-string-regexp/blob/main/index.js
|
||||
// the developer of this has migrated everything to Force ES6 style modules,
|
||||
@@ -128,3 +129,7 @@ export function IsValidURL(string: string) {
|
||||
export function Sleep(ms: number) {
|
||||
return new Promise<void>((resolve) => setTimeout(() => resolve(), ms));
|
||||
}
|
||||
|
||||
export function GetTimeXHoursAgo(hours: integer) {
|
||||
return Date.now() - ONE_HOUR * hours;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import db from "external/mongo/db";
|
||||
import { integer } from "tachi-common";
|
||||
import { GetTimeXHoursAgo } from "utils/misc";
|
||||
|
||||
// Various utils related to the player summary endpoint.
|
||||
const REASONABLE_HOURS_AGO = 16;
|
||||
|
||||
export function GetRecentPlaycount(userID: integer) {
|
||||
const time = GetTimeXHoursAgo(REASONABLE_HOURS_AGO);
|
||||
|
||||
return db.scores.count({ userID, timeAchieved: { $gte: time } });
|
||||
}
|
||||
|
||||
export function GetRecentSessions(userID: integer) {
|
||||
const time = GetTimeXHoursAgo(REASONABLE_HOURS_AGO);
|
||||
|
||||
return db.sessions.find({
|
||||
userID,
|
||||
timeEnded: { $gte: time },
|
||||
});
|
||||
}
|
||||
|
||||
export async function GetRecentlyViewedFoldersAnyGPT(userID: integer) {
|
||||
const time = GetTimeXHoursAgo(REASONABLE_HOURS_AGO);
|
||||
|
||||
const views = await db["recent-folder-views"].find(
|
||||
{
|
||||
userID,
|
||||
lastViewed: { $gte: time },
|
||||
},
|
||||
{
|
||||
sort: {
|
||||
lastViewed: -1,
|
||||
},
|
||||
limit: 4,
|
||||
}
|
||||
);
|
||||
|
||||
const folders = await db.folders.find({
|
||||
folderID: { $in: views.map((e) => e.folderID) },
|
||||
});
|
||||
|
||||
// TODO: Sort recently viewed folders based on how recently viewed
|
||||
// they were.
|
||||
|
||||
return folders;
|
||||
}
|
||||
Reference in New Issue
Block a user