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 = get_all_bonus_events_names() 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 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 comp_results(comp_id): """ A route for showing results for a specific competition. """ competition = get_competition(comp_id) if not competition: return "Oops, that's not a real competition. Try again, ya clown.", 404 comp_events = get_all_comp_events_for_comp(comp_id) comp_events = sort_comp_events_by_global_sort_order(comp_events) # alternative_title = "{} leaderboards".format(competition.title) events = map( lambda c: { 'name': c.Event.name, 'format': c.Event.eventFormat, 'compEventId': c.id, 'eventId': c.Event.id, 'slug': slugify(c.Event.name) }, comp_events) comp_data = { "compId": competition.id, "compTitle": competition.title, "events": list(events) } return jsonify(comp_data)
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. """ if IS_DEVO: return 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 = get_all_bonus_events_names() 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): username = get_user_by_id(user_id).username message_body = NEW_COMP_TEMPLATE.format(comp_title=competition.title, bonus_events_desc=event_desc, username=username) send_competition_notification_pm(username, message_body)
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: msg = __NO_CODES_LEFT_TEMPLATE.format( comp_title=competition.title, code_refill_url=__CODE_REFILL_ADMIN_URL) send_PM_to_user_with_title_and_body(__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) return 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_with_title_and_body(__CODE_CONFIRM_REDDIT_USER, __CODE_CONFIRM_DENY_TITLE, msg)
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_with_title_and_body(user.reddit_id, __GIFT_CODE_RECIPIENT_TITLE, msg)
def gc_select_user(comp_id): """ Grab a list of participating users for the specified competition, and choose one at random. """ users = get_participants_in_competition(comp_id) if not users: winner = 'nobody' else: winner = random.choice(users) selected_comp = get_competition(comp_id) return render_template("admin/gc_select/user_list.html", users=users, winner=winner,\ selected_comp=selected_comp)
def send_weekly_report(comp_id): """ Builds and sends an end-of-week report with stats from the specified competition. """ metrics = get_weekly_metrics(comp_id) new_users_count = metrics.new_users_count if metrics.new_users_count else 0 title = WEEKLY_REPORT_TITLE_TEMPLATE.format( comp_name=get_competition(comp_id).title) content = WEEKLY_REPORT_BODY_TEMPLATE.format( total_participants=len(get_participants_in_competition(comp_id)), new_users_count=new_users_count, ) notify_admin(title, content, AdminNotificationType.PUSHBULLET_NOTE)
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)