-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
dont update , last version works fine
- Loading branch information
Showing
7 changed files
with
616 additions
and
155 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,11 @@ | ||
from discord.utils import maybe_coroutine | ||
from redbot.core.errors import CogLoadError | ||
|
||
from .ocr import OCR | ||
|
||
__red_end_user_data_statement__ = "This cog does not persistently store any data or metadata about users." | ||
|
||
|
||
async def setup(bot): | ||
await maybe_coroutine(bot.add_cog, OCR()) | ||
if not getattr(bot, "session", None): | ||
raise CogLoadError("This cog requires bot.session attr to be set.") | ||
await bot.add_cog(OCR(bot)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,63 +1,75 @@ | ||
# This is a slightly modified version of converter originally made by TrustyJAID for his NotSoBot cog | ||
# Attribution at: https://github.com/TrustyJAID/Trusty-cogs/blob/master/notsobot/converter.py | ||
# I have included original LICENSE notice bundled with this cog to adhere to the license terms. | ||
# I am forever indebted to and wholeheartedly thank TrustyJAID for providing this converter. | ||
# originally made by TrustyJAID for his NotSoBot cog | ||
# https://github.com/TrustyJAID/Trusty-cogs/blob/master/notsobot/converter.py | ||
import re | ||
|
||
from typing import Pattern, List | ||
|
||
import discord | ||
from redbot.core import commands | ||
from redbot.core.commands import BadArgument, Context, Converter | ||
|
||
IMAGE_LINKS: re.Pattern[str] = re.compile( | ||
r"(https?:\/\/[^\"\'\s]*\.(?:png|jpg|jpeg|webp)(\?size=[0-9]{1,4})?)", flags=re.I | ||
) | ||
|
||
IMAGE_LINKS: Pattern = re.compile( | ||
r"(https?:\/\/[^\"\'\s]*\.(?:png|jpg|jpeg|webp|gif)(\?size=[0-9]*)?)", flags=re.I | ||
DISCORD_CDN: tuple[str, str] = ( | ||
"https://cdn.discordapp.com/attachments", | ||
"https://media.discordapp.net/attachments", | ||
) | ||
|
||
|
||
class ImageFinder(commands.Converter): | ||
class ImageFinder(Converter): | ||
""" | ||
This is a class to convert NotSoBot's image searching | ||
capabilities into a more general converter class | ||
""" | ||
|
||
async def convert(self, ctx: commands.Context, argument: str) -> List[str]: | ||
attachments = ctx.message.attachments | ||
matches = IMAGE_LINKS.finditer(argument) | ||
urls = [] | ||
if matches: | ||
async def convert(self, ctx: Context, argument: str) -> list[str]: | ||
urls: list[str] = [] | ||
if argument.startswith(DISCORD_CDN): | ||
urls.append(argument.split()[0]) | ||
if matches := IMAGE_LINKS.finditer(argument): | ||
urls.extend(match.group(1) for match in matches) | ||
if attachments: | ||
urls.extend( | ||
match.group(1) | ||
for attachment in attachments | ||
if (match := IMAGE_LINKS.match(attachment.url)) | ||
) | ||
|
||
if attachments := ctx.message.attachments: | ||
urls.extend(img.url for img in attachments if img.content_type and img.content_type.startswith("image")) | ||
if (e := ctx.message.embeds) and e[0].image: | ||
urls.append(e[0].image.url) | ||
if not urls: | ||
if ctx.message.reference and (message := ctx.message.reference.resolved): | ||
urls = await find_images_in_replies(message) | ||
else: | ||
urls = await search_for_images(ctx) | ||
if not urls: | ||
raise BadArgument("No images or image links found in chat bro 🥸") | ||
return urls | ||
|
||
async def find_images_in_replies(self, reference: discord.Message) -> List[str]: | ||
urls = [] | ||
if match := IMAGE_LINKS.search(reference.content): | ||
urls.append(match.group(1)) | ||
if reference.attachments: | ||
if match := IMAGE_LINKS.match(reference.attachments[0].url): | ||
urls.append(match.group(1)) | ||
if reference.embeds and reference.embeds[0].image: | ||
urls.append(reference.embeds[0].image.url) | ||
return urls | ||
|
||
async def search_for_images(self, ctx: commands.Context) -> List[str]: | ||
urls = [] | ||
async for message in ctx.channel.history(limit=20): | ||
if message.embeds and message.embeds[0].image: | ||
urls.append(message.embeds[0].image.url) | ||
if message.attachments: | ||
urls.extend( | ||
match.group(1) | ||
for attachment in message.attachments | ||
if (match := IMAGE_LINKS.match(attachment.url)) | ||
) | ||
|
||
if match := IMAGE_LINKS.search(message.content): | ||
urls.append(match.group(1)) | ||
return urls | ||
async def find_images_in_replies(reference: discord.DeletedReferencedMessage | discord.Message | None) -> list[str]: | ||
if not reference or not isinstance(reference, discord.Message): | ||
return [] | ||
urls = [] | ||
argument = reference.system_content | ||
if argument.startswith(DISCORD_CDN): | ||
urls.append(argument.split()[0]) | ||
if match := IMAGE_LINKS.search(argument): | ||
urls.append(match.group(1)) | ||
if reference.attachments: | ||
urls.extend( | ||
img.url for img in reference.attachments if img.content_type and img.content_type.startswith("image") | ||
) | ||
if reference.embeds and reference.embeds[0].image: | ||
urls.append(reference.embeds[0].image.url) | ||
return urls | ||
|
||
|
||
async def search_for_images(ctx: Context) -> list[str]: | ||
urls = [] | ||
async for message in ctx.channel.history(limit=20): | ||
if message.embeds and message.embeds[0].image: | ||
urls.append(message.embeds[0].image.url) | ||
if message.attachments: | ||
urls.extend( | ||
img.url for img in message.attachments if img.content_type and img.content_type.startswith("image") | ||
) | ||
if message.system_content.startswith(DISCORD_CDN): | ||
urls.append(message.system_content.split()[0]) | ||
if match := IMAGE_LINKS.search(message.system_content): | ||
urls.append(match.group(1)) | ||
return urls |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
from typing import Mapping | ||
|
||
|
||
ISO639_MAP: Mapping[str, str] = { | ||
"af": "Afrikaans", | ||
"ak": "Twi (Akan)", | ||
"am": "Amharic", | ||
"ar": "Arabic", | ||
"as": "Assamese", | ||
"ay": "Aymara", | ||
"az": "Azerbaijani", | ||
"be": "Belarusian", | ||
"bg": "Bulgarian", | ||
"bho": "Bhojpuri", | ||
"bm": "Bambara", | ||
"bn": "Bengali", | ||
"bs": "Bosnian", | ||
"ca": "Catalan", | ||
"ceb": "Cebuano", | ||
"ckb": "Kurdish (Sorani)", | ||
"co": "Corsican", | ||
"cs": "Czech", | ||
"cy": "Welsh", | ||
"da": "Danish", | ||
"de": "German", | ||
"doi": "Dogri", | ||
"dv": "Divehi", | ||
"ee": "Ewe", | ||
"el": "Greek", | ||
"en": "English", | ||
"eo": "Esperanto", | ||
"es": "Spanish", | ||
"et": "Estonian", | ||
"eu": "Basque", | ||
"fa": "Persian", | ||
"fi": "Finnish", | ||
"fo": "Faroese", | ||
"fr": "French", | ||
"fy": "Frisian", | ||
"ga": "Irish Gaelic", | ||
"gd": "Scottish Gaelic", | ||
"gl": "Galician", | ||
"gn": "Guarani", | ||
"gom": "Konkani", | ||
"gu": "Gujarati", | ||
"ha": "Hausa", | ||
"haw": "Hawaiian", | ||
"he": "Hebrew", | ||
"hi": "Hindi", | ||
"hmn": "Hmong", | ||
"hr": "Croatian", | ||
"ht": "Haitian Creole", | ||
"hu": "Hungarian", | ||
"hy": "Armenian", | ||
"id": "Indonesian", | ||
"ig": "Igbo", | ||
"ilo": "Ilocano", | ||
"is": "Icelandic", | ||
"it": "Italian", | ||
"iw": "Hebrew", | ||
"ja": "Japanese", | ||
"jv": "Javanese", | ||
"jw": "Javanese", | ||
"ka": "Georgian", | ||
"kk": "Kazakh", | ||
"kl": "Kalaallisut", | ||
"km": "Khmer", | ||
"kn": "Kannada", | ||
"ko": "Korean", | ||
"kri": "Krio", | ||
"ku": "Kurdish (Kurmanji)", | ||
"ky": "Kyrgyz", | ||
"la": "Latin", | ||
"lb": "Luxembourgish", | ||
"lg": "Luganda", | ||
"ln": "Lingala", | ||
"lo": "Lao", | ||
"lt": "Lithuanian", | ||
"lus": "Mizo", | ||
"lv": "Latvian", | ||
"mai": "Maithili", | ||
"mg": "Malagasy", | ||
"mi": "Māori", | ||
"mk": "Macedonian", | ||
"ml": "Malayalam", | ||
"mn": "Mongolian", | ||
"mni-Mtei": "Meitei (Manipuri)", | ||
"mr": "Marathi", | ||
"ms": "Malay", | ||
"mt": "Maltese", | ||
"my": "Burmese", | ||
"ne": "Nepali", | ||
"nl": "Dutch", | ||
"no": "Norwegian", | ||
"nso": "Sepedi (Northern Sotho)", | ||
"ny": "Chichewa", | ||
"om": "Oromo", | ||
"or": "Odia (Oriya)", | ||
"pa": "Punjabi", | ||
"pl": "Polish", | ||
"ps": "Pashto", | ||
"pt": "Portuguese", | ||
"qu": "Quechua", | ||
"ro": "Romanian", | ||
"ru": "Russian", | ||
"rw": "Kinyarwanda", | ||
"sa": "Sanskrit", | ||
"sd": "Sindhi", | ||
"si": "Sinhalese", | ||
"sk": "Slovak", | ||
"sl": "Slovenian", | ||
"sm": "Samoan", | ||
"sn": "Shona", | ||
"so": "Somali", | ||
"sq": "Albanian", | ||
"sr": "Serbian", | ||
"st": "Sesotho", | ||
"su": "Sundanese", | ||
"sv": "Swedish", | ||
"sw": "Swahili", | ||
"ta": "Tamil", | ||
"te": "Telugu", | ||
"tg": "Tajik", | ||
"th": "Thai", | ||
"ti": "Tigrinya", | ||
"tk": "Turkmen", | ||
"tl": "Filipino", | ||
"tr": "Turkish", | ||
"ts": "Tsonga", | ||
"tt": "Tatar", | ||
"ug": "Uyghur", | ||
"uk": "Ukrainian", | ||
"ur": "Urdu", | ||
"uz": "Uzbek", | ||
"vi": "Vietnamese", | ||
"xh": "Xhosa", | ||
"yi": "Yiddish", | ||
"yo": "Yoruba", | ||
"zu": "Zulu", | ||
"zh": "Chinese Simplified", | ||
"zh-cn": "Chinese Simplified", | ||
"zh-tw": "Chinese Traditional", | ||
"zh-CN": "Chinese Simplified", | ||
"zh-TW": "Chinese Traditional", | ||
"auto": "Autodetect", | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
from dataclasses import dataclass, field | ||
from typing import List | ||
|
||
|
||
@dataclass(slots=True) | ||
class TextAnnotation: | ||
locale: str = "en" | ||
description: str = "" | ||
|
||
|
||
@dataclass(slots=True) | ||
class DetectedLanguage: | ||
languageCode: str | ||
confidence: float | ||
|
||
|
||
@dataclass(slots=True) | ||
class Property: | ||
detectedLanguages: List[DetectedLanguage] | ||
|
||
|
||
@dataclass(slots=True) | ||
class Page: | ||
width: int | ||
height: int | ||
confidence: float | ||
property: Property | None = None | ||
|
||
|
||
@dataclass(slots=True) | ||
class FullTextAnnotation: | ||
pages: List[Page] = field(default_factory=list) | ||
text: str = "" | ||
|
||
@property | ||
def language_code(self) -> str: | ||
if not self.pages: | ||
return "auto" | ||
if not self.pages[0].property: | ||
return "auto" | ||
if not self.pages[0].property.detectedLanguages: | ||
return "auto" | ||
return self.pages[0].property.detectedLanguages[0].languageCode | ||
|
||
|
||
@dataclass(slots=True) | ||
class VisionError: | ||
code: int | ||
message: str | ||
status: str | None | ||
|
||
def __str__(self) -> str: | ||
return f"Error code: {self.code} ({self.message})" | ||
|
||
|
||
@dataclass(slots=True) | ||
class VisionPayload: | ||
fullTextAnnotation: FullTextAnnotation | None | ||
error: VisionError | None | ||
textAnnotations: List[TextAnnotation] = field(default_factory=list) | ||
|
||
@property | ||
def text_value(self) -> str | None: | ||
if not self.fullTextAnnotation: | ||
if self.error: | ||
return self.error.message | ||
return None | ||
return self.fullTextAnnotation.text or self.textAnnotations[0].description |
Oops, something went wrong.