-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathimage_source.py
148 lines (111 loc) · 3.87 KB
/
image_source.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import hashlib
from pathlib import Path
import anyio
import emoji
from nonebot.compat import PYDANTIC_V2
from pydantic import BaseModel
from strenum import StrEnum
from .utils import download_url
class ImageSource(BaseModel):
def get_url(self) -> str:
raise NotImplementedError
async def get_image(self) -> bytes:
raise NotImplementedError
class ImageUrl(ImageSource):
url: str
def get_url(self) -> str:
return self.url
async def get_image(self) -> bytes:
return await download_url(self.url)
class EmojiStyle(StrEnum):
Apple = "apple"
Google = "google"
Microsoft = "microsoft"
Samsung = "samsung"
WhatsApp = "whatsapp"
Twitter = "twitter"
Facebook = "facebook"
Messenger = "messenger"
JoyPixels = "joypixels"
OpenMoji = "openmoji"
EmojiDex = "emojidex"
LG = "lg"
HTC = "htc"
Mozilla = "mozilla"
class Emoji(ImageSource):
data: str
if PYDANTIC_V2:
from pydantic import field_validator
@field_validator("data")
def check_emoji(cls, value: str) -> str:
if not emoji.is_emoji(value):
raise ValueError("Not a emoji")
return value
else:
from pydantic import validator
@validator("data")
def check_emoji(cls, value: str) -> str:
if not emoji.is_emoji(value):
raise ValueError("Not a emoji")
return value
def get_url(self, style: EmojiStyle = EmojiStyle.Apple) -> str:
return f"https://emojicdn.elk.sh/{self.data}?style={style}"
async def get_image(self, style: EmojiStyle = EmojiStyle.Apple) -> bytes:
url = self.get_url(style)
return await download_url(url)
class QQAvatar(ImageSource):
qq: int
def get_url(self, size: int = 640) -> str:
return f"http://q1.qlogo.cn/g?b=qq&nk={self.qq}&s={size}"
async def get_image(self) -> bytes:
url = self.get_url(size=640)
data = await download_url(url)
if hashlib.md5(data).hexdigest() == "acef72340ac0e914090bd35799f5594e":
url = self.get_url(size=100)
data = await download_url(url)
return data
class QQAvatarOpenId(ImageSource):
appid: str
user_openid: str
def get_url(self) -> str:
return f"https://q.qlogo.cn/qqapp/{self.appid}/{self.user_openid}/100"
async def get_image(self) -> bytes:
url = self.get_url()
return await download_url(url)
class TelegramFile(ImageSource):
token: str
file_path: str
def get_url(self, api_server: str = "https://api.telegram.org/") -> str:
if Path(self.file_path).exists():
return f"file://{self.file_path}"
return f"{api_server}file/bot{self.token}/{self.file_path}"
async def get_image(self, api_server: str = "https://api.telegram.org/") -> bytes:
if Path(self.file_path).exists():
return await anyio.Path(self.file_path).read_bytes()
url = self.get_url(api_server)
return await download_url(url)
class DiscordImageFormat(StrEnum):
JPEG = "jpeg"
PNG = "png"
WebP = "webp"
GIF = "gif"
Lottie = "json"
class DiscordUserAvatar(ImageSource):
# https://discord.com/developers/docs/reference#image-formatting
user_id: int
image_hash: str
def get_url(
self,
base_url: str = "https://cdn.discordapp.com/",
image_format: DiscordImageFormat = DiscordImageFormat.PNG,
image_size: int = 1024,
) -> str:
return f"{base_url}avatars/{self.user_id}/{self.image_hash}.{image_format}?size={image_size}"
async def get_image(
self,
base_url: str = "https://cdn.discordapp.com/",
image_format: DiscordImageFormat = DiscordImageFormat.PNG,
image_size: int = 1024,
) -> bytes:
url = self.get_url(base_url, image_format, image_size)
return await download_url(url)