curation_concerns-models 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/Rakefile +1 -1
- data/app/actors/concerns/curation_concerns/manages_embargoes_actor.rb +11 -19
- data/app/actors/curation_concerns/base_actor.rb +41 -45
- data/app/actors/curation_concerns/embargo_actor.rb +19 -0
- data/app/actors/curation_concerns/file_set_actor.rb +200 -0
- data/app/actors/curation_concerns/lease_actor.rb +19 -0
- data/app/actors/curation_concerns/work_actor_behavior.rb +55 -58
- data/app/indexers/curation_concerns/collection_indexer.rb +10 -0
- data/app/indexers/curation_concerns/file_set_indexing_service.rb +24 -0
- data/app/{services/curation_concerns/generic_work_indexing_service.rb → indexers/curation_concerns/work_indexing_service.rb} +6 -6
- data/app/jobs/active_fedora_id_based_job.rb +5 -12
- data/app/jobs/audit_job.rb +11 -17
- data/app/jobs/characterize_job.rb +8 -7
- data/app/jobs/create_derivatives_job.rb +8 -11
- data/app/jobs/import_url_job.rb +12 -25
- data/app/jobs/ingest_file_job.rb +16 -0
- data/app/jobs/ingest_local_file_job.rb +14 -35
- data/app/jobs/resolrize_job.rb +3 -5
- data/app/jobs/upload_set_update_job.rb +68 -0
- data/app/models/checksum_audit_log.rb +2 -3
- data/app/models/concerns/curation_concerns/ability.rb +18 -10
- data/app/models/concerns/curation_concerns/basic_metadata.rb +1 -3
- data/app/models/concerns/curation_concerns/collection_behavior.rb +13 -14
- data/app/models/concerns/curation_concerns/file_set/belongs_to_upload_sets.rb +15 -0
- data/app/models/concerns/curation_concerns/{generic_file → file_set}/belongs_to_works.rb +8 -14
- data/app/models/concerns/curation_concerns/file_set/derivatives.rb +54 -0
- data/app/models/concerns/curation_concerns/{generic_file → file_set}/full_text_indexing.rb +1 -2
- data/app/models/concerns/curation_concerns/{generic_file → file_set}/indexing.rb +2 -2
- data/app/models/concerns/curation_concerns/{generic_file → file_set}/versions.rb +2 -3
- data/app/models/concerns/curation_concerns/file_set_behavior.rb +36 -0
- data/app/models/concerns/curation_concerns/generic_file.rb +1 -1
- data/app/models/concerns/curation_concerns/has_representative.rb +6 -7
- data/app/models/concerns/curation_concerns/human_readable_type.rb +5 -7
- data/app/models/concerns/curation_concerns/permissions.rb +2 -2
- data/app/models/concerns/curation_concerns/permissions/readable.rb +0 -1
- data/app/models/concerns/curation_concerns/permissions/writable.rb +10 -51
- data/app/models/concerns/curation_concerns/serializers.rb +3 -5
- data/app/models/concerns/curation_concerns/solr_document_behavior.rb +37 -40
- data/app/models/concerns/curation_concerns/upload_set_behavior.rb +38 -0
- data/app/models/concerns/curation_concerns/user.rb +4 -51
- data/app/models/concerns/curation_concerns/with_file_sets.rb +28 -0
- data/app/models/concerns/curation_concerns/{generic_work_behavior.rb → work_behavior.rb} +12 -6
- data/app/models/curation_concerns/classify_concern.rb +7 -7
- data/app/models/curation_concerns/quick_classification_query.rb +6 -7
- data/app/models/single_use_link.rb +34 -0
- data/app/models/upload_set.rb +3 -0
- data/app/services/curation_concerns/derivative_path.rb +32 -0
- data/app/services/curation_concerns/{generic_file_audit_service.rb → file_set_audit_service.rb} +17 -18
- data/app/services/curation_concerns/indexes_thumbnails.rb +14 -0
- data/app/services/curation_concerns/local_file_service.rb +10 -0
- data/app/services/curation_concerns/lock_manager.rb +40 -0
- data/app/services/curation_concerns/noid.rb +1 -1
- data/app/services/curation_concerns/persist_derivatives.rb +33 -0
- data/app/services/curation_concerns/persist_directly_contained_output_file_service.rb +26 -0
- data/app/services/curation_concerns/repository_audit_service.rb +1 -3
- data/app/services/curation_concerns/thumbnail_path_service.rb +46 -0
- data/app/services/curation_concerns/time_service.rb +7 -0
- data/app/services/curation_concerns/versioning_service.rb +11 -12
- data/curation_concerns-models.gemspec +6 -6
- data/lib/curation_concerns/configuration.rb +154 -0
- data/lib/curation_concerns/messages.rb +26 -26
- data/lib/curation_concerns/models.rb +5 -14
- data/lib/curation_concerns/models/engine.rb +0 -30
- data/lib/curation_concerns/models/utils.rb +4 -4
- data/lib/curation_concerns/models/version.rb +1 -1
- data/lib/generators/curation_concerns/models/abstract_migration_generator.rb +8 -7
- data/lib/generators/curation_concerns/models/clamav_generator.rb +3 -3
- data/lib/generators/curation_concerns/models/install_generator.rb +13 -20
- data/lib/generators/curation_concerns/models/templates/app/models/file_set.rb +4 -0
- data/lib/generators/curation_concerns/models/templates/config/clamav.rb +1 -1
- data/lib/generators/curation_concerns/models/templates/config/curation_concerns.rb +52 -65
- data/lib/generators/curation_concerns/models/templates/config/redis_config.rb +13 -17
- data/lib/generators/curation_concerns/models/templates/config/resque_config.rb +2 -1
- data/lib/generators/curation_concerns/models/templates/migrations/create_checksum_audit_logs.rb +3 -3
- data/lib/generators/curation_concerns/models/templates/migrations/create_single_use_links.rb +12 -0
- data/lib/tasks/curation_concerns-models_tasks.rake +4 -62
- data/lib/tasks/migrate.rake +1 -1
- data/lib/tasks/resque.rake +1 -0
- data/lib/tasks/solr_reindex.rake +1 -1
- metadata +59 -52
- data/app/actors/curation_concerns/generic_file_actor.rb +0 -150
- data/app/jobs/active_fedora_pid_based_job.rb +0 -6
- data/app/jobs/copy_permissions_job.rb +0 -24
- data/app/models/concerns/curation_concerns/generic_file/characterization.rb +0 -89
- data/app/models/concerns/curation_concerns/generic_file/content.rb +0 -8
- data/app/models/concerns/curation_concerns/generic_file/export.rb +0 -343
- data/app/models/concerns/curation_concerns/generic_file_behavior.rb +0 -44
- data/app/models/concerns/curation_concerns/with_basic_metadata.rb +0 -98
- data/app/models/concerns/curation_concerns/with_generic_files.rb +0 -29
- data/app/models/datastreams/fits_datastream.rb +0 -148
- data/app/services/curation_concerns/characterization_service.rb +0 -71
- data/app/services/curation_concerns/full_text_extraction_service.rb +0 -38
- data/app/services/curation_concerns/generic_file_indexing_service.rb +0 -14
- data/lib/curation_concerns/models/resque.rb +0 -36
- data/lib/generators/curation_concerns/models/fulltext_generator.rb +0 -28
- data/lib/generators/curation_concerns/models/templates/app/models/generic_file.rb +0 -4
- data/lib/generators/curation_concerns/models/templates/config/resque_admin.rb +0 -10
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
module CurationConcerns
|
|
2
|
-
# Actions are decoupled from controller logic so that they may be called from a controller or a background job.
|
|
3
|
-
class GenericFileActor
|
|
4
|
-
include CurationConcerns::ManagesEmbargoesActor
|
|
5
|
-
|
|
6
|
-
attr_reader :generic_file, :user, :attributes, :curation_concern
|
|
7
|
-
|
|
8
|
-
def initialize(generic_file, user)
|
|
9
|
-
# we're setting attributes and curation_concern to bridge the difference
|
|
10
|
-
# between CurationConcerns::GenericFileActor and ManagesEmbargoesActor
|
|
11
|
-
@curation_concern = generic_file
|
|
12
|
-
@generic_file = generic_file
|
|
13
|
-
@user = user
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
# Adds the appropriate metadata, visibility and relationships to generic_file
|
|
17
|
-
#
|
|
18
|
-
# *Note*: In past versions of Sufia this method did not perform a save because it is mainly used in conjunction with
|
|
19
|
-
# create_content, which also performs a save. However, due to the relationship between Hydra::PCDM objects,
|
|
20
|
-
# we have to save both the parent work and the generic_file in order to record the "metadata" relationship
|
|
21
|
-
# between them.
|
|
22
|
-
# @param [String] batch_id id of the batch that the file was uploaded within
|
|
23
|
-
# @param [String] work_id id of the parent work that will contain the generic_file.
|
|
24
|
-
# @param [Hash] generic_file_params specifying the visibility, lease and/or embargo of the generic file. If you don't provide at least one of visibility, embargo_release_date or lease_expiration_date, visibility will be copied from the parent.
|
|
25
|
-
|
|
26
|
-
def create_metadata(batch_id, work_id, generic_file_params={})
|
|
27
|
-
generic_file.apply_depositor_metadata(user)
|
|
28
|
-
time_in_utc = DateTime.now.new_offset(0)
|
|
29
|
-
generic_file.date_uploaded = time_in_utc
|
|
30
|
-
generic_file.date_modified = time_in_utc
|
|
31
|
-
generic_file.creator = [user.name]
|
|
32
|
-
# TODO: Remove this? see https://github.com/projecthydra-labs/curation_concerns/issues/27
|
|
33
|
-
if batch_id && generic_file.respond_to?(:batch_id=)
|
|
34
|
-
generic_file.batch_id = batch_id
|
|
35
|
-
else
|
|
36
|
-
ActiveFedora::Base.logger.warn "unable to find batch to attach to"
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
unless work_id.blank?
|
|
40
|
-
work = ActiveFedora::Base.find(work_id)
|
|
41
|
-
|
|
42
|
-
if !((generic_file_params || {}).keys & ["visibility", "embargo_release_date", "lease_expiration_date"]).empty?
|
|
43
|
-
interpret_visibility generic_file_params
|
|
44
|
-
else
|
|
45
|
-
copy_visibility(work, generic_file)
|
|
46
|
-
end
|
|
47
|
-
work.generic_files << generic_file
|
|
48
|
-
# Save the work so the association between the work and the generic_file is persisted (head_id)
|
|
49
|
-
work.save
|
|
50
|
-
end
|
|
51
|
-
yield(generic_file) if block_given?
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def create_content(file)
|
|
55
|
-
# Tell UploadFileToGenericFile service to skip versioning because versions will be minted by VersionCommitter (called by save_characterize_and_record_committer) when necessary
|
|
56
|
-
Hydra::Works::UploadFileToGenericFile.call(generic_file, file, versioning: false)
|
|
57
|
-
generic_file.label ||= file.original_filename
|
|
58
|
-
generic_file.title = [generic_file.label] if generic_file.title.blank?
|
|
59
|
-
save_characterize_and_record_committer do
|
|
60
|
-
if CurationConcerns.config.respond_to?(:after_create_content)
|
|
61
|
-
CurationConcerns.config.after_create_content.call(generic_file, user)
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def revert_content(revision_id)
|
|
67
|
-
generic_file.original_file.restore_version(revision_id)
|
|
68
|
-
save_characterize_and_record_committer do
|
|
69
|
-
if CurationConcerns.config.respond_to?(:after_revert_content)
|
|
70
|
-
CurationConcerns.config.after_revert_content.call(generic_file, user, revision_id)
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def update_content(file)
|
|
76
|
-
# Tell UploadFileToGenericFile service to skip versioning because versions will be minted by VersionCommitter (called by save_characterize_and_record_committer) when necessary
|
|
77
|
-
Hydra::Works::UploadFileToGenericFile.call(generic_file, file, versioning: false)
|
|
78
|
-
save_characterize_and_record_committer do
|
|
79
|
-
if CurationConcerns.config.respond_to?(:after_update_content)
|
|
80
|
-
CurationConcerns.config.after_update_content.call(generic_file, user)
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def update_metadata(model_attributes, all_attributes)
|
|
86
|
-
update_visibility(all_attributes)
|
|
87
|
-
model_attributes.delete(:visibility) # Applying this attribute is handled by update_visibility
|
|
88
|
-
generic_file.attributes = model_attributes
|
|
89
|
-
generic_file.date_modified = DateTime.now
|
|
90
|
-
save do
|
|
91
|
-
if CurationConcerns.config.respond_to?(:after_update_metadata)
|
|
92
|
-
CurationConcerns.config.after_update_metadata.call(generic_file, user)
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def destroy
|
|
98
|
-
generic_file.destroy
|
|
99
|
-
if CurationConcerns.config.respond_to?(:after_destroy)
|
|
100
|
-
CurationConcerns.config.after_destroy.call(generic_file.id, user)
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
# Saves the generic file, queues a job to characterize it, and records the committer.
|
|
105
|
-
# Takes a block which is run if the save was successful.
|
|
106
|
-
def save_characterize_and_record_committer
|
|
107
|
-
save do
|
|
108
|
-
push_characterize_job
|
|
109
|
-
CurationConcerns::VersioningService.create(generic_file.original_file, user)
|
|
110
|
-
yield if block_given?
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
# Takes an optional block and executes the block if the save was successful.
|
|
115
|
-
# returns false if the save was unsuccessful
|
|
116
|
-
def save
|
|
117
|
-
save_tries = 0
|
|
118
|
-
begin
|
|
119
|
-
return false unless generic_file.save
|
|
120
|
-
rescue RSolr::Error::Http => error
|
|
121
|
-
ActiveFedora::Base.logger.warn "CurationConcerns::GenericFileActor#save Caught RSOLR error #{error.inspect}"
|
|
122
|
-
save_tries+=1
|
|
123
|
-
# fail for good if the tries is greater than 3
|
|
124
|
-
raise error if save_tries >=3
|
|
125
|
-
sleep 0.01
|
|
126
|
-
retry
|
|
127
|
-
end
|
|
128
|
-
yield if block_given?
|
|
129
|
-
true
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
def push_characterize_job
|
|
133
|
-
CurationConcerns.queue.push(CharacterizeJob.new(@generic_file.id))
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
protected
|
|
137
|
-
|
|
138
|
-
# This method can be overridden in case there is a custom approach for visibility (e.g. embargo)
|
|
139
|
-
def update_visibility(attributes)
|
|
140
|
-
interpret_visibility(attributes) # relies on CurationConcerns::ManagesEmbargoesActor to interpret and apply visibility
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
private
|
|
144
|
-
|
|
145
|
-
# copy visibility from source_concern to destination_concern
|
|
146
|
-
def copy_visibility(source_concern, destination_concern)
|
|
147
|
-
destination_concern.visibility = source_concern.visibility
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
end
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
class CopyPermissionsJob
|
|
2
|
-
def queue_name
|
|
3
|
-
:permissions
|
|
4
|
-
end
|
|
5
|
-
|
|
6
|
-
attr_accessor :id
|
|
7
|
-
|
|
8
|
-
def initialize(id)
|
|
9
|
-
self.id = id
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def run
|
|
13
|
-
# work = ActiveFedora::Base.load_instance_from_solr(id)
|
|
14
|
-
work = ActiveFedora::Base.find(id) # Hydra::Works::GenericWork is not compatible with load_instance_from_solr. Using (slower) ActiveFedora::Base.find instead.
|
|
15
|
-
if work.respond_to?(:generic_files)
|
|
16
|
-
work.generic_files.each do |file|
|
|
17
|
-
|
|
18
|
-
work.permissions.each {|perm| file.permissions << Hydra::AccessControls::Permission.new(perm.to_hash)}
|
|
19
|
-
new_permissions = file.permissions.uniq! { |item| item.to_hash}
|
|
20
|
-
file.permissions = new_permissions unless new_permissions.blank?
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
module CurationConcerns
|
|
2
|
-
module GenericFile
|
|
3
|
-
module Characterization
|
|
4
|
-
extend ActiveSupport::Concern
|
|
5
|
-
included do
|
|
6
|
-
contains "characterization", class_name: 'FitsDatastream'
|
|
7
|
-
property :mime_type, delegate_to: 'characterization', multiple: false do |index|
|
|
8
|
-
index.as :stored_searchable
|
|
9
|
-
end
|
|
10
|
-
property :format_label, delegate_to: 'characterization'
|
|
11
|
-
property :file_size, delegate_to: 'characterization'
|
|
12
|
-
property :last_modified, delegate_to: 'characterization'
|
|
13
|
-
property :filename, delegate_to: 'characterization'
|
|
14
|
-
property :original_checksum, delegate_to: 'characterization'
|
|
15
|
-
property :rights_basis, delegate_to: 'characterization'
|
|
16
|
-
property :copyright_basis, delegate_to: 'characterization'
|
|
17
|
-
property :copyright_note, delegate_to: 'characterization'
|
|
18
|
-
property :well_formed, delegate_to: 'characterization'
|
|
19
|
-
property :valid, delegate_to: 'characterization'
|
|
20
|
-
property :status_message, delegate_to: 'characterization'
|
|
21
|
-
property :file_title, delegate_to: 'characterization'
|
|
22
|
-
property :file_author, delegate_to: 'characterization'
|
|
23
|
-
property :page_count, delegate_to: 'characterization'
|
|
24
|
-
property :file_language, delegate_to: 'characterization'
|
|
25
|
-
property :word_count, delegate_to: 'characterization'
|
|
26
|
-
property :character_count, delegate_to: 'characterization'
|
|
27
|
-
property :paragraph_count, delegate_to: 'characterization'
|
|
28
|
-
property :line_count, delegate_to: 'characterization'
|
|
29
|
-
property :table_count, delegate_to: 'characterization'
|
|
30
|
-
property :graphics_count, delegate_to: 'characterization'
|
|
31
|
-
property :byte_order, delegate_to: 'characterization'
|
|
32
|
-
property :compression, delegate_to: 'characterization'
|
|
33
|
-
property :color_space, delegate_to: 'characterization'
|
|
34
|
-
property :profile_name, delegate_to: 'characterization'
|
|
35
|
-
property :profile_version, delegate_to: 'characterization'
|
|
36
|
-
property :orientation, delegate_to: 'characterization'
|
|
37
|
-
property :color_map, delegate_to: 'characterization'
|
|
38
|
-
property :image_producer, delegate_to: 'characterization'
|
|
39
|
-
property :capture_device, delegate_to: 'characterization'
|
|
40
|
-
property :scanning_software, delegate_to: 'characterization'
|
|
41
|
-
property :exif_version, delegate_to: 'characterization'
|
|
42
|
-
property :gps_timestamp, delegate_to: 'characterization'
|
|
43
|
-
property :latitude, delegate_to: 'characterization'
|
|
44
|
-
property :longitude, delegate_to: 'characterization'
|
|
45
|
-
property :character_set, delegate_to: 'characterization'
|
|
46
|
-
property :markup_basis, delegate_to: 'characterization'
|
|
47
|
-
property :markup_language, delegate_to: 'characterization'
|
|
48
|
-
property :bit_depth, delegate_to: 'characterization'
|
|
49
|
-
property :channels, delegate_to: 'characterization'
|
|
50
|
-
property :data_format, delegate_to: 'characterization'
|
|
51
|
-
property :offset, delegate_to: 'characterization'
|
|
52
|
-
property :frame_rate, delegate_to: 'characterization'
|
|
53
|
-
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def width
|
|
57
|
-
characterization.width.blank? ? characterization.video_width : characterization.width
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def height
|
|
61
|
-
characterization.height.blank? ? characterization.video_height : characterization.height
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def duration
|
|
65
|
-
characterization.duration.blank? ? characterization.video_duration : characterization.duration
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def sample_rate
|
|
69
|
-
characterization.sample_rate.blank? ? characterization.video_sample_rate : characterization.sample_rate
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def characterization_terms
|
|
73
|
-
h = {}
|
|
74
|
-
self.characterization.class.terminology.terms.each_pair do |k, v|
|
|
75
|
-
next unless v.respond_to? :proxied_term
|
|
76
|
-
term = v.proxied_term
|
|
77
|
-
begin
|
|
78
|
-
value = self.send(term.name)
|
|
79
|
-
h[term.name] = value unless value.empty?
|
|
80
|
-
rescue NoMethodError
|
|
81
|
-
next
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
h
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
end
|
|
@@ -1,343 +0,0 @@
|
|
|
1
|
-
module CurationConcerns
|
|
2
|
-
module GenericFile
|
|
3
|
-
module Export
|
|
4
|
-
# MIME: 'application/x-endnote-refer'
|
|
5
|
-
def export_as_endnote
|
|
6
|
-
end_note_format = {
|
|
7
|
-
'%T' => [:title, lambda { |x| x.first }],
|
|
8
|
-
'%Q' => [:title, lambda { |x| x.drop(1) }],
|
|
9
|
-
'%A' => [:creator],
|
|
10
|
-
'%C' => [:publication_place],
|
|
11
|
-
'%D' => [:date_created],
|
|
12
|
-
'%8' => [:date_uploaded],
|
|
13
|
-
'%E' => [:contributor],
|
|
14
|
-
'%I' => [:publisher],
|
|
15
|
-
'%J' => [:series_title],
|
|
16
|
-
'%@' => [:isbn],
|
|
17
|
-
'%U' => [:related_url],
|
|
18
|
-
'%7' => [:edition_statement],
|
|
19
|
-
'%R' => [:persistent_url],
|
|
20
|
-
'%X' => [:description],
|
|
21
|
-
'%G' => [:language],
|
|
22
|
-
'%[' => [:date_modified],
|
|
23
|
-
'%9' => [:resource_type],
|
|
24
|
-
'%~' => I18n.t('curation_concerns.product_name'),
|
|
25
|
-
'%W' => I18n.t('curation_concerns.institution_name')
|
|
26
|
-
}
|
|
27
|
-
text = []
|
|
28
|
-
text << "%0 GenericFile"
|
|
29
|
-
end_note_format.each do |endnote_key, mapping|
|
|
30
|
-
if mapping.is_a? String
|
|
31
|
-
values = [mapping]
|
|
32
|
-
else
|
|
33
|
-
values = self.send(mapping[0]) if self.respond_to? mapping[0]
|
|
34
|
-
values = mapping[1].call(values) if mapping.length == 2
|
|
35
|
-
values = Array(values)
|
|
36
|
-
end
|
|
37
|
-
next if values.empty? or values.first.nil?
|
|
38
|
-
spaced_values = values.join("; ")
|
|
39
|
-
text << "#{endnote_key} #{spaced_values}"
|
|
40
|
-
end
|
|
41
|
-
return text.join("\n")
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def persistent_url
|
|
45
|
-
"#{CurationConcerns.config.persistent_hostpath}#{id}"
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# MIME type: 'application/x-openurl-ctx-kev'
|
|
49
|
-
def export_as_openurl_ctx_kev
|
|
50
|
-
export_text = []
|
|
51
|
-
export_text << "url_ver=Z39.88-2004&ctx_ver=Z39.88-2004&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&rfr_id=info%3Asid%2Fblacklight.rubyforge.org%3Agenerator"
|
|
52
|
-
field_map = {
|
|
53
|
-
title: 'title',
|
|
54
|
-
creator: 'creator',
|
|
55
|
-
subject: 'subject',
|
|
56
|
-
description: 'description',
|
|
57
|
-
publisher: 'publisher',
|
|
58
|
-
contributor: 'contributor',
|
|
59
|
-
date_created: 'date',
|
|
60
|
-
resource_type: 'format',
|
|
61
|
-
identifier: 'identifier',
|
|
62
|
-
language: 'language',
|
|
63
|
-
tag: 'relation',
|
|
64
|
-
based_near: 'coverage',
|
|
65
|
-
rights: 'rights'
|
|
66
|
-
}
|
|
67
|
-
field_map.each do |element, kev|
|
|
68
|
-
values = self.send(element)
|
|
69
|
-
next if values.empty? or values.first.nil?
|
|
70
|
-
values.each do |value|
|
|
71
|
-
export_text << "rft.#{kev}=#{CGI::escape(value.to_s)}"
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
export_text.join('&') unless export_text.blank?
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def export_as_apa_citation
|
|
78
|
-
text = ''
|
|
79
|
-
authors_list = []
|
|
80
|
-
authors_list_final = []
|
|
81
|
-
|
|
82
|
-
#setup formatted author list
|
|
83
|
-
authors = get_author_list
|
|
84
|
-
authors.each do |author|
|
|
85
|
-
next if author.blank?
|
|
86
|
-
authors_list.push(abbreviate_name(author))
|
|
87
|
-
end
|
|
88
|
-
authors_list.each do |author|
|
|
89
|
-
if author == authors_list.first #first
|
|
90
|
-
authors_list_final.push(author.strip)
|
|
91
|
-
elsif author == authors_list.last #last
|
|
92
|
-
authors_list_final.push(", & " + author.strip)
|
|
93
|
-
else #all others
|
|
94
|
-
authors_list_final.push(", " + author.strip)
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
text << authors_list_final.join
|
|
98
|
-
unless text.blank?
|
|
99
|
-
if text[-1,1] != "."
|
|
100
|
-
text << ". "
|
|
101
|
-
else
|
|
102
|
-
text << " "
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
# Get Pub Date
|
|
106
|
-
text << "(" + setup_pub_date + "). " unless setup_pub_date.nil?
|
|
107
|
-
|
|
108
|
-
# setup title info
|
|
109
|
-
title_info = setup_title_info
|
|
110
|
-
text << "<i>" + title_info + "</i> " unless title_info.nil?
|
|
111
|
-
|
|
112
|
-
# Publisher info
|
|
113
|
-
text << setup_pub_info unless setup_pub_info.nil?
|
|
114
|
-
unless text.blank?
|
|
115
|
-
if text[-1,1] != "."
|
|
116
|
-
text += "."
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
text.html_safe
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def export_as_mla_citation
|
|
123
|
-
text = ''
|
|
124
|
-
authors_final = []
|
|
125
|
-
|
|
126
|
-
#setup formatted author list
|
|
127
|
-
authors = get_author_list
|
|
128
|
-
|
|
129
|
-
if authors.length < 4
|
|
130
|
-
authors.each do |author|
|
|
131
|
-
if author == authors.first #first
|
|
132
|
-
authors_final.push(author)
|
|
133
|
-
elsif author == authors.last #last
|
|
134
|
-
authors_final.push(", and " + name_reverse(author) + ".")
|
|
135
|
-
else #all others
|
|
136
|
-
authors_final.push(", " + name_reverse(author))
|
|
137
|
-
end
|
|
138
|
-
end
|
|
139
|
-
text << authors_final.join
|
|
140
|
-
unless text.blank?
|
|
141
|
-
if text[-1,1] != "."
|
|
142
|
-
text << ". "
|
|
143
|
-
else
|
|
144
|
-
text << " "
|
|
145
|
-
end
|
|
146
|
-
end
|
|
147
|
-
else
|
|
148
|
-
text << authors.first + ", et al. "
|
|
149
|
-
end
|
|
150
|
-
# setup title
|
|
151
|
-
title_info = setup_title_info
|
|
152
|
-
text << "<i>" + mla_citation_title(title_info) + "</i> " unless title.blank?
|
|
153
|
-
|
|
154
|
-
# Publication
|
|
155
|
-
text << setup_pub_info + ", " unless setup_pub_info.nil?
|
|
156
|
-
|
|
157
|
-
# Get Pub Date
|
|
158
|
-
text << setup_pub_date unless setup_pub_date.nil?
|
|
159
|
-
if text[-1,1] != "."
|
|
160
|
-
text << "." unless text.blank?
|
|
161
|
-
end
|
|
162
|
-
text.html_safe
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
def export_as_chicago_citation
|
|
166
|
-
author_text = ""
|
|
167
|
-
authors = get_all_authors
|
|
168
|
-
unless authors.blank?
|
|
169
|
-
if authors.length > 10
|
|
170
|
-
authors.each_with_index do |author, index|
|
|
171
|
-
if index < 7
|
|
172
|
-
if index == 0
|
|
173
|
-
author_text << "#{author}"
|
|
174
|
-
if author.ends_with?(",")
|
|
175
|
-
author_text << " "
|
|
176
|
-
else
|
|
177
|
-
author_text << ", "
|
|
178
|
-
end
|
|
179
|
-
else
|
|
180
|
-
author_text << "#{name_reverse(author)}, "
|
|
181
|
-
end
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
author_text << " et al."
|
|
185
|
-
elsif authors.length > 1
|
|
186
|
-
authors.each_with_index do |author,index|
|
|
187
|
-
if index == 0
|
|
188
|
-
author_text << "#{author}"
|
|
189
|
-
if author.ends_with?(",")
|
|
190
|
-
author_text << " "
|
|
191
|
-
else
|
|
192
|
-
author_text << ", "
|
|
193
|
-
end
|
|
194
|
-
elsif index + 1 == authors.length
|
|
195
|
-
author_text << "and #{name_reverse(author)}."
|
|
196
|
-
else
|
|
197
|
-
author_text << "#{name_reverse(author)}, "
|
|
198
|
-
end
|
|
199
|
-
end
|
|
200
|
-
else
|
|
201
|
-
author_text << authors.first
|
|
202
|
-
end
|
|
203
|
-
end
|
|
204
|
-
title_info = ""
|
|
205
|
-
title_info << citation_title(clean_end_punctuation(CGI::escapeHTML(title.first)).strip) unless title.blank?
|
|
206
|
-
|
|
207
|
-
pub_info = ""
|
|
208
|
-
place = self.based_near.first
|
|
209
|
-
publisher = self.publisher.first
|
|
210
|
-
unless place.blank?
|
|
211
|
-
place = CGI::escapeHTML(place)
|
|
212
|
-
pub_info << place
|
|
213
|
-
pub_info << ": " unless publisher.blank?
|
|
214
|
-
end
|
|
215
|
-
unless publisher.blank?
|
|
216
|
-
publisher = CGI::escapeHTML(publisher)
|
|
217
|
-
pub_info << publisher
|
|
218
|
-
pub_info << ", " unless setup_pub_date.nil?
|
|
219
|
-
end
|
|
220
|
-
unless setup_pub_date.nil?
|
|
221
|
-
pub_info << setup_pub_date
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
citation = ""
|
|
225
|
-
citation << "#{author_text} " unless author_text.blank?
|
|
226
|
-
citation << "<i>#{title_info}.</i> " unless title_info.blank?
|
|
227
|
-
citation << "#{pub_info}." unless pub_info.blank?
|
|
228
|
-
citation.html_safe
|
|
229
|
-
end
|
|
230
|
-
|
|
231
|
-
private
|
|
232
|
-
|
|
233
|
-
def setup_pub_date
|
|
234
|
-
first_date = self.date_created.first
|
|
235
|
-
unless first_date.blank?
|
|
236
|
-
first_date = CGI::escapeHTML(first_date)
|
|
237
|
-
date_value = first_date.gsub(/[^0-9|n\.d\.]/, "")[0,4]
|
|
238
|
-
return nil if date_value.nil?
|
|
239
|
-
end
|
|
240
|
-
clean_end_punctuation(date_value) if date_value
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
def setup_pub_info
|
|
244
|
-
text = ''
|
|
245
|
-
place = self.based_near.first
|
|
246
|
-
publisher = self.publisher.first
|
|
247
|
-
unless place.blank?
|
|
248
|
-
place = CGI::escapeHTML(place)
|
|
249
|
-
text << place
|
|
250
|
-
text << ": " unless publisher.blank?
|
|
251
|
-
end
|
|
252
|
-
unless publisher.blank?
|
|
253
|
-
publisher = CGI::escapeHTML(publisher)
|
|
254
|
-
text << publisher
|
|
255
|
-
end
|
|
256
|
-
return nil if text.strip.blank?
|
|
257
|
-
clean_end_punctuation(text.strip)
|
|
258
|
-
end
|
|
259
|
-
|
|
260
|
-
def mla_citation_title(text)
|
|
261
|
-
no_upcase = ["a","an","and","but","by","for","it","of","the","to","with"]
|
|
262
|
-
new_text = []
|
|
263
|
-
word_parts = text.split(" ")
|
|
264
|
-
word_parts.each do |w|
|
|
265
|
-
if !no_upcase.include? w
|
|
266
|
-
new_text.push(w.capitalize)
|
|
267
|
-
else
|
|
268
|
-
new_text.push(w)
|
|
269
|
-
end
|
|
270
|
-
end
|
|
271
|
-
new_text.join(" ")
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
def citation_title(title_text)
|
|
275
|
-
prepositions = ["a","about","across","an","and","before","but","by","for","it","of","the","to","with","without"]
|
|
276
|
-
new_text = []
|
|
277
|
-
title_text.split(" ").each_with_index do |word,index|
|
|
278
|
-
if (index == 0 and word != word.upcase) or (word.length > 1 and word != word.upcase and !prepositions.include?(word))
|
|
279
|
-
# the split("-") will handle the capitalization of hyphenated words
|
|
280
|
-
new_text << word.split("-").map!{|w| w.capitalize }.join("-")
|
|
281
|
-
else
|
|
282
|
-
new_text << word
|
|
283
|
-
end
|
|
284
|
-
end
|
|
285
|
-
new_text.join(" ")
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
def setup_title_info
|
|
289
|
-
text = ''
|
|
290
|
-
title = self.title.first
|
|
291
|
-
unless title.blank?
|
|
292
|
-
title = CGI::escapeHTML(title)
|
|
293
|
-
title_info = clean_end_punctuation(title.strip)
|
|
294
|
-
text << title_info
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
return nil if text.strip.blank?
|
|
298
|
-
clean_end_punctuation(text.strip) + "."
|
|
299
|
-
end
|
|
300
|
-
|
|
301
|
-
def clean_end_punctuation(text)
|
|
302
|
-
if [".",",",":",";","/"].include? text[-1,1]
|
|
303
|
-
return text[0,text.length-1]
|
|
304
|
-
end
|
|
305
|
-
text
|
|
306
|
-
end
|
|
307
|
-
|
|
308
|
-
def get_author_list
|
|
309
|
-
self.creator.map { |author| clean_end_punctuation(CGI::escapeHTML(author)) }.uniq
|
|
310
|
-
end
|
|
311
|
-
|
|
312
|
-
def get_all_authors
|
|
313
|
-
authors = self.creator
|
|
314
|
-
return authors.empty? ? nil : authors.map { |author| CGI::escapeHTML(author) }
|
|
315
|
-
end
|
|
316
|
-
|
|
317
|
-
def abbreviate_name(name)
|
|
318
|
-
abbreviated_name = ''
|
|
319
|
-
name = name.join('') if name.is_a? Array
|
|
320
|
-
# make sure we handle "Cher" correctly
|
|
321
|
-
return name if !name.include?(' ') and !name.include?(',')
|
|
322
|
-
surnames_first = name.include?(',')
|
|
323
|
-
delimiter = surnames_first ? ', ' : ' '
|
|
324
|
-
name_segments = name.split(delimiter)
|
|
325
|
-
given_names = surnames_first ? name_segments.last.split(' ') : name_segments.first.split(' ')
|
|
326
|
-
surnames = surnames_first ? name_segments.first.split(' ') : name_segments.last.split(' ')
|
|
327
|
-
abbreviated_name << surnames.join(' ')
|
|
328
|
-
abbreviated_name << ', '
|
|
329
|
-
abbreviated_name << given_names.map { |n| "#{n[0]}." }.join if given_names.is_a? Array
|
|
330
|
-
abbreviated_name << "#{given_names[0]}." if given_names.is_a? String
|
|
331
|
-
abbreviated_name
|
|
332
|
-
end
|
|
333
|
-
|
|
334
|
-
def name_reverse(name)
|
|
335
|
-
name = clean_end_punctuation(name)
|
|
336
|
-
return name unless name =~ /,/
|
|
337
|
-
temp_name = name.split(", ")
|
|
338
|
-
return temp_name.last + " " + temp_name.first
|
|
339
|
-
end
|
|
340
|
-
|
|
341
|
-
end
|
|
342
|
-
end
|
|
343
|
-
end
|