aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/gorilla
diff options
context:
space:
mode:
authorChristine Dodrill <me@christine.website>2017-12-13 10:43:58 -0800
committerChristine Dodrill <me@christine.website>2017-12-13 11:42:37 -0800
commit3a21ef192628f6952eaa981bcdf718a35a4b43c7 (patch)
tree9c88a3ddc57ab5014f436ec2c08c96280872632e /vendor/github.com/gorilla
parent3b4b6cede9bc30008b0f40989a1564b26e64fd05 (diff)
downloadxesite-3a21ef192628f6952eaa981bcdf718a35a4b43c7.tar.xz
xesite-3a21ef192628f6952eaa981bcdf718a35a4b43c7.zip
convert to go buildpack
Diffstat (limited to 'vendor/github.com/gorilla')
-rw-r--r--vendor/github.com/gorilla/feeds/.travis.yml15
-rw-r--r--vendor/github.com/gorilla/feeds/LICENSE22
-rw-r--r--vendor/github.com/gorilla/feeds/README.md184
-rw-r--r--vendor/github.com/gorilla/feeds/atom.go17
-rw-r--r--vendor/github.com/gorilla/feeds/doc.go13
-rw-r--r--vendor/github.com/gorilla/feeds/feed.go29
-rw-r--r--vendor/github.com/gorilla/feeds/feed_test.go254
-rw-r--r--vendor/github.com/gorilla/feeds/json.go181
-rw-r--r--vendor/github.com/gorilla/feeds/rss.go18
-rw-r--r--vendor/github.com/gorilla/feeds/to-implement.md20
-rw-r--r--vendor/github.com/gorilla/feeds/uuid_test.go19
11 files changed, 754 insertions, 18 deletions
diff --git a/vendor/github.com/gorilla/feeds/.travis.yml b/vendor/github.com/gorilla/feeds/.travis.yml
new file mode 100644
index 0000000..3ec3993
--- /dev/null
+++ b/vendor/github.com/gorilla/feeds/.travis.yml
@@ -0,0 +1,15 @@
+language: go
+sudo: false
+matrix:
+ include:
+ - go: 1.7
+ - go: 1.8
+ - go: 1.x
+ - go: master
+ allow_failures:
+ - go: master
+script:
+ - go get -t -v ./...
+ - diff -u <(echo -n) <(gofmt -d -s .)
+ - go tool vet .
+ - go test -v -race ./...
diff --git a/vendor/github.com/gorilla/feeds/LICENSE b/vendor/github.com/gorilla/feeds/LICENSE
new file mode 100644
index 0000000..bb908df
--- /dev/null
+++ b/vendor/github.com/gorilla/feeds/LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2013 The Gorilla Feeds Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/gorilla/feeds/README.md b/vendor/github.com/gorilla/feeds/README.md
new file mode 100644
index 0000000..de9cb6d
--- /dev/null
+++ b/vendor/github.com/gorilla/feeds/README.md
@@ -0,0 +1,184 @@
+## 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.
+
+### Goals
+
+ * Provide a simple interface to create both Atom & RSS 2.0 feeds
+ * Full support for [Atom][atom], [RSS 2.0][rss], and [JSON Feed Version 1][jsonfeed] spec elements
+ * Ability to modify particulars for each spec
+
+[atom]: https://tools.ietf.org/html/rfc4287
+[rss]: http://www.rssboard.org/rss-specification
+[jsonfeed]: https://jsonfeed.org/version/1
+
+### Usage
+
+```go
+package main
+
+import (
+ "fmt"
+ "log"
+ "time"
+ "github.com/gorilla/feeds"
+)
+
+func main() {
+ now := time.Now()
+ feed := &feeds.Feed{
+ Title: "jmoiron.net blog",
+ Link: &feeds.Link{Href: "http://jmoiron.net/blog"},
+ Description: "discussion about tech, footie, photos",
+ Author: &feeds.Author{Name: "Jason Moiron", Email: "jmoiron@jmoiron.net"},
+ Created: now,
+ }
+
+ feed.Items = []*feeds.Item{
+ &feeds.Item{
+ Title: "Limiting Concurrency in Go",
+ Link: &feeds.Link{Href: "http://jmoiron.net/blog/limiting-concurrency-in-go/"},
+ Description: "A discussion on controlled parallelism in golang",
+ Author: &feeds.Author{Name: "Jason Moiron", Email: "jmoiron@jmoiron.net"},
+ Created: now,
+ },
+ &feeds.Item{
+ Title: "Logic-less Template Redux",
+ Link: &feeds.Link{Href: "http://jmoiron.net/blog/logicless-template-redux/"},
+ Description: "More thoughts on logicless templates",
+ Created: now,
+ },
+ &feeds.Item{
+ Title: "Idiomatic Code Reuse in Go",
+ Link: &feeds.Link{Href: "http://jmoiron.net/blog/idiomatic-code-reuse-in-go/"},
+ Description: "How to use interfaces <em>effectively</em>",
+ Created: now,
+ },
+ }
+
+ atom, err := feed.ToAtom()
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ rss, err := feed.ToRss()
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ json, err := feed.ToJSON()
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ fmt.Println(atom, "\n", rss, "\n", json)
+}
+```
+
+Outputs:
+
+```xml
+<?xml version="1.0" encoding="UTF-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <title>jmoiron.net blog</title>
+ <link href="http://jmoiron.net/blog"></link>
+ <id>http://jmoiron.net/blog</id>
+ <updated>2013-01-16T03:26:01-05:00</updated>
+ <summary>discussion about tech, footie, photos</summary>
+ <entry>
+ <title>Limiting Concurrency in Go</title>
+ <link href="http://jmoiron.net/blog/limiting-concurrency-in-go/"></link>
+ <updated>2013-01-16T03:26:01-05:00</updated>
+ <id>tag:jmoiron.net,2013-01-16:/blog/limiting-concurrency-in-go/</id>
+ <summary type="html">A discussion on controlled parallelism in golang</summary>
+ <author>
+ <name>Jason Moiron</name>
+ <email>jmoiron@jmoiron.net</email>
+ </author>
+ </entry>
+ <entry>
+ <title>Logic-less Template Redux</title>
+ <link href="http://jmoiron.net/blog/logicless-template-redux/"></link>
+ <updated>2013-01-16T03:26:01-05:00</updated>
+ <id>tag:jmoiron.net,2013-01-16:/blog/logicless-template-redux/</id>
+ <summary type="html">More thoughts on logicless templates</summary>
+ <author></author>
+ </entry>
+ <entry>
+ <title>Idiomatic Code Reuse in Go</title>
+ <link href="http://jmoiron.net/blog/idiomatic-code-reuse-in-go/"></link>
+ <updated>2013-01-16T03:26:01-05:00</updated>
+ <id>tag:jmoiron.net,2013-01-16:/blog/idiomatic-code-reuse-in-go/</id>
+ <summary type="html">How to use interfaces &lt;em&gt;effectively&lt;/em&gt;</summary>
+ <author></author>
+ </entry>
+</feed>
+
+<?xml version="1.0" encoding="UTF-8"?>
+<rss version="2.0">
+ <channel>
+ <title>jmoiron.net blog</title>
+ <link>http://jmoiron.net/blog</link>
+ <description>discussion about tech, footie, photos</description>
+ <managingEditor>jmoiron@jmoiron.net (Jason Moiron)</managingEditor>
+ <pubDate>2013-01-16T03:22:24-05:00</pubDate>
+ <item>
+ <title>Limiting Concurrency in Go</title>
+ <link>http://jmoiron.net/blog/limiting-concurrency-in-go/</link>
+ <description>A discussion on controlled parallelism in golang</description>
+ <pubDate>2013-01-16T03:22:24-05:00</pubDate>
+ </item>
+ <item>
+ <title>Logic-less Template Redux</title>
+ <link>http://jmoiron.net/blog/logicless-template-redux/</link>
+ <description>More thoughts on logicless templates</description>
+ <pubDate>2013-01-16T03:22:24-05:00</pubDate>
+ </item>
+ <item>
+ <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>
+ <pubDate>2013-01-16T03:22:24-05:00</pubDate>
+ </item>
+ </channel>
+</rss>
+
+{
+ "version": "https://jsonfeed.org/version/1",
+ "title": "jmoiron.net blog",
+ "home_page_url": "http://jmoiron.net/blog",
+ "description": "discussion about tech, footie, photos",
+ "author": {
+ "name": "Jason Moiron"
+ },
+ "items": [
+ {
+ "id": "",
+ "url": "http://jmoiron.net/blog/limiting-concurrency-in-go/",
+ "title": "Limiting Concurrency in Go",
+ "summary": "A discussion on controlled parallelism in golang",
+ "date_published": "2013-01-16T03:22:24.530817846-05:00",
+ "author": {
+ "name": "Jason Moiron"
+ }
+ },
+ {
+ "id": "",
+ "url": "http://jmoiron.net/blog/logicless-template-redux/",
+ "title": "Logic-less Template Redux",
+ "summary": "More thoughts on logicless templates",
+ "date_published": "2013-01-16T03:22:24.530817846-05:00"
+ },
+ {
+ "id": "",
+ "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",
+ "date_published": "2013-01-16T03:22:24.530817846-05:00"
+ }
+ ]
+}
+```
+
diff --git a/vendor/github.com/gorilla/feeds/atom.go b/vendor/github.com/gorilla/feeds/atom.go
index 512976b..6b0ddcb 100644
--- a/vendor/github.com/gorilla/feeds/atom.go
+++ b/vendor/github.com/gorilla/feeds/atom.go
@@ -4,7 +4,6 @@ import (
"encoding/xml"
"fmt"
"net/url"
- "strconv"
"time"
)
@@ -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"`
@@ -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 {
diff --git a/vendor/github.com/gorilla/feeds/doc.go b/vendor/github.com/gorilla/feeds/doc.go
index 5b005ea..70ae5ec 100644
--- a/vendor/github.com/gorilla/feeds/doc.go
+++ b/vendor/github.com/gorilla/feeds/doc.go
@@ -5,7 +5,7 @@ Installing
go get github.com/gorilla/feeds
-Feeds provides a simple, generic Feed interface with a generic Item object as well as RSS and Atom specific RssFeed and AtomFeed objects which allow access to all of each spec's defined elements.
+Feeds provides a simple, generic Feed interface with a generic Item object as well as RSS, Atom and JSON Feed specific RssFeed, AtomFeed and JSONFeed objects which allow access to all of each spec's defined elements.
Examples
@@ -49,15 +49,17 @@ Create a Feed and some Items in that feed using the generic interfaces:
},
}
-From here, you can output Atom or RSS versions of this feed easily
+From here, you can output Atom, RSS, or JSON Feed versions of this feed easily
atom, err := feed.ToAtom()
rss, err := feed.ToRss()
+ json, err := feed.ToJSON()
You can also get access to the underlying objects that feeds uses to export its XML
- atomFeed := &Atom{feed}.AtomFeed()
- rssFeed := &Rss{feed}.RssFeed()
+ atomFeed := (&Atom{Feed: feed}).AtomFeed()
+ rssFeed := (&Rss{Feed: feed}).RssFeed()
+ jsonFeed := (&JSON{Feed: feed}).JSONFeed()
From here, you can modify or add each syndication's specific fields before outputting
@@ -65,6 +67,7 @@ From here, you can modify or add each syndication's specific fields before outpu
atom, err := ToXML(atomFeed)
rssFeed.Generator = "gorilla/feeds v1.0 (github.com/gorilla/feeds)"
rss, err := ToXML(rssFeed)
-
+ jsonFeed.NextUrl = "https://www.example.com/feed.json?page=2"
+ json, err := jsonFeed.ToJSON()
*/
package feeds
diff --git a/vendor/github.com/gorilla/feeds/feed.go b/vendor/github.com/gorilla/feeds/feed.go
index fe4833e..f756abf 100644
--- a/vendor/github.com/gorilla/feeds/feed.go
+++ b/vendor/github.com/gorilla/feeds/feed.go
@@ -1,6 +1,7 @@
package feeds
import (
+ "encoding/json"
"encoding/xml"
"io"
"time"
@@ -14,14 +15,25 @@ 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
+ Source *Link
Author *Author
Description string // used as description in rss, summary in atom
Id string // used as guid in rss, id in atom
Updated time.Time
Created time.Time
+ Enclosure *Enclosure
}
type Feed struct {
@@ -35,6 +47,7 @@ type Feed struct {
Subtitle string
Items []*Item
Copyright string
+ Image *Image
}
// add a new Item to a Feed
@@ -104,3 +117,19 @@ func (f *Feed) ToRss() (string, error) {
func (f *Feed) WriteRss(w io.Writer) error {
return WriteXML(&Rss{f}, w)
}
+
+// ToJSON creates a JSON Feed representation of this feed
+func (f *Feed) ToJSON() (string, error) {
+ j := &JSON{f}
+ return j.ToJSON()
+}
+
+// WriteJSON writes an JSON representation of this feed to the writer.
+func (f *Feed) WriteJSON(w io.Writer) error {
+ j := &JSON{f}
+ feed := j.JSONFeed()
+
+ e := json.NewEncoder(w)
+ e.SetIndent("", " ")
+ return e.Encode(feed)
+}
diff --git a/vendor/github.com/gorilla/feeds/feed_test.go b/vendor/github.com/gorilla/feeds/feed_test.go
new file mode 100644
index 0000000..afd00bb
--- /dev/null
+++ b/vendor/github.com/gorilla/feeds/feed_test.go
@@ -0,0 +1,254 @@
+package feeds
+
+import (
+ "bytes"
+ "testing"
+ "time"
+)
+
+var atomOutput = `<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom">
+ <title>jmoiron.net blog</title>
+ <id>http://jmoiron.net/blog</id>
+ <updated>2013-01-16T21:52:35-05:00</updated>
+ <rights>This work is copyright © Benjamin Button</rights>
+ <subtitle>discussion about tech, footie, photos</subtitle>
+ <link href="http://jmoiron.net/blog"></link>
+ <author>
+ <name>Jason Moiron</name>
+ <email>jmoiron@jmoiron.net</email>
+ </author>
+ <entry>
+ <title>Limiting Concurrency in Go</title>
+ <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/" rel="alternate"></link>
+ <author>
+ <name>Jason Moiron</name>
+ <email>jmoiron@jmoiron.net</email>
+ </author>
+ </entry>
+ <entry>
+ <title>Logic-less Template Redux</title>
+ <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/" 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/" 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" rel="alternate"></link>
+ </entry>
+</feed>`
+
+var rssOutput = `<?xml version="1.0" encoding="UTF-8"?><rss version="2.0">
+ <channel>
+ <title>jmoiron.net blog</title>
+ <link>http://jmoiron.net/blog</link>
+ <description>discussion about tech, footie, photos</description>
+ <copyright>This work is copyright © Benjamin Button</copyright>
+ <managingEditor>jmoiron@jmoiron.net (Jason Moiron)</managingEditor>
+ <pubDate>Wed, 16 Jan 2013 21:52:35 -0500</pubDate>
+ <item>
+ <title>Limiting Concurrency in Go</title>
+ <link>http://jmoiron.net/blog/limiting-concurrency-in-go/</link>
+ <description>A discussion on controlled parallelism in golang</description>
+ <author>Jason Moiron</author>
+ <pubDate>Wed, 16 Jan 2013 21:52:35 -0500</pubDate>
+ </item>
+ <item>
+ <title>Logic-less Template Redux</title>
+ <link>http://jmoiron.net/blog/logicless-template-redux/</link>
+ <description>More thoughts on logicless templates</description>
+ <pubDate>Wed, 16 Jan 2013 21:52:35 -0500</pubDate>
+ </item>
+ <item>
+ <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>
+ <title>Never Gonna Give You Up Mp3</title>
+ <link>http://example.com/RickRoll.mp3</link>
+ <description>Never gonna give you up - Never gonna let you down.</description>
+ <enclosure url="http://example.com/RickRoll.mp3" length="123456" type="audio/mpeg"></enclosure>
+ <pubDate>Wed, 16 Jan 2013 21:52:35 -0500</pubDate>
+ </item>
+ <item>
+ <title>String formatting in Go</title>
+ <link>http://example.com/strings</link>
+ <description>How to use things like %s, %v, %d, etc.</description>
+ <pubDate>Wed, 16 Jan 2013 21:52:35 -0500</pubDate>
+ </item>
+ </channel>
+</rss>`
+
+var jsonOutput = `{
+ "version": "https://jsonfeed.org/version/1",
+ "title": "jmoiron.net blog",
+ "home_page_url": "http://jmoiron.net/blog",
+ "description": "discussion about tech, footie, photos",
+ "author": {
+ "name": "Jason Moiron"
+ },
+ "items": [
+ {
+ "id": "",
+ "url": "http://jmoiron.net/blog/limiting-concurrency-in-go/",
+ "title": "Limiting Concurrency in Go",
+ "summary": "A discussion on controlled parallelism in golang",
+ "date_published": "2013-01-16T21:52:35-05:00",
+ "author": {
+ "name": "Jason Moiron"
+ }
+ },
+ {
+ "id": "",
+ "url": "http://jmoiron.net/blog/logicless-template-redux/",
+ "title": "Logic-less Template Redux",
+ "summary": "More thoughts on logicless templates",
+ "date_published": "2013-01-16T21:52:35-05:00"
+ },
+ {
+ "id": "",
+ "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"
+ },
+ {
+ "id": "",
+ "url": "http://example.com/RickRoll.mp3",
+ "title": "Never Gonna Give You Up Mp3",
+ "summary": "Never gonna give you up - Never gonna let you down.",
+ "date_published": "2013-01-16T21:52:35-05:00"
+ },
+ {
+ "id": "",
+ "url": "http://example.com/strings",
+ "title": "String formatting in Go",
+ "summary": "How to use things like %s, %v, %d, etc.",
+ "date_published": "2013-01-16T21:52:35-05:00"
+ }
+ ]
+}`
+
+func TestFeed(t *testing.T) {
+ now, err := time.Parse(time.RFC3339, "2013-01-16T21:52:35-05:00")
+ if err != nil {
+ t.Error(err)
+ }
+ tz := time.FixedZone("EST", -5*60*60)
+ now = now.In(tz)
+
+ feed := &Feed{
+ Title: "jmoiron.net blog",
+ Link: &Link{Href: "http://jmoiron.net/blog"},
+ Description: "discussion about tech, footie, photos",
+ Author: &Author{Name: "Jason Moiron", Email: "jmoiron@jmoiron.net"},
+ Created: now,
+ Copyright: "This work is copyright © Benjamin Button",
+ }
+
+ feed.Items = []*Item{
+ {
+ Title: "Limiting Concurrency in Go",
+ Link: &Link{Href: "http://jmoiron.net/blog/limiting-concurrency-in-go/"},
+ Description: "A discussion on controlled parallelism in golang",
+ Author: &Author{Name: "Jason Moiron", Email: "jmoiron@jmoiron.net"},
+ Created: now,
+ },
+ {
+ Title: "Logic-less Template Redux",
+ Link: &Link{Href: "http://jmoiron.net/blog/logicless-template-redux/"},
+ Description: "More thoughts on logicless templates",
+ Created: now,
+ },
+ {
+ 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"},
+ 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,
+ },
+ {
+ Title: "String formatting in Go",
+ Link: &Link{Href: "http://example.com/strings"},
+ Description: "How to use things like %s, %v, %d, etc.",
+ Created: now,
+ }}
+
+ atom, err := feed.ToAtom()
+ if err != nil {
+ t.Errorf("unexpected error encoding Atom: %v", err)
+ }
+ if atom != atomOutput {
+ t.Errorf("Atom not what was expected. Got:\n%s\n\nExpected:\n%s\n", atom, atomOutput)
+ }
+ var buf bytes.Buffer
+ if err := feed.WriteAtom(&buf); err != nil {
+ t.Errorf("unexpected error writing Atom: %v", err)
+ }
+ if got := buf.String(); got != atomOutput {
+ t.Errorf("Atom not what was expected. Got:\n%s\n\nExpected:\n%s\n", got, atomOutput)
+ }
+
+ rss, err := feed.ToRss()
+ if err != nil {
+ t.Errorf("unexpected error encoding RSS: %v", err)
+ }
+ if rss != rssOutput {
+ t.Errorf("Rss not what was expected. Got:\n%s\n\nExpected:\n%s\n", rss, rssOutput)
+ }
+ buf.Reset()
+ if err := feed.WriteRss(&buf); err != nil {
+ t.Errorf("unexpected error writing RSS: %v", err)
+ }
+ if got := buf.String(); got != rssOutput {
+ t.Errorf("Rss not what was expected. Got:\n%s\n\nExpected:\n%s\n", got, rssOutput)
+ }
+
+ json, err := feed.ToJSON()
+ if err != nil {
+ t.Errorf("unexpected error encoding JSON: %v", err)
+ }
+ if json != jsonOutput {
+ t.Errorf("JSON not what was expected. Got:\n%s\n\nExpected:\n%s\n", json, jsonOutput)
+ }
+ buf.Reset()
+ if err := feed.WriteJSON(&buf); err != nil {
+ t.Errorf("unexpected error writing JSON: %v", err)
+ }
+ if got := buf.String(); got != jsonOutput+"\n" { //json.Encode appends a newline after the JSON output: https://github.com/golang/go/commit/6f25f1d4c901417af1da65e41992d71c30f64f8f#diff-50848cbd686f250623a2ef6ddb07e157
+ t.Errorf("JSON not what was expected. Got:\n||%s||\n\nExpected:\n||%s||\n", got, jsonOutput)
+ }
+}
diff --git a/vendor/github.com/gorilla/feeds/json.go b/vendor/github.com/gorilla/feeds/json.go
new file mode 100644
index 0000000..e262e4e
--- /dev/null
+++ b/vendor/github.com/gorilla/feeds/json.go
@@ -0,0 +1,181 @@
+package feeds
+
+import (
+ "encoding/json"
+ "strings"
+ "time"
+)
+
+const jsonFeedVersion = "https://jsonfeed.org/version/1"
+
+// JSONAuthor represents the author of the feed or of an individual item
+// in the feed
+type JSONAuthor struct {
+ Name string `json:"name,omitempty"`
+ Url string `json:"url,omitempty"`
+ Avatar string `json:"avatar,omitempty"`
+}
+
+// JSONAttachment represents a related resource. Podcasts, for instance, would
+// include an attachment that’s an audio or video file.
+type JSONAttachment struct {
+ Url string `json:"url,omitempty"`
+ MIMEType string `json:"mime_type,omitempty"`
+ Title string `json:"title,omitempty"`
+ Size int32 `json:"size,omitempty"`
+ Duration time.Duration `json:"duration_in_seconds,omitempty"`
+}
+
+// MarshalJSON implements the json.Marshaler interface.
+// The Duration field is marshaled in seconds, all other fields are marshaled
+// based upon the definitions in struct tags.
+func (a *JSONAttachment) MarshalJSON() ([]byte, error) {
+ type EmbeddedJSONAttachment JSONAttachment
+ return json.Marshal(&struct {
+ Duration float64 `json:"duration_in_seconds,omitempty"`
+ *EmbeddedJSONAttachment
+ }{
+ EmbeddedJSONAttachment: (*EmbeddedJSONAttachment)(a),
+ Duration: a.Duration.Seconds(),
+ })
+}
+
+// UnmarshalJSON implements the json.Unmarshaler interface.
+// The Duration field is expected to be in seconds, all other field types
+// match the struct definition.
+func (a *JSONAttachment) UnmarshalJSON(data []byte) error {
+ type EmbeddedJSONAttachment JSONAttachment
+ var raw struct {
+ Duration float64 `json:"duration_in_seconds,omitempty"`
+ *EmbeddedJSONAttachment
+ }
+ raw.EmbeddedJSONAttachment = (*EmbeddedJSONAttachment)(a)
+
+ err := json.Unmarshal(data, &raw)
+ if err != nil {
+ return err
+ }
+
+ if raw.Duration > 0 {
+ nsec := int64(raw.Duration * float64(time.Second))
+ raw.EmbeddedJSONAttachment.Duration = time.Duration(nsec)
+ }
+
+ return nil
+}
+
+// JSONItem represents a single entry/post for the feed.
+type JSONItem struct {
+ Id string `json:"id"`
+ Url string `json:"url,omitempty"`
+ ExternalUrl string `json:"external_url,omitempty"`
+ Title string `json:"title,omitempty"`
+ ContentHTML string `json:"content_html,omitempty"`
+ ContentText string `json:"content_text,omitempty"`
+ Summary string `json:"summary,omitempty"`
+ Image string `json:"image,omitempty"`
+ BannerImage string `json:"banner_,omitempty"`
+ PublishedDate *time.Time `json:"date_published,omitempty"`
+ ModifiedDate *time.Time `json:"date_modified,omitempty"`
+ Author *JSONAuthor `json:"author,omitempty"`
+ Tags []string `json:"tags,omitempty"`
+ Attachments []JSONAttachment `json:"attachments,omitempty"`
+}
+
+// JSONHub describes an endpoint that can be used to subscribe to real-time
+// notifications from the publisher of this feed.
+type JSONHub struct {
+ Type string `json:"type"`
+ Url string `json:"url"`
+}
+
+// JSONFeed represents a syndication feed in the JSON Feed Version 1 format.
+// Matching the specification found here: https://jsonfeed.org/version/1.
+type JSONFeed struct {
+ Version string `json:"version"`
+ Title string `json:"title"`
+ HomePageUrl string `json:"home_page_url,omitempty"`
+ FeedUrl string `json:"feed_url,omitempty"`
+ Description string `json:"description,omitempty"`
+ UserComment string `json:"user_comment,omitempty"`
+ NextUrl string `json:"next_url,omitempty"`
+ Icon string `json:"icon,omitempty"`
+ Favicon string `json:"favicon,omitempty"`
+ Author *JSONAuthor `json:"author,omitempty"`
+ Expired *bool `json:"expired,omitempty"`
+ Hubs []*JSONItem `json:"hubs,omitempty"`
+ Items []*JSONItem `json:"items,omitempty"`
+}
+
+// JSON is used to convert a generic Feed to a JSONFeed.
+type JSON struct {
+ *Feed
+}
+
+// ToJSON encodes f into a JSON string. Returns an error if marshalling fails.
+func (f *JSON) ToJSON() (string, error) {
+ return f.JSONFeed().ToJSON()
+}
+
+// ToJSON encodes f into a JSON string. Returns an error if marshalling fails.
+func (f *JSONFeed) ToJSON() (string, error) {
+ data, err := json.MarshalIndent(f, "", " ")
+ if err != nil {
+ return "", err
+ }
+
+ return string(data), nil
+}
+
+// JSONFeed creates a new JSONFeed with a generic Feed struct's data.
+func (f *JSON) JSONFeed() *JSONFeed {
+ feed := &JSONFeed{
+ Version: jsonFeedVersion,
+ Title: f.Title,
+ Description: f.Description,
+ }
+
+ if f.Link != nil {
+ feed.HomePageUrl = f.Link.Href
+ }
+ if f.Author != nil {
+ feed.Author = &JSONAuthor{
+ Name: f.Author.Name,
+ }
+ }
+ for _, e := range f.Items {
+ feed.Items = append(feed.Items, newJSONItem(e))
+ }
+ return feed
+}
+
+func newJSONItem(i *Item) *JSONItem {
+ item := &JSONItem{
+ Id: i.Id,
+ Title: i.Title,
+ Summary: i.Description,
+ }
+
+ if i.Link != nil {
+ item.Url = i.Link.Href
+ }
+ if i.Source != nil {
+ item.ExternalUrl = i.Source.Href
+ }
+ if i.Author != nil {
+ item.Author = &JSONAuthor{
+ Name: i.Author.Name,
+ }
+ }
+ if !i.Created.IsZero() {
+ item.PublishedDate = &i.Created
+ }
+ 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
+}
diff --git a/vendor/github.com/gorilla/feeds/rss.go b/vendor/github.com/gorilla/feeds/rss.go
index 3381f74..fec5915 100644
--- a/vendor/github.com/gorilla/feeds/rss.go
+++ b/vendor/github.com/gorilla/feeds/rss.go
@@ -7,7 +7,6 @@ package feeds
import (
"encoding/xml"
"fmt"
- "strconv"
"time"
)
@@ -94,12 +93,15 @@ func newRssItem(i *Item) *RssItem {
Guid: i.Id,
PubDate: anyTimeFormat(time.RFC1123Z, i.Created, i.Updated),
}
+ if i.Source != nil {
+ 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