2021-08-07 07:56:48 +00:00
|
|
|
import re
|
2021-07-26 12:43:51 +00:00
|
|
|
import uuid
|
2021-11-12 14:25:53 +00:00
|
|
|
from os.path import abspath
|
2022-01-20 12:13:03 +00:00
|
|
|
from typing import List
|
|
|
|
from urllib import parse
|
2021-11-12 14:25:53 +00:00
|
|
|
|
2021-08-25 14:32:37 +00:00
|
|
|
import aiohttp
|
2021-07-26 12:43:51 +00:00
|
|
|
import filetype
|
2021-10-12 15:02:36 +00:00
|
|
|
from PIL import Image as PImage
|
2021-12-31 14:44:34 +00:00
|
|
|
from tenacity import retry, stop_after_attempt
|
2021-11-12 14:25:53 +00:00
|
|
|
|
2023-04-05 04:33:29 +00:00
|
|
|
from config import CachePath, Config
|
2023-02-05 14:33:33 +00:00
|
|
|
from core.types.message.internal import Plain as P, Image as I, Voice as V, Embed as E, EmbedField as EF, \
|
|
|
|
Url as U, ErrorMessage as EMsg
|
2021-07-26 12:43:51 +00:00
|
|
|
|
2023-03-05 11:15:44 +00:00
|
|
|
from core.utils.i18n import Locale
|
|
|
|
|
2021-07-26 12:43:51 +00:00
|
|
|
|
2023-02-05 14:33:33 +00:00
|
|
|
class Plain(P):
|
2021-07-26 12:43:51 +00:00
|
|
|
def __init__(self,
|
2022-01-07 15:02:57 +00:00
|
|
|
text, *texts):
|
|
|
|
self.text = str(text)
|
|
|
|
for t in texts:
|
|
|
|
self.text += str(t)
|
2021-07-26 12:43:51 +00:00
|
|
|
|
2022-01-17 13:28:49 +00:00
|
|
|
def __str__(self):
|
|
|
|
return self.text
|
|
|
|
|
2022-06-26 06:06:26 +00:00
|
|
|
def __repr__(self):
|
|
|
|
return f'Plain(text="{self.text}")'
|
|
|
|
|
2022-01-17 13:28:49 +00:00
|
|
|
|
2023-02-05 14:33:33 +00:00
|
|
|
class Url(U):
|
2022-01-17 15:30:38 +00:00
|
|
|
mm = False
|
2022-06-12 07:07:53 +00:00
|
|
|
disable_mm = False
|
2022-01-17 13:28:49 +00:00
|
|
|
|
2022-01-29 11:25:23 +00:00
|
|
|
def __init__(self, url: str, use_mm: bool = False, disable_mm: bool = False):
|
2022-01-17 13:28:49 +00:00
|
|
|
self.url = url
|
2022-06-12 07:07:53 +00:00
|
|
|
if (Url.mm and not disable_mm) or (use_mm and not Url.disable_mm):
|
2022-06-30 06:35:17 +00:00
|
|
|
mm_url = f'https://mm.teahouse.team/?source=akaribot&rot13=%s'
|
2022-01-17 15:30:38 +00:00
|
|
|
rot13 = str.maketrans(
|
|
|
|
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
|
|
|
"nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM")
|
|
|
|
self.url = mm_url % parse.quote(parse.unquote(url).translate(rot13))
|
2022-01-17 13:28:49 +00:00
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return self.url
|
|
|
|
|
2022-06-26 06:06:26 +00:00
|
|
|
def __repr__(self):
|
|
|
|
return f'Url(url="{self.url}")'
|
|
|
|
|
2021-07-26 12:43:51 +00:00
|
|
|
|
2023-02-05 14:33:33 +00:00
|
|
|
class ErrorMessage(EMsg):
|
2023-03-05 11:15:44 +00:00
|
|
|
def __init__(self, error_message, locale=None):
|
|
|
|
self.error_message = error_message
|
|
|
|
if locale:
|
|
|
|
locale = Locale(locale)
|
|
|
|
if locale_str := re.findall(r'\{(.*)}', error_message):
|
|
|
|
for l in locale_str:
|
|
|
|
error_message = error_message.replace(f'{{{l}}}', locale.t(l))
|
|
|
|
self.error_message = locale.t('error.prompt', error_msg=error_message) + \
|
2023-04-05 04:33:29 +00:00
|
|
|
str(Url(Config('bug_report_url')))
|
2022-07-03 06:05:40 +00:00
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return self.error_message
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
return self.error_message
|
|
|
|
|
|
|
|
|
2023-02-05 14:33:33 +00:00
|
|
|
class Image(I):
|
2021-07-26 12:43:51 +00:00
|
|
|
def __init__(self,
|
2021-12-31 14:44:34 +00:00
|
|
|
path, headers=None):
|
2021-07-31 14:26:41 +00:00
|
|
|
self.need_get = False
|
|
|
|
self.path = path
|
2021-12-31 14:44:34 +00:00
|
|
|
self.headers = headers
|
2021-10-12 15:02:36 +00:00
|
|
|
if isinstance(path, PImage.Image):
|
2023-02-03 15:48:29 +00:00
|
|
|
save = f'{CachePath}{str(uuid.uuid4())}.png'
|
|
|
|
path.convert('RGBA').save(save)
|
2021-12-31 14:44:34 +00:00
|
|
|
self.path = save
|
2021-10-12 15:02:36 +00:00
|
|
|
elif re.match('^https?://.*', path):
|
2021-07-31 14:26:41 +00:00
|
|
|
self.need_get = True
|
|
|
|
|
|
|
|
async def get(self):
|
|
|
|
if self.need_get:
|
2021-12-31 14:44:34 +00:00
|
|
|
return abspath(await self.get_image())
|
2021-10-12 15:02:36 +00:00
|
|
|
return abspath(self.path)
|
2021-07-26 12:43:51 +00:00
|
|
|
|
2021-12-31 14:44:34 +00:00
|
|
|
@retry(stop=stop_after_attempt(3))
|
|
|
|
async def get_image(self):
|
|
|
|
url = self.path
|
2022-01-07 15:02:57 +00:00
|
|
|
async with aiohttp.ClientSession() as session:
|
2021-07-31 14:26:41 +00:00
|
|
|
async with session.get(url, timeout=aiohttp.ClientTimeout(total=20)) as req:
|
|
|
|
raw = await req.read()
|
|
|
|
ft = filetype.match(raw).extension
|
|
|
|
img_path = f'{CachePath}{str(uuid.uuid4())}.{ft}'
|
|
|
|
with open(img_path, 'wb+') as image_cache:
|
|
|
|
image_cache.write(raw)
|
|
|
|
return img_path
|
2021-07-28 18:51:24 +00:00
|
|
|
|
2022-06-26 06:06:26 +00:00
|
|
|
def __str__(self):
|
|
|
|
return self.path
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
return f'Image(path="{self.path}", headers={self.headers})'
|
|
|
|
|
2021-07-28 18:51:24 +00:00
|
|
|
|
2023-02-05 14:33:33 +00:00
|
|
|
class Voice(V):
|
2021-07-28 18:51:24 +00:00
|
|
|
def __init__(self,
|
|
|
|
path=None):
|
|
|
|
self.path = path
|
2021-08-23 12:44:31 +00:00
|
|
|
|
2022-06-26 06:06:26 +00:00
|
|
|
def __str__(self):
|
|
|
|
return self.path
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
return f'Voice(path={self.path})'
|
|
|
|
|
2022-01-17 14:54:59 +00:00
|
|
|
|
2023-02-05 14:33:33 +00:00
|
|
|
class EmbedField(EF):
|
2021-12-25 14:01:33 +00:00
|
|
|
def __init__(self,
|
|
|
|
name: str = None,
|
|
|
|
value: str = None,
|
|
|
|
inline: bool = False):
|
|
|
|
self.name = name
|
|
|
|
self.value = value
|
|
|
|
self.inline = inline
|
|
|
|
|
2022-06-26 06:06:26 +00:00
|
|
|
def __str__(self):
|
|
|
|
return f'{self.name}: {self.value}'
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
return f'EmbedField(name="{self.name}", value="{self.value}", inline={self.inline})'
|
|
|
|
|
2021-12-25 14:01:33 +00:00
|
|
|
|
2023-02-05 14:33:33 +00:00
|
|
|
class Embed(E):
|
2021-12-25 14:01:33 +00:00
|
|
|
def __init__(self,
|
|
|
|
title: str = None,
|
|
|
|
description: str = None,
|
|
|
|
url: str = None,
|
|
|
|
timestamp: float = None,
|
|
|
|
color: int = None,
|
2022-01-10 14:32:47 +00:00
|
|
|
image: Image = None,
|
|
|
|
thumbnail: Image = None,
|
2021-12-25 14:01:33 +00:00
|
|
|
author: str = None,
|
|
|
|
footer: str = None,
|
|
|
|
fields: List[EmbedField] = None):
|
|
|
|
self.title = title
|
|
|
|
self.description = description
|
|
|
|
self.url = url
|
|
|
|
self.timestamp = timestamp
|
|
|
|
self.color = color
|
2022-01-10 14:32:47 +00:00
|
|
|
self.image = image
|
|
|
|
self.thumbnail = thumbnail
|
2021-12-25 14:01:33 +00:00
|
|
|
self.author = author
|
|
|
|
self.footer = footer
|
|
|
|
self.fields = fields
|
|
|
|
|
|
|
|
def to_msgchain(self):
|
|
|
|
text_lst = []
|
|
|
|
if self.title is not None:
|
|
|
|
text_lst.append(self.title)
|
|
|
|
if self.description is not None:
|
|
|
|
text_lst.append(self.description)
|
|
|
|
if self.url is not None:
|
|
|
|
text_lst.append(self.url)
|
|
|
|
if self.fields is not None:
|
|
|
|
for f in self.fields:
|
|
|
|
if f.inline:
|
|
|
|
text_lst.append(f"{f.name}: {f.value}")
|
|
|
|
else:
|
|
|
|
text_lst.append(f"{f.name}:\n{f.value}")
|
|
|
|
if self.author is not None:
|
|
|
|
text_lst.append("作者:" + self.author)
|
|
|
|
if self.footer is not None:
|
|
|
|
text_lst.append(self.footer)
|
|
|
|
msgchain = []
|
|
|
|
if text_lst:
|
|
|
|
msgchain.append(Plain('\n'.join(text_lst)))
|
2022-01-10 14:32:47 +00:00
|
|
|
if self.image is not None:
|
|
|
|
msgchain.append(self.image)
|
2021-12-25 14:01:33 +00:00
|
|
|
return msgchain
|
|
|
|
|
2022-06-26 06:06:26 +00:00
|
|
|
def __str__(self):
|
|
|
|
return str(self.to_msgchain())
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
return f'Embed(title="{self.title}", description="{self.description}", url="{self.url}", ' \
|
|
|
|
f'timestamp={self.timestamp}, color={self.color}, image={self.image.__repr__()}, ' \
|
|
|
|
f'thumbnail={self.thumbnail.__repr__()}, author="{self.author}", footer="{self.footer}", ' \
|
|
|
|
f'fields={self.fields})'
|
|
|
|
|
2021-12-25 14:01:33 +00:00
|
|
|
|
2022-07-03 06:05:40 +00:00
|
|
|
__all__ = ["Plain", "Image", "Voice", "Embed", "EmbedField", "Url", "ErrorMessage"]
|