hydra-head 4.0.0.rc2 → 4.0.0.rc3
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.
- data/Gemfile +8 -1
- data/Gemfile.lock +46 -46
- data/HISTORY.textile +2 -0
- data/app/controllers/hydra/application_controller.rb +5 -0
- data/app/controllers/hydra/contributors_controller.rb +2 -1
- data/app/controllers/hydra/permissions_controller.rb +2 -2
- data/app/helpers/hydra/hydra_assets_helper_behavior.rb +4 -3
- data/app/models/ability.rb +97 -0
- data/app/models/common_metadata_asset.rb +2 -2
- data/app/models/generic_content.rb +2 -4
- data/app/models/generic_image.rb +3 -3
- data/app/models/hydra/datastream/common_mods_index_methods.rb +45 -0
- data/app/models/hydra/datastream/mods_article.rb +528 -0
- data/app/models/hydra/datastream/mods_dataset.rb +166 -0
- data/app/models/hydra/datastream/mods_generic_content.rb +496 -0
- data/app/models/hydra/datastream/mods_image.rb +496 -0
- data/app/models/hydra/datastream/rights_metadata.rb +190 -0
- data/app/models/mods_asset.rb +4 -4
- data/app/models/uses_default_partials.rb +2 -2
- data/app/views/catalog/_edit_partials/_default.html.erb +1 -1
- data/app/views/catalog/show.html.erb +1 -1
- data/app/views/contributors/_edit_conference.html.erb +1 -1
- data/app/views/contributors/_edit_organization.html.erb +1 -1
- data/app/views/contributors/_edit_person.html.erb +1 -1
- data/app/views/contributors/_show_organization.html.erb +1 -1
- data/app/views/hydra/file_assets/_index.html.erb +1 -1
- data/app/views/hydra/file_assets/_result.html.erb +1 -1
- data/app/views/hydra/permissions/index.html.erb +1 -1
- data/app/views/hydra/permissions/new.html.erb +1 -1
- data/app/views/mods_assets/_show_permissions.html.erb +1 -1
- data/hydra-head.gemspec +4 -6
- data/lib/hydra/access_controls_enforcement.rb +10 -6
- data/lib/hydra/access_controls_evaluation.rb +7 -71
- data/lib/hydra/assets.rb +1 -4
- data/lib/hydra/common_mods_index_methods.rb +5 -0
- data/lib/hydra/controller.rb +4 -7
- data/lib/hydra/file_assets.rb +3 -8
- data/lib/hydra/model_methods.rb +3 -2
- data/lib/hydra/model_mixins/common_metadata.rb +2 -2
- data/lib/hydra/model_mixins/mods_object.rb +3 -3
- data/lib/hydra/models/file_asset.rb +3 -3
- data/lib/hydra/mods_article.rb +7 -1
- data/lib/hydra/mods_dataset.rb +8 -0
- data/lib/hydra/mods_generic_content.rb +5 -0
- data/lib/hydra/mods_image.rb +5 -0
- data/lib/hydra/repository_controller.rb +14 -15
- data/lib/hydra/rights_metadata.rb +5 -1
- data/lib/hydra/submission_workflow.rb +1 -1
- data/lib/hydra-head/version.rb +1 -1
- data/lib/hydra.rb +1 -0
- data/lib/mediashelf/active_fedora_helper.rb +71 -0
- data/lib/uva/mods_index_methods.rb +5 -0
- data/test_support/etc/Gemfile +3 -2
- data/test_support/spec/controllers/catalog_controller_viewing_context_spec.rb +5 -7
- data/test_support/spec/controllers/file_assets_controller_spec.rb +3 -14
- data/test_support/spec/controllers/hydra-assets_controller_spec.rb +2 -2
- data/test_support/spec/helpers/access_controls_enforcement_spec.rb +14 -0
- data/test_support/spec/helpers/access_controls_evaluation_spec.rb +7 -16
- data/test_support/spec/helpers/hydra-repository_controller_spec.rb +0 -14
- data/test_support/spec/helpers/hydra_assets_helper_spec.rb +11 -11
- data/test_support/spec/helpers/hydra_model_methods_spec.rb +2 -2
- data/test_support/spec/integration/file_asset_spec.rb +0 -1
- data/test_support/spec/lib/common_mods_index_methods_spec.rb +1 -1
- data/test_support/spec/lib/hydra_submission_workflow_spec.rb +1 -1
- data/test_support/spec/models/ability_spec.rb +16 -0
- data/test_support/spec/models/file_asset_spec.rb +0 -1
- data/test_support/spec/models/hydra_rights_metadata_spec.rb +4 -5
- data/test_support/spec/models/mods_asset_spec.rb +2 -11
- data/vendor/cache/{active-fedora-4.0.0.rc13.gem → active-fedora-4.0.0.rc18.gem} +0 -0
- data/vendor/cache/blacklight-3.3.1.gem +0 -0
- data/vendor/cache/cancan-1.6.7.gem +0 -0
- data/vendor/cache/compass-0.12.1.gem +0 -0
- data/vendor/cache/compass-rails-1.0.1.gem +0 -0
- data/vendor/cache/compass-susy-plugin-0.9.gem +0 -0
- data/vendor/cache/factory_girl-2.6.4.gem +0 -0
- data/vendor/cache/gherkin-2.9.1.gem +0 -0
- data/vendor/cache/mail-2.4.4.gem +0 -0
- data/vendor/cache/nokogiri-1.5.2.gem +0 -0
- data/vendor/cache/om-1.6.0.rc3.gem +0 -0
- data/vendor/cache/orm_adapter-0.0.7.gem +0 -0
- data/vendor/cache/rack-cache-1.2.gem +0 -0
- data/vendor/cache/rspec-2.9.0.gem +0 -0
- data/vendor/cache/rspec-core-2.9.0.gem +0 -0
- data/vendor/cache/rspec-expectations-2.9.0.gem +0 -0
- data/vendor/cache/rspec-mocks-2.9.0.gem +0 -0
- data/vendor/cache/rspec-rails-2.9.0.gem +0 -0
- data/vendor/cache/sass-rails-3.2.5.gem +0 -0
- data/vendor/cache/stomp-1.2.2.gem +0 -0
- metadata +71 -59
- data/lib/hydra/image.rb +0 -178
- data/uninstall.rb +0 -1
- data/vendor/cache/compass-0.12.rc.1.gem +0 -0
- data/vendor/cache/factory_girl-2.6.1.gem +0 -0
- data/vendor/cache/gherkin-2.9.0.gem +0 -0
- data/vendor/cache/mail-2.4.3.gem +0 -0
- data/vendor/cache/nokogiri-1.5.0.gem +0 -0
- data/vendor/cache/om-1.5.3.gem +0 -0
- data/vendor/cache/orm_adapter-0.0.6.gem +0 -0
- data/vendor/cache/rack-cache-1.1.gem +0 -0
- data/vendor/cache/rspec-2.6.0.gem +0 -0
- data/vendor/cache/rspec-core-2.6.4.gem +0 -0
- data/vendor/cache/rspec-expectations-2.6.0.gem +0 -0
- data/vendor/cache/rspec-mocks-2.6.0.gem +0 -0
- data/vendor/cache/rspec-rails-2.6.1.gem +0 -0
- data/vendor/cache/sass-rails-3.2.4.gem +0 -0
- data/vendor/cache/stomp-1.2.1.gem +0 -0
@@ -0,0 +1,496 @@
|
|
1
|
+
module Hydra
|
2
|
+
module Datastream
|
3
|
+
class ModsImage < ActiveFedora::NokogiriDatastream
|
4
|
+
include Hydra::Datastream::CommonModsIndexMethods
|
5
|
+
|
6
|
+
set_terminology do |t|
|
7
|
+
t.root(:path=>"mods", :xmlns=>"http://www.loc.gov/mods/v3", :schema=>"http://www.loc.gov/standards/mods/v3/mods-3-2.xsd")
|
8
|
+
|
9
|
+
t.title_info(:path=>"titleInfo") {
|
10
|
+
t.main_title(:path=>"title", :label=>"title")
|
11
|
+
t.language(:index_as=>[:facetable],:path=>{:attribute=>"lang"})
|
12
|
+
}
|
13
|
+
|
14
|
+
t.language{
|
15
|
+
t.lang_code(:index_as=>[:facetable], :path=>"languageTerm", :attributes=>{:type=>"code"})
|
16
|
+
}
|
17
|
+
t.abstract
|
18
|
+
t.subject {
|
19
|
+
t.topic
|
20
|
+
}
|
21
|
+
t.topic_tag(:index_as=>[:facetable],:path=>"subject", :default_content_path=>"topic")
|
22
|
+
|
23
|
+
# mods:physicaldescription/mods:extent - used for storing file size in human-readable form.
|
24
|
+
t.physical_description(:path => "physicalDescription") {
|
25
|
+
t.extent( :path => "extent" )
|
26
|
+
}
|
27
|
+
|
28
|
+
# This is a mods:name. The underscore is purely to avoid namespace conflicts.
|
29
|
+
t.name_ {
|
30
|
+
# this is a namepart
|
31
|
+
t.namePart(:type=>:string, :label=>"generic name")
|
32
|
+
# affiliations are great
|
33
|
+
t.affiliation
|
34
|
+
t.institution(:path=>"affiliation", :index_as=>[:facetable], :label=>"organization")
|
35
|
+
t.displayForm
|
36
|
+
t.role(:ref=>[:role])
|
37
|
+
t.description
|
38
|
+
t.date(:path=>"namePart", :attributes=>{:type=>"date"})
|
39
|
+
t.last_name(:path=>"namePart", :attributes=>{:type=>"family"})
|
40
|
+
t.first_name(:path=>"namePart", :attributes=>{:type=>"given"}, :label=>"first name")
|
41
|
+
t.terms_of_address(:path=>"namePart", :attributes=>{:type=>"termsOfAddress"})
|
42
|
+
}
|
43
|
+
# lookup :person, :first_name
|
44
|
+
t.person(:ref=>:name, :attributes=>{:type=>"personal"}, :index_as=>[:facetable])
|
45
|
+
t.organization(:ref=>:name, :attributes=>{:type=>"corporate"}, :index_as=>[:facetable])
|
46
|
+
t.conference(:ref=>:name, :attributes=>{:type=>"conference"}, :index_as=>[:facetable])
|
47
|
+
t.role {
|
48
|
+
t.text(:path=>"roleTerm",:attributes=>{:type=>"text"})
|
49
|
+
t.code(:path=>"roleTerm",:attributes=>{:type=>"code"})
|
50
|
+
}
|
51
|
+
t.journal(:path=>'relatedItem', :attributes=>{:type=>"host"}) {
|
52
|
+
t.title_info(:index_as=>[:facetable],:ref=>[:title_info])
|
53
|
+
t.origin_info(:path=>"originInfo") {
|
54
|
+
t.publisher
|
55
|
+
t.date_issued(:path=>"dateIssued")
|
56
|
+
}
|
57
|
+
t.issn(:path=>"identifier", :attributes=>{:type=>"issn"})
|
58
|
+
t.issue(:path=>"part") {
|
59
|
+
t.volume(:path=>"detail", :attributes=>{:type=>"volume"}, :default_content_path=>"number")
|
60
|
+
t.level(:path=>"detail", :attributes=>{:type=>"number"}, :default_content_path=>"number")
|
61
|
+
t.extent
|
62
|
+
t.pages(:path=>"extent", :attributes=>{:unit=>"pages"}) {
|
63
|
+
t.start
|
64
|
+
t.end
|
65
|
+
}
|
66
|
+
t.start_page(:proxy=>[:pages, :start])
|
67
|
+
t.end_page(:proxy=>[:pages, :end])
|
68
|
+
t.publication_date(:path=>"date")
|
69
|
+
}
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
# accessor :title, :term=>[:mods, :title_info, :main_title]
|
74
|
+
|
75
|
+
# Generates an empty Mods Image (used when you call ModsImage.new without passing in existing xml)
|
76
|
+
def self.xml_template
|
77
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
78
|
+
xml.mods(:version=>"3.3", "xmlns:xlink"=>"http://www.w3.org/1999/xlink",
|
79
|
+
"xmlns:xsi"=>"http://www.w3.org/2001/XMLSchema-instance",
|
80
|
+
"xmlns"=>"http://www.loc.gov/mods/v3",
|
81
|
+
"xsi:schemaLocation"=>"http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-3.xsd") {
|
82
|
+
xml.titleInfo(:lang=>"") {
|
83
|
+
xml.title
|
84
|
+
}
|
85
|
+
xml.name(:type=>"personal") {
|
86
|
+
xml.namePart(:type=>"given")
|
87
|
+
xml.namePart(:type=>"family")
|
88
|
+
xml.affiliation
|
89
|
+
xml.role {
|
90
|
+
xml.roleTerm(:authority=>"marcrelator", :type=>"text")
|
91
|
+
}
|
92
|
+
}
|
93
|
+
xml.typeOfResource
|
94
|
+
xml.genre(:authority=>"marcgt")
|
95
|
+
xml.language {
|
96
|
+
xml.languageTerm(:authority=>"iso639-2b", :type=>"code")
|
97
|
+
}
|
98
|
+
# mods:physicaldescription/mods:extent - used for storing file size in human-readable form.
|
99
|
+
xml.physicalDescription {
|
100
|
+
xml.extent
|
101
|
+
}
|
102
|
+
xml.abstract
|
103
|
+
xml.subject {
|
104
|
+
xml.topic
|
105
|
+
}
|
106
|
+
xml.relatedItem(:type=>"host") {
|
107
|
+
xml.titleInfo {
|
108
|
+
xml.title
|
109
|
+
}
|
110
|
+
xml.identifier(:type=>"issn")
|
111
|
+
xml.originInfo {
|
112
|
+
xml.publisher
|
113
|
+
xml.dateIssued
|
114
|
+
}
|
115
|
+
xml.part {
|
116
|
+
xml.detail(:type=>"volume") {
|
117
|
+
xml.number
|
118
|
+
}
|
119
|
+
xml.detail(:type=>"number") {
|
120
|
+
xml.number
|
121
|
+
}
|
122
|
+
xml.extent(:unit=>"pages") {
|
123
|
+
xml.start
|
124
|
+
xml.end
|
125
|
+
}
|
126
|
+
xml.date
|
127
|
+
}
|
128
|
+
}
|
129
|
+
xml.location {
|
130
|
+
xml.url
|
131
|
+
}
|
132
|
+
}
|
133
|
+
end
|
134
|
+
return builder.doc
|
135
|
+
end
|
136
|
+
|
137
|
+
# Generates a new Person node
|
138
|
+
def self.person_template
|
139
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
140
|
+
xml.name(:type=>"personal") {
|
141
|
+
xml.namePart(:type=>"family")
|
142
|
+
xml.namePart(:type=>"given")
|
143
|
+
xml.affiliation
|
144
|
+
xml.role {
|
145
|
+
xml.roleTerm(:type=>"text")
|
146
|
+
}
|
147
|
+
}
|
148
|
+
end
|
149
|
+
return builder.doc.root
|
150
|
+
end
|
151
|
+
|
152
|
+
def self.full_name_template
|
153
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
154
|
+
xml.full_name(:type => "personal")
|
155
|
+
end
|
156
|
+
return builder.doc.root
|
157
|
+
end
|
158
|
+
|
159
|
+
# Generates a new Organization node
|
160
|
+
# Uses mods:name[@type="corporate"]
|
161
|
+
def self.organization_template
|
162
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
163
|
+
xml.name(:type=>"corporate") {
|
164
|
+
xml.namePart
|
165
|
+
xml.role {
|
166
|
+
xml.roleTerm(:authority=>"marcrelator", :type=>"text")
|
167
|
+
}
|
168
|
+
}
|
169
|
+
end
|
170
|
+
return builder.doc.root
|
171
|
+
end
|
172
|
+
|
173
|
+
# Generates a new Conference node
|
174
|
+
def self.conference_template
|
175
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
176
|
+
xml.name(:type=>"conference") {
|
177
|
+
xml.namePart
|
178
|
+
xml.role {
|
179
|
+
xml.roleTerm(:authority=>"marcrelator", :type=>"text")
|
180
|
+
}
|
181
|
+
}
|
182
|
+
end
|
183
|
+
return builder.doc.root
|
184
|
+
end
|
185
|
+
|
186
|
+
# Inserts a new contributor (mods:name) into the mods document
|
187
|
+
# creates contributors of type :person, :organization, or :conference
|
188
|
+
def insert_contributor(type, opts={})
|
189
|
+
case type.to_sym
|
190
|
+
when :person
|
191
|
+
node = Hydra::Datastream::ModsImage.person_template
|
192
|
+
nodeset = self.find_by_terms(:person)
|
193
|
+
when :organization
|
194
|
+
node = Hydra::Datastream::ModsImage.organization_template
|
195
|
+
nodeset = self.find_by_terms(:organization)
|
196
|
+
when :conference
|
197
|
+
node = Hydra::Datastream::ModsImage.conference_template
|
198
|
+
nodeset = self.find_by_terms(:conference)
|
199
|
+
else
|
200
|
+
ActiveFedora.logger.warn("#{type} is not a valid argument for Hydra::Datastream::ModsImage.insert_contributor")
|
201
|
+
node = nil
|
202
|
+
index = nil
|
203
|
+
end
|
204
|
+
|
205
|
+
unless nodeset.nil?
|
206
|
+
if nodeset.empty?
|
207
|
+
self.ng_xml.root.add_child(node)
|
208
|
+
index = 0
|
209
|
+
else
|
210
|
+
nodeset.after(node)
|
211
|
+
index = nodeset.length
|
212
|
+
end
|
213
|
+
self.dirty = true
|
214
|
+
end
|
215
|
+
|
216
|
+
return node, index
|
217
|
+
end
|
218
|
+
|
219
|
+
# Remove the contributor entry identified by @contributor_type and @index
|
220
|
+
def remove_contributor(contributor_type, index)
|
221
|
+
self.find_by_terms( {contributor_type.to_sym => index.to_i} ).first.remove
|
222
|
+
self.dirty = true
|
223
|
+
end
|
224
|
+
|
225
|
+
def self.common_relator_terms
|
226
|
+
{"aut" => "Author",
|
227
|
+
"clb" => "Collaborator",
|
228
|
+
"com" => "Compiler",
|
229
|
+
"ctb" => "Contributor",
|
230
|
+
"cre" => "Creator",
|
231
|
+
"edt" => "Editor",
|
232
|
+
"ill" => "Illustrator",
|
233
|
+
"oth" => "Other",
|
234
|
+
"trl" => "Translator",
|
235
|
+
}
|
236
|
+
end
|
237
|
+
|
238
|
+
def self.person_relator_terms
|
239
|
+
{"aut" => "Author",
|
240
|
+
"clb" => "Collaborator",
|
241
|
+
"com" => "Compiler",
|
242
|
+
"cre" => "Creator",
|
243
|
+
"ctb" => "Contributor",
|
244
|
+
"edt" => "Editor",
|
245
|
+
"ill" => "Illustrator",
|
246
|
+
"res" => "Researcher",
|
247
|
+
"rth" => "Research team head",
|
248
|
+
"rtm" => "Research team member",
|
249
|
+
"trl" => "Translator"
|
250
|
+
}
|
251
|
+
end
|
252
|
+
|
253
|
+
def self.conference_relator_terms
|
254
|
+
{
|
255
|
+
"hst" => "Host"
|
256
|
+
}
|
257
|
+
end
|
258
|
+
|
259
|
+
def self.organization_relator_terms
|
260
|
+
{
|
261
|
+
"fnd" => "Funder",
|
262
|
+
"hst" => "Host"
|
263
|
+
}
|
264
|
+
end
|
265
|
+
|
266
|
+
def self.dc_relator_terms
|
267
|
+
{"acp" => "Art copyist",
|
268
|
+
"act" => "Actor",
|
269
|
+
"adp" => "Adapter",
|
270
|
+
"aft" => "Author of afterword, colophon, etc.",
|
271
|
+
"anl" => "Analyst",
|
272
|
+
"anm" => "Animator",
|
273
|
+
"ann" => "Annotator",
|
274
|
+
"ant" => "Bibliographic antecedent",
|
275
|
+
"app" => "Applicant",
|
276
|
+
"aqt" => "Author in quotations or text abstracts",
|
277
|
+
"arc" => "Architect",
|
278
|
+
"ard" => "Artistic director ",
|
279
|
+
"arr" => "Arranger",
|
280
|
+
"art" => "Artist",
|
281
|
+
"asg" => "Assignee",
|
282
|
+
"asn" => "Associated name",
|
283
|
+
"att" => "Attributed name",
|
284
|
+
"auc" => "Auctioneer",
|
285
|
+
"aud" => "Author of dialog",
|
286
|
+
"aui" => "Author of introduction",
|
287
|
+
"aus" => "Author of screenplay",
|
288
|
+
"aut" => "Author",
|
289
|
+
"bdd" => "Binding designer",
|
290
|
+
"bjd" => "Bookjacket designer",
|
291
|
+
"bkd" => "Book designer",
|
292
|
+
"bkp" => "Book producer",
|
293
|
+
"bnd" => "Binder",
|
294
|
+
"bpd" => "Bookplate designer",
|
295
|
+
"bsl" => "Bookseller",
|
296
|
+
"ccp" => "Conceptor",
|
297
|
+
"chr" => "Choreographer",
|
298
|
+
"clb" => "Collaborator",
|
299
|
+
"cli" => "Client",
|
300
|
+
"cll" => "Calligrapher",
|
301
|
+
"clt" => "Collotyper",
|
302
|
+
"cmm" => "Commentator",
|
303
|
+
"cmp" => "Composer",
|
304
|
+
"cmt" => "Compositor",
|
305
|
+
"cng" => "Cinematographer",
|
306
|
+
"cnd" => "Conductor",
|
307
|
+
"cns" => "Censor",
|
308
|
+
"coe" => "Contestant -appellee",
|
309
|
+
"col" => "Collector",
|
310
|
+
"com" => "Compiler",
|
311
|
+
"cos" => "Contestant",
|
312
|
+
"cot" => "Contestant -appellant",
|
313
|
+
"cov" => "Cover designer",
|
314
|
+
"cpc" => "Copyright claimant",
|
315
|
+
"cpe" => "Complainant-appellee",
|
316
|
+
"cph" => "Copyright holder",
|
317
|
+
"cpl" => "Complainant",
|
318
|
+
"cpt" => "Complainant-appellant",
|
319
|
+
"cre" => "Creator",
|
320
|
+
"crp" => "Correspondent",
|
321
|
+
"crr" => "Corrector",
|
322
|
+
"csl" => "Consultant",
|
323
|
+
"csp" => "Consultant to a project",
|
324
|
+
"cst" => "Costume designer",
|
325
|
+
"ctb" => "Contributor",
|
326
|
+
"cte" => "Contestee-appellee",
|
327
|
+
"ctg" => "Cartographer",
|
328
|
+
"ctr" => "Contractor",
|
329
|
+
"cts" => "Contestee",
|
330
|
+
"ctt" => "Contestee-appellant",
|
331
|
+
"cur" => "Curator",
|
332
|
+
"cwt" => "Commentator for written text",
|
333
|
+
"dfd" => "Defendant",
|
334
|
+
"dfe" => "Defendant-appellee",
|
335
|
+
"dft" => "Defendant-appellant",
|
336
|
+
"dgg" => "Degree grantor",
|
337
|
+
"dis" => "Dissertant",
|
338
|
+
"dln" => "Delineator",
|
339
|
+
"dnc" => "Dancer",
|
340
|
+
"dnr" => "Donor",
|
341
|
+
"dpc" => "Depicted",
|
342
|
+
"dpt" => "Depositor",
|
343
|
+
"drm" => "Draftsman",
|
344
|
+
"drt" => "Director",
|
345
|
+
"dsr" => "Designer",
|
346
|
+
"dst" => "Distributor",
|
347
|
+
"dtc" => "Data contributor ",
|
348
|
+
"dte" => "Dedicatee",
|
349
|
+
"dtm" => "Data manager ",
|
350
|
+
"dto" => "Dedicator",
|
351
|
+
"dub" => "Dubious author",
|
352
|
+
"edt" => "Editor",
|
353
|
+
"egr" => "Engraver",
|
354
|
+
"elg" => "Electrician ",
|
355
|
+
"elt" => "Electrotyper",
|
356
|
+
"eng" => "Engineer",
|
357
|
+
"etr" => "Etcher",
|
358
|
+
"exp" => "Expert",
|
359
|
+
"fac" => "Facsimilist",
|
360
|
+
"fld" => "Field director ",
|
361
|
+
"flm" => "Film editor",
|
362
|
+
"fmo" => "Former owner",
|
363
|
+
"fpy" => "First party",
|
364
|
+
"fnd" => "Funder",
|
365
|
+
"frg" => "Forger",
|
366
|
+
"gis" => "Geographic information specialist ",
|
367
|
+
"grt" => "Graphic technician",
|
368
|
+
"hnr" => "Honoree",
|
369
|
+
"hst" => "Host",
|
370
|
+
"ill" => "Illustrator",
|
371
|
+
"ilu" => "Illuminator",
|
372
|
+
"ins" => "Inscriber",
|
373
|
+
"inv" => "Inventor",
|
374
|
+
"itr" => "Instrumentalist",
|
375
|
+
"ive" => "Interviewee",
|
376
|
+
"ivr" => "Interviewer",
|
377
|
+
"lbr" => "Laboratory ",
|
378
|
+
"lbt" => "Librettist",
|
379
|
+
"ldr" => "Laboratory director ",
|
380
|
+
"led" => "Lead",
|
381
|
+
"lee" => "Libelee-appellee",
|
382
|
+
"lel" => "Libelee",
|
383
|
+
"len" => "Lender",
|
384
|
+
"let" => "Libelee-appellant",
|
385
|
+
"lgd" => "Lighting designer",
|
386
|
+
"lie" => "Libelant-appellee",
|
387
|
+
"lil" => "Libelant",
|
388
|
+
"lit" => "Libelant-appellant",
|
389
|
+
"lsa" => "Landscape architect",
|
390
|
+
"lse" => "Licensee",
|
391
|
+
"lso" => "Licensor",
|
392
|
+
"ltg" => "Lithographer",
|
393
|
+
"lyr" => "Lyricist",
|
394
|
+
"mcp" => "Music copyist",
|
395
|
+
"mfr" => "Manufacturer",
|
396
|
+
"mdc" => "Metadata contact",
|
397
|
+
"mod" => "Moderator",
|
398
|
+
"mon" => "Monitor",
|
399
|
+
"mrk" => "Markup editor",
|
400
|
+
"msd" => "Musical director",
|
401
|
+
"mte" => "Metal-engraver",
|
402
|
+
"mus" => "Musician",
|
403
|
+
"nrt" => "Narrator",
|
404
|
+
"opn" => "Opponent",
|
405
|
+
"org" => "Originator",
|
406
|
+
"orm" => "Organizer of meeting",
|
407
|
+
"oth" => "Other",
|
408
|
+
"own" => "Owner",
|
409
|
+
"pat" => "Patron",
|
410
|
+
"pbd" => "Publishing director",
|
411
|
+
"pbl" => "Publisher",
|
412
|
+
"pdr" => "Project director",
|
413
|
+
"pfr" => "Proofreader",
|
414
|
+
"pht" => "Photographer",
|
415
|
+
"plt" => "Platemaker",
|
416
|
+
"pma" => "Permitting agency",
|
417
|
+
"pmn" => "Production manager",
|
418
|
+
"pop" => "Printer of plates",
|
419
|
+
"ppm" => "Papermaker",
|
420
|
+
"ppt" => "Puppeteer",
|
421
|
+
"prc" => "Process contact",
|
422
|
+
"prd" => "Production personnel",
|
423
|
+
"prf" => "Performer",
|
424
|
+
"prg" => "Programmer",
|
425
|
+
"prm" => "Printmaker",
|
426
|
+
"pro" => "Producer",
|
427
|
+
"prt" => "Printer",
|
428
|
+
"pta" => "Patent applicant",
|
429
|
+
"pte" => "Plaintiff -appellee",
|
430
|
+
"ptf" => "Plaintiff",
|
431
|
+
"pth" => "Patent holder",
|
432
|
+
"ptt" => "Plaintiff-appellant",
|
433
|
+
"rbr" => "Rubricator",
|
434
|
+
"rce" => "Recording engineer",
|
435
|
+
"rcp" => "Recipient",
|
436
|
+
"red" => "Redactor",
|
437
|
+
"ren" => "Renderer",
|
438
|
+
"res" => "Researcher",
|
439
|
+
"rev" => "Reviewer",
|
440
|
+
"rps" => "Repository",
|
441
|
+
"rpt" => "Reporter",
|
442
|
+
"rpy" => "Responsible party",
|
443
|
+
"rse" => "Respondent-appellee",
|
444
|
+
"rsg" => "Restager",
|
445
|
+
"rsp" => "Respondent",
|
446
|
+
"rst" => "Respondent-appellant",
|
447
|
+
"rth" => "Research team head",
|
448
|
+
"rtm" => "Research team member",
|
449
|
+
"sad" => "Scientific advisor",
|
450
|
+
"sce" => "Scenarist",
|
451
|
+
"scl" => "Sculptor",
|
452
|
+
"scr" => "Scribe",
|
453
|
+
"sds" => "Sound designer",
|
454
|
+
"sec" => "Secretary",
|
455
|
+
"sgn" => "Signer",
|
456
|
+
"sht" => "Supporting host",
|
457
|
+
"sng" => "Singer",
|
458
|
+
"spk" => "Speaker",
|
459
|
+
"spn" => "Sponsor",
|
460
|
+
"spy" => "Second party",
|
461
|
+
"srv" => "Surveyor",
|
462
|
+
"std" => "Set designer",
|
463
|
+
"stl" => "Storyteller",
|
464
|
+
"stm" => "Stage manager",
|
465
|
+
"stn" => "Standards body",
|
466
|
+
"str" => "Stereotyper",
|
467
|
+
"tcd" => "Technical director",
|
468
|
+
"tch" => "Teacher",
|
469
|
+
"ths" => "Thesis advisor",
|
470
|
+
"trc" => "Transcriber",
|
471
|
+
"trl" => "Translator",
|
472
|
+
"tyd" => "Type designer",
|
473
|
+
"tyg" => "Typographer",
|
474
|
+
"vdg" => "Videographer",
|
475
|
+
"voc" => "Vocalist",
|
476
|
+
"wam" => "Writer of accompanying material",
|
477
|
+
"wdc" => "Woodcutter",
|
478
|
+
"wde" => "Wood -engraver",
|
479
|
+
"wit" => "Witness"}
|
480
|
+
end
|
481
|
+
|
482
|
+
def self.valid_child_types
|
483
|
+
["data", "supporting file", "profile", "lorem ipsum", "dolor"]
|
484
|
+
end
|
485
|
+
|
486
|
+
def to_solr(solr_doc=Hash.new)
|
487
|
+
super(solr_doc)
|
488
|
+
solr_doc.merge!(extract_person_full_names)
|
489
|
+
solr_doc.merge!(extract_person_organizations)
|
490
|
+
solr_doc.merge!(:object_type_facet => "Image")
|
491
|
+
solr_doc
|
492
|
+
end
|
493
|
+
|
494
|
+
end
|
495
|
+
end
|
496
|
+
end
|
@@ -0,0 +1,190 @@
|
|
1
|
+
module Hydra
|
2
|
+
module Datastream
|
3
|
+
class RightsMetadata < ActiveFedora::NokogiriDatastream
|
4
|
+
|
5
|
+
set_terminology do |t|
|
6
|
+
t.root(:path=>"rightsMetadata", :xmlns=>"http://hydra-collab.stanford.edu/schemas/rightsMetadata/v1", :schema=>"http://github.com/projecthydra/schemas/tree/v1/rightsMetadata.xsd")
|
7
|
+
t.copyright {
|
8
|
+
t.machine {
|
9
|
+
t.uvalicense
|
10
|
+
t.cclicense
|
11
|
+
t.license
|
12
|
+
}
|
13
|
+
t.human_readable(:path=>"human")
|
14
|
+
t.license(:proxy=>[:machine, :license ])
|
15
|
+
t.cclicense(:proxy=>[:machine, :cclicense ])
|
16
|
+
}
|
17
|
+
t.access {
|
18
|
+
t.human_readable(:path=>"human")
|
19
|
+
t.machine {
|
20
|
+
t.group
|
21
|
+
t.person
|
22
|
+
}
|
23
|
+
t.person(:proxy=>[:machine, :person])
|
24
|
+
t.group(:proxy=>[:machine, :group])
|
25
|
+
# accessor :access_person, :term=>[:access, :machine, :person]
|
26
|
+
}
|
27
|
+
t.discover_access(:ref=>[:access], :attributes=>{:type=>"discover"})
|
28
|
+
t.read_access(:ref=>[:access], :attributes=>{:type=>"read"})
|
29
|
+
t.edit_access(:ref=>[:access], :attributes=>{:type=>"edit"})
|
30
|
+
# A bug in OM prevnts us from declaring proxy terms at the root of a Terminology
|
31
|
+
# t.access_person(:proxy=>[:access,:machine,:person])
|
32
|
+
# t.access_group(:proxy=>[:access,:machine,:group])
|
33
|
+
|
34
|
+
t.embargo {
|
35
|
+
t.human_readable(:path=>"human")
|
36
|
+
t.machine{
|
37
|
+
t.date(:type =>"release")
|
38
|
+
}
|
39
|
+
t.embargo_release_date(:proxy => [:machine, :date])
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
# Generates an empty Mods Article (used when you call ModsArticle.new without passing in existing xml)
|
44
|
+
def self.xml_template
|
45
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
46
|
+
xml.rightsMetadata(:version=>"0.1", "xmlns"=>"http://hydra-collab.stanford.edu/schemas/rightsMetadata/v1") {
|
47
|
+
xml.copyright {
|
48
|
+
xml.human
|
49
|
+
xml.machine {
|
50
|
+
xml.uvalicense "no"
|
51
|
+
}
|
52
|
+
}
|
53
|
+
xml.access(:type=>"discover") {
|
54
|
+
xml.human
|
55
|
+
xml.machine
|
56
|
+
}
|
57
|
+
xml.access(:type=>"read") {
|
58
|
+
xml.human
|
59
|
+
xml.machine
|
60
|
+
}
|
61
|
+
xml.access(:type=>"edit") {
|
62
|
+
xml.human
|
63
|
+
xml.machine
|
64
|
+
}
|
65
|
+
xml.embargo{
|
66
|
+
xml.human
|
67
|
+
xml.machine
|
68
|
+
}
|
69
|
+
}
|
70
|
+
end
|
71
|
+
return builder.doc
|
72
|
+
end
|
73
|
+
|
74
|
+
# Returns the permissions for the selected person/group
|
75
|
+
# If new_access_level is provided, updates the selected person/group access_level to the one specified
|
76
|
+
# A new_access_level of "none" will remove all access_levels for the selected person/group
|
77
|
+
# @param [Hash] selector hash in format {type => identifier}
|
78
|
+
# @param new_access_level (default nil)
|
79
|
+
# @return Hash in format {type => access_level}.
|
80
|
+
#
|
81
|
+
# ie.
|
82
|
+
# permissions({:person=>"person123"})
|
83
|
+
# => {"person123"=>"edit"}
|
84
|
+
# permissions({:person=>"person123"}, "read")
|
85
|
+
# => {"person123"=>"read"}
|
86
|
+
# permissions({:person=>"person123"})
|
87
|
+
# => {"person123"=>"read"}
|
88
|
+
def permissions(selector, new_access_level=nil)
|
89
|
+
type = selector.keys.first.to_sym
|
90
|
+
actor = selector.values.first
|
91
|
+
if new_access_level.nil?
|
92
|
+
xpath = self.class.terminology.xpath_for(:access, type, actor)
|
93
|
+
nodeset = self.find_by_terms(xpath)
|
94
|
+
if nodeset.empty?
|
95
|
+
return "none"
|
96
|
+
else
|
97
|
+
return nodeset.first.ancestors("access").first.attributes["type"].text
|
98
|
+
end
|
99
|
+
else
|
100
|
+
remove_all_permissions(selector)
|
101
|
+
unless new_access_level == "none"
|
102
|
+
access_type_symbol = "#{new_access_level}_access".to_sym
|
103
|
+
result = self.update_values([access_type_symbol, type] => {"-1"=>actor})
|
104
|
+
end
|
105
|
+
self.dirty = true
|
106
|
+
return new_access_level
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
# Reports on which groups have which permissions
|
112
|
+
# @return Hash in format {group_name => group_permissions, group_name => group_permissions}
|
113
|
+
def groups
|
114
|
+
return quick_search_by_type(:group)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Reports on which groups have which permissions
|
118
|
+
# @return Hash in format {person_name => person_permissions, person_name => person_permissions}
|
119
|
+
def individuals
|
120
|
+
return quick_search_by_type(:person)
|
121
|
+
end
|
122
|
+
|
123
|
+
# Updates permissions for all of the persons and groups in a hash
|
124
|
+
# @param ex. {"group"=>{"group1"=>"discover","group2"=>"edit"}, "person"=>{"person1"=>"read","person2"=>"discover"}}
|
125
|
+
# Currently restricts actor type to group or person. Any others will be ignored
|
126
|
+
def update_permissions(params)
|
127
|
+
params.fetch("group", {}).each_pair {|group_id, access_level| self.permissions({"group"=>group_id}, access_level)}
|
128
|
+
params.fetch("person", {}).each_pair {|group_id, access_level| self.permissions({"person"=>group_id}, access_level)}
|
129
|
+
end
|
130
|
+
|
131
|
+
# @param [Symbol] symbol (either :group or :person)
|
132
|
+
# @return
|
133
|
+
# This method limits the response to known access levels. Probably runs a bit faster than .permissions().
|
134
|
+
def quick_search_by_type(type)
|
135
|
+
result = {}
|
136
|
+
[{:discover_access=>"discover"},{:read_access=>"read"},{:edit_access=>"edit"}].each do |access_levels_hash|
|
137
|
+
access_level = access_levels_hash.keys.first
|
138
|
+
access_level_name = access_levels_hash.values.first
|
139
|
+
self.find_by_terms(*[access_level, type]).each do |entry|
|
140
|
+
result[entry.text] = access_level_name
|
141
|
+
end
|
142
|
+
end
|
143
|
+
return result
|
144
|
+
end
|
145
|
+
|
146
|
+
attr_reader :embargo_release_date
|
147
|
+
def embargo_release_date=(release_date)
|
148
|
+
release_date = release_date.to_s if release_date.is_a? Date
|
149
|
+
begin
|
150
|
+
Date.parse(release_date)
|
151
|
+
rescue
|
152
|
+
return "INVALID DATE"
|
153
|
+
end
|
154
|
+
self.update_values({[:embargo,:machine,:date]=>release_date})
|
155
|
+
end
|
156
|
+
def embargo_release_date(opts={})
|
157
|
+
embargo_release_date = self.find_by_terms(*[:embargo,:machine,:date]).first ? self.find_by_terms(*[:embargo,:machine,:date]).first.text : nil
|
158
|
+
if embargo_release_date.present? && opts[:format] && opts[:format] == :solr_date
|
159
|
+
embargo_release_date << "T23:59:59Z"
|
160
|
+
end
|
161
|
+
embargo_release_date
|
162
|
+
end
|
163
|
+
def under_embargo?
|
164
|
+
(embargo_release_date && Date.today < embargo_release_date.to_date) ? true : false
|
165
|
+
end
|
166
|
+
|
167
|
+
def to_solr(solr_doc=Hash.new)
|
168
|
+
super(solr_doc)
|
169
|
+
::Solrizer::Extractor.insert_solr_field_value(solr_doc, "embargo_release_date_dt", embargo_release_date(:format=>:solr_date)) if embargo_release_date
|
170
|
+
solr_doc
|
171
|
+
end
|
172
|
+
|
173
|
+
|
174
|
+
|
175
|
+
|
176
|
+
|
177
|
+
private
|
178
|
+
# Purge all access given group/person
|
179
|
+
def remove_all_permissions(selector)
|
180
|
+
return unless ng_xml
|
181
|
+
type = selector.keys.first.to_sym
|
182
|
+
actor = selector.values.first
|
183
|
+
xpath = self.class.terminology.xpath_for(:access, type, actor)
|
184
|
+
nodes_to_purge = self.find_by_terms(xpath)
|
185
|
+
nodes_to_purge.each {|node| node.remove}
|
186
|
+
end
|
187
|
+
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|