Esempio n. 1
0
    def get_popular_projects() -> ProjectSearchResultsDTO:
        """ Get all projects ordered by task_history """

        rate_func = func.count(TaskHistory.user_id) / extract(
            "epoch", func.sum(cast(TaskHistory.action_date, Time))
        )

        query = (
            TaskHistory.query.with_entities(
                TaskHistory.project_id.label("id"), rate_func.label("rate")
            )
            .filter(TaskHistory.action_date >= date.today() - timedelta(days=90))
            .filter(
                or_(
                    TaskHistory.action == TaskAction.LOCKED_FOR_MAPPING.name,
                    TaskHistory.action == TaskAction.LOCKED_FOR_VALIDATION.name,
                )
            )
            .filter(TaskHistory.action_text is not None)
            .filter(TaskHistory.action_text != "")
            .group_by(TaskHistory.project_id)
            .order_by(desc("rate"))
            .limit(10)
            .subquery()
        )

        projects_query = ProjectSearchService.create_search_query()
        projects = projects_query.filter(Project.id == query.c.id).all()
        # Get total contributors.
        contrib_counts = ProjectSearchService.get_total_contributions(projects)
        zip_items = zip(projects, contrib_counts)

        dto = ProjectSearchResultsDTO()
        dto.results = [
            ProjectSearchService.create_result_dto(p, "en", t) for p, t in zip_items
        ]

        return dto
Esempio n. 2
0
    def test_get_area_from_3857_bbox(self):
        # polygon = ProjectSearchService._make_4326_polygon_from_bbox(
        #   [3618104.193026841, -1413969.7644834695, 3861479.691086842, -1297785.4814900015], 3857)
        polygon = Polygon([
            (34.68826225820438, -12.59912449955007),
            (34.68826225820438, -11.57858317689196),
            (32.50198296132938, -11.57858317689196),
            (32.50198296132938, -12.59912449955007),
            (34.68826225820438, -12.59912449955007),
        ])

        # act
        expected = ProjectSearchService._get_area_sqm(polygon)

        # assert
        self.assertAlmostEqual(expected, 28276407740.2797, places=3)
Esempio n. 3
0
    def test_make_polygon_from_3857_bbox(self):

        # arrange
        expected = (
            32.50198296132938,
            -12.59912449955007,
            34.68826225820438,
            -11.578583176891955,
        )

        # act
        polygon = ProjectSearchService._make_4326_polygon_from_bbox(
            [
                3618104.193026841,
                -1413969.7644834695,
                3861479.691086842,
                -1297785.4814900015,
            ],
            3857,
        )

        # assert
        for expected_val, actual_val in zip(expected, polygon.bounds):
            self.assertAlmostEqual(expected_val, actual_val, places=10)
 def get_projects_for_admin(admin_id: int, preferred_locale: str,
                            search_dto: ProjectSearchDTO):
     """ Get all projects for provided admin """
     ProjectSearchService.create_search_query()
     return Project.get_projects_for_admin(admin_id, preferred_locale,
                                           search_dto)
Esempio n. 5
0
    def get(self):
        """
        List and search projects by bounding box
        ---
        tags:
            - projects
        produces:
            - application/json
        parameters:
            - in: header
              name: Authorization
              description: Base64 encoded session token
              required: true
              type: string
              default: Token sessionTokenHere==
            - in: header
              name: Accept-Language
              description: Language user is requesting
              type: string
              default: en
            - in: query
              name: bbox
              description: comma separated list xmin, ymin, xmax, ymax
              type: string
              required: true
              default: 34.404,-1.034, 34.717,-0.624
            - in: query
              name: srid
              description: srid of bbox coords
              type: integer
              default: 4326
            - in: query
              name: createdByMe
              description: limit to projects created by authenticated user
              type: boolean
              required: true
              default: false

        responses:
            200:
                description: ok
            400:
                description: Client Error - Invalid Request
            403:
                description: Forbidden
            500:
                description: Internal Server Error
        """
        try:
            authenticated_user_id = token_auth.current_user()
            orgs_dto = OrganisationService.get_organisations_managed_by_user_as_dto(
                authenticated_user_id
            )
            if len(orgs_dto.organisations) < 1:
                raise ValueError("User not a project manager")
        except ValueError as e:
            error_msg = f"ProjectsQueriesBboxAPI GET: {str(e)}"
            return {"Error": error_msg}, 403

        try:
            search_dto = ProjectSearchBBoxDTO()
            search_dto.bbox = map(float, request.args.get("bbox").split(","))
            search_dto.input_srid = request.args.get("srid")
            search_dto.preferred_locale = request.environ.get("HTTP_ACCEPT_LANGUAGE")
            created_by_me = (
                strtobool(request.args.get("createdByMe"))
                if request.args.get("createdByMe")
                else False
            )
            if created_by_me:
                search_dto.project_author = authenticated_user_id
            search_dto.validate()
        except Exception as e:
            current_app.logger.error(f"Error validating request: {str(e)}")
            return {"Error": "Unable to fetch projects"}, 400
        try:
            geojson = ProjectSearchService.get_projects_geojson(search_dto)
            return geojson, 200
        except BBoxTooBigError:
            return {"Error": "Bounding Box too large"}, 403
        except ProjectSearchServiceError:
            return {"Error": "Unable to fetch projects"}, 400
        except Exception as e:
            error_msg = f"ProjectsQueriesBboxAPI GET - unhandled error: {str(e)}"
            current_app.logger.critical(error_msg)
            return {"Error": "Unable to fetch projects"}, 500
Esempio n. 6
0
 def get(self):
     """
     List and search for projects
     ---
     tags:
         - projects
     produces:
         - application/json
     parameters:
         - in: header
           name: Authorization
           description: Base64 encoded session token
           type: string
           default: Token sessionTokenHere==
         - in: header
           name: Accept-Language
           description: Language user is requesting
           type: string
           required: true
           default: en
         - in: query
           name: mapperLevel
           type: string
         - in: query
           name: orderBy
           type: string
           default: priority
           enum: [id,mapper_level,priority,status,last_updated,due_date]
         - in: query
           name: orderByType
           type: string
           default: ASC
           enum: [ASC, DESC]
         - in: query
           name: mappingTypes
           type: string
         - in: query
           name: mappingTypesExact
           type: boolean
           default: false
           description: if true, limits projects to match the exact mapping types requested
         - in: query
           name: organisationName
           description: Organisation name to search for
           type: string
         - in: query
           name: organisationId
           description: Organisation ID to search for
           type: integer
         - in: query
           name: campaign
           description: Campaign name to search for
           type: string
         - in: query
           name: page
           description: Page of results user requested
           type: integer
           default: 1
         - in: query
           name: textSearch
           description: Text to search
           type: string
         - in: query
           name: country
           description: Project country
           type: string
         - in: query
           name: action
           description: Filter projects by possible actions
           enum: [map, validate, any]
           type: string
         - in: query
           name: projectStatuses
           description: Authenticated PMs can search for archived or draft statuses
           type: string
         - in: query
           name: interests
           type: string
           description: Filter by interest on project
           default: null
         - in: query
           name: createdByMe
           description: Limit to projects created by the authenticated user
           type: boolean
           default: false
         - in: query
           name: mappedByMe
           description: Limit to projects mapped/validated by the authenticated user
           type: boolean
           default: false
         - in: query
           name: favoritedByMe
           description: Limit to projects favorited by the authenticated user
           type: boolean
           default: false
         - in: query
           name: managedByMe
           description:
             Limit to projects that can be managed by the authenticated user,
             excluding the ones created by them
           type: boolean
           default: false
         - in: query
           name: teamId
           type: string
           description: Filter by team on project
           default: null
           name: omitMapResults
           type: boolean
           description: If true, it will not return the project centroid's geometries.
           default: false
     responses:
         200:
             description: Projects found
         404:
             description: No projects found
         500:
             description: Internal Server Error
     """
     try:
         user = None
         user_id = token_auth.current_user()
         if user_id:
             user = UserService.get_user_by_id(user_id)
         search_dto = self.setup_search_dto()
         results_dto = ProjectSearchService.search_projects(search_dto, user)
         return results_dto.to_primitive(), 200
     except NotFound:
         return {"mapResults": {}, "results": []}, 200
     except Exception as e:
         error_msg = f"Project GET - unhandled error: {str(e)}"
         current_app.logger.critical(error_msg)
         return {"Error": "Unable to fetch projects"}, 500