add web
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
# inventory.roblox.com
|
||||
|
||||
from flask import Blueprint, jsonify, request, make_response
|
||||
from flask_wtf.csrf import CSRFError, generate_csrf
|
||||
from app.extensions import db, redis_controller, limiter, csrf
|
||||
from app.models.user import User
|
||||
from app.models.userassets import UserAsset
|
||||
from app.models.asset import Asset
|
||||
from app.util import membership
|
||||
from app.enums.AssetType import AssetType
|
||||
from app.enums.MembershipType import MembershipType
|
||||
|
||||
InventoryAPI = Blueprint('InventoryAPI', __name__, url_prefix='/')
|
||||
csrf.exempt(InventoryAPI)
|
||||
@InventoryAPI.errorhandler(CSRFError)
|
||||
def handle_csrf_error(e):
|
||||
ErrorResponse = make_response(jsonify({
|
||||
"errors": [
|
||||
{
|
||||
"code": 0,
|
||||
"message": "Token Validation Failed"
|
||||
}
|
||||
]
|
||||
}))
|
||||
|
||||
ErrorResponse.status_code = 403
|
||||
ErrorResponse.headers["x-csrf-token"] = generate_csrf()
|
||||
return ErrorResponse
|
||||
|
||||
@InventoryAPI.errorhandler(429)
|
||||
def handle_ratelimit_reached(e):
|
||||
return jsonify({
|
||||
"errors": [
|
||||
{
|
||||
"code": 9,
|
||||
"message": "The flood limit has been exceeded."
|
||||
}
|
||||
]
|
||||
}), 429
|
||||
|
||||
@InventoryAPI.before_request
|
||||
def before_request():
|
||||
if "Roblox/" not in request.user_agent.string:
|
||||
csrf.protect()
|
||||
|
||||
itemTypes = {
|
||||
"asset": 0,
|
||||
"gamepass": 1,
|
||||
"badge": 2,
|
||||
"bundle": 3
|
||||
}
|
||||
|
||||
@InventoryAPI.route('/v1/users/<int:userId>/items/<itemType>/<int:itemTargetId>', methods=['GET'])
|
||||
@limiter.limit("60/minute")
|
||||
def get_user_item(userId : int , itemType : str , itemTargetId : int):
|
||||
userObject : User = User.query.filter_by(id=userId).first()
|
||||
if userObject is None:
|
||||
return jsonify( { "errors": [ { "code": 1, "message": "The specified user does not exist!" } ] } ), 400
|
||||
|
||||
try:
|
||||
itemType = int(itemType)
|
||||
if itemType < 0 or itemType > 3:
|
||||
return jsonify( { "errors": [ { "code": 6, "message": "The specified item type does not exist." } ] } ), 400
|
||||
except ValueError:
|
||||
if itemType.lower() not in itemTypes:
|
||||
return jsonify( { "errors": [ { "code": 7, "message": "The specified Asset does not exist!" } ] } ), 400
|
||||
|
||||
itemType = itemTypes[itemType.lower()]
|
||||
|
||||
assetObj : Asset = Asset.query.filter_by(id=itemTargetId).first()
|
||||
if assetObj is None:
|
||||
return jsonify( { "errors": [ { "code": 3, "message": "The specified item does not exist!" } ] } ), 400
|
||||
|
||||
dataList = []
|
||||
|
||||
userAssetList : list[UserAsset] = UserAsset.query.filter_by(userid=userId, assetid=itemTargetId).all()
|
||||
for user_asset_obj in userAssetList:
|
||||
dataList.append({
|
||||
"type": "Asset",
|
||||
"id": user_asset_obj.assetid,
|
||||
"name": user_asset_obj.asset.name,
|
||||
"instanceId": user_asset_obj.id,
|
||||
})
|
||||
|
||||
return jsonify({
|
||||
"previousPageCursor": None,
|
||||
"nextPageCursor": None,
|
||||
"data": dataList
|
||||
}), 200
|
||||
|
||||
@InventoryAPI.route('/v1/users/<int:userId>/items/<itemType>/<int:itemTargetId>/is-owned', methods=['GET'])
|
||||
@limiter.limit("60/minute")
|
||||
def lookup_user_ownership(userId : int , itemType , itemTargetId : int):
|
||||
userObject : User = User.query.filter_by(id=userId).first()
|
||||
if userObject is None:
|
||||
return jsonify( { "errors": [ { "code": 1, "message": "The specified user does not exist!" } ] } ), 400
|
||||
|
||||
try:
|
||||
itemType = int(itemType)
|
||||
if itemType < 0 or itemType > 3:
|
||||
return jsonify( { "errors": [ { "code": 6, "message": "The specified item type does not exist." } ] } ), 400
|
||||
except ValueError:
|
||||
if itemType.lower() not in itemTypes:
|
||||
return jsonify( { "errors": [ { "code": 7, "message": "The specified Asset does not exist!" } ] } ), 400
|
||||
|
||||
itemType = itemTypes[itemType.lower()]
|
||||
|
||||
assetObj : Asset = Asset.query.filter_by(id=itemTargetId).first()
|
||||
if assetObj is None:
|
||||
return jsonify( { "errors": [ { "code": 3, "message": "The specified item does not exist!" } ] } ), 400
|
||||
|
||||
userAssetObj : UserAsset = UserAsset.query.filter_by(userid=userId, assetid=itemTargetId).first()
|
||||
if userAssetObj is None:
|
||||
return "false", 200
|
||||
|
||||
return "true", 200
|
||||
|
||||
#@InventoryAPI.route('/v2/users/<int:userId>/inventory', methods=['GET'])
|
||||
@InventoryAPI.route('/v2/users/<int:userId>/inventory/<int:assetTypeId>/', methods=['GET'])
|
||||
@InventoryAPI.route('/v2/users/<int:userId>/inventory/<int:assetTypeId>', methods=['GET'])
|
||||
@limiter.limit("60/minute")
|
||||
def get_user_inventory(userId : int, assetTypeId : int = None):
|
||||
userObject : User = User.query.filter_by(id=userId).first()
|
||||
if userObject is None:
|
||||
return jsonify( { "errors": [ { "code": 1, "message": "Invalid user Id." } ] } ), 400
|
||||
|
||||
cursorPage : int = request.args.get("cursor", default = 1, type = int)
|
||||
if cursorPage < 1:
|
||||
return jsonify( { "errors": [ { "code": 4, "message": "The specified cursor is invalid!" } ] } ), 400
|
||||
|
||||
pageLimit : int = request.args.get("limit", default = 10, type = int)
|
||||
if pageLimit not in [10, 25, 50, 100]:
|
||||
return jsonify( { "errors": [ { "code": 5, "message": "The specified limit is invalid!" } ] } ), 400
|
||||
|
||||
sortOrder : str = request.args.get("sortOrder", default = "Asc", type = str)
|
||||
if sortOrder.lower() not in ["asc", "desc"]:
|
||||
return jsonify( { "errors": [ { "code": 6, "message": "The specified sort order is invalid!" } ] } ), 400
|
||||
|
||||
try:
|
||||
AssetTypeEnum : AssetType = AssetType(assetTypeId)
|
||||
except ValueError:
|
||||
return jsonify( { "errors": [ { "code": 2, "message": "Invalid asset type Id." } ] } ), 400
|
||||
|
||||
UserAssetList : list[UserAsset] = UserAsset.query.filter_by(userid=userId).outerjoin(
|
||||
Asset, UserAsset.assetid == Asset.id
|
||||
).filter(
|
||||
Asset.asset_type == AssetTypeEnum
|
||||
).order_by(
|
||||
UserAsset.updated.desc() if sortOrder.lower() == "desc" else UserAsset.updated.asc()
|
||||
).paginate(
|
||||
page = cursorPage,
|
||||
per_page = pageLimit,
|
||||
error_out = False
|
||||
)
|
||||
|
||||
UserMembershipType : int = membership.GetUserMembership( userObject ).value
|
||||
|
||||
dataList = []
|
||||
for user_asset_obj in UserAssetList.items:
|
||||
user_asset_obj : UserAsset = user_asset_obj
|
||||
dataList.append({
|
||||
"userAssetId": user_asset_obj.id,
|
||||
"assetId": user_asset_obj.assetid,
|
||||
"assetName": user_asset_obj.asset.name,
|
||||
"collectibleItemId": None,
|
||||
"collectibleItemInstanceId": None,
|
||||
"serialNumber": user_asset_obj.serial,
|
||||
"owner": {
|
||||
"userId": user_asset_obj.userid,
|
||||
"username": userObject.username,
|
||||
"buildersClubMembershipType": UserMembershipType
|
||||
},
|
||||
"created": user_asset_obj.created.isoformat(),
|
||||
"updated": user_asset_obj.updated.isoformat(),
|
||||
})
|
||||
|
||||
return jsonify({
|
||||
"previousPageCursor": str(UserAssetList.prev_num) if UserAssetList.has_prev else None,
|
||||
"nextPageCursor": str(UserAssetList.next_num) if UserAssetList.has_next else None,
|
||||
"data": dataList
|
||||
}), 200
|
||||
Reference in New Issue
Block a user