| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- // SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
- // SPDX-License-Identifier: Apache-2.0
- package rdf // import "miniflux.app/v2/internal/reader/rdf"
- import (
- "html"
- "log/slog"
- "strings"
- "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 rdfAdapter struct {
- rdf *rdf
- }
- func (r *rdfAdapter) buildFeed(baseURL string) *model.Feed {
- feed := &model.Feed{
- Title: stripTags(r.rdf.Channel.Title),
- FeedURL: strings.TrimSpace(baseURL),
- SiteURL: strings.TrimSpace(r.rdf.Channel.Link),
- Description: strings.TrimSpace(r.rdf.Channel.Description),
- }
- if feed.Title == "" {
- feed.Title = baseURL
- }
- if siteURL, err := urllib.AbsoluteURL(feed.FeedURL, feed.SiteURL); err == nil {
- feed.SiteURL = siteURL
- }
- for _, item := range r.rdf.Items {
- entry := model.NewEntry()
- itemLink := strings.TrimSpace(item.Link)
- // Populate the entry URL.
- if itemLink == "" {
- entry.URL = feed.SiteURL // Fallback to the feed URL if the entry URL is empty.
- } else if entryURL, err := urllib.AbsoluteURL(feed.SiteURL, itemLink); err == nil {
- entry.URL = entryURL
- } else {
- entry.URL = itemLink
- }
- // Populate the entry title.
- for _, title := range []string{item.Title, item.DublinCoreTitle} {
- title = strings.TrimSpace(title)
- if title != "" {
- entry.Title = html.UnescapeString(title)
- break
- }
- }
- // If the entry title is empty, we use the entry URL as a fallback.
- if entry.Title == "" {
- entry.Title = entry.URL
- }
- // Populate the entry content.
- if item.DublinCoreContent != "" {
- entry.Content = item.DublinCoreContent
- } else {
- entry.Content = item.Description
- }
- // Generate the entry hash.
- hashValue := itemLink
- if hashValue == "" {
- hashValue = item.Title + item.Description // Fallback to the title and description if the link is empty.
- }
- entry.Hash = crypto.SHA256(hashValue)
- // Populate the entry date.
- entry.Date = time.Now()
- if item.DublinCoreDate != "" {
- if itemDate, err := date.Parse(item.DublinCoreDate); err != nil {
- slog.Debug("Unable to parse date from RDF feed",
- slog.String("date", item.DublinCoreDate),
- slog.String("link", itemLink),
- slog.Any("error", err),
- )
- } else {
- entry.Date = itemDate
- }
- }
- // Populate the entry author.
- switch {
- case item.DublinCoreCreator != "":
- entry.Author = stripTags(item.DublinCoreCreator)
- case r.rdf.Channel.DublinCoreCreator != "":
- entry.Author = stripTags(r.rdf.Channel.DublinCoreCreator)
- }
- feed.Entries = append(feed.Entries, entry)
- }
- return feed
- }
- func stripTags(value string) string {
- return strings.TrimSpace(sanitizer.StripTags(value))
- }
|