243 lines
7.3 KiB
Go
243 lines
7.3 KiB
Go
package handler
|
|
|
|
import (
|
|
"context"
|
|
"tailly_clips/internal/domain"
|
|
"tailly_clips/internal/service"
|
|
"tailly_clips/proto"
|
|
|
|
"google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/status"
|
|
"google.golang.org/protobuf/types/known/emptypb"
|
|
"google.golang.org/protobuf/types/known/timestamppb"
|
|
)
|
|
|
|
type GRPCHandler struct {
|
|
proto.UnimplementedClipServiceServer
|
|
clipService service.ClipService
|
|
likeService service.LikeService
|
|
commentService service.CommentService
|
|
}
|
|
|
|
func NewGRPCHandler(
|
|
clipService service.ClipService,
|
|
likeService service.LikeService,
|
|
commentService service.CommentService,
|
|
) *GRPCHandler {
|
|
return &GRPCHandler{
|
|
clipService: clipService,
|
|
likeService: likeService,
|
|
commentService: commentService,
|
|
}
|
|
}
|
|
|
|
func (h *GRPCHandler) CreateClip(ctx context.Context, req *proto.CreateClipRequest) (*proto.CreateClipResponse, error) {
|
|
createReq := domain.CreateClipRequest{
|
|
UserID: int(req.UserId),
|
|
Title: req.Title,
|
|
VideoData: req.VideoData,
|
|
FileName: req.FileName,
|
|
ContentType: req.ContentType,
|
|
}
|
|
|
|
clip, err := h.clipService.CreateClip(ctx, createReq)
|
|
if err != nil {
|
|
return nil, status.Errorf(codes.Internal, "failed to create clip: %v", err)
|
|
}
|
|
|
|
return &proto.CreateClipResponse{
|
|
Clip: h.clipToProto(clip),
|
|
}, nil
|
|
}
|
|
|
|
func (h *GRPCHandler) GetClip(ctx context.Context, req *proto.GetClipRequest) (*proto.GetClipResponse, error) {
|
|
clip, err := h.clipService.GetClip(ctx, int(req.ClipId))
|
|
if err != nil {
|
|
return nil, status.Errorf(codes.NotFound, "clip not found: %v", err)
|
|
}
|
|
|
|
return &proto.GetClipResponse{
|
|
Clip: h.clipToProto(clip),
|
|
}, nil
|
|
}
|
|
|
|
func (h *GRPCHandler) GetUserClips(ctx context.Context, req *proto.GetUserClipsRequest) (*proto.GetUserClipsResponse, error) {
|
|
clips, totalCount, err := h.clipService.GetUserClips(ctx, int(req.UserId), int(req.Limit), int(req.Offset))
|
|
if err != nil {
|
|
return nil, status.Errorf(codes.Internal, "failed to get user clips: %v", err)
|
|
}
|
|
|
|
return &proto.GetUserClipsResponse{
|
|
Clips: h.clipsToProto(clips),
|
|
TotalCount: int32(totalCount),
|
|
}, nil
|
|
}
|
|
|
|
func (h *GRPCHandler) GetClips(ctx context.Context, req *proto.GetClipsRequest) (*proto.GetClipsResponse, error) {
|
|
clips, totalCount, err := h.clipService.GetClips(ctx, int(req.Limit), int(req.Offset))
|
|
if err != nil {
|
|
return nil, status.Errorf(codes.Internal, "failed to get clips: %v", err)
|
|
}
|
|
|
|
return &proto.GetClipsResponse{
|
|
Clips: h.clipsToProto(clips),
|
|
TotalCount: int32(totalCount),
|
|
}, nil
|
|
}
|
|
|
|
func (h *GRPCHandler) DeleteClip(ctx context.Context, req *proto.DeleteClipRequest) (*emptypb.Empty, error) {
|
|
err := h.clipService.DeleteClip(ctx, int(req.ClipId), int(req.UserId))
|
|
if err != nil {
|
|
return nil, status.Errorf(codes.Internal, "failed to delete clip: %v", err)
|
|
}
|
|
|
|
return &emptypb.Empty{}, nil
|
|
}
|
|
|
|
func (h *GRPCHandler) LikeClip(ctx context.Context, req *proto.LikeClipRequest) (*proto.LikeClipResponse, error) {
|
|
like, err := h.likeService.LikeClip(ctx, int(req.ClipId), int(req.UserId))
|
|
if err != nil {
|
|
return nil, status.Errorf(codes.Internal, "failed to like clip: %v", err)
|
|
}
|
|
|
|
return &proto.LikeClipResponse{
|
|
Like: h.likeToProto(like),
|
|
}, nil
|
|
}
|
|
|
|
func (h *GRPCHandler) UnlikeClip(ctx context.Context, req *proto.UnlikeClipRequest) (*emptypb.Empty, error) {
|
|
err := h.likeService.UnlikeClip(ctx, int(req.ClipId), int(req.UserId))
|
|
if err != nil {
|
|
return nil, status.Errorf(codes.Internal, "failed to unlike clip: %v", err)
|
|
}
|
|
|
|
return &emptypb.Empty{}, nil
|
|
}
|
|
|
|
func (h *GRPCHandler) GetClipLikes(ctx context.Context, req *proto.GetClipLikesRequest) (*proto.GetClipLikesResponse, error) {
|
|
likes, totalCount, err := h.likeService.GetClipLikes(ctx, int(req.ClipId), int(req.Limit), int(req.Offset))
|
|
if err != nil {
|
|
return nil, status.Errorf(codes.Internal, "failed to get clip likes: %v", err)
|
|
}
|
|
|
|
return &proto.GetClipLikesResponse{
|
|
Likes: h.likesToProto(likes),
|
|
TotalCount: int32(totalCount),
|
|
}, nil
|
|
}
|
|
|
|
func (h *GRPCHandler) CheckIfLiked(ctx context.Context, req *proto.CheckIfLikedRequest) (*proto.CheckIfLikedResponse, error) {
|
|
isLiked, err := h.likeService.CheckIfLiked(ctx, int(req.ClipId), int(req.UserId))
|
|
if err != nil {
|
|
return nil, status.Errorf(codes.Internal, "failed to check like status: %v", err)
|
|
}
|
|
|
|
return &proto.CheckIfLikedResponse{
|
|
IsLiked: isLiked,
|
|
}, nil
|
|
}
|
|
|
|
func (h *GRPCHandler) CreateComment(ctx context.Context, req *proto.CreateCommentRequest) (*proto.CreateCommentResponse, error) {
|
|
comment, err := h.commentService.CreateComment(ctx, int(req.ClipId), int(req.UserId), req.Content)
|
|
if err != nil {
|
|
return nil, status.Errorf(codes.Internal, "failed to create comment: %v", err)
|
|
}
|
|
|
|
return &proto.CreateCommentResponse{
|
|
Comment: h.commentToProto(comment),
|
|
}, nil
|
|
}
|
|
|
|
func (h *GRPCHandler) GetClipComments(ctx context.Context, req *proto.GetClipCommentsRequest) (*proto.GetClipCommentsResponse, error) {
|
|
comments, totalCount, err := h.commentService.GetClipComments(ctx, int(req.ClipId), int(req.Limit), int(req.Offset))
|
|
if err != nil {
|
|
return nil, status.Errorf(codes.Internal, "failed to get clip comments: %v", err)
|
|
}
|
|
|
|
return &proto.GetClipCommentsResponse{
|
|
Comments: h.commentsToProto(comments),
|
|
TotalCount: int32(totalCount),
|
|
}, nil
|
|
}
|
|
|
|
func (h *GRPCHandler) DeleteComment(ctx context.Context, req *proto.DeleteCommentRequest) (*emptypb.Empty, error) {
|
|
err := h.commentService.DeleteComment(ctx, int(req.CommentId), int(req.UserId))
|
|
if err != nil {
|
|
return nil, status.Errorf(codes.Internal, "failed to delete comment: %v", err)
|
|
}
|
|
|
|
return &emptypb.Empty{}, nil
|
|
}
|
|
|
|
// Вспомогательные методы для конвертации
|
|
|
|
func (h *GRPCHandler) clipToProto(clip *domain.Clip) *proto.Clip {
|
|
if clip == nil {
|
|
return nil
|
|
}
|
|
|
|
return &proto.Clip{
|
|
Id: int32(clip.ID),
|
|
Title: clip.Title,
|
|
VideoUrl: clip.VideoURL,
|
|
ThumbnailUrl: clip.ThumbnailURL,
|
|
AuthorId: int32(clip.AuthorID),
|
|
LikesCount: int32(clip.LikesCount),
|
|
CommentsCount: int32(clip.CommentsCount),
|
|
CreatedAt: timestamppb.New(clip.CreatedAt),
|
|
UpdatedAt: timestamppb.New(clip.UpdatedAt),
|
|
}
|
|
}
|
|
|
|
func (h *GRPCHandler) clipsToProto(clips []*domain.Clip) []*proto.Clip {
|
|
var protoClips []*proto.Clip
|
|
for _, clip := range clips {
|
|
protoClips = append(protoClips, h.clipToProto(clip))
|
|
}
|
|
return protoClips
|
|
}
|
|
|
|
func (h *GRPCHandler) likeToProto(like *domain.ClipLike) *proto.ClipLike {
|
|
if like == nil {
|
|
return nil
|
|
}
|
|
|
|
return &proto.ClipLike{
|
|
Id: int32(like.ID),
|
|
ClipId: int32(like.ClipID),
|
|
UserId: int32(like.UserID),
|
|
CreatedAt: timestamppb.New(like.CreatedAt),
|
|
}
|
|
}
|
|
|
|
func (h *GRPCHandler) likesToProto(likes []*domain.ClipLike) []*proto.ClipLike {
|
|
var protoLikes []*proto.ClipLike
|
|
for _, like := range likes {
|
|
protoLikes = append(protoLikes, h.likeToProto(like))
|
|
}
|
|
return protoLikes
|
|
}
|
|
|
|
func (h *GRPCHandler) commentToProto(comment *domain.ClipComment) *proto.ClipComment {
|
|
if comment == nil {
|
|
return nil
|
|
}
|
|
|
|
return &proto.ClipComment{
|
|
Id: int32(comment.ID),
|
|
ClipId: int32(comment.ClipID),
|
|
AuthorId: int32(comment.AuthorID),
|
|
Content: comment.Content,
|
|
CreatedAt: timestamppb.New(comment.CreatedAt),
|
|
UpdatedAt: timestamppb.New(comment.UpdatedAt),
|
|
}
|
|
}
|
|
|
|
func (h *GRPCHandler) commentsToProto(comments []*domain.ClipComment) []*proto.ClipComment {
|
|
var protoComments []*proto.ClipComment
|
|
for _, comment := range comments {
|
|
protoComments = append(protoComments, h.commentToProto(comment))
|
|
}
|
|
return protoComments
|
|
}
|