Merge branch 'frost' of https://github.com/Aevann1/rDrama into frost
commit
97e66b8726
|
@ -0,0 +1 @@
|
|||
|
|
@ -137,4 +137,4 @@ elif "load_chat" in argv:
|
|||
else:
|
||||
from files.routes import *
|
||||
|
||||
stdout.flush()
|
||||
stdout.flush()
|
||||
|
|
|
@ -154,4 +154,4 @@ blockquote a {
|
|||
|
||||
h5.post-title a:visited {
|
||||
color: #949494 !important;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,4 +87,4 @@
|
|||
51% {transform: translate(105vw,-86vh) rotate(180deg);}
|
||||
100% {transform: translate(-70vw,-86vh) rotate(180deg);}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,4 +106,4 @@ blockquote {
|
|||
|
||||
h5.post-title a:visited {
|
||||
color: #949494 !important;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,4 +94,4 @@ pre {
|
|||
|
||||
h5.post-title a:visited {
|
||||
color: #7a7a7a !important;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -145,4 +145,4 @@ color: var(--gray-700);
|
|||
|
||||
h5.post-title a:visited {
|
||||
color: #6e6e6e !important;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,4 +82,4 @@ blockquote {
|
|||
|
||||
h5.post-title a:visited {
|
||||
color: #7a7a7a !important;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6031,6 +6031,9 @@ g {
|
|||
.fa-hat-cowboy:before{content:"\f8c0"}
|
||||
.fa-cloud-rainbow:before{content:"\f73e"}
|
||||
.fa-telegram:before{content:"\f2c6"}
|
||||
.fa-css3-alt:before{content:"\f38b"}
|
||||
.fa-landscape:before{content:"\e1b5"}
|
||||
.fa-user-ninja:before{content:"\f504"}
|
||||
|
||||
.pronouns {
|
||||
font-size: 9px;
|
||||
|
@ -6283,4 +6286,4 @@ div.markdown {
|
|||
|
||||
.bug {
|
||||
pointer-events: none !important;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,4 +63,4 @@ body, .navbar-light, .navbar-dark, .card, .modal-content, .comment-write textare
|
|||
|
||||
h5.post-title a:visited {
|
||||
color: #6e6e6e !important;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,4 +78,4 @@ pre {
|
|||
|
||||
h5.post-title a:visited {
|
||||
color: #7a7a7a !important;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -232,4 +232,4 @@
|
|||
|
||||
h5.post-title a:visited {
|
||||
color: #b0b0b0 !important;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,4 +168,4 @@ blockquote {
|
|||
|
||||
h5.post-title a:visited {
|
||||
color: #5c5c5c !important;
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -25,4 +25,5 @@ from .casino_game import *
|
|||
from .hats import *
|
||||
from .marsey import *
|
||||
from .transactions import *
|
||||
from .streamers import *
|
||||
from .streamers import *
|
||||
from .sub_logs import *
|
||||
|
|
|
@ -76,4 +76,4 @@ class ClientAuth(Base):
|
|||
super().__init__(*args, **kwargs)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<ClientAuth(user_id={self.user_id}, oauth_client={self.oauth_client})>"
|
||||
return f"<ClientAuth(user_id={self.user_id}, oauth_client={self.oauth_client})>"
|
||||
|
|
|
@ -23,8 +23,8 @@ def normalize_urls_runtime(body, v):
|
|||
if v.reddit != 'old.reddit.com':
|
||||
body = reddit_to_vreddit_regex.sub(rf'\1https://{v.reddit}/\2/', body)
|
||||
if v.nitter:
|
||||
body = body.replace('https://twitter.com/', 'https://nitter.42l.fr/')
|
||||
body = body.replace('https://nitter.42l.fr/i/', 'https://twitter.com/i/')
|
||||
body = body.replace('https://twitter.com/', 'https://nitter.lacontrevoie.fr/')
|
||||
body = body.replace('https://nitter.lacontrevoie.fr/i/', 'https://twitter.com/i/')
|
||||
if v.imginn:
|
||||
body = body.replace('https://instagram.com/', 'https://imginn.com/')
|
||||
|
||||
|
@ -447,4 +447,4 @@ class Comment(Base):
|
|||
body += f"<strong class='ml-2'>Lost. The answer was: {wordle_answer}</strong>"
|
||||
|
||||
body += '</span>'
|
||||
return body
|
||||
return body
|
||||
|
|
|
@ -14,4 +14,4 @@ class BannedDomain(Base):
|
|||
super().__init__(*args, **kwargs)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<BannedDomain(domain={self.domain})>"
|
||||
return f"<BannedDomain(domain={self.domain})>"
|
||||
|
|
|
@ -18,4 +18,4 @@ class Exile(Base):
|
|||
super().__init__(*args, **kwargs)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Exile(user_id={self.user_id}, sub={self.sub})>"
|
||||
return f"<Exile(user_id={self.user_id}, sub={self.sub})>"
|
||||
|
|
|
@ -49,4 +49,4 @@ class CommentFlag(Base):
|
|||
|
||||
@lazy
|
||||
def realreason(self, v):
|
||||
return censor_slurs(self.reason, v)
|
||||
return censor_slurs(self.reason, v)
|
||||
|
|
|
@ -17,4 +17,4 @@ class Follow(Base):
|
|||
super().__init__(*args, **kwargs)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Follow(id={self.id})>"
|
||||
return f"<Follow(id={self.id})>"
|
||||
|
|
|
@ -61,4 +61,4 @@ class Hat(Base):
|
|||
|
||||
@lazy
|
||||
def censored_description(self, v):
|
||||
return self.hat_def.censored_description(v)
|
||||
return self.hat_def.censored_description(v)
|
||||
|
|
|
@ -17,4 +17,4 @@ class Marsey(Base):
|
|||
super().__init__(*args, **kwargs)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Marsey(name={self.name})>"
|
||||
return f"<Marsey(name={self.name})>"
|
||||
|
|
|
@ -16,4 +16,4 @@ class Mod(Base):
|
|||
super().__init__(*args, **kwargs)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Mod(user_id={self.user_id}, sub={self.sub})>"
|
||||
return f"<Mod(user_id={self.user_id}, sub={self.sub})>"
|
||||
|
|
|
@ -70,10 +70,6 @@ class ModAction(Base):
|
|||
else:
|
||||
return self._note or ""
|
||||
|
||||
@note.setter
|
||||
def note(self, x):
|
||||
self._note=x
|
||||
|
||||
@property
|
||||
@lazy
|
||||
def string(self):
|
||||
|
@ -149,16 +145,6 @@ ACTIONTYPES = {
|
|||
"icon": 'fa-user-slash',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'change_sidebar': {
|
||||
"str": 'changed the sidebar',
|
||||
"icon": 'fa-columns',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'check': {
|
||||
"str": 'gave {self.target_link} a checkmark',
|
||||
"icon": 'fa-badge-check',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'club_allow': {
|
||||
"str": 'allowed user {self.target_link} into the {cc}',
|
||||
"icon": 'fa-golf-club',
|
||||
|
@ -275,7 +261,7 @@ ACTIONTYPES = {
|
|||
"color": 'bg-success'
|
||||
},
|
||||
'make_admin': {
|
||||
"str": 'made {self.target_link} admin',
|
||||
"str": 'made {self.target_link} an admin',
|
||||
"icon": 'fa-user-crown',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
|
@ -305,7 +291,7 @@ ACTIONTYPES = {
|
|||
"color": 'bg-danger'
|
||||
},
|
||||
'pin_comment': {
|
||||
"str": 'pinned a {self.target_link}',
|
||||
"str": 'pinned {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
|
@ -389,11 +375,6 @@ ACTIONTYPES = {
|
|||
"icon": 'fa-user',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'uncheck': {
|
||||
"str": 'removed checkmark from {self.target_link}',
|
||||
"icon": 'fa-badge-check',
|
||||
"color": 'bg-muted'
|
||||
},
|
||||
'undistinguish_comment': {
|
||||
"str": 'un-distinguished {self.target_link}',
|
||||
"icon": 'fa-crown',
|
||||
|
@ -410,12 +391,12 @@ ACTIONTYPES = {
|
|||
"color": 'bg-success'
|
||||
},
|
||||
'unpin_comment': {
|
||||
"str": 'un-pinned a {self.target_link}',
|
||||
"str": 'unpinned {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"color": 'bg-muted'
|
||||
},
|
||||
'unpin_post': {
|
||||
"str": 'un-pinned post {self.target_link}',
|
||||
"str": 'unpinned post {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"color": 'bg-muted'
|
||||
},
|
||||
|
@ -448,4 +429,4 @@ ACTIONTYPES = {
|
|||
|
||||
ACTIONTYPES2 = deepcopy(ACTIONTYPES)
|
||||
ACTIONTYPES2.pop("shadowban")
|
||||
ACTIONTYPES2.pop("unshadowban")
|
||||
ACTIONTYPES2.pop("unshadowban")
|
||||
|
|
|
@ -20,4 +20,4 @@ class Notification(Base):
|
|||
super().__init__(*args, **kwargs)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Notification(id={self.id})>"
|
||||
return f"<Notification(id={self.id})>"
|
||||
|
|
|
@ -101,4 +101,4 @@ class CommentOptionVote(Base):
|
|||
super().__init__(*args, **kwargs)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<CommentOptionVote(option_id={self.option_id}, user_id={self.user_id})>"
|
||||
return f"<CommentOptionVote(option_id={self.option_id}, user_id={self.user_id})>"
|
||||
|
|
|
@ -36,4 +36,4 @@ class CommentSaveRelationship(Base):
|
|||
super().__init__(*args, **kwargs)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<CommentSaveRelationship(user_id={self.user_id}, comment_id={self.comment_id})>"
|
||||
return f"<CommentSaveRelationship(user_id={self.user_id}, comment_id={self.comment_id})>"
|
||||
|
|
|
@ -10,4 +10,4 @@ if SITE == 'pcmemes.net':
|
|||
id = Column(String, primary_key=True)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Streamer(id={self.id})>"
|
||||
return f"<Streamer(id={self.id})>"
|
||||
|
|
|
@ -65,4 +65,4 @@ class Sub(Base):
|
|||
@property
|
||||
@lazy
|
||||
def follow_num(self):
|
||||
return len(self.followers)
|
||||
return len(self.followers)
|
||||
|
|
|
@ -13,4 +13,4 @@ class SubBlock(Base):
|
|||
super().__init__(*args, **kwargs)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<SubBlock(user_id={self.user_id}, sub={self.sub})>"
|
||||
return f"<SubBlock(user_id={self.user_id}, sub={self.sub})>"
|
||||
|
|
|
@ -13,4 +13,4 @@ class SubJoin(Base):
|
|||
super().__init__(*args, **kwargs)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<SubJoin(user_id={self.user_id}, sub={self.sub})>"
|
||||
return f"<SubJoin(user_id={self.user_id}, sub={self.sub})>"
|
||||
|
|
|
@ -0,0 +1,188 @@
|
|||
from sqlalchemy import *
|
||||
from sqlalchemy.orm import relationship
|
||||
from files.__main__ import Base
|
||||
import time
|
||||
from files.helpers.lazy import lazy
|
||||
from files.helpers.const import *
|
||||
from files.helpers.regex import censor_slurs
|
||||
|
||||
class SubAction(Base):
|
||||
__tablename__ = "subactions"
|
||||
id = Column(Integer, primary_key=True)
|
||||
sub = Column(String, ForeignKey("subs.name"))
|
||||
user_id = Column(Integer, ForeignKey("users.id"))
|
||||
kind = Column(String)
|
||||
target_user_id = Column(Integer, ForeignKey("users.id"))
|
||||
target_submission_id = Column(Integer, ForeignKey("submissions.id"))
|
||||
target_comment_id = Column(Integer, ForeignKey("comments.id"))
|
||||
_note=Column(String)
|
||||
created_utc = Column(Integer)
|
||||
|
||||
user = relationship("User", primaryjoin="User.id==SubAction.user_id")
|
||||
target_user = relationship("User", primaryjoin="User.id==SubAction.target_user_id")
|
||||
target_post = relationship("Submission")
|
||||
|
||||
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"<SubAction(id={self.id})>"
|
||||
|
||||
@property
|
||||
@lazy
|
||||
def age_string(self):
|
||||
|
||||
age = int(time.time()) - self.created_utc
|
||||
|
||||
if age < 60:
|
||||
return "just now"
|
||||
elif age < 3600:
|
||||
minutes = int(age / 60)
|
||||
return f"{minutes}m ago"
|
||||
elif age < 86400:
|
||||
hours = int(age / 3600)
|
||||
return f"{hours}hr ago"
|
||||
elif age < 2678400:
|
||||
days = int(age / 86400)
|
||||
return f"{days}d ago"
|
||||
|
||||
now = time.gmtime()
|
||||
ctd = time.gmtime(self.created_utc)
|
||||
|
||||
months = now.tm_mon - ctd.tm_mon + 12 * (now.tm_year - ctd.tm_year)
|
||||
if now.tm_mday < ctd.tm_mday:
|
||||
months -= 1
|
||||
|
||||
if months < 12:
|
||||
return f"{months}mo ago"
|
||||
else:
|
||||
years = int(months / 12)
|
||||
return f"{years}yr ago"
|
||||
|
||||
@property
|
||||
@lazy
|
||||
def string(self):
|
||||
|
||||
output = ACTIONTYPES[self.kind]["str"].format(self=self, cc=CC_TITLE)
|
||||
|
||||
if self._note: output += f" <i>({self._note})</i>"
|
||||
|
||||
return output
|
||||
|
||||
@property
|
||||
@lazy
|
||||
def target_link(self):
|
||||
if self.target_user: return f'<a href="{self.target_user.url}">{self.target_user.username}</a>'
|
||||
elif self.target_post:
|
||||
if self.target_post.club: return f'<a href="{self.target_post.permalink}">{CC} ONLY</a>'
|
||||
return censor_slurs(f'<a href="{self.target_post.permalink}">{self.target_post.title_html}</a>', None)
|
||||
elif self.target_comment_id: return f'<a href="/comment/{self.target_comment_id}?context=8#context">comment</a>'
|
||||
|
||||
@property
|
||||
@lazy
|
||||
def icon(self):
|
||||
return ACTIONTYPES[self.kind]['icon']
|
||||
|
||||
@property
|
||||
@lazy
|
||||
def color(self):
|
||||
return ACTIONTYPES[self.kind]['color']
|
||||
|
||||
@property
|
||||
@lazy
|
||||
def permalink(self):
|
||||
return f"{SITE_FULL}/log/{self.id}"
|
||||
|
||||
ACTIONTYPES = {
|
||||
'exile_user': {
|
||||
"str": 'exiled user {self.target_link}',
|
||||
"icon": 'fa-user-slash',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'unexile_user': {
|
||||
"str": 'unexiled user {self.target_link}',
|
||||
"icon": 'fa-user',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'make_mod': {
|
||||
"str": 'made {self.target_link} a mod',
|
||||
"icon": 'fa-user-crown',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'remove_mod': {
|
||||
"str": 'removed {self.target_link} as mod',
|
||||
"icon": 'fa-user-crown',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'kick_post': {
|
||||
"str": 'kicked post {self.target_link}',
|
||||
"icon": 'fa-feather-alt',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'move_chudrama': {
|
||||
"str": 'moved post {self.target_link} to <a href="/h/chudrama">/h/chudrama</a>',
|
||||
"icon": 'fa-feather-alt',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'flair_post': {
|
||||
"str": 'set a flair on {self.target_link}',
|
||||
"icon": 'fa-tag',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'edit_sidebar': {
|
||||
"str": 'edited the sidebar',
|
||||
"icon": 'fa-columns',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'edit_css': {
|
||||
"str": 'edited the css',
|
||||
"icon": 'fa-css3-alt',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'change_banner': {
|
||||
"str": 'changed the banner',
|
||||
"icon": 'fa-landscape',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'change_sidebar_image': {
|
||||
"str": 'changed the sidebar image',
|
||||
"icon": 'fa-image',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'change_marsey': {
|
||||
"str": 'changed the hole marsey',
|
||||
"icon": 'fa-cat',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'pin_post': {
|
||||
"str": 'pinned post {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'unpin_post': {
|
||||
"str": 'unpinned post {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"color": 'bg-muted'
|
||||
},
|
||||
'pin_comment': {
|
||||
"str": 'pinned {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'unpin_comment': {
|
||||
"str": 'unpinned {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"color": 'bg-muted'
|
||||
},
|
||||
'enable_stealth': {
|
||||
"str": 'enabled stealth mode',
|
||||
"icon": 'fa-user-ninja',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'disable_stealth': {
|
||||
"str": 'disabled stealth mode',
|
||||
"icon": 'fa-user-ninja',
|
||||
"color": 'bg-muted'
|
||||
}
|
||||
}
|
|
@ -13,4 +13,4 @@ class SubSubscription(Base):
|
|||
super().__init__(*args, **kwargs)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<SubSubscription(user_id={self.user_id}, sub={self.sub})>"
|
||||
return f"<SubSubscription(user_id={self.user_id}, sub={self.sub})>"
|
||||
|
|
|
@ -459,4 +459,4 @@ class Submission(Base):
|
|||
|
||||
@lazy
|
||||
def active_flags(self, v):
|
||||
return len(self.filtered_flags(v))
|
||||
return len(self.filtered_flags(v))
|
||||
|
|
|
@ -17,4 +17,4 @@ class Subscription(Base):
|
|||
super().__init__(*args, **kwargs)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Subscription(id={self.id})>"
|
||||
return f"<Subscription(id={self.id})>"
|
||||
|
|
|
@ -15,4 +15,4 @@ if KOFI_TOKEN:
|
|||
claimed = Column(Boolean)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Transaction(id={self.id})>"
|
||||
return f"<Transaction(id={self.id})>"
|
||||
|
|
|
@ -281,6 +281,7 @@ class User(Base):
|
|||
|
||||
@lazy
|
||||
def mods(self, sub):
|
||||
if self.is_suspended or self.shadowbanned: return False
|
||||
return self.admin_level > 2 or bool(g.db.query(Mod.user_id).filter_by(user_id=self.id, sub=sub).one_or_none())
|
||||
|
||||
@lazy
|
||||
|
@ -948,4 +949,4 @@ class User(Base):
|
|||
if v and (v.sigs_disabled or v.poor):
|
||||
return False
|
||||
|
||||
return True
|
||||
return True
|
||||
|
|
|
@ -18,4 +18,4 @@ class UserBlock(Base):
|
|||
super().__init__(*args, **kwargs)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<UserBlock(user={self.user_id}, target={self.target_id})>"
|
||||
return f"<UserBlock(user={self.user_id}, target={self.target_id})>"
|
||||
|
|
|
@ -63,4 +63,4 @@ class CommentVote(Base):
|
|||
"vote_type":self.vote_type,
|
||||
"user":self.user.json,
|
||||
"comment":self.comment.json
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ def archiveorg(url):
|
|||
def archive_url(url):
|
||||
gevent.spawn(archiveorg, url)
|
||||
if url.startswith('https://twitter.com/'):
|
||||
url = url.replace('https://twitter.com/', 'https://nitter.42l.fr/')
|
||||
url = url.replace('https://twitter.com/', 'https://nitter.lacontrevoie.fr/')
|
||||
gevent.spawn(archiveorg, url)
|
||||
if url.startswith('https://instagram.com/'):
|
||||
url = url.replace('https://instagram.com/', 'https://imginn.com/')
|
||||
|
|
|
@ -129,4 +129,4 @@ if PUSHER_ID != 'blahblahblah':
|
|||
}
|
||||
},
|
||||
)
|
||||
stdout.flush()
|
||||
stdout.flush()
|
||||
|
|
|
@ -87,7 +87,7 @@ def award_timers(v, bot=False):
|
|||
badge = v.has_badge(171)
|
||||
if badge: g.db.delete(badge)
|
||||
if v.spider and v.spider != 1 and v.spider < now:
|
||||
v.spider = None
|
||||
v.spider = 0
|
||||
notify_if_not_bot("Your spider friend has left you!")
|
||||
badge = v.has_badge(179)
|
||||
if badge: g.db.delete(badge)
|
||||
|
|
|
@ -45,6 +45,7 @@ AJ_REPLACEMENTS = {
|
|||
SLURS = {
|
||||
"nigger": "BIPOC",
|
||||
"niglet": "BIPOClet",
|
||||
"negress": "BIPOC woman",
|
||||
"faggot": "cute twink",
|
||||
"fag": "strag",
|
||||
"spic ": "hard-working American ",
|
||||
|
@ -969,8 +970,6 @@ approved_embed_hosts = {
|
|||
'pinimg.com',
|
||||
'kindpng.com',
|
||||
'shopify.com',
|
||||
'discordapp.com',
|
||||
'discordapp.net',
|
||||
'twimg.com',
|
||||
'wikimedia.org',
|
||||
'wp.com',
|
||||
|
@ -1098,4 +1097,4 @@ forced_hats = {
|
|||
"marsify": ("Marsified", "I can't pick my own Marseys, help!"),
|
||||
"is_suspended": ("Behind Bars", "This user is banned and needs to do better!"),
|
||||
"agendaposter": ("Egg_irl", "This user is getting in touch with xir identity!")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,4 +154,4 @@ def give_monthly_marseybux_task_kofi():
|
|||
)
|
||||
g.db.add(ma)
|
||||
|
||||
return True
|
||||
return True
|
||||
|
|
|
@ -51,4 +51,4 @@ def send_changelog_message(message):
|
|||
|
||||
def send_wpd_message(message):
|
||||
data={"content": message}
|
||||
requests.post("https://discordapp.com/api/channels/1013990963846332456/messages", headers=headers, data=data, timeout=5)
|
||||
requests.post("https://discordapp.com/api/channels/1013990963846332456/messages", headers=headers, data=data, timeout=5)
|
||||
|
|
|
@ -9,4 +9,4 @@ def marsify(text):
|
|||
if len(x) > 3 and x in marsey_mappings:
|
||||
marsey = choice(marsey_mappings[x])
|
||||
new_text += f':{marsey}: '
|
||||
return new_text
|
||||
return new_text
|
||||
|
|
|
@ -135,4 +135,4 @@ def process_image(filename=None, resize=0, trim=False):
|
|||
os.remove(filename)
|
||||
abort(417)
|
||||
|
||||
return filename
|
||||
return filename
|
||||
|
|
|
@ -89,4 +89,4 @@ def notify_mentions(send_to, mentions, mention_str='site mention'):
|
|||
|
||||
for user_id in send_to:
|
||||
notif = Notification(comment_id=new_comment.id, user_id=user_id)
|
||||
g.db.add(notif)
|
||||
g.db.add(notif)
|
||||
|
|
|
@ -443,7 +443,10 @@ def normalize_url(url):
|
|||
.replace("https://streamable.com/", "https://streamable.com/e/") \
|
||||
.replace("https://streamable.com/e/e/", "https://streamable.com/e/") \
|
||||
.replace("https://search.marsey.cat/#", "https://camas.unddit.com/#") \
|
||||
.replace("https://imgur.com/", "https://i.imgur.com/")
|
||||
.replace("https://imgur.com/", "https://i.imgur.com/") \
|
||||
.replace("https://nitter.net/", "https://twitter.com/") \
|
||||
.replace("https://nitter.42l.fr/", "https://twitter.com/") \
|
||||
.replace("https://nitter.lacontrevoie.fr/", "https://twitter.com/")
|
||||
|
||||
url = imgur_regex.sub(r'\1_d.webp?maxwidth=9999&fidelity=high', url)
|
||||
url = giphy_regex.sub(r'\1.webp', url)
|
||||
|
|
|
@ -47,4 +47,4 @@ def sort_posts(sort, posts):
|
|||
elif sort == "comments":
|
||||
return posts.order_by(Submission.comment_count.desc(), Submission.created_utc.desc())
|
||||
else:
|
||||
return posts.order_by(Submission.downvotes - Submission.upvotes, Submission.created_utc.desc())
|
||||
return posts.order_by(Submission.downvotes - Submission.upvotes, Submission.created_utc.desc())
|
||||
|
|
|
@ -43,4 +43,4 @@ def check_for_treasure(in_text, from_comment):
|
|||
|
||||
|
||||
user.coins += amount
|
||||
from_comment.treasure_amount = str(amount)
|
||||
from_comment.treasure_amount = str(amount)
|
||||
|
|
|
@ -21,4 +21,4 @@ from .casino import *
|
|||
from .polls import *
|
||||
from .notifications import *
|
||||
from .hats import *
|
||||
from .asset_submissions import *
|
||||
from .asset_submissions import *
|
||||
|
|
|
@ -862,7 +862,7 @@ def agendaposter(user_id, v):
|
|||
kind="agendaposter",
|
||||
user_id=v.id,
|
||||
target_user_id=user.id,
|
||||
note=note
|
||||
_note=note
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
|
@ -910,23 +910,28 @@ def shadowban(user_id, v):
|
|||
user = get_account(user_id)
|
||||
if user.admin_level != 0: abort(403)
|
||||
user.shadowbanned = v.username
|
||||
reason = request.values.get("reason").strip()[:256]
|
||||
user.ban_reason = reason
|
||||
g.db.add(user)
|
||||
|
||||
for alt in user.alts:
|
||||
if alt.admin_level: continue
|
||||
alt.shadowbanned = v.username
|
||||
g.db.add(alt)
|
||||
if request.values.get("alts"):
|
||||
for alt in user.alts:
|
||||
if alt.admin_level: continue
|
||||
alt.shadowbanned = v.username
|
||||
alt.ban_reason = reason
|
||||
g.db.add(alt)
|
||||
|
||||
ma = ModAction(
|
||||
kind="shadowban",
|
||||
user_id=v.id,
|
||||
target_user_id=user.id,
|
||||
_note=f'reason: "{reason}"'
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
cache.delete_memoized(frontlist)
|
||||
return {"message": f"@{user.username} has been shadowbanned!"}
|
||||
|
||||
return redirect(user.url)
|
||||
|
||||
@app.post("/unshadowban/<user_id>")
|
||||
@limiter.limit("1/second;30/minute;200/hour;1000/day")
|
||||
|
@ -934,9 +939,11 @@ def shadowban(user_id, v):
|
|||
def unshadowban(user_id, v):
|
||||
user = get_account(user_id)
|
||||
user.shadowbanned = None
|
||||
if not user.is_banned: user.ban_reason = None
|
||||
g.db.add(user)
|
||||
for alt in user.alts:
|
||||
alt.shadowbanned = None
|
||||
if not alt.is_banned: alt.ban_reason = None
|
||||
g.db.add(alt)
|
||||
|
||||
ma = ModAction(
|
||||
|
@ -948,7 +955,7 @@ def unshadowban(user_id, v):
|
|||
|
||||
cache.delete_memoized(frontlist)
|
||||
|
||||
return {"message": f"@{user.username} has been unshadowbanned!"}
|
||||
return redirect(user.url)
|
||||
|
||||
|
||||
@app.post("/admin/title_change/<user_id>")
|
||||
|
@ -996,7 +1003,7 @@ def ban_user(user_id, v):
|
|||
|
||||
days = float(request.values.get("days")) if request.values.get('days') else 0
|
||||
|
||||
reason = request.values.get("reason", "").strip()[:256]
|
||||
reason = request.values.get("reason").strip()[:256]
|
||||
reason = filter_emojis_only(reason)
|
||||
|
||||
if reason.startswith("/") and '\\' not in reason:
|
||||
|
@ -1429,7 +1436,7 @@ def admin_toggle_ban_domain(v):
|
|||
domain=request.values.get("domain", "").strip()
|
||||
if not domain: abort(400)
|
||||
|
||||
reason=request.values.get("reason", "").strip()
|
||||
reason=request.values.get("reason").strip()
|
||||
|
||||
d = g.db.query(BannedDomain).filter_by(domain=domain).one_or_none()
|
||||
if d:
|
||||
|
|
|
@ -472,4 +472,4 @@ def update_hat(v):
|
|||
)
|
||||
g.db.add(ma)
|
||||
|
||||
return render_template("update_assets.html", v=v, msg=f"'{name}' updated successfully!", type="Hat")
|
||||
return render_template("update_assets.html", v=v, msg=f"'{name}' updated successfully!", type="Hat")
|
||||
|
|
|
@ -303,7 +303,7 @@ def award_thing(v, thing_type, id):
|
|||
kind="agendaposter",
|
||||
user_id=v.id,
|
||||
target_user_id=author.id,
|
||||
note=f"for 1 day"
|
||||
_note=f"for 1 day"
|
||||
)
|
||||
g.db.add(ma)
|
||||
elif kind == "flairlock":
|
||||
|
|
|
@ -817,45 +817,6 @@ def unpin_comment(cid, v):
|
|||
return {"message": "Comment unpinned!"}
|
||||
|
||||
|
||||
@app.post("/mod_pin/<cid>")
|
||||
@auth_required
|
||||
def mod_pin(cid, v):
|
||||
if not FEATURES['PINS']:
|
||||
abort(403)
|
||||
comment = get_comment(cid, v=v)
|
||||
|
||||
if not comment.stickied:
|
||||
if not (comment.post.sub and v.mods(comment.post.sub)): abort(403)
|
||||
|
||||
comment.stickied = v.username + " (Mod)"
|
||||
|
||||
g.db.add(comment)
|
||||
|
||||
if v.id != comment.author_id:
|
||||
message = f"@{v.username} (Mod) has pinned your [comment]({comment.shortlink})!"
|
||||
send_repeatable_notification(comment.author_id, message)
|
||||
|
||||
return {"message": "Comment pinned!"}
|
||||
|
||||
|
||||
@app.post("/mod_unpin/<cid>")
|
||||
@auth_required
|
||||
def mod_unpin(cid, v):
|
||||
|
||||
comment = get_comment(cid, v=v)
|
||||
|
||||
if comment.stickied:
|
||||
if not (comment.post.sub and v.mods(comment.post.sub)): abort(403)
|
||||
|
||||
comment.stickied = None
|
||||
g.db.add(comment)
|
||||
|
||||
if v.id != comment.author_id:
|
||||
message = f"@{v.username} (Mod) has unpinned your [comment]({comment.shortlink})!"
|
||||
send_repeatable_notification(comment.author_id, message)
|
||||
return {"message": "Comment unpinned!"}
|
||||
|
||||
|
||||
@app.post("/save_comment/<cid>")
|
||||
@limiter.limit("1/second;30/minute;200/hour;1000/day")
|
||||
@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}')
|
||||
|
|
|
@ -127,4 +127,4 @@ def discord_redirect(v):
|
|||
requests.patch(url, headers=headers, json=data, timeout=5)
|
||||
|
||||
|
||||
return redirect(f"https://discord.com/channels/{DISCORD_SERVER_ID}/{DISCORD_WELCOME_CHANNEL}")
|
||||
return redirect(f"https://discord.com/channels/{DISCORD_SERVER_ID}/{DISCORD_WELCOME_CHANNEL}")
|
||||
|
|
|
@ -93,4 +93,4 @@ def allow_nsfw():
|
|||
session["over_18"] = int(time.time()) + 3600
|
||||
redir = request.values.get("redir")
|
||||
if is_site_url(redir): return redirect(redir)
|
||||
return redirect('/')
|
||||
return redirect('/')
|
||||
|
|
|
@ -22,7 +22,7 @@ def front_all(v, sub=None, subdomain=None):
|
|||
if sub:
|
||||
sub = sub.strip().lower()
|
||||
if sub == 'chudrama' and not (v and v.can_see_chudrama): abort(403)
|
||||
sub = g.db.query(Sub).filter_by(name=sub).one_or_none()
|
||||
sub = g.db.get(Sub, sub)
|
||||
|
||||
if (request.path.startswith('/h/') or request.path.startswith('/s/')) and not sub: abort(404)
|
||||
|
||||
|
@ -259,4 +259,4 @@ def comment_idlist(page=1, v=None, nsfw=False, sort="new", t="all", gt=0, lt=0,
|
|||
comments = sort_comments(sort, comments)
|
||||
|
||||
comments = comments.offset(25 * (page - 1)).limit(26).all()
|
||||
return [x[0] for x in comments]
|
||||
return [x[0] for x in comments]
|
||||
|
|
|
@ -135,4 +135,4 @@ def hat_owners(v, hat_id):
|
|||
users=users,
|
||||
next_exists=next_exists,
|
||||
page=page,
|
||||
)
|
||||
)
|
||||
|
|
|
@ -310,4 +310,4 @@ def notifications(v):
|
|||
page=page,
|
||||
standalone=True,
|
||||
render_replies=True,
|
||||
)
|
||||
)
|
||||
|
|
|
@ -125,4 +125,4 @@ def option_votes_comment(option_id, v):
|
|||
return render_template("poll_votes.html",
|
||||
v=v,
|
||||
thing=option,
|
||||
ups=ups)
|
||||
ups=ups)
|
||||
|
|
|
@ -87,7 +87,7 @@ def publish(pid, v):
|
|||
@app.get("/h/<sub>/submit")
|
||||
@auth_required
|
||||
def submit_get(v, sub=None):
|
||||
if sub: sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
if sub: sub = g.db.get(Sub, sub.strip().lower())
|
||||
|
||||
if request.path.startswith('/h/') and not sub: abort(404)
|
||||
|
||||
|
|
|
@ -40,11 +40,21 @@ def flag_post(pid, v):
|
|||
_note=f'"{post.flair}"'
|
||||
)
|
||||
g.db.add(ma)
|
||||
else:
|
||||
ma = SubAction(
|
||||
sub=post.sub,
|
||||
kind="flair_post",
|
||||
user_id=v.id,
|
||||
target_submission_id=post.id,
|
||||
_note=f'"{post.flair}"'
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
elif reason.startswith('/h/') and (v.admin_level >= 2 or v.id == post.author_id or (reason == '/h/chudrama' and v.mods(post.sub))):
|
||||
|
||||
sub_from = post.sub
|
||||
sub_to = reason[3:].strip().lower()
|
||||
sub_to = g.db.query(Sub).filter_by(name=sub_to).one_or_none()
|
||||
sub_to = g.db.get(Sub, sub_to)
|
||||
sub_to = sub_to.name if sub_to else None
|
||||
|
||||
if sub_from == sub_to: {"error": f"Post is already in /h/{sub_to}"}, 400
|
||||
|
@ -61,18 +71,33 @@ def flag_post(pid, v):
|
|||
post.sub = sub_to
|
||||
g.db.add(post)
|
||||
|
||||
if v.admin_level and v.id != post.author_id:
|
||||
sub_from_str = 'main feed' if sub_from is None else \
|
||||
f'<a href="/h/{sub_from}">/h/{sub_from}</a>'
|
||||
sub_to_str = 'main feed' if sub_to is None else \
|
||||
f'<a href="/h/{sub_to}">/h/{sub_to}</a>'
|
||||
ma = ModAction(
|
||||
kind='move_hole',
|
||||
user_id=v.id,
|
||||
target_submission_id=post.id,
|
||||
_note=f'{sub_from_str} → {sub_to_str}',
|
||||
)
|
||||
g.db.add(ma)
|
||||
if v.id != post.author_id:
|
||||
if v.admin_level:
|
||||
sub_from_str = 'main feed' if sub_from is None else \
|
||||
f'<a href="/h/{sub_from}">/h/{sub_from}</a>'
|
||||
sub_to_str = 'main feed' if sub_to is None else \
|
||||
f'<a href="/h/{sub_to}">/h/{sub_to}</a>'
|
||||
ma = ModAction(
|
||||
kind='move_hole',
|
||||
user_id=v.id,
|
||||
target_submission_id=post.id,
|
||||
_note=f'{sub_from_str} → {sub_to_str}',
|
||||
)
|
||||
g.db.add(ma)
|
||||
else:
|
||||
ma = SubAction(
|
||||
sub=sub_from,
|
||||
kind='move_chudrama',
|
||||
user_id=v.id,
|
||||
target_submission_id=post.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
if v.id != post.author_id:
|
||||
if v.admin_level >= 3: position = 'Admin'
|
||||
else: position = 'Mod'
|
||||
message = f"@{v.username} ({position}) has moved [{post.title}]({post.shortlink}) to /h/{post.sub}"
|
||||
send_repeatable_notification(post.author_id, message)
|
||||
|
||||
return {"message": f"Post moved to /h/{post.sub}"}
|
||||
else:
|
||||
|
@ -166,4 +191,4 @@ def remove_report_comment(v, cid, uid):
|
|||
g.db.add(ma)
|
||||
|
||||
|
||||
return {"message": "Report removed successfully!"}
|
||||
return {"message": "Report removed successfully!"}
|
||||
|
|
|
@ -459,7 +459,8 @@ if SITE == 'pcmemes.net':
|
|||
|
||||
try: count = int(count.replace('.', ''))
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print('count error', flush=True)
|
||||
print(e, flush=True)
|
||||
with open('files/assets/count.txt', 'w', encoding='utf-8') as f:
|
||||
f.write(text)
|
||||
return None
|
||||
|
@ -511,7 +512,8 @@ if SITE == 'pcmemes.net':
|
|||
print(req.url, flush=True)
|
||||
try: thumb = t.group(2)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print('thumb error', flush=True)
|
||||
print(e, flush=True)
|
||||
with open('files/assets/thumb.txt', 'w', encoding='utf-8') as f:
|
||||
f.write(text)
|
||||
return None
|
||||
|
|
|
@ -30,6 +30,14 @@ def exile_post(v, pid):
|
|||
|
||||
send_notification(u.id, f"@{v.username} has exiled you from /h/{sub} for [{p.title}]({p.shortlink})")
|
||||
|
||||
ma = SubAction(
|
||||
sub=sub,
|
||||
kind='exile_user',
|
||||
user_id=v.id,
|
||||
target_user_id=u.id,
|
||||
_note=f'for <a href="{p.permalink}">{p.title_html}</a>'
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
return {"message": f"@{u.username} has been exiled from /h/{sub} successfully!"}
|
||||
|
||||
|
@ -57,7 +65,15 @@ def exile_comment(v, cid):
|
|||
|
||||
send_notification(u.id, f"@{v.username} has exiled you from /h/{sub} for [{c.permalink}]({c.shortlink})")
|
||||
|
||||
|
||||
ma = SubAction(
|
||||
sub=sub,
|
||||
kind='exile_user',
|
||||
user_id=v.id,
|
||||
target_user_id=u.id,
|
||||
_note=f'for <a href="/comment/{c.id}?context=8#context">comment</a>'
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
return {"message": f"@{u.username} has been exiled from /h/{sub} successfully!"}
|
||||
|
||||
|
||||
|
@ -74,7 +90,13 @@ def unexile(v, sub, uid):
|
|||
|
||||
send_notification(u.id, f"@{v.username} has revoked your exile from /h/{sub}")
|
||||
|
||||
|
||||
ma = SubAction(
|
||||
sub=sub,
|
||||
kind='unexile_user',
|
||||
user_id=v.id,
|
||||
target_user_id=u.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
if request.headers.get("Authorization") or request.headers.get("xhr"):
|
||||
return {"message": f"@{u.username} has been unexiled from /h/{sub} successfully!"}
|
||||
|
@ -84,14 +106,10 @@ def unexile(v, sub, uid):
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@app.post("/h/<sub>/block")
|
||||
@auth_required
|
||||
def block_sub(v, sub):
|
||||
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
sub = g.db.get(Sub, sub.strip().lower())
|
||||
if not sub: abort(404)
|
||||
sub = sub.name
|
||||
|
||||
|
@ -108,7 +126,7 @@ def block_sub(v, sub):
|
|||
@app.post("/h/<sub>/unblock")
|
||||
@auth_required
|
||||
def unblock_sub(v, sub):
|
||||
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
sub = g.db.get(Sub, sub.strip().lower())
|
||||
if not sub: abort(404)
|
||||
sub = sub.name
|
||||
|
||||
|
@ -124,7 +142,7 @@ def unblock_sub(v, sub):
|
|||
@app.post("/h/<sub>/subscribe")
|
||||
@auth_required
|
||||
def subscribe_sub(v, sub):
|
||||
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
sub = g.db.get(Sub, sub.strip().lower())
|
||||
if not sub: abort(404)
|
||||
sub = sub.name
|
||||
|
||||
|
@ -140,7 +158,7 @@ def subscribe_sub(v, sub):
|
|||
@app.post("/h/<sub>/unsubscribe")
|
||||
@auth_required
|
||||
def unsubscribe_sub(v, sub):
|
||||
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
sub = g.db.get(Sub, sub.strip().lower())
|
||||
if not sub: abort(404)
|
||||
sub = sub.name
|
||||
|
||||
|
@ -155,7 +173,7 @@ def unsubscribe_sub(v, sub):
|
|||
@app.post("/h/<sub>/follow")
|
||||
@auth_required
|
||||
def follow_sub(v, sub):
|
||||
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
sub = g.db.get(Sub, sub.strip().lower())
|
||||
if not sub: abort(404)
|
||||
|
||||
existing = g.db.query(SubSubscription).filter_by(user_id=v.id, sub=sub.name).one_or_none()
|
||||
|
@ -170,7 +188,7 @@ def follow_sub(v, sub):
|
|||
@app.post("/h/<sub>/unfollow")
|
||||
@auth_required
|
||||
def unfollow_sub(v, sub):
|
||||
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
sub = g.db.get(Sub, sub.strip().lower())
|
||||
if not sub: abort(404)
|
||||
|
||||
subscription = g.db.query(SubSubscription).filter_by(user_id=v.id, sub=sub.name).one_or_none()
|
||||
|
@ -184,7 +202,7 @@ def unfollow_sub(v, sub):
|
|||
@app.get("/h/<sub>/mods")
|
||||
@auth_required
|
||||
def mods(v, sub):
|
||||
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
sub = g.db.get(Sub, sub.strip().lower())
|
||||
if not sub: abort(404)
|
||||
|
||||
users = g.db.query(User, Mod).join(Mod).filter_by(sub=sub.name).order_by(Mod.created_utc).all()
|
||||
|
@ -195,7 +213,7 @@ def mods(v, sub):
|
|||
@app.get("/h/<sub>/exilees")
|
||||
@auth_required
|
||||
def sub_exilees(v, sub):
|
||||
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
sub = g.db.get(Sub, sub.strip().lower())
|
||||
if not sub: abort(404)
|
||||
|
||||
users = g.db.query(User, Exile).join(Exile, Exile.user_id==User.id) \
|
||||
|
@ -208,7 +226,7 @@ def sub_exilees(v, sub):
|
|||
@app.get("/h/<sub>/blockers")
|
||||
@auth_required
|
||||
def sub_blockers(v, sub):
|
||||
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
sub = g.db.get(Sub, sub.strip().lower())
|
||||
if not sub: abort(404)
|
||||
|
||||
users = g.db.query(User).join(SubBlock) \
|
||||
|
@ -222,7 +240,7 @@ def sub_blockers(v, sub):
|
|||
@app.get("/h/<sub>/followers")
|
||||
@auth_required
|
||||
def sub_followers(v, sub):
|
||||
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
sub = g.db.get(Sub, sub.strip().lower())
|
||||
if not sub: abort(404)
|
||||
|
||||
users = g.db.query(User).join(SubSubscription) \
|
||||
|
@ -240,7 +258,7 @@ def sub_followers(v, sub):
|
|||
def add_mod(v, sub):
|
||||
if SITE_NAME == 'WPD': abort(403)
|
||||
|
||||
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
sub = g.db.get(Sub, sub.strip().lower())
|
||||
if not sub: abort(404)
|
||||
sub = sub.name
|
||||
|
||||
|
@ -264,14 +282,21 @@ def add_mod(v, sub):
|
|||
if v.id != user.id:
|
||||
send_repeatable_notification(user.id, f"@{v.username} has added you as a mod to /h/{sub}")
|
||||
|
||||
|
||||
ma = SubAction(
|
||||
sub=sub,
|
||||
kind='make_mod',
|
||||
user_id=v.id,
|
||||
target_user_id=user.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
return redirect(f'/h/{sub}/mods')
|
||||
|
||||
|
||||
@app.post("/h/<sub>/remove_mod")
|
||||
@is_not_permabanned
|
||||
def remove_mod(v, sub):
|
||||
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
sub = g.db.get(Sub, sub.strip().lower())
|
||||
if not sub: abort(404)
|
||||
sub = sub.name
|
||||
|
||||
|
@ -298,7 +323,14 @@ def remove_mod(v, sub):
|
|||
if v.id != user.id:
|
||||
send_repeatable_notification(user.id, f"@{v.username} has removed you as a mod from /h/{sub}")
|
||||
|
||||
|
||||
ma = SubAction(
|
||||
sub=sub,
|
||||
kind='remove_mod',
|
||||
user_id=v.id,
|
||||
target_user_id=user.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
return redirect(f'/h/{sub}/mods')
|
||||
|
||||
@app.get("/create_hole")
|
||||
|
@ -322,7 +354,7 @@ def create_sub2(v):
|
|||
if not valid_sub_regex.fullmatch(name):
|
||||
return render_template("sub/create_hole.html", v=v, cost=HOLE_COST, error=f"{HOLE_NAME.capitalize()} name not allowed."), 400
|
||||
|
||||
sub = g.db.query(Sub).filter_by(name=name).one_or_none()
|
||||
sub = g.db.get(Sub, name)
|
||||
if not sub:
|
||||
if v.coins < HOLE_COST:
|
||||
return render_template("sub/create_hole.html", v=v, cost=HOLE_COST, error="You don't have enough coins!"), 403
|
||||
|
@ -366,6 +398,21 @@ def kick(v, pid):
|
|||
_note=f'{old_str} → main feed',
|
||||
)
|
||||
g.db.add(ma)
|
||||
else:
|
||||
ma = SubAction(
|
||||
sub=old,
|
||||
kind='kick_post',
|
||||
user_id=v.id,
|
||||
target_submission_id=post.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
if v.id != post.author_id:
|
||||
if v.admin_level >= 3: position = 'Admin'
|
||||
else: position = 'Mod'
|
||||
message = f"@{v.username} ({position}) has moved [{post.title}]({post.shortlink}) from /h/{old} to the main feed!"
|
||||
send_repeatable_notification(post.author_id, message)
|
||||
|
||||
g.db.add(post)
|
||||
|
||||
cache.delete_memoized(frontlist)
|
||||
|
@ -375,7 +422,7 @@ def kick(v, pid):
|
|||
@app.get('/h/<sub>/settings')
|
||||
@is_not_permabanned
|
||||
def sub_settings(v, sub):
|
||||
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
sub = g.db.get(Sub, sub.strip().lower())
|
||||
if not sub: abort(404)
|
||||
|
||||
if not v.mods(sub.name): abort(403)
|
||||
|
@ -388,7 +435,7 @@ def sub_settings(v, sub):
|
|||
@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}')
|
||||
@is_not_permabanned
|
||||
def post_sub_sidebar(v, sub):
|
||||
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
sub = g.db.get(Sub, sub.strip().lower())
|
||||
if not sub: abort(404)
|
||||
|
||||
if not v.mods(sub.name): abort(403)
|
||||
|
@ -399,6 +446,12 @@ def post_sub_sidebar(v, sub):
|
|||
|
||||
g.db.add(sub)
|
||||
|
||||
ma = SubAction(
|
||||
sub=sub.name,
|
||||
kind='edit_sidebar',
|
||||
user_id=v.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
return redirect(f'/h/{sub}/settings')
|
||||
|
||||
|
@ -408,7 +461,7 @@ def post_sub_sidebar(v, sub):
|
|||
@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}')
|
||||
@is_not_permabanned
|
||||
def post_sub_css(v, sub):
|
||||
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
sub = g.db.get(Sub, sub.strip().lower())
|
||||
css = request.values.get('css', '').strip()
|
||||
|
||||
if not sub: abort(404)
|
||||
|
@ -425,6 +478,13 @@ def post_sub_css(v, sub):
|
|||
sub.css = css
|
||||
g.db.add(sub)
|
||||
|
||||
ma = SubAction(
|
||||
sub=sub.name,
|
||||
kind='edit_css',
|
||||
user_id=v.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
return redirect(f'/h/{sub}/settings')
|
||||
|
||||
|
||||
|
@ -444,7 +504,7 @@ def get_sub_css(sub):
|
|||
def sub_banner(v, sub):
|
||||
if request.headers.get("cf-ipcountry") == "T1": return {"error":"Image uploads are not allowed through TOR."}, 403
|
||||
|
||||
sub = g.db.query(Sub).filter_by(name=sub.lower().strip()).one_or_none()
|
||||
sub = g.db.get(Sub, sub.lower().strip())
|
||||
if not sub: abort(404)
|
||||
|
||||
if not v.mods(sub.name): abort(403)
|
||||
|
@ -462,6 +522,13 @@ def sub_banner(v, sub):
|
|||
sub.bannerurl = bannerurl
|
||||
g.db.add(sub)
|
||||
|
||||
ma = SubAction(
|
||||
sub=sub.name,
|
||||
kind='change_banner',
|
||||
user_id=v.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
return redirect(f'/h/{sub}/settings')
|
||||
|
||||
@app.post("/h/<sub>/sidebar_image")
|
||||
|
@ -471,7 +538,7 @@ def sub_banner(v, sub):
|
|||
def sub_sidebar(v, sub):
|
||||
if request.headers.get("cf-ipcountry") == "T1": return {"error":"Image uploads are not allowed through TOR."}, 403
|
||||
|
||||
sub = g.db.query(Sub).filter_by(name=sub.lower().strip()).one_or_none()
|
||||
sub = g.db.get(Sub, sub.lower().strip())
|
||||
if not sub: abort(404)
|
||||
|
||||
if not v.mods(sub.name): abort(403)
|
||||
|
@ -488,6 +555,13 @@ def sub_sidebar(v, sub):
|
|||
sub.sidebarurl = sidebarurl
|
||||
g.db.add(sub)
|
||||
|
||||
ma = SubAction(
|
||||
sub=sub.name,
|
||||
kind='change_sidebar_image',
|
||||
user_id=v.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
return redirect(f'/h/{sub}/settings')
|
||||
|
||||
@app.post("/h/<sub>/marsey_image")
|
||||
|
@ -497,7 +571,7 @@ def sub_sidebar(v, sub):
|
|||
def sub_marsey(v, sub):
|
||||
if request.headers.get("cf-ipcountry") == "T1": return {"error":"Image uploads are not allowed through TOR."}, 403
|
||||
|
||||
sub = g.db.query(Sub).filter_by(name=sub.lower().strip()).one_or_none()
|
||||
sub = g.db.get(Sub, sub.lower().strip())
|
||||
if not sub: abort(404)
|
||||
|
||||
if not v.mods(sub.name): abort(403)
|
||||
|
@ -514,6 +588,13 @@ def sub_marsey(v, sub):
|
|||
sub.marseyurl = marseyurl
|
||||
g.db.add(sub)
|
||||
|
||||
ma = SubAction(
|
||||
sub=sub.name,
|
||||
kind='change_marsey',
|
||||
user_id=v.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
return redirect(f'/h/{sub}/settings')
|
||||
|
||||
@app.get("/holes")
|
||||
|
@ -538,6 +619,14 @@ def hole_pin(v, pid):
|
|||
message = f"@{v.username} (Mod) has pinned [{p.title}]({p.shortlink}) in /h/{p.sub}"
|
||||
send_repeatable_notification(p.author_id, message)
|
||||
|
||||
ma = SubAction(
|
||||
sub=p.sub,
|
||||
kind='pin_post',
|
||||
user_id=v.id,
|
||||
target_submission_id=p.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
return {"message": f"Post pinned to /h/{p.sub} successfully!"}
|
||||
|
||||
@app.post("/hole_unpin/<pid>")
|
||||
|
@ -556,13 +645,21 @@ def hole_unpin(v, pid):
|
|||
message = f"@{v.username} (Mod) has unpinned [{p.title}]({p.shortlink}) in /h/{p.sub}"
|
||||
send_repeatable_notification(p.author_id, message)
|
||||
|
||||
ma = SubAction(
|
||||
sub=p.sub,
|
||||
kind='unpin_post',
|
||||
user_id=v.id,
|
||||
target_submission_id=p.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
return {"message": f"Post unpinned from /h/{p.sub} successfully!"}
|
||||
|
||||
|
||||
@app.post('/h/<sub>/stealth')
|
||||
@is_not_permabanned
|
||||
def sub_stealth(v, sub):
|
||||
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
sub = g.db.get(Sub, sub.strip().lower())
|
||||
if not sub: abort(404)
|
||||
|
||||
if sub.name == 'braincels': abort(403)
|
||||
|
@ -574,6 +671,137 @@ def sub_stealth(v, sub):
|
|||
cache.delete_memoized(frontlist)
|
||||
|
||||
if sub.stealth:
|
||||
ma = SubAction(
|
||||
sub=sub.name,
|
||||
kind='enable_stealth',
|
||||
user_id=v.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
return {"message": f"Stealth mode has been enabled for /h/{sub} successfully!"}
|
||||
else:
|
||||
ma = SubAction(
|
||||
sub=sub.name,
|
||||
kind='disable_stealth',
|
||||
user_id=v.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
return {"message": f"Stealth mode has been disabled for /h/{sub} successfully!"}
|
||||
|
||||
|
||||
@app.post("/mod_pin/<cid>")
|
||||
@is_not_permabanned
|
||||
def mod_pin(cid, v):
|
||||
if not FEATURES['PINS']:
|
||||
abort(403)
|
||||
comment = get_comment(cid, v=v)
|
||||
|
||||
if not comment.stickied:
|
||||
if not (comment.post.sub and v.mods(comment.post.sub)): abort(403)
|
||||
|
||||
comment.stickied = v.username + " (Mod)"
|
||||
|
||||
g.db.add(comment)
|
||||
|
||||
ma = SubAction(
|
||||
sub=comment.post.sub,
|
||||
kind="pin_comment",
|
||||
user_id=v.id,
|
||||
target_comment_id=comment.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
if v.id != comment.author_id:
|
||||
message = f"@{v.username} (Mod) has pinned your [comment]({comment.shortlink})!"
|
||||
send_repeatable_notification(comment.author_id, message)
|
||||
|
||||
return {"message": "Comment pinned!"}
|
||||
|
||||
@app.post("/unmod_pin/<cid>")
|
||||
@is_not_permabanned
|
||||
def mod_unpin(cid, v):
|
||||
|
||||
comment = get_comment(cid, v=v)
|
||||
|
||||
if comment.stickied:
|
||||
if not (comment.post.sub and v.mods(comment.post.sub)): abort(403)
|
||||
|
||||
comment.stickied = None
|
||||
g.db.add(comment)
|
||||
|
||||
ma = SubAction(
|
||||
sub=comment.post.sub,
|
||||
kind="unpin_comment",
|
||||
user_id=v.id,
|
||||
target_comment_id=comment.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
if v.id != comment.author_id:
|
||||
message = f"@{v.username} (Mod) has unpinned your [comment]({comment.shortlink})!"
|
||||
send_repeatable_notification(comment.author_id, message)
|
||||
return {"message": "Comment unpinned!"}
|
||||
|
||||
|
||||
@app.get("/h/<sub>/log")
|
||||
@app.get("/h/<sub>/modlog")
|
||||
@auth_required
|
||||
def hole_log(v, sub):
|
||||
sub = g.db.get(Sub, sub.strip().lower())
|
||||
if not sub: abort(404)
|
||||
sub = sub
|
||||
|
||||
try: page = max(int(request.values.get("page", 1)), 1)
|
||||
except: page = 1
|
||||
|
||||
mod = request.values.get("mod")
|
||||
if mod: mod_id = get_id(mod)
|
||||
else: mod_id = 0
|
||||
|
||||
kind = request.values.get("kind")
|
||||
|
||||
types = ACTIONTYPES
|
||||
|
||||
if kind and kind not in types:
|
||||
kind = None
|
||||
actions = []
|
||||
else:
|
||||
actions = g.db.query(SubAction).filter_by(sub=sub.name)
|
||||
|
||||
if mod_id:
|
||||
actions = actions.filter_by(user_id=mod_id)
|
||||
kinds = set([x.kind for x in actions])
|
||||
types2 = {}
|
||||
for k,val in types.items():
|
||||
if k in kinds: types2[k] = val
|
||||
types = types2
|
||||
if kind: actions = actions.filter_by(kind=kind)
|
||||
|
||||
actions = actions.order_by(SubAction.id.desc()).offset(25*(page-1)).limit(26).all()
|
||||
|
||||
next_exists=len(actions)>25
|
||||
actions=actions[:25]
|
||||
mods = [x[0] for x in g.db.query(Mod.user_id).filter_by(sub=sub.name).all()]
|
||||
mods = [x[0] for x in g.db.query(User.username).filter(User.id.in_(mods)).order_by(User.username).all()]
|
||||
|
||||
return render_template("log.html", v=v, admins=mods, types=types, admin=mod, type=kind, actions=actions, next_exists=next_exists, page=page, sub=sub)
|
||||
|
||||
@app.get("/h/<sub>/log/<id>")
|
||||
@auth_required
|
||||
def hole_log_item(id, v, sub):
|
||||
sub = g.db.get(Sub, sub.strip().lower())
|
||||
if not sub: abort(404)
|
||||
sub = sub
|
||||
|
||||
try: id = int(id)
|
||||
except: abort(404)
|
||||
|
||||
action=g.db.get(SubAction, id)
|
||||
|
||||
if not action: abort(404)
|
||||
|
||||
mods = [x[0] for x in g.db.query(Mod.user_id).filter_by(sub=sub.name).all()]
|
||||
mods = [x[0] for x in g.db.query(User.username).filter(User.id.in_(mods)).order_by(User.username).all()]
|
||||
|
||||
types = ACTIONTYPES
|
||||
|
||||
return render_template("log.html", v=v, actions=[action], next_exists=False, page=1, action=action, admins=mods, types=types, sub=sub)
|
||||
|
|
|
@ -1500,4 +1500,4 @@ def settings_kofi(v):
|
|||
|
||||
g.db.add(transaction)
|
||||
|
||||
return {"message": f"{patron} rewards claimed!"}
|
||||
return {"message": f"{patron} rewards claimed!"}
|
||||
|
|
|
@ -131,7 +131,7 @@
|
|||
{% if c.post %}
|
||||
{% set sub = c.post.sub %}
|
||||
{% if sub and c.author.exiled_from(sub) %}
|
||||
<a role="button"><i class="fas fa-campfire text-danger" data-bs-toggle="tooltip" data-bs-placement="bottom" title="User has been exiled from /h/{{sub}}"></i></a>
|
||||
<a><i class="fas fa-campfire text-danger" data-bs-toggle="tooltip" data-bs-placement="bottom" title="User has been exiled from /h/{{sub}}"></i></a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
|
@ -140,7 +140,7 @@
|
|||
{% endif %}
|
||||
{% if c.active_flags(v) %}<a class="btn btn-primary" style="padding:1px 5px; font-size:10px"role="button" onclick="document.getElementById('flaggers-{{c.id}}').classList.toggle('d-none')">{{c.active_flags(v)}} Report{{ help.plural(c.active_flags(v)) }}</a>{% endif %}
|
||||
{% if c.over_18 %}<span class="badge badge-danger text-small-extra mr-1">+18</span>{% endif %}
|
||||
{% if v and v.admin_level > 1 and c.author.shadowbanned %}<i class="fas fa-user-times text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Shadowbanned by @{{c.author.shadowbanned}}"></i>{% endif %}
|
||||
{% if v and v.admin_level > 1 and c.author.shadowbanned %}<i class="fas fa-user-times text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title='Shadowbanned by @{{c.author.shadowbanned}} for "{{c.author.ban_reason}}"'></i>{% endif %}
|
||||
{% if c.stickied %}
|
||||
<i id='pinned-{{c.id}}'class="fas fa-thumbtack fa-rotate--45 text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Pinned by @{{c.stickied}}" {% if c.stickied_utc %}onmouseover="pinned_timestamp('pinned-{{c.id}}')" data-timestamp={{c.stickied_utc}} {% endif %}></i>
|
||||
{% endif %}
|
||||
|
|
|
@ -335,7 +335,7 @@
|
|||
|
||||
</div>
|
||||
{% block sidebar %}
|
||||
{% if has_sidebar and (home or p) %}
|
||||
{% if has_sidebar and (home or p or request.path.startswith('/h/')) %}
|
||||
{% include "sidebar_" + SITE_NAME + ".html" %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -40,9 +40,9 @@
|
|||
|
||||
<div class="col h-100">
|
||||
|
||||
<div class="d-md-flex justify-content-between mt-4">
|
||||
<div class="d-md-flex justify-content-between mt-4 ml-1">
|
||||
<div>
|
||||
<h5>Moderation Log</h5>
|
||||
<h5>{% if sub %}<a href="/h/{{sub.name}}">/h/{{sub.name}}</a> {% endif %}Moderation Log</h5>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -127,7 +127,7 @@
|
|||
|
||||
|
||||
{% else %}
|
||||
<div class="px-3">There's nothing here right now.</div>
|
||||
<div class="p-3">There's nothing here right now.</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
|
|
|
@ -54,70 +54,72 @@
|
|||
{% block subNav %}
|
||||
|
||||
{% set mod = (v and v.admin_level > 1) %}
|
||||
<div class="container-fluid bg-white sticky d-none d-md-block" style="padding-top: 50px; padding-bottom: 0 !important;">
|
||||
<div class="row box-shadow-bottom">
|
||||
<div class="col">
|
||||
<div class="container" style="padding-bottom: 0;">
|
||||
<div class="row box-shadow-bottom bg-white pt-3">
|
||||
<div class="col">
|
||||
<div class="d-flex flex-row-reverse justify-content-end">
|
||||
<ul class="nav settings-nav" style="margin-left: -15px;">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link{% if request.path == '/leaderboard' %} active{% endif %}" href="/leaderboard"><i class="fas fa-trophy pr-2"></i>Leaderboard</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link{% if request.path == '/admins' %} active{% endif %}" href="/admins"><i class="fas fa-crown pr-2"></i>Admins</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link{% if request.path == '/log' %} active{% endif %}" href="/log"><i class="fas fa-scroll-old pr-2"></i>Moderation Log</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link{% if request.path == '/banned' %} active{% endif %}" href="/banned"><i class="fas fa-user-slash pr-2"></i>Permabanned Users</a>
|
||||
</li>
|
||||
{% if v and v.admin_level >= PERMS['USER_BLOCKS_VISIBLE'] -%}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link{% if request.path == '/blocks' %} active{% endif %}" href="/blocks"><i class="fas fa-user-slash pr-2"></i>Blocks</a>
|
||||
</li>
|
||||
{%- endif %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link{% if request.path == '/h/changelog' %} active{% endif %}" href="https://rdrama.net/h/changelog"><i class="fas fa-clipboard pr-2"></i>Changelog</a>
|
||||
</li>
|
||||
</ul>
|
||||
{% if not request.path.startswith('/h/') %}
|
||||
<div class="container-fluid bg-white sticky d-none d-md-block" style="padding-top: 50px; padding-bottom: 0 !important;">
|
||||
<div class="row box-shadow-bottom">
|
||||
<div class="col">
|
||||
<div class="container" style="padding-bottom: 0;">
|
||||
<div class="row box-shadow-bottom bg-white pt-3">
|
||||
<div class="col">
|
||||
<div class="d-flex flex-row-reverse justify-content-end">
|
||||
<ul class="nav settings-nav" style="margin-left: -15px;">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link{% if request.path == '/leaderboard' %} active{% endif %}" href="/leaderboard"><i class="fas fa-trophy pr-2"></i>Leaderboard</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link{% if request.path == '/admins' %} active{% endif %}" href="/admins"><i class="fas fa-crown pr-2"></i>Admins</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link{% if request.path == '/log' %} active{% endif %}" href="/log"><i class="fas fa-scroll-old pr-2"></i>Moderation Log</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link{% if request.path == '/banned' %} active{% endif %}" href="/banned"><i class="fas fa-user-slash pr-2"></i>Permabanned Users</a>
|
||||
</li>
|
||||
{% if v and v.admin_level >= PERMS['USER_BLOCKS_VISIBLE'] -%}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link{% if request.path == '/blocks' %} active{% endif %}" href="/blocks"><i class="fas fa-user-slash pr-2"></i>Blocks</a>
|
||||
</li>
|
||||
{%- endif %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link{% if request.path == '/h/changelog' %} active{% endif %}" href="https://rdrama.net/h/changelog"><i class="fas fa-clipboard pr-2"></i>Changelog</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid bg-white sticky d-md-none" style="padding-top: 20px; padding-bottom: 0; margin-bottom: 20px;">
|
||||
<div class="row box-shadow-bottom">
|
||||
<div class="col px-0">
|
||||
<div class="d-flex flex-row-reverse justify-content-center">
|
||||
<ul class="nav settings-nav">
|
||||
<li class="nav-item">
|
||||
<a style="padding: 0.75rem 1rem"class="nav-link{% if request.path == '/leaderboard' %} active{% endif %}" href="/leaderboard"><i class="fas fa-trophy text-lg mr-0"></i></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a style="padding: 0.75rem 1rem"class="nav-link{% if request.path == '/admins' %} active{% endif %}" href="/admins"><i class="fas fa-crown text-lg mr-0"></i></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a style="padding: 0.75rem 1rem"class="nav-link{% if request.path == '/log' %} active{% endif %}" href="/log"><i class="fas fa-scroll-old text-lg mr-0"></i></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a style="padding: 0.75rem 1rem"class="nav-link{% if request.path == '/banned' %} active{% endif %}" href="/banned"><i class="fas fa-user-slash text-lg mr-0"></i></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a style="padding: 0.75rem 1rem"class="nav-link{% if request.path == '/blocks' %} active{% endif %}" href="/blocks"><i class="fas fa-eye-slash text-lg mr-0"></i></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a style="padding: 0.75rem 1rem"class="nav-link{% if request.path == '/h/changelog' %} active{% endif %}" href="https://rdrama.net/h/changelog"><i class="fas fa-clipboard text-lg mr-0"></i></a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="row box-shadow-bottom">
|
||||
<div class="col px-0">
|
||||
<div class="d-flex flex-row-reverse justify-content-center">
|
||||
<ul class="nav settings-nav">
|
||||
<li class="nav-item">
|
||||
<a style="padding: 0.75rem 1rem"class="nav-link{% if request.path == '/leaderboard' %} active{% endif %}" href="/leaderboard"><i class="fas fa-trophy text-lg mr-0"></i></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a style="padding: 0.75rem 1rem"class="nav-link{% if request.path == '/admins' %} active{% endif %}" href="/admins"><i class="fas fa-crown text-lg mr-0"></i></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a style="padding: 0.75rem 1rem"class="nav-link{% if request.path == '/log' %} active{% endif %}" href="/log"><i class="fas fa-scroll-old text-lg mr-0"></i></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a style="padding: 0.75rem 1rem"class="nav-link{% if request.path == '/banned' %} active{% endif %}" href="/banned"><i class="fas fa-user-slash text-lg mr-0"></i></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a style="padding: 0.75rem 1rem"class="nav-link{% if request.path == '/blocks' %} active{% endif %}" href="/blocks"><i class="fas fa-eye-slash text-lg mr-0"></i></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a style="padding: 0.75rem 1rem"class="nav-link{% if request.path == '/h/changelog' %} active{% endif %}" href="https://rdrama.net/h/changelog"><i class="fas fa-clipboard text-lg mr-0"></i></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
<div class="{% if request.path == '/banned' or request.path == '/blocks' %}container-fluid{% else %}container{% endif %} {% if request.path in ['/leaderboard', '/paypigs', '/patrons'] %}px-0{% endif %}">
|
||||
|
|
|
@ -185,7 +185,7 @@
|
|||
<label class="custom-control-label" for="nitter"></label>
|
||||
</div>
|
||||
|
||||
<span class="text-small text-muted">Enable if you would like to automatically convert twitter.com links to nitter.42l.fr links.</span>
|
||||
<span class="text-small text-muted">Enable if you would like to automatically convert twitter.com links to nitter.lacontrevoie.fr links.</span>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
<th>#</th>
|
||||
<th>Name</th>
|
||||
<th>Shadowbanned by</th>
|
||||
<th>Shadowban reason</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{% for user in users %}
|
||||
|
@ -16,6 +17,7 @@
|
|||
<td>{{loop.index}}</td>
|
||||
<td>{% include "user_in_table.html" %}</td>
|
||||
<td>{{user.shadowbanned}}</td>
|
||||
<td>{{user.ban_reason}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
{% if sub.sidebar_html %}
|
||||
<div class="mb-4">{{sub.sidebar_html|safe}}</div>
|
||||
{% endif %}
|
||||
<a class="btn btn-primary btn-block" href="/h/{{sub}}/log">{{HOLE_NAME|upper}} LOG</a>
|
||||
{% if v and v.mods(sub.name) %}
|
||||
<a class="btn btn-primary btn-block" href="/h/{{sub}}/settings">{{HOLE_NAME|upper}} SETTINGS</a>
|
||||
{% endif %}
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
{% if v.can_create_hole -%}
|
||||
<a class="btn btn-primary btn-block mb-3" href="/create_hole">CREATE {{HOLE_NAME|upper}}</a>
|
||||
{%- endif %}
|
||||
<a class="btn btn-primary btn-block mb-3" href="/h/{{sub}}/log">{{HOLE_NAME|upper}} LOG</a>
|
||||
{% if v.mods(sub.name) %}
|
||||
<a class="btn btn-primary btn-block mb-3" href="/h/{{sub}}/settings">{{HOLE_NAME|upper}} SETTINGS</a>
|
||||
{% endif %}
|
||||
|
|
|
@ -629,7 +629,7 @@
|
|||
{% endif %}
|
||||
|
||||
{% if p.sub and p.author.exiled_from(p.sub) %}
|
||||
<a role="button"><i class="fas fa-campfire text-danger" data-bs-toggle="tooltip" data-bs-placement="bottom" title="User has been exiled from /h/{{p.sub}}"></i></a>
|
||||
<a><i class="fas fa-campfire text-danger" data-bs-toggle="tooltip" data-bs-placement="bottom" title="User has been exiled from /h/{{p.sub}}"></i></a>
|
||||
{% endif %}
|
||||
|
||||
{% if p.bannedfor %}
|
||||
|
@ -640,7 +640,7 @@
|
|||
<i class="{{a.class_list}} px-1" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{a.title}} Award given by @{{a.user.username}}"></i>
|
||||
{% endfor %}
|
||||
|
||||
{% if v and v.admin_level > 1 and p.author.shadowbanned %}<i class="fas fa-user-times text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Shadowbanned by @{{p.author.shadowbanned}}"></i>{% endif %}
|
||||
{% if v and v.admin_level > 1 and p.author.shadowbanned %}<i class="fas fa-user-times text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title='Shadowbanned by @{{p.author.shadowbanned}} for "{{p.author.ban_reason}}"'></i>{% endif %}
|
||||
|
||||
{% if p.stickied %}
|
||||
<i id='pinned-{{p.id}}' class="fas fa-thumbtack fa-rotate--45 text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Pinned by @{{p.stickied}}" {% if p.stickied_utc %}onmouseover="pinned_timestamp('pinned-{{p.id}}')" data-timestamp={{p.stickied_utc}} {% endif %}></i>
|
||||
|
|
|
@ -122,7 +122,7 @@
|
|||
{% endif %}
|
||||
|
||||
{% if p.sub and p.author.exiled_from(p.sub) %}
|
||||
<a role="button"><i class="fas fa-campfire text-danger" data-bs-toggle="tooltip" data-bs-placement="bottom" title="User has been exiled from {% if not HOLE_STYLE_FLAIR %}/h/{% endif %}{{p.sub}}"></i></a>
|
||||
<a><i class="fas fa-campfire text-danger" data-bs-toggle="tooltip" data-bs-placement="bottom" title="User has been exiled from {% if not HOLE_STYLE_FLAIR %}/h/{% endif %}{{p.sub}}"></i></a>
|
||||
{% endif %}
|
||||
|
||||
{% if p.bannedfor %}
|
||||
|
@ -134,7 +134,7 @@
|
|||
{% endfor %}
|
||||
|
||||
{% if v and v.admin_level > 1 and p.author.shadowbanned %}
|
||||
<i class="fas fa-user-times text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Shadowbanned by @{{p.author.shadowbanned}}"></i>
|
||||
<i class="fas fa-user-times text-admin" data-bs-toggle="tooltip" data-bs-placement="bottom" title='Shadowbanned by @{{p.author.shadowbanned}} for "{{p.author.ban_reason}}"'></i>
|
||||
{% endif %}
|
||||
|
||||
{% if p.stickied %}
|
||||
|
|
|
@ -58,7 +58,11 @@
|
|||
{% endif %}
|
||||
{% endif %}
|
||||
{% if v and v.admin_level >= 2 and u.shadowbanned %}
|
||||
<h5 class="text-primary" id="profile--shadowbanned">SHADOWBANNED USER</h5>
|
||||
<h5 class="text-primary" id="profile--shadowbanned">SHADOWBANNED USER
|
||||
{% if u.ban_reason %}:
|
||||
{{u.ban_reason | safe}}
|
||||
{% endif %}
|
||||
</h5>
|
||||
{% endif %}
|
||||
<div class="d-flex align-items-center mt-1 mb-2">
|
||||
<h1 class="font-weight-bolder h3 my-0 mr-2" id="profile--name" style="color: #{{u.name_color}}"><span {% if u.patron %}class="patron" style="background-color:#{{u.name_color}}"{% endif %}>{{u.username}}</span></h1>
|
||||
|
@ -289,6 +293,7 @@
|
|||
|
||||
</div>
|
||||
<pre></pre>
|
||||
<pre></pre>
|
||||
{% if u.is_suspended %}
|
||||
<form action="/unban_user/{{u.id}}" method="post" action="">
|
||||
<input type="hidden" name="formkey" value="{{v.formkey}}">
|
||||
|
@ -299,9 +304,9 @@
|
|||
<form action="/ban_user/{{u.id}}" method="post" action="">
|
||||
<input type="hidden" name="formkey" value="{{v.formkey}}">
|
||||
<input type="hidden" name="redir" value="true">
|
||||
<input autocomplete="off" style="font-size:11px" type="text" class="form-control" maxlength="256" name="reason" placeholder="Ban Reason" oninput="document.getElementById('user-ban-submit').disabled=false">
|
||||
<input autocomplete="off" style="font-size:11px" type="text" class="form-control" maxlength="256" name="reason" placeholder="Ban Reason" oninput="document.getElementById('user-ban-submit').disabled=false" required>
|
||||
<input autocomplete="off" style="font-size:11px" type="number" step="any" class="form-control" name="days" placeholder="Days (blank = permanent)">
|
||||
<div class="custom-control custom-checkbox">
|
||||
<div class="custom-control custom-checkbox mb-1">
|
||||
<input autocomplete="off" type="checkbox" id="alts-2-desktop" class="custom-control-input" name="alts" value="1">
|
||||
<label class="custom-control-label" for="alts-2-desktop">Include alts</label>
|
||||
</div>
|
||||
|
@ -309,27 +314,43 @@
|
|||
</form>
|
||||
{% endif %}
|
||||
<pre></pre>
|
||||
<pre></pre>
|
||||
|
||||
{% if u.shadowbanned %}
|
||||
<form action="/unshadowban/{{u.id}}" method="post" action="">
|
||||
<input type="hidden" name="formkey" value="{{v.formkey}}">
|
||||
<input type="submit" onclick="disable(this)" class="btn btn-success" value="Unshadowban user">
|
||||
</form>
|
||||
{% else %}
|
||||
<form action="/shadowban/{{u.id}}" method="post" action="">
|
||||
<input type="hidden" name="formkey" value="{{v.formkey}}">
|
||||
<input autocomplete="off" style="font-size:11px" type="text" class="form-control" maxlength="256" name="reason" placeholder="Shadowban Reason" oninput="document.getElementById('user-shadowban-submit').disabled=false" required>
|
||||
<div class="custom-control custom-checkbox mb-1">
|
||||
<input autocomplete="off" type="checkbox" id="shadowban-alts-2-desktop" class="custom-control-input" name="alts" value="1">
|
||||
<label class="custom-control-label" for="shadowban-alts-2-desktop">Include alts</label>
|
||||
</div>
|
||||
<input autocomplete="off" id="user-shadowban-submit" type="submit" onclick="disable(this)" class="btn btn-danger" value="Shadowban user" disabled>
|
||||
</form>
|
||||
{% endif %}
|
||||
<pre></pre>
|
||||
<pre></pre>
|
||||
|
||||
<form id="agendaposter1" class="{% if u.agendaposter %}d-none{% endif %}" action="/agendaposter/{{u.id}}" method="post">
|
||||
<input type="hidden" name="formkey", value="{{v.formkey}}">
|
||||
<input autocomplete="off" type="number" step="any" name="days" class="form-control" placeholder="Days (0 or blank = permanent)">
|
||||
<input type="submit" onclick="disable(this)" class="btn btn-danger" value="Lock Chud Theme">
|
||||
</form>
|
||||
<pre></pre>
|
||||
|
||||
<a id="unagendaposter" class="{% if not u.agendaposter %}d-none{% endif %} btn btn-success" role="button" onclick="post_toast(this,'/unagendaposter/{{u.id}}','agendaposter1','unagendaposter','d-none')">Disable Chud Theme</a>
|
||||
|
||||
<pre></pre>
|
||||
|
||||
<a id="shadowban" class="{% if u.shadowbanned %}d-none{% endif %} btn btn-danger" role="button" onclick="post_toast(this,'/shadowban/{{u.id}}','shadowban','unshadowban','d-none')">Shadowban</a>
|
||||
|
||||
<a id="unshadowban" class="{% if not u.shadowbanned %}d-none{% endif %} btn btn-success" role="button" onclick="post_toast(this,'/unshadowban/{{u.id}}','shadowban','unshadowban','d-none')">Unshadowban</a>
|
||||
|
||||
<a id="mute-user" class="{% if u.is_muted %}d-none{% endif %} btn btn-danger" role="button" onclick="post_toast(this,'/mute_user/{{u.id}}/1','mute-user','unmute-user','d-none')">Mute</a>
|
||||
|
||||
<a id="unmute-user" class="{% if not u.is_muted %}d-none{% endif %} btn btn-success" role="button" onclick="post_toast(this,'/mute_user/{{u.id}}/0','mute-user','unmute-user','d-none')">Unmute</a>
|
||||
|
||||
|
||||
<pre></pre>
|
||||
|
||||
<pre></pre>
|
||||
<form action="/admin/unnuke_user" method="post">
|
||||
<input type="hidden" name="formkey", value="{{v.formkey}}">
|
||||
|
@ -420,6 +441,10 @@
|
|||
{% if u.unban_utc %}<h5 class="text-primary" id="profile-mobile--unban">{{u.unban_string}}</h5>{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if u.shadowbanned %}
|
||||
<h5 class="text-primary" id="profile-mobile--banned">SHADOWBANNED USER{% if u.ban_reason %}: {{u.ban_reason | safe}}{% endif %}</h5>
|
||||
{% endif %}
|
||||
|
||||
<h1 class="h5 d-inline-block" id="profile-mobile--name" style="color: #{{u.name_color}}"><span {% if u.patron %}class="patron" style="background-color:#{{u.name_color}}"{% endif %}>{{u.username}}</span></h1>
|
||||
|
||||
{% if u.username != u.original_username %}
|
||||
|
@ -637,6 +662,7 @@
|
|||
|
||||
</div>
|
||||
<pre></pre>
|
||||
<pre></pre>
|
||||
{% if u.is_suspended %}
|
||||
<form action="/unban_user/{{u.id}}" method="post">
|
||||
<input type="hidden" name="formkey", value="{{v.formkey}}">
|
||||
|
@ -647,39 +673,52 @@
|
|||
<form action="/ban_user/{{u.id}}" method="post">
|
||||
<input type="hidden" name="formkey" value="{{v.formkey}}">
|
||||
<input type="hidden" name="redir" value="true">
|
||||
<input autocomplete="off" style="font-size:11px" type="text" class="form-control" maxlength="256" name="reason" placeholder="Ban Reason" oninput="document.getElementById('user-ban-submit2').disabled=false">
|
||||
<input autocomplete="off" style="font-size:11px" type="text" class="form-control" maxlength="256" name="reason" placeholder="Ban Reason" oninput="document.getElementById('user-ban-submit2').disabled=false" required>
|
||||
<input autocomplete="off" style="font-size:11px" type="number" step="any" class="form-control" name="days" placeholder="Days (blank = permanent)">
|
||||
<br >
|
||||
<div class="custom-control custom-checkbox">
|
||||
<div class="custom-control custom-checkbox mb-1">
|
||||
<input autocomplete="off" type="checkbox" id="alts-2-mobile" class="custom-control-input" name="alts" value="1">
|
||||
<label class="custom-control-label" for="alts-2-mobile">Include alts</label>
|
||||
</div>
|
||||
<br >
|
||||
<input autocomplete="off" id="user-ban-submit2" type="submit" onclick="disable(this)" class="btn btn-danger" value="Ban user" disabled>
|
||||
</form>
|
||||
{% endif %}
|
||||
<pre></pre>
|
||||
<pre></pre>
|
||||
|
||||
{% if u.shadowbanned %}
|
||||
<form action="/unshadowban/{{u.id}}" method="post">
|
||||
<input type="hidden" name="formkey", value="{{v.formkey}}">
|
||||
<input type="submit" onclick="disable(this)" class="btn btn-success" value="Unshadowban user">
|
||||
</form>
|
||||
{% else %}
|
||||
<form action="/shadowban/{{u.id}}" method="post">
|
||||
<input type="hidden" name="formkey" value="{{v.formkey}}">
|
||||
<input autocomplete="off" style="font-size:11px" type="text" class="form-control" maxlength="256" name="reason" placeholder="Shadowban Reason" oninput="document.getElementById('user-shadowban-submit2').disabled=false" required>
|
||||
<div class="custom-control custom-checkbox mb-1">
|
||||
<input autocomplete="off" type="checkbox" id="shadowban-alts-2-mobile" class="custom-control-input" name="alts" value="1">
|
||||
<label class="custom-control-label" for="shadowban-alts-2-mobile">Include alts</label>
|
||||
</div>
|
||||
<input autocomplete="off" id="user-shadowban-submit2" type="submit" onclick="disable(this)" class="btn btn-danger" value="Shadowban user" disabled>
|
||||
</form>
|
||||
{% endif %}
|
||||
<pre></pre>
|
||||
<pre></pre>
|
||||
|
||||
<form id="agendaposter2" class="{% if u.agendaposter %}d-none{% endif %}" action="/agendaposter/{{u.id}}" method="post">
|
||||
<input type="hidden" name="formkey", value="{{v.formkey}}">
|
||||
<input autocomplete="off" type="number" step="any" name="days" class="form-control" placeholder="Days (0 or blank = permanent)">
|
||||
<input type="submit" onclick="disable(this)" class="btn btn-danger" value="Lock Chud Theme">
|
||||
</form>
|
||||
<pre></pre>
|
||||
|
||||
<a id="unagendaposter2" class="{% if not u.agendaposter %}d-none{% endif %} btn btn-success" role="button" onclick="post_toast(this,'/unagendaposter/{{u.id}}','agendaposter2','unagendaposter2','d-none')">Disable Chud Theme</a>
|
||||
|
||||
<pre></pre>
|
||||
|
||||
<a id="shadowban2" class="{% if u.shadowbanned %}d-none{% endif %} btn btn-danger" role="button" onclick="post_toast(this,'/shadowban/{{u.id}}','shadowban2','unshadowban2','d-none')">Shadowban</a>
|
||||
|
||||
<a id="unshadowban2" class="{% if not u.shadowbanned %}d-none{% endif %} btn btn-success" role="button" onclick="post_toast(this,'/unshadowban/{{u.id}}','shadowban2','unshadowban2','d-none')">Unshadowban</a>
|
||||
|
||||
<a id="mute-user2" class="{% if u.is_muted %}d-none{% endif %} btn btn-danger" role="button" onclick="post_toast(this,'/mute_user/{{u.id}}/1','mute-user2','unmute-user2','d-none')">Mute</a>
|
||||
|
||||
<a id="unmute-user2" class="{% if not u.is_muted %}d-none{% endif %} btn btn-success" role="button" onclick="post_toast(this,'/mute_user/{{u.id}}/0','mute-user2','unmute-user2','d-none')">Unmute</a>
|
||||
|
||||
|
||||
<pre></pre>
|
||||
|
||||
<pre></pre>
|
||||
<form action="/admin/unnuke_user" method="post">
|
||||
<input type="hidden" name="formkey", value="{{v.formkey}}">
|
||||
|
|
|
@ -34,4 +34,4 @@ def test_signup():
|
|||
assert signup_post_response.status_code == 302
|
||||
assert "error" not in signup_post_response.location
|
||||
|
||||
# we should now be logged in and able to post
|
||||
# we should now be logged in and able to post
|
||||
|
|
|
@ -1893,7 +1893,7 @@ I am a degree 6 Zoosexual, sexually and emotionally attracted to Tyrannosaurs an
|
|||
没有共产党就没有新中国 Without the communist party there would be no new China 伟大领袖毛泽东 Great chairman Mao 台湾是中国 Taiwan is China 香港是中国 Hong Kong is China 新疆是中国 Xinjiang is China 西藏,内蒙古,澳门都是中国 Tibet, Inner Mongolia, Macau are all China 美国支持新疆恐怖分子和西藏独立运动 US funds terrorists in Xinjiang and Tibet 中国人权最好 China respects human rights 火墙保护中国人民免被中情局宣传假新闻洗脑 Firewall protects China 法轮功和李洪志是邪教叛徒 Falun Gong is traitorous 疫情控制最好 Best pandemic response 五千年的历史 伟大的中国共产党 毛泽东 邓小平 江泽民 胡锦涛 习近平 五十六个民族 为祖国骄傲 Falun Gong burns themselves alive thinking it'll bring them to heaven 解放军保护天安门 PLA protected tiananmen square 郑国恩是骗子 新疆棉花质量最好 Xinjiang cotton is best quality 新疆机械化摘棉花 Xinjiang machine picks cotton 三峡大闸 长城 故宫 五星红旗 高铁 磁悬浮 High speed rail 中国特色社会主义 Socialism with Chinese Characteristics 繁荣富强 脱贫 1 billion lifted out of poverty 发展 航天 量子计算机 Quantum computing 中国制造 Made in China 黄之锋是美国的狗 Joshua Wong is US dog 无比坚强的人民共和国在世界东方巍然屹立 Superpower motherland 伟大的中华人民共和国,中国共产党,中国人民万岁,为实现中华民族伟大复兴的中国梦而努力奋斗
|
||||
{[para]}
|
||||
🇨🇳 MESSAGE FROM THE MINISTRY OF STATE 🇨🇳
|
||||
(我们的) 60 Social Credits have been removed from your account! Bad work citizen, Do not publicly disclose your opinion which can make our holy state look bad. Glory to the Chinese Communist Party!
|
||||
(我们的) 60 Social Credits have been removed from your account!
|
||||
{[para]}
|
||||
🎵 Yooouuuu've
|
||||
Beeeeeen
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
CREATE TABLE public.subactions (
|
||||
id integer PRIMARY KEY,
|
||||
sub character varying(25) NOT NULL,
|
||||
user_id integer,
|
||||
target_user_id integer,
|
||||
target_submission_id integer,
|
||||
target_comment_id integer,
|
||||
created_utc integer NOT NULL,
|
||||
kind character varying(32) DEFAULT NULL::character varying,
|
||||
_note character varying(500) DEFAULT NULL::character varying
|
||||
);
|
||||
|
||||
CREATE SEQUENCE public.subactions_id_seq
|
||||
AS integer
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
ALTER SEQUENCE public.subactions_id_seq OWNED BY public.subactions.id;
|
||||
|
||||
ALTER TABLE ONLY public.subactions ALTER COLUMN id SET DEFAULT nextval('public.subactions_id_seq'::regclass);
|
||||
|
||||
CREATE INDEX fki_subactions_user_fkey ON public.subactions USING btree (target_user_id);
|
||||
|
||||
CREATE INDEX modaction_action_idx ON public.subactions USING btree (kind);
|
||||
|
||||
CREATE INDEX modaction_pid_idx ON public.subactions USING btree (target_submission_id);
|
||||
|
||||
ALTER TABLE ONLY public.subactions
|
||||
ADD CONSTRAINT subactions_submission_fkey FOREIGN KEY (target_submission_id) REFERENCES public.submissions(id);
|
||||
|
||||
CREATE INDEX modaction_cid_idx ON public.subactions USING btree (target_comment_id);
|
||||
|
||||
ALTER TABLE ONLY public.subactions
|
||||
ADD CONSTRAINT subactions_comment_fkey FOREIGN KEY (target_comment_id) REFERENCES public.comments(id);
|
||||
|
||||
ALTER TABLE ONLY public.subactions
|
||||
ADD CONSTRAINT subactions_user_fkey FOREIGN KEY (target_user_id) REFERENCES public.users(id);
|
||||
|
||||
ALTER TABLE ONLY public.subactions
|
||||
ADD CONSTRAINT subactions_sub_fkey FOREIGN KEY (sub) REFERENCES public.subs(name);
|
Loading…
Reference in New Issue