-
Notifications
You must be signed in to change notification settings - Fork 0
/
discover.go
133 lines (111 loc) · 3.31 KB
/
discover.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
package discover
import (
"crypto/sha1"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"strconv"
"strings"
"time"
"github.com/podcreep/server/util"
)
var (
apiKey string
apiSecret string
// http.Client we'll use to make HTTP requests.
httpClient = &http.Client{}
)
type Podcast struct {
ID int64 `json:"id"`
Url string `json:"url"`
Title string `json:"title"`
Description string `json:"description"`
Link string `json:"link"`
Author string `json:"author"`
ImageUrl string `json:"image"`
ArtworkUrl string `json:"artwork"`
NewestItemPublishTime int64 `json:"newestItemPublishTime"`
// TODO "itunesId": 269169796,
// TODO "trendScore": 227,
// TODO "language": "en",
// TODO "categories": { "55": "News", "59": "Politics", "16": "Comedy" }
}
type PodcastListResult struct {
Status string `json:"status"`
Feeds []Podcast `json:"feeds"`
}
type PodcastResult struct {
Status string `json:"status"`
Feed Podcast `json:"feed"`
}
// makeRequest makes a request for the given URL and then appends all
func makeRequest(url string) (*http.Request, error) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, fmt.Errorf("error fetching %s: %w", url, err)
}
authDate := strconv.FormatInt(time.Now().Unix(), 10)
req.Header["User-Agent"] = []string{util.GetUserAgent()}
req.Header["X-Auth-Key"] = []string{apiKey}
req.Header["X-Auth-Date"] = []string{authDate}
// Add the Authorization header
hasher := sha1.New()
_, err = io.WriteString(hasher, apiKey+apiSecret+authDate)
if err != nil {
return nil, fmt.Errorf("error hashing auth header: %v", err)
}
req.Header["Authorization"] = []string{fmt.Sprintf("%x", hasher.Sum(nil))}
return req, nil
}
func Setup() error {
apiKey = os.Getenv("PODCASTINDEX_APIKEY")
apiSecret = os.Getenv("PODCASTINDEX_APISECRET")
return nil
}
func FetchTrending() ([]Podcast, error) {
req, err := makeRequest("https://api.podcastindex.org/api/1.0/podcasts/trending")
if err != nil {
return nil, fmt.Errorf("error making request: %v", err)
}
resp, err := httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("error fetching trending: %v", err)
}
defer resp.Body.Close()
bytes, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("error reading resp: %v", err)
}
decoder := json.NewDecoder(strings.NewReader(string(bytes)))
res := PodcastListResult{}
err = decoder.Decode(&res)
if err != nil {
return nil, fmt.Errorf(string(bytes[0:100])+": %v", err)
}
return res.Feeds, nil
}
func FetchPodcast(id int64) (*Podcast, error) {
req, err := makeRequest(fmt.Sprintf("https://api.podcastindex.org/api/1.0/podcasts/byfeedid?id=%d", id))
if err != nil {
return nil, fmt.Errorf("error making request: %v", err)
}
resp, err := httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("error fetching trending: %v", err)
}
defer resp.Body.Close()
bytes, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("error reading resp: %v", err)
}
decoder := json.NewDecoder(strings.NewReader(string(bytes)))
res := PodcastResult{}
err = decoder.Decode(&res)
if err != nil {
return nil, fmt.Errorf(string(bytes[0:100])+": %v", err)
}
fmt.Printf("feed: %v", res.Feed)
return &res.Feed, nil
}