Ejemplo n.º 1
0
 def test_validate_singularity_container_fail(self):
     """
     A non-Singularity container should raise an error.
     :return:
     """
     with self.assertRaisesMessage(
             ValidationError, Container.
             DEFAULT_ERROR_MESSAGES["invalid_singularity_container"]):
         Container.validate_singularity_container(self.useless_file)
Ejemplo n.º 2
0
 def test_validate_singularity_container_fail(self):
     """
     A non-Singularity container should raise an error.
     :return:
     """
     with self.assertRaisesMessage(
             ValidationError,
             Container.DEFAULT_ERROR_MESSAGES["invalid_singularity_container"]
     ):
         Container.validate_singularity_container(self.useless_file)
Ejemplo n.º 3
0
 def test_good_zip_archive(self):
     """
     A good zip archive container passes validation.
     :return:
     """
     parent = Container(id=41, file_type=Container.SIMG)
     container = Container(id=42, file_type=Container.ZIP, parent=parent)
     with open(self.zip_archive, "rb") as zip_archive:
         container.file = File(zip_archive)
         container.clean()
Ejemplo n.º 4
0
 def test_good_tar_archive(self):
     """
     A good tar archive container passes validation.
     :return:
     """
     parent = Container(id=41, file_type=Container.SIMG)
     container = Container(id=42, file_type=Container.TAR, parent=parent)
     with open(self.tar_archive, "rb") as tar_archive:
         container.file = File(tar_archive)
         container.clean()
Ejemplo n.º 5
0
    def clean(self):
        """
        Perform Singularity container file validation (it's more efficient to do here than at the model level).

        Fill in the values for file and file_type.
        :return:
        """
        self.cleaned_data = super(ContainerForm, self).clean()

        # Check the file extension of the file.
        the_file = self.cleaned_data.get("file")
        if the_file is None:
            raise ValidationError(
                Container.DEFAULT_ERROR_MESSAGES["invalid_archive"],
                code="invalid_archive",
            )
        upload_name = getattr(the_file, 'name', 'container.simg')
        upload_base, upload_ext = os.path.splitext(upload_name)
        upload_lower = upload_name.lower()
        file_type = None
        for ext in Container.ACCEPTED_FILE_EXTENSIONS:
            if upload_lower.endswith(ext):
                file_type = Container.ACCEPTED_FILE_EXTENSIONS[ext]
                break
        if file_type is None:
            raise ValidationError(
                Container.DEFAULT_ERROR_MESSAGES["bad_extension"],
                code="bad_extension")

        if file_type == Container.SIMG:
            # We need to get a file object to validate. We might have a path or we might
            # have to read the data out of memory.
            if hasattr(the_file, 'temporary_file_path'):
                Container.validate_singularity_container(
                    the_file.temporary_file_path())
            else:
                with NamedTemporaryFile(prefix=upload_base,
                                        suffix=upload_ext) as f_temp:
                    if hasattr(the_file, 'read'):
                        f_temp.write(the_file.read())
                    else:
                        f_temp.write(the_file['content'])
                    f_temp.flush()
                    Container.validate_singularity_container(f_temp.name)

                if hasattr(the_file, 'seek') and callable(the_file.seek):
                    the_file.seek(0)

            # Annotate self.instance with a marker that we already validated the container.
            self.instance.singularity_validated = True

        # Having figured out the file type, add it to self.instance manually.
        self.instance.file_type = file_type
        return self.cleaned_data
Ejemplo n.º 6
0
 def bad_archive_test_helper(self, archive_type):
     """
     Helper for testing bad archive containers.
     :return:
     """
     parent = Container(id=41, file_type=Container.SIMG)
     container = Container(id=42, file_type=archive_type, parent=parent)
     with open(self.useless_file, "rb") as f:
         container.file = File(f)
         with self.assertRaisesMessage(
                 ValidationError,
                 Container.DEFAULT_ERROR_MESSAGES["invalid_archive"]):
             container.clean()
Ejemplo n.º 7
0
 def empty_archive_test_helper(self, archive_type):
     """
     Helper for testing archive containers that are just empty files (as opposed to empty archives).
     :return:
     """
     parent = Container(id=41, file_type=Container.SIMG)
     container = Container(id=42, file_type=archive_type, parent=parent)
     with open(self.empty_file, "rb") as f:
         container.file = File(f)
         with self.assertRaisesMessage(
                 ValidationError,
                 Container.DEFAULT_ERROR_MESSAGES["invalid_archive"]):
             container.clean()
Ejemplo n.º 8
0
    def test_clean_singularity_image_with_parent(self):
        """
        A Singularity container should not have a parent.
        :return:
        """
        parent = Container(id=41)
        container = Container(id=42, parent=parent, file_type=Container.SIMG)
        with open(self.alpine_path, "rb") as alpine_file:
            container.file = File(alpine_file)

            with self.assertRaisesMessage(
                    ValidationError, Container.
                    DEFAULT_ERROR_MESSAGES["singularity_cannot_have_parent"]):
                container.clean()
Ejemplo n.º 9
0
    def admissible_driver_test_helper(self, archive_type, driver_type):
        """
        Helper for testing archive containers' drivers' admissibility.
        :return:
        """
        pipeline_dict = {"steps": [{"driver": "foobarbaz"}]}

        # Archives that contain a mix of files, including one driver.
        fd, archive = tempfile.mkstemp()
        try:
            with open(archive, mode="wb") as f:
                if archive_type == Container.ZIP:
                    archive_handler = ZipHandler(f, mode="w")
                else:
                    archive_handler = TarHandler(f, mode="w")

                archive_handler.write(u"hello_world.sh",
                                      self.hello_world_script)
                archive_handler.write(u"useless.lib", self.useless)
                archive_handler.write(u"not_a_script", self.not_a_script)

                if driver_type == "good":
                    pipeline_dict["steps"][0]["driver"] = "hello_world.sh"
                elif driver_type == "bad":
                    pipeline_dict["steps"][0]["driver"] = "not_a_script"
                archive_handler.write("kive/pipeline0.json",
                                      json.dumps(pipeline_dict))
                archive_handler.close()

            parent = Container(id=41, file_type=Container.SIMG)
            container = Container(id=42, file_type=archive_type, parent=parent)
            with open(archive, "rb") as f:
                container.file = File(f)

                if driver_type == "good":
                    container.clean()

                elif driver_type == "bad":
                    with self.assertRaisesMessage(
                            ValidationError, Container.
                            DEFAULT_ERROR_MESSAGES["inadmissible_driver"]):
                        container.clean()

                elif driver_type == "nonexistent":
                    with self.assertRaisesMessage(
                            ValidationError, Container.
                            DEFAULT_ERROR_MESSAGES["driver_not_in_archive"]):
                        container.clean()
        finally:
            os.remove(archive)
Ejemplo n.º 10
0
    def clean(self):
        """
        Perform Singularity container file validation (it's more efficient to do here than at the model level).

        Fill in the values for file and file_type.
        :return:
        """
        self.cleaned_data = super(ContainerForm, self).clean()

        # Check the file extension of the file.
        the_file = self.cleaned_data["file"]
        upload_name = getattr(the_file, 'name', 'container.simg')
        upload_base, upload_ext = os.path.splitext(upload_name)
        upload_lower = upload_name.lower()
        file_type = None
        for ext in Container.ACCEPTED_FILE_EXTENSIONS:
            if upload_lower.endswith(ext):
                file_type = Container.ACCEPTED_FILE_EXTENSIONS[ext]
                break
        if file_type is None:
            raise ValidationError(
                Container.DEFAULT_ERROR_MESSAGES["bad_extension"],
                code="bad_extension"
            )

        if file_type == Container.SIMG:
            # We need to get a file object to validate. We might have a path or we might
            # have to read the data out of memory.
            if hasattr(the_file, 'temporary_file_path'):
                Container.validate_singularity_container(the_file.temporary_file_path())
            else:
                with NamedTemporaryFile(prefix=upload_base,
                                        suffix=upload_ext) as f_temp:
                    if hasattr(the_file, 'read'):
                        f_temp.write(the_file.read())
                    else:
                        f_temp.write(the_file['content'])
                    f_temp.flush()
                    Container.validate_singularity_container(f_temp.name)

                if hasattr(the_file, 'seek') and callable(the_file.seek):
                    the_file.seek(0)

            # Annotate self.instance with a marker that we already validated the container.
            self.instance.singularity_validated = True

        # Having figured out the file type, add it to self.instance manually.
        self.instance.file_type = file_type
        return self.cleaned_data
Ejemplo n.º 11
0
    def test_removal(self):
        container = Container(id=42)
        expected_plan = {'Containers': {container}}

        plan = container.build_removal_plan()

        self.assertEqual(expected_plan, strip_removal_plan(plan))
Ejemplo n.º 12
0
    def test_str(self):
        family = ContainerFamily(name='Spline Reticulator')
        container = Container(tag='v1.0.7', family=family)

        s = str(container)

        self.assertEqual("Spline Reticulator:v1.0.7", s)
Ejemplo n.º 13
0
    def get_context_data(self, **kwargs):
        app_id = int(self.request.GET.get("app"))
        visible_containers = Container.filter_by_user(self.request.user)
        app_qs = ContainerApp.objects.filter(pk=app_id,
                                             container__in=visible_containers)

        app = app_qs.first()
        if app is None:
            raise Http404("ID {} is not accessible".format(app_id))
        context = super(ContainerInputList, self).get_context_data(**kwargs)
        context['app'] = app
        context['app_url'] = rest_framework.reverse.reverse(
            str('containerapp-detail'),
            kwargs=dict(pk=app.pk),
            request=self.request)
        context['batch_form'] = BatchForm()
        context['inputs'] = [
            dict(name=arg.name,
                 url=rest_framework.reverse.reverse(
                     str('containerargument-detail'),
                     kwargs=dict(pk=arg.pk),
                     request=self.request)) for arg in app.arguments.filter(
                         type=ContainerArgument.INPUT).order_by('position')
        ]
        context['priolist'] = [t[0] for t in settings.SLURM_QUEUES]
        return context
Ejemplo n.º 14
0
    def get_context_data(self, **kwargs):
        app_id = int(self.request.GET.get("app"))
        visible_containers = Container.filter_by_user(self.request.user)
        app_qs = ContainerApp.objects.filter(pk=app_id,
                                             container__in=visible_containers)

        app = app_qs.first()
        if app is None:
            raise Http404("ID {} is not accessible".format(app_id))
        context = super(ContainerInputList, self).get_context_data(**kwargs)
        context['app'] = app
        context['app_url'] = rest_framework.reverse.reverse(
            str('containerapp-detail'),
            kwargs=dict(pk=app.pk),
            request=self.request)
        context['batch_form'] = BatchForm()
        context['inputs'] = [
            dict(name=arg.name, url=rest_framework.reverse.reverse(
                str('containerargument-detail'),
                kwargs=dict(pk=arg.pk),
                request=self.request))
            for arg in app.arguments.filter(
                type=ContainerArgument.INPUT).order_by('position')]
        context['priolist'] = [t[0] for t in settings.SLURM_QUEUES]
        return context
Ejemplo n.º 15
0
    def test_removal_with_app(self):
        container = Container(id=42)
        app = container.apps.create(id=43)
        expected_plan = {'Containers': {container}, 'ContainerApps': {app}}

        plan = container.build_removal_plan()

        self.assertEqual(expected_plan, strip_removal_plan(plan))
Ejemplo n.º 16
0
    def test_removal_with_child(self):
        container = Container(id=42)
        child_container = container.children.create(id=43)
        expected_plan = {'Containers': {container, child_container}}

        plan = container.build_removal_plan()

        self.assertEqual(expected_plan, strip_removal_plan(plan))
Ejemplo n.º 17
0
    def test_removal_with_method(self):
        container = Container(id=42)
        method = container.methods.create(transformation_ptr_id=43)
        expected_plan = {'Containers': {container}, 'Methods': {method}}

        plan = container.build_removal_plan()

        self.assertEqual(expected_plan, strip_removal_plan(plan))
Ejemplo n.º 18
0
def get_context(request):
    """ Returns the context for lemmatised feature words.

    The parameters object;
    {
        containerid: int,
        lemma: list[str],
        highlight: bool,
    }
    :param request:
    :return:
    """
    params = request.GET.dict() or json.loads(request.body)

    if not params:
        raise Http404
    try:
        containerid = int(params['containerid'])
        container = Container.get_object(pk=containerid)
        lemma = params['lemma']
    except (ValueError, KeyError, TypeError) as _:
        raise Http404(params)

    highlight = params.get('highlight', False)

    lemma_to_words, lemma = container.get_lemma_words(lemma)
    matchwords = []
    for i in lemma:
        try:
            mapping = next(_ for _ in lemma_to_words if _.get('lemma') == i)
            matchwords.extend(mapping.get('words'))
        except StopIteration:
            matchwords.append(i)
    data = search_texts(path=container.container_path(),
                        highlight=highlight,
                        words=matchwords)

    serialiser = SerialiserFactory().get_serialiser('search_text_csv')

    data_objs = [{
        'title': _.title,
        'url': _.url,
        'pk': _.pk,
        'dataid': _.dataid,
        'created': _.created
    } for _ in container.data_set.filter(file_id__in=list(
        uuid.UUID(_['dataid']) for _ in data['data']))]
    serialiser = serialiser(data={
        'docs': data_objs,
        'response': data,
        'lemma': lemma
    })
    zip_name = serialiser.get_zip_name(
        f'Feature-Context-ContainerID-{containerid}')
    resp = HttpResponse(serialiser.get_value(),
                        content_type='application/force-download')
    resp['Content-Disposition'] = 'attachment; filename="%s"' % zip_name
    return resp
Ejemplo n.º 19
0
    def test_display_default(self):
        app = ContainerApp(name='')  # default app
        app.container = Container(tag='v1.0')
        app.container.family = ContainerFamily(name='Splines')
        expected_display_name = 'Splines:v1.0'

        display_name = app.display_name

        self.assertEqual(expected_display_name, display_name)
Ejemplo n.º 20
0
 def build_run(self):
     run = ContainerRun()
     run.app = ContainerApp()
     run.app.container = Container()
     run.app.container.file = Namespace(path='/tmp/foo.simg')
     run.sandbox_path = '/tmp/box23'
     run.app.arguments.create(type=ContainerArgument.INPUT, name='in_csv')
     run.app.arguments.create(type=ContainerArgument.OUTPUT, name='out_csv')
     return run
Ejemplo n.º 21
0
 def test_clean_good_singularity_image(self):
     """
     A proper Singularity container should pass validation.
     :return:
     """
     container = Container(id=42)
     container.file_type = Container.SIMG
     with open(self.alpine_path, 'rb') as alpine_file:
         container.file = File(alpine_file)
         container.clean()
Ejemplo n.º 22
0
    def test_display_name(self):
        app = ContainerApp(name='reticulate')
        app.container = Container(tag='v1.0')
        app.container.family = ContainerFamily(name='Splines')
        expected_display_name = 'Splines:v1.0 / reticulate'

        display_name = app.display_name
        app_str = str(app)

        self.assertEqual(expected_display_name, display_name)
        self.assertEqual(expected_display_name, app_str)
Ejemplo n.º 23
0
    def get_file_path(self, container: Container = None):
        """
        Returns the path of the file as it is saved on disk
        :return:
        """
        containerid = self.container.pk
        if not container:
            container = Container.get_object(containerid)

        return os.path.normpath(
            os.path.join(container.container_path(), self.dataid))
Ejemplo n.º 24
0
 def no_driver_archive_test_helper(self, archive_type, empty=True):
     """
     Helper for testing archive containers with no driver.
     :return:
     """
     parent = Container(id=41, file_type=Container.SIMG)
     container = Container(id=42, file_type=archive_type, parent=parent)
     archive_file = self.empty_zip_archive
     if empty and archive_type == Container.TAR:
         archive_file = self.empty_tar_archive
     elif not empty:
         if archive_type == Container.ZIP:
             archive_file = self.no_driver_zip
         else:
             archive_file = self.no_driver_tar
     with open(archive_file, "rb") as f:
         container.file = File(f)
         with self.assertRaisesMessage(
                 ValidationError, Container.
                 DEFAULT_ERROR_MESSAGES["archive_has_no_drivers"]):
             container.clean()
Ejemplo n.º 25
0
 def test_skip_singularity_validation(self, mock_val):
     """
     Skip Singularity validation if it's marked as having already been done.
     :param mock_val:
     :return:
     """
     container = Container(id=42, file_type=Container.SIMG)
     container.singularity_validated = True
     with open(self.alpine_path, 'rb') as alpine_file:
         container.file = File(alpine_file)
         container.clean()
     mock_val.assert_not_called()
Ejemplo n.º 26
0
    def save(self, data, element_object=None):
        if element_object == None:
            container = Container()
            uid = self.generateUID()
            container.uid = uid
        else:
            container = element_object

            vars = container.variable.all()
            for vr in vars:
                container.variable.remove(vr)


        uid_deploy = self.parseData(data, "parent")
        deployment = self.getDeployment(uid_deploy)

        if not deployment == None:
            container.name = self.parseData(data, "name")
            container.type = self.parseData(data, "type")
            container.base_image = self.parseData(data, "base_image")
            container.image_name = self.parseData(data, "image_name")
            container.source = self.parseData(data, "source")
            container.port = self.parseData(data, "port")
            container.commands = self.parseData(data, "commands")
            container.cmd = self.parseData(data, "cmd")
            container.volume_path = self.parseData(data, "volume_path")
            container.save()



            list_variables = self.parseData(data, "variables")

            for variable_uid in list_variables:
                variable_item = self.getVariable(variable_uid)
                if not variable_item == None:
                    container.variable.add(variable_item)

            list_variables_items = self.parseData(data, "variables_items")


            print(list_variables_items)
            for var_item in list_variables_items:
                var_item_object = self.saveVariable(var_item)
                if not var_item_object == None:
                    container.variable.add(var_item_object)


            container.deployment.add(deployment)

            return { "status" : "success", "message" : "Saved", "uid" : container.uid, "element" :  "container" }
        else:
            return {"status": "error", "message": "Deployment Not exist", "element" :  "container"}
Ejemplo n.º 27
0
    def test_archive_with_no_parent(self):
        """
        An archive container must have a parent.
        :return:
        """
        container = Container(id=42, file_type=Container.ZIP)
        with open(self.zip_archive, "rb") as zip_archive:
            container.file = File(zip_archive)

            with self.assertRaisesMessage(
                    ValidationError, Container.
                    DEFAULT_ERROR_MESSAGES["archive_must_have_parent"]):
                container.clean()
Ejemplo n.º 28
0
 def delete_many(cls, data_ids: typing.List[int], containerid: int = None):
     """
     Delete many objects for a given containerid and a list of data ids.
     :param data_ids:
     :param containerid:
     :return:
     """
     container = Container.get_object(pk=containerid)
     for obj in cls.objects.filter(pk__in=data_ids):
         if container != obj.container:
             continue
         _path = obj.file_path
         if os.path.exists(_path):
             os.remove(_path)
         obj.delete()
Ejemplo n.º 29
0
    def test_slurm_command_custom_memory(self):
        run = ContainerRun(pk=99)
        run.user = User(username='******')
        run.app = ContainerApp(threads=3, memory=100)
        run.app.container = Container()
        run.app.container.family = ContainerFamily(name='my container')
        run.sandbox_path = 'run23'
        expected_command = [
            'sbatch', '-J', 'r99 my container', '--parsable', '--output',
            '/tmp/kive_media/run23/logs/job%J_node%N_stdout.txt', '--error',
            '/tmp/kive_media/run23/logs/job%J_node%N_stderr.txt', '-c', '3',
            '--mem', '100', EXPECTED_MANAGE_PATH, 'runcontainer', '99'
        ]

        command = run.build_slurm_command()

        self.assertListEqual(expected_command, command)
Ejemplo n.º 30
0
    def create(cls,
               data: (
                   str,
                   list,
               ) = None,
               containerid: int = None,
               links: list = None,
               title: str = None,
               endpoint: str = None,
               seed: bool = False):
        """
        Create and save a Data object with all the urls that make it.

        :param data:
        :param containerid:
        :param links:
        :param title:
        :param endpoint:
        :param seed:
        :return:
        """
        container_obj = Container.get_object(containerid)
        url_parse = urllib.parse.urlparse(endpoint)
        obj = cls(title=title,
                  container=container_obj,
                  url=endpoint,
                  seed=seed,
                  hostname=url_parse.hostname)

        file_path = obj.get_file_path(container=container_obj)
        obj.file_path = file_path
        try:
            hash_text = obj.write_data_to_file(path=file_path, data=data)
        except DuplicateUrlError as _:
            return None
        else:
            obj.hash_text = hash_text
        obj.save()
        for item in links:
            Link.create(url=item, data=obj)
        return obj
Ejemplo n.º 31
0
    def test_slurm_command_priority(self):
        run = ContainerRun(pk=99)
        run.user = User(username='******')
        run.app = ContainerApp()
        run.app.container = Container()
        run.app.container.family = ContainerFamily(name='my container')
        slurm_queues = (('low', 'kive-low'), ('medium', 'kive-medium'),
                        ('high', 'kive-high'))
        run.priority = 2
        run.sandbox_path = 'run23'
        expected_command = [
            'sbatch', '-J', 'r99 my container', '--parsable', '--output',
            '/tmp/kive_media/run23/logs/job%J_node%N_stdout.txt', '--error',
            '/tmp/kive_media/run23/logs/job%J_node%N_stderr.txt', '-c', '1',
            '--mem', '6000', '-p', 'kive-high', EXPECTED_MANAGE_PATH,
            'runcontainer', '99'
        ]

        command = run.build_slurm_command(slurm_queues)

        self.assertListEqual(expected_command, command)
Ejemplo n.º 32
0
 def prepare_data(self, containerid, data):
     """
     :param containerid:
     :param data:
     :return:
     """
     try:
         container = Container.get_object(pk=containerid)
     except ValueError:
         raise Http404(containerid)
     dataset = list(container.data_set.all())
     for item in data:
         try:
             rec = next(_ for _ in dataset if _.dataid == item['fileid'])
         except StopIteration:
             continue
         else:
             del item['fileid']
             item['url'] = rec.url
             item['title'] = rec.title
             item['pk'] = rec.pk
             item['created'] = rec.created
     data.reverse()
     return data
Ejemplo n.º 33
0
Archivo: ajax.py Proyecto: cfe-lab/Kive
    def filter_granted(self, queryset):
        """ Args don't have permissions, so filter by parent containers. """
        granted_containers = Container.filter_by_user(self.request.user)

        return queryset.filter(app__container_id__in=granted_containers)
Ejemplo n.º 34
0
 def test_validate_singularity_container_pass(self):
     """
     A proper Singularity container should pass validation.
     :return:
     """
     Container.validate_singularity_container(self.alpine_path)
Ejemplo n.º 35
0
    def post(self, request, format=None):
        url = f"{BACKEND_DOMAIN}{reverse('lti')}"
        consumers = LTI_CONFIG["consumers"]
        method = request.method
        headers = request.META
        payload = request.POST.dict()

        # Verify that the payload received from LTI is valid
        try:
            verify_request_common(consumers, url, method, headers, payload)
        # If not, redirect to the error page
        # This page would be displayed in an iframe on Moodle
        except LTIException:
            # TODO: Implement logging of this error
            return redirect(FRONTEND_DOMAIN + "/forbidden")

        current_user_email = payload["lis_person_contact_email_primary"]
        data = {
            "email": current_user_email,
            "first_name": payload["lis_person_name_given"],
            "last_name": payload["lis_person_name_family"],
        }
        user = get_or_create_user(data)

        # Elevate the user to instructor group if they have a staff role in LTI
        # If they are already instructor or admin, then do nothing
        user_groups = [group.name for group in user.groups.all()]
        is_lti_instructor = (LTI_CONFIG["staff_role"]
                             in payload["roles"].split(",")
                             if LTI_CONFIG.get("staff_role") else False)
        if "user" in user_groups and is_lti_instructor:
            user.groups.set([Group.objects.get(name="instructor")])

        token = generate_one_time_token(user)

        user.last_login = dt.now(timezone.utc)
        user.save()

        logger.info("authentication.login",
                    extra={
                        "user": user.email,
                        "type": "LTI"
                    })

        # Store the important LTI fields for this user
        # These fields be used to grant permissions in containers
        lti_payload = {
            "lti_id": payload["user_id"],
            "lti_email": current_user_email,
            "user_id": payload.get(LTI_CONFIG.get("username_field")),
        }
        lti.objects(user=user.id).update_one(payload=lti_payload, upsert=True)

        # If any containers have been bound to this LTI resource, then
        # redirect to that container
        # Otherwise, prompt the user to choose a container for binding
        lti_resource_id = payload["resource_link_id"]
        try:
            container = Container.objects.get(lti_resource=lti_resource_id)

            if LTI_CONFIG.get("auto_create_share_containers"):
                if container.owner != current_user_email and current_user_email not in container.sharing:
                    container.sharing.append(current_user_email)
                    container.save()

            return redirect(FRONTEND_DOMAIN + "?tkn=" + token + "&container=" +
                            str(container.id))
        except:
            if LTI_CONFIG.get("auto_create_share_containers"):
                container = Container(owner=current_user_email,
                                      code=payload["context_title"],
                                      lti_resource=payload["resource_link_id"],
                                      lti_context=payload["context_id"])
                container.save()

            return redirect(FRONTEND_DOMAIN + "?tkn=" + token + "&lti=" +
                            lti_resource_id)
Ejemplo n.º 36
0
def method_revise(request, pk):
    """
    Add a revision of an existing Method.  revision_parent is defined by the
    previous version.
    """
    t = loader.get_template('method/method.html')
    c = {}
    creating_user = request.user

    # Retrieve the most recent member of this Method's family.
    parent_method = Method.check_accessible(pk, creating_user)
    family = parent_method.family

    # Retrieve the most recent revision of the corresponding CR.
    parent_revision = parent_method.driver
    if not parent_revision:
        this_code_resource = None
        all_revisions = []
    else:
        this_code_resource = parent_revision.coderesource
        # Filter the available revisions by user.
        all_revisions = CodeResourceRevision.filter_by_user(
            creating_user,
            queryset=this_code_resource.revisions.all()).order_by('-revision_DateTime')

    parent_container = parent_method.container
    if not parent_container:
        this_container_family = None
        all_containers = []
    else:
        this_container_family = parent_container.family
        all_containers = Container.filter_by_user(
            creating_user,
            queryset=this_container_family.containers.all())

    if request.method == 'POST':
        # Because there is no CodeResource specified, the second value is of type MethodReviseForm.
        family_form, method_revise_form,\
            dep_forms, input_form_tuples,\
            output_form_tuples, _ = create_method_forms(request.POST, creating_user, family=family)
        if not _method_forms_check_valid(family_form, method_revise_form, dep_forms,
                                         input_form_tuples, output_form_tuples):
            # Bail out now if there are any problems.
            c.update(
                {
                    'coderesource': this_code_resource,
                    'containerfamily': this_container_family,
                    'method_revise_form': method_revise_form,
                    'dep_forms': dep_forms,
                    'input_forms': input_form_tuples,
                    'output_forms': output_form_tuples,
                    'family': family,
                    'family_form': family_form,
                    'parent': parent_method,
                    'docker_default': DockerImage.DEFAULT_IMAGE
                })
            return HttpResponse(t.render(c, request))

        # Next, attempt to build the Method and add it to family.
        create_method_from_forms(
            family_form, method_revise_form, dep_forms, input_form_tuples, output_form_tuples, creating_user,
            family=family, parent_method=parent_method
        )
        if _method_forms_check_valid(family_form, method_revise_form, dep_forms,
                                     input_form_tuples, output_form_tuples):
            # Success!
            return HttpResponseRedirect('/methods/{}'.format(family.pk))

    else:
        # Initialize forms with values of parent Method.
        family_form = MethodFamilyForm({"name": family.name, "description": family.description})
        parent_users_allowed = [x.username for x in parent_method.users_allowed.all()]
        parent_groups_allowed = [x.name for x in parent_method.groups_allowed.all()]
        method_revise_form = MethodReviseForm(
            initial={
                "revision_desc": parent_method.revision_desc,
                "driver_revisions": parent_revision and parent_revision.pk,
                "docker_image": parent_method.docker_image_id,
                "reusable": parent_method.reusable,
                "threads": parent_method.threads,
                "memory": parent_method.memory,
                "permissions": [parent_users_allowed, parent_groups_allowed]
            })

        dependencies = parent_method.dependencies.all()
        dep_forms = []
        for i, dependency in enumerate(dependencies):
            its_crv = dependency.requirement
            its_cr = its_crv.coderesource
            dep_form = MethodDependencyForm(
                user=creating_user,
                auto_id='id_%s_'+str(i),
                initial={
                    'coderesource': its_cr.pk,
                    'revisions': its_crv.pk,
                    'path': dependency.path,
                    'filename': dependency.filename
                }
            )
            dep_forms.append(dep_form)
        # If the parent Method has no dependencies, add a blank form.
        if len(dep_forms) == 0:
            dep_forms.append(MethodDependencyForm(user=creating_user, auto_id='id_%s_0'))

        xput_forms = []
        inputs = parent_method.inputs.order_by("dataset_idx")
        outputs = parent_method.outputs.order_by("dataset_idx")
        for xput_type, xputs in (("in", inputs), ("out", outputs)):
            forms = []
            for xput in xputs:
                tx_form = TransformationXputForm(auto_id='id_%s_{}_{}'.format(xput_type, len(forms)),
                                                 initial={'dataset_name': xput.dataset_name,
                                                          'dataset_idx': xput.dataset_idx})
                if xput.has_structure:
                    structure = xput.structure
                    xs_form = XputStructureForm(user=creating_user,
                                                auto_id='id_%s_{}_{}'.format(xput_type, len(forms)),
                                                initial={'compounddatatype': structure.compounddatatype.id,
                                                         'min_row': structure.min_row,
                                                         'max_row': structure.max_row})
                else:
                    xs_form = XputStructureForm(user=creating_user,
                                                auto_id='id_%s_{}_{}'.format(xput_type, len(forms)),
                                                initial={'compounddatatype': '__raw__'})

                forms.append((tx_form, xs_form))
            xput_forms.append(forms)

        input_form_tuples, output_form_tuples = xput_forms
        # if previous Method has no inputs, provide blank forms
        if len(input_form_tuples) == 0:
            tx_form = TransformationXputForm(auto_id='id_%s_in_0')
            xs_form = XputStructureForm(user=creating_user, auto_id='id_%s_in_0')
            input_form_tuples.append((tx_form, xs_form))

    method_revise_form.fields['driver_revisions'].widget.choices = [
        (str(x.id), '{}: {}'.format(x.revision_number, x.revision_name)) for x in all_revisions
    ]
    method_revise_form.fields['container'].widget.choices = [
        (str(x.id), x.tag) for x in all_containers]
    c.update(
        {
            'coderesource': this_code_resource,
            'containerfamily': this_container_family,
            'method_form': method_revise_form,
            'dep_forms': dep_forms,
            'input_forms': input_form_tuples,
            'output_forms': output_form_tuples,
            'family': family,
            'family_form': family_form,
            'parent': parent_method,
            'docker_default': DockerImage.DEFAULT_IMAGE
        }
    )
    return HttpResponse(t.render(c, request))