ultisuite-backend/internal/api/contacts/service.go

86 lines
2.5 KiB
Go

package contacts
import (
"context"
"strings"
"github.com/ultisuite/ulti-backend/internal/api/paginate"
"github.com/ultisuite/ulti-backend/internal/api/query"
"github.com/ultisuite/ulti-backend/internal/nextcloud"
)
type Service struct {
nc *nextcloud.Client
}
func NewService(nc *nextcloud.Client) *Service {
return &Service{nc: nc}
}
func bookPath(userID, bookID string) string {
return "/remote.php/dav/addressbooks/users/" + userID + "/" + bookID + "/"
}
func (s *Service) ListAddressBooks(ctx context.Context, userID string) ([]nextcloud.AddressBook, error) {
return s.nc.ListAddressBooks(ctx, userID)
}
type ContactsList struct {
Contacts []nextcloud.Contact `json:"contacts"`
Pagination query.PaginationMeta `json:"pagination,omitempty"`
}
func (s *Service) ListContacts(ctx context.Context, userID, bookID string, params query.ListParams) (ContactsList, error) {
contacts, err := s.nc.ListContacts(ctx, userID, bookPath(userID, bookID))
if err != nil {
return ContactsList{}, err
}
filtered := filterContacts(contacts, params.Q)
page, total := paginate.Slice(filtered, params.Offset(), params.Limit())
return ContactsList{
Contacts: page,
Pagination: params.Meta(&total),
}, nil
}
func (s *Service) SearchContacts(ctx context.Context, userID, bookID, q string, params query.ListParams) (ContactsList, error) {
searchQ := strings.TrimSpace(q)
if searchQ == "" {
searchQ = strings.TrimSpace(params.Q)
}
contacts, err := s.nc.SearchContacts(ctx, userID, bookPath(userID, bookID), searchQ)
if err != nil {
return ContactsList{}, err
}
page, total := paginate.Slice(contacts, params.Offset(), params.Limit())
return ContactsList{
Contacts: page,
Pagination: params.Meta(&total),
}, nil
}
func (s *Service) CreateContact(ctx context.Context, userID, bookID string, contact *nextcloud.Contact) error {
return s.nc.CreateContact(ctx, userID, bookPath(userID, bookID), contact)
}
func (s *Service) DeleteContact(ctx context.Context, userID, contactPath string) error {
return s.nc.DeleteContact(ctx, userID, contactPath)
}
func filterContacts(contacts []nextcloud.Contact, q string) []nextcloud.Contact {
q = strings.ToLower(strings.TrimSpace(q))
if q == "" {
return contacts
}
out := make([]nextcloud.Contact, 0, len(contacts))
for _, c := range contacts {
if strings.Contains(strings.ToLower(c.FullName), q) ||
strings.Contains(strings.ToLower(c.Email), q) ||
strings.Contains(strings.ToLower(c.Phone), q) ||
strings.Contains(strings.ToLower(c.Org), q) {
out = append(out, c)
}
}
return out
}