Problem uploading¶
Problem sources¶
Let us consider the most typical use case.
A contest admin decides to upload a new problem or modify an existing one.
Depending on the OIOIOI installation there could be many sources of the
problem. Such a source should inherit from the
ProblemSource
.
- class oioioi.problems.problem_sources.ProblemSource[source]¶
- view(request, contest, existing_problem=None)[source]¶
Renders the view where the user can upload the file or point out where to get the problem from.
If the request method is
GET
, it should return rendered HTML, which will be injected in an appropriate div element.TemplateResponse
is fine, too.If the request method is
POST
, it should start the unpacking process. If no errors occur, it should returnHttpResponseRedirect
(e.g. to a view with problem packages queued for processing).- Parameters:
request – Django request
contest –
Contest
where the problem is going to be attached (or is already attached); may beNone
.existing_problem –
Problem
to update (if problem update was requested)
The complete list of available problem sources
can be specified in the
deployment/settings.py
file under the PROBLEM_SOURCES
name. The listed
problem sources
will be displayed as tabs of the problem upload view,
provided that their
is_available()
method
returns True
.
Developers are expected to implement their custom problem sources
by
inheriting from the above-mentioned class, such code should be preferably
placed in a problem_sources
module in a given app.
Package sources¶
The most basic problem source is a
PackageSource
. It may be used when
all the data necessary for creating a problem may be uploaded in a single file.
- class oioioi.problems.problem_sources.PackageSource[source]¶
- make_form(request, contest, existing_problem=None)[source]¶
Creates a form, which can be later filled in by the user with information necessary for obtaining the problem package.
If the request method is
POST
, then the form should be filled with its data.
- create_package_instance(user, contest, path, existing_problem=None, original_filename=None)[source]¶
Creates a
ProblemPackage
instance from a given package file.
- choose_backend(path, original_filename=None)[source]¶
Returns the dotted name of a
ProblemPackageBackend
suitable for processing a given package.This function is called when an unpacking environment is created, i.e. from
create_env()
.
- create_env(user, contest, path, package, form, round_id=None, visibility='FR', existing_problem=None, original_filename=None)[source]¶
Creates an environment which will be later passed to
unpackmgr_job()
.
Since every instance of PackageSource
is associated with a file of some kind, the file, together with some additional
data, is represented as a separate model, namely the
ProblemPackage
. Such a design is quite natural
when combined with the unpacking manager
pipeline, which is described
below.
Unpacking manager¶
When a user uploads a problem via the
PackageSource
, an unpacking
environment is created and passed to a new Celery task, that
is to unpackmgr_job()
.
- oioioi.problems.unpackmgr.unpackmgr_job(env)[source]¶
Creates (or modifies) a
Problem
instance using a package file represented by aProblemPackage
.- Used
env
keys: package_id
: id of theProblemPackage
instance to processbackend_name
: problem package backend (dotted name) to be used for unpackingpost_upload_handlers
: a list of handler functions to be called after the new problem is created
Before the handlers are called, the following
env
keys are produced:job_id
: theCelery
task idproblem_id
: id of theProblemPackage
instance, which was created or modified- Used
The above-mentioned post-upload handlers
are functions, which accept an
environment (a dictionary) as their only argument and return the modified
environment. Before the handlers are called,
the following new env
keys are produced:
job_id
: the Celery
task id
problem_id`: id of the
ProblemPackage
instance, which was created or modified
Normally, when you add a new Problem
,
you want to attach it to a specific Round
of a given Contest
. That is why the default
implementation of PackageSource
specifies one post-upload handler
, namely
create_problem_instance()
.
Problem package backends¶
The PackageSource
class
defines how problem data should be uploaded by
a user, which keys should be present in the unpacking environment and
what should be done after the new Problem
is created. However, it is not involved in the actual unpacking and processing
of the uploaded file.
It only chooses an appropriate
ProblemPackageBackend
(choose_backend()
) and
delegates this responsibility to it.
oioioi.problems.package¶
This module contains a problem package backend interface. You should
create a package.py
file in your new app and implement your package
backend (inheriting from
ProblemPackageBackend
)
whenever you introduce a new problem package format.
- exception oioioi.problems.package.ProblemPackageError[source]¶
A generic exception to be used by or subclassed by backends.
- class oioioi.problems.package.ProblemPackageBackend(*args, **kwargs)[source]¶
A class which manages problem packages.
The main functionality is extracting archives with problem statements, data, model solutions etc. and building
Problem
instances.- identify(path, original_filename=None)[source]¶
Checks if the backend is suitable for processing the specified problem package.
- Parameters:
path – a path to the processed problem package
original_filename – the name of the package specified by the
uploading user.
Returns
True
if the backend can handle the specified problem package file.
- get_short_name(path, original_filename=None)[source]¶
Returns the problem’s short name.
- Parameters:
path – a path to the processed problem package
original_filename – the name of the package specified by the
uploading user.
- unpack(env)[source]¶
Processes a package, creating a new
Problem
or updating an existing one.This function will be called either from
unpackmgr_job()
(Celery task) or fromsimple_unpack()
(e.g. when a problem is added from a command line).- Used
env
keys: package_id
: an id of theProblemPackage
instance with the package file to unpack.- Produced
env
keys: problem_id
: an id of theProblem
instance representing the created or modified problem.
- Used
- simple_unpack(filename, existing_problem=None)[source]¶
This function may be used for unpacking outside unpackmgr.
- Parameters:
filename – a path to the problem package file
existing_problem –
an instance of
Problem
to be changed.If
None
, a newProblem
is created.
Returns a
Problem
instance.
- pack(problem)[source]¶
Creates a package from problem, returns a
django.http.HttpResponse
instance.Should raise
NotImplementedError
if creating packages is not supported.
- mixins = []¶
A list of mixins to be automatically mixed in to all instances of the particular class and its subclasses.
- oioioi.problems.package.backend_for_package(filename, original_filename=None)[source]¶
Finds a backend suitable for unpacking the given package and returns its dotted name.
- Parameters:
filename – a path to the processed problem package
original_filename – the name of the package specified by the
uploading user.
oioioi.sinolpack.package¶
Provides ProblemPackageBackend
implementation to deal with
Sinol packages - standardized archives with problem data.
Sinolpack is OIOIOI standard problem package format.
The detailed archive content description can be found here:
https://sio2project.mimuw.edu.pl/display/DOC/Preparing+Task+Packages.
- class oioioi.sinolpack.package.SinolPackageCreator(problem)[source]¶
Responsible for packing SinolPackages.
- class oioioi.sinolpack.package.SinolPackageBackend(*args, **kwargs)[source]¶
Backend that use
SinolPackage
to unpack andSinolPackageCreator
to pack sinol packages.- identify(path, original_filename=None)[source]¶
Checks if the backend is suitable for processing the specified problem package.
- Parameters:
path – a path to the processed problem package
original_filename – the name of the package specified by the
uploading user.
Returns
True
if the backend can handle the specified problem package file.
- get_short_name(path, original_filename=None)[source]¶
Returns the problem’s short name.
- Parameters:
path – a path to the processed problem package
original_filename – the name of the package specified by the
uploading user.
- unpack(env)[source]¶
Processes a package, creating a new
Problem
or updating an existing one.This function will be called either from
unpackmgr_job()
(Celery task) or fromsimple_unpack()
(e.g. when a problem is added from a command line).- Used
env
keys: package_id
: an id of theProblemPackage
instance with the package file to unpack.- Produced
env
keys: problem_id
: an id of theProblem
instance representing the created or modified problem.
- Used
- pack(problem)[source]¶
Creates a package from problem, returns a
django.http.HttpResponse
instance.Should raise
NotImplementedError
if creating packages is not supported.
- mixins = []¶
A list of mixins to be automatically mixed in to all instances of the particular class and its subclasses.