stash-merritt 0.0.1

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.
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>