Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AUTHORS
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Daniel Walton <daniel@RubyDeveloper.com>

Josh Beckman <email@andjosh.com>



66 changes: 7 additions & 59 deletions README.markdown
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
About
=====

This is a library implementing an RSS feed generator for the Go programming
This is a library implementing an RSS/Podcast feed generator for the Go programming
language (http://golang.org/).

RSS (Rich Site Summary, or Really Simple Syndication) is a data format used to
publish frequently updated works - such as blog entries, news headlines, audio
and video - in a standardized format.
and video - in a standardized format. Podcasts utilize this format to deliver audio and video files and assiciated metadata.

An RSS document (which is called a "feed", "web feed", or "channel") includes
full or summarized text, plus metadata such as publishing dates and authorship.
Expand All @@ -15,68 +15,16 @@ full or summarized text, plus metadata such as publishing dates and authorship.
Installing
==========

$ go get github.com/baliw/moverss
$ go get github.com/jbckmn/gopod

Example
=======

```go
package main

import (
"fmt"
"github.com/baliw/moverss"
"time"
)

func main() {
c := moverss.ChannelFactory("Daniel's Channel", "http://RubyDeveloper.com/", "My Blog")
c.SetPubDate(time.Now().UTC())

c.AddItem(&moverss.Item{
Title: "Ruby Developer",
Link: "http://RubyDeveloper.com/",
Description: "Ruby Developer",
PubDate: time.Now().UTC().Format(time.RFC1123),
})
c.AddItem(&moverss.Item{
Title: "Stack Overflow",
Link: "http://stackoverflow.com/users/1305696/daniel",
Description: "Stack Overflow",
PubDate: time.Now().UTC().Format(time.RFC1123),
})

// Example: Using an item's SetPubDate method
i := &moverss.Item{
Title: "LinkedIn",
Link: "http://www.linkedin.com/in/dangogh",
Description: "My LinkedIn",
}
i.SetPubDate(time.Now().Unix())
c.AddItem(i)

fmt.Printf("%s\n\n", c.Publish())
fmt.Printf("%s\n\n", c.PublishIndent())
}
```

Full documentation
==================

Read it [online](http://go.pkgdoc.org/github.com/baliw/moverss) or run

$ go doc github.com/baliw/moverss

Other Details
=====================

A few of the more obscure data points aren't implemented yet.
I haven't seen feeds that implement them yet and I just want to make sure my implementation is good.

If you find this package useful and want to give back, I'd greatly appreciate a link to my [Ruby developer](http://RubyDeveloper.com/) site.


The best example is in [the test file](https://github.com/jbckmn/gopod/blob/master/gopod_test.go)

Docs
=======
[http://godoc.org/github.com/jbckmn/gopod](http://godoc.org/github.com/jbckmn/gopod)



171 changes: 125 additions & 46 deletions moverss.go → gopod.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
// Copyright 2012 Daniel Walton - All rights reserved.
// Author: Daniel Walton <dan@RubyDeveloper.com>
// https://github.com/baliw
// @dan_gogh

// Package moverss implements a rss 2.0 feed generator
// Package gopod implements a RSS/Podcast 2.0 feed generator
//
//
// RSS (Rich Site Summary, or Really Simple Syndication) is a data format used
// to publish frequently updated works - such as blog entries, news headlines,
// audio and video - in a standardized format.
// audio and video - in a standardized format. Podcasts utilize this format
// to deliver audio and video files and assiciated metadata.
//
// An RSS document (which is called a "feed", "web feed", or "channel") includes
// full or summarized text, plus metadata such as publishing dates and
Expand All @@ -18,20 +14,20 @@
//
// Example Usage
//
// c := moverss.ChannelFavtory("Ruby Developer", "http://RubyDeveloper.com/", "Ruby Developer Blog")
// c.AddItem(&moverss.Item{
// c := gopod.ChannelFavtory("Ruby Developer", "http://RubyDeveloper.com/", "Ruby Developer Blog", "http://example.com/image.png")
// c.AddItem(&gopod.Item{
// Title:"Ruby Developer",
// Link:"http://RubyDeveloper.com/",
// Description:"My Blog",
// PubDate:time.Now().Unix(),
// })
// c.AddItem(&moverss.Item{
// c.AddItem(&gopod.Item{
// Title:"Stack Overflow",
// Link:"http://stackoverflow.com/users/1305696/daniel",
// Description:"My Stack Overflow",
// PubDate:time.Now().Unix(),
// })
// c.AddItem(&moverss.Item{
// c.AddItem(&gopod.Item{
// Title:"LinkedIn",
// Link:"http://www.linkedin.com/in/dangogh",
// Description:"My LinkedIn",
Expand All @@ -41,7 +37,7 @@
//
//
//
package moverss
package gopod

import (
"bytes"
Expand All @@ -63,20 +59,27 @@ type Channel struct {
/////////////////////
// Optional Fields //
/////////////////////
Language string `xml:"language,omitempty"`
Copyright string `xml:"copyright,omitempty"`
ManagingEditor string `xml:"managingEditor,omitempty"`
WebMaster string `xml:"webMaster,omitempty"`
PubDate string `xml:"pubDate,omitempty"`
LastBuildDate string `xml:"lastBuildDate,omitempty"`
Category string `xml:"category,omitempty"`
Generator string `xml:"generator,omitempty"`
Docs string `xml:"docs,omitempty"`
TTL string `xml:"ttl,omitempty"`
SkipHours string `xml:"skiphours,omitempty"`
SkipDays string `xml:"skipdays,omitempty"`

Items []*Item
Language string `xml:"language,omitempty"`
Copyright string `xml:"copyright,omitempty"`
ManagingEditor string `xml:"managingEditor,omitempty"`
WebMaster string `xml:"webMaster,omitempty"`
PubDate string `xml:"pubDate,omitempty"`
LastBuildDate string `xml:"lastBuildDate,omitempty"`
Category string `xml:"category,omitempty"`
Generator string `xml:"generator,omitempty"`
Docs string `xml:"docs,omitempty"`
TTL string `xml:"ttl,omitempty"`
SkipHours string `xml:"skiphours,omitempty"`
SkipDays string `xml:"skipdays,omitempty"`
TunesAuthor string `xml:"itunes:author,omitempty"`
TunesSubtitle string `xml:"itunes:subtitle,omitempty"`
TunesSummary string `xml:"itunes:summary,omitempty"`
TunesExplicit string `xml:"itunes:explicit,omitempty"`

TunesOwner []*TunesOwner
TunesImage []*TunesImage
AtomLink []*AtomLink
Items []*Item

// [Fields to be implemented]
// Cloud
Expand All @@ -88,6 +91,27 @@ type Channel struct {
XMLName xml.Name `xml:"channel"`
}

type TunesOwner struct {
Name string `xml:"itunes:name,omitempty"`
Email string `xml:"itunes:email,omitempty"`

XMLName xml.Name `xml:"itunes:owner"`
}

type TunesImage struct {
Href string `xml:"href,attr"`

XMLName xml.Name `xml:"itunes:image"`
}

type AtomLink struct {
Href string `xml:"href,attr"`
Rel string `xml:"rel,attr"`
Type string `xml:"type,attr"`

XMLName xml.Name `xml:"atom:link"`
}

type Item struct {
//The URL of the item.
Link string `xml:"link"`
Expand All @@ -114,28 +138,54 @@ type Item struct {
// http://cyber.law.harvard.edu/rss/rss.html#ltcommentsgtSubelementOfLtitemgt
Comments string `xml:"comments,omitempty"`

// [Fields to be implemented]
// Category
// Enclosure
// Source
Creator string `xml:"dc:creator,omitempty"`
TunesAuthor string `xml:"itunes:author,omitempty"`
TunesSubtitle string `xml:"itunes:subtitle,omitempty"`
TunesSummary string `xml:"itunes:summary,omitempty"`
TunesExplicit string `xml:"itunes:explicit,omitempty"`
TunesDuration string `xml:"itunes:duration,omitempty"`

Enclosure []*Enclosure

// Stub member just for the xml generator.
XMLName xml.Name `xml:"item"`
}

type Enclosure struct {
Url string `xml:"url,attr"`
Length string `xml:"length,attr"`
Type string `xml:"type,attr"`

XMLName xml.Name `xml:"enclosure"`
}

// Use this to create the base channel of the rss feed.
// The Title is the name of the channel. It's how people refer to your
// service. If you have an HTML website that contains the same information
// as your RSS file, the title of your channel should be the same as the
// title of your website.
// The Link is the URL to the HTML website corresponding to the channel.
// The Description is the phrase or sentence describing the channel.
func ChannelFactory(Title string, Link string, Description string) *Channel {
// The Image is the image to be displayed with the podcast.
func ChannelFactory(Title string, Link string, Description string, Image string) *Channel {
c := &Channel{Title: Title, Link: Link, Description: Description}
c.Generator = "Moverrs - http://github.com/baliw/moverss"
c.Generator = "gopod - http://github.com/jbckmn/gopod"
c.SetTunesImage(&TunesImage{
Href: Image,
})
c.AtomLink = append(c.AtomLink, &AtomLink{
Href: Link,
Rel: "self",
Type: "application/rss+xml",
})
return c
}

// Add an image struct to the feed
func (c *Channel) SetTunesImage(i *TunesImage) {
c.TunesImage = append(c.TunesImage, i)
}

// Add an item to the feed list
func (c *Channel) AddItem(i *Item) {
c.Items = append(c.Items, i)
Expand All @@ -148,8 +198,8 @@ func (c *Channel) Publish() []byte {
panic(err)
}
return bytes.Join([][]byte{
[]byte(`<?xml version="1.0"?>`),
[]byte(`<rss version="2.0">`),
[]byte(`<?xml version="1.0" encoding="UTF-8"?>`),
[]byte(`<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0">`),
output,
[]byte(`</rss>`),
}, []byte(""))
Expand All @@ -162,8 +212,8 @@ func (c *Channel) PublishIndent() []byte {
panic(err)
}
return bytes.Join([][]byte{
[]byte(`<?xml version="1.0"?>`),
[]byte(`<rss version="2.0">`),
[]byte(`<?xml version="1.0" encoding="UTF-8"?>`),
[]byte(`<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0">`),
output,
[]byte(`</rss>`),
}, []byte("\n"))
Expand Down Expand Up @@ -218,7 +268,7 @@ func (c *Channel) SetPubDate(t interface{}) {
c.PubDate = time.Unix(t.(int64), 0).UTC().Format(time.RFC1123)
return
}
panic("moverss.Channel.SetPubDate() error: Invalid date type")
panic("gopod.Channel.SetPubDate() error: Invalid date type")
}

// (optional) Set the lastBuildDate field. The lastBuildDate is The last time
Expand All @@ -235,7 +285,7 @@ func (c *Channel) SetLastBuildDate(t interface{}) {
c.LastBuildDate = time.Unix(t.(int64), 0).UTC().Format(time.RFC1123)
return
}
panic("moverss.Channel.SetPubDate() error: Invalid date type")
panic("gopod.Channel.SetPubDate() error: Invalid date type")
}

// (optional) Set the category field. The category field specifies one or more
Expand Down Expand Up @@ -283,13 +333,33 @@ func (c *Channel) SetSkipDays(skipdays string) {
c.SkipDays = skipdays
}

// (Not implemented) Set the cloud field. The cloud field allows processes to
// register with a cloud to be notified of updates to the channel, implementing
// a lightweight publish-subscribe protocol for RSS feeds. More Info:
// http://cyber.law.harvard.edu/rss/rss.html#ltcloudgtSubelementOfLtchannelgt
//func (c *Channel) SetCloud(cloud string) {
// return
//}
// (optional) Set the channel's iTunes Explicit field.
func (c *Channel) SetiTunesExplicit(explicit string) {
c.TunesExplicit = explicit
}

// (optional) Set the channel's iTunes Author field.
func (c *Channel) SetiTunesAuthor(author string) {
c.TunesAuthor = author
}

// (optional) Set the channel's iTunes Subtitle field.
func (c *Channel) SetiTunesSubtitle(subtitle string) {
c.TunesSubtitle = subtitle
}

// (optional) Set the channel's iTunes Summary field.
func (c *Channel) SetiTunesSummary(summary string) {
c.TunesSummary = summary
}

// (optional) Set the channel's iTunes Owner struct.
func (c *Channel) SetiTunesOwner(name string, email string) {
c.TunesOwner = append(c.TunesOwner, &TunesOwner{
Name: name,
Email: email,
})
}

// (optional) Set the item's pubDate field. This method can take an instance
// of time.Time, a unix timestamp (int64) or a raw string to use for the date.
Expand All @@ -310,5 +380,14 @@ func (i *Item) SetPubDate(t interface{}) {
i.PubDate = time.Unix(t.(int64), 0).UTC().Format(time.RFC1123)
return
}
panic("moverss.Item.SetPubDate() error: Invalid date type")
panic("gopod.Item.SetPubDate() error: Invalid date type")
}

// (optional) Set the item's iTunes Enclosure struct.
func (i *Item) SetEnclosure(url string, length string, eType string) {
i.Enclosure = append(i.Enclosure, &Enclosure{
Url: url,
Length: length,
Type: eType,
})
}
Loading