openaccess-apc 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c1c1f1d067a196318d056eaae505d6ecc50fdffb
4
+ data.tar.gz: 729dab62bef1fcfc3a9b03231b120385e3b6d556
5
+ SHA512:
6
+ metadata.gz: '08b4d2233a9165d57b30e2a91ca16a6d93bb46d7bcadd61ad3c4e302f5b3073b1cce4f60d46b980de3dc49b078bce985d8079bc8342e493cc54f953495eefe21'
7
+ data.tar.gz: 2d97a3ca77a39bab5e5efb6bc2820e425d915d4b8dcea96224dd35e846bc569b39015e8ca173ff6e32382077ede18f40b57e988856f5c908a3cfe66b408c0280
data/.gitignore ADDED
@@ -0,0 +1,54 @@
1
+ # RubyMine
2
+ /.idea/
3
+
4
+ # Ruby .gitignore from GitHub
5
+ *.gem
6
+ *.rbc
7
+ /.config
8
+ /coverage/
9
+ /InstalledFiles
10
+ /pkg/
11
+ /spec/reports/
12
+ /spec/examples.txt
13
+ /test/tmp/
14
+ /test/version_tmp/
15
+ /tmp/
16
+
17
+ # Used by dotenv library to load environment variables.
18
+ .env
19
+
20
+ ## Specific to RubyMotion:
21
+ .dat*
22
+ .repl_history
23
+ build/
24
+ *.bridgesupport
25
+ build-iPhoneOS/
26
+ build-iPhoneSimulator/
27
+
28
+ ## Specific to RubyMotion (use of CocoaPods):
29
+ #
30
+ # We recommend against adding the Pods directory to your .gitignore. However
31
+ # you should judge for yourself, the pros and cons are mentioned at:
32
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
33
+ #
34
+ # vendor/Pods/
35
+
36
+ ## Documentation cache and generated files:
37
+ /.yardoc/
38
+ /_yardoc/
39
+ /doc/
40
+ /rdoc/
41
+
42
+ ## Environment normalization:
43
+ /.bundle/
44
+ /vendor/bundle
45
+ /lib/bundler/man/
46
+
47
+ # for a library or gem, you might want to ignore these files since the code is
48
+ # intended to run in multiple environments; otherwise, check them in:
49
+ Gemfile.lock
50
+ .ruby-version
51
+ .ruby-gemset
52
+
53
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
54
+ .rvmrc
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.2
5
+ before_install: gem install bundler -v 1.15.4
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at Sh3d0fd00m. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in openaccess-apc.gemspec
6
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 lbaajh
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,114 @@
1
+ # OpenAccess::APC
2
+
3
+ This gem provides tools for managing open access article processing charge (APC)
4
+ funding applications at Lancaster University.
5
+
6
+ Researchers are expected to create publication records in the Pure research
7
+ information system before making an PC funding application. This gem retrieves
8
+ these records from Pure to support the process of selecting publications for
9
+ funding.
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'openaccess-apc'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install openaccess-apc
26
+
27
+ ## Usage
28
+
29
+ ### Configuration
30
+
31
+ ```ruby
32
+ require 'openaccess-apc'
33
+
34
+ OpenAccess::APC.configure do |config|
35
+
36
+ # Use LDAP for user resolution
37
+ # The attribute supplying the Pure user ID
38
+ config[:ldap][:attribute_pure_id] = 'uolOwnerCid'
39
+ # The attribute supplying the single-sign-on username
40
+ config[:ldap][:attribute_username] = 'uid'
41
+ # The LDAP service username and password
42
+ config[:ldap][:auth][:password] = 'ldap-service-password'
43
+ config[:ldap][:auth][:username] = 'ldap-service-username'
44
+ # The LDAP base for searches
45
+ config[:ldap][:base] = 'ou=users,dc=lancs,dc=ac,dc=uk'
46
+ # The LDAP server
47
+ config[:ldap][:host] = '<LDAP-server>'
48
+
49
+ # Pure
50
+ config[:pure][:password] = 'Pure web service password'
51
+ config[:pure][:url] = 'https://<Pure-server>/ws/rest'
52
+ config[:pure][:username] = 'Pure web service username'
53
+ end
54
+ ```
55
+ ### Get Pure person ID
56
+
57
+ ```ruby
58
+ username = ENV['REMOTE_USER']
59
+ begin
60
+ person_uuid = OpenAccess::APC.person(username)
61
+ rescue OpenAccess::APC::Exceptions::UserNotFound
62
+ # Raised when the user can't be resolved in Pure
63
+ end
64
+ ```
65
+
66
+ ### Get publications summary
67
+
68
+ By default, publications created in Pure within the last 6 months with workflow
69
+ status 'forApproval' or 'approved'.
70
+
71
+ ```ruby
72
+ pubs = OpenAccess::APC.publications_for_person(person_uuid)
73
+
74
+ # => [
75
+ # {
76
+ # created: 'date created in Pure: YYYY-MM-DD',
77
+ # description: 'publication description',
78
+ # dois: ['doi1', 'doi2', ...],
79
+ # subtitle: 'publication subtitle',
80
+ # title: 'publication title',
81
+ # translated_subtitle: 'translated subtitle',
82
+ # translated_title: 'translated title',
83
+ # uuid: 'publication UUID',
84
+ # workflow_state: 'approved'|'entryInProgress'|'forApproval'|
85
+ # 'forRevalidation'
86
+ # },
87
+ # { ... },
88
+ # ]
89
+ ```
90
+ To limit by creation date and workflow state:
91
+
92
+ ```ruby
93
+ pubs = OpenAccess::API.publications_for_person(person_uuid,
94
+ created_start: '2017-01-01',
95
+ created_end: '2017-12-31',
96
+ workflow_states: ['forApproval'])
97
+ ```
98
+ ## Development
99
+
100
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
101
+
102
+ 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 tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
103
+
104
+ ## Contributing
105
+
106
+ Bug reports and pull requests are welcome on GitHub at https://github.com/lulibrary/openaccess-apc. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
107
+
108
+ ## License
109
+
110
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
111
+
112
+ ## Code of Conduct
113
+
114
+ Everyone interacting in the OpenAccess::APC project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/openaccess-apc/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "openaccess/apc"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,286 @@
1
+ require 'net/ldap'
2
+ require 'puree'
3
+
4
+ require 'openaccess/apc/exceptions'
5
+ require 'openaccess/apc/version'
6
+
7
+ # Monkey-patch the Puree person-publications query to support additional
8
+ # parameters
9
+ module Puree
10
+ module Query
11
+ # Add the creation and modification dates to the selection criteria for
12
+ # publications
13
+ class Person
14
+ # Maps keyword arguments to Pure query parameters
15
+ # The query parameter is either a String (the name of the parameter) or
16
+ # a Proc which accepts the keyword argument name, value and query
17
+ # parameter hash and modifies the query hash as required.
18
+ OPTS = {
19
+ created_end: 'createdDate.toDate',
20
+ created_start: 'createdDate.fromDate',
21
+ modified_end: 'modifiedDate.toDate',
22
+ modified_start: 'modifiedDate.fromDate',
23
+ order_by: proc do |_opt, values, query|
24
+ values = [values] unless values.is_a?(Array)
25
+ values.each_index do |i|
26
+ value = values[i]
27
+ if '+-'.include?(value[0])
28
+ descending = value[0] == '-' ? 'true' : 'false'
29
+ value = value[1..-1]
30
+ else
31
+ descending = 'false'
32
+ end
33
+ param = format('orderBy.property[%d]', i)
34
+ query[param] = value
35
+ param = format('orderBy.property[%d].descending', i)
36
+ query[param] = descending
37
+ end
38
+ end,
39
+ published_end: 'publicationDate.toDate',
40
+ published_start: 'publicationDate.fromDate',
41
+ workflow_states: proc do |_opt, values, query|
42
+ values = [values] unless value.is_a?(Array)
43
+ values.each_index do |i|
44
+ param = format('workflowStates.workflowState[%d].workflowName', i)
45
+ query[param] = 'publication'
46
+ param = format('workflowStates.workflowState[%d]', i)
47
+ query[param] = values[i].to_s
48
+ end
49
+ end
50
+ }.freeze
51
+
52
+ # Returns an array of publications for the given person's UUID
53
+ # @param uuid [String] the person UUID
54
+ # @param limit [Integer] the number of results to return
55
+ # @param opts [Hash] the options hash
56
+ # @option opts [String] :uuid the person UUID owning the publications
57
+ # @option opts [Numeric] :limit the maximum number of results to return
58
+ # @option opts [Numeric] :offset the start of the result set
59
+ # @option opts [String] :created_start the creation start date
60
+ # @option opts [String] :created_end the creation end date
61
+ # @option opts [String] :modified_start the modification start date
62
+ # @option opts [String] :modified_end the modification end date
63
+ # @option opts [Array<String>] :order_by the list of fields to sort the
64
+ # result set. Each field can be prefixed by '+' (ascending sort) or '-'
65
+ # (descending sort); the default is ascending.
66
+ # @option opts [String] :published_start the publication start date
67
+ # @option opts [String] :published_end the publication end date
68
+ # @option opts [Array<String>] :workflow_states the valid workflow
69
+ # states (:approved|:entryInProgress|:forApproval|:forRevalidation)
70
+ # @return [Array<Puree::Model::Publication] the array of publications
71
+ def publications_extended(uuid:, limit:, **opts)
72
+ uuids = publication_uuids_extended(uuid: uuid, limit: limit, **opts)
73
+ publications = []
74
+ uuids.each do |u|
75
+ publication_extractor = Puree::Extractor::Publication.new(@config)
76
+ publication = publication_extractor.find uuid: u
77
+ publications << publication if publication
78
+ end
79
+ publications
80
+ end
81
+
82
+ # Returns an array of publication UUIDs for the given person's UUID
83
+ # @param (see #publications_extended)
84
+ # @return [Array<String>] the array of publication UUIDs
85
+ def publication_uuids_extended(uuid:, limit:, **opts)
86
+ params = {
87
+ 'associatedPersonUuids.uuid' => uuid,
88
+ 'rendering' => :system,
89
+ 'window.size' => limit.to_s,
90
+ 'window.offset' => (opts[:offset] || 0).to_s
91
+ }
92
+ self.class.query_params(params, **opts)
93
+ headers
94
+ response = @req.get(build_publication_url, params: params)
95
+ extract_publication_uuids(make_doc(response.body))
96
+ end
97
+
98
+ # Adds whitelisted keyword arguments to the supplied query parameter hash
99
+ # @param params [Hash] the query parameters hash
100
+ # @return [void]
101
+ def self.query_params(params, **opts)
102
+ OPTS.each do |opt, param|
103
+ next unless opts[opt]
104
+ if param.is_a?(Proc)
105
+ param.call(opt, opts[opt], params)
106
+ else
107
+ params[param] = opts[opt]
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+
115
+ module OpenAccess
116
+ # Methods for managing open access article publishing charges (APCs)
117
+ module APC
118
+ # Exceptions
119
+ include Exceptions
120
+
121
+ # Module configuration
122
+ @config = {
123
+ ldap: {
124
+ # The LDAP attribute supplying the Pure employee ID
125
+ attribute_pure_id: nil,
126
+ # The LDAP attribute supplying the network username
127
+ attribute_username: nil,
128
+ auth: {
129
+ # The LDAP authentication method
130
+ method: :simple,
131
+ # The LDAP service user account's password
132
+ password: nil,
133
+ # The LDAP service user account's username
134
+ username: nil
135
+ },
136
+ # The base tree of the LDAP directory
137
+ base: nil,
138
+ # The LDAP server hostname
139
+ host: nil,
140
+ # The LDAP server's port
141
+ port: 389
142
+ },
143
+ pure: {
144
+ # The Pure web service user's password
145
+ password: nil,
146
+ # The base URL of the Pure web service
147
+ url: nil,
148
+ # The Pure web service user's username
149
+ username: nil
150
+ }
151
+ }
152
+
153
+ @person_extractor = nil
154
+ @person_query = nil
155
+
156
+ # Sets the module configuration
157
+ # @return [void]
158
+ # @yield [config] Passes the configuration hash to the block
159
+ # @yieldparam config [Hash] the configuration hash
160
+ def self.configure
161
+ # Get user-supplied configuration from the block
162
+ yield(@config)
163
+
164
+ # LDAP client for person resolution
165
+ @ldap = configure_ldap
166
+
167
+ # Pure clients
168
+ @person_extractor = Puree::Extractor::Person.new(@config[:pure])
169
+ @person_query = Puree::Query::Person.new(@config[:pure])
170
+ end
171
+
172
+ # Returns the Pure person UUID given a network username
173
+ # @param username [String] the network username
174
+ # @return [String] the Pure UUID of the corresponding person
175
+ def self.person(username = nil)
176
+ employee_id = person_employee_id(username)
177
+ person = @person_extractor.find_by_id(employee_id: employee_id)
178
+ return person.uuid unless person.nil?
179
+ raise UserNotFound, 'No user for employee ID: ' \
180
+ "#{employee_id} (username: #{username})"
181
+ end
182
+
183
+ # Returns an array of publication summary details for the N most recent
184
+ # funding-eligible publications
185
+ # @param username [String] the network username
186
+ # @param opts [Hash] the options hash
187
+ # @option opts [Date, DateTime, String, Time] :created_end include
188
+ # publications deposited on or up to this date
189
+ # @option opts [Date, DateTime, String, Time] :created_start include
190
+ # publications deposited on or after this date
191
+ # @option opts [Integer] :results the number of eligible publications
192
+ # required
193
+ def self.publications_for_person(username, **opts)
194
+ person_uuid = person(username)
195
+ publications_criteria(opts)
196
+ pubs = @person_query.publications_extended(uuid: person_uuid, **opts)
197
+ publications_summary(pubs[0..opts[:results]])
198
+ end
199
+
200
+ # Private helpers
201
+
202
+ # Returns a configured Net::LDAP instance
203
+ # @return [Net::LDAP] the LDAP instance
204
+ def self.configure_ldap
205
+ conf = @config[:ldap]
206
+ Net::LDAP.new(host: conf[:host], port: conf[:port], auth: conf[:auth])
207
+ end
208
+ private_class_method :configure_ldap
209
+
210
+ # Returns the Pure employee ID given a network username
211
+ # @param username [String] the network username
212
+ # @return [String] the Pure employee ID
213
+ def self.person_employee_id(username = nil)
214
+ # Get the LDAP record for the username
215
+ c = @config[:ldap]
216
+ filter = Net::LDAP::Filter.eq(c[:attribute_username], username)
217
+ # Return the value of the LDAP attribute containing the Pure employee ID
218
+ @ldap.search(base: c[:base], filter: filter) do |entry|
219
+ pure_id = entry[c[:attribute_pure_id]]
220
+ return pure_id[0] unless pure_id.nil? || pure_id.empty?
221
+ end
222
+ raise UserNotFound, "No user for username: #{username}"
223
+ end
224
+ private_class_method :person_employee_id
225
+
226
+ # Returns a hash of publication summary details ready for JSON formatting
227
+ # @param pub [Puree::Model::Publication] the publication
228
+ # @return [Hash] the publication summary
229
+ # rubocop:disable Metrics/MethodLength
230
+ def self.publication_summary(pub)
231
+ {
232
+ created: pub.created,
233
+ description: pub.description,
234
+ dois: pub.dois,
235
+ subtitle: pub.subtitle,
236
+ title: pub.title,
237
+ translated_subtitle: pub.translated_subtitle,
238
+ translated_title: pub.translated_title,
239
+ uuid: pub.uuid,
240
+ workflow_state: pub.workflow_state
241
+ }
242
+ end
243
+ private_class_method :publication_summary
244
+
245
+ # Sets the Puree person query criteria in an options hash
246
+ # @param opts [Hash] the options hash
247
+ # @return [Hash] the options hash
248
+ def self.publications_criteria(opts)
249
+ opts[:results] ||= 5
250
+ opts[:limit] ||= opts[:results] * 10
251
+ opts[:order_by] = ['-created']
252
+ # End date defaults to today; start date defaults to 6 months before end
253
+ end_date = to_date(opts[:created_date_end], Date.today)
254
+ start_date = to_date(opts[:created_date_start], end_date - 183)
255
+ opts[:created_end] = end_date.to_s # YYYY-MM-DD
256
+ opts[:created_start] = start_date.to_s
257
+ opts
258
+ end
259
+ private_class_method :publications_criteria
260
+
261
+ # Returns a list of publication summaries ready for JSON formatting
262
+ # @param pubs [Array<Puree::Model::Publication>] the publications
263
+ # @return [Array<Hash>] the publication summaries
264
+ def self.publications_summary(pubs)
265
+ pubs.map { |p| publication_summary(p) }
266
+ end
267
+ private_class_method :publications_summary
268
+
269
+ # Converts a date representation to a Date instance.
270
+ # Date instances are returned as-is. DateTime and Time instances are
271
+ # converted to Date instances. All other types are converted to a string
272
+ # and parsed.
273
+ # @param date [Object] the date representation
274
+ # @param default [Date, nil] the default value if no date is supplied or
275
+ # string parsing fails
276
+ def self.to_date(date = nil, default = nil)
277
+ return default if date.nil? || date.empty?
278
+ return date if date.is_a?(Date)
279
+ return date.to_date if date.respond_to?(:to_date)
280
+ Date.parse(date.to_s)
281
+ rescue ArgumentError
282
+ default
283
+ end
284
+ private_class_method :to_date
285
+ end
286
+ end
@@ -0,0 +1,11 @@
1
+ module OpenAccess
2
+ module APC
3
+ module Exceptions
4
+ # The base class for all exceptions
5
+ class APCError < StandardError; end
6
+
7
+ # Raised when a user can't be identified in Pure
8
+ class UserNotFound < APCError; end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ module OpenAccess
2
+ module APC
3
+ VERSION = '0.1.0'.freeze
4
+ end
5
+ end
@@ -0,0 +1,35 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'openaccess/apc/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'openaccess-apc'
7
+ spec.version = OpenAccess::APC::VERSION
8
+ spec.authors = ['Digital Innovation, Lancaster University Library']
9
+ spec.email = ['library.dit@lancaster.ac.uk']
10
+
11
+ spec.summary = 'Open Access article processing charge (APC) funding ' \
12
+ 'application tools'
13
+ spec.description = 'This gem integrates with the Pure CRIS to streamline ' \
14
+ 'the process of applying for funding for Open Access ' \
15
+ 'publishing charges.'
16
+ spec.homepage = 'https://github.com/lulibrary/openaccess-apc.git'
17
+ spec.license = 'MIT'
18
+
19
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
20
+ f.match(%r{^(test|spec|features)/})
21
+ end
22
+ spec.bindir = 'exe'
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ['lib']
25
+
26
+ spec.add_dependency 'net-ldap', '~> 0.16'
27
+ spec.add_dependency 'puree', '~> 1.7'
28
+
29
+ spec.add_development_dependency 'bundler', '~> 1.15'
30
+ spec.add_development_dependency 'dotenv', '~> 2.2'
31
+ spec.add_development_dependency 'minitest', '~> 5.0'
32
+ spec.add_development_dependency 'minitest-reporters', '~> 1.1'
33
+ spec.add_development_dependency 'rake', '~> 10.0'
34
+ spec.add_development_dependency 'rubocop', '~> 0.50'
35
+ end
metadata ADDED
@@ -0,0 +1,170 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: openaccess-apc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Digital Innovation, Lancaster University Library
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-11-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: net-ldap
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.16'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: puree
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.7'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.15'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.15'
55
+ - !ruby/object:Gem::Dependency
56
+ name: dotenv
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '5.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '5.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: minitest-reporters
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.1'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.1'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '10.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '10.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.50'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0.50'
125
+ description: This gem integrates with the Pure CRIS to streamline the process of applying
126
+ for funding for Open Access publishing charges.
127
+ email:
128
+ - library.dit@lancaster.ac.uk
129
+ executables: []
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - ".gitignore"
134
+ - ".travis.yml"
135
+ - CODE_OF_CONDUCT.md
136
+ - Gemfile
137
+ - LICENSE.txt
138
+ - README.md
139
+ - Rakefile
140
+ - bin/console
141
+ - bin/setup
142
+ - lib/openaccess/apc.rb
143
+ - lib/openaccess/apc/exceptions.rb
144
+ - lib/openaccess/apc/version.rb
145
+ - openaccess-apc.gemspec
146
+ homepage: https://github.com/lulibrary/openaccess-apc.git
147
+ licenses:
148
+ - MIT
149
+ metadata: {}
150
+ post_install_message:
151
+ rdoc_options: []
152
+ require_paths:
153
+ - lib
154
+ required_ruby_version: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ required_rubygems_version: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - ">="
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ requirements: []
165
+ rubyforge_project:
166
+ rubygems_version: 2.6.13
167
+ signing_key:
168
+ specification_version: 4
169
+ summary: Open Access article processing charge (APC) funding application tools
170
+ test_files: []