Example #1
0
func parseRSS(c appengine.Context, body []byte, charsetReader func(string, io.Reader) (io.Reader, error)) (*Feed, []*Story, error) {
	var f Feed
	var s []*Story
	r := rss.Rss{}
	d := xml.NewDecoder(bytes.NewReader(body))
	d.CharsetReader = charsetReader
	d.DefaultSpace = "DefaultSpace"
	if err := d.Decode(&r); err != nil {
		return nil, nil, err
	}
	f.Title = r.Title
	if t, err := parseDate(c, &f, r.LastBuildDate, r.PubDate); err == nil {
		f.Updated = t
	} else {
		c.Warningf("no rss feed date: %v", f.Link)
	}
	f.Link = r.BaseLink()
	f.Hub = r.Hub()

	for _, i := range r.Items {
		st := Story{
			Link:   i.Link,
			Author: i.Author,
		}
		if i.Content != "" {
			st.content = i.Content
		} else if i.Description != "" {
			st.content = i.Description
		}
		if i.Title != "" {
			st.Title = i.Title
		} else if i.Description != "" {
			st.Title = i.Description
		}
		if st.content == st.Title {
			st.Title = ""
		}
		st.Title = textTitle(st.Title)
		if i.Guid != nil {
			st.Id = i.Guid.Guid
		}
		if i.Enclosure != nil && strings.HasPrefix(i.Enclosure.Type, "audio/") {
			st.MediaContent = i.Enclosure.Url
		} else if i.Media != nil && strings.HasPrefix(i.Media.Type, "audio/") {
			st.MediaContent = i.Media.URL
		}
		if t, err := parseDate(c, &f, i.PubDate, i.Date, i.Published); err == nil {
			st.Published = t
			st.Updated = t
		}

		s = append(s, &st)
	}
	return &f, s, nil
}
Example #2
0
// makeOpf creates an epub opf for the specified rss feed.
func (e FeedEpub) makeOpf(rssFeed rss.Rss) (epub.Opf, []epub.Chapter, error) {
	if len(rssFeed.Items) == 0 {
		return epub.Opf{}, nil, errors.New("No feed items to build")
	}
	ids := []epub.Identifier{
		{Value: rssFeed.BaseLink(),
			IdentifierType: codelist5.URN}}
	creator := epub.Creator{
		Name: rssFeed.Items[0].Author,
		Role: "aut",
	}
	metadata := epub.Metadata{
		Language: "en", // maybe, lol!
		Title:    rssFeed.Title,
		Creator:  creator,
		Date:     rssFeed.LastBuildDate,
	}

	var manifestItems []epub.ManifestItem
	var chapters []epub.Chapter
	// TODO: This is a totally naive build of file names that may be non-unique.
	for i, item := range rssFeed.Items {
		var manifestItem epub.ManifestItem
		var chapter epub.Chapter
		//  TODO: in a better world this would be generated by sanitized filename
		manifestItem.Id = fmt.Sprintf("manifest_id_%d", i)
		filename := "chapters/" + item.Title + ".xhtml"
		manifestItem.Href = filename
		manifestItem.Title = &item.Title
		chapter.FileName = filename
		// TODO: we should fetch all the assets used in each rss item and put them in the
		// epub in an assets directory, then rewrite the paths to each asset.  At the
		// very least we should rewrite relative urls to actually point to the feed.
		chapter.Contents = item.Description
		manifestItem.MediaType = xhtmlMediaType
		manifestItems = append(manifestItems, manifestItem)
		chapters = append(chapters, chapter)
	}
	manifest := epub.Manifest{
		ManifestItems: manifestItems,
	}

	opfRootFile := epub.OpfRootFile{
		FullPath:    fmt.Sprintf("OEBPS/%s.opf", rssFeed.Title),
		MediaType:   "application/oebps-package+xml",
		Identifiers: ids,
		Metadata:    metadata,
		Manifest:    manifest,
	}

	opf := epub.Opf{
		RootFiles: []epub.OpfRootFile{opfRootFile},
	}
	return opf, chapters, nil
}