diff --git a/files/assets/js/filter_actions.js b/files/assets/js/filter_actions.js new file mode 100644 index 000000000..5c8ae212d --- /dev/null +++ b/files/assets/js/filter_actions.js @@ -0,0 +1,26 @@ +function filter_new_status(id, new_status) { + fetch('/admin/update_filter_status', { + method: 'POST', + body: JSON.stringify({ post_id: id, new_status: new_status, formkey: formkey() }), + headers: { 'content-type': 'application/json' } + }) + .then(response => response.json()) + .then(json => { + if(json.result === 'Update successful') { + const postRow = document.getElementById(`post-${id}`); + if(document.location.pathname === '/admin/filtered_submissions') { + postRow.parentElement.removeChild(postRow); + } else { + const approveLink = postRow.querySelector('a#filter-approve') + const removeLink = postRow.querySelector('a#filter-remove') + approveLink.parentElement.removeChild(approveLink); + removeLink.parentElement.removeChild(removeLink); + } + document.getElementById('toast-post-success-text').innerText = json.result; + bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-success')).show(); + } else { + document.getElementById('toast-post-error-text').innerText = "Error, please try again later." + bootstrap.Toast.getOrCreateInstance(document.getElementById('toast-post-error')).show(); + } + }); +} diff --git a/files/classes/submission.py b/files/classes/submission.py index adcae93e6..1fda0d16f 100644 --- a/files/classes/submission.py +++ b/files/classes/submission.py @@ -51,6 +51,7 @@ class Submission(Base): flair = Column(String) ban_reason = Column(String) embed_url = Column(String) + filter_state = Column(String) author = relationship("User", primaryjoin="Submission.author_id==User.id") oauth_app = relationship("OauthApp", viewonly=True) diff --git a/files/helpers/wrappers.py b/files/helpers/wrappers.py index 3d3280969..261946621 100644 --- a/files/helpers/wrappers.py +++ b/files/helpers/wrappers.py @@ -26,6 +26,10 @@ def get_logged_in_user(): if request.method != "GET": submitted_key = request.values.get("formkey") + if not submitted_key and request.is_json: + json = request.get_json(silent=True) + if json and type(json) is dict: + submitted_key = json.get('formkey') if not submitted_key: abort(401) if not v.validate_formkey(submitted_key): abort(401) diff --git a/files/routes/admin.py b/files/routes/admin.py index e8adb197a..c2c8a2ae6 100644 --- a/files/routes/admin.py +++ b/files/routes/admin.py @@ -400,6 +400,42 @@ def shadowbanned(v): users = [x for x in g.db.query(User).filter(User.shadowbanned != None).order_by(User.shadowbanned).all()] return render_template("shadowbanned.html", v=v, users=users) +@app.get("/admin/filtered_submissions") +@admin_level_required(2) +def filtered_submissions(v): + try: page = int(request.values.get('page', 1)) + except: page = 1 + + posts_just_ids = g.db.query(Submission) \ + .order_by(Submission.id.desc()) \ + .filter(Submission.filter_state == 'filtered') \ + .limit(26) \ + .offset(25 * (page - 1)) \ + .with_entities(Submission.id) + + post_ids = [x.id for x in posts_just_ids] + next_exists = (len(post_ids) > 25) + posts = get_posts(post_ids[:25], v=v) + + return render_template("admin/filtered_submissions.html", v=v, listing=posts, next_exists=next_exists, page=page, sort="new") + +@app.post("/admin/update_filter_status") +@admin_level_required(2) +def update_filter_status(v): + update_body = request.get_json() + new_status = update_body.get('new_status') + post_id = update_body.get('post_id') + if new_status not in ['normal', 'removed']: + return { 'result': f'Status of {new_status} is not permitted' } + + rows_updated = g.db.query(Submission).where(Submission.id == post_id).update({Submission.filter_state: new_status}) + + if rows_updated == 1: + g.db.commit() + return { 'result': 'Update successful' } + else: + return { 'result': f'Submission ID {post_id} does not exist' } + @app.get("/admin/image_posts") @admin_level_required(2) diff --git a/files/routes/front.py b/files/routes/front.py index 73c6d3941..3ec529df8 100644 --- a/files/routes/front.py +++ b/files/routes/front.py @@ -303,6 +303,12 @@ def frontlist(v=None, sort="hot", page=1, t="all", ids_only=True, ccmode="false" voted = [x[0] for x in g.db.query(Vote.submission_id).filter_by(user_id=v.id).all()] posts = posts.filter(Submission.id.notin_(voted)) + if not v or v.admin_level < 2: + filter_clause = (Submission.filter_state != 'filtered') & (Submission.filter_state != 'removed') + if v: + filter_clause = filter_clause | (Submission.author_id == v.id) + posts = posts.filter(filter_clause) + if sub: posts = posts.filter_by(sub=sub.name) elif v: posts = posts.filter(or_(Submission.sub == None, Submission.sub.notin_(v.all_blocks))) diff --git a/files/routes/posts.py b/files/routes/posts.py index b45a5656b..84bbd1748 100644 --- a/files/routes/posts.py +++ b/files/routes/posts.py @@ -1025,7 +1025,8 @@ def submit_post(v, sub=None): title=title[:500], title_html=title_html, sub=sub, - ghost=ghost + ghost=ghost, + filter_state='filtered' if v.admin_level == 0 else 'normal' ) g.db.add(post) diff --git a/files/templates/admin/admin_home.html b/files/templates/admin/admin_home.html index 6b705fe68..ee6d44235 100644 --- a/files/templates/admin/admin_home.html +++ b/files/templates/admin/admin_home.html @@ -17,6 +17,11 @@
  • Removed Posts/Comments
  • +

    Filtering

    + +

    Users