Browse Source

Add PartialEmoji.from_str helper

pull/6978/head
Rapptz 4 years ago
parent
commit
6874aa73c4
  1. 38
      discord/partial_emoji.py
  2. 30
      discord/ui/button.py

38
discord/partial_emoji.py

@ -25,6 +25,7 @@ DEALINGS IN THE SOFTWARE.
from __future__ import annotations
from typing import Any, Dict, Optional, TYPE_CHECKING, Type, TypeVar
import re
from .asset import Asset, AssetMixin
from .errors import InvalidArgument
@ -88,6 +89,8 @@ class PartialEmoji(_EmojiTag, AssetMixin):
__slots__ = ('animated', 'name', 'id', '_state')
_CUSTOM_EMOJI_RE = re.compile(r'<?(?P<animated>a)?:?(?P<name>[A-Za-z0-9\_]+):(?P<id>[0-9]{13,20})>?')
if TYPE_CHECKING:
id: Optional[int]
@ -105,6 +108,41 @@ class PartialEmoji(_EmojiTag, AssetMixin):
name=data.get('name', ''),
)
@classmethod
def from_str(cls: Type[PE], value: str) -> PE:
"""Converts a Discord string representation of an emoji to a :class:`PartialEmoji`.
The formats accepted are:
- ``a:name:id``
- ``<a:name:id>``
- ``name:id``
- ``<:name:id>``
If the format does not match then it is assumed to be a unicode emoji.
.. versionadded:: 2.0
Parameters
------------
value: :class:`str`
The string representation of an emoji.
Returns
--------
:class:`PartialEmoji`
The partial emoji from this string.
"""
match = cls._CUSTOM_EMOJI_RE.match(value)
if match is not None:
groups = match.groupdict()
animated = bool(groups['animated'])
emoji_id = int(groups['id'])
name = groups['name']
return cls(name=name, animated=animated, id=emoji_id)
return cls(name=value, id=None, animated=False)
def to_dict(self) -> Dict[str, Any]:
o: Dict[str, Any] = {'name': self.name}
if self.id:

30
discord/ui/button.py

@ -26,7 +26,6 @@ from __future__ import annotations
from typing import Callable, Optional, TYPE_CHECKING, Tuple, Type, TypeVar, Union
import inspect
import re
import os
@ -43,25 +42,6 @@ __all__ = (
if TYPE_CHECKING:
from .view import View
_custom_emoji = re.compile(r'<?(?P<animated>a)?:?(?P<name>[A-Za-z0-9\_]+):(?P<id>[0-9]{13,20})>?')
def _to_partial_emoji(obj: Union[str, PartialEmoji], *, _custom_emoji=_custom_emoji) -> PartialEmoji:
if isinstance(obj, PartialEmoji):
return obj
obj = str(obj)
match = _custom_emoji.match(obj)
if match is not None:
groups = match.groupdict()
animated = bool(groups['animated'])
emoji_id = int(groups['id'])
name = groups['name']
return PartialEmoji(name=name, animated=animated, id=emoji_id)
return PartialEmoji(name=obj, id=None, animated=False)
B = TypeVar('B', bound='Button')
V = TypeVar('V', bound='View', covariant=True)
@ -118,6 +98,9 @@ class Button(Item[V]):
if url is not None:
style = ButtonStyle.link
if isinstance(emoji, str):
emoji = PartialEmoji.from_str(emoji)
self._underlying = ButtonComponent._raw_construct(
type=ComponentType.button,
custom_id=custom_id,
@ -125,7 +108,7 @@ class Button(Item[V]):
disabled=disabled,
label=label,
style=style,
emoji=None if emoji is None else _to_partial_emoji(emoji),
emoji=emoji,
)
self.group_id = group
@ -190,7 +173,10 @@ class Button(Item[V]):
@emoji.setter
def emoji(self, value: Optional[Union[str, PartialEmoji]]): # type: ignore
if value is not None:
self._underlying.emoji = _to_partial_emoji(value)
if isinstance(value, str):
self._underlying.emoji = PartialEmoji.from_str(value)
else:
self._underlying.emoji = value
else:
self._underlying.emoji = None

Loading…
Cancel
Save