collectionspace-client 0.15.1 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b9f5c5e51e9a99c4ac0ab4d9a9e0ac8cecac7bc38391c3cc57d3c987394110de
4
- data.tar.gz: 3106c95bf948acacb6b109b2c672ef9e2e71d51b6d9ee16b40794c4c98b8d2d6
3
+ metadata.gz: e8efeeecb56c776b3a9b04c57e412e22a3ee1fc091f1c400a38412d14eb2bfc4
4
+ data.tar.gz: 6cadb420c9cf8dd23794be7bdd069641fd6738afad9faaedfa8a45fa42ca9cf8
5
5
  SHA512:
6
- metadata.gz: 0aa8523a50202bebcaf3a09151e3376251b5575e7e344a32624016979f8e49de45193cb630f0a5be1acec660a94f959ef03e935ed1042a244a52fe076c92c067
7
- data.tar.gz: 9074177d65643755b34380f53ecf3bcfd77ec3c5e7d1c8af92df2e11e0edeac89ae6223e4645f7aac75f6983e826a22055021017259c27b743c08a86eb610e40
6
+ metadata.gz: afa91f5b105bef4a7d8507f703081fc0a18e342defac0b4b11e9809334070f301722813053e574a435b2d2bca3fb86ef3e98e53b2b70041bb1cee9209928922b
7
+ data.tar.gz: e023f885dd4912e71f2df99b59dd339578c75278654b22b23213ba888826b06f63ba2487114ffa0386dbe442b247183933f82e70c7d58ae3b64eea8dc44d6837
@@ -7,7 +7,7 @@ jobs:
7
7
  runs-on: ubuntu-latest
8
8
  strategy:
9
9
  matrix:
10
- ruby-version: ['3.2', '3.1', '3.0', '2.7']
10
+ ruby-version: ['3.3', '3.2', '3.1', '3.0']
11
11
  steps:
12
12
  - name: Checkout code
13
13
  uses: actions/checkout@v3
@@ -18,7 +18,6 @@ jobs:
18
18
  uses: ruby/setup-ruby@v1
19
19
  with:
20
20
  bundler-cache: true
21
- ruby-version: 2.7
22
21
  rubygems: latest
23
22
 
24
23
  - name: Release Gem
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.2.1
1
+ 3.0.6
data/.standard.yml ADDED
@@ -0,0 +1 @@
1
+ ruby_version: 3.0
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- collectionspace-client (0.15.1)
4
+ collectionspace-client (1.0.0)
5
5
  httparty
6
6
  json
7
7
  nokogiri
@@ -9,82 +9,100 @@ PATH
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- addressable (2.8.1)
13
- public_suffix (>= 2.0.2, < 6.0)
12
+ addressable (2.8.7)
13
+ public_suffix (>= 2.0.2, < 7.0)
14
14
  ast (2.4.2)
15
15
  awesome_print (1.9.2)
16
+ base64 (0.2.0)
17
+ bigdecimal (3.1.9)
16
18
  coderay (1.1.3)
17
- crack (0.4.5)
19
+ crack (1.0.0)
20
+ bigdecimal
18
21
  rexml
19
- diff-lcs (1.5.0)
20
- docile (1.4.0)
21
- hashdiff (1.0.1)
22
- httparty (0.21.0)
22
+ csv (3.3.2)
23
+ diff-lcs (1.5.1)
24
+ docile (1.4.1)
25
+ hashdiff (1.1.2)
26
+ httparty (0.22.0)
27
+ csv
23
28
  mini_mime (>= 1.0.0)
24
29
  multi_xml (>= 0.5.2)
25
- json (2.6.3)
30
+ json (2.9.1)
26
31
  language_server-protocol (3.17.0.3)
27
- method_source (1.0.0)
28
- mini_mime (1.1.2)
29
- mini_portile2 (2.8.1)
32
+ lint_roller (1.1.0)
33
+ method_source (1.1.0)
34
+ mini_mime (1.1.5)
35
+ mini_portile2 (2.8.8)
30
36
  multi_xml (0.6.0)
31
- nokogiri (1.14.2)
32
- mini_portile2 (~> 2.8.0)
37
+ nokogiri (1.17.2)
38
+ mini_portile2 (~> 2.8.2)
33
39
  racc (~> 1.4)
34
- parallel (1.22.1)
35
- parser (3.2.1.0)
40
+ parallel (1.26.3)
41
+ parser (3.3.7.0)
36
42
  ast (~> 2.4.1)
37
- pry (0.14.2)
43
+ racc
44
+ pry (0.15.2)
38
45
  coderay (~> 1.1)
39
46
  method_source (~> 1.0)
40
- public_suffix (5.0.1)
41
- racc (1.6.2)
47
+ public_suffix (6.0.1)
48
+ racc (1.8.1)
42
49
  rainbow (3.1.1)
43
- rake (13.0.6)
44
- regexp_parser (2.7.0)
45
- rexml (3.2.5)
46
- rspec (3.12.0)
47
- rspec-core (~> 3.12.0)
48
- rspec-expectations (~> 3.12.0)
49
- rspec-mocks (~> 3.12.0)
50
- rspec-core (3.12.1)
51
- rspec-support (~> 3.12.0)
52
- rspec-expectations (3.12.2)
50
+ rake (13.2.1)
51
+ regexp_parser (2.10.0)
52
+ rexml (3.4.0)
53
+ rspec (3.13.0)
54
+ rspec-core (~> 3.13.0)
55
+ rspec-expectations (~> 3.13.0)
56
+ rspec-mocks (~> 3.13.0)
57
+ rspec-core (3.13.2)
58
+ rspec-support (~> 3.13.0)
59
+ rspec-expectations (3.13.3)
53
60
  diff-lcs (>= 1.2.0, < 2.0)
54
- rspec-support (~> 3.12.0)
55
- rspec-mocks (3.12.3)
61
+ rspec-support (~> 3.13.0)
62
+ rspec-mocks (3.13.2)
56
63
  diff-lcs (>= 1.2.0, < 2.0)
57
- rspec-support (~> 3.12.0)
58
- rspec-support (3.12.0)
59
- rubocop (1.44.1)
64
+ rspec-support (~> 3.13.0)
65
+ rspec-support (3.13.2)
66
+ rubocop (1.70.0)
60
67
  json (~> 2.3)
68
+ language_server-protocol (>= 3.17.0)
61
69
  parallel (~> 1.10)
62
- parser (>= 3.2.0.0)
70
+ parser (>= 3.3.0.2)
63
71
  rainbow (>= 2.2.2, < 4.0)
64
- regexp_parser (>= 1.8, < 3.0)
65
- rexml (>= 3.2.5, < 4.0)
66
- rubocop-ast (>= 1.24.1, < 2.0)
72
+ regexp_parser (>= 2.9.3, < 3.0)
73
+ rubocop-ast (>= 1.36.2, < 2.0)
67
74
  ruby-progressbar (~> 1.7)
68
- unicode-display_width (>= 2.4.0, < 3.0)
69
- rubocop-ast (1.27.0)
70
- parser (>= 3.2.1.0)
71
- rubocop-performance (1.15.2)
72
- rubocop (>= 1.7.0, < 2.0)
73
- rubocop-ast (>= 0.4.0)
74
- ruby-progressbar (1.12.0)
75
+ unicode-display_width (>= 2.4.0, < 4.0)
76
+ rubocop-ast (1.37.0)
77
+ parser (>= 3.3.1.0)
78
+ rubocop-performance (1.23.1)
79
+ rubocop (>= 1.48.1, < 2.0)
80
+ rubocop-ast (>= 1.31.1, < 2.0)
81
+ ruby-progressbar (1.13.0)
75
82
  simplecov (0.22.0)
76
83
  docile (~> 1.1)
77
84
  simplecov-html (~> 0.11)
78
85
  simplecov_json_formatter (~> 0.1)
79
- simplecov-html (0.12.3)
86
+ simplecov-html (0.13.1)
80
87
  simplecov_json_formatter (0.1.4)
81
- standard (1.24.3)
88
+ standard (1.44.0)
82
89
  language_server-protocol (~> 3.17.0.2)
83
- rubocop (= 1.44.1)
84
- rubocop-performance (= 1.15.2)
85
- unicode-display_width (2.4.2)
86
- vcr (6.1.0)
87
- webmock (3.18.1)
90
+ lint_roller (~> 1.0)
91
+ rubocop (~> 1.70.0)
92
+ standard-custom (~> 1.0.0)
93
+ standard-performance (~> 1.6)
94
+ standard-custom (1.0.2)
95
+ lint_roller (~> 1.0)
96
+ rubocop (~> 1.50)
97
+ standard-performance (1.6.0)
98
+ lint_roller (~> 1.1)
99
+ rubocop-performance (~> 1.23.0)
100
+ unicode-display_width (3.1.4)
101
+ unicode-emoji (~> 4.0, >= 4.0.4)
102
+ unicode-emoji (4.0.4)
103
+ vcr (6.3.1)
104
+ base64
105
+ webmock (3.24.0)
88
106
  addressable (>= 2.8.0)
89
107
  crack (>= 0.3.2)
90
108
  hashdiff (>= 0.4.0, < 2.0.0)
@@ -97,13 +115,12 @@ DEPENDENCIES
97
115
  bundler
98
116
  collectionspace-client!
99
117
  pry
100
- rake (~> 13.0)
118
+ rake
101
119
  rspec
102
- rubocop
103
- simplecov (~> 0.21)
120
+ simplecov
104
121
  standard
105
- vcr (~> 6.1)
122
+ vcr
106
123
  webmock
107
124
 
108
125
  BUNDLED WITH
109
- 2.4.7
126
+ 2.4.1
data/bin/standardrb ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'standardrb' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
12
+
13
+ bundle_binstub = File.expand_path("bundle", __dir__)
14
+
15
+ if File.file?(bundle_binstub)
16
+ if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
17
+ load(bundle_binstub)
18
+ else
19
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
20
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
21
+ end
22
+ end
23
+
24
+ require "rubygems"
25
+ require "bundler/setup"
26
+
27
+ load Gem.bin_path("standard", "standardrb")
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
12
12
  spec.description = "Client for interacting with CollectionSpace Services API"
13
13
  spec.homepage = "https://github.com/lyrasis/collectionspace-client.git"
14
14
  spec.license = "MIT"
15
- spec.required_ruby_version = ">= 2.7.4"
15
+ spec.required_ruby_version = ">= 3.0.6"
16
16
 
17
17
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
18
  spec.bindir = "exe"
@@ -26,11 +26,10 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency "awesome_print"
27
27
  spec.add_development_dependency "bundler"
28
28
  spec.add_development_dependency "pry"
29
- spec.add_development_dependency "rake", "~> 13.0"
29
+ spec.add_development_dependency "rake"
30
30
  spec.add_development_dependency "rspec"
31
- spec.add_development_dependency "rubocop"
32
- spec.add_development_dependency "simplecov", "~> 0.21"
31
+ spec.add_development_dependency "simplecov"
33
32
  spec.add_development_dependency "standard"
34
- spec.add_development_dependency "vcr", "~> 6.1"
33
+ spec.add_development_dependency "vcr"
35
34
  spec.add_development_dependency "webmock"
36
35
  end
data/examples/demo.rb CHANGED
@@ -4,13 +4,33 @@ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
4
4
  require "awesome_print"
5
5
  require "collectionspace/client"
6
6
 
7
- client = CollectionSpace::Client.new(
8
- CollectionSpace::Configuration.new(
9
- base_uri: "https://core.dev.collectionspace.org/cspace-services",
10
- username: "admin@core.collectionspace.org",
11
- password: "Administrator"
12
- )
7
+ config = CollectionSpace::Configuration.new(
8
+ base_uri: "https://core.collectionspace.org/cspace-services",
9
+ username: "admin@core.collectionspace.org",
10
+ password: "Administrator"
13
11
  )
12
+ client = CollectionSpace::Client.new(config)
13
+
14
+ version_data = client.version
15
+ puts "Success getting UI version?: #{version_data.ui.success?}"
16
+ puts "Instance UI profile: #{version_data.ui.profile}"
17
+ puts "Instance UI version: #{version_data.ui.version}"
18
+ puts "Combined UI profile/version: #{version_data.ui.joined}"
19
+ puts ""
20
+ puts "Success getting API version?: #{version_data.api.success?}"
21
+ puts "API major version number: #{version_data.api.major}"
22
+ puts "API display version: #{version_data.api.joined}"
23
+ puts ""
24
+ puts "Client version: #{version_data.client}"
25
+
26
+ # GET REQUEST FOR CONDITIONCHECK RECORDS AND PRINT THE PARSED RESPONSE AND XML
27
+ response = client.get("conditionchecks")
28
+ ap response.parsed if response.result.success?
29
+
30
+ # GET ALL PERSON RECORDS AND PROCESS PER PAGE (INSTEAD OF WAITING FOR ALL)
31
+ client.all("personauthorities/urn:cspace:name(person)/items").each do |item|
32
+ puts item
33
+ end
14
34
 
15
35
  # GET REQUEST FOR CONDITIONCHECK RECORDS AND PRINT THE PARSED RESPONSE AND XML
16
36
  response = client.get("conditionchecks")
data/examples/reports.rb CHANGED
@@ -1,45 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
4
- require "awesome_print"
5
4
  require "collectionspace/client"
6
5
 
7
- STANDARD_TENANTS = [
8
- :anthro,
9
- :bonsai,
10
- :botgarden,
11
- :core,
12
- :fcart,
13
- :herbarium,
14
- :lhmc,
15
- :materials,
16
- :publicart
17
- ]
18
-
19
- # https://github.com/collectionspace/Tools/blob/master/scripts/install_report_records.sh
20
- # https://github.com/collectionspace/Tools/blob/master/scripts/create-report-records.sh
21
-
22
- STANDARD_REPORTS = CollectionSpace::Report.all
23
-
24
- STANDARD_TENANTS.each do |tenant|
25
- client = CollectionSpace::Client.new(
26
- CollectionSpace::Configuration.new(
27
- base_uri: "https://#{tenant}.dev.collectionspace.org/cspace-services",
28
- username: "admin@#{tenant}.collectionspace.org",
29
- password: "Administrator"
30
- )
6
+ client = CollectionSpace::Client.new(
7
+ CollectionSpace::Configuration.new(
8
+ base_uri: "https://core.dev.collectionspace.org/cspace-services",
9
+ username: "admin@core.collectionspace.org",
10
+ password: "Administrator"
31
11
  )
32
- base = client.config.base_uri
33
- .delete_suffix("/cspace-services")
34
- .delete_prefix("https://")
12
+ )
13
+
14
+ report_xml = File.join("spec", "fixtures", "files", "Exhibition_List_Basic.xml")
35
15
 
36
- STANDARD_REPORTS.each do |report|
37
- response = client.add_report(report)
38
- if response.result.success?
39
- puts "Added #{report[:name]} to #{base}"
40
- else
41
- puts "FAILED TO ADD #{report[:name]} to #{base}"
42
- puts response.inspect
43
- end
44
- end
16
+ response = client.add_report(report_xml)
17
+ if response.result.success?
18
+ puts "Report added/updated"
19
+ else
20
+ puts "Report addition/update failed"
21
+ puts response.inspect
45
22
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CollectionSpace
4
+ ApiVersion = Struct.new(:status, :message, :major, :minor, :patch,
5
+ :build, keyword_init: true) do
6
+ def success? = status == :success
7
+
8
+ def failure? = !success?
9
+
10
+ def joined
11
+ return if failure?
12
+
13
+ [major, minor].compact.join(".")
14
+ end
15
+ end
16
+ end
@@ -14,6 +14,21 @@ module CollectionSpace
14
14
  @config = config
15
15
  end
16
16
 
17
+ # User is required to be authenticated in order to access accounts
18
+ # endpoint. We cannot distinguish between unknown user and known
19
+ # user with bad password because CollectionSpace returns a 401
20
+ # error regardless of reason for
21
+ # non-authentication/authorization
22
+ def can_authenticate?
23
+ return false unless login_credentials_provided?
24
+
25
+ response = get("accounts/0/accountperms")
26
+ response.result.success? &&
27
+ response.parsed.respond_to?(:dig) &&
28
+ response.parsed.dig("account_permission", "account",
29
+ "userId") == config.username
30
+ end
31
+
17
32
  def get(path, options = {})
18
33
  request "GET", path, options
19
34
  end
@@ -43,8 +58,21 @@ module CollectionSpace
43
58
  request "DELETE", path
44
59
  end
45
60
 
61
+ def version
62
+ Struct.new(:api, :client, :ui, keyword_init: true)
63
+ .new(
64
+ api: get_api_version,
65
+ client: VERSION,
66
+ ui: CollectionSpace::UiVersion.call(self)
67
+ )
68
+ end
69
+
46
70
  private
47
71
 
72
+ def login_credentials_provided?
73
+ config.username && config.password
74
+ end
75
+
48
76
  def check_payload(payload)
49
77
  errors = Nokogiri::XML(payload).errors
50
78
  raise CollectionSpace::PayloadError, errors if errors.any?
@@ -54,5 +82,23 @@ module CollectionSpace
54
82
  sleep config.throttle
55
83
  Response.new(Request.new(config, method, path, options).execute)
56
84
  end
85
+
86
+ def get_api_version
87
+ response = get("systeminfo")
88
+ unless response.result.success?
89
+ return CollectionSpace::ApiVersion.new(
90
+ status: :failure, message: response.result.body
91
+ )
92
+ end
93
+
94
+ version_info = response.parsed.dig("system_info_common", "version")
95
+ CollectionSpace::ApiVersion.new(
96
+ status: :success,
97
+ major: version_info["major"],
98
+ minor: version_info["minor"],
99
+ patch: version_info["patch"],
100
+ build: version_info["build"]
101
+ )
102
+ end
57
103
  end
58
104
  end
@@ -21,7 +21,7 @@ module CollectionSpace
21
21
  settings.each do |property, value|
22
22
  next unless DEFAULTS.key?(property)
23
23
 
24
- instance_variable_set("@#{property}", value)
24
+ instance_variable_set(:"@#{property}", value)
25
25
  end
26
26
  end
27
27
  end
@@ -18,10 +18,11 @@ module CollectionSpace
18
18
  end
19
19
 
20
20
  # add / update reports
21
- def add_report(data = {}, params = {pgSz: 100})
22
- payload = Template.process("report", data)
21
+ def add_report(payload_path, params = {pgSz: 100})
22
+ payload = File.read(File.expand_path(payload_path))
23
+ report_name = payload.match(/<name>(.*)<\/name>/)[1]
23
24
  response = get("reports", {query: params})
24
- create_or_update(response, "reports", "name", data[:name], payload)
25
+ create_or_update(response, "reports", "name", report_name, payload)
25
26
  end
26
27
 
27
28
  # returns Array of authority doctypes for use in setting up batches
@@ -81,7 +82,7 @@ module CollectionSpace
81
82
  path: service[:path],
82
83
  namespace: "#{service[:ns_prefix]}_#{schema}",
83
84
  field: field,
84
- expression: "#{operator} '#{value.gsub(/'/, "\\\\'")}'"
85
+ expression: "#{operator} '#{value.gsub("'", "\\\\'")}'"
85
86
  )
86
87
  search(search_args, sortBy: CollectionSpace::Search::DEFAULT_SORT)
87
88
  end
@@ -109,16 +110,13 @@ module CollectionSpace
109
110
  }.fetch(path, %w[abstract_common_list list_item])
110
111
  end
111
112
 
112
- def reindex_full_text(doctype, csids = [])
113
- if csids.any?
114
- run_job(
115
- "Reindex Full Text", :reindex_full_text, :reindex_by_csids, {doctype: doctype, csids: csids}
116
- )
117
- else
118
- run_job(
119
- "Reindex Full Text", :reindex_full_text, :reindex_by_doctype, {doctype: doctype}
120
- )
121
- end
113
+ def reindex_full_text(doctype = nil, csids = [])
114
+ run_job(
115
+ "Reindex Full Text",
116
+ :reindex_full_text,
117
+ :reindex,
118
+ {doctype: doctype, csids: csids}
119
+ )
122
120
  end
123
121
 
124
122
  # @param id [String] media record's identificationNumber value
@@ -16,7 +16,7 @@ module CollectionSpace
16
16
 
17
17
  def from_hash(query)
18
18
  query.each do |property, value|
19
- instance_variable_set("@#{property}", value)
19
+ instance_variable_set(:"@#{property}", value)
20
20
  end
21
21
  self
22
22
  end
@@ -54,18 +54,48 @@ module CollectionSpace
54
54
  path: "conservation",
55
55
  term: nil
56
56
  },
57
+ "consultations" => {
58
+ identifier: "consultationNumber",
59
+ ns_prefix: "consultations",
60
+ path: "consultations",
61
+ term: nil
62
+ },
63
+ "deaccessions" => {
64
+ identifier: "deaccessionNumber",
65
+ ns_prefix: "deaccessions",
66
+ path: "deaccessions",
67
+ term: nil
68
+ },
69
+ "dutiesofcare" => {
70
+ identifier: "dutyOfCareNumber",
71
+ ns_prefix: "dutiesofcare",
72
+ path: "dutiesofcare",
73
+ term: nil
74
+ },
57
75
  "exhibitions" => {
58
76
  identifier: "exhibitionNumber",
59
77
  ns_prefix: "exhibitions",
60
78
  path: "exhibitions",
61
79
  term: nil
62
80
  },
81
+ "exits" => {
82
+ identifier: "exitNumber",
83
+ ns_prefix: "exits",
84
+ path: "exits",
85
+ term: nil
86
+ },
63
87
  "groups" => {
64
88
  identifier: "title",
65
89
  ns_prefix: "groups",
66
90
  path: "groups",
67
91
  term: nil
68
92
  },
93
+ "heldintrusts" => {
94
+ identifier: "heldInTrustNumber",
95
+ ns_prefix: "heldintrusts",
96
+ path: "heldintrusts",
97
+ term: nil
98
+ },
69
99
  "insurances" => {
70
100
  identifier: "insuranceIndemnityReferenceNumber",
71
101
  ns_prefix: "insurances",
@@ -120,6 +150,12 @@ module CollectionSpace
120
150
  path: "movements",
121
151
  term: nil
122
152
  },
153
+ "nagprainventories" => {
154
+ identifier: "inventoryNumber",
155
+ ns_prefix: "nagprainventories",
156
+ path: "nagprainventories",
157
+ term: nil
158
+ },
123
159
  "objectexit" => {
124
160
  identifier: "exitNumber",
125
161
  ns_prefix: "objectexit",
@@ -168,6 +204,24 @@ module CollectionSpace
168
204
  path: "relations",
169
205
  term: nil
170
206
  },
207
+ "repatriationrequests" => {
208
+ identifier: "requestNumber",
209
+ ns_prefix: "repatriationrequests",
210
+ path: "repatriationrequests",
211
+ term: nil
212
+ },
213
+ "restrictedmedia" => {
214
+ identifier: "identificationNumber",
215
+ ns_prefix: "restrictedmedia",
216
+ path: "restrictedmedia",
217
+ term: nil
218
+ },
219
+ "summarydocumentations" => {
220
+ identifier: "documentationNumber",
221
+ ns_prefix: "summarydocumentations",
222
+ path: "summarydocumentations",
223
+ term: nil
224
+ },
171
225
  "taxonomyauthority" => {
172
226
  identifier: "shortIdentifier",
173
227
  ns_prefix: "taxon",
@@ -1,10 +1,16 @@
1
1
  <?xml version="1.0" encoding="utf-8" standalone="yes"?>
2
2
  <ns2:invocationContext xmlns:ns2="http://collectionspace.org/services/common/invocable">
3
+ <% if data[:csids].any? %>
3
4
  <mode>list</mode>
4
- <docType><%= data[:doctype] %></docType>
5
5
  <listCSIDs>
6
- <% data[:csids].each do |csid| %>
7
- <csid><%= csid %></csid>
8
- <% end %>
6
+ <% data[:csids].each do |csid| %>
7
+ <csid><%= csid %></csid>
8
+ <% end %>
9
9
  </listCSIDs>
10
+ <% else %>
11
+ <mode>nocontext</mode>
12
+ <% end %>
13
+ <% if data[:doctype] %>
14
+ <docType><%= data[:doctype] %></docType>
15
+ <% end %>
10
16
  </ns2:invocationContext>
@@ -11,11 +11,8 @@
11
11
  <createsNewFocus>false</createsNewFocus>
12
12
  <forDocTypes>
13
13
  <forDocType>Acquisition</forDocType>
14
- <forDocType>Batch</forDocType>
15
- <forDocType>Blob</forDocType>
16
14
  <forDocType>Citation</forDocType>
17
15
  <forDocType>Citationauthority</forDocType>
18
- <forDocType>Claim</forDocType>
19
16
  <forDocType>CollectionObject</forDocType>
20
17
  <forDocType>Conceptauthority</forDocType>
21
18
  <forDocType>Conceptitem</forDocType>
@@ -32,7 +29,6 @@
32
29
  <forDocType>ObjectExit</forDocType>
33
30
  <forDocType>Organization</forDocType>
34
31
  <forDocType>Orgauthority</forDocType>
35
- <forDocType>Osteology</forDocType>
36
32
  <forDocType>Person</forDocType>
37
33
  <forDocType>Personauthority</forDocType>
38
34
  <forDocType>Placeauthority</forDocType>
@@ -45,7 +41,6 @@
45
41
  <forDocType>Vocabulary</forDocType>
46
42
  <forDocType>Vocabularyitem</forDocType>
47
43
  <forDocType>Workauthority</forDocType>
48
- <forDocType>Workitem</forDocType>
49
44
  </forDocTypes>
50
45
  </ns2:batch_common>
51
46
  </document>
@@ -0,0 +1,170 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "strscan"
4
+ require "net/http"
5
+ require "uri"
6
+
7
+ module CollectionSpace
8
+ # CollectionSpace request
9
+ class UiVersion
10
+ Data = Struct.new(:status, :message, :profile, :version,
11
+ keyword_init: true) do
12
+ def success? = status == :success
13
+
14
+ def failure? = !success?
15
+
16
+ def joined
17
+ return if failure?
18
+
19
+ [profile, version].compact.join(" ")
20
+ end
21
+ end
22
+
23
+ class << self
24
+ def call(...) = new(...).call
25
+ end
26
+
27
+ # @param client [CollectionSpace::Client]
28
+ def initialize(client)
29
+ @uri = client.config.base_uri
30
+ end
31
+
32
+ def call
33
+ body = retrieve_response
34
+ return body if body.respond_to?(:status) && body.status == :failure
35
+
36
+ script = last_script_src(body)
37
+ return script if script.respond_to?(:status) && script.status == :failure
38
+
39
+ version = extract_version(script) if script
40
+ return version if version.respond_to?(:status) &&
41
+ version.status == :failure
42
+
43
+ profile = extract_profile(script) if version
44
+ return profile if profile.respond_to?(:status) &&
45
+ profile.status == :failure
46
+
47
+ Data.new(status: :success,
48
+ profile: profile.downcase.tr(" ", "-"),
49
+ version: version)
50
+ end
51
+
52
+ private
53
+
54
+ attr_reader :uri
55
+
56
+ def retrieve_response
57
+ unless response.is_a?(Net::HTTPSuccess)
58
+ return Data.new(status: :failure, message: response.message)
59
+ end
60
+
61
+ response.body
62
+ end
63
+
64
+ def response
65
+ @response ||= fetch(base_uri)
66
+ rescue => err
67
+ err
68
+ end
69
+
70
+ def base_uri = URI(uri.sub(/\/cspace-services\/?/, ""))
71
+
72
+ def fetch(uri, limit = 10)
73
+ uri = URI(uri) unless uri.is_a?(URI)
74
+
75
+ # You should choose a better exception.
76
+ raise ArgumentError, "too many HTTP redirects" if limit == 0
77
+
78
+ response = Net::HTTP.get_response(uri)
79
+
80
+ case response
81
+ when Net::HTTPSuccess
82
+ response
83
+ when Net::HTTPRedirection
84
+ location = response["location"]
85
+ new_loc = "#{base_uri}#{location}"
86
+ fetch(new_loc, limit - 1)
87
+ else
88
+ response.value
89
+ end
90
+ end
91
+
92
+ def last_script_src(str)
93
+ scripts = []
94
+ scanner = StringScanner.new(str)
95
+ script_begin = Regexp.new("<script src=\"")
96
+ script_end_str = '"></script>'
97
+ script_end = Regexp.new(script_end_str)
98
+
99
+ while scanner.exist?(script_begin)
100
+ scanner.scan_until(script_begin)
101
+ scripts << scanner.scan_until(script_end)
102
+ .delete_suffix(script_end_str)
103
+ end
104
+
105
+ if scripts.empty?
106
+ return Data.new(status: :failure,
107
+ message: "No CollectionSpace UI plugin script sources " \
108
+ "detected for #{base_uri}")
109
+ end
110
+
111
+ scripts.last
112
+ end
113
+
114
+ def extract_version(src)
115
+ case src
116
+ when /^\/cspace-ui/
117
+ extract_from_cspace_ui_src(src)
118
+ when /cspace-ui-plugin-profile-.*@\d.*cspaceUIPluginProfile.*\.min\.js/
119
+ get_specific_delivered_version(src)
120
+ when /^https:\/\/cdn\.jsdelivr\.net\/npm.*@latest/
121
+ get_latest_npm_version(src)
122
+ else
123
+ Data.new(status: :failure, message: "Unhandled src type: #{src}")
124
+ end
125
+ end
126
+
127
+ def extract_from_cspace_ui_src(src)
128
+ src.match(/@(.*)\.min\.js/)
129
+ .captures
130
+ .first
131
+ rescue
132
+ Value.new(status: :failure, message: "Cannot extract version from #{src}")
133
+ end
134
+
135
+ def get_specific_delivered_version(src)
136
+ src.match(/cspace-ui-plugin-profile-.*@(\d[^\/]+)\//)
137
+ .captures
138
+ .first
139
+ end
140
+
141
+ def get_latest_npm_version(src)
142
+ package = src.match(/npm\/(.*)@latest/)
143
+ .captures.first
144
+ uri = URI("https://data.jsdelivr.com/v1/packages/npm/#{package}")
145
+ response = fetch(uri)
146
+ unless response.is_a?(Net::HTTPSuccess)
147
+ return Data.new(status: :failure,
148
+ message: "ERROR: Cannot retrieve latest version " \
149
+ "number for #{package} from jsdelivr: " \
150
+ "#{response.message}")
151
+ end
152
+
153
+ data = JSON.parse(response.body)
154
+ value = data.dig("tags", "latest")
155
+ unless value
156
+ return Data.new(status: :failure,
157
+ message: "Could not extract latest version from #{uri}")
158
+ end
159
+
160
+ value
161
+ end
162
+
163
+ def extract_profile(src)
164
+ return "core" if src.match?(/^\/cspace-ui\/cspaceUI@/)
165
+
166
+ src.match(/UIPluginProfile([^@]+)(?:@|\.min\.js)/)
167
+ .captures.first
168
+ end
169
+ end
170
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module CollectionSpace
4
4
  class Client
5
- VERSION = "0.15.1"
5
+ VERSION = "1.0.0"
6
6
  end
7
7
  end
@@ -8,15 +8,16 @@ require "uri"
8
8
  require "collectionspace/client/helpers"
9
9
  require "collectionspace/client/template"
10
10
 
11
+ require "collectionspace/client/api_version"
11
12
  require "collectionspace/client/batch"
12
13
  require "collectionspace/client/client"
13
14
  require "collectionspace/client/configuration"
14
15
  require "collectionspace/client/refname"
15
- require "collectionspace/client/report"
16
16
  require "collectionspace/client/request"
17
17
  require "collectionspace/client/response"
18
18
  require "collectionspace/client/search"
19
19
  require "collectionspace/client/service"
20
+ require "collectionspace/client/ui_version"
20
21
  require "collectionspace/client/version"
21
22
 
22
23
  module CollectionSpace
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: collectionspace-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Cooper
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-04 00:00:00.000000000 Z
11
+ date: 2025-05-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -96,20 +96,6 @@ dependencies:
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rake
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: '13.0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: '13.0'
111
- - !ruby/object:Gem::Dependency
112
- name: rspec
113
99
  requirement: !ruby/object:Gem::Requirement
114
100
  requirements:
115
101
  - - ">="
@@ -123,7 +109,7 @@ dependencies:
123
109
  - !ruby/object:Gem::Version
124
110
  version: '0'
125
111
  - !ruby/object:Gem::Dependency
126
- name: rubocop
112
+ name: rspec
127
113
  requirement: !ruby/object:Gem::Requirement
128
114
  requirements:
129
115
  - - ">="
@@ -140,16 +126,16 @@ dependencies:
140
126
  name: simplecov
141
127
  requirement: !ruby/object:Gem::Requirement
142
128
  requirements:
143
- - - "~>"
129
+ - - ">="
144
130
  - !ruby/object:Gem::Version
145
- version: '0.21'
131
+ version: '0'
146
132
  type: :development
147
133
  prerelease: false
148
134
  version_requirements: !ruby/object:Gem::Requirement
149
135
  requirements:
150
- - - "~>"
136
+ - - ">="
151
137
  - !ruby/object:Gem::Version
152
- version: '0.21'
138
+ version: '0'
153
139
  - !ruby/object:Gem::Dependency
154
140
  name: standard
155
141
  requirement: !ruby/object:Gem::Requirement
@@ -168,16 +154,16 @@ dependencies:
168
154
  name: vcr
169
155
  requirement: !ruby/object:Gem::Requirement
170
156
  requirements:
171
- - - "~>"
157
+ - - ">="
172
158
  - !ruby/object:Gem::Version
173
- version: '6.1'
159
+ version: '0'
174
160
  type: :development
175
161
  prerelease: false
176
162
  version_requirements: !ruby/object:Gem::Requirement
177
163
  requirements:
178
- - - "~>"
164
+ - - ">="
179
165
  - !ruby/object:Gem::Version
180
- version: '6.1'
166
+ version: '0'
181
167
  - !ruby/object:Gem::Dependency
182
168
  name: webmock
183
169
  requirement: !ruby/object:Gem::Requirement
@@ -204,8 +190,8 @@ files:
204
190
  - ".github/workflows/publish.yml"
205
191
  - ".gitignore"
206
192
  - ".rspec"
207
- - ".rubocop.yml"
208
193
  - ".ruby-version"
194
+ - ".standard.yml"
209
195
  - ".travis.yml"
210
196
  - Gemfile
211
197
  - Gemfile.lock
@@ -214,6 +200,7 @@ files:
214
200
  - Rakefile
215
201
  - bin/console
216
202
  - bin/rspec
203
+ - bin/standardrb
217
204
  - collectionspace-client.gemspec
218
205
  - examples/batches.rb
219
206
  - examples/demo.rb
@@ -224,29 +211,29 @@ files:
224
211
  - examples/search.rb
225
212
  - examples/update_password.rb
226
213
  - lib/collectionspace/client.rb
214
+ - lib/collectionspace/client/api_version.rb
227
215
  - lib/collectionspace/client/batch.rb
228
216
  - lib/collectionspace/client/client.rb
229
217
  - lib/collectionspace/client/configuration.rb
230
218
  - lib/collectionspace/client/helpers.rb
231
219
  - lib/collectionspace/client/refname.rb
232
- - lib/collectionspace/client/report.rb
233
220
  - lib/collectionspace/client/request.rb
234
221
  - lib/collectionspace/client/response.rb
235
222
  - lib/collectionspace/client/search.rb
236
223
  - lib/collectionspace/client/service.rb
237
224
  - lib/collectionspace/client/template.rb
238
225
  - lib/collectionspace/client/templates/batch.xml.erb
239
- - lib/collectionspace/client/templates/reindex_by_csids.xml.erb
240
- - lib/collectionspace/client/templates/reindex_by_doctype.xml.erb
226
+ - lib/collectionspace/client/templates/reindex.xml.erb
241
227
  - lib/collectionspace/client/templates/reindex_full_text.xml.erb
242
228
  - lib/collectionspace/client/templates/report.xml.erb
243
229
  - lib/collectionspace/client/templates/reset_media_blob.xml.erb
230
+ - lib/collectionspace/client/ui_version.rb
244
231
  - lib/collectionspace/client/version.rb
245
232
  homepage: https://github.com/lyrasis/collectionspace-client.git
246
233
  licenses:
247
234
  - MIT
248
235
  metadata: {}
249
- post_install_message:
236
+ post_install_message:
250
237
  rdoc_options: []
251
238
  require_paths:
252
239
  - lib
@@ -254,15 +241,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
254
241
  requirements:
255
242
  - - ">="
256
243
  - !ruby/object:Gem::Version
257
- version: 2.7.4
244
+ version: 3.0.6
258
245
  required_rubygems_version: !ruby/object:Gem::Requirement
259
246
  requirements:
260
247
  - - ">="
261
248
  - !ruby/object:Gem::Version
262
249
  version: '0'
263
250
  requirements: []
264
- rubygems_version: 3.4.20
265
- signing_key:
251
+ rubygems_version: 3.5.23
252
+ signing_key:
266
253
  specification_version: 4
267
254
  summary: CollectionSpace API client.
268
255
  test_files: []
data/.rubocop.yml DELETED
@@ -1,4 +0,0 @@
1
- require: standard
2
-
3
- inherit_gem:
4
- standard: config/base.yml
@@ -1,180 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module CollectionSpace
4
- # CollectionSpace report
5
- class Report
6
- def self.all
7
- [
8
- {
9
- name: "Acquisition Summary",
10
- notes: "An acquisition summary report. Runs on a single record only.",
11
- doctype: "Acquisition",
12
- supports_single_doc: "true",
13
- supports_doc_list: "false",
14
- supports_group: "false",
15
- supports_no_context: "false",
16
- filename: "acq_basic.jrxml",
17
- mimetype: "application/pdf"
18
- },
19
- {
20
- name: "Acquisition Basic List",
21
- notes: "Catalog info for objects related to an acquisition record. Runs on a single record only.",
22
- doctype: "Acquisition",
23
- supports_single_doc: "true",
24
- supports_doc_list: "false",
25
- supports_group: "false",
26
- supports_no_context: "false",
27
- filename: "Acq_List_Basic.jrxml",
28
- mimetype: "application/pdf"
29
- },
30
- {
31
- name: "Condition Check Basic List",
32
- notes: "Catalog info for objects related to a condition check record. Runs on a single record only.",
33
- doctype: "Conditioncheck",
34
- supports_single_doc: "true",
35
- supports_doc_list: "false",
36
- supports_group: "false",
37
- supports_no_context: "false",
38
- filename: "CC_List_Basic.jrxml",
39
- mimetype: "application/pdf"
40
- },
41
- {
42
- name: "Exhibition Basic List",
43
- notes: "Catalog info for objects related to a exhibition record. Runs on a single record only.",
44
- doctype: "Exhibition",
45
- supports_single_doc: "true",
46
- supports_doc_list: "false",
47
- supports_group: "false",
48
- supports_no_context: "false",
49
- filename: "Exhibition_List_Basic.jrxml",
50
- mimetype: "application/pdf"
51
- },
52
- {
53
- name: "Group Basic List",
54
- notes: "Catalog info for objects related to a group record. Runs on a single record only.",
55
- doctype: "Group",
56
- supports_single_doc: "true",
57
- supports_doc_list: "false",
58
- supports_group: "false",
59
- supports_no_context: "false",
60
- filename: "Group_List_Basic.jrxml",
61
- mimetype: "application/pdf"
62
- },
63
- {
64
- name: "Loan In Basic List",
65
- notes: "Catalog info for objects related to a loan in record. Runs on a single record only.",
66
- doctype: "Loanin",
67
- supports_single_doc: "true",
68
- supports_doc_list: "false",
69
- supports_group: "false",
70
- supports_no_context: "false",
71
- filename: "LoansIn_List_Basic.jrxml",
72
- mimetype: "application/pdf"
73
- },
74
- {
75
- name: "Loan Out Basic List",
76
- notes: "Catalog info for objects related to a loan out record. Runs on a single record only.",
77
- doctype: "Loanout",
78
- supports_single_doc: "true",
79
- supports_doc_list: "false",
80
- supports_group: "false",
81
- supports_no_context: "false",
82
- filename: "LoansOut_List_Basic.jrxml",
83
- mimetype: "application/pdf"
84
- },
85
- {
86
- name: "Acquisition Ethnographic Object List",
87
- notes: "Core acquisition report. Runs on a single record only.",
88
- doctype: "Acquisition",
89
- supports_single_doc: "true",
90
- supports_doc_list: "false",
91
- supports_group: "false",
92
- supports_no_context: "false",
93
- filename: "coreAcquisition.jrxml",
94
- mimetype: "application/pdf"
95
- },
96
- {
97
- name: "Group Object Ethnographic Object List",
98
- notes: "Core group object report. Runs on a single record only.",
99
- doctype: "Group",
100
- supports_single_doc: "true",
101
- supports_doc_list: "false",
102
- supports_group: "false",
103
- supports_no_context: "false",
104
- filename: "coreGroupObject.jrxml",
105
- mimetype: "application/pdf"
106
- },
107
- {
108
- name: "Intake Ethnographic Object List",
109
- notes: "Core intake report. Runs on a single record only.",
110
- doctype: "Intake",
111
- supports_single_doc: "true",
112
- supports_doc_list: "false",
113
- supports_group: "false",
114
- supports_no_context: "false",
115
- filename: "coreIntake.jrxml",
116
- mimetype: "application/pdf"
117
- },
118
- {
119
- name: "Loan In Ethnographic Object List",
120
- notes: "Core loan in report. Runs on a single record only.",
121
- doctype: "Loanin",
122
- supports_single_doc: "true",
123
- supports_doc_list: "false",
124
- supports_group: "false",
125
- supports_no_context: "false",
126
- filename: "coreLoanIn.jrxml",
127
- mimetype: "application/pdf"
128
- },
129
- {
130
- name: "Loan Out Ethnographic Object List",
131
- notes: "Core loan out report. Runs on a single record only.",
132
- doctype: "Loanout",
133
- supports_single_doc: "true",
134
- supports_doc_list: "false",
135
- supports_group: "false",
136
- supports_no_context: "false",
137
- filename: "coreLoanOut.jrxml",
138
- mimetype: "application/pdf"
139
- },
140
- {
141
- name: "Object Exit Ethnographic Object List",
142
- notes: "Core object exit report. Runs on a single record only.",
143
- doctype: "ObjectExit",
144
- supports_single_doc: "true",
145
- supports_doc_list: "false",
146
- supports_group: "false",
147
- supports_no_context: "false",
148
- filename: "coreObjectExit.jrxml",
149
- mimetype: "application/pdf"
150
- },
151
- {
152
- name: "Object Valuation",
153
- notes: "Returns latest valuation information for selected objects",
154
- doctype: "CollectionObject",
155
- supports_single_doc: "false",
156
- supports_doc_list: "true",
157
- supports_group: "false",
158
- supports_no_context: "true",
159
- filename: "object_valuation.jrxml",
160
- mimetype: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
161
- },
162
- {
163
- name: "Systematic Inventory",
164
- notes: "Generate a checklist for performing an inventory on a range of storage locations. Runs on all records, using the provided start and end locations.",
165
- doctype: "Locationitem",
166
- supports_single_doc: "false",
167
- supports_doc_list: "false",
168
- supports_group: "false",
169
- supports_no_context: "true",
170
- filename: "systematicInventory.jrxml",
171
- mimetype: "application/pdf"
172
- }
173
- ]
174
- end
175
-
176
- def self.find(key, value)
177
- all.find { |report| report[key] == value }
178
- end
179
- end
180
- end
@@ -1,5 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8" standalone="yes"?>
2
- <ns2:invocationContext xmlns:ns2="http://collectionspace.org/services/common/invocable">
3
- <mode>nocontext</mode>
4
- <docType><%= data[:doctype] %></docType>
5
- </ns2:invocationContext>