From 7dfbb1541e445ea0aca4b100527092e89918e7e7 Mon Sep 17 00:00:00 2001 From: Aevann Date: Wed, 7 Feb 2024 00:04:43 +0200 Subject: [PATCH] add effortpost marking --- files/assets/css/main.css | 6 +- files/assets/js/submit.js | 2 +- files/classes/post.py | 1 + files/helpers/alerts.py | 16 +++++ files/helpers/config/const.py | 1 + files/helpers/config/modaction_types.py | 10 +++ files/routes/admin.py | 68 +++++++++++++++++++ files/routes/oauth.py | 15 +--- files/routes/posts.py | 5 ++ files/routes/votes.py | 24 ++++--- files/templates/post.html | 2 + files/templates/post_actions.html | 4 ++ .../templates/post_admin_actions_mobile.html | 4 ++ files/templates/post_listing.html | 1 + files/templates/submit.html | 4 ++ .../20240206-add-mark-effortpost-button.sql | 2 + 16 files changed, 141 insertions(+), 24 deletions(-) create mode 100644 migrations/20240206-add-mark-effortpost-button.sql diff --git a/files/assets/css/main.css b/files/assets/css/main.css index 682b62568..c608c715b 100644 --- a/files/assets/css/main.css +++ b/files/assets/css/main.css @@ -219,6 +219,7 @@ .fa-coin:before{content:"\f85c"} .fa-scarecrow:before{content:"\f70d"} .fa-chart-simple:before{content:"\e473"} +.fa-memo:before{content:"\e1d8"} /* do not remove - fixes hand, talking, marsey-love components from breaking out of the comment box @@ -5194,6 +5195,9 @@ span.green { padding: 2px 5px !important; } } +.effortpost-flair { + padding: 5px 5px 4px 5px !important; +} .patron[style*="background-color:#ffffff"] { color: black !important; } @@ -7652,7 +7656,7 @@ blink { animation: 60s linear 0s infinite move-colors; } -:not(td) > a[href="/h/highrollerclub"].hole-flair { +:not(td) > a[href="/h/highrollerclub"].hole-flair, .effortpost-flair { font-family: open sans,sans-serif !important; background: repeating-linear-gradient( 45deg, diff --git a/files/assets/js/submit.js b/files/assets/js/submit.js index fa4e2f297..30b52351b 100644 --- a/files/assets/js/submit.js +++ b/files/assets/js/submit.js @@ -8,7 +8,7 @@ for (const id of save_value) { autoExpand(document.getElementById('post-text')) markdown(document.getElementById("post-text")); -const save_checked = ['post-notify', 'post-new', 'post-nsfw', 'post-private', 'post-ghost'] +const save_checked = ['post-notify', 'post-new', 'post-nsfw', 'post-private', 'post-effortpost', 'post-ghost'] for (const key of save_checked) { const value = localStorage.getItem(key) if (value) { diff --git a/files/classes/post.py b/files/classes/post.py index cbd9c4846..fc4ada669 100644 --- a/files/classes/post.py +++ b/files/classes/post.py @@ -34,6 +34,7 @@ class Post(Base): bannedfor = Column(String) chuddedfor = Column(String) ghost = Column(Boolean, default=False) + effortpost = Column(Boolean, default=False) views = Column(Integer, default=0) deleted_utc = Column(Integer, default=0) distinguish_level = Column(Integer, default=0) diff --git a/files/helpers/alerts.py b/files/helpers/alerts.py index 8b3ec95b7..b5a27b937 100644 --- a/files/helpers/alerts.py +++ b/files/helpers/alerts.py @@ -297,3 +297,19 @@ def alert_everyone(cid): select id, {cid}, false, {t} from users on conflict do nothing;""") g.db.execute(_everyone_query) + +def alert_admins(body): + body_html = sanitize(body, blackjack="admin alert") + + new_comment = Comment(author_id=AUTOJANNY_ID, + parent_post=None, + level=1, + body_html=body_html, + sentto=MODMAIL_ID, + distinguish_level=6, + is_bot=True + ) + g.db.add(new_comment) + g.db.flush() + + new_comment.top_comment_id = new_comment.id diff --git a/files/helpers/config/const.py b/files/helpers/config/const.py index a8e8542ae..0820c4b3a 100644 --- a/files/helpers/config/const.py +++ b/files/helpers/config/const.py @@ -206,6 +206,7 @@ PERMS = { # Minimum admin_level to perform action. 'UPDATE_ASSETS': 3, 'CHANGE_UNDER_SIEGE': 3, 'VIEW_IPS': 3, + 'MARK_EFFORTPOST': 3, 'PROGSTACK': 4, 'UNDO_AWARD_PINS': 4, diff --git a/files/helpers/config/modaction_types.py b/files/helpers/config/modaction_types.py index 9b5e3c744..0ecfd18e0 100644 --- a/files/helpers/config/modaction_types.py +++ b/files/helpers/config/modaction_types.py @@ -206,6 +206,16 @@ MODACTION_TYPES = { "icon": 'fa-file-signature', "color": 'bg-success' }, + 'mark_effortpost': { + "str": 'marked {self.target_link} as an effortpost', + "icon": 'fa-memo', + "color": 'bg-success' + }, + 'unmark_effortpost': { + "str": 'unmarked {self.target_link} as an effortpost', + "icon": 'fa-memo', + "color": 'bg-danger' + }, 'move_hole': { "str": 'changed hole of {self.target_link}', "icon": 'fa-manhole', diff --git a/files/routes/admin.py b/files/routes/admin.py index 676024046..aa4d4b5f3 100644 --- a/files/routes/admin.py +++ b/files/routes/admin.py @@ -2174,3 +2174,71 @@ if FEATURES['IP_LOGGING']: def view_ip_users(v, ip): ip_logs = g.db.query(IPLog).filter_by(ip=ip).order_by(IPLog.last_used.desc()) return render_template('admin/ip_users.html', v=v, ip=ip, ip_logs=ip_logs) + + +@app.post("/mark_effortpost/") +@limiter.limit('1/second', scope=rpath) +@limiter.limit('1/second', scope=rpath, key_func=get_ID) +@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) +@admin_level_required(PERMS['MARK_EFFORTPOST']) +def mark_effortpost(pid, v): + p = get_post(pid) + + if p.effortpost: + abort(400, "Post is already marked as an effortpost!") + + p.effortpost = True + g.db.add(p) + + ma = ModAction( + kind = "mark_effortpost", + user_id = v.id, + target_post_id = p.id, + ) + g.db.add(ma) + + if SITE_NAME == 'WPD': + mul = 8 + else: + mul = 4 + + coins = (p.upvotes + p.downvotes) * mul + + send_repeatable_notification(p.author_id, f":marseyclapping: @{v.username} (a site admin) has marked [{p.title}](/post/{p.id}) as an effortpost, it now gets x{mul} coins from votes. You have received {coins} coins retroactively, thanks! :!marseyclapping:") + + return {"message": "Post has been marked as an effortpost!"} + + +@app.post("/unmark_effortpost/") +@limiter.limit('1/second', scope=rpath) +@limiter.limit('1/second', scope=rpath, key_func=get_ID) +@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) +@admin_level_required(PERMS['MARK_EFFORTPOST']) +def unmark_effortpost(pid, v): + p = get_post(pid) + + if not p.effortpost: + abort(400, "Post is already not marked as an effortpost!") + + p.effortpost = False + g.db.add(p) + + ma = ModAction( + kind = "unmark_effortpost", + user_id = v.id, + target_post_id = p.id, + ) + g.db.add(ma) + + if SITE_NAME == 'WPD': + mul = 8 + else: + mul = 4 + + coins = (p.upvotes + p.downvotes) * mul + + send_repeatable_notification(p.author_id, f":marseyitsover: @{v.username} (a site admin) has unmarked [{p.title}](/post/{p.id}) as an effortpost. {coins} coins have been deducted from you. :!marseyitsover:") + + return {"message": "Post has been unmarked as an effortpost!"} diff --git a/files/routes/oauth.py b/files/routes/oauth.py index 40a773f8c..0dd5bfdd3 100644 --- a/files/routes/oauth.py +++ b/files/routes/oauth.py @@ -67,20 +67,7 @@ def request_api_keys(v): g.db.add(new_app) body = f"@{v.username} has requested API keys for `{request.values.get('name')}`. You can approve or deny the request [here](/admin/apps)." - body_html = sanitize(body, blackjack="app description") - - new_comment = Comment(author_id=AUTOJANNY_ID, - parent_post=None, - level=1, - body_html=body_html, - sentto=MODMAIL_ID, - distinguish_level=6, - is_bot=True - ) - g.db.add(new_comment) - g.db.flush() - - new_comment.top_comment_id = new_comment.id + alert_admins(body) return {"message": "API keys requested successfully!"} diff --git a/files/routes/posts.py b/files/routes/posts.py index 0d218f9f1..34b1e5074 100644 --- a/files/routes/posts.py +++ b/files/routes/posts.py @@ -540,6 +540,7 @@ def submit_post(v, hole=None): flag_new = request.values.get("new", False, bool) or 'megathread' in title.lower() flag_nsfw = FEATURES['NSFW_MARKING'] and request.values.get("nsfw", False, bool) flag_private = request.values.get("private", False, bool) + flag_effortpost = request.values.get("effortpost", False, bool) flag_ghost = request.values.get("ghost", False, bool) and v.can_post_in_ghost_threads if flag_ghost: hole = None @@ -702,6 +703,10 @@ def submit_post(v, hole=None): generate_thumb = (not p.thumburl and p.url and p.domain != SITE) gevent.spawn(postprocess_post, p.url, p.body, p.body_html, p.id, generate_thumb, False) + if flag_effortpost: + body = f"@{v.username} has requested that [{p.title}](/post/{p.id}) be marked as an effortpost!" + alert_admins(body) + if v.client: return p.json else: p.voted = 1 diff --git a/files/routes/votes.py b/files/routes/votes.py index be9b3e343..bc4f1faa2 100644 --- a/files/routes/votes.py +++ b/files/routes/votes.py @@ -44,8 +44,6 @@ def vote_post_comment(target_id, new, v, cls, vote_cls): coin_delta = -1 alt = True - coin_mult = 1 - g.db.flush() existing = g.db.query(vote_cls).filter_by(user_id=v.id) if vote_cls == Vote: @@ -56,14 +54,24 @@ def vote_post_comment(target_id, new, v, cls, vote_cls): abort(400) existing = existing.one_or_none() - if SITE_NAME == 'WPD': - coin_mult *= 4 - if IS_EVENT(): - coin_mult *= 2 + if cls == Post and target.effortpost: + if SITE_NAME == 'WPD': + coin_mult = 8 + else: + coin_mult = 4 + else: + coin_mult = 1 + + if SITE_NAME == 'WPD': + coin_mult *= 4 + + if IS_EVENT(): + coin_mult *= 2 + + if IS_HOMOWEEN() and target.author.zombie > 0: + coin_mult += 1 - if IS_HOMOWEEN() and target.author.zombie > 0: - coin_mult += 1 coin_value = coin_delta * coin_mult diff --git a/files/templates/post.html b/files/templates/post.html index 12bacf337..8806c8d79 100644 --- a/files/templates/post.html +++ b/files/templates/post.html @@ -94,10 +94,12 @@

{% if p.realurl(v) and not v_forbid_deleted %} + {% if p.effortpost %}EFFORTPOST{% endif %} {% if p.flair %}{{p.flair | safe}}{% endif %} {{p.realtitle(v) | safe}} {% else %} + {% if p.effortpost %}EFFORTPOST{% endif %} {% if p.flair %}{{p.flair | safe}}{% endif %} {{p.realtitle(v) | safe}} {% endif %} diff --git a/files/templates/post_actions.html b/files/templates/post_actions.html index 817a15c77..a17f2e953 100644 --- a/files/templates/post_actions.html +++ b/files/templates/post_actions.html @@ -83,6 +83,10 @@ {% endif %} + {% if v.admin_level >= PERMS['MARK_EFFORTPOST'] %} + + + {% endif %} {% if v.admin_level >= PERMS['PROGSTACK'] %} diff --git a/files/templates/post_admin_actions_mobile.html b/files/templates/post_admin_actions_mobile.html index db7c3e20e..938721292 100644 --- a/files/templates/post_admin_actions_mobile.html +++ b/files/templates/post_admin_actions_mobile.html @@ -37,6 +37,10 @@ {% endif %} + {% if v.admin_level >= PERMS['MARK_EFFORTPOST'] %} + + + {% endif %} {% if v.admin_level >= PERMS['PROGSTACK'] %} diff --git a/files/templates/post_listing.html b/files/templates/post_listing.html index dfa33f043..2bfd74809 100644 --- a/files/templates/post_listing.html +++ b/files/templates/post_listing.html @@ -92,6 +92,7 @@

+ {% if p.effortpost %}EFFORTPOST{% endif %} {% if p.flair %}{{p.flair | safe}}{% endif %} {{p.realtitle(v) | safe}}
diff --git a/files/templates/submit.html b/files/templates/submit.html index 76f0c3fc2..a226c7c2b 100644 --- a/files/templates/submit.html +++ b/files/templates/submit.html @@ -82,6 +82,10 @@ +
+ + +
diff --git a/migrations/20240206-add-mark-effortpost-button.sql b/migrations/20240206-add-mark-effortpost-button.sql new file mode 100644 index 000000000..1fade1a7e --- /dev/null +++ b/migrations/20240206-add-mark-effortpost-button.sql @@ -0,0 +1,2 @@ +alter table posts add column effortpost bool default false not null; +alter table posts alter column effortpost drop default;