Merge remote-tracking branch 'origin/frost' into pr_pmreply
This commit is contained in:
commit
6b8c314087
25 changed files with 107 additions and 214 deletions
|
@ -55,7 +55,7 @@ class ModAction(CreatedDateTimeBase):
|
|||
@property
|
||||
@lazy
|
||||
def string(self):
|
||||
output = self.lookup_action_type()["str"].format(self=self, cc=CC_TITLE)
|
||||
output = self.lookup_action_type()["str"].format(self=self)
|
||||
if not self.note: return output
|
||||
output += f" <i>({self.note})</i>"
|
||||
return output
|
||||
|
@ -65,7 +65,6 @@ class ModAction(CreatedDateTimeBase):
|
|||
def target_link(self):
|
||||
if self.target_user: return f'<a href="{self.target_user.url}">{self.target_user.username}</a>'
|
||||
elif self.target_post:
|
||||
if self.target_post.club: return f'<a href="{self.target_post.permalink}">{CC} ONLY</a>'
|
||||
return f'<a href="{self.target_post.permalink}">{self.target_post.title_html}</a>'
|
||||
elif self.target_comment_id: return f'<a href="/comment/{self.target_comment_id}?context=8#context">comment</a>'
|
||||
|
||||
|
@ -140,16 +139,6 @@ ACTIONTYPES = {
|
|||
"icon": 'fa-badge-check',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'club_allow': {
|
||||
"str": 'allowed user {self.target_link} into the {cc}',
|
||||
"icon": 'fa-golf-club',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'club_ban': {
|
||||
"str": 'disallowed user {self.target_link} from the {cc}',
|
||||
"icon": 'fa-golf-club',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'delete_report': {
|
||||
"str": 'deleted report on {self.target_link}',
|
||||
"icon": 'fa-flag',
|
||||
|
|
|
@ -32,7 +32,6 @@ class Submission(CreatedBase):
|
|||
stickied_utc = Column(Integer)
|
||||
is_pinned = Column(Boolean, default=False, nullable=False)
|
||||
private = Column(Boolean, default=False, nullable=False)
|
||||
club = Column(Boolean, default=False, nullable=False)
|
||||
comment_count = Column(Integer, default=0, nullable=False)
|
||||
over_18 = Column(Boolean, default=False, nullable=False)
|
||||
is_bot = Column(Boolean, default=False, nullable=False)
|
||||
|
@ -170,7 +169,6 @@ class Submission(CreatedBase):
|
|||
@lazy
|
||||
def shortlink(self):
|
||||
link = f"/post/{self.id}"
|
||||
if self.club: return link + '/-'
|
||||
|
||||
output = title_regex.sub('', self.title.lower())
|
||||
output = output.split()[:6]
|
||||
|
@ -251,7 +249,6 @@ class Submission(CreatedBase):
|
|||
'distinguish_level': self.distinguish_level,
|
||||
'voted': self.voted if hasattr(self, 'voted') else 0,
|
||||
'flags': flags,
|
||||
'club': self.club,
|
||||
}
|
||||
|
||||
return data
|
||||
|
|
|
@ -22,9 +22,7 @@ from files.classes.userblock import UserBlock
|
|||
from files.classes.visstate import StateMod
|
||||
from files.helpers.assetcache import assetcache_path
|
||||
from files.helpers.config.const import *
|
||||
from files.helpers.config.environment import (CARD_VIEW,
|
||||
CLUB_TRUESCORE_MINIMUM,
|
||||
DEFAULT_COLOR,
|
||||
from files.helpers.config.environment import (CARD_VIEW, DEFAULT_COLOR,
|
||||
DEFAULT_TIME_FILTER, SITE_FULL,
|
||||
SITE_ID)
|
||||
from files.helpers.security import *
|
||||
|
@ -95,7 +93,6 @@ class User(CreatedBase):
|
|||
is_banned = Column(Integer, default=0, nullable=False)
|
||||
unban_utc = Column(Integer, default=0, nullable=False)
|
||||
ban_reason = deferred(Column(String))
|
||||
club_allowed = Column(Boolean)
|
||||
login_nonce = Column(Integer, default=0, nullable=False)
|
||||
reserved = deferred(Column(String))
|
||||
coins = Column(Integer, default=0, nullable=False)
|
||||
|
@ -218,11 +215,6 @@ class User(CreatedBase):
|
|||
def is_blocking(self, target):
|
||||
return g.db.query(UserBlock).filter_by(user_id=self.id, target_id=target.id).one_or_none()
|
||||
|
||||
@property
|
||||
@lazy
|
||||
def paid_dues(self):
|
||||
return not self.shadowbanned and not (self.is_banned and not self.unban_utc) and (self.admin_level or self.club_allowed or (self.club_allowed != False and self.truescore > CLUB_TRUESCORE_MINIMUM))
|
||||
|
||||
@lazy
|
||||
def any_block_exists(self, other):
|
||||
return g.db.query(UserBlock).filter(
|
||||
|
|
|
@ -93,7 +93,6 @@ def seed_db_worker(num_users = 900, num_posts = 40, num_toplevel_comments = 1000
|
|||
user = users[int(len(users) * detrand())]
|
||||
post = Submission(
|
||||
private=False,
|
||||
club=None,
|
||||
author_id=user.id,
|
||||
over_18=False,
|
||||
app_id=None,
|
||||
|
|
|
@ -43,9 +43,6 @@ class Service(IntEnum):
|
|||
def enable_services(self) -> bool:
|
||||
return self not in {self.CRON, self.MIGRATION}
|
||||
|
||||
CC = "COUNTRY CLUB"
|
||||
CC_TITLE = CC.title()
|
||||
|
||||
NOTIFICATIONS_ID = 1
|
||||
AUTOJANNY_ID = 2
|
||||
MODMAIL_ID = 2
|
||||
|
|
|
@ -93,8 +93,6 @@ CARD_VIEW = bool_from_string(environ.get("CARD_VIEW", True))
|
|||
FINGERPRINT_TOKEN = environ.get("FP", None)
|
||||
|
||||
# other stuff from const.py that aren't constants
|
||||
CLUB_TRUESCORE_MINIMUM = int(environ.get("DUES").strip())
|
||||
|
||||
IMGUR_KEY = environ.get("IMGUR_KEY", "").strip()
|
||||
PUSHER_ID = environ.get("PUSHER_ID", "").strip()
|
||||
PUSHER_KEY = environ.get("PUSHER_KEY", "").strip()
|
||||
|
|
|
@ -65,8 +65,6 @@ def inject_constants():
|
|||
"NOTIFICATIONS_ID":NOTIFICATIONS_ID,
|
||||
"MODMAIL_ID":MODMAIL_ID,
|
||||
"PUSHER_ID":PUSHER_ID,
|
||||
"CC":CC,
|
||||
"CC_TITLE":CC_TITLE,
|
||||
"listdir":listdir,
|
||||
"config":app.config.get,
|
||||
"ENABLE_DOWNVOTES": ENABLE_DOWNVOTES,
|
||||
|
|
|
@ -23,7 +23,7 @@ USERPAGELISTING_TIMEOUT_SECS: Final[int] = 86400
|
|||
CHANGELOGLIST_TIMEOUT_SECS: Final[int] = 86400
|
||||
|
||||
@cache.memoize(timeout=FRONTLIST_TIMEOUT_SECS)
|
||||
def frontlist(v=None, sort='new', page=1, t="all", ids_only=True, ccmode="false", filter_words='', gt=0, lt=0):
|
||||
def frontlist(v=None, sort='new', page=1, t="all", ids_only=True, filter_words='', gt=0, lt=0):
|
||||
posts = g.db.query(Submission)
|
||||
|
||||
if v and v.hidevotedon:
|
||||
|
@ -42,14 +42,8 @@ def frontlist(v=None, sort='new', page=1, t="all", ids_only=True, ccmode="false"
|
|||
if not gt and not lt:
|
||||
posts = apply_time_filter(posts, t, Submission)
|
||||
|
||||
if (ccmode == "true"):
|
||||
posts = posts.filter(Submission.club == True)
|
||||
|
||||
posts = posts.filter_by(private=False, state_user_deleted_utc=None)
|
||||
|
||||
if ccmode == "false" and not gt and not lt:
|
||||
posts = posts.filter_by(stickied=None)
|
||||
|
||||
if v and v.admin_level < 2:
|
||||
posts = posts.filter(Submission.author_id.notin_(v.userblocks))
|
||||
|
||||
|
@ -77,7 +71,7 @@ def frontlist(v=None, sort='new', page=1, t="all", ids_only=True, ccmode="false"
|
|||
|
||||
posts = posts[:size]
|
||||
|
||||
if page == 1 and ccmode == "false" and not gt and not lt:
|
||||
if page == 1 and not gt and not lt:
|
||||
pins = g.db.query(Submission).filter(Submission.stickied != None, Submission.state_mod == StateMod.VISIBLE)
|
||||
if v:
|
||||
if v.admin_level < 2:
|
||||
|
|
|
@ -163,62 +163,6 @@ def revert_actions(v, username):
|
|||
return {"message": "Admin actions reverted!"}
|
||||
|
||||
|
||||
@app.post("/@<username>/club_allow")
|
||||
@limiter.exempt
|
||||
@admin_level_required(2)
|
||||
def club_allow(v, username):
|
||||
u = get_user(username, v=v)
|
||||
|
||||
if not u: abort(404)
|
||||
|
||||
if u.admin_level >= v.admin_level:
|
||||
abort(403, "Can't target users with admin level higher than you")
|
||||
|
||||
u.club_allowed = True
|
||||
g.db.add(u)
|
||||
|
||||
for x in u.alts_unique:
|
||||
x.club_allowed = True
|
||||
g.db.add(x)
|
||||
|
||||
ma = ModAction(
|
||||
kind="club_allow",
|
||||
user_id=v.id,
|
||||
target_user_id=u.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
g.db.commit()
|
||||
return {"message": f"@{username} has been allowed into the {CC_TITLE}!"}
|
||||
|
||||
|
||||
@app.post("/@<username>/club_ban")
|
||||
@limiter.exempt
|
||||
@admin_level_required(2)
|
||||
def club_ban(v, username):
|
||||
u = get_user(username, v=v)
|
||||
|
||||
if not u: abort(404)
|
||||
|
||||
if u.admin_level >= v.admin_level:
|
||||
abort(403, "Can't target users with admin level higher than you")
|
||||
|
||||
u.club_allowed = False
|
||||
|
||||
for x in u.alts_unique:
|
||||
u.club_allowed = False
|
||||
g.db.add(x)
|
||||
|
||||
ma = ModAction(
|
||||
kind="club_ban",
|
||||
user_id=v.id,
|
||||
target_user_id=u.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
g.db.commit()
|
||||
return {"message": f"@{username} has been kicked from the {CC_TITLE}. Deserved."}
|
||||
|
||||
@app.get("/admin/shadowbanned")
|
||||
@limiter.exempt
|
||||
@auth_required
|
||||
|
|
|
@ -23,8 +23,6 @@ def post_pid_comment_cid(cid, pid=None, anything=None, v=None):
|
|||
g.db.add(notif)
|
||||
g.db.commit()
|
||||
|
||||
if comment.post and comment.post.club and not (v and (v.paid_dues or v.id in [comment.author_id, comment.post.author_id])): abort(403)
|
||||
|
||||
if comment.post and comment.post.private and not (v and (v.admin_level >= 2 or v.id == comment.post.author.id)): abort(403)
|
||||
|
||||
if not comment.parent_submission and not (v and (comment.author.id == v.id or comment.sentto == v.id)) and not (v and v.admin_level >= 2) : abort(403)
|
||||
|
|
|
@ -207,7 +207,6 @@ def front_all(v, subdomain=None):
|
|||
|
||||
sort=request.values.get("sort", defaultsorting)
|
||||
t=request.values.get('t', defaulttime)
|
||||
ccmode=request.values.get('ccmode', "false").lower()
|
||||
|
||||
if sort == 'bump': t='all'
|
||||
|
||||
|
@ -221,7 +220,6 @@ def front_all(v, subdomain=None):
|
|||
page=page,
|
||||
t=t,
|
||||
v=v,
|
||||
ccmode=ccmode,
|
||||
filter_words=v.filter_words if v else [],
|
||||
gt=gt,
|
||||
lt=lt,
|
||||
|
@ -247,7 +245,7 @@ def front_all(v, subdomain=None):
|
|||
g.db.commit()
|
||||
|
||||
if request.headers.get("Authorization"): return {"data": [x.json for x in posts], "next_exists": next_exists}
|
||||
return render_template("home.html", v=v, listing=posts, next_exists=next_exists, sort=sort, t=t, page=page, ccmode=ccmode, home=True)
|
||||
return render_template("home.html", v=v, listing=posts, next_exists=next_exists, sort=sort, t=t, page=page, home=True)
|
||||
|
||||
|
||||
@app.get("/changelog")
|
||||
|
|
|
@ -35,21 +35,6 @@ MAX_TITLE_LENGTH = 500
|
|||
MAX_URL_LENGTH = 2048
|
||||
|
||||
|
||||
@app.post("/toggle_club/<pid>")
|
||||
@auth_required
|
||||
def toggle_club(pid, v):
|
||||
post = get_post(pid)
|
||||
if post.author_id != v.id and v.admin_level < 2: abort(403)
|
||||
|
||||
post.club = not post.club
|
||||
g.db.add(post)
|
||||
|
||||
g.db.commit()
|
||||
|
||||
if post.club: return {"message": "Post has been marked as club-only!"}
|
||||
else: return {"message": "Post has been unmarked as club-only!"}
|
||||
|
||||
|
||||
@app.post("/publish/<pid>")
|
||||
@limiter.limit("1/second;30/minute;200/hour;1000/day")
|
||||
@auth_required
|
||||
|
@ -85,8 +70,6 @@ def post_id(pid, anything=None, v=None):
|
|||
else: defaultsortingcomments = "new"
|
||||
sort = request.values.get("sort", defaultsortingcomments)
|
||||
|
||||
if post.club and not (v and (v.paid_dues or v.id == post.author_id)): abort(403)
|
||||
|
||||
limit = app.config['RESULTS_PER_PAGE_COMMENTS']
|
||||
offset = 0
|
||||
|
||||
|
@ -130,8 +113,6 @@ def post_id(pid, anything=None, v=None):
|
|||
@auth_desired
|
||||
def viewmore(v, pid, sort, offset):
|
||||
post = get_post(pid, v=v)
|
||||
if post.club and not (v and (v.paid_dues or v.id == post.author_id)): abort(403)
|
||||
|
||||
offset_prev = int(offset)
|
||||
try: ids = set(int(x) for x in request.values.get("ids").split(','))
|
||||
except: abort(400)
|
||||
|
@ -557,7 +538,6 @@ def submit_post(v):
|
|||
|
||||
_do_antispam_submission_check(v, validated_post)
|
||||
|
||||
club = bool(request.values.get("club",""))
|
||||
is_bot = bool(request.headers.get("Authorization"))
|
||||
|
||||
# Invariant: these values are guarded and obey the length bound
|
||||
|
@ -566,7 +546,6 @@ def submit_post(v):
|
|||
|
||||
post = Submission(
|
||||
private=bool(request.values.get("private","")),
|
||||
club=club,
|
||||
author_id=v.id,
|
||||
over_18=bool(request.values.get("over_18","")),
|
||||
app_id=v.client.application.id if v.client else None,
|
||||
|
|
|
@ -42,8 +42,6 @@ def searchposts(v):
|
|||
|
||||
posts = g.db.query(Submission.id)
|
||||
|
||||
if not (v and v.paid_dues): posts = posts.filter_by(club=False)
|
||||
|
||||
if v and v.admin_level < 2:
|
||||
posts = posts.filter(Submission.state_user_deleted_utc == None, Submission.state_mod == StateMod.VISIBLE, Submission.private == False, Submission.author_id.notin_(v.userblocks))
|
||||
elif not v:
|
||||
|
@ -174,15 +172,8 @@ def searchcomments(v):
|
|||
private = [x[0] for x in g.db.query(Submission.id).filter(Submission.private == True).all()]
|
||||
comments = comments.filter(Comment.state_mod == StateMod.VISIBLE, Comment.state_user_deleted_utc == None, Comment.parent_submission.notin_(private))
|
||||
|
||||
|
||||
if not (v and v.paid_dues):
|
||||
club = [x[0] for x in g.db.query(Submission.id).filter(Submission.club == True).all()]
|
||||
comments = comments.filter(Comment.parent_submission.notin_(club))
|
||||
|
||||
comments = sort_objects(comments, sort, Comment)
|
||||
|
||||
total = comments.count()
|
||||
|
||||
comments = comments.offset(25 * (page - 1)).limit(26).all()
|
||||
|
||||
ids = [x[0] for x in comments]
|
||||
|
|
|
@ -4,7 +4,7 @@ from files.__main__ import app
|
|||
from files.classes.comment import Comment
|
||||
from files.classes.flags import CommentFlag
|
||||
from files.classes.user import User
|
||||
from files.classes.visstate import StateReport
|
||||
from files.classes.visstate import StateReport, StateMod
|
||||
from files.classes.volunteer_janitor import VolunteerJanitorRecord, VolunteerJanitorResult
|
||||
from files.helpers.volunteer_janitor import update_comment_badness
|
||||
from files.routes.volunteer_common import VolunteerDuty
|
||||
|
@ -12,6 +12,7 @@ from flask import g
|
|||
import pprint
|
||||
import random
|
||||
import sqlalchemy
|
||||
from sqlalchemy.orm import aliased
|
||||
|
||||
class VolunteerDutyJanitor(VolunteerDuty):
|
||||
|
||||
|
@ -31,7 +32,7 @@ class VolunteerDutyJanitor(VolunteerDuty):
|
|||
|
||||
def embed_template(self) -> str:
|
||||
return "volunteer_janitor.html"
|
||||
|
||||
|
||||
def comments(self) -> list[Comment]:
|
||||
return g.db.query(Comment).where(Comment.id.in_(self.choices))
|
||||
|
||||
|
@ -42,11 +43,15 @@ def get_duty(u: User) -> Optional[VolunteerDutyJanitor]:
|
|||
|
||||
# these could probably be combined into one query somehow
|
||||
|
||||
# find reported not-deleted comments not made by the current user
|
||||
# find reported visible comments not made by the current user or in reply to the current user
|
||||
ParentComment = aliased(Comment)
|
||||
reported_comments = g.db.query(Comment) \
|
||||
.where(Comment.state_report == StateReport.REPORTED) \
|
||||
.where(Comment.state_mod == StateMod.VISIBLE) \
|
||||
.where(Comment.state_user_deleted_utc == None) \
|
||||
.where(Comment.author_id != u.id) \
|
||||
.outerjoin(ParentComment, ParentComment.id == Comment.parent_comment_id) \
|
||||
.where(sqlalchemy.or_(ParentComment.author_id != u.id, ParentComment.author_id == None)) \
|
||||
.with_entities(Comment.id)
|
||||
|
||||
reported_ids = [reported.id for reported in reported_comments]
|
||||
|
|
|
@ -53,11 +53,6 @@
|
|||
<a id="unpin-{{p.id}}" class="dropdown-item {% if not p.stickied %}d-none{% endif %} list-inline-item text-info" role="button" onclick="postToastSwitch(this,'/unsticky/{{p.id}}','POST','pin-{{p.id}}','unpin-{{p.id}}');"><i class="fas fa-thumbtack fa-rotate--45"></i>Unpin</a>
|
||||
{% endif %}
|
||||
|
||||
{# {% if v.admin_level > 1 or v.id == p.author_id %}
|
||||
<a id="club-{{p.id}}" class="dropdown-item {% if p.club %}d-none{% endif %} list-inline-item text-info" role="button" onclick="postToastSwitch(this,'/toggle_club/{{p.id}}','POST','club-{{p.id}}','unclub-{{p.id}}');"><i class="fas fa-eye-slash"></i>Mark club</a>
|
||||
<a id="unclub-{{p.id}}" class="dropdown-item {% if not p.club %}d-none{% endif %} list-inline-item text-info" role="button" onclick="postToastSwitch(this,'/toggle_club/{{p.id}}','POST','club-{{p.id}}','unclub-{{p.id}}');"><i class="fas fa-eye"></i>Unmark club</a>
|
||||
{% endif %} #}
|
||||
|
||||
{%- if v and v.admin_level >= PERMS['POST_COMMENT_MODERATION'] -%}
|
||||
{%- set show_approve = p.state_mod != StateMod.VISIBLE or "/reported/" in request.path -%}
|
||||
{%- set show_remove = p.state_mod == StateMod.VISIBLE -%}
|
||||
|
|
|
@ -13,10 +13,7 @@
|
|||
<button class="nobackground btn btn-link btn-block btn-lg text-left text-muted" data-bs-dismiss="modal" onclick="togglePostEdit('{{p.id}}')"><i class="far fa-edit text-center text-muted mr-3"></i>Edit</button>
|
||||
{% endif %}
|
||||
|
||||
{# <button id="club2-{{p.id}}" class="{% if p.club %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-info text-left" role="button" onclick="postToastSwitch(this,'/toggle_club/{{p.id}}','POST','club2-{{p.id}}','unclub2-{{p.id}}');" data-bs-dismiss="modal"><i class="fas fa-eye-slash mr-3"></i>Mark club</button>
|
||||
<button id="unclub2-{{p.id}}" class="{% if not p.club %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-info text-left" role="button" onclick="postToastSwitch(this,'/toggle_club/{{p.id}}','POST','club2-{{p.id}}','unclub2-{{p.id}}');" data-bs-dismiss="modal"><i class="fas fa-eye mr-3"></i>Unmark club</button>
|
||||
|
||||
<button id="distinguish2-{{p.id}}" class="{% if p.distinguish_level %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-primary" role="button" onclick="postToastSwitch(this,'/distinguish/{{p.id}}','POST','distinguish2-{{p.id}}','undistinguish2-{{p.id}}');" data-bs-dismiss="modal"><i class="fas fa-crown text-center text-primary mr-3"></i>Distinguish</button>
|
||||
{#<button id="distinguish2-{{p.id}}" class="{% if p.distinguish_level %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-primary" role="button" onclick="postToastSwitch(this,'/distinguish/{{p.id}}','POST','distinguish2-{{p.id}}','undistinguish2-{{p.id}}');" data-bs-dismiss="modal"><i class="fas fa-crown text-center text-primary mr-3"></i>Distinguish</button>
|
||||
<button id="undistinguish2-{{p.id}}" class="{% if not p.distinguish_level %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-primary" role="button" onclick="postToastSwitch(this,'/distinguish/{{p.id}}','POST','distinguish2-{{p.id}}','undistinguish2-{{p.id}}');" data-bs-dismiss="modal"><i class="fas fa-crown text-center text-primary mr-3"></i>Undistinguish</button> #}
|
||||
|
||||
<button id="pin2-{{p.id}}" class="{% if p.stickied %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-primary" role="button" onclick="postToastSwitch(this,'/sticky/{{p.id}}','POST','pin2-{{p.id}}','unpin2-{{p.id}}');" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center text-primary mr-3"></i>Pin</button>
|
||||
|
|
|
@ -31,15 +31,9 @@
|
|||
<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" role="button" onclick="postToastSwitch(this,'/pin/{{p.id}}','POST','pin-profile2-{{p.id}}','unpin-profile2-{{p.id}}');" data-bs-dismiss="modal"><i class="fas fa-thumbtack fa-rotate--45 text-center mr-3"></i>Unpin from profile</button>
|
||||
{% endif %}
|
||||
|
||||
|
||||
<button id="undelete-{{p.id}}" class="{% if not p.state_user_deleted_utc %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-success" role="button" onclick="postToastSwitch(this,'/undelete_post/{{p.id}}','POST','delete-{{p.id}}','undelete-{{p.id}}');document.getElementById('post-{{p.id}}').classList.remove('deleted');" data-bs-dismiss="modal"><i class="far fa-trash-alt text-center mr-3"></i>Undelete</button>
|
||||
|
||||
<button id="delete-{{p.id}}" class="{% if p.state_user_deleted_utc %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-danger" data-bs-toggle="modal" data-bs-dismiss="modal" data-bs-target="#deletePostModal" onclick="delete_postModal('{{p.id}}')"><i class="far fa-trash-alt mr-3"></i>Delete</button>
|
||||
|
||||
|
||||
{# <button id="club3-{{p.id}}" class="{% if p.club %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-danger text-left" role="button" onclick="postToastSwitch(this,'/toggle_club/{{p.id}}','POST','club3-{{p.id}}','unclub3-{{p.id}}');" data-bs-dismiss="modal"><i class="fas fa-eye-slash mr-3"></i>Mark club</button>
|
||||
<button id="unclub3-{{p.id}}" class="{% if not p.club %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-success text-left" role="button" onclick="postToastSwitch(this,'/toggle_club/{{p.id}}','POST','club3-{{p.id}}','unclub3-{{p.id}}');" data-bs-dismiss="modal"><i class="fas fa-eye mr-3"></i>Unmark club</button> #}
|
||||
|
||||
<button id="mark3-{{p.id}}" class="{% if p.over_18 %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-danger" onclick="postToastSwitch(this,'/toggle_post_nsfw/{{p.id}}','POST','mark3-{{p.id}}','unmark3-{{p.id}}');" data-bs-dismiss="modal"><i class="far fa-eye-evil text-center mr-3"></i>Mark +18</button>
|
||||
<button id="unmark3-{{p.id}}" class="{% if not p.over_18 %}d-none{% endif %} nobackground btn btn-link btn-block btn-lg text-left text-success" onclick="postToastSwitch(this,'/toggle_post_nsfw/{{p.id}}','POST','mark3-{{p.id}}','unmark3-{{p.id}}');" data-bs-dismiss="modal"><i class="far fa-eye-evil text-center mr-3"></i>Unmark +18</button>
|
||||
{% else %}
|
||||
|
|
|
@ -54,16 +54,15 @@
|
|||
{{t | capitalize}}
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton" x-placement="bottom-start" style="position: absolute; will-change: transform; top: 0px; left: 0px; transform: translate3d(0px, 31px, 0px);">
|
||||
{% if t != "hour" %}<a class="dropdown-item" href="?sort={{sort}}&t=hour&ccmode={{ccmode}}"><i class="fas fa-clock mr-2 "></i>Hour</a>{% endif %}
|
||||
{% if t != "day" %}<a class="dropdown-item" href="?sort={{sort}}&t=day&ccmode={{ccmode}}"><i class="fas fa-calendar-day mr-2 "></i>Day</a>{% endif %}
|
||||
{% if t != "week" %}<a class="dropdown-item" href="?sort={{sort}}&t=week&ccmode={{ccmode}}"><i class="fas fa-calendar-week mr-2 "></i>Week</a>{% endif %}
|
||||
{% if t != "month" %}<a class="dropdown-item" href="?sort={{sort}}&t=month&ccmode={{ccmode}}"><i class="fas fa-calendar-alt mr-2 "></i>Month</a>{% endif %}
|
||||
{% if t != "year" %}<a class="dropdown-item" href="?sort={{sort}}&t=year&ccmode={{ccmode}}"><i class="fas fa-calendar mr-2 "></i>Year</a>{% endif %}
|
||||
{% if t != "all" %}<a class="dropdown-item" href="?sort={{sort}}&t=all&ccmode={{ccmode}}"><i class="fas fa-infinity mr-2 "></i>All</a>{% endif %}
|
||||
{% if t != "hour" %}<a class="dropdown-item" href="?sort={{sort}}&t=hour"><i class="fas fa-clock mr-2 "></i>Hour</a>{% endif %}
|
||||
{% if t != "day" %}<a class="dropdown-item" href="?sort={{sort}}&t=day"><i class="fas fa-calendar-day mr-2 "></i>Day</a>{% endif %}
|
||||
{% if t != "week" %}<a class="dropdown-item" href="?sort={{sort}}&t=week"><i class="fas fa-calendar-week mr-2 "></i>Week</a>{% endif %}
|
||||
{% if t != "month" %}<a class="dropdown-item" href="?sort={{sort}}&t=month"><i class="fas fa-calendar-alt mr-2 "></i>Month</a>{% endif %}
|
||||
{% if t != "year" %}<a class="dropdown-item" href="?sort={{sort}}&t=year"><i class="fas fa-calendar mr-2 "></i>Year</a>{% endif %}
|
||||
{% if t != "all" %}<a class="dropdown-item" href="?sort={{sort}}&t=all"><i class="fas fa-infinity mr-2 "></i>All</a>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% set ccmode_text = 'ccmode=' ~ ccmode %}
|
||||
{{sorting_time.sort_dropdown(sort, t, SORTS_POSTS, ccmode_text)}}
|
||||
{{sorting_time.sort_dropdown(sort, t, SORTS_POSTS)}}
|
||||
</div>
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
@ -87,14 +86,14 @@
|
|||
<ul class="pagination pagination-sm mb-0">
|
||||
{% if page>1 %}
|
||||
<li class="page-item">
|
||||
<small><a class="page-link" href="?sort={{sort}}&page={{page-1}}&t={{t}}&ccmode={{ccmode}}" tabindex="-1">Prev</a></small>
|
||||
<small><a class="page-link" href="?sort={{sort}}&page={{page-1}}&t={{t}}" tabindex="-1">Prev</a></small>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="page-item disabled"><span class="page-link">Prev</span></li>
|
||||
{% endif %}
|
||||
{% if next_exists %}
|
||||
<li class="page-item">
|
||||
<small><a class="page-link" href="?sort={{sort}}&page={{page+1}}&t={{t}}&ccmode={{ccmode}}">Next</a></small>
|
||||
<small><a class="page-link" href="?sort={{sort}}&page={{page+1}}&t={{t}}">Next</a></small>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="page-item disabled"><span class="page-link">Next</span></li>
|
||||
|
|
|
@ -25,14 +25,16 @@
|
|||
<li><a href="#Clarity">Make your point reasonably clear and plain. Try to assume other people are doing the same.</a></li>
|
||||
<li><a href="#Antagonism">Be no more antagonistic than is absolutely necessary for your argument.</a></li>
|
||||
<li><a href="#Charity">Be charitable.</a></li>
|
||||
<li><a href="#Single">Keep to a single account.</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#Content">Content</a>
|
||||
<ul>
|
||||
<li><a href="#Effort">Avoid low-effort participation</a></li>
|
||||
<li><a href="#Weakman">Do not weakman in order to show how bad a group is</a></li>
|
||||
<li><a href="#Culture">Keep culture war in the culture war thread</a></li>
|
||||
<li><a href="#Leave">Leave the rest of the internet at the door</a></li>
|
||||
<li><a href="#Effort">Avoid low-effort participation.</a></li>
|
||||
<li><a href="#Weakman">Do not weakman in order to show how bad a group is.</a></li>
|
||||
<li><a href="#Culture">Keep culture war in the culture war thread.</a></li>
|
||||
<li><a href="#Leave">Leave the rest of the internet at the door.</a></li>
|
||||
<li><a href="#Multiple">Post on multiple subjects.</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#Engagement">Engagement</a>
|
||||
|
@ -155,6 +157,15 @@
|
|||
what I think".
|
||||
</p>
|
||||
|
||||
<h4 id="Single"><a href="#Single">Keep to a single account.</a></h4>
|
||||
<p>
|
||||
We strongly discourage people from making alt accounts without good reason, and in the absence of a good reason, we consider alt accounts to be bannable on sight. Alt accounts are almost exclusively used for mod evasion purposes and very rarely used for any purpose that helps the community; it makes moderation more difficult and it makes conversation more difficult.
|
||||
<br /><br />
|
||||
If you do feel you need an alt account (most commonly, if you're a well-established user who wants to post something that can't be linked to their public persona), please ask the mods.
|
||||
<br /><br />
|
||||
If you don't want the mods to know about it either, be aware that there's a good chance we'll find out about it anyway.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
|
||||
</pre>
|
||||
|
@ -167,7 +178,7 @@
|
|||
invest effort if they want to post things that have traditionally been pain points.
|
||||
</p>
|
||||
|
||||
<h4 id="Effort"><a href="#Effort">Avoid low-effort participation</a></h4>
|
||||
<h4 id="Effort"><a href="#Effort">Avoid low-effort participation.</a></h4>
|
||||
<p>
|
||||
Discussing things is hard. Discussing things in a useful way, in an environment with opposing views, is really
|
||||
hard. Doing all of this while responding to three-word shitposts is basically impossible.<br/><br/>
|
||||
|
@ -177,7 +188,7 @@
|
|||
in encouraging that.
|
||||
</p>
|
||||
|
||||
<h4 id="Weakman"><a href="#Weakman">Do not weakman in order to show how bad a group is</a></h4>
|
||||
<h4 id="Weakman"><a href="#Weakman">Do not weakman in order to show how bad a group is.</a></h4>
|
||||
<p>
|
||||
There are literally millions of people on either side of every major conflict, and finding that one of them is
|
||||
doing something wrong or thoughtless proves nothing and adds nothing to the conversation. We want to engage with
|
||||
|
@ -203,7 +214,7 @@
|
|||
discussion), a news story which is about tweets from non-prominent people reacting to some event isn't ok.
|
||||
</p>
|
||||
|
||||
<h4 id="Culture"><a href="#Culture">Keep culture war in the culture war thread</a></h4>
|
||||
<h4 id="Culture"><a href="#Culture">Keep culture war in the culture war thread.</a></h4>
|
||||
<p>
|
||||
"Culture war" is hard to define, but here's a list of things that currently fall in that category:
|
||||
<ul>
|
||||
|
@ -241,7 +252,7 @@
|
|||
is inconvenient, but that's intended.
|
||||
</p>
|
||||
|
||||
<h4 id="Leave"><a href="#Leave">Leave the rest of the internet at the door</a></h4>
|
||||
<h4 id="Leave"><a href="#Leave">Leave the rest of the internet at the door.</a></h4>
|
||||
<p>
|
||||
In keeping with the rules above regarding "low-effort" and "weak-man" comments, and our goal to produce more
|
||||
light than heat, we ask that you refrain from posting bare links to culture-war-related discussions held outside
|
||||
|
@ -254,6 +265,17 @@
|
|||
may be made for communities specifically designed for compatible content, but these will be examined by the
|
||||
moderators on a case by case basis. If in doubt, please ask first by messaging the moderators.
|
||||
</p>
|
||||
|
||||
<h4 id="Multiple"><a href="#Multiple">Post on multiple subjects.</a></h4>
|
||||
<p>
|
||||
We occasionally have trouble with people who turn into single-issue posters, posting and commenting only on a single subject. We'd like to discourage this. If you find yourself posting constantly on a single subject, please make an effort to post on other subjects as well.
|
||||
<br/><br/>
|
||||
|
||||
This doesn't mean you need to write megaposts! This can be as simple as going to the Friday Fun Thread once in a while and posting a few paragraphs about whatever video game you last played. But this community is fundamentally for people, and if a poster is acting more like a propaganda-bot than a person, we're going to start looking at them suspiciously.
|
||||
<br/><br/>
|
||||
|
||||
This rule is going to be applied with delicacy; if I can find not-low-effort comments about three different subjects within your last two weeks or two pages of comments, you're likely fine.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
|
||||
|
|
|
@ -61,14 +61,16 @@
|
|||
<li><a href="/rules#Clarity">Make your point reasonably clear and plain. Try to assume other people are doing the same.</a></li>
|
||||
<li><a href="/rules#Antagonism">Be no more antagonistic than is absolutely necessary for your argument.</a></li>
|
||||
<li><a href="/rules#Charity">Be charitable.</a></li>
|
||||
<li><a href="/rules#Single">Keep to a single account.</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="/rules#Content">Content</a>
|
||||
<ul>
|
||||
<li><a href="/rules#Effort">Avoid low-effort participation</a></li>
|
||||
<li><a href="/rules#Weakman">Do not weakman in order to show how bad a group is</a></li>
|
||||
<li><a href="/rules#Culture">Keep culture war in the culture war thread</a></li>
|
||||
<li><a href="/rules#Leave">Leave the rest of the internet at the door</a></li>
|
||||
<li><a href="/rules#Effort">Avoid low-effort participation.</a></li>
|
||||
<li><a href="/rules#Weakman">Do not weakman in order to show how bad a group is.</a></li>
|
||||
<li><a href="/rules#Culture">Keep culture war in the culture war thread.</a></li>
|
||||
<li><a href="/rules#Leave">Leave the rest of the internet at the door.</a></li>
|
||||
<li><a href="/rules#Multiple">Post on multiple subjects.</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="/rules#Engagement">Engagement</a>
|
||||
|
|
|
@ -127,9 +127,6 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% set cc='COUNTRY CLUB' %}
|
||||
|
||||
<div class="row mb-3" style="background-color:var(--gray-600)">
|
||||
<div id="post-root" class="col-12">
|
||||
<div class="card border-0 mt-3{% if p.state_mod == StateMod.REMOVED %} removed{% endif %}{% if p.state_mod == StateMod.FILTERED %} filtered{% endif %}{% if p.stickied %} stickied{% endif %}{% if voted==1 %} upvoted{% elif voted==-1 %} downvoted{% endif %}">
|
||||
|
@ -199,13 +196,11 @@
|
|||
{% endif %}
|
||||
{% if p.realurl(v) %}
|
||||
<h1 id="post-title" class="card-title post-title text-left mb-md-3"><a {% if not v or v.newtabexternal %}target="_blank"{% endif %} rel="nofollow noopener noreferrer" href="{{p.realurl(v)}}">
|
||||
{% if p.club %}<span class="patron font-weight-bolder mr-1" style="background-color:red; font-size:12px; line-height:2;">{{CC}}</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}}
|
||||
</a></h1>
|
||||
{% else %}
|
||||
<h1 id="post-title" class="card-title post-title text-left mb-md-3">
|
||||
{% if p.club %}<span class="patron font-weight-bolder mr-1" style="background-color:red; font-size:12px; line-height:2;">{{CC}}</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}}
|
||||
</h1>
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
{% set cc='COUNTRY CLUB' %}
|
||||
|
||||
{% if not v or v.highlightcomments %}
|
||||
<script src="{{ 'js/new_comments_count.js' | asset }}"></script>
|
||||
{% endif %}
|
||||
|
@ -148,7 +146,6 @@
|
|||
<div class="post-meta text-left mb-md-2">
|
||||
<h5 class="card-title post-title text-left mb-0 pb-0 pb-md-1">
|
||||
<a id="{{p.id}}-title" {% if v and v.newtab and not g.webview %}target="_blank"{% endif %} href="{{p.permalink}}">
|
||||
{% if p.club %}<span class="patron font-weight-bolder mr-1" style="background-color:red; font-size:12px; line-height:2;">{{CC}}</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}}
|
||||
</a></h5>
|
||||
|
@ -305,30 +302,28 @@
|
|||
{% include "component/post/actions_admin_mobile.html" %}
|
||||
{% endif %}
|
||||
|
||||
{% if not p.club or v and (v.paid_dues or v.id == p.author_id) %}
|
||||
{% if p.realbody(v) %}
|
||||
<div class="d-none card rounded border pt-3 pb-2 my-2" id="post-text-{{p.id}}">
|
||||
{{p.realbody(v) | safe}}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if p.realbody(v) %}
|
||||
<div class="d-none card rounded border pt-3 pb-2 my-2" id="post-text-{{p.id}}">
|
||||
{{p.realbody(v) | safe}}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if p.is_image and not p.over_18 and ((v and v.cardview) or (not v and CARD_VIEW)) %}
|
||||
<div style="text-align: center" class="mt-3 mb-4">
|
||||
<a {% if v and v.newtab and not g.webview %}target="_blank"{% endif %} rel="nofollow noopener noreferrer" href="{{p.realurl(v)}}">
|
||||
<img loading="lazy" data-src="{{p.realurl(v)}}" src="/assets/images/loading.webp" class="img-fluid" style="max-height:20rem" alt="Unable to load image">
|
||||
</a>
|
||||
</div>
|
||||
{% elif p.is_video %}
|
||||
<div id="video-{{p.id}}" style="text-align: center" class="{% if p.over_18 or not ((v and v.cardview) or (not v and CARD_VIEW)) %}d-none{% endif %} mt-4">
|
||||
<video id="video2-{{p.id}}" controls preload="none" class="vid">
|
||||
<source src="{{p.realurl(v)}}" type="video/mp4">
|
||||
</video>
|
||||
</div>
|
||||
{% elif p.is_youtube %}
|
||||
<div id="video-{{p.id}}" class="{% if p.over_18 or not ((v and v.cardview) or (not v and CARD_VIEW)) %}d-none{% endif %} mt-3 mb-4 youtube_embed">
|
||||
{{p.embed_url | safe}}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if p.is_image and not p.over_18 and ((v and v.cardview) or (not v and CARD_VIEW)) %}
|
||||
<div style="text-align: center" class="mt-3 mb-4">
|
||||
<a {% if v and v.newtab and not g.webview %}target="_blank"{% endif %} rel="nofollow noopener noreferrer" href="{{p.realurl(v)}}">
|
||||
<img loading="lazy" data-src="{{p.realurl(v)}}" src="/assets/images/loading.webp" class="img-fluid" style="max-height:20rem" alt="Unable to load image">
|
||||
</a>
|
||||
</div>
|
||||
{% elif p.is_video %}
|
||||
<div id="video-{{p.id}}" style="text-align: center" class="{% if p.over_18 or not ((v and v.cardview) or (not v and CARD_VIEW)) %}d-none{% endif %} mt-4">
|
||||
<video id="video2-{{p.id}}" controls preload="none" class="vid">
|
||||
<source src="{{p.realurl(v)}}" type="video/mp4">
|
||||
</video>
|
||||
</div>
|
||||
{% elif p.is_youtube %}
|
||||
<div id="video-{{p.id}}" class="{% if p.over_18 or not ((v and v.cardview) or (not v and CARD_VIEW)) %}d-none{% endif %} mt-3 mb-4 youtube_embed">
|
||||
{{p.embed_url | safe}}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
|
|
@ -246,9 +246,6 @@
|
|||
<input type="hidden" name="user" value="{{u.username}}">
|
||||
<input type="submit" class="btn btn-danger" value="Remove User's Content">
|
||||
</form>
|
||||
<pre></pre>
|
||||
<button id="grant2" class="{% if u.paid_dues %}d-none{% endif %} btn btn-success" onclick="postToastSwitch(this,'/@{{u.username}}/club_allow','POST','grant2','bar2');">Grant club access</button>
|
||||
<button id="bar2" class="{% if u.club_allowed == False %}d-none{% endif %} btn btn-danger" onclick="postToastSwitch(this,'/@{{u.username}}/club_ban','POST','grant2','bar2');">Bar from club</button>
|
||||
{% endif %}
|
||||
{% if v and v.admin_level >= PERMS['USER_SET_PROFILE_PRIVACY'] %}
|
||||
<a id="private-desktop" class="{% if u.is_private %}d-none{% endif %} btn btn-danger" role="button" onclick="postToastSwitch(this,'/id/{{u.id}}/private/1','POST','private-desktop','unprivate-desktop');">Set Private Mode</a>
|
||||
|
@ -425,15 +422,8 @@
|
|||
<div id="message-preview-mobile" class="preview my-3"></div>
|
||||
|
||||
{% if v and v.admin_level >= 2 %}
|
||||
|
||||
<button id="grant" class="{% if u.paid_dues %}d-none{% endif %} btn btn-success" onclick="postToastSwitch(this,'/@{{u.username}}/club_allow','POST','grant','bar');">Grant club access</button>
|
||||
<button id="bar" class="{% if u.club_allowed == False %}d-none{% endif %} btn btn-danger" onclick="postToastSwitch(this,'/@{{u.username}}/club_ban','POST','grant','bar');">Bar from club</button>
|
||||
|
||||
<br><br>
|
||||
<div class="body d-lg-flex border-bottom">
|
||||
|
||||
<div class="w-lg-100">
|
||||
|
||||
<form action="/admin/title_change/{{u.id}}" method="post">
|
||||
{{forms.formkey(v)}}
|
||||
<input maxlength=100 autocomplete="off" id="customtitlebody-mobile" type="text" name="title" class="form-control" placeholder='Enter a flair here' value="{% if u.customtitleplain %}{{u.customtitleplain}}{% endif %}">
|
||||
|
@ -447,7 +437,6 @@
|
|||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<pre></pre>
|
||||
{% if u.is_suspended %}
|
||||
|
|
|
@ -192,7 +192,6 @@ def test_bulk_update_descendant_count_quick(accounts, submissions, comments):
|
|||
for i in range(2):
|
||||
post = Submission(**{
|
||||
'private': False,
|
||||
'club': None,
|
||||
'author_id': alice.id,
|
||||
'over_18': False,
|
||||
'app_id': None,
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
"""excise country club
|
||||
|
||||
Revision ID: d08833c2adc7
|
||||
Revises: 85dad82a4a67
|
||||
Create Date: 2023-08-08 14:36:38.797624+00:00
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'd08833c2adc7'
|
||||
down_revision = '85dad82a4a67'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.drop_column('submissions', 'club')
|
||||
op.drop_column('users', 'club_allowed')
|
||||
|
||||
|
||||
def downgrade():
|
||||
op.add_column('users', sa.Column('club_allowed', sa.BOOLEAN(), autoincrement=False, nullable=True))
|
||||
op.add_column('submissions', sa.Column('club', sa.BOOLEAN(), server_default=sa.text('false'), autoincrement=False, nullable=False))
|
||||
op.add_column('commentvotes', sa.Column('created_utc', sa.INTEGER(), autoincrement=False, nullable=False))
|
Loading…
Add table
Add a link
Reference in a new issue