Skip to content
Open
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
5 changes: 1 addition & 4 deletions AUTHORS
Original file line number Diff line number Diff line change
@@ -1,5 +1,2 @@
Daniel Walton <daniel@RubyDeveloper.com>




Josh Beckman <email@andjosh.com>
64 changes: 6 additions & 58 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 @@ -20,63 +20,11 @@ Installing
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/baliw/moverss/blob/master/gopod_test.go)

Docs
=======
[http://godoc.org/github.com/baliw/moverss](http://godoc.org/github.com/baliw/moverss)



126 changes: 101 additions & 25 deletions moverss.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 moverss 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,7 +14,7 @@
//
// Example Usage
//
// c := moverss.ChannelFavtory("Ruby Developer", "http://RubyDeveloper.com/", "Ruby Developer Blog")
// c := moverss.ChannelFavtory("Ruby Developer", "http://RubyDeveloper.com/", "Ruby Developer Blog", "http://example.com/image.png")
// c.AddItem(&moverss.Item{
// Title:"Ruby Developer",
// Link:"http://RubyDeveloper.com/",
Expand Down Expand Up @@ -75,8 +71,15 @@ type Channel struct {
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"`

Items []*Item
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,51 @@ 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.
// The Image is the image to be displayed with the podcast.
func ChannelFactory(Title string, Link string, Description string) *Channel {
c := &Channel{Title: Title, Link: Link, Description: Description}
c.Generator = "Moverrs - http://github.com/baliw/moverss"
c.Generator = "moverss - http://github.com/baliw/moverss"
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 +195,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 +209,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 @@ -283,13 +330,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 @@ -312,3 +379,12 @@ func (i *Item) SetPubDate(t interface{}) {
}
panic("moverss.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,
})
}
35 changes: 16 additions & 19 deletions moverss_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
// Copyright 2012 Daniel Walton - All rights reserved.
// Author: Daniel Walton <dan@RubyDeveloper.com>
// https://github.com/baliw
// @dan_gogh

//
// This package implements a rss 2.0 feed generator based on the spec
// located at: http://cyber.law.harvard.edu/rss/rss.html
// This package implements a RSS/Podcast 2.0 feed generator
//
// Test code for moverss.
//
Expand All @@ -22,30 +16,33 @@ import (
)

func Test1(*testing.T) {
fmt.Printf("Testing Moverss...\n")
fmt.Printf("Testing moverss...\n")

c := ChannelFactory("Daniel's Channel", "http://RubyDeveloper.com/", "My Blog")
c.SetPubDate(time.Now().UTC())
c.SetiTunesExplicit("No")

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

// Example: Using an item's SetPubDate method
// Example: Using an item's methods
t := "My title"
l := "http://linkedin.com"
i := &Item{
Title: "LinkedIn",
Link: "http://www.linkedin.com/in/dangogh",
Description: "My LinkedIn",
Title: t,
TunesSubtitle: t,
Link: l,
Description: "My LinkedIn",
TunesDuration: "600",
TunesSummary: "I asked myself that question more than a decade ago and it changed my...",
Guid: l,
Creator: "Daniel's Channel",
}
i.SetEnclosure("http://example.com/sound.mp3", "600", "audio/mpeg")
i.SetPubDate(time.Now().Unix())
c.AddItem(i)

Expand Down