diff --git a/files/assets/css/main.css b/files/assets/css/main.css index 9edb1e782..3039c0079 100644 --- a/files/assets/css/main.css +++ b/files/assets/css/main.css @@ -5134,7 +5134,7 @@ th, td { } #account-menu-header, #account-menu { - min-width: 10em; + min-width: 13em; } .navigation-secondary-link { diff --git a/files/assets/js/comments.js b/files/assets/js/comments.js index 966f2c02b..4e7c0a903 100644 --- a/files/assets/js/comments.js +++ b/files/assets/js/comments.js @@ -56,4 +56,22 @@ function expandMarkdown(t,id) { let val = t.getElementsByTagName('span')[0] if (val.innerHTML == 'View source') val.innerHTML = 'Hide source' else val.innerHTML = 'View source' -}; \ No newline at end of file +}; + +function commentsAddUnreadIndicator(commentIds) { + commentIds.forEach(element => { + const commentOnly = document.getElementById(`comment-${element}-only`); + if (!commentOnly) { + console.warn(`Couldn't find comment (comment ID ${element}) in page while attempting to add an unread indicator.`); + return; + } + if (commentOnly.classList.contains("unread")) return; + commentOnly.classList.add("unread"); + const commentUserInfo = document.getElementById(`comment-${element}`)?.querySelector(".comment-user-info"); + if (!commentUserInfo) { + console.warn(`Couldn't find comment user info (comment ID ${element}) in page while attempting to add an unread indicator.`); + return; + } + commentUserInfo.innerHTML += "~new~"; + }); +} diff --git a/files/assets/js/comments_admin.js b/files/assets/js/comments_admin.js index 5317a9e02..0f20ce187 100644 --- a/files/assets/js/comments_admin.js +++ b/files/assets/js/comments_admin.js @@ -1,78 +1,23 @@ -function removeCommentBackend(post_id) { - url="/remove_comment/"+post_id - - post(url) -} - -function approveCommentBackend(post_id) { - url="/unremove_comment/"+post_id - - post(url) -} - -function removeCommentDesktop(post_id,button1,button2) { - removeCommentBackend(post_id) - - try { - document.getElementById("comment-"+post_id+"-only").classList.add("banned"); - } catch(e) { - document.getElementById("context").classList.add("banned"); +function moderate(isPost, id, removing, removeButtonDesktopId, removeButtonMobileId, approveButtonDesktopId, approveButtonMobileId) { + const filterState = removing ? "removed" : "normal"; + if (isPost) { + filter_new_status(id, filterState); + } else { + filter_new_comment_status(id, filterState); } - - var button=document.getElementById("remove-"+post_id); - button.onclick=function(){approveCommentDesktop(post_id)}; - button.innerHTML='Approve' - - if (typeof button1 !== 'undefined') { - document.getElementById(button1).classList.toggle("d-md-inline-block"); - document.getElementById(button2).classList.toggle("d-md-inline-block"); - } -}; - -function approveCommentDesktop(post_id,button1,button2) { - approveCommentBackend(post_id) - - try { - document.getElementById("comment-"+post_id+"-only").classList.remove("banned"); - } catch(e) { - document.getElementById("context").classList.remove("banned"); - } - - var button=document.getElementById("remove-"+post_id); - button.onclick=function(){removeCommentDesktop(post_id)}; - button.innerHTML='Remove' - - if (typeof button1 !== 'undefined') { - document.getElementById(button1).classList.toggle("d-md-inline-block"); - document.getElementById(button2).classList.toggle("d-md-inline-block"); - } -} - - -function removeCommentMobile(post_id,button1,button2) { - removeCommentBackend(post_id) - - document.getElementById("comment-"+post_id+"-only").classList.add("banned"); - var button=document.getElementById("remove-"+post_id); - button.onclick=function(){approveCommentMobile(post_id)}; - button.innerHTML='Approve' - - if (typeof button1 !== 'undefined') { - document.getElementById(button1).classList.toggle("d-none"); - document.getElementById(button2).classList.toggle("d-none"); - } -}; - -function approveCommentMobile(post_id,button1,button2) { - approveCommentBackend(post_id) - - document.getElementById("comment-"+post_id+"-only").classList.remove("banned"); - var button=document.getElementById("remove-"+post_id); - button.onclick=function(){removeCommentMobile(post_id)}; - button.innerHTML='Remove' - - if (typeof button1 !== 'undefined') { - document.getElementById(button1).classList.toggle("d-none"); - document.getElementById(button2).classList.toggle("d-none"); + const removeButtonDesktop = document.getElementById(removeButtonDesktopId); + const removeButtonMobile = document.getElementById(removeButtonMobileId); + const approveButtonDesktop = document.getElementById(approveButtonDesktopId); + const approveButtonMobile = document.getElementById(approveButtonMobileId); + if (removing) { + removeButtonDesktop.classList.add("d-none"); + removeButtonMobile.classList.add("d-none"); + approveButtonDesktop.classList.remove("d-none"); + approveButtonMobile.classList.remove("d-none"); + } else { + removeButtonDesktop.classList.remove("d-none"); + removeButtonMobile.classList.remove("d-none"); + approveButtonDesktop.classList.add("d-none"); + approveButtonMobile.classList.add("d-none"); } } diff --git a/files/classes/mod_logs.py b/files/classes/mod_logs.py index 24047861e..245bb98fc 100644 --- a/files/classes/mod_logs.py +++ b/files/classes/mod_logs.py @@ -85,6 +85,26 @@ class ModAction(CreatedBase): return f"/log/{self.id}" ACTIONTYPES = { + 'approve_post': { + "str": 'approved post {self.target_link}', + "icon": 'fa-feather-alt', + "color": 'bg-success' + }, + 'approve_comment': { + "str": 'approved {self.target_link}', + "icon": 'fa-comment', + "color": 'bg-success' + }, + 'remove_post': { + "str": 'removed post {self.target_link}', + "icon": 'fa-feather-alt', + "color": 'bg-danger' + }, + 'remove_comment': { + "str": 'removed {self.target_link}', + "icon": 'fa-comment', + "color": 'bg-danger' + }, 'approve_app': { "str": 'approved an application by {self.target_link}', "icon": 'fa-robot', @@ -100,21 +120,11 @@ ACTIONTYPES = { "icon": 'fa-badge', "color": 'bg-danger' }, - 'remove_comment': { - "str": 'removed {self.target_link}', - "icon": 'fa-comment', - "color": 'bg-danger' - }, 'ban_domain': { "str": 'banned a domain', "icon": 'fa-globe', "color": 'bg-danger' }, - 'remove_post': { - "str": 'removed post {self.target_link}', - "icon": 'fa-feather-alt', - "color": 'bg-danger' - }, 'ban_user': { "str": 'banned user {self.target_link}', "icon": 'fa-user-slash', @@ -300,21 +310,11 @@ ACTIONTYPES = { "icon": 'fa-eye-slash', "color": 'bg-danger' }, - 'unremove_comment': { - "str": 'reinstated {self.target_link}', - "icon": 'fa-comment', - "color": 'bg-success' - }, 'unban_domain': { "str": 'unbanned a domain', "icon": 'fa-globe', "color": 'bg-success' }, - 'unremove_post': { - "str": 'reinstated post {self.target_link}', - "icon": 'fa-feather-alt', - "color": 'bg-success' - }, 'unban_user': { "str": 'unbanned user {self.target_link}', "icon": 'fa-user', diff --git a/files/classes/visstate.py b/files/classes/visstate.py index 50d1b754f..a0bfd9fc0 100644 --- a/files/classes/visstate.py +++ b/files/classes/visstate.py @@ -64,13 +64,14 @@ class VisibilityState: op_name_safe=target.author_name ) - def moderated_body(self, v: User | None) -> str | None: + def moderated_body(self, v: User | None, is_blocking: bool=False) -> str | None: if v and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] \ or v.id == self.op_id): return None if self.deleted: return 'Deleted' if self.appear_removed(v): return 'Removed' if self.filtered: return 'Filtered' + if is_blocking: return f'You are blocking @{self.op_name_safe}' return None def visibility_and_message(self, v: User | None, is_blocking: bool) -> tuple[bool, str]: diff --git a/files/helpers/content.py b/files/helpers/content.py index 447acaf53..f6e913c1d 100644 --- a/files/helpers/content.py +++ b/files/helpers/content.py @@ -87,7 +87,10 @@ def canonicalize_url2(url:str, *, httpsify:bool=False) -> urllib.parse.ParseResu def body_displayed(target:Submittable, v:Optional[User], is_html:bool) -> str: - moderated:Optional[str] = target.visibility_state.moderated_body(v) + moderated:Optional[str] = target.visibility_state.moderated_body( + v=v, + is_blocking=getattr(target, 'is_blocking', False) + ) if moderated: return moderated body = target.body_html if is_html else target.body diff --git a/files/routes/admin/admin.py b/files/routes/admin/admin.py index efedbf8e0..866892053 100644 --- a/files/routes/admin/admin.py +++ b/files/routes/admin/admin.py @@ -272,14 +272,14 @@ def filtered_comments(v): # (also rename Unremove to Approve, sigh) @app.post("/admin/update_filter_status") @limiter.exempt -@admin_level_required(2) +@admin_level_required(PERMS['POST_COMMENT_MODERATION']) def update_filter_status(v): update_body = request.get_json() new_status = update_body.get('new_status') post_id = update_body.get('post_id') comment_id = update_body.get('comment_id') if new_status not in ['normal', 'removed', 'ignored']: - return { 'result': f'Status of {new_status} is not permitted' } + return {'result': f'Status of {new_status} is not permitted'}, 403 if new_status == 'normal': state_mod_new = StateMod.VISIBLE @@ -292,43 +292,45 @@ def update_filter_status(v): state_report_new = StateReport.IGNORED if post_id: - target = g.db.get(Submission, post_id) - old_status = target.state_mod - - # this could totally be one query but it would be kinda ugly - if state_mod_new is not None: - g.db.query(Submission).where(Submission.id == post_id) \ - .update({Submission.state_mod: state_mod_new, Submission.state_mod_set_by: v.username}) - g.db.query(Submission).where(Submission.id == post_id) \ - .update({Submission.state_report: state_report_new}) + target: Submission = get_post(post_id, graceful=True) + modlog_target_type: str = 'post' elif comment_id: - target = g.db.get(Comment, comment_id) - old_status = target.state_mod - - if state_mod_new is not None: - g.db.query(Comment).where(Comment.id == comment_id) \ - .update({Comment.state_mod: state_mod_new, Comment.state_mod_set_by: v.username}) - g.db.query(Comment).where(Comment.id == comment_id) \ - .update({Comment.state_report: state_report_new}) + target: Comment = get_comment(comment_id, graceful=True) + modlog_target_type: str = 'comment' else: - return { 'result': f'No valid item ID provided' } + return {"result": "No valid item ID provided"}, 404 + + if not target: + return {"result": "Item ID does not exist"}, 404 - if target is not None: - # If comment now visible, update state to reflect publication. - if (isinstance(target, Comment) - and old_status != StateMod.VISIBLE - and state_mod_new == StateMod.VISIBLE): - comment_on_publish(target) # XXX: can cause discrepancies if removal state ≠ filter state + old_status = target.state_mod - if (isinstance(target, Comment) - and old_status == StateMod.VISIBLE - and state_mod_new != StateMod.VISIBLE and state_mod_new is not None): - comment_on_unpublish(target) # XXX: can cause discrepancies if removal state ≠ filter state + if state_mod_new is not None: + target.state_mod = state_mod_new + target.state_mod_set_by = v.username + target.state_report = state_report_new - g.db.commit() - return { 'result': 'Update successful' } - else: - return { 'result': 'Item ID does not exist' } + making_visible: bool = old_status != StateMod.VISIBLE and state_mod_new == StateMod.VISIBLE + making_invisible: bool = old_status == StateMod.VISIBLE and state_mod_new != StateMod.VISIBLE and state_mod_new is not None + + if making_visible: + modlog_action: str = "approve" + if isinstance(target, Comment): comment_on_publish(target) + elif making_invisible: + modlog_action: str = "remove" + if isinstance(target, Comment): comment_on_unpublish(target) + + if making_visible or making_invisible: + g.db.add(ModAction( + kind=f"{modlog_action}_{modlog_target_type}", + user_id=v.id, + target_submission_id=target.id if isinstance(target, Submission) else None, + target_comment_id=target.id if isinstance(target, Comment) else None + )) + + g.db.commit() + invalidate_cache(frontlist=True) + return { 'result': 'Update successful' } @app.get("/admin/image_posts") @limiter.exempt @@ -809,7 +811,7 @@ def admin_removed_comments(v): try: page = int(request.values.get("page", 1)) except: page = 1 - ids = g.db.query(Comment.id).join(User, User.id == Comment.author_id).filter(or_(Comment.state_mode == StateMod.REMOVED, User.shadowbanned != None)).order_by(Comment.id.desc()).offset(25 * (page - 1)).limit(26).all() + ids = g.db.query(Comment.id).join(User, User.id == Comment.author_id).filter(or_(Comment.state_mod == StateMod.REMOVED, User.shadowbanned != None)).order_by(Comment.id.desc()).offset(25 * (page - 1)).limit(26).all() ids=[x[0] for x in ids] @@ -1100,74 +1102,6 @@ def unban_user(user_id, v): else: return {"message": f"@{user.username} was unbanned!"} -@app.post("/remove_post/") -@limiter.exempt -@admin_level_required(2) -def remove_post(post_id, v): - post = g.db.query(Submission).filter_by(id=post_id).one_or_none() - - if not post: - abort(400) - - post.state_mod = StateMod.REMOVED - post.state_mod_set_by = v.username - post.stickied = None - post.is_pinned = False - g.db.add(post) - - - - ma=ModAction( - kind="remove_post", - user_id=v.id, - target_submission_id=post.id, - ) - g.db.add(ma) - - invalidate_cache(frontlist=True) - - v.coins += 1 - g.db.add(v) - - requests.post(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/purge_cache', headers=CF_HEADERS, json={'files': [f"{SITE_FULL}/logged_out/"]}, timeout=5) - - g.db.commit() - - return {"message": "Post removed!"} - - -@app.post("/unremove_post/") -@limiter.exempt -@admin_level_required(2) -def unremove_post(post_id, v): - post = g.db.query(Submission).filter_by(id=post_id).one_or_none() - - if not post: - abort(400) - - if post.state_mod != StateMod.VISIBLE: - ma=ModAction( - kind="unremove_post", - user_id=v.id, - target_submission_id=post.id, - ) - g.db.add(ma) - - post.state_mod = StateMod.VISIBLE - post.state_mod_set_by = v.username - - g.db.add(post) - - invalidate_cache(frontlist=True) - - v.coins -= 1 - g.db.add(v) - - g.db.commit() - - return {"message": "Post approved!"} - - @app.post("/distinguish/") @limiter.exempt @admin_level_required(1) @@ -1307,59 +1241,10 @@ def unsticky_comment(cid, v): return {"message": "Comment unpinned!"} -@app.post("/remove_comment/") -@limiter.exempt -@admin_level_required(2) -def api_remove_comment(c_id, v): - comment = g.db.query(Comment).filter_by(id=c_id).one_or_none() - if not comment: - abort(404) - - comment.state_mod = StateMod.REMOVED - comment.state_mod_set_by = v.username - comment_on_unpublish(comment) # XXX: can cause discrepancies if removal state ≠ filter state - ma=ModAction( - kind="remove_comment", - user_id=v.id, - target_comment_id=comment.id, - ) - g.db.add(ma) - g.db.commit() - return {"message": "Comment removed!"} - - -@app.post("/unremove_comment/") -@limiter.exempt -@admin_level_required(2) -def api_unremove_comment(c_id, v): - comment = g.db.query(Comment).filter_by(id=c_id).one_or_none() - if not comment: abort(404) - - if comment.state_mod == StateMod.REMOVED: - ma=ModAction( - kind="unremove_comment", - user_id=v.id, - target_comment_id=comment.id, - ) - g.db.add(ma) - - comment.state_mod = StateMod.VISIBLE - comment.state_mod_set_by = v.username - comment_on_publish(comment) # XXX: can cause discrepancies if removal state ≠ filter state - - g.db.add(comment) - - g.db.commit() - - return {"message": "Comment approved!"} - - @app.post("/distinguish_comment/") @limiter.exempt @admin_level_required(1) def admin_distinguish_comment(c_id, v): - - comment = get_comment(c_id, v=v) if comment.author_id != v.id: abort(403) diff --git a/files/routes/users.py b/files/routes/users.py index de8be3825..25809fb07 100644 --- a/files/routes/users.py +++ b/files/routes/users.py @@ -646,13 +646,12 @@ def visitors(v): return render_template("viewers.html", v=v, viewers=viewers) -@app.get("/@") +@app.get("/@/posts") @auth_desired def u_username(username, v=None): u = get_user(username, v=v, include_blocks=True) - if username != u.username: - return redirect(SITE_FULL + request.full_path.replace(username, u.username)[:-1]) + if username != u.username: return redirect(f'/@{u.username}/posts') if u.reserved: if request.headers.get("Authorization") or request.headers.get("xhr"): abort(403, f"That username is reserved for: {u.reserved}") @@ -698,7 +697,7 @@ def u_username(username, v=None): if u.unban_utc: if request.headers.get("Authorization"): {"data": [x.json for x in listing]} - return render_template("userpage.html", + return render_template("userpage_submissions.html", unban=u.unban_string, u=u, v=v, @@ -712,7 +711,7 @@ def u_username(username, v=None): if request.headers.get("Authorization"): return {"data": [x.json for x in listing]} - return render_template("userpage.html", + return render_template("userpage_submissions.html", u=u, v=v, listing=listing, @@ -723,12 +722,13 @@ def u_username(username, v=None): is_following=(v and u.has_follower(v))) -@app.get("/@/comments") +@app.get("/@/") @auth_desired def u_username_comments(username, v=None): user = get_user(username, v=v, include_blocks=True) - if username != user.username: return redirect(f'/@{user.username}/comments') + if username != user.username: + return redirect(SITE_FULL + request.full_path.replace(username, user.username)[:-1]) u = user if u.reserved: @@ -935,13 +935,14 @@ def saved_posts(v, username): listing = get_posts(ids, v=v, eager=True) if request.headers.get("Authorization"): return {"data": [x.json for x in listing]} - return render_template("userpage.html", - u=v, - v=v, - listing=listing, - page=page, - next_exists=next_exists, - ) + return render_template( + "userpage_submissions.html", + u=v, + v=v, + listing=listing, + page=page, + next_exists=next_exists, + ) @app.get("/@/saved/comments") @@ -959,13 +960,15 @@ def saved_comments(v, username): if request.headers.get("Authorization"): return {"data": [x.json for x in listing]} - return render_template("userpage_comments.html", - u=v, - v=v, - listing=listing, - page=page, - next_exists=next_exists, - standalone=True) + return render_template( + "userpage_comments.html", + u=v, + v=v, + listing=listing, + page=page, + next_exists=next_exists, + standalone=True + ) @app.post("/fp/") diff --git a/files/routes/votes.py b/files/routes/votes.py index 4fcc518e6..bbc949867 100644 --- a/files/routes/votes.py +++ b/files/routes/votes.py @@ -65,7 +65,8 @@ def api_vote_post(post_id, new, v): new = int(new) # get the post - post = get_post(post_id) + post = get_post(post_id, v=v) + if getattr(post, 'is_blocking', False): abort(403, "Can't vote on things from users you've blocked") # get the old vote, if we have one vote = g.db.query(Vote).filter_by(user_id=v.id, submission_id=post.id).one_or_none() @@ -132,7 +133,8 @@ def api_vote_comment(comment_id, new, v): new = int(new) # get the comment - comment = get_comment(comment_id) + comment = get_comment(comment_id, v=v) + if getattr(comment, 'is_blocking', False): abort(403, "Can't vote on things from users you've blocked") # get the old vote, if we have one vote = g.db.query(CommentVote).filter_by(user_id=v.id, comment_id=comment.id).one_or_none() diff --git a/files/templates/admin/admin_home.html b/files/templates/admin/admin_home.html index 4c895620c..08a549dfd 100644 --- a/files/templates/admin/admin_home.html +++ b/files/templates/admin/admin_home.html @@ -17,13 +17,13 @@

Content

Filtering

Users

diff --git a/files/templates/admin/filtered_submissions.html b/files/templates/admin/filtered_submissions.html index dcc4518cc..3416b046a 100644 --- a/files/templates/admin/filtered_submissions.html +++ b/files/templates/admin/filtered_submissions.html @@ -23,13 +23,13 @@ diff --git a/files/templates/admin/removed_posts.html b/files/templates/admin/removed_posts.html index 7f35da0a0..62dffd062 100644 --- a/files/templates/admin/removed_posts.html +++ b/files/templates/admin/removed_posts.html @@ -20,13 +20,13 @@ diff --git a/files/templates/admin/reported_posts.html b/files/templates/admin/reported_posts.html index 50b542679..a965478ee 100644 --- a/files/templates/admin/reported_posts.html +++ b/files/templates/admin/reported_posts.html @@ -20,13 +20,13 @@ diff --git a/files/templates/comments.html b/files/templates/comments.html index 879709ef6..793ec7d87 100644 --- a/files/templates/comments.html +++ b/files/templates/comments.html @@ -201,23 +201,23 @@ + {# See https://github.com/themotte/rDrama/pull/642#issuecomment-1646649781 for info on this section of the code #} {% endblock %} diff --git a/files/templates/submission.html b/files/templates/submission.html index 4a64610fc..fac5b94a6 100644 --- a/files/templates/submission.html +++ b/files/templates/submission.html @@ -489,19 +489,19 @@ comments = JSON.parse(localStorage.getItem("old-comment-counts")) || {} lastCount = comments['{{p.id}}'] - if (lastCount) - { - {% for c in p.comments %} + + var commentsToCheck = [ + {% for c in p.comments -%} {% if not (v and v.id==c.author_id) and not c.voted %} - if ({{c.created_utc*1000}} > lastCount.t) - try { - document.getElementById("comment-{{c.id}}-only").classList.add('unread') - document.getElementById("comment-{{c.id}}").querySelector(".comment-user-info").innerHTML += "~new~"; - } - catch(e) {} - {% endif %} + [{{c.id}}, {{c.created_utc * 1000}}], + {%- endif -%} {% endfor %} - } + ]; + + commentsToCheck = commentsToCheck.filter(comment => comment[1] > lastCount.t) + .map(comment => comment[0]); + + if (lastCount) commentsAddUnreadIndicator(commentsToCheck); collapsedCommentStorageApply(); } diff --git a/files/templates/userpage.html b/files/templates/userpage.html index 4be9b061a..70375492b 100644 --- a/files/templates/userpage.html +++ b/files/templates/userpage.html @@ -520,23 +520,23 @@ {% endblock %} {% block content %} - +{% block userpage_nav %}
{% endif %} - -
- -
- -
- {% include "submission_listing.html" %} -
- -
- -
+{% endblock %} +{% block userpage_content required %}{% endblock %} {% if v %}
{% if v.patron or u.patron or v.alts_patron or u.alts_patron %}0{% else %}0.03{% endif %}
diff --git a/files/templates/userpage_comments.html b/files/templates/userpage_comments.html index b8f4890bd..55c9af2f1 100644 --- a/files/templates/userpage_comments.html +++ b/files/templates/userpage_comments.html @@ -1,67 +1,7 @@ {% extends "userpage.html" %} -{%- import 'component/sorting_time.html' as sorting_time -%} - -{% block content %} - - - -{% if not "saved" in request.full_path %} -
- -
-
- - -
- {{sorting_time.sort_dropdown(sort, t, SORTS_COMMENTS)}} -
-
-{% endif %} - +{% block userpage_content %}
-
- {% if listing %}
{% with comments=listing %} @@ -86,13 +26,6 @@
{% endif %} +
-
- -{% if v %} -
{% if v.patron or u.patron %}0{% else %}0.03{% endif %}
- -
{{u.username}}
-{% endif %} - {% endblock %} diff --git a/files/templates/userpage_submissions.html b/files/templates/userpage_submissions.html new file mode 100644 index 000000000..9cf790d18 --- /dev/null +++ b/files/templates/userpage_submissions.html @@ -0,0 +1,10 @@ +{% extends "userpage.html" %} +{% block userpage_content %} +
+
+
+ {% include "submission_listing.html" %} +
+
+
+{% endblock %} diff --git a/migrations/versions/2023_07_22_14_37_20_a23fe2f1515c_rename_approve_mod_actions.py b/migrations/versions/2023_07_22_14_37_20_a23fe2f1515c_rename_approve_mod_actions.py new file mode 100644 index 000000000..2b799ee20 --- /dev/null +++ b/migrations/versions/2023_07_22_14_37_20_a23fe2f1515c_rename_approve_mod_actions.py @@ -0,0 +1,25 @@ +"""Rename approve mod actions + +Revision ID: a23fe2f1515c +Revises: 7ae4658467d7 +Create Date: 2023-07-22 14:37:20.485816+00:00 + +""" +from alembic import op + + +# revision identifiers, used by Alembic. +revision = 'a23fe2f1515c' +down_revision = '7ae4658467d7' +branch_labels = None +depends_on = None + + +def upgrade(): + op.execute("UPDATE modactions SET kind='approve_post' WHERE kind='unremove_post';") + op.execute("UPDATE modactions SET kind='approve_comment' WHERE kind='unremove_comment';") + + +def downgrade(): + op.execute("UPDATE modactions SET kind='unremove_post' WHERE kind='approve_post';") + op.execute("UPDATE modactions SET kind='unremove_comment' WHERE kind='approve_comment';")