2020-01-14 14:38:33 +00:00
const constants = require ( "../../lib/constants" )
2020-04-22 11:59:45 +00:00
const { Feed } = require ( "feed" )
const { getFeedSetup } = require ( "../../lib/utils/feed" )
2020-02-02 14:53:37 +00:00
const { fetchUser , userRequestCache } = require ( "../../lib/collectors" )
2020-05-04 11:50:54 +00:00
const { render , getStaticURL } = require ( "pinski/plugins" )
2020-02-01 03:15:12 +00:00
const { pugCache } = require ( "../passthrough" )
2020-04-22 11:59:45 +00:00
const { compile } = require ( "pug" )
const rssAnnouncementTemplate = compile ( `
p ( style = "white-space: pre-line" ) # { message } # [ a ( href = link ) = link ]
` )
function respondWithFeed ( feed , kind , maxAge , available ) {
if ( kind === "rss" ) {
var data = {
2022-05-22 12:15:40 +00:00
contentType : "application/rss+xml; charset=utf-8" , // see https://stackoverflow.com/questions/595616/what-is-the-correct-mime-type-to-use-for-an-rss-feed,
2020-04-22 11:59:45 +00:00
content : feed . rss2 ( )
}
} else if ( kind === "atom" ) {
var data = {
2022-05-22 12:15:40 +00:00
contentType : "application/atom+xml; charset=utf-8" , // see https://en.wikipedia.org/wiki/Atom_(standard)#Including_in_HTML
2020-04-22 11:59:45 +00:00
content : feed . atom1 ( )
}
}
const headers = {
2021-12-06 05:20:15 +00:00
"Access-Control-Allow-Origin" : "*" ,
2020-04-22 11:59:45 +00:00
"Cache-Control" : ` public, max-age= ${ maxAge } `
}
if ( ! available ) headers [ "X-Bibliogram-Feed-Unavailable" ] = 1
return {
statusCode : 200 , // must return 200 even if announcement only, since readers might not display anything with a failed status code
contentType : data . contentType ,
headers ,
content : data . content
}
}
/ * *
* @ param { Feed } feed
* /
function addAnnouncementFeedItem ( feed ) {
feed . addItem ( {
title : constants . feeds . feed _message . title ,
description : rssAnnouncementTemplate ( {
message : constants . feeds . feed _message . message ,
link : constants . feeds . feed _message . link
} ) ,
link : constants . feeds . feed _message . link ,
id : constants . feeds . feed _message . id ,
published : new Date ( constants . feeds . feed _message . timestamp ) ,
date : new Date ( constants . feeds . feed _message . timestamp )
} )
}
2020-01-14 14:38:33 +00:00
module . exports = [
2020-04-22 11:59:45 +00:00
{
route : ` /u/( ${ constants . external . username _regex } )/(rss|atom) \\ .xml ` , methods : [ "GET" ] , code : ( { fill } ) => {
2020-02-18 00:39:20 +00:00
const kind = fill [ 1 ]
2020-04-22 11:59:45 +00:00
if ( constants . feeds . enabled ) {
2020-07-22 12:58:21 +00:00
return fetchUser ( fill [ 0 ] , constants . symbols . fetch _context . RSS ) . then ( async ( { user } ) => {
2020-04-22 11:59:45 +00:00
const feed = await user . timeline . fetchFeed ( )
if ( constants . feeds . feed _message . enabled ) {
addAnnouncementFeedItem ( feed )
2020-02-18 00:39:20 +00:00
}
2020-04-22 11:59:45 +00:00
return respondWithFeed ( feed , kind , userRequestCache . getTtl ( "user/" + user . data . username , 1000 ) , true )
} ) . catch ( error => {
if ( error === constants . symbols . NOT _FOUND || error === constants . symbols . ENDPOINT _OVERRIDDEN ) {
return render ( 404 , "pug/friendlyerror.pug" , {
statusCode : 404 ,
title : "Not found" ,
message : "This user doesn't exist." ,
withInstancesLink : false
2020-02-01 03:15:12 +00:00
} )
2021-03-04 09:26:52 +00:00
} else if ( error === constants . symbols . INSTAGRAM _DEMANDS _LOGIN || error === constants . symbols . RATE _LIMITED || error === constants . symbols . INSTAGRAM _BLOCK _TYPE _DECEMBER ) {
2020-04-22 11:59:45 +00:00
return {
statusCode : 503 ,
contentType : "text/html" ,
headers : {
"Cache-Control" : ` public, max-age= ${ userRequestCache . getTtl ( "user/" + fill [ 0 ] , 1000 ) } ` ,
"Retry-After" : userRequestCache . getTtl ( "user/" + fill [ 0 ] , 1000 )
} ,
2021-03-04 09:26:52 +00:00
content : pugCache . get ( "pug/blocked_december.pug" ) . web ( {
2020-06-11 16:09:28 +00:00
website _origin : constants . website _origin ,
2020-05-04 11:50:54 +00:00
getStaticURL
2020-04-22 11:59:45 +00:00
} )
}
} else if ( error === constants . symbols . extractor _results . AGE _RESTRICTED ) {
return render ( 403 , "pug/age_gated.pug" )
} else {
throw error
2020-02-01 03:15:12 +00:00
}
2020-04-22 11:59:45 +00:00
} )
} else {
if ( constants . feeds . feed _message . enabled ) {
const setup = getFeedSetup ( fill [ 0 ] , "" , undefined , new Date ( ) )
const feed = new Feed ( setup )
addAnnouncementFeedItem ( feed )
return Promise . resolve ( respondWithFeed ( feed , kind , constants . feeds . feed _disabled _max _age , false ) )
2020-02-01 03:15:12 +00:00
} else {
2020-04-22 11:59:45 +00:00
return Promise . resolve ( render ( 403 , "pug/friendlyerror.pug" , {
statusCode : 403 ,
title : "Feeds disabled" ,
message : "Feeds are disabled on this instance." ,
withInstancesLink : true
} ) )
2020-02-01 03:15:12 +00:00
}
2020-04-22 11:59:45 +00:00
}
2020-02-01 03:15:12 +00:00
}
2020-04-22 11:59:45 +00:00
}
2020-01-14 14:38:33 +00:00
]