Skip to content
This repository was archived by the owner on Dec 14, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions cf.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Usage:
cf parse [<specifier>...]
cf gen [<alias>]
cf test [<file>]
cf customtest [-l <language-id>] <file> [<input-file>]
cf watch [all] [<specifier>...]
cf open [<specifier>...]
cf stand [<specifier>...]
Expand All @@ -48,6 +49,9 @@ Options:
--version Show version.
-f <file>, --file <file>, <file>
Path to file. E.g. "a.cpp", "./temp/a.cpp"
-l <language-id>, --language-id <language-id>
Language ID. Choose "Add a template" option in "cf config"
to view the list of available language ID.
<specifier> Any useful text. E.g.
"https://codeforces.com/contest/100",
"https://codeforces.com/contest/180/problem/A",
Expand Down Expand Up @@ -85,6 +89,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
Expand Down
108 changes: 108 additions & 0 deletions client/customtest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package client

import (
"fmt"
"io/ioutil"
"strconv"
"time"
"strings"
"errors"
"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 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": {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 != customTestSubmitId {
color.Red("Error: Expected %v, actual %v", customTestSubmitId, output.CustomTestSubmitId)
}
if output.Verdict != "" {
fmt.Printf("%v\n=====\nUsed: %v\n", output.Output, output.Stat)
return
}
// otherwise there will be only CustomTestSubmitId field
}
}
47 changes: 25 additions & 22 deletions cmd/args.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,31 @@ import (

// ParsedArgs parsed arguments
type ParsedArgs struct {
Info client.Info
File string
Specifier []string `docopt:"<specifier>"`
Alias string `docopt:"<alias>"`
Accepted bool `docopt:"ac"`
All bool `docopt:"all"`
Handle string `docopt:"<handle>"`
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:"<specifier>"`
Alias string `docopt:"<alias>"`
LanguageID string `docopt:"--language-id"`
InputFile string `docopt:"<input-file>"`
Accepted bool `docopt:"ac"`
All bool `docopt:"all"`
Handle string `docopt:"<handle>"`
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
Expand Down
2 changes: 2 additions & 0 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
55 changes: 55 additions & 0 deletions cmd/customtest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package cmd

import (
//"github.com/docopt/docopt-go"
"io/ioutil"
"strconv"
"os"

"github.com/xalanq/cf-tool/client"
"github.com/xalanq/cf-tool/config"
)

// CustomTest command
func CustomTest() (err 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 := 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 }
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
}