-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathweb_client.go
132 lines (119 loc) · 2.87 KB
/
web_client.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
package benchmark
import (
"fmt"
"io/ioutil"
"net/http"
"net/http/cookiejar"
"net/url"
)
const (
authCookie = ".ASPXAUTH"
)
type WebClient struct {
bacsBaseUrl string
httpClient *http.Client
contestId int
}
func NewWebClient(bacsBaseUrl string) (*WebClient, error) {
cookieJar, err := cookiejar.New(nil)
if err != nil {
return nil, err
}
return &WebClient{
bacsBaseUrl: bacsBaseUrl,
httpClient: &http.Client{
Jar: cookieJar,
},
}, nil
}
func (c *WebClient) URL(relative string) string {
return c.bacsBaseUrl + relative
}
func (c *WebClient) URLf(format string, param ...interface{}) string {
return c.URL(fmt.Sprintf(format, param...))
}
func (c *WebClient) Login(username, password string) error {
resp, err := c.httpClient.Get(c.URL("/Account/LogOn"))
if err != nil {
return err
}
resp.Body.Close()
resp, err = c.httpClient.PostForm(c.URL("/Account/LogOn"),
url.Values{
"Login": {username},
"Password": {password},
"RememberMe": {"false"},
"logon": {"Вход"},
})
if err != nil {
return err
}
defer resp.Body.Close()
// check that login succeeded
url, err := url.Parse(c.bacsBaseUrl)
if err != nil {
return err
}
if resp.StatusCode/100 == 5 {
return fmt.Errorf("unable to login: %d %q", resp.StatusCode, resp.Status)
}
for _, cookie := range c.httpClient.Jar.Cookies(url) {
if cookie.Name == authCookie {
return nil
}
}
return fmt.Errorf("unable to login: %q cookie not found", authCookie)
}
func (c *WebClient) EnterContest(contestId int) error {
resp, err := c.httpClient.Get(
c.URLf("/Contest/EnterContest?contestID=%d", contestId))
if err != nil {
return err
}
resp.Body.Close()
c.contestId = contestId
return nil
}
func (c *WebClient) monitor(name string, params ...string) (string, error) {
url := c.URLf("/Monitor/%s?contestId=%d", name, c.contestId)
for _, param := range params {
url += "&" + param
}
resp, err := c.httpClient.Get(url)
if err != nil {
return "", err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return "", fmt.Errorf("unable to read monitor: %v", resp.Status)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
return string(body), nil
}
func (c *WebClient) AcmMonitor() (string, error) {
return c.monitor("AcmMonitor", "showLeftMenu=True")
}
func (c *WebClient) SchoolFinalMonitor() (string, error) {
return c.monitor("SchoolFinalMonitor")
}
func (c *WebClient) MySchoolFinalSubmits() (string, error) {
return c.monitor("MySchoolFinalSubmits")
}
func (c *WebClient) Submit(problem, compiler, solution string) error {
resp, err := c.httpClient.PostForm(
c.URLf("/Contest/Submit?contestId=%d", c.contestId),
url.Values{
"Problem": {problem},
"Compiler": {CompilerId(compiler)},
"SolutionText": {solution},
"SolutionFileType": {"Text"},
})
if err != nil {
return err
}
resp.Body.Close()
return nil
}