Actually remember to publish changes

Updates, caching mechanism, new article, changes to stack and problem-solving, GUIHacker betterness, UUIDs on RSS
This commit is contained in:
osmarks 2023-02-14 22:49:48 +00:00
parent 568248177b
commit 0b19f8c578
10 changed files with 156 additions and 45 deletions

BIN
assets/images/rote.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

@ -242,6 +242,9 @@ function GuiHacker(){
this.consoleOutput();
}
var progressBar = document.querySelector(".progress")
var barProgress = 1
GuiHacker.prototype.render = function(){
var ctx = settings.ctx,
canvas = settings.canvas,
@ -291,6 +294,15 @@ GuiHacker.prototype.render = function(){
ctxBars.fillRect(i+5,canvasBars.height,15,-barVal.val);
}
barProgress += 0.0001
if (barProgress < 1) {
progressBar.style.display = "block"
progressBar.style.backgroundImage = `linear-gradient(to right, green, green ${barProgress * 100}%, black ${barProgress * 100}%, black 100%)`
progressBar.innerHTML = `${Math.floor(barProgress * 100)}%`
} else {
progressBar.style.display = "none"
}
var self = this;
requestAnimationFrame(function(){self.render();});
};
@ -423,6 +435,10 @@ window.addEventListener("keydown", ev => {
accessDenied.style.display = accessDenied.style.display === "none" ? "block" : "none"
ev.preventDefault()
}
if (ev.key === "p" && ev.altKey) {
console.log("activating ominous progress bar")
barProgress = 0
}
else if (Math.random() > 0.8) {
guiHacker.consoleOutput(true)
}

View File

@ -3,6 +3,7 @@ title: "'Problem Solving' Tasks and Computer Science"
description: Is solving Sudoku and similar puzzles by hand really useful in building computer science ability? We don't think so.
slug: csproblem
created: 20/05/2020
uodated: 28/01/2023
---
*Co-written with Aidan, developer of [Emu War](/emu-war). He did most of it.*
@ -26,4 +27,8 @@ Instead of being able to create a formal program to solve Sudoku, the solver has
These puzzles are demonstrably a different class of problem to designing algorithms to solve them; if they were similar, then machines that can solve one set should mostly be able to solve the other.
However, although modern computers are extremely fast, and able to solve many common 'computational thinking' tasks orders of magnitude faster than humans, humans are still in control, for this simple reason: *computers cannot program other computers*.
Since computers can do 'computational skills' tasks easily, but cannot (yet) solve the problems of computer science itself, we can conclude that these are entirely different categories of problem.
In other words, learning to do 'computational skills' problems does not help you become a computer scientist, it helps you become a computer - and one easily outdone by a real computer at these tasks.
In other words, learning to do 'computational skills' problems does not help you become a computer scientist, it helps you become a computer - and one easily outdone by a real computer at these tasks.
Update (28/01/2023 CE):
It only took a year after this was written for [OpenAI Codex](https://openai.com/blog/openai-codex/) to become reasonably competent at programming. Oops. And I didn't actually think to update this until now, when I happened to be reviewing it. Regardless, I think the relevant argument still holds up, inasmuch as even today's language models still aren't that great at "thinky" programming tasks, and mostly serve to reveal how much stupid glue code we have to write.

View File

@ -0,0 +1,27 @@
---
title: Against being against rote memorization
description: A common criticism of school is that it focuses overmuch on rote memorization. While I don't endorse school, I think this argument is wrong.
slug: rote
created: 28/01/2023
---
It is popular to be against rote-memorizing things (i.e. spending time to deliberately commit things exactly to memory) and in favour of something like learning "problem-solving"; I think this is a false dichotomy and memorization can help with more advanced skills.
## Remembering things is faster than using reference materials
A common argument made against reliance on external tools for cognition like calculators is that you "won't always have them".
Obviously in today's world of ubiquitous portable computers this is mostly wrong in noncontrived situations, but a better reason is that they're not tightly integrated enough; access is *very slow*.
Even with the best search tools it's generally faster to recall things (assuming they're not extremely long and you remember them well) than to retrieve and consult relevant notes.
This can be a significant bottleneck: imagine how much slower mental arithmetic would be if you had to look up the results of single-digit operations each time.
Even if the time cost isn't that large, it can still be problematic via removing you from "flow".
## Notes tools aren't good at making connections
Despite recent work in this area (graph-structured note-taking applications/Zettelkasten and LLM-based semantic search), modern note tools will generally only surface related ideas if they use identical or similar wording, while humans' "general intelligence" can relate structurally similar or conceptually similar things as well.
I expect this to improve in the future, but for now, if you want to be able to do that you have to retain at least a rough overview in your brain (knowing the exact wording of whatever you've read isn't that valuable).
Being able to effectively "problem-solve" requires making this kind of connection a lot in order to relate new patterns to ones you've previously seen and can understand.
## Efficient spaced repetition makes the time cost small
A naïve flashcard system which shows you all the things you need to remember every day would be a terrible timesink and probably not worth using.
Fortunately, this is not at all necessary: research has elicited a decent model of how we remember and forget things, and it turns out that the time you retain a memory for increases each time you see it again.
This insight has been incorporated into "spaced repetition systems" like [Anki](https://apps.ankiweb.net/), which only show you things frequently enough to keep them memorized, meaning that you can learn a fact with only a few minutes of lifetime time investment.

View File

@ -2,10 +2,11 @@
title: Site tech stack
description: Learn about how osmarks.net works internally! Spoiler warning if you wanted to reverse-engineer it yourself.
created: 24/02/2022
updated: 20/12/2022
---
As you may know, osmarks.net is a website, served from computers which are believed to exist. But have you ever wondered exactly how it's all set up? If not, you may turn elsewhere and live in ignorance. Otherwise, continue reading.
Many similar personal sites are hosted on free static site services or various cloud platforms, but mine actually runs on a physical server. This was originally done because of my general distrust of SaaS/cloud platforms, to learn about Linux administration, and desire to run some non-web things, but now it's necessary to run the full range of weird components which are now important to the website. The hardware has remained the same since early 2019, before I actually had a public site, apart from the addition of more disk capacity and a spare GPU for occasional machine learning workloads - I am using an old HP ML110 G7 tower server. Despite limited RAM and CPU power compared to contemporary rackmount models, it was cheap, has continued to work amazingly reliably, and is much more power-efficient than those would have been. It mostly only runs at about 5% CPU load and 2GB of RAM in use anyway, so it's not been an issue.
Many similar personal sites are hosted on free static site services or various cloud platforms, but mine actually runs on a physical server. This was originally done because of my general distrust of SaaS/cloud platforms, to learn about Linux administration, and desire to run some non-web things, but now it's necessary to run the full range of weird components which are now important to the website. ~~The hardware has remained the same since early 2019, before I actually had a public site, apart from the addition of more disk capacity and a spare GPU for occasional machine learning workloads - I am using an old HP ML110 G7 tower server. Despite limited RAM and CPU power compared to contemporary rackmount models, it was cheap, has continued to work amazingly reliably, and is much more power-efficient than those would have been. It mostly only runs at about 5% CPU load and 2GB of RAM in use anyway, so it's not been an issue.~~ Due to the increasing compute demands of internal workloads, among other things, it has now been replaced with a custom build using a consumer Ryzen CPU. This has massively increased performance thanks to the CPU's much better IPC, clocks and core count, the 8x increase in RAM, and actually having an SSD.
The main site itself, which you're currently reading, is in fact just a simple static website. Over the years the exact implementation has varied a lot, from the original not-actually-that-static version using Caddy, some weird PHP scripts for Markdown, and a few folders of HTML files, to the later strange combination of Haskell (using Hakyll) and makefiles to the current somewhat horrible Node.js program (which also interacts with someone else's Go program. Fun!). The modern implementation of the compiler does templating, dependency resolution, Markdown and some optimization tasks in about 300 lines of poorly-described JavaScript.

View File

@ -61,9 +61,17 @@ description: <a href="https://github.com/osmarks/guihacker">My fork</a> of GUIHa
padding: 0.5em;
border: 0.05em solid #666;
}
.progress {
font-size: 4em;
min-width: 40rem;
text-align: center;
padding: 2rem;
border: 1px solid #00FF00;
}
</style>
<canvas class='hacker-3d-shiz'></canvas>
<canvas class='bars-and-stuff'></canvas>
<div class="output-console"></div>
<div class="overlay"><div class="accessdenied" style="display: none">ACCESS DENIED</div></div>
<div class="overlay"><div class="accessdenied" style="display: none">ACCESS DENIED</div><div class="progress" style="display: none"></div></div>
<script src="/assets/js/h4xx0r.js"></script>

112
package-lock.json generated
View File

@ -5,6 +5,7 @@
"requires": true,
"packages": {
"": {
"name": "website",
"version": "1.0.0",
"license": "MIT",
"dependencies": {
@ -14,14 +15,15 @@
"gray-matter": "^4.0.2",
"handlebars": "^4.7.6",
"html-minifier": "^4.0.0",
"markdown-it": "^10.0.0",
"markdown-it": "^13.0.1",
"markdown-it-footnote": "^3.0.3",
"mustache": "^4.0.1",
"nanoid": "^2.1.11",
"pug": "^3.0.2",
"ramda": "^0.26.1",
"sass": "^1.26.8",
"terser": "^4.8.0"
"terser": "^4.8.0",
"uuid": "^9.0.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
@ -261,9 +263,15 @@
"integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk="
},
"node_modules/entities": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz",
"integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ=="
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz",
"integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/esprima": {
"version": "4.0.1",
@ -580,9 +588,9 @@
}
},
"node_modules/linkify-it": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
"integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==",
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz",
"integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==",
"dependencies": {
"uc.micro": "^1.0.1"
}
@ -593,13 +601,13 @@
"integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw="
},
"node_modules/markdown-it": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz",
"integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==",
"version": "13.0.1",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz",
"integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==",
"dependencies": {
"argparse": "^1.0.7",
"entities": "~2.0.0",
"linkify-it": "^2.0.0",
"argparse": "^2.0.1",
"entities": "~3.0.1",
"linkify-it": "^4.0.1",
"mdurl": "^1.0.1",
"uc.micro": "^1.0.5"
},
@ -612,15 +620,23 @@
"resolved": "https://registry.npmjs.org/markdown-it-footnote/-/markdown-it-footnote-3.0.3.tgz",
"integrity": "sha512-YZMSuCGVZAjzKMn+xqIco9d1cLGxbELHZ9do/TSYVzraooV8ypsppKNmUJ0fVH5ljkCInQAtFpm8Rb3eXSrt5w=="
},
"node_modules/markdown-it/node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"node_modules/mdurl": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
"integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4="
},
"node_modules/minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
"integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/mustache": {
"version": "4.2.0",
@ -912,9 +928,9 @@
}
},
"node_modules/terser": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
"integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==",
"version": "4.8.1",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz",
"integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==",
"dependencies": {
"commander": "^2.20.0",
"source-map": "~0.6.1",
@ -980,6 +996,14 @@
"resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz",
"integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg="
},
"node_modules/uuid": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
"integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/void-elements": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
@ -1190,9 +1214,9 @@
"integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk="
},
"entities": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz",
"integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ=="
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz",
"integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q=="
},
"esprima": {
"version": "4.0.1",
@ -1418,9 +1442,9 @@
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
},
"linkify-it": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
"integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==",
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz",
"integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==",
"requires": {
"uc.micro": "^1.0.1"
}
@ -1431,15 +1455,22 @@
"integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw="
},
"markdown-it": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz",
"integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==",
"version": "13.0.1",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz",
"integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==",
"requires": {
"argparse": "^1.0.7",
"entities": "~2.0.0",
"linkify-it": "^2.0.0",
"argparse": "^2.0.1",
"entities": "~3.0.1",
"linkify-it": "^4.0.1",
"mdurl": "^1.0.1",
"uc.micro": "^1.0.5"
},
"dependencies": {
"argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
}
}
},
"markdown-it-footnote": {
@ -1453,9 +1484,9 @@
"integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4="
},
"minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
"integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g=="
},
"mustache": {
"version": "4.2.0",
@ -1705,9 +1736,9 @@
}
},
"terser": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
"integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==",
"version": "4.8.1",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz",
"integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==",
"requires": {
"commander": "^2.20.0",
"source-map": "~0.6.1",
@ -1752,6 +1783,11 @@
"resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz",
"integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg="
},
"uuid": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
"integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg=="
},
"void-elements": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",

View File

@ -10,14 +10,15 @@
"gray-matter": "^4.0.2",
"handlebars": "^4.7.6",
"html-minifier": "^4.0.0",
"markdown-it": "^10.0.0",
"markdown-it": "^13.0.1",
"markdown-it-footnote": "^3.0.3",
"mustache": "^4.0.1",
"nanoid": "^2.1.11",
"pug": "^3.0.2",
"ramda": "^0.26.1",
"sass": "^1.26.8",
"terser": "^4.8.0"
"terser": "^4.8.0",
"uuid": "^9.0.0"
},
"license": "MIT"
}

View File

@ -17,6 +17,7 @@ const util = require("util")
const childProcess = require("child_process")
const chalk = require("chalk")
const crypto = require("crypto")
const uuid = require("uuid")
dayjs.extend(customParseFormat)
@ -133,7 +134,8 @@ const applyTemplate = async (template, input, getOutput, options = {}) => {
return page.data
}
const addColors = R.map(x => ({ ...x, bgcol: hashColor(x.title, 0.7, 0.85) }))
const addColors = R.map(x => ({ ...x, bgcol: hashColor(x.title, 1, 0.9) }))
const addGuids = R.map(x => ({ ...x, guid: uuid.v5(`${x.lastUpdate}:${x.slug}`, "9111a1fc-59c3-46f0-9ab4-47c607a958f2") }))
const processExperiments = async () => {
const templates = globalData.templates
@ -168,7 +170,7 @@ const processBlog = async () => {
}, { processMeta: meta => { meta.slug = meta.slug || removeExtension(basename) }, processContent: renderMarkdown })
})
console.log(chalk.yellow(`${Object.keys(blog).length} blog entries`))
globalData.blog = addColors(R.sortBy(x => x.updated ? -x.updated.valueOf() : 0, R.values(blog)))
globalData.blog = addGuids(addColors(R.sortBy(x => x.updated ? -x.updated.valueOf() : 0, R.values(blog))))
}
const processErrorPages = () => {
@ -201,12 +203,26 @@ const loadTemplates = async () => {
globalData.templates = await loadDir(templateDir, async fullPath => pug.compile(await readFile(fullPath), { filename: fullPath }))
}
const runOpenring = async () => {
try {
var cached = JSON.parse(await fsp.readFile("cache.json", {encoding: "utf8"}))
} catch(e) {
console.log(chalk.keyword("orange")("Failed to load cache:"), e)
}
if (cached && (Date.now() - cached.time) < (60 * 60 * 1000)) {
console.log(chalk.keyword("orange")("Loading Openring data from cache"))
return cached.data
}
globalData.openring = "bee"
// wildly unsafe but only runs on input from me anyway
const arg = `./openring -n6 ${globalData.feeds.map(x => '-s "' + x + '"').join(" ")} < openring.html`
console.log(chalk.keyword("orange")("Openring:") + " " + arg)
const out = await util.promisify(childProcess.exec)(arg)
console.log(chalk.keyword("orange")("Openring:") + "\n" + out.stderr.trim())
globalData.openring = minifyHTML(out.stdout)
await fsp.writeFile("cache.json", JSON.stringify({
time: Date.now(),
data: globalData.openring
}))
}
const genRSS = async () => {
const rssFeed = globalData.templates.rss({ ...globalData, items: globalData.blog, lastUpdate: new Date() })

View File

@ -12,5 +12,6 @@ rss(version='2.0')
title= item.title
description= item.description
link= `https://${domain}/${item.slug}`
guid= item.guid
if item.updated
pubDate= item.updated.toDate().toUTCString()