1
0
Fork 0
mirror of https://github.com/miniflux/v2.git synced 2025-08-11 17:51:01 +00:00
miniflux-v2/internal/reader/atom/atom_03_adapter.go

117 lines
2.8 KiB
Go
Raw Normal View History

2024-03-15 16:39:32 -07:00
// 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"
)
2025-08-08 02:27:04 +02:00
type atom03Adapter struct {
atomFeed *atom03Feed
2024-03-15 16:39:32 -07:00
}
2025-08-08 02:27:04 +02:00
// TODO No need for a constructor, as it's only used in this package
func NewAtom03Adapter(atomFeed *atom03Feed) *atom03Adapter {
return &atom03Adapter{atomFeed}
2024-03-15 16:39:32 -07:00
}
2025-08-08 02:27:04 +02:00
func (a *atom03Adapter) buildFeed(baseURL string) *model.Feed {
2024-03-15 16:39:32 -07:00
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.
2025-08-08 02:27:04 +02:00
siteURL := a.atomFeed.Links.originalLink()
2024-03-15 16:39:32 -07:00
if siteURL != "" {
if absoluteSiteURL, err := urllib.AbsoluteURL(baseURL, siteURL); err == nil {
feed.SiteURL = absoluteSiteURL
}
} else {
feed.SiteURL = baseURL
}
// Populate the feed title.
2025-08-08 02:27:04 +02:00
feed.Title = a.atomFeed.Title.content()
2024-03-15 16:39:32 -07:00
if feed.Title == "" {
feed.Title = feed.SiteURL
}
for _, atomEntry := range a.atomFeed.Entries {
entry := model.NewEntry()
// Populate the entry URL.
2025-08-08 02:27:04 +02:00
entry.URL = atomEntry.Links.originalLink()
2024-03-15 16:39:32 -07:00
if entry.URL != "" {
if absoluteEntryURL, err := urllib.AbsoluteURL(feed.SiteURL, entry.URL); err == nil {
entry.URL = absoluteEntryURL
}
}
// Populate the entry content.
2025-08-08 02:27:04 +02:00
entry.Content = atomEntry.Content.content()
2024-03-15 16:39:32 -07:00
if entry.Content == "" {
2025-08-08 02:27:04 +02:00
entry.Content = atomEntry.Summary.content()
2024-03-15 16:39:32 -07:00
}
// Populate the entry title.
2025-08-08 02:27:04 +02:00
entry.Title = atomEntry.Title.content()
2024-03-15 16:39:32 -07:00
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.
2025-08-08 02:27:04 +02:00
for _, value := range []string{atomEntry.ID, atomEntry.Links.originalLink()} {
2024-03-15 16:39:32 -07:00
if value != "" {
entry.Hash = crypto.SHA256(value)
2024-03-15 16:39:32 -07:00
break
}
}
feed.Entries = append(feed.Entries, entry)
}
return feed
}