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.TemplateResponseis 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 –
Contestwhere the problem is going to be attached (or is already attached); may beNone.existing_problem –
Problemto 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
ProblemPackageinstance from a given package file.
- choose_backend(path, original_filename=None)[source]¶
Returns the dotted name of a
ProblemPackageBackendsuitable 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
Probleminstance using a package file represented by aProblemPackage.- Used
envkeys: package_id: id of theProblemPackageinstance 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
envkeys are produced:job_id: theCelerytask idproblem_id: id of theProblemPackageinstance, 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
Probleminstances.- 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
Trueif 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
Problemor 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
envkeys: package_id: an id of theProblemPackageinstance with the package file to unpack.- Produced
envkeys: problem_id: an id of theProbleminstance 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
Problemto be changed.If
None, a newProblemis created.
Returns a
Probleminstance.
- pack(problem)[source]¶
Creates a package from problem, returns a
django.http.HttpResponseinstance.Should raise
NotImplementedErrorif 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
SinolPackageto unpack andSinolPackageCreatorto 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
Trueif 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
Problemor 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
envkeys: package_id: an id of theProblemPackageinstance with the package file to unpack.- Produced
envkeys: problem_id: an id of theProbleminstance representing the created or modified problem.
- Used
- pack(problem)[source]¶
Creates a package from problem, returns a
django.http.HttpResponseinstance.Should raise
NotImplementedErrorif 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.