{"size": 3924, "ext": "js", "max_stars_repo_path": "src/tools/rss-migration/historian.js", "max_stars_repo_name": "arkits/historian", "max_stars_repo_stars_event_min_datetime": "2020-12-09T17:55:47.000Z", "max_stars_repo_stars_event_max_datetime": "2021-05-21T17:35:28.000Z", "max_issues_repo_path": "src/tools/rss-migration/historian.js", "max_issues_repo_name": "arkits/historian", "max_issues_repo_issues_event_min_datetime": "2021-09-02T10:33:54.000Z", "max_issues_repo_issues_event_max_datetime": "2022-03-26T18:54:13.000Z", "max_forks_repo_path": "src/tools/rss-migration/historian.js", "max_forks_repo_name": "arkits/historian", "max_forks_repo_forks_event_min_datetime": "2021-05-21T17:35:30.000Z", "max_forks_repo_forks_event_max_datetime": "2021-05-21T17:35:30.000Z"}
{"max_stars_count": 2, "max_issues_count": 20, "max_forks_count": 1, "avg_line_length": 29.0666666667, "max_line_length": 112, "alphanum_fraction": 0.5731396534}
const config = require('config');
const axios = require('axios');

/**
 * Parsed the Saved content from Snoowrap into the data model preferred by Historian
 * @param {*} redditSavedContent
 */
function parseRedditSavedContent(redditSavedContent) {
    let histories = [];

    redditSavedContent.forEach((saved) => {
        let parsedMetadata = {
            author: saved.author.name,
            pk: saved.id,
            permalink: saved.permalink,
            subreddit: saved.subreddit.display_name,
            created_utc: saved.created_utc,
            score: saved.score,
            title: saved.title,
            thumbnail: saved.thumbnail,
            content_url: saved.url
        };

        let historyBody = {
            type: 'reddit_saved',
            metadata: parsedMetadata,
            timestamp: new Date()
        };

        console.log('Parsed - ', historyBody.metadata.pk);

        histories.push(historyBody);
    });

    logger.info('Completed Parsing...');
    return histories;
}

/**
 * Takes care of submitting all the Histories in a staggered fashion.
 * Prevent DDOSing the Backend
 * @param {*} histories
 */
async function staggeredHistoryInsert(histories) {
    // This controls the length of each staggered submission to Historian
    let chunkSize = config.get('agent.chunkSize');

    for (let i = 0; i < histories.length; i += chunkSize) {
        // Slice the passed Histories into a smaller array
        let slicedHistories = histories.slice(i, i + chunkSize);
        // logger.debug('slicedHistories - ', slicedHistories);

        // Post to Historian
        // We don't need to await for the response of the API call
        axios
            .post(config.get('historian.url') + config.get('historian.endpoints.addHistory'), slicedHistories, {
                headers: {
                    Authorization: createBasicAuthHeader(
                        config.get('historian.creds.username'),
                        config.get('historian.creds.password')
                    )
                }
            })
            .then(function (response) {
                console.log('Submitted History! response -', response.data);
            })
            .catch(function (error) {
                console.log('Caught Error - ', error.response.data);
            });

        // Wait for 1 second before submitting the next batch
        console.log('Waiting...');
        await sleep(1000);
    }
}

/**
 * Updates User's Metadata to document last_saved
 */
async function updateUserMetadata() {
    let body = {
        metadata: {
            reddit_saved: {
                last_saved: new Date()
            }
        }
    };

    try {
        let updateResponse = await axios.post(
            config.get('historian.url') + config.get('historian.endpoints.updateUser'),
            body,
            {
                headers: {
                    Authorization: createBasicAuthHeader(
                        config.get('historian.creds.username'),
                        config.get('historian.creds.password')
                    )
                }
            }
        );
        console.log('Updated Metadata - ', updateResponse.data);
    } catch (error) {
        console.log('Caught Error in updateUserMetadata - ', error);
    }
}

/**
 * Decodes the HTTP Authorization header
 * @param {*} username
 * @param {*} password
 */
function createBasicAuthHeader(username, password) {
    var encodedCreds = Buffer.from(username + ':' + password).toString('base64');
    var basicAuthHeader = 'Basic ' + encodedCreds;
    return basicAuthHeader;
}

/**
 * Util function to halt the code execution for X amount of ms
 * @param {*} ms
 */
function sleep(ms) {
    return new Promise((resolve) => {
        setTimeout(resolve, ms);
    });
}

module.exports = {
    parseRedditSavedContent,
    staggeredHistoryInsert,
    updateUserMetadata,
    sleep
};
