Beispiel #1
0
    def assert_can_chat(self, race, user):
        can_moderate = race.category.can_moderate(user)
        can_monitor = race.can_monitor(user)

        if (not can_monitor and not race.allow_prerace_chat
                and race.is_preparing):
            raise SafeException(
                'You do not have permission to chat prior to the race.')
        if (not can_monitor and not race.allow_midrace_chat
                and (race.is_pending or race.is_in_progress)):
            raise SafeException(
                'You do not have permission to chat during the race.')
        if (not can_monitor and not race.allow_non_entrant_chat
                and not race.in_race(user)
                and (race.is_pending or race.is_in_progress)):
            raise SafeException(
                'You do not have permission to chat during the race.')

        if not can_moderate and race.chat_is_closed:
            raise SafeException(
                'This race chat is now closed. No new messages may be added.')

        if (not can_moderate and models.Message.objects.filter(
                user=user,
                race=race,
                posted_at__gte=timezone.now() - timedelta(seconds=5),
        ).count() > 10):
            raise SafeException(
                'You are chatting too much. Please wait a few seconds.')
Beispiel #2
0
    def action(self, race, user, data):
        comment = data.get('comment', '').strip()
        if comment in self.shortcuts:
            pattern = self.shortcuts[comment]
        else:
            pattern = comment

        if pattern and re.match('.*[#*?]', pattern):
            if len(pattern) > self.MAX_LENGTH:
                raise SafeException(
                    'Pattern too long. It should be at most %d characters.' %
                    self.MAX_LENGTH)
            else:
                result = re.sub('#',
                                lambda *args: random.choice(string.digits),
                                pattern)
                result = re.sub(
                    '\\*', lambda *args: random.choice(string.ascii_letters),
                    result)
                result = re.sub(
                    '\\?', lambda *args: random.choice(string.ascii_letters +
                                                       string.digits), result)
                models.Message.objects.create(
                    user=user,
                    race=race,
                    message='.random %s' % comment,
                )
                race.add_message('Random string result: ##bot##%(result)s##' %
                                 {'result': result})
        else:
            raise SafeException(
                'Usage: .random #*? (use # for a digit, * for a letter, ? for either)'
            )
Beispiel #3
0
 def action(self, race, user, data):
     team_str = (data.get('team')
                 or data.get('comment', '')).lower().strip()
     available_teams = race.get_available_teams(user)
     if not team_str:
         raise SafeException(
             'You must specify a team. Available teams are: "new" (create '
             'a new team), "%(teams)s".' %
             {'teams': '", "'.join(sorted(available_teams.keys()))}
             if available_teams else
             'You must specify a team. Available teams are: "new" (create '
             'a new team).')
     if team_str == 'new':
         race.create_team(user)
     elif team_str in available_teams:
         race.join_team(user, available_teams[team_str])
     else:
         for team in available_teams.values():
             if team.name.lower() == team_str:
                 race.join_team(user, team)
                 return
         raise SafeException(
             'Team not found. Available teams are: "new" (create a new '
             'team), "%(teams)s".' %
             {'teams': '", "'.join(sorted(available_teams.keys()))}
             if available_teams else
             'Team not found. Available teams are: "new" (create a new team).'
         )
Beispiel #4
0
    def assert_can_chat(self, race, user):
        can_moderate = race.category.can_moderate(user)
        can_monitor = race.can_monitor(user)

        if (not can_monitor and not race.allow_midrace_chat
                and race.is_in_progress):
            raise SafeException(
                'You do not have permission to chat during the race.')
        if (not can_monitor and not race.allow_non_entrant_chat
                and not race.in_race(user) and race.is_in_progress):
            raise SafeException(
                'You do not have permission to chat during the race.')

        if (not can_moderate and race.is_done
                and (race.recorded or (not race.recordable and
                                       (race.ended_at or race.cancelled_at) <=
                                       timezone.now() - timedelta(hours=1)))):
            raise SafeException(
                'This race chat is now closed. No new messages may be added.')

        if (not can_moderate and len(
                models.Message.objects.filter(
                    user=user,
                    race=race,
                    posted_at__gte=timezone.now() - timedelta(seconds=5),
                )) > 10):
            raise SafeException(
                'You are chatting too much. Please wait a few seconds.')
Beispiel #5
0
    def action(self, race, user, data):
        if not self.guid_is_new(data.get('guid', '')):
            return

        form = forms.ChatForm(data)
        if not form.is_valid():
            raise SafeException(form.errors)
        message = form.save(commit=False)

        if message.message[0] == '.':
            command, msg = (message.message[1:] + ' ').split(' ', 1)
            command = command.lower()
            if command in commands:
                race_action = commands[command]()

                if isinstance(race_action, AddComment) and not msg.strip():
                    raise SafeException('Your comment cannot be blank.')

                try:
                    return race_action.action(race, user, {'comment': msg})
                except SafeException as ex:
                    if str(ex) == 'Possible sync error. Refresh to continue.':
                        raise SafeException(
                            f'You cannot .{command} at this time (is your stream live yet?).'
                            if command == 'ready' and race.streaming_required
                            else
                            f'You cannot .{command} at this time (try reloading if you get stuck).'
                        )
                    raise

        self.assert_can_chat(race, user)

        message.user = user
        message.race = race
        message.save()
Beispiel #6
0
    def action(self, race, user, data):
        form = forms.CommentForm(data)
        if not form.is_valid():
            raise SafeException(form.errors)

        entrant = race.in_race(user)
        comment = form.cleaned_data.get('comment', '').strip()
        if entrant and comment:
            entrant.add_comment(comment)
        else:
            raise SafeException('Possible sync error. Refresh to continue.')
    def action(self, race, bot, data):
        user = self.get_user(data)

        if race.in_race(user):
            raise SafeException('%(user)s is already an entrant.' %
                                {'user': user})
        elif not race.can_join(user):
            raise SafeException('%(user)s is not allowed to join this race.' %
                                {'user': user})

        race.invite(user, bot)
Beispiel #8
0
 def assert_can_chat(self, race, bot):
     if (race.is_done
             and (race.recorded or (not race.recordable and
                                    (race.ended_at or race.cancelled_at) <=
                                    timezone.now() - timedelta(hours=1)))):
         raise SafeException(
             'This race chat is now closed. No new messages may be added.')
Beispiel #9
0
 def action(self, race, user, data):
     entrant = race.in_race(user)
     if entrant and entrant.finish_time:
         entrant.undone()
     elif entrant and entrant.dnf:
         entrant.unforfeit()
     else:
         raise SafeException('Possible sync error. Refresh to continue.')
 def get_entrant(self, race, data):
     try:
         return models.Entrant.objects.get(
             user=self.get_user(data),
             race=race,
         )
     except models.Entrant.DoesNotExist:
         raise SafeException('Specified user is not a race entrant.')
Beispiel #11
0
 def action(self, race, user, data):
     entrant = race.in_race(user)
     if entrant:
         if race.is_preparing:
             entrant.leave()
         else:
             entrant.forfeit()
     else:
         raise SafeException('Possible sync error. Refresh to continue.')
Beispiel #12
0
    def action(self, race, bot, data):
        form = RaceSetInfoForm(data=data)
        if not form.is_valid():
            raise SafeException(form.errors)

        race.info = form.cleaned_data.get('info')
        race.version = F('version') + 1
        race.save()

        race.add_message('##bot##%(bot)s## updated the race information.' %
                         {'bot': bot})
    def action(self, race, bot, data):
        if not self.guid_is_new(data.get('guid', '')):
            return

        form = forms.ChatForm(data)
        if not form.is_valid():
            raise SafeException(form.errors)

        self.assert_can_chat(race, bot)

        message = form.save(commit=False)
        message.bot = bot
        message.race = race
        message.save()
Beispiel #14
0
 def guid_is_new(self, guid):
     """
     Check if we've seen the GUID posted with this message in the last 5
     minutes. If so, it's almost certainly a duplicate message and we should
     silently ignore it.
     """
     if not re.match(r'^[0-9a-z\-]+$', guid):
         raise SafeException(
             'Bad request, no GUID supplied. A unique string is required '
             'to prevent duplicate messaging.')
     if cache.get('guid/message/' + guid):
         return False
     cache.set('guid/message/' + guid, True, 300)
     return True
    def action(self, race, bot, data):
        if 'info' in data:
            # Backwards compatibility.
            data = {'info_user': data['info']}
        form = forms.RaceSetInfoForm(data=data)
        if not form.is_valid():
            raise SafeException(form.errors)

        if 'info_bot' in form.changed_data:
            race.info_bot = form.cleaned_data.get('info_bot')
        if 'info_user' in form.changed_data:
            race.info_user = form.cleaned_data.get('info_user')
        race.version = F('version') + 1
        race.save()

        race.add_message('##bot##%(bot)s## updated the race information.' %
                         {'bot': bot})
 def assert_can_chat(self, race, bot):
     if race.chat_is_closed:
         raise SafeException(
             'This race chat is now closed. No new messages may be added.'
         )
 def get_user(self, data):
     try:
         return models.User.objects.get_by_hashid(data.get('user'))
     except models.User.DoesNotExist:
         raise SafeException('No user found matching the given ID.')
Beispiel #18
0
 def action(self, race, user, data):
     entrant = race.in_race(user)
     if entrant:
         entrant.decline_invite()
     else:
         raise SafeException('Possible sync error. Refresh to continue.')
Beispiel #19
0
 def action(self, race, user, data):
     entrant = race.in_race(user)
     if entrant:
         entrant.cancel_request()
     else:
         raise SafeException('Possible sync error. Refresh to continue.')