Add the ability to ban posts
This commit is contained in:
parent
782f069031
commit
1d00a8f60d
10 changed files with 146 additions and 1 deletions
|
@ -108,7 +108,7 @@
|
|||
</section>
|
||||
<% } %>
|
||||
|
||||
<% if (ctx.canFeaturePosts || ctx.canDeletePosts || ctx.canMergePosts) { %>
|
||||
<% if (ctx.canFeaturePosts || ctx.canDeletePosts || ctx.canMergePosts || ctx.canBanPosts) { %>
|
||||
<section class='management'>
|
||||
<ul>
|
||||
<% if (ctx.canFeaturePosts) { %>
|
||||
|
@ -120,6 +120,9 @@
|
|||
<% if (ctx.canDeletePosts) { %>
|
||||
<li><a href class='delete'>Delete this post</a></li>
|
||||
<% } %>
|
||||
<% if (ctx.canBanPosts) { %>
|
||||
<li><a href class='ban'>Ban this post</a></li>
|
||||
<% } %>
|
||||
</ul>
|
||||
</section>
|
||||
<% } %>
|
||||
|
|
|
@ -88,6 +88,9 @@ class PostMainController extends BasePostController {
|
|||
this._view.sidebarControl.addEventListener("delete", (e) =>
|
||||
this._evtDeletePost(e)
|
||||
);
|
||||
this._view.sidebarControl.addEventListener("ban", (e) =>
|
||||
this._evtBanPost(e)
|
||||
);
|
||||
this._view.sidebarControl.addEventListener("merge", (e) =>
|
||||
this._evtMergePost(e)
|
||||
);
|
||||
|
@ -165,6 +168,22 @@ class PostMainController extends BasePostController {
|
|||
);
|
||||
}
|
||||
|
||||
_evtBanPost(e) {
|
||||
this._view.sidebarControl.disableForm();
|
||||
this._view.sidebarControl.clearMessages();
|
||||
e.detail.post.ban().then(
|
||||
() => {
|
||||
misc.disableExitConfirmation();
|
||||
const ctx = router.show(uri.formatClientLink("posts"));
|
||||
ctx.controller.showSuccess("Post banned.");
|
||||
},
|
||||
(error) => {
|
||||
this._view.sidebarControl.showError(error.message);
|
||||
this._view.sidebarControl.enableForm();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
_evtUpdatePost(e) {
|
||||
this._view.sidebarControl.disableForm();
|
||||
this._view.sidebarControl.clearMessages();
|
||||
|
|
|
@ -46,6 +46,7 @@ class PostEditSidebarControl extends events.EventTarget {
|
|||
"posts:create:anonymous"
|
||||
),
|
||||
canDeletePosts: api.hasPrivilege("posts:delete"),
|
||||
canBanPosts: api.hasPrivilege("posts:ban"),
|
||||
canFeaturePosts: api.hasPrivilege("posts:feature"),
|
||||
canMergePosts: api.hasPrivilege("posts:merge"),
|
||||
})
|
||||
|
@ -186,6 +187,12 @@ class PostEditSidebarControl extends events.EventTarget {
|
|||
);
|
||||
}
|
||||
|
||||
if (this._banLinkNode) {
|
||||
this._banLinkNode.addEventListener("click", (e) =>
|
||||
this._evtBanClick(e)
|
||||
);
|
||||
}
|
||||
|
||||
this._postNotesOverlayControl.addEventListener("blur", (e) =>
|
||||
this._evtNoteBlur(e)
|
||||
);
|
||||
|
@ -301,6 +308,19 @@ class PostEditSidebarControl extends events.EventTarget {
|
|||
}
|
||||
}
|
||||
|
||||
_evtBanClick(e) {
|
||||
e.preventDefault();
|
||||
if (confirm("Are you sure you want to ban this post?")) {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("ban", {
|
||||
detail: {
|
||||
post: this._post,
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
_evtNoteTextChangeRequest(e) {
|
||||
if (this._editedNote) {
|
||||
this._editedNote.text = this._noteTextareaNode.value;
|
||||
|
@ -517,6 +537,11 @@ class PostEditSidebarControl extends events.EventTarget {
|
|||
return this._formNode.querySelector(".management .delete");
|
||||
}
|
||||
|
||||
get _banLinkNode() {
|
||||
return this._formNode.querySelector(".management .ban");
|
||||
}
|
||||
|
||||
|
||||
get _addNoteLinkNode() {
|
||||
return this._formNode.querySelector(".notes .add");
|
||||
}
|
||||
|
|
|
@ -334,6 +334,23 @@ class Post extends events.EventTarget {
|
|||
});
|
||||
}
|
||||
|
||||
ban() {
|
||||
return api
|
||||
.post(uri.formatApiLink("post-ban", this.id), {
|
||||
version: this._version
|
||||
})
|
||||
.then((response) => {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("ban", {
|
||||
detail: {
|
||||
post: this
|
||||
}
|
||||
})
|
||||
);
|
||||
return Promise.resolve();
|
||||
})
|
||||
}
|
||||
|
||||
delete() {
|
||||
return api
|
||||
.delete(uri.formatApiLink("post", this.id), {
|
||||
|
|
|
@ -116,6 +116,7 @@ privileges:
|
|||
'posts:bulk-edit:tags': power
|
||||
'posts:bulk-edit:safety': power
|
||||
'posts:bulk-edit:delete': power
|
||||
'posts:ban': moderator
|
||||
|
||||
'tags:create': regular
|
||||
'tags:edit:names': power
|
||||
|
|
|
@ -183,6 +183,18 @@ def delete_post(ctx: rest.Context, params: Dict[str, str]) -> rest.Response:
|
|||
return {}
|
||||
|
||||
|
||||
@rest.routes.post("/post-ban/(?P<post_id>[^/]+)/?")
|
||||
def ban_post(ctx: rest.Context, params: Dict[str, str]) -> rest.Response:
|
||||
auth.verify_privilege(ctx.user, "posts:ban")
|
||||
post = _get_post(params)
|
||||
versions.verify_version(post, ctx)
|
||||
posts.ban(posts.create_ban(post))
|
||||
snapshots.delete(post, ctx.user)
|
||||
posts.delete(post)
|
||||
ctx.session.commit()
|
||||
return {}
|
||||
|
||||
|
||||
@rest.routes.post("/post-merge/?")
|
||||
def merge_posts(
|
||||
ctx: rest.Context, _params: Dict[str, str] = {}
|
||||
|
|
|
@ -50,6 +50,12 @@ class PostAlreadyUploadedError(errors.ValidationError):
|
|||
)
|
||||
|
||||
|
||||
class PostBannedError(errors.ValidationError):
|
||||
def __init__(self, message: str = "This file was banned", extra_fields: Dict[str, str] = None) -> None:
|
||||
super().__init__(message, extra_fields)
|
||||
|
||||
|
||||
|
||||
class InvalidPostIdError(errors.ValidationError):
|
||||
pass
|
||||
|
||||
|
@ -425,6 +431,15 @@ def create_post(
|
|||
return post, new_tags
|
||||
|
||||
|
||||
def create_ban(post: model.Post) -> model.PostBan:
|
||||
ban = model.PostBan()
|
||||
ban.checksum = post.checksum
|
||||
ban.time = datetime.utcnow()
|
||||
|
||||
db.session.add(ban)
|
||||
return ban
|
||||
|
||||
|
||||
def update_post_safety(post: model.Post, safety: str) -> None:
|
||||
assert post
|
||||
safety = util.flip(SAFETY_MAP).get(safety, None)
|
||||
|
@ -634,6 +649,7 @@ def update_post_content(post: model.Post, content: Optional[bytes]) -> None:
|
|||
.filter(model.Post.post_id != post.post_id)
|
||||
.one_or_none()
|
||||
)
|
||||
|
||||
if (
|
||||
other_post
|
||||
and other_post.post_id
|
||||
|
@ -641,6 +657,15 @@ def update_post_content(post: model.Post, content: Optional[bytes]) -> None:
|
|||
):
|
||||
raise PostAlreadyUploadedError(other_post)
|
||||
|
||||
|
||||
post_ban = (db.session.query(model.PostBan)
|
||||
.filter(model.PostBan.checksum == post.checksum)
|
||||
.one_or_none()
|
||||
)
|
||||
if (post_ban):
|
||||
raise PostBannedError()
|
||||
|
||||
|
||||
if update_signature:
|
||||
purge_post_signature(post)
|
||||
post.signature = generate_post_signature(post, content)
|
||||
|
@ -806,6 +831,11 @@ def delete(post: model.Post) -> None:
|
|||
db.session.delete(post)
|
||||
|
||||
|
||||
def ban(ban: model.PostBan) -> None:
|
||||
assert ban
|
||||
db.session.add(ban)
|
||||
|
||||
|
||||
def merge_posts(
|
||||
source_post: model.Post, target_post: model.Post, replace_content: bool
|
||||
) -> None:
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
'''
|
||||
create ban table
|
||||
|
||||
Revision ID: cc2956cb8ee7
|
||||
Created at: 2023-05-12 02:04:22.592006
|
||||
'''
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
|
||||
|
||||
revision = 'cc2956cb8ee7'
|
||||
down_revision = 'adcd63ff76a2'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
def upgrade():
|
||||
op.create_table(
|
||||
"post_ban",
|
||||
sa.Column("id", sa.Integer(), nullable=False),
|
||||
sa.Column("checksum", sa.Unicode(64), nullable=False),
|
||||
sa.Column("time", sa.DateTime, nullable=False),
|
||||
sa.PrimaryKeyConstraint("id")
|
||||
)
|
||||
op.create_unique_constraint("uq_ban_checksum", "post_ban", ["checksum"])
|
||||
|
||||
def downgrade():
|
||||
op.drop_table("post_ban")
|
|
@ -5,6 +5,7 @@ from szurubooru.model.pool import Pool, PoolName, PoolPost
|
|||
from szurubooru.model.pool_category import PoolCategory
|
||||
from szurubooru.model.post import (
|
||||
Post,
|
||||
PostBan,
|
||||
PostFavorite,
|
||||
PostFeature,
|
||||
PostNote,
|
||||
|
|
|
@ -94,6 +94,14 @@ class PostFavorite(Base):
|
|||
)
|
||||
|
||||
|
||||
class PostBan(Base):
|
||||
__tablename__ = "post_ban"
|
||||
|
||||
ban_id = sa.Column("id", sa.Integer, primary_key=True)
|
||||
checksum = sa.Column("checksum", sa.Unicode(64), nullable=False)
|
||||
time = sa.Column("time", sa.DateTime, nullable=False)
|
||||
|
||||
|
||||
class PostNote(Base):
|
||||
__tablename__ = "post_note"
|
||||
|
||||
|
|
Reference in a new issue