2022-10-06 07:05:46 -05:00
|
|
|
#!/usr/bin/node
|
|
|
|
'use strict';
|
|
|
|
/*
|
2022-10-08 09:19:40 -05:00
|
|
|
2022-09-14 Hyperling
|
|
|
|
Coding my own website rather than using WordPress or anything bloaty.
|
2022-10-06 07:05:46 -05:00
|
|
|
*/
|
|
|
|
|
2022-10-08 09:19:40 -05:00
|
|
|
//// Libraries ////
|
|
|
|
|
2022-10-06 07:05:46 -05:00
|
|
|
let express = require('express');
|
|
|
|
let app = express();
|
|
|
|
|
|
|
|
const execSync = require('child_process').execSync;
|
|
|
|
|
2022-10-08 09:19:40 -05:00
|
|
|
const fs = require('fs');
|
|
|
|
|
|
|
|
//// Global Variables ////
|
2022-10-06 07:05:46 -05:00
|
|
|
|
2022-10-08 09:19:40 -05:00
|
|
|
const DEBUG = false;
|
2022-10-06 07:05:46 -05:00
|
|
|
|
2022-10-08 09:19:40 -05:00
|
|
|
const app_name = "hyperling.com";
|
|
|
|
|
|
|
|
let pages = [];
|
|
|
|
const pages_dir = "./pages/";
|
|
|
|
const file_types = ["php", "sh"];
|
2022-10-06 07:05:46 -05:00
|
|
|
|
|
|
|
let ports = [];
|
2024-01-24 11:02:23 +00:00
|
|
|
// Check parameters for numeric port numbers.
|
|
|
|
process.argv.forEach(function (val, index, array) {
|
|
|
|
console.log("Parameter", index + ':', val, !isNaN(val));
|
|
|
|
if (!isNaN(val)) {
|
|
|
|
console.log("Adding Port", val)
|
|
|
|
ports.push(val);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
// Default port if none were passed.
|
|
|
|
if (ports.length === 0) {
|
|
|
|
ports.push(8080);
|
|
|
|
}
|
2022-10-06 07:05:46 -05:00
|
|
|
|
2024-02-08 09:26:54 -07:00
|
|
|
const stringsToRemove = [
|
|
|
|
RegExp("#!/usr/bin/php\n", "g")
|
|
|
|
]
|
|
|
|
|
2022-10-08 09:19:40 -05:00
|
|
|
//// Functions ////
|
|
|
|
|
2022-10-19 04:56:51 -05:00
|
|
|
/* Code exists inside a main function so that we may use async/await.
|
|
|
|
*/
|
2022-10-06 07:05:46 -05:00
|
|
|
async function main() {
|
2022-10-08 09:19:40 -05:00
|
|
|
console.log("...Starting Main...");
|
2022-10-06 07:05:46 -05:00
|
|
|
|
2022-10-19 04:56:51 -05:00
|
|
|
// Getting dates in Node.js is awful, just use Linux.
|
|
|
|
const start_datetime = "" + await execSync('date "+%Y-%m-%dT%H:%M:%S%:z"');
|
|
|
|
const start_datetime_trimmed = start_datetime.trim();
|
|
|
|
|
2022-10-08 09:19:40 -05:00
|
|
|
console.log("Set app to return HTML documents.");
|
2022-10-06 22:15:36 -05:00
|
|
|
app.use(function (req, res, next) {
|
|
|
|
res.contentType('text/html');
|
|
|
|
next();
|
|
|
|
});
|
2022-10-06 07:05:46 -05:00
|
|
|
|
2022-10-08 09:19:40 -05:00
|
|
|
/* Loop through all file in the pages subdirectory and add the allowed
|
|
|
|
// file types into the pages array for automatic router creation.
|
|
|
|
*/
|
|
|
|
console.log("...Starting Main...");
|
|
|
|
let ls = await fs.promises.readdir(pages_dir);
|
|
|
|
if (DEBUG) console.log("DEBUG: Results of ls, ", ls);
|
|
|
|
for (let file of ls) {
|
|
|
|
let file_test = file.split(".");
|
|
|
|
let file_name = file_test[0];
|
|
|
|
let file_type = file_test[file_test.length - 1];
|
|
|
|
if (file_types.includes(file_type)) {
|
|
|
|
if (DEBUG) console.log("DEBUG: Hooray!", file, "is being added.");
|
|
|
|
pages[file_name] = pages_dir + file;
|
|
|
|
console.log(" * Added page", file);
|
|
|
|
} else {
|
|
|
|
if (DEBUG) console.log("DEBUG: ", file, "is not an approved type, skipping.");
|
|
|
|
}
|
2022-10-06 22:15:36 -05:00
|
|
|
}
|
2022-10-08 09:19:40 -05:00
|
|
|
console.log(" * Pages loaded: ", pages);
|
|
|
|
//return; // Stop execution FORTESTING
|
|
|
|
|
2022-10-19 04:56:51 -05:00
|
|
|
/* Create both an XML and HTML sitemap based on these entries. XML is used for
|
|
|
|
// bots like SEO scrapers. HTML will be for human users looking for a list of
|
|
|
|
// all pages. Some are not in the menu. Generated an example XML sitemap at
|
|
|
|
// www.xml-sitemaps.com then stripped it apart and made it dynamic.
|
|
|
|
*/
|
|
|
|
let sitemap_xml = `<?xml version="1.0" encoding="UTF-8"?>
|
|
|
|
<urlset
|
|
|
|
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
|
|
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
|
|
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
|
|
|
|
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"
|
|
|
|
>
|
|
|
|
<url>
|
|
|
|
<loc>https://hyperling.com/</loc>
|
|
|
|
<lastmod>`+start_datetime_trimmed+`</lastmod>
|
|
|
|
<priority>1.00</priority>
|
|
|
|
</url>
|
|
|
|
<url>
|
|
|
|
<loc>https://hyperling.com/sitemap/</loc>
|
|
|
|
<lastmod>`+start_datetime_trimmed+`</lastmod>
|
|
|
|
<priority>0.80</priority>
|
|
|
|
</url>
|
|
|
|
`;
|
|
|
|
let sitemap_html = `
|
|
|
|
<html><body>
|
|
|
|
<strong>Special Pages</strong>
|
|
|
|
<ul>
|
|
|
|
<li>
|
|
|
|
<b>Main Site</b>
|
|
|
|
(<a href="/">Local</a>)
|
|
|
|
(<a href="https://`+app_name+`/">Hardlink</a>)
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<b>XML Site Map</b>
|
|
|
|
(<a href="/sitemap.xml">Local</a>)
|
|
|
|
(<a href="https://`+app_name+`/sitemap.xml">Hardlink</a>)
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
<b>HTML Site Map</b>
|
|
|
|
(<a href="/sitemap/">Local</a>)
|
|
|
|
(<a href="https://`+app_name+`/sitemap/">Hardlink</a>)
|
|
|
|
<i>[You are here!]</i>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
<strong>Web Pages (Alphabetical)</strong>
|
|
|
|
<ul>
|
|
|
|
`;
|
|
|
|
|
2022-10-08 09:19:40 -05:00
|
|
|
console.log("...Adding Routes...");
|
|
|
|
let router = express.Router();
|
|
|
|
|
2024-01-24 11:02:23 +00:00
|
|
|
/* AUTOMATIC METHOD BASED ON OBJECT/ARRAY OF WEB SCRIPTS
|
2022-10-08 09:19:40 -05:00
|
|
|
// Creates routes with the URL of the key and location of the value.
|
|
|
|
*/
|
|
|
|
for (let key in pages) {
|
|
|
|
console.log(" * Creating router for", key);
|
|
|
|
router.get("/" + key, function (req,res) {
|
2024-02-08 09:26:54 -07:00
|
|
|
console.log(key, "fulfilling request to", req.socket.remoteAddress, "asking for", req.url);
|
|
|
|
let html = "" + execSync(pages[key]);
|
|
|
|
stringsToRemove.forEach(string => {
|
|
|
|
html = html.replace(string, "");
|
|
|
|
});
|
|
|
|
res.send(html);
|
2022-10-06 22:15:36 -05:00
|
|
|
});
|
2022-10-19 04:56:51 -05:00
|
|
|
|
|
|
|
/* Append the page to the sitemap variables.
|
|
|
|
*/
|
|
|
|
console.log(" * * Adding to sitemap.xml");
|
|
|
|
sitemap_xml = sitemap_xml + `
|
|
|
|
<url>
|
|
|
|
<loc>https://hyperling.com/`+key+`/</loc>
|
|
|
|
<lastmod>`+start_datetime_trimmed+`</lastmod>
|
|
|
|
<priority>0.80</priority>
|
|
|
|
</url>
|
|
|
|
`;
|
|
|
|
console.log(" * * Adding to sitemap.html");
|
|
|
|
sitemap_html = sitemap_html + `
|
|
|
|
<li>
|
|
|
|
<b>`+key+`</b>
|
|
|
|
(<a href="/`+key+`/">Local</a>)
|
|
|
|
(<a href="https://`+app_name+`/`+key+`/">Hardlink</a>)
|
|
|
|
</li>
|
|
|
|
`;
|
2022-10-06 22:15:36 -05:00
|
|
|
}
|
2022-10-08 09:19:40 -05:00
|
|
|
|
2022-10-19 04:56:51 -05:00
|
|
|
/* Close the sitemap variables
|
|
|
|
*/
|
|
|
|
sitemap_xml = sitemap_xml + `
|
|
|
|
</urlset>
|
|
|
|
`;
|
|
|
|
sitemap_html = sitemap_html + `
|
|
|
|
</ul></body></html>
|
|
|
|
`;
|
|
|
|
|
|
|
|
// Provide sitemap.xml file for "SEO".
|
|
|
|
console.log(" * Creating router for sitemap.xml");
|
|
|
|
router.get('/sitemap.xml', function (req, res) {
|
|
|
|
console.log("sitemap.xml being provided to", req.socket.remoteAddress)
|
|
|
|
res.contentType('text/xml');
|
|
|
|
res.send(sitemap_xml);
|
|
|
|
});
|
|
|
|
|
|
|
|
// Provide human-usable sitemap links.
|
|
|
|
console.log(" * Creating router for sitemap*");
|
|
|
|
router.get('/sitemap*', function (req, res) {
|
|
|
|
console.log("sitemap.html being provided to", req.socket.remoteAddress)
|
|
|
|
res.send(sitemap_html);
|
2022-10-08 09:19:40 -05:00
|
|
|
});
|
|
|
|
|
2024-01-24 11:02:23 +00:00
|
|
|
// Return a resource from the files folder.
|
|
|
|
console.log(" * Creating router for files");
|
|
|
|
router.get('/files*', function (req, res) {
|
|
|
|
console.log("file response to", req.socket.remoteAddress, "asking for", req.url)
|
|
|
|
|
|
|
|
// Build variables.
|
|
|
|
const file = "." + req.path;
|
|
|
|
const extensions = req.path.split(".");
|
|
|
|
const extension = extensions[extensions.length-1];
|
|
|
|
|
|
|
|
// Check extension and guess a MIME type.
|
|
|
|
let mime;
|
|
|
|
switch (extension) {
|
|
|
|
case "apk":
|
|
|
|
mime = "application/vnd.android.package-archive";
|
|
|
|
break;
|
|
|
|
case "jpg" || "jpeg":
|
|
|
|
mime = "image/jpeg";
|
|
|
|
break;
|
|
|
|
case "png":
|
|
|
|
mime = "image/png";
|
|
|
|
break;
|
|
|
|
case "html":
|
|
|
|
mime = "text/html";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
mime = "text/*";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return the file
|
|
|
|
res.contentType(mime);
|
|
|
|
let f = fs.createReadStream(file)
|
|
|
|
.on("error", function(e) {
|
|
|
|
res.contentType("text/plain");
|
|
|
|
res.send(404, "File Not Found");
|
|
|
|
})
|
|
|
|
.pipe(res)
|
|
|
|
;
|
|
|
|
});
|
|
|
|
|
2022-10-08 09:19:40 -05:00
|
|
|
// Originally a test, now a catch-all redirection to Home!
|
2022-10-19 04:56:51 -05:00
|
|
|
console.log(" * Creating router for redirection");
|
2022-10-06 22:15:36 -05:00
|
|
|
router.get('/*', function (req, res) {
|
2022-10-08 09:19:40 -05:00
|
|
|
// WARNING: These are huge so only look when you need to.
|
2022-10-06 22:15:36 -05:00
|
|
|
//console.log(req);
|
|
|
|
//console.log(res);
|
2022-10-08 09:19:40 -05:00
|
|
|
console.log("*wildcard* replying to", req.socket.remoteAddress, "asking for", req.url)
|
2024-02-08 09:32:54 -07:00
|
|
|
let html = "" + execSync("./pages/home.php");
|
2024-02-08 09:26:54 -07:00
|
|
|
stringsToRemove.forEach(string => {
|
|
|
|
html = html.replace(string, "");
|
|
|
|
});
|
2022-10-06 22:15:36 -05:00
|
|
|
res.send(html);
|
|
|
|
});
|
2022-10-06 07:05:46 -05:00
|
|
|
|
2022-10-06 22:15:36 -05:00
|
|
|
app.use('', router);
|
2022-10-06 07:05:46 -05:00
|
|
|
|
2022-10-08 09:19:40 -05:00
|
|
|
console.log("...Adding Ports...");
|
2022-10-06 22:15:36 -05:00
|
|
|
ports.forEach(port => {
|
|
|
|
app.listen(port);
|
|
|
|
console.log(" * Now listening on port " + port + ".");
|
|
|
|
});
|
2022-10-06 07:05:46 -05:00
|
|
|
console.log("Done! Now we wait...");
|
|
|
|
}
|
|
|
|
|
2022-10-08 09:19:40 -05:00
|
|
|
//// Program Execution ////
|
|
|
|
|
2022-10-06 07:05:46 -05:00
|
|
|
main();
|