Beispiel #1
0
func (ap *Parser) parseSource(p *xpp.XMLPullParser) (*Source, error) {

	if err := p.Expect(xpp.StartTag, "source"); err != nil {
		return nil, err
	}

	source := &Source{}

	contributors := []*Person{}
	authors := []*Person{}
	categories := []*Category{}
	links := []*Link{}
	extensions := ext.Extensions{}

	for {
		tok, err := p.NextTag()
		if err != nil {
			return nil, err
		}

		if tok == xpp.EndTag {
			break
		}

		if tok == xpp.StartTag {

			name := strings.ToLower(p.Name)

			if shared.IsExtension(p) {
				e, err := shared.ParseExtension(extensions, p)
				if err != nil {
					return nil, err
				}
				extensions = e
			} else if name == "title" {
				result, err := ap.parseAtomText(p)
				if err != nil {
					return nil, err
				}
				source.Title = result
			} else if name == "id" {
				result, err := ap.parseAtomText(p)
				if err != nil {
					return nil, err
				}
				source.ID = result
			} else if name == "updated" ||
				name == "modified" {
				result, err := ap.parseAtomText(p)
				if err != nil {
					return nil, err
				}
				source.Updated = result
				date, err := shared.ParseDate(result)
				if err == nil {
					utcDate := date.UTC()
					source.UpdatedParsed = &utcDate
				}
			} else if name == "subtitle" ||
				name == "tagline" {
				result, err := ap.parseAtomText(p)
				if err != nil {
					return nil, err
				}
				source.Subtitle = result
			} else if name == "link" {
				result, err := ap.parseLink(p)
				if err != nil {
					return nil, err
				}
				links = append(links, result)
			} else if name == "generator" {
				result, err := ap.parseGenerator(p)
				if err != nil {
					return nil, err
				}
				source.Generator = result
			} else if name == "icon" {
				result, err := ap.parseAtomText(p)
				if err != nil {
					return nil, err
				}
				source.Icon = result
			} else if name == "logo" {
				result, err := ap.parseAtomText(p)
				if err != nil {
					return nil, err
				}
				source.Logo = result
			} else if name == "rights" ||
				name == "copyright" {
				result, err := ap.parseAtomText(p)
				if err != nil {
					return nil, err
				}
				source.Rights = result
			} else if name == "contributor" {
				result, err := ap.parsePerson("contributor", p)
				if err != nil {
					return nil, err
				}
				contributors = append(contributors, result)
			} else if name == "author" {
				result, err := ap.parsePerson("author", p)
				if err != nil {
					return nil, err
				}
				authors = append(authors, result)
			} else if name == "category" {
				result, err := ap.parseCategory(p)
				if err != nil {
					return nil, err
				}
				categories = append(categories, result)
			} else {
				err := p.Skip()
				if err != nil {
					return nil, err
				}
			}
		}
	}

	if len(categories) > 0 {
		source.Categories = categories
	}

	if len(authors) > 0 {
		source.Authors = authors
	}

	if len(contributors) > 0 {
		source.Contributors = contributors
	}

	if len(links) > 0 {
		source.Links = links
	}

	if len(extensions) > 0 {
		source.Extensions = extensions
	}

	if err := p.Expect(xpp.EndTag, "source"); err != nil {
		return nil, err
	}

	return source, nil
}
Beispiel #2
0
func (ap *Parser) parseEntry(p *xpp.XMLPullParser) (*Entry, error) {
	if err := p.Expect(xpp.StartTag, "entry"); err != nil {
		return nil, err
	}
	entry := &Entry{}

	contributors := []*Person{}
	authors := []*Person{}
	categories := []*Category{}
	links := []*Link{}
	extensions := ext.Extensions{}

	for {
		tok, err := p.NextTag()
		if err != nil {
			return nil, err
		}

		if tok == xpp.EndTag {
			break
		}

		if tok == xpp.StartTag {

			name := strings.ToLower(p.Name)

			if shared.IsExtension(p) {
				e, err := shared.ParseExtension(extensions, p)
				if err != nil {
					return nil, err
				}
				extensions = e
			} else if name == "title" {
				result, err := ap.parseAtomText(p)
				if err != nil {
					return nil, err
				}
				entry.Title = result
			} else if name == "id" {
				result, err := ap.parseAtomText(p)
				if err != nil {
					return nil, err
				}
				entry.ID = result
			} else if name == "rights" ||
				name == "copyright" {
				result, err := ap.parseAtomText(p)
				if err != nil {
					return nil, err
				}
				entry.Rights = result
			} else if name == "summary" {
				result, err := ap.parseAtomText(p)
				if err != nil {
					return nil, err
				}
				entry.Summary = result
			} else if name == "source" {
				result, err := ap.parseSource(p)
				if err != nil {
					return nil, err
				}
				entry.Source = result
			} else if name == "updated" ||
				name == "modified" {
				result, err := ap.parseAtomText(p)
				if err != nil {
					return nil, err
				}
				entry.Updated = result
				date, err := shared.ParseDate(result)
				if err == nil {
					utcDate := date.UTC()
					entry.UpdatedParsed = &utcDate
				}
			} else if name == "contributor" {
				result, err := ap.parsePerson("contributor", p)
				if err != nil {
					return nil, err
				}
				contributors = append(contributors, result)
			} else if name == "author" {
				result, err := ap.parsePerson("author", p)
				if err != nil {
					return nil, err
				}
				authors = append(authors, result)
			} else if name == "category" {
				result, err := ap.parseCategory(p)
				if err != nil {
					return nil, err
				}
				categories = append(categories, result)
			} else if name == "link" {
				result, err := ap.parseLink(p)
				if err != nil {
					return nil, err
				}
				links = append(links, result)
			} else if name == "published" ||
				name == "issued" {
				result, err := ap.parseAtomText(p)
				if err != nil {
					return nil, err
				}
				entry.Published = result
				date, err := shared.ParseDate(result)
				if err == nil {
					utcDate := date.UTC()
					entry.PublishedParsed = &utcDate
				}
			} else if name == "content" {
				result, err := ap.parseContent(p)
				if err != nil {
					return nil, err
				}
				entry.Content = result
			} else {
				err := p.Skip()
				if err != nil {
					return nil, err
				}
			}
		}
	}

	if len(categories) > 0 {
		entry.Categories = categories
	}

	if len(authors) > 0 {
		entry.Authors = authors
	}

	if len(links) > 0 {
		entry.Links = links
	}

	if len(contributors) > 0 {
		entry.Contributors = contributors
	}

	if len(extensions) > 0 {
		entry.Extensions = extensions
	}

	if err := p.Expect(xpp.EndTag, "entry"); err != nil {
		return nil, err
	}

	return entry, nil
}
Beispiel #3
0
func (rp *Parser) parseRoot(p *xpp.XMLPullParser) (*Feed, error) {
	rssErr := p.Expect(xpp.StartTag, "rss")
	rdfErr := p.Expect(xpp.StartTag, "rdf")
	if rssErr != nil && rdfErr != nil {
		return nil, fmt.Errorf("%s or %s", rssErr.Error(), rdfErr.Error())
	}

	// Items found in feed root
	var channel *Feed
	var textinput *TextInput
	var image *Image
	items := []*Item{}

	ver := rp.parseVersion(p)

	for {
		tok, err := p.NextTag()
		if err != nil {
			return nil, err
		}

		if tok == xpp.EndTag {
			break
		}

		if tok == xpp.StartTag {

			// Skip any extensions found in the feed root.
			if shared.IsExtension(p) {
				p.Skip()
				continue
			}

			name := strings.ToLower(p.Name)

			if name == "channel" {
				channel, err = rp.parseChannel(p)
				if err != nil {
					fmt.Printf("error in channel: %s\n", err)
					return nil, err
				}
			} else if name == "item" {
				item, err := rp.parseItem(p)
				if err != nil {
					return nil, err
				}
				items = append(items, item)
			} else if name == "textinput" {
				textinput, err = rp.parseTextInput(p)
				if err != nil {
					return nil, err
				}
			} else if name == "image" {
				image, err = rp.parseImage(p)
				if err != nil {
					return nil, err
				}
			} else {
				p.Skip()
			}
		}
	}

	rssErr = p.Expect(xpp.EndTag, "rss")
	rdfErr = p.Expect(xpp.EndTag, "rdf")
	if rssErr != nil && rdfErr != nil {
		return nil, fmt.Errorf("%s or %s", rssErr.Error(), rdfErr.Error())
	}

	if channel == nil {
		channel = &Feed{}
		channel.Items = []*Item{}
	}

	if len(items) > 0 {
		channel.Items = append(channel.Items, items...)
	}

	if textinput != nil {
		channel.TextInput = textinput
	}

	if image != nil {
		channel.Image = image
	}

	channel.Version = ver
	return channel, nil
}
Beispiel #4
0
func (rp *Parser) parseItem(p *xpp.XMLPullParser) (item *Item, err error) {

	if err = p.Expect(xpp.StartTag, "item"); err != nil {
		return nil, err
	}

	item = &Item{}
	extensions := ext.Extensions{}
	categories := []*Category{}

	for {
		tok, err := p.NextTag()
		if err != nil {
			return nil, err
		}

		if tok == xpp.EndTag {
			break
		}

		if tok == xpp.StartTag {

			name := strings.ToLower(p.Name)

			if shared.IsExtension(p) {
				ext, err := shared.ParseExtension(extensions, p)
				if err != nil {
					return nil, err
				}
				item.Extensions = ext
			} else if name == "title" {
				result, err := shared.ParseText(p)
				if err != nil {
					return nil, err
				}
				item.Title = result
			} else if name == "description" {
				result, err := shared.ParseText(p)
				if err != nil {
					return nil, err
				}
				item.Description = result
			} else if name == "link" {
				result, err := shared.ParseText(p)
				if err != nil {
					return nil, err
				}
				item.Link = result
			} else if name == "author" {
				result, err := shared.ParseText(p)
				if err != nil {
					return nil, err
				}
				item.Author = result
			} else if name == "comments" {
				result, err := shared.ParseText(p)
				if err != nil {
					return nil, err
				}
				item.Comments = result
			} else if name == "pubdate" {
				result, err := shared.ParseText(p)
				if err != nil {
					return nil, err
				}
				item.PubDate = result
				date, err := shared.ParseDate(result)
				if err == nil {
					utcDate := date.UTC()
					item.PubDateParsed = &utcDate
				}
			} else if name == "source" {
				result, err := rp.parseSource(p)
				if err != nil {
					return nil, err
				}
				item.Source = result
			} else if name == "enclosure" {
				result, err := rp.parseEnclosure(p)
				if err != nil {
					return nil, err
				}
				item.Enclosure = result
			} else if name == "guid" {
				result, err := rp.parseGUID(p)
				if err != nil {
					return nil, err
				}
				item.GUID = result
			} else if name == "category" {
				result, err := rp.parseCategory(p)
				if err != nil {
					return nil, err
				}
				categories = append(categories, result)
			} else {
				// Skip any elements not part of the item spec
				p.Skip()
			}
		}
	}

	if len(categories) > 0 {
		item.Categories = categories
	}

	if len(extensions) > 0 {
		item.Extensions = extensions

		if itunes, ok := item.Extensions["itunes"]; ok {
			item.ITunesExt = ext.NewITunesItemExtension(itunes)
		}

		if dc, ok := item.Extensions["dc"]; ok {
			item.DublinCoreExt = ext.NewDublinCoreExtension(dc)
		}
	}

	if err = p.Expect(xpp.EndTag, "item"); err != nil {
		return nil, err
	}

	return item, nil
}
Beispiel #5
0
func (rp *Parser) parseChannel(p *xpp.XMLPullParser) (rss *Feed, err error) {

	if err = p.Expect(xpp.StartTag, "channel"); err != nil {
		return nil, err
	}

	rss = &Feed{}
	rss.Items = []*Item{}

	extensions := ext.Extensions{}
	categories := []*Category{}

	for {
		tok, err := p.NextTag()
		if err != nil {
			return nil, err
		}

		if tok == xpp.EndTag {
			break
		}

		if tok == xpp.StartTag {

			name := strings.ToLower(p.Name)

			if shared.IsExtension(p) {
				ext, err := shared.ParseExtension(extensions, p)
				if err != nil {
					return nil, err
				}
				extensions = ext
			} else if name == "title" {
				result, err := shared.ParseText(p)
				if err != nil {
					return nil, err
				}
				rss.Title = result
			} else if name == "description" {
				result, err := shared.ParseText(p)
				if err != nil {
					return nil, err
				}
				rss.Description = result
			} else if name == "link" {
				result, err := shared.ParseText(p)
				if err != nil {
					return nil, err
				}
				rss.Link = result
			} else if name == "language" {
				result, err := shared.ParseText(p)
				if err != nil {
					return nil, err
				}
				rss.Language = result
			} else if name == "copyright" {
				result, err := shared.ParseText(p)
				if err != nil {
					return nil, err
				}
				rss.Copyright = result
			} else if name == "managingeditor" {
				result, err := shared.ParseText(p)
				if err != nil {
					return nil, err
				}
				rss.ManagingEditor = result
			} else if name == "webmaster" {
				result, err := shared.ParseText(p)
				if err != nil {
					return nil, err
				}
				rss.WebMaster = result
			} else if name == "pubdate" {
				result, err := shared.ParseText(p)
				if err != nil {
					return nil, err
				}
				rss.PubDate = result
				date, err := shared.ParseDate(result)
				if err == nil {
					utcDate := date.UTC()
					rss.PubDateParsed = &utcDate
				}
			} else if name == "lastbuilddate" {
				result, err := shared.ParseText(p)
				if err != nil {
					return nil, err
				}
				rss.LastBuildDate = result
				date, err := shared.ParseDate(result)
				if err == nil {
					utcDate := date.UTC()
					rss.LastBuildDateParsed = &utcDate
				}
			} else if name == "generator" {
				result, err := shared.ParseText(p)
				if err != nil {
					return nil, err
				}
				rss.Generator = result
			} else if name == "docs" {
				result, err := shared.ParseText(p)
				if err != nil {
					return nil, err
				}
				rss.Docs = result
			} else if name == "ttl" {
				result, err := shared.ParseText(p)
				if err != nil {
					return nil, err
				}
				rss.TTL = result
			} else if name == "rating" {
				result, err := shared.ParseText(p)
				if err != nil {
					return nil, err
				}
				rss.Rating = result
			} else if name == "skiphours" {
				result, err := rp.parseSkipHours(p)
				if err != nil {
					return nil, err
				}
				rss.SkipHours = result
			} else if name == "skipdays" {
				result, err := rp.parseSkipDays(p)
				if err != nil {
					return nil, err
				}
				rss.SkipDays = result
			} else if name == "item" {
				result, err := rp.parseItem(p)
				if err != nil {
					return nil, err
				}
				rss.Items = append(rss.Items, result)
			} else if name == "cloud" {
				result, err := rp.parseCloud(p)
				if err != nil {
					return nil, err
				}
				rss.Cloud = result
			} else if name == "category" {
				result, err := rp.parseCategory(p)
				if err != nil {
					return nil, err
				}
				categories = append(categories, result)
			} else if name == "image" {
				result, err := rp.parseImage(p)
				if err != nil {
					return nil, err
				}
				rss.Image = result
			} else if name == "textinput" {
				result, err := rp.parseTextInput(p)
				if err != nil {
					return nil, err
				}
				rss.TextInput = result
			} else {
				// Skip element as it isn't an extension and not
				// part of the spec
				p.Skip()
			}
		}
	}

	if err = p.Expect(xpp.EndTag, "channel"); err != nil {
		return nil, err
	}

	if len(categories) > 0 {
		rss.Categories = categories
	}

	if len(extensions) > 0 {
		rss.Extensions = extensions

		if itunes, ok := rss.Extensions["itunes"]; ok {
			rss.ITunesExt = ext.NewITunesFeedExtension(itunes)
		}

		if dc, ok := rss.Extensions["dc"]; ok {
			rss.DublinCoreExt = ext.NewDublinCoreExtension(dc)
		}
	}

	return rss, nil
}