aboutsummaryrefslogtreecommitdiff
path: root/internal/reader/atom/atom_03_adapter.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/reader/atom/atom_03_adapter.go')
-rw-r--r--internal/reader/atom/atom_03_adapter.go115
1 files changed, 115 insertions, 0 deletions
diff --git a/internal/reader/atom/atom_03_adapter.go b/internal/reader/atom/atom_03_adapter.go
new file mode 100644
index 00000000..02d78ec8
--- /dev/null
+++ b/internal/reader/atom/atom_03_adapter.go
@@ -0,0 +1,115 @@
+// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package atom // import "miniflux.app/v2/internal/reader/atom"
+
+import (
+ "log/slog"
+ "time"
+
+ "miniflux.app/v2/internal/crypto"
+ "miniflux.app/v2/internal/model"
+ "miniflux.app/v2/internal/reader/date"
+ "miniflux.app/v2/internal/reader/sanitizer"
+ "miniflux.app/v2/internal/urllib"
+)
+
+type Atom03Adapter struct {
+ atomFeed *Atom03Feed
+}
+
+func NewAtom03Adapter(atomFeed *Atom03Feed) *Atom03Adapter {
+ return &Atom03Adapter{atomFeed}
+}
+
+func (a *Atom03Adapter) BuildFeed(baseURL string) *model.Feed {
+ feed := new(model.Feed)
+
+ // Populate the feed URL.
+ feedURL := a.atomFeed.Links.firstLinkWithRelation("self")
+ if feedURL != "" {
+ if absoluteFeedURL, err := urllib.AbsoluteURL(baseURL, feedURL); err == nil {
+ feed.FeedURL = absoluteFeedURL
+ }
+ } else {
+ feed.FeedURL = baseURL
+ }
+
+ // Populate the site URL.
+ siteURL := a.atomFeed.Links.OriginalLink()
+ if siteURL != "" {
+ if absoluteSiteURL, err := urllib.AbsoluteURL(baseURL, siteURL); err == nil {
+ feed.SiteURL = absoluteSiteURL
+ }
+ } else {
+ feed.SiteURL = baseURL
+ }
+
+ // Populate the feed title.
+ feed.Title = a.atomFeed.Title.Content()
+ if feed.Title == "" {
+ feed.Title = feed.SiteURL
+ }
+
+ for _, atomEntry := range a.atomFeed.Entries {
+ entry := model.NewEntry()
+
+ // Populate the entry URL.
+ entry.URL = atomEntry.Links.OriginalLink()
+ if entry.URL != "" {
+ if absoluteEntryURL, err := urllib.AbsoluteURL(feed.SiteURL, entry.URL); err == nil {
+ entry.URL = absoluteEntryURL
+ }
+ }
+
+ // Populate the entry content.
+ entry.Content = atomEntry.Content.Content()
+ if entry.Content == "" {
+ entry.Content = atomEntry.Summary.Content()
+ }
+
+ // Populate the entry title.
+ entry.Title = atomEntry.Title.Content()
+ if entry.Title == "" {
+ entry.Title = sanitizer.TruncateHTML(entry.Content, 100)
+ }
+ if entry.Title == "" {
+ entry.Title = entry.URL
+ }
+
+ // Populate the entry author.
+ entry.Author = atomEntry.Author.PersonName()
+ if entry.Author == "" {
+ entry.Author = a.atomFeed.Author.PersonName()
+ }
+
+ // Populate the entry date.
+ for _, value := range []string{atomEntry.Issued, atomEntry.Modified, atomEntry.Created} {
+ if parsedDate, err := date.Parse(value); err == nil {
+ entry.Date = parsedDate
+ break
+ } else {
+ slog.Debug("Unable to parse date from Atom 0.3 feed",
+ slog.String("date", value),
+ slog.String("id", atomEntry.ID),
+ slog.Any("error", err),
+ )
+ }
+ }
+ if entry.Date.IsZero() {
+ entry.Date = time.Now()
+ }
+
+ // Generate the entry hash.
+ for _, value := range []string{atomEntry.ID, atomEntry.Links.OriginalLink()} {
+ if value != "" {
+ entry.Hash = crypto.Hash(value)
+ break
+ }
+ }
+
+ feed.Entries = append(feed.Entries, entry)
+ }
+
+ return feed
+}