hub/internal/topic/usecase/topic_ucase.go

67 lines
1.5 KiB
Go

package usecase
import (
"context"
"errors"
"fmt"
"io"
"net/http"
"net/url"
"time"
"source.toby3d.me/toby3d/hub/internal/common"
"source.toby3d.me/toby3d/hub/internal/domain"
"source.toby3d.me/toby3d/hub/internal/topic"
)
type topicUseCase struct {
client *http.Client
topics topic.Repository
}
func NewTopicUseCase(topics topic.Repository, client *http.Client) topic.UseCase {
return &topicUseCase{
topics: topics,
client: client,
}
}
func (ucase *topicUseCase) Publish(ctx context.Context, u *url.URL) (bool, error) {
now := time.Now().UTC().Round(time.Second)
resp, err := ucase.client.Get(u.String())
if err != nil {
return false, fmt.Errorf("cannot fetch publishing url: %w", err)
}
content, err := io.ReadAll(resp.Body)
if err != nil {
return false, fmt.Errorf("cannot read topic response body: %w", err)
}
if err := ucase.topics.Update(ctx, u, func(tx *domain.Topic) (*domain.Topic, error) {
tx.Self = resp.Request.URL
tx.UpdatedAt = now
tx.Content = content
tx.ContentType = resp.Header.Get(common.HeaderContentType)
return tx, nil
}); err != nil {
if !errors.Is(err, topic.ErrNotExist) {
return false, fmt.Errorf("cannot publish exists topic: %w", err)
}
if err = ucase.topics.Create(ctx, resp.Request.URL, domain.Topic{
CreatedAt: now,
UpdatedAt: now,
Self: resp.Request.URL,
ContentType: resp.Header.Get(common.HeaderContentType),
Content: content,
}); err != nil {
return false, fmt.Errorf("cannot publish a new topic: %w", err)
}
}
return true, nil
}