Пример #1
0
 async def quote_delete_command(self, ctx, quote_id: str):
     """
     Delete a specific Quote with quote_id
     """
     user = self.get_user(ctx.message.author)
     server = self.get_server(ctx.message.server)
     try:
         quote = Quote.objects.get(quote_id=quote_id.strip())
         try:
             quote.delete()
             Log.objects.create(
                 message="Quote ID {} deleted by {}.\nQuote Message:\n\n{}".
                 format(quote_id, user, quote.message))
             await self.bot.say(
                 "{}, The Quote with ID `{}` has been deleted!".format(
                     ctx.message.author.mention, quote_id))
         except Exception as e:
             log_item = Log.objects.create(
                 message="{}\nError deleting Quote\n{}\nquote_id: {}".
                 format(logify_exception_info(), e, quote_id))
             await self.bot.say(
                 "{}, The Quote with ID `{}` could not be deleted! Please contact my owner with the following code: `{}`"
                 .format(ctx.message.author.mention, quote_id,
                         log_item.message_token))
     except Quote.DoesNotExist as e:
         await self.bot.say(
             "{}, A Quote qith ID `{}` cannot be found!".format())
     except Exception as e:
         log_item = Log.objects.create(
             message="{}\nError retrieving Quote\n{}\nquote_id: {}".format(
                 logify_exception_info(), e, quote_id))
         await self.bot.say(
             "{}, There was an error when trying to get your Quote. Please contact my Owner with the following code: `{}`"
             .format(ctx.message.author.mention, log_item.message_token),
             delete_after=30)
Пример #2
0
 async def prune_channels(self):
     error = False
     channels = Channel.objects.filter(private=False, game_channel=True, expire_date__lte=timezone.now(), deleted=False)
     if channels.count() >= 1:
         log_item = Log(message="Running task to prune channels:\n{}\n\n".format(logify_object(channels)))
         for channel in channels:
             if channel is None:
                 continue
             log_item.message += 'Deleting channel {}\n\n'.format(channel)
             try:
                 c = await self.bot.get_channel(channel.channel_id)
                 if c is not None:
                     try:
                         await self.bot.delete_channel(c)
                         # log_item.message += '- Success'
                     except Exception as e:
                         error = True
                         log_item.message += '- Failure\n\n{}{}\n'.format(logify_exception_info(), e)
             except Exception as e:
                 # Channel no longer exists on server
                 error = True
                 log_item.message += '- Failure\n\n{}{}\n'.format(logify_exception_info(), e)
             finally:
                 channel.deleted = True
                 channel.save()
             log_item.message += "\n\n"
             await asyncio.sleep(1)
         if error:
             log_item.save()
     else:
         # No channels found to be deleted
         pass
Пример #3
0
 async def run_scheduled_tasks(self):
     error = False
     tasks = Task.objects.filter(cancelled=False, completed=False, expire_date__lte=timezone.now())
     log_item = Log(message="Starting task processing\n")
     for task in tasks:
         # log_item.message += 'Running task for {} at {}\n'.format(task.user, timezone.now())
         if task.task == Task.ADD_TO_GAME_CHAT:
             try:
                 user = DiscordUser.objects.get(pk=task.user.pk)
                 game = Game.objects.get(pk=task.game.pk)
                 channel = Channel.objects.get(pk=task.channel.pk)
                 # log_item.message += 'Game: {}\nChannel: {}\nUser: {}\nTask PK: {}\n\n'.format(user, game, channel, task.pk)
             except Game.DoesNotExist as e:
                 error = True
                 log_item.message += '- Error finding game for task.\n{}{}\n'.format(logify_exception_info(), e)
             except Channel.DoesNotExist as e:
                 error = True
                 log_item.message += '- Error finding channel for game {}\n{}{}\n'.format(game, logify_exception_info(), e)
             except Exception as e:
                 error = True
                 log_item.message += '- Unknown error happened\n{}{}\n'.format(logify_exception_info(), e)
         else:
             # Not really a task for some reason
             # log_item.message += '- I don\'t recognize the task type \'{}\'...'.format()
             pass
         # log_item.message += '- Finished processing task\n'
         if error:
             log_item.save()
Пример #4
0
 async def quote_add_command(self, ctx, user: discord.Member, *,
                             message: str):
     """
     Create a quote for a specific User
     """
     quote_user = self.get_user(user)
     server = self.get_server(ctx.message.server)
     user = self.get_user(ctx.message.author)
     content = message.strip()
     try:
         quote = Quote.objects.create(timestamp=timezone.now(),
                                      user=quote_user,
                                      added_by=user,
                                      server=server,
                                      message=content)
         await self.bot.say(
             "{0}, Your quote was create successfully!\nThe Quote ID is `{1}`\nYou can use this to reference it in the future by typing `?quote get {1}`"
             .format(ctx.message.author.mention, quote.quote_id),
             delete_after=30)
     except Exception as e:
         log_item = Log.objects.create(
             message=
             "{}\nError creating Quote\n{}\nquote_user: {}\nuser: {}\nserver: {}\nmessage: {}\nmentions: {}"
             .format(logify_exception_info(), e, quote_user, user, server,
                     message, mentions))
         await self.bot.say(
             "{}, There was an error when trying to create your Quote. Please contact my Owner with the following code: `{}`"
             .format(ctx.message.author.mention, log_item.message_token),
             delete_after=30)
Пример #5
0
def email_log(sender, instance, *args, **kwargs):
    if isinstance(instance, Log):
        if instance.email:
            if instance.subject is None or instance.subject == '':
                subject = "Log item needs your attention"
            else:
                subject = instance.subject
            if instance.body is None or instance.body == '':
                body = instance.message
            else:
                body = instance.body

            try:
                divider = '-' * 50
                send_mail(
                    subject='{} {}'.format(settings.EMAIL_SUBJECT_PREFIX,
                                           subject),
                    message="Message Token: {0}\n\n{1}\n\n{2}\n\n{1}".format(
                        instance.message_token, divider, body),
                    from_email=settings.SERVER_EMAIL,
                    recipient_list=settings.ADMINS)
            except Exception as e:
                Log.objects.create(
                    message="Error sending email about log {}\n\n{}".format(
                        logify_exception_info()),
                    message_token='ERROR_SENDING_EMAIL')
Пример #6
0
 async def update_channels(self):
     error = False
     for server in Server.objects.all():
         # This will be to populate Channels and Users
         s = self.bot.get_server(server.server_id)
         log_item = Log(message="Starting population of channels for server {}\n\n".format(server))
         try:
             for c in s.channels:
                 if c.is_private or c.type == ChannelType.voice:
                     continue
                 channel, created = Channel.objects.get_or_create(channel_id=c.id, server=server)
                 channel.name = c.name
                 channel.created_date = pytz.timezone('UTC').localize(c.created_at)
                 channel.save()
             channels = Channel.objects.filter(server=server, deleted=False)
             # log_item.message += "Found channels:\n{}\n\n".format(logify_object(channels))
             for channel in channels:
                 try:
                     # log_item.message += "Running for channel {}\n".format(channel)
                     c = self.bot.get_channel(channel.channel_id)
                     if c.is_default:
                         # log_item.message += "- Channel is default channel, skipping...\n"
                         continue
                     if c is None:
                         # log_item.message += "- Channel is not found, marking as deleted\n"
                         c.deleted = True
                         c.save()
                         continue
                 except Exception as e:
                     error = True
                     log_item.message += "- Failed:\n{}\n{}\n".format(logify_exception_info(), e)
                 finally:
                     # log_item.message += "- Finished channel processing\n\n"
                     pass
             # log_item.message += "\n"
         except Exception as e:
             error = True
             log_item.message += "- Failed: {}\n{}\n".format(logify_exception_info(), e)
         finally:
             if error:
                 log_item.save()
Пример #7
0
def update_account_view(request):
    template = 'gaming/update_account.html'

    user = request.user
    if not user.is_authenticated():
        messages.add_message(request, messages.WARNING,
                             'Please login before accessing that page')
        return redirect('{}?next={}'.format(reverse('account_login'),
                                            reverse('account_update')))

    if request.method == 'POST':
        form = UpdateAccountForm(request.POST, instance=user)
        if form.is_valid():
            try:
                u = form.save()
                if u.is_active:
                    messages.add_message(request, messages.SUCCESS,
                                         'Profile saved successfully!')
                    form = UpdateAccountForm(instance=u)
                else:
                    return redirect('account_logout')
            except Exception as e:
                log_item = Log.objects.create(
                    message="Error saving form for user {}\n{}".format(
                        user, logify_exception_info()))
                messages.add_message(request, messages.ERROR,
                                     'An error occurred saving the settings.')
                messages.add_message(
                    request, messages.ERROR,
                    'Please contact your administrator with the following: {}'.
                    format(log_item.message_token))
        else:
            messages.add_message(request, messages.WARNING,
                                 'The form is not valid, please try again.')
    else:
        form = UpdateAccountForm(instance=user)

    context = {
        'form': form,
    }
    return render(request, template, context)
Пример #8
0
 async def quote_get_command(self, ctx, quote_id: str):
     """
     Get a specific Quote based on quote_id
     """
     server = self.get_server(ctx.message.server)
     user = self.get_user(ctx.message.author)
     quote_id = quote_id.strip()
     try:
         quote = Quote.objects.get(quote_id=quote_id.strip())
         await self.bot.say("{}".format(
             self.beautify_quote(quote, requester=user)))
     except Quote.DoesNotExist as e:
         await self.bot.say(
             "{}, I'm sorry but I can't find a quote with the ID `{}`".
             format(ctx.message.author.mention, quote_id),
             delete_after=30)
     except Exception as e:
         log_item = Log.objects.create(
             message="{}\nError retrieving Quote\n{}\nquote_id: {}".format(
                 logify_exception_info(), e, quote_id))
         await self.bot.say(
             "{}, There was an error when trying to get your Quote. Please contact my Owner with the following code: `{}`"
             .format(ctx.message.author.mention, log_item.message_token),
             delete_after=30)
Пример #9
0
 def get_user(self, member):
     """
     Returns a :class:`gaming.models.DiscordUser` object after getting or creating the user
     """
     error = False
     u, created = DiscordUser.objects.get_or_create(user_id=member.id)
     try:
         u.name = member.name
         u.bot = member.bot
         avatar_url = member.avatar_url
         if avatar_url is None or avatar_url == "":
             avatar_url = member.default_avatar_url
         u.avatar_url = avatar_url
         # Log.objects.create(message="u: {0}\ncreated: {1}\nname: {0.name}\navatar_url: {0.avatar_url}\nbot: {0.bot}".format(u, created))
     except Exception as e:
         error = True
         Log.objects.create(message="Error trying to get DiscordUser object for member: {}.\n{}".format(u, logify_exception_info()))
     finally:
         u.save()
         return u
Пример #10
0
 def get_server(self, server):
     """
     Returns a :class:`gaming.models.Server` object after getting or creating the server
     """
     error = False
     s, created = Server.objects.get_or_create(server_id=server.id)
     try:
         s.name = server.name
         s.icon = server.icon
         s.owner = self.get_user(server.owner)
         s.save()
         # Log.objects.create(message="s: {0}\ncreated: {1}\nname: {0.name}\nicon: {0.icon}\nowner: {0.owner}".format(s, created))
     except Exception as e:
         error = True
         Log.objects.create(message="Error trying to get Server object for server {}.\n{}".format(s, logify_exception_info()))
     finally:
         s.save()
         return s
Пример #11
0
    def generate_log_token(self, save=True):
        """
        Used to generate a unique token for this Log

        Called by a signal if no message_token is specified (recommended)

        If an error occurs generating a token, a new Log will be created with the exception information and a token of "ERROR_GENERATING_LOG_TOKEN"
        """
        try:
            if self.message_token is None or self.message_token == '':
                self.message_token = self.generate_token()
                if save:
                    self.save()
            return True
        except Exception as e:
            print(e)
            self.__class__.objects.create(message="{}\nError generating log token.\n\nException:\n{}".format(logify_exception_info(), e), message_token="ERROR_GENERATING_LOG_TOKEN")
            return False
Пример #12
0
    def generate_quote_id(self, save=True):
        """
        Used to generate a unique ID for this Quote

        Called by a signal if no quote_id is specified (recommended)

        If an error occurs generating an ID, a Log will be created with the exception information
        """
        try:
            if self.quote_id is None or self.quote_id == '':
                self.quote_id = self.generate_id()
                if save:
                    self.save()
            return True
        except Exception as e:
            print(e)
            Log.objects.create(message="{}\nError generating quote id.\n\nException:\n{}".format(logify_exception_info(), e))
            return False
Пример #13
0
    async def who_plays(self,
                        ctx,
                        *,
                        game_search_key: str = None,
                        page_number: str = None):
        """
        See who has played a certain game in the past
        """
        user = self.get_user(ctx.message.author)
        server = self.get_server(ctx.message.server)
        games = Game.objects.all()

        log_item = Log.objects.create(
            message="Log item for {} on {} searching for {}".format(
                user, server, game_search_key))

        if not user or user.bot:
            return

        time_ran_out = False
        game = False

        page = 0
        if page_number:
            if page_number.lower().startswith('p'):
                page = int(page_number[1::]) - 1

        if game_search_key:
            current_searches = self.get_game_searches(user=user, server=server)
            current_searches_games = [
                search.game for search in current_searches
            ]
            try:
                possible_games = Game.objects.filter(pk=int(game_search_key))
            except:
                possible_games = Game.objects.filter(
                    name__icontains=game_search_key)
            games = possible_games
        games = self.map_games(games)
        if len(games) == 1:
            game = games[1]
            game_search, created = self.create_game_search(user, game)
        else:
            msg = False
            temp_message = '{0.message.author.mention}: Which game did you want to search for?\n_Please only type in the number next to the game_\n_You have 30 seconds to respond_\n'.format(
                ctx)
            formatted_games = await self.game_beautify(
                games, reserve=len(temp_message), page=page)
            final_message = '{}{}'.format(temp_message, formatted_games)
            question_message = await self.bot.say(final_message)
            gameIDs = games.keys()

            def check(msg):
                try:
                    return int(msg.content.strip()) in gameIDs
                except:
                    return False

            msg = await self.bot.wait_for_message(author=ctx.message.author,
                                                  check=check,
                                                  timeout=30)
            if isinstance(msg, discord.Message):
                try:
                    content = msg.content.strip()
                    try:
                        possible_game = Game.objects.filter(
                            pk=games[int(content)].pk)
                    except:
                        possible_game = Game.objects.filter(
                            name__icontains=content)
                    if possible_game.count() == 1:
                        game = possible_game[0]
                except Exception as e:
                    log_item.message += '- Failed\n\n{}'.format(
                        logify_exception_info())
                await self.bot.delete_message(msg)
            else:
                time_ran_out = True
            await self.bot.delete_message(question_message)
        log_item.save()

        if game:
            temp_message = '{0.message.author.mention}\n'.format(ctx)
            await self.bot.say('{}{}'.format(
                temp_message, await
                self.game_user_beautify(game,
                                        server,
                                        user,
                                        reserve=len(temp_message),
                                        page=page)),
                               delete_after=30)
        elif time_ran_out:
            await self.bot.say(
                'Whoops... looks like your time ran out {0.message.author.mention}. Please re-run the command and try again.'
                .format(ctx),
                delete_after=30)
        else:
            await self.bot.say(
                "{0.message.author.mention}: I didn't quite understand your response, please run the command again."
                .format(ctx),
                delete_after=30)
        await self.bot.delete_message(ctx.message)
Пример #14
0
    async def looking_for_game_remove(self,
                                      ctx,
                                      *,
                                      game_search_key: str = None,
                                      page_number: str = None):
        """
        Stop searching for a game
        """
        user = self.get_user(ctx.message.author)
        server = self.get_server(ctx.message.server)
        games_removed = []

        log_item = Log.objects.create(
            message="Log item for {} on {} trying to stop searching for {}".
            format(user, server, game_search_key))

        if not user or user.bot:
            return

        page = 0
        if page_number:
            if page_number.lower().startswith('p'):
                page = int(page_number[1::]) - 1

        game_search_cancelled = False
        time_ran_out = False
        no_game_searches = False

        if game_search_key:
            games = Game.objects.filter(name__icontains=game_search_key)
        else:
            game_pks = []
            for search in self.get_game_searches(user=user):
                game_pks.append(search.game.pk)
            games = Game.objects.filter(pk__in=game_pks)
        game_removed = 'All Games'
        games = self.order_games(games)

        if games.count() == 1:
            game = games[0]
            game_search = self.get_game_searches(user=user, game=game)
            games_removed = [search.game for search in game_search]
            game_search.update(cancelled=True)
            game_search_cancelled = True
        else:
            game_searches = self.get_game_searches(user=user)
            games = []
            for game in game_searches:
                if game.game not in games:
                    games.append(game.game)
            if len(games) >= 1:
                games = self.map_games(games)
                temp_message = '{0.message.author.mention}: Which game would you like to stop searching for?\n_Please only type in the number next to the game_\n_You have 30 seconds to respond_\n'.format(
                    ctx)
                formatted_games = await self.game_beautify(games, page=page)
                final_message = '{}{}'.format(temp_message, formatted_games)
                question_message = await self.bot.say(final_message)
                gameIDs = games.keys()

                def check(msg):
                    try:
                        return int(msg.content.strip()) in gameIDs
                    except:
                        return False

                msg = False
                msg = await self.bot.wait_for_message(
                    author=ctx.message.author, check=check, timeout=30)
                if isinstance(msg, discord.Message):
                    try:
                        content = msg.content.strip()
                        try:
                            possible_game = Game.objects.filter(
                                pk=games[int(content)].pk)
                        except:
                            possible_game = Game.objects.filter(
                                name__icontains=game_pk)
                        if possible_game.count() == 1:
                            game = possible_game[0]
                            game_searches = self.get_game_searches(user=user,
                                                                   game=game)
                            game_searches.update(cancelled=True)
                            games_removed = [game]
                            game_search_cancelled = True
                    except Exception as e:
                        log_item.message += '- Failed\n\n{}'.format(
                            logify_exception_info())
                    await self.bot.delete_message(msg)
                await self.bot.delete_message(question_message)
            else:
                no_game_searches = True
        log_item.save()

        if game_search_cancelled:
            await self.bot.say(
                "{0.message.author.mention}: You've stopped searching for the following game(s):\n{1}"
                .format(
                    ctx, await self.game_beautify(games_removed,
                                                  available=False)),
                delete_after=30)
        elif time_ran_out:
            await self.bot.say(
                'Whoops... looks like your time ran out {0.message.author.mention}. Please re-run the command and try again.'
                .format(ctx),
                delete_after=30)
        elif no_game_searches:
            await self.bot.say(
                'It doesn\'t look like you\'re currently searching for any games {0.message.author.mention}.\nIf you would like to start, type {0.prefix}lfg'
                .format(ctx),
                delete_after=30)
        else:
            await self.bot.say(
                "I didn't quite understand your response {0.message.author.mention}, please run the command again."
                .format(ctx),
                delete_after=30)
        await self.bot.delete_message(ctx.message)
Пример #15
0
    async def looking_for_game(self,
                               ctx,
                               game_search_key: str = None,
                               page_number: str = None):
        """Used when users want to play a game with others
        Example: ?lfg overwatch"""
        user = self.get_user(ctx.message.author)
        games = [game for game in Game.objects.all()]
        server = self.get_server(ctx.message.server)

        log_item = Log.objects.create(
            message="Log item for {} on {} searching for {}".format(
                user, server, game_search_key))

        if not user or user.bot:
            return

        page = 0
        if page_number:
            if page_number.lower().startswith('p'):
                page = int(page_number[1::]) - 1

        game_search = False
        created = False
        create_search = False

        if game_search_key:
            current_searches = self.get_game_searches(user=user)
            current_searches_games = [
                search.game for search in current_searches
            ]
            games = []
            try:
                possible_games = Game.objects.filter(pk=int(game_search_key))
            except:
                possible_games = Game.objects.filter(
                    name__icontains=game_search_key)
            for game in possible_games:
                if game not in current_searches_games:
                    if game not in games:
                        games.append(game)
        if len(games) == 1:
            game = games[0]
        else:
            games = self.map_games(games)
            msg = False
            temp_message = '{0.message.author.mention}: Which game did you want to search for?\n_Please only type in the number next to the game_\n_You have 30 seconds to respond_\n'.format(
                ctx)
            formatted_games = await self.game_beautify(
                games, reserve=len(temp_message), page=page)
            final_message = '{}{}'.format(temp_message, formatted_games)
            question_message = await self.bot.say(final_message)
            time_ran_out = False
            gameIDs = games.keys()

            def check(msg):
                try:
                    return int(msg.content.strip()) in gameIDs
                except:
                    return False

            msg = await self.bot.wait_for_message(author=ctx.message.author,
                                                  check=check,
                                                  timeout=30)
            if isinstance(msg, discord.Message):
                try:
                    content = msg.content.strip()
                    try:
                        possible_game = Game.objects.filter(
                            pk=games[int(content)].pk)
                    except:
                        possible_game = Game.objects.filter(
                            name__icontains=content)
                    if possible_game.count() == 1:
                        game = possible_game[0]
                except Exception as e:
                    log_item.message += '- Failed\n\n{}'.format(
                        logify_exception_info())
                await self.bot.delete_message(msg)
            else:
                time_ran_out = True
            await self.bot.delete_message(question_message)

        if isinstance(game, Game):
            """
            .. todo:: Ask the user if they want to join a currently (non-full) game group
            or if they want to start their own search
            Somehow limit the number of people per group to 5 (or some other good number)
            """
            current_searches = self.get_game_searches(game=game)
            current_game_channels = self.get_game_channels(game=game)
            game_channel = None

            for channel in current_game_channels:
                c = await self.bot.get_channel(channel.channel_id)
                if c is None:
                    channel.deleted = True
                    channel.save()
                    continue
                if channel.num_users > 5:
                    continue
                else:
                    game_channel = channel
                    break

            if current_searches.count() == 0:
                create_search = True
            else:
                msg = False
                temp_message = '{0.message.author.mention}: There is a group with less than 5 people for {1.name}, would you like to join them?\n_Please only type in `yes` or `no`_\n_You have 30 seconds to respond_\n'.format(
                    ctx, game)
                question_message = await self.bot.say(temp_message)
                time_ran_out = False

                def yesno_check(msg):
                    try:
                        return msg.content.strip().lower() in ['yes', 'no']
                    except:
                        return False

                msg = await self.bot.wait_for_message(
                    author=ctx.message.author, check=yesno_check, timeout=30)
                if isinstance(msg, discord.Message):
                    try:
                        log_item.message += "Response from user about joining existing group: '{}'\n".format(
                            message.content)
                        content = msg.content.strip().lower()
                        if content == 'yes':
                            # Put the user with the group already found
                            pass
                        elif content == 'no':
                            # They said no, so start a new search
                            create_search = True
                        else:
                            raise Exception("Content is not equal to yes/no")
                    except Exception as e:
                        log_item.message += '- Failed\n\n{}'.format(
                            logify_exception_info())
                    await self.bot.delete_message(msg)
                else:
                    time_ran_out = True
                await self.bot.delete_message(question_message)

        if create_search:
            game_search, created = self.create_game_search(user, game)
        log_item.message += "game_search: {0}\ncreated: {1}\ngame_found: {2}\ntime_ran_out: {3}\ncreate_search: {4}\n".format(
            game_search, created, game_found, time_ran_out, create_search)
        log_item.save()

        if created and game_search:
            await self.bot.say(
                "{0.message.author.mention}: You've been added to the search queue for `{1.name}`!"
                .format(ctx, game),
                delete_after=30)
        elif game_found:
            await self.bot.say(
                "{0.message.author.mention}: You've been added to the current group `{1.name}`!"
                .format(ctx, game),
                delete_after=30)
        elif game_search:
            await self.bot.say(
                "{0.message.author.mention}: You're already in the queue for `{1.name}`. If you would like to stop looking for this game, type {0.prefix}lfgstop {1.name}"
                .format(ctx, gaame),
                delete_after=30)
        elif time_ran_out:
            await self.bot.say(
                'Whoops... looks like your time ran out `{0.message.author.mention}`. Please re-run the command and try again.'
                .format(ctx),
                delete_after=30)
        else:
            await self.bot.say(
                "{0.message.author.mention}: I didn't quite understand your response, please run the command again."
                .format(ctx),
                delete_after=30)
        await self.bot.delete_message(ctx.message)