Add Static Resource Hosting (#8)

* Add ability to host files from web API rather than using the static site files.hyperling.com.

* Add details.

* Prevent further files from being committed in the static resource folder.

* Beginnings of a photo share from the website to replace PhotoPrism.

* Fix log message for files route.

* Allow customization of ports via shell script.

* Update README goals and fix URLs.

* FInalize the PHOTOS page, complete with video controls!

* Moe enhancements, such as displaying README's and adding [VIDEO] tag.

* Clean file a little.

* Remove TODO.
This commit is contained in:
Hyperling 2024-01-24 11:02:23 +00:00 committed by GitHub
parent 01277d0c9c
commit 2fa8b555e7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 222 additions and 19 deletions

1
.gitignore vendored
View File

@ -105,3 +105,4 @@ dist
## Above is Github's recommendations for Node.js. Below are my additions. ##
package-lock.json
files/*

View File

@ -14,25 +14,29 @@ All content is formatted so that the page source is readible.
# How To Run
The install script is currently only set up for apt, and the package names only tested on Ubuntu.
The install script is currently only set up for apt, and the package names only
tested on Ubuntu and Debian.
`git clone https://github.com/Hyperling/www www`
```
git clone https://github.com/Hyperling/website www
cd www
./run.sh
```
`cd www`
`./run.sh`
Then in a web browser, navigate to `your_machines_ip_address:8080`.
Then in a web browser, navigate to `localhost:8080`.
## TODO
All goals are currently completed.
- ~~Add support for Let's Encrypt without using `nginx` or `apache`.~~
- Going to continue using a reverse proxy, but may still be nice someday.
## Inspiration
- [https://liquorix.net/]
- [Liquorix Kernel](https://liquorix.net/)
- The linux-zen kernel, a really great one if you're running FOSS OS's!
- [https://cahlen.org/]
- [Cahlen.org](https://cahlen.org/)
- Also has really interesting and important content, it is highly recommended.
- [https://merkinvineyardsosteria.com/]
- [Merkin Vineyards Osteria](https://merkinvineyardsosteria.com/)
- A winery website for MJ Keenan.

9
files/README.md Normal file
View File

@ -0,0 +1,9 @@
# Hyperling.com - Files
Place files into this folder which should be used as static resources.
Examples would be APKs, zip files, images, text files, etc.
For example, if `test.jpg` was placed here, it could be accessed via
`http://localhost:8080/files/test.jpg`. Depending on the file type the MIME type
may be detected automatically, otherwise it will be assumed a text file and
most likely ask to be downloaded by the browser.

57
main.js
View File

@ -25,7 +25,18 @@ const pages_dir = "./pages/";
const file_types = ["php", "sh"];
let ports = [];
ports.push(8080);
// 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);
}
//// Functions ////
@ -116,7 +127,7 @@ async function main() {
console.log("...Adding Routes...");
let router = express.Router();
/* AUTOMATIC METHOD BASED ON OBJECT/ARRAY OF WEB SCRIPTS
/* AUTOMATIC METHOD BASED ON OBJECT/ARRAY OF WEB SCRIPTS
// Creates routes with the URL of the key and location of the value.
*/
for (let key in pages) {
@ -170,6 +181,48 @@ async function main() {
res.send(sitemap_html);
});
// 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;
}
console.log("- Extension", extension, "led to MIME", mime);
// 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)
;
});
// Originally a test, now a catch-all redirection to Home!
console.log(" * Creating router for redirection");
router.get('/*', function (req, res) {

99
pages/photos.sh Executable file
View File

@ -0,0 +1,99 @@
#!/bin/bash
# 2024-01-21 Hyperling
# Transition away from PhotoPrism. Helps to save system resources and downsize.
# Static Variables
header="<html>\n\t<header>\n\t\t<title>ALBUM</title>\n\t</header>\n\t<body>"
footer="\n\t</body>\n</html>"
HELPER_DIR=./pages/helpers
# Move to the main project directory.
cd `dirname $0`/..
# Create the necessary HTML components for a web page.
$HELPER_DIR/body_open.php
# Give the page a description.
echo -e "\n\t\t<h1 class='col-12 title'>Photo Albums</h1>"
echo -en "\t\t<p class='col-12 text'>You may click on an album name to view "
echo -en "all of its files, or click on a specific image to bring up the full "
echo -en "resolution. On the album pages you may also click an image or video "
echo -e "name to pull up the full resolution for download.</p>"
# Display the album names descending.
ls files/photos/ | sort -r | while read album; do
# Clean album name.
album_name=${album}
album_name=${album_name//_/ }
album_name=${album_name//-/ }
echo -en "\t\t<h2 class='col-12 title'>"
echo -en "<a href='/files/photos/$album/index.html' "
echo -e "target='_blank' rel='noopener noreferrer'>$album_name</a></h2>"
echo -e "\t\t<div class='col-12 text'>"
# Create index for each photo album based on its contents.
page=""
subpage="files/photos/$album/index.html"
$HELPER_DIR/body_open.php > $subpage
echo -e "\n\t\t<h1 class='col-12 title'>$album_name</h1>" >> $subpage
ls files/photos/$album/* | sort | while read photo; do
# Do not include the index page.
if [[ $photo == *"index.html" ]]; then
continue
fi
# Clean filename to be a little more presentable.
# Going with CAPSLOCK. ;)
typeset -u filename
filename="`basename $photo`"
# Remove extension.
filename="${filename%%.*}"
# Remove special characters for spaces.
filename="${filename//_/ }"
filename="${filename//-/ }"
if [[ $photo == *"/README.md" || $photo == *"/README.txt" ]]; then
# If there is a README, show it on the PHOTOS page without a link.
echo -e "\t\t\t<p>`cat $photo`</p>"
else
# Otherwise put in the PHOTOS page list.
echo -en "\t\t\t<li class='indent'><a href=/$photo target='_blank' "
echo -en "rel='noopener noreferrer'>$filename"
if [[ $photo == *".mp4" ]]; then
echo -en " [VIDEO]"
fi
echo -e "</a></li>"
fi
# Put in the subpage HTML.
echo -e "\t\t<div class='col-6 center'>" >> $subpage
echo -en "\t\t\t<a href=/$photo target='_blank' " >> $subpage
echo -e "rel='noopener noreferrer'>" >> $subpage
if [[ $photo == *".mp4" ]]; then
echo -e "\t\t\t\t<video width='320px' controls>" >> $subpage
echo -e "\t\t\t\t\t<source src='/$photo' type=video/mp4>" >> $subpage
echo -e "\t\t\t\t\tYour browser does not support videos." >> $subpage
echo -e "\t\t\t\t</video>" >> $subpage
elif [[ $photo == *".md" || $photo == *".txt" ]]; then
echo -e "\t\t\t\t<p>`cat $photo`</p>" >> $subpage
else
echo -e "\t\t\t\t<img src='/$photo'/>" >> $subpage
fi
# Add a descriptive link.
echo -en "\t\t\t\t<p>$filename" >> $subpage
if [[ $photo == *".mp4" ]]; then
echo -en " [VIDEO]" >> $subpage
fi
echo -e "</p>\n\t\t\t</a>\n\t\t</div>" >> $subpage
done
# End album on PHOTOS page.
echo -e "\t\t</div>"
# Close out the ALBUM's page.
$HELPER_DIR/body_close.php >> $subpage
done
# Finish the web page.
$HELPER_DIR/body_close.php

51
run.sh
View File

@ -2,12 +2,46 @@
# 2022-09-14 Hyperling
# Ensure dependencies are met and start the webserver.
# Ensure we are executing from this file's directory.
cd `dirname $0`
## Setup ##
### Can docker-compose do this rather than running a sh file on the host OS?
# Look at Dockerfile-ADD for doing git clones into a docker environment.
# Out of scope for this project, this project is just the site, leave for now.
DIR=`dirname $0`
PROG=`basename $0`
## Functions ##
function usage {
cat <<- EOF
$PROG calls the main Node.js program after ensuring the project can run.
(PORTS)
-p : Pass the port numbers that the API/website should listen at.
Example: $PROG -p 80 -p 443 -p 8080
(HELP)
-h : Show this usage output and exit successfully.
EOF
exit $1
}
## Parameters ##
while getopts ':p:h' opt; do
case "$opt" in
p) (( OPTARG < 1024 )) && [[ $LOGNAME != "root" ]] && {
echo "WARNING: Port $OPTARG is privileged. Will need to be root."
exit 1
}
ports="$ports $OPTARG" ;;
h) usage 0 ;;
*) echo "ERROR: Option $OPTARG not recognized." >&2
usage 1 ;;
esac
done
## Build Environment ##
# Ensure we are executing from this file's directory.
cd $DIR
# Check if any dependencies need installed.
if [[ ! `which php` || ! `which node`|| ! `which npm` ]]; then
sudo apt install -y php-fpm nodejs npm
fi
@ -25,7 +59,10 @@ done
npm install
./main.js
###
## Main ##
./main.js $ports
## Finish ##
exit $?