Fix some bugs, document new API
This commit is contained in:
parent
bd8cdc8509
commit
002f49d7db
11 changed files with 95 additions and 39 deletions
|
@ -1,9 +1,9 @@
|
||||||
<tr data-category='<%- ctx.postBan.checksum %>'><%
|
<tr data-category='<%- ctx.postBan.checksum %>'>
|
||||||
<td class='name'>
|
<td class='name'>
|
||||||
<%- ctx.postBan.checksum %>
|
<%- ctx.postBan.checksum %>
|
||||||
</td>
|
</td>
|
||||||
<td class='time'>
|
<td class='time'>
|
||||||
<%- ctx.makeRelativeTime(ctx.postBan.time) %>
|
<%= ctx.makeRelativeTime(ctx.postBan.time) %>
|
||||||
</td>
|
</td>
|
||||||
<% if (ctx.canDelete) { %>
|
<% if (ctx.canDelete) { %>
|
||||||
<td class='remove'>
|
<td class='remove'>
|
||||||
|
|
|
@ -53,6 +53,9 @@ class TopNavigationController {
|
||||||
if (!api.hasPrivilege("pools:list")) {
|
if (!api.hasPrivilege("pools:list")) {
|
||||||
topNavigation.hide("pools");
|
topNavigation.hide("pools");
|
||||||
}
|
}
|
||||||
|
if (!api.hasPrivilege("posts:ban:list")) {
|
||||||
|
topNavigation.hide("banned-posts");
|
||||||
|
}
|
||||||
if (api.isLoggedIn()) {
|
if (api.isLoggedIn()) {
|
||||||
if (!api.hasPrivilege("users:create:any")) {
|
if (!api.hasPrivilege("users:create:any")) {
|
||||||
topNavigation.hide("register");
|
topNavigation.hide("register");
|
||||||
|
|
|
@ -26,8 +26,8 @@ class BannedPostList extends AbstractList {
|
||||||
|
|
||||||
save() {
|
save() {
|
||||||
let promises = [];
|
let promises = [];
|
||||||
for (let BannedPost of this._deletedBans) {
|
for (let bannedPost of this._deletedBans) {
|
||||||
promises.push(BannedPost.delete());
|
promises.push(bannedPost.delete());
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.all(promises).then((response) => {
|
return Promise.all(promises).then((response) => {
|
||||||
|
@ -37,7 +37,7 @@ class BannedPostList extends AbstractList {
|
||||||
}
|
}
|
||||||
|
|
||||||
_evtBannedPostDeleted(e) {
|
_evtBannedPostDeleted(e) {
|
||||||
this._deletedBans.push(e.detail.BannedPost);
|
this._deletedBans.push(e.detail.bannedPost);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -336,7 +336,8 @@ class Post extends events.EventTarget {
|
||||||
|
|
||||||
ban() {
|
ban() {
|
||||||
return api
|
return api
|
||||||
.post(uri.formatApiLink("post-ban", this.id), {
|
.post(uri.formatApiLink("post-ban"), {
|
||||||
|
post_id: this.id,
|
||||||
version: this._version
|
version: this._version
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
|
|
|
@ -90,6 +90,7 @@ function _makeTopNavigation() {
|
||||||
ret.add("login", new TopNavigationItem("L", "Log in", "login"));
|
ret.add("login", new TopNavigationItem("L", "Log in", "login"));
|
||||||
ret.add("logout", new TopNavigationItem("O", "Logout", "logout"));
|
ret.add("logout", new TopNavigationItem("O", "Logout", "logout"));
|
||||||
ret.add("help", new TopNavigationItem("E", "Help", "help"));
|
ret.add("help", new TopNavigationItem("E", "Help", "help"));
|
||||||
|
ret.add("banned-posts", new TopNavigationItem("B", "Banned posts", "banned-posts"));
|
||||||
ret.add(
|
ret.add(
|
||||||
"settings",
|
"settings",
|
||||||
new TopNavigationItem(null, "<i class='fa fa-cog'></i>", "settings")
|
new TopNavigationItem(null, "<i class='fa fa-cog'></i>", "settings")
|
||||||
|
|
|
@ -83,7 +83,7 @@ class BannedPostsView extends events.EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
_evtBannedPostDeleted(e) {
|
_evtBannedPostDeleted(e) {
|
||||||
this._removeBannedPostRowNode(e.detail.poolCategory);
|
this._removeBannedPostRowNode(e.detail.bannedPost);
|
||||||
}
|
}
|
||||||
|
|
||||||
_evtDeleteButtonClick(e, rowNode, link) {
|
_evtDeleteButtonClick(e, rowNode, link) {
|
||||||
|
|
65
doc/API.md
65
doc/API.md
|
@ -912,7 +912,7 @@ data.
|
||||||
|
|
||||||
- **Output**
|
- **Output**
|
||||||
|
|
||||||
A [post resource](#post).
|
A [post resource](#banned-post).
|
||||||
|
|
||||||
- **Errors**
|
- **Errors**
|
||||||
|
|
||||||
|
@ -1006,15 +1006,35 @@ data.
|
||||||
Deletes existing post. Related posts and tags are kept.
|
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
|
## Banning post
|
||||||
- **Request**
|
- **Request**
|
||||||
|
|
||||||
`POST /post-ban/<id>`
|
`POST /post-ban`
|
||||||
|
|
||||||
- **Input**
|
- **Input**
|
||||||
|
|
||||||
```json5
|
```json5
|
||||||
{
|
{
|
||||||
|
"post_id": <post id>
|
||||||
"version": <version>
|
"version": <version>
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -1039,6 +1059,27 @@ data.
|
||||||
Related posts and tags are kept.
|
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
|
## Merging posts
|
||||||
- **Request**
|
- **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`,
|
A [pool resource](#pool) stripped down to `id`, `names`, `category`,
|
||||||
`description` and `postCount` fields.
|
`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
|
## Comment
|
||||||
**Description**
|
**Description**
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Dict, List, Optional
|
from typing import Dict, List, Optional
|
||||||
from server.szurubooru.api import post_api
|
from szurubooru.api import post_api
|
||||||
from server.szurubooru.func import posts
|
from szurubooru.func import posts
|
||||||
from server.szurubooru.model.bans import PostBan
|
from szurubooru.model.bans import PostBan
|
||||||
|
|
||||||
from szurubooru import db, errors, model, rest, search
|
from szurubooru import db, errors, model, rest, search
|
||||||
from szurubooru.func import (
|
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>[^/]+)/?")
|
@rest.routes.delete("/post-ban/(?P<image_hash>[^/]+)/?")
|
||||||
def unban_post(ctx: rest.Context, params: Dict[str, str]) -> rest.Response:
|
def unban_post(ctx: rest.Context, params: Dict[str, str]) -> rest.Response:
|
||||||
auth.verify_privilege(ctx.user, "posts:ban:delete")
|
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 {}
|
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/?")
|
@rest.routes.get("/post-ban/?")
|
||||||
def get_bans(ctx: rest.Context, _params: Dict[str, str] = {}) -> rest.Response:
|
def get_bans(ctx: rest.Context, _params: Dict[str, str] = {}) -> rest.Response:
|
||||||
auth.verify_privilege(ctx.user, "posts:ban:list")
|
auth.verify_privilege(ctx.user, "posts:ban:list")
|
||||||
return _search_executor.execute_and_serialize(
|
return _search_executor.execute_and_serialize(
|
||||||
ctx, lambda tag: _serialize(ctx, tag)
|
ctx, lambda ban: _serialize(ctx, ban)
|
||||||
)
|
)
|
||||||
|
|
|
@ -15,7 +15,7 @@ class HashNotBannedError(errors.ValidationError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TagSerializer(serialization.BaseSerializer):
|
class BanSerializer(serialization.BaseSerializer):
|
||||||
def __init__(self, ban: model.PostBan) -> None:
|
def __init__(self, ban: model.PostBan) -> None:
|
||||||
self.ban = ban
|
self.ban = ban
|
||||||
|
|
||||||
|
@ -65,4 +65,4 @@ def serialize_ban(
|
||||||
) -> Optional[rest.Response]:
|
) -> Optional[rest.Response]:
|
||||||
if not ban:
|
if not ban:
|
||||||
return None
|
return None
|
||||||
return serialization.BaseSerializer(ban).serialize(options)
|
return BanSerializer(ban).serialize(options)
|
||||||
|
|
|
@ -4,7 +4,7 @@ from datetime import datetime
|
||||||
from typing import Any, Callable, Dict, List, Optional, Tuple
|
from typing import Any, Callable, Dict, List, Optional, Tuple
|
||||||
|
|
||||||
import sqlalchemy as sa
|
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 import config, db, errors, model, rest
|
||||||
from szurubooru.func import (
|
from szurubooru.func import (
|
||||||
|
|
|
@ -14,17 +14,7 @@ from szurubooru.search.typing import SaColumn, SaQuery
|
||||||
|
|
||||||
class BanSearchConfig(BaseSearchConfig):
|
class BanSearchConfig(BaseSearchConfig):
|
||||||
def create_filter_query(self, _disable_eager_loads: bool) -> SaQuery:
|
def create_filter_query(self, _disable_eager_loads: bool) -> SaQuery:
|
||||||
strategy = (
|
return db.session.query(model.PostBan)
|
||||||
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)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def create_count_query(self, _disable_eager_loads: bool) -> SaQuery:
|
def create_count_query(self, _disable_eager_loads: bool) -> SaQuery:
|
||||||
return db.session.query(model.PostBan)
|
return db.session.query(model.PostBan)
|
||||||
|
|
Loading…
Reference in a new issue