145 lines
4.2 KiB
Python
145 lines
4.2 KiB
Python
from tokenize import Token
|
|
|
|
from bs4 import BeautifulSoup
|
|
from files.helpers.config.const import SITE_FULL_IMAGES
|
|
from files.helpers.get import get_user
|
|
from files.helpers.marseyfx.tokenizer import ArgsToken, DotToken, GroupToken, NumberLiteralToken, Tokenizer, WordToken
|
|
from files.helpers.marseyfx.modifiers import Modified, Modifier, modifier_whitelist
|
|
|
|
emoji_replacers = {
|
|
'!': 'is_flipped',
|
|
'#': 'is_big',
|
|
'@': 'is_user'
|
|
}
|
|
|
|
class Emoji:
|
|
name: str
|
|
token: Token
|
|
is_big = False
|
|
is_flipped = False
|
|
is_user = False
|
|
modifiers: list[Modifier]
|
|
is_primary = True
|
|
|
|
def __init__(self, name: str, modifiers, token: Token, **args):
|
|
for symbol, value in emoji_replacers.items():
|
|
if symbol in name:
|
|
name = name.replace(symbol, '')
|
|
setattr(self, value, True)
|
|
|
|
self.name = name
|
|
self.modifiers = modifiers
|
|
self.token = token
|
|
self.is_primary = args.get('is_primary', True)
|
|
|
|
def create_el(self, tokenizer: Tokenizer):
|
|
soup = BeautifulSoup()
|
|
el = None
|
|
if (self.is_user):
|
|
user = get_user(self.name, graceful=True)
|
|
src = None
|
|
if user:
|
|
src = f'/pp/{user.id}'
|
|
|
|
el = soup.new_tag(
|
|
'img',
|
|
loading='lazy',
|
|
src=src,
|
|
attrs={
|
|
'class': f'marseyfx-emoji marseyfx-image marseyfx-user',
|
|
}
|
|
)
|
|
else:
|
|
el = soup.new_tag(
|
|
'img',
|
|
loading='lazy',
|
|
src=f'{SITE_FULL_IMAGES}/e/{self.name}.webp',
|
|
attrs={
|
|
'class': f'marseyfx-emoji marseyfx-image',
|
|
}
|
|
)
|
|
|
|
soup.append(el)
|
|
el = el.wrap(
|
|
soup.new_tag('div', attrs={
|
|
'class': 'marseyfx-emoji-container'
|
|
})
|
|
)
|
|
|
|
mod = Modified(el, tokenizer)
|
|
mod.apply_modifiers(self.modifiers)
|
|
|
|
|
|
container_attrs = {
|
|
'class': 'marseyfx-container',
|
|
}
|
|
|
|
if self.is_primary:
|
|
container_attrs |= {
|
|
'data-bs-toggle': 'tooltip',
|
|
'title': tokenizer.str
|
|
}
|
|
|
|
container = soup.new_tag('div', attrs=container_attrs)
|
|
|
|
if (self.is_big):
|
|
container['class'].append(' marseyfx-big')
|
|
|
|
if (self.is_flipped):
|
|
container['class'].append(' marseyfx-flipped')
|
|
|
|
return mod.container.wrap(container)
|
|
|
|
def parse_emoji(tokenizer: Tokenizer):
|
|
token = tokenizer.parse_next_tokens()
|
|
|
|
if len(tokenizer.errors) > 0 or token is None:
|
|
return False, None, token
|
|
|
|
emoji = parse_from_token(tokenizer, token)
|
|
print(f'Here! {emoji}')
|
|
|
|
if not emoji:
|
|
return False, None, token
|
|
|
|
return True, emoji, token
|
|
|
|
def parse_from_token(tokenizer: Tokenizer, token: GroupToken):
|
|
if not isinstance(token, GroupToken):
|
|
tokenizer.error('Malformed token -- Expected a group token')
|
|
return
|
|
|
|
emoji = token.children[0]
|
|
|
|
if not isinstance(emoji, WordToken) and not isinstance(emoji, NumberLiteralToken):
|
|
tokenizer.error('Malformed token -- Expected an emoji (word token) or number literal token')
|
|
return
|
|
|
|
modifiers = []
|
|
|
|
i = 1
|
|
while i + 1 < len(token.children):
|
|
t = token.children[i]
|
|
|
|
if not isinstance(t, DotToken):
|
|
tokenizer.error('Malformed token -- Expected a dot')
|
|
return
|
|
|
|
modifier = token.children[i + 1]
|
|
if not isinstance(modifier, WordToken):
|
|
tokenizer.error('Malformed token -- Expected a modifier name (word token)')
|
|
return
|
|
|
|
if not modifier.value in modifier_whitelist:
|
|
tokenizer.error(f'Unknown modifier: {modifier.value}')
|
|
return
|
|
|
|
if not i + 2 < len(token.children) or not isinstance(token.children[i + 2], ArgsToken):
|
|
modifiers.append(Modifier(modifier.value, []))
|
|
i += 2
|
|
else:
|
|
args = token.children[i + 2]
|
|
modifiers.append(Modifier(modifier.value, args.children))
|
|
i += 3
|
|
|
|
return Emoji(tokenizer.str[emoji.span[0]:emoji.span[1]], modifiers, token) |