forked from rDrama/rDrama
1
0
Fork 0

Compare commits

...

43 Commits

Author SHA1 Message Date
Aevann 44eaad5e43 fix 500 error 2024-02-16 23:59:29 +02:00
Aevann 95ec09a6b3 make wpd report queue usable 2024-02-16 23:58:27 +02:00
Aevann aa67af527d its forced 8 now 2024-02-16 23:27:56 +02:00
Aevann e200a011c6 fix this https://rdrama.net/h/changelog/post/165657/changelog-megathread-marseynotes/5958269#context 2024-02-16 23:13:42 +02:00
Aevann 9009fa7d92 fix notifs 2024-02-16 23:05:06 +02:00
Aevann 0f9ed086ca move USER_BADGES to JL1 2024-02-16 23:03:34 +02:00
Aevann 31e263fe9d fix 500 error on devrama 2024-02-16 22:56:49 +02:00
Aevann 26b9feea2c fix cron error 2024-02-16 22:55:26 +02:00
Aevann 7624413b33 fix 500 error 2024-02-16 22:53:40 +02:00
Aevann 8707129a2e if not IS_LOCALHOST: 2024-02-16 22:50:32 +02:00
Aevann df2b5856fe add lemmy mention notifs 2024-02-16 22:42:42 +02:00
Aevann 61afbb5bf6 support .one 2024-02-16 21:34:21 +02:00
Aevann 1aae6f1cfb pin joan posts 2024-02-16 20:08:02 +02:00
Aevann d5621428db fix bio 2024-02-16 19:06:55 +02:00
Aevann eb39afc999 allow jannies to change author 2024-02-16 19:02:43 +02:00
Aevann 4201224595 remove useless name="" 2024-02-16 19:00:40 +02:00
Aevann a767ec2767 allow ??? in author field 2024-02-16 18:52:18 +02:00
Aevann e755205da8 fix this https://rdrama.net/h/singapore/post/246430/budget-2024-all-sporean-households-to/5955314#context 2024-02-16 17:37:34 +02:00
Aevann 667bdcc0bf allow "" - or 2024-02-16 17:20:17 +02:00
Aevann 638f4350be nsfw logic consistency 2024-02-16 16:50:03 +02:00
Aevann 01e6942e5c remove unnecessary exact parameter (quotation marks work) 2024-02-16 16:41:11 +02:00
SneedBot 19bc67ead7 sneed 2024-02-16 14:31:47 +00:00
Aevann c4351d97c0 capitalization consistency 2024-02-16 16:31:34 +02:00
SneedBot f6e0f81f2c sneed 2024-02-16 14:29:52 +00:00
Aevann f8614d79cd make top poster of the day get a badge 2024-02-16 16:27:28 +02:00
SneedBot 7ceaf62183 sneed 2024-02-16 14:22:13 +00:00
Aevann 6976619282 remove line 2024-02-16 16:21:17 +02:00
SneedBot 0ae67b83ab sneed 2024-02-16 14:16:23 +00:00
Aevann c8c4652300 do this https://rdrama.net/h/changelog/post/165657/changelog-megathread-marseynotes/5944237#context 2024-02-16 15:56:48 +02:00
Aevann 32ca7d1a69 add clearer error messages 2024-02-16 15:23:48 +02:00
Aevann c3d0b2c60a consistent capitalization 2024-02-16 15:08:05 +02:00
Aevann dc979659e9 fix this https://rdrama.net/h/changelog/post/165657/changelog-megathread-marseynotes/5954720#context 2024-02-16 15:06:49 +02:00
Aevann 91d7d16d9f hide ricardo for loggedout 2024-02-16 14:50:44 +02:00
Aevann 892137f23b do this https://rdrama.net/h/countryclub/post/79285/-/4426657#context 2024-02-16 14:49:26 +02:00
Aevann 00a2497118 shorter if conditions 2024-02-16 14:36:45 +02:00
Aevann 1e289e8941 pin autodrama and use PIZZASHILL_ID var 2024-02-16 14:22:11 +02:00
Aevann aa28bbb6f2 add more filters 2024-02-16 14:18:06 +02:00
Aevann ae0ed85301 fix 500 error 2024-02-16 14:12:37 +02:00
Aevann e6c2950666 rename distinguish_level to distinguished 2024-02-16 14:11:13 +02:00
SneedBot 5945ecc9b6 sneed 2024-02-16 12:00:15 +00:00
Aevann 821c606b8d move mods and exiles to hole_relationships.py 2024-02-16 13:44:38 +02:00
Aevann c2918d67f0 consistency 2024-02-16 13:44:37 +02:00
SneedBot 826ad536a1 sneed 2024-02-16 10:00:14 +00:00
56 changed files with 389 additions and 339 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1015 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1015 KiB

View File

@ -5,6 +5,7 @@ function approve_emoji(t, name) {
"tags": document.getElementById(`${name}-tags`).value,
"name": document.getElementById(`${name}-name`).value,
"kind": document.getElementById(`${name}-kind`).value,
"author": document.getElementById(`${name}-author`).value,
"nsfw": document.getElementById(`${name}-nsfw`).checked,
},
() => {

View File

@ -182,7 +182,7 @@ class Comment(Base):
ghost = Column(Boolean, default=False)
bannedfor = Column(String)
chuddedfor = Column(String)
distinguish_level = Column(Integer, default=0)
distinguished = Column(Boolean, default=False)
deleted_utc = Column(Integer, default=0)
is_approved = Column(Integer, ForeignKey("users.id"))
level = Column(Integer, default=1)
@ -383,7 +383,7 @@ class Comment(Base):
'is_nsfw': self.nsfw,
'permalink': f'/comment/{self.id}#context',
'stickied': self.stickied,
'distinguish_level': self.distinguish_level,
'distinguished': self.distinguished,
'post_id': self.post.id if self.post else 0,
'score': self.score,
'upvotes': self.upvotes,

View File

@ -1,23 +0,0 @@
import time
from sqlalchemy import Column, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.sql.sqltypes import *
from files.classes import Base
class Exile(Base):
__tablename__ = "exiles"
user_id = Column(Integer, ForeignKey("users.id"), primary_key=True)
hole = Column(String, ForeignKey("holes.name"), primary_key=True)
exiler_id = Column(Integer, ForeignKey("users.id"))
created_utc = Column(Integer)
exiler = relationship("User", primaryjoin="User.id==Exile.exiler_id")
def __init__(self, *args, **kwargs):
if "created_utc" not in kwargs: kwargs["created_utc"] = int(time.time())
super().__init__(*args, **kwargs)
def __repr__(self):
return f"<{self.__class__.__name__}(user_id={self.user_id}, hole={self.hole})>"

View File

@ -4,7 +4,7 @@ import time
from sqlalchemy import Column
from sqlalchemy.ext.mutable import MutableList
from sqlalchemy.orm import relationship, deferred
from sqlalchemy.types import VARCHAR, Boolean, Integer
from sqlalchemy.types import *
from sqlalchemy.dialects.postgresql import ARRAY
from files.classes import Base
@ -15,20 +15,20 @@ from .hole_relationship import *
class Hole(Base):
__tablename__ = "holes"
name = Column(VARCHAR(HOLE_NAME_COLUMN_LENGTH), primary_key=True)
sidebar = Column(VARCHAR(HOLE_SIDEBAR_COLUMN_LENGTH))
sidebar_html = Column(VARCHAR(HOLE_SIDEBAR_HTML_COLUMN_LENGTH))
sidebarurls = Column(MutableList.as_mutable(ARRAY(VARCHAR(HOLE_BANNER_URL_COLUMN_LENGTH))), default=MutableList([]))
bannerurls = Column(MutableList.as_mutable(ARRAY(VARCHAR(HOLE_BANNER_URL_COLUMN_LENGTH))), default=MutableList([]))
marseyurl = Column(VARCHAR(HOLE_MARSEY_URL_LENGTH))
css = deferred(Column(VARCHAR(CSS_LENGTH_LIMIT)))
name = Column(String, primary_key=True)
sidebar = Column(String)
sidebar_html = Column(String)
sidebarurls = Column(MutableList.as_mutable(ARRAY(String)), default=MutableList([]))
bannerurls = Column(MutableList.as_mutable(ARRAY(String)), default=MutableList([]))
marseyurl = Column(String)
css = deferred(Column(String))
stealth = Column(Boolean, default=False)
public_use = Column(Boolean, default=False)
created_utc = Column(Integer)
if SITE_NAME == 'WPD':
snappy_quotes = None
else:
snappy_quotes = deferred(Column(VARCHAR(HOLE_SNAPPY_QUOTES_LENGTH)))
snappy_quotes = deferred(Column(String))
blocks = relationship("HoleBlock", primaryjoin="HoleBlock.hole==Hole.name")
followers = relationship("HoleFollow", primaryjoin="HoleFollow.hole==Hole.name")

View File

@ -1,7 +1,7 @@
import time
from sqlalchemy import Column, ForeignKey
from sqlalchemy.orm import declared_attr
from sqlalchemy.orm import relationship
from sqlalchemy.sql.sqltypes import *
from files.classes import Base
@ -10,17 +10,9 @@ class HoleRelationship(Base):
__tablename__ = NotImplemented
__abstract__ = True
@declared_attr
def user_id(self):
return Column(Integer, ForeignKey("users.id"), primary_key=True)
@declared_attr
def hole(self):
return Column(String(20), ForeignKey("holes.name"), primary_key=True)
@declared_attr
def created_utc(self):
return Column(Integer)
user_id = Column(Integer, ForeignKey("users.id"), primary_key=True)
hole = Column(String, ForeignKey("holes.name"), primary_key=True)
created_utc = Column(Integer)
def __init__(self, *args, **kwargs):
if "created_utc" not in kwargs: kwargs["created_utc"] = int(time.time())
@ -37,3 +29,11 @@ class HoleBlock(HoleRelationship):
class HoleFollow(HoleRelationship):
__tablename__ = "hole_follows"
class Mod(HoleRelationship):
__tablename__ = "mods"
class Exile(HoleRelationship):
__tablename__ = "exiles"
exiler_id = Column(Integer, ForeignKey("users.id"))
exiler = relationship("User", primaryjoin="User.id==Exile.exiler_id")

View File

@ -1,20 +0,0 @@
import time
from sqlalchemy import Column, ForeignKey
from sqlalchemy.sql.sqltypes import *
from files.classes import Base
from files.helpers.lazy import *
class Mod(Base):
__tablename__ = "mods"
user_id = Column(Integer, ForeignKey("users.id"), primary_key=True)
hole = Column(String, ForeignKey("holes.name"), primary_key=True)
created_utc = Column(Integer)
def __init__(self, *args, **kwargs):
if "created_utc" not in kwargs: kwargs["created_utc"] = int(time.time())
super().__init__(*args, **kwargs)
def __repr__(self):
return f"<{self.__class__.__name__}(user_id={self.user_id}, hole={self.hole})>"

View File

@ -38,7 +38,7 @@ class Post(Base):
effortpost = Column(Boolean, default=False)
views = Column(Integer, default=0)
deleted_utc = Column(Integer, default=0)
distinguish_level = Column(Integer, default=0)
distinguished = Column(Boolean, default=False)
stickied = Column(String)
stickied_utc = Column(Integer)
hole_pinned = Column(String)
@ -254,7 +254,7 @@ class Post(Base):
'downvotes': self.downvotes,
'stickied': self.stickied,
'private' : self.private,
'distinguish_level': self.distinguish_level,
'distinguished': self.distinguished,
'voted': self.voted if hasattr(self, 'voted') else 0,
'reports': reports,
}
@ -269,7 +269,10 @@ class Post(Base):
if v and v.poor:
return 0
if self.distinguish_level and SITE_NAME == 'WPD':
if self.distinguished and SITE_NAME == 'WPD':
return 0
if not v and kind == "ricardo":
return 0
num = len([x for x in self.awards if x.kind == kind])
@ -420,4 +423,4 @@ class Post(Base):
if self.hole == 'chudrama':
return v.admin_level >= PERMS['POST_COMMENT_MODERATION']
else:
return v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or (self.hole and v.mods_hole(self.hole)) or self.author_id == v.id
return v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or (v.mods_hole(self.hole)) or self.author_id == v.id

View File

@ -26,10 +26,8 @@ from .alts import Alt
from .award import AwardRelationship
from .badges import *
from .clients import *
from .exiles import *
from .follows import *
from .hats import *
from .mod import *
from .mod_logs import *
from .notifications import Notification
from .saves import *
@ -138,7 +136,7 @@ class User(Base):
last_viewed_modmail_notifs = Column(Integer, default=0)
last_viewed_post_notifs = Column(Integer, default=0)
last_viewed_log_notifs = Column(Integer, default=0)
last_viewed_reddit_notifs = Column(Integer, default=0)
last_viewed_offsite_notifs = Column(Integer, default=0)
bite = Column(Integer, default=0)
owoify = Column(Integer, default=0)
sharpen = Column(Integer, default=0)
@ -204,7 +202,7 @@ class User(Base):
kwargs["last_viewed_modmail_notifs"] = kwargs["created_utc"]
kwargs["last_viewed_post_notifs"] = kwargs["created_utc"]
kwargs["last_viewed_log_notifs"] = kwargs["created_utc"]
kwargs["last_viewed_reddit_notifs"] = kwargs["created_utc"]
kwargs["last_viewed_offsite_notifs"] = kwargs["created_utc"]
super().__init__(**kwargs)
@ -431,6 +429,7 @@ class User(Base):
@lazy
def mods_hole(self, hole):
if not hole: return False
if self.is_permabanned or self.shadowbanned: return False
if hole == 'test'and self.truescore >= TRUESCORE_MINIMUM: return True
if self.admin_level >= PERMS['MODS_EVERY_HOLE']: return True
@ -557,8 +556,8 @@ class User(Base):
@property
@lazy
def can_view_offsitementions(self):
return self.offsitementions or self.admin_level >= PERMS['NOTIFICATIONS_REDDIT']
def can_view_offsite_mentions(self):
return self.has_badge(140) or self.admin_level >= PERMS['NOTIFICATIONS_OFFSITE']
@lazy
def can_edit(self, target):
@ -787,7 +786,7 @@ class User(Base):
Comment.deleted_utc == 0,
)
return notifs.count() + self.modmail_notifications_count + self.post_notifications_count + self.modaction_notifications_count + self.reddit_notifications_count
return notifs.count() + self.modmail_notifications_count + self.post_notifications_count + self.modaction_notifications_count + self.offsite_notifications_count
@property
@lazy
@ -797,7 +796,7 @@ class User(Base):
- self.modmail_notifications_count \
- self.post_notifications_count \
- self.modaction_notifications_count \
- self.reddit_notifications_count
- self.offsite_notifications_count
@property
@lazy
@ -886,13 +885,13 @@ class User(Base):
@property
@lazy
def reddit_notifications_count(self):
if not self.can_view_offsitementions or (SITE == "watchpeopledie.tv" and self.id == AEVANN_ID):
def offsite_notifications_count(self):
if not self.can_view_offsite_mentions or (SITE == "watchpeopledie.tv" and self.id == AEVANN_ID):
return 0
return g.db.query(Comment).filter(
Comment.created_utc > self.last_viewed_reddit_notifs,
Comment.created_utc > self.last_viewed_offsite_notifs,
Comment.is_banned == False, Comment.deleted_utc == 0,
Comment.body_html.like('%<p>New site mention%<a href="https://old.reddit.com/r/%'),
Comment.body_html.like('%<p>New site mention by <a href=%'),
Comment.parent_post == None, Comment.author_id == AUTOJANNY_ID).count()
@property
@ -909,8 +908,8 @@ class User(Base):
return 'posts'
elif self.modaction_notifications_count > 0:
return 'modactions'
elif self.reddit_notifications_count > 0:
return 'reddit'
elif self.offsite_notifications_count > 0:
return 'offsite'
return ''
@property
@ -922,7 +921,7 @@ class User(Base):
'modmail': '#f15387',
'posts': '#0000ff',
'modactions': '#1ad80d',
'reddit': '#805ad5',
'offsite': '#805ad5',
}
return colors[self.notifications_do] if self.notifications_do \
else colors['']
@ -1288,11 +1287,6 @@ class User(Base):
def unblockable(self):
return self.has_badge(87)
@property
@lazy
def offsitementions(self):
return self.has_badge(140)
@lazy
def pride_username(self, v):
return not (v and v.poor) and self.has_badge(303)

View File

@ -12,7 +12,7 @@ from files.classes.mod_logs import ModAction
from files.classes.notifications import Notification
from files.classes.polls import CommentOption, PostOption
from files.classes.award import AwardRelationship
from files.classes.exiles import Exile
from files.classes.hole_relationship import Exile
from files.helpers.alerts import send_repeatable_notification, push_notif
from files.helpers.config.const import *
@ -241,7 +241,7 @@ def execute_snappy(post, v):
if len(body_html) < COMMENT_BODY_HTML_LENGTH_LIMIT:
c = Comment(author_id=SNAPPY_ID,
distinguish_level=6,
distinguished=True,
parent_post=post.id,
level=1,
nsfw=False,
@ -314,7 +314,7 @@ def execute_zozbot(c, level, post, v):
body_html='<p class="zozbot">zoz</p>',
top_comment_id=c.top_comment_id,
ghost=c.ghost,
distinguish_level=6
distinguished=True
)
g.db.add(c2)
@ -332,7 +332,7 @@ def execute_zozbot(c, level, post, v):
body_html='<p class="zozbot">zle</p>',
top_comment_id=c.top_comment_id,
ghost=c.ghost,
distinguish_level=6
distinguished=True
)
g.db.add(c3)
@ -349,7 +349,7 @@ def execute_zozbot(c, level, post, v):
body_html='<p class="zozbot">zozzle</p>',
top_comment_id=c.top_comment_id,
ghost=c.ghost,
distinguish_level=6
distinguished=True
)
g.db.add(c4)

View File

@ -19,7 +19,7 @@ def create_comment(text_html):
new_comment = Comment(author_id=AUTOJANNY_ID,
parent_post=None,
body_html=text_html,
distinguish_level=6,
distinguished=True,
is_bot=True)
g.db.add(new_comment)
g.db.flush()
@ -310,7 +310,7 @@ def alert_admins(body):
level=1,
body_html=body_html,
sentto=MODMAIL_ID,
distinguish_level=6,
distinguished=True,
is_bot=True
)
g.db.add(new_comment)

View File

@ -4,7 +4,7 @@ from files.classes.comment import Comment
from files.classes.hole import Hole
from flask import request
words_to_hide = ('israel', 'palestin', 'muslim', 'islam', 'hamas', 'jew', 'gaza', 'rafah', 'isis', 'terror', 'iraq')
words_to_hide = ('israel', 'isreal', 'palestin', 'muslim', 'islam', 'hamas', 'jew', 'zion', 'gaza', 'rafah', 'isis', 'terror', 'iraq', 'allah', 'mohammad', 'muhammad', 'mohammed', 'muhammed', 'mohamad', 'muhamad', 'mohamed', 'muhamed')
def can_see(user, other):
if isinstance(other, (Post, Comment)):

View File

@ -132,14 +132,14 @@ GIRL_PHRASES = [
patron = "Patron"
REDDIT_NOTIFS_SITE = set()
OFFSITE_NOTIF_QUERIES = set()
REDDIT_NOTIFS_USERS = {}
if len(SITE_NAME) > 5:
REDDIT_NOTIFS_SITE.add(SITE_NAME.lower())
OFFSITE_NOTIF_QUERIES.add(SITE_NAME.lower())
if not IS_LOCALHOST:
REDDIT_NOTIFS_SITE.add(SITE)
OFFSITE_NOTIF_QUERIES.add(SITE)
TAGLINES = ()
@ -154,7 +154,7 @@ PERMS = { # Minimum admin_level to perform action.
'BYPASS_CHAT_TRUESCORE_REQUIREMENT': 1,
'BYPASS_ANTISPAM_CHECKS': 1,
'WARN_ON_FAILED_LOGIN': 1,
'NOTIFICATIONS_REDDIT': 1,
'NOTIFICATIONS_OFFSITE': 1,
'NOTIFICATIONS_SPECIFIC_WPD_COMMENTS': 1,
'MESSAGE_BLOCKED_USERS': 1,
'ADMIN_MOP_VISIBLE': 1,
@ -175,9 +175,9 @@ PERMS = { # Minimum admin_level to perform action.
'ENABLE_VOTE_BUTTONS_ON_USER_PAGE': 1,
'NOTIFICATIONS_MODERATOR_ACTIONS': 1,
'EXEMPT_FROM_IP_LOGGING': 1,
'USER_BADGES': 1,
'IS_PERMA_PROGSTACKED': 2,
'USER_BADGES': 2,
'USER_LINK': 2,
'USER_CHANGE_FLAIR': 2,
'LOTTERY_VIEW_PARTICIPANTS': 2,
@ -316,10 +316,10 @@ if SITE_NAME == 'rDrama':
'atheism',
}
REDDIT_NOTIFS_SITE.update({'marsey', 'r/drama', 'justice4darrell', 'cringetopia.org'})
OFFSITE_NOTIF_QUERIES.update({'marsey', 'r/drama', 'justice4darrell', 'cringetopia.org'})
elif SITE_NAME == 'WPD':
REDDIT_NOTIFS_SITE.update({'marsey', 'watchpeopledie', 'makemycoffin'})
OFFSITE_NOTIF_QUERIES.update({'marsey', 'watchpeopledie', 'makemycoffin'})
LONGPOSTBOT_REPLIES = (
@ -693,7 +693,9 @@ if SITE in {'rdrama.net', 'staging.rdrama.net'}:
IMMUNE_TO_NEGATIVE_AWARDS = {PIZZASHILL_ID, CARP_ID, 23629}
PINNED_POSTS_IDS = {
2424: 1, #pizzashill
PIZZASHILL_ID: 1,
28: 1, #Joan_Wayne_Gacy
10953: 1, #autodrama
864: 1, #RitalinRx
1096: 1, #xa15428
1357: 1, #_______________

View File

@ -14,7 +14,6 @@ import requests
import ffmpeg
import files.helpers.offsitementions as offsitementions
import files.helpers.stats as stats
import files.routes.static as route_static
from files.routes.front import frontlist
@ -27,6 +26,9 @@ from files.helpers.lottery import check_if_end_lottery_task
from files.helpers.roulette import spin_roulette_wheel
from files.helpers.sanitize import filter_emojis_only, sanitize
from files.helpers.useractions import *
from files.helpers.reddit_mentions import *
from files.helpers.lemmy_mentions import *
from files.cli import app, db_session, g
CRON_CACHE_TIMEOUT = 172800
@ -58,7 +60,10 @@ def cron_fn(every_5m, every_1d, every_1mo):
g.db.commit()
if not IS_LOCALHOST:
offsitementions.offsite_mentions_task(cache)
reddit_mentions_task()
g.db.commit()
lemmy_mentions_task()
g.db.commit()
if every_1d or (not cache.get('stats') and not IS_LOCALHOST):

View File

@ -326,15 +326,15 @@ def get_comments_v_properties(v, should_keep_func=None, *criterion):
def get_hole(hole, v=None, graceful=False):
if not hole:
if graceful: return None
else: abort(404)
else: abort(404, f"/h/{hole} was not found.")
hole = hole.replace('/h/', '').replace('h/', '').strip().lower()
if not hole:
if graceful: return None
else: abort(404)
else: abort(404, f"/h/{hole} was not found.")
hole = g.db.get(Hole, hole)
if not hole:
if graceful: return None
else: abort(404)
else: abort(404, f"/h/{hole} was not found.")
return hole
@cache.memoize(timeout=3600)

View File

@ -0,0 +1,56 @@
import requests
from flask import g
from files.helpers.config.const import *
from files.classes.comment import Comment
from files.helpers.sanitize import *
from files.helpers.alerts import push_notif
from files.classes.notifications import Notification
def lemmy_mentions_task():
for q in OFFSITE_NOTIF_QUERIES:
url = f'https://lemm.ee/api/v3/search?q={q}'
data = requests.get(url, headers=HEADERS, timeout=5).json()
for kind in ("post", "comment"):
for thing in data[f'{kind}s']:
creator = thing['creator']
author_string = f"[/u/{creator['name']}]({creator['actor_id']})"
thing = thing[kind]
if kind == 'comment':
body = thing["content"]
text = f'<blockquote><p>{body}</p></blockquote>'
else:
title = thing["name"]
text = f'<blockquote><p>{title}</p></blockquote>'
if thing["body"]:
selftext = thing["body"][:5000]
text += f'<br><blockquote><p>{selftext}</p></blockquote>'
if 'erdrama' in text: continue
permalink = thing['ap_id']
text = f'New site mention by {author_string}\n\n{permalink}\n\n{text}'
text = sanitize(text, blackjack="lemmy mention", golden=False)
existing_comment = g.db.query(Comment.id).filter_by(
author_id=AUTOJANNY_ID,
parent_post=None,
body_html=text).one_or_none()
if existing_comment: break
try: created_utc = int(time.mktime(time.strptime(thing['published'].split('.')[0], "%Y-%m-%dT%H:%M:%S")))
except: created_utc = int(time.mktime(time.strptime(thing['published'].split('.')[0], "%Y-%m-%dT%H:%M:%SZ")))
new_comment = Comment(
author_id=AUTOJANNY_ID,
parent_post=None,
body_html=text,
distinguished=True,
created_utc=created_utc,
)
g.db.add(new_comment)
g.db.flush()
new_comment.top_comment_id = new_comment.id

View File

@ -92,7 +92,7 @@ def process_audio(file, v, old=None):
extension = guess_extension(file.content_type)
if not extension:
os.remove(old)
abort(400)
abort(400, "Unsupported audio format.")
new = old + extension
try:
@ -101,7 +101,7 @@ def process_audio(file, v, old=None):
os.remove(old)
if os.path.isfile(new):
os.remove(new)
abort(400)
abort(400, "Something went wrong processing your audio on our end. Please try uploading it to https://pomf2.lain.la and post the link instead.")
os.remove(old)
@ -162,7 +162,7 @@ def process_video(file, v):
bitrate = int(video_info.get('bit_rate', 3000000))
except:
os.remove(old)
abort(400, "Something went wrong processing your video and it might be on our end. Please try uploading it to https://pomf2.lain.la and post the link instead.")
abort(400, "Something went wrong processing your video on our end. Please try uploading it to https://pomf2.lain.la and post the link instead.")
if codec != 'h264':
copyfile(old, new)
@ -177,7 +177,7 @@ def process_video(file, v):
os.remove(old)
if os.path.isfile(new):
os.remove(new)
abort(400)
abort(400, "Something went wrong processing your video on our end. Please try uploading it to https://pomf2.lain.la and post the link instead.")
os.remove(old)
@ -227,7 +227,7 @@ def process_image(filename, v, resize=0, trim=False, uploader_id=None):
except:
os.remove(filename)
if has_request and not filename.startswith('/chat_images/'):
abort(415)
abort(400, "Something went wrong processing your image on our end. Please try uploading it to https://pomf2.lain.la and post the link instead.")
return None
params.append(filename)

View File

@ -1,36 +1,23 @@
import time
import itertools
import requests
from flask_caching import Cache
from flask import g
from sqlalchemy import or_
import files.helpers.config.const as const
from files.classes.badges import Badge
from files.helpers.config.const import *
from files.classes.comment import Comment
from files.classes.user import User
from files.helpers.sanitize import *
from files.helpers.alerts import push_notif
from files.classes.notifications import Notification
# Note: while https://api.pushshift.io/meta provides the key
# server_ratelimit_per_minute, in practice Cloudflare puts stricter,
# unofficially documented limits at around 60/minute. We get nowhere near this
# with current keyword quantities. If this ever changes, consider reading the
# value from /meta (or just guessing) and doing a random selection of keywords.
def offsite_mentions_task(cache):
site_mentions = get_mentions(cache, const.REDDIT_NOTIFS_SITE)
def reddit_mentions_task():
site_mentions = get_mentions(OFFSITE_NOTIF_QUERIES)
notify_mentions(site_mentions)
if const.REDDIT_NOTIFS_USERS:
for query, send_user in const.REDDIT_NOTIFS_USERS.items():
user_mentions = get_mentions(cache, [query], reddit_notifs_users=True)
if REDDIT_NOTIFS_USERS:
for query, send_user in REDDIT_NOTIFS_USERS.items():
user_mentions = get_mentions([query], reddit_notifs_users=True)
if user_mentions:
notify_mentions(user_mentions, send_to=send_user, mention_str='mention of you')
def get_mentions(cache, queries, reddit_notifs_users=False):
def get_mentions(queries, reddit_notifs_users=False):
mentions = []
for kind in ('submission', 'comment'):
q = " or ".join(queries)
@ -73,33 +60,32 @@ def notify_mentions(mentions, send_to=None, mention_str='site mention'):
for m in mentions:
author = m['author']
permalink = m['permalink']
text = sanitize(m['text'], blackjack="reddit mention", golden=False)
notif_text = (
text = (
f'<p>New {mention_str} by <a href="https://old.reddit.com/user/{author}" '
f'rel="nofollow noopener" target="_blank">/u/{author}</a></p>'
f'<p><a href="https://old.reddit.com{permalink}?context=89" '
f'<p><a href="https://old.reddit.com{permalink}?context=8" '
'rel="nofollow noopener" target="_blank">'
f'https://old.reddit.com{permalink}?context=89</a></p>'
f'{text}'
f'https://old.reddit.com{permalink}?context=8</a></p>'
f'{m["text"]}'
)
text = sanitize(text, blackjack="reddit mention", golden=False)
g.db.flush()
try:
existing_comment = g.db.query(Comment.id).filter_by(
author_id=const.AUTOJANNY_ID,
author_id=AUTOJANNY_ID,
parent_post=None,
body_html=notif_text).one_or_none()
body_html=text).one_or_none()
if existing_comment: break
# todo: handle this exception by removing one of the existing
# means that multiple rows were found, happens on new install for some reason
except:
pass
new_comment = Comment(
author_id=const.AUTOJANNY_ID,
author_id=AUTOJANNY_ID,
parent_post=None,
body_html=notif_text,
distinguish_level=6,
body_html=text,
distinguished=True,
created_utc=int(m['created_utc']),
)
g.db.add(new_comment)

View File

@ -211,7 +211,7 @@ tlds = ( # Original gTLDs and ccTLDs
'vu','wf','ws','xn','xxx','ye','yt','yu','za','zm','zw',
# New gTLDs
'app','cleaning','club','dev','farm','florist','fun','gay','lgbt','life','lol',
'moe','mom','monster','new','news','online','pics','press','pub','site','blog',
'moe','mom','monster','new','news','one','online','pics','press','pub','site','blog',
'vip','win','world','wtf','xyz','video','host','art','media','wiki','tech',
'cooking','network','party','goog','markets','today','beauty','camp','top',
'red','city','quest','works','soy','zone',

View File

@ -34,7 +34,7 @@ def create_comment_duplicated(text_html):
new_comment = Comment(author_id=AUTOJANNY_ID,
parent_post=None,
body_html=text_html,
distinguish_level=6,
distinguished=True,
is_bot=True)
g.db.add(new_comment)
g.db.flush()
@ -44,7 +44,6 @@ def create_comment_duplicated(text_html):
return new_comment.id
def send_repeatable_notification_duplicated(uid, text):
if uid in BOT_IDs: return
text_html = sanitize(text)
@ -742,8 +741,7 @@ def normalize_url(url):
if not url.startswith('/') and not url.startswith('https://rdrama.net') and not url.startswith('https://watchpeopledie.tv'):
try: parsed_url = urlparse(url)
except:
print(url, flush=True)
abort(500)
abort(400, f"Something is wrong with the url you submitted ({url}) and it couldn't be parsed.")
netloc = parsed_url.netloc
path = parsed_url.path

View File

@ -27,4 +27,4 @@ def badge_grant(user, badge_id, description=None, url=None, notify=True):
if notify:
send_repeatable_notification(user.id,
"@AutoJanny has given you the following profile badge:\n\n" +
f"{badge.path}\n\n**{badge.name}**\n\n{badge.badge.description}")
f"{badge.path}\n\n**{badge.name}**\n\n{badge.badge.description}").created_utc += 1

View File

@ -135,7 +135,7 @@ def remove_admin(v, username):
user = get_user(username)
if user.admin_level > v.admin_level:
abort(403)
abort(403, "You can't remove an admin with higher level than you.")
if user.admin_level:
user.admin_level = 0
@ -164,7 +164,8 @@ def distribute(v, kind, option_id):
option = g.db.get(cls, option_id)
if option.exclusive != 2: abort(403)
if option.exclusive != 2:
abort(400, "This is not a bet.")
option.exclusive = 3
g.db.add(option)
@ -226,7 +227,7 @@ def revert_actions(v, username):
revertee = get_user(username)
if revertee.admin_level > v.admin_level:
abort(403)
abort(403, "You can't revert the actions of an admin with higher level that you.")
ma = ModAction(
kind="revert",
@ -341,7 +342,7 @@ def reported_posts(v):
is_approved=None,
is_banned=False,
deleted_utc=0
).join(Post.reports)
).join(Post.reports).join(User, User.id == Report.user_id).filter(User.shadowbanned == None, User.is_muted == False)
total = listing.count()
@ -364,7 +365,7 @@ def reported_comments(v):
is_approved=None,
is_banned=False,
deleted_utc=0
).join(Comment.reports)
).join(Comment.reports).join(User, User.id == CommentReport.user_id).filter(User.shadowbanned == None, User.is_muted == False)
total = listing.count()
@ -485,7 +486,7 @@ def badge_grant_post(v):
user = get_user(username)
try: badge_id = int(request.values.get("badge_id"))
except: abort(400)
except: abort(400, "Invalid badge id.")
if badge_id not in [b.id for b in badges]:
abort(403, "You can't grant this badge!")
@ -497,7 +498,7 @@ def badge_grant_post(v):
abort(400, "This badge requires a url!")
if url:
if '\\' in url: abort(400)
if '\\' in url: abort(400, "Nice try nigger.")
if url.startswith(f'{SITE_FULL}/'):
url = url.split(SITE_FULL, 1)[1]
else:
@ -563,10 +564,10 @@ def badge_remove_post(v):
user = get_user(username)
try: badge_id = int(request.values.get("badge_id"))
except: abort(400)
except: abort(400, "Invalid badge id.")
if badge_id not in [b.id for b in badges]:
abort(403)
abort(403, "You're not allowed to remove this badge.")
badge = user.has_badge(badge_id)
if not badge: continue
@ -749,7 +750,7 @@ def admin_delink_relink_alt(v, username, other):
user2 = get_account(other)
ids = [user1.id, user2.id]
a = g.db.query(Alt).filter(Alt.user1.in_(ids), Alt.user2.in_(ids)).one_or_none()
if not a: abort(404)
if not a: abort(404, "Alt doesn't exist.")
g.db.delete(a)
cache.delete_memoized(get_alt_graph_ids, user1.id)
@ -869,7 +870,7 @@ def unchud(fullname, v):
def shadowban(user_id, v):
user = get_account(user_id)
if user.admin_level > v.admin_level:
abort(403)
abort(403, "You can't shadowban an admin with higher level than you.")
user.shadowbanned = v.id
reason = request.values.get("reason", "").strip()
@ -1000,7 +1001,7 @@ def ban_user(fullname, v):
user = get_account(fullname)
if user.admin_level > v.admin_level:
abort(403)
abort(403, "You can't ban an admin with higher level than you.")
if user.is_permabanned:
abort(403, f"@{user.username} is already banned permanently!")
@ -1442,36 +1443,6 @@ def approve_post(post_id, v):
return {"message": "Post approved!"}
@app.post("/distinguish/<int:post_id>")
@limiter.limit('1/second', scope=rpath)
@limiter.limit('1/second', scope=rpath, key_func=get_ID)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID)
@admin_level_required(PERMS['POST_COMMENT_DISTINGUISH'])
def distinguish_post(post_id, v):
post = get_post(post_id)
if post.distinguish_level:
post.distinguish_level = 0
kind = 'undistinguish_post'
else:
post.distinguish_level = v.admin_level
kind = 'distinguish_post'
g.db.add(post)
ma = ModAction(
kind=kind,
user_id=v.id,
target_post_id=post.id
)
g.db.add(ma)
if post.distinguish_level: return {"message": "Post distinguished!"}
else: return {"message": "Post undistinguished!"}
@app.post("/sticky/<int:post_id>")
@feature_required('PINS')
@limiter.limit('1/second', scope=rpath)
@ -1676,36 +1647,6 @@ def approve_comment(c_id, v):
return {"message": "Comment approved!"}
@app.post("/distinguish_comment/<int:c_id>")
@limiter.limit('1/second', scope=rpath)
@limiter.limit('1/second', scope=rpath, key_func=get_ID)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID)
@admin_level_required(PERMS['POST_COMMENT_DISTINGUISH'])
def admin_distinguish_comment(c_id, v):
comment = get_comment(c_id, v=v)
if comment.distinguish_level:
comment.distinguish_level = 0
kind = 'undistinguish_comment'
else:
comment.distinguish_level = v.admin_level
kind = 'distinguish_comment'
g.db.add(comment)
ma = ModAction(
kind=kind,
user_id=v.id,
target_comment_id=comment.id
)
g.db.add(ma)
if comment.distinguish_level: return {"message": "Comment distinguished!"}
else: return {"message": "Comment undistinguished!"}
@app.get("/admin/banned_domains/")
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID)

View File

@ -173,16 +173,18 @@ def approve_emoji(v, name):
nsfw = request.values.get("nsfw") == 'true'
author = request.values.get('author').strip()
author = get_user(author)
old_name = emoji.name
emoji.name = new_name
emoji.kind = new_kind
emoji.tags = tags
emoji.nsfw = nsfw
emoji.author_id = author.id
g.db.add(emoji)
author = get_account(emoji.author_id)
if emoji.kind == "Marsey":
all_by_author = g.db.query(Emoji).filter_by(kind="Marsey", author_id=author.id).count()

View File

@ -205,7 +205,7 @@ def award_thing(v, thing_type, id):
if isinstance(obj, Post) and obj.id == 210983:
abort(403, "You can't award this post!")
if isinstance(obj, Post) and obj.distinguish_level and AWARDS[kind]['cosmetic']:
if isinstance(obj, Post) and obj.distinguished and AWARDS[kind]['cosmetic']:
abort(403, "Distinguished posts are immune to cosmetic awards!")
if kind == "benefactor":

View File

@ -326,7 +326,7 @@ def comment(v):
c_jannied = Comment(author_id=AUTOJANNY_ID,
parent_post=post_target.id if posting_to_post else None,
wall_user_id=post_target.id if not posting_to_post else None,
distinguish_level=6,
distinguished=True,
parent_comment_id=c.id,
level=level+1,
is_bot=True,
@ -611,7 +611,7 @@ def diff_words(answer, guess):
def toggle_comment_nsfw(cid, v):
comment = get_comment(cid)
if comment.author_id != v.id and v.admin_level < PERMS['POST_COMMENT_MODERATION'] and not (comment.post and comment.post.hole and v.mods_hole(comment.post.hole)) and comment.wall_user_id != v.id:
if comment.author_id != v.id and v.admin_level < PERMS['POST_COMMENT_MODERATION'] and not (comment.post and v.mods_hole(comment.post.hole)) and comment.wall_user_id != v.id:
abort(403)
comment.nsfw = not comment.nsfw
@ -625,7 +625,7 @@ def toggle_comment_nsfw(cid, v):
target_comment_id = comment.id,
)
g.db.add(ma)
elif comment.post and comment.post.hole and v.mods_hole(comment.post.hole):
elif comment.post and v.mods_hole(comment.post.hole):
ma = HoleAction(
hole = comment.post.hole,
kind = "set_nsfw_comment" if comment.nsfw else "unset_nsfw_comment",
@ -782,3 +782,36 @@ def postprocess_comment(comment_body, comment_body_html, cid):
g.db.close()
stdout.flush()
@app.post("/distinguish_comment/<int:c_id>")
@limiter.limit('1/second', scope=rpath)
@limiter.limit('1/second', scope=rpath, key_func=get_ID)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID)
@auth_required
def admin_distinguish_comment(c_id, v):
comment = get_comment(c_id, v=v)
if v.admin_level < PERMS['POST_COMMENT_DISTINGUISH'] and not (comment.parent_post and v.mods_hole(comment.post.hole)):
abort(403, "You can't distinguish this comment")
if comment.distinguished:
comment.distinguished = False
kind = 'undistinguish_comment'
else:
comment.distinguished = True
kind = 'distinguish_comment'
g.db.add(comment)
ma = ModAction(
kind=kind,
user_id=v.id,
target_comment_id=comment.id
)
g.db.add(ma)
if comment.distinguished: return {"message": "Comment distinguished!"}
else: return {"message": "Comment undistinguished!"}

View File

@ -901,7 +901,7 @@ def pin_comment_mod(cid, v):
comment = get_comment(cid, v=v)
if not comment.stickied:
if not (comment.post.hole and v.mods_hole(comment.post.hole)): abort(403)
if not v.mods_hole(comment.post.hole): abort(403)
comment.stickied = v.username + " (Mod)"
@ -934,7 +934,7 @@ def unpin_comment_mod(cid, v):
comment = get_comment(cid, v=v)
if comment.stickied:
if not (comment.post.hole and v.mods_hole(comment.post.hole)): abort(403)
if not v.mods_hole(comment.post.hole): abort(403)
comment.stickied = None
comment.stickied_utc = None

View File

@ -20,6 +20,8 @@ from files.helpers.settings import *
from files.helpers.cloudflare import *
from files.helpers.sorting_and_time import make_age_string
from files.helpers.can_see import *
from files.helpers.alerts import send_notification
from files.helpers.useractions import *
from files.routes.routehelpers import get_alt_graph, get_formkey
from files.routes.wrappers import calc_users
from files.__main__ import app, cache
@ -135,12 +137,21 @@ def poster_of_the_day_id():
db = db_session()
uid = db.query(User.id, func.sum(Post.upvotes)).join(Post, Post.author_id == User.id).filter(
user = db.query(User, func.sum(Post.upvotes)).join(Post, Post.author_id == User.id).filter(
Post.created_utc > t,
User.admin_level == 0,
).group_by(User.id).order_by(func.sum(Post.upvotes).desc()).first()[0]
).group_by(User).order_by(func.sum(Post.upvotes).desc()).one_or_none()
db.rollback()
if not user: return SNAPPY_ID
user = user[0]
t = datetime.datetime.now()
send_notification(user.id, f":marseyjam: You're the Top Poster of the Day for the day of {t.year}-{t.month}-{t.day} :marseyjam:")
badge_grant(badge_id=327, user=user)
uid = user.id
db.commit()
db.close()
return uid

View File

@ -323,7 +323,7 @@ def sign_up_post(v):
new_user.admin_level = 5
new_user.coins = 100000000
new_user.marseybux = 100000000
del session["history"]
session.pop("history", None)
if ref_id and ref_id not in session.get("history", []):
ref_user = get_account(ref_id)

View File

@ -32,7 +32,7 @@ def clear(v):
v.last_viewed_modmail_notifs = int(time.time())
v.last_viewed_post_notifs = int(time.time())
v.last_viewed_log_notifs = int(time.time())
v.last_viewed_reddit_notifs = int(time.time())
v.last_viewed_offsite_notifs = int(time.time())
g.db.add(v)
return {"message": "Notifications marked as read!"}
@ -268,17 +268,17 @@ def notifications_modactions(v):
@app.get("/notifications/reddit")
@app.get("/notifications/offsite")
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID)
@auth_required
def notifications_reddit(v):
def notifications_offsite(v):
page = get_page()
if not v.can_view_offsitementions: abort(403)
if not v.can_view_offsite_mentions: abort(403)
listing = g.db.query(Comment).filter(
Comment.body_html.like('%<p>New site mention%<a href="https://old.reddit.com/r/%'),
Comment.body_html.like('%<p>New site mention by <a href=%'),
Comment.parent_post == None,
Comment.author_id == AUTOJANNY_ID
)
@ -287,10 +287,10 @@ def notifications_reddit(v):
listing = listing.order_by(Comment.created_utc.desc()).offset(PAGE_SIZE*(page-1)).limit(PAGE_SIZE).all()
for ma in listing:
ma.unread = ma.created_utc > v.last_viewed_reddit_notifs
ma.unread = ma.created_utc > v.last_viewed_offsite_notifs
if not session.get("GLOBAL") and not request.values.get('nr'):
v.last_viewed_reddit_notifs = int(time.time())
v.last_viewed_offsite_notifs = int(time.time())
g.db.add(v)
if v.client: return {"data":[x.json for x in listing]}

View File

@ -674,7 +674,7 @@ def submit_post(v, hole=None):
nsfw=False,
is_bot=True,
app_id=None,
distinguish_level=6,
distinguished=True,
body=body,
body_html=body_jannied_html,
ghost=p.ghost
@ -795,7 +795,7 @@ def undelete_post_pid(pid, v):
def mark_post_nsfw(pid, v):
p = get_post(pid)
if p.author_id != v.id and v.admin_level < PERMS['POST_COMMENT_MODERATION'] and not (p.hole and v.mods_hole(p.hole)):
if p.author_id != v.id and v.admin_level < PERMS['POST_COMMENT_MODERATION'] and not v.mods_hole(p.hole):
abort(403)
p.nsfw = True
@ -834,7 +834,7 @@ def mark_post_nsfw(pid, v):
def unmark_post_nsfw(pid, v):
p = get_post(pid)
if p.author_id != v.id and v.admin_level < PERMS['POST_COMMENT_MODERATION'] and not (p.hole and v.mods_hole(p.hole)):
if p.author_id != v.id and v.admin_level < PERMS['POST_COMMENT_MODERATION'] and not v.mods_hole(p.hole):
abort(403)
if p.nsfw and v.is_permabanned:
@ -1148,3 +1148,36 @@ if SITE_NAME == 'WPD':
send_repeatable_notification(p.author_id, f"@{v.username} (a site admin) has removed the child warning from [{p.title}](/post/{p.id})")
return {"message": "The child warning has been removed from the post!"}
@app.post("/distinguish/<int:post_id>")
@limiter.limit('1/second', scope=rpath)
@limiter.limit('1/second', scope=rpath, key_func=get_ID)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID)
@auth_required
def distinguish_post(post_id, v):
post = get_post(post_id)
if v.admin_level < PERMS['POST_COMMENT_DISTINGUISH'] and not v.mods_hole(post.hole):
abort(403, "You can't distinguish this post")
if post.distinguished:
post.distinguished = False
kind = 'undistinguish_post'
else:
post.distinguished = True
kind = 'distinguish_post'
g.db.add(post)
ma = ModAction(
kind=kind,
user_id=v.id,
target_post_id=post.id
)
g.db.add(ma)
if post.distinguished: return {"message": "Post distinguished!"}
else: return {"message": "Post undistinguished!"}

View File

@ -31,7 +31,7 @@ def report_post(pid, v):
if len(reason_html) > 350:
abort(400, "Rendered report reason is too long!")
if reason.startswith('!') and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or post.hole and v.mods_hole(post.hole)):
if reason.startswith('!') and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or v.mods_hole(post.hole)):
post.flair = reason_html[1:]
g.db.add(post)
if v.admin_level >= PERMS['POST_COMMENT_MODERATION']:

View File

@ -52,7 +52,7 @@ def get_alt_graph(uid):
def add_alt(user1, user2):
if user1 in {1375580,14713} or user2 in {1375580,14713}:
del session["history"]
session.pop("history", None)
if session.get("GLOBAL"):
return

View File

@ -3,6 +3,7 @@ import time
from calendar import timegm
from sqlalchemy.orm import load_only
from sqlalchemy import select
from files.helpers.regex import *
from files.helpers.sorting_and_time import *
@ -17,7 +18,6 @@ valid_params = [
'post',
'before',
'after',
'exact',
'title',
'sentto',
'hole',
@ -228,16 +228,16 @@ def searchcomments(v):
else: comments = comments.filter(Comment.author_id == author.id)
if 'q' in criteria:
tokens = map(lambda x: search_regex_1.sub('', x), criteria['q'])
tokens = filter(lambda x: len(x) > 0, tokens)
tokens = map(lambda x: search_regex_2.sub("\\'", x), tokens)
tokens = map(lambda x: x.strip(), tokens)
tokens = map(lambda x: search_regex_3.sub(' <-> ', x), tokens)
comments = comments.filter(Comment.body_ts.match(
' & '.join(tokens),
postgresql_regconfig='english'))
text = criteria['full_text']
comments = comments.filter(
Comment.body_ts.bool_op("@@")(
func.websearch_to_tsquery("english", text)
)
)
if 'nsfw' in criteria: comments = comments.filter(Comment.nsfw == True)
if 'nsfw' in criteria:
nsfw = criteria['nsfw'].lower().strip() == 'true'
comments = comments.filter(Comment.nsfw == nsfw)
if 'hole' in criteria:
comments = comments.filter(Post.hole == criteria['hole'])
@ -327,14 +327,12 @@ def searchmessages(v):
else: comments = comments.filter(Comment.author_id == author.id)
if 'q' in criteria:
tokens = map(lambda x: search_regex_1.sub('', x), criteria['q'])
tokens = filter(lambda x: len(x) > 0, tokens)
tokens = map(lambda x: search_regex_2.sub("\\'", x), tokens)
tokens = map(lambda x: x.strip(), tokens)
tokens = map(lambda x: search_regex_3.sub(' <-> ', x), tokens)
comments = comments.filter(Comment.body_ts.match(
' & '.join(tokens),
postgresql_regconfig='english'))
text = criteria['full_text']
comments = comments.filter(
Comment.body_ts.bool_op("@@")(
func.websearch_to_tsquery("english", text)
)
)
comments = apply_time_filter(t, comments, Comment)

View File

@ -337,7 +337,8 @@ def settings_personal_post(v):
if len(bio_html) > BIO_FRIENDS_ENEMIES_HTML_LENGTH_LIMIT:
abort(400, "Your rendered bio is too long!")
v.bio_html=bio_html
v.bio = bio
v.bio_html = bio_html
g.db.add(v)
return {"message": "Your bio has been updated."}

View File

@ -31,7 +31,7 @@
<div class="user-info">
<span class="comment-collapse-icon" data-nonce="{{g.nonce}}" data-onclick="collapse_comment('{{c.id}}')"></span>
{% if standalone and c.nsfw %}<span class="badge badge-danger">NSFW</span> {% endif %}
{% if c.is_banned %}Removed by @{{c.ban_reason}} (Site Admin){% elif c.deleted_utc %}Deleted by author{% endif %}
{% if c.is_banned %}Removed by @{{c.ban_reason}} (site admin){% elif c.deleted_utc %}Deleted by author{% endif %}
</div>
</div>
{% if render_replies %}
@ -153,8 +153,14 @@
<i id='pinned-{{c.id}}'class="fas fa-thumbtack fa-rotate--45 pr-1 text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Pinned by @{{c.stickied}}" {% if c.stickied_utc %}data-onmouseover="pinned_timestamp('pinned-{{c.id}}')" data-timestamp={{c.stickied_utc}} data-nonce="{{g.nonce}}"{% endif %}></i>
{% endif %}
{% if c.distinguish_level and not c.ghost %}
<i class="fas fa-broom text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{SITE_NAME}} Admin, speaking officially"></i>
{% if c.distinguished and not c.ghost %}
<i class="fas fa-broom text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="
{%- if c.parent_post and c.author.mods_hole(c.post.hole) -%}
/h/{{c.post.hole}} mod
{%- else -%}
{{SITE_NAME}} admin
{%- endif -%}
, speaking officially"></i>
{% endif %}
{% if c.is_op %}
@ -174,7 +180,7 @@
{% endif %}
{% if c.ghost %}
<span {% if c.distinguish_level %}class="mod {% if SITE_NAME == 'rDrama' %}mod-rdrama{% endif %}"{% endif %}>πŸ‘»</span>
<span {% if c.distinguished %}class="mod {% if SITE_NAME == 'rDrama' %}mod-rdrama{% endif %}"{% endif %}>πŸ‘»</span>
{% else %}
{% if FEATURES['PATRON_ICONS'] and c.author.patron > 1 %}
<img loading="lazy" src="{{SITE_FULL_IMAGES}}/i/{{SITE_NAME}}/badges/2{{c.author.patron}}.webp?b=11" class="patron-img" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{c.author.patron_tooltip}}" alt="{{c.author.patron_tooltip}}">
@ -194,7 +200,7 @@
<img class="profile-pic-30-hat hat" loading="lazy" src="{{c.author.hat_active(v)[0]}}?x=7" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{c.author.hat_active(v)[1]}}" alt="@{{c.author.username}}'s hat">
{%- endif %}
</div>
<span {% if c.author.patron and not c.distinguish_level %}class="patron" style="background-color:#{{c.author.name_color}}"{% elif c.distinguish_level %}class="mod {% if SITE_NAME == 'rDrama' %}mod-rdrama{% endif %}"{% endif %} {% if c.author.pride_username(v) %}pride_username{% endif %}>{{c.author_name}}</span>
<span {% if c.author.patron and not c.distinguished %}class="patron" style="background-color:#{{c.author.name_color}}"{% elif c.distinguished %}class="mod {% if SITE_NAME == 'rDrama' %}mod-rdrama{% endif %}"{% endif %} {% if c.author.pride_username(v) %}pride_username{% endif %}>{{c.author_name}}</span>
</a>
{% if FEATURES['PRONOUNS'] %}
<span class="pronouns" style="color:#{{c.author.flaircolor}} !important;border-color:#{{c.author.flaircolor}} !important">{{c.author.pronouns_display}}</span>
@ -267,7 +273,7 @@
{{macros.reports(c, 'comment')}}
{% if c.is_banned %}
<div id="comment-banned-warning" class="comment-text text-removed mb-0">Removed by @{{c.ban_reason}} (Site Admin)</div>
<div id="comment-banned-warning" class="comment-text text-removed mb-0">Removed by @{{c.ban_reason}} (site admin)</div>
{% endif %}
{% set realbody = c.realbody(v) %}
@ -421,10 +427,10 @@
<a href="{{c.oauth_app.permalink}}/comments" class="dropdown-item list-inline-item d-mob-none text-primary"><i class="fas fa-code text-primary fa-fw"></i>API App</a>
{% endif %}
{% if v.admin_level >= PERMS['POST_COMMENT_DISTINGUISH'] %}
<button type="button" id="distinguish-{{c.id}}" class="dropdown-item list-inline-item d-none {% if not c.distinguish_level %}d-md-block{% endif %} text-info" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/distinguish_comment/{{c.id}}','distinguish-{{c.id}}','undistinguish-{{c.id}}','d-md-block')"><i class="fas fa-id-badge text-info fa-fw"></i>Distinguish</button>
{% if v.admin_level >= PERMS['POST_COMMENT_DISTINGUISH'] or (c.parent_post and v.mods_hole(c.post.hole)) %}
<button type="button" id="distinguish-{{c.id}}" class="dropdown-item list-inline-item d-none {% if not c.distinguished %}d-md-block{% endif %} text-info" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/distinguish_comment/{{c.id}}','distinguish-{{c.id}}','undistinguish-{{c.id}}','d-md-block')"><i class="fas fa-id-badge text-info fa-fw"></i>Distinguish</button>
<button type="button" id="undistinguish-{{c.id}}" class="dropdown-item list-inline-item d-none {% if c.distinguish_level %}d-md-block{% endif %} text-info" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/distinguish_comment/{{c.id}}','distinguish-{{c.id}}','undistinguish-{{c.id}}','d-md-block')"><i class="fas fa-id-badge text-info fa-fw"></i>Undistinguish</button>
<button type="button" id="undistinguish-{{c.id}}" class="dropdown-item list-inline-item d-none {% if c.distinguished %}d-md-block{% endif %} text-info" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/distinguish_comment/{{c.id}}','distinguish-{{c.id}}','undistinguish-{{c.id}}','d-md-block')"><i class="fas fa-id-badge text-info fa-fw"></i>Undistinguish</button>
{% endif %}
{% if c.parent_post %}
@ -434,7 +440,7 @@
{% set url = "sticky_comment" %}
{% elif v.id == c.post.author_id %}
{% set url = "pin_comment" %}
{% elif c.post.hole and v.mods_hole(c.post.hole) %}
{% elif v.mods_hole(c.post.hole) %}
{% set url = "pin_comment_mod" %}
{% endif %}
@ -465,7 +471,7 @@
{% if c.parent_post %}
{% set hole = c.post.hole %}
{% if hole and v.mods_hole(hole) and not c.author.mods_hole(hole) %}
{% if v.mods_hole(hole) and not c.author.mods_hole(hole) %}
<button type="button" id="exile-{{c.id}}" class="d-none {% if not c.author.exiler_username(hole) %}d-md-block{% endif %} dropdown-item list-inline-item text-danger" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/exile/comment/{{c.id}}','exile-{{c.id}}','unexile-{{c.id}}','d-none')"><i class="fas fa-campfire text-danger fa-fw"></i>Exile user</button>
<button type="button" id="unexile-{{c.id}}" class="d-none {% if c.author.exiler_username(hole) %}d-md-block{% endif %} dropdown-item list-inline-item text-success" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{hole}}/unexile/{{c.author_id}}','exile-{{c.id}}','unexile-{{c.id}}','d-none')"><i class="fas fa-campfire text-success fa-fw"></i>Unexile user</button>
{% endif %}
@ -476,7 +482,7 @@
<button type="button" id="unprogstack-{{c.id}}" class="dropdown-item list-inline-item d-none {% if c.is_approved == PROGSTACK_ID %}d-md-block{% endif %} text-danger" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/admin/unprogstack/comment/{{c.id}}','progstack-{{c.id}}','unprogstack-{{c.id}}','d-md-block')"><i class="fas fa-bullhorn text-danger fa-fw"></i>Remove Progressive Stack</button>
{% endif %}
{% if FEATURES['NSFW_MARKING'] and (c.parent_post or c.wall_user_id) and (c.author_id == v.id or v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or (c.post.hole and v.mods_hole(c.post.hole))) or c.wall_user_id == v.id %}
{% if FEATURES['NSFW_MARKING'] and (c.parent_post or c.wall_user_id) and (c.author_id == v.id or v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or v.mods_hole(c.post.hole)) or c.wall_user_id == v.id %}
<button type="button" id="mark-{{c.id}}" class="dropdown-item list-inline-item d-none {% if not c.nsfw %}d-md-block{% endif %} text-danger" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/toggle_comment_nsfw/{{c.id}}','mark-{{c.id}}','unmark-{{c.id}}','d-md-block')"><i class="fas fa-eye-evil text-danger fa-fw"></i>Mark NSFW</button>
<button type="button" id="unmark-{{c.id}}" class="dropdown-item list-inline-item d-none {% if c.nsfw %}d-md-block{% endif %} text-success" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/toggle_comment_nsfw/{{c.id}}','mark-{{c.id}}','unmark-{{c.id}}','d-md-block')"><i class="fas fa-eye-evil text-success fa-fw"></i>Unmark NSFW</button>
{% endif %}
@ -634,17 +640,22 @@
{% endif %}
{% endif %}
{% if FEATURES['NSFW_MARKING'] and v.admin_level < PERMS['POST_COMMENT_MODERATION'] and (c.author_id == v.id or (c.post.hole and v.mods_hole(c.post.hole))) or c.wall_user_id == v.id %}
{% if FEATURES['NSFW_MARKING'] and v.admin_level < PERMS['POST_COMMENT_MODERATION'] and (c.author_id == v.id or v.mods_hole(c.post.hole)) or c.wall_user_id == v.id %}
<button type="button" id="mark2-{{c.id}}" class="{% if c.nsfw %}d-none{% endif %} list-group-item text-danger" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/toggle_comment_nsfw/{{c.id}}','mark2-{{c.id}}','unmark2-{{c.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-eye-evil text-danger mr-2"></i>Mark NSFW</button>
<button type="button" id="unmark2-{{c.id}}" class="{% if not c.nsfw %}d-none{% endif %} list-group-item text-success" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/toggle_comment_nsfw/{{c.id}}','mark2-{{c.id}}','unmark2-{{c.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-eye-evil text-success mr-2"></i>Unmark NSFW</button>
{% endif %}
{% if v.admin_level < PERMS['POST_COMMENT_DISTINGUISH'] and v.mods_hole(c.post.hole) %}
<button type="button" id="distinguish2-{{c.id}}" class="list-group-item {% if c.distinguished %}d-none{% endif %} text-info" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/distinguish_comment/{{c.id}}','distinguish2-{{c.id}}','undistinguish2-{{c.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-id-badge text-info mr-2"></i>Distinguish</button>
<button type="button" id="undistinguish2-{{c.id}}" class="list-group-item {% if not c.distinguished %}d-none{% endif %} text-info" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/distinguish_comment/{{c.id}}','distinguish2-{{c.id}}','undistinguish2-{{c.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-id-badge text-info mr-2"></i>Undistinguish</button>
{% endif %}
{% if v.admin_level < PERMS['POST_COMMENT_MODERATION'] %}
{% if c.parent_post and v.id == c.post.author_id %}
<button type="button" id="pin2-{{c.id}}" class="list-group-item {% if c.stickied %}d-none{% endif %} text-info" data-bs-target="#actionsModal-{{c.id}}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/pin_comment/{{c.id}}','pin2-{{c.id}}','unpin2-{{c.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-info mr-2"></i>Pin</button>
<button type="button" id="unpin2-{{c.id}}" class="list-group-item {% if not c.stickied %}d-none{% endif %} text-info" data-bs-target="#actionsModal-{{c.id}}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/unpin_comment/{{c.id}}','pin2-{{c.id}}','unpin2-{{c.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-info mr-2"></i>Unpin</button>
{% elif c.post.hole and v.mods_hole(c.post.hole) %}
{% elif v.mods_hole(c.post.hole) %}
<button type="button" id="pin2-{{c.id}}" class="list-group-item {% if c.stickied %}d-none{% endif %} text-info" data-bs-target="#actionsModal-{{c.id}}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/pin_comment_mod/{{c.id}}','pin2-{{c.id}}','unpin2-{{c.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-info mr-2"></i>Pin</button>
<button type="button" id="unpin2-{{c.id}}" class="list-group-item {% if not c.stickied %}d-none{% endif %} text-info" data-bs-target="#actionsModal-{{c.id}}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/unpin_comment_mod/{{c.id}}','pin2-{{c.id}}','unpin2-{{c.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-info mr-2"></i>Unpin</button>
{% endif %}
@ -652,7 +663,7 @@
{% if c.parent_post %}
{% set hole = c.post.hole %}
{% if hole and v.mods_hole(hole) and not c.author.mods_hole(hole) %}
{% if v.mods_hole(hole) and not c.author.mods_hole(hole) %}
<button type="button" data-bs-dismiss="modal" id="exile2-{{c.id}}" class="{% if c.author.exiler_username(hole) %}d-none{% endif %} list-group-item text-danger" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/exile/comment/{{c.id}}','exile2-{{c.id}}','unexile2-{{c.id}}','d-none')"><i class="fas fa-campfire text-danger mr-2"></i>Exile user</button>
<button type="button" data-bs-dismiss="modal" id="unexile2-{{c.id}}" class="{% if not c.author.exiler_username(hole) %}d-none{% endif %} list-group-item text-success" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{hole}}/unexile/{{c.author_id}}','exile2-{{c.id}}','unexile2-{{c.id}}','d-none')"><i class="fas fa-campfire text-success mr-2"></i>Unexile user</button>
{% endif %}
@ -688,8 +699,8 @@
{% endif %}
{% if v.admin_level >= PERMS['POST_COMMENT_DISTINGUISH'] %}
<button type="button" id="distinguish2-{{c.id}}" class="list-group-item {% if c.distinguish_level %}d-none{% endif %} text-info" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/distinguish_comment/{{c.id}}','distinguish2-{{c.id}}','undistinguish2-{{c.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-id-badge text-info mr-2"></i>Distinguish</button>
<button type="button" id="undistinguish2-{{c.id}}" class="list-group-item {% if not c.distinguish_level %}d-none{% endif %} text-info" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/distinguish_comment/{{c.id}}','distinguish2-{{c.id}}','undistinguish2-{{c.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-id-badge text-info mr-2"></i>Undistinguish</button>
<button type="button" id="distinguish2-{{c.id}}" class="list-group-item {% if c.distinguished %}d-none{% endif %} text-info" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/distinguish_comment/{{c.id}}','distinguish2-{{c.id}}','undistinguish2-{{c.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-id-badge text-info mr-2"></i>Distinguish</button>
<button type="button" id="undistinguish2-{{c.id}}" class="list-group-item {% if not c.distinguished %}d-none{% endif %} text-info" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/distinguish_comment/{{c.id}}','distinguish2-{{c.id}}','undistinguish2-{{c.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-id-badge text-info mr-2"></i>Undistinguish</button>
{% endif %}
<button type="button" id="pin2-{{c.id}}" class="list-group-item {% if c.stickied %}d-none{% endif %} text-info" data-bs-target="#adminModal-{{c.id}}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/sticky_comment/{{c.id}}','pin2-{{c.id}}','unpin2-{{c.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-info mr-2"></i>Pin</button>

View File

@ -38,10 +38,10 @@
</a>
</li>
{% endif %}
{% if v.can_view_offsitementions %}
{% if v.can_view_offsite_mentions %}
<li class="nav-item">
<a class="nav-link py-3{% if request.path == '/notifications/reddit' %} active{% endif %}" href="/notifications/reddit">
Reddit {% if v.reddit_notifications_count %}<span class="font-weight-bold" style="color:#805ad5">({{v.reddit_notifications_count}})</span>{% endif %}
<a class="nav-link py-3{% if request.path == '/notifications/offsite' %} active{% endif %}" href="/notifications/offsite">
Offsite {% if v.offsite_notifications_count %}<span class="font-weight-bold" style="color:#805ad5">({{v.offsite_notifications_count}})</span>{% endif %}
</a>
</li>
{% endif %}

View File

@ -175,7 +175,7 @@
{{p.realbody(v) | safe}}
{% if p.is_banned %}
<div class="text-removed mb-0">Removed by @{{p.ban_reason}} (Site Admin)</div>
<div class="text-removed mb-0">Removed by @{{p.ban_reason}} (site admin)</div>
{% endif %}
</div>
{% if not p.ghost %}

View File

@ -58,9 +58,9 @@
<button type="button" class="dropdown-item {% if not p.new %} d-none{% endif %} list-inline-item text-info" id="{{p.id}}-unsort-new" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this, '/post/{{p.id}}/hot', '{{p.id}}-unsort-new', '{{p.id}}-sort-new', 'd-none', 'null')"><i class="fas fa-fire text-center mr-2"></i>Set Default Sort Hot</button>
{% endif %}
{% if v.admin_level >= PERMS['POST_COMMENT_DISTINGUISH'] %}
<button type="button" id="distinguish-{{p.id}}" class="dropdown-item {% if p.distinguish_level %}d-none{% endif %} list-inline-item text-info" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/distinguish/{{p.id}}','distinguish-{{p.id}}','undistinguish-{{p.id}}','d-none')"><i class="fas fa-crown"></i>Distinguish</button>
<button type="button" id="undistinguish-{{p.id}}" class="dropdown-item {% if not p.distinguish_level %}d-none{% endif %} list-inline-item text-info" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/distinguish/{{p.id}}','distinguish-{{p.id}}','undistinguish-{{p.id}}','d-none')"><i class="fas fa-crown"></i>Undistinguish</button>
{% if v.admin_level >= PERMS['POST_COMMENT_DISTINGUISH'] or v.mods_hole(p.hole) %}
<button type="button" id="distinguish-{{p.id}}" class="dropdown-item {% if p.distinguished %}d-none{% endif %} list-inline-item text-info" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/distinguish/{{p.id}}','distinguish-{{p.id}}','undistinguish-{{p.id}}','d-none')"><i class="fas fa-crown"></i>Distinguish</button>
<button type="button" id="undistinguish-{{p.id}}" class="dropdown-item {% if not p.distinguished %}d-none{% endif %} list-inline-item text-info" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/distinguish/{{p.id}}','distinguish-{{p.id}}','undistinguish-{{p.id}}','d-none')"><i class="fas fa-crown"></i>Undistinguish</button>
{% endif %}
{% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}
@ -68,7 +68,7 @@
<button type="button" id="unpin-{{p.id}}" class="dropdown-item {% if not p.stickied %}d-none{% endif %} list-inline-item text-info" data-nonce="{{g.nonce}}" data-onclick="unpinPost(this, '{{p.id}}')"><i class="fas fa-thumbtack fa-rotate--45"></i>Unpin</button>
{% endif %}
{% if p.hole and v.mods_hole(p.hole) %}
{% if v.mods_hole(p.hole) %}
<button type="button" id="hole-pin-{{p.id}}" class="dropdown-item {% if p.hole_pinned %}d-none{% endif %} list-inline-item text-info" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/hole_pin/{{p.id}}','hole-pin-{{p.id}}','hole-unpin-{{p.id}}','d-none')"><i class="fas fa-thumbtack fa-rotate--45"></i>Pin to /h/{{p.hole}}</button>
<button type="button" id="hole-unpin-{{p.id}}" class="dropdown-item {% if not p.hole_pinned %}d-none{% endif %} list-inline-item text-info" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/hole_unpin/{{p.id}}','hole-pin-{{p.id}}','hole-unpin-{{p.id}}','d-none')"><i class="fas fa-thumbtack fa-rotate--45"></i>Unpin from /h/{{p.hole}}</button>
{% endif %}
@ -83,7 +83,7 @@
<button type="button" id="unblock-{{p.id}}" class="dropdown-item text-success list-inline-item {% if not p.is_blocking %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/unblock_user?username={{p.author_name}}','block-{{p.id}}','unblock-{{p.id}}','d-none')"><i class="fas fa-eye text-success"></i>Unblock user</button>
{% endif %}
{% if p.hole and v.mods_hole(p.hole) %}
{% if v.mods_hole(p.hole) %}
<button type="button" class="dropdown-item list-inline-item text-danger" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/kick/{{p.id}}')"><i class="fas fa-sign-out text-danger"></i>Kick</button>
{% if not p.author.mods_hole(p.hole) %}
<button type="button" id="exile-{{p.id}}" class="{% if p.author.exiler_username(p.hole) %}d-none{% endif %} dropdown-item list-inline-item text-danger" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/exile/post/{{p.id}}','exile-{{p.id}}','unexile-{{p.id}}','d-none')"><i class="fas fa-campfire text-danger"></i>Exile user</button>
@ -91,7 +91,7 @@
{% endif %}
{% endif %}
{% if (v.id == p.author_id or v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or (p.hole and v.mods_hole(p.hole))) %}
{% if (v.id == p.author_id or v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or v.mods_hole(p.hole)) %}
{% if FEATURES['NSFW_MARKING'] %}
<button type="button" id="mark-{{p.id}}" class="dropdown-item {% if p.nsfw %}d-none{% endif %} list-inline-item text-danger" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/mark_post_nsfw/{{p.id}}','mark-{{p.id}}','unmark-{{p.id}}','d-none')"><i class="fas fa-eye-evil"></i>Mark NSFW</button>
<button type="button" id="unmark-{{p.id}}" class="dropdown-item {% if not p.nsfw %}d-none{% endif %} list-inline-item text-success" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/unmark_post_nsfw/{{p.id}}','mark-{{p.id}}','unmark-{{p.id}}','d-none')"><i class="fas fa-eye-evil"></i>Unmark NSFW</button>

View File

@ -35,11 +35,6 @@
<button type="button" id="unpin-profile2-{{p.id}}" class="{% if not p.is_pinned %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-muted text-left" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/pin/{{p.id}}','pin-profile2-{{p.id}}','unpin-profile2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center mr-2"></i>Unpin from profile</button>
{% endif %}
{% if p.hole and v.mods_hole(p.hole) %}
<button type="button" id="hole-pin2-{{p.id}}" class="{% if p.hole_pinned %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-info" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/hole_pin/{{p.id}}','hole-pin2-{{p.id}}','hole-unpin2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center text-info mr-2"></i>Pin to /h/{{p.hole}}</button>
<button type="button" id="hole-unpin2-{{p.id}}" class="{% if not p.hole_pinned %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-info" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/hole_unpin/{{p.id}}','hole-pin2-{{p.id}}','hole-unpin2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center text-info mr-2"></i>Unpin from /h/{{p.hole}}</button>
{% endif %}
{% if v.id == p.author_id %}
<button type="button" id="delete-{{p.id}}" class="{% if p.deleted_utc %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-danger" data-bs-toggle="modal" data-bs-dismiss="modal" data-bs-target="#deletePostModal" data-nonce="{{g.nonce}}" data-onclick="delete_postModal('{{p.id}}')"><i class="fas fa-trash-alt mr-2"></i>Delete</button>
<button type="button" id="undelete-{{p.id}}" class="{% if not p.deleted_utc %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-success" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/undelete_post/{{p.id}}', 'delete-{{p.id}}', 'undelete-{{p.id}}','d-none')" data-toggleelement="#post-{{p.id}}" data-toggleattr="deleted" data-bs-dismiss="modal"><i class="fas fa-trash-alt text-center mr-2"></i>Undelete</button>
@ -54,7 +49,7 @@
{% endif %}
{% endif %}
{% if v.id == p.author_id or (p.hole and v.mods_hole(p.hole)) %}
{% if v.id == p.author_id or v.mods_hole(p.hole) %}
{% if FEATURES['NSFW_MARKING'] %}
<button type="button" id="mark3-{{p.id}}" class="{% if p.nsfw %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-danger" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/mark_post_nsfw/{{p.id}}','mark3-{{p.id}}','unmark3-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-eye-evil text-center mr-2"></i>Mark NSFW</button>
<button type="button" id="unmark3-{{p.id}}" class="{% if not p.nsfw %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-success" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/unmark_post_nsfw/{{p.id}}','mark3-{{p.id}}','unmark3-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-eye-evil text-center mr-2"></i>Unmark NSFW</button>
@ -66,7 +61,16 @@
{% endif %}
{% endif %}
{% if p.hole and v.mods_hole(p.hole) %}
{% if v.mods_hole(p.hole) %}
{% if v.admin_level < PERMS['POST_COMMENT_DISTINGUISH'] %}
<button type="button" id="distinguish2-{{p.id}}" class="{% if p.distinguished %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-primary" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/distinguish/{{p.id}}','distinguish2-{{p.id}}','undistinguish2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-crown text-center text-primary mr-2"></i>Distinguish</button>
<button type="button" id="undistinguish2-{{p.id}}" class="{% if not p.distinguished %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-primary" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/distinguish/{{p.id}}','distinguish2-{{p.id}}','undistinguish2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-crown text-center text-primary mr-2"></i>Undistinguish</button>
{% endif %}
<button type="button" id="hole-pin2-{{p.id}}" class="{% if p.hole_pinned %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-info" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/hole_pin/{{p.id}}','hole-pin2-{{p.id}}','hole-unpin2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center text-info mr-2"></i>Pin to /h/{{p.hole}}</button>
<button type="button" id="hole-unpin2-{{p.id}}" class="{% if not p.hole_pinned %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-info" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/hole_unpin/{{p.id}}','hole-pin2-{{p.id}}','hole-unpin2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center text-info mr-2"></i>Unpin from /h/{{p.hole}}</button>
<button type="button" data-bs-dismiss="modal" class="nobackground btn btn-link btn-block btn-lg text-left text-danger" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/kick/{{p.id}}')"><i class="fas fa-sign-out text-danger text-center mr-2"></i>Kick</button>
{% if not p.author.mods_hole(p.hole) %}

View File

@ -23,9 +23,9 @@
{% endif %}
{% if v.admin_level >= PERMS['POST_COMMENT_DISTINGUISH'] %}
<button type="button" id="distinguish2-{{p.id}}" class="{% if p.distinguish_level %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-primary" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/distinguish/{{p.id}}','distinguish2-{{p.id}}','undistinguish2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-crown text-center text-primary mr-2"></i>Distinguish</button>
<button type="button" id="distinguish2-{{p.id}}" class="{% if p.distinguished %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-primary" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/distinguish/{{p.id}}','distinguish2-{{p.id}}','undistinguish2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-crown text-center text-primary mr-2"></i>Distinguish</button>
<button type="button" id="undistinguish2-{{p.id}}" class="{% if not p.distinguish_level %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-primary" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/distinguish/{{p.id}}','distinguish2-{{p.id}}','undistinguish2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-crown text-center text-primary mr-2"></i>Undistinguish</button>
<button type="button" id="undistinguish2-{{p.id}}" class="{% if not p.distinguished %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-primary" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/distinguish/{{p.id}}','distinguish2-{{p.id}}','undistinguish2-{{p.id}}','d-none')" data-bs-dismiss="modal"><i class="fas fa-crown text-center text-primary mr-2"></i>Undistinguish</button>
{% endif %}
{% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}

View File

@ -19,9 +19,9 @@
<div class="col-12">
<div id="post-{{p.id}}" class="banned {% if p.award_count('glowie', v) %}glow{% endif %} 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">
<div class="post-meta text-left d-md-none mb-1">{% if p.nsfw %}<span class="badge badge-danger">NSFW</span> {% endif %}{% if p.is_banned %}Removed by @{{p.ban_reason}} (Site Admin){% else %}[Deleted by user]{% endif %}</div>
<div class="post-meta text-left d-md-none mb-1">{% if p.nsfw %}<span class="badge badge-danger">NSFW</span> {% endif %}{% if p.is_banned %}Removed by @{{p.ban_reason}} (site admin){% else %}[Deleted by user]{% endif %}</div>
<h5 class="card-title post-title text-left mb-0 mb-md-1">{{p.plaintitle(v)}}</h5>
<div class="post-meta text-left d-mob-none">{% if p.nsfw %}<span class="badge badge-danger">NSFW</span> {% endif %}{% if p.is_banned %}Removed by @{{p.ban_reason}} (Site Admin){% else %}[Deleted by user]{% endif %}</div>
<div class="post-meta text-left d-mob-none">{% if p.nsfw %}<span class="badge badge-danger">NSFW</span> {% endif %}{% if p.is_banned %}Removed by @{{p.ban_reason}} (site admin){% else %}[Deleted by user]{% endif %}</div>
</div>
<div id="voting" class="d-md-block my-auto mr-3 text-center">
<div class="post-{{p.id}}-up arrow-up mx-auto"></div>

View File

@ -1,6 +1,5 @@
<h3 style="filter: sepia(100%) saturate(500%) hue-rotate(60deg) drop-shadow(-4px 4px 10px lime);">CURRENT EVENTS:</h3>
<h4 style="filter: sepia(50%) saturate(500%) hue-rotate(10deg) drop-shadow(-1px 1px 5px hotpink);"><a href="/post/213373/the-rdrama-marseysex-project" rel="nofollow" target="_blank">rDrama Marseydex Project</a></h4><sup>8 badges, 500dc per emoji, no limit</sup><br>
<h4 style="filter: sepia(50%) saturate(500%) hue-rotate(10deg) drop-shadow(-1px 1px 5px hotpink);"><a href="/post/155945/platyrich-marseybux-opportunity-real-platyrich" rel="nofollow" target="_blank">Find Rightoid Drama</a></h4><sup>500 mbux per post, no limit</sup><br>
<h4 style="filter: sepia(50%) saturate(500%) hue-rotate(10deg) drop-shadow(-1px 1px 5px hotpink);"><a href="/post/155945/platyrich-marseybux-opportunity-real-platyrich" target="_blank" rel="nofollow">Find Rightoid Drama</a></h4><sup>500 mbux per post, no limit</sup><br>
<hr>
<hr>
<hr>
@ -10,7 +9,7 @@
<ul>
<li><p>Asking to see who saved comments/posts=1 day ban</p></li>
<li><p>You must be 18 or older to view this site.</p></li>
<li><p><strong><a href="/post/19711/a-short-guide-on-how-to" rel="nofollow" target="_blank">NO RIGHTWING AGENDAPOSTING.</a></strong></p></li>
<li><p><strong><a href="/post/19711/a-short-guide-on-how-to" target="_blank" rel="nofollow">NO RIGHTWING AGENDAPOSTING.</a></strong></p></li>
<li><p>Discord users will be banned on sight.</p></li>
<li><p>Don't post anything illegal.</p></li>
<li><p>No sexualizing minors, even as a joke. This includes cartoons.</p></li>

View File

@ -73,10 +73,6 @@
<div style="display: inline-block; width: 150px; text-align: center">Post Title Only:</div>
<button type="button" data-nonce="{{g.nonce}}" data-onclick="addParam(this, 'bool')" class="searchparam mb-1">title:true</button>
</div>
<div>
<div style="display: inline-block; width: 150px; text-align: center">Exact Match Only:</div>
<button type="button" data-nonce="{{g.nonce}}" data-onclick="addParam(this, 'bool')" class="searchparam mb-1">exact:true</button>
</div>
{% if SITE_NAME != 'WPD' %}
<div>
<div style="display: inline-block; width: 150px; text-align: center">Subreddit:</div>

View File

@ -1,7 +1,7 @@
<div class="col sidebar text-left {% if not request.path.startswith('/sidebar') %}d-none d-lg-block{% endif %} pt-2" {% if request.path != '/sidebar' %}id="sidebar-content"{% endif %}>
<h5 class="text-center mt-0 mt-md-2 mb-4">
Top poster of the day:
Top Poster of the Day:
<p>
{% with user=poster_of_the_day() %}
{% include "user_in_table.html" %}
@ -11,7 +11,7 @@
<a href="/users">
<h5 class="text-center mt-0 mt-md-2 mb-4">
Current registered users: {{current_registered_users()}}
Current Registered Users: {{current_registered_users()}}
</h5>
</a>

View File

@ -1,7 +1,7 @@
<div class="col sidebar text-left {% if not request.path.startswith('/sidebar') %}d-none d-lg-block{% endif %} pt-2" {% if request.path != '/sidebar' %}id="sidebar-content"{% endif %}>
<h5 class="text-center mt-0 mt-md-2 mb-4">
Top poster of the day:
Top Poster of the Day:
<p>
{% with user=poster_of_the_day() %}
{% include "user_in_table.html" %}
@ -11,7 +11,7 @@
<a href="/users">
<h5 class="text-center mt-0 mt-md-2 mb-4">
Current registered users: {{current_registered_users()}}
Current Registered Users: {{current_registered_users()}}
</h5>
</a>

View File

@ -38,7 +38,7 @@
<input autocomplete="off" type="text" id="name" class="form-control" name="name" maxlength="30" pattern='[a-zA-Z0-9]{1,30}' placeholder="Required" value="{{name}}" required>
<label class="mt-3" for="author">Author</label>
<input autocomplete="off" type="text" id="author" class="form-control" name="author" maxlength="30" pattern='[a-zA-Z0-9_\-]{1,30}' placeholder="Required" value="{{username}}" required>
<input autocomplete="off" type="text" id="author" class="form-control" name="author" maxlength="30" pattern='[a-zA-Z0-9_\-]{1,30}|\?{3}' placeholder="Required" value="{{username}}" required>
<label class="mt-3" for="tags">Tags (must be separated by spaces)</label>
<input autocomplete="off" type="text" id="tags" class="form-control" name="tags" maxlength="200" pattern='[a-zA-Z0-9: ]{1,200}' placeholder="Required" value="{{tags}}" required>
@ -71,14 +71,14 @@
<div id="{{emoji.name}}-emoji" class="settings-section rounded">
<div class="d-lg-flex">
<div class="body w-lg-100">
<input hidden name="formkey" value="{{v|formkey}}">
<input hidden value="{{v|formkey}}">
<div><label class="mt-3">Image</label></div>
<img loading="lazy" src="{{SITE_FULL_IMAGES}}/asset_submissions/emojis/{{emoji.name}}.webp?s={{range(1, 10000000)|random}}" style="max-width:50%;border:5px white solid">
<div><label class="mt-3" for="{{emoji.name}}-kind">Kind</label></div>
<div class="input-group">
<select autocomplete="off" id='{{emoji.name}}-kind' class="form-control" name="kind" required {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'] %}disabled readonly{% endif %}>
<select autocomplete="off" id='{{emoji.name}}-kind' class="form-control" required {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'] %}disabled readonly{% endif %}>
{% for entry in EMOJI_KINDS %}
<option value="{{entry}}" {% if emoji.kind == entry %}selected{% endif %}>
{{entry}}
@ -91,23 +91,23 @@
<input autocomplete="off" type="text" id="{{emoji.name}}-submitter" class="form-control" maxlength="30" value="{{emoji.submitter}}" readonly>
<label class="mt-3" for="{{emoji.name}}-author">Author</label>
<input autocomplete="off" type="text" id="{{emoji.name}}-author" class="form-control" maxlength="30" value="{{emoji.author}}" readonly>
<input autocomplete="off" type="text" id="{{emoji.name}}-author" class="form-control" maxlength="30" value="{{emoji.author}}" pattern='[a-zA-Z0-9_\-]{1,30}|\?{3}' placeholder="Required" required {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'] %}readonly{% endif %}>
<label class="mt-3" for="{{emoji.name}}-name">Emoji Name</label>
<input autocomplete="off" type="text" id="{{emoji.name}}-name" class="form-control" name="name" maxlength="30" value="{{emoji.name}}" pattern='emoji[a-z0-9]{1,24}' placeholder="Required" required {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'] %}readonly{% endif %}>
<input autocomplete="off" type="text" id="{{emoji.name}}-name" class="form-control" maxlength="30" value="{{emoji.name}}" pattern='emoji[a-z0-9]{1,24}' placeholder="Required" required {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'] %}readonly{% endif %}>
<label class="mt-3" for="{{emoji.name}}-tags">Tags</label>
<input autocomplete="off" type="text" id="{{emoji.name}}-tags" class="form-control" name="tags" maxlength="200" value="{{emoji.tags}}" pattern='[a-z0-9: ]{1,200}' placeholder="Required" required {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'] %}readonly{% endif %}>
<input autocomplete="off" type="text" id="{{emoji.name}}-tags" class="form-control" maxlength="200" value="{{emoji.tags}}" pattern='[a-z0-9: ]{1,200}' placeholder="Required" required {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'] %}readonly{% endif %}>
<div class="custom-control custom-checkbox mt-4 pt-1 ml-1">
<input autocomplete="off" type="checkbox" class="custom-control-input" id="{{emoji.name}}-nsfw" name="nsfw" {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'] %}readonly{% endif %} {% if emoji.nsfw %}checked{% endif %}>
<input autocomplete="off" type="checkbox" class="custom-control-input" id="{{emoji.name}}-nsfw" {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'] %}readonly{% endif %} {% if emoji.nsfw %}checked{% endif %}>
<label class="custom-control-label" for="{{emoji.name}}-nsfw">NSFW</label>
</div>
</div>
</div>
{% if v.admin_level >= PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'] or v.id == emoji.submitter_id %}
<div class="d-flex my-4 mx-3">
<input autocomplete="off" type="text" id="{{emoji.name}}-comment" class="form-control mr-4" name="comment" placeholder="Comment..." maxlength="500" {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'] %}hidden{% endif %}>
<input autocomplete="off" type="text" id="{{emoji.name}}-comment" class="form-control mr-4" placeholder="Comment..." maxlength="500" {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'] %}hidden{% endif %}>
<button type="button" class="btn btn-danger ml-auto" data-nonce="{{g.nonce}}" data-onclick="remove_emoji(this, '{{emoji.name}}')">Remove</button>
{% if v.admin_level >= PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'] %}

View File

@ -51,7 +51,15 @@
<i id='hole-pinned-{{p.id}}' class="fas fa-thumbtack fa-rotate--45 pr-1 ml-1 mt-3 text-blue" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Pinned to /h/{{p.hole}} by @{{p.hole_pinned}}"></i>
{% endif %}
{% if p.distinguish_level %}<i class="fas fa-broom text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{SITE_NAME}} Admin, speaking officially"></i>{% endif %}
{% if p.distinguished %}
<i class="fas fa-broom text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="
{%- if p.author.mods_hole(p.hole) -%}
/h/{{p.hole}} mod
{%- else -%}
{{SITE_NAME}} admin
{%- endif -%}
, speaking officially"></i>
{% endif %}
{% if p.is_pinned and request.path != '/' %}
<i class="fas fa-thumbtack fa-rotate--45 pr-1 ml-1 mt-3 text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Pinned to profile"></i>
{% endif %}
@ -66,7 +74,7 @@
{% endif %}
{% if p.ghost %}
<span {% if p.distinguish_level %}class="mod {% if SITE_NAME == 'rDrama' %}mod-rdrama{% endif %}"{% endif %}>πŸ‘»</span>
<span {% if p.distinguished %}class="mod {% if SITE_NAME == 'rDrama' %}mod-rdrama{% endif %}"{% endif %}>πŸ‘»</span>
{% else %}
{% if FEATURES['PATRON_ICONS'] and p.author.patron > 1 %}
<img loading="lazy" src="{{SITE_FULL_IMAGES}}/i/{{SITE_NAME}}/badges/2{{p.author.patron}}.webp?b=11" class="patron-img" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{p.author.patron_tooltip}}" alt="{{p.author.patron_tooltip}}">
@ -85,7 +93,7 @@
<img class="profile-pic-30-hat hat" loading="lazy" src="{{p.author.hat_active(v)[0]}}?x=7" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{p.author.hat_active(v)[1]}}" alt="@{{p.author.username}}'s hat">
{%- endif %}
</div>
<span {% if p.author.patron and not p.distinguish_level %}class="patron" style="background-color:#{{p.author.name_color}}"{% elif p.distinguish_level %}class="mod {% if SITE_NAME == 'rDrama' %}mod-rdrama{% endif %}"{% endif %} {% if p.author.pride_username(v) %}pride_username{% endif %}>{{p.author_name}}</span>
<span {% if p.author.patron and not p.distinguished %}class="patron" style="background-color:#{{p.author.name_color}}"{% elif p.distinguished %}class="mod {% if SITE_NAME == 'rDrama' %}mod-rdrama{% endif %}"{% endif %} {% if p.author.pride_username(v) %}pride_username{% endif %}>{{p.author_name}}</span>
</a>
{% if FEATURES['PRONOUNS'] %}
<span class="pronouns" style="color:#{{p.author.flaircolor}} !important;border-color:#{{p.author.flaircolor}} !important">{{p.author.pronouns_display}}</span>

View File

@ -0,0 +1 @@
alter table users rename column last_viewed_reddit_notifs to last_viewed_offsite_notifs;

View File

@ -0,0 +1,9 @@
alter table posts add column distinguished bool default false not null;
update posts set distinguished=true where distinguish_level>0;
alter table comments add column distinguished bool default false not null;
update comments set distinguished=true where distinguish_level>0;
alter table posts alter column distinguished drop default;
alter table posts drop column distinguish_level;
alter table comments alter column distinguished drop default;
alter table comments drop column distinguish_level;

View File

@ -163,7 +163,7 @@ CREATE TABLE public.users (
rainbow integer,
spider integer,
profanityreplacer integer DEFAULT 1 NOT NULL,
last_viewed_reddit_notifs integer NOT NULL,
last_viewed_offsite_notifs integer NOT NULL,
profile_background character varying(167),
chudded_by integer,
blacklisted_by integer,
@ -426,7 +426,6 @@ CREATE TABLE public.comments (
created_utc integer NOT NULL,
parent_post integer,
is_banned boolean DEFAULT false NOT NULL,
distinguish_level integer DEFAULT 0 NOT NULL,
edited_utc integer DEFAULT 0 NOT NULL,
deleted_utc integer DEFAULT 0 NOT NULL,
is_approved integer,
@ -459,7 +458,8 @@ CREATE TABLE public.comments (
queened boolean NOT NULL,
sharpened boolean NOT NULL,
num_of_pinned_children integer NOT NULL,
body_ts tsvector GENERATED ALWAYS AS (to_tsvector('english'::regconfig, (body)::text)) STORED
body_ts tsvector GENERATED ALWAYS AS (to_tsvector('english'::regconfig, (body)::text)) STORED,
distinguished boolean NOT NULL
);
@ -834,7 +834,6 @@ CREATE TABLE public.posts (
created_utc integer NOT NULL,
is_banned boolean DEFAULT false NOT NULL,
nsfw boolean DEFAULT false NOT NULL,
distinguish_level integer DEFAULT 0 NOT NULL,
deleted_utc integer DEFAULT 0 NOT NULL,
is_approved integer,
edited_utc integer DEFAULT 0 NOT NULL,
@ -872,7 +871,8 @@ CREATE TABLE public.posts (
rainbowed boolean NOT NULL,
queened boolean NOT NULL,
sharpened boolean NOT NULL,
effortpost boolean NOT NULL
effortpost boolean NOT NULL,
distinguished boolean NOT NULL
);
@ -3073,4 +3073,3 @@ ALTER TABLE ONLY public.comments
--
-- PostgreSQL database dump complete
--

View File

@ -31,6 +31,7 @@ INSERT INTO public.badge_defs VALUES (319, 'Fistmas 23 Survivor', 'Awarded for s
INSERT INTO public.badge_defs VALUES (320, 'Best Marsey 2023', 'The creator of the best Marsey emote of 2023, as voted by rdrama users.', 1705457637);
INSERT INTO public.badge_defs VALUES (325, 'Best rdrama activist 2023', 'Went out there and touched grass for the sake of drama, and was voted the best rdrama activist of 2023.', 1705459943);
INSERT INTO public.badge_defs VALUES (326, 'Chud Hunter', 'Successfully reported wrongthink and got paid πŸ€‘', 1707748016);
INSERT INTO public.badge_defs VALUES (327, 'Top Poster of the Day', 'Has been Top Poster of the Day at least once', 1708092535);
INSERT INTO public.badge_defs VALUES (296, 'SEX!', 'This user verifiably had sex with another dramatard.', 1692195588);
INSERT INTO public.badge_defs VALUES (297, 'Weather Balloon', 'This user was shot down over the territory of /r/UFOs.', 1694716945);
INSERT INTO public.badge_defs VALUES (180, 'Marsey Consoomer', 'Conned rDrama out of sick merch in exchange for a donation to Redbubble.', 1664417205);
@ -289,7 +290,7 @@ INSERT INTO public.badge_defs VALUES (87, 'Unblockable', 'This user is unblockab
-- Name: badge_defs_id_seq; Type: SEQUENCE SET; Schema: public; Owner: -
--
SELECT pg_catalog.setval('public.badge_defs_id_seq', 326, true);
SELECT pg_catalog.setval('public.badge_defs_id_seq', 327, true);
--

View File

@ -611,6 +611,7 @@ INSERT INTO public.hat_defs VALUES (563, 'The Dundee', 'That''s not a hat. THIS
INSERT INTO public.hat_defs VALUES (566, 'Heart Crown (rainbow)', 'β€πŸ§‘πŸ’›πŸ’šπŸ’™πŸ’œ', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (565, 'Sparkles Crown', '✨✨✨', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (572, 'Heart Crown (sparkles)', 'πŸ’•πŸ’›πŸ’”πŸ’—β™₯πŸ–€βœ¨πŸ’™ or something idk', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (1447, 'Pink bowtie', 'to show everyone your cute aesthetic!', 2, 500, NULL, 1708075863);
INSERT INTO public.hat_defs VALUES (574, 'Heart Crown (Rainbow II)', 'More gay than the other rainbow heart crown πŸ‘', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (575, 'Heart Crown (superstraight)', 'πŸ–€πŸ§‘πŸ–€πŸ§‘πŸ–€πŸ§‘', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (567, 'Heart Crown (blue and purple)', 'πŸ’™πŸ’œ', 2, 500, NULL, 1662167687);
@ -1202,7 +1203,7 @@ INSERT INTO public.hat_defs VALUES (170, 'Kenny', 'User''s life insurance claim
-- Name: hat_defs_id_seq; Type: SEQUENCE SET; Schema: public; Owner: -
--
SELECT pg_catalog.setval('public.hat_defs_id_seq', 1446, true);
SELECT pg_catalog.setval('public.hat_defs_id_seq', 1447, true);
--

View File

@ -2,7 +2,7 @@ INSERT INTO public.users (
username, passhash, created_utc, admin_level, email_verified,
original_username, defaultsorting, defaultsortingcomments, defaulttime, namecolor, flaircolor, theme, themecolor,
reddit, pronouns, verified, profileurl, highres,
marsify, last_viewed_modmail_notifs, last_viewed_post_notifs, last_viewed_log_notifs, last_viewed_reddit_notifs, lifetimedonated, lifetimedonated_visible, show_sigs, grinch
marsify, last_viewed_modmail_notifs, last_viewed_post_notifs, last_viewed_log_notifs, last_viewed_offsite_notifs, lifetimedonated, lifetimedonated_visible, show_sigs, grinch
) VALUES
('AutoJanny', '', extract(epoch from now()), 0, true,
'AutoJanny', 'hot', 'top', 'day', 'ff459a', 'ff459a', 'dark', 'ff459a',

View File

@ -3296,7 +3296,7 @@ You are one of the dumbest people I have ever seen, ever. Your reading comprehen
[para]
Can we get a new leaderbaord state for deleted posts/comments. because 999% of what i post gets deleted for some reason. but im a really good person and ive never done anything wrong And this is like that book i red called 1984 last week (My techer told me to read it but i onlt red like 10 pages πŸ˜‚) but if you Idiots are going to delete my post atleast please give me something to Brag about. thanks
> Removed by @G-tix (Site Admin)
> Removed by @G-tix (site admin)
[para]
I'm a proud conservative American from Murica' but I have fallen in love with Colombia πŸ‡¨πŸ‡΄ over the past couple of years. I had my wedding down there last summer and look forward to moving there next year for a few years on their new nomad visa.