server/users: offer more stats in user entity

This commit is contained in:
rr- 2016-06-03 21:18:17 +02:00
parent aa95afb989
commit caecaee785
7 changed files with 164 additions and 8 deletions

28
API.md
View file

@ -1391,13 +1391,18 @@ A single user.
```json5
{
"name": <name>,
"email": <email>,
"rank": <rank>,
"lastLoginTime": <last-login-time>,
"creationTime": <creation-time>,
"avatarStyle": <avatar-style>,
"avatarUrl": <avatar-url>
"name": <name>,
"email": <email>,
"rank": <rank>,
"lastLoginTime": <last-login-time>,
"creationTime": <creation-time>,
"avatarStyle": <avatar-style>,
"avatarUrl": <avatar-url>,
"commentCount": <comment-count>,
"uploadedPostCount": <uploaded-post-count>,
"likedPostCount": <liked-post-count>,
"dislikedPostCount": <disliked-post-count>,
"faoritevPostCount": <favorite-post-count>
}
```
@ -1427,6 +1432,15 @@ A single user.
- `"manual"`: the user has uploaded a picture manually.
- `<avatarUrl>`: the URL to the avatar.
- `<comment-count>`: number of comments.
- `<uploaded-post-count>`: number of uploaded posts.
- `<liked-post-count>`: nubmer of liked posts. It is available only if the
request is authenticated by the same user. If it's unavailable, the server
returns `false`.
- `<disliked-post-count>`: number of disliked posts. It is available only if
the request is authenticated by the same user. If it's unavailable, the
server returns `false`.
- `<favorite-post-count>`: number of favorited posts.
## Micro user
**Description**

View file

@ -1,5 +1,9 @@
from sqlalchemy import Column, Integer, Unicode, DateTime
from sqlalchemy.orm import column_property
from sqlalchemy.sql.expression import func, select
from szurubooru.db.base import Base
from szurubooru.db.post import Post, PostScore, PostFavorite
from szurubooru.db.comment import Comment
class User(Base):
__tablename__ = 'user'
@ -25,3 +29,30 @@ class User(Base):
last_login_time = Column('last_login_time', DateTime)
avatar_style = Column(
'avatar_style', Unicode(32), nullable=False, default=AVATAR_GRAVATAR)
post_count = column_property(
select([func.coalesce(func.count(1), 0)]) \
.where(Post.user_id == user_id) \
.correlate_except(Post))
comment_count = column_property(
select([func.coalesce(func.count(1), 0)]) \
.where(Comment.user_id == user_id) \
.correlate_except(Comment))
favorite_post_count = column_property(
select([func.coalesce(func.count(1), 0)]) \
.where(PostFavorite.user_id == user_id) \
.correlate_except(PostFavorite))
liked_post_count = column_property(
select([func.coalesce(func.count(1), 0)]) \
.where(PostScore.user_id == user_id) \
.where(PostScore.score == 1) \
.correlate_except(PostScore))
disliked_post_count = column_property(
select([func.coalesce(func.count(1), 0)]) \
.where(PostScore.user_id == user_id) \
.where(PostScore.score == -1) \
.correlate_except(PostScore))

View file

@ -28,6 +28,16 @@ def _get_email(user, authenticated_user, force_show_email):
return False
return user.email
def _get_liked_post_count(user, authenticated_user):
if authenticated_user.user_id != user.user_id:
return False
return user.liked_post_count
def _get_disliked_post_count(user, authenticated_user):
if authenticated_user.user_id != user.user_id:
return False
return user.disliked_post_count
def serialize_user(user, authenticated_user, options=None, force_show_email=False):
return util.serialize_entity(
user,
@ -38,7 +48,15 @@ def serialize_user(user, authenticated_user, options=None, force_show_email=Fals
'lastLoginTime': lambda: user.last_login_time,
'avatarStyle': lambda: user.avatar_style,
'avatarUrl': lambda: _get_avatar_url(user),
'email': lambda: _get_email(user, authenticated_user, force_show_email),
'commentCount': lambda: user.comment_count,
'uploadedPostCount': lambda: user.post_count,
'favoritePostCount': lambda: user.favorite_post_count,
'likedPostCount':
lambda: _get_liked_post_count(user, authenticated_user),
'dislikedPostCount':
lambda: _get_disliked_post_count(user, authenticated_user),
'email':
lambda: _get_email(user, authenticated_user, force_show_email),
},
options)

View file

@ -43,6 +43,11 @@ def test_creating_user(test_ctx, fake_datetime):
'name': 'chewie1',
'rank': 'administrator',
'email': 'asd@asd.asd',
'commentCount': 0,
'likedPostCount': 0,
'dislikedPostCount': 0,
'favoritePostCount': 0,
'uploadedPostCount': 0,
}
user = users.get_user_by_name('chewie1')
assert user.name == 'chewie1'

View file

@ -56,7 +56,15 @@ def test_retrieving_single(test_ctx):
'avatarUrl': 'http://gravatar.com/avatar/' +
'275876e34cf609db118f3d84b799a790?d=retro&s=200',
'email': False,
'commentCount': 0,
'likedPostCount': False,
'dislikedPostCount': False,
'favoritePostCount': 0,
'uploadedPostCount': 0,
}
assert result['email'] is False
assert result['likedPostCount'] is False
assert result['dislikedPostCount'] is False
def test_trying_to_retrieve_single_non_existing(test_ctx):
with pytest.raises(users.UserNotFoundError):

View file

@ -57,6 +57,11 @@ def test_updating_user(test_ctx):
'email': 'asd@asd.asd',
'name': 'chewie',
'rank': 'moderator',
'commentCount': 0,
'likedPostCount': 0,
'dislikedPostCount': 0,
'favoritePostCount': 0,
'uploadedPostCount': 0,
}
user = users.get_user_by_name('chewie')
assert user.name == 'chewie'

View file

@ -21,3 +21,78 @@ def test_saving_user():
assert user.rank == 'rank'
assert user.creation_time == datetime(1997, 1, 1)
assert user.avatar_style == db.User.AVATAR_GRAVATAR
def test_upload_count(user_factory, post_factory):
user = user_factory()
db.session.add(user)
db.session.flush()
assert user.post_count == 0
post1 = post_factory()
post1.user = user
post2 = post_factory()
db.session.add_all([post1, post2])
db.session.flush()
db.session.refresh(user)
assert user.post_count == 1
def test_comment_count(user_factory, comment_factory):
user = user_factory()
db.session.add(user)
db.session.flush()
assert user.comment_count == 0
db.session.add_all([
comment_factory(user=user),
comment_factory(),
])
db.session.flush()
db.session.refresh(user)
assert user.comment_count == 1
def test_favorite_count(user_factory, post_factory):
user = user_factory()
db.session.add(user)
db.session.flush()
assert user.comment_count == 0
post1 = post_factory()
post2 = post_factory()
db.session.add_all([
db.PostFavorite(post=post1, time=datetime.now(), user=user),
db.PostFavorite(post=post2, time=datetime.now(), user=user_factory()),
])
db.session.flush()
db.session.refresh(user)
assert user.favorite_post_count == 1
def test_liked_post_count(user_factory, post_factory):
user = user_factory()
db.session.add(user)
db.session.flush()
assert user.liked_post_count == 0
assert user.disliked_post_count == 0
post1 = post_factory()
post2 = post_factory()
db.session.add_all([
db.PostScore(post=post1, time=datetime.now(), user=user, score=1),
db.PostScore(post=post2, time=datetime.now(), user=user_factory(), score=1),
])
db.session.flush()
db.session.refresh(user)
assert user.liked_post_count == 1
assert user.disliked_post_count == 0
def test_disliked_post_count(user_factory, post_factory):
user = user_factory()
db.session.add(user)
db.session.flush()
assert user.liked_post_count == 0
assert user.disliked_post_count == 0
post1 = post_factory()
post2 = post_factory()
db.session.add_all([
db.PostScore(post=post1, time=datetime.now(), user=user, score=-1),
db.PostScore(post=post2, time=datetime.now(), user=user_factory(), score=1),
])
db.session.flush()
db.session.refresh(user)
assert user.liked_post_count == 0
assert user.disliked_post_count == 1