Skip to content

Commit 4c968c6

Browse files
Erouichermehdi
authored andcommitted
Add contest parsing support
1 parent 7a9624c commit 4c968c6

File tree

1 file changed

+89
-20
lines changed

1 file changed

+89
-20
lines changed

commands/parse.go

+89-20
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@ import (
44
"bytes"
55
"context"
66
json2 "encoding/json"
7+
"errors"
8+
"fmt"
79
"io/ioutil"
810
"net/http"
911
"os"
1012
"path"
13+
"strconv"
1114
"strings"
1215
template2 "text/template"
1316
"time"
@@ -20,6 +23,8 @@ import (
2023

2124
const listenAddr = ":4243"
2225

26+
var TaskExistsError = errors.New("Task already exists, creation skipped!")
27+
2328
// Serialize task into a JSON string.
2429
func SerializeTask(meta EgorMeta) (string, error) {
2530
var buffer bytes.Buffer
@@ -33,6 +38,9 @@ func SerializeTask(meta EgorMeta) (string, error) {
3338
func CreateDirectoryStructure(task Task, config Config, rootDir string, context *cli.Context) (string, error) {
3439
taskDir := path.Join(rootDir, task.Name)
3540
if err := os.Mkdir(taskDir, 0777); err != nil {
41+
if os.IsExist(err) {
42+
return "", TaskExistsError
43+
}
3644
return "", err
3745
}
3846
if err := os.Chdir(taskDir); err != nil {
@@ -128,8 +136,42 @@ func createWebServer(quit chan<- string) *http.Server {
128136
}
129137
}
130138

131-
func waitForShutDown(server *http.Server, done chan<- string, quit <-chan string) {
132-
content := <-quit
139+
func waitForShutDown(server *http.Server, done chan<- string, quit <-chan string, problemsCount int) {
140+
141+
readProblems := func() <-chan string {
142+
results := make(chan string, problemsCount)
143+
defer close(results)
144+
has := false
145+
for i := 0; i < problemsCount; i++ {
146+
if has {
147+
select {
148+
case content := <-quit:
149+
results <- content
150+
case <-time.After(5 * time.Second):
151+
fmt.Println("Timed Out!")
152+
return results
153+
}
154+
} else {
155+
content := <-quit
156+
results <- content
157+
has = true
158+
}
159+
160+
}
161+
return results
162+
}
163+
164+
consumeProblems := func(results <-chan string) {
165+
defer close(done)
166+
for result := range results {
167+
done <- result
168+
}
169+
}
170+
171+
problems := readProblems()
172+
consumeProblems(problems)
173+
174+
color.Green("Received data from CHelper companion")
133175
color.Magenta("Shutting down the server")
134176

135177
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
@@ -140,30 +182,34 @@ func waitForShutDown(server *http.Server, done chan<- string, quit <-chan string
140182
if err := server.Shutdown(ctx); err != nil {
141183
color.Red("Could not shutdown the server")
142184
}
143-
done <- content
185+
186+
color.Green("Server stopped")
144187
}
145188

146189
func ParseAction(context *cli.Context) error {
147-
msgReceiveChannel := make(chan string, 1)
148-
msgReadChannel := make(chan string, 1)
190+
problemsCount := 1
191+
192+
if context.Bool("contest") && context.NArg() > 0 {
193+
count, err := strconv.Atoi(context.Args().Get(0))
194+
if err != nil {
195+
color.Red(fmt.Sprintf("Cannot parse problems count = '%s', a number required!", context.Args().Get(0)))
196+
return fmt.Errorf("Failed to parse test id = %s", context.Args().Get(0))
197+
}
198+
problemsCount = count
199+
}
200+
201+
msgReceiveChannel := make(chan string, problemsCount)
202+
msgReadChannel := make(chan string, problemsCount)
149203

150204
server := createWebServer(msgReadChannel)
151205

152-
go waitForShutDown(server, msgReceiveChannel, msgReadChannel)
206+
go waitForShutDown(server, msgReceiveChannel, msgReadChannel, problemsCount)
153207

154208
color.Green("Starting the server on %s\n", listenAddr)
155209
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
156210
color.Red("Could not listen on %s, %v\n", listenAddr, err)
157211
}
158-
json := <-msgReceiveChannel
159-
color.Green("Server stopped")
160-
color.Green("Received data from CHelper companion")
161-
// first line contains a json string
162-
lines := strings.Split(json, "\n")
163-
task, err := extractTaskFromJson(lines[1])
164-
if err != nil {
165-
return err
166-
}
212+
167213
config, err := LoadDefaultConfiguration()
168214
if err != nil {
169215
return err
@@ -172,12 +218,29 @@ func ParseAction(context *cli.Context) error {
172218
if err != nil {
173219
return err
174220
}
175-
taskDir, err := CreateDirectoryStructure(*task, *config, cwd, context)
176-
if err != nil {
177-
color.Red("Error happened %v", err)
178-
return err
221+
222+
for json := range msgReceiveChannel {
223+
// first line contains a json string
224+
lines := strings.Split(json, "\n")
225+
task, err := extractTaskFromJson(lines[1])
226+
if err != nil {
227+
return err
228+
}
229+
230+
taskDir, err := CreateDirectoryStructure(*task, *config, cwd, context)
231+
if err != nil {
232+
if err == TaskExistsError {
233+
color.Magenta("Skipping creating task %s as it already exists", task.Name)
234+
continue
235+
} else {
236+
color.Red("Unexpected error happened %s", err.Error())
237+
return err
238+
}
239+
}
240+
241+
color.Green("Created task directory in : %s\n", taskDir)
179242
}
180-
color.Green("Created task directory in : %s\n", taskDir)
243+
181244
return nil
182245
}
183246

@@ -202,6 +265,12 @@ var ParseCommand = cli.Command{
202265
Aliases: []string{"m", "mul"},
203266
Value: false,
204267
},
268+
&cli.BoolFlag{
269+
Name: "contest",
270+
Usage: "Indicates if this is a contest to parse",
271+
Aliases: []string{"c"},
272+
Value: false,
273+
},
205274
},
206275
Usage: "Parse task from navigator",
207276
UsageText: "egor parse",

0 commit comments

Comments
 (0)