URL = 'https://api.hera.dev/' if settings.HERA_URL is None else settings.HERA_URL
def get_auth(auth):
    def __init__(self, id, auth=None):
    def create(self, timeout, disk, owner='me', memory=128, whole_node=False, auth=None,
               async=False, webhook_url=None, webhook_secret=None, priority=None, priority_growth=None):
    def save_as_template(self, name=None):
    def execute(self, args, sync=False, chroot=True, shell=False,
                stderr_to_stdout=False, pty_size=None):
    def unpack(self, archive_type, archive, archive_size=None, compress_type='', target='/'):
    def wait(self):
    def kill(self):
    def action(self, type, **args):
    def __init__(self, resp, sync):
    def read_stdout(self):
    def read_stderr(self):
    def _read_stream(self, name):
    def __init__(self, id, auth=None, data=None):
    def change(self, public=None, name=None):
    def list(self, auth=None):
def response_raise(resp):
def filter_out_if_none(dict):
def new_disk(size):
def get_cluster(auth=None):
    def __init__(self, urls):
    def download(self):
    def upload(self, data):
    def upload_file(self, file_obj_or_name, size=None):
    def _upload(self, stream, size):
    def _make_connection(self, url):
    def __init__(self):
    def read_some(self):
    def read(self, n=2**64):
    def unread(self, data):
    def readline(self):
        def read(self, n=None):
        def write(self, data):
        def close(self, data):
        def read_some(self):
        def __init__(self, urls):
        def websocket_conn(self):
        def _unbuffered_read(self):
        def write(self, data):
        def close(self):
class Sandbox(object):
class Process(object):
class Template(object):
class ApiError(Exception):
class _StreamBase(object):
class _BufferedInputFileMixin(object):
    class Stream(_StreamBase):
    class Stream(_StreamBase, _BufferedInputFileMixin): class SubmitForm(forms.Form):
    solution = forms.FileField(label="Upload your solution")
    task = forms.ModelChoiceField(queryset=None, empty_label=None)

    def __init__(self, *args, **kwargs):
        contest = kwargs.pop('contest')
        super(SubmitForm, self).__init__(*args, **kwargs)
        self.fields['task'].queryset = Task.objects.filter(contest=contest)

    def clean(self):
        solution = self.cleaned_data['solution']
        max_solution_size = self.cleaned_data['task'].max_solution_size
        if solution._size > max_solution_size:
            error_message = 'You cannot upload files larger than %(max_size)s.'
            max_size = filesizeformat(max_solution_size)
            raise forms.ValidationError(_(error_message),
                                        params={'max_size': max_size},
                                        code='too_large_solution') class Submit(models.Model):
    submitter = models.ForeignKey(User)
    submitted = models.DateTimeField(auto_now_add=True)
    task = models.ForeignKey('contest.Task')
    solution = models.BinaryField()
    status = models.CharField(max_length=3,
                              choices=TestCase.STATUS_CHOICES)
    webhook_secret = models.CharField(
                        max_length=settings.WEBHOOK_SECRET_LENGTH)

    def __str__(self):
        return self.id

    def change_status(self, status):
        if status not in [choice[0] for choice in TestCase.STATUS_CHOICES]:
            raise ValueError("Invalid status")
        else:
            self.status = status
            self.save() class ContestForm(forms.ModelForm):
    class Meta:
        model = Contest
        fields = ['name', 'description'] class GroupForm(forms.ModelForm):
    class Meta:
        model = Group
        fields = ['name'] class NewsForm(forms.ModelForm):
    class Meta:
        model = News
        fields = ['title', 'description'] class TaskFetchForm(forms.Form):
    task = forms.ModelChoiceField(queryset=Task.objects.filter(parent=None),
                                  empty_label=None)

    open = forms.DateTimeField(initial=now)
    deadline = forms.DateTimeField(initial=(lambda: now() + timedelta(days=7)))
    close = forms.DateTimeField(initial=(lambda: now() + timedelta(days=14)))

    def clean(self):
        cleaned_data = super(TaskFetchForm, self).clean()

        date_open = cleaned_data.get('open')
        date_deadline = cleaned_data.get('deadline')
        date_close = cleaned_data.get('close')

        if not date_open < date_deadline < date_close:
            raise forms.ValidationError('Dates must be in order: open < ' +
                                        'deadline < close.') def save_task(task):
    try:
        with transaction.atomic():
            task.save()
        return True
    except Exception as e:
        print('Error while saving task: %s' % e)
        return False class Contest(models.Model):
    name = models.CharField(max_length=250, unique=True, null=False)
    slug = models.SlugField()
    description = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    modified_at = models.DateTimeField(auto_now=True)
    creator = models.ForeignKey(User)

    class Meta:
        permissions = (
            ('view_contest', 'Can view'),
            ('participate_in_contest', 'Can participate'),
            ('manage_contest', 'Can manage contest'))

    def __str__(self):
        return self.name class GroupTaskDetails(models.Model):
    group = models.ForeignKey(Group, null=False)
    task = models.ForeignKey(Task, null=False)

    open = models.DateTimeField()
    deadline = models.DateTimeField()
    close = models.DateTimeField()

    class Meta:
        index_together = ['group', 'task'] class Task(models.Model):
    name = models.CharField(max_length=250)
    short_name = models.CharField(max_length=3)
    description = models.TextField()
    test_environment = models.ForeignKey('checker.TestEnvironment')
    author = models.ForeignKey(User)
    parent = models.ForeignKey('self', null=True, default=None)
    contest = models.ForeignKey(Contest, null=True, default=None)
    max_solution_size = models.PositiveIntegerField()

    # Default timestamps values for task. Can be overridden individually in
    # groups. See GroupsTaskDetails.
    open = models.DateTimeField(null=True, default=None)
    deadline = models.DateTimeField(null=True, default=None)
    close = models.DateTimeField(null=True, default=None)

    class Meta:
        permissions = (
            ('view_task', 'Can view task'),
            ('submit_solution', 'Can submit solution'),
            ('edit_task', 'Can edit task'))

    def __str__(self):
        return self.name

    @property
    def display_name(self):
        if self.contest is not None and self.contest.name.strip() != "":
            return "%s (%s)" % (self.name, self.contest.name)
        else:
            return self.name
import random
import string
from copy import deepcopy
from django.conf import settings
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.core.cache import cache
from django.core.cache.utils import make_template_fragment_key
from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.utils.text import slugify
from django.views.decorators.http import (require_http_methods, require_POST,
                                          require_safe)
from guardian.shortcuts import (assign_perm, get_groups_with_perms,
                                get_users_with_perms)
from harnas.checker import heraclient
from harnas.checker.forms import SubmitForm
from harnas.checker.models import Submit
from harnas.contest.forms import (ContestForm, GroupForm, NewsForm,
                                  TaskFetchForm)
from harnas.contest.helpers import save_task
from harnas.contest.models import Contest, GroupTaskDetails, Task

    contest_form = ContestForm(instance=contest)

    groups = get_groups_with_perms(contest, attach_perms=True)
    groups = [k for k, v in groups.items() if 'view_contest' in v]
    group_form = GroupForm()

    news_set = contest.news_set.all().order_by('-created_at')
    news_form = NewsForm()

    fetch_task_form = TaskFetchForm()

    participants = []
    if request.user.has_perm('contest.manage_contest', contest):
        participants = get_users_with_perms(contest, attach_perms=True)
        participants = [k for k, v in participants.items()
                        if 'participate_in_contest' in v]

    tasks = Task.objects.filter(contest=contest)

    # test

    return render(request, 'contest/contest_details.html', {
        'contest': contest,
        'contest_form': contest_form,
        'groups': groups,
        'group_form': group_form,
        'participants': participants,
        'news_set': news_set,
        'news_form': news_form,
        'fetch_task_form': fetch_task_form,
        'tasks': tasks,
    })


@require_http_methods(['GET', 'POST'])
@login_required
def edit(request, contest_id=None):
    if contest_id:
        contest = Contest.objects.get(pk=contest_id)
        form_post = reverse('contest_edit', args=[contest_id])
        if not request.user.has_perm('contest.manage_contest', contest):
            raise PermissionDenied
    else:
        contest = Contest()
        form_post = reverse('contest_new')
        if not request.user.has_perm('contest.add_contest'):
            raise PermissionDenied

    if request.method == 'POST':
        form = ContestForm(request.POST, instance=contest)
    else:
        form = ContestForm(instance=contest)
    if form.is_valid():
        new_contest = form.save(commit=False)
        new_contest.slug = slugify(new_contest.name)
        if contest_id is None:
            new_contest.creator_id = request.user.pk
        new_contest.save()
        assign_perm('contest.manage_contest', request.user, new_contest)
        assign_perm('contest.view_contest', request.user, new_contest)
        cache_key = make_template_fragment_key('contest_description',
                                               [new_contest.pk])
        cache.delete(cache_key)
        messages.add_message(request,
                             messages.SUCCESS,
                             "Contest has been successfully updated.")
        return HttpResponseRedirect(reverse('contest_details',
                                            args=[new_contest.pk]))

    messages.add_message(request,
                         messages.SUCCESS,
                         "Contest has been successfully created.")
    return render(request, 'contest/contest_new.html', {
        'form': form,
        'form_post': form_post
    })


@require_POST
@login_required
def fetch_task(request, contest_id):
    contest = Contest.objects.get(pk=contest_id)
    if not request.user.has_perm('manage_contest', contest):
        raise PermissionDenied
    elif request.method == 'POST':
        form = TaskFetchForm(request.POST)
        if form.is_valid():
            fetched_task = copy_task(form)
            fetched_task.contest = contest
            if save_task(fetched_task):
                messages.add_message(
                    request,
                    messages.SUCCESS,
                    'New task has been added to contest %s.' % contest.name)
                add_task_to_groups(contest, fetched_task)
            else:
                messages.add_message(
                    request,
                    messages.ERROR,
                    'Unable to fetch task %s. Please report this accident'
                    ' to administrator.' % fetched_task)

    return HttpResponseRedirect(
        reverse('contest_details', args=[contest_id]) + '?current_tab=tasks')


def copy_task(form):
    parent_task = form.cleaned_data['task']
    fetched_task = deepcopy(parent_task)
    fetched_task.pk = None
    fetched_task.parent = parent_task
    fetched_task.open = form.cleaned_data['open']
    fetched_task.deadline = form.cleaned_data['deadline']
    fetched_task.close = form.cleaned_data['close']
    return fetched_task


def add_task_to_groups(contest, task):
    for group in get_groups_with_perms(contest, attach_perms=True):

        GroupTaskDetails.objects.create(task=task,