aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Powers <mark@marks.kitchen>2021-02-23 20:09:29 -0600
committerMark Powers <mark@marks.kitchen>2021-02-23 20:09:29 -0600
commit8a0a3a00e75dc2351a7218d0059b87f7e9345871 (patch)
tree180a3dc0065db849301d0e87c11f129475c02eb5
parent4ed0b48232f2d0fdaa1ed85f243119608d2d5caf (diff)
parent5b5dc610bc0da17fd006982de50b4dc74b134a54 (diff)
Merge branch 'master' of marks.kitchen:/srv/git/markskitchen
-rw-r--r--README.md4
-rw-r--r--src/css/styles.css34
-rw-r--r--src/html/admin.html3
-rw-r--r--src/index.js9
-rw-r--r--src/js/background.js29
-rw-r--r--src/js/like.js11
-rw-r--r--src/res/change.jpgbin0 -> 4689611 bytes
-rw-r--r--src/res/day.jpgbin0 -> 3710493 bytes
-rw-r--r--src/res/favicon.ico (renamed from src/icon/favicon.ico)bin1150 -> 1150 bytes
-rw-r--r--src/res/favicon.svg (renamed from src/icon/favicon.svg)0
-rw-r--r--src/res/night.jpgbin0 -> 4125007 bytes
-rw-r--r--src/server.js65
-rw-r--r--src/templates/feed.html8
-rw-r--r--src/templates/footer.html6
-rw-r--r--src/templates/header.html2
-rw-r--r--src/templates/misc.html5
-rw-r--r--src/templates/navigation.html18
17 files changed, 135 insertions, 59 deletions
diff --git a/README.md b/README.md
index b325d16..83bb85a 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,7 @@
+# marks.kitchen
+My personal website engine. Allows for posting content from a web interface.
+Uses handlesbars templates and a database backend via sequelize.
+
Configuration:
- Requires mysql database. Include a `config.json` in `src` directory with the following structure:
```json
diff --git a/src/css/styles.css b/src/css/styles.css
index f406104..4572569 100644
--- a/src/css/styles.css
+++ b/src/css/styles.css
@@ -8,14 +8,18 @@
--btn-hover: #0a0;
--light-text: #aaa;
}
-
body {
- width: 80%;
+ width: 60%;
+ min-width: 500px;
margin: auto;
/* margin: 0px; */
background-color: var(--background);
font-family: Arial, Helvetica, sans-serif;
+ height: 100%;
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: cover;
}
h1, h2 {
@@ -30,6 +34,10 @@ h1 {
margin-left: 20px;
}
+.card-title {
+ margin-left: 0;
+}
+
@keyframes zoom-left {
0% {left: 100%; }
100% {left: 0;}
@@ -115,12 +123,17 @@ p {
border-top: 1px solid var(--light-text);
border-bottom: 1px solid var(--light-text);
background-color: var(--background-accent);
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-evenly;
}
+
.titlebar a{
margin: auto;
max-width: 10%;
min-width: 100px;
+ flex-grow: 1;
}
.btn {
@@ -128,16 +141,17 @@ p {
padding: 1px 3px;
border: 1px solid var(--btn-text);
border-radius: 3px;
- width: 100%;
max-width: 100px;
line-height: 2em;
text-align: center;
vertical-align: middle;
white-space: nowrap;
text-decoration: none;
+ cursor: pointer;
}
.btn-primary {
+ width: 100%;
height: 2em;
font-size: 20px;
background-color: var(--btn-color);
@@ -148,6 +162,15 @@ p {
background-color: var(--btn-hover);
}
+.btn-secondary {
+ background-color: var(--btn-color);
+ color: var(--btn-text);
+}
+
+.btn-secondary:hover{
+ background-color: var(--btn-hover);
+}
+
.date {
font-style: italic;
margin: 0em;
@@ -209,3 +232,8 @@ a.navigation:visited, a.navigation:link {
.email::after {
content: "@marks.kitchen";
}
+
+.cool {
+ float: right;
+}
+
diff --git a/src/html/admin.html b/src/html/admin.html
index 3eaa60a..29e4b87 100644
--- a/src/html/admin.html
+++ b/src/html/admin.html
@@ -42,6 +42,9 @@
<div class="form">
<form action="/admin/posts" method="post" enctype="multipart/form-data">
<div>
+ <input name="title" placeholder="title">
+ </div>
+ <div>
<textarea name="description"></textarea>
</div>
<div>
diff --git a/src/index.js b/src/index.js
index 4b9a3c6..7ceecf0 100644
--- a/src/index.js
+++ b/src/index.js
@@ -53,7 +53,14 @@ function setUpModels(){
type: {
type: Sequelize.STRING,
allowNull: false,
- },}),
+ },
+ title: {
+ type: Sequelize.STRING,
+ },
+ likes: {
+ type: Sequelize.INTEGER,
+ }
+ }),
"pictures": database.define('pictures', {
source: { type: Sequelize.TEXT, allowNull: false},
}),
diff --git a/src/js/background.js b/src/js/background.js
new file mode 100644
index 0000000..f8a7684
--- /dev/null
+++ b/src/js/background.js
@@ -0,0 +1,29 @@
+function set_background_image(){
+ let date = new Date();
+ let current_hour = date.getHours()
+ if(current_hour <= 8 || current_hour >= 20){
+ var photo = "night.jpg"
+ } else if(current_hour <= 10 || current_hour > 17){
+ var photo = "change.jpg"
+ } else {
+ var photo = "day.jpg"
+ }
+ let btn = document.getElementById("loadBtn")
+ if(btn){
+ btn.remove()
+ }
+ if(!document.getElementById("backgroundId")){
+ document.body.style.backgroundImage = `url('/res/${photo}')`;
+ let desc = document.createElement("p")
+ desc.id = "backgroundId"
+ desc.innerHTML = "Background images in the public domain, painted by <a href=\"https://artvee.com/artist/ivan-konstantinovich-aivazovsky/\">Ivan Konstantinovich Aivazovsky.</a>"
+ footer.appendChild(desc)
+ }
+}
+let el = document.createElement("a")
+el.id = "loadBtn"
+el.innerText = "load background"
+el.onclick = set_background_image
+let footer = document.getElementsByTagName("footer")[0]
+footer.appendChild(el)
+
diff --git a/src/js/like.js b/src/js/like.js
new file mode 100644
index 0000000..cd1e015
--- /dev/null
+++ b/src/js/like.js
@@ -0,0 +1,11 @@
+function likePost(type, id){
+ fetch(`/post/like/${type}/${id}`)
+ .then(response => response.json())
+ .then(response => {
+ console.log(response)
+ let btn_id=`btn_${type}_${id}`
+ let el = document.getElementById(btn_id)
+ el.innerText = `👍 (${response.likes})`
+ })
+}
+
diff --git a/src/res/change.jpg b/src/res/change.jpg
new file mode 100644
index 0000000..0d0b1c3
--- /dev/null
+++ b/src/res/change.jpg
Binary files differ
diff --git a/src/res/day.jpg b/src/res/day.jpg
new file mode 100644
index 0000000..13c115c
--- /dev/null
+++ b/src/res/day.jpg
Binary files differ
diff --git a/src/icon/favicon.ico b/src/res/favicon.ico
index 7646b67..7646b67 100644
--- a/src/icon/favicon.ico
+++ b/src/res/favicon.ico
Binary files differ
diff --git a/src/icon/favicon.svg b/src/res/favicon.svg
index ad339b8..ad339b8 100644
--- a/src/icon/favicon.svg
+++ b/src/res/favicon.svg
diff --git a/src/res/night.jpg b/src/res/night.jpg
new file mode 100644
index 0000000..9b9471c
--- /dev/null
+++ b/src/res/night.jpg
Binary files differ
diff --git a/src/server.js b/src/server.js
index 297c135..58d29fb 100644
--- a/src/server.js
+++ b/src/server.js
@@ -51,41 +51,9 @@ function hashWithSalt(password, salt){
return hash.digest("base64");
};
-function constructFeed(posts){
- var html = []
- html.push(`<div class="feed">`)
- posts.forEach(post => {
- html.push(`<div class="card">
- <p class="card-text">${post.description}</p>
- <div class="card-img">`)
- post.images.forEach(image => {
- html.push(`<span>
- <a href="/${image}"><img src="/${image}"></a>
- </span>`)
- })
- html.push(`</div>
- <p class="date">
- <a href="/post/${post.type}/${post.id}">${post.createdAt.toString().substring(0,10)}</a>`)
- post.tags.forEach(tag => {
- html.push(`<span>
- <a class="tag" href="/tags/${tag}">${tag}</a>
- </span>`)
- })
- html.push(`</p>
- </div>`)
- })
- html.push(`</div>`)
- return html.join("");
-}
-
-async function constructFeedFromType(models, postType){
- var posts = await models.posts.findAll({
- where: { type: postType }, order: [['createdAt', 'DESC']]
- });
- posts = posts.map(x => x.get({ plain: true }));
- await addImagesAndTagsToPosts(models, posts)
-
- return constructFeed(posts)
+function formatDate(d) {
+ let month = d.toLocaleString('default', { month: 'long' });
+ return month + " " + d.getDate() + ", " + (1900+d.getYear())
}
async function formatPostsforSingle(models, postType, postId){
@@ -98,7 +66,8 @@ async function formatPostsforSingle(models, postType, postId){
posts = posts.map(x => x.get({ plain: true }));
await addImagesAndTagsToPosts(models, posts)
posts.forEach(post => {
- post.createdAt = post.createdAt.toString().substring(0, 10)
+ post.createdAt = formatDate(post.createdAt)
+ post.showTitle = post.type != "bread"
})
return posts
}
@@ -110,7 +79,8 @@ async function formatPostsForType(models, postType){
posts = posts.map(x => x.get({ plain: true }));
await addImagesAndTagsToPosts(models, posts)
posts.forEach(post => {
- post.createdAt = post.createdAt.toString().substring(0, 10)
+ post.createdAt = formatDate(post.createdAt)
+ post.showTitle = post.type != "bread"
})
return posts;
}
@@ -177,7 +147,20 @@ function setUpRoutes(models, jwtFunctions, database, templates) {
let body = templates["blog-single"]({posts, date});
res.status(200).send(body)
})
+<<<<<<< HEAD
server.get('/tags/:name', cache('5 minutes'), async (req, res) => {
+=======
+ server.get('/post/like/:type/:id', async (req, res) => {
+ let type = req.params.type
+ let id = req.params.id
+ var post = await models.posts.findOne({
+ where: { type, id },
+ });
+ post.update({likes: post.likes+1})
+ res.status(200).send({likes: post.likes});
+ })
+ server.get('/tags/:name', async (req, res) => {
+>>>>>>> 5b5dc610bc0da17fd006982de50b4dc74b134a54
const { name } = req.params;
const postsWithTag = await models.tags.findAll({ attributes: ["postId"], where: { text: name } })
.map(function (x) {
@@ -287,6 +270,7 @@ function setUpRoutes(models, jwtFunctions, database, templates) {
try {
const type = req.body.type
req.body.description = marked(req.body.description)
+ req.body.likes = 0
const newPost = await models.posts.create(req.body);
req.files.forEach(async (file) => {
await models.pictures.create({ "source": "uploads/" + file.filename, "postId": newPost.id });
@@ -368,6 +352,9 @@ function setUpRoutes(models, jwtFunctions, database, templates) {
server.get('/js/:id', cache('5 minutes'), (req, res) => {
res.sendFile(__dirname + "/js/" + req.params.id);
});
+ server.get('/res/:id', (req, res) => {
+ res.sendFile(__dirname + "/res/" + req.params.id);
+ });
server.get('/feed.xml', cache('1 hour'), async (req, res) => {
var feed = new rss({
@@ -375,7 +362,7 @@ function setUpRoutes(models, jwtFunctions, database, templates) {
description: "Posts from marks.kitchen",
feed_url: "https://marks.kitchen/rss",
site_url: "https://marks.kitchen",
- webMaster: "webmaster@marks.kitchen",
+ webMaster: "webmaster@marks.kitchen (Mark Powers)",
copyright: "Mark Powers"
})
var posts = await models.posts.findAll({
@@ -384,7 +371,7 @@ function setUpRoutes(models, jwtFunctions, database, templates) {
posts = posts.map(x => x.get({ plain: true }));
posts.forEach(post =>{
feed.item({
- title: post.createdAt.toString().substring(0, post.createdAt.toString().indexOf(" GMT")),
+ title: post.title,
description: post.description,
date: post.createdAt,
url: `https://marks.kitchen/post/${post.type}/${post.id}`,
diff --git a/src/templates/feed.html b/src/templates/feed.html
index 2158f3e..3ea4f16 100644
--- a/src/templates/feed.html
+++ b/src/templates/feed.html
@@ -1,6 +1,9 @@
<div class="feed">
{{#each posts}}
<div class="card">
+ {{#if this.showTitle}}
+ <h1 class="card-title">{{this.title}}</h1>
+ {{/if}}
<p class="card-text">{{{this.description}}}</p>
<div class="card-img">
{{#each this.images}}
@@ -18,7 +21,10 @@
<a class="tag" href="/tags/{{this}}">{{this}}</a>
{{/each}}
</span>
+ <span class="cool btn btn-secondary" onclick="likePost('{{this.type}}', {{this.id}})" id="btn_{{this.type}}_{{this.id}}">
+ &#128077; ({{this.likes}})
+ </span>
</p>
</div>
{{/each}}
-</div> \ No newline at end of file
+</div>
diff --git a/src/templates/footer.html b/src/templates/footer.html
index 617b5fa..6dc5a48 100644
--- a/src/templates/footer.html
+++ b/src/templates/footer.html
@@ -11,4 +11,8 @@
<span class="spacer"></span>
<br>
</div>
-</footer> \ No newline at end of file
+ <div>
+ <noscript>Enable javascript for a background image</noscript>
+ <script src="/js/background.js"></script>
+ </div>
+</footer>
diff --git a/src/templates/header.html b/src/templates/header.html
index 2ceebfd..1989b04 100644
--- a/src/templates/header.html
+++ b/src/templates/header.html
@@ -2,4 +2,4 @@
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="icon" href="/favicon.svg">
<link rel="alternate icon" href="/favicon.ico">
-
+<script src="/js/like.js"></script>
diff --git a/src/templates/misc.html b/src/templates/misc.html
index ee641d1..3f0aee8 100644
--- a/src/templates/misc.html
+++ b/src/templates/misc.html
@@ -8,16 +8,13 @@
</head>
<body>
-
+
<h1>
<a class="navigation" href="/" title="marks.kitchen">&lt;</a>
Miscellany
</h1>
{{> navigation}}
<div>
- <a href="projects" class="btn btn-primary">Projects</a>
- </div>
- <div>
<a href="chess" class="btn btn-primary">Chess</a>
</div>
<div>
diff --git a/src/templates/navigation.html b/src/templates/navigation.html
index 6bb10f1..b101bab 100644
--- a/src/templates/navigation.html
+++ b/src/templates/navigation.html
@@ -1,10 +1,10 @@
<nav class="titlebar">
- <div>
- <a href="/" class="btn btn-primary">Home</a>
- <a href="/bread" class="btn btn-primary">Bread</a>
- <a href="/blog" class="btn btn-primary">Blog</a>
- <a href="https://games.marks.kitchen" class="btn btn-primary">Games</a>
- <a href="/email" class="btn btn-primary">Email</a>
- <a href="/misc" class="btn btn-primary">Misc</a>
- </div>
-</nav> \ No newline at end of file
+ <a href="/" class="btn btn-primary">Home</a>
+ <a href="/bread" class="btn btn-primary">Bread</a>
+ <a href="/blog" class="btn btn-primary">Blog</a>
+ <a href="https://games.marks.kitchen" class="btn btn-primary">Games</a>
+ <a href="/email" class="btn btn-primary">Email</a>
+ <a href="/projects" class="btn btn-primary">Projects</a>
+ <a href="https://wiki.marks.kitchen/public" class="btn btn-primary">Wiki</a>
+ <a href="/misc" class="btn btn-primary">Misc</a>
+</nav>