From fd2ca001afdb50e2a9e2a35f1da3efecead236e3 Mon Sep 17 00:00:00 2001 From: noirscape Date: Wed, 4 Jan 2023 17:16:40 +0100 Subject: [PATCH] server: poolpost nearby implementation --- doc/API.md | 37 ++++++++++++++++++++++++ server/szurubooru/api/post_api.py | 15 ++++++++-- server/szurubooru/func/posts.py | 48 ++++++++++++++++++++++++++++++- 3 files changed, 97 insertions(+), 3 deletions(-) diff --git a/doc/API.md b/doc/API.md index 63a50a2f..5fc33084 100644 --- a/doc/API.md +++ b/doc/API.md @@ -975,6 +975,43 @@ data. Retrieves information about posts that are before or after an existing post. +## Getting pools around post +- **Request** + + `GET /post//pools-nearby` + +- **Output** + + ```json5 + [ + { + "pool": , + "firstPost": , + "lastPost": , + "nextPost": , + "previousPost": + }, + ... + ] + ``` + +- **Field meaning** + +- ``: The associated [micro pool resource](#micro-pool). +- `firstPost`: A [micro post resource](#micro-post) that displays the first post in the pool. +- `lastPost`: A [micro post resource](#micro-post) that displays the last post in the pool. +- `nextPost`: A [micro post resource](#micro-post) that displays the next post in the pool. +- `prevPost`: A [micro post resource](#micro-post) that displays the previous post in the pool. + +- **Errors** + + - the post does not exist + - privileges are too low + +- **Description** + + Retrieves extra information about any pools that the post is in. + ## Deleting post - **Request** diff --git a/server/szurubooru/api/post_api.py b/server/szurubooru/api/post_api.py index daba7f7e..34a2136c 100644 --- a/server/szurubooru/api/post_api.py +++ b/server/szurubooru/api/post_api.py @@ -5,12 +5,10 @@ from szurubooru import db, errors, model, rest, search from szurubooru.func import ( auth, favorites, - mime, posts, scores, serialization, snapshots, - tags, versions, ) @@ -283,6 +281,19 @@ def get_posts_around( ctx, post_id, lambda post: _serialize_post(ctx, post) ) +@rest.routes.get("/post/(?P[^/]+)/pools-nearby/?") +def get_pools_around( + ctx: rest.Context, params: Dict[str, str] +) -> rest.Response: + auth.verify_privilege(ctx.user, "posts:list") + auth.verify_privilege(ctx.user, "posts:view") + auth.verify_privilege(ctx.user, "pools:list") + _search_executor_config.user = ctx.user + post = _get_post(params) + results = posts.get_pools_nearby(post) + return posts.serialize_pool_posts_nearby(results) + + @rest.routes.post("/posts/reverse-search/?") def get_posts_by_image( diff --git a/server/szurubooru/func/posts.py b/server/szurubooru/func/posts.py index be2259cf..eeea4509 100644 --- a/server/szurubooru/func/posts.py +++ b/server/szurubooru/func/posts.py @@ -1,5 +1,6 @@ import hmac import logging +from collections import namedtuple from datetime import datetime from typing import Any, Callable, Dict, List, Optional, Tuple @@ -15,7 +16,6 @@ from szurubooru.func import ( pools, scores, serialization, - snapshots, tags, users, util, @@ -968,3 +968,49 @@ def search_by_image(image_content: bytes) -> List[Tuple[float, model.Post]]: ] else: return [] + +PoolPostsNearby = namedtuple('PoolPostsNearby', 'pool first_post prev_post next_post last_post') +def get_pools_nearby( + post: model.Post +) -> List[PoolPostsNearby]: + response = [] + pools = post.pools + + for pool in pools: + prev_post_id = None + next_post_id = None + break_loop = False + + for pool_post in pools.posts: + next_post_id = pool_post.post_id + + if break_loop == True: + break + + if post.id == pool_post.post_id: + break_loop = True + + prev_post_id = pool_post.post_id + + resp_entry = PoolPostsNearby( + pool=pool, + first_post=pool.posts[0].post_id, + last_post=pool.posts[-1].post_id, + prev_post=next_post_id, + next_post=prev_post_id, + ) + response.append(resp_entry) + return response + +def serialize_pool_posts_nearby( + nearby: List[PoolPostsNearby] +) -> Optional[rest.Response]: + return [ + { + "pool": pools.serialize_pool(entry.pool), + "firstPost": serialize_micro_post(try_get_post_by_id(entry.first_post)), + "lastPost": serialize_micro_post(try_get_post_by_id(entry.last_post)), + "prevPost": serialize_micro_post(try_get_post_by_id(entry.prev_post)), + "nextPost": serialize_micro_post(try_get_post_by_id(entry.first_post)), + } for entry in nearby + ]