Esempio n. 1
0
def main():

    if not os.path.exists('Logs'):
        os.makedirs('Logs')
    #sets up the logging for discord.py
    disc_log = logging.getLogger('discord')
    disc_log.setLevel(logging.DEBUG)
    disc_log_name = Path(
        f'Logs/{datetime.now().strftime("%Y-%m-%d-%H.%M.%S")}_discord.log')
    handler = logging.FileHandler(filename=disc_log_name,
                                  encoding='utf-8',
                                  mode='w')
    handler.setFormatter(
        logging.Formatter('%(asctime)s:%(levelname)s:%(name)s: %(message)s'))
    disc_log.addHandler(handler)

    #creates the logger for the Bot Itself
    setup_logger()
    bot_log = logging.getLogger('bot')
    bot_log_name = Path(
        f'Logs/{datetime.now().strftime("%Y-%m-%d-%H.%M.%S")}_bot.log')
    bot_file_handle = logging.FileHandler(filename=bot_log_name,
                                          encoding='utf-8',
                                          mode='w')
    bot_file_handle.setFormatter(
        logging.Formatter('%(asctime)s %(levelname)s %(message)s'))
    bot_log.addHandler(bot_file_handle)

    try:
        bot_log.info(f'Attempting to load BotSecrets.json from {os.getcwd()}')
        with open("BotSecrets.json") as f:
            BotSecrets.get_instance().load_secrets(f.read())
    except FileNotFoundError as e:
        bot_log.error(f'{e}: The bot could not find your BotSecrets Json File')
        sys.exit(0)
    except KeyError as e:
        bot_log.error(f'{e} is not a valid key in BotSecrets')
        sys.exit(0)
    except Exception as e:
        bot_log.error(e)

    token = os.environ.get('BotToken', None)

    if token is not None:
        BotSecrets.get_instance().bot_token = token

    prefix = BotSecrets.get_instance().bot_prefix

    #Initialize the messenger here and inject it into the base bot class,
    #this is so it can be reused later on
    #if we decide to add something not related to the bot
    # E.G a website frontend
    messenger = Messenger(name='primary_bot_messenger')

    bot_log.info('Bot Starting Up')
    ClemBot(
        command_prefix=prefix,  # noqa: E126
        messenger=messenger,
        max_messages=5000).run(BotSecrets.get_instance().bot_token)
Esempio n. 2
0
def main():

    if not os.path.exists('Logs'):
        os.makedirs('Logs')
    #sets up the logging for discord.py
    logger = logging.getLogger('discord')
    logger.setLevel(logging.DEBUG)
    handler = logging.FileHandler(filename='Logs/discord.log',
                                  encoding='utf-8',
                                  mode='w')
    handler.setFormatter(
        logging.Formatter('%(asctime)s:%(levelname)s:%(name)s: %(message)s'))
    logger.addHandler(handler)

    #creates the logger for the Bot Itself
    setup_logger()
    bot_log = logging.getLogger('bot')
    bot_file_handle = logging.FileHandler('Logs/bot.log',
                                          encoding='utf-8',
                                          mode='w')
    bot_file_handle.setFormatter(
        logging.Formatter('%(asctime)s %(levelname)s %(message)s'))
    bot_log.addHandler(bot_file_handle)

    try:
        bot_log.info(f'Attempting to load BotSecrets.json from {os.getcwd()}')
        with open("BotSecrets.json") as f:
            BotSecrets.get_instance().load_secrets(f.read())
    except FileNotFoundError as e:
        bot_log.error(f'{e}: The bot could not find your BotSecrets Json File')
        sys.exit(0)
    except KeyError as e:
        bot_log.error(f'{e} is not a valid key in BotSecrets')
        sys.exit(0)
    except Exception as e:
        bot_log.error(e)

    token = os.environ.get('BotToken', None)

    if token is not None:
        BotSecrets.get_instance().bot_token = token

    bot_log.info('Bot Starting Up')
    ClemBot(command_prefix='$').run(BotSecrets.get_instance().bot_token)
Esempio n. 3
0
    async def _post_eval(self, code) -> t.Union[str, None]:
        data = {"input": code}

        json_data = json.dumps(data)

        async with aiohttp.ClientSession() as s:
            async with s.post(BotSecrets.get_instance().repl_url,
                              data=json_data,
                              headers=HEADERS) as resp:
                if resp.status == 200:
                    return json.loads(await resp.text())
Esempio n. 4
0
    async def define(self, ctx, word):
        """
        Given a word, find its definition and any other relevant information
        
        USE: define <word>
        EXAMPLE: define schadenfreude

        For phrases, use underscores
        EXAMPLE: define computer_science

        Letters, numbers, and special characters (_, &, and -) are supported
        """

        self.api_key = BotSecrets.get_instance().merriam_key

        # Remove any characters besides &, _, or - that are not in ranges a-z, A-Z, or 0-9
        # per the ASCII Table https://www.asciitable.com
        word = re.sub("[^a-zA-Z0-9 &_-]+", "", word)

        actualWord = word.replace('_', ' ')
        word = word.replace('_', '%20').lower()

        url = f'{API_URL}{word}?key={self.api_key}'
        wordPages = []

        # Try Except for catching errors that could give away the API key
        try:
            async with aiohttp.request('get', url) as response:
                if response.status == 200:
                    jsonData = await response.json()
                    wordPages = self.getPageData(jsonData, word)

                else:
                    embed = discord.Embed(title='Merriam_Webster Dictionary',
                                          color=Colors.Error)
                    ErrMsg = f'Oh No! There appears to be an issue! Yell at one of the developers with the following code.\nError Code: {response.status}'
                    embed.add_field(name='Error with API',
                                    value=ErrMsg,
                                    inline=False)
                    await ctx.send(embed=embed)
                    return

                await self.bot.messenger.publish(
                    Events.on_set_pageable_text,
                    embed_name='Merriam-Webster Dictionary',
                    field_title=f'Word: {actualWord}',
                    pages=wordPages,
                    author=ctx.author,
                    channel=ctx.channel)
        except Exception as err:
            err_str = str(err)
            err_str = re.sub(self.api_key, "CLASSIFIED", err_str)
            raise Exception(err_str).with_traceback(err.__traceback__)
Esempio n. 5
0
    def __init__(self, bot) -> None:
        self.bot = bot
        self.bot_files = {}
        self.ignored = ['Logs', 'venv', '__pycache__', 'database', '.git', '.pytest_cache', 'bot_env.env']
        self.repo_url = BotSecrets.get_instance().github_url

        root = os.getcwd()
        root_dir = root.split('/')[-1]
        for root, dirs, files in os.walk(root, topdown= True):
            dirs[:] = [d for d in dirs if not d.startswith('.')]
            if not any(folder in f'{root}/' for folder in self.ignored):
                for f in files:
                    path = os.path.join(root, f)
                    self.bot_files[f] = FilePaths(path, path.split(root_dir)[1])
Esempio n. 6
0
    async def on_ready(self) -> None:
        """
        This is the entry point of the bot that is run when discord.py has finished its startup procedures.
        This is where services are loaded and the startup procedures for each service is run
        """

        await Database(BotSecrets.get_instance().database_name).create_database()
        await self.load_services()

        #Send the ready event AFTER services have been loaded so that the designated channel service is there
        embed = discord.Embed(title='Bot Ready', color= Colors.ClemsonOrange)
        embed.add_field(name= 'Startup Time', value= datetime.datetime.utcnow())
        embed.set_thumbnail(url= self.user.avatar_url)
        await messenger.publish(Events.on_broadcast_designated_channel, DesignatedChannels.startup_log, embed)

        log.info(f'Logged on as {self.user}')
Esempio n. 7
0
    async def translate_detect_lang(self, ctx, input):
        output_lang = await get_lang_code(self, ctx, input[0])
        if output_lang == None:
            return

        text = ' '.join(input[1:])

        output_lang = await get_lang_code(self, ctx, output_lang)
        log.info(f'Output Lang Code: {output_lang}')

        params = {'api-version': '3.0', 'to': output_lang}

        body = [{'text': text}]

        headers = {
            'Ocp-Apim-Subscription-Key':
            BotSecrets.get_instance().azure_translate_key,
            'Ocp-Apim-Subscription-Region': 'global',
            'Content-type': 'application/json',
            'X-ClientTraceId': TRACE_ID
        }

        async with aiohttp.ClientSession() as session:
            async with await session.post(url=TRANSLATE_API_URL,
                                          params=params,
                                          headers=headers,
                                          json=body) as resp:
                response = json.loads(await resp.text())

        log.info(response[0]['detectedLanguage'])
        log.info(response[0]['translations'])
        embed = discord.Embed(title='Translate', color=Colors.ClemsonOrange)
        name = 'Translated to ' + LANGUAGE_SHORT_CODE_TO_NAME[
            response[0]['translations'][0]['to'].lower()]
        embed.add_field(name=name,
                        value=response[0]['translations'][0]['text'],
                        inline=False)
        embed.add_field(name='Confidence Level:',
                        value=response[0]['detectedLanguage']['score'],
                        inline=True)
        embed.add_field(name='Detected Language:',
                        value=LANGUAGE_SHORT_CODE_TO_NAME[
                            response[0]['detectedLanguage']['language']],
                        inline=True)
        await ctx.send(embed=embed)
        return
Esempio n. 8
0
    async def reset(self, ctx):

        default_prefix = BotSecrets.get_instance().bot_prefix

        if await self.bot.get_prefix(ctx.message) == default_prefix:
            embed = discord.Embed(title= 'Error', color= Colors.Error)
            embed.add_field(name= 'Invalid prefix', value= f'"{default_prefix}" Prefix is already the default')
            await ctx.send(embed= embed)
            return

        repo = CustomPrefixesRepository()

        await repo.set_prefix(ctx.guild.id, default_prefix)
        await self.bot.messenger.publish(Events.on_set_custom_prefix, ctx.guild, default_prefix)

        embed = discord.Embed(color= Colors.ClemsonOrange)
        embed.add_field(
            name= 'Prefix reset   :white_check_mark:',
            value= f'New Prefix: ```{default_prefix}```')

        await ctx.send(embed= embed)
Esempio n. 9
0
    async def database(self, ctx, *, query):
        """Runs arbitrary sql queries on the db in readonly mode and returns the results"""

        database_name = BotSecrets.get_instance().database_name
        db_path = f'database/{database_name}'
        connect_mode = 'ro'
        json_params = {'indent': 2, 'separators': (',', ': ')}

        async with aiosqlite.connect(f'file:{db_path}?mode={connect_mode}',
                                     uri=True) as db:
            async with db.execute(query) as c:
                result = await BaseRepository().fetcthall_as_dict(c)

        json_res = json.dumps(result, **json_params)

        if len(json_res) > DiscordLimits.MessageLength:
            await ctx.send(
                'Query result greater then discord message length limit')
            return

        await ctx.send(f'```{json_res}```')
Esempio n. 10
0
    async def on_ready(self) -> None:
        """
        This is the entry point of the bot that is run when discord.py has finished its startup procedures.
        This is where the bot checks to see if its in any new guilds and acts accordingly
        """

        await Database(BotSecrets.get_instance().database_name
                       ).create_database()

        log.info('Initializing guilds')
        for guild in self.guilds:
            try:
                await services.guild_handling.GuildHandling().add_guild(guild)
            except PrimaryKeyError as e:
                log.info(f'"{guild.name}" already known')

            log.info(f'Initializing members of {guild.name}')
            for user in guild.members:
                await services.user_handling.UserHandling().add_existing_user(
                    user, guild.id)

        log.info(f'Logged on as {self.user}')
Esempio n. 11
0
def _decrypt_message(message: str):
    fernet = Fernet(bytes(BotSecrets.get_instance().message_encryption_key))
    return fernet.decrypt(bytes(message)).decode()
Esempio n. 12
0
    "thai": "th",
    "turkish": "tr",
    "ukrainian": "uk",
    "urdu": "ur",
    "vietnamese": "vi",
    "welsh": "cy",
    "yucatec maya": "yua"
}
CHUNK_SIZE = 15
LANGUAGE_SHORT_CODE_TO_NAME = {
    value: key
    for key, value in LANGUAGE_NAME_TO_SHORT_CODE.items()
}

HEADERS = {
    'Ocp-Apim-Subscription-Key': BotSecrets.get_instance().azure_translate_key,
    'Ocp-Apim-Subscription-Region': 'global',
    'Content-type': 'application/json',
    'X-ClientTraceId': str(uuid.uuid4())
}

TRANSLATE_API_URL = "https://api.cognitive.microsofttranslator.com/translate"


class TranslateCog(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @ext.group(case_insensitive=True, invoke_without_command=True)
    @ext.long_help(
        'Allows you to translate words or sentences by either specifying both the input and output language with the text to translate, or just the output language and the text to translate. run \'translate languages\' to see available languages'
Esempio n. 13
0
 def __init__(self):
     self.database_name = BotSecrets.get_instance().database_name
     self.resolved_db_path = f'database/{self.database_name}'
Esempio n. 14
0
    async def weatherCode(self, ctx, loc, is_cond, is_hr, is_day):
        # Remove any characters not in ranges a-z, A-Z, or 0-9
        # Exceptions: & _ - , and <space>
        # per the ASCII Table https://www.asciitable.com
        loc = re.sub("[^a-zA-Z0-9 ,&_-]+", "", loc)

        # Geocoding URL
        url_Geo_API = f'{URL_GEO}{loc}'

        self.geocode_api_key = BotSecrets.get_instance().geocode_key
        self.weather_api_key = BotSecrets.get_instance().weather_key

        geo_queryparams = {
            'auth': self.geocode_api_key,
            'json': '1',
        }

        # Message to Display while APIs are called
        wait_msg = await ctx.send('Converting location')

        # Try Except for catching errors that could give away either API key
        try:
            async with aiohttp.request("GET",
                                       url_Geo_API,
                                       params=geo_queryparams) as response:
                if (response.status != 200):
                    embed = discord.Embed(title='OpenWeatherMap Weather',
                                          color=Colors.Error)
                    ErrMsg = f'Error Code: {response.status}'
                    embed.add_field(name='Error with geocode API',
                                    value=ErrMsg,
                                    inline=False)
                    await ctx.send(embed=embed)
                    return
                res_geo_json = await response.json()
        except Exception as err:
            err_str = str(err)
            err_str = re.sub(self.geocode_api_key, "CLASSIFIED", err_str)
            err_str = re.sub(self.weather_api_key, "CLASSIFIED", err_str)
            raise Exception(err_str).with_traceback(err.__traceback__)

        city = res_geo_json.get('standard', {}).get('city', {})
        lon = res_geo_json.get('longt', {})
        lat = res_geo_json.get('latt', {})

        queryparams = {
            'lat': lat,
            'lon': lon,
            'appid': self.weather_api_key,
            'units': 'imperial',
            'lang': 'en'
        }

        weatherPages = []
        await wait_msg.edit(content='Checking the weather')

        try:
            async with aiohttp.request("GET", URL_WEATHER,
                                       params=queryparams) as response:
                if (response.status != 200):
                    embed = discord.Embed(title='OpenWeatherMap Weather',
                                          color=Colors.Error)
                    ErrMsg = f'Error Code: {response.status}'
                    embed.add_field(name='Error with weather API',
                                    value=ErrMsg,
                                    inline=False)
                    await ctx.send(embed=embed)
                    return
                res_weather_json = await response.json()
        except Exception as err:
            err_str = str(err)
            err_str = re.sub(self.geocode_api_key, "CLASSIFIED", err_str)
            err_str = re.sub(self.weather_api_key, "CLASSIFIED", err_str)
            raise Exception(err_str).with_traceback(err.__traceback__)

        weatherPages, num_hr, num_day = self.getPageData(
            lat, lon, res_weather_json, city, is_cond, is_hr, is_day)

        # Construct Title Message
        msg_title = ''
        if is_cond:
            msg_title += f'Current Conditions'
        if is_cond and (is_hr or is_day):
            msg_title += ' with '

        if is_hr and is_day:
            msg_title += 'Forecast'
        elif is_hr:
            msg_title += f'{num_hr}-Hour Forecast'
        elif is_day:
            msg_title += f'{num_day}-Day Forecast'

        await wait_msg.delete()
        await self.bot.messenger.publish(Events.on_set_pageable_text,
                                         embed_name='OpenWeatherMap Weather',
                                         field_title=msg_title,
                                         pages=weatherPages,
                                         author=ctx.author,
                                         channel=ctx.channel)
        """ 
Esempio n. 15
0
 def __init__(self, bot):
     self.bot = bot
     self.api_key = BotSecrets.get_instance().merriam_key
Esempio n. 16
0
def _encrypt_message(message: str):
    fernet = Fernet(BotSecrets.get_instance().message_encryption_key)
    return fernet.encrypt(message.encode())
Esempio n. 17
0
def main():

    if not os.path.exists('Logs'):
        os.makedirs('Logs')
    #sets up the logging for discord.py
    disc_log = logging.getLogger('discord')
    disc_log.setLevel(logging.DEBUG)
    disc_log_name = Path(
        f'Logs/{datetime.now().strftime("%Y-%m-%d-%H.%M.%S")}_discord.log')
    handler = logging.FileHandler(filename=disc_log_name,
                                  encoding='utf-8',
                                  mode='w')
    handler.setFormatter(
        logging.Formatter('%(asctime)s:%(levelname)s:%(name)s: %(message)s'))
    disc_log.addHandler(handler)

    #creates the logger for the Bot Itself
    setup_logger()
    bot_log = logging.getLogger('bot')
    bot_log_name = Path(
        f'Logs/{datetime.now().strftime("%Y-%m-%d-%H.%M.%S")}_bot.log')
    bot_file_handle = logging.FileHandler(filename=bot_log_name,
                                          encoding='utf-8',
                                          mode='w')
    bot_file_handle.setFormatter(
        logging.Formatter('%(asctime)s %(levelname)s %(message)s'))
    bot_log.addHandler(bot_file_handle)

    #check if this is a prod or a dev instance
    if bool(os.environ.get('PROD')):
        bot_log.info('Production env var found, loading production enviroment')
        BotSecrets.get_instance().load_production_secrets()
    else:
        try:
            bot_log.info(
                f'Attempting to load BotSecrets.json from {os.getcwd()}')
            with open("BotSecrets.json") as f:
                BotSecrets.get_instance().load_development_secrets(f.read())
        except FileNotFoundError as e:
            bot_log.error(
                f'{e}: The bot could not find your BotSecrets Json File')
            sys.exit(0)
        except KeyError as e:
            bot_log.error(f'{e} is not a valid key in BotSecrets')
            sys.exit(0)
        except Exception as e:
            bot_log.error(e)

    #get the default prefix for the bot instance
    prefix = BotSecrets.get_instance().bot_prefix

    #Initialize the messenger here and inject it into the base bot class,
    #this is so it can be reused later on
    #if we decide to add something not related to the bot
    # E.G a website frontend
    messenger = Messenger(name='primary_bot_messenger')

    #create the custom prefix handler class, and register its methods
    #as event callbacks
    custom_prefix = CustomPrefix(default=prefix)
    messenger.subscribe(Events.on_set_custom_prefix, custom_prefix.set_prefix)

    #enable privileged member gateway intents
    intents = discord.Intents.default()
    intents.members = True

    #Create the scheduler for injection into the bot instance
    scheduler = Scheduler()

    #set allowed mentions
    mentions = discord.AllowedMentions(everyone=False, roles=False)

    bot_log.info('Bot Starting Up')
    ClemBot(
        messenger=messenger,
        scheduler=scheduler,
        command_prefix=custom_prefix.get_prefix,  # noqa: E126
        help_command=None,
        case_insensitive=True,
        max_messages=50000,
        allowed_mentions=mentions,
        intents=intents).run(BotSecrets.get_instance().bot_token)