diff --git a/src/opml/opml.go b/src/opml/opml.go index a77f220..b6b92c7 100644 --- a/src/opml/opml.go +++ b/src/opml/opml.go @@ -8,8 +8,8 @@ import ( type Folder struct { Title string - Folders []*Folder - Feeds []*Feed + Folders []Folder + Feeds []Feed } type Feed struct { @@ -18,16 +18,8 @@ type Feed struct { SiteUrl string } -func NewFolder(title string) *Folder { - return &Folder{ - Title: title, - Folders: make([]*Folder, 0), - Feeds: make([]*Feed, 0), - } -} - -func (f *Folder) AllFeeds() []*Feed { - feeds := make([]*Feed, 0) +func (f Folder) AllFeeds() []Feed { + feeds := make([]Feed, 0) feeds = append(feeds, f.Feeds...) for _, subfolder := range f.Folders { feeds = append(feeds, subfolder.AllFeeds()...) @@ -39,7 +31,7 @@ var e = html.EscapeString var indent = " " var nl = "\n" -func (f *Folder) outline(level int) string { +func (f Folder) outline(level int) string { builder := strings.Builder{} prefix := strings.Repeat(indent, level) @@ -58,14 +50,14 @@ func (f *Folder) outline(level int) string { return builder.String() } -func (f *Feed) outline(level int) string { +func (f Feed) outline(level int) string { return strings.Repeat(indent, level) + fmt.Sprintf( `` + nl, e(f.Title), e(f.FeedUrl), e(f.SiteUrl), ) } -func (f *Folder) OPML() string { +func (f Folder) OPML() string { builder := strings.Builder{} builder.WriteString(`` + nl) builder.WriteString(`` + nl) diff --git a/src/opml/opml_test.go b/src/opml/opml_test.go index 2086638..4a97b1b 100644 --- a/src/opml/opml_test.go +++ b/src/opml/opml_test.go @@ -7,31 +7,31 @@ import ( func TestOPML(t *testing.T) { - have := (&Folder{ + have := (Folder{ Title: "", - Feeds: []*Feed{ - &Feed{ + Feeds: []Feed{ + Feed{ Title: "title1", FeedUrl: "https://baz.com/feed.xml", SiteUrl: "https://baz.com/", }, }, - Folders: []*Folder{ - &Folder{ + Folders: []Folder{ + Folder{ Title: "sub", - Feeds: []*Feed{ - &Feed{ + Feeds: []Feed{ + Feed{ Title: "subtitle1", FeedUrl: "https://foo.com/feed.xml", SiteUrl: "https://foo.com/", }, - &Feed{ + Feed{ Title: "&>", FeedUrl: "https://bar.com/feed.xml", SiteUrl: "https://bar.com/", }, }, - Folders: []*Folder{}, + Folders: []Folder{}, }, }, }).OPML() diff --git a/src/opml/read.go b/src/opml/read.go index 3e6b6c0..9899061 100644 --- a/src/opml/read.go +++ b/src/opml/read.go @@ -18,11 +18,11 @@ type outline struct { Outlines []outline `xml:"outline,omitempty"` } -func buildFolder(title string, outlines []outline) *Folder { - folder := NewFolder(title) +func buildFolder(title string, outlines []outline) Folder { + folder := Folder{Title: title} for _, outline := range outlines { if outline.Type == "rss" { - folder.Feeds = append(folder.Feeds, &Feed{ + folder.Feeds = append(folder.Feeds, Feed{ Title: outline.Title, FeedUrl: outline.FeedUrl, SiteUrl: outline.SiteUrl, @@ -35,7 +35,7 @@ func buildFolder(title string, outlines []outline) *Folder { return folder } -func Parse(r io.Reader) (*Folder, error) { +func Parse(r io.Reader) (Folder, error) { val := new(opml) decoder := xml.NewDecoder(r) decoder.Entity = xml.HTMLEntity @@ -43,7 +43,7 @@ func Parse(r io.Reader) (*Folder, error) { err := decoder.Decode(&val) if err != nil { - return nil, err + return Folder{}, err } return buildFolder("", val.Outlines), nil } diff --git a/src/opml/read_test.go b/src/opml/read_test.go index ca5dd9b..85adaa9 100644 --- a/src/opml/read_test.go +++ b/src/opml/read_test.go @@ -24,31 +24,30 @@ func TestParse(t *testing.T) { `)) - want := &Folder{ + want := Folder{ Title: "", - Feeds: []*Feed{ - &Feed{ + Feeds: []Feed{ + Feed{ Title: "title1", FeedUrl: "https://baz.com/feed.xml", SiteUrl: "https://baz.com/", }, }, - Folders: []*Folder{ - &Folder{ + Folders: []Folder{ + Folder{ Title: "sub", - Feeds: []*Feed{ - &Feed{ + Feeds: []Feed{ + Feed{ Title: "subtitle1", FeedUrl: "https://foo.com/feed.xml", SiteUrl: "https://foo.com/", }, - &Feed{ + Feed{ Title: "&>", FeedUrl: "https://bar.com/feed.xml", SiteUrl: "https://bar.com/", }, }, - Folders: []*Folder{}, }, }, } diff --git a/src/server/routes.go b/src/server/routes.go index 15c208a..64a897a 100644 --- a/src/server/routes.go +++ b/src/server/routes.go @@ -2,17 +2,18 @@ package server import ( "encoding/json" - "github.com/nkanaev/yarr/src/assets" - "github.com/nkanaev/yarr/src/auth" - "github.com/nkanaev/yarr/src/router" - "github.com/nkanaev/yarr/src/storage" - "github.com/nkanaev/yarr/src/opml" - "github.com/nkanaev/yarr/src/worker" "io/ioutil" "log" "math" "net/http" "reflect" + + "github.com/nkanaev/yarr/src/assets" + "github.com/nkanaev/yarr/src/auth" + "github.com/nkanaev/yarr/src/opml" + "github.com/nkanaev/yarr/src/router" + "github.com/nkanaev/yarr/src/storage" + "github.com/nkanaev/yarr/src/worker" ) func (s *Server) handler() http.Handler { @@ -331,14 +332,13 @@ func (s *Server) handleOPMLImport(c *router.Context) { c.Out.WriteHeader(http.StatusBadRequest) return } - for _, f := range doc.Feeds { s.db.CreateFeed(f.Title, "", f.SiteUrl, f.FeedUrl, nil) } for _, f := range doc.Folders { folder := s.db.CreateFolder(f.Title) for _, ff := range f.AllFeeds() { - s.db.CreateFeed(f.Title, "", ff.SiteUrl, ff.FeedUrl, &folder.Id) + s.db.CreateFeed(ff.Title, "", ff.SiteUrl, ff.FeedUrl, &folder.Id) } } @@ -354,13 +354,13 @@ func (s *Server) handleOPMLExport(c *router.Context) { c.Out.Header().Set("Content-Type", "application/xml; charset=utf-8") c.Out.Header().Set("Content-Disposition", `attachment; filename="subscriptions.opml"`) - doc := opml.NewFolder("") + doc := opml.Folder{} feedsByFolderID := make(map[int64][]*storage.Feed) for _, feed := range s.db.ListFeeds() { feed := feed if feed.FolderId == nil { - doc.Feeds = append(doc.Feeds, &opml.Feed{ + doc.Feeds = append(doc.Feeds, opml.Feed{ Title: feed.Title, FeedUrl: feed.FeedLink, SiteUrl: feed.Link, @@ -376,14 +376,15 @@ func (s *Server) handleOPMLExport(c *router.Context) { if len(folderFeeds) == 0 { continue } - opmlfolder := opml.NewFolder(folder.Title) + opmlfolder := opml.Folder{Title: folder.Title} for _, feed := range folderFeeds { - opmlfolder.Feeds = append(opmlfolder.Feeds, &opml.Feed{ + opmlfolder.Feeds = append(opmlfolder.Feeds, opml.Feed{ Title: feed.Title, FeedUrl: feed.FeedLink, SiteUrl: feed.Link, }) } + doc.Folders = append(doc.Folders, opmlfolder) } c.Out.Write([]byte(doc.OPML()))