Exemple #1
0
async def get_image_from_album(album_hash, image_id=-1):
    """Gets an image from an imgur album. By default will get a random image in the album, but a value can be given.
    Returns a url pointing to the image.
    Arguments
    ---------
    album_hash : str
        The imgur album hash
    image_id : int (default=-1)
        The imgur image id. If negative, a random image will be taken.
    """
    url = f"https://api.imgur.com/3/album/{album_hash}"

    async with aiohttp.ClientSession() as session:
        async with session.get(
                url, headers=dict(
                    Authorization=f"Client-ID {CLIENT_ID}")) as response:
            try:
                album = await response.json()
                if image_id < 0:
                    image_id = randrange(album["data"]["images_count"])
                image = album["data"]["images"][image_id]
                return image["link"]
            except JSONDecodeError:
                print("JSON Error")
                raise UserError("Bad Response from Imgur")
            except (KeyError, IndexError):
                raise UserError("Invalid Response format from Imgur")
Exemple #2
0
    async def wordcloud(self, ctx,
        in_time = CONFIG["commands"]["whatdidimiss"]["defaulttime"],
        one_channel = "True",
        case_insensitive = "True"
        ):
        try:
            await self.check_cooldown(ctx)
            
            # Checking for appropriate permissions
            check_cmd_perms(ctx)

            seconds = utils.parse_time_to_seconds(in_time)
            if  seconds > utils.parse_time_to_seconds(CONFIG["commands"]["whatdidimiss"]["maxtime"]) or seconds < 1:
                raise UserError(f'Thats too much time! {CONFIG["commands"]["whatdidimiss"]["maxtime"]} Maximum!', True)

            one_channel = utils.parse_bool(one_channel)
            case_insensitive = utils.parse_bool(case_insensitive)
            # Getting the earliest time that should be used
            timestamp = datetime.datetime.utcnow() - datetime.timedelta(seconds=seconds)

            # And now for the slow stuff
            with ctx.typing():
                # Next, recursively grabbing messages and appending them to a long ass string
                words = await utils.collect_messages(ctx, one_channel, timestamp, CONFIG["commands"]["whatdidimiss"]["stopwords"], case_insensitive)
                with concurrent.futures.ProcessPoolExecutor() as pool:
                    image = await asyncio.get_event_loop().run_in_executor(pool, create_wordcloud, words)
                    await ctx.send(f"Heres what happened in the past: {in_time}", file=discord.File(fp=image, filename="wordcloud.png"))
        except UserError as e:
            await ctx.send(f":warning:  {e.message}")
            # Removing the cooldown as an act of mercy
            if e.no_cooldown:
                cooldown.remove_cooldown(ctx)
Exemple #3
0
def create_wordcloud(words):
    r"""Creates a wordcloud given a frequency dictionary, saves it to filename.
    Parameters
    ----------
    words : dict
        A dictionary of words to be used in the cloud.
        Every string should have an integer value representing it's frequency.
        Passes data, and config, to WordCloud.WordCloud().generate_from_frequencies()
        for generation.
    """
    wc = wordcloud.WordCloud(
        scale = CONFIG["commands"]["whatdidimiss"]["scale"],
        width = CONFIG["commands"]["whatdidimiss"]["width"],
        height = CONFIG["commands"]["whatdidimiss"]["height"],
        background_color = CONFIG["commands"]["whatdidimiss"]["background-colour"],
        mode = "RGBA",
        outline_thickness = CONFIG["commands"]["whatdidimiss"]["outline-thickness"],
        font_path = CONFIG["commands"]["whatdidimiss"]["fontpath"],
        tint_emoji = CONFIG["commands"]["whatdidimiss"]["tint"],
        emoji_cache_path = CONFIG["commands"]["whatdidimiss"]["cache"],
        rotate_emoji = CONFIG["commands"]["whatdidimiss"]["rotate"],
        font_size_mod = CONFIG["commands"]["whatdidimiss"]["limit"],
        colormap=secrets.choice(CONFIG["commands"]["whatdidimiss"]["colormaps"])
    )
    file = BytesIO()
    if words:
        wc.generate_from_frequencies(words, False).to_image().save(file, 'png')
        file.seek(0)
    else:
        raise UserError("I need words for a wordcloud!", True)
    return file
Exemple #4
0
async def get_json(url, headers_={}):
    async with aiohttp.ClientSession() as session:
        async with session.get(url, headers=headers_) as response:
            try:
                return await response.json()
            except JSONDecodeError:
                raise UserError("Imgur gave a bad response :(")
    async def whatdidimiss(self, ctx):
        try:
            # Checking cooldown:
            if cooldown.cooldown_in_effect(ctx):
                raise UserError("Please wait for cooldown.")
            cooldown.add_cooldown(
                ctx, CONFIG["commands"]["whatdidimiss"]["cooldown"])

            # Checking for appropriate permissions
            check_cmd_perms(ctx)

            timestamp = datetime.datetime.utcnow() - datetime.timedelta(
                seconds=utils.parse_time_to_seconds(
                    CONFIG["commands"]["whatdidimiss"]["max-lookback-time"]))

            with ctx.typing():
                (words, msg_time) = await utils.collect_messages(
                    ctx, True, timestamp,
                    CONFIG["commands"]["whatdidimiss"]["stopwords"], True,
                    True)
                with concurrent.futures.ProcessPoolExecutor() as pool:
                    image = await asyncio.get_event_loop().run_in_executor(
                        pool, create_wordcloud, words)
                if msg_time.total_seconds() == 0:
                    time_diff = f'Hit max time of {CONFIG["commands"]["whatdidimiss"]["max-lookback-time"]}'
                else:
                    time_diff = utils.parse_seconds_to_time(
                        int(msg_time.total_seconds()))
                await ctx.send(
                    f"Here are the messages since your last post: ({time_diff})",
                    file=discord.File(fp=image, filename="wordcloud.png"))
            cooldown.add_cooldown(
                ctx, CONFIG["commands"]["whatdidimiss"]["cooldown"])
        except UserError as e:
            await ctx.send(f"Invalid input: {e.message}")
Exemple #6
0
async def get_dog_image(gif=False, download=True):
    url = "https://api.thedogapi.com/v1/images/search?mime_types="
    url += int(gif)*"gif" + int(not gif)*"jpg,png"
    try:
        url = (await get_json(url))[0]["url"]
        return (await get_image("dog", url)) if download else url
    except (KeyError, IndexError):
        raise UserError("Dog API gave a bad response :(")
Exemple #7
0
def check_cmd_perms(ctx):
    # Checking for appropriate permissions
    # Only check if the bot type is a member of a server
    if not utils.check_perms(ctx, discord.Permissions(
        read_message_history = True,
        attach_files = True,
        send_messages = True
    )):
        raise UserError("`read_message_history`, `attach_files`, and `send_messages` permissions required.", True)
    async def find_wordcloud(self, ctx, in_time, one_channel=True, case_insensitive=True, stop_after_usermsg=False):
        try:
            await self.check_cooldown(ctx)
            
            if not utils.check_perms(ctx, discord.Permissions(
                read_message_history = True,
                attach_files = True,
                send_messages = True
            )):
                raise UserError("`read_message_history`, `attach_files`, and `send_messages` permissions required.", True)

            seconds = utils.parse_time_to_seconds(in_time)
            if  seconds > utils.parse_time_to_seconds(CONFIG["commands"]["whatdidimiss"]["maxtime"]) or seconds < 1:
                raise UserError(f'Thats too much time! {CONFIG["commands"]["whatdidimiss"]["maxtime"]} Maximum!', True)
            
            # Getting the earliest time that should be used
            timestamp = datetime.datetime.utcnow() - datetime.timedelta(seconds=seconds)

            # And now for the slow stuff
            with ctx.typing():
                # Next, recursively grabbing messages and appending them to a long ass string
                result = await utils.collect_messages(
                    ctx, one_channel, timestamp, CONFIG["commands"]["whatdidimiss"]["stopwords"], case_insensitive, stop_after_usermsg
                )
                # Depending on if stop_after_usermsg is set, it'll either just return the frequency dict, or a tuple with more information
                words = result[0]
                msg_count = result[1]
                if stop_after_usermsg:
                    if result[2].total_seconds() == 0:
                        time_diff = f'Hit max time of {CONFIG["commands"]["whatdidimiss"]["max-lookback-time"]}'
                    else:
                        time_diff = utils.parse_seconds_to_time(int(result[2].total_seconds()))
                
                with concurrent.futures.ProcessPoolExecutor() as pool:
                    image = await asyncio.get_event_loop().run_in_executor(pool, create_wordcloud, words)
                    if stop_after_usermsg:
                        await ctx.send(f"Heres what happened since your last post {time_diff} ago ({msg_count} messages)", file=discord.File(fp=image, filename="wordcloud.png"))
                    else:
                        await ctx.send(f"Heres what happened in the past {utils.prettify_time(in_time)} ({msg_count} messages)", file=discord.File(fp=image, filename="wordcloud.png"))
        except UserError as e:
            await ctx.send(f":warning:  {e.message}")
            # Removing the cooldown as an act of mercy
            if e.no_cooldown:
                cooldown.remove_cooldown(ctx)
Exemple #9
0
async def get_image_from_album(album_hash, download=True, image_id=-1):
    """Gets an image from an imgur album. By default will get a random image in the album, but a value can be given.
    Returns a url pointing to the image.
    Arguments
    ---------
    album_hash : str
        The imgur album hash
    image_id : int (default=-1)
        The imgur image id. If negative, a random image will be taken.
    """
    url = f"https://api.imgur.com/3/album/{album_hash}"
    try:
        album = await get_json(url, {"Authorization": f"Client-ID {CLIENT_ID}"})
        image_id = image_id if image_id > -1 else randrange(album["data"]["images_count"])
        url = album["data"]["images"][image_id]["link"]
        return (await get_image("gator", url)) if download else url
    except (KeyError, IndexError):
        raise UserError("Got an Invalid Response")
Exemple #10
0
 async def check_cooldown(self, ctx):
     c, t = cooldown.cooldown_in_effect(ctx)
     if c:
         t = utils.parse_seconds_to_time(t)
         raise UserError(f"Relax. Your cooldown expires in {t}!")
     cooldown.add_cooldown(ctx, CONFIG["commands"]["whatdidimiss"]["cooldown"])