class WorkstationImageForm(ModelForm):
    chunked_upload = uploader.UploadedAjaxFileList(
        widget=uploader.AjaxUploadWidget(multifile=False),
        label="Workstation Image",
        validators=[
            ExtensionValidator(allowed_extensions=(".tar", ".tar.gz"))
        ],
        help_text=(
            ".tar.gz archive of the container image produced from the command "
            "'docker save IMAGE | gzip -c > IMAGE.tar.gz'. See "
            "https://docs.docker.com/engine/reference/commandline/save/"),
    )

    def __init__(self, *args, user, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper(self)
        self.fields["chunked_upload"].widget.user = user

    class Meta:
        model = WorkstationImage
        fields = (
            "initial_path",
            "http_port",
            "websocket_port",
            "chunked_upload",
        )
class MethodForm(SaveFormInitMixin, forms.ModelForm):
    phase = ModelChoiceField(
        queryset=None,
        help_text="Which phase is this evaluation container for?",
    )
    chunked_upload = UploadedAjaxFileList(
        widget=uploader.AjaxUploadWidget(multifile=False, auto_commit=False),
        label="Evaluation Method Container",
        validators=[
            ExtensionValidator(allowed_extensions=(".tar", ".tar.gz"))
        ],
        help_text=(
            ".tar.gz archive of the container image produced from the command "
            "'docker save IMAGE | gzip -c > IMAGE.tar.gz'. See "
            "https://docs.docker.com/engine/reference/commandline/save/"),
    )

    def __init__(self, *args, user, challenge, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["chunked_upload"].widget.user = user
        self.fields["phase"].queryset = challenge.phase_set.all()

    class Meta:
        model = Method
        fields = ["phase", "chunked_upload"]
Esempio n. 3
0
class AlgorithmImageForm(ModelForm):
    chunked_upload = UploadedAjaxFileList(
        widget=uploader.AjaxUploadWidget(multifile=False),
        label="Algorithm Image",
        validators=[
            ExtensionValidator(allowed_extensions=(".tar", ".tar.gz"))
        ],
        help_text=(
            ".tar.gz archive of the container image produced from the command "
            "'docker save IMAGE | gzip -c > IMAGE.tar.gz'. See "
            "https://docs.docker.com/engine/reference/commandline/save/"),
    )
    requires_memory_gb = IntegerField(
        min_value=1,
        max_value=24,
        initial=4,
        help_text=
        "The maximum system memory required by the algorithm in gigabytes.",
    )

    def __init__(self, *args, user, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper(self)
        self.fields["chunked_upload"].widget.user = user

    class Meta:
        model = AlgorithmImage
        fields = ("requires_gpu", "requires_memory_gb", "chunked_upload")
Esempio n. 4
0
class ImportForm(SaveFormInitMixin, forms.Form):
    products_file = forms.FileField()
    companies_file = forms.FileField()
    images_zip = UploadedAjaxFileList(widget=uploader.AjaxUploadWidget(
        multifile=False, auto_commit=False), )

    def __init__(self, *args, user, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.add_input(Submit("save", "Submit"))
        self.fields["images_zip"].widget.user = user
Esempio n. 5
0
    def __init__(
        self,
        *,
        kind: InterfaceKind.InterfaceKindChoices,
        initial=None,
        user=None,
        help_text="",
    ):
        field_type = field_for_interface(kind)

        # bool can't be required
        kwargs = {
            "required": (kind != InterfaceKind.InterfaceKindChoices.BOOL),
        }

        extra_help = ""

        if initial is not None:
            kwargs["initial"] = initial
        if kind in InterfaceKind.interface_type_annotation():
            kwargs["widget"] = JSONEditorWidget(
                schema=ANSWER_TYPE_SCHEMA["definitions"][kind])
        if kind in InterfaceKind.interface_type_file():
            kwargs["widget"] = uploader.AjaxUploadWidget(multifile=False,
                                                         auto_commit=False)
            kwargs["validators"] = [
                ExtensionValidator(allowed_extensions=(f".{kind.lower()}", ))
            ]
            extra_help = f"{file_upload_text} .{kind.lower()}"
        if kind in InterfaceKind.interface_type_image():
            kwargs["widget"] = uploader.AjaxUploadWidget(multifile=True,
                                                         auto_commit=False)
            extra_help = IMAGE_UPLOAD_HELP_TEXT

        self._field = field_type(help_text=_join_with_br(
            help_text, extra_help),
                                 **kwargs)

        if user:
            self._field.widget.user = user
Esempio n. 6
0
class SubmissionForm(forms.ModelForm):
    chunked_upload = UploadedAjaxFileList(
        widget=uploader.AjaxUploadWidget(multifile=False),
        label="Predictions File",
        validators=[ExtensionValidator(allowed_extensions=(".zip", ".csv"))],
    )

    def __init__(
        self,
        *args,
        user,
        display_comment_field=False,
        supplementary_file_choice=Config.OFF,
        supplementary_file_label="",
        supplementary_file_help_text="",
        publication_url_choice=Config.OFF,
        **kwargs,
    ):
        """
        Conditionally render the comment field based on the
        display_comment_field kwarg
        """
        super().__init__(*args, **kwargs)

        if not display_comment_field:
            del self.fields["comment"]

        if supplementary_file_label:
            self.fields["supplementary_file"].label = supplementary_file_label

        if supplementary_file_help_text:
            self.fields[
                "supplementary_file"].help_text = supplementary_file_help_text

        if supplementary_file_choice == Config.REQUIRED:
            self.fields["supplementary_file"].required = True
        elif supplementary_file_choice == Config.OFF:
            del self.fields["supplementary_file"]

        if publication_url_choice == Config.REQUIRED:
            self.fields["publication_url"].required = True
        elif publication_url_choice == Config.OFF:
            del self.fields["publication_url"]

        self.helper = FormHelper(self)

        self.fields["chunked_upload"].widget.user = user

    class Meta:
        model = Submission
        fields = submission_fields
Esempio n. 7
0
class UploadRawImagesForm(forms.ModelForm):
    files = UploadedAjaxFileList(
        widget=uploader.AjaxUploadWidget(multifile=True, auto_commit=False),
        label="Image files",
        help_text=IMAGE_UPLOAD_HELP_TEXT,
    )

    def __init__(self, *args, user, linked_task=None, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.add_input(Submit("save", "Submit"))
        self.fields["files"].widget.user = user
        self._linked_task = linked_task

    def clean_files(self):
        files = self.cleaned_data["files"]

        if len({f.name for f in files}) != len(files):
            raise ValidationError("Filenames must be unique.")

        if sum([f.size for f in files]) > settings.UPLOAD_SESSION_MAX_BYTES:
            raise ValidationError(
                "Total size of all files exceeds the upload limit.")

        return files

    def save(self, commit=True):
        instance = super().save(commit=False)  # type: RawImageUploadSession

        # Create links between the created session and all uploaded files
        uploaded_files = self.cleaned_data[
            "files"]  # type: List[StagedAjaxFile]

        raw_files = [
            RawImageFile(
                upload_session=instance,
                filename=uploaded_file.name,
                staged_file_id=uploaded_file.uuid,
            ) for uploaded_file in uploaded_files
        ]

        if commit:
            instance.save()
            RawImageFile.objects.bulk_create(raw_files)
            instance.process_images(linked_task=self._linked_task)

        return instance

    class Meta:
        model = RawImageUploadSession
        fields = ["files"]
Esempio n. 8
0
class AnnotationSetUpdateLabelsForm(forms.ModelForm):
    chunked_upload = UploadedAjaxFileList(
        widget=uploader.AjaxUploadWidget(multifile=False),
        label="Labels File",
        validators=[ExtensionValidator(allowed_extensions=(".csv",))],
    )

    def __init__(self, *args, user, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper(self)
        self.fields["chunked_upload"].widget.user = user

    class Meta:
        model = AnnotationSet
        fields = ("chunked_upload",)
Esempio n. 9
0
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
from django import forms
from django.db import transaction

from grandchallenge.cases.models import RawImageUploadSession, RawImageFile
from grandchallenge.jqfileupload.filters import reject_duplicate_filenames
from grandchallenge.jqfileupload.widgets import uploader
from grandchallenge.jqfileupload.widgets.uploader import (
    UploadedAjaxFileList, StagedAjaxFile
)

upload_raw_files_widget = uploader.AjaxUploadWidget(
    ajax_target_path="ajax/raw_files/",
    multifile=True,
    auto_commit=False,
    upload_validators=[
        reject_duplicate_filenames,
    ],
)


class UploadRawImagesForm(forms.ModelForm):
    files = UploadedAjaxFileList(
        widget=upload_raw_files_widget,
        label="Image files",
        help_text=(
            'Upload images for creating a new archive'
        ),
    )

    def __init__(self, *args, **kwargs):
Esempio n. 10
0
# -*- coding: utf-8 -*-
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
from django import forms

from grandchallenge.algorithms.models import Algorithm, Job
from grandchallenge.core.validators import (
    ExtensionValidator, MimeTypeValidator
)
from grandchallenge.jqfileupload.widgets import uploader
from grandchallenge.jqfileupload.widgets.uploader import UploadedAjaxFileList

algorithm_upload_widget = uploader.AjaxUploadWidget(
    ajax_target_path="ajax/algorithm-upload/", multifile=False,
)


class AlgorithmForm(forms.ModelForm):
    ipython_notebook = forms.FileField(
        validators=[
            MimeTypeValidator(allowed_types=('text/plain',))
        ],
        required=False,
        help_text=(
            "Please upload an iPython notebook that describes your algorithm"
        ),
    )
    chunked_upload = UploadedAjaxFileList(
        widget=algorithm_upload_widget,
        label='Algorithm Image',
        validators=[
Esempio n. 11
0
class SubmissionForm(forms.ModelForm):
    chunked_upload = UploadedAjaxFileList(
        widget=uploader.AjaxUploadWidget(multifile=False, auto_commit=False),
        label="Predictions File",
        validators=[ExtensionValidator(allowed_extensions=(".zip", ".csv"))],
    )
    algorithm = ModelChoiceField(
        queryset=None,
        help_text=format_lazy(
            "Select one of your algorithms to submit as a solution to this "
            "challenge. If you have not created your algorithm yet you can "
            "do so <a href={}>on this page</a>.",
            reverse_lazy("algorithms:create"),
        ),
    )

    def __init__(
        self,
        *args,
        user,
        algorithm_submission=False,
        display_comment_field=False,
        supplementary_file_choice=Config.OFF,
        supplementary_file_label="",
        supplementary_file_help_text="",
        publication_url_choice=Config.OFF,
        **kwargs,
    ):
        """
        Conditionally render the comment field based on the
        display_comment_field kwarg
        """
        super().__init__(*args, **kwargs)

        if not display_comment_field:
            del self.fields["comment"]

        if supplementary_file_label:
            self.fields["supplementary_file"].label = supplementary_file_label

        if supplementary_file_help_text:
            self.fields[
                "supplementary_file"].help_text = supplementary_file_help_text

        if supplementary_file_choice == Config.REQUIRED:
            self.fields["supplementary_file"].required = True
        elif supplementary_file_choice == Config.OFF:
            del self.fields["supplementary_file"]

        if publication_url_choice == Config.REQUIRED:
            self.fields["publication_url"].required = True
        elif publication_url_choice == Config.OFF:
            del self.fields["publication_url"]

        if algorithm_submission:
            del self.fields["chunked_upload"]

            self.fields["algorithm"].queryset = get_objects_for_user(
                user,
                f"{Algorithm._meta.app_label}.change_{Algorithm._meta.model_name}",
                Algorithm,
            ).order_by("title")
        else:
            del self.fields["algorithm"]

            self.fields["chunked_upload"].widget.user = user

        self.helper = FormHelper(self)
        self.helper.layout.append(Submit("save", "Save"))

    def clean_algorithm(self):
        algorithm = self.cleaned_data["algorithm"]

        if algorithm.latest_ready_image is None:
            raise ValidationError(
                "This algorithm does not have a usable container image. "
                "Please add one and try again.")

        return algorithm

    class Meta:
        model = Submission
        fields = submission_fields
Esempio n. 12
0
class UploadRawImagesForm(forms.ModelForm):
    files = UploadedAjaxFileList(
        widget=uploader.AjaxUploadWidget(multifile=True, auto_commit=False),
        label="Image files",
        help_text=(
            "The total size of all files uploaded in a single session "
            "cannot exceed 10 GB.<br>"
            "The following file formats are supported: "
            ".mha, .mhd, .raw, .zraw, .dcm, .nii, .nii.gz, "
            ".tiff, .png, .jpeg and .jpg.<br>"
            "The following file formats can be uploaded and will be converted to "
            "tif: Aperio(.svs), Hamamatsu(.vms, .vmu, .ndpi), Leica(.scn), MIRAX"
            "(.mrxs) and Ventana(.bif)."
        ),
    )

    def __init__(self, *args, user, linked_task=None, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.add_input(Submit("save", "Submit"))
        self.fields["files"].widget.user = user
        self._linked_task = linked_task

    def clean_files(self):
        files = self.cleaned_data["files"]

        if len({f.name for f in files}) != len(files):
            raise ValidationError("Filenames must be unique.")

        if sum([f.size for f in files]) > settings.UPLOAD_SESSION_MAX_BYTES:
            raise ValidationError(
                "Total size of all files exceeds the upload limit."
            )

        return files

    def save(self, commit=True):
        instance = super().save(commit=False)  # type: RawImageUploadSession

        # Create links between the created session and all uploaded files
        uploaded_files = self.cleaned_data[
            "files"
        ]  # type: List[StagedAjaxFile]

        raw_files = [
            RawImageFile(
                upload_session=instance,
                filename=uploaded_file.name,
                staged_file_id=uploaded_file.uuid,
            )
            for uploaded_file in uploaded_files
        ]

        if commit:
            instance.save()
            RawImageFile.objects.bulk_create(raw_files)
            instance.process_images(linked_task=self._linked_task)

        return instance

    class Meta:
        model = RawImageUploadSession
        fields = ["files"]
Esempio n. 13
0
        model = Config
        fields = (
            *submission_options,
            *scoring_options,
            *leaderboard_options,
            *result_detail_options,
        )
        widgets = {
            "submission_page_html":
            SummernoteInplaceWidget(),
            "extra_results_columns":
            JSONEditorWidget(schema=EXTRA_RESULT_COLUMNS_SCHEMA),
        }


method_upload_widget = uploader.AjaxUploadWidget(
    ajax_target_path="ajax/method-upload/", multifile=False)


class MethodForm(forms.ModelForm):
    chunked_upload = UploadedAjaxFileList(
        widget=method_upload_widget,
        label="Evaluation Method Container",
        validators=[ExtensionValidator(allowed_extensions=(".tar", ))],
        help_text=(
            "Tar archive of the container image produced from the command "
            "`docker save IMAGE > IMAGE.tar`. See "
            "https://docs.docker.com/engine/reference/commandline/save/"),
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
Esempio n. 14
0
from django import forms

from grandchallenge.jqfileupload.widgets import uploader
from grandchallenge.jqfileupload.widgets.uploader import UploadedAjaxFileList

test_upload_widget = uploader.AjaxUploadWidget(
    ajax_target_path="ajax/ulwidget1/"
)
test_upload_widget2 = uploader.AjaxUploadWidget(
    ajax_target_path="ajax/ulwidget2/", multifile=False
)


class UploadForm(forms.Form):
    title = forms.CharField(label="Blah")
    something = forms.CharField(label="Blabl")
    upload_form = UploadedAjaxFileList(widget=test_upload_widget)
    upload_form2 = UploadedAjaxFileList(widget=test_upload_widget2)
Esempio n. 15
0
from grandchallenge.jqfileupload.widgets import uploader
from grandchallenge.workstations.models import Workstation, WorkstationImage


class WorkstationForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.helper = FormHelper(self)
        self.helper.layout.append(Submit("save", "Save"))

    class Meta:
        model = Workstation
        fields = ("title", "logo", "description")


workstation_image_upload_widget = uploader.AjaxUploadWidget(
    ajax_target_path="ajax/workstation-image-upload/", multifile=False)


class WorkstationImageForm(ModelForm):
    chunked_upload = uploader.UploadedAjaxFileList(
        widget=workstation_image_upload_widget,
        label="Workstation Image",
        validators=[
            ExtensionValidator(allowed_extensions=(".tar", ".tar.gz"))
        ],
        help_text=(
            ".tar.gz archive of the container image produced from the command "
            "'docker save IMAGE | gzip -c > IMAGE.tar.gz'. See "
            "https://docs.docker.com/engine/reference/commandline/save/"),
    )
class SubmissionForm(forms.ModelForm):
    chunked_upload = UploadedAjaxFileList(
        widget=uploader.AjaxUploadWidget(multifile=False, auto_commit=False),
        label="Predictions File",
        validators=[ExtensionValidator(allowed_extensions=(".zip", ".csv"))],
    )
    algorithm = ModelChoiceField(
        queryset=None,
        help_text=format_lazy(
            "Select one of your algorithms to submit as a solution to this "
            "challenge. If you have not created your algorithm yet you can "
            "do so <a href={}>on this page</a>.",
            reverse_lazy("algorithms:create"),
        ),
    )

    def __init__(
        self,
        *args,
        user,
        creator_must_be_verified=False,
        algorithm_submission=False,
        display_comment_field=False,
        supplementary_file_choice=Phase.OFF,
        supplementary_file_label="",
        supplementary_file_help_text="",
        publication_url_choice=Phase.OFF,
        **kwargs,
    ):
        """
        Conditionally render the comment field based on the
        display_comment_field kwarg
        """
        super().__init__(*args, **kwargs)

        self.creator_must_be_verified = creator_must_be_verified

        if not display_comment_field:
            del self.fields["comment"]

        if supplementary_file_label:
            self.fields["supplementary_file"].label = supplementary_file_label

        if supplementary_file_help_text:
            self.fields[
                "supplementary_file"].help_text = supplementary_file_help_text

        if supplementary_file_choice == Phase.REQUIRED:
            self.fields["supplementary_file"].required = True
        elif supplementary_file_choice == Phase.OFF:
            del self.fields["supplementary_file"]

        if publication_url_choice == Phase.REQUIRED:
            self.fields["publication_url"].required = True
        elif publication_url_choice == Phase.OFF:
            del self.fields["publication_url"]

        if algorithm_submission:
            del self.fields["chunked_upload"]

            self.fields["algorithm"].queryset = get_objects_for_user(
                user,
                f"{Algorithm._meta.app_label}.change_{Algorithm._meta.model_name}",
                Algorithm,
            ).order_by("title")
        else:
            del self.fields["algorithm"]

            self.fields["chunked_upload"].widget.user = user

        self.fields["creator"].queryset = get_user_model().objects.filter(
            pk=user.pk)
        self.fields["creator"].initial = user

        self.helper = FormHelper(self)
        self.helper.layout.append(Submit("save", "Save"))

    def clean_algorithm(self):
        algorithm = self.cleaned_data["algorithm"]

        if algorithm.latest_ready_image is None:
            raise ValidationError(
                "This algorithm does not have a usable container image. "
                "Please add one and try again.")

        return algorithm

    def clean_creator(self):
        creator = self.cleaned_data["creator"]

        try:
            user_is_verified = creator.verification.is_verified
        except ObjectDoesNotExist:
            user_is_verified = False

        if self.creator_must_be_verified and not user_is_verified:
            error_message = format_html(
                "You must verify your account before you can make a "
                "submission to this phase. Please "
                '<a href="{}"> request verification here</a>.',
                reverse("verifications:create"),
            )

            # Add this to the non-field errors as we use a HiddenInput
            self.add_error(None, error_message)

            raise ValidationError(error_message)

        return creator

    class Meta:
        model = Submission
        fields = submission_fields
        widgets = {"creator": forms.HiddenInput}