sufia-models 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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.md +177 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/app/models/batch.rb +46 -0
- data/app/models/checksum_audit_log.rb +35 -0
- data/app/models/contact_form.rb +42 -0
- data/app/models/datastreams/batch_rdf_datastream.rb +23 -0
- data/app/models/datastreams/file_content_datastream.rb +18 -0
- data/app/models/datastreams/fits_datastream.rb +188 -0
- data/app/models/datastreams/generic_file_rdf_datastream.rb +75 -0
- data/app/models/datastreams/paranoid_rights_datastream.rb +37 -0
- data/app/models/datastreams/properties_datastream.rb +33 -0
- data/app/models/domain_term.rb +18 -0
- data/app/models/follow.rb +28 -0
- data/app/models/generic_file.rb +16 -0
- data/app/models/geo_names_resource.rb +34 -0
- data/app/models/group.rb +8 -0
- data/app/models/local_authority.rb +93 -0
- data/app/models/local_authority_entry.rb +18 -0
- data/app/models/single_use_link.rb +26 -0
- data/app/models/subject_local_authority_entry.rb +16 -0
- data/app/models/trophy.rb +12 -0
- data/app/models/version_committer.rb +17 -0
- data/lib/sufia/models.rb +11 -0
- data/lib/sufia/models/active_fedora/redis.rb +49 -0
- data/lib/sufia/models/active_record/redis.rb +56 -0
- data/lib/sufia/models/engine.rb +34 -0
- data/lib/sufia/models/file_content.rb +9 -0
- data/lib/sufia/models/file_content/extract_metadata.rb +60 -0
- data/lib/sufia/models/file_content/versions.rb +23 -0
- data/lib/sufia/models/generic_file.rb +183 -0
- data/lib/sufia/models/generic_file/actions.rb +39 -0
- data/lib/sufia/models/generic_file/audit.rb +119 -0
- data/lib/sufia/models/generic_file/characterization.rb +81 -0
- data/lib/sufia/models/generic_file/export.rb +339 -0
- data/lib/sufia/models/generic_file/permissions.rb +64 -0
- data/lib/sufia/models/generic_file/thumbnail.rb +91 -0
- data/lib/sufia/models/id_service.rb +57 -0
- data/lib/sufia/models/jobs/audit_job.rb +65 -0
- data/lib/sufia/models/jobs/batch_update_job.rb +86 -0
- data/lib/sufia/models/jobs/characterize_job.rb +43 -0
- data/lib/sufia/models/jobs/content_delete_event_job.rb +31 -0
- data/lib/sufia/models/jobs/content_deposit_event_job.rb +32 -0
- data/lib/sufia/models/jobs/content_new_version_event_job.rb +32 -0
- data/lib/sufia/models/jobs/content_restored_version_event_job.rb +40 -0
- data/lib/sufia/models/jobs/content_update_event_job.rb +32 -0
- data/lib/sufia/models/jobs/event_job.rb +33 -0
- data/lib/sufia/models/jobs/ffmpeg_transcode_job.rb +61 -0
- data/lib/sufia/models/jobs/resolrize_job.rb +23 -0
- data/lib/sufia/models/jobs/transcode_audio_job.rb +40 -0
- data/lib/sufia/models/jobs/transcode_video_job.rb +39 -0
- data/lib/sufia/models/jobs/unzip_job.rb +54 -0
- data/lib/sufia/models/jobs/user_edit_profile_event_job.rb +35 -0
- data/lib/sufia/models/jobs/user_follow_event_job.rb +37 -0
- data/lib/sufia/models/jobs/user_unfollow_event_job.rb +38 -0
- data/lib/sufia/models/model_methods.rb +39 -0
- data/lib/sufia/models/noid.rb +42 -0
- data/lib/sufia/models/solr_document_behavior.rb +125 -0
- data/lib/sufia/models/user.rb +126 -0
- data/lib/sufia/models/utils.rb +36 -0
- data/lib/sufia/models/version.rb +5 -0
- data/lib/tasks/sufia-models_tasks.rake +4 -0
- data/sufia-models.gemspec +28 -0
- metadata +151 -0
@@ -0,0 +1,119 @@
|
|
1
|
+
module Sufia
|
2
|
+
module GenericFile
|
3
|
+
module Audit
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
included do
|
6
|
+
end
|
7
|
+
|
8
|
+
NO_RUNS = 999
|
9
|
+
|
10
|
+
def audit(force = false)
|
11
|
+
logs = []
|
12
|
+
self.per_version do |ver|
|
13
|
+
logs << ::GenericFile.audit(ver, force)
|
14
|
+
end
|
15
|
+
logs
|
16
|
+
end
|
17
|
+
|
18
|
+
def per_version(&block)
|
19
|
+
self.datastreams.each do |dsid, ds|
|
20
|
+
ds.versions.each do |ver|
|
21
|
+
block.call(ver)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def logs(dsid)
|
27
|
+
ChecksumAuditLog.where(:dsid=>dsid, :pid=>self.pid).order('created_at desc, id desc')
|
28
|
+
end
|
29
|
+
|
30
|
+
def audit!
|
31
|
+
audit(true)
|
32
|
+
end
|
33
|
+
|
34
|
+
def audit_stat!
|
35
|
+
audit_stat(true)
|
36
|
+
end
|
37
|
+
|
38
|
+
def audit_stat(force = false)
|
39
|
+
logs = audit(force)
|
40
|
+
audit_results = logs.collect { |result| result["pass"] }
|
41
|
+
|
42
|
+
# check how many non runs we had
|
43
|
+
non_runs =audit_results.reduce(0) { |sum, value| (value == NO_RUNS) ? sum = sum+1 : sum }
|
44
|
+
if (non_runs == 0)
|
45
|
+
result =audit_results.reduce(true) { |sum, value| sum && value }
|
46
|
+
return result
|
47
|
+
elsif (non_runs < audit_results.length)
|
48
|
+
result =audit_results.reduce(true) { |sum, value| (value == NO_RUNS) ? sum : sum && value }
|
49
|
+
return 'Some audits have not been run, but the ones run were '+ ((result)? 'passing' : 'failing') + '.'
|
50
|
+
else
|
51
|
+
return 'Audits have not yet been run on this file.'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
module ClassMethods
|
57
|
+
def audit!(version)
|
58
|
+
::GenericFile.audit(version, true)
|
59
|
+
end
|
60
|
+
|
61
|
+
def audit(version, force = false)
|
62
|
+
latest_audit = self.find(version.pid).logs(version.dsid).first
|
63
|
+
unless force
|
64
|
+
return latest_audit unless ::GenericFile.needs_audit?(version, latest_audit)
|
65
|
+
end
|
66
|
+
# Resque.enqueue(AuditJob, version.pid, version.dsid, version.versionID)
|
67
|
+
Sufia.queue.push(AuditJob.new(version.pid, version.dsid, version.versionID))
|
68
|
+
|
69
|
+
# run the find just incase the job has finished already
|
70
|
+
latest_audit = self.find(version.pid).logs(version.dsid).first
|
71
|
+
latest_audit = ChecksumAuditLog.new(:pass=>NO_RUNS, :pid=>version.pid, :dsid=>version.dsid, :version=>version.versionID) unless latest_audit
|
72
|
+
return latest_audit
|
73
|
+
end
|
74
|
+
|
75
|
+
def needs_audit?(version, latest_audit)
|
76
|
+
if latest_audit and latest_audit.updated_at
|
77
|
+
#logger.debug "***AUDIT*** last audit = #{latest_audit.updated_at.to_date}"
|
78
|
+
days_since_last_audit = (DateTime.now - latest_audit.updated_at.to_date).to_i
|
79
|
+
#logger.debug "***AUDIT*** days since last audit: #{days_since_last_audit}"
|
80
|
+
if days_since_last_audit < Sufia::Engine.config.max_days_between_audits
|
81
|
+
#logger.debug "***AUDIT*** No audit needed for #{version.pid} #{version.versionID} (#{latest_audit.updated_at})"
|
82
|
+
return false
|
83
|
+
end
|
84
|
+
else
|
85
|
+
logger.warn "***AUDIT*** problem with audit log! Latest Audit is not nil, but updated_at is not set #{latest_audit}" unless latest_audit.nil?
|
86
|
+
end
|
87
|
+
#logger.info "***AUDIT*** Audit needed for #{version.pid} #{version.versionID}"
|
88
|
+
return true
|
89
|
+
end
|
90
|
+
|
91
|
+
def audit_everything(force = false)
|
92
|
+
::GenericFile.find_each do |gf|
|
93
|
+
gf.per_version do |ver|
|
94
|
+
::GenericFile.audit(ver, force)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def audit_everything!
|
100
|
+
::GenericFile.audit_everything(true)
|
101
|
+
end
|
102
|
+
|
103
|
+
def run_audit(version)
|
104
|
+
if version.dsChecksumValid
|
105
|
+
#logger.info "***AUDIT*** Audit passed for #{version.pid} #{version.versionID}"
|
106
|
+
passing = 1
|
107
|
+
ChecksumAuditLog.prune_history(version)
|
108
|
+
else
|
109
|
+
logger.warn "***AUDIT*** Audit failed for #{version.pid} #{version.versionID}"
|
110
|
+
passing = 0
|
111
|
+
end
|
112
|
+
check = ChecksumAuditLog.create!(:pass=>passing, :pid=>version.pid,
|
113
|
+
:dsid=>version.dsid, :version=>version.versionID)
|
114
|
+
return check
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'datastreams/fits_datastream'
|
2
|
+
module Sufia
|
3
|
+
module GenericFile
|
4
|
+
module Characterization
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
included do
|
7
|
+
has_metadata :name => "characterization", :type => FitsDatastream
|
8
|
+
delegate :mime_type, :to => :characterization, :unique => true
|
9
|
+
delegate_to :characterization, [:format_label, :file_size, :last_modified,
|
10
|
+
:filename, :original_checksum, :rights_basis,
|
11
|
+
:copyright_basis, :copyright_note,
|
12
|
+
:well_formed, :valid, :status_message,
|
13
|
+
:file_title, :file_author, :page_count,
|
14
|
+
:file_language, :word_count, :character_count,
|
15
|
+
:paragraph_count, :line_count, :table_count,
|
16
|
+
:graphics_count, :byte_order, :compression,
|
17
|
+
:width, :height, :color_space, :profile_name,
|
18
|
+
:profile_version, :orientation, :color_map,
|
19
|
+
:image_producer, :capture_device,
|
20
|
+
:scanning_software, :exif_version,
|
21
|
+
:gps_timestamp, :latitude, :longitude,
|
22
|
+
:character_set, :markup_basis,
|
23
|
+
:markup_language, :duration, :bit_depth,
|
24
|
+
:sample_rate, :channels, :data_format, :offset]
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
def characterize_if_changed
|
29
|
+
content_changed = self.content.changed?
|
30
|
+
yield
|
31
|
+
#logger.debug "DOING CHARACTERIZE ON #{self.pid}"
|
32
|
+
Sufia.queue.push(CharacterizeJob.new(self.pid)) if content_changed
|
33
|
+
end
|
34
|
+
|
35
|
+
## Extract the metadata from the content datastream and record it in the characterization datastream
|
36
|
+
def characterize
|
37
|
+
self.characterization.ng_xml = self.content.extract_metadata
|
38
|
+
self.append_metadata
|
39
|
+
self.filename = self.label
|
40
|
+
save unless self.new_object?
|
41
|
+
end
|
42
|
+
|
43
|
+
# Populate descMetadata with fields from FITS (e.g. Author from pdfs)
|
44
|
+
def append_metadata
|
45
|
+
terms = self.characterization_terms
|
46
|
+
Sufia::Engine.config.fits_to_desc_mapping.each_pair do |k, v|
|
47
|
+
if terms.has_key?(k)
|
48
|
+
# coerce to array to remove a conditional
|
49
|
+
terms[k] = [terms[k]] unless terms[k].is_a? Array
|
50
|
+
terms[k].each do |term_value|
|
51
|
+
proxy_term = self.send(v)
|
52
|
+
if proxy_term.kind_of?(Array)
|
53
|
+
proxy_term << term_value unless proxy_term.include?(term_value)
|
54
|
+
else
|
55
|
+
# these are single-valued terms which cannot be appended to
|
56
|
+
self.send("#{v}=", term_value)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def characterization_terms
|
64
|
+
h = {}
|
65
|
+
self.characterization.class.terminology.terms.each_pair do |k, v|
|
66
|
+
next unless v.respond_to? :proxied_term
|
67
|
+
term = v.proxied_term
|
68
|
+
begin
|
69
|
+
value = self.send(term.name)
|
70
|
+
h[term.name] = value unless value.empty?
|
71
|
+
rescue NoMethodError
|
72
|
+
next
|
73
|
+
end
|
74
|
+
end
|
75
|
+
h
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,339 @@
|
|
1
|
+
module Sufia
|
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
|
+
'%~' => Application.config.application_name,
|
25
|
+
'%W' => 'Penn State University'
|
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 = [values] unless values.is_a? Array
|
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
|
+
# MIME type: 'application/x-openurl-ctx-kev'
|
45
|
+
def export_as_openurl_ctx_kev
|
46
|
+
export_text = []
|
47
|
+
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"
|
48
|
+
field_map = {
|
49
|
+
:title => 'title',
|
50
|
+
:creator => 'creator',
|
51
|
+
:subject => 'subject',
|
52
|
+
:description => 'description',
|
53
|
+
:publisher => 'publisher',
|
54
|
+
:contributor => 'contributor',
|
55
|
+
:date_created => 'date',
|
56
|
+
:resource_type => 'format',
|
57
|
+
:identifier => 'identifier',
|
58
|
+
:language => 'language',
|
59
|
+
:tag => 'relation',
|
60
|
+
:based_near => 'coverage',
|
61
|
+
:rights => 'rights'
|
62
|
+
}
|
63
|
+
field_map.each do |element, kev|
|
64
|
+
values = self.send(element)
|
65
|
+
next if values.empty? or values.first.nil?
|
66
|
+
values.each do |value|
|
67
|
+
export_text << "rft.#{kev}=#{CGI::escape(value)}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
export_text.join('&') unless export_text.blank?
|
71
|
+
end
|
72
|
+
|
73
|
+
def export_as_apa_citation
|
74
|
+
text = ''
|
75
|
+
authors_list = []
|
76
|
+
authors_list_final = []
|
77
|
+
|
78
|
+
#setup formatted author list
|
79
|
+
authors = get_author_list
|
80
|
+
authors.each do |author|
|
81
|
+
next if author.blank?
|
82
|
+
authors_list.push(abbreviate_name(author))
|
83
|
+
end
|
84
|
+
authors_list.each do |author|
|
85
|
+
if author == authors_list.first #first
|
86
|
+
authors_list_final.push(author.strip)
|
87
|
+
elsif author == authors_list.last #last
|
88
|
+
authors_list_final.push(", & " + author.strip)
|
89
|
+
else #all others
|
90
|
+
authors_list_final.push(", " + author.strip)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
text << authors_list_final.join
|
94
|
+
unless text.blank?
|
95
|
+
if text[-1,1] != "."
|
96
|
+
text << ". "
|
97
|
+
else
|
98
|
+
text << " "
|
99
|
+
end
|
100
|
+
end
|
101
|
+
# Get Pub Date
|
102
|
+
text << "(" + setup_pub_date + "). " unless setup_pub_date.nil?
|
103
|
+
|
104
|
+
# setup title info
|
105
|
+
title_info = setup_title_info
|
106
|
+
text << "<i>" + title_info + "</i> " unless title_info.nil?
|
107
|
+
|
108
|
+
# Publisher info
|
109
|
+
text << setup_pub_info unless setup_pub_info.nil?
|
110
|
+
unless text.blank?
|
111
|
+
if text[-1,1] != "."
|
112
|
+
text += "."
|
113
|
+
end
|
114
|
+
end
|
115
|
+
text.html_safe
|
116
|
+
end
|
117
|
+
|
118
|
+
def export_as_mla_citation
|
119
|
+
text = ''
|
120
|
+
authors_final = []
|
121
|
+
|
122
|
+
#setup formatted author list
|
123
|
+
authors = get_author_list
|
124
|
+
|
125
|
+
if authors.length < 4
|
126
|
+
authors.each do |author|
|
127
|
+
if author == authors.first #first
|
128
|
+
authors_final.push(author)
|
129
|
+
elsif author == authors.last #last
|
130
|
+
authors_final.push(", and " + name_reverse(author) + ".")
|
131
|
+
else #all others
|
132
|
+
authors_final.push(", " + name_reverse(author))
|
133
|
+
end
|
134
|
+
end
|
135
|
+
text << authors_final.join
|
136
|
+
unless text.blank?
|
137
|
+
if text[-1,1] != "."
|
138
|
+
text << ". "
|
139
|
+
else
|
140
|
+
text << " "
|
141
|
+
end
|
142
|
+
end
|
143
|
+
else
|
144
|
+
text << authors.first + ", et al. "
|
145
|
+
end
|
146
|
+
# setup title
|
147
|
+
title_info = setup_title_info
|
148
|
+
text << "<i>" + mla_citation_title(title_info) + "</i> " unless title.blank?
|
149
|
+
|
150
|
+
# Publication
|
151
|
+
text << setup_pub_info + ", " unless setup_pub_info.nil?
|
152
|
+
|
153
|
+
# Get Pub Date
|
154
|
+
text << setup_pub_date unless setup_pub_date.nil?
|
155
|
+
if text[-1,1] != "."
|
156
|
+
text << "." unless text.blank?
|
157
|
+
end
|
158
|
+
text.html_safe
|
159
|
+
end
|
160
|
+
|
161
|
+
def export_as_chicago_citation
|
162
|
+
author_text = ""
|
163
|
+
authors = get_all_authors
|
164
|
+
unless authors.blank?
|
165
|
+
if authors.length > 10
|
166
|
+
authors.each_with_index do |author, index|
|
167
|
+
if index < 7
|
168
|
+
if index == 0
|
169
|
+
author_text << "#{author}"
|
170
|
+
if author.ends_with?(",")
|
171
|
+
author_text << " "
|
172
|
+
else
|
173
|
+
author_text << ", "
|
174
|
+
end
|
175
|
+
else
|
176
|
+
author_text << "#{name_reverse(author)}, "
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
author_text << " et al."
|
181
|
+
elsif authors.length > 1
|
182
|
+
authors.each_with_index do |author,index|
|
183
|
+
if index == 0
|
184
|
+
author_text << "#{author}"
|
185
|
+
if author.ends_with?(",")
|
186
|
+
author_text << " "
|
187
|
+
else
|
188
|
+
author_text << ", "
|
189
|
+
end
|
190
|
+
elsif index + 1 == authors.length
|
191
|
+
author_text << "and #{name_reverse(author)}."
|
192
|
+
else
|
193
|
+
author_text << "#{name_reverse(author)}, "
|
194
|
+
end
|
195
|
+
end
|
196
|
+
else
|
197
|
+
author_text << authors.first
|
198
|
+
end
|
199
|
+
end
|
200
|
+
title_info = ""
|
201
|
+
title_info << citation_title(clean_end_punctuation(CGI::escapeHTML(title.first)).strip) unless title.blank?
|
202
|
+
|
203
|
+
pub_info = ""
|
204
|
+
place = self.based_near.first
|
205
|
+
publisher = self.publisher.first
|
206
|
+
unless place.blank?
|
207
|
+
place = CGI::escapeHTML(place)
|
208
|
+
pub_info << place
|
209
|
+
pub_info << ": " unless publisher.blank?
|
210
|
+
end
|
211
|
+
unless publisher.blank?
|
212
|
+
publisher = CGI::escapeHTML(publisher)
|
213
|
+
pub_info << publisher
|
214
|
+
pub_info << ", " unless setup_pub_date.nil?
|
215
|
+
end
|
216
|
+
unless setup_pub_date.nil?
|
217
|
+
pub_info << setup_pub_date
|
218
|
+
end
|
219
|
+
|
220
|
+
citation = ""
|
221
|
+
citation << "#{author_text} " unless author_text.blank?
|
222
|
+
citation << "<i>#{title_info}.</i> " unless title_info.blank?
|
223
|
+
citation << "#{pub_info}." unless pub_info.blank?
|
224
|
+
citation.html_safe
|
225
|
+
end
|
226
|
+
|
227
|
+
private
|
228
|
+
|
229
|
+
def setup_pub_date
|
230
|
+
first_date = self.date_created.first
|
231
|
+
unless first_date.blank?
|
232
|
+
first_date = CGI::escapeHTML(first_date)
|
233
|
+
date_value = first_date.gsub(/[^0-9|n\.d\.]/, "")[0,4]
|
234
|
+
return nil if date_value.nil?
|
235
|
+
end
|
236
|
+
clean_end_punctuation(date_value) if date_value
|
237
|
+
end
|
238
|
+
|
239
|
+
def setup_pub_info
|
240
|
+
text = ''
|
241
|
+
place = self.based_near.first
|
242
|
+
publisher = self.publisher.first
|
243
|
+
unless place.blank?
|
244
|
+
place = CGI::escapeHTML(place)
|
245
|
+
text << place
|
246
|
+
text << ": " unless publisher.blank?
|
247
|
+
end
|
248
|
+
unless publisher.blank?
|
249
|
+
publisher = CGI::escapeHTML(publisher)
|
250
|
+
text << publisher
|
251
|
+
end
|
252
|
+
return nil if text.strip.blank?
|
253
|
+
clean_end_punctuation(text.strip)
|
254
|
+
end
|
255
|
+
|
256
|
+
def mla_citation_title(text)
|
257
|
+
no_upcase = ["a","an","and","but","by","for","it","of","the","to","with"]
|
258
|
+
new_text = []
|
259
|
+
word_parts = text.split(" ")
|
260
|
+
word_parts.each do |w|
|
261
|
+
if !no_upcase.include? w
|
262
|
+
new_text.push(w.capitalize)
|
263
|
+
else
|
264
|
+
new_text.push(w)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
new_text.join(" ")
|
268
|
+
end
|
269
|
+
|
270
|
+
def citation_title(title_text)
|
271
|
+
prepositions = ["a","about","across","an","and","before","but","by","for","it","of","the","to","with","without"]
|
272
|
+
new_text = []
|
273
|
+
title_text.split(" ").each_with_index do |word,index|
|
274
|
+
if (index == 0 and word != word.upcase) or (word.length > 1 and word != word.upcase and !prepositions.include?(word))
|
275
|
+
# the split("-") will handle the capitalization of hyphenated words
|
276
|
+
new_text << word.split("-").map!{|w| w.capitalize }.join("-")
|
277
|
+
else
|
278
|
+
new_text << word
|
279
|
+
end
|
280
|
+
end
|
281
|
+
new_text.join(" ")
|
282
|
+
end
|
283
|
+
|
284
|
+
def setup_title_info
|
285
|
+
text = ''
|
286
|
+
title = self.title.first
|
287
|
+
unless title.blank?
|
288
|
+
title = CGI::escapeHTML(title)
|
289
|
+
title_info = clean_end_punctuation(title.strip)
|
290
|
+
text << title_info
|
291
|
+
end
|
292
|
+
|
293
|
+
return nil if text.strip.blank?
|
294
|
+
clean_end_punctuation(text.strip) + "."
|
295
|
+
end
|
296
|
+
|
297
|
+
def clean_end_punctuation(text)
|
298
|
+
if [".",",",":",";","/"].include? text[-1,1]
|
299
|
+
return text[0,text.length-1]
|
300
|
+
end
|
301
|
+
text
|
302
|
+
end
|
303
|
+
|
304
|
+
def get_author_list
|
305
|
+
self.creator.map { |author| clean_end_punctuation(CGI::escapeHTML(author)) }.uniq
|
306
|
+
end
|
307
|
+
|
308
|
+
def get_all_authors
|
309
|
+
authors = self.creator
|
310
|
+
return authors.empty? ? nil : authors.map { |author| CGI::escapeHTML(author) }
|
311
|
+
end
|
312
|
+
|
313
|
+
def abbreviate_name(name)
|
314
|
+
abbreviated_name = ''
|
315
|
+
name = name.join('') if name.is_a? Array
|
316
|
+
# make sure we handle "Cher" correctly
|
317
|
+
return name if !name.include?(' ') and !name.include?(',')
|
318
|
+
surnames_first = name.include?(',')
|
319
|
+
delimiter = surnames_first ? ', ' : ' '
|
320
|
+
name_segments = name.split(delimiter)
|
321
|
+
given_names = surnames_first ? name_segments.last.split(' ') : name_segments.first.split(' ')
|
322
|
+
surnames = surnames_first ? name_segments.first.split(' ') : name_segments.last.split(' ')
|
323
|
+
abbreviated_name << surnames.join(' ')
|
324
|
+
abbreviated_name << ', '
|
325
|
+
abbreviated_name << given_names.map { |n| "#{n[0]}." }.join if given_names.is_a? Array
|
326
|
+
abbreviated_name << "#{given_names[0]}." if given_names.is_a? String
|
327
|
+
abbreviated_name
|
328
|
+
end
|
329
|
+
|
330
|
+
def name_reverse(name)
|
331
|
+
name = clean_end_punctuation(name)
|
332
|
+
return name unless name =~ /,/
|
333
|
+
temp_name = name.split(", ")
|
334
|
+
return temp_name.last + " " + temp_name.first
|
335
|
+
end
|
336
|
+
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end
|