from flask import Blueprint, render_template, request, redirect, url_for, jsonify, make_response, abort from app.models.asset_votes import AssetVote from app.models.asset_favorite import AssetFavorite from app.models.asset import Asset from app.enums.AssetType import AssetType from app.models.user import User from app.models.userassets import UserAsset from app.models.previously_played import PreviouslyPlayed from app.extensions import limiter, db, redis_controller from app.util import auth import json AssetRateRoute = Blueprint("assetrate", __name__, template_folder="pages") def ClearAssetVotesCache( assetId : int ): redis_controller.delete(f"asset:{str(assetId)}:votes") def GetAssetLikesAndDislikes( assetId : int ) -> tuple[int, int]: """ Returns 2 int values the first being the likes count and the second being the dislikes count. """ # See if we have the likes and dislikes in redis CachedVoteData = redis_controller.get(f"asset:{str(assetId)}:votes") if CachedVoteData is not None: CachedVoteData = json.loads(CachedVoteData) return CachedVoteData["likes"], CachedVoteData["dislikes"] LikesCount = AssetVote.query.filter_by(assetid=assetId, vote=True).count() DislikesCount = AssetVote.query.filter_by(assetid=assetId, vote=False).count() redis_controller.set(f"asset:{str(assetId)}:votes", json.dumps({"likes":LikesCount, "dislikes":DislikesCount}), ex=600) return LikesCount, DislikesCount def GetUserVoteStatus( assetId : int, userId : int ) -> int: # 2 = dislike, 0 = no vote, 1 = like """ Returns an int value which is 2 if the user disliked the asset, 0 if the user didn't vote and 1 if the user liked the asset. """ UserVoteObj : AssetVote = AssetVote.query.filter_by(assetid=assetId, userid=userId).first() if UserVoteObj is None: return 0 if UserVoteObj.vote == True: return 1 return 2 def GetAssetVotePercentage( assetId : int ) -> int: """ Returns an int value which is the percentage of likes the asset has. """ LikesCount, DislikesCount = GetAssetLikesAndDislikes(assetId) if LikesCount == 0 and DislikesCount == 0: return 50 return int((LikesCount / (LikesCount + DislikesCount)) * 100) @AssetRateRoute.route("/vote//", methods=["POST"]) @auth.authenticated_required_api @limiter.limit("5/minute") def vote_asset(assetid : int, status : int): if status > 2 or status < 0: return abort(400) AuthenticatedUser = auth.GetCurrentUser() AssetObj : Asset = Asset.query.filter_by(id=assetid).first() if AssetObj is None: return abort(404) AuthenticatedUser : User = auth.GetCurrentUser() if AssetObj.asset_type == AssetType.Place: if PreviouslyPlayed.query.filter_by(userid=AuthenticatedUser.id, placeid=AssetObj.id).first() is None: return abort(400) elif AssetObj.asset_type in [AssetType.GamePass, AssetType.Shirt, AssetType.TShirt, AssetType.Pants, AssetType.Hat, AssetType.Gear, AssetType.Plugin, AssetType.HairAccessory, AssetType.FaceAccessory, AssetType.NeckAccessory, AssetType.ShoulderAccessory, AssetType.FrontAccessory, AssetType.BackAccessory, AssetType.WaistAccessory, AssetType.EarAccessory, AssetType.EyeAccessory, AssetType.TShirtAccessory, AssetType.ShirtAccessory, AssetType.PantsAccessory, AssetType.JacketAccessory, AssetType.Package]: if UserAsset.query.filter_by(userid=AuthenticatedUser.id, assetid=AssetObj.id).first() is None: return abort(400) AssetVoteObj : AssetVote = AssetVote.query.filter_by(assetid=assetid, userid=AuthenticatedUser.id).first() if AssetVoteObj is None and status != 0: AssetVoteObj = AssetVote(assetid=assetid, userid=AuthenticatedUser.id, vote=True) db.session.add(AssetVoteObj) if AssetVoteObj is not None and status == 0: db.session.delete(AssetVoteObj) if AssetVoteObj is not None and status != 0: AssetVoteObj.vote = status == 1 db.session.commit() ClearAssetVotesCache(assetid) LikesCount, DislikesCount = GetAssetLikesAndDislikes(assetid) return jsonify({"success":True}), 200 def GetAssetFavoriteCount( assetId : int ) -> int: """ Returns an int value which is the amount of users who favorited the asset. """ if redis_controller.exists(f"asset:{str(assetId)}:favorites"): return int(redis_controller.get(f"asset:{str(assetId)}:favorites")) favoriteCount = AssetFavorite.query.filter_by(assetid=assetId).count() redis_controller.set(f"asset:{str(assetId)}:favorites", str(favoriteCount)) return favoriteCount def GetUserFavoriteStatus( assetId : int, userId : int ) -> bool: """ Returns a bool value which is True if the user favorited the asset and False if the user didn't favorite the asset. """ UserFavoriteObj : AssetFavorite = AssetFavorite.query.filter_by(assetid=assetId, userid=userId).first() if UserFavoriteObj is None: return False return True @AssetRateRoute.route("/favorite/", methods=["POST"]) @auth.authenticated_required_api @limiter.limit("5/minute") def favorite_asset(assetid : int): AuthenticatedUser = auth.GetCurrentUser() AssetFavoriteObj : AssetFavorite = AssetFavorite.query.filter_by(assetid=assetid, userid=AuthenticatedUser.id).first() if AssetFavoriteObj is None: AssetFavoriteObj = AssetFavorite(assetid=assetid, userid=AuthenticatedUser.id) db.session.add(AssetFavoriteObj) db.session.commit() return jsonify({"success":True}), 200 @AssetRateRoute.route("/favorite/", methods=["DELETE"]) @auth.authenticated_required_api @limiter.limit("5/minute") def unfavorite_asset(assetid : int): AuthenticatedUser = auth.GetCurrentUser() AssetFavoriteObj : AssetFavorite = AssetFavorite.query.filter_by(assetid=assetid, userid=AuthenticatedUser.id).first() if AssetFavoriteObj is not None: db.session.delete(AssetFavoriteObj) db.session.commit() redis_controller.delete(f"asset:{str(assetid)}:favorites") return jsonify({"success":True}), 200