- Coverage for admin.py: - 18% -
- -- 350 statements - - - -
-- « prev - ^ index - » next - - coverage.py v7.5.1, - created at 2024-05-04 12:59 -0400 -
- -diff --git a/.gitignore b/.gitignore index f5ae3c53..09bc2eb6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,53 @@ -*.pyc +# --- Security (CRITICAL) --- .env -.venv -__pycache__ -.DS_Store +.env.* +*.key +secrets.json + +# --- Python --- +__pycache__/ +*.py[cod] +*$py.class + +# --- Virtual Environments --- +.venv/ +venv/ +ENV/ +env/ + +# --- Distribution / Build --- +build/ +dist/ +*.egg-info/ +.eggs/ + +# --- Testing & Coverage (The "Ugly" Folders) --- +htmlcov/ .coverage +.coverage.* +.tox/ +.pytest_cache/ +nosetests.xml +coverage.xml + +# --- Flask --- +instance/ +.webassets-cache + +# --- IDEs & Editors --- +.vscode/ +.idea/ +*.swp +*.swo + +# --- OS Specific --- +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# --- Project Specific --- picturedata.txt \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 23fd35f0..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/htmlcov/admin_py.html b/htmlcov/admin_py.html deleted file mode 100644 index 99351216..00000000 --- a/htmlcov/admin_py.html +++ /dev/null @@ -1,613 +0,0 @@ - - -
- -- « prev - ^ index - » next - - coverage.py v7.5.1, - created at 2024-05-04 12:59 -0400 -
- -1#-----------------------------------------------------------------------
-2# admin.py
-3# Contains Flask App Routing
-4#-----------------------------------------------------------------------
- -6#external libraries
-7import flask
-8import os
-9import auth
-10import dotenv
-11import random
- -13#Tiger Spot files
-14import database
-15import challenges_database
-16import matches_database
-17import versus_database
-18import pictures_database
-19import user_database
-20import distance_func
-21import daily_user_database
-22import points
-23import user_database
- -25#-----------------------------------------------------------------------
-26app = flask.Flask(__name__, template_folder='.')
-27dotenv.load_dotenv()
-28#used for CAS login
-29app.secret_key = os.environ['APP_SECRET_KEY']
- -31#-----------------------------------------------------------------------
-32# GLOBAL VAR DEFAULT VAL FOR ID, NEED TO RESOLVE SECURITY MEASURES
-33id = 1
-34#-----------------------------------------------------------------------
- -36# For error handling
-37# checks if a function call had a database error based on function's return value
-38def database_check(list):
-39 if "database error" in list:
-40 return False
-41 return True
- -43#-----------------------------------------------------------------------
- -45# If the user is playing the game for the first time of today, their matches and challenges are cleared
-46def reset_versus(username):
- -48 last_date = daily_user_database.get_last_versus_date(username)
-49 print(f"LAST VERSUS DATE IS: {last_date}")
-50 current_date = pictures_database.get_current_date()
-51 print(f"CURRENT DATE IS: {current_date}")
- -53 if last_date != current_date:
-54 challenges_database.clear_user_challenges(username)
-55 daily_user_database.update_player_versus(username)
- -57#-----------------------------------------------------------------------
- -59@app.route('/sam', methods=['GET'])
-60def sam():
-61 html_code = flask.render_template('sam.html')
-62 response = flask.make_response(html_code)
-63 return response
- -65#-----------------------------------------------------------------------
- -67# Routes for authentication.
-68@app.route('/logoutapp', methods=['GET'])
-69def logoutapp():
-70 return auth.logoutapp()
- -72@app.route('/logoutcas', methods=['GET'])
-73def logoutcas():
-74 return auth.logoutcas()
- -76#-----------------------------------------------------------------------
-77# Displays page with log in button
-78@app.route('/', methods=['GET'])
-79@app.route('/index', methods=['GET'])
-80def index():
- -82 html_code = flask.render_template('index.html')
-83 response = flask.make_response(html_code)
-84 return response
- -86#-----------------------------------------------------------------------
- -88# Home page after user logs in through Princeton's CAS
-89@app.route('/menu', methods=['GET'])
-90def menu():
-91 global id
-92 username = auth.authenticate()
-93 user_insert = user_database.insert_player(username)
-94 daily_insert = daily_user_database.insert_player_daily(username)
-95 played_date = daily_user_database.get_last_played_date(username)
-96 current_date = pictures_database.get_current_date()
- -98 check = database_check([user_insert, daily_insert, played_date, current_date])
-99 if check is False:
-100 html_code = flask.render_template('contact_admin.html')
-101 return flask.make_response(html_code)
- -103 if played_date != current_date:
-104 reset = daily_user_database.reset_player(username)
-105 user_played = daily_user_database.player_played(username)
-106 id = pictures_database.pic_of_day()
-107 check = database_check([reset, user_played, id])
-108 if check is False:
-109 html_code = flask.render_template('contact_admin.html')
-110 return flask.make_response(html_code)
- -112 html_code = flask.render_template('menu.html', username = username)
-113 response = flask.make_response(html_code)
-114 return response
- -116#-----------------------------------------------------------------------
- -118# if there are no database errors, renders versus page listing a user's challenges. Otherwise, renders error page
-119@app.route('/requests', methods=['GET'])
-120def requests():
-121 username = flask.request.args.get('username')
-122 username_auth = auth.authenticate()
-123 last_date = daily_user_database.get_last_versus_date(username)
-124 current_date = pictures_database.get_current_date()
- -126 check = database_check([last_date, current_date])
-127 if check is False:
-128 html_code = flask.render_template('contact_admin.html')
-129 return flask.make_response(html_code)
- -131 if last_date != current_date:
-132 challenges_database.clear_user_challenges(username)
-133 daily_user_database.update_player_versus(username)
-134 # Need to add check here too
- -136 pending_challenges = challenges_database.get_user_challenges(username_auth)
-137 users = user_database.get_players()
- -139 check = database_check([pending_challenges, users])
-140 if check is False:
-141 html_code = flask.render_template('contact_admin.html')
-142 else:
-143 html_code = flask.render_template('Versus/challenges.html', challenges=pending_challenges, user=username_auth, users=flask.json.dumps(users), username=username)
- -145 response = flask.make_response(html_code)
-146 return response
- -148#-----------------------------------------------------------------------
- -150# if there are no errors, loads the daily game
-151# or if user has already played today's game, loads a page stating their points and distance between their guess and correct location
-152@app.route('/game', methods=['GET'])
-153def game():
- -155 global id
- -157 username = auth.authenticate()
- -159 user_played = daily_user_database.player_played(username)
-160 today_points = daily_user_database.get_daily_points(username)
-161 today_distance = daily_user_database.get_daily_distance(username)
- -163 check = database_check([user_played, today_points, today_distance])
-164 if check is False:
-165 html_code = flask.render_template('contact_admin.html')
-166 return flask.make_response(html_code)
- -168 if user_played:
-169 html_code = flask.render_template('alrplayed.html', username = username, today_points = today_points, today_distance = today_distance)
-170 response = flask.make_response(html_code)
-171 return response
- -173 link = pictures_database.get_pic_info("link", id)
- -175 check = database_check([link])
-176 if check is False:
-177 html_code = flask.render_template('contact_admin.html')
-178 else:
-179 html_code = flask.render_template('gamepage.html', link = link, id = id)
- -181 response = flask.make_response(html_code)
-182 return response
- -184#-----------------------------------------------------------------------
- -186# if there are no errors with database, calculates distance and points and updates usersDaily table with points and adds today's points to total points column in users table
-187# Then loads the results page which displays the correct location, the distance from guess to acutal location, points earned, place where picture was taken
-188@app.route('/submit', methods=['POST'])
-189def submit():
- -191 username = auth.authenticate()
- -193 user_played = daily_user_database.player_played(username)
-194 today_points = daily_user_database.get_daily_points(username)
-195 today_distance = daily_user_database.get_daily_distance(username)
- -197 check = database_check([user_played, today_points, today_distance])
-198 if check is False:
-199 html_code = flask.render_template('contact_admin.html')
-200 return flask.make_response(html_code)
- -202 if user_played:
-203 html_code = flask.render_template('alrplayed.html', username = username, today_points = today_points, today_distance = today_distance)
-204 response = flask.make_response(html_code)
-205 return response
- -207 # get user input using flask.request.args.get('')
-208 #once user clicks submit then get coordinates
-209 currLat = flask.request.form.get('currLat') # Use .get for safe retrieval
-210 currLon = flask.request.form.get('currLon')
-211 if not currLat or not currLon:
-212 return
- -214 coor = pictures_database.get_pic_info("coordinates", id)
-215 place = pictures_database.get_pic_info("place", id)
-216 distance = round(distance_func.calc_distance(currLat, currLon, coor))
-217 today_points = round(points.calculate_today_points(distance))
-218 total_points = round(points.calculate_total_points(username, today_points))
-219 update= user_database.update_player(username, total_points)
-220 daily_update = daily_user_database.update_player_daily(username, today_points, distance)
- -222 check = database_check([coor, place, update, daily_update])
-223 if check is False:
-224 html_code = flask.render_template('contact_admin.html')
-225 else:
-226 html_code = flask.render_template('results.html', dis = distance, lat = currLat, lon = currLon, coor=coor, today_points = today_points, place = place, today_distance = distance)
- -228 response = flask.make_response(html_code)
-229 return response
- -231#-----------------------------------------------------------------------
- -233# Displays rules page for both daily game and versus mode
-234@app.route('/rules', methods=['GET'])
-235def rules():
-236 # user must be logged in to access page
-237 auth.authenticate()
-238 html_code = flask.render_template('rules.html')
-239 response = flask.make_response(html_code)
-240 return response
- -242#-----------------------------------------------------------------------
- -244# Displays about the team page
-245@app.route('/team', methods=['GET'])
-246def team():
-247 # user must be logged in to access page
-248 auth.authenticate()
-249 html_code = flask.render_template('team.html')
-250 response = flask.make_response(html_code)
-251 return response
- -253#-----------------------------------------------------------------------
- -255# Displays the leaderboard for overall points
-256@app.route('/totalboard', methods=['GET'])
-257def leaderboard():
-258 top_players = user_database.get_top_players()
-259 username = auth.authenticate()
-260 points = user_database.get_points(username)
-261 daily_points = daily_user_database.get_daily_points(username)
-262 rank = user_database.get_rank(username)
-263 daily_rank = daily_user_database.get_daily_rank(username)
-264 streak = daily_user_database.get_streak(username)
- -266 check = database_check([top_players, points, daily_points, rank, daily_rank, streak])
- -268 if check is False:
-269 html_code = flask.render_template('contact_admin.html')
-270 else:
-271 html_code = flask.render_template('totalboard.html', top_players = top_players, points = points, daily_points = daily_points, rank = rank, daily_rank = daily_rank, streak = streak)
- -273 response = flask.make_response(html_code)
-274 return response
- -276#-----------------------------------------------------------------------
- -278# Displays the leaderboard for today's daily game points
-279@app.route('/leaderboard', methods=['GET'])
-280def totalleaderboard():
-281 top_players = daily_user_database.get_daily_top_players()
-282 username = auth.authenticate()
-283 points = user_database.get_points(username)
-284 daily_points = daily_user_database.get_daily_points(username)
-285 rank = user_database.get_rank(username)
-286 daily_rank = daily_user_database.get_daily_rank(username)
-287 streak = daily_user_database.get_streak(username)
- -289 check = database_check([top_players, points, daily_points, rank, daily_rank, streak])
-290 if check is False:
-291 html_code = flask.render_template('contact_admin.html')
-292 else:
-293 html_code = flask.render_template('leaderboard.html', top_players = top_players, points = points, daily_points = daily_points, rank = rank, daily_rank = daily_rank, streak = streak)
- -295 response = flask.make_response(html_code)
-296 return response
- -298#-----------------------------------------------------------------------
- -300# checks that users table is not corrupted and then displays the versus page where users can initiate and see challenges
-301@app.route('/versus', methods=['GET'])
-302def versus_func():
-303 users = user_database.get_players()
-304 username = flask.request.args.get('username')
- -306 check = database_check([users])
-307 if check is False:
-308 html_code = flask.render_template('contact_admin.html')
-309 else:
-310 html_code = flask.render_template('Versus/challenges.html', users=flask.json.dumps(users), username=username)
- -312 response = flask.make_response(html_code)
-313 return response
- -315#-----------------------------------------------------------------------
- -317# checks that user table is not corrupted and that opponent enters is a valid user (exisiting netiID and has logged in before)
-318@app.route('/create-challenge', methods=['POST'])
-319def create_challenge_route():
-320 challengee_id = flask.request.form['challengee_id'].strip() # Trim whitespace
-321 users = user_database.get_players()
- -323 check = database_check([users])
-324 if check is False:
-325 html_code = flask.render_template('contact_admin.html')
-326 return flask.make_response(html_code)
- -328 # Ensure challengee_id is not empty and exists in the users list
-329 if challengee_id == None or challengee_id not in users or challengee_id == auth.authenticate():
-330 response = {'status': 'error', 'message': 'Invalid challengee ID'}
-331 return flask.jsonify(response), 400 # Including a 400 Bad Request status code
-332 else:
-333 result = challenges_database.create_challenge(auth.authenticate(), challengee_id)
- -335 # Handle the response from the database function
-336 if 'error' in result:
-337 return flask.jsonify({'status': 'error', 'message': result['error']}), 400
-338 else:
-339 return flask.jsonify({'status': 'success', 'message': result['success'], 'challenge_id': result['challenge_id']}), 200
- -341#-----------------------------------------------------------------------
- -343# Accepts challenge unless there is a database error
-344@app.route('/accept_challenge', methods=['POST'])
-345def accept_challenge_route():
-346 challenge_id = flask.request.form.get('challenge_id')
-347 result = challenges_database.accept_challenge(challenge_id) # Returns whether or not challenge acceptance was successful
- -349 check = database_check([result])
-350 if check is False:
-351 html_code = flask.render_template('contact_admin.html')
-352 return flask.make_response(html_code)
- -354 if result == "accepted":
-355 flask.flash('Challenge accepted successfully.')
-356 else:
-357 flask.flash('Error accepting challenge.')
-358 return flask.redirect(flask.url_for('requests')) # Redirects back to the versus page with the tables of user's challenges
- -360#-----------------------------------------------------------------------
- -362# Declines challenge unless there is a database error
-363@app.route('/decline_challenge', methods=['POST'])
-364def decline_challenge_route():
-365 challenge_id = flask.request.form.get('challenge_id')
-366 result = challenges_database.decline_challenge(challenge_id)
- -368 check = database_check([result])
-369 if check is False:
-370 html_code = flask.render_template('contact_admin.html')
-371 return flask.make_response(html_code)
- -373 if result == "declined":
-374 flask.flash('Challenge declined successfully.')
-375 else:
-376 flask.flash('Error declining challenge.')
-377 return flask.redirect(flask.url_for('requests'))
- -379#-----------------------------------------------------------------------
- -381@app.route('/play_button', methods=['POST'])
-382def play_button():
-383 challenge_id = flask.request.form.get('challenge_id')
-384 user = auth.authenticate()
-385 status = challenges_database.get_playbutton_status(challenge_id, user)
-386 if status is None:
-387 return flask.redirect(flask.url_for('requests'))
-388 elif status is False:
-389 challenges_database.update_playbutton_status(challenge_id, user)
-390 return flask.redirect(flask.url_for('start_challenge', challenge_id=challenge_id))
-391 elif status is True:
-392 challenges_database.update_finish_status(challenge_id, user)
-393 status = challenges_database.check_finish_status(challenge_id)
-394 if status['status'] == "finished":
-395 result = challenges_database.get_challenge_results(challenge_id)
-396 matches_database.complete_match(challenge_id, result['winner'], result['challenger_points'], result['challengee_points'])
-397 return flask.redirect(flask.url_for('requests'))
-398 else:
-399 return flask.redirect(flask.url_for('requests'))
- -401#-----------------------------------------------------------------------
- -403@app.route('/start_challenge', methods=['GET'])
-404def start_challenge():
-405 challenge_id = flask.request.args.get('challenge_id')
-406 if challenge_id is None:
-407 return flask.redirect(flask.url_for('requests'))
- -409 index = int(flask.request.args.get('index', 0))
-410 versusList = challenges_database.get_random_versus(challenge_id)
-411 if versusList is None:
-412 return flask.redirect(flask.url_for('requests'))
- -414 if index < len(versusList):
-415 link = pictures_database.get_pic_info("link", versusList[index])
-416 html_code = flask.render_template('versusgame.html', challenge_id=challenge_id, index=index, link=link)
-417 return flask.make_response(html_code)
-418 else:
-419 return flask.redirect(flask.url_for('requests'))
- -421#-----------------------------------------------------------------------
- -423@app.route('/end_challenge', methods=['POST'])
-424def end_challenge():
-425 challenge_id = flask.request.form.get('challenge_id')
-426 user = auth.authenticate()
-427 finish = challenges_database.update_finish_status(challenge_id, user)
-428 if finish == None:
-429 return flask.redirect(flask.url_for('requests'))
-430 status = challenges_database.check_finish_status(challenge_id)
-431 if status['status'] == "finished":
-432 result = challenges_database.get_challenge_results(challenge_id)
-433 matches_database.complete_match(challenge_id, result['winner'], result['challenger_points'], result['challengee_points'])
-434 return flask.redirect(flask.url_for('requests'))
-435 else:
-436 return flask.redirect(flask.url_for('requests'))
- -438#-----------------------------------------------------------------------
- -440@app.route('/submit2', methods=['POST'])
-441def submit2():
-442 currLat = flask.request.form.get('currLat')
-443 currLon = flask.request.form.get('currLon')
-444 points = 0
-445 if not currLat or not currLon:
-446 index = int(flask.request.form.get('index'))
-447 challenge_id = flask.request.form.get('challenge_id')
-448 distance = 0
-449 pic_status = versus_database.get_versus_pic_status(challenge_id, auth.authenticate(), index+1)
-450 if pic_status is None:
-451 return flask.redirect(flask.url_for('requests'))
-452 if pic_status == False:
-453 fin1 = versus_database.update_versus_pic_status(challenge_id, auth.authenticate(), index+1)
-454 print(fin1)
-455 if fin1 is None:
-456 return flask.redirect(flask.url_for('requests'))
-457 fin2 = versus_database.store_versus_pic_points(challenge_id, auth.authenticate(), index+1, points)
-458 print(fin2)
-459 if fin2 is None:
-460 return flask.redirect(flask.url_for('requests'))
-461 fin3 = versus_database.update_versus_points(challenge_id, auth.authenticate(), points)
-462 print(fin3)
-463 if fin3 is None:
-464 return flask.redirect(flask.url_for('requests'))
-465 else:
-466 points = "Already submitted."
-467 index = int(index) + 1
-468 html_code = flask.render_template('versusresults.html', dis = distance, lat = None, lon = None, coor=None, index=index, challenge_id=challenge_id, points=str(points))
-469 response = flask.make_response(html_code)
-470 return response
- -472 index = int(flask.request.form.get('index'))
-473 challenge_id = flask.request.form.get('challenge_id')
-474 time = int(flask.request.form.get('time'))
-475 versusList = challenges_database.get_random_versus(challenge_id)
-476 print(versusList)
-477 if versusList is None:
-478 return flask.redirect(flask.url_for('requests'))
-479 coor = pictures_database.get_pic_info("coordinates", versusList[index])
-480 distance = round(distance_func.calc_distance(currLat, currLon, coor))
-481 pic_status = versus_database.get_versus_pic_status(challenge_id, auth.authenticate(), index+1)
-482 print(pic_status)
-483 if pic_status is None:
-484 return flask.redirect(flask.url_for('requests'))
-485 if pic_status == False:
-486 points = round(versus_database.calculate_versus(distance, time))
-487 fin1 = versus_database.store_versus_pic_points(challenge_id, auth.authenticate(), index+1, points)
-488 print(fin1)
-489 if fin1 is None:
-490 return flask.redirect(flask.url_for('requests'))
-491 fin2 = versus_database.update_versus_points(challenge_id, auth.authenticate(), points)
-492 print(fin2)
-493 if fin2 is None:
-494 return flask.redirect(flask.url_for('requests'))
-495 fin3 = versus_database.update_versus_pic_status(challenge_id, auth.authenticate(), index+1)
-496 print(fin3)
-497 if fin3 is None:
-498 return flask.redirect(flask.url_for('requests'))
-499 else:
-500 points = "Already submitted."
-501 index = int(index) + 1
-502 html_code = flask.render_template('versusresults.html', dis = distance, lat = currLat, lon = currLon, coor=coor, index=index, challenge_id=challenge_id, points=str(points))
-503 response = flask.make_response(html_code)
-504 return response
- -506#-----------------------------------------------------------------------
- -508@app.route('/versus_stats', methods=['GET'])
-509def versus_stats():
-510 challenge_id = flask.request.args.get('challenge_id')
-511 results = challenges_database.get_challenge_results(challenge_id)
-512 versusList = challenges_database.get_random_versus(challenge_id)
-513 pictures = [pictures_database.get_pic_info("link", pic) for pic in versusList]
-514 html_code = flask.render_template('versus_stats.html', results=results, images=pictures)
-515 response = flask.make_response(html_code)
-516 return response
-- « prev - ^ index - » next - - coverage.py v7.5.1, - created at 2024-05-04 12:59 -0400 -
- -2#-----------------------------------------------------------------------
-3# auth.py
-4#-----------------------------------------------------------------------
- -6import urllib.request
-7import urllib.parse
-8import re
-9import flask
- -11#-----------------------------------------------------------------------
- -13_CAS_URL = 'https://fed.princeton.edu/cas/'
- -15#-----------------------------------------------------------------------
- -17# Return url after stripping out the "ticket" parameter that was
-18# added by the CAS server.
- -20def strip_ticket(url):
-21 if url is None:
-22 return "something is badly wrong"
-23 url = re.sub(r'ticket=[^&]*&?', '', url)
-24 url = re.sub(r'\?&?$|&$', '', url)
-25 return url
- -27#-----------------------------------------------------------------------
- -29# Validate a login ticket by contacting the CAS server. If
-30# valid, return the user's username; otherwise, return None.
- -32def validate(ticket):
-33 val_url = (_CAS_URL + "validate" + '?service='
-34 + urllib.parse.quote(strip_ticket(flask.request.url))
-35 + '&ticket=' + urllib.parse.quote(ticket))
-36 lines = []
-37 with urllib.request.urlopen(val_url) as flo:
-38 lines = flo.readlines() # Should return 2 lines.
-39 if len(lines) != 2:
-40 return None
-41 first_line = lines[0].decode('utf-8')
-42 second_line = lines[1].decode('utf-8')
-43 if not first_line.startswith('yes'):
-44 return None
-45 return second_line
- -47#-----------------------------------------------------------------------
- -49# Authenticate the remote user, and return the user's username.
-50# Do not return unless the user is successfully authenticated.
- -52def authenticate():
- -54 # If the username is in the session, then the user was
-55 # authenticated previously. So return the username.
-56 if 'username' in flask.session:
-57 return flask.session.get('username')
- -59 # If the request does not contain a login ticket, then redirect
-60 # the browser to the login page to get one.
-61 ticket = flask.request.args.get('ticket')
-62 if ticket is None:
-63 login_url = (_CAS_URL + 'login?service=' +
-64 urllib.parse.quote(flask.request.url))
-65 flask.abort(flask.redirect(login_url))
- -67 # If the login ticket is invalid, then redirect the browser
-68 # to the login page to get a new one.
-69 username = validate(ticket)
-70 if username is None:
-71 login_url = (_CAS_URL + 'login?service='
-72 + urllib.parse.quote(strip_ticket(flask.request.url)))
-73 flask.abort(flask.redirect(login_url))
- -75 # The user is authenticated, so store the username in
-76 # the session.
-77 username = username.strip()
-78 flask.session['username'] = username
-79 return username
- -81#-----------------------------------------------------------------------
- -83def logoutapp():
- -85 # Log out of the application.
-86 flask.session.clear()
-87 html_code = flask.render_template('index.html')
-88 response = flask.make_response(html_code)
-89 return response
- -91#-----------------------------------------------------------------------
- -93def logoutcas():
- -95 # Log out of the CAS session, and then the application.
-96 logout_url = (_CAS_URL + 'logout?service='
-97 + urllib.parse.quote(
-98 re.sub('logoutcas', 'logoutapp', flask.request.url)))
-99 flask.abort(flask.redirect(logout_url))
-- « prev - ^ index - » next - - coverage.py v7.5.1, - created at 2024-05-04 12:59 -0400 -
- -1import psycopg2
-2import random
-3import database
-4import versus_database
- -6DATABASE_URL = 'postgres://tigerspot_user:9WtP1U9PRdh1VLlP4VdwnT0BFSdbrPWk@dpg-cnrjs7q1hbls73e04390-a.ohio-postgres.render.com/tigerspot'
- -8#dont run again
-9def create_challenges_table():
-10 conn = psycopg2.connect(DATABASE_URL)
-11 cur = conn.cursor()
-12 cur.execute('''CREATE TABLE IF NOT EXISTS challenges(
-13 id SERIAL PRIMARY KEY,
-14 challenger_id VARCHAR(255),
-15 challengee_id VARCHAR(255),
-16 status VARCHAR(50));''')
-17 conn.commit()
-18 cur.close()
-19 conn.close()
- -21#-----------------------------------------------------------------------
- -23def clear_challenges_table():
-24 conn = None
-25 try:
-26 conn = psycopg2.connect(DATABASE_URL)
-27 cur = conn.cursor()
-28 # Deletes all records from the challenges table
-29 cur.execute("DELETE FROM challenges;")
-30 conn.commit() # Commit the transaction to make changes permanent
-31 print("Challenges table cleared.")
-32 cur.execute("DELETE FROM matches;")
-33 conn.commit() # Commit the transaction to make changes permanent
-34 print("Matches table cleared.")
-35 cur.execute("ALTER SEQUENCE challenges_id_seq RESTART WITH 1;")
-36 conn.commit() # Commit the change to make it permanent
-37 print("Challenges id sequence reset.")
-38 cur.execute("ALTER SEQUENCE matches_id_seq RESTART WITH 1;")
-39 conn.commit() # Commit the change to make it permanent
-40 print("Matches id sequence reset.")
-41 except (Exception, psycopg2.DatabaseError) as error:
-42 print(f"Error clearing challenges table: {error}")
-43 finally:
-44 if conn is not None:
-45 conn.close()
- - -48def clear_user_challenges(user_id):
-49 conn = None
-50 try:
-51 conn = psycopg2.connect(DATABASE_URL)
-52 cur = conn.cursor()
- -54 # Query to find challenges related to the user_id
-55 cur.execute("""
-56 SELECT id FROM challenges
-57 WHERE challenger_id = %s OR challengee_id = %s;
-58 """, (user_id, user_id))
- -60 challenge_ids = [row[0] for row in cur.fetchall()]
- -62 if challenge_ids:
-63 # Delete matching entries from the matches table
-64 cur.execute("""
-65 DELETE FROM matches
-66 WHERE challenge_id IN %s;
-67 """, (tuple(challenge_ids),))
- -69 # Delete entries from the challenges table
-70 cur.execute("""
-71 DELETE FROM challenges
-72 WHERE id IN %s;
-73 """, (tuple(challenge_ids),))
- -75 conn.commit() # Commit the transaction to make changes permanent
-76 print(f"Entries related to user_id {user_id} cleared from challenges and matches tables.")
- -78 except (Exception, psycopg2.DatabaseError) as error:
-79 print(f"Error clearing entries for user_id {user_id}: {error}")
-80 finally:
-81 if conn is not None:
-82 conn.close()
- -84#-----------------------------------------------------------------------
- -86def create_challenge(challenger_id, challengee_id):
-87 conn = None
-88 try:
-89 conn = psycopg2.connect(DATABASE_URL)
-90 cur = conn.cursor()
- -92 # Check for existing challenge between the two users
-93 cur.execute("""
-94 SELECT id FROM challenges
-95 WHERE
-96 ((challenger_id = %s AND challengee_id = %s) OR
-97 (challenger_id = %s AND challengee_id = %s))
-98 AND status IN ('pending', 'accepted')
-99 """, (challenger_id, challengee_id, challengee_id, challenger_id))
- -101 existing_challenge = cur.fetchone()
- -103 if existing_challenge:
-104 # An existing challenge was found
-105 return {'error': 'Challenge already exists', 'challenge_id': existing_challenge[0]}
- -107 # No existing challenge found, proceed to create a new one
-108 cur.execute("""
-109 INSERT INTO challenges (challenger_id, challengee_id, status)
-110 VALUES (%s, %s, 'pending') RETURNING id;
-111 """, (challenger_id, challengee_id))
- -113 challenge_id = cur.fetchone()[0]
-114 conn.commit()
-115 print(f"Challenge created with ID: {challenge_id}")
-116 return {'success': 'Challenge created successfully', 'challenge_id': challenge_id}
- -118 except (Exception, psycopg2.DatabaseError) as error:
-119 print(error)
-120 return {'error': 'Database error occurred'}
-121 finally:
-122 if conn is not None:
-123 conn.close()
- -125#-----------------------------------------------------------------------
- -127# Accept a challenge
-128def accept_challenge(challenge_id):
-129 status = "database error" # Default status in case of error
-130 conn = None
-131 try:
-132 conn = psycopg2.connect(DATABASE_URL)
-133 cur = conn.cursor()
-134 cur.execute("""
-135 UPDATE challenges
-136 SET status = 'accepted',
-137 versusList = %s
-138 WHERE id = %s;
-139 """, (create_random_versus(), challenge_id))
-140 conn.commit()
-141 cur.close()
-142 status = "accepted" # Update status on success
-143 except (Exception, psycopg2.DatabaseError) as error:
-144 print(error)
-145 # Optionally, handle different types of exceptions differently
-146 finally:
-147 if conn is not None:
-148 conn.close()
-149 return status
- - -152#-----------------------------------------------------------------------
- -154# Decline a challenge
-155def decline_challenge(challenge_id):
-156 status = "database error" # Default status in case of error
-157 conn = None
-158 try:
-159 conn = psycopg2.connect(DATABASE_URL)
-160 cur = conn.cursor()
-161 cur.execute("UPDATE challenges SET status = 'declined' WHERE id = %s;", (challenge_id,))
-162 conn.commit()
-163 cur.close()
-164 status = "declined" # Update status on success
-165 except (Exception, psycopg2.DatabaseError) as error:
-166 print(error)
-167 finally:
-168 if conn is not None:
-169 conn.close()
-170 return status
- - -173def reset_challenges_id_sequence():
-174 conn = None
-175 try:
-176 conn = psycopg2.connect(DATABASE_URL)
-177 cur = conn.cursor()
-178 # Assuming the sequence name is 'challenges_id_seq'
-179 cur.execute("ALTER SEQUENCE challenges_id_seq RESTART WITH 1;")
-180 conn.commit() # Commit the change to make it permanent
-181 print("Challenges id sequence reset.")
-182 cur.execute("ALTER SEQUENCE matches_id_seq RESTART WITH 1;")
-183 conn.commit() # Commit the change to make it permanent
-184 print("Matches id sequence reset.")
-185 except (Exception, psycopg2.DatabaseError) as error:
-186 print(f"Error resetting challenges id sequence: {error}")
-187 finally:
-188 if conn is not None:
-189 conn.close()
- -191def get_user_challenges(user_id):
-192 conn = psycopg2.connect(DATABASE_URL) # Ensure DATABASE_URL is properly configured
-193 cur = conn.cursor()
-194 # Query for both challenges initiated by the user and challenges where the user is the challengee,
-195 # including whether each side has finished the challenge.
-196 cur.execute("""
-197 SELECT challenges.id, challenger_id, challengee_id, status, challenger_finished, challengee_finished
-198 FROM challenges
-199 WHERE (challenges.challenger_id = %s OR challenges.challengee_id = %s);
-200 """, (user_id, user_id))
-201 challenges = cur.fetchall()
-202 cur.close()
-203 conn.close()
- -205 # Initialize dictionaries to hold the two types of challenges
-206 user_challenges = {'initiated': [], 'received': []}
- -208 # Iterate through the results and categorize each challenge
-209 for challenge in challenges:
-210 # Add challenger_finished and challengee_finished to the dictionary
-211 if versus_database.get_winner(challenge[0]) is not None:
-212 challenge_dict = {
-213 "id": challenge[0],
-214 "challenger_id": challenge[1],
-215 "challengee_id": challenge[2],
-216 "status": challenge[3],
-217 "challenger_finished": challenge[4],
-218 "challengee_finished": challenge[5],
-219 "winner_id": versus_database.get_winner(challenge[0])
-220 }
-221 else:
-222 challenge_dict = {
-223 "id": challenge[0],
-224 "challenger_id": challenge[1],
-225 "challengee_id": challenge[2],
-226 "status": challenge[3],
-227 "challenger_finished": challenge[4],
-228 "challengee_finished": challenge[5],
-229 "winner_id": None
-230 }
-231 if challenge[1] == user_id: # User is the challenger
-232 user_challenges['initiated'].append(challenge_dict)
-233 else: # User is the challengee
-234 user_challenges['received'].append(challenge_dict)
- -236 return user_challenges
- -238def update_finish_status(challenge_id, user_id):
-239 conn = None
-240 try:
-241 conn = psycopg2.connect(DATABASE_URL)
-242 cur = conn.cursor()
- -244 # First, determine if the user is the challenger or the challengee for this challenge
-245 cur.execute('''
-246 SELECT challenger_id, challengee_id
-247 FROM challenges
-248 WHERE id = %s;
-249 ''', (challenge_id,))
- -251 result = cur.fetchone()
-252 if result is None:
-253 print("Challenge not found.")
-254 return
- -256 challenger_id, challengee_id = result
- -258 # Depending on whether the user is the challenger or the challengee,
-259 # update the corresponding finished column in the matches table
-260 if user_id == challenger_id:
-261 cur.execute('''
-262 UPDATE challenges
-263 SET challenger_finished = TRUE
-264 WHERE id = %s;
-265 ''', (challenge_id,))
-266 elif user_id == challengee_id:
-267 cur.execute('''
-268 UPDATE challenges
-269 SET challengee_finished = TRUE
-270 WHERE id = %s;
-271 ''', (challenge_id,))
-272 else:
-273 print("User is not part of this challenge.")
-274 return
- -276 conn.commit()
-277 print("Finish status updated successfully.")
-278 return {"status": "success"}
- -280 except (Exception, psycopg2.DatabaseError) as error:
-281 print(f"Error: {error}")
-282 finally:
-283 if conn is not None:
-284 conn.close()
- -286def check_finish_status(challenge_id):
-287 conn = None
-288 status = {"status": "unfinished"} # Default status
-289 try:
-290 conn = psycopg2.connect(DATABASE_URL)
-291 cur = conn.cursor()
- -293 # Query to check the finish status for both challenger and challengee
-294 cur.execute('''
-295 SELECT challenger_finished, challengee_finished
-296 FROM challenges
-297 WHERE id = %s;
-298 ''', (challenge_id,))
- -300 result = cur.fetchone()
-301 if result:
-302 challenger_finished, challengee_finished = result
-303 if challenger_finished and challengee_finished:
-304 status = {"status": "finished"}
-305 else:
-306 print("No match found with the given challenge_id.")
- -308 except (Exception, psycopg2.DatabaseError) as error:
-309 print(f"Error checking finish status: {error}")
-310 finally:
-311 if conn is not None:
-312 conn.close()
- -314 return status
- -316def get_challenge_participants(challenge_id):
-317 conn = None
-318 try:
-319 conn = psycopg2.connect(DATABASE_URL)
-320 cur = conn.cursor()
- -322 # SQL query to select challenger_id and challengee_id from the challenges table
-323 cur.execute('''
-324 SELECT challenger_id, challengee_id
-325 FROM challenges
-326 WHERE id = %s;
-327 ''', (challenge_id,))
- -329 result = cur.fetchone()
-330 if result:
-331 # Unpack the result
-332 challenger_id, challengee_id = result
-333 participants = {
-334 "challenger_id": challenger_id,
-335 "challengee_id": challengee_id
-336 }
-337 return participants
-338 else:
-339 print("No challenge found with the given ID.")
-340 return None
- -342 except (Exception, psycopg2.DatabaseError) as error:
-343 print(f"Database error: {error}")
-344 return None
-345 finally:
-346 if conn is not None:
-347 conn.close()
- -349#-----------------------------------------------------------------------
- -351def get_challenge_results(challenge_id):
-352 conn = None
-353 try:
-354 conn = psycopg2.connect(DATABASE_URL)
-355 cur = conn.cursor()
- -357 # Query to get challenger and challengee points for the given challenge ID
-358 cur.execute('''
-359 SELECT challenger_id, challengee_id, challenger_points, challengee_points, challenger_pic_points, challengee_pic_points
-360 FROM challenges
-361 WHERE id = %s;
-362 ''', (challenge_id,))
- -364 result = cur.fetchone()
-365 if result is None:
-366 print("Challenge not found.")
-367 return
- -369 challenger_id, challengee_id, challenger_points, challengee_points, challenger_pic_points, challengee_pic_points = result
- -371 # Determine the winner or if it's a tie
-372 if challenger_points > challengee_points:
-373 winner = challenger_id
-374 elif challengee_points > challenger_points:
-375 winner = challengee_id
-376 else:
-377 winner = "Tie"
- -379 # Return a dictionary with the results
-380 return {
-381 "winner": winner,
-382 "challenger_id": challenger_id,
-383 "challengee_id": challengee_id,
-384 "challenger_points": challenger_points,
-385 "challengee_points": challengee_points,
-386 "challenge_id": challenge_id,
-387 "challenger_pic_points": challenger_pic_points,
-388 "challengee_pic_points": challengee_pic_points,
-389 }
- -391 except (Exception, psycopg2.DatabaseError) as error:
-392 print(f"Error: {error}")
-393 return {"error": str(error)}
-394 finally:
-395 if conn is not None:
-396 conn.close()
- -398def create_random_versus():
-399 row_count = database.get_table_size('pictures')
- -401 # Generate 5 unique pseudo-random integers from 1 to row_count
-402 random_indices = random.sample(range(1, row_count + 1), 5)
- -404 return random_indices
- -406def get_random_versus(challenge_id):
-407 conn = None
-408 try:
-409 conn = psycopg2.connect(DATABASE_URL)
-410 cur = conn.cursor()
- -412 # Query to get the versusList for the given challenge ID
-413 cur.execute('''
-414 SELECT versusList
-415 FROM challenges
-416 WHERE id = %s;
-417 ''', (challenge_id,))
- -419 result = cur.fetchone()
-420 if result is None:
-421 print("Challenge not found.")
-422 return
- -424 versusList = result[0]
-425 return versusList
- -427 except (Exception, psycopg2.DatabaseError) as error:
-428 print(f"Error: {error}")
-429 return
-430 finally:
-431 if conn is not None:
-432 conn.close()
- -434def update_playbutton_status(challenge_id, user_id):
-435 conn = None
-436 try:
-437 conn = psycopg2.connect(DATABASE_URL)
-438 cur = conn.cursor()
- -440 # First, determine if the user is the challenger or the challengee for this challenge
-441 cur.execute('''
-442 SELECT challenger_id, challengee_id
-443 FROM challenges
-444 WHERE id = %s;
-445 ''', (challenge_id,))
- -447 result = cur.fetchone()
-448 if result is None:
-449 print("Challenge not found.")
-450 return
- -452 challenger_id, challengee_id = result
- -454 # Depending on whether the user is the challenger or the challengee,
-455 # update the corresponding finished column in the matches table
-456 if user_id == challenger_id:
-457 cur.execute('''
-458 UPDATE challenges
-459 SET playger_button_status = TRUE
-460 WHERE id = %s;
-461 ''', (challenge_id,))
-462 elif user_id == challengee_id:
-463 cur.execute('''
-464 UPDATE challenges
-465 SET playgee_button_status = TRUE
-466 WHERE id = %s;
-467 ''', (challenge_id,))
-468 else:
-469 print("User is not part of this challenge.")
-470 return
- -472 conn.commit()
-473 print("Play button status updated successfully.")
- -475 except (Exception, psycopg2.DatabaseError) as error:
-476 print(f"Error: {error}")
-477 finally:
-478 if conn is not None:
-479 conn.close()
- -481def get_playbutton_status(challenge_id, user_id):
-482 conn = None
-483 try:
-484 conn = psycopg2.connect(DATABASE_URL)
-485 cur = conn.cursor()
- -487 # First, determine if the user is the challenger or the challengee for this challenge
-488 cur.execute('''
-489 SELECT challenger_id, challengee_id
-490 FROM challenges
-491 WHERE id = %s;
-492 ''', (challenge_id,))
- -494 result = cur.fetchone()
-495 if result is None:
-496 print("Challenge not found.")
-497 return
- -499 challenger_id, challengee_id = result
- -501 # Depending on whether the user is the challenger or the challengee,
-502 # update the corresponding finished column in the matches table
-503 if user_id == challenger_id:
-504 cur.execute('''
-505 SELECT playger_button_status
-506 FROM challenges
-507 WHERE id = %s;
-508 ''', (challenge_id,))
-509 elif user_id == challengee_id:
-510 cur.execute('''
-511 SELECT playgee_button_status
-512 FROM challenges
-513 WHERE id = %s;
-514 ''', (challenge_id,))
-515 else:
-516 print("User is not part of this challenge.")
-517 return
- -519 result = cur.fetchone()
-520 if result is not None:
-521 return result[0]
-522 else:
-523 print("No results found.")
-524 return None
- -526 except (Exception, psycopg2.DatabaseError) as error:
-527 print(f"Error: {error}")
-528 finally:
-529 if conn is not None:
-530 conn.close()
- -532def main():
-533 #clear_challenges_table()
-534 #reset_challenges_id_sequence()
-535 print()
-536 create_challenge('a', 'ed8205')
-537 update_finish_status(1, 'a')
- -539if __name__=="__main__":
-540 main()
-- coverage.py v7.5.1, - created at 2024-05-04 12:59 -0400 -
-| File | -class | -statements | -missing | -excluded | -coverage | -
|---|---|---|---|---|---|
| admin.py | -(no class) | -64 | -0 | -0 | -100% | -
| auth.py | -(no class) | -10 | -0 | -0 | -100% | -
| challenges_database.py | -(no class) | -24 | -1 | -0 | -96% | -
| cloud.py | -(no class) | -6 | -1 | -0 | -83% | -
| daily_user_database.py | -(no class) | -21 | -1 | -0 | -95% | -
| database.py | -(no class) | -11 | -1 | -0 | -91% | -
| distance_func.py | -(no class) | -7 | -1 | -0 | -86% | -
| matches_database.py | -(no class) | -8 | -1 | -0 | -88% | -
| pictures_database.py | -(no class) | -17 | -1 | -0 | -94% | -
| points.py | -(no class) | -9 | -1 | -0 | -89% | -
| runserver.py | -(no class) | -6 | -0 | -0 | -100% | -
| user_database.py | -(no class) | -14 | -1 | -0 | -93% | -
| versus_database.py | -(no class) | -12 | -1 | -0 | -92% | -
| Total | -- | 209 | -10 | -0 | -95% | -
- No items found using the specified filter. -
-- « prev - ^ index - » next - - coverage.py v7.5.1, - created at 2024-05-04 12:59 -0400 -
- -1#-----------------------------------------------------------------------
-2# cloud.py
-3#-----------------------------------------------------------------------
- -5import cloudinary.api
-6import json
- -8#-----------------------------------------------------------------------
- -10# extracts the url, latitude, longitude, and place metadata from
-11# each image in the cloudinary folder
-12def image_data(resource):
-13 url = resource['url']
-14 custom_metadata = resource.get('context', {}).get('custom', {})
-15 latitude = float(custom_metadata.get('Latitude'))
-16 longitude = float(custom_metadata.get('Longitude'))
-17 place = custom_metadata.get('Place')
-18 return url, latitude, longitude, place
- -20#-----------------------------------------------------------------------
- -22def main():
- -24 # configures and connects to cloudinary account
-25 cloudinary.config(
-26 cloud_name = 'dmiaxw4rr',
-27 api_key = '678414952824331',
-28 api_secret = 'wt-aWFLd0n-CelO5kN8h1NCYFzY'
-29 )
- -31 # name of folder to extract resources from
-32 folder_name = 'TigerSpot/Checked'
- -34 # extracts all resources from folder
-35 resources = cloudinary.api.resources(
-36 type = 'upload',
-37 prefix = folder_name,
-38 max_results = 500,
-39 context = True
-40 )
- -42 # extracts and writes all image data to picturedata.txt
-43 with open('picturedata.txt', 'w') as f:
-44 for resource in resources.get('resources', []):
-45 url, latitude, longitude, place = image_data(resource)
-46 f.write(f"{place}\n")
-47 f.write(f"{latitude}, {longitude}\n")
-48 f.write(url + '\n\n')
- -50 print("TigerSpot's image data saved to picturedata.txt")
- -52if __name__=="__main__":
-53 main()
- - -- « prev - ^ index - » next - - coverage.py v7.5.1, - created at 2024-05-04 12:59 -0400 -
- -1#-----------------------------------------------------------------------
-2# daily_user_database.py
-3#-----------------------------------------------------------------------
- -5import psycopg2
-6import database
- -8#-----------------------------------------------------------------------
- -10DATABASE_URL = 'postgres://tigerspot_user:9WtP1U9PRdh1VLlP4VdwnT0BFSdbrPWk@dpg-cnrjs7q1hbls73e04390-a.ohio-postgres.render.com/tigerspot'
- -12#-----------------------------------------------------------------------
- -14# Creates usersDaily table with columns username, points, distance,
-15# played, last_played, last_versus, and current streak.
- -17def create_daily_user_table():
- -19 try:
-20 with psycopg2.connect(DATABASE_URL) as conn:
-21 with conn.cursor() as cur:
-22 cur.execute('''CREATE TABLE IF NOT EXISTS usersDaily (
-23 username varchar(255),
-24 points int,
-25 distance int,
-26 played boolean,
-27 last_played date,
-28 last_versus date,
-29 current_streak int);''')
-30 conn.commit()
- -32 except (Exception, psycopg2.DatabaseError) as error:
-33 print(error)
-34 return "database error"
- -36#-----------------------------------------------------------------------
- -38# Inserts username into usersDaily table.
- -40def insert_player_daily(username):
- -42 try:
-43 with psycopg2.connect(DATABASE_URL) as conn:
-44 with conn.cursor() as cur:
- -46 cur.execute("SELECT points FROM usersDaily WHERE username=%s;", (username,))
-47 result = cur.fetchone()
- -49 if result is None:
-50 cur.execute("INSERT INTO usersDaily (username, points, distance, played, last_played, last_versus, current_streak) VALUES (%s, %s, %s, %s, NULL, NULL, %s);", (username, 0, 0, False, 0))
- -52 conn.commit()
- -54 return "success"
- -56 except (Exception, psycopg2.DatabaseError) as error:
-57 print(error)
-58 return "database error"
- - -61#-----------------------------------------------------------------------
- -63# Updates username's daily stats with new points and distance.
-64# Updates that username has played at current date and updates streaks.
- -66def update_player_daily(username, points, distance):
- -68 try:
-69 with psycopg2.connect(DATABASE_URL) as conn:
-70 with conn.cursor() as cur:
- -72 cur.execute("SET TIME ZONE 'America/New_York';")
- -74 cur.execute('''UPDATE usersDaily
-75 SET
-76 points=%s,
-77 distance=%s,
-78 played=%s,
-79 current_streak = CASE
-80 WHEN last_played IS NULL THEN 1
-81 WHEN last_played::date = (CURRENT_DATE - INTERVAL '1 day')::date THEN current_streak + 1
-82 ELSE 1
-83 END,
-84 last_played= CURRENT_DATE
-85 WHERE username=%s;''', (points, distance, True, username))
-86 conn.commit()
- -88 return "success"
- -90 except (Exception, psycopg2.DatabaseError) as error:
-91 print(error)
-92 return "database error"
- -94#-----------------------------------------------------------------------
- -96# Updates username's last_versus to current date.
- -98def update_player_versus(username):
- -100 try:
-101 with psycopg2.connect(DATABASE_URL) as conn:
-102 with conn.cursor() as cur:
- -104 cur.execute("SET TIME ZONE 'America/New_York';")
- -106 cur.execute('''UPDATE usersDaily
-107 SET
-108 last_versus= CURRENT_DATE
-109 WHERE username=%s;''', (username, ))
-110 conn.commit()
-111 print(f"UPDATED VERSUS DATE IN DAILY")
- -113 return "success"
- -115 except (Exception, psycopg2.DatabaseError) as error:
-116 print(error)
-117 return "database error"
- -119#-----------------------------------------------------------------------
- -121# Returns whether username has played for the day or not.
- -123def player_played(username):
- -125 try:
-126 with psycopg2.connect(DATABASE_URL) as conn:
-127 with conn.cursor() as cur:
- -129 cur.execute("SELECT played FROM usersDaily WHERE username=%s;", (username, ))
-130 result = cur.fetchall()[0][0]
- -132 return result
- -134 except (Exception, psycopg2.DatabaseError) as error:
-135 print(error)
-136 return "database error"
- - -139#-----------------------------------------------------------------------
- -141# Resets the user's daily points, distance, and if they have played.
- -143def reset_player(username):
- -145 try:
-146 with psycopg2.connect(DATABASE_URL) as conn:
-147 with conn.cursor() as cur:
-148 cur.execute("UPDATE usersDaily SET played=%s, points=%s, distance=%s WHERE username=%s;", (False, 0, 0, username))
-149 print(f"Player {username} has been reset for the daily round")
-150 conn.commit()
- -152 return "success"
- -154 except (Exception, psycopg2.DatabaseError) as error:
-155 print(error)
-156 return "database error"
- -158#-----------------------------------------------------------------------
- -160# Resets all players' daily points, distance, and if they have played.
- -162def reset_players():
- -164 try:
-165 with psycopg2.connect(DATABASE_URL) as conn:
-166 with conn.cursor() as cur:
-167 cur.execute("UPDATE usersDaily SET played=%s, points=%s, distance=%s, last_played=NULL, current_streak = %s;", (False, 0, 0, 0))
-168 conn.commit()
- -170 return "success"
- -172 except (Exception, psycopg2.DatabaseError) as error:
-173 print(error)
-174 return "database error"
- -176#-----------------------------------------------------------------------
- -178# Returns the date when the username last played.
- -180def get_last_played_date(username):
- -182 try:
-183 with psycopg2.connect(DATABASE_URL) as conn:
-184 with conn.cursor() as cur:
-185 cur.execute('''SELECT last_played FROM usersDaily WHERE username=%s;''', (username,))
-186 date = cur.fetchone()
- -188 if date is None:
-189 return 0
- -191 return date[0]
- -193 except (Exception, psycopg2.DatabaseError) as error:
-194 print(error)
-195 return "database error"
- -197#-----------------------------------------------------------------------
- -199# Returns the date when the username last used the versus mode.
- -201def get_last_versus_date(username):
- -203 try:
-204 with psycopg2.connect(DATABASE_URL) as conn:
-205 with conn.cursor() as cur:
-206 cur.execute('''SELECT last_versus FROM usersDaily WHERE username=%s;''', (username,))
-207 date = cur.fetchone()
- -209 if date is None:
-210 return 0
- -212 return date[0]
- -214 except (Exception, psycopg2.DatabaseError) as error:
-215 print(error)
-216 return "database error"
- -218#-----------------------------------------------------------------------
- -220# Returns username's streak.
- -222def get_streak(username):
- -224 try:
-225 with psycopg2.connect(DATABASE_URL) as conn:
-226 with conn.cursor() as cur:
-227 cur.execute('''SELECT current_streak FROM usersDaily WHERE username=%s;''', (username,))
-228 streak = cur.fetchone()
- -230 if streak is None:
-231 return 0
- -233 return streak[0]
- -235 except (Exception, psycopg2.DatabaseError) as error:
-236 print(error)
-237 return "database error"
- -239#-----------------------------------------------------------------------
- -241# Returns username's daily points.
- -243def get_daily_points(username):
- -245 try:
-246 with psycopg2.connect(DATABASE_URL) as conn:
-247 with conn.cursor() as cur:
-248 cur.execute('''SELECT points FROM usersDaily WHERE username=%s;''', (username,))
-249 points = cur.fetchone()
- -251 if points is None:
-252 return 0
- -254 return points[0]
- -256 except (Exception, psycopg2.DatabaseError) as error:
-257 print(error)
-258 return "database error"
- -260#-----------------------------------------------------------------------
- -262# Returns username's guess distance.
- -264def get_daily_distance(username):
- -266 try:
-267 with psycopg2.connect(DATABASE_URL) as conn:
-268 with conn.cursor() as cur:
-269 cur.execute('''SELECT distance FROM usersDaily WHERE username=%s;''', (username,))
-270 distance = cur.fetchone()
- -272 if distance is None:
-273 return 0
- -275 return distance[0]
- -277 except (Exception, psycopg2.DatabaseError) as error:
-278 print(error)
-279 return "database error"
- -281#-----------------------------------------------------------------------
- -283# Returns a dictionary of the usernames and points of the the top 10
-284# scoring players for the day.
- -286def get_daily_top_players():
- -288 try:
-289 with psycopg2.connect(DATABASE_URL) as conn:
-290 with conn.cursor() as cur:
-291 daily_top_players = []
-292 cur.execute("SET TIME ZONE 'America/New_York';")
-293 cur.execute("SELECT username, points FROM usersDaily WHERE last_played = CURRENT_DATE ORDER BY points DESC, username ASC LIMIT 10;")
-294 table = cur.fetchall()
-295 for row in table:
-296 username, points = row
-297 player_stats = {'username': username, 'points': points}
-298 daily_top_players.append(player_stats)
- -300 return daily_top_players
- -302 except (Exception, psycopg2.DatabaseError) as error:
-303 print(error)
-304 return "database error"
- -306#-----------------------------------------------------------------------
- -308# Returns username's daily rank among all players who played for the day.
- -310def get_daily_rank(username):
- -312 try:
-313 with psycopg2.connect(DATABASE_URL) as conn:
-314 with conn.cursor() as cur:
-315 cur.execute("SET TIME ZONE 'America/New_York';")
-316 cur.execute("SELECT username, points, DENSE_RANK() OVER (ORDER BY points DESC, username ASC) as rank FROM usersDaily WHERE last_played = CURRENT_DATE;")
-317 players = cur.fetchall()
- -319 for player in players:
-320 if player[0] == username:
-321 return player[2]
-322 return "Play Today's Game!"
- -324 except (Exception, psycopg2.DatabaseError) as error:
-325 print(error)
-326 return "database error"
- -328#-----------------------------------------------------------------------
- -330# Removes username from the usersDaily table.
- -332def remove_daily_user(username):
-333 try:
-334 with psycopg2.connect(DATABASE_URL) as conn:
-335 with conn.cursor() as cur:
- -337 cur.execute("DELETE FROM usersDaily WHERE username=%s;", (username,))
-338 conn.commit()
- -340 return "success"
- -342 except (Exception, psycopg2.DatabaseError) as error:
-343 print(error)
-344 return "database error"
- -346#-----------------------------------------------------------------------
- -348def main():
- -350 #database.drop_table("usersDaily")
-351 # update_player_daily('wn4759', 100, 30)
-352 #reset_player('cl7359')
-353 #reset_player('jy3107')
-354 #reset_player('fl9971')
-355 #print(get_last_played_date('fl9971'))
-356 #reset_player('wn4759')
-357 #reset_player('ed8205')
-358 # remove_daily_user('fl9971')
-359 #reset_player('jy1365')
-360 #create_daily_user_table()
-361 date = get_last_played_date('fl9971')
-362 # print(date)
-363 # streak = get_streak('fl9971')
-364 # print(streak)
-365 # date1 = get_last_played_date('cl7359')
-366 # print(date1)
- -368 # print(get_last_versus_date('wn4759'))
-369 #update_player_versus('wn4759')
- -371 #remove_daily_user('wn4759')
- -373#-----------------------------------------------------------------------
- -375if __name__=="__main__":
- -377 main()
-- « prev - ^ index - » next - - coverage.py v7.5.1, - created at 2024-05-04 12:59 -0400 -
- -1#-----------------------------------------------------------------------
-2# database.py
-3# This file is for general actions with tables
-4# Tables in Tiger Spot: pictures, users, usersDaily, challenges, matches
-5#-----------------------------------------------------------------------
-6import psycopg2
-7#-----------------------------------------------------------------------
- -9DATABASE_URL = 'postgres://tigerspot_user:9WtP1U9PRdh1VLlP4VdwnT0BFSdbrPWk@dpg-cnrjs7q1hbls73e04390-a.ohio-postgres.render.com/tigerspot'
- -11#-----------------------------------------------------------------------
-12#drops a specified table
-13def drop_table(table):
-14 try:
-15 with psycopg2.connect(DATABASE_URL) as conn:
-16 with conn.cursor() as cur:
-17 cur.execute("DROP TABLE %s;" % (table))
-18 conn.commit()
-19 print(f"{table} has been dropped")
-20 except (Exception, psycopg2.DatabaseError) as error:
-21 print(error)
-22 return "database error"
- -24#updates a specific row in a table
-25#id_type can be pictureID or challenge_id for example
-26def update(table, col, value, id_type, id_num):
-27 try:
-28 with psycopg2.connect(DATABASE_URL) as conn:
-29 with conn.cursor() as cur:
-30 cur.execute("UPDATE %s SET %s = %s WHERE %s = %s;" % (table, col, value, id_type, id_num))
-31 print(f"Updated with value as {value}")
-32 conn.commit()
-33 except (Exception, psycopg2.DatabaseError) as error:
-34 print(error)
-35 return "database error"
- -37#returns all the values from a specified column in a table in the form of an array of tuples
-38def query(column, table):
-39 try:
-40 with psycopg2.connect(DATABASE_URL) as conn:
-41 with conn.cursor() as cur:
-42 cur.execute("SELECT %s FROM %s" % (column, table))
-43 rows = cur.fetchall()
-44 print(f"Returning values in column '{column}' from table '{table}'")
-45 return rows
-46 except (Exception, psycopg2.DatabaseError) as error:
-47 print(error)
-48 return "database error"
- -50#Returns the number of rows in a table
-51def get_table_size(table):
-52 try:
-53 with psycopg2.connect(DATABASE_URL) as conn:
-54 with conn.cursor() as cur:
-55 cur.execute("SELECT COUNT(*) FROM %s;" % (table))
-56 print(f"Returning number of rows in table '{table}'")
-57 result = cur.fetchone()
-58 pic_num = result[0]
-59 return pic_num
-60 except (Exception, psycopg2.DatabaseError) as error:
-61 print(error)
-62 return "database error"
- -64#prints out all rows in the users, usersDaily, pictures, challenges, and matches tables
-65def show_rows():
-66 print("Showing all rows in users, usersDaily, pictures, challenges, and matches tables")
-67 print()
-68 print("USERS TABLE")
-69 print(query("*", "users"))
-70 print()
-71 print("DAILY USERS TABLE")
-72 print(query("*", "usersDaily"))
-73 print()
-74 print("PICTURES TABLE")
-75 print(query("*", "pictures"))
-76 print()
-77 print("CHALLENGES TABLE")
-78 print(query("*", "challenges"))
-79 print()
-80 print("MATCHES TABLE")
-81 print(query("*", "matches"))
-82 print()
- -84#-----------------------------------------------------------------------
-85#tests the above functions that do not commit changes to the tables
-86def testing():
-87 print('-----Testing query()-----')
-88 print(query('pictureID', 'pictures'))
-89 print(query('place', 'pictures'))
-90 print()
-91 print('-----Testing get_table_size()-----')
-92 print(get_table_size('pictures'))
-93 print(get_table_size('users'))
-94 print(get_table_size('usersDaily'))
-95 print(get_table_size('challenges'))
-96 print(get_table_size('matches'))
-97 print()
-98 print('-----Testing show_rows()-----')
-99 show_rows()
- -101def main():
-102 testing()
- -104if __name__=="__main__":
-105 main()
- - - - -- « prev - ^ index - » next - - coverage.py v7.5.1, - created at 2024-05-04 12:59 -0400 -
- -1#-----------------------------------------------------------------------
-2# distance_func.py
-3# This file contains functions relating distance calculation
-4#-----------------------------------------------------------------------
-5import psycopg2
-6from geopy.distance import geodesic
- -8DATABASE_URL = 'postgres://tigerspot_user:9WtP1U9PRdh1VLlP4VdwnT0BFSdbrPWk@dpg-cnrjs7q1hbls73e04390-a.ohio-postgres.render.com/tigerspot'
-9#-----------------------------------------------------------------------
- -11#Using the geopy library, we calculate the distance between two coordinates using the Haversine formula
-12#Measuring in meters
-13def calc_distance(lat1, lon1, coor2):
-14 coor1 = (lat1, lon1)
-15 distance = geodesic(coor1, coor2).meters
-16 return distance
- -18def main():
-19 #testing that calc_distance() calculates correct distance
-20 expected_distance = 751 #estimation using calculator
-21 calculated_distance = calc_distance(40.3487 , -74.6593, (40.3421, -74.6612))
-22 print("Expected distance:", expected_distance)
-23 print("Calculated distance:", calculated_distance)
- -25 if(abs(expected_distance - calculated_distance) > 2):
-26 print("Error with distance calculation")
- - -29if __name__=="__main__":
-30 main()
-- coverage.py v7.5.1, - created at 2024-05-04 12:59 -0400 -
-| File | -function | -statements | -missing | -excluded | -coverage | -
|---|---|---|---|---|---|
| admin.py | -database_check | -3 | -3 | -0 | -0% | -
| admin.py | -reset_versus | -7 | -7 | -0 | -0% | -
| admin.py | -sam | -3 | -3 | -0 | -0% | -
| admin.py | -logoutapp | -1 | -1 | -0 | -0% | -
| admin.py | -logoutcas | -1 | -1 | -0 | -0% | -
| admin.py | -index | -3 | -3 | -0 | -0% | -
| admin.py | -menu | -20 | -20 | -0 | -0% | -
| admin.py | -requests | -19 | -19 | -0 | -0% | -
| admin.py | -game | -19 | -19 | -0 | -0% | -
| admin.py | -submit | -29 | -29 | -0 | -0% | -
| admin.py | -rules | -4 | -4 | -0 | -0% | -
| admin.py | -team | -4 | -4 | -0 | -0% | -
| admin.py | -leaderboard | -13 | -13 | -0 | -0% | -
| admin.py | -totalleaderboard | -13 | -13 | -0 | -0% | -
| admin.py | -versus_func | -8 | -8 | -0 | -0% | -
| admin.py | -create_challenge_route | -13 | -13 | -0 | -0% | -
| admin.py | -accept_challenge_route | -10 | -10 | -0 | -0% | -
| admin.py | -decline_challenge_route | -10 | -10 | -0 | -0% | -
| admin.py | -play_button | -16 | -16 | -0 | -0% | -
| admin.py | -start_challenge | -12 | -12 | -0 | -0% | -
| admin.py | -end_challenge | -11 | -11 | -0 | -0% | -
| admin.py | -submit2 | -60 | -60 | -0 | -0% | -
| admin.py | -versus_stats | -7 | -7 | -0 | -0% | -
| admin.py | -(no function) | -64 | -0 | -0 | -100% | -
| auth.py | -strip_ticket | -5 | -5 | -0 | -0% | -
| auth.py | -validate | -11 | -11 | -0 | -0% | -
| auth.py | -authenticate | -13 | -13 | -0 | -0% | -
| auth.py | -logoutapp | -4 | -4 | -0 | -0% | -
| auth.py | -logoutcas | -2 | -2 | -0 | -0% | -
| auth.py | -(no function) | -10 | -0 | -0 | -100% | -
| challenges_database.py | -create_challenges_table | -6 | -6 | -0 | -0% | -
| challenges_database.py | -clear_challenges_table | -20 | -20 | -0 | -0% | -
| challenges_database.py | -clear_user_challenges | -15 | -15 | -0 | -0% | -
| challenges_database.py | -create_challenge | -18 | -18 | -0 | -0% | -
| challenges_database.py | -accept_challenge | -14 | -14 | -0 | -0% | -
| challenges_database.py | -decline_challenge | -14 | -14 | -0 | -0% | -
| challenges_database.py | -reset_challenges_id_sequence | -14 | -14 | -0 | -0% | -
| challenges_database.py | -get_user_challenges | -15 | -15 | -0 | -0% | -
| challenges_database.py | -update_finish_status | -23 | -23 | -0 | -0% | -
| challenges_database.py | -check_finish_status | -17 | -17 | -0 | -0% | -
| challenges_database.py | -get_challenge_participants | -17 | -17 | -0 | -0% | -
| challenges_database.py | -get_challenge_results | -21 | -21 | -0 | -0% | -
| challenges_database.py | -create_random_versus | -3 | -3 | -0 | -0% | -
| challenges_database.py | -get_random_versus | -16 | -16 | -0 | -0% | -
| challenges_database.py | -update_playbutton_status | -22 | -22 | -0 | -0% | -
| challenges_database.py | -get_playbutton_status | -25 | -25 | -0 | -0% | -
| challenges_database.py | -main | -3 | -3 | -0 | -0% | -
| challenges_database.py | -(no function) | -24 | -1 | -0 | -96% | -
| cloud.py | -image_data | -6 | -6 | -0 | -0% | -
| cloud.py | -main | -10 | -10 | -0 | -0% | -
| cloud.py | -(no function) | -6 | -1 | -0 | -83% | -
| daily_user_database.py | -create_daily_user_table | -8 | -8 | -0 | -0% | -
| daily_user_database.py | -insert_player_daily | -12 | -12 | -0 | -0% | -
| daily_user_database.py | -update_player_daily | -10 | -10 | -0 | -0% | -
| daily_user_database.py | -update_player_versus | -11 | -11 | -0 | -0% | -
| daily_user_database.py | -player_played | -9 | -9 | -0 | -0% | -
| daily_user_database.py | -reset_player | -10 | -10 | -0 | -0% | -
| daily_user_database.py | -reset_players | -9 | -9 | -0 | -0% | -
| daily_user_database.py | -get_last_played_date | -11 | -11 | -0 | -0% | -
| daily_user_database.py | -get_last_versus_date | -11 | -11 | -0 | -0% | -
| daily_user_database.py | -get_streak | -11 | -11 | -0 | -0% | -
| daily_user_database.py | -get_daily_points | -11 | -11 | -0 | -0% | -
| daily_user_database.py | -get_daily_distance | -11 | -11 | -0 | -0% | -
| daily_user_database.py | -get_daily_top_players | -15 | -15 | -0 | -0% | -
| daily_user_database.py | -get_daily_rank | -13 | -13 | -0 | -0% | -
| daily_user_database.py | -remove_daily_user | -9 | -9 | -0 | -0% | -
| daily_user_database.py | -main | -1 | -1 | -0 | -0% | -
| daily_user_database.py | -(no function) | -21 | -1 | -0 | -95% | -
| database.py | -drop_table | -9 | -9 | -0 | -0% | -
| database.py | -update | -9 | -9 | -0 | -0% | -
| database.py | -query | -10 | -10 | -0 | -0% | -
| database.py | -get_table_size | -11 | -11 | -0 | -0% | -
| database.py | -show_rows | -17 | -17 | -0 | -0% | -
| database.py | -testing | -13 | -13 | -0 | -0% | -
| database.py | -main | -1 | -1 | -0 | -0% | -
| database.py | -(no function) | -11 | -1 | -0 | -91% | -
| distance_func.py | -calc_distance | -3 | -3 | -0 | -0% | -
| distance_func.py | -main | -6 | -6 | -0 | -0% | -
| distance_func.py | -(no function) | -7 | -1 | -0 | -86% | -
| matches_database.py | -create_matches_table | -6 | -6 | -0 | -0% | -
| matches_database.py | -clear_matches_table | -11 | -11 | -0 | -0% | -
| matches_database.py | -complete_match | -14 | -14 | -0 | -0% | -
| matches_database.py | -main | -1 | -1 | -0 | -0% | -
| matches_database.py | -(no function) | -8 | -1 | -0 | -88% | -
| pictures_database.py | -create_pic_table | -21 | -21 | -0 | -0% | -
| pictures_database.py | -insert_picture | -9 | -9 | -0 | -0% | -
| pictures_database.py | -get_current_date | -4 | -4 | -0 | -0% | -
| pictures_database.py | -pic_of_day | -4 | -4 | -0 | -0% | -
| pictures_database.py | -get_pic_info | -10 | -10 | -0 | -0% | -
| pictures_database.py | -main | -10 | -10 | -0 | -0% | -
| pictures_database.py | -(no function) | -17 | -1 | -0 | -94% | -
| points.py | -calculate_today_points | -9 | -9 | -0 | -0% | -
| points.py | -calculate_total_points | -2 | -2 | -0 | -0% | -
| points.py | -test_point_distribution | -1 | -1 | -0 | -0% | -
| points.py | -main | -10 | -10 | -0 | -0% | -
| points.py | -(no function) | -9 | -1 | -0 | -89% | -
| runserver.py | -main | -12 | -6 | -0 | -50% | -
| runserver.py | -(no function) | -6 | -0 | -0 | -100% | -
| user_database.py | -create_user_table | -8 | -8 | -0 | -0% | -
| user_database.py | -insert_player | -12 | -12 | -0 | -0% | -
| user_database.py | -reset_player_total_points | -13 | -13 | -0 | -0% | -
| user_database.py | -update_player | -9 | -9 | -0 | -0% | -
| user_database.py | -get_points | -9 | -9 | -0 | -0% | -
| user_database.py | -get_rank | -12 | -12 | -0 | -0% | -
| user_database.py | -get_top_players | -14 | -14 | -0 | -0% | -
| user_database.py | -remove_from_user_table | -9 | -9 | -0 | -0% | -
| user_database.py | -get_players | -10 | -10 | -0 | -0% | -
| user_database.py | -main | -1 | -1 | -0 | -0% | -
| user_database.py | -(no function) | -14 | -1 | -0 | -93% | -
| versus_database.py | -update_versus_points | -23 | -23 | -0 | -0% | -
| versus_database.py | -calculate_versus | -9 | -9 | -0 | -0% | -
| versus_database.py | -get_winner | -13 | -13 | -0 | -0% | -
| versus_database.py | -update_versus_pic_status | -23 | -23 | -0 | -0% | -
| versus_database.py | -get_versus_pic_status | -25 | -25 | -0 | -0% | -
| versus_database.py | -store_versus_pic_points | -23 | -23 | -0 | -0% | -
| versus_database.py | -store_versus_pic_points | -23 | -23 | -0 | -0% | -
| versus_database.py | -main | -1 | -1 | -0 | -0% | -
| versus_database.py | -(no function) | -12 | -1 | -0 | -92% | -
| Total | -- | 1411 | -1206 | -0 | -15% | -
- No items found using the specified filter. -
-- coverage.py v7.5.1, - created at 2024-05-04 12:59 -0400 -
-| File | -statements | -missing | -excluded | -coverage | -
|---|---|---|---|---|
| admin.py | -350 | -286 | -0 | -18% | -
| auth.py | -45 | -35 | -0 | -22% | -
| challenges_database.py | -287 | -264 | -0 | -8% | -
| cloud.py | -22 | -17 | -0 | -23% | -
| daily_user_database.py | -183 | -163 | -0 | -11% | -
| database.py | -81 | -71 | -0 | -12% | -
| distance_func.py | -16 | -10 | -0 | -38% | -
| matches_database.py | -40 | -33 | -0 | -18% | -
| pictures_database.py | -75 | -59 | -0 | -21% | -
| points.py | -31 | -23 | -0 | -26% | -
| runserver.py | -18 | -6 | -0 | -67% | -
| user_database.py | -111 | -98 | -0 | -12% | -
| versus_database.py | -152 | -141 | -0 | -7% | -
| Total | -1411 | -1206 | -0 | -15% | -
- No items found using the specified filter. -
-- « prev - ^ index - » next - - coverage.py v7.5.1, - created at 2024-05-04 12:59 -0400 -
- -1import psycopg2
- -3DATABASE_URL = 'postgres://tigerspot_user:9WtP1U9PRdh1VLlP4VdwnT0BFSdbrPWk@dpg-cnrjs7q1hbls73e04390-a.ohio-postgres.render.com/tigerspot'
- - -6#dont run again
-7def create_matches_table():
-8 conn = psycopg2.connect(DATABASE_URL)
-9 cur = conn.cursor()
-10 cur.execute('''CREATE TABLE IF NOT EXISTS matches (
-11 id SERIAL PRIMARY KEY,
-12 challenge_id INTEGER,
-13 winner_id VARCHAR(255),
-14 challenger_score INTEGER,
-15 challengee_score INTEGER);''')
-16 conn.commit()
-17 cur.close()
-18 conn.close()
- -20#-----------------------------------------------------------------------
- -22def clear_matches_table():
-23 conn = None
-24 try:
-25 conn = psycopg2.connect(DATABASE_URL)
-26 cur = conn.cursor()
-27 # Deletes all records from the matches table
-28 cur.execute("DELETE FROM matches;")
-29 conn.commit() # Commit the transaction to make changes permanent
-30 print("Matches table cleared.")
-31 except (Exception, psycopg2.DatabaseError) as error:
-32 print(f"Error clearing matches table: {error}")
-33 finally:
-34 if conn is not None:
-35 conn.close()
- - -38# Complete a match
-39def complete_match(challenge_id, winner_id, challenger_score, challengee_score):
-40 conn = None
-41 try:
-42 conn = psycopg2.connect(DATABASE_URL)
-43 cur = conn.cursor()
-44 cur.execute("UPDATE challenges SET status = 'completed' WHERE id = %s;", (challenge_id,))
-45 cur.execute("INSERT INTO matches (challenge_id, winner_id, challenger_score, challengee_score) VALUES (%s, %s, %s, %s) RETURNING id;", (challenge_id, winner_id, challenger_score, challengee_score))
-46 match_id = cur.fetchone()[0]
-47 conn.commit()
-48 cur.close()
-49 print(f"Match completed with ID: {match_id}")
-50 except (Exception, psycopg2.DatabaseError) as error:
-51 print(error)
-52 finally:
-53 if conn is not None:
-54 conn.close()
- -56def main():
-57 #clear_matches_table()
-58 print()
- -60if __name__=="__main__":
-61 main()
-- « prev - ^ index - » next - - coverage.py v7.5.1, - created at 2024-05-04 12:59 -0400 -
- -1#-----------------------------------------------------------------------
-2# pictures_database.py
-3#-----------------------------------------------------------------------
- -5import psycopg2
-6import datetime
-7import cloudinary
-8import cloudinary.api
-9import cloud
-10import database
-11import pytz
-12import daily_user_database
- -14#-----------------------------------------------------------------------
- -16DATABASE_URL = 'postgres://tigerspot_user:9WtP1U9PRdh1VLlP4VdwnT0BFSdbrPWk@dpg-cnrjs7q1hbls73e04390-a.ohio-postgres.render.com/tigerspot'
- -18#-----------------------------------------------------------------------
- -20# Creates pictures database table
-21def create_pic_table():
- -23 try:
-24 with psycopg2.connect(DATABASE_URL) as conn:
-25 with conn.cursor() as cur:
- -27 cur.execute('''CREATE TABLE IF NOT EXISTS pictures (
-28 pictureID int,
-29 coordinates float[2],
-30 link varchar(255),
-31 place varchar(255));''')
- -33 # configures and connects to cloudinary account
-34 cloudinary.config(
-35 cloud_name = 'dmiaxw4rr',
-36 api_key = '678414952824331',
-37 api_secret = 'wt-aWFLd0n-CelO5kN8h1NCYFzY'
-38 )
- -40 # name of folder to extract resources from
-41 folder_name = 'TigerSpot/Checked'
- -43 # extracts all resources from folder
-44 resources = cloudinary.api.resources(
-45 type = 'upload',
-46 prefix = folder_name,
-47 max_results = 500,
-48 context = True
-49 )
- -51 pictureID = 0
- -53 # loops through folder and retrieves image url, coordinates, place, and sets pictureid per resource
-54 for resource in resources.get('resources', []):
-55 link, latitude, longitude, place = cloud.image_data(resource)
-56 coordinates = [latitude, longitude]
-57 cur.execute("SELECT * FROM pictures WHERE link = %s", (link,))
-58 exists = cur.fetchone()
-59 if not exists:
-60 pictureID += 1
-61 cur.execute('''INSERT INTO pictures (pictureID, coordinates, link, place)
-62 VALUES (%s, %s, %s, %s);''', (pictureID, coordinates, link, place))
- -64 conn.commit()
-65 print("Pictures database table created successfully.")
- -67 except (Exception, psycopg2.DatabaseError) as error:
-68 print(error)
-69 return "database error"
- -71# Inserts a new row into pictures database table
-72def insert_picture(pictureID, coordinates, link, place):
- -74 try:
-75 with psycopg2.connect(DATABASE_URL) as conn:
-76 with conn.cursor() as cur:
- -78 cur.execute('''INSERT INTO pictures (pictureID, coordinates, link)
-79 VALUES (%s, %s, %s);''', (pictureID, coordinates, link, place))
-80 conn.commit()
-81 print("Row inserted successfully.")
- -83 except (Exception, psycopg2.DatabaseError) as error:
-84 print(error)
-85 return "database error"
- -87#-----------------------------------------------------------------------
- -89# Returns the date based on eastern time zone
-90def get_current_date():
-91 eastern = pytz.timezone('America/New_York')
-92 eastern_timezone = datetime.datetime.now(eastern)
-93 eastern_date = eastern_timezone.date()
- -95 return eastern_date
- -97#-----------------------------------------------------------------------
- -99# Checks the current date and returns associated picture id
-100def pic_of_day():
- -102 eastern_date = get_current_date()
-103 day_of_year = eastern_date.timetuple().tm_yday
-104 picture_id = (day_of_year - 1) % database.get_table_size("pictures") + 1
- -106 return picture_id
- -108# Returns specified information of picture using its id
-109def get_pic_info(col, id):
- -111 try:
-112 with psycopg2.connect(DATABASE_URL) as conn:
-113 with conn.cursor() as cur:
- -115 cur.execute(f"SELECT {col} FROM pictures WHERE pictureID = {id}")
-116 rows = cur.fetchall()
-117 row = rows[0][0]
- -119 return row
- -121 except (Exception, psycopg2.DatabaseError) as error:
-122 print(error)
-123 return "database error"
- -125#-----------------------------------------------------------------------
- -127def main():
- -129 # create_pic_table()
- -131 current_date = get_current_date()
-132 today_id = pic_of_day()
-133 pic_place = get_pic_info("place", 1)
-134 pic_coords = get_pic_info("coordinates", 1)
-135 pic_url = get_pic_info("link", 1)
- -137 print(f"Current date: {current_date}")
- -139 print(f"Picture ID Today: {today_id}")
- -141 # Effron Music Building
-142 print(f"Place: {pic_place}")
- -144 # 40.342396, -74.659527
-145 print(f"Coordinates: {pic_coords}")
- -147 # http://res.cloudinary.com/dmiaxw4rr/image/upload/v1712640742/TigerSpot/Checked/91271FD2-F874-4AAE-B589-F6FD7BB0920B_1_201_a_r2hcfr.jpg
-148 print(f"URL: {pic_url}")
- -150if __name__=="__main__":
-151 main()
-- « prev - ^ index - » next - - coverage.py v7.5.1, - created at 2024-05-04 12:59 -0400 -
- -1#-----------------------------------------------------------------------
-2# points.py
-3#-----------------------------------------------------------------------
- -5import user_database
-6import daily_user_database
-7import math
- -9#-----------------------------------------------------------------------
- -11# Returns points based on distance from actual coordinates
-12def calculate_today_points(distance):
-13 if distance < 3:
-14 points = 1500
-15 elif distance < 6:
-16 points = 1250
-17 elif distance < 10:
-18 points = 1000
-19 else:
-20 distance -= 10
-21 points = max(0, 1 - distance / 100) * 1000
-22 return points
- -24# Returns a player's updated cummulative points after their daily guess
-25def calculate_total_points(username, today_points):
-26 points = today_points + user_database.get_points(username)
-27 return points
- -29#-----------------------------------------------------------------------
- -31def test_point_distribution(distance):
-32 print(f"If distance is {distance}, then points is", calculate_today_points(distance))
- -34#-----------------------------------------------------------------------
- -36def main():
- -38 test_point_distribution(0) # 1500
-39 test_point_distribution(3) # 1250
-40 test_point_distribution(6) # 1000
-41 test_point_distribution(10) # ~1000
-42 test_point_distribution(100) # ~100
-43 test_point_distribution(110) # 0
- -45 cummulative_points = calculate_total_points('wn4759', 0)
-46 print(cummulative_points)
-47 cummulative_points = calculate_total_points('wn4759', 1000)
-48 print(cummulative_points)
- -50if __name__=="__main__":
-51 main()
-- « prev - ^ index - » next - - coverage.py v7.5.1, - created at 2024-05-04 12:59 -0400 -
- -1#-----------------------------------------------------------------------
-2# runserver.py
-3# Runs Tiger Spot application
-4#-----------------------------------------------------------------------
-5import sys
-6import argparse
-7import admin
-8#-----------------------------------------------------------------------
- -10# Runs the server on the specified port, which in turn runs application
-11# When executed with -h as a command-line argument, displays a help message that describes the program's behavior
-12def main():
-13 parser = argparse.ArgumentParser(
-14 description="Tiger Spot"
-15 )
-16 parser.add_argument(
-17 "port", type=int, help="the port at which the server should \
-18 listen"
-19 )
- -21 try:
-22 args = parser.parse_args()
-23 except argparse.ArgumentError as e:
-24 print(e, file=sys.stderr)
-25 sys.exit(2)
- -27 try:
-28 admin.app.run(host='0.0.0.0', port=args.port, debug=True)
- -30 except Exception as ex:
-31 print(ex, file=sys.stderr)
-32 sys.exit(1)
- -34if __name__ == '__main__':
-35 main()
-- « prev - ^ index - » next - - coverage.py v7.5.1, - created at 2024-05-04 12:59 -0400 -
- -1#-----------------------------------------------------------------------
-2# user_database.py
-3#-----------------------------------------------------------------------
- -5import psycopg2
- -7#-----------------------------------------------------------------------
- -9DATABASE_URL = 'postgres://tigerspot_user:9WtP1U9PRdh1VLlP4VdwnT0BFSdbrPWk@dpg-cnrjs7q1hbls73e04390-a.ohio-postgres.render.com/tigerspot'
- -11#-----------------------------------------------------------------------
- -13# Creates users table with columns username and points.
- -15def create_user_table():
- -17 try:
-18 with psycopg2.connect(DATABASE_URL) as conn:
-19 with conn.cursor() as cur:
-20 cur.execute('''CREATE TABLE IF NOT EXISTS users (
-21 username varchar(255),
-22 points int);''')
-23 conn.commit()
- -25 except (Exception, psycopg2.DatabaseError) as error:
-26 print(error)
-27 return "database error"
- -29#-----------------------------------------------------------------------
- -31# Inserts username into users table.
- -33def insert_player(username):
- -35 try:
-36 with psycopg2.connect(DATABASE_URL) as conn:
-37 with conn.cursor() as cur:
-38 # Check if username exists
-39 cur.execute("SELECT points FROM users WHERE username=%s;", (username,))
-40 result = cur.fetchone()
- -42 if result is None:
-43 cur.execute("INSERT INTO users (username, points) VALUES (%s, %s);", (username, 0,))
-44 conn.commit()
- -46 return "success"
- -48 except (Exception, psycopg2.DatabaseError) as error:
-49 print(error)
-50 return "database error"
- -52#-----------------------------------------------------------------------
- -54# Resets username's total points to 0.
- -56def reset_player_total_points(username):
- -58 try:
-59 with psycopg2.connect(DATABASE_URL) as conn:
-60 with conn.cursor() as cur:
-61 # Check if username exists
-62 cur.execute("SELECT points FROM users WHERE username=%s;", (username,))
-63 result = cur.fetchone()
- -65 if result is None:
-66 return
-67 else:
-68 cur.execute("UPDATE users SET points=%s WHERE username=%s;", (0, username))
-69 conn.commit()
- -71 return "success"
- -73 except (Exception, psycopg2.DatabaseError) as error:
-74 print(error)
-75 return "database error"
- - -78#-----------------------------------------------------------------------
- -80# Updates username's total points with points.
- -82def update_player(username, points):
- -84 try:
-85 with psycopg2.connect(DATABASE_URL) as conn:
-86 with conn.cursor() as cur:
-87 cur.execute("UPDATE users SET points=%s WHERE username=%s;", (points, username))
-88 conn.commit()
- -90 return "success"
- -92 except (Exception, psycopg2.DatabaseError) as error:
-93 print(error)
-94 return "database error"
- -96#-----------------------------------------------------------------------
- -98# Returns username's points.
- -100def get_points(username):
- -102 try:
-103 with psycopg2.connect(DATABASE_URL) as conn:
-104 with conn.cursor() as cur:
-105 cur.execute('''SELECT points FROM users WHERE username=%s;''', (username,))
-106 points = cur.fetchone()
- -108 return points[0]
- -110 except (Exception, psycopg2.DatabaseError) as error:
-111 print(error)
-112 return "database error"
- -114#-----------------------------------------------------------------------
- -116# Returns username's total rank among all players.
- -118def get_rank(username):
- -120 try:
-121 with psycopg2.connect(DATABASE_URL) as conn:
-122 with conn.cursor() as cur:
-123 cur.execute("SELECT username, points, DENSE_RANK() OVER (ORDER BY points DESC, username ASC) as rank FROM users;")
-124 players = cur.fetchall()
- -126 for player in players:
-127 if player[0] == username:
-128 return player[2]
-129 return "Player not found"
- -131 except (Exception, psycopg2.DatabaseError) as error:
-132 print(error)
-133 return "database error"
- -135#-----------------------------------------------------------------------
- -137# Returns a dictionary of the usernames and points of the the top 10
-138# scoring players.
- -140def get_top_players():
- -142 try:
-143 with psycopg2.connect(DATABASE_URL) as conn:
-144 with conn.cursor() as cur:
- -146 top_players = []
-147 cur.execute("SELECT username, points FROM users ORDER BY points DESC, username ASC LIMIT 10;")
-148 table = cur.fetchall()
-149 for row in table:
-150 username, points = row
-151 player_stats = {'username': username, 'points': points}
-152 top_players.append(player_stats)
- -154 return top_players
- -156 except (Exception, psycopg2.DatabaseError) as error:
-157 print(error)
-158 return "database error"
- -160#-----------------------------------------------------------------------
- -162# Removes username from the users table.
- -164def remove_from_user_table(username):
- -166 try:
-167 with psycopg2.connect(DATABASE_URL) as conn:
-168 with conn.cursor() as cur:
-169 cur.execute("DELETE FROM users WHERE username=%s;", (username,))
-170 conn.commit()
- -172 return "success"
- -174 except (Exception, psycopg2.DatabaseError) as error:
-175 print(error)
-176 return "database error"
- -178#-----------------------------------------------------------------------
- -180# Returns all players in users table.
- -182def get_players():
- -184 try:
-185 with psycopg2.connect(DATABASE_URL) as conn:
-186 with conn.cursor() as cur:
-187 cur.execute("SELECT username FROM users;")
-188 table = cur.fetchall()
-189 user_ids = [row[0] for row in table]
-190 return user_ids
- -192 except (Exception, psycopg2.DatabaseError) as error:
-193 print(error)
-194 return "database error"
- -196#-----------------------------------------------------------------------
- -198def main():
-199 print(get_top_players())
- -201#-----------------------------------------------------------------------
- -203if __name__=="__main__":
-204 main()
-- « prev - ^ index - » next - - coverage.py v7.5.1, - created at 2024-05-04 12:59 -0400 -
- -1import psycopg2
- -3DATABASE_URL = 'postgres://tigerspot_user:9WtP1U9PRdh1VLlP4VdwnT0BFSdbrPWk@dpg-cnrjs7q1hbls73e04390-a.ohio-postgres.render.com/tigerspot'
- - -6def update_versus_points(challenge_id, user_id, additional_points):
-7 conn = None
-8 try:
-9 conn = psycopg2.connect(DATABASE_URL)
-10 cur = conn.cursor()
- -12 # First, determine if the user is the challenger or the challengee for this challenge
-13 cur.execute('''
-14 SELECT challenger_id, challengee_id
-15 FROM challenges
-16 WHERE id = %s;
-17 ''', (challenge_id,))
- -19 result = cur.fetchone()
-20 if result is None:
-21 print("Challenge not found.")
-22 return
- -24 challenger_id, challengee_id = result
- -26 # Depending on whether the user is the challenger or the challengee,
-27 # increment the corresponding points column for that user in the challenges table
-28 if user_id == challenger_id:
-29 cur.execute('''
-30 UPDATE challenges
-31 SET challenger_points = COALESCE(challenger_points, 0) + %s
-32 WHERE id = %s;
-33 ''', (additional_points, challenge_id))
-34 elif user_id == challengee_id:
-35 cur.execute('''
-36 UPDATE challenges
-37 SET challengee_points = COALESCE(challengee_points, 0) + %s
-38 WHERE id = %s;
-39 ''', (additional_points, challenge_id))
-40 else:
-41 print("User is not part of this challenge.")
-42 return
- -44 conn.commit()
-45 print("User points incremented successfully.")
-46 return {"status": "success"}
- -48 except (Exception, psycopg2.DatabaseError) as error:
-49 print(f"Error: {error}")
-50 finally:
-51 if conn is not None:
-52 conn.close()
-53#-----------------------------------------------------------------------
- -55def calculate_versus(distance, time):
-56 if time < 10 and distance < 10:
-57 return 1000
-58 else:
-59 if distance < 0:
-60 raise ValueError("Distance cannot be negative")
-61 dis_points = max(0, 1 - distance / 110) * 900
-62 if time < 0 or time > 120:
-63 raise ValueError("Time taken must be between 0 and the maximum allowed time")
-64 time_points = max(0, 1 - time / 120) * 100
- -66 return dis_points + time_points
- -68def get_winner(challenge_id):
-69 conn = None
-70 try:
-71 conn = psycopg2.connect(DATABASE_URL)
-72 cur = conn.cursor()
-73 cur.execute("SELECT winner_id FROM matches WHERE challenge_id = %s;", (challenge_id,))
-74 result = cur.fetchone()
-75 if result is None:
-76 return None
-77 else:
-78 return result[0]
- -80 except (Exception, psycopg2.DatabaseError) as error:
-81 print(f"Error: {error}")
-82 finally:
-83 if conn is not None:
-84 conn.close()
- -86def update_versus_pic_status(challenge_id, user_id, index):
-87 conn = None
-88 try:
-89 conn = psycopg2.connect(DATABASE_URL)
-90 cur = conn.cursor()
- -92 # First, determine if the user is the challenger or the challengee for this challenge
-93 cur.execute('''
-94 SELECT challenger_id, challengee_id
-95 FROM challenges
-96 WHERE id = %s;
-97 ''', (challenge_id,))
- -99 result = cur.fetchone()
-100 if result is None:
-101 print("Challenge not found.")
-102 return
- -104 challenger_id, challengee_id = result
- -106 # Depending on whether the user is the challenger or the challengee,
-107 # update the corresponding finished column in the matches table
-108 if user_id == challenger_id:
-109 cur.execute('''
-110 UPDATE challenges
-111 SET challenger_bool[%s] = TRUE
-112 WHERE id = %s;
-113 ''', (index, challenge_id))
-114 elif user_id == challengee_id:
-115 cur.execute('''
-116 UPDATE challenges
-117 SET challengee_bool[%s] = TRUE
-118 WHERE id = %s;
-119 ''', (index, challenge_id))
-120 else:
-121 print("User is not part of this challenge.")
-122 return
- -124 conn.commit()
-125 print("Finish status updated successfully.")
-126 return {"status": "success"}
- -128 except (Exception, psycopg2.DatabaseError) as error:
-129 print(f"Error: {error}")
-130 finally:
-131 if conn is not None:
-132 conn.close()
- -134def get_versus_pic_status(challenge_id, user_id, index):
-135 conn = None
-136 try:
-137 conn = psycopg2.connect(DATABASE_URL)
-138 cur = conn.cursor()
- -140 # First, determine if the user is the challenger or the challengee for this challenge
-141 cur.execute('''
-142 SELECT challenger_id, challengee_id
-143 FROM challenges
-144 WHERE id = %s;
-145 ''', (challenge_id,))
- -147 result = cur.fetchone()
-148 if result is None:
-149 print("Challenge not found.")
-150 return
- -152 challenger_id, challengee_id = result
- -154 # Depending on whether the user is the challenger or the challengee,
-155 # get the corresponding finished column in the matches table
-156 if user_id == challenger_id:
-157 cur.execute('''
-158 SELECT challenger_bool[%s]
-159 FROM challenges
-160 WHERE id = %s;
-161 ''', (index, challenge_id))
-162 elif user_id == challengee_id:
-163 cur.execute('''
-164 SELECT challengee_bool[%s]
-165 FROM challenges
-166 WHERE id = %s;
-167 ''', (index, challenge_id))
-168 else:
-169 print("User is not part of this challenge.")
-170 return
- -172 result = cur.fetchone()
-173 if result is None:
-174 print("Index not found.")
-175 return
-176 else:
-177 return result[0]
- -179 except (Exception, psycopg2.DatabaseError) as error:
-180 print(f"Error: {error}")
-181 finally:
-182 if conn is not None:
-183 conn.close()
-184#-----------------------------------------------------------------------
- -186def store_versus_pic_points(challenge_id, user_id, index, points):
-187 conn = None
-188 try:
-189 conn = psycopg2.connect(DATABASE_URL)
-190 cur = conn.cursor()
- -192 # First, determine if the user is the challenger or the challengee for this challenge
-193 cur.execute('''
-194 SELECT challenger_id, challengee_id
-195 FROM challenges
-196 WHERE id = %s;
-197 ''', (challenge_id,))
- -199 result = cur.fetchone()
-200 if result is None:
-201 print("Challenge not found.")
-202 return
- -204 challenger_id, challengee_id = result
- -206 # Depending on whether the user is the challenger or the challengee,
-207 # update the corresponding finished column in the matches table
-208 if user_id == challenger_id:
-209 cur.execute('''
-210 UPDATE challenges
-211 SET challenger_points[%s] = %s
-212 WHERE id = %s;
-213 ''', (index, points, challenge_id))
-214 elif user_id == challengee_id:
-215 cur.execute('''
-216 UPDATE challenges
-217 SET challengee_points[%s] = %s
-218 WHERE id = %s;
-219 ''', (index, points, challenge_id))
-220 else:
-221 print("User is not part of this challenge.")
-222 return
- -224 conn.commit()
-225 print("Points updated successfully.")
-226 return {"status": "success"}
- -228 except (Exception, psycopg2.DatabaseError) as error:
-229 print(f"Error: {error}")
-230 finally:
-231 if conn is not None:
-232 conn.close()
- -234#-----------------------------------------------------------------------
- -236def store_versus_pic_points(challenge_id, user_id, index, points):
-237 conn = None
-238 try:
-239 conn = psycopg2.connect(DATABASE_URL)
-240 cur = conn.cursor()
- -242 # First, determine if the user is the challenger or the challengee for this challenge
-243 cur.execute('''
-244 SELECT challenger_id, challengee_id
-245 FROM challenges
-246 WHERE id = %s;
-247 ''', (challenge_id,))
- -249 result = cur.fetchone()
-250 if result is None:
-251 print("Challenge not found.")
-252 return
- -254 challenger_id, challengee_id = result
- -256 # Depending on whether the user is the challenger or the challengee,
-257 # update the corresponding points column in the challenges table
-258 if user_id == challenger_id:
-259 cur.execute('''
-260 UPDATE challenges
-261 SET challenger_pic_points[%s] = %s
-262 WHERE id = %s;
-263 ''', (index, points, challenge_id))
-264 elif user_id == challengee_id:
-265 cur.execute('''
-266 UPDATE challenges
-267 SET challengee_pic_points[%s] = %s
-268 WHERE id = %s;
-269 ''', (index, points, challenge_id))
-270 else:
-271 print("User is not part of this challenge.")
-272 return
- -274 conn.commit()
-275 print("Versus pic points updated successfully.")
-276 return {"status": "success"}
- -278 except (Exception, psycopg2.DatabaseError) as error:
-279 print(f"Error: {error}")
-280 finally:
-281 if conn is not None:
-282 conn.close()
- -284#-----------------------------------------------------------------------
-285def main():
-286 print()
- -288if __name__=="__main__":
-289 main()
-