diff options
author | Frédéric Guillot <fred@miniflux.net> | 2019-12-22 22:18:21 -0800 |
---|---|---|
committer | Frédéric Guillot <fred@miniflux.net> | 2019-12-22 22:42:00 -0800 |
commit | 33fdb2c489727f8af972d69506fef02c121c4fd0 (patch) | |
tree | 0cf62c594f3fb7827b28e57f41483e927d74b740 /reader/atom/parser.go | |
parent | cfb6ddfcea3e387a7141d4c65099d2f08bc1732b (diff) |
Add support for Atom 0.3
Diffstat (limited to 'reader/atom/parser.go')
-rw-r--r-- | reader/atom/parser.go | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/reader/atom/parser.go b/reader/atom/parser.go index 90a84aa..9a9cb57 100644 --- a/reader/atom/parser.go +++ b/reader/atom/parser.go @@ -5,21 +5,58 @@ package atom // import "miniflux.app/reader/atom" import ( + "bytes" + "encoding/xml" "io" "miniflux.app/errors" "miniflux.app/model" - "miniflux.app/reader/xml" + xml_decoder "miniflux.app/reader/xml" ) +type atomFeed interface { + Transform() *model.Feed +} + // Parse returns a normalized feed struct from a Atom feed. -func Parse(data io.Reader) (*model.Feed, *errors.LocalizedError) { - atomFeed := new(atomFeed) - decoder := xml.NewDecoder(data) - err := decoder.Decode(atomFeed) +func Parse(r io.Reader) (*model.Feed, *errors.LocalizedError) { + var buf bytes.Buffer + tee := io.TeeReader(r, &buf) + + var rawFeed atomFeed + if getAtomFeedVersion(tee) == "0.3" { + rawFeed = new(atom03Feed) + } else { + rawFeed = new(atom10Feed) + } + + decoder := xml_decoder.NewDecoder(&buf) + err := decoder.Decode(rawFeed) if err != nil { return nil, errors.NewLocalizedError("Unable to parse Atom feed: %q", err) } - return atomFeed.Transform(), nil + return rawFeed.Transform(), nil +} + +func getAtomFeedVersion(data io.Reader) string { + decoder := xml_decoder.NewDecoder(data) + for { + token, _ := decoder.Token() + if token == nil { + break + } + + if element, ok := token.(xml.StartElement); ok { + if element.Name.Local == "feed" { + for _, attr := range element.Attr { + if attr.Name.Local == "version" && attr.Value == "0.3" { + return "0.3" + } + } + return "1.0" + } + } + } + return "1.0" } |