Add userlink priorities and clean up

Also added Twitter as a supported website
This commit is contained in:
Bad Manners 2023-06-30 16:46:16 -03:00
parent 8311391ba2
commit 0ae3e97186
4 changed files with 202 additions and 112 deletions

230
parse.py
View file

@ -1,6 +1,10 @@
from collections import OrderedDict
import json
import lark
import os
import typing
SUPPORTED_USER_TAGS = ('eka', 'fa', 'weasyl', 'ib', 'sf', 'twitter')
DESCRIPTION_GRAMMAR = r"""
?start: document_list
@ -17,25 +21,16 @@ DESCRIPTION_GRAMMAR = r"""
b_tag: "[b]" [document_list] "[/b]"
i_tag: "[i]" [document_list] "[/i]"
url_tag: "[url" ["=" [URL]] "]" [document_list] "[/url]"
self_tag: "[self]" [WS] "[/self]"
user_tag_root: user_tag
user_tag: eka_tag
| fa_tag
| weasyl_tag
| ib_tag
| sf_tag
user_tag: """
eka_tag: "[eka" ["=" USERNAME] "]" USERNAME "[/eka]"
| "[eka" "=" USERNAME "]" [user_tag] "[/eka]"
fa_tag: "[fa" ["=" USERNAME] "]" USERNAME "[/fa]"
| "[fa" "=" USERNAME "]" [user_tag] "[/fa]"
weasyl_tag: "[weasyl" ["=" USERNAME] "]" USERNAME "[/weasyl]"
| "[weasyl" "=" USERNAME "]" [user_tag] "[/weasyl]"
ib_tag: "[ib" ["=" USERNAME] "]" USERNAME "[/ib]"
| "[ib" "=" USERNAME "]" [user_tag] "[/ib]"
sf_tag: "[sf" ["=" USERNAME] "]" USERNAME "[/sf]"
| "[sf" "=" USERNAME "]" [user_tag] "[/sf]"
DESCRIPTION_GRAMMAR += ' | '.join(f'{tag}_tag' for tag in SUPPORTED_USER_TAGS)
DESCRIPTION_GRAMMAR += ''.join(f'\n {tag}_tag: "[{tag}" ["=" USERNAME] "]" USERNAME "[/{tag}]" | "[{tag}" "=" USERNAME "]" [user_tag] "[/{tag}]"' for tag in SUPPORTED_USER_TAGS)
DESCRIPTION_GRAMMAR += r"""
USERNAME: /[a-zA-Z0-9][a-zA-Z0-9 _-]*/
URL: /(https?:\/\/)?[^\]]+/
@ -48,15 +43,49 @@ DESCRIPTION_PARSER = lark.Lark(DESCRIPTION_GRAMMAR, parser='lalr')
class UserTag:
def __init__(self, default=None, eka=None, fa=None, weasyl=None, ib=None, sf=None):
self.default = default
self.eka = eka
self.fa = fa
self.weasyl = weasyl
self.ib = ib
self.sf = sf
def __init__(self, default=None, **kwargs):
self.default: typing.Optional[str] = default
self._sites: typing.OrderedDict[str, typing.Optional[str]] = OrderedDict()
for (k, v) in kwargs.items():
if k in SUPPORTED_USER_TAGS:
self.__setitem__(k, v)
def __setitem__(self, name: str, value: typing.Optional[str]) -> None:
if name in self._sites:
if value is None:
self._sites.pop(name)
else:
self._sites[name] = value
elif value is not None:
self._sites[name] = value
def __getitem__(self, name: str) -> typing.Optional[str]:
return self._sites.get(name)
@property
def sites(self):
yield from self._sites
class UploadTransformer(lark.Transformer):
def __init__(self, *args, **kwargs):
super(UploadTransformer, self).__init__(*args, **kwargs)
def _user_tag_factory(tag):
def user_tag(data):
attribute, inner = data[0], data[1]
if attribute and attribute.strip():
if isinstance(inner, UserTag):
inner[tag] = attribute.strip()
return inner
user = UserTag(default=inner and inner.strip())
user[tag] = attribute.strip()
return user
user = UserTag()
user[tag] = inner.strip()
return user
return user_tag
for tag in SUPPORTED_USER_TAGS:
setattr(self, f'{tag}_tag', _user_tag_factory(tag))
def document_list(self, data):
return ''.join(data)
@ -77,66 +106,24 @@ class UploadTransformer(lark.Transformer):
def user_tag_root(self, data):
user_data: UserTag = data[0]
if user_data.fa:
return self.url_tag((f'https://furaffinity.net/user/{user_data.fa.replace("_", "")}', user_data.default or user_data.fa))
if user_data.eka:
return self.url_tag((f'https://aryion.com/g4/user/{user_data.eka}', user_data.default or user_data.eka))
if user_data.ib:
return self.url_tag((f'https://inkbunny.net/{user_data.ib}', user_data.default or user_data.ib))
if user_data.sf:
return self.url_tag((f'https://{user_data.sf.replace(" ", "-").lower()}.sofurry.com', user_data.default or user_data.sf))
if user_data.weasyl:
self.url_tag((f'https://www.weasyl.com/~{user_data.weasyl}', user_data.default or user_data.weasyl))
for site in user_data.sites:
if site == 'eka':
return self.url_tag((f'https://aryion.com/g4/user/{user_data["eka"]}', user_data.default or user_data["eka"]))
if site == 'fa':
return self.url_tag((f'https://furaffinity.net/user/{user_data["fa"].replace("_", "")}', user_data.default or user_data['fa']))
if site == 'ib':
return self.url_tag((f'https://inkbunny.net/{user_data["ib"]}', user_data.default or user_data['ib']))
if site == 'sf':
return self.url_tag((f'https://{user_data["sf"].replace(" ", "-").lower()}.sofurry.com', user_data.default or user_data['sf']))
if site == 'twitter':
return self.url_tag((f'https://twitter.com/{user_data["twitter"]}', user_data.default or user_data['twitter']))
if site == 'weasyl':
self.url_tag((f'https://www.weasyl.com/~{user_data["weasyl"].replace(" ", "").lower()}', user_data.default or user_data['weasyl']))
raise TypeError('Invalid UserTag data')
def user_tag(self, data):
return data[0]
def eka_tag(self, data):
attribute, inner = data[0], data[1]
if attribute and attribute.strip():
if isinstance(inner, UserTag):
inner.eka = attribute.strip()
return inner
return UserTag(eka=attribute.strip(), default=inner and inner.strip())
return UserTag(eka=inner.strip())
def fa_tag(self, data):
attribute, inner = data[0], data[1]
if attribute and attribute.strip():
if isinstance(inner, UserTag):
inner.fa = attribute.strip()
return inner
return UserTag(fa=attribute.strip(), default=inner and inner.strip())
return UserTag(fa=inner.strip())
def weasyl_tag(self, data):
attribute, inner = data[0], data[1]
if attribute and attribute.strip():
if isinstance(inner, UserTag):
inner.weasyl = attribute.strip()
return inner
return UserTag(weasyl=attribute.strip(), default=inner and inner.strip())
return UserTag(weasyl=inner.strip())
def ib_tag(self, data):
attribute, inner = data[0], data[1]
if attribute and attribute.strip():
if isinstance(inner, UserTag):
inner.ib = attribute.strip()
return inner
return UserTag(ib=attribute.strip(), default=inner and inner.strip())
return UserTag(ib=inner.strip())
def sf_tag(self, data):
attribute, inner = data[0], data[1]
if attribute and attribute.strip():
if isinstance(inner, UserTag):
inner.sf = attribute.strip()
return inner
return UserTag(sf=attribute.strip(), default=inner and inner.strip())
return UserTag(sf=inner.strip())
class BbcodeTransformer(UploadTransformer):
def b_tag(self, data):
if data[0] is None or not data[0].strip():
@ -165,6 +152,18 @@ class MarkdownTransformer(UploadTransformer):
def url_tag(self, data):
return f'[{data[1] or ""}]({data[0] or ""})'
class PlaintextTransformer(UploadTransformer):
def b_tag(self, data):
return f'{data[0] or ""}'
def i_tag(self, data):
return f'{data[0] or ""}'
def url_tag(self, data):
if data[1] is None or not data[1].strip():
return f'{data[0] or ""}'
return f'{data[1].strip()}: {data[0] or ""}'
class AryionTransformer(BbcodeTransformer):
def __init__(self, this_user, *args, **kwargs):
super(AryionTransformer, self).__init__(*args, **kwargs)
@ -172,8 +171,8 @@ class AryionTransformer(BbcodeTransformer):
def user_tag_root(self, data):
user_data = data[0]
if user_data.eka:
return f':icon{user_data.eka}:'
if user_data['eka']:
return f':icon{user_data["eka"]}:'
return super(AryionTransformer, self).user_tag_root(data)
class FuraffinityTransformer(BbcodeTransformer):
@ -183,8 +182,8 @@ class FuraffinityTransformer(BbcodeTransformer):
def user_tag_root(self, data):
user_data = data[0]
if user_data.fa:
return f':icon{user_data.fa}:'
if user_data['fa']:
return f':icon{user_data["fa"]}:'
return super(FuraffinityTransformer, self).user_tag_root(data)
class WeasylTransformer(MarkdownTransformer):
@ -194,15 +193,16 @@ class WeasylTransformer(MarkdownTransformer):
def user_tag_root(self, data):
user_data = data[0]
if user_data.weasyl:
return f'<!~{user_data.weasyl}>'
if user_data['weasyl']:
return f'<!~{user_data["weasyl"].replace(" ", "")}>'
if user_data.default is None:
if user_data.fa:
return f'<fa:{user_data.fa}>'
if user_data.ib:
return f'<ib:{user_data.ib}>'
if user_data.sf:
return f'<sf:{user_data.sf}>'
for site in user_data.sites:
if site == 'fa':
return f'<fa:{user_data["fa"]}>'
if site == 'ib':
return f'<ib:{user_data["ib"]}>'
if site == 'sf':
return f'<sf:{user_data["sf"]}>'
return super(WeasylTransformer, self).user_tag_root(data)
class InkbunnyTransformer(BbcodeTransformer):
@ -212,15 +212,16 @@ class InkbunnyTransformer(BbcodeTransformer):
def user_tag_root(self, data):
user_data = data[0]
if user_data.ib:
return f'[iconname]{user_data.ib}[/iconname]'
if user_data['ib']:
return f'[iconname]{user_data["ib"]}[/iconname]'
if user_data.default is None:
if user_data.fa:
return f'[fa]{user_data.fa}[/fa]'
if user_data.sf:
return f'[sf]{user_data.sf}[/sf]'
if user_data.weasyl:
return f'[weasyl]{user_data.weasyl}[/weasyl]'
for site in user_data.sites:
if site == 'fa':
return f'[fa]{user_data["fa"]}[/fa]'
if site == 'sf':
return f'[sf]{user_data["sf"]}[/sf]'
if site == 'weasyl':
return f'[weasyl]{user_data["weasyl"].replace(" ", "").lower()}[/weasyl]'
return super(InkbunnyTransformer, self).user_tag_root(data)
class SoFurryTransformer(BbcodeTransformer):
@ -230,27 +231,40 @@ class SoFurryTransformer(BbcodeTransformer):
def user_tag_root(self, data):
user_data = data[0]
if user_data.sf:
return f':icon{user_data.sf}:'
if user_data['sf']:
return f':icon{user_data["sf"]}:'
if user_data.default is None:
if user_data.fa:
return f'fa!{user_data.fa}'
if user_data.ib:
return f'ib!{user_data.ib}'
for site in user_data.sites:
if site == 'fa':
return f'fa!{user_data["fa"]}'
if site == 'ib':
return f'ib!{user_data["ib"]}'
return super(SoFurryTransformer, self).user_tag_root(data)
class TwitterTransformer(PlaintextTransformer):
def __init__(self, this_user, *args, **kwargs):
super(TwitterTransformer, self).__init__(*args, **kwargs)
self.self_tag = lambda _: self.user_tag_root((UserTag(twitter=this_user),))
def user_tag_root(self, data):
user_data = data[0]
if user_data['twitter']:
return f'@{user_data["twitter"]}'
return super(TwitterTransformer, self).user_tag_root(data)
TRANSFORMATIONS = {
'furaffinity': ('desc_furaffinity.txt', FuraffinityTransformer),
'aryion': ('desc_aryion.txt', AryionTransformer),
'weasyl': ('desc_weasyl.md', WeasylTransformer),
'furaffinity': ('desc_furaffinity.txt', FuraffinityTransformer),
'inkbunny': ('desc_inkbunny.txt', InkbunnyTransformer),
'sofurry': ('desc_sofurry.txt', SoFurryTransformer),
'twitter': ('desc_twitter.txt', TwitterTransformer),
'weasyl': ('desc_weasyl.md', WeasylTransformer),
}
def parse_description(description, out_dir):
def parse_description(description, config_path, out_dir):
parsed_description = DESCRIPTION_PARSER.parse(description)
with open('config.json', 'r') as f:
with open(config_path, 'r') as f:
config = json.load(f)
# Validate JSON
errors = []