mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-04 05:18:25 +00:00 
			
		
		
		
	Add RSS/Atom feed support for user actions (#16002)
Return rss/atom feed for user based on rss url suffix or Content-Type header.
This commit is contained in:
		
							
								
								
									
										16
									
								
								vendor/github.com/gorilla/feeds/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								vendor/github.com/gorilla/feeds/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
language: go
 | 
			
		||||
sudo: false
 | 
			
		||||
matrix:
 | 
			
		||||
  include:
 | 
			
		||||
    - go: 1.8
 | 
			
		||||
    - go: 1.9
 | 
			
		||||
    - go: "1.10"
 | 
			
		||||
    - go: 1.x
 | 
			
		||||
    - go: tip
 | 
			
		||||
  allow_failures:
 | 
			
		||||
    - go: tip
 | 
			
		||||
script:
 | 
			
		||||
  - go get -t -v ./...
 | 
			
		||||
  - diff -u <(echo -n) <(gofmt -d -s .)
 | 
			
		||||
  - go vet .
 | 
			
		||||
  - go test -v -race ./...
 | 
			
		||||
							
								
								
									
										29
									
								
								vendor/github.com/gorilla/feeds/AUTHORS
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/gorilla/feeds/AUTHORS
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
# This is the official list of gorilla/feeds authors for copyright purposes.
 | 
			
		||||
# Please keep the list sorted.
 | 
			
		||||
 | 
			
		||||
Dmitry Chestnykh <dmitry@codingrobots.com>
 | 
			
		||||
Eddie Scholtz <eascholtz@gmail.com>
 | 
			
		||||
Gabriel Simmer <bladesimmer@gmail.com>
 | 
			
		||||
Google LLC (https://opensource.google.com/)
 | 
			
		||||
honky <honky@defendtheplanet.net>
 | 
			
		||||
James Gregory <james@jagregory.com>
 | 
			
		||||
Jason Hall <imjasonh@gmail.com>
 | 
			
		||||
Jason Moiron <jmoiron@jmoiron.net>
 | 
			
		||||
Kamil Kisiel <kamil@kamilkisiel.net>
 | 
			
		||||
Kevin Stock <kevinstock@tantalic.com>
 | 
			
		||||
Markus Zimmermann <markus.zimmermann@nethead.at>
 | 
			
		||||
Matt Silverlock <matt@eatsleeprepeat.net>
 | 
			
		||||
Matthew Dawson <matthew@mjdsystems.ca>
 | 
			
		||||
Milan Aleksic <milanaleksic@gmail.com>
 | 
			
		||||
Milan Aleksić <milanaleksic@gmail.com>
 | 
			
		||||
nlimpid <jshuangzl@gmail.com>
 | 
			
		||||
Paul Petring <paul@defendtheplanet.net>
 | 
			
		||||
Sean Enck <enckse@users.noreply.github.com>
 | 
			
		||||
Sue Spence <virtuallysue@gmail.com>
 | 
			
		||||
Supermighty <ukiah@faction.com>
 | 
			
		||||
Toru Fukui <fukuimone@gmail.com>
 | 
			
		||||
Vabd <vabd@anon.acme>
 | 
			
		||||
Volker <lists.volker@gmail.com>
 | 
			
		||||
ZhiFeng Hu <hufeng1987@gmail.com>
 | 
			
		||||
weberc2 <weberc2@gmail.com>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										22
									
								
								vendor/github.com/gorilla/feeds/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								vendor/github.com/gorilla/feeds/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
Copyright (c) 2013-2018 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.
 | 
			
		||||
							
								
								
									
										185
									
								
								vendor/github.com/gorilla/feeds/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								vendor/github.com/gorilla/feeds/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,185 @@
 | 
			
		||||
## gorilla/feeds
 | 
			
		||||
[](https://godoc.org/github.com/gorilla/feeds)
 | 
			
		||||
[](https://travis-ci.org/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"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										169
									
								
								vendor/github.com/gorilla/feeds/atom.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								vendor/github.com/gorilla/feeds/atom.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,169 @@
 | 
			
		||||
package feeds
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/xml"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Generates Atom feed as XML
 | 
			
		||||
 | 
			
		||||
const ns = "http://www.w3.org/2005/Atom"
 | 
			
		||||
 | 
			
		||||
type AtomPerson struct {
 | 
			
		||||
	Name  string `xml:"name,omitempty"`
 | 
			
		||||
	Uri   string `xml:"uri,omitempty"`
 | 
			
		||||
	Email string `xml:"email,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type AtomSummary struct {
 | 
			
		||||
	XMLName xml.Name `xml:"summary"`
 | 
			
		||||
	Content string   `xml:",chardata"`
 | 
			
		||||
	Type    string   `xml:"type,attr"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type AtomContent struct {
 | 
			
		||||
	XMLName xml.Name `xml:"content"`
 | 
			
		||||
	Content string   `xml:",chardata"`
 | 
			
		||||
	Type    string   `xml:"type,attr"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type AtomAuthor struct {
 | 
			
		||||
	XMLName xml.Name `xml:"author"`
 | 
			
		||||
	AtomPerson
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type AtomContributor struct {
 | 
			
		||||
	XMLName xml.Name `xml:"contributor"`
 | 
			
		||||
	AtomPerson
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type AtomEntry struct {
 | 
			
		||||
	XMLName     xml.Name `xml:"entry"`
 | 
			
		||||
	Xmlns       string   `xml:"xmlns,attr,omitempty"`
 | 
			
		||||
	Title       string   `xml:"title"`   // required
 | 
			
		||||
	Updated     string   `xml:"updated"` // required
 | 
			
		||||
	Id          string   `xml:"id"`      // required
 | 
			
		||||
	Category    string   `xml:"category,omitempty"`
 | 
			
		||||
	Content     *AtomContent
 | 
			
		||||
	Rights      string `xml:"rights,omitempty"`
 | 
			
		||||
	Source      string `xml:"source,omitempty"`
 | 
			
		||||
	Published   string `xml:"published,omitempty"`
 | 
			
		||||
	Contributor *AtomContributor
 | 
			
		||||
	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"`
 | 
			
		||||
	Href    string   `xml:"href,attr"`
 | 
			
		||||
	Rel     string   `xml:"rel,attr,omitempty"`
 | 
			
		||||
	Type    string   `xml:"type,attr,omitempty"`
 | 
			
		||||
	Length  string   `xml:"length,attr,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type AtomFeed struct {
 | 
			
		||||
	XMLName     xml.Name `xml:"feed"`
 | 
			
		||||
	Xmlns       string   `xml:"xmlns,attr"`
 | 
			
		||||
	Title       string   `xml:"title"`   // required
 | 
			
		||||
	Id          string   `xml:"id"`      // required
 | 
			
		||||
	Updated     string   `xml:"updated"` // required
 | 
			
		||||
	Category    string   `xml:"category,omitempty"`
 | 
			
		||||
	Icon        string   `xml:"icon,omitempty"`
 | 
			
		||||
	Logo        string   `xml:"logo,omitempty"`
 | 
			
		||||
	Rights      string   `xml:"rights,omitempty"` // copyright used
 | 
			
		||||
	Subtitle    string   `xml:"subtitle,omitempty"`
 | 
			
		||||
	Link        *AtomLink
 | 
			
		||||
	Author      *AtomAuthor `xml:"author,omitempty"`
 | 
			
		||||
	Contributor *AtomContributor
 | 
			
		||||
	Entries     []*AtomEntry `xml:"entry"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Atom struct {
 | 
			
		||||
	*Feed
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newAtomEntry(i *Item) *AtomEntry {
 | 
			
		||||
	id := i.Id
 | 
			
		||||
	// assume the description is html
 | 
			
		||||
	s := &AtomSummary{Content: i.Description, Type: "html"}
 | 
			
		||||
 | 
			
		||||
	if len(id) == 0 {
 | 
			
		||||
		// if there's no id set, try to create one, either from data or just a uuid
 | 
			
		||||
		if len(i.Link.Href) > 0 && (!i.Created.IsZero() || !i.Updated.IsZero()) {
 | 
			
		||||
			dateStr := anyTimeFormat("2006-01-02", i.Updated, i.Created)
 | 
			
		||||
			host, path := i.Link.Href, "/invalid.html"
 | 
			
		||||
			if url, err := url.Parse(i.Link.Href); err == nil {
 | 
			
		||||
				host, path = url.Host, url.Path
 | 
			
		||||
			}
 | 
			
		||||
			id = fmt.Sprintf("tag:%s,%s:%s", host, dateStr, path)
 | 
			
		||||
		} else {
 | 
			
		||||
			id = "urn:uuid:" + NewUUID().String()
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	var name, email string
 | 
			
		||||
	if i.Author != nil {
 | 
			
		||||
		name, email = i.Author.Name, i.Author.Email
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	link_rel := i.Link.Rel
 | 
			
		||||
	if link_rel == "" {
 | 
			
		||||
		link_rel = "alternate"
 | 
			
		||||
	}
 | 
			
		||||
	x := &AtomEntry{
 | 
			
		||||
		Title:   i.Title,
 | 
			
		||||
		Links:   []AtomLink{{Href: i.Link.Href, Rel: link_rel, Type: i.Link.Type}},
 | 
			
		||||
		Id:      id,
 | 
			
		||||
		Updated: anyTimeFormat(time.RFC3339, i.Updated, i.Created),
 | 
			
		||||
		Summary: s,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// if there's a content, assume it's html
 | 
			
		||||
	if len(i.Content) > 0 {
 | 
			
		||||
		x.Content = &AtomContent{Content: i.Content, Type: "html"}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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 {
 | 
			
		||||
		x.Author = &AtomAuthor{AtomPerson: AtomPerson{Name: name, Email: email}}
 | 
			
		||||
	}
 | 
			
		||||
	return x
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// create a new AtomFeed with a generic Feed struct's data
 | 
			
		||||
func (a *Atom) AtomFeed() *AtomFeed {
 | 
			
		||||
	updated := anyTimeFormat(time.RFC3339, a.Updated, a.Created)
 | 
			
		||||
	feed := &AtomFeed{
 | 
			
		||||
		Xmlns:    ns,
 | 
			
		||||
		Title:    a.Title,
 | 
			
		||||
		Link:     &AtomLink{Href: a.Link.Href, Rel: a.Link.Rel},
 | 
			
		||||
		Subtitle: a.Description,
 | 
			
		||||
		Id:       a.Link.Href,
 | 
			
		||||
		Updated:  updated,
 | 
			
		||||
		Rights:   a.Copyright,
 | 
			
		||||
	}
 | 
			
		||||
	if a.Author != nil {
 | 
			
		||||
		feed.Author = &AtomAuthor{AtomPerson: AtomPerson{Name: a.Author.Name, Email: a.Author.Email}}
 | 
			
		||||
	}
 | 
			
		||||
	for _, e := range a.Items {
 | 
			
		||||
		feed.Entries = append(feed.Entries, newAtomEntry(e))
 | 
			
		||||
	}
 | 
			
		||||
	return feed
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FeedXml returns an XML-Ready object for an Atom object
 | 
			
		||||
func (a *Atom) FeedXml() interface{} {
 | 
			
		||||
	return a.AtomFeed()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FeedXml returns an XML-ready object for an AtomFeed object
 | 
			
		||||
func (a *AtomFeed) FeedXml() interface{} {
 | 
			
		||||
	return a
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										73
									
								
								vendor/github.com/gorilla/feeds/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								vendor/github.com/gorilla/feeds/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
			
		||||
/*
 | 
			
		||||
Syndication (feed) generator library for golang.
 | 
			
		||||
 | 
			
		||||
Installing
 | 
			
		||||
 | 
			
		||||
	go get github.com/gorilla/feeds
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
Create a Feed and some Items in that feed using the generic interfaces:
 | 
			
		||||
 | 
			
		||||
	import (
 | 
			
		||||
		"time"
 | 
			
		||||
		. "github.com/gorilla/feeds"
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	now = time.Now()
 | 
			
		||||
 | 
			
		||||
	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{
 | 
			
		||||
		&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,
 | 
			
		||||
		},
 | 
			
		||||
		&Item{
 | 
			
		||||
			Title:       "Logic-less Template Redux",
 | 
			
		||||
			Link:        &Link{Href: "http://jmoiron.net/blog/logicless-template-redux/"},
 | 
			
		||||
			Description: "More thoughts on logicless templates",
 | 
			
		||||
			Created:     now,
 | 
			
		||||
		},
 | 
			
		||||
		&Item{
 | 
			
		||||
			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>",
 | 
			
		||||
			Created:     now,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
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: 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
 | 
			
		||||
 | 
			
		||||
	atomFeed.Subtitle = "plays the blues"
 | 
			
		||||
	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
 | 
			
		||||
							
								
								
									
										145
									
								
								vendor/github.com/gorilla/feeds/feed.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								vendor/github.com/gorilla/feeds/feed.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,145 @@
 | 
			
		||||
package feeds
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"encoding/xml"
 | 
			
		||||
	"io"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Link struct {
 | 
			
		||||
	Href, Rel, Type, Length string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
	Content     string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Feed struct {
 | 
			
		||||
	Title       string
 | 
			
		||||
	Link        *Link
 | 
			
		||||
	Description string
 | 
			
		||||
	Author      *Author
 | 
			
		||||
	Updated     time.Time
 | 
			
		||||
	Created     time.Time
 | 
			
		||||
	Id          string
 | 
			
		||||
	Subtitle    string
 | 
			
		||||
	Items       []*Item
 | 
			
		||||
	Copyright   string
 | 
			
		||||
	Image       *Image
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// add a new Item to a Feed
 | 
			
		||||
func (f *Feed) Add(item *Item) {
 | 
			
		||||
	f.Items = append(f.Items, item)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// returns the first non-zero time formatted as a string or ""
 | 
			
		||||
func anyTimeFormat(format string, times ...time.Time) string {
 | 
			
		||||
	for _, t := range times {
 | 
			
		||||
		if !t.IsZero() {
 | 
			
		||||
			return t.Format(format)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// interface used by ToXML to get a object suitable for exporting XML.
 | 
			
		||||
type XmlFeed interface {
 | 
			
		||||
	FeedXml() interface{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// turn a feed object (either a Feed, AtomFeed, or RssFeed) into xml
 | 
			
		||||
// returns an error if xml marshaling fails
 | 
			
		||||
func ToXML(feed XmlFeed) (string, error) {
 | 
			
		||||
	x := feed.FeedXml()
 | 
			
		||||
	data, err := xml.MarshalIndent(x, "", "  ")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	// strip empty line from default xml header
 | 
			
		||||
	s := xml.Header[:len(xml.Header)-1] + string(data)
 | 
			
		||||
	return s, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WriteXML writes a feed object (either a Feed, AtomFeed, or RssFeed) as XML into
 | 
			
		||||
// the writer. Returns an error if XML marshaling fails.
 | 
			
		||||
func WriteXML(feed XmlFeed, w io.Writer) error {
 | 
			
		||||
	x := feed.FeedXml()
 | 
			
		||||
	// write default xml header, without the newline
 | 
			
		||||
	if _, err := w.Write([]byte(xml.Header[:len(xml.Header)-1])); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	e := xml.NewEncoder(w)
 | 
			
		||||
	e.Indent("", "  ")
 | 
			
		||||
	return e.Encode(x)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// creates an Atom representation of this feed
 | 
			
		||||
func (f *Feed) ToAtom() (string, error) {
 | 
			
		||||
	a := &Atom{f}
 | 
			
		||||
	return ToXML(a)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WriteAtom writes an Atom representation of this feed to the writer.
 | 
			
		||||
func (f *Feed) WriteAtom(w io.Writer) error {
 | 
			
		||||
	return WriteXML(&Atom{f}, w)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// creates an Rss representation of this feed
 | 
			
		||||
func (f *Feed) ToRss() (string, error) {
 | 
			
		||||
	r := &Rss{f}
 | 
			
		||||
	return ToXML(r)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WriteRss writes an RSS representation of this feed to the writer.
 | 
			
		||||
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)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sort sorts the Items in the feed with the given less function.
 | 
			
		||||
func (f *Feed) Sort(less func(a, b *Item) bool) {
 | 
			
		||||
	lessFunc := func(i, j int) bool {
 | 
			
		||||
		return less(f.Items[i], f.Items[j])
 | 
			
		||||
	}
 | 
			
		||||
	sort.SliceStable(f.Items, lessFunc)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										183
									
								
								vendor/github.com/gorilla/feeds/json.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								vendor/github.com/gorilla/feeds/json.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,183 @@
 | 
			
		||||
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,
 | 
			
		||||
 | 
			
		||||
		ContentHTML: i.Content,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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.Updated
 | 
			
		||||
	}
 | 
			
		||||
	if i.Enclosure != nil && strings.HasPrefix(i.Enclosure.Type, "image/") {
 | 
			
		||||
		item.Image = i.Enclosure.Url
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return item
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										168
									
								
								vendor/github.com/gorilla/feeds/rss.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								vendor/github.com/gorilla/feeds/rss.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,168 @@
 | 
			
		||||
package feeds
 | 
			
		||||
 | 
			
		||||
// rss support
 | 
			
		||||
// validation done according to spec here:
 | 
			
		||||
//    http://cyber.law.harvard.edu/rss/rss.html
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/xml"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// private wrapper around the RssFeed which gives us the <rss>..</rss> xml
 | 
			
		||||
type RssFeedXml struct {
 | 
			
		||||
	XMLName          xml.Name `xml:"rss"`
 | 
			
		||||
	Version          string   `xml:"version,attr"`
 | 
			
		||||
	ContentNamespace string   `xml:"xmlns:content,attr"`
 | 
			
		||||
	Channel          *RssFeed
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type RssContent struct {
 | 
			
		||||
	XMLName xml.Name `xml:"content:encoded"`
 | 
			
		||||
	Content string   `xml:",cdata"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type RssImage struct {
 | 
			
		||||
	XMLName xml.Name `xml:"image"`
 | 
			
		||||
	Url     string   `xml:"url"`
 | 
			
		||||
	Title   string   `xml:"title"`
 | 
			
		||||
	Link    string   `xml:"link"`
 | 
			
		||||
	Width   int      `xml:"width,omitempty"`
 | 
			
		||||
	Height  int      `xml:"height,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type RssTextInput struct {
 | 
			
		||||
	XMLName     xml.Name `xml:"textInput"`
 | 
			
		||||
	Title       string   `xml:"title"`
 | 
			
		||||
	Description string   `xml:"description"`
 | 
			
		||||
	Name        string   `xml:"name"`
 | 
			
		||||
	Link        string   `xml:"link"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type RssFeed struct {
 | 
			
		||||
	XMLName        xml.Name `xml:"channel"`
 | 
			
		||||
	Title          string   `xml:"title"`       // required
 | 
			
		||||
	Link           string   `xml:"link"`        // required
 | 
			
		||||
	Description    string   `xml:"description"` // required
 | 
			
		||||
	Language       string   `xml:"language,omitempty"`
 | 
			
		||||
	Copyright      string   `xml:"copyright,omitempty"`
 | 
			
		||||
	ManagingEditor string   `xml:"managingEditor,omitempty"` // Author used
 | 
			
		||||
	WebMaster      string   `xml:"webMaster,omitempty"`
 | 
			
		||||
	PubDate        string   `xml:"pubDate,omitempty"`       // created or updated
 | 
			
		||||
	LastBuildDate  string   `xml:"lastBuildDate,omitempty"` // updated used
 | 
			
		||||
	Category       string   `xml:"category,omitempty"`
 | 
			
		||||
	Generator      string   `xml:"generator,omitempty"`
 | 
			
		||||
	Docs           string   `xml:"docs,omitempty"`
 | 
			
		||||
	Cloud          string   `xml:"cloud,omitempty"`
 | 
			
		||||
	Ttl            int      `xml:"ttl,omitempty"`
 | 
			
		||||
	Rating         string   `xml:"rating,omitempty"`
 | 
			
		||||
	SkipHours      string   `xml:"skipHours,omitempty"`
 | 
			
		||||
	SkipDays       string   `xml:"skipDays,omitempty"`
 | 
			
		||||
	Image          *RssImage
 | 
			
		||||
	TextInput      *RssTextInput
 | 
			
		||||
	Items          []*RssItem `xml:"item"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type RssItem struct {
 | 
			
		||||
	XMLName     xml.Name `xml:"item"`
 | 
			
		||||
	Title       string   `xml:"title"`       // required
 | 
			
		||||
	Link        string   `xml:"link"`        // required
 | 
			
		||||
	Description string   `xml:"description"` // required
 | 
			
		||||
	Content     *RssContent
 | 
			
		||||
	Author      string `xml:"author,omitempty"`
 | 
			
		||||
	Category    string `xml:"category,omitempty"`
 | 
			
		||||
	Comments    string `xml:"comments,omitempty"`
 | 
			
		||||
	Enclosure   *RssEnclosure
 | 
			
		||||
	Guid        string `xml:"guid,omitempty"`    // Id used
 | 
			
		||||
	PubDate     string `xml:"pubDate,omitempty"` // created or updated
 | 
			
		||||
	Source      string `xml:"source,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type RssEnclosure struct {
 | 
			
		||||
	//RSS 2.0 <enclosure url="http://example.com/file.mp3" length="123456789" type="audio/mpeg" />
 | 
			
		||||
	XMLName xml.Name `xml:"enclosure"`
 | 
			
		||||
	Url     string   `xml:"url,attr"`
 | 
			
		||||
	Length  string   `xml:"length,attr"`
 | 
			
		||||
	Type    string   `xml:"type,attr"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Rss struct {
 | 
			
		||||
	*Feed
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// create a new RssItem with a generic Item struct's data
 | 
			
		||||
func newRssItem(i *Item) *RssItem {
 | 
			
		||||
	item := &RssItem{
 | 
			
		||||
		Title:       i.Title,
 | 
			
		||||
		Link:        i.Link.Href,
 | 
			
		||||
		Description: i.Description,
 | 
			
		||||
		Guid:        i.Id,
 | 
			
		||||
		PubDate:     anyTimeFormat(time.RFC1123Z, i.Created, i.Updated),
 | 
			
		||||
	}
 | 
			
		||||
	if len(i.Content) > 0 {
 | 
			
		||||
		item.Content = &RssContent{Content: i.Content}
 | 
			
		||||
	}
 | 
			
		||||
	if i.Source != nil {
 | 
			
		||||
		item.Source = i.Source.Href
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 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
 | 
			
		||||
	}
 | 
			
		||||
	return item
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// create a new RssFeed with a generic Feed struct's data
 | 
			
		||||
func (r *Rss) RssFeed() *RssFeed {
 | 
			
		||||
	pub := anyTimeFormat(time.RFC1123Z, r.Created, r.Updated)
 | 
			
		||||
	build := anyTimeFormat(time.RFC1123Z, r.Updated)
 | 
			
		||||
	author := ""
 | 
			
		||||
	if r.Author != nil {
 | 
			
		||||
		author = r.Author.Email
 | 
			
		||||
		if len(r.Author.Name) > 0 {
 | 
			
		||||
			author = fmt.Sprintf("%s (%s)", r.Author.Email, r.Author.Name)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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,
 | 
			
		||||
		Description:    r.Description,
 | 
			
		||||
		ManagingEditor: author,
 | 
			
		||||
		PubDate:        pub,
 | 
			
		||||
		LastBuildDate:  build,
 | 
			
		||||
		Copyright:      r.Copyright,
 | 
			
		||||
		Image:          image,
 | 
			
		||||
	}
 | 
			
		||||
	for _, i := range r.Items {
 | 
			
		||||
		channel.Items = append(channel.Items, newRssItem(i))
 | 
			
		||||
	}
 | 
			
		||||
	return channel
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FeedXml returns an XML-Ready object for an Rss object
 | 
			
		||||
func (r *Rss) FeedXml() interface{} {
 | 
			
		||||
	// only generate version 2.0 feeds for now
 | 
			
		||||
	return r.RssFeed().FeedXml()
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FeedXml returns an XML-ready object for an RssFeed object
 | 
			
		||||
func (r *RssFeed) FeedXml() interface{} {
 | 
			
		||||
	return &RssFeedXml{
 | 
			
		||||
		Version:          "2.0",
 | 
			
		||||
		Channel:          r,
 | 
			
		||||
		ContentNamespace: "http://purl.org/rss/1.0/modules/content/",
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										92
									
								
								vendor/github.com/gorilla/feeds/test.atom
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								vendor/github.com/gorilla/feeds/test.atom
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<feed xmlns:atom="http://www.w3.org/2005/Atom">
 | 
			
		||||
        <title><![CDATA[Lorem ipsum feed for an interval of 1 minutes]]></title>
 | 
			
		||||
        <description><![CDATA[This is a constantly updating lorem ipsum feed]]></description>
 | 
			
		||||
        <link>http://example.com/</link>
 | 
			
		||||
        <generator>RSS for Node</generator>
 | 
			
		||||
        <lastBuildDate>Tue, 30 Oct 2018 23:22:37 GMT</lastBuildDate>
 | 
			
		||||
        <author><![CDATA[John Smith]]></author>
 | 
			
		||||
        <pubDate>Tue, 30 Oct 2018 23:22:00 GMT</pubDate>
 | 
			
		||||
        <copyright><![CDATA[Michael Bertolacci, licensed under a Creative Commons Attribution 3.0 Unported License.]]></copyright>
 | 
			
		||||
        <ttl>60</ttl>
 | 
			
		||||
        <entry>
 | 
			
		||||
            <title><![CDATA[Lorem ipsum 2018-10-30T23:22:00+00:00]]></title>
 | 
			
		||||
            <description><![CDATA[Exercitation ut Lorem sint proident.]]></description>
 | 
			
		||||
            <link>http://example.com/test/1540941720</link>
 | 
			
		||||
            <guid isPermaLink="true">http://example.com/test/1540941720</guid>
 | 
			
		||||
            <dc:creator><![CDATA[John Smith]]></dc:creator>
 | 
			
		||||
            <pubDate>Tue, 30 Oct 2018 23:22:00 GMT</pubDate>
 | 
			
		||||
        </entry>
 | 
			
		||||
        <entry>
 | 
			
		||||
            <title><![CDATA[Lorem ipsum 2018-10-30T23:21:00+00:00]]></title>
 | 
			
		||||
            <description><![CDATA[Ea est do quis fugiat exercitation.]]></description>
 | 
			
		||||
            <link>http://example.com/test/1540941660</link>
 | 
			
		||||
            <guid isPermaLink="true">http://example.com/test/1540941660</guid>
 | 
			
		||||
            <dc:creator><![CDATA[John Smith]]></dc:creator>
 | 
			
		||||
            <pubDate>Tue, 30 Oct 2018 23:21:00 GMT</pubDate>
 | 
			
		||||
        </entry>
 | 
			
		||||
        <entry>
 | 
			
		||||
            <title><![CDATA[Lorem ipsum 2018-10-30T23:20:00+00:00]]></title>
 | 
			
		||||
            <description><![CDATA[Ipsum velit cillum ad laborum sit nulla exercitation consequat sint veniam culpa veniam voluptate incididunt.]]></description>
 | 
			
		||||
            <link>http://example.com/test/1540941600</link>
 | 
			
		||||
            <guid isPermaLink="true">http://example.com/test/1540941600</guid>
 | 
			
		||||
            <dc:creator><![CDATA[John Smith]]></dc:creator>
 | 
			
		||||
            <pubDate>Tue, 30 Oct 2018 23:20:00 GMT</pubDate>
 | 
			
		||||
        </entry>
 | 
			
		||||
        <entry>
 | 
			
		||||
            <title><![CDATA[Lorem ipsum 2018-10-30T23:19:00+00:00]]></title>
 | 
			
		||||
            <description><![CDATA[Ullamco pariatur aliqua consequat ea veniam id qui incididunt laborum.]]></description>
 | 
			
		||||
            <link>http://example.com/test/1540941540</link>
 | 
			
		||||
            <guid isPermaLink="true">http://example.com/test/1540941540</guid>
 | 
			
		||||
            <dc:creator><![CDATA[John Smith]]></dc:creator>
 | 
			
		||||
            <pubDate>Tue, 30 Oct 2018 23:19:00 GMT</pubDate>
 | 
			
		||||
        </entry>
 | 
			
		||||
        <entry>
 | 
			
		||||
            <title><![CDATA[Lorem ipsum 2018-10-30T23:18:00+00:00]]></title>
 | 
			
		||||
            <description><![CDATA[Velit proident aliquip aliquip anim mollit voluptate laboris voluptate et occaecat occaecat laboris ea nulla.]]></description>
 | 
			
		||||
            <link>http://example.com/test/1540941480</link>
 | 
			
		||||
            <guid isPermaLink="true">http://example.com/test/1540941480</guid>
 | 
			
		||||
            <dc:creator><![CDATA[John Smith]]></dc:creator>
 | 
			
		||||
            <pubDate>Tue, 30 Oct 2018 23:18:00 GMT</pubDate>
 | 
			
		||||
        </entry>
 | 
			
		||||
        <entry>
 | 
			
		||||
            <title><![CDATA[Lorem ipsum 2018-10-30T23:17:00+00:00]]></title>
 | 
			
		||||
            <description><![CDATA[Do in quis mollit consequat id in minim laborum sint exercitation laborum elit officia.]]></description>
 | 
			
		||||
            <link>http://example.com/test/1540941420</link>
 | 
			
		||||
            <guid isPermaLink="true">http://example.com/test/1540941420</guid>
 | 
			
		||||
            <dc:creator><![CDATA[John Smith]]></dc:creator>
 | 
			
		||||
            <pubDate>Tue, 30 Oct 2018 23:17:00 GMT</pubDate>
 | 
			
		||||
        </entry>
 | 
			
		||||
        <entry>
 | 
			
		||||
            <title><![CDATA[Lorem ipsum 2018-10-30T23:16:00+00:00]]></title>
 | 
			
		||||
            <description><![CDATA[Irure id sint ullamco Lorem magna consectetur officia adipisicing duis incididunt.]]></description>
 | 
			
		||||
            <link>http://example.com/test/1540941360</link>
 | 
			
		||||
            <guid isPermaLink="true">http://example.com/test/1540941360</guid>
 | 
			
		||||
            <dc:creator><![CDATA[John Smith]]></dc:creator>
 | 
			
		||||
            <pubDate>Tue, 30 Oct 2018 23:16:00 GMT</pubDate>
 | 
			
		||||
        </entry>
 | 
			
		||||
        <entry>
 | 
			
		||||
            <title><![CDATA[Lorem ipsum 2018-10-30T23:15:00+00:00]]></title>
 | 
			
		||||
            <description><![CDATA[Sunt anim excepteur esse nisi commodo culpa laborum exercitation ad anim ex elit.]]></description>
 | 
			
		||||
            <link>http://example.com/test/1540941300</link>
 | 
			
		||||
            <guid isPermaLink="true">http://example.com/test/1540941300</guid>
 | 
			
		||||
            <dc:creator><![CDATA[John Smith]]></dc:creator>
 | 
			
		||||
            <pubDate>Tue, 30 Oct 2018 23:15:00 GMT</pubDate>
 | 
			
		||||
        </entry>
 | 
			
		||||
        <entry>
 | 
			
		||||
            <title><![CDATA[Lorem ipsum 2018-10-30T23:14:00+00:00]]></title>
 | 
			
		||||
            <description><![CDATA[Excepteur aliquip fugiat ex labore nisi.]]></description>
 | 
			
		||||
            <link>http://example.com/test/1540941240</link>
 | 
			
		||||
            <guid isPermaLink="true">http://example.com/test/1540941240</guid>
 | 
			
		||||
            <dc:creator><![CDATA[John Smith]]></dc:creator>
 | 
			
		||||
            <pubDate>Tue, 30 Oct 2018 23:14:00 GMT</pubDate>
 | 
			
		||||
        </entry>
 | 
			
		||||
        <entry>
 | 
			
		||||
            <title><![CDATA[Lorem ipsum 2018-10-30T23:13:00+00:00]]></title>
 | 
			
		||||
            <description><![CDATA[Id proident adipisicing proident pariatur aute pariatur pariatur dolor dolor in voluptate dolor.]]></description>
 | 
			
		||||
            <link>http://example.com/test/1540941180</link>
 | 
			
		||||
            <guid isPermaLink="true">http://example.com/test/1540941180</guid>
 | 
			
		||||
            <dc:creator><![CDATA[John Smith]]></dc:creator>
 | 
			
		||||
            <pubDate>Tue, 30 Oct 2018 23:13:00 GMT</pubDate>
 | 
			
		||||
        </entry>
 | 
			
		||||
</feed>
 | 
			
		||||
							
								
								
									
										96
									
								
								vendor/github.com/gorilla/feeds/test.rss
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								vendor/github.com/gorilla/feeds/test.rss
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,96 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" 
 | 
			
		||||
    xmlns:content="http://purl.org/rss/1.0/modules/content/" 
 | 
			
		||||
    xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
 | 
			
		||||
    <channel>
 | 
			
		||||
        <title><![CDATA[Lorem ipsum feed for an interval of 1 minutes]]></title>
 | 
			
		||||
        <description><![CDATA[This is a constantly updating lorem ipsum feed]]></description>
 | 
			
		||||
        <link>http://example.com/</link>
 | 
			
		||||
        <generator>RSS for Node</generator>
 | 
			
		||||
        <lastBuildDate>Tue, 30 Oct 2018 23:22:37 GMT</lastBuildDate>
 | 
			
		||||
        <author><![CDATA[John Smith]]></author>
 | 
			
		||||
        <pubDate>Tue, 30 Oct 2018 23:22:00 GMT</pubDate>
 | 
			
		||||
        <copyright><![CDATA[Michael Bertolacci, licensed under a Creative Commons Attribution 3.0 Unported License.]]></copyright>
 | 
			
		||||
        <ttl>60</ttl>
 | 
			
		||||
        <item>
 | 
			
		||||
            <title><![CDATA[Lorem ipsum 2018-10-30T23:22:00+00:00]]></title>
 | 
			
		||||
            <description><![CDATA[Exercitation ut Lorem sint proident.]]></description>
 | 
			
		||||
            <link>http://example.com/test/1540941720</link>
 | 
			
		||||
            <guid isPermaLink="true">http://example.com/test/1540941720</guid>
 | 
			
		||||
            <dc:creator><![CDATA[John Smith]]></dc:creator>
 | 
			
		||||
            <pubDate>Tue, 30 Oct 2018 23:22:00 GMT</pubDate>
 | 
			
		||||
        </item>
 | 
			
		||||
        <item>
 | 
			
		||||
            <title><![CDATA[Lorem ipsum 2018-10-30T23:21:00+00:00]]></title>
 | 
			
		||||
            <description><![CDATA[Ea est do quis fugiat exercitation.]]></description>
 | 
			
		||||
            <link>http://example.com/test/1540941660</link>
 | 
			
		||||
            <guid isPermaLink="true">http://example.com/test/1540941660</guid>
 | 
			
		||||
            <dc:creator><![CDATA[John Smith]]></dc:creator>
 | 
			
		||||
            <pubDate>Tue, 30 Oct 2018 23:21:00 GMT</pubDate>
 | 
			
		||||
        </item>
 | 
			
		||||
        <item>
 | 
			
		||||
            <title><![CDATA[Lorem ipsum 2018-10-30T23:20:00+00:00]]></title>
 | 
			
		||||
            <description><![CDATA[Ipsum velit cillum ad laborum sit nulla exercitation consequat sint veniam culpa veniam voluptate incididunt.]]></description>
 | 
			
		||||
            <link>http://example.com/test/1540941600</link>
 | 
			
		||||
            <guid isPermaLink="true">http://example.com/test/1540941600</guid>
 | 
			
		||||
            <dc:creator><![CDATA[John Smith]]></dc:creator>
 | 
			
		||||
            <pubDate>Tue, 30 Oct 2018 23:20:00 GMT</pubDate>
 | 
			
		||||
        </item>
 | 
			
		||||
        <item>
 | 
			
		||||
            <title><![CDATA[Lorem ipsum 2018-10-30T23:19:00+00:00]]></title>
 | 
			
		||||
            <description><![CDATA[Ullamco pariatur aliqua consequat ea veniam id qui incididunt laborum.]]></description>
 | 
			
		||||
            <link>http://example.com/test/1540941540</link>
 | 
			
		||||
            <guid isPermaLink="true">http://example.com/test/1540941540</guid>
 | 
			
		||||
            <dc:creator><![CDATA[John Smith]]></dc:creator>
 | 
			
		||||
            <pubDate>Tue, 30 Oct 2018 23:19:00 GMT</pubDate>
 | 
			
		||||
        </item>
 | 
			
		||||
        <item>
 | 
			
		||||
            <title><![CDATA[Lorem ipsum 2018-10-30T23:18:00+00:00]]></title>
 | 
			
		||||
            <description><![CDATA[Velit proident aliquip aliquip anim mollit voluptate laboris voluptate et occaecat occaecat laboris ea nulla.]]></description>
 | 
			
		||||
            <link>http://example.com/test/1540941480</link>
 | 
			
		||||
            <guid isPermaLink="true">http://example.com/test/1540941480</guid>
 | 
			
		||||
            <dc:creator><![CDATA[John Smith]]></dc:creator>
 | 
			
		||||
            <pubDate>Tue, 30 Oct 2018 23:18:00 GMT</pubDate>
 | 
			
		||||
        </item>
 | 
			
		||||
        <item>
 | 
			
		||||
            <title><![CDATA[Lorem ipsum 2018-10-30T23:17:00+00:00]]></title>
 | 
			
		||||
            <description><![CDATA[Do in quis mollit consequat id in minim laborum sint exercitation laborum elit officia.]]></description>
 | 
			
		||||
            <link>http://example.com/test/1540941420</link>
 | 
			
		||||
            <guid isPermaLink="true">http://example.com/test/1540941420</guid>
 | 
			
		||||
            <dc:creator><![CDATA[John Smith]]></dc:creator>
 | 
			
		||||
            <pubDate>Tue, 30 Oct 2018 23:17:00 GMT</pubDate>
 | 
			
		||||
        </item>
 | 
			
		||||
        <item>
 | 
			
		||||
            <title><![CDATA[Lorem ipsum 2018-10-30T23:16:00+00:00]]></title>
 | 
			
		||||
            <description><![CDATA[Irure id sint ullamco Lorem magna consectetur officia adipisicing duis incididunt.]]></description>
 | 
			
		||||
            <link>http://example.com/test/1540941360</link>
 | 
			
		||||
            <guid isPermaLink="true">http://example.com/test/1540941360</guid>
 | 
			
		||||
            <dc:creator><![CDATA[John Smith]]></dc:creator>
 | 
			
		||||
            <pubDate>Tue, 30 Oct 2018 23:16:00 GMT</pubDate>
 | 
			
		||||
        </item>
 | 
			
		||||
        <item>
 | 
			
		||||
            <title><![CDATA[Lorem ipsum 2018-10-30T23:15:00+00:00]]></title>
 | 
			
		||||
            <description><![CDATA[Sunt anim excepteur esse nisi commodo culpa laborum exercitation ad anim ex elit.]]></description>
 | 
			
		||||
            <link>http://example.com/test/1540941300</link>
 | 
			
		||||
            <guid isPermaLink="true">http://example.com/test/1540941300</guid>
 | 
			
		||||
            <dc:creator><![CDATA[John Smith]]></dc:creator>
 | 
			
		||||
            <pubDate>Tue, 30 Oct 2018 23:15:00 GMT</pubDate>
 | 
			
		||||
        </item>
 | 
			
		||||
        <item>
 | 
			
		||||
            <title><![CDATA[Lorem ipsum 2018-10-30T23:14:00+00:00]]></title>
 | 
			
		||||
            <description><![CDATA[Excepteur aliquip fugiat ex labore nisi.]]></description>
 | 
			
		||||
            <link>http://example.com/test/1540941240</link>
 | 
			
		||||
            <guid isPermaLink="true">http://example.com/test/1540941240</guid>
 | 
			
		||||
            <dc:creator><![CDATA[John Smith]]></dc:creator>
 | 
			
		||||
            <pubDate>Tue, 30 Oct 2018 23:14:00 GMT</pubDate>
 | 
			
		||||
        </item>
 | 
			
		||||
        <item>
 | 
			
		||||
            <title><![CDATA[Lorem ipsum 2018-10-30T23:13:00+00:00]]></title>
 | 
			
		||||
            <description><![CDATA[Id proident adipisicing proident pariatur aute pariatur pariatur dolor dolor in voluptate dolor.]]></description>
 | 
			
		||||
            <link>http://example.com/test/1540941180</link>
 | 
			
		||||
            <guid isPermaLink="true">http://example.com/test/1540941180</guid>
 | 
			
		||||
            <dc:creator><![CDATA[John Smith]]></dc:creator>
 | 
			
		||||
            <pubDate>Tue, 30 Oct 2018 23:13:00 GMT</pubDate>
 | 
			
		||||
        </item>
 | 
			
		||||
    </channel>
 | 
			
		||||
</rss>
 | 
			
		||||
							
								
								
									
										20
									
								
								vendor/github.com/gorilla/feeds/to-implement.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								vendor/github.com/gorilla/feeds/to-implement.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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>
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										27
									
								
								vendor/github.com/gorilla/feeds/uuid.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/gorilla/feeds/uuid.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
package feeds
 | 
			
		||||
 | 
			
		||||
// relevant bits from https://github.com/abneptis/GoUUID/blob/master/uuid.go
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto/rand"
 | 
			
		||||
	"fmt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type UUID [16]byte
 | 
			
		||||
 | 
			
		||||
// create a new uuid v4
 | 
			
		||||
func NewUUID() *UUID {
 | 
			
		||||
	u := &UUID{}
 | 
			
		||||
	_, err := rand.Read(u[:16])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	u[8] = (u[8] | 0x80) & 0xBf
 | 
			
		||||
	u[6] = (u[6] | 0x40) & 0x4f
 | 
			
		||||
	return u
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (u *UUID) String() string {
 | 
			
		||||
	return fmt.Sprintf("%x-%x-%x-%x-%x", u[:4], u[4:6], u[6:8], u[8:10], u[10:])
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user