-
Notifications
You must be signed in to change notification settings - Fork 0
/
parsehub.go
206 lines (162 loc) · 5.96 KB
/
parsehub.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
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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
package parsehub
import (
"encoding/json"
"io/ioutil"
"net/http"
"net/url"
"github.com/defval/parsehub/internal"
)
const (
BaseUrl = "https://www.parsehub.com/api/"
)
// ParseHub adapter
type ParseHub struct {
apiKey string
watchQueue chan *Run
projectRegistry map[string]*Project
runRegistry map[string]*Run
}
// Creates new ParseHub adapter with api key
func NewParseHub(apiKey string) *ParseHub {
debugf("ParseHub: Create new parsehub client with api key: %v", apiKey)
parsehub := &ParseHub{
apiKey: apiKey,
projectRegistry: map[string]*Project{},
runRegistry: map[string]*Run{},
}
return parsehub
}
// This will return all of the projects in your account
func (parsehub *ParseHub) GetAllProjects() ([]*Project, error) {
requestUrl, _ := url.Parse(BaseUrl + "v2/projects")
values := url.Values{}
values.Add("api_key", parsehub.apiKey)
requestUrl.RawQuery = values.Encode()
if resp, err := http.Get(requestUrl.String()); err != nil {
warningf("ParseHub.GetAllProjects: ParseHub HTTP request problem: %s", err.Error())
return nil, err
} else if success, err := internal.CheckHTTPStatusCode(resp.StatusCode); success {
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
debugf("ParseHub.GetAllProjects: Response string: %s", body)
projectsResponse := &ProjectsResponse{}
if err := json.Unmarshal(body, projectsResponse); err != nil {
warningf("ParseHub.GetAllProjects: Unmarshal error with body %s", body)
return nil, err
}
projects := []*Project{}
var p *Project
for _, projectResponse := range projectsResponse.Projects {
p = NewProject(parsehub, projectResponse.Token)
p.response = projectResponse
projects = append(projects, p)
}
debugf("ParseHub.GetAllProjects: Get all projects response: %v", projects)
return projects, nil
} else {
warningf("ParseHub.GetAllProjects: ParseHub HTTP response problem: %s", err.Error())
return nil, err
}
}
// This will return the project object wrapper for a specific project.
//
// Params:
//
// start_url (Optional)
// The url to start running on. Defaults to the project’s start_site.
//
// start_template (Optional)
// The template to start running with.
// Defaults to the projects’s start_template (inside the options_json).
//
// start_value_override (Optional)
// The starting global scope for this run. This can be used to pass parameters to your run.
// For example, you can pass {"query": "San Francisco"} to use the query somewhere in your run.
// Defaults to the project’s start_value.
//
// send_email (Optional)
// If set to anything other than 0, send an email when the run either completes successfully
// or fails due to an error. Defaults to 0.
func (parsehub *ParseHub) GetProject(projectToken string) (*Project, error) {
debugf("ParseHub.GetProject: Get project with token: %s", projectToken)
requestUrl, _ := url.Parse(BaseUrl + "v2/projects/" + projectToken)
values := url.Values{}
values.Add("api_key", parsehub.apiKey)
requestUrl.RawQuery = values.Encode()
debugf("ParseHub.GetProject: Requested Url: %s", requestUrl)
if resp, err := http.Get(requestUrl.String()); err != nil {
warningf("ParseHub.GetProject: ParseHub HTTP request problem: %s", err.Error())
return nil, err
} else if success, err := internal.CheckHTTPStatusCode(resp.StatusCode); success {
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
projectResponse := &ProjectResponse{}
if err := json.Unmarshal(body, projectResponse); err != nil {
warningf("ParseHub.GetProject: Unmarshal error with body %s", body)
return nil, err
}
internal.Lock.RLock()
project := parsehub.projectRegistry[projectToken]
internal.Lock.RUnlock()
debugf("ParseHub.GetProject: Loaded project with token %s from registry: %+v", projectToken, project)
if project == nil {
debugf("ParseHub.GetProject: Need to put new project with token %s into registry", projectToken)
project = NewProject(parsehub, projectToken)
internal.Lock.RLock()
parsehub.projectRegistry[projectToken] = project
internal.Lock.RUnlock()
}
project.response = projectResponse
return project, nil
} else {
warningf("ParseHub.GetProject: ParseHub HTTP response problem: %s", err.Error())
return nil, err
}
}
// This returns the run object wrapper for a given run token.
func (parsehub *ParseHub) GetRun(runToken string) (*Run, error) {
debugf("ParseHub.GetRun: Get run with token %s", runToken)
requestUrl, _ := url.Parse(BaseUrl + "v2/runs/" + runToken)
values := url.Values{}
values.Add("api_key", parsehub.apiKey)
requestUrl.RawQuery = values.Encode()
if resp, err := http.Get(requestUrl.String()); err != nil {
warningf("ParseHub.GetRun: ParseHub HTTP request problem: %s", err.Error())
return nil, err
} else if success, err := internal.CheckHTTPStatusCode(resp.StatusCode); success {
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
debugf("ParseHub.GetRun: Response string for run %s: %s", runToken, body)
runResponse := &RunResponse{}
if err := json.Unmarshal(body, runResponse); err != nil {
warningf("ParseHub.GetRun: Problem with unmarshal json string: %s", body)
return nil, err
}
debugf("ParseHub.GetRun: Run response: %+v", runResponse)
internal.Lock.RLock()
run := parsehub.runRegistry[runToken]
internal.Lock.RUnlock()
if run == nil {
run = NewRun(parsehub, runToken)
internal.Lock.Lock()
parsehub.runRegistry[runToken] = run
internal.Lock.Unlock()
}
run.response = runResponse // update response
return run, nil
} else {
warningf("ParseHub.GetRun: ParseHub HTTP response problem: %s", err.Error())
return nil, err
}
}
// Loads run from string
// Example from webhook post body
func (parsehub *ParseHub) LoadRunFromBytes(body []byte) (*Run, error) {
runResponse := &RunResponse{}
if err := json.Unmarshal(body, runResponse); err != nil {
warningf("NewRunFromString: Problem with unmarshal json string: %s", body)
return nil, err
}
run := NewRun(parsehub, runResponse.RunToken)
return run, nil
}