67 lines
1.5 KiB
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
|
|
}
|