All files / services SummaryService.js

100% Statements 61/61
100% Branches 11/11
75% Functions 3/4
100% Lines 61/61

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 611x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 32x 32x 32x 32x 32x 32x 32x 2x 32x 2x 2x 2x 32x 5x 32x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x
import {cacheEvictKey, cacheGetTtlObject} from "../lib/MemoryCache.js";
import {htmlOfPosts, txtOfPosts} from "../domain/post.js";
 
export const SUMMARY_CACHE_KEY = "cache:summary";
export const ONE_DAY_SECOND = 60 * 60 * 24;
 
export default class SummaryService {
    constructor(config, loggerService, blueskyService) {
        this.config = config;
        this.logger = loggerService.getLogger().child({label: 'SummaryService'});
        this.blueskyService = blueskyService;
    }
 
    cacheGetWeekSummary(config) {
        return cacheGetTtlObject(SUMMARY_CACHE_KEY, ONE_DAY_SECOND, this.getWeekSummary.bind(this, config));
    }
 
    async getWeekSummary(options) {
        const {blueskyService, logger} = this;
        const {context = {}} = options;
        const botPosts = await blueskyService.searchPosts({
            searchQuery: "from:botensky.bsky.social",
            "hasImages": true,
            "maxHoursOld": 7 * 24,// now-7d ... now
            "limit": 100
        })
        logger.info(`Summary - ${botPosts.length} post(s)`, context);
        const analytics = {
            posts: 0, likes: 0, replies: 0, reposts: 0,
            bestScore: 0, bestScorePosts: [],
            bestLikes: 0, bestLikesPosts: []
        };
        botPosts.forEach(p => {
            // DEBUG // logger.info(` - ${p.record.createdAt} - likes:${p.likeCount} replies:${p.replyCount}, reposts:${p.repostCount}`, context);
            analytics.posts++;
            analytics.likes += p.likeCount;
            analytics.replies += p.replyCount;
            analytics.reposts += p.repostCount;
            const postScore = p.likeCount * 2 + p.replyCount * 3 + p.repostCount * 4;
            if (postScore === analytics.bestScore) {
                analytics.bestScorePosts.push(p);
            } else if (postScore > analytics.bestScore) {
                analytics.bestScorePosts = [p];
                analytics.bestScore = postScore;
            }
            if (p.likeCount === analytics.bestLikes) {
                analytics.bestLikesPosts.push(p);
            } else if (p.likeCount > analytics.bestLikes) {
                analytics.bestLikesPosts = [p];
                analytics.bestLikes = p.likeCount;
            }
        });
        analytics.bestScorePostsHtml = htmlOfPosts(analytics.bestScorePosts, 2);
        analytics.bestLikesPostsHtml = htmlOfPosts(analytics.bestLikesPosts, 2);
        analytics.bestScorePostsTxt = txtOfPosts(analytics.bestScorePosts, 2);
        analytics.bestLikesPostsTxt = txtOfPosts(analytics.bestLikesPosts, 2);
        return analytics;
    }
}
 
export const clearSummaryCache = () => cacheEvictKey(SUMMARY_CACHE_KEY);