nasturtium 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+

|
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
|
+
|