From 143afdb885ca453a81073cbffdbcb82e9402f7a6 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Fri, 24 Jan 2025 00:54:16 +0800 Subject: [PATCH] :sparkles: Internal grpc apis --- pkg/internal/grpc/attachment.go | 104 +++++++++++++++++++++++++++++ pkg/internal/grpc/server.go | 9 ++- pkg/internal/models/attachments.go | 19 ++++++ pkg/proto/attachment.proto | 60 +++++++++++++++++ 4 files changed, 189 insertions(+), 3 deletions(-) create mode 100644 pkg/internal/grpc/attachment.go create mode 100644 pkg/proto/attachment.proto diff --git a/pkg/internal/grpc/attachment.go b/pkg/internal/grpc/attachment.go new file mode 100644 index 0000000..f5b639e --- /dev/null +++ b/pkg/internal/grpc/attachment.go @@ -0,0 +1,104 @@ +package grpc + +import ( + "context" + "git.solsynth.dev/hypernet/paperclip/pkg/internal/database" + "git.solsynth.dev/hypernet/paperclip/pkg/internal/models" + "git.solsynth.dev/hypernet/paperclip/pkg/proto" + "github.com/samber/lo" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (v *Server) GetAttachment(ctx context.Context, request *proto.GetAttachmentRequest) (*proto.GetAttachmentResponse, error) { + tx := database.C + if request.Id != nil { + tx = tx.Where("id = ?", request.Id) + } else if request.Rid != nil { + tx = tx.Where("rid = ?", request.Rid) + } else { + return nil, status.Error(codes.InvalidArgument, "you must provide id or random id") + } + + var attachment models.Attachment + if err := tx.First(&attachment).Error; err != nil { + return nil, status.Error(codes.NotFound, "attachment not found") + } + + return &proto.GetAttachmentResponse{ + Attachment: lo.ToPtr(attachment).ToAttachmentInfo(), + }, nil +} + +func (v *Server) ListAttachment(ctx context.Context, request *proto.ListAttachmentRequest) (*proto.ListAttachmentResponse, error) { + tx := database.C + if len(request.Id) == 0 && len(request.Rid) == 0 { + return nil, status.Error(codes.InvalidArgument, "you must provide at least one id or random id") + } + if len(request.Id) > 0 { + tx = tx.Where("id IN ?", request.Id) + } + if len(request.Rid) > 0 { + tx = tx.Where("rid IN ?", request.Rid) + } + + attachments := make([]models.Attachment, 0) + err := tx.Find(&attachments).Error + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + return &proto.ListAttachmentResponse{ + Attachments: lo.Map(attachments, func(v models.Attachment, _ int) *proto.AttachmentInfo { + return v.ToAttachmentInfo() + }), + }, nil +} + +func (v *Server) UpdateVisibility(ctx context.Context, request *proto.UpdateVisibilityRequest) (*proto.UpdateVisibilityResponse, error) { + tx := database.C + if len(request.Id) == 0 && len(request.Rid) == 0 { + return nil, status.Error(codes.InvalidArgument, "you must provide at least one id or random id") + } + if len(request.Id) > 0 { + tx = tx.Where("id IN ?", request.Id) + } + if len(request.Rid) > 0 { + tx = tx.Where("rid IN ?", request.Rid) + } + + var rowsAffected int64 + if err := tx.Update("is_indexable", request.IsIndexable).Error; err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } else { + rowsAffected = tx.RowsAffected + } + + return &proto.UpdateVisibilityResponse{ + Count: int32(rowsAffected), + }, nil +} + +func (v *Server) DeleteAttachment(ctx context.Context, request *proto.DeleteAttachmentRequest) (*proto.DeleteAttachmentResponse, error) { + tx := database.C + if len(request.Id) == 0 && len(request.Rid) == 0 { + return nil, status.Error(codes.InvalidArgument, "you must provide at least one id or random id") + } + if len(request.Id) > 0 { + tx = tx.Where("id IN ?", request.Id) + } + if len(request.Rid) > 0 { + tx = tx.Where("rid IN ?", request.Rid) + } + + var rowsAffected int64 + if err := tx.Delete(&models.Attachment{}).Error; err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } else { + rowsAffected = tx.RowsAffected + } + + return &proto.DeleteAttachmentResponse{ + Count: int32(rowsAffected), + }, nil +} diff --git a/pkg/internal/grpc/server.go b/pkg/internal/grpc/server.go index 3f23e3a..336680f 100644 --- a/pkg/internal/grpc/server.go +++ b/pkg/internal/grpc/server.go @@ -1,9 +1,10 @@ package grpc import ( + "git.solsynth.dev/hypernet/paperclip/pkg/proto" "net" - "git.solsynth.dev/hypernet/nexus/pkg/proto" + nproto "git.solsynth.dev/hypernet/nexus/pkg/proto" "github.com/spf13/viper" "google.golang.org/grpc" health "google.golang.org/grpc/health/grpc_health_v1" @@ -11,7 +12,8 @@ import ( ) type Server struct { - proto.UnimplementedDirectoryServiceServer + nproto.UnimplementedDirectoryServiceServer + proto.UnimplementedAttachmentServiceServer health.UnimplementedHealthServer srv *grpc.Server @@ -22,7 +24,8 @@ func NewGrpc() *Server { srv: grpc.NewServer(), } - proto.RegisterDirectoryServiceServer(server.srv, server) + nproto.RegisterDirectoryServiceServer(server.srv, server) + proto.RegisterAttachmentServiceServer(server.srv, server) health.RegisterHealthServer(server.srv, server) reflection.Register(server.srv) diff --git a/pkg/internal/models/attachments.go b/pkg/internal/models/attachments.go index 8a5aa3b..2e628fd 100644 --- a/pkg/internal/models/attachments.go +++ b/pkg/internal/models/attachments.go @@ -3,6 +3,8 @@ package models import ( "context" "fmt" + "git.solsynth.dev/hypernet/paperclip/pkg/proto" + "strconv" "time" "git.solsynth.dev/hypernet/nexus/pkg/nex/cruda" @@ -77,6 +79,23 @@ type Attachment struct { IsMature bool `json:"is_mature" gorm:"-"` } +func (v *Attachment) ToAttachmentInfo() *proto.AttachmentInfo { + if v == nil { + return nil + } + + return &proto.AttachmentInfo{ + Id: v.Uuid, + Rid: v.Rid, + Name: v.Name, + Type: v.MimeType, + Size: strconv.FormatInt(v.Size, 10), + Hash: v.HashCode, + Mime: v.MimeType, + IsIndexable: v.IsIndexable, + } +} + func (v *Attachment) AfterUpdate(tx *gorm.DB) error { cacheManager := cache.New[any](localCache.S) marshal := marshaler.New(cacheManager) diff --git a/pkg/proto/attachment.proto b/pkg/proto/attachment.proto new file mode 100644 index 0000000..34d38af --- /dev/null +++ b/pkg/proto/attachment.proto @@ -0,0 +1,60 @@ +syntax = "proto3"; + +option go_package = ".;proto"; + +package proto; + +service AttachmentService { + rpc GetAttachment(GetAttachmentRequest) returns (GetAttachmentResponse) {} + rpc ListAttachment(ListAttachmentRequest) returns (ListAttachmentResponse) {} + rpc UpdateVisibility(UpdateVisibilityRequest) returns (UpdateVisibilityResponse) {} + rpc DeleteAttachment(DeleteAttachmentRequest) returns (DeleteAttachmentResponse) {} +} + +message AttachmentInfo { + string id = 1; + string rid = 2; + string name = 3; + string type = 4; + string size = 5; + string hash = 6; + string mime = 7; + bool is_indexable = 8; +} + +message GetAttachmentRequest { + optional uint64 id = 1; + optional string rid = 2; +} + +message GetAttachmentResponse { + optional AttachmentInfo attachment = 1; +} + +message ListAttachmentRequest { + repeated uint64 id = 1; + repeated string rid = 2; +} + +message ListAttachmentResponse { + repeated AttachmentInfo attachments = 1; +} + +message UpdateVisibilityRequest { + repeated uint64 id = 1; + repeated string rid = 2; + bool is_indexable = 3; +} + +message UpdateVisibilityResponse { + int32 count = 1; +} + +message DeleteAttachmentRequest { + repeated uint64 id = 1; + repeated string rid = 2; +} + +message DeleteAttachmentResponse { + int32 count = 1; +} \ No newline at end of file