colrapi 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 +12 -0
- data/Gemfile.lock +75 -0
- data/LICENSE.txt +21 -0
- data/README.md +44 -0
- data/Rakefile +14 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/colrapi.gemspec +56 -0
- data/lib/colrapi/faraday.rb +74 -0
- data/lib/colrapi/helpers/configuration.rb +26 -0
- data/lib/colrapi/request.rb +169 -0
- data/lib/colrapi/utils.rb +38 -0
- data/lib/colrapi/version.rb +5 -0
- data/lib/colrapi.rb +1026 -0
- metadata +209 -0
data/lib/colrapi.rb
ADDED
|
@@ -0,0 +1,1026 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "erb"
|
|
4
|
+
require_relative "colrapi/version"
|
|
5
|
+
require_relative "colrapi/request"
|
|
6
|
+
require "colrapi/helpers/configuration"
|
|
7
|
+
|
|
8
|
+
module Colrapi
|
|
9
|
+
extend Configuration
|
|
10
|
+
|
|
11
|
+
define_setting :base_url, "https://api.checklistbank.org/"
|
|
12
|
+
define_setting :mailto, ENV["COL_API_EMAIL"]
|
|
13
|
+
|
|
14
|
+
# Get assembly status
|
|
15
|
+
#
|
|
16
|
+
# @param dataset_id [String] The dataset id
|
|
17
|
+
#
|
|
18
|
+
# @return [Hash] A result hash of the assembly queue
|
|
19
|
+
def self.assembly(dataset_id, verbose: false)
|
|
20
|
+
endpoint = "dataset/#{dataset_id}/assembly"
|
|
21
|
+
Request.new(endpoint: endpoint, verbose: verbose).perform
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Get a dataset's original archive
|
|
25
|
+
#
|
|
26
|
+
# @param dataset_id [String] The dataset id
|
|
27
|
+
#
|
|
28
|
+
# @return [Binary] An archive of the original dataset
|
|
29
|
+
def self.archive(dataset_id, verbose: false)
|
|
30
|
+
endpoint = "dataset/#{dataset_id}/archive"
|
|
31
|
+
Request.new(endpoint: endpoint, verbose: verbose).perform
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Get dataset metadata
|
|
35
|
+
#
|
|
36
|
+
# For a specific dataset:
|
|
37
|
+
# @param dataset_id [String] The dataset id
|
|
38
|
+
# @param attempt [Integer] Returns archived metadata for a past import attempt number
|
|
39
|
+
#
|
|
40
|
+
# Search datasets:
|
|
41
|
+
# @param q [String] A search query for datasets
|
|
42
|
+
# @param short_title [String] A dataset alias
|
|
43
|
+
# @param code [String] The nomenclatural code (bacterial, botanical, cultivars, phytosociological, virus, zoological)
|
|
44
|
+
# @param private [Boolean] Whether the dataset is private or not
|
|
45
|
+
# @param released_from [Integer] Filter by a project id that a dataset was released from
|
|
46
|
+
# @param contributes_to [Integer] Filter by a project id that a dataset contributes to
|
|
47
|
+
# @param has_source_dataset [Boolean] Filter by if source datasets contribute to the project dataset
|
|
48
|
+
# @param has_gbif_id [Boolean] Whether the dataset has a GBIF registry id
|
|
49
|
+
# @param gbif_id [String] The GBIF registry id
|
|
50
|
+
# @param gbif_publisher_id [String] Filter by a GBIF publisher's id
|
|
51
|
+
# @param editor [Integer] Filter by an editor's user id
|
|
52
|
+
# @param reviewer [Integer] Filter by a reviewer's user id
|
|
53
|
+
# @param modified_by [Integer] Filter by a user id on last modified by
|
|
54
|
+
# @param origin [Array, String] Filter by the origin of a dataset (external, project, release, xrelease)
|
|
55
|
+
# @param type [Array, String] Filter by the dataset type (nomenclatural, taxonomic, phylogenetic, article, legal, thematic, other)
|
|
56
|
+
# @param license [Array, String] Filter by the license type (cc0, cc_by, cc_by_sa, cc_by_nc, cc_by_nd, cc_by_nc_sa, cc_by_nc_nd, unspecified, other)
|
|
57
|
+
# @param row_type [Array, String] Filter by datasets that include a row type (e.g., acef:AcceptedSpecies, col:Taxon, dwc:Taxon)
|
|
58
|
+
# @param created_after [Date] Filter by created after date
|
|
59
|
+
# @param created_before [Date] Filter by created before date
|
|
60
|
+
# @param issued_after [Date] Filter by issued after date
|
|
61
|
+
# @param issued_before [Date] Filter by issued before date
|
|
62
|
+
# @param modified_after [Date] Filter by modified after date
|
|
63
|
+
# @param modified_before [Date] Filter by modified before date
|
|
64
|
+
# @param min_size [Integer] Filter by minimum record size
|
|
65
|
+
#
|
|
66
|
+
# @param sort_by [String] Sort by (key, alias, title, creator, relevance, created, modified, imported, size)
|
|
67
|
+
# @param reverse [Boolean] Sort in reverse
|
|
68
|
+
# @param offset [Integer] Offset for pagination
|
|
69
|
+
# @param limit [Integer] Limit for pagination
|
|
70
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
71
|
+
#
|
|
72
|
+
# @return [Array, Boolean] An array of hashes
|
|
73
|
+
def self.dataset(dataset_id: nil, attempt: nil, q: nil, short_title: nil, code: nil, private: nil, released_from: nil,
|
|
74
|
+
contributes_to: nil, has_source_dataset: nil, has_gbif_id: nil, gbif_id: nil, gbif_publisher_id: nil,
|
|
75
|
+
editor: nil, reviewer: nil, modified_by: nil, origin: nil, type: nil, license: nil, row_type: nil,
|
|
76
|
+
created_after: nil, created_before: nil, issued_after: nil, issued_before: nil, modified_after: nil,
|
|
77
|
+
modified_before: nil, min_size: nil, sort_by: nil, reverse: nil, offset: nil, limit: nil,
|
|
78
|
+
verbose: false)
|
|
79
|
+
endpoint = "dataset"
|
|
80
|
+
unless dataset_id.nil?
|
|
81
|
+
endpoint = "#{endpoint}/#{dataset_id}"
|
|
82
|
+
unless attempt.nil?
|
|
83
|
+
endpoint = "#{endpoint}/#{attempt}"
|
|
84
|
+
end
|
|
85
|
+
endpoint = "#{endpoint}.json"
|
|
86
|
+
Request.new(endpoint: endpoint, verbose: verbose).perform
|
|
87
|
+
else
|
|
88
|
+
Request.new(endpoint: endpoint, q: q, short_title: short_title, code: code, private: private,
|
|
89
|
+
released_from: released_from, contributes_to: contributes_to, has_source_dataset: has_source_dataset,
|
|
90
|
+
has_gbif_id: has_gbif_id, gbif_id: gbif_id, gbif_publisher_id: gbif_publisher_id, editor: editor,
|
|
91
|
+
reviewer: reviewer, modified_by: modified_by, origin: origin, type: type, license: license,
|
|
92
|
+
row_type: row_type, created_after: created_after, created_before: created_before,
|
|
93
|
+
issued_after: issued_after, issued_before: issued_before, modified_after: modified_after,
|
|
94
|
+
modified_before: modified_before, min_size: min_size, sort_by: sort_by, reverse: reverse,
|
|
95
|
+
offset: offset, limit: limit, verbose: verbose).perform
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Get project decisions
|
|
100
|
+
#
|
|
101
|
+
# @param dataset_id [String] The dataset id
|
|
102
|
+
# @param decision_id [Integer, nil] The decision id
|
|
103
|
+
# @param name [String, nil] The scientific name to match
|
|
104
|
+
# @param rank [String, nil] The rank of the scientific name
|
|
105
|
+
# @param modified_by [Integer, nil] Filter by a user id on last modified by
|
|
106
|
+
# @param broken [Boolean, nil] Whether the decision is broken or not
|
|
107
|
+
# @param subject_dataset_id [String, nil] The source dataset id
|
|
108
|
+
# @param mode [String, nil] The type of decision (block, reviewed, update, update_recursive, ignore)
|
|
109
|
+
# @param subject [Boolean, nil] TODO: what does this do? All decisions with subject=true are bare names, so maybe it checks if the subject taxon exists?
|
|
110
|
+
#
|
|
111
|
+
# @param offset [Integer] Offset for pagination
|
|
112
|
+
# @param limit [Integer] Limit for pagination
|
|
113
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
114
|
+
#
|
|
115
|
+
# @return [Hash, Boolean] A result hash
|
|
116
|
+
def self.decision(dataset_id, decision_id: nil, name: nil, rank: nil, modified_by: nil, broken: nil,
|
|
117
|
+
subject_dataset_id: nil, mode: nil, subject: nil, offset: nil, limit: nil, verbose: false)
|
|
118
|
+
if decision_id.nil?
|
|
119
|
+
endpoint = "dataset/#{dataset_id}/decision"
|
|
120
|
+
Request.new(endpoint: endpoint, name: name, rank: rank, modified_by: modified_by, broken: broken,
|
|
121
|
+
subject_dataset_id: subject_dataset_id, mode: mode, subject: subject, offset: offset,
|
|
122
|
+
limit: limit, verbose: verbose).perform
|
|
123
|
+
else
|
|
124
|
+
endpoint = "dataset/#{dataset_id}/decision/#{decision_id}"
|
|
125
|
+
Request.new(endpoint: endpoint, verbose: verbose).perform
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Get duplicate names
|
|
130
|
+
#
|
|
131
|
+
# @param dataset_id [String] The dataset id
|
|
132
|
+
#
|
|
133
|
+
# @param offset [Integer] Offset for pagination
|
|
134
|
+
# @param limit [Integer] Limit for pagination
|
|
135
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
136
|
+
def self.duplicate(dataset_id, offset: nil, limit: nil, verbose: false)
|
|
137
|
+
endpoint = "dataset/#{dataset_id}/duplicate"
|
|
138
|
+
Request.new(endpoint: endpoint, offset: offset, limit: limit, verbose: verbose).perform
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Get names diff between 2 datasets
|
|
142
|
+
#
|
|
143
|
+
# @param dataset_id [String] The first dataset id
|
|
144
|
+
# @param dataset2_id [String] The second dataset id
|
|
145
|
+
# @param root_id [Array, String, nil] The root taxon for the first dataset
|
|
146
|
+
# @param root2_id [Array, String, nil] The root taxon for the second dataset
|
|
147
|
+
# @param min_rank [String, nil] The minimum taxonomic rank
|
|
148
|
+
# @param authorship [Boolean, nil] Include authorship
|
|
149
|
+
# @param include_synonyms [Boolean, nil] Include synonyms
|
|
150
|
+
# @param include_parent [Boolean, nil] Include parent
|
|
151
|
+
# @param parent_rank [String, nil] Filter by parent rank
|
|
152
|
+
# @param token [String, nil] An authentication token from Colrapi.user_login()
|
|
153
|
+
#
|
|
154
|
+
# @param offset [Integer] Offset for pagination
|
|
155
|
+
# @param limit [Integer] Limit for pagination
|
|
156
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
157
|
+
#
|
|
158
|
+
# @return [String, Boolean] A text diff of names
|
|
159
|
+
def self.diff(dataset_id, dataset2_id, root_id: nil, root2_id: nil, min_rank: nil,
|
|
160
|
+
authorship: nil, include_synonyms: nil, include_parent: nil, parent_rank: nil,
|
|
161
|
+
offset: nil, limit: nil, token: nil, verbose: false)
|
|
162
|
+
endpoint = "dataset/#{dataset_id}/diff/#{dataset2_id}"
|
|
163
|
+
Request.new(endpoint: endpoint, root_id: root_id, root2_id: root2_id, min_rank: min_rank,
|
|
164
|
+
authorship: authorship, include_synonyms: include_synonyms,
|
|
165
|
+
include_parent: include_parent, parent_rank: parent_rank,
|
|
166
|
+
offset: offset, limit: limit, token: token, verbose: verbose).perform
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Get editor info
|
|
170
|
+
#
|
|
171
|
+
# @param dataset_id [String] The dataset id
|
|
172
|
+
# @param token [String, nil] The authentication token from retrieved with Colrapi.user_login(user, password)
|
|
173
|
+
#
|
|
174
|
+
# # @return [Array, Hash, Boolean] An array of hashes
|
|
175
|
+
def self.editor(dataset_id, token, verbose: false)
|
|
176
|
+
endpoint = "dataset/#{dataset_id}/editor"
|
|
177
|
+
Request.new(endpoint: endpoint, token: token, verbose: verbose).perform
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Get estimates
|
|
181
|
+
# @param dataset_id [String] The dataset id
|
|
182
|
+
# @param estimate_id [Integer, nil] The estimate ID
|
|
183
|
+
# @param name [String] The scientific name
|
|
184
|
+
# @param rank [String, nil] taxonomic rank
|
|
185
|
+
# @param modified_by [Integer, nil] Filter by a user id on last modified by
|
|
186
|
+
# @param broken [Boolean, nil] Whether the estimate is broken or not
|
|
187
|
+
# @param min [Integer, nil] Filter by the minimum estimate
|
|
188
|
+
# @param max [Integer, nil] Filter by the maximum estimate
|
|
189
|
+
#
|
|
190
|
+
# @param offset [Integer] Offset for pagination
|
|
191
|
+
# @param limit [Integer] Limit for pagination
|
|
192
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
193
|
+
#
|
|
194
|
+
# @return [Hash, Boolean] A results hash
|
|
195
|
+
def self.estimate(dataset_id, estimate_id: nil, name: nil, rank: nil, modified_by: nil, broken: nil, min: nil,
|
|
196
|
+
max: nil, offset: nil, limit: nil, verbose: false)
|
|
197
|
+
endpoint = "dataset/#{dataset_id}/estimate"
|
|
198
|
+
if estimate_id.nil?
|
|
199
|
+
Request.new(endpoint: endpoint, name: name, rank: rank, modified_by: modified_by, broken: broken,
|
|
200
|
+
min: min, max: max, offset: offset, limit: limit, verbose: verbose).perform
|
|
201
|
+
else
|
|
202
|
+
endpoint = "dataset/#{dataset_id}/estimate/#{estimate_id}"
|
|
203
|
+
Request.new(endpoint: endpoint, verbose: verbose).perform
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# TODO: /dataset/{key}/export is covered, but /export and /export/{id} are not
|
|
208
|
+
# Get a dataset export
|
|
209
|
+
#
|
|
210
|
+
# @param dataset_id [String] The dataset id
|
|
211
|
+
# @param show_id [Boolean, nil] TODO: not implemented because it doesn't seem to do anything?
|
|
212
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
213
|
+
#
|
|
214
|
+
# @return [Hash, Boolean] An export hash
|
|
215
|
+
def self.export(dataset_id, show_id: nil, verbose: false)
|
|
216
|
+
endpoint = "dataset/#{dataset_id}/export"
|
|
217
|
+
Request.new(endpoint: endpoint, verbose: verbose).perform
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# Get data quality issues
|
|
221
|
+
#
|
|
222
|
+
# @param dataset_id [String] The dataset id
|
|
223
|
+
# @param issue [String] Filter by data quality issue (e.g., ACCEPTED_NAME_MISSING, DUPLICATE_NAME, URL_INVALID)
|
|
224
|
+
# @param mode [String] Verbatim (default) or interpreted
|
|
225
|
+
#
|
|
226
|
+
# @param offset [Integer] Offset for pagination
|
|
227
|
+
# @param limit [Integer] Limit for pagination
|
|
228
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
229
|
+
#
|
|
230
|
+
# @return [Array, Hash, Boolean] An array of hashes
|
|
231
|
+
def self.issues(dataset_id, issue: nil, mode: 'verbatim', offset: nil, limit: nil, verbose: false)
|
|
232
|
+
if issue.nil?
|
|
233
|
+
metrics = Request.new(endpoint: "/dataset/#{dataset_id}/import?state=finished").perform
|
|
234
|
+
return {"issuesCount" => metrics[0]['issuesCount']}
|
|
235
|
+
else
|
|
236
|
+
if mode == 'interpreted'
|
|
237
|
+
issues = self.vocab(term: 'issue')
|
|
238
|
+
record_type = 'any'
|
|
239
|
+
issues.each do |i|
|
|
240
|
+
if i['name'] == issue.downcase
|
|
241
|
+
record_type = i['group']
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# TODO: so far issues are only filterable on nameusage/search and /reference
|
|
246
|
+
# for other record_types, may need to add other endpoints in the future
|
|
247
|
+
if record_type == 'reference'
|
|
248
|
+
self.reference(dataset_id, issue: issue, offset: offset, limit: limit, verbose: verbose)
|
|
249
|
+
else
|
|
250
|
+
self.nameusage_search(dataset_id: dataset_id, issue: issue, facet: 'issue', offset: offset, limit: limit,
|
|
251
|
+
verbose: verbose)
|
|
252
|
+
end
|
|
253
|
+
else
|
|
254
|
+
self.verbatim(dataset_id, issue: issue, offset: offset, limit: limit, verbose: verbose)
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# Get importer status
|
|
260
|
+
#
|
|
261
|
+
# @param dataset_id [String] Calls the dataset_id endpoint /importer/{dataset_id}
|
|
262
|
+
# @param dataset_id_filter [String] Filters the importer queue by dataset_id
|
|
263
|
+
# @param state [Array, String] The import status (e.g., waiting, preparing, downloading, processing, inserting, ...)
|
|
264
|
+
# @param running [Boolean] Filter by actively importing datasets
|
|
265
|
+
#
|
|
266
|
+
# @param offset [Integer] Offset for pagination
|
|
267
|
+
# @param limit [Integer] Limit for pagination
|
|
268
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
269
|
+
#
|
|
270
|
+
# @return [Array, Boolean] An array of hashes
|
|
271
|
+
def self.importer(dataset_id: nil, dataset_id_filter: nil, state: nil, running: nil, offset: nil, limit: nil,
|
|
272
|
+
verbose: false)
|
|
273
|
+
endpoint = "importer"
|
|
274
|
+
if dataset_id.nil?
|
|
275
|
+
Request.new(endpoint: endpoint, dataset_id_filter: dataset_id_filter, state: state, running: running,
|
|
276
|
+
offset: offset, limit: limit, verbose: verbose).perform
|
|
277
|
+
else
|
|
278
|
+
endpoint = "#{endpoint}/#{dataset_id}"
|
|
279
|
+
Request.new(endpoint: endpoint, verbose: verbose).perform
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
# Get a dataset's logo
|
|
284
|
+
#
|
|
285
|
+
# @param dataset_id [String] The dataset id
|
|
286
|
+
# @param size [String] The size of the logo (original, large, medium, small)
|
|
287
|
+
#
|
|
288
|
+
# @return [Binary] The dataset logo
|
|
289
|
+
def self.logo(dataset_id, size: nil, verbose: false)
|
|
290
|
+
endpoint = "dataset/#{dataset_id}/logo"
|
|
291
|
+
Request.new(endpoint: endpoint, size: size, verbose: verbose).perform
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
# Get names or a name from a dataset
|
|
295
|
+
#
|
|
296
|
+
# @param dataset_id [String] The dataset id
|
|
297
|
+
# @param name [String] The scientific name to match
|
|
298
|
+
# @param authorship [String] The authorship string for the scientific name
|
|
299
|
+
# @param code [String] The nomenclatural code (bacterial, botanical, cultivars, phytosociological, virus, zoological)
|
|
300
|
+
# @param rank [String] The rank of the scientific name
|
|
301
|
+
# @param within_superkingdom [String] Restricts query to within a superkingdom
|
|
302
|
+
# @param within_kingdom [String] Restricts query to within a kingdom
|
|
303
|
+
# @param within_subkingdom [String] Restricts query to within a subkingdom
|
|
304
|
+
# @param within_superphylum [String] Restricts query to within a superphylum
|
|
305
|
+
# @param within_phylum [String] Restricts query to within a phylum
|
|
306
|
+
# @param within_subphylum [String] Restricts query to within a subphylum
|
|
307
|
+
# @param within_superclass [String] Restricts query to within a superclass
|
|
308
|
+
# @param within_class [String] Restricts query to within a class
|
|
309
|
+
# @param within_subclass [String] Restricts query to within a subclass
|
|
310
|
+
# @param within_superorder [String] Restricts query to within a superorder
|
|
311
|
+
# @param within_order [String] Restricts query to within a order
|
|
312
|
+
# @param within_suborder [String] Restricts query to within a suborder
|
|
313
|
+
# @param within_superfamily [String] Restricts query to within a superfamily
|
|
314
|
+
# @param within_family [String] Restricts query to within a family
|
|
315
|
+
# @param within_subfamily [String] Restricts query to within a subfamily
|
|
316
|
+
# @param within_tribe [String] Restricts query to within a tribe
|
|
317
|
+
# @param within_subtribe [String] Restricts query to within a subtribe
|
|
318
|
+
# @param within_genus [String] Restricts query to within a genus
|
|
319
|
+
# @param within_subgenus [String] Restricts query to within a subgenus
|
|
320
|
+
# @param within_section [String] Restricts query to within a section
|
|
321
|
+
# @param within_species [String] Restricts query to within a species
|
|
322
|
+
#
|
|
323
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
324
|
+
#
|
|
325
|
+
# @return [Array, Boolean] An array of hashes
|
|
326
|
+
# def self.matching(dataset_id, name: nil, authorship: nil, code: nil, rank: nil, within_superkingdom: nil,
|
|
327
|
+
# within_kingdom: nil, within_subkingdom: nil, within_superphylum: nil, within_phylum: nil,
|
|
328
|
+
# within_subphylum: nil, within_superclass: nil, within_class: nil, within_subclass: nil,
|
|
329
|
+
# within_superorder: nil, within_order: nil, within_suborder: nil, within_superfamily: nil,
|
|
330
|
+
# within_family: nil, within_subfamily: nil, within_tribe: nil, within_subtribe: nil,
|
|
331
|
+
# within_genus: nil, within_subgenus: nil, within_section: nil, within_species: nil,
|
|
332
|
+
# verbose: false)
|
|
333
|
+
# endpoint = "dataset/#{dataset_id}/matching"
|
|
334
|
+
# Request.new(endpoint: endpoint, name: name, authorship: authorship, code: code, rank: rank,
|
|
335
|
+
# within_superkingdom: within_superkingdom, within_kingdom: within_kingdom,
|
|
336
|
+
# within_subkingdom: within_subkingdom, within_superphylum: within_superphylum,
|
|
337
|
+
# within_phylum: within_phylum, within_subphylum: within_subphylum, within_superclass: within_superclass,
|
|
338
|
+
# within_class: within_class, within_subclass: within_subclass, within_superorder: within_superorder,
|
|
339
|
+
# within_order: within_order, within_suborder: within_suborder, within_superfamily: within_superfamily,
|
|
340
|
+
# within_family: within_family, within_subfamily: within_subfamily, within_tribe: within_tribe,
|
|
341
|
+
# within_subtribe: within_subtribe, within_genus: within_genus, within_subgenus: within_subgenus,
|
|
342
|
+
# within_section: within_section, within_species: within_species, verbose: verbose).perform
|
|
343
|
+
# end
|
|
344
|
+
|
|
345
|
+
# Get metrics for the *last successful* import of a dataset or a specific import_attempt
|
|
346
|
+
#
|
|
347
|
+
# @param dataset_id [String] The dataset id
|
|
348
|
+
# @param import_attempt [Integer] The import attempt
|
|
349
|
+
#
|
|
350
|
+
# @return [Array, Hash, Boolean] An array of hashes
|
|
351
|
+
def self.metrics(dataset_id, import_attempt: nil, verbose: false)
|
|
352
|
+
|
|
353
|
+
import = self.importer(dataset_id: dataset_id)
|
|
354
|
+
unless %w[unchanged finished].include? import['state']
|
|
355
|
+
return {"code" => 400, 'message' => 'Dataset has not finished importing or failed to import'}
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
# it's necessary to get the last finished import attempt because status=unchanged import results don't have metrics
|
|
359
|
+
# project release datasets do not seem to have import_attempts or should be taken from the project dataset, e.g.:
|
|
360
|
+
# https://api.checklistbank.org/dataset/3/import/107 == https://api.checklistbank.org/dataset/9837/import
|
|
361
|
+
if import_attempt.nil?
|
|
362
|
+
import = self.importer(dataset_id_filter: dataset_id, state: 'finished')
|
|
363
|
+
if import['total'] > 0
|
|
364
|
+
import_attempt = import['result'][0]['attempt']
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
endpoint = "dataset/#{dataset_id}/import"
|
|
369
|
+
if !import_attempt.nil?
|
|
370
|
+
endpoint = "#{endpoint}/#{import_attempt}"
|
|
371
|
+
Request.new(endpoint: endpoint, verbose: verbose).perform
|
|
372
|
+
else
|
|
373
|
+
# /dataset/{id}/import returns an array of 1 item while /dataset/{id}/import/{attempt} doesn't
|
|
374
|
+
res = Request.new(endpoint: endpoint, verbose: verbose).perform
|
|
375
|
+
res[0]
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
# Get names or a name from a dataset
|
|
380
|
+
#
|
|
381
|
+
# @param dataset_id [String] The dataset id
|
|
382
|
+
# @param name_id [String] The name id
|
|
383
|
+
# @param subresource [String] The name subresource endpoint (relations, synonyms, types, or orphans)
|
|
384
|
+
#
|
|
385
|
+
# @param offset [Integer] Offset for pagination
|
|
386
|
+
# @param limit [Integer] Limit for pagination
|
|
387
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
388
|
+
#
|
|
389
|
+
# @return [Array, Boolean] An array of hashes
|
|
390
|
+
def self.name(dataset_id, name_id: nil, subresource: nil, offset: nil, limit: nil, verbose: false)
|
|
391
|
+
endpoint = "dataset/#{dataset_id}/name"
|
|
392
|
+
unless name_id.nil?
|
|
393
|
+
endpoint = "#{endpoint}/#{name_id}"
|
|
394
|
+
offset = nil
|
|
395
|
+
limit = nil
|
|
396
|
+
end
|
|
397
|
+
if !subresource.nil? and %w[relations synonyms types orphans].include? subresource
|
|
398
|
+
endpoint = "#{endpoint}/#{subresource}"
|
|
399
|
+
end
|
|
400
|
+
Request.new(endpoint: endpoint, offset: offset, limit: limit, verbose: verbose).perform
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
# Get a text list of names for a dataset
|
|
404
|
+
#
|
|
405
|
+
# @param dataset_id [String] The dataset id
|
|
406
|
+
# @param import_attempt [Integer] The import attempt number
|
|
407
|
+
#
|
|
408
|
+
def self.name_list(dataset_id, import_attempt: nil, verbose: nil)
|
|
409
|
+
|
|
410
|
+
# get last import attempt number if none given
|
|
411
|
+
if import_attempt.nil?
|
|
412
|
+
import = self.importer(dataset_id: dataset_id)
|
|
413
|
+
import_attempt = import['attempt']
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
endpoint = "dataset/#{dataset_id}/import/#{import_attempt}/names"
|
|
417
|
+
Request.new(endpoint: endpoint, verbose: verbose).perform
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
# Get a text tree of names for a dataset
|
|
421
|
+
#
|
|
422
|
+
# @param dataset_id [String] The dataset id
|
|
423
|
+
# @param import_attempt [Integer] The import attempt number
|
|
424
|
+
#
|
|
425
|
+
def self.name_tree(dataset_id, import_attempt: nil, verbose: nil)
|
|
426
|
+
|
|
427
|
+
# get last import attempt number if none given
|
|
428
|
+
if import_attempt.nil?
|
|
429
|
+
import = self.importer(dataset_id: dataset_id)
|
|
430
|
+
import_attempt = import['attempt']
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
endpoint = "dataset/#{dataset_id}/import/#{import_attempt}/tree"
|
|
434
|
+
Request.new(endpoint: endpoint, verbose: verbose).perform
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
# Get name usages or a nameusage from a dataset
|
|
438
|
+
# Note: Queries the PSQL database, whereas nameusage_search uses Elastic Search
|
|
439
|
+
#
|
|
440
|
+
# @param dataset_id [String] The dataset id
|
|
441
|
+
# @param nameusage_id [String] The nameusage id
|
|
442
|
+
# @param q [String] The scientific name or authorship search query
|
|
443
|
+
# @param rank [Array, String] The rank of the taxon in the search query q
|
|
444
|
+
# @param nidx_id [String] The name index id
|
|
445
|
+
# @param subresource [String] The name subresource endpoint (relations, synonyms, types, or orphans)
|
|
446
|
+
#
|
|
447
|
+
# @param offset [Integer] Offset for pagination
|
|
448
|
+
# @param limit [Integer] Limit for pagination
|
|
449
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
450
|
+
#
|
|
451
|
+
# @return [Array, Boolean] An array of hashes
|
|
452
|
+
def self.nameusage(dataset_id, nameusage_id: nil, q: nil, rank: nil, nidx_id: nil, subresource: nil,
|
|
453
|
+
offset: nil, limit: nil, verbose: false)
|
|
454
|
+
endpoint = "dataset/#{dataset_id}/nameusage"
|
|
455
|
+
unless nameusage_id.nil?
|
|
456
|
+
endpoint = "#{endpoint}/#{nameusage_id}"
|
|
457
|
+
offset = nil
|
|
458
|
+
limit = nil
|
|
459
|
+
end
|
|
460
|
+
unless subresource.nil?
|
|
461
|
+
endpoint = "#{endpoint}/#{subresource}"
|
|
462
|
+
end
|
|
463
|
+
Request.new(endpoint: endpoint, q: q, rank: rank, nidx_id: nidx_id, offset: offset, limit: limit,
|
|
464
|
+
verbose: verbose).perform
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
# TODO: /dataset/{key}/nameusage/{id}/related not covered
|
|
468
|
+
# TODO: /dataset/{key}/nameusage/{id}/source not covered
|
|
469
|
+
|
|
470
|
+
# Get names or a name from a dataset
|
|
471
|
+
#
|
|
472
|
+
# @param dataset_id [String] The dataset id
|
|
473
|
+
# @param name [String] The scientific name to match
|
|
474
|
+
# @param authorship [String] The authorship string for the scientific name
|
|
475
|
+
# @param code [String] The nomenclatural code (bacterial, botanical, cultivars, phytosociological, virus, zoological)
|
|
476
|
+
# @param rank [String] The rank of the scientific name
|
|
477
|
+
# @param within_superkingdom [String] Restricts query to within a superkingdom
|
|
478
|
+
# @param within_kingdom [String] Restricts query to within a kingdom
|
|
479
|
+
# @param within_subkingdom [String] Restricts query to within a subkingdom
|
|
480
|
+
# @param within_superphylum [String] Restricts query to within a superphylum
|
|
481
|
+
# @param within_phylum [String] Restricts query to within a phylum
|
|
482
|
+
# @param within_subphylum [String] Restricts query to within a subphylum
|
|
483
|
+
# @param within_superclass [String] Restricts query to within a superclass
|
|
484
|
+
# @param within_class [String] Restricts query to within a class
|
|
485
|
+
# @param within_subclass [String] Restricts query to within a subclass
|
|
486
|
+
# @param within_superorder [String] Restricts query to within a superorder
|
|
487
|
+
# @param within_order [String] Restricts query to within a order
|
|
488
|
+
# @param within_suborder [String] Restricts query to within a suborder
|
|
489
|
+
# @param within_superfamily [String] Restricts query to within a superfamily
|
|
490
|
+
# @param within_family [String] Restricts query to within a family
|
|
491
|
+
# @param within_subfamily [String] Restricts query to within a subfamily
|
|
492
|
+
# @param within_tribe [String] Restricts query to within a tribe
|
|
493
|
+
# @param within_subtribe [String] Restricts query to within a subtribe
|
|
494
|
+
# @param within_genus [String] Restricts query to within a genus
|
|
495
|
+
# @param within_subgenus [String] Restricts query to within a subgenus
|
|
496
|
+
# @param within_section [String] Restricts query to within a section
|
|
497
|
+
# @param within_species [String] Restricts query to within a species
|
|
498
|
+
#
|
|
499
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
500
|
+
#
|
|
501
|
+
# @return [Array, Boolean] An array of hashes
|
|
502
|
+
def self.matching(dataset_id, name: nil, authorship: nil, code: nil, rank: nil, within_superkingdom: nil,
|
|
503
|
+
within_kingdom: nil, within_subkingdom: nil, within_superphylum: nil, within_phylum: nil,
|
|
504
|
+
within_subphylum: nil, within_superclass: nil, within_class: nil, within_subclass: nil,
|
|
505
|
+
within_superorder: nil, within_order: nil, within_suborder: nil, within_superfamily: nil,
|
|
506
|
+
within_family: nil, within_subfamily: nil, within_tribe: nil, within_subtribe: nil,
|
|
507
|
+
within_genus: nil, within_subgenus: nil, within_section: nil, within_species: nil,
|
|
508
|
+
verbose: false)
|
|
509
|
+
endpoint = "dataset/#{dataset_id}/nameusage/match"
|
|
510
|
+
Request.new(endpoint: endpoint, name: name, authorship: authorship, code: code, rank: rank,
|
|
511
|
+
within_superkingdom: within_superkingdom, within_kingdom: within_kingdom,
|
|
512
|
+
within_subkingdom: within_subkingdom, within_superphylum: within_superphylum,
|
|
513
|
+
within_phylum: within_phylum, within_subphylum: within_subphylum, within_superclass: within_superclass,
|
|
514
|
+
within_class: within_class, within_subclass: within_subclass, within_superorder: within_superorder,
|
|
515
|
+
within_order: within_order, within_suborder: within_suborder, within_superfamily: within_superfamily,
|
|
516
|
+
within_family: within_family, within_subfamily: within_subfamily, within_tribe: within_tribe,
|
|
517
|
+
within_subtribe: within_subtribe, within_genus: within_genus, within_subgenus: within_subgenus,
|
|
518
|
+
within_section: within_section, within_species: within_species, verbose: verbose).perform
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
# Search for a name usage with a regex pattern
|
|
522
|
+
#
|
|
523
|
+
# @param dataset_id [String, nil] restricts name usage pattern search within a dataset
|
|
524
|
+
# @param regexp [String] The regular expression pattern
|
|
525
|
+
# @param status [String, nil] The taxonomic status (accepted, provisionally_accepted, synonym, ambiguous_synonym, misapplied, bare_name)
|
|
526
|
+
# @param rank [String, nil] The taxonomic rank
|
|
527
|
+
# @param project_id [String, nil] Filter to names from project_id, required if decision_mode used
|
|
528
|
+
# @param decision_mode [String, nil] The type of decision (block, reviewed, update, update_recursive, ignore)
|
|
529
|
+
#
|
|
530
|
+
# @param offset [Integer] Offset for pagination
|
|
531
|
+
# @param limit [Integer] Limit for pagination
|
|
532
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
533
|
+
def self.nameusage_pattern(dataset_id, regexp, status: nil, rank: nil, project_id: nil, decision_mode: nil,
|
|
534
|
+
offset: nil, limit: nil, verbose: false)
|
|
535
|
+
endpoint = "dataset/#{dataset_id}/nameusage/pattern"
|
|
536
|
+
Request.new(endpoint: endpoint, regexp: regexp, project_id: project_id, status: status, rank: rank,
|
|
537
|
+
decision_mode: decision_mode, offset: offset, limit: limit, verbose: verbose).perform
|
|
538
|
+
end
|
|
539
|
+
|
|
540
|
+
# Search the nameusage route, which uses Elastic Search
|
|
541
|
+
#
|
|
542
|
+
# @param q [String] A query string
|
|
543
|
+
# @param dataset_id [String, nil] restricts name usage search within a dataset
|
|
544
|
+
# @param endpoint [String, nil] some endpoints have nested options
|
|
545
|
+
# @param content [Array, String, nil] restrict search to SCIENTIFIC_NAME, or AUTHORSHIP
|
|
546
|
+
# @param issue [Array, String, nil] the data quality issue
|
|
547
|
+
# @param type [String, nil] sets the type of search to PREFIX, WHOLE_WORDS, or EXACT
|
|
548
|
+
# @param rank [String, nil] taxonomic rank of name usages
|
|
549
|
+
# @param min_rank [String, nil] minimum taxonomic rank of name usages
|
|
550
|
+
# @param max_rank [String, nil] maximum taxonomic rank of name usages
|
|
551
|
+
# @param facet [Array, String, nil] the search facet
|
|
552
|
+
#
|
|
553
|
+
# @param sort_by [String, nil] sort results by NAME, TAXONOMIC, INDEX_NAME_ID, NATIVE, or RELEVANCE
|
|
554
|
+
# @param reverse [Boolean] sort in reverse order
|
|
555
|
+
# @param offset [Integer] Offset for pagination
|
|
556
|
+
# @param limit [Integer] Limit for pagination
|
|
557
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
558
|
+
#
|
|
559
|
+
# @return [Array, Boolean] An array of hashes
|
|
560
|
+
def self.nameusage_search(q: nil, dataset_id: nil, endpoint: 'nameusage/search', content: nil, issue: nil,
|
|
561
|
+
type: nil, rank: nil, min_rank: nil, max_rank: nil, facet: nil,
|
|
562
|
+
sort_by: nil, reverse: nil, offset: nil, limit: nil,
|
|
563
|
+
verbose: false)
|
|
564
|
+
|
|
565
|
+
# a nil dataset_id will search name usages from all datasets in ChecklistBank
|
|
566
|
+
unless dataset_id.nil?
|
|
567
|
+
endpoint = "dataset/#{dataset_id}/nameusage/search"
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
Request.new(endpoint: endpoint, q: q, content: content, issue: issue, type: type,
|
|
571
|
+
rank: rank, min_rank: min_rank, max_rank: max_rank, facet: facet,
|
|
572
|
+
sort_by: sort_by, reverse: reverse, offset: offset, limit: limit, verbose: verbose).perform
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
# Get a name usage suggestion
|
|
576
|
+
#
|
|
577
|
+
# @param dataset_id [String] restricts name usage search within a dataset
|
|
578
|
+
# @param q [String] A suggestion search query
|
|
579
|
+
# @param fuzzy [Boolean, nil] Whether to include fuzzy matches for misspellings (TODO: might not actually work?)
|
|
580
|
+
# @param min_rank [String, nil] The minimum rank to suggest
|
|
581
|
+
# @param max_rank [String, nil] The maximum rank to suggest
|
|
582
|
+
# @param sort_by [String, nil] The sorting order (name, taxonomic, index_name_id, native, relevance)
|
|
583
|
+
# @param reverse [Boolean, nil] Sort in opposite order
|
|
584
|
+
# @param accepted [Boolean, nil] Suggest only accepted names
|
|
585
|
+
#
|
|
586
|
+
# @limit [Integer, nil] Limit the suggestion number (offset not available)
|
|
587
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
588
|
+
#
|
|
589
|
+
# @return [Hash, Boolean] A a hash of name usage suggestions
|
|
590
|
+
def self.nameusage_suggest(dataset_id, q, fuzzy: nil, min_rank: nil, max_rank: nil, sort_by: nil, reverse: nil,
|
|
591
|
+
accepted: nil, limit: nil, verbose: false)
|
|
592
|
+
endpoint = "dataset/#{dataset_id}/nameusage/suggest"
|
|
593
|
+
Request.new(endpoint: endpoint, q: q, fuzzy: fuzzy, min_rank: min_rank, max_rank: max_rank, sort_by: sort_by,
|
|
594
|
+
reverse: reverse, accepted: accepted, limit: limit, verbose: verbose).perform
|
|
595
|
+
end
|
|
596
|
+
|
|
597
|
+
# Get names index info
|
|
598
|
+
#
|
|
599
|
+
# @param nidx_id [Integer] a names index ID
|
|
600
|
+
# @param subresource [String, nil] the subresource (group)
|
|
601
|
+
def self.nidx(nidx_id, subresource: nil, verbose: false)
|
|
602
|
+
endpoint = "nidx/#{nidx_id}"
|
|
603
|
+
endpoint = "nidx/#{nidx_id}/#{subresource}" unless subresource.nil?
|
|
604
|
+
Request.new(endpoint: endpoint, verbose: verbose).perform
|
|
605
|
+
end
|
|
606
|
+
|
|
607
|
+
# Get names index matches
|
|
608
|
+
# @param q [String, nil] A match query
|
|
609
|
+
# @param authorship [String, nil] An authorship string
|
|
610
|
+
# @param rank [String, nil] The taxonomic rank
|
|
611
|
+
# @param code [String, nil] The nomenclatural code
|
|
612
|
+
#
|
|
613
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
614
|
+
#
|
|
615
|
+
# @return [Hash, Boolean] A match hash
|
|
616
|
+
def self.nidx_match(q, authorship: nil, rank: nil, code: nil, verbose: false)
|
|
617
|
+
endpoint = "nidx/match"
|
|
618
|
+
Request.new(endpoint: endpoint, q: q, authorship: authorship, rank: rank, code: code, verbose: verbose).perform
|
|
619
|
+
end
|
|
620
|
+
|
|
621
|
+
# Parse a {subresource}
|
|
622
|
+
#
|
|
623
|
+
# This is the generic parser wrapper. For specialized parsers, like the names, homoglyphs, idconverter, metadata,
|
|
624
|
+
# use the specialized parsers below like Colrapi.parser_name(). Returns a list of parsers if no subresource given.
|
|
625
|
+
#
|
|
626
|
+
# @param subresource [String] the type of parser to use
|
|
627
|
+
# @param q [Array, String] a query string or array of query strings to parse
|
|
628
|
+
#
|
|
629
|
+
# @return [Array, Hash, Boolean] An array of parsers, or a parser result hash
|
|
630
|
+
def self.parser(subresource: nil, q: nil, verbose: false)
|
|
631
|
+
endpoint = "parser"
|
|
632
|
+
endpoint = "#{endpoint}/#{subresource}" unless subresource.nil?
|
|
633
|
+
Request.new(endpoint: endpoint, q: q, verbose: verbose).perform
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
# Encode or decode identifiers to different formats (e.g., proquints are used as stable identifiers in ChecklistBank)
|
|
637
|
+
# @param mode [String] encode or decode
|
|
638
|
+
# @param id [String] the identifier to convert
|
|
639
|
+
# @param format [String] the format (proquint, hex, latin29, latin32, latin36, base64)
|
|
640
|
+
#
|
|
641
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
642
|
+
#
|
|
643
|
+
# @return [String, Integer, Boolean] A parser result hash
|
|
644
|
+
def self.parser_idconverter(mode, id, format, verbose: false)
|
|
645
|
+
endpoint = "parser/idconverter/#{mode}"
|
|
646
|
+
Request.new(endpoint: endpoint, id: id, format: format, verbose: verbose).perform
|
|
647
|
+
end
|
|
648
|
+
|
|
649
|
+
# Parse metadata
|
|
650
|
+
# @param url [String] The url to a metadata file
|
|
651
|
+
# @param format [String] The format of the metadata (yaml, json, eml, datacite, zenodo)
|
|
652
|
+
#
|
|
653
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
654
|
+
#
|
|
655
|
+
# @return [String, Integer, Boolean] A parser result hash
|
|
656
|
+
def self.parser_metadata(url, format: nil, verbose: false)
|
|
657
|
+
endpoint = 'parser/metadata'
|
|
658
|
+
Request.new(endpoint: endpoint, url: url, format: format, verbose: verbose).perform
|
|
659
|
+
end
|
|
660
|
+
|
|
661
|
+
# Parse a scientific name
|
|
662
|
+
#
|
|
663
|
+
# @param name [String] The scientific name to parse
|
|
664
|
+
# @param authorship [String, nil] The authorship string for the scientific name
|
|
665
|
+
# @param rank [String, nil] The rank of the scientific name to parse
|
|
666
|
+
# @param code [String] The nomenclatural code (bacterial, botanical, cultivars, phytosociological, virus, zoological)
|
|
667
|
+
#
|
|
668
|
+
# @return [Hash, Boolean] A hash with the parsed scientific name
|
|
669
|
+
def self.parser_name(name, authorship: nil, rank: nil, code: nil, verbose: false)
|
|
670
|
+
endpoint = 'parser/name'
|
|
671
|
+
Request.new(endpoint: endpoint, name: name, authorship: authorship, rank: rank, code: code,
|
|
672
|
+
verbose: verbose).perform
|
|
673
|
+
end
|
|
674
|
+
|
|
675
|
+
# Get metadata patch
|
|
676
|
+
#
|
|
677
|
+
# @param dataset_id [String] The dataset id
|
|
678
|
+
# @param token [String, nil] The authentication token from retrieved with Colrapi.user_login(user, password)
|
|
679
|
+
def self.patch(dataset_id, patch_id: nil, token: nil, verbose: false)
|
|
680
|
+
endpoint = "dataset/#{dataset_id}/patch"
|
|
681
|
+
unless patch_id.nil?
|
|
682
|
+
endpoint = "#{endpoint}/#{patch_id}"
|
|
683
|
+
end
|
|
684
|
+
Request.new(endpoint: endpoint, token: token, verbose: verbose).perform
|
|
685
|
+
end
|
|
686
|
+
|
|
687
|
+
# Get the latest preview release metadata (or points to the project draft dataset after the preview is released?)
|
|
688
|
+
# (Note: you can also use 3LRC where 3 is the project_id as an ID on any endpoint with dataset_id or project_id
|
|
689
|
+
# to get data from the latest release candidate, or 3LR gets the latest release)
|
|
690
|
+
# @param project_id [String] The project id
|
|
691
|
+
#
|
|
692
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
693
|
+
# @return [Array, Boolean] An array of hashes
|
|
694
|
+
def self.preview(project_id, verbose: false)
|
|
695
|
+
Request.new(endpoint: "dataset/#{project_id}/preview", verbose: verbose).perform
|
|
696
|
+
end
|
|
697
|
+
|
|
698
|
+
# Get a reference with @reference_id from dataset @dataset_id via the reference route
|
|
699
|
+
#
|
|
700
|
+
# @param dataset_id [String] The dataset id
|
|
701
|
+
# @param reference_id [String] The reference id
|
|
702
|
+
# @param subresource [String] The reference subresource endpoint (orphans)
|
|
703
|
+
# @param issue [Array, String] The data quality issue (https://api.checklistbank.org/vocab/issue)
|
|
704
|
+
#
|
|
705
|
+
# @param offset [Integer] Offset for pagination
|
|
706
|
+
# @param limit [Integer] Limit for pagination
|
|
707
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
708
|
+
#
|
|
709
|
+
# @return [Array, Boolean] An array of hashes
|
|
710
|
+
def self.reference(dataset_id, reference_id: nil, subresource: nil, issue: nil, offset: nil, limit: nil,
|
|
711
|
+
verbose: false)
|
|
712
|
+
endpoint = "dataset/#{dataset_id}/reference"
|
|
713
|
+
if subresource == 'orphans'
|
|
714
|
+
reference_id = nil
|
|
715
|
+
endpoint = "#{endpoint}/orphans"
|
|
716
|
+
end
|
|
717
|
+
unless reference_id.nil?
|
|
718
|
+
endpoint = "#{endpoint}/#{reference_id}"
|
|
719
|
+
end
|
|
720
|
+
Request.new(endpoint: endpoint, issue: issue, offset: offset, limit: limit, verbose: verbose).perform
|
|
721
|
+
end
|
|
722
|
+
|
|
723
|
+
# Get reviewer info
|
|
724
|
+
#
|
|
725
|
+
# @param dataset_id [String] The dataset id
|
|
726
|
+
# @param token [String, nil] The authentication token from retrieved with Colrapi.user_login(user, password)
|
|
727
|
+
#
|
|
728
|
+
# # @return [Array, Hash, Boolean] An array of hashes
|
|
729
|
+
def self.reviewer(dataset_id, token, verbose: false)
|
|
730
|
+
endpoint = "dataset/#{dataset_id}/reviewer"
|
|
731
|
+
Request.new(endpoint: endpoint, token: token, verbose: verbose).perform
|
|
732
|
+
end
|
|
733
|
+
|
|
734
|
+
# Get sector metadata, which allows importing datasets into project subtrees
|
|
735
|
+
#
|
|
736
|
+
# @param dataset_id [String] The dataset id
|
|
737
|
+
# @param sector_id [Integer, nil] The sector id
|
|
738
|
+
# @param name [String] The scientific name to query
|
|
739
|
+
# @param rank [String, nil] The rank of the scientific name
|
|
740
|
+
# @param modified_by [Integer, nil] Filter by a user id on last modified by
|
|
741
|
+
# @param broken [Boolean, nil] Whether the decision is broken or not
|
|
742
|
+
# @param subject_dataset_id [String, nil] The source dataset id
|
|
743
|
+
# @param last_synced_before [Date, nil] Filter by sectors synced before this date
|
|
744
|
+
# @param mode [String, nil] Filter by type of sector (attach, union, merge)
|
|
745
|
+
# @param subject [Boolean, nil] TODO: what does this do? All decisions with subject=true are bare names, so maybe it checks if the subject taxon exists?
|
|
746
|
+
# @param min_size [Integer, nil] The minimum number of records in the sector
|
|
747
|
+
# @param without_data [Boolean, nil] Filters to empty sectors with no data synced into the project yet
|
|
748
|
+
#
|
|
749
|
+
# @param offset [Integer] Offset for pagination
|
|
750
|
+
# @param limit [Integer] Limit for pagination
|
|
751
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
752
|
+
#
|
|
753
|
+
# @return [Hash, Boolean] An hash of results
|
|
754
|
+
def self.sector(dataset_id, sector_id: nil, name: nil, rank: nil, modified_by: nil, broken: nil,
|
|
755
|
+
subject_dataset_id: nil, last_synced_before: nil, mode: nil, subject: nil, min_size: nil, without_data: nil,
|
|
756
|
+
offset: nil, limit: nil, verbose: false)
|
|
757
|
+
endpoint = "dataset/#{dataset_id}/sector"
|
|
758
|
+
if sector_id.nil?
|
|
759
|
+
Request.new(endpoint: endpoint, name: name, rank: rank, modified_by: modified_by, broken: broken,
|
|
760
|
+
subject_dataset_id: subject_dataset_id, last_synced_before: last_synced_before, mode: mode,
|
|
761
|
+
subject: subject, min_size: min_size, without_data: without_data,
|
|
762
|
+
offset: offset, limit: limit, verbose: verbose).perform
|
|
763
|
+
else
|
|
764
|
+
endpoint = "#{endpoint}/#{sector_id}"
|
|
765
|
+
Request.new(endpoint: endpoint, verbose: verbose).perform
|
|
766
|
+
end
|
|
767
|
+
end
|
|
768
|
+
|
|
769
|
+
# Get sector sync info
|
|
770
|
+
#
|
|
771
|
+
# @param dataset_id [String] The dataset id
|
|
772
|
+
# @param sector_id [Integer, nil] The sector id
|
|
773
|
+
# @param state [Array, String, nil] The sector sync state (e.g., waiting, processing, inserting, indexing, finished, etc.)
|
|
774
|
+
# @param running [Boolean, nil] Filter to sector syncs that are only running
|
|
775
|
+
# @param attempt [Integer, nil] The sync attempt number for sector_id
|
|
776
|
+
# @param subresource [String, nil] The subresource for attempt (names or tree)
|
|
777
|
+
#
|
|
778
|
+
# @param offset [Integer] Offset for pagination
|
|
779
|
+
# @param limit [Integer] Limit for pagination
|
|
780
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
781
|
+
#
|
|
782
|
+
# @return [Hash, Boolean] An hash of results
|
|
783
|
+
def self.sector_sync(dataset_id, sector_id: nil, attempt: nil, subresource: nil, state: nil, running: nil, offset: nil, limit: nil, verbose: false)
|
|
784
|
+
endpoint = "dataset/#{dataset_id}/sector/sync"
|
|
785
|
+
if sector_id.nil?
|
|
786
|
+
Request.new(endpoint: endpoint, state: state, running: running, offset: offset, limit: limit,
|
|
787
|
+
verbose:verbose).perform
|
|
788
|
+
else
|
|
789
|
+
if attempt.nil?
|
|
790
|
+
endpoint = "dataset/#{dataset_id}/sector/#{sector_id}/sync"
|
|
791
|
+
else
|
|
792
|
+
endpoint = "dataset/#{dataset_id}/sector/#{sector_id}/sync/#{attempt}"
|
|
793
|
+
endpoint = "#{endpoint}/#{subresource}" unless subresource.nil?
|
|
794
|
+
end
|
|
795
|
+
Request.new(endpoint: endpoint, verbose:verbose).perform
|
|
796
|
+
end
|
|
797
|
+
end
|
|
798
|
+
|
|
799
|
+
# Get source metadata for datasets assembled into a project dataset
|
|
800
|
+
#
|
|
801
|
+
# @param dataset_id [String] The project dataset id
|
|
802
|
+
# @param source_id [String] The source dataset id
|
|
803
|
+
# @param not_current_only [String] Return only not current sources
|
|
804
|
+
# @param original [String] TODO: what does this do?
|
|
805
|
+
#
|
|
806
|
+
# @return [Array, Hash, Boolean] An array of source hashes, or a hash of a source
|
|
807
|
+
def self.source(dataset_id, source_id: nil, not_current_only: nil, original: nil, verbose: false)
|
|
808
|
+
endpoint = "dataset/#{dataset_id}/source"
|
|
809
|
+
if source_id.nil?
|
|
810
|
+
Request.new(endpoint: endpoint, not_current_only: not_current_only, verbose: verbose).perform
|
|
811
|
+
else
|
|
812
|
+
endpoint = "dataset/#{dataset_id}/source/#{source_id}"
|
|
813
|
+
Request.new(endpoint: endpoint, original: original, verbose: verbose).perform
|
|
814
|
+
end
|
|
815
|
+
end
|
|
816
|
+
|
|
817
|
+
|
|
818
|
+
# Get the dataset settings
|
|
819
|
+
# @param dataset_id [String] The dataset id
|
|
820
|
+
#
|
|
821
|
+
# @return [Hash, Boolean] A hash including the dataset settings
|
|
822
|
+
def self.settings(dataset_id)
|
|
823
|
+
Request.new(endpoint: "dataset/#{dataset_id}/settings").perform
|
|
824
|
+
end
|
|
825
|
+
|
|
826
|
+
# Get a synonym with @synonym_id from dataset @dataset_id via the synonym route
|
|
827
|
+
#
|
|
828
|
+
# @param dataset_id [String] The dataset id
|
|
829
|
+
# @param synonym_id [String] The synonym id
|
|
830
|
+
# @param subresource [String] The synonym subresource endpoint (source)
|
|
831
|
+
#
|
|
832
|
+
# @param offset [Integer] Offset for pagination
|
|
833
|
+
# @param limit [Integer] Limit for pagination
|
|
834
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
835
|
+
#
|
|
836
|
+
# @return [Array, Boolean] An array of hashes
|
|
837
|
+
def self.synonym(dataset_id, synonym_id: nil, subresource: nil, offset: nil, limit: nil, verbose: false)
|
|
838
|
+
endpoint = "dataset/#{dataset_id}/synonym"
|
|
839
|
+
unless synonym_id.nil?
|
|
840
|
+
endpoint = "#{endpoint}/#{synonym_id}"
|
|
841
|
+
end
|
|
842
|
+
if subresource == 'source'
|
|
843
|
+
endpoint = "#{endpoint}/source"
|
|
844
|
+
end
|
|
845
|
+
Request.new(endpoint: endpoint, offset: offset, limit: limit, verbose: verbose).perform
|
|
846
|
+
end
|
|
847
|
+
|
|
848
|
+
# Get the full list of taxon IDs for a dataset (returns 1 ID string per line, not JSON)
|
|
849
|
+
#
|
|
850
|
+
# @param dataset_id [String] The dataset id
|
|
851
|
+
#
|
|
852
|
+
# @return [Array, Boolean] An array of hashes
|
|
853
|
+
def self.taxon_ids(dataset_id, verbose: false)
|
|
854
|
+
Request.new(endpoint: "dataset/#{dataset_id}/taxon/ids", verbose: verbose).perform
|
|
855
|
+
end
|
|
856
|
+
|
|
857
|
+
# Get a taxon with @id from dataset @dataset_id via the taxon route
|
|
858
|
+
#
|
|
859
|
+
# @param dataset_id [String] The dataset id
|
|
860
|
+
# @param taxon_id [String] The taxon id
|
|
861
|
+
# @param subresource [String] The taxon subresource endpoint (classification, distribution, info, interaction, media,
|
|
862
|
+
# relation, source, synonyms, treatment, or vernacular)
|
|
863
|
+
# @param format [String] The format of the treatment (plain_text, markdown, xml, html, tax_pub, taxon_x, rdf)
|
|
864
|
+
#
|
|
865
|
+
# @param offset [Integer] Offset for pagination
|
|
866
|
+
# @param limit [Integer] Limit for pagination
|
|
867
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
868
|
+
#
|
|
869
|
+
# @return [Array, Boolean] An array of hashes
|
|
870
|
+
def self.taxon(dataset_id, taxon_id: nil, subresource: nil, format: nil, offset: nil, limit: nil, verbose: false)
|
|
871
|
+
endpoint = "dataset/#{dataset_id}/taxon"
|
|
872
|
+
unless taxon_id.nil?
|
|
873
|
+
endpoint = "#{endpoint}/#{taxon_id}"
|
|
874
|
+
end
|
|
875
|
+
|
|
876
|
+
if !subresource.nil?
|
|
877
|
+
endpoint = "#{endpoint}/#{subresource}"
|
|
878
|
+
end
|
|
879
|
+
Request.new(endpoint: endpoint, offset: offset, format: format, limit: limit, verbose: verbose).perform
|
|
880
|
+
end
|
|
881
|
+
|
|
882
|
+
# Get the root taxa
|
|
883
|
+
#
|
|
884
|
+
# @param dataset_id [String] The dataset id
|
|
885
|
+
# @param taxon_id [String] The taxon id
|
|
886
|
+
# @param children [Boolean] Display the children of taxon_id
|
|
887
|
+
#
|
|
888
|
+
# @param offset [Integer] Offset for pagination
|
|
889
|
+
# @param limit [Integer] Limit for pagination
|
|
890
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
891
|
+
#
|
|
892
|
+
# @return [Array, Boolean] An array of hashes
|
|
893
|
+
def self.tree(dataset_id, taxon_id: nil, children: false, offset: nil, limit: nil, verbose: false)
|
|
894
|
+
endpoint = "dataset/#{dataset_id}/tree"
|
|
895
|
+
endpoint = "#{endpoint}/#{taxon_id}" unless taxon_id.nil?
|
|
896
|
+
endpoint = "#{endpoint}/children" unless taxon_id.nil? or !children
|
|
897
|
+
Request.new(endpoint: endpoint, offset: offset, limit: limit, verbose: verbose).perform
|
|
898
|
+
end
|
|
899
|
+
|
|
900
|
+
# Get user data
|
|
901
|
+
#
|
|
902
|
+
# @param user_id [Integer, nil] The user id
|
|
903
|
+
# @param q [String, nil] The search query
|
|
904
|
+
# @param role [String, nil] The user role (admin, editor, or reviewer)
|
|
905
|
+
#
|
|
906
|
+
# @param offset [Integer] Offset for pagination
|
|
907
|
+
# @param limit [Integer] Limit for pagination
|
|
908
|
+
# @param token [String, nil] The authentication token from retrieved with Colrapi.user_login(user, password)
|
|
909
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
910
|
+
#
|
|
911
|
+
# @return [Array, Boolean] An array of hashes
|
|
912
|
+
def self.user(user_id: nil, q: nil, role: nil, offset: nil, limit: nil, token: nil, verbose: false)
|
|
913
|
+
if user_id.nil?
|
|
914
|
+
endpoint = "user"
|
|
915
|
+
Request.new(endpoint: endpoint, q: q, role: role, offset: offset, limit: limit, token: token,
|
|
916
|
+
verbose: verbose).perform
|
|
917
|
+
else
|
|
918
|
+
endpoint = "user/#{user_id}"
|
|
919
|
+
Request.new(endpoint: endpoint, token: token, verbose: verbose).perform
|
|
920
|
+
end
|
|
921
|
+
end
|
|
922
|
+
|
|
923
|
+
# Get datasets user can access
|
|
924
|
+
# @param token [String] The access token from Colrapi.user_login()
|
|
925
|
+
# @param dataset_id [String, nil] A dataset id to check
|
|
926
|
+
# @param origin [Array, String, nil] Filter by the origin of a dataset (external, project, release, xrelease)
|
|
927
|
+
#
|
|
928
|
+
# @return [Array, Boolean] An array of datasets, or returns a boolean if dataset_id is provided
|
|
929
|
+
def self.user_dataset(token, dataset_id: nil, origin: nil, verbose: false)
|
|
930
|
+
endpoint = "user/dataset"
|
|
931
|
+
if dataset_id.nil?
|
|
932
|
+
Request.new(endpoint: endpoint, token: token, origin: origin, verbose: verbose).perform
|
|
933
|
+
else
|
|
934
|
+
endpoint = "user/dataset/#{dataset_id}"
|
|
935
|
+
Request.new(endpoint: endpoint, token: token, verbose: verbose).perform
|
|
936
|
+
end
|
|
937
|
+
end
|
|
938
|
+
|
|
939
|
+
# Authenticate user and get authentication token
|
|
940
|
+
def self.user_login(user, password, verbose: false)
|
|
941
|
+
Request.new(endpoint: "user/login", user: user, password: password, verbose: verbose).perform
|
|
942
|
+
end
|
|
943
|
+
|
|
944
|
+
# Get the authenticated user
|
|
945
|
+
#
|
|
946
|
+
# @param token [String, nil] The authentication token from retrieved with Colrapi.user_login(user, password)
|
|
947
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
948
|
+
#
|
|
949
|
+
# @return [Array, Boolean] An array of hashes
|
|
950
|
+
def self.user_me(token, verbose: false)
|
|
951
|
+
Request.new(endpoint: "user/me", token: token, verbose: verbose).perform
|
|
952
|
+
end
|
|
953
|
+
|
|
954
|
+
# Get verbatim data
|
|
955
|
+
#
|
|
956
|
+
# @param dataset_id [String] The dataset id
|
|
957
|
+
# @param verbatim_id [String] The verbatim id
|
|
958
|
+
# @param q [String] The search query string
|
|
959
|
+
# @param issue [Array, String] Filter by data quality issue (e.g., ACCEPTED_NAME_MISSING, DUPLICATE_NAME, URL_INVALID)
|
|
960
|
+
# @param type [Array, String] The file type (e.g., acef:AcceptedSpecies, col:Taxon, dwc:Taxon)
|
|
961
|
+
#
|
|
962
|
+
# TODO: May not work yet: https://github.com/CatalogueOfLife/backend/issues/1201
|
|
963
|
+
# @param term [Array, String] Filter by term (http://api.checklistbank.org/vocab/term)
|
|
964
|
+
# @param term_operator [String] The operator to use with term ('and' or 'or')
|
|
965
|
+
#
|
|
966
|
+
# @param offset [Integer] Offset for pagination
|
|
967
|
+
# @param limit [Integer] Limit for pagination
|
|
968
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
969
|
+
#
|
|
970
|
+
# @return [Array, Boolean] An array of hashes
|
|
971
|
+
def self.verbatim(dataset_id, verbatim_id: nil, q: nil, issue: nil, type: nil, term: nil, term_operator: nil,
|
|
972
|
+
offset: nil, limit: nil, verbose: false)
|
|
973
|
+
endpoint = "dataset/#{dataset_id}/verbatim"
|
|
974
|
+
if verbatim_id.nil?
|
|
975
|
+
Request.new(endpoint: endpoint, q: q, issue: issue, type: type, term: term, term_operator: term_operator,
|
|
976
|
+
offset: offset, limit: limit, verbose: verbose).perform
|
|
977
|
+
else
|
|
978
|
+
endpoint = "#{endpoint}/#{verbatim_id}"
|
|
979
|
+
Request.new(endpoint: endpoint, verbose: verbose).perform
|
|
980
|
+
end
|
|
981
|
+
end
|
|
982
|
+
|
|
983
|
+
# Get vernacular names
|
|
984
|
+
#
|
|
985
|
+
# @param dataset_id [String, nil] The dataset id
|
|
986
|
+
# @param q [String] A vernacular name search query
|
|
987
|
+
# @param language [String, nil] The language of the vernacular name (see: http://api.checklistbank.org/vocab/language)
|
|
988
|
+
#
|
|
989
|
+
# @param offset [Integer] Offset for pagination
|
|
990
|
+
# @param limit [Integer] Limit for pagination
|
|
991
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
992
|
+
#
|
|
993
|
+
# @return [Hash] A hash of vernacular results
|
|
994
|
+
def self.vernacular(dataset_id: nil, q: nil, language: nil, offset: nil, limit: nil, verbose: false)
|
|
995
|
+
if dataset_id.nil?
|
|
996
|
+
endpoint = 'vernacular'
|
|
997
|
+
Request.new(endpoint: endpoint, q: q, language: language, offset: offset, limit: limit, verbose: verbose).perform
|
|
998
|
+
else
|
|
999
|
+
endpoint = "dataset/#{dataset_id}/vernacular"
|
|
1000
|
+
Request.new(endpoint: endpoint, q: q, language: language, offset: offset, limit: limit, verbose: verbose).perform
|
|
1001
|
+
end
|
|
1002
|
+
end
|
|
1003
|
+
|
|
1004
|
+
# Get backend version
|
|
1005
|
+
#
|
|
1006
|
+
# @return [String] A version string
|
|
1007
|
+
def self.version(verbose: false)
|
|
1008
|
+
Request.new(endpoint: 'version', verbose: verbose).perform
|
|
1009
|
+
end
|
|
1010
|
+
|
|
1011
|
+
# Get vocab
|
|
1012
|
+
# @param term [String] The vocab term
|
|
1013
|
+
# @param subresource [String] The subresource which is usually the id, code, or name
|
|
1014
|
+
# @param children [Boolean] Returns the geotime's children if true
|
|
1015
|
+
#
|
|
1016
|
+
# @param verbose [Boolean] Print headers to STDOUT
|
|
1017
|
+
#
|
|
1018
|
+
# @return [Array]
|
|
1019
|
+
def self.vocab(term: nil, subresource: nil, children: false, verbose: false)
|
|
1020
|
+
endpoint = "vocab"
|
|
1021
|
+
endpoint = "#{endpoint}/#{term}" unless term.nil?
|
|
1022
|
+
endpoint = "#{endpoint}/#{subresource}" unless term.nil? or subresource.nil?
|
|
1023
|
+
endpoint = "#{endpoint}/children" if children and term == "geotime"
|
|
1024
|
+
Request.new(endpoint: endpoint, verbose: verbose).perform
|
|
1025
|
+
end
|
|
1026
|
+
end
|