From 128e38651da616a5f2009739e85e7ce4df144d79 Mon Sep 17 00:00:00 2001 From: Niko Abeler Date: Thu, 20 Jul 2023 19:49:52 +0200 Subject: [PATCH] minimal xml from v1 --- Dockerfile | 8 ++- domain/model/siteconfig.go | 1 + render/templates/views/site_config.tmpl | 3 + web/app.go | 2 +- web/rss_handler.go | 92 +++++++++++++++++++++++-- web/siteconfig_handler.go | 1 + 6 files changed, 98 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8d9b4c5..b9c1301 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ FROM golang:1.20-alpine as build -RUN apk add --no-cache git +RUN apk add --no-cache --update git gcc g++ WORKDIR /tmp/owl @@ -15,7 +15,7 @@ RUN go mod download COPY . . -RUN go build -o ./out/owl ./cmd/owl +RUN CGO_ENABLED=1 GOOS=linux go build -o ./out/owl ./cmd/owl ## @@ -27,7 +27,9 @@ RUN apk add ca-certificates COPY --from=build /tmp/owl/out/ /bin/ # This container exposes port 8080 to the outside world -EXPOSE 8080 +EXPOSE 3000 + +WORKDIR /owl # Run the binary program produced by `go install` ENTRYPOINT ["/bin/owl"] \ No newline at end of file diff --git a/domain/model/siteconfig.go b/domain/model/siteconfig.go index b705e8b..1f3e99f 100644 --- a/domain/model/siteconfig.go +++ b/domain/model/siteconfig.go @@ -31,4 +31,5 @@ type SiteConfig struct { FooterMenu []MenuItem Secret string AvatarUrl string + FullUrl string } diff --git a/render/templates/views/site_config.tmpl b/render/templates/views/site_config.tmpl index 81da0a9..745ac9b 100644 --- a/render/templates/views/site_config.tmpl +++ b/render/templates/views/site_config.tmpl @@ -31,6 +31,9 @@ + + + diff --git a/web/app.go b/web/app.go index 738f2df..79859c8 100644 --- a/web/app.go +++ b/web/app.go @@ -36,7 +36,7 @@ func NewWebApp( listHandler := NewListHandler(entryService, configRepo) entryHandler := NewEntryHandler(entryService, typeRegistry, authorService, configRepo) mediaHandler := NewMediaHandler(binService) - rssHandler := NewRSSHandler(entryService) + rssHandler := NewRSSHandler(entryService, configRepo) loginHandler := NewLoginHandler(authorService, configRepo) editorListHandler := NewEditorListHandler(typeRegistry, configRepo) editorHandler := NewEditorHandler(entryService, typeRegistry, binService, configRepo) diff --git a/web/rss_handler.go b/web/rss_handler.go index dc12784..e84d6d1 100644 --- a/web/rss_handler.go +++ b/web/rss_handler.go @@ -1,19 +1,101 @@ package web import ( + "bytes" + "encoding/xml" + "net/url" "owl-blogs/app" + "owl-blogs/app/repository" + "owl-blogs/domain/model" + "sort" + "time" "github.com/gofiber/fiber/v2" ) -type RSSHandler struct { - entrySvc *app.EntryService +type RSS struct { + XMLName xml.Name `xml:"rss"` + Version string `xml:"version,attr"` + Channel RSSChannel `xml:"channel"` } -func NewRSSHandler(entryService *app.EntryService) *RSSHandler { - return &RSSHandler{entrySvc: entryService} +type RSSChannel struct { + Title string `xml:"title"` + Link string `xml:"link"` + Description string `xml:"description"` + Items []RSSItem `xml:"item"` +} + +type RSSItem struct { + Guid string `xml:"guid"` + Title string `xml:"title"` + Link string `xml:"link"` + PubDate string `xml:"pubDate"` + Description string `xml:"description"` +} + +func RenderRSSFeed(config model.SiteConfig, entries []model.Entry) (string, error) { + + rss := RSS{ + Version: "2.0", + Channel: RSSChannel{ + Title: config.Title, + Link: config.FullUrl, + Description: config.SubTitle, + Items: make([]RSSItem, 0), + }, + } + + for _, entry := range entries { + content := entry.Content() + url, _ := url.JoinPath(config.FullUrl, "/posts/", entry.ID()) + rss.Channel.Items = append(rss.Channel.Items, RSSItem{ + Guid: url, + Title: entry.Title(), + Link: url, + PubDate: entry.PublishedAt().Format(time.RFC1123Z), + Description: string(content), + }) + } + + buf := new(bytes.Buffer) + err := xml.NewEncoder(buf).Encode(rss) + if err != nil { + return "", err + } + + return xml.Header + buf.String(), nil + +} + +type RSSHandler struct { + configRepo repository.ConfigRepository + entrySvc *app.EntryService +} + +func NewRSSHandler(entryService *app.EntryService, configRepo repository.ConfigRepository) *RSSHandler { + return &RSSHandler{entrySvc: entryService, configRepo: configRepo} } func (h *RSSHandler) Handle(c *fiber.Ctx) error { - return c.SendString("Hello, RSS!") + c.Set(fiber.HeaderContentType, fiber.MIMEApplicationXML) + + siteConfig := getSiteConfig(h.configRepo) + + entries, err := h.entrySvc.FindAllByType(&siteConfig.PrimaryListInclude, true, false) + if err != nil { + return err + } + + // sort entries by date descending + sort.Slice(entries, func(i, j int) bool { + return entries[i].PublishedAt().After(*entries[j].PublishedAt()) + }) + + rss, err := RenderRSSFeed(siteConfig, entries) + if err != nil { + return err + } + + return c.SendString(rss) } diff --git a/web/siteconfig_handler.go b/web/siteconfig_handler.go index 0e62e25..f70a8cd 100644 --- a/web/siteconfig_handler.go +++ b/web/siteconfig_handler.go @@ -46,6 +46,7 @@ func (h *SiteConfigHandler) HandlePost(c *fiber.Ctx) error { siteConfig.HeaderColor = c.FormValue("HeaderColor") siteConfig.AuthorName = c.FormValue("AuthorName") siteConfig.AvatarUrl = c.FormValue("AvatarUrl") + siteConfig.FullUrl = c.FormValue("FullUrl") err = h.siteConfigRepo.Update(config.SITE_CONFIG, siteConfig) if err != nil {