gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

rss.go (5004B)


      1 package feeds
      2 
      3 // rss support
      4 // validation done according to spec here:
      5 //    http://cyber.law.harvard.edu/rss/rss.html
      6 
      7 import (
      8 	"encoding/xml"
      9 	"fmt"
     10 	"time"
     11 )
     12 
     13 // private wrapper around the RssFeed which gives us the <rss>..</rss> xml
     14 type RssFeedXml struct {
     15 	XMLName          xml.Name `xml:"rss"`
     16 	Version          string   `xml:"version,attr"`
     17 	ContentNamespace string   `xml:"xmlns:content,attr"`
     18 	Channel          *RssFeed
     19 }
     20 
     21 type RssContent struct {
     22 	XMLName xml.Name `xml:"content:encoded"`
     23 	Content string   `xml:",cdata"`
     24 }
     25 
     26 type RssImage struct {
     27 	XMLName xml.Name `xml:"image"`
     28 	Url     string   `xml:"url"`
     29 	Title   string   `xml:"title"`
     30 	Link    string   `xml:"link"`
     31 	Width   int      `xml:"width,omitempty"`
     32 	Height  int      `xml:"height,omitempty"`
     33 }
     34 
     35 type RssTextInput struct {
     36 	XMLName     xml.Name `xml:"textInput"`
     37 	Title       string   `xml:"title"`
     38 	Description string   `xml:"description"`
     39 	Name        string   `xml:"name"`
     40 	Link        string   `xml:"link"`
     41 }
     42 
     43 type RssFeed struct {
     44 	XMLName        xml.Name `xml:"channel"`
     45 	Title          string   `xml:"title"`       // required
     46 	Link           string   `xml:"link"`        // required
     47 	Description    string   `xml:"description"` // required
     48 	Language       string   `xml:"language,omitempty"`
     49 	Copyright      string   `xml:"copyright,omitempty"`
     50 	ManagingEditor string   `xml:"managingEditor,omitempty"` // Author used
     51 	WebMaster      string   `xml:"webMaster,omitempty"`
     52 	PubDate        string   `xml:"pubDate,omitempty"`       // created or updated
     53 	LastBuildDate  string   `xml:"lastBuildDate,omitempty"` // updated used
     54 	Category       string   `xml:"category,omitempty"`
     55 	Generator      string   `xml:"generator,omitempty"`
     56 	Docs           string   `xml:"docs,omitempty"`
     57 	Cloud          string   `xml:"cloud,omitempty"`
     58 	Ttl            int      `xml:"ttl,omitempty"`
     59 	Rating         string   `xml:"rating,omitempty"`
     60 	SkipHours      string   `xml:"skipHours,omitempty"`
     61 	SkipDays       string   `xml:"skipDays,omitempty"`
     62 	Image          *RssImage
     63 	TextInput      *RssTextInput
     64 	Items          []*RssItem `xml:"item"`
     65 }
     66 
     67 type RssItem struct {
     68 	XMLName     xml.Name `xml:"item"`
     69 	Title       string   `xml:"title"`       // required
     70 	Link        string   `xml:"link"`        // required
     71 	Description string   `xml:"description"` // required
     72 	Content     *RssContent
     73 	Author      string `xml:"author,omitempty"`
     74 	Category    string `xml:"category,omitempty"`
     75 	Comments    string `xml:"comments,omitempty"`
     76 	Enclosure   *RssEnclosure
     77 	Guid        string `xml:"guid,omitempty"`    // Id used
     78 	PubDate     string `xml:"pubDate,omitempty"` // created or updated
     79 	Source      string `xml:"source,omitempty"`
     80 }
     81 
     82 type RssEnclosure struct {
     83 	//RSS 2.0 <enclosure url="http://example.com/file.mp3" length="123456789" type="audio/mpeg" />
     84 	XMLName xml.Name `xml:"enclosure"`
     85 	Url     string   `xml:"url,attr"`
     86 	Length  string   `xml:"length,attr"`
     87 	Type    string   `xml:"type,attr"`
     88 }
     89 
     90 type Rss struct {
     91 	*Feed
     92 }
     93 
     94 // create a new RssItem with a generic Item struct's data
     95 func newRssItem(i *Item) *RssItem {
     96 	item := &RssItem{
     97 		Title:       i.Title,
     98 		Link:        i.Link.Href,
     99 		Description: i.Description,
    100 		Guid:        i.Id,
    101 		PubDate:     anyTimeFormat(time.RFC1123Z, i.Created, i.Updated),
    102 	}
    103 	if len(i.Content) > 0 {
    104 		item.Content = &RssContent{Content: i.Content}
    105 	}
    106 	if i.Source != nil {
    107 		item.Source = i.Source.Href
    108 	}
    109 
    110 	// Define a closure
    111 	if i.Enclosure != nil && i.Enclosure.Type != "" && i.Enclosure.Length != "" {
    112 		item.Enclosure = &RssEnclosure{Url: i.Enclosure.Url, Type: i.Enclosure.Type, Length: i.Enclosure.Length}
    113 	}
    114 
    115 	if i.Author != nil {
    116 		item.Author = i.Author.Name
    117 	}
    118 	return item
    119 }
    120 
    121 // create a new RssFeed with a generic Feed struct's data
    122 func (r *Rss) RssFeed() *RssFeed {
    123 	pub := anyTimeFormat(time.RFC1123Z, r.Created, r.Updated)
    124 	build := anyTimeFormat(time.RFC1123Z, r.Updated)
    125 	author := ""
    126 	if r.Author != nil {
    127 		author = r.Author.Email
    128 		if len(r.Author.Name) > 0 {
    129 			author = fmt.Sprintf("%s (%s)", r.Author.Email, r.Author.Name)
    130 		}
    131 	}
    132 
    133 	var image *RssImage
    134 	if r.Image != nil {
    135 		image = &RssImage{Url: r.Image.Url, Title: r.Image.Title, Link: r.Image.Link, Width: r.Image.Width, Height: r.Image.Height}
    136 	}
    137 
    138 	channel := &RssFeed{
    139 		Title:          r.Title,
    140 		Link:           r.Link.Href,
    141 		Description:    r.Description,
    142 		ManagingEditor: author,
    143 		PubDate:        pub,
    144 		LastBuildDate:  build,
    145 		Copyright:      r.Copyright,
    146 		Image:          image,
    147 	}
    148 	for _, i := range r.Items {
    149 		channel.Items = append(channel.Items, newRssItem(i))
    150 	}
    151 	return channel
    152 }
    153 
    154 // FeedXml returns an XML-Ready object for an Rss object
    155 func (r *Rss) FeedXml() interface{} {
    156 	// only generate version 2.0 feeds for now
    157 	return r.RssFeed().FeedXml()
    158 
    159 }
    160 
    161 // FeedXml returns an XML-ready object for an RssFeed object
    162 func (r *RssFeed) FeedXml() interface{} {
    163 	return &RssFeedXml{
    164 		Version:          "2.0",
    165 		Channel:          r,
    166 		ContentNamespace: "http://purl.org/rss/1.0/modules/content/",
    167 	}
    168 }