nasturtium 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -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
+