diff --git a/README.md b/README.md
index 19cc6e2..88f8eac 100644
--- a/README.md
+++ b/README.md
@@ -21,8 +21,8 @@ Read the [configuation guide](docs/CONFIG.md) for configuration help (in config.
* user creation, modification and deletion via frontend
* multi user
* powerful customisation via EJS
+* Configuration via config.json
* site wide and user specific rss, atom
-* hitcount
* Markdown syntax in posts
* Commenting on posts and replying to other comments
* site wide custom CSS and strings
diff --git a/src/data.js b/src/data.js
index 82e4826..763ad3a 100644
--- a/src/data.js
+++ b/src/data.js
@@ -14,7 +14,7 @@ export function increment_hitcount(postID = -1) { // -1 Means it will increment
writedata('hitcount', hitcount);
}
else {
- let post = getdata('posts', postID);
+ let post = getdata('posts','id', postID);
if (typeof post.hitcount != 'undefined') {
post.hitcount += 1;
writedata('posts', post, postID)
@@ -68,60 +68,62 @@ export function searchdata(term, type) { // Searches users and posts for any mat
return search_results;
};
-export function getdata(data, index=-1) {
-
- if (config["data_storage"] == "json") {
- if (data == "posts" || data == 'users' || data == 'comments') {
- let result = func.require_module(`../data/${data}.json`)
- if (index != -1) {
- if (index < result.length) {
- return result[index]
- }
- return 1 // This index doesn't exist
+export function getdata(data_type, key=-1, value=-1) {
+ let result = undefined
+ switch (config["data_storage"]) {
+ case 'json':
+ switch (data_type) {
+ case 'users':
+ case 'posts':
+ case 'comments':
+ result = func.require_module(`../data/${data_type}.json`)
+ if (key != -1) {
+ return result[func.find_key_value_pair(result, key, value)]
+ return -1 // This index doesn't exist
+ }
+ return result
+ break;
+ case 'hitcount':
+ result = func.require_module('../data/data.json') // This file is actually called data.json
+ return result["hitcount"]
+ break;
+ default:
+ console.log("Error, invalid requested")
+ return -1
+ break;
}
- return result
- }
- else if (data == "hitcount") {
- let result = func.require_module('../data/data.json') // This file is actually called data.json
- return result["hitcount"]
- }
- else {
- console.log("Error, invalid requested")
- return 1
- }
- }
-
+ break;
// NOT YET WORKING!
- if (config["data_storage"] == "mysql") {
- const mysql = require('mysql');
- let con = mysql.createConnection({
- host: config.database.host,
- user: config.database.user,
- password: config.database.password,
- database: config.database.database,
- });
+ case 'mysql':
+ const mysql = require('mysql');
+ let con = mysql.createConnection({
+ host: config.database.host,
+ user: config.database.user,
+ password: config.database.password,
+ database: config.database.database,
+ });
- con.connect(function(err) {
- if (err) throw err;
+ con.connect(function(err) {
+ if (err) throw err;
- if (data == "posts" || data == 'users' || data == 'comments') {
- con.query(`SELECT * FROM ${data}`, function (err, result, fields) {
- if (err) throw err;
- result = Object.values(JSON.parse(JSON.stringify(result)))
- console.log(result)
- return result;
- });
- }
- else if (data == 'hitcount') {
- con.query(`SELECT paramValue FROM params WHERE paramName = '${data}'`, function (err, result, fields) {
- if (err) throw err;
- result = Object.values(JSON.parse(JSON.stringify(result)))
- console.log(result)
- return result;
- });
+ if (data == "posts" || data == 'users' || data == 'comments') {
+ con.query(`SELECT * FROM ${data}`, function (err, result, fields) {
+ if (err) throw err;
+ result = Object.values(JSON.parse(JSON.stringify(result)))
+ console.log(result)
+ return result;
+ });
+ }
+ else if (data == 'hitcount') {
+ con.query(`SELECT paramValue FROM params WHERE paramName = '${data}'`, function (err, result, fields) {
+ if (err) throw err;
+ result = Object.values(JSON.parse(JSON.stringify(result)))
+ console.log(result)
+ return result;
+ });
- }
- });
+ }
+ });
}
}
diff --git a/src/functions.js b/src/functions.js
index 8cfd817..cdcb3f9 100644
--- a/src/functions.js
+++ b/src/functions.js
@@ -7,12 +7,15 @@ const locale = require(`../locales/${config.locale}.json`)
// This function requires a module without caching it
// So the server doesn't need to be restarted, though this can slow it down a bit.
// https://stackoverflow.com/a/16060619
-export function require_module(module) {
- if (config.cache_data == false) {
+export function require_module(module)
+{
+ if (config.cache_data == false)
+ {
delete require.cache[require.resolve(module)];
return require(module);
}
- else {
+ else
+ {
return require(module);
}
}
@@ -22,7 +25,8 @@ export function require_module(module) {
// this converts unix time (an integer) into a string that is formatted according to config.js
// uses date-fns's fromUnixTime() and format() functions
// returns the formatted date (string)
-export function unix_time_to_date_format(unix_time) {
+export function unix_time_to_date_format(unix_time)
+{
const { fromUnixTime, format, getUnixTime } = require("date-fns") // A date utility library
let date = fromUnixTime(unix_time)
let formatted_date = format(date, config.date_format)
@@ -33,14 +37,16 @@ export function unix_time_to_date_format(unix_time) {
// eg "Mon, 23 May 2025 18:59:59 +0100"
// accepts unix time (int)
// returns the formatted date (string)
-export function unix_time_to_rss_date(unix_time) {
+export function unix_time_to_rss_date(unix_time)
+{
const { fromUnixTime, format, getUnixTime } = require("date-fns") // A date utility library
let date = fromUnixTime(unix_time)
let formatted_date = format(date, "EEE, dd MMM yyyy HH:mm:ss")
return `${formatted_date} ${config.time_zone}`
}
// And again with atom's date format
-export function unix_time_to_atom_date(unix_time) {
+export function unix_time_to_atom_date(unix_time)
+{
const { fromUnixTime, format, getUnixTime } = require("date-fns") // A date utility library
let date = fromUnixTime(unix_time)
let formatted_date = format(date, "yyyy-MM-dd'T'HH:mm:ss'Z'")
@@ -51,13 +57,17 @@ export function unix_time_to_atom_date(unix_time) {
// eg "string1, string2, string3"
// this is so you can have a list of tags that each point to their individual tag page
// returns: string
-export function render_tags(tags) {
+export function render_tags(tags)
+{
let string = "" // Initialises the string
- if (tags.length == 1 && tags[0] == "") {
+ if (tags.length == 1 && tags[0] == "")
+ {
string = ''; // If there are no tags, output nothing
}
- else {
- for (let tag_index = 0; tag_index < tags.length; tag_index++) { // Loop over each tag
+ else
+ {
+ for (let tag_index = 0; tag_index < tags.length; tag_index++)
+ { // Loop over each tag
string += `#${tags[tag_index].trim()} ` // Adds the tag to the string as a HTML href
}
}
@@ -68,10 +78,13 @@ export function render_tags(tags) {
// This function returns the username for a given userID by looping over every user
// if the user is present, it returns the index of the user (integer)
// if the user is not present it returns -1
-export function get_userID(username) {
- const users = require("../data/users.json")
- for (let i = 0; i < users.length; i++) { // Loop over every user
- if (users[i]['username'] == username) {
+export function get_userID(username)
+{
+ const users = require_module("../data/users.json")
+ for (let i = 0; i < users.length; i++)
+ { // Loop over every user
+ if (users[i]['username'] == username)
+ {
return i // If the username matches then return the index of that user
}
}
@@ -82,7 +95,8 @@ export function get_userID(username) {
// https://www.freeformatter.com/html-entities.html
// accepts a string
// returns a string with some character replaced by their entities
-export function escape_input(input) {
+export function escape_input(input)
+{
let output = input
.replaceAll("&", "&") // This must be first
.replaceAll("<", "<")
@@ -97,7 +111,8 @@ export function escape_input(input) {
// Render comment content by replacing the >> int with a url link to that comment
// Syntax: ">> postID-commentID"
-export function render_comment(comment_content) {
+export function render_comment(comment_content)
+{
return comment_content
.replaceAll(/>> ([0-9]*)-([0-9]*)/g, ">> $1-$2")
.replaceAll(/>>([0-9]*)-([0-9]*)/g, ">>$1-$2")
@@ -108,9 +123,11 @@ export function render_comment(comment_content) {
};
// Renders a string into markdown using markdown-it library
-export function render_md(content) {
+export function render_md(content)
+{
const markdownit = require("markdown-it")
- const md = markdownit({ // this is just defining some options for markdown-it, should I add this to config.json?
+ const md = markdownit
+ ({ // this is just defining some options for markdown-it, should I add this to config.json?
html: false,
xhtmlOut: false,
breaks: true,
@@ -121,3 +138,11 @@ export function render_md(content) {
return md.render(content)
};
+export function find_key_value_pair(data_array, key, value) {
+ for (let i = 0; i < data_array.length; i++) {
+ if (data_array[i][key] == value) {
+ return i
+ }
+ }
+ return -1
+};
diff --git a/src/routes/form_actions.js b/src/routes/form_actions.js
index 6d7e32c..688f0da 100644
--- a/src/routes/form_actions.js
+++ b/src/routes/form_actions.js
@@ -31,11 +31,10 @@ router.post("/submit_comment", (req,res) => {
new_comment = {
"name": name,
"content": content,
- "id": comments[postID].length,
+ "id": comments[postID]['comments'].length,
"pubdate": unix_timestamp,
- "postID": postID,
};
- comments[postID].push(new_comment);
+ comments[postID]['comments'].push(new_comment);
fs.writeFileSync(`../data/comments.json`, `${JSON.stringify(comments)}`, 'utf-8');
}
@@ -59,8 +58,9 @@ router.post("/submit_post", (req,res) => {
else if (users[func.get_userID(username)]['hash'] == password) { // Password matches
console.log(username, "is submitting a post titled:", title);
+ id = posts.length
posts.push({
- "id": posts.length,
+ "id": id,
"userID": func.get_userID(username),
"title": title,
"content": content,
@@ -69,7 +69,7 @@ router.post("/submit_post", (req,res) => {
"tags": tags,
})
fs.writeFileSync(`../data/posts.json`, `${JSON.stringify(posts)}`, 'utf-8');
- comments.push([])
+ comments.push({'id': id, 'comments': []})
fs.writeFileSync(`../data/comments.json`, `${JSON.stringify(comments)}`)
res.redirect(302, "/");
}
@@ -216,7 +216,7 @@ router.get('/search', (req, res) => {
console.log('searching for: ', search_term);
const search_results = data.searchdata(search_term, search_type); // data.searchdata returns an array of search results
- res.render('partials/search', {
+ res.render('pages/search', {
config,
locale,
search_results,
diff --git a/src/routes/indexes.js b/src/routes/indexes.js
index fba0931..6c3cbbb 100644
--- a/src/routes/indexes.js
+++ b/src/routes/indexes.js
@@ -13,7 +13,7 @@ router.get("/index/pages", (req,res) => {
users: data.getdata('users'),
comments: data.getdata('comments'),
});
-}); // /index/posts
+}); // /index/pages
router.get("/index/posts", (req,res) => {
res.render("indexes/posts", {
config,
@@ -25,13 +25,13 @@ router.get("/index/users", (req,res) => {
config,
users: data.getdata('users'),
});
-}); // /index/posts
+}); // /index/users
router.get("/index/comments", (req,res) => {
res.render("indexes/comments", {
config,
comments: data.getdata('comments'),
});
-}); // /index/posts
+}); // /index/comments
module.exports = router;
diff --git a/src/routes/standard_pages.js b/src/routes/standard_pages.js
index f0cd459..6ac781f 100644
--- a/src/routes/standard_pages.js
+++ b/src/routes/standard_pages.js
@@ -33,7 +33,7 @@ router.get("/", (req,res) => {
// Users
router.get("/user/:username", (req, res) => {
const userID = func.get_userID(req.params.username)
- let user = data.getdata('users', userID)
+ let user = data.getdata('users', 'id', userID)
if (userID != -1) {
res.render("pages/user",
{
@@ -61,7 +61,7 @@ router.get("/user/:username", (req, res) => {
// Posts
router.get("/post/:post_index", (req, res) => {
const postID = parseInt(req.params.post_index)
- let post = data.getdata('posts', postID)
+ let post = data.getdata('posts','id', postID)
if (post == 1) { // data.getdata returns error code 1 if nothing is available
res.render("partials/message", {
message: locale.post_doesnt_exist,
@@ -69,7 +69,7 @@ router.get("/post/:post_index", (req, res) => {
})
}
if (config.enable_hitcount) {
- data.increment_hitcount(postID)
+ data.increment_hitcount(postID)
}
if (typeof post["deleted"] == "undefined" || post["deleted"] == false) {
res.render("pages/post",
@@ -78,8 +78,8 @@ router.get("/post/:post_index", (req, res) => {
locale,
post,
postID,
- user: data.getdata('users', post.userID),
- comments: data.getdata('comments', postID),
+ user: data.getdata('users','id', post.userID),
+ comments: data.getdata('comments','id', postID)["comments"],
fromUnixTime,
format,
getUnixTime,
@@ -117,7 +117,7 @@ router.get("/comment/:postID-:commentID", (req,res) => {
const commentID = parseInt(req.params.commentID);
const postID = parseInt(req.params.postID);
- let posts_comments = data.getdata('comments', postID)
+ let posts_comments = data.getdata('comments', 'id', postID)["comments"]
let comment = 1
// For loop to find the comment with matching ID
posts_comments.forEach((current_comment, index) => {
diff --git a/views/indexes/all_pages.ejs b/views/indexes/all_pages.ejs
index 1f645ea..53cfdcf 100644
--- a/views/indexes/all_pages.ejs
+++ b/views/indexes/all_pages.ejs
@@ -20,7 +20,7 @@
<% }; %>
Comments:
<% for (let postID = 0; postID < comments.length; postID++) { %>
- <% for (let comment_index = 0; comment_index < comments[postID].length; comment_index++) { %>
+ <% for (let comment_index = 0; comment_index < comments[postID]['comments'].length; comment_index++) { %>
<%= postID %>-<%= comment_index %>
<% }; %>
<% }; %>
diff --git a/views/indexes/comments.ejs b/views/indexes/comments.ejs
index 39192ea..25399d5 100644
--- a/views/indexes/comments.ejs
+++ b/views/indexes/comments.ejs
@@ -5,7 +5,7 @@