0
# Emoji Sources
1
2
Comprehensive system for fetching emoji images from various providers. The source system supports multiple emoji styles (Twitter, Apple, Microsoft, etc.), Discord custom emojis, HTTP optimization with requests library, and extensibility through custom source implementations.
3
4
## Capabilities
5
6
### Base Source Interface
7
8
Abstract base class defining the interface for all emoji sources, with methods for retrieving both Unicode emojis and Discord custom emojis.
9
10
```python { .api }
11
class BaseSource(ABC):
12
"""Base class for emoji image sources."""
13
14
@abstractmethod
15
def get_emoji(self, emoji: str, /) -> Optional[BytesIO]:
16
"""
17
Retrieves emoji image as BytesIO stream.
18
19
Parameters:
20
- emoji: str - Unicode emoji to retrieve
21
22
Returns:
23
- BytesIO - Image stream, or None if not found
24
"""
25
26
@abstractmethod
27
def get_discord_emoji(self, id: int, /) -> Optional[BytesIO]:
28
"""
29
Retrieves Discord emoji image as BytesIO stream.
30
31
Parameters:
32
- id: int - Discord emoji snowflake ID
33
34
Returns:
35
- BytesIO - Image stream, or None if not found
36
"""
37
```
38
39
### HTTP-Based Source
40
41
Base class for sources that fetch emojis via HTTP, with automatic fallback from requests library to urllib and configurable request parameters.
42
43
```python { .api }
44
class HTTPBasedSource(BaseSource):
45
"""Base class for HTTP-based emoji sources."""
46
47
REQUEST_KWARGS: ClassVar[Dict[str, Any]] = {
48
'headers': {'User-Agent': 'Mozilla/5.0'}
49
}
50
51
def request(self, url: str) -> bytes:
52
"""
53
Makes GET request to URL using requests library or urllib fallback.
54
55
Parameters:
56
- url: str - URL to request
57
58
Returns:
59
- bytes - Response content
60
61
Raises:
62
- HTTPError - Request failed
63
"""
64
```
65
66
### Discord Emoji Mixin
67
68
Mixin class that adds Discord emoji functionality to other sources, fetching from Discord's CDN.
69
70
```python { .api }
71
class DiscordEmojiSourceMixin(HTTPBasedSource):
72
"""Mixin adding Discord emoji functionality."""
73
74
BASE_DISCORD_EMOJI_URL: ClassVar[str] = 'https://cdn.discordapp.com/emojis/'
75
76
def get_discord_emoji(self, id: int, /) -> Optional[BytesIO]:
77
"""
78
Fetches Discord emoji from Discord CDN.
79
80
Parameters:
81
- id: int - Discord emoji ID
82
83
Returns:
84
- BytesIO - Emoji image stream
85
"""
86
```
87
88
### EmojiCDN Source
89
90
Base class for sources using the emojicdn.elk.sh service, supporting multiple emoji styles through style parameter.
91
92
```python { .api }
93
class EmojiCDNSource(DiscordEmojiSourceMixin):
94
"""Base source for emojicdn.elk.sh service."""
95
96
BASE_EMOJI_CDN_URL: ClassVar[str] = 'https://emojicdn.elk.sh/'
97
STYLE: ClassVar[str] = None # Must be overridden in subclasses
98
99
def get_emoji(self, emoji: str, /) -> Optional[BytesIO]:
100
"""
101
Fetches emoji from EmojiCDN with configured style.
102
103
Parameters:
104
- emoji: str - Unicode emoji
105
106
Returns:
107
- BytesIO - Emoji image stream
108
"""
109
```
110
111
### Built-in Emoji Providers
112
113
Ready-to-use emoji sources for major emoji providers, each with distinct visual styles and characteristics.
114
115
```python { .api }
116
# Primary providers
117
class Twemoji(EmojiCDNSource):
118
"""Twitter-style emojis (default source, also used by Discord)."""
119
STYLE = 'twitter'
120
121
class AppleEmojiSource(EmojiCDNSource):
122
"""Apple-style emojis with iOS aesthetic."""
123
STYLE = 'apple'
124
125
class MicrosoftEmojiSource(EmojiCDNSource):
126
"""Microsoft-style emojis with Windows aesthetic."""
127
STYLE = 'microsoft'
128
129
class GoogleEmojiSource(EmojiCDNSource):
130
"""Google-style Noto emojis."""
131
STYLE = 'google'
132
133
# Additional providers
134
class SamsungEmojiSource(EmojiCDNSource):
135
"""Samsung-style emojis."""
136
STYLE = 'samsung'
137
138
class WhatsAppEmojiSource(EmojiCDNSource):
139
"""WhatsApp-style emojis."""
140
STYLE = 'whatsapp'
141
142
class FacebookEmojiSource(EmojiCDNSource):
143
"""Facebook-style emojis."""
144
STYLE = 'facebook'
145
146
class MessengerEmojiSource(EmojiCDNSource):
147
"""Facebook Messenger-style emojis."""
148
STYLE = 'messenger'
149
150
class JoyPixelsEmojiSource(EmojiCDNSource):
151
"""JoyPixels (formerly EmojiOne) emojis."""
152
STYLE = 'joypixels'
153
154
class OpenmojiEmojiSource(EmojiCDNSource):
155
"""Open-source Openmoji emojis."""
156
STYLE = 'openmoji'
157
158
class EmojidexEmojiSource(EmojiCDNSource):
159
"""Emojidex-style emojis."""
160
STYLE = 'emojidex'
161
162
class MozillaEmojiSource(EmojiCDNSource):
163
"""Mozilla-style emojis."""
164
STYLE = 'mozilla'
165
166
# Convenience aliases
167
TwemojiEmojiSource = Twemoji = TwitterEmojiSource
168
Openmoji = OpenmojiEmojiSource
169
FacebookMessengerEmojiSource = MessengerEmojiSource
170
```
171
172
#### Usage Examples
173
174
```python
175
from pilmoji import Pilmoji
176
from pilmoji.source import (
177
MicrosoftEmojiSource, AppleEmojiSource,
178
OpenmojiEmojiSource, JoyPixelsEmojiSource
179
)
180
from PIL import Image
181
182
image = Image.new('RGB', (300, 200), 'white')
183
184
# Use different emoji sources
185
sources = [
186
('Microsoft', MicrosoftEmojiSource),
187
('Apple', AppleEmojiSource),
188
('Openmoji', OpenmojiEmojiSource),
189
('JoyPixels', JoyPixelsEmojiSource)
190
]
191
192
y_pos = 10
193
for name, source_class in sources:
194
with Pilmoji(image, source=source_class) as pilmoji:
195
pilmoji.text((10, y_pos), f"{name}: π π π β€οΈ", (0, 0, 0))
196
y_pos += 40
197
```
198
199
### Custom Source Implementation
200
201
Guide for implementing custom emoji sources by subclassing BaseSource or HTTPBasedSource.
202
203
#### Custom HTTP Source Example
204
205
```python
206
class CustomEmojiSource(HTTPBasedSource):
207
"""Custom emoji source from your own CDN."""
208
209
def __init__(self, base_url: str):
210
super().__init__()
211
self.base_url = base_url.rstrip('/')
212
213
def get_emoji(self, emoji: str) -> Optional[BytesIO]:
214
# Convert emoji to custom URL format
215
emoji_code = hex(ord(emoji))[2:].upper()
216
url = f"{self.base_url}/emoji_{emoji_code}.png"
217
218
try:
219
return BytesIO(self.request(url))
220
except HTTPError:
221
return None
222
223
def get_discord_emoji(self, id: int) -> Optional[BytesIO]:
224
# Custom Discord emoji handling
225
url = f"{self.base_url}/discord/{id}.png"
226
227
try:
228
return BytesIO(self.request(url))
229
except HTTPError:
230
return None
231
232
# Usage
233
custom_source = CustomEmojiSource("https://my-emoji-cdn.com")
234
with Pilmoji(image, source=custom_source) as pilmoji:
235
pilmoji.text((10, 10), "Custom emojis! π¨", (0, 0, 0))
236
```
237
238
#### Local File Source Example
239
240
```python
241
import os
242
from pathlib import Path
243
244
class LocalEmojiSource(BaseSource):
245
"""Source that loads emojis from local filesystem."""
246
247
def __init__(self, emoji_dir: str):
248
self.emoji_dir = Path(emoji_dir)
249
250
def get_emoji(self, emoji: str) -> Optional[BytesIO]:
251
# Convert emoji to filename
252
emoji_code = f"U+{ord(emoji):04X}"
253
emoji_file = self.emoji_dir / f"{emoji_code}.png"
254
255
if emoji_file.exists():
256
with open(emoji_file, 'rb') as f:
257
return BytesIO(f.read())
258
return None
259
260
def get_discord_emoji(self, id: int) -> Optional[BytesIO]:
261
emoji_file = self.emoji_dir / "discord" / f"{id}.png"
262
263
if emoji_file.exists():
264
with open(emoji_file, 'rb') as f:
265
return BytesIO(f.read())
266
return None
267
268
# Usage
269
local_source = LocalEmojiSource("/path/to/emoji/files")
270
with Pilmoji(image, source=local_source) as pilmoji:
271
pilmoji.text((10, 10), "Local emojis! π", (0, 0, 0))
272
```