|
| 1 | +/* |
| 2 | + * Copyright 2024 Adobe. All rights reserved. |
| 3 | + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); |
| 4 | + * you may not use this file except in compliance with the License. You may obtain a copy |
| 5 | + * of the License at http://www.apache.org/licenses/LICENSE-2.0 |
| 6 | + * |
| 7 | + * Unless required by applicable law or agreed to in writing, software distributed under |
| 8 | + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS |
| 9 | + * OF ANY KIND, either express or implied. See the License for the specific language |
| 10 | + * governing permissions and limitations under the License. |
| 11 | + */ |
| 12 | + |
| 13 | +import glob from 'glob'; |
| 14 | +import fs from 'fs'; |
| 15 | +import xml from "xml"; |
| 16 | +import process from 'process'; |
| 17 | +import {parseArgs} from 'node:util'; |
| 18 | + |
| 19 | +let options = { |
| 20 | + releases: { |
| 21 | + type: 'string' |
| 22 | + }, |
| 23 | + blog: { |
| 24 | + type: 'string' |
| 25 | + } |
| 26 | +}; |
| 27 | + |
| 28 | +(async function createRssFeed() { |
| 29 | + |
| 30 | + let args = parseArgs({options, allowPositionals: true}); |
| 31 | + |
| 32 | + if (args.positionals.length < 1) { |
| 33 | + console.error('Expected at least one argument'); |
| 34 | + process.exit(1); |
| 35 | + } |
| 36 | + |
| 37 | + let type = args.positionals[0]; |
| 38 | + if (type !== 'releases' && type !== 'blog') { |
| 39 | + console.error('Expected argument to be either releases or blog'); |
| 40 | + process.exit(1); |
| 41 | + } |
| 42 | + |
| 43 | + let titleType = type === 'releases' ? 'Releases' : 'Blog' |
| 44 | + let posts = getFeed(type); |
| 45 | + const feedObject = { |
| 46 | + rss: [ |
| 47 | + {_attr: { |
| 48 | + version: "2.0", |
| 49 | + "xmlns:atom": "http://www.w3.org/2005/Atom", |
| 50 | + }, |
| 51 | + }, |
| 52 | + {channel: [ |
| 53 | + {"atom:link": { |
| 54 | + _attr: { |
| 55 | + href: `https://react-spectrum.adobe.com/${type}/${type}-feed.rss`, |
| 56 | + rel: "self", |
| 57 | + type: "application/rss+xml", |
| 58 | + }, |
| 59 | + }, |
| 60 | + }, |
| 61 | + {title: `Adobe React Spectrum ${titleType}`}, |
| 62 | + {link: `https://react-spectrum.adobe.com/${type}`}, |
| 63 | + {description: "A collection of libraries and tools that help you build adaptive, accessible, and robust user experiences."}, |
| 64 | + {language: "en-US"}, |
| 65 | + ...buildFeed(type, posts) |
| 66 | + ], |
| 67 | + }, |
| 68 | + ], |
| 69 | + }; |
| 70 | + |
| 71 | + const feed = xml(feedObject, {declaration: true}); |
| 72 | + await fs.writeFile(`scripts/${type}-feed.rss`, feed, (err) => console.log(err === null ? 'Success' : err)); |
| 73 | +})(); |
| 74 | + |
| 75 | +function getFeed(type) { |
| 76 | + let files = glob.sync(`packages/dev/docs/pages/${type}/*.mdx`, {ignore: [`packages/dev/docs/pages/${type}/index.mdx`]}); |
| 77 | + let posts = []; |
| 78 | + |
| 79 | + for (let file of files) { |
| 80 | + let contents = fs.readFileSync(file, 'utf8').split("\n"); |
| 81 | + |
| 82 | + let date = ''; |
| 83 | + let description = ''; |
| 84 | + let title = ''; |
| 85 | + let index = 0; |
| 86 | + while (date === '' || description === '' || title === '' && index < contents.length) { |
| 87 | + if (contents[index].startsWith('description')) { |
| 88 | + description = contents[index].replace('description:', '').trim(); |
| 89 | + } else if (contents[index].startsWith('date:')) { |
| 90 | + date = contents[index].replace('date:', '').trim(); |
| 91 | + } else if (contents[index].startsWith('#')) { |
| 92 | + title = contents[index].replace('#', '').trim(); |
| 93 | + } |
| 94 | + index++; |
| 95 | + } |
| 96 | + |
| 97 | + let f = file.split('/'); |
| 98 | + let fileName = f[f.length - 1].replace('.mdx', ''); |
| 99 | + |
| 100 | + let post = {date: date, description: description, title: title, fileName: fileName}; |
| 101 | + posts.push(post); |
| 102 | + } |
| 103 | + |
| 104 | + posts = posts.sort((a, b) => a.date < b.date ? 1 : -1).slice(0, 5); |
| 105 | + return posts; |
| 106 | +} |
| 107 | + |
| 108 | +function buildFeed(type, posts) { |
| 109 | + const feedItems = []; |
| 110 | + |
| 111 | + feedItems.push( |
| 112 | + ...posts.map(function (post) { |
| 113 | + const feedItem = { |
| 114 | + item: [ |
| 115 | + {title: post.title}, |
| 116 | + {pubDate: new Date(post.date).toUTCString(),}, |
| 117 | + {guid: [ |
| 118 | + { _attr: { isPermaLink: true } }, |
| 119 | + `https://react-spectrum.adobe.com/${type}/${post.fileName}.html`, |
| 120 | + ], |
| 121 | + }, |
| 122 | + {description: { |
| 123 | + _cdata: post.description, |
| 124 | + }, |
| 125 | + }, |
| 126 | + ], |
| 127 | + }; |
| 128 | + return feedItem; |
| 129 | + }) |
| 130 | + ); |
| 131 | + |
| 132 | + return feedItems; |
| 133 | +} |
| 134 | + |
0 commit comments