From 5c873a2707fd692b730c1ff66ca0952e65a4e3f1 Mon Sep 17 00:00:00 2001 From: "Gustavo \"Guz\" L de Mello" Date: Fri, 28 Mar 2025 16:39:32 -0300 Subject: [PATCH] refactor(service,router): return ProjectPage struct instead of just image reader --- router/editor.go | 6 +++--- service/editor.go | 35 ++++++++++++++++++++++++++++------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/router/editor.go b/router/editor.go index 2dab46a..e6b070b 100644 --- a/router/editor.go +++ b/router/editor.go @@ -87,7 +87,7 @@ func (router *router) getPage(w http.ResponseWriter, r *http.Request) { imgID := r.PathValue("PageID") router.assert.NotZero(imgID, "This method should be used after the path values are checked") - img, err := router.service.GetPage(id, imgID) + page, err := router.service.GetPage(id, pageID) if errors.Is(err, service.ErrPageNotExists) { exception.NotFound(exception.WithError(err)).ServeHTTP(w, r) return @@ -97,10 +97,10 @@ func (router *router) getPage(w http.ResponseWriter, r *http.Request) { return } - if i, ok := img.(io.WriterTo); ok { + if i, ok := page.Image.(io.WriterTo); ok { _, err = i.WriteTo(w) } else { - _, err = io.Copy(w, img) + _, err = io.Copy(w, page.Image) } if err != nil { diff --git a/service/editor.go b/service/editor.go index 5e9b2ce..e3d4688 100644 --- a/service/editor.go +++ b/service/editor.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "net/http" + "slices" "forge.capytal.company/capytalcode/project-comicverse/internals/randstr" awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" @@ -21,7 +22,10 @@ type Project struct { Pages []ProjectPage `json:"pages"` } -type ProjectPage struct{} +type ProjectPage struct { + ID string `json:"id"` + Image io.ReadCloser `json:"-"` +} func (s *Service) AddPage(projectID string, img io.Reader) error { s.assert.NotNil(s.ctx) @@ -56,14 +60,25 @@ func (s *Service) AddPage(projectID string, img io.Reader) error { return err } -func (s *Service) GetPage(projectID string, imgID string) (io.Reader, error) { +func (s *Service) GetPage(projectID string, pageID string) (ProjectPage, error) { s.assert.NotNil(s.ctx) s.assert.NotNil(s.s3) s.assert.NotNil(s.bucket) s.assert.NotZero(projectID) - s.assert.NotNil(imgID) + s.assert.NotNil(pageID) - k := fmt.Sprintf("%s/%s", projectID, imgID) + p, err := s.GetProject(projectID) + if err != nil { + return ProjectPage{}, errors.Join(errors.New("unable to get project"), err) + } + + pageIndex := slices.IndexFunc(p.Pages, func(p ProjectPage) bool { return p.ID == pageID }) + if pageIndex == -1 { + return ProjectPage{}, ErrPageNotExists + } + page := p.Pages[pageIndex] + + k := fmt.Sprintf("%s/%s", projectID, pageID) res, err := s.s3.GetObject(s.ctx, &s3.GetObjectInput{ Key: &k, Bucket: &s.bucket, @@ -71,13 +86,19 @@ func (s *Service) GetPage(projectID string, imgID string) (io.Reader, error) { if err != nil { var resErr *awshttp.ResponseError if errors.As(err, &resErr) && resErr.ResponseError.HTTPStatusCode() == http.StatusNotFound { - return nil, errors.Join(ErrPageNotExists, resErr) + // TODO: This would probably be better in some background "maintenance" worker + p.Pages = slices.Delete(p.Pages, pageIndex, pageIndex) + _ = s.UpdateProject(projectID, p) + + return ProjectPage{}, errors.Join(ErrPageNotExists, resErr) } - return nil, err + return ProjectPage{}, err } s.assert.NotNil(res.Body) - return res.Body, nil + page.Image = res.Body + + return page, nil } func (s *Service) DeletePage(projectID string, id string) error {