Skip to content

Commit 1b9e4f4

Browse files
authored
Feature/get post (#49)
* Get post feature - feature added - untested - missing: video's thumbnail, author's avatar url, can_comment Author: thanhphanphu18@gmail.com * get_post fix & test - update the get post router - fix the form media url function (missing "post") - add the cleanup token daemon - tested - 1000 | OK | get by creator Author: thanhphanphu18@gmail.com
1 parent 51d4ec2 commit 1b9e4f4

File tree

18 files changed

+453
-34
lines changed

18 files changed

+453
-34
lines changed

cmd/laclongquan/start.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,12 @@ func start(configPath string) {
6969
}
7070
logger.Info("http server OK")
7171

72+
// ------------- Daemons ---------------
7273
mainCtx := context.Background()
7374
daemonMan := booting.NewDaemonManeger(mainCtx)
7475

7576
logger.Info("starting daemons....")
76-
daemonMan.Start(httpDaemon)
77+
daemonMan.Start(httpDaemon, authSrv.DeleteExpiredDaemons())
7778
booting.WaitSignals(mainCtx)
7879
daemonMan.Stop()
7980

internal/laclongquan/application/application.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ func NewApplication(
3232
PostHandler: NewPostHandler(
3333
postRepo,
3434
saveDir,
35+
likeRepo,
3536
commentRepo,
3637
relationRepo,
3738
userRepo,

internal/laclongquan/application/posthandler.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
type PostHandler struct {
1313
fac entity.PostFactory
1414
repo repository.PostRepository
15+
likeRepo repository.LikeRepository
1516
commentRepo repository.CommentRepository
1617
relationRepo repository.RelationRepository
1718
userRepo repository.UserRepository
@@ -20,13 +21,15 @@ type PostHandler struct {
2021
}
2122

2223
func NewPostHandler(repo repository.PostRepository, saveDir string,
24+
likeRepo repository.LikeRepository,
2325
commentRepo repository.CommentRepository,
2426
relationRepo repository.RelationRepository,
2527
userRepo repository.UserRepository,
2628
) PostHandler {
2729
return PostHandler{
2830
fac: entity.NewPostFactory(),
2931
repo: repo,
32+
likeRepo: likeRepo,
3033
commentRepo: commentRepo,
3134
relationRepo: relationRepo,
3235
userRepo: userRepo,
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package application
2+
3+
import (
4+
"context"
5+
6+
"github.com/thanhpp/zola/internal/laclongquan/domain/entity"
7+
)
8+
9+
type GetPostResult struct {
10+
Post *entity.Post
11+
Author *entity.User
12+
LikeCount int
13+
CommentCount int
14+
IsLiked bool
15+
CanEdit bool
16+
CanComment bool
17+
}
18+
19+
func (p PostHandler) GetPost(ctx context.Context, userID, postID string) (*GetPostResult, error) {
20+
user, err := p.userRepo.GetByID(ctx, userID)
21+
if err != nil {
22+
return nil, err
23+
}
24+
25+
post, err := p.repo.GetByID(ctx, postID)
26+
if err != nil {
27+
return nil, err
28+
}
29+
30+
// get the relation between the user and the post creator
31+
var relation *entity.Relation
32+
if userID != post.Creator() {
33+
relation, err = p.relationRepo.GetRelationBetween(ctx, userID, post.Creator())
34+
if err != nil {
35+
return nil, err
36+
}
37+
38+
if relation.IsBlock() {
39+
return nil, ErrAlreadyBlocked
40+
}
41+
}
42+
43+
// authorization
44+
if err := post.CanUserGetPost(user, relation); err != nil {
45+
return nil, err
46+
}
47+
48+
// get the author of the post
49+
author, err := p.userRepo.GetByID(ctx, post.Creator())
50+
if err != nil {
51+
return nil, err
52+
}
53+
54+
// like count
55+
likeCount, err := p.likeRepo.Count(ctx, postID)
56+
if err != nil {
57+
return nil, err
58+
}
59+
60+
// comment count
61+
commentCount, err := p.commentRepo.CountByPostID(ctx, postID)
62+
if err != nil {
63+
return nil, err
64+
}
65+
66+
// form response
67+
var (
68+
canEdit bool
69+
// FIXME: canComment bool
70+
)
71+
if err := post.CanUserEditPost(user); err == nil {
72+
canEdit = true
73+
}
74+
75+
return &GetPostResult{
76+
Post: post,
77+
Author: author,
78+
CommentCount: commentCount,
79+
LikeCount: likeCount,
80+
IsLiked: p.likeRepo.IsLiked(ctx, userID, postID),
81+
CanEdit: canEdit,
82+
}, nil
83+
}

internal/laclongquan/domain/entity/post.go

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
11
package entity
22

33
import (
4+
"errors"
45
"strings"
6+
"time"
57

68
"github.com/google/uuid"
79
)
810

11+
var (
12+
ErrNilUser = errors.New("nil user")
13+
)
14+
915
type Post struct {
10-
id uuid.UUID
11-
creator uuid.UUID
12-
content string
13-
status PostStatus
14-
media []Media
16+
id uuid.UUID
17+
creator uuid.UUID
18+
content string
19+
status PostStatus
20+
media []Media
21+
createdAt time.Time
22+
updatedAt time.Time
1523
}
1624

1725
func (p Post) ID() string {
@@ -75,6 +83,14 @@ func (p *Post) AddMedia(m Media) error {
7583
return nil
7684
}
7785

86+
func (p Post) CreatedAt() int64 {
87+
return p.createdAt.Unix()
88+
}
89+
90+
func (p Post) UpdatedAt() int64 {
91+
return p.updatedAt.Unix()
92+
}
93+
7894
func (p Post) CanUserGetMedia(user *User, relation *Relation, mediaID string) (*Media, error) {
7995
if user.IsLocked() {
8096
return nil, ErrLockedUser
@@ -84,7 +100,7 @@ func (p Post) CanUserGetMedia(user *User, relation *Relation, mediaID string) (*
84100
return nil, ErrLockedPost
85101
}
86102

87-
if user.ID().String() != p.Creator() && relation == nil || (relation != nil && relation.IsFriend()) {
103+
if (user.ID().String() != p.Creator() && relation == nil) || (relation != nil && relation.IsFriend()) {
88104
return nil, ErrPermissionDenied
89105
}
90106

@@ -97,6 +113,42 @@ func (p Post) CanUserGetMedia(user *User, relation *Relation, mediaID string) (*
97113
return nil, ErrPostNotContainsMedia
98114
}
99115

116+
func (p Post) CanUserGetPost(user *User, relation *Relation) error {
117+
if user.IsLocked() {
118+
return ErrLockedUser
119+
}
120+
121+
if p.IsLocked() {
122+
return ErrLockedUser
123+
}
124+
125+
if (user.ID().String() != p.Creator() && relation == nil) || (relation != nil && relation.IsFriend()) {
126+
return ErrPermissionDenied
127+
}
128+
129+
return nil
130+
}
131+
132+
func (p Post) CanUserEditPost(user *User) error {
133+
if user == nil {
134+
return ErrNilUser
135+
}
136+
137+
if user.IsLocked() {
138+
return ErrLockedUser
139+
}
140+
141+
if p.IsLocked() {
142+
return ErrLockedPost
143+
}
144+
145+
if p.Creator() != user.ID().String() {
146+
return ErrNotCreator
147+
}
148+
149+
return nil
150+
}
151+
100152
func (p *Post) RemoveMedia(ids ...string) ([]*Media, error) {
101153
var (
102154
deleted = make([]*Media, 0, len(ids))

internal/laclongquan/domain/entity/post_database.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package entity
22

33
import (
44
"os"
5+
"time"
56

67
"github.com/google/uuid"
78
)
@@ -30,7 +31,7 @@ func NewMediaFromDB(id, owner, mediaType, path string) (*Media, error) {
3031
}, nil
3132
}
3233

33-
func NewPostFromDB(id, creator, status, content string, media []Media) (*Post, error) {
34+
func NewPostFromDB(id, creator, status, content string, media []Media, createdAt, updatedAt time.Time) (*Post, error) {
3435
postID, err := uuid.Parse(id)
3536
if err != nil {
3637
return nil, err
@@ -42,10 +43,12 @@ func NewPostFromDB(id, creator, status, content string, media []Media) (*Post, e
4243
}
4344

4445
return &Post{
45-
id: postID,
46-
creator: creatorID,
47-
status: PostStatus(status),
48-
content: content,
49-
media: media,
46+
id: postID,
47+
creator: creatorID,
48+
status: PostStatus(status),
49+
content: content,
50+
media: media,
51+
createdAt: createdAt,
52+
updatedAt: updatedAt,
5053
}, nil
5154
}

internal/laclongquan/domain/repository/commentrepo.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ var (
1414
type CommentUpdateFunc func(ctx context.Context, comment *entity.Comment) (*entity.Comment, error)
1515

1616
type CommentRepository interface {
17+
// read
1718
GetByIDAndPostID(ctx context.Context, commentID, postID string) (*entity.Comment, error)
19+
CountByPostID(ctx context.Context, postID string) (int, error)
20+
21+
// write
1822
Create(ctx context.Context, comment *entity.Comment) error
1923
Update(ctx context.Context, commentID, postID string, fn CommentUpdateFunc) error
2024
Delete(ctx context.Context, comment *entity.Comment) error

internal/laclongquan/domain/repository/likerepo.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import (
77
)
88

99
type LikeRepository interface {
10-
CreateOrDelete(ctx context.Context, like *entity.Like) error
10+
// read
1111
Count(ctx context.Context, postID string) (int, error)
12+
IsLiked(ctx context.Context, userID, postID string) bool
13+
14+
// write
15+
CreateOrDelete(ctx context.Context, like *entity.Like) error
1216
}

internal/laclongquan/infrastructure/adapter/gormdb/commentdb.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,17 @@ func (c commentGorm) getByPostIDCommentID(ctx context.Context, tx *gorm.DB, post
7777
return c.unmarshal(cmtDB, post, user), nil
7878
}
7979

80+
func (c commentGorm) CountByPostID(ctx context.Context, postID string) (int, error) {
81+
var commentCount int64
82+
if err := c.db.WithContext(ctx).Model(c.cmtModel).
83+
Where("post_uuid = ?", postID).Count(&commentCount).
84+
Error; err != nil {
85+
return 0, err
86+
}
87+
88+
return int(commentCount), nil
89+
}
90+
8091
func (c commentGorm) Create(ctx context.Context, comment *entity.Comment) error {
8192
return c.db.WithContext(ctx).Model(c.cmtModel).
8293
Create(c.marshal(comment)).Error

internal/laclongquan/infrastructure/adapter/gormdb/likedb.go

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,30 @@ func (l likeGorm) unmarshal(likeDB *LikeDB) *entity.Like {
3333
}
3434
}
3535

36+
func (l likeGorm) Count(ctx context.Context, postID string) (int, error) {
37+
var count = new(int64)
38+
39+
if err := l.db.WithContext(ctx).Model(l.model).
40+
Where("post_uuid = ?", postID).
41+
Count(count).Error; err != nil {
42+
return 0, err
43+
}
44+
45+
return int(*count), nil
46+
}
47+
48+
func (l likeGorm) IsLiked(ctx context.Context, userID, postID string) bool {
49+
var count = new(int64)
50+
51+
if err := l.db.WithContext(ctx).Model(l.model).
52+
Where("post_uuid = ? AND creator_uuid = ?", postID, userID).
53+
Count(count).Error; err != nil {
54+
return false
55+
}
56+
57+
return *count > 0
58+
}
59+
3660
func (l likeGorm) CreateOrDelete(ctx context.Context, like *entity.Like) error {
3761
likeDB := l.marshal(like)
3862

@@ -51,15 +75,3 @@ func (l likeGorm) CreateOrDelete(ctx context.Context, like *entity.Like) error {
5175

5276
return nil
5377
}
54-
55-
func (l likeGorm) Count(ctx context.Context, postID string) (int, error) {
56-
var count = new(int64)
57-
58-
if err := l.db.WithContext(ctx).Model(l.model).
59-
Where("post_uuid = ?", postID).
60-
Count(count).Error; err != nil {
61-
return 0, err
62-
}
63-
64-
return int(*count), nil
65-
}

0 commit comments

Comments
 (0)