From d85951d912c4a5e1fd76c0521567b7359a6733ec Mon Sep 17 00:00:00 2001 From: float-trip <102226344+float-trip@users.noreply.github.com> Date: Wed, 27 Apr 2022 10:46:47 -0400 Subject: [PATCH] add :@userpat: emojis (#231) * refactor emoji formatting * add user patting --- files/helpers/const.py | 10 ++-- files/helpers/sanitize.py | 120 ++++++++++++++++---------------------- 2 files changed, 57 insertions(+), 73 deletions(-) diff --git a/files/helpers/const.py b/files/helpers/const.py index d7e80a9c6..c5a97dac2 100644 --- a/files/helpers/const.py +++ b/files/helpers/const.py @@ -717,10 +717,12 @@ marseys_const2 = marseys_const + ['chudsey','a','b','c','d','e','f','g','h','i', db.close() if SITE_NAME == 'PCM': + valid_username_chars = 'a-zA-Z0-9_\-А-я' valid_username_regex = re.compile("^[a-zA-Z0-9_\-А-я]{3,25}$", flags=re.A) mention_regex = re.compile('(^|\s|

)@(([a-zA-Z0-9_\-А-я]){3,25})', flags=re.A) mention_regex2 = re.compile('

@(([a-zA-Z0-9_\-А-я]){3,25})', flags=re.A) else: + valid_username_chars = 'a-zA-Z0-9_\-' valid_username_regex = re.compile("^[a-zA-Z0-9_\-]{3,25}$", flags=re.A) mention_regex = re.compile('(^|\s|

)@(([a-zA-Z0-9_\-]){1,25})', flags=re.A) mention_regex2 = re.compile('

@(([a-zA-Z0-9_\-]){1,25})', flags=re.A) @@ -759,10 +761,10 @@ strikethrough_regex = re.compile('''~{1,2}([^~]+)~{1,2}''', flags=re.A) mute_regex = re.compile("/mute @([a-z0-9_\-]{3,25}) ([0-9])+", flags=re.A) -emoji_regex = re.compile("[^a]>\s*(:[!#]{0,2}\w+:\s*)+<\/", flags=re.A) -emoji_regex2 = re.compile('(?\s*(:[!#@]{{0,3}}[{valid_username_chars}]+:\s*)+<\/", flags=re.A) +emoji_regex2 = re.compile(f"(?([\w:~,()\-.#&\/=?@%;+]{5,250})<\/a>', flags=re.A) diff --git a/files/helpers/sanitize.py b/files/helpers/sanitize.py index 7127c5bc8..9c41067d1 100644 --- a/files/helpers/sanitize.py +++ b/files/helpers/sanitize.py @@ -43,7 +43,8 @@ def allowed_attributes(tag, name, value): if name == 'loading' and value == 'lazy': return True if name == 'referrpolicy' and value == 'no-referrer': return True if name == 'data-bs-toggle' and value == 'tooltip': return True - if name in ['alt','title','g','b']: return True + if name in ['alt','title','g','b','pat']: return True + if name == 'class' and value == 'pat-hand': return True return False if tag == 'lite-youtube': @@ -64,6 +65,13 @@ def allowed_attributes(tag, name, value): if name == 'class' and value == 'mb-0': return True return False + if tag == 'span': + if name == 'class' and value in ['pat-container', 'pat-hand']: return True + if name == 'data-bs-toggle' and value == 'tooltip': return True + if name == 'title': return True + if name == 'alt': return True + return False + url_re = build_url_re(tlds=TLDS, protocols=['http', 'https']) @@ -81,6 +89,43 @@ def handler(signum, frame): print("Timeout!") raise Exception("Timeout") +def render_emoji(html, regexp, edit, marseys_used=set(), b=False): + emojis = list(regexp.finditer(html)) + captured = set() + + for i in emojis: + if i.group(0) in captured: continue + captured.add(i.group(0)) + + emoji = i.group(1).lower() + attrs = '' + if b: attrs += ' b' + if not edit and len(emojis) <= 20 and random() < 0.0025 and ('marsey' in emoji or emoji in marseys_const2): attrs += ' g' + + old = emoji + emoji = emoji.replace('!','').replace('#','') + if emoji == 'marseyrandom': emoji = choice(marseys_const2) + + emoji_partial = ':{0}:' + emoji_html = None + + if path.isfile(f'files/assets/images/emojis/{emoji}.webp'): + emoji_html = emoji_partial.format(old, f'/e/{emoji}.webp', attrs) + elif emoji.endswith('pat'): + if path.isfile(f"files/assets/images/emojis/{emoji.replace('pat','')}.webp"): + pat(emoji.replace('pat','')) + emoji_html = emoji_partial.format(old, f'/e/{emoji}.webp', attrs) + requests.post(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/purge_cache', headers=CF_HEADERS, data={'files': [f"https://{request.host}/e/{emoji}.webp"]}, timeout=5) + elif emoji.startswith('@'): + if u := get_user(emoji[1:-3], graceful=True): + attrs += ' pat' + emoji_html = f'{emoji_partial.format(old, f"/pp/{u.id}", attrs)}' + + + if emoji_html: + html = re.sub(f'(?\1', sanitized) - if comment: marseys_used = set() + marseys_used = set() emojis = list(emoji_regex.finditer(sanitized)) if len(emojis) > 20: edit = True @@ -159,55 +204,14 @@ def sanitize(sanitized, alert=False, comment=False, edit=False): if 'marseylong1' in old or 'marseylong2' in old or 'marseyllama1' in old or 'marseyllama2' in old: new = old.lower().replace(">", " class='mb-0'>") else: new = old.lower() - captured2 = [] - for i in emoji_regex2.finditer(new): - if i.group(0) in captured2: continue - captured2.append(i.group(0)) - - emoji = i.group(1).lower() - remoji = emoji.replace('!','').replace('#','') - - golden = ' ' - if not edit and random() < 0.0025 and ('marsey' in emoji or emoji in marseys_const2): golden = 'g ' - - if remoji == 'marseyrandom': remoji = choice(marseys_const2) - - if path.isfile(f'files/assets/images/emojis/{remoji}.webp'): - new = re.sub(f'(?', new, flags=re.I|re.A) - if comment: marseys_used.add(emoji) - elif remoji.endswith('pat') and path.isfile(f"files/assets/images/emojis/{remoji.replace('pat','')}.webp"): - pat(remoji.replace('pat','')) - new = re.sub(f'(?', new, flags=re.I|re.A) - requests.post(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/purge_cache', headers=CF_HEADERS, data={'files': [f"https://{request.host}/e/{emoji}.webp"]}, timeout=5) - + new = render_emoji(new, emoji_regex2, edit, marseys_used, True) sanitized = sanitized.replace(old, new) emojis = list(emoji_regex3.finditer(sanitized)) if len(emojis) > 20: edit = True - captured = [] - for i in emojis: - if i.group(0) in captured: continue - captured.append(i.group(0)) - - emoji = i.group(1).lower() - golden = ' ' - if not edit and random() < 0.0025 and ('marsey' in emoji or emoji in marseys_const2): golden = 'g ' - - old = emoji - emoji = emoji.replace('!','').replace('#','') - if emoji == 'marseyrandom': emoji = choice(marseys_const2) - - - if path.isfile(f'files/assets/images/emojis/{emoji}.webp'): - sanitized = re.sub(f'(?', sanitized, flags=re.I|re.A) - if comment: marseys_used.add(emoji) - elif emoji.endswith('pat') and path.isfile(f"files/assets/images/emojis/{emoji.replace('pat','')}.webp"): - pat(emoji.replace('pat','')) - sanitized = re.sub(f'(?', sanitized, flags=re.I|re.A) - requests.post(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/purge_cache', headers=CF_HEADERS, data={'files': [f"https://{request.host}/e/{emoji}.webp"]}, timeout=5) - + sanitized = render_emoji(sanitized, emoji_regex3, edit, marseys_used) for rd in ["://reddit.com", "://new.reddit.com", "://www.reddit.com", "://redd.it", "://libredd.it", "://teddit.net"]: sanitized = sanitized.replace(rd, "://old.reddit.com") @@ -313,29 +317,7 @@ def filter_emojis_only(title, edit=False, graceful=False): title = title.replace('‎','').replace('​','').replace("\ufeff", "").replace("𒐪","").replace("\n", "").replace("\r", "").replace("\t", "").replace("&", "&").replace('<','<').replace('>','>').replace('"', '"').replace("'", "'").strip() - emojis = list(emoji_regex4.finditer(title)) - if len(emojis) > 20: edit = True - - captured = [] - for i in emojis: - if i.group(0) in captured: continue - captured.append(i.group(0)) - - emoji = i.group(1).lower() - golden = ' ' - if not edit and random() < 0.0025 and ('marsey' in emoji or emoji in marseys_const2): golden = 'g ' - - old = emoji - emoji = emoji.replace('!','').replace('#','') - if emoji == 'marseyrandom': emoji = choice(marseys_const2) - - if path.isfile(f'files/assets/images/emojis/{emoji}.webp'): - title = re.sub(f'(?', title, flags=re.I|re.A) - elif emoji.endswith('pat') and path.isfile(f"files/assets/images/emojis/{emoji.replace('pat','')}.webp"): - pat(emoji.replace('pat','')) - title = re.sub(f'(?', title, flags=re.I|re.A) - requests.post(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/purge_cache', headers=CF_HEADERS, data={'files': [f"https://{request.host}/e/{emoji}.webp"]}, timeout=5) - + title = render_emoji(title, emoji_regex4, edit) title = strikethrough_regex.sub(r'\1', title) @@ -344,4 +326,4 @@ def filter_emojis_only(title, edit=False, graceful=False): signal.alarm(0) if len(title) > 1500 and not graceful: abort(400) - else: return title \ No newline at end of file + else: return title