diff --git a/files/classes/mod_logs.py b/files/classes/mod_logs.py
index f9e23a68b..19aa5f0fb 100644
--- a/files/classes/mod_logs.py
+++ b/files/classes/mod_logs.py
@@ -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" ({self.note})"
return output
@@ -65,7 +65,6 @@ class ModAction(CreatedDateTimeBase):
def target_link(self):
if self.target_user: return f'{self.target_user.username}'
elif self.target_post:
- if self.target_post.club: return f'{CC} ONLY'
return f'{self.target_post.title_html}'
elif self.target_comment_id: return f'comment'
@@ -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',
diff --git a/files/classes/submission.py b/files/classes/submission.py
index 4346cea2e..d406aba4b 100644
--- a/files/classes/submission.py
+++ b/files/classes/submission.py
@@ -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
diff --git a/files/classes/user.py b/files/classes/user.py
index 47f36f169..9bae9fc2e 100644
--- a/files/classes/user.py
+++ b/files/classes/user.py
@@ -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(
diff --git a/files/commands/seed_db.py b/files/commands/seed_db.py
index 23e306047..64c1d6fc8 100644
--- a/files/commands/seed_db.py
+++ b/files/commands/seed_db.py
@@ -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,
diff --git a/files/helpers/config/const.py b/files/helpers/config/const.py
index 16f1de03d..fbf3bf75f 100644
--- a/files/helpers/config/const.py
+++ b/files/helpers/config/const.py
@@ -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
diff --git a/files/helpers/config/environment.py b/files/helpers/config/environment.py
index e152664da..b2150b84e 100644
--- a/files/helpers/config/environment.py
+++ b/files/helpers/config/environment.py
@@ -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()
diff --git a/files/helpers/jinja2.py b/files/helpers/jinja2.py
index a8f999ef2..b6d34c57a 100644
--- a/files/helpers/jinja2.py
+++ b/files/helpers/jinja2.py
@@ -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,
diff --git a/files/helpers/listing.py b/files/helpers/listing.py
index 70a1f7960..c73c9021b 100644
--- a/files/helpers/listing.py
+++ b/files/helpers/listing.py
@@ -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:
diff --git a/files/routes/admin/admin.py b/files/routes/admin/admin.py
index 1dcca6815..ee6636868 100644
--- a/files/routes/admin/admin.py
+++ b/files/routes/admin/admin.py
@@ -163,62 +163,6 @@ def revert_actions(v, username):
return {"message": "Admin actions reverted!"}
-@app.post("/@/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("/@/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
diff --git a/files/routes/comments.py b/files/routes/comments.py
index 83a57ca3a..53c4c8f86 100644
--- a/files/routes/comments.py
+++ b/files/routes/comments.py
@@ -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)
diff --git a/files/routes/front.py b/files/routes/front.py
index 2ce1a5b56..415d998c2 100644
--- a/files/routes/front.py
+++ b/files/routes/front.py
@@ -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")
diff --git a/files/routes/posts.py b/files/routes/posts.py
index f22389de5..76357f092 100644
--- a/files/routes/posts.py
+++ b/files/routes/posts.py
@@ -35,21 +35,6 @@ MAX_TITLE_LENGTH = 500
MAX_URL_LENGTH = 2048
-@app.post("/toggle_club/")
-@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/")
@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,
diff --git a/files/routes/search.py b/files/routes/search.py
index 7830c3865..3732f609c 100644
--- a/files/routes/search.py
+++ b/files/routes/search.py
@@ -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]
diff --git a/files/routes/volunteer_janitor.py b/files/routes/volunteer_janitor.py
index 2c8bf171c..eb3777f9e 100644
--- a/files/routes/volunteer_janitor.py
+++ b/files/routes/volunteer_janitor.py
@@ -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]
diff --git a/files/templates/component/post/actions.html b/files/templates/component/post/actions.html
index 990e8afe8..1a3d58338 100644
--- a/files/templates/component/post/actions.html
+++ b/files/templates/component/post/actions.html
@@ -53,11 +53,6 @@
Unpin
{% endif %}
- {# {% if v.admin_level > 1 or v.id == p.author_id %}
- Mark club
- Unmark club
- {% 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 -%}
diff --git a/files/templates/component/post/actions_admin_mobile.html b/files/templates/component/post/actions_admin_mobile.html
index 2c2376769..9d95d01ed 100644
--- a/files/templates/component/post/actions_admin_mobile.html
+++ b/files/templates/component/post/actions_admin_mobile.html
@@ -13,10 +13,7 @@
{% endif %}
- {#
-
-
-
+ {#
#}
diff --git a/files/templates/component/post/actions_mobile.html b/files/templates/component/post/actions_mobile.html
index 3e86905d3..2c49d4add 100644
--- a/files/templates/component/post/actions_mobile.html
+++ b/files/templates/component/post/actions_mobile.html
@@ -31,15 +31,9 @@
{% endif %}
-
-
-
- {#
- #}
-
{% else %}
diff --git a/files/templates/home.html b/files/templates/home.html
index 00ac43b95..12915f406 100644
--- a/files/templates/home.html
+++ b/files/templates/home.html
@@ -54,16 +54,15 @@
{{t | capitalize}}
- {% if t != "hour" %}Hour{% endif %}
- {% if t != "day" %}Day{% endif %}
- {% if t != "week" %}Week{% endif %}
- {% if t != "month" %}Month{% endif %}
- {% if t != "year" %}Year{% endif %}
- {% if t != "all" %}All{% endif %}
+ {% if t != "hour" %}Hour{% endif %}
+ {% if t != "day" %}Day{% endif %}
+ {% if t != "week" %}Week{% endif %}
+ {% if t != "month" %}Month{% endif %}
+ {% if t != "year" %}Year{% endif %}
+ {% if t != "all" %}All{% endif %}
+ 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.
+
+ 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.
+
+ 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.
+
+
@@ -167,7 +178,7 @@
invest effort if they want to post things that have traditionally been pain points.
-
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.
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.
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.
+ 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.
+
+
+ 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.
+
+
+ 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.
+
@@ -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) %}
-
- {{p.realbody(v) | safe}}
-
- {% endif %}
+ {% if p.realbody(v) %}
+
+ {{p.realbody(v) | safe}}
+
+ {% endif %}
- {% if p.is_image and not p.over_18 and ((v and v.cardview) or (not v and CARD_VIEW)) %}
-