Ejemplo n.º 1
0
 def push_attached_pictures_at_inaturalist(self, access_token, user_agent):
     if self.inaturalist_id:
         for picture in self.pictures.all():
             add_photo_to_observation(observation_id=self.inaturalist_id,
                                      file_object=picture.image.read(),
                                      access_token=access_token,
                                      user_agent=user_agent)
Ejemplo n.º 2
0
def update_test_obs(test_obs_id, token):
    response = add_photo_to_observation(
        test_obs_id,
        photo=SAMPLE_PHOTO,
        access_token=token,
    )
    photo_id = response.get("photo").get("id")
    assert photo_id
    print("Added photo to observation: {}".format(photo_id))
    # pprint(response, indent=2)

    response = update_observation(
        test_obs_id,
        geoprivacy="obscured",
        ignore_photos=True,
        access_token=token,
    )
    new_geoprivacy = response[0]["geoprivacy"]
    assert new_geoprivacy == "obscured"
    print("Updated observation")
    # pprint(response, indent=2)

    response = put_observation_field_values(
        observation_id=test_obs_id,
        observation_field_id=297,
        value=2,
        access_token=token,
    )
    print("Added observation field value:")
    pprint(response, indent=2)
def upload_obs(obs: Observation, token: str):

    logger.debug('upload_obs()')
    #TODO: Give the observation class a method to generate this JSON
    params = {
        'observation': {
            'taxon_id':
            obs.taxon_id,
            'species_guess':
            obs.taxon_name,
            'observed_on_string':
            str(obs.observed_on),
            'time_zone':
            obs.tzone,
            'description':
            obs.comment,
            'tag_list':
            obs.tags,
            'latitude':
            obs.coordinates[0],
            'longitude':
            obs.coordinates[1],
            'positional_accuracy':
            obs.geotag_accuracy,  # meters,
            'geoprivacy':
            obs.geotag_privacy,
            'observation_field_values_attributes': [{
                'observation_field_id': '',
                'value': ''
            }],
        },
    }

    try:
        logger.info('Uploading observation for taxon {0}'.format(obs.taxon_id))
        r = create_observations(params=params, access_token=token)

        obs.inat_id = r[0]['id']

        for file in obs.photos:

            r = add_photo_to_observation(observation_id=obs.inat_id,
                                         file_object=open(file, 'rb'),
                                         access_token=token)

    except HTTPError as ex:
        obs.inat_result = 'Error creating observation: {0}'.format(ex)
        logger.error('Bad result from iNaturalist API, skipping this one')
        logger.exception(ex)

    except Exception as ex:
        raise
    else:
        logger.info('Success')
        obs.inat_result = 'ok'
Ejemplo n.º 4
0
def test_add_photo_to_observation(requests_mock):
    requests_mock.post(
        urljoin(INAT_BASE_URL, "observation_photos"),
        json=load_sample_data("add_photo_to_observation.json"),
        status_code=200,
    )

    response = add_photo_to_observation(1234, BytesIO(), access_token="token")
    assert response["id"] == 1234
    assert response["created_at"] == "2020-09-24T21:06:16.964-05:00"
    assert response["photo"]["native_username"] == "username"
Ejemplo n.º 5
0
                time_zone,
                'description':
                'This is a test upload',
                'tag_list':
                '',
                'latitude':
                coordinates[0],
                'longitude':
                coordinates[1],
                'positional_accuracy':
                50,  # meters,
                'observation_field_values_attributes': [{
                    'observation_field_id':
                    '',
                    'value':
                    ''
                }],
            },
        }
        r = create_observations(params=params, access_token=token)

        new_observation_id = r[0]['id']

        from pyinaturalist.rest_api import add_photo_to_observation

        r = add_photo_to_observation(observation_id=new_observation_id,
                                     file_object=open(file, 'rb'),
                                     access_token=token)

print("Program complete")
Ejemplo n.º 6
0
def upload_folder_multiple(species_folder, folder, uploaded_folder, time_zone,
                           accuracy, user, passw, app, secret):
    # Makes a list of all files in the folder inside element 2 of a tuple
    for file in os.walk(folder):
        if file[0] == folder:
            files = file

    # Creates list of all the file paths for every file in the folder.
    file_paths = []
    for file in files[2]:  # All files are in files[2]
        file_path = files[0] + file  # files[0] has the path to the folder
        file_paths.append(file_path)  # Makes a big list of paths

    # This is getting a token to allow photos to be uploaded.
    token = get_access_token(username=user,
                             password=passw,
                             app_id=app,
                             app_secret=secret)

    # This goes to every file, checks if it is a jpg, gets the gps coordinates,
    # get the time, and uploads it to iNaturalist.
    jpgs = []
    for file in file_paths:
        if file[-3:].lower() == 'jpg':
            jpgs.append(file)

    try:
        img = PIL.Image.open(jpgs[0])
        coordinates = get_lat_long(img)
        img.close()
    except:
        coordinates = 'No Coordinates'
    try:
        date_time = get_date(file)
        img.close()
    except:
        date_time = 'No Date or Time'

    [species, taxon] = get_taxon(species_folder)
    print(species)
    #    print(coordinates)
    #    print(date_time)
    #    print(' the taxon is ' + str(taxon))

    params = {
        'observation': {
            'taxon_id':
            taxon,
            'species_guess':
            species,
            'observed_on_string':
            date_time,
            'time_zone':
            time_zone,
            'description':
            '',
            'tag_list':
            '',
            'latitude':
            coordinates[0],
            'longitude':
            coordinates[1],
            'positional_accuracy':
            int(accuracy),  # meters,
            'observation_field_values_attributes': [{
                'observation_field_id': '',
                'value': ''
            }],
        },
    }
    r = create_observations(params=params, access_token=token)

    new_observation_id = r[0]['id']

    print('Uploaded as observation #' + str(new_observation_id))
    print('Uploading photos')
    for file in jpgs:
        print('uploading ' + str(file) + ' TO ' + str(new_observation_id))
        r = add_photo_to_observation(observation_id=new_observation_id,
                                     file_object=open(file, 'rb'),
                                     access_token=token)

    folder_name = os.path.split(folder)
    folder1_name = os.path.split(folder_name[0])
    folder2_name = os.path.split(folder1_name[0])

    new_species_folder = uploaded_folder + folder2_name[1] + '/'
    destination = new_species_folder + folder1_name[1]

    if new_observation_id:

        try:
            os.mkdir(new_species_folder)
        except:
            pass
        try:
            shutil.move(folder, destination)
        except:
            print('failed file move')
            pass
Ejemplo n.º 7
0
def inaturalist_api():
    json_data = json.loads(request.data)
    print(json_data)
    utc_key = json_data['utc_key']
    print(f'utc_key: {utc_key}')
    if utc_key is None:
        return
    print(f'key: {utc_key}')
    conn = sqlite3.connect(DB_PATH, timeout=15)
    query = '''SELECT datetime, file_name, prediction, true_label, inaturalist_id
               FROM results 
               WHERE utc_datetime = ?
               LIMIT 1;'''
    c = conn.cursor()
    c.execute(query, (utc_key, ))
    row = c.fetchone()
    if row is None:
        return
    else:
        obs_timestamp = row[0]
        img_fn = row[1]
        pred_label = row[2]
        true_label = row[3]
        existing_inat_id = row[4]
    if true_label is not None:
        obs_label = true_label
    else:
        obs_label = pred_label

    # Get a token for the inaturalist API
    token = get_access_token(
        username=INAT_USERNAME,
        password=INAT_PASSWORD,
        app_id=INAT_APP_ID,
        app_secret=INAT_APP_SECRET,
    )

    obs_file_name = f'{DATA_DIR}/imgs/{img_fn}'

    # Upload the observation to iNaturalist
    if existing_inat_id is None:
        # Check if there's an existing inat id within 5 minutes of this image
        # upload this image to that observation if so.
        window_timestamp = dt.datetime.fromisoformat(utc_key) - dt.timedelta(
            minutes=10)
        window_timestamp = window_timestamp.strftime(dt_fmt)
        query = '''SELECT inaturalist_id
                   FROM results 
                   WHERE utc_datetime <= :utc_dt
                   AND utc_datetime >= :prev_dt
                   AND inaturalist_id IS NOT NULL
                   AND (true_label = :lab OR (true_label IS NULL AND prediction = :lab))
                   ORDER BY utc_datetime DESC
                   LIMIT 1;'''
        c.execute(query, {
            'utc_dt': utc_key,
            'prev_dt': window_timestamp,
            'lab': obs_label
        })
        row = c.fetchone()
        if row is None or row[0] is None:
            response = create_observation(
                taxon_id=species_map[obs_label]['taxa_id'],
                observed_on_string=obs_timestamp,
                time_zone='Mountain Time (US & Canada)',
                description=
                'Birb Cam image upload: https://github.com/evjrob/birbcam',
                tag_list=f'{obs_label}, Canada',
                latitude=INAT_LATITUDE,
                longitude=INAT_LONGITUDE,
                positional_accuracy=INAT_POSITIONAL_ACCURACY,  # meters,
                access_token=token,
            )
            inat_observation_id = response[0]['id']
            print(
                f'No iNaturalist id found in previous ten minutes, creating new row with id {inat_observation_id}.'
            )
        else:
            inat_observation_id = row[0]
            print(
                f'Found iNaturalist id in previous ten minutes, adding to id {inat_observation_id}.'
            )
        # Upload the image captured
        r = add_photo_to_observation(
            inat_observation_id,
            access_token=token,
            photo=obs_file_name,
        )
        # Update the row in the database with the inaturalist id
        c.execute("UPDATE results SET inaturalist_id=? WHERE utc_datetime=?;",
                  (inat_observation_id, utc_key))
    else:
        # This image had already been uploaded, we do not want to upload it again
        inat_observation_id = existing_inat_id
        print(
            f'Found existing iNaturalist id {inat_observation_id} for row, skipping.'
        )

    conn.commit()
    conn.close()
    return jsonify({'inat_id': inat_observation_id})