diff --git a/files/assets/js/emoji_modal.js b/files/assets/js/emoji_modal.js index 94d8f6a9b..d5475ba38 100644 --- a/files/assets/js/emoji_modal.js +++ b/files/assets/js/emoji_modal.js @@ -307,7 +307,7 @@ function switchEmojiTab(e) } async function start_search() { - emojiSearcher.addQuery(emojiSearchBarDOM.value); + emojiSearcher.addQuery(emojiSearchBarDOM.value.trim()); // Remove any selected tab, now it is meaningless for(let i = 0; i < classesSelectorDOM.children.length; i++) diff --git a/files/helpers/get.py b/files/helpers/get.py index 76f55e03e..5b8345458 100644 --- a/files/helpers/get.py +++ b/files/helpers/get.py @@ -89,13 +89,13 @@ def get_users(usernames, graceful=False): return users -def get_account(id, v=None): +def get_account(id, v=None, graceful=False): try: id = int(id) except: abort(404) user = g.db.get(User, id) - if not user: abort(404) + if not user and not graceful: abort(404) if v: block = g.db.query(UserBlock).filter( diff --git a/files/helpers/regex.py b/files/helpers/regex.py index 35e44cca0..224723383 100644 --- a/files/helpers/regex.py +++ b/files/helpers/regex.py @@ -132,9 +132,7 @@ def torture_ap(body, username): lines[i] = torture_regex.sub(rf'\1@{username} ', lines[i]) lines[i] = torture_regex2.sub(rf'\1@{username} is ', lines[i]) - body = ''.join(lines) + '\n:#trumpjaktalking:' - - return body + return ''.join(lines).strip() commands = { diff --git a/files/helpers/sanitize.py b/files/helpers/sanitize.py index 2f8422c04..885e59ea4 100644 --- a/files/helpers/sanitize.py +++ b/files/helpers/sanitize.py @@ -193,9 +193,13 @@ def with_sigalrm_timeout(timeout: int): @with_sigalrm_timeout(2) -def sanitize(sanitized, edit=False, limit_pings=0, showmore=True, marsified=False): +def sanitize(sanitized, edit=False, limit_pings=0, showmore=True, marsified=False, torture=False): sanitized = sanitized.strip() + if torture: + sanitized = torture_ap(sanitized, g.v.username) + sanitized += '\n:#trumpjaktalking:' + sanitized = normalize_url(sanitized) if '```' not in sanitized and '
' not in sanitized: @@ -399,7 +403,11 @@ def allowed_attributes_emojis(tag, name, value): @with_sigalrm_timeout(1) -def filter_emojis_only(title, edit=False, graceful=False): +def filter_emojis_only(title, edit=False, graceful=False, torture=False): + title = title.strip() + + if torture: + title = torture_ap(title, g.v.username) title = title.replace('','').replace('','').replace("\ufeff", "").replace("𒐪","").replace("\n", "").replace("\r", "").replace("\t", "").replace("&", "&").replace('<','<').replace('>','>').replace('"', '"').replace("'", "'").strip() diff --git a/files/helpers/wrappers.py b/files/helpers/wrappers.py index 669710925..0c1661401 100644 --- a/files/helpers/wrappers.py +++ b/files/helpers/wrappers.py @@ -26,8 +26,11 @@ def get_logged_in_user(): lo_user = session.get("lo_user") if lo_user: id = int(lo_user) - v = get_account(id) - if v: + v = get_account(id, graceful=True) + if not v: + session.clear() + return None + else: nonce = session.get("login_nonce", 0) if nonce < v.login_nonce or v.id != id: abort(401) diff --git a/files/routes/admin.py b/files/routes/admin.py index 4f8c2018d..4d4af6c72 100644 --- a/files/routes/admin.py +++ b/files/routes/admin.py @@ -639,7 +639,7 @@ def users_list(v): next_exists = (len(users) > 25) users = users[:25] - return render_template("admin/new_users.html", + return render_template("user_cards.html", v=v, users=users, next_exists=next_exists, @@ -647,28 +647,6 @@ def users_list(v): ) -@app.get("/badge_owners/") -@auth_required -def bid_list(v, bid): - - try: bid = int(bid) - except: abort(400) - - try: page = int(request.values.get("page", 1)) - except: page = 1 - - users = g.db.query(User).join(User.badges).filter(Badge.badge_id==bid).offset(25 * (page - 1)).limit(26).all() - - next_exists = (len(users) > 25) - users = users[:25] - - return render_template("admin/new_users.html", - v=v, - users=users, - next_exists=next_exists, - page=page, - ) - @app.get("/admin/alt_votes") @admin_level_required(2) diff --git a/files/routes/comments.py b/files/routes/comments.py index a006a61f2..e7e60a270 100644 --- a/files/routes/comments.py +++ b/files/routes/comments.py @@ -332,16 +332,15 @@ def comment(v): with open(f"snappy_{SITE_NAME}.txt", "a", encoding="utf-8") as f: f.write('\n{[para]}\n' + body) - if v.agendaposter and not v.marseyawarded and parent_post.id not in ADMIGGERS and parent_post.sub != 'chudrama': - body = torture_ap(body, v.username) - body_for_sanitize = body if v.owoify: body_for_sanitize = owoify(body_for_sanitize) if v.marsify: body_for_sanitize = marsify(body_for_sanitize) - body_html = sanitize(body_for_sanitize, limit_pings=5, marsified=True) + torture = (v.agendaposter and not v.marseyawarded and parent_post.sub != 'chudrama' and parent_post.id not in ADMIGGERS) + + body_html = sanitize(body_for_sanitize, limit_pings=5, marsified=True, torture=torture) if parent_post.id not in ADMIGGERS and '!wordle' not in body.lower() and AGENDAPOSTER_PHRASE not in body.lower(): @@ -707,9 +706,6 @@ def edit_comment(cid, v): elif v.bird and len(body) > 140: return {"error":"You have to type less than 140 characters!"}, 403 - if v.agendaposter and not v.marseyawarded and c.post.sub != 'chudrama': - body = torture_ap(body, v.username) - for i in poll_regex.finditer(body): body = body.replace(i.group(0), "") option = CommentOption( @@ -772,7 +768,9 @@ def edit_comment(cid, v): if v.marsify: body_for_sanitize = marsify(body_for_sanitize) - body_html = sanitize(body_for_sanitize, edit=True, limit_pings=5, marsified=True) + torture = (v.agendaposter and not v.marseyawarded and c.post.sub != 'chudrama') + + body_html = sanitize(body_for_sanitize, edit=True, limit_pings=5, marsified=True, torture=torture) if len(body_html) > 20000: abort(400) diff --git a/files/routes/hats.py b/files/routes/hats.py index 1f0e60d6a..904cfa14f 100644 --- a/files/routes/hats.py +++ b/files/routes/hats.py @@ -125,7 +125,7 @@ def hat_owners(v, hat_id): next_exists = (len(users) > 25) users = users[:25] - return render_template("admin/new_users.html", + return render_template("user_cards.html", v=v, users=users, next_exists=next_exists, diff --git a/files/routes/posts.py b/files/routes/posts.py index 740218418..288228a60 100644 --- a/files/routes/posts.py +++ b/files/routes/posts.py @@ -405,10 +405,9 @@ def edit_post(pid, v): return {"error":"You have to type less than 140 characters!"}, 403 if title != p.title: - if v.id == p.author_id and v.agendaposter and not v.marseyawarded and p.sub != 'chudrama': - title = torture_ap(title, v.username) + torture = (v.agendaposter and not v.marseyawarded and p.sub != 'chudrama' and v.id == p.author_id) - title_html = filter_emojis_only(title, edit=True) + title_html = filter_emojis_only(title, edit=True, torture=torture) if v.id == p.author_id and v.marseyawarded and not marseyaward_title_regex.fullmatch(title_html): return {"error":"You can only type marseys!"}, 403 @@ -421,9 +420,6 @@ def edit_post(pid, v): body = body.strip() if body != p.body: - if v.id == p.author_id and v.agendaposter and not v.marseyawarded and p.sub != 'chudrama': - body = torture_ap(body, v.username) - for i in poll_regex.finditer(body): body = body.replace(i.group(0), "") option = SubmissionOption( @@ -443,7 +439,9 @@ def edit_post(pid, v): g.db.add(option) - body_html = sanitize(body, edit=True, limit_pings=100, showmore=False) + torture = (v.agendaposter and not v.marseyawarded and p.sub != 'chudrama' and v.id == p.author_id) + + body_html = sanitize(body, edit=True, limit_pings=100, showmore=False, torture=torture) if v.id == p.author_id and v.marseyawarded and marseyaward_body_regex.search(body_html): return {"error":"You can only type marseys!"}, 403 @@ -721,10 +719,9 @@ def submit_post(v, sub=None): if v.is_suspended: return error("You can't perform this action while banned.") - if v.agendaposter and not v.marseyawarded and sub != 'chudrama': - title = torture_ap(title, v.username) + torture = (v.agendaposter and not v.marseyawarded and sub != 'chudrama') - title_html = filter_emojis_only(title, graceful=True) + title_html = filter_emojis_only(title, graceful=True, torture=torture) if v.marseyawarded and not marseyaward_title_regex.fullmatch(title_html): return error("You can only type marseys!") @@ -892,14 +889,13 @@ def submit_post(v, sub=None): choices.append(i.group(1)) body = body.replace(i.group(0), "") - if v.agendaposter and not v.marseyawarded and sub != 'chudrama': - body = torture_ap(body, v.username) - body += process_files() body = body.strip() - body_html = sanitize(body, limit_pings=100, showmore=False) + torture = (v.agendaposter and not v.marseyawarded and sub != 'chudrama') + + body_html = sanitize(body, limit_pings=100, showmore=False, torture=torture) if v.marseyawarded and marseyaward_body_regex.search(body_html): return error("You can only type marseys!") diff --git a/files/routes/static.py b/files/routes/static.py index 192c74552..8b779f728 100644 --- a/files/routes/static.py +++ b/files/routes/static.py @@ -68,8 +68,7 @@ def sidebar(v): @app.get("/stats") @auth_required def participation_stats(v): - return render_template("admin/content_stats.html", - v=v, title="Content Statistics", data=stats_cached()) + return render_template("stats.html", v=v, title="Content Statistics", data=stats_cached()) @cache.memoize(timeout=86400) def stats_cached(): diff --git a/files/routes/users.py b/files/routes/users.py index 0df748527..95ef62a78 100644 --- a/files/routes/users.py +++ b/files/routes/users.py @@ -19,11 +19,10 @@ from sys import stdout import os -def leaderboard_thread(): - global users9, users9_1, users9_2, users13, users13_1, users13_2 - +def leaderboard_thread(): db = db_session() + global users9, users9_1, users9_2 votes1 = db.query(Submission.author_id, func.count(Submission.author_id)).join(Vote).filter(Vote.vote_type==-1).group_by(Submission.author_id).order_by(func.count(Submission.author_id).desc()).all() votes2 = db.query(Comment.author_id, func.count(Comment.author_id)).join(CommentVote).filter(CommentVote.vote_type==-1).group_by(Comment.author_id).order_by(func.count(Comment.author_id).desc()).all() votes3 = Counter(dict(votes1)) + Counter(dict(votes2)) @@ -31,13 +30,11 @@ def leaderboard_thread(): users9 = [] for user in users8: users9.append((user.id, votes3[user.id])) + if not users9: users9 = [(None,None)] users9 = sorted(users9, key=lambda x: x[1], reverse=True) - - if (len(users9) < 2): - return - users9_1, users9_2 = zip(*users9[:25]) + global users13, users13_1, users13_2 votes1 = db.query(Vote.user_id, func.count(Vote.user_id)).filter(Vote.vote_type==1).group_by(Vote.user_id).order_by(func.count(Vote.user_id).desc()).all() votes2 = db.query(CommentVote.user_id, func.count(CommentVote.user_id)).filter(CommentVote.vote_type==1).group_by(CommentVote.user_id).order_by(func.count(CommentVote.user_id).desc()).all() votes3 = Counter(dict(votes1)) + Counter(dict(votes2)) @@ -45,24 +42,20 @@ def leaderboard_thread(): users13 = [] for user in users14: users13.append((user.id, votes3[user.id]-user.post_count-user.comment_count)) + if not users13: users13 = [(None,None)] users13 = sorted(users13, key=lambda x: x[1], reverse=True) users13_1, users13_2 = zip(*users13[:25]) db.close() stdout.flush() + gevent.spawn(leaderboard_thread()) - - - - - - @app.get("/@ /upvoters/ /posts") @auth_required def upvoters_posts(v, username, uid): @@ -1352,3 +1345,49 @@ def toggle_pins(sort): if is_site_url(request.referrer): return redirect(request.referrer) return redirect('/') + + +@app.get("/badge_owners/ ") +@auth_required +def bid_list(v, bid): + + try: bid = int(bid) + except: abort(400) + + try: page = int(request.values.get("page", 1)) + except: page = 1 + + users = g.db.query(User).join(User.badges).filter(Badge.badge_id==bid).offset(25 * (page - 1)).limit(26).all() + + next_exists = (len(users) > 25) + users = users[:25] + + return render_template("user_cards.html", + v=v, + users=users, + next_exists=next_exists, + page=page, + ) + + +@app.get("/blockers/ ") +@auth_required +def blockers_list(v, uid): + + try: uid = int(uid) + except: abort(400) + + try: page = int(request.values.get("page", 1)) + except: page = 1 + + users = g.db.query(User).join(User.blocking).filter(UserBlock.target_id==uid).offset(25 * (page - 1)).limit(26).all() + + next_exists = (len(users) > 25) + users = users[:25] + + return render_template("user_cards.html", + v=v, + users=users, + next_exists=next_exists, + page=page, + ) \ No newline at end of file diff --git a/files/templates/leaderboard.html b/files/templates/leaderboard.html index 1f798b187..876fb3fab 100644 --- a/files/templates/leaderboard.html +++ b/files/templates/leaderboard.html @@ -95,7 +95,7 @@ Truescore - + {% for user in users10 %}{{loop.index}} @@ -131,7 +131,7 @@{% endfor %} {% if pos2 > 25 %} @@ -247,7 +247,7 @@ {{loop.index}} {% include "user_in_table.html" %} -{{user.stored_subscriber_count}} +{{user.stored_subscriber_count}} Downvotes - + {% for user, num in users9 %}- + {% for user, num in users11 %} {{loop.index}} @@ -280,7 +280,7 @@Badges - + {% for user, num in users12 %} {{loop.index}} @@ -348,7 +348,7 @@Marseys - + {% for user, num in users13 %} {{loop.index}} @@ -382,7 +382,7 @@Upvotes {{loop.index}} @@ -480,7 +480,7 @@{% endfor %} diff --git a/files/templates/admin/content_stats.html b/files/templates/stats.html similarity index 100% rename from files/templates/admin/content_stats.html rename to files/templates/stats.html diff --git a/files/templates/admin/new_users.html b/files/templates/user_cards.html similarity index 100% rename from files/templates/admin/new_users.html rename to files/templates/user_cards.html diff --git a/files/templates/util/assetcache.html b/files/templates/util/assetcache.html index a874e73f6..93a5f63f1 100644 --- a/files/templates/util/assetcache.html +++ b/files/templates/util/assetcache.html @@ -22,7 +22,7 @@ set CACHE_VER = { 'js/comments_admin.js': 4000, 'js/comments_v.js': 4000, 'js/submission_listing.js': 4000, - 'js/emoji_modal.js': 4000, + 'js/emoji_modal.js': 4001, 'js/formatting.js': 4000, 'js/lottery.js': 4000, 'js/marked.js': 4000, diff --git a/readme.md b/readme.md index 9060b56b2..44a7a3017 100644 --- a/readme.md +++ b/readme.md @@ -29,5 +29,4 @@ docker-compose up For returning contributors, we have noticed the following issues (if you can help fix them, we will be very grateful!): 1. Docker doesn't know when we add a new Python dependency, `docker-compose build` is needed. -2. DB schema changes are not applied automatically, the easiest way to deal with that is to delete the entire environment from the Docker GUI and do `docker-compose up`. Also wait five minutes for a "sneed" commit from Aevann meaning that the sql file was regenerated. -3. Old authorization cookies from the previous instance cause a weird 404 error, clear cookies for localhost to fix. +2. DB schema changes are not applied automatically, the easiest way to deal with that is to delete the entire environment from the Docker GUI and do `docker-compose up`. Also wait five minutes for a "sneed" commit from Aevann meaning that the sql file was regenerated. \ No newline at end of file {{loop.index}} {% include "user_in_table.html" %} -{{num}} +{{num}}