diff --git a/Gemfile b/Gemfile index 9ad4349..c4a19d8 100644 --- a/Gemfile +++ b/Gemfile @@ -117,3 +117,5 @@ group :development, :test do # jettywrapper gem 'jettywrapper', :github => "projecthydra/jettywrapper" end + +gem 'blacklight-oembed' diff --git a/Gemfile.lock b/Gemfile.lock index 7e180d1..74f9bb3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -138,6 +138,11 @@ GEM bootstrap-sass (~> 3.0) openseadragon (>= 0.2.0) rails + blacklight-oembed (0.0.4) + blacklight (~> 5.0) + bootstrap-sass (~> 3.0) + rails + ruby-oembed blacklight_advanced_search (5.1.4) blacklight (~> 5.10) parslet @@ -472,6 +477,7 @@ GEM rspec-mocks (~> 3.2.0) rspec-support (~> 3.2.0) rspec-support (3.2.2) + ruby-oembed (0.8.14) ruby-vips (0.3.9) rubydora (1.8.1) activemodel @@ -583,6 +589,7 @@ DEPENDENCIES best_in_place blacklight blacklight-gallery + blacklight-oembed blacklight_advanced_search capistrano (~> 2.0) capybara diff --git a/app/assets/javascripts/blacklight_oembed.js b/app/assets/javascripts/blacklight_oembed.js new file mode 100644 index 0000000..72acb3e --- /dev/null +++ b/app/assets/javascripts/blacklight_oembed.js @@ -0,0 +1,5 @@ +//= require 'blacklight_oembed/jquery.oembed.js' + +Blacklight.onLoad(function() { + $('[data-embed-url]').oEmbed(); +}); \ No newline at end of file diff --git a/app/assets/stylesheets/blacklight_oembed.css.scss b/app/assets/stylesheets/blacklight_oembed.css.scss new file mode 100644 index 0000000..e69de29 diff --git a/app/controllers/records_controller.rb b/app/controllers/records_controller.rb index 5d237f1..1ab7e50 100644 --- a/app/controllers/records_controller.rb +++ b/app/controllers/records_controller.rb @@ -4,7 +4,7 @@ class RecordsController < ApplicationController protected def collect_form_attributes - AttributeURIConverter.new(super).convert_attributes + CleanedAttributes.from(super) end def resource @@ -24,4 +24,5 @@ def resource_decorators ) end + end diff --git a/app/forms/external_asset_form.rb b/app/forms/external_asset_form.rb new file mode 100644 index 0000000..c0fdace --- /dev/null +++ b/app/forms/external_asset_form.rb @@ -0,0 +1,4 @@ +class ExternalAssetForm < GenericAssetForm + self.model_class = ExternalAsset + self.terms = [:oembed] + self.terms +end diff --git a/app/forms/generic_asset_form.rb b/app/forms/generic_asset_form.rb index bcfb055..8021c4d 100644 --- a/app/forms/generic_asset_form.rb +++ b/app/forms/generic_asset_form.rb @@ -3,7 +3,7 @@ class GenericAssetForm delegate :validators, :to => :model # TODO: Put :workType back in once our editor can support URLs and/or we have # a "clean" graph from AF - skip_terms = [:workType] + skip_terms = [:workType, :oembed] self.terms = ODDataModel.simple_properties.keys - skip_terms def self.permitted_params diff --git a/app/models/blacklight_config.rb b/app/models/blacklight_config.rb index 03aaf78..b6d4cd8 100644 --- a/app/models/blacklight_config.rb +++ b/app/models/blacklight_config.rb @@ -25,9 +25,15 @@ def configurations SearchFieldConfiguration.new(configuration), ShowActions.new(configuration), ThumbnailConfiguration.new(configuration), - Gallery.new(configuration), IndexConfiguration.new(configuration), - FacetFields.new(configuration) + FacetFields.new(configuration), + ] | plugins + end + + def plugins + [ + Gallery.new(configuration), + Embed.new(configuration) ] end diff --git a/app/models/blacklight_config/embed.rb b/app/models/blacklight_config/embed.rb new file mode 100644 index 0000000..182a635 --- /dev/null +++ b/app/models/blacklight_config/embed.rb @@ -0,0 +1,10 @@ +class BlacklightConfig + class Embed + pattr_initialize :configuration + + def run + configuration.show.oembed_field = :oembed_ssim + configuration.show.partials.insert(1, :oembed) + end + end +end diff --git a/app/models/external_asset.rb b/app/models/external_asset.rb new file mode 100644 index 0000000..a7c65fd --- /dev/null +++ b/app/models/external_asset.rb @@ -0,0 +1,2 @@ +class ExternalAsset < GenericAsset +end diff --git a/app/models/od_data_model.rb b/app/models/od_data_model.rb index b38a36b..9da1c93 100644 --- a/app/models/od_data_model.rb +++ b/app/models/od_data_model.rb @@ -205,5 +205,14 @@ class ODDataModel < DataModel property :containedInJournal, :predicate => RDF::URI('http://sw-portal.deri.org/ontologies/swportal#containedInJournal') property :isVolume, :predicate => RDF::URI('http://sw-portal.deri.org/ontologies/swportal#isVolume') property :hasNumber, :predicate => RDF::URI('http://sw-portal.deri.org/ontologies/swportal#hasNumber') + + # OEmbed + property:oembed, :predicate => OregonDigital::Vocabularies::OPAQUENAMESPACE.oembed, :cast => false + + def self.string_properties + @string_properties ||= properties.select{|x| x.cast == false} + .map(&:name) + .map(&:to_s) + end end diff --git a/app/models/solr_document.rb b/app/models/solr_document.rb index fe8b7ac..e7374e2 100644 --- a/app/models/solr_document.rb +++ b/app/models/solr_document.rb @@ -18,9 +18,15 @@ def derivative_paths def property(key) if key == "id" SingularSolrProperty.new(key, _source[key]) + elsif uncasted_keys.include?(SolrProperty.new(key).key) + SolrProperty.new(key, _source[key]) else EnrichedSolrPropertyResult.new(key, _source) end end + + def uncasted_keys + ODDataModel.string_properties + end end diff --git a/app/values/cleaned_attributes.rb b/app/values/cleaned_attributes.rb new file mode 100644 index 0000000..418b1c3 --- /dev/null +++ b/app/values/cleaned_attributes.rb @@ -0,0 +1,25 @@ +class CleanedAttributes + def self.from(base) + new(base).result + end + + pattr_initialize :base + + def result + base.merge(converted) + end + + private + + def converted + @converted ||= AttributeURIConverter.new(truncated_base).convert_attributes + end + + def truncated_base + base.except(*string_properties) + end + + def string_properties + @string_properties ||= ODDataModel.string_properties + end +end diff --git a/config/initializers/hydra_editor.rb b/config/initializers/hydra_editor.rb index 0cacc8c..d165d40 100644 --- a/config/initializers/hydra_editor.rb +++ b/config/initializers/hydra_editor.rb @@ -1,4 +1,4 @@ -HydraEditor.models = ["Image", "Document", "GenericSet"] +HydraEditor.models = ["Image", "Document", "GenericSet", "ExternalAsset"] HydraEditor::Fields::Generator.factory = OregonDigital::Fields::InputFactory.new( HydraEditor::Fields::Factory, DecoratorList.new(HasHintOption, HasURIInputType) diff --git a/config/initializers/oembed_providers.rb b/config/initializers/oembed_providers.rb new file mode 100644 index 0000000..fa8763e --- /dev/null +++ b/config/initializers/oembed_providers.rb @@ -0,0 +1,9 @@ +require 'oembed' + +OEmbed::Providers.register_all + +## Register OSU Mediaspace Provider +mediaspace_provider = OEmbed::Provider.new("https://media.oregonstate.edu/oembed") +mediaspace_provider << "https://media.oregonstate.edu/id*" +mediaspace_provider << "http.://media.oregonstate.edu/id*" +OEmbed::Providers.register(mediaspace_provider) diff --git a/config/locales/en.yml b/config/locales/en.yml index b2c39c2..832f0b2 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -31,3 +31,7 @@ en: destroy: fail: "Failed to delete facet" success: "Deleted facet" + hydra_editor: + form: + model_label: + ExternalAsset: "External Asset" diff --git a/config/routes.rb b/config/routes.rb index 1dd31d5..2577e30 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,5 @@ Rails.application.routes.draw do + mount Blacklight::Oembed::Engine, at: 'oembed' root :to => "catalog#index" blacklight_for :catalog devise_for :users diff --git a/spec/features/hydra_editor_spec.rb b/spec/features/hydra_editor_spec.rb index 0fce84b..66a4cbd 100644 --- a/spec/features/hydra_editor_spec.rb +++ b/spec/features/hydra_editor_spec.rb @@ -34,6 +34,16 @@ expect(image.workflow_metadata.pyramidal_path).not_to be_blank end end + + it "should save an external resource", :perform_enqueued => false do + as_user(admin) do + navigate_to_new_external_resource_path + fill_in "external_asset_oembed", :with => "http://test.org" + find(:css, "input.btn-primary").click + expect(page).to have_content("successfully created") + expect(page).to have_selector(:css, "*[data-embed-url]") + end + end it "should show invalid fields" do as_user(admin) do navigate_to_new_image_path @@ -102,4 +112,9 @@ def navigate_to_new_image_path page.select("Image", :from => "type") find(:css, "input.btn-primary").click end + def navigate_to_new_external_resource_path + visit "/records/new" + page.select("External Asset", :from => "type") + find(:css, "input.btn-primary").click + end end diff --git a/spec/forms/external_asset_form_spec.rb b/spec/forms/external_asset_form_spec.rb new file mode 100644 index 0000000..0132581 --- /dev/null +++ b/spec/forms/external_asset_form_spec.rb @@ -0,0 +1,9 @@ +require 'rails_helper' + +RSpec.describe ExternalAssetForm do + describe ".terms" do + it "should include oembed" do + expect(described_class.terms.first).to eq :oembed + end + end +end diff --git a/spec/forms/generic_asset_form_spec.rb b/spec/forms/generic_asset_form_spec.rb index 4edb94d..f2dfb63 100644 --- a/spec/forms/generic_asset_form_spec.rb +++ b/spec/forms/generic_asset_form_spec.rb @@ -25,4 +25,10 @@ end end end + + describe ".terms" do + it "should not include oembed" do + expect(ImageForm.terms).not_to include :oembed + end + end end diff --git a/spec/models/blacklight_config_spec.rb b/spec/models/blacklight_config_spec.rb index 05202d8..3ccc444 100644 --- a/spec/models/blacklight_config_spec.rb +++ b/spec/models/blacklight_config_spec.rb @@ -96,6 +96,10 @@ it "should have an edit action for index" do expect(subject.index.document_actions[:edit_record].partial).to eq "edit_action" end - end + it "should configure OEmbed" do + expect(subject.show.oembed_field).to eq :oembed_ssim + expect(subject.show.partials).to include :oembed + end + end end diff --git a/spec/models/od_data_model_spec.rb b/spec/models/od_data_model_spec.rb index f2a906a..8de5236 100644 --- a/spec/models/od_data_model_spec.rb +++ b/spec/models/od_data_model_spec.rb @@ -7,4 +7,10 @@ expect(subject.simple_properties).to include ({:title => RDF::DC.title}) end end + + describe "#properties" do + it "should not not cast oembed" do + expect(subject.properties.find{|x| x.name == :oembed}.cast).to eq false + end + end end diff --git a/spec/models/solr_document_spec.rb b/spec/models/solr_document_spec.rb index fe4611b..63d0a0a 100644 --- a/spec/models/solr_document_spec.rb +++ b/spec/models/solr_document_spec.rb @@ -15,12 +15,16 @@ { :title_ssim => ["http://test.test.org", "Raw String"], :title_preferred_label_ssim => ["Test"], - :title_alt_label_ssim => ["Alternative"] + :title_alt_label_ssim => ["Alternative"], + :oembed_ssim => ["http://test.org"] } end it "should show title labels together with their preferred label" do expect(subject[:title_ssim]).to eq ["Test", "Raw String"] end + it "should allow access to fields with URI casting off" do + expect(subject[:oembed_ssim]).to eq ["http://test.org"] + end end end describe "#derivative_paths" do