minimal xml from v1

This commit is contained in:
Niko Abeler 2023-07-20 19:49:52 +02:00
parent 838e949e57
commit 128e38651d
6 changed files with 98 additions and 9 deletions

View File

@ -4,7 +4,7 @@
FROM golang:1.20-alpine as build 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 WORKDIR /tmp/owl
@ -15,7 +15,7 @@ RUN go mod download
COPY . . 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/ COPY --from=build /tmp/owl/out/ /bin/
# This container exposes port 8080 to the outside world # This container exposes port 8080 to the outside world
EXPOSE 8080 EXPOSE 3000
WORKDIR /owl
# Run the binary program produced by `go install` # Run the binary program produced by `go install`
ENTRYPOINT ["/bin/owl"] ENTRYPOINT ["/bin/owl"]

View File

@ -31,4 +31,5 @@ type SiteConfig struct {
FooterMenu []MenuItem FooterMenu []MenuItem
Secret string Secret string
AvatarUrl string AvatarUrl string
FullUrl string
} }

View File

@ -31,6 +31,9 @@
<label for="AvatarUrl">AvatarUrl</label> <label for="AvatarUrl">AvatarUrl</label>
<input type="text" name="AvatarUrl" id="AvatarUrl" value="{{.AvatarUrl}}"/> <input type="text" name="AvatarUrl" id="AvatarUrl" value="{{.AvatarUrl}}"/>
<label for="FullUrl">FullUrl</label>
<input type="text" name="FullUrl" id="FullUrl" value="{{.FullUrl}}"/>
<input type="submit" value="Save" /> <input type="submit" value="Save" />
</form> </form>

View File

@ -36,7 +36,7 @@ func NewWebApp(
listHandler := NewListHandler(entryService, configRepo) listHandler := NewListHandler(entryService, configRepo)
entryHandler := NewEntryHandler(entryService, typeRegistry, authorService, configRepo) entryHandler := NewEntryHandler(entryService, typeRegistry, authorService, configRepo)
mediaHandler := NewMediaHandler(binService) mediaHandler := NewMediaHandler(binService)
rssHandler := NewRSSHandler(entryService) rssHandler := NewRSSHandler(entryService, configRepo)
loginHandler := NewLoginHandler(authorService, configRepo) loginHandler := NewLoginHandler(authorService, configRepo)
editorListHandler := NewEditorListHandler(typeRegistry, configRepo) editorListHandler := NewEditorListHandler(typeRegistry, configRepo)
editorHandler := NewEditorHandler(entryService, typeRegistry, binService, configRepo) editorHandler := NewEditorHandler(entryService, typeRegistry, binService, configRepo)

View File

@ -1,19 +1,101 @@
package web package web
import ( import (
"bytes"
"encoding/xml"
"net/url"
"owl-blogs/app" "owl-blogs/app"
"owl-blogs/app/repository"
"owl-blogs/domain/model"
"sort"
"time"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
) )
type RSS struct {
XMLName xml.Name `xml:"rss"`
Version string `xml:"version,attr"`
Channel RSSChannel `xml:"channel"`
}
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 { type RSSHandler struct {
configRepo repository.ConfigRepository
entrySvc *app.EntryService entrySvc *app.EntryService
} }
func NewRSSHandler(entryService *app.EntryService) *RSSHandler { func NewRSSHandler(entryService *app.EntryService, configRepo repository.ConfigRepository) *RSSHandler {
return &RSSHandler{entrySvc: entryService} return &RSSHandler{entrySvc: entryService, configRepo: configRepo}
} }
func (h *RSSHandler) Handle(c *fiber.Ctx) error { 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)
} }

View File

@ -46,6 +46,7 @@ func (h *SiteConfigHandler) HandlePost(c *fiber.Ctx) error {
siteConfig.HeaderColor = c.FormValue("HeaderColor") siteConfig.HeaderColor = c.FormValue("HeaderColor")
siteConfig.AuthorName = c.FormValue("AuthorName") siteConfig.AuthorName = c.FormValue("AuthorName")
siteConfig.AvatarUrl = c.FormValue("AvatarUrl") siteConfig.AvatarUrl = c.FormValue("AvatarUrl")
siteConfig.FullUrl = c.FormValue("FullUrl")
err = h.siteConfigRepo.Update(config.SITE_CONFIG, siteConfig) err = h.siteConfigRepo.Update(config.SITE_CONFIG, siteConfig)
if err != nil { if err != nil {