Source code for fusionsid.image

from io import BytesIO
from datetime import datetime

import PIL
import aiohttp
import aiofiles
from PIL import Image as img

from .http import HTTPClient
from .errors import ImageNotGenerated


[docs]class BaseImage: """ Base class for all images ------------------------- Methods ------- save(path : str) : Saves the file to a path """ def __init__(self, image_bytes=None) -> None: self.image_bytes = image_bytes
[docs] async def save(self, path: str) -> None: """ Saves an image """ if self.image_bytes is None: raise ImageNotGenerated async with aiofiles.open(path, "wb") as f: await f.write(self.image_bytes)
[docs] async def show(self) -> None: """ Shows an image """ if self.image_bytes is None: raise ImageNotGenerated image = img.open(BytesIO(self.image_bytes)) image.show() return None
[docs] async def save_bytesio(self) -> BytesIO: """ Saves the image to BytesIO Returns ------- :class:`BytesIO` """ if self.image_bytes is None: raise ImageNotGenerated image = BytesIO(self.image_bytes) return image
[docs] async def pil(self) -> PIL.Image.Image: """ Converts the image to a PIL.Image.Image object and returns it Returns ------- :class:`PIL.Image.Image` """ image = img.open(BytesIO(self.image_bytes)) return image
[docs]class RandomMeme(BaseImage): """ Random Meme ----------- Example ------- >>> meme = await Image.random_meme() >>> await meme.save('meme.png') Attrbutes --------- image_bytes (bytes) : The image in bytes title (str) : Title of the post upvotes (str) : How many upvotes the meme has author (str) : Author of the meme url (str) : Url to the reddit post ext (str) : The file extension (eg: png) json (Dict) : The json response from the api created_at (datetime.datetime) : The time when the class was made """ def __init__(self, json, image_bytes) -> None: self.json = json super().__init__(image_bytes=image_bytes) self.created_at = datetime.now() @property def title(self) -> str: """The title of the meme""" if self.image_bytes is None: raise ImageNotGenerated return self.json["title"] @property def upvotes(self) -> str: """How many upvotes the meme has""" if self.image_bytes is None: raise ImageNotGenerated return self.json["upvotes"] @property def author(self) -> str: """Author of the post""" if self.image_bytes is None: raise ImageNotGenerated return self.json["author"] @property def url(self) -> str: """Url to the reddit post""" if self.image_bytes is None: raise ImageNotGenerated return self.json["url"] @property def ext(self) -> str: """The file extension""" if self.image_bytes is None: raise ImageNotGenerated return self.json["url"].split(".")[-1]
[docs]class QRCode(BaseImage): """ QR Code ------- Example ------- >>> qrcode = Image.qrcode("https://google.com") >>> await meme.save('qrcode.png') Attrbutes --------- url (str) : The url that your making the meme for image_bytes (bytes) : The image in bytes created_at (datetime) : The time when the class was made """ def __init__(self, url, image_bytes): self.url = url self.created_at = datetime.now() super().__init__(image_bytes=image_bytes)
[docs]class FontImage(BaseImage): """ FontConvertedImage ------------------ Attributes ---------- created_at (datetime) : The time when the class was made """ def __init__(self, image_bytes): self.created_at = datetime.now() super().__init__(image_bytes=image_bytes)
[docs]class Image: """ Group of non meme generating image function ------------------------------------------- Methods ------- random_meme() qrcode(url : str) get_colors(filepath : str, show_hex : bool = True) """
[docs] @classmethod async def random_meme(cls) -> RandomMeme: """ Gets a random meme from the subreddit: r/memes Returns ------- :class:`RandomMeme` : The meme """ while True: image = await HTTPClient().get_json(url="meme?reddit_json_info=True") if "." in image["url"]: break image_url = image["url"] image_bytes = await HTTPClient().get_url_image(image_url) return RandomMeme(json=image, image_bytes=image_bytes)
[docs] @classmethod async def qrcode(cls, url: str) -> QRCode: """ Generates a qr code Returns ------- :class:`QRCode` : The qrcode """ qrcode = await HTTPClient().get_image(f"qrcode?link={url}") return QRCode(url, qrcode)
[docs] @classmethod async def get_colors(cls, filepath: str, show_hex=True) -> dict: """ Gets the most dominant color and color palette of an image Parameters ---------- filepath (str) : The path to the file show_hex (bool) : By default the api will return hex values but if you want rgb set this to False Example ------- >>> await Image.get_colors("snail.png", False) """ try: with open(filepath, "rb") as f: image_in_bytes = f.read() except FileNotFoundError: return "File not found" async with aiohttp.ClientSession() as session: async with session.post( f"https://api.fusionsid.xyz/api/get_colors/?show_hex={show_hex}", data={"image": image_in_bytes}, ) as resp: data = await resp.json() return data
[docs] @classmethod async def font_convert( cls, text: str, font_name: str, color: str = "black" ) -> FontImage: """ Converts text to a font you choose Parameters ---------- text (str): The text you are converting font_name (str): The font you are converting to, Use the Image.font_list() function to get a list of them color (str, Optional): The color of the text, Defaults to black Returns ------- :class:`FontImage`: The image of the font """ list_of_fonts = await HTTPClient().get_json("fontconvert/list") list_of_fonts = list_of_fonts["Font_List"] if font_name not in list_of_fonts: url = "https://api.fusionsid.xyz/api/fontconvert/list" return print( f"Invalid font, go to {url} to get a list of them or use the font list function" ) url = f"""fontconvert?text={text}&font={font_name}&color={color}""" image_bytes = await HTTPClient().get_image(url) return FontImage(image_bytes)
[docs] @classmethod async def font_list(cls, print_all: bool = False) -> list: """ Prints a list of all the fonts that the api supports converting to Parameters ---------- print_all (bool, Optional): setting this to true will print all the fonts in console Returns ------- :class:`List` : The list of fonts """ list_of_fonts = await HTTPClient().get_json("fontconvert/list") list_of_fonts = list_of_fonts["Font_List"] if print_all: print("\n".join(list_of_fonts)) return list_of_fonts
[docs]class Meme(BaseImage): """ Meme ---- Attributes ---------- created_at (datetime) : The time when the class was made """ def __init__(self, image_bytes): self.created_at = datetime.now() super().__init__(image_bytes=image_bytes)
[docs]class GenerateMeme: """ Generate Memes -------------- """
[docs] @classmethod async def abandon(cls, text: str) -> Meme: """ Generates the abandon meme Parameters ---------- text (str) : The text you want to use for the meme Returns ------- Meme """ image_bytes = await HTTPClient().get_image( f"abandon?text={text}" ) return Meme(image_bytes)
[docs] @classmethod async def armor(cls, text: str) -> Meme: """ Generates the armor meme Parameters ---------- text (str) : The text you want to use for the meme Returns ------- Meme """ image_bytes = await HTTPClient().get_image( f"armor?text={text}" ) return Meme(image_bytes)
[docs] @classmethod async def surprised(cls, text: str) -> Meme: """ Generates the surprised meme Parameters ---------- text (str) : The text you want to use for the meme Returns ------- Meme """ image_bytes = await HTTPClient().get_image( f"surprised?text={text}" ) return Meme(image_bytes)
[docs] @classmethod async def violence(cls, text: str) -> Meme: """ Generates the violence meme Parameters ---------- text (str) : The text you want to use for the meme Returns ------- Meme """ image_bytes = await HTTPClient().get_image( f"violence?text={text}" ) return Meme(image_bytes)
[docs] @classmethod async def change_my_mind(cls, text: str) -> Meme: """ Generates the change my mind meme Parameters ---------- text (str) : The text you want to use for the meme Returns ------- Meme """ image_bytes = await HTTPClient().get_image( f"changemymind?text={text}" ) return Meme(image_bytes)
[docs] @classmethod async def balloon(cls, balloon_text: str, arrow_text: str) -> Meme: """ Generates the balloon meme Parameters ---------- balloon_text (str) : The text you want to use for the ballon part of the meme arrow_text (str) : The text you want to use for the arrow part of the meme Returns ------- Meme """ image_bytes = await HTTPClient().get_image( f"balloon?text1={balloon_text}&text2={arrow_text}" ) return Meme(image_bytes)
[docs] @classmethod async def boo(cls, text_1: str, text_2: str) -> Meme: """ Generates the boo meme Parameters ---------- text_1 (str) : The text you want to use for the first part of the meme text_2 (str) : The text you want to use for the second part of the meme Returns ------- Meme """ image_bytes = await HTTPClient().get_image( f"boo?text_1={text_1}&text_2={text_2}" ) return Meme(image_bytes)
[docs] @classmethod async def brain(cls, text_1: str, text_2: str, text_3 : str, text_4 : str) -> Meme: """ Generates the brain meme Parameters ---------- text_1 (str): The text you want to use for the first box text_2 (str): The text you want to use for the second box text_3 (str): The text you want to use for the third box text_4 (str): The text you want to use for the forth box Returns ------- Meme """ image_bytes = await HTTPClient().get_image( f"brain?text_1={text_1}&text_2={text_2}&text_3={text_3}&text_4={text_4}" ) return Meme(image_bytes)
[docs] @classmethod async def expanding_wwe(cls, text_1: str, text_2: str, text_3 : str, text_4 : str, text_5 : str) -> Meme: """ Generates the expanding wwe meme Parameters ---------- text_1 (str): The text you want to use for the first box text_2 (str): The text you want to use for the second box text_3 (str): The text you want to use for the third box text_4 (str): The text you want to use for the forth box text_5 (str): The text you want to use for the fifth box Returns ------- Meme """ image_bytes = await HTTPClient().get_image( f"expandingwwe?text_1={text_1}&text_2={text_2}&text_3={text_3}&text_4={text_4}&text_5={text_5}" ) return Meme(image_bytes)
[docs] @classmethod async def bongocat(cls, image_url: str) -> Meme: """ Generates the bongocat meme Parameters ---------- image_url (str) : The image you want to use for the meme Returns ------- Meme """ image_bytes = await HTTPClient().get_image(f"bongocat?image_url={image_url}") return Meme(image_bytes)
[docs] @classmethod async def brazzers(cls, image_url: str) -> Meme: """ Generates the brazzers meme Parameters ---------- image_url (str) : The image you want to use for the meme Returns ------- Meme """ image_bytes = await HTTPClient().get_image(f"brazzers?image_url={image_url}") return Meme(image_bytes)
[docs] @classmethod async def gun(cls, image_url: str) -> Meme: """ Generates the gun meme Parameters ---------- image_url (str) : The image you want to use for the meme Returns ------- Meme """ image_bytes = await HTTPClient().get_image(f"gun?image_url={image_url}") return Meme(image_bytes)
[docs] @classmethod async def trash(cls, image_url: str) -> Meme: """ Generates the trash meme Parameters ---------- image_url (str) : The image you want to use for the meme Returns ------- Meme """ image_bytes = await HTTPClient().get_image(f"trash?image_url={image_url}") return Meme(image_bytes)
[docs] @classmethod async def aborted(cls, image_url: str) -> Meme: """ Generates the aborted meme Parameters ---------- image_url (str) : The image you want to use for the meme Returns ------- Meme """ image_bytes = await HTTPClient().get_image(f"aborted?image_url={image_url}") return Meme(image_bytes)
[docs] @classmethod async def affect(cls, image_url: str) -> Meme: """ Generates the aborted meme Parameters ---------- image_url (str) : The image you want to use for the meme Returns ------- Meme """ image_bytes = await HTTPClient().get_image(f"affect?image_url={image_url}") return Meme(image_bytes)
[docs] @classmethod async def wanted(cls, image_url: str) -> Meme: """ Generates the wanted meme Parameters ---------- image_url (str) : The image you want to use for the meme Returns ------- Meme """ image_bytes = await HTTPClient().get_image(f"wanted?image_url={image_url}") return Meme(image_bytes)
[docs] @classmethod async def delete(cls, image_url: str) -> Meme: """ Generates the delete meme Parameters ---------- image_url (str) : The image you want to use for the meme Returns ------- Meme """ image_bytes = await HTTPClient().get_image(f"delete?image_url={image_url}") return Meme(image_bytes)