minimal xml from v1
This commit is contained in:
parent
838e949e57
commit
128e38651d
|
@ -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"]
|
|
@ -31,4 +31,5 @@ type SiteConfig struct {
|
||||||
FooterMenu []MenuItem
|
FooterMenu []MenuItem
|
||||||
Secret string
|
Secret string
|
||||||
AvatarUrl string
|
AvatarUrl string
|
||||||
|
FullUrl string
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue