Skip to content

Commit

Permalink
Merge pull request #371 from LafayetteCollegeLibraries/develop
Browse files Browse the repository at this point in the history
2019.9
  • Loading branch information
rococodogs authored Dec 20, 2019
2 parents 96164d7 + dcd5f2b commit f4120f6
Show file tree
Hide file tree
Showing 78 changed files with 2,382 additions and 722 deletions.
37 changes: 37 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,41 @@
# changelog

## [2019.9] - 2019-12-20

### features 🎉

- adds suggestions from solr to the following fields (#370, #378):
- bibliographic_citation
- contributor
- creator
- editor
- keyword
- organization
- physical_medium
- publisher
- source
- adds Image metadata model and creates a base indexer and presenter using shared properties (#258)
- reorders PublicationForm fields to conform with suggestions (#375)

### bugfixes 🐞

- fix typo in `rights_statement.yml` authority file (#374)

### dependencies 👩‍👩‍👧‍👧

- updates rack to 2.0.8 (thanks @dependabot! #376)
- see https://github.com/advisories/GHSA-hrqr-hxpp-chr3

### notes 🗒

- will require updating Solr config files and reindexing for the suggestions and new date-sort field (as well as correcting the the rights_statement typo bug)

### issues affected 🔧

- closes #359
- closes #373


## [2019.8] - 2019-12-06

### features ☃️
Expand Down Expand Up @@ -208,6 +244,7 @@ fixes:

Initial pre-release (live on ldr.stage.lafayette.edu)

[2019.9]: https://github.com/LafayetteCollegeLibraries/spot/releases/tag/2019.9
[2019.8]: https://github.com/LafayetteCollegeLibraries/spot/releases/tag/2019.8
[2019.7]: https://github.com/LafayetteCollegeLibraries/spot/releases/tag/2019.7
[2019.6]: https://github.com/LafayetteCollegeLibraries/spot/releases/tag/2019.6
Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ GEM
rails (~> 5.0)
rdf
raabro (1.1.6)
rack (2.0.7)
rack (2.0.8)
rack-protection (2.0.7)
rack
rack-test (1.1.0)
Expand Down
7 changes: 7 additions & 0 deletions app/actors/hyrax/actors/image_actor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true
module Hyrax
module Actors
class ImageActor < ::Spot::BaseActor
end
end
end
35 changes: 2 additions & 33 deletions app/actors/hyrax/actors/publication_actor.rb
Original file line number Diff line number Diff line change
@@ -1,21 +1,10 @@
# frozen_string_literal: true
module Hyrax
module Actors
class PublicationActor < Hyrax::Actors::BaseActor
include ::DeserializesRdfLiterals

class PublicationActor < ::Spot::BaseActor
private

# Overrides the BaseActor method to allow us to stuff in
# `date_uploaded` values where necessary.
#
# @param [Hyrax::Actors::Environment] env
# @return [void]
def apply_deposit_date(env)
env.curation_concern.date_uploaded = get_date_uploaded_value(env)
end

# Overrides the BaseActor method so that we can apply a +date_available+
# Overrides the +Hyrax::Actors::BaseActor+ method so that we can apply a +date_available+
# value to the item.
#
# @param [Hyrax::Actors::Environment] env
Expand Down Expand Up @@ -46,26 +35,6 @@ def apply_date_available(env)
[Time.zone.now.strftime('%Y-%m-%d')]
end
end

# @param [Hyrax::Actors::Environment] env
# @return [DateTime]
def get_date_uploaded_value(env)
concern = env.curation_concern

if env.attributes[:date_uploaded].present?
DateTime.parse(env.attributes[:date_uploaded]).utc
elsif concern.date_uploaded.present?
# since this is only being called on `#create`, the concern
# shouldn't necessarily have a date_uploaded set already.
# but, in the event that it is, we should retain the value
# as a UTC DateTime.
DateTime.parse(concern.date_uploaded.to_s).utc
else
# this is what `BaseActor#apply_deposit_date` does, so we'll
# keep that as our fallback.
TimeService.time_in_utc
end
end
end
end
end
44 changes: 44 additions & 0 deletions app/actors/solr_suggest_actor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# frozen_string_literal: true
class SolrSuggestActor < ::Hyrax::Actors::AbstractActor
# @param [Hyrax::Actors::Environment] env
# @return [void]
def create(env)
next_actor.create(env) && update_suggest_dictionaries(env)
end

# @param [Hyrax::Actors::Environment] env
# @return [void]
def update(env)
next_actor.update(env) && update_suggest_dictionaries(env)
end

# @param [Hyrax::Actors::Environment] env
# @return [void]
def destroy(env)
next_actor.destroy(env) && update_suggest_dictionaries(env)
end

private

# Enqueue the job to update the solr suggest dictionaries if this actor
# isn't a part of a batch ingest
#
# @param [Hyrax::Actors::Environment] env
# @return [void]
def update_suggest_dictionaries(env)
Spot::UpdateSolrSuggestDictionariesJob.perform_now unless part_of_batch_ingest?(env)
end

# @return [Symbol]
def batch_ingest_key
::Spot::Importers::Base::RecordImporter::BATCH_INGEST_KEY
end

# Does the environment's attributes include the BATCH_INGEST_KEY?
#
# @param [Hyrax::Actors::Environment] env
# @return [true, false]
def part_of_batch_ingest?(env)
env.attributes.include?(batch_ingest_key) && env.attributes[batch_ingest_key] == true
end
end
46 changes: 46 additions & 0 deletions app/actors/spot/base_actor.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# frozen_string_literal: true
module Spot
# Starting point for Spot models. Adds mixin to better pass-around
# RDF language-tagged values (see {::DeserializesRdfLiterals})
# as well as allowing us to apply a +date_uploaded+ value on +#create+.
#
# @example
# module Hyrax
# class WorkActor < ::Spot::BaseActor
# end
# end
#
class BaseActor < ::Hyrax::Actors::BaseActor
include ::DeserializesRdfLiterals

private

# Overrides the BaseActor method to allow us to stuff in
# `date_uploaded` values where necessary.
#
# @return [void]
def apply_deposit_date(env)
env.curation_concern.date_uploaded = get_date_uploaded_value(env)
end

# @param [Hyrax::Actors::Environment] env
# @return [DateTime]
def get_date_uploaded_value(env)
concern = env.curation_concern

if env.attributes[:date_uploaded].present?
DateTime.parse(env.attributes[:date_uploaded]).utc
elsif concern.date_uploaded.present?
# since this is only being called on `#create`, the concern
# shouldn't necessarily have a date_uploaded set already.
# but, in the event that it is, we should retain the value
# as a UTC DateTime.
DateTime.parse(concern.date_uploaded.to_s).utc
else
# this is what `BaseActor#apply_deposit_date` does, so we'll
# keep that as our fallback.
::Hyrax::TimeService.time_in_utc
end
end
end
end
120 changes: 120 additions & 0 deletions app/authorities/qa/authorities/solr_suggest.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# frozen_string_literal: true
module Qa::Authorities
# An base class for building out local authorities to use Solr's
# suggestion engine for autocomplete-options for fields.
# This is a more flexible approach than using Blacklight's
# suggestion search, which appears to only work for a single field.
#
# To begin, first ensure that a suggestion dictionary has been set-up + created
# for your field. In +schemal.xml+, you'll want to ensure that a copyfield
# has been created as the pool to draw from. Note: this field needs to be
# a stored field.
#
# @example Configuring a copyfield for suggestions
# <copyField source="keyword_sim" dest="keyword_suggest_ssim" />
#
# In +solrconfig.xml+, you'll need to build a suggester. The property
# +suggestAnalyzerFieldType+ should be a simple tokenizing field.
#
# @example Configuring a suggestion dictionary
# <lst name="suggester">
# <str name="name">keyword</str>
# <str name="lookupImpl">AnalyzingInfixLookupFactory</str>
# <str name="dictionaryImpl">DocumentDictionaryFactory</str>
# <str name="indexPath">suggestion_index_keyword</str>
# <str name="highlight">false</str>
# <str name="suggestAnalyzerFieldType">textSuggest</str>
# <!--
# buildOnCommit can bring ingests to a crawl, so we suggest
# leaving this false and manually triggering builds via
# a cron-job or something similar
# -->
# <str name="buildOnCommit">false</str>
# <str name="field">keyword_suggest_ssim</str>
# </lst>
#
class SolrSuggest < Qa::Authorities::Base
BUILD_ALL_KEYWORD = :__all__

attr_reader :dictionary

def self.build_dictionaries!
new(BUILD_ALL_KEYWORD).build_dictionary!
end

def initialize(dictionary)
@dictionary = dictionary
end

# @return [void]
def build_dictionary!
params = { 'suggest' => true }

if dictionary == BUILD_ALL_KEYWORD
params['suggest.buildAll'] = true
else
params['suggest.dictionary'] = dictionary
params['suggest.build'] = true
end

connection.get(suggest_path, params: params)
end

# @return [RSolr::Client]

def search(query)
solr_suggestion_for_query(query)
end

def term(_id)
{}
end

def all
[]
end

private

def connection
ActiveFedora::SolrService.instance.conn
end

# @return [String]
def suggest_path
@suggest_path ||= begin
url = Rails.application.config_for(:solr)['url']
URI.join(url + '/', 'suggest').path
end
end

# @param [String] query
# @return [Array<Hash<String => String>>]
def solr_suggestion_for_query(query)
params = {
'suggest.q' => query,
'suggest.dictionary' => dictionary
}

raw = connection.get(suggest_path, params: params)
parse_raw_response(raw, query: query)
end

# Takes the Solr response and transforms the results into the
# Questioning Authority preferred format.
#
# @param [Hash<String => *>] raw
# @param [Hash] options
# @option [String] query
# The initial query, used to extract results from the returned Hash
# @return [Array<Hash<String => String>>]
def parse_raw_response(raw, query:)
suggestions = raw.dig('suggest', dictionary, query, 'suggestions')
suggestions ||= []

suggestions.map do |res|
{ id: res['term'], label: res['term'], value: res['term'] }
end
end
end
end
6 changes: 2 additions & 4 deletions app/controllers/catalog_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -252,10 +252,8 @@ class CatalogController < ApplicationController
# the labels through +I18n.t+ first, displaying only the symbolized translation
# keys we're sending here.
config.add_sort_field 'score desc, system_create_dtsi desc', label: "Relevance"
config.add_sort_field 'date_issued_sort_dtsi asc', label: "Issue Date \u25B2"
config.add_sort_field 'date_issued_sort_dtsi desc', label: "Issue Date \u25BC"
config.add_sort_field 'system_create_dtsi asc', label: "Date Added \u25B2"
config.add_sort_field 'system_create_dtsi desc', label: "Date Added \u25BC"
config.add_sort_field 'date_sort_dtsi asc', label: "Date \u25B2"
config.add_sort_field 'date_sort_dtsi desc', label: "Date \u25BC"
config.add_sort_field 'title_sort_si asc', label: "Title \u25B2"
config.add_sort_field 'title_sort_si desc', label: "Title \u25BC"

Expand Down
16 changes: 16 additions & 0 deletions app/controllers/hyrax/images_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

# Generated via
# `rails generate hyrax:work Image`
module Hyrax
# Generated controller for Image
class ImagesController < ApplicationController
# Adds Hyrax behaviors to the controller.
include Hyrax::WorksControllerBehavior
include Hyrax::BreadcrumbsForWorks
self.curation_concern_type = ::Image

# Use this line if you want to use a custom presenter
self.show_presenter = Hyrax::ImagePresenter
end
end
12 changes: 12 additions & 0 deletions app/forms/hyrax/image_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true
module Hyrax
# Generated form for Image
class ImageForm < Hyrax::Forms::WorkForm
include ::IdentifierFormFields
include ::LanguageTaggedFormFields
include ::NestedFormFields

self.model_class = ::Image
self.terms += [:resource_type]
end
end
Loading

0 comments on commit f4120f6

Please sign in to comment.