aboutsummaryrefslogtreecommitdiffhomepage
path: root/reader/atom/parser.go
diff options
context:
space:
mode:
Diffstat (limited to 'reader/atom/parser.go')
-rw-r--r--reader/atom/parser.go49
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"
}