diff --git a/admin/admin.js b/admin/admin.js index 96f544d..5a08579 100644 --- a/admin/admin.js +++ b/admin/admin.js @@ -1,20 +1,29 @@ /** - * Renders the admin page contents + * Determines what template and controls that will be + * displayed based on the url such as + * / + * /posts + * /downloads + * + * For each controls it calls that "pages" associated javascript file + * which fetches the template, deals with post data and gathers context + * for the template engine. */ //file IO const utils = require('../utils/utils.js'); - - module.exports= { /** - * Method calls the admin widgets it correct order * - * @param request - * @return {*|Promise} + * @param request -- used to get post data + * @param clientAddress -- used to see if user is banned for login + * @param templateContext -- used by whiskers for information to plug + * in the template + * @param filename -- specific admin page requested + * @returns {Promise} resolves once everything has been added to the template context */ main: function(request, clientAddress, templateContext, filename) { @@ -48,19 +57,6 @@ module.exports= { console.log(error); }); - - // console.log(postData); - // Promise.all([require("./posts/newPost.js").main(postData), - // require("./category/addCategory.js").main(postData), - // require("./posts/editPost.js").main(postData), - // require("./downloads/adminDownloads.js").main(postData)]) - // .then(function(content) - // { - // resolve(content.join('')); - // }).catch(function(error) - // { - // reject(error); - // }); }); } else diff --git a/admin/adminDownloads.js b/admin/adminDownloads.js index 8ef8153..08e45d6 100644 --- a/admin/adminDownloads.js +++ b/admin/adminDownloads.js @@ -5,10 +5,9 @@ * @author Jeffery Russell 6-30-18 */ +/** Whiskers template file */ const TEMPLATE_FILE = "admin/adminDownloads.html"; -//file IO -const utils = require('../utils/utils.js'); const includes = require('../includes/includes.js'); @@ -50,12 +49,9 @@ const addDownloadPostData = function(postData) - /** - * Handel form requests from the downloads table - * - * @param postData - * @returns {*|Promise} + * Removes a download if requested by the + * post data from an admin. */ const removeDownloads = function(postData) { @@ -81,11 +77,14 @@ const removeDownloads = function(postData) /** - * Displays all the download information in a table - * @param postData - * @returns {*|Promise} + * Fetches the download items in the database so that + * the template engine can use it to display them in + * a table. + * + * @param templateContext-- context item used by whiskers + * @returns {Promise} */ -const displayDownloads = function(postData, templateContext) +const displayDownloads = function(templateContext) { return new Promise(function(resolve, reject) { @@ -103,22 +102,21 @@ const displayDownloads = function(postData, templateContext) module.exports= { - /** - * Renders tha download section of the admin page + /** Fetches context information for the template and handles + * post data for the downloads. * - * @param postData - * @returns {Promise} + * @param postData posted by user + * @param templateContext json object used as the template context + * @returns {Promise} renders the template used for this page */ main: function(postData, templateContext) { - console.log(postData); - console.log("downloads page called"); return new Promise(function(resolve, reject) { Promise.all([includes.fetchTemplate(TEMPLATE_FILE), addDownloadPostData(postData), removeDownloads(postData), - displayDownloads(postData, templateContext)]).then(function(template) + displayDownloads(templateContext)]).then(function(template) { resolve(template[0]); }).catch(function(error) diff --git a/admin/adminHome.js b/admin/adminHome.js new file mode 100644 index 0000000..c1dbdd0 --- /dev/null +++ b/admin/adminHome.js @@ -0,0 +1,138 @@ + +const TEMPLATE_FILE = "admin/adminHome.html"; + +const includes = require('../includes/includes.js'); + +const sql = require('../utils/sql'); + +const qs = require('querystring'); + + +/** + * Checks for post data regarding adding a new category. + * If a post is made with add_category, it parses the url-- replaces spaces + * with dashes -- and calls a insert method on the database + * + * @param postData + * @return {*|Promise} + */ +const processPostAddCategory = function(postData) +{ + return new Promise(function(resolve, reject) + { + const post = qs.parse(postData); + if(post.add_category) + { + const url = post.add_category.split(" ").join("-").toLowerCase(); + const q = "insert into categories (name, url) values " + + "('" + post.add_category + "','" + url + "')"; + if(sql.insert(q) != 0) + { + console.log("category added"); + } + else + { + console.log("error adding category"); + } + } + resolve(""); + }); +}; + +/** + * Displays all the categories in the database + * @return {*|Promise} + */ +const appendCategoriesToTemplate = function(templateContext) +{ + return new Promise(function(resolve, reject) + { + sql.getCategories().then(function(categories) + { + templateContext.categories = categories; + resolve(); + }).catch(function(error) + { + reject(error); + }) + }); +}; + +/** + * + * @param postData + * @return {*|Promise} + */ +const processPost = function(postData) +{ + return new Promise(function(resolve, reject) + { + var post = qs.parse(postData); + if(post.add_post_name) + { + var urls = post.add_post_name; + urls = urls.split(" ").join("-"); + urls =urls.toLowerCase(); + + + var q = "insert into posts (category_id, picture_url, published, name, url) values "; + + q += "('" + post.add_post_category + "', '" + post.add_post_picture + + "', '" + post.add_post_date + "', '" + post.add_post_name + "', '" + urls + "')"; + sql.insert(q).then(function() + { + var map = require('../utils/generateSiteMap'); + map.main(); + resolve(""); + }).catch(function(error) + { + reject(error); + }) + } + else if(post.clear_cache) + { + require("../sites/blog.js").clearCache(); + require("../includes/includes.js").clearCache(); + } + else if(post.git_pull) + { + const execSync = require('child_process').execSync; + code = execSync('git pull') + } + else + { + resolve(""); + } + }); +}; + + + +module.exports= + { + /** + * + * @param postData posted by user + * @param templateContext json object used as the template context + * @returns {Promise} renders the template used for this page + */ + main: function(postData, templateContext) + { + console.log("called"); + return new Promise(function(resolve, reject) + { + Promise.all([includes.fetchTemplate(TEMPLATE_FILE), + processPostAddCategory(postData), + appendCategoriesToTemplate(templateContext), + processPost(postData)]) + .then(function(template) + { + resolve(template[0]); + }).catch(function(error) + { + console.log("error in add downloads.js"); + reject(error); + }); + }); + } + }; \ No newline at end of file diff --git a/admin/category/addCategory.html b/admin/category/addCategory.html deleted file mode 100644 index 3817d97..0000000 --- a/admin/category/addCategory.html +++ /dev/null @@ -1,15 +0,0 @@ -
-

Add Category

- -
-
- - -
-
- -
-
-
-
\ No newline at end of file diff --git a/admin/category/addCategory.js b/admin/category/addCategory.js deleted file mode 100644 index 247b9fd..0000000 --- a/admin/category/addCategory.js +++ /dev/null @@ -1,37 +0,0 @@ -//file io -const utils = require('../../utils/utils.js'); - -//update db -const sql = require('../../utils/sql'); - -//parse post data -const qs = require('querystring'); - - - - - - - - -module.exports= -{ - main: function(postData) - { - return new Promise(function(resolve, reject) - { - Promise.all([utils.include("./admin/category/addCategory.html"), - printCategories(), - processPost(postData)]).then(function(html) - { - resolve("
" + - html.join('') + - "
"); - }).catch(function(error) - { - console.log("error in addCategory.js"); - reject(error); - }) - }); - } -}; \ No newline at end of file diff --git a/admin/login/login.html b/admin/login/login.html deleted file mode 100644 index dfc44c4..0000000 --- a/admin/login/login.html +++ /dev/null @@ -1,28 +0,0 @@ -
-
-
-

Login

-
- -
-
- - -
-
- - -
-
- -
-
-
- -
-
\ No newline at end of file diff --git a/admin/login/login.js b/admin/login/login.js index 21f5ab7..663a3c2 100644 --- a/admin/login/login.js +++ b/admin/login/login.js @@ -6,7 +6,7 @@ const sql = require('../../utils/sql'); const qs = require('querystring'); -const DEBUG = true; +const DEBUG = false; /** diff --git a/admin/posts.js b/admin/posts.js new file mode 100644 index 0000000..3a98894 --- /dev/null +++ b/admin/posts.js @@ -0,0 +1,103 @@ +/** Whiskers template file + * this has stuff for both editing posts and viewing a list of posts*/ +const TEMPLATE_FILE = "admin/adminPosts.html"; + +const includes = require('../includes/includes.js'); + +const sql = require('../utils/sql'); + +//parses the post data +const qs = require('querystring'); + + +/** + * Detects if the post data came from the edit form in posts table or edit post + * in the edit post form. + * + * @param postData + * @param renderContext + * @returns {Promise} + */ +const processPostData = function(postData, renderContext) +{ + return new Promise(function(resolve, reject) + { + var postParsed = qs.parse(postData); + + if(postParsed.edit_post) + { + renderContext.editPost = true; + sql.getPostById(postParsed.edit_post).then(function(post) + { + post.published = post.published.toISOString().split('T')[0]; + renderContext.post = post; + resolve(); + }); + } + else if(postParsed.edit_post_2) + { + sql.editPost(postParsed).then(function() + { + resolve(); + }).catch(function(error) + { + reject(error); + }); + } + else + { + resolve(); + } + }); +}; + + +/** + * Grabs and appends the list of posts from the SQL database to + * the template context for the template renderer. + * + * @param templateContext + * @returns {Promise} + */ +const fetchPostsInformation = function(templateContext) +{ + return new Promise(function(resolve, reject) + { + sql.getAllPosts().then(function(posts) + { + templateContext.posts = posts; + resolve(); + }).catch(function(error) + { + reject(error); + }) + }); +}; + +module.exports= + { + /** + * Fetches context information for the admin posts page and handles post + * data sent regarding editing posts. + * + * @param postData posted by user + * @param templateContext json object used as the template context + * @returns {Promise} renders the template used for this page + */ + main: function(postData, templateContext) + { + return new Promise(function(resolve, reject) + { + Promise.all([includes.fetchTemplate(TEMPLATE_FILE), + processPostData(postData, templateContext), + fetchPostsInformation(templateContext)]).then(function(template) + { + resolve(template[0]); + }).catch(function(error) + { + console.log("error in add admin posts.js"); + reject(error); + }); + }); + } + }; \ No newline at end of file diff --git a/admin/posts/editPost.js b/admin/posts/editPost.js deleted file mode 100644 index ee9aa91..0000000 --- a/admin/posts/editPost.js +++ /dev/null @@ -1,182 +0,0 @@ -/** - * File which renders the edit form for the posts and processes - * the post data generated by edit forms. - * - * @type {Promise|*} - */ - -//parses the post data -const qs = require('querystring'); - -//updates db -const sql = require('../../utils/sql'); - - -/** - * Displays a single row in the posts view - * - * @param post - */ -const renderPostRow = function(post) -{ - return "" + - "" + post.category_id + "" + - "" + post.name + "" + - "" + post.picture_url + "" + - "" + post.published + "" + - "
\n" + - "\n" + - ""+ - "
" + - ""; -}; - - -/** - * Displays all the posts in a table - */ -const postsTable = function() -{ - const html = "
" + - "

Posts

" + - "
" + - "" + - "" + - ""; - return new Promise(function(resolve, reject) - { - sql.getAllPosts().then(function(posts) - { - var postPromises = []; - posts.forEach(function(post) - { - postPromises.push(renderPostRow(post)); - }); - - Promise.all(postPromises).then(function(htmls) - { - resolve(html + htmls.join('') + "
Category #NameHeader PictureDateEdit

"); - }).catch(function(error) - { - reject(error); - }); - }).catch(function(error) - { - reject(error); - }) - }); -}; - - -/** - * Displays the edit form for edit posts - * - * @param post_id - */ -const displayRenderForm = function(post_id) -{ - return new Promise(function(resolve, reject) - { - sql.getPostById(post_id).then(function(post) - { - const html = "
"+ - "

Edit Post

"+ - "
"+ - "
\n" + - " \n" + - " \n" + - "
"+ - "
\n" + - " \n" + - " \n" + - "
"+ - "
\n" + - " \n" + - " \n" + - "
"+ - "
\n" + - " \n" + - " \n" + - "
"+ - "
"+ - ""+ - "
"+ - "

"; - - resolve(html); - }).catch(function(error) - { - reject(error); - }); - - }); -}; - - -/** - * Detects if the post data came from the edit form in posts table or edit post - * in the edit post form. Based on this, this function will call one of two functions - * - * @param postData - */ -const processPost = function(postData) -{ - return new Promise(function(resolve, reject) - { - var postParsed = qs.parse(postData); - - if(postParsed.edit_post) - { - //display edit form - displayRenderForm(postParsed.edit_post).then(function(html) - { - resolve(html); - }).catch(function(error) - { - reject(error); - }); - } - else if(postParsed.edit_post_2) - { - sql.editPost(postParsed).then(function(html) - { - resolve(html); - }).catch(function(error) - { - reject(error); - }); - } - else - { - resolve(""); - } - }); -}; - - -module.exports= -{ - /** - * Method which calls helper functions which processes post data for editing posts - * and calls a function which displays all the posts in a table - * - * @param postData - */ - main: function(postData) - { - return new Promise(function(resolve, reject) - { - Promise.all([processPost(postData), - postsTable()]).then(function(html) - { - resolve("
" + html.join('')); - }).catch(function(error) - { - console.log("error in edit post.js"); - reject(error); - }) - }); - } -}; \ No newline at end of file diff --git a/admin/posts/newPost.html b/admin/posts/newPost.html deleted file mode 100644 index d6bd5ed..0000000 --- a/admin/posts/newPost.html +++ /dev/null @@ -1,56 +0,0 @@ -
-
-

Server Controls

- -
- -
- - -
- -
- -
- - -
- -
- -
- - -
-
-

New Post

- -
- -
- - -
- -
- - -
- -
- - -
- - -
- - -
-
- -
-
-
-
\ No newline at end of file diff --git a/admin/posts/newPost.js b/admin/posts/newPost.js deleted file mode 100644 index 1004922..0000000 --- a/admin/posts/newPost.js +++ /dev/null @@ -1,30 +0,0 @@ -const utils = require('../../utils/utils.js'); -const sql = require('../../utils/sql'); - -const qs = require('querystring'); - - - - - -module.exports= - { - /** - * - * @param postData - * @return {*} - */ - main: function(postData) - { - return new Promise(function(resolve, reject) - { - Promise.all([utils.include("./admin/posts/newPost.html"), processPost(postData)]).then(function(html) - { - resolve(html.join('')); - }).catch(function(error) - { - reject(error); - }) - }); - } - }; \ No newline at end of file diff --git a/docs/sqlConfig.md b/docs/sqlConfig.md new file mode 100644 index 0000000..cc438d6 --- /dev/null +++ b/docs/sqlConfig.md @@ -0,0 +1,60 @@ +# MYSQL Schema + +![](docs/blogSql.svg) + +```mysql +create database jrtechs_blog; + +use jrtechs_blog; + +create table users( +user_id mediumint unsigned not null AUTO_INCREMENT, +user_name varchar(60) not null, +password char(64) not null, +salt char(64) not null, +primary key(user_id) +); + +create table categories( +category_id mediumint unsigned not null AUTO_INCREMENT, +name varchar(60) not null, +url varchar(60) not null, +primary key(category_id) +); + +create table posts( +post_id mediumint unsigned not null AUTO_INCREMENT, +category_id mediumint unsigned not null, +picture_url varchar(100) not null, +published datetime not null, +name varchar(100) not null, +url varchar(100) not null, +primary key(post_id) +); + + +create table downloads( +download_id mediumint unsigned not null AUTO_INCREMENT, +file varchar(40) not null, +name varchar(40) not null, +download_count mediumint not null, +primary key(download_id) +); + +create table popular_posts( +popular_post_id mediumint unsigned not null AUTO_INCREMENT, +post_id mediumint unsigned not null, +primary key(popular_post_id) +); + +create table traffic_log( +log_id mediumint unsigned not null AUTO_INCREMENT, +url varchar(60) not null, +ip varchar(20) not null, +date datetime not null, +primary key(log_id) +); + + +grant all on jrtechs_blog.* to blog_user@localhost identified by "password"; +``` \ No newline at end of file diff --git a/templates/admin/adminPosts.html b/templates/admin/adminPosts.html index e69de29..d49ebc8 100644 --- a/templates/admin/adminPosts.html +++ b/templates/admin/adminPosts.html @@ -0,0 +1,68 @@ +
+
+ {if editPost} +
+

Edit Post

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ +
+
+
+ {/if} +
+
+ +
+
+
+

Posts

+ + + + + + + + + + + + {for post in posts} + + + + + + + + {/for} + +
Category #NameHeader PictureDateEdit
{post.category_id}{post.name}{post.picture_url}{post.published} +
+ + +
+
+
+
+
+
\ No newline at end of file