stash-merritt 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +193 -0
  3. data/.rubocop.yml +32 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +12 -0
  6. data/Gemfile +6 -0
  7. data/Gemfile.lock +326 -0
  8. data/LICENSE.md +22 -0
  9. data/README.md +53 -0
  10. data/Rakefile +49 -0
  11. data/lib/datacite/mapping/datacite_xml_factory.rb +212 -0
  12. data/lib/stash/merritt/ezid_helper.rb +50 -0
  13. data/lib/stash/merritt/module_info.rb +12 -0
  14. data/lib/stash/merritt/repository.rb +17 -0
  15. data/lib/stash/merritt/submission_job.rb +90 -0
  16. data/lib/stash/merritt/submission_package/data_one_manifest_builder.rb +41 -0
  17. data/lib/stash/merritt/submission_package/merritt_datacite_builder.rb +22 -0
  18. data/lib/stash/merritt/submission_package/merritt_delete_builder.rb +25 -0
  19. data/lib/stash/merritt/submission_package/merritt_oaidc_builder.rb +130 -0
  20. data/lib/stash/merritt/submission_package/stash_wrapper_builder.rb +59 -0
  21. data/lib/stash/merritt/submission_package.rb +125 -0
  22. data/lib/stash/merritt/sword_helper.rb +58 -0
  23. data/lib/stash/merritt.rb +5 -0
  24. data/lib/stash.rb +5 -0
  25. data/spec/.rubocop.yml +10 -0
  26. data/spec/config/app_config.yml +3 -0
  27. data/spec/config/database.yml +7 -0
  28. data/spec/config/licenses.yml +18 -0
  29. data/spec/data/archive/mrt-datacite.xml +121 -0
  30. data/spec/data/archive/mrt-dataone-manifest.txt +32 -0
  31. data/spec/data/archive/mrt-oaidc.xml +38 -0
  32. data/spec/data/archive/stash-wrapper.xml +213 -0
  33. data/spec/data/archive.zip +0 -0
  34. data/spec/data/dc4-with-funding-references.xml +123 -0
  35. data/spec/db/datacite/mapping/datacite_xml_factory_spec.rb +56 -0
  36. data/spec/db/stash/merritt/merritt_oaidc_builder_spec.rb +72 -0
  37. data/spec/db/stash/merritt/submission_package_spec.rb +174 -0
  38. data/spec/db/stash/merritt/sword_helper_spec.rb +162 -0
  39. data/spec/db_spec_helper.rb +31 -0
  40. data/spec/rspec_custom_matchers.rb +92 -0
  41. data/spec/spec_helper.rb +86 -0
  42. data/spec/unit/stash/merritt/ezid_helper_spec.rb +88 -0
  43. data/spec/unit/stash/merritt/repository_spec.rb +19 -0
  44. data/spec/unit/stash/merritt/submission_job_spec.rb +127 -0
  45. data/spec/util/resource_builder.rb +333 -0
  46. data/stash-merritt.gemspec +48 -0
  47. data/stash-merritt.iml +147 -0
  48. data/stash-merritt.ipr +127 -0
  49. data/travis-local-deps.sh +43 -0
  50. metadata +337 -0
@@ -0,0 +1,333 @@
1
+ require 'datacite/mapping'
2
+ require 'stash/wrapper'
3
+ require 'time'
4
+
5
+ # TODO: Get rid of this and use FactoryGirl or something
6
+ module StashDatacite
7
+ class ResourceBuilder # rubocop:disable Metrics/ClassLength
8
+ DESCRIPTION_TYPE = Datacite::Mapping::DescriptionType
9
+
10
+ attr_reader :user_id
11
+ attr_reader :dcs_resource
12
+ attr_reader :stash_files
13
+ attr_reader :upload_time
14
+
15
+ def initialize(user_id:, dcs_resource:, stash_files:, upload_date:)
16
+ @user_id = user_id
17
+ @dcs_resource = ResourceBuilder.dcs_resource(dcs_resource)
18
+ @stash_files = ResourceBuilder.stash_files(stash_files)
19
+ @upload_time = upload_date.to_time
20
+ end
21
+
22
+ def self.dcs_resource(dcs_resource)
23
+ return dcs_resource if dcs_resource.is_a?(Datacite::Mapping::Resource)
24
+ return dcs_resource if dcs_resource.to_s =~ /InstanceDouble\(Datacite::Mapping::Resource\)/ # For RSpec tests
25
+ raise ArgumentError, "dcs_resource does not appear to be a Datacite::Mapping::Resource: #{dcs_resource || 'nil'}"
26
+ end
27
+
28
+ def self.stash_files(stash_files)
29
+ return stash_files if stash_files.all? do |file|
30
+ file.is_a?(Stash::Wrapper::StashFile) ||
31
+ file.to_s =~ /InstanceDouble\(Stash::Wrapper::StashFile\)/ # For RSpec tests
32
+ end
33
+ raise ArgumentError, "stash_files does not appear to be an array of Stash::Wrapper::StashFile objects: #{stash_files || 'nil'}"
34
+ end
35
+
36
+ def build
37
+ populate_se_resource!
38
+ end
39
+
40
+ private
41
+
42
+ def se_resource
43
+ @se_resource ||= StashEngine::Resource.create(user_id: user_id)
44
+ end
45
+
46
+ def se_resource_id
47
+ se_resource.id
48
+ end
49
+
50
+ def populate_se_resource! # rubocop:disable Metrics/AbcSize
51
+ set_sd_identifier(dcs_resource.identifier)
52
+ stash_files.each { |stash_file| add_stash_file(stash_file) }
53
+ dcs_resource.creators.each { |dcs_creator| add_sd_creator(dcs_creator) }
54
+ dcs_resource.titles.each { |dcs_title| add_sd_title(dcs_title) }
55
+ set_sd_publisher(dcs_resource.publisher)
56
+ set_sd_pubyear(dcs_resource.publication_year)
57
+ dcs_resource.subjects.each { |dcs_subject| add_sd_subject(dcs_subject) }
58
+ dcs_resource.contributors.each { |dcs_contributor| add_sd_contributor(dcs_contributor) }
59
+ dcs_resource.dates.each { |dcs_date| add_sd_date(dcs_date) }
60
+ set_sd_language(dcs_resource.language)
61
+ set_sd_resource_type(dcs_resource.resource_type)
62
+ dcs_resource.alternate_identifiers.each { |dcs_alternate_ident| add_sd_alternate_ident(dcs_alternate_ident) }
63
+ dcs_resource.related_identifiers.each { |dcs_related_ident| add_sd_related_ident(dcs_related_ident) }
64
+ dcs_resource.sizes.each { |dcs_size| add_sd_size(dcs_size) }
65
+ dcs_resource.formats.each { |dcs_format| add_sd_format(dcs_format) }
66
+ set_sd_version(dcs_resource.version)
67
+ dcs_resource.rights_list.each { |dcs_rights| add_sd_rights(dcs_rights) }
68
+ dcs_resource.descriptions.each { |dcs_description| add_sd_description(dcs_description) }
69
+ dcs_resource.geo_locations.each { |dcs_geo_location| add_sd_geo_location(dcs_geo_location) }
70
+ dcs_resource.funding_references.each { |dcs_funding_reference| add_funding(dcs_funding_reference) }
71
+ se_resource.save!
72
+ se_resource
73
+ end
74
+
75
+ def set_sd_identifier(dcs_identifier)
76
+ return unless dcs_identifier
77
+ se_resource.identifier_id = StashEngine::Identifier.create(
78
+ identifier: dcs_identifier.value && dcs_identifier.value.strip,
79
+ identifier_type: dcs_identifier.identifier_type
80
+ ).id
81
+ end
82
+
83
+ def add_stash_file(stash_file)
84
+ StashEngine::FileUpload.create(
85
+ resource_id: se_resource_id,
86
+ upload_file_name: stash_file.pathname,
87
+ upload_content_type: stash_file.mime_type.to_s,
88
+ upload_file_size: stash_file.size_bytes,
89
+ upload_updated_at: upload_time,
90
+ file_state: 'created'
91
+ )
92
+ end
93
+
94
+ def add_sd_creator(dcs_creator)
95
+ last_name, first_name = extract_last_first(dcs_creator.name)
96
+ sd_creator = Creator.create(
97
+ creator_first_name: first_name,
98
+ creator_last_name: last_name,
99
+ name_identifier_id: sd_name_identifier_id_for(dcs_creator.identifier),
100
+ resource_id: se_resource_id
101
+ )
102
+ sd_creator.affiliation_ids = dcs_creator.affiliations.map { |affiliation_str| sd_affiliation_id_for(affiliation_str) }
103
+ sd_creator
104
+ end
105
+
106
+ def add_sd_title(dcs_title)
107
+ title_type = dcs_title.type
108
+ Title.create(
109
+ title: dcs_title.value && dcs_title.value.strip,
110
+ title_type_friendly: (title_type.value if title_type),
111
+ resource_id: se_resource_id
112
+ )
113
+ end
114
+
115
+ def set_sd_publisher(dcs_publisher)
116
+ Publisher.create(publisher: dcs_publisher, resource_id: se_resource_id) unless dcs_publisher.blank?
117
+ end
118
+
119
+ def set_sd_pubyear(dcs_publication_year)
120
+ return if dcs_publication_year.blank?
121
+ PublicationYear.create(publication_year: dcs_publication_year, resource_id: se_resource_id)
122
+ end
123
+
124
+ def add_sd_subject(dcs_subject)
125
+ sd_subject_id = sd_subject_id_for(dcs_subject)
126
+ ResourcesSubjects.create(resource_id: se_resource_id, subject_id: sd_subject_id)
127
+ end
128
+
129
+ def add_sd_contributor(dcs_contributor)
130
+ contributor_type = dcs_contributor.type
131
+ sd_contributor = Contributor.create(
132
+ contributor_name: dcs_contributor.name,
133
+ contributor_type_friendly: (contributor_type.value if contributor_type),
134
+ name_identifier_id: sd_name_identifier_id_for(dcs_contributor.identifier),
135
+ resource_id: se_resource_id
136
+ )
137
+ sd_contributor.affiliation_ids = dcs_contributor.affiliations.map { |affiliation_str| sd_affiliation_id_for(affiliation_str) }
138
+ sd_contributor
139
+ end
140
+
141
+ def add_sd_date(dcs_date)
142
+ date_type = dcs_date.type
143
+ DataciteDate.create(
144
+ date: dcs_date.value && dcs_date.value.strip,
145
+ date_type_friendly: (date_type.value if date_type),
146
+ resource_id: se_resource_id
147
+ )
148
+ end
149
+
150
+ def set_sd_language(dcs_language)
151
+ return nil if dcs_language.blank?
152
+ Language.create(language: dcs_language, resource_id: se_resource_id)
153
+ end
154
+
155
+ def set_sd_resource_type(dcs_resource_type)
156
+ return nil unless dcs_resource_type
157
+ dcs_resource_type_general = dcs_resource_type.resource_type_general
158
+ dcs_resource_type_value = dcs_resource_type.value
159
+ se_resource_type = dcs_resource_type_general.value.downcase
160
+ resource_type_friendly = (ResourceType::ResourceTypesGeneralLimited.values.include?(se_resource_type) ? se_resource_type : 'other')
161
+
162
+ ResourceType.create(
163
+ resource_id: se_resource_id,
164
+ resource_type_general: resource_type_friendly,
165
+ resource_type: dcs_resource_type_value
166
+ )
167
+
168
+ # resource_type_friendly = (ResourceType::ResourceTypesGeneralLimited.values.include?(se_resource_type) ? se_resource_type : 'other')
169
+ # ResourceType.create(
170
+ # resource_id: se_resource_id,
171
+ # resource_type_friendly: resource_type_friendly
172
+ # )
173
+ end
174
+
175
+ def add_sd_alternate_ident(dcs_alternate_ident)
176
+ AlternateIdentifier.create(
177
+ alternate_identifier: dcs_alternate_ident.value && dcs_alternate_ident.value.strip,
178
+ alternate_identifier_type: dcs_alternate_ident.type, # a string, not an enum
179
+ resource_id: se_resource_id
180
+ )
181
+ end
182
+
183
+ def add_sd_related_ident(dcs_related_ident)
184
+ ident_type = dcs_related_ident.identifier_type
185
+ rel_type = dcs_related_ident.relation_type
186
+ scheme_uri = dcs_related_ident.scheme_uri
187
+ RelatedIdentifier.create(
188
+ related_identifier: dcs_related_ident.value && dcs_related_ident.value.strip,
189
+ related_identifier_type_friendly: (ident_type.value if ident_type),
190
+ relation_type_friendly: (rel_type.value if rel_type),
191
+ related_metadata_scheme: dcs_related_ident.related_metadata_scheme,
192
+ scheme_URI: (scheme_uri.to_s if scheme_uri),
193
+ scheme_type: dcs_related_ident.scheme_type,
194
+ resource_id: se_resource_id
195
+ )
196
+ end
197
+
198
+ def add_sd_size(dcs_size)
199
+ return if dcs_size.blank?
200
+ Size.create(size: dcs_size, resource_id: se_resource_id)
201
+ end
202
+
203
+ def add_sd_format(dcs_format)
204
+ return if dcs_format.blank?
205
+ Format.create(format: dcs_format, resource_id: se_resource_id)
206
+ end
207
+
208
+ def set_sd_version(dcs_version)
209
+ return if dcs_version.blank?
210
+ Version.create(version: dcs_version, resource_id: se_resource_id)
211
+ end
212
+
213
+ def add_sd_rights(dcs_rights)
214
+ rights_uri = dcs_rights.uri
215
+ Right.create(
216
+ rights: dcs_rights.value && dcs_rights.value.strip,
217
+ rights_uri: (rights_uri.to_s if rights_uri),
218
+ resource_id: se_resource_id
219
+ )
220
+ end
221
+
222
+ def add_sd_description(dcs_description)
223
+ desc_type = dcs_description.type
224
+ if desc_type == DESCRIPTION_TYPE::OTHER && dcs_description.value.start_with?('Data were created with funding')
225
+ add_sd_award_number(dcs_description.value)
226
+ else
227
+ Description.create(
228
+ description: dcs_description.value && dcs_description.value.strip,
229
+ description_type_friendly: (desc_type.value if desc_type),
230
+ resource_id: se_resource_id
231
+ )
232
+ end
233
+ end
234
+
235
+ def add_sd_award_number(funding_desc_value)
236
+ pat = /Data were created with funding from(.*)under grant\(?s?\)?(.*)\.?/m
237
+ return unless (md = pat.match(funding_desc_value)) && md.size == 3
238
+
239
+ contrib_name = md[1].gsub(/\s+/m, ' ').strip
240
+ award_num = md[2].gsub(/\s+/m, ' ').sub(/.$/, '').strip
241
+
242
+ matching_contrib = find_sd_funder(contrib_name)
243
+ return unless matching_contrib
244
+
245
+ matching_contrib.award_number = award_num
246
+ matching_contrib.save!
247
+ end
248
+
249
+ def find_sd_funder(contrib_name)
250
+ se_resource.contributors.where(
251
+ "contributor_name LIKE ? and contributor_type='funder'",
252
+ "%#{contrib_name.sub(/^[Tt]he ?/, '')}%"
253
+ ).take
254
+ end
255
+
256
+ def add_sd_geo_location(dcs_geo_location)
257
+ return unless dcs_geo_location.location?
258
+ loc = Geolocation.create(resource_id: se_resource_id)
259
+ add_sd_geo_location_place(loc, dcs_geo_location.place)
260
+ add_sd_geo_location_point(loc, dcs_geo_location.point)
261
+ add_sd_geo_location_box(loc, dcs_geo_location.box)
262
+ loc.save
263
+ end
264
+
265
+ def add_sd_geo_location_place(se_geo_location, dcs_geo_location_place)
266
+ return if dcs_geo_location_place.blank?
267
+ se_place = GeolocationPlace.create(geo_location_place: dcs_geo_location_place)
268
+ se_geo_location.place_id = se_place.id
269
+ end
270
+
271
+ def add_sd_geo_location_point(se_geo_location, dcs_geo_location_point)
272
+ return unless dcs_geo_location_point
273
+ se_point = GeolocationPoint.create(
274
+ latitude: dcs_geo_location_point.latitude,
275
+ longitude: dcs_geo_location_point.longitude
276
+ )
277
+ se_geo_location.point_id = se_point.id
278
+ end
279
+
280
+ def add_sd_geo_location_box(se_geo_location, dcs_geo_location_box)
281
+ return unless dcs_geo_location_box
282
+ se_box = GeolocationBox.create(
283
+ sw_latitude: dcs_geo_location_box.south_latitude,
284
+ sw_longitude: dcs_geo_location_box.west_longitude,
285
+ ne_latitude: dcs_geo_location_box.north_latitude,
286
+ ne_longitude: dcs_geo_location_box.east_longitude
287
+ )
288
+ se_geo_location.box_id = se_box.id
289
+ end
290
+
291
+ def add_funding(dcs_funding_reference)
292
+ award_number = dcs_funding_reference.award_number
293
+ Contributor.create(
294
+ contributor_name: dcs_funding_reference.name,
295
+ contributor_type: Datacite::Mapping::ContributorType::FUNDER.value.downcase,
296
+ award_number: (award_number.value if award_number),
297
+ resource_id: se_resource_id
298
+ )
299
+ end
300
+
301
+ def extract_last_first(name_w_comma)
302
+ name_w_comma.split(',', 2).map(&:strip)
303
+ end
304
+
305
+ def sd_affiliation_id_for(affiliation_str)
306
+ sd_affiliations = StashDatacite::Affiliation.where('short_name = ? or long_name = ?', affiliation_str, affiliation_str)
307
+ return sd_affiliations.first.id unless sd_affiliations.empty?
308
+ StashDatacite::Affiliation.create(long_name: affiliation_str).id unless affiliation_str.blank?
309
+ end
310
+
311
+ def sd_name_identifier_id_for(dcs_name_identifier)
312
+ return nil unless dcs_name_identifier
313
+ scheme_uri = dcs_name_identifier.scheme_uri
314
+ value = dcs_name_identifier.value
315
+ sd_name_ident = StashDatacite::NameIdentifier.find_or_create_by(
316
+ name_identifier: value.to_s.strip,
317
+ name_identifier_scheme: dcs_name_identifier.scheme,
318
+ scheme_URI: (scheme_uri if scheme_uri)
319
+ )
320
+ sd_name_ident.id
321
+ end
322
+
323
+ def sd_subject_id_for(dcs_subject)
324
+ return nil unless dcs_subject
325
+ scheme_uri = dcs_subject.scheme_uri
326
+ StashDatacite::Subject.find_or_create_by(
327
+ subject: dcs_subject.value && dcs_subject.value.strip,
328
+ subject_scheme: dcs_subject.scheme,
329
+ scheme_URI: (scheme_uri if scheme_uri)
330
+ ).id
331
+ end
332
+ end
333
+ end
@@ -0,0 +1,48 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ require 'stash/merritt/module_info'
6
+ require 'uri'
7
+
8
+ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
9
+ spec.name = Stash::Merritt::NAME
10
+ spec.version = Stash::Merritt::VERSION
11
+ spec.authors = ['David Moles']
12
+ spec.email = ['david.moles@ucop.edu']
13
+ spec.summary = 'Merritt integration for Stash'
14
+ spec.description = 'Packaging and SWORD deposit module for submitting Stash datasets to Merritt'
15
+ spec.license = 'MIT'
16
+
17
+ origin = `git config --get remote.origin.url`.chomp
18
+ origin_uri = origin.start_with?('http') ? URI(origin) : URI(origin.gsub(%r{git@([^:]+)(.com|.org)[^\/]+}, 'http://\1\2'))
19
+ spec.homepage = URI::HTTP.build(host: origin_uri.host, path: origin_uri.path.chomp('.git')).to_s
20
+
21
+ spec.files = `git ls-files -z`.split("\x0")
22
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
23
+
24
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
25
+ spec.require_paths = ['lib']
26
+
27
+ spec.add_dependency 'rubyzip', '~> 1.1'
28
+
29
+ spec.add_dependency 'stash_ezid_datacite', '~> 0.1' # TODO: fold this in
30
+
31
+ spec.add_dependency 'stash_datacite'
32
+ spec.add_dependency 'stash_engine' # TODO: should stash_datacite export this?
33
+
34
+ spec.add_development_dependency 'bundler', '~> 1.7'
35
+ spec.add_development_dependency 'rake', '~> 10.4'
36
+ spec.add_development_dependency 'rspec', '~> 3.2'
37
+ spec.add_development_dependency 'simplecov', '~> 0.9.2'
38
+ spec.add_development_dependency 'simplecov-console', '~> 0.2.0'
39
+ spec.add_development_dependency 'rubocop', '~> 0.47'
40
+ spec.add_development_dependency 'yard', '~> 0.8'
41
+
42
+ spec.add_development_dependency 'database_cleaner', '~> 1.5'
43
+ spec.add_development_dependency 'diffy', '~> 3.1'
44
+ spec.add_development_dependency 'equivalent-xml', '~> 0.6.0'
45
+ spec.add_development_dependency 'mysql2', '~> 0.3'
46
+ spec.add_development_dependency 'webmock', '~> 1.24'
47
+
48
+ end
data/stash-merritt.iml ADDED
@@ -0,0 +1,147 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="RUBY_MODULE" version="4">
3
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
4
+ <exclude-output />
5
+ <content url="file://$MODULE_DIR$" />
6
+ <content url="file://$MODULE_DIR$/../stash_engines/stash_engine" />
7
+ <orderEntry type="jdk" jdkName="ruby-2.2.5-p319" jdkType="RUBY_SDK" />
8
+ <orderEntry type="sourceFolder" forTests="false" />
9
+ <orderEntry type="module-library">
10
+ <library name="stash_datacite (v0.0.5) [path][gem]">
11
+ <CLASSES>
12
+ <root url="file://$MODULE_DIR$/../stash_engines/stash_datacite/db" />
13
+ <root url="file://$MODULE_DIR$/../stash_engines/stash_datacite/app" />
14
+ <root url="file://$MODULE_DIR$/../stash_engines/stash_datacite/bin" />
15
+ <root url="file://$MODULE_DIR$/../stash_engines/stash_datacite/lib" />
16
+ <root url="file://$MODULE_DIR$/../stash_engines/stash_datacite/tmp" />
17
+ <root url="file://$MODULE_DIR$/../stash_engines/stash_datacite/config" />
18
+ <root url="file://$MODULE_DIR$/../stash_engines/stash_datacite/coverage" />
19
+ </CLASSES>
20
+ <JAVADOC />
21
+ <SOURCES>
22
+ <root url="file://$MODULE_DIR$/../stash_engines/stash_datacite/db" />
23
+ <root url="file://$MODULE_DIR$/../stash_engines/stash_datacite/app" />
24
+ <root url="file://$MODULE_DIR$/../stash_engines/stash_datacite/bin" />
25
+ <root url="file://$MODULE_DIR$/../stash_engines/stash_datacite/lib" />
26
+ <root url="file://$MODULE_DIR$/../stash_engines/stash_datacite/tmp" />
27
+ <root url="file://$MODULE_DIR$/../stash_engines/stash_datacite/config" />
28
+ <root url="file://$MODULE_DIR$/../stash_engines/stash_datacite/coverage" />
29
+ </SOURCES>
30
+ </library>
31
+ </orderEntry>
32
+ <orderEntry type="library" scope="PROVIDED" name="actionmailer (v4.2.7.1, ruby-2.2.5-p319) [gem]" level="application" />
33
+ <orderEntry type="library" scope="PROVIDED" name="actionpack (v4.2.7.1, ruby-2.2.5-p319) [gem]" level="application" />
34
+ <orderEntry type="library" scope="PROVIDED" name="actionview (v4.2.7.1, ruby-2.2.5-p319) [gem]" level="application" />
35
+ <orderEntry type="library" scope="PROVIDED" name="activejob (v4.2.7.1, ruby-2.2.5-p319) [gem]" level="application" />
36
+ <orderEntry type="library" scope="PROVIDED" name="activemodel (v4.2.7.1, ruby-2.2.5-p319) [gem]" level="application" />
37
+ <orderEntry type="library" scope="PROVIDED" name="activerecord (v4.2.7.1, ruby-2.2.5-p319) [gem]" level="application" />
38
+ <orderEntry type="library" scope="PROVIDED" name="activesupport (v4.2.7.1, ruby-2.2.5-p319) [gem]" level="application" />
39
+ <orderEntry type="library" scope="PROVIDED" name="addressable (v2.5.0, ruby-2.2.5-p319) [gem]" level="application" />
40
+ <orderEntry type="library" scope="PROVIDED" name="amoeba (v3.0.0, ruby-2.2.5-p319) [gem]" level="application" />
41
+ <orderEntry type="library" scope="PROVIDED" name="arel (v6.0.4, ruby-2.2.5-p319) [gem]" level="application" />
42
+ <orderEntry type="library" scope="PROVIDED" name="ast (v2.3.0, ruby-2.2.5-p319) [gem]" level="application" />
43
+ <orderEntry type="library" scope="PROVIDED" name="builder (v3.2.3, ruby-2.2.5-p319) [gem]" level="application" />
44
+ <orderEntry type="library" scope="PROVIDED" name="carrierwave (v0.10.0, ruby-2.2.5-p319) [gem]" level="application" />
45
+ <orderEntry type="library" scope="PROVIDED" name="colorize (v0.8.1, ruby-2.2.5-p319) [gem]" level="application" />
46
+ <orderEntry type="library" scope="PROVIDED" name="concurrent-ruby (v1.0.4, ruby-2.2.5-p319) [gem]" level="application" />
47
+ <orderEntry type="library" scope="PROVIDED" name="crack (v0.4.3, ruby-2.2.5-p319) [gem]" level="application" />
48
+ <orderEntry type="library" scope="PROVIDED" name="database_cleaner (v1.5.3, ruby-2.2.5-p319) [gem]" level="application" />
49
+ <orderEntry type="library" scope="PROVIDED" name="datacite-mapping (v0.2.5, ruby-2.2.5-p319) [gem]" level="application" />
50
+ <orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.3, ruby-2.2.5-p319) [gem]" level="application" />
51
+ <orderEntry type="library" scope="PROVIDED" name="diffy (v3.1.0, ruby-2.2.5-p319) [gem]" level="application" />
52
+ <orderEntry type="library" scope="PROVIDED" name="docile (v1.1.5, ruby-2.2.5-p319) [gem]" level="application" />
53
+ <orderEntry type="library" scope="PROVIDED" name="domain_name (v0.5.20161129, ruby-2.2.5-p319) [gem]" level="application" />
54
+ <orderEntry type="library" scope="PROVIDED" name="equivalent-xml (v0.6.0, ruby-2.2.5-p319) [gem]" level="application" />
55
+ <orderEntry type="library" scope="PROVIDED" name="erubis (v2.7.0, ruby-2.2.5-p319) [gem]" level="application" />
56
+ <orderEntry type="library" scope="PROVIDED" name="ezid-client (v1.5.0, ruby-2.2.5-p319) [gem]" level="application" />
57
+ <orderEntry type="library" scope="PROVIDED" name="faraday (v0.10.1, ruby-2.2.5-p319) [gem]" level="application" />
58
+ <orderEntry type="library" scope="PROVIDED" name="filesize (v0.1.1, ruby-2.2.5-p319) [gem]" level="application" />
59
+ <orderEntry type="library" scope="PROVIDED" name="font-awesome-rails (v4.7.0.1, ruby-2.2.5-p319) [gem]" level="application" />
60
+ <orderEntry type="library" scope="PROVIDED" name="globalid (v0.3.7, ruby-2.2.5-p319) [gem]" level="application" />
61
+ <orderEntry type="library" scope="PROVIDED" name="hashdiff (v0.3.2, ruby-2.2.5-p319) [gem]" level="application" />
62
+ <orderEntry type="library" scope="PROVIDED" name="hashie (v3.5.1, ruby-2.2.5-p319) [gem]" level="application" />
63
+ <orderEntry type="library" scope="PROVIDED" name="hirb (v0.7.3, ruby-2.2.5-p319) [gem]" level="application" />
64
+ <orderEntry type="library" scope="PROVIDED" name="http-cookie (v1.0.3, ruby-2.2.5-p319) [gem]" level="application" />
65
+ <orderEntry type="library" scope="PROVIDED" name="i18n (v0.8.0, ruby-2.2.5-p319) [gem]" level="application" />
66
+ <orderEntry type="library" scope="PROVIDED" name="jquery-fileupload-rails (v0.4.7, ruby-2.2.5-p319) [gem]" level="application" />
67
+ <orderEntry type="library" scope="PROVIDED" name="jquery-rails (v4.2.2, ruby-2.2.5-p319) [gem]" level="application" />
68
+ <orderEntry type="library" scope="PROVIDED" name="jquery-turbolinks (v2.1.0, ruby-2.2.5-p319) [gem]" level="application" />
69
+ <orderEntry type="library" scope="PROVIDED" name="jquery-ui-rails (v6.0.1, ruby-2.2.5-p319) [gem]" level="application" />
70
+ <orderEntry type="library" scope="PROVIDED" name="json (v1.8.6, ruby-2.2.5-p319) [gem]" level="application" />
71
+ <orderEntry type="library" scope="PROVIDED" name="jwt (v1.5.6, ruby-2.2.5-p319) [gem]" level="application" />
72
+ <orderEntry type="library" scope="PROVIDED" name="kaminari (v1.0.1, ruby-2.2.5-p319) [gem]" level="application" />
73
+ <orderEntry type="library" scope="PROVIDED" name="kaminari-actionview (v1.0.1, ruby-2.2.5-p319) [gem]" level="application" />
74
+ <orderEntry type="library" scope="PROVIDED" name="kaminari-activerecord (v1.0.1, ruby-2.2.5-p319) [gem]" level="application" />
75
+ <orderEntry type="library" scope="PROVIDED" name="kaminari-core (v1.0.1, ruby-2.2.5-p319) [gem]" level="application" />
76
+ <orderEntry type="library" scope="PROVIDED" name="leaflet-rails (v1.0.2, ruby-2.2.5-p319) [gem]" level="application" />
77
+ <orderEntry type="library" scope="PROVIDED" name="loofah (v2.0.3, ruby-2.2.5-p319) [gem]" level="application" />
78
+ <orderEntry type="library" scope="PROVIDED" name="mail (v2.6.4, ruby-2.2.5-p319) [gem]" level="application" />
79
+ <orderEntry type="library" scope="PROVIDED" name="mime-types (v2.99.3, ruby-2.2.5-p319) [gem]" level="application" />
80
+ <orderEntry type="library" scope="PROVIDED" name="mini_portile2 (v2.1.0, ruby-2.2.5-p319) [gem]" level="application" />
81
+ <orderEntry type="library" scope="PROVIDED" name="minitest (v5.10.1, ruby-2.2.5-p319) [gem]" level="application" />
82
+ <orderEntry type="library" scope="PROVIDED" name="multi_json (v1.12.1, ruby-2.2.5-p319) [gem]" level="application" />
83
+ <orderEntry type="library" scope="PROVIDED" name="multi_xml (v0.6.0, ruby-2.2.5-p319) [gem]" level="application" />
84
+ <orderEntry type="library" scope="PROVIDED" name="multipart-post (v2.0.0, ruby-2.2.5-p319) [gem]" level="application" />
85
+ <orderEntry type="library" scope="PROVIDED" name="mysql2 (v0.4.5, ruby-2.2.5-p319) [gem]" level="application" />
86
+ <orderEntry type="library" scope="PROVIDED" name="netrc (v0.11.0, ruby-2.2.5-p319) [gem]" level="application" />
87
+ <orderEntry type="library" scope="PROVIDED" name="nokogiri (v1.7.0.1, ruby-2.2.5-p319) [gem]" level="application" />
88
+ <orderEntry type="library" scope="PROVIDED" name="oauth2 (v1.3.0, ruby-2.2.5-p319) [gem]" level="application" />
89
+ <orderEntry type="library" scope="PROVIDED" name="omniauth (v1.2.2, ruby-2.2.5-p319) [gem]" level="application" />
90
+ <orderEntry type="library" scope="PROVIDED" name="omniauth-google-oauth2 (v0.2.10, ruby-2.2.5-p319) [gem]" level="application" />
91
+ <orderEntry type="library" scope="PROVIDED" name="omniauth-oauth2 (v1.3.1, ruby-2.2.5-p319) [gem]" level="application" />
92
+ <orderEntry type="library" scope="PROVIDED" name="omniauth-orcid (v1.0.38, ruby-2.2.5-p319) [gem]" level="application" />
93
+ <orderEntry type="library" scope="PROVIDED" name="omniauth-shibboleth (v1.2.1, ruby-2.2.5-p319) [gem]" level="application" />
94
+ <orderEntry type="library" scope="PROVIDED" name="parser (v2.3.3.1, ruby-2.2.5-p319) [gem]" level="application" />
95
+ <orderEntry type="library" scope="PROVIDED" name="powerpack (v0.1.1, ruby-2.2.5-p319) [gem]" level="application" />
96
+ <orderEntry type="library" scope="PROVIDED" name="public_suffix (v2.0.5, ruby-2.2.5-p319) [gem]" level="application" />
97
+ <orderEntry type="library" scope="PROVIDED" name="rack (v1.6.5, ruby-2.2.5-p319) [gem]" level="application" />
98
+ <orderEntry type="library" scope="PROVIDED" name="rack-test (v0.6.3, ruby-2.2.5-p319) [gem]" level="application" />
99
+ <orderEntry type="library" scope="PROVIDED" name="rails (v4.2.7.1, ruby-2.2.5-p319) [gem]" level="application" />
100
+ <orderEntry type="library" scope="PROVIDED" name="rails-deprecated_sanitizer (v1.0.3, ruby-2.2.5-p319) [gem]" level="application" />
101
+ <orderEntry type="library" scope="PROVIDED" name="rails-dom-testing (v1.0.8, ruby-2.2.5-p319) [gem]" level="application" />
102
+ <orderEntry type="library" scope="PROVIDED" name="rails-html-sanitizer (v1.0.3, ruby-2.2.5-p319) [gem]" level="application" />
103
+ <orderEntry type="library" scope="PROVIDED" name="railties (v4.2.7.1, ruby-2.2.5-p319) [gem]" level="application" />
104
+ <orderEntry type="library" scope="PROVIDED" name="rainbow (v2.2.1, ruby-2.2.5-p319) [gem]" level="application" />
105
+ <orderEntry type="library" scope="PROVIDED" name="rake (v10.5.0, ruby-2.2.5-p319) [gem]" level="application" />
106
+ <orderEntry type="library" scope="PROVIDED" name="redcarpet (v3.4.0, ruby-2.2.5-p319) [gem]" level="application" />
107
+ <orderEntry type="library" scope="PROVIDED" name="responders (v2.3.0, ruby-2.2.5-p319) [gem]" level="application" />
108
+ <orderEntry type="library" scope="PROVIDED" name="rest-client (v2.0.0, ruby-2.2.5-p319) [gem]" level="application" />
109
+ <orderEntry type="library" scope="PROVIDED" name="rspec (v3.5.0, ruby-2.2.5-p319) [gem]" level="application" />
110
+ <orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.5.4, ruby-2.2.5-p319) [gem]" level="application" />
111
+ <orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.5.0, ruby-2.2.5-p319) [gem]" level="application" />
112
+ <orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.5.0, ruby-2.2.5-p319) [gem]" level="application" />
113
+ <orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.5.0, ruby-2.2.5-p319) [gem]" level="application" />
114
+ <orderEntry type="library" scope="PROVIDED" name="rubocop (v0.47.1, ruby-2.2.5-p319) [gem]" level="application" />
115
+ <orderEntry type="library" scope="PROVIDED" name="ruby-progressbar (v1.8.1, ruby-2.2.5-p319) [gem]" level="application" />
116
+ <orderEntry type="library" scope="PROVIDED" name="rubyzip (v1.2.0, ruby-2.2.5-p319) [gem]" level="application" />
117
+ <orderEntry type="library" scope="PROVIDED" name="safe_yaml (v1.0.4, ruby-2.2.5-p319) [gem]" level="application" />
118
+ <orderEntry type="library" scope="PROVIDED" name="sass (v3.4.23, ruby-2.2.5-p319) [gem]" level="application" />
119
+ <orderEntry type="library" scope="PROVIDED" name="simplecov (v0.9.2, ruby-2.2.5-p319) [gem]" level="application" />
120
+ <orderEntry type="library" scope="PROVIDED" name="simplecov-console (v0.2.0, ruby-2.2.5-p319) [gem]" level="application" />
121
+ <orderEntry type="library" scope="PROVIDED" name="simplecov-html (v0.9.0, ruby-2.2.5-p319) [gem]" level="application" />
122
+ <orderEntry type="library" scope="PROVIDED" name="sprockets (v3.7.1, ruby-2.2.5-p319) [gem]" level="application" />
123
+ <orderEntry type="library" scope="PROVIDED" name="sprockets-rails (v3.2.0, ruby-2.2.5-p319) [gem]" level="application" />
124
+ <orderEntry type="library" scope="PROVIDED" name="stash-sword (v0.1.5, ruby-2.2.5-p319) [gem]" level="application" />
125
+ <orderEntry type="library" scope="PROVIDED" name="stash-wrapper (v0.1.11.1, ruby-2.2.5-p319) [gem]" level="application" />
126
+ <orderEntry type="library" scope="PROVIDED" name="stash_ezid_datacite (v0.1.5, ruby-2.2.5-p319) [gem]" level="application" />
127
+ <orderEntry type="library" scope="PROVIDED" name="thor (v0.19.4, ruby-2.2.5-p319) [gem]" level="application" />
128
+ <orderEntry type="library" scope="PROVIDED" name="thread_safe (v0.3.5, ruby-2.2.5-p319) [gem]" level="application" />
129
+ <orderEntry type="library" scope="PROVIDED" name="turbolinks (v5.0.1, ruby-2.2.5-p319) [gem]" level="application" />
130
+ <orderEntry type="library" scope="PROVIDED" name="turbolinks-source (v5.0.0, ruby-2.2.5-p319) [gem]" level="application" />
131
+ <orderEntry type="library" scope="PROVIDED" name="typesafe_enum (v0.1.7, ruby-2.2.5-p319) [gem]" level="application" />
132
+ <orderEntry type="library" scope="PROVIDED" name="tzinfo (v1.2.2, ruby-2.2.5-p319) [gem]" level="application" />
133
+ <orderEntry type="library" scope="PROVIDED" name="unf (v0.1.4, ruby-2.2.5-p319) [gem]" level="application" />
134
+ <orderEntry type="library" scope="PROVIDED" name="unf_ext (v0.0.7.2, ruby-2.2.5-p319) [gem]" level="application" />
135
+ <orderEntry type="library" scope="PROVIDED" name="unicode-display_width (v1.1.3, ruby-2.2.5-p319) [gem]" level="application" />
136
+ <orderEntry type="library" scope="PROVIDED" name="webmock (v1.24.6, ruby-2.2.5-p319) [gem]" level="application" />
137
+ <orderEntry type="library" scope="PROVIDED" name="wicked_pdf (v1.1.0, ruby-2.2.5-p319) [gem]" level="application" />
138
+ <orderEntry type="library" scope="PROVIDED" name="wkhtmltopdf-binary (v0.12.3.1, ruby-2.2.5-p319) [gem]" level="application" />
139
+ <orderEntry type="library" scope="PROVIDED" name="xml-mapping (v0.10.0, ruby-2.2.5-p319) [gem]" level="application" />
140
+ <orderEntry type="library" scope="PROVIDED" name="xml-mapping_extensions (v0.4.7, ruby-2.2.5-p319) [gem]" level="application" />
141
+ <orderEntry type="library" scope="PROVIDED" name="yard (v0.9.8, ruby-2.2.5-p319) [gem]" level="application" />
142
+ </component>
143
+ <component name="RModuleSettingsStorage">
144
+ <LOAD_PATH number="2" string0="$MODULE_DIR$/lib" string1="$MODULE_DIR$/spec" />
145
+ <I18N_FOLDERS number="0" />
146
+ </component>
147
+ </module>