-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
135 lines (113 loc) · 4.01 KB
/
Copy pathindex.js
File metadata and controls
135 lines (113 loc) · 4.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
const fs = require("fs");
const http = require("http");
const https = require("https");
const [{ APIKEY }] = require("./auth/credentials.json");
const port = 3000;
const cachedQuoteFilePath = "auth/cachedQuote.json";
const server = http.createServer();
server.on("listening", listen_handler);
server.listen(port);
function listen_handler() {
console.log(`Now Listening on Port ${port}`);
}
server.on("request", request_handler);
function request_handler(req, res) {
console.log(`New Request from ${req.socket.remoteAddress} for ${req.url}`);
if (req.url === "/") {
const form = fs.createReadStream("html/index.html");
res.writeHead(200, { "Content-Type": "text/html" });
form.pipe(res);
} else if (req.url.startsWith("/cat_and_quote")) {
const user_input = new URL(req.url, `https://${req.headers.host}`).searchParams;
const limit = user_input.get("limit");
cat_api(limit, res);
} else {
not_found(res);
}
}
function not_found(res) {
res.writeHead(404, { "Content-Type": "text/html" });
res.end(`<h1>404 Not Found</h1>`);
}
function cat_api(limit, res) {
if (isNaN(limit) || limit < 1 || limit > 20) {
res.writeHead(400, { "Content-Type": "text/plain" });
res.end("Error: Limit must be between 1 and 20");
return;
}
const apiEndpoint = "https://api.thecatapi.com/v1/images/search";
const queryParams = new URLSearchParams({ limit }).toString();
const apiUrl = `${apiEndpoint}?${queryParams}`;
const options = {
method: "GET",
headers: {
"Content-Type": "application/json",
"x-api-key": APIKEY,
},
};
https.get(apiUrl, options, (catApiStream) => {
process_stream(catApiStream, (body) => {
anime_quote(body, res);
});
});
}
function anime_quote(body, res) {
const catImages = JSON.parse(body).map((item) => item.url);
https.get("https://animechan.xyz/api/random", (animeQuoteStream) => {
process_stream(animeQuoteStream, (secondApiResponse) => {
printResult(secondApiResponse, catImages, res);
});
});
}
function printResult(secondApiResponse, catImages, res) {
let animeQuote = null;
const responseText = secondApiResponse.trim();
if (responseText.includes("Too Many Requests")) {
const cachedQuotesData = fs.readFileSync(cachedQuoteFilePath, "utf8");
const cachedQuotes = JSON.parse(cachedQuotesData);
if (cachedQuotes.length > 0) {
const randomIndex = Math.floor(Math.random() * cachedQuotes.length);
animeQuote = cachedQuotes[randomIndex].quote;
}
} else {
const responseData = JSON.parse(responseText);
animeQuote = responseData.quote;
const cachedQuotesData = fs.readFileSync(cachedQuoteFilePath, "utf8");
const cachedQuotes = JSON.parse(cachedQuotesData);
cachedQuotes.push({ quote: animeQuote });
fs.writeFileSync(cachedQuoteFilePath, JSON.stringify(cachedQuotes, null, 2));
}
const htmlContent = generateHtml({ animeQuote, catImages });
res.writeHead(200, { "Content-Type": "text/html" });
res.end(htmlContent);
}
function process_stream(stream, callback) {
let body = "";
stream.on("data", (chunk) => (body += chunk));
stream.on("end", () => callback(body));
}
function generateHtml(data) {
return `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>API Data</title>
<style>
body{
background-color: aquamarine;
}
</style>
</head>
<body>
<h1>Anime Quote:</h1>
<h3>${data.animeQuote}</h3>
<h1>Cat Images:</h1>
<ul>
${data.catImages.map((image) => `<li><img src="${image}" alt="Cat"></li>`).join("")}
</ul>
</body>
</html>
`;
}