-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathproject.go
More file actions
176 lines (146 loc) · 4.83 KB
/
Copy pathproject.go
File metadata and controls
176 lines (146 loc) · 4.83 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
package parsehub
import (
"encoding/json"
"github.com/defval/parsehub/internal"
"io/ioutil"
"net/http"
"net/url"
)
// Project run params
type ProjectRunParams struct {
StartUrl string
StartTemplate string
StartValueOverride map[string]interface{}
SendEmail bool
}
// ParseHub project Wrapper
type Project struct {
parsehub *ParseHub
token string
response *ProjectResponse
}
// Creates new parsehub project wrapper
func NewProject(parsehub *ParseHub, token string) *Project {
project := parsehub.projectRegistry[token]
if project == nil {
project = &Project{
parsehub: parsehub,
token: token,
}
}
return project
}
// Get project data
func (p *Project) GetResponse() *ProjectResponse {
return p.response
}
// Refresh project data
func (p *Project) Refresh() error {
_, err := p.parsehub.GetProject(p.token)
return err
}
// This will start running an instance of the project on the ParseHub cloud. It will create a new run object.
// This method will return immediately, while the run continues in the background.
// You can use webhooks or polling to figure out when the data for this
// run is ready in order to retrieve it.
//
// 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 (p *Project) Run(params ProjectRunParams, handleFunc HandleRunFunc) (*Run, error) {
debugf(
"Project.Run: Run project %s with params: %+v",
p.token,
params,
)
requestUrl, _ := url.Parse(BaseUrl + "v2/projects/" + p.token + "/run")
values := url.Values{}
values.Add("api_key", p.parsehub.apiKey)
if params.StartUrl != "" {
values.Add("start_url", params.StartUrl)
}
if params.StartTemplate != "" {
values.Add("start_template", params.StartTemplate)
}
if len(params.StartValueOverride) != 0 {
if bytes, err := json.Marshal(params.StartValueOverride); err != nil {
fatalf("Project.Run: Incorrect StartValueOverride")
} else {
values.Add("start_value_override", string(bytes))
}
}
if params.SendEmail {
values.Add("send_email", "1")
}
if resp, err := http.PostForm(requestUrl.String(), values); err != nil {
warningf("Project.Run: 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)
runResponse := &RunResponse{}
if err := json.Unmarshal(body, runResponse); err != nil {
warningf("Project.Run: Unmarshal error with body %s", body)
return nil, err
}
internal.Lock.RLock()
run := p.parsehub.runRegistry[runResponse.RunToken]
internal.Lock.RUnlock()
if run == nil {
run = NewRun(p.parsehub, runResponse.RunToken)
internal.Lock.Lock()
p.parsehub.runRegistry[runResponse.RunToken] = run
internal.Lock.Unlock()
}
run.response = runResponse
run.SetHandler(handleFunc)
internal.Lock.Lock()
p.parsehub.runRegistry[run.token] = run
internal.Lock.Unlock()
// watch only with handler
if handleFunc != nil {
debugf("Project.Run: Start WatchAndHandle for run with token %s", run.token)
go run.WatchAndHandle()
}
return run, nil
} else {
warningf("Project.Run: ParseHub HTTP response problem: %s", err.Error())
return nil, err
}
}
// This returns the data for the most recent ready run for a project.
// You can use this method in order to have a synchronous interface to your project.
func (p *Project) LoadLastReadyData(target interface{}) error {
debugf("Project.LoadLastReadyData: Load: %s", p.token)
requestUrl, _ := url.Parse(BaseUrl + "v2/projects/" + p.token + "/last_ready_run/data")
values := url.Values{}
values.Add("api_key", p.parsehub.apiKey)
requestUrl.RawQuery = values.Encode()
if resp, err := http.Get(requestUrl.String()); err != nil {
warningf("Project.LoadLastReadyData: ParseHub HTTP request problem: %s", err.Error())
return err
} else if success, err := internal.CheckHTTPStatusCode(resp.StatusCode); success {
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
if err := json.Unmarshal(body, target); err != nil {
warningf("Project.LoadLastReadyData: Unmarshal error with body %s", body)
return err
}
return nil
} else {
warningf("Project.LoadLastReadyData: ParseHub HTTP response problem: %s", err.Error())
return err
}
}