diff --git a/coffeeani/coffeeani.py b/coffeeani/coffeeani.py index 032a40d..3009ffe 100644 --- a/coffeeani/coffeeani.py +++ b/coffeeani/coffeeani.py @@ -47,7 +47,6 @@ async def manga(self, ctx, *, title): To search by source, use: - `[p]anilist manga` - `[p]batoto` - - `[p]kakao` - `[p]mangadex` """ msg = await ctx.send(embeds=[discord_embed_source(NAME_ANILIST, COLOR_ANILIST)]) @@ -155,26 +154,3 @@ async def batoto(self, ctx, *, title): if embeds: return await ExtendedSimpleMenu(pages=embeds, timeout=90).replace(ctx, msg) return await msg.edit(embeds=[discord_embed_source(None)]) - - @commands.hybrid_command() - @app_commands.describe(title="Search Kakao for manhwa") - @commands.bot_has_permissions(embed_links=True, add_reactions=True) - async def kakao(self, ctx, *, title): - """Search Kakao - - Search Kakao Webtoons for manhwa. Korean version only. - - > ✅ 공주 - """ - msg = await ctx.send(embeds=[discord_embed_source(NAME_KAKAO_WEBTOON, COLOR_KAKAO)]) - # TODO: Add DeepL translation for EN -> KO - # if title.startswith('"') and title.endswith('"') and len(title) > 2: - # title = title[1:-1] - # elif title.isascii(): - # translated = await translate_deepl(self, title, "EN", "KO") - # if translated: - # title = translated - embeds = await discord_kakao_embeds(self, title) - if embeds: - return await ExtendedSimpleMenu(pages=embeds, timeout=90).replace(ctx, msg) - return await msg.edit(embeds=[discord_embed_source(None)]) diff --git a/coffeeani/coffeeani_utils/sources/__init__.py b/coffeeani/coffeeani_utils/sources/__init__.py index 7aa359e..b85ab7a 100644 --- a/coffeeani/coffeeani_utils/sources/__init__.py +++ b/coffeeani/coffeeani_utils/sources/__init__.py @@ -12,12 +12,6 @@ discord_batoto_embeds ) -from .kakao_discord import ( - NAME_KAKAO_WEBTOON, - COLOR_KAKAO, - discord_kakao_embeds -) - from .mangadex_discord import ( NAME_MANGADEX, COLOR_MANGADEX, diff --git a/coffeeani/coffeeani_utils/sources/kakao.py b/coffeeani/coffeeani_utils/sources/kakao.py deleted file mode 100644 index 324dfe8..0000000 --- a/coffeeani/coffeeani_utils/sources/kakao.py +++ /dev/null @@ -1,176 +0,0 @@ -import aiohttp -try: - from korean_romanizer.romanizer import Romanizer -except ImportError: - Romanizer = None - -import asyncio -import base64 -import io -import json -import urllib.parse - -from ..models import SearchResult -from ..utils import * - -import logging -logger = logging.getLogger(__name__) - -try: - from PIL import Image - DEP_PIL = True -except: - DEP_PIL = False - -NAME_KAKAO_WEBTOON = "Kakao Webtoon (카카오웹툰)" - -COLOR_KAKAO = "#121212" - -URL_KAKAO_WEBTOON_SEARCH = "https://gateway-kw.kakao.com/search/v2/content?limit=6&offset=0&word=###KAKAO_VAR###" -URL_KAKAO_WEBTOON_ID = "https://gateway-kw.kakao.com/decorator/v2/decorator/contents/###KAKAO_VAR###" - -async def kakao_request(base_url, query=""): - url = str(base_url).replace("###KAKAO_VAR###", str(query)) - async with aiohttp.ClientSession() as session: - async with session.get(url) as response: - return await response.json() - -async def kakao_search_manga(query): - try: - raw_data = await kakao_request(URL_KAKAO_WEBTOON_SEARCH, query) - if not raw_data: - return None - if raw_data["meta"]["pagination"]["totalCount"] <= 0: - return None - except Exception as err: - logger.error(err, exc_info=True) - return None - - embeds = [] - j_data = raw_data.get("data", {}) - j_content = j_data.get("content", []) - if len(j_content) <= 0: - logger.debug("No results") - return None - - for idx, anime_manga in enumerate(j_content): - payload = SearchResult() - payload.series_id = anime_manga.get("id", None) - payload.link = "https://webtoon.kakao.com/content/"+urllib.parse.quote(anime_manga.get("seoId", ""), safe="")+"/"+str(payload.series_id) - payload.title = anime_manga.get("title", "None") - payload.description = anime_manga.get("catchphraseThreeLines", None) or anime_manga.get("catchphraseTwoLines", None) or None - payload.embed_description = kakao_get_description(payload.description) - payload.image = None - payload.image_thumbnail = kakao_get_image(anime_manga.get("backgroundImage")) - payload.info_format = "MANHWA" - payload.authors = kakao_get_authors(anime_manga) - payload.country_of_origin = "ko" - payload.country_of_origin_flag_str = ":flag_kr: " - payload.names = [anime_manga.get("title", None)] - payload.tags = kakao_get_tags(anime_manga) - payload.background_color = anime_manga.get("backgroundColor", None) - if Romanizer: - payload.romanized_title = Romanizer(str(payload.title)).romanize().title() - else: - payload.romanized_title = None - - manhwa = await kakao_request_manhwa(payload.series_id) - if manhwa: - new_description = manhwa.get("synopsis", None) - payload.description = new_description - payload.embed_description = kakao_get_description(new_description) - payload.image = kakao_get_image(manhwa.get("thumbnailImage")) - payload.image_thumbnail = None - payload.info_status = "Status: " + str(manhwa.get("status", None)).lower().replace("_", " ").capitalize() - payload.info_statistics = kakao_get_statistics(manhwa.get("statistics")) - payload.info_links = f"[Kakao Webtoon]({payload.link})" - payload.info = "\n".join(filter(None, [payload.info_statistics, payload.info_links])) - - embeds.append(payload.__dict__) - return (embeds, j_content) - -async def kakao_request_manhwa(id): - j_profile = await kakao_request(URL_KAKAO_WEBTOON_ID, str(id)) - if j_profile.get("data", None): - return j_profile.get("data", None) - return None - -async def kakao_request_image(image_url): - if not image_url: - return None - url = str(image_url) + ".webp" - async with aiohttp.ClientSession() as session: - async with session.get(url) as resp: - data = await resp.read() - return io.BytesIO(data) - -def kakao_get_description(text): - condensed_text = description_parser(text, limit_lines=False, limit_char=155, flatten_lines=True) - translate_link = format_translate(text, "ko", "en") - if len(translate_link) > 1800: - translate_link = format_translate(description_parser(text, limit_lines=False, limit_char=1000, flatten_lines=True), "ko", "en") - if len(translate_link) > 1800: - translate_link = "https://deepl.com/translator" - return condensed_text + f"\n[See Translation >]({translate_link})" - -def kakao_get_image(image_url): - if image_url: - return str(image_url)+".webp" - return None - -def kakao_get_authors(result): - authors = result.get("authors", []) - msg = [] - for au in authors: - name = au.get('name') - if Romanizer and name and not name.isascii(): - name = name + f' *({Romanizer(str(name)).romanize().title()})*' - msg.append(f"{str(au.get('type')).lower().replace('_', ' ').capitalize()}: {str(name)}") - return "\n".join(msg) - -def kakao_get_statistics(statistics): - msg = [] - view_count = statistics.get("viewCount") - if view_count: - msg.append(f"👀 {view_count:,}") - like_count = statistics.get("likeCount") - if like_count: - msg.append(f"👍 {like_count:,}") - return "\n".join(msg) - -def kakao_get_tags(manhwa): - tag = manhwa.get("genre") - if GENRES_MAP.get(tag): - return [GENRES_MAP.get(tag)] - elif tag: - return [tag] - return None - -async def kakao_build_image_banner(bg_img_url, char_img_url): - if not bg_img_url and not char_img_url: - return None - if not bg_img_url: - return char_img_url - if not char_img_url: - return bg_img_url - bg_img_raw = await kakao_request_image(bg_img_url) - bg_img = Image.open(bg_img_raw) - char_img_raw = await kakao_request_image(char_img_url) - char_img = Image.open(char_img_raw) - # Build base image - left, upper, right, lower = 0, 50, bg_img.width, 350 - final_img = bg_img.crop((left, upper, right, lower)) - # Build opacity overlay - overlay = Image.new('RGBA', final_img.size, (0,0,0,128)) # 128/255 -> 0.5 opacity - final_img = Image.alpha_composite(final_img.convert('RGBA'), overlay) - # Build char_img - char_img_width = int((280 / char_img.height) * char_img.width) - char_img_resized = char_img.resize((char_img_width, 280)) - final_img.paste(char_img_resized, (final_img.width - char_img_resized.width - 20, 20), char_img_resized) - # Save to image - output = io.BytesIO() - final_img.save(output, format="WEBP") - output.seek(0) - # data_uri = base64.b64encode(output.getvalue()).decode("utf-8") - # return "data:image/webp;base64," + str(data_uri) - return output diff --git a/coffeeani/coffeeani_utils/sources/kakao_discord.py b/coffeeani/coffeeani_utils/sources/kakao_discord.py deleted file mode 100644 index 63eade8..0000000 --- a/coffeeani/coffeeani_utils/sources/kakao_discord.py +++ /dev/null @@ -1,43 +0,0 @@ -import discord - -import io -from typing import List - -from .kakao import NAME_KAKAO_WEBTOON, COLOR_KAKAO, kakao_search_manga -from ..utils import discord_embed_result, description_parser, discord_translate_deepl - -import logging -logger = logging.getLogger(__name__) - -async def discord_kakao_embeds(self, entered_title): - results = await kakao_search_manga(entered_title) - if not results: - logger.debug(f'No results for: {str(entered_title)}', exc_info=True) - return None - embed_data, data = results - - embeds = [] - idx_total = len(embed_data) - for idx, em in enumerate(embed_data): - romanized_title = em.get('romanized_title') - translated_title = await discord_translate_deepl(self, em.get('title'), "KO", "EN") - if romanized_title: - em['title'] = em['title'] + f' ({str(romanized_title)})' - em['names'].append(str(romanized_title)) - if translated_title: - em['names'] = [str(translated_title).title()] - translated_description = await discord_translate_deepl(self, em.get('description'), "KO", "EN") - translated_embed_description = description_parser(translated_description, limit_lines=False, flatten_lines=True) - if translated_embed_description: - em['embed_description'] = translated_embed_description - embed = discord_embed_result(em, COLOR_KAKAO, NAME_KAKAO_WEBTOON, idx, idx_total) - embed.insert_field_at(1, name="Creators", value=em.get('authors'), inline=True) - embeds.append({"embed": embed}) - return embeds - -def discord_kakao_generate_image_banner(files_list: List, embed, em_result, idx: int, image: io.BytesIO): - files = files_list - file_obj = discord.File(fp=em_result.get("image", None), filename="kakao-webtoon-"+str(idx+1)+".webp") - files.append(file_obj) - embed.set_image(url="attachment://kakao-webtoon-"+str(idx+1)+".webp") - return (files_list, embed) diff --git a/coffeeani/info.json b/coffeeani/info.json index 612fdfe..c6105b5 100644 --- a/coffeeani/info.json +++ b/coffeeani/info.json @@ -3,11 +3,11 @@ "name" : "coffeeani", "disabled" : false, "hidden" : false, - "requirements" : ["aiohttp", "korean_romanizer"], - "description": "Search anime, manga, manhwa/manhua, light novels, and characters. See series info, status, episodes/chapters, and tags.\n\nSearches Anilist, MangaDex, Batoto, and Kakao Webtoon.\n\nForked from anisearch by Jintaku and Wyn.", + "requirements" : ["aiohttp"], + "description": "Search anime, manga, manhwa/manhua, light novels, and characters. See series info, status, episodes/chapters, and tags.\n\nSearches Anilist, MangaDex, and Batoto.\n\nForked from anisearch by Jintaku and Wyn.", "short": "Search for anime, manga, manhwa/manhua, light novels, and characters. See series info, status, episodes/chapters, and tags.", "install_msg" : "Thanks for installing, I hope you enjoy :) To stay up to date with breaking changes, you might want to join my Support Discord. To find documentation, Discord, and more, drop by my site at https://coffeebank.github.io/coffee-cogs/coffeeani/", - "tags" : ["anime", "manga", "anilist", "myanimelist", "漫画", "만화", "漫画", "mangadex", "batoto", "kakao", "webtoons", "anisearch"], + "tags" : ["anime", "manga", "anilist", "myanimelist", "漫画", "만화", "漫画", "mangadex", "batoto", "webtoons", "anisearch"], "permissions": ["add_reactions", "embed_links"], "end_user_data_statement": "This cog does not persistently store data or metadata about users.", "min_bot_version": "3.5.0" diff --git a/coffeeani/tests/test_sources.py b/coffeeani/tests/test_sources.py index b40ca6c..2685e49 100644 --- a/coffeeani/tests/test_sources.py +++ b/coffeeani/tests/test_sources.py @@ -2,7 +2,7 @@ from unittest.mock import patch, Mock import asyncio -from coffeeani_utils.sources import anilist, batoto, kakao, mangadex +from coffeeani_utils.sources import anilist, batoto, mangadex LOREM_IPSUM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."