From bcaa3487dd6bb218209d2195207847cc2abaf4d6 Mon Sep 17 00:00:00 2001 From: deadvey Date: Sat, 12 Jul 2025 22:28:36 +0100 Subject: [PATCH] commenting --- .gitignore | 1 + README.md | 6 ++++- app.js | 68 +++++++++++++++++++++++++++++++++++++++++++--------- config.js | 9 +++++++ hitcount.txt | 2 +- 5 files changed, 73 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 34225d9..2ae919f 100755 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ node_modules package-lock.json posts.js +comments.js users.js *.swp diff --git a/README.md b/README.md index 4c7b9e5..d5b6cdc 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,13 @@ In action on my website: [deadvey.com](https://deadvey.com)
* rss * timeline, user page, post page and tag specific page * edit/delete posts -* probably insecure as hell * hitcount * Markdown syntax in posts +* Commenting on posts + +# Bugs +* probably scales like shit +* probably insecure as hell # planned features * atom diff --git a/app.js b/app.js index d749531..bab5527 100755 --- a/app.js +++ b/app.js @@ -3,14 +3,17 @@ const showdown = require('showdown') const crypto = require('crypto'); // For encrypting passwords const { fromUnixTime, format, getUnixTime } = require("date-fns") const fs = require('fs'); + const users = require('./users.js'); const posts = require('./posts.js'); +const comments = require('./comments.js'); const config = require('./config.js'); let converter = new showdown.Converter({simpleLineBreaks: true, tables: true, strikethrough: true, tasklists: true, encodeEmails: true}) const app = express(); let footer_div = config.site_wide_footer footer_div = replace_format_indicators(footer_div) + app.use(express.urlencoded({ extended: true })); app.use(express.json()); app.use(express.static(config.root_path)); @@ -61,6 +64,7 @@ function replace_format_indicators(input_string, post_index=0, tag_name="tag") { .replaceAll("%G", tag_name) .replaceAll("%I", users.users[post_object['userID']]['description']) .replaceAll("%L", `/post/${post_index}`) + .replaceAll("%M", return_comments(post_index)) .replaceAll("%N", users.users[post_object["userID"]]['username']) .replaceAll("%P", "/post") .replaceAll("%O", `/edit/${post_index}`) @@ -68,6 +72,12 @@ function replace_format_indicators(input_string, post_index=0, tag_name="tag") { .replaceAll("%S", config.seperator) .replaceAll("%T", post_object["title"]) .replaceAll("%U", `/user/${users.users[post_object["userID"]]['username']}`) + .replaceAll("%X", `
+ +
+
+ +
`) .replaceAll("%Y", config.site_name) .replaceAll("%W", config.site_description) .replaceAll("%Z", config.attribution) @@ -90,6 +100,21 @@ function escape_input(input) { return output } +// TODO make the formatting customisable +function return_comments(post_id) { + const post_comments = comments.comments[post_id] + let comment_content = "" + for (let comment_index = 0; comment_index < post_comments.length; comment_index++) { + let comment = {...post_comments[comment_index]}; + comment['content'] = comment['content'] + .replaceAll(/>> ([0-9]*)/g, ">> $1") + .replaceAll("\n", "
") + comment_content += `
${comment['name']} ${unix_time_to_date_format(comment['pubdate'])} No. ${comment['id']}
${comment['content']}

` + } + return comment_content +} + +// RSS protocol gets app.get(config.rss_path, (req,res) => { if (config.rss == false) { res.send("Sorry, RSS is disabled!") @@ -106,7 +131,7 @@ app.get(config.rss_path, (req,res) => { rss_content += ` ${posts.posts[i]["title"]} - ${config.site_url}/post/${i}.${config.file_extension} + ${config.site_url}/post/${i} ${config.site_url}/post/${i} ${unix_time_to_rss_date(posts.posts[i]['pubdate'])}` @@ -177,11 +202,11 @@ app.get("/tag/:tag", (req,res) => { app.get("/post", (req,res) => { res.send(`
-
-
-
-
-
+
+
+
+
+

* Markdown supported
`); @@ -194,17 +219,34 @@ app.get("/edit/:post_id", (req,res) => {
-
-
- -
-
+
+
+
+


* Markdown supported
`); }); +app.post("/submit_comment", (req,res) => { + const unix_timestamp = getUnixTime(new Date()) + let name = escape_input(req.body.name) + if (name == "") { + name = config.default_username + } + new_comment = { + "name": name, + "content": escape_input(req.body.content), + "id": comments.counter, + "pubdate": unix_timestamp + }; + let counter = comments.counter+1; + comments.comments[req.body.post_index].push(new_comment); + fs.writeFileSync(`${__dirname}/comments.js`, `export const comments = ${JSON.stringify(comments.comments)}\nexport const counter = ${counter}`, 'utf-8'); + + res.redirect(301,`/post/${req.body.post_index}`) +}); app.post("/submit_edit", (req,res) => { const password = crypto.createHash('sha512').update(req.body.password).digest('hex'); const postID = req.body.postID @@ -225,6 +267,8 @@ app.post("/submit_edit", (req,res) => { if (typeof delete_bool != "undefined") { console.log("Deleting post!") posts.posts.splice(postID,1) + comments.comments.splice(postID,1) + fs.writeFileSync(`${__dirname}/comments.js`, `export const comments = ${JSON.stringify(comments.comments)}\nexport const counter = ${comments.counter}`, 'utf-8'); } fs.writeFileSync(`${__dirname}/posts.js`, `export const posts = ${JSON.stringify(posts.posts)}`, 'utf-8'); res.redirect(302, "/"); @@ -256,6 +300,8 @@ app.post("/submit_post", (req,res) => { "tags": tags, }) fs.writeFileSync(`${__dirname}/posts.js`, `export const posts = ${JSON.stringify(posts.posts)}`, 'utf-8'); + comments.comments.push([]) + fs.writeFileSync(`${__dirname}/comments.js`, `export const comments = ${JSON.stringify(comments.comments)}\nexport const counter = ${comments.counter}`) res.redirect(302, "/"); } else { diff --git a/config.js b/config.js index 74b59e9..71e2f6d 100755 --- a/config.js +++ b/config.js @@ -1,4 +1,5 @@ export const seperator = "
" +export const comment_indent = "| " export const site_name = "Deadvey's Blog" export const site_url = "https://deadvey.com" export const port = 8080 @@ -9,6 +10,9 @@ export const charset = "UTF-8" // Don't change unless you know why // Anything in this directory will be in the webroot, so put favicon.ico and anything else here. export const root_path = "/var/www/deadvey.com/blog" +// Default username if no username is inputted in comment submission +export const default_username = "Anon" + //export const federation = true //export const fediverse_url = "deadvey.com" export const rss = true @@ -31,6 +35,7 @@ export const time_zone = "+0000" // %H - Frontpage hit count // %I - User description // %L - URL Permanent link to the post +// %M - comments // %N - the username of the user (poster) // %P - URL to create a new post // %O - URL to edit this post @@ -38,6 +43,7 @@ export const time_zone = "+0000" // %S - post seperator as defined by post_seperator // %T - Title // %U - URL the the user (poster) +// %X - Comment submission box // %Y - Site Name as defined by site_name // %W - Site Description as defined by site_description // %Z - Attribution (to me) and source code link and license @@ -65,6 +71,9 @@ export const post_page_format = `

%T

Edit Post
Posted: %D
Edited: %E +%S +%X +%M %S` export const timeline_post_format = `

%T

%C

diff --git a/hitcount.txt b/hitcount.txt index b854a29..b3b2268 100644 --- a/hitcount.txt +++ b/hitcount.txt @@ -1 +1 @@ -128 \ No newline at end of file +228 \ No newline at end of file