Fix some bugs, document new API

This commit is contained in:
rebel 2023-05-17 03:30:49 +02:00
parent bd8cdc8509
commit 002f49d7db
11 changed files with 95 additions and 39 deletions

View file

@ -1,9 +1,9 @@
<tr data-category='<%- ctx.postBan.checksum %>'><%
<tr data-category='<%- ctx.postBan.checksum %>'>
<td class='name'>
<%- ctx.postBan.checksum %>
</td>
<td class='time'>
<%- ctx.makeRelativeTime(ctx.postBan.time) %>
<%= ctx.makeRelativeTime(ctx.postBan.time) %>
</td>
<% if (ctx.canDelete) { %>
<td class='remove'>

View file

@ -53,6 +53,9 @@ class TopNavigationController {
if (!api.hasPrivilege("pools:list")) {
topNavigation.hide("pools");
}
if (!api.hasPrivilege("posts:ban:list")) {
topNavigation.hide("banned-posts");
}
if (api.isLoggedIn()) {
if (!api.hasPrivilege("users:create:any")) {
topNavigation.hide("register");

View file

@ -26,8 +26,8 @@ class BannedPostList extends AbstractList {
save() {
let promises = [];
for (let BannedPost of this._deletedBans) {
promises.push(BannedPost.delete());
for (let bannedPost of this._deletedBans) {
promises.push(bannedPost.delete());
}
return Promise.all(promises).then((response) => {
@ -37,7 +37,7 @@ class BannedPostList extends AbstractList {
}
_evtBannedPostDeleted(e) {
this._deletedBans.push(e.detail.BannedPost);
this._deletedBans.push(e.detail.bannedPost);
}
}

View file

@ -336,7 +336,8 @@ class Post extends events.EventTarget {
ban() {
return api
.post(uri.formatApiLink("post-ban", this.id), {
.post(uri.formatApiLink("post-ban"), {
post_id: this.id,
version: this._version
})
.then((response) => {

View file

@ -90,6 +90,7 @@ function _makeTopNavigation() {
ret.add("login", new TopNavigationItem("L", "Log in", "login"));
ret.add("logout", new TopNavigationItem("O", "Logout", "logout"));
ret.add("help", new TopNavigationItem("E", "Help", "help"));
ret.add("banned-posts", new TopNavigationItem("B", "Banned posts", "banned-posts"));
ret.add(
"settings",
new TopNavigationItem(null, "<i class='fa fa-cog'></i>", "settings")

View file

@ -83,7 +83,7 @@ class BannedPostsView extends events.EventTarget {
}
_evtBannedPostDeleted(e) {
this._removeBannedPostRowNode(e.detail.poolCategory);
this._removeBannedPostRowNode(e.detail.bannedPost);
}
_evtDeleteButtonClick(e, rowNode, link) {

View file

@ -912,7 +912,7 @@ data.
- **Output**
A [post resource](#post).
A [post resource](#banned-post).
- **Errors**
@ -1006,15 +1006,35 @@ data.
Deletes existing post. Related posts and tags are kept.
## Listing banned posts
- **Request**
`GET /post-ban`
- **Output**
An [unpaged search result](#unpaged-search-result) of [banned posts](#postban).
- **Errors**
- the post does not exist
- privileges are too low
- **Description**
Retrieves information about an existing post.
## Banning post
- **Request**
`POST /post-ban/<id>`
`POST /post-ban`
- **Input**
```json5
{
"post_id": <post id>
"version": <version>
}
```
@ -1039,6 +1059,27 @@ data.
Related posts and tags are kept.
## Undoing post ban
- **Request**
`DELETE /post-ban/<image_hash>`
- **Output**
```json5
{}
```
- **Errors**
- there is no banned image with that hash
- privileges are too low
- **Description**
Removes a banned image from the ban list. Takes a SHA-1 hash of the image as input.
## Merging posts
- **Request**
@ -2617,6 +2658,26 @@ An ordered list of posts, with a description and category.
A [pool resource](#pool) stripped down to `id`, `names`, `category`,
`description` and `postCount` fields.
## Banned post
**Description**
A record of a post that has been banned.
**Structure**
```json5
{
"checksum": <sha-hash>,
"time": <time-of-ban>
}
```
**Field meaning**
- `<sha-hash>`: SHA-1 hash of an image that has been banned
- `<time-of-ban>`: time the post was banned
## Comment
**Description**

View file

@ -1,8 +1,8 @@
from datetime import datetime
from typing import Dict, List, Optional
from server.szurubooru.api import post_api
from server.szurubooru.func import posts
from server.szurubooru.model.bans import PostBan
from szurubooru.api import post_api
from szurubooru.func import posts
from szurubooru.model.bans import PostBan
from szurubooru import db, errors, model, rest, search
from szurubooru.func import (
@ -29,18 +29,6 @@ def _serialize(ctx: rest.Context, ban: model.PostBan) -> rest.Response:
)
@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:create")
post = post_api._get_post(params)
versions.verify_version(post, ctx)
posts.ban(bans.create_ban(post))
snapshots.delete(post, ctx.user)
posts.delete(post)
ctx.session.commit()
return {}
@rest.routes.delete("/post-ban/(?P<image_hash>[^/]+)/?")
def unban_post(ctx: rest.Context, params: Dict[str, str]) -> rest.Response:
auth.verify_privilege(ctx.user, "posts:ban:delete")
@ -50,9 +38,21 @@ def unban_post(ctx: rest.Context, params: Dict[str, str]) -> rest.Response:
return {}
@rest.routes.post("/post-ban/?")
def ban_post(ctx: rest.Context, params: Dict[str, str]) -> rest.Response:
auth.verify_privilege(ctx.user, "posts:ban:create")
# post = post_api._get_post(params)
post = posts.get_post_by_id(ctx.get_param_as_int("post_id"))
versions.verify_version(post, ctx)
posts.ban(bans.create_ban(post))
snapshots.delete(post, ctx.user)
posts.delete(post)
ctx.session.commit()
return {}
@rest.routes.get("/post-ban/?")
def get_bans(ctx: rest.Context, _params: Dict[str, str] = {}) -> rest.Response:
auth.verify_privilege(ctx.user, "posts:ban:list")
return _search_executor.execute_and_serialize(
ctx, lambda tag: _serialize(ctx, tag)
ctx, lambda ban: _serialize(ctx, ban)
)

View file

@ -15,7 +15,7 @@ class HashNotBannedError(errors.ValidationError):
pass
class TagSerializer(serialization.BaseSerializer):
class BanSerializer(serialization.BaseSerializer):
def __init__(self, ban: model.PostBan) -> None:
self.ban = ban
@ -65,4 +65,4 @@ def serialize_ban(
) -> Optional[rest.Response]:
if not ban:
return None
return serialization.BaseSerializer(ban).serialize(options)
return BanSerializer(ban).serialize(options)

View file

@ -4,7 +4,7 @@ from datetime import datetime
from typing import Any, Callable, Dict, List, Optional, Tuple
import sqlalchemy as sa
from server.szurubooru.func.bans import PostBannedError
from szurubooru.func.bans import PostBannedError
from szurubooru import config, db, errors, model, rest
from szurubooru.func import (

View file

@ -14,17 +14,7 @@ from szurubooru.search.typing import SaColumn, SaQuery
class BanSearchConfig(BaseSearchConfig):
def create_filter_query(self, _disable_eager_loads: bool) -> SaQuery:
strategy = (
sa.orm.lazyload if _disable_eager_loads else sa.orm.subqueryload
)
return (
db.session.query(model.PostBan)
.options(
sa.orm.defer(model.PostBan.checksum),
sa.orm.defer(model.PostBan.time),
sa.orm.defer(model.PostBan.ban_id)
)
)
return db.session.query(model.PostBan)
def create_count_query(self, _disable_eager_loads: bool) -> SaQuery:
return db.session.query(model.PostBan)