versia-go/internal/service/svc_impls/Inbox_service_impl.go

145 lines
4 KiB
Go
Raw Normal View History

2024-08-11 03:51:22 +02:00
package svc_impls
import (
"context"
"github.com/google/uuid"
"github.com/lysand-org/versia-go/internal/repository"
"github.com/lysand-org/versia-go/internal/service"
2024-08-22 23:03:38 +02:00
"github.com/lysand-org/versia-go/pkg/versia"
2024-08-11 03:51:22 +02:00
"git.devminer.xyz/devminer/unitel"
"github.com/go-logr/logr"
"github.com/lysand-org/versia-go/ent"
"github.com/lysand-org/versia-go/ent/user"
"github.com/lysand-org/versia-go/internal/api_schema"
"github.com/lysand-org/versia-go/internal/entity"
)
var _ service.InboxService = (*InboxServiceImpl)(nil)
type InboxServiceImpl struct {
federationService service.FederationService
2024-08-20 22:43:26 +02:00
repositories repository.Manager
2024-08-11 03:51:22 +02:00
telemetry *unitel.Telemetry
log logr.Logger
}
2024-08-20 22:43:26 +02:00
func NewInboxService(federationService service.FederationService, repositories repository.Manager, telemetry *unitel.Telemetry, log logr.Logger) *InboxServiceImpl {
2024-08-11 03:51:22 +02:00
return &InboxServiceImpl{
federationService: federationService,
2024-08-20 22:43:26 +02:00
repositories: repositories,
telemetry: telemetry,
log: log,
2024-08-11 03:51:22 +02:00
}
}
func (i InboxServiceImpl) WithRepositories(repositories repository.Manager) service.InboxService {
2024-08-20 22:43:26 +02:00
return NewInboxService(i.federationService, repositories, i.telemetry, i.log)
2024-08-11 03:51:22 +02:00
}
func (i InboxServiceImpl) Handle(ctx context.Context, obj any, userId uuid.UUID) error {
2024-08-20 22:43:26 +02:00
s := i.telemetry.StartSpan(ctx, "function", "svc_impls/InboxServiceImpl.Handle")
2024-08-11 03:51:22 +02:00
defer s.End()
ctx = s.Context()
return i.repositories.Atomic(ctx, func(ctx context.Context, tx repository.Manager) error {
i := i.WithRepositories(tx).(*InboxServiceImpl)
u, err := i.repositories.Users().GetLocalByID(ctx, userId)
if err != nil {
i.log.Error(err, "Failed to get user", "id", userId)
return api_schema.ErrInternalServerError(nil)
}
if u == nil {
return api_schema.ErrNotFound(map[string]any{
"id": userId,
})
}
// TODO: Implement more types
switch o := obj.(type) {
2024-08-22 23:03:38 +02:00
case versia.Note:
2024-08-11 03:51:22 +02:00
i.log.Info("Received note", "note", o)
if err := i.handleNote(ctx, o, u); err != nil {
i.log.Error(err, "Failed to handle note", "note", o)
return err
}
2024-08-22 23:03:38 +02:00
case versia.Follow:
2024-08-11 03:51:22 +02:00
if err := i.handleFollow(ctx, o, u); err != nil {
i.log.Error(err, "Failed to handle follow", "follow", o)
return err
}
default:
i.log.Info("Unimplemented object type", "object", obj)
return api_schema.ErrNotImplemented(nil)
}
return nil
})
}
2024-08-22 23:03:38 +02:00
func (i InboxServiceImpl) handleFollow(ctx context.Context, o versia.Follow, u *entity.User) error {
2024-08-20 22:43:26 +02:00
s := i.telemetry.StartSpan(ctx, "function", "svc_impls/InboxServiceImpl.handleFollow")
2024-08-11 03:51:22 +02:00
defer s.End()
ctx = s.Context()
author, err := i.repositories.Users().Resolve(ctx, o.Author)
if err != nil {
i.log.Error(err, "Failed to resolve author", "author", o.Author)
return err
}
f, err := i.repositories.Follows().Follow(ctx, author, u)
if err != nil {
// TODO: Handle constraint errors
if ent.IsConstraintError(err) {
i.log.Error(err, "Follow already exists", "user", user.ID, "author", author.ID)
return nil
}
i.log.Error(err, "Failed to create follow", "user", user.ID, "author", author.ID)
return err
}
switch u.PrivacyLevel {
case user.PrivacyLevelPublic:
if err := i.repositories.Follows().AcceptFollow(ctx, author, u); err != nil {
i.log.Error(err, "Failed to accept follow", "user", user.ID, "author", author.ID)
return err
}
if _, err := i.federationService.SendToInbox(ctx, u, author, f.ToLysandAccept()); err != nil {
i.log.Error(err, "Failed to send follow accept to inbox", "user", user.ID, "author", author.ID)
return err
}
case user.PrivacyLevelRestricted:
case user.PrivacyLevelPrivate:
}
return nil
}
2024-08-22 23:03:38 +02:00
func (i InboxServiceImpl) handleNote(ctx context.Context, o versia.Note, u *entity.User) error {
2024-08-20 22:43:26 +02:00
s := i.telemetry.StartSpan(ctx, "function", "svc_impls/InboxServiceImpl.handleNote")
2024-08-11 03:51:22 +02:00
defer s.End()
ctx = s.Context()
author, err := i.repositories.Users().Resolve(ctx, o.Author)
if err != nil {
i.log.Error(err, "Failed to resolve author", "author", o.Author)
return err
}
// TODO: Implement
_ = author
return nil
}