def get_municipalities():
    """List all enabled municipalities
        ---
        tags:
          - Reférentiel géo
        definitions:
          area_name:
            type: string
            description: Municipality name
          area_code:
            type: string
            description: Municipality insee code
          geometry:
            type: geometry
        responses:
          200:
            description: A list of municipalities
        """
    try:
        q = db.session.query(
            LAreas.area_name, LAreas.area_code,
            func.ST_Transform(LAreas.geom, 4326).label('geom')).filter(
                LAreas.enable, LAreas.id_type == 101)
        datas = q.all()
        features = []
        for data in datas:
            feature = get_geojson_feature(data.geom)
            feature['properties']['area_name'] = data.area_name
            feature['properties']['area_code'] = data.area_code
            features.append(feature)
        return FeatureCollection(features)
    except Exception as e:
        return {'message': str(e)}, 400
def observations2features4export(
    records: List[ObservationRecord4Export],
) -> Optional[List[Feature]]:
    features: List[Feature] = []
    for record in records:
        feature: Feature = get_geojson_feature(record.ObservationModel.geom)
        feature["properties"].update(
            record.ObservationModel.as_dict(
                True, ("id_observation", "uuid_sinp", *obs_keys)
            )
        )
        feature["properties"]["nom_complet"] = record.nom_complet
        feature["properties"]["nom_vern"] = record.nom_vern
        feature["properties"]["municipality_name"] = record.area_name
        feature["properties"]["municipality_insee"] = record.municipality_insee
        feature["properties"]["observer"] = (
            record.__getattribute__("username") or "Anonymous"
        )
        feature["properties"]["image"] = (
            "/".join(
                [
                    current_app.config["API_ENDPOINT"],
                    current_app.config["MEDIA_FOLDER"],
                    record.image,
                ]
            )
            if record.image
            else ""
        )
        features.append(feature)
    return features
def observations2features4front(
    records: List[ObservationRecord4Program],
) -> Optional[List[Feature]]:
    features: List[Feature] = []
    for record in records:
        feature: Feature = get_geojson_feature(record.ObservationModel.geom)
        feature["properties"].update(record.ObservationModel.as_dict(True, obs_keys))
        feature["properties"]["municipality"] = {
            "name": record.area_name,
            "code": record.area_code,
        }
        feature["properties"]["observer"] = {"username": record.username}
        feature["properties"]["image"] = (
            "/".join(
                [
                    current_app.config["API_ENDPOINT"],
                    current_app.config["MEDIA_FOLDER"],
                    record.image,
                ]
            )
            if record.image
            else None
        )
        features.append(feature)
    return features
Exemple #4
0
def get_observations_from_list(id):  # noqa: A002
    """Get all observations from a taxonomy list
    GET
        ---
        tags:
          - observations
        parameters:
          - name: id
            in: path
            type: integer
            required: true
            example: 1
        definitions:
          cd_nom:
            type: integer
            description: cd_nom taxref
          geometry:
            type: dict
            description: Géométrie de la donnée
          name:
            type: string
          geom:
            type: geometry
        responses:
          200:
            description: A list of all species lists
        """
    # taxhub_url = load_config()['TAXHUB_API_URL']
    taxhub_lists_taxa_url = taxhub_lists_url + "taxons/" + str(id)
    rtaxa = requests.get(taxhub_lists_taxa_url)
    if rtaxa.status_code == 200:
        try:
            taxa = rtaxa.json()["items"]
            current_app.logger.debug(taxa)
            features = []
            for t in taxa:
                current_app.logger.debug("R", t["cd_nom"])
                datas = (ObservationModel.query.filter_by(
                    cd_nom=t["cd_nom"]).order_by(
                        desc(ObservationModel.timestamp_create)).all())
                for d in datas:
                    feature = get_geojson_feature(d.geom)
                    observation_dict = d.as_dict(True)
                    for k in observation_dict:
                        if k in obs_keys:
                            feature["properties"][k] = observation_dict[k]
                    taxref = get_specie_from_cd_nom(
                        feature["properties"]["cd_nom"])
                    for k in taxref:
                        feature["properties"][k] = taxref[k]
                    features.append(feature)
            return FeatureCollection(features)
        except Exception as e:
            current_app.logger.critical(
                "[get_observations_from_list] Error: %s", str(e))
            return {"message": str(e)}, 400
def format_site(site, dashboard=False):
    feature = get_geojson_feature(site.geom)
    site_dict = site.as_dict(True)
    for k in site_dict:
        if k not in ("geom", ):
            feature["properties"][k] = site_dict[k]
    if dashboard:
        # Site creator can delete it only if no visit have been added by others
        feature["properties"]["creator_can_delete"] = (
            site.id_role
            and VisitModel.query.filter_by(id_site=site.id_site).filter(
                or_(VisitModel.id_role != site.id_role,
                    VisitModel.id_role.is_(None))).count() == 0)
    return feature
Exemple #6
0
def get_observations():
    """Get all observations
        ---
        tags:
          - observations
        definitions:
          cd_nom:
            type: integer
            description: cd_nom taxref
          geometry:
            type: dict
            description: Géométrie de la donnée
          name:
            type: string
          geom:
            type: geometry
        responses:
          200:
            description: A list of all observations
        """
    try:
        observations = ObservationModel.query.order_by(
            ObservationModel.timestamp_create.desc()
        ).all()
        features = []
        for observation in observations:
            feature = get_geojson_feature(observation.geom)
            observation_dict = observation.as_dict(True)
            for k in observation_dict:
                if k in obs_keys:
                    feature["properties"][k] = observation_dict[k]

            taxref = get_specie_from_cd_nom(feature["properties"]["cd_nom"])
            for k in taxref:
                feature["properties"][k] = taxref[k]
            features.append(feature)
        return FeatureCollection(features)
    except Exception as e:
        current_app.logger.critical("[get_observations] Error: %s", str(e))
        return {"message": str(e)}, 400
def export_sites_xls(user_id):
    current_user = get_jwt_identity()
    try:
        if current_user != UserModel.query.get(user_id).email:
            return ("unauthorized"), 403
        title_style = xlwt.easyxf("font: bold on")
        date_style = xlwt.easyxf(num_format_str="D/M/YY")
        wb = xlwt.Workbook()
        # SITES SHEET
        ws = wb.add_sheet("mes sites")
        sites = _get_user_sites(user_id)
        fields = (
            {
                "col_name": "id_site",
                "getter": lambda s: s.id_site
            },
            {
                "col_name": "Programme",
                "getter": lambda s: s.program.title
            },
            {
                "col_name": "Type",
                "getter": lambda s: s.site_type.type
            },
            {
                "col_name": "Nom",
                "getter": lambda s: s.name
            },
            {
                "col_name": "Coord. x",
                "getter": lambda s: s.coordinates[0]
            },
            {
                "col_name": "Coord. y",
                "getter": lambda s: s.coordinates[1]
            },
            {
                "col_name": "Date création",
                "getter": lambda s: s.timestamp_create,
                "style": date_style,
            },
        )
        row = 0
        for col, field in enumerate(fields):
            ws.write(row, col, field["col_name"], title_style)
        row += 1
        for site in sites:
            site.coordinates = get_geojson_feature(
                site.geom)["geometry"]["coordinates"]
            for col, field in enumerate(fields):
                args = []
                if field.get("style"):
                    args.append(field.get("style"))
                ws.write(row, col, field["getter"](site), *args)
            row += 1
        # VISITS SHEET
        ws = wb.add_sheet("mes visites")
        visits = VisitModel.query.filter_by(id_role=user_id)
        basic_fields = (
            {
                "col_name": "id_visit",
                "getter": lambda s: s.id_visit
            },
            {
                "col_name": "Site",
                "getter": lambda s: s.site.name
            },
            {
                "col_name": "Date",
                "getter": lambda s: s.date,
                "style": date_style
            },
        )
        json_keys = list(
            set([key for v in visits for key in v.json_data.keys()]))
        row, col = 0, 0
        for field in basic_fields:
            ws.write(row, col, field["col_name"], title_style)
            col += 1
        for key in json_keys:
            ws.write(row, col, key, title_style)
            col += 1
        row, col = 1, 0
        for visit in visits:
            for field in basic_fields:
                args = []
                if field.get("style"):
                    args.append(field.get("style"))
                ws.write(row, col, field["getter"](visit), *args)
                col += 1
            for key in json_keys:
                ws.write(row, col, visit.json_data.get(key))
                col += 1
            row += 1
            col = 0
        # In memory save and return xls file
        xls_file = io.BytesIO()
        wb.save(xls_file)
        output = make_response(xls_file.getvalue())
        output.headers["Content-Disposition"] = ("attachment; filename=" +
                                                 "export_sites.xls")
        output.headers["Content-type"] = "application/xls"
        return output
    except Exception as e:
        current_app.logger.warning("Error: %s", str(e))
        return {"error_message": str(e)}, 400
Exemple #8
0
def get_observations_by_user_id(user_id):
    try:
        observations = (db.session.query(
            ObservationModel,
            ProgramsModel,
            UserModel.username,
            func.json_agg(
                func.json_build_array(MediaModel.filename,
                                      MediaModel.id_media)).label("images"),
            LAreas.area_name,
            LAreas.area_code,
        ).filter(ObservationModel.id_role == user_id).join(
            LAreas,
            LAreas.id_area == ObservationModel.municipality,
            isouter=True).join(
                ProgramsModel,
                ProgramsModel.id_program == ObservationModel.id_program,
                isouter=True,
                full=True,
            ).join(
                ObservationMediaModel,
                ObservationMediaModel.id_data_source ==
                ObservationModel.id_observation,
                isouter=True,
            ).join(
                MediaModel,
                ObservationMediaModel.id_media == MediaModel.id_media,
                isouter=True,
            ).join(UserModel,
                   ObservationModel.id_role == UserModel.id_user,
                   full=True).group_by(
                       ObservationModel.id_observation,
                       ProgramsModel.id_program,
                       UserModel.username,
                       LAreas.area_name,
                       LAreas.area_code,
                   ))

        observations = observations.order_by(
            desc(ObservationModel.timestamp_create))
        # current_app.logger.debug(str(observations))
        observations = observations.all()

        try:
            if current_app.config.get("API_TAXHUB") is not None:
                taxon_repository = []
                taxhub_list_id = []
                for observation in observations:
                    if observation.ProgramsModel.taxonomy_list not in taxhub_list_id:
                        taxhub_list_id.append(
                            observation.ProgramsModel.taxonomy_list)
                for tax_list in taxhub_list_id:
                    taxon_repository.append(mkTaxonRepository(tax_list))

            features = []
        except Exception as e:
            return {"message": str(e)}, 500

        for observation in observations:
            feature = get_geojson_feature(observation.ObservationModel.geom)
            feature["properties"]["municipality"] = {
                "name": observation.area_name,
                "code": observation.area_code,
            }

            # Observer
            feature["properties"]["observer"] = {
                "username": observation.username
            }
            # Observer submitted media
            feature["properties"]["image"] = ("/".join([
                "/api",
                current_app.config["MEDIA_FOLDER"],
                observation.images[0][0],
            ]) if observation.images and observation.images != [[None, None]]
                                              else None)
            # Photos
            feature["properties"]["photos"] = [{
                "url":
                "/media/{}".format(filename),
                "id_media":
                id_media
            } for filename, id_media in observation.images
                                               if id_media is not None]
            # Municipality
            observation_dict = observation.ObservationModel.as_dict(True)
            for k in observation_dict:
                if k in obs_keys and k != "municipality":
                    feature["properties"][k] = observation_dict[k]
            # Program
            program_dict = observation.ProgramsModel.as_dict(True)
            for program in program_dict:
                if program == "title":
                    feature["properties"]["program_title"] = program_dict[
                        program]
            # TaxRef
            if current_app.config.get("API_TAXHUB") is None:
                taxref = Taxref.query.filter(Taxref.cd_nom == observation.
                                             ObservationModel.cd_nom).first()
                if taxref:
                    feature["properties"]["taxref"] = taxref.as_dict(True)

                medias = TMedias.query.filter(TMedias.cd_ref == observation.
                                              ObservationModel.cd_nom).all()
                if medias:
                    feature["properties"]["medias"] = [
                        media.as_dict(True) for media in medias
                    ]
            else:
                try:
                    for taxon_rep in taxon_repository:
                        for taxon in taxon_rep:
                            if (taxon["taxref"]["cd_nom"] ==
                                    observation.ObservationModel.cd_nom):
                                feature["properties"]["nom_francais"] = taxon[
                                    "nom_francais"]
                                feature["properties"]["taxref"] = taxon[
                                    "taxref"]
                                feature["properties"]["medias"] = taxon[
                                    "medias"]

                except StopIteration:
                    pass
            features.append(feature)

        return FeatureCollection(features), 200

    except Exception as e:
        raise e
        current_app.logger.critical("[get_program_observations] Error: %s",
                                    str(e))
        return {"message": str(e)}, 400
Exemple #9
0
def get_all_observations() -> Union[FeatureCollection, Tuple[Dict, int]]:
    """Get all observations from all programs
    GET
        ---
        tags:
          - observations
        responses:
          200:
            description: A list of all species lists
        """
    try:
        observations = (db.session.query(
            ObservationModel,
            UserModel.username,
            MediaModel.filename.label("image"),
            LAreas.area_name,
            LAreas.area_code,
        ).filter(ProgramsModel.is_active).join(
            LAreas,
            LAreas.id_area == ObservationModel.municipality,
            isouter=True).join(
                ProgramsModel,
                ProgramsModel.id_program == ObservationModel.id_program,
                isouter=True,
            ).join(
                ObservationMediaModel,
                ObservationMediaModel.id_data_source ==
                ObservationModel.id_observation,
                isouter=True,
            ).join(
                MediaModel,
                ObservationMediaModel.id_media == MediaModel.id_media,
                isouter=True,
            ).join(UserModel,
                   ObservationModel.id_role == UserModel.id_user,
                   full=True))

        observations = observations.order_by(
            desc(ObservationModel.timestamp_create))
        # current_app.logger.debug(str(observations))
        observations = observations.all()

        # loop to retrieve taxonomic data from all programs
        if current_app.config.get("API_TAXHUB") is not None:
            programs = ProgramsModel.query.all()
            taxon_repository = []
            for program in programs:
                taxhub_list_id = (ProgramsModel.query.filter_by(
                    id_program=program.id_program).one().taxonomy_list)
                taxon_data = mkTaxonRepository(taxhub_list_id)
                try:
                    for taxon in taxon_data:
                        if taxon not in taxon_repository:
                            taxon_repository.append(taxon)
                except Exception as e:
                    current_app.logger.critical(str(e))

        features = []
        for observation in observations:
            feature = get_geojson_feature(observation.ObservationModel.geom)
            feature["properties"]["municipality"] = {
                "name": observation.area_name,
                "code": observation.area_code,
            }

            # Observer
            feature["properties"]["observer"] = {
                "username": observation.username
            }

            # Observer submitted media
            feature["properties"]["image"] = ("/".join([
                "/api",
                current_app.config["MEDIA_FOLDER"],
                observation.image,
            ]) if observation.image else None)

            # Municipality
            observation_dict = observation.ObservationModel.as_dict(True)
            for k in observation_dict:
                if k in obs_keys and k != "municipality":
                    feature["properties"][k] = observation_dict[k]

            # TaxRef
            if current_app.config.get("API_TAXHUB") is None:
                taxref = Taxref.query.filter(Taxref.cd_nom == observation.
                                             ObservationModel.cd_nom).first()
                if taxref:
                    feature["properties"]["taxref"] = taxref.as_dict(True)

                medias = TMedias.query.filter(TMedias.cd_ref == observation.
                                              ObservationModel.cd_nom).all()
                if medias:
                    feature["properties"]["medias"] = [
                        media.as_dict(True) for media in medias
                    ]
            else:
                try:
                    taxon = next(
                        taxon for taxon in taxon_repository if taxon
                        and taxon["cd_nom"] == feature["properties"]["cd_nom"])
                    feature["properties"]["taxref"] = taxon["taxref"]
                    feature["properties"]["medias"] = taxon["medias"]
                except StopIteration:
                    pass
            features.append(feature)

        return FeatureCollection(features)

    except Exception as e:
        # if current_app.config["DEBUG"]:
        # import traceback
        # import sys

        # import pdb
        # pdb.set_trace()
        # etype, value, tb = sys.exc_info()
        # trace = str(traceback.print_exception(etype, value, tb))
        # trace = traceback.format_exc()
        # return("<pre>" + trace + "</pre>"), 500
        raise e
        current_app.logger.critical("[get_program_observations] Error: %s",
                                    str(e))
        return {"message": str(e)}, 400
Exemple #10
0
def generate_observation_geojson(id_observation):
    """generate observation in geojson format from observation id

      :param id_observation: Observation unique id
      :type id_observation: int

      :return features: Observations as a Feature dict
      :rtype features: dict
    """

    # Crée le dictionnaire de l'observation
    observation = (db.session.query(
        ObservationModel, UserModel.username, LAreas.area_name,
        LAreas.area_code).join(
            UserModel,
            ObservationModel.id_role == UserModel.id_user,
            full=True).join(
                LAreas,
                LAreas.id_area == ObservationModel.municipality,
                isouter=True).filter(
                    ObservationModel.id_observation == id_observation)).one()

    photos = (db.session.query(MediaModel, ObservationModel).filter(
        ObservationModel.id_observation == id_observation).join(
            ObservationMediaModel,
            ObservationMediaModel.id_data_source ==
            ObservationModel.id_observation,
        ).join(MediaModel,
               ObservationMediaModel.id_media == MediaModel.id_media).all())

    result_dict = observation.ObservationModel.as_dict(True)
    result_dict["observer"] = {"username": observation.username}
    result_dict["municipality"] = {
        "name": observation.area_name,
        "code": observation.area_code,
    }

    # Populate "geometry"
    features = []
    feature = get_geojson_feature(observation.ObservationModel.geom)

    # Populate "properties"
    for k in result_dict:
        if k in obs_keys:
            feature["properties"][k] = result_dict[k]

    feature["properties"]["photos"] = [{
        "url":
        "/media/{}".format(p.MediaModel.filename),
        "date":
        p.ObservationModel.as_dict()["date"],
        "author":
        p.ObservationModel.obs_txt,
    } for p in photos]

    if current_app.config.get("API_TAXHUB") is None:
        current_app.logger.debug("Selecting TaxHub Medias schema.")
        # Get official taxref scientific and common names (first one) from cd_nom where cd_nom = cd_ref
        # taxref = get_specie_from_cd_nom(feature["properties"]["cd_nom"])
        # for k in taxref:
        #     feature["properties"][k] = taxref[k]
        taxref = Taxref.query.filter(
            Taxref.cd_nom == observation.ObservationModel.cd_nom).first()
        if taxref:
            feature["properties"]["taxref"] = taxref.as_dict(True)

        medias = TMedias.query.filter(
            TMedias.cd_ref == observation.ObservationModel.cd_nom).all()
        if medias:
            feature["properties"]["medias"] = [
                media.as_dict(True) for media in medias
            ]

    else:
        taxhub_list_id = (ProgramsModel.query.filter_by(
            id_program=observation.ObservationModel.id_program).one().
                          taxonomy_list)
        taxon_repository = mkTaxonRepository(taxhub_list_id)
        try:
            taxon = next(
                taxon for taxon in taxon_repository if taxon
                and taxon["cd_nom"] == feature["properties"]["cd_nom"])
            feature["properties"]["taxref"] = taxon["taxref"]
            feature["properties"]["medias"] = taxon["medias"]
        except StopIteration:
            pass

    features.append(feature)
    return features