2023-06-19 23:42:47 +02:00
|
|
|
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
2017-11-20 06:10:04 +01:00
|
|
|
|
2023-08-11 04:46:45 +02:00
|
|
|
package rss // import "miniflux.app/v2/internal/reader/rss"
|
2017-11-20 06:10:04 +01:00
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/xml"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
|
2023-09-09 01:50:06 +02:00
|
|
|
"miniflux.app/v2/internal/reader/dublincore"
|
2024-03-12 05:43:27 +01:00
|
|
|
"miniflux.app/v2/internal/reader/googleplay"
|
|
|
|
"miniflux.app/v2/internal/reader/itunes"
|
2023-08-11 04:46:45 +02:00
|
|
|
"miniflux.app/v2/internal/reader/media"
|
2017-11-21 00:15:10 +01:00
|
|
|
)
|
2017-11-20 06:10:04 +01:00
|
|
|
|
2024-03-12 04:43:14 +01:00
|
|
|
// Specs: https://www.rssboard.org/rss-specification
|
2024-03-14 05:06:28 +01:00
|
|
|
type RSS struct {
|
2024-03-12 04:43:14 +01:00
|
|
|
Version string `xml:"rss version,attr"`
|
2024-03-14 05:06:28 +01:00
|
|
|
Channel RSSChannel `xml:"rss channel"`
|
2024-03-12 04:43:14 +01:00
|
|
|
}
|
|
|
|
|
2024-03-14 05:06:28 +01:00
|
|
|
type RSSChannel struct {
|
2024-03-12 04:43:14 +01:00
|
|
|
Title string `xml:"rss title"`
|
|
|
|
Link string `xml:"rss link"`
|
|
|
|
Description string `xml:"rss description"`
|
2024-03-14 05:06:28 +01:00
|
|
|
Language string `xml:"rss language"`
|
|
|
|
Copyright string `xml:"rss copyRight"`
|
2024-03-12 04:43:14 +01:00
|
|
|
ManagingEditor string `xml:"rss managingEditor"`
|
|
|
|
Webmaster string `xml:"rss webMaster"`
|
2024-03-14 05:06:28 +01:00
|
|
|
PubDate string `xml:"rss pubDate"`
|
|
|
|
LastBuildDate string `xml:"rss lastBuildDate"`
|
|
|
|
Categories []string `xml:"rss category"`
|
|
|
|
Generator string `xml:"rss generator"`
|
|
|
|
Docs string `xml:"rss docs"`
|
|
|
|
Cloud *RSSCloud `xml:"rss cloud"`
|
|
|
|
Image *RSSImage `xml:"rss image"`
|
|
|
|
TTL string `xml:"rss ttl"`
|
|
|
|
SkipHours []string `xml:"rss skipHours>hour"`
|
|
|
|
SkipDays []string `xml:"rss skipDays>day"`
|
|
|
|
Items []RSSItem `xml:"rss item"`
|
2024-03-12 04:43:14 +01:00
|
|
|
AtomLinks
|
2024-03-14 05:06:28 +01:00
|
|
|
itunes.ItunesChannelElement
|
|
|
|
googleplay.GooglePlayChannelElement
|
2023-10-21 04:39:32 +02:00
|
|
|
}
|
|
|
|
|
2024-03-14 05:06:28 +01:00
|
|
|
type RSSCloud struct {
|
|
|
|
Domain string `xml:"domain,attr"`
|
|
|
|
Port string `xml:"port,attr"`
|
|
|
|
Path string `xml:"path,attr"`
|
|
|
|
RegisterProcedure string `xml:"registerProcedure,attr"`
|
|
|
|
Protocol string `xml:"protocol,attr"`
|
2019-12-23 22:29:53 +01:00
|
|
|
}
|
|
|
|
|
2024-03-14 05:06:28 +01:00
|
|
|
type RSSImage struct {
|
|
|
|
// URL is the URL of a GIF, JPEG or PNG image that represents the channel.
|
|
|
|
URL string `xml:"url"`
|
2019-12-23 22:29:53 +01:00
|
|
|
|
2024-03-14 05:06:28 +01:00
|
|
|
// Title describes the image, it's used in the ALT attribute of the HTML <img> tag when the channel is rendered in HTML.
|
|
|
|
Title string `xml:"title"`
|
2019-12-23 22:29:53 +01:00
|
|
|
|
2024-03-14 05:06:28 +01:00
|
|
|
// Link is the URL of the site, when the channel is rendered, the image is a link to the site.
|
|
|
|
Link string `xml:"link"`
|
2017-11-20 06:10:04 +01:00
|
|
|
}
|
|
|
|
|
2024-03-14 05:06:28 +01:00
|
|
|
type RSSItem struct {
|
|
|
|
Title string `xml:"rss title"`
|
|
|
|
Link string `xml:"rss link"`
|
|
|
|
Description string `xml:"rss description"`
|
|
|
|
Author RSSAuthor `xml:"rss author"`
|
|
|
|
Categories []string `xml:"rss category"`
|
|
|
|
CommentsURL string `xml:"rss comments"`
|
|
|
|
Enclosures []RSSEnclosure `xml:"rss enclosure"`
|
|
|
|
GUID RSSGUID `xml:"rss guid"`
|
|
|
|
PubDate string `xml:"rss pubDate"`
|
|
|
|
Source RSSSource `xml:"rss source"`
|
|
|
|
dublincore.DublinCoreItemElement
|
|
|
|
FeedBurnerItemElement
|
|
|
|
media.MediaItemElement
|
|
|
|
AtomAuthor
|
|
|
|
AtomLinks
|
|
|
|
itunes.ItunesItemElement
|
|
|
|
googleplay.GooglePlayItemElement
|
2022-10-10 01:51:39 +02:00
|
|
|
}
|
|
|
|
|
2024-03-14 05:06:28 +01:00
|
|
|
type RSSAuthor struct {
|
2020-06-30 03:08:19 +02:00
|
|
|
XMLName xml.Name
|
|
|
|
Data string `xml:",chardata"`
|
|
|
|
Inner string `xml:",innerxml"`
|
|
|
|
}
|
|
|
|
|
2024-03-14 05:06:28 +01:00
|
|
|
type RSSEnclosure struct {
|
2018-04-10 05:38:12 +02:00
|
|
|
URL string `xml:"url,attr"`
|
|
|
|
Type string `xml:"type,attr"`
|
|
|
|
Length string `xml:"length,attr"`
|
|
|
|
}
|
|
|
|
|
2024-03-14 05:06:28 +01:00
|
|
|
func (enclosure *RSSEnclosure) Size() int64 {
|
|
|
|
if strings.TrimSpace(enclosure.Length) == "" {
|
2019-11-29 06:21:00 +01:00
|
|
|
return 0
|
|
|
|
}
|
|
|
|
size, _ := strconv.ParseInt(enclosure.Length, 10, 0)
|
|
|
|
return size
|
|
|
|
}
|
|
|
|
|
2024-03-14 05:06:28 +01:00
|
|
|
type RSSGUID struct {
|
|
|
|
Data string `xml:",chardata"`
|
|
|
|
IsPermaLink string `xml:"isPermaLink,attr"`
|
2017-11-20 06:10:04 +01:00
|
|
|
}
|
|
|
|
|
2024-03-14 05:06:28 +01:00
|
|
|
type RSSSource struct {
|
|
|
|
URL string `xml:"url,attr"`
|
|
|
|
Name string `xml:",chardata"`
|
2018-04-10 05:30:55 +02:00
|
|
|
}
|