Doc: Auto-generate RSS feed from news

release-2.8
Laurent Cozic 2022-06-03 12:31:42 +01:00
parent 40d9ccf183
commit 232e0a3a72
13 changed files with 115 additions and 18 deletions

View File

@ -2098,6 +2098,9 @@ packages/tools/website/updateNews.js.map
packages/tools/website/utils/frontMatter.d.ts
packages/tools/website/utils/frontMatter.js
packages/tools/website/utils/frontMatter.js.map
packages/tools/website/utils/news.d.ts
packages/tools/website/utils/news.js
packages/tools/website/utils/news.js.map
packages/tools/website/utils/openGraph.d.ts
packages/tools/website/utils/openGraph.js
packages/tools/website/utils/openGraph.js.map

3
.gitignore vendored
View File

@ -2088,6 +2088,9 @@ packages/tools/website/updateNews.js.map
packages/tools/website/utils/frontMatter.d.ts
packages/tools/website/utils/frontMatter.js
packages/tools/website/utils/frontMatter.js.map
packages/tools/website/utils/news.d.ts
packages/tools/website/utils/news.js
packages/tools/website/utils/news.js.map
packages/tools/website/utils/openGraph.d.ts
packages/tools/website/utils/openGraph.js
packages/tools/website/utils/openGraph.js.map

View File

@ -13,6 +13,7 @@
<meta name="theme-color" content="#000000" />
<link rel="stylesheet" href="{{{assetUrls.css.fontawesome}}}">
{{> openGraphTags}}
{{> rssFeedLink}}
<link
rel="stylesheet"
href="{{cssBaseUrl}}/bootstrap5.0.2.min.css"

View File

@ -25,6 +25,7 @@ https://github.com/laurent22/joplin/blob/dev/{{{sourceMarkdownFile}}}
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
{{> openGraphTags}}
{{> rssFeedLink}}
<link
rel="stylesheet"
href="{{cssBaseUrl}}/bootstrap5.0.2.min.css"

View File

@ -0,0 +1 @@
<link rel="alternate" type="application/rss+xml" title="Joplin RSS feed" href="https://joplinapp.org/rss.xml" />

View File

@ -50,6 +50,7 @@
"gettext-extractor": "^3.5.3",
"gulp": "^4.0.2",
"jest": "^26.6.3",
"rss": "^1.2.2",
"sass": "^1.39.2",
"sqlite3": "^5.0.0",
"typescript": "^4.1.3"

View File

@ -4,13 +4,12 @@ import { pressCarouselItems } from './utils/pressCarousel';
import { getMarkdownIt, loadMustachePartials, markdownToPageHtml, renderMustache } from './utils/render';
import { AssetUrls, Env, PlanPageParams, Sponsors, TemplateParams } from './utils/types';
import { createFeatureTableMd, getPlans, loadStripeConfig } from '@joplin/lib/utils/joplinCloud';
import { MarkdownAndFrontMatter, stripOffFrontMatter } from './utils/frontMatter';
import { stripOffFrontMatter } from './utils/frontMatter';
import { dirname, basename } from 'path';
import { readmeFileTitle, replaceGitHubByWebsiteLinks } from './utils/parser';
import { extractOpenGraphTags } from './utils/openGraph';
import { readCredentialFileJson } from '@joplin/lib/utils/credentialFiles';
const moment = require('moment');
import { getNewsDateString } from './utils/news';
interface BuildConfig {
env: Env;
@ -178,19 +177,6 @@ async function loadSponsors(): Promise<Sponsors> {
return output;
}
const getNewsDateString = (info: MarkdownAndFrontMatter, mdFilePath: string): string => {
// If the date is set in the metadata, we get it from there. Otherwise we
// derive it from the filename (eg. 20220224-release-2-7.md)
if (info.created) {
return moment(info.created).format('D MMM YYYY');
} else {
const filenameNoExt = basename(mdFilePath, '.md');
const s = filenameNoExt.split('-');
return moment(s[0], 'YYYYMMDD').format('D MMM YYYY');
}
};
const processNewsMarkdown = (md: string, mdFilePath: string): string => {
const info = stripOffFrontMatter(md);
md = info.doc.trim();

View File

@ -7,6 +7,9 @@ import { basename } from 'path';
import { rootDir } from '../tool-utils';
import fetch from 'node-fetch';
import { compileWithFrontMatter, MarkdownAndFrontMatter, stripOffFrontMatter } from './utils/frontMatter';
import { markdownToHtml } from './utils/render';
import { getNewsDateString } from './utils/news';
const RSS = require('rss');
interface ApiConfig {
baseUrl: string;
@ -61,6 +64,11 @@ const getPosts = async (newsDir: string): Promise<Post[]> => {
});
}
output.sort((a: Post, b: Post) => {
if (a.id < b.id) return -1;
return +1;
});
return output;
};
@ -124,6 +132,37 @@ const getForumTopPostByExternalId = async (externalId: string): Promise<ForumTop
}
};
const generateRssFeed = async (posts: Post[]) => {
const feed = new RSS({
title: 'Joplin',
description: 'Joplin, the open source note-taking application',
feed_url: 'https://joplinapp.org/rss.xml',
site_url: 'https://joplinapp.org',
});
let postCount = 0;
for (const post of posts.reverse()) {
const content = await getPostContent(post);
const html = markdownToHtml(content.body);
feed.item({
title: content.title,
description: html,
url: `https://joplinapp.org/news/${post.id}/`,
guid: post.id,
date: getNewsDateString(content.parsed, post.path),
custom_elements: [
{ 'twitter-text': content.parsed.tweet },
],
});
postCount++;
if (postCount >= 20) break;
}
return feed.xml() as string;
};
const main = async () => {
const argv = require('yargs').argv;
config.key = argv._[0];
@ -133,6 +172,9 @@ const main = async () => {
const posts = await getPosts(`${rootDir}/readme/news`);
const rssFeed = await generateRssFeed(posts);
await writeFile(`${rootDir}/Assets/WebsiteAssets/rss.xml`, rssFeed, 'utf8');
for (const post of posts) {
if (ignoredPostIds.includes(post.id)) continue;

View File

@ -6,6 +6,7 @@ export interface MarkdownAndFrontMatter {
updated?: Date;
source_url?: string;
forum_url?: string;
tweet?: string;
}
const readProp = (line: string): string[] => {

View File

@ -0,0 +1,18 @@
/* eslint-disable import/prefer-default-export */
import { MarkdownAndFrontMatter } from './frontMatter';
import { basename } from 'path';
const moment = require('moment');
export const getNewsDateString = (info: MarkdownAndFrontMatter, mdFilePath: string): string => {
// If the date is set in the metadata, we get it from there. Otherwise we
// derive it from the filename (eg. 20220224-release-2-7.md)
if (info.created) {
return moment(info.created).format('D MMM YYYY');
} else {
const filenameNoExt = basename(mdFilePath, '.md');
const s = filenameNoExt.split('-');
return moment(s[0], 'YYYYMMDD').format('D MMM YYYY');
}
};

View File

@ -47,6 +47,11 @@ export function getMarkdownIt() {
}
export function markdownToPageHtml(md: string, templateParams: TemplateParams): string {
const html = markdownToHtml(md);
return renderMustache(html, templateParams);
}
export const markdownToHtml = (md: string): string => {
const markdownIt = getMarkdownIt();
markdownIt.use(headerAnchor);
markdownIt.linkify.set({
@ -54,5 +59,5 @@ export function markdownToPageHtml(md: string, templateParams: TemplateParams):
'fuzzyIP': false,
'fuzzyEmail': false,
});
return renderMustache(markdownIt.render(md), templateParams);
}
return markdownIt.render(md);
};

View File

@ -1,5 +1,6 @@
---
forum_url: https://discourse.joplinapp.org/t/25726
tweet: Joplin received 6 Contributor Projects for GSoC 2022! Welcome to our new contributors who will be working on these projects over summer! #GSoC2022
---
# Joplin received 6 Contributor Projects for GSoC 2022!

View File

@ -3676,6 +3676,7 @@ __metadata:
node-fetch: 1.7.3
relative: ^3.0.2
request: ^2.88.0
rss: ^1.2.2
sass: ^1.39.2
sharp: ^0.25.2
source-map-support: ^0.5.19
@ -21653,6 +21654,22 @@ __metadata:
languageName: node
linkType: hard
"mime-db@npm:~1.25.0":
version: 1.25.0
resolution: "mime-db@npm:1.25.0"
checksum: bf1c56d50cb5752c5495ddf2a1dd938015c58b3bc0c8d19c4cacb198322267d6fc1b944e70efec0d5215584cf1c57d58e2d4f609094ebe3e88bdf34028ca102d
languageName: node
linkType: hard
"mime-types@npm:2.1.13":
version: 2.1.13
resolution: "mime-types@npm:2.1.13"
dependencies:
mime-db: ~1.25.0
checksum: 661db5db5900dcf8bc345d2aea9cc2bd38d53374c000e0d8d7b592230ff37ea173b9514f15bfd89efe46476f57f1785866d13060c71d12ca98c5b5a8f662ae04
languageName: node
linkType: hard
"mime-types@npm:^2.1.12, mime-types@npm:^2.1.18, mime-types@npm:^2.1.27, mime-types@npm:~2.1.19, mime-types@npm:~2.1.24, mime-types@npm:~2.1.7":
version: 2.1.34
resolution: "mime-types@npm:2.1.34"
@ -26829,6 +26846,16 @@ __metadata:
languageName: unknown
linkType: soft
"rss@npm:^1.2.2":
version: 1.2.2
resolution: "rss@npm:1.2.2"
dependencies:
mime-types: 2.1.13
xml: 1.0.1
checksum: 9f823a6c1c807b4d9a800f74063d03eb188751c2e7fab36a50d5bdc33577a03562d5a610d8c809729f5a3721805a5495119c105237a87a6bb5a8a146df8b887a
languageName: node
linkType: hard
"rsvp@npm:^4.8.4":
version: 4.8.5
resolution: "rsvp@npm:4.8.5"
@ -31688,6 +31715,13 @@ __metadata:
languageName: node
linkType: hard
"xml@npm:1.0.1":
version: 1.0.1
resolution: "xml@npm:1.0.1"
checksum: 11b5545ef3f8fec3fa29ce251f50ad7b6c97c103ed4d851306ec23366f5fa4699dd6a942262df52313a0cd1840ab26256da253c023bad3309d8ce46fe6020ca0
languageName: node
linkType: hard
"xmlbuilder@npm:>=11.0.1":
version: 15.1.1
resolution: "xmlbuilder@npm:15.1.1"