First commit
This commit is contained in:
commit
455ae8c0ee
36 changed files with 677 additions and 0 deletions
35
.gitignore
vendored
Normal file
35
.gitignore
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
yarn.lock
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# vercel
|
||||
.vercel
|
8
.idea/.gitignore
vendored
Normal file
8
.idea/.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
18
package.json
Normal file
18
package.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next",
|
||||
"build": "next build",
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"dayjs": "^1.10.7",
|
||||
"next": "latest",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"swr": "^1.0.1",
|
||||
"redis": "^4.0.1",
|
||||
"dotenv": "^10.0.0",
|
||||
"fast-levenshtein": "^3.0.0"
|
||||
}
|
||||
}
|
21
pages/api/artifacts/[id].js
Normal file
21
pages/api/artifacts/[id].js
Normal file
|
@ -0,0 +1,21 @@
|
|||
import {getArtifacts} from "./utils";
|
||||
import {addResultToRedis, getResultFromRedis} from "../../../utils/redis";
|
||||
|
||||
export default async function artifactHandler({query: {id}}, res) {
|
||||
let artifact = JSON.parse(await getResultFromRedis(`artifact-${id}`))
|
||||
if (!artifact) {
|
||||
let artifacts = JSON.parse(await getResultFromRedis("artifact-all"));
|
||||
if (!artifacts){
|
||||
artifacts = await getArtifacts();
|
||||
addResultToRedis("artifact-all", JSON.stringify(artifacts)).catch(console.error);
|
||||
}
|
||||
artifact = artifacts[id];
|
||||
}
|
||||
|
||||
if (artifact) {
|
||||
res.status(200).json(artifact);
|
||||
addResultToRedis(`artifact-${id}`, JSON.stringify(artifact)).catch(console.error)
|
||||
} else {
|
||||
res.status(404).json({message: `Artifact ${id} doesn't exist`})
|
||||
}
|
||||
}
|
21
pages/api/artifacts/index.js
Normal file
21
pages/api/artifacts/index.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
import {getArtifacts} from "./utils";
|
||||
import {addResultToRedis, getResultFromRedis} from "../../../utils/redis";
|
||||
|
||||
export default async function handler(req, res) {
|
||||
let t0 = performance.now()
|
||||
|
||||
let artifacts = JSON.parse(await getResultFromRedis(`artifact-all`))
|
||||
if (!artifacts) {
|
||||
artifacts = await getArtifacts();
|
||||
}
|
||||
|
||||
if (artifacts) {
|
||||
res.status(200).json(Object.keys(artifacts));
|
||||
addResultToRedis(`artifact-all`, JSON.stringify(artifacts)).catch(console.error)
|
||||
} else {
|
||||
res.status(404).json({message: "An error has occurred"})
|
||||
}
|
||||
|
||||
let t1 = performance.now();
|
||||
console.debug(`Execution took ${t1-t0} ms`)
|
||||
}
|
23
pages/api/artifacts/search/[id].js
Normal file
23
pages/api/artifacts/search/[id].js
Normal file
|
@ -0,0 +1,23 @@
|
|||
import {getArtifacts} from "../utils";
|
||||
import {getClosest} from "../../../../utils/levenshtein";
|
||||
import {addResultToRedis, getResultFromRedis} from "../../../../utils/redis";
|
||||
|
||||
export default async function artifactHandler({query: {id}}, res) {
|
||||
|
||||
let artifacts = JSON.parse(await getResultFromRedis('artifact-all'));
|
||||
if (!artifacts) {
|
||||
artifacts = await getArtifacts();
|
||||
addResultToRedis('artifact-all', JSON.stringify(artifacts)).catch(console.error)
|
||||
}
|
||||
|
||||
const closestArtifacts = []
|
||||
getClosest(id, artifacts).forEach(a => {
|
||||
closestArtifacts.push(artifacts[a.name])
|
||||
})
|
||||
|
||||
if (closestArtifacts) {
|
||||
res.status(200).json(closestArtifacts);
|
||||
} else {
|
||||
res.status(404).json({message: `Artifact ${id} not found`});
|
||||
}
|
||||
}
|
5
pages/api/artifacts/utils.js
Normal file
5
pages/api/artifacts/utils.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
export async function getArtifacts(){
|
||||
const res = await fetch("https://raw.githubusercontent.com/MadeBaruna/paimon-moe/main/src/data/artifacts/en.json");
|
||||
const artifacts = JSON.parse(await res.text());
|
||||
return artifacts;
|
||||
}
|
21
pages/api/builds/[id].js
Normal file
21
pages/api/builds/[id].js
Normal file
|
@ -0,0 +1,21 @@
|
|||
import {getBuilds} from "./utils";
|
||||
import {addResultToRedis, getResultFromRedis} from "../../../utils/redis";
|
||||
|
||||
export default async function buildHandler({query: {id}}, res) {
|
||||
let build = JSON.parse(await getResultFromRedis(`build-${id}`));
|
||||
if (!build) {
|
||||
let builds = JSON.parse(await getResultFromRedis('build-all'));
|
||||
if (!builds){
|
||||
builds = await getBuilds();
|
||||
addResultToRedis('build-all', JSON.stringify(builds)).catch(console.error);
|
||||
}
|
||||
build = builds[id];
|
||||
}
|
||||
|
||||
if (build) {
|
||||
res.status(200).json(build);
|
||||
addResultToRedis(`build-${id}`, JSON.stringify(build)).catch(console.error);
|
||||
} else {
|
||||
res.status(404).json({message : `Build for ${id} not found`});
|
||||
}
|
||||
}
|
16
pages/api/builds/index.js
Normal file
16
pages/api/builds/index.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
import {getBuilds} from "./utils";
|
||||
import {addResultToRedis, getResultFromRedis} from "../../../utils/redis";
|
||||
|
||||
export default async function handler(req, res) {
|
||||
let builds = JSON.parse(await getResultFromRedis('build-all'));
|
||||
if (!builds) {
|
||||
builds = await getBuilds();
|
||||
addResultToRedis('build-all', JSON.stringify(builds)).catch(console.error);
|
||||
}
|
||||
|
||||
if (builds){
|
||||
res.status(200).json(Object.keys(builds));
|
||||
} else {
|
||||
res.status(404).json({message: "An error has occurred"});
|
||||
}
|
||||
}
|
21
pages/api/builds/utils.js
Normal file
21
pages/api/builds/utils.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
const AsyncFunction = Object.getPrototypeOf(async function () {
|
||||
}).constructor;
|
||||
|
||||
export async function getBuilds() {
|
||||
let builds = await new AsyncFunction(
|
||||
(await (await fetch(
|
||||
"https://raw.githubusercontent.com/MadeBaruna/paimon-moe/main/src/data/build.js",
|
||||
)).text()).replace("export const builds =", "return"),
|
||||
)();
|
||||
|
||||
Object.values(builds).forEach(b => {
|
||||
let d = [];
|
||||
for (let c in b["roles"]) {
|
||||
b["roles"][c]["name"] = c;
|
||||
d.push(b["roles"][c]);
|
||||
}
|
||||
b["roles"] = d;
|
||||
})
|
||||
|
||||
return builds;
|
||||
}
|
21
pages/api/characters/[id].js
Normal file
21
pages/api/characters/[id].js
Normal file
|
@ -0,0 +1,21 @@
|
|||
import {getCharacters} from "./utils";
|
||||
import {addResultToRedis, getResultFromRedis} from "../../../utils/redis";
|
||||
|
||||
export default async function characterHandler({query: {id}}, res) {
|
||||
let character = JSON.parse(await getResultFromRedis(`character-${id}`));
|
||||
if (!character) {
|
||||
let characters = JSON.parse(await getResultFromRedis(`character-all`));
|
||||
if (!characters) {
|
||||
characters = await getCharacters();
|
||||
addResultToRedis('character-all', JSON.stringify(characters)).catch(console.error);
|
||||
}
|
||||
character = characters[id];
|
||||
}
|
||||
|
||||
if (character){
|
||||
res.status(200).json(character);
|
||||
addResultToRedis(`character-${id}`, JSON.stringify(character)).catch(console.error);
|
||||
} else {
|
||||
res.status(404).json({message: `Character ${id} doesn't exist`});
|
||||
}
|
||||
}
|
15
pages/api/characters/index.js
Normal file
15
pages/api/characters/index.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
import {getCharacters} from "./utils";
|
||||
import {addResultToRedis, getResultFromRedis} from "../../../utils/redis";
|
||||
|
||||
export default async function handler(req, res) {
|
||||
let characters = JSON.parse(await getResultFromRedis('character-all'));
|
||||
if (!characters){
|
||||
characters = await getCharacters();
|
||||
addResultToRedis('character-all', JSON.stringify(characters)).catch(console.error)
|
||||
}
|
||||
if (characters) {
|
||||
res.status(200).json(Object.keys(characters));
|
||||
} else {
|
||||
res.status(404).json({message: "An error has occurred"});
|
||||
}
|
||||
}
|
23
pages/api/characters/search/[id].js
Normal file
23
pages/api/characters/search/[id].js
Normal file
|
@ -0,0 +1,23 @@
|
|||
import {getCharacters} from "../utils";
|
||||
import {getClosest} from "../../../../utils/levenshtein";
|
||||
import {addResultToRedis, getResultFromRedis} from "../../../../utils/redis";
|
||||
|
||||
export default async function artifactHandler({query: {id}}, res) {
|
||||
|
||||
let characters = JSON.parse(await getResultFromRedis('character-all'));
|
||||
if (!characters) {
|
||||
characters = await getCharacters();
|
||||
addResultToRedis('character-all', JSON.stringify(characters)).catch(console.error)
|
||||
}
|
||||
|
||||
const closestCharacters = []
|
||||
getClosest(id, characters).forEach(a => {
|
||||
closestCharacters.push(characters[a.name])
|
||||
})
|
||||
|
||||
if (closestCharacters) {
|
||||
res.status(200).json(closestCharacters);
|
||||
} else {
|
||||
res.status(404).json({message: `Character ${id} not found`});
|
||||
}
|
||||
}
|
37
pages/api/characters/utils.js
Normal file
37
pages/api/characters/utils.js
Normal file
|
@ -0,0 +1,37 @@
|
|||
import {weapons} from "../weapons/utils";
|
||||
import {getElements} from "../elements/utils";
|
||||
import {getItems} from "../items/utils";
|
||||
import {getBuilds} from "../builds/utils";
|
||||
|
||||
const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor;
|
||||
|
||||
export async function getCharacters() {
|
||||
|
||||
const builds = await getBuilds();
|
||||
|
||||
let func = (await (await fetch(
|
||||
"https://raw.githubusercontent.com/MadeBaruna/paimon-moe/main/src/data/characters.js",
|
||||
)).text());
|
||||
func = func.substr(func.indexOf("export const characters ="));
|
||||
const characters = await new AsyncFunction(
|
||||
"weapons",
|
||||
"elements",
|
||||
"itemList",
|
||||
func.replace("export const characters = ", "return"),
|
||||
)(weapons, await getElements(), await getItems());
|
||||
|
||||
for (let chr in characters){
|
||||
characters[chr].builds = builds[chr]['roles'];
|
||||
for (let y in characters[chr]['ascension']) {
|
||||
for (let x in characters[chr]['ascension'][y].items) {
|
||||
if (!characters[chr]['ascension'][y]["items"][x]["amount"]) {
|
||||
delete characters[chr]['ascension'][y]["items"].splice(x, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return characters;
|
||||
|
||||
}
|
10
pages/api/domains/[id].js
Normal file
10
pages/api/domains/[id].js
Normal file
|
@ -0,0 +1,10 @@
|
|||
import {getDomains} from "./utils";
|
||||
|
||||
export default async function domainHandler({query : {id}}, res) {
|
||||
const domains = await getDomains();
|
||||
if (domains[id]) {
|
||||
res.status(200).json(domains[id]);
|
||||
} else {
|
||||
res.status(404).json({message: `Domain ${id} doesn't exist`});
|
||||
}
|
||||
}
|
10
pages/api/domains/index.js
Normal file
10
pages/api/domains/index.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
import {getDomains} from "./utils";
|
||||
|
||||
export default async function handler(req, res) {
|
||||
const domains = await getDomains();
|
||||
if (domains) {
|
||||
res.status(200).json(Object.keys(domains));
|
||||
} else {
|
||||
res.status(404).json({message: "An error has occurred"});
|
||||
}
|
||||
}
|
11
pages/api/domains/utils.js
Normal file
11
pages/api/domains/utils.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
const AsyncFunction = Object.getPrototypeOf(async function () {
|
||||
}).constructor;
|
||||
|
||||
|
||||
export async function getDomains() {
|
||||
return await new AsyncFunction(
|
||||
(await (await fetch(
|
||||
"https://raw.githubusercontent.com/MadeBaruna/paimon-moe/main/src/data/domain.js",
|
||||
)).text()).replace("export const domains =", "return"),
|
||||
)();
|
||||
}
|
12
pages/api/elements/[id].js
Normal file
12
pages/api/elements/[id].js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import {getElements} from "./utils.js";
|
||||
|
||||
|
||||
export default async function elementsHandler({ query: { id } }, res) {
|
||||
const element = await getElements();
|
||||
console.log(element, id);
|
||||
if (element[id]) {
|
||||
res.status(200).json(element[id]);
|
||||
} else {
|
||||
res.status(404).json({ message: `Element ${id} not found` });
|
||||
}
|
||||
}
|
10
pages/api/elements/index.js
Normal file
10
pages/api/elements/index.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
import {getElements} from "./utils.js";
|
||||
|
||||
export default async function handler(req, res) {
|
||||
const elements = await getElements();
|
||||
if (elements) {
|
||||
res.status(200).json(Object.keys(elements));
|
||||
} else {
|
||||
res.status(404).json({ message: 'An error occurred' });
|
||||
}
|
||||
}
|
25
pages/api/elements/utils.js
Normal file
25
pages/api/elements/utils.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor;
|
||||
|
||||
const elementColor = {
|
||||
anemo: 0x7fffd4,
|
||||
cryo: 0xd6fffa,
|
||||
dendro: 0x7de91c,
|
||||
electro: 0xbf00ff,
|
||||
geo: 0xffbf00,
|
||||
hydro: 0x0f5e9c,
|
||||
pyro: 0xe35822
|
||||
}
|
||||
|
||||
export async function getElements() {
|
||||
let elements = await new AsyncFunction(
|
||||
(await (await fetch(
|
||||
"https://raw.githubusercontent.com/MadeBaruna/paimon-moe/main/src/data/elements.js",
|
||||
)).text()).replace("export const elements =", "return"),
|
||||
)();
|
||||
|
||||
Object.keys(elements).forEach(k => {
|
||||
elements[k].color = elementColor[k];
|
||||
})
|
||||
|
||||
return elements;
|
||||
}
|
13
pages/api/events/current.js
Normal file
13
pages/api/events/current.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
import {compareEndTimes, isCurrentEvent} from "../../../utils/time";
|
||||
import {getEvents} from "./utils";
|
||||
|
||||
export default async function currentEvents(req, res){
|
||||
const allEvents = await getEvents();
|
||||
let currents = allEvents.flat().map(isCurrentEvent).filter(x=>x);
|
||||
currents = currents.sort(compareEndTimes);
|
||||
if (currents) {
|
||||
res.status(200).json(currents);
|
||||
} else {
|
||||
res.status(404).json({message: "There is no event currently going"});
|
||||
}
|
||||
}
|
10
pages/api/events/index.js
Normal file
10
pages/api/events/index.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
import {getEvents} from "./utils";
|
||||
|
||||
export default async function handler(req, res) {
|
||||
const events = await getEvents();
|
||||
if (events) {
|
||||
res.status(200).json(events);
|
||||
} else {
|
||||
res.status(404).json({message: "An error has occured"});
|
||||
}
|
||||
}
|
13
pages/api/events/upcoming.js
Normal file
13
pages/api/events/upcoming.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
import {getEvents} from "./utils";
|
||||
import {compareStartTimes, isUpcomingEvent} from "../../../utils/time";
|
||||
|
||||
export default async function upcomingEvents(req, res){
|
||||
const allEvents = await getEvents();
|
||||
let upcoming = allEvents.flat().map(isUpcomingEvent).filter(x=>x);
|
||||
upcoming = upcoming.sort(compareStartTimes);
|
||||
if (upcoming){
|
||||
res.status(200).json(upcoming);
|
||||
} else {
|
||||
res.status(404).json({message: "There is no upcoming event"});
|
||||
}
|
||||
}
|
12
pages/api/events/utils.js
Normal file
12
pages/api/events/utils.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import {isCurrentEvent} from "../../../utils/time";
|
||||
|
||||
const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor;
|
||||
|
||||
export async function getEvents(){
|
||||
const allEvents = await new AsyncFunction(
|
||||
(await (await fetch(
|
||||
"https://raw.githubusercontent.com/MadeBaruna/paimon-moe/main/src/data/timeline.js",
|
||||
)).text()).replace("export const eventsData = ", "return"),
|
||||
)();
|
||||
return allEvents;
|
||||
}
|
5
pages/api/index.js
Normal file
5
pages/api/index.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
const fs = require('fs')
|
||||
export default function handle(req, res) {
|
||||
const dirs = fs.readdirSync('./pages/api').filter(x=>x != "index.js")
|
||||
res.status(200).json(dirs)
|
||||
}
|
21
pages/api/items/[id].js
Normal file
21
pages/api/items/[id].js
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { getItems } from "./utils";
|
||||
import {addResultToRedis, getResultFromRedis} from "../../../utils/redis";
|
||||
import {getArtifacts} from "../artifacts/utils";
|
||||
|
||||
export default async function itemsHandler({ query: { id } }, res) {
|
||||
let item = JSON.parse(await getResultFromRedis(`item-${id}`))
|
||||
if (!item) {
|
||||
let items = JSON.parse(await getResultFromRedis("item-all"));
|
||||
if (!items){
|
||||
items = await getItems();
|
||||
addResultToRedis("item-all", JSON.stringify(items)).catch(console.error);
|
||||
}
|
||||
item = items[id]
|
||||
}
|
||||
if (item) {
|
||||
res.status(200).json(item);
|
||||
addResultToRedis(`item-${id}`, JSON.stringify(item)).catch(console.error)
|
||||
} else {
|
||||
res.status(404).json({ message: `Item ${id} not found` });
|
||||
}
|
||||
}
|
16
pages/api/items/index.js
Normal file
16
pages/api/items/index.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { getItems } from "./utils";
|
||||
import {addResultToRedis, getResultFromRedis} from "../../../utils/redis";
|
||||
|
||||
export default async function handler(req, res) {
|
||||
let items = JSON.parse(await getResultFromRedis('item-all'))
|
||||
if (!items) {
|
||||
items = await getItems();
|
||||
}
|
||||
|
||||
if (items) {
|
||||
res.status(200).json(Object.keys(items));
|
||||
addResultToRedis('item-all', JSON.stringify(items)).catch(console.error)
|
||||
} else {
|
||||
res.status(404).json({ message: 'An error occurred' });
|
||||
}
|
||||
}
|
23
pages/api/items/search/[id].js
Normal file
23
pages/api/items/search/[id].js
Normal file
|
@ -0,0 +1,23 @@
|
|||
import {getItems} from "../utils";
|
||||
import {getClosest} from "../../../../utils/levenshtein";
|
||||
import {addResultToRedis, getResultFromRedis} from "../../../../utils/redis";
|
||||
|
||||
export default async function itemHandler({query: {id}}, res) {
|
||||
|
||||
let items = JSON.parse(await getResultFromRedis('item-all'));
|
||||
if (!items) {
|
||||
items = await getItems();
|
||||
addResultToRedis('item-all', JSON.stringify(items)).catch(console.error)
|
||||
}
|
||||
|
||||
const closestItems = []
|
||||
getClosest(id, items).forEach(a => {
|
||||
closestItems.push(items[a.name])
|
||||
})
|
||||
|
||||
if (closestItems) {
|
||||
res.status(200).json(closestItems);
|
||||
} else {
|
||||
res.status(404).json({message: `Item ${id} not found`});
|
||||
}
|
||||
}
|
9
pages/api/items/utils.js
Normal file
9
pages/api/items/utils.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
const AsyncFunction = Object.getPrototypeOf(async function () { }).constructor;
|
||||
|
||||
export async function getItems() {
|
||||
return await new AsyncFunction(
|
||||
(await (await fetch(
|
||||
"https://raw.githubusercontent.com/MadeBaruna/paimon-moe/main/src/data/itemList.js",
|
||||
)).text()).replace("export const itemList =", "return"),
|
||||
)();
|
||||
}
|
21
pages/api/weapons/[id].js
Normal file
21
pages/api/weapons/[id].js
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { getWeapons } from "./utils";
|
||||
import {addResultToRedis, getResultFromRedis} from "../../../utils/redis";
|
||||
|
||||
export default async function weaponsHandler({ query: { id } }, res) {
|
||||
let weapon = JSON.parse(await getResultFromRedis(`weapon-${id}`));
|
||||
if (!weapon) {
|
||||
let weapons = JSON.parse(await getResultFromRedis("weapon-all"));
|
||||
if (!weapons){
|
||||
weapons = await getWeapons();
|
||||
addResultToRedis("weapon-all", JSON.stringify(weapons)).catch(console.error);
|
||||
}
|
||||
weapon = weapons[id];
|
||||
}
|
||||
|
||||
if (weapon) {
|
||||
res.status(200).json(weapon);
|
||||
addResultToRedis(`weapon-${id}`, JSON.stringify(weapon)).catch(console.error);
|
||||
} else {
|
||||
res.status(404).json({ message: `Item ${id} not found` });
|
||||
}
|
||||
}
|
16
pages/api/weapons/index.js
Normal file
16
pages/api/weapons/index.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { getWeapons } from "./utils";
|
||||
import {addResultToRedis, getResultFromRedis} from "../../../utils/redis";
|
||||
|
||||
export default async function handler(req, res) {
|
||||
|
||||
let weapons = JSON.parse(await getResultFromRedis("weapon-all"));
|
||||
if (!weapons)
|
||||
weapons = await getWeapons();
|
||||
|
||||
if (weapons) {
|
||||
res.status(200).json(Object.keys(weapons));
|
||||
addResultToRedis("weapon-all", JSON.stringify(weapons)).catch(console.error);
|
||||
} else {
|
||||
res.status(404).json({ message: 'An error has occurred' });
|
||||
}
|
||||
}
|
23
pages/api/weapons/search/[id].js
Normal file
23
pages/api/weapons/search/[id].js
Normal file
|
@ -0,0 +1,23 @@
|
|||
import {getWeapons} from "../utils";
|
||||
import {getClosest} from "../../../../utils/levenshtein";
|
||||
import {addResultToRedis, getResultFromRedis} from "../../../../utils/redis";
|
||||
|
||||
export default async function weaponsHandler({query: {id}}, res) {
|
||||
|
||||
let weapons = JSON.parse(await getResultFromRedis('weapon-all'));
|
||||
if (!weapons) {
|
||||
weapons = await getWeapons();
|
||||
addResultToRedis('weapon-all', JSON.stringify(weapons)).catch(console.error)
|
||||
}
|
||||
|
||||
const closestWeapons = []
|
||||
getClosest(id, weapons).forEach(w => {
|
||||
closestWeapons.push(weapons[w.name])
|
||||
})
|
||||
|
||||
if (closestWeapons) {
|
||||
res.status(200).json(closestWeapons);
|
||||
} else {
|
||||
res.status(404).json({message: `Weapon ${id} not found`});
|
||||
}
|
||||
}
|
47
pages/api/weapons/utils.js
Normal file
47
pages/api/weapons/utils.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
import { getItems } from "../items/utils";
|
||||
|
||||
const AsyncFunction = Object.getPrototypeOf(async function () { }).constructor;
|
||||
|
||||
export const weapons = {
|
||||
sword: {
|
||||
id: "sword",
|
||||
name: "Sword",
|
||||
},
|
||||
bow: {
|
||||
id: "bow",
|
||||
name: "Bow",
|
||||
},
|
||||
polearm: {
|
||||
id: "polearm",
|
||||
name: "Polearm",
|
||||
},
|
||||
claymore: {
|
||||
id: "claymore",
|
||||
name: "Claymore",
|
||||
},
|
||||
catalyst: {
|
||||
id: "catalyst",
|
||||
name: "Catalyst",
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
export async function getWeapons() {
|
||||
|
||||
const data = JSON.parse(await (await fetch("https://raw.githubusercontent.com/MadeBaruna/paimon-moe/main/src/data/weapons/en.json")).text());
|
||||
|
||||
let func = (await (await fetch(
|
||||
"https://raw.githubusercontent.com/MadeBaruna/paimon-moe/main/src/data/weaponList.js",
|
||||
)).text());
|
||||
func = func.slice(func.indexOf("export const weaponList ="));
|
||||
|
||||
let weaponList = await new AsyncFunction("weapons", "itemList",
|
||||
func.replace("export const weaponList = ", "return"),
|
||||
)(weapons, await getItems());
|
||||
|
||||
Object.values(weaponList).forEach(x => {
|
||||
weaponList[x.id].extras = data[x.id];
|
||||
})
|
||||
|
||||
return weaponList;
|
||||
}
|
18
utils/levenshtein.js
Normal file
18
utils/levenshtein.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
const levenshtein = require("fast-levenshtein");
|
||||
|
||||
export function getClosest(input, list, limit=5){
|
||||
let t0 = performance.now();
|
||||
const things = []
|
||||
for (let s in list) {
|
||||
let ns = s.replaceAll("_"," ");
|
||||
if (ns.toLowerCase().includes(input.toLowerCase())){
|
||||
things.push({name: s, dist: 0})
|
||||
continue;
|
||||
}
|
||||
things.push({name: s, dist: levenshtein.get(input, ns)})
|
||||
}
|
||||
things.sort((a,b) => a.dist - b.dist);
|
||||
let t1 = performance.now();
|
||||
console.debug(`Levenshtein took ${t1-t0} ms`)
|
||||
return things.splice(0,limit);
|
||||
}
|
15
utils/redis.js
Normal file
15
utils/redis.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
const redis = require("redis");
|
||||
const client = redis.createClient("redis://localhost:6379");
|
||||
client.connect();
|
||||
|
||||
|
||||
export async function getResultFromRedis(key){
|
||||
if (await client.exists(key)) {
|
||||
return await client.get(key)
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export async function addResultToRedis(key, value){
|
||||
await client.set(key, value, {EX: 600});
|
||||
}
|
52
utils/time.js
Normal file
52
utils/time.js
Normal file
|
@ -0,0 +1,52 @@
|
|||
const dayjs = require('dayjs');
|
||||
|
||||
export const getTimeDifferenceAsia = () => {
|
||||
const now = dayjs();
|
||||
const local = now.utcOffset();
|
||||
const serverTime = now.utcOffset(8);
|
||||
return serverTime - local;
|
||||
};
|
||||
|
||||
function convertToNow(event){
|
||||
let start;
|
||||
if (event["timezoneDependent"]) {
|
||||
start = dayjs(event.start, 'YYYY-MM-DD HH:mm:ss').subtract(getTimeDifferenceAsia(), 'minute');
|
||||
} else {
|
||||
start = dayjs(event.start, 'YYYY-MM-DD HH:mm:ss').subtract(0, 'minute');
|
||||
}
|
||||
const end = dayjs(event.end, 'YYYY-MM-DD HH:mm:ss').subtract(0, 'minute');
|
||||
|
||||
return [start, end];
|
||||
}
|
||||
|
||||
export function isCurrentEvent(event) {
|
||||
const [start, end] = convertToNow(event);
|
||||
|
||||
const timeSinceStart = -start.diff(dayjs(), 'day', true);
|
||||
const timeUntilEnd = end.diff(dayjs(), 'day', true);
|
||||
|
||||
if (timeSinceStart > 0 && timeUntilEnd > 0){
|
||||
event["startTimestamp"] = start.unix();
|
||||
event["endTimestamp"] = end.unix();
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
||||
export function isUpcomingEvent(event){
|
||||
const [start, ] = convertToNow(event);
|
||||
const timeUntilStart = start.diff(dayjs(), 'day', true);
|
||||
|
||||
if (timeUntilStart > 0){
|
||||
event["startTimestamp"] = start.unix();
|
||||
event["endTimestamp"] = 0;
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
||||
export function compareStartTimes(a, b) {
|
||||
return dayjs(a.start).diff(dayjs(b.start), 'day', true);
|
||||
}
|
||||
|
||||
export function compareEndTimes(a, b) {
|
||||
return dayjs(a.end).diff(dayjs(b.end), 'day', true);
|
||||
}
|
Loading…
Reference in a new issue