evergreen-ils 0.2.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d4a950c35117be9bb820cc29a6c51a7b6d617182cea54d5fc83449dd02654e13
4
+ data.tar.gz: 44124d0b23d86d2da8d60a5e169ead1d23ab98238cffd16e1be5dbb149350971
5
+ SHA512:
6
+ metadata.gz: 6085835b66450141c9a330cc7b98f8e8e9b61e6d31779bcb4f0e974864a0a8942c78c5dc493c42216f8b827ad6559ac35bf286b3cdfd0fab5568fe9b04a5a402
7
+ data.tar.gz: 5ce0821e80d4ce4dd4d08c39685311a98edbe98edca5859724e4d5d589f8f3cbcf27ba1f51fdee503426eb42c8d33abfd705c23ffd87220a73e06583a95d47e3
data/.reek.yml ADDED
@@ -0,0 +1,23 @@
1
+ # Auto generated by Reeks --todo flag
2
+ ---
3
+ detectors:
4
+ Attribute:
5
+ exclude:
6
+ - Evergreen::Configuration#default_password
7
+ - Evergreen::Configuration#default_username
8
+ - Evergreen::Configuration#host
9
+ - Evergreen::Configuration#read_only
10
+ FeatureEnvy:
11
+ exclude:
12
+ - Evergreen::Configuration#field_is_empty
13
+ LongParameterList:
14
+ exclude:
15
+ - Evergreen::IDL::IDLSaxHandler#start_element
16
+ NilCheck:
17
+ exclude:
18
+ - Evergreen::Configuration#field_is_empty
19
+ UtilityFunction:
20
+ exclude:
21
+ - Evergreen#initialize
22
+ exclude_paths:
23
+ - spec
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,12 @@
1
+ require:
2
+ - rubocop-performance
3
+ - rubocop-rspec
4
+ AllCops:
5
+ TargetRubyVersion: 3.0
6
+ NewCops: enable
7
+ Exclude:
8
+ - 'sig/**/*'
9
+ - 'vendor/**/*'
10
+ SuggestExtensions: false
11
+ RSpec/ExampleLength:
12
+ Max: 10
data/.tool-versions ADDED
@@ -0,0 +1 @@
1
+ ruby 3.2.1
data/Gemfile ADDED
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in evergreen-ils.gemspec
6
+ gemspec
7
+
8
+ gem 'rake'
9
+
10
+ group :test do
11
+ gem 'rspec'
12
+ gem 'webmock'
13
+ end
14
+
15
+ group :check do
16
+ gem 'flay'
17
+ gem 'flog'
18
+ gem 'rbs'
19
+ gem 'reek'
20
+ gem 'rubocop', require: false
21
+ gem 'rubocop-performance', require: false
22
+ gem 'rubocop-rspec', require: false
23
+ gem 'steep'
24
+ end
25
+
26
+ group :development do
27
+ gem 'debug'
28
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,180 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ evergreen-ils (0.2.0)
5
+ marc (>= 1.0.0, < 2.0)
6
+ rexml (>= 3.0.0, < 4.0)
7
+ zeitwerk (>= 2.0.0, < 3.0)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ activesupport (7.0.6)
13
+ concurrent-ruby (~> 1.0, >= 1.0.2)
14
+ i18n (>= 1.6, < 2)
15
+ minitest (>= 5.1)
16
+ tzinfo (~> 2.0)
17
+ addressable (2.8.5)
18
+ public_suffix (>= 2.0.2, < 6.0)
19
+ ast (2.4.2)
20
+ concurrent-ruby (1.2.2)
21
+ crack (0.4.5)
22
+ rexml
23
+ csv (3.2.7)
24
+ debug (1.8.0)
25
+ irb (>= 1.5.0)
26
+ reline (>= 0.3.1)
27
+ diff-lcs (1.5.0)
28
+ erubi (1.12.0)
29
+ ffi (1.15.5)
30
+ ffi (1.15.5-java)
31
+ fileutils (1.7.1)
32
+ flay (2.13.1)
33
+ erubi (~> 1.10)
34
+ path_expander (~> 1.0)
35
+ ruby_parser (~> 3.0)
36
+ sexp_processor (~> 4.0)
37
+ flog (4.7.0)
38
+ path_expander (~> 1.0)
39
+ ruby_parser (~> 3.1, > 3.1.0)
40
+ sexp_processor (~> 4.8)
41
+ hashdiff (1.0.1)
42
+ i18n (1.14.1)
43
+ concurrent-ruby (~> 1.0)
44
+ io-console (0.6.0)
45
+ io-console (0.6.0-java)
46
+ irb (1.7.4)
47
+ reline (>= 0.3.6)
48
+ json (2.6.3)
49
+ json (2.6.3-java)
50
+ kwalify (0.7.2)
51
+ language_server-protocol (3.17.0.3)
52
+ listen (3.8.0)
53
+ rb-fsevent (~> 0.10, >= 0.10.3)
54
+ rb-inotify (~> 0.9, >= 0.9.10)
55
+ logger (1.5.3)
56
+ marc (1.2.0)
57
+ rexml
58
+ scrub_rb (>= 1.0.1, < 2)
59
+ unf
60
+ minitest (5.19.0)
61
+ parallel (1.23.0)
62
+ parser (3.2.2.3)
63
+ ast (~> 2.4.1)
64
+ racc
65
+ path_expander (1.1.1)
66
+ public_suffix (5.0.3)
67
+ racc (1.7.1)
68
+ racc (1.7.1-java)
69
+ rainbow (3.1.1)
70
+ rake (13.0.6)
71
+ rb-fsevent (0.11.2)
72
+ rb-inotify (0.10.1)
73
+ ffi (~> 1.0)
74
+ rbs (3.1.3)
75
+ reek (6.1.4)
76
+ kwalify (~> 0.7.0)
77
+ parser (~> 3.2.0)
78
+ rainbow (>= 2.0, < 4.0)
79
+ regexp_parser (2.8.1)
80
+ reline (0.3.7)
81
+ io-console (~> 0.5)
82
+ rexml (3.2.6)
83
+ rspec (3.12.0)
84
+ rspec-core (~> 3.12.0)
85
+ rspec-expectations (~> 3.12.0)
86
+ rspec-mocks (~> 3.12.0)
87
+ rspec-core (3.12.2)
88
+ rspec-support (~> 3.12.0)
89
+ rspec-expectations (3.12.3)
90
+ diff-lcs (>= 1.2.0, < 2.0)
91
+ rspec-support (~> 3.12.0)
92
+ rspec-mocks (3.12.6)
93
+ diff-lcs (>= 1.2.0, < 2.0)
94
+ rspec-support (~> 3.12.0)
95
+ rspec-support (3.12.1)
96
+ rubocop (1.55.1)
97
+ json (~> 2.3)
98
+ language_server-protocol (>= 3.17.0)
99
+ parallel (~> 1.10)
100
+ parser (>= 3.2.2.3)
101
+ rainbow (>= 2.2.2, < 4.0)
102
+ regexp_parser (>= 1.8, < 3.0)
103
+ rexml (>= 3.2.5, < 4.0)
104
+ rubocop-ast (>= 1.28.1, < 2.0)
105
+ ruby-progressbar (~> 1.7)
106
+ unicode-display_width (>= 2.4.0, < 3.0)
107
+ rubocop-ast (1.29.0)
108
+ parser (>= 3.2.1.0)
109
+ rubocop-capybara (2.18.0)
110
+ rubocop (~> 1.41)
111
+ rubocop-factory_bot (2.23.1)
112
+ rubocop (~> 1.33)
113
+ rubocop-performance (1.18.0)
114
+ rubocop (>= 1.7.0, < 2.0)
115
+ rubocop-ast (>= 0.4.0)
116
+ rubocop-rspec (2.23.1)
117
+ rubocop (~> 1.33)
118
+ rubocop-capybara (~> 2.17)
119
+ rubocop-factory_bot (~> 2.22)
120
+ ruby-progressbar (1.13.0)
121
+ ruby_parser (3.20.3)
122
+ sexp_processor (~> 4.16)
123
+ scrub_rb (1.0.1)
124
+ securerandom (0.2.2)
125
+ sexp_processor (4.17.0)
126
+ steep (1.5.2)
127
+ activesupport (>= 5.1)
128
+ concurrent-ruby (>= 1.1.10)
129
+ csv (>= 3.0.9)
130
+ fileutils (>= 1.1.0)
131
+ json (>= 2.1.0)
132
+ language_server-protocol (>= 3.15, < 4.0)
133
+ listen (~> 3.0)
134
+ logger (>= 1.3.0)
135
+ parser (>= 3.1)
136
+ rainbow (>= 2.2.2, < 4.0)
137
+ rbs (>= 3.1.0)
138
+ securerandom (>= 0.1)
139
+ strscan (>= 1.0.0)
140
+ terminal-table (>= 2, < 4)
141
+ strscan (3.0.6)
142
+ strscan (3.0.6-java)
143
+ terminal-table (3.0.2)
144
+ unicode-display_width (>= 1.1.1, < 3)
145
+ tzinfo (2.0.6)
146
+ concurrent-ruby (~> 1.0)
147
+ unf (0.1.4)
148
+ unf_ext
149
+ unf (0.1.4-java)
150
+ unf_ext (0.0.8.2)
151
+ unicode-display_width (2.4.2)
152
+ webmock (3.18.1)
153
+ addressable (>= 2.8.0)
154
+ crack (>= 0.3.2)
155
+ hashdiff (>= 0.4.0, < 2.0.0)
156
+ zeitwerk (2.6.11)
157
+
158
+ PLATFORMS
159
+ arm64-darwin-21
160
+ arm64-darwin-22
161
+ universal-java-11
162
+ x86_64-linux
163
+
164
+ DEPENDENCIES
165
+ debug
166
+ evergreen-ils!
167
+ flay
168
+ flog
169
+ rake
170
+ rbs
171
+ reek
172
+ rspec
173
+ rubocop
174
+ rubocop-performance
175
+ rubocop-rspec
176
+ steep
177
+ webmock
178
+
179
+ BUNDLED WITH
180
+ 2.4.6
data/README.md ADDED
@@ -0,0 +1,68 @@
1
+ # Evergreen
2
+
3
+ A gem for interacting with [Evergreen ILS](https://evergreen-ils.org)
4
+
5
+ ## Installation
6
+
7
+ Install the gem and add to the application's Gemfile by executing:
8
+
9
+ $ bundle add evergreen-ils
10
+
11
+ If bundler is not being used to manage dependencies, install the gem by executing:
12
+
13
+ $ gem install evergreen-ils
14
+
15
+ ## Usage
16
+
17
+ ### Configuration
18
+
19
+ Configure your `Evergreen` object with a hostname, and any other relevant
20
+ options. If using Rails, you might create an Evergreen service:
21
+
22
+ ```
23
+ class EvergreenService
24
+ attr_reader :evergreen
25
+ def initialize
26
+ @evergreen ||= Evergreen.new do |config|
27
+ config.host = 'my.evergreen.server'
28
+ config.default_username = 'user1'
29
+ config.default_username = ENV['my_pass']
30
+ config.read_only = false
31
+ end
32
+ end
33
+ end
34
+ ```
35
+
36
+ You can then access those configurations in your app at
37
+ `service.evergreen.configuration.host`.
38
+
39
+ ### Retrieving objects
40
+
41
+ Once you have an object:
42
+
43
+ ```
44
+ Evergreen.new(host: 'my.evergreen.server') do |evergreen|
45
+ bib = evergreen.get_bib_record(123)
46
+ bib.to_marc
47
+ evergreen.get_item(345)
48
+ evergreen.get_call_number(2345)
49
+ end
50
+ ```
51
+
52
+
53
+ ## Development
54
+
55
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
56
+
57
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
58
+
59
+ ## Goals
60
+
61
+ The priorities here are:
62
+ * Thread safety
63
+ * Good documentation
64
+ * Good tests
65
+
66
+ ## Contributing
67
+
68
+ Bug reports and pull requests are welcome on GitHub at https://github.com/sandbergja/evergreen-rb.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/Steepfile ADDED
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # D = Steep::Diagnostic
4
+ #
5
+ target :lib do
6
+ signature 'sig'
7
+
8
+ check 'lib'
9
+
10
+ library 'json', 'net-http', 'uri'
11
+
12
+ ignore 'lib/evergreen.rb'
13
+ ignore 'lib/evergreen/bib_record.rb'
14
+ ignore 'lib/evergreen/connection.rb'
15
+ ignore 'lib/evergreen/idl.rb'
16
+ ignore 'lib/evergreen/mixins'
17
+ ignore 'lib/opensrf/http_translator_request.rb'
18
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/evergreen/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'evergreen-ils'
7
+ spec.version = Evergreen::VERSION
8
+ spec.authors = ['Jane Sandberg']
9
+ spec.email = ['sandbergja@gmail.com']
10
+
11
+ spec.summary = 'Evergreen ILS'
12
+ spec.description = 'A gem for interacting with the Evergreen Integrated Library System'
13
+ spec.homepage = 'https://github.com/sandbergja/evergreen-rb'
14
+ spec.required_ruby_version = '>= 3.0.0'
15
+
16
+ spec.metadata['homepage_uri'] = spec.homepage
17
+ spec.metadata['source_code_uri'] = 'https://github.com/sandbergja/evergreen-rb'
18
+
19
+ # Specify which files should be added to the gem when it is released.
20
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
21
+ spec.files = Dir.chdir(__dir__) do
22
+ `git ls-files -z`.split("\x0").reject do |f|
23
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
24
+ end
25
+ end
26
+ spec.bindir = 'exe'
27
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ['lib']
29
+
30
+ # Uncomment to register a new dependency of your gem
31
+ spec.add_dependency 'marc', '>= 1.0.0', '< 2.0'
32
+ spec.add_dependency 'rexml', '>= 3.0.0', '< 4.0'
33
+ spec.add_dependency 'zeitwerk', '>= 2.0.0', '< 3.0'
34
+
35
+ # For more information and examples about making a new gem, check out our
36
+ # guide at: https://bundler.io/guides/creating_gem.html
37
+ spec.metadata['rubygems_mfa_required'] = 'true'
38
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'marc'
4
+ require 'stringio'
5
+
6
+ class Evergreen
7
+ # A bibliographic record (title)
8
+ class BibRecord < IDLObject
9
+ include Mixins::AnonymousPcrud
10
+ def initialize(id:, configuration:, idl:)
11
+ @id = id
12
+ @configuration = configuration
13
+ super(idl)
14
+ end
15
+
16
+ # rubocop:disable Naming/MemoizedInstanceVariableName
17
+ def to_marc
18
+ @marc ||= MARC::XMLReader.new(StringIO.new(get('marc'))).first
19
+ end
20
+ # rubocop:enable Naming/MemoizedInstanceVariableName
21
+
22
+ def holdings
23
+ payload = OpenSRF::ClassAndData.new(klass: 'osrfMessage', data: {
24
+ 'method' => 'open-ils.cat.asset.copy_tree.global.retrieve',
25
+ 'params' => ['', @id.to_s]
26
+ }).to_h
27
+ OpenSRF::HTTPTranslatorRequest.new(payload: payload, configuration: @configuration,
28
+ service: 'open-ils.cat').response
29
+ end
30
+
31
+ def tcn
32
+ get 'tcn_value'
33
+ end
34
+
35
+ private
36
+
37
+ def idl_class
38
+ 'bre'
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Evergreen
4
+ # Configuration for an instance of Evergreen
5
+ class Configuration
6
+ attr_reader :host, :default_username, :default_password, :read_only
7
+
8
+ def initialize(config_hash)
9
+ @read_only = true
10
+ config_hash.each_pair do |key, value|
11
+ instance_variable_set("@#{key}", value)
12
+ end
13
+ configuration_complete
14
+ end
15
+
16
+ private
17
+
18
+ def configuration_complete
19
+ check_required_fields
20
+ freeze
21
+ end
22
+
23
+ def check_required_fields
24
+ raise ArgumentError, 'you must supply a host' if field_is_empty :host
25
+ return unless !@read_only && (field_is_empty(:default_username) || field_is_empty(:default_password))
26
+
27
+ raise ArgumentError, 'you must supply default credentials unless you are in read-only mode'
28
+ end
29
+
30
+ def field_is_empty(field_name)
31
+ field_value = instance_variable_get("@#{field_name}")
32
+ field_value.nil? || field_value.empty?
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Evergreen
4
+ # This class provides an interface for making
5
+ # requests to the Evergreen server
6
+ class Connection
7
+ include Mixins::RetrievalMethods
8
+ attr_reader :configuration
9
+
10
+ def initialize(configuration:)
11
+ @configuration = configuration
12
+ end
13
+
14
+ def close; end
15
+
16
+ def idl
17
+ @idl ||= IDL.new(@configuration)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open-uri'
4
+ require 'rexml/parsers/sax2parser'
5
+ require 'rexml/sax2listener'
6
+
7
+ class Evergreen
8
+ # Evergreen's fieldmapper IDL
9
+ class IDL
10
+ attr_reader :fields
11
+
12
+ def initialize(configuration)
13
+ @configuration = configuration
14
+ @handler = IDLSaxHandler.new
15
+ fetch
16
+ freeze
17
+ end
18
+
19
+ def [](key)
20
+ fields[key]
21
+ end
22
+
23
+ private
24
+
25
+ def fetch
26
+ URI.open("https://#{@configuration.host}/reports/fm_IDL.xml") do |file|
27
+ @fields = IDLSaxParser.new(file).parse
28
+ end
29
+ rescue Errno::ECONNREFUSED, OpenURI::HTTPError
30
+ raise Evergreen::ConnectionError
31
+ end
32
+
33
+ # A wrapper around the SAX parser
34
+ class IDLSaxParser
35
+ def initialize(file)
36
+ @parser = REXML::Parsers::SAX2Parser.new(file)
37
+ @handler = IDLSaxHandler.new
38
+ end
39
+
40
+ def parse
41
+ @parser.listen(@handler)
42
+ @parser.parse
43
+ @handler.idl_fields
44
+ end
45
+ end
46
+
47
+ # A SAX parsing handler
48
+ class IDLSaxHandler
49
+ include REXML::SAX2Listener
50
+ attr_reader :idl_fields
51
+
52
+ def initialize
53
+ @idl_fields = {}
54
+ @current_class = nil
55
+ super
56
+ end
57
+
58
+ # Callback for when we hit an XML attribute
59
+ def start_element(_uri, _localname, _qname, attributes)
60
+ if attributes.key? 'id'
61
+ # We found a class ID!
62
+ @current_class = attributes['id']
63
+ @idl_fields[@current_class] = []
64
+ elsif attributes.key? 'name'
65
+ # We found the name of a field!
66
+ @idl_fields[@current_class].push(attributes['name'])
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Evergreen
4
+ # A base class for any object represented in
5
+ # Evergreen's IDL
6
+ class IDLObject
7
+ def initialize(idl)
8
+ @idl = idl
9
+ end
10
+
11
+ def idl_fields
12
+ @idl[idl_class]
13
+ end
14
+
15
+ def get(field_name)
16
+ data[idl_fields.index(field_name)]
17
+ end
18
+
19
+ private
20
+
21
+ # This should be overriden by subclasses
22
+ def idl_class
23
+ 'acp'
24
+ end
25
+
26
+ def data; end
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Evergreen
4
+ module Mixins
5
+ # This read-only API is available
6
+ # without any credentials
7
+ module AnonymousPcrud
8
+ def data
9
+ return @data if @data
10
+ return unless @id && @configuration && idl_class && idl_fields
11
+
12
+ payload = OpenSRF::ClassAndData.new(klass: 'osrfMessage', data: {
13
+ 'method' => "open-ils.pcrud.retrieve.#{idl_class}",
14
+ 'params' => ['ANONYMOUS', @id.to_s]
15
+ }).to_h
16
+ response = OpenSRF::HTTPTranslatorRequest.new(payload: payload, configuration: @configuration,
17
+ service: 'open-ils.pcrud').response
18
+ @data = OpenSRF::ClassAndData.parse(response['content']).data
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Evergreen
4
+ module Mixins
5
+ # Convenience methods to search for data
6
+ # and initialize objects based on the results
7
+ module RetrievalMethods
8
+ def get_bib_record(id)
9
+ Evergreen::BibRecord.new(id: id, configuration: configuration, idl: idl)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Evergreen
4
+ VERSION = '0.2.0'
5
+ end
data/lib/evergreen.rb ADDED
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'zeitwerk'
4
+ loader = Zeitwerk::Loader.for_gem
5
+ loader.inflector.inflect(
6
+ 'http_translator_request' => 'HTTPTranslatorRequest',
7
+ 'idl' => 'IDL',
8
+ 'idl_object' => 'IDLObject',
9
+ 'opensrf' => 'OpenSRF',
10
+ 'json' => 'JSON'
11
+ )
12
+ loader.setup
13
+
14
+ # The main class provided by this gem
15
+ class Evergreen
16
+ def initialize(config_hash)
17
+ connection = Connection.new(configuration: Configuration.new(config_hash))
18
+ yield connection
19
+ connection.close
20
+ end
21
+
22
+ # An error when we can't connect to the Evergreen server
23
+ class ConnectionError < StandardError; end
24
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenSRF
4
+ # OpenSRF requests and responses often
5
+ # take the following form
6
+ # {"__c": "clasname", "__p": ["all", "the", "data"]}
7
+ class ClassAndData
8
+ attr_reader :klass, :data
9
+
10
+ def initialize(klass:, data:)
11
+ @klass = klass
12
+ @data = data
13
+ end
14
+
15
+ def self.parse(hash, path = [])
16
+ small_json = new(klass: hash['__c'], data: hash['__p'])
17
+ return small_json if path.empty?
18
+
19
+ key = path.shift
20
+ parse(small_json.data[key], path)
21
+ end
22
+
23
+ def to_h
24
+ { '__c' => @klass,
25
+ '__p' => @data }
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'net/http'
5
+ require 'uri'
6
+
7
+ module OpenSRF
8
+ # A stateful endpoint, described in
9
+ # this documentation:
10
+ # https://docs.evergreen-ils.org/eg/docs/latest/integrations/web_services.html#_http_translator
11
+ class HTTPTranslatorRequest
12
+ def initialize(configuration:, service:, payload:)
13
+ @configuration = configuration
14
+ @service = service
15
+ @payload = payload
16
+ end
17
+
18
+ def response
19
+ raw = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
20
+ http.request(request)
21
+ end
22
+ OpenSRF::ClassAndData.parse(::JSON.parse(raw.body).first, ['payload']).data
23
+ end
24
+
25
+ private
26
+
27
+ def request
28
+ request = Net::HTTP::Post.new(uri)
29
+ request['X-Opensrf-Service'] = @service
30
+ request.body = "osrf-msg=#{osrf_message.to_json}"
31
+ request
32
+ end
33
+
34
+ def osrf_message
35
+ [
36
+ OpenSRF::ClassAndData.new(klass: 'osrfMessage', data: {
37
+ 'threadTrace' => 0,
38
+ 'locale' => 'en-CA',
39
+ 'type' => 'REQUEST',
40
+ 'payload' => @payload
41
+ }).to_h
42
+ ]
43
+ end
44
+
45
+ def req_options
46
+ { use_ssl: true }
47
+ end
48
+
49
+ def uri
50
+ URI.parse("https://#{@configuration.host}/osrf-http-translator")
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,22 @@
1
+ class Evergreen
2
+ # Configuration for an instance of Evergreen
3
+ class Configuration
4
+ attr_accessor host: untyped
5
+
6
+ attr_accessor default_username: untyped
7
+
8
+ attr_accessor default_password: untyped
9
+
10
+ attr_accessor read_only: untyped
11
+
12
+ def initialize: (Hash[Symbol, (String | bool)]) -> void
13
+
14
+ def configuration_complete: () -> untyped
15
+
16
+ private
17
+
18
+ def check_required_fields: () -> (nil | untyped)
19
+
20
+ def field_is_empty: (untyped field_name) -> untyped
21
+ end
22
+ end
@@ -0,0 +1,13 @@
1
+ class Evergreen
2
+ # This class provides an interface for making
3
+ # requests to the Evergreen server
4
+ class Connection
5
+ attr_reader configuration: Evergreen::Configuration
6
+
7
+ def initialize: (configuration: untyped) -> void
8
+
9
+ def close: () -> nil
10
+
11
+ def idl: () -> Evergreen::IDL
12
+ end
13
+ end
@@ -0,0 +1,31 @@
1
+ class Evergreen
2
+ # Evergreen's fieldmapper IDL
3
+ class IDL
4
+ attr_reader fields: untyped
5
+
6
+ def initialize: (untyped configuration) -> void
7
+
8
+ def []: (untyped key) -> untyped
9
+
10
+ private
11
+
12
+ def fetch: () -> untyped
13
+
14
+ # A wrapper around the SAX parser
15
+ class IDLSaxParser
16
+ def initialize: (untyped file) -> void
17
+
18
+ def parse: () -> untyped
19
+ end
20
+
21
+ # A SAX parsing handler
22
+ class IDLSaxHandler
23
+ attr_reader idl_fields: untyped
24
+
25
+ def initialize: () -> void
26
+
27
+ # Callback for when we hit an XML attribute
28
+ def start_element: (untyped _uri, untyped _localname, untyped _qname, untyped attributes) -> (untyped | untyped | nil)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,10 @@
1
+ class Evergreen::IDLObject
2
+ @idl: untyped
3
+
4
+ def initialize: (untyped idl) -> void
5
+ def idl_fields: -> untyped
6
+
7
+ private
8
+ def idl_class: -> String
9
+ def data: -> untyped
10
+ end
@@ -0,0 +1,9 @@
1
+ class Evergreen
2
+ module Mixins
3
+ # Convenience methods to search for data
4
+ # and initialize objects based on the results
5
+ module RetrievalMethods
6
+ def get_bib_record: (untyped id) -> untyped
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ # TypeProf 0.21.2
2
+
3
+ # Classes
4
+ class Evergreen
5
+ VERSION: String
6
+ end
@@ -0,0 +1,12 @@
1
+ # TypeProf 0.21.2
2
+
3
+ # Classes
4
+ module OpenSRF
5
+ class ClassAndData
6
+ attr_reader klass: untyped
7
+ attr_reader data: untyped
8
+ def initialize: (klass: untyped, data: untyped) -> void
9
+ def self.parse: (untyped hash, ?Array[untyped] path) -> ClassAndData
10
+ def to_h: -> Hash[String, untyped]
11
+ end
12
+ end
@@ -0,0 +1,20 @@
1
+ module OpenSRF
2
+ # A stateful endpoint, described in
3
+ # this documentation:
4
+ # https://docs.evergreen-ils.org/eg/docs/latest/integrations/web_services.html#_http_translator
5
+ class HTTPTranslatorRequest
6
+ def initialize: (configuration: untyped, service: untyped, payload: untyped) -> void
7
+
8
+ def response: () -> untyped
9
+
10
+ private
11
+
12
+ def request: () -> untyped
13
+
14
+ def osrf_message: () -> ::Array[untyped]
15
+
16
+ def req_options: () -> { use_ssl: true }
17
+
18
+ def uri: () -> untyped
19
+ end
20
+ end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: evergreen-ils
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Jane Sandberg
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-08-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: marc
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.0
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '2.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 1.0.0
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '2.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: rexml
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 3.0.0
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: '4.0'
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 3.0.0
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: '4.0'
53
+ - !ruby/object:Gem::Dependency
54
+ name: zeitwerk
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 2.0.0
60
+ - - "<"
61
+ - !ruby/object:Gem::Version
62
+ version: '3.0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: 2.0.0
70
+ - - "<"
71
+ - !ruby/object:Gem::Version
72
+ version: '3.0'
73
+ description: A gem for interacting with the Evergreen Integrated Library System
74
+ email:
75
+ - sandbergja@gmail.com
76
+ executables: []
77
+ extensions: []
78
+ extra_rdoc_files: []
79
+ files:
80
+ - ".reek.yml"
81
+ - ".rspec"
82
+ - ".rubocop.yml"
83
+ - ".tool-versions"
84
+ - Gemfile
85
+ - Gemfile.lock
86
+ - README.md
87
+ - Rakefile
88
+ - Steepfile
89
+ - evergreen-ils.gemspec
90
+ - lib/evergreen.rb
91
+ - lib/evergreen/bib_record.rb
92
+ - lib/evergreen/configuration.rb
93
+ - lib/evergreen/connection.rb
94
+ - lib/evergreen/idl.rb
95
+ - lib/evergreen/idl_object.rb
96
+ - lib/evergreen/mixins/anonymous_pcrud.rb
97
+ - lib/evergreen/mixins/retrieval_methods.rb
98
+ - lib/evergreen/version.rb
99
+ - lib/opensrf/class_and_data.rb
100
+ - lib/opensrf/http_translator_request.rb
101
+ - sig/evergreen/configuration.rbs
102
+ - sig/evergreen/connection.rbs
103
+ - sig/evergreen/idl.rbs
104
+ - sig/evergreen/idl_object.rbs
105
+ - sig/evergreen/mixins/retrieval_methods.rb
106
+ - sig/evergreen/version.rbs
107
+ - sig/opensrf/class_and_data.rbs
108
+ - sig/opensrf/http_translator_request.rbs
109
+ homepage: https://github.com/sandbergja/evergreen-rb
110
+ licenses: []
111
+ metadata:
112
+ homepage_uri: https://github.com/sandbergja/evergreen-rb
113
+ source_code_uri: https://github.com/sandbergja/evergreen-rb
114
+ rubygems_mfa_required: 'true'
115
+ post_install_message:
116
+ rdoc_options: []
117
+ require_paths:
118
+ - lib
119
+ required_ruby_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: 3.0.0
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubygems_version: 3.4.6
131
+ signing_key:
132
+ specification_version: 4
133
+ summary: Evergreen ILS
134
+ test_files: []