Beispiel #1
0
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)
Beispiel #2
0
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
Beispiel #3
0
    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)
Beispiel #4
0
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)
Beispiel #5
0
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)
Beispiel #6
0
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)
Beispiel #7
0
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)
Beispiel #8
0
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)
Beispiel #9
0
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)
Beispiel #10
0
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)
Beispiel #11
0
    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)
Beispiel #12
0
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)
Beispiel #13
0
    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)}")
Beispiel #14
0
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)
Beispiel #15
0
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
Beispiel #16
0
# Works with Python 3.6
from web import db, create_app
from services import TournamentService

app = create_app()
app.app_context().push()

TournamentService.update()
Beispiel #17
0
 def after_model_change(self, form, model, is_created):
   TournamentService.update_tournament_in_sheet(model)
Beispiel #18
0
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."})
Beispiel #19
0
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))
Beispiel #20
0
def tournaments_cards(tournament_id):
    """Update tournaments from sheet"""
    tourn = Tournament.query.get(tournament_id)
    return jsonify(TournamentService.cards(tourn))
Beispiel #21
0
    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
Beispiel #22
0
    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