def comp_results(comp_id): """ A route for showing results for a specific competition. """ competition = get_competition(comp_id) if not competition: msg = "Oops, that's not a real competition. Try again, ya clown." return render_template('error.html', error_message=msg) comp_events = get_all_comp_events_for_comp(comp_id) comp_events = sort_comp_events_by_global_sort_order(comp_events) events_names_ids = list() id_3x3 = None for comp_event in comp_events: if comp_event.Event.name == '3x3': id_3x3 = comp_event.id events_names_ids.append({ 'name': comp_event.Event.name, 'comp_event_id': comp_event.id, 'event_id': comp_event.Event.id, }) alternative_title = "{} leaderboards".format(competition.title) return render_template("results/results_comp.html", alternative_title=alternative_title, events_names_ids=events_names_ids, id_3x3=id_3x3, comp_id=comp_id)
def send_gift_code_winner_approval_pm(comp_id): """ Chooses a random participant from the competition provided, and builds a WeeklyCodeRecipientConfirmDeny record. Sends a PM to the configured admin user to approve or deny that user. """ winner = get_random_reddit_participant_for_competition(comp_id) competition = get_competition(comp_id) gift_code = get_unused_gift_code() if not gift_code: return msg = __NO_CODES_LEFT_TEMPLATE.format( comp_title=competition.title, code_refill_url=__CODE_REFILL_ADMIN_URL) send_pm_to_user(__CODE_TOP_OFF_REDDIT_USER, __NO_CODES_LEFT_TITLE, msg) send_gift_code_winner_approval_pm.schedule( (comp_id, ), delay=__GIFT_CODE_SELECTION_RETRY_DELAY) confirm_deny_record = create_confirm_deny_record(gift_code.id, winner.id, comp_id) msg = __CODE_CONFIRM_DENY_MSG_TEMPLATE.format( reddit_id=winner.reddit_id, comp_title=competition.title, user_profile_url=__USER_PROFILE_URL.format(username=winner.username), confirm_url=__CONFIRM_URL_TEMPLATE.format( confirm_code=confirm_deny_record.confirm_code), deny_url=__DENY_URL_TEMPLATE.format( deny_code=confirm_deny_record.deny_code), unused_codes_count=get_unused_gift_code_count()) send_pm_to_user(__CODE_CONFIRM_REDDIT_USER, __CODE_CONFIRM_DENY_TITLE, msg)
def post_results_thread(competition_id, is_rerun=False): """ Iterate over the events in the competition being scored """ user_points = dict() # Retrieve the competition being scored comp = get_competition(competition_id) title = __RESULTS_TITLE_TEMPLATE.format(comp_title=comp.title) post_body = __RESULTS_BODY_START_TEMPLATE.format( comp_title=comp.title, point_user_limit=__USER_LIMIT_IN_POINTS, event_user_limit=__USER_PER_EVENT_LIMIT, leaderboards_url=__LEADERBOARDS_URL_TEMPLATE.format(comp_id=comp.id)) # Iterate over all the events in the competition, simultaneously building up the post body and # tallying user points for comp_event in sort_comp_events_by_global_sort_order(list(comp.events)): results = list( get_all_complete_user_results_for_comp_event(comp_event.id)) if not results: continue results_with_ranks = sort_user_results_with_rankings( results, comp_event.Event.eventFormat) post_body += __RESULTS_EVENT_HEADER_TEMPLATE.format( event_name=comp_event.Event.name) total_participants = len(results) for i, _, result in results_with_ranks: username = result.User.username if username not in user_points.keys(): user_points[username] = 0 user_points[username] += (total_participants - i) if i <= __USER_PER_EVENT_LIMIT: post_body += __RESULTS_USER_LINE_TEMPLATE.format( username=__escape_username(username), profile_url=__profile_for(username), result=result.friendly_result()) user_points = [(username, points) for username, points in user_points.items()] user_points.sort(key=lambda x: x[1], reverse=True) post_body += __RESULTS_POINTS_SECTION_HEADER for username, points in user_points[:__USER_LIMIT_IN_POINTS]: post_body += __RESULTS_USER_POINTS_TEMPLATE.format( username=__escape_username(username), profile_url=__profile_for(username), points=points) if not is_rerun: new_post_id = submit_post(title, post_body) comp.result_thread_id = new_post_id save_competition(comp) else: results_thread_id = comp.result_thread_id update_post(post_body, results_thread_id)
def prepare_new_competition_notification(comp_id, is_all_events): """ Builds a new competition notification message, looks up all users who want to receive this sort of message, and queues up tasks to send those users PMs. """ competition = get_competition(comp_id) if is_all_events: event_desc = ALL_EVENTS_DESC else: all_events = get_all_comp_events_for_comp(comp_id) all_event_names = [event.Event.name for event in all_events] all_bonus_event_names = [e.name for e in BONUS_EVENTS] bonus_event_names = [ name for name in all_event_names if name in all_bonus_event_names ] bonus_event_names = naturally_join(bonus_event_names) event_desc = ROTATING_EVENTS_DESC.format( bonus_events_list=bonus_event_names) for user_id in get_all_user_ids_with_setting_value( SettingCode.REDDIT_COMP_NOTIFY, TRUE_STR): reddit_id = get_user_by_id(user_id).reddit_id # If the user doesn't have Reddit info, skip them if not reddit_id: continue message_body = NEW_COMP_TEMPLATE.format(comp_title=competition.title, bonus_events_desc=event_desc, username=reddit_id, opt_out_info=OPT_OUT_INFO) send_competition_notification_pm(reddit_id, message_body)
def send_gift_code_to_winner(user_id: int, gift_code_id: int, comp_id: int) -> None: """ Sends a PM to recipient of a weekly SCS gift code. """ user = get_user_by_id(user_id) msg = __GIFT_CODE_RECIPIENT_TEMPLATE.format( username=user.reddit_id, gift_code=get_gift_code_by_id(gift_code_id).gift_code, comp_title=get_competition(comp_id).title) send_pm_to_user(user.reddit_id, __GIFT_CODE_RECIPIENT_TITLE, msg)
def prepare_end_of_competition_info_notifications(comp_id): """ Prepares a list of end-of-competition stats and info for users who have both opted in and participated in the specified competition. """ users_in_comp = get_reddit_participants_in_competition(comp_id) opted_in = get_all_user_ids_with_setting_value( SettingCode.REDDIT_RESULTS_NOTIFY, TRUE_STR) # Make sure we're only sending messages to users who have both participated in the specified # competition, and opted in to receive these messages user_ids_to_notify = list(set(users_in_comp) & set(opted_in)) comp_title = get_competition(comp_id).title for user_id in user_ids_to_notify: send_end_of_competition_message(user_id, comp_id, comp_title)
def score_comp_only(comp_id, rerun): """ Score only the specified competition, optionally as a re-run. """ comp = get_competition(comp_id) post_results_thread_task(comp.id, is_rerun=rerun)