import fs from 'fs' ; import { Feed } from 'feed' ; import path from 'path' ; import dayjs from 'dayjs' ; import { PostFrontMatter } from 'src/types' ; import { useURL } from 'src/hooks/useURL' ; import { GroupedReadingList } from 'src/components/readingList/defs' ; import { useUTMLink } from 'src/hooks/useUTMLink' ; import { filterArticles , renderReadingListDescription } from 'src/components/readingList/utils' ; export async function generateBlogPostsFeeds ( posts ) { const feed = new Feed ( { title : 'Articles by François Best' , description : 'I write about TypeScript, Node.js, React, security and privacy.' , id : useURL ( '/posts' ) , link : useURL ( '/posts' ) , language : 'en' , image : useURL ( '/favicons/apple-icon-120x120.png' ) , favicon : useURL ( '/favicon.ico' ) , copyright : 'All rights reserved 2020, François Best' , feedLinks : { json : useURL ( '/posts/feed/articles.json' ) , atom : useURL ( '/posts/feed/atom.xml' ) , rss : useURL ( '/posts/feed/rss.xml' ) } , author : { name : 'Francois Best' , email : 'contact@francoisbest.com' , link : useURL ( ) } } ) ; new Set ( posts . filter ( post => ! ! post . publicationDate ) . flatMap ( post => post . tags || [ ] ) ) . forEach ( tag => { feed . addCategory ( tag ) ; } ) ; posts . filter ( post => ! ! post . publicationDate ) . forEach ( post => { const postUrl = new URL ( post . url ) ; postUrl . searchParams . set ( 'utm_source' , 'rss' ) ; feed . addItem ( { title : post . title , id : post . url , link : postUrl . toString ( ) , image : post . ogImage ?. url , category : post . tags ?. map ( tag => ( { name : tag , term : tag } ) ) , description : post . description , content : `${ post . description }
<a href="${ postUrl . toString ( ) }">Full article</a>.` , author : [ { name : 'Francois Best' , email : 'contact@francoisbest.com' , link : useURL ( ) } ] , date : new Date ( post . publicationDate ! ) } ) ; } ) ; const writeFeedFile = ( name , contents ) => { const filePath = path . resolve ( process . cwd ( ) , 'public/posts/feed' , name ) ; fs . writeFileSync ( filePath , contents ) ; } ; writeFeedFile ( 'articles.json' , feed . json1 ( ) ) ; writeFeedFile ( 'atom.xml' , feed . atom1 ( ) ) ; writeFeedFile ( 'rss.xml' , feed . rss2 ( ) ) ; } export async function generateReadingListDailyFeed ( articles ) { const feed = new Feed ( { title : "François Best's Reading List" , description : "All the blog posts I've read in 2021" , id : useURL ( '/reading-list' ) , link : useURL ( '/reading-list' ) , language : 'en' , image : useURL ( '/images/reading-list/og.jpg' ) , favicon : useURL ( '/favicon.ico' ) , copyright : 'All rights reserved 2020, François Best' , feedLinks : { json : useURL ( '/feeds/reading-list/daily/feed.json' ) , atom : useURL ( '/feeds/reading-list/daily/atom.xml' ) , rss : useURL ( '/feeds/reading-list/daily/rss.xml' ) } , author : { name : 'Francois Best' , email : 'contact@francoisbest.com' , link : useURL ( ) } } ) ; const until = dayjs ( ) . startOf ( 'day' ) . valueOf ( ) ; const from = dayjs ( until ) . subtract ( 5 , 'day' ) . valueOf ( ) ; const last5DaysArticles = filterArticles ( articles , article => article . timestamp >= from && article . timestamp < until ) ; Object . entries ( last5DaysArticles ) . forEach ( ( [ day , articles ] ) => { const isoDate = dayjs ( day ) . format ( 'YYYY-MM-DD' ) ; const pageURL = useUTMLink ( useURL ( `/reading-list/archives/${ isoDate }` ) , { source : 'rss' } ) ; const description = `My reading list for ${ day }: ${ renderReadingListDescription ( articles ) }` ; feed . addItem ( { title : '' , id : pageURL , link : pageURL , image : useURL ( '/images/reading-list/og.jpg' ) , description , content : `${ description }
<a href="${ pageURL }">Full list</a>.` , author : [ { name : 'Francois Best' , email : 'contact@francoisbest.com' , link : useURL ( ) } ] , date : new Date ( isoDate ) } ) ; } ) ; const writeFeedFile = ( name , contents ) => { const filePath = path . resolve ( process . cwd ( ) , 'public/feeds/reading-list/daily' , name ) ; fs . writeFileSync ( filePath , contents ) ; } ; writeFeedFile ( 'feed.json' , feed . json1 ( ) ) ; writeFeedFile ( 'atom.xml' , feed . atom1 ( ) ) ; writeFeedFile ( 'rss.xml' , feed . rss2 ( ) ) ; }