diff --git a/leaderboard.py b/leaderboard.py new file mode 100644 index 0000000..ce8c8d5 --- /dev/null +++ b/leaderboard.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python3 + +import os +import cgi +import sys +import json +import yaml +import pymysql +import requests + +# Print header +print('Content-type: application/json\n') + + +def jsonify(response): + return json.dumps(response) + + +def get_leaderboard_obj(username, avatar, category_count, rank): + obj = { + "username": username, + "avatar": avatar, + "rank": rank, + "category_count": category_count + } + return obj + + +def get_res(status, username, avatar, rank, category_count, category, duration, limit, offset, leaderboard_list): + response = { + "status": status, + "username": username, + "avatar": avatar, + "rank": rank, + "category_count": category_count, + "category": category, + "duration": duration, + "limit": limit, + "offset": offset, + "leaderboard_list": leaderboard_list + } + return jsonify(response) + + +def get_res_error(status, user, message): + response = {'status': status, 'user': user, 'message': message} + return jsonify(response) + + +offset = None +limit = None + +# Fetch params +if 'QUERY_STRING' in os.environ: + QS = os.environ['QUERY_STRING'] + qs = cgi.parse_qs(QS) + try: + if 'offset' in qs: + offset = qs['offset'][0] + + if 'limit' in qs: + limit = qs['limit'][0] + + username = qs['user'][0].replace('_', ' ') + duration = qs['duration'][0] + category = qs['category'][0] + except: + print(get_res_error('400', '', 'Invalid Parameters')) + sys.exit(0) + + # Load config + __dir__ = os.path.dirname(__file__) + config = yaml.safe_load(open(os.path.join(__dir__, 'config.yaml'))) + conn = pymysql.connect(db='s53794__leaderboard', + host=config['DB_HOST'], + user=config['DB_USER'], + password=config['DB_PASS'], + charset="utf8", + ) +else: + print(get_res_error('500', username, 'Unable to connect to database')) + sys.exit(0) + + +##### PROGRAM #### + + +def get_leaderboard_list(data): + result = [] + rank = 1 + for row in data: + result.append(get_leaderboard_obj(row[1], row[2], row[3], rank)) + rank += 1 + return result + + +def get_user_details(username, leaderboard_list): + try: + return next(item for item in leaderboard_list if item['username'] == username) + except: + print(get_res_error('400', username, 'Username not found')) + sys.exit(0) + + +def get_sql(duration, category, offset=None, limit=None): + + if limit != None and offset != None: + return """select leaderboard_user.user_id, leaderboard_user.username, leaderboard_user.user_avatar, leaderboard_{category}.{duration} + from leaderboard_{category} + LEFT JOIN (leaderboard_user) on (leaderboard_{category}.user_id = leaderboard_user.user_id) + order by {duration} desc limit {limit} offset {offset};""".format(duration=duration, category=category, limit=limit, offset=offset) + else: + return """select leaderboard_user.user_id, leaderboard_user.username, leaderboard_user.user_avatar, leaderboard_{category}.{duration} + from leaderboard_{category} + LEFT JOIN (leaderboard_user) on (leaderboard_{category}.user_id = leaderboard_user.user_id) + order by {duration} desc;""".format(duration=duration, category=category) + + +try: + cur = conn.cursor() + with cur: + sql = get_sql(duration, category, offset, limit) + cur.execute(sql) + data = cur.fetchall() + + leaderboard_list = get_leaderboard_list(data) + user_details = get_user_details(username, leaderboard_list) + result = get_res(200, username, user_details['avatar'], user_details['rank'], user_details['category_count'], + category, duration, limit, offset, leaderboard_list) + print(result) + +except: + print(get_res_error('500', username, 'Internal Server Error')) + sys.exit(0)