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, "tags": document.getElementById(`${name}-tags`).value,
"name": document.getElementById(`${name}-name`).value, "name": document.getElementById(`${name}-name`).value,
"kind": document.getElementById(`${name}-kind`).value, "kind": document.getElementById(`${name}-kind`).value,
"author": document.getElementById(`${name}-author`).value,
"nsfw": document.getElementById(`${name}-nsfw`).checked, "nsfw": document.getElementById(`${name}-nsfw`).checked,
}, },
() => { () => {

View File

@ -182,7 +182,7 @@ class Comment(Base):
ghost = Column(Boolean, default=False) ghost = Column(Boolean, default=False)
bannedfor = Column(String) bannedfor = Column(String)
chuddedfor = Column(String) chuddedfor = Column(String)
distinguish_level = Column(Integer, default=0) distinguished = Column(Boolean, default=False)
deleted_utc = Column(Integer, default=0) deleted_utc = Column(Integer, default=0)
is_approved = Column(Integer, ForeignKey("users.id")) is_approved = Column(Integer, ForeignKey("users.id"))
level = Column(Integer, default=1) level = Column(Integer, default=1)
@ -383,7 +383,7 @@ class Comment(Base):
'is_nsfw': self.nsfw, 'is_nsfw': self.nsfw,
'permalink': f'/comment/{self.id}#context', 'permalink': f'/comment/{self.id}#context',
'stickied': self.stickied, 'stickied': self.stickied,
'distinguish_level': self.distinguish_level, 'distinguished': self.distinguished,
'post_id': self.post.id if self.post else 0, 'post_id': self.post.id if self.post else 0,
'score': self.score, 'score': self.score,
'upvotes': self.upvotes, '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 import Column
from sqlalchemy.ext.mutable import MutableList from sqlalchemy.ext.mutable import MutableList
from sqlalchemy.orm import relationship, deferred from sqlalchemy.orm import relationship, deferred
from sqlalchemy.types import VARCHAR, Boolean, Integer from sqlalchemy.types import *
from sqlalchemy.dialects.postgresql import ARRAY from sqlalchemy.dialects.postgresql import ARRAY
from files.classes import Base from files.classes import Base
@ -15,20 +15,20 @@ from .hole_relationship import *
class Hole(Base): class Hole(Base):
__tablename__ = "holes" __tablename__ = "holes"
name = Column(VARCHAR(HOLE_NAME_COLUMN_LENGTH), primary_key=True) name = Column(String, primary_key=True)
sidebar = Column(VARCHAR(HOLE_SIDEBAR_COLUMN_LENGTH)) sidebar = Column(String)
sidebar_html = Column(VARCHAR(HOLE_SIDEBAR_HTML_COLUMN_LENGTH)) sidebar_html = Column(String)
sidebarurls = Column(MutableList.as_mutable(ARRAY(VARCHAR(HOLE_BANNER_URL_COLUMN_LENGTH))), default=MutableList([])) sidebarurls = Column(MutableList.as_mutable(ARRAY(String)), default=MutableList([]))
bannerurls = Column(MutableList.as_mutable(ARRAY(VARCHAR(HOLE_BANNER_URL_COLUMN_LENGTH))), default=MutableList([])) bannerurls = Column(MutableList.as_mutable(ARRAY(String)), default=MutableList([]))
marseyurl = Column(VARCHAR(HOLE_MARSEY_URL_LENGTH)) marseyurl = Column(String)
css = deferred(Column(VARCHAR(CSS_LENGTH_LIMIT))) css = deferred(Column(String))
stealth = Column(Boolean, default=False) stealth = Column(Boolean, default=False)
public_use = Column(Boolean, default=False) public_use = Column(Boolean, default=False)
created_utc = Column(Integer) created_utc = Column(Integer)
if SITE_NAME == 'WPD': if SITE_NAME == 'WPD':
snappy_quotes = None snappy_quotes = None
else: else:
snappy_quotes = deferred(Column(VARCHAR(HOLE_SNAPPY_QUOTES_LENGTH))) snappy_quotes = deferred(Column(String))
blocks = relationship("HoleBlock", primaryjoin="HoleBlock.hole==Hole.name") blocks = relationship("HoleBlock", primaryjoin="HoleBlock.hole==Hole.name")
followers = relationship("HoleFollow", primaryjoin="HoleFollow.hole==Hole.name") followers = relationship("HoleFollow", primaryjoin="HoleFollow.hole==Hole.name")

View File

@ -1,7 +1,7 @@
import time import time
from sqlalchemy import Column, ForeignKey from sqlalchemy import Column, ForeignKey
from sqlalchemy.orm import declared_attr from sqlalchemy.orm import relationship
from sqlalchemy.sql.sqltypes import * from sqlalchemy.sql.sqltypes import *
from files.classes import Base from files.classes import Base
@ -10,17 +10,9 @@ class HoleRelationship(Base):
__tablename__ = NotImplemented __tablename__ = NotImplemented
__abstract__ = True __abstract__ = True
@declared_attr user_id = Column(Integer, ForeignKey("users.id"), primary_key=True)
def user_id(self): hole = Column(String, ForeignKey("holes.name"), primary_key=True)
return Column(Integer, ForeignKey("users.id"), primary_key=True) created_utc = Column(Integer)
@declared_attr
def hole(self):
return Column(String(20), ForeignKey("holes.name"), primary_key=True)
@declared_attr
def created_utc(self):
return Column(Integer)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
if "created_utc" not in kwargs: kwargs["created_utc"] = int(time.time()) if "created_utc" not in kwargs: kwargs["created_utc"] = int(time.time())
@ -37,3 +29,11 @@ class HoleBlock(HoleRelationship):
class HoleFollow(HoleRelationship): class HoleFollow(HoleRelationship):
__tablename__ = "hole_follows" __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) effortpost = Column(Boolean, default=False)
views = Column(Integer, default=0) views = Column(Integer, default=0)
deleted_utc = 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 = Column(String)
stickied_utc = Column(Integer) stickied_utc = Column(Integer)
hole_pinned = Column(String) hole_pinned = Column(String)
@ -254,7 +254,7 @@ class Post(Base):
'downvotes': self.downvotes, 'downvotes': self.downvotes,
'stickied': self.stickied, 'stickied': self.stickied,
'private' : self.private, 'private' : self.private,
'distinguish_level': self.distinguish_level, 'distinguished': self.distinguished,
'voted': self.voted if hasattr(self, 'voted') else 0, 'voted': self.voted if hasattr(self, 'voted') else 0,
'reports': reports, 'reports': reports,
} }
@ -269,7 +269,10 @@ class Post(Base):
if v and v.poor: if v and v.poor:
return 0 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 return 0
num = len([x for x in self.awards if x.kind == kind]) num = len([x for x in self.awards if x.kind == kind])
@ -420,4 +423,4 @@ class Post(Base):
if self.hole == 'chudrama': if self.hole == 'chudrama':
return v.admin_level >= PERMS['POST_COMMENT_MODERATION'] return v.admin_level >= PERMS['POST_COMMENT_MODERATION']
else: 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 .award import AwardRelationship
from .badges import * from .badges import *
from .clients import * from .clients import *
from .exiles import *
from .follows import * from .follows import *
from .hats import * from .hats import *
from .mod import *
from .mod_logs import * from .mod_logs import *
from .notifications import Notification from .notifications import Notification
from .saves import * from .saves import *
@ -138,7 +136,7 @@ class User(Base):
last_viewed_modmail_notifs = Column(Integer, default=0) last_viewed_modmail_notifs = Column(Integer, default=0)
last_viewed_post_notifs = Column(Integer, default=0) last_viewed_post_notifs = Column(Integer, default=0)
last_viewed_log_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) bite = Column(Integer, default=0)
owoify = Column(Integer, default=0) owoify = Column(Integer, default=0)
sharpen = 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_modmail_notifs"] = kwargs["created_utc"]
kwargs["last_viewed_post_notifs"] = kwargs["created_utc"] kwargs["last_viewed_post_notifs"] = kwargs["created_utc"]
kwargs["last_viewed_log_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) super().__init__(**kwargs)
@ -431,6 +429,7 @@ class User(Base):
@lazy @lazy
def mods_hole(self, hole): def mods_hole(self, hole):
if not hole: return False
if self.is_permabanned or self.shadowbanned: return False if self.is_permabanned or self.shadowbanned: return False
if hole == 'test'and self.truescore >= TRUESCORE_MINIMUM: return True if hole == 'test'and self.truescore >= TRUESCORE_MINIMUM: return True
if self.admin_level >= PERMS['MODS_EVERY_HOLE']: return True if self.admin_level >= PERMS['MODS_EVERY_HOLE']: return True
@ -557,8 +556,8 @@ class User(Base):
@property @property
@lazy @lazy
def can_view_offsitementions(self): def can_view_offsite_mentions(self):
return self.offsitementions or self.admin_level >= PERMS['NOTIFICATIONS_REDDIT'] return self.has_badge(140) or self.admin_level >= PERMS['NOTIFICATIONS_OFFSITE']
@lazy @lazy
def can_edit(self, target): def can_edit(self, target):
@ -787,7 +786,7 @@ class User(Base):
Comment.deleted_utc == 0, 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 @property
@lazy @lazy
@ -797,7 +796,7 @@ class User(Base):
- self.modmail_notifications_count \ - self.modmail_notifications_count \
- self.post_notifications_count \ - self.post_notifications_count \
- self.modaction_notifications_count \ - self.modaction_notifications_count \
- self.reddit_notifications_count - self.offsite_notifications_count
@property @property
@lazy @lazy
@ -886,13 +885,13 @@ class User(Base):
@property @property
@lazy @lazy
def reddit_notifications_count(self): def offsite_notifications_count(self):
if not self.can_view_offsitementions or (SITE == "watchpeopledie.tv" and self.id == AEVANN_ID): if not self.can_view_offsite_mentions or (SITE == "watchpeopledie.tv" and self.id == AEVANN_ID):
return 0 return 0
return g.db.query(Comment).filter( 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.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() Comment.parent_post == None, Comment.author_id == AUTOJANNY_ID).count()
@property @property
@ -909,8 +908,8 @@ class User(Base):
return 'posts' return 'posts'
elif self.modaction_notifications_count > 0: elif self.modaction_notifications_count > 0:
return 'modactions' return 'modactions'
elif self.reddit_notifications_count > 0: elif self.offsite_notifications_count > 0:
return 'reddit' return 'offsite'
return '' return ''
@property @property
@ -922,7 +921,7 @@ class User(Base):
'modmail': '#f15387', 'modmail': '#f15387',
'posts': '#0000ff', 'posts': '#0000ff',
'modactions': '#1ad80d', 'modactions': '#1ad80d',
'reddit': '#805ad5', 'offsite': '#805ad5',
} }
return colors[self.notifications_do] if self.notifications_do \ return colors[self.notifications_do] if self.notifications_do \
else colors[''] else colors['']
@ -1288,11 +1287,6 @@ class User(Base):
def unblockable(self): def unblockable(self):
return self.has_badge(87) return self.has_badge(87)
@property
@lazy
def offsitementions(self):
return self.has_badge(140)
@lazy @lazy
def pride_username(self, v): def pride_username(self, v):
return not (v and v.poor) and self.has_badge(303) 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.notifications import Notification
from files.classes.polls import CommentOption, PostOption from files.classes.polls import CommentOption, PostOption
from files.classes.award import AwardRelationship 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.alerts import send_repeatable_notification, push_notif
from files.helpers.config.const import * from files.helpers.config.const import *
@ -241,7 +241,7 @@ def execute_snappy(post, v):
if len(body_html) < COMMENT_BODY_HTML_LENGTH_LIMIT: if len(body_html) < COMMENT_BODY_HTML_LENGTH_LIMIT:
c = Comment(author_id=SNAPPY_ID, c = Comment(author_id=SNAPPY_ID,
distinguish_level=6, distinguished=True,
parent_post=post.id, parent_post=post.id,
level=1, level=1,
nsfw=False, nsfw=False,
@ -314,7 +314,7 @@ def execute_zozbot(c, level, post, v):
body_html='<p class="zozbot">zoz</p>', body_html='<p class="zozbot">zoz</p>',
top_comment_id=c.top_comment_id, top_comment_id=c.top_comment_id,
ghost=c.ghost, ghost=c.ghost,
distinguish_level=6 distinguished=True
) )
g.db.add(c2) g.db.add(c2)
@ -332,7 +332,7 @@ def execute_zozbot(c, level, post, v):
body_html='<p class="zozbot">zle</p>', body_html='<p class="zozbot">zle</p>',
top_comment_id=c.top_comment_id, top_comment_id=c.top_comment_id,
ghost=c.ghost, ghost=c.ghost,
distinguish_level=6 distinguished=True
) )
g.db.add(c3) g.db.add(c3)
@ -349,7 +349,7 @@ def execute_zozbot(c, level, post, v):
body_html='<p class="zozbot">zozzle</p>', body_html='<p class="zozbot">zozzle</p>',
top_comment_id=c.top_comment_id, top_comment_id=c.top_comment_id,
ghost=c.ghost, ghost=c.ghost,
distinguish_level=6 distinguished=True
) )
g.db.add(c4) g.db.add(c4)

View File

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

View File

@ -4,7 +4,7 @@ from files.classes.comment import Comment
from files.classes.hole import Hole from files.classes.hole import Hole
from flask import request 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): def can_see(user, other):
if isinstance(other, (Post, Comment)): if isinstance(other, (Post, Comment)):

View File

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

View File

@ -14,7 +14,6 @@ import requests
import ffmpeg import ffmpeg
import files.helpers.offsitementions as offsitementions
import files.helpers.stats as stats import files.helpers.stats as stats
import files.routes.static as route_static import files.routes.static as route_static
from files.routes.front import frontlist 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.roulette import spin_roulette_wheel
from files.helpers.sanitize import filter_emojis_only, sanitize from files.helpers.sanitize import filter_emojis_only, sanitize
from files.helpers.useractions import * 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 from files.cli import app, db_session, g
CRON_CACHE_TIMEOUT = 172800 CRON_CACHE_TIMEOUT = 172800
@ -58,7 +60,10 @@ def cron_fn(every_5m, every_1d, every_1mo):
g.db.commit() g.db.commit()
if not IS_LOCALHOST: if not IS_LOCALHOST:
offsitementions.offsite_mentions_task(cache) reddit_mentions_task()
g.db.commit()
lemmy_mentions_task()
g.db.commit() g.db.commit()
if every_1d or (not cache.get('stats') and not IS_LOCALHOST): 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): def get_hole(hole, v=None, graceful=False):
if not hole: if not hole:
if graceful: return None if graceful: return None
else: abort(404) else: abort(404, f"/h/{hole} was not found.")
hole = hole.replace('/h/', '').replace('h/', '').strip().lower() hole = hole.replace('/h/', '').replace('h/', '').strip().lower()
if not hole: if not hole:
if graceful: return None if graceful: return None
else: abort(404) else: abort(404, f"/h/{hole} was not found.")
hole = g.db.get(Hole, hole) hole = g.db.get(Hole, hole)
if not hole: if not hole:
if graceful: return None if graceful: return None
else: abort(404) else: abort(404, f"/h/{hole} was not found.")
return hole return hole
@cache.memoize(timeout=3600) @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) extension = guess_extension(file.content_type)
if not extension: if not extension:
os.remove(old) os.remove(old)
abort(400) abort(400, "Unsupported audio format.")
new = old + extension new = old + extension
try: try:
@ -101,7 +101,7 @@ def process_audio(file, v, old=None):
os.remove(old) os.remove(old)
if os.path.isfile(new): if os.path.isfile(new):
os.remove(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) os.remove(old)
@ -162,7 +162,7 @@ def process_video(file, v):
bitrate = int(video_info.get('bit_rate', 3000000)) bitrate = int(video_info.get('bit_rate', 3000000))
except: except:
os.remove(old) 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': if codec != 'h264':
copyfile(old, new) copyfile(old, new)
@ -177,7 +177,7 @@ def process_video(file, v):
os.remove(old) os.remove(old)
if os.path.isfile(new): if os.path.isfile(new):
os.remove(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) os.remove(old)
@ -227,7 +227,7 @@ def process_image(filename, v, resize=0, trim=False, uploader_id=None):
except: except:
os.remove(filename) os.remove(filename)
if has_request and not filename.startswith('/chat_images/'): 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 return None
params.append(filename) params.append(filename)

View File

@ -1,36 +1,23 @@
import time
import itertools
import requests import requests
from flask_caching import Cache
from flask import g from flask import g
from sqlalchemy import or_
import files.helpers.config.const as const from files.helpers.config.const import *
from files.classes.badges import Badge
from files.classes.comment import Comment from files.classes.comment import Comment
from files.classes.user import User
from files.helpers.sanitize import * from files.helpers.sanitize import *
from files.helpers.alerts import push_notif from files.helpers.alerts import push_notif
from files.classes.notifications import Notification from files.classes.notifications import Notification
# Note: while https://api.pushshift.io/meta provides the key def reddit_mentions_task():
# server_ratelimit_per_minute, in practice Cloudflare puts stricter, site_mentions = get_mentions(OFFSITE_NOTIF_QUERIES)
# 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)
notify_mentions(site_mentions) notify_mentions(site_mentions)
if const.REDDIT_NOTIFS_USERS: if REDDIT_NOTIFS_USERS:
for query, send_user in const.REDDIT_NOTIFS_USERS.items(): for query, send_user in REDDIT_NOTIFS_USERS.items():
user_mentions = get_mentions(cache, [query], reddit_notifs_users=True) user_mentions = get_mentions([query], reddit_notifs_users=True)
if user_mentions: if user_mentions:
notify_mentions(user_mentions, send_to=send_user, mention_str='mention of you') 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 = [] mentions = []
for kind in ('submission', 'comment'): for kind in ('submission', 'comment'):
q = " or ".join(queries) q = " or ".join(queries)
@ -73,33 +60,32 @@ def notify_mentions(mentions, send_to=None, mention_str='site mention'):
for m in mentions: for m in mentions:
author = m['author'] author = m['author']
permalink = m['permalink'] permalink = m['permalink']
text = sanitize(m['text'], blackjack="reddit mention", golden=False) text = (
notif_text = (
f'<p>New {mention_str} by <a href="https://old.reddit.com/user/{author}" ' 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'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">' 'rel="nofollow noopener" target="_blank">'
f'https://old.reddit.com{permalink}?context=89</a></p>' f'https://old.reddit.com{permalink}?context=8</a></p>'
f'{text}' f'{m["text"]}'
) )
text = sanitize(text, blackjack="reddit mention", golden=False)
g.db.flush() g.db.flush()
try: try:
existing_comment = g.db.query(Comment.id).filter_by( existing_comment = g.db.query(Comment.id).filter_by(
author_id=const.AUTOJANNY_ID, author_id=AUTOJANNY_ID,
parent_post=None, parent_post=None,
body_html=notif_text).one_or_none() body_html=text).one_or_none()
if existing_comment: break 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: except:
pass pass
new_comment = Comment( new_comment = Comment(
author_id=const.AUTOJANNY_ID, author_id=AUTOJANNY_ID,
parent_post=None, parent_post=None,
body_html=notif_text, body_html=text,
distinguish_level=6, distinguished=True,
created_utc=int(m['created_utc']), created_utc=int(m['created_utc']),
) )
g.db.add(new_comment) 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', 'vu','wf','ws','xn','xxx','ye','yt','yu','za','zm','zw',
# New gTLDs # New gTLDs
'app','cleaning','club','dev','farm','florist','fun','gay','lgbt','life','lol', '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', 'vip','win','world','wtf','xyz','video','host','art','media','wiki','tech',
'cooking','network','party','goog','markets','today','beauty','camp','top', 'cooking','network','party','goog','markets','today','beauty','camp','top',
'red','city','quest','works','soy','zone', '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, new_comment = Comment(author_id=AUTOJANNY_ID,
parent_post=None, parent_post=None,
body_html=text_html, body_html=text_html,
distinguish_level=6, distinguished=True,
is_bot=True) is_bot=True)
g.db.add(new_comment) g.db.add(new_comment)
g.db.flush() g.db.flush()
@ -44,7 +44,6 @@ def create_comment_duplicated(text_html):
return new_comment.id return new_comment.id
def send_repeatable_notification_duplicated(uid, text): def send_repeatable_notification_duplicated(uid, text):
if uid in BOT_IDs: return if uid in BOT_IDs: return
text_html = sanitize(text) 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'): if not url.startswith('/') and not url.startswith('https://rdrama.net') and not url.startswith('https://watchpeopledie.tv'):
try: parsed_url = urlparse(url) try: parsed_url = urlparse(url)
except: except:
print(url, flush=True) abort(400, f"Something is wrong with the url you submitted ({url}) and it couldn't be parsed.")
abort(500)
netloc = parsed_url.netloc netloc = parsed_url.netloc
path = parsed_url.path path = parsed_url.path

View File

@ -27,4 +27,4 @@ def badge_grant(user, badge_id, description=None, url=None, notify=True):
if notify: if notify:
send_repeatable_notification(user.id, send_repeatable_notification(user.id,
"@AutoJanny has given you the following profile badge:\n\n" + "@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) user = get_user(username)
if user.admin_level > v.admin_level: 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: if user.admin_level:
user.admin_level = 0 user.admin_level = 0
@ -164,7 +164,8 @@ def distribute(v, kind, option_id):
option = g.db.get(cls, 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 option.exclusive = 3
g.db.add(option) g.db.add(option)
@ -226,7 +227,7 @@ def revert_actions(v, username):
revertee = get_user(username) revertee = get_user(username)
if revertee.admin_level > v.admin_level: 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( ma = ModAction(
kind="revert", kind="revert",
@ -341,7 +342,7 @@ def reported_posts(v):
is_approved=None, is_approved=None,
is_banned=False, is_banned=False,
deleted_utc=0 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() total = listing.count()
@ -364,7 +365,7 @@ def reported_comments(v):
is_approved=None, is_approved=None,
is_banned=False, is_banned=False,
deleted_utc=0 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() total = listing.count()
@ -485,7 +486,7 @@ def badge_grant_post(v):
user = get_user(username) user = get_user(username)
try: badge_id = int(request.values.get("badge_id")) 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]: if badge_id not in [b.id for b in badges]:
abort(403, "You can't grant this badge!") abort(403, "You can't grant this badge!")
@ -497,7 +498,7 @@ def badge_grant_post(v):
abort(400, "This badge requires a url!") abort(400, "This badge requires a url!")
if url: if url:
if '\\' in url: abort(400) if '\\' in url: abort(400, "Nice try nigger.")
if url.startswith(f'{SITE_FULL}/'): if url.startswith(f'{SITE_FULL}/'):
url = url.split(SITE_FULL, 1)[1] url = url.split(SITE_FULL, 1)[1]
else: else:
@ -563,10 +564,10 @@ def badge_remove_post(v):
user = get_user(username) user = get_user(username)
try: badge_id = int(request.values.get("badge_id")) 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]: 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) badge = user.has_badge(badge_id)
if not badge: continue if not badge: continue
@ -749,7 +750,7 @@ def admin_delink_relink_alt(v, username, other):
user2 = get_account(other) user2 = get_account(other)
ids = [user1.id, user2.id] ids = [user1.id, user2.id]
a = g.db.query(Alt).filter(Alt.user1.in_(ids), Alt.user2.in_(ids)).one_or_none() 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) g.db.delete(a)
cache.delete_memoized(get_alt_graph_ids, user1.id) cache.delete_memoized(get_alt_graph_ids, user1.id)
@ -869,7 +870,7 @@ def unchud(fullname, v):
def shadowban(user_id, v): def shadowban(user_id, v):
user = get_account(user_id) user = get_account(user_id)
if user.admin_level > v.admin_level: 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 user.shadowbanned = v.id
reason = request.values.get("reason", "").strip() reason = request.values.get("reason", "").strip()
@ -1000,7 +1001,7 @@ def ban_user(fullname, v):
user = get_account(fullname) user = get_account(fullname)
if user.admin_level > v.admin_level: 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: if user.is_permabanned:
abort(403, f"@{user.username} is already banned permanently!") abort(403, f"@{user.username} is already banned permanently!")
@ -1442,36 +1443,6 @@ def approve_post(post_id, v):
return {"message": "Post approved!"} 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>") @app.post("/sticky/<int:post_id>")
@feature_required('PINS') @feature_required('PINS')
@limiter.limit('1/second', scope=rpath) @limiter.limit('1/second', scope=rpath)
@ -1676,36 +1647,6 @@ def approve_comment(c_id, v):
return {"message": "Comment approved!"} 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/") @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)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID) @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' nsfw = request.values.get("nsfw") == 'true'
author = request.values.get('author').strip()
author = get_user(author)
old_name = emoji.name old_name = emoji.name
emoji.name = new_name emoji.name = new_name
emoji.kind = new_kind emoji.kind = new_kind
emoji.tags = tags emoji.tags = tags
emoji.nsfw = nsfw emoji.nsfw = nsfw
emoji.author_id = author.id
g.db.add(emoji) g.db.add(emoji)
author = get_account(emoji.author_id)
if emoji.kind == "Marsey": if emoji.kind == "Marsey":
all_by_author = g.db.query(Emoji).filter_by(kind="Marsey", author_id=author.id).count() 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: if isinstance(obj, Post) and obj.id == 210983:
abort(403, "You can't award this post!") 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!") abort(403, "Distinguished posts are immune to cosmetic awards!")
if kind == "benefactor": if kind == "benefactor":

View File

@ -326,7 +326,7 @@ def comment(v):
c_jannied = Comment(author_id=AUTOJANNY_ID, c_jannied = Comment(author_id=AUTOJANNY_ID,
parent_post=post_target.id if posting_to_post else None, parent_post=post_target.id if posting_to_post else None,
wall_user_id=post_target.id if not 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, parent_comment_id=c.id,
level=level+1, level=level+1,
is_bot=True, is_bot=True,
@ -611,7 +611,7 @@ def diff_words(answer, guess):
def toggle_comment_nsfw(cid, v): def toggle_comment_nsfw(cid, v):
comment = get_comment(cid) 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) abort(403)
comment.nsfw = not comment.nsfw comment.nsfw = not comment.nsfw
@ -625,7 +625,7 @@ def toggle_comment_nsfw(cid, v):
target_comment_id = comment.id, target_comment_id = comment.id,
) )
g.db.add(ma) 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( ma = HoleAction(
hole = comment.post.hole, hole = comment.post.hole,
kind = "set_nsfw_comment" if comment.nsfw else "unset_nsfw_comment", 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() g.db.close()
stdout.flush() 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) comment = get_comment(cid, v=v)
if not comment.stickied: 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)" comment.stickied = v.username + " (Mod)"
@ -934,7 +934,7 @@ def unpin_comment_mod(cid, v):
comment = get_comment(cid, v=v) comment = get_comment(cid, v=v)
if comment.stickied: 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 = None
comment.stickied_utc = None comment.stickied_utc = None

View File

@ -20,6 +20,8 @@ from files.helpers.settings import *
from files.helpers.cloudflare import * from files.helpers.cloudflare import *
from files.helpers.sorting_and_time import make_age_string from files.helpers.sorting_and_time import make_age_string
from files.helpers.can_see import * 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.routehelpers import get_alt_graph, get_formkey
from files.routes.wrappers import calc_users from files.routes.wrappers import calc_users
from files.__main__ import app, cache from files.__main__ import app, cache
@ -135,12 +137,21 @@ def poster_of_the_day_id():
db = db_session() 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, Post.created_utc > t,
User.admin_level == 0, 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() db.close()
return uid return uid

View File

@ -323,7 +323,7 @@ def sign_up_post(v):
new_user.admin_level = 5 new_user.admin_level = 5
new_user.coins = 100000000 new_user.coins = 100000000
new_user.marseybux = 100000000 new_user.marseybux = 100000000
del session["history"] session.pop("history", None)
if ref_id and ref_id not in session.get("history", []): if ref_id and ref_id not in session.get("history", []):
ref_user = get_account(ref_id) 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_modmail_notifs = int(time.time())
v.last_viewed_post_notifs = int(time.time()) v.last_viewed_post_notifs = int(time.time())
v.last_viewed_log_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) g.db.add(v)
return {"message": "Notifications marked as read!"} 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)
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID) @limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID)
@auth_required @auth_required
def notifications_reddit(v): def notifications_offsite(v):
page = get_page() 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( 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.parent_post == None,
Comment.author_id == AUTOJANNY_ID 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() listing = listing.order_by(Comment.created_utc.desc()).offset(PAGE_SIZE*(page-1)).limit(PAGE_SIZE).all()
for ma in listing: 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'): 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) g.db.add(v)
if v.client: return {"data":[x.json for x in listing]} 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, nsfw=False,
is_bot=True, is_bot=True,
app_id=None, app_id=None,
distinguish_level=6, distinguished=True,
body=body, body=body,
body_html=body_jannied_html, body_html=body_jannied_html,
ghost=p.ghost ghost=p.ghost
@ -795,7 +795,7 @@ def undelete_post_pid(pid, v):
def mark_post_nsfw(pid, v): def mark_post_nsfw(pid, v):
p = get_post(pid) 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) abort(403)
p.nsfw = True p.nsfw = True
@ -834,7 +834,7 @@ def mark_post_nsfw(pid, v):
def unmark_post_nsfw(pid, v): def unmark_post_nsfw(pid, v):
p = get_post(pid) 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) abort(403)
if p.nsfw and v.is_permabanned: 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})") 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!"} 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: if len(reason_html) > 350:
abort(400, "Rendered report reason is too long!") 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:] post.flair = reason_html[1:]
g.db.add(post) g.db.add(post)
if v.admin_level >= PERMS['POST_COMMENT_MODERATION']: if v.admin_level >= PERMS['POST_COMMENT_MODERATION']:

View File

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

View File

@ -3,6 +3,7 @@ import time
from calendar import timegm from calendar import timegm
from sqlalchemy.orm import load_only from sqlalchemy.orm import load_only
from sqlalchemy import select
from files.helpers.regex import * from files.helpers.regex import *
from files.helpers.sorting_and_time import * from files.helpers.sorting_and_time import *
@ -17,7 +18,6 @@ valid_params = [
'post', 'post',
'before', 'before',
'after', 'after',
'exact',
'title', 'title',
'sentto', 'sentto',
'hole', 'hole',
@ -228,16 +228,16 @@ def searchcomments(v):
else: comments = comments.filter(Comment.author_id == author.id) else: comments = comments.filter(Comment.author_id == author.id)
if 'q' in criteria: if 'q' in criteria:
tokens = map(lambda x: search_regex_1.sub('', x), criteria['q']) text = criteria['full_text']
tokens = filter(lambda x: len(x) > 0, tokens) comments = comments.filter(
tokens = map(lambda x: search_regex_2.sub("\\'", x), tokens) Comment.body_ts.bool_op("@@")(
tokens = map(lambda x: x.strip(), tokens) func.websearch_to_tsquery("english", text)
tokens = map(lambda x: search_regex_3.sub(' <-> ', x), tokens) )
comments = comments.filter(Comment.body_ts.match( )
' & '.join(tokens),
postgresql_regconfig='english'))
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: if 'hole' in criteria:
comments = comments.filter(Post.hole == criteria['hole']) comments = comments.filter(Post.hole == criteria['hole'])
@ -327,14 +327,12 @@ def searchmessages(v):
else: comments = comments.filter(Comment.author_id == author.id) else: comments = comments.filter(Comment.author_id == author.id)
if 'q' in criteria: if 'q' in criteria:
tokens = map(lambda x: search_regex_1.sub('', x), criteria['q']) text = criteria['full_text']
tokens = filter(lambda x: len(x) > 0, tokens) comments = comments.filter(
tokens = map(lambda x: search_regex_2.sub("\\'", x), tokens) Comment.body_ts.bool_op("@@")(
tokens = map(lambda x: x.strip(), tokens) func.websearch_to_tsquery("english", text)
tokens = map(lambda x: search_regex_3.sub(' <-> ', x), tokens) )
comments = comments.filter(Comment.body_ts.match( )
' & '.join(tokens),
postgresql_regconfig='english'))
comments = apply_time_filter(t, comments, Comment) 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: if len(bio_html) > BIO_FRIENDS_ENEMIES_HTML_LENGTH_LIMIT:
abort(400, "Your rendered bio is too long!") 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) g.db.add(v)
return {"message": "Your bio has been updated."} return {"message": "Your bio has been updated."}

View File

@ -31,7 +31,7 @@
<div class="user-info"> <div class="user-info">
<span class="comment-collapse-icon" data-nonce="{{g.nonce}}" data-onclick="collapse_comment('{{c.id}}')"></span> <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 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>
</div> </div>
{% if render_replies %} {% 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> <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 %} {% endif %}
{% if c.distinguish_level and not c.ghost %} {% if c.distinguished 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> <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 %} {% endif %}
{% if c.is_op %} {% if c.is_op %}
@ -174,7 +180,7 @@
{% endif %} {% endif %}
{% if c.ghost %} {% 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 %} {% else %}
{% if FEATURES['PATRON_ICONS'] and c.author.patron > 1 %} {% 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}}"> <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"> <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 %} {%- endif %}
</div> </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> </a>
{% if FEATURES['PRONOUNS'] %} {% if FEATURES['PRONOUNS'] %}
<span class="pronouns" style="color:#{{c.author.flaircolor}} !important;border-color:#{{c.author.flaircolor}} !important">{{c.author.pronouns_display}}</span> <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')}} {{macros.reports(c, 'comment')}}
{% if c.is_banned %} {% 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 %} {% endif %}
{% set realbody = c.realbody(v) %} {% 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> <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 %} {% endif %}
{% if v.admin_level >= PERMS['POST_COMMENT_DISTINGUISH'] %} {% 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.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> <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 %} {% endif %}
{% if c.parent_post %} {% if c.parent_post %}
@ -434,7 +440,7 @@
{% set url = "sticky_comment" %} {% set url = "sticky_comment" %}
{% elif v.id == c.post.author_id %} {% elif v.id == c.post.author_id %}
{% set url = "pin_comment" %} {% 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" %} {% set url = "pin_comment_mod" %}
{% endif %} {% endif %}
@ -465,7 +471,7 @@
{% if c.parent_post %} {% if c.parent_post %}
{% set hole = c.post.hole %} {% 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="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> <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 %} {% 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> <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 %} {% 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="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> <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 %} {% endif %}
@ -634,17 +640,22 @@
{% endif %} {% endif %}
{% 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="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> <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 %} {% 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 v.admin_level < PERMS['POST_COMMENT_MODERATION'] %}
{% if c.parent_post and v.id == c.post.author_id %} {% 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="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> <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="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> <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 %} {% endif %}
@ -652,7 +663,7 @@
{% if c.parent_post %} {% if c.parent_post %}
{% set hole = c.post.hole %} {% 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="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> <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 %} {% endif %}
@ -688,8 +699,8 @@
{% endif %} {% endif %}
{% if v.admin_level >= PERMS['POST_COMMENT_DISTINGUISH'] %} {% 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="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.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="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 %} {% 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> <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> </a>
</li> </li>
{% endif %} {% endif %}
{% if v.can_view_offsitementions %} {% if v.can_view_offsite_mentions %}
<li class="nav-item"> <li class="nav-item">
<a class="nav-link py-3{% if request.path == '/notifications/reddit' %} active{% endif %}" href="/notifications/reddit"> <a class="nav-link py-3{% if request.path == '/notifications/offsite' %} active{% endif %}" href="/notifications/offsite">
Reddit {% if v.reddit_notifications_count %}<span class="font-weight-bold" style="color:#805ad5">({{v.reddit_notifications_count}})</span>{% endif %} Offsite {% if v.offsite_notifications_count %}<span class="font-weight-bold" style="color:#805ad5">({{v.offsite_notifications_count}})</span>{% endif %}
</a> </a>
</li> </li>
{% endif %} {% endif %}

View File

@ -175,7 +175,7 @@
{{p.realbody(v) | safe}} {{p.realbody(v) | safe}}
{% if p.is_banned %} {% 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 %} {% endif %}
</div> </div>
{% if not p.ghost %} {% 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> <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 %} {% endif %}
{% if v.admin_level >= PERMS['POST_COMMENT_DISTINGUISH'] %} {% 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.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="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.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> <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 %} {% endif %}
{% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %} {% 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> <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 %} {% 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-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> <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 %} {% 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> <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 %} {% 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> <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) %} {% 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> <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 %}
{% 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'] %} {% 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="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> <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> <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 %} {% 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 %} {% 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="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> <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 %}
{% 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'] %} {% 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="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> <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 %}
{% 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> <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) %} {% if not p.author.mods_hole(p.hole) %}

View File

@ -23,9 +23,9 @@
{% endif %} {% endif %}
{% if v.admin_level >= PERMS['POST_COMMENT_DISTINGUISH'] %} {% 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 %} {% endif %}
{% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %} {% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}

View File

@ -19,9 +19,9 @@
<div class="col-12"> <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 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="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> <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>
<div id="voting" class="d-md-block my-auto mr-3 text-center"> <div id="voting" class="d-md-block my-auto mr-3 text-center">
<div class="post-{{p.id}}-up arrow-up mx-auto"></div> <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> <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" target="_blank" rel="nofollow">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" rel="nofollow" target="_blank">Find Rightoid Drama</a></h4><sup>500 mbux per post, no limit</sup><br>
<hr> <hr>
<hr> <hr>
<hr> <hr>
@ -10,7 +9,7 @@
<ul> <ul>
<li><p>Asking to see who saved comments/posts=1 day ban</p></li> <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>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>Discord users will be banned on sight.</p></li>
<li><p>Don't post anything illegal.</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> <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> <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> <button type="button" data-nonce="{{g.nonce}}" data-onclick="addParam(this, 'bool')" class="searchparam mb-1">title:true</button>
</div> </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' %} {% if SITE_NAME != 'WPD' %}
<div> <div>
<div style="display: inline-block; width: 150px; text-align: center">Subreddit:</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 %}> <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"> <h5 class="text-center mt-0 mt-md-2 mb-4">
Top poster of the day: Top Poster of the Day:
<p> <p>
{% with user=poster_of_the_day() %} {% with user=poster_of_the_day() %}
{% include "user_in_table.html" %} {% include "user_in_table.html" %}
@ -11,7 +11,7 @@
<a href="/users"> <a href="/users">
<h5 class="text-center mt-0 mt-md-2 mb-4"> <h5 class="text-center mt-0 mt-md-2 mb-4">
Current registered users: {{current_registered_users()}} Current Registered Users: {{current_registered_users()}}
</h5> </h5>
</a> </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 %}> <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"> <h5 class="text-center mt-0 mt-md-2 mb-4">
Top poster of the day: Top Poster of the Day:
<p> <p>
{% with user=poster_of_the_day() %} {% with user=poster_of_the_day() %}
{% include "user_in_table.html" %} {% include "user_in_table.html" %}
@ -11,7 +11,7 @@
<a href="/users"> <a href="/users">
<h5 class="text-center mt-0 mt-md-2 mb-4"> <h5 class="text-center mt-0 mt-md-2 mb-4">
Current registered users: {{current_registered_users()}} Current Registered Users: {{current_registered_users()}}
</h5> </h5>
</a> </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> <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> <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> <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> <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 id="{{emoji.name}}-emoji" class="settings-section rounded">
<div class="d-lg-flex"> <div class="d-lg-flex">
<div class="body w-lg-100"> <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> <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"> <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><label class="mt-3" for="{{emoji.name}}-kind">Kind</label></div>
<div class="input-group"> <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 %} {% for entry in EMOJI_KINDS %}
<option value="{{entry}}" {% if emoji.kind == entry %}selected{% endif %}> <option value="{{entry}}" {% if emoji.kind == entry %}selected{% endif %}>
{{entry}} {{entry}}
@ -91,23 +91,23 @@
<input autocomplete="off" type="text" id="{{emoji.name}}-submitter" class="form-control" maxlength="30" value="{{emoji.submitter}}" readonly> <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> <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> <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> <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"> <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> <label class="custom-control-label" for="{{emoji.name}}-nsfw">NSFW</label>
</div> </div>
</div> </div>
</div> </div>
{% if v.admin_level >= PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'] or v.id == emoji.submitter_id %} {% if v.admin_level >= PERMS['MODERATE_PENDING_SUBMITTED_ASSETS'] or v.id == emoji.submitter_id %}
<div class="d-flex my-4 mx-3"> <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> <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'] %} {% 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> <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 %} {% 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 != '/' %} {% 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> <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 %} {% endif %}
@ -66,7 +74,7 @@
{% endif %} {% endif %}
{% if p.ghost %} {% 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 %} {% else %}
{% if FEATURES['PATRON_ICONS'] and p.author.patron > 1 %} {% 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}}"> <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"> <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 %} {%- endif %}
</div> </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> </a>
{% if FEATURES['PRONOUNS'] %} {% if FEATURES['PRONOUNS'] %}
<span class="pronouns" style="color:#{{p.author.flaircolor}} !important;border-color:#{{p.author.flaircolor}} !important">{{p.author.pronouns_display}}</span> <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, rainbow integer,
spider integer, spider integer,
profanityreplacer integer DEFAULT 1 NOT NULL, 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), profile_background character varying(167),
chudded_by integer, chudded_by integer,
blacklisted_by integer, blacklisted_by integer,
@ -426,7 +426,6 @@ CREATE TABLE public.comments (
created_utc integer NOT NULL, created_utc integer NOT NULL,
parent_post integer, parent_post integer,
is_banned boolean DEFAULT false NOT NULL, is_banned boolean DEFAULT false NOT NULL,
distinguish_level integer DEFAULT 0 NOT NULL,
edited_utc integer DEFAULT 0 NOT NULL, edited_utc integer DEFAULT 0 NOT NULL,
deleted_utc integer DEFAULT 0 NOT NULL, deleted_utc integer DEFAULT 0 NOT NULL,
is_approved integer, is_approved integer,
@ -459,7 +458,8 @@ CREATE TABLE public.comments (
queened boolean NOT NULL, queened boolean NOT NULL,
sharpened boolean NOT NULL, sharpened boolean NOT NULL,
num_of_pinned_children integer 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, created_utc integer NOT NULL,
is_banned boolean DEFAULT false NOT NULL, is_banned boolean DEFAULT false NOT NULL,
nsfw 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, deleted_utc integer DEFAULT 0 NOT NULL,
is_approved integer, is_approved integer,
edited_utc integer DEFAULT 0 NOT NULL, edited_utc integer DEFAULT 0 NOT NULL,
@ -872,7 +871,8 @@ CREATE TABLE public.posts (
rainbowed boolean NOT NULL, rainbowed boolean NOT NULL,
queened boolean NOT NULL, queened boolean NOT NULL,
sharpened 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 -- 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 (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 (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 (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 (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 (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); 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: - -- 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 (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 (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 (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 (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 (575, 'Heart Crown (superstraight)', 'πŸ–€πŸ§‘πŸ–€πŸ§‘πŸ–€πŸ§‘', 2, 500, NULL, 1662167687);
INSERT INTO public.hat_defs VALUES (567, 'Heart Crown (blue and purple)', 'πŸ’™πŸ’œ', 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: - -- 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, username, passhash, created_utc, admin_level, email_verified,
original_username, defaultsorting, defaultsortingcomments, defaulttime, namecolor, flaircolor, theme, themecolor, original_username, defaultsorting, defaultsortingcomments, defaulttime, namecolor, flaircolor, theme, themecolor,
reddit, pronouns, verified, profileurl, highres, 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 ) VALUES
('AutoJanny', '', extract(epoch from now()), 0, true, ('AutoJanny', '', extract(epoch from now()), 0, true,
'AutoJanny', 'hot', 'top', 'day', 'ff459a', 'ff459a', 'dark', 'ff459a', '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] [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 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] [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. 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.