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 @@ <% 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/partials/search.ejs b/views/partials/search.ejs deleted file mode 100644 index b0df7bb..0000000 --- a/views/partials/search.ejs +++ /dev/null @@ -1,37 +0,0 @@ - - - - <%- include('../partials/head'); %> - - - - - - - <%- config.seperator %> - -
- <% search_results.posts.forEach((result, index) => { %> - <%- result.title %>
- <% }); %> - <% search_results.users.forEach((result, index) => { %> - <%- result.prettyname %>
- <% }); %> -
- - diff --git a/views/posts/post.ejs b/views/posts/post.ejs index f906c33..c882528 100644 --- a/views/posts/post.ejs +++ b/views/posts/post.ejs @@ -15,7 +15,7 @@
- <%= locale.written_by %> <%= user.username %> + <%= locale.written_by %> <%= user.prettyname %> - diff --git a/views/posts/tag.ejs b/views/posts/tag.ejs index 2370aa7..a2959c6 100644 --- a/views/posts/tag.ejs +++ b/views/posts/tag.ejs @@ -15,7 +15,7 @@
- <%= user.username %> + <%= user.prettyname %> - diff --git a/views/posts/timeline.ejs b/views/posts/timeline.ejs index 2370aa7..a2959c6 100644 --- a/views/posts/timeline.ejs +++ b/views/posts/timeline.ejs @@ -15,7 +15,7 @@
- <%= user.username %> + <%= user.prettyname %> - diff --git a/views/posts/user.ejs b/views/posts/user.ejs index 2370aa7..a2959c6 100644 --- a/views/posts/user.ejs +++ b/views/posts/user.ejs @@ -15,7 +15,7 @@
- <%= user.username %> + <%= user.prettyname %> - diff --git a/webroot/default.css b/webroot/default.css index 248f564..e9e6a16 100644 --- a/webroot/default.css +++ b/webroot/default.css @@ -15,11 +15,23 @@ body { input, textarea, button { border: none; border-radius: 5px; - field-sizing: content; /* Only supported by Chromium */ + 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; }