Customize feed

This commit is contained in:
Dennis Reimann
2021-09-19 18:43:19 +02:00
parent 9bf0f045f1
commit d6bcb7b771
5 changed files with 174 additions and 132 deletions

View File

@@ -1,3 +1,5 @@
const { decode } = require('html-entities')
// configure markdown-it // configure markdown-it
const transformer = require('jstransformer') const transformer = require('jstransformer')
const { _tr: mdTransformer } = transformer(require('jstransformer-markdown-it')) const { _tr: mdTransformer } = transformer(require('jstransformer-markdown-it'))
@@ -14,7 +16,11 @@ mdTransformer.render = str => renderMd(str, config)
// replacements // replacements
const replacements = str => { const replacements = str => {
return str.replace(/<\/?u>/g, '') return str && str.replace(/<\/?u>/g, '')
}
const stripHTML = str => {
return str && decode(str.replace(/(<([^>]+)>)/ig, '').trim().replace(/\n\s*/g, '\n'))
} }
// slug // slug
@@ -34,5 +40,6 @@ module.exports = {
markdown: mdTransformer.render, markdown: mdTransformer.render,
replacements, replacements,
slugify, slugify,
stripHTML,
truncate truncate
} }

151
package-lock.json generated
View File

@@ -15,7 +15,11 @@
"autoprefixer": "10.3.4", "autoprefixer": "10.3.4",
"browser-sync": "2.27.5", "browser-sync": "2.27.5",
"csso-cli": "3.0.0", "csso-cli": "3.0.0",
"fast-xml-parser": "3.20.0",
"glob": "7.1.7", "glob": "7.1.7",
"he": "1.2.0",
"html-entities": "2.3.2",
"jstoxmlparser": "1.0.2",
"jstransformer-markdown-it": "2.1.0", "jstransformer-markdown-it": "2.1.0",
"markdown-it": "12.2.0", "markdown-it": "12.2.0",
"node-file-rev": "1.1.3", "node-file-rev": "1.1.3",
@@ -29,7 +33,6 @@
"postcss-media-variables": "2.0.1", "postcss-media-variables": "2.0.1",
"postcss-nesting": "8.0.1", "postcss-nesting": "8.0.1",
"pug": "3.0.2", "pug": "3.0.2",
"rss-parser": "3.12.0",
"sync-request": "6.1.0" "sync-request": "6.1.0"
}, },
"engines": { "engines": {
@@ -1344,6 +1347,22 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/fast-xml-parser": {
"version": "3.20.0",
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.20.0.tgz",
"integrity": "sha512-cMQwDJYVDjMPU56DviszewgMKuNzuf4NQSBuDf9RgZ6FKm5QEMxW05Za8lvnuL6moxoeZVUWBlL733WmovvV6g==",
"dev": true,
"dependencies": {
"strnum": "^1.0.3"
},
"bin": {
"xml2js": "cli.js"
},
"funding": {
"type": "paypal",
"url": "https://paypal.me/naturalintelligence"
}
},
"node_modules/fastq": { "node_modules/fastq": {
"version": "1.11.0", "version": "1.11.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz",
@@ -1658,12 +1677,27 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"dev": true,
"bin": {
"he": "bin/he"
}
},
"node_modules/hosted-git-info": { "node_modules/hosted-git-info": {
"version": "2.8.9", "version": "2.8.9",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
"dev": true "dev": true
}, },
"node_modules/html-entities": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.2.tgz",
"integrity": "sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==",
"dev": true
},
"node_modules/http-basic": { "node_modules/http-basic": {
"version": "8.1.3", "version": "8.1.3",
"resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz",
@@ -2118,6 +2152,12 @@
"graceful-fs": "^4.1.6" "graceful-fs": "^4.1.6"
} }
}, },
"node_modules/jstoxmlparser": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/jstoxmlparser/-/jstoxmlparser-1.0.2.tgz",
"integrity": "sha512-EVy/kaRwz9kgIR3WwG3lzqP2uQgCZwd1s1f2axVgwydy7qYn+VNuCdiOIa8b7Kg1F2cM5OpYmPJ42QBmTMgUQw==",
"dev": true
},
"node_modules/jstransformer": { "node_modules/jstransformer": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz",
@@ -3932,16 +3972,6 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/rss-parser": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/rss-parser/-/rss-parser-3.12.0.tgz",
"integrity": "sha512-aqD3E8iavcCdkhVxNDIdg1nkBI17jgqF+9OqPS1orwNaOgySdpvq6B+DoONLhzjzwV8mWg37sb60e4bmLK117A==",
"dev": true,
"dependencies": {
"entities": "^2.0.3",
"xml2js": "^0.4.19"
}
},
"node_modules/run-parallel": { "node_modules/run-parallel": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -3981,12 +4011,6 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"dev": true "dev": true
}, },
"node_modules/sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
"dev": true
},
"node_modules/semver": { "node_modules/semver": {
"version": "5.7.1", "version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
@@ -4500,6 +4524,12 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/strnum": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.3.tgz",
"integrity": "sha512-GVoRjsqAYZkAH16GDzfTuafuwKxzKdaaCQyLaWf37gOP1e2PPbAKWoME1OmO+c4RCKMfNrrPRDLFCNBFU45N/A==",
"dev": true
},
"node_modules/supports-color": { "node_modules/supports-color": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
@@ -4904,28 +4934,6 @@
} }
} }
}, },
"node_modules/xml2js": {
"version": "0.4.23",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
"integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
"dev": true,
"dependencies": {
"sax": ">=0.6.0",
"xmlbuilder": "~11.0.0"
},
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/xmlbuilder": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
"dev": true,
"engines": {
"node": ">=4.0"
}
},
"node_modules/xmlhttprequest-ssl": { "node_modules/xmlhttprequest-ssl": {
"version": "1.6.2", "version": "1.6.2",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.2.tgz", "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.2.tgz",
@@ -6073,6 +6081,15 @@
"picomatch": "^2.2.1" "picomatch": "^2.2.1"
} }
}, },
"fast-xml-parser": {
"version": "3.20.0",
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.20.0.tgz",
"integrity": "sha512-cMQwDJYVDjMPU56DviszewgMKuNzuf4NQSBuDf9RgZ6FKm5QEMxW05Za8lvnuL6moxoeZVUWBlL733WmovvV6g==",
"dev": true,
"requires": {
"strnum": "^1.0.3"
}
},
"fastq": { "fastq": {
"version": "1.11.0", "version": "1.11.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz",
@@ -6320,12 +6337,24 @@
"type-fest": "^0.8.0" "type-fest": "^0.8.0"
} }
}, },
"he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"dev": true
},
"hosted-git-info": { "hosted-git-info": {
"version": "2.8.9", "version": "2.8.9",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
"dev": true "dev": true
}, },
"html-entities": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.2.tgz",
"integrity": "sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==",
"dev": true
},
"http-basic": { "http-basic": {
"version": "8.1.3", "version": "8.1.3",
"resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz",
@@ -6694,6 +6723,12 @@
"graceful-fs": "^4.1.6" "graceful-fs": "^4.1.6"
} }
}, },
"jstoxmlparser": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/jstoxmlparser/-/jstoxmlparser-1.0.2.tgz",
"integrity": "sha512-EVy/kaRwz9kgIR3WwG3lzqP2uQgCZwd1s1f2axVgwydy7qYn+VNuCdiOIa8b7Kg1F2cM5OpYmPJ42QBmTMgUQw==",
"dev": true
},
"jstransformer": { "jstransformer": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz",
@@ -8172,16 +8207,6 @@
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
"dev": true "dev": true
}, },
"rss-parser": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/rss-parser/-/rss-parser-3.12.0.tgz",
"integrity": "sha512-aqD3E8iavcCdkhVxNDIdg1nkBI17jgqF+9OqPS1orwNaOgySdpvq6B+DoONLhzjzwV8mWg37sb60e4bmLK117A==",
"dev": true,
"requires": {
"entities": "^2.0.3",
"xml2js": "^0.4.19"
}
},
"run-parallel": { "run-parallel": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -8218,12 +8243,6 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"dev": true "dev": true
}, },
"sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
"dev": true
},
"semver": { "semver": {
"version": "5.7.1", "version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
@@ -8677,6 +8696,12 @@
"min-indent": "^1.0.0" "min-indent": "^1.0.0"
} }
}, },
"strnum": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.3.tgz",
"integrity": "sha512-GVoRjsqAYZkAH16GDzfTuafuwKxzKdaaCQyLaWf37gOP1e2PPbAKWoME1OmO+c4RCKMfNrrPRDLFCNBFU45N/A==",
"dev": true
},
"supports-color": { "supports-color": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
@@ -9002,22 +9027,6 @@
"dev": true, "dev": true,
"requires": {} "requires": {}
}, },
"xml2js": {
"version": "0.4.23",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
"integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
"dev": true,
"requires": {
"sax": ">=0.6.0",
"xmlbuilder": "~11.0.0"
}
},
"xmlbuilder": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
"dev": true
},
"xmlhttprequest-ssl": { "xmlhttprequest-ssl": {
"version": "1.6.2", "version": "1.6.2",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.2.tgz", "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.2.tgz",

View File

@@ -35,7 +35,11 @@
"autoprefixer": "10.3.4", "autoprefixer": "10.3.4",
"browser-sync": "2.27.5", "browser-sync": "2.27.5",
"csso-cli": "3.0.0", "csso-cli": "3.0.0",
"fast-xml-parser": "3.20.0",
"glob": "7.1.7", "glob": "7.1.7",
"he": "1.2.0",
"html-entities": "2.3.2",
"jstoxmlparser": "1.0.2",
"jstransformer-markdown-it": "2.1.0", "jstransformer-markdown-it": "2.1.0",
"markdown-it": "12.2.0", "markdown-it": "12.2.0",
"node-file-rev": "1.1.3", "node-file-rev": "1.1.3",
@@ -49,7 +53,6 @@
"postcss-media-variables": "2.0.1", "postcss-media-variables": "2.0.1",
"postcss-nesting": "8.0.1", "postcss-nesting": "8.0.1",
"pug": "3.0.2", "pug": "3.0.2",
"rss-parser": "3.12.0",
"sync-request": "6.1.0" "sync-request": "6.1.0"
} }
} }

View File

@@ -2,7 +2,7 @@ extends /template.pug
block vars block vars
- const title = episode.title - const title = episode.title
- const description = episode.contentSnippet - const description = episode.description
- const cardImage = episode.image - const cardImage = episode.image
- const cardSize = episode.image.match('cloudfront') ? 3000 : 1400 - const cardSize = episode.image.match('cloudfront') ? 3000 : 1400

View File

@@ -1,86 +1,109 @@
const { writeFileSync } = require('fs') const { writeFileSync } = require('fs')
const { join, resolve } = require('path') const { join, resolve } = require('path')
const { replacements, slugify } = require('../helpers') const { replacements, slugify, stripHTML } = require('../helpers')
const { masterFeedUrl, publicFeedUrl } = require('../content/meta.json') const { masterFeedUrl, publicFeedUrl } = require('../content/meta.json')
const request = require('sync-request') const request = require('sync-request')
const Parser = require('rss-parser') const parser = require('fast-xml-parser')
const JSON2XMLParser = require("fast-xml-parser").j2xParser;
const he = require('he')
const dir = resolve(__dirname, '..') const dir = resolve(__dirname, '..')
const write = (name, data) => writeFileSync(join(dir, name), data) const write = (name, data) => writeFileSync(join(dir, name), data)
const writeJSON = (name, data) => write(`generated/${name}.json`, JSON.stringify(data, null, 2)) const writeJSON = (name, data) => write(`generated/${name}.json`, JSON.stringify(data, null, 2))
const parseBaseInfoFromMatch = m => { const commonOpts = {
let [, categoryName = 'News', number, titlePlain] = m ? m : [,,,] attributeNamePrefix: "",
if (!number) categoryName = 'Verschiedenes' attrNodeName: "__attr",
if (categoryName === 'Der-Weg') categoryName = 'Der Weg' textNodeName: "#text",
return { categoryName, number, titlePlain } ignoreAttributes: false,
cdataTagName: "__cdata",
cdataPositionChar: "\\c"
} }
const parseInfo = e => { const xml2jsonOpts = {
const titleMatch = e.title.match(/([\w\s]+?)?\s?#(\d+) - (.*)/) || [,,,e.title] ...commonOpts,
const { categoryName, number, titlePlain } = parseBaseInfoFromMatch(titleMatch) ignoreNameSpace: false,
const blockMatch = e.contentSnippet.match(/Blockzeit\s(\d+)/) parseNodeValue: true,
parseAttributeValue: false,
trimValues: true,
parseTrueNumberOnly: false,
arrayMode: false,
numParseOptions: {
hex: true,
leadingZeros: true,
},
tagValueProcessor: val => he.decode(val),
attrValueProcessor: val => he.decode(val, { isAttributeValue: true })
}
var json2xmlOpts = {
...commonOpts,
format: false,
indentBy: " ",
supressEmptyNode: false,
tagValueProcessor: a => a,
attrValueProcessor: a => he.encode(a, { isAttributeValue: true, useNamedReferences: true })
};
const parseEpisode = e => {
const guid = e.guid['#text']
const title = e.title.__cdata.trim()
const content = replacements(e.description.__cdata).trim()
const description = stripHTML(content)
let [, categoryName = 'News', number, titlePlain] = title.match(/([\w\s]+?)?\s?#(\d+) - (.*)/) || [, , , title]
if (!number) categoryName = 'Verschiedenes'
if (categoryName === 'Der-Weg') categoryName = 'Der Weg'
const firstLine = description.split('\n')[0]
const blockMatch = firstLine.match(/Blockzeit\s(\d+)/)
const block = blockMatch ? parseInt(blockMatch[1]) : null const block = blockMatch ? parseInt(blockMatch[1]) : null
const category = slugify(categoryName) const category = slugify(categoryName)
const slug = slugify(`${categoryName} ${number || ''} ${titlePlain}`) const slug = slugify(`${categoryName} ${number || ''} ${titlePlain}`)
return { block, category, categoryName, number, titlePlain, slug } const date = new Date(e.pubDate)
const img = e['itunes:image'].__attr.href
const image = ['interview', 'lesestunde', 'verschiedenes'].includes(category) ? img : `/img/cover/${category}.png`
const duration = e['itunes:duration']
const enclosure = e.enclosure.__attr
const [, participantsString] = firstLine.match(/ - (?:(?:von und )?mit )(.*)/i) || []
const participants = participantsString ? participantsString.replace(/(\s*,\s*|\s*und\s*)/ig, '%').split('%') : []
return { block, category, categoryName, number, title, titlePlain, description, content, duration, slug, image, guid , date, enclosure, participants }
} }
;(async () => { ;(async () => {
// Load and adapt feed // Load and adapt feed
const xml = request('GET', masterFeedUrl).getBody('utf8') const anchorXML = request('GET', masterFeedUrl).getBody('utf8')
.replace(/<itunes:email>(.*?)<\/itunes:email>/g, '<itunes:email>einundzwanzigpodcast@pm.me</itunes:email>') const xml = anchorXML
.replace(`"${masterFeedUrl}"`, `"${publicFeedUrl}"`) .replace(`"${masterFeedUrl}"`, `"${publicFeedUrl}"`)
.replace('xmlns:anchor="https://anchor.fm/xmlns"', 'xmlns:anchor="https://anchor.fm/xmlns" xmlns:podcast="https://podcastindex.org/namespace/1.0"')
.replace('<channel>', `<channel>
<podcast:value type="lightning" method="keysend">
<podcast:valueRecipient name="Dennis" type="node" address="0231f73aef9bbdbf69e840640255946264026b56e17701f2d410b08b8b6e5d637a" split="1" />
<podcast:valueRecipient name="Fab" type="node" address="03f14237bb08f0afcb1ea07eff6b0b41e79294e66888971cccf1f585f5e21bf8f9" split="1" />
<podcast:valueRecipient name="Gigi" type="node" address="02e12fea95f576a680ec1938b7ed98ef0855eadeced493566877d404e404bfbf52" split="1" />
<podcast:valueRecipient name="Markus" type="node" address="0286e50ebeaafdf7dc321f6c8cb7e964e236b03ed67494b6337215c5c3c42252f2" split="1" />
<podcast:valueRecipient name="Daniel" type="node" address="0201d14101401add234ebe3bc0e3020a39726daadf82bc3fa6b9871c4f5b17ab3f" split="1" />
</podcast:value>`)
// Parse feed const feed = parser.parse(xml, xml2jsonOpts, true)
const parser = new Parser() const episodes = []
const feed = await parser.parseString(xml)
// Original Anchor-Feed delete feed.rss.channel.author // remove invalid tag
write('dist/feed.xml', xml)
writeJSON('feed', feed)
// All episodes feed.rss.channel.item = feed.rss.channel.item.map(item => {
const episodes = feed.items.map(e => { const episode = parseEpisode(item)
const info = parseInfo(e) episodes.push(episode)
const image = ['interview', 'lesestunde', 'verschiedenes'].includes(info.category) ? e.itunes.image : `/img/cover/${info.category}.png`
return { return {
title: e.title.trim(), ...item,
content: replacements(e.content.trim()), link: `https://einundzwanzig.space/podcast/${episode.slug}`, // replace Anchor link
contentSnippet: replacements(e.contentSnippet.trim()), 'itunes:summary': episode.description // please the validator, Anchor's itunes:summary contains HTML
anchor: e.link,
date: e.isoDate,
enclosure: e.enclosure,
duration: e.itunes.duration,
season: e.itunes.season,
episode: e.itunes.episode,
guid: e.guid,
image,
originalImage: e.itunes.image,
...info
} }
}) })
writeJSON('episodes', episodes) writeJSON('feed', feed)
// Original Anchor-Feed const JSON2XML = new JSON2XMLParser(json2xmlOpts)
const updated = xml const outputXML = JSON2XML.parse(feed)
.replace(/<link>(https:\/\/anchor\.fm\/einundzwanzig\/episodes\/(.*?))<\/link>/gi, (match, url, anchorSlug) => {
const slugMatch = anchorSlug.match(/^(?:(.*)-)?([0-9]+?)---/) writeJSON('episodes', episodes)
const { categoryName, number } = parseBaseInfoFromMatch(slugMatch) write('dist/feed.xml', outputXML)
const episode = slugMatch ? episodes.find(e => e.categoryName == categoryName && e.number === number) : null write('dist/anchor.xml', anchorXML)
const link = episode ? `https://einundzwanzig.space/podcast/${episode.slug}` : url
return `<link>${link}</link>`
})
.replace('xmlns:anchor="https://anchor.fm/xmlns"', 'xmlns:anchor="https://anchor.fm/xmlns" xmlns:podcast="https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md"')
.replace('<channel>', `<channel>
<podcast:value type="lightning" method="keysend" suggested="0.00000005000">
<podcast:valueRecipient name="Dennis (Podcaster)" type="node" address="0231f73aef9bbdbf69e840640255946264026b56e17701f2d410b08b8b6e5d637a" split="19" />
<podcast:valueRecipient name="Fab (Podcaster)" type="node" address="03f14237bb08f0afcb1ea07eff6b0b41e79294e66888971cccf1f585f5e21bf8f9" split="19" />
<podcast:valueRecipient name="Gigi (Podcaster)" type="node" address="02e12fea95f576a680ec1938b7ed98ef0855eadeced493566877d404e404bfbf52" split="19" />
<podcast:valueRecipient name="Markus (Podcaster)" type="node" address="0286e50ebeaafdf7dc321f6c8cb7e964e236b03ed67494b6337215c5c3c42252f2" split="19" />
<podcast:valueRecipient name="Daniel (Podcaster)" type="node" address="0201d14101401add234ebe3bc0e3020a39726daadf82bc3fa6b9871c4f5b17ab3f" split="19" />
<podcast:valueRecipient name="Podcastindex.org (Donation)" type="node" address="03ae9f91a0cb8ff43840e3c322c4c61f019d8c1c3cea15a25cfc425ac605e61a4a" split="5" />
</podcast:value>`)
write('dist/feed.xml', updated)
})() })()