sub -> hole

pull/215/head
Aevann 2023-10-07 20:55:50 +03:00
parent 9be96bf827
commit 62d1940a8f
56 changed files with 739 additions and 720 deletions

View File

@ -4203,7 +4203,7 @@ small, .small {
min-height: 30px; min-height: 30px;
} }
.sub-flair { .hole-flair {
padding: 3px 5px 2px 5px; padding: 3px 5px 2px 5px;
border-radius: 5px; border-radius: 5px;
color: white; color: white;
@ -4211,7 +4211,7 @@ small, .small {
margin-right: 3px; margin-right: 3px;
font-weight: bold; font-weight: bold;
} }
.sub-flair:hover { .hole-flair:hover {
color: var(--white); color: var(--white);
text-decoration: none; text-decoration: none;
} }
@ -6919,7 +6919,7 @@ div.markdown {
} }
} }
.sub-banner-update-section .sub-settings-subsection { .hole-banner-update-section .hole-settings-subsection {
margin-bottom: 1em; margin-bottom: 1em;
} }
@ -7568,12 +7568,12 @@ p { /* DO NOT REMOVE */
overflow: hidden !important; overflow: hidden !important;
} }
#sub-name { #hole-name {
font-size: max(14px, 1.2vw); font-size: max(14px, 1.2vw);
} }
@media (min-width: 768px) { @media (min-width: 768px) {
#sub-name { #hole-name {
font-size: 1.5vw; font-size: 1.5vw;
} }
} }

View File

@ -1,4 +1,4 @@
const save_value = ['post-title', 'post-text', 'post-url', 'sub'] const save_value = ['post-title', 'post-text', 'post-url', 'hole']
for (const id of save_value) { for (const id of save_value) {
const value = localStorage.getItem(id) const value = localStorage.getItem(id)
if (value) if (value)
@ -106,15 +106,15 @@ function autoSuggestTitle() {
function ghost_toggle(t) { function ghost_toggle(t) {
const followers = document.getElementById("post-notify") const followers = document.getElementById("post-notify")
const sub = document.getElementById("sub") const hole = document.getElementById("hole")
if (t.checked == true) { if (t.checked == true) {
followers.checked = false; followers.checked = false;
followers.disabled = true; followers.disabled = true;
sub.value = ''; hole.value = '';
sub.disabled = true; hole.disabled = true;
} else { } else {
followers.disabled = false; followers.disabled = false;
sub.disabled = false; hole.disabled = false;
} }
} }

View File

@ -18,7 +18,7 @@ from .domains import *
from .subscriptions import * from .subscriptions import *
from .mod_logs import * from .mod_logs import *
from .award import * from .award import *
from .sub_relationship import * from .hole_relationship import *
from .saves import * from .saves import *
from .views import * from .views import *
from .notifications import * from .notifications import *
@ -28,7 +28,7 @@ from .casino_game import *
from .hats import * from .hats import *
from .emoji import * from .emoji import *
from .transactions import * from .transactions import *
from .sub_logs import * from .hole_logs import *
from .media import * from .media import *
from .push_subscriptions import * from .push_subscriptions import *
from .group import * from .group import *

View File

@ -126,13 +126,13 @@ def add_options(self, body, v):
if v: if v:
if kind == 'post': if kind == 'post':
sub = self.sub hole = self.hole
elif self.parent_post: elif self.parent_post:
sub = self.post.sub hole = self.post.hole
else: else:
sub = None hole = None
if sub in {'furry','vampire','racist','femboy','edgy'} and not v.house.lower().startswith(sub): if hole in {'furry','vampire','racist','femboy','edgy'} and not v.house.lower().startswith(hole):
disabled = True disabled = True
option_body += ' disabled ' option_body += ' disabled '
@ -407,7 +407,7 @@ class Comment(Base):
body = add_options(self, body, v) body = add_options(self, body, v)
if body: if body:
if not (self.parent_post and self.post.sub == 'chudrama'): if not (self.parent_post and self.post.hole == 'chudrama'):
body = censor_slurs_profanities(body, v) body = censor_slurs_profanities(body, v)
body = normalize_urls_runtime(body, v) body = normalize_urls_runtime(body, v)
@ -423,7 +423,7 @@ class Comment(Base):
if not body: return "" if not body: return ""
if not (self.parent_post and self.post.sub == 'chudrama'): if not (self.parent_post and self.post.hole == 'chudrama'):
body = censor_slurs_profanities(body, v, True) body = censor_slurs_profanities(body, v, True)
return body return body

View File

@ -9,7 +9,7 @@ from files.classes import Base
class Exile(Base): class Exile(Base):
__tablename__ = "exiles" __tablename__ = "exiles"
user_id = Column(Integer, ForeignKey("users.id"), primary_key=True) user_id = Column(Integer, ForeignKey("users.id"), primary_key=True)
sub = Column(String, ForeignKey("subs.name"), primary_key=True) hole = Column(String, ForeignKey("holes.name"), primary_key=True)
exiler_id = Column(Integer, ForeignKey("users.id")) exiler_id = Column(Integer, ForeignKey("users.id"))
created_utc = Column(Integer) created_utc = Column(Integer)
@ -20,4 +20,4 @@ class Exile(Base):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
def __repr__(self): def __repr__(self):
return f"<{self.__class__.__name__}(user_id={self.user_id}, sub={self.sub})>" return f"<{self.__class__.__name__}(user_id={self.user_id}, hole={self.hole})>"

View File

@ -11,23 +11,23 @@ from files.classes import Base
from files.helpers.lazy import lazy from files.helpers.lazy import lazy
from files.helpers.config.const import * from files.helpers.config.const import *
from .sub_relationship import * from .hole_relationship import *
class Sub(Base): class Hole(Base):
__tablename__ = "subs" __tablename__ = "holes"
name = Column(VARCHAR(SUB_NAME_COLUMN_LENGTH), primary_key=True) name = Column(VARCHAR(HOLE_NAME_COLUMN_LENGTH), primary_key=True)
sidebar = Column(VARCHAR(SUB_SIDEBAR_COLUMN_LENGTH)) sidebar = Column(VARCHAR(HOLE_SIDEBAR_COLUMN_LENGTH))
sidebar_html = Column(VARCHAR(SUB_SIDEBAR_HTML_COLUMN_LENGTH)) sidebar_html = Column(VARCHAR(HOLE_SIDEBAR_HTML_COLUMN_LENGTH))
sidebarurl = Column(VARCHAR(SUB_SIDEBAR_URL_COLUMN_LENGTH)) sidebarurl = Column(VARCHAR(HOLE_SIDEBAR_URL_COLUMN_LENGTH))
bannerurls = Column(MutableList.as_mutable(ARRAY(VARCHAR(SUB_BANNER_URL_COLUMN_LENGTH))), default=MutableList([]), nullable=False) bannerurls = Column(MutableList.as_mutable(ARRAY(VARCHAR(HOLE_BANNER_URL_COLUMN_LENGTH))), default=MutableList([]), nullable=False)
marseyurl = Column(VARCHAR(SUB_MARSEY_URL_LENGTH)) marseyurl = Column(VARCHAR(HOLE_MARSEY_URL_LENGTH))
css = Column(VARCHAR(SUB_CSS_COLUMN_LENGTH)) css = Column(VARCHAR(HOLE_CSS_COLUMN_LENGTH))
stealth = Column(Boolean) stealth = Column(Boolean)
created_utc = Column(Integer) created_utc = Column(Integer)
blocks = relationship("SubBlock", primaryjoin="SubBlock.sub==Sub.name") blocks = relationship("HoleBlock", primaryjoin="HoleBlock.hole==Hole.name")
followers = relationship("SubSubscription", primaryjoin="SubSubscription.sub==Sub.name") followers = relationship("HoleFollow", primaryjoin="HoleFollow.hole==Hole.name")
joins = relationship("SubJoin", lazy="dynamic", primaryjoin="SubJoin.sub==Sub.name") joins = relationship("StealthHoleUnblock", lazy="dynamic", primaryjoin="StealthHoleUnblock.hole==Hole.name")
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())

View File

@ -10,10 +10,10 @@ from files.helpers.lazy import lazy
from files.helpers.slurs_and_profanities import censor_slurs_profanities from files.helpers.slurs_and_profanities import censor_slurs_profanities
from files.helpers.sorting_and_time import make_age_string from files.helpers.sorting_and_time import make_age_string
class SubAction(Base): class HoleAction(Base):
__tablename__ = "subactions" __tablename__ = "hole_actions"
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
sub = Column(String, ForeignKey("subs.name")) hole = Column(String, ForeignKey("holes.name"))
user_id = Column(Integer, ForeignKey("users.id")) user_id = Column(Integer, ForeignKey("users.id"))
kind = Column(String) kind = Column(String)
target_user_id = Column(Integer, ForeignKey("users.id")) target_user_id = Column(Integer, ForeignKey("users.id"))
@ -22,8 +22,8 @@ class SubAction(Base):
_note = Column(String) _note = Column(String)
created_utc = Column(Integer) created_utc = Column(Integer)
user = relationship("User", primaryjoin="User.id==SubAction.user_id") user = relationship("User", primaryjoin="User.id==HoleAction.user_id")
target_user = relationship("User", primaryjoin="User.id==SubAction.target_user_id") target_user = relationship("User", primaryjoin="User.id==HoleAction.target_user_id")
target_post = relationship("Post") target_post = relationship("Post")
target_comment = relationship("Comment") target_comment = relationship("Comment")
@ -42,7 +42,7 @@ class SubAction(Base):
@property @property
@lazy @lazy
def string(self): def string(self):
output = SUBACTION_TYPES[self.kind]["str"].format(self=self) output = HOLEACTION_TYPES[self.kind]["str"].format(self=self)
if self._note: output += f" <i>({self._note})</i>" if self._note: output += f" <i>({self._note})</i>"
return output return output
@ -59,16 +59,16 @@ class SubAction(Base):
@property @property
@lazy @lazy
def icon(self): def icon(self):
return SUBACTION_TYPES[self.kind]['icon'] return HOLEACTION_TYPES[self.kind]['icon']
@property @property
@lazy @lazy
def color(self): def color(self):
return SUBACTION_TYPES[self.kind]['color'] return HOLEACTION_TYPES[self.kind]['color']
@property @property
@lazy @lazy
def permalink(self): def permalink(self):
return f"{SITE_FULL}/h/{self.sub}/log/{self.id}" return f"{SITE_FULL}/h/{self.hole}/log/{self.id}"
from files.helpers.config.subaction_types import SUBACTION_TYPES from files.helpers.config.holeaction_types import HOLEACTION_TYPES

View File

@ -6,7 +6,7 @@ from sqlalchemy.sql.sqltypes import *
from files.classes import Base from files.classes import Base
class SubRelationship(Base): class HoleRelationship(Base):
__tablename__ = NotImplemented __tablename__ = NotImplemented
__abstract__ = True __abstract__ = True
@ -15,8 +15,8 @@ class SubRelationship(Base):
return Column(Integer, ForeignKey("users.id"), primary_key=True) return Column(Integer, ForeignKey("users.id"), primary_key=True)
@declared_attr @declared_attr
def sub(self): def hole(self):
return Column(String(20), ForeignKey("subs.name"), primary_key=True) return Column(String(20), ForeignKey("holes.name"), primary_key=True)
@declared_attr @declared_attr
def created_utc(self): def created_utc(self):
@ -27,13 +27,13 @@ class SubRelationship(Base):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
def __repr__(self): def __repr__(self):
return f"<{self.__class__.__name__}(user_id={self.user_id}, sub={self.sub})>" return f"<{self.__class__.__name__}(user_id={self.user_id}, hole={self.hole})>"
class SubJoin(SubRelationship): class StealthHoleUnblock(HoleRelationship):
__tablename__ = "sub_joins" __tablename__ = "stealth_hole_unblocks"
class SubBlock(SubRelationship): class HoleBlock(HoleRelationship):
__tablename__ = "sub_blocks" __tablename__ = "hole_blocks"
class SubSubscription(SubRelationship): class HoleFollow(HoleRelationship):
__tablename__ = "sub_subscriptions" __tablename__ = "hole_follows"

View File

@ -9,7 +9,7 @@ from files.helpers.lazy import *
class Mod(Base): class Mod(Base):
__tablename__ = "mods" __tablename__ = "mods"
user_id = Column(Integer, ForeignKey("users.id"), primary_key=True) user_id = Column(Integer, ForeignKey("users.id"), primary_key=True)
sub = Column(String, ForeignKey("subs.name"), primary_key=True) hole = Column(String, ForeignKey("holes.name"), primary_key=True)
created_utc = Column(Integer) created_utc = Column(Integer)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -17,4 +17,4 @@ class Mod(Base):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
def __repr__(self): def __repr__(self):
return f"<{self.__class__.__name__}(user_id={self.user_id}, sub={self.sub})>" return f"<{self.__class__.__name__}(user_id={self.user_id}, hole={self.hole})>"

View File

@ -17,7 +17,7 @@ from files.helpers.sorting_and_time import make_age_string
from .comment import normalize_urls_runtime, add_options, get_award_classes from .comment import normalize_urls_runtime, add_options, get_award_classes
from .polls import * from .polls import *
from .sub import * from .hole import *
from .subscriptions import * from .subscriptions import *
from .saves import SaveRelationship from .saves import SaveRelationship
@ -40,7 +40,7 @@ class Post(Base):
stickied = Column(String) stickied = Column(String)
stickied_utc = Column(Integer) stickied_utc = Column(Integer)
hole_pinned = Column(String) hole_pinned = Column(String)
sub = Column(String, ForeignKey("subs.name")) hole = Column(String, ForeignKey("holes.name"))
is_pinned = Column(Boolean, default=False) is_pinned = Column(Boolean, default=False)
private = Column(Boolean, default=False) private = Column(Boolean, default=False)
comment_count = Column(Integer, default=0) comment_count = Column(Integer, default=0)
@ -74,7 +74,7 @@ class Post(Base):
awards = relationship("AwardRelationship", order_by="AwardRelationship.awarded_utc.desc()", back_populates="post") awards = relationship("AwardRelationship", order_by="AwardRelationship.awarded_utc.desc()", back_populates="post")
reports = relationship("Report", order_by="Report.created_utc") reports = relationship("Report", order_by="Report.created_utc")
comments = relationship("Comment", primaryjoin="Comment.parent_post==Post.id", back_populates="post") comments = relationship("Comment", primaryjoin="Comment.parent_post==Post.id", back_populates="post")
subr = relationship("Sub", primaryjoin="foreign(Post.sub)==remote(Sub.name)") hole_obj = relationship("Hole", primaryjoin="foreign(Post.hole)==remote(Hole.name)")
options = relationship("PostOption", order_by="PostOption.id") options = relationship("PostOption", order_by="PostOption.id")
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -126,9 +126,9 @@ class Post(Base):
@lazy @lazy
def shortlink(self): def shortlink(self):
link = f"/post/{self.id}" link = f"/post/{self.id}"
if self.sub: link = f"/h/{self.sub}{link}" if self.hole: link = f"/h/{self.hole}{link}"
if self.sub and self.sub in {'chudrama', 'countryclub', 'highrollerclub'}: if self.hole and self.hole in {'chudrama', 'countryclub', 'highrollerclub'}:
output = '-' output = '-'
else: else:
title = self.plaintitle(None).lower() title = self.plaintitle(None).lower()
@ -228,7 +228,7 @@ class Post(Base):
'is_bot': self.is_bot, 'is_bot': self.is_bot,
'thumb_url': self.thumb_url, 'thumb_url': self.thumb_url,
'domain': self.domain, 'domain': self.domain,
'sub': self.sub, 'hole': self.hole,
'url': self.realurl(None), 'url': self.realurl(None),
'body': self.body, 'body': self.body,
'body_html': self.body_html, 'body_html': self.body_html,
@ -307,7 +307,7 @@ class Post(Base):
body = add_options(self, body, v) body = add_options(self, body, v)
if self.sub != 'chudrama': if self.hole != 'chudrama':
body = censor_slurs_profanities(body, v) body = censor_slurs_profanities(body, v)
body = normalize_urls_runtime(body, v) body = normalize_urls_runtime(body, v)
@ -322,7 +322,7 @@ class Post(Base):
body = self.body body = self.body
if not body: return "" if not body: return ""
if self.sub != 'chudrama': if self.hole != 'chudrama':
body = censor_slurs_profanities(body, v, True) body = censor_slurs_profanities(body, v, True)
body = normalize_urls_runtime(body, v) body = normalize_urls_runtime(body, v)
@ -333,7 +333,7 @@ class Post(Base):
def realtitle(self, v): def realtitle(self, v):
title = self.title_html title = self.title_html
if self.sub != 'chudrama': if self.hole != 'chudrama':
title = censor_slurs_profanities(title, v) title = censor_slurs_profanities(title, v)
return title return title
@ -342,7 +342,7 @@ class Post(Base):
def plaintitle(self, v): def plaintitle(self, v):
title = self.title title = self.title
if self.sub != 'chudrama': if self.hole != 'chudrama':
title = censor_slurs_profanities(title, v, True) title = censor_slurs_profanities(title, v, True)
return title return title

View File

@ -13,7 +13,7 @@ from flask import g, session, request
from files.classes import Base from files.classes import Base
from files.classes.casino_game import CasinoGame from files.classes.casino_game import CasinoGame
from files.classes.group import GroupMembership from files.classes.group import GroupMembership
from files.classes.sub import Sub from files.classes.hole import Hole
from files.helpers.config.const import * from files.helpers.config.const import *
from files.helpers.config.modaction_types import * from files.helpers.config.modaction_types import *
from files.helpers.config.awards import AWARDS_ENABLED, HOUSE_AWARDS from files.helpers.config.awards import AWARDS_ENABLED, HOUSE_AWARDS
@ -33,8 +33,8 @@ 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 *
from .sub_relationship import * from .hole_relationship import *
from .sub_logs import * from .hole_logs import *
from .subscriptions import * from .subscriptions import *
from .userblock import * from .userblock import *
from .usermute import * from .usermute import *
@ -171,7 +171,7 @@ class User(Base):
designed_hats = relationship("HatDef", primaryjoin="User.id==HatDef.author_id", back_populates="author") designed_hats = relationship("HatDef", primaryjoin="User.id==HatDef.author_id", back_populates="author")
owned_hats = relationship("Hat", back_populates="owners") owned_hats = relationship("Hat", back_populates="owners")
hats_equipped = relationship("Hat", lazy="raise", viewonly=True) hats_equipped = relationship("Hat", lazy="raise", viewonly=True)
sub_mods = relationship("Mod", primaryjoin="User.id == Mod.user_id", lazy="raise") hole_mods = relationship("Mod", primaryjoin="User.id == Mod.user_id", lazy="raise")
def __init__(self, **kwargs): def __init__(self, **kwargs):
@ -414,13 +414,13 @@ class User(Base):
return True return True
@lazy @lazy
def mods(self, sub): def mods(self, hole):
if self.is_permabanned or self.shadowbanned: return False if self.is_permabanned or self.shadowbanned: return False
if self.admin_level >= PERMS['MODS_EVERY_HOLE']: return True if self.admin_level >= PERMS['MODS_EVERY_HOLE']: return True
try: try:
return any(map(lambda x: x.sub == sub, self.sub_mods)) return any(map(lambda x: x.hole == hole, self.hole_mods))
except: except:
return bool(g.db.query(Mod.user_id).filter_by(user_id=self.id, sub=sub).one_or_none()) return bool(g.db.query(Mod.user_id).filter_by(user_id=self.id, hole=hole).one_or_none())
@lazy @lazy
def mods_group(self, group): def mods_group(self, group):
@ -430,8 +430,8 @@ class User(Base):
return bool(g.db.query(GroupMembership.user_id).filter_by(user_id=self.id, group_name=group.name, is_mod=True).one_or_none()) return bool(g.db.query(GroupMembership.user_id).filter_by(user_id=self.id, group_name=group.name, is_mod=True).one_or_none())
@lazy @lazy
def exiler_username(self, sub): def exiler_username(self, hole):
exile = g.db.query(Exile).options(load_only(Exile.exiler_id)).filter_by(user_id=self.id, sub=sub).one_or_none() exile = g.db.query(Exile).options(load_only(Exile.exiler_id)).filter_by(user_id=self.id, hole=hole).one_or_none()
if exile: if exile:
return exile.exiler.username return exile.exiler.username
else: else:
@ -439,35 +439,35 @@ class User(Base):
@property @property
@lazy @lazy
def sub_blocks(self): def hole_blocks(self):
stealth = set([x[0] for x in g.db.query(Sub.name).filter_by(stealth=True)]) stealth = set([x[0] for x in g.db.query(Hole.name).filter_by(stealth=True)])
stealth = stealth - set([x[0] for x in g.db.query(SubJoin.sub).filter_by(user_id=self.id)]) stealth = stealth - set([x[0] for x in g.db.query(StealthHoleUnblock.hole).filter_by(user_id=self.id)])
if self.chud == 1: stealth = stealth - {'chudrama'} if self.chud == 1: stealth = stealth - {'chudrama'}
return list(stealth) + [x[0] for x in g.db.query(SubBlock.sub).filter_by(user_id=self.id)] return list(stealth) + [x[0] for x in g.db.query(HoleBlock.hole).filter_by(user_id=self.id)]
@lazy @lazy
def blocks(self, sub): def blocks(self, hole):
return g.db.query(SubBlock).filter_by(user_id=self.id, sub=sub).one_or_none() return g.db.query(HoleBlock).filter_by(user_id=self.id, hole=hole).one_or_none()
@lazy @lazy
def subscribes(self, sub): def subscribes(self, hole):
return g.db.query(SubJoin).filter_by(user_id=self.id, sub=sub).one_or_none() return g.db.query(StealthHoleUnblock).filter_by(user_id=self.id, hole=hole).one_or_none()
@property @property
@lazy @lazy
def all_follows(self): def all_follows(self):
return [x[0] for x in g.db.query(SubSubscription.sub).filter_by(user_id=self.id)] return [x[0] for x in g.db.query(HoleFollow.hole).filter_by(user_id=self.id)]
@lazy @lazy
def follows(self, sub): def follows(self, hole):
return g.db.query(SubSubscription).filter_by(user_id=self.id, sub=sub).one_or_none() return g.db.query(HoleFollow).filter_by(user_id=self.id, hole=hole).one_or_none()
@lazy @lazy
def mod_date(self, sub): def mod_date(self, hole):
if self.admin_level >= PERMS['MODS_EVERY_HOLE']: return 1 if self.admin_level >= PERMS['MODS_EVERY_HOLE']: return 1
mod_ts = g.db.query(Mod.created_utc).filter_by(user_id=self.id, sub=sub).one_or_none() mod_ts = g.db.query(Mod.created_utc).filter_by(user_id=self.id, hole=hole).one_or_none()
if mod_ts is None: if mod_ts is None:
return None return None
return mod_ts[0] return mod_ts[0]
@ -737,8 +737,8 @@ class User(Base):
@property @property
@lazy @lazy
def followed_subs(self): def followed_holes(self):
return [x[0] for x in g.db.query(SubSubscription.sub).filter_by(user_id=self.id)] return [x[0] for x in g.db.query(HoleFollow.hole).filter_by(user_id=self.id)]
@property @property
@lazy @lazy
@ -796,7 +796,7 @@ class User(Base):
return g.db.query(Post).filter( return g.db.query(Post).filter(
Post.created_utc > self.last_viewed_post_notifs, Post.created_utc > self.last_viewed_post_notifs,
or_( or_(
Post.sub.in_(self.followed_subs), Post.hole.in_(self.followed_holes),
and_( and_(
Post.author_id.in_(self.followed_users), Post.author_id.in_(self.followed_users),
Post.notify == True, Post.notify == True,
@ -808,7 +808,7 @@ class User(Base):
Post.private == False, Post.private == False,
Post.author_id != self.id, Post.author_id != self.id,
Post.author_id.notin_(self.userblocks), Post.author_id.notin_(self.userblocks),
or_(Post.sub == None, Post.sub.notin_(self.sub_blocks)), or_(Post.hole == None, Post.hole.notin_(self.hole_blocks)),
).count() ).count()
@property @property
@ -830,11 +830,11 @@ class User(Base):
return q.count() return q.count()
if self.moderated_subs: if self.moderated_holes:
return g.db.query(SubAction).filter( return g.db.query(HoleAction).filter(
SubAction.created_utc > self.last_viewed_log_notifs, HoleAction.created_utc > self.last_viewed_log_notifs,
SubAction.user_id != self.id, HoleAction.user_id != self.id,
SubAction.sub.in_(self.moderated_subs), HoleAction.hole.in_(self.moderated_holes),
).count() ).count()
return 0 return 0
@ -896,8 +896,8 @@ class User(Base):
@property @property
@lazy @lazy
def moderated_subs(self): def moderated_holes(self):
return [x[0] for x in g.db.query(Mod.sub).filter_by(user_id=self.id).order_by(Mod.sub)] return [x[0] for x in g.db.query(Mod.hole).filter_by(user_id=self.id).order_by(Mod.hole)]
@property @property
@lazy @lazy

View File

@ -50,7 +50,7 @@ def snappy_report(post, reason):
send_repeatable_notification(post.author_id, message) send_repeatable_notification(post.author_id, message)
def execute_snappy(post, v): def execute_snappy(post, v):
if post.sub and g.db.query(Exile.user_id).filter_by(user_id=SNAPPY_ID, sub=post.sub).one_or_none(): if post.hole and g.db.query(Exile.user_id).filter_by(user_id=SNAPPY_ID, hole=post.hole).one_or_none():
return return
ghost = post.ghost ghost = post.ghost
@ -271,7 +271,7 @@ def execute_zozbot(c, level, post, v):
posting_to_post = isinstance(post, Post) posting_to_post = isinstance(post, Post)
if posting_to_post and post.sub and g.db.query(Exile.user_id).filter_by(user_id=ZOZBOT_ID, sub=post.sub).one_or_none(): if posting_to_post and post.hole and g.db.query(Exile.user_id).filter_by(user_id=ZOZBOT_ID, hole=post.hole).one_or_none():
return return
c2 = Comment(author_id=ZOZBOT_ID, c2 = Comment(author_id=ZOZBOT_ID,
@ -344,7 +344,7 @@ def execute_longpostbot(c, level, body, body_html, post, v):
posting_to_post = isinstance(post, Post) posting_to_post = isinstance(post, Post)
if posting_to_post and post.sub and g.db.query(Exile.user_id).filter_by(user_id=LONGPOSTBOT_ID, sub=post.sub).one_or_none(): if posting_to_post and post.hole and g.db.query(Exile.user_id).filter_by(user_id=LONGPOSTBOT_ID, hole=post.hole).one_or_none():
return return
body = random.choice(LONGPOSTBOT_REPLIES) body = random.choice(LONGPOSTBOT_REPLIES)

View File

@ -103,7 +103,7 @@ def notif_comment2(p):
if existing: return existing[0], text if existing: return existing[0], text
else: else:
if p.sub: text += f" in <a href='/h/{p.sub}'>/h/{p.sub}" if p.hole: text += f" in <a href='/h/{p.hole}'>/h/{p.hole}"
text_html = sanitize(text, blackjack="notification", post_mention_notif=True) text_html = sanitize(text, blackjack="notification", post_mention_notif=True)
return create_comment(text_html), text return create_comment(text_html), text

View File

@ -1,7 +1,7 @@
from .config.const import * from .config.const import *
from files.classes.post import Post from files.classes.post import Post
from files.classes.comment import Comment from files.classes.comment import Comment
from files.classes.sub import Sub from files.classes.hole import Hole
from flask import request from flask import request
def can_see(user, other): def can_see(user, other):
@ -9,7 +9,7 @@ def can_see(user, other):
if not can_see(user, other.author): return False if not can_see(user, other.author): return False
if user and user.id == other.author_id: return True if user and user.id == other.author_id: return True
if isinstance(other, Post): if isinstance(other, Post):
if other.sub and not can_see(user, other.subr): if other.hole and not can_see(user, other.hole_obj):
return False return False
if request.headers.get("Cf-Ipcountry") == 'NZ': if request.headers.get("Cf-Ipcountry") == 'NZ':
if 'christchurch' in other.title.lower(): if 'christchurch' in other.title.lower():
@ -30,7 +30,7 @@ def can_see(user, other):
return user.admin_level >= PERMS['VIEW_MODMAIL'] return user.admin_level >= PERMS['VIEW_MODMAIL']
if other.sentto != user.id: if other.sentto != user.id:
return user.admin_level >= PERMS['BLACKJACK_NOTIFICATIONS'] return user.admin_level >= PERMS['BLACKJACK_NOTIFICATIONS']
elif isinstance(other, Sub): elif isinstance(other, Hole):
if other.name == 'chudrama': return bool(user) and user.can_see_chudrama if other.name == 'chudrama': return bool(user) and user.can_see_chudrama
if other.name == 'countryclub': return bool(user) and user.can_see_countryclub if other.name == 'countryclub': return bool(user) and user.can_see_countryclub
if other.name == 'highrollerclub': return bool(user) and user.can_see_highrollerclub if other.name == 'highrollerclub': return bool(user) and user.can_see_highrollerclub

View File

@ -292,13 +292,13 @@ POST_SORTS = COMMENT_SORTS | {
### COLUMN INFO ### COLUMN INFO
################################################################################ ################################################################################
SUB_NAME_COLUMN_LENGTH = 25 HOLE_NAME_COLUMN_LENGTH = 25
SUB_SIDEBAR_COLUMN_LENGTH = 10000 HOLE_SIDEBAR_COLUMN_LENGTH = 10000
SUB_SIDEBAR_HTML_COLUMN_LENGTH = 20000 HOLE_SIDEBAR_HTML_COLUMN_LENGTH = 20000
SUB_SIDEBAR_URL_COLUMN_LENGTH = 60 HOLE_SIDEBAR_URL_COLUMN_LENGTH = 60
SUB_BANNER_URL_COLUMN_LENGTH = 60 HOLE_BANNER_URL_COLUMN_LENGTH = 60
SUB_CSS_COLUMN_LENGTH = 6000 HOLE_CSS_COLUMN_LENGTH = 6000
SUB_MARSEY_URL_LENGTH = 60 HOLE_MARSEY_URL_LENGTH = 60
################################################################################ ################################################################################
### SITE SPECIFIC CONSTANTS ### SITE SPECIFIC CONSTANTS
@ -487,7 +487,7 @@ COMMENT_MAX_DEPTH = 200
TRANSFER_MESSAGE_LENGTH_LIMIT = 200 # do not make larger than 10000 characters (comment limit) without altering the table TRANSFER_MESSAGE_LENGTH_LIMIT = 200 # do not make larger than 10000 characters (comment limit) without altering the table
MIN_REPOST_CHECK_URL_LENGTH = 9 # also change the constant in checkRepost() of submit.js MIN_REPOST_CHECK_URL_LENGTH = 9 # also change the constant in checkRepost() of submit.js
CHAT_LENGTH_LIMIT = 1000 CHAT_LENGTH_LIMIT = 1000
SUB_BANNER_LIMIT = 10 HOLE_BANNER_LIMIT = 10
BIO_FRIENDS_ENEMIES_LENGTH_LIMIT = 5000 # do not make larger than 5000 characters without altering the table BIO_FRIENDS_ENEMIES_LENGTH_LIMIT = 5000 # do not make larger than 5000 characters without altering the table
BIO_FRIENDS_ENEMIES_HTML_LENGTH_LIMIT = 20000 # do not make larger than 20000 characters without altering the table BIO_FRIENDS_ENEMIES_HTML_LENGTH_LIMIT = 20000 # do not make larger than 20000 characters without altering the table
@ -706,7 +706,7 @@ elif SITE == 'watchpeopledie.tv':
PERMS['MODS_EVERY_HOLE'] = 3 PERMS['MODS_EVERY_HOLE'] = 3
PERMS['IS_PERMA_PROGSTACKED'] = 4 PERMS['IS_PERMA_PROGSTACKED'] = 4
SUB_BANNER_LIMIT = 69420 HOLE_BANNER_LIMIT = 69420
ERROR_TITLES.update({ ERROR_TITLES.update({
400: "Bad Request", 400: "Bad Request",
@ -800,7 +800,7 @@ else: # localhost or testing environment implied
FEATURES['PRONOUNS'] = True FEATURES['PRONOUNS'] = True
FEATURES['HOUSES'] = True FEATURES['HOUSES'] = True
FEATURES['USERS_PERMANENT_WORD_FILTERS'] = True FEATURES['USERS_PERMANENT_WORD_FILTERS'] = True
SUB_BANNER_LIMIT = 69420 HOLE_BANNER_LIMIT = 69420
HOUSES = ("None","Furry","Femboy","Vampire","Racist","Edgy") if FEATURES['HOUSES'] else ("None") HOUSES = ("None","Furry","Femboy","Vampire","Racist","Edgy") if FEATURES['HOUSES'] else ("None")

View File

@ -1,4 +1,4 @@
SUBACTION_TYPES = { HOLEACTION_TYPES = {
'exile_user': { 'exile_user': {
"str": 'exiled user {self.target_link}', "str": 'exiled user {self.target_link}',
"icon": 'fa-user-slash', "icon": 'fa-user-slash',
@ -116,4 +116,4 @@ SUBACTION_TYPES = {
}, },
} }
SUBACTION_TYPES = dict(sorted(SUBACTION_TYPES.items())) HOLEACTION_TYPES = dict(sorted(HOLEACTION_TYPES.items()))

View File

@ -1,6 +1,6 @@
from os import path from os import path
from files.classes import Emoji, Sub from files.classes import Emoji, Hole
from files.helpers.config.const import * from files.helpers.config.const import *
SNAPPY_KONGS = [] SNAPPY_KONGS = []
@ -32,7 +32,7 @@ def const_initialize():
SNAPPY_KONGS = db.query(Emoji.name).filter(Emoji.kind=="Donkey Kong", Emoji.submitter_id==None, Emoji.nsfw == False).all() SNAPPY_KONGS = db.query(Emoji.name).filter(Emoji.kind=="Donkey Kong", Emoji.submitter_id==None, Emoji.nsfw == False).all()
SNAPPY_KONGS = [f':#{x[0]}:' for x in SNAPPY_KONGS] SNAPPY_KONGS = [f':#{x[0]}:' for x in SNAPPY_KONGS]
STEALTH_HOLES = [x[0] for x in db.query(Sub.name).filter_by(stealth=True)] STEALTH_HOLES = [x[0] for x in db.query(Hole.name).filter_by(stealth=True)]
OVER_18_EMOJIS = [x[0] for x in db.query(Emoji.name).filter_by(nsfw=True)] OVER_18_EMOJIS = [x[0] for x in db.query(Emoji.name).filter_by(nsfw=True)]

View File

@ -70,7 +70,7 @@ def cron_fn(every_5m, every_1d, every_fri_12, every_fri_23, every_sat_00, every_
_leaderboard_task() _leaderboard_task()
g.db.commit() g.db.commit()
_sub_inactive_purge_task() _hole_inactive_purge_task()
g.db.commit() g.db.commit()
stats.generate_charts_task(SITE) stats.generate_charts_task(SITE)
@ -170,7 +170,7 @@ def _create_post(title, body, pin_hours):
embed=None, embed=None,
title=title, title=title,
title_html=title_html, title_html=title_html,
sub='countryclub', hole='countryclub',
ghost=False, ghost=False,
chudded=False, chudded=False,
rainbowed=False, rainbowed=False,
@ -248,29 +248,29 @@ def _grant_two_year_badges():
from users where created_utc < {two_years_ago} and id not in (select user_id from badges where badge_id=237);""") from users where created_utc < {two_years_ago} and id not in (select user_id from badges where badge_id=237);""")
g.db.execute(_badge_query) g.db.execute(_badge_query)
def _sub_inactive_purge_task(): def _hole_inactive_purge_task():
if not HOLE_INACTIVITY_DELETION: if not HOLE_INACTIVITY_DELETION:
return False return False
one_week_ago = time.time() - 604800 one_week_ago = time.time() - 604800
active_holes = [x[0] for x in g.db.query(Post.sub).distinct() \ active_holes = [x[0] for x in g.db.query(Post.hole).distinct() \
.filter(Post.sub != None, Post.created_utc > one_week_ago, .filter(Post.hole != None, Post.created_utc > one_week_ago,
Post.private == False, Post.is_banned == False, Post.private == False, Post.is_banned == False,
Post.deleted_utc == 0)] Post.deleted_utc == 0)]
active_holes.extend(['changelog','countryclub','museumofrdrama','highrollerclub']) # holes immune from deletion active_holes.extend(['changelog','countryclub','museumofrdrama','highrollerclub']) # holes immune from deletion
dead_holes = g.db.query(Sub).filter(Sub.name.notin_(active_holes)).all() dead_holes = g.db.query(Hole).filter(Hole.name.notin_(active_holes)).all()
names = [x.name for x in dead_holes] names = [x.name for x in dead_holes]
admins = [x[0] for x in g.db.query(User.id).filter(User.admin_level >= PERMS['NOTIFICATIONS_HOLE_INACTIVITY_DELETION'])] admins = [x[0] for x in g.db.query(User.id).filter(User.admin_level >= PERMS['NOTIFICATIONS_HOLE_INACTIVITY_DELETION'])]
mods = g.db.query(Mod).filter(Mod.sub.in_(names)).all() mods = g.db.query(Mod).filter(Mod.hole.in_(names)).all()
for x in mods: for x in mods:
if x.user_id in admins: continue if x.user_id in admins: continue
send_repeatable_notification(x.user_id, f":marseyrave: /h/{x.sub} has been deleted for inactivity after one week without new posts. All posts in it have been moved to the main feed :marseyrave:") send_repeatable_notification(x.user_id, f":marseyrave: /h/{x.hole} has been deleted for inactivity after one week without new posts. All posts in it have been moved to the main feed :marseyrave:")
for name in names: for name in names:
first_mod_id = g.db.query(Mod.user_id).filter_by(sub=name).order_by(Mod.created_utc).first() first_mod_id = g.db.query(Mod.user_id).filter_by(hole=name).order_by(Mod.created_utc).first()
if first_mod_id: if first_mod_id:
first_mod = get_account(first_mod_id[0]) first_mod = get_account(first_mod_id[0])
badge_grant( badge_grant(
@ -282,22 +282,22 @@ def _sub_inactive_purge_task():
for admin in admins: for admin in admins:
send_repeatable_notification(admin, f":marseyrave: /h/{name} has been deleted for inactivity after one week without new posts. All posts in it have been moved to the main feed :marseyrave:") send_repeatable_notification(admin, f":marseyrave: /h/{name} has been deleted for inactivity after one week without new posts. All posts in it have been moved to the main feed :marseyrave:")
posts = g.db.query(Post).filter(Post.sub.in_(names)).all() posts = g.db.query(Post).filter(Post.hole.in_(names)).all()
for post in posts: for post in posts:
if post.sub == 'programming': if post.hole == 'programming':
post.sub = 'slackernews' post.hole = 'slackernews'
else: else:
post.sub = None post.hole = None
post.hole_pinned = None post.hole_pinned = None
g.db.add(post) g.db.add(post)
to_delete = mods \ to_delete = mods \
+ g.db.query(Exile).filter(Exile.sub.in_(names)).all() \ + g.db.query(Exile).filter(Exile.hole.in_(names)).all() \
+ g.db.query(SubBlock).filter(SubBlock.sub.in_(names)).all() \ + g.db.query(HoleBlock).filter(HoleBlock.hole.in_(names)).all() \
+ g.db.query(SubJoin).filter(SubJoin.sub.in_(names)).all() \ + g.db.query(StealthHoleUnblock).filter(StealthHoleUnblock.hole.in_(names)).all() \
+ g.db.query(SubSubscription).filter(SubSubscription.sub.in_(names)).all() \ + g.db.query(HoleFollow).filter(HoleFollow.hole.in_(names)).all() \
+ g.db.query(SubAction).filter(SubAction.sub.in_(names)).all() + g.db.query(HoleAction).filter(HoleAction.hole.in_(names)).all()
for x in to_delete: for x in to_delete:
g.db.delete(x) g.db.delete(x)

View File

@ -3,7 +3,7 @@ from flask import *
from sqlalchemy import and_, any_, or_ from sqlalchemy import and_, any_, or_
from sqlalchemy.orm import joinedload, Query, load_only from sqlalchemy.orm import joinedload, Query, load_only
from files.classes import Comment, CommentVote, Hat, Sub, Post, User, UserBlock, Vote from files.classes import Comment, CommentVote, Hat, Hole, Post, User, UserBlock, Vote
from files.helpers.config.const import * from files.helpers.config.const import *
from files.__main__ import cache from files.__main__ import cache
@ -321,16 +321,16 @@ def get_comments_v_properties(v, should_keep_func=None, *criterion):
else: dump.append(comment) else: dump.append(comment)
return (comments, output) return (comments, output)
def get_sub_by_name(sub, v=None, graceful=False): def get_hole(hole, v=None, graceful=False):
if not sub: if not hole:
if graceful: return None if graceful: return None
else: abort(404) else: abort(404)
sub = sub.replace('/h/', '').replace('h/', '').strip().lower() hole = hole.replace('/h/', '').replace('h/', '').strip().lower()
if not sub: if not hole:
if graceful: return None if graceful: return None
else: abort(404) else: abort(404)
sub = g.db.get(Sub, sub) hole = g.db.get(Hole, hole)
if not sub: if not hole:
if graceful: return None if graceful: return None
else: abort(404) else: abort(404)
return sub return sub

View File

@ -836,10 +836,10 @@ def complies_with_chud(obj):
if isinstance(obj, Post): if isinstance(obj, Post):
if obj.id in ADMIGGER_THREADS: return True if obj.id in ADMIGGER_THREADS: return True
if obj.sub == "chudrama": return True if obj.hole == "chudrama": return True
elif obj.parent_post: elif obj.parent_post:
if obj.parent_post in ADMIGGER_THREADS: return True if obj.parent_post in ADMIGGER_THREADS: return True
if obj.post.sub == "chudrama": return True if obj.post.hole == "chudrama": return True
#perserve old body_html to be used in checking for chud phrase #perserve old body_html to be used in checking for chud phrase
old_body_html = obj.body_html old_body_html = obj.body_html

View File

@ -36,7 +36,7 @@ from .feeds import *
if FEATURES['AWARDS']: if FEATURES['AWARDS']:
from .awards import * from .awards import *
from .giphy import * from .giphy import *
from .subs import * from .holes import *
if FEATURES['GAMBLING']: if FEATURES['GAMBLING']:
from .lottery import * from .lottery import *
from .casino import * from .casino import *

View File

@ -1029,7 +1029,7 @@ def ban_user(fullname, v):
except: abort(400) except: abort(400)
actual_reason = reason.split(str(post_id))[1].strip() actual_reason = reason.split(str(post_id))[1].strip()
post = get_post(post_id) post = get_post(post_id)
if post.sub != 'chudrama': if post.hole != 'chudrama':
post.bannedfor = f'{duration} by @{v.username}' post.bannedfor = f'{duration} by @{v.username}'
if actual_reason: if actual_reason:
post.bannedfor += f' for "{actual_reason}"' post.bannedfor += f' for "{actual_reason}"'
@ -1134,7 +1134,7 @@ def chud(fullname, v):
try: post = int(reason.split("/post/")[1].split(None, 1)[0]) try: post = int(reason.split("/post/")[1].split(None, 1)[0])
except: abort(400) except: abort(400)
post = get_post(post) post = get_post(post)
if post.sub == 'chudrama': if post.hole == 'chudrama':
abort(403, "You can't chud people in /h/chudrama") abort(403, "You can't chud people in /h/chudrama")
post.chuddedfor = f'{duration} by @{v.username}' post.chuddedfor = f'{duration} by @{v.username}'
g.db.add(post) g.db.add(post)
@ -1142,7 +1142,7 @@ def chud(fullname, v):
try: comment = int(reason.split("/comment/")[1].split(None, 1)[0]) try: comment = int(reason.split("/comment/")[1].split(None, 1)[0])
except: abort(400) except: abort(400)
comment = get_comment(comment) comment = get_comment(comment)
if comment.post.sub == 'chudrama': if comment.post.hole == 'chudrama':
abort(403, "You can't chud people in /h/chudrama") abort(403, "You can't chud people in /h/chudrama")
comment.chuddedfor = f'{duration} by @{v.username}' comment.chuddedfor = f'{duration} by @{v.username}'
g.db.add(comment) g.db.add(comment)

View File

@ -351,8 +351,8 @@ def award_thing(v, thing_type, id):
thing.title_html = filter_emojis_only(thing.title, golden=False, obj=thing, author=author) thing.title_html = filter_emojis_only(thing.title, golden=False, obj=thing, author=author)
elif kind == "chud": elif kind == "chud":
if thing_type == 'post' and thing.sub == 'chudrama' \ if thing_type == 'post' and thing.hole == 'chudrama' \
or thing_type == 'comment' and thing.post and thing.post.sub == 'chudrama': or thing_type == 'comment' and thing.post and thing.post.hole == 'chudrama':
abort(403, "You can't give the chud award in /h/chudrama") abort(403, "You can't give the chud award in /h/chudrama")
if author.queen: if author.queen:

View File

@ -38,11 +38,11 @@ def _mark_comment_as_read(cid, vid):
@app.get("/comment/<int:cid>") @app.get("/comment/<int:cid>")
@app.get("/post/<int:pid>/<anything>/<int:cid>") @app.get("/post/<int:pid>/<anything>/<int:cid>")
@app.get("/h/<sub>/comment/<int:cid>") @app.get("/h/<hole>/comment/<int:cid>")
@app.get("/h/<sub>/post/<int:pid>/<anything>/<int:cid>") @app.get("/h/<hole>/post/<int:pid>/<anything>/<int:cid>")
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400) @limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400)
@auth_desired_with_logingate @auth_desired_with_logingate
def post_pid_comment_cid(cid, v, pid=None, anything=None, sub=None): def post_pid_comment_cid(cid, v, pid=None, anything=None, hole=None):
comment = get_comment(cid, v=v) comment = get_comment(cid, v=v)
@ -95,7 +95,7 @@ def post_pid_comment_cid(cid, v, pid=None, anything=None, sub=None):
else: else:
if post.is_banned and not (v and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or post.author_id == v.id)): template = "post_banned.html" if post.is_banned and not (v and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or post.author_id == v.id)): template = "post_banned.html"
else: template = "post.html" else: template = "post.html"
return render_template(template, v=v, p=post, sort=sort, comment_info=comment_info, render_replies=True, sub=post.subr) return render_template(template, v=v, p=post, sort=sort, comment_info=comment_info, render_replies=True, hole=post.hole_obj)
@app.post("/comment") @app.post("/comment")
@limiter.limit('1/second', scope=rpath) @limiter.limit('1/second', scope=rpath)
@ -158,10 +158,10 @@ def comment(v):
abort(403, "You can't reply to deleted comments!") abort(403, "You can't reply to deleted comments!")
if posting_to_post: if posting_to_post:
sub = post_target.sub hole = post_target.hole
if sub and v.exiler_username(sub): abort(403, f"You're exiled from /h/{sub}") if hole and v.exiler_username(hole): abort(403, f"You're exiled from /h/{hole}")
if sub in {'furry','vampire','racist','femboy','edgy'} and not v.client and not v.house.lower().startswith(sub): if hole in {'furry','vampire','racist','femboy','edgy'} and not v.client and not v.house.lower().startswith(hole):
abort(403, f"You need to be a member of House {sub.capitalize()} to comment in /h/{sub}") abort(403, f"You need to be a member of House {hole.capitalize()} to comment in /h/{hole}")
if level > COMMENT_MAX_DEPTH: abort(400, f"Max comment level is {COMMENT_MAX_DEPTH}") if level > COMMENT_MAX_DEPTH: abort(400, f"Max comment level is {COMMENT_MAX_DEPTH}")
@ -255,7 +255,7 @@ def comment(v):
is_bot = v.client is not None and v.id not in BOT_SYMBOL_HIDDEN is_bot = v.client is not None and v.id not in BOT_SYMBOL_HIDDEN
chudded = v.chud and not (posting_to_post and post_target.sub == 'chudrama') chudded = v.chud and not (posting_to_post and post_target.hole == 'chudrama')
c = Comment(author_id=v.id, c = Comment(author_id=v.id,
parent_post=post_target.id if posting_to_post else None, parent_post=post_target.id if posting_to_post else None,
@ -610,7 +610,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.sub and v.mods(comment.post.sub)): if comment.author_id != v.id and v.admin_level < PERMS['POST_COMMENT_MODERATION'] and not (comment.post.hole and v.mods(comment.post.hole)):
abort(403) abort(403)
if comment.nsfw and v.is_permabanned: if comment.nsfw and v.is_permabanned:
@ -628,8 +628,8 @@ def toggle_comment_nsfw(cid, v):
) )
g.db.add(ma) g.db.add(ma)
else: else:
ma = SubAction( ma = HoleAction(
sub = comment.post.sub, 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",
user_id = v.id, user_id = v.id,
target_comment_id = comment.id, target_comment_id = comment.id,

View File

@ -13,30 +13,30 @@ from files.routes.wrappers import *
from files.__main__ import app, cache, limiter, redis_instance from files.__main__ import app, cache, limiter, redis_instance
@app.get("/") @app.get("/")
@app.get("/h/<sub>") @app.get("/h/<hole>")
@limiter.limit("30/minute;5000/hour;10000/day", deduct_when=lambda response: response.status_code < 400) @limiter.limit("30/minute;5000/hour;10000/day", deduct_when=lambda response: response.status_code < 400)
@auth_desired_with_logingate @auth_desired_with_logingate
def front_all(v, sub=None): def front_all(v, hole=None):
if sub: if hole:
sub = get_sub_by_name(sub, graceful=True) hole = get_hole(hole, graceful=True)
if sub and not can_see(v, sub): if hole and not can_see(v, hole):
abort(403) abort(403)
if request.path.startswith('/h/') and not sub: if request.path.startswith('/h/') and not hole:
abort(404) abort(404)
page = get_page() page = get_page()
if v: if v:
defaultsorting = v.defaultsorting defaultsorting = v.defaultsorting
if sub or SITE_NAME != 'rDrama': defaulttime = 'all' if hole or SITE_NAME != 'rDrama': defaulttime = 'all'
else: defaulttime = v.defaulttime else: defaulttime = v.defaulttime
else: else:
defaultsorting = "hot" defaultsorting = "hot"
if sub or SITE_NAME != 'rDrama': defaulttime = 'all' if hole or SITE_NAME != 'rDrama': defaulttime = 'all'
else: defaulttime = DEFAULT_TIME_FILTER else: defaulttime = DEFAULT_TIME_FILTER
if sub: defaultsorting = "new" if hole: defaultsorting = "new"
sort = request.values.get("sort", defaultsorting) sort = request.values.get("sort", defaultsorting)
t = request.values.get('t', defaulttime) t = request.values.get('t', defaulttime)
@ -53,10 +53,10 @@ def front_all(v, sub=None):
if sort == 'hot': default = True if sort == 'hot': default = True
else: default = False else: default = False
pins = session.get(f'{sub}_{sort}', default) pins = session.get(f'{hole}_{sort}', default)
if not v: if not v:
result = cache.get(f'frontpage_{sort}_{t}_{page}_{sub}_{pins}') result = cache.get(f'frontpage_{sort}_{t}_{page}_{hole}_{pins}')
if result: if result:
calc_users() calc_users()
return result return result
@ -68,7 +68,7 @@ def front_all(v, sub=None):
filter_words=v.filter_words if v else [], filter_words=v.filter_words if v else [],
gt=gt, gt=gt,
lt=lt, lt=lt,
sub=sub, hole=hole,
pins=pins, pins=pins,
) )
@ -79,10 +79,10 @@ def front_all(v, sub=None):
if v and v.client: return {"data": [x.json for x in posts], "total": total} if v and v.client: return {"data": [x.json for x in posts], "total": total}
result = render_template("home.html", v=v, listing=posts, total=total, sort=sort, t=t, page=page, sub=sub, home=True, pins=pins, size=size) result = render_template("home.html", v=v, listing=posts, total=total, sort=sort, t=t, page=page, hole=hole, home=True, pins=pins, size=size)
if not v: if not v:
cache.set(f'frontpage_{sort}_{t}_{page}_{sub}_{pins}', result, timeout=900) cache.set(f'frontpage_{sort}_{t}_{page}_{hole}_{pins}', result, timeout=900)
return result return result
@ -92,7 +92,7 @@ LIMITED_WPD_HOLES = ('aftermath', 'fights', 'gore', 'medical', 'request', 'selfh
'countryclub', 'highrollerclub') 'countryclub', 'highrollerclub')
@cache.memoize() @cache.memoize()
def frontlist(v=None, sort="hot", page=1, t="all", ids_only=True, filter_words='', gt=0, lt=0, sub=None, pins=True): def frontlist(v=None, sort="hot", page=1, t="all", ids_only=True, filter_words='', gt=0, lt=0, hole=None, pins=True):
posts = g.db.query(Post) posts = g.db.query(Post)
if v and v.hidevotedon: if v and v.hidevotedon:
@ -100,13 +100,13 @@ def frontlist(v=None, sort="hot", page=1, t="all", ids_only=True, filter_words='
and_(Vote.post_id == Post.id, Vote.user_id == v.id) and_(Vote.post_id == Post.id, Vote.user_id == v.id)
).filter(Vote.post_id == None) ).filter(Vote.post_id == None)
if sub: if hole:
posts = posts.filter(Post.sub == sub.name) posts = posts.filter(Post.hole == hole.name)
elif v: elif v:
posts = posts.filter(or_(Post.sub == None, Post.sub.notin_(v.sub_blocks))) posts = posts.filter(or_(Post.hole == None, Post.hole.notin_(v.hole_blocks)))
else: else:
stealth = [x[0] for x in g.db.query(Sub.name).filter_by(stealth=True)] stealth = [x[0] for x in g.db.query(Hole.name).filter_by(stealth=True)]
posts = posts.filter(or_(Post.sub == None, Post.sub.notin_(stealth))) posts = posts.filter(or_(Post.hole == None, Post.hole.notin_(stealth)))
if gt: posts = posts.filter(Post.created_utc > gt) if gt: posts = posts.filter(Post.created_utc > gt)
if lt: posts = posts.filter(Post.created_utc < lt) if lt: posts = posts.filter(Post.created_utc < lt)
@ -121,7 +121,7 @@ def frontlist(v=None, sort="hot", page=1, t="all", ids_only=True, filter_words='
) )
if pins and not gt and not lt: if pins and not gt and not lt:
if sub: posts = posts.filter(Post.hole_pinned == None) if hole: posts = posts.filter(Post.hole_pinned == None)
else: posts = posts.filter(Post.stickied == None) else: posts = posts.filter(Post.stickied == None)
if v: if v:
@ -141,28 +141,28 @@ def frontlist(v=None, sort="hot", page=1, t="all", ids_only=True, filter_words='
posts = posts.options(load_only(Post.id)).offset(size * (page - 1)) posts = posts.options(load_only(Post.id)).offset(size * (page - 1))
if SITE_NAME == 'WPD' and sort == "hot" and sub == None: if SITE_NAME == 'WPD' and sort == "hot" and hole == None:
posts = posts.limit(200).all() posts = posts.limit(200).all()
to_remove = [] to_remove = []
for h in LIMITED_WPD_HOLES: for h in LIMITED_WPD_HOLES:
to_remove += [x.id for x in posts if x.sub == h][1:] to_remove += [x.id for x in posts if x.hole == h][1:]
posts = [x for x in posts if x.id not in to_remove][:size] posts = [x for x in posts if x.id not in to_remove][:size]
elif SITE_NAME == 'WPD' and not v and sub == None: elif SITE_NAME == 'WPD' and not v and hole == None:
posts = posts.limit(200).all() posts = posts.limit(200).all()
posts = [x for x in posts if x.sub not in {'pets','selfharm'}][:size] posts = [x for x in posts if x.hole not in {'pets','selfharm'}][:size]
else: else:
posts = posts.limit(size).all() posts = posts.limit(size).all()
if pins and page == 1 and not gt and not lt: if pins and page == 1 and not gt and not lt:
if sub: if hole:
pins = g.db.query(Post).options(load_only(Post.id)).filter(Post.sub == sub.name, Post.hole_pinned != None) pins = g.db.query(Post).options(load_only(Post.id)).filter(Post.hole == hole.name, Post.hole_pinned != None)
else: else:
pins = g.db.query(Post).options(load_only(Post.id)).filter(Post.stickied != None, Post.is_banned == False) pins = g.db.query(Post).options(load_only(Post.id)).filter(Post.stickied != None, Post.is_banned == False)
if v: if v:
pins = pins.filter(or_(Post.sub == None, Post.sub.notin_(v.sub_blocks))) pins = pins.filter(or_(Post.hole == None, Post.hole.notin_(v.hole_blocks)))
if v: pins = pins.filter(Post.author_id.notin_(v.userblocks)) if v: pins = pins.filter(Post.author_id.notin_(v.userblocks))
@ -185,7 +185,7 @@ def random_post(v):
Post.deleted_utc == 0, Post.deleted_utc == 0,
Post.is_banned == False, Post.is_banned == False,
Post.private == False, Post.private == False,
or_(Post.sub == None, Post.sub.notin_(v.sub_blocks)), or_(Post.hole == None, Post.hole.notin_(v.hole_blocks)),
).order_by(func.random()).first() ).order_by(func.random()).first()
if p: p = p[0] if p: p = p[0]

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@ from sqlalchemy.sql.expression import not_, and_, or_
from sqlalchemy.orm import load_only from sqlalchemy.orm import load_only
from files.classes.mod_logs import ModAction from files.classes.mod_logs import ModAction
from files.classes.sub_logs import SubAction from files.classes.hole_logs import HoleAction
from files.helpers.config.const import * from files.helpers.config.const import *
from files.helpers.config.modaction_types import * from files.helpers.config.modaction_types import *
from files.helpers.get import * from files.helpers.get import *
@ -167,7 +167,7 @@ def notifications_posts(v):
listing = g.db.query(Post).filter( listing = g.db.query(Post).filter(
or_( or_(
Post.sub.in_(v.followed_subs), Post.hole.in_(v.followed_holes),
and_( and_(
Post.author_id.in_(v.followed_users), Post.author_id.in_(v.followed_users),
Post.notify == True, Post.notify == True,
@ -179,7 +179,7 @@ def notifications_posts(v):
Post.private == False, Post.private == False,
Post.author_id != v.id, Post.author_id != v.id,
Post.author_id.notin_(v.userblocks), Post.author_id.notin_(v.userblocks),
or_(Post.sub == None, Post.sub.notin_(v.sub_blocks)), or_(Post.hole == None, Post.hole.notin_(v.hole_blocks)),
).options(load_only(Post.id)) ).options(load_only(Post.id))
total = listing.count() total = listing.count()
@ -217,8 +217,8 @@ def notifications_modactions(v):
if v.admin_level >= PERMS['NOTIFICATIONS_MODERATOR_ACTIONS']: if v.admin_level >= PERMS['NOTIFICATIONS_MODERATOR_ACTIONS']:
cls = ModAction cls = ModAction
elif v.moderated_subs: elif v.moderated_holes:
cls = SubAction cls = HoleAction
else: else:
abort(403) abort(403)
@ -230,8 +230,8 @@ def notifications_modactions(v):
if v.admin_level < PERMS['PROGSTACK']: if v.admin_level < PERMS['PROGSTACK']:
listing = listing.filter(cls.kind.notin_(MODACTION_PRIVILEGED__TYPES)) listing = listing.filter(cls.kind.notin_(MODACTION_PRIVILEGED__TYPES))
if cls == SubAction: if cls == HoleAction:
listing = listing.filter(cls.sub.in_(v.moderated_subs)) listing = listing.filter(cls.hole.in_(v.moderated_holes))
total = listing.count() total = listing.count()
listing = listing.order_by(cls.id.desc()) listing = listing.order_by(cls.id.desc())

View File

@ -18,10 +18,10 @@ def vote_option(option_id, v):
abort(404) abort(404)
option = g.db.get(PostOption, option_id) option = g.db.get(PostOption, option_id)
if not option: abort(404) if not option: abort(404)
sub = option.parent.sub hole = option.parent.hole
if sub in {'furry','vampire','racist','femboy','edgy'} and not v.house.lower().startswith(sub): if hole in {'furry','vampire','racist','femboy','edgy'} and not v.house.lower().startswith(hole):
abort(403, f"You need to be a member of House {sub.capitalize()} to vote on polls in /h/{sub}") abort(403, f"You need to be a member of House {hole.capitalize()} to vote on polls in /h/{hole}")
if option.exclusive == 2: if option.exclusive == 2:
if option.parent.total_bet_voted(v): if option.parent.total_bet_voted(v):
@ -72,12 +72,12 @@ def vote_option_comment(option_id, v):
if not option: abort(404) if not option: abort(404)
if option.parent.parent_post: if option.parent.parent_post:
sub = option.parent.post.sub hole = option.parent.post.hole
else: else:
sub = None hole = None
if sub in {'furry','vampire','racist','femboy','edgy'} and not v.house.lower().startswith(sub): if hole in {'furry','vampire','racist','femboy','edgy'} and not v.house.lower().startswith(hole):
abort(403, f"You need to be a member of House {sub.capitalize()} to vote on polls in /h/{sub}") abort(403, f"You need to be a member of House {hole.capitalize()} to vote on polls in /h/{hole}")
if option.exclusive == 2: if option.exclusive == 2:
if option.parent.total_bet_voted(v): if option.parent.total_bet_voted(v):

View File

@ -79,25 +79,25 @@ def publish(pid, v):
return {"message": "Post has been published successfully!"} return {"message": "Post has been published successfully!"}
@app.get("/submit") @app.get("/submit")
@app.get("/h/<sub>/submit") @app.get("/h/<hole>/submit")
@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 submit_get(v, sub=None): def submit_get(v, hole=None):
sub = get_sub_by_name(sub, graceful=True) hole = get_hole(hole, graceful=True)
if request.path.startswith('/h/') and not sub: abort(404) if request.path.startswith('/h/') and not hole: abort(404)
SUBS = [x[0] for x in g.db.query(Sub.name).order_by(Sub.name)] HOLES = [x[0] for x in g.db.query(Hole.name).order_by(Hole.name)]
return render_template("submit.html", SUBS=SUBS, v=v, sub=sub) return render_template("submit.html", HOLES=HOLES, v=v, hole=hole)
@app.get("/post/<int:pid>") @app.get("/post/<int:pid>")
@app.get("/post/<int:pid>/<anything>") @app.get("/post/<int:pid>/<anything>")
@app.get("/h/<sub>/post/<int:pid>") @app.get("/h/<hole>/post/<int:pid>")
@app.get("/h/<sub>/post/<int:pid>/<anything>") @app.get("/h/<hole>/post/<int:pid>/<anything>")
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400) @limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400)
@auth_desired_with_logingate @auth_desired_with_logingate
def post_id(pid, v, anything=None, sub=None): def post_id(pid, v, anything=None, hole=None):
p = get_post(pid, v=v) p = get_post(pid, v=v)
if not can_see(v, p): abort(403) if not can_see(v, p): abort(403)
@ -192,7 +192,7 @@ def post_id(pid, v, anything=None, sub=None):
template = "post_banned.html" template = "post_banned.html"
result = render_template(template, v=v, p=p, ids=list(ids), result = render_template(template, v=v, p=p, ids=list(ids),
sort=sort, render_replies=True, offset=offset, sub=p.subr, sort=sort, render_replies=True, offset=offset, hole=p.hole_obj,
fart=get_setting('fart_mode')) fart=get_setting('fart_mode'))
if not v: if not v:
@ -426,13 +426,13 @@ def is_repost(v):
else: return not_a_repost else: return not_a_repost
@app.post("/submit") @app.post("/submit")
@app.post("/h/<sub>/submit") @app.post("/h/<hole>/submit")
@limiter.limit('1/second', scope=rpath) @limiter.limit('1/second', scope=rpath)
@limiter.limit('1/second', scope=rpath, key_func=get_ID) @limiter.limit('1/second', scope=rpath, key_func=get_ID)
@limiter.limit('20/day', deduct_when=lambda response: response.status_code < 400) @limiter.limit('20/day', deduct_when=lambda response: response.status_code < 400)
@limiter.limit('20/day', deduct_when=lambda response: response.status_code < 400, key_func=get_ID) @limiter.limit('20/day', deduct_when=lambda response: response.status_code < 400, key_func=get_ID)
@is_not_banned @is_not_banned
def submit_post(v, sub=None): def submit_post(v, hole=None):
url = request.values.get("url", "").strip() url = request.values.get("url", "").strip()
if '\\' in url: abort(400) if '\\' in url: abort(400)
@ -446,35 +446,35 @@ def submit_post(v, sub=None):
if not title: if not title:
abort(400, "Please enter a better title!") abort(400, "Please enter a better title!")
sub = request.values.get("sub", "").lower().replace('/h/','').strip() hole = request.values.get("hole", "").lower().replace('/h/','').strip()
if SITE == 'rdrama.net' and (v.chud == 1 or v.id == 253): if SITE == 'rdrama.net' and (v.chud == 1 or v.id == 253):
sub = 'chudrama' hole = 'chudrama'
if SITE == 'rdrama.net' and v.id == 10947: if SITE == 'rdrama.net' and v.id == 10947:
sub = 'mnn' hole = 'mnn'
if sub == 'changelog': if hole == 'changelog':
abort(400, "/h/changelog is archived") abort(400, "/h/changelog is archived")
if sub in {'furry','vampire','racist','femboy','edgy'} and not v.client and not v.house.lower().startswith(sub): if hole in {'furry','vampire','racist','femboy','edgy'} and not v.client and not v.house.lower().startswith(hole):
abort(400, f"You need to be a member of House {sub.capitalize()} to post in /h/{sub}") abort(400, f"You need to be a member of House {hole.capitalize()} to post in /h/{hole}")
if sub and sub != 'none': if hole and hole != 'none':
sub_name = sub.strip().lower() hole_name = hole.strip().lower()
sub = g.db.query(Sub).options(load_only(Sub.name)).filter_by(name=sub_name).one_or_none() hole = g.db.query(Hole).options(load_only(Hole.name)).filter_by(name=hole_name).one_or_none()
if not sub: abort(400, f"/h/{sub_name} not found!") if not hole: abort(400, f"/h/{hole_name} not found!")
if not can_see(v, sub): if not can_see(v, hole):
if sub.name == 'highrollerclub': if hole.name == 'highrollerclub':
abort(403, f"Only {patron}s can post in /h/{sub}") abort(403, f"Only {patron}s can post in /h/{hole}")
abort(403, f"You're not allowed to post in /h/{sub}") abort(403, f"You're not allowed to post in /h/{hole}")
sub = sub.name hole = hole.name
if v.exiler_username(sub): abort(400, f"You're exiled from /h/{sub}") if v.exiler_username(hole): abort(400, f"You're exiled from /h/{hole}")
else: sub = None else: hole = None
if not sub and HOLE_REQUIRED: if not hole and HOLE_REQUIRED:
abort(400, f"You must choose a {HOLE_NAME} for your post!") abort(400, f"You must choose a {HOLE_NAME} for your post!")
if v.longpost and (len(body) < 280 or ' [](' in body or body.startswith('[](')): if v.longpost and (len(body) < 280 or ' [](' in body or body.startswith('[](')):
@ -536,7 +536,7 @@ def submit_post(v, sub=None):
flag_private = request.values.get("private", False, bool) flag_private = request.values.get("private", False, bool)
flag_ghost = request.values.get("ghost", False, bool) and v.can_post_in_ghost_threads flag_ghost = request.values.get("ghost", False, bool) and v.can_post_in_ghost_threads
if flag_ghost: sub = None if flag_ghost: hole = None
if embed and len(embed) > 1500: embed = None if embed and len(embed) > 1500: embed = None
if embed: embed = embed.strip() if embed: embed = embed.strip()
@ -546,7 +546,7 @@ def submit_post(v, sub=None):
if url == '': url = None if url == '': url = None
flag_chudded = v.chud and sub != 'chudrama' flag_chudded = v.chud and hole != 'chudrama'
p = Post( p = Post(
private=flag_private, private=flag_private,
@ -560,7 +560,7 @@ def submit_post(v, sub=None):
body=body, body=body,
embed=embed, embed=embed,
title=title, title=title,
sub=sub, hole=hole,
ghost=flag_ghost, ghost=flag_ghost,
chudded=flag_chudded, chudded=flag_chudded,
rainbowed=bool(v.rainbow), rainbowed=bool(v.rainbow),
@ -684,7 +684,7 @@ def submit_post(v, sub=None):
if (SITE == 'rdrama.net' if (SITE == 'rdrama.net'
and v.id in {2008, 3336} and v.id in {2008, 3336}
and not (p.sub and p.subr.stealth)) and p.sub != 'slavshit' and not p.ghost: and not (p.hole and p.hole_obj.stealth)) and p.hole != 'slavshit' and not p.ghost:
p.stickied_utc = int(time.time()) + 28800 p.stickied_utc = int(time.time()) + 28800
p.stickied = "AutoJanny" p.stickied = "AutoJanny"
@ -766,7 +766,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.sub and v.mods(p.sub)): if p.author_id != v.id and v.admin_level < PERMS['POST_COMMENT_MODERATION'] and not (p.hole and v.mods(p.hole)):
abort(403) abort(403)
if p.nsfw and v.is_permabanned: if p.nsfw and v.is_permabanned:
@ -784,8 +784,8 @@ def mark_post_nsfw(pid, v):
) )
g.db.add(ma) g.db.add(ma)
else: else:
ma = SubAction( ma = HoleAction(
sub = p.sub, hole = p.hole,
kind = "set_nsfw", kind = "set_nsfw",
user_id = v.id, user_id = v.id,
target_post_id = p.id, target_post_id = p.id,
@ -805,7 +805,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.sub and v.mods(p.sub)): if p.author_id != v.id and v.admin_level < PERMS['POST_COMMENT_MODERATION'] and not (p.hole and v.mods(p.hole)):
abort(403) abort(403)
if p.nsfw and v.is_permabanned: if p.nsfw and v.is_permabanned:
@ -823,8 +823,8 @@ def unmark_post_nsfw(pid, v):
) )
g.db.add(ma) g.db.add(ma)
else: else:
ma = SubAction( ma = HoleAction(
sub = p.sub, hole = p.hole,
kind = "unset_nsfw", kind = "unset_nsfw",
user_id = v.id, user_id = v.id,
target_post_id = p.id, target_post_id = p.id,

View File

@ -2,7 +2,7 @@ from flask import g
from files.classes.reports import Report, CommentReport from files.classes.reports import Report, CommentReport
from files.classes.mod_logs import ModAction from files.classes.mod_logs import ModAction
from files.classes.sub_logs import SubAction from files.classes.hole_logs import HoleAction
from files.helpers.actions import * from files.helpers.actions import *
from files.helpers.alerts import * from files.helpers.alerts import *
from files.helpers.get import * from files.helpers.get import *
@ -28,7 +28,7 @@ def report_post(pid, v):
if len(reason_html) > 350: if len(reason_html) > 350:
abort(400, "Report reason too long!") abort(400, "Report reason too long!")
if reason.startswith('!') and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or post.sub and v.mods(post.sub)): if reason.startswith('!') and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or post.hole and v.mods(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']:
@ -41,15 +41,15 @@ def report_post(pid, v):
g.db.add(ma) g.db.add(ma)
position = 'a site admin' position = 'a site admin'
else: else:
ma = SubAction( ma = HoleAction(
sub=post.sub, hole=post.hole,
kind="flair_post", kind="flair_post",
user_id=v.id, user_id=v.id,
target_post_id=post.id, target_post_id=post.id,
_note=f'"{post.flair}"' _note=f'"{post.flair}"'
) )
g.db.add(ma) g.db.add(ma)
position = f'a /h/{post.sub} mod' position = f'a /h/{post.hole} mod'
if v.id != post.author_id: if v.id != post.author_id:
message = f'@{v.username} ({position}) has flaired [{post.title}]({post.shortlink}) with the flair: `"{og_flair}"`' message = f'@{v.username} ({position}) has flaired [{post.title}]({post.shortlink}) with the flair: `"{og_flair}"`'
@ -156,75 +156,75 @@ def move_post(post, v, reason):
if not reason.startswith('/h/') and not reason.startswith('h/'): if not reason.startswith('/h/') and not reason.startswith('h/'):
return False return False
sub_from = post.sub hole_from = post.hole
sub_to = get_sub_by_name(reason, graceful=True) hole_to = get_hole(reason, graceful=True)
sub_to = sub_to.name if sub_to else None hole_to = hole_to.name if hole_to else None
can_move_post = v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or (post.sub and v.mods(sub_from)) can_move_post = v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or (post.hole and v.mods(hole_from))
if sub_from != 'chudrama': # posts can only be moved out of /h/chudrama by admins if hole_from != 'chudrama': # posts can only be moved out of /h/chudrama by admins
can_move_post = can_move_post or post.author_id == v.id can_move_post = can_move_post or post.author_id == v.id
if not can_move_post: return False if not can_move_post: return False
if sub_to == None: if hole_to == None:
if HOLE_REQUIRED: if HOLE_REQUIRED:
abort(403, "All posts are required to be flaired!") abort(403, "All posts are required to be flaired!")
sub_to_in_notif = 'the main feed' hole_to_in_notif = 'the main feed'
else: else:
sub_to_in_notif = f'/h/{sub_to}' hole_to_in_notif = f'/h/{hole_to}'
if sub_from == sub_to: abort(409, f"Post is already in {sub_to_in_notif}") if hole_from == hole_to: abort(409, f"Post is already in {hole_to_in_notif}")
if post.author.exiler_username(sub_to): if post.author.exiler_username(hole_to):
abort(403, f"User is exiled from this {HOLE_NAME}!") abort(403, f"User is exiled from this {HOLE_NAME}!")
if sub_to == 'changelog': if hole_to == 'changelog':
abort(403, "/h/changelog is archived!") abort(403, "/h/changelog is archived!")
if sub_to in {'furry','vampire','racist','femboy','edgy'} and not v.client and not post.author.house.lower().startswith(sub_to): if hole_to in {'furry','vampire','racist','femboy','edgy'} and not v.client and not post.author.house.lower().startswith(hole_to):
if v.id == post.author_id: if v.id == post.author_id:
abort(403, f"You need to be a member of House {sub_to.capitalize()} to post in /h/{sub_to}") abort(403, f"You need to be a member of House {hole_to.capitalize()} to post in /h/{hole_to}")
else: else:
abort(403, f"@{post.author_name} needs to be a member of House {sub_to.capitalize()} for their post to be moved to /h/{sub_to}") abort(403, f"@{post.author_name} needs to be a member of House {hole_to.capitalize()} for their post to be moved to /h/{hole_to}")
post.sub = sub_to post.hole = hole_to
post.hole_pinned = None post.hole_pinned = None
g.db.add(post) g.db.add(post)
if v.id != post.author_id: if v.id != post.author_id:
sub_from_str = 'main feed' if sub_from is None else \ hole_from_str = 'main feed' if hole_from is None else \
f'<a href="/h/{sub_from}">/h/{sub_from}</a>' f'<a href="/h/{hole_from}">/h/{hole_from}</a>'
sub_to_str = 'main feed' if sub_to is None else \ hole_to_str = 'main feed' if hole_to is None else \
f'<a href="/h/{sub_to}">/h/{sub_to}</a>' f'<a href="/h/{hole_to}">/h/{hole_to}</a>'
if v.admin_level >= PERMS['POST_COMMENT_MODERATION']: if v.admin_level >= PERMS['POST_COMMENT_MODERATION']:
ma = ModAction( ma = ModAction(
kind='move_hole', kind='move_hole',
user_id=v.id, user_id=v.id,
target_post_id=post.id, target_post_id=post.id,
_note=f'{sub_from_str}{sub_to_str}', _note=f'{hole_from_str}{hole_to_str}',
) )
g.db.add(ma) g.db.add(ma)
else: else:
ma = SubAction( ma = HoleAction(
sub=sub_from, hole=hole_from,
kind='move_hole', kind='move_hole',
user_id=v.id, user_id=v.id,
target_post_id=post.id, target_post_id=post.id,
_note=f'{sub_from_str}{sub_to_str}', _note=f'{hole_from_str}{hole_to_str}',
) )
g.db.add(ma) g.db.add(ma)
if v.admin_level >= PERMS['POST_COMMENT_MODERATION']: position = 'a site admin' if v.admin_level >= PERMS['POST_COMMENT_MODERATION']: position = 'a site admin'
else: position = f'a /h/{sub_from} mod' else: position = f'a /h/{hole_from} mod'
if sub_from == None: if hole_from == None:
sub_from_in_notif = 'the main feed' hole_from_in_notif = 'the main feed'
else: else:
sub_from_in_notif = f'/h/{sub_from}' hole_from_in_notif = f'/h/{hole_from}'
message = f"@{v.username} ({position}) has moved [{post.title}]({post.shortlink}) from {sub_from_in_notif} to {sub_to_in_notif}" message = f"@{v.username} ({position}) has moved [{post.title}]({post.shortlink}) from {hole_from_in_notif} to {hole_to_in_notif}"
send_repeatable_notification(post.author_id, message) send_repeatable_notification(post.author_id, message)
cache.delete_memoized(frontlist) cache.delete_memoized(frontlist)
return f"Post moved to {sub_to_in_notif} successfully!" return f"Post moved to {hole_to_in_notif} successfully!"

View File

@ -140,7 +140,7 @@ def searchposts(v):
if search_operator_hole in criteria: if search_operator_hole in criteria:
posts = posts.filter(Post.sub == criteria[search_operator_hole]) posts = posts.filter(Post.hole == criteria[search_operator_hole])
if 'after' in criteria: if 'after' in criteria:
after = criteria['after'] after = criteria['after']
@ -239,7 +239,7 @@ def searchcomments(v):
if 'nsfw' in criteria: comments = comments.filter(Comment.nsfw == True) if 'nsfw' in criteria: comments = comments.filter(Comment.nsfw == True)
if search_operator_hole in criteria: if search_operator_hole in criteria:
comments = comments.filter(Post.sub == criteria[search_operator_hole]) comments = comments.filter(Post.hole == criteria[search_operator_hole])
comments = apply_time_filter(t, comments, Comment) comments = apply_time_filter(t, comments, Comment)

View File

@ -1300,14 +1300,14 @@ def fp(v, fp):
g.db.add(v) g.db.add(v)
return '', 204 return '', 204
@app.post("/toggle_pins/<sub>/<sort>") @app.post("/toggle_pins/<hole>/<sort>")
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400) @limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400)
def toggle_pins(sub, sort): def toggle_pins(hole, sort):
if sort == 'hot': default = True if sort == 'hot': default = True
else: default = False else: default = False
pins = session.get(f'{sub}_{sort}', default) pins = session.get(f'{hole}_{sort}', default)
session[f'{sub}_{sort}'] = not pins session[f'{hole}_{sort}'] = not pins
return {"message": "Pins toggled successfully!"} return {"message": "Pins toggled successfully!"}

View File

@ -153,11 +153,11 @@ def vote_post_comment(target_id, new, v, cls, vote_cls):
or 'forum' in target.domain or 'chan' in target.domain or 'lemmy' in target.domain or 'mastodon' in target.domain or 'forum' in target.domain or 'chan' in target.domain or 'lemmy' in target.domain or 'mastodon' in target.domain
or (target.domain in BOOSTED_SITES and not target.url.startswith('/'))): or (target.domain in BOOSTED_SITES and not target.url.startswith('/'))):
mul = 2 mul = 2
elif target.sub in STEALTH_HOLES or target.sub in {'countryclub', 'highrollerclub'}: elif target.hole in STEALTH_HOLES or target.hole in {'countryclub', 'highrollerclub'}:
mul = 2 mul = 2
elif 6 <= datetime.fromtimestamp(target.created_utc).hour <= 10: elif 6 <= datetime.fromtimestamp(target.created_utc).hour <= 10:
mul = 2 mul = 2
elif target.sub in BOOSTED_HOLES: elif target.hole in BOOSTED_HOLES:
mul = 1.25 mul = 1.25
if target.body_html and target.author.id != 8768: if target.body_html and target.author.id != 8768:

View File

@ -74,8 +74,8 @@
<span class="font-weight-bold"><a {% if v and v.newtab %}data-target="t" target="_blank"{% endif %} href="{{c.post.permalink}}">{{c.post.realtitle(v) | safe}}</a></span> <span class="font-weight-bold"><a {% if v and v.newtab %}data-target="t" target="_blank"{% endif %} href="{{c.post.permalink}}">{{c.post.realtitle(v) | safe}}</a></span>
{% endif %} {% endif %}
{% if c.post.sub %} {% if c.post.hole %}
<span class="ml-1"> in <a href="/h/{{c.post.sub}}" {% if v and v.newtab %}data-target="t" target="_blank"{% endif %}>/h/{{c.post.sub}}</a></span> <span class="ml-1"> in <a href="/h/{{c.post.hole}}" {% if v and v.newtab %}data-target="t" target="_blank"{% endif %}>/h/{{c.post.hole}}</a></span>
{% endif %} {% endif %}
{% elif c.author_id==AUTOJANNY_ID %} {% elif c.author_id==AUTOJANNY_ID %}
<span class="font-weight-bold">Notification</span> <span class="font-weight-bold">Notification</span>
@ -124,17 +124,17 @@
{% endfor %} {% endfor %}
{% if c.parent_post %} {% if c.parent_post %}
{% set sub = c.post.sub %} {% set hole = c.post.hole %}
{% if sub and c.author.exiler_username(sub) %} {% if hole and c.author.exiler_username(hole) %}
<a><i class="fas fa-campfire text-danger" data-bs-toggle="tooltip" data-bs-placement="bottom" title="User has been exiled from /h/{{sub}} by @{{c.author.exiler_username(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/{{hole}} by @{{c.author.exiler_username(hole)}}"></i></a>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if c.bannedfor and not (c.parent_post and c.post.sub == 'chudrama') %} {% if c.bannedfor and not (c.parent_post and c.post.hole == 'chudrama') %}
<i class="fas fa-hammer-crash text-danger" data-bs-toggle="tooltip" data-bs-placement="bottom" title="User was banned for this comment {{c.bannedfor}}"></i> <i class="fas fa-hammer-crash text-danger" data-bs-toggle="tooltip" data-bs-placement="bottom" title="User was banned for this comment {{c.bannedfor}}"></i>
{% endif %} {% endif %}
{% if c.chuddedfor and not (c.parent_post and c.post.sub == 'chudrama') %} {% if c.chuddedfor and not (c.parent_post and c.post.hole == 'chudrama') %}
<i class="fas fa-face-sleeping text-danger" data-bs-toggle="tooltip" data-bs-placement="bottom" title="User was chudded for this comment {{c.chuddedfor}}"></i> <i class="fas fa-face-sleeping text-danger" data-bs-toggle="tooltip" data-bs-placement="bottom" title="User was chudded for this comment {{c.chuddedfor}}"></i>
{% endif %} {% endif %}
@ -436,7 +436,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.sub and v.mods(c.post.sub) %} {% elif c.post.hole and v.mods(c.post.hole) %}
{% set url = "pin_comment_mod" %} {% set url = "pin_comment_mod" %}
{% endif %} {% endif %}
@ -466,10 +466,10 @@
{% endif %} {% endif %}
{% if c.parent_post %} {% if c.parent_post %}
{% set sub = c.post.sub %} {% set hole = c.post.hole %}
{% if sub and v.mods(sub) and not c.author.mods(sub) %} {% if hole and v.mods(hole) and not c.author.mods(hole) %}
<button type="button" id="exile-{{c.id}}" class="d-none {% if not c.author.exiler_username(sub) %}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(sub) %}d-md-block{% endif %} dropdown-item list-inline-item text-success" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{sub}}/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 %}
{% endif %} {% endif %}
@ -478,7 +478,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.sub and v.mods(c.post.sub))) %} {% 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(c.post.hole))) %}
<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 %}
@ -636,7 +636,7 @@
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if FEATURES['NSFW_MARKING'] and (c.author_id == v.id or (c.post.sub and v.mods(c.post.sub))) %} {% if FEATURES['NSFW_MARKING'] and (c.author_id == v.id or (c.post.hole and v.mods(c.post.hole))) %}
<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>
@ -646,17 +646,17 @@
{% 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.sub and v.mods(c.post.sub) %} {% elif c.post.hole and v.mods(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 %}
{% endif %} {% endif %}
{% if c.parent_post %} {% if c.parent_post %}
{% set sub = c.post.sub %} {% set hole = c.post.hole %}
{% if sub and v.mods(sub) and not c.author.mods(sub) %} {% if hole and v.mods(hole) and not c.author.mods(hole) %}
<button type="button" data-bs-dismiss="modal" id="exile2-{{c.id}}" class="{% if c.author.exiler_username(sub) %}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(sub) %}d-none{% endif %} list-group-item text-success" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{sub}}/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 %}
{% endif %} {% endif %}
{% endif %} {% endif %}

View File

@ -9,17 +9,17 @@
{% block banner %} {% block banner %}
{% include "modals/expanded_image.html" %} {% include "modals/expanded_image.html" %}
{% if err or '@' not in request.path %} {% if err or '@' not in request.path %}
{% if IS_FISTMAS() and not sub %} {% if IS_FISTMAS() and not hole %}
{% include 'events/fistmas/banner.html' %} {% include 'events/fistmas/banner.html' %}
{% elif IS_HOMOWEEN() and not sub %} {% elif IS_HOMOWEEN() and not hole %}
{% include 'events/homoween/banner.html' %} {% include 'events/homoween/banner.html' %}
{% else %} {% else %}
{% set path = "files/assets/images/" ~ SITE_NAME %} {% set path = "files/assets/images/" ~ SITE_NAME %}
{% if err and SITE_NAME == 'rDrama' %} {% if err and SITE_NAME == 'rDrama' %}
{% set src = "banner_error.webp" | asset_siteimg %} {% set src = "banner_error.webp" | asset_siteimg %}
{% elif sub and sub.has_banners %} {% elif hole and hole.has_banners %}
{% set src = sub.random_banner() %} {% set src = hole.random_banner() %}
{% set alt = ['/h/', sub, 'banner']|join %} {% set alt = ['/h/', sub, 'banner']|join %}
{% set class = 'site-banner-hole' %} {% set class = 'site-banner-hole' %}
{% elif get_orgy(v) and os_path.exists(path ~ "/orgy_banners") %} {% elif get_orgy(v) and os_path.exists(path ~ "/orgy_banners") %}
@ -34,8 +34,8 @@
{% endif %} {% endif %}
{% if SITE_NAME == "WPD" %} {% if SITE_NAME == "WPD" %}
{% if sub %} {% if hole %}
{% set href = "/h/" ~ sub %} {% set href = "/h/" ~ hole %}
{% set expand = false %} {% set expand = false %}
{% else %} {% else %}
{% set href = "/" %} {% set href = "/" %}
@ -62,7 +62,7 @@
<img data-nonce="{{g.nonce}}" data-onclick="{{expand|default('expandImage()')}}" class="{{class|default('site-banner')}}" alt="{{alt|default('site banner')}}" src="{{banner_url}}"> <img data-nonce="{{g.nonce}}" data-onclick="{{expand|default('expandImage()')}}" class="{{class|default('site-banner')}}" alt="{{alt|default('site banner')}}" src="{{banner_url}}">
{% endmacro %} {% endmacro %}
{% if sub and sub.has_banners %} {% if hole and hole.has_banners %}
{{img_element()}} {{img_element()}}
{% else %} {% else %}
<div class="banner-wrapper"> <div class="banner-wrapper">

View File

@ -4,7 +4,7 @@
<a href="{{image}}" style="text-decoration:none"> <a href="{{image}}" style="text-decoration:none">
<img class="mb-4" alt="sidebar image" data-nonce="{{g.nonce}}" data-onclick="expandImage()" loading="lazy" src="{{image}}" width="100%"> <img class="mb-4" alt="sidebar image" data-nonce="{{g.nonce}}" data-onclick="expandImage()" loading="lazy" src="{{image}}" width="100%">
{% if not sub %} {% if not hole %}
{% set coordsLookup = ({ {% set coordsLookup = ({
"1.webp":({ "1.webp":({
"left":({ "left":({

View File

@ -1,4 +1,4 @@
{% if SITE_NAME != 'WPD' and not (v and v.poor) and (not v or v.event_music) and not (sub and sub.name == 'music') and not (IS_HOMOWEEN() and p and p.award_count("haunt", v)) %} {% if SITE_NAME != 'WPD' and not (v and v.poor) and (not v or v.event_music) and not (hole and hole.name == 'music') and not (IS_HOMOWEEN() and p and p.award_count("haunt", v)) %}
{% set path = "assets/events/" ~ IS_EVENT() ~ "/music" %} {% set path = "assets/events/" ~ IS_EVENT() ~ "/music" %}
{% set song = SITE_FULL ~ "/" ~ path ~ "/" ~ listdir('files/'~path)|random() ~ '?x=45' %} {% set song = SITE_FULL ~ "/" ~ path ~ "/" ~ listdir('files/'~path)|random() ~ '?x=45' %}
<input hidden id="event-song" value="{{song}}"> <input hidden id="event-song" value="{{song}}">

View File

@ -1,6 +1,6 @@
{%- set search_placeholder = "Search" -%} {%- set search_placeholder = "Search" -%}
{%- if sub -%} {%- if hole -%}
{%- set search_placeholder = "Search (try '" ~ HOLE_NAME ~ ":" ~ sub.name ~ "')" -%} {%- set search_placeholder = "Search (try '" ~ HOLE_NAME ~ ":" ~ hole.name ~ "')" -%}
{%- endif -%} {%- endif -%}
<nav class="shadow-md fixed-top"> <nav class="shadow-md fixed-top">
@ -84,7 +84,7 @@
<div class="navbar navbar-expand-md navbar-light" id="navbar"> <div class="navbar navbar-expand-md navbar-light" id="navbar">
<div class="container-fluid" style="padding:0"> <div class="container-fluid" style="padding:0">
<a href="/" class="navbar-brand mr-auto {% if not has_logo and not sub %}flex-grow-1{% endif %}"> <a href="/" class="navbar-brand mr-auto {% if not has_logo and not hole %}flex-grow-1{% endif %}">
{% if IS_DKD() %} {% if IS_DKD() %}
{% set icon_url = macros.random_image('assets/events/DKD/images/icon') %} {% set icon_url = macros.random_image('assets/events/DKD/images/icon') %}
{% elif IS_FISTMAS() %} {% elif IS_FISTMAS() %}
@ -112,8 +112,8 @@
{% endif %} {% endif %}
{% endif %} {% endif %}
<img loading="lazy" id="header--icon" alt="header icon" <img loading="lazy" id="header--icon" alt="header icon"
{%- if sub and sub.marseyurl -%} {%- if hole and hole.marseyurl -%}
src="{{sub.marseyurl}}" src="{{hole.marseyurl}}"
{%- else -%} {%- else -%}
src="{{icon_url}}" src="{{icon_url}}"
{%- if width -%} {%- if width -%}
@ -123,8 +123,8 @@
> >
</a> </a>
{% if sub %} {% if hole %}
<a id="sub-name" href="/h/{{sub}}" class="font-weight-bold flex-grow-1 ml-2 mt-1" {% if sub.name|length >= 17 %}style="font-size:max(10px,1.2vw)"{% endif %}>{% if not HOLE_STYLE_FLAIR %}/h/{% endif %}{{sub}}</a> <a id="hole-name" href="/h/{{hole}}" class="font-weight-bold flex-grow-1 ml-2 mt-1" {% if hole.name|length >= 17 %}style="font-size:max(10px,1.2vw)"{% endif %}>{% if not HOLE_STYLE_FLAIR %}/h/{% endif %}{{hole}}</a>
{% elif has_logo %} {% elif has_logo %}
<div id="logo-container" class="flex-grow-1 logo-container"> <div id="logo-container" class="flex-grow-1 logo-container">
<a href="/"> <a href="/">

View File

@ -1,7 +1,7 @@
{% extends "default.html" %} {% extends "default.html" %}
{% block pagetitle %}Users {{verb}} /h/{{sub}}{% endblock %} {% block pagetitle %}Users {{verb}} /h/{{hole}}{% endblock %}
{% block content %} {% block content %}
<h5 class="mt-3">Users {{verb}} /h/{{sub}}</h5> <h5 class="mt-3">Users {{verb}} /h/{{hole}}</h5>
<div class="overflow-x-auto mt-1"><table class="table table-striped mb-5"> <div class="overflow-x-auto mt-1"><table class="table table-striped mb-5">
<thead class="bg-primary text-white"> <thead class="bg-primary text-white">
<tr> <tr>

View File

@ -9,7 +9,7 @@
<h3 class=" d-md-none">Create a {{HOLE_NAME}}</h3> <h3 class=" d-md-none">Create a {{HOLE_NAME}}</h3>
<div class="body"> <div class="body">
<input hidden name="formkey" value="{{v|formkey}}"> <input hidden name="formkey" value="{{v|formkey}}">
<label for="title">Sub Name</label> <label for="title">Hole Name</label>
<input minlength="3" maxlength="25" pattern='[a-zA-Z0-9_\-]*' class="form-control" id="title-register" type="text" name="name" required> <input minlength="3" maxlength="25" pattern='[a-zA-Z0-9_\-]*' class="form-control" id="title-register" type="text" name="name" required>
<small class="form-text text-muted">3-25 characters, including letters, numbers, _ , and -</small> <small class="form-text text-muted">3-25 characters, including letters, numbers, _ , and -</small>
{% if HOLE_INACTIVITY_DELETION %} {% if HOLE_INACTIVITY_DELETION %}

View File

@ -1,7 +1,7 @@
{% extends "default.html" %} {% extends "default.html" %}
{% block pagetitle %}/h/{{sub}} Exiles{% endblock %} {% block pagetitle %}/h/{{hole}} Exiles{% endblock %}
{% block content %} {% block content %}
<h5 class="my-4 ml-2">Users exiled from /h/{{sub}}</h5> <h5 class="my-4 ml-2">Users exiled from /h/{{hole}}</h5>
<div class="overflow-x-auto"><table class="table table-striped mb-5"> <div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white"> <thead class="bg-primary text-white">
<tr> <tr>
@ -23,8 +23,8 @@
</td> </td>
<td {% if exile.created_utc %}data-time="{{exile.created_utc}}"{% endif %}></td> <td {% if exile.created_utc %}data-time="{{exile.created_utc}}"{% endif %}></td>
<td> <td>
{% if v.mods(sub.name) %} {% if v.mods(hole.name) %}
<form action="/h/{{sub}}/unexile/{{user.id}}" method="post" data-nonce="{{g.nonce}}" data-onsubmit="sendFormXHRReload(this)"> <form action="/h/{{hole}}/unexile/{{user.id}}" method="post" data-nonce="{{g.nonce}}" data-onsubmit="sendFormXHRReload(this)">
<input hidden name="formkey" value="{{v|formkey}}"> <input hidden name="formkey" value="{{v|formkey}}">
<input autocomplete="off" class="btn btn-primary ml-auto" type="submit" value="Unexile"> <input autocomplete="off" class="btn btn-primary ml-auto" type="submit" value="Unexile">
</form> </form>

View File

@ -18,15 +18,15 @@
{% for sub, count in subs %} {% for sub, count in subs %}
<tr> <tr>
<td>{{loop.index}}</td> <td>{{loop.index}}</td>
<td><a href="/h/{{sub}}">{{sub}} {% if sub.name in v.sub_blocks %}<span class="text-danger">[blocked, visit it to unblock it]</span>{% endif %}</a></td> <td><a href="/h/{{hole}}">{{hole}} {% if hole.name in v.hole_blocks %}<span class="text-danger">[blocked, visit it to unblock it]</span>{% endif %}</a></td>
<td><a href="/h/{{sub}}">{{count}}</a></td> <td><a href="/h/{{hole}}">{{count}}</a></td>
<td><a href="/h/{{sub}}/followers">{{sub.follow_num}}</a></td> <td><a href="/h/{{hole}}/followers">{{hole.follow_num}}</a></td>
{% if sub.stealth %} {% if hole.stealth %}
<td>{{total_users - sub.join_num}}</td> <td>{{total_users - hole.join_num}}</td>
{% else %} {% else %}
<td><a href="/h/{{sub}}/blockers">{{sub.block_num}}</a></td> <td><a href="/h/{{hole}}/blockers">{{hole.block_num}}</a></td>
{% endif %} {% endif %}
<td data-time="{{sub.created_utc}}"></td> <td data-time="{{hole.created_utc}}"></td>
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>

View File

@ -1,10 +1,10 @@
{% extends "default.html" %} {% extends "default.html" %}
{% block pagetitle %}/h/{{sub}} Mods{% endblock %} {% block pagetitle %}/h/{{hole}} Mods{% endblock %}
{% block content %} {% block content %}
<script defer src="{{'js/remove_mod.js' | asset}}"></script> <script defer src="{{'js/remove_mod.js' | asset}}"></script>
<h5 class="mt-2">/h/{{sub}} Mods</h5> <h5 class="mt-2">/h/{{hole}} Mods</h5>
<div class="overflow-x-auto mt-1"><table class="table table-striped mb-5"> <div class="overflow-x-auto mt-1"><table class="table table-striped mb-5">
<thead class="bg-primary text-white"> <thead class="bg-primary text-white">
<tr> <tr>
@ -20,8 +20,8 @@
<td>{% include "user_in_table.html" %}</td> <td>{% include "user_in_table.html" %}</td>
<td data-time="{{mod.created_utc}}"></td> <td data-time="{{mod.created_utc}}"></td>
<td> <td>
{% if v.id == user.id or v.mod_date(sub.name) and v.mod_date(sub.name) < mod.created_utc %} {% if v.id == user.id or v.mod_date(hole.name) and v.mod_date(hole.name) < mod.created_utc %}
<form action="/h/{{sub}}/remove_mod" method="post" data-nonce="{{g.nonce}}" data-onsubmit="removeMod(this)"> <form action="/h/{{hole}}/remove_mod" method="post" data-nonce="{{g.nonce}}" data-onsubmit="removeMod(this)">
<input hidden name="formkey" value="{{v|formkey}}"> <input hidden name="formkey" value="{{v|formkey}}">
<input hidden name="uid" value="{{user.id}}"> <input hidden name="uid" value="{{user.id}}">
<input autocomplete="off" class="btn btn-primary ml-auto" type="submit" value="{% if v.id == user.id %}Resign{% else %}Remove Mod{% endif %}"> <input autocomplete="off" class="btn btn-primary ml-auto" type="submit" value="{% if v.id == user.id %}Resign{% else %}Remove Mod{% endif %}">
@ -33,8 +33,8 @@
</table> </table>
{% if v.mods(sub.name) %} {% if v.mods(hole.name) %}
<form action="/h/{{sub}}/add_mod" method="post" data-nonce="{{g.nonce}}" data-onsubmit="sendFormXHRReload(this)"> <form action="/h/{{hole}}/add_mod" method="post" data-nonce="{{g.nonce}}" data-onsubmit="sendFormXHRReload(this)">
<input hidden name="formkey" value="{{v|formkey}}"> <input hidden name="formkey" value="{{v|formkey}}">
<input class="form-control" style="display:inline;width:250px" autocomplete="off" type="text" name="user" class="form-control" placeholder="Enter username.."> <input class="form-control" style="display:inline;width:250px" autocomplete="off" type="text" name="user" class="form-control" placeholder="Enter username..">
<input autocomplete="off" class="btn btn-primary ml-auto" type="submit" value="Add Mod" style="margin-bottom: 5px"> <input autocomplete="off" class="btn btn-primary ml-auto" type="submit" value="Add Mod" style="margin-bottom: 5px">

View File

@ -1,5 +1,5 @@
{% extends "default.html" %} {% extends "default.html" %}
{% block pagetitle %}/h/{{sub}} Settings{% endblock %} {% block pagetitle %}/h/{{hole}} Settings{% endblock %}
{% block content %} {% block content %}
@ -8,7 +8,7 @@
</div> </div>
<div class="d-inline-block w-lg-100 pt-1 pt-lg-3"> <div class="d-inline-block w-lg-100 pt-1 pt-lg-3">
<div class="custom-control custom-switch"> <div class="custom-control custom-switch">
<input autocomplete="off" type="checkbox" class="custom-control-input" id="stealth" name="stealth" {% if sub.stealth %}checked{% endif %} data-nonce="{{g.nonce}}" data-onchange="postToastSwitch(this,'/h/{{sub}}/stealth')"> <input autocomplete="off" type="checkbox" class="custom-control-input" id="stealth" name="stealth" {% if hole.stealth %}checked{% endif %} data-nonce="{{g.nonce}}" data-onchange="postToastSwitch(this,'/h/{{hole}}/stealth')">
<label class="custom-control-label" for="stealth"></label> <label class="custom-control-label" for="stealth"></label>
</div> </div>
<span class="text-small text-muted"> <span class="text-small text-muted">
@ -18,8 +18,8 @@
<h5 class="mt-5">Marsey</h5> <h5 class="mt-5">Marsey</h5>
<div class="settings-section rounded"> <div class="settings-section rounded">
<img loading="lazy" alt="sub marsey picture" src="{{sub.marsey_url}}" style="max-width:100px"> <img loading="lazy" alt="sub marsey picture" src="{{hole.marsey_url}}" style="max-width:100px">
<form class="d-inline-block" action="/h/{{sub}}/marsey_image" method="post" enctype="multipart/form-data"> <form class="d-inline-block" action="/h/{{hole}}/marsey_image" method="post" enctype="multipart/form-data">
<input hidden name="formkey" value="{{v|formkey}}"> <input hidden name="formkey" value="{{v|formkey}}">
<label class="btn btn-secondary text-capitalize mr-2 mb-0"> <label class="btn btn-secondary text-capitalize mr-2 mb-0">
Upload<input autocomplete="off" type="file" accept="image/*" {% if g.is_tor %}disabled{% endif %} hidden name="marsey" data-nonce="{{g.nonce}}" onchange_submit> Upload<input autocomplete="off" type="file" accept="image/*" {% if g.is_tor %}disabled{% endif %} hidden name="marsey" data-nonce="{{g.nonce}}" onchange_submit>
@ -32,8 +32,8 @@
<h5 class=" mt-5">Sidebar Picture</h5> <h5 class=" mt-5">Sidebar Picture</h5>
<div class="settings-section rounded"> <div class="settings-section rounded">
<img class="mr-3" loading="lazy" alt="sub sidebar picture" src="{{sub.sidebar_url}}" style="max-width:min(300px,100%)"> <img class="mr-3" loading="lazy" alt="sub sidebar picture" src="{{hole.sidebar_url}}" style="max-width:min(300px,100%)">
<form class="d-inline-block mt-2" action="/h/{{sub}}/sidebar_image" method="post" enctype="multipart/form-data"> <form class="d-inline-block mt-2" action="/h/{{hole}}/sidebar_image" method="post" enctype="multipart/form-data">
<input hidden name="formkey" value="{{v|formkey}}"> <input hidden name="formkey" value="{{v|formkey}}">
<label class="btn btn-secondary text-capitalize mr-2 mb-0"> <label class="btn btn-secondary text-capitalize mr-2 mb-0">
Upload<input autocomplete="off" type="file" accept="image/*" {% if g.is_tor %}disabled{% endif %} hidden name="sidebar" data-nonce="{{g.nonce}}" onchange_submit> Upload<input autocomplete="off" type="file" accept="image/*" {% if g.is_tor %}disabled{% endif %} hidden name="sidebar" data-nonce="{{g.nonce}}" onchange_submit>
@ -45,26 +45,26 @@
</div> </div>
<h5 class="mt-5">Banners</h5> <h5 class="mt-5">Banners</h5>
<div class="settings-section rounded sub-banner-update-section"> <div class="settings-section rounded hole-banner-update-section">
{% for banner in sub.banner_urls %} {% for banner in hole.banner_urls %}
<section id="sub-banner-update-{{loop.index - 1}}" class="mt-5 d-block sub-settings-subsection"> <section id="hole-banner-update-{{loop.index - 1}}" class="mt-5 d-block hole-settings-subsection">
<img class="mr-3" loading="lazy" alt="/h/{{sub.name}} banner" src="{{banner}}" style="max-height:300px;max-width:100%"> <img class="mr-3" loading="lazy" alt="/h/{{hole.name}} banner" src="{{banner}}" style="max-height:300px;max-width:100%">
<button class="btn btn-danger sub-banner-delete-button mt-2" id="sub-banner-delete-{{loop.index}}" data-nonce="{{g.nonce}}" data-onclick="areyousure(this)" data-areyousure="postToastReload(this, '/h/{{sub.name}}/settings/banners/delete/{{loop.index - 1}}')">Delete</button> <button class="btn btn-danger hole-banner-delete-button mt-2" id="hole-banner-delete-{{loop.index}}" data-nonce="{{g.nonce}}" data-onclick="areyousure(this)" data-areyousure="postToastReload(this, '/h/{{hole.name}}/settings/banners/delete/{{loop.index - 1}}')">Delete</button>
</section> </section>
{% else %} {% else %}
<section id="sub-banner-no-banners" class="d-block sub-settings-subsection"> <section id="hole-banner-no-banners" class="d-block hole-settings-subsection">
{{macros.ghost_box("No banners uploaded", "", 2, "flex:1")}} {{macros.ghost_box("No banners uploaded", "", 2, "flex:1")}}
</section> </section>
{% endfor %} {% endfor %}
{% if not g.is_tor %} {% if not g.is_tor %}
<section id="sub-banner-upload-new" class="mt-5 sub-settings-subsection"> <section id="hole-banner-upload-new" class="mt-5 hole-settings-subsection">
<form class="d-inline-block" action="/h/{{sub.name}}/settings/banners/" method="post" enctype="multipart/form-data"> <form class="d-inline-block" action="/h/{{hole.name}}/settings/banners/" method="post" enctype="multipart/form-data">
<input hidden name="formkey" value="{{v|formkey}}"> <input hidden name="formkey" value="{{v|formkey}}">
<label class="btn btn-secondary text-capitalize mr-2 mb-0"> <label class="btn btn-secondary text-capitalize mr-2 mb-0">
Upload New Banner<input autocomplete="off" type="file" accept="image/*" hidden name="banner" data-nonce="{{g.nonce}}" onchange_submit> Upload New Banner<input autocomplete="off" type="file" accept="image/*" hidden name="banner" data-nonce="{{g.nonce}}" onchange_submit>
</label> </label>
</form> </form>
<button type="button" class="btn btn-danger sub-banner-delete-button" id="sub-banner-delete-all" data-nonce="{{g.nonce}}" data-onclick="areyousure(this)" data-areyousure="postToastReload(this, '/h/{{sub.name}}/settings/banners/delete_all')">Delete All Banners</button> <button type="button" class="btn btn-danger hole-banner-delete-button" id="hole-banner-delete-all" data-nonce="{{g.nonce}}" data-onclick="areyousure(this)" data-areyousure="postToastReload(this, '/h/{{hole.name}}/settings/banners/delete_all')">Delete All Banners</button>
<div class="text-small text-muted mt-3"> <div class="text-small text-muted mt-3">
All image files are supported. Max file size is {% if v and v.patron %}16{% else %}8{% endif %} MB. All image files are supported. Max file size is {% if v and v.patron %}16{% else %}8{% endif %} MB.
</div> </div>
@ -80,9 +80,9 @@
</div> </div>
<div class="body d-lg-flex"> <div class="body d-lg-flex">
<div class="w-lg-100"> <div class="w-lg-100">
<form id="sidebar" action="/h/{{sub}}/sidebar" method="post" data-nonce="{{g.nonce}}" data-onsubmit="sendFormXHR(this)"> <form id="sidebar" action="/h/{{hole}}/sidebar" method="post" data-nonce="{{g.nonce}}" data-onsubmit="sendFormXHR(this)">
<input hidden name="formkey" value="{{v|formkey}}"> <input hidden name="formkey" value="{{v|formkey}}">
<textarea autocomplete="off" maxlength="10000" class="form-control rounded" id="bio-text" placeholder="Enter sidebar here..." rows="10" name="sidebar" form="sidebar">{% if sub.sidebar %}{{sub.sidebar}}{% endif %}</textarea> <textarea autocomplete="off" maxlength="10000" class="form-control rounded" id="bio-text" placeholder="Enter sidebar here..." rows="10" name="sidebar" form="sidebar">{% if hole.sidebar %}{{hole.sidebar}}{% endif %}</textarea>
<div class="d-flex mt-2"> <div class="d-flex mt-2">
<input autocomplete="off" class="btn btn-primary ml-auto" type="submit" value="Save"> <input autocomplete="off" class="btn btn-primary ml-auto" type="submit" value="Save">
</div> </div>
@ -101,7 +101,7 @@
</div> </div>
<div class="body d-lg-flex"> <div class="body d-lg-flex">
<div class="w-lg-100"> <div class="w-lg-100">
<form id="css" action="/h/{{sub}}/css" method="post" data-nonce="{{g.nonce}}" data-onsubmit="sendFormXHR(this)"> <form id="css" action="/h/{{hole}}/css" method="post" data-nonce="{{g.nonce}}" data-onsubmit="sendFormXHR(this)">
<input hidden name="formkey" value="{{v|formkey}}"> <input hidden name="formkey" value="{{v|formkey}}">
<textarea autocomplete="off" maxlength="6000" class="form-control rounded" id="bio-text" placeholder="Enter css here..." rows="10" name="css" form="css">{% if css %}{{css}}{% endif %}</textarea> <textarea autocomplete="off" maxlength="6000" class="form-control rounded" id="bio-text" placeholder="Enter css here..." rows="10" name="css" form="css">{% if css %}{{css}}{% endif %}</textarea>
<div class="d-flex mt-2"> <div class="d-flex mt-2">

View File

@ -1,7 +1,7 @@
{% extends "default.html" %} {% extends "default.html" %}
{% block title %} {% block title %}
{% if sub %} {% if hole %}
<title>/h/{{sub.name}}</title> <title>/h/{{hole.name}}</title>
{% elif request.path == '/' %} {% elif request.path == '/' %}
{% if IS_DKD() %} {% if IS_DKD() %}
<title>Kongrama</title> <title>Kongrama</title>
@ -12,13 +12,13 @@
{{super()}} {{super()}}
{% endif %} {% endif %}
{% endblock %} {% endblock %}
{% block pagetitle %}{{SITE_NAME if not sub else '/h/' ~ sub.name}}{% endblock %} {% block pagetitle %}{{SITE_NAME if not hole else '/h/' ~ hole.name}}{% endblock %}
{% block head_final %} {% block head_final %}
{% set preview = sub.siderbarurl if sub and sub.sidebarurl else sub.bannerurl %} {% set preview = hole.siderbarurl if hole and hole.sidebarurl else hole.bannerurl %}
{% if sub %} {% if hole %}
<meta property="og:type" content="article"> <meta property="og:type" content="article">
<meta property="og:title" content="/h/{{sub}}"> <meta property="og:title" content="/h/{{hole}}">
<meta property="og:site_name" content="{{SITE}}"> <meta property="og:site_name" content="{{SITE}}">
<meta property="og:image" content="{{preview}}"> <meta property="og:image" content="{{preview}}">
<meta property="og:url" content="{{request.full_path}}"> <meta property="og:url" content="{{request.full_path}}">
@ -26,20 +26,20 @@
<meta name="twitter:card" content="summary_large_image"> <meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="{{SITE_FULL}}"> <meta name="twitter:site" content="{{SITE_FULL}}">
<meta name="twitter:title" content="/h/{{sub.name}}"> <meta name="twitter:title" content="/h/{{hole.name}}">
<meta name="twitter:creator" content="{{SITE_FULL}}"> <meta name="twitter:creator" content="{{SITE_FULL}}">
<meta name="twitter:image" content="{{preview}}"> <meta name="twitter:image" content="{{preview}}">
<meta name="twitter:url" content="{{request.full_path}}"> <meta name="twitter:url" content="{{request.full_path}}">
{% endif %} {% endif %}
{% if sub.sidebar %} {% if hole.sidebar %}
<meta property="og:description" name="description" content="{{sub.sidebar}}"> <meta property="og:description" name="description" content="{{hole.sidebar}}">
<meta name="twitter:description" content="{{sub.sidebar}}"> <meta name="twitter:description" content="{{hole.sidebar}}">
{% endif %} {% endif %}
{% endblock %} {% endblock %}
{% block desktopBanner %} {% block desktopBanner %}
{%- set search_placeholder = "Search" -%} {%- set search_placeholder = "Search" -%}
{%- if sub -%} {%- if hole -%}
{%- set search_placeholder = "Search (try '" ~ HOLE_NAME ~ ":" ~ sub.name ~ "')" -%} {%- set search_placeholder = "Search (try '" ~ HOLE_NAME ~ ":" ~ hole.name ~ "')" -%}
{%- endif -%} {%- endif -%}
<div class="row" style="overflow: visible;padding-top:5px"> <div class="row" style="overflow: visible;padding-top:5px">
<div class="col"> <div class="col">
@ -52,23 +52,23 @@
</span> </span>
</form> </form>
<a class="btn btn-primary btn-block mt-3" href="{% if sub %}/h/{{sub}}{% endif %}/submit"><i class="fas fa-feather-alt mr-2"></i>Create Post {% if sub %}in /h/{{sub}}{% endif %}</a> <a class="btn btn-primary btn-block mt-3" href="{% if hole %}/h/{{hole}}{% endif %}/submit"><i class="fas fa-feather-alt mr-2"></i>Create Post {% if hole %}in /h/{{hole}}{% endif %}</a>
{% if sub %} {% if hole %}
{% if v %} {% if v %}
{% if sub.stealth %} {% if hole.stealth %}
<button type="button" id="unsubscribe-sub" class="btn btn-primary btn-block {% if not v.subscribes(sub.name) %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{sub.name}}/unsubscribe','subscribe-sub','unsubscribe-sub','d-none')"><i class="fas fa-eye-slash mr-2"></i>Block /h/{{sub.name}}</button> <button type="button" id="unsubscribe-sub" class="btn btn-primary btn-block {% if not v.subscribes(hole.name) %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{hole.name}}/unsubscribe','subscribe-sub','unsubscribe-sub','d-none')"><i class="fas fa-eye-slash mr-2"></i>Block /h/{{hole.name}}</button>
<button type="button" id="subscribe-sub" class="btn btn-primary btn-block {% if v.subscribes(sub.name) %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{sub.name}}/subscribe','subscribe-sub','unsubscribe-sub','d-none')"><i class="fas fa-eye mr-2"></i>Unblock /h/{{sub.name}}</button> <button type="button" id="subscribe-sub" class="btn btn-primary btn-block {% if v.subscribes(hole.name) %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{hole.name}}/subscribe','subscribe-sub','unsubscribe-sub','d-none')"><i class="fas fa-eye mr-2"></i>Unblock /h/{{hole.name}}</button>
{% else %} {% else %}
<button type="button" id="block-sub" class="btn btn-primary btn-block mt-3 {% if v.blocks(sub.name) %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{sub.name}}/block','block-sub','unblock-sub','d-none')"><i class="fas fa-eye-slash mr-2"></i>Block /h/{{sub.name}}</button> <button type="button" id="block-sub" class="btn btn-primary btn-block mt-3 {% if v.blocks(hole.name) %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{hole.name}}/block','block-sub','unblock-sub','d-none')"><i class="fas fa-eye-slash mr-2"></i>Block /h/{{hole.name}}</button>
<button type="button" id="unblock-sub" class="btn btn-primary btn-block mt-3 {% if not v.blocks(sub.name) %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{sub.name}}/unblock','block-sub','unblock-sub','d-none')"><i class="fas fa-eye mr-2"></i>Unblock /h/{{sub.name}}</button> <button type="button" id="unblock-sub" class="btn btn-primary btn-block mt-3 {% if not v.blocks(hole.name) %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{hole.name}}/unblock','block-sub','unblock-sub','d-none')"><i class="fas fa-eye mr-2"></i>Unblock /h/{{hole.name}}</button>
{% endif %} {% endif %}
<button type="button" id="follow-sub" class="btn btn-primary btn-follow {% if v.follows(sub.name) %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{sub.name}}/follow','follow-sub','unfollow-sub','d-none')"><i class="fas fa-bell mr-2"></i>Follow /h/{{sub.name}}</button> <button type="button" id="follow-sub" class="btn btn-primary btn-follow {% if v.follows(hole.name) %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{hole.name}}/follow','follow-sub','unfollow-sub','d-none')"><i class="fas fa-bell mr-2"></i>Follow /h/{{hole.name}}</button>
<button type="button" id="unfollow-sub" class="btn btn-primary btn-follow {% if not v.follows(sub.name) %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{sub.name}}/unfollow','follow-sub','unfollow-sub','d-none')"><i class="fas fa-bell-slash mr-2"></i>Unfollow /h/{{sub.name}}</button> <button type="button" id="unfollow-sub" class="btn btn-primary btn-follow {% if not v.follows(hole.name) %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{hole.name}}/unfollow','follow-sub','unfollow-sub','d-none')"><i class="fas fa-bell-slash mr-2"></i>Unfollow /h/{{hole.name}}</button>
{% else %} {% else %}
<a class="btn btn-primary btn-block" href="/login?redirect={{request.full_path | urlencode}}"><i class="fas fa-eye-slash mr-2"></i>Block /h/{{sub.name}}</a> <a class="btn btn-primary btn-block" href="/login?redirect={{request.full_path | urlencode}}"><i class="fas fa-eye-slash mr-2"></i>Block /h/{{hole.name}}</a>
<a class="btn btn-primary btn-block" href="/login?redirect={{request.full_path | urlencode}}"><i class="fas fa-bell mr-2"></i>Follow /h/{{sub.name}}</a> <a class="btn btn-primary btn-block" href="/login?redirect={{request.full_path | urlencode}}"><i class="fas fa-bell mr-2"></i>Follow /h/{{hole.name}}</a>
{% endif %} {% endif %}
{% endif %} {% endif %}
@ -77,7 +77,7 @@
{% block navbar %} {% block navbar %}
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
{% set pcolor = "primary" if pins else "secondary" %} {% set pcolor = "primary" if pins else "secondary" %}
<form action="/toggle_pins/{{sub}}/{{sort}}" method="post" data-nonce="{{g.nonce}}" data-onsubmit="sendFormXHRReload(this)"> <form action="/toggle_pins/{{hole}}/{{sort}}" method="post" data-nonce="{{g.nonce}}" data-onsubmit="sendFormXHRReload(this)">
<button type="submit" class="btn btn-{{pcolor}} text-{{pcolor}} mx-2"><i type="submit" class="fas fas fa-thumbtack fa-rotate--45 mr-2"></i>Pins</button> <button type="submit" class="btn btn-{{pcolor}} text-{{pcolor}} mx-2"><i type="submit" class="fas fas fa-thumbtack fa-rotate--45 mr-2"></i>Pins</button>
</form> </form>

View File

@ -5,7 +5,7 @@
<div class="col h-100"> <div class="col h-100">
<div class="justify-content-between"> <div class="justify-content-between">
<div> <div>
<h5 class="font-weight-bolder text-center pt-2 pb-3">{% if sub %}<a href="/h/{{sub.name}}">/h/{{sub.name}}</a> {% endif %}<span>Moderation Log</span></h5> <h5 class="font-weight-bolder text-center pt-2 pb-3">{% if hole %}<a href="/h/{{hole.name}}">/h/{{hole.name}}</a> {% endif %}<span>Moderation Log</span></h5>
</div> </div>
</div> </div>
@ -22,9 +22,9 @@
</button> </button>
<div class="dropdown-menu" x-placement="bottom-start" style="position: absolute; will-change: transform; top: 0px; left: 0px; transform: translate3d(0px, 31px, 0px); max-height: 50vh; <div class="dropdown-menu" x-placement="bottom-start" style="position: absolute; will-change: transform; top: 0px; left: 0px; transform: translate3d(0px, 31px, 0px); max-height: 50vh;
overflow: auto"> overflow: auto">
<a class="dropdown-item" href="{% if sub %}/h/{{sub}}{% endif %}/log{% if type %}?kind={{type}}{% endif %}"><img loading="lazy" src="{{SITE_FULL_IMAGES}}/e/marseyjanny.webp" alt="avatar" class="profile-pic-20 mr-2">All</a> <a class="dropdown-item" href="{% if hole %}/h/{{hole}}{% endif %}/log{% if type %}?kind={{type}}{% endif %}"><img loading="lazy" src="{{SITE_FULL_IMAGES}}/e/marseyjanny.webp" alt="avatar" class="profile-pic-20 mr-2">All</a>
{% for a in admins %} {% for a in admins %}
<a class="dropdown-item" href="{% if sub %}/h/{{sub}}{% endif %}/log?{{single_user_url}}={{a}}{% if type %}&kind={{type}}{% endif %}"><img loading="lazy" src="/@{{a}}/pic" alt="avatar" class="profile-pic-20 mr-2">{{a}}</a> <a class="dropdown-item" href="{% if hole %}/h/{{hole}}{% endif %}/log?{{single_user_url}}={{a}}{% if type %}&kind={{type}}{% endif %}"><img loading="lazy" src="/@{{a}}/pic" alt="avatar" class="profile-pic-20 mr-2">{{a}}</a>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
@ -35,9 +35,9 @@
</button> </button>
<div class="dropdown-menu" x-placement="bottom-start" style="position: absolute; will-change: transform; top: 0px; left: 0px; transform: translate3d(0px, 31px, 0px); max-height: 50vh; <div class="dropdown-menu" x-placement="bottom-start" style="position: absolute; will-change: transform; top: 0px; left: 0px; transform: translate3d(0px, 31px, 0px); max-height: 50vh;
overflow: auto"> overflow: auto">
<a class="dropdown-item" href="{% if sub %}/h/{{sub}}{% endif %}/log{% if admin %}?{{single_user_url}}={{admin}}{% endif %}"><i class="fas fa-broom mr-2"></i>All</a> <a class="dropdown-item" href="{% if hole %}/h/{{hole}}{% endif %}/log{% if admin %}?{{single_user_url}}={{admin}}{% endif %}"><i class="fas fa-broom mr-2"></i>All</a>
{% for t, v in types.items() %} {% for t, v in types.items() %}
<a class="dropdown-item" href="{% if sub %}/h/{{sub}}{% endif %}/log?{% if admin %}{{single_user_url}}={{admin}}&{% endif %}kind={{t}}"><i class="fas {{v['icon']}} mr-2"></i>{{t}}</a> <a class="dropdown-item" href="{% if hole %}/h/{{hole}}{% endif %}/log?{% if admin %}{{single_user_url}}={{admin}}&{% endif %}kind={{t}}"><i class="fas {{v['icon']}} mr-2"></i>{{t}}</a>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>

View File

@ -25,7 +25,7 @@
Posts {% if v.post_notifications_count %}<span class="font-weight-bold" style="color:#0000ff">({{v.post_notifications_count}})</span>{% endif %} Posts {% if v.post_notifications_count %}<span class="font-weight-bold" style="color:#0000ff">({{v.post_notifications_count}})</span>{% endif %}
</a> </a>
</li> </li>
{% if v.admin_level >= PERMS['NOTIFICATIONS_MODERATOR_ACTIONS'] or v.moderated_subs %} {% if v.admin_level >= PERMS['NOTIFICATIONS_MODERATOR_ACTIONS'] or v.moderated_holes %}
<li class="nav-item"> <li class="nav-item">
<a class="nav-link py-3{% if request.path == '/notifications/modactions' %} active{% endif %}" href="/notifications/modactions"> <a class="nav-link py-3{% if request.path == '/notifications/modactions' %} active{% endif %}" href="/notifications/modactions">
Modactions {% if v.modaction_notifications_count %}<span class="font-weight-bold" style="color:#1ad80d">({{v.modaction_notifications_count}})</span>{% endif %} Modactions {% if v.modaction_notifications_count %}<span class="font-weight-bold" style="color:#1ad80d">({{v.modaction_notifications_count}})</span>{% endif %}
@ -83,8 +83,8 @@
</span> </span>
<div class="text-muted pl-3"> <div class="text-muted pl-3">
<div> <div>
{% if ma.sub %} {% if ma.hole %}
<a href="/h/{{ma.sub}}">/h/{{ma.sub}}</a> <a href="/h/{{ma.hole}}">/h/{{ma.hole}}</a>
- -
{% endif %} {% endif %}
<a href="{{ma.user.url}}" class="font-weight-bold text-black" target="_self">@{{ma.user.username}}</a> <a href="{{ma.user.url}}" class="font-weight-bold text-black" target="_self">@{{ma.user.username}}</a>

View File

@ -51,9 +51,9 @@
<button type="button" id="pin-{{p.id}}" class="dropdown-item {% if p.stickied and not p.stickied_utc %}d-none{% endif %} list-inline-item text-info" data-nonce="{{g.nonce}}" data-onclick="pinPost(this, '{{p.id}}')"><i class="fas fa-thumbtack fa-rotate--45"></i>Pin {% if p.stickied_utc %}permanently{% else %}for 1 hour{% endif %}</button> <button type="button" id="pin-{{p.id}}" class="dropdown-item {% if p.stickied and not p.stickied_utc %}d-none{% endif %} list-inline-item text-info" data-nonce="{{g.nonce}}" data-onclick="pinPost(this, '{{p.id}}')"><i class="fas fa-thumbtack fa-rotate--45"></i>Pin {% if p.stickied_utc %}permanently{% else %}for 1 hour{% endif %}</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> <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.sub and v.mods(p.sub) %} {% if p.hole and v.mods(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.sub}}</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.sub}}</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 %}
{% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %} {% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}
<button type="button" id="remove-{{p.id}}" class="dropdown-item {% if p.is_banned %}d-none{% endif %} list-inline-item text-danger" data-nonce="{{g.nonce}}" data-onclick="removePost(this,'{{p.id}}','remove-{{p.id}}','approve-{{p.id}}','d-none')"><i class="fas fa-ban"></i>Remove</button> <button type="button" id="remove-{{p.id}}" class="dropdown-item {% if p.is_banned %}d-none{% endif %} list-inline-item text-danger" data-nonce="{{g.nonce}}" data-onclick="removePost(this,'{{p.id}}','remove-{{p.id}}','approve-{{p.id}}','d-none')"><i class="fas fa-ban"></i>Remove</button>
@ -63,18 +63,18 @@
<button type="button" id="block-{{p.id}}" class="dropdown-item list-inline-item text-danger {% if p.is_blocking %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/block_user?username={{p.author_name}}','block-{{p.id}}','unblock-{{p.id}}','d-none')"><i class="fas fa-eye-slash text-danger"></i>Block user</button> <button type="button" id="block-{{p.id}}" class="dropdown-item list-inline-item text-danger {% if p.is_blocking %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/block_user?username={{p.author_name}}','block-{{p.id}}','unblock-{{p.id}}','d-none')"><i class="fas fa-eye-slash text-danger"></i>Block 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> <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 v.id != p.author_id and p.sub %} {% if v.id != p.author_id and p.hole %}
<button type="button" id="block-sub-{{p.id}}" class="dropdown-item list-inline-item text-danger {% if v.blocks(p.sub) %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{p.sub}}/block','block-sub-{{p.id}}','unblock-sub-{{p.id}}','d-none')"><i class="fas fa-eye-slash text-danger"></i>Block /h/{{p.sub}}</button> <button type="button" id="block-hole-{{p.id}}" class="dropdown-item list-inline-item text-danger {% if v.blocks(p.hole) %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{p.hole}}/block','block-hole-{{p.id}}','unblock-hole-{{p.id}}','d-none')"><i class="fas fa-eye-slash text-danger"></i>Block /h/{{p.hole}}</button>
<button type="button" id="unblock-sub-{{p.id}}" class="dropdown-item text-success list-inline-item {% if not v.blocks(p.sub) %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{p.sub}}/unblock','block-sub-{{p.id}}','unblock-sub-{{p.id}}','d-none')"><i class="fas fa-eye text-success"></i>Unblock /h/{{p.sub}}</button> <button type="button" id="unblock-hole-{{p.id}}" class="dropdown-item text-success list-inline-item {% if not v.blocks(p.hole) %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{p.hole}}/unblock','block-hole-{{p.id}}','unblock-hole-{{p.id}}','d-none')"><i class="fas fa-eye text-success"></i>Unblock /h/{{p.hole}}</button>
{% endif %} {% endif %}
{% if p.sub and v.mods(p.sub) %} {% if p.hole and v.mods(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(p.sub) %} {% if not p.author.mods(p.hole) %}
<button type="button" id="exile-{{p.id}}" class="{% if p.author.exiler_username(p.sub) %}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>
<button type="button" id="unexile-{{p.id}}" class="{% if not p.author.exiler_username(p.sub) %}d-none{% endif %} dropdown-item list-inline-item text-success" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{sub}}/unexile/{{p.author_id}}','exile-{{p.id}}','unexile-{{p.id}}','d-none')"><i class="fas fa-campfire text-success"></i>Unexile user</button> <button type="button" id="unexile-{{p.id}}" class="{% if not p.author.exiler_username(p.hole) %}d-none{% endif %} dropdown-item list-inline-item text-success" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{hole}}/unexile/{{p.author_id}}','exile-{{p.id}}','unexile-{{p.id}}','d-none')"><i class="fas fa-campfire text-success"></i>Unexile user</button>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if FEATURES['NSFW_MARKING'] and (v.id==p.author_id or v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or (p.sub and v.mods(p.sub))) %} {% if FEATURES['NSFW_MARKING'] and (v.id==p.author_id or v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or (p.hole and v.mods(p.hole))) %}
<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>
{% endif %} {% endif %}

View File

@ -31,9 +31,9 @@
<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.sub and v.mods(p.sub) %} {% if p.hole and v.mods(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.sub}}</button> <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.sub}}</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 %} {% endif %}
{% if v.id==p.author_id %} {% if v.id==p.author_id %}
@ -44,22 +44,22 @@
<button type="button" id="block2-{{p.id}}" class="blockuser nobackground btn btn-link btn-block btn-lg text-danger text-left" data-areyousure="postToastSwitch(this,'/block_user?username={{p.author_name}}','block2-{{p.id}}','unblock2-{{p.id}}','d-none')" data-nonce="{{g.nonce}}" data-onclick="areyousure(this)" data-dismiss="modal"><i class="fas fa-eye-slash mr-2 text-danger"></i>Block user</button> <button type="button" id="block2-{{p.id}}" class="blockuser nobackground btn btn-link btn-block btn-lg text-danger text-left" data-areyousure="postToastSwitch(this,'/block_user?username={{p.author_name}}','block2-{{p.id}}','unblock2-{{p.id}}','d-none')" data-nonce="{{g.nonce}}" data-onclick="areyousure(this)" data-dismiss="modal"><i class="fas fa-eye-slash mr-2 text-danger"></i>Block user</button>
<button type="button" id="unblock2-{{p.id}}" class="nobackground btn btn-link btn-block btn-lg text-success text-left {% if not p.is_blocking %}d-none{% endif %}" data-bs-dismiss="modal" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/unblock_user?username={{p.author_name}}','block2-{{p.id}}','unblock2-{{p.id}}','d-none')"><i class="fas fa-eye mr-2 text-success"></i>Unblock user</button> <button type="button" id="unblock2-{{p.id}}" class="nobackground btn btn-link btn-block btn-lg text-success text-left {% if not p.is_blocking %}d-none{% endif %}" data-bs-dismiss="modal" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/unblock_user?username={{p.author_name}}','block2-{{p.id}}','unblock2-{{p.id}}','d-none')"><i class="fas fa-eye mr-2 text-success"></i>Unblock user</button>
{% endif %} {% endif %}
{% if p.sub %} {% if p.hole %}
<button type="button" id="block-sub2-{{p.id}}" class="nobackground btn btn-link btn-block btn-lg text-danger text-left {% if v.blocks(p.sub) %}d-none{% endif %}" data-bs-dismiss="modal" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{p.sub}}/block','block-sub2-{{p.id}}','unblock-sub2-{{p.id}}','d-none')"><i class="fas fa-eye mr-2 text-danger"></i>Block /h/{{p.sub}}</button> <button type="button" id="block-sub2-{{p.id}}" class="nobackground btn btn-link btn-block btn-lg text-danger text-left {% if v.blocks(p.hole) %}d-none{% endif %}" data-bs-dismiss="modal" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{p.hole}}/block','block-sub2-{{p.id}}','unblock-sub2-{{p.id}}','d-none')"><i class="fas fa-eye mr-2 text-danger"></i>Block /h/{{p.hole}}</button>
<button type="button" id="unblock-sub2-{{p.id}}" class="nobackground btn btn-link btn-block btn-lg text-success text-left {% if not v.blocks(p.sub) %}d-none{% endif %}" data-bs-dismiss="modal" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{p.sub}}/unblock','block-sub2-{{p.id}}','unblock-sub2-{{p.id}}','d-none')"><i class="fas fa-eye mr-2 text-success"></i>Unblock /h/{{p.sub}}</button> <button type="button" id="unblock-sub2-{{p.id}}" class="nobackground btn btn-link btn-block btn-lg text-success text-left {% if not v.blocks(p.hole) %}d-none{% endif %}" data-bs-dismiss="modal" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{p.hole}}/unblock','block-sub2-{{p.id}}','unblock-sub2-{{p.id}}','d-none')"><i class="fas fa-eye mr-2 text-success"></i>Unblock /h/{{p.hole}}</button>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if FEATURES['NSFW_MARKING'] and (v.id==p.author_id or (p.sub and v.mods(p.sub))) %} {% if FEATURES['NSFW_MARKING'] and (v.id==p.author_id or (p.hole and v.mods(p.hole))) %}
<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>
{% endif %} {% endif %}
{% if p.sub and v.mods(p.sub) %} {% if p.hole and v.mods(p.hole) %}
<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(p.sub) %} {% if not p.author.mods(p.hole) %}
<button type="button" data-bs-dismiss="modal" id="exile2" class="{% if p.author.exiler_username(p.sub) %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-danger" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/exile/post/{{p.id}}','exile2','unexile2','d-none')"><i class="fas fa-campfire mr-2 text-danger"></i>Exile user</button> <button type="button" data-bs-dismiss="modal" id="exile2" class="{% if p.author.exiler_username(p.hole) %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-danger" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/exile/post/{{p.id}}','exile2','unexile2','d-none')"><i class="fas fa-campfire mr-2 text-danger"></i>Exile user</button>
<button type="button" data-bs-dismiss="modal" id="unexile2" class="{% if not p.author.exiler_username(p.sub) %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-success" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{sub}}/unexile/{{p.author_id}}','exile2','unexile2','d-none')"><i class="fas fa-campfire mr-2 text-success"></i>Unexile user</button> <button type="button" data-bs-dismiss="modal" id="unexile2" class="{% if not p.author.exiler_username(p.hole) %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-success" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/h/{{hole}}/unexile/{{p.author_id}}','exile2','unexile2','d-none')"><i class="fas fa-campfire mr-2 text-success"></i>Unexile user</button>
{% endif %} {% endif %}
{% endif %} {% endif %}

View File

@ -96,7 +96,7 @@
{{macros.post_meta(p)}} {{macros.post_meta(p)}}
</div> </div>
<h5 class="card-title post-title text-left w-lg-95 pb-0 pb-md-1"> <h5 class="card-title post-title text-left w-lg-95 pb-0 pb-md-1">
<a id="{{p.id}}-title" {% if v and v.newtab %}data-target="t" target="_blank"{% endif %} href="{{p.permalink}}" class="{% if p.sub %}sub{% endif %} stretched-link {% if p.chudded %}text-uppercase{% endif %}"> <a id="{{p.id}}-title" {% if v and v.newtab %}data-target="t" target="_blank"{% endif %} href="{{p.permalink}}" class="{% if p.hole %}sub{% endif %} stretched-link {% if p.chudded %}text-uppercase{% endif %}">
{% if p.flair %}<span class="patron font-weight-bolder mr-1" style="background-color:var(--primary); font-size:12px; line-height:2">{{p.flair | safe}}</span>{% endif %} {% if p.flair %}<span class="patron font-weight-bolder mr-1" style="background-color:var(--primary); font-size:12px; line-height:2">{{p.flair | safe}}</span>{% endif %}
{{p.realtitle(v) | safe}} {{p.realtitle(v) | safe}}
</a></h5> </a></h5>

View File

@ -6,8 +6,8 @@
</h5> </h5>
</a> </a>
{% if sub %} {% if hole %}
{% set image = sub.sidebar_url %} {% set image = hole.sidebar_url %}
{% elif IS_EVENT() %} {% elif IS_EVENT() %}
{% set image = macros.random_image("assets/events/" ~ IS_EVENT() ~ "/images/sidebar") %} {% set image = macros.random_image("assets/events/" ~ IS_EVENT() ~ "/images/sidebar") %}
{% else %} {% else %}
@ -15,13 +15,13 @@
{% endif %} {% endif %}
{% if request.path != '/sidebar' %} {% if request.path != '/sidebar' %}
{% if not sub and (IS_FISTMAS() or IS_HOMOWEEN()) %} {% if not hole and (IS_FISTMAS() or IS_HOMOWEEN()) %}
{% include "events/shared/eye_tracking.html" %} {% include "events/shared/eye_tracking.html" %}
{% elif v and (v.is_banned or v.chud) %} {% elif v and (v.is_banned or v.chud) %}
<a href="{{SITE_FULL_IMAGES}}/i/{{SITE_NAME}}/sidebar2.webp"> <a href="{{SITE_FULL_IMAGES}}/i/{{SITE_NAME}}/sidebar2.webp">
<img class="mb-4 sidebar-img" alt="sidebar image" data-nonce="{{g.nonce}}" data-onclick="expandImage()" loading="lazy" src="{{SITE_FULL_IMAGES}}/i/{{SITE_NAME}}/sidebar2.webp"> <img class="mb-4 sidebar-img" alt="sidebar image" data-nonce="{{g.nonce}}" data-onclick="expandImage()" loading="lazy" src="{{SITE_FULL_IMAGES}}/i/{{SITE_NAME}}/sidebar2.webp">
</a> </a>
{% elif not (sub and sub.name == 'chudrama' and v and not v.can_see_chudrama) %} {% elif not (hole and hole.name == 'chudrama' and v and not v.can_see_chudrama) %}
<a href="{{image}}"> <a href="{{image}}">
<img class="mb-4 sidebar-img" alt="sidebar image" data-nonce="{{g.nonce}}" data-onclick="expandImage()" loading="lazy" src="{{image}}"> <img class="mb-4 sidebar-img" alt="sidebar image" data-nonce="{{g.nonce}}" data-onclick="expandImage()" loading="lazy" src="{{image}}">
</a> </a>
@ -47,8 +47,8 @@
</div> </div>
{% endif %} {% endif %}
{% if sub and sub.sidebar_html %} {% if hole and hole.sidebar_html %}
<div class="mb-4">{{sub.sidebar_html|safe}}</div> <div class="mb-4">{{hole.sidebar_html|safe}}</div>
{% endif %} {% endif %}
<a class="btn btn-primary btn-block mb-3" href="/post/151246/rdrama-featureset">SITE GUIDE</a> <a class="btn btn-primary btn-block mb-3" href="/post/151246/rdrama-featureset">SITE GUIDE</a>
@ -60,17 +60,17 @@
<a class="btn btn-primary btn-block mb-3" href="/holes">BROWSE {{HOLE_NAME|upper}}S</a> <a class="btn btn-primary btn-block mb-3" href="/holes">BROWSE {{HOLE_NAME|upper}}S</a>
<a class="btn btn-primary btn-block mb-3" href="/create_hole">CREATE {{HOLE_NAME|upper}}</a> <a class="btn btn-primary btn-block mb-3" href="/create_hole">CREATE {{HOLE_NAME|upper}}</a>
{% if sub %} {% if hole %}
<br> <br>
{% if v and v.mods(sub.name) %} {% if v and v.mods(hole.name) %}
<a class="btn btn-primary btn-block mb-3 text-uppercase" style="font-size: 0.87rem" href="/h/{{sub}}/settings">/h/{{sub}} SETTINGS</a> <a class="btn btn-primary btn-block mb-3 text-uppercase" style="font-size: 0.87rem" href="/h/{{hole}}/settings">/h/{{hole}} SETTINGS</a>
{% endif %} {% endif %}
<a class="btn btn-primary btn-block mb-3 text-uppercase" style="font-size: 0.87rem" href="/h/{{sub}}/log">/h/{{sub}} LOG</a> <a class="btn btn-primary btn-block mb-3 text-uppercase" style="font-size: 0.87rem" href="/h/{{hole}}/log">/h/{{hole}} LOG</a>
<a class="btn btn-primary btn-block mb-3 text-uppercase" style="font-size: 0.87rem" href="/h/{{sub}}/mods">/h/{{sub}} MODS</a> <a class="btn btn-primary btn-block mb-3 text-uppercase" style="font-size: 0.87rem" href="/h/{{hole}}/mods">/h/{{hole}} MODS</a>
<a class="btn btn-primary btn-block mb-3 text-uppercase" style="font-size: 0.87rem" href="/h/{{sub}}/exilees">/h/{{sub}} EXILEES</a> <a class="btn btn-primary btn-block mb-3 text-uppercase" style="font-size: 0.87rem" href="/h/{{hole}}/exilees">/h/{{hole}} EXILEES</a>
<a class="btn btn-primary btn-block mb-3 text-uppercase" style="font-size: 0.87rem" href="/h/{{sub}}/followers">/h/{{sub}} FOLLOWERS</a> <a class="btn btn-primary btn-block mb-3 text-uppercase" style="font-size: 0.87rem" href="/h/{{hole}}/followers">/h/{{hole}} FOLLOWERS</a>
<a class="btn btn-primary btn-block mb-3 text-uppercase" style="font-size: 0.87rem" href="/h/{{sub}}/blockers">/h/{{sub}} BLOCKERS</a> <a class="btn btn-primary btn-block mb-3 text-uppercase" style="font-size: 0.87rem" href="/h/{{hole}}/blockers">/h/{{hole}} BLOCKERS</a>
{% else %} {% else %}
<div class="sidebar--rules sidebar--rules--rdrama pt-2"> <div class="sidebar--rules sidebar--rules--rdrama pt-2">
{% set rules = "rules_" ~ SITE_NAME ~ ".html" %} {% set rules = "rules_" ~ SITE_NAME ~ ".html" %}

View File

@ -10,7 +10,7 @@
{% block content %} {% block content %}
{% block form %} {% block form %}
<div class="submit-grid-view"> <div class="submit-grid-view">
<form id="submitform" action="{% if SITE == 'watchpeopledie.tv' %}https://videos.watchpeopledie.tv{% elif sub %}/h/{{sub}}{% endif %}/submit" method="post" enctype="multipart/form-data" style="grid-column: 2" data-nonce="{{g.nonce}}" data-onsubmit="submit(this)"> <form id="submitform" action="{% if SITE == 'watchpeopledie.tv' %}https://videos.watchpeopledie.tv{% elif hole %}/h/{{hole}}{% endif %}/submit" method="post" enctype="multipart/form-data" style="grid-column: 2" data-nonce="{{g.nonce}}" data-onsubmit="submit(this)">
<div class="container pb-0"> <div class="container pb-0">
<div class="row justify-content-center"> <div class="row justify-content-center">
<div class="col px-3 py-0"> <div class="col px-3 py-0">
@ -20,9 +20,9 @@
<label class='mt-4' for="title">{{HOLE_NAME|capitalize}}</label> <label class='mt-4' for="title">{{HOLE_NAME|capitalize}}</label>
<div class="input-group"> <div class="input-group">
{%- set hole_placeholder = 'Required' if HOLE_REQUIRED else 'Optional' -%} {%- set hole_placeholder = 'Required' if HOLE_REQUIRED else 'Optional' -%}
<input list="subs" autocomplete="off" id='sub' class="form-control" form="submitform" name="sub" data-nonce="{{g.nonce}}" data-oninput="savetext()" {% if sub %}value="{{sub}}"{% endif %} placeholder="{{hole_placeholder}}" {% if HOLE_REQUIRED %}required{% endif %}> <input list="holes" autocomplete="off" id="hole" class="form-control" form="submitform" name="hole" data-nonce="{{g.nonce}}" data-oninput="savetext()" {% if hole %}value="{{hole}}"{% endif %} placeholder="{{hole_placeholder}}" {% if HOLE_REQUIRED %}required{% endif %}>
<datalist id="subs"> <datalist id="holes">
{% for s in SUBS %} {% for s in HOLES %}
<option value="{{s}}"></option> <option value="{{s}}"></option>
{% endfor %} {% endfor %}
</datalist> </datalist>

View File

@ -140,10 +140,10 @@
</div> </div>
{% endif %} {% endif %}
{% if u.moderated_subs %} {% if u.moderated_holes %}
<div class="text-white rounded p-2 mb-3" id="profile--holes" style="background-color: rgba(50, 50, 50, 0.6); width: 30%"> <div class="text-white rounded p-2 mb-3" id="profile--holes" style="background-color: rgba(50, 50, 50, 0.6); width: 30%">
<p class="text-uppercase my-0 pb-1" style="font-weight: bold; font-size: 12px">Moderator of</p> <p class="text-uppercase my-0 pb-1" style="font-weight: bold; font-size: 12px">Moderator of</p>
{% for i in u.moderated_subs %} {% for i in u.moderated_holes %}
<span class="d-inline-block mx-1"> <span class="d-inline-block mx-1">
<a href="/h/{{i}}">/h/{{i}}</a> <a href="/h/{{i}}">/h/{{i}}</a>
</span> </span>
@ -437,10 +437,10 @@
</div> </div>
{% endif %} {% endif %}
{% if u.moderated_subs %} {% if u.moderated_holes %}
<div class="text-white rounded p-2 mb-3" id="profile-mobile--holes" style="background-color: rgba(50, 50, 50, 0.6)"> <div class="text-white rounded p-2 mb-3" id="profile-mobile--holes" style="background-color: rgba(50, 50, 50, 0.6)">
<p class="text-uppercase my-0 pb-1" style="font-weight: bold; font-size: 12px">Moderator of</p> <p class="text-uppercase my-0 pb-1" style="font-weight: bold; font-size: 12px">Moderator of</p>
{% for i in u.moderated_subs %} {% for i in u.moderated_holes %}
<span class="d-inline-block mx-1"> <span class="d-inline-block mx-1">
<a href="/h/{{i}}">/h/{{i}}</a> <a href="/h/{{i}}">/h/{{i}}</a>
</span> </span>

View File

@ -57,9 +57,9 @@
- {{u.bio}} - {{u.bio}}
{% endif %} {% endif %}
{% endset %} {% endset %}
{% elif sub %} {% elif hole %}
{% set title, description = {% set title, description =
'/h/'+sub.name, sub.sidebar if sub.sidebar %} '/h/'+hole.name, hole.sidebar if hole.sidebar %}
{% endif %} {% endif %}
<link rel="icon" type="image/webp" href="/icon.webp?x=6"> <link rel="icon" type="image/webp" href="/icon.webp?x=6">
@ -135,8 +135,8 @@
<link rel="stylesheet" href="{{'events/homoween/css/main_homoween.css' | asset}}"> <link rel="stylesheet" href="{{'events/homoween/css/main_homoween.css' | asset}}">
{% endif %} {% endif %}
{% if sub and sub.css and not request.path.endswith('settings') and not request.values.get('nocss') %} {% if hole and hole.css and not request.path.endswith('settings') and not request.values.get('nocss') %}
<link rel="stylesheet" href="/h/{{sub}}/css"> <link rel="stylesheet" href="/h/{{hole}}/css">
{% endif %} {% endif %}
{% if IS_FISTMAS() %} {% if IS_FISTMAS() %}

View File

@ -9,23 +9,23 @@
{%- endmacro -%} {%- endmacro -%}
{% macro post_meta(p) %} {% macro post_meta(p) %}
{% if p.sub %} {% if p.hole %}
{% if not HOLE_STYLE_FLAIR -%} {% if not HOLE_STYLE_FLAIR -%}
<a class="mr-2 font-weight-bold" href='/h/{{p.sub}}'>/h/{{p.sub}}</a> <a class="mr-2 font-weight-bold" href='/h/{{p.hole}}'>/h/{{p.hole}}</a>
{%- else -%} {%- else -%}
<a href='/h/{{p.sub}}' class="sub-flair font-weight-bold">{{p.sub|capitalize}}</a> <a href='/h/{{p.hole}}' class="hole-flair font-weight-bold">{{p.hole|capitalize}}</a>
{%- endif %} {%- endif %}
{% endif %} {% endif %}
{% if p.sub and p.author.exiler_username(p.sub) %} {% if p.hole and p.author.exiler_username(p.hole) %}
<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}} by @{{p.author.exiler_username(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.hole}} by @{{p.author.exiler_username(p.hole)}}"></i></a>
{% endif %} {% endif %}
{% if p.bannedfor and p.sub != 'chudrama' %} {% if p.bannedfor and p.hole != 'chudrama' %}
<i class="fas fa-hammer-crash text-danger" data-bs-toggle="tooltip" data-bs-placement="bottom" title="User was banned for this post {{p.bannedfor}}"></i> <i class="fas fa-hammer-crash text-danger" data-bs-toggle="tooltip" data-bs-placement="bottom" title="User was banned for this post {{p.bannedfor}}"></i>
{% endif %} {% endif %}
{% if p.chuddedfor and p.sub != 'chudrama' %} {% if p.chuddedfor and p.hole != 'chudrama' %}
<i class="fas fa-face-sleeping text-danger" data-bs-toggle="tooltip" data-bs-placement="bottom" title="User was chudded for this post {{p.chuddedfor}}"></i> <i class="fas fa-face-sleeping text-danger" data-bs-toggle="tooltip" data-bs-placement="bottom" title="User was chudded for this post {{p.chuddedfor}}"></i>
{% endif %} {% endif %}
@ -46,7 +46,7 @@
{% endif %} {% endif %}
{% if p.hole_pinned %} {% if p.hole_pinned %}
<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.sub}} 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.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 %}

View File

@ -0,0 +1,19 @@
alter table subs rename to holes;
alter table subactions rename to hole_actions;
alter table hole_actions rename column sub to hole;
alter table sub_joins rename to stealth_hole_unblocks;
alter table stealth_hole_unblocks rename column sub to hole;
alter table sub_blocks rename to hole_blocks;
alter table hole_blocks rename column sub to hole;
alter table sub_subscriptions rename to hole_follows;
alter table hole_follows rename column sub to hole;
alter table mods rename column sub to hole;
alter table posts rename column sub to hole;
alter table exiles rename column sub to hole;