nasturtium 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/main.yml +19 -0
- data/.gitignore +10 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +53 -0
- data/LICENSE.txt +13 -0
- data/README.md +534 -0
- data/Rakefile +14 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/lib/nasturtium/error.rb +24 -0
- data/lib/nasturtium/faraday.rb +75 -0
- data/lib/nasturtium/helpers/configuration.rb +26 -0
- data/lib/nasturtium/request.rb +329 -0
- data/lib/nasturtium/utils.rb +38 -0
- data/lib/nasturtium/version.rb +5 -0
- data/lib/nasturtium.rb +843 -0
- data/nasturtium.gemspec +56 -0
- metadata +215 -0
data/README.md
ADDED
@@ -0,0 +1,534 @@
|
|
1
|
+
# Nasturtium
|
2
|
+
|
3
|
+
![Nasturtium Logo](https://github.com/SpeciesFileGroup/nasturtium/assets/8573609/7a19d255-a62e-429d-9fa0-43711ad60f2c)
|
4
|
+
|
5
|
+
This is a Ruby wrapper on the [iNaturalist](https://api.inaturalist.org/v1/docs/#!/Search/get_search) API. Code follow the spirit/approach of the Gem [serrano](https://github.com/sckott/serrano), and indeed much of the wrapping utility is copied 1:1 from that repo, thanks [@sckott](https://github.com/sckott).
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'nasturtium'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle install
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install nasturtium
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
### Controlled vocabulary terms
|
26
|
+
|
27
|
+
Get controlled vocabulary terms
|
28
|
+
```ruby
|
29
|
+
Nasturtium.controlled_terms # => MultiJson object
|
30
|
+
```
|
31
|
+
|
32
|
+
Get controlled vocabulary terms for a taxon
|
33
|
+
```ruby
|
34
|
+
Nasturtium.controlled_terms(taxon_id: 1) # => MultiJson object
|
35
|
+
```
|
36
|
+
|
37
|
+
### Identifications
|
38
|
+
These are just some examples. For a complete list [view the tests](https://github.com/SpeciesFileGroup/nasturtium/blob/main/test/identifications_test.rb) for examples or the [API documentation](https://api.inaturalist.org/v1/docs/#!/Identifications/get_identifications).
|
39
|
+
|
40
|
+
Get an identification by ID
|
41
|
+
```ruby
|
42
|
+
Nasturtium.identifications(id: 342040114) # => MultiJson object
|
43
|
+
```
|
44
|
+
|
45
|
+
Get identifications in which the taxon is the same as the observation's taxon
|
46
|
+
```ruby
|
47
|
+
Nasturtium.identifications(current_taxon: true) # => MultiJson object
|
48
|
+
```
|
49
|
+
|
50
|
+
Get identifications which were added by the observer
|
51
|
+
```ruby
|
52
|
+
Nasturtium.identifications(own_observation: true) # => MultiJson object
|
53
|
+
```
|
54
|
+
|
55
|
+
Get identifications by taxonomic rank
|
56
|
+
```ruby
|
57
|
+
Nasturtium.identifications(rank: 'suborder') # => MultiJson object
|
58
|
+
```
|
59
|
+
|
60
|
+
Get identifications with the rank species and the observation rank variety:
|
61
|
+
```ruby
|
62
|
+
Nasturtium.identifications(rank: 'species', observation_rank: 'variety') # => MultiJson object
|
63
|
+
```
|
64
|
+
|
65
|
+
Get identifications by a user_id:
|
66
|
+
```ruby
|
67
|
+
Nasturtium.identifications(user_id: '20717') # => MultiJson object
|
68
|
+
```
|
69
|
+
|
70
|
+
Get identifications by category:
|
71
|
+
```ruby
|
72
|
+
Nasturtium.identifications(category: 'improving') # => MultiJson object
|
73
|
+
```
|
74
|
+
|
75
|
+
Get identifications by quality grade:
|
76
|
+
```ruby
|
77
|
+
Nasturtium.identifications(quality_grade: 'research') # => MultiJson object
|
78
|
+
```
|
79
|
+
|
80
|
+
Get identifications by taxon_id:
|
81
|
+
```ruby
|
82
|
+
Nasturtium.identifications(taxon_id: 42196) # => MultiJson object
|
83
|
+
```
|
84
|
+
|
85
|
+
---
|
86
|
+
### Mapping
|
87
|
+
Get a grid map tile for the turkey vulture at zoom level 2 for coordinates (0, 1):
|
88
|
+
```ruby
|
89
|
+
Nasturtium.mapping('grid', 2, 0, 1, style: 'geotilegrid', tile_size: 512, taxon_id: 4756)
|
90
|
+
```
|
91
|
+
|
92
|
+
Get a colored_heatmap map tile for the turkey vulture at zoom level 2 for coordinates (0, 1):
|
93
|
+
```ruby
|
94
|
+
Nasturtium.mapping('colored_heatmap', 2, 0, 1, tile_size: 512, taxon_id: 4756, color: '#00ff00')
|
95
|
+
```
|
96
|
+
|
97
|
+
Get a points map tile for the turkey vulture at zoom level 2 for coordinates (0, 0):
|
98
|
+
```ruby
|
99
|
+
Nasturtium.mapping('points', 2, 0, 0, tile_size: 512, taxon_id: 4756, color: '#00ff00')
|
100
|
+
```
|
101
|
+
|
102
|
+
Get a points map tile for the turkey vulture at zoom level 2 for coordinates (0, 0):
|
103
|
+
```ruby
|
104
|
+
Nasturtium.mapping('grid', 2, 0, 1, taxon_id: 4756, return_json: true)
|
105
|
+
```
|
106
|
+
|
107
|
+
Get the taxon_places map for turkey vultures:
|
108
|
+
```ruby
|
109
|
+
Nasturtium.mapping('taxon_places', 2, 0, 1, taxon_id: 4756)
|
110
|
+
```
|
111
|
+
|
112
|
+
Get the taxon_ranges map for turkey vultures:
|
113
|
+
```ruby
|
114
|
+
Nasturtium.mapping('taxon_ranges', 2, 0, 1, taxon_id: 4756)
|
115
|
+
```
|
116
|
+
|
117
|
+
Get the places map for turkey vultures in place 35:
|
118
|
+
```ruby
|
119
|
+
Nasturtium.mapping('places', 2, 0, 0, place_id: 35, taxon_id: 4756, tile_size: 512)
|
120
|
+
```
|
121
|
+
|
122
|
+
|
123
|
+
---
|
124
|
+
### Observations
|
125
|
+
These are just some examples. For a complete list [view the tests](https://github.com/SpeciesFileGroup/nasturtium/blob/main/test/observations_test.rb) for examples or the [API documentation](https://api.inaturalist.org/v1/docs/#!/Observations/get_observations).
|
126
|
+
|
127
|
+
Get an observation by ID
|
128
|
+
```ruby
|
129
|
+
Nasturtium.observations(id: '150842485') # => MultiJson object
|
130
|
+
```
|
131
|
+
|
132
|
+
Get observations with positional accuracy/coordinate uncertainty specified
|
133
|
+
```ruby
|
134
|
+
Nasturtium.observations(acc: true) # => MultiJson object
|
135
|
+
```
|
136
|
+
|
137
|
+
Get captive/cultivated observations
|
138
|
+
```ruby
|
139
|
+
Nasturtium.observations(captive: true) # => MultiJson object
|
140
|
+
```
|
141
|
+
|
142
|
+
Exclude captive/cultivated observations
|
143
|
+
```ruby
|
144
|
+
Nasturtium.observations(captive: false) # => MultiJson object
|
145
|
+
```
|
146
|
+
|
147
|
+
Get observations in which the taxon is endemic to their location
|
148
|
+
```ruby
|
149
|
+
Nasturtium.observations(endemic: true) # => MultiJson object
|
150
|
+
```
|
151
|
+
|
152
|
+
Get observations that are georeferenced
|
153
|
+
```ruby
|
154
|
+
Nasturtium.observations(geo: true) # => MultiJson object
|
155
|
+
```
|
156
|
+
|
157
|
+
Get observations that have been identified
|
158
|
+
```ruby
|
159
|
+
Nasturtium.observations(identified: true) # => MultiJson object
|
160
|
+
```
|
161
|
+
|
162
|
+
Get observations in which the taxon has been introduced in their location
|
163
|
+
```ruby
|
164
|
+
Nasturtium.observations(introduced: true) # => MultiJson object
|
165
|
+
```
|
166
|
+
|
167
|
+
Get observations that show on map tiles
|
168
|
+
```ruby
|
169
|
+
Nasturtium.observations(mappable: true) # => MultiJson object
|
170
|
+
```
|
171
|
+
|
172
|
+
Get observations in which the taxon is native in their location
|
173
|
+
```ruby
|
174
|
+
Nasturtium.observations(native: true) # => MultiJson object
|
175
|
+
```
|
176
|
+
|
177
|
+
Get observations in which the taxon was observed outside of their known range
|
178
|
+
```ruby
|
179
|
+
Nasturtium.observations(out_of_range: true) # => MultiJson object
|
180
|
+
```
|
181
|
+
|
182
|
+
Get observations with photos
|
183
|
+
```ruby
|
184
|
+
Nasturtium.observations(photos: true) # => MultiJson object
|
185
|
+
```
|
186
|
+
|
187
|
+
Get observations that have been favorited by at least 1 user
|
188
|
+
```ruby
|
189
|
+
Nasturtium.observations(popular: true) # => MultiJson object
|
190
|
+
```
|
191
|
+
|
192
|
+
Get observations with sounds
|
193
|
+
```ruby
|
194
|
+
Nasturtium.observations(sounds: true) # => MultiJson object
|
195
|
+
```
|
196
|
+
|
197
|
+
Get observations in which the taxon concept is active
|
198
|
+
```ruby
|
199
|
+
Nasturtium.observations(taxon_is_active: true) # => MultiJson object
|
200
|
+
```
|
201
|
+
|
202
|
+
Get observations in which the taxon is threatened in their location
|
203
|
+
```ruby
|
204
|
+
Nasturtium.observations(threatened: true) # => MultiJson object
|
205
|
+
```
|
206
|
+
|
207
|
+
Get observations with a quality_grade of needs_id or research
|
208
|
+
```ruby
|
209
|
+
Nasturtium.observations(verifiable: true) # => MultiJson object
|
210
|
+
```
|
211
|
+
|
212
|
+
Get observations that have a cc0 license
|
213
|
+
```ruby
|
214
|
+
Nasturtium.observations(license: 'cc0') # => MultiJson object
|
215
|
+
```
|
216
|
+
|
217
|
+
Get observations that have a license
|
218
|
+
```ruby
|
219
|
+
Nasturtium.observations(licensed: true) # => MultiJson object
|
220
|
+
```
|
221
|
+
|
222
|
+
Get observations that have a cc0 photo license
|
223
|
+
```ruby
|
224
|
+
Nasturtium.observations(photo_license: 'cc0') # => MultiJson object
|
225
|
+
```
|
226
|
+
|
227
|
+
Get observations in which at least 1 photo has a license
|
228
|
+
```ruby
|
229
|
+
Nasturtium.observations(photo_licensed: true) # => MultiJson object
|
230
|
+
```
|
231
|
+
|
232
|
+
Get observations by a place_id
|
233
|
+
```ruby
|
234
|
+
Nasturtium.observations(place_id: 26) # => MultiJson object
|
235
|
+
```
|
236
|
+
|
237
|
+
Get observations from a project_id
|
238
|
+
```ruby
|
239
|
+
Nasturtium.observations(project_id: 22499) # => MultiJson object
|
240
|
+
```
|
241
|
+
|
242
|
+
Get observations by a taxonomic rank
|
243
|
+
```ruby
|
244
|
+
Nasturtium.observations(rank: 'subspecies') # => MultiJson object
|
245
|
+
```
|
246
|
+
|
247
|
+
Get observations by an iNaturalist network website site_id
|
248
|
+
```ruby
|
249
|
+
Nasturtium.observations(site_id: 2) # => MultiJson object
|
250
|
+
```
|
251
|
+
|
252
|
+
Get observations with a cc0 licensed sound recording
|
253
|
+
```ruby
|
254
|
+
Nasturtium.observations(sound_license: 'cc0') # => MultiJson object
|
255
|
+
```
|
256
|
+
|
257
|
+
Get observations by a taxon_id
|
258
|
+
```ruby
|
259
|
+
Nasturtium.observations(taxon_id: '522193') # => MultiJson object
|
260
|
+
```
|
261
|
+
|
262
|
+
Get observations by a taxon_name
|
263
|
+
```ruby
|
264
|
+
Nasturtium.observations(taxon_name: 'Nasturtium floridanum') # => MultiJson object
|
265
|
+
```
|
266
|
+
|
267
|
+
Get observations by a user_id
|
268
|
+
```ruby
|
269
|
+
Nasturtium.observations(user_id: '20717') # => MultiJson object
|
270
|
+
```
|
271
|
+
|
272
|
+
Get observations by a user_login
|
273
|
+
```ruby
|
274
|
+
Nasturtium.observations(user_login: 'debpaul') # => MultiJson object
|
275
|
+
```
|
276
|
+
|
277
|
+
Get observations by a date
|
278
|
+
```ruby
|
279
|
+
Nasturtium.observations(year: 2020, month: 3, day: 15) # => MultiJson object
|
280
|
+
```
|
281
|
+
|
282
|
+
Get observations that have a controlled vocabulary term
|
283
|
+
```ruby
|
284
|
+
Nasturtium.observations(term_id: 1) # => MultiJson object
|
285
|
+
```
|
286
|
+
|
287
|
+
Get observations that have controlled vocabulary term 1 and controlled vocabulary value 2
|
288
|
+
```ruby
|
289
|
+
Nasturtium.observations(term_id: 1, term_value_id: 2)
|
290
|
+
```
|
291
|
+
|
292
|
+
Get observations with positional accuracy above 100 meters and below 200 meters
|
293
|
+
```ruby
|
294
|
+
Nasturtium.observations(acc_above: 100, acc_below: 200)
|
295
|
+
```
|
296
|
+
|
297
|
+
Get observations with open geoprivacy
|
298
|
+
```ruby
|
299
|
+
Nasturtium.observations(geoprivacy: 'open')
|
300
|
+
```
|
301
|
+
|
302
|
+
Get observations with a taxonomic rank above genus and below phylum
|
303
|
+
```ruby
|
304
|
+
Nasturtium.observations(rank_highest: 'genus', rank_lowest: 'phylum')
|
305
|
+
```
|
306
|
+
|
307
|
+
Get observations in which most people agree on the identification
|
308
|
+
```ruby
|
309
|
+
Nasturtium.observations(identifications: 'most_agree')
|
310
|
+
```
|
311
|
+
|
312
|
+
Get observations with research quality grade identifications
|
313
|
+
```ruby
|
314
|
+
Nasturtium.observations(quality_grade: 'research')
|
315
|
+
```
|
316
|
+
|
317
|
+
Get observations within a 1 km radius of 45.703259, -85.552406
|
318
|
+
```ruby
|
319
|
+
@ne_lat = 40.084300
|
320
|
+
@sw_lat = 40.075877
|
321
|
+
@ne_lng = -88.198636
|
322
|
+
@sw_lng = -88.210169
|
323
|
+
Nasturtium.observations(latitude: 45.703259, longitude: -85.552406, radius: 1)
|
324
|
+
```
|
325
|
+
|
326
|
+
Get observations within a bounding box
|
327
|
+
```ruby
|
328
|
+
@ne_lat = 40.084300
|
329
|
+
@sw_lat = 40.075877
|
330
|
+
@ne_lng = -88.198636
|
331
|
+
@sw_lng = -88.210169
|
332
|
+
Nasturtium.observations(ne_latitude: @ne_lat, ne_longitude: @ne_lng, sw_longitude: @sw_lat, sw_latitude: @sw_lng)
|
333
|
+
```
|
334
|
+
|
335
|
+
Search for observations with the query Parastratiosphecomyia
|
336
|
+
```ruby
|
337
|
+
Nasturtium.observations(q: 'Parastratiosphecomyia')
|
338
|
+
```
|
339
|
+
|
340
|
+
Search for observations with Meadowbrook in a place name
|
341
|
+
```ruby
|
342
|
+
Nasturtium.observations(q: 'Meadowbrook', search_on: 'place')
|
343
|
+
```
|
344
|
+
|
345
|
+
Search for observations with blue in a tag name
|
346
|
+
```ruby
|
347
|
+
Nasturtium.observations(q: 'blue', search_on: 'tags')
|
348
|
+
```
|
349
|
+
|
350
|
+
Search for observations with blue in the description
|
351
|
+
```ruby
|
352
|
+
Nasturtium.observations(q: 'blue', search_on: 'description')
|
353
|
+
```
|
354
|
+
|
355
|
+
Search for observations with grizzly in the names
|
356
|
+
```ruby
|
357
|
+
Nasturtium.observations(q: 'grizzly', search_on: 'names')
|
358
|
+
```
|
359
|
+
|
360
|
+
---
|
361
|
+
### Places
|
362
|
+
Get places by ID with an admin_level of 100
|
363
|
+
```ruby
|
364
|
+
Nasturtium.places_id(1000, admin_level: 100) # => MultiJson object
|
365
|
+
```
|
366
|
+
|
367
|
+
---
|
368
|
+
### Places autocomplete
|
369
|
+
Get suggested place name autocompletions
|
370
|
+
```ruby
|
371
|
+
Nasturtium.places_autocomplete('Kickapoo Rail Trail') # => MultiJson object
|
372
|
+
```
|
373
|
+
|
374
|
+
---
|
375
|
+
### Places nearby
|
376
|
+
Get place names nearby within a bounding box and that include the string Meadowbrook
|
377
|
+
```ruby
|
378
|
+
@ne_lat = 40.084300
|
379
|
+
@sw_lat = 40.075877
|
380
|
+
@ne_lng = -88.198636
|
381
|
+
@sw_lng = -88.210169
|
382
|
+
Nasturtium.places_nearby(@ne_lat, @ne_lng, @sw_lat, @sw_lng, name: "Meadowbrook") # => MultiJson object
|
383
|
+
```
|
384
|
+
|
385
|
+
---
|
386
|
+
### Posts
|
387
|
+
Get journal posts:
|
388
|
+
```ruby
|
389
|
+
Nasturtium.posts # => MultiJson object
|
390
|
+
```
|
391
|
+
|
392
|
+
Get journal posts for parent_id:
|
393
|
+
```ruby
|
394
|
+
Nasturtium.posts(parent_id: 1, page: 1, per_page: 10) # => MultiJson object
|
395
|
+
```
|
396
|
+
|
397
|
+
Get journal posts for project_id:
|
398
|
+
```ruby
|
399
|
+
Nasturtium.posts(project_id: 42768) # => MultiJson object
|
400
|
+
```
|
401
|
+
|
402
|
+
Get journal posts for a user:
|
403
|
+
```ruby
|
404
|
+
Nasturtium.posts(login: 'loarie') # => MultiJson object
|
405
|
+
```
|
406
|
+
|
407
|
+
---
|
408
|
+
### Projects
|
409
|
+
Search projects with query term, Illinois:
|
410
|
+
```ruby
|
411
|
+
Nasturtium.projects(q: 'Illinois') # => MultiJson object
|
412
|
+
```
|
413
|
+
|
414
|
+
Get a project by ID
|
415
|
+
```ruby
|
416
|
+
Nasturtium.projects(id: 22499) # => MultiJson object
|
417
|
+
```
|
418
|
+
|
419
|
+
Search for projects within 5 km of 40.11136254505831, -88.2460817474295
|
420
|
+
```ruby
|
421
|
+
Nasturtium.projects(latitude: 40.11136254505831, longitude: -88.2460817474295, radius: 5) # => MultiJson object
|
422
|
+
```
|
423
|
+
|
424
|
+
Get projects with place_id or with place_id as a place ancestor
|
425
|
+
```ruby
|
426
|
+
Nasturtium.projects(place_id: 35) # => MultiJson object
|
427
|
+
```
|
428
|
+
|
429
|
+
Get featured projects on iNaturalist México
|
430
|
+
```ruby
|
431
|
+
Nasturtium.projects(featured: true, site_id: 2) # => MultiJson object
|
432
|
+
```
|
433
|
+
|
434
|
+
Get noteworthy projects on iNaturalist
|
435
|
+
```ruby
|
436
|
+
Nasturtium.projects(noteworthy: true, site_id: 1) # => MultiJson object
|
437
|
+
```
|
438
|
+
|
439
|
+
Get projects that include user_id as a member
|
440
|
+
```ruby
|
441
|
+
Nasturtium.projects(member_id: 477) # => MultiJson object
|
442
|
+
```
|
443
|
+
|
444
|
+
Get projects with journal posts
|
445
|
+
```ruby
|
446
|
+
Nasturtium.projects(has_posts: true) # => MultiJson object
|
447
|
+
```
|
448
|
+
|
449
|
+
---
|
450
|
+
### Project members
|
451
|
+
Get the members of project_id 733
|
452
|
+
```ruby
|
453
|
+
Nasturtium.project_members(733, page: 1, per_page: 10)
|
454
|
+
```
|
455
|
+
|
456
|
+
---
|
457
|
+
### Search
|
458
|
+
Search places, projects, taxa, or users:
|
459
|
+
```ruby
|
460
|
+
Nasturtium.search(q: 'Quercus', sources: 'taxa') # => MultiJson object
|
461
|
+
```
|
462
|
+
|
463
|
+
---
|
464
|
+
### Taxa
|
465
|
+
Search and fetch taxa with a comma-separted list of IDs:
|
466
|
+
```ruby
|
467
|
+
Nasturtium.taxa(id: '1,2') # => MultiJson object
|
468
|
+
```
|
469
|
+
Search and fetch taxa:
|
470
|
+
```ruby
|
471
|
+
Nasturtium.taxa(q: 'Danaus plexippus', rank: 'species') # => MultiJson object
|
472
|
+
```
|
473
|
+
Fetch taxa ordered by greatest observations count:
|
474
|
+
```ruby
|
475
|
+
Nasturtium.taxa(rank: 'species', order: 'desc', order_by: 'observations_count') # => MultiJson object
|
476
|
+
```
|
477
|
+
|
478
|
+
---
|
479
|
+
### Taxa autocomplete
|
480
|
+
Get suggested taxa names for a query Sinapis at ranks genus,species,subspecies with a limit of 5 suggestions:
|
481
|
+
```ruby
|
482
|
+
Nasturtium.taxa_autocomplete(q: 'Sinapis', rank: 'genus,species,subspecies', per_page: 5) # => MultiJson object
|
483
|
+
```
|
484
|
+
Include all names for each suggested taxon:
|
485
|
+
```ruby
|
486
|
+
Nasturtium.taxa_autocomplete(q: 'Sinapis', rank: 'genus,species,subspecies', per_page: 5, all_names: true) # => MultiJson object
|
487
|
+
```
|
488
|
+
Get common names by the language at preferred_place_id which adds a preferred_common_name key (use Nasturtium.places_autocomplete to lookup place_id's):
|
489
|
+
```ruby
|
490
|
+
Nasturtium.taxa_autocomplete(q: 'Danaus plexippus', preferred_place_id: 6903, rank: 'species') # => MultiJson object
|
491
|
+
```
|
492
|
+
|
493
|
+
---
|
494
|
+
### User
|
495
|
+
Get a user by ID
|
496
|
+
```ruby
|
497
|
+
Nasturtium.user(20717) # => MultiJson object
|
498
|
+
```
|
499
|
+
|
500
|
+
|
501
|
+
---
|
502
|
+
### User autocomplete
|
503
|
+
Suggest a user by autocomplete
|
504
|
+
```ruby
|
505
|
+
Nasturtium.user_autocomplete('debpau') # => MultiJson object
|
506
|
+
```
|
507
|
+
|
508
|
+
|
509
|
+
---
|
510
|
+
### User projects
|
511
|
+
Get a user's projects of type collection
|
512
|
+
```ruby
|
513
|
+
Nasturtium.user_projects(20717, project_type: 'collection') # => MultiJson object
|
514
|
+
```
|
515
|
+
---
|
516
|
+
|
517
|
+
|
518
|
+
## Development
|
519
|
+
|
520
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
521
|
+
|
522
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
523
|
+
|
524
|
+
## Contributing
|
525
|
+
|
526
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/SpeciesFileGroup/nasturtium. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/SpeciesFileGroup/nasturtium/blob/main/CODE_OF_CONDUCT.md).
|
527
|
+
|
528
|
+
## License
|
529
|
+
|
530
|
+
The gem is available as open source under the terms of the [NCSA/Illinois](https://opensource.org/licenses/NCSA).
|
531
|
+
|
532
|
+
## Code of Conduct
|
533
|
+
|
534
|
+
Everyone interacting in the Nasturtium project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/SpeciesFileGroup/nasturtium/blob/main/CODE_OF_CONDUCT.md).
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rake/testtask"
|
5
|
+
|
6
|
+
Rake::TestTask.new(:test) do |t|
|
7
|
+
t.libs << "test"
|
8
|
+
t.libs << "lib"
|
9
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
10
|
+
t.verbose = true
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Run tests"
|
14
|
+
task default: :test
|
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "nasturtium"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require "irb"
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nasturtium
|
4
|
+
# Custom error class for rescuing from all Bonamia errors
|
5
|
+
class Error < StandardError; end
|
6
|
+
|
7
|
+
# Raised when Bionomia returns the HTTP status code 400
|
8
|
+
class BadRequest < Error; end
|
9
|
+
|
10
|
+
# Raised when Bionomia returns the HTTP status code 404
|
11
|
+
class NotFound < Error; end
|
12
|
+
|
13
|
+
# Raised when Bionomia returns the HTTP status code 500
|
14
|
+
class InternalServerError < Error; end
|
15
|
+
|
16
|
+
# Raised when Bionomia returns the HTTP status code 502
|
17
|
+
class BadGateway < Error; end
|
18
|
+
|
19
|
+
# Raised when Bionomia returns the HTTP status code 503
|
20
|
+
class ServiceUnavailable < Error; end
|
21
|
+
|
22
|
+
# Raised when Bionomia returns the HTTP status code 504
|
23
|
+
class GatewayTimeout < Error; end
|
24
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "faraday"
|
4
|
+
require "multi_json"
|
5
|
+
|
6
|
+
# @private
|
7
|
+
module Faraday
|
8
|
+
module NasturtiumErrors
|
9
|
+
# @private
|
10
|
+
class Middleware < Faraday::Middleware
|
11
|
+
def call(env)
|
12
|
+
@app.call(env).on_complete do |response|
|
13
|
+
case response[:status].to_i
|
14
|
+
when 400
|
15
|
+
raise Nasturtium::BadRequest, error_message_400(response)
|
16
|
+
when 404
|
17
|
+
raise Nasturtium::NotFound, error_message_400(response)
|
18
|
+
when 500
|
19
|
+
raise Nasturtium::InternalServerError, error_message_500(response, "Something is technically wrong.")
|
20
|
+
when 502
|
21
|
+
raise Nasturtium::BadGateway, error_message_500(response, "The server returned an invalid or incomplete response.")
|
22
|
+
when 503
|
23
|
+
raise Nasturtium::ServiceUnavailable, error_message_500(response, "Crossref is rate limiting your requests.")
|
24
|
+
when 504
|
25
|
+
raise Nasturtium::GatewayTimeout, error_message_500(response, "504 Gateway Time-out")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def initialize(app)
|
32
|
+
super app
|
33
|
+
@parser = nil
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def error_message_400(response)
|
39
|
+
"\n #{response[:method].to_s.upcase} #{response[:url]}\n Status #{response[:status]}#{error_body(response[:body])}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def error_body(body)
|
43
|
+
if !body.nil? && !body.empty? && body.is_a?(String)
|
44
|
+
if json?(body)
|
45
|
+
body = ::MultiJson.load(body)
|
46
|
+
if body["message"].nil?
|
47
|
+
body = nil
|
48
|
+
elseif body["message"].length == 1
|
49
|
+
body = body["message"]
|
50
|
+
else
|
51
|
+
body = body["message"].collect { |x| x["message"] }.join("; ")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
if body.nil?
|
57
|
+
nil
|
58
|
+
else
|
59
|
+
": #{body}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def error_message_500(response, body = nil)
|
64
|
+
"#{response[:method].to_s.upcase} #{response[:url]}: #{[response[:status].to_s + ":", body].compact.join(" ")}"
|
65
|
+
end
|
66
|
+
|
67
|
+
def json?(string)
|
68
|
+
MultiJson.load(string)
|
69
|
+
true
|
70
|
+
rescue MultiJson::ParseError
|
71
|
+
false
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# taken from https://raw.githubusercontent.com/sckott/serrano/main/lib/serrano/helpers/configuration.rb
|
2
|
+
# taken from: https://viget.com/extend/easy-gem-configuration-variables-with-defaults
|
3
|
+
module Configuration
|
4
|
+
def configuration
|
5
|
+
yield self
|
6
|
+
end
|
7
|
+
|
8
|
+
def define_setting(name, default = nil)
|
9
|
+
class_variable_set("@@#{name}", default)
|
10
|
+
define_class_method "#{name}=" do |value|
|
11
|
+
class_variable_set("@@#{name}", value)
|
12
|
+
end
|
13
|
+
define_class_method name do
|
14
|
+
class_variable_get("@@#{name}")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def define_class_method(name, &block)
|
21
|
+
(class << self; self; end).instance_eval do
|
22
|
+
define_method name, &block
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|