2018-04-09 22:26:30 +00:00
'use strict' ;
const config = require ( 'config' ) ;
2018-06-16 23:11:10 +00:00
const Snoowrap = require ( 'snoowrap' ) ;
2018-07-01 22:25:48 +00:00
const fs = require ( 'fs-extra' ) ;
2018-07-02 01:45:20 +00:00
const Promise = require ( 'bluebird' ) ;
2018-06-12 23:51:45 +00:00
const exiftool = require ( 'node-exiftool' ) ;
const exiftoolBin = require ( 'dist-exiftool' ) ;
2018-07-01 21:16:03 +00:00
const cron = require ( 'node-cron' ) ;
2018-07-01 01:38:29 +00:00
const { format } = require ( 'date-fns' ) ;
2018-05-04 22:51:58 +00:00
require ( 'array.prototype.flatten' ) . shim ( ) ;
2018-04-22 21:46:14 +00:00
2018-06-16 23:11:10 +00:00
const reddit = new Snoowrap ( config . reddit . api ) ;
const args = require ( './cli.js' ) ( ) ;
2018-04-22 23:50:07 +00:00
2019-11-01 03:22:36 +00:00
const dissectLink = require ( './dissectLink.js' ) ;
2018-04-29 00:02:34 +00:00
const curatePosts = require ( './curate/posts.js' ) ;
2018-04-22 23:50:07 +00:00
2019-11-01 03:22:36 +00:00
const { attachContentInfo , getInfo } = require ( './fetch/info.js' ) ;
const { fetchSaveUserContent , fetchSaveDirectContent } = require ( './fetch/content.js' ) ;
2018-04-22 21:46:14 +00:00
2018-05-05 00:27:15 +00:00
const getPosts = require ( './sources/getPosts.js' ) ( reddit , args ) ;
const getUserPosts = require ( './sources/getUserPosts.js' ) ( reddit , args ) ;
2018-04-18 02:04:39 +00:00
2018-07-01 22:25:48 +00:00
async function getFileContents ( location , label ) {
try {
const fileContents = await fs . readFile ( location , 'utf8' ) ;
return fileContents . split ( '\n' ) . filter ( entry => entry ) ;
} catch ( error ) {
console . log ( '\x1b[31m%s\x1b[0m' , ` Could not read ${ label } file ' ${ location } ': ${ error } . ` ) ;
return [ ] ;
}
}
2019-11-01 03:22:36 +00:00
async function getCompletePosts ( ) {
2018-06-30 23:07:32 +00:00
let userPosts = { } ;
2018-07-02 00:33:34 +00:00
let ignoreIds = [ ] ;
2018-07-01 22:25:48 +00:00
let usernames = args . users || [ ] ;
let postIds = args . posts || [ ] ;
if ( args . fileUsers ) {
usernames = usernames . concat ( await getFileContents ( args . fileUsers , 'username' ) ) ;
}
if ( args . filePosts ) {
postIds = postIds . concat ( await getFileContents ( args . filePosts , 'post ID' ) ) ;
}
if ( ! usernames . length && ! postIds . length ) {
2019-11-02 01:19:23 +00:00
return null ;
2018-07-01 22:25:48 +00:00
}
2018-06-30 23:07:32 +00:00
2018-07-01 22:25:48 +00:00
if ( usernames . length ) {
userPosts = await getUserPosts ( usernames ) ;
2018-06-30 23:07:32 +00:00
}
2018-06-16 23:11:10 +00:00
2018-07-01 22:25:48 +00:00
if ( postIds . length ) {
userPosts = await getPosts ( postIds , userPosts ) ;
2018-06-16 23:11:10 +00:00
}
2018-07-02 00:33:34 +00:00
if ( args . fileIgnore ) {
ignoreIds = await getFileContents ( args . fileIgnore , 'ignore' ) ;
}
const curatedUserPosts = curatePosts ( userPosts , ignoreIds , args ) ;
2018-06-16 23:11:10 +00:00
return attachContentInfo ( curatedUserPosts ) ;
2018-04-22 21:46:14 +00:00
}
2019-11-01 04:55:55 +00:00
async function getDirectContent ( links , ep ) {
return Promise . map ( links , async ( link ) => {
const host = dissectLink ( link ) ;
const info = await getInfo ( host ) ;
return fetchSaveDirectContent ( info , host , ep ) ;
} , {
concurrency : 5 ,
} ) ;
}
2019-11-01 03:22:36 +00:00
2019-11-01 04:55:55 +00:00
async function getCompleteContents ( ep ) {
if ( args . fetch ) {
return getDirectContent ( [ args . fetch ] , ep ) ;
}
2019-11-01 03:22:36 +00:00
2019-11-01 04:55:55 +00:00
if ( args . fileDirect ) {
return getDirectContent ( await getFileContents ( args . fileDirect , 'direct' ) , ep ) ;
}
2019-11-01 03:22:36 +00:00
2019-11-01 04:55:55 +00:00
return null ;
2019-11-01 03:22:36 +00:00
}
2018-06-16 23:11:10 +00:00
function fetchSavePosts ( userPosts , ep ) {
2018-07-02 01:45:20 +00:00
// don't map to apply concurrency limit and reduce network stress
2019-11-01 03:22:36 +00:00
return Promise . reduce ( Object . values ( userPosts ) , ( acc , user ) => fetchSaveUserContent ( user , ep , args ) , null ) ;
2018-06-16 23:11:10 +00:00
}
2018-06-12 23:51:45 +00:00
2018-06-16 23:11:10 +00:00
async function initApp ( ) {
try {
const ep = new exiftool . ExiftoolProcess ( exiftoolBin ) ;
2019-11-01 04:55:55 +00:00
await ep . open ( ) ;
2018-06-16 23:11:10 +00:00
2019-11-01 04:55:55 +00:00
if ( args . fetch || args . fileDirect ) {
await getCompleteContents ( ep ) ;
2019-11-01 03:22:36 +00:00
}
const userPosts = await getCompletePosts ( ) ;
2019-11-02 01:19:23 +00:00
if ( userPosts ) {
await fetchSavePosts ( userPosts , ep ) ;
}
2018-06-17 01:39:12 +00:00
await ep . close ( ) ;
2018-07-01 01:06:57 +00:00
if ( args . watch ) {
2018-07-01 21:16:03 +00:00
console . log ( ` [ ${ format ( new Date ( ) , 'YYYY-MM-DD HH:mm:ss' ) } ] Watch-mode enabled, checking again for new posts according to crontab ' ${ config . fetch . watch . schedule } '. ` ) ;
2018-07-01 01:06:57 +00:00
}
2018-06-16 23:11:10 +00:00
} catch ( error ) {
2018-07-05 21:27:11 +00:00
if ( args . debug ) {
console . log ( '\x1b[31m%s\x1b[0m' , error . stack ) ;
} else {
console . log ( '\x1b[31m%s\x1b[0m' , error . message ) ;
}
2018-06-16 23:11:10 +00:00
}
}
initApp ( ) ;
2018-07-01 21:16:03 +00:00
if ( args . watch ) {
cron . schedule ( config . fetch . watch . schedule , initApp ) ;
}