fast exact not done
This commit is contained in:
@@ -1,9 +1,15 @@
|
|||||||
package broker
|
package broker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"local/storage"
|
||||||
"local/truckstop/config"
|
"local/truckstop/config"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FastExact struct {
|
type FastExact struct {
|
||||||
@@ -35,35 +41,100 @@ func (fe FastExact) Search(states []config.State) ([]Job, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (fe FastExact) login() error {
|
func (fe FastExact) login() error {
|
||||||
return errors.New("not impl")
|
conf := config.Get()
|
||||||
|
return fe._login(conf.Brokers.FastExact.Username, conf.Brokers.FastExact.Password, conf.DB())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fe FastExact) _login(username, password string, db storage.DB) error {
|
||||||
|
req, err := http.NewRequest(
|
||||||
|
http.MethodPost,
|
||||||
|
`https://www.fastexact.com/secure/index.php?page=userLogin`,
|
||||||
|
strings.NewReader(fmt.Sprintf(
|
||||||
|
`user_name=%s&user_password=%s&buttonSubmit=Login`,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fe.setHeaders(req)
|
||||||
|
|
||||||
|
db.Set("cookies_"+req.URL.Host, nil)
|
||||||
|
resp, err := fe.doer.doRequest(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
b, _ := ioutil.ReadAll(resp.Body)
|
||||||
|
resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return fmt.Errorf("bad status logging into fast exact: %d: %s", resp.StatusCode, b)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fe FastExact) setHeaders(req *http.Request) {
|
||||||
|
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0")
|
||||||
|
req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8")
|
||||||
|
req.Header.Set("Accept-Language", "en-US,en;q=0.5")
|
||||||
|
req.Header.Set("Accept-Encoding", "gzip, deflate, br")
|
||||||
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fe FastExact) search(states []config.State) ([]Job, error) {
|
func (fe FastExact) search(states []config.State) ([]Job, error) {
|
||||||
req, err := fe.newRequest(states)
|
var result []Job
|
||||||
|
for _, state := range states {
|
||||||
|
jobs, err := fe.searchOne(state)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result = append(result, jobs...)
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fe FastExact) searchOne(state config.State) ([]Job, error) {
|
||||||
|
req, err := fe.newRequest(state)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := fe.doRequest(req)
|
resp, err := fe.doer.doRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return fe.parse(resp)
|
return fe.parse(resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fe FastExact) newRequest(states []config.State) (*http.Request, error) {
|
func (fe FastExact) newRequest(state config.State) (*http.Request, error) {
|
||||||
return nil, errors.New("not impl")
|
return nil, errors.New("not impl: fe.newreq")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fe FastExact) doRequest(req *http.Request) (*http.Response, error) {
|
func (fe FastExact) doRequest(req *http.Request) (*http.Response, error) {
|
||||||
return nil, errors.New("not impl")
|
return nil, errors.New("not impl: fe.doreq")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fe FastExact) parse(resp *http.Response) ([]Job, error) {
|
func (fe FastExact) parse(resp *http.Response) ([]Job, error) {
|
||||||
return nil, errors.New("not impl")
|
return nil, errors.New("not impl: fe.parse")
|
||||||
}
|
}
|
||||||
|
|
||||||
type mockFastExactDoer struct{}
|
type mockFastExactDoer struct{}
|
||||||
|
|
||||||
func (mock mockFastExactDoer) doRequest(*http.Request) (*http.Response, error) {
|
func (mock mockFastExactDoer) doRequest(req *http.Request) (*http.Response, error) {
|
||||||
return nil, errors.New("not impl")
|
switch req.URL.Path {
|
||||||
|
case "/secure/index.php":
|
||||||
|
if req.URL.Query().Get("page") != "userLogin" {
|
||||||
|
return nil, errors.New("bad query")
|
||||||
|
}
|
||||||
|
if b, _ := ioutil.ReadAll(req.Body); !bytes.Equal(b, []byte(`user_name=u&user_password=p&buttonSubmit=Login`)) {
|
||||||
|
return nil, errors.New("bad req body")
|
||||||
|
}
|
||||||
|
return &http.Response{
|
||||||
|
Status: http.StatusText(http.StatusOK),
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
Header: http.Header{"Set-Cookie": []string{"PHPSESSID=8o0slo18q6cr0v5v5k9ohjcg01; path=/"}},
|
||||||
|
Body: io.NopCloser(bytes.NewReader([]byte{})),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
return nil, errors.New("bad path")
|
||||||
}
|
}
|
||||||
|
|||||||
32
broker/fastexact_test.go
Normal file
32
broker/fastexact_test.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package broker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"local/storage"
|
||||||
|
"local/truckstop/config"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"golang.org/x/time/rate"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFastExactLogin(t *testing.T) {
|
||||||
|
limiter = rate.NewLimiter(rate.Limit(60.0), 1)
|
||||||
|
fe := NewFastExact().WithMock()
|
||||||
|
_ = fe
|
||||||
|
db := storage.NewMap()
|
||||||
|
if err := fe._login("u", "p", db); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFastExactSearch(t *testing.T) {
|
||||||
|
limiter = rate.NewLimiter(rate.Limit(60.0), 1)
|
||||||
|
fe := NewFastExact().WithMock()
|
||||||
|
_ = fe
|
||||||
|
db := storage.NewMap()
|
||||||
|
_ = db
|
||||||
|
if jobs, err := fe.search([]config.State{config.State("NC"), config.State("SC")}); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else {
|
||||||
|
t.Fatal(jobs)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user