server/users: offer more stats in user entity
This commit is contained in:
parent
aa95afb989
commit
caecaee785
7 changed files with 164 additions and 8 deletions
28
API.md
28
API.md
|
@ -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**
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue