Merge branch 'master' into constants

remotes/1693045480750635534/spooky-22
atrc445 2021-08-21 23:10:23 +02:00
commit d3f3c0b6a7
17 changed files with 153 additions and 159 deletions

View File

@ -401,7 +401,7 @@ class Submission(Base, Stndrd, Age_times, Scores, Fuzzing):
@property
def is_image(self):
if self.url: return self.url.lower().endswith('.jpg') or self.url.lower().endswith('.png') or self.url.lower().endswith('.gif') or self.url.lower().endswith('.jpeg') or self.url.lower().endswith('?maxwidth=9999') or self.url.lower().endswith('?maxwidth=8888')
if self.url: return self.url.lower().endswith('.jpg') or self.url.lower().endswith('.png') or self.url.lower().endswith('.gif') or self.url.lower().endswith('.jpeg') or self.url.lower().endswith('?maxwidth=9999')
else: return False
@property

View File

@ -14,7 +14,7 @@ def send_notification(vid, user, text):
with CustomRenderer() as renderer:
text_html = renderer.render(mistletoe.Document(text))
text_html = sanitize(text_html, linkgen=True)
text_html = sanitize(text_html)
new_comment = Comment(author_id=vid,
parent_submission=None,
@ -39,7 +39,7 @@ def send_pm(vid, user, text):
with CustomRenderer() as renderer: text_html = renderer.render(mistletoe.Document(text))
text_html = sanitize(text_html, linkgen=True)
text_html = sanitize(text_html)
new_comment = Comment(author_id=vid,
parent_submission=None,
@ -62,7 +62,7 @@ def send_follow_notif(vid, user, text):
text = text.replace("\n", "\n\n").replace("\n\n\n\n\n\n", "\n\n").replace("\n\n\n\n", "\n\n").replace("\n\n\n", "\n\n")
with CustomRenderer() as renderer: text_html = renderer.render(mistletoe.Document(text))
text_html = sanitize(text_html, linkgen=True)
text_html = sanitize(text_html)
new_comment = Comment(author_id=NOTIFICATIONS_ACCOUNT,
parent_submission=None,
@ -88,7 +88,7 @@ def send_unfollow_notif(vid, user, text):
with CustomRenderer() as renderer:
text_html = renderer.render(mistletoe.Document(text))
text_html = sanitize(text_html, linkgen=True)
text_html = sanitize(text_html)
new_comment = Comment(author_id=NOTIFICATIONS_ACCOUNT,
parent_submission=None,
@ -114,7 +114,7 @@ def send_block_notif(vid, user, text):
with CustomRenderer() as renderer:
text_html = renderer.render(mistletoe.Document(text))
text_html = sanitize(text_html, linkgen=True)
text_html = sanitize(text_html)
new_comment = Comment(author_id=NOTIFICATIONS_ACCOUNT,
parent_submission=None,
@ -140,7 +140,7 @@ def send_unblock_notif(vid, user, text):
with CustomRenderer() as renderer:
text_html = renderer.render(mistletoe.Document(text))
text_html = sanitize(text_html, linkgen=True)
text_html = sanitize(text_html)
new_comment = Comment(author_id=NOTIFICATIONS_ACCOUNT,
parent_submission=None,
@ -166,7 +166,7 @@ def send_admin(vid, text):
with CustomRenderer() as renderer: text_html = renderer.render(mistletoe.Document(text))
text_html = sanitize(text_html, linkgen=True)
text_html = sanitize(text_html)
new_comment = Comment(author_id=vid,
parent_submission=None,

View File

@ -59,8 +59,7 @@ _allowed_styles =[
# filter to make all links show domain on hover
def a_modify(attrs, new=False):
def a_modify(attrs, whatever):
raw_url=attrs.get((None, "href"), None)
if raw_url:
@ -85,16 +84,14 @@ def a_modify(attrs, new=False):
return attrs
def sanitize(sanitized):
sanitized = sanitized.replace("\ufeff", "").replace("m.youtube.com", "youtube.com")
for i in re.finditer('https://i.imgur.com/(([^_]*?)\.(jpg|png|jpeg))', sanitized):
sanitized = sanitized.replace(i.group(1), i.group(2) + "_d." + i.group(3) + "?maxwidth=9999")
_clean_wo_links = bleach.Cleaner(tags=_allowed_tags,
attributes=_allowed_attributes,
protocols=_allowed_protocols,
)
_clean_w_links = bleach.Cleaner(tags=_allowed_tags,
sanitized = bleach.Cleaner(tags=_allowed_tags,
attributes=_allowed_attributes,
protocols=_allowed_protocols,
styles=_allowed_styles,
@ -104,74 +101,64 @@ _clean_w_links = bleach.Cleaner(tags=_allowed_tags,
callbacks=[a_modify]
)
]
)
).clean(sanitized)
#soupify
soup = BeautifulSoup(sanitized, features="html.parser")
#img elements - embed
for tag in soup.find_all("img"):
url = tag.get("src", "")
if not url: continue
if "profile-pic-20" not in tag.get("class", ""):
#print(tag.get('class'))
# set classes and wrap in link
tag["rel"] = "nofollow"
tag["style"] = "max-height: 100px; max-width: 100%;"
tag["class"] = "in-comment-image rounded-sm my-2"
link = soup.new_tag("a")
link["href"] = tag["src"]
link["rel"] = "nofollow noopener"
link["target"] = "_blank"
link["onclick"] = f"expandDesktopImage('{tag['src']}');"
link["data-toggle"] = "modal"
link["data-target"] = "#expandImageModal"
tag.wrap(link)
#disguised link preventer
for tag in soup.find_all("a"):
if re.match("https?://\S+", str(tag.string)):
try:
tag.string = tag["href"]
except:
tag.string = ""
#clean up tags in code
for tag in soup.find_all("code"):
tag.contents=[x.string for x in tag.contents if x.string]
#whatever else happens with images, there are only two sets of classes allowed
for tag in soup.find_all("img"):
if 'profile-pic-20' not in tag.attrs.get("class",""):
tag.attrs['class']="in-comment-image rounded-sm my-2"
#table format
for tag in soup.find_all("table"):
tag.attrs['class']="table table-striped"
for tag in soup.find_all("thead"):
tag.attrs['class']="bg-primary text-white"
def sanitize(text, linkgen=False):
sanitized = str(soup)
text = text.replace("\ufeff", "").replace("m.youtube.com", "youtube.com")
if linkgen:
sanitized = _clean_w_links.clean(text)
#soupify
soup = BeautifulSoup(sanitized, features="html.parser")
#img elements - embed
for tag in soup.find_all("img"):
url = tag.get("src", "")
if not url: continue
if "profile-pic-20" not in tag.get("class", ""):
#print(tag.get('class'))
# set classes and wrap in link
tag["rel"] = "nofollow"
tag["style"] = "max-height: 100px; max-width: 100%;"
tag["class"] = "in-comment-image rounded-sm my-2"
link = soup.new_tag("a")
link["href"] = tag["src"]
link["rel"] = "nofollow noopener"
link["target"] = "_blank"
link["onclick"] = f"expandDesktopImage('{tag['src']}');"
link["data-toggle"] = "modal"
link["data-target"] = "#expandImageModal"
tag.wrap(link)
#disguised link preventer
for tag in soup.find_all("a"):
if re.match("https?://\S+", str(tag.string)):
try:
tag.string = tag["href"]
except:
tag.string = ""
#clean up tags in code
for tag in soup.find_all("code"):
tag.contents=[x.string for x in tag.contents if x.string]
#whatever else happens with images, there are only two sets of classes allowed
for tag in soup.find_all("img"):
if 'profile-pic-20' not in tag.attrs.get("class",""):
tag.attrs['class']="in-comment-image rounded-sm my-2"
#table format
for tag in soup.find_all("table"):
tag.attrs['class']="table table-striped"
for tag in soup.find_all("thead"):
tag.attrs['class']="bg-primary text-white"
sanitized = str(soup)
else:
sanitized = _clean_wo_links.clean(text)
start = '<s>'
end = '</s>'

View File

@ -567,7 +567,7 @@ def admin_title_change(user_id, v):
new_name=request.form.get("title").strip()
user.customtitleplain=new_name
new_name = sanitize(new_name, linkgen=True)
new_name = sanitize(new_name)
user=g.db.query(User).with_for_update().options(lazyload('*')).filter_by(id=user.id).first()
user.customtitle=new_name
@ -704,7 +704,7 @@ def ban_post(post_id, v):
ban_reason = ban_reason.replace("\n", "\n\n").replace("\n\n\n\n\n\n", "\n\n").replace("\n\n\n\n", "\n\n").replace("\n\n\n", "\n\n")
with CustomRenderer() as renderer:
ban_reason = renderer.render(mistletoe.Document(ban_reason))
ban_reason = sanitize(ban_reason, linkgen=True)
ban_reason = sanitize(ban_reason)
post.ban_reason = ban_reason

View File

@ -158,7 +158,7 @@ def api_comment(v):
for i in re.finditer('^(https:\/\/.*\.(png|jpg|jpeg|gif|PNG|JPG|JPEG|GIF|9999))', body, re.MULTILINE): body = body.replace(i.group(1), f'![]({i.group(1)})')
body = body.replace("\n", "\n\n").replace("\n\n\n\n\n\n", "\n\n").replace("\n\n\n\n", "\n\n").replace("\n\n\n", "\n\n")
with CustomRenderer(post_id=parent_id) as renderer: body_md = renderer.render(mistletoe.Document(body))
body_html = sanitize(body_md, linkgen=True)
body_html = sanitize(body_md)
# Run safety filter
bans = filter_comment_html(body_html)
@ -281,7 +281,7 @@ def api_comment(v):
body = body.replace("\n", "\n\n").replace("\n\n\n\n\n\n", "\n\n").replace("\n\n\n\n", "\n\n").replace("\n\n\n", "\n\n")
with CustomRenderer(post_id=parent_id) as renderer:
body_md = renderer.render(mistletoe.Document(body))
body_html = sanitize(body_md, linkgen=True)
body_html = sanitize(body_md)
c_aux = CommentAux(
id=c.id,
@ -341,7 +341,7 @@ def api_comment(v):
body = random.choice(LONGPOST_REPLIES)
body = body.replace("\n", "\n\n").replace("\n\n\n\n\n\n", "\n\n").replace("\n\n\n\n", "\n\n").replace("\n\n\n", "\n\n")
with CustomRenderer(post_id=parent_id) as renderer: body_md = renderer.render(mistletoe.Document(body))
body_html2 = sanitize(body_md, linkgen=True)
body_html2 = sanitize(body_md)
c_aux = CommentAux(
id=c2.id,
body_html=body_html2,
@ -371,7 +371,7 @@ def api_comment(v):
body = "zoz"
with CustomRenderer(post_id=parent_id) as renderer: body_md = renderer.render(mistletoe.Document(body))
body_html2 = sanitize(body_md, linkgen=True)
body_html2 = sanitize(body_md)
c_aux = CommentAux(
id=c2.id,
body_html=body_html2,
@ -397,7 +397,7 @@ def api_comment(v):
body = "zle"
with CustomRenderer(post_id=parent_id) as renderer: body_md = renderer.render(mistletoe.Document(body))
body_html2 = sanitize(body_md, linkgen=True)
body_html2 = sanitize(body_md)
c_aux = CommentAux(
id=c3.id,
body_html=body_html2,
@ -423,7 +423,7 @@ def api_comment(v):
body = "zozzle"
with CustomRenderer(post_id=parent_id) as renderer: body_md = renderer.render(mistletoe.Document(body))
body_html2 = sanitize(body_md, linkgen=True)
body_html2 = sanitize(body_md)
c_aux = CommentAux(
id=c4.id,
body_html=body_html2,
@ -530,7 +530,7 @@ def edit_comment(cid, v):
for i in re.finditer('^(https:\/\/.*\.(png|jpg|jpeg|gif|PNG|JPG|JPEG|GIF|9999))', body, re.MULTILINE): body = body.replace(i.group(1), f'![]({i.group(1)})')
body = body.replace("\n", "\n\n").replace("\n\n\n\n\n\n", "\n\n").replace("\n\n\n\n", "\n\n").replace("\n\n\n", "\n\n")
with CustomRenderer(post_id=c.post.id) as renderer: body_md = renderer.render(mistletoe.Document(body))
body_html = sanitize(body_md, linkgen=True)
body_html = sanitize(body_md)
bans = filter_comment_html(body_html)
@ -624,7 +624,7 @@ def edit_comment(cid, v):
body = body.replace("\n", "\n\n").replace("\n\n\n\n\n\n", "\n\n").replace("\n\n\n\n", "\n\n").replace("\n\n\n", "\n\n")
with CustomRenderer(post_id=c.parent_submission) as renderer:
body_md = renderer.render(mistletoe.Document(body))
body_html = sanitize(body_md, linkgen=True)
body_html = sanitize(body_md)
c.body = body
c.body_html = body_html

View File

@ -241,7 +241,7 @@ def edit_post(pid, v):
body = request.form.get("body", "")
for i in re.finditer('^(https:\/\/.*\.(png|jpg|jpeg|gif|PNG|JPG|JPEG|GIF|9999))', body, re.MULTILINE): body = body.replace(i.group(1), f'![]({i.group(1)})')
with CustomRenderer() as renderer: body_md = renderer.render(mistletoe.Document(body))
body_html = sanitize(body_md, linkgen=True)
body_html = sanitize(body_md)
# Run safety filter
bans = filter_comment_html(body_html)
@ -559,7 +559,7 @@ def submit_post(v):
else:
url = ""
if "i.imgur.com" in url: url = url.replace(".png", "_d.png").replace(".jpg", "_d.jpg").replace(".jpeg", "_d.jpeg") + "?maxwidth=8888"
if "i.imgur.com" in url: url = url.replace(".png", "_d.png").replace(".jpg", "_d.jpg").replace(".jpeg", "_d.jpeg") + "?maxwidth=9999"
body = request.form.get("body", "")
# check for duplicate
@ -606,7 +606,7 @@ def submit_post(v):
if t: embed = f"https://youtube.com/embed/{yt_id}?start={t}"
else: embed = f"https://youtube.com/embed/{yt_id}"
elif app.config['SERVER_NAME'] in domain and "/post/" in url:
elif app.config['SERVER_NAME'] in domain and "/post/" in url and "context" not in url:
id = url.split("/post/")[1]
if "/" in id: id = id.split("/")[0]
embed = id
@ -704,7 +704,7 @@ def submit_post(v):
for i in re.finditer('^(https:\/\/.*\.(png|jpg|jpeg|gif|PNG|JPG|JPEG|GIF|9999))', body, re.MULTILINE): body = body.replace(i.group(1), f'![]({i.group(1)})')
with CustomRenderer() as renderer:
body_md = renderer.render(mistletoe.Document(body))
body_html = sanitize(body_md, linkgen=True)
body_html = sanitize(body_md)
# Run safety filter
bans = filter_comment_html(body_html)
@ -893,7 +893,7 @@ def submit_post(v):
body += f"Snapshots:\n\n* [reveddit.com](https://reveddit.com/{new_post.url})\n* [archive.org](https://web.archive.org/{new_post.url})\n* [archive.ph](https://archive.ph/?url={urllib.parse.quote(new_post.url)}&run=1) (click to archive)"
gevent.spawn(archiveorg, new_post.url)
with CustomRenderer(post_id=new_post.id) as renderer: body_md = renderer.render(mistletoe.Document(body))
body_html = sanitize(body_md, linkgen=True)
body_html = sanitize(body_md)
c_aux = CommentAux(
id=c.id,
body_html=body_html,

View File

@ -82,7 +82,7 @@ def settings_profile_post(v):
for i in re.finditer('^(https:\/\/.*\.(png|jpg|jpeg|gif|PNG|JPG|JPEG|GIF|9999))', bio, re.MULTILINE): bio = bio.replace(i.group(1), f'![]({i.group(1)})')
bio = bio.replace("\n", "\n\n").replace("\n\n\n\n\n\n", "\n\n").replace("\n\n\n\n", "\n\n").replace("\n\n\n", "\n\n")
with CustomRenderer() as renderer: bio_html = renderer.render(mistletoe.Document(bio))
bio_html = sanitize(bio_html, linkgen=True)
bio_html = sanitize(bio_html)
# Run safety filter
bans = filter_comment_html(bio_html)

View File

@ -115,7 +115,7 @@ def messagereply(v, username, id):
if existing: return redirect('/notifications?messages=true')
with CustomRenderer() as renderer: text_html = renderer.render(mistletoe.Document(message))
text_html = sanitize(text_html, linkgen=True)
text_html = sanitize(text_html)
parent = get_comment(int(id), v=v)
new_comment = Comment(author_id=v.id,
parent_submission=None,

View File

@ -4,7 +4,7 @@
{% block content %}
<pre class="d-none d-md-inline-block"></pre>
<h5 style="font-weight:bold;">admins</h5>
<h5 style="font-weight:bold;">Admins</h5>
<pre></pre>
<table class="table table-striped mb-5">
<thead class="bg-primary text-white">

View File

@ -29,7 +29,7 @@
<div class="user-info">
<span class="comment-collapse d-md-none" onclick="collapse_comment('{{c.id}}')"></span>
{% if standalone and c.over_18 %}<span class="badge badge-danger">+18</span> {% endif %}
[{% if c.is_banned %}Removed by admins{% elif c.deleted_utc > 0 %}Deleted by author{% elif c.is_blocking %}You are blocking @{{c.author.username}}{% elif c.is_blocked %}This user has blocked you{% endif %}]
[{% if c.is_suspended %}Removed by admins{% elif c.deleted_utc > 0 %}Deleted by author{% elif c.is_blocking %}You are blocking @{{c.author.username}}{% elif c.is_blocked %}This user has blocked you{% endif %}]
</div>
@ -107,7 +107,7 @@
<div class="comment-body">
<div id="{% if comment_info and comment_info.id == c.id %}context{%else%}comment-{{c.id}}-only{% endif %}" class="{% if comment_info and comment_info.id == c.id %}context{%endif%}{% if c.is_banned %} banned{% endif %}{% if c.deleted_utc %} deleted{% endif %}">
<div id="{% if comment_info and comment_info.id == c.id %}context{%else%}comment-{{c.id}}-only{% endif %}" class="{% if comment_info and comment_info.id == c.id %}context{%endif%}{% if c.is_suspended %} banned{% endif %}{% if c.deleted_utc %} deleted{% endif %}">
<div class="user-info">
<span class="comment-collapse d-md-none" onclick="collapse_comment('{{c.id}}')"></span>
@ -131,13 +131,28 @@
{% if c.is_blocking %}<i class="fas fa-user-minus text-warning" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="{% if v and v.admin_level >= 2 %}You're blocking this user, but you can see this comment because {{'it\'s an admin comment' if c.distinguish_level else 'you\'re an admin'}}.{% else %}Comment author is banned{% endif %}"></i>&nbsp;{% endif %}
{% if c.is_blocked %}<i class="fas fa-user-minus text-danger" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="This user is blocking you, but you can see this comment because {{'it\'s an admin comment' if c.distinguish_level else 'you\'re an admin'}}."></i>&nbsp;{% endif %}
<a style="color:#{{c.author.namecolor}}; font-size:12px; font-weight:bold;" href="/@{{c.author.username}}"><img src="{{c.author.profile_url}}" class="profile-pic-25 mr-2"/><span {% if c.author.patron %}class="patron" style="background-color:#{{c.author.namecolor}};"{% endif %}>{{c.author.username}}</span></a>{% if c.author.customtitle %}&nbsp;<bdi style="color: #{{c.author.titlecolor}}">&nbsp;{{c.author.customtitle | safe}}</bdi>{% endif %}
{% if c.author.verified %}<i class="fas fa-badge-check align-middle ml-1" style="color:#1DA1F2" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="Verified"></i>
{% endif %}
<a {% if v %}href="{{c.author.url}}"{% else %}href="/logged_out{{c.author.url}}"{% endif %} style="color:#{{c.author.namecolor}}; font-size:12px; font-weight:bold;"><img src="{{c.author.profile_url}}" class="profile-pic-25 mr-2"/><span {% if c.author.patron %}class="patron" style="background-color:#{{c.author.namecolor}};"{% endif %}>{{c.author.username}}</span></a>{% if c.author.customtitle %}&nbsp;<bdi style="color: #{{c.author.titlecolor}}">&nbsp;{{c.author.customtitle | safe}}</bdi>{% endif %}
<span id="timestamp-{{c.id}}" data-toggle="tooltip" data-placement="bottom" title="" class="time-stamp">&nbsp;{{c.age_string}}</span>
{% if c.edited_utc %}
<span class="time-edited"><span>&#183;</span> <span class="font-italic">Edited {{c.edited_string}}</span></span>
{% endif %}
</div>
{% if c.active_flags %}
<div id="flaggers-{{c.id}}" class="flaggers d-none">
<strong><i class="far fa-fw fa-flag"></i> Reported by:</strong>
<pre></pre>
<ul style="padding-left:20px; margin-bottom: 0;">
{% for f in c.ordered_flags %}
<li><a style="font-weight:bold" href="{{f.user.url}}">@{{f.user.username}}</a>{% if f.reason %}: {{f.reason | safe}}{% endif %}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% if c.is_banned and c.ban_reason %}
<div id="comment-banned-warning" class="comment-text text-danger text-small mb-0">Reason: {{c.ban_reason}}</div>
@ -192,18 +207,6 @@
</form>
</div>
{% endif %}
{% if c.active_flags %}
<div id="flaggers-{{c.id}}" class="flaggers d-none">
<strong><i class="far fa-fw fa-flag"></i> Reported by:</strong>
<pre></pre>
<ul style="padding-left:20px; margin-bottom: 0;">
{% for f in c.ordered_flags %}
<li><a style="font-weight:bold" href="{{f.user.url}}">@{{f.user.username}}</a>{% if f.reason %}: {{f.reason | safe}}{% endif %}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<div id="comment-{{c.id}}-actions" class="comment-actions{% if voted==1 %} upvoted{% elif voted==-1 %} downvoted{% endif %}">
<ul class="list-inline text-right text-md-left">
@ -311,7 +314,7 @@
{% endif %}
{% if v and v.admin_level==6 and v.id != c.author_id %}
{% if c.author.is_banned %}
{% if c.author.is_suspended %}
<li class="list-inline-item d-none d-md-inline-block"><a class="text-success" id="unexile-comment-{{c.id}}" href="javascript:void(0)" onclick="post_toast('/unban_user/{{c.author_id}}?toast=1')"><i class="fas fa-user-slash text-success fa-fw"></i>Unban user</a></li>
{% else %}
<li class="list-inline-item d-none d-md-inline-block"><a class="text-danger" id="exile-comment-{{c.id}}" href="javascript:void(0)" onclick="post_toast('/ban_user/{{c.author_id}}/?reason={{c.permalink}}')"><i class="fas fa-user-slash text-danger fa-fw"></i>Ban user</a></li>
@ -470,7 +473,7 @@
{% if v and (c.post and v.admin_level == 6) %}
{% if c.author_id != v.id %}
{% if c.author.is_banned %}
{% if c.author.is_suspended %}
<li class="list-group-item"><a class="text-success d-block" id="unexile-comment2-{{c.id}}" href="javascript:void(0)" onclick="post('/unban_user/{{c.author_id}}', function(){window.location.reload(true);})"><i class="fas fa-user-minus fa-fw text-success"></i>Unban user</a></li>
{% else %}
<li class="list-group-item"><a class="text-danger d-block" id="exile-comment2-{{c.id}}" href="javascript:void(0)" onclick="post('/ban_user/{{c.author_id}}', function(){window.location.reload(true);})"><i class="fas fa-user-minus fa-fw text-danger"></i>Ban user</a></li>

View File

@ -1034,7 +1034,7 @@
<body id="{% if request.path != '/comments' %}{% block pagetype %}frontpage{% endblock %}{% endif %}" style="overflow-x: hidden; {% if v and v.background %} background:url(/assets/images/backgrounds/{{v.background}}) no-repeat center center fixed !important; background-size: cover!important; background-color: #000!important;{% endif %}">
<a href="https://secure.transequality.org/site/Donation2?df_id=1480"><img src="/assets/images/{{'SITE_NAME' | app_config}}/{% if v %}banner.gif{% else %}cached.gif{% endif %}" width="100%"></a>
<a href="https://secure.transequality.org/site/Donation2?df_id=1480"><img src="/assets/images/{{'SITE_NAME' | app_config}}/{% if v %}banner.gif{% else %}cached.gif{% endif %}" style="padding:4px;" width="100%"></a>
{% include "header.html" %}

View File

@ -98,7 +98,7 @@
<a class="nav-link{% if request.path.endswith('/leaderboard') %} active{% endif %}" href="/leaderboard"><i class="fas fa-trophy"></i>Leaderboard</a>
</li>
<li class="nav-item">
<a class="nav-link{% if request.path.endswith('/admins') %} active{% endif %}" href="/admins"><i class="fas fa-crown"></i>admins</a>
<a class="nav-link{% if request.path.endswith('/admins') %} active{% endif %}" href="/admins"><i class="fas fa-crown"></i>Admins</a>
</li>
<li class="nav-item">
<a class="nav-link{% if request.path.endswith('/log') %} active{% endif %}" href="/log"><i class="fas fa-scroll-old"></i>Moderation Log</a>

View File

@ -159,7 +159,7 @@
{% endif %}
{% if v and v.admin_level == 6 and v.id!=p.author_id %}
{% if p.author.is_banned %}
{% if p.author.is_suspended %}
<button class="nobackground btn btn-link btn-block btn-lg text-success text-left" href="javascript:void(0)" onclick="post_toast('/unban_user/{{p.author_id}}?toast=1')"><i class="fas fa-user-minus mr-3"></i>Unban user</a></button>
{% else %}
<button class="nobackground btn btn-link btn-block btn-lg text-danger text-left" href="javascript:void(0)" onclick="post_toast('/ban_user/{{p.author_id}}?toast=1')"><i class="fas fa-user-minus mr-3"></i>Ban user</a></button>
@ -194,7 +194,7 @@
<div class="col-12">
<div id="post-{{p.id}}" class="card border-0 mt-3{% if p.is_banned %} banned{% endif %}{% if p.stickied %} stickied{% endif %}{% if voted==1 %} upvoted{% elif voted==-1 %} downvoted{% endif %}">
<div id="post-{{p.id}}" class="card border-0 mt-3{% if p.is_suspended %} banned{% endif %}{% if p.stickied %} stickied{% endif %}{% if voted==1 %} upvoted{% elif voted==-1 %} downvoted{% endif %}">
<div class="{% if p.deleted_utc > 0 %}deleted {% endif %}d-flex flex-row-reverse flex-nowrap justify-content-end">
{% if p.thumb_url and not p.embed_url %}
@ -225,7 +225,9 @@
{% if p.over_18 %}<span class="badge badge-danger text-small-extra mr-1">+18</span>{% endif %}
{% if p.private %}<span class="badge border-warning border-1 text-small-extra">unlisted</span>{% endif %}
{% if p.active_flags %}<a class="btn btn-primary" href="javascript:void(0)" style="padding:1px 5px; font-size:10px;" onclick="document.getElementById('flaggers').classList.toggle('d-none')">{{p.active_flags}} Reports</a>{% endif %}
&nbsp;<a {% if v %}href="{{p.author.url}}"{% else %}href="/logged_out{{p.author.url}}"{% endif %} style="color: #{{p.author.namecolor}}; font-weight: bold;" class="user-name"><img src="{{p.author.profile_url}}" class="profile-pic-25 mr-2"/><span {% if p.author.patron %}class="patron" style="background-color:#{{p.author.namecolor}};"{% endif %}>{{p.author.username}}</span></a>{% if p.author.customtitle %}&nbsp;<bdi style="color: #{{p.author.titlecolor}}">&nbsp;{{p.author.customtitle | safe}}</bdi>{% endif %}
{% if p.author.verified %}<i class="fas fa-badge-check align-middle ml-1" style="color:#1DA1F2" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="Verified"></i>
{% endif %}
<a {% if v %}href="{{p.author.url}}"{% else %}href="/logged_out{{p.author.url}}"{% endif %} style="color: #{{p.author.namecolor}}; font-weight: bold;" class="user-name"><img src="{{p.author.profile_url}}" class="profile-pic-25 mr-2"/><span {% if p.author.patron %}class="patron" style="background-color:#{{p.author.namecolor}};"{% endif %}>{{p.author.username}}</span></a>{% if p.author.customtitle %}&nbsp;<bdi style="color: #{{p.author.titlecolor}}">&nbsp;{{p.author.customtitle | safe}}</bdi>{% endif %}
<span data-toggle="tooltip" data-placement="bottom" id="timestamp" title="">&nbsp;{{p.age_string}}</span>
({% if p.realurl(v) %}<a href="/search/posts/?q=domain%3A{{p.domain}}&sort=new&t=all" {% if not v or v.newtabexternal %}target="_blank"{% endif %}>{{p.domain}}</a>{% else %}text post{% endif %})
@ -234,6 +236,18 @@
&nbsp;&nbsp;{{p.views}} views
</div>
{% if p.active_flags %}
<div id="flaggers" class="flaggers d-none">
<strong><i class="far fa-fw fa-flag"></i> Reported by:</strong>
<pre></pre>
<ul style="padding-left:20px; margin-bottom: 0;">
{% for f in p.ordered_flags %}
<li><a style="font-weight:bold" href="{{f.user.url}}">@{{f.user.username}}</a>{% if f.reason %}: {{f.reason | safe}}{% endif %}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% if p.realurl(v) %}
<h1 id="post-title" class="card-title post-title text-left mb-md-3"><a {% if not v or v.newtabexternal %}target="_blank"{% endif %} rel="noopener noreferrer" href="{{p.realurl(v)}}" rel="nofollow noopener">{{title | safe}}</a></h1>
{% else %}
@ -277,7 +291,7 @@
</div>
{% if v and v.id==p.author_id and not v.is_banned %}
{% if v and v.id==p.author_id and not v.is_suspended %}
<div id="edit-post-body-{{p.id}}" class="d-none comment-write collapsed child">
<form id="post-edit-form-{{p.id}}" class="d-flex flex-column" action="/edit_post/{{p.id}}" method="post" class="input-group">
<input type="hidden" name="formkey" value="{{v.formkey}}">
@ -390,7 +404,7 @@
{% endif %}
{% if v.admin_level >=3 and v.id!=p.author_id %}
{% if p.author.is_banned %}
{% if p.author.is_suspended %}
<li class="list-inline-item"><a class="text-success" href="javascript:void(0)" onclick="post_toast('/unban_user/{{p.author_id}}')"
><i class="fas fa-user-slash text-success"></i>Unban user</a></li>
{% else %}
@ -423,7 +437,7 @@
<div id="voting" class="voting d-none d-md-block mb-auto">
<div id="post-{{p.id}}-up" tabindex="0" class="arrow-up mx-auto" onclick="location.href='/login?redirect={{request.path | urlencode}}';">
</div>
<span id="post-{{p.id}}-score-none" class="score text-muted"{% if not p.is_banned %} data-toggle="tooltip" data-placement="right" data-original-title="+{{ups}} | -{{downs}}"{% endif %}>{{score}}</span>
<span id="post-{{p.id}}-score-none" class="score text-muted"{% if not p.is_suspended %} data-toggle="tooltip" data-placement="right" data-original-title="+{{ups}} | -{{downs}}"{% endif %}>{{score}}</span>
<div id="post-{{p.id}}-down" tabindex="0" class="arrow-down mx-auto" onclick="location.href='/login?redirect={{request.path | urlencode}}';">
</div>
</div>
@ -494,18 +508,6 @@
</div>
{% if p.active_flags %}
<div id="flaggers" class="flaggers d-none">
<strong><i class="far fa-fw fa-flag"></i> Reported by:</strong>
<pre></pre>
<ul style="padding-left:20px; margin-bottom: 0;">
{% for f in p.ordered_flags %}
<li><a style="font-weight:bold" href="{{f.user.url}}">@{{f.user.username}}</a>{% if f.reason %}: {{f.reason | safe}}{% endif %}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<div class="row border-md-0 comment-section pb-3">
<div class="col border-top">
<div class="comments-count py-3">
@ -569,7 +571,7 @@
</form>
</div>
{% if not v and not p.is_banned %}
{% if not v and not p.is_suspended %}
<div class="comment-write mb-3">
<textarea class="comment-box form-control rounded" name="body" aria-label="With textarea" placeholder="Add your comment..." rows="3" onclick="location.href='/login?redirect={{request.path | urlencode}}';"></textarea>
</div>

View File

@ -11,7 +11,7 @@
{% block title %}
<title>{{p.realtitle(v)}}</title>
{% if p.is_banned %}
{% if p.is_suspended %}
<meta name="description" content="[removed by admins]">
{% else %}
<meta name="description" content="[deleted by user]">
@ -32,7 +32,7 @@
</form>
{% endif %}
{% if v.admin_level >=1 and v.admin_level > p.author.admin_level %}
{% if p.is_banned %}
{% if p.is_suspended %}
<form action="/unban_post/{{p.id}}" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<input type="submit" value="Approve Post">
@ -53,10 +53,10 @@
<div class="col-12">
<div id="post-{{p.id}}" class="card d-flex flex-row-reverse flex-nowrap justify-content-end border-0 p-0 {% if voted==1 %} upvoted{% elif voted==-1 %} downvoted{% endif %}">
<div class="card-block my-md-auto{% if p.is_banned %} banned{% endif %}">
<div class="post-meta text-left d-block d-md-none mb-1">{% if p.over_18 %}<span class="badge badge-danger">+18</span> {% endif %}{% if p.is_banned %}[Removed by admins]{% else %}[Deleted by user]{% endif %}</div>
<div class="card-block my-md-auto{% if p.is_suspended %} banned{% endif %}">
<div class="post-meta text-left d-block d-md-none mb-1">{% if p.over_18 %}<span class="badge badge-danger">+18</span> {% endif %}{% if p.is_suspended %}[Removed by admins]{% else %}[Deleted by user]{% endif %}</div>
<h5 class="card-title post-title text-left mb-0 mb-md-1">{{p.realtitle(v)}}</h5>
<div class="post-meta text-left d-none d-md-block">{% if p.over_18 %}<span class="badge badge-danger">+18</span> {% endif %}{% if p.is_banned %}[Removed by admins]{% else %}[Deleted by user]{% endif %}</div>
<div class="post-meta text-left d-none d-md-block">{% if p.over_18 %}<span class="badge badge-danger">+18</span> {% endif %}{% if p.is_suspended %}[Removed by admins]{% else %}[Deleted by user]{% endif %}</div>
</div>

View File

@ -20,7 +20,7 @@
{% endif %}
<div id="post-{{p.id}}" class="card{% if p.is_banned %} banned{% endif %}{% if p.deleted_utc > 0 %} deleted{% endif %}{% if p.stickied %} stickied{% endif %}{% if voted==1 %} upvoted{% elif voted==-1 %} downvoted{% endif %}{% if p.over_18 %} nsfw{% endif %}">
<div id="post-{{p.id}}" class="card{% if p.is_suspended %} banned{% endif %}{% if p.deleted_utc > 0 %} deleted{% endif %}{% if p.stickied %} stickied{% endif %}{% if voted==1 %} upvoted{% elif voted==-1 %} downvoted{% endif %}{% if p.over_18 %} nsfw{% endif %}">
<div class="d-flex flex-row-reverse flex-md-row flex-nowrap justify-content-end">
@ -33,7 +33,7 @@
<div class="mx-auto arrow-up post-{{p.id}}-up active"></div>
{% endif %}
<span id="post-score-{{p.id}}" class="score post-score-{{p.id}} {% if voted==1 %}score-up{% elif voted==-1%}score-down{% endif %}"{% if not p.is_banned %} data-toggle="tooltip" data-placement="right" data-original-title="+{{ups}} | -{{downs}}"{% endif %}>{{score}}</span>
<span id="post-score-{{p.id}}" class="score post-score-{{p.id}} {% if voted==1 %}score-up{% elif voted==-1%}score-down{% endif %}"{% if not p.is_suspended %} data-toggle="tooltip" data-placement="right" data-original-title="+{{ups}} | -{{downs}}"{% endif %}>{{score}}</span>
{% if voted==-1 %}
<div class="text-muted mx-auto arrow-down post-{{p.id}}-down active"></div>
@ -43,7 +43,7 @@
<div id="post-{{p.id}}-up" tabindex="0" data-id-up="{{p.id}}" data-content-type="post" class="mx-auto arrow-up upvote-button post-{{p.id}}-up {% if voted==1 %}active{% endif %}"></div>
<span id="post-score-{{p.id}}" class="score post-score-{{p.id}} {% if voted==1 %}score-up{% elif voted==-1%}score-down{% endif %}"{% if not p.is_banned %} data-toggle="tooltip" data-placement="right" data-original-title="+{{ups}} | -{{downs}}"{% endif %}>{{score}}</span>
<span id="post-score-{{p.id}}" class="score post-score-{{p.id}} {% if voted==1 %}score-up{% elif voted==-1%}score-down{% endif %}"{% if not p.is_suspended %} data-toggle="tooltip" data-placement="right" data-original-title="+{{ups}} | -{{downs}}"{% endif %}>{{score}}</span>
<div id="post-{{p.id}}-down" tabindex="0" data-id-down="{{p.id}}" data-content-type="post" class="text-muted mx-auto arrow-down downvote-button post-{{p.id}}-down {% if voted==-1 %}active{% endif %}"></div>
@ -51,7 +51,7 @@
<div id="post-{{p.id}}-up" tabindex="0" class="mx-auto arrow-up" onclick="location.href='/login';"></div>
<span id="post-{{p.id}}-score-none" class="score"{% if not p.is_banned %} data-toggle="tooltip" data-placement="right" data-original-title="+{{ups}} | -{{downs}}"{% endif %}>{{score}}</span>
<span id="post-{{p.id}}-score-none" class="score"{% if not p.is_suspended %} data-toggle="tooltip" data-placement="right" data-original-title="+{{ups}} | -{{downs}}"{% endif %}>{{score}}</span>
<div id="post-{{p.id}}-down" tabindex="0" class="text-muted mx-auto arrow-down" onclick="location.href='/login';"></div>
@ -106,7 +106,9 @@
{% if p.is_blocked %}<i class="fas fa-user-minus text-danger" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="This user is blocking you."></i>{% endif %}
{% if p.private %}<span class="badge border-warning border-1 text-small-extra">unlisted</span>{% endif %}
{% if p.active_flags %}<a class="btn btn-primary" href="javascript:void(0)" style="padding:1px 5px; font-size:10px;" onclick="document.getElementById('flaggers-{{p.id}}').classList.toggle('d-none')">{{p.active_flags}} Reports</a>{% endif %}
&nbsp;<a {% if v %}href="{{p.author.url}}"{% else %}href="/logged_out{{p.author.url}}"{% endif %} style="color: #{{p.author.namecolor}}; font-weight: bold;" class="user-name"><img src="{{p.author.profile_url}}" class="profile-pic-25 mr-2"/><span {% if p.author.patron %}class="patron" style="background-color:#{{p.author.namecolor}};"{% endif %}>{{p.author.username}}</span></a>{% if p.author.customtitle %}<bdi style="color: #{{p.author.titlecolor}}">&nbsp;&nbsp;{{p.author.customtitle | safe}}</bdi>{% endif %}
{% if p.author.verified %}<i class="fas fa-badge-check align-middle ml-1" style="color:#1DA1F2" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="Verified"></i>
{% endif %}
<a {% if v %}href="{{p.author.url}}"{% else %}href="/logged_out{{p.author.url}}"{% endif %} style="color: #{{p.author.namecolor}}; font-weight: bold;" class="user-name"><img src="{{p.author.profile_url}}" class="profile-pic-25 mr-2"/><span {% if p.author.patron %}class="patron" style="background-color:#{{p.author.namecolor}};"{% endif %}>{{p.author.username}}</span></a>{% if p.author.customtitle %}<bdi style="color: #{{p.author.titlecolor}}">&nbsp;&nbsp;{{p.author.customtitle | safe}}</bdi>{% endif %}
<span data-toggle="tooltip" data-placement="bottom" id="timestamp-{{p.id}}" title="">&nbsp;{{p.age_string}}</span>
&nbsp;
({% if p.realurl(v) %}<a href="/search/posts/?q=domain%3A{{p.domain}}&sort=new&t=all" target="_blank">{{p.domain}}</a>{% else %}text post{% endif %})
@ -199,7 +201,7 @@
{% endif %}
{% if v.admin_level >=3 and v.id!=p.author_id %}
{% if p.author.is_banned %}
{% if p.author.is_suspended %}
<li class="list-inline-item"><a class="text-danger" id="unexile2-user-{{p.id}}" href="javascript:void(0)" onclick="post_toast('/unban_user/{{p.author_id}}')"
><i class="fas fa-user-slash"></i>Unban user</a></li>
{% else %}
@ -246,7 +248,7 @@
</span>
{% endif %}
<span id="post-score-{{p.id}}-mobile" class="score post-score-{{p.id}} {% if voted==1 %}score-up{% elif voted==-1%}score-down{% endif %}"{% if not p.is_banned %} data-toggle="tooltip" data-placement="top" data-original-title="+{{ups}} | -{{downs}}"{% endif %}>{{score}}</span>
<span id="post-score-{{p.id}}-mobile" class="score post-score-{{p.id}} {% if voted==1 %}score-up{% elif voted==-1%}score-down{% endif %}"{% if not p.is_suspended %} data-toggle="tooltip" data-placement="top" data-original-title="+{{ups}} | -{{downs}}"{% endif %}>{{score}}</span>
{% if voted==-1 %}
<span class="ml-2 my-0 arrow-down post-{{p.id}}-down active">
@ -261,7 +263,7 @@
<span id="post-{{p.id}}-up-mobile" tabindex="0" data-id-up="{{p.id}}" data-content-type="post" class="mr-2 arrow-up upvote-button post-{{p.id}}-up {% if voted==1 %}active{% endif %}">
</span>
<span id="post-score-{{p.id}}-mobile" class="score post-score-{{p.id}} {% if voted==1 %}score-up{% elif voted==-1%}score-down{% endif %}"{% if not p.is_banned %} data-toggle="tooltip" data-placement="top" data-original-title="+{{ups}} | -{{downs}}"{% endif %}>{{score}}</span>
<span id="post-score-{{p.id}}-mobile" class="score post-score-{{p.id}} {% if voted==1 %}score-up{% elif voted==-1%}score-down{% endif %}"{% if not p.is_suspended %} data-toggle="tooltip" data-placement="top" data-original-title="+{{ups}} | -{{downs}}"{% endif %}>{{score}}</span>
<span id="post-{{p.id}}-down-mobile" tabindex="0" data-id-down="{{p.id}}" data-content-type="post" class="ml-2 my-0 arrow-down downvote-button post-{{p.id}}-down {% if voted==-1 %}active{% endif %}">
</span>
@ -273,7 +275,7 @@
<i class="fas fa-arrow-alt-up mx-0" aria-hidden="true"></i>
</span>
<span id="post-score-{{p.id}}-mobile" class="score"{% if not p.is_banned %} data-toggle="tooltip" data-placement="top" data-original-title="+{{ups}} | -{{downs}}"{% endif %}>{{score}}</span>
<span id="post-score-{{p.id}}-mobile" class="score"{% if not p.is_suspended %} data-toggle="tooltip" data-placement="top" data-original-title="+{{ups}} | -{{downs}}"{% endif %}>{{score}}</span>
<span id="arrow-{{p.id}}-mobile-down" tabindex="0" class="arrow-mobile-down ml-2 my-0" onclick="location.href='/login';">
<i class="fas fa-arrow-alt-down mx-0" aria-hidden="true"></i>
@ -359,7 +361,7 @@
{% endif %}
{% if v and v.admin_level == 6 and v.id!=p.author_id %}
{% if p.author.is_banned %}
{% if p.author.is_suspended %}
<button class="nobackground btn btn-link btn-block btn-lg text-success text-left" href="javascript:void(0)" onclick="post_toast('/unban_user/{{p.author_id}}?toast=1')"><i class="fas fa-user-minus mr-3"></i>Unban user</a></button>
{% else %}
<button class="nobackground btn btn-link btn-block btn-lg text-danger text-left" href="javascript:void(0)" onclick="post_toast('/ban_user/{{p.author_id}}?toast=1')"><i class="fas fa-user-minus mr-3"></i>Ban user</a></button>

View File

@ -21,8 +21,8 @@
{% endif %}
</div>
{% if not hide_bios %}
<div class="card-text">{{u.bio_html | safe}}</div>
{% if not hide_bios and u.bio_html %}
<div class="card-text">{{u.bio_html | safe}}</div>
{% endif %}
</div>
</div>

View File

@ -114,10 +114,10 @@
<i class="fad fa-user-tag text-info align-middle ml-2" data-toggle="tooltip" data-placement="bottom" title="Original Username: @{{u.original_username}}"></i>
</span>
{% endif %}
{% if u.verified %}<span><i class="fas fa-badge-check align-middle ml-1" style="color:#1DA1F2" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="Verified"></i></span>{% endif %}
{% if u.admin_level > 1 or (u.admin_level == 1 and (not v or v.admin_level < 2)) %}
<span>
<i class="fas fa-broom text-admin align-middle ml-2" data-toggle="tooltip" data-placement="bottom" title="Admin"></i>
{% if u.verified %}<i class="fas fa-badge-check align-middle ml-1" style="color:#1DA1F2" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="Verified"></i>{% endif %}
</span>
{% elif u.admin_level == 1 %}
<span>
@ -238,7 +238,7 @@
</div>
<pre></pre>
{% if u.is_banned %}
{% if u.is_suspended %}
<form action="/unban_user/{{u.id}}/" method="post" action="">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<div class="custom-control custom-checkbox">
@ -357,10 +357,10 @@
<i class="fad fa-user-tag text-info align-middle ml-2" data-toggle="tooltip" data-placement="bottom" title="Original Username: @{{u.original_username}}"></i>
</span>
{% endif %}
{% if u.verified %}<span><i class="fas fa-badge-check align-middle ml-1" style="color:#1DA1F2" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="Verified"></i></span>{% endif %}
{% if u.admin_level > 1 or (u.admin_level == 1 and (not v or v.admin_level < 2)) %}
<span>
<i class="fas fa-broom text-admin align-middle ml-2" data-toggle="tooltip" data-placement="bottom" title="Admin"></i>
{% if u.verified %}<i class="fas fa-badge-check align-middle ml-1" style="color:#1DA1F2" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="Verified"></i>{% endif %}
</span>
{% elif u.admin_level == 1 %}
<span>
@ -457,7 +457,7 @@
</div>
<pre></pre>
{% if u.is_banned %}
{% if u.is_suspended %}
<form action="/unban_user/{{u.id}}" method="post">
<input type="hidden" name="formkey", value="{{v.formkey}}">
<br />