Skip to content

Commit

Permalink
chore: dependency update fallout
Browse files Browse the repository at this point in the history
  • Loading branch information
blackfyre committed Jan 31, 2025
1 parent fca5017 commit fef7bee
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 141 deletions.
3 changes: 2 additions & 1 deletion errs/artists.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ package errs

import "errors"

var ErrArtistNotFound = errors.New("artist not found")
var ErrArtistNotFound = errors.New("Artist not found")
var ErrArtworkNotFound = errors.New("Artwork not found")
141 changes: 61 additions & 80 deletions handlers/artist/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package artist

import (
"bytes"
"cmp"
"context"
"encoding/json"
Expand All @@ -12,14 +13,13 @@ import (
"github.com/blackfyre/wga/assets/templ/dto"
"github.com/blackfyre/wga/assets/templ/pages"
tmplUtils "github.com/blackfyre/wga/assets/templ/utils"
wgaModels "github.com/blackfyre/wga/models"
"github.com/blackfyre/wga/errs"
"github.com/blackfyre/wga/utils"
"github.com/blackfyre/wga/utils/jsonld"
"github.com/blackfyre/wga/utils/url"
"github.com/labstack/echo/v5"
"github.com/pocketbase/pocketbase"
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/models"
)

const (
Expand Down Expand Up @@ -77,24 +77,23 @@ func normalizedBioExcerpt(d BioExcerptDTO) string {
// findArtworksByAuthorId retrieves a list of artworks by the given author ID.
// It uses the provided PocketBase instance to query the database and returns
// a slice of Record pointers and an error, if any.
func findArtworksByAuthorId(app *pocketbase.PocketBase, authorId string) ([]*models.Record, error) {
return app.Dao().FindRecordsByFilter("artworks", "author = '"+authorId+"'", "+title", 100, 0)
func findArtworksByAuthorId(app *pocketbase.PocketBase, authorId string) ([]*core.Record, error) {
return app.FindRecordsByFilter("artworks", "author = '"+authorId+"'", "+title", 100, 0)
}

// RenderArtistContent renders the content of an artist by generating a DTO (Data Transfer Object) that contains
// information about the artist, their works, and JSON-LD metadata. It takes the PocketBase application instance,
// the Echo context, and the artist record as input parameters. It returns the DTO representing the artist content
// and an error if any occurred during the process.
func RenderArtistContent(app *pocketbase.PocketBase, c echo.Context, artist *models.Record, hxTarget string) (dto.Artist, error) {
id := artist.GetId()
func RenderArtistContent(app *pocketbase.PocketBase, c *core.RequestEvent, artist *core.Record, hxTarget string) (dto.Artist, error) {
id := artist.GetString("id")
expectedSlug := utils.GenerateArtistSlug(artist)

works, err := findArtworksByAuthorId(app, id)

if err != nil {
app.Logger().Error("Error finding artworks: ", "error", err.Error())

return dto.Artist{}, utils.NotFoundError(c)
return dto.Artist{}, errs.ErrArtistNotFound
}

schools := utils.RenderSchoolNames(app, artist.GetStringSlice("school"))
Expand All @@ -119,21 +118,7 @@ func RenderArtistContent(app *pocketbase.PocketBase, c echo.Context, artist *mod
HxTarget: hxTarget,
}

artistReferenceModel := &wgaModels.Artist{
Id: artist.GetId(),
Name: artist.GetString("name"),
Slug: artist.GetString("slug"),
Bio: artist.GetString("bio"),
YearOfBirth: artist.GetInt("year_of_birth"),
YearOfDeath: artist.GetInt("year_of_death"),
PlaceOfBirth: artist.GetString("place_of_birth"),
PlaceOfDeath: artist.GetString("place_of_death"),
Published: artist.GetBool("published"),
School: schools,
Profession: artist.GetString("profession"),
}

JsonLd := jsonld.ArtistJsonLd(artistReferenceModel, c)
JsonLd := jsonld.ArtistJsonLd(artist)

marshalled, err := json.Marshal(JsonLd)

Expand All @@ -145,22 +130,22 @@ func RenderArtistContent(app *pocketbase.PocketBase, c echo.Context, artist *mod

for _, w := range works {

artJsonLd := jsonld.ArtworkJsonLd(w, artistReferenceModel, c)
artJsonLd := jsonld.ArtworkJsonLd(w, artist)

marshalled, err := json.Marshal(artJsonLd)

if err != nil {
app.Logger().Error("Error marshalling artwork jsonld for"+w.GetId(), "error", err.Error())
app.Logger().Error("Error marshalling artwork jsonld for"+w.GetString("id"), "error", err.Error())
}

content.Works = append(content.Works, dto.Image{
Id: w.GetId(),
Id: w.GetString("id"),
Title: w.GetString("title"),
Comment: w.GetString("comment"),
Technique: w.GetString("technique"),
Image: url.GenerateFileUrl("artworks", w.GetString("id"), w.GetString("image"), ""),
Thumb: url.GenerateThumbUrl("artworks", w.GetString("id"), w.GetString("image"), "320x240", ""),
Url: c.Request().URL.String() + "/" + utils.Slugify(w.GetString("title")) + "-" + w.GetString("id"),
Url: utils.AssetUrl(utils.Slugify(w.GetString("title")) + "-" + w.GetString("id")),
Jsonld: fmt.Sprintf(`<script type="application/ld+json">%s</script>`, marshalled),
HxTarget: hxTarget,
})
Expand All @@ -175,13 +160,13 @@ func RenderArtistContent(app *pocketbase.PocketBase, c echo.Context, artist *mod
// If the artist is not found, it returns a not found error.
// If the rendering fails, it returns an error.
// It also sets the HX-Push-Url header to enable Htmx push for the artist page.
func processArtist(c echo.Context, app *pocketbase.PocketBase) error {
slug := c.PathParam("name")
func processArtist(c *core.RequestEvent, app *pocketbase.PocketBase) error {
slug := c.Request.PathValue("name")

id := utils.ExtractIdFromString(slug)

fullUrl := utils.GenerateCurrentPageUrl(c)
artist, err := app.Dao().FindRecordById("artists", id)
artist, err := app.FindRecordById("artists", id)

if err != nil {
app.Logger().Error("Artist not found: ", slug, err)
Expand All @@ -204,19 +189,22 @@ func processArtist(c echo.Context, app *pocketbase.PocketBase) error {
ctx = tmplUtils.DecorateContext(ctx, tmplUtils.DescriptionKey, content.Bio)
ctx = tmplUtils.DecorateContext(ctx, tmplUtils.OgUrlKey, fullUrl)
if len(content.Works) > 0 {
ctx = tmplUtils.DecorateContext(ctx, tmplUtils.OgImageKey, c.Scheme()+"://"+c.Request().Host+content.Works[0].Image)
ctx = tmplUtils.DecorateContext(ctx, tmplUtils.OgImageKey, utils.AssetUrl(content.Works[0].Image))
}

c.Response().Header().Set("HX-Push-Url", fullUrl)
err = pages.ArtistPage(content).Render(ctx, c.Response().Writer)
c.Response.Header().Set("HX-Push-Url", fullUrl)

var buff bytes.Buffer

err = pages.ArtistPage(content).Render(ctx, &buff)

if err != nil {
app.Logger().Error("Error rendering artist page", "error", err.Error())

return utils.ServerFaultError(c)
}

return nil
return c.HTML(http.StatusOK, buff.String())
}

// processArtwork processes the artwork based on the given context and PocketBase application.
Expand All @@ -229,20 +217,20 @@ func processArtist(c echo.Context, app *pocketbase.PocketBase) error {
// - app: The PocketBase application instance.
// Returns:
// - An error if any error occurs during the processing, or nil if the processing is successful.
func processArtwork(c echo.Context, app *pocketbase.PocketBase) error {
artistSlug := c.PathParam("name")
artworkSlug := c.PathParam("awid")
func processArtwork(c *core.RequestEvent, app *pocketbase.PocketBase) error {
artistSlug := c.Request.PathValue("name")
artworkSlug := c.Request.PathValue("awid")

// split the slug on the last dash and use the last part as the artist id
artistSlugParts := strings.Split(artistSlug, "-")
artistId := artistSlugParts[len(artistSlugParts)-1]

artist, err := app.Dao().FindRecordById("artists", artistId)
artist, err := app.FindRecordById("artists", artistId)

// if the artist is not found, return a not found error
if err != nil {
app.Logger().Error("Artist not found: ", artistSlug, err)
return utils.NotFoundError(c)
return errs.ErrArtistNotFound
}

// generate the expected slug for the artist
Expand All @@ -253,11 +241,11 @@ func processArtwork(c echo.Context, app *pocketbase.PocketBase) error {
artworkId := artworkSlugParts[len(artworkSlugParts)-1]

// find the artwork by id
aw, err := app.Dao().FindRecordById("artworks", artworkId)
aw, err := app.FindRecordById("artworks", artworkId)

if err != nil {
app.Logger().Error("Error finding artwork: ", artworkSlug, err)
return utils.NotFoundError(c)
return errs.ErrArtworkNotFound
}

// generate the expected slug for the artwork
Expand All @@ -269,14 +257,14 @@ func processArtwork(c echo.Context, app *pocketbase.PocketBase) error {
}

content := dto.Artwork{
Id: aw.GetId(),
Id: aw.GetString("id"),
Title: aw.GetString("title"),
Comment: aw.GetString("comment"),
Technique: aw.GetString("technique"),
Url: url.GenerateFullArtworkUrl(url.ArtworkUrlDTO{
ArtistName: artist.GetString("name"),
ArtistId: artist.Id,
ArtworkId: aw.GetId(),
ArtworkId: aw.GetString("id"),
ArtworkTitle: aw.GetString("title"),
}),
Image: dto.Image{
Expand All @@ -288,25 +276,25 @@ func processArtwork(c echo.Context, app *pocketbase.PocketBase) error {
Thumb: url.GenerateThumbUrl("artworks", aw.GetString("id"), aw.GetString("image"), "320x240", ""),
},
Artist: dto.Artist{
Id: artist.GetId(),
Id: artist.GetString("id"),
Name: artist.GetString("name"),
Bio: artist.GetString("bio"),
Profession: artist.GetString("profession"),
Url: url.GenerateArtistUrl(url.ArtistUrlDTO{
ArtistId: artist.GetId(),
ArtistId: artist.GetString("id"),
ArtistName: artist.GetString("name"),
}),
},
}

fullUrl := c.Scheme() + "://" + c.Request().Host + c.Request().URL.String()
fullUrl := c.Request.URL.Scheme + "://" + c.Request.URL.Host + c.Request.URL.String()

school := artist.GetStringSlice("school")

var schoolCollector []string

for _, s := range school {
r, err := app.Dao().FindRecordById("schools", s)
r, err := app.FindRecordById("schools", s)

if err != nil {
app.Logger().Error("school not found", "error", err.Error())
Expand All @@ -317,74 +305,65 @@ func processArtwork(c echo.Context, app *pocketbase.PocketBase) error {

}

jsonLd := jsonld.ArtworkJsonLd(aw, &wgaModels.Artist{
Id: artist.GetId(),
Name: artist.GetString("name"),
Slug: artist.GetString("slug"),
Bio: artist.GetString("bio"),
YearOfBirth: artist.GetInt("year_of_birth"),
YearOfDeath: artist.GetInt("year_of_death"),
PlaceOfBirth: artist.GetString("place_of_birth"),
PlaceOfDeath: artist.GetString("place_of_death"),
Published: artist.GetBool("published"),
School: strings.Join(schoolCollector, ", "),
Profession: artist.GetString("profession"),
}, c)
jsonLd := jsonld.ArtworkJsonLd(aw, artist)

marshalled, err := json.Marshal(jsonLd)

if err != nil {
app.Logger().Error("Error marshalling artwork jsonld for"+aw.GetId(), "error", err.Error())
app.Logger().Error("Error marshalling artwork jsonld for"+aw.GetString("id"), "error", err.Error())
}

content.Jsonld = fmt.Sprintf(`<script type="application/ld+json">%s</script>`, marshalled)

ctx := tmplUtils.DecorateContext(context.Background(), tmplUtils.TitleKey, fmt.Sprintf("%s - %s", content.Title, content.Artist.Name))
ctx = tmplUtils.DecorateContext(ctx, tmplUtils.DescriptionKey, content.Comment)
ctx = tmplUtils.DecorateContext(ctx, tmplUtils.CanonicalUrlKey, fullUrl)
ctx = tmplUtils.DecorateContext(ctx, tmplUtils.OgImageKey, c.Scheme()+"://"+c.Request().Host+content.Image.Image)
ctx = tmplUtils.DecorateContext(ctx, tmplUtils.OgImageKey, utils.AssetUrl(content.Image.Image))

c.Response.Header().Set("HX-Push-Url", fullUrl)

c.Response().Header().Set("HX-Push-Url", fullUrl)
err = pages.ArtworkPage(content).Render(ctx, c.Response().Writer)
var buff bytes.Buffer

err = pages.ArtworkPage(content).Render(ctx, &buff)

if err != nil {
app.Logger().Error("Error rendering artwork page", "error", err.Error())
return c.String(http.StatusInternalServerError, "failed to render response template")
}

return nil
return c.HTML(http.StatusOK, buff.String())
}

func RenderArtworkContent(app *pocketbase.PocketBase, c echo.Context, artwork *models.Record, hxTarget string) (dto.Artwork, error) {
func RenderArtworkContent(app *pocketbase.PocketBase, c echo.Context, artwork *core.Record, hxTarget string) (dto.Artwork, error) {

artistId := cmp.Or(artwork.GetStringSlice("author")[0], "")

var artworkUrl string
var artist *models.Record
var artist *core.Record

if artistId != "" {
artist, err := app.Dao().FindRecordById("Artists", artistId)
artist, err := app.FindRecordById("Artists", artistId)

if err != nil {
app.Logger().Error("Error finding artist: "+artistId, "error", err.Error())
app.Logger().Error(fmt.Sprintf("Error finding artist (%s) related to artwork (%s)", artistId, &artwork.Id), "error", err.Error())
}

artworkUrl = url.GenerateFullArtworkUrl(url.ArtworkUrlDTO{
ArtistName: artist.GetString("name"),
ArtistId: artist.GetId(),
ArtworkId: artwork.GetId(),
ArtistId: artist.GetString("id"),
ArtworkId: artwork.GetString("id"),
ArtworkTitle: artwork.GetString("title"),
})

} else {
artworkUrl = url.GenerateArtworkUrl(url.ArtworkUrlDTO{
ArtworkId: artwork.GetId(),
ArtworkId: artwork.GetString("id"),
ArtworkTitle: artwork.GetString("title"),
})
}

content := dto.Artwork{
Id: artwork.GetId(),
Id: artwork.GetString("id"),
Title: artwork.GetString("title"),
Comment: artwork.GetString("comment"),
Technique: artwork.GetString("technique"),
Expand All @@ -402,12 +381,12 @@ func RenderArtworkContent(app *pocketbase.PocketBase, c echo.Context, artwork *m
// Check if artist pointer is nil
if artist != nil {
content.Artist = dto.Artist{
Id: artist.GetId(),
Id: artist.GetString("id"),
Name: artist.GetString("name"),
Bio: artist.GetString("bio"),
Profession: artist.GetString("profession"),
Url: url.GenerateArtistUrl(url.ArtistUrlDTO{
ArtistId: artist.GetId(),
ArtistId: artist.GetString("id"),
ArtistName: artist.GetString("name"),
}),
}
Expand All @@ -423,14 +402,16 @@ func RenderArtworkContent(app *pocketbase.PocketBase, c echo.Context, artwork *m
// It also caches the HTML response for each route to improve performance.
func RegisterHandlers(app *pocketbase.PocketBase) {

app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
app.OnServe().BindFunc(func(se *core.ServeEvent) error {

ag := se.Router.Group("artists")

e.Router.GET("artists/:name", func(c echo.Context) error {
return processArtist(c, app)
ag.GET("/:name", func(e *core.RequestEvent) error {
return processArtist(e, app)
})

e.Router.GET("artists/:name/:awid", func(c echo.Context) error {
return processArtwork(c, app)
ag.GET("/:name/:awid", func(e *core.RequestEvent) error {
return processArtwork(e, app)
})
return nil
})
Expand Down
16 changes: 16 additions & 0 deletions migrations/1687801090_initial_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,19 @@ func init() {
return app.Save(settings)
}, nil)
}

func deleteCollection(app core.App, name string) error {
collection, err := app.FindCollectionByNameOrId(name)

if err != nil {
return nil
}

err = app.Delete(collection)

if err != nil {
app.Logger().Error("Error deleting collection %s: %v", name, err)
}

return nil
}
Loading

0 comments on commit fef7bee

Please sign in to comment.