add count logging w redis + display on main page

This commit is contained in:
cnrad
2022-02-22 18:03:41 -05:00
parent 2adf379833
commit de3950acb8
7 changed files with 131 additions and 3 deletions

1
.env Normal file
View File

@@ -0,0 +1 @@
REDIS_URL=rediss://:b608c52a48584bf584b97d7a92a9bd97@us1-excited-honeybee-34947.upstash.io:34947

View File

@@ -10,11 +10,13 @@
}, },
"dependencies": { "dependencies": {
"@types/escape-html": "^1.0.1", "@types/escape-html": "^1.0.1",
"@types/ioredis": "^4.28.8",
"@types/styled-components": "^5.1.10", "@types/styled-components": "^5.1.10",
"axios": "^0.21.1", "axios": "^0.21.1",
"escape-html": "^1.0.3", "escape-html": "^1.0.3",
"framer-motion": "^4.1.17", "framer-motion": "^4.1.17",
"image-to-base64": "^2.2.0", "image-to-base64": "^2.2.0",
"ioredis": "^4.28.5",
"next": "11.0.0", "next": "11.0.0",
"react": "17.0.2", "react": "17.0.2",
"react-dom": "17.0.2", "react-dom": "17.0.2",

View File

@@ -2,6 +2,7 @@ import type { NextApiRequest, NextApiResponse } from "next";
import axios from "axios"; import axios from "axios";
import renderCard from "../../src/renderCard"; import renderCard from "../../src/renderCard";
import { isSnowflake } from "../../src/snowflake"; import { isSnowflake } from "../../src/snowflake";
import redis from "../../src/redis";
type Data = { type Data = {
id?: string | string[]; id?: string | string[];
@@ -30,7 +31,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
try { try {
getUser = await axios(`https://api.lanyard.rest/v1/users/${userId}`); getUser = await axios(`https://api.lanyard.rest/v1/users/${userId}`);
} catch (error) { } catch (error: any) {
if (error.response.status === 404) return res.status(404).send({ error: "Invalid user!" }); if (error.response.status === 404) return res.status(404).send({ error: "Invalid user!" });
console.log(error); // Only console log the error if its not a 404 console.log(error); // Only console log the error if its not a 404
@@ -40,6 +41,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
}); });
} }
let user = await redis.hget("users", userId);
if (!user) await redis.hset("users", userId, "true");
res.setHeader("Content-Type", "image/svg+xml; charset=utf-8"); res.setHeader("Content-Type", "image/svg+xml; charset=utf-8");
res.setHeader("content-security-policy", "default-src 'none'; img-src * data:; style-src 'unsafe-inline'"); res.setHeader("content-security-policy", "default-src 'none'; img-src * data:; style-src 'unsafe-inline'");

View File

@@ -0,0 +1,9 @@
import type { NextApiRequest, NextApiResponse } from "next";
import redis from "../../src/redis";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
let users = await redis.hgetall("users");
let count = Object.keys(users);
res.status(200).send({ count: count.length });
}

View File

@@ -1,8 +1,10 @@
import Head from "next/head"; import Head from "next/head";
import styled, { createGlobalStyle } from "styled-components"; import styled, { createGlobalStyle } from "styled-components";
import { useState } from "react"; import { useState, useEffect } from "react";
import axios from "axios";
export default function Home() { export default function Home() {
const [userCount, setUserCount] = useState<null | number>(null);
const [userId, setUserId] = useState<null | string>(null); const [userId, setUserId] = useState<null | string>(null);
const [copyState, setCopyState] = useState("Copy"); const [copyState, setCopyState] = useState("Copy");
const copy = () => { const copy = () => {
@@ -13,6 +15,13 @@ export default function Home() {
setTimeout(() => setCopyState("Copy"), 1500); setTimeout(() => setCopyState("Copy"), 1500);
}; };
useEffect(() => {
(async () => {
let userCount = await axios.get("/api/getUserCount").then(res => res.data);
setUserCount(userCount.count);
})();
}, []);
return ( return (
<> <>
<GlobalStyle /> <GlobalStyle />
@@ -47,7 +56,13 @@ export default function Home() {
)](https://discord.com/users/{userId}) )](https://discord.com/users/{userId})
</Output> </Output>
<Copy onClick={copy}>{copyState}</Copy> <Copy onClick={copy}>{copyState}</Copy>
<a href='https://github.com/cnrad/lanyard-profile-readme#options' target="_blank" rel="noreferrer"><Options>Options</Options></a> <a
href="https://github.com/cnrad/lanyard-profile-readme#options"
target="_blank"
rel="noreferrer"
>
<Options>Options</Options>
</a>
<Example <Example
src={`/api/${userId}`} src={`/api/${userId}`}
alt="[Please provide a valid user ID!]" alt="[Please provide a valid user ID!]"
@@ -57,6 +72,9 @@ export default function Home() {
) : null} ) : null}
</Container> </Container>
</Main> </Main>
<FooterStat>
Lanyard Profile Readme has <b>{userCount}</b> recorded users!
</FooterStat>
</> </>
); );
} }
@@ -85,6 +103,7 @@ const GlobalStyle = createGlobalStyle`
const Main = styled.div` const Main = styled.div`
display: flex; display: flex;
flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
margin: 0; margin: 0;
@@ -212,3 +231,15 @@ const Example = styled.img`
width: 100%; width: 100%;
filter: drop-shadow(0px 3px 15px rgba(0, 0, 0, 0.2)); filter: drop-shadow(0px 3px 15px rgba(0, 0, 0, 0.2));
`; `;
const FooterStat = styled.div`
position: absolute;
line-height: 1rem;
bottom: 1rem;
left: 50%;
transform: translate(-50%, 0);
background: rgba(0, 0, 0, 0.5);
padding: 1rem 1.25rem;
color: #fff;
border-radius: 0.5rem;
`;

5
src/redis.ts Normal file
View File

@@ -0,0 +1,5 @@
import Redis from "ioredis";
const redis = new Redis(process.env.REDIS_URL);
export default redis;

View File

@@ -289,6 +289,13 @@
resolved "https://registry.yarnpkg.com/@types/image-to-base64/-/image-to-base64-2.1.0.tgz#8c77b09b7988df3a9a2a4278bbcc27efabbec379" resolved "https://registry.yarnpkg.com/@types/image-to-base64/-/image-to-base64-2.1.0.tgz#8c77b09b7988df3a9a2a4278bbcc27efabbec379"
integrity sha512-UgmqJVJyPIkzzI23TWqLc9iO+hZTzNoVD0rEf+I70FeKtcxxvLIlKJ5CrejkxkvDc/8/lk9yswSYZoAv8eyOYQ== integrity sha512-UgmqJVJyPIkzzI23TWqLc9iO+hZTzNoVD0rEf+I70FeKtcxxvLIlKJ5CrejkxkvDc/8/lk9yswSYZoAv8eyOYQ==
"@types/ioredis@^4.28.8":
version "4.28.8"
resolved "https://registry.yarnpkg.com/@types/ioredis/-/ioredis-4.28.8.tgz#a181d6eb70e402a6db670fe54b9c5bb66c0fac17"
integrity sha512-mULOyO2smtvkE1zmzRRA4P0+1UjEqusi014kXOL1q3CY0RgqkR5/wKvv+vAJbPw2Q66wPyylKeevUy+m/FaRMg==
dependencies:
"@types/node" "*"
"@types/json5@^0.0.29": "@types/json5@^0.0.29":
version "0.0.29" version "0.0.29"
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
@@ -798,6 +805,11 @@ classnames@2.2.6:
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
cluster-key-slot@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d"
integrity sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==
color-convert@^1.9.0: color-convert@^1.9.0:
version "1.9.3" version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
@@ -1002,6 +1014,11 @@ define-properties@^1.1.3:
dependencies: dependencies:
object-keys "^1.0.12" object-keys "^1.0.12"
denque@^1.1.0:
version "1.5.1"
resolved "https://registry.yarnpkg.com/denque/-/denque-1.5.1.tgz#07f670e29c9a78f8faecb2566a1e2c11929c5cbf"
integrity sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==
depd@~1.1.2: depd@~1.1.2:
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
@@ -1770,6 +1787,23 @@ internal-slot@^1.0.3:
has "^1.0.3" has "^1.0.3"
side-channel "^1.0.4" side-channel "^1.0.4"
ioredis@^4.28.5:
version "4.28.5"
resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.28.5.tgz#5c149e6a8d76a7f8fa8a504ffc85b7d5b6797f9f"
integrity sha512-3GYo0GJtLqgNXj4YhrisLaNNvWSNwSS2wS4OELGfGxH8I69+XfNdnmV1AyN+ZqMh0i7eX+SWjrwFKDBDgfBC1A==
dependencies:
cluster-key-slot "^1.1.0"
debug "^4.3.1"
denque "^1.1.0"
lodash.defaults "^4.2.0"
lodash.flatten "^4.4.0"
lodash.isarguments "^3.1.0"
p-map "^2.1.0"
redis-commands "1.7.0"
redis-errors "^1.2.0"
redis-parser "^3.0.0"
standard-as-callback "^2.1.0"
is-arguments@^1.0.4: is-arguments@^1.0.4:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9"
@@ -2025,6 +2059,21 @@ lodash.clonedeep@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
lodash.defaults@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=
lodash.flatten@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
lodash.isarguments@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=
lodash.merge@^4.6.2: lodash.merge@^4.6.2:
version "4.6.2" version "4.6.2"
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
@@ -2392,6 +2441,11 @@ p-locate@^4.1.0:
dependencies: dependencies:
p-limit "^2.2.0" p-limit "^2.2.0"
p-map@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175"
integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==
p-try@^1.0.0: p-try@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
@@ -2749,6 +2803,23 @@ readdirp@~3.5.0:
dependencies: dependencies:
picomatch "^2.2.1" picomatch "^2.2.1"
redis-commands@1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.7.0.tgz#15a6fea2d58281e27b1cd1acfb4b293e278c3a89"
integrity sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==
redis-errors@^1.0.0, redis-errors@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad"
integrity sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=
redis-parser@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4"
integrity sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=
dependencies:
redis-errors "^1.0.0"
regenerator-runtime@^0.13.4: regenerator-runtime@^0.13.4:
version "0.13.7" version "0.13.7"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55"
@@ -2983,6 +3054,11 @@ stacktrace-parser@0.1.10:
dependencies: dependencies:
type-fest "^0.7.1" type-fest "^0.7.1"
standard-as-callback@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45"
integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==
"statuses@>= 1.5.0 < 2": "statuses@>= 1.5.0 < 2":
version "1.5.0" version "1.5.0"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"