Example #1
0
    async def on_message(self, message, **kwargs):
        trans = self.trans

        prefix = kwargs.get("prefix")
        lang = kwargs.get("lang")

        # Check if this is a valid command
        if not is_valid_command(message.content, commands, prefix):
            return
        else:
            self.stats.add(MESSAGE)

        def startswith(*matches):
            for match in matches:
                if message.content.startswith(match):
                    return True

            return False

        # !gamedb [name]
        if startswith(prefix + "gamedb"):
            game_name = message.content[len(prefix + "gamedb "):]
            if not game_name:
                await message.channel.send(trans.get("MSG_IGDB_NONAME", lang))
                return

            game = await self.gamedb.get_game_by_name(game_name)
            if not game:
                await message.channel.send(
                    trans.get("MSG_IGDB_NO_RESULT", lang))
                return

            embed = Embed(description=game.summary)
            embed.set_image(url=game.cover_image)
            embed.set_author(name=game.name, url=game.url)

            genres = " ".join(["`{}`".format(a) for a in game.genres])
            embed.add_field(name=trans.get("MSG_IGDB_GENRES", lang),
                            value=genres)
            publishers = " ".join(["`{}`".format(a) for a in game.publishers])
            embed.add_field(name=trans.get("MSG_IGDB_PUBLISHERS", lang),
                            value=publishers,
                            inline=False)

            if game.rating:
                rating = "{} / 100".format(int(game.rating))
                embed.add_field(name=trans.get("MSG_IGDB_RATING", lang),
                                value=rating,
                                inline=False)

            if game.video:
                embed.add_field(name=trans.get("MSG_IGDB_VIDEO", lang),
                                value=game.video,
                                inline=False)

            embed.set_footer(text="Powered by idgb.com")

            await message.channel.send(embed=embed)
Example #2
0
    async def on_message(self, message, **kwargs):
        trans = self.trans

        prefix = kwargs.get("prefix")
        lang = kwargs.get("lang")

        # Check if this is a valid command
        if not is_valid_command(message.content, commands, prefix):
            return
        else:
            self.stats.add(MESSAGE)

        def startswith(*matches):
            for match in matches:
                if message.content.startswith(match):
                    return True

            return False

        # !tf [item name]
        if startswith(prefix + "tf"):
            if not self.tf.success:
                await message.channel.send(
                    trans.get("MSG_TF_UNAVAILABLE", lang))
                return

            item_name = message.content[len(prefix + "tf "):]
            if not item_name:
                await message.channel.send(trans.get("MSG_TF_NO_PARAMS", lang))
                return

            item = await self.tf.get_item_by_name(str(item_name))
            if not item:
                await message.channel.send(
                    trans.get("MSG_TF_NO_SUCH_ITEM", lang).format(item_name))
                self.stats.add(WRONG_ARG)
                return

            ls = []
            for qu in item.get_all_qualities():
                v_data = qu.get(list(qu.keys())[0])
                quality = get_quality_name(list(qu.keys())[0])
                currency = "ref" if v_data.get("price").get(
                    "currency") == "metal" else v_data.get("price").get(
                        "currency")

                ls.append("__**{}**__: `{} {}`".format(
                    quality,
                    v_data.get("price").get("value"), currency))

            det = trans.get("MSG_TF_LIST",
                            lang).format(item.name, "\n".join(ls))
            await message.channel.send(det)
Example #3
0
    async def on_message(self, message, **kwargs):
        client = self.client

        prefix = kwargs.get("prefix")
        lang = kwargs.get("lang")

        # Check if this is a valid command
        if not is_valid_command(message.content, commands, prefix):
            return
        else:
            self.stats.add(MESSAGE)

        def startswith(*matches):
            for match in matches:
                if message.content.startswith(match):
                    return True

            return False

        # Global owner filter

        if not self.handler.is_bot_owner(message.author.id):
            await message.channel.send(self.trans.get("PERM_OWNER", lang))
            return

        # nano.dev.server_info [id]
        elif startswith("nano.dev.server_info"):
            s_id = message.content[len("nano.dev.server_info "):]

            srv = utils.find(lambda b: b.id == s_id, client.guilds)

            if not srv:
                await message.channel.send("No such guild. " + StandardEmoji.CROSS)
                return

            nano_data = self.handler.get_server_data(srv)
            to_send = "{}\n```css\nMember count: {}\nChannels: {}\nOwner: {}```\n" \
                      "*Settings*: ```{}```".format(srv.name, srv.member_count, ",".join([ch.name for ch in srv.channels]), srv.owner.name, nano_data)

            await message.channel.send(to_send)

        # nano.dev.test_exception
        elif startswith("nano.dev.test_exception"):
            int("abcdef")

        # nano.dev.embed_test
        elif startswith("nano.dev.embed_test"):
            emb = Embed(title="Stats", colour=Colour.darker_grey())
            emb.add_field(name="Messages Sent", value="sample messages")

            await message.channel.send("Stats", embed=emb)

        # nano.dev.backup
        elif startswith("nano.dev.backup"):
            self.backup.manual_backup()
            await message.channel.send("Backup completed " + StandardEmoji.PERFECT)

        # nano.dev.leave_server
        elif startswith("nano.dev.leave_server"):
            try:
                sid = int(message.content[len("nano.dev.leave_server "):])
            except ValueError:
                await message.channel.send("Not a number.")
                return

            srv = await self.client.get_guild(sid)
            await srv.leave()
            await message.channel.send("Left {}".format(srv.id))

        # nano.dev.tf.reload
        elif startswith("nano.dev.tf.clean"):
            self.nano.get_plugin("tf2").instance.tf.request()

            await message.channel.send("Re-downloaded data...")

        # nano.dev.plugin.reload
        elif startswith("nano.dev.plugin.reload"):
            name = message.content[len("nano.dev.plugin.reload "):]

            v_old = self.nano.get_plugin(name).plugin.NanoPlugin.version
            s = await self.nano.reload_plugin(name)
            v_new = self.nano.get_plugin(name).plugin.NanoPlugin.version

            if s:
                await message.channel.send("Successfully reloaded **{}**\nFrom version *{}* to *{}*.".format(name, v_old, v_new))
            else:
                await message.channel.send("Something went wrong, check the logs.")

        # nano.dev.servers.clean
        elif startswith("nano.dev.servers.tidy"):
            self.handler.delete_server_by_list([s.id for s in self.client.guilds])

        # nano.restart
        elif startswith("nano.restart"):
            await message.channel.send("**DED, but gonna come back**")

            await client.logout()

            self.shutdown_mode = "restart"
            return "shutdown"

        # nano.kill
        elif startswith("nano.kill"):
            await message.channel.send("**DED**")

            await client.logout()

            self.shutdown_mode = "exit"
            return "shutdown"

        # nano.playing
        elif startswith("nano.playing"):
            status = message.content[len("nano.playing "):]

            await client.change_presence(activity=Game(name=str(status)))
            await message.channel.send("Status changed " + StandardEmoji.THUMBS_UP)

        # nano.dev.translations.reload
        elif startswith("nano.dev.translations.reload"):
            self.trans.reload_translations()

            await message.channel.send(StandardEmoji.PERFECT)

        # nano.dev.test_default_channel
        elif startswith("nano.dev.test_default_channel"):
            df = await self.default_channel(message.guild)

            if not df:
                await message.channel.send("No default channel? w a t")
                return

            await message.channel.send("Default channel is {}, sending test message".format(df.mention))
            await df.send("This is a test message. Apparently everything is ok.")

        # nano.dev.announce
        elif startswith("nano.dev.announce"):
            await message.channel.send("Sending... ")
            ann = message.content[len("nano.dev.announce "):]

            s = []
            for g in self.client.guilds:
                try:
                    d_chan = await self.default_channel(g)
                    await d_chan.send(ann)
                    log_to_file("Sent announcement for {}".format(g.name))
                    s.append(g.name)
                except DiscordException:
                    log_to_file("Couldn't send announcement for {}".format(g.name))

            await message.channel.send("Sent to {} servers".format(len(s)))

        # nano.dev.userdetective

        elif startswith("nano.dev.userdetective"):
            param = str(message.content[len(prefix + "nano.dev.userdetective"):])

            # Number
            if param.isdigit():
                user = self.client.get_user(int(param))
                if not user:
                    await message.channel.send("No user with such ID.")
                    return
            elif len(message.mentions) > 0:
                user = message.mentions[0]
            else:
                members = [user for user in self.client.get_all_members()
                           if user.name == param]

                if not members:
                    await message.channel.send("No users with that name.")
                    return

                user = members[0]

            srv_in_common = 0
            server_table_temp = []
            # Loop though servers and find ones the user is in
            for srv in self.client.guilds:
                mem = srv.get_member(user.id)
                if mem:
                    srv_in_common += 1
                    server_table_temp.append("{}: {}".format(srv.name, mem.display_name))


            join_time_ago = int((datetime.now() - user.created_at).total_seconds())
            join_time_ago = resolve_time(join_time_ago, "en")

            embed = Embed(title="{}#{}{}".format(user.name, user.discriminator, ":robot:" if user.bot else ""), description="ID: {}".format(user.id))
            embed.add_field(name="Joined Discord", value="**{}** ago\nISO time: {}".format(join_time_ago, user.created_at))
            embed.add_field(name="Avatar url", value=user.avatar_url_as(format="png"))
            embed.add_field(name="Servers in common", value="**{}** on this shard:\n```http\n{}```".format(srv_in_common, "\n".join(server_table_temp)))

            await message.channel.send(embed=embed)
Example #4
0
    async def on_message(self, message, **kwargs):
        trans = self.trans

        prefix = kwargs.get("prefix")
        lang = kwargs.get("lang")

        # Check if this is a valid command
        if not is_valid_command(message.content, commands, prefix):
            return
        else:
            self.stats.add(MESSAGE)

        def startswith(*matches):
            for match in matches:
                if message.content.startswith(match):
                    return True

            return False

        # !imdb
        if startswith(prefix + "imdb"):
            # The process can take some time so we show that something is happening
            await message.channel.trigger_typing()

            cut = message.content[len(prefix + "imdb "):]

            try:
                subcommand, argument = cut.split(" ", maxsplit=1)
            # In case there are no parameters
            except ValueError:
                # Check if no subcommand - valid
                # If there's a subcommand, but no argument, fail
                if not cut.strip(" "):
                    await message.channel.send(trans.get("MSG_IMDB_INVALID_USAGE", lang).format(prefix))
                    return

                else:
                    subcommand, argument = cut, ""

            # !imdb plot
            if subcommand == "plot":
                data = await self._imdb_search(argument, message, lang)

                # Check type
                if data.media_type not in ["tv", "movie"]:
                    await message.channel.send(trans.get("MSG_IMDB_CANTPERSON", lang))
                    return

                # Try to send
                try:
                    info = trans.get("MSG_IMDB_PLOT", lang).format(data.title, data.overview)

                    await message.channel.send(filter_text(info))
                except AttributeError:
                    await message.channel.send(trans.get("MSG_IMDB_PLOT_MISSING", lang))


            # !imdb trailer
            elif subcommand == "trailer":
                data = await self._imdb_search(argument, message, lang)

                try:
                    title, trailer = filter_text(data.title), filter_text(data.trailer)
                    await message.channel.send(trans.get("MSG_IMDB_TRAILER", lang).format(title, trailer))
                except (AttributeError, KeyError):
                    await message.channel.send(trans.get("MSG_IMDB_TRAILER_MISSING", lang))

            # !imdb rating
            elif subcommand == "rating":
                data = await self._imdb_search(argument, message, lang)

                try:
                    title, vote_avg = filter_text(data.title), filter_text(data.vote_average)
                    content = trans.get("MSG_IMDB_RATINGS", lang).format(title, vote_avg)
                    await message.channel.send(content)
                except AttributeError:
                    await message.channel.send(trans.get("MSG_IMDB_RATINGS_MISSING", lang))

            # !imdb help
            elif subcommand == "help":
                await message.channel.send(trans.get("MSG_IMDB_HELP", lang).replace("_", prefix))

            # !imdb search
            else:
                # Parse arguments
                if subcommand == "search":
                    # !imdb search the hunger games
                    query = argument
                else:
                    # !imdb the hunger games
                    query = " ".join((subcommand, argument))

                data = await self._imdb_search(query, message, lang)

                # Check type
                if data.media_type in ["tv", "movie"]:
                    info = []

                    # Step-by-step adding - some data might be missing
                    try:
                        media_type = trans.get("MSG_IMDB_SERIES", lang) if data.media_type == "tv" else ""

                        info.append("**{}** {}\n".format(data.title, media_type))
                    except AttributeError:
                        pass

                    try:
                        genres = "`{}`".format("`, `".join(data.genres))
                        info.append(trans.get("MSG_IMDB_GENRES", lang).format(genres))
                    except AttributeError:
                        pass

                    try:
                        info.append(trans.get("MSG_IMDB_AVGRATING", lang).format(data.vote_average))
                    except AttributeError:
                        pass

                    if data.media_type == "tv":
                        try:
                            info.append(trans.get("MSG_IMDB_SEASONS", lang).format(len(data.seasons)))
                        except AttributeError:
                            pass

                    try:
                        info.append(trans.get("MSG_IMDB_SUMMARY", lang).format(data.overview))
                    except AttributeError:
                        pass

                    try:
                        if data.poster:
                            info.append(trans.get("MSG_IMDB_POSTER", lang).format(data.poster))
                    except AttributeError:
                        pass

                    # Compile together info that is available
                    media_info = filter_text("\n".join(info))

                else:
                    await message.channel.send(trans.get("MSG_IMDB_PERSON_NOT_SUPPORTED", lang))
                    return

                # Send the details
                try:
                    await message.channel.send(media_info)
                except errors.HTTPException:
                    await message.channel.send(trans.get("MSG_IMDB_ERROR", lang))
Example #5
0
    async def on_message(self, message, **kwargs):
        client = self.client
        trans = self.trans

        prefix = kwargs.get("prefix")
        lang = kwargs.get("lang")

        # Check if this is a valid command
        if not is_valid_command(message.content, commands, prefix):
            return
        else:
            self.stats.add(MESSAGE)

        def startswith(*matches):
            for match in matches:
                if message.content.startswith(match):
                    return True

            return False

        # !status
        if startswith(prefix + "status"):
            server_count = 0
            members = 0
            channels = 0

            # Iterate though servers and add up things
            for guild in client.guilds:

                server_count += 1
                members += int(guild.member_count)
                channels += len(guild.channels)

            embed = Embed(name=trans.get("MSG_STATUS_STATS", lang),
                          colour=Colour.dark_blue())

            embed.add_field(name=trans.get("MSG_STATUS_SERVERS", lang),
                            value=trans.get("MSG_STATUS_SERVERS_L",
                                            lang).format(server_count),
                            inline=True)
            embed.add_field(name=trans.get("MSG_STATUS_USERS", lang),
                            value=trans.get("MSG_STATUS_USERS_L",
                                            lang).format(members),
                            inline=True)
            embed.add_field(name=trans.get("MSG_STATUS_CHANNELS", lang),
                            value=trans.get("MSG_STATUS_CHANNELS_L",
                                            lang).format(channels),
                            inline=True)

            await message.channel.send("**Stats**", embed=embed)

        # !debug
        elif startswith(prefix + "debug", prefix + "stats more"):
            # Some more debug data

            # Ratelimit every 360 seconds
            if ((self.lt - time.time()) <
                    360) and not self.handler.is_bot_owner(message.author.id):
                await message.channel.send(
                    trans.get("MSG_STATUS_RATELIMIT", lang))
                return

            self.lt = time.time()

            # CPU
            cpu = psutil.cpu_percent(interval=0.3)

            # RAM
            def get_ram_usage():
                nano_process = psutil.Process(os.getpid())
                return round(nano_process.memory_info()[0] / float(2**20),
                             1)  # Converts to MB

            mem_before = get_ram_usage()
            # Attempt garbage collection
            gc.collect()

            mem_after = get_ram_usage()
            garbage = round(mem_after - mem_before, 2)

            # OTHER
            nano_version = self.nano.version
            discord_version = d_version

            reminders = self.nano.get_plugin(
                "reminder").instance.reminder.get_reminder_amount()
            polls = self.nano.get_plugin(
                "voting").instance.vote.get_vote_amount()

            # Redis db stats
            redis_mem = self.handler.db_info("memory").get("used_memory_human")
            redis_size = self.handler.db_size()

            fields = trans.get("MSG_DEBUG_MULTI",
                               lang).format(nano_version,
                                            discord_version, mem_after,
                                            abs(garbage), cpu, reminders,
                                            polls, redis_mem, redis_size)

            total_shards = len(self.client.shards.keys())
            current_shard = message.guild.shard_id

            additional = trans.get("MSG_DEBUG_MULTI_2",
                                   lang).format(total_shards, current_shard)

            await message.channel.send(fields + "\n" + additional)

        # !prefix
        elif startswith(prefix + "prefix"):
            await message.channel.send(trans.get("MSG_PREFIX_OHYEAH", lang))

        # nano.prefix
        elif startswith("nano.prefix"):
            await message.channel.send(
                trans.get("MSG_PREFIX", lang).format(prefix))

        # !members
        elif startswith(prefix + "members"):
            ls = [member.name for member in message.guild.members]
            amount = len(ls)

            members = trans.get("MSG_MEMBERS_LIST", lang).format(", ".join(["`{}`".format(mem) for mem in ls])) + \
                      trans.get("MSG_MEMBERS_TOTAL", lang).format(amount)

            if len(members) > 2000:
                # Only send the number if the message is too long.
                await message.channel.send(
                    trans.get("MSG_MEMBERS_AMOUNT", lang).format(amount))

            else:
                await message.channel.send(members)

        # !server
        elif startswith(prefix + "server"):
            user_count = message.guild.member_count
            users_online = len([
                user.id for user in message.guild.members
                if user.status == user.status.online
            ])

            v_level = message.guild.verification_level
            if v_level == v_level.none:
                v_level = trans.get("MSG_SERVER_VL_NONE", lang)
            elif v_level == v_level.low:
                v_level = trans.get("MSG_SERVER_VL_LOW", lang)
            elif v_level == v_level.medium:
                v_level = trans.get("MSG_SERVER_VL_MEDIUM", lang)
            else:
                v_level = trans.get("MSG_SERVER_VL_HIGH", lang)

            text_chan = len(message.guild.text_channels)
            voice_chan = len(message.guild.voice_channels)
            channels = text_chan + voice_chan

            # Teal Blue
            embed = Embed(colour=Colour(0x3F51B5),
                          description=trans.get("MSG_SERVER_ID",
                                                lang).format(message.guild.id))

            if message.guild.icon:
                embed.set_author(name=message.guild.name,
                                 icon_url=message.guild.icon_url)
                embed.set_thumbnail(url=message.guild.icon_url)
            else:
                embed.set_author(name=message.guild.name)

            embed.set_footer(text=trans.get("MSG_SERVER_DATE_CREATED", lang).
                             format(message.guild.created_at))

            embed.add_field(name=trans.get("MSG_SERVER_MEMBERS",
                                           lang).format(user_count),
                            value=trans.get("MSG_SERVER_MEMBERS_L",
                                            lang).format(users_online))

            embed.add_field(name=trans.get("MSG_SERVER_CHANNELS",
                                           lang).format(channels),
                            value=trans.get("MSG_SERVER_CHANNELS_L",
                                            lang).format(
                                                voice_chan, text_chan))

            embed.add_field(name=trans.get("MSG_SERVER_VL", lang),
                            value=v_level)
            embed.add_field(
                name=trans.get("MSG_SERVER_ROLES", lang),
                value=trans.get("MSG_SERVER_ROLES_L",
                                lang).format(len(message.guild.roles) - 1))

            owner = message.guild.owner

            embed.add_field(name=trans.get("MSG_SERVER_OWNER", lang),
                            value=trans.get("MSG_SERVER_OWNER_L", lang).format(
                                owner.name, owner.discriminator, owner.id))

            await message.channel.send(trans.get("MSG_SERVER_INFO", lang),
                                       embed=embed)
Example #6
0
    async def on_message(self, message, **kwargs):
        client = self.client
        trans = self.trans

        prefix = kwargs.get("prefix")
        lang = kwargs.get("lang")

        # Custom commands registered for the server
        server_commands = self.handler.get_custom_commands_keys(
            message.guild.id)

        if server_commands:
            # According to tests, .startswith is faster than slicing, m8pls
            for k in server_commands:
                k = str(k)

                if message.content.startswith(k):
                    # raw_resp = self.handler.get_custom_command_by_key(message.guild.id, k)
                    # response = self.parser.parse(raw_resp, message)
                    response = self.handler.get_custom_command_by_key(
                        message.guild.id, k)

                    await message.channel.send(response)
                    return

        # Check if this is a valid command
        if not is_valid_command(message.content, commands, prefix):
            return
        else:
            self.stats.add(MESSAGE)

        def startswith(*matches):
            for match in matches:
                if message.content.startswith(match):
                    return True

            return False

        # COMMANDS

        # !hello
        if startswith(prefix + "hello"):
            argument = message.content[len(prefix + "hello "):]

            # Parse mentions or name
            if argument:
                if len(message.mentions) > 0:
                    mention = message.mentions[0].mention
                else:
                    # Find user
                    usr = utils.find(lambda a: a.name == argument,
                                     message.guild.members)
                    if not usr:
                        mention = message.author.mention
                    else:
                        mention = usr.mention
            else:
                mention = message.author.mention

            if len(message.mentions) >= 1:
                await message.channel.send(
                    trans.get("INFO_HI", lang).format(mention))
            elif len(message.mentions) == 0:
                await message.channel.send(
                    trans.get("INFO_HI", lang).format(mention))

        # !uptime
        elif startswith(prefix + "uptime"):
            d = datetime(
                1, 1, 1) + timedelta(seconds=time.time() - self.nano.boot_time)
            uptime = trans.get("MSG_UPTIME",
                               lang).format(d.day - 1, d.hour, d.minute,
                                            d.second)

            await message.channel.send(uptime)

        # !nano, nano.info
        elif startswith((prefix + "nano", "nano.info")):
            await message.channel.send(
                trans.get("INFO_GENERAL", lang).format(p=prefix,
                                                       ver=self.nano.version))

        # !github
        elif startswith(prefix + "github"):
            await message.channel.send(trans.get("INFO_GITHUB", lang))

        # !roll [number]
        elif startswith(prefix + "roll", prefix + "rng "):
            if startswith(prefix + "roll"):
                num = message.content[len(prefix + "roll "):]
            else:
                num = message.content[len(prefix + "rng "):]

            if not num.isnumeric():
                await message.channel.send(trans.get("ERROR_NOT_NUMBER", lang))
                return

            rn = randint(0, int(num))
            result = "**{}**. {}".format(rn,
                                         "**GG**" if rn == int(num) else "")

            await message.channel.send(
                trans.get("MSG_ROLL", lang).format(message.author.mention,
                                                   result))

        # !dice [dice expression: 5d6 + 1d8]
        elif startswith(prefix + "dice"):
            cut = message.content[len(prefix + "dice "):]

            # Defaults to a normal dice
            if not cut:
                dice_types = ["1d6"]
            else:
                dice_types = [a.strip(" ") for a in cut.split("+")]

            # To prevent lag
            if len(dice_types) > MAX_DICE_EXPR:
                await message.channel.send(
                    trans.get("MSG_DICE_TOO_MANY", lang).format(MAX_DICE_EXPR))
                return

            results = []
            tt = 0
            for dice in dice_types:
                try:
                    times, sides = dice.split("d")
                    times, sides = int(times), int(sides)

                    if sides <= 0 or times <= 0:
                        raise ValueError("can't roll 0 sides/times")

                except ValueError:
                    await message.channel.send(
                        trans.get("MSG_DICE_INVALID",
                                  lang).replace("_", prefix))
                    return

                if times > MAX_DICE or sides > MAX_DICE:
                    await message.channel.send(
                        trans.get("MSG_DICE_TOO_BIG", lang).format(MAX_DICE))
                    return

                total = 0
                for _ in range(times):
                    total += randint(1, sides)

                tt += total

                results.append(
                    trans.get("MSG_DICE_ENTRY", lang).format(dice, total))

            await message.channel.send(
                trans.get("MSG_DICE_RESULTS",
                          lang).format(message.author.mention,
                                       "\n".join(results), tt))

        # !ping
        elif startswith(prefix + "ping"):
            base_time = datetime.now() - message.created_at
            base_taken = int(divmod(base_time.total_seconds(), 60)[1] * 1000)

            a = await message.channel.send(
                trans.get("MSG_PING_MEASURING", lang))
            self.pings[a.id] = [time.monotonic(), a, base_taken]

            # Thumbs up
            await a.add_reaction("\U0001F44D")
            self.stats.add(PING)

        # !decide [item1]|[item2]|etc...
        elif startswith(prefix + "decide"):
            cut = str(message.content)[len(prefix + "decide "):].strip(" ")

            if not cut:
                await message.channel.send(
                    trans.get("MSG_DECIDE_NO_ARGS", lang))
                return

            # If | is not used, try spaces
            options = cut.split("|")
            if len(options) == 1:
                options = cut.split(" ")

            if len(options) == 1:
                await message.channel.send(
                    trans.get("MSG_DECIDE_SPECIAL", lang).format(cut))

            else:
                rn = randint(0, len(options) - 1)
                await message.channel.send(
                    trans.get("MSG_DECIDE_NORMAL", lang).format(options[rn]))

        # !8ball
        elif startswith(prefix + "8ball"):
            eight_ball = [
                a.strip(" ")
                for a in trans.get("MSG_8BALL_STRINGS", lang).split("|")
            ]
            answer = eight_ball[randint(0, len(eight_ball) - 1)]

            await message.channel.send(
                trans.get("MSG_8BALL", lang).format(answer))

        # !quote
        elif startswith(prefix + "quote"):
            chosen = str(quotes[randint(0, len(quotes) - 1)])

            # Find the part where the author is mentioned
            place = chosen.rfind("–")
            await message.channel.send("{}\n- __{}__".format(
                chosen[:place], chosen[place + 1:]))

        # !invite
        elif startswith(prefix + "invite", "nano.invite"):
            # ONLY FOR TESTING - if nano beta is active
            if startswith("nano.invite.make_real"):
                application = await client.application_info()

                # Most of the permissions that Nano uses
                perms = "1543765079"
                url = "<https://discordapp.com/oauth2/" \
                      "authorize?client_id={}&scope=bot&permissions={}>".format(application.id, perms)

                await message.channel.send(
                    trans.get("INFO_INVITE", lang).replace("<link>", url))
                return

            await message.channel.send(
                trans.get("INFO_INVITE",
                          lang).replace("<link>",
                                        "<http://invite.nanobot.pw>"))

        # !avatar
        elif startswith(prefix + "avatar"):
            name = message.content[len(prefix + "avatar "):]

            if not name:
                member = message.author
            else:
                member = await self.resolve_user(name, message, lang)

            url = member.avatar_url

            if url:
                await message.channel.send(
                    trans.get("MSG_AVATAR_OWNERSHIP",
                              lang).format(member.name, url))
            else:
                await message.channel.send(
                    trans.get("MSG_AVATAR_NONE", lang).format(member.name))

        # !say (#channel) [message]
        elif startswith(prefix + "say"):
            if not self.handler.is_mod(message.author, message.guild):
                await message.channel.send(trans.get("PERM_MOD", lang))
                return "return"

            content = str(message.content[len(prefix + "say "):]).strip(" ")

            if not content:
                await message.channel.send(
                    trans.get("ERROR_INVALID_CMD_ARGUMENTS", lang))
                return

            if len(message.channel_mentions) != 0:
                channel = message.channel_mentions[0]
                content = content.replace(channel.mention, "").strip(" ")
            else:
                channel = message.channel

            content = self.at_everyone_filter(content, message.author)

            try:
                await channel.send(content)
                await self.log_say_command(message, content, prefix, lang)
            except Forbidden:
                await message.channel.send(
                    trans.get("MSG_SAY_NOPERM", lang).format(channel.id))
Example #7
0
    async def on_message(self, message, **kwargs):
        assert isinstance(message, Message)

        prefix = kwargs.get("prefix")

        trans = self.trans
        lang = kwargs.get("lang")

        if not is_valid_command(message.content, commands, prefix=prefix):
            return
        else:
            self.stats.add(MESSAGE)

        def startswith(*msg):
            for a in msg:
                if message.content.startswith(a):
                    return True

            return False

        if startswith(prefix + "wiki", prefix + "define"):
            if startswith(prefix + "wiki"):
                search = str(message.content)[len(prefix +
                                                  "wiki "):].strip(" ")
            elif startswith(prefix + "define"):
                search = str(message.content)[len(prefix +
                                                  "define "):].strip(" ")
            else:
                # Not possible, but k
                return

            if not search:
                await message.channel.send(trans.get("MSG_WIKI_NO_QUERY",
                                                     lang))
                return

            summary = await self.wiki.get_definition(search)

            if not summary:
                await message.channel.send(trans.get("MSG_WIKI_NO_DEF", lang))
                return

            await message.channel.send(
                trans.get("MSG_WIKI_DEFINITION", lang).format(
                    search, add_dots(summary, max_len=MAX_WIKI_LENGTH)))

        elif startswith(prefix + "urban"):
            search = str(message.content)[len(prefix + "urban "):].strip(" ")

            if not search:
                await message.channel.send(
                    trans.get("MSG_URBAN_NO_QUERY", lang))
                return

            description = await self.urban.urban_dictionary(search)

            if not description:
                await message.channel.send(trans.get("MSG_URBAN_NO_DEF", lang))
                return

            await message.channel.send(
                trans.get("MSG_URBAN_DEFINITION", lang).format(
                    search, add_dots(description, max_len=MAX_URBAN_LENGTH)))
Example #8
0
    async def on_message(self, message, **kwargs):
        trans = self.trans

        prefix = kwargs.get("prefix")
        lang = kwargs.get("lang")

        # If any of the commands match, add user to statistics
        if message.content.startswith(prefix):
            np_text = message.content[len(prefix):]
        else:
            np_text = message.content

        np_text = "_" + np_text.split(" ", maxsplit=1)[0]
        if np_text in self.valid_commands:
            # Register user to stats
            self.adv_stats.track_user(message.author.id, message.guild.id)

        # Check if this is a valid command
        if not is_valid_command(message.content, commands, prefix):
            return
        else:
            self.stats.add(MESSAGE)

        def startswith(*matches):
            for match in matches:
                if message.content.startswith(match):
                    return True

            return False

        # !stats
        if startswith(prefix + "stats"):
            stats = self.stats.get_data()

            messages = stats.get("msgcount") or 0
            wrong_args = stats.get("wrongargcount") or 0
            sleeps = stats.get("timesslept") or 0
            wrong_permissions = stats.get("wrongpermscount") or 0
            helps = stats.get("peoplehelped") or 0
            votes = stats.get("votesgot") or 0
            pings = stats.get("timespinged") or 0
            imgs = stats.get("imagessent") or 0

            embed = Embed(colour=Colour.gold())

            embed.add_field(name=trans.get("MSG_STATS_MSGS", lang),
                            value=messages)
            embed.add_field(name=trans.get("MSG_STATS_ARGS", lang),
                            value=wrong_args)
            embed.add_field(name=trans.get("MSG_STATS_PERM", lang),
                            value=wrong_permissions)
            embed.add_field(name=trans.get("MSG_STATS_HELP", lang),
                            value=helps)
            embed.add_field(name=trans.get("MSG_STATS_IMG", lang), value=imgs)
            embed.add_field(name=trans.get("MSG_STATS_VOTES", lang),
                            value=votes)
            embed.add_field(name=trans.get("MSG_STATS_SLEPT", lang),
                            value=sleeps)
            embed.add_field(name=trans.get("MSG_STATS_PONG", lang),
                            value=pings)
            embed.add_field(name=trans.get("MSG_STATS_IMG", lang), value=imgs)

            await message.channel.send(trans.get("MSG_STATS_INFO", lang),
                                       embed=embed)

        # !advancedstats
        elif startswith(prefix + "advancedstats"):
            u_users, u_guilds = self.adv_stats.get_statistics_uniques()

            data = self.adv_stats.get_statistics_history()

            description = trans.get("MSG_ADVS_DESC", lang).format(u_users, u_guilds) \
                        + "\n\n"\
                        + trans.get("MSG_ADVS_HISTORY", lang)\
                        + trans.get("MSG_ADVS_HISTORY_BODY", lang).format(
                                day_u=data["day"]["users"],
                                day_g=data["day"]["guilds"],
                                week_u=data["week"]["users"],
                                week_g=data["week"]["guilds"],
                                month_u=data["month"]["users"],
                                month_g=data["month"]["guilds"],
                            )

            embed = Embed(title=trans.get("MSG_ADVS_TITLE",
                                          lang).format(NanoPlugin.version),
                          description=description)

            await message.channel.send(embed=embed)
Example #9
0
    async def on_message(self, message, **kwargs):
        trans = self.trans

        prefix = kwargs.get("prefix")
        lang = kwargs.get("lang")

        # Check if this is a valid command
        if not is_valid_command(message.content, commands, prefix):
            return
        else:
            self.stats.add(MESSAGE)

        def startswith(*matches):
            for match in matches:
                if message.content.startswith(match):
                    return True

            return False

        # !poll start
        # Arguments: "[title]" [option1]|(option2)|...
        # OR       : "[title]" [option1],(option2),...
        if startswith(prefix + "poll start"):
            if not self.handler.is_admin(message.author, message.guild):
                await message.channel.send(trans.get("PERM_ADMIN", lang))
                self.stats.add(WRONG_PERMS)
                return

            if self.vote.in_progress(message.guild.id):
                await message.channel.send(
                    trans.get("MSG_VOTING_IN_PROGRESS", lang))
                return

            arguments = message.content[len(prefix +
                                            "poll start "):].strip(" ")
            if not arguments:
                await message.channel.send(
                    trans.get("MSG_VOTING_I_USAGE", lang).format(prefix))
                return

            # TITLE
            # Handle short_title, "longer title", 'also like this'
            if arguments[0] == "\"":
                _, title, arguments = arguments.split("\"", maxsplit=3)
            elif arguments[0] == "'":
                _, title, arguments = arguments.split("'", maxsplit=3)
            else:
                title, arguments = arguments.split(" ", maxsplit=1)

            arguments = arguments.lstrip(" ")

            # CHOICES
            # | as separator
            if "|" in arguments:
                items = [a.strip(" ") for a in arguments.split("|") if a]
            # , used as separator
            else:
                items = [a.strip(" ") for a in arguments.split(",") if a]

            # Send an error if there's only a title
            if len(items) < 2:
                await message.channel.send(
                    trans.get("MSG_VOTING_NEED_OPTIONS", lang).format(prefix))
                return
            # END OF ARGUMENT PARSING

            # Check item amount
            if len(items) > VOTE_ITEM_LIMIT:
                await message.channel.send(
                    trans.get("MSG_VOTING_OPTIONS_TM",
                              lang).format(VOTE_ITEM_LIMIT, len(items)))
                return

            # Check total length
            if (len(title) + sum([len(a)
                                  for a in items])) > VOTE_ITEM_MAX_LENGTH:
                await message.channel.send(
                    trans.get("MSG_VOTING_OPTIONS_TL ",
                              lang).format(VOTE_ITEM_MAX_LENGTH,
                                           sum([len(a) for a in items])))
                return

            # Check if any option is empty
            if any(e == "" for e in items):
                await message.channel.send(
                    trans.get("MSG_VOTING_EMPTY_ITEM", lang))
                return

            self.vote.start_vote(message.author.id, message.guild.id, title,
                                 items)

            # Generates a list of options to show
            choices = "\n\n".join([
                "[{}]\n{}".format(en + 1, ch) for en, ch in enumerate(
                    self.vote.get_choices(message.guild.id))
            ])

            await message.channel.send(
                trans.get("MSG_VOTING_STARTED", lang).format(title, choices))

        # !poll end
        elif startswith(prefix + "poll end"):
            if not self.handler.is_admin(message.author, message.guild):
                await message.channel.send(trans.get("PERM_ADMIN", lang))
                self.stats.add(WRONG_PERMS)
                return

            if not self.vote.in_progress(message.guild.id):
                await message.channel.send(
                    trans.get("MSG_VOTING_NO_PROGRESS", lang))
                return

            # Wait for confirmation
            msg = await message.channel.send(
                trans.get("MSG_VOTING_END_CONFIRMATION",
                          lang).format(OK_EMOJI))
            await msg.add_reaction(OK_EMOJI)

            def check(reaction, user):
                return user == message.author and str(
                    reaction.emoji) == OK_EMOJI

            try:
                await self.client.wait_for('reaction_add',
                                           timeout=45,
                                           check=check)
            except asyncio.TimeoutError:
                await message.channel.send(
                    trans.get("MSG_VOTING_END_ABORT", lang))
                return

            await msg.delete()

            votes = self.vote.get_votes(message.guild.id)
            title = self.vote.get_title(message.guild.id)

            total_votes = sum(votes.values())

            embed = Embed(title="**{}**".format(title),
                          colour=Colour(0x303F9F),
                          description=trans.get("MSG_VOTING_AMOUNT",
                                                lang).format(total_votes))

            for name, val in votes.items():
                # Zero-width space
                dotted = add_dots(name, max_len=240) or "\u200B"
                embed.add_field(name=dotted,
                                value=trans.get("MSG_VOTING_AMOUNT2",
                                                lang).format(val))

            # Actually end the voting
            self.vote.end_voting(message.guild.id)

            try:
                await message.channel.send(
                    trans.get("MSG_VOTING_ENDED", lang) + "\n", embed=embed)
            except errors.HTTPException as e:
                await message.channel.send(trans.get("MSG_VOTING_ERROR", lang))
                log_to_file("VOTING ({}): {}".format(e, embed.to_dict()),
                            "bug")

        # !poll status
        elif startswith(prefix + "poll status"):
            if not self.vote.in_progress(message.guild.id):
                await message.channel.send(
                    trans.get("MSG_VOTING_NO_PROGRESS", lang))
                return

            header = self.vote.get_title(message.guild.id)
            votes = sum(self.vote.get_votes(message.guild.id).values())

            if votes == 0:
                vote_disp = trans.get("MSG_VOTING_S_NONE", lang)
            elif votes == 1:
                vote_disp = trans.get("MSG_VOTING_S_ONE", lang)
            else:
                vote_disp = trans.get("MSG_VOTING_S_MULTI", lang).format(votes)

            await message.channel.send(
                trans.get("MSG_VOTING_STATUS", lang).format(header, vote_disp))

        # !vote
        elif startswith(prefix + "vote"):
            # Ignore if there is no vote going on instead of getting an exception
            if not self.vote.in_progress(message.guild.id):
                await message.add_reaction(X_EMOJI)

                msg = await message.channel.send(
                    trans.get("MSG_VOTING_NO_PROGRESS", lang))
                await asyncio.sleep(2)
                await msg.delete()

                return

            # Get the choice, but tell the author if he/she didn't supply a number
            try:
                choice = int(message.content[len(prefix + "vote "):]) - 1
            # Cannot convert to int
            except ValueError:
                await message.add_reaction(BLOCK_EMOJI)

                m = await message.channel.send(
                    trans.get("MSG_VOTING_NOT_NUMBER", lang))
                await asyncio.sleep(2)
                await m.delete()
                return

            res = self.vote.plus_one(choice, message.author.id,
                                     message.guild.id)

            # User already voted
            if res == -1:
                await message.add_reaction(BLOCK_EMOJI)

                msg = await message.channel.send(
                    trans.get("MSG_VOTING_CHEATER", lang))
                await asyncio.sleep(2)
                await msg.delete()

            # No such option
            elif not res:
                await message.add_reaction(X_EMOJI)

                msg = await message.channel.send(
                    trans.get("MSG_VOTING_INVALID_NUMBER", lang))
                await asyncio.sleep(2)
                await msg.delete()

            # Everything ok, was added
            else:
                await message.add_reaction(OK_EMOJI)

            self.stats.add(VOTE)
Example #10
0
    async def on_message(self, message, **kwargs):
        trans = self.trans

        prefix = kwargs.get("prefix")
        lang = kwargs.get("lang")

        # Check if this is a valid command
        if not is_valid_command(message.content, commands, prefix):
            return
        else:
            self.stats.add(MESSAGE)

        def startswith(*matches):
            for match in matches:
                if message.content.startswith(match):
                    return True

            return False

        # !remind me in [time]:[text] or [time] to [text]
        if startswith(prefix + "remind me in"):
            try:
                r_time, text = await self.parse_parameters(
                    message,
                    len(prefix) + 13, lang,
                    trans.get("MSG_REMINDER_WU_ME",
                              lang).format(prefix=prefix))
            # Raised when reminder content is too long
            except ValueError:
                await message.channel.send(
                    trans.get("MSG_REMINDER_TOO_LONG_CONTENT",
                              lang).format(REM_MAX_CONTENT))
                return

            resp = self.reminder.set_reminder(message.author, message.author,
                                              text, r_time, lang)

            # Too many reminders going on
            if resp == -1:
                await message.channel.send(
                    trans.get("MSG_REMINDER_LIMIT_EXCEEDED",
                              lang).format(DEFAULT_REMINDER_LIMIT))

            # Invalid range
            elif resp is False:
                await message.channel.send(
                    trans.get("MSG_REMINDER_INVALID_RANGE",
                              lang).format(REM_MIN_DURATION, REM_MAX_DAYS))

            # Everything valid
            else:
                await message.channel.send(trans.get("MSG_REMINDER_SET", lang))

        # !remind here in [time]:[reminder]
        elif startswith(prefix + "remind here in"):
            try:
                r_time, text = await self.parse_parameters(
                    message,
                    len(prefix) + 13, lang,
                    trans.get("MSG_REMINDER_WU_HERE",
                              lang).format(prefix=prefix))
            # Raised when reminder content is too long
            except ValueError:
                await message.channel.send(
                    trans.get("MSG_REMINDER_TOO_LONG_CONTENT",
                              lang).format(REM_MAX_CONTENT))
                return

            resp = self.reminder.set_reminder(message.channel,
                                              message.author,
                                              text,
                                              r_time,
                                              lang,
                                              reminder_type=REMINDER_CHANNEL)

            if resp == -1:
                await message.channel.send(
                    trans.get("MSG_REMINDER_LIMIT_EXCEEDED",
                              lang).format(DEFAULT_REMINDER_LIMIT))

            elif resp is False:
                await message.channel.send(
                    trans.get("MSG_REMINDER_INVALID_RANGE",
                              lang).format(REM_MIN_DURATION, REM_MAX_DAYS))

            else:
                await message.channel.send(trans.get("MSG_REMINDER_SET", lang))

        # !remind list
        elif startswith(prefix + "remind list", prefix + "reminder list"):
            reminders = self.reminder.get_reminders(message.author.id)

            if not reminders:
                await message.channel.send(
                    trans.get("MSG_REMINDER_LIST_NONE", lang))
                return

            rem = []
            rem_literal = trans.get("MSG_REMINDER_LIST_L", lang)

            for reminder in reminders.values():
                # Gets the remaining time
                ttl = int(reminder["time_target"]) - time.time()

                cont = self.filter(reminder.get("raw"), message.author)

                # Zero or negative number
                if ttl <= 0:
                    when = trans.get("MSG_REMINDER_SOON", lang)
                else:
                    when = resolve_time(ttl, lang)

                rem.append(rem_literal.format(cont, when))

            await message.channel.send(
                trans.get("MSG_REMINDER_LIST", lang).format("\n\n".join(rem)))

        # !remind remove
        elif startswith(prefix + "remind remove"):
            r_name = message.content[len(prefix + "remind remove "):]

            if not r_name:
                await message.channel.send(
                    trans.get("ERROR_INVALID_CMD_ARGUMENTS", lang))
                return

            if r_name == "all":
                self.reminder.remove_all_reminders(message.author.id)
                await message.channel.send(
                    trans.get("MSG_REMINDER_DELETE_ALL", lang))
                return

            else:
                r_id = self.reminder.find_id_from_content(
                    message.author.id, r_name)

                # No reminder with such content
                if not r_id:
                    await message.channel.send(
                        trans.get("MSG_REMINDER_DELETE_NONE", lang))
                else:
                    self.reminder.remove_reminder(message.author.id, r_id)
                    await message.channel.send(
                        trans.get("MSG_REMINDER_DELETE_SUCCESS", lang))

        # !remind help
        elif startswith(prefix + "remind"):
            await message.channel.send(
                trans.get("MSG_REMINDER_HELP", lang).format(prefix=prefix))
Example #11
0
    async def on_message(self, message, **kwargs):
        trans = self.trans
        mc = self.mc

        prefix = kwargs.get("prefix")
        lang = kwargs.get("lang")

        # Check if this is a valid command
        if not is_valid_command(message.content, commands, prefix):
            return
        else:
            self.stats.add(MESSAGE)

        def startswith(*matches):
            for match in matches:
                if message.content.startswith(match):
                    return True

            return False

        # !mc
        if startswith(prefix + "mc"):
            argument = message.content[len(prefix + "mc "):].strip(" ").lower()

            if not argument:
                await message.channel.send(trans.get("MSG_MC_PLSARUGMENTS", lang))
                return

            # !mc help
            if argument == "help":
                await message.channel.send(trans.get("MSG_MC_HELP", lang).replace("_", prefix))
                return

            # Argument is name
            if not is_number(argument.split(":")[0]):
                # Check for groupings
                gr = mc.get_group_by_name(argument)
                if gr:
                    data = gr
                # Not a group
                else:
                    data = mc.find_by_name(str(argument))

            # Argument is id and meta
            else:
                try:
                    i_type, i_meta = argument.split(":")
                except ValueError:
                    i_type, i_meta = argument, 0

                data = mc.find_by_id_meta(i_type, i_meta)

            if not data:
                await message.channel.send(trans.get("MSG_MC_NO_ITEMS", lang))
                self.stats.add(WRONG_ARG)
                return

            # One item, not a group
            if not isinstance(data, list):
                details = trans.get("MSG_MC_DETAILS", lang).format(data.get("name"), data.get("type"), data.get("meta"))

                # Details are uploaded simultaneously with the picture

                # No image
                path = mc.get_picture_path_by_item(data)
                if not path:
                    await message.channel.send(details)
                    self.stats.add(IMAGE_SENT)
                else:
                    with open(mc.get_picture_path_by_item(data), "rb") as pic:
                        await message.channel.send(details, file=File(pic))
                        self.stats.add(IMAGE_SENT)

            # Multiple items, a group
            else:
                combined = []
                for item in data:
                    details = trans.get("MSG_MC_DETAILS", lang).format(item.get("name"), item.get("type"), item.get("meta"))
                    combined.append(details)

                await message.channel.send("".join(combined))
Example #12
0
File: steam.py Project: RossKM/Nano
    async def on_message(self, message, **kwargs):
        prefix = kwargs.get("prefix")

        trans = self.trans
        lang = kwargs.get("lang")

        if not is_valid_command(message.content, commands, prefix=prefix):
            return
        else:
            self.stats.add(MESSAGE)

        def startswith(*msg):
            for a in msg:
                if message.content.startswith(a):
                    return True

            return False

        if startswith(prefix + "steam"):
            await message.channel.trigger_typing()

            cut = message.content[len(prefix + "steam "):].strip(" ")

            try:
                subcommand, argument = cut.split(" ", maxsplit=1)
            # In case there are no parameters
            except ValueError:
                # Check if no subcommand - valid
                # If there's a subcommand, but no argument, fail
                if not cut.strip(" "):
                    await message.channel.send(
                        trans.get("MSG_STEAM_INVALID_PARAMS",
                                  lang).format(prefix))
                    return

                subcommand, argument = cut, ""

            # !steam games
            if subcommand == "games":
                if not argument:
                    await message.channel.send(
                        trans.get("MSG_STEAM_NEED_URL", lang))
                    return

                # Game search
                try:
                    username, games = await self.steam.get_owned_games(argument
                                                                       )
                except ValueError:
                    await message.channel.send(
                        trans.get("MSG_STEAM_INVALID_URL", lang))
                    return
                except (steamapi.errors.APIFailure,
                        steamapi.errors.APIException,
                        steamapi.errors.AccessException):
                    await message.channel.send(
                        trans.get("MSG_STEAM_PRIVATE", lang))
                    raise

                if not username:
                    await message.channel.send(
                        trans.get("ERROR_NO_USER2", lang))
                    self.stats.add(WRONG_ARG)
                    return

                if not games:
                    await message.channel.send(
                        trans.get("MSG_STEAM_PRIVATE_GAMES", lang))
                    self.stats.add(WRONG_ARG)
                    return

                games = ["`{}`".format(game) for game in games]

                try:
                    await message.channel.send(
                        trans.get("MSG_STEAM_GAMES",
                                  lang).format(username,
                                               filter_text(", ".join(games))))
                except HTTPException:
                    await message.channel.send(
                        trans.get("MSG_STEAM_GAMES_TOO_MANY", lang))

            elif subcommand == "user":
                if not argument:
                    await message.channel.send(
                        trans.get("MSG_STEAM_NEED_URL", lang))
                    return

                # Basic search
                try:
                    steam_user = await self.steam.get_user(argument)
                except ValueError:
                    await message.channel.send(
                        trans.get("MSG_STEAM_INVALID_URL", lang))
                    return
                except (steamapi.errors.APIFailure,
                        steamapi.errors.APIException):
                    await message.channel.send(
                        trans.get("MSG_STEAM_PRIVATE", lang))
                    raise

                if not steam_user:
                    await message.channel.send(
                        trans.get("ERROR_NO_USER2", lang))
                    self.stats.add(WRONG_ARG)
                    return

                state = trans.get("MSG_STEAM_ONLINE",
                                  lang) if steam_user.state else trans.get(
                                      "MSG_STEAM_OFFLINE", lang)

                try:
                    info = trans.get("MSG_STEAM_USER_INFO",
                                     lang).format(steam_user.name, state,
                                                  steam_user.level,
                                                  len(steam_user.games),
                                                  len(steam_user.friends),
                                                  argument)
                except AttributeError:
                    await message.channel.send(
                        trans.get("MSG_STEAM_PRIVATE", lang))
                    return

                if len(info) > 2000:
                    await message.channel.send(
                        trans.get("MSG_STEAM_FRIENDS_TOO_MANY", lang))

                else:
                    await message.channel.send(filter_text(info))

            elif subcommand == "help":
                await message.channel.send(
                    trans.get("MSG_STEAM_HELP", lang).replace("!", prefix))
Example #13
0
File: help.py Project: RossKM/Nano
    async def on_message(self, message, *_, **kwargs):
        trans = self.trans

        prefix = kwargs.get("prefix")
        lang = kwargs.get("lang")

        # Check if this is a valid command
        if not is_valid_command(message.content, commands, prefix):
            return
        else:
            self.stats.add(MESSAGE)

        def startswith(*matches):
            for match in matches:
                if message.content.startswith(match):
                    return True

            return False

        # Bare !help
        if message.content.strip(" ") == (prefix + "help"):
            await message.channel.send(
                trans.get("MSG_HELP", lang).format(prefix=prefix))

            self.stats.add(HELP)

        # !cmds or !commands
        elif startswith(prefix + "cmds", prefix + "commands"):
            if startswith(prefix + "cmds"):
                arg = message.content[len(prefix + "cmds "):].lower()
            else:
                arg = message.content[len(prefix + "commands "):].lower()

            if not arg or not cmd_links.get(arg):
                await message.channel.send(trans.get("MSG_HELP_CMDWEB", lang))
            else:
                ending = cmd_links.get(arg)
                full_link = BASE_CMDS_LINK + ending

                await message.channel.send(
                    trans.get("MSG_HELP_CMD_SPEC", lang).format(full_link))

            self.stats.add(HELP)

        # !help simple
        elif startswith(prefix + "help simple"):
            await message.channel.send(
                trans.get("MSG_HELP_SIMPLE", lang).format(prefix=prefix))

            self.stats.add(HELP)

        # !help [command]
        elif startswith(prefix + "help"):
            search = str(message.content)[len(prefix + "help "):]

            # Allows for !help ping AND !help !ping
            if search.startswith(prefix) or search.startswith("nano."):
                name, embed = self.get_command_info(search, prefix, lang)

                if name:
                    await message.channel.send(name, embed=embed)
                else:
                    await message.channel.send(
                        trans.get("MSG_HELP_CMDNOTFOUND",
                                  lang).format(prefix=prefix))

            else:
                name, embed = self.get_command_info(prefix + search, prefix,
                                                    lang)

                if name:
                    await message.channel.send(name, embed=embed)
                else:
                    await message.channel.send(
                        trans.get("MSG_HELP_CMDNOTFOUND",
                                  lang).format(prefix=prefix))

                self.stats.add(HELP)

        # !notifydev
        # Not translated
        elif startswith(prefix + "suggest"):
            report = message.content[len(prefix + "suggest "):].strip(" ")

            # Disallow empty reports
            if not report:
                await message.channel.send(trans.get("MSG_REPORT_EMPTY", lang))
                return

            # :P
            if report in ("hi", "hello"):
                await message.channel.send(trans.get("MSG_REPORT_EE_THX",
                                                     lang))
                return

            # Cooldown implementation
            if not self.last_times.get(message.author.id):
                self.last_times[message.author.id] = time.time()
            else:
                # 300 seconds --> 5 minute cooldown
                if (time.time() - self.last_times[message.author.id]) < 300:
                    await message.channel.send(
                        trans.get("MSG_REPORT_RATELIMIT", lang))
                    return

                else:
                    self.last_times[message.author.id] = time.time()

            dev_server = self.client.get_guild(self.nano.dev_server)
            owner = dev_server.get_member(self.nano.owner_id)
            # Timestamp
            ts = datetime.now().strftime("%d.%m.%Y %H:%M:%S")

            # Reused stuff
            name = message.author.name
            u_id = message.author.id
            guild_name = message.guild.name
            guild_id = message.guild.id
            guild_owner = message.guild.owner
            guild_members = message.guild.member_count
            owner_info = "Yes" if message.author == guild_owner else "{}:{}".format(
                guild_owner.id, guild_owner.id)

            # 'Compiled' report
            # NOT TRANSLATED!!
            comp = "Suggestion from {} ({}):\n```{}```\n**__Timestamp__**: `{}`" \
                   "\n**__Server__**: `{}` ID:{} ({} members)\n**__Server Owner__**: {}" \
                   "\n**Language used:** `{}`".format(name, u_id, report, ts, guild_name, guild_id, guild_members, owner_info, lang)

            # Saves the submission
            to_file = "Suggestion from {0}:{1}\nMessage: {2}\n" \
                      "Server: {3}:{4} with {5} members\nServer owner: {6}\n" \
                      "Language used: {7}".format(name, u_id, report, guild_name, guild_id, guild_members, owner_info, lang)

            save_submission(to_file)
            await owner.send(comp)

            await message.channel.send(trans.get("MSG_REPORT_THANKS", lang))

        # !bug
        elif startswith(prefix + "bug"):
            await message.channel.send(trans.get("MSG_BUG", lang))

        # !tos
        elif startswith(prefix + "tos"):
            await message.channel.send(trans.get("MSG_TOS", lang))
Example #14
0
    async def on_message(self, message, **kwargs):
        trans = self.trans

        prefix = kwargs.get("prefix")
        lang = kwargs.get("lang")

        simple_commands = {"( ͡° ͜ʖ ͡°)": trans.get("MSG_WHOKNOWS", lang)}

        # Loop over simple commands
        for k, v in simple_commands.items():
            if message.content.startswith(k):
                await message.channel.send(v)
                self.stats.add(MESSAGE)
                return

        # Check if this is a valid command
        if not is_valid_command(message.content, commands, prefix):
            return
        else:
            self.stats.add(MESSAGE)

        def startswith(*matches):
            for match in matches:
                if message.content.startswith(match):
                    return True

            return False

        # Other commands
        if startswith(prefix + "kappa"):
            await message.channel.send(file=File(KAPPA_LOCATION, "kappa.png"))

            self.stats.add(IMAGE_SENT)

        # !randomgif (optional_tag)
        elif startswith(prefix + "randomgif"):
            tags = message.content[len(prefix + "randomgif "):]

            gif = await self.gif.get_random_gif(tags or None)
            nonexistent = False

            if gif == -1:
                await message.channel.send(trans.get("MSG_GIPHY_TOOFAST",
                                                     lang))
                return

            # Gif with such tag does not exist, fall back to random one
            if gif is None:
                gif = await self.gif.get_random_gif()
                nonexistent = True

            embed = Embed(colour=Colour(GIPHY_GREEN))
            embed.set_image(url=gif)

            if not nonexistent:
                embed.set_footer(text=trans.get("MSG_GIPHY_POWEREDBY", lang))
            else:
                that_text = trans.get(
                    "MSG_GIPHY_POWEREDBY", lang) + " | " + trans.get(
                        "MSG_GIPHY_NOSUCHTAG", lang).format(add_dots(tags, 20))
                embed.set_footer(text=that_text)

            await message.channel.send(embed=embed)

            self.stats.add(IMAGE_SENT)

        # !meme [meme name]|[top text]|[bottom text]
        elif startswith(prefix + "meme"):
            query = message.content[len(prefix + "meme "):]

            if not query:
                await message.channel.send(
                    trans.get("ERROR_INVALID_CMD_ARGUMENTS", lang))
                return

            middle = [a.strip(" ") for a in query.split("|")]

            # If only two arguments are passed, assume no bottom text
            if len(middle) == 2:
                name = middle[0]
                top = middle[1]
                bottom = ""

            # 0, 1 or more than 3 arguments - error
            elif len(middle) < 2 or len(middle) > 3:
                await message.channel.send(
                    trans.get("MSG_MEME_USAGE", lang).replace("_", prefix))
                return

            # Normal
            else:
                name = middle[0]
                top = middle[1]
                bottom = middle[2]

            meme = await self.generator.caption_meme(name, top, bottom)

            if not meme:
                await message.channel.send(
                    trans.get("MSG_MEME_NONEXISTENT", lang))
            else:
                embed = Embed(colour=Colour(0x607D8B))
                embed.set_image(url=meme)
                embed.set_footer(text=trans.get("MSG_MEME_FOOTER", lang))

                await message.channel.send(embed=embed)

        elif startswith(prefix + "rip"):
            if len(message.mentions) == 1:
                ripperoni = " " + message.mentions[0].name

            elif len(message.mentions) == 0:
                ripperoni = " " + message.content[len(prefix + "rip "):]

            else:
                ripperoni = ""

            ripperoni = self.everyone_filter(ripperoni,
                                             message.author,
                                             force_remove=True)

            prays = self.stats.get_amount(PRAYER)
            await message.channel.send(
                trans.get("MSG_RIP", lang).format(ripperoni, prays))

            self.stats.add(PRAYER)

        elif startswith(prefix + "achievement"):
            text = message.content[len(prefix + "achievement "):].strip(" ")

            if not text:
                await message.channel.send(
                    trans.get("MSG_ACHIEVMENT_NOTEXT", lang))
                return

            img = self.achievement.create_image(text)
            img_filename = "Achievement_{}.png".format(gen_id(4))

            await message.channel.send(file=File(img, img_filename))
            # Just in case GC fails
            del img
Example #15
0
File: jokes.py Project: RossKM/Nano
    async def on_message(self, message, **kwargs):
        trans = self.trans

        prefix = kwargs.get("prefix")
        lang = kwargs.get("lang")

        # Check if this is a valid command
        if not is_valid_command(message.content, commands, prefix):
            return
        else:
            self.stats.add(MESSAGE)

        def startswith(*matches):
            for match in matches:
                if message.content.startswith(match):
                    return True

            return False

        # !cat gif/jpg/png
        if startswith(prefix + "cat"):
            fmt = str(message.content[len(prefix + "cat"):]).strip(" ")

            # GIF is the default type!
            if fmt == "jpg":
                type_ = "jpg"
            elif fmt == "png":
                type_ = "png"
            else:
                type_ = "gif"

            pic = await self.cats.random_cat(type_)

            if pic:
                # Teal (blue-ish)
                embed = Embed(colour=Colour(0x00796b))
                embed.set_image(url=pic)
                embed.set_footer(text=trans.get("MSG_CAT_FOOTER", lang))

                await message.channel.send(embed=embed)
            else:
                await message.channel.send(trans.get("MSG_CAT_FAILED", lang))

            self.stats.add(IMAGE_SENT)

        # !xkcd random/number/latest
        elif startswith(prefix + "xkcd"):
            fmt = str(message.content[len(prefix + "xkcd"):]).strip(" ")

            # Decides mode
            fetch = "random"
            if fmt:
                if is_number(fmt):
                    # Check if number is valid
                    if int(fmt) > self.xkcd.last_num:
                        await message.channel.send(
                            trans.get("MSG_XKCD_NO_SUCH", lang))
                        return
                    else:
                        fetch = "number"
                elif fmt == trans.get("INFO_RANDOM", lang) or fmt == "random":
                    fetch = "random"
                # Any other argument means latest
                else:
                    fetch = "latest"
            # Default: random
            else:
                fetch == "random"

            if fetch == "random":
                xkcd = await self.xkcd.get_random_xkcd()
            elif fetch == "number":
                xkcd = await self.xkcd.get_xkcd_by_number(fmt)
            # Can only mean latest
            else:
                xkcd = await self.xkcd.get_latest_xkcd()

            # In case something went wrong
            if not xkcd:
                await message.channel.send(trans.get("MSG_XKCD_FAILED", lang))
                log_to_file("XKCD: string {}, fetch: {}, got None".format(
                    fmt, fetch))

            xkcd_link = self.xkcd.make_link(xkcd["num"])

            embed = Embed(title=trans.get("MSG_XKCD",
                                          lang).format(xkcd["num"]),
                          description=filter_text(xkcd["safe_title"]))
            embed.set_image(url=xkcd["img"])
            embed.set_footer(
                text=trans.get("MSG_XKCD_SOURCE", lang).format(xkcd_link))

            await message.channel.send(embed=embed)

        # !joke (yo mama/chuck norris)
        elif startswith(prefix + "joke"):
            content = filter_text(self.joke.random_joke())

            embed = Embed(description=content)
            await message.channel.send(embed=embed)
Example #16
0
    async def on_message(self, message, **kwargs):
        assert isinstance(message, Message)

        prefix = kwargs.get("prefix")

        trans = self.trans
        lang = kwargs.get("lang")

        if not is_valid_command(message.content, commands, prefix=prefix):
            return
        else:
            self.stats.add(MESSAGE)

        def startswith(*msg):
            for a in msg:
                if message.content.startswith(a):
                    return True

            return False

        if startswith(prefix + "wiki", prefix + "define"):
            if startswith(prefix + "wiki"):
                search = str(message.content)[len(prefix +
                                                  "wiki "):].strip(" ")
            elif startswith(prefix + "define"):
                search = str(message.content)[len(prefix +
                                                  "define "):].strip(" ")
            else:
                # Shouldn't happen, RuntimeError means startswith() is not working properly
                raise RuntimeError

            # filter mentions
            search = filter_text(search)

            if not search:
                await message.channel.send(trans.get("MSG_WIKI_NO_QUERY",
                                                     lang))
                return

            summary = await self.wiki.get_definition(search)

            if not summary:
                await message.channel.send(trans.get("MSG_WIKI_NO_DEF", lang))
                return

            await message.channel.send(
                trans.get("MSG_WIKI_DEFINITION", lang).format(
                    search,
                    add_dots(filter_text(summary), max_len=MAX_WIKI_LENGTH)))

        elif startswith(prefix + "urban"):
            search = str(message.content)[len(prefix + "urban "):].strip(" ")

            if not search:
                await message.channel.send(
                    trans.get("MSG_URBAN_NO_QUERY", lang))
                return

            # filter mentions
            search = filter_text(search)

            description = await self.urban.urban_dictionary(search)

            if not description:
                await message.channel.send(trans.get("MSG_URBAN_NO_DEF", lang))
                return

            await message.channel.send(
                trans.get("MSG_URBAN_DEFINITION", lang).format(
                    search,
                    add_dots(filter_text(description),
                             max_len=MAX_URBAN_LENGTH)))