server/posts: add post retrieving

This commit is contained in:
rr- 2016-04-25 10:48:15 +02:00
parent 52f4018bee
commit 587a8f8276
8 changed files with 108 additions and 12 deletions

55
API.md
View file

@ -31,7 +31,7 @@
- ~~Listing posts~~ - ~~Listing posts~~
- ~~Creating post~~ - ~~Creating post~~
- ~~Updating post~~ - ~~Updating post~~
- ~~Getting post~~ - [Getting post](#getting-post)
- ~~Deleting post~~ - ~~Deleting post~~
- [Rating post](#rating-post) - [Rating post](#rating-post)
- ~~Adding post to favorites~~ - ~~Adding post to favorites~~
@ -178,7 +178,7 @@ data.
] ]
} }
``` ```
...where `<tag-category>` is a [tag category resource](#tag-category), and ...where `<tag-category>` is a [tag category resource](#tag-category) and
`snapshots` contain its earlier versions. `snapshots` contain its earlier versions.
- **Errors** - **Errors**
@ -220,7 +220,7 @@ data.
] ]
} }
``` ```
...where `<tag-category>` is a [tag category resource](#tag-category), and ...where `<tag-category>` is a [tag category resource](#tag-category) and
`snapshots` contain its earlier versions. `snapshots` contain its earlier versions.
- **Errors** - **Errors**
@ -255,7 +255,7 @@ data.
] ]
} }
``` ```
...where `<tag-category>` is a [tag category resource](#tag-category), and ...where `<tag-category>` is a [tag category resource](#tag-category) and
`snapshots` contain its earlier versions. `snapshots` contain its earlier versions.
- **Errors** - **Errors**
@ -403,7 +403,7 @@ data.
] ]
} }
``` ```
...where `<tag>` is a [tag resource](#tag), and `snapshots` contain its ...where `<tag>` is a [tag resource](#tag) and `snapshots` contain its
earlier versions. earlier versions.
- **Errors** - **Errors**
@ -457,7 +457,7 @@ data.
] ]
} }
``` ```
...where `<tag>` is a [tag resource](#tag), and `snapshots` contain its ...where `<tag>` is a [tag resource](#tag) and `snapshots` contain its
earlier versions. earlier versions.
- **Errors** - **Errors**
@ -499,7 +499,7 @@ data.
] ]
} }
``` ```
...where `<tag>` is a [tag resource](#tag), and `snapshots` contain its ...where `<tag>` is a [tag resource](#tag) and `snapshots` contain its
earlier versions. earlier versions.
- **Errors** - **Errors**
@ -560,7 +560,7 @@ data.
] ]
} }
``` ```
...where `<tag>` is the target [tag resource](#tag), and `snapshots` ...where `<tag>` is the target [tag resource](#tag) and `snapshots`
contain its earlier versions. contain its earlier versions.
- **Errors** - **Errors**
@ -612,6 +612,41 @@ data.
list is truncated to the first 50 elements. Doesn't use paging. list is truncated to the first 50 elements. Doesn't use paging.
## Getting post
- **Request**
`GET /post/<id>`
- **Output**
```json5
{
"post": <post>,
"snapshots": {
<snapshot>,
<snapshot>,
<snapshot>
},
"comments": {
<comment>,
<comment>,
<comment>
}
}
```
...where `<post>` is a [post resource](#post), `<comment>` is a [comment
resource](#comment) and `snapshots` contain post's earlier versions.
- **Errors**
- the post does not exist
- privileges are too low
- **Description**
Retrieves information about an existing post.
## Rating post ## Rating post
- **Request** - **Request**
@ -663,7 +698,7 @@ data.
] ]
} }
``` ```
...where `<post>` is a [post resource](#post), and `snapshots` contain its ...where `<post>` is a [post resource](#post) and `snapshots` contain its
earlier versions. earlier versions.
- **Errors** - **Errors**
@ -694,7 +729,7 @@ data.
] ]
} }
``` ```
...where `<post>` is a [post resource](#post), and `snapshots` contain its ...where `<post>` is a [post resource](#post) and `snapshots` contain its
earlier versions. earlier versions.
- **Errors** - **Errors**

View file

@ -15,6 +15,7 @@ from szurubooru.api.comment_api import (
CommentDetailApi, CommentDetailApi,
CommentScoreApi) CommentScoreApi)
from szurubooru.api.post_api import ( from szurubooru.api.post_api import (
PostDetailApi,
PostFeatureApi, PostFeatureApi,
PostScoreApi) PostScoreApi)
from szurubooru.api.snapshot_api import SnapshotListApi from szurubooru.api.snapshot_api import SnapshotListApi

View file

@ -1,6 +1,12 @@
from szurubooru.api.base_api import BaseApi from szurubooru.api.base_api import BaseApi
from szurubooru.func import auth, posts, snapshots, scores from szurubooru.func import auth, posts, snapshots, scores
class PostDetailApi(BaseApi):
def get(self, ctx, post_id):
auth.verify_privilege(ctx.user, 'posts:view')
post = posts.get_post_by_id(post_id)
return posts.serialize_post_with_details(post, ctx.user)
class PostFeatureApi(BaseApi): class PostFeatureApi(BaseApi):
def post(self, ctx): def post(self, ctx):
auth.verify_privilege(ctx.user, 'posts:feature') auth.verify_privilege(ctx.user, 'posts:feature')

View file

@ -65,6 +65,7 @@ def create_app():
app.add_route('/tag-merge/', api.TagMergeApi()) app.add_route('/tag-merge/', api.TagMergeApi())
app.add_route('/tag-siblings/{tag_name}', api.TagSiblingsApi()) app.add_route('/tag-siblings/{tag_name}', api.TagSiblingsApi())
app.add_route('/post/{post_id}', api.PostDetailApi())
app.add_route('/post/{post_id}/score', api.PostScoreApi()) app.add_route('/post/{post_id}/score', api.PostScoreApi())
app.add_route('/comments/', api.CommentListApi()) app.add_route('/comments/', api.CommentListApi())

View file

@ -107,6 +107,7 @@ class Post(Base):
notes = relationship( notes = relationship(
'PostNote', cascade='all, delete-orphan', lazy='joined') 'PostNote', cascade='all, delete-orphan', lazy='joined')
comments = relationship('Comment')
tag_count = column_property( tag_count = column_property(
select([func.count(PostTag.tag_id)]) \ select([func.count(PostTag.tag_id)]) \
.where(PostTag.post_id == post_id) \ .where(PostTag.post_id == post_id) \

View file

@ -1,7 +1,7 @@
import datetime import datetime
import sqlalchemy import sqlalchemy
from szurubooru import db, errors from szurubooru import db, errors
from szurubooru.func import users, snapshots, scores from szurubooru.func import users, snapshots, scores, comments
class PostNotFoundError(errors.NotFoundError): pass class PostNotFoundError(errors.NotFoundError): pass
class PostAlreadyFeaturedError(errors.ValidationError): pass class PostAlreadyFeaturedError(errors.ValidationError): pass
@ -42,9 +42,15 @@ def serialize_post(post, authenticated_user):
return ret return ret
def serialize_post_with_details(post, authenticated_user): def serialize_post_with_details(post, authenticated_user):
comment_list = []
if post:
for comment in post.comments:
comment_list.append(
comments.serialize_comment(comment, authenticated_user))
return { return {
'post': serialize_post(post, authenticated_user), 'post': serialize_post(post, authenticated_user),
'snapshots': snapshots.get_serialized_history(post), 'snapshots': snapshots.get_serialized_history(post),
'comments': comment_list,
} }
def get_post_count(): def get_post_count():

View file

@ -24,7 +24,7 @@ def test_no_featured_post(test_ctx):
result = test_ctx.api.get( result = test_ctx.api.get(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank='regular_user')))
assert result == {'post': None, 'snapshots': []} assert result == {'post': None, 'snapshots': [], 'comments': []}
def test_featuring(test_ctx): def test_featuring(test_ctx):
db.session.add(test_ctx.post_factory(id=1)) db.session.add(test_ctx.post_factory(id=1))

View file

@ -0,0 +1,46 @@
import datetime
import pytest
from szurubooru import api, db, errors
from szurubooru.func import util, posts
@pytest.fixture
def test_ctx(context_factory, config_injector, user_factory, post_factory):
config_injector({
'privileges': {
'posts:list': 'regular_user',
'posts:view': 'regular_user',
},
'thumbnails': {'avatar_width': 200},
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
'rank_names': {'regular_user': 'Peasant'},
})
ret = util.dotdict()
ret.context_factory = context_factory
ret.user_factory = user_factory
ret.post_factory = post_factory
ret.detail_api = api.PostDetailApi()
return ret
def test_retrieving_single(test_ctx):
db.session.add(test_ctx.post_factory(id=1))
result = test_ctx.detail_api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 1)
assert 'post' in result
assert 'id' in result['post']
assert 'snapshots' in result
assert 'comments' in result
def test_trying_to_retrieve_single_non_existing(test_ctx):
with pytest.raises(posts.PostNotFoundError):
test_ctx.detail_api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')),
'-')
def test_trying_to_retrieve_single_without_privileges(test_ctx):
with pytest.raises(errors.AuthError):
test_ctx.detail_api.get(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='anonymous')),
'-')