Restructure get_presence function

Our shared `get_presence` function is also used while rendering page templates, so API-specific checks were migrated into the API-specific routes calling.
This commit is contained in:
Spotlight 2024-09-23 02:07:00 -05:00
parent bfe9f47e8d
commit 3c43d0a4f3
No known key found for this signature in database
GPG Key ID: 874AA355B3209BDC

View File

@ -273,29 +273,24 @@ def userAgentCheck():
except: except:
raise Exception('this client is invalid') raise Exception('this client is invalid')
def getPresence(friendCode:int, network:NetworkType, *, createAccount:bool = True, ignoreUserAgent = False, ignoreBackend = False):
try:
if not ignoreUserAgent:
userAgentCheck()
def get_presence(friend_code: int, network: NetworkType):
try:
network_start_time = db.session.get(Config, network).backend_uptime network_start_time = db.session.get(Config, network).backend_uptime
if network_start_time is None and not ignoreBackend and not disableBackendWarnings: if network_start_time is None and not disableBackendWarnings:
raise Exception('Backend currently offline. please try again later') raise Exception('Backend currently offline. please try again later')
friendCode = str(friendCode).zfill(12) principal_id = friend_code_to_principal_id(friend_code)
if createAccount:
createUser(friendCode, network, False)
principalId = friend_code_to_principal_id(friendCode)
stmt = ( stmt = (
select(Friend) select(Friend)
.where(Friend.friend_code == friendCode) .where(Friend.friend_code == friend_code)
.where(Friend.network == network) .where(Friend.network == network)
) )
result = db.session.scalar(stmt) result = db.session.scalar(stmt)
if not result: if not result:
raise Exception('friendCode not recognized\nHint: You may not have added the bot as a friend') raise Exception('Friend code not recognized!\nHint: You may not have added the bot as a friend')
if result.online: if result.online:
presence = { presence = {
'titleID': result.title_id, 'titleID': result.title_id,
@ -313,8 +308,8 @@ def getPresence(friendCode:int, network:NetworkType, *, createAccount:bool = Tru
return { return {
'Exception': False, 'Exception': False,
'User': { 'User': {
'principalId': principalId, 'principalId': principal_id,
'friendCode': str(principal_id_to_friend_code(principalId)).zfill(12), 'friendCode': str(friend_code).zfill(12),
'online': result.online, 'online': result.online,
'Presence': presence, 'Presence': presence,
'username': result.username, 'username': result.username,
@ -565,7 +560,8 @@ def userPage(friendCode:str):
try: try:
network = nameToNetworkType(request.args.get('network')) network = nameToNetworkType(request.args.get('network'))
userData = getPresence(int(friendCode.replace('-', '')), network, createAccount= False, ignoreUserAgent = True, ignoreBackend = True) friend_code_int = int(friendCode.replace('-', ''))
userData = get_presence(friend_code_int, network)
if userData['Exception'] or not userData['User']['username']: if userData['Exception'] or not userData['User']['username']:
raise Exception(userData['Exception']) raise Exception(userData['Exception'])
except: except:
@ -626,25 +622,37 @@ def newUser(friendCode:int, network:int=-1, userCheck:bool = True):
} }
} }
# Grab presence from friendCode # Grab presence from friendCode
@app.route('/api/user/<int:friendCode>/', methods=['GET']) @app.route('/api/user/<int:friend_code>/', methods=['GET'])
@limiter.limit(userPresenceLimit) @limiter.limit(userPresenceLimit)
def userPresence(friendCode:int, network:NetworkType=None, *, createAccount:bool = True, ignoreUserAgent = False, ignoreBackend = False): def userPresence(friend_code: int):
if network == None: # First, run 3DS-RPC client checks.
if request.args.get('network') != None: userAgentCheck()
network = nameToNetworkType(request.args.get('network'))
else: # Check if a specific network is being specified as a query parameter.
network = NetworkType.NINTENDO network_name = request.args.get('network')
return getPresence(friendCode, network, createAccount=createAccount, ignoreUserAgent = ignoreUserAgent, ignoreBackend = ignoreBackend) if network_name:
network = nameToNetworkType(network_name)
else:
network = NetworkType.NINTENDO
# Create a user for this friend code, or update its last access date.
# TODO(spotlightishere): This should be restructured!
createUser(friend_code, network, False)
return get_presence(friend_code, network)
# Alias # Alias
@app.route('/api/u/<int:friendCode>/', methods=['GET']) @app.route('/api/u/<int:friend_code>/', methods=['GET'])
@limiter.limit(userPresenceLimit) @limiter.limit(userPresenceLimit)
def userAlias(friendCode:int): def userAlias(friend_code:int):
network = NetworkType.NINTENDO network = NetworkType.NINTENDO
if request.args.get('network') != None: if request.args.get('network'):
network = nameToNetworkType(request.args.get('network')) network = nameToNetworkType(request.args.get('network'))
return userPresence(friendCode, network) return userPresence(friend_code, network)
# Alias # Alias
@app.route('/api/u/c/<int:friendCode>/', methods=['POST']) @app.route('/api/u/c/<int:friendCode>/', methods=['POST'])