def confirm_pools(request, stage): pool_stage = stage.poolstage_set.first() if stage.state != Stage.READY: return api_failure("incorrect state", _("Stage not in ready state")) if 'pools' not in request.POST: stage.state = Stage.STARTED stage.save() return api_success() original_pools = pool_stage.pool_set.all() pools = json.loads(request.POST['pools']) if len(pools) != len(original_pools): return api_failure("pool count mismatch", _("Number of pools submitted does not match number of pools in this round")) original_competitors_ids = set() [original_competitors_ids.update(x.poolentry_set.values_list('entry_id', flat=True)) for x in original_pools] competitors_ids = set() new_lengths = [] for pool_num, entries in pools.items(): competitors_ids.update(map(int, entries)) new_lengths.append(len(entries)) if competitors_ids != original_competitors_ids: return api_failure("pool entry mismatch", _("Manipulation of entry ids detected")) if not (max(new_lengths) <= min(new_lengths) + 1): return api_failure("pool size difference", _("Pools can differ in size by at most 1")) original_pools.delete() for index, pool in enumerate(pools.items()): new_pool = pool_stage.pool_set.create(number=index+1) for index, entry_id in enumerate(pool[1]): new_pool.poolentry_set.create(number=index+1, entry_id=int(entry_id)) stage.state = Stage.STARTED stage.save() return api_success()
def mark_table_complete(request, table): if table.complete: return api_failure('already_complete', _("This table is already marked as complete")) if table.detableentry_set.count() == 2: table.complete = True table.save() return api_success() try: table.make_children() return api_success() except UnfinishedTableException: return api_failure('incomplete_bouts', _('One or more bouts incomplete'))
def add_entries(request, stage: Stage): """add entries and set stage as ready entries will be ordered according to their seed :param request: expecting POST parameters:\n :param list of int ids: list of entry ids to add :param stage: Stage of type add :return: JSONResponse with either success or an error message """ add_stage = stage.addstage_set.first() if stage.state != Stage.NOT_STARTED: return api_failure("incorrect state", _("Stage not in NOT_STARTED state")) ids = request.POST.getlist('ids') entries = stage.competition.entry_set.filter(pk__in=ids) if len(entries) != len(ids) or not set(entries.all()).issubset( add_stage.possible_additions()): return api_failure( 'bad_entry', _('one of these entries has already been added or is not in this competition' )) additions = [] for y, equal_fencers in groupby(entries.order_by('seed'), lambda x: x.seed): additions.append(list(equal_fencers)) add_stage.add_entries(additions) stage.state = Stage.READY stage.save() return api_success()
def set_cull_level(request, stage: Stage): """set what level a cull should happen from :param request: expecting POST parameters:\n cull_number: value to set CullStage.number at :param stage: Stage of type cull to set :return: JSONResponse with either success or an error message """ cull_stage = stage.cullstage_set.first() if stage.state == Stage.NOT_STARTED: try: input_size = len(stage.input()) except Stage.NotCompleteError: return api_failure("previous stage incomplete") number = int(request.POST['cull_number']) if 2 < number < input_size: cull_stage.number = number stage.state = Stage.READY cull_stage.save() stage.save() return api_success() else: return api_failure( "invalid cull number", "cull number must be > 2 and < size of stages input ") else: return api_failure("incorrect state", "stage not in ready state")
def add_stage(request, comp): """add a stage to a competition incrementing other stages numbers :param request: expecting POST parameters:\n :param int number: number of the stage to add a stage after :param str stage_type: type of stage to add :param Competition comp: competition to delete stage from :return: """ number = int(request.POST['number']) stage_type = request.POST['stage_type'] if stage_type not in map(lambda x: x[0], Stage.stage_types): return api_failure('bad_type', _('Failed to add stage: unrecognised stage type')) if comp.stage_set.exists(): stage = get_object_or_404(Stage, competition=comp, number=number) if stage.appendable_to(): stages = comp.stage_set.filter(number__gt=number).order_by('-number').all() for stage in stages: stage.number += 1 stage.save() if comp.stage_set.create(number=number + 1, type=request.POST['stage_type'], state=Stage.NOT_STARTED): out = {'success': True} return JsonResponse(out) else: return api_failure('error_adding_stage', _('Failed to add stage')) else: out = {'success': False, 'reason': 'stage_unappendable_to', 'verbose_reason': _('Stage cannot be appended to')} return JsonResponse(out) else: if comp.stage_set.create(type=stage_type, number=0): return api_success() else: return api_failure('error_adding_stage', _('Failed to add stage'))
def add_entry(request, comp): """ Manually add a single entry to a competition :param request: expecting POST parameters:\n :param str name: name of competitor to add :param str license_number: license number of the competitor to add :param str club_name: name of the club to enter competitor under :param int seed: seed of entry being added :param optional bool check_in: if true checks in entry at same time :param Competition comp: Competition to enter competitor into :return: """ if 'seed' in request.POST: try: seed = int(request.POST['seed']) except ValueError: return api_failure('seed_parse_error', _('one of the seeds could not be interpreted as a number')) else: seed = 999 entry = comp.add_entry(request.POST['license_number'], request.POST['name'], request.POST['club_name'], seed) if 'check_in' in request.POST and int(request.POST['check_in']): entry.state = Entry.CHECKED_IN entry.save() return api_success()
def check_in_all(comp): """ Check in all Un-Checked in entries of a competition :param Competition comp: Competition to check in entries for """ comp.entry_set.filter(state=Entry.NOT_CHECKED_IN).update(state=Entry.CHECKED_IN) return api_success()
def finish_stage(request, stage: Stage) -> JsonResponse: """mark a finished de_stage as finished is it is complete""" if stage.state != Stage.STARTED: return api_failure("invalid state", _("Stage not currently running")) de_stage = stage.destage_set.first() # type: DeStage if de_stage.detable_set.filter(complete=False).exists(): return api_failure('stage not finished', _('Stage not finished')) stage.state = Stage.FINISHED stage.save() return api_success()
def confirm_add(stage: Stage): """advances a stage from READY -> FINISHED :param request: expects type: "confirm_add" :param stage: Stage of type add :return: JSONResponse with either success or an error message """ if stage.state != Stage.READY: return api_failure("incorrect state", _("Stage not in READY state")) stage.state = Stage.FINISHED stage.save() return api_success()
def finish_stage(request, stage): pool_stage = stage.poolstage_set.first() if stage.state == Stage.STARTED: if all(map(lambda x: x.complete(), pool_stage.pool_set.all())): stage.state = Stage.FINISHED stage.save() return api_success() else: return api_failure('stage not finished') else: return api_failure("incorrect state", "stage not currently running")
def start_stage(request, stage: Stage) -> JsonResponse: """start a not running de stage and generate its head table""" if stage.state != Stage.NOT_STARTED: return api_failure("invalid state", "Stage has already started") de_stage = stage.destage_set.first() # type: DeStage try: de_stage.start() except Stage.NotCompleteError: return api_failure('previous stage incomplete', 'Previous stage not finished yet') stage.state = Stage.STARTED stage.save() return api_success()
def check_in(request, comp): """ Check in a single entry :param request: expecting POST parameters:\n :param int id: id of the stage to delete :param comp: Competition to check in entry for :return: """ entry = get_object_or_404(Entry, pk=request.POST['id'], competition=comp) if entry.state != Entry.NOT_CHECKED_IN: return api_failure('already_checked_in', _('That entry has already checked in')) entry.state = Entry.CHECKED_IN entry.save() return api_success()
def confirm_cull(request, stage: Stage): """confirm a cull :param request: no additional parameters :param stage: Stage of type cull to set :return: JSONResponse with either success or an error message """ cull_stage = stage.cullstage_set.first() if stage.state == Stage.NOT_STARTED: return api_failure('number not set') elif stage.state == Stage.READY: stage.state = Stage.FINISHED stage.save() return api_success() else: return api_failure("stage already complete")
def do_add_result(request, e1, e2, e1_score, e2_score, e1_victory): if e1.against() != e2: return api_failure( 'bad entry pair', "these entries aren't fighting each other this round") if (e1.entry is None and e1_victory) or (e2.entry is None and not e1_victory): return api_failure('bye_victory', _('Byes cannot win a match')) if (e1_victory and e2_score > e1_score) or (not e1_victory and e2_score < e1_score): return api_failure('score victory mismatch') e1.victory = e1_victory e1.score = e1_score e2.victory = not e1_victory e2.score = e2_score e1.save() e2.save() return api_success()
def accept_application(request, org): """Allows an organisation manager to accept applications to join an org :param request: expecting POST parameters:\n :param int user_id: id of the user who's application is being accepted :param Organisation org: organisation the application is for """ user_id = request.POST['user_id'] membership = get_object_or_404(OrganisationMembership, user_id=user_id, organisation=org) if membership.state == OrganisationMembership.APPLICANT: membership.state = OrganisationMembership.DT membership.save() return api_success() else: return api_failure("already_full_member", _("User is already a full member"))
def generate_pools(request, stage): pool_stage = stage.poolstage_set.first() previous = Stage.objects.get(competition=stage.competition, number=stage.number - 1) if stage.state != stage.NOT_STARTED: return api_failure("incorrect state", _('this stage has already generated pools')) if previous.state not in [Stage.FINISHED, Stage.LOCKED]: return api_failure('previous stage not completed yet') number = int(request.POST['number_of_pools']) entry_count = len(previous.ordered_competitors()) if entry_count / number >= 3.0 and ceil(entry_count / number) <= MAX_POOL_SIZE: pool_stage.start(number) stage.state = Stage.READY stage.save() return api_success() else: return api_failure("invalid pool size", _('produces pools with less than 3 or more than %(max_pool_size)i fencers') % {'max_pool_size': MAX_POOL_SIZE})
def delete_stage(request, comp): """delete a stage from the competition :param request: expecting POST parameters:\n :param int id: id of the stage to delete :param Competition comp: competition to delete stage from :return: """ stage_id = request.POST['id'] stage = get_object_or_404(Stage, competition=comp, pk=stage_id) if stage.deletable(): number = stage.number if stage.delete(): stages = comp.stage_set.filter(number__gt=number).order_by('number') for stage in stages: stage.number -= 1 stage.save() return api_success() else: return api_failure('deletion_failure', _('Failed to delete stage')) else: return api_failure('stage_undeletable', 'Cannot delete this stage')
def join_organisation(request, org): """create organisation memberships :param request: expecting POST parameters:\n :param int user_id: id of the user to create a membership for :param Organisation org: organisation the application is for """ user = get_object_or_404(User, pk=request.POST['user_id']) if user == request.user or request.user.has_perm( 'main.manage_organisation', org): if request.user.has_perm('main.manage_organisation', org): org.organisationmembership_set.update_or_create( user=user, state=OrganisationMembership.DT) else: org.organisationmembership_set.update_or_create( user=user, state=OrganisationMembership.APPLICANT) return api_success() else: return JsonResponse( { 'success': False, 'reason': 'InsufficientPermissions' }, status=403)