#!/usr/bin/perl -w use v5.14; use Gruntmaster::Data; use IO::Prompter [ -style => 'bold', '-stdio', '-verbatim' ]; use File::Slurp qw/read_file/; use Term::ANSIColor qw/RED RESET/; use Getopt::Long qw/:config require_order/; ################################################## my $contest; sub cmd_help{ exec perldoc => $0 } sub prompt_file{ my ($meta, $name, $prefix) = @_; my $filename = prompt '$prefix filename', -complete => 'filenames'; $meta->{files}{$name}{content} = read_file $filename; $meta->{files}{$name}{format} = prompt '$prefix format', -menu => [qw/C CPP MONO JAVA PASCAL PERL PYTHON/]; $meta->{files}{$name}{name} = prompt "$prefix filename [$filename]", -default => $filename; } sub cmd_add{ my $id = shift; my $name = prompt 'Problem name'; my $private = prompt('Private?', '-yn') eq 'y'; my $author = prompt 'Problem author (full name)'; my $owner = prompt 'Problem owner (username)'; my $level = prompt 'Problem level', -menu => "beginner\neasy\nmedium\nhard"; my $statement = read_file prompt 'File with problem statement', -complete => 'filenames'; my %meta; my $generator = prompt 'Generator', -menu => "File\nRun\nUndef"; my $runner = prompt 'Runner', -menu => "File\nVerifier\nInteractive"; my $judge = prompt 'Judge', -menu => "Absolute\nPoints"; my $testcnt = prompt 'Test count', '-i'; my $timeout = prompt 'Time limit (seconds)', '-n'; my $olimit = prompt 'Output limit (bytes)', '-i'; say 'Memory limits are broken, so I won\'t ask you for one'; prompt_file \%meta, gen => '[Generator::Run] Generator' if $generator eq 'Run'; if ($runner eq 'File') { $meta{tests}[$_ - 1] = prompt "[Runner::File] Score for test ${_} [10]", '-i', -default => 10 for 1 .. $testcnt; } prompt_file \%meta, ver => '[Runner::Verifier] Verifier' if $runner eq 'Verifier'; if ($runner eq 'Interactive') { say RED, 'WARNING: Runner::Interactive is experimental', RESET; prompt_file \%meta, int => '[Runner::Interactive] Interactive verifier'; } insert_problem $id => ( name => $name, level => $level, statement => $statement, author => $author, owner => $owner, generator => $generator, runner => $runner, judge => $judge, testcnt => $testcnt, ($private ? (private => $private) : ()), (defined $timeout ? (timeout => $timeout) : ()), (defined $olimit ? (olimit => $olimit) : ())); set_problem_meta $id => \%meta; PUBLISH genpage => $contest ? "ct/$contest/pb/index.html" : 'pb/index.html'; PUBLISH genpage => $contest ? "ct/$contest/pb/$id.html" : "pb/$id.html"; } sub cmd_set{ my $file; GetOptions ( 'file!' => \$file ); my ($id, %values) = @ARGV; %values = map { $_ => scalar read_file $values{$_} } keys %values if $file; edit_problem $id => %values; PUBLISH genpage => 'pb/index.html'; PUBLISH genpage => "pb/$id.html"; } sub cmd_list{ local $, = "\n"; say problems; } sub cmd_rm{ remove_problem shift; PUBLISH genpage => $contest ? "ct/$contest/pb/index.html" : 'pb/index.html'; } sub cmd_show{ local $_ = shift or goto &cmd_list; } ################################################## GetOptions ( 'contest=s' => \$contest ); local $Gruntmaster::Data::contest = $contest; my $cmd = 'cmd_' . shift; cmd_help unless exists $main::{$cmd}; no strict 'refs'; $cmd->(@ARGV) if exists $main::{$cmd}; 1; __END__ =encoding utf-8 =head1 NAME gruntmaster-problem - shell interface to Gruntmaster 6000 problems =head1 SYNOPSIS gruntmaster-problem [--contest=mycontest] add problem_id gruntmaster-problem [--contest=mycontest] list gruntmaster-problem [--contest=mycontest] rm problem_id gruntmaster-problem [--contest=mycontest] show problem_id gruntmaster-problem [--contest=mycontest] set [--file] problem_id key value =head1 DESCRIPTION gruntmaster-problem is a tool for managing problems. Select the contest with the optional argument I<--contest>. =over =item B Prints the list of problems in the selected contest. =item B I Prints detailed information about problem I. =item B I Adds a new problem with id I. =item B I Removes the problem with id I. =item B I I I Sets the I configuration option of problem I to I. =item B --file I I I Sets the I configuration option of problem I to the contents of the file I. =back =head1 AUTHOR Marius Gavrilescu Emarius@ieval.roE =head1 COPYRIGHT AND LICENSE Copyright (C) 2014 by Marius Gavrilescu This library is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. =cut