From 050c661d7252467d7ab2aeb59a9fc8d228c27cf0 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Thu, 20 Feb 2020 21:58:45 +0700 Subject: [PATCH 1/4] Add cf customtest command --- cf.go | 3 ++ client/customtest.go | 96 ++++++++++++++++++++++++++++++++++++++++++++ cmd/args.go | 47 ++++++++++++---------- cmd/cmd.go | 2 + cmd/customtest.go | 46 +++++++++++++++++++++ 5 files changed, 172 insertions(+), 22 deletions(-) create mode 100644 client/customtest.go create mode 100644 cmd/customtest.go diff --git a/cf.go b/cf.go index 44290328..4b8af67e 100644 --- a/cf.go +++ b/cf.go @@ -34,6 +34,7 @@ Usage: cf parse [...] cf gen [] cf test [] + cf customtest [] cf watch [all] [...] cf open [...] cf stand [...] @@ -85,6 +86,8 @@ Examples: test all samples. If you want to add a new testcase, create two files "inK.txt" and "ansK.txt" where K is a string with 0~9. + cf customtest a.py 31 + cf customtest a.py 31 input.txt cf watch Watch the first 10 submissions of current contest. cf watch all Watch all submissions of current contest. cf open 1136a Use default web browser to open the page of contest diff --git a/client/customtest.go b/client/customtest.go new file mode 100644 index 00000000..f6db1ee3 --- /dev/null +++ b/client/customtest.go @@ -0,0 +1,96 @@ +package client + +import ( + "fmt" + "io/ioutil" + "strconv" + "time" + "net/url" + "encoding/json" + + "github.com/fatih/color" +) + +func (c *Client) CustomTest(langId int, source, input string) (err error) { + color.Cyan("Custom Test %v", Langs[strconv.Itoa(langId)]) + + resp, err := c.client.Get(c.host+"/problemset/customtest") + if err != nil { + return + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return + } + + _, err = findHandle(body) + if err != nil { + return + } + + fmt.Printf("Current user: %v\n", c.Handle) + + csrf, err := findCsrf(body) + if err != nil { + return + } + + // fmt.Sprintf("%v?csrf_token=%v", URL, csrf) + resp, err = c.client.PostForm(c.host+"/data/customtest", url.Values{ + "csrf_token": {csrf}, + "source": {source}, + "programTypeId": {strconv.Itoa(langId)}, + "input": {input}, + //"_tta": {440}, + //"communityCode": {}, + "action": {"submitSourceCode"}, + "sourceCode": {source}, + }) + if err != nil { + return + } + + defer resp.Body.Close() + body, err = ioutil.ReadAll(resp.Body) + if err != nil { return } + + var customtestInfo struct { + CustomTestSubmitId string + } + json.Unmarshal(body, &customtestInfo) + + + color.Green("Submitted") + for { + time.Sleep(2500 * time.Millisecond) + + resp, err = c.client.PostForm(c.host+"/data/customtest", url.Values{ + "customTestSubmitId": {customtestInfo.CustomTestSubmitId}, + "csrf_token": {csrf}, + //"communityCode": {}, + "action": {"getVerdict"}, + }) + if err != nil { return } + + defer resp.Body.Close() + body, err = ioutil.ReadAll(resp.Body) + if err != nil { return } + + var output struct { + CustomTestSubmitId string + Output string + Stat string + Verdict string + } + json.Unmarshal(body, &output) + if output.CustomTestSubmitId != customtestInfo.CustomTestSubmitId { + color.Red("Error: Expected %v, actual %v", customtestInfo.CustomTestSubmitId, output.CustomTestSubmitId) + } + if output.Verdict == "OK" { + fmt.Printf("%v\n=====\nUsed: %v\n", output.Output, output.Stat) + return + } + // otherwise there will be only CustomTestSubmitId field + } +} diff --git a/cmd/args.go b/cmd/args.go index 9e9c8b6b..f899bdd4 100644 --- a/cmd/args.go +++ b/cmd/args.go @@ -13,28 +13,31 @@ import ( // ParsedArgs parsed arguments type ParsedArgs struct { - Info client.Info - File string - Specifier []string `docopt:""` - Alias string `docopt:""` - Accepted bool `docopt:"ac"` - All bool `docopt:"all"` - Handle string `docopt:""` - Version string `docopt:"{version}"` - Config bool `docopt:"config"` - Submit bool `docopt:"submit"` - List bool `docopt:"list"` - Parse bool `docopt:"parse"` - Gen bool `docopt:"gen"` - Test bool `docopt:"test"` - Watch bool `docopt:"watch"` - Open bool `docopt:"open"` - Stand bool `docopt:"stand"` - Sid bool `docopt:"sid"` - Race bool `docopt:"race"` - Pull bool `docopt:"pull"` - Clone bool `docopt:"clone"` - Upgrade bool `docopt:"upgrade"` + Info client.Info + File string + Specifier []string `docopt:""` + Alias string `docopt:""` + LanguageID string `docopt:""` + InputFile string `docopt:""` + Accepted bool `docopt:"ac"` + All bool `docopt:"all"` + Handle string `docopt:""` + Version string `docopt:"{version}"` + Config bool `docopt:"config"` + Submit bool `docopt:"submit"` + List bool `docopt:"list"` + Parse bool `docopt:"parse"` + Gen bool `docopt:"gen"` + Test bool `docopt:"test"` + CustomTest bool `docopt:"customtest"` + Watch bool `docopt:"watch"` + Open bool `docopt:"open"` + Stand bool `docopt:"stand"` + Sid bool `docopt:"sid"` + Race bool `docopt:"race"` + Pull bool `docopt:"pull"` + Clone bool `docopt:"clone"` + Upgrade bool `docopt:"upgrade"` } // Args global variable diff --git a/cmd/cmd.go b/cmd/cmd.go index 5dd29c92..c6cf8247 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -35,6 +35,8 @@ func Eval(opts docopt.Opts) error { return Gen() } else if Args.Test { return Test() + } else if Args.CustomTest { + return CustomTest() } else if Args.Watch { return Watch() } else if Args.Open { diff --git a/cmd/customtest.go b/cmd/customtest.go new file mode 100644 index 00000000..d99e415e --- /dev/null +++ b/cmd/customtest.go @@ -0,0 +1,46 @@ +package cmd + +import ( + //"github.com/docopt/docopt-go" + "io/ioutil" + "strconv" + "os" + + "github.com/xalanq/cf-tool/client" +) + +// CustomTest command +func CustomTest() error { + input := "" + if Args.InputFile != "" { + file, err := os.Open(Args.InputFile) + if err != nil { return err } + defer file.Close() + + bytes, err := ioutil.ReadAll(file) + if err != nil { return err } + + input = string(bytes) + } + + langId, err := strconv.Atoi(Args.LanguageID) + if err != nil { return err } + + file, err := os.Open(Args.File) + if err != nil { return err } + defer file.Close() + + bytes, err := ioutil.ReadAll(file) + if err != nil { return err } + + source := string(bytes) + + cln := client.Instance + if err = cln.CustomTest(langId, source, input); err != nil { + if err = loginAgain(cln, err); err == nil { + err = cln.CustomTest(langId, source, input) + } + } + + return nil +} From 940a4d2c2faa157068ca0465c47f204727c5b2c5 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sat, 29 Feb 2020 22:01:22 +0700 Subject: [PATCH 2/4] cf customtest: Automated language deduction --- cf.go | 5 ++++- cmd/args.go | 4 ++-- cmd/customtest.go | 15 ++++++++++++--- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/cf.go b/cf.go index 4b8af67e..3be7a79a 100644 --- a/cf.go +++ b/cf.go @@ -34,7 +34,7 @@ Usage: cf parse [...] cf gen [] cf test [] - cf customtest [] + cf customtest [-l ] [] cf watch [all] [...] cf open [...] cf stand [...] @@ -49,6 +49,9 @@ Options: --version Show version. -f , --file , Path to file. E.g. "a.cpp", "./temp/a.cpp" + -l , --language-id + Language ID. Choose "Add a template" option in "cf config" + to view the list of available language ID. Any useful text. E.g. "https://codeforces.com/contest/100", "https://codeforces.com/contest/180/problem/A", diff --git a/cmd/args.go b/cmd/args.go index f899bdd4..c62a0cd6 100644 --- a/cmd/args.go +++ b/cmd/args.go @@ -17,8 +17,8 @@ type ParsedArgs struct { File string Specifier []string `docopt:""` Alias string `docopt:""` - LanguageID string `docopt:""` - InputFile string `docopt:""` + LanguageID string `docopt:"--language-id"` + InputFile string `docopt:""` Accepted bool `docopt:"ac"` All bool `docopt:"all"` Handle string `docopt:""` diff --git a/cmd/customtest.go b/cmd/customtest.go index d99e415e..a4a3c90d 100644 --- a/cmd/customtest.go +++ b/cmd/customtest.go @@ -7,10 +7,11 @@ import ( "os" "github.com/xalanq/cf-tool/client" + "github.com/xalanq/cf-tool/config" ) // CustomTest command -func CustomTest() error { +func CustomTest() (err error) { input := "" if Args.InputFile != "" { file, err := os.Open(Args.InputFile) @@ -23,8 +24,16 @@ func CustomTest() error { input = string(bytes) } - langId, err := strconv.Atoi(Args.LanguageID) - if err != nil { return err } + langId := 0 + if Args.LanguageID == "" { + cfg := config.Instance + _, index, err := getOneCode(Args.File, cfg.Template) + if err != nil { return err } + langId, _ = strconv.Atoi(cfg.Template[index].Lang) + } else { + langId, err = strconv.Atoi(Args.LanguageID) + if err != nil { return err } + } file, err := os.Open(Args.File) if err != nil { return err } From 33c07f1b8814a178d316171f6dfed663e0d2f75e Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Tue, 24 Mar 2020 17:57:14 +0700 Subject: [PATCH 3/4] Fix error handling bug, handle submit errors --- client/customtest.go | 26 +++++++++++++++++++------- cmd/customtest.go | 2 +- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/client/customtest.go b/client/customtest.go index f6db1ee3..fd3133ed 100644 --- a/client/customtest.go +++ b/client/customtest.go @@ -5,6 +5,8 @@ import ( "io/ioutil" "strconv" "time" + "strings" + "errors" "net/url" "encoding/json" @@ -55,18 +57,28 @@ func (c *Client) CustomTest(langId int, source, input string) (err error) { body, err = ioutil.ReadAll(resp.Body) if err != nil { return } - var customtestInfo struct { - CustomTestSubmitId string - } - json.Unmarshal(body, &customtestInfo) + var customTestInfo map[string]string + json.Unmarshal(body, &customTestInfo) + var customTestSubmitId string + var ok bool + if customTestSubmitId, ok = customTestInfo["customTestSubmitId"]; !ok { + errorMessage := "" + for key, message := range customTestInfo { + if errorMessage != "" { + errorMessage += "; " + } + errorMessage += strings.TrimPrefix(key, "error__") + ": " + message + } + return errors.New(errorMessage) + } color.Green("Submitted") for { time.Sleep(2500 * time.Millisecond) resp, err = c.client.PostForm(c.host+"/data/customtest", url.Values{ - "customTestSubmitId": {customtestInfo.CustomTestSubmitId}, + "customTestSubmitId": {customTestSubmitId}, "csrf_token": {csrf}, //"communityCode": {}, "action": {"getVerdict"}, @@ -84,8 +96,8 @@ func (c *Client) CustomTest(langId int, source, input string) (err error) { Verdict string } json.Unmarshal(body, &output) - if output.CustomTestSubmitId != customtestInfo.CustomTestSubmitId { - color.Red("Error: Expected %v, actual %v", customtestInfo.CustomTestSubmitId, output.CustomTestSubmitId) + if output.CustomTestSubmitId != customTestSubmitId { + color.Red("Error: Expected %v, actual %v", customTestSubmitId, output.CustomTestSubmitId) } if output.Verdict == "OK" { fmt.Printf("%v\n=====\nUsed: %v\n", output.Output, output.Stat) diff --git a/cmd/customtest.go b/cmd/customtest.go index a4a3c90d..c5d7993a 100644 --- a/cmd/customtest.go +++ b/cmd/customtest.go @@ -51,5 +51,5 @@ func CustomTest() (err error) { } } - return nil + return } From 6d91b73604fa2299f161b591e9851f6ecc88711e Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Thu, 2 Apr 2020 15:35:27 +0700 Subject: [PATCH 4/4] Fix behavior with compilation error --- client/customtest.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/customtest.go b/client/customtest.go index fd3133ed..8b7f7fd1 100644 --- a/client/customtest.go +++ b/client/customtest.go @@ -99,7 +99,7 @@ func (c *Client) CustomTest(langId int, source, input string) (err error) { if output.CustomTestSubmitId != customTestSubmitId { color.Red("Error: Expected %v, actual %v", customTestSubmitId, output.CustomTestSubmitId) } - if output.Verdict == "OK" { + if output.Verdict != "" { fmt.Printf("%v\n=====\nUsed: %v\n", output.Output, output.Stat) return }