def stage_directory(self, dir_name):
        """
        Stage a project directory from a "general" directory
        :param dir_name: to stage from
        :return: a dictionary for project name -> staging id
        """
        known_projects = self.project_dir_repo.get_projects()

        matching_project = list(
            filter(lambda p: p.name == dir_name, known_projects))

        if not matching_project:
            raise ProjectNotFoundException(
                "Could not find a project with name: {}".format(dir_name))
        if len(matching_project) > 1:
            raise TooManyProjectsFound(
                "Found more than one project matching name: {}. This should"
                "not be possible...".format(dir()))

        exact_project = matching_project[0]

        staging_order = self.staging_repo.create_staging_order(
            source=exact_project.path,
            status=StagingStatus.pending,
            staging_target_dir=self.staging_dir)
        self.stage_order(staging_order)
        return {exact_project.name: staging_order.id}
    def stage_runfolder(self,
                        runfolder_id,
                        projects_to_stage=None,
                        callback=None):
        """
        Stage a runfolder
        :param runfolder_id: identifier (name) of runfolder that should be staged
        :param projects_to_stage: defaults to None, otherwise only stage the project names given in this list, i.e.
                                  ["ABC_123", "DEF_456"]
        :return: the ids of the stage orders created, as a dict of project -> stage id.
         This can than be used to poll for status using e.g. `get_status_of_stage_order`
        """

        runfolder = self.runfolder_repo.get_runfolder(runfolder_id)

        if not runfolder:
            raise RunfolderNotFoundException(
                "Couldn't find runfolder matching: {}".format(runfolder_id))

        names_of_project_on_runfolder = list(
            map(lambda x: x.name, runfolder.projects))

        # If no projects have been specified, stage all projects
        if not projects_to_stage:
            projects_to_stage = names_of_project_on_runfolder

        log.debug("Projects to stage: {}".format(projects_to_stage))

        if not self._validate_project_lists(names_of_project_on_runfolder,
                                            projects_to_stage):
            raise ProjectNotFoundException(
                "Projects to stage: {} do not match projects on runfolder: {}".
                format(projects_to_stage, names_of_project_on_runfolder))

        project_and_stage_order_ids = {}
        for project in runfolder.projects:
            if project.name in projects_to_stage:
                # TODO Verify that there is no currently ongoing staging order before
                # creating a new one...

                staging_order = self.staging_repo.create_staging_order(
                    source=project.path,
                    status=StagingStatus.pending,
                    staging_target_dir=self.staging_dir)
                log.debug("Created a staging order: {}".format(staging_order))
                self.stage_order(staging_order)
                project_and_stage_order_ids[project.name] = staging_order.id

        return project_and_stage_order_ids
示例#3
0
    def get_project(self, project_name):
        """
        TODO
        :param project_name:
        :return:
        """
        known_projects = self.get_projects()
        matching_project = list(filter(lambda p: p.name == project_name, known_projects))

        if not matching_project:
            raise ProjectNotFoundException("Could not find a project with name: {}".format(dir_name))
        if len(matching_project) > 1:
            raise TooManyProjectsFound("Found more than one project matching name: {}. This should"
                                       "not be possible...".format(dir()))

        exact_project = matching_project[0]
        return exact_project
    def find_projects_on_runfolder(self, runfolder_name, only_these_projects=None):
        runfolder = self.find_runfolder(runfolder_name)

        names_of_project_on_runfolder = list(map(lambda x: x.name, runfolder.projects))

        # If no projects have been specified, get all projects
        if only_these_projects:
            projects_to_return = only_these_projects
        else:
            projects_to_return = names_of_project_on_runfolder

        log.debug("Projects to stage: {}".format(projects_to_return))

        if not self._validate_project_lists(names_of_project_on_runfolder, projects_to_return):
            raise ProjectNotFoundException("Projects to stage: {} do not match projects on runfolder: {}".
                                           format(projects_to_return, names_of_project_on_runfolder))

        for project in runfolder.projects:
            if project.name in projects_to_return:
                yield project
示例#5
0
 def test_get_samples_unknown_project(self):
     self.general_project_repo.get_project.side_effect = ProjectNotFoundException(
     )
     response = self.fetch(self.API_BASE +
                           "/project/foo/best_practice_samples")
     self.assertEqual(response.code, 404)
    def deliver_all_runfolders_for_project(self, project_name, mode):
        """
        This method will attempt to deliver all runfolders for the specified project.

        Since the process is somewhat involved, here's a explanation of what's going on and why.

        First, there are three modes of delivery which needs to be handled. CLEAN, which denotes
        that this project is not allowed to be delivered previously. BATCH, which will deliver any
        runfolders which have not previously been delivered. And finally, FORCE, which will deliver
        all the runfolders regardless of their previous status.

        Two steps are then required to enable the staging, that require some explanation.
        Reading the code you will note that the _get_projects_to_deliver will create a
        DeliverySource and then a new DeliverySource will be created by this method. The reason
        for this is that since we create a intermediate directory in which links to all the
        runfolders which are to be delivered together are created. This directory is then passed
        as a DeliverySource when creating a new StagingOrder (which is goes on to be staged).

        :param project_name: of project to deliver
        :param mode: A DeliveryMode
        :return: a tupple with a dict with {<project name>: <staging order id>}, and the projects
        """
        projects = list(
            self.runfolder_service.find_runfolders_for_project(project_name))

        if len(projects) < 1:
            raise ProjectNotFoundException(
                "Could not find any Project "
                "folders for project name: {}".format(project_name))

        max_batch_nbr = self.delivery_sources_repo.find_highest_batch_nbr(
            project_name)
        if not max_batch_nbr:
            batch_nbr = 1
        else:
            batch_nbr = max_batch_nbr + 1

        projects_to_deliver = list(
            self._get_projects_to_deliver(projects, mode, batch_nbr))

        if not projects_to_deliver:
            raise ProjectAlreadyDeliveredException(
                "All runfolders for this project has already "
                "been delivered.")

        log.debug("The following projects were to be delivered: {}".format(
            projects_to_deliver))
        log.debug("This will be batch nbr: {}".format(batch_nbr))

        links_directory = self._create_links_area_for_project_runfolders(
            project_name, projects_to_deliver, batch_nbr)
        source = self.delivery_sources_repo.create_source(
            project_name=project_name,
            source_name="{}/batch{}".format(project_name, batch_nbr),
            path=links_directory,
            batch_nbr=batch_nbr)

        self.delivery_sources_repo.add_source(source)

        stage_order = self.staging_service.create_new_stage_order(
            path=source.path, project_name=project_name)
        self.staging_service.stage_order(stage_order)
        return {source.project_name: stage_order.id}, projects_to_deliver