diff options
| author | Christine Dodrill <me@christine.website> | 2017-12-13 10:43:58 -0800 |
|---|---|---|
| committer | Christine Dodrill <me@christine.website> | 2017-12-13 11:42:37 -0800 |
| commit | 3a21ef192628f6952eaa981bcdf718a35a4b43c7 (patch) | |
| tree | 9c88a3ddc57ab5014f436ec2c08c96280872632e /vendor/github.com/gorilla | |
| parent | 3b4b6cede9bc30008b0f40989a1564b26e64fd05 (diff) | |
| download | xesite-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.yml | 15 | ||||
| -rw-r--r-- | vendor/github.com/gorilla/feeds/LICENSE | 22 | ||||
| -rw-r--r-- | vendor/github.com/gorilla/feeds/README.md | 184 | ||||
| -rw-r--r-- | vendor/github.com/gorilla/feeds/atom.go | 17 | ||||
| -rw-r--r-- | vendor/github.com/gorilla/feeds/doc.go | 13 | ||||
| -rw-r--r-- | vendor/github.com/gorilla/feeds/feed.go | 29 | ||||
| -rw-r--r-- | vendor/github.com/gorilla/feeds/feed_test.go | 254 | ||||
| -rw-r--r-- | vendor/github.com/gorilla/feeds/json.go | 181 | ||||
| -rw-r--r-- | vendor/github.com/gorilla/feeds/rss.go | 18 | ||||
| -rw-r--r-- | vendor/github.com/gorilla/feeds/to-implement.md | 20 | ||||
| -rw-r--r-- | vendor/github.com/gorilla/feeds/uuid_test.go | 19 |
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 +[](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 <em>effectively</em></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 <em>effectively</em></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 <em>effectively</em></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 <em>effectively</em></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 |
