From 4eaa437c0a285c617e30a533d1ef369eaa8644a6 Mon Sep 17 00:00:00 2001
From: terminaldweller
Date: Tue, 5 Jul 2022 20:19:16 +0430
Subject: WIP, adding rss to the blog
---
Dockerfile | 4 ++--
docker-compose-test.yaml | 25 ++++++++++++----------
docker-compose.yaml | 39 ++++++++++++++++++++++++++++++----
model.js | 55 ++++++++++++++++++++++++++++++++++++------------
server.js | 34 ++++++++++++++++++++++--------
static/about.html | 6 ++++++
views/index.ejs | 8 ++++++-
views/rss_feed.pug | 18 ++++++++--------
8 files changed, 140 insertions(+), 49 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index 23e5984..551946e 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -3,7 +3,7 @@ RUN apk add openssl
WORKDIR /certs
RUN openssl req -nodes -new -x509 -subj="/C=US/ST=Denial/L=springfield/O=Dis/CN=localhost" -keyout server.key -out server.cert
-FROM node:lts-alpine3.13
+FROM node:lts-alpine3.15
COPY --from=certbuilder /certs/ /certs
COPY ./package.* /server/
RUN cd /server && npm install --production
@@ -11,6 +11,6 @@ COPY ./css /server/css/
COPY ./views /server/views/
COPY ./static /server/static/
COPY ./mds /server/mds/
-COPY ./server.js /server/
+COPY ./*.js /server/
ENTRYPOINT ["/server/server.js"]
EXPOSE 9000
diff --git a/docker-compose-test.yaml b/docker-compose-test.yaml
index 243b282..fceb9b9 100644
--- a/docker-compose-test.yaml
+++ b/docker-compose-test.yaml
@@ -1,11 +1,11 @@
version: "3.7"
services:
- web:
- image: web
+ blog:
+ image: blog
build:
- context: ./
+ context: .
networks:
- - webnet
+ - blognet
- dbnet
ports:
- "19009:9000"
@@ -16,30 +16,33 @@ services:
- SERVER_LISTEN_PORT=9000
depends_on:
- mongo
+ secrets:
+ - mongo_user
+ - mongo_pass
mongo:
image: mongo:5.0
networks:
- dbnet
restart: on-failure
ports:
- - "27117:27017"
+ - "127.0.0.1:27117:27017"
- "127.0.0.1:27118:27018"
- "127.0.0.1:27119:27019"
volumes:
- - db-data:/data/db
- env:
+ - blog-data:/data/db
+ environment:
- MONGO_INITDB_ROOT_USERNAME_FILE=/run/secrets/mongo_user
- MONGO_INITDB_ROOT_PASSWORD_FILE=/run/secrets/mongo_pass
secrets:
- mongo_user
- mongo_pass
networks:
- webnet:
+ blognet:
dbnet:
volumes:
- db-data:
+ blog-data:
secrets:
mongo_user:
- file: ./mongo_user
+ file: ./mongo_secrets/mongo_user
mongo_pass:
- file: ./mongo_pass
+ file: ./mongo_secrets/mongo_pass
diff --git a/docker-compose.yaml b/docker-compose.yaml
index 5f3e217..79e5d0c 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -1,11 +1,12 @@
version: "3.7"
services:
- web:
- image: web
+ blog:
+ image: blog
build:
context: ./
networks:
- - webnet
+ - blognet
+ - dbnet
restart: unless-stopped
ports:
- "9000:9000"
@@ -16,5 +17,35 @@ services:
environment:
- SERVER_DEPLOYMENT_TYPE=deployment
- SERVER_LISTEN_PORT=9000
+ depends_on:
+ - mongo
+ secrets:
+ - mongo_user
+ - mongo_pass
+ mongo:
+ image: mongo:5.0
+ networks:
+ - dbnet
+ restart: on-failure
+ ports:
+ - "127.0.0.1:27117:27017"
+ - "127.0.0.1:27118:27018"
+ - "127.0.0.1:27119:27019"
+ volumes:
+ - blog-data:/data/db
+ environment:
+ - MONGO_INITDB_ROOT_USERNAME_FILE=/run/secrets/mongo_user
+ - MONGO_INITDB_ROOT_PASSWORD_FILE=/run/secrets/mongo_pass
+ secrets:
+ - mongo_user
+ - mongo_pass
networks:
- webnet:
+ blognet:
+ dbnet:
+volumes:
+ blog-data:
+secrets:
+ mongo_user:
+ file: ./mongo_secrets/mongo_user
+ mongo_pass:
+ file: ./mongo_secrets/mongo_pass
diff --git a/model.js b/model.js
index 7eba2a4..d4bfc83 100644
--- a/model.js
+++ b/model.js
@@ -1,22 +1,30 @@
"use strict";
+const fs = require("fs");
+const path = require("path");
const mongoose = require("mongoose");
+const Schema = mongoose.Schema;
mongoose.Promise = global.Promise;
const db = {};
db.mongoose = mongoose;
-db.url = "mongo:27017";
+const db_pass = fs.readFileSync("/run/secrets/mongo_pass").toString();
+const db_user = fs.readFileSync("/run/secrets/mongo_user").toString();
+db.url = "mongodb://" + db_user + ":" + db_pass + "@mongo:27017";
-const blogPostModel = mongoose.model(
- "blogPost",
- mongoose.Schema(
- {
- title: String,
- description: String,
- published: Boolean,
- },
- { timestamps: true }
- )
-);
+const BlogPostSchema = new Schema({
+ title: { type: String, required: true, trim: true },
+ slug: { type: String, required: true, lowercase: true, trim: true },
+ body: { type: String, required: true },
+ teaser: { type: String, required: true },
+ keywords: { type: Array, required: true },
+ lastUpdatedAt: { type: Number },
+});
+
+// a simple hook to update the timestamp(lastUpdatedAt) on update
+BlogPostSchema.pre("save", function (next) {
+ this.lastUpdatedAt = Date.now();
+ next();
+});
function dbInit() {
db.mongoose
@@ -29,4 +37,25 @@ function dbInit() {
process.exit(1);
});
}
-module.exports = dbInit;
+
+function populateDB(model) {
+ let filePaths = fs.readdirSync(path.join(__dirname, "mds"));
+ filePaths.forEach((fileName) => {
+ let fileContent = fs
+ .readFileSync(path.join(__dirname, "mds", fileName), "utf-8")
+ .toString();
+ let newBlogPost = new model({
+ title: fileName,
+ slug: "slug",
+ body: fileContent,
+ teaser: "teaser",
+ keywords: ["kw1", "kw2"],
+ });
+ newBlogPost.save();
+ });
+}
+module.exports = {
+ blogPost: mongoose.model("BlogPost", BlogPostSchema),
+ dbInit: dbInit,
+ populateDB: populateDB,
+};
diff --git a/server.js b/server.js
index a42072f..bd23a1f 100755
--- a/server.js
+++ b/server.js
@@ -22,15 +22,23 @@ const mit = require("markdown-it")({ html: true })
const spdy = require("spdy");
const helmet = require("helmet");
const morgan = require("morgan");
-const pug = require("pug");
+// const pug = require("pug");
+const model = require("./model");
+
+model.dbInit();
+model.populateDB(model.blogPost);
const app = express();
app.disable("x-powered-by");
app.use(express.static(path.join(__dirname, "css")));
app.use(express.static(path.join(__dirname, "static")));
app.set("views", path.join(__dirname, "views"));
+// app.set("view engine", "ejs");
+// app.engine("ejs", require("ejs").__express);
+// app.engine("pug", require("pug").renderFilej);
+// app.engine("pug", "pug");
app.set("view engine", "ejs");
-app.engine("ejs", require("ejs").__express);
+app.set("view engine", "pug");
app.use(helmet.crossOriginEmbedderPolicy());
app.use(helmet.crossOriginOpenerPolicy());
@@ -85,7 +93,7 @@ function renderAndSend(req, res) {
);
//FIXME-this can obviously fail
readStream.on("data", (chunk) => {
- res.render("index", {
+ res.render("index.ejs", {
cache: true,
data: {
blogHttp: mit.render(chunk),
@@ -111,7 +119,7 @@ app.get("/about", (req, res) => {
app.get("/archive", (req, res) => {
res.type("text/html");
- res.render("archive", {
+ res.render("archive.ejs", {
cache: true,
data: {
mds: fs.readdirSync(path.join(__dirname, "mds"), "utf-8"),
@@ -129,11 +137,19 @@ app.get("/robots.txt", (req, res) => {
});
app.get("/rss/feed", (req, res) => {
- const compiledFunction = pug.compileFile("./views/rss_feed.pug");
- const files = fs.readdirSync(path.join(__dirname, "mds"));
- for (const file of files) {
- res.send(compiledFunction(file));
- }
+ model.blogPost
+ .find({})
+ .sort("-lastUpdatedAt")
+ .select("title slug lastUpdatedAt teaser")
+ .exec(function (err, posts) {
+ if (err) return err;
+ return res.render("rss_feed.pug", { cache: true, posts: posts });
+ });
+ // const compiledFunction = pug.compileFile("./views/rss_feed.pug");
+ // const files = fs.readdirSync(path.join(__dirname, "mds"));
+ // for (const file of files) {
+ // res.send(compiledFunction(file));
+ // }
});
app.get("/$", (req, res) => {
diff --git a/static/about.html b/static/about.html
index b6bdfa9..a56ad24 100644
--- a/static/about.html
+++ b/static/about.html
@@ -25,5 +25,11 @@
here
.
+
+
+
+
+
+