-
Notifications
You must be signed in to change notification settings - Fork 0
/
plugin.go
121 lines (107 loc) · 3.18 KB
/
plugin.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
package syndfeed
import (
"strings"
"github.com/antchfx/xmlquery"
)
// http://www.disobey.com/detergent/2002/extendingrss2/
// Module is an interface is used to handle an extension element
// which not specified in either the Atom 1.0 or RSS 2.0 specifications.
type Module interface {
ParseElement(n *xmlquery.Node, v interface{})
}
// ModuleHandlerFunc is a utility function that wrapper a function
// as Module object.
type ModuleHandlerFunc func(*xmlquery.Node, interface{})
func (f ModuleHandlerFunc) ParseElement(n *xmlquery.Node, v interface{}) {
f(n, v)
}
// http://web.resource.org/rss/1.0/modules/content/
var rssContentModule = ModuleHandlerFunc(func(n *xmlquery.Node, v interface{}) {
if n.Data == "encoded" {
v.(*Item).Content = n.InnerText()
}
})
// http://web.resource.org/rss/1.0/modules/syndication/
var rssSyndicationModule = ModuleHandlerFunc(func(n *xmlquery.Node, v interface{}) {
if n.Data == "updateBase" {
if t, err := parseDateString(n.InnerText()); err == nil {
v.(*Feed).LastUpdatedTime = t
}
}
})
// http://web.resource.org/rss/1.0/modules/dc/
var rssDublinCoreModule = ModuleHandlerFunc(func(n *xmlquery.Node, v interface{}) {
switch v2 := v.(type) {
case *Feed:
switch n.Data {
case "title":
v2.Title = n.InnerText()
case "creator":
v2.Authors = append(v2.Authors, &Person{Name: n.InnerText()})
case "subject":
case "description":
v2.Description = n.InnerText()
case "publisher":
case "contributor":
v2.Contributors = append(v2.Contributors, &Person{Name: n.InnerText()})
case "date":
if t, err := parseDateString(n.InnerText()); err == nil {
v2.LastUpdatedTime = t
}
case "language":
v2.Language = n.InnerText()
case "rights":
v2.Copyright = n.InnerText()
}
case *Item:
switch n.Data {
case "title":
v2.Title = n.InnerText()
case "creator":
v2.Authors = append(v2.Authors, &Person{Name: n.InnerText()})
case "subject":
case "description":
v2.Summary = n.InnerText()
case "publisher":
case "contributor":
v2.Contributors = append(v2.Contributors, &Person{Name: n.InnerText()})
case "date":
if t, err := parseDateString(n.InnerText()); err == nil {
v2.PublishDate = t
}
case "rights":
v2.Copyright = n.InnerText()
}
}
})
type module struct {
ns string // namespace URL without https:// or http:// prefix
handler Module
}
var modules []module
func lookupModule(nsURL string) Module {
ns := strings.TrimPrefix(strings.TrimPrefix(nsURL, "http://"), "https://")
for _, m := range modules {
if m.ns == ns {
return m.handler
}
}
return nil
}
// RegisterExtensionModule registers Module with the specified XML namespace.
func RegisterExtensionModule(nsURL string, m Module) {
ns := strings.TrimPrefix(strings.TrimPrefix(nsURL, "http://"), "https://")
b := modules[:0]
for _, v := range modules {
if lookupModule(ns) == nil {
b = append(b, v)
}
}
b = append(b, module{ns, m})
modules = b
}
func init() {
RegisterExtensionModule("http://purl.org/dc/elements/1.1/", rssDublinCoreModule)
RegisterExtensionModule("http://purl.org/rss/1.0/modules/content/", rssContentModule)
RegisterExtensionModule("http://purl.org/rss/1.0/modules/syndication/", rssSyndicationModule)
}