From 6116769757ddd88781129e7339fc7ff60a259337 Mon Sep 17 00:00:00 2001 From: Patryk Niedźwiedziński Date: Fri, 7 Aug 2020 21:55:16 +0200 Subject: Add rss feed generation --- lib/generateRss.ts | 26 +++++++++++++++ lib/index.ts | 17 +++++++--- lib/interfaces.ts | 6 ++++ package-lock.json | 82 ++++++++++++++++++++++++++++++------------------ package.json | 4 ++- test/generateRss.spec.ts | 18 +++++++++++ 6 files changed, 117 insertions(+), 36 deletions(-) create mode 100644 lib/generateRss.ts create mode 100644 test/generateRss.spec.ts diff --git a/lib/generateRss.ts b/lib/generateRss.ts new file mode 100644 index 0000000..2f341c0 --- /dev/null +++ b/lib/generateRss.ts @@ -0,0 +1,26 @@ +import * as fs from "fs" +import RSS from "rss"; + +import { FeedOptions } from "./interfaces"; +import Post from "./Post"; + +export function generateRss(posts: Array, feed_path: string, feedOptions: FeedOptions) { + const feed = new RSS(feedOptions); + const parsedPosts = posts.forEach((post) => { + const { title, content, path, date, author } = post.toApi(); + feed.item({ + title, + description: content, + url: feedOptions.site_url + path, + guid: path, + author, + date, + }) + }) + const xml = feed.xml(); + fs.writeFile(feed_path, xml, (err) => { + if (err) { + console.log(err); + } + }) +} diff --git a/lib/index.ts b/lib/index.ts index 4bf4dd3..3eddf7a 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -1,6 +1,8 @@ +import { FeedOptions } from "./interfaces"; import { getPost as apiGetPost } from "./getPost"; import { getPosts as apiGetPosts } from "./getPosts"; -import { generateApi as apiGenerateApi } from "./generateApi" +import { generateApi as apiGenerateApi } from "./generateApi"; +import { generateRss as apiGenerateRss } from "./generateRss"; import Post from "./Post"; export default class Kronikarz { @@ -13,11 +15,18 @@ export default class Kronikarz { getPosts(): Array { return apiGetPosts(this.postPath); } + getPost(year: string, month: string, day: string, title: string): Post { return apiGetPost({ year, month, day, title }, this.postPath); } - generateApi(path: string) { - const posts = this.getPosts(); - apiGenerateApi(posts, path) + + generateApi(path: string) { + const posts = this.getPosts(); + apiGenerateApi(posts, path) + } + + generateRss(path: string, feedOptions: FeedOptions) { + const posts = this.getPosts(); + apiGenerateRss(posts, path, feedOptions); } } diff --git a/lib/interfaces.ts b/lib/interfaces.ts index 1fbb226..931f712 100644 --- a/lib/interfaces.ts +++ b/lib/interfaces.ts @@ -31,3 +31,9 @@ export interface PostApiListEntry { export interface PostApiEntry extends PostApiListEntry { content: string; } + +export interface FeedOptions { + title: string; + feed_url: string; + site_url: string; +} diff --git a/package-lock.json b/package-lock.json index 046111d..4760a60 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "kronikarz", - "version": "2.0.1", + "version": "2.0.3", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -2366,6 +2366,11 @@ "minimist": "^1.2.0" } }, + "@gerhobbelt/markdown-it-html5-media": { + "version": "0.6.0-1", + "resolved": "https://registry.npmjs.org/@gerhobbelt/markdown-it-html5-media/-/markdown-it-html5-media-0.6.0-1.tgz", + "integrity": "sha512-zxdRACZy6AvgyGqM4MSqGykGcq9STf0qQVARw/XBHTD18Nay3dqY6/3hcqINZnn6Z/vfW9YsEjG3S9r2eTusRQ==" + }, "@jest/console": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz", @@ -2682,6 +2687,11 @@ "integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==", "dev": true }, + "@types/rss": { + "version": "0.0.28", + "resolved": "https://registry.npmjs.org/@types/rss/-/rss-0.0.28.tgz", + "integrity": "sha512-Kymd0BI1tBOSwOwCN5Y8dtlJegTIF+izS8tJETiivJ7qAJGHhnuZjiunXWqBkgv6dg0ZZWyf0kEfMgkr4YWJzg==" + }, "@types/stack-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", @@ -6341,8 +6351,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -6363,14 +6372,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6385,20 +6392,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -6515,8 +6519,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -6528,7 +6531,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -6543,7 +6545,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -6551,14 +6552,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -6577,7 +6576,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -6658,8 +6656,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -6671,7 +6668,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -6757,8 +6753,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -6794,7 +6789,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -6814,7 +6808,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -6858,14 +6851,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, @@ -11577,6 +11568,30 @@ "inherits": "^2.0.1" } }, + "rss": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/rss/-/rss-1.2.2.tgz", + "integrity": "sha1-UKFpiHYTgTOnT5oF0r3I240nqSE=", + "requires": { + "mime-types": "2.1.13", + "xml": "1.0.1" + }, + "dependencies": { + "mime-db": { + "version": "1.25.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.25.0.tgz", + "integrity": "sha1-wY29fHOl2/b0SgJNwNFloeexw5I=" + }, + "mime-types": { + "version": "2.1.13", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.13.tgz", + "integrity": "sha1-4HqqnGxrmnyjASxpADrSWjnpKog=", + "requires": { + "mime-db": "~1.25.0" + } + } + } + }, "rsvp": { "version": "4.8.5", "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", @@ -13982,6 +13997,11 @@ "async-limiter": "^1.0.0" } }, + "xml": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", + "integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=" + }, "xml-name-validator": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", diff --git a/package.json b/package.json index 8b9baac..13023ed 100644 --- a/package.json +++ b/package.json @@ -17,11 +17,13 @@ "author": "Patryk Niedźwiedziński", "license": "ISC", "dependencies": { + "@gerhobbelt/markdown-it-html5-media": "0.6.0-1", "@types/jsdom": "^12.2.4", + "@types/rss": "0.0.28", "front-matter": "^3.0.2", "jsdom": "^15.1.1", "markdown-it": "^10.0.0", - "@gerhobbelt/markdown-it-html5-media": "0.6.0-1" + "rss": "^1.2.2" }, "devDependencies": { "@types/jest": "^24.0.18", diff --git a/test/generateRss.spec.ts b/test/generateRss.spec.ts new file mode 100644 index 0000000..5b3af66 --- /dev/null +++ b/test/generateRss.spec.ts @@ -0,0 +1,18 @@ +import * as fs from "fs"; +import Kronikarz from "../dist"; + +const k = new Kronikarz(__dirname + "/samples"); +const dir = "./tmp/rss.xml"; + +test("generate RSS feed", () => { + k.generateRss(dir, { title: "Test", feed_url: "https://site.com/rss.xml", site_url: "https://site.com" }); + fs.readFile("./tmp/rss.xml", "utf-8", (err, data) => { + expect(data).toBe(`<![CDATA[Test]]>https://site.comRSS for NodeFri, 07 Aug 2020 19:53:08 GMT<![CDATA[Test]]>

Test

+

12-12-2019 | Tester

+

test test test

+]]>
https://site.com/kronika/2019/12/12/test/kronika/2019/12/12/testThu, 12 Dec 2019 00:00:00 GMT
<![CDATA[Category]]>

Category

+

01-01-2020 | Tester

+

This file is for testing categories

+]]>
https://site.com/kronika/2019/12/12/category/kronika/2019/12/12/categoryThu, 12 Dec 2019 00:00:00 GMT
`); + }); +}); -- cgit 1.4.1