def tournament_close(tournament_id): if current_user(): try: tourn = Tournament.query.get(tournament_id) coach = Coach.query.options(raiseload(Coach.cards),raiseload(Coach.packs)).filter_by(disc_id=current_user()['id']).one_or_none() if not coach: raise InvalidUsage("Coach not found", status_code=403) if not coach.web_admin: raise InvalidUsage("Coach does not have webadmin role", status_code=403) #prizes for prize in request.get_json(): tmp_coach = Coach.query.options(raiseload(Coach.cards),raiseload(Coach.packs)).get(prize['coach']) reason = prize['reason']+" by "+coach.short_name() TransactionService.process(tmp_coach,int(prize['amount'])*-1,reason) for coach in tourn.coaches: TournamentService.unregister(tourn,coach,admin=True,refund=False) tourn.phase="deck_building" db.session.commit() result = tournament_schema.dump(tourn) return jsonify(result.data) except (RegistrationError,TransactionError) as e: raise InvalidUsage(str(e), status_code=403) else: raise InvalidUsage('You are not authenticated', status_code=401)
async def resign(tournament_id, coach, ctx, admin=False): """routine to resign a coach to tournament""" if admin: tourn = Tournament.query.filter_by( tournament_id=tournament_id).one_or_none() else: tourn = Tournament.query.filter_by( status="OPEN", tournament_id=tournament_id).one_or_none() if not tourn: raise ValueError("Incorrect **tournament_id** specified") if TournamentService.unregister(tourn, coach, admin): await ctx.send(f"Resignation succeeded!!!") coaches = [ discord.utils.get(ctx.guild.members, id=str(signup.coach.disc_id)) for signup in TournamentService.update_signups(tourn) ] msg = [coach.mention for coach in coaches if coach] msg.append( f"Your signup to {tourn.name} has been updated from RESERVE to ACTIVE" ) if len(msg) > 1: tourn_channel = discord.utils.get(ctx.bot.get_all_channels(), name='tournament-notice-board') if tourn_channel: await tourn_channel.send("\n".join(msg)) else: await ctx.send("\n".join(msg)) return True
async def left(self, ctx): """Lists coaches left to finish current tournament phase""" room = ctx.channel.name coaches = TournamentService.left_phase(room) phase = TournamentService.get_phase(room) msg = f"**Phase:** {phase}\n**Left:**\n" for coach in coaches: msg += f"{coach.short_name()}\n" await ctx.send(msg)
def tournament_sign(tournament_id, **kwargs): """Sign coach into tournament""" try: coach = kwargs['coach'] tourn = Tournament.query.get(tournament_id) TournamentService.register(tourn, coach) result = tournament_schema.dump(tourn) return jsonify(result.data) except RegistrationError as exc: raise InvalidUsage(str(exc), status_code=403)
def tournament_start(tournament_id): """Set tournament phase""" try: tourn = Tournament.query.get(tournament_id) TournamentService.kick_off(tourn) result = tournament_schema.dump(tourn) return jsonify(result.data) except (RegistrationError, TransactionError, TypeError, TournamentError) as exc: raise InvalidUsage(str(exc), status_code=403)
def tournament_set_phase(tournament_id): """Set tournament phase""" try: tourn = Tournament.query.get(tournament_id) phase = request.get_json()['phase'] TournamentService.set_phase(tourn, phase) db.session.commit() result = tournament_schema.dump(tourn) return jsonify(result.data) except (RegistrationError, TransactionError, TypeError) as exc: raise InvalidUsage(str(exc), status_code=403)
def tournaments_update(): """Update tournaments from sheet""" try: TournamentService.update() all_tournaments = Tournament.query.options( raiseload(Tournament.coaches)).filter( Tournament.status.in_(("OPEN", "RUNNING"))).all() result = tournaments_schema.dump(all_tournaments) return jsonify(result.data) except RegistrationError as exc: raise InvalidUsage(str(exc), status_code=403)
def tournaments_update(): if current_user(): try: coach = Coach.query.options(raiseload(Coach.cards),raiseload(Coach.packs)).filter_by(disc_id=current_user()['id']).one_or_none() if not coach: raise InvalidUsage("Coach not found", status_code=403) if not coach.web_admin: raise InvalidUsage("Coach does not have webadmin role", status_code=403) TournamentService.update() return jsonify(True) except RegistrationError as e: raise InvalidUsage(str(e), status_code=403) else: raise InvalidUsage('You are not authenticated', status_code=401)
def tournament_resign(tournament_id): if current_user(): try: tourn = Tournament.query.get(tournament_id) coach = Coach.query.filter_by(disc_id=current_user()['id']).one_or_none() if not coach: raise InvalidUsage("Coach not found", status_code=403) TournamentService.unregister(tourn,coach) result = tournament_schema.dump(tourn) return jsonify(result.data) except RegistrationError as e: raise InvalidUsage(str(e), status_code=403) else: raise InvalidUsage('You are not authenticated', status_code=401)
def tournament_resign(tournament_id, **kwargs): """resign from tournament""" try: coach = kwargs['coach'] tourn = Tournament.query.get(tournament_id) TournamentService.unregister(tourn, coach) signups = TournamentService.update_signups(tourn) if signups: coaches = [signup.coach for signup in signups] msg = (", ").join([f"<@{coach.disc_id}>" for coach in coaches]) Notificator("bank").notify( f"{msg}: Your signup to {tourn.name} has been updated from RESERVE to ACTIVE" ) result = tournament_schema.dump(tourn) return jsonify(result.data) except RegistrationError as exc: raise InvalidUsage(str(exc), status_code=403)
async def done(self, ctx): """Confirms Special Play, Inducement and Blood Bowl phase""" coach = CoachService.discord_user_to_coach(ctx.author) room = ctx.channel.name if coach is None: await ctx.send( f"Coach {ctx.author.mention} does not exist. Use !newcoach to create coach first." ) return if TournamentService.get_phase(room) in [ Tourn.DB_PHASE, Tourn.LOCKED_PHASE ]: msg = "This command has no effect in this phase. Go and commit your deck!" elif TournamentService.confirm_phase(coach, room): msg = f"Phase confirmed for {coach.short_name()}" else: msg = "No deck found!" await ctx.send(msg)
def tournament_resign(tournament_id): if current_user(): try: tourn = Tournament.query.get(tournament_id) coach = Coach.query.options(raiseload(Coach.cards),raiseload(Coach.packs)).filter_by(disc_id=current_user()['id']).one_or_none() if not coach: raise InvalidUsage("Coach not found", status_code=403) TournamentService.unregister(tourn,coach) signups = TournamentService.update_signups(tourn) if len(signups)>0: coaches = [signup.coach for signup in signups] msg = (", ").join([f"<@{coach.disc_id}>" for coach in coaches]) NotificationService.notify(f"{msg}: Your signup to {tourn.name} has been updated from RESERVE to ACTIVE") result = tournament_schema.dump(tourn) return jsonify(result.data) except RegistrationError as e: raise InvalidUsage(str(e), status_code=403) else: raise InvalidUsage('You are not authenticated', status_code=401)
async def focus(self, ctx): """Reviews your deck and tells what the deck focus is""" me = CoachService.discord_user_to_coach(ctx.author) tourn = TournamentService.get_tournament_using_room(ctx.channel.name) deck = [ts.deck for ts in tourn.tournament_signups if ts.coach == me] if not deck: raise Exception( f"#{me.short_name()} is not signed into the tournament. Nice try!" ) focus = DeckService.focus(deck[0]) await ctx.send(f"Deck focus is {', '.join(focus)}")
def tournament_close(tournament_id): """Close tournaments and award prizes""" try: tourn = Tournament.query.get(tournament_id) coach = current_coach() #prizes for prize in request.get_json(): tmp_coach = Coach.query.options(raiseload(Coach.cards), raiseload(Coach.packs)).get( prize['coach']) reason = prize['reason'] + " by " + coach.short_name() TransactionService.process(tmp_coach, int(prize['amount']) * -1, reason) TournamentService.close_tournament(tourn) result = tournament_schema.dump(tourn) return jsonify(result.data) except (RegistrationError, TransactionError) as exc: raise InvalidUsage(str(exc), status_code=403)
async def sign(tournament_id, coach, ctx, admin=False): """routine to sign a coach to tournament""" if admin: tourn = Tournament.query.filter_by( tournament_id=tournament_id).one_or_none() else: tourn = Tournament.query.filter_by( status="OPEN", tournament_id=tournament_id).one_or_none() if not tourn: raise ValueError("Incorrect **tournament_id** specified") signup = TournamentService.register(tourn, coach, admin) add_msg = "" if signup.mode == "active" else " as RESERVE" await ctx.send(f"Signup succeeded{add_msg}!!!") return True
# Works with Python 3.6 from web import db, create_app from services import TournamentService app = create_app() app.app_context().push() TournamentService.update()
def after_model_change(self, form, model, is_created): TournamentService.update_tournament_in_sheet(model)
from services import UserService, PlayerService, TournamentService from repositories import UserRepository, PlayerRepository, TournamentRepository from dbOperations import dbConnection import os dbConnectionPool = dbConnection.connectionPool() userRepository = UserRepository.UserRepository(dbConnectionPool) userService = UserService.UserService(userRepository) playerRepository = PlayerRepository.PlayerRepository(dbConnectionPool) playerService = PlayerService.PlayerService(playerRepository) tournamentRepository = TournamentRepository.TournamentRepository( dbConnectionPool) tournamentService = TournamentService.TournamentService(tournamentRepository) def isLoggedIn(function): def check(*args, **kwargs): uuid = request.headers.get('uuid') if uuid: loggedUser = userService.isLoggedIn( {"uuid": request.headers.get('uuid')}) if isinstance(loggedUser, User.User): return function(loggedUser, *args, **kwargs) else: return jsonify( {"result": "Your Session Expired. Login to proceed."})
from web import db, app from models.data_models import Coach, Tournament from services import Notificator, TournamentService, ImperiumSheetService, TournamentError app.app_context().push() tournaments = Tournament.query.filter_by(status="OPEN").all() auto = [] for tournament in tournaments: if len(tournament.tournament_signups) == tournament.coach_limit: if tournament.can_auto_start(): auto.append(tournament) # automatic kick off if auto: msg = "Automatically started tournaments:\n" for t in auto: try: TournamentService.kick_off(t) Notificator('tournament').notify( f"Tournament {t.tournament_id}. {t.name} kicked off: deadline {t.deadline_date}, admin {t.admin}, sponsor {t.sponsor}, room {t.discord_channel}" ) except TournamentError as e: Notificator('tournament').notify(str(e))
def tournaments_cards(tournament_id): """Update tournaments from sheet""" tourn = Tournament.query.get(tournament_id) return jsonify(TournamentService.cards(tourn))
async def comp(self, ctx, *args): """Manages in-game competitions for tournaments. Needs to be run in the tournament discord channel USAGE: !comp list list all competitions for tournament !comp create ladder creates ladder comp for tournament if it does not exists !comp create 1on1 <competition_name> creates 1 on 1 comp with <competition_name> for tournament if it does not exists !comp create knockout <team_number> <name> creates knockout comp with <name> for <team_number> teams !comp ticket <competition_name> sends ticket to the <competition_name> to the coach issuing the command in the tournament room !comp start <competition_name> starts comp with <competition_name> for tournament """ room = ctx.channel.name args_len = len(args) if args_len == 0 \ or (args_len > 0 and args[0] not in ["list","create", "ticket", "start"]) \ or (args[0] == "create" and \ (args_len < 2 or args[1] not in ["ladder", "1on1","knockout"] or (args[1] == "1on1" and args_len == 2) \ or (args[1] == "knockout" and args_len < 4 and not represents_int(args[2])))) \ or (args[0] in ["ticket", "start"] and args_len < 2): raise ValueError("Incorrect arguments") tourn = TournamentService.get_tournament_using_room(room) if tourn.status != "RUNNING": await ctx.send("Tournament is not running!") return if args[0] == "create": if args[1] == "ladder": comp_name = tourn.ladder_room_name() comp = CompetitionService.create_imperium_ladder(comp_name) if args[1] == "1on1": comp_name = " ".join(args[2:]) comp_name = comp_name[:25] if len( comp_name) > 25 else comp_name comp = CompetitionService.create_imperium_rr(comp_name) if args[1] == "knockout": comp_name = " ".join(args[3:]) comp_name = comp_name[:25] if len( comp_name) > 25 else comp_name comp = CompetitionService.create_imperium_knockout( comp_name, int(args[2])) tourn.competitions.append(comp) db.session.commit() await ctx.send( f"Competition **{comp.name}** created in **{comp.league_name}**" ) return if args[0] == "list": msg = [] msg.append('{:25s} | {:25} | {:25}'.format("League", "Name", "Type")) msg.append(78 * "-") for comp in tourn.competitions: msg.append('{:25s} | {:25} | {:25}'.format( comp.league_name, comp.name, comp.type_str())) await self.send_message(ctx.channel, msg, block=True) # await ctx.send("\n".join(msg)) return if args[0] == "ticket": comp_name = " ".join(args[1:]) # get coach coach = CoachService.discord_user_to_coach(ctx.author) result = CompetitionService.ticket_competition( comp_name, coach, tourn) team_name = result['ResponseCreateCompetitionTicket'][ 'TicketInfos']['RowTeam']['Name'] await ctx.send( f"Ticket sent to **{team_name}** for competition **{comp_name}**" ) return if args[0] == "start": comp_name = " ".join(args[1:]) comp = Competition.query.filter_by(name=comp_name).one_or_none() if not comp: raise CompetitionError( f"Competition **{comp_name}** does not exist") result = CompetitionService.start_competition(comp) await ctx.send(f"Started competition **{comp_name}**") return
async def admincomp(self, ctx, action: str, tournamnent_id: int = None): """Manipulate tournaments USAGE: !admincomp <action> [tournament_id] start: Notifies all registered coaches that tournament started in the tournament channel and links the ledger stop: Resigns all coaches from the tournament update: Updates data from Tournament sheet special_play: Initiates special play phase inducement: Initiates inducement phase blood_bowl: Initiates blood bowl phase <tournament_id>: id of tournament from Tournament master sheet """ self.is_admin_channel(ctx.channel) if action not in [ "start", "stop", "update", Tournament.SP_PHASE, Tournament.IND_PHASE, Tournament.BB_PHASE ]: raise ValueError("Incorrect arguments!!!") if action in [ "start", "stop", Tournament.SP_PHASE, Tournament.IND_PHASE, Tournament.BB_PHASE ]: if not tournamnent_id: raise ValueError("Incorrect arguments!!!") tourn = Tournament.query.filter_by( tournament_id=tournamnent_id).one_or_none() if not tourn: raise ValueError(f"Incorrect tournament **id** specified") if action == "update": await ctx.send("Updating...") TournamentService.update() await ctx.send("Tournaments updated!!!") if action == "stop": TournamentService.close_tournament(tourn) await ctx.send(f"Coaches have been resigned from {tourn.name}!!!") return if action in [ "start", Tournament.SP_PHASE, Tournament.IND_PHASE, Tournament.BB_PHASE ]: result, err = TournamentService.start_check(tourn) if err: raise Exception(err) channel = discord.utils.get(ctx.bot.get_all_channels(), name=tourn.discord_channel.lower()) if not channel: await ctx.send( f"Discord channel {tourn.discord_channel.lower()} does not exists, please create it and rerun this command!" ) return admin = discord.utils.get(ctx.guild.members, name=tourn.admin) if not admin: await ctx.send( f"Tournament admin {tourn.admin} was not found on the discord server, check name in the Tournament sheet and run **!admincomp update**!" ) return if action == "start": TournamentService.reset_phase(tourn) TournamentService.set_status(tourn, status="RUNNING") db.session.commit() TournamentService.release_reserves(tourn) submit_deck_channel = discord.utils.get( ctx.bot.get_all_channels(), name='submit-a-deck') members = [ discord.utils.get(ctx.guild.members, id=coach.disc_id) for coach in tourn.coaches.filter( TournamentSignups.mode == "active") ] msg = [member.mention for member in members if member] msg.append( f"This will be scheduling channel for your {tourn.name}") if submit_deck_channel: msg.append( f"Please submit decks as instructed in {submit_deck_channel.mention}" ) msg.append(f"We start on {tourn.expected_start_date}!") msg.append(f"Deadline is on {tourn.deadline_date}") msg.append(f"Your tournament admin is {admin.mention}") msg.append( f"**Deck Size/Deck Target Value/Deck Max Value**: {tourn.deck_limit}/{tourn.deck_value_target}/{tourn.deck_value_limit}" ) msg.append(f"**Conclave Ranges**:") msg.append( f"\t**3 Blessing Points:**\t\t {tourn.conclave_ranges().blessing3.start}-{tourn.conclave_ranges().blessing3.stop}" ) msg.append( f"\t**2 Blessing Points:**\t\t {tourn.conclave_ranges().blessing2.start}-{tourn.conclave_ranges().blessing2.stop}" ) msg.append( f"\t**1 Blessing Point:** \t\t {tourn.conclave_ranges().blessing1.start}-{tourn.conclave_ranges().blessing1.stop}" ) msg.append( f"\t**Conclave equilibrium:** {tourn.deck_value_target}") msg.append( f"\t**1 Curse Point:**\t\t\t\t {tourn.conclave_ranges().curse1.start}-{tourn.conclave_ranges().curse1.stop}" ) msg.append( f"\t**2 Curse Points:**\t\t\t {tourn.conclave_ranges().curse2.start}-{tourn.conclave_ranges().curse2.stop}" ) msg.append( f"\t**3 Curse Points:**\t\t\t {tourn.conclave_ranges().curse3.start}-{tourn.conclave_ranges().curse3.stop}" ) msg.append(f"**Tournament Sponsor:** {tourn.sponsor}") msg.append(f"{tourn.sponsor_description}") msg.append(f"**Special Rules:**") msg.append(f"{tourn.special_rules}") msg.append(f"**Banned Cards:**") msg.append(', '.join(tourn.banned_cards.split(';'))) msg.append(f"**Prizes:**") msg.append(f"{tourn.prizes}") msg.append(f"**Unique Prize:**") msg.append(f"{tourn.unique_prize}") #room setup if tourn.is_development(): msg.append(f"**In-game rooms:**") try: CompetitionService.import_competitions() comp = Competition.query.filter_by( name=tourn.ladder_room_name()).one_or_none() if not comp: comp = CompetitionService.create_imperium_ladder( tourn.ladder_room_name()) comp.tournament_id = tourn.id db.session.commit() for comp in tourn.competitions: msg.append( f"**{comp.name}** in **{comp.league_name}** league" ) except BB2APINotAvailable: msg.append( "Cyanide API is not available, in-game room was not created!" ) if action == Tournament.SP_PHASE: msg = TournamentService.special_play_msg(tourn) if action == Tournament.IND_PHASE: msg = TournamentService.inducement_msg(tourn) if action == Tournament.BB_PHASE: msg = TournamentService.blood_bowl_msg(tourn) await self.send_message(channel, msg) await ctx.send("Done.") return