Browse Source

Move iTunes and GooglePlay XML definitions to their own packages

Frédéric Guillot 2 years ago
parent
commit
f8e50947f2

+ 31 - 0
internal/reader/googleplay/googleplay.go

@@ -0,0 +1,31 @@
+// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package googleplay // import "miniflux.app/v2/internal/reader/googleplay"
+
+// Specs:
+// https://support.google.com/googleplay/podcasts/answer/6260341
+// https://www.google.com/schemas/play-podcasts/1.0/play-podcasts.xsd
+type GooglePlayFeedElement struct {
+	GooglePlayAuthor      string                    `xml:"http://www.google.com/schemas/play-podcasts/1.0 author"`
+	GooglePlayEmail       string                    `xml:"http://www.google.com/schemas/play-podcasts/1.0 email"`
+	GooglePlayImage       GooglePlayImageElement    `xml:"http://www.google.com/schemas/play-podcasts/1.0 image"`
+	GooglePlayDescription string                    `xml:"http://www.google.com/schemas/play-podcasts/1.0 description"`
+	GooglePlayCategory    GooglePlayCategoryElement `xml:"http://www.google.com/schemas/play-podcasts/1.0 category"`
+}
+
+type GooglePlayItemElement struct {
+	GooglePlayAuthor      string `xml:"http://www.google.com/schemas/play-podcasts/1.0 author"`
+	GooglePlayDescription string `xml:"http://www.google.com/schemas/play-podcasts/1.0 description"`
+	GooglePlayExplicit    string `xml:"http://www.google.com/schemas/play-podcasts/1.0 explicit"`
+	GooglePlayBlock       string `xml:"http://www.google.com/schemas/play-podcasts/1.0 block"`
+	GooglePlayNewFeedURL  string `xml:"http://www.google.com/schemas/play-podcasts/1.0 new-feed-url"`
+}
+
+type GooglePlayImageElement struct {
+	Href string `xml:"href,attr"`
+}
+
+type GooglePlayCategoryElement struct {
+	Text string `xml:"text,attr"`
+}

+ 64 - 0
internal/reader/itunes/itunes.go

@@ -0,0 +1,64 @@
+// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
+// SPDX-License-Identifier: Apache-2.0
+
+package itunes // import "miniflux.app/v2/internal/reader/itunes"
+
+import "strings"
+
+// Specs: https://help.apple.com/itc/podcasts_connect/#/itcb54353390
+type ItunesFeedElement struct {
+	ItunesAuthor     string                  `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd author"`
+	ItunesBlock      string                  `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd block"`
+	ItunesCategories []ItunesCategoryElement `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd category"`
+	ItunesComplete   string                  `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd complete"`
+	ItunesCopyright  string                  `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd copyright"`
+	ItunesExplicit   string                  `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd explicit"`
+	ItunesImage      ItunesImageElement      `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd image"`
+	Keywords         string                  `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd keywords"`
+	ItunesNewFeedURL string                  `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd new-feed-url"`
+	ItunesOwner      ItunesOwnerElement      `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd owner"`
+	ItunesSummary    string                  `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd summary"`
+	ItunesTitle      string                  `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd title"`
+	ItunesType       string                  `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd type"`
+}
+
+type ItunesItemElement struct {
+	ItunesAuthor      string             `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd author"`
+	ItunesEpisode     string             `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd episode"`
+	ItunesEpisodeType string             `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd episodeType"`
+	ItunesExplicit    string             `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd explicit"`
+	ItunesDuration    string             `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd duration"`
+	ItunesImage       ItunesImageElement `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd image"`
+	ItunesSeason      string             `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd season"`
+	ItunesSubtitle    string             `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd subtitle"`
+	ItunesSummary     string             `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd summary"`
+	ItunesTitle       string             `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd title"`
+	ItunesTranscript  string             `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd transcript"`
+}
+
+type ItunesImageElement struct {
+	Href string `xml:"href,attr"`
+}
+
+type ItunesCategoryElement struct {
+	Text        string                 `xml:"text,attr"`
+	SubCategory *ItunesCategoryElement `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd category"`
+}
+
+type ItunesOwnerElement struct {
+	Name  string `xml:"name"`
+	Email string `xml:"email"`
+}
+
+func (i *ItunesOwnerElement) String() string {
+	var name string
+
+	switch {
+	case i.Name != "":
+		name = i.Name
+	case i.Email != "":
+		name = i.Email
+	}
+
+	return strings.TrimSpace(name)
+}

+ 0 - 78
internal/reader/rss/podcast.go

@@ -12,84 +12,6 @@ import (
 
 var ErrInvalidDurationFormat = errors.New("rss: invalid duration format")
 
-// PodcastFeedElement represents iTunes and GooglePlay feed XML elements.
-// Specs:
-// - https://github.com/simplepie/simplepie-ng/wiki/Spec:-iTunes-Podcast-RSS
-// - https://support.google.com/podcast-publishers/answer/9889544
-type PodcastFeedElement struct {
-	ItunesAuthor     string       `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd author"`
-	Subtitle         string       `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd subtitle"`
-	Summary          string       `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd summary"`
-	PodcastOwner     PodcastOwner `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd owner"`
-	GooglePlayAuthor string       `xml:"http://www.google.com/schemas/play-podcasts/1.0 author"`
-}
-
-// PodcastEntryElement represents iTunes and GooglePlay entry XML elements.
-type PodcastEntryElement struct {
-	ItunesAuthor          string       `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd author"`
-	Subtitle              string       `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd subtitle"`
-	Summary               string       `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd summary"`
-	Duration              string       `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd duration"`
-	PodcastOwner          PodcastOwner `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd owner"`
-	GooglePlayAuthor      string       `xml:"http://www.google.com/schemas/play-podcasts/1.0 author"`
-	GooglePlayDescription string       `xml:"http://www.google.com/schemas/play-podcasts/1.0 description"`
-}
-
-// PodcastOwner represents contact information for the podcast owner.
-type PodcastOwner struct {
-	Name  string `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd name"`
-	Email string `xml:"http://www.itunes.com/dtds/podcast-1.0.dtd email"`
-}
-
-func (p *PodcastOwner) String() string {
-	var name string
-
-	switch {
-	case p.Name != "":
-		name = p.Name
-	case p.Email != "":
-		name = p.Email
-	}
-
-	return strings.TrimSpace(name)
-}
-
-// Image represents podcast artwork.
-type Image struct {
-	URL string `xml:"href,attr"`
-}
-
-// PodcastAuthor returns the author of the podcast.
-func (e *PodcastFeedElement) PodcastAuthor() string {
-	author := ""
-
-	switch {
-	case e.ItunesAuthor != "":
-		author = e.ItunesAuthor
-	case e.GooglePlayAuthor != "":
-		author = e.GooglePlayAuthor
-	case e.PodcastOwner.String() != "":
-		author = e.PodcastOwner.String()
-	}
-
-	return strings.TrimSpace(author)
-}
-
-// PodcastDescription returns the description of the podcast.
-func (e *PodcastEntryElement) PodcastDescription() string {
-	description := ""
-
-	switch {
-	case e.GooglePlayDescription != "":
-		description = e.GooglePlayDescription
-	case e.Summary != "":
-		description = e.Summary
-	case e.Subtitle != "":
-		description = e.Subtitle
-	}
-	return strings.TrimSpace(description)
-}
-
 // normalizeDuration returns the duration tag value as a number of minutes
 func normalizeDuration(rawDuration string) (int, error) {
 	var sumSeconds int

+ 21 - 11
internal/reader/rss/rss.go

@@ -16,6 +16,8 @@ import (
 	"miniflux.app/v2/internal/model"
 	"miniflux.app/v2/internal/reader/date"
 	"miniflux.app/v2/internal/reader/dublincore"
+	"miniflux.app/v2/internal/reader/googleplay"
+	"miniflux.app/v2/internal/reader/itunes"
 	"miniflux.app/v2/internal/reader/media"
 	"miniflux.app/v2/internal/reader/sanitizer"
 	"miniflux.app/v2/internal/urllib"
@@ -40,7 +42,8 @@ type rssChannel struct {
 	TimeToLive     rssTTL    `xml:"rss ttl"`
 	Items          []rssItem `xml:"rss item"`
 	AtomLinks
-	PodcastFeedElement
+	itunes.ItunesFeedElement
+	googleplay.GooglePlayFeedElement
 }
 
 type rssTTL struct {
@@ -128,16 +131,18 @@ func (r *rssFeed) feedURL() string {
 }
 
 func (r rssFeed) feedAuthor() string {
-	author := r.Channel.PodcastAuthor()
+	var author string
 	switch {
+	case r.Channel.ItunesAuthor != "":
+		author = r.Channel.ItunesAuthor
+	case r.Channel.GooglePlayAuthor != "":
+		author = r.Channel.GooglePlayAuthor
+	case r.Channel.ItunesOwner.String() != "":
+		author = r.Channel.ItunesOwner.String()
 	case r.Channel.ManagingEditor != "":
 		author = r.Channel.ManagingEditor
 	case r.Channel.Webmaster != "":
 		author = r.Channel.Webmaster
-	case r.Channel.GooglePlayAuthor != "":
-		author = r.Channel.GooglePlayAuthor
-	case r.Channel.PodcastOwner.String() != "":
-		author = r.Channel.PodcastOwner.String()
 	}
 	return sanitizer.StripTags(strings.TrimSpace(author))
 }
@@ -186,10 +191,11 @@ type rssItem struct {
 	Categories     []rssCategory  `xml:"rss category"`
 	dublincore.DublinCoreItemElement
 	FeedBurnerElement
-	PodcastEntryElement
 	media.Element
 	AtomAuthor
 	AtomLinks
+	itunes.ItunesItemElement
+	googleplay.GooglePlayItemElement
 }
 
 func (r *rssItem) Transform() *model.Entry {
@@ -203,7 +209,7 @@ func (r *rssItem) Transform() *model.Entry {
 	entry.Title = r.entryTitle()
 	entry.Enclosures = r.entryEnclosures()
 	entry.Tags = r.entryCategories()
-	if duration, err := normalizeDuration(r.Duration); err == nil {
+	if duration, err := normalizeDuration(r.ItunesDuration); err == nil {
 		entry.ReadingTime = duration
 	}
 
@@ -237,8 +243,6 @@ func (r *rssItem) entryAuthor() string {
 	var author string
 
 	switch {
-	case r.PodcastOwner.String() != "":
-		author = r.PodcastOwner.String()
 	case r.GooglePlayAuthor != "":
 		author = r.GooglePlayAuthor
 	case r.ItunesAuthor != "":
@@ -277,7 +281,13 @@ func (r *rssItem) entryTitle() string {
 }
 
 func (r *rssItem) entryContent() string {
-	for _, value := range []string{r.DublinCoreContent, r.Description, r.PodcastDescription()} {
+	for _, value := range []string{
+		r.DublinCoreContent,
+		r.Description,
+		r.GooglePlayDescription,
+		r.ItunesSummary,
+		r.ItunesSubtitle,
+	} {
 		if value != "" {
 			return value
 		}