예제 #1
0
def create_canned_project() -> Tuple[Project, User]:
    """ Generates a canned project in the DB to help with integration tests """
    test_aoi_geojson = geojson.loads(json.dumps(get_canned_json("test_aoi.json")))

    task_feature = geojson.loads(json.dumps(get_canned_json("splittable_task.json")))
    task_non_square_feature = geojson.loads(
        json.dumps(get_canned_json("non_square_task.json"))
    )

    test_user = create_canned_user()

    test_project_dto = DraftProjectDTO()
    test_project_dto.project_name = "Test"
    test_project_dto.user_id = test_user.id
    test_project_dto.area_of_interest = test_aoi_geojson
    test_project = Project()
    test_project.create_draft_project(test_project_dto)
    test_project.set_project_aoi(test_project_dto)
    test_project.total_tasks = 2

    # Setup test task
    test_task = Task.from_geojson_feature(1, task_feature)
    test_task.task_status = TaskStatus.MAPPED.value
    test_task.mapped_by = test_user.id
    test_task.is_square = True

    test_task2 = Task.from_geojson_feature(2, task_non_square_feature)
    test_task2.task_status = TaskStatus.READY.value
    test_task2.is_square = False

    test_project.tasks.append(test_task)
    test_project.tasks.append(test_task2)
    test_project.create()

    return test_project, test_user
    def test_feature_collection_multi_polygon_with_zcoord_nodissolve(self):
        # arrange
        project_json = get_canned_json("canned_kml_project.json")
        project_dto = DraftProjectDTO(project_json)
        expected = geojson.loads(json.dumps(get_canned_json("2d_multi_polygon.json")))
        aoi_geojson = geojson.loads(json.dumps(project_dto.area_of_interest))

        # act
        result = GridService.merge_to_multi_polygon(aoi_geojson, dissolve=False)

        # assert
        self.assertEqual(str(expected), str(result))
    def create_draft_project(draft_project_dto: DraftProjectDTO) -> int:
        """
        Validates and then persists draft projects in the DB
        :param draft_project_dto: Draft Project DTO with data from API
        :raises InvalidGeoJson
        :returns ID of new draft project
        """
        user_id = draft_project_dto.user_id
        is_admin = UserService.is_user_an_admin(user_id)
        user_orgs = OrganisationService.get_organisations_managed_by_user_as_dto(
            user_id)
        is_org_manager = len(user_orgs.organisations) > 0

        # First things first, we need to validate that the author_id is a PM. issue #1715
        if not (is_admin or is_org_manager):
            user = UserService.get_user_by_id(user_id)
            raise (ProjectAdminServiceError(
                f"User {user.username} is not permitted to create project"))

        # If we're cloning we'll copy all the project details from the clone, otherwise create brand new project
        if draft_project_dto.cloneFromProjectId:
            draft_project = Project.clone(draft_project_dto.cloneFromProjectId,
                                          user_id)
        else:
            draft_project = Project()
            org = OrganisationService.get_organisation_by_id(
                draft_project_dto.organisation)
            if org is None:
                raise NotFound("Organisation does not exist")
            draft_project_dto.organisation = org
            draft_project.create_draft_project(draft_project_dto)

        draft_project.set_project_aoi(draft_project_dto)

        # if arbitrary_tasks requested, create tasks from aoi otherwise use tasks in DTO
        if draft_project_dto.has_arbitrary_tasks:
            tasks = GridService.tasks_from_aoi_features(
                draft_project_dto.area_of_interest)
            draft_project.task_creation_mode = TaskCreationMode.ARBITRARY.value
        else:
            tasks = draft_project_dto.tasks
        ProjectAdminService._attach_tasks_to_project(draft_project, tasks)

        if draft_project_dto.cloneFromProjectId:
            draft_project.save()  # Update the clone
        else:
            draft_project.create()  # Create the new project

        draft_project.set_default_changeset_comment()
        draft_project.set_country_info()
        return draft_project.id
예제 #4
0
    def post(self):
        """
        Creates a tasking-manager project
        ---
        tags:
            - projects
        produces:
            - application/json
        parameters:
            - in: header
              name: Authorization
              description: Base64 encoded session token
              required: true
              type: string
              default: Token sessionTokenHere==
            - in: body
              name: body
              required: true
              description: JSON object for creating draft project
              schema:
                properties:
                    cloneFromProjectId:
                        type: int
                        default: 1
                        description: Specify this value if you want to clone a project, otherwise avoid information
                    projectName:
                        type: string
                        default: HOT Project
                    areaOfInterest:
                        schema:
                            properties:
                                type:
                                    type: string
                                    default: FeatureCollection
                                features:
                                    type: array
                                    items:
                                        schema:
                                            $ref: "#/definitions/GeoJsonFeature"
                        tasks:
                            schema:
                                properties:
                                    type:
                                        type: string
                                        default: FeatureCollection
                                    features:
                                        type: array
                                        items:
                                            schema:
                                                $ref: "#/definitions/GeoJsonFeature"
                        arbitraryTasks:
                            type: boolean
                            default: false
        responses:
            201:
                description: Draft project created successfully
            400:
                description: Client Error - Invalid Request
            401:
                description: Unauthorized - Invalid credentials
            403:
                description: Forbidden
            500:
                description: Internal Server Error
        """
        try:
            draft_project_dto = DraftProjectDTO(request.get_json())
            draft_project_dto.user_id = token_auth.current_user()
            draft_project_dto.validate()
        except DataError as e:
            current_app.logger.error(f"error validating request: {str(e)}")
            return {"Error": "Unable to create project"}, 400

        try:
            draft_project_id = ProjectAdminService.create_draft_project(
                draft_project_dto
            )
            return {"projectId": draft_project_id}, 201
        except ProjectAdminServiceError as e:
            return {"Error": str(e)}, 403
        except (InvalidGeoJson, InvalidData):
            return {"Error": "Invalid GeoJson"}, 400
        except Exception as e:
            error_msg = f"Project PUT - unhandled error: {str(e)}"
            current_app.logger.critical(error_msg)
            return {"Error": "Unable to create project"}, 500