aboutsummaryrefslogtreecommitdiffstats
path: root/internal/exporter/exporter.go
blob: 2d32fdb7912a996dd0c89f42873dfc18e97b3d1c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package exporter

import (
	"bytes"
	"encoding/json"
	"encoding/xml"
	"fmt"
	"html/template"

	"adammathes.com/neko/models/feed"
)

type OPML struct {
	XMLName xml.Name `xml:"opml"`
	Version string   `xml:"version,attr"`
	Head    struct {
		Title string `xml:"title"`
	} `xml:"head"`
	Body struct {
		Outlines []Outline `xml:"outline"`
	} `xml:"body"`
}

type Outline struct {
	XMLName  xml.Name  `xml:"outline"`
	Text     string    `xml:"text,attr"`
	Title    string    `xml:"title,attr,omitempty"`
	Type     string    `xml:"type,attr,omitempty"`
	XMLURL   string    `xml:"xmlUrl,attr,omitempty"`
	HTMLURL  string    `xml:"htmlUrl,attr,omitempty"`
	Outlines []Outline `xml:"outline,omitempty"`
}

func ExportFeeds(format string) string {
	feeds, err := feed.All()
	if err != nil {
		return ""
	}

	switch format {
	case "text":
		var b bytes.Buffer
		for _, f := range feeds {
			fmt.Fprintf(&b, "%s\n", f.Url)
		}
		return b.String()

	case "opml":
		var o OPML
		o.Version = "2.0"
		o.Head.Title = "neko feeds"

		// Group by category
		cats := make(map[string][]*feed.Feed)
		var noCat []*feed.Feed
		for _, f := range feeds {
			if f.Category != "" {
				cats[f.Category] = append(cats[f.Category], f)
			} else {
				noCat = append(noCat, f)
			}
		}

		for cat, fds := range cats {
			out := Outline{Text: cat}
			for _, f := range fds {
				out.Outlines = append(out.Outlines, Outline{
					Text:    f.Title,
					Title:   f.Title,
					Type:    "rss",
					XMLURL:  f.Url,
					HTMLURL: f.WebUrl,
				})
			}
			o.Body.Outlines = append(o.Body.Outlines, out)
		}

		for _, f := range noCat {
			o.Body.Outlines = append(o.Body.Outlines, Outline{
				Text:    f.Title,
				Title:   f.Title,
				Type:    "rss",
				XMLURL:  f.Url,
				HTMLURL: f.WebUrl,
			})
		}

		b, err := xml.MarshalIndent(o, "", "  ")
		if err != nil {
			return ""
		}
		return xml.Header + string(b)

	case "json":
		js, _ := json.MarshalIndent(feeds, "", "  ")
		return string(js)

	case "html":
		htmlTemplateString := `<html>
<head>
<title>feeds</title>
</head>
<body>
<ul>
{{ range . }}
<li><a href="{{.WebUrl}}">{{.Title}}</a> | <a href="{{.Url}}">xml</a></li>
{{ end }}
</ul>
</body>
</html>`
		var bts bytes.Buffer
		htmlTemplate, err := template.New("feeds").Parse(htmlTemplateString)
		if err != nil {
			return ""
		}
		err = htmlTemplate.Execute(&bts, feeds)
		if err != nil {
			return ""
		}
		return bts.String()
	}

	return ""
}