site

Website's source files.
Log | Files | Refs | Submodules | LICENSE

commit fc5b3a9080c716bb3e79fdaed79ed1295682bca6
parent 04ad77edc89438cbc9cd2098cb4dc4695e73e862
Author: Ryan Jeffrey <ryan@ryanmj.xyz>
Date:   Sun,  6 Feb 2022 21:25:30 -0800

Deleted old files, 0-padding ls output

Diffstat:
DMakefile | 18------------------
Dserver.ts | 271-------------------------------------------------------------------------------
Msrc/main/rmjxyz/app.cljs | 24+++++++++++++-----------
Dtsconfig.json | 15---------------
4 files changed, 13 insertions(+), 315 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,18 +0,0 @@ -# Makefile for Ryan's Blog - -.PHONY: all publish publish_no_init - -all: publish - -publish: - @echo "Publishing normal configuration" - tsc - cd external/site-bkgs && $(MAKE) - -run: publish - @exec node bin/server.js - -clean: - @echo "Cleaning up main site" - rm -rf bin/ - cd external/site-bkgs && $(MAKE) clean diff --git a/server.ts b/server.ts @@ -1,271 +0,0 @@ -// Cropyright (C) Ryan Jeffrey 2022 -// A simple express server that uses handlebars. -import express from 'express'; -import path from 'path'; -import exphbs, { engine } from 'express-handlebars'; -import fs from 'fs'; - -const app = express(); -const port = process.env.PORT || 3000; -let theBkgScript = ''; -let allBkgScripts: string[] = []; - -function getBkgScripts(scriptDir: string) : string[] { - let result: string[] = []; - let files = fs.readdirSync(scriptDir); - files.forEach(file => { - if(path.extname(file) == '.js' && file != 'backs.js') { - result.push(file); - } - }); - return result; -} - -allBkgScripts = getBkgScripts('./external/site-bkgs/bin/'); -theBkgScript = allBkgScripts[Math.floor(Math.random() * allBkgScripts.length)]; - -// Get a new background script once per day. -setInterval(() => { - theBkgScript = allBkgScripts[Math.floor(Math.random() * allBkgScripts.length)]; -}, (1000 * 60 * 60 * 24)); - -function getMonthByNumber(i: number) : string { - const months = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', - 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]; - return (i in months) ? months[i] : ""; -} - -function permissionToString(i: number) : string { - // Unix file permission array. The mode is the index in the array. - const permStrings = ['---', '--x', '-w-', '-wx', 'r--', 'r-x', 'rw-', 'rwx']; - return (i in permStrings) ? permStrings[i] : ""; -} - -class LSStat { - perms: string; - numLinks: number; - fileSize: number; - mtime: string; - basename: string; - - constructor(thePath: string) { - let stats = fs.statSync(thePath); - - // ls file permissions. Convert into an easier format to use. - if(!stats) { - console.error("Could not stat", thePath); - return; - } - // Convert mode to string. - let unixFilePermissions = (stats.mode & parseInt('777', 8)).toString(8); - let permsResult = permissionToString(parseInt(unixFilePermissions[0])); - permsResult += permissionToString(parseInt(unixFilePermissions[1])); - permsResult += permissionToString(parseInt(unixFilePermissions[2])); - - let prefixChar = '-'; - if(stats.isDirectory()) { - prefixChar = 'd'; - } - - this.perms = `${prefixChar}${permsResult}`; - this.numLinks = stats.nlink; - this.fileSize = stats.size; - this.mtime = LSStat.lsTime(stats.mtimeMs); - this.basename = thePath; - } - - // Get the mtime in the same format that LS would. - static lsTime(timeMS: number) : string { - let fileDate = new Date(timeMS); - let addString = ""; - // If the file was updated this year then set the last column to the - // hour and minute. Else, the last column should be the year. - if((new Date()).getFullYear() != fileDate.getFullYear()) - addString = `${fileDate.getHours()}:${fileDate.getMinutes()}`; - else - addString = ` ${fileDate.getFullYear()}`; - return `${getMonthByNumber(fileDate.getMonth())} ${fileDate.getDate()} ${addString}`; - } - - static lsList(theDir: string, ext: string, files: string[]) : LSStat[] { - let fileStats: LSStat[] = []; - files.forEach((element: string) => { - fileStats.push(new LSStat(path.join(theDir, element + ext))); - }); - return fileStats; - } - - static lsDir(thePath: string) : LSStat[] { - let fileStats: LSStat[] = []; - // TODO error checking. - let files = fs.readdirSync(thePath); - - files.forEach((file) => { - fileStats.push(new LSStat(file)); - }); - - return fileStats; - } - - static fileExistsIn(thePath: string, statList: LSStat[]) : boolean { - for(let i = 0; i < statList.length; i++) { - if(statList[i].basename == thePath) - return true; - } - return false; - } -} - -// Dummy class just for inheritance. -class Command { - args: string; - constructor(args: string) { - this.args = args; - } -} - -class LS extends Command { - lsList: LSStat[]; - - constructor(dir: string, ext:string, names: string[]) { - super(dir); - this.lsList = LSStat.lsList(dir, ext, names); - } -} - -class Cat extends Command { - markup: string; - - constructor(path: string) { - super(path); - this.markup = fs.readFileSync(path, 'utf8'); - } -} - -class TerminalWindow { - commands: Command[]; - - constructor(...commands: Command[]) { - this.commands = commands; - } -} - -// App config - -app.engine('handlebars', engine({ defaultLayout: 'main' })); -app.set('view engine', 'handlebars'); -app.set('views', "./views"); - -app.use(express.static(path.join(process.cwd(), 'public'))); -app.use(express.static(path.join(process.cwd(), 'external'))); -app.use(express.json()); - -// TODO maybe a system that exports org to handlebars. -const postItems = LSStat.lsDir('posts'); -// Get the requested post -app.get('/posts/:post', async (req, res, next) => { - let post = req.params.post.toLowerCase(); - if(LSStat.fileExistsIn(post, postItems)) { - await fs.readFile(post, 'utf8', (err, data) => { - if(err) { - console.log("Error when looking for post", post); - // TODO internal error. - res.status(404).render('404'); - } - else { - res.status(200).render('writing', { text : data }); - } - }); - } - else { - // Page not found. - res.status(404).render('404'); - } -}); -// Posts index file. -app.get('/posts', (req, res, next) => { - res.status(200).render('indexWriting'); -}); -// index.html should be before 404 and after everything else -// Generate files object. -const files = LSStat.lsDir('public/files'); -// Server entry for files. -app.get('/files', (req, res, next) => { - res.status(200).render('files', { - entries: files - }); -}); - -// LS everything. -const frontPageItems = LSStat.lsList('.', '.html', ['main', 'software', 'sneed']); - -app.get('/bkgs', (req, res, next) => { - res.status(200).render('index', { - windows: [new TerminalWindow(new Cat('public/bkgs/index.html'))], - bkgScript: `/site-bkgs/bin/${theBkgScript}`, - }); -}); - -app.get('/bkgs/:item', async (req, res, next) => { - let scriptPath = path.join(process.cwd(), - `external/site-bkgs/bin/${req.params.item}.js`); - await fs.exists(scriptPath, (exists) => { - if(exists) { - res.set('Content-Type', 'text/html'); - res.status(200).send(Buffer.from( - `<?xml version="1.0" encoding="utf-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" -"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> -<body> -<script defer type="module" src="/site-bkgs/bin/${req.params.item}.js"></script> -</body> -</html> -`)); - } - else { - res.status(404).render('404'); - } - }); -}); - -app.get('/:item', async (req, res, next) => { - let item = req.params.item.toLowerCase(); - if(LSStat.fileExistsIn(item, frontPageItems)) { - await fs.readFile(item, 'utf8', (err, buf) => { - if(err) { - console.log("Error when looking for item", item); - // TODO internal error. - res.status(404).render('404'); - } - else { - res.status(200).render('post', { text : fs.readFileSync(item) }); - } - }); - } - else { - // Page not found. - res.status(404).render('404'); - } -}); - -app.get('/', (req, res, next) => { - // TODO cache. - res.status(200).render('index', { - windows: [new TerminalWindow(new Cat('public/figlet.html'), - new LS('.', '.html', ['main', 'software', 'sneed']), - new Cat('public/front.html'))], - bkgScript: `/site-bkgs/bin/${theBkgScript}`, - }); -}); - -// 404 is last. -app.get('*', (req, res) => { - res.status(404).render('404'); -}); - -// Server initialize. -app.listen(port, () => { - console.log('== Server is listening on port', port, - 'in current directory', process.cwd()); -}); diff --git a/src/main/rmjxyz/app.cljs b/src/main/rmjxyz/app.cljs @@ -2,6 +2,8 @@ (:require [cljs.nodejs :as nodejs] ["express" :as express] ["express-handlebars" :refer [engine]] + [goog.string :as gstring] + [goog.string.format] [cljs.core.async :refer-macros [go]] [cljs.pprint :refer [pprint]] [cljs.core.async.interop :refer-macros [<p!]])) @@ -33,11 +35,11 @@ "Convert time stamp in milliseconds to LS time format." [timeMS] (let [file-date (js/Date. timeMS)] - (str (mon-by-index (.getMonth file-date)) " " (.getDate file-date) " " + (str (mon-by-index (.getMonth file-date)) " " (gstring/format "%02d" (.getDate file-date)) " " ;; If the file was updated this year then set the last column to the ;; hour and minute. Else, the last column should be the year. - (if (= (compare (.getFullYear file-date) (.getFullYear (js/Date.))) 0) - (str (.getHours file-date) ":" (.getMinutes file-date)) + (if (= (.getFullYear file-date) (.getFullYear (js/Date.))) + (str (gstring/format "%02d" (.getHours file-date)) ":" (gstring/format "%02d" (.getMinutes file-date))) (str (.getFullYear file-date)))))) (defn create-lstat @@ -46,25 +48,25 @@ (let [stats (.statSync fs file-path) unixFilePerms (when stats (.toString (bit-and (.-mode stats) (js/parseInt "777" 8)) 8))] (if stats - { "perms" (str (if (.isDirectory stats) "d" "-") + { :perms (str (if (.isDirectory stats) "d" "-") (permissions-to-string (js/parseInt (first unixFilePerms))) (permissions-to-string (js/parseInt (second unixFilePerms))) (permissions-to-string (js/parseInt (nth unixFilePerms 2)))) - "numLinks" (.-nlink stats) - "fileSize" (.-size stats) - "mtime" (ls-time (.-mtimeMs stats)) - "basename" file-path } + :numLinks (.-nlink stats) + :fileSize (.-size stats) + :mtime (ls-time (.-mtimeMs stats)) + :basename (.basename path file-path) } ;; TODO actually deal with error. (js/console.error "Could not stat" file-path)))) (defn ls-list - "Create a list of ls-stats from a list of file paths." + "Create a list of ls-stats from a list of file paths. Looks into public." ([paths] (for [file paths] (create-lstat file))) ([basedir ext paths] (for [file paths] - (create-lstat (.join path basedir (str file ext)))))) + (create-lstat (.join path "./public" basedir (str file ext)))))) (defn ls-dir "Create a list of ls-stats from a directory." @@ -148,7 +150,7 @@ (reset! app (init-server)) (reset! post-items (ls-dir "posts")) (reset! index-items (create-windows [[(create-command "public/figlet.html") - (create-command "." ".html" ["main" "software" "sneed"]) + (create-command "." "" ["main.html" "software.html" "sneed.html" "posts"]) (create-command "public/front.html")]])) (reset! all-bkg-scripts (let [files (.readdirSync fs "./external/site-bkgs/bin/")] (for [file files diff --git a/tsconfig.json b/tsconfig.json @@ -1,15 +0,0 @@ -{ - "compilerOptions": { - "esModuleInterop": true, - "module": "commonjs", - "noImplicitAny": true, - "removeComments": true, - "preserveConstEnums": true, - "sourceMap": true, - "target": "es2021", - "outDir": "bin" - }, - "files": [ - "server.ts" - ] -}