Merge f91de88698
into 5596f53744
This commit is contained in:
commit
f7b9c9b175
14 changed files with 373 additions and 4 deletions
34
client/css/pool-navigator-control.styl
Normal file
34
client/css/pool-navigator-control.styl
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
@import colors
|
||||||
|
|
||||||
|
.pool-navigator-container
|
||||||
|
padding: 0
|
||||||
|
margin: 0 auto
|
||||||
|
|
||||||
|
.pool-info-wrapper
|
||||||
|
box-sizing: border-box
|
||||||
|
width: 100%
|
||||||
|
margin: 0 0 1em 0
|
||||||
|
display: flex
|
||||||
|
padding: 0.5em 1em
|
||||||
|
border: 1px solid $pool-navigator-border-color
|
||||||
|
background: $pool-navigator-background-color
|
||||||
|
|
||||||
|
.pool-name
|
||||||
|
flex: 1 1;
|
||||||
|
text-align: center;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
-o-text-overflow: ellipsis;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
|
||||||
|
.first, .last
|
||||||
|
flex-basis: 1em;
|
||||||
|
|
||||||
|
.first, .prev, .next, .last
|
||||||
|
flex: 0 1;
|
||||||
|
margin: 0 .25em;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
|
||||||
|
.darktheme .pool-navigator-container
|
||||||
|
background: $pool-navigator-header-background-color-darktheme
|
9
client/css/pool-navigator-list.styl
Normal file
9
client/css/pool-navigator-list.styl
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
.pool-navigators>ul
|
||||||
|
list-style-type: none
|
||||||
|
margin: 0
|
||||||
|
padding: 0
|
||||||
|
|
||||||
|
>li
|
||||||
|
margin-bottom: 1em
|
||||||
|
&:last-child
|
||||||
|
margin-bottom: 0
|
49
client/html/pool_navigator.tpl
Normal file
49
client/html/pool_navigator.tpl
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
<div class='pool-navigator-container'>
|
||||||
|
<div class='pool-info-wrapper'>
|
||||||
|
<span class='first'>
|
||||||
|
<% if (ctx.canViewPosts && ctx.firstPost) { %>
|
||||||
|
<a class='<%- ctx.linkClass %>' href='<%= ctx.getPostUrl(ctx.firstPost.id, ctx.parameters) %>'>
|
||||||
|
<% } %>
|
||||||
|
«
|
||||||
|
<% if (ctx.canViewPosts && ctx.firstPost) { %>
|
||||||
|
</a>
|
||||||
|
<% } %>
|
||||||
|
</span>
|
||||||
|
<span class='prev'>
|
||||||
|
<% if (ctx.canViewPosts && ctx.previousPost) { %>
|
||||||
|
<a class='<%- ctx.linkClass %>' href='<%= ctx.getPostUrl(ctx.previousPost.id, ctx.parameters) %>'>
|
||||||
|
<% } %>
|
||||||
|
‹ prev
|
||||||
|
<% if (ctx.canViewPosts && ctx.previousPost) { %>
|
||||||
|
</a>
|
||||||
|
<% } %>
|
||||||
|
</span>
|
||||||
|
<span class='pool-name'>
|
||||||
|
<% if (ctx.canViewPools) { %>
|
||||||
|
<a class='<%- ctx.linkClass %>' href='<%= ctx.formatClientLink("pool", ctx.pool.id) %>'>
|
||||||
|
<% } %>
|
||||||
|
Pool: <%- ctx.pool.names[0] %>
|
||||||
|
<% if (ctx.canViewPools) { %>
|
||||||
|
</a>
|
||||||
|
<% } %>
|
||||||
|
</span>
|
||||||
|
<span class='next'>
|
||||||
|
<% if (ctx.canViewPosts && ctx.nextPost) { %>
|
||||||
|
<a class='<%- ctx.linkClass %>' href='<%= ctx.getPostUrl(ctx.nextPost.id, ctx.parameters) %>'>
|
||||||
|
<% } %>
|
||||||
|
next ›
|
||||||
|
<% if (ctx.canViewPosts && ctx.nextPost) { %>
|
||||||
|
</a>
|
||||||
|
<% } %>
|
||||||
|
</span>
|
||||||
|
<span class='last'>
|
||||||
|
<% if (ctx.canViewPosts && ctx.lastPost) { %>
|
||||||
|
<a class='<%- ctx.linkClass %>' href='<%= ctx.getPostUrl(ctx.lastPost.id, ctx.parameters) %>'>
|
||||||
|
<% } %>
|
||||||
|
»
|
||||||
|
<% if (ctx.canViewPosts && ctx.lastPost) { %>
|
||||||
|
</a>
|
||||||
|
<% } %>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
4
client/html/pool_navigator_list.tpl
Normal file
4
client/html/pool_navigator_list.tpl
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<div class='pool-navigators'>
|
||||||
|
<ul>
|
||||||
|
</ul>
|
||||||
|
</div>
|
|
@ -54,6 +54,10 @@
|
||||||
<div class='content'>
|
<div class='content'>
|
||||||
<div class='post-container'></div>
|
<div class='post-container'></div>
|
||||||
|
|
||||||
|
<% if (ctx.canListPools && ctx.canViewPools) { %>
|
||||||
|
<div class='pool-navigators-container'></div>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
<% if (ctx.canListComments) { %>
|
<% if (ctx.canListComments) { %>
|
||||||
<div class='comments-container'></div>
|
<div class='comments-container'></div>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
|
@ -11,11 +11,17 @@ const PostList = require("../models/post_list.js");
|
||||||
const PostMainView = require("../views/post_main_view.js");
|
const PostMainView = require("../views/post_main_view.js");
|
||||||
const BasePostController = require("./base_post_controller.js");
|
const BasePostController = require("./base_post_controller.js");
|
||||||
const EmptyView = require("../views/empty_view.js");
|
const EmptyView = require("../views/empty_view.js");
|
||||||
|
const PoolNavigatorListControl = require("../controls/pool_navigator_list_control.js");
|
||||||
|
|
||||||
class PostMainController extends BasePostController {
|
class PostMainController extends BasePostController {
|
||||||
constructor(ctx, editMode) {
|
constructor(ctx, editMode) {
|
||||||
super(ctx);
|
super(ctx);
|
||||||
|
|
||||||
|
let poolPostsNearby = Promise.resolve({results: []});
|
||||||
|
if (api.hasPrivilege("pools:list") && api.hasPrivilege("pools:view")) {
|
||||||
|
poolPostsNearby = PostList.getNearbyPoolPosts(ctx.parameters.id);
|
||||||
|
}
|
||||||
|
|
||||||
let parameters = ctx.parameters;
|
let parameters = ctx.parameters;
|
||||||
Promise.all([
|
Promise.all([
|
||||||
Post.get(ctx.parameters.id),
|
Post.get(ctx.parameters.id),
|
||||||
|
@ -23,9 +29,10 @@ class PostMainController extends BasePostController {
|
||||||
ctx.parameters.id,
|
ctx.parameters.id,
|
||||||
parameters ? parameters.query : null
|
parameters ? parameters.query : null
|
||||||
),
|
),
|
||||||
|
poolPostsNearby
|
||||||
]).then(
|
]).then(
|
||||||
(responses) => {
|
(responses) => {
|
||||||
const [post, aroundResponse] = responses;
|
const [post, aroundResponse, poolPostsNearby] = responses;
|
||||||
|
|
||||||
// remove junk from query, but save it into history so that it can
|
// remove junk from query, but save it into history so that it can
|
||||||
// be still accessed after history navigation / page refresh
|
// be still accessed after history navigation / page refresh
|
||||||
|
@ -44,6 +51,7 @@ class PostMainController extends BasePostController {
|
||||||
this._post = post;
|
this._post = post;
|
||||||
this._view = new PostMainView({
|
this._view = new PostMainView({
|
||||||
post: post,
|
post: post,
|
||||||
|
poolPostsNearby: poolPostsNearby,
|
||||||
editMode: editMode,
|
editMode: editMode,
|
||||||
prevPostId: aroundResponse.prev
|
prevPostId: aroundResponse.prev
|
||||||
? aroundResponse.prev.id
|
? aroundResponse.prev.id
|
||||||
|
@ -56,6 +64,8 @@ class PostMainController extends BasePostController {
|
||||||
canFeaturePosts: api.hasPrivilege("posts:feature"),
|
canFeaturePosts: api.hasPrivilege("posts:feature"),
|
||||||
canListComments: api.hasPrivilege("comments:list"),
|
canListComments: api.hasPrivilege("comments:list"),
|
||||||
canCreateComments: api.hasPrivilege("comments:create"),
|
canCreateComments: api.hasPrivilege("comments:create"),
|
||||||
|
canListPools: api.hasPrivilege("pools:list"),
|
||||||
|
canViewPools: api.hasPrivilege("pools:view"),
|
||||||
parameters: parameters,
|
parameters: parameters,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
33
client/js/controls/pool_navigator_control.js
Normal file
33
client/js/controls/pool_navigator_control.js
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const api = require("../api.js");
|
||||||
|
const misc = require("../util/misc.js");
|
||||||
|
const events = require("../events.js");
|
||||||
|
const views = require("../util/views.js");
|
||||||
|
|
||||||
|
const template = views.getTemplate("pool-navigator");
|
||||||
|
|
||||||
|
class PoolNavigatorControl extends events.EventTarget {
|
||||||
|
constructor(hostNode, poolPostNearby) {
|
||||||
|
super();
|
||||||
|
this._hostNode = hostNode;
|
||||||
|
this._poolPostNearby = poolPostNearby;
|
||||||
|
|
||||||
|
views.replaceContent(
|
||||||
|
this._hostNode,
|
||||||
|
template({
|
||||||
|
pool: poolPostNearby.pool,
|
||||||
|
parameters: { query: `pool:${poolPostNearby.pool.id}` },
|
||||||
|
linkClass: misc.makeCssName(poolPostNearby.pool.category, "pool"),
|
||||||
|
canViewPosts: api.hasPrivilege("posts:view"),
|
||||||
|
canViewPools: api.hasPrivilege("pools:view"),
|
||||||
|
firstPost: poolPostNearby.firstPost,
|
||||||
|
previousPost: poolPostNearby.previousPost,
|
||||||
|
nextPost: poolPostNearby.nextPost,
|
||||||
|
lastPost: poolPostNearby.lastPost,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = PoolNavigatorControl;
|
49
client/js/controls/pool_navigator_list_control.js
Normal file
49
client/js/controls/pool_navigator_list_control.js
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const events = require("../events.js");
|
||||||
|
const views = require("../util/views.js");
|
||||||
|
const PoolNavigatorControl = require("../controls/pool_navigator_control.js");
|
||||||
|
|
||||||
|
const template = views.getTemplate("pool-navigator-list");
|
||||||
|
|
||||||
|
class PoolNavigatorListControl extends events.EventTarget {
|
||||||
|
constructor(hostNode, poolPostNearby) {
|
||||||
|
super();
|
||||||
|
this._hostNode = hostNode;
|
||||||
|
this._poolPostNearby = poolPostNearby;
|
||||||
|
this._indexToNode = {};
|
||||||
|
|
||||||
|
for (let [i, entry] of this._poolPostNearby.entries()) {
|
||||||
|
this._installPoolNavigatorNode(entry, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get _poolNavigatorListNode() {
|
||||||
|
return this._hostNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
_installPoolNavigatorNode(poolPostNearby, i) {
|
||||||
|
const poolListItemNode = document.createElement("div");
|
||||||
|
const poolControl = new PoolNavigatorControl(
|
||||||
|
poolListItemNode,
|
||||||
|
poolPostNearby,
|
||||||
|
);
|
||||||
|
this._indexToNode[poolPostNearby.id] = poolListItemNode;
|
||||||
|
this._poolNavigatorListNode.appendChild(poolListItemNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
_uninstallPoolNavigatorNode(index) {
|
||||||
|
const poolListItemNode = this._indexToNode[index];
|
||||||
|
poolListItemNode.parentNode.removeChild(poolListItemNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
_evtAdd(e) {
|
||||||
|
this._installPoolNavigatorNode(e.detail.index);
|
||||||
|
}
|
||||||
|
|
||||||
|
_evtRemove(e) {
|
||||||
|
this._uninstallPoolNavigatorNode(e.detail.index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = PoolNavigatorListControl;
|
|
@ -16,6 +16,14 @@ class PostList extends AbstractList {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getNearbyPoolPosts(id) {
|
||||||
|
return api.get(
|
||||||
|
uri.formatApiLink("post", id, "pools-nearby", {
|
||||||
|
fields: "id",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
static search(text, offset, limit, fields) {
|
static search(text, offset, limit, fields) {
|
||||||
return api
|
return api
|
||||||
.get(
|
.get(
|
||||||
|
|
|
@ -10,6 +10,7 @@ const PostContentControl = require("../controls/post_content_control.js");
|
||||||
const PostNotesOverlayControl = require("../controls/post_notes_overlay_control.js");
|
const PostNotesOverlayControl = require("../controls/post_notes_overlay_control.js");
|
||||||
const PostReadonlySidebarControl = require("../controls/post_readonly_sidebar_control.js");
|
const PostReadonlySidebarControl = require("../controls/post_readonly_sidebar_control.js");
|
||||||
const PostEditSidebarControl = require("../controls/post_edit_sidebar_control.js");
|
const PostEditSidebarControl = require("../controls/post_edit_sidebar_control.js");
|
||||||
|
const PoolNavigatorListControl = require("../controls/pool_navigator_list_control.js");
|
||||||
const CommentControl = require("../controls/comment_control.js");
|
const CommentControl = require("../controls/comment_control.js");
|
||||||
const CommentListControl = require("../controls/comment_list_control.js");
|
const CommentListControl = require("../controls/comment_list_control.js");
|
||||||
|
|
||||||
|
@ -57,6 +58,7 @@ class PostMainView {
|
||||||
this._installSidebar(ctx);
|
this._installSidebar(ctx);
|
||||||
this._installCommentForm();
|
this._installCommentForm();
|
||||||
this._installComments(ctx.post.comments);
|
this._installComments(ctx.post.comments);
|
||||||
|
this._installPoolNavigators(ctx.poolPostsNearby);
|
||||||
|
|
||||||
const showPreviousImage = () => {
|
const showPreviousImage = () => {
|
||||||
if (ctx.prevPostId) {
|
if (ctx.prevPostId) {
|
||||||
|
@ -137,6 +139,20 @@ class PostMainView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_installPoolNavigators(poolPostsNearby) {
|
||||||
|
const poolNavigatorsContainerNode = document.querySelector(
|
||||||
|
"#content-holder .pool-navigators-container"
|
||||||
|
);
|
||||||
|
if (!poolNavigatorsContainerNode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.poolNavigatorsControl = new PoolNavigatorListControl(
|
||||||
|
poolNavigatorsContainerNode,
|
||||||
|
poolPostsNearby,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
_installCommentForm() {
|
_installCommentForm() {
|
||||||
const commentFormContainer = document.querySelector(
|
const commentFormContainer = document.querySelector(
|
||||||
"#content-holder .comment-form-container"
|
"#content-holder .comment-form-container"
|
||||||
|
|
37
doc/API.md
37
doc/API.md
|
@ -975,6 +975,43 @@ data.
|
||||||
|
|
||||||
Retrieves information about posts that are before or after an existing post.
|
Retrieves information about posts that are before or after an existing post.
|
||||||
|
|
||||||
|
## Getting pools around post
|
||||||
|
- **Request**
|
||||||
|
|
||||||
|
`GET /post/<id>/pools-nearby`
|
||||||
|
|
||||||
|
- **Output**
|
||||||
|
|
||||||
|
```json5
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"pool": <pool>,
|
||||||
|
"firstPost": <first-post>,
|
||||||
|
"lastPost": <last-post>,
|
||||||
|
"nextPost": <next-post>,
|
||||||
|
"previousPost": <previous-post>
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Field meaning**
|
||||||
|
|
||||||
|
- `<pool>`: The associated [micro pool resource](#micro-pool).
|
||||||
|
- `<first-post>`: A [micro post resource](#micro-post) that displays the first post in the pool.
|
||||||
|
- `<last-post>`: A [micro post resource](#micro-post) that displays the last post in the pool.
|
||||||
|
- `<next-post>`: A [micro post resource](#micro-post) that displays the next post in the pool.
|
||||||
|
- `<previous-post>`: 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
|
## Deleting post
|
||||||
- **Request**
|
- **Request**
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,10 @@ from szurubooru import db, errors, model, rest, search
|
||||||
from szurubooru.func import (
|
from szurubooru.func import (
|
||||||
auth,
|
auth,
|
||||||
favorites,
|
favorites,
|
||||||
mime,
|
|
||||||
posts,
|
posts,
|
||||||
scores,
|
scores,
|
||||||
serialization,
|
serialization,
|
||||||
snapshots,
|
snapshots,
|
||||||
tags,
|
|
||||||
versions,
|
versions,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -283,6 +281,19 @@ def get_posts_around(
|
||||||
ctx, post_id, lambda post: _serialize_post(ctx, post)
|
ctx, post_id, lambda post: _serialize_post(ctx, post)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@rest.routes.get("/post/(?P<post_id>[^/]+)/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/?")
|
@rest.routes.post("/posts/reverse-search/?")
|
||||||
def get_posts_by_image(
|
def get_posts_by_image(
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import hmac
|
import hmac
|
||||||
import logging
|
import logging
|
||||||
|
from collections import namedtuple
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from itertools import tee, chain, islice
|
||||||
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
|
||||||
|
@ -15,7 +17,6 @@ from szurubooru.func import (
|
||||||
pools,
|
pools,
|
||||||
scores,
|
scores,
|
||||||
serialization,
|
serialization,
|
||||||
snapshots,
|
|
||||||
tags,
|
tags,
|
||||||
users,
|
users,
|
||||||
util,
|
util,
|
||||||
|
@ -96,6 +97,13 @@ FLAG_MAP = {
|
||||||
model.Post.FLAG_SOUND: "sound",
|
model.Post.FLAG_SOUND: "sound",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# https://stackoverflow.com/a/1012089
|
||||||
|
def _get_nearby_iter(post_list):
|
||||||
|
previous_item, current_item, next_item = tee(post_list, 3)
|
||||||
|
previous_item = chain([None], previous_item)
|
||||||
|
next_item = chain(islice(next_item, 1, None), [None])
|
||||||
|
return zip(previous_item, current_item, next_item)
|
||||||
|
|
||||||
|
|
||||||
def get_post_security_hash(id: int) -> str:
|
def get_post_security_hash(id: int) -> str:
|
||||||
return hmac.new(
|
return hmac.new(
|
||||||
|
@ -968,3 +976,47 @@ def search_by_image(image_content: bytes) -> List[Tuple[float, model.Post]]:
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
return []
|
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
|
||||||
|
first_post_id = pool.posts[0].post_id,
|
||||||
|
last_post_id = pool.posts[-1].post_id,
|
||||||
|
|
||||||
|
for previous_item, current_item, next_item in _get_nearby_iter(pool.posts):
|
||||||
|
if post.post_id == current_item.post_id:
|
||||||
|
if previous_item != None:
|
||||||
|
prev_post_id = previous_item.post_id
|
||||||
|
if next_item != None:
|
||||||
|
next_post_id = next_item.post_id
|
||||||
|
break
|
||||||
|
|
||||||
|
resp_entry = PoolPostsNearby(
|
||||||
|
pool=pool,
|
||||||
|
first_post=first_post_id,
|
||||||
|
last_post=last_post_id,
|
||||||
|
prev_post=prev_post_id,
|
||||||
|
next_post=next_post_id,
|
||||||
|
)
|
||||||
|
response.append(resp_entry)
|
||||||
|
return response
|
||||||
|
|
||||||
|
def serialize_pool_posts_nearby(
|
||||||
|
nearby: List[PoolPostsNearby]
|
||||||
|
) -> Optional[rest.Response]:
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
"pool": pools.serialize_micro_pool(entry.pool),
|
||||||
|
"firstPost": serialize_micro_post(try_get_post_by_id(entry.first_post), None),
|
||||||
|
"lastPost": serialize_micro_post(try_get_post_by_id(entry.last_post), None),
|
||||||
|
"previousPost": serialize_micro_post(try_get_post_by_id(entry.prev_post), None),
|
||||||
|
"nextPost": serialize_micro_post(try_get_post_by_id(entry.next_post), None),
|
||||||
|
} for entry in nearby
|
||||||
|
]
|
||||||
|
|
|
@ -14,6 +14,7 @@ def inject_config(config_injector):
|
||||||
"privileges": {
|
"privileges": {
|
||||||
"posts:list": model.User.RANK_REGULAR,
|
"posts:list": model.User.RANK_REGULAR,
|
||||||
"posts:view": model.User.RANK_REGULAR,
|
"posts:view": model.User.RANK_REGULAR,
|
||||||
|
"pools:list": model.User.RANK_REGULAR,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -125,3 +126,55 @@ def test_trying_to_retrieve_single_without_privileges(
|
||||||
context_factory(user=user_factory(rank=model.User.RANK_ANONYMOUS)),
|
context_factory(user=user_factory(rank=model.User.RANK_ANONYMOUS)),
|
||||||
{"post_id": 999},
|
{"post_id": 999},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_get_pool_post_around(user_factory, post_factory, pool_factory, pool_post_factory, context_factory):
|
||||||
|
p1 = post_factory(id=1)
|
||||||
|
p2 = post_factory(id=2)
|
||||||
|
p3 = post_factory(id=3)
|
||||||
|
db.session.add_all([p1, p2, p3])
|
||||||
|
|
||||||
|
pool = pool_factory(id=1)
|
||||||
|
db.session.add(pool)
|
||||||
|
|
||||||
|
pool_posts = [pool_post_factory(pool=pool, post=p1), pool_post_factory(pool=pool, post=p2), pool_post_factory(pool=pool, post=p3)]
|
||||||
|
db.session.add_all(pool_posts)
|
||||||
|
|
||||||
|
result = api.post_api.get_pools_around(context_factory(user=user_factory(rank=model.User.RANK_REGULAR)), {"post_id": 2})
|
||||||
|
assert result[0]["previousPost"]["id"] == 1 and result[0]["nextPost"]["id"] == 3
|
||||||
|
|
||||||
|
def test_get_pool_post_around_start(user_factory, post_factory, pool_factory, pool_post_factory, context_factory):
|
||||||
|
p1 = post_factory(id=1)
|
||||||
|
p2 = post_factory(id=2)
|
||||||
|
p3 = post_factory(id=3)
|
||||||
|
db.session.add_all([p1, p2, p3])
|
||||||
|
|
||||||
|
pool = pool_factory(id=1)
|
||||||
|
db.session.add(pool)
|
||||||
|
|
||||||
|
pool_posts = [pool_post_factory(pool=pool, post=p1), pool_post_factory(pool=pool, post=p2), pool_post_factory(pool=pool, post=p3)]
|
||||||
|
db.session.add_all(pool_posts)
|
||||||
|
|
||||||
|
result = api.post_api.get_pools_around(context_factory(user=user_factory(rank=model.User.RANK_REGULAR)), {"post_id": 1})
|
||||||
|
assert result[0]["previousPost"] == None and result[0]["nextPost"]["id"] == 2
|
||||||
|
|
||||||
|
def test_get_pool_post_around_end(user_factory, post_factory, pool_factory, pool_post_factory, context_factory):
|
||||||
|
p1 = post_factory(id=1)
|
||||||
|
p2 = post_factory(id=2)
|
||||||
|
p3 = post_factory(id=3)
|
||||||
|
db.session.add_all([p1, p2, p3])
|
||||||
|
|
||||||
|
pool = pool_factory(id=1)
|
||||||
|
db.session.add(pool)
|
||||||
|
|
||||||
|
pool_posts = [pool_post_factory(pool=pool, post=p1), pool_post_factory(pool=pool, post=p2), pool_post_factory(pool=pool, post=p3)]
|
||||||
|
db.session.add_all(pool_posts)
|
||||||
|
|
||||||
|
result = api.post_api.get_pools_around(context_factory(user=user_factory(rank=model.User.RANK_REGULAR)), {"post_id": 3})
|
||||||
|
assert result[0]["previousPost"]["id"] == 2 and result[0]["nextPost"] == None
|
||||||
|
|
||||||
|
def test_get_pool_post_around_no_pool(user_factory, post_factory, pool_factory, pool_post_factory, context_factory):
|
||||||
|
p1 = post_factory(id=1)
|
||||||
|
db.session.add(p1)
|
||||||
|
|
||||||
|
result = api.post_api.get_pools_around(context_factory(user=user_factory(rank=model.User.RANK_REGULAR)), {"post_id": 1})
|
||||||
|
assert result == []
|
||||||
|
|
Reference in a new issue