Skip to content

Commit

Permalink
[feature] Support feed item images (#41)
Browse files Browse the repository at this point in the history
* Add support for podcast-centered tags
* Adding proper support for Enclosure and and Image tags, which didn't seem to generate properly (might have been a bug on my end but I'm not sure).
* Enclosure.Length from string to int
* Revert change from string to int for Enclosure length
* Accidently changed err == to != for enclosure & author
* Update README to reflect fork goals
* List of tags to implement
* fix RSS image when no Image is mentioned in the Feed
* do not assume that a Link with a field Type is an Enclosure
* expected tests
* better handling of enclosures
* fix package
* Fixes as requested
* Fix travis build error
  • Loading branch information
gmemstr authored and elithrar committed Nov 8, 2017
1 parent b78e02c commit 4b936b5
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 19 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
## gorilla/feeds
[![GoDoc](https://godoc.org/github.com/gorilla/feeds?status.svg)](https://godoc.org/github.com/gorilla/feeds) [![Build Status](https://travis-ci.org/gorilla/feeds.png?branch=master)](https://travis-ci.org/gorilla/feeds)
[![GoDoc](https://godoc.org/github.com/gorilla/feeds?status.svg)](https://godoc.org/github.com/gorilla/feeds)

feeds is a web feed generator library for generating RSS, Atom and JSON feeds from Go
applications.
Expand Down
17 changes: 9 additions & 8 deletions atom.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"encoding/xml"
"fmt"
"net/url"
"strconv"
"time"
)

Expand Down Expand Up @@ -52,11 +51,12 @@ type AtomEntry struct {
Source string `xml:"source,omitempty"`
Published string `xml:"published,omitempty"`
Contributor *AtomContributor
Link *AtomLink // required if no child 'content' elements
Links []AtomLink // required if no child 'content' elements
Summary *AtomSummary // required if content has src or content is base64
Author *AtomAuthor // required if feed lacks an author
}

// Multiple links with different rel can coexist
type AtomLink struct {
//Atom 1.0 <link rel="enclosure" type="audio/mpeg" title="MP3" href="http://www.example.org/myaudiofile.mp3" length="1234" />
XMLName xml.Name `xml:"link"`
Expand Down Expand Up @@ -110,19 +110,20 @@ func newAtomEntry(i *Item) *AtomEntry {
name, email = i.Author.Name, i.Author.Email
}

link_rel := i.Link.Rel
if link_rel == "" {
link_rel = "alternate"
}
x := &AtomEntry{
Title: i.Title,
Link: &AtomLink{Href: i.Link.Href, Rel: i.Link.Rel, Type: i.Link.Type},
Links: []AtomLink{{Href: i.Link.Href, Rel: link_rel, Type: i.Link.Type}},
Content: c,
Id: id,
Updated: anyTimeFormat(time.RFC3339, i.Updated, i.Created),
}

intLength, err := strconv.ParseInt(i.Link.Length, 10, 64)

if err == nil && (intLength > 0 || i.Link.Type != "") {
i.Link.Rel = "enclosure"
x.Link = &AtomLink{Href: i.Link.Href, Rel: i.Link.Rel, Type: i.Link.Type, Length: i.Link.Length}
if i.Enclosure != nil && link_rel != "enclosure" {
x.Links = append(x.Links, AtomLink{Href: i.Enclosure.Url, Rel: "enclosure", Type: i.Enclosure.Type, Length: i.Enclosure.Length})
}

if len(name) > 0 || len(email) > 0 {
Expand Down
11 changes: 11 additions & 0 deletions feed.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ type Author struct {
Name, Email string
}

type Image struct {
Url, Title, Link string
Width, Height int
}

type Enclosure struct {
Url, Length, Type string
}

type Item struct {
Title string
Link *Link
Expand All @@ -24,6 +33,7 @@ type Item struct {
Id string // used as guid in rss, id in atom
Updated time.Time
Created time.Time
Enclosure *Enclosure
}

type Feed struct {
Expand All @@ -37,6 +47,7 @@ type Feed struct {
Subtitle string
Items []*Item
Copyright string
Image *Image
}

// add a new Item to a Feed
Expand Down
16 changes: 11 additions & 5 deletions feed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ var atomOutput = `<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.
<updated>2013-01-16T21:52:35-05:00</updated>
<id>tag:jmoiron.net,2013-01-16:/blog/limiting-concurrency-in-go/</id>
<content type="html">A discussion on controlled parallelism in golang</content>
<link href="http://jmoiron.net/blog/limiting-concurrency-in-go/"></link>
<link href="http://jmoiron.net/blog/limiting-concurrency-in-go/" rel="alternate"></link>
<author>
<name>Jason Moiron</name>
<email>jmoiron@jmoiron.net</email>
Expand All @@ -33,28 +33,30 @@ var atomOutput = `<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.
<updated>2013-01-16T21:52:35-05:00</updated>
<id>tag:jmoiron.net,2013-01-16:/blog/logicless-template-redux/</id>
<content type="html">More thoughts on logicless templates</content>
<link href="http://jmoiron.net/blog/logicless-template-redux/"></link>
<link href="http://jmoiron.net/blog/logicless-template-redux/" rel="alternate"></link>
</entry>
<entry>
<title>Idiomatic Code Reuse in Go</title>
<updated>2013-01-16T21:52:35-05:00</updated>
<id>tag:jmoiron.net,2013-01-16:/blog/idiomatic-code-reuse-in-go/</id>
<content type="html">How to use interfaces &lt;em&gt;effectively&lt;/em&gt;</content>
<link href="http://jmoiron.net/blog/idiomatic-code-reuse-in-go/"></link>
<link href="http://jmoiron.net/blog/idiomatic-code-reuse-in-go/" rel="alternate"></link>
<link href="http://example.com/cover.jpg" rel="enclosure" type="image/jpg" length="123456"></link>
</entry>
<entry>
<title>Never Gonna Give You Up Mp3</title>
<updated>2013-01-16T21:52:35-05:00</updated>
<id>tag:example.com,2013-01-16:/RickRoll.mp3</id>
<content type="html">Never gonna give you up - Never gonna let you down.</content>
<link href="http://example.com/RickRoll.mp3" rel="alternate"></link>
<link href="http://example.com/RickRoll.mp3" rel="enclosure" type="audio/mpeg" length="123456"></link>
</entry>
<entry>
<title>String formatting in Go</title>
<updated>2013-01-16T21:52:35-05:00</updated>
<id>tag:example.com,2013-01-16:/strings</id>
<content type="html">How to use things like %s, %v, %d, etc.</content>
<link href="http://example.com/strings"></link>
<link href="http://example.com/strings" rel="alternate"></link>
</entry>
</feed>`

Expand Down Expand Up @@ -83,6 +85,7 @@ var rssOutput = `<?xml version="1.0" encoding="UTF-8"?><rss version="2.0">
<title>Idiomatic Code Reuse in Go</title>
<link>http://jmoiron.net/blog/idiomatic-code-reuse-in-go/</link>
<description>How to use interfaces &lt;em&gt;effectively&lt;/em&gt;</description>
<enclosure url="http://example.com/cover.jpg" length="123456" type="image/jpg"></enclosure>
<pubDate>Wed, 16 Jan 2013 21:52:35 -0500</pubDate>
</item>
<item>
Expand Down Expand Up @@ -132,6 +135,7 @@ var jsonOutput = `{
"url": "http://jmoiron.net/blog/idiomatic-code-reuse-in-go/",
"title": "Idiomatic Code Reuse in Go",
"summary": "How to use interfaces \u003cem\u003eeffectively\u003c/em\u003e",
"image": "http://example.com/cover.jpg",
"date_published": "2013-01-16T21:52:35-05:00"
},
{
Expand Down Expand Up @@ -186,11 +190,13 @@ func TestFeed(t *testing.T) {
Title: "Idiomatic Code Reuse in Go",
Link: &Link{Href: "http://jmoiron.net/blog/idiomatic-code-reuse-in-go/"},
Description: "How to use interfaces <em>effectively</em>",
Enclosure: &Enclosure{Url: "http://example.com/cover.jpg", Length: "123456", Type: "image/jpg"},
Created: now,
},
{
Title: "Never Gonna Give You Up Mp3",
Link: &Link{Href: "http://example.com/RickRoll.mp3", Length: "123456", Type: "audio/mpeg"},
Link: &Link{Href: "http://example.com/RickRoll.mp3"},
Enclosure: &Enclosure{Url: "http://example.com/RickRoll.mp3", Length: "123456", Type: "audio/mpeg"},
Description: "Never gonna give you up - Never gonna let you down.",
Created: now,
},
Expand Down
4 changes: 4 additions & 0 deletions json.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package feeds

import (
"encoding/json"
"strings"
"time"
)

Expand Down Expand Up @@ -172,6 +173,9 @@ func newJSONItem(i *Item) *JSONItem {
if !i.Updated.IsZero() {
item.ModifiedDate = &i.Created
}
if i.Enclosure != nil && strings.HasPrefix(i.Enclosure.Type, "image/") {
item.Image = i.Enclosure.Url
}

return item
}
15 changes: 10 additions & 5 deletions rss.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ package feeds
import (
"encoding/xml"
"fmt"
"strconv"
"time"
)

Expand Down Expand Up @@ -98,11 +97,11 @@ func newRssItem(i *Item) *RssItem {
item.Source = i.Source.Href
}

intLength, err := strconv.ParseInt(i.Link.Length, 10, 64)

if err == nil && (intLength > 0 || i.Link.Type != "") {
item.Enclosure = &RssEnclosure{Url: i.Link.Href, Type: i.Link.Type, Length: i.Link.Length}
// Define a closure
if i.Enclosure != nil && i.Enclosure.Type != "" && i.Enclosure.Length != "" {
item.Enclosure = &RssEnclosure{Url: i.Enclosure.Url, Type: i.Enclosure.Type, Length: i.Enclosure.Length}
}

if i.Author != nil {
item.Author = i.Author.Name
}
Expand All @@ -121,6 +120,11 @@ func (r *Rss) RssFeed() *RssFeed {
}
}

var image *RssImage
if r.Image != nil {
image = &RssImage{Url: r.Image.Url, Title: r.Image.Title, Link: r.Image.Link, Width: r.Image.Width, Height: r.Image.Height}
}

channel := &RssFeed{
Title: r.Title,
Link: r.Link.Href,
Expand All @@ -129,6 +133,7 @@ func (r *Rss) RssFeed() *RssFeed {
PubDate: pub,
LastBuildDate: build,
Copyright: r.Copyright,
Image: image,
}
for _, i := range r.Items {
channel.Items = append(channel.Items, newRssItem(i))
Expand Down
20 changes: 20 additions & 0 deletions to-implement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[Full iTunes list](https://help.apple.com/itc/podcasts_connect/#/itcb54353390)

[Example of ideal iTunes RSS feed](https://help.apple.com/itc/podcasts_connect/#/itcbaf351599)

```
<itunes:author>
<itunes:block>
<itunes:catergory>
<itunes:image>
<itunes:duration>
<itunes:explicit>
<itunes:isClosedCaptioned>
<itunes:order>
<itunes:complete>
<itunes:new-feed-url>
<itunes:owner>
<itunes:subtitle>
<itunes:summary>
<language>
```

0 comments on commit 4b936b5

Please sign in to comment.