1
0
Fork 0
mirror of https://github.com/myned/modufur.git synced 2024-11-01 21:02:38 +00:00
modufur/commands/booru.py

142 lines
4.8 KiB
Python
Raw Normal View History

2022-02-21 07:10:57 +00:00
import urlextract
import hikari
import lightbulb
import pysaucenao
from tools import components, scraper
2022-02-21 20:53:53 +00:00
plugin = lightbulb.Plugin("booru")
2022-02-21 07:10:57 +00:00
extractor = urlextract.URLExtract()
@plugin.command
2022-02-21 20:53:53 +00:00
# @lightbulb.option('attachment', 'Attachment(s) to reverse')
@lightbulb.option("url", "URL(s) to reverse, separated by space")
@lightbulb.command("reverse", "Reverse image search using SauceNAO & Kheina", ephemeral=True)
2022-02-21 07:10:57 +00:00
@lightbulb.implements(lightbulb.SlashCommand, lightbulb.MessageCommand)
async def reverse(context):
match context:
case lightbulb.SlashContext():
2022-02-21 20:53:53 +00:00
urls = extractor.find_urls(context.options.url or "", only_unique=True, with_schema_only=True)
2022-02-21 07:10:57 +00:00
if not urls:
2022-03-04 05:57:35 +00:00
await context.respond("***Invalid URL(s)***")
2022-02-21 07:10:57 +00:00
return
await _reverse(context, urls)
case lightbulb.MessageContext():
2022-02-21 20:53:53 +00:00
urls = extractor.find_urls(context.options.target.content or "", only_unique=True, with_schema_only=True)
2022-02-21 07:10:57 +00:00
urls += [attachment.url for attachment in context.options.target.attachments if attachment.url not in urls]
if not urls:
2022-03-04 05:57:35 +00:00
await context.respond("***No images found***")
2022-02-21 07:10:57 +00:00
return
selector = None
if len(urls) > 1:
selector = components.Selector(
2022-02-21 20:53:53 +00:00
pages=[
f"**Select potential images to search: `{urls.index(url) + 1}/{len(urls)}`**\n{url}"
for url in urls
],
2022-02-21 19:41:01 +00:00
buttons=[components.Back(), components.Forward(), components.Select(), components.Confirm()],
2022-02-21 20:53:53 +00:00
urls=urls,
2022-02-21 19:41:01 +00:00
)
2022-02-21 07:10:57 +00:00
await selector.send(context.interaction, ephemeral=True)
await selector.wait()
if selector.timed_out:
2022-03-04 05:57:35 +00:00
await context.interaction.edit_initial_response("***Timed out***", components=None)
2022-02-21 07:10:57 +00:00
return
urls = selector.selected
await _reverse(context, urls, selector=selector)
2022-02-21 20:53:53 +00:00
2022-03-04 05:59:46 +00:00
# Listener for reverse exceptions
2022-02-21 07:10:57 +00:00
@reverse.set_error_handler()
async def on_reverse_error(event):
error = None
match event.exception.__cause__:
case pysaucenao.ShortLimitReachedException():
2022-03-04 05:57:35 +00:00
error = "***API limit reached. Please try again in a minute***"
2022-02-21 07:10:57 +00:00
case pysaucenao.DailyLimitReachedException():
2022-03-04 05:57:35 +00:00
error = "***Daily API limit reached. Please try again tomorrow***"
2022-02-21 07:10:57 +00:00
case pysaucenao.FileSizeLimitException() as url:
2022-03-04 05:57:35 +00:00
error = f"***Image file size too large***\n{url}"
2022-02-21 07:10:57 +00:00
case pysaucenao.ImageSizeException() as url:
2022-03-04 05:57:35 +00:00
error = f"***Image resolution too small***\n{url}"
2022-02-21 07:10:57 +00:00
case pysaucenao.InvalidImageException() as url:
2022-03-04 05:57:35 +00:00
error = f"***Invalid image***\n{url}"
2022-02-21 07:10:57 +00:00
case pysaucenao.UnknownStatusCodeException():
2022-03-04 05:57:35 +00:00
error = "***An unknown SauceNAO error has occurred. The service may be down***"
2022-02-21 07:10:57 +00:00
if error:
try:
2022-03-04 06:03:46 +00:00
await event.context.respond(error, flags=hikari.MessageFlag.EPHEMERAL)
except:
await event.context.interaction.edit_initial_response(error, components=None)
2022-02-21 07:10:57 +00:00
return True
2022-02-21 20:53:53 +00:00
2022-03-04 05:59:46 +00:00
# Reverse images and respond
2022-02-21 07:10:57 +00:00
async def _reverse(context, urls, *, selector=None):
if not selector:
await context.respond(hikari.ResponseType.DEFERRED_MESSAGE_CREATE)
matches = await scraper.reverse(urls)
if not matches:
if selector:
2022-03-04 05:57:35 +00:00
await context.interaction.edit_initial_response("***No matches found***", components=None)
2022-02-21 07:10:57 +00:00
else:
2022-03-04 05:57:35 +00:00
await context.respond("***No matches found***")
2022-02-21 07:10:57 +00:00
return
2022-02-21 20:53:53 +00:00
pages = [
(
hikari.Embed(
2022-02-22 23:22:50 +00:00
title=match["artist"],
url=match["url"],
color=context.get_guild().get_my_member().get_top_role().color if context.get_guild() else "#1a1a1a",
2022-02-21 20:53:53 +00:00
)
2022-02-23 23:47:12 +00:00
.set_author(name=f"{match['similarity']}% Match")
2022-02-21 20:53:53 +00:00
.set_image(match["thumbnail"])
.set_footer(match["source"])
)
if match
2022-03-04 05:57:35 +00:00
else f"***No match found***\n{urls[index]}"
2022-02-21 20:53:53 +00:00
for index, match in enumerate(matches)
]
2022-02-21 07:10:57 +00:00
if len(pages) > 1:
2022-03-04 06:03:14 +00:00
selector = components.Selector(
pages=pages,
buttons=[components.Back(), components.Forward()],
timeout=600,
)
2022-02-21 07:10:57 +00:00
await selector.send_edit(context.interaction)
else:
if selector:
2022-03-07 04:19:22 +00:00
if isinstance(pages[0], hikari.Embed):
await context.interaction.edit_initial_response(content=None, embed=pages[0], components=None)
else:
await context.interaction.edit_initial_response(pages[0], components=None)
2022-02-21 07:10:57 +00:00
else:
await context.respond(pages[0])
2022-02-21 20:53:53 +00:00
2022-02-21 07:10:57 +00:00
def load(bot):
bot.add_plugin(plugin)
2022-02-21 20:53:53 +00:00
2022-02-21 07:10:57 +00:00
def unload(bot):
bot.remove_plugin(plugin)