syntaxwebsite/app/routes/rate.py

131 lines
6.0 KiB
Python

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/<int:assetid>/<int:status>", 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/<int:assetid>", 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/<int:assetid>", 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