Changed how comments are stored and how data is retrieved
This commit is contained in:
@@ -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
|
||||
|
||||
42
src/data.js
42
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,31 +68,33 @@ 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
|
||||
}
|
||||
else if (data == "hitcount") {
|
||||
let result = func.require_module('../data/data.json') // This file is actually called data.json
|
||||
break;
|
||||
case 'hitcount':
|
||||
result = func.require_module('../data/data.json') // This file is actually called data.json
|
||||
return result["hitcount"]
|
||||
}
|
||||
else {
|
||||
break;
|
||||
default:
|
||||
console.log("Error, invalid requested")
|
||||
return 1
|
||||
return -1
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
// NOT YET WORKING!
|
||||
if (config["data_storage"] == "mysql") {
|
||||
case 'mysql':
|
||||
const mysql = require('mysql');
|
||||
let con = mysql.createConnection({
|
||||
host: config.database.host,
|
||||
|
||||
@@ -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 "<a href="/tag/string1">string1</a>, <a href="/tag/string2">string2</a>, <a href="/tag/string3">string3</a>"
|
||||
// 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 += `<a href="/tag/${tags[tag_index].trim()}">#${tags[tag_index].trim()}</a> ` // 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, "<a href='/comment/$1-$2'>>> $1-$2</a>")
|
||||
.replaceAll(/>>([0-9]*)-([0-9]*)/g, "<a href='/comment/$1-$2'>>>$1-$2</a>")
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
@@ -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) => {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<% }; %>
|
||||
Comments:<br/>
|
||||
<% 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++) { %>
|
||||
<a href="/comment/<%= postID %>-<%= comment_index %>"><%= postID %>-<%= comment_index %></a><br/>
|
||||
<% }; %>
|
||||
<% }; %>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<% 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++) { %>
|
||||
<a href="/comment/<%= postID %>-<%= comment_index %>"><%= postID %>-<%= comment_index %></a><br/>
|
||||
<% }; %>
|
||||
<% }; %>
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang='<%- config.locale %>'>
|
||||
<head>
|
||||
<%- include('../partials/head'); %>
|
||||
</head>
|
||||
<body>
|
||||
<div id='header'>
|
||||
<%- include('../headers/site_wide'); %>
|
||||
</div>
|
||||
|
||||
<div id='advanced-search'>
|
||||
<form method="GET" action="/search">
|
||||
<label>Search Term:</label>
|
||||
<input type='text' placeholder='🔍' name='q' value='<%- search_term %>'><br/>
|
||||
|
||||
<label>Search for:</label><br/>
|
||||
<label>Post:</label>
|
||||
<input type="checkbox" name="type" value="post" <% if (search_type.includes('post')) {%>checked<% } %>><br/>
|
||||
<label>User:</label>
|
||||
<input type="checkbox" name="type" value="user" <% if (search_type.includes('user')) {%>checked<% } %>><br/>
|
||||
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<%- config.seperator %>
|
||||
|
||||
<div id='results'>
|
||||
<% search_results.posts.forEach((result, index) => { %>
|
||||
<a href="/post/<%- result.id %>"><%- result.title %></a><br/>
|
||||
<% }); %>
|
||||
<% search_results.users.forEach((result, index) => { %>
|
||||
<a href="/user/<%- result.username %>"><%- result.prettyname %></a><br/>
|
||||
<% }); %>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -15,7 +15,7 @@
|
||||
</div>
|
||||
<div id="post-details">
|
||||
<span id="post-author">
|
||||
<i><%= locale.written_by %> <a href="/user/<%= user.username %>"><%= user.username %></a></i>
|
||||
<i><%= locale.written_by %> <a href="/user/<%= user.username %>"><%= user.prettyname %></a></i>
|
||||
</span>
|
||||
-
|
||||
<span id="post-pubdate">
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</div>
|
||||
<div id="post-details">
|
||||
<span id="post-author">
|
||||
<i><a href="/user/<%= user.username %>"><%= user.username %></a></i>
|
||||
<i><a href="/user/<%= user.username %>"><%= user.prettyname %></a></i>
|
||||
</span>
|
||||
-
|
||||
<span id="post-pubdate">
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</div>
|
||||
<div id="post-details">
|
||||
<span id="post-author">
|
||||
<i><a href="/user/<%= user.username %>"><%= user.username %></a></i>
|
||||
<i><a href="/user/<%= user.username %>"><%= user.prettyname %></a></i>
|
||||
</span>
|
||||
-
|
||||
<span id="post-pubdate">
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</div>
|
||||
<div id="post-details">
|
||||
<span id="post-author">
|
||||
<i><a href="/user/<%= user.username %>"><%= user.username %></a></i>
|
||||
<i><a href="/user/<%= user.username %>"><%= user.prettyname %></a></i>
|
||||
</span>
|
||||
-
|
||||
<span id="post-pubdate">
|
||||
|
||||
@@ -15,11 +15,23 @@ body {
|
||||
input, textarea, button {
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
font-size: 20px;
|
||||
|
||||
}
|
||||
textarea {
|
||||
width: 100%;
|
||||
height: 250px;
|
||||
field-sizing: content; /* Only supported by Chromium */
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
#search-form input {
|
||||
border: none;
|
||||
border-radius: 0px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user