diff --git a/src/feed/atom.go b/src/feed/atom.go
new file mode 100644
index 0000000..3e966f7
--- /dev/null
+++ b/src/feed/atom.go
@@ -0,0 +1,87 @@
+package feed
+
+import (
+ "encoding/xml"
+ "html"
+ "io"
+ "strings"
+)
+
+type atomFeed struct {
+ XMLName xml.Name `xml:"http://www.w3.org/2005/Atom feed"`
+ ID string `xml:"id"`
+ Title atomText `xml:"title"`
+ Links atomLinks `xml:"link"`
+ Entries []atomEntry `xml:"entry"`
+}
+
+type atomEntry struct {
+ ID string `xml:"id"`
+ Title atomText `xml:"title"`
+ Summary atomText `xml:"summary"`
+ Published string `xml:"published"`
+ Updated string `xml:"updated"`
+ Links atomLinks `xml:"link"`
+ Content atomText `xml:"content"`
+}
+
+type atomText struct {
+ Type string `xml:"type,attr"`
+ Data string `xml:",chardata"`
+ XML string `xml:",innerxml"`
+}
+
+type atomLink struct {
+ Href string `xml:"href,attr"`
+ Rel string `xml:"rel,attr"`
+}
+
+type atomLinks []atomLink
+
+func (a *atomText) String() string {
+ data := a.Data
+ if a.Type == "xhtml" {
+ data = a.XML
+ }
+ return html.UnescapeString(strings.TrimSpace(data))
+}
+
+func (links atomLinks) First(rel string) string {
+ for _, l := range links {
+ if l.Rel == rel {
+ return l.Href
+ }
+ }
+ return ""
+}
+
+func ParseAtom(r io.Reader) (*Feed, error) {
+ f := atomFeed{}
+
+ decoder := xml.NewDecoder(r)
+ if err := decoder.Decode(&f); err != nil {
+ return nil, err
+ }
+
+ feed := &Feed{
+ Title: f.Title.String(),
+ SiteURL: first(f.Links.First("alternate"), f.Links.First("")),
+ FeedURL: f.Links.First("self"),
+ }
+ for _, e := range f.Entries {
+ date, _ := dateParse(first(e.Published, e.Updated))
+ imageUrl := ""
+ podcastUrl := ""
+
+ feed.Items = append(feed.Items, Item{
+ GUID: first(e.ID),
+ Date: date,
+ URL: first(e.Links.First("alternate"), f.Links.First("")),
+ Title: e.Title.String(),
+ Content: e.Content.String(),
+ ImageURL: imageUrl,
+ PodcastURL: podcastUrl,
+ })
+ }
+ return feed, nil
+}
diff --git a/src/feed/atom_test.go b/src/feed/atom_test.go
new file mode 100644
index 0000000..49e5b14
--- /dev/null
+++ b/src/feed/atom_test.go
@@ -0,0 +1,59 @@
+package feed
+
+import (
+ "reflect"
+ "strings"
+ "testing"
+ "time"
+)
+
+func TestAtom(t *testing.T) {
+ have, _ := ParseAtom(strings.NewReader(`
+
+ This is the entry content.
This is the entry content.