示例#1
0
 def write_volume(self):
     """Writes the current volume to the data.json"""
     # Update the volume
     data = datatools.get_data()
     data["discord"]["servers"][self.server_id][
         _data.modulename]["volume"] = self.volume
     datatools.write_data(data)
示例#2
0
async def on_message(message):
    """The on_message event handler for this module

    Args:
        message (discord.Message): Input message
    """

    # Simplify message info
    server = message.server
    author = message.author
    channel = message.channel
    content = message.content

    data = datatools.get_data()

    if not data["discord"]["servers"][server.id][
            _data.modulename]["activated"]:
        return

    # Only reply to server messages and don't reply to myself
    if server is not None and author != channel.server.me:
        # Do a flip check
        flipchecked = api_flipcheck.flipcheck(content)
        if flipchecked:
            await client.send_typing(channel)
            await client.send_message(channel, flipchecked)
示例#3
0
async def warn_user(channel, user):
    """
    Gives a user a warning, and bans them if they are over the maximum warnings

    Args:
        channel: The channel to send the warning message in
        user: The user to give the warning to
    """

    data = datatools.get_data()
    server_id = channel.server.id

    if "warnings_max" not in data["discord"]["servers"][server_id][_data.modulename]:
        data["discord"]["servers"][server_id][_data.modulename]["warnings_max"] = 3
    if "warnings" not in data["discord"]["servers"][server_id][_data.modulename]:
        data["discord"]["servers"][server_id][_data.modulename]["warnings"] = {}

    if user.id in data["discord"]["servers"][server_id][_data.modulename]["warnings"]:
        data["discord"]["servers"][server_id][_data.modulename]["warnings"][user.id] += 1
    else:
        data["discord"]["servers"][server_id][_data.modulename]["warnings"][user.id] = 1

    datatools.write_data(data)

    warnings = data["discord"]["servers"][server_id][_data.modulename]["warnings"][user.id]
    max_warnings = data["discord"]["servers"][server_id][_data.modulename]["warnings_max"]

    await client.send_typing(channel)
    embed = ui_embed.user_warning(channel, user, warnings, max_warnings)
    await embed.send()

    if warnings >= max_warnings:
        await ban_user(channel, user)
示例#4
0
def build_spotify_api():
    """Build the Spotify API for future use"""
    data = datatools.get_data()
    if "spotify_client_id" not in data["discord"]["keys"]:
        logger.warning("No API key found with name 'spotify_client_id'")
        logger.info(
            "Please add your Spotify client id with name 'spotify_client_id' "
            "in data.json to use Spotify features of the music module")
        return False
    if "spotify_client_secret" not in data["discord"]["keys"]:
        logger.warning("No API key found with name 'spotify_client_secret'")
        logger.info(
            "Please add your Spotify client secret with name 'spotify_client_secret' "
            "in data.json to use Spotify features of the music module")
        return False

    try:
        global spclient
        client_credentials_manager = SpotifyClientCredentials(
            data["discord"]["keys"]["spotify_client_id"],
            data["discord"]["keys"]["spotify_client_secret"])
        spclient = spotipy.Spotify(
            client_credentials_manager=client_credentials_manager)
        logger.debug("Spotify build successful")
        return True
    except Exception as e:
        logger.exception(e)
        return False
示例#5
0
def build_yt_api():
    """Build the YouTube API for future use"""
    data = datatools.get_data()
    if "google_api_key" not in data["discord"]["keys"]:
        logger.warning("No API key found with name 'google_api_key'")
        logger.info(
            "Please add your Google API key with name 'google_api_key' "
            "in data.json to use YouTube features of the music module")
        return False

    logger.debug("Building YouTube discovery API")
    ytdevkey = data["discord"]["keys"]["google_api_key"]

    try:
        global ytdiscoveryapi
        ytdiscoveryapi = googleapiclient.discovery.build("youtube",
                                                         "v3",
                                                         developerKey=ytdevkey)
        logger.debug("YouTube API build successful")
        return True
    except Exception as e:
        logger.exception(e)
        logger.warning(
            "HTTP error connecting to YouTube API, YouTube won't be available")
        return False
示例#6
0
async def on_message(message):
    """The on_message event handler for this module

    Args:
        message (discord.Message): Input message
    """

    # Simplify message info
    server = message.server
    author = message.author
    channel = message.channel
    content = message.content

    data = datatools.get_data()

    if not data["discord"]["servers"][server.id][_data.modulename]["activated"]:
        return

    # Only reply to server messages and don't reply to myself
    if server is not None and author != channel.server.me:
        # Retrieve replies from server data
        normal_replies = data["discord"]["servers"][server.id][_data.modulename]["normal"]
        tts_replies = data["discord"]["servers"][server.id][_data.modulename]["tts"]

        # Check normal replies
        for r in normal_replies.keys():
            if r in content.lower().replace(' ', ''):
                await client.send_typing(channel)
                await client.send_message(channel, normal_replies[r])

        # Check tts replies
        for r in tts_replies.keys():
            if r in content.lower().replace(' ', ''):
                await client.send_typing(channel)
                await client.send_message(channel, tts_replies[r])
示例#7
0
async def activate_module(channel, module_name, activate):
    """
    Changes a modules activated/deactivated state for a server

    Args:
        channel: The channel to send the message to
        module_name: The name of the module to change state for
        activate: The activated/deactivated state of the module
    """

    data = datatools.get_data()
    server_id = channel.server.id

    _dir = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
    _dir_modules = "{}/../".format(_dir)
    if not os.path.isfile("{}/{}/_data.py".format(_dir_modules, module_name)):
        await client.send_typing(channel)
        embed = ui_embed.error(channel, "Error", "No module found named '{}'".format(module_name))
        await embed.send()
        return

    try:
        import_name = ".discord_modis.modules.{}.{}".format(module_name, "_data")
        module_data = importlib.import_module(import_name, "modis")

        # Don't try and deactivate this module (not that it would do anything)
        if module_data.modulename == _data.modulename:
            await client.send_typing(channel)
            embed = ui_embed.error(channel, "Error", "I'm sorry, Dave. I'm afraid I can't do that.")
            await embed.send()
            return

        # This /should/ never happen if everything goes well
        if module_data.modulename not in data["discord"]["servers"][server_id]:
            await client.send_typing(channel)
            embed = ui_embed.error(channel, "Error",
                                   "No data found for module '{}'".format(module_data.modulename))
            await embed.send()
            return

        # Modify the module
        if "activated" in data["discord"]["servers"][server_id][module_data.modulename]:
            data["discord"]["servers"][server_id][module_data.modulename]["activated"] = activate
            # Write the data
            datatools.write_data(data)

            await client.send_typing(channel)
            embed = ui_embed.modify_module(channel, module_data.modulename, activate)
            await embed.send()
            return
        else:
            await client.send_typing(channel)
            embed = ui_embed.error(channel, "Error", "Can't deactivate module '{}'".format(module_data.modulename))
            await embed.send()
            return
    except Exception as e:
        logger.error("Could not modify module {}".format(module_name))
        logger.exception(e)
示例#8
0
async def on_message(message):
    """The on_message event handler for this module

    Args:
        message (discord.Message): Input message
    """

    # Simplify message info
    server = message.server
    author = message.author
    channel = message.channel
    content = message.content

    data = datatools.get_data()

    if not data["discord"]["servers"][server.id][
            _data.modulename]["activated"]:
        return

    # Only reply to server messages and don't reply to myself
    if server is not None and author != channel.server.me:
        # Only reply to mentions
        if channel.server.me in message.mentions:

            logger.info("Bot was mentioned, summoning Mitsuku")
            await client.send_typing(channel)

            # Get new botcust2 from Mitsuku if does not exist for channel in serverdata
            if channel.id not in data["discord"]["servers"][server.id][
                    _data.modulename]["channels"]:
                new_serverdata = data
                new_serverdata["discord"]["servers"][server.id][_data.modulename]["channels"][channel.id] = \
                    api_mitsuku.get_botcust2()
                datatools.write_data(new_serverdata)

            # Get botcust2 from serverdata
            botcust2 = data["discord"]["servers"][server.id][
                _data.modulename]["channels"][channel.id]

            # Remove mention from message content so Mitsuku doesn't see it
            content = content.replace(
                "<@{}>".format(str(channel.server.me.id)), ' ')
            content = content.replace(
                "<@!{}>".format(str(channel.server.me.id)), ' ')

            # Send Mitsuku's reply
            if botcust2:
                response = api_mitsuku.query(botcust2, content)
                if response:
                    await client.send_message(channel, response)
                else:
                    await client.send_message(
                        channel,
                        "```Couldn't get readable response from Mitsuku.```")
            else:
                await client.send_message(
                    channel, "```Couldn't initialise with Mitsuku.```")
示例#9
0
async def on_message(message):
    """The on_message event handler for this module

    Args:
        message (discord.Message): Input message
    """

    # Simplify message info
    server = message.server
    author = message.author
    channel = message.channel
    content = message.content

    data = datatools.get_data()

    if not data["discord"]["servers"][server.id][
            _data.modulename]["activated"]:
        return

    # Only reply to server messages and don't reply to myself
    if server is not None and author != channel.server.me:
        # Commands section
        prefix = data["discord"]["servers"][server.id]["prefix"]
        if content.startswith(prefix):
            # Parse message
            package = content.split(" ")
            command = package[0][len(prefix):]
            args = package[1:]
            arg = ' '.join(args)

            # Commands
            if command == 'hex':
                await client.send_typing(channel)

                # Parse message
                hex_strs = api_hexconvert.convert_hex_value(arg)
                # Create embed UI
                if len(hex_strs) > 0:
                    for hex_str in hex_strs:
                        image_url = convert_hex_to_url(hex_str)
                        embed = ui_embed.success(channel, image_url, hex_str)
                        await embed.send()
                else:
                    embed = ui_embed.fail_api(channel)
                    await embed.send()
        else:
            # Parse message
            hex_strs = api_hexconvert.convert_hex_value(content)
            # Create embed UI
            if len(hex_strs) > 0:
                for hex_str in hex_strs:
                    await client.send_typing(channel)
                    image_url = convert_hex_to_url(hex_str)
                    embed = ui_embed.success(channel, image_url, hex_str)
                    await embed.send()
示例#10
0
async def on_reaction_add(reaction, user):
    """The on_message event handler for this module

    Args:
        reaction (discord.Reaction): Input reaction
        user (discord.User): The user that added the reaction
    """

    # Simplify reaction info
    server = reaction.message.server
    emoji = reaction.emoji

    data = datatools.get_data()

    if not data["discord"]["servers"][server.id][
            _data.modulename]["activated"]:
        return

    # Commands section
    if user != reaction.message.channel.server.me:
        if server.id not in _data.cache or _data.cache[
                server.id].state == 'destroyed':
            return

        try:
            valid_reaction = reaction.message.id == _data.cache[
                server.id].embed.sent_embed.id
        except AttributeError:
            pass
        else:
            if valid_reaction:
                # Remove reaction
                try:
                    await client.remove_reaction(reaction.message, emoji, user)
                except discord.errors.NotFound:
                    pass
                except discord.errors.Forbidden:
                    pass

                # Commands
                if emoji == "⏯":
                    await _data.cache[server.id].toggle()
                if emoji == "⏹":
                    await _data.cache[server.id].stop()
                if emoji == "⏭":
                    await _data.cache[server.id].skip("1")
                if emoji == "⏮":
                    await _data.cache[server.id].rewind("1")
                if emoji == "🔀":
                    await _data.cache[server.id].shuffle()
                if emoji == "🔉":
                    await _data.cache[server.id].setvolume('-')
                if emoji == "🔊":
                    await _data.cache[server.id].setvolume('+')
示例#11
0
def check_all_servers():
    """Checks all servers, removing any that Modis isn't part of any more"""
    data = datatools.get_data()
    for server_id in data["discord"]["servers"]:
        is_in_client = False
        for client_server in client.servers:
            if server_id == client_server.id:
                is_in_client = True
                break

        if not is_in_client:
            remove_server_data(server_id)
示例#12
0
async def on_message(message):
    """The on_message event handler for this module

    Args:
        message (discord.Message): Input message
    """

    # Simplify message info
    server = message.server
    author = message.author
    channel = message.channel
    content = message.content

    data = datatools.get_data()

    # Only reply to server messages and don't reply to myself
    if server is not None and author != channel.server.me:
        # Commands section
        prefix = data["discord"]["servers"][server.id]["prefix"]
        if content.startswith(prefix):
            # Parse message
            package = content.split(" ")
            command = package[0][len(prefix):]
            args = package[1:]
            arg = ' '.join(args)

            # Commands
            if command == 'help':
                if args:
                    # Parse message
                    datapacks = api_help.get_help_datapacks(arg, prefix)
                    # Create embed UI
                    if datapacks:
                        await client.send_typing(channel)
                        embed = ui_embed.success(channel, arg, datapacks)
                        try:
                            await embed.send()
                        except discord.errors.HTTPException:
                            embed = ui_embed.http_exception(channel, arg)
                            await embed.send()
                else:
                    # Parse message
                    datapacks = api_help.get_help_commands(prefix)
                    # Create embed UI
                    if datapacks:
                        await client.send_typing(channel)
                        embed = ui_embed.success(channel, arg, datapacks)
                        try:
                            await embed.send()
                        except discord.errors.HTTPException:
                            embed = ui_embed.http_exception(channel, arg)
                            await embed.send()
示例#13
0
    async def set_topic_channel(self, channel):
        """Set the topic channel for this server"""
        data = datatools.get_data()
        data["discord"]["servers"][self.server_id][
            _data.modulename]["topic_id"] = channel.id
        datatools.write_data(data)

        self.topicchannel = channel
        await self.set_topic(self.topic)

        await client.send_typing(channel)
        embed = ui_embed.topic_update(channel, self.topicchannel)
        await embed.send()
示例#14
0
def remove_server_data(server_id):
    """
    Remove a server from the server data

    Args:
        server_id (int): The server to remove from the server data
    """

    logger.debug("Removing server from serverdata")
    # Remove the server from data
    data = datatools.get_data()
    if server_id in data["discord"]["servers"]:
        data["discord"]["servers"].pop(server_id)
        datatools.write_data(data)
示例#15
0
async def on_message(message):
    """The on_message event handler for this module

    Args:
        message (discord.Message): Input message
    """

    # Simplify message info
    server = message.server
    author = message.author
    channel = message.channel
    content = message.content

    data = datatools.get_data()

    if not data["discord"]["servers"][server.id][
            _data.modulename]["activated"]:
        return

    # Only reply to server messages and don't reply to myself
    if server is not None and author != channel.server.me:
        # Commands section
        prefix = data["discord"]["servers"][server.id]["prefix"]
        if content.startswith(prefix):
            # Parse message
            package = content.split(" ")
            command = package[0][len(prefix):]
            args = package[1:]
            arg = ' '.join(args)

            # Commands
            if command == 'gamedeals':
                await client.send_typing(channel)

                # Get posts from Reddit API
                posts = api_reddit.get_top10()

                if posts:
                    for post in posts:
                        # Create embed UI
                        embed = ui_embed.success(channel, post)
                        await embed.send()
                else:
                    embed = ui_embed.no_results(channel)
                    await embed.send()
示例#16
0
def build_sc_api():
    """Build the SoundCloud API for future use"""
    data = datatools.get_data()
    if "soundcloud_client_id" not in data["discord"]["keys"]:
        logger.warning("No API key found with name 'soundcloud_client_id'")
        logger.info(
            "Please add your SoundCloud client id with name 'soundcloud_client_id' "
            "in data.json to use Soundcloud features of the music module")
        return False

    try:
        global scclient
        scclient = soundcloud.Client(
            client_id=data["discord"]["keys"]["soundcloud_client_id"])
        logger.debug("SoundCloud build successful")
        return True
    except Exception as e:
        logger.exception(e)
        return False
示例#17
0
    async def clear_topic_channel(self, channel):
        """Set the topic channel for this server"""
        try:
            if self.topicchannel:
                await client.edit_channel(self.topicchannel, topic="")
        except Exception as e:
            logger.exception(e)

        self.topicchannel = None
        logger.debug("Clearing topic channel")

        data = datatools.get_data()
        data["discord"]["servers"][self.server_id][
            _data.modulename]["topic_id"] = ""
        datatools.write_data(data)

        await client.send_typing(channel)
        embed = ui_embed.topic_update(channel, self.topicchannel)
        await embed.send()
示例#18
0
def build_api():
    data = datatools.get_data()
    if "reddit_api_user_agent" not in data["discord"]["keys"] or \
            "reddit_api_client_id" not in data["discord"]["keys"] or \
            "reddit_api_client_secret" not in data["discord"]["keys"]:
        logger.warning("For gamedeals to work, please make sure \"reddit_api_user_agent\", " +
                       "\"reddit_api_client_id\", and \"reddit_api_client_secret\" are all added as API keys")

    logger.debug("Building Reddit API")
    try:
        global redditapi
        redditapi = praw.Reddit(
            user_agent=data["discord"]["keys"]["reddit_api_user_agent"],
            client_id=data["discord"]["keys"]["reddit_api_client_id"],
            client_secret=data["discord"]["keys"]["reddit_api_client_secret"])
        logger.debug("Build successfull")
        return True
    except:
        logger.warning("Error connecting to Reddit API, Reddit won't be available")
        return False
def build_api():
    data = datatools.get_data()
    if "google_api_key" not in data["discord"]["keys"]:
        logger.critical("No API key found with name 'google_api_key'")
        logger.info(
            "Please add your google API key with name 'google_api_key' int the control panel"
        )
        return False

    logger.debug("Building YouTube discovery API")
    ytdevkey = data["discord"]["keys"]["google_api_key"]
    try:
        global ytdiscoveryapi
        ytdiscoveryapi = googleapiclient.discovery.build("youtube",
                                                         "v3",
                                                         developerKey=ytdevkey)
        logger.debug("Build successfull")
        return True
    except:
        logger.critical("HTTP error connecting to YouTube API, build failed")
        return False
示例#20
0
def build_api():
    data = datatools.get_data()
    if "reddit_api_user_agent" not in data["discord"]["keys"] or \
            "reddit_api_client_id" not in data["discord"]["keys"] or \
            "reddit_api_client_secret" not in data["discord"]["keys"]:
        logger.error(
            "Please make sure \"reddit_api_user_agent\"," +
            "\"reddit_api_client_id\", and \"reddit_api_client_id\" are all added as API keys"
        )

    logger.debug("Building Reddit API")
    try:
        global redditapi
        redditapi = praw.Reddit(
            user_agent=data["discord"]["keys"]["reddit_api_user_agent"],
            client_id=data["discord"]["keys"]["reddit_api_client_id"],
            client_secret=data["discord"]["keys"]["reddit_api_client_secret"])
        logger.debug("Build successfull")
        return True
    except:
        logger.critical("Error connecting to Reddit API, build failed")
        return False
示例#21
0
def send_message(channel_id, message):
    """
    Send a message to a channel

    Args:
        channel_id (str): The id of the channel to send the message to
        message (str): The message to send to the channel
    """

    channel = client.get_channel(channel_id)

    if channel is None:
        logger.info("{} is not a channel".format(channel_id))
        return

    # Check that it's enabled in the server
    data = datatools.get_data()
    if not data["discord"]["servers"][channel.server.id][modulename]["activated"]:
        logger.info("This module has been disabled in {} ({})".format(channel.server.name, channel.server.id))

    try:
        runcoro(client.send_message(channel, message))
    except Exception as e:
        logger.exception(e)
示例#22
0
async def ban_user(channel, user):
    """
    Bans a user from a server

    Args:
        channel: The channel to send the warning message in
        user: The user to give the warning to
    """

    data = datatools.get_data()
    server_id = channel.server.id

    try:
        await client.ban(user)
    except discord.errors.Forbidden:
        await client.send_typing(channel)
        embed = ui_embed.error(channel, "Ban Error", "I do not have the permissions to ban that person.")
        await embed.send()
        return

    # Set the user's warnings to 0
    if "warnings" in data["discord"]["servers"][server_id][_data.modulename]:
        if user.id in data["discord"]["servers"][server_id][_data.modulename]["warnings"]:
            data["discord"]["servers"][server_id][_data.modulename]["warnings"][user.id] = 0
            datatools.write_data(data)

    await client.send_typing(channel)
    embed = ui_embed.user_ban(channel, user)
    await embed.send()

    try:
        response = "You have been banned from the server '{}' " \
                   "contact the owners to resolve this issue.".format(channel.server.name)
        await client.send_message(user, response)
    except Exception as e:
        logger.exception(e)
示例#23
0
async def on_message(message):
    """The on_message event handler for this module

    Args:
        message (discord.Message): Input message
    """

    # Simplify message info
    server = message.server
    author = message.author
    channel = message.channel
    content = message.content

    data = datatools.get_data()

    if not data["discord"]["servers"][server.id][
            _data.modulename]["activated"]:
        return

    # Only reply to server messages and don't reply to myself
    if server is not None and author != channel.server.me:
        # Commands section
        prefix = data["discord"]["servers"][server.id]["prefix"]
        if content.startswith(prefix):
            # Parse message
            package = content.split(" ")
            command = package[0][len(prefix):]
            args = package[1:]
            arg = ' '.join(args)

            # Lock on to server if not yet locked
            if server.id not in _data.cache or _data.cache[
                    server.id].state == 'destroyed':
                _data.cache[server.id] = _musicplayer.MusicPlayer(server.id)

            # Remove message
            if command in [
                    'play', 'playnext', 'playnow', 'pause', 'resume', 'skip',
                    'shuffle', 'volume', 'stop', 'destroy', 'front', 'movehere'
            ]:
                try:
                    await client.delete_message(message)
                except discord.errors.NotFound:
                    logger.warning(
                        "Could not delete music player command message - NotFound"
                    )
                except discord.errors.Forbidden:
                    logger.warning(
                        "Could not delete music player command message - Forbidden"
                    )

            # Commands
            if command == 'play':
                await _data.cache[server.id].play(author, channel, arg)

            if command == 'playnext':
                await _data.cache[server.id].play(author,
                                                  channel,
                                                  arg,
                                                  now=True)

            if command == 'playnow':
                await _data.cache[server.id].play(author,
                                                  channel,
                                                  arg,
                                                  now=True,
                                                  stop_current=True)

            elif command == 'pause':
                await _data.cache[server.id].pause()

            elif command == 'resume':
                await _data.cache[server.id].resume()

            elif command == 'skip':
                await _data.cache[server.id].skip(query=arg)

            elif command == 'shuffle':
                await _data.cache[server.id].shuffle()

            elif command == 'stop':
                await _data.cache[server.id].stop()

            elif command == 'destroy':
                await _data.cache[server.id].destroy()

            elif command == 'volume':
                await _data.cache[server.id].setvolume(arg)

            elif command == 'front' or command == 'movehere':
                await _data.cache[server.id].movehere(channel)
示例#24
0
async def on_message(message):
    """The on_message event handler for this module

    Args:
        message (discord.Message): Input message
    """

    # Simplify message info
    server = message.server
    author = message.author
    channel = message.channel
    content = message.content

    data = datatools.get_data()

    # Only reply to server messages and don't reply to myself
    if server is not None and author != channel.server.me:
        prefix = data["discord"]["servers"][server.id]["prefix"]
        # Check for mentions reply to mentions
        if channel.server.me in message.mentions:
            await client.send_typing(channel)
            response = "The current server prefix is `{0}`. Type `{0}help` for help.".format(
                prefix)
            await client.send_message(channel, response)

        # Commands section
        if content.startswith(prefix):
            # Parse message
            package = content.split(" ")
            command = package[0][len(prefix):]
            args = package[1:]
            arg = ' '.join(args)

            # Commands
            if command not in ["prefix", "activate", "deactivate"]:
                return

            is_admin = False
            for role in message.author.roles:
                if role.permissions.administrator or \
                        role.permissions.manage_server or \
                        role.permissions.manage_channels:
                    is_admin = True

            if not is_admin:
                await client.send_typing(channel)
                reason = "You must have a role that has the permission" + \
                         "'Administrator', 'Manage Server', or 'Manage Channels'"
                embed = ui_embed.error(channel, "Insufficient Permissions",
                                       reason)
                await embed.send()
                return

            if command == "prefix" and args:
                new_prefix = arg.replace(" ", "").strip()
                data["discord"]["servers"][server.id]["prefix"] = new_prefix
                # Write the data
                datatools.write_data(data)

                await client.send_typing(channel)
                embed = ui_embed.modify_prefix(channel, new_prefix)
                await embed.send()

            if command in ["activate", "deactivate"] and args:
                _dir = os.path.realpath(
                    os.path.join(os.getcwd(), os.path.dirname(__file__)))
                _dir_modules = "{}/../".format(_dir)
                if not os.path.isfile("{}/{}/_data.py".format(
                        _dir_modules, arg)):
                    await client.send_typing(channel)
                    embed = ui_embed.error(
                        channel, "Error",
                        "No module found named '{}'".format(arg))
                    await embed.send()
                    return

                try:
                    import_name = ".discord_modis.modules.{}.{}".format(
                        arg, "_data")
                    module_data = importlib.import_module(import_name, "modis")

                    # Don't try and deactivate this module (not that it would do anything)
                    if module_data.modulename == _data.modulename:
                        await client.send_typing(channel)
                        embed = ui_embed.error(
                            channel, "Error",
                            "I'm sorry, Dave. I'm afraid I can't do that.")
                        await embed.send()
                        return

                    # This /should/ never happen if everything goes well
                    if module_data.modulename not in data["discord"][
                            "servers"][server.id]:
                        await client.send_typing(channel)
                        embed = ui_embed.error(
                            channel, "Error",
                            "No data found for module '{}'".format(
                                module_data.modulename))
                        await embed.send()
                        return

                    # Modify the module
                    if "activated" in data["discord"]["servers"][server.id][
                            module_data.modulename]:
                        is_activate = command == "activate"
                        data["discord"]["servers"][server.id][
                            module_data.modulename]["activated"] = is_activate
                        # Write the data
                        datatools.write_data(data)

                        await client.send_typing(channel)
                        embed = ui_embed.modify_module(channel,
                                                       module_data.modulename,
                                                       is_activate)
                        await embed.send()
                        return
                    else:
                        await client.send_typing(channel)
                        embed = ui_embed.error(
                            channel, "Error",
                            "Can't deactivate module '{}'".format(
                                module_data.modulename))
                        await embed.send()
                        return
                except Exception as e:
                    logger.error("Could not modify module {}".format(arg))
                    logger.exception(e)
示例#25
0
async def on_message(message):
    """The on_message event handler for this module

    Args:
        message (discord.Message): Input message
    """

    # Simplify message info
    server = message.server
    author = message.author
    channel = message.channel
    content = message.content

    data = datatools.get_data()

    if not data["discord"]["servers"][server.id][
            _data.modulename]["activated"]:
        return

    # Only reply to server messages and don't reply to myself
    if server is not None and author != channel.server.me:
        # Commands section
        prefix = data["discord"]["servers"][server.id]["prefix"]
        if content.startswith(prefix):
            # Parse message
            package = content.split(" ")
            command = package[0][len(prefix):]
            args = package[1:]

            alias_steam = ["steam", "pc"]
            alias_ps = ["ps", "psn", "playstation", "ps4", "playstation 4"]
            alias_xbox = ["xbox", "xb", "xb1", "xbone", "xbox one", "xbox one"]

            platform = "steam"
            if len(args) > 0:
                player_name = args[0]
            else:
                return

            if len(args) > 1:
                platform = ' '.join(args[1:]).lower()

            if platform in alias_steam:
                platform = "steam"
            elif platform in alias_ps:
                platform = "ps"
            elif platform in alias_xbox:
                platform = "xbox"

            # Commands
            if command == 'rlstats':
                await client.send_typing(channel)

                # Get Rocket League stats from stats API
                success, rldata = api_rocketleaguestats.check_rank(
                    player_name, platform)
                # Create embed UI
                if success:
                    embed = ui_embed.success(channel, rldata[0], rldata[1],
                                             rldata[2], rldata[3])
                else:
                    embed = ui_embed.fail_api(channel)

                await embed.send()
示例#26
0
async def update_server_data(server):
    """
    Updates the server info for the given server

    Args:
        server: The Discord server to update info for
    """

    data = datatools.get_data()
    # Add the server to server data if it doesn't yet exist
    send_welcome_message = False
    if server.id not in data["discord"]["servers"]:
        logger.debug("Adding new server to serverdata")
        data["discord"]["servers"][server.id] = {"prefix": "!"}
        send_welcome_message = True

    # Make sure all modules are in the server
    _dir = os.path.realpath(
        os.path.join(os.getcwd(), os.path.dirname(__file__)))
    _dir_modules = "{}/../".format(_dir)
    for module_name in os.listdir(_dir_modules):
        if not os.path.isfile("{}/{}/_data.py".format(_dir_modules,
                                                      module_name)):
            logger.warning(
                "No _data.py file found for module {}".format(module_name))
            continue

        try:
            import_name = ".discord_modis.modules.{}.{}".format(
                module_name, "_data")
            _data = importlib.import_module(import_name, "modis")

            if _data.modulename not in data["discord"]["servers"][server.id]:
                data["discord"]["servers"][server.id][
                    _data.modulename] = _data.sd_structure
                datatools.write_data(data)
        except Exception as e:
            logger.error("Could not initialise module {}".format(module_name))
            logger.exception(e)

    datatools.write_data(data)

    # Send a welcome message now
    if send_welcome_message:
        default_channel = server.default_channel
        if not default_channel:
            for channel in server.channels:
                if channel.name == "general":
                    default_channel = channel
                    break
        if not default_channel:
            for channel in server.channels:
                if "general" in channel.name:
                    default_channel = channel
                    break
        if not default_channel:
            for channel in server.channels:
                if channel.type == discord.ChannelType.text:
                    default_channel = channel
                    break

        # Display a welcome message
        if default_channel:
            hello_message = "Hello! I'm Modis.\n\n" + \
                            "The prefix is currently `!`, and can be changed at any time using `!prefix`\n\n" + \
                            "You can use `!help` to get help commands for all modules, " + \
                            "or {} me to get the server prefix and help commands.".format(server.me.mention)
            await client.send_message(default_channel, hello_message)
示例#27
0
import os
import sys
import time

from modis import datatools

working_dir = os.getcwd()
file_dir = os.path.dirname(os.path.realpath(__file__))
logs_dir = "{}/logs/".format(working_dir)
if not os.path.isdir(logs_dir):
    os.mkdir(logs_dir)

logger = logging.getLogger(__name__)
logger.setLevel("DEBUG")
if datatools.has_data():
    data = datatools.get_data()
    if "log_level" in data:
        logger.setLevel(data["log_level"])

formatter = logging.Formatter("{asctime} {levelname:8} {name} - {message}", style="{")
printhandler = logging.StreamHandler(sys.stdout)
printhandler.setFormatter(formatter)
filehandler = logging.FileHandler("{}/{}.log".format(logs_dir, time.time()))
filehandler.setFormatter(formatter)

logger.addHandler(printhandler)
logger.addHandler(filehandler)

logger.info("----------------NEW INSTANCE----------------")
logger.info("Loading Modis")
示例#28
0
    def __init__(self, server_id):
        """Locks onto a server for easy management of various UIs

        Args:
            server_id (str): The Discord ID of the server to lock on to
        """

        data = datatools.get_data()
        # Player variables
        self.server_id = server_id
        self.logger = logging.getLogger("{}.{}".format(__name__,
                                                       self.server_id))
        # File variables
        self.songcache_dir = "{}/{}".format(_root_songcache_dir,
                                            self.server_id)
        self.songcache_next_dir = "{}/{}/next".format(_root_songcache_dir,
                                                      self.server_id)
        self.output_format = "{}/{}".format(self.songcache_dir, file_format)
        self.output_format_next = "{}/{}".format(self.songcache_next_dir,
                                                 file_format)

        # Voice variables
        self.vchannel = None
        self.vclient = None
        self.streamer = None
        self.current_duration = 0
        self.current_download_elapsed = 0
        self.is_live = False
        self.queue = []
        self.prev_queue = []
        self.prev_queue_max = 500
        self.volume = 20
        # Timebar
        self.vclient_starttime = None
        self.vclient_task = None
        self.pause_time = None
        self.prev_time = ""
        # Loop
        self.loop_type = 'off'

        # Status variables
        self.mready = False
        self.vready = False
        self.state = 'off'

        # Gui variables
        self.mchannel = None
        self.embed = None
        self.queue_display = 9
        self.nowplayinglog = logging.getLogger("{}.{}.nowplaying".format(
            __name__, self.server_id))
        self.nowplayinglog.setLevel("DEBUG")
        self.nowplayingauthorlog = logging.getLogger(
            "{}.{}.nowplayingauthor".format(__name__, self.server_id))
        self.nowplayingauthorlog.setLevel("DEBUG")
        self.nowplayingsourcelog = logging.getLogger(
            "{}.{}.nowplayingsource".format(__name__, self.server_id))
        self.nowplayingsourcelog.setLevel("DEBUG")
        self.timelog = logging.getLogger("{}.{}.time".format(
            __name__, self.server_id))
        self.timelog.setLevel("DEBUG")
        self.timelog.propagate = False
        self.queuelog = logging.getLogger("{}.{}.queue".format(
            __name__, self.server_id))
        self.queuelog.setLevel("DEBUG")
        self.queuelog.propagate = False
        self.queuelenlog = logging.getLogger("{}.{}.queuelen".format(
            __name__, self.server_id))
        self.queuelenlog.setLevel("DEBUG")
        self.queuelenlog.propagate = False
        self.volumelog = logging.getLogger("{}.{}.volume".format(
            __name__, self.server_id))
        self.volumelog.setLevel("DEBUG")
        self.statuslog = logging.getLogger("{}.{}.status".format(
            __name__, self.server_id))
        self.statuslog.setLevel("DEBUG")
        self.statustimer = None

        # Clear the cache
        self.clear_cache()

        # Get channel topic
        self.topic = ""
        self.topicchannel = None
        # Set topic channel
        if "topic_id" in data["discord"]["servers"][self.server_id][
                _data.modulename]:
            topic_id = data["discord"]["servers"][self.server_id][
                _data.modulename]["topic_id"]
            if topic_id is not None and topic_id != "":
                logger.debug("Topic channel id: {}".format(topic_id))
                self.topicchannel = client.get_channel(topic_id)
        # Get volume
        if "volume" in data["discord"]["servers"][self.server_id][
                _data.modulename]:
            self.volume = data["discord"]["servers"][self.server_id][
                _data.modulename]["volume"]
        else:
            self.write_volume()
示例#29
0
async def on_message(message):
    """The on_message event handler for this module

    Args:
        message (discord.Message): Input message
    """

    # Simplify message info
    server = message.server
    author = message.author
    channel = message.channel
    content = message.content

    data = datatools.get_data()

    # Only reply to server messages and don't reply to myself
    if server is not None and author != channel.server.me:
        prefix = data["discord"]["servers"][server.id]["prefix"]
        # Check for mentions reply to mentions
        if channel.server.me in message.mentions:
            await client.send_typing(channel)
            response = "The current server prefix is `{0}`. Type `{0}help` for help.".format(
                prefix)
            await client.send_message(channel, response)

        # Commands section
        if content.startswith(prefix):
            # Parse message
            package = content.split(" ")
            command = package[0][len(prefix):]
            args = package[1:]
            arg = ' '.join(args)

            # Commands
            if command not in [
                    "prefix", "activate", "deactivate", "warnmax", "warn",
                    "ban"
            ]:
                return

            is_admin = author == server.owner
            for role in message.author.roles:
                if role.permissions.administrator:
                    is_admin = True

            if not is_admin:
                await client.send_typing(channel)
                reason = "You must have a role that has the permission 'Administrator'"
                embed = ui_embed.error(channel, "Insufficient Permissions",
                                       reason)
                await embed.send()
                return

            if command == "prefix" and args:
                new_prefix = arg.replace(" ", "").strip()
                data["discord"]["servers"][server.id]["prefix"] = new_prefix
                # Write the data
                datatools.write_data(data)

                await client.send_typing(channel)
                embed = ui_embed.modify_prefix(channel, new_prefix)
                await embed.send()

            if command == "warnmax" and args:
                try:
                    warn_max = int(arg)
                    if warn_max > 0:
                        data["discord"]["servers"][server.id][
                            _data.modulename]["warnings_max"] = warn_max
                        datatools.write_data(data)
                        await client.send_typing(channel)
                        embed = ui_embed.warning_max_changed(channel, warn_max)
                        await embed.send()
                    else:
                        reason = "Maximum warnings must be greater than 0"
                        embed = ui_embed.error(channel, "Error", reason)
                        await embed.send()
                except (ValueError, TypeError):
                    reason = "Warning maximum must be a number"
                    embed = ui_embed.error(channel, "Error", reason)
                    await embed.send()
                except Exception as e:
                    logger.exception(e)

            if command == "warn" and args:
                for user in message.mentions:
                    await api_manager.warn_user(channel, user)

            if command == "ban" and args:
                for user in message.mentions:
                    await api_manager.ban_user(channel, user)

            if command == "activate" and args:
                await api_manager.activate_module(channel, arg, True)
            elif command == "deactivate" and args:
                await api_manager.activate_module(channel, arg, False)