MaazAli/phanime

View on GitHub
server/methods/calculateAnimeRatingById.js

Summary

Maintainability
A
2 hrs
Test Coverage
Meteor.methods({
    
    calculateAnimeRatingById: function(animeId) {
        // Get all the library entries for an anime
        // We only need the rating and episodes seen fields
        var libraryEntries = LibraryEntries.find({animeId: animeId}, {fields: {status: 1, rating: 1, episodesSeen: 1}});
        var ratingCounts = {
            1: 0,
            2: 0,
            3: 0,
            4: 0,
            5: 0, 
            6: 0,
            7: 0,
            8: 0,
            9: 0,
            10: 0
        };

        var totalWeightedRatings = 0;
        var totalWeight = 0;
        var averageRating;
        var totalRatings = 0;

        // We can let other methods be executed, this could take a while 
        this.unblock();


        libraryEntries.forEach(function(libraryEntry) {
            var rating = libraryEntry.rating;
            var episodesSeen = libraryEntry.episodesSeen;
            var status = libraryEntry.status;


            // We don't want to count entries that have status 
            // as plan to watch. Even if they rated the anime,
            // their rating shouldn't really matter
            if (status !== 'Plan to watch') {

                // rating and episodesSeen must exist for the 
                // weighted average to work
                if (rating > 0 && episodesSeen > 0) {
                    ratingCounts[rating] += 1;
                    totalWeightedRatings += rating * episodesSeen;
                    totalWeight += episodesSeen;
                    totalRatings++;
                }

            }

        });


        // We only want to calculate the rating 
        // and update the anime if we have data

        if (totalWeightedRatings > 0) {
            // Calculate the weighted average
            // console.log(totalWeightedRatings);
            // console.log(totalWeight);
            averageRating = totalWeightedRatings/totalWeight;

            console.log("Average Rating for " + animeId + " : " + averageRating);
            
            // Update the anime with calculated ratings
            Anime.update(
                {
                    _id: animeId
                }, 
                {
                    $unset: {
                        ratingCount: ""
                    }, 
                    $set: {
                        rating: averageRating, 
                        totalRatings: totalRatings, 
                        ratingCounts: ratingCounts, 
                        ratingUpdatedAt: new Date()
                    }
                }, 
                {
                    // We don't want to define these keys in the schema
                    // since this is mostly meta information, so we'll just 
                    // disable the filtering and validation (We know what we're doing, hopefully)
                    filter: false, 
                    validate: false
                }
            );

        }

    }


});