Bump version and update Changes
[gruntmaster-data.git] / lib / Gruntmaster / Data.pm
CommitLineData
4ed3f8e7 1use utf8;
bbf8209c 2package Gruntmaster::Data;
4ed3f8e7
MG
3
4# Created by DBIx::Class::Schema::Loader
5# DO NOT MODIFY THE FIRST PART OF THIS FILE
6
7use strict;
bbf8209c 8use warnings;
014ee8a6 9
4ed3f8e7
MG
10use base 'DBIx::Class::Schema';
11
12__PACKAGE__->load_namespaces;
014ee8a6 13
f7386aab 14
4ed3f8e7
MG
15# Created by DBIx::Class::Schema::Loader v0.07039 @ 2014-03-05 13:11:39
16# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:dAEmtAexvUaNXLgYz2rNEg
17
26d60269 18our $VERSION = '5999.000_007';
4ed3f8e7
MG
19
20use Lingua::EN::Inflect qw/PL_N/;
de625c9b 21use JSON qw/decode_json/;
4ed3f8e7 22use Sub::Name qw/subname/;
014ee8a6 23
de625c9b
MG
24use constant PROBLEM_PUBLIC_COLUMNS => [qw/id author writer level name owner private statement timeout olimit value/];
25use constant USER_PUBLIC_COLUMNS => [qw/id admin name town university level/];
26use constant JOBS_PER_PAGE => 10;
27
014ee8a6 28sub dynsub{
fb6a4e3d 29 our ($name, $sub) = @_;
014ee8a6 30 no strict 'refs';
fb6a4e3d 31 *$name = subname $name => $sub
014ee8a6
MG
32}
33
34BEGIN {
4ed3f8e7
MG
35 for my $rs (qw/contest contest_problem job open problem user/) {
36 my $rsname = ucfirst $rs;
37 $rsname =~ s/_([a-z])/\u$1/g;
38 dynsub PL_N($rs) => sub { $_[0]->resultset($rsname) };
39 dynsub $rs => sub { $_[0]->resultset($rsname)->find($_[1]) };
014ee8a6
MG
40 }
41}
42
de625c9b
MG
43sub user_list {
44 my $rs = $_[0]->users->search(undef, {order_by => 'name', columns => USER_PUBLIC_COLUMNS});
45 [ map +{ $_->get_columns }, $rs->all ]
46}
47
48sub user_entry {
49 my ($self, $id) = @_;
50 +{ $self->users->find($id, {columns => USER_PUBLIC_COLUMNS})->get_columns }
51}
52
53sub problem_list {
54 my ($self, %args) = @_;
55 my $rs = $self->problems->search(undef, {order_by => 'me.name', columns => PROBLEM_PUBLIC_COLUMNS, prefetch => 'owner'});
56 $rs = $rs->search({-or => ['contest_problems.contest' => undef, 'contest.stop' => {'<=', time}], 'me.private' => 0}, {join => {'contest_problems' => 'contest'}, distinct => 1}) unless $args{contest};
57 $rs = $rs->search({'contest_problems.contest' => $args{contest}}, {join => 'contest_problems'}) if $args{contest};
58 $rs = $rs->search({'me.owner' => $args{owner}}) if $args{owner};
59 my %params;
60 $params{contest} = $args{contest} if $args{contest};
61 for ($rs->all) {
62 $params{$_->level} //= [];
63 push $params{$_->level}, {$_->get_columns, owner_name => $_->owner->name} ;
64 }
65 \%params
66}
67
68sub problem_entry {
69 my ($self, $id, $contest, $user) = @_;
70 my $pb = $self->problems->find($id, {columns => PROBLEM_PUBLIC_COLUMNS, prefetch => 'owner'});
71 my $running = $contest && $self->contest($contest)->is_running;
72 eval {
73 $self->opens->create({
74 contest => $contest,
75 problem => $id,
76 owner => $user,
77 time => time,
78 })
79 } if $running;
80 +{ $pb->get_columns, owner_name => $pb->owner->name, cansubmit => $contest ? $running : 1 }
81}
82
83sub contest_list {
84 my ($self, %args) = @_;
85 my $rs = $self->contests->search(undef, {order_by => {-desc => 'start'}, prefetch => 'owner'});
86 $rs = $rs->search({owner => $args{owner}}) if $args{owner};
87 my %params;
88 for ($rs->all) {
89 my $state = $_->is_pending ? 'pending' : $_->is_running ? 'running' : 'finished';
90 $params{$state} //= [];
91 push $params{$state}, { $_->get_columns, started => !$_->is_pending, owner_name => $_->owner->name };
92 }
93 \%params
94}
95
96sub contest_entry {
97 my ($self, $id) = @_;
98 my $ct = $self->contest($id);
99 +{ $ct->get_columns, started => !$ct->is_pending, owner_name => $ct->owner->name }
100}
101
102sub job_list {
103 my ($self, %args) = @_;
104 $args{page} //= 1;
105 my $rs = $self->jobs->search(undef, {order_by => {-desc => 'me.id'}, prefetch => ['problem', 'owner'], rows => JOBS_PER_PAGE, offset => ($args{page} - 1) * JOBS_PER_PAGE});
106 $rs = $rs->search({owner => $args{owner}}) if $args{owner};
107 $rs = $rs->search({contest => $args{contest}}) if $args{contest};
108 $rs = $rs->search({problem => $args{problem}}) if $args{problem};
109 [map {
110 my %params = $_->get_columns;
111 $params{owner_name} = $_->owner->name;
112 $params{problem_name} = $_->problem->name;
113 $params{results} &&= decode_json $params{results};
114 $params{size} = length $params{source};
115 delete $params{source};
116 \%params
117 } $rs->all]
118}
119
120sub job_entry {
121 my ($self, $id) = @_;
122 my $job = $self->jobs->find($id, {prefetch => ['problem', 'owner']});
123 my %params = $job->get_columns;
124 $params{owner_name} = $job->owner->name;
125 $params{problem_name} = $job->problem->name;
126 $params{results} &&= decode_json $params{results};
127 $params{size} = length $params{source};
128 delete $params{source};
129 \%params
130}
131
f7386aab 1321;
4a8747ef
MG
133
134__END__
135
136=encoding utf-8
137
138=head1 NAME
139
140Gruntmaster::Data - Gruntmaster 6000 Online Judge -- database interface and tools
141
142=head1 SYNOPSIS
143
144 my $db = Gruntmaster::Data->connect('dbi:Pg:');
cbb36c78
MG
145
146 my $problem = $db->problem('my_problem');
147 $problem->update({timeout => 2.5}); # Set time limit to 2.5 seconds
148 $problem->rerun; # And rerun all jobs for this problem
149
150 # ...
151
152 my $contest = $db->contests->create({ # Create a new contest
153 id => 'my_contest',
154 name => 'My Awesome Contest',
155 start => time + 100,
156 end => time + 1900,
157 });
158 $db->contest_problems->create({ # Add a problem to the contest
159 contest => 'my_contest',
160 problem => 'my_problem',
161 });
162
163 say 'The contest has not started yet' if $contest->is_pending;
164
165 # ...
166
167 my @jobs = $db->jobs->search({contest => 'my_contest', owner => 'MGV'})->all;
168 $_->rerun for @jobs; # Rerun all jobs sent by MGV in my_contest
4a8747ef
MG
169
170=head1 DESCRIPTION
171
cbb36c78
MG
172Gruntmaster::Data is the interface to the Gruntmaster 6000 database. Read the L<DBIx::Class> documentation for usage information.
173
174In addition to the typical DBIx::Class::Schema methods, this module contains several convenience methods:
175
176=over
177
178=item contests
179
180Equivalent to C<< $schema->resultset('Contest') >>
181
182=item contest_problems
183
184Equivalent to C<< $schema->resultset('ContestProblem') >>
185
186=item jobs
187
188Equivalent to C<< $schema->resultset('Job') >>
189
190=item problems
191
192Equivalent to C<< $schema->resultset('Problem') >>
193
194=item users
195
196Equivalent to C<< $schema->resultset('User') >>
197
198=item contest($id)
199
200Equivalent to C<< $schema->resultset('Contest')->find($id) >>
201
202=item job($id)
203
204Equivalent to C<< $schema->resultset('Job')->find($id) >>
205
206=item problem($id)
207
208Equivalent to C<< $schema->resultset('Problem')->find($id) >>
209
210=item user($id)
211
212Equivalent to C<< $schema->resultset('User')->find($id) >>
213
de625c9b
MG
214=item user_list
215
216Returns a list of users as an arrayref containing hashrefs.
217
218=item user_entry($id)
219
220Returns a hashref with information about the user $id.
221
222=item problem_list([%args])
223
224Returns a list of problems grouped by level. A hashref with levels as keys.
225
226Takes the following arguments:
227
228=over
229
230=item owner
231
232Only show problems owned by this user
233
234=item contest
235
236Only show problems in this contest
237
238=back
239
240=item problem_entry($id, [$contest, $user])
241
242Returns a hashref with information about the problem $id. If $contest and $user are present, problem open data is updated.
243
244=item contest_list([%args])
245
246Returns a list of contests grouped by state. A hashref with the following keys:
247
248=over
249
250=item pending
251
252An arrayref of hashrefs representing pending contests
253
254=item running
255
256An arrayref of hashrefs representing running contests
257
258=item finished
259
260An arrayref of hashrefs representing finished contests
261
262=back
263
264Takes the following arguments:
265
266=over
267
268=item owner
269
270Only show contests owned by this user.
271
272=back
273
274=item contest_entry($id)
275
276Returns a hashref with information about the contest $id.
277
278=item job_list([%args])
279
280Returns a list of jobs as an arrayref containing hashrefs. Takes the following arguments:
281
282=over
283
284=item owner
285
286Only show jobs submitted by this user.
287
288=item contest
289
290Only show jobs submitted in this contest.
291
292=item problem
293
294Only show jobs submitted for this problem.
295
296=item page
297
298Show this page of results. Defaults to 1. Pages have 10 entries, and the first page has the most recent jobs.
299
300=back
301
302=item job_entry($id)
303
304Returns a hashref with information about the job $id.
305
cbb36c78 306=back
4a8747ef
MG
307
308=head1 AUTHOR
309
310Marius Gavrilescu E<lt>marius@ieval.roE<gt>
311
312=head1 COPYRIGHT AND LICENSE
313
314Copyright (C) 2014 by Marius Gavrilescu
315
9d2e740e
MG
316This library is free software; you can redistribute it and/or modify
317it under the same terms as Perl itself, either Perl version 5.18.1 or,
318at your option, any later version of Perl 5 you may have available.
4a8747ef
MG
319
320
321=cut
This page took 0.030221 seconds and 4 git commands to generate.