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.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -0
  3. data/Rakefile +1 -1
  4. data/app/actors/concerns/curation_concerns/manages_embargoes_actor.rb +11 -19
  5. data/app/actors/curation_concerns/base_actor.rb +41 -45
  6. data/app/actors/curation_concerns/embargo_actor.rb +19 -0
  7. data/app/actors/curation_concerns/file_set_actor.rb +200 -0
  8. data/app/actors/curation_concerns/lease_actor.rb +19 -0
  9. data/app/actors/curation_concerns/work_actor_behavior.rb +55 -58
  10. data/app/indexers/curation_concerns/collection_indexer.rb +10 -0
  11. data/app/indexers/curation_concerns/file_set_indexing_service.rb +24 -0
  12. data/app/{services/curation_concerns/generic_work_indexing_service.rb → indexers/curation_concerns/work_indexing_service.rb} +6 -6
  13. data/app/jobs/active_fedora_id_based_job.rb +5 -12
  14. data/app/jobs/audit_job.rb +11 -17
  15. data/app/jobs/characterize_job.rb +8 -7
  16. data/app/jobs/create_derivatives_job.rb +8 -11
  17. data/app/jobs/import_url_job.rb +12 -25
  18. data/app/jobs/ingest_file_job.rb +16 -0
  19. data/app/jobs/ingest_local_file_job.rb +14 -35
  20. data/app/jobs/resolrize_job.rb +3 -5
  21. data/app/jobs/upload_set_update_job.rb +68 -0
  22. data/app/models/checksum_audit_log.rb +2 -3
  23. data/app/models/concerns/curation_concerns/ability.rb +18 -10
  24. data/app/models/concerns/curation_concerns/basic_metadata.rb +1 -3
  25. data/app/models/concerns/curation_concerns/collection_behavior.rb +13 -14
  26. data/app/models/concerns/curation_concerns/file_set/belongs_to_upload_sets.rb +15 -0
  27. data/app/models/concerns/curation_concerns/{generic_file → file_set}/belongs_to_works.rb +8 -14
  28. data/app/models/concerns/curation_concerns/file_set/derivatives.rb +54 -0
  29. data/app/models/concerns/curation_concerns/{generic_file → file_set}/full_text_indexing.rb +1 -2
  30. data/app/models/concerns/curation_concerns/{generic_file → file_set}/indexing.rb +2 -2
  31. data/app/models/concerns/curation_concerns/{generic_file → file_set}/versions.rb +2 -3
  32. data/app/models/concerns/curation_concerns/file_set_behavior.rb +36 -0
  33. data/app/models/concerns/curation_concerns/generic_file.rb +1 -1
  34. data/app/models/concerns/curation_concerns/has_representative.rb +6 -7
  35. data/app/models/concerns/curation_concerns/human_readable_type.rb +5 -7
  36. data/app/models/concerns/curation_concerns/permissions.rb +2 -2
  37. data/app/models/concerns/curation_concerns/permissions/readable.rb +0 -1
  38. data/app/models/concerns/curation_concerns/permissions/writable.rb +10 -51
  39. data/app/models/concerns/curation_concerns/serializers.rb +3 -5
  40. data/app/models/concerns/curation_concerns/solr_document_behavior.rb +37 -40
  41. data/app/models/concerns/curation_concerns/upload_set_behavior.rb +38 -0
  42. data/app/models/concerns/curation_concerns/user.rb +4 -51
  43. data/app/models/concerns/curation_concerns/with_file_sets.rb +28 -0
  44. data/app/models/concerns/curation_concerns/{generic_work_behavior.rb → work_behavior.rb} +12 -6
  45. data/app/models/curation_concerns/classify_concern.rb +7 -7
  46. data/app/models/curation_concerns/quick_classification_query.rb +6 -7
  47. data/app/models/single_use_link.rb +34 -0
  48. data/app/models/upload_set.rb +3 -0
  49. data/app/services/curation_concerns/derivative_path.rb +32 -0
  50. data/app/services/curation_concerns/{generic_file_audit_service.rb → file_set_audit_service.rb} +17 -18
  51. data/app/services/curation_concerns/indexes_thumbnails.rb +14 -0
  52. data/app/services/curation_concerns/local_file_service.rb +10 -0
  53. data/app/services/curation_concerns/lock_manager.rb +40 -0
  54. data/app/services/curation_concerns/noid.rb +1 -1
  55. data/app/services/curation_concerns/persist_derivatives.rb +33 -0
  56. data/app/services/curation_concerns/persist_directly_contained_output_file_service.rb +26 -0
  57. data/app/services/curation_concerns/repository_audit_service.rb +1 -3
  58. data/app/services/curation_concerns/thumbnail_path_service.rb +46 -0
  59. data/app/services/curation_concerns/time_service.rb +7 -0
  60. data/app/services/curation_concerns/versioning_service.rb +11 -12
  61. data/curation_concerns-models.gemspec +6 -6
  62. data/lib/curation_concerns/configuration.rb +154 -0
  63. data/lib/curation_concerns/messages.rb +26 -26
  64. data/lib/curation_concerns/models.rb +5 -14
  65. data/lib/curation_concerns/models/engine.rb +0 -30
  66. data/lib/curation_concerns/models/utils.rb +4 -4
  67. data/lib/curation_concerns/models/version.rb +1 -1
  68. data/lib/generators/curation_concerns/models/abstract_migration_generator.rb +8 -7
  69. data/lib/generators/curation_concerns/models/clamav_generator.rb +3 -3
  70. data/lib/generators/curation_concerns/models/install_generator.rb +13 -20
  71. data/lib/generators/curation_concerns/models/templates/app/models/file_set.rb +4 -0
  72. data/lib/generators/curation_concerns/models/templates/config/clamav.rb +1 -1
  73. data/lib/generators/curation_concerns/models/templates/config/curation_concerns.rb +52 -65
  74. data/lib/generators/curation_concerns/models/templates/config/redis_config.rb +13 -17
  75. data/lib/generators/curation_concerns/models/templates/config/resque_config.rb +2 -1
  76. data/lib/generators/curation_concerns/models/templates/migrations/create_checksum_audit_logs.rb +3 -3
  77. data/lib/generators/curation_concerns/models/templates/migrations/create_single_use_links.rb +12 -0
  78. data/lib/tasks/curation_concerns-models_tasks.rake +4 -62
  79. data/lib/tasks/migrate.rake +1 -1
  80. data/lib/tasks/resque.rake +1 -0
  81. data/lib/tasks/solr_reindex.rake +1 -1
  82. metadata +59 -52
  83. data/app/actors/curation_concerns/generic_file_actor.rb +0 -150
  84. data/app/jobs/active_fedora_pid_based_job.rb +0 -6
  85. data/app/jobs/copy_permissions_job.rb +0 -24
  86. data/app/models/concerns/curation_concerns/generic_file/characterization.rb +0 -89
  87. data/app/models/concerns/curation_concerns/generic_file/content.rb +0 -8
  88. data/app/models/concerns/curation_concerns/generic_file/export.rb +0 -343
  89. data/app/models/concerns/curation_concerns/generic_file_behavior.rb +0 -44
  90. data/app/models/concerns/curation_concerns/with_basic_metadata.rb +0 -98
  91. data/app/models/concerns/curation_concerns/with_generic_files.rb +0 -29
  92. data/app/models/datastreams/fits_datastream.rb +0 -148
  93. data/app/services/curation_concerns/characterization_service.rb +0 -71
  94. data/app/services/curation_concerns/full_text_extraction_service.rb +0 -38
  95. data/app/services/curation_concerns/generic_file_indexing_service.rb +0 -14
  96. data/lib/curation_concerns/models/resque.rb +0 -36
  97. data/lib/generators/curation_concerns/models/fulltext_generator.rb +0 -28
  98. data/lib/generators/curation_concerns/models/templates/app/models/generic_file.rb +0 -4
  99. 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,6 +0,0 @@
1
- class ActiveFedoraPidBasedJob < ActiveFedoraIdBasedJob
2
- extend Deprecation
3
- def self.extended(document)
4
- Deprecation.warn ActiveFedoraPidBasedJob, "ActiveFedoraPidBasedJob is deprecated; use ActiveFedoraIdBasedJob instead."
5
- end
6
- 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,8 +0,0 @@
1
- module CurationConcerns
2
- module GenericFile
3
- module Content
4
- extend ActiveSupport::Concern
5
-
6
- end
7
- end
8
- 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(", &amp; " + 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