Passed
Push — master ( 49f1ef...b2146d )
by John
05:49 queued 11s
created

SubmissionModel::countSolution()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace App\Models;
4
5
use Illuminate\Database\Eloquent\Model;
6
use Illuminate\Support\Facades\DB;
7
use App\Models\Tool\PastebinModel;
8
use Cache;
9
10
class SubmissionModel extends Model
11
{
12
    protected $tableName='submission';
13
    protected $table='submission';
14
    protected $primaryKey='sid';
15
    const DELETED_AT=null;
16
    const UPDATED_AT=null;
17
    const CREATED_AT=null;
18
19
    public $colorScheme=[
20
        "Waiting"                => "wemd-blue-text",
21
        "Judge Error"            => "wemd-black-text",
22
        "System Error"           => "wemd-black-text",
23
        "Compile Error"          => "wemd-orange-text",
24
        "Runtime Error"          => "wemd-red-text",
25
        "Wrong Answer"           => "wemd-red-text",
26
        "Time Limit Exceed"      => "wemd-deep-purple-text",
27
        "Real Time Limit Exceed" => "wemd-deep-purple-text",
28
        "Accepted"               => "wemd-green-text",
29
        "Memory Limit Exceed"    => "wemd-deep-purple-text",
30
        "Presentation Error"     => "wemd-red-text",
31
        "Submitted"              => "wemd-blue-text",
32
        "Pending"                => "wemd-blue-text",
33
        "Judging"                => "wemd-blue-text",
34
        "Partially Accepted"     => "wemd-cyan-text",
35
        'Submission Error'       => 'wemd-black-text',
36
        'Output Limit Exceeded'  => 'wemd-deep-purple-text',
37
        "Idleness Limit Exceed"  => 'wemd-deep-purple-text'
38
    ];
39
    public $langConfig=[];
40
41
    public function __construct()
42
    {
43
        $tempLangConfig=[[
44
            "id" => "plaintext",
45
            "extensions" => [".txt", ".gitignore"],
46
            "aliases" => ["Plain Text", "text"],
47
            "mimetypes" => ["text/plain"]
48
        ], [
49
            "id" => "json",
50
            "extensions" => [".json", ".bowerrc", ".jshintrc", ".jscsrc", ".eslintrc", ".babelrc"],
51
            "aliases" => ["JSON", "json"],
52
            "mimetypes" => ["application/json"]
53
        ], [
54
            "id" => "bat",
55
            "extensions" => [".bat", ".cmd"],
56
            "aliases" => ["Batch", "bat"]
57
        ], [
58
            "id" => "coffeescript",
59
            "extensions" => [".coffee"],
60
            "aliases" => ["CoffeeScript", "coffeescript", "coffee"],
61
            "mimetypes" => ["text/x-coffeescript", "text/coffeescript"]
62
        ], [
63
            "id" => "c",
64
            "extensions" => [".c", ".h"],
65
            "aliases" => ["C", "c"]
66
        ], [
67
            "id" => "cpp",
68
            "extensions" => [".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx"],
69
            "aliases" => ["C++", "Cpp", "cpp"]
70
        ], [
71
            "id" => "csharp",
72
            "extensions" => [".cs", ".csx", ".cake"],
73
            "aliases" => ["C#", "csharp"]
74
        ], [
75
            "id" => "csp",
76
            "extensions" => [],
77
            "aliases" => ["CSP", "csp"]
78
        ], [
79
            "id" => "css",
80
            "extensions" => [".css"],
81
            "aliases" => ["CSS", "css"],
82
            "mimetypes" => ["text/css"]
83
        ], [
84
            "id" => "dockerfile",
85
            "extensions" => [".dockerfile"],
86
            "filenames" => ["Dockerfile"],
87
            "aliases" => ["Dockerfile"]
88
        ], [
89
            "id" => "fsharp",
90
            "extensions" => [".fs", ".fsi", ".ml", ".mli", ".fsx", ".fsscript"],
91
            "aliases" => ["F#", "FSharp", "fsharp"]
92
        ], [
93
            "id" => "go",
94
            "extensions" => [".go"],
95
            "aliases" => ["Go"]
96
        ], [
97
            "id" => "handlebars",
98
            "extensions" => [".handlebars", ".hbs"],
99
            "aliases" => ["Handlebars", "handlebars"],
100
            "mimetypes" => ["text/x-handlebars-template"]
101
        ], [
102
            "id" => "html",
103
            "extensions" => [".html", ".htm", ".shtml", ".xhtml", ".mdoc", ".jsp", ".asp", ".aspx", ".jshtm"],
104
            "aliases" => ["HTML", "htm", "html", "xhtml"],
105
            "mimetypes" => ["text/html", "text/x-jshtm", "text/template", "text/ng-template"]
106
        ], [
107
            "id" => "ini",
108
            "extensions" => [".ini", ".properties", ".gitconfig"],
109
            "filenames" => ["config", ".gitattributes", ".gitconfig", ".editorconfig"],
110
            "aliases" => ["Ini", "ini"]
111
        ], [
112
            "id" => "java",
113
            "extensions" => [".java", ".jav"],
114
            "aliases" => ["Java", "java"],
115
            "mimetypes" => ["text/x-java-source", "text/x-java"]
116
        ], [
117
            "id" => "javascript",
118
            "extensions" => [".js", ".es6", ".jsx"],
119
            "firstLine" => "^#!.*\\bnode",
120
            "filenames" => ["jakefile"],
121
            "aliases" => ["JavaScript", "javascript", "js"],
122
            "mimetypes" => ["text/javascript"]
123
        ], [
124
            "id" => "less",
125
            "extensions" => [".less"],
126
            "aliases" => ["Less", "less"],
127
            "mimetypes" => ["text/x-less", "text/less"]
128
        ], [
129
            "id" => "lua",
130
            "extensions" => [".lua"],
131
            "aliases" => ["Lua", "lua"]
132
        ], [
133
            "id" => "markdown",
134
            "extensions" => [".md", ".markdown", ".mdown", ".mkdn", ".mkd", ".mdwn", ".mdtxt", ".mdtext"],
135
            "aliases" => ["Markdown", "markdown"]
136
        ], [
137
            "id" => "msdax",
138
            "extensions" => [".dax", ".msdax"],
139
            "aliases" => ["DAX", "MSDAX"]
140
        ], [
141
            "id" => "mysql",
142
            "extensions" => [],
143
            "aliases" => ["MySQL", "mysql"]
144
        ], [
145
            "id" => "objective-c",
146
            "extensions" => [".m"],
147
            "aliases" => ["Objective-C"]
148
        ], [
149
            "id" => "pgsql",
150
            "extensions" => [],
151
            "aliases" => ["PostgreSQL", "postgres", "pg", "postgre"]
152
        ], [
153
            "id" => "php",
154
            "extensions" => [".php", ".php4", ".php5", ".phtml", ".ctp"],
155
            "aliases" => ["PHP", "php"],
156
            "mimetypes" => ["application/x-php"]
157
        ], [
158
            "id" => "postiats",
159
            "extensions" => [".dats", ".sats", ".hats"],
160
            "aliases" => ["ATS", "ATS/Postiats"]
161
        ], [
162
            "id" => "powerquery",
163
            "extensions" => [".pq", ".pqm"],
164
            "aliases" => ["PQ", "M", "Power Query", "Power Query M"]
165
        ], [
166
            "id" => "powershell",
167
            "extensions" => [".ps1", ".psm1", ".psd1"],
168
            "aliases" => ["PowerShell", "powershell", "ps", "ps1"]
169
        ], [
170
            "id" => "pug",
171
            "extensions" => [".jade", ".pug"],
172
            "aliases" => ["Pug", "Jade", "jade"]
173
        ], [
174
            "id" => "python",
175
            "extensions" => [".py", ".rpy", ".pyw", ".cpy", ".gyp", ".gypi"],
176
            "aliases" => ["Python", "py"],
177
            "firstLine" => "^#!/.*\\bpython[0-9.-]*\\b"
178
        ], [
179
            "id" => "r",
180
            "extensions" => [".r", ".rhistory", ".rprofile", ".rt"],
181
            "aliases" => ["R", "r"]
182
        ], [
183
            "id" => "razor",
184
            "extensions" => [".cshtml"],
185
            "aliases" => ["Razor", "razor"],
186
            "mimetypes" => ["text/x-cshtml"]
187
        ], [
188
            "id" => "redis",
189
            "extensions" => [".redis"],
190
            "aliases" => ["redis"]
191
        ], [
192
            "id" => "redshift",
193
            "extensions" => [],
194
            "aliases" => ["Redshift", "redshift"]
195
        ], [
196
            "id" => "ruby",
197
            "extensions" => [".rb", ".rbx", ".rjs", ".gemspec", ".pp"],
198
            "filenames" => ["rakefile"],
199
            "aliases" => ["Ruby", "rb"]
200
        ], [
201
            "id" => "rust",
202
            "extensions" => [".rs", ".rlib"],
203
            "aliases" => ["Rust", "rust"]
204
        ], [
205
            "id" => "sb",
206
            "extensions" => [".sb"],
207
            "aliases" => ["Small Basic", "sb"]
208
        ], [
209
            "id" => "scss",
210
            "extensions" => [".scss"],
211
            "aliases" => ["Sass", "sass", "scss"],
212
            "mimetypes" => ["text/x-scss", "text/scss"]
213
        ], [
214
            "id" => "sol",
215
            "extensions" => [".sol"],
216
            "aliases" => ["sol", "solidity", "Solidity"]
217
        ], [
218
            "id" => "sql",
219
            "extensions" => [".sql"],
220
            "aliases" => ["SQL"]
221
        ], [
222
            "id" => "st",
223
            "extensions" => [".st", ".iecst", ".iecplc", ".lc3lib"],
224
            "aliases" => ["StructuredText", "scl", "stl"]
225
        ], [
226
            "id" => "swift",
227
            "aliases" => ["Swift", "swift"],
228
            "extensions" => [".swift"],
229
            "mimetypes" => ["text/swift"]
230
        ], [
231
            "id" => "typescript",
232
            "extensions" => [".ts", ".tsx"],
233
            "aliases" => ["TypeScript", "ts", "typescript"],
234
            "mimetypes" => ["text/typescript"]
235
        ], [
236
            "id" => "vb",
237
            "extensions" => [".vb"],
238
            "aliases" => ["Visual Basic", "vb"]
239
        ], [
240
            "id" => "xml",
241
            "extensions" => [".xml", ".dtd", ".ascx", ".csproj", ".config", ".wxi", ".wxl", ".wxs", ".xaml", ".svg", ".svgz"],
242
            "firstLine" => "(\\<\\?xml.*)|(\\<svg)|(\\<\\!doctype\\s+svg)",
243
            "aliases" => ["XML", "xml"],
244
            "mimetypes" => ["text/xml", "application/xml", "application/xaml+xml", "application/xml-dtd"]
245
        ], [
246
            "id" => "yaml",
247
            "extensions" => [".yaml", ".yml"],
248
            "aliases" => ["YAML", "yaml", "YML", "yml"],
249
            "mimetypes" => ["application/x-yaml"]
250
        ], [
251
            "id" => "scheme",
252
            "extensions" => [".scm", ".ss", ".sch", ".rkt"],
253
            "aliases" => ["scheme", "Scheme"]
254
        ], [
255
            "id" => "clojure",
256
            "extensions" => [".clj", ".clojure"],
257
            "aliases" => ["clojure", "Clojure"]
258
        ], [
259
            "id" => "shell",
260
            "extensions" => [".sh", ".bash"],
261
            "aliases" => ["Shell", "sh"]
262
        ], [
263
            "id" => "perl",
264
            "extensions" => [".pl"],
265
            "aliases" => ["Perl", "pl"]
266
        ], [
267
            "id" => "azcli",
268
            "extensions" => [".azcli"],
269
            "aliases" => ["Azure CLI", "azcli"]
270
        ], [
271
            "id" => "apex",
272
            "extensions" => [".cls"],
273
            "aliases" => ["Apex", "apex"],
274
            "mimetypes" => ["text/x-apex-source", "text/x-apex"]
275
        ]];
276
        foreach ($tempLangConfig as $t) {
277
            $this->langConfig[$t["id"]]=$t;
278
        }
279
    }
280
281
    public function insert($sub)
282
    {
283
        if (strlen($sub['verdict'])==0) {
284
            $sub['verdict']="Judge Error";
285
        }
286
287
        $sid=DB::table($this->tableName)->insertGetId([
288
            'time' => $sub['time'],
289
            'verdict' => $sub['verdict'],
290
            'solution' => $sub['solution'],
291
            'language' => $sub['language'],
292
            'submission_date' => $sub['submission_date'],
293
            'memory' => $sub['memory'],
294
            'uid' => $sub['uid'],
295
            'pid' => $sub['pid'],
296
            'cid' => $sub['cid'],
297
            'color' => $this->colorScheme[$sub['verdict']],
298
            'remote_id'=>$sub['remote_id'],
299
            'compile_info'=>"",
300
            'coid'=>$sub['coid'],
301
            'score'=>$sub['score']
302
        ]);
303
304
        return $sid;
305
    }
306
307
    public function basic($sid)
308
    {
309
        return DB::table($this->tableName)->where(['sid'=>$sid])->first();
310
    }
311
312
    public function getJudgeStatus($sid, $uid)
313
    {
314
        $status=$this->basic($sid);
315
        if (empty($status)) {
316
            return [];
317
        }
318
        if ($status["share"]==1 && $status["cid"]) {
319
            $end_time=strtotime(DB::table("contest")->where(["cid"=>$status["cid"]])->select("end_time")->first()["end_time"]);
320
            if (time()<$end_time) {
321
                $status["solution"]=null;
322
            }
323
        }
324
        if ($status["share"]==0 && $status["uid"]!=$uid) {
325
            $status["solution"]=null;
326
        }
327
        $compilerModel=new CompilerModel();
328
        $status["lang"]=$compilerModel->detail($status["coid"])["lang"];
329
        $status["owner"]=$uid==$status["uid"];
330
        return $status;
331
    }
332
333
    public function downloadCode($sid, $uid)
334
    {
335
        $status=DB::table($this->tableName)->where(['sid'=>$sid])->first();
336
        if (empty($status) || ($status["share"]==0 && $status["uid"]!=$uid)) {
337
            return [];
338
        }
339
        $lang=DB::table("compiler")->where(['coid'=>$status["coid"]])->first()["lang"];
340
        $curLang=isset($this->langConfig[$lang]) ? $this->langConfig[$lang] : $this->langConfig["plaintext"];
341
        return [
342
            "content"=>$status["solution"],
343
            "name"=>$status["submission_date"].$curLang["extensions"][0],
344
        ];
345
    }
346
347
    public function getProblemStatus($pid, $uid, $cid=null)
348
    {
349
        if ($cid) {
350
            $end_time=strtotime(DB::table("contest")->where(["cid"=>$cid])->select("end_time")->first()["end_time"]);
351
            // Get the very first AC record
352
            $ac=DB::table($this->tableName)->where([
353
                'pid'=>$pid,
354
                'uid'=>$uid,
355
                'cid'=>$cid,
356
                'verdict'=>'Accepted'
357
            ])->where("submission_date", "<", $end_time)->orderBy('submission_date', 'desc')->first();
358
            if (empty($ac)) {
359
                $pac=DB::table($this->tableName)->where([
360
                    'pid'=>$pid,
361
                    'uid'=>$uid,
362
                    'cid'=>$cid,
363
                    'verdict'=>'Partially Accepted'
364
                ])->where("submission_date", "<", $end_time)->orderBy('submission_date', 'desc')->first();
365
                return empty($pac) ? DB::table($this->tableName)->where(['pid'=>$pid, 'uid'=>$uid, 'cid'=>$cid])->where("submission_date", "<", $end_time)->orderBy('submission_date', 'desc')->first() : $pac;
366
            } else {
367
                return $ac;
368
            }
369
        } else {
370
            $ac=DB::table($this->tableName)->where([
371
                'pid'=>$pid,
372
                'uid'=>$uid,
373
                'cid'=>$cid,
374
                'verdict'=>'Accepted'
375
            ])->orderBy('submission_date', 'desc')->first();
376
            return empty($ac) ? DB::table($this->tableName)->where(['pid'=>$pid, 'uid'=>$uid, 'cid'=>$cid])->orderBy('submission_date', 'desc')->first() : $ac;
377
        }
378
    }
379
380
    public function getProblemSubmission($pid, $uid, $cid=null)
381
    {
382
        $statusList=DB::table($this->tableName)->where(['pid'=>$pid, 'uid'=>$uid, 'cid'=>$cid])->orderBy('submission_date', 'desc')->limit(10)->get()->all();
383
        return $statusList;
384
    }
385
386
    public function countSolution($s)
387
    {
388
        return DB::table($this->tableName)->where(['solution'=>$s])->count();
389
    }
390
391
    public function getEarliestSubmission($oid)
392
    {
393
        return DB::table($this->tableName)  ->join('problem', 'problem.pid', '=', 'submission.pid')
394
                                            ->select("sid", "OJ as oid", "remote_id", "cid", "jid")
395
                                            ->where(['verdict'=>'Waiting', 'OJ'=>$oid])
396
                                            ->orderBy("sid", "asc")
397
                                            ->first();
398
    }
399
400
    public function countEarliestWaitingSubmission($oid)
401
    {
402
        $early_sid=$this->getEarliestSubmission($oid);
403
        if ($early_sid==null) {
404
            return 0;
405
        }
406
        $early_sid=$early_sid["sid"];
407
        return DB::table($this->tableName)  ->join('problem', 'problem.pid', '=', 'submission.pid')
408
                                            ->where(['OJ'=>$oid])
409
                                            ->where("sid", ">=", $early_sid)
410
                                            ->count();
411
    }
412
413
414
    public function getWaitingSubmission()
415
    {
416
        $ret=DB::table($this->tableName)    ->join('problem', 'problem.pid', '=', 'submission.pid')
417
                                            ->select("sid", "OJ as oid", "remote_id", "cid", "jid", "vcid", "problem.pid as pid")
418
                                            ->where(['verdict'=>'Waiting'])
419
                                            ->get()
420
                                            ->all();
421
        foreach($ret as &$r){
422
            $r["ocode"]=DB::table("oj")->where(["oid"=>$r["oid"]])->first()["ocode"];
423
        }
424
        return $ret;
425
    }
426
427
    public function countWaitingSubmission($oid)
428
    {
429
        return DB::table($this->tableName)  ->join('problem', 'problem.pid', '=', 'submission.pid')
430
                                            ->where(['verdict'=>'Waiting', 'OJ'=>$oid])
431
                                            ->count();
432
    }
433
434
    public function updateSubmission($sid, $sub)
435
    {
436
        if (isset($sub['verdict'])) {
437
            $sub["color"]=$this->colorScheme[$sub['verdict']];
438
        }
439
        $result = DB::table($this->tableName)->where(['sid'=>$sid])->update($sub);
440
        $contestModel = new ContestModel();
441
        $submission_info = DB::table($this->tableName) -> where(['sid'=>$sid]) -> get() -> first();
442
        if ($result==1 && $submission_info['cid'] && $contestModel->isContestRunning($submission_info['cid'])){
443
            $sub['pid'] = $submission_info['pid'];
444
            $sub['uid'] = $submission_info['uid'];
445
            $sub['cid'] = $submission_info['cid'];
446
            $sub['sid'] = $sid;
447
            $contestModel->updateContestRankTable($submission_info['cid'],$sub);
448
        }
449
        return $result;
450
    }
451
452
    public function formatSubmitTime($date)
453
    {
454
        $periods=["second", "minute", "hour", "day", "week", "month", "year", "decade"];
455
        $lengths=["60", "60", "24", "7", "4.35", "12", "10"];
456
457
        $now=time();
458
        $unix_date=strtotime($date);
459
460
        if (empty($unix_date)) {
461
            return "Bad date";
462
        }
463
464
        if ($now>$unix_date) {
465
            $difference=$now-$unix_date;
466
            $tense="ago";
467
        } else {
468
            $difference=$unix_date-$now;
469
            $tense="from now";
470
        }
471
472
        for ($j=0; $difference>=$lengths[$j] && $j<count($lengths)-1; $j++) {
473
            $difference/=$lengths[$j];
474
        }
475
476
        $difference=round($difference);
477
478
        if ($difference!=1) {
479
            $periods[$j].="s";
480
        }
481
482
        return "$difference $periods[$j] {$tense}";
483
    }
484
485
    public function getRecord($filter)
486
    {
487
        $paginator=DB::table("submission")->where([
488
            'cid'=>null
489
        ])->join(
490
            "users",
491
            "users.id",
492
            "=",
493
            "submission.uid"
494
        )->join(
495
            "problem",
496
            "problem.pid",
497
            "=",
498
            "submission.pid"
499
        )->select(
500
            "sid",
501
            "uid",
502
            "problem.pid as pid",
503
            "pcode",
504
            "name",
505
            "color",
506
            "verdict",
507
            "time",
508
            "memory",
509
            "language",
510
            "score",
511
            "submission_date",
512
            "share"
513
        )->orderBy(
514
            'submission_date',
515
            'desc'
516
        );
517
518
        if($filter["pcode"]){
519
            $paginator=$paginator->where(["pcode"=>$filter["pcode"]]);
520
        }
521
522
        if($filter["result"]){
523
            $paginator=$paginator->where(["verdict"=>$filter["result"]]);
524
        }
525
526
        if($filter["account"]){
527
            $paginator=$paginator->where(["name"=>$filter["account"]]);
528
        }
529
530
        $paginator=$paginator->paginate(50);
531
532
533
        $records=$paginator->all();
534
        foreach ($records as &$r) {
535
            $r["submission_date_parsed"]=$this->formatSubmitTime(date('Y-m-d H:i:s', $r["submission_date"]));
536
            $r["submission_date"]=date('Y-m-d H:i:s', $r["submission_date"]);
537
            $r["nick_name"]="";
538
        }
539
        return [
540
            "paginator"=>$paginator,
541
            "records"=>$records
542
        ];
543
    }
544
545
    public function share($sid, $uid)
546
    {
547
        $basic=DB::table($this->tableName)->where(['sid'=>$sid, 'uid'=>$uid])->first();
548
        if (empty($basic)) {
549
            return [];
550
        }
551
        DB::table($this->tableName)->where(['sid'=>$sid])->update([
552
            "share"=>$basic["share"] ? 0 : 1
553
        ]);
554
        return [
555
            "share"=>$basic["share"] ? 0 : 1
556
        ];
557
    }
558
559
    public function sharePB($sid, $uid)
560
    {
561
        $basic=DB::table($this->tableName)->where(['sid'=>$sid, 'uid'=>$uid])->first();
562
        $problem=DB::table("problem")->where(['pid'=>$basic["pid"]])->first();
563
        $compiler=DB::table("compiler")->where(['coid'=>$basic["coid"]])->first();
564
        if (empty($basic)) {
565
            return [];
566
        }
567
        $pastebinModel=new PastebinModel();
568
        $ret=$pastebinModel->generate([
569
            "syntax"=>$compiler["lang"],
570
            "expiration"=>0,
571
            "content"=>$basic["solution"],
572
            "title"=>$problem["pcode"]." - ".$basic["verdict"],
573
            "uid"=>$uid
574
        ]);
575
576
        if (is_null($ret)) {
577
            return [];
578
        } else {
579
            return [
580
                "code" => $ret
581
            ];
582
        }
583
    }
584
}
585