'use strict'; const Promise = require('bluebird'); const getIndex = require('./getIndex.js'); const getArchivePostIds = require('../archives/getArchivePostIds.js'); const curateUser = require('../curate/user.js'); const logger = require('../logger')(__filename); const limiter = require('../limiter').reddit; async function getUser(username, reddit) { try { const user = await limiter.schedule(async () => reddit.getUser(username).fetch()); logger.info(`Fetched user profile for '${username}' (https://reddit.com/user/${username})`); return curateUser(user); } catch (error) { logger.error(`Failed to fetch reddit user '${username}': ${error.message} (https://reddit.com/user/${username})`); return { name: username, fallback: true, }; } } async function getPosts(username, reddit, args) { try { const submissions = await limiter.schedule(async () => reddit .getUser(username) .getSubmissions({ sort: args.sort, limit: Infinity, })); logger.info(`Fetched ${submissions.length} submissions for '${username}' (https://reddit.com/user/${username})`); return submissions; } catch (error) { logger.warn(`Failed to fetch posts from reddit user '${username}': ${error.message} (https://reddit.com/user/${username})`); return []; } } async function getArchivedPosts(username, posts, reddit) { const postIds = await getArchivePostIds(username, posts.map(post => post.id)); return Promise.all(postIds.map(postId => limiter.schedule(async () => reddit.getSubmission(postId).fetch()))); } function getUserPostsWrap(reddit, args) { return async function getUserPosts(usernames) { try { const users = await Promise.map(usernames, async (username) => { try { const [user, posts] = await Promise.all([ getUser(username, reddit), getPosts(username, reddit, args), ]); const { profile, posts: indexed } = await getIndex(user); if (args.archives) { posts.push(...await getArchivedPosts(username, posts, reddit)); } if (posts.length) { return { ...user, posts, indexed: { profile, original: indexed, updated: [], }, }; } return null; } catch (error) { logger.error(`Failed to fetch posts from 'username': ${error.message}`); return null; } }, { concurrency: 10, }); return users.reduce( (userPosts, user) => (user ? { ...userPosts, [user.name]: user, } : userPosts ), {}, ); } catch (error) { logger.error(error); throw error; } }; } module.exports = getUserPostsWrap;