@@ -4,10 +4,13 @@ import (
4
4
"bytes"
5
5
"context"
6
6
json2 "encoding/json"
7
+ "errors"
8
+ "fmt"
7
9
"io/ioutil"
8
10
"net/http"
9
11
"os"
10
12
"path"
13
+ "strconv"
11
14
"strings"
12
15
template2 "text/template"
13
16
"time"
@@ -20,6 +23,8 @@ import (
20
23
21
24
const listenAddr = ":4243"
22
25
26
+ var TaskExistsError = errors .New ("Task already exists, creation skipped!" )
27
+
23
28
// Serialize task into a JSON string.
24
29
func SerializeTask (meta EgorMeta ) (string , error ) {
25
30
var buffer bytes.Buffer
@@ -33,6 +38,9 @@ func SerializeTask(meta EgorMeta) (string, error) {
33
38
func CreateDirectoryStructure (task Task , config Config , rootDir string , context * cli.Context ) (string , error ) {
34
39
taskDir := path .Join (rootDir , task .Name )
35
40
if err := os .Mkdir (taskDir , 0777 ); err != nil {
41
+ if os .IsExist (err ) {
42
+ return "" , TaskExistsError
43
+ }
36
44
return "" , err
37
45
}
38
46
if err := os .Chdir (taskDir ); err != nil {
@@ -128,8 +136,42 @@ func createWebServer(quit chan<- string) *http.Server {
128
136
}
129
137
}
130
138
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" )
133
175
color .Magenta ("Shutting down the server" )
134
176
135
177
ctx , cancel := context .WithTimeout (context .Background (), 10 * time .Second )
@@ -140,30 +182,34 @@ func waitForShutDown(server *http.Server, done chan<- string, quit <-chan string
140
182
if err := server .Shutdown (ctx ); err != nil {
141
183
color .Red ("Could not shutdown the server" )
142
184
}
143
- done <- content
185
+
186
+ color .Green ("Server stopped" )
144
187
}
145
188
146
189
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 )
149
203
150
204
server := createWebServer (msgReadChannel )
151
205
152
- go waitForShutDown (server , msgReceiveChannel , msgReadChannel )
206
+ go waitForShutDown (server , msgReceiveChannel , msgReadChannel , problemsCount )
153
207
154
208
color .Green ("Starting the server on %s\n " , listenAddr )
155
209
if err := server .ListenAndServe (); err != nil && err != http .ErrServerClosed {
156
210
color .Red ("Could not listen on %s, %v\n " , listenAddr , err )
157
211
}
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
+
167
213
config , err := LoadDefaultConfiguration ()
168
214
if err != nil {
169
215
return err
@@ -172,12 +218,29 @@ func ParseAction(context *cli.Context) error {
172
218
if err != nil {
173
219
return err
174
220
}
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 )
179
242
}
180
- color . Green ( "Created task directory in : %s \n " , taskDir )
243
+
181
244
return nil
182
245
}
183
246
@@ -202,6 +265,12 @@ var ParseCommand = cli.Command{
202
265
Aliases : []string {"m" , "mul" },
203
266
Value : false ,
204
267
},
268
+ & cli.BoolFlag {
269
+ Name : "contest" ,
270
+ Usage : "Indicates if this is a contest to parse" ,
271
+ Aliases : []string {"c" },
272
+ Value : false ,
273
+ },
205
274
},
206
275
Usage : "Parse task from navigator" ,
207
276
UsageText : "egor parse" ,
0 commit comments