2018-04-09 22:26:30 +00:00
'use strict' ;
const config = require ( 'config' ) ;
2018-04-15 01:55:10 +00:00
const util = require ( 'util' ) ;
2018-04-22 21:46:14 +00:00
const fs = require ( 'fs-extra' ) ;
2018-04-09 22:26:30 +00:00
const snoowrap = require ( 'snoowrap' ) ;
2018-05-04 22:51:58 +00:00
require ( 'promise.prototype.finally' ) . shim ( ) ;
require ( 'array.prototype.flatten' ) . shim ( ) ;
2018-04-22 21:46:14 +00:00
2018-04-22 23:50:07 +00:00
const reddit = new snoowrap ( config . reddit . api ) ;
2018-04-29 00:02:34 +00:00
const curatePosts = require ( './curate/posts.js' ) ;
2018-04-22 21:46:14 +00:00
const curateUser = require ( './curate/user.js' ) ;
2018-04-22 23:50:07 +00:00
2018-04-22 21:46:14 +00:00
const interpolate = require ( './interpolate.js' ) ;
2018-04-29 00:02:34 +00:00
const attachContentInfo = require ( './fetch/info.js' ) ;
2018-04-22 23:50:07 +00:00
const fetchContent = require ( './fetch/content.js' ) ;
2018-04-22 21:46:14 +00:00
2018-05-04 22:51:58 +00:00
const archives = require ( './archives/archives.js' ) ;
2018-04-22 23:50:07 +00:00
const save = require ( './save/save.js' ) ;
const saveProfileDetails = require ( './save/profileDetails.js' ) ;
2018-04-22 21:46:14 +00:00
2018-04-29 00:02:34 +00:00
const args = require ( './cli.js' ) ;
2018-04-18 02:04:39 +00:00
2018-04-29 00:02:34 +00:00
if ( ! ( args . users && args . users . length ) && ! ( args . posts && args . posts . length ) ) {
return console . log ( '\x1b[31m%s\x1b[0m' , 'Please supply at least one user with --user <user> or one post with --post <post-id>. See --help for more options.' ) ;
2018-04-22 21:46:14 +00:00
}
2018-04-29 00:02:34 +00:00
Promise . resolve ( ) . then ( ( ) => {
if ( args . users ) {
return getUserPosts ( args . users ) ;
}
2018-05-04 22:51:58 +00:00
return [ ] ;
} ) . then ( userPosts => {
2018-04-29 00:02:34 +00:00
if ( args . posts ) {
return getPosts ( args . posts ) . then ( posts => posts . concat ( userPosts ) ) ;
}
return userPosts ;
} ) . then ( posts => {
2018-05-04 22:51:58 +00:00
return curatePosts ( posts , args . ignore ) . slice ( 0 , args . limit ) ;
2018-04-29 00:02:34 +00:00
} ) . then ( posts => {
2018-05-04 23:22:23 +00:00
return attachContentInfo ( posts ) ;
2018-05-04 22:51:58 +00:00
} ) . then ( posts => {
return fetchContent ( posts ) ;
2018-04-29 00:02:34 +00:00
} ) . catch ( error => {
return console . error ( error ) ;
2018-04-22 21:46:14 +00:00
} ) ;
2018-04-29 00:02:34 +00:00
2018-05-04 22:51:58 +00:00
function getUserPosts ( usernames ) {
return usernames . reduce ( ( chain , username ) => {
2018-04-29 00:02:34 +00:00
return chain . then ( accPosts => {
2018-05-04 22:51:58 +00:00
return reddit . getUser ( username ) . fetch ( ) . then ( curateUser ) . then ( saveProfileDetails ) . then ( user => ( {
user ,
accPosts
} ) ) ;
2018-04-29 00:02:34 +00:00
} ) . then ( ( { user , accPosts } ) => {
return reddit . getUser ( username ) . getSubmissions ( {
sort : args . sort ,
limit : Infinity
2018-05-04 22:51:58 +00:00
} ) . then ( posts => ( {
user ,
accPosts : accPosts . concat ( posts )
} ) ) ;
} ) . then ( ( { user , accPosts } ) => {
if ( args . archives || config . fetch . archives . search ) {
return getArchivePostIds ( username , accPosts . map ( post => post . id ) ) . then ( postIds => {
return Promise . all ( postIds . map ( postId => {
return reddit . getSubmission ( postId ) . fetch ( ) ;
} ) ) ;
} ) . then ( archivedPosts => {
return {
user ,
accPosts : accPosts . concat ( archivedPosts )
} ;
} ) ;
}
2018-04-29 00:02:34 +00:00
2018-05-04 22:51:58 +00:00
return { user , accPosts } ;
} ) . then ( ( { user , accPosts } ) => {
return accPosts . map ( post => Object . assign ( post , { user } ) ) ;
2018-04-29 00:02:34 +00:00
} ) ;
} , Promise . resolve ( [ ] ) ) ;
} ;
function getPosts ( postIds ) {
return postIds . reduce ( ( chain , postId ) => {
return chain . then ( acc => {
return reddit . getSubmission ( postId ) . fetch ( ) . then ( post => ( { post , acc } ) ) ;
} ) . then ( ( { post , acc } ) => {
if ( acc . users [ post . author . name ] ) {
return { post , acc , user : acc . users [ post . author . name ] }
}
2018-05-01 00:46:13 +00:00
if ( post . author . name === '[deleted]' ) {
return { post , acc , user : { name : '[deleted]' } } ;
}
2018-04-29 00:02:34 +00:00
return reddit . getUser ( post . author . name ) . fetch ( ) . then ( curateUser ) . then ( saveProfileDetails ) . then ( user => ( { post , acc , user } ) ) ;
} ) . then ( ( { post , acc , user } ) => {
post . user = user ;
acc . posts . push ( post ) ;
// keep track of users to prevent fetching one user multiple times
acc . users [ user . name ] = user ;
return acc ;
} ) ;
} , Promise . resolve ( {
posts : [ ] ,
users : { }
} ) ) . then ( ( { posts , users } ) => {
return posts ;
} ) ;
} ;
2018-05-04 22:51:58 +00:00
function getArchivePostIds ( username , exclude ) {
console . log ( 'Searching archives for posts...' ) ;
return Promise . all ( config . fetch . archives . reddit . map ( source => archives [ source ] ( username ) ) ) . then ( postIds => postIds . flatten ( ) ) . then ( postIds => {
return exclude ? postIds . filter ( postId => ! exclude . includes ( postId ) ) : postIds ;
} ) . then ( postIds => {
console . log ( ` Found ${ postIds . length } unique archived posts ` ) ;
return postIds ;
} ) ;
} ;