示例#1
0
    def on_message(self, message):
        yield from super().on_message(message)

        if not message.content.startswith(PREFIX):
            return

        command = Command(None, for_message=message)
        command.client = self.client

        cmd = message.content[len(PREFIX):]
        try:
            reddit_cmd = RedditCommand.objects.get(command=cmd)
            reddit_cmd.times_used = F('times_used') + 1
            reddit_cmd.save()
        except RedditCommand.DoesNotExist:
            return

        allow_nsfw = self.get_nsfw_allowed(command)
        if reddit_cmd.nsfw and not allow_nsfw:
            yield from command.reply('No NSFW commands allowed here')
            return

        yield from command.send_typing()
        subreddit = self.reddit_bot.get_subreddit(reddit_cmd.subreddit)
        logger.debug('Fetched subreddit %s', reddit_cmd.subreddit)
        submissions = [s for s in subreddit.get_hot(limit=50)]
        submission = random.choice(submissions)
        logger.debug('Picked a submission')
        yield from command.reply(submission.url)
        logger.debug('Sent message')
示例#2
0
    def seen(self, command):
        if command.message.mentions:
            if len(command.message.mentions) > 1:
                yield from command.reply('Supply one user at a time')
                return
            d_member = command.message.mentions[0]
            member = Member.objects.filter(discord_id=d_member.id).first()
            username = d_member.name
        else:
            username = command.args.name
            member = Member.objects.filter(name__iexact=username).first()
            all_members = command.message.channel.server.members
            d_member = next(
                (m for m in all_members if m.name.lower() == username.lower()),
                None)

        if d_member and d_member.status == Status.online:
            yield from command.reply('{} is currently online'.format(
                d_member.name))
            if member:
                member.last_seen = now()
                member.save()
            return

        if not member or not member.last_seen:
            yield from command.reply('Haven\'t seen {} (yet)'.format(username))
            return

        if member:
            last_message = member.messages_authored.latest('timestamp')
            reply1 = "{name} was last seen: {last_seen} ago".format(
                name=username, last_seen=timesince(member.last_seen))
            reply2 = "The last message was: ```{message}```".format(
                message=last_message.content)
            yield from command.reply("{}\n{}".format(reply1, reply2))
示例#3
0
    def on_message(self, message):
        yield from super().on_message(message)

        if not message.content.startswith(PREFIX):
            return

        command = Command(None, for_message=message)
        command.client = self.client

        cmd = message.content[len(PREFIX):]
        try:
            reddit_cmd = RedditCommand.objects.get(command=cmd)
            reddit_cmd.times_used = F('times_used') + 1
            reddit_cmd.save()
        except RedditCommand.DoesNotExist:
            return

        allow_nsfw = self.get_nsfw_allowed(command)
        if reddit_cmd.nsfw and not allow_nsfw:
            yield from command.reply('No NSFW commands allowed here')
            return

        yield from command.send_typing()
        subreddit = self.reddit_bot.get_subreddit(reddit_cmd.subreddit)
        logger.debug('Fetched subreddit %s', reddit_cmd.subreddit)
        submissions = [s for s in subreddit.get_hot(limit=50)]
        submission = random.choice(submissions)
        logger.debug('Picked a submission')
        yield from command.reply(submission.url)
        logger.debug('Sent message')
示例#4
0
 def add_status(self, command):
     """
     Adds a new status to the database
     """
     status, created = GameStatus.objects.get_or_create(status=command.args.status.strip())
     if created:
         yield from command.reply('Status `{status}` added to the database.'.format(status=status))
     else:
         yield from command.reply('Status already existed, pk: {}'.format(status.pk))
示例#5
0
    def mark_nsfw(self, command):
        sr = command.args.subreddit
        rc = RedditCommand.objects.filter(subreddit=sr, nsfw=False)
        if not rc.exists():
            yield from command.reply('No command configured for {sr}'.format(sr=sr))
            return

        updated = rc.update(nsfw=True)
        yield from command.reply('Marked **{sr}** as NSFW (affected {n} command(s))'.format(sr=sr, n=updated))
示例#6
0
 def delete_status(self, command):
     """
     Deletes the specified status (supply the ID from !list status)
     """
     id_ = command.args.id
     deleted, _ = GameStatus.objects.filter(id=id_).delete()
     if not deleted:
         yield from command.reply('Status {id} did not exist'.format(id=id_))
     else:
         yield from command.reply('Status deleted')
示例#7
0
 def remindme(self, command):
     yield from command.send_typing()
     try:
         timestamp = self.parse_time(command.args.time)
     except ValueError:
         yield from command.reply("Could not parse the time \"{}\"".format(command.args.time))
         return
     member = Member.objects.from_message(command.message)
     Message.objects.create(member=member, text=command.args.message, deliver_at=timestamp)
     yield from command.reply("I'll do so in {}".format(timeuntil(timestamp)))
示例#8
0
 def git_checkout(self, command):
     repo = Repo(settings.PROJECT_ROOT)
     branch = command.args.branch
     try:
         head = getattr(repo.heads, branch)
     except AttributeError:
         yield from command.reply('Branch `%s` does not exist' % branch)
     else:
         head.checkout()
         yield from command.reply('Checked out `%s`' % branch)
     return
示例#9
0
 def delete_status(self, command):
     """
     Deletes the specified status (supply the ID from !list status)
     """
     id_ = command.args.id
     deleted, _ = GameStatus.objects.filter(id=id_).delete()
     if not deleted:
         yield from command.reply(
             'Status {id} did not exist'.format(id=id_))
     else:
         yield from command.reply('Status deleted')
示例#10
0
 def git_checkout(self, command):
     repo = Repo(settings.PROJECT_ROOT)
     branch = command.args.branch
     try:
         head = getattr(repo.heads, branch)
     except AttributeError:
         yield from command.reply('Branch `%s` does not exist' % branch)
     else:
         head.checkout()
         yield from command.reply('Checked out `%s`' % branch)
     return
示例#11
0
    def mark_nsfw(self, command):
        sr = command.args.subreddit
        rc = RedditCommand.objects.filter(subreddit=sr, nsfw=False)
        if not rc.exists():
            yield from command.reply(
                'No command configured for {sr}'.format(sr=sr))
            return

        updated = rc.update(nsfw=True)
        yield from command.reply(
            'Marked **{sr}** as NSFW (affected {n} command(s))'.format(
                sr=sr, n=updated))
示例#12
0
 def add_status(self, command):
     """
     Adds a new status to the database
     """
     status, created = GameStatus.objects.get_or_create(
         status=command.args.status.strip())
     if created:
         yield from command.reply(
             'Status `{status}` added to the database.'.format(
                 status=status))
     else:
         yield from command.reply('Status already existed, pk: {}'.format(
             status.pk))
示例#13
0
    def allow_nsfw(self, command):
        discord_channel = command.message.channel
        if discord_channel.is_private:
            return

        channel, _ = Channel.objects.get_or_create(
            discord_id=discord_channel.id,
            defaults={'name': discord_channel.name})
        if channel.allow_nsfw:
            yield from command.reply('Channel already allowed NSFW')
            return
        channel.allow_nsfw = True
        channel.save()
        yield from command.reply('NSFW is now allowed')
示例#14
0
    def allow_nsfw(self, command):
        discord_channel = command.message.channel
        if discord_channel.is_private:
            return

        channel, _ = Channel.objects.get_or_create(
            discord_id=discord_channel.id,
            defaults={'name': discord_channel.name})
        if channel.allow_nsfw:
            yield from command.reply('Channel already allowed NSFW')
            return
        channel.allow_nsfw = True
        channel.save()
        yield from command.reply('NSFW is now allowed')
示例#15
0
    def add_subreddit(self, command):
        cmd, subreddit = command.args.cmd, command.args.subreddit

        try:
            sr = self.reddit_bot.get_subreddit(subreddit)
            nsfw = sr.over18
        except praw.errors.InvalidSubreddit:
            yield from command.reply('Subreddit `{}` does not exist'.format(subreddit))
            return

        reddit_cmd, created = RedditCommand.objects.get_or_create(
            command=cmd, defaults={'subreddit': subreddit, 'nsfw': nsfw}
        )
        tpl = 'Added %r' if created else 'Command already exists: %r'
        yield from command.reply(tpl % reddit_cmd)
示例#16
0
 def stat_messages(self, command):
     yield from command.send_typing()
     queryset = Member.objects.exclude(is_bot=True).annotate(num_messages=Count('messages_authored'))
     top_10 = queryset.order_by('-num_messages')[:10]
     data = [(member.name or str(member), member.num_messages) for member in top_10]
     output = tabulate(data, headers=('User', 'Messages'))
     yield from command.reply("```\n{}\n```".format(output))
示例#17
0
 def unsubscribe_all(self, command):
     """
     Removes all notifications subscriptions
     """
     user = command.message.author.id
     deleted, _ = GameNotification.objects.filter(user=user).delete()
     yield from command.reply('Unsubscribed you from {num} games'.format(num=deleted))
示例#18
0
 def unsubscribe_all(self, command):
     """
     Removes all notifications subscriptions
     """
     user = command.message.author.id
     deleted, _ = GameNotification.objects.filter(user=user).delete()
     yield from command.reply('Unsubscribed you from {num} games'.format(num=deleted))
示例#19
0
 def list_status(self, command):
     """
     Lists all available statuses
     """
     statuses = GameStatus.objects.values('id', 'status').order_by('id')
     msg = '\n'.join(['{id} - {status}'.format(**status) for status in statuses])
     yield from command.reply(msg)
示例#20
0
    def sysinfo(self, command):
        """
        Shows system/bot information
        """
        process = psutil.Process(os.getpid())
        mem_usage = process.memory_info().rss
        created = datetime.datetime.fromtimestamp(int(process.create_time()))

        repo = Repo(settings.PROJECT_ROOT)

        msg = (
            "Uptime: `{uptime}`\n"
            "Memory usage: `{mem}`\n"
            "OS: `{system}, {release}`\n"
            "Current branch: `{branch}`, `{commit}`, \n`{message}`\n"
        ).format(
            mem=filesizeformat(mem_usage),
            uptime=timesince(created),
            system=platform.system(),
            release=platform.release(),
            branch=repo.active_branch.name,
            commit=repo.active_branch.commit.hexsha,
            message=repo.active_branch.commit.message,
        )
        yield from command.reply(msg)
示例#21
0
    def sysinfo(self, command):
        """
        Shows system/bot information
        """
        process = psutil.Process(os.getpid())
        mem_usage = process.memory_info().rss
        created = datetime.datetime.fromtimestamp(int(process.create_time()))

        repo = Repo(settings.PROJECT_ROOT)

        msg = (
            "Uptime: `{uptime}`\n"
            "Memory usage: `{mem}`\n"
            "OS: `{system}, {release}`\n"
            "Current branch: `{branch}`, `{commit}`, \n`{message}`\n"
            "{website}, \n{github}\n"
        ).format(
            mem=filesizeformat(mem_usage),
            uptime=timesince(created),
            system=platform.system(),
            release=platform.release(),
            branch=repo.active_branch.name,
            commit=repo.active_branch.commit.hexsha,
            message=repo.active_branch.commit.message,
            website=settings.SITE_URL,
            github=settings.GITHUB_URL
        )
        yield from command.reply(msg)
示例#22
0
 def list_status(self, command):
     """
     Lists all available statuses
     """
     statuses = GameStatus.objects.values('id', 'status').order_by('id')
     msg = '\n'.join(
         ['{id} - {status}'.format(**status) for status in statuses])
     yield from command.reply(msg)
示例#23
0
 def migrate(self, command):
     """
     Migrates the database forward
     """
     out = StringIO()
     call_command('migrate', interactive=False, no_color=True, stdout=out)
     out.seek(0)
     yield from command.reply(out.read())
示例#24
0
 def migrate(self, command):
     """
     Migrates the database forward
     """
     out = StringIO()
     call_command('migrate', interactive=False, no_color=True, stdout=out)
     out.seek(0)
     yield from command.reply(out.read())
示例#25
0
    def export_stat_games(self, command):
        yield from command.reply('Generating file...')
        file_format = EXPORT_FORMATS[command.args.format or 'csv']()
        resource = GamesPlayedResource()
        dataset = resource.export(GameSession.objects.get_game_durations())
        export_data = file_format.export_data(dataset)
        if file_format.is_binary():
            _file = BytesIO(export_data)
        else:
            _file = StringIO(export_data)

        download = Download.objects.create(title='Games playtime')
        filename = '{}.{}'.format(command.command.name,
                                  file_format.get_extension())
        download.file.save(filename, File(_file))
        yield from command.reply('Download the file at {}'.format(
            download.file.url))
示例#26
0
 def unmute(self, command):
     user = command.message.author.id
     game = command.args.game
     updated = GameNotification.objects.filter(user=user, game_name__iexact=game).update(muted=False)
     if updated:
         msg = 'Unmuted {game} notifications'
     else:
         msg = '{game} notifications were not muted'
     yield from command.reply(msg.format(game=game))
示例#27
0
 def subscribe(self, command):
     """
     Sets up notifications for <game>
     """
     user = command.message.author.id
     game = command.args.game
     notification, created = GameNotification.objects.get_or_create(game_name=game.lower(), user=user)
     msg = 'Subscribed you to {game}' if created else 'You were already subscribed to {game}'
     yield from command.reply(msg.format(game=game))
示例#28
0
 def update_self(self, command):
     """
     Shortcut to update current branch
     """
     yield from command.reply('Starting full self update...')
     yield from self.git_pull(command)
     yield from self.migrate(command)
     yield from self.sysinfo(command)
     yield from self.restart(command)
示例#29
0
 def subscribe(self, command):
     """
     Sets up notifications for <game>
     """
     user = command.message.author.id
     game = command.args.game
     notification, created = GameNotification.objects.get_or_create(game_name=game.lower(), user=user)
     msg = 'Subscribed you to {game}' if created else 'You were already subscribed to {game}'
     yield from command.reply(msg.format(game=game))
示例#30
0
    def list_plugins(self, command):
        all_plugins = set(settings.PLUGINS)
        enabled = set(self.plugins)
        disabled = all_plugins ^ enabled

        msg = 'Enabled plugins: `{enabled}`\nDisabled plugins: `{disabled}`'.format(
            enabled='`, `'.join(enabled), disabled='`, `'.join(disabled)
        )
        yield from command.reply(msg)
示例#31
0
 def unsubscribe(self, command):
     """
     Removes notification subscription for <game>
     """
     user = command.message.author.id
     game = command.args.game
     deleted, _ = GameNotification.objects.filter(user=user, game_name__iexact=game).delete()
     if deleted:
         yield from command.reply('Unsubscribed you from {game}'.format(game=game))
示例#32
0
 def update_self(self, command):
     """
     Shortcut to update current branch
     """
     yield from command.reply('Starting full self update...')
     yield from self.git_pull(command)
     yield from self.migrate(command)
     yield from self.sysinfo(command)
     yield from self.restart(command)
示例#33
0
 def unsubscribe(self, command):
     """
     Removes notification subscription for <game>
     """
     user = command.message.author.id
     game = command.args.game
     deleted, _ = GameNotification.objects.filter(user=user, game_name__iexact=game).delete()
     if deleted:
         yield from command.reply('Unsubscribed you from {game}'.format(game=game))
示例#34
0
    def add_subreddit(self, command):
        cmd, subreddit = command.args.cmd, command.args.subreddit

        try:
            sr = self.reddit_bot.get_subreddit(subreddit)
            nsfw = sr.over18
        except praw.errors.InvalidSubreddit:
            yield from command.reply(
                'Subreddit `{}` does not exist'.format(subreddit))
            return

        reddit_cmd, created = RedditCommand.objects.get_or_create(
            command=cmd, defaults={
                'subreddit': subreddit,
                'nsfw': nsfw
            })
        tpl = 'Added %r' if created else 'Command already exists: %r'
        yield from command.reply(tpl % reddit_cmd)
示例#35
0
 def til(self, command):
     """
     Shows a random submission from r/todayilearned
     """
     yield from command.send_typing()
     subreddit = self.reddit_bot.get_subreddit(self.options['subreddit'])
     logger.debug('Fetched subreddit')
     submissions = [s for s in subreddit.get_hot(limit=50) if s.url]
     submission = random.choice(submissions)
     logger.debug('Picked a submission')
     yield from command.reply('{title}\n{url}'.format(url=submission.url, title=submission.title))
示例#36
0
 def daisy(self, command):
     """
     Shows a random submission from r/DaisyRidley
     """
     yield from command.send_typing()
     subreddit = self.reddit_bot.get_subreddit(self.options['subreddit'])
     logger.debug('Fetched subreddit')
     submissions = [s for s in subreddit.get_hot(limit=50) if 'imgur' in s.url]
     submission = random.choice(submissions)
     logger.debug('Picked a submission')
     yield from command.reply(submission.url)
     logger.debug('Sent message')
示例#37
0
 def change_status(self, command):
     """
     Randomly picks a new status
     """
     status = command.args.status
     if not status:
         status = GameStatus.objects.order_by('?').values_list('status', flat=True).first()
         if status is None:
             yield from command.reply('I have no known statuses...')
             return
     game = Game(name=status)
     yield from self.client.change_status(game=game, idle=False)
示例#38
0
 def change_status(self, command):
     """
     Randomly picks a new status
     """
     status = command.args.status
     if not status:
         status = GameStatus.objects.order_by('?').values_list(
             'status', flat=True).first()
         if status is None:
             yield from command.reply('I have no known statuses...')
             return
     game = Game(name=status)
     yield from self.client.change_status(game=game, idle=False)
示例#39
0
    def list_subreddits(self, command):
        i = 0
        buffer_ = []

        commands = RedditCommand.objects.all()
        allow_nsfw = self.get_nsfw_allowed(command)
        if not allow_nsfw:
            commands = commands.filter(nsfw=False)

        for reddit_cmd in commands:
            i += 1
            line = '{i}. {cmd} ({used}x used)'.format(
                i=i, cmd=reddit_cmd, used=reddit_cmd.times_used)
            if reddit_cmd.nsfw:
                line = '{} **NSFW**'.format(line)
            buffer_.append(line)

            if len(buffer_) % 10 == 0:
                yield from command.reply("\n".join(buffer_))
                buffer_ = []

        if len(buffer_):
            yield from command.reply("\n".join(buffer_))
示例#40
0
 def daisy(self, command):
     """
     Shows a random submission from r/DaisyRidley
     """
     yield from command.send_typing()
     subreddit = self.reddit_bot.get_subreddit(self.options['subreddit'])
     logger.debug('Fetched subreddit')
     submissions = [
         s for s in subreddit.get_hot(limit=50) if 'imgur' in s.url
     ]
     submission = random.choice(submissions)
     logger.debug('Picked a submission')
     yield from command.reply(submission.url)
     logger.debug('Sent message')
示例#41
0
    def list(self, command):
        """
        Lists the current notification subscriptions
        """
        user = command.message.author.id
        games = GameNotification.objects.filter(user=user).values('game_name', 'muted')

        _games = []
        for game in games:
            _games.append(
                '{name}{muted}'.format(name=game['game_name'], muted=' (muted)' if game['muted'] else '')
            )
        msg = 'You\'re subscribed to: {games}'.format(games=', '.join(_games))
        yield from command.reply(msg)
示例#42
0
    def list(self, command):
        """
        Lists the current notification subscriptions
        """
        user = command.message.author.id
        games = GameNotification.objects.filter(user=user).values('game_name', 'muted')

        _games = []
        for game in games:
            _games.append(
                '{name}{muted}'.format(name=game['game_name'], muted=' (muted)' if game['muted'] else '')
            )
        msg = 'You\'re susbcribed to: {games}'.format(games=', '.join(_games))
        yield from command.reply(msg)
示例#43
0
    def restart(self, command):
        """
        Restarts the bot.

        Check that the person sending the command has permission to restart the bot.
        We rely on ``supervisord`` here - if the process dies, supervisord will
        bring it back up.

        FIXME: https://docs.python.org/3/library/asyncio-dev.html#pending-task-destroyed
        """
        author_id = command.message.author.id
        logger.info('Restart issued by %s, with ID %s', command.message.author.name, author_id)
        yield from command.send_typing()
        yield from command.reply('Restarting...')
        raise KeyboardInterrupt
示例#44
0
    def list_subreddits(self, command):
        i = 0
        buffer_ = []

        commands = RedditCommand.objects.all()
        allow_nsfw = self.get_nsfw_allowed(command)
        if not allow_nsfw:
            commands = commands.filter(nsfw=False)

        for reddit_cmd in commands:
            i += 1
            line = '{i}. {cmd} ({used}x used)'.format(
                i=i, cmd=reddit_cmd, used=reddit_cmd.times_used
            )
            if reddit_cmd.nsfw:
                line = '{} **NSFW**'.format(line)
            buffer_.append(line)

            if len(buffer_) % 10 == 0:
                yield from command.reply("\n".join(buffer_))
                buffer_ = []

        if len(buffer_):
            yield from command.reply("\n".join(buffer_))
示例#45
0
    def restart(self, command):
        """
        Restarts the bot.

        Check that the person sending the command has permission to restart the bot.
        We rely on ``supervisord`` here - if the process dies, supervisord will
        bring it back up.

        FIXME: https://docs.python.org/3/library/asyncio-dev.html#pending-task-destroyed
        """
        author_id = command.message.author.id
        logger.info('Restart issued by %s, with ID %s', command.message.author.name, author_id)
        yield from command.send_typing()
        yield from command.reply('Restarting...')
        raise KeyboardInterrupt
示例#46
0
    def help(self, command):
        help_messages = []
        for module, plugin in self.client._method_pool.plugin_modules.items():
            if plugin is self:  # TODO: FIXME
                continue

            msgs = [cmd.as_help() for cmd in get_commands(plugin)]
            if not msgs:
                continue

            help_messages += [
                '**{plugin}**'.format(plugin=module_to_plugin_name(module))
            ] + msgs + ['']

        msg = '\n'.join(help_messages)
        yield from command.reply(msg)
示例#47
0
    def stat_games(self, command):
        yield from command.send_typing()
        games = GameSession.objects.get_game_durations()[:15]

        def format_delta(delta):
            hours, seconds = divmod(delta.seconds, 3600)
            minutes, seconds = divmod(seconds, 60)
            min_minutes = not hours and not delta.days
            return "{days} days, {hours} hours, {minutes} minutes".format(
                days=delta.days,
                hours=hours,
                minutes=max(1, minutes) if min_minutes else minutes)

        data = [(game['game__name'], format_delta(game['time']))
                for game in games]
        yield from command.reply("```\n{}\n```".format(
            tabulate(data, headers=('Game', 'Time'))))
示例#48
0
    def stat_games(self, command):
        yield from command.send_typing()
        games = GameSession.objects.filter(duration__isnull=False).values('game__name').annotate(
            time=Sum('duration'),
            num_players=Count('member', distinct=True)
        ).filter(num_players__gt=1).order_by('-time')[:15]

        def format_delta(delta):
            hours, seconds = divmod(delta.seconds, 3600)
            minutes, seconds = divmod(seconds, 60)
            min_minutes = not hours and not delta.days
            return "{days} days, {hours} hours, {minutes} minutes".format(
                days=delta.days, hours=hours, minutes=max(1, minutes) if min_minutes else minutes)

        data = [
            (game['game__name'], format_delta(game['time'])) for game in games
        ]
        yield from command.reply("```\n{}\n```".format(tabulate(data, headers=('Game', 'Time'))))
示例#49
0
 def discord_id(self, command):
     member = command.message.author
     yield from command.reply('{0.mention}: {0.id}'.format(member))
示例#50
0
 def list(self, command):
     user = command.message.author.id
     games = GameNotification.objects.filter(user=user).values_list('game_name', flat=True)
     msg = 'You\'re susbcribed to: {games}'.format(games=', '.join(games))
     yield from command.reply(msg)
示例#51
0
 def git_pull(self, command):
     repo = Repo(settings.PROJECT_ROOT)
     repo.remotes.origin.pull()
     yield from command.reply('Pulled the latest commits')
示例#52
0
 def penis(self, command):
     length = random.choice(range(3, 15))
     yield from command.reply('8{length}3'.format(length='='*length))
 def whoinvented(self, command):
     guspetti = find(lambda m: m.id == '104532370899611648',
                     command.message.server.members)
     yield from command.reply(
         "According to {guspetti}, {word} was invented by the Romans in Rome"
         .format(guspetti=guspetti.mention, word=command.args.subject))
示例#54
0
 def penis(self, command):
     """
     Draws an ASCII penis
     """
     length = random.choice(range(3, 15))
     yield from command.reply('8{length}D'.format(length='='*length))