Skip to content

Commit e294207

Browse files
authored
Merge pull request #82 from scinscinscin/main
📦NEW: Add web and cli dashboard
2 parents 96ca817 + cf29faf commit e294207

29 files changed

+1524
-253
lines changed

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"license": "GPL-3.0",
3131
"devDependencies": {
3232
"@types/asciichart": "^1.5.4",
33+
"@types/blessed": "^0.1.17",
3334
"@types/express": "^4.17.11",
3435
"@types/minimist": "^1.2.1",
3536
"@types/morgan": "^1.9.2",
@@ -43,10 +44,13 @@
4344
"dependencies": {
4445
"asciichart": "^1.5.25",
4546
"axios": "^0.21.1",
47+
"blessed": "^0.1.81",
48+
"blessed-contrib": "^4.8.21",
4649
"colors": "^1.4.0",
4750
"express": "^4.17.1",
4851
"minimist": "^1.2.5",
4952
"morgan": "^1.10.0",
50-
"typescript": "^4.2.3"
53+
"typescript": "^4.2.3",
54+
"world-countries": "^4.0.0"
5155
}
5256
}

src/api.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,30 @@
11
import express from "express";
22
import morgan from "morgan";
3+
import { dashboardRouter } from "./api/dashboardRouter";
34
import { errorHandler } from "./api/errorHandler";
45
import { plainRouter } from "./api/plainRouter";
5-
import { router } from "./api/router";
6+
import { regularRouter } from "./api/regularRouter";
67
import { userAgentMiddleware } from "./api/userAgent";
7-
import { lines } from "./utils/getResponses";
8+
import { lines } from "./utils/libs/getResponses";
89

910
const port = parseInt(process.env.PORT!) || 7070;
1011

1112
const app = express();
1213
app.use(morgan("common"));
14+
app.use("/history/web/charts", dashboardRouter);
15+
1316
app.use(userAgentMiddleware);
1417

18+
app.use("/history/charts", dashboardRouter);
19+
1520
/**
1621
* Plain CMD/Basic routes have both quiet and full modes
1722
* Same with regular / routes with ansi color codes
1823
*/
1924
app.use(["/quiet/basic", "/quiet/cmd", "/quiet/plain"], plainRouter);
2025
app.use(["/basic", "/cmd", "/plain"], plainRouter);
2126

22-
app.use(["/quiet", "/"], router);
27+
app.use(["/quiet", "/"], regularRouter);
2328
app.use("/", errorHandler);
2429

2530
// Not found handler

src/api/dashboardRouter.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { Request, Router } from "express";
2+
import {
3+
globalDashboard,
4+
DashboardSize,
5+
countryDashboard,
6+
} from "../utils/routes/dashboard/dashboardHandlers";
7+
import handleAsync from "./handleAsync";
8+
import { isTerminal } from "./userAgent";
9+
10+
export const dashboardRouter = Router({ mergeParams: true });
11+
12+
/**
13+
*
14+
* @param req Express request
15+
* @returns True if the request is from a not from wget, curl or httpie
16+
*/
17+
const isWeb: (req: Request) => boolean = (req) => {
18+
// Check if the link is asking for web version of dashboard
19+
const link = req.baseUrl.startsWith("/history/web/charts");
20+
// Check if the user agent is NOT coming from terminal based application
21+
const isNotTerminal = !isTerminal(req.headers["user-agent"]);
22+
return link && isNotTerminal;
23+
};
24+
25+
dashboardRouter.get(
26+
"/:size?",
27+
handleAsync(async (req, res, next) => {
28+
// Get parameters from request
29+
let size = req.params.size as DashboardSize;
30+
31+
// Set default size and check then check if size var matches
32+
if (size === undefined) size = "sm";
33+
if (!["sm", "md", "lg"].includes(size)) return next();
34+
35+
let response = await globalDashboard(size, isWeb(req));
36+
res.send(response);
37+
})
38+
);
39+
40+
dashboardRouter.get(
41+
"/:country/:size?",
42+
handleAsync(async (req, res, next) => {
43+
// Get parameters from request
44+
let country = req.params.country;
45+
let size = req.params.size as DashboardSize;
46+
47+
// Set default size and check then check if size var matches
48+
if (size === undefined) size = "sm";
49+
if (!["sm", "md", "lg"].includes(size)) return next();
50+
51+
let response = await countryDashboard(country, size, isWeb(req));
52+
res.send(response);
53+
})
54+
);

src/api/plainRouter.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import {
55
informationPerCountryPlain,
66
historyPerCountryPlain,
77
globalHistoryPlain,
8-
} from "../utils/plainHandlers";
9-
import { isQuiet } from "./router";
8+
} from "../utils/routes/plain/plainHandlers";
9+
import { isQuiet } from "./regularRouter";
1010

1111
/**
1212
* The plainRouter handles all the plain routes such as /basic, /cmd, and /plain

src/api/router.ts renamed to src/api/regularRouter.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
globalInformation,
55
historyPerCountry,
66
informationPerCountry,
7-
} from "../utils/handlers";
7+
} from "../utils/routes/regular/regularHandlers";
88
import handleAsync from "./handleAsync";
99

1010
/**
@@ -16,13 +16,12 @@ export const isQuiet: (req: Request) => boolean = (req) =>
1616
req.baseUrl.startsWith("/quiet");
1717

1818
/**
19-
* The rootRouter handles all the processing of the requests *after* passing through
19+
* The regularRouter handles all the processing of the requests *after* passing through
2020
* all middlewares except not found and error handling middleware
2121
*/
22-
export const router = Router({ mergeParams: true });
22+
export const regularRouter = Router({ mergeParams: true });
2323

24-
// rootRouter.get("/history/:country/:type", historyPerCountryAndType);
25-
router.get(
24+
regularRouter.get(
2625
"/history/:mode?",
2726
handleAsync(async (req, res, next) => {
2827
// get mode from params
@@ -37,7 +36,7 @@ router.get(
3736
})
3837
);
3938

40-
router.get(
39+
regularRouter.get(
4140
"/history/:country/:mode?",
4241
handleAsync(async (req, res, next) => {
4342
const country = req.params.country;
@@ -53,15 +52,15 @@ router.get(
5352
})
5453
);
5554

56-
router.get(
55+
regularRouter.get(
5756
"/:country",
5857
handleAsync(async (req, res, _next) => {
5958
const country = req.params.country;
6059
res.send(await informationPerCountry(country, isQuiet(req)));
6160
})
6261
);
6362

64-
router.get(
63+
regularRouter.get(
6564
"/",
6665
handleAsync(async (req, res, _next) => {
6766
res.send(await globalInformation(isQuiet(req)));

src/api/userAgent.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Request, Response, NextFunction } from "express";
2-
import { lines } from "../utils/getResponses";
2+
import { lines } from "../utils/libs/getResponses";
33

44
// Type of middleware and handler
55
export type Handler = (
@@ -13,7 +13,9 @@ export type Handler = (
1313
* @param userAgent The user agent of the requester
1414
* @returns A boolean that is true of the user agent provided is from curl / wget / httpie
1515
*/
16-
const isTerminal: (userAgent: string | undefined) => boolean = (userAgent) => {
16+
export const isTerminal: (userAgent: string | undefined) => boolean = (
17+
userAgent
18+
) => {
1719
if (userAgent === undefined) return false;
1820
if (/curl|wget|httpie/i.test(userAgent)) return true;
1921
return false;

src/cli.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
#!/usr/bin/env node
22
import argv from "minimist";
3-
import { lines, welcomeMessage } from "./utils/getResponses";
3+
import { lines, welcomeMessage } from "./utils/libs/getResponses";
44
import {
55
globalHistory,
66
globalInformation,
77
historyPerCountry,
88
informationPerCountry,
9-
} from "./utils/handlers";
9+
} from "./utils/routes/regular/regularHandlers";
1010
import {
1111
globalHistoryPlain,
1212
globalInformationPlain,
1313
historyPerCountryPlain,
1414
informationPerCountryPlain,
15-
} from "./utils/plainHandlers";
15+
} from "./utils/routes/plain/plainHandlers";
1616

1717
const args = argv(process.argv.slice(2));
1818
let { history, mode, help, quiet, plain } = args;

0 commit comments

Comments
 (0)