-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclient.go
More file actions
177 lines (147 loc) · 4.72 KB
/
client.go
File metadata and controls
177 lines (147 loc) · 4.72 KB
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// Package gtvapi provides a client for the Gronkh.TV API.
//
// This package offers a comprehensive interface to interact with the Gronkh.TV API,
// including video information retrieval, comments, playlists, discovery features,
// and Twitch live status checking.
//
// Example usage:
//
// client := gtvapi.NewClient(nil)
// ctx := context.Background()
// videoInfo, err := client.VideoInfo(ctx, 1000)
// if err != nil {
// log.Fatal(err)
// }
// fmt.Printf("Video: %s\n", videoInfo.Title)
package gtvapi
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"
"resty.dev/v3"
)
const (
// DefaultBaseURL is the default base URL for the Gronkh.TV API.
DefaultBaseURL = "https://api.gronkh.tv/v1"
// DefaultUserAgent is the default user agent string used for API requests.
DefaultUserAgent = "gtvapi/2.0 (+https://github.com/wehmoen-dev/gtvapi)"
// DefaultTimeout is the default timeout for API requests.
DefaultTimeout = 30 * time.Second
// DefaultMaxRetries is the default number of retry attempts for failed requests.
DefaultMaxRetries = 3
// DefaultRetryWaitMin is the minimum wait time between retries.
DefaultRetryWaitMin = 1 * time.Second //revive:disable-line:time-naming
// DefaultRetryWaitMax is the maximum wait time between retries.
DefaultRetryWaitMax = 30 * time.Second
)
// Client represents a Gronkh.TV API client.
type Client struct {
httpClient *resty.Client
baseURL string
}
// ClientConfig holds configuration options for the Client.
type ClientConfig struct {
// Debug enables debug logging for HTTP requests and responses.
Debug bool
// Timeout is the request timeout duration.
// If not specified, DefaultTimeout is used.
Timeout time.Duration
// MaxRetries is the maximum number of retry attempts for failed requests.
// If not specified, DefaultMaxRetries is used.
MaxRetries int
// RetryWaitMin is the minimum wait time between retries.
// If not specified, DefaultRetryWaitMin is used.
RetryWaitMin time.Duration
// RetryWaitMax is the maximum wait time between retries.
// If not specified, DefaultRetryWaitMax is used.
RetryWaitMax time.Duration
// BaseURL is the base URL for the API.
// If not specified, DefaultBaseURL is used.
BaseURL string
// UserAgent is the user agent string for requests.
// If not specified, DefaultUserAgent is used.
UserAgent string
// HTTPClient allows providing a custom HTTP client.
// If nil, a default client will be created.
HTTPClient *http.Client
}
// NewClient creates a new Gronkh.TV API client with the given configuration.
// If config is nil, default configuration values are used.
func NewClient(config *ClientConfig) *Client {
if config == nil {
config = &ClientConfig{}
}
// Set defaults
if config.BaseURL == "" {
config.BaseURL = DefaultBaseURL
}
if config.UserAgent == "" {
config.UserAgent = DefaultUserAgent
}
if config.Timeout == 0 {
config.Timeout = DefaultTimeout
}
if config.MaxRetries == 0 {
config.MaxRetries = DefaultMaxRetries
}
if config.RetryWaitMin == 0 {
config.RetryWaitMin = DefaultRetryWaitMin
}
if config.RetryWaitMax == 0 {
config.RetryWaitMax = DefaultRetryWaitMax
}
// Create Resty client
restyClient := resty.New().
SetBaseURL(config.BaseURL).
SetHeader("User-Agent", config.UserAgent).
SetTimeout(config.Timeout).
SetRetryCount(config.MaxRetries).
SetRetryWaitTime(config.RetryWaitMin).
SetRetryMaxWaitTime(config.RetryWaitMax).
SetDebug(config.Debug)
// Set custom HTTP client if provided
if config.HTTPClient != nil {
restyClient.SetTransport(config.HTTPClient.Transport)
}
return &Client{
httpClient: restyClient,
baseURL: config.BaseURL,
}
}
// get performs a GET request to the specified endpoint with optional query parameters.
func (c *Client) get(ctx context.Context, endpoint string, query map[string]string) ([]byte, error) {
if ctx == nil {
ctx = context.Background()
}
requestURL, err := url.Parse(fmt.Sprintf("%s/%s", c.baseURL, endpoint))
if err != nil {
return nil, fmt.Errorf("failed to parse URL: %w", err)
}
if query != nil {
q := requestURL.Query()
for key, value := range query {
q.Set(key, value)
}
requestURL.RawQuery = q.Encode()
}
resp, err := c.httpClient.R().
SetContext(ctx).
Get(requestURL.String())
if err != nil {
return nil, fmt.Errorf("request failed: %w", err)
}
if resp.StatusCode() != http.StatusOK {
return nil, fmt.Errorf("unexpected status code: %d, body: %s", resp.StatusCode(), string(resp.Bytes()))
}
return resp.Bytes(), nil
}
// unmarshalResponse unmarshals the JSON response into the provided target.
func unmarshalResponse(data []byte, target interface{}) error {
if err := json.Unmarshal(data, target); err != nil {
return fmt.Errorf("failed to unmarshal response: %w", err)
}
return nil
}