def get_project_by_id(project_id: int) -> Project:
        project = Project.get(project_id)

        if project is None:
            raise NotFound()

        return project
    def test_project_can_be_cloned(self):

        if self.skip_tests:
            return

        # Arrange
        self.update_project_with_info()

        # Act
        original_id = copy.copy(self.test_project.id)
        cloned_project = Project.clone(original_id, self.test_user.id)

        self.assertTrue(cloned_project)
        self.assertEqual(cloned_project.project_info[0].name,
                         'Thinkwhere Test')

        # Tidy Up
        cloned_project.delete()
        original_project = Project.get(
            original_id
        )  # SQLAlchemy is hanging on to a ref to the old project
        original_project.delete()
    def transfer_project_to(project_id: int, transfering_user_id: int, username: str):
        """ Transfers project from old owner (transfering_user_id) to new owner (username) """
        project = Project.get(project_id)

        transfering_user = UserService.get_user_by_id(transfering_user_id)
        new_owner = UserService.get_user_by_username(username)
        is_pm = new_owner.role in (UserRole.PROJECT_MANAGER.value, UserRole.ADMIN.value)

        if not is_pm:
            raise Exception("User must be a project manager")

        if transfering_user.role == UserRole.PROJECT_MANAGER.value:
            if project.author_id == transfering_user_id:
                project.author_id = new_owner.id
                project.save()
            else:
                raise Exception("Invalid owner_id")
        elif transfering_user.role == UserRole.ADMIN.value:
            project.author_id = new_owner.id
            project.save()
        else:
            raise Exception("Normal users cannot transfer projects")
Esempio n. 4
0
    def split_task(split_task_dto: SplitTaskDTO) -> TaskDTOs:
        """
        Replaces a task square with 4 smaller tasks at the next OSM tile grid zoom level
        Validates that task is:
         - locked for mapping by current user
         - splittable (splittable property is True)
        :param split_task_dto:
        :return: new tasks in a DTO
        """
        # get the task to be split
        original_task = Task.get(split_task_dto.task_id,
                                 split_task_dto.project_id)
        if original_task is None:
            raise NotFound()

        # check it's splittable
        if not original_task.splittable:
            raise SplitServiceError('Task is not splittable')

        # check its locked for mapping by the current user
        if TaskStatus(
                original_task.task_status) != TaskStatus.LOCKED_FOR_MAPPING:
            raise SplitServiceError(
                'Status must be LOCKED_FOR_MAPPING to split')

        if original_task.locked_by != split_task_dto.user_id:
            raise SplitServiceError(
                'Attempting to split a task owned by another user')

        # create new geometries from the task geometry
        try:
            new_tasks_geojson = SplitService._create_split_tasks(
                original_task.x, original_task.y, original_task.zoom)
        except Exception as e:
            raise SplitServiceError(f'Error splitting task{str(e)}')

        # create new tasks from the new geojson
        i = Task.get_max_task_id_for_project(split_task_dto.project_id)
        new_tasks_dto = []
        for new_task_geojson in new_tasks_geojson:
            # insert new tasks into database
            i = i + 1
            new_task = Task.from_geojson_feature(i, new_task_geojson)
            new_task.project_id = split_task_dto.project_id
            new_task.task_status = TaskStatus.READY.value
            new_task.create()
            new_task.task_history.extend(original_task.copy_task_history())
            if new_task.task_history:
                new_task.clear_task_lock()  # since we just copied the lock
            new_task.set_task_history(TaskAction.STATE_CHANGE,
                                      split_task_dto.user_id, None,
                                      TaskStatus.SPLIT)
            new_task.set_task_history(TaskAction.STATE_CHANGE,
                                      split_task_dto.user_id, None,
                                      TaskStatus.READY)
            new_task.task_status = TaskStatus.READY.value
            new_task.update()
            new_tasks_dto.append(
                new_task.as_dto_with_instructions(
                    split_task_dto.preferred_locale))

        # delete original task from the database
        original_task.delete()

        # update project task counts
        project = Project.get(split_task_dto.project_id)
        project.total_tasks = project.tasks.count()
        # update bad imagery because we may have split a bad imagery tile
        project.tasks_bad_imagery = project.tasks.filter(
            Task.task_status == TaskStatus.BADIMAGERY.value).count()
        project.save()

        # return the new tasks in a DTO
        task_dtos = TaskDTOs()
        task_dtos.tasks = new_tasks_dto
        return task_dtos