-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatomtranslator.go
108 lines (87 loc) · 1.91 KB
/
atomtranslator.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
package feedcrawler
import (
"errors"
"net/url"
"strings"
"github.com/mmcdole/gofeed"
"github.com/mmcdole/gofeed/atom"
)
type EnhancedAtomTranslator struct {
defaultTranslator *gofeed.DefaultAtomTranslator
}
func NewEnhancedAtomTranslator() *EnhancedAtomTranslator {
return &EnhancedAtomTranslator{
defaultTranslator: &gofeed.DefaultAtomTranslator{},
}
}
func (ct *EnhancedAtomTranslator) Translate(feed interface{}) (*gofeed.Feed, error) {
af, ok := feed.(*atom.Feed)
if !ok {
return nil, errors.New("Feed did not match expected type of *atom.Feed")
}
f, err := ct.defaultTranslator.Translate(feed)
if err != nil {
return nil, err
}
ct.fillUpLink(f, af)
return f, nil
}
func (ct *EnhancedAtomTranslator) fillUpLink(f *gofeed.Feed, af *atom.Feed) {
if f.Link == "" {
f.Link = extractFeedLink(af)
}
for _, item := range f.Items {
if item.Link == "" {
entry := findEntry(af.Entries, item.GUID)
if entry != nil {
item.Link = extractEntryLink(entry)
}
}
}
}
func findEntry(entries []*atom.Entry, id string) *atom.Entry {
for _, entry := range entries {
if entry.ID == id {
return entry
}
}
return nil
}
func extractFeedLink(af *atom.Feed) string {
var link string
if af.Links != nil {
link = extractLink(af.Links, "alternate")
}
if link == "" && isURL(af.ID) {
link = af.ID
}
return link
}
func extractEntryLink(entry *atom.Entry) string {
var link string
if entry.Links != nil {
link = extractLink(entry.Links, "alternate")
}
if link == "" && isURL(entry.ID) {
link = entry.ID
}
return link
}
func extractLink(links []*atom.Link, rel string) string {
if links == nil || len(links) == 0 {
return ""
}
for _, link := range links {
if rel == "" || link.Rel == rel {
return link.Href
}
}
return ""
}
func isURL(value string) bool {
u, err := url.Parse(value)
if err != nil {
return false
}
return u.IsAbs() || strings.HasPrefix(value, "//")
}