Class: Document

Inherits:
Kithe::Work
  • Object
show all
Includes:
ActiveModel::Validations, AttrJson::Record::QueryScopes
Defined in:
app/models/document.rb,
app/models/document/reference.rb,
app/models/document/bbox_validator.rb,
app/models/document/date_validator.rb,
app/models/document/geom_validator.rb,
app/models/document/controlled_lists.rb,
app/models/document/date_range_validator.rb

Overview

Date Range Validation

Allow: YYYY-YYYY, *-YYYY, YYYY-*, Start YYYY == End YYYY Disallow: YYYX-YYYY, YYYY-, 2000-1999, YYYY-YYYY?

Defined Under Namespace

Classes: BboxValidator, ControlledLists, DateRangeValidator, DateValidator, GeomValidator, Reference

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#skip_callbacksObject

Returns the value of attribute skip_callbacks.



15
16
17
# File 'app/models/document.rb', line 15

def skip_callbacks
  @skip_callbacks
end

Instance Method Details

#a_downloadable_resource?Boolean

Downloadable Resouce

Returns:

  • (Boolean)


91
92
93
# File 'app/models/document.rb', line 91

def a_downloadable_resource?
  distributions_json.include?("downloadUrl")
end

#access_jsonObject



402
403
404
405
406
# File 'app/models/document.rb', line 402

def access_json
  access = {}
  access_urls.each { |au| access[au.institution_code] = au.access_url }
  access.to_json
end

#access_urlsObject

Institutional Access URLs



480
481
482
# File 'app/models/document.rb', line 480

def access_urls
  DocumentAccess.where(friendlier_id: friendlier_id).order(institution_code: :asc)
end

#apply_assets(distributions) ⇒ Object



214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'app/models/document.rb', line 214

def apply_assets(distributions)
  # Distributable Document Assets
  # - Via DocumentAssets (Assets)
  # - With Downloadable URI
  if distributable_assets.present?
    distributable_assets.each do |asset|
      if asset.dct_references_uri_key == "download"
        distributions["http://schema.org/downloadUrl"] ||= []
        distributions["http://schema.org/downloadUrl"] << asset.to_aardvark_reference["http://schema.org/downloadUrl"]
      else
        distributions.merge!(asset.to_aardvark_reference)
      end
    end
  end

  distributions
end

#apply_downloads(distributions) ⇒ Object

BEFORE - Apply Downloads @TODO: Remove this once we’ve migrated to DocumentDistributions

  1. Native Aardvark Downloads

  2. Multiple Document Download Links

  3. Downloadable Document Assets



237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
# File 'app/models/document.rb', line 237

def apply_downloads(distributions)
  multiple_downloads = []

  dct_downloads = distributions["http://schema.org/downloadUrl"]

  logger.debug("Document#dct_downloads > init: #{dct_downloads}\n\n")

  # Native Aardvark Downloads
  # - Via CSV Import or via the webform
  if dct_downloads.present?
    dct_downloads.each do |download|
      multiple_downloads << {label: download_text(send(GeoblacklightAdmin::Schema.instance.solr_fields[:format])),
                            url: download}
    end
  end

  logger.debug("Document#multiple_downloads > aardvark: #{multiple_downloads.inspect}\n\n")

  # Multiple Document Download Links
  # - Via DocumentDownloads
  if document_downloads.present?
    multiple_downloads_array.each do |download|
      multiple_downloads << download
    end
  end

  logger.debug("Document#dct_downloads > document_downloads: #{multiple_downloads.inspect}\n\n")

  multiple_downloads = multiple_downloads.uniq { |d| [d[:label], d[:url]] } unless multiple_downloads.empty?

  distributions[:"http://schema.org/downloadUrl"] = multiple_downloads.flatten unless multiple_downloads.empty?
  distributions
end

#asset_label(asset) ⇒ Object



206
207
208
209
210
211
212
# File 'app/models/document.rb', line 206

def asset_label(asset)
  if asset.label.present?
    asset.label
  else
    asset.title
  end
end

#available?Boolean

GBL SolrDocument convience methods

Returns:

  • (Boolean)


302
303
304
# File 'app/models/document.rb', line 302

def available?
  public? || same_institution?
end

#checked_endpoint(type) ⇒ Object

Provides a convenience method to access a SolrDocument’s References endpoint url without having to check and see if it is available :type => a string which if its a Geoblacklight::Constants::URI key

will return a coresponding Geoblacklight::Reference


390
391
392
393
# File 'app/models/document.rb', line 390

def checked_endpoint(type)
  type = distributions.send(type)
  type.endpoint if type.present?
end

#created_at_dtObject



408
409
410
# File 'app/models/document.rb', line 408

def created_at_dt
  created_at&.utc&.iso8601
end

#current_versionObject



474
475
476
477
# File 'app/models/document.rb', line 474

def current_version
  # Will return 0 if no PaperTrail version exists yet
  versions&.last&.index || 0
end

#data_dictionary_downloadObject



356
357
358
# File 'app/models/document.rb', line 356

def data_dictionary_download
  distributions.data_dictionary.to_hash if distributions.data_dictionary.present?
end

#date_range_jsonObject



421
422
423
424
425
426
427
428
429
430
431
432
# File 'app/models/document.rb', line 421

def date_range_json
  date_ranges = []
  unless send(GeoblacklightAdmin::Schema.instance.solr_fields[:date_range]).all?(&:blank?)
    send(GeoblacklightAdmin::Schema.instance.solr_fields[:date_range]).each do |date_range|
      start_d, end_d = date_range.split("-")
      start_d = "*" if start_d == "YYYY" || start_d.nil?
      end_d = "*" if end_d == "YYYY" || end_d.nil?
      date_ranges << "[#{start_d} TO #{end_d}]" if start_d.present?
    end
  end
  date_ranges
end

#dct_references_s_to_csv(key, destination) ⇒ Object



466
467
468
469
470
471
472
# File 'app/models/document.rb', line 466

def dct_references_s_to_csv(key, destination)
  send(destination).detect do |ref|
    ref.category == GeoblacklightAdmin::Schema.instance.dct_references_mappings[key]
  end.value
rescue NoMethodError
  nil
end

#dct_title_sObject

Ensures a manually created “title” makes it into the attr_json “title”



417
418
419
# File 'app/models/document.rb', line 417

def dct_title_s
  title
end

#derive_dcat_bboxObject

Convert GEOM for Solr Indexing



517
518
519
520
521
522
523
524
525
# File 'app/models/document.rb', line 517

def derive_dcat_bbox
  if send(GeoblacklightAdmin::Schema.instance.solr_fields[:bounding_box]).present?
    # "W,S,E,N" convert to "ENVELOPE(W,E,N,S)"
    w, s, e, n = send(GeoblacklightAdmin::Schema.instance.solr_fields[:bounding_box]).split(",")
    "ENVELOPE(#{w},#{e},#{n},#{s})"
  else
    ""
  end
end

#derive_dcat_centroidObject



527
528
529
530
531
532
533
534
# File 'app/models/document.rb', line 527

def derive_dcat_centroid
  if send(GeoblacklightAdmin::Schema.instance.solr_fields[:bounding_box]).present?
    w, s, e, n = send(GeoblacklightAdmin::Schema.instance.solr_fields[:bounding_box]).split(",")
    "#{(n.to_f + s.to_f) / 2},#{(e.to_f + w.to_f) / 2}"
  else
    ""
  end
end

#derive_locn_geometryObject



484
485
486
487
488
489
490
491
492
# File 'app/models/document.rb', line 484

def derive_locn_geometry
  if send(GeoblacklightAdmin::Schema.instance.solr_fields[:geometry]).present?
    send(GeoblacklightAdmin::Schema.instance.solr_fields[:geometry])
  elsif send(GeoblacklightAdmin::Schema.instance.solr_fields[:bounding_box]).present?
    derive_polygon
  else
    ""
  end
end

#derive_polygonObject

Convert BBOX to GEOM Polygon



495
496
497
498
499
500
501
502
503
504
505
506
507
508
# File 'app/models/document.rb', line 495

def derive_polygon
  if send(GeoblacklightAdmin::Schema.instance.solr_fields[:bounding_box]).present?
    # Guard against a whole world polygons
    if send(GeoblacklightAdmin::Schema.instance.solr_fields[:bounding_box]) == "-180,-90,180,90"
      "ENVELOPE(-180,180,90,-90)"
    else
      # "W,S,E,N" convert to "POLYGON((W N, E N, E S, W S, W N))"
      w, s, e, n = send(GeoblacklightAdmin::Schema.instance.solr_fields[:bounding_box]).split(",")
      "POLYGON((#{w} #{n}, #{e} #{n}, #{e} #{s}, #{w} #{s}, #{w} #{n}))"
    end
  else
    ""
  end
end

#direct_downloadObject



331
332
333
# File 'app/models/document.rb', line 331

def direct_download
  distributions.download.to_hash if distributions.download.present?
end

#display_noteObject



335
336
337
# File 'app/models/document.rb', line 335

def display_note
  send(Settings.FIELDS.DISPLAY_NOTE) || ""
end

#distributable_assetsObject



49
50
51
# File 'app/models/document.rb', line 49

def distributable_assets
  document_assets.select { |a| a.dct_references_uri_key.present? }
end

#distributionsObject

Distributions

  • BEFORE DocumentDistributions

    • Use dct_references_s

    • Use multiple downloads

    • Use distributable assets

  • AFTER DocumentDistributions

    • Use document_distributions

    • Use distributable assets

@TODO: Remove BEFORE path once we’ve migrated to DocumentDistributions



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'app/models/document.rb', line 124

def distributions
  distributions = {}

  # AFTER - Add DocumentDistributions to distributions
  if ENV["GBL_ADMIN_REFERENCES_MIGRATED"] == "true"
    distributions = document_distributions.to_aardvark_distributions
  else
    # BEFORE - Prep value arrays
    # @TODO: Remove this once we've migrated to DocumentDistributions
    send(GeoblacklightAdmin::Schema.instance.solr_fields[:reference]).each do |ref|
      if ref.category.present?
        distributions[Document::Reference::REFERENCE_VALUES[ref.category.to_sym][:uri]] = []
      end
    end

    # BEFORE - Seed value arrays
    # @TODO: Remove this once we've migrated to DocumentDistributions
    send(GeoblacklightAdmin::Schema.instance.solr_fields[:reference]).each do |ref|
      if ref.category.present?
        distributions[Document::Reference::REFERENCE_VALUES[ref.category.to_sym][:uri]] << ref.value
      end
    end
    logger.debug("\n\nDocument#distributions > seeded: #{distributions}")

    # BEFORE - Apply Multiple Downloads
    # @TODO: Remove this once we've migrated to DocumentDistributions
    if ENV["GBL_ADMIN_REFERENCES_MIGRATED"] == "false"
      distributions = apply_downloads(distributions)
      logger.debug("Document#distributions > downloads: #{distributions}")
    end
  end

  # BEFORE & AFTER - Apply Distributable Assets
  distributions = apply_assets(distributions)
  logger.debug("Document#distributions > assets: #{distributions}")

  # Need to flatten the arrays here to avoid the following potential error:
  # - ArgumentError: Please use symbols for polymorphic route arguments.
  # - Via: app/helpers/geoblacklight_helper.rb:224:in `render_references_url'
  distributions.each do |key, value|
    next if key == "http://schema.org/downloadUrl"
    if value.is_a?(Array) && value.length == 1
      distributions[key] = value.first
    end
  end

  distributions
end

#distributions_csvObject



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'app/models/document.rb', line 189

def distributions_csv
  # Initialize CSV
  # - [document_id, category, value, label]
  csv = []

  distributions.each do |key, value|
    if key == "http://schema.org/downloadUrl"
      value.each do |download|
        csv << [friendlier_id, ReferenceType.find_by(reference_uri: key).name, download["url"], download["label"]]
      end
    else
      csv << [friendlier_id, ReferenceType.find_by(reference_uri: key)&.name, value, nil]
    end
  end
  csv
end

#distributions_jsonObject

Distributions JSON

  • Indexes to Solr as dct_distributions_s



175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'app/models/document.rb', line 175

def distributions_json
  if ENV["GBL_ADMIN_REFERENCES_MIGRATED"] == "true"
    logger.debug("Document#distributions_json > using document_distributions")
    distributions = document_distributions.to_aardvark_distributions
    distributions = apply_assets(distributions)
    distributions.to_json
  else
    logger.debug("Document#distributions > #{distributions.inspect}")
    logger.debug("Document#distributions_json > using distributions")
    logger.warn("Deprecation warning: AttrJSON-based dct_references_s will not be supported soon.")
    self.distributions.to_json
  end
end

#document_assetsObject

DocumentAssets - Thumbnails, Attachments, etc @TODO: Redundant? Kithe also includes a members association



43
44
45
46
47
# File 'app/models/document.rb', line 43

def document_assets
  scope = Kithe::Asset
  scope = scope.where(parent_id: id).order(position: :asc)
  scope.includes(:parent)
end

#download_text(format) ⇒ Object

Wraps download text with proper_case_format



292
293
294
295
296
297
# File 'app/models/document.rb', line 292

def download_text(format)
  download_format = proper_case_format(format)
  download_format.to_s.html_safe
rescue
  format.to_s.html_safe
end

#downloadable?Boolean

Returns:

  • (Boolean)


327
328
329
# File 'app/models/document.rb', line 327

def downloadable?
  (direct_download || download_types.present? || iiif_download) && available?
end

#external_urlObject



360
361
362
# File 'app/models/document.rb', line 360

def external_url
  distributions.url&.endpoint
end

#file_formatObject



381
382
383
# File 'app/models/document.rb', line 381

def file_format
  send(Settings.FIELDS.FORMAT) || ""
end

#gbl_mdModified_dtObject



412
413
414
# File 'app/models/document.rb', line 412

def gbl_mdModified_dt
  updated_at&.utc&.iso8601
end

#geom_fieldObject



368
369
370
# File 'app/models/document.rb', line 368

def geom_field
  send(Settings.FIELDS.GEOMETRY) || ""
end

#geometryObject



372
373
374
375
# File 'app/models/document.rb', line 372

def geometry
  # @TODO
  # @geometry ||= Geoblacklight::Geometry.new(geom_field)
end

#hgl_downloadObject



339
340
341
# File 'app/models/document.rb', line 339

def hgl_download
  distributions.hgl.to_hash if distributions.hgl.present?
end

#iiif_downloadObject



352
353
354
# File 'app/models/document.rb', line 352

def iiif_download
  distributions.iiif.to_hash if distributions.iiif.present?
end

#iso_language_mappingObject

Convert three char language code to proper string



537
538
539
540
541
542
543
544
545
546
# File 'app/models/document.rb', line 537

def iso_language_mapping
  mapping = []

  if send(GeoblacklightAdmin::Schema.instance.solr_fields[:language]).present?
    send(GeoblacklightAdmin::Schema.instance.solr_fields[:language]).each do |lang|
      mapping << GeoblacklightAdmin::IsoLanguageCodes.call[lang]
    end
  end
  mapping
end

#item_viewerObject



11
12
13
# File 'app/models/document.rb', line 11

def item_viewer
  GeoblacklightAdmin::ItemViewer.new(distributions)
end

#itemtypeObject



364
365
366
# File 'app/models/document.rb', line 364

def itemtype
  "http://schema.org/Dataset"
end

#local?Boolean

Returns:

  • (Boolean)


314
315
316
317
# File 'app/models/document.rb', line 314

def local?
  local = send(Settings.FIELDS.PROVIDER) || ""
  local.casecmp(Settings.INSTITUTION)&.zero?
end

#local_restricted?Boolean

Returns:

  • (Boolean)


310
311
312
# File 'app/models/document.rb', line 310

def local_restricted?
  local? && restricted?
end

#multiple_downloads_arrayObject

BEFORE - Multiple Downloads Array @TODO: Remove this once we’ve migrated to DocumentDistributions



273
274
275
# File 'app/models/document.rb', line 273

def multiple_downloads_array
  document_downloads.collect { |d| {label: d.label, url: d.value} }
end

#oembedObject



343
344
345
# File 'app/models/document.rb', line 343

def oembed
  distributions.oembed.endpoint if distributions.oembed.present?
end

#proper_case_format(format) ⇒ Object

From GBL

Looks up properly formatted names for formats



281
282
283
284
285
286
287
# File 'app/models/document.rb', line 281

def proper_case_format(format)
  if I18n.exists?("geoblacklight.formats.#{format.to_s.parameterize(separator: "_")}")
    I18n.t("geoblacklight.formats.#{format.to_s.parameterize(separator: "_")}")
  else
    format
  end
end

#public?Boolean

Returns:

  • (Boolean)


306
307
308
# File 'app/models/document.rb', line 306

def public?
  rights_field_data.present? && rights_field_data.casecmp("public").zero?
end

#raw_solr_documentObject



72
73
74
# File 'app/models/document.rb', line 72

def raw_solr_document
  Blacklight.default_index.connection.get("select", {params: {q: "id:\"#{geomg_id_s}\""}})["response"]["docs"][0]
end

#restricted?Boolean

Returns:

  • (Boolean)


319
320
321
# File 'app/models/document.rb', line 319

def restricted?
  rights_field_data.blank? || rights_field_data.casecmp("restricted").zero?
end

#rights_field_dataObject



323
324
325
# File 'app/models/document.rb', line 323

def rights_field_data
  send(Settings.FIELDS.ACCESS_RIGHTS) || ""
end

#same_institution?Boolean

Returns:

  • (Boolean)


347
348
349
350
# File 'app/models/document.rb', line 347

def same_institution?
  institution = send(Settings.FIELDS.PROVIDER) || ""
  institution.casecmp(Settings.INSTITUTION.downcase).zero?
end

#set_geometryObject



510
511
512
513
514
# File 'app/models/document.rb', line 510

def set_geometry
  return unless locn_geometry.blank? && self&.dcat_bbox&.present?

  self.locn_geometry = derive_polygon
end

#solr_year_jsonObject Also known as: gbl_indexYear_im



434
435
436
437
438
439
# File 'app/models/document.rb', line 434

def solr_year_json
  return [] if send(GeoblacklightAdmin::Schema.instance.solr_fields[:date_range]).blank?

  start_d, _end_d = send(GeoblacklightAdmin::Schema.instance.solr_fields[:date_range]).first.split("-")
  [start_d] if start_d.presence
end

#state_machineObject

@TODO: Rename this to publication_state_machine



59
60
61
# File 'app/models/document.rb', line 59

def state_machine
  @state_machine ||= DocumentStateMachine.new(self, transition_class: DocumentTransition)
end

#thumbnailObject

Thumbnail is a special case of document_assets



398
399
400
# File 'app/models/document.rb', line 398

def thumbnail
  members.find { |m| m.respond_to?(:thumbnail) && m.thumbnail? }
end

#thumbnail_state_machineObject



68
69
70
# File 'app/models/document.rb', line 68

def thumbnail_state_machine
  @thumbnail_state_machine ||= DocumentThumbnailStateMachine.new(self, transition_class: DocumentThumbnailTransition)
end

#to_csvObject

Export Transformations - to_*



443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
# File 'app/models/document.rb', line 443

def to_csv
  attributes = GeoblacklightAdmin::Schema.instance.exportable_fields
  attributes.map do |key, value|
    if value[:delimited]
      send(value[:destination])&.join("|")
    elsif value[:destination] == "dct_references_s"
      # @TODO: Downloads need to be handled differently
      # - Need to support multiple entries per key here
      # - Need to respect label and url
      dct_references_s_to_csv(key, value[:destination])
    elsif value[:destination] == "b1g_publication_state_s"
      send(:current_state)
    else
      next if send(value[:destination]).blank?
      send(value[:destination])
    end
  end
end

#to_trajectObject



462
463
464
# File 'app/models/document.rb', line 462

def to_traject
  Kithe::Model.find_by_friendlier_id(friendlier_id).update_index(writer: Traject::DebugWriter.new({}))
end

#wxs_identifierObject



377
378
379
# File 'app/models/document.rb', line 377

def wxs_identifier
  send(Settings.FIELDS.WXS_IDENTIFIER) || ""
end