forked from indes/flowerss-bot
-
Notifications
You must be signed in to change notification settings - Fork 3
/
opml.go
149 lines (130 loc) · 3.82 KB
/
opml.go
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package bot
import (
"crypto/tls"
"encoding/xml"
"errors"
"io/ioutil"
"net/http"
"net/url"
"time"
"github.com/reaitten/flowerss-bot/internal/config"
"github.com/reaitten/flowerss-bot/internal/model"
)
// OPML opml struct
type OPML struct {
XMLName xml.Name `xml:"opml"`
Version string `xml:"version,attr"`
Head Head `xml:"head"`
Body Body `xml:"body"`
}
// Head opml head
type Head struct {
Title string `xml:"title"`
DateCreated string `xml:"dateCreated,omitempty"`
DateModified string `xml:"dateModified,omitempty"`
OwnerName string `xml:"ownerName,omitempty"`
OwnerEmail string `xml:"ownerEmail,omitempty"`
OwnerID string `xml:"ownerId,omitempty"`
Docs string `xml:"docs,omitempty"`
ExpansionState string `xml:"expansionState,omitempty"`
VertScrollState string `xml:"vertScrollState,omitempty"`
WindowTop string `xml:"windowTop,omitempty"`
WindowBottom string `xml:"windowBottom,omitempty"`
WindowLeft string `xml:"windowLeft,omitempty"`
WindowRight string `xml:"windowRight,omitempty"`
}
// Body opml body
type Body struct {
Outlines []Outline `xml:"outline"`
}
// Outline opml outline
type Outline struct {
Outlines []Outline `xml:"outline"`
Text string `xml:"text,attr"`
Type string `xml:"type,attr,omitempty"`
IsComment string `xml:"isComment,attr,omitempty"`
IsBreakpoint string `xml:"isBreakpoint,attr,omitempty"`
Created string `xml:"created,attr,omitempty"`
Category string `xml:"category,attr,omitempty"`
XMLURL string `xml:"xmlUrl,attr,omitempty"`
HTMLURL string `xml:"htmlUrl,attr,omitempty"`
URL string `xml:"url,attr,omitempty"`
Language string `xml:"language,attr,omitempty"`
Title string `xml:"title,attr,omitempty"`
Version string `xml:"version,attr,omitempty"`
Description string `xml:"description,attr,omitempty"`
}
// NewOPML gen OPML form []byte
func NewOPML(b []byte) (*OPML, error) {
var root OPML
err := xml.Unmarshal(b, &root)
if err != nil {
return nil, err
}
return &root, nil
}
// GetOPMLByURL get OPML form url
func GetOPMLByURL(fileURL string) (*OPML, error) {
var proxy *url.URL
if config.Socks5 != "" {
proxy, _ = url.Parse("socks5://" + config.Socks5)
}
tr := &http.Transport{
Proxy: http.ProxyURL(proxy),
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{
Transport: tr,
Timeout: time.Second * 5,
}
resp, err := client.Get(fileURL)
if err != nil {
return nil, errors.New("fetch opml file error")
}
body, _ := ioutil.ReadAll(resp.Body)
o, err := NewOPML(body)
if err != nil {
return nil, errors.New("parse opml file error")
}
return o, nil
}
// GetFlattenOutlines make all outline at the same xml level
func (o OPML) GetFlattenOutlines() ([]Outline, error) {
var flattenOutlines []Outline
for _, line := range o.Body.Outlines {
if line.Outlines != nil {
for _, subLine := range line.Outlines {
// 查找子outline
if subLine.XMLURL != "" {
flattenOutlines = append(flattenOutlines, subLine)
}
}
}
if line.XMLURL != "" {
flattenOutlines = append(flattenOutlines, line)
}
}
return flattenOutlines, nil
}
// XML dump OPML to xml file
func (o OPML) XML() (string, error) {
b, err := xml.MarshalIndent(o, "", "\t")
return xml.Header + string(b), err
}
// ToOPML dump OPML to opml file
func ToOPML(sources []model.Source) (string, error) {
O := OPML{}
O.XMLName.Local = "opml"
O.Version = "2.0"
O.XMLName.Space = ""
O.Head.Title = "subscriptions in flowerss"
O.Head.DateCreated = time.Now().Format(time.RFC1123)
for _, s := range sources {
outline := Outline{}
outline.Text = s.Title
outline.Type = "rss"
outline.XMLURL = s.Link
O.Body.Outlines = append(O.Body.Outlines, outline)
}
return O.XML()
}