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 {