diff options
Diffstat (limited to 'reader/atom/atom.go')
-rw-r--r-- | reader/atom/atom.go | 273 |
1 files changed, 0 insertions, 273 deletions
diff --git a/reader/atom/atom.go b/reader/atom/atom.go deleted file mode 100644 index 677f69a..0000000 --- a/reader/atom/atom.go +++ /dev/null @@ -1,273 +0,0 @@ -// Copyright 2017 Frédéric Guillot. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -package atom // import "miniflux.app/reader/atom" - -import ( - "encoding/xml" - "html" - "strconv" - "strings" - "time" - - "miniflux.app/crypto" - "miniflux.app/logger" - "miniflux.app/model" - "miniflux.app/reader/date" - "miniflux.app/reader/media" - "miniflux.app/reader/sanitizer" - "miniflux.app/url" -) - -type atomFeed struct { - XMLName xml.Name `xml:"http://www.w3.org/2005/Atom feed"` - ID string `xml:"id"` - Title string `xml:"title"` - Author atomAuthor `xml:"author"` - Links []atomLink `xml:"link"` - Entries []atomEntry `xml:"entry"` -} - -type atomEntry struct { - ID string `xml:"id"` - Title atomContent `xml:"title"` - Published string `xml:"published"` - Updated string `xml:"updated"` - Links []atomLink `xml:"link"` - Summary atomContent `xml:"summary"` - Content atomContent `xml:"http://www.w3.org/2005/Atom content"` - Author atomAuthor `xml:"author"` - media.Element -} - -type atomAuthor struct { - Name string `xml:"name"` - Email string `xml:"email"` -} - -type atomLink struct { - URL string `xml:"href,attr"` - Type string `xml:"type,attr"` - Rel string `xml:"rel,attr"` - Length string `xml:"length,attr"` -} - -type atomContent struct { - Type string `xml:"type,attr"` - Data string `xml:",chardata"` - XML string `xml:",innerxml"` -} - -func (a *atomFeed) Transform() *model.Feed { - feed := new(model.Feed) - feed.FeedURL = getRelationURL(a.Links, "self") - feed.SiteURL = getURL(a.Links) - feed.Title = strings.TrimSpace(a.Title) - - if feed.Title == "" { - feed.Title = feed.SiteURL - } - - for _, entry := range a.Entries { - item := entry.Transform() - entryURL, err := url.AbsoluteURL(feed.SiteURL, item.URL) - if err == nil { - item.URL = entryURL - } - - if item.Author == "" { - item.Author = getAuthor(a.Author) - } - - if item.Title == "" { - item.Title = item.URL - } - - feed.Entries = append(feed.Entries, item) - } - - return feed -} - -func (a *atomEntry) Transform() *model.Entry { - entry := new(model.Entry) - entry.URL = getURL(a.Links) - entry.Date = getDate(a) - entry.Author = getAuthor(a.Author) - entry.Hash = getHash(a) - entry.Content = getContent(a) - entry.Title = getTitle(a) - entry.Enclosures = getEnclosures(a) - entry.CommentsURL = getRelationURLWithType(a.Links, "replies", "text/html") - return entry -} - -func getURL(links []atomLink) string { - for _, link := range links { - if strings.ToLower(link.Rel) == "alternate" { - return strings.TrimSpace(link.URL) - } - - if link.Rel == "" && link.Type == "" { - return strings.TrimSpace(link.URL) - } - } - - return "" -} - -func getRelationURL(links []atomLink, relation string) string { - for _, link := range links { - if strings.ToLower(link.Rel) == relation { - return strings.TrimSpace(link.URL) - } - } - - return "" -} - -func getRelationURLWithType(links []atomLink, relation, contentType string) string { - for _, link := range links { - if strings.ToLower(link.Rel) == relation && strings.ToLower(link.Type) == contentType { - return strings.TrimSpace(link.URL) - } - } - - return "" -} - -func getDate(a *atomEntry) time.Time { - // Note: The published date represents the original creation date for YouTube feeds. - // Example: - // <published>2019-01-26T08:02:28+00:00</published> - // <updated>2019-01-29T07:27:27+00:00</updated> - dateText := a.Published - if dateText == "" { - dateText = a.Updated - } - - if dateText != "" { - result, err := date.Parse(dateText) - if err != nil { - logger.Error("atom: %v", err) - return time.Now() - } - - return result - } - - return time.Now() -} - -func atomContentToString(c atomContent) string { - if c.Type == "xhtml" { - return c.XML - } - - if c.Type == "html" { - return c.Data - } - - if c.Type == "text" || c.Type == "" { - return html.EscapeString(c.Data) - } - - return "" -} - -func getContent(a *atomEntry) string { - r := atomContentToString(a.Content) - if r != "" { - return r - } - - r = atomContentToString(a.Summary) - if r != "" { - return r - } - - mediaDescription := a.FirstMediaDescription() - if mediaDescription != "" { - return mediaDescription - } - - return "" -} - -func getTitle(a *atomEntry) string { - title := atomContentToString(a.Title) - return strings.TrimSpace(sanitizer.StripTags(title)) -} - -func getHash(a *atomEntry) string { - for _, value := range []string{a.ID, getURL(a.Links)} { - if value != "" { - return crypto.Hash(value) - } - } - - return "" -} - -func getEnclosures(a *atomEntry) model.EnclosureList { - enclosures := make(model.EnclosureList, 0) - duplicates := make(map[string]bool, 0) - - for _, mediaThumbnail := range a.AllMediaThumbnails() { - if _, found := duplicates[mediaThumbnail.URL]; !found { - duplicates[mediaThumbnail.URL] = true - enclosures = append(enclosures, &model.Enclosure{ - URL: mediaThumbnail.URL, - MimeType: mediaThumbnail.MimeType(), - Size: mediaThumbnail.Size(), - }) - } - } - - for _, link := range a.Links { - if strings.ToLower(link.Rel) == "enclosure" { - if _, found := duplicates[link.URL]; !found { - duplicates[link.URL] = true - length, _ := strconv.ParseInt(link.Length, 10, 0) - enclosures = append(enclosures, &model.Enclosure{URL: link.URL, MimeType: link.Type, Size: length}) - } - } - } - - for _, mediaContent := range a.AllMediaContents() { - if _, found := duplicates[mediaContent.URL]; !found { - duplicates[mediaContent.URL] = true - enclosures = append(enclosures, &model.Enclosure{ - URL: mediaContent.URL, - MimeType: mediaContent.MimeType(), - Size: mediaContent.Size(), - }) - } - } - - for _, mediaPeerLink := range a.AllMediaPeerLinks() { - if _, found := duplicates[mediaPeerLink.URL]; !found { - duplicates[mediaPeerLink.URL] = true - enclosures = append(enclosures, &model.Enclosure{ - URL: mediaPeerLink.URL, - MimeType: mediaPeerLink.MimeType(), - Size: mediaPeerLink.Size(), - }) - } - } - - return enclosures -} - -func getAuthor(author atomAuthor) string { - if author.Name != "" { - return strings.TrimSpace(author.Name) - } - - if author.Email != "" { - return strings.TrimSpace(author.Email) - } - - return "" -} |