From 649ce6ffd861af3bd0b2a9e28ffb48819d50bf86 Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Wed, 20 Sep 2023 23:59:46 -0700 Subject: [PATCH 001/126] add blacklight advances search, blacklight date ranges and order already to the gem file and configure them --- Gemfile | 3 + app/assets/javascripts/admin_font_select.js | 32 +- app/assets/javascripts/application.js | 11 + .../range_limit_distro_facets.js | 300 ++++++++++++++++++ .../range_limit_shared.js | 24 ++ .../range_limit_slider.js | 130 ++++++++ app/assets/stylesheets/application.css | 3 + app/controllers/catalog_controller.rb | 86 ++++- app/controllers/saved_searches_controller.rb | 7 + app/controllers/search_history_controller.rb | 8 + app/models/collection.rb | 1 + app/models/generic_work.rb | 3 + app/models/image.rb | 2 + app/models/search_builder.rb | 4 + .../advanced/_advanced_search_help.html.erb | 26 ++ .../_range_limit_panel.html.erb | 125 ++++++++ config/routes.rb | 4 +- 17 files changed, 757 insertions(+), 12 deletions(-) create mode 100644 app/assets/javascripts/blacklight_range_limit/range_limit_distro_facets.js create mode 100644 app/assets/javascripts/blacklight_range_limit/range_limit_shared.js create mode 100644 app/assets/javascripts/blacklight_range_limit/range_limit_slider.js create mode 100644 app/controllers/saved_searches_controller.rb create mode 100644 app/controllers/search_history_controller.rb create mode 100644 app/views/advanced/_advanced_search_help.html.erb create mode 100644 app/views/blacklight_range_limit/_range_limit_panel.html.erb diff --git a/Gemfile b/Gemfile index 868c97ba3..8cda67972 100644 --- a/Gemfile +++ b/Gemfile @@ -13,7 +13,9 @@ gem 'addressable', '2.8.1' # remove once https://github.com/postrank-labs/postra gem 'apartment' gem 'aws-sdk-sqs', group: %i[aws] gem 'blacklight', '~> 6.7' +gem 'blacklight_advanced_search' gem 'blacklight_oai_provider', '~> 6.1', '>= 6.1.1' +gem 'blacklight_range_limit', '6.5.0' gem 'bolognese', '>= 1.9.10' gem 'bootstrap-datepicker-rails' gem 'bulkrax', '~> 5.3' @@ -54,6 +56,7 @@ gem 'omniauth-multi-provider' gem 'omniauth-rails_csrf_protection', '~> 1.0' gem 'omniauth-saml', '~> 2.1' gem 'omniauth_openid_connect' +gem 'order_already' gem 'parser', '~> 2.5.3' gem 'pg' gem 'postrank-uri', '>= 1.0.24' diff --git a/app/assets/javascripts/admin_font_select.js b/app/assets/javascripts/admin_font_select.js index 7fa065108..e2c3e89cb 100644 --- a/app/assets/javascripts/admin_font_select.js +++ b/app/assets/javascripts/admin_font_select.js @@ -1,6 +1,34 @@ Blacklight.onLoad(function() { if($("#admin_appearance_body_font").length > 0){ - $("#admin_appearance_body_font").fontselect({lookahead: 20}); - $("#admin_appearance_headline_font").fontselect({lookahead: 20}); + $("#admin_appearance_body_font").fontselect({lookahead: 20}) + $("#admin_appearance_headline_font").fontselect({lookahead: 20}) } }); + +$('div.defaultable-fonts a.restore-default-font').click(function(e) { + e.preventDefault() + var defaultTarget = $(e.target).data('default-target') + var input = $("input[name='admin_appearance["+ defaultTarget +"]']") + var defaultValue = input.data('default-value').replace(';', '') + var inputDisplay = $("div[class$='"+ defaultTarget +"']").find('div.font-select span') + + input.val(defaultValue) + inputDisplay.css("font-family", defaultValue) + inputDisplay.text(defaultValue) +}) + +$('.panel-footer a.restore-all-default-fonts').click(function(e) { + e.preventDefault() + + var allFontInputs = $("input[name*='font']") + + allFontInputs.each(function() { + var thisTarget = $(this).attr('id').replace('admin_appearance_', '') + var defaultValue = $(this).data('default-value').replace(';', '') + var inputDisplay = $("div[class$='"+ thisTarget +"']").find('div.font-select span') + + $(this).val(defaultValue) + inputDisplay.css("font-family", defaultValue) + inputDisplay.text(defaultValue) + }) +}); diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index fe1ce9b26..c2e416d37 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -26,6 +26,8 @@ // Required by Blacklight //= require blacklight/blacklight //= require admin_font_select +//= require admin_color_select +//= require blacklight_advanced_search // Moved the Hyku JS *above* the Hyrax JS to resolve #1187 (following // a pattern found in ScholarSphere) @@ -49,3 +51,12 @@ //= require flot_graph //= require statistics_tab_manager //= require blacklight_gallery/default + +// Required for blacklight range limit +//= require blacklight_range_limit/range_limit_distro_facets +//= require blacklight_range_limit/range_limit_shared +//= require blacklight_range_limit/range_limit_slider +//= require bootstrap-slider +//= require jquery.flot.js + +//= require tinymce diff --git a/app/assets/javascripts/blacklight_range_limit/range_limit_distro_facets.js b/app/assets/javascripts/blacklight_range_limit/range_limit_distro_facets.js new file mode 100644 index 000000000..4b2807651 --- /dev/null +++ b/app/assets/javascripts/blacklight_range_limit/range_limit_distro_facets.js @@ -0,0 +1,300 @@ +// for Blacklight.onLoad: + +/* A custom event "plotDrawn.blacklight.rangeLimit" will be sent when flot plot + is (re-)drawn on screen possibly with a new size. target of event will be the DOM element + containing the plot. Used to resize slider to match. */ + + Blacklight.onLoad(function() { + // ratio of width to height for desired display, multiply width by this ratio + // to get height. hard-coded in for now. + var display_ratio = 1/(1.618 * 2); // half a golden rectangle, why not + var redrawnEvent = "plotDrawn.blacklight.rangeLimit"; + + + + // Facets already on the page? Turn em into a chart. + $(".range_limit .profile .distribution.chart_js ul").each(function() { + turnIntoPlot($(this).parent()); + }); + + + // Add AJAX fetched range facets if needed, and add a chart to em + $(".range_limit .profile .distribution a.load_distribution").each(function() { + var container = $(this).parent('div.distribution'); + + $(container).load($(this).attr('href'), function(response, status) { + if ($(container).hasClass("chart_js") && status == "success" ) { + turnIntoPlot(container); + } + }); + }); + + // Listen for twitter bootstrap collapsible open events, to render flot + // in previously hidden divs on open, if needed. + $("body").on("show.bs.collapse", function(event) { + // Was the target a .facet-content including a .chart-js? + var container = $(event.target).filter(".facet-content").find(".chart_js"); + + // only if it doesn't already have a canvas, it isn't already drawn + if (container && container.find("canvas").length == 0) { + // be willing to wait up to 1100ms for container to + // have width -- right away on show.bs is too soon, but + // shown.bs is later than we want, we want to start rendering + // while animation is still in progress. + turnIntoPlot(container, 1100); + } + }); + + + + // after a collapsible facet contents is fully shown, + // resize the flot chart to current conditions. This way, if you change + // browser window size, you can get chart resized to fit by closing and opening + // again, if needed. + + function redrawPlot(container) { + if (container && container.width() > 0) { + // resize the container's height, since width may have changed. + container.height( container.width() * display_ratio ); + + // redraw the chart. + var plot = container.data("plot"); + if (plot) { + // how to redraw after possible resize? + // Cribbed from https://github.com/flot/flot/blob/master/jquery.flot.resize.js + plot.resize(); + plot.setupGrid(); + plot.draw(); + // plus trigger redraw of the selection, which otherwise ain't always right + // we'll trigger a fake event on one of the boxes + var form = $(container).closest(".limit_content").find("form.range_limit"); + form.find("input.range_begin").trigger("change"); + + // send our custom event to trigger redraw of slider + $(container).trigger(redrawnEvent); + } + } + } + + $("body").on("shown.bs.collapse", function(event) { + var container = $(event.target).filter(".facet-content").find(".chart_js"); + redrawPlot(container); + }); + + // debouce borrowed from underscore + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. If `immediate` is passed, trigger the function on the + // leading edge, instead of the trailing. + debounce = function(func, wait, immediate) { + var timeout; + return function() { + var context = this, args = arguments; + var later = function() { + timeout = null; + if (!immediate) func.apply(context, args); + }; + var callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + if (callNow) func.apply(context, args); + }; + }; + + $(window).on("resize", debounce(function() { + $(".chart_js").each(function(i, container) { + redrawPlot($(container)); + }); + }, 350)); + + // second arg, if provided, is a number of ms we're willing to + // wait for the container to have width before giving up -- we'll + // set 50ms timers to check back until timeout is expired or the + // container is finally visible. The timeout is used when we catch + // bootstrap show event, but the animation hasn't barely begun yet -- but + // we don't want to wait until it's finished, we want to start rendering + // as soon as we can. + // + // We also will + function turnIntoPlot(container, wait_for_visible) { + // flot can only render in a a div with a defined width. + // for instance, a hidden div can't generally be rendered in (although if you set + // an explicit width on it, it might work) + // + // We'll count on later code that catch bootstrap collapse open to render + // on show, for currently hidden divs. + + // for some reason width sometimes return negative, not sure + // why but it's some kind of hidden. + if (container.width() > 0) { + var height = container.width() * display_ratio; + + // Need an explicit height to make flot happy. + container.height( height ) + + areaChart($(container)); + + $(container).trigger(redrawnEvent); + } + else if (wait_for_visible > 0) { + setTimeout(function() { + turnIntoPlot(container, wait_for_visible - 50); + }, 50); + } + } + + // Takes a div holding a ul of distribution segments produced by + // blacklight_range_limit/_range_facets and makes it into + // a flot area chart. + function areaChart(container) { + //flot loaded? And canvas element supported. + if ( domDependenciesMet() ) { + + // Grab the data from the ul div + var series_data = new Array(); + var pointer_lookup = new Array(); + var x_ticks = new Array(); + var min = BlacklightRangeLimit.parseNum($(container).find("ul li:first-child span.from").text()); + var max = BlacklightRangeLimit.parseNum($(container).find("ul li:last-child span.to").text()); + + $(container).find("ul li").each(function() { + var from = BlacklightRangeLimit.parseNum($(this).find("span.from").text()); + var to = BlacklightRangeLimit.parseNum($(this).find("span.to").text()); + var count = BlacklightRangeLimit.parseNum($(this).find("span.count").text()); + var avg = (count / (to - from + 1)); + + + //We use the avg as the y-coord, to make the area of each + //segment proportional to how many documents it holds. + series_data.push( [from, avg ] ); + series_data.push( [to+1, avg] ); + + x_ticks.push(from); + + pointer_lookup.push({'from': from, 'to': to, 'count': count, 'label': $(this).find(".facet_select").text() }); + }); + var max_plus_one = BlacklightRangeLimit.parseNum($(container).find("ul li:last-child span.to").text())+1; + x_ticks.push( max_plus_one ); + + + + var plot; + var config = $(container).closest('.facet_limit').data('plot-config') || {}; + + try { + plot = $.plot($(container), [series_data], + $.extend(true, config, { + yaxis: { ticks: [], min: 0, autoscaleMargin: 0.1}, + //xaxis: { ticks: x_ticks }, + xaxis: { tickDecimals: 0 }, // force integer ticks + series: { lines: { fill: true, steps: true }}, + grid: {clickable: true, hoverable: true, autoHighlight: false}, + selection: {mode: "x"} + })); + } + catch(err) { + alert(err); + } + + find_segment_for = function_for_find_segment(pointer_lookup); + var last_segment = null; + $(container).tooltip({'placement': 'bottom', 'trigger': 'manual', 'delay': { show: 0, hide: 100}}); + + $(container).bind("plothover", function (event, pos, item) { + segment = find_segment_for(pos.x); + + if(segment != last_segment) { + var title = find_segment_for(pos.x).label + ' (' + BlacklightRangeLimit.parseNum(segment.count) + ')'; + $(container).attr("title", title).tooltip("_fixTitle").tooltip("show"); + + last_segment = segment; + } + }); + + $(container).bind("mouseout", function() { + last_segment = null; + $(container).tooltip('hide'); + }); + $(container).bind("plotclick", function (event, pos, item) { + if ( plot.getSelection() == null) { + segment = find_segment_for(pos.x); + plot.setSelection( normalized_selection(segment.from, segment.to)); + } + }); + $(container).bind("plotselected plotselecting", function(event, ranges) { + if (ranges != null ) { + var from = Math.floor(ranges.xaxis.from); + var to = Math.floor(ranges.xaxis.to); + + var form = $(container).closest(".limit_content").find("form.range_limit"); + form.find("input.range_begin").val(from); + form.find("input.range_end").val(to); + + var slider_placeholder = $(container).closest(".limit_content").find("[data-slider-placeholder]"); + if (slider_placeholder) { + slider_placeholder.slider("setValue", [from, to+1]); + } + } + }); + + var form = $(container).closest(".limit_content").find("form.range_limit"); + form.find("input.range_begin, input.range_end").change(function () { + plot.setSelection( form_selection(form, min, max) , true ); + }); + $(container).closest(".limit_content").find(".profile .range").on("slide", function(event, ui) { + var values = $(event.target).data("slider").getValue(); + form.find("input.range_begin").val(values[0]); + form.find("input.range_end").val(values[1]); + plot.setSelection( normalized_selection(values[0], Math.max(values[0], values[1]-1)), true); + }); + + // initially entirely selected, to match slider + plot.setSelection( {xaxis: { from:min, to:max+0.9999}} ); + } + } + + + // Send endpoint to endpoint+0.99999 to have display + // more closely approximate limiting behavior esp + // at small resolutions. (Since we search on whole numbers, + // inclusive, but flot chart is decimal.) + function normalized_selection(min, max) { + max += 0.99999; + + return {xaxis: { 'from':min, 'to':max}} + } + + function form_selection(form, min, max) { + var begin_val = BlacklightRangeLimit.parseNum($(form).find("input.range_begin").val()); + if (isNaN(begin_val) || begin_val < min) { + begin_val = min; + } + var end_val = BlacklightRangeLimit.parseNum($(form).find("input.range_end").val()); + if (isNaN(end_val) || end_val > max) { + end_val = max; + } + + return normalized_selection(begin_val, end_val); + } + + function function_for_find_segment(pointer_lookup_arr) { + return function(x_coord) { + for (var i = pointer_lookup_arr.length-1 ; i >= 0 ; i--) { + var hash = pointer_lookup_arr[i]; + if (x_coord >= hash.from) + return hash; + } + return pointer_lookup_arr[0]; + }; + } + + // Check if Flot is loaded, and if browser has support for + // canvas object, either natively or via IE excanvas. + function domDependenciesMet() { + var flotLoaded = (typeof $.plot != "undefined"); + var canvasAvailable = ((typeof(document.createElement('canvas').getContext) != "undefined") || (typeof window.CanvasRenderingContext2D != 'undefined' || typeof G_vmlCanvasManager != 'undefined')); + + return (flotLoaded && canvasAvailable); + } + }); + \ No newline at end of file diff --git a/app/assets/javascripts/blacklight_range_limit/range_limit_shared.js b/app/assets/javascripts/blacklight_range_limit/range_limit_shared.js new file mode 100644 index 000000000..74aef9e9e --- /dev/null +++ b/app/assets/javascripts/blacklight_range_limit/range_limit_shared.js @@ -0,0 +1,24 @@ + +// takes a string and parses into an integer, but throws away commas first, to avoid truncation when there is a comma +// use in place of javascript's native parseInt +!function(global) { + 'use strict'; + + var previousBlacklightRangeLimit = global.BlacklightRangeLimit; + + function BlacklightRangeLimit(options) { + this.options = options || {}; + } + + BlacklightRangeLimit.parseNum = function parseNum(str) { + str = String(str).replace(/[^0-9]/g, ''); + return parseInt(str, 10); + }; + + BlacklightRangeLimit.noConflict = function noConflict() { + global.BlacklightRangeLimit = previousBlacklightRangeLimit; + return BlacklightRangeLimit; + }; + + global.BlacklightRangeLimit = BlacklightRangeLimit; +}(this); diff --git a/app/assets/javascripts/blacklight_range_limit/range_limit_slider.js b/app/assets/javascripts/blacklight_range_limit/range_limit_slider.js new file mode 100644 index 000000000..e29464229 --- /dev/null +++ b/app/assets/javascripts/blacklight_range_limit/range_limit_slider.js @@ -0,0 +1,130 @@ +// for Blacklight.onLoad: + +Blacklight.onLoad(function() { + + $(".range_limit .profile .range.slider_js").each(function() { + var range_element = $(this); + + var boundaries = min_max(this); + var min = boundaries[0]; + var max = boundaries[1]; + + if (isInt(min) && isInt(max)) { + $(this).contents().wrapAll('
'); + + var range_element = $(this); + var form = $(range_element).closest(".range_limit").find("form.range_limit"); + var begin_el = form.find("input.range_begin"); + var end_el = form.find("input.range_end"); + + var placeholder_input = $('').appendTo(range_element); + + // make sure slider is loaded + if (placeholder_input.slider !== undefined) { + placeholder_input.slider({ + min: min, + max: max+1, + value: [min, max+1], + tooltip: "hide" + }); + + // try to make slider width/orientation match chart's + var container = range_element.closest(".range_limit"); + var plot = container.find(".chart_js").data("plot"); + var slider_el = container.find(".slider"); + + if (plot && slider_el) { + slider_el.width(plot.width()); + slider_el.css("display", "block") + slider_el.css('margin-right', 'auto'); + slider_el.css('margin-left', 'auto'); + } + else if (slider_el) { + slider_el.css("width", "100%"); + } + } + + // Slider change should update text input values. + var parent = $(this).parent(); + var form = $(parent).closest(".limit_content").find("form.range_limit"); + $(parent).closest(".limit_content").find(".profile .range").on("slide", function(event, ui) { + var values = $(event.target).data("slider").getValue(); + form.find("input.range_begin").val(values[0]); + form.find("input.range_end").val(values[1]); + }); + } + + begin_el.val(min); + end_el.val(max); + + begin_el.change( function() { + var val = BlacklightRangeLimit.parseNum($(this).val()); + if ( isNaN(val) || val < min) { + //for weird data, set slider at min + val = min; + } + var values = placeholder_input.data("slider").getValue(); + values[0] = val; + placeholder_input.slider("setValue", values); + }); + + end_el.change( function() { + var val = BlacklightRangeLimit.parseNum($(this).val()); + if ( isNaN(val) || val > max ) { + //weird entry, set slider to max + val = max; + } + var values = placeholder_input.data("slider").getValue(); + values[1] = val; + placeholder_input.slider("setValue", values); + }); + + }); + + // catch event for redrawing chart, to redraw slider to match width + $("body").on("plotDrawn.blacklight.rangeLimit", function(event) { + var area = $(event.target).closest(".limit_content.range_limit"); + var plot = area.find(".chart_js").data("plot"); + var slider_el = area.find(".slider"); + + if (plot && slider_el) { + slider_el.width(plot.width()); + slider_el.css("display", "block") + slider_el.css('margin-right', 'auto'); + slider_el.css('margin-left', 'auto'); + } + }); + + // returns two element array min/max as numbers. If there is a limit applied, + // it's boundaries are are limits. Otherwise, min/max in current result + // set as sniffed from HTML. Pass in a DOM element for a div.range + // Will return NaN as min or max in case of error or other weirdness. + function min_max(range_element) { + var current_limit = $(range_element).closest(".limit_content.range_limit").find(".current") + + + + var min = max = BlacklightRangeLimit.parseNum(current_limit.find(".single").text()) + if ( isNaN(min)) { + min = BlacklightRangeLimit.parseNum(current_limit.find(".from").first().text()); + max = BlacklightRangeLimit.parseNum(current_limit.find(".to").first().text()); + } + + if (isNaN(min) || isNaN(max)) { + //no current limit, take from results min max included in spans + min = BlacklightRangeLimit.parseNum($(range_element).find(".min").first().text()); + max = BlacklightRangeLimit.parseNum($(range_element).find(".max").first().text()); + } + + return [min, max] + } + + + // Check to see if a value is an Integer + // see: http://stackoverflow.com/questions/3885817/how-to-check-if-a-number-is-float-or-integer + function isInt(n) { + return n % 1 === 0; + } + + }); + \ No newline at end of file diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 8b66c7d5d..bb4734825 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -18,5 +18,8 @@ *= require dataTables/bootstrap/3/jquery.dataTables.bootstrap *= require bootstrap-datepicker *= require single_signon + *= require blacklight_advanced_search + *= require blacklight_range_limit + *= require iiif_print/iiif_print *= require_self */ diff --git a/app/controllers/catalog_controller.rb b/app/controllers/catalog_controller.rb index 72265252c..17eca79a9 100644 --- a/app/controllers/catalog_controller.rb +++ b/app/controllers/catalog_controller.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class CatalogController < ApplicationController + include BlacklightAdvancedSearch::Controller + include BlacklightRangeLimit::ControllerOverride include Hydra::Catalog include Hydra::Controller::ControllerBehavior include BlacklightOaiProvider::Controller @@ -8,20 +10,33 @@ class CatalogController < ApplicationController # These before_action filters apply the hydra access controls before_action :enforce_show_permissions, only: :show - def self.uploaded_field - 'system_create_dtsi' + def self.created_field + 'date_created_ssim' + end + + def self.creator_field + 'creator_ssim' end def self.modified_field 'system_modified_dtsi' end + def self.title_field + 'title_ssim' + end + + def self.uploaded_field + 'system_create_dtsi' + end + # CatalogController-scope behavior and configuration for BlacklightIiifSearch include BlacklightIiifSearch::Controller configure_blacklight do |config| # IiifPrint index fields - config.add_index_field 'all_text_tsimv', highlight: true, helper_method: :render_ocr_snippets + config.add_index_field 'all_text_timv' + config.add_index_field 'file_set_text_tsimv', label: "Item contents", highlight: true, helper_method: :render_ocr_snippets # configuration for Blacklight IIIF Content Search config.iiif_search = { @@ -44,18 +59,32 @@ def self.modified_field config.advanced_search[:url_key] ||= 'advanced' config.advanced_search[:query_parser] ||= 'dismax' config.advanced_search[:form_solr_parameters] ||= {} + config.advanced_search[:form_facet_partial] ||= "advanced_search_facets_as_select" config.search_builder_class = IiifPrint::CatalogSearchBuilder + # Use locally customized AdvSearchBuilder so we can enable blacklight_advanced_search + # TODO ROB config.search_builder_class = AdvSearchBuilder + # Show gallery view config.view.gallery.partials = %i[index_header index] config.view.slideshow.partials = [:index] + # Because too many times on Samvera tech people raise a problem regarding a failed query to SOLR. + # Often, it's because they inadvertently exceeded the character limit of a GET request. + config.http_method = :post + ## Default parameters to send to solr for all search-like requests. See also SolrHelper#solr_search_params config.default_solr_params = { qt: "search", rows: 10, - qf: "title_tesim description_tesim creator_tesim keyword_tesim all_text_timv" + qf: IiifPrint.config.metadata_fields.keys.map { |attribute| "#{attribute}_tesim" } + .join(' ') << " title_tesim description_tesim all_text_timv file_set_text_tsimv", # the first space character is necessary! + "hl": true, + "hl.simple.pre": "", + "hl.simple.post": "", + "hl.snippets": 30, + "hl.fragsize": 100 } # Specify which field to use in the tag cloud on the homepage. @@ -81,11 +110,34 @@ def self.modified_field config.add_facet_field 'file_format_sim', limit: 5 config.add_facet_field 'member_of_collections_ssim', limit: 5, label: 'Collections' + + # TODO deal with part of facet changes + # config.add_facet_field solr_name("part", :facetable), limit: 5, label: 'Part' + # config.add_facet_field solr_name("part_of", :facetable), limit: 5 + # removed # config.add_facet_field solr_name("file_format", :facetable), limit: 5 + # removed # config.add_facet_field solr_name("contributor", :facetable), label: "Contributor", limit: 5 + # remvode config.add_facet_field solr_name("refereed", :facetable), limit: 5 + # Have BL send all facet field names to Solr, which has been the default # previously. Simply remove these lines if you'd rather use Solr request # handler defaults, or have no facets. config.add_facet_fields_to_solr_request! + # Prior to this change, the applications specific translations were not loaded. Dogbiscuits were assuming the translations were already loaded. + Rails.root.glob("config/locales/*.yml").each do |path| + I18n.load_path << path.to_s + end + I18n.backend.reload! + index_props = DogBiscuits.config.index_properties.collect do |prop| + { prop => index_options(prop, DogBiscuits.config.property_mappings[prop]) } + end + add_index_field config, index_props + + # solr fields to be displayed in the show (single result) view + # The ordering of the field names is the order of the display + # show_props = DogBiscuits.config.all_properties + # add_show_field config, show_props + # solr fields to be displayed in the index (search results) view # The ordering of the field names is the order of the display config.add_index_field 'title_tesim', label: "Title", itemprop: 'name', if: false @@ -150,6 +202,8 @@ def self.modified_field # since we aren't specifying it otherwise. config.add_search_field('all_fields', label: 'All Fields', include_in_advanced_search: false) do |field| all_names = config.show_fields.values.map(&:field).join(" ") +# TODO ROB all_names = (config.show_fields.values.map { |v| v.field.to_s } + + # DogBiscuits.config.all_properties.map { |p| "#{p}_tesim" }).uniq.join(" ") title_name = 'title_tesim' field.solr_parameters = { qf: "#{all_names} file_format_tesim all_text_timv", @@ -178,6 +232,7 @@ def self.modified_field end config.add_search_field('creator') do |field| + # TODO ROB field.label = "Author" field.solr_parameters = { "spellcheck.dictionary": "creator" } solr_name = 'creator_tesim' field.solr_local_parameters = { @@ -220,6 +275,8 @@ def self.modified_field } end + date_fields = ['date_created_tesim', 'sorted_date_isi', 'sorted_month_isi'] + config.add_search_field('date_created') do |field| field.solr_parameters = { "spellcheck.dictionary": "date_created" @@ -343,16 +400,27 @@ def self.modified_field } end + config.add_search_field('source') do |field| + solr_name = solr_name("source", :stored_searchable) + field.solr_local_parameters = { + qf: solr_name, + pf: solr_name + } + end + # "sort results by" select (pulldown) # label in pulldown is followed by the name of the SOLR field to sort by and # whether the sort is ascending or descending (it must be asc or desc # except in the relevancy case). # label is key, solr field is value - config.add_sort_field "score desc, #{uploaded_field} desc", label: "relevance" - config.add_sort_field "#{uploaded_field} desc", label: "date uploaded \u25BC" - config.add_sort_field "#{uploaded_field} asc", label: "date uploaded \u25B2" - config.add_sort_field "#{modified_field} desc", label: "date modified \u25BC" - config.add_sort_field "#{modified_field} asc", label: "date modified \u25B2" + config.add_sort_field "score desc, #{uploaded_field} desc", label: "Relevance" + + config.add_sort_field "#{title_field} asc", label: "Title" + config.add_sort_field "#{creator_field} asc", label: "Author" + config.add_sort_field "#{created_field} asc", label: "Published Date (Ascending)" + config.add_sort_field "#{created_field} desc", label: "Published Date (Descending)" + config.add_sort_field "#{modified_field} asc", label: "Upload Date (Ascending)" + config.add_sort_field "#{modified_field} desc", label: "Upload Date (Descending)" # OAI Config fields config.oai = { diff --git a/app/controllers/saved_searches_controller.rb b/app/controllers/saved_searches_controller.rb new file mode 100644 index 000000000..f2618be72 --- /dev/null +++ b/app/controllers/saved_searches_controller.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class SavedSearchesController < ApplicationController + include Blacklight::SavedSearches + + helper BlacklightAdvancedSearch::RenderConstraintsOverride +end diff --git a/app/controllers/search_history_controller.rb b/app/controllers/search_history_controller.rb new file mode 100644 index 000000000..a97b2e3ff --- /dev/null +++ b/app/controllers/search_history_controller.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +class SearchHistoryController < ApplicationController + include Blacklight::SearchHistory + helper BlacklightAdvancedSearch::RenderConstraintsOverride + helper BlacklightRangeLimit::ViewHelperOverride + helper RangeLimitHelper +end diff --git a/app/models/collection.rb b/app/models/collection.rb index 39bd58492..2b2298fd8 100644 --- a/app/models/collection.rb +++ b/app/models/collection.rb @@ -8,6 +8,7 @@ class Collection < ActiveFedora::Base self.indexer = CollectionIndexer after_update :remove_featured, if: proc { |collection| collection.private? } after_destroy :remove_featured + prepend OrderAlready.for(:creator) def remove_featured FeaturedCollection.where(collection_id: id).destroy_all diff --git a/app/models/generic_work.rb b/app/models/generic_work.rb index b8b740217..5ee8e9c01 100644 --- a/app/models/generic_work.rb +++ b/app/models/generic_work.rb @@ -10,4 +10,7 @@ class GenericWork < ActiveFedora::Base validates :title, presence: { message: 'Your work must have a title.' } self.indexer = GenericWorkIndexer + + prepend OrderAlready.for(:creator) + end diff --git a/app/models/image.rb b/app/models/image.rb index e0218ec94..83adf2208 100644 --- a/app/models/image.rb +++ b/app/models/image.rb @@ -17,6 +17,8 @@ class Image < ActiveFedora::Base include ::Hyrax::BasicMetadata self.indexer = ImageIndexer + prepend OrderAlready.for(:creator) + # Change this to restrict which works can be added as a child. # self.valid_child_concerns = [] validates :title, presence: { message: 'Your work must have a title.' } diff --git a/app/models/search_builder.rb b/app/models/search_builder.rb index ad50b6e1e..4410a5bc8 100644 --- a/app/models/search_builder.rb +++ b/app/models/search_builder.rb @@ -2,6 +2,10 @@ class SearchBuilder < Blacklight::SearchBuilder include Blacklight::Solr::SearchBuilderBehavior + include BlacklightRangeLimit::RangeLimitBuilder + include BlacklightAdvancedSearch::AdvancedSearchBuilder include Hydra::AccessControlsEnforcement include Hyrax::SearchFilters + + self.default_processor_chain += %i[add_advanced_parse_q_to_solr add_advanced_search_to_solr] end diff --git a/app/views/advanced/_advanced_search_help.html.erb b/app/views/advanced/_advanced_search_help.html.erb new file mode 100644 index 000000000..df18fcbc5 --- /dev/null +++ b/app/views/advanced/_advanced_search_help.html.erb @@ -0,0 +1,26 @@ +
+
+

Search tips

+
    +
  • Select "match all" to require all fields. +
  • + +
  • Select "match any" to find at least one field. +
  • + +
  • Combine keywords and attributes to find specific items. +
  • + +
  • Search by date with format: YYYYMMDD, YYYYMM or YYYY. Do not use "-", "/", or any other special characters.
  • + +
  • Use quotation marks to search as a phrase. + +
  • Use "+" before a term to make it required. (Otherwise results matching only some of your terms may be included).
  • + +
  • Use "-" before a word or phrase to exclude. + +
  • Use "OR", "AND", and "NOT" to create complex boolean logic. You can use parentheses in your complex expressions.
  • +
  • Truncation and wildcards are not supported - word-stemming is done automatically.
  • +
+
+
diff --git a/app/views/blacklight_range_limit/_range_limit_panel.html.erb b/app/views/blacklight_range_limit/_range_limit_panel.html.erb new file mode 100644 index 000000000..738e6e3d7 --- /dev/null +++ b/app/views/blacklight_range_limit/_range_limit_panel.html.erb @@ -0,0 +1,125 @@ +<%- # requires solr_config local passed in + field_config = range_config(field_name) + label = facet_field_label(field_name) + + input_label_range_begin = field_config[:input_label_range_begin] || t("blacklight.range_limit.range_begin", field_label: label) + input_label_range_end = field_config[:input_label_range_end] || t("blacklight.range_limit.range_end", field_label: label) + maxlength = field_config[:maxlength] +-%> + + +<%# NOTE(dewey4iv): leaving the styling here for now so that Christy can test out what she wants this to look like %> + + +
+ <% if has_selected_range_limit?(field_name) %> +
    +
  • + + <%= range_display(field_name) %> + <%= link_to remove_range_param(field_name), :class=>"remove", :title => t('blacklight.range_limit.remove_limit') do %> + + [<%= t('blacklight.range_limit.remove_limit') %>] + <% end %> + + <%= number_with_delimiter(@response.total) %> +
  • +
+ + <% end %> + + <% unless selected_missing_for_range_limit?(field_name) %> + <%= form_tag search_action_path, :method => :get, class: [BlacklightRangeLimit.classes[:form], "range_#{field_name}"].join(' ') do %> + <%= render_hash_as_hidden_fields(search_state.params_for_search.except(:page)) %> + + + <% unless params.has_key?(:search_field) %> + <%= hidden_field_tag("search_field", "dummy_range") %> + <% end %> + +
+ Between year: + <%= render_range_input(field_name, :begin, input_label_range_begin, maxlength) %> +
+
+ and year: + <%= render_range_input(field_name, :end, input_label_range_end, maxlength) %> +
+ <%= submit_tag t('blacklight.range_limit.submit_limit'), class: "#{BlacklightRangeLimit.classes[:submit]} btn btn-default btn-block" %> + <% end %> + <% end %> + + + <% unless selected_missing_for_range_limit?(field_name) %> + +
+ <% if stats_for_field?(field_name) %> + + <% end %> + + <% if (min = range_results_endpoint(field_name, :min)) && + (max = range_results_endpoint(field_name, :max)) %> +

"> + +

+ + <% if field_config[:segments] != false %> +
+ + <% if solr_range_queries_to_a(field_name).length > 0 %> + + <%= render(:partial => "blacklight_range_limit/range_segments", :locals => {:solr_field => field_name}) %> + + <% else %> + <%= link_to('View distribution', main_app.url_for(search_state.to_h.merge(action: 'range_limit', range_field: field_name, range_start: min, range_end: max)), :class => "load_distribution") %> + <% end %> +
+ <% end %> + <% end %> + + <% if (stats = stats_for_field(field_name)) %> +
    +
  • + + <%= link_to BlacklightRangeLimit.labels[:missing], add_range_missing(field_name) %> + + + <%= number_with_delimiter(stats["missing"]) %> + +
  • +
+ <% end %> +
+ <% end %> +
diff --git a/config/routes.rb b/config/routes.rb index 73a5d0f50..49f57635c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -70,9 +70,10 @@ mount Qa::Engine => '/authorities' mount Blacklight::Engine => '/' + mount BlacklightAdvancedSearch::Engine => '/' mount Hyrax::Engine, at: '/' mount Bulkrax::Engine, at: '/' if ENV.fetch('HYKU_BULKRAX_ENABLED', 'true') == 'true' - + mount HykuKnapsack::Engine, at: '/' concern :searchable, Blacklight::Routes::Searchable.new concern :exportable, Blacklight::Routes::Exportable.new @@ -82,6 +83,7 @@ concerns :oai_provider concerns :searchable + concerns :range_searchable end resources :solr_documents, only: [:show], path: '/catalog', controller: 'catalog' do From 0a6a2667c691c216d000cd8e51d1621dddcab21a Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Thu, 21 Sep 2023 00:01:30 -0700 Subject: [PATCH 002/126] add a few content blocks in from adventist --- .../content_blocks_controller_decorator.rb | 18 ++++++++ app/views/hyrax/content_blocks/_form.html.erb | 42 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 app/controllers/hyrax/content_blocks_controller_decorator.rb diff --git a/app/controllers/hyrax/content_blocks_controller_decorator.rb b/app/controllers/hyrax/content_blocks_controller_decorator.rb new file mode 100644 index 000000000..348ac4f20 --- /dev/null +++ b/app/controllers/hyrax/content_blocks_controller_decorator.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# OVERRIDE Hyrax v3.4.0 to add home_text to permitted_params - Adding themes +module Hyrax + module ContentBlocksControllerDecorator + # override hyrax v2.9.0 added the home_text content block to permitted_params - Adding Themes + def permitted_params + params.require(:content_block).permit(:marketing, + :announcement, + :home_text, + :homepage_about_section_heading, + :homepage_about_section_content, + :researcher) + end + end +end + +Hyrax::ContentBlocksController.prepend Hyrax::ContentBlocksControllerDecorator diff --git a/app/views/hyrax/content_blocks/_form.html.erb b/app/views/hyrax/content_blocks/_form.html.erb index ccf22f70f..76d7e0d26 100644 --- a/app/views/hyrax/content_blocks/_form.html.erb +++ b/app/views/hyrax/content_blocks/_form.html.erb @@ -15,6 +15,12 @@
  • <%= t(:'hyrax.content_blocks.tabs.featured_researcher') %>
  • +
  • + <%= t(:'hyrax.content_blocks.tabs.homepage_about_section_heading') %> +
  • +
  • + <%= t(:'hyrax.content_blocks.tabs.homepage_about_section_content') %> +
  • @@ -90,6 +96,42 @@ <% end %>
    +
    +
    + <%= simple_form_for ContentBlock.for(:homepage_about_section_heading), url: hyrax.content_block_path(ContentBlock.for(:homepage_about_section_heading)), html: {class: 'nav-safety'} do |f| %> +
    +
    + <%= f.label :homepage_about_section_heading %>
    + <%# the following line was changed from hyrax to give some context for what this context block does %> +

    <%= t(:'hyrax.content_blocks.instructions.homepage_about_section_heading_instructions') %>

    + <%= f.text_area :homepage_about_section_heading, value: f.object.value, class: 'form-control tinymce', rows: 20, cols: 120 %> +
    +
    + + <% end %> +
    +
    +
    +
    + <%= simple_form_for ContentBlock.for(:homepage_about_section_content), url: hyrax.content_block_path(ContentBlock.for(:homepage_about_section_content)), html: {class: 'nav-safety'} do |f| %> +
    +
    + <%= f.label :homepage_about_section_content %>
    + <%# the following line was changed from hyrax to give some context for what this context block does %> +

    <%= t(:'hyrax.content_blocks.instructions.homepage_about_section_content_instructions') %>

    + <%= f.text_area :homepage_about_section_content, value: f.object.value, class: 'form-control tinymce', rows: 20, cols: 120 %> +
    +
    + + <% end %> +
    +
    <%= tinymce :content_block %> From f78eb75f5aa6e08f3e3c6514affe6649975adfb1 Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Thu, 21 Sep 2023 00:02:33 -0700 Subject: [PATCH 003/126] do not need full controller override --- .../hyrax/content_blocks_controller.rb | 44 ------------------- 1 file changed, 44 deletions(-) delete mode 100644 app/controllers/hyrax/content_blocks_controller.rb diff --git a/app/controllers/hyrax/content_blocks_controller.rb b/app/controllers/hyrax/content_blocks_controller.rb deleted file mode 100644 index 60edc5286..000000000 --- a/app/controllers/hyrax/content_blocks_controller.rb +++ /dev/null @@ -1,44 +0,0 @@ -# frozen_string_literal: true - -# OVERRIDE Hyrax v3.4.0 to add home_text to permitted_params - Adding themes -module Hyrax - class ContentBlocksController < ApplicationController - load_and_authorize_resource - with_themed_layout 'dashboard' - - def edit - add_breadcrumb t(:'hyrax.controls.home'), root_path - add_breadcrumb t(:'hyrax.dashboard.breadcrumbs.admin'), hyrax.dashboard_path - add_breadcrumb t(:'hyrax.admin.sidebar.configuration'), '#' - add_breadcrumb t(:'hyrax.admin.sidebar.content_blocks'), hyrax.edit_content_blocks_path - end - - def update - respond_to do |format| - if @content_block.update(value: update_value_from_params) - format.html { redirect_to hyrax.edit_content_blocks_path, notice: t(:'hyrax.content_blocks.updated') } - else - format.html { render :edit } - end - end - end - - private - - # override hyrax v2.9.0 added the home_text content block to permitted_params - Adding Themes - def permitted_params - params.require(:content_block).permit(:marketing, - :announcement, - :home_text, - :researcher) - end - - # When a request comes to the controller, it will be for one and - # only one of the content blocks. Params always looks like: - # {'about_page' => 'Here is an awesome about page!'} - # So reach into permitted params and pull out the first value. - def update_value_from_params - permitted_params.values.first - end - end -end From 29873b1a0841f89559263718fc622993e122533d Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Thu, 21 Sep 2023 00:08:38 -0700 Subject: [PATCH 004/126] use the new content blocks --- app/controllers/hyrax/homepage_controller.rb | 131 ------------------ .../hyrax/homepage_controller_decorator.rb | 20 +++ 2 files changed, 20 insertions(+), 131 deletions(-) delete mode 100644 app/controllers/hyrax/homepage_controller.rb create mode 100644 app/controllers/hyrax/homepage_controller_decorator.rb diff --git a/app/controllers/hyrax/homepage_controller.rb b/app/controllers/hyrax/homepage_controller.rb deleted file mode 100644 index a38eda845..000000000 --- a/app/controllers/hyrax/homepage_controller.rb +++ /dev/null @@ -1,131 +0,0 @@ -# frozen_string_literal: true - -# OVERRIDE: Hyrax v2.9.0 to add home_text content block to the index method - Adding themes -# OVERRIDE: Hyrax v2.9.0 from Hyrax v2.9.0 to add facets to home page - inheriting from -# CatalogController rather than ApplicationController -# OVERRIDE: Hyrax v2.9.0 from Hyrax v2.9.0 to add inject_theme_views method for theming -# OVERRIDE: Hyrax v2.9.0 to add search_action_url method from Blacklight 6.23.0 to make facet links to go to /catalog -# OVERRIDE: Hyrax v2.9.0 to add .sort_by to return collections in alphabetical order by title on the homepage -# OVERRIDE: Hyrax v2.9.0 add all_collections page for IR theme -# OVERRIDE: Hyrax v2.9.0 to add facet counts for resource types for IR theme -# OVERRIDE: Hyrax v. 2.9.0 to add @featured_collection_list to index method - -module Hyrax - # Changed to inherit from CatalogController for home page facets - class HomepageController < CatalogController - # Adds Hydra behaviors into the application controller - include Blacklight::SearchContext - include Blacklight::SearchHelper - include Blacklight::AccessControls::Catalog - - around_action :inject_theme_views - - # The search builder for finding recent documents - # Override of Blacklight::RequestBuilders - def search_builder_class - Hyrax::HomepageSearchBuilder - end - - class_attribute :presenter_class - self.presenter_class = Hyrax::HomepagePresenter - layout 'homepage' - helper Hyrax::ContentBlockHelper - - # override hyrax v2.9.0 added @home_text - Adding Themes - def index - @presenter = presenter_class.new(current_ability, collections) - @featured_researcher = ContentBlock.for(:researcher) - @marketing_text = ContentBlock.for(:marketing) - @home_text = ContentBlock.for(:home_text) - @featured_work_list = FeaturedWorkList.new - # OVERRIDE here to add featured collection list - @featured_collection_list = FeaturedCollectionList.new - @announcement_text = ContentBlock.for(:announcement) - recent - ir_counts if home_page_theme == 'institutional_repository' - - # override hyrax v2.9.0 added for facets on homepage - Adding Themes - (@response, @document_list) = search_results(params) - - respond_to do |format| - format.html { store_preferred_view } - format.rss { render layout: false } - format.atom { render layout: false } - format.json do - @presenter = Blacklight::JsonPresenter.new(@response, - @document_list, - facets_from_request, - blacklight_config) - end - additional_response_formats(format) - document_export_formats(format) - end - end - - def browserconfig; end - - def all_collections - @presenter = presenter_class.new(current_ability, collections) - @marketing_text = ContentBlock.for(:marketing) - @announcement_text = ContentBlock.for(:announcement) - @collections = collections(rows: 100_000) - ir_counts if home_page_theme == 'institutional_repository' - end - - # Added from Blacklight 6.23.0 to change url for facets on home page - protected - - # Default route to the search action (used e.g. in global partials). Override this method - # in a controller or in your ApplicationController to introduce custom logic for choosing - # which action the search form should use - def search_action_url(options = {}) - # Rails 4.2 deprecated url helpers accepting string keys for 'controller' or 'action' - main_app.search_catalog_path(options) - end - - private - - # Return 6 collections - def collections(rows: 6) - builder = Hyrax::CollectionSearchBuilder.new(self) - .rows(rows) - response = repository.search(builder) - # adding .sort_by to return collections in alphabetical order by title on the homepage - response.documents.sort_by(&:title) - rescue Blacklight::Exceptions::ECONNREFUSED, Blacklight::Exceptions::InvalidRequest - [] - end - - def recent - # grab any recent documents - (_, @recent_documents) = search_results(q: '', sort: sort_field, rows: 6) - rescue Blacklight::Exceptions::ECONNREFUSED, Blacklight::Exceptions::InvalidRequest - @recent_documents = [] - end - - # OVERRIDE: Hyrax v2.9.0 to add facet counts for resource types for IR theme - def ir_counts - @ir_counts = get_facet_field_response('resource_type_sim', {}, "f.resource_type_sim.facet.limit" => "-1") - end - - def sort_field - "date_uploaded_dtsi desc" - end - - # Add this method to prepend the theme views into the view_paths - def inject_theme_views - if home_page_theme && home_page_theme != 'default_home' - original_paths = view_paths - home_theme_view_path = Rails.root.join('app', 'views', "themes", home_page_theme.to_s) - prepend_view_path(home_theme_view_path) - yield - # rubocop:disable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses - # Do NOT change this line. This is calling the Rails view_paths=(paths) method and not a variable assignment. - view_paths=(original_paths) - # rubocop:enable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses - else - yield - end - end - end -end diff --git a/app/controllers/hyrax/homepage_controller_decorator.rb b/app/controllers/hyrax/homepage_controller_decorator.rb new file mode 100644 index 000000000..58712bfd7 --- /dev/null +++ b/app/controllers/hyrax/homepage_controller_decorator.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +# OVERRIDE Hyrax 3.5 to add content blocks +module Hyrax + module HomepageControllerDecorator + + def index + @presenter = presenter_class.new(current_ability, collections) + @featured_researcher = ContentBlock.for(:researcher) + @marketing_text = ContentBlock.for(:marketing) + @featured_work_list = FeaturedWorkList.new + @announcement_text = ContentBlock.for(:announcement) + @homepage_about_section_heading = ContentBlock.for(:homepage_about_section_heading) + @homepage_about_section_content = ContentBlock.for(:homepage_about_section_content) + recent + end + end +end + +Hyrax::HomepageController.prepend Hyrax::HomepageControllerDecorator From 7510b7c67825cda9f468bb761a3e880f823b440c Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Thu, 21 Sep 2023 00:17:46 -0700 Subject: [PATCH 005/126] iiif rodeo includes --- config/application.rb | 61 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/config/application.rb b/config/application.rb index 850a2b515..acf7c0523 100644 --- a/config/application.rb +++ b/config/application.rb @@ -9,7 +9,35 @@ Bundler.require(*groups) module Hyku + # Providing a common method to ensure consistent UTF-8 encoding. Also removing the tricksy Byte + # Order Marker character which is an invisible 0 space character. + # + # @note In testing, we encountered errors with the file's character encoding + # (e.g. `Encoding::UndefinedConversionError`). The following will force the encoding to + # UTF-8 and replace any invalid or undefined characters from the original encoding with a + # "?". + # + # Given that we still have the original, and this is a derivative, the forced encoding + # should be acceptable. + # + # @param [String] + # @return [String] + # + # @see https://sentry.io/organizations/scientist-inc/issues/3773392603/?project=6745020&query=is%3Aunresolved&referrer=issue-stream + # @see https://github.com/samvera-labs/bulkrax/pull/689 + # @see https://github.com/samvera-labs/bulkrax/issues/688 + # @see https://github.com/scientist-softserv/adventist-dl/issues/179 + def self.utf_8_encode(string) + string + .encode(Encoding.find('UTF-8'), invalid: :replace, undef: :replace, replace: "?") + .delete("\xEF\xBB\xBF") + end + class Application < Rails::Application + # Add this line to load the lib folder first because we need + # IiifPrint::SplitPdfs::AdventistPagesToJpgsSplitter + config.autoload_paths.unshift("#{Rails.root}/lib") + # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. @@ -33,22 +61,37 @@ class Application < Rails::Application end config.to_prepare do - # Allows us to use decorator files in the app directory + + # By default plain text files are not processed for text extraction. In adding + # Adventist::TextFileTextExtractionService to the beginning of the services array we are + # enabling text extraction from plain text files. + Hyrax::DerivativeService.services = [ + Adventist::TextFileTextExtractionService, + IiifPrint::PluggableDerivativeService] + + # When you are ready to use the derivative rodeo instead of the pluggable uncomment the + # following and comment out the preceding Hyrax::DerivativeService.service + # + # Hyrax::DerivativeService.services = [ + # Adventist::TextFileTextExtractionService, + # IiifPrint::DerivativeRodeoService, + # Hyrax::FileSetDerivativesService] + + DerivativeRodeo::Generators::HocrGenerator.additional_tessearct_options = "-l eng_best" + + # Allows us to use decorator files Dir.glob(File.join(File.dirname(__FILE__), "../app/**/*_decorator*.rb")).sort.each do |c| Rails.configuration.cache_classes ? require(c) : load(c) end - end - config.to_prepare do - # Allows us to use decorator files in the app directory Dir.glob(File.join(File.dirname(__FILE__), "../lib/**/*_decorator*.rb")).sort.each do |c| Rails.configuration.cache_classes ? require(c) : load(c) end - end - # OAI additions - Dir.glob(File.join(File.dirname(__FILE__), "../lib/oai/**/*.rb")).sort.each do |c| - Rails.configuration.cache_classes ? require(c) : load(c) + # OAI additions + Dir.glob(File.join(File.dirname(__FILE__), "../lib/oai/**/*.rb")).sort.each do |c| + Rails.configuration.cache_classes ? require(c) : load(c) + end end # resolve reloading issue in dev mode @@ -67,6 +110,8 @@ class Application < Rails::Application Object.include(AccountSwitch) end + # copies tinymce assets directly into public/assets + config.tinymce.install = :copy ## # Psych Allow YAML Classes # From 3f22a3353508fa9c277b1762372182bd04b4856b Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Thu, 21 Sep 2023 01:06:38 -0700 Subject: [PATCH 006/126] remove dogbiscuit crossover, fix routes --- app/controllers/catalog_controller.rb | 19 ++++++++++--------- config/routes.rb | 1 + 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/app/controllers/catalog_controller.rb b/app/controllers/catalog_controller.rb index 17eca79a9..c50f887b0 100644 --- a/app/controllers/catalog_controller.rb +++ b/app/controllers/catalog_controller.rb @@ -123,15 +123,16 @@ def self.uploaded_field # handler defaults, or have no facets. config.add_facet_fields_to_solr_request! - # Prior to this change, the applications specific translations were not loaded. Dogbiscuits were assuming the translations were already loaded. - Rails.root.glob("config/locales/*.yml").each do |path| - I18n.load_path << path.to_s - end - I18n.backend.reload! - index_props = DogBiscuits.config.index_properties.collect do |prop| - { prop => index_options(prop, DogBiscuits.config.property_mappings[prop]) } - end - add_index_field config, index_props + # TODO ROB +# # Prior to this change, the applications specific translations were not loaded. Dogbiscuits were assuming the translations were already loaded. +# Rails.root.glob("config/locales/*.yml").each do |path| +# I18n.load_path << path.to_s +# end +# I18n.backend.reload! +# index_props = DogBiscuits.config.index_properties.collect do |prop| +# { prop => index_options(prop, DogBiscuits.config.property_mappings[prop]) } +# end +# add_index_field config, index_props # solr fields to be displayed in the show (single result) view # The ordering of the field names is the order of the display diff --git a/config/routes.rb b/config/routes.rb index 49f57635c..f0a2a3753 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -6,6 +6,7 @@ Rails.application.routes.draw do # rubocop:disable Metrics/BlockLength resources :identity_providers + concern :range_searchable, BlacklightRangeLimit::Routes::RangeSearchable.new concern :iiif_search, BlacklightIiifSearch::Routes.new concern :oai_provider, BlacklightOaiProvider::Routes.new From 36590bc0fe34569bd56cd3eba5ca6cac70bef5ba Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Thu, 21 Sep 2023 10:12:59 -0700 Subject: [PATCH 007/126] add spec for search history --- .../search_history_controller_spec.rb | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 spec/controllers/search_history_controller_spec.rb diff --git a/spec/controllers/search_history_controller_spec.rb b/spec/controllers/search_history_controller_spec.rb new file mode 100644 index 000000000..d9a349279 --- /dev/null +++ b/spec/controllers/search_history_controller_spec.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +RSpec.describe SearchHistoryController do + routes { Blacklight::Engine.routes } + + describe 'index' do + let(:one) { Search.create } + let(:two) { Search.create } + let(:three) { Search.create } + + it 'only fetches searches with ids in the session' do + session[:history] = [one.id, three.id] + get :index + searches = assigns(:searches) + expect(searches).to include(one) + expect(searches).not_to include(two) + end + + it 'tolerates bad ids in session' do + session[:history] = [one.id, three.id, 'NOT_IN_DB'] + get :index + searches = assigns(:searches) + expect(searches).to include(one) + expect(searches).to include(three) + end + + it 'does not fetch any searches if there is no history' do + session[:history] = [] + get :index + searches = assigns(:searches) + expect(searches).to be_empty + end + end +end From 326576ecb20fe033d777f7c3276e533744825609 Mon Sep 17 00:00:00 2001 From: Shana Moore Date: Thu, 21 Sep 2023 10:25:09 -0700 Subject: [PATCH 008/126] add missing methods to avoid content block errors --- .../hyrax/homepage_controller_decorator.rb | 20 +++++++++++++++++++ app/models/content_block.rb | 20 ++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 app/controllers/hyrax/homepage_controller_decorator.rb diff --git a/app/controllers/hyrax/homepage_controller_decorator.rb b/app/controllers/hyrax/homepage_controller_decorator.rb new file mode 100644 index 000000000..826a8599b --- /dev/null +++ b/app/controllers/hyrax/homepage_controller_decorator.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +# OVERRIDE Hyrax 3.5 to add content blocks +module Hyrax + module HomepageControllerDecorator + + def index + @presenter = presenter_class.new(current_ability, collections) + @featured_researcher = ContentBlock.for(:researcher) + @marketing_text = ContentBlock.for(:marketing) + @featured_work_list = FeaturedWorkList.new + @announcement_text = ContentBlock.for(:announcement) + @homepage_about_section_heading = ContentBlock.for(:homepage_about_section_heading) + @homepage_about_section_content = ContentBlock.for(:homepage_about_section_content) + recent + end + end +end + +Hyrax::HomepageController.prepend Hyrax::HomepageControllerDecorator diff --git a/app/models/content_block.rb b/app/models/content_block.rb index c9e72b26e..4c00535b3 100644 --- a/app/models/content_block.rb +++ b/app/models/content_block.rb @@ -16,7 +16,9 @@ class ContentBlock < ApplicationRecord help: :help_page, terms: :terms_page, agreement: :agreement_page, - home_text: :home_text + home_text: :home_text, + homepage_about_section_heading: :homepage_about_section_heading, + homepage_about_section_content: :homepage_about_section_content }.freeze # NOTE: method defined outside the metaclass wrapper below because @@ -90,6 +92,22 @@ def home_text=(value) home_text.update(value: value) end + def homepage_about_section_heading + find_or_create_by(name: 'homepage_about_section_heading') + end + + def homepage_about_section_heading=(value) + homepage_about_section_heading.update(value: value) + end + + def homepage_about_section_content + find_or_create_by(name: 'homepage_about_section_content') + end + + def homepage_about_section_content=(value) + homepage_about_section_content.update(value: value) + end + def about_page find_or_create_by(name: 'about_page') end From 189917593629103f6c21031d575fab6fcc404ec2 Mon Sep 17 00:00:00 2001 From: LaRita Robinson Date: Fri, 22 Sep 2023 15:28:48 -0400 Subject: [PATCH 009/126] Update Hyku Gemfile.lock --- Gemfile.lock | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Gemfile.lock b/Gemfile.lock index 4436734e8..f471801a6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -210,6 +210,9 @@ GEM bootstrap-sass (~> 3.0) openseadragon (>= 0.2.0) rails + blacklight_advanced_search (6.4.1) + blacklight (~> 6.0, >= 6.0.1) + parslet blacklight_iiif_search (1.0.0) blacklight (~> 6.0) iiif-presentation @@ -217,6 +220,10 @@ GEM blacklight_oai_provider (6.1.1) blacklight (~> 6.0) oai (~> 1.0) + blacklight_range_limit (6.5.0) + blacklight (~> 6.10) + jquery-rails + rails (>= 4.2, < 6) bolognese (1.11.0) activesupport (>= 4.2.5) benchmark_methods (~> 0.7) @@ -871,6 +878,8 @@ GEM openseadragon (0.6.0) rails (> 3.2.0) optimist (3.0.1) + order_already (0.3.1) + rails-html-sanitizer (~> 1.4) orm_adapter (0.5.0) os (1.1.4) parallel (1.23.0) @@ -1296,7 +1305,9 @@ DEPENDENCIES apartment aws-sdk-sqs blacklight (~> 6.7) + blacklight_advanced_search blacklight_oai_provider (~> 6.1, >= 6.1.1) + blacklight_range_limit (= 6.5.0) bolognese (>= 1.9.10) bootstrap-datepicker-rails bulkrax (~> 5.3) @@ -1338,6 +1349,7 @@ DEPENDENCIES omniauth-rails_csrf_protection (~> 1.0) omniauth-saml (~> 2.1) omniauth_openid_connect + order_already parser (~> 2.5.3) pg postrank-uri (>= 1.0.24) From 4dc0dcd362a56c5ed94cacaff8f881305a121175 Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Fri, 22 Sep 2023 13:08:16 -0700 Subject: [PATCH 010/126] add option to support good job for background jobs instead of sidekiq --- Gemfile | 1 + Gemfile.lock | 17 +++++++ bin/worker | 8 +++- config/environments/development.rb | 7 ++- config/initializers/good_job.rb | 44 +++++++++++++++++++ config/initializers/sidekiq.rb | 17 ++++--- config/routes.rb | 12 ++++- db/migrate/20230406183814_create_good_jobs.rb | 38 ++++++++++++++++ 8 files changed, 133 insertions(+), 11 deletions(-) create mode 100644 config/initializers/good_job.rb create mode 100644 db/migrate/20230406183814_create_good_jobs.rb diff --git a/Gemfile b/Gemfile index 868c97ba3..630f95a0f 100644 --- a/Gemfile +++ b/Gemfile @@ -35,6 +35,7 @@ gem 'factory_bot_rails', group: %i[test] gem 'fcrepo_wrapper', '~> 0.4', group: %i[development test] gem 'flipflop', '~> 2.6.0' # waiting for hyrax 4 upgrade gem 'flutie' +gem 'good_job' gem 'hyrax', '~> 3.5.0' gem 'hyrax-doi', github: 'samvera-labs/hyrax-doi', branch: 'main' gem 'hyrax-iiif_av', github: 'samvera-labs/hyrax-iiif_av', branch: 'main' diff --git a/Gemfile.lock b/Gemfile.lock index 4436734e8..88b7a3175 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -13,6 +13,7 @@ GIT branch: upstream_main specs: hyku_knapsack (0.0.1) + good_job rails (>= 5.2.0) GIT @@ -448,6 +449,8 @@ GEM equivalent-xml (0.6.0) nokogiri (>= 1.4.3) erubi (1.12.0) + et-orbi (1.2.7) + tzinfo ethon (0.16.0) ffi (>= 1.15.0) excon (0.71.1) @@ -473,11 +476,23 @@ GEM flutie (2.2.0) font-awesome-rails (4.7.0.8) railties (>= 3.2, < 8.0) + fugit (1.8.1) + et-orbi (~> 1, >= 1.2.7) + raabro (~> 1.4) gender_detector (0.1.2) unicode_utils (>= 1.3.0) geocoder (1.8.1) globalid (1.1.0) activesupport (>= 5.0) + good_job (2.99.0) + activejob (>= 5.2.0) + activerecord (>= 5.2.0) + concurrent-ruby (>= 1.0.2) + fugit (>= 1.1) + railties (>= 5.2.0) + thor (>= 0.14.1) + webrick (>= 1.3) + zeitwerk (>= 2.0) google-apis-core (0.11.0) addressable (~> 2.5, >= 2.5.1) googleauth (>= 0.16.2, < 2.a) @@ -904,6 +919,7 @@ GEM nokogiri (~> 1.6) rails (>= 5.0, < 7.1) rdf + raabro (1.4.0) racc (1.7.1) rack (2.2.8) rack-oauth2 (1.21.3) @@ -1318,6 +1334,7 @@ DEPENDENCIES fcrepo_wrapper (~> 0.4) flipflop (~> 2.6.0) flutie + good_job hyku_knapsack! hyrax (~> 3.5.0) hyrax-doi! diff --git a/bin/worker b/bin/worker index b7605486b..7698b346e 100755 --- a/bin/worker +++ b/bin/worker @@ -9,4 +9,10 @@ else puts 'DATABASE_URL not set, no pool change needed' end -exec "echo $DATABASE_URL && bundle exec sidekiq" +queue = ENV.fetch('HYRAX_ACTIVE_JOB_QUEUE', 'sidekiq') +case queue +when 'sidekiq' + exec "echo $DATABASE_URL && bundle exec sidekiq" +when 'good_job' + exec "echo $DATABASE_URL && bundle exec good_job start" +end diff --git a/config/environments/development.rb b/config/environments/development.rb index 9bafa102c..500278da4 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -4,7 +4,12 @@ # In the development environment your application's code is reloaded on # every request. This slows down response time but is perfect for development # since you don't have to restart the web server when you make code changes. - config.cache_classes = !!Sidekiq.server? + if ENV.fetch('HYRAX_ACTIVE_JOB_QUEUE', 'sidekiq') == 'sidekiq' + config.cache_classes = !!Sidekiq.server? + else + config.cache_classes = false + end + # Do not eager load code on boot. config.eager_load = false diff --git a/config/initializers/good_job.rb b/config/initializers/good_job.rb new file mode 100644 index 000000000..7929a5d4b --- /dev/null +++ b/config/initializers/good_job.rb @@ -0,0 +1,44 @@ + +# frozen_string_literal: true + +if ENV.fetch('HYRAX_ACTIVE_JOB_QUEUE', 'sidekiq') == 'good_job' + Rails.application.configure do + # Configure options individually... + config.good_job.preserve_job_records = true + config.good_job.retry_on_unhandled_error = false + config.good_job.on_thread_error = ->(exception) { Raven.capture_exception(exception) } + config.good_job.execution_mode = :external + # config.good_job.queues = '*' + config.good_job.shutdown_timeout = 60 # seconds + config.good_job.poll_interval = 5 + # config.good_job.enable_cron = true + # config.good_job.cron = { example: { cron: '0 * * * *', class: 'ExampleJob' } } + end + + # Wrapping this in an after_initialize block to ensure that all constants are loaded + Rails.application.config.after_initialize do + # baseline of 0, higher is sooner + + # Commented out the following two jobs because they were + # specfically used for the sdapi ingests. + # see sdapi_ingest_script directory and + # ref: https://github.com/scientist-softserv/adventist-dl/issues/468 + # CollectionMembershipJob.priority = 70 + # UpdateCollectionMembershipJob.priority = 60 + Bulkrax::ScheduleRelationshipsJob.priority = 50 + CreateDerivativesJob.priority = 40 + CharacterizeJob.priority = 30 + Hyrax::GrantEditToMembersJob.priority = 10 + ImportUrlJob.priority = 10 + IngestJob.priority = 10 + ApplicationJob.priority = 0 + AttachFilesToWorkJob.priority = -1 + Bulkrax::ImportWorkJob.priority = -5 + Bulkrax::ImportFileSetJob.priority = -15 + Bulkrax::CreateRelationshipsJob.priority = -20 + Bulkrax::ImporterJob.priority = -20 + IiifPrint::Jobs::CreateRelationshipsJob.priority = -20 + ContentDepositEventJob.priority = -50 + ContentUpdateEventJob.priority = -50 + end +end diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index 6377db666..dc3a30bae 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -1,10 +1,13 @@ -config = YAML.load(ERB.new(IO.read(Rails.root + 'config' + 'redis.yml')).result)[Rails.env].with_indifferent_access -redis_config = config.merge(thread_safe: true) +if ENV.fetch('HYRAX_ACTIVE_JOB_QUEUE', 'sidekiq') == 'sidekiq' -Sidekiq.configure_server do |s| - s.redis = redis_config -end + config = YAML.load(ERB.new(IO.read(Rails.root + 'config' + 'redis.yml')).result)[Rails.env].with_indifferent_access + redis_config = config.merge(thread_safe: true) + + Sidekiq.configure_server do |s| + s.redis = redis_config + end -Sidekiq.configure_client do |s| - s.redis = redis_config + Sidekiq.configure_client do |s| + s.redis = redis_config + end end diff --git a/config/routes.rb b/config/routes.rb index 73a5d0f50..dd3a92676 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,7 +2,9 @@ # OVERRIDE Hyrax 2.9.0 to add featured collection routes -require 'sidekiq/web' +if ENV.fetch('HYRAX_ACTIVE_JOB_QUEUE', 'sidekiq') + require 'sidekiq/web' +end Rails.application.routes.draw do # rubocop:disable Metrics/BlockLength resources :identity_providers @@ -13,7 +15,13 @@ mount Riiif::Engine => 'images', as: :riiif if Hyrax.config.iiif_image_server? authenticate :user, ->(u) { u.is_superadmin || u.is_admin } do - mount Sidekiq::Web => '/jobs' + queue = ENV.fetch('HYRAX_ACTIVE_JOB_QUEUE', 'sidekiq') + case queue + when 'sideki' + mount Sidekiq::Web => '/jobs' + when 'good_job' + mount GoodJob::Engine => '/jobs' + end end if ActiveModel::Type::Boolean.new.cast(ENV.fetch('HYKU_MULTITENANT', false)) diff --git a/db/migrate/20230406183814_create_good_jobs.rb b/db/migrate/20230406183814_create_good_jobs.rb new file mode 100644 index 000000000..d86ab61ac --- /dev/null +++ b/db/migrate/20230406183814_create_good_jobs.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true +class CreateGoodJobs < ActiveRecord::Migration[5.2] + def change + enable_extension 'pgcrypto' + + create_table :good_jobs, id: :uuid do |t| + t.text :queue_name + t.integer :priority + t.jsonb :serialized_params + t.timestamp :scheduled_at + t.timestamp :performed_at + t.timestamp :finished_at + t.text :error + + t.timestamps + + t.uuid :active_job_id + t.text :concurrency_key + t.text :cron_key + t.uuid :retried_good_job_id + t.timestamp :cron_at + end + + create_table :good_job_processes, id: :uuid do |t| + t.timestamps + t.jsonb :state + end + + add_index :good_jobs, :scheduled_at, where: "(finished_at IS NULL)", name: "index_good_jobs_on_scheduled_at" + add_index :good_jobs, [:queue_name, :scheduled_at], where: "(finished_at IS NULL)", name: :index_good_jobs_on_queue_name_and_scheduled_at + add_index :good_jobs, [:active_job_id, :created_at], name: :index_good_jobs_on_active_job_id_and_created_at + add_index :good_jobs, :concurrency_key, where: "(finished_at IS NULL)", name: :index_good_jobs_on_concurrency_key_when_unfinished + add_index :good_jobs, [:cron_key, :created_at], name: :index_good_jobs_on_cron_key_and_created_at + add_index :good_jobs, [:cron_key, :cron_at], name: :index_good_jobs_on_cron_key_and_cron_at, unique: true + add_index :good_jobs, [:active_job_id], name: :index_good_jobs_on_active_job_id + add_index :good_jobs, [:finished_at], where: "retried_good_job_id IS NULL AND finished_at IS NOT NULL", name: :index_good_jobs_jobs_on_finished_at + end +end From c32a948dc1c2fb52286fde5296b2a739075c6cf0 Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Fri, 22 Sep 2023 13:10:45 -0700 Subject: [PATCH 011/126] update gemfile lock --- Gemfile.lock | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 88b7a3175..bd14970f6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -13,8 +13,8 @@ GIT branch: upstream_main specs: hyku_knapsack (0.0.1) - good_job rails (>= 5.2.0) + sentry-raven GIT remote: https://github.com/samvera-labs/hyrax-doi.git @@ -211,6 +211,9 @@ GEM bootstrap-sass (~> 3.0) openseadragon (>= 0.2.0) rails + blacklight_advanced_search (6.4.1) + blacklight (~> 6.0, >= 6.0.1) + parslet blacklight_iiif_search (1.0.0) blacklight (~> 6.0) iiif-presentation @@ -218,6 +221,10 @@ GEM blacklight_oai_provider (6.1.1) blacklight (~> 6.0) oai (~> 1.0) + blacklight_range_limit (6.5.0) + blacklight (~> 6.10) + jquery-rails + rails (>= 4.2, < 6) bolognese (1.11.0) activesupport (>= 4.2.5) benchmark_methods (~> 0.7) @@ -886,6 +893,8 @@ GEM openseadragon (0.6.0) rails (> 3.2.0) optimist (3.0.1) + order_already (0.3.1) + rails-html-sanitizer (~> 1.4) orm_adapter (0.5.0) os (1.1.4) parallel (1.23.0) @@ -1144,6 +1153,8 @@ GEM rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) + sentry-raven (2.13.0) + faraday (>= 0.7.6, < 1.0) shacl (0.1.1) json-ld (~> 3.1, >= 3.1.7) rdf (~> 3.1, >= 3.1.8) @@ -1312,7 +1323,9 @@ DEPENDENCIES apartment aws-sdk-sqs blacklight (~> 6.7) + blacklight_advanced_search blacklight_oai_provider (~> 6.1, >= 6.1.1) + blacklight_range_limit (= 6.5.0) bolognese (>= 1.9.10) bootstrap-datepicker-rails bulkrax (~> 5.3) @@ -1355,6 +1368,7 @@ DEPENDENCIES omniauth-rails_csrf_protection (~> 1.0) omniauth-saml (~> 2.1) omniauth_openid_connect + order_already parser (~> 2.5.3) pg postrank-uri (>= 1.0.24) From 8cf14c488fb4a052ceecca327ef514bdd049f534 Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Fri, 22 Sep 2023 13:13:56 -0700 Subject: [PATCH 012/126] Update good_job.rb --- config/initializers/good_job.rb | 7 ------- 1 file changed, 7 deletions(-) diff --git a/config/initializers/good_job.rb b/config/initializers/good_job.rb index 7929a5d4b..0fe0259a7 100644 --- a/config/initializers/good_job.rb +++ b/config/initializers/good_job.rb @@ -18,13 +18,6 @@ # Wrapping this in an after_initialize block to ensure that all constants are loaded Rails.application.config.after_initialize do # baseline of 0, higher is sooner - - # Commented out the following two jobs because they were - # specfically used for the sdapi ingests. - # see sdapi_ingest_script directory and - # ref: https://github.com/scientist-softserv/adventist-dl/issues/468 - # CollectionMembershipJob.priority = 70 - # UpdateCollectionMembershipJob.priority = 60 Bulkrax::ScheduleRelationshipsJob.priority = 50 CreateDerivativesJob.priority = 40 CharacterizeJob.priority = 30 From 61a9504fbe46041c9fa32285faf97b974ed0969c Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Fri, 22 Sep 2023 15:55:31 -0700 Subject: [PATCH 013/126] merge --- .env | 2 +- config/routes.rb | 4 ++-- db/schema.rb | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/.env b/.env index c8df50c68..c51b5a51e 100644 --- a/.env +++ b/.env @@ -23,7 +23,7 @@ PASSENGER_APP_ENV=development RAILS_LOG_TO_STDOUT=true REDIS_HOST=redis SECRET_KEY_BASE=asdf -HYRAX_ACTIVE_JOB_QUEUE=sidekiq +HYRAX_ACTIVE_JOB_QUEUE=good_job HYRAX_FITS_PATH=/app/fits/fits.sh NEGATIVE_CAPTCHA_SECRET=default-value-change-me SOLR_ADMIN_PASSWORD=SolrRocks diff --git a/config/routes.rb b/config/routes.rb index dd3a92676..93f74b568 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,7 +2,7 @@ # OVERRIDE Hyrax 2.9.0 to add featured collection routes -if ENV.fetch('HYRAX_ACTIVE_JOB_QUEUE', 'sidekiq') +if ENV.fetch('HYRAX_ACTIVE_JOB_QUEUE', 'sidekiq') == 'sidekiq' require 'sidekiq/web' end @@ -17,7 +17,7 @@ authenticate :user, ->(u) { u.is_superadmin || u.is_admin } do queue = ENV.fetch('HYRAX_ACTIVE_JOB_QUEUE', 'sidekiq') case queue - when 'sideki' + when 'sidekiq' mount Sidekiq::Web => '/jobs' when 'good_job' mount GoodJob::Engine => '/jobs' diff --git a/db/schema.rb b/db/schema.rb index c7e628973..c523cfd22 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -13,6 +13,7 @@ ActiveRecord::Schema.define(version: 2023_08_04_073106) do # These are extensions that must be enabled in order to support this database + enable_extension "pgcrypto" enable_extension "plpgsql" create_table "account_cross_searches", force: :cascade do |t| @@ -312,6 +313,37 @@ t.index ["user_id"], name: "index_file_view_stats_on_user_id" end + create_table "good_job_processes", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.jsonb "state" + end + + create_table "good_jobs", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.text "queue_name" + t.integer "priority" + t.jsonb "serialized_params" + t.datetime "scheduled_at" + t.datetime "performed_at" + t.datetime "finished_at" + t.text "error" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.uuid "active_job_id" + t.text "concurrency_key" + t.text "cron_key" + t.uuid "retried_good_job_id" + t.datetime "cron_at" + t.index ["active_job_id", "created_at"], name: "index_good_jobs_on_active_job_id_and_created_at" + t.index ["active_job_id"], name: "index_good_jobs_on_active_job_id" + t.index ["concurrency_key"], name: "index_good_jobs_on_concurrency_key_when_unfinished", where: "(finished_at IS NULL)" + t.index ["cron_key", "created_at"], name: "index_good_jobs_on_cron_key_and_created_at" + t.index ["cron_key", "cron_at"], name: "index_good_jobs_on_cron_key_and_cron_at", unique: true + t.index ["finished_at"], name: "index_good_jobs_jobs_on_finished_at", where: "((retried_good_job_id IS NULL) AND (finished_at IS NOT NULL))" + t.index ["queue_name", "scheduled_at"], name: "index_good_jobs_on_queue_name_and_scheduled_at", where: "(finished_at IS NULL)" + t.index ["scheduled_at"], name: "index_good_jobs_on_scheduled_at", where: "(finished_at IS NULL)" + end + create_table "group_roles", force: :cascade do |t| t.bigint "role_id" t.bigint "group_id" From 363f9ee909e04afa001f80134775a479e42321cd Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Fri, 22 Sep 2023 15:55:51 -0700 Subject: [PATCH 014/126] fix routes file, add missing js file --- app/assets/javascripts/admin_color_select.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 app/assets/javascripts/admin_color_select.js diff --git a/app/assets/javascripts/admin_color_select.js b/app/assets/javascripts/admin_color_select.js new file mode 100644 index 000000000..919193c96 --- /dev/null +++ b/app/assets/javascripts/admin_color_select.js @@ -0,0 +1,20 @@ +$(document).on('turbolinks:load', function() { + $('div.defaultable-colors a.restore-default-color').click(function(e) { + e.preventDefault() + + var defaultTarget = $(e.target).data('default-target') + var input = $("input[name='admin_appearance["+ defaultTarget +"]']") + + input.val(input.data('default-value')) + }) + + $('.panel-footer a.restore-all-default-colors').click(function(e) { + e.preventDefault() + + var allColorInputs = $("input[name*='color']") + + allColorInputs.each(function() { + $(this).val($(this).data('default-value')) + }) + }) +}); \ No newline at end of file From 03dd69e50cc46f5d6e4b6caf02a8b2464742f542 Mon Sep 17 00:00:00 2001 From: Shana Moore Date: Mon, 25 Sep 2023 09:58:43 -0700 Subject: [PATCH 015/126] :lipstick: styling fix --- .../hyrax/homepage_controller_decorator.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/controllers/hyrax/homepage_controller_decorator.rb b/app/controllers/hyrax/homepage_controller_decorator.rb index 826a8599b..0299f6a63 100644 --- a/app/controllers/hyrax/homepage_controller_decorator.rb +++ b/app/controllers/hyrax/homepage_controller_decorator.rb @@ -5,14 +5,14 @@ module Hyrax module HomepageControllerDecorator def index - @presenter = presenter_class.new(current_ability, collections) - @featured_researcher = ContentBlock.for(:researcher) - @marketing_text = ContentBlock.for(:marketing) - @featured_work_list = FeaturedWorkList.new - @announcement_text = ContentBlock.for(:announcement) - @homepage_about_section_heading = ContentBlock.for(:homepage_about_section_heading) - @homepage_about_section_content = ContentBlock.for(:homepage_about_section_content) - recent + @presenter = presenter_class.new(current_ability, collections) + @featured_researcher = ContentBlock.for(:researcher) + @marketing_text = ContentBlock.for(:marketing) + @featured_work_list = FeaturedWorkList.new + @announcement_text = ContentBlock.for(:announcement) + @homepage_about_section_heading = ContentBlock.for(:homepage_about_section_heading) + @homepage_about_section_content = ContentBlock.for(:homepage_about_section_content) + recent end end end From ed161f85c8690c66efdac1a00bd7a87b0cc6a1d9 Mon Sep 17 00:00:00 2001 From: Shana Moore Date: Mon, 25 Sep 2023 10:33:45 -0700 Subject: [PATCH 016/126] :lipstick: rubocop fixes --- app/controllers/catalog_controller.rb | 31 ++++++++++--------- .../content_blocks_controller_decorator.rb | 10 +++--- .../hyrax/homepage_controller_decorator.rb | 1 - app/models/content_block.rb | 2 +- app/models/generic_work.rb | 1 - .../find_ids_by_model_decorator.rb | 7 ++++- 6 files changed, 28 insertions(+), 24 deletions(-) diff --git a/app/controllers/catalog_controller.rb b/app/controllers/catalog_controller.rb index c50f887b0..fbaccce7d 100644 --- a/app/controllers/catalog_controller.rb +++ b/app/controllers/catalog_controller.rb @@ -110,8 +110,7 @@ def self.uploaded_field config.add_facet_field 'file_format_sim', limit: 5 config.add_facet_field 'member_of_collections_ssim', limit: 5, label: 'Collections' - - # TODO deal with part of facet changes + # TODO: deal with part of facet changes # config.add_facet_field solr_name("part", :facetable), limit: 5, label: 'Part' # config.add_facet_field solr_name("part_of", :facetable), limit: 5 # removed # config.add_facet_field solr_name("file_format", :facetable), limit: 5 @@ -123,16 +122,16 @@ def self.uploaded_field # handler defaults, or have no facets. config.add_facet_fields_to_solr_request! - # TODO ROB -# # Prior to this change, the applications specific translations were not loaded. Dogbiscuits were assuming the translations were already loaded. -# Rails.root.glob("config/locales/*.yml").each do |path| -# I18n.load_path << path.to_s -# end -# I18n.backend.reload! -# index_props = DogBiscuits.config.index_properties.collect do |prop| -# { prop => index_options(prop, DogBiscuits.config.property_mappings[prop]) } -# end -# add_index_field config, index_props + # TODO: ROB + # # Prior to this change, the applications specific translations were not loaded. Dogbiscuits were assuming the translations were already loaded. + # Rails.root.glob("config/locales/*.yml").each do |path| + # I18n.load_path << path.to_s + # end + # I18n.backend.reload! + # index_props = DogBiscuits.config.index_properties.collect do |prop| + # { prop => index_options(prop, DogBiscuits.config.property_mappings[prop]) } + # end + # add_index_field config, index_props # solr fields to be displayed in the show (single result) view # The ordering of the field names is the order of the display @@ -203,8 +202,8 @@ def self.uploaded_field # since we aren't specifying it otherwise. config.add_search_field('all_fields', label: 'All Fields', include_in_advanced_search: false) do |field| all_names = config.show_fields.values.map(&:field).join(" ") -# TODO ROB all_names = (config.show_fields.values.map { |v| v.field.to_s } + - # DogBiscuits.config.all_properties.map { |p| "#{p}_tesim" }).uniq.join(" ") + # TODO: ROB all_names = (config.show_fields.values.map { |v| v.field.to_s } + + # DogBiscuits.config.all_properties.map { |p| "#{p}_tesim" }).uniq.join(" ") title_name = 'title_tesim' field.solr_parameters = { qf: "#{all_names} file_format_tesim all_text_timv", @@ -233,7 +232,7 @@ def self.uploaded_field end config.add_search_field('creator') do |field| - # TODO ROB field.label = "Author" + # TODO: ROB field.label = "Author" field.solr_parameters = { "spellcheck.dictionary": "creator" } solr_name = 'creator_tesim' field.solr_local_parameters = { @@ -276,7 +275,9 @@ def self.uploaded_field } end + # rubocop:disable Lint/UselessAssignment date_fields = ['date_created_tesim', 'sorted_date_isi', 'sorted_month_isi'] + # rubocop:enable Lint/UselessAssignment config.add_search_field('date_created') do |field| field.solr_parameters = { diff --git a/app/controllers/hyrax/content_blocks_controller_decorator.rb b/app/controllers/hyrax/content_blocks_controller_decorator.rb index 348ac4f20..afaa2201f 100644 --- a/app/controllers/hyrax/content_blocks_controller_decorator.rb +++ b/app/controllers/hyrax/content_blocks_controller_decorator.rb @@ -6,11 +6,11 @@ module ContentBlocksControllerDecorator # override hyrax v2.9.0 added the home_text content block to permitted_params - Adding Themes def permitted_params params.require(:content_block).permit(:marketing, - :announcement, - :home_text, - :homepage_about_section_heading, - :homepage_about_section_content, - :researcher) + :announcement, + :home_text, + :homepage_about_section_heading, + :homepage_about_section_content, + :researcher) end end end diff --git a/app/controllers/hyrax/homepage_controller_decorator.rb b/app/controllers/hyrax/homepage_controller_decorator.rb index 0299f6a63..e4564a9bb 100644 --- a/app/controllers/hyrax/homepage_controller_decorator.rb +++ b/app/controllers/hyrax/homepage_controller_decorator.rb @@ -3,7 +3,6 @@ # OVERRIDE Hyrax 3.5 to add content blocks module Hyrax module HomepageControllerDecorator - def index @presenter = presenter_class.new(current_ability, collections) @featured_researcher = ContentBlock.for(:researcher) diff --git a/app/models/content_block.rb b/app/models/content_block.rb index 4c00535b3..5b383f192 100644 --- a/app/models/content_block.rb +++ b/app/models/content_block.rb @@ -16,7 +16,7 @@ class ContentBlock < ApplicationRecord help: :help_page, terms: :terms_page, agreement: :agreement_page, - home_text: :home_text, + home_text: :home_text, homepage_about_section_heading: :homepage_about_section_heading, homepage_about_section_content: :homepage_about_section_content }.freeze diff --git a/app/models/generic_work.rb b/app/models/generic_work.rb index 5ee8e9c01..0abd4f9db 100644 --- a/app/models/generic_work.rb +++ b/app/models/generic_work.rb @@ -12,5 +12,4 @@ class GenericWork < ActiveFedora::Base self.indexer = GenericWorkIndexer prepend OrderAlready.for(:creator) - end diff --git a/lib/wings/services/custom_queries/find_ids_by_model_decorator.rb b/lib/wings/services/custom_queries/find_ids_by_model_decorator.rb index 7cbaaef29..84e3b2c50 100644 --- a/lib/wings/services/custom_queries/find_ids_by_model_decorator.rb +++ b/lib/wings/services/custom_queries/find_ids_by_model_decorator.rb @@ -29,7 +29,12 @@ def find_ids_by_model(model:, ids: :all) response_docs.each { |doc| yield doc['id'] } break if (solr_response['start'] + solr_response['docs'].count) >= solr_response['numFound'] - solr_response = ActiveFedora::SolrService.post(solr_query, fl: 'id', rows: @query_rows, start: solr_response['start'] + @query_rows)['response'] + solr_response = ActiveFedora::SolrService.post( + solr_query, + fl: 'id', + rows: @query_rows, + start: solr_response['start'] + @query_rows + )['response'] end end end From 00a4b4af7a0dd18f5a3b393d60e9728322f4943e Mon Sep 17 00:00:00 2001 From: Shana Moore Date: Mon, 25 Sep 2023 10:49:34 -0700 Subject: [PATCH 017/126] remove iiif_print/iiif_print require cause of Sprockets::FileNotFound in Splash#index error. Doesn't seem necessary. --- app/assets/stylesheets/application.css | 1 - 1 file changed, 1 deletion(-) diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index bb4734825..61efe4aa9 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -20,6 +20,5 @@ *= require single_signon *= require blacklight_advanced_search *= require blacklight_range_limit - *= require iiif_print/iiif_print *= require_self */ From 2ac46251a4b01b2fc6a11e628c0e7721757d6b79 Mon Sep 17 00:00:00 2001 From: Shana Moore Date: Mon, 25 Sep 2023 12:49:21 -0700 Subject: [PATCH 018/126] :gift: :broom: add missing file and format with semicolons The previous build revealed that admin_color_select.js was missing. It also complained about missing semicolons. --- app/assets/javascripts/admin_color_select.js | 20 ++++++++ app/assets/javascripts/admin_font_select.js | 54 +++++++++++--------- 2 files changed, 49 insertions(+), 25 deletions(-) create mode 100644 app/assets/javascripts/admin_color_select.js diff --git a/app/assets/javascripts/admin_color_select.js b/app/assets/javascripts/admin_color_select.js new file mode 100644 index 000000000..5bff8eb25 --- /dev/null +++ b/app/assets/javascripts/admin_color_select.js @@ -0,0 +1,20 @@ +$(document).on("turbolinks:load", function () { + $("div.defaultable-colors a.restore-default-color").click(function (e) { + e.preventDefault(); + + var defaultTarget = $(e.target).data("default-target"); + var input = $("input[name='admin_appearance[" + defaultTarget + "]']"); + + input.val(input.data("default-value")); + }); + + $(".panel-footer a.restore-all-default-colors").click(function (e) { + e.preventDefault(); + + var allColorInputs = $("input[name*='color']"); + + allColorInputs.each(function () { + $(this).val($(this).data("default-value")); + }); + }); +}); diff --git a/app/assets/javascripts/admin_font_select.js b/app/assets/javascripts/admin_font_select.js index e2c3e89cb..26abe89fa 100644 --- a/app/assets/javascripts/admin_font_select.js +++ b/app/assets/javascripts/admin_font_select.js @@ -1,34 +1,38 @@ -Blacklight.onLoad(function() { - if($("#admin_appearance_body_font").length > 0){ - $("#admin_appearance_body_font").fontselect({lookahead: 20}) - $("#admin_appearance_headline_font").fontselect({lookahead: 20}) +Blacklight.onLoad(function () { + if ($("#admin_appearance_body_font").length > 0) { + $("#admin_appearance_body_font").fontselect({ lookahead: 20 }); + $("#admin_appearance_headline_font").fontselect({ lookahead: 20 }); } }); -$('div.defaultable-fonts a.restore-default-font').click(function(e) { - e.preventDefault() - var defaultTarget = $(e.target).data('default-target') - var input = $("input[name='admin_appearance["+ defaultTarget +"]']") - var defaultValue = input.data('default-value').replace(';', '') - var inputDisplay = $("div[class$='"+ defaultTarget +"']").find('div.font-select span') +$("div.defaultable-fonts a.restore-default-font").click(function (e) { + e.preventDefault(); + var defaultTarget = $(e.target).data("default-target"); + var input = $("input[name='admin_appearance[" + defaultTarget + "]']"); + var defaultValue = input.data("default-value").replace(";", ""); + var inputDisplay = $("div[class$='" + defaultTarget + "']").find( + "div.font-select span" + ); - input.val(defaultValue) - inputDisplay.css("font-family", defaultValue) - inputDisplay.text(defaultValue) -}) + input.val(defaultValue); + inputDisplay.css("font-family", defaultValue); + inputDisplay.text(defaultValue); +}); -$('.panel-footer a.restore-all-default-fonts').click(function(e) { - e.preventDefault() +$(".panel-footer a.restore-all-default-fonts").click(function (e) { + e.preventDefault(); - var allFontInputs = $("input[name*='font']") + var allFontInputs = $("input[name*='font']"); - allFontInputs.each(function() { - var thisTarget = $(this).attr('id').replace('admin_appearance_', '') - var defaultValue = $(this).data('default-value').replace(';', '') - var inputDisplay = $("div[class$='"+ thisTarget +"']").find('div.font-select span') + allFontInputs.each(function () { + var thisTarget = $(this).attr("id").replace("admin_appearance_", ""); + var defaultValue = $(this).data("default-value").replace(";", ""); + var inputDisplay = $("div[class$='" + thisTarget + "']").find( + "div.font-select span" + ); - $(this).val(defaultValue) - inputDisplay.css("font-family", defaultValue) - inputDisplay.text(defaultValue) - }) + $(this).val(defaultValue); + inputDisplay.css("font-family", defaultValue); + inputDisplay.text(defaultValue); + }); }); From 15d313680a84fa2401f7be7b0b94ea1900539a9e Mon Sep 17 00:00:00 2001 From: Shana Moore Date: Mon, 25 Sep 2023 12:52:25 -0700 Subject: [PATCH 019/126] :lipstick: correct missing semicolons appease the hound by formatting js file with semicolons. --- .../range_limit_distro_facets.js | 606 ++++++++++-------- 1 file changed, 327 insertions(+), 279 deletions(-) diff --git a/app/assets/javascripts/blacklight_range_limit/range_limit_distro_facets.js b/app/assets/javascripts/blacklight_range_limit/range_limit_distro_facets.js index 4b2807651..1133b8dec 100644 --- a/app/assets/javascripts/blacklight_range_limit/range_limit_distro_facets.js +++ b/app/assets/javascripts/blacklight_range_limit/range_limit_distro_facets.js @@ -4,297 +4,345 @@ is (re-)drawn on screen possibly with a new size. target of event will be the DOM element containing the plot. Used to resize slider to match. */ - Blacklight.onLoad(function() { - // ratio of width to height for desired display, multiply width by this ratio - // to get height. hard-coded in for now. - var display_ratio = 1/(1.618 * 2); // half a golden rectangle, why not - var redrawnEvent = "plotDrawn.blacklight.rangeLimit"; - - - - // Facets already on the page? Turn em into a chart. - $(".range_limit .profile .distribution.chart_js ul").each(function() { - turnIntoPlot($(this).parent()); - }); - - - // Add AJAX fetched range facets if needed, and add a chart to em - $(".range_limit .profile .distribution a.load_distribution").each(function() { - var container = $(this).parent('div.distribution'); - - $(container).load($(this).attr('href'), function(response, status) { - if ($(container).hasClass("chart_js") && status == "success" ) { - turnIntoPlot(container); - } - }); - }); - - // Listen for twitter bootstrap collapsible open events, to render flot - // in previously hidden divs on open, if needed. - $("body").on("show.bs.collapse", function(event) { - // Was the target a .facet-content including a .chart-js? - var container = $(event.target).filter(".facet-content").find(".chart_js"); - - // only if it doesn't already have a canvas, it isn't already drawn - if (container && container.find("canvas").length == 0) { - // be willing to wait up to 1100ms for container to - // have width -- right away on show.bs is too soon, but - // shown.bs is later than we want, we want to start rendering - // while animation is still in progress. - turnIntoPlot(container, 1100); - } - }); - - - - // after a collapsible facet contents is fully shown, - // resize the flot chart to current conditions. This way, if you change - // browser window size, you can get chart resized to fit by closing and opening - // again, if needed. - - function redrawPlot(container) { - if (container && container.width() > 0) { - // resize the container's height, since width may have changed. - container.height( container.width() * display_ratio ); - - // redraw the chart. - var plot = container.data("plot"); - if (plot) { - // how to redraw after possible resize? - // Cribbed from https://github.com/flot/flot/blob/master/jquery.flot.resize.js - plot.resize(); - plot.setupGrid(); - plot.draw(); - // plus trigger redraw of the selection, which otherwise ain't always right - // we'll trigger a fake event on one of the boxes - var form = $(container).closest(".limit_content").find("form.range_limit"); - form.find("input.range_begin").trigger("change"); - - // send our custom event to trigger redraw of slider - $(container).trigger(redrawnEvent); +Blacklight.onLoad(function () { + // ratio of width to height for desired display, multiply width by this ratio + // to get height. hard-coded in for now. + var display_ratio = 1 / (1.618 * 2); // half a golden rectangle, why not + var redrawnEvent = "plotDrawn.blacklight.rangeLimit"; + + // Facets already on the page? Turn em into a chart. + $(".range_limit .profile .distribution.chart_js ul").each(function () { + turnIntoPlot($(this).parent()); + }); + + // Add AJAX fetched range facets if needed, and add a chart to em + $(".range_limit .profile .distribution a.load_distribution").each( + function () { + var container = $(this).parent("div.distribution"); + + $(container).load($(this).attr("href"), function (response, status) { + if ($(container).hasClass("chart_js") && status == "success") { + turnIntoPlot(container); } + }); + } + ); + + // Listen for twitter bootstrap collapsible open events, to render flot + // in previously hidden divs on open, if needed. + $("body").on("show.bs.collapse", function (event) { + // Was the target a .facet-content including a .chart-js? + var container = $(event.target).filter(".facet-content").find(".chart_js"); + + // only if it doesn't already have a canvas, it isn't already drawn + if (container && container.find("canvas").length == 0) { + // be willing to wait up to 1100ms for container to + // have width -- right away on show.bs is too soon, but + // shown.bs is later than we want, we want to start rendering + // while animation is still in progress. + turnIntoPlot(container, 1100); + } + }); + + // after a collapsible facet contents is fully shown, + // resize the flot chart to current conditions. This way, if you change + // browser window size, you can get chart resized to fit by closing and opening + // again, if needed. + + function redrawPlot(container) { + if (container && container.width() > 0) { + // resize the container's height, since width may have changed. + container.height(container.width() * display_ratio); + + // redraw the chart. + var plot = container.data("plot"); + if (plot) { + // how to redraw after possible resize? + // Cribbed from https://github.com/flot/flot/blob/master/jquery.flot.resize.js + plot.resize(); + plot.setupGrid(); + plot.draw(); + // plus trigger redraw of the selection, which otherwise ain't always right + // we'll trigger a fake event on one of the boxes + var form = $(container) + .closest(".limit_content") + .find("form.range_limit"); + form.find("input.range_begin").trigger("change"); + + // send our custom event to trigger redraw of slider + $(container).trigger(redrawnEvent); } } - - $("body").on("shown.bs.collapse", function(event) { - var container = $(event.target).filter(".facet-content").find(".chart_js"); - redrawPlot(container); - }); - - // debouce borrowed from underscore - // Returns a function, that, as long as it continues to be invoked, will not - // be triggered. The function will be called after it stops being called for - // N milliseconds. If `immediate` is passed, trigger the function on the - // leading edge, instead of the trailing. - debounce = function(func, wait, immediate) { - var timeout; - return function() { - var context = this, args = arguments; - var later = function() { - timeout = null; - if (!immediate) func.apply(context, args); - }; - var callNow = immediate && !timeout; - clearTimeout(timeout); - timeout = setTimeout(later, wait); - if (callNow) func.apply(context, args); + } + + $("body").on("shown.bs.collapse", function (event) { + var container = $(event.target).filter(".facet-content").find(".chart_js"); + redrawPlot(container); + }); + + // debouce borrowed from underscore + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. If `immediate` is passed, trigger the function on the + // leading edge, instead of the trailing. + debounce = function (func, wait, immediate) { + var timeout; + return function () { + var context = this, + args = arguments; + var later = function () { + timeout = null; + if (!immediate) func.apply(context, args); }; + var callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + if (callNow) func.apply(context, args); }; - - $(window).on("resize", debounce(function() { - $(".chart_js").each(function(i, container) { + }; + + $(window).on( + "resize", + debounce(function () { + $(".chart_js").each(function (i, container) { redrawPlot($(container)); }); - }, 350)); - - // second arg, if provided, is a number of ms we're willing to - // wait for the container to have width before giving up -- we'll - // set 50ms timers to check back until timeout is expired or the - // container is finally visible. The timeout is used when we catch - // bootstrap show event, but the animation hasn't barely begun yet -- but - // we don't want to wait until it's finished, we want to start rendering - // as soon as we can. + }, 350) + ); + + // second arg, if provided, is a number of ms we're willing to + // wait for the container to have width before giving up -- we'll + // set 50ms timers to check back until timeout is expired or the + // container is finally visible. The timeout is used when we catch + // bootstrap show event, but the animation hasn't barely begun yet -- but + // we don't want to wait until it's finished, we want to start rendering + // as soon as we can. + // + // We also will + function turnIntoPlot(container, wait_for_visible) { + // flot can only render in a a div with a defined width. + // for instance, a hidden div can't generally be rendered in (although if you set + // an explicit width on it, it might work) // - // We also will - function turnIntoPlot(container, wait_for_visible) { - // flot can only render in a a div with a defined width. - // for instance, a hidden div can't generally be rendered in (although if you set - // an explicit width on it, it might work) - // - // We'll count on later code that catch bootstrap collapse open to render - // on show, for currently hidden divs. - - // for some reason width sometimes return negative, not sure - // why but it's some kind of hidden. - if (container.width() > 0) { - var height = container.width() * display_ratio; - - // Need an explicit height to make flot happy. - container.height( height ) - - areaChart($(container)); - - $(container).trigger(redrawnEvent); - } - else if (wait_for_visible > 0) { - setTimeout(function() { - turnIntoPlot(container, wait_for_visible - 50); - }, 50); - } + // We'll count on later code that catch bootstrap collapse open to render + // on show, for currently hidden divs. + + // for some reason width sometimes return negative, not sure + // why but it's some kind of hidden. + if (container.width() > 0) { + var height = container.width() * display_ratio; + + // Need an explicit height to make flot happy. + container.height(height); + + areaChart($(container)); + + $(container).trigger(redrawnEvent); + } else if (wait_for_visible > 0) { + setTimeout(function () { + turnIntoPlot(container, wait_for_visible - 50); + }, 50); } - - // Takes a div holding a ul of distribution segments produced by - // blacklight_range_limit/_range_facets and makes it into - // a flot area chart. - function areaChart(container) { - //flot loaded? And canvas element supported. - if ( domDependenciesMet() ) { - - // Grab the data from the ul div - var series_data = new Array(); - var pointer_lookup = new Array(); - var x_ticks = new Array(); - var min = BlacklightRangeLimit.parseNum($(container).find("ul li:first-child span.from").text()); - var max = BlacklightRangeLimit.parseNum($(container).find("ul li:last-child span.to").text()); - - $(container).find("ul li").each(function() { - var from = BlacklightRangeLimit.parseNum($(this).find("span.from").text()); - var to = BlacklightRangeLimit.parseNum($(this).find("span.to").text()); - var count = BlacklightRangeLimit.parseNum($(this).find("span.count").text()); - var avg = (count / (to - from + 1)); - - - //We use the avg as the y-coord, to make the area of each - //segment proportional to how many documents it holds. - series_data.push( [from, avg ] ); - series_data.push( [to+1, avg] ); - - x_ticks.push(from); - - pointer_lookup.push({'from': from, 'to': to, 'count': count, 'label': $(this).find(".facet_select").text() }); - }); - var max_plus_one = BlacklightRangeLimit.parseNum($(container).find("ul li:last-child span.to").text())+1; - x_ticks.push( max_plus_one ); - - - - var plot; - var config = $(container).closest('.facet_limit').data('plot-config') || {}; - - try { - plot = $.plot($(container), [series_data], - $.extend(true, config, { - yaxis: { ticks: [], min: 0, autoscaleMargin: 0.1}, - //xaxis: { ticks: x_ticks }, - xaxis: { tickDecimals: 0 }, // force integer ticks - series: { lines: { fill: true, steps: true }}, - grid: {clickable: true, hoverable: true, autoHighlight: false}, - selection: {mode: "x"} - })); - } - catch(err) { - alert(err); - } - - find_segment_for = function_for_find_segment(pointer_lookup); - var last_segment = null; - $(container).tooltip({'placement': 'bottom', 'trigger': 'manual', 'delay': { show: 0, hide: 100}}); - - $(container).bind("plothover", function (event, pos, item) { - segment = find_segment_for(pos.x); - - if(segment != last_segment) { - var title = find_segment_for(pos.x).label + ' (' + BlacklightRangeLimit.parseNum(segment.count) + ')'; - $(container).attr("title", title).tooltip("_fixTitle").tooltip("show"); - - last_segment = segment; - } - }); - - $(container).bind("mouseout", function() { - last_segment = null; - $(container).tooltip('hide'); - }); - $(container).bind("plotclick", function (event, pos, item) { - if ( plot.getSelection() == null) { - segment = find_segment_for(pos.x); - plot.setSelection( normalized_selection(segment.from, segment.to)); - } - }); - $(container).bind("plotselected plotselecting", function(event, ranges) { - if (ranges != null ) { - var from = Math.floor(ranges.xaxis.from); - var to = Math.floor(ranges.xaxis.to); - - var form = $(container).closest(".limit_content").find("form.range_limit"); - form.find("input.range_begin").val(from); - form.find("input.range_end").val(to); - - var slider_placeholder = $(container).closest(".limit_content").find("[data-slider-placeholder]"); - if (slider_placeholder) { - slider_placeholder.slider("setValue", [from, to+1]); - } - } - }); - - var form = $(container).closest(".limit_content").find("form.range_limit"); - form.find("input.range_begin, input.range_end").change(function () { - plot.setSelection( form_selection(form, min, max) , true ); - }); - $(container).closest(".limit_content").find(".profile .range").on("slide", function(event, ui) { - var values = $(event.target).data("slider").getValue(); - form.find("input.range_begin").val(values[0]); - form.find("input.range_end").val(values[1]); - plot.setSelection( normalized_selection(values[0], Math.max(values[0], values[1]-1)), true); + } + + // Takes a div holding a ul of distribution segments produced by + // blacklight_range_limit/_range_facets and makes it into + // a flot area chart. + function areaChart(container) { + //flot loaded? And canvas element supported. + if (domDependenciesMet()) { + // Grab the data from the ul div + var series_data = new Array(); + var pointer_lookup = new Array(); + var x_ticks = new Array(); + var min = BlacklightRangeLimit.parseNum( + $(container).find("ul li:first-child span.from").text() + ); + var max = BlacklightRangeLimit.parseNum( + $(container).find("ul li:last-child span.to").text() + ); + + $(container) + .find("ul li") + .each(function () { + var from = BlacklightRangeLimit.parseNum( + $(this).find("span.from").text() + ); + var to = BlacklightRangeLimit.parseNum( + $(this).find("span.to").text() + ); + var count = BlacklightRangeLimit.parseNum( + $(this).find("span.count").text() + ); + var avg = count / (to - from + 1); + + //We use the avg as the y-coord, to make the area of each + //segment proportional to how many documents it holds. + series_data.push([from, avg]); + series_data.push([to + 1, avg]); + + x_ticks.push(from); + + pointer_lookup.push({ + from: from, + to: to, + count: count, + label: $(this).find(".facet_select").text(), }); - - // initially entirely selected, to match slider - plot.setSelection( {xaxis: { from:min, to:max+0.9999}} ); - } - } - - - // Send endpoint to endpoint+0.99999 to have display - // more closely approximate limiting behavior esp - // at small resolutions. (Since we search on whole numbers, - // inclusive, but flot chart is decimal.) - function normalized_selection(min, max) { - max += 0.99999; - - return {xaxis: { 'from':min, 'to':max}} + }); + var max_plus_one = + BlacklightRangeLimit.parseNum( + $(container).find("ul li:last-child span.to").text() + ) + 1; + x_ticks.push(max_plus_one); + + var plot; + var config = + $(container).closest(".facet_limit").data("plot-config") || {}; + + try { + plot = $.plot( + $(container), + [series_data], + $.extend(true, config, { + yaxis: { ticks: [], min: 0, autoscaleMargin: 0.1 }, + //xaxis: { ticks: x_ticks }, + xaxis: { tickDecimals: 0 }, // force integer ticks + series: { lines: { fill: true, steps: true } }, + grid: { clickable: true, hoverable: true, autoHighlight: false }, + selection: { mode: "x" }, + }) + ); + } catch (err) { + alert(err); } - - function form_selection(form, min, max) { - var begin_val = BlacklightRangeLimit.parseNum($(form).find("input.range_begin").val()); - if (isNaN(begin_val) || begin_val < min) { - begin_val = min; + + find_segment_for = function_for_find_segment(pointer_lookup); + var last_segment = null; + $(container).tooltip({ + placement: "bottom", + trigger: "manual", + delay: { show: 0, hide: 100 }, + }); + + $(container).bind("plothover", function (event, pos, item) { + segment = find_segment_for(pos.x); + + if (segment != last_segment) { + var title = + find_segment_for(pos.x).label + + " (" + + BlacklightRangeLimit.parseNum(segment.count) + + ")"; + $(container) + .attr("title", title) + .tooltip("_fixTitle") + .tooltip("show"); + + last_segment = segment; } - var end_val = BlacklightRangeLimit.parseNum($(form).find("input.range_end").val()); - if (isNaN(end_val) || end_val > max) { - end_val = max; + }); + + $(container).bind("mouseout", function () { + last_segment = null; + $(container).tooltip("hide"); + }); + $(container).bind("plotclick", function (event, pos, item) { + if (plot.getSelection() == null) { + segment = find_segment_for(pos.x); + plot.setSelection(normalized_selection(segment.from, segment.to)); } - - return normalized_selection(begin_val, end_val); - } - - function function_for_find_segment(pointer_lookup_arr) { - return function(x_coord) { - for (var i = pointer_lookup_arr.length-1 ; i >= 0 ; i--) { - var hash = pointer_lookup_arr[i]; - if (x_coord >= hash.from) - return hash; + }); + $(container).bind("plotselected plotselecting", function (event, ranges) { + if (ranges != null) { + var from = Math.floor(ranges.xaxis.from); + var to = Math.floor(ranges.xaxis.to); + + var form = $(container) + .closest(".limit_content") + .find("form.range_limit"); + form.find("input.range_begin").val(from); + form.find("input.range_end").val(to); + + var slider_placeholder = $(container) + .closest(".limit_content") + .find("[data-slider-placeholder]"); + if (slider_placeholder) { + slider_placeholder.slider("setValue", [from, to + 1]); } - return pointer_lookup_arr[0]; - }; - } - - // Check if Flot is loaded, and if browser has support for - // canvas object, either natively or via IE excanvas. - function domDependenciesMet() { - var flotLoaded = (typeof $.plot != "undefined"); - var canvasAvailable = ((typeof(document.createElement('canvas').getContext) != "undefined") || (typeof window.CanvasRenderingContext2D != 'undefined' || typeof G_vmlCanvasManager != 'undefined')); - - return (flotLoaded && canvasAvailable); + } + }); + + var form = $(container) + .closest(".limit_content") + .find("form.range_limit"); + form.find("input.range_begin, input.range_end").change(function () { + plot.setSelection(form_selection(form, min, max), true); + }); + $(container) + .closest(".limit_content") + .find(".profile .range") + .on("slide", function (event, ui) { + var values = $(event.target).data("slider").getValue(); + form.find("input.range_begin").val(values[0]); + form.find("input.range_end").val(values[1]); + plot.setSelection( + normalized_selection(values[0], Math.max(values[0], values[1] - 1)), + true + ); + }); + + // initially entirely selected, to match slider + plot.setSelection({ xaxis: { from: min, to: max + 0.9999 } }); + } + } + + // Send endpoint to endpoint+0.99999 to have display + // more closely approximate limiting behavior esp + // at small resolutions. (Since we search on whole numbers, + // inclusive, but flot chart is decimal.) + function normalized_selection(min, max) { + max += 0.99999; + + return { xaxis: { from: min, to: max } }; + } + + function form_selection(form, min, max) { + var begin_val = BlacklightRangeLimit.parseNum( + $(form).find("input.range_begin").val() + ); + if (isNaN(begin_val) || begin_val < min) { + begin_val = min; + } + var end_val = BlacklightRangeLimit.parseNum( + $(form).find("input.range_end").val() + ); + if (isNaN(end_val) || end_val > max) { + end_val = max; + } + + return normalized_selection(begin_val, end_val); + } + + function function_for_find_segment(pointer_lookup_arr) { + return function (x_coord) { + for (var i = pointer_lookup_arr.length - 1; i >= 0; i--) { + var hash = pointer_lookup_arr[i]; + if (x_coord >= hash.from) return hash; } - }); - \ No newline at end of file + return pointer_lookup_arr[0]; + }; + } + + // Check if Flot is loaded, and if browser has support for + // canvas object, either natively or via IE excanvas. + function domDependenciesMet() { + var flotLoaded = typeof $.plot != "undefined"; + var canvasAvailable = + typeof document.createElement("canvas").getContext != "undefined" || + typeof window.CanvasRenderingContext2D != "undefined" || + typeof G_vmlCanvasManager != "undefined"; + + return flotLoaded && canvasAvailable; + } +}); From 21133eae712b74e627c7eeef4230577aa3156621 Mon Sep 17 00:00:00 2001 From: Shana Moore Date: Mon, 25 Sep 2023 13:39:16 -0700 Subject: [PATCH 020/126] :broom: remove call to iiif_print/iiif_print Cause of build error. It's already being included in sass. --- app/assets/stylesheets/application.css | 1 - 1 file changed, 1 deletion(-) diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index bb4734825..61efe4aa9 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -20,6 +20,5 @@ *= require single_signon *= require blacklight_advanced_search *= require blacklight_range_limit - *= require iiif_print/iiif_print *= require_self */ From 05304fd3874a01d0f094cc3ce9ca3a51c6ed3084 Mon Sep 17 00:00:00 2001 From: Shana Moore Date: Mon, 25 Sep 2023 14:15:46 -0700 Subject: [PATCH 021/126] :lipstick: Rubocop fixes --- app/controllers/catalog_controller.rb | 31 ++++++++++++--------------- app/models/generic_work.rb | 1 - 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/app/controllers/catalog_controller.rb b/app/controllers/catalog_controller.rb index c50f887b0..523788a6b 100644 --- a/app/controllers/catalog_controller.rb +++ b/app/controllers/catalog_controller.rb @@ -110,8 +110,7 @@ def self.uploaded_field config.add_facet_field 'file_format_sim', limit: 5 config.add_facet_field 'member_of_collections_ssim', limit: 5, label: 'Collections' - - # TODO deal with part of facet changes + # TODO: deal with part of facet changes # config.add_facet_field solr_name("part", :facetable), limit: 5, label: 'Part' # config.add_facet_field solr_name("part_of", :facetable), limit: 5 # removed # config.add_facet_field solr_name("file_format", :facetable), limit: 5 @@ -123,16 +122,16 @@ def self.uploaded_field # handler defaults, or have no facets. config.add_facet_fields_to_solr_request! - # TODO ROB -# # Prior to this change, the applications specific translations were not loaded. Dogbiscuits were assuming the translations were already loaded. -# Rails.root.glob("config/locales/*.yml").each do |path| -# I18n.load_path << path.to_s -# end -# I18n.backend.reload! -# index_props = DogBiscuits.config.index_properties.collect do |prop| -# { prop => index_options(prop, DogBiscuits.config.property_mappings[prop]) } -# end -# add_index_field config, index_props + # TODO: ROB + # # Prior to this change, the applications specific translations were not loaded. Dogbiscuits were assuming the translations were already loaded. + # Rails.root.glob("config/locales/*.yml").each do |path| + # I18n.load_path << path.to_s + # end + # I18n.backend.reload! + # index_props = DogBiscuits.config.index_properties.collect do |prop| + # { prop => index_options(prop, DogBiscuits.config.property_mappings[prop]) } + # end + # add_index_field config, index_props # solr fields to be displayed in the show (single result) view # The ordering of the field names is the order of the display @@ -203,8 +202,8 @@ def self.uploaded_field # since we aren't specifying it otherwise. config.add_search_field('all_fields', label: 'All Fields', include_in_advanced_search: false) do |field| all_names = config.show_fields.values.map(&:field).join(" ") -# TODO ROB all_names = (config.show_fields.values.map { |v| v.field.to_s } + - # DogBiscuits.config.all_properties.map { |p| "#{p}_tesim" }).uniq.join(" ") + # TODO: ROB all_names = (config.show_fields.values.map { |v| v.field.to_s } + + # DogBiscuits.config.all_properties.map { |p| "#{p}_tesim" }).uniq.join(" ") title_name = 'title_tesim' field.solr_parameters = { qf: "#{all_names} file_format_tesim all_text_timv", @@ -233,7 +232,7 @@ def self.uploaded_field end config.add_search_field('creator') do |field| - # TODO ROB field.label = "Author" + # TODO: ROB field.label = "Author" field.solr_parameters = { "spellcheck.dictionary": "creator" } solr_name = 'creator_tesim' field.solr_local_parameters = { @@ -276,8 +275,6 @@ def self.uploaded_field } end - date_fields = ['date_created_tesim', 'sorted_date_isi', 'sorted_month_isi'] - config.add_search_field('date_created') do |field| field.solr_parameters = { "spellcheck.dictionary": "date_created" diff --git a/app/models/generic_work.rb b/app/models/generic_work.rb index 5ee8e9c01..0abd4f9db 100644 --- a/app/models/generic_work.rb +++ b/app/models/generic_work.rb @@ -12,5 +12,4 @@ class GenericWork < ActiveFedora::Base self.indexer = GenericWorkIndexer prepend OrderAlready.for(:creator) - end From 8d81514d37435ec6d1c7b60ae3f6a87785332a62 Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Mon, 25 Sep 2023 16:32:55 -0700 Subject: [PATCH 022/126] =?UTF-8?q?=E2=9C=85=20Fix=20test=20setup=20for=20?= =?UTF-8?q?catalog=5Fcontroller=5Fspec?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit will add additional setup to the catalog_controller_spec. --- spec/requests/catalog_controller_spec.rb | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/spec/requests/catalog_controller_spec.rb b/spec/requests/catalog_controller_spec.rb index 818b80bd3..c36a9c43d 100644 --- a/spec/requests/catalog_controller_spec.rb +++ b/spec/requests/catalog_controller_spec.rb @@ -56,6 +56,18 @@ before do host! "http://#{cross_search_tenant_account.cname}/" + black_light_config.add_search_field('title') do |field| + field.solr_parameters = { + "spellcheck.dictionary": "title" + } + solr_name = 'title_tesim' + field.solr_local_parameters = { + qf: solr_name, + pf: solr_name + } + end + black_light_config.advanced_search ||= Blacklight::OpenStructWithHashAccess.new + black_light_config.advanced_search[:query_parser] ||= 'dismax' end context 'can fetch data from other tenants' do @@ -66,7 +78,7 @@ # get '/catalog', params: { q: '*' } # get search_catalog_url, params: { locale: 'en', q: 'test' } - get "http://#{cross_search_tenant_account.cname}/catalog?q=test" # , params: { q: 'test' } + get "http://#{cross_search_tenant_account.cname}/catalog?q=test", params: { q: 'title' } expect(response.status).to eq(200) end end From aa7f8c636094598c2e43dc7262b64c0715d15233 Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Tue, 26 Sep 2023 12:26:55 -0700 Subject: [PATCH 023/126] Add knapsack helper --- app/helpers/application_helper.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index e27eee4ae..44531726b 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -5,6 +5,7 @@ module ApplicationHelper include Hyrax::OverrideHelperBehavior include GroupNavigationHelper include SharedSearchHelper + include HykuKnapsack::ApplicationHelper def hint_for(term:, record_class: nil) hint = locale_for(type: 'hints', term: term, record_class: record_class) From 7740cfd6a07ee2a54de6af277b81ef56f492fb87 Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Tue, 26 Sep 2023 14:43:26 -0700 Subject: [PATCH 024/126] remove Adventist from application.rb --- config/application.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/application.rb b/config/application.rb index acf7c0523..9244f821c 100644 --- a/config/application.rb +++ b/config/application.rb @@ -66,8 +66,8 @@ class Application < Rails::Application # Adventist::TextFileTextExtractionService to the beginning of the services array we are # enabling text extraction from plain text files. Hyrax::DerivativeService.services = [ - Adventist::TextFileTextExtractionService, - IiifPrint::PluggableDerivativeService] + IiifPrint::PluggableDerivativeService + ] # When you are ready to use the derivative rodeo instead of the pluggable uncomment the # following and comment out the preceding Hyrax::DerivativeService.service From 5108af162eb56ad6947e1486b1b1e132c2896e4b Mon Sep 17 00:00:00 2001 From: Shana Moore Date: Thu, 28 Sep 2023 11:31:35 -0700 Subject: [PATCH 025/126] =?UTF-8?q?=F0=9F=8E=81=20Add=20conditional=20to?= =?UTF-8?q?=20run=20correct=20command=20for=20worker?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds a conditional to run the correct command for sidekiq or good_job, when running docker compose up. --- docker-compose.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 0d349e7e3..dafc2446b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -176,7 +176,15 @@ services: - ghcr.io/samvera/hyku/base:latest - ghcr.io/samvera/hyku:latest - ghcr.io/samvera/hyku/worker:latest - command: bundle exec sidekiq + command: + - /bin/sh + - -c + - > + if [ "$$HYRAX_ACTIVE_JOB_QUEUE" == "good_job" ]; then + exec bundle exec good_job start + else + exec bundle exec sidekiq + fi depends_on: check_volumes: condition: service_completed_successfully From b8af51e6b45486855bb6d7ba055b8c50b2b3dca2 Mon Sep 17 00:00:00 2001 From: LaRita Robinson Date: Fri, 29 Sep 2023 12:56:24 -0400 Subject: [PATCH 026/126] Make appearance constants overrideable This allows for the knapsack to override the constants by defining and using a method rather than a constant in the look-ups. --- app/forms/hyrax/forms/admin/appearance.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/forms/hyrax/forms/admin/appearance.rb b/app/forms/hyrax/forms/admin/appearance.rb index 7f20affae..ec64d6bb3 100644 --- a/app/forms/hyrax/forms/admin/appearance.rb +++ b/app/forms/hyrax/forms/admin/appearance.rb @@ -42,8 +42,6 @@ class Appearance 'facet_panel_text_color' => '#333333' }.freeze - DEFAULT_VALUES = DEFAULT_FONTS.merge(DEFAULT_COLORS).freeze - # @param [Hash] attributes the list of parameters from the form def initialize(attributes = {}) @attributes = attributes @@ -430,8 +428,12 @@ def convert_to_rgba(hex_color, alpha = 0.5) "rgba(#{rgb[0]}, #{rgb[1]}, #{rgb[2]}, #{alpha})" end + def default_values + @default_values ||= DEFAULT_FONTS.merge(DEFAULT_COLORS) + end + def block_for(name, dynamic_default = nil) - ContentBlock.block_for(name: name, fallback_value: DEFAULT_VALUES[name] || dynamic_default) + ContentBlock.block_for(name: name, fallback_value: default_values[name] || dynamic_default) end # Persist a key/value tuple as a ContentBlock From 6126bf6b5bc9eb8556775436b174e252afad5a0e Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Sat, 30 Sep 2023 23:31:01 -0400 Subject: [PATCH 027/126] add reporting fix to hyku ci --- .env | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.env b/.env index c51b5a51e..b4e6bf781 100644 --- a/.env +++ b/.env @@ -1,5 +1,6 @@ CHROME_HOSTNAME=chrome COMPOSE_DOCKER_CLI_BUILD=1 +DATABASE_CLEANER_ALLOW_REMOTE_DATABASE_URL=true DB_ADAPTER=postgresql DB_HOST=db DB_HOST=db @@ -13,19 +14,19 @@ FCREPO_BASE_PATH=/hykudemo FCREPO_HOST=fcrepo FCREPO_PORT=8080 FCREPO_REST_PATH=rest +HYRAX_ACTIVE_JOB_QUEUE=good_job +HYRAX_FITS_PATH=/app/fits/fits.sh INITIAL_ADMIN_EMAIL=admin@example.com INITIAL_ADMIN_PASSWORD=testing123 -JAVA_OPTS=-Xmx4g -Xms1g IN_DOCKER=true JAVA_OPTS= +JAVA_OPTS=-Xmx4g -Xms1g LD_LIBRARY_PATH=/opt/fits/tools/mediainfo/linux +NEGATIVE_CAPTCHA_SECRET=default-value-change-me PASSENGER_APP_ENV=development RAILS_LOG_TO_STDOUT=true REDIS_HOST=redis SECRET_KEY_BASE=asdf -HYRAX_ACTIVE_JOB_QUEUE=good_job -HYRAX_FITS_PATH=/app/fits/fits.sh -NEGATIVE_CAPTCHA_SECRET=default-value-change-me SOLR_ADMIN_PASSWORD=SolrRocks SOLR_ADMIN_USER=solr SOLR_COLLECTION_NAME=hydra-development @@ -33,6 +34,8 @@ SOLR_CONFIGSET_NAME=hyku SOLR_HOST=solr SOLR_PORT=8983 SOLR_URL=http://solr:SolrRocks@solr:8983/solr/ +TB_RSPEC_FORMATTER=progress +TB_RSPEC_OPTIONS="--format RspecJunitFormatter --out rspec.xml" # Comment out these 5 for single tenancy / Uncomment for multi HYKU_ADMIN_HOST=hyku.test From 2a80187c8e54db4c80812cb2ae56762767b3dcc0 Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Sun, 1 Oct 2023 15:44:24 -0400 Subject: [PATCH 028/126] spec loading fixes --- Gemfile.lock | 8 ++++---- spec/controllers/search_history_controller_spec.rb | 2 +- spec/tasks/rake_spec.rb | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 4436734e8..23b91297a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -786,7 +786,7 @@ GEM mini_magick (4.12.0) mini_mime (1.1.2) mini_portile2 (2.8.4) - minitest (5.18.1) + minitest (5.20.0) mods (2.4.1) edtf iso-639 @@ -933,7 +933,7 @@ GEM actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) activesupport (>= 5.0.1.rc1) - rails-dom-testing (2.1.1) + rails-dom-testing (2.2.0) activesupport (>= 5.0.0) minitest nokogiri (>= 1.6) @@ -1067,7 +1067,7 @@ GEM rspec-its (1.3.0) rspec-core (>= 3.0.0) rspec-expectations (>= 3.0.0) - rspec-mocks (3.12.5) + rspec-mocks (3.12.6) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) rspec-rails (5.1.2) @@ -1080,7 +1080,7 @@ GEM rspec-support (~> 3.10) rspec-retry (0.6.2) rspec-core (> 3.3) - rspec-support (3.12.0) + rspec-support (3.12.1) rspec_junit_formatter (0.6.0) rspec-core (>= 2, < 4, != 2.12.0) rubocop (0.52.1) diff --git a/spec/controllers/search_history_controller_spec.rb b/spec/controllers/search_history_controller_spec.rb index d9a349279..379e29e59 100644 --- a/spec/controllers/search_history_controller_spec.rb +++ b/spec/controllers/search_history_controller_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.describe SearchHistoryController do +RSpec.describe SearchHistoryController, type: :controller do routes { Blacklight::Engine.routes } describe 'index' do diff --git a/spec/tasks/rake_spec.rb b/spec/tasks/rake_spec.rb index 3543bf304..0011bf4a3 100644 --- a/spec/tasks/rake_spec.rb +++ b/spec/tasks/rake_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require 'rake' -load 'app/models/site.rb' +load Rails.root.join('app/models/site.rb') RSpec.describe "Rake tasks" do before(:all) do From 691dda747dae1611b8520e377caccdb4aea96bf9 Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Sun, 1 Oct 2023 15:55:20 -0400 Subject: [PATCH 029/126] rubocop --- spec/tasks/rake_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/tasks/rake_spec.rb b/spec/tasks/rake_spec.rb index 0011bf4a3..c4734c2cf 100644 --- a/spec/tasks/rake_spec.rb +++ b/spec/tasks/rake_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require 'rake' -load Rails.root.join('app/models/site.rb') +load Rails.root.join('app', 'models', 'site.rb') RSpec.describe "Rake tasks" do before(:all) do From deec7e2f6c5501eb99a95dddeef97617657af2df Mon Sep 17 00:00:00 2001 From: LaRita Robinson Date: Mon, 2 Oct 2023 14:31:28 -0400 Subject: [PATCH 030/126] =?UTF-8?q?=F0=9F=A7=B9Make=20appearance=20default?= =?UTF-8?q?s=20overrideable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/forms/hyrax/forms/admin/appearance.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/forms/hyrax/forms/admin/appearance.rb b/app/forms/hyrax/forms/admin/appearance.rb index 7f20affae..ec64d6bb3 100644 --- a/app/forms/hyrax/forms/admin/appearance.rb +++ b/app/forms/hyrax/forms/admin/appearance.rb @@ -42,8 +42,6 @@ class Appearance 'facet_panel_text_color' => '#333333' }.freeze - DEFAULT_VALUES = DEFAULT_FONTS.merge(DEFAULT_COLORS).freeze - # @param [Hash] attributes the list of parameters from the form def initialize(attributes = {}) @attributes = attributes @@ -430,8 +428,12 @@ def convert_to_rgba(hex_color, alpha = 0.5) "rgba(#{rgb[0]}, #{rgb[1]}, #{rgb[2]}, #{alpha})" end + def default_values + @default_values ||= DEFAULT_FONTS.merge(DEFAULT_COLORS) + end + def block_for(name, dynamic_default = nil) - ContentBlock.block_for(name: name, fallback_value: DEFAULT_VALUES[name] || dynamic_default) + ContentBlock.block_for(name: name, fallback_value: default_values[name] || dynamic_default) end # Persist a key/value tuple as a ContentBlock From cb2e3bfc09928830ed2e3d4f2593f8fa1aba725a Mon Sep 17 00:00:00 2001 From: Shana Moore Date: Mon, 2 Oct 2023 15:01:09 -0700 Subject: [PATCH 031/126] bump bulkrax to 5.4.0 This commit pulls in a small collection of bug fixes. --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 21850c73c..976ad7d3a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -266,7 +266,7 @@ GEM signet (~> 0.8) typhoeus builder (3.2.4) - bulkrax (5.3.0) + bulkrax (5.4.0) bagit (~> 0.4) coderay dry-monads (~> 1.4.0) From c700d41d457cbe33ea58ea23f766a1fc19f510f3 Mon Sep 17 00:00:00 2001 From: LaRita Robinson Date: Mon, 2 Oct 2023 23:02:04 -0400 Subject: [PATCH 032/126] =?UTF-8?q?=F0=9F=A7=B9=20Include=20knapsack=20css?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/assets/stylesheets/application.css | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 61efe4aa9..f468cc6c3 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -21,4 +21,5 @@ *= require blacklight_advanced_search *= require blacklight_range_limit *= require_self + *= require hyku_knapsack/application */ From 35526646c157b5f2ea489f78ddb825c0e25cc245 Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Tue, 3 Oct 2023 11:26:46 -0400 Subject: [PATCH 033/126] fix job loading when selecting good job --- config/initializers/apartment.rb | 2 +- .../20230406183810_setup_good_jobs_schema.rb | 16 ++++++++++++++++ db/schema.rb | 2 ++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20230406183810_setup_good_jobs_schema.rb diff --git a/config/initializers/apartment.rb b/config/initializers/apartment.rb index a2647571d..53934a77b 100644 --- a/config/initializers/apartment.rb +++ b/config/initializers/apartment.rb @@ -12,7 +12,7 @@ # Add any models that you do not want to be multi-tenanted, but remain in the global (public) namespace. # A typical example would be a Customer or Tenant model that stores each Tenant's information. - config.excluded_models = %w{ Account AccountCrossSearch DomainName Endpoint User UserStat SolrEndpoint FcrepoEndpoint RedisEndpoint } + config.excluded_models = %w{ Account AccountCrossSearch DomainName Endpoint User UserStat SolrEndpoint FcrepoEndpoint RedisEndpoint GoodJob::Execution GoodJob::Job GoodJob::Process } # In order to migrate all of your Tenants you need to provide a list of Tenant names to Apartment. # You can make this dynamic by providing a Proc object to be called on migrations. diff --git a/db/migrate/20230406183810_setup_good_jobs_schema.rb b/db/migrate/20230406183810_setup_good_jobs_schema.rb new file mode 100644 index 000000000..5ffdffee0 --- /dev/null +++ b/db/migrate/20230406183810_setup_good_jobs_schema.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +# This migration pre-sets the shared_extensions schema for in prep for good_jobs +class SetupGoodJobsSchema < ActiveRecord::Migration[5.2] + def change + # Create Schema + ActiveRecord::Base.connection.execute 'CREATE SCHEMA IF NOT EXISTS shared_extensions;' + # Enable Hstore + ActiveRecord::Base.connection.execute 'CREATE EXTENSION IF NOT EXISTS HSTORE SCHEMA shared_extensions;' + # Enable UUID-OSSP + ActiveRecord::Base.connection.execute 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp" SCHEMA shared_extensions;' + ActiveRecord::Base.connection.execute 'CREATE EXTENSION IF NOT EXISTS "pgcrypto" SCHEMA shared_extensions;' + # Grant usage to public + ActiveRecord::Base.connection.execute 'GRANT usage ON SCHEMA shared_extensions to public;' + end +end diff --git a/db/schema.rb b/db/schema.rb index c523cfd22..c2b964beb 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -13,8 +13,10 @@ ActiveRecord::Schema.define(version: 2023_08_04_073106) do # These are extensions that must be enabled in order to support this database + enable_extension "hstore" enable_extension "pgcrypto" enable_extension "plpgsql" + enable_extension "uuid-ossp" create_table "account_cross_searches", force: :cascade do |t| t.bigint "search_account_id" From 64d9281acf8362d4eb8e99c4ae64e5c1e9128684 Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Tue, 3 Oct 2023 11:29:05 -0400 Subject: [PATCH 034/126] adjust docker compose to use the startup script --- docker-compose.yml | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index dafc2446b..512e9bf4b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -135,7 +135,7 @@ services: web: <<: *app - # Uncomment command to access container with out starting Rails. Useful for debugging + # Uncomment command to access container with out starting bin/web. Useful for debugging # command: sleep infinity environment: - VIRTUAL_PORT=3000 @@ -167,6 +167,8 @@ services: worker: <<: *app image: ghcr.io/samvera/hyku/worker:${TAG:-latest} + # Uncomment command to access container with out starting bin/worker. Useful for debugging + # command: sleep infinity build: context: . target: hyku-worker @@ -176,15 +178,6 @@ services: - ghcr.io/samvera/hyku/base:latest - ghcr.io/samvera/hyku:latest - ghcr.io/samvera/hyku/worker:latest - command: - - /bin/sh - - -c - - > - if [ "$$HYRAX_ACTIVE_JOB_QUEUE" == "good_job" ]; then - exec bundle exec good_job start - else - exec bundle exec sidekiq - fi depends_on: check_volumes: condition: service_completed_successfully From 5feb7f429b8ba9d90d40ae40d5b0b3e4910c2b1d Mon Sep 17 00:00:00 2001 From: Shana Moore Date: Tue, 3 Oct 2023 10:54:27 -0700 Subject: [PATCH 035/126] :gift: install tesseract eng_best --- Dockerfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Dockerfile b/Dockerfile index d13b8e942..c9d3ecdd9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -47,6 +47,11 @@ RUN wget https://github.com/ImageMagick/ImageMagick/archive/refs/tags/7.1.0-57.t && rm -rf ImageMagick* \ && rm -rf /var/cache/apk/* +# Install "best" training data for Tesseract +RUN echo "📚 Installing Tesseract Best (training data)!" && \ + cd /usr/share/tessdata/ && \ + wget https://github.com/tesseract-ocr/tessdata_best/blob/main/eng.traineddata?raw=true -O eng_best.traineddata + ARG VIPS_VERSION=8.11.3 RUN set -x -o pipefail \ From e568fbd8372f920954e261b76ac5793dfbc5e1fc Mon Sep 17 00:00:00 2001 From: Shana Moore Date: Tue, 3 Oct 2023 15:16:06 -0700 Subject: [PATCH 036/126] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20revert=20tesseract?= =?UTF-8?q?=20best=20changes=20to=20dockerfile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit this change belongs in the knapsack directory instead --- Dockerfile | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index c9d3ecdd9..d13b8e942 100644 --- a/Dockerfile +++ b/Dockerfile @@ -47,11 +47,6 @@ RUN wget https://github.com/ImageMagick/ImageMagick/archive/refs/tags/7.1.0-57.t && rm -rf ImageMagick* \ && rm -rf /var/cache/apk/* -# Install "best" training data for Tesseract -RUN echo "📚 Installing Tesseract Best (training data)!" && \ - cd /usr/share/tessdata/ && \ - wget https://github.com/tesseract-ocr/tessdata_best/blob/main/eng.traineddata?raw=true -O eng_best.traineddata - ARG VIPS_VERSION=8.11.3 RUN set -x -o pipefail \ From 0f9169517d5a8651ee245d083b7a75f31383d7f0 Mon Sep 17 00:00:00 2001 From: Shana Moore Date: Tue, 3 Oct 2023 15:16:06 -0700 Subject: [PATCH 037/126] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20revert=20tesseract?= =?UTF-8?q?=20best=20changes=20to=20dockerfile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit this change belongs in the knapsack directory instead --- Dockerfile | 5 ----- config/application.rb | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index c9d3ecdd9..d13b8e942 100644 --- a/Dockerfile +++ b/Dockerfile @@ -47,11 +47,6 @@ RUN wget https://github.com/ImageMagick/ImageMagick/archive/refs/tags/7.1.0-57.t && rm -rf ImageMagick* \ && rm -rf /var/cache/apk/* -# Install "best" training data for Tesseract -RUN echo "📚 Installing Tesseract Best (training data)!" && \ - cd /usr/share/tessdata/ && \ - wget https://github.com/tesseract-ocr/tessdata_best/blob/main/eng.traineddata?raw=true -O eng_best.traineddata - ARG VIPS_VERSION=8.11.3 RUN set -x -o pipefail \ diff --git a/config/application.rb b/config/application.rb index 9244f821c..2c6ceefb2 100644 --- a/config/application.rb +++ b/config/application.rb @@ -77,7 +77,7 @@ class Application < Rails::Application # IiifPrint::DerivativeRodeoService, # Hyrax::FileSetDerivativesService] - DerivativeRodeo::Generators::HocrGenerator.additional_tessearct_options = "-l eng_best" + DerivativeRodeo::Generators::HocrGenerator.additional_tessearct_options = nil # Allows us to use decorator files Dir.glob(File.join(File.dirname(__FILE__), "../app/**/*_decorator*.rb")).sort.each do |c| From 26ae01378bd9c1317869aa50964c741420076326 Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Wed, 4 Oct 2023 11:52:29 -0700 Subject: [PATCH 038/126] =?UTF-8?q?=F0=9F=90=9B=20Bring=20fix=20for=20entr?= =?UTF-8?q?y=20show=20page=20not=20showing=20link?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit will bring in a fix from Bulkrax that correctly shows the object from the entry show page. ref: - https://github.com/samvera-labs/bulkrax/commit/0e68a5ea81307dc9e06f9a1e7c0c4cc8cd3de873 --- app/factories/bulkrax/object_factory_decorator.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/factories/bulkrax/object_factory_decorator.rb b/app/factories/bulkrax/object_factory_decorator.rb index 928cd8384..67f2d74a6 100644 --- a/app/factories/bulkrax/object_factory_decorator.rb +++ b/app/factories/bulkrax/object_factory_decorator.rb @@ -8,6 +8,21 @@ module ObjectFactoryDecorator def environment(attrs) Hyrax::Actors::Environment.new(object, Ability.new(@user), attrs, true) end + + # TODO: Verify and remove this once Bulkrax is updated 5.4.1 over greater and this is no longer needed + def search_by_identifier + # ref: https://github.com/samvera-labs/bulkrax/issues/866 + # ref:https://github.com/samvera-labs/bulkrax/issues/867 + # work_index = ::ActiveFedora.index_field_mapper.solr_name(work_identifier, :facetable) + work_index = work_identifier + query = { work_index => + source_identifier_value } + # Query can return partial matches (something6 matches both something6 and something68) + # so we need to weed out any that are not the correct full match. But other items might be + # in the multivalued field, so we have to go through them one at a time. + match = klass.where(query).detect { |m| m.send(work_identifier).include?(source_identifier_value) } + return match if match + end end end From 07fde572f9152d513b13f71cae90dd4fdfbfba6c Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Wed, 4 Oct 2023 12:19:18 -0700 Subject: [PATCH 039/126] =?UTF-8?q?=F0=9F=A7=B9=20Revert=20previous=20comm?= =?UTF-8?q?it=20and=20update=20Bulkrax?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit will update Bulkrax to 5.4.1 instead of using the override from the last commit. We also revert the changes from the last commit. --- Gemfile | 2 +- Gemfile.lock | 4 ++-- app/factories/bulkrax/object_factory_decorator.rb | 15 --------------- 3 files changed, 3 insertions(+), 18 deletions(-) diff --git a/Gemfile b/Gemfile index 683b0b823..c4a98f9c0 100644 --- a/Gemfile +++ b/Gemfile @@ -18,7 +18,7 @@ gem 'blacklight_oai_provider', '~> 6.1', '>= 6.1.1' gem 'blacklight_range_limit', '6.5.0' gem 'bolognese', '>= 1.9.10' gem 'bootstrap-datepicker-rails' -gem 'bulkrax', '~> 5.3' +gem 'bulkrax', '~> 5.4' gem 'byebug', group: %i[development test] gem 'capybara', group: %i[test] gem 'capybara-screenshot', '~> 1.0', group: %i[test] diff --git a/Gemfile.lock b/Gemfile.lock index 976ad7d3a..1b3206776 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -266,7 +266,7 @@ GEM signet (~> 0.8) typhoeus builder (3.2.4) - bulkrax (5.4.0) + bulkrax (5.4.1) bagit (~> 0.4) coderay dry-monads (~> 1.4.0) @@ -1328,7 +1328,7 @@ DEPENDENCIES blacklight_range_limit (= 6.5.0) bolognese (>= 1.9.10) bootstrap-datepicker-rails - bulkrax (~> 5.3) + bulkrax (~> 5.4) byebug capybara capybara-screenshot (~> 1.0) diff --git a/app/factories/bulkrax/object_factory_decorator.rb b/app/factories/bulkrax/object_factory_decorator.rb index 67f2d74a6..928cd8384 100644 --- a/app/factories/bulkrax/object_factory_decorator.rb +++ b/app/factories/bulkrax/object_factory_decorator.rb @@ -8,21 +8,6 @@ module ObjectFactoryDecorator def environment(attrs) Hyrax::Actors::Environment.new(object, Ability.new(@user), attrs, true) end - - # TODO: Verify and remove this once Bulkrax is updated 5.4.1 over greater and this is no longer needed - def search_by_identifier - # ref: https://github.com/samvera-labs/bulkrax/issues/866 - # ref:https://github.com/samvera-labs/bulkrax/issues/867 - # work_index = ::ActiveFedora.index_field_mapper.solr_name(work_identifier, :facetable) - work_index = work_identifier - query = { work_index => - source_identifier_value } - # Query can return partial matches (something6 matches both something6 and something68) - # so we need to weed out any that are not the correct full match. But other items might be - # in the multivalued field, so we have to go through them one at a time. - match = klass.where(query).detect { |m| m.send(work_identifier).include?(source_identifier_value) } - return match if match - end end end From 8ae51d8d1ae8fb74768c4631ba382c42bbb7ec2d Mon Sep 17 00:00:00 2001 From: Shana Moore Date: Wed, 4 Oct 2023 13:45:47 -0700 Subject: [PATCH 040/126] :bug: subject can't be blank for the contact form Previously there was a bug because even if you typed in a subject, the contact form would error saying that it was blank. Part of issue: - https://github.com/scientist-softserv/adventist-dl/issues/608 --- app/controllers/hyrax/contact_form_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/hyrax/contact_form_controller.rb b/app/controllers/hyrax/contact_form_controller.rb index 17f6cb614..705d7e0b1 100644 --- a/app/controllers/hyrax/contact_form_controller.rb +++ b/app/controllers/hyrax/contact_form_controller.rb @@ -50,6 +50,7 @@ def create # not spam, form is valid, and captcha is valid @captcha.values[:category] = params[:contact_form][:category] @captcha.values[:contact_method] = params[:contact_form][:contact_method] + @captcha.values[:subjects] = params[:contact_form][:subject] @contact_form = model_class.new(@captcha.values) if @contact_form.valid? && @captcha.valid? ContactMailer.contact(@contact_form).deliver_now From fd32f03e0571fc21517743534b264a45e67baa7b Mon Sep 17 00:00:00 2001 From: Shana Moore Date: Wed, 4 Oct 2023 13:48:47 -0700 Subject: [PATCH 041/126] mend --- app/controllers/hyrax/contact_form_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/hyrax/contact_form_controller.rb b/app/controllers/hyrax/contact_form_controller.rb index 705d7e0b1..a420f82d4 100644 --- a/app/controllers/hyrax/contact_form_controller.rb +++ b/app/controllers/hyrax/contact_form_controller.rb @@ -50,7 +50,7 @@ def create # not spam, form is valid, and captcha is valid @captcha.values[:category] = params[:contact_form][:category] @captcha.values[:contact_method] = params[:contact_form][:contact_method] - @captcha.values[:subjects] = params[:contact_form][:subject] + @captcha.values[:subject] = params[:contact_form][:subject] @contact_form = model_class.new(@captcha.values) if @contact_form.valid? && @captcha.valid? ContactMailer.contact(@contact_form).deliver_now From 5e0cc2c05d33b25c8105bee8f182a0ae60575100 Mon Sep 17 00:00:00 2001 From: Jeremy Friesen Date: Wed, 4 Oct 2023 17:15:13 -0400 Subject: [PATCH 042/126] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Add=20handling=20f?= =?UTF-8?q?or=20Knapsack=20theme=20overrides?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prior to this commit, we were looking for themes yaml files relative to the directory of the spawning script. For Hyku that was always the `Rails.root` directory. However, when running specs in Knapsack, that directory was `Knapsack::Engine.root`. This unearthed a potential configuration issue; namely that we want Knapsack's to control what themes are available, meaning we don't want to require amending Hyku's themes. So, we introduce a mechanism for looking up files first in the Knapsack then in Hyku. I discovered this bug in the specs for knapsack (below is the *Error stack trace*)
    Error stack trace ``` 2) Hyrax::Admin::AppearancesController with an administrator GET #show assigns the requested site as @site Failure/Error: get :show, params: {} Errno::ENOENT: No such file or directory @ rb_sysopen - config/home_themes.yml # /usr/local/bundle/gems/psych-3.3.4/lib/psych.rb:582:in `initialize' # /usr/local/bundle/gems/psych-3.3.4/lib/psych.rb:582:in `open' # /usr/local/bundle/gems/psych-3.3.4/lib/psych.rb:582:in `unsafe_load_file' # ./hyrax-webapp/app/controllers/hyrax/admin/appearances_controller.rb:19:in `show' # /usr/local/bundle/gems/rails-controller-testing-1.0.5/lib/rails/controller/testing/template_assertions.rb:62:in `process' # /usr/local/bundle/gems/devise-4.9.2/lib/devise/test/controller_helpers.rb:35:in `block in process' # /usr/local/bundle/gems/devise-4.9.2/lib/devise/test/controller_helpers.rb:104:in `catch' # /usr/local/bundle/gems/devise-4.9.2/lib/devise/test/controller_helpers.rb:104:in `_catch_warden' # /usr/local/bundle/gems/devise-4.9.2/lib/devise/test/controller_helpers.rb:35:in `process' # /usr/local/bundle/gems/rails-controller-testing-1.0.5/lib/rails/controller/testing/integration.rb:16:in `block (2 levels) in ' # ./spec/controllers/hyrax/hyrax/admin/appearances_controller_spec.rb:31:in `block (4 levels) in ' # /usr/local/bundle/gems/webmock-3.19.1/lib/webmock/rspec.rb:39:in `block (2 levels) in ' # ./hyrax-webapp/spec/support/multitenancy_metadata.rb:50:in `block (2 levels) in ' # /usr/local/bundle/gems/rspec-retry-0.6.2/lib/rspec/retry.rb:124:in `block in run' # /usr/local/bundle/gems/rspec-retry-0.6.2/lib/rspec/retry.rb:110:in `loop' # /usr/local/bundle/gems/rspec-retry-0.6.2/lib/rspec/retry.rb:110:in `run' # /usr/local/bundle/gems/rspec-retry-0.6.2/lib/rspec_ext/rspec_ext.rb:12:in `run_with_retry' # /usr/local/bundle/gems/rspec-retry-0.6.2/lib/rspec/retry.rb:37:in `block (2 levels) in setup' # ./spec/spec_helper.rb:10:in `block (2 levels) in ' ```
    Related to: - https://github.com/samvera/hyku/pull/2007 - https://github.com/samvera/hyku/pull/2008 The above two commits will require some reconciliation once this is incorporated. --- .../hyrax/admin/appearances_controller.rb | 4 ++-- config/application.rb | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/app/controllers/hyrax/admin/appearances_controller.rb b/app/controllers/hyrax/admin/appearances_controller.rb index b37308ebc..9130b8b11 100644 --- a/app/controllers/hyrax/admin/appearances_controller.rb +++ b/app/controllers/hyrax/admin/appearances_controller.rb @@ -16,8 +16,8 @@ def show add_breadcrumbs @form = form_class.new @fonts = [@form.headline_font, @form.body_font] - @home_theme_information = YAML.load_file('config/home_themes.yml') - @show_theme_information = YAML.load_file('config/show_themes.yml') + @home_theme_information = YAML.load_file(Hyku::Application.path_for('config/home_themes.yml')) + @show_theme_information = YAML.load_file(Hyku::Application.path_for('config/show_themes.yml')) @home_theme_names = load_home_theme_names @show_theme_names = load_show_theme_names @search_themes = load_search_themes diff --git a/config/application.rb b/config/application.rb index c221d0090..6aad688cf 100644 --- a/config/application.rb +++ b/config/application.rb @@ -37,6 +37,22 @@ class Application < Rails::Application # Add this line to load the lib folder first because we need config.autoload_paths.unshift("#{Rails.root}/lib") + ## + # @api public + # + # @param relative_path [String] lookup the relative paths first in the Knapsack then in Hyku. + # + # @return [String] the path to the file, favoring those found in the knapsack but falling back + # to those in the Rails.root. + def self.path_for(relative_path) + if defined?(HykuKnapsack) + engine_path = HykuKnapsack::Engine.root.join(relative_path) + return engine_path.to_s if engine_path.exist? + end + + Rails.root.join(relative_path).to_s + end + # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. From ff3fbcc5b0059577fdd24d841b8f5f01e66f070b Mon Sep 17 00:00:00 2001 From: Jeremy Friesen Date: Thu, 5 Oct 2023 08:47:22 -0400 Subject: [PATCH 043/126] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Favor=20Hyku::Appl?= =?UTF-8?q?ication.path=5Ffor=20over=20Rails.root?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Given the existence of Knapsack we need to consider how overrides in Knapsack will take precedence over Hyku files. This change handles cases where we want to use the Knapsack's uploaded thumbnails. Related to: - #2010 --- app/services/uploaded_collection_thumbnail_path_service.rb | 4 ++-- .../hyrax/dashboard/collections/_current_thumbnail.html.erb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/services/uploaded_collection_thumbnail_path_service.rb b/app/services/uploaded_collection_thumbnail_path_service.rb index 18a3f662e..c22ac5801 100644 --- a/app/services/uploaded_collection_thumbnail_path_service.rb +++ b/app/services/uploaded_collection_thumbnail_path_service.rb @@ -9,11 +9,11 @@ def call(object) # rubocop:disable Metrics/LineLength, Rails/FilePath, Lint/StringConversionInInterpolation def uploaded_thumbnail?(collection) - File.exist?("#{Rails.root.to_s}/public/uploads/uploaded_collection_thumbnails/#{collection.id}/#{collection.id}_card.jpg") + File.exist?(File.join(upload_dir(collection), "#{collection.id}_card.jpg")) end def upload_dir(collection) - "#{Rails.root.to_s}/public/uploads/uploaded_collection_thumbnails/#{collection.id}" + Hyku::Application.path_for("public/uploads/uploaded_collection_thumbnails/#{collection.id}") end # rubocop:enable Metrics/LineLength, Rails/FilePath, Lint/StringConversionInInterpolation end diff --git a/app/views/hyrax/dashboard/collections/_current_thumbnail.html.erb b/app/views/hyrax/dashboard/collections/_current_thumbnail.html.erb index 33306d375..fb64f8cc4 100644 --- a/app/views/hyrax/dashboard/collections/_current_thumbnail.html.erb +++ b/app/views/hyrax/dashboard/collections/_current_thumbnail.html.erb @@ -1,5 +1,5 @@ <% thumbnail_path = SolrDocument.find(@collection.id).thumbnail_path %> - <% if thumbnail_path.include?("uploaded_collection_thumbnails") and File.exist? Rails.root.join("public#{::SolrDocument.find(@collection.id).thumbnail_path}") %> + <% if thumbnail_path.include?("uploaded_collection_thumbnails") and File.exist? Hyky::Application.path_for("public#{::SolrDocument.find(@collection.id).thumbnail_path}") %> <%= image_tag(thumbnail_path, class: "current-thumbnail") %>

    Current image: <%= @thumbnail_filename %>

    <% else %> From 80e02d360760f87f2414245490b1c3f25f6923f2 Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Fri, 6 Oct 2023 08:48:40 -0700 Subject: [PATCH 044/126] =?UTF-8?q?=F0=9F=8E=81=20Add=20highlight=20key=20?= =?UTF-8?q?to=20UV?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit allows for the `parent_query` to be highlighted in the UV so users won't have to do a catalog search and also a UV search. --- config/uv/uv.html | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/config/uv/uv.html b/config/uv/uv.html index c8e8eced5..c44dbb45d 100644 --- a/config/uv/uv.html +++ b/config/uv/uv.html @@ -19,20 +19,20 @@ } - + - +
    - + From ae093f1c04e036057c17ec14e8a8ebeeac32a6bb Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Fri, 6 Oct 2023 22:12:27 -0700 Subject: [PATCH 045/126] =?UTF-8?q?=F0=9F=90=9B=20Mixin=20`HykuKnapsack::A?= =?UTF-8?q?pplicationHelper`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit will mixin the `HykuKnapsack::ApplicationHelper` into the ApplicationHelper which will allow us to use #render_ocr_snippets for snippet highlighting. --- app/controllers/application_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 9449da3c0..6bb33d215 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -2,6 +2,7 @@ class ApplicationController < ActionController::Base include HykuHelper + include HykuKnapsack::ApplicationHelper # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. protect_from_forgery with: :exception, prepend: true From 9827c14489eedde7b5fffe6642bb038fb3aa4fd8 Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Fri, 6 Oct 2023 22:25:02 -0700 Subject: [PATCH 046/126] =?UTF-8?q?Revert=20"=F0=9F=90=9B=20Mixin=20`HykuK?= =?UTF-8?q?napsack::ApplicationHelper`"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit ae093f1c04e036057c17ec14e8a8ebeeac32a6bb. --- app/controllers/application_controller.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 6bb33d215..9449da3c0 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -2,7 +2,6 @@ class ApplicationController < ActionController::Base include HykuHelper - include HykuKnapsack::ApplicationHelper # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. protect_from_forgery with: :exception, prepend: true From 6ccd6181287d31b6f52e46f8c3107d36ad9f811a Mon Sep 17 00:00:00 2001 From: Jeremy Friesen Date: Tue, 10 Oct 2023 09:08:32 -0400 Subject: [PATCH 047/126] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Favor=20class=5Fat?= =?UTF-8?q?tribute=20over=20constant?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In Adventist, we're needing to override the constant's values. By making this a class_attribute we can more readily do the override via configuration instead of obliteration of a constant. --- app/forms/hyrax/forms/admin/appearance.rb | 18 ++++++++++++---- ...oaded_collection_thumbnail_path_service.rb | 4 ++-- .../appearances/_default_colors_form.html.erb | 4 ++-- .../appearances/_default_fonts_form.html.erb | 4 ++-- .../hyrax/forms/admin/appearance_spec.rb | 21 +++++++++++++++++++ 5 files changed, 41 insertions(+), 10 deletions(-) create mode 100644 spec/forms/hyrax/forms/admin/appearance_spec.rb diff --git a/app/forms/hyrax/forms/admin/appearance.rb b/app/forms/hyrax/forms/admin/appearance.rb index ec64d6bb3..a58cb732d 100644 --- a/app/forms/hyrax/forms/admin/appearance.rb +++ b/app/forms/hyrax/forms/admin/appearance.rb @@ -17,12 +17,21 @@ class Appearance delegate :default_collection_image, :default_collection_image?, to: :site delegate :default_work_image, :default_work_image?, to: :site - DEFAULT_FONTS = { + ## + # @!group Class Attributes + # + # @!attribute default_fonts + # @return [Hash] there should be at least the key "body_font" and + # "headline_font" + class_attribute :default_fonts, default: { 'body_font' => 'Helvetica Neue, Helvetica, Arial, sans-serif;', 'headline_font' => 'Helvetica Neue, Helvetica, Arial, sans-serif;' - }.freeze + } - DEFAULT_COLORS = { + ## + # @!attribute default_colors + # @return [Hash] + class_attribute :default_colors, default: { 'header_and_footer_background_color' => '#3c3c3c', 'header_and_footer_text_color' => '#dcdcdc', 'navbar_background_color' => '#000000', @@ -40,7 +49,8 @@ class Appearance # 'active_tabs_background_color' => '#337ab7', 'facet_panel_background_color' => '#f5f5f5', 'facet_panel_text_color' => '#333333' - }.freeze + } + # @!endgroup Class Attributes # @param [Hash] attributes the list of parameters from the form def initialize(attributes = {}) diff --git a/app/services/uploaded_collection_thumbnail_path_service.rb b/app/services/uploaded_collection_thumbnail_path_service.rb index c22ac5801..1abfb8013 100644 --- a/app/services/uploaded_collection_thumbnail_path_service.rb +++ b/app/services/uploaded_collection_thumbnail_path_service.rb @@ -7,7 +7,7 @@ def call(object) "/uploads/uploaded_collection_thumbnails/#{object.id}/#{object.id}_card.jpg" end - # rubocop:disable Metrics/LineLength, Rails/FilePath, Lint/StringConversionInInterpolation + # rubocop:disable Metrics/LineLength, Rails/FilePath def uploaded_thumbnail?(collection) File.exist?(File.join(upload_dir(collection), "#{collection.id}_card.jpg")) end @@ -15,6 +15,6 @@ def uploaded_thumbnail?(collection) def upload_dir(collection) Hyku::Application.path_for("public/uploads/uploaded_collection_thumbnails/#{collection.id}") end - # rubocop:enable Metrics/LineLength, Rails/FilePath, Lint/StringConversionInInterpolation + # rubocop:enable Metrics/LineLength, Rails/FilePath end end diff --git a/app/views/hyrax/admin/appearances/_default_colors_form.html.erb b/app/views/hyrax/admin/appearances/_default_colors_form.html.erb index 9a8251957..69c66108f 100644 --- a/app/views/hyrax/admin/appearances/_default_colors_form.html.erb +++ b/app/views/hyrax/admin/appearances/_default_colors_form.html.erb @@ -1,6 +1,6 @@ <%= simple_form_for @form, url: admin_appearance_path do |f| %>
    - <% @form.class::DEFAULT_COLORS.each do |color_name, hex| %> + <% @form.default_colors.each do |color_name, hex| %> <%= render 'color_input', f: f, color_name: color_name, hex: hex %> <% end %>
    @@ -8,4 +8,4 @@ <%= link_to 'Restore All Defaults', '#color', class: 'btn btn-default restore-all-default-colors' %> <%= f.submit class: 'btn btn-primary pull-right' %> -<% end %> \ No newline at end of file +<% end %> diff --git a/app/views/hyrax/admin/appearances/_default_fonts_form.html.erb b/app/views/hyrax/admin/appearances/_default_fonts_form.html.erb index 3df04aba3..04e6192b2 100644 --- a/app/views/hyrax/admin/appearances/_default_fonts_form.html.erb +++ b/app/views/hyrax/admin/appearances/_default_fonts_form.html.erb @@ -1,6 +1,6 @@ <%= simple_form_for @form, url: admin_appearance_path do |f| %>
    - <% df = @form.class::DEFAULT_FONTS %> + <% df = @form.default_fonts %> <% font = f.object.body_font %> <%= f.input :body_font, label: 'Select Body Font', required: false, input_html: { class: 'font-fields', data: { default_value: df['body_font'] } } %> @@ -14,4 +14,4 @@ <%= link_to 'Restore All Defaults', '#font', class: 'btn btn-default restore-all-default-fonts' %> <%= f.submit class: 'btn btn-primary pull-right' %>
    -<% end %> \ No newline at end of file +<% end %> diff --git a/spec/forms/hyrax/forms/admin/appearance_spec.rb b/spec/forms/hyrax/forms/admin/appearance_spec.rb new file mode 100644 index 000000000..466c50e3b --- /dev/null +++ b/spec/forms/hyrax/forms/admin/appearance_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Hyrax::Forms::Admin::Appearance do + describe '.default_fonts' do + subject { described_class.default_fonts } + + it { is_expected.to be_a(Hash) } + + it "has the 'body_font' and 'headline_font' keys" do + expect(subject.keys).to match_array(['body_font', 'headline_font']) + end + end + + describe '.default_colors' do + subject { described_class.default_colors } + + it { is_expected.to be_a(Hash) } + end +end From 2ff5f6c6e2a5695ffa89277049bf1ce8ac08c928 Mon Sep 17 00:00:00 2001 From: Jeremy Friesen Date: Tue, 10 Oct 2023 09:12:59 -0400 Subject: [PATCH 048/126] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Favor=20configurab?= =?UTF-8?q?le=20html=20head=20title=20value?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prior to this commit, we hard-coded the page title; this is something that should be far more configurable. And this refactor is a step towards that. This also allows for downstream implementors to not have to override the view simply to change the title element. --- app/views/layouts/application.html.erb | 2 +- config/application.rb | 9 +++++++++ spec/config/application_spec.rb | 9 +++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 spec/config/application_spec.rb diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 7b0575693..f0a8e0a85 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -1,7 +1,7 @@ - Hyku + <%= Hyku::Application.html_head_title %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> <%= csrf_meta_tags %> diff --git a/config/application.rb b/config/application.rb index 1eed55d69..40f2c32f2 100644 --- a/config/application.rb +++ b/config/application.rb @@ -34,6 +34,15 @@ def self.utf_8_encode(string) end class Application < Rails::Application + ## + # @!group Class Attributes + # + # @!attribute html_head_title + # The title to render for the application's HTML > HEAD > TITLE element. + # @return [String] + class_attribute :html_head_title, default: "Hyku", attr_accessor: false + # @!endgroup Class Attributes + # Add this line to load the lib folder first because we need # IiifPrint::SplitPdfs::AdventistPagesToJpgsSplitter config.autoload_paths.unshift("#{Rails.root}/lib") diff --git a/spec/config/application_spec.rb b/spec/config/application_spec.rb new file mode 100644 index 000000000..35ce1619b --- /dev/null +++ b/spec/config/application_spec.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Hyku::Application do + describe '.html_head_title' do + it { is_expected.to be_a(String) } + end +end From 1c2a9d4912f76e80ebf221208d666669b1fdf79a Mon Sep 17 00:00:00 2001 From: Jeremy Friesen Date: Tue, 10 Oct 2023 10:11:10 -0400 Subject: [PATCH 049/126] =?UTF-8?q?=F0=9F=90=9B=20Add=20custom=20rendering?= =?UTF-8?q?=20for=20license?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prior to this commit, the License would render as a plain URL. With this change, we are now coercing the license into a URL that is labeled and titled with the name of the license. This is copied and modified based on [Rights show partial][1] Related to: - https://github.com/scientist-softserv/adventist-dl/issues/620 [1]: https://github.com/samvera/hyrax/blob/b334e186e77691d7da8ed59ff27f091be1c2a700/app/views/records/show_fields/_rights.html.erb --- .rubocop.yml | 4 ++++ app/services/uploaded_collection_thumbnail_path_service.rb | 2 -- app/views/records/show_fields/_license.html.erb | 4 ++++ 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 app/views/records/show_fields/_license.html.erb diff --git a/.rubocop.yml b/.rubocop.yml index 90961c959..4a5fb78c8 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -127,3 +127,7 @@ Metrics/BlockLength: - 'spec/**/*.rb' - 'lib/tasks/*.rake' - 'app/controllers/catalog_controller.rb' + +RSpec/FilePath: + Exclude: + - 'spec/config/application_spec.rb' diff --git a/app/services/uploaded_collection_thumbnail_path_service.rb b/app/services/uploaded_collection_thumbnail_path_service.rb index 1abfb8013..3685f9bb9 100644 --- a/app/services/uploaded_collection_thumbnail_path_service.rb +++ b/app/services/uploaded_collection_thumbnail_path_service.rb @@ -7,7 +7,6 @@ def call(object) "/uploads/uploaded_collection_thumbnails/#{object.id}/#{object.id}_card.jpg" end - # rubocop:disable Metrics/LineLength, Rails/FilePath def uploaded_thumbnail?(collection) File.exist?(File.join(upload_dir(collection), "#{collection.id}_card.jpg")) end @@ -15,6 +14,5 @@ def uploaded_thumbnail?(collection) def upload_dir(collection) Hyku::Application.path_for("public/uploads/uploaded_collection_thumbnails/#{collection.id}") end - # rubocop:enable Metrics/LineLength, Rails/FilePath end end diff --git a/app/views/records/show_fields/_license.html.erb b/app/views/records/show_fields/_license.html.erb new file mode 100644 index 000000000..15cef91e0 --- /dev/null +++ b/app/views/records/show_fields/_license.html.erb @@ -0,0 +1,4 @@ +<% service = Hyrax::LicenseService.new %> +<% record.license.each do |r| %> + <%= link_to_field('license', r, service.label(r)) %> <%= iconify_auto_link(r, false) %>
    +<% end %> From 363bc070b2e0c8d782cf4037203cb0f1bf75297d Mon Sep 17 00:00:00 2001 From: Jeremy Friesen Date: Tue, 10 Oct 2023 15:31:16 -0400 Subject: [PATCH 050/126] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Add=20option=20to?= =?UTF-8?q?=20override=20devise=20configuration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For Adventist, we wanted to disable registration of accounts as this was creating a case where folks were creating their own accounts and tenants. Related to: - https://github.com/scientist-softserv/adventist-dl/issues/492 - https://github.com/scientist-softserv/adventist-dl/issues/618 - https://github.com/samvera/hyku/pull/1964 - https://github.com/scientist-softserv/adventist-dl/pull/493 --- app/models/user.rb | 4 +--- config/application.rb | 15 +++++++++++++++ spec/config/application_spec.rb | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 7bfdd16cf..cfdea7500 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -14,9 +14,7 @@ class User < ApplicationRecord include Blacklight::User # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable - devise :database_authenticatable, :invitable, :registerable, - :recoverable, :rememberable, :trackable, :validatable, - :omniauthable, omniauth_providers: %i[saml openid_connect cas] + devise(*Hyku::Application.user_devise_parameters) after_create :add_default_group_membership! diff --git a/config/application.rb b/config/application.rb index 40f2c32f2..3af68f13f 100644 --- a/config/application.rb +++ b/config/application.rb @@ -41,6 +41,21 @@ class Application < Rails::Application # The title to render for the application's HTML > HEAD > TITLE element. # @return [String] class_attribute :html_head_title, default: "Hyku", attr_accessor: false + + # @!attribute user_devise_parameters + # @return [Object] + # + # This is a value that you want to set in the before_initialize block. + class_attribute :user_devise_parameters, instance_accessor: false, default: [ + :database_authenticatable, + :invitable, + :registerable, + :recoverable, + :rememberable, + :trackable, + :validatable, + :omniauthable, { omniauth_providers: %i[saml openid_connect cas] }] + # @!endgroup Class Attributes # Add this line to load the lib folder first because we need diff --git a/spec/config/application_spec.rb b/spec/config/application_spec.rb index 35ce1619b..a3ab79038 100644 --- a/spec/config/application_spec.rb +++ b/spec/config/application_spec.rb @@ -4,6 +4,24 @@ RSpec.describe Hyku::Application do describe '.html_head_title' do + subject { described_class.html_head_title } + it { is_expected.to be_a(String) } end + + describe '.user_devise_parameters' do + subject { described_class.user_devise_parameters } + + it do + is_expected.to eq([:database_authenticatable, + :invitable, + :registerable, + :recoverable, + :rememberable, + :trackable, + :validatable, + :omniauthable, + { omniauth_providers: %i[saml openid_connect cas] }]) + end + end end From 961b712aeafa419c167d51996057ac636f0716b7 Mon Sep 17 00:00:00 2001 From: Rob Kaufman Date: Thu, 12 Oct 2023 13:39:49 -0700 Subject: [PATCH 051/126] run asset build later in process to allow knapsack to run it only one time --- Dockerfile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index d13b8e942..8916c378e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -91,10 +91,9 @@ ONBUILD RUN git config --global --add safe.directory /app/samvera && \ ONBUILD COPY --chown=1001:101 $APP_PATH /app/samvera/hyrax-webapp -ONBUILD RUN RAILS_ENV=production SECRET_KEY_BASE=`bin/rake secret` DB_ADAPTER=nulldb DB_URL='postgresql://fake' bundle exec rake assets:precompile && yarn install - - FROM hyku-base as hyku-web +RUN RAILS_ENV=production SECRET_KEY_BASE=`bin/rake secret` DB_ADAPTER=nulldb DB_URL='postgresql://fake' bundle exec rake assets:precompile && yarn install + CMD ./bin/web FROM hyku-web as hyku-worker From 6930f7fdc71d693fb049a580eb9b7fc8cbafbba4 Mon Sep 17 00:00:00 2001 From: Jeremy Friesen Date: Fri, 13 Oct 2023 12:34:12 -0400 Subject: [PATCH 052/126] =?UTF-8?q?=F0=9F=90=9B=20Fix=20Add=20to=20Collect?= =?UTF-8?q?ion=20for=20page=202+=20of=20works?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prior to this commit, when you were on page 2 of your works and selected a work to add to a collection, the query for available collections would use the page 2 as part of the collection query. This would mean the first 100 collections (default page size) that you had access to add works to were skipped. With this commit, we omit the query parameters from the works page and then query collections. Related to: - https://github.com/samvera/hyrax/pull/5972 - https://github.com/samvera/hyrax/issues/5969 - https://github.com/scientist-softserv/adventist-dl/issues/625 Co-authored-by: LaRita Robinson --- .../hyrax/my/works_controller_decorator.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 app/controllers/hyrax/my/works_controller_decorator.rb diff --git a/app/controllers/hyrax/my/works_controller_decorator.rb b/app/controllers/hyrax/my/works_controller_decorator.rb new file mode 100644 index 000000000..2817729e9 --- /dev/null +++ b/app/controllers/hyrax/my/works_controller_decorator.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +## +# OVERRIDE Hyrax 3.5.0; when Hyrax hits v4.0.0 we can remove this. +# @see https://github.com/samvera/hyrax/pull/5972 +module Hyrax + module My + module WorksControllerDecorator + def collection_service + cloned = clone + cloned.params = {} + Hyrax::CollectionsService.new(cloned) + end + end + end +end + +Hyrax::My::WorksController.prepend(Hyrax::My::WorksControllerDecorator) From ad8444e99446afe93c188052fd0f41ff13fa3c87 Mon Sep 17 00:00:00 2001 From: Benjamin Kiah Stroud <32469930+bkiahstroud@users.noreply.github.com> Date: Fri, 13 Oct 2023 10:26:12 -0700 Subject: [PATCH 053/126] test that invited users are added to the registered group --- .../hyku/invitations_controller_spec.rb | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/spec/controllers/hyku/invitations_controller_spec.rb b/spec/controllers/hyku/invitations_controller_spec.rb index 4ed0cf5c0..bf87c4ff4 100644 --- a/spec/controllers/hyku/invitations_controller_spec.rb +++ b/spec/controllers/hyku/invitations_controller_spec.rb @@ -31,5 +31,31 @@ expect(response).to redirect_to Hyrax::Engine.routes.url_helpers.admin_users_path(locale: 'en') expect(flash[:notice]).to eq 'An invitation email has been sent to user@guest.org.' end + + context 'when user already exists' do + let(:user) { create(:user) } + + # Mimic the state of a user who is only active in other tenants; + # i.e. a user who has no roles in this tenant + before do + user.roles.destroy_all + end + + it 'adds the user to the registered group' do + expect(user.roles).to be_empty + expect(user.groups).to be_empty + + post :create, params: { + user: { + email: user.email, + role: '' + } + } + + user.reload + expect(user.roles).not_to be_empty + expect(user.groups).to eq([Ability.registered_group_name]) + end + end end end From db098e1d313624d824d1de287ffe543842f6885b Mon Sep 17 00:00:00 2001 From: Benjamin Kiah Stroud <32469930+bkiahstroud@users.noreply.github.com> Date: Thu, 12 Oct 2023 18:21:19 -0700 Subject: [PATCH 054/126] Add invited users to the registered group Fixes a bug where users who were invited with no roles would not show up in the users list at all --- app/controllers/hyku/invitations_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/hyku/invitations_controller.rb b/app/controllers/hyku/invitations_controller.rb index dbe246cda..2aa11fcac 100644 --- a/app/controllers/hyku/invitations_controller.rb +++ b/app/controllers/hyku/invitations_controller.rb @@ -14,6 +14,7 @@ def create authorize! :grant_admin_role, User if params[:user][:role] == ::RolesService::ADMIN_ROLE self.resource = User.find_by(email: params[:user][:email]) || invite_resource + resource.add_default_group_membership! resource.add_role(params[:user][:role], Site.instance) if params[:user][:role].present? yield resource if block_given? From 3919082b95d1cba35c1fbdc8f8d63422e9a74962 Mon Sep 17 00:00:00 2001 From: LaRita Robinson Date: Wed, 18 Oct 2023 12:49:43 -0400 Subject: [PATCH 055/126] =?UTF-8?q?=F0=9F=90=9B=20Change=20Hyky=20to=20Hyk?= =?UTF-8?q?u=20(#2029)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Typo caused inability to upload collection thumbnail. --- .../hyrax/dashboard/collections/_current_thumbnail.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/hyrax/dashboard/collections/_current_thumbnail.html.erb b/app/views/hyrax/dashboard/collections/_current_thumbnail.html.erb index fb64f8cc4..7c78b27a4 100644 --- a/app/views/hyrax/dashboard/collections/_current_thumbnail.html.erb +++ b/app/views/hyrax/dashboard/collections/_current_thumbnail.html.erb @@ -1,5 +1,5 @@ <% thumbnail_path = SolrDocument.find(@collection.id).thumbnail_path %> - <% if thumbnail_path.include?("uploaded_collection_thumbnails") and File.exist? Hyky::Application.path_for("public#{::SolrDocument.find(@collection.id).thumbnail_path}") %> + <% if thumbnail_path.include?("uploaded_collection_thumbnails") and File.exist? Hyku::Application.path_for("public#{::SolrDocument.find(@collection.id).thumbnail_path}") %> <%= image_tag(thumbnail_path, class: "current-thumbnail") %>

    Current image: <%= @thumbnail_filename %>

    <% else %> From b0f2c442c18809c31f4cfe02e995558655dfa2b4 Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Wed, 1 Nov 2023 12:23:11 -0700 Subject: [PATCH 056/126] =?UTF-8?q?=F0=9F=8E=81=20Modify=20labels=20in=20U?= =?UTF-8?q?V=20for=20V3=20manifests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit will add the same treatment as we have for V2 manifests to V3 manifests. This will allow the UV to add a more human readable label to the pages. Ref: - https://github.com/scientist-softserv/adventist-dl/issues/628 --- .../canvas_builder_decorator.rb | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 lib/iiif_manifest/v3/manifest_builder/canvas_builder_decorator.rb diff --git a/lib/iiif_manifest/v3/manifest_builder/canvas_builder_decorator.rb b/lib/iiif_manifest/v3/manifest_builder/canvas_builder_decorator.rb new file mode 100644 index 000000000..990bd1409 --- /dev/null +++ b/lib/iiif_manifest/v3/manifest_builder/canvas_builder_decorator.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +# OVERRIDE IIIFManifest v1.3.1 to use the parent's title as the label instead of the filename + +module IIIFManifest + module V3 + module ManifestBuilderDecorator + module CanvasBuilderDecorator + def apply_record_properties + super + canvas.label = if record.to_s.present? + ManifestBuilder.language_map(record['parent_title_tesim']&.first || record.to_s) + end + end + end + end + end +end + +IIIFManifest::V3::ManifestBuilder.prepend(IIIFManifest::V3::ManifestBuilderDecorator) +IIIFManifest::V3::ManifestBuilder::CanvasBuilder.prepend(IIIFManifest::V3::ManifestBuilder::CanvasBuilderDecorator) From 7add38e9b4d8087b878714b0aa0439a1e3b23f73 Mon Sep 17 00:00:00 2001 From: Jeremy Friesen Date: Mon, 27 Nov 2023 15:46:41 -0500 Subject: [PATCH 057/126] =?UTF-8?q?=F0=9F=90=9B=20Fix=20bad=20method=20nam?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Related to: - https://github.com/samvera/hyku/pull/2023/files - https://github.com/scientist-softserv/atla-hyku/pull/198 --- app/controllers/hyrax/my/works_controller_decorator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/hyrax/my/works_controller_decorator.rb b/app/controllers/hyrax/my/works_controller_decorator.rb index 2817729e9..df68ce1ca 100644 --- a/app/controllers/hyrax/my/works_controller_decorator.rb +++ b/app/controllers/hyrax/my/works_controller_decorator.rb @@ -6,7 +6,7 @@ module Hyrax module My module WorksControllerDecorator - def collection_service + def collections_service cloned = clone cloned.params = {} Hyrax::CollectionsService.new(cloned) From dbe996e71afa63a5ba8f68f55e4c50ed25d3729d Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Wed, 29 Nov 2023 13:36:24 -0800 Subject: [PATCH 058/126] =?UTF-8?q?=F0=9F=90=9B=20Move=20some=20methods=20?= =?UTF-8?q?to=20be=20public?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit will move #solr_document, #current_ability, and #request to be public methods. Since these methods in Hyrax were not private, in the decorator it should not be private either. Ref: - https://github.com/samvera/hyrax/blob/b334e186e77691d7da8ed59ff27f091be1c2a700/app/presenters/hyrax/file_set_presenter.rb#L10 --- .../iiif_av/displays_content_decorator.rb | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/app/presenters/concerns/hyrax/iiif_av/displays_content_decorator.rb b/app/presenters/concerns/hyrax/iiif_av/displays_content_decorator.rb index 8348c245f..6260e456a 100644 --- a/app/presenters/concerns/hyrax/iiif_av/displays_content_decorator.rb +++ b/app/presenters/concerns/hyrax/iiif_av/displays_content_decorator.rb @@ -8,21 +8,21 @@ module IiifAv # request.base_url => hostname # also to remove #auth_service since it was not working for now module DisplaysContentDecorator - private + def solr_document + defined?(super) ? super : object + end - def solr_document - defined?(super) ? super : object - end + def current_ability + defined?(super) ? super : @ability + end - def current_ability - defined?(super) ? super : @ability - end + def request + Request.new(base_url: hostname) + end - Request = Struct.new(:base_url, keyword_init: true) + private - def request - Request.new(base_url: hostname) - end + Request = Struct.new(:base_url, keyword_init: true) def image_content return nil unless latest_file_id From da162d4d10864de607c43946b16af2e1a754af6e Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Mon, 11 Dec 2023 14:52:50 -0800 Subject: [PATCH 059/126] First attempt for upgrade to Hyrax 5.0.0.rc2 So far the changes throw an error `The adapter `nulldb_adapter` is not yet supported` when doing a `docker compose build`. Commenting out `RUN RAILS_ENV=production SECRET_KEY_BASE=`bin/rake secret` DB_ADAPTER=nulldb DB_URL='postgresql://fake' bundle exec rake assets:precompile && yarn install` in the Dockerfile allows the build to complete but still can't boot yet. --- Dockerfile | 3 +- Gemfile | 23 +- Gemfile.lock | 1142 +++++++++++++++++----------------- config/application.rb | 6 + config/initializers/riiif.rb | 2 +- 5 files changed, 601 insertions(+), 575 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8916c378e..da22d3d7c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,4 @@ -ARG HYRAX_IMAGE_VERSION=hyrax-v4.0.0.rc1 -ARG RUBY_VERSION=2.7.7 +ARG HYRAX_IMAGE_VERSION=hyrax-v5.0.0.rc2 FROM ghcr.io/samvera/hyrax/hyrax-base:$HYRAX_IMAGE_VERSION as hyku-base USER root diff --git a/Gemfile b/Gemfile index 3fd4a6453..f09b9adc8 100644 --- a/Gemfile +++ b/Gemfile @@ -4,16 +4,16 @@ source 'https://rubygems.org' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '~> 5.2.5' +gem 'rails', '~> 6.0' -gem 'active-fedora', '>= 11.1.4' +gem 'active-fedora', '~> 14.0' gem 'active_elastic_job', github: 'active-elastic-job/active-elastic-job', ref: 'ec51c5d9dedc4a1b47f2db41f26d5fceb251e979', group: %i[aws] gem 'activerecord-nulldb-adapter' gem 'addressable', '2.8.1' # remove once https://github.com/postrank-labs/postrank-uri/issues/49 is fixed gem 'apartment' gem 'aws-sdk-sqs', group: %i[aws] -gem 'blacklight', '~> 6.7' -gem 'blacklight_oai_provider', '~> 6.1', '>= 6.1.1' +gem 'blacklight', '~> 7.29' +gem 'blacklight_oai_provider', '~> 7.0' gem 'bolognese', '>= 1.9.10' gem 'bootstrap-datepicker-rails' gem 'bulkrax', '~> 5.3' @@ -29,15 +29,14 @@ gem 'devise' gem 'devise-guests', '~> 0.3' gem 'devise-i18n' gem 'devise_invitable', '~> 1.6' -gem 'dry-monads', '~> 1.4.0' # Locked because 1.5.0 was not compatible with Hyrax v.3.4.2 +gem 'dry-monads', '~> 1.5' gem 'easy_translate', group: %i[development] gem 'factory_bot_rails', group: %i[test] gem 'fcrepo_wrapper', '~> 0.4', group: %i[development test] -gem 'flipflop', '~> 2.6.0' # waiting for hyrax 4 upgrade gem 'flutie' -gem 'hyrax', '~> 3.5.0' -gem 'hyrax-doi', github: 'samvera-labs/hyrax-doi', branch: 'main' -gem 'hyrax-iiif_av', github: 'samvera-labs/hyrax-iiif_av', branch: 'main' +gem 'hyrax', github: 'samvera/hyrax', tag: 'hyrax-v5.0.0.rc2' +gem 'hyrax-doi', github: 'samvera-labs/hyrax-doi', branch: 'rails_hyrax_upgrade' +gem 'hyrax-iiif_av', github: 'samvera-labs/hyrax-iiif_av', branch: 'rails_hyrax_upgrade' gem 'i18n-debug', require: false, group: %i[development test] gem 'i18n-tasks', group: %i[development test] gem 'iiif_print', github: 'scientist-softserv/iiif_print', branch: 'main' @@ -63,9 +62,9 @@ gem 'pry-byebug', group: %i[development test] gem 'puma', '~> 5.6' # Use Puma as the app server gem 'rack-test', '0.7.0', group: %i[test] # rack-test >= 0.71 does not work with older Capybara versions (< 2.17). See #214 for more details gem 'rails-controller-testing', group: %i[test] -gem 'rdf', '~> 3.1.15' # rdf 3.2.0 removed SerializedTransaction which ldp requires +gem 'rdf', '~> 3.2' gem 'redlock', '>= 0.1.2', '< 2.0' # lock redlock per https://github.com/samvera/hyrax/pull/5961 -gem 'riiif', '~> 1.1' +gem 'riiif', '~> 2.0' gem 'rolify' gem 'rsolr', '~> 2.0' gem 'rspec', group: %i[development test] @@ -76,7 +75,7 @@ gem 'rspec-retry', group: %i[test] gem 'rspec_junit_formatter', group: %i[test] gem 'rubocop', '~> 0.50', '<= 0.52.1', group: %i[development test] gem 'rubocop-rspec', '~> 1.22', '<= 1.22.2', group: %i[development test] -gem 'sass-rails', '~> 5.0' # Use SCSS for stylesheets +gem 'sass-rails', '~> 6.0' # Use SCSS for stylesheets gem 'scss_lint', require: false, group: %i[development] gem 'secure_headers' gem 'selenium-webdriver', '4.8.1', group: %i[test] diff --git a/Gemfile.lock b/Gemfile.lock index 651139ee2..fc61e6b27 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -9,47 +9,106 @@ GIT GIT remote: https://github.com/samvera-labs/hyku_knapsack.git - revision: 446f16b928f7f12125fdaaf6feb08dcdacf1bd38 + revision: 14f688b61afab9ee886f5f7fa26a76a37bced597 branch: upstream_main specs: hyku_knapsack (0.0.1) rails (>= 5.2.0) - sentry-raven GIT remote: https://github.com/samvera-labs/hyrax-doi.git - revision: d494a50ef8ce3eae594c7ed7148c33b3c977d4a7 - branch: main + revision: 9b7ab7f8054a14385b838de1118f55ad2e0f5da8 + branch: rails_hyrax_upgrade specs: hyrax-doi (0.2.0) - bolognese (~> 1.8, >= 1.8.6) + bolognese (>= 1.8.6, < 2.0) flipflop (~> 2.3) - hyrax (>= 2.9, < 4.0) - rails (~> 5.2.4, >= 5.2.4.3) + hyrax (>= 2.9, < 6.0) + rails (>= 5.2.4.3, < 8.0) GIT remote: https://github.com/samvera-labs/hyrax-iiif_av.git - revision: 6273f90016c153d2add33f85cc24285d51a25382 - branch: main + revision: 4bc4af3ebbc47b68a313108c72c319945c673c1b + branch: rails_hyrax_upgrade specs: hyrax-iiif_av (0.2.0) blacklight - hyrax (>= 2.9, < 4.0) + hyrax (>= 3.5, < 6.0) iiif_manifest (> 0.5) - rails (~> 5.1) + rails (>= 5.1, < 8.0) + +GIT + remote: https://github.com/samvera/hyrax.git + revision: 3dd81340fc2586132772fa4017946ed4c60adb8a + tag: hyrax-v5.0.0.rc2 + specs: + hyrax (5.0.0.rc2) + active-fedora (~> 14.0) + almond-rails (~> 0.1) + awesome_nested_set (~> 3.1) + blacklight (~> 7.29) + blacklight-gallery (~> 4.0) + breadcrumbs_on_rails (~> 3.0) + browse-everything (>= 0.16, < 2.0) + carrierwave (~> 1.0) + clipboard-rails (~> 1.5) + concurrent-ruby (~> 1.0) + connection_pool (~> 2.4) + draper (~> 4.0) + dry-container (~> 0.11) + dry-events (~> 1.0, >= 1.0.1) + dry-logic (~> 1.5) + dry-monads (~> 1.6) + dry-struct (~> 1.6) + dry-validation (~> 1.10) + flipflop (~> 2.3) + flot-rails (~> 0.0.6) + font-awesome-rails (~> 4.2) + hydra-derivatives (~> 3.3) + hydra-editor (~> 6.0) + hydra-file_characterization (~> 1.1) + hydra-head (~> 12.0) + hydra-works (>= 0.16) + iiif_manifest (>= 0.3, < 2.0) + json-schema + legato (~> 0.3) + linkeddata + mailboxer (~> 0.12) + nest (~> 3.1) + noid-rails (~> 3.0) + oauth + oauth2 (~> 1.2) + openseadragon + posix-spawn + qa (~> 5.5, >= 5.5.1) + rails (~> 6.1) + rails_autolink (~> 1.1) + rdf-rdfxml + rdf-vocab (~> 3.0) + redis (~> 4.0) + redis-namespace (~> 1.5) + redlock (>= 0.1.2, < 2.0) + reform (~> 2.3) + reform-rails (~> 0.2.0) + retriable (>= 2.9, < 4.0) + sass-rails (~> 6.0) + select2-rails (~> 3.5) + signet + sprockets (~> 3.7) + tinymce-rails (~> 5.10) + valkyrie (~> 3.1.1) + view_component (~> 2.74.1) GIT remote: https://github.com/scientist-softserv/iiif_print.git - revision: 9e7837ce4bd08bf8fff9126455d0e0e2602f6018 + revision: e476998ab453afabf1bcb8afa059b4416af9b705 branch: main specs: iiif_print (1.0.0) - blacklight_iiif_search (~> 1.0) + blacklight_iiif_search (>= 1.0, < 3.0) derivative-rodeo (~> 0.5) - dry-monads (~> 1.4.0) - hyrax (>= 2.5, < 4) + hyrax (>= 2.5, < 6) nokogiri (>= 1.13.2) - rails (~> 5.0) rdf-vocab (~> 3.0) GIT @@ -65,35 +124,50 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (5.2.8.1) - actionpack (= 5.2.8.1) + actioncable (6.1.7.6) + actionpack (= 6.1.7.6) + activesupport (= 6.1.7.6) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailer (5.2.8.1) - actionpack (= 5.2.8.1) - actionview (= 5.2.8.1) - activejob (= 5.2.8.1) + actionmailbox (6.1.7.6) + actionpack (= 6.1.7.6) + activejob (= 6.1.7.6) + activerecord (= 6.1.7.6) + activestorage (= 6.1.7.6) + activesupport (= 6.1.7.6) + mail (>= 2.7.1) + actionmailer (6.1.7.6) + actionpack (= 6.1.7.6) + actionview (= 6.1.7.6) + activejob (= 6.1.7.6) + activesupport (= 6.1.7.6) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (5.2.8.1) - actionview (= 5.2.8.1) - activesupport (= 5.2.8.1) - rack (~> 2.0, >= 2.0.8) + actionpack (6.1.7.6) + actionview (= 6.1.7.6) + activesupport (= 6.1.7.6) + rack (~> 2.0, >= 2.0.9) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (5.2.8.1) - activesupport (= 5.2.8.1) + rails-html-sanitizer (~> 1.0, >= 1.2.0) + actiontext (6.1.7.6) + actionpack (= 6.1.7.6) + activerecord (= 6.1.7.6) + activestorage (= 6.1.7.6) + activesupport (= 6.1.7.6) + nokogiri (>= 1.8.5) + actionview (6.1.7.6) + activesupport (= 6.1.7.6) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.0.3) - active-fedora (13.3.0) + rails-html-sanitizer (~> 1.1, >= 1.2.0) + active-fedora (14.0.1) active-triples (>= 0.11.0, < 2.0.0) activemodel (>= 5.1) activesupport (>= 5.1) deprecation - faraday (~> 0.12) + faraday (>= 1.0) faraday-encoding (>= 0.0.5) ldp (>= 0.7.0, < 2) rsolr (>= 1.1.2, < 3) @@ -106,68 +180,65 @@ GEM active_encode (0.8.2) rails sprockets (< 4) - activejob (5.2.8.1) - activesupport (= 5.2.8.1) + activejob (6.1.7.6) + activesupport (= 6.1.7.6) globalid (>= 0.3.6) - activemodel (5.2.8.1) - activesupport (= 5.2.8.1) + activemodel (6.1.7.6) + activesupport (= 6.1.7.6) activemodel-serializers-xml (1.0.2) activemodel (> 5.x) activesupport (> 5.x) builder (~> 3.1) - activerecord (5.2.8.1) - activemodel (= 5.2.8.1) - activesupport (= 5.2.8.1) - arel (>= 9.0) - activerecord-import (1.4.1) + activerecord (6.1.7.6) + activemodel (= 6.1.7.6) + activesupport (= 6.1.7.6) + activerecord-import (1.5.1) activerecord (>= 4.2) - activerecord-nulldb-adapter (0.9.0) - activerecord (>= 5.2.0, < 7.1) - activestorage (5.2.8.1) - actionpack (= 5.2.8.1) - activerecord (= 5.2.8.1) - marcel (~> 1.0.0) - activesupport (5.2.8.1) + activerecord-nulldb-adapter (1.0.1) + activerecord (>= 5.2.0, < 7.2) + activestorage (6.1.7.6) + actionpack (= 6.1.7.6) + activejob (= 6.1.7.6) + activerecord (= 6.1.7.6) + activesupport (= 6.1.7.6) + marcel (~> 1.0) + mini_mime (>= 1.1.0) + activesupport (6.1.7.6) concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (>= 0.7, < 2) - minitest (~> 5.1) - tzinfo (~> 1.1) + i18n (>= 1.6, < 2) + minitest (>= 5.1) + tzinfo (~> 2.0) + zeitwerk (~> 2.3) addressable (2.8.1) public_suffix (>= 2.0.2, < 6.0) aes_key_wrap (1.1.0) almond-rails (0.3.0) rails (>= 4.2) - amazing_print (1.4.0) - apartment (2.2.1) - activerecord (>= 3.1.2, < 6.0) - parallel (>= 0.7.1) - public_suffix (>= 2) + apartment (0.24.3) + activerecord (>= 3.1.2) rack (>= 1.3.6) - arel (9.0.0) ast (2.4.2) attr_required (1.0.1) - autoprefixer-rails (10.4.13.0) - execjs (~> 2) - awesome_nested_set (3.5.0) - activerecord (>= 4.0.0, < 7.1) - aws-eventstream (1.2.0) - aws-partitions (1.785.0) - aws-sdk-core (3.178.0) - aws-eventstream (~> 1, >= 1.0.2) + awesome_nested_set (3.6.0) + activerecord (>= 4.0.0, < 7.2) + aws-eventstream (1.3.0) + aws-partitions (1.864.0) + aws-sdk-core (3.190.0) + aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) - aws-sigv4 (~> 1.5) + aws-sigv4 (~> 1.8) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.64.0) - aws-sdk-core (~> 3, >= 3.165.0) + aws-sdk-kms (1.74.0) + aws-sdk-core (~> 3, >= 3.188.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.121.0) - aws-sdk-core (~> 3, >= 3.165.0) + aws-sdk-s3 (1.141.0) + aws-sdk-core (~> 3, >= 3.189.0) aws-sdk-kms (~> 1) - aws-sigv4 (~> 1.4) - aws-sdk-sqs (1.61.0) - aws-sdk-core (~> 3, >= 3.177.0) + aws-sigv4 (~> 1.8) + aws-sdk-sqs (1.69.0) + aws-sdk-core (~> 3, >= 3.188.0) aws-sigv4 (~> 1.1) - aws-sigv4 (1.6.0) + aws-sigv4 (1.8.0) aws-eventstream (~> 1, >= 1.0.2) babel-source (5.8.35) babel-transpiler (0.7.0) @@ -176,49 +247,50 @@ GEM bagit (0.4.6) docopt (~> 0.5.0) validatable (~> 1.6) + base64 (0.2.0) bcp47 (0.3.3) i18n - bcrypt (3.1.18) + bcp47_spec (0.2.1) + bcrypt (3.1.20) benchmark_methods (0.7) - better_html (1.0.16) - actionview (>= 4.0) - activesupport (>= 4.0) + better_html (2.0.2) + actionview (>= 6.0) + activesupport (>= 6.0) ast (~> 2.0) erubi (~> 1.4) - html_tokenizer (~> 0.0.6) parser (>= 2.4) smart_properties bibtex-ruby (6.0.0) latex-decode (~> 0.0) + bigdecimal (3.1.4) bindata (2.4.15) bindex (0.8.1) - blacklight (6.25.0) - bootstrap-sass (~> 3.2) + blacklight (7.35.0) deprecation globalid + hashdiff + i18n (>= 1.7.0) jbuilder (~> 2.7) kaminari (>= 0.15) - nokogiri (~> 1.6) - rails (>= 4.2, < 6) - rsolr (>= 1.0.6, < 3) - twitter-typeahead-rails (= 0.11.1.pre.corejavascript) - blacklight-access_controls (0.6.2) - blacklight (~> 6.0) - cancancan (~> 1.8) + ostruct (>= 0.3.2) + rails (>= 5.1, < 7.2) + view_component (>= 2.66, < 4) + blacklight-access_controls (6.0.1) + blacklight (> 6.0, < 8) + cancancan (>= 1.8) deprecation (~> 1.0) - blacklight-gallery (0.12.0) - blacklight (~> 6.3) - bootstrap-sass (~> 3.0) - openseadragon (>= 0.2.0) - rails - blacklight_iiif_search (1.0.0) - blacklight (~> 6.0) + blacklight-gallery (4.4.0) + blacklight (>= 7.17, < 9) + rails (>= 6.1, < 8) + blacklight_iiif_search (2.0.0) + blacklight (~> 7.0) iiif-presentation - rails (>= 4.2, < 6) - blacklight_oai_provider (6.1.1) - blacklight (~> 6.0) - oai (~> 1.0) - bolognese (1.11.0) + rails (>= 5.1, < 7) + blacklight_oai_provider (7.0.2) + blacklight (~> 7.0) + oai (~> 1.2) + rexml + bolognese (1.11.5) activesupport (>= 4.2.5) benchmark_methods (~> 0.7) bibtex-ruby (>= 5.1.0) @@ -242,27 +314,23 @@ GEM rdf-rdfxml (~> 3.1) rdf-turtle (~> 3.1) thor (>= 0.19) - bootstrap-datepicker-rails (1.9.0.1) + bootstrap-datepicker-rails (1.10.0.1) railties (>= 3.0) - bootstrap-sass (3.4.1) - autoprefixer-rails (>= 5.2.1) - sassc (>= 2.0.0) breadcrumbs_on_rails (3.0.1) - browse-everything (1.2.0) + browse-everything (1.3.0) addressable (~> 2.5) aws-sdk-s3 dropbox_api (>= 0.1.20) google-apis-drive_v3 googleauth (>= 0.6.6, < 2.0) - rails (>= 4.2, < 7.1) + rails (>= 4.2, < 7.2) ruby-box signet (~> 0.8) typhoeus builder (3.2.4) - bulkrax (5.4.0) + bulkrax (5.5.0) bagit (~> 0.4) coderay - dry-monads (~> 1.4.0) iso8601 (~> 0.9.0) kaminari language_list (~> 1.2, >= 1.2.1) @@ -275,8 +343,8 @@ GEM rubyzip simple_form byebug (11.1.3) - cancancan (1.17.0) - capybara (3.39.0) + cancancan (3.5.0) + capybara (3.39.2) addressable matrix mini_mime (>= 0.1.3) @@ -288,7 +356,7 @@ GEM capybara-screenshot (1.0.26) capybara (>= 1.0, < 4) launchy - carrierwave (1.3.3) + carrierwave (1.3.4) activemodel (>= 4.0.0) activesupport (>= 4.0.0) mime-types (>= 1.16) @@ -303,8 +371,7 @@ GEM csl (~> 1.6) clipboard-rails (1.7.1) cocoon (1.2.15) - codemirror-rails (5.16.0) - railties (>= 3.0, < 6.0) + codemirror-rails (0.3.1) coderay (1.1.3) coffee-rails (4.2.2) coffee-script (>= 2.2.0) @@ -315,7 +382,7 @@ GEM coffee-script-source (1.12.2) colorize (0.8.1) concurrent-ruby (1.2.2) - connection_pool (2.4.0) + connection_pool (2.4.1) crack (0.4.5) rexml crass (1.0.6) @@ -330,14 +397,11 @@ GEM activerecord (>= 5.a) database_cleaner-core (~> 2.0.0) database_cleaner-core (2.0.1) - date (3.3.3) + date (3.3.4) declarative (0.0.20) - declarative-builder (0.1.0) - declarative-option (< 0.2.0) - declarative-option (0.1.0) deprecation (1.1.0) activesupport - derivative-rodeo (0.5.0) + derivative-rodeo (0.5.3) activesupport (>= 5) aws-sdk-s3 aws-sdk-sqs @@ -346,7 +410,7 @@ GEM mime-types mini_magick nokogiri - devise (4.9.2) + devise (4.9.3) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0) @@ -354,18 +418,15 @@ GEM warden (~> 1.2.3) devise-guests (0.8.1) devise - devise-i18n (1.11.0) + devise-i18n (1.12.0) devise (>= 4.9.0) devise_invitable (1.7.5) actionmailer (>= 4.1.0) devise (>= 4.0.0) diff-lcs (1.5.0) - disposable (0.4.7) + disposable (0.6.3) declarative (>= 0.0.9, < 1.0.0) - declarative-builder (< 0.2.0) - declarative-option (< 0.2.0) - representable (>= 2.4.0, <= 3.1.0) - uber (< 0.2.0) + representable (>= 3.1.1, < 4) docile (1.4.0) docopt (0.5.0) draper (4.0.2) @@ -378,97 +439,96 @@ GEM dropbox_api (0.1.21) faraday (< 3.0) oauth2 (~> 1.1) - dry-configurable (0.16.1) - dry-core (~> 0.6) + dry-configurable (1.1.0) + dry-core (~> 1.0, < 2) zeitwerk (~> 2.6) dry-container (0.11.0) concurrent-ruby (~> 1.0) - dry-core (0.9.1) + dry-core (1.0.1) concurrent-ruby (~> 1.0) zeitwerk (~> 2.6) - dry-equalizer (0.3.0) - dry-events (0.2.0) + dry-events (1.0.1) concurrent-ruby (~> 1.0) - dry-core (~> 0.4) - dry-equalizer (~> 0.2) - dry-inflector (0.3.0) + dry-core (~> 1.0, < 2) + dry-inflector (1.0.0) dry-initializer (3.1.1) - dry-logic (1.3.0) + dry-logic (1.5.0) concurrent-ruby (~> 1.0) - dry-core (~> 0.9, >= 0.9) + dry-core (~> 1.0, < 2) zeitwerk (~> 2.6) - dry-matcher (0.9.0) - dry-core (~> 0.4, >= 0.4.8) - dry-monads (1.4.0) + dry-monads (1.6.0) concurrent-ruby (~> 1.0) - dry-core (~> 0.7) - dry-schema (1.11.3) + dry-core (~> 1.0, < 2) + zeitwerk (~> 2.6) + dry-schema (1.13.3) concurrent-ruby (~> 1.0) - dry-configurable (~> 0.16, >= 0.16) - dry-core (~> 0.9, >= 0.9) + dry-configurable (~> 1.0, >= 1.0.1) + dry-core (~> 1.0, < 2) dry-initializer (~> 3.0) - dry-logic (~> 1.3) - dry-types (~> 1.6) + dry-logic (>= 1.4, < 2) + dry-types (>= 1.7, < 2) zeitwerk (~> 2.6) - dry-struct (1.5.2) - dry-core (~> 0.9, >= 0.9) - dry-types (~> 1.6) + dry-struct (1.6.0) + dry-core (~> 1.0, < 2) + dry-types (>= 1.7, < 2) ice_nine (~> 0.11) zeitwerk (~> 2.6) - dry-transaction (0.13.3) - dry-container (>= 0.2.8) - dry-events (>= 0.1.0) - dry-matcher (>= 0.7.0) - dry-monads (>= 0.4.0) - dry-types (1.6.1) + dry-types (1.7.1) concurrent-ruby (~> 1.0) - dry-container (~> 0.3) - dry-core (~> 0.9, >= 0.9) - dry-inflector (~> 0.1, >= 0.1.2) - dry-logic (~> 1.3, >= 1.3) + dry-core (~> 1.0) + dry-inflector (~> 1.0) + dry-logic (~> 1.4) zeitwerk (~> 2.6) - dry-validation (1.9.0) + dry-validation (1.10.0) concurrent-ruby (~> 1.0) - dry-container (~> 0.7, >= 0.7.1) - dry-core (~> 0.9, >= 0.9) + dry-core (~> 1.0, < 2) dry-initializer (~> 3.0) - dry-schema (~> 1.11, >= 1.11.0) + dry-schema (>= 1.12, < 2) zeitwerk (~> 2.6) easy_translate (0.5.1) thread thread_safe - ebnf (2.2.1) - amazing_print (~> 1.2) + ebnf (2.4.0) htmlentities (~> 4.3) - rdf (~> 3.1) + rdf (~> 3.3) scanf (~> 1.0) - sxp (~> 1.1) - unicode-types (~> 1.6) + sxp (~> 1.3) + unicode-types (~> 1.8) edtf (3.1.1) activesupport (>= 3.0, < 8.0) - equivalent-xml (0.6.0) - nokogiri (>= 1.4.3) erubi (1.12.0) ethon (0.16.0) ffi (>= 1.15.0) excon (0.71.1) - execjs (2.8.1) - factory_bot (6.2.1) + execjs (2.9.1) + factory_bot (6.4.2) activesupport (>= 5.0.0) - factory_bot_rails (6.2.0) - factory_bot (~> 6.2.0) + factory_bot_rails (6.4.2) + factory_bot (~> 6.4) railties (>= 5.0.0) - faraday (0.17.6) - multipart-post (>= 1.2, < 3) + faraday (2.7.12) + base64 + faraday-net_http (>= 2.0, < 3.1) + ruby2_keywords (>= 0.0.4) faraday-encoding (0.0.5) faraday - faraday_middleware (0.14.0) - faraday (>= 0.7.4, < 1.0) + faraday-excon (2.1.0) + excon (>= 0.27.4) + faraday (~> 2.0) + faraday-follow_redirects (0.3.0) + faraday (>= 1, < 3) + faraday-gzip (0.1.0) + faraday (>= 1.0) + zlib (~> 2.1) + faraday-multipart (1.0.4) + multipart-post (~> 2) + faraday-net_http (3.0.2) fcrepo_wrapper (0.9.0) ruby-progressbar - ffi (1.15.5) - flipflop (2.6.0) + ffi (1.16.3) + flipflop (2.7.1) activesupport (>= 4.0) + terminal-table (>= 1.8) flot-rails (0.0.7) jquery-rails flutie (2.2.0) @@ -476,10 +536,11 @@ GEM railties (>= 3.2, < 8.0) gender_detector (0.1.2) unicode_utils (>= 1.3.0) - geocoder (1.8.1) - globalid (1.1.0) - activesupport (>= 5.0) - google-apis-core (0.11.0) + geo_coord (0.2.0) + geocoder (1.8.2) + globalid (1.2.1) + activesupport (>= 6.1) + google-apis-core (0.11.2) addressable (~> 2.5, >= 2.5.1) googleauth (>= 0.16.2, < 2.a) httpclient (>= 2.8.1, < 3.a) @@ -488,17 +549,20 @@ GEM retriable (>= 2.0, < 4.a) rexml webrick - google-apis-drive_v3 (0.39.0) + google-apis-drive_v3 (0.46.0) google-apis-core (>= 0.11.0, < 2.a) - googleauth (1.5.2) - faraday (>= 0.17.3, < 3.a) + google-cloud-env (2.0.1) + faraday (>= 1.0, < 3.a) + googleauth (1.9.0) + faraday (>= 1.0, < 3.a) + google-cloud-env (~> 2.0, >= 2.0.1) jwt (>= 1.4, < 3.0) - memoist (~> 0.16) multi_json (~> 1.11) os (>= 0.9, < 2.0) signet (>= 0.16, < 2.a) - haml (5.2.2) - temple (>= 0.8.0) + haml (6.3.0) + temple (>= 0.8.2) + thor tilt hamster (3.0.0) concurrent-ruby (~> 1.0) @@ -506,46 +570,46 @@ GEM hashie (5.0.0) highline (2.1.0) hiredis (0.6.3) - html_tokenizer (0.0.7) htmlentities (4.3.4) http_logger (0.7.0) httparty (0.21.0) mini_mime (>= 1.0.0) multi_xml (>= 0.5.2) httpclient (2.8.3) - hydra-access-controls (11.0.7) + hydra-access-controls (12.1.0) active-fedora (>= 10.0.0) - activesupport (>= 4, < 6) - blacklight (>= 5.16) - blacklight-access_controls (~> 0.6.0) - cancancan (~> 1.8) + activesupport (>= 5.2, < 7.1) + blacklight-access_controls (~> 6.0) + cancancan (>= 1.8, < 4) deprecation (~> 1.0) - hydra-core (11.0.7) - hydra-access-controls (= 11.0.7) - railties (>= 4.0.0, < 6) - hydra-derivatives (3.7.0) - active-fedora (>= 11.5.6, != 13.2.1, != 13.2.0, != 13.1.3, != 13.1.2, != 13.1.1, != 13.1.0, != 13.0.0, != 12.2.1, != 12.2.0, != 12.1.1, != 12.1.0, != 12.0.3, != 12.0.2, != 12.0.1, != 12.0.0) + hydra-core (12.1.0) + hydra-access-controls (= 12.1.0) + railties (>= 5.2, < 7.1) + hydra-derivatives (3.8.0) + active-fedora (>= 14.0) + active-triples (>= 1.2) active_encode (~> 0.1) - activesupport (>= 4.0, < 7) + activesupport (>= 4.0, < 7.1) addressable (~> 2.5) deprecation mime-types (> 2.0, < 4.0) mini_magick (>= 3.2, < 5) - hydra-editor (5.0.5) + hydra-editor (6.2.0) active-fedora (>= 9.0.0) - activerecord (~> 5.0) + activerecord (>= 5.2, < 7.1) almond-rails (~> 0.1) - cancancan (~> 1.8) - rails (>= 5, < 6) - simple_form (>= 4.1.0, < 6.0) - sprockets (~> 3.7) + cancancan + psych (~> 3.3, < 4) + rails (>= 5.2, < 7.1) + simple_form (>= 4.1.0, < 5.2) + sprockets (>= 3.7) sprockets-es6 - hydra-file_characterization (1.1.2) + hydra-file_characterization (1.2.0) activesupport (>= 3.0.0) - hydra-head (11.0.7) - hydra-access-controls (= 11.0.7) - hydra-core (= 11.0.7) - rails (>= 5.2, < 6.1) + hydra-head (12.1.0) + hydra-access-controls (= 12.1.0) + hydra-core (= 12.1.0) + rails (>= 5.2, < 7.1) hydra-pcdm (1.3.0) active-fedora (>= 10, < 15) mime-types (>= 1) @@ -555,64 +619,6 @@ GEM hydra-derivatives (~> 3.6) hydra-file_characterization (~> 1.0) hydra-pcdm (>= 0.9) - hyrax (3.5.0) - active-fedora (~> 13.1, >= 13.1.2) - almond-rails (~> 0.1) - awesome_nested_set (~> 3.1) - blacklight (~> 6.14) - blacklight-gallery (~> 0.7) - breadcrumbs_on_rails (~> 3.0) - browse-everything (>= 0.16, < 2.0) - carrierwave (~> 1.0) - clipboard-rails (~> 1.5) - draper (~> 4.0) - dry-equalizer (~> 0.2) - dry-events (~> 0.2.0) - dry-monads (< 1.5) - dry-struct (~> 1.0) - dry-transaction (~> 0.11) - dry-validation (~> 1.3) - flipflop (~> 2.3) - flot-rails (~> 0.0.6) - font-awesome-rails (~> 4.2) - hydra-derivatives (~> 3.3) - hydra-editor (~> 5.0, >= 5.0.4) - hydra-file_characterization (~> 1.1.2) - hydra-head (~> 11.0, >= 11.0.1) - hydra-works (>= 0.16) - iiif_manifest (>= 0.3, < 2.0) - jquery-datatables-rails (~> 3.4) - jquery-ui-rails (~> 6.0) - json-ld (< 3.2) - json-schema - kaminari_route_prefix (~> 0.1.1) - legato (~> 0.3) - linkeddata - mailboxer (~> 0.12) - nest (~> 3.1) - noid-rails (~> 3.0.0) - oauth - oauth2 (~> 1.2) - posix-spawn - power_converter (~> 0.1, >= 0.1.2) - psych (~> 3.3) - qa (~> 5.5, >= 5.5.1) - rails (~> 5.0) - rails_autolink (~> 1.1) - rdf-rdfxml - rdf-vocab (~> 3.0) - redis (~> 4.0) - redis-namespace (~> 1.5) - redlock (>= 0.1.2) - reform (~> 2.3) - reform-rails (~> 0.2.0) - retriable (>= 2.9, < 4.0) - samvera-nesting_indexer (~> 2.0) - sass-rails (~> 5.0) - select2-rails (~> 3.5) - signet - tinymce-rails (~> 5.10) - valkyrie (~> 2, >= 2.1.1) i18n (1.14.1) concurrent-ruby (~> 1.0) i18n-debug (1.2.0) @@ -629,9 +635,12 @@ GEM rainbow (>= 2.2.2, < 4.0) terminal-table (>= 1.5.1) ice_nine (0.11.2) - iiif-presentation (1.1.0) + iiif-image-api (0.2.0) + activesupport + iiif-presentation (1.3.0) activesupport (>= 3.2.18) - faraday (>= 0.9) + faraday (~> 2.7) + geo_coord json iiif_manifest (1.3.1) activesupport (>= 4) @@ -641,40 +650,34 @@ GEM actionview (>= 5.0.0) activesupport (>= 5.0.0) jmespath (1.6.2) - jquery-datatables-rails (3.4.0) - actionpack (>= 3.1) - jquery-rails - railties (>= 3.1) - sass-rails - jquery-rails (4.5.1) + jquery-rails (4.6.0) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) - jquery-ui-rails (6.0.1) - railties (>= 3.2.16) - json (2.6.3) + json (2.7.1) json-canonicalization (0.3.1) - json-jwt (1.15.3) + json-jwt (1.16.3) activesupport (>= 4.2) aes_key_wrap bindata - httpclient - json-ld (3.1.10) + faraday (~> 2.0) + faraday-follow_redirects + json-ld (3.2.4) htmlentities (~> 4.3) - json-canonicalization (~> 0.2) + json-canonicalization (~> 0.3) link_header (~> 0.0, >= 0.0.8) - multi_json (~> 1.14) - rack (~> 2.0) - rdf (~> 3.1) - json-ld-preloaded (3.1.6) - json-ld (~> 3.1) - rdf (~> 3.1) - json-schema (4.0.0) + multi_json (~> 1.15) + rack (>= 2.2, < 4) + rdf (~> 3.2, >= 3.2.10) + json-ld-preloaded (3.2.2) + json-ld (~> 3.2) + rdf (~> 3.2) + json-schema (4.1.1) addressable (>= 2.8) jsonlint (0.3.0) oj (~> 3) optimist (~> 3) - jwt (2.7.0) + jwt (2.7.1) kaminari (1.2.2) activesupport (>= 4.1.0) kaminari-actionview (= 1.2.2) @@ -687,25 +690,24 @@ GEM activerecord kaminari-core (= 1.2.2) kaminari-core (1.2.2) - kaminari_route_prefix (0.1.1) - kaminari (~> 1.0) language_list (1.2.1) latex-decode (0.4.0) launchy (2.5.2) addressable (~> 2.8) - ld-patch (3.1.3) - ebnf (~> 2.1) - rdf (~> 3.1) - rdf-xsd (~> 3.1) - sparql (~> 3.1) - sxp (~> 1.1) - ldp (1.0.3) + ld-patch (3.3.0) + ebnf (~> 2.4) + rdf (~> 3.3) + rdf-xsd (~> 3.3) + sparql (~> 3.3) + sxp (~> 1.3) + ldp (1.2.0) deprecation - faraday + faraday (>= 1) http_logger - json-ld - rdf (>= 1.1) + json-ld (~> 3.2) + rdf (~> 3.2) rdf-isomorphic + rdf-ldp rdf-turtle rdf-vocab (>= 0.8) slop @@ -718,44 +720,44 @@ GEM multi_json libxml-ruby (3.2.4) link_header (0.0.8) - linkeddata (3.1.6) - equivalent-xml (~> 0.6) - json-ld (~> 3.1, >= 3.1.10) - json-ld-preloaded (~> 3.1, >= 3.1.6) - ld-patch (~> 3.1, >= 3.1.3) - nokogiri (~> 1.12) - rdf (~> 3.1, >= 3.1.15) - rdf-aggregate-repo (~> 3.1) - rdf-isomorphic (~> 3.1, >= 3.1.1) - rdf-json (~> 3.1) - rdf-microdata (~> 3.1, >= 3.1.4) - rdf-n3 (~> 3.1, >= 3.1.2) - rdf-normalize (~> 0.4) - rdf-ordered-repo (~> 3.1, >= 3.1.1) - rdf-rdfa (~> 3.1, >= 3.1.3) - rdf-rdfxml (~> 3.1, >= 3.1.1) - rdf-reasoner (~> 0.7, >= 0.7.2) - rdf-tabular (~> 3.1, >= 3.1.1) - rdf-trig (~> 3.1, >= 3.1.2) - rdf-trix (~> 3.1, >= 3.1.1) - rdf-turtle (~> 3.1, >= 3.1.3) - rdf-vocab (~> 3.1, >= 3.1.14) - rdf-xsd (~> 3.1, >= 3.1.1) - shacl (~> 0.1, >= 0.1.1) - shex (~> 0.6, >= 0.6.4) - sparql (~> 3.1, >= 3.1.8) - sparql-client (~> 3.1, >= 3.1.2) - listen (3.1.5) + linkeddata (3.2.1) + json-ld (~> 3.2, >= 3.2.3) + json-ld-preloaded (~> 3.2) + ld-patch (~> 3.2) + nokogiri (~> 1.13, >= 1.13.8) + rdf (~> 3.2, >= 3.2.9) + rdf-aggregate-repo (~> 3.2, >= 3.2.1) + rdf-hamster-repo (~> 3.2) + rdf-isomorphic (~> 3.2, >= 3.2.1) + rdf-json (~> 3.2) + rdf-microdata (~> 3.2, >= 3.2.1) + rdf-n3 (~> 3.2, >= 3.2.1) + rdf-normalize (~> 0.5) + rdf-ordered-repo (~> 3.2, >= 3.2.1) + rdf-rdfa (~> 3.2) + rdf-rdfxml (~> 3.2) + rdf-reasoner (~> 0.8) + rdf-tabular (~> 3.2, >= 3.2.1) + rdf-trig (~> 3.2) + rdf-trix (~> 3.2) + rdf-turtle (~> 3.2, >= 3.2.1) + rdf-vocab (~> 3.2, >= 3.2.1) + rdf-xsd (~> 3.2, >= 3.2.1) + shacl (~> 0.2, >= 0.2.1) + shex (~> 0.7, >= 0.7.1) + sparql (~> 3.2, >= 3.2.4) + sparql-client (~> 3.2, >= 3.2.1) + yaml-ld (~> 0.0) + listen (3.0.8) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) - ruby_dep (~> 1.2) - logger (1.5.3) - lograge (0.12.0) + logger (1.6.0) + lograge (0.14.0) actionpack (>= 4) activesupport (>= 4) railties (>= 4) request_store (~> 1.0) - loofah (2.21.3) + loofah (2.22.0) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.8.1) @@ -767,27 +769,29 @@ GEM carrierwave (>= 0.5.8) rails (>= 5.0.0) marcel (1.0.2) - maremma (4.9.8) + maremma (4.9.9) activesupport (>= 4.2.5) addressable (>= 2.3.6) builder (~> 3.2, >= 3.2.2) excon (~> 0.71.0) - faraday (~> 0.17.3) - faraday-encoding (~> 0.0.4) - faraday_middleware (~> 0.14.0) - nokogiri (>= 1.11.2, < 1.14.0) + faraday (>= 2.0) + faraday-encoding (~> 0.0.5) + faraday-excon (~> 2.1.0) + faraday-follow_redirects (~> 0.3.0) + faraday-gzip (~> 0.1.0) + faraday-multipart (~> 1.0.4) + nokogiri (>= 1.13.1, < 1.14.0) oj (>= 2.8.3) oj_mimic_json (~> 1.0, >= 1.0.1) matrix (0.4.2) - memoist (0.16.2) method_source (1.0.0) - mime-types (3.4.1) + mime-types (3.5.1) mime-types-data (~> 3.2015) - mime-types-data (3.2023.0218.1) + mime-types-data (3.2023.1205) mini_magick (4.12.0) - mini_mime (1.1.2) - mini_portile2 (2.8.4) - minitest (5.18.1) + mini_mime (1.1.5) + mini_portile2 (2.8.5) + minitest (5.20.0) mods (2.4.1) edtf iso-639 @@ -804,19 +808,19 @@ GEM redic net-http-persistent (4.0.2) connection_pool (~> 2.2) - net-imap (0.3.6) + net-imap (0.4.8) date net-protocol net-pop (0.1.2) net-protocol - net-protocol (0.2.1) + net-protocol (0.2.2) timeout - net-smtp (0.3.3) + net-smtp (0.4.0) net-protocol - nio4r (2.5.9) + nio4r (2.7.0) noid (0.9.0) - noid-rails (3.0.3) - actionpack (>= 5.0.0, < 7) + noid-rails (3.1.0) + actionpack (>= 5.0.0, < 7.1) noid (~> 0.9) nokogiri (1.13.10) mini_portile2 (~> 2.8.0) @@ -824,10 +828,10 @@ GEM nom-xml (1.2.0) i18n nokogiri - oai (1.1.0) + oai (1.2.1) builder (>= 3.1.0) - faraday - faraday_middleware + faraday (< 3) + faraday-follow_redirects (>= 0.3.0, < 2) oauth (1.1.0) oauth-tty (~> 1.0, >= 1.0.1) snaky_hash (~> 2.0) @@ -840,9 +844,10 @@ GEM multi_json (~> 1.3) multi_xml (~> 0.5) rack (>= 1.2, < 4) - oj (3.14.3) + oj (3.16.3) + bigdecimal (>= 3.0) oj_mimic_json (1.0.1) - okcomputer (1.18.4) + okcomputer (1.18.5) omniauth (2.1.1) hashie (>= 3.4.6) rack (>= 2.2.3) @@ -855,36 +860,38 @@ GEM omniauth-saml (2.1.0) omniauth (~> 2.0) ruby-saml (~> 1.12) - omniauth_openid_connect (0.6.1) + omniauth_openid_connect (0.7.1) omniauth (>= 1.9, < 3) - openid_connect (~> 1.1) - openid_connect (1.4.2) + openid_connect (~> 2.2) + openid_connect (2.2.0) activemodel attr_required (>= 1.0.0) - json-jwt (>= 1.15.0) + faraday (~> 2.0) + faraday-follow_redirects + json-jwt (>= 1.16) net-smtp - rack-oauth2 (~> 1.21) - swd (~> 1.3) + rack-oauth2 (~> 2.2) + swd (~> 2.0) tzinfo validate_email validate_url - webfinger (~> 1.2) + webfinger (~> 2.0) openseadragon (0.6.0) rails (> 3.2.0) - optimist (3.0.1) + optimist (3.1.0) orm_adapter (0.5.0) os (1.1.4) + ostruct (0.6.0) parallel (1.23.0) parser (2.5.3.0) ast (~> 2.4.0) parslet (2.0.0) - pg (1.5.3) + pg (1.5.4) posix-spawn (0.3.15) postrank-uri (1.1) addressable (>= 2.4.0) nokogiri (>= 1.8.0) public_suffix (>= 4.0.0, < 5) - power_converter (0.1.2) powerpack (0.1.3) pry (0.14.2) coderay (~> 1.1) @@ -896,158 +903,168 @@ GEM public_suffix (4.0.7) puma (5.6.7) nio4r (~> 2.0) - qa (5.10.0) + qa (5.11.0) activerecord-import deprecation faraday (< 3.0, != 2.0.0) geocoder ldpath nokogiri (~> 1.6) - rails (>= 5.0, < 7.1) + rails (>= 5.0, < 7.2) rdf - racc (1.7.1) + racc (1.7.3) rack (2.2.8) - rack-oauth2 (1.21.3) + rack-oauth2 (2.2.0) activesupport attr_required - httpclient + faraday (~> 2.0) + faraday-follow_redirects json-jwt (>= 1.11.0) rack (>= 2.1.0) - rack-protection (3.0.6) - rack + rack-protection (3.1.0) + rack (~> 2.2, >= 2.2.4) rack-test (0.7.0) rack (>= 1.0, < 3) - rails (5.2.8.1) - actioncable (= 5.2.8.1) - actionmailer (= 5.2.8.1) - actionpack (= 5.2.8.1) - actionview (= 5.2.8.1) - activejob (= 5.2.8.1) - activemodel (= 5.2.8.1) - activerecord (= 5.2.8.1) - activestorage (= 5.2.8.1) - activesupport (= 5.2.8.1) - bundler (>= 1.3.0) - railties (= 5.2.8.1) + rails (6.1.7.6) + actioncable (= 6.1.7.6) + actionmailbox (= 6.1.7.6) + actionmailer (= 6.1.7.6) + actionpack (= 6.1.7.6) + actiontext (= 6.1.7.6) + actionview (= 6.1.7.6) + activejob (= 6.1.7.6) + activemodel (= 6.1.7.6) + activerecord (= 6.1.7.6) + activestorage (= 6.1.7.6) + activesupport (= 6.1.7.6) + bundler (>= 1.15.0) + railties (= 6.1.7.6) sprockets-rails (>= 2.0.0) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) activesupport (>= 5.0.1.rc1) - rails-dom-testing (2.1.1) + rails-dom-testing (2.2.0) activesupport (>= 5.0.0) minitest nokogiri (>= 1.6) rails-html-sanitizer (1.5.0) loofah (~> 2.19, >= 2.19.1) - rails-i18n (5.1.3) + rails-i18n (7.0.8) i18n (>= 0.7, < 2) - railties (>= 5.0, < 6) + railties (>= 6.0.0, < 8) rails_autolink (1.1.8) actionview (> 3.1) activesupport (> 3.1) railties (> 3.1) - railties (5.2.8.1) - actionpack (= 5.2.8.1) - activesupport (= 5.2.8.1) + railties (6.1.7.6) + actionpack (= 6.1.7.6) + activesupport (= 6.1.7.6) method_source - rake (>= 0.8.7) - thor (>= 0.19.0, < 2.0) + rake (>= 12.2) + thor (~> 1.0) rainbow (3.1.1) - rake (13.0.6) + rake (13.1.0) rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) - rdf (3.1.15) - hamster (~> 3.0) + rdf (3.3.1) + bcp47_spec (~> 0.2) link_header (~> 0.0, >= 0.0.8) - rdf-aggregate-repo (3.1.0) - rdf (~> 3.1) - rdf-isomorphic (3.1.1) - rdf (~> 3.1) - rdf-json (3.1.0) - rdf (~> 3.1) - rdf-microdata (3.1.4) + rdf-aggregate-repo (3.3.0) + rdf (~> 3.3) + rdf-hamster-repo (3.3.0) + hamster (~> 3.0) + rdf (~> 3.3) + rdf-isomorphic (3.3.0) + rdf (~> 3.3) + rdf-json (3.3.0) + rdf (~> 3.3) + rdf-ldp (0.1.0) + deprecation + rdf + rdf-microdata (3.2.1) htmlentities (~> 4.3) - nokogiri (~> 1.12) - rdf (~> 3.1, >= 3.1.13) - rdf-rdfa (~> 3.1, >= 3.1.3) - rdf-xsd (~> 3.1) - rdf-n3 (3.1.2) - ebnf (~> 2.1) - rdf (~> 3.1, >= 3.1.8) - sparql (~> 3.1, >= 3.1.4) - sxp (~> 1.1) - rdf-normalize (0.4.0) - rdf (~> 3.1) - rdf-ordered-repo (3.1.1) - rdf (~> 3.1) - rdf-rdfa (3.1.3) - haml (~> 5.2) + nokogiri (~> 1.13) + rdf (~> 3.2) + rdf-rdfa (~> 3.2) + rdf-xsd (~> 3.2) + rdf-n3 (3.3.0) + ebnf (~> 2.4) + rdf (~> 3.3) + sparql (~> 3.3) + sxp (~> 1.3) + rdf-normalize (0.7.0) + rdf (~> 3.3) + rdf-ordered-repo (3.3.0) + rdf (~> 3.3) + rdf-rdfa (3.3.0) + haml (~> 6.1) htmlentities (~> 4.3) - rdf (~> 3.1, >= 3.1.13) - rdf-aggregate-repo (~> 3.1) - rdf-vocab (~> 3.1, >= 3.1.11) - rdf-xsd (~> 3.1) - rdf-rdfxml (3.1.1) + rdf (~> 3.3) + rdf-aggregate-repo (~> 3.3) + rdf-vocab (~> 3.3) + rdf-xsd (~> 3.3) + rdf-rdfxml (3.3.0) + builder (~> 3.2, >= 3.2.4) htmlentities (~> 4.3) - rdf (~> 3.1) - rdf-rdfa (~> 3.1) - rdf-xsd (~> 3.1) - rdf-reasoner (0.7.2) - rdf (~> 3.1, >= 3.1.12) - rdf-xsd (~> 3.1) - rdf-tabular (3.1.1) - addressable (~> 2.3) + rdf (~> 3.3) + rdf-xsd (~> 3.3) + rdf-reasoner (0.9.0) + rdf (~> 3.3) + rdf-xsd (~> 3.3) + rdf-tabular (3.2.1) + addressable (~> 2.8) bcp47 (~> 0.3, >= 0.3.3) - json-ld (~> 3.1) - rdf (~> 3.1) - rdf-vocab (~> 3.1) - rdf-xsd (~> 3.1) - rdf-trig (3.1.2) - ebnf (~> 2.1) - rdf (~> 3.1) - rdf-turtle (~> 3.1) - rdf-trix (3.1.1) - rdf (~> 3.1) - rdf-xsd (~> 3.1) - rdf-turtle (3.1.3) - ebnf (~> 2.1) - rdf (~> 3.1, >= 3.1.8) - rdf-vocab (3.1.14) - rdf (~> 3.1, >= 3.1.12) - rdf-xsd (3.1.1) - rdf (~> 3.1) + json-ld (~> 3.2) + rdf (~> 3.2, >= 3.2.7) + rdf-vocab (~> 3.2) + rdf-xsd (~> 3.2) + rdf-trig (3.3.0) + ebnf (~> 2.4) + rdf (~> 3.3) + rdf-turtle (~> 3.3) + rdf-trix (3.3.0) + rdf (~> 3.3) + rdf-xsd (~> 3.3) + rdf-turtle (3.3.0) + ebnf (~> 2.4) + rdf (~> 3.3) + rdf-vocab (3.3.0) + rdf (~> 3.3) + rdf-xsd (3.3.0) + rdf (~> 3.3) rexml (~> 3.2) redic (1.5.3) hiredis redis (4.8.1) - redis-namespace (1.10.0) + redis-namespace (1.11.0) redis (>= 4) redlock (1.3.2) redis (>= 3.0.0, < 6.0) - reform (2.5.0) - disposable (>= 0.4.2, < 0.5.0) - representable (>= 2.4.0, < 3.1.0) + reform (2.6.2) + disposable (>= 0.5.0, < 1.0.0) + representable (>= 3.1.1, < 4) uber (< 0.2.0) - reform-rails (0.2.3) + reform-rails (0.2.6) activemodel (>= 5.0) reform (>= 2.3.1, < 3.0.0) - regexp_parser (2.8.0) - representable (3.0.4) + regexp_parser (2.8.3) + representable (3.2.0) declarative (< 0.1.0) - declarative-option (< 0.2.0) + trailblazer-option (>= 0.1.1, < 0.2.0) uber (< 0.2.0) request_store (1.5.1) rack (>= 1.4) - responders (3.1.0) + responders (3.1.1) actionpack (>= 5.2) railties (>= 5.2) retriable (3.1.2) - rexml (3.2.5) - riiif (1.7.1) + rexml (3.2.6) + riiif (2.4.0) deprecation (>= 1.0.0) - railties (>= 4.2, < 6) + iiif-image-api (>= 0.1.0) + railties (>= 4.2, < 8) rolify (6.0.1) rsolr (2.5.0) builder (>= 2.1.2) @@ -1056,7 +1073,7 @@ GEM rspec-core (~> 3.12.0) rspec-expectations (~> 3.12.0) rspec-mocks (~> 3.12.0) - rspec-activemodel-mocks (1.1.0) + rspec-activemodel-mocks (1.2.0) activemodel (>= 3.0) activesupport (>= 3.0) rspec-mocks (>= 2.99, < 4.0) @@ -1068,20 +1085,20 @@ GEM rspec-its (1.3.0) rspec-core (>= 3.0.0) rspec-expectations (>= 3.0.0) - rspec-mocks (3.12.5) + rspec-mocks (3.12.6) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) - rspec-rails (5.1.2) - actionpack (>= 5.2) - activesupport (>= 5.2) - railties (>= 5.2) - rspec-core (~> 3.10) - rspec-expectations (~> 3.10) - rspec-mocks (~> 3.10) - rspec-support (~> 3.10) + rspec-rails (6.1.0) + actionpack (>= 6.1) + activesupport (>= 6.1) + railties (>= 6.1) + rspec-core (~> 3.12) + rspec-expectations (~> 3.12) + rspec-mocks (~> 3.12) + rspec-support (~> 3.12) rspec-retry (0.6.2) rspec-core (> 3.3) - rspec-support (3.12.0) + rspec-support (3.12.1) rspec_junit_formatter (0.6.0) rspec-core (>= 2, < 4, != 2.12.0) rubocop (0.52.1) @@ -1099,27 +1116,26 @@ GEM multipart-post oauth2 ruby-progressbar (1.13.0) - ruby-saml (1.15.0) + ruby-saml (1.16.0) nokogiri (>= 1.13.10) rexml ruby2_keywords (0.0.5) - ruby_dep (1.5.0) rubyzip (2.3.2) - samvera-nesting_indexer (2.0.0) - dry-equalizer sass (3.7.4) sass-listen (~> 4.0.0) sass-listen (4.0.0) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) - sass-rails (5.1.0) - railties (>= 5.2.0) - sass (~> 3.1) - sprockets (>= 2.8, < 4.0) - sprockets-rails (>= 2.0, < 4.0) - tilt (>= 1.1, < 3) + sass-rails (6.0.0) + sassc-rails (~> 2.1, >= 2.1.1) sassc (2.4.0) ffi (~> 1.9) + sassc-rails (2.1.2) + railties (>= 4.0.0) + sassc (>= 2.0) + sprockets (> 3.0) + sprockets-rails + tilt scanf (1.0.0) scss_lint (0.60.0) sass (~> 3.5, >= 3.5.5) @@ -1129,34 +1145,32 @@ GEM rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) - sentry-raven (2.13.0) - faraday (>= 0.7.6, < 1.0) - shacl (0.1.1) - json-ld (~> 3.1, >= 3.1.7) - rdf (~> 3.1, >= 3.1.8) - sparql (~> 3.1) - sxp (~> 1.1) - shex (0.6.4) - ebnf (~> 2.1, >= 2.2) + shacl (0.3.0) + json-ld (~> 3.2) + rdf (~> 3.2, >= 3.2.8) + sparql (~> 3.2, >= 3.2.4) + sxp (~> 1.2) + shex (0.7.1) + ebnf (~> 2.2) htmlentities (~> 4.3) - json-ld (~> 3.1) - json-ld-preloaded (~> 3.1) - rdf (~> 3.1) - rdf-xsd (~> 3.1) - sparql (~> 3.1) - sxp (~> 1.1) + json-ld (~> 3.2) + json-ld-preloaded (~> 3.2) + rdf (~> 3.2) + rdf-xsd (~> 3.2) + sparql (~> 3.2) + sxp (~> 1.2) shoulda-matchers (4.5.1) activesupport (>= 4.2.0) - sidekiq (6.5.9) + sidekiq (6.5.12) connection_pool (>= 2.2.5, < 3) rack (~> 2.0) redis (>= 4.5.0, < 5) - signet (0.17.0) + signet (0.18.0) addressable (~> 2.8) faraday (>= 0.17.5, < 3.a) jwt (>= 1.5, < 3.0) multi_json (~> 1.10) - simple_form (5.2.0) + simple_form (5.1.0) actionpack (>= 5.2) activemodel (>= 5.2) simplecov (0.22.0) @@ -1175,18 +1189,18 @@ GEM retriable ruby-progressbar rubyzip - sparql (3.1.8) - builder (~> 3.2) - ebnf (~> 2.1) - logger (~> 1.4) - rdf (~> 3.1, >= 3.1.14) - rdf-aggregate-repo (~> 3.1) - rdf-xsd (~> 3.1) - sparql-client (~> 3.1, >= 3.1.2) - sxp (~> 1.1) - sparql-client (3.1.2) - net-http-persistent (~> 4.0, >= 4.0.1) - rdf (~> 3.1) + sparql (3.3.0) + builder (~> 3.2, >= 3.2.4) + ebnf (~> 2.4) + logger (~> 1.5) + rdf (~> 3.3) + rdf-aggregate-repo (~> 3.3) + rdf-xsd (~> 3.3) + sparql-client (~> 3.3) + sxp (~> 1.3) + sparql-client (3.3.0) + net-http-persistent (~> 4.0, >= 4.0.2) + rdf (~> 3.3) spring (1.7.2) spring-watcher-listen (2.0.1) listen (>= 2.7, < 4.0) @@ -1203,40 +1217,39 @@ GEM activesupport (>= 5.2) sprockets (>= 3.0.0) ssrf_filter (1.0.8) - swd (1.3.0) + swd (2.0.2) activesupport (>= 3) attr_required (>= 0.0.5) - httpclient (>= 2.4) - sxp (1.1.0) - rdf (~> 3.1) - temple (0.10.0) + faraday (~> 2.0) + faraday-follow_redirects + sxp (1.3.0) + matrix (~> 0.4) + rdf (~> 3.3) + temple (0.10.3) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) - terser (1.1.14) + terser (1.1.20) execjs (>= 0.3.0, < 3) tether-rails (1.4.0) rails (>= 3.1) - thor (1.2.2) + thor (1.3.0) thread (0.2.2) thread_safe (0.3.6) - tilt (2.1.0) - timeout (0.4.0) - tinymce-rails (5.10.7) + tilt (2.3.0) + timeout (0.4.1) + tinymce-rails (5.10.9) railties (>= 3.1.1) + trailblazer-option (0.1.2) turbolinks (5.2.1) turbolinks-source (~> 5.2) turbolinks-source (5.2.0) - twitter-typeahead-rails (0.11.1.pre.corejavascript) - actionpack (>= 3.1) - jquery-rails - railties (>= 3.1) - typhoeus (1.4.0) + typhoeus (1.4.1) ethon (>= 0.9.0) - tzinfo (1.2.11) - thread_safe (~> 0.1) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) uber (0.1.0) unicode-display_width (1.8.0) - unicode-types (1.8.0) + unicode-types (1.9.0) unicode_utils (1.4.0) validatable (1.6.7) validate_email (0.1.6) @@ -1245,14 +1258,13 @@ GEM validate_url (1.0.15) activemodel (>= 3.0.0) public_suffix - valkyrie (2.2.0) + valkyrie (3.1.1) activemodel activesupport - disposable (~> 0.4.5) - draper dry-struct dry-types (~> 1.0) - faraday (< 1.0) + faraday (>= 0.9, < 3, != 2.0.0) + faraday-multipart json json-ld railties @@ -1260,46 +1272,57 @@ GEM rdf-vocab reform (~> 2.2) reform-rails - version_gem (1.1.2) + version_gem (1.1.3) + view_component (2.74.1) + activesupport (>= 5.0.0, < 8.0) + concurrent-ruby (~> 1.0) + method_source (~> 1.0) warden (1.2.9) rack (>= 2.0.9) - web-console (3.7.0) - actionview (>= 5.0) - activemodel (>= 5.0) + web-console (4.2.1) + actionview (>= 6.0.0) + activemodel (>= 6.0.0) bindex (>= 0.4.0) - railties (>= 5.0) + railties (>= 6.0.0) webdrivers (4.7.0) nokogiri (~> 1.6) rubyzip (>= 1.3.0) selenium-webdriver (> 3.141, < 5.0) - webfinger (1.2.0) + webfinger (2.1.2) activesupport - httpclient (>= 2.4) - webmock (3.18.1) + faraday (~> 2.0) + faraday-follow_redirects + webmock (3.19.1) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) webrick (1.8.1) - websocket (1.2.9) - websocket-driver (0.7.5) + websocket (1.2.10) + websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.8) + yaml-ld (0.0.2) + json-ld (~> 3.2, >= 3.2.3) + psych (>= 3.3) + rdf (~> 3.2, >= 3.2.9) + rdf-xsd (~> 3.2) + zeitwerk (2.6.12) + zlib (2.1.1) PLATFORMS - ruby + x86_64-linux-musl DEPENDENCIES - active-fedora (>= 11.1.4) + active-fedora (~> 14.0) active_elastic_job! activerecord-nulldb-adapter addressable (= 2.8.1) apartment aws-sdk-sqs - blacklight (~> 6.7) - blacklight_oai_provider (~> 6.1, >= 6.1.1) + blacklight (~> 7.29) + blacklight_oai_provider (~> 7.0) bolognese (>= 1.9.10) bootstrap-datepicker-rails bulkrax (~> 5.3) @@ -1315,14 +1338,13 @@ DEPENDENCIES devise-guests (~> 0.3) devise-i18n devise_invitable (~> 1.6) - dry-monads (~> 1.4.0) + dry-monads (~> 1.5) easy_translate factory_bot_rails fcrepo_wrapper (~> 0.4) - flipflop (~> 2.6.0) flutie hyku_knapsack! - hyrax (~> 3.5.0) + hyrax! hyrax-doi! hyrax-iiif_av! i18n-debug @@ -1348,11 +1370,11 @@ DEPENDENCIES pry-byebug puma (~> 5.6) rack-test (= 0.7.0) - rails (~> 5.2.5) + rails (~> 6.0) rails-controller-testing - rdf (~> 3.1.15) + rdf (~> 3.2) redlock (>= 0.1.2, < 2.0) - riiif (~> 1.1) + riiif (~> 2.0) rolify rsolr (~> 2.0) rspec @@ -1363,7 +1385,7 @@ DEPENDENCIES rspec_junit_formatter rubocop (~> 0.50, <= 0.52.1) rubocop-rspec (~> 1.22, <= 1.22.2) - sass-rails (~> 5.0) + sass-rails (~> 6.0) scss_lint secure_headers selenium-webdriver (= 4.8.1) @@ -1381,4 +1403,4 @@ DEPENDENCIES webmock BUNDLED WITH - 2.4.14 + 2.4.21 diff --git a/config/application.rb b/config/application.rb index c221d0090..88b9b87e3 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,4 +1,5 @@ require_relative 'boot' +require_relative '../app/middleware/no_cache_middleware' require 'rails/all' require 'i18n/debug' if ENV['I18N_DEBUG'] @@ -37,6 +38,9 @@ class Application < Rails::Application # Add this line to load the lib folder first because we need config.autoload_paths.unshift("#{Rails.root}/lib") + # Add the middleware directory to the eager load paths + config.eager_load_paths << "#{Rails.root}/app/middleware" + # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. @@ -128,5 +132,7 @@ class Application < Rails::Application Time ] end + + end end diff --git a/config/initializers/riiif.rb b/config/initializers/riiif.rb index e64daf644..9b7328ee2 100644 --- a/config/initializers/riiif.rb +++ b/config/initializers/riiif.rb @@ -18,7 +18,7 @@ end end -Riiif::Image.authorization_service = Hyrax::IIIFAuthorizationService +Riiif::Image.authorization_service = Hyrax::IiifAuthorizationService Riiif.not_found_image = Rails.root.join('app', 'assets', 'images', 'us_404.svg') Riiif.unauthorized_image = Rails.root.join('app', 'assets', 'images', 'us_404.svg') From 0840f985c7714fc8d45a3b17a13c815ccfecb52f Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Tue, 12 Dec 2023 11:53:08 -0800 Subject: [PATCH 060/126] =?UTF-8?q?=F0=9F=A7=B9=20Get=20assets=20to=20prec?= =?UTF-8?q?ompile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit has a lot in it, but of note: - We forked apartment gem to expand activerecord version support - Used the Hyrax upgrade guide to update assets - Replaced bootstrap 3 variables with hard coded values - Commented out blacklight_helper_behavior.rb because Blacklight 7 removed it, we'll have to figure out how to get the same functionality in the new version --- Gemfile | 6 ++- Gemfile.lock | 40 +++++++++++++------ app/assets/javascripts/application.js | 9 +++-- app/assets/stylesheets/application.css | 2 +- app/assets/stylesheets/hyku.scss | 14 +++---- app/assets/stylesheets/hyrax.scss | 11 +++-- .../themes/cultural_repository.scss | 10 ++--- .../themes/neutral_repository.scss | 4 +- app/controllers/application_controller.rb | 7 ---- ...r.rb => blacklight_helper_behavior.rb.old} | 0 app/models/user.rb | 1 - config/analytics.yml | 4 ++ config/environments/development.rb | 2 + config/environments/production.rb | 2 +- config/initializers/hyrax.rb | 1 - 15 files changed, 64 insertions(+), 49 deletions(-) rename app/helpers/blacklight/{blacklight_helper_behavior.rb => blacklight_helper_behavior.rb.old} (100%) diff --git a/Gemfile b/Gemfile index f09b9adc8..1d102d515 100644 --- a/Gemfile +++ b/Gemfile @@ -10,11 +10,12 @@ gem 'active-fedora', '~> 14.0' gem 'active_elastic_job', github: 'active-elastic-job/active-elastic-job', ref: 'ec51c5d9dedc4a1b47f2db41f26d5fceb251e979', group: %i[aws] gem 'activerecord-nulldb-adapter' gem 'addressable', '2.8.1' # remove once https://github.com/postrank-labs/postrank-uri/issues/49 is fixed -gem 'apartment' +gem 'apartment', github: 'scientist-softserv/apartment', branch: 'development' gem 'aws-sdk-sqs', group: %i[aws] gem 'blacklight', '~> 7.29' gem 'blacklight_oai_provider', '~> 7.0' gem 'bolognese', '>= 1.9.10' +gem 'bootstrap', '~> 4.6' gem 'bootstrap-datepicker-rails' gem 'bulkrax', '~> 5.3' gem 'byebug', group: %i[development test] @@ -28,12 +29,13 @@ gem 'database_cleaner', group: %i[test] gem 'devise' gem 'devise-guests', '~> 0.3' gem 'devise-i18n' -gem 'devise_invitable', '~> 1.6' +gem 'devise_invitable', '~> 2.0' gem 'dry-monads', '~> 1.5' gem 'easy_translate', group: %i[development] gem 'factory_bot_rails', group: %i[test] gem 'fcrepo_wrapper', '~> 0.4', group: %i[development test] gem 'flutie' +gem 'googleauth', '= 1.8.1' # 1.9.0 got yanked from rubygems, hard pinning until we can upgrade gem 'hyrax', github: 'samvera/hyrax', tag: 'hyrax-v5.0.0.rc2' gem 'hyrax-doi', github: 'samvera-labs/hyrax-doi', branch: 'rails_hyrax_upgrade' gem 'hyrax-iiif_av', github: 'samvera-labs/hyrax-iiif_av', branch: 'rails_hyrax_upgrade' diff --git a/Gemfile.lock b/Gemfile.lock index fc61e6b27..5ebb4c929 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -99,6 +99,17 @@ GIT valkyrie (~> 3.1.1) view_component (~> 2.74.1) +GIT + remote: https://github.com/scientist-softserv/apartment.git + revision: e1a24b5574dca7116f69e99f140372c42b75e041 + branch: development + specs: + apartment (2.2.1) + activerecord (>= 3.1.2, < 7.0) + parallel (>= 0.7.1) + public_suffix (>= 2) + rack (>= 1.3.6) + GIT remote: https://github.com/scientist-softserv/iiif_print.git revision: e476998ab453afabf1bcb8afa059b4416af9b705 @@ -214,11 +225,10 @@ GEM aes_key_wrap (1.1.0) almond-rails (0.3.0) rails (>= 4.2) - apartment (0.24.3) - activerecord (>= 3.1.2) - rack (>= 1.3.6) ast (2.4.2) attr_required (1.0.1) + autoprefixer-rails (10.4.16.0) + execjs (~> 2) awesome_nested_set (3.6.0) activerecord (>= 4.0.0, < 7.2) aws-eventstream (1.3.0) @@ -314,6 +324,10 @@ GEM rdf-rdfxml (~> 3.1) rdf-turtle (~> 3.1) thor (>= 0.19) + bootstrap (4.6.2) + autoprefixer-rails (>= 9.1.0) + popper_js (>= 1.16.1, < 2) + sassc-rails (>= 2.0.0) bootstrap-datepicker-rails (1.10.0.1) railties (>= 3.0) breadcrumbs_on_rails (3.0.1) @@ -420,9 +434,9 @@ GEM devise devise-i18n (1.12.0) devise (>= 4.9.0) - devise_invitable (1.7.5) - actionmailer (>= 4.1.0) - devise (>= 4.0.0) + devise_invitable (2.0.9) + actionmailer (>= 5.0) + devise (>= 4.6) diff-lcs (1.5.0) disposable (0.6.3) declarative (>= 0.0.9, < 1.0.0) @@ -551,11 +565,8 @@ GEM webrick google-apis-drive_v3 (0.46.0) google-apis-core (>= 0.11.0, < 2.a) - google-cloud-env (2.0.1) - faraday (>= 1.0, < 3.a) - googleauth (1.9.0) - faraday (>= 1.0, < 3.a) - google-cloud-env (~> 2.0, >= 2.0.1) + googleauth (1.8.1) + faraday (>= 0.17.3, < 3.a) jwt (>= 1.4, < 3.0) multi_json (~> 1.11) os (>= 0.9, < 2.0) @@ -887,6 +898,7 @@ GEM ast (~> 2.4.0) parslet (2.0.0) pg (1.5.4) + popper_js (1.16.1) posix-spawn (0.3.15) postrank-uri (1.1) addressable (>= 2.4.0) @@ -1319,11 +1331,12 @@ DEPENDENCIES active_elastic_job! activerecord-nulldb-adapter addressable (= 2.8.1) - apartment + apartment! aws-sdk-sqs blacklight (~> 7.29) blacklight_oai_provider (~> 7.0) bolognese (>= 1.9.10) + bootstrap (~> 4.6) bootstrap-datepicker-rails bulkrax (~> 5.3) byebug @@ -1337,12 +1350,13 @@ DEPENDENCIES devise devise-guests (~> 0.3) devise-i18n - devise_invitable (~> 1.6) + devise_invitable (~> 2.0) dry-monads (~> 1.5) easy_translate factory_bot_rails fcrepo_wrapper (~> 0.4) flutie + googleauth (= 1.8.1) hyku_knapsack! hyrax! hyrax-doi! diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index df9e83c18..04b9aebbf 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -14,10 +14,12 @@ //= require codemirror-autorefresh //= require codemirror/modes/css //= require jquery3 -//= require jquery_ujs +//= require rails-ujs +//= require popper +//= require bootstrap //= require jquery.fontselect -//= require dataTables/jquery.dataTables -//= require dataTables/bootstrap/3/jquery.dataTables.bootstrap +//= require jquery.dataTables +//= require dataTables.bootstrap4 //= require stat_slider //= require turbolinks //= require cocoon @@ -25,6 +27,7 @@ //= require tether // Required by Blacklight //= require blacklight/blacklight +//= require blacklight_gallery // Moved the Hyku JS *above* the Hyrax JS to resolve #1187 (following // a pattern found in ScholarSphere) diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 8b66c7d5d..9694fb3af 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -15,7 +15,7 @@ *= require codemirror *= require codemirror-theme *= require hyrax - *= require dataTables/bootstrap/3/jquery.dataTables.bootstrap + *= require dataTables.bootstrap4 *= require bootstrap-datepicker *= require single_signon *= require_self diff --git a/app/assets/stylesheets/hyku.scss b/app/assets/stylesheets/hyku.scss index 8979ddd16..118e799ac 100644 --- a/app/assets/stylesheets/hyku.scss +++ b/app/assets/stylesheets/hyku.scss @@ -16,7 +16,7 @@ } } -@media (min-width: $screen-sm-min) { +@media (min-width: 768px) { .logo-set { display: flex; flex-direction: column; @@ -131,7 +131,7 @@ footer.navbar { .sidebar { .h5 { - padding: $nav-link-padding; + padding: 10px 15px; } &.maximized { @@ -275,7 +275,7 @@ footer.navbar { } .callout-danger { - background-color: $well-bg; + background-color: #f5f5f5; border-color: $brand-danger; h1, @@ -374,7 +374,7 @@ a.btn.btn-default.restore-default-color.with-color-hint { height: auto; } -@media (min-width: $screen-lg-min) { +@media (min-width: 1200px) { a.restore-default-color { margin-top: 2em; } @@ -388,7 +388,7 @@ a.btn.btn-default.restore-default-color.with-color-hint { display: inline-block; } -@media (max-width: $screen-md-min) { +@media (max-width: 992px) { .product-features { .grid-item { width: 50%; @@ -396,7 +396,7 @@ a.btn.btn-default.restore-default-color.with-color-hint { } } -@media (max-width: $screen-sm-min) { +@media (max-width: 768px) { .product-features { .grid-item { width: 100%; @@ -433,7 +433,7 @@ body.public-facing { } // FEATURED COLLECTIONS -@media (max-width: $screen-sm-min) { +@media (max-width: 768px) { .admin-show-page .collection-title-row-wrapper .collection-title-row-content diff --git a/app/assets/stylesheets/hyrax.scss b/app/assets/stylesheets/hyrax.scss index 5efe46c15..411eca65f 100644 --- a/app/assets/stylesheets/hyrax.scss +++ b/app/assets/stylesheets/hyrax.scss @@ -5,18 +5,17 @@ */ @import "variables"; @import "bootstrap-default-overrides"; -@import "bootstrap-sprockets"; @import "bootstrap"; @import "blacklight/blacklight"; +@import "blacklight_gallery/gallery"; +@import "blacklight_gallery/masonry"; +@import "blacklight_gallery/slideshow"; +@import "blacklight_gallery/osd_viewer"; +@import "hyrax/blacklight_gallery"; @import "font-awesome"; @import "hyrax/hyrax"; @import "hyku"; @import "accounts"; @import "viewer"; -@import "blacklight_gallery/gallery"; -@import "blacklight_gallery/masonry"; -@import "blacklight_gallery/slideshow"; -@import "blacklight_gallery/osd_viewer"; - @import "themes/*"; diff --git a/app/assets/stylesheets/themes/cultural_repository.scss b/app/assets/stylesheets/themes/cultural_repository.scss index fc451c0c7..811e8e7dc 100644 --- a/app/assets/stylesheets/themes/cultural_repository.scss +++ b/app/assets/stylesheets/themes/cultural_repository.scss @@ -14,7 +14,7 @@ body.dashboard { padding-top: 100px !important; - @media (max-width: $screen-md-min) { + @media (max-width: 992px) { padding-top: 0 !important; } @@ -162,7 +162,7 @@ .facet-panel-background-color { background-color: #ffffff; - @media (max-width: $screen-md-min) { + @media (max-width: 992px) { background-color: transparent; } @@ -240,14 +240,14 @@ ////// Media Queries ////// - @media (min-width: $screen-xs-min) and (max-width: $screen-md-max) { + @media (min-width: 480px) and (max-width: 1199px) { .mt-reverse-mb { margin-bottom: 40px; margin-top: 0; } } - @media (max-width: $screen-sm-max) { + @media (max-width: 991px) { div.home_page_text.homepage-text-container { height: 0; margin-bottom: 30px; @@ -255,7 +255,7 @@ } } - @media screen and (max-width: $screen-md-min) { + @media screen and (max-width: 992px) { div.recently-uploaded:nth-of-type(2n+3), div.featured-works-6-column-layout:nth-of-type(2n+3), div.featured-works-4-column-layout:nth-of-type(2n+3) { diff --git a/app/assets/stylesheets/themes/neutral_repository.scss b/app/assets/stylesheets/themes/neutral_repository.scss index ec037fa89..26639ca41 100644 --- a/app/assets/stylesheets/themes/neutral_repository.scss +++ b/app/assets/stylesheets/themes/neutral_repository.scss @@ -152,13 +152,13 @@ ////// Media Queries ////// - @media (max-width: $screen-md-min) { + @media (max-width: 992px) { div.neutral-repository-collections:nth-of-type(2n+3) { clear: left; } } - @media (min-width: $screen-md-min) { + @media (min-width: 992px) { div.neutral-repository-collections:nth-of-type(3n+4) { clear: left; } diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 9449da3c0..424590530 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -6,8 +6,6 @@ class ApplicationController < ActionController::Base # For APIs, you may want to use :null_session instead. protect_from_forgery with: :exception, prepend: true - force_ssl if: :ssl_configured? - helper Openseadragon::OpenseadragonHelper # Adds a few additional behaviors into the application controller include Blacklight::Controller @@ -24,7 +22,6 @@ class ApplicationController < ActionController::Base before_action :require_active_account!, if: :multitenant? before_action :set_account_specific_connections! before_action :elevate_single_tenant!, if: :singletenant? - skip_after_action :discard_flash_if_xhr rescue_from Apartment::TenantNotFound do raise ActionController::RoutingError, 'Not Found' @@ -131,8 +128,4 @@ def append_info_to_payload(payload) payload[:user_id] = current_user.id if current_user payload[:account_id] = current_account.cname if current_account end - - def ssl_configured? - ActiveRecord::Type::Boolean.new.cast(current_account.ssl_configured) - end end diff --git a/app/helpers/blacklight/blacklight_helper_behavior.rb b/app/helpers/blacklight/blacklight_helper_behavior.rb.old similarity index 100% rename from app/helpers/blacklight/blacklight_helper_behavior.rb rename to app/helpers/blacklight/blacklight_helper_behavior.rb.old diff --git a/app/models/user.rb b/app/models/user.rb index 7bfdd16cf..cf903b102 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -9,7 +9,6 @@ class User < ApplicationRecord include Hyrax::User include Hyrax::UserUsageStats - attr_accessible :email, :password, :password_confirmation if Blacklight::Utils.needs_attr_accessible? # Connects this user object to Blacklights Bookmarks. include Blacklight::User # Include default devise modules. Others available are: diff --git a/config/analytics.yml b/config/analytics.yml index 42cbb1452..9b5ab5a7f 100644 --- a/config/analytics.yml +++ b/config/analytics.yml @@ -9,3 +9,7 @@ # privkey_path: <%= ENV['GOOGLE_OAUTH_PRIVATE_KEY_PATH'] %> # privkey_secret: <%= ENV['GOOGLE_OAUTH_PRIVATE_KEY_SECRET'] %> # client_email: <%= ENV['GOOGLE_OAUTH_CLIENT_EMAIL'] %> +# matomo: +# base_url: <%= ENV['MATOMO_BASE_URL'] %> +# site_id: <%= ENV['MATOMO_SITE_ID'] %> +# auth_token: <%= ENV['MATOMO_AUTH_TOKEN'] %> diff --git a/config/environments/development.rb b/config/environments/development.rb index 9bafa102c..4a0d92943 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -63,4 +63,6 @@ # Use an evented file watcher to asynchronously detect changes in source code, # routes, locales, etc. This feature depends on the listen gem. # config.file_watcher = ActiveSupport::EventedFileUpdateChecker + + config.hosts << "hyku.test" end diff --git a/config/environments/production.rb b/config/environments/production.rb index 311b96965..249a5507b 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -44,7 +44,7 @@ # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ] # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. - # config.force_ssl = true + config.force_ssl = true # Use the lowest log level to ensure availability of diagnostic information # when problems arise. diff --git a/config/initializers/hyrax.rb b/config/initializers/hyrax.rb index 1d2480ddc..1269df850 100644 --- a/config/initializers/hyrax.rb +++ b/config/initializers/hyrax.rb @@ -27,7 +27,6 @@ # Specify a Google Analytics tracking ID to gather usage statistics # This is set by account settings - # config.google_analytics_id = 'UA-99999999-1' # Specify a date you wish to start collecting Google Analytic statistics for. # config.analytic_start_date = DateTime.new(2014,9,10) From 68f89094ffeb22e32789ca81d444ba72d42a79b1 Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Tue, 12 Dec 2023 13:07:03 -0800 Subject: [PATCH 061/126] =?UTF-8?q?=F0=9F=A7=B9=20Switch=20to=20Hyrax=20`d?= =?UTF-8?q?ouble=5Fcombo`=20branch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We are using this branch on Hyrax because it has quite a few Valkyrie related fixes in it. --- Gemfile | 2 +- Gemfile.lock | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 1d102d515..905efd1ad 100644 --- a/Gemfile +++ b/Gemfile @@ -36,7 +36,7 @@ gem 'factory_bot_rails', group: %i[test] gem 'fcrepo_wrapper', '~> 0.4', group: %i[development test] gem 'flutie' gem 'googleauth', '= 1.8.1' # 1.9.0 got yanked from rubygems, hard pinning until we can upgrade -gem 'hyrax', github: 'samvera/hyrax', tag: 'hyrax-v5.0.0.rc2' +gem 'hyrax', github: 'samvera/hyrax', branch: 'double_combo' gem 'hyrax-doi', github: 'samvera-labs/hyrax-doi', branch: 'rails_hyrax_upgrade' gem 'hyrax-iiif_av', github: 'samvera-labs/hyrax-iiif_av', branch: 'rails_hyrax_upgrade' gem 'i18n-debug', require: false, group: %i[development test] diff --git a/Gemfile.lock b/Gemfile.lock index 5ebb4c929..90d84f205 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -39,8 +39,8 @@ GIT GIT remote: https://github.com/samvera/hyrax.git - revision: 3dd81340fc2586132772fa4017946ed4c60adb8a - tag: hyrax-v5.0.0.rc2 + revision: 9ef64090a13abdeaabfaabdee851829093d02cc4 + branch: double_combo specs: hyrax (5.0.0.rc2) active-fedora (~> 14.0) @@ -59,7 +59,6 @@ GIT dry-events (~> 1.0, >= 1.0.1) dry-logic (~> 1.5) dry-monads (~> 1.6) - dry-struct (~> 1.6) dry-validation (~> 1.10) flipflop (~> 2.3) flot-rails (~> 0.0.6) @@ -1366,7 +1365,6 @@ DEPENDENCIES iiif_print! jbuilder (~> 2.5) jquery-rails - json-canonicalization (= 0.3.1) launchy listen (>= 3.0.5, < 3.2) lograge From 0f67c4c259f917d02cea2053883644fca8324749 Mon Sep 17 00:00:00 2001 From: Shana Moore Date: Wed, 13 Dec 2023 09:10:22 -0800 Subject: [PATCH 062/126] =?UTF-8?q?=F0=9F=A7=B9=20use=20class=20attribute?= =?UTF-8?q?=20instead=20of=20constant=20to=20correct=20failing=20specs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/forms/hyrax/forms/admin/appearance.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/forms/hyrax/forms/admin/appearance.rb b/app/forms/hyrax/forms/admin/appearance.rb index a58cb732d..56000bd98 100644 --- a/app/forms/hyrax/forms/admin/appearance.rb +++ b/app/forms/hyrax/forms/admin/appearance.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -# OVERRIDE Hyrax 3.4.0 ot add custom theming +# OVERRIDE Hyrax 3.4.0 to add custom theming # rubocop:disable Metrics/ClassLength module Hyrax @@ -439,7 +439,7 @@ def convert_to_rgba(hex_color, alpha = 0.5) end def default_values - @default_values ||= DEFAULT_FONTS.merge(DEFAULT_COLORS) + @default_values ||= default_fonts.merge(default_colors) end def block_for(name, dynamic_default = nil) From 6930a863d531286565e443876cdc8dfba3854075 Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Tue, 12 Dec 2023 19:32:41 -0800 Subject: [PATCH 063/126] Fix specs --- app/controllers/hyrax/homepage_controller.rb | 147 ++++++++++++++++++ .../hyrax/homepage_controller_decorator.rb | 19 --- .../content_blocks/edit.html.erb_spec.rb | 2 +- 3 files changed, 148 insertions(+), 20 deletions(-) create mode 100644 app/controllers/hyrax/homepage_controller.rb delete mode 100644 app/controllers/hyrax/homepage_controller_decorator.rb diff --git a/app/controllers/hyrax/homepage_controller.rb b/app/controllers/hyrax/homepage_controller.rb new file mode 100644 index 000000000..b9130eb9e --- /dev/null +++ b/app/controllers/hyrax/homepage_controller.rb @@ -0,0 +1,147 @@ +# frozen_string_literal: true + +######################################################################################### +######################################################################################### +# +# +# HACK: We have copied over the Hyrax::HomepageController to address Hyku specific +# customizations. This controller needs significant refactoring and reconciliation +# with Hyrax prime. Note, we are inheriting differently than Hyrax does and +# there are other adjustments. +# +# +######################################################################################### +######################################################################################### +# OVERRIDE: Hyrax v2.9.0 to add home_text content block to the index method - Adding themes +# OVERRIDE: Hyrax v2.9.0 from Hyrax v2.9.0 to add facets to home page - inheriting from +# CatalogController rather than ApplicationController +# OVERRIDE: Hyrax v2.9.0 from Hyrax v2.9.0 to add inject_theme_views method for theming +# OVERRIDE: Hyrax v2.9.0 to add search_action_url method from Blacklight 6.23.0 to make facet links to go to /catalog +# OVERRIDE: Hyrax v2.9.0 to add .sort_by to return collections in alphabetical order by title on the homepage +# OVERRIDE: Hyrax v2.9.0 add all_collections page for IR theme +# OVERRIDE: Hyrax v2.9.0 to add facet counts for resource types for IR theme +# OVERRIDE: Hyrax v. 2.9.0 to add @featured_collection_list to index method + +module Hyrax + # Changed to inherit from CatalogController for home page facets + class HomepageController < CatalogController + # Adds Hydra behaviors into the application controller + include Blacklight::SearchContext + include Blacklight::SearchHelper + include Blacklight::AccessControls::Catalog + + # OVERRIDE: account for Hyku themes + around_action :inject_theme_views + + # The search builder for finding recent documents + # Override of Blacklight::RequestBuilders and default CatalogController behavior + def search_builder_class + Hyrax::HomepageSearchBuilder + end + + class_attribute :presenter_class + self.presenter_class = Hyrax::HomepagePresenter + layout 'homepage' + helper Hyrax::ContentBlockHelper + + def index + # BEGIN copy Hyrax prime's Hyrax::HomepageController#index + @presenter = presenter_class.new(current_ability, collections) + @featured_researcher = ContentBlock.for(:researcher) + @marketing_text = ContentBlock.for(:marketing) + @featured_work_list = FeaturedWorkList.new + @announcement_text = ContentBlock.for(:announcement) + recent + # END copy + + # BEGIN OVERRIDE + # What follows is Hyku specific overrides + @home_text = ContentBlock.for(:home_text) # hyrax v3.5.0 added @home_text - Adding Themes + @featured_collection_list = FeaturedCollectionList.new # OVERRIDE here to add featured collection list + + ir_counts if home_page_theme == 'institutional_repository' + + (@response, @document_list) = search_results(params) + + respond_to do |format| + format.html { store_preferred_view } + format.rss { render layout: false } + format.atom { render layout: false } + format.json do + @presenter = Blacklight::JsonPresenter.new(@response, + @document_list, + facets_from_request, + blacklight_config) + end + additional_response_formats(format) + document_export_formats(format) + end + end + + def browserconfig; end + + def all_collections + @presenter = presenter_class.new(current_ability, collections) + @marketing_text = ContentBlock.for(:marketing) + @announcement_text = ContentBlock.for(:announcement) + @collections = collections(rows: 100_000) + ir_counts if home_page_theme == 'institutional_repository' + end + + # Added from Blacklight 6.23.0 to change url for facets on home page + protected + + # Default route to the search action (used e.g. in global partials). Override this method + # in a controller or in your ApplicationController to introduce custom logic for choosing + # which action the search form should use + def search_action_url(options = {}) + # Rails 4.2 deprecated url helpers accepting string keys for 'controller' or 'action' + main_app.search_catalog_path(options) + end + + private + + # Return 6 collections + def collections(rows: 6) + builder = Hyrax::CollectionSearchBuilder.new(self) + .rows(rows) + response = repository.search(builder) + # adding .sort_by to return collections in alphabetical order by title on the homepage + response.documents.sort_by(&:title) + rescue Blacklight::Exceptions::ECONNREFUSED, Blacklight::Exceptions::InvalidRequest + [] + end + + def recent + # grab any recent documents + (_, @recent_documents) = search_results(q: '', sort: sort_field, rows: 6) + rescue Blacklight::Exceptions::ECONNREFUSED, Blacklight::Exceptions::InvalidRequest + @recent_documents = [] + end + + def ir_counts + @ir_counts = get_facet_field_response('resource_type_sim', {}, "f.resource_type_sim.facet.limit" => "-1") + end + + # COPIED from Hyrax::HomepageController + def sort_field + "date_uploaded_dtsi desc" + end + + # Add this method to prepend the theme views into the view_paths + def inject_theme_views + if home_page_theme && home_page_theme != 'default_home' + original_paths = view_paths + home_theme_view_path = Rails.root.join('app', 'views', "themes", home_page_theme.to_s) + prepend_view_path(home_theme_view_path) + yield + # rubocop:disable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses + # Do NOT change this line. This is calling the Rails view_paths=(paths) method and not a variable assignment. + view_paths=(original_paths) + # rubocop:enable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses + else + yield + end + end + end +end diff --git a/app/controllers/hyrax/homepage_controller_decorator.rb b/app/controllers/hyrax/homepage_controller_decorator.rb deleted file mode 100644 index e4564a9bb..000000000 --- a/app/controllers/hyrax/homepage_controller_decorator.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -# OVERRIDE Hyrax 3.5 to add content blocks -module Hyrax - module HomepageControllerDecorator - def index - @presenter = presenter_class.new(current_ability, collections) - @featured_researcher = ContentBlock.for(:researcher) - @marketing_text = ContentBlock.for(:marketing) - @featured_work_list = FeaturedWorkList.new - @announcement_text = ContentBlock.for(:announcement) - @homepage_about_section_heading = ContentBlock.for(:homepage_about_section_heading) - @homepage_about_section_content = ContentBlock.for(:homepage_about_section_content) - recent - end - end -end - -Hyrax::HomepageController.prepend Hyrax::HomepageControllerDecorator diff --git a/spec/views/hyrax/content_blocks/edit.html.erb_spec.rb b/spec/views/hyrax/content_blocks/edit.html.erb_spec.rb index 9039fa2bf..5dbd31afa 100644 --- a/spec/views/hyrax/content_blocks/edit.html.erb_spec.rb +++ b/spec/views/hyrax/content_blocks/edit.html.erb_spec.rb @@ -36,7 +36,7 @@ end it "renders the instruction blocks" do - expect(rendered).to have_xpath('//p[@class="content-block-instructions" ]', count: 4) + expect(rendered).to have_xpath('//p[@class="content-block-instructions" ]', count: 6) end # TODO: These next 4 tests are tightly coupled with the implimentation, From 939bd17eb4ab071b83002e0091432e98ad81d795 Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Tue, 12 Dec 2023 13:36:58 -0800 Subject: [PATCH 064/126] =?UTF-8?q?=F0=9F=A7=B9=20Get=20the=20page=20to=20?= =?UTF-8?q?load?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit will get the proprietor page to load. You can create a tenant and vist it as well. --- Gemfile.lock | 3 ++- app/helpers/application_helper.rb | 2 +- app/jobs/create_default_admin_set_job.rb | 2 +- app/services/create_account.rb | 2 +- app/services/roles_service.rb | 2 +- app/views/layouts/hyrax.html.erb | 2 +- config/environments/development.rb | 3 ++- db/seeds.rb | 2 +- spec/features/admin_set_form_participants_tab_spec.rb | 2 +- spec/features/assign_workflow_to_group_spec.rb | 2 +- spec/features/create_generic_work_spec.rb | 2 +- spec/features/create_image_spec.rb | 2 +- spec/features/create_work_spec.rb | 2 +- spec/features/show_page_theme_spec.rb | 2 +- spec/requests/work_depositor_role_spec.rb | 2 +- 15 files changed, 17 insertions(+), 15 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 90d84f205..8c95cd3bb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -100,7 +100,7 @@ GIT GIT remote: https://github.com/scientist-softserv/apartment.git - revision: e1a24b5574dca7116f69e99f140372c42b75e041 + revision: 9ad4b0ef2ee6debb956e86ef9e7095c8358fef5e branch: development specs: apartment (2.2.1) @@ -1365,6 +1365,7 @@ DEPENDENCIES iiif_print! jbuilder (~> 2.5) jquery-rails + json-canonicalization (= 0.3.1) launchy listen (>= 3.0.5, < 3.2) lograge diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index e27eee4ae..681cd4d18 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -24,7 +24,7 @@ def locale_for(type:, term:, record_class:) locale end - def missing_translation(value) + def missing_translation(value, options = {}) value.include?('translation missing') end end diff --git a/app/jobs/create_default_admin_set_job.rb b/app/jobs/create_default_admin_set_job.rb index 592b32f8e..1f8ee9437 100644 --- a/app/jobs/create_default_admin_set_job.rb +++ b/app/jobs/create_default_admin_set_job.rb @@ -2,6 +2,6 @@ class CreateDefaultAdminSetJob < ApplicationJob def perform(_account) - AdminSet.find_or_create_default_admin_set_id + Hyrax::AdminSetCreateService.find_or_create_default_admin_set.id end end diff --git a/app/services/create_account.rb b/app/services/create_account.rb index f021fbff4..1ce61f94e 100644 --- a/app/services/create_account.rb +++ b/app/services/create_account.rb @@ -46,7 +46,7 @@ def create_defaults Hyrax::CollectionType.find_or_create_admin_set_type return if account.search_only? - AdminSet.find_or_create_default_admin_set_id + Hyrax::AdminSetCreateService.find_or_create_default_admin_set.id end # Workaround for upstream issue https://github.com/samvera/hyrax/issues/3136 diff --git a/app/services/roles_service.rb b/app/services/roles_service.rb index c5c6a5de8..7b28747ad 100644 --- a/app/services/roles_service.rb +++ b/app/services/roles_service.rb @@ -87,7 +87,7 @@ def create_default_hyrax_groups_with_roles! default_hyrax_groups_with_roles.each do |group_name, group_attrs| group_roles = group_attrs.delete(:roles) group = Hyrax::Group.find_or_create_by!(name: group_name) - group.update_attributes(group_attrs) + group.update(group_attrs) group_roles.each do |role_name| next if role_name.blank? diff --git a/app/views/layouts/hyrax.html.erb b/app/views/layouts/hyrax.html.erb index e2ff69136..448eba3d3 100644 --- a/app/views/layouts/hyrax.html.erb +++ b/app/views/layouts/hyrax.html.erb @@ -31,6 +31,6 @@ <%= content_for?(:content) ? yield(:content) : yield %> <%= render 'shared/footer' %> - <%= render 'shared/ajax_modal' %> + <%= render 'shared/modal' %> diff --git a/config/environments/development.rb b/config/environments/development.rb index 4a0d92943..07f298607 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -64,5 +64,6 @@ # routes, locales, etc. This feature depends on the listen gem. # config.file_watcher = ActiveSupport::EventedFileUpdateChecker - config.hosts << "hyku.test" + # adding `.` wildcard to allow for subdomains + config.hosts << "." + ENV['HYKU_ADMIN_HOST'] end diff --git a/db/seeds.rb b/db/seeds.rb index 509224c1e..a3b84dae7 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -17,7 +17,7 @@ AccountElevator.switch!(single_tenant_default.cname) puts "\n== Creating default admin set" - admin_set = AdminSet.find(AdminSet.find_or_create_default_admin_set_id) + admin_set = AdminSet.find(Hyrax::AdminSetCreateService.find_or_create_default_admin_set.id) puts "\n== Creating default collection types" Hyrax::CollectionType.find_or_create_default_collection_type diff --git a/spec/features/admin_set_form_participants_tab_spec.rb b/spec/features/admin_set_form_participants_tab_spec.rb index 06fb8d1fa..13bea005e 100644 --- a/spec/features/admin_set_form_participants_tab_spec.rb +++ b/spec/features/admin_set_form_participants_tab_spec.rb @@ -23,7 +23,7 @@ end let(:admin) { FactoryBot.create(:admin) } - let!(:admin_set_id) { AdminSet.find_or_create_default_admin_set_id } + let!(:admin_set_id) { Hyrax::AdminSetCreateService.find_or_create_default_admin_set.id } let!(:permission_template) { Hyrax::PermissionTemplate.find_or_create_by!(source_id: admin_set_id) } context 'add group participants' do diff --git a/spec/features/assign_workflow_to_group_spec.rb b/spec/features/assign_workflow_to_group_spec.rb index 636d3859c..e6d791630 100644 --- a/spec/features/assign_workflow_to_group_spec.rb +++ b/spec/features/assign_workflow_to_group_spec.rb @@ -25,7 +25,7 @@ let!(:group) { FactoryBot.create(:group, name: 'flinstones', humanized_name: 'Flinstones') } let!(:group_3) { FactoryBot.create(:group, name: 'town_of_bedrock', humanized_name: 'Town of Bedrock') } - let!(:admin_set_id) { AdminSet.find_or_create_default_admin_set_id } + let!(:admin_set_id) { Hyrax::AdminSetCreateService.find_or_create_default_admin_set.id } let!(:permission_template) { Hyrax::PermissionTemplate.find_or_create_by!(source_id: admin_set_id) } it 'admin assigns an approving workflow role to a user' do diff --git a/spec/features/create_generic_work_spec.rb b/spec/features/create_generic_work_spec.rb index 890e6ebf6..1490a6710 100644 --- a/spec/features/create_generic_work_spec.rb +++ b/spec/features/create_generic_work_spec.rb @@ -10,7 +10,7 @@ context 'a logged in user with the :work_depositor role' do let(:user) { create(:user, roles: [:work_depositor]) } - let(:admin_set_id) { AdminSet.find_or_create_default_admin_set_id } + let(:admin_set_id) { Hyrax::AdminSetCreateService.find_or_create_default_admin_set.id } let(:permission_template) { Hyrax::PermissionTemplate.find_or_create_by!(source_id: admin_set_id) } let(:workflow) do Sipity::Workflow.create!( diff --git a/spec/features/create_image_spec.rb b/spec/features/create_image_spec.rb index 9154f3b88..8cd1cf796 100644 --- a/spec/features/create_image_spec.rb +++ b/spec/features/create_image_spec.rb @@ -10,7 +10,7 @@ context 'a logged in user with the :work_depositor role' do let(:user) { create(:user, roles: [:work_depositor]) } - let(:admin_set_id) { AdminSet.find_or_create_default_admin_set_id } + let(:admin_set_id) { Hyrax::AdminSetCreateService.find_or_create_default_admin_set.id } let(:permission_template) { Hyrax::PermissionTemplate.find_or_create_by!(source_id: admin_set_id) } let(:workflow) do Sipity::Workflow.create!( diff --git a/spec/features/create_work_spec.rb b/spec/features/create_work_spec.rb index 6eddc7e85..49523a9cc 100644 --- a/spec/features/create_work_spec.rb +++ b/spec/features/create_work_spec.rb @@ -9,7 +9,7 @@ FactoryBot.create(:admin_group) FactoryBot.create(:editors_group) FactoryBot.create(:depositors_group) - AdminSet.find_or_create_default_admin_set_id + Hyrax::AdminSetCreateService.find_or_create_default_admin_set.id login_as user, scope: :user end diff --git a/spec/features/show_page_theme_spec.rb b/spec/features/show_page_theme_spec.rb index 941ae652f..2e66de5b3 100644 --- a/spec/features/show_page_theme_spec.rb +++ b/spec/features/show_page_theme_spec.rb @@ -13,7 +13,7 @@ user: user) end - let(:admin_set_id) { AdminSet.find_or_create_default_admin_set_id } + let(:admin_set_id) { Hyrax::AdminSetCreateService.find_or_create_default_admin_set.id } let(:permission_template) { Hyrax::PermissionTemplate.find_or_create_by!(source_id: admin_set_id) } let(:workflow) do Sipity::Workflow.create!( diff --git a/spec/requests/work_depositor_role_spec.rb b/spec/requests/work_depositor_role_spec.rb index b95ae1c2e..0053ac892 100644 --- a/spec/requests/work_depositor_role_spec.rb +++ b/spec/requests/work_depositor_role_spec.rb @@ -15,7 +15,7 @@ end describe 'read permissions' do - let!(:admin_set_id) { AdminSet.find_or_create_default_admin_set_id } + let!(:admin_set_id) { Hyrax::AdminSetCreateService.find_or_create_default_admin_set.id } before do solr = Blacklight.default_index.connection From 31de0fe382db138f342a42df59774f1111d38fc1 Mon Sep 17 00:00:00 2001 From: Jeremy Friesen Date: Wed, 4 Oct 2023 10:49:31 -0400 Subject: [PATCH 065/126] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Introduce=20Hyku::?= =?UTF-8?q?Application.theme=5Fview=5Fpath=5Froots?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the introduction of [HykuKnapsack][1], we are adjusting how we create instances of Hyku. Namely we don't clone Hyku but instead we incorporate Hyku as a submodule into a Knapsack. The Knapsack is a Rails engine that is mounted in the Hyku application. What this means is that when we want to Prior to this commit, the only way to adjust themed views would have been to add them to the Rails application (e.g. Hyku) directly. Which would work in a non-Knapsack ecosystem. However, with Knapsack we need a means of saying "Hey, for themes we want to be able to add/adjust views within the knapsack." Hence this change. [1]: https://github.com/samvera-labs/hyku_knapsack --- .../concerns/hyrax/works_controller_behavior.rb | 6 ++++-- .../hyrax/contact_form_controller.rb | 6 ++++-- app/controllers/hyrax/pages_controller.rb | 6 ++++-- config/application.rb | 17 +++++++++++++++++ 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/app/controllers/concerns/hyrax/works_controller_behavior.rb b/app/controllers/concerns/hyrax/works_controller_behavior.rb index f5b51f64f..91f005843 100644 --- a/app/controllers/concerns/hyrax/works_controller_behavior.rb +++ b/app/controllers/concerns/hyrax/works_controller_behavior.rb @@ -505,8 +505,10 @@ def available_admin_sets def inject_show_theme_views if show_page_theme && show_page_theme != 'default_show' original_paths = view_paths - show_theme_view_path = Rails.root.join('app', 'views', "themes", show_page_theme.to_s) - prepend_view_path(show_theme_view_path) + Hyku::Application.theme_view_path_roots.each do |root| + show_theme_view_path = File.join(root, 'app', 'views', "themes", show_page_theme.to_s) + prepend_view_path(show_theme_view_path) + end yield # rubocop:disable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses # Do NOT change this line. This is calling the Rails view_paths=(paths) method and not a variable assignment. diff --git a/app/controllers/hyrax/contact_form_controller.rb b/app/controllers/hyrax/contact_form_controller.rb index a420f82d4..c941ee191 100644 --- a/app/controllers/hyrax/contact_form_controller.rb +++ b/app/controllers/hyrax/contact_form_controller.rb @@ -102,8 +102,10 @@ def collections(rows: 6) def inject_theme_views if home_page_theme && home_page_theme != 'default_home' original_paths = view_paths - home_theme_view_path = Rails.root.join('app', 'views', "themes", home_page_theme.to_s) - prepend_view_path(home_theme_view_path) + Hyku::Application.theme_view_path_roots.each do |root| + home_theme_view_path = File.join(root, 'app', 'views', "themes", home_page_theme.to_s) + prepend_view_path(home_theme_view_path) + end yield # rubocop:disable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses # Do NOT change this line. This is calling the Rails view_paths=(paths) method and not a variable assignment. diff --git a/app/controllers/hyrax/pages_controller.rb b/app/controllers/hyrax/pages_controller.rb index cdfd8d0a7..b47e19856 100644 --- a/app/controllers/hyrax/pages_controller.rb +++ b/app/controllers/hyrax/pages_controller.rb @@ -101,8 +101,10 @@ def collections(rows: 6) def inject_theme_views if home_page_theme && home_page_theme != 'default_home' original_paths = view_paths - home_theme_view_path = Rails.root.join('app', 'views', "themes", home_page_theme.to_s) - prepend_view_path(home_theme_view_path) + Hyku::Application.theme_view_path_roots.each do |root| + home_theme_view_path = File.join(root, 'app', 'views', "themes", home_page_theme.to_s) + prepend_view_path(home_theme_view_path) + end yield # rubocop:disable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses # Do NOT change this method. This is an override of the view_paths= method and not a variable assignment. diff --git a/config/application.rb b/config/application.rb index 3af68f13f..616515c97 100644 --- a/config/application.rb +++ b/config/application.rb @@ -62,6 +62,22 @@ class Application < Rails::Application # IiifPrint::SplitPdfs::AdventistPagesToJpgsSplitter config.autoload_paths.unshift("#{Rails.root}/lib") + ## + # @return [Array] an array of strings in which we should be looking for theme view + # candidates. + # @see Hyrax::WorksControllerBehavior + # @see Hyrax::ContactFormController + # @see Hyrax::PagesController + # @see https://api.rubyonrails.org/classes/ActionView/ViewPaths.html#method-i-prepend_view_path + # + # @see .path_for + # @see + def self.theme_view_path_roots + returning_value = [Rails.root.to_s] + returning_value.push HykuKnapsack::Engine.root.to_s if defined?(HykuKnapsack) + returning_value + end + ## # @api public # @@ -69,6 +85,7 @@ class Application < Rails::Application # # @return [String] the path to the file, favoring those found in the knapsack but falling back # to those in the Rails.root. + # @see .theme_view_path_roots def self.path_for(relative_path) if defined?(HykuKnapsack) engine_path = HykuKnapsack::Engine.root.join(relative_path) From 2d7f8b76813f6849521278bd5de3234b3ca4efcd Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Wed, 13 Dec 2023 15:05:40 -0800 Subject: [PATCH 066/126] =?UTF-8?q?=F0=9F=A7=B9=20Prepping=20for=20rubocop?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit will change the Docker image to rc1 because rc2 stopped working (at least locally). Also getting things ready to run rubocop. --- .rubocop.yml | 170 +++++++++++---------- .rubocop_fixme.yml | 201 +++++++++++++++++++++++++ .rubocop_todo.yml | 235 ++++++++++++------------------ Dockerfile | 2 +- Gemfile | 6 +- Gemfile.lock | 38 +++-- app/helpers/application_helper.rb | 2 +- 7 files changed, 412 insertions(+), 242 deletions(-) create mode 100644 .rubocop_fixme.yml diff --git a/.rubocop.yml b/.rubocop.yml index 4a5fb78c8..7af771792 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,133 +1,127 @@ -# Turn on RSpec cops -require: rubocop-rspec -inherit_from: .rubocop_todo.yml +inherit_from: + - .rubocop_fixme.yml -# With the rubocop 0.47.0 and rubocop-rspec 1.8.0 the following stderr message was sent: -# An error occurred while RSpec/DescribedClass cop was inspecting path/to/file -RSpec/DescribedClass: - Enabled: false +inherit_gem: + bixby: bixby_default.yml AllCops: + TargetRubyVersion: 2.6 DisplayCopNames: true - TargetRubyVersion: 2.3 Exclude: - - 'bin/**/*' - 'db/**/*' - - 'config/**/*' - - 'vendor/**/*' - - '.internal_test_app/**/*' - - 'spec/fixtures/**/*' - - 'spec/internal/**/*' + - 'script/**/*' - 'spec/test_app_templates/**/*' - - 'Rakefile' - - 'lib/tasks/rubocop.rake' - # disabling collections controller as most of the rubocop errors are in hyrax - - 'app/controllers/hyrax/dashboard/collections_controller.rb' - -Rails: - Enabled: true + - 'vendor/**/*' + - 'lib/hyrax/specs/**/*' -Rails/DynamicFindBy: - Whitelist: - - find_by_user_key +Lint/ImplicitStringConcatenation: Exclude: - - 'lib/importer/factory/object_factory.rb' + - 'lib/generators/hyrax/**/*' -Rails/UnknownEnv: - Environments: - - development - - production - - staging - - test +Rails/Output: + Exclude: + - 'lib/generators/**/*' -Metrics/LineLength: - Max: 120 +Metrics/BlockLength: + ExcludedMethods: ['included'] Exclude: - - 'app/controllers/catalog_controller.rb' - - 'spec/controllers/curation_concerns/generic_works_controller_spec.rb' - - 'spec/services/iiif_collection_thumbnail_path_service_spec.rb' - - 'spec/services/iiif_work_thumbnail_path_service_spec.rb' - - 'spec/routing/proprietor/accounts_routing_spec.rb' + - 'hyrax.gemspec' + - 'app/models/concerns/hyrax/content_block_behavior.rb' + - 'app/services/hyrax/workflow/workflow_schema.rb' + - 'config/initializers/simple_form.rb' + - 'config/features.rb' + - 'config/routes.rb' + - 'lib/generators/hyrax/templates/catalog_controller.rb' + - 'lib/generators/hyrax/templates/config/initializers/simple_form_bootstrap.rb' + - 'lib/hyrax/rails/routes.rb' + - 'lib/tasks/*.rake' + - 'spec/**/*.rb' + - 'tasks/benchmark.rake' -Layout/IndentationConsistency: - EnforcedStyle: rails +Style/AsciiComments: + Enabled: false -Layout/DotPosition: - EnforcedStyle: leading +# rubocop suggests !thing.nil? instead, but that is NOT equivalent +Style/DoubleNegation: + Enabled: false + +Style/CollectionMethods: + PreferredMethods: + collect: 'map' + collect!: 'map!' + inject: 'reduce' + detect: 'find' + find_all: 'select' -Style/Documentation: +Style/SymbolArray: Enabled: false -Style/StringLiterals: +Style/ClassAndModuleChildren: Enabled: false -Style/WordArray: +Style/SingleLineBlockParams: Enabled: false -Metrics/ClassLength: - Exclude: - - 'app/controllers/catalog_controller.rb' +Rails/ApplicationJob: + Enabled: false -Metrics/ModuleLength: - Max: 200 +Rails/ApplicationRecord: + Enabled: false -Rails/HasAndBelongsToMany: - Exclude: - - 'app/models/role.rb' +Rails/RakeEnvironment: + Enabled: false -RSpec/AnyInstance: +# We define custom methods like `find_by_user_key`, +# `find_by_created_date`, etc +Rails/DynamicFindBy: Enabled: false -RSpec/InstanceVariable: +Rails/FilePath: Exclude: - - 'spec/controllers/hyku/registrations_controller_spec.rb' + - 'spec/abilities/**/*' -RSpec/NamedSubject: - Enabled: false +Rails/OutputSafety: + Exclude: + - 'app/builders/hyrax/form_builder.rb' + - 'app/helpers/hyrax/citations_behaviors/formatters/apa_formatter.rb' + - 'app/helpers/hyrax/citations_behaviors/formatters/chicago_formatter.rb' + - 'app/helpers/hyrax/citations_behaviors/formatters/mla_formatter.rb' + - 'app/helpers/hyrax/collections_helper.rb' + - 'app/helpers/hyrax/content_block_helper_behavior.rb' + - 'app/helpers/hyrax/hyrax_helper_behavior.rb' + - 'app/presenters/hyrax/fixity_status_presenter.rb' + - 'app/presenters/hyrax/presents_attributes.rb' + - 'app/renderers/hyrax/renderers/attribute_renderer.rb' + - 'spec/views/hyrax/my/works/_list_works.html.erb_spec.rb' RSpec/DescribeClass: Exclude: - - 'spec/requests/**/*' + - 'spec/abilities/**/*' + - 'spec/config/hyrax_events_spec.rb' + - 'spec/conversions/**/*' - 'spec/features/**/*' + - 'spec/inputs/**/*' + - 'spec/javascripts/jasmine_spec.rb' + - 'spec/tasks/rake_spec.rb' - 'spec/views/**/*' - - 'spec/routing/**/*' - - 'spec/tasks/**/*' -Rails/FilePath: - Exclude: - - 'spec/routing/**/*' +# # By default RSpec/MessageSpies has the following: +# # Prefer have_received for setting message expectations. Setup form as a spy using allow or instance_spy. +# # The default assumes EnforcedStyle is 'have_received'. Most of our specs are 'receive' +RSpec/MessageSpies: + Enabled: false RSpec/ExpectActual: - Exclude: - - 'spec/routing/**/*' + Enabled: false -RSpec/VerifiedDoubles: +RSpec/LetSetup: Enabled: false RSpec/MessageExpectation: Enabled: false -# By default RSpec/MessageSpies has the following: -# Prefer have_received for setting message expectations. Setup form as a spy using allow or instance_spy. -RSpec/MessageSpies: - Enabled: true - EnforcedStyle: receive - -RSpec/ExampleLength: - Max: 20 - RSpec/NestedGroups: - Max: 4 - -RSpec/MultipleExpectations: Enabled: false -Metrics/BlockLength: - Exclude: - - 'spec/**/*.rb' - - 'lib/tasks/*.rake' - - 'app/controllers/catalog_controller.rb' - -RSpec/FilePath: - Exclude: - - 'spec/config/application_spec.rb' +RSpec/LeadingSubject: + Enabled: false diff --git a/.rubocop_fixme.yml b/.rubocop_fixme.yml new file mode 100644 index 000000000..964bae6dc --- /dev/null +++ b/.rubocop_fixme.yml @@ -0,0 +1,201 @@ +Security/MarshalLoad: + Exclude: + - 'app/models/concerns/hyrax/user.rb' + +Metrics/ClassLength: + Exclude: + - 'app/controllers/hyrax/dashboard/collections_controller.rb' + - 'app/controllers/hyrax/admin/admin_sets_controller.rb' + - 'app/controllers/hyrax/batch_edits_controller.rb' + - 'app/controllers/hyrax/downloads_controller.rb' + - 'app/controllers/hyrax/file_sets_controller.rb' + - 'app/forms/hyrax/forms/permission_template_form.rb' + - 'app/presenters/hyrax/work_show_presenter.rb' + - 'app/presenters/hyrax/collection_presenter.rb' + - 'app/services/hyrax/user_stat_importer.rb' + - 'lib/generators/hyrax/templates/catalog_controller.rb' + - 'lib/generators/hyrax/install_generator.rb' + - 'lib/hyrax/configuration.rb' + +Metrics/ParameterLists: + Exclude: + - 'app/jobs/batch_create_job.rb' + +Metrics/ModuleLength: + Exclude: + - 'app/controllers/concerns/hyrax/works_controller_behavior.rb' + - 'app/helpers/hyrax/hyrax_helper_behavior.rb' + - 'app/models/concerns/hyrax/ability.rb' + - 'app/services/hyrax/workflow/permission_query.rb' + - 'spec/services/hyrax/workflow/permission_query_spec.rb' + # TODO: extract CollectionAccessControls or something, so we don't have to skip this check? + - 'app/models/concerns/hyrax/collection_behavior.rb' + +RSpec/NamedSubject: + Enabled: false + +RSpec/ExampleLength: + Max: 9 + Exclude: + - 'spec/actors/hyrax/actors/file_set_actor_spec.rb' + - 'spec/actors/hyrax/actors/generic_work_actor_spec.rb' + - 'spec/controllers/hyrax/api/items_controller_spec.rb' + - 'spec/controllers/hyrax/batch_edits_controller_spec.rb' + - 'spec/controllers/hyrax/batch_uploads_controller_spec.rb' + - 'spec/controllers/hyrax/file_sets_controller_spec.rb' + - 'spec/controllers/hyrax/generic_works_controller_spec.rb' + - 'spec/controllers/hyrax/my/highlights_controller_spec.rb' + - 'spec/controllers/hyrax/transfers_controller_spec.rb' + - 'spec/forms/hyrax/forms/collection_form_spec.rb' + - 'spec/forms/hyrax/forms/batch_edit_form_spec.rb' + - 'spec/forms/hyrax/forms/batch_upload_form_spec.rb' + - 'spec/forms/hyrax/forms/file_set_edit_form_spec.rb' + - 'spec/features/**/*' + - 'spec/helpers/hyrax/charts_helper_spec.rb' + - 'spec/helpers/dashboard_helper_spec.rb' + - 'spec/helpers/hyrax_helper_spec.rb' + - 'spec/indexers/hyrax/file_set_indexer_spec.rb' + - 'spec/javascripts/jasmine_spec.rb' + - 'spec/jobs/file_set_attached_event_job_spec.rb' + - 'spec/jobs/batch_create_job_spec.rb' + - 'spec/jobs/create_work_job_spec.rb' + - 'spec/jobs/content_update_event_job_spec.rb' + - 'spec/jobs/content_restored_version_event_job_spec.rb' + - 'spec/jobs/content_new_version_event_job_spec.rb' + - 'spec/jobs/content_depositor_change_event_job_spec.rb' + - 'spec/jobs/change_depositor_event_job_spec.rb' + - 'spec/jobs/content_deposit_event_job_spec.rb' + - 'spec/jobs/content_delete_event_job_spec.rb' + - 'spec/jobs/ingest_file_job_spec.rb' + - 'spec/lib/hyrax/arkivo/actor_spec.rb' + - 'spec/lib/hyrax/resource_sync/capability_list_writer_spec.rb' + - 'spec/models/checksum_audit_log_spec.rb' + - 'spec/models/featured_work_spec.rb' + - 'spec/models/file_set_spec.rb' + - 'spec/models/generic_work_spec.rb' + - 'spec/presenters/hyrax/inspect_work_presenter_spec.rb' + - 'spec/services/hyrax/actor_factory_spec.rb' + - 'spec/services/hyrax/admin_set_create_service_spec.rb' + - 'spec/services/hyrax/default_middleware_stack_spec.rb' + - 'spec/services/hyrax/graph_exporter_spec.rb' + - 'spec/services/hyrax/user_stat_importer_spec.rb' + - 'spec/services/hyrax/workflow/activate_object_spec.rb' + - 'spec/services/hyrax/workflow/deactivate_object_spec.rb' + - 'spec/services/hyrax/workflow/permission_generator_spec.rb' + - 'spec/services/hyrax/workflow/permission_query_spec.rb' + - 'spec/services/hyrax/workflow/state_machine_generator_spec.rb' + - 'spec/services/hyrax/workflow/workflow_importer_spec.rb' + - 'spec/views/**/*' + - 'spec/wings/valkyrie/persister_spec.rb' + +RSpec/VerifiedDoubles: + Enabled: false + +RSpec/SubjectStub: + Exclude: + - 'spec/actors/hyrax/actors/generic_work_actor_spec.rb' + - 'spec/controllers/hyrax/file_sets_controller_spec.rb' + - 'spec/models/file_set_spec.rb' + - 'spec/models/hyrax/work_behavior_spec.rb' + - 'spec/search_builders/hyrax/file_set_search_builder_spec.rb' + - 'spec/models/hyrax/operation_spec.rb' + - 'spec/controllers/hyrax/accepts_batches_controller_spec.rb' + - 'spec/indexers/hyrax/repository_reindexer_spec.rb' + - 'spec/lib/hyrax/analytics_spec.rb' + - 'spec/models/job_io_wrapper_spec.rb' + - 'spec/search_builders/hyrax/abstract_type_relation_spec.rb' + - 'spec/services/hyrax/database_migrator_spec.rb' + +RSpec/AnyInstance: + Exclude: + - 'spec/actors/hyrax/actors/generic_work_actor_spec.rb' + - 'spec/controllers/hyrax/api/items_controller_spec.rb' + - 'spec/controllers/hyrax/api/zotero_controller_spec.rb' + - 'spec/controllers/hyrax/batch_edits_controller_spec.rb' + - 'spec/controllers/hyrax/stats_controller_spec.rb' + - 'spec/controllers/hyrax/users_controller_spec.rb' + - 'spec/hyrax/transactions/steps/delete_access_control_spec.rb' + - 'spec/hyrax/transactions/steps/save_access_control_spec.rb' + - 'spec/jobs/content_restored_version_event_job_spec.rb' + - 'spec/jobs/file_set_attached_event_job_spec.rb' + - 'spec/jobs/hyrax/grant_edit_to_members_job_spec.rb' + - 'spec/jobs/hyrax/grant_read_to_members_job_spec.rb' + - 'spec/jobs/hyrax/revoke_edit_from_members_job_spec.rb' + - 'spec/lib/hyrax/arkivo/create_subscription_job_spec.rb' + - 'spec/presenters/hyrax/file_usage_spec.rb' + - 'spec/presenters/hyrax/work_usage_spec.rb' + - 'spec/services/hyrax/repository_fixity_check_service_spec.rb' + - 'spec/services/hyrax/workflow/permission_generator_spec.rb' + - 'spec/services/hyrax/workflow/sipity_actions_generator_spec.rb' + - 'spec/services/hyrax/workflow/state_machine_generator_spec.rb' + - 'spec/services/hyrax/workflow/workflow_permissions_generator_spec.rb' + - 'spec/controllers/hyrax/homepage_controller_spec.rb' + - 'spec/controllers/hyrax/my/collections_controller_spec.rb' + - 'spec/controllers/hyrax/my/works_controller_spec.rb' + - 'spec/presenters/hyrax/admin/repository_object_presenter_spec.rb' + +# Offense count: 51 +RSpec/ExpectInHook: + Enabled: false + +# Offense count: 27 +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: and_return, block +RSpec/ReturnFromStub: + Exclude: + - 'spec/controllers/hyrax/api/items_controller_spec.rb' + - 'spec/controllers/hyrax/file_sets_controller_spec.rb' + - 'spec/lib/hyrax/arkivo/create_subscription_job_spec.rb' + - 'spec/models/file_set_spec.rb' + - 'spec/presenters/hyrax/admin_set_options_presenter_spec.rb' + - 'spec/routing/api_route_spec.rb' + - 'spec/views/_user_util_links.html.erb_spec.rb' + - 'spec/views/hyrax/base/_attributes.html.erb_spec.rb' + - 'spec/views/hyrax/base/_form.html.erb_spec.rb' + - 'spec/views/hyrax/base/file_manager.html.erb_spec.rb' + - 'spec/views/hyrax/dashboard/profiles/edit.html.erb_spec.rb' + - 'spec/views/hyrax/users/_user_info.html.erb_spec.rb' + +# Offense count: 26 +RSpec/RepeatedDescription: + Exclude: + - 'spec/models/sipity/agent_spec.rb' + - 'spec/models/sipity/comment_spec.rb' + - 'spec/models/sipity/entity_spec.rb' + - 'spec/models/sipity/entity_specific_responsibility_spec.rb' + - 'spec/models/sipity/role_spec.rb' + - 'spec/models/sipity/workflow_action_spec.rb' + - 'spec/models/sipity/workflow_responsibility_spec.rb' + - 'spec/models/sipity/workflow_role_spec.rb' + - 'spec/models/sipity/workflow_state_action_permission_spec.rb' + - 'spec/models/sipity/workflow_state_action_spec.rb' + - 'spec/models/sipity/workflow_state_spec.rb' + +# Offense count: 2 +# Configuration parameters: Include. +# Include: app/models/**/*.rb +Rails/HasManyOrHasOneDependent: + Exclude: + - 'app/models/admin_set.rb' + - 'app/models/hyrax/permission_template.rb' + +# Offense count: 1 +Rails/SkipsModelValidations: + Exclude: + - 'app/services/hyrax/works/migration_service.rb' + +# Offense count: 12 +Lint/MissingSuper: + Exclude: + - 'app/actors/hyrax/actors/interpret_visibility_actor.rb' + - 'app/actors/hyrax/actors/ordered_members_actor.rb' + - 'app/models/concerns/hyrax/file_set/characterization.rb' + - 'app/presenters/hyrax/file_usage.rb' + - 'app/presenters/hyrax/work_usage.rb' + - 'app/services/hyrax/batch_create_failure_service.rb' + - 'app/services/hyrax/batch_create_success_service.rb' + - 'app/services/hyrax/collection_types/create_service.rb' + - 'app/services/hyrax/solr_query_service.rb' + - 'lib/hyrax/form_fields.rb' + - 'lib/hyrax/health_checks/solr_check.rb' + - 'lib/hyrax/schema.rb' diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 902a16471..ad19a7fd2 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,186 +1,139 @@ # This configuration was generated by -# `rubocop --auto-gen-config` -# on 2020-05-15 17:53:23 +0000 using RuboCop version 0.52.1. +# `rubocop --auto-gen-config --no-auto-gen-timestamp` +# using RuboCop version 1.28.2. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 1 -Lint/AmbiguousBlockAssociation: - Exclude: - - 'app/controllers/catalog_controller.rb' - -# Offense count: 5 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleAlignWith, AutoCorrect. -# SupportedStylesAlignWith: keyword, variable, start_of_line -Lint/EndAlignment: +# Offense count: 2 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EmptyLineBetweenMethodDefs, EmptyLineBetweenClassDefs, EmptyLineBetweenModuleDefs, AllowAdjacentOneLineDefs, NumberOfEmptyLines. +Layout/EmptyLineBetweenDefs: Exclude: - - 'app/helpers/blacklight/catalog_helper_behavior.rb' + - 'app/jobs/bulkrax/import_file_set_job.rb' + - 'app/models/bulkrax/entry.rb' # Offense count: 2 -Lint/UselessAssignment: +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: empty_lines, no_empty_lines +Layout/EmptyLinesAroundBlockBody: Exclude: - - 'app/forms/hyrax/forms/admin/appearance.rb' - - 'spec/controllers/proprietor/users_controller_spec.rb' - -# Offense count: 10 -Metrics/AbcSize: - Max: 49 + - 'spec/rails_helper.rb' # Offense count: 3 -# Configuration parameters: CountComments. -Metrics/ClassLength: - Max: 112 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle. +# SupportedHashRocketStyles: key, separator, table +# SupportedColonStyles: key, separator, table +# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit +Layout/HashAlignment: + Exclude: + - 'app/parsers/bulkrax/csv_parser.rb' + - 'spec/models/bulkrax/rdf_entry_spec.rb' + - 'spec/models/bulkrax/xml_entry_spec.rb' -# Offense count: 2 -Metrics/CyclomaticComplexity: - Max: 12 +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: Width, AllowedPatterns, IgnoredPatterns. +Layout/IndentationWidth: + Exclude: + - 'spec/rails_helper.rb' -# Offense count: 23 -# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. +# Offense count: 8 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns, IgnoredPatterns. # URISchemes: http, https -Metrics/LineLength: - Max: 376 - -# Offense count: 7 -# Configuration parameters: CountComments. -Metrics/MethodLength: - Max: 35 +Layout/LineLength: + Max: 301 # Offense count: 1 -# Configuration parameters: CountComments. -Metrics/ModuleLength: - Max: 168 - -# Offense count: 2 -Metrics/PerceivedComplexity: - Max: 14 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: symmetrical, new_line, same_line +Layout/MultilineMethodCallBraceLayout: + Exclude: + - 'app/parsers/bulkrax/csv_parser.rb' # Offense count: 1 -# Configuration parameters: Blacklist. -# Blacklist: END, (?-mix:EO[A-Z]{1}) -Naming/HeredocDelimiterNaming: +# This cop supports safe auto-correction (--auto-correct). +Layout/RescueEnsureAlignment: Exclude: - - 'spec/jobs/import_work_from_purl_job_spec.rb' - -# Offense count: 6 -# Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist, MethodDefinitionMacros. -# NamePrefix: is_, has_, have_ -# NamePrefixBlacklist: is_, has_, have_ -# NameWhitelist: is_a? -# MethodDefinitionMacros: define_method, define_singleton_method -Naming/PredicateName: - Exclude: - - 'spec/**/*' - - 'app/controllers/application_controller.rb' - - 'app/helpers/blacklight/catalog_helper_behavior.rb' - - 'app/models/user.rb' + - 'spec/rails_helper.rb' -# Offense count: 6 -RSpec/BeforeAfterAll: - Exclude: - - 'spec/spec_helper.rb' +# Offense count: 7 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: AllowInHeredoc. +Layout/TrailingWhitespace: + Exclude: + - 'app/models/bulkrax/csv_entry.rb' + - 'app/parsers/bulkrax/csv_parser.rb' + - 'spec/models/bulkrax/rdf_entry_spec.rb' + - 'spec/models/bulkrax/xml_entry_spec.rb' - 'spec/rails_helper.rb' - - 'spec/support/**/*.rb' - - 'spec/models/hyku/group_spec.rb' - - 'spec/models/uploaded_file_spec.rb' - - 'spec/tasks/rake_spec.rb' -# Offense count: 85 -# Configuration parameters: Prefixes. -# Prefixes: when, with, without -RSpec/ContextWording: - Enabled: false +# Offense count: 16 +# Configuration parameters: IgnoredMethods, CountRepeatedAttributes. +Metrics/AbcSize: + Max: 42 -# Offense count: 3 -RSpec/ExpectInHook: - Exclude: - - 'spec/controllers/sites_controller_spec.rb' - - 'spec/models/uploaded_file_spec.rb' +# Offense count: 4 +# Configuration parameters: CountComments, CountAsOne. +Metrics/ClassLength: + Max: 201 -# Offense count: 1 -RSpec/IteratedExpectation: - Exclude: - - 'spec/tasks/rake_spec.rb' +# Offense count: 13 +# Configuration parameters: IgnoredMethods. +Metrics/CyclomaticComplexity: + Max: 19 -# Offense count: 4 -RSpec/LetSetup: - Exclude: - - 'spec/models/account_spec.rb' - - 'spec/models/role_spec.rb' - - 'spec/models/user_spec.rb' +# Offense count: 32 +# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods. +Metrics/MethodLength: + Max: 26 # Offense count: 2 -RSpec/MessageChain: - Exclude: - - 'spec/views/shared/select_work_type_modal.html.erb_spec.rb' +# Configuration parameters: CountComments, CountAsOne. +Metrics/ModuleLength: + Max: 131 -# Offense count: 8 -RSpec/ScatteredLet: - Exclude: - - 'spec/controllers/account_sign_up_controller_spec.rb' - - 'spec/controllers/admin/accounts_controller_spec.rb' - - 'spec/controllers/proprietor/accounts_controller_spec.rb' - - 'spec/jobs/import_work_from_purl_job_spec.rb' +# Offense count: 9 +# Configuration parameters: IgnoredMethods. +Metrics/PerceivedComplexity: + Max: 19 # Offense count: 1 # Configuration parameters: Include. # Include: app/models/**/*.rb Rails/HasManyOrHasOneDependent: Exclude: - - 'app/models/endpoint.rb' + - 'app/models/concerns/bulkrax/status_info.rb' -# Offense count: 5 -Rails/OutputSafety: - Exclude: - - 'app/forms/hyrax/forms/admin/appearance.rb' - - 'app/helpers/blacklight/catalog_helper_behavior.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: AutoCorrect, EnforcedStyle. -# SupportedStyles: nested, compact -Style/ClassAndModuleChildren: - Exclude: - - 'app/helpers/blacklight/catalog_helper_behavior.rb' - -# Offense count: 3 -# Configuration parameters: EnforcedStyle. -# SupportedStyles: annotated, template, unannotated -Style/FormatStringToken: +# Offense count: 2 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: Keywords, RequireColon. +# Keywords: TODO, FIXME, OPTIMIZE, HACK, REVIEW, NOTE +Style/CommentAnnotation: Exclude: - - 'app/models/account.rb' - - 'spec/models/account_spec.rb' + - 'app/models/bulkrax/xml_entry.rb' + - 'spec/models/bulkrax/oai_entry_spec.rb' -# Offense count: 4 -# Configuration parameters: MinBodyLength. -Style/GuardClause: +# Offense count: 2 +# This cop supports safe auto-correction (--auto-correct). +Style/IfUnlessModifier: Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/hyrax/downloads_controller.rb' - - 'app/helpers/blacklight/catalog_helper_behavior.rb' - - 'app/models/bulkrax/entry.rb' + - 'app/models/bulkrax/csv_entry.rb' + - 'lib/generators/bulkrax/templates/config/initializers/bulkrax.rb' # Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: line_count_dependent, lambda, literal -Style/Lambda: +# This cop supports safe auto-correction (--auto-correct). +Style/MultilineIfModifier: Exclude: - - 'app/models/user.rb' + - 'app/models/bulkrax/csv_entry.rb' # Offense count: 1 -Style/MixinUsage: +# This cop supports safe auto-correction (--auto-correct). +Style/RedundantBegin: Exclude: - - 'spec/support/devise.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: AutoCorrect, EnforcedStyle. -# SupportedStyles: predicate, comparison -Style/NumericPredicate: - Exclude: - - 'spec/**/*' - - 'app/helpers/blacklight/catalog_helper_behavior.rb' + - 'spec/rails_helper.rb' diff --git a/Dockerfile b/Dockerfile index da22d3d7c..325d61452 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -ARG HYRAX_IMAGE_VERSION=hyrax-v5.0.0.rc2 +ARG HYRAX_IMAGE_VERSION=hyrax-v5.0.0.rc1 FROM ghcr.io/samvera/hyrax/hyrax-base:$HYRAX_IMAGE_VERSION as hyku-base USER root diff --git a/Gemfile b/Gemfile index 1ddb2fe60..a676dbfcb 100644 --- a/Gemfile +++ b/Gemfile @@ -19,6 +19,7 @@ gem 'blacklight_range_limit' gem 'bolognese', '>= 1.9.10' gem 'bootstrap', '~> 4.6' gem 'bootstrap-datepicker-rails' +gem 'bixby', '~> 5.0', '>= 5.0.2', group: %i[development test] gem 'bulkrax', '~> 5.4' gem 'byebug', group: %i[development test] gem 'capybara', group: %i[test] @@ -61,7 +62,7 @@ gem 'omniauth-rails_csrf_protection', '~> 1.0' gem 'omniauth-saml', '~> 2.1' gem 'omniauth_openid_connect' gem 'order_already' -gem 'parser', '~> 2.5.3' +gem 'parser', '>= 3.1.0.0' gem 'pg' gem 'postrank-uri', '>= 1.0.24' gem 'pry-byebug', group: %i[development test] @@ -79,8 +80,9 @@ gem 'rspec-its', group: %i[test] gem 'rspec-rails', '>= 3.6.0', group: %i[development test] gem 'rspec-retry', group: %i[test] gem 'rspec_junit_formatter', group: %i[test] -gem 'rubocop', '~> 0.50', '<= 0.52.1', group: %i[development test] +gem 'rubocop', '1.28.2', group: %i[development test] gem 'rubocop-rspec', '~> 1.22', '<= 1.22.2', group: %i[development test] +gem 'rubocop-rails', '~> 2.15', group: %i[development test] gem 'sass-rails', '~> 6.0' # Use SCSS for stylesheets gem 'scss_lint', require: false, group: %i[development] gem 'secure_headers' diff --git a/Gemfile.lock b/Gemfile.lock index c397bf7af..6676493a1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -274,6 +274,12 @@ GEM bigdecimal (3.1.5) bindata (2.4.15) bindex (0.8.1) + bixby (5.0.2) + rubocop (= 1.28.2) + rubocop-ast + rubocop-performance + rubocop-rails + rubocop-rspec blacklight (7.35.0) deprecation globalid @@ -916,8 +922,9 @@ GEM os (1.1.4) ostruct (0.6.0) parallel (1.23.0) - parser (2.5.3.0) - ast (~> 2.4.0) + parser (3.2.2.4) + ast (~> 2.4.1) + racc parslet (2.0.0) pg (1.5.4) popper_js (1.16.1) @@ -926,7 +933,6 @@ GEM addressable (>= 2.4.0) nokogiri (>= 1.8.0) public_suffix (>= 4.0.0, < 5) - powerpack (0.1.3) pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) @@ -1136,13 +1142,24 @@ GEM rspec-support (3.12.1) rspec_junit_formatter (0.6.0) rspec-core (>= 2, < 4, != 2.12.0) - rubocop (0.52.1) + rubocop (1.28.2) parallel (~> 1.10) - parser (>= 2.4.0.2, < 3.0) - powerpack (~> 0.1) + parser (>= 3.1.0.0) rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml + rubocop-ast (>= 1.17.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (~> 1.0, >= 1.0.1) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.30.0) + parser (>= 3.2.1.0) + rubocop-performance (1.19.1) + rubocop (>= 1.7.0, < 2.0) + rubocop-ast (>= 0.4.0) + rubocop-rails (2.15.2) + activesupport (>= 4.2.0) + rack (>= 1.1) + rubocop (>= 1.7.0, < 2.0) rubocop-rspec (1.22.2) rubocop (>= 0.52.1) ruby-box (1.15.0) @@ -1347,6 +1364,7 @@ GEM zlib (2.1.1) PLATFORMS + aarch64-linux-musl x86_64-linux-musl DEPENDENCIES @@ -1356,6 +1374,7 @@ DEPENDENCIES addressable (= 2.8.1) apartment! aws-sdk-sqs + bixby (~> 5.0, >= 5.0.2) blacklight (~> 7.29) blacklight_advanced_search blacklight_oai_provider (~> 7.0) @@ -1405,7 +1424,7 @@ DEPENDENCIES omniauth-saml (~> 2.1) omniauth_openid_connect order_already - parser (~> 2.5.3) + parser (>= 3.1.0.0) pg postrank-uri (>= 1.0.24) pry-byebug @@ -1424,7 +1443,8 @@ DEPENDENCIES rspec-rails (>= 3.6.0) rspec-retry rspec_junit_formatter - rubocop (~> 0.50, <= 0.52.1) + rubocop (= 1.28.2) + rubocop-rails (~> 2.15) rubocop-rspec (~> 1.22, <= 1.22.2) sass-rails (~> 6.0) scss_lint diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 18b2d58b4..df85c9a77 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -25,7 +25,7 @@ def locale_for(type:, term:, record_class:) locale end - def missing_translation(value, options = {}) + def missing_translation(value, _options = {}) value.include?('translation missing') end end From fecb4e923038594123b7f05d9e5ca360db0408cb Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Wed, 13 Dec 2023 15:07:35 -0800 Subject: [PATCH 067/126] =?UTF-8?q?=F0=9F=A7=B9=20Ran=20`bundle=20exec=20r?= =?UTF-8?q?ubocop=20-a`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gemfile | 10 +- app/controllers/account_sign_up_controller.rb | 32 +- app/controllers/admin/accounts_controller.rb | 12 +- .../admin/group_roles_controller.rb | 30 +- .../admin/group_users_controller.rb | 32 +- app/controllers/admin/groups_controller.rb | 18 +- app/controllers/admin/users_controller.rb | 6 +- .../admin/work_types_controller.rb | 6 +- app/controllers/admin_controller.rb | 12 +- app/controllers/application_controller.rb | 156 ++--- app/controllers/catalog_controller.rb | 4 +- .../hyrax/admin/users_controller_behavior.rb | 10 +- .../hyrax/users_controller_decorator.rb | 40 +- .../hyrax/works_controller_behavior.rb | 624 +++++++++--------- .../hyku/invitations_controller.rb | 10 +- .../hyku/registrations_controller.rb | 6 +- .../hyrax/admin/appearances_controller.rb | 64 +- .../hyrax/admin/workflow_roles_controller.rb | 6 +- .../hyrax/contact_form_controller.rb | 86 +-- .../hyrax/dashboard/collections_controller.rb | 50 +- .../featured_collection_lists_controller.rb | 6 +- app/controllers/hyrax/homepage_controller.rb | 88 +-- app/controllers/hyrax/pages_controller.rb | 78 +-- .../identity_providers_controller.rb | 42 +- app/controllers/labels_controller.rb | 12 +- .../proprietor/accounts_controller.rb | 64 +- .../proprietor/users_controller.rb | 72 +- app/controllers/roles_controller.rb | 6 +- app/controllers/sites_controller.rb | 56 +- .../users/omniauth_callbacks_controller.rb | 2 +- app/forms/hyrax/forms/admin/appearance.rb | 94 +-- app/helpers/shared_search_helper.rb | 22 +- app/jobs/cleanup_account_job.rb | 28 +- app/jobs/create_solr_collection_job.rb | 120 ++-- app/jobs/delete_old_guests_job.rb | 6 +- app/jobs/embargo_auto_expiry_job.rb | 6 +- app/jobs/import_work_from_purl_job.rb | 100 +-- app/jobs/lease_auto_expiry_job.rb | 6 +- app/jobs/remove_solr_collection_job.rb | 8 +- app/mailers/hyku_mailer.rb | 6 +- app/models/concerns/account_cname.rb | 8 +- app/models/concerns/account_settings.rb | 126 ++-- app/models/concerns/account_switch.rb | 2 +- app/models/featured_collection_list.rb | 32 +- app/models/hyrax/group.rb | 28 +- app/models/nil_fcrepo_endpoint.rb | 6 +- app/models/nil_solr_endpoint.rb | 22 +- app/models/redis_endpoint.rb | 6 +- app/models/role.rb | 10 +- app/models/site.rb | 38 +- app/models/user.rb | 2 +- .../iiif_av/displays_content_decorator.rb | 110 +-- .../hyku/admin/group/navigation_presenter.rb | 118 ++-- .../hyku/collapsable_section_presenter.rb | 22 +- app/presenters/hyku/work_show_presenter.rb | 30 +- app/presenters/hyrax/admin/users_presenter.rb | 8 +- .../hyrax/collection_presenter_decorator.rb | 20 +- app/presenters/hyrax/homepage_presenter.rb | 8 +- app/services/create_account.rb | 8 +- app/services/group_aware_role_checker.rb | 20 +- .../manifest_builder_service_decorator.rb | 30 +- app/services/hyrax/thumbnail_path_service.rb | 80 +-- .../hyrax/workflow/permission_grantor.rb | 90 +-- app/services/roles_service.rb | 4 +- bin/extract_mods_to_spreadsheet | 10 +- bin/git-cleanup | 6 +- bin/graph | 13 +- bin/import_from_purl | 2 +- bin/import_mods_files | 2 - bin/web | 4 +- bin/worker | 6 +- config/application.rb | 22 +- config/environments/development.rb | 13 +- config/environments/production.rb | 6 +- config/initializers/0db_created.rb | 4 +- config/initializers/apartment.rb | 11 +- config/initializers/bulkrax.rb | 23 +- config/initializers/devise.rb | 4 +- .../file_set_derivatives_overrides.rb | 4 +- config/initializers/hyrax.rb | 10 +- config/initializers/mailboxer.rb | 15 +- config/initializers/mime_types.rb | 2 +- config/initializers/rolify.rb | 2 +- config/initializers/simple_form.rb | 1 - config/routes.rb | 12 +- config/spring.rb | 4 +- lib/active_job_tenant.rb | 22 +- .../derivatives/processors/image_decorator.rb | 18 +- .../canvas_builder_decorator.rb | 4 +- lib/importer/csv_importer.rb | 38 +- lib/importer/csv_parser.rb | 200 +++--- lib/importer/factory/object_factory.rb | 98 +-- .../factory/with_associated_collection.rb | 6 +- lib/importer/mods_parser.rb | 102 +-- lib/stanford/importer/mods_parser.rb | 14 +- lib/stanford/importer/purl_parser.rb | 18 +- lib/stanford/importer/purl_retriever.rb | 16 +- spec/factories/admin_sets.rb | 4 +- spec/factories/collection_types.rb | 8 +- spec/factories/collections.rb | 16 +- spec/factories/permission_templates.rb | 24 +- spec/lib/importer/csv_importer_spec.rb | 2 +- spec/models/account_spec.rb | 2 +- .../admin/group/navigation_presenter_spec.rb | 8 +- spec/rails_helper.rb | 8 +- .../account_sign_up/new.html.erb_spec.rb | 2 +- .../proprietor/accounts/new.html.erb_spec.rb | 2 +- .../proprietor/users/new.html.erb_spec.rb | 2 +- .../proprietor/users/show.html.erb_spec.rb | 2 +- 109 files changed, 1796 insertions(+), 1860 deletions(-) diff --git a/Gemfile b/Gemfile index a676dbfcb..a350101b3 100644 --- a/Gemfile +++ b/Gemfile @@ -6,12 +6,13 @@ source 'https://rubygems.org' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '~> 6.0' -gem 'active-fedora', '~> 14.0' gem 'active_elastic_job', github: 'active-elastic-job/active-elastic-job', ref: 'ec51c5d9dedc4a1b47f2db41f26d5fceb251e979', group: %i[aws] +gem 'active-fedora', '~> 14.0' gem 'activerecord-nulldb-adapter' gem 'addressable', '2.8.1' # remove once https://github.com/postrank-labs/postrank-uri/issues/49 is fixed gem 'apartment', github: 'scientist-softserv/apartment', branch: 'development' gem 'aws-sdk-sqs', group: %i[aws] +gem 'bixby', '~> 5.0', '>= 5.0.2', group: %i[development test] gem 'blacklight', '~> 7.29' gem 'blacklight_advanced_search' gem 'blacklight_oai_provider', '~> 7.0' @@ -19,7 +20,6 @@ gem 'blacklight_range_limit' gem 'bolognese', '>= 1.9.10' gem 'bootstrap', '~> 4.6' gem 'bootstrap-datepicker-rails' -gem 'bixby', '~> 5.0', '>= 5.0.2', group: %i[development test] gem 'bulkrax', '~> 5.4' gem 'byebug', group: %i[development test] gem 'capybara', group: %i[test] @@ -58,9 +58,9 @@ gem 'negative_captcha' gem 'okcomputer' gem 'omniauth-cas', github: 'stanhu/omniauth-cas', ref: '4211e6d05941b4a981f9a36b49ec166cecd0e271' gem 'omniauth-multi-provider' +gem 'omniauth_openid_connect' gem 'omniauth-rails_csrf_protection', '~> 1.0' gem 'omniauth-saml', '~> 2.1' -gem 'omniauth_openid_connect' gem 'order_already' gem 'parser', '>= 3.1.0.0' gem 'pg' @@ -77,12 +77,12 @@ gem 'rsolr', '~> 2.0' gem 'rspec', group: %i[development test] gem 'rspec-activemodel-mocks', group: %i[test] gem 'rspec-its', group: %i[test] +gem 'rspec_junit_formatter', group: %i[test] gem 'rspec-rails', '>= 3.6.0', group: %i[development test] gem 'rspec-retry', group: %i[test] -gem 'rspec_junit_formatter', group: %i[test] gem 'rubocop', '1.28.2', group: %i[development test] -gem 'rubocop-rspec', '~> 1.22', '<= 1.22.2', group: %i[development test] gem 'rubocop-rails', '~> 2.15', group: %i[development test] +gem 'rubocop-rspec', '~> 1.22', '<= 1.22.2', group: %i[development test] gem 'sass-rails', '~> 6.0' # Use SCSS for stylesheets gem 'scss_lint', require: false, group: %i[development] gem 'secure_headers' diff --git a/app/controllers/account_sign_up_controller.rb b/app/controllers/account_sign_up_controller.rb index 89b06cb6e..c0fe62fae 100644 --- a/app/controllers/account_sign_up_controller.rb +++ b/app/controllers/account_sign_up_controller.rb @@ -27,24 +27,24 @@ def create private - def ensure_admin! - # Require Admin access to perform any actions - authorize! :read, :admin_dashboard - end + def ensure_admin! + # Require Admin access to perform any actions + authorize! :read, :admin_dashboard + end - def admin_only_tenant_creation? - ActiveModel::Type::Boolean.new.cast(ENV.fetch('HYKU_ADMIN_ONLY_TENANT_CREATION', false)) - end + def admin_only_tenant_creation? + ActiveModel::Type::Boolean.new.cast(ENV.fetch('HYKU_ADMIN_ONLY_TENANT_CREATION', false)) + end - def first_user_registration_url - if current_user - new_user_session_url(host: @account.cname) - else - new_user_registration_url(host: @account.cname) - end + def first_user_registration_url + if current_user + new_user_session_url(host: @account.cname) + else + new_user_registration_url(host: @account.cname) end + end - def create_params - params.require(:account).permit(:name) - end + def create_params + params.require(:account).permit(:name) + end end diff --git a/app/controllers/admin/accounts_controller.rb b/app/controllers/admin/accounts_controller.rb index f27c0e2a7..d5028b217 100644 --- a/app/controllers/admin/accounts_controller.rb +++ b/app/controllers/admin/accounts_controller.rb @@ -28,12 +28,12 @@ def update private - def account_params - params.require(:account).permit(:name, :cname, :title, *@account.public_settings.keys) - end + def account_params + params.require(:account).permit(:name, :cname, :title, *@account.public_settings.keys) + end - def set_current_account - @account = Site.account - end + def set_current_account + @account = Site.account + end end end diff --git a/app/controllers/admin/group_roles_controller.rb b/app/controllers/admin/group_roles_controller.rb index d1966f2dd..1818e85a6 100644 --- a/app/controllers/admin/group_roles_controller.rb +++ b/app/controllers/admin/group_roles_controller.rb @@ -44,23 +44,23 @@ def destroy private - def load_group - @group = Hyrax::Group.find_by(id: params[:group_id]) - end + def load_group + @group = Hyrax::Group.find_by(id: params[:group_id]) + end - def redirect_not_found - flash[:error] = 'Unable to find Group Role with that ID' - redirect_to admin_group_roles_path(@group) - end + def redirect_not_found + flash[:error] = 'Unable to find Group Role with that ID' + redirect_to admin_group_roles_path(@group) + end - def cannot_remove_admin_role_from_admin_group - role = Role.find_by(id: params[:role_id]) - return unless @group.name == ::Ability.admin_group_name && role.name == 'admin' + def cannot_remove_admin_role_from_admin_group + role = Role.find_by(id: params[:role_id]) + return unless @group.name == ::Ability.admin_group_name && role.name == 'admin' - redirect_back( - fallback_location: edit_admin_group_path(@group), - flash: { error: "Admin role cannot be removed from this group" } - ) - end + redirect_back( + fallback_location: edit_admin_group_path(@group), + flash: { error: "Admin role cannot be removed from this group" } + ) + end end end diff --git a/app/controllers/admin/group_users_controller.rb b/app/controllers/admin/group_users_controller.rb index 3488fda4c..c7544ead0 100644 --- a/app/controllers/admin/group_users_controller.rb +++ b/app/controllers/admin/group_users_controller.rb @@ -32,25 +32,25 @@ def destroy private - def load_group - @group = Hyrax::Group.find_by(id: params[:group_id]) - end + def load_group + @group = Hyrax::Group.find_by(id: params[:group_id]) + end - def page_number - params.fetch(:page, 1).to_i - end + def page_number + params.fetch(:page, 1).to_i + end - def page_size - params.fetch(:per, 10).to_i - end + def page_size + params.fetch(:per, 10).to_i + end - def cannot_remove_admin_users_from_admin_group - return unless @group.name == ::Ability.admin_group_name + def cannot_remove_admin_users_from_admin_group + return unless @group.name == ::Ability.admin_group_name - redirect_back( - fallback_location: edit_admin_group_path(@group), - flash: { error: "Admin users cannot be removed from this group" } - ) - end + redirect_back( + fallback_location: edit_admin_group_path(@group), + flash: { error: "Admin users cannot be removed from this group" } + ) + end end end diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb index c939ff5de..513ef190e 100644 --- a/app/controllers/admin/groups_controller.rb +++ b/app/controllers/admin/groups_controller.rb @@ -83,16 +83,16 @@ def destroy private - def group_params - params.require(:group).permit(:name, :humanized_name, :description) - end + def group_params + params.require(:group).permit(:name, :humanized_name, :description) + end - def page_number - params.fetch(:page, 1).to_i - end + def page_number + params.fetch(:page, 1).to_i + end - def page_size - params.fetch(:per, 10).to_i - end + def page_size + params.fetch(:per, 10).to_i + end end end diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index fa6740127..6230b44c3 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -28,8 +28,8 @@ def activate private - def load_user - @user = User.from_url_component(params[:id]) - end + def load_user + @user = User.from_url_component(params[:id]) + end end end diff --git a/app/controllers/admin/work_types_controller.rb b/app/controllers/admin/work_types_controller.rb index babaf515c..105745775 100644 --- a/app/controllers/admin/work_types_controller.rb +++ b/app/controllers/admin/work_types_controller.rb @@ -24,8 +24,8 @@ def update private - def site - @site ||= Site.first - end + def site + @site ||= Site.first + end end end diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index 2f8d6cb33..e9005f827 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -7,11 +7,11 @@ class AdminController < ApplicationController private - def ensure_admin! - authorize! :read, :admin_dashboard - end + def ensure_admin! + authorize! :read, :admin_dashboard + end - def deny_access(_exception) - redirect_to main_app.root_url, alert: t('hyku.admin.flash.access_denied') - end + def deny_access(_exception) + redirect_to main_app.root_url, alert: t('hyku.admin.flash.access_denied') + end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 424590530..4c6abe1a8 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -29,103 +29,103 @@ class ApplicationController < ActionController::Base protected - def is_hidden - current_account.persisted? && !current_account.is_public? - end + def is_hidden + current_account.persisted? && !current_account.is_public? + end - def is_api_or_pdf - request.format.to_s.match('json') || - params[:print] || - request.path.include?('api') || - request.path.include?('pdf') - end + def is_api_or_pdf + request.format.to_s.match('json') || + params[:print] || + request.path.include?('api') || + request.path.include?('pdf') + end - def is_staging - ['staging'].include?(Rails.env) - end + def is_staging + ['staging'].include?(Rails.env) + end - ## - # Extra authentication for palni-palci during development phase - def authenticate_if_needed - # Disable this extra authentication in test mode - return true if Rails.env.test? - if (is_hidden || is_staging) && !is_api_or_pdf - authenticate_or_request_with_http_basic do |username, password| - username == "samvera" && password == "hyku" - end + ## + # Extra authentication for palni-palci during development phase + def authenticate_if_needed + # Disable this extra authentication in test mode + return true if Rails.env.test? + if (is_hidden || is_staging) && !is_api_or_pdf + authenticate_or_request_with_http_basic do |username, password| + username == "samvera" && password == "hyku" end end + end - def super_and_current_users - users = Role.find_by(name: 'superadmin')&.users.to_a - users << current_user if current_user && !users.include?(current_user) - users - end + def super_and_current_users + users = Role.find_by(name: 'superadmin')&.users.to_a + users << current_user if current_user && !users.include?(current_user) + users + end private - def require_active_account! - return if singletenant? - return if devise_controller? - raise Apartment::TenantNotFound, "No tenant for #{request.host}" unless current_account.persisted? - end + def require_active_account! + return if singletenant? + return if devise_controller? + raise Apartment::TenantNotFound, "No tenant for #{request.host}" unless current_account.persisted? + end - def set_account_specific_connections! - current_account&.switch! - end + def set_account_specific_connections! + current_account&.switch! + end - def multitenant? - @multitenant ||= ActiveModel::Type::Boolean.new.cast(ENV.fetch('HYKU_MULTITENANT', false)) - end + def multitenant? + @multitenant ||= ActiveModel::Type::Boolean.new.cast(ENV.fetch('HYKU_MULTITENANT', false)) + end - def singletenant? - !multitenant? - end + def singletenant? + !multitenant? + end - def elevate_single_tenant! - AccountElevator.switch!(current_account.cname) if current_account && root_host? - end + def elevate_single_tenant! + AccountElevator.switch!(current_account.cname) if current_account && root_host? + end - def root_host? - Account.canonical_cname(request.host) == Account.root_host - end + def root_host? + Account.canonical_cname(request.host) == Account.root_host + end - def admin_host? - return false if singletenant? - Account.canonical_cname(request.host) == Account.admin_host - end + def admin_host? + return false if singletenant? + Account.canonical_cname(request.host) == Account.admin_host + end - def current_account - @current_account ||= Account.from_request(request) - @current_account ||= if multitenant? - Account.new do |a| - a.build_solr_endpoint - a.build_fcrepo_endpoint - a.build_redis_endpoint - end - else - Account.single_tenant_default + def current_account + @current_account ||= Account.from_request(request) + @current_account ||= if multitenant? + Account.new do |a| + a.build_solr_endpoint + a.build_fcrepo_endpoint + a.build_redis_endpoint end - end + else + Account.single_tenant_default + end + end - # Find themes set on Site model, or return default - def home_page_theme - current_account.sites&.first&.home_theme || 'default_home' - end + # Find themes set on Site model, or return default + def home_page_theme + current_account.sites&.first&.home_theme || 'default_home' + end - def show_page_theme - current_account.sites&.first&.show_theme || 'default_show' - end + def show_page_theme + current_account.sites&.first&.show_theme || 'default_show' + end - def search_results_theme - current_account.sites&.first&.search_theme || 'list_view' - end + def search_results_theme + current_account.sites&.first&.search_theme || 'list_view' + end - # Add context information to the lograge entries - def append_info_to_payload(payload) - super - payload[:request_id] = request.uuid - payload[:user_id] = current_user.id if current_user - payload[:account_id] = current_account.cname if current_account - end + # Add context information to the lograge entries + def append_info_to_payload(payload) + super + payload[:request_id] = request.uuid + payload[:user_id] = current_user.id if current_user + payload[:account_id] = current_account.cname if current_account + end end diff --git a/app/controllers/catalog_controller.rb b/app/controllers/catalog_controller.rb index a9105df5b..ebbb4bf82 100644 --- a/app/controllers/catalog_controller.rb +++ b/app/controllers/catalog_controller.rb @@ -427,8 +427,8 @@ def self.uploaded_field repository_name: ->(controller) { controller.send(:current_account)&.name.presence }, # repository_url: ->(controller) { controller.oai_catalog_url }, record_prefix: ->(controller) { controller.send(:current_account).oai_prefix }, - admin_email: ->(controller) { controller.send(:current_account).oai_admin_email }, - sample_id: ->(controller) { controller.send(:current_account).oai_sample_identifier } + admin_email: ->(controller) { controller.send(:current_account).oai_admin_email }, + sample_id: ->(controller) { controller.send(:current_account).oai_sample_identifier } }, document: { limit: 100, # number of records returned with each request, default: 15 diff --git a/app/controllers/concerns/hyrax/admin/users_controller_behavior.rb b/app/controllers/concerns/hyrax/admin/users_controller_behavior.rb index cd4d075e9..8b15f9e23 100644 --- a/app/controllers/concerns/hyrax/admin/users_controller_behavior.rb +++ b/app/controllers/concerns/hyrax/admin/users_controller_behavior.rb @@ -30,11 +30,11 @@ def index private - # OVERRIDE Hyrax v3.4.2 Replace :ensure_admin! with :ensure_access! to leverage User abilities. - # @see app/models/concerns/hyrax/ability/user_ability.rb - def ensure_access! - authorize! :read, ::User - end + # OVERRIDE Hyrax v3.4.2 Replace :ensure_admin! with :ensure_access! to leverage User abilities. + # @see app/models/concerns/hyrax/ability/user_ability.rb + def ensure_access! + authorize! :read, ::User + end end end end diff --git a/app/controllers/concerns/hyrax/users_controller_decorator.rb b/app/controllers/concerns/hyrax/users_controller_decorator.rb index 98f6ca53e..bdbc358bc 100644 --- a/app/controllers/concerns/hyrax/users_controller_decorator.rb +++ b/app/controllers/concerns/hyrax/users_controller_decorator.rb @@ -11,28 +11,28 @@ module UsersControllerDecorator private - def users_match! - # The #find_user method is a :before_action on the Hyrax::UsersController. It sets - # the @user variable, which we need in this method. - # - # However, because we are decorating Hyrax::UsersController with this module, - # this method's :before_action will fire before the one that calls #find_user. - # This means that #find_user will fire a second time after this method runs. - # - # This is not ideal, but after discussing with @jeremyf, we decided that this is - # the "lesser evil" compared to other override methods (i.e. using #class_eval, - # overriding the entire file, etc.); since User is an ActiveRecord object, the - # database query that sets @user in #find_user will be cached. - # - # Classes that inherit from Hyrax::UsersController do not have this problem - # (e.g. Hyrax::Dashboard::ProfilesController), which is why we check for presence. - find_user if @user.blank? + def users_match! + # The #find_user method is a :before_action on the Hyrax::UsersController. It sets + # the @user variable, which we need in this method. + # + # However, because we are decorating Hyrax::UsersController with this module, + # this method's :before_action will fire before the one that calls #find_user. + # This means that #find_user will fire a second time after this method runs. + # + # This is not ideal, but after discussing with @jeremyf, we decided that this is + # the "lesser evil" compared to other override methods (i.e. using #class_eval, + # overriding the entire file, etc.); since User is an ActiveRecord object, the + # database query that sets @user in #find_user will be cached. + # + # Classes that inherit from Hyrax::UsersController do not have this problem + # (e.g. Hyrax::Dashboard::ProfilesController), which is why we check for presence. + find_user if @user.blank? - return if can?(:read, @user) - return if current_user == @user + return if can?(:read, @user) + return if current_user == @user - raise CanCan::AccessDenied - end + raise CanCan::AccessDenied + end end end diff --git a/app/controllers/concerns/hyrax/works_controller_behavior.rb b/app/controllers/concerns/hyrax/works_controller_behavior.rb index f5b51f64f..a8f9fa914 100644 --- a/app/controllers/concerns/hyrax/works_controller_behavior.rb +++ b/app/controllers/concerns/hyrax/works_controller_behavior.rb @@ -147,375 +147,375 @@ def json_manifest private - def iiif_manifest_presenter - IiifManifestPresenter.new(search_result_document(id: params[:id])).tap do |p| - p.hostname = request.hostname - p.ability = current_ability - end + def iiif_manifest_presenter + IiifManifestPresenter.new(search_result_document(id: params[:id])).tap do |p| + p.hostname = request.hostname + p.ability = current_ability end + end - def user_collections - collections_service.search_results(:deposit) - end + def user_collections + collections_service.search_results(:deposit) + end - def collections_service - Hyrax::CollectionsService.new(self) - end + def collections_service + Hyrax::CollectionsService.new(self) + end - def admin_set_id_for_new - Hyrax::AdminSetCreateService.find_or_create_default_admin_set.id.to_s - end + def admin_set_id_for_new + Hyrax::AdminSetCreateService.find_or_create_default_admin_set.id.to_s + end - def build_form - @form = work_form_service.build(curation_concern, current_ability, self) - end + def build_form + @form = work_form_service.build(curation_concern, current_ability, self) + end - def actor - @actor ||= Hyrax::CurationConcern.actor - end + def actor + @actor ||= Hyrax::CurationConcern.actor + end - ## - # @return [#errors] - def create_valkyrie_work - form = build_form - return after_create_error(form_err_msg(form)) unless form.validate(params[hash_key_for_curation_concern]) - - result = - transactions['change_set.create_work'] - .with_step_args( - 'work_resource.add_to_parent' => { parent_id: params[:parent_id], user: current_user }, - 'work_resource.add_file_sets' => { uploaded_files: uploaded_files, file_set_params: params[hash_key_for_curation_concern][:file_set] }, - 'change_set.set_user_as_depositor' => { user: current_user }, - 'work_resource.change_depositor' => { user: ::User.find_by_user_key(form.on_behalf_of) } - ) - .call(form) - @curation_concern = result.value_or { return after_create_error(transaction_err_msg(result)) } - after_create_response - end + ## + # @return [#errors] + def create_valkyrie_work + form = build_form + return after_create_error(form_err_msg(form)) unless form.validate(params[hash_key_for_curation_concern]) + + result = + transactions['change_set.create_work'] + .with_step_args( + 'work_resource.add_to_parent' => { parent_id: params[:parent_id], user: current_user }, + 'work_resource.add_file_sets' => { uploaded_files: uploaded_files, file_set_params: params[hash_key_for_curation_concern][:file_set] }, + 'change_set.set_user_as_depositor' => { user: current_user }, + 'work_resource.change_depositor' => { user: ::User.find_by_user_key(form.on_behalf_of) } + ) + .call(form) + @curation_concern = result.value_or { return after_create_error(transaction_err_msg(result)) } + after_create_response + end - def update_valkyrie_work - form = build_form - return after_update_error(form_err_msg(form)) unless form.validate(params[hash_key_for_curation_concern]) - result = - transactions['change_set.update_work'] - .with_step_args('work_resource.add_file_sets' => { uploaded_files: uploaded_files, file_set_params: params[hash_key_for_curation_concern][:file_set] }, - 'work_resource.update_work_members' => { work_members_attributes: work_members_attributes }) - .call(form) - @curation_concern = result.value_or { return after_update_error(transaction_err_msg(result)) } - after_update_response - end + def update_valkyrie_work + form = build_form + return after_update_error(form_err_msg(form)) unless form.validate(params[hash_key_for_curation_concern]) + result = + transactions['change_set.update_work'] + .with_step_args('work_resource.add_file_sets' => { uploaded_files: uploaded_files, file_set_params: params[hash_key_for_curation_concern][:file_set] }, + 'work_resource.update_work_members' => { work_members_attributes: work_members_attributes }) + .call(form) + @curation_concern = result.value_or { return after_update_error(transaction_err_msg(result)) } + after_update_response + end - def work_members_attributes - params[hash_key_for_curation_concern][:work_members_attributes]&.permit!&.to_h - end + def work_members_attributes + params[hash_key_for_curation_concern][:work_members_attributes]&.permit!&.to_h + end - def form_err_msg(form) - form.errors.messages.values.flatten.to_sentence - end + def form_err_msg(form) + form.errors.messages.values.flatten.to_sentence + end - def transaction_err_msg(result) - result.failure.first - end + def transaction_err_msg(result) + result.failure.first + end - def presenter - @presenter ||= show_presenter.new(search_result_document(id: params[:id]), current_ability, request) - end + def presenter + @presenter ||= show_presenter.new(search_result_document(id: params[:id]), current_ability, request) + end - def parent_presenter - return @parent_presenter unless params[:parent_id] + def parent_presenter + return @parent_presenter unless params[:parent_id] - @parent_presenter ||= - show_presenter.new(search_result_document(id: params[:parent_id]), current_ability, request) - end + @parent_presenter ||= + show_presenter.new(search_result_document(id: params[:parent_id]), current_ability, request) + end - # Include 'hyrax/base' in the search path for views, while prefering - # our local paths. Thus we are unable to just override `self.local_prefixes` - def _prefixes - @_prefixes ||= super + ['hyrax/base'] - end + # Include 'hyrax/base' in the search path for views, while prefering + # our local paths. Thus we are unable to just override `self.local_prefixes` + def _prefixes + @_prefixes ||= super + ['hyrax/base'] + end - def actor_environment - Actors::Environment.new(curation_concern, current_ability, attributes_for_actor) - end + def actor_environment + Actors::Environment.new(curation_concern, current_ability, attributes_for_actor) + end - def hash_key_for_curation_concern - _curation_concern_type.model_name.param_key - end + def hash_key_for_curation_concern + _curation_concern_type.model_name.param_key + end - def contextual_path(presenter, parent_presenter) - ::Hyrax::ContextualPath.new(presenter, parent_presenter).show - end + def contextual_path(presenter, parent_presenter) + ::Hyrax::ContextualPath.new(presenter, parent_presenter).show + end - # @deprecated - def curation_concern_from_search_results - Deprecation.warn("'##{__method__}' will be removed in Hyrax 4.0. " \ - "Instead, use '#search_result_document'.") - search_params = params.deep_dup - search_params.delete :page - search_result_document(search_params) - end + # @deprecated + def curation_concern_from_search_results + Deprecation.warn("'##{__method__}' will be removed in Hyrax 4.0. " \ + "Instead, use '#search_result_document'.") + search_params = params.deep_dup + search_params.delete :page + search_result_document(search_params) + end - ## - # Only returns unsuppressed documents the user has read access to - # - # @api public - # - # @param search_params [ActionController::Parameters] this should - # include an :id key, but based on implementation and use of the - # WorkSearchBuilder, it need not. - # - # @return [SolrDocument] - # - # @raise [WorkflowAuthorizationException] when the object is not - # found via the search builder's search logic BUT the object is - # suppressed AND the user can read it (Yeah, it's confusing but - # after a lot of debugging that's the logic) - # - # @raise [CanCan::AccessDenied] when the object is not found via - # the search builder's search logic BUT the object is not - # supressed OR not readable by the user (Yeah.) - # - # @note This is Jeremy, I have suspicions about the first line of - # this comment (eg, "Only return unsuppressed..."). The - # reason is that I've encounter situations in the specs - # where the document_list is empty but if I then query Solr - # for the object by ID, I get a document that is NOT - # suppressed AND can be read. In other words, I believe - # there is more going on in the search_results method - # (e.g. a filter is being applied that is beyond what the - # comment indicates) - # - # @see #document_not_found! - def search_result_document(search_params) - _, document_list = search_results(search_params) - return document_list.first unless document_list.empty? - document_not_found! - end + ## + # Only returns unsuppressed documents the user has read access to + # + # @api public + # + # @param search_params [ActionController::Parameters] this should + # include an :id key, but based on implementation and use of the + # WorkSearchBuilder, it need not. + # + # @return [SolrDocument] + # + # @raise [WorkflowAuthorizationException] when the object is not + # found via the search builder's search logic BUT the object is + # suppressed AND the user can read it (Yeah, it's confusing but + # after a lot of debugging that's the logic) + # + # @raise [CanCan::AccessDenied] when the object is not found via + # the search builder's search logic BUT the object is not + # supressed OR not readable by the user (Yeah.) + # + # @note This is Jeremy, I have suspicions about the first line of + # this comment (eg, "Only return unsuppressed..."). The + # reason is that I've encounter situations in the specs + # where the document_list is empty but if I then query Solr + # for the object by ID, I get a document that is NOT + # suppressed AND can be read. In other words, I believe + # there is more going on in the search_results method + # (e.g. a filter is being applied that is beyond what the + # comment indicates) + # + # @see #document_not_found! + def search_result_document(search_params) + _, document_list = search_results(search_params) + return document_list.first unless document_list.empty? + document_not_found! + end - def document_not_found! - doc = ::SolrDocument.find(params[:id]) - raise WorkflowAuthorizationException if doc.suppressed? && current_ability.can?(:read, doc) - raise CanCan::AccessDenied.new(nil, :show) - end + def document_not_found! + doc = ::SolrDocument.find(params[:id]) + raise WorkflowAuthorizationException if doc.suppressed? && current_ability.can?(:read, doc) + raise CanCan::AccessDenied.new(nil, :show) + end - def render_unavailable - message = I18n.t("hyrax.workflow.unauthorized") - respond_to do |wants| - wants.html do - unavailable_presenter - flash[:notice] = message - render 'unavailable', status: :unauthorized - end - wants.json { render plain: message, status: :unauthorized } - additional_response_formats(wants) - wants.ttl { render plain: message, status: :unauthorized } - wants.jsonld { render plain: message, status: :unauthorized } - wants.nt { render plain: message, status: :unauthorized } + def render_unavailable + message = I18n.t("hyrax.workflow.unauthorized") + respond_to do |wants| + wants.html do + unavailable_presenter + flash[:notice] = message + render 'unavailable', status: :unauthorized end + wants.json { render plain: message, status: :unauthorized } + additional_response_formats(wants) + wants.ttl { render plain: message, status: :unauthorized } + wants.jsonld { render plain: message, status: :unauthorized } + wants.nt { render plain: message, status: :unauthorized } end + end - def unavailable_presenter - @presenter ||= show_presenter.new(::SolrDocument.find(params[:id]), current_ability, request) - end + def unavailable_presenter + @presenter ||= show_presenter.new(::SolrDocument.find(params[:id]), current_ability, request) + end - def decide_layout - layout = case action_name - when 'show' - '1_column' - else - 'dashboard' - end - File.join(theme, layout) - end + def decide_layout + layout = case action_name + when 'show' + '1_column' + else + 'dashboard' + end + File.join(theme, layout) + end - ## - # @todo should the controller know so much about browse_everything? - # hopefully this can be refactored to be more reusable. - # - # Add uploaded_files to the parameters received by the actor. - def attributes_for_actor - raw_params = params[hash_key_for_curation_concern] - attributes = if raw_params - work_form_service.form_class(curation_concern).model_attributes(raw_params) - else - {} - end - - # If they selected a BrowseEverything file, but then clicked the - # remove button, it will still show up in `selected_files`, but - # it will no longer be in uploaded_files. By checking the - # intersection, we get the files they added via BrowseEverything - # that they have not removed from the upload widget. - uploaded_files = params.fetch(:uploaded_files, []) - selected_files = params.fetch(:selected_files, {}).values - browse_everything_urls = uploaded_files & - selected_files.map { |f| f[:url] } - - # we need the hash of files with url and file_name - browse_everything_files = selected_files - .select { |v| uploaded_files.include?(v[:url]) } - attributes[:remote_files] = browse_everything_files - # Strip out any BrowseEverthing files from the regular uploads. - attributes[:uploaded_files] = uploaded_files - - browse_everything_urls - attributes - end + ## + # @todo should the controller know so much about browse_everything? + # hopefully this can be refactored to be more reusable. + # + # Add uploaded_files to the parameters received by the actor. + def attributes_for_actor + raw_params = params[hash_key_for_curation_concern] + attributes = if raw_params + work_form_service.form_class(curation_concern).model_attributes(raw_params) + else + {} + end + + # If they selected a BrowseEverything file, but then clicked the + # remove button, it will still show up in `selected_files`, but + # it will no longer be in uploaded_files. By checking the + # intersection, we get the files they added via BrowseEverything + # that they have not removed from the upload widget. + uploaded_files = params.fetch(:uploaded_files, []) + selected_files = params.fetch(:selected_files, {}).values + browse_everything_urls = uploaded_files & + selected_files.map { |f| f[:url] } + + # we need the hash of files with url and file_name + browse_everything_files = selected_files + .select { |v| uploaded_files.include?(v[:url]) } + attributes[:remote_files] = browse_everything_files + # Strip out any BrowseEverthing files from the regular uploads. + attributes[:uploaded_files] = uploaded_files - + browse_everything_urls + attributes + end - def after_create_response - respond_to do |wants| - wants.html do - # Calling `#t` in a controller context does not mark _html keys as html_safe - flash[:notice] = view_context.t('hyrax.works.create.after_create_html', application_name: view_context.application_name) + def after_create_response + respond_to do |wants| + wants.html do + # Calling `#t` in a controller context does not mark _html keys as html_safe + flash[:notice] = view_context.t('hyrax.works.create.after_create_html', application_name: view_context.application_name) - redirect_to [main_app, curation_concern] - end - wants.json { render :show, status: :created, location: polymorphic_path([main_app, curation_concern]) } + redirect_to [main_app, curation_concern] end + wants.json { render :show, status: :created, location: polymorphic_path([main_app, curation_concern]) } end + end - def format_error_messages(errors) - errors.messages.map do |field, messages| - field_name = field.to_s.humanize - messages.map { |message| "#{field_name} #{message.sub(/^./, &:downcase)}" } - end.flatten.join("\n") - end + def format_error_messages(errors) + errors.messages.map do |field, messages| + field_name = field.to_s.humanize + messages.map { |message| "#{field_name} #{message.sub(/^./, &:downcase)}" } + end.flatten.join("\n") + end - def after_create_error(errors, original_input_params_for_form = nil) - respond_to do |wants| - wants.html do - flash[:error] = format_error_messages(errors) - rebuild_form(original_input_params_for_form) if original_input_params_for_form.present? - render 'new', status: :unprocessable_entity - end - wants.json { render_json_response(response_type: :unprocessable_entity, options: { errors: errors }) } + def after_create_error(errors, original_input_params_for_form = nil) + respond_to do |wants| + wants.html do + flash[:error] = format_error_messages(errors) + rebuild_form(original_input_params_for_form) if original_input_params_for_form.present? + render 'new', status: :unprocessable_entity end + wants.json { render_json_response(response_type: :unprocessable_entity, options: { errors: errors }) } end + end - # Creating a form object that can re-render most of the submitted parameters. - # Required for ActiveFedora::Base objects only. - def rebuild_form(original_input_params_for_form) - build_form - @form = Hyrax::Forms::FailedSubmissionFormWrapper - .new(form: @form, - input_params: original_input_params_for_form) - end - - def after_update_response - return redirect_to hyrax.confirm_access_permission_path(curation_concern) if permissions_changed? && concern_has_file_sets? + # Creating a form object that can re-render most of the submitted parameters. + # Required for ActiveFedora::Base objects only. + def rebuild_form(original_input_params_for_form) + build_form + @form = Hyrax::Forms::FailedSubmissionFormWrapper + .new(form: @form, + input_params: original_input_params_for_form) + end - respond_to do |wants| - wants.html { redirect_to [main_app, curation_concern], notice: "Work \"#{curation_concern}\" successfully updated." } - wants.json { render :show, status: :ok, location: polymorphic_path([main_app, curation_concern]) } - end - end + def after_update_response + return redirect_to hyrax.confirm_access_permission_path(curation_concern) if permissions_changed? && concern_has_file_sets? - def after_update_error(errors) - respond_to do |wants| - wants.html do - flash[:error] = format_error_messages(errors) - build_form unless @form.is_a? Hyrax::ChangeSet - render 'edit', status: :unprocessable_entity - end - wants.json { render_json_response(response_type: :unprocessable_entity, options: { errors: errors }) } - end + respond_to do |wants| + wants.html { redirect_to [main_app, curation_concern], notice: "Work \"#{curation_concern}\" successfully updated." } + wants.json { render :show, status: :ok, location: polymorphic_path([main_app, curation_concern]) } end + end - def after_destroy_response(title) - respond_to do |wants| - wants.html { redirect_to hyrax.my_works_path, notice: "Deleted #{title}" } - wants.json { render_json_response(response_type: :deleted, message: "Deleted #{curation_concern.id}") } + def after_update_error(errors) + respond_to do |wants| + wants.html do + flash[:error] = format_error_messages(errors) + build_form unless @form.is_a? Hyrax::ChangeSet + render 'edit', status: :unprocessable_entity end + wants.json { render_json_response(response_type: :unprocessable_entity, options: { errors: errors }) } end + end - def additional_response_formats(format) - format.endnote do - send_data(presenter.solr_document.export_as_endnote, - type: "application/x-endnote-refer", - filename: presenter.solr_document.endnote_filename) - end + def after_destroy_response(title) + respond_to do |wants| + wants.html { redirect_to hyrax.my_works_path, notice: "Deleted #{title}" } + wants.json { render_json_response(response_type: :deleted, message: "Deleted #{curation_concern.id}") } end + end - def save_permissions - @saved_permissions = - case curation_concern - when ActiveFedora::Base - curation_concern.permissions.map(&:to_hash) - else - Hyrax::AccessControl.for(resource: curation_concern).permissions - end + def additional_response_formats(format) + format.endnote do + send_data(presenter.solr_document.export_as_endnote, + type: "application/x-endnote-refer", + filename: presenter.solr_document.endnote_filename) end + end - def permissions_changed? - @saved_permissions != - case curation_concern - when ActiveFedora::Base - curation_concern.permissions.map(&:to_hash) - else - Hyrax::AccessControl.for(resource: curation_concern).permissions - end - end + def save_permissions + @saved_permissions = + case curation_concern + when ActiveFedora::Base + curation_concern.permissions.map(&:to_hash) + else + Hyrax::AccessControl.for(resource: curation_concern).permissions + end + end - def concern_has_file_sets? + def permissions_changed? + @saved_permissions != case curation_concern - when ActiveFedora::Common - curation_concern.file_sets.present? + when ActiveFedora::Base + curation_concern.permissions.map(&:to_hash) else - Hyrax.custom_queries.find_child_file_set_ids(resource: curation_concern).any? + Hyrax::AccessControl.for(resource: curation_concern).permissions end - end + end - def uploaded_files - UploadedFile.find(params.fetch(:uploaded_files, [])) + def concern_has_file_sets? + case curation_concern + when ActiveFedora::Common + curation_concern.file_sets.present? + else + Hyrax.custom_queries.find_child_file_set_ids(resource: curation_concern).any? end + end - def available_admin_sets - # only returns admin sets in which the user can deposit - admin_set_results = Hyrax::AdminSetService.new(self).search_results(:deposit) - - # get all the templates at once, reducing query load - templates = PermissionTemplate.where(source_id: admin_set_results.map(&:id)).to_a - - admin_sets = admin_set_results.map do |admin_set_doc| - template = templates.find { |temp| temp.source_id == admin_set_doc.id.to_s } - - ## OVERRIDE Hyrax v3.4.2 - # Removes a short-circuit that allowed users with manage access to - # the given permission_template to always be able to edit a record's sharing - # (i.e. the "Sharing" tab in forms). - # - # We remove this because there is currently a bug in Hyrax where, if the - # workflow does not allow access grants, changes to a record's sharing - # are not being persisted, leading to a confusing UX. - # @see https://github.com/samvera/hyrax/issues/5904 - # - # TEMPORARY: This override should be removed when the bug is resolved in - # upstream Hyrax and brought into this project. - # - # determine if sharing tab should be visible - sharing = !!template&.active_workflow&.allows_access_grant? # rubocop:disable Style/DoubleNegation - - AdminSetSelectionPresenter::OptionsEntry - .new(admin_set: admin_set_doc, permission_template: template, permit_sharing: sharing) - end + def uploaded_files + UploadedFile.find(params.fetch(:uploaded_files, [])) + end - AdminSetSelectionPresenter.new(admin_sets: admin_sets) - end + def available_admin_sets + # only returns admin sets in which the user can deposit + admin_set_results = Hyrax::AdminSetService.new(self).search_results(:deposit) + + # get all the templates at once, reducing query load + templates = PermissionTemplate.where(source_id: admin_set_results.map(&:id)).to_a + + admin_sets = admin_set_results.map do |admin_set_doc| + template = templates.find { |temp| temp.source_id == admin_set_doc.id.to_s } + + ## OVERRIDE Hyrax v3.4.2 + # Removes a short-circuit that allowed users with manage access to + # the given permission_template to always be able to edit a record's sharing + # (i.e. the "Sharing" tab in forms). + # + # We remove this because there is currently a bug in Hyrax where, if the + # workflow does not allow access grants, changes to a record's sharing + # are not being persisted, leading to a confusing UX. + # @see https://github.com/samvera/hyrax/issues/5904 + # + # TEMPORARY: This override should be removed when the bug is resolved in + # upstream Hyrax and brought into this project. + # + # determine if sharing tab should be visible + sharing = !!template&.active_workflow&.allows_access_grant? # rubocop:disable Style/DoubleNegation + + AdminSetSelectionPresenter::OptionsEntry + .new(admin_set: admin_set_doc, permission_template: template, permit_sharing: sharing) + end + + AdminSetSelectionPresenter.new(admin_sets: admin_sets) + end - # added to prepend the show theme views into the view_paths - def inject_show_theme_views - if show_page_theme && show_page_theme != 'default_show' - original_paths = view_paths - show_theme_view_path = Rails.root.join('app', 'views', "themes", show_page_theme.to_s) - prepend_view_path(show_theme_view_path) - yield - # rubocop:disable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses - # Do NOT change this line. This is calling the Rails view_paths=(paths) method and not a variable assignment. - view_paths=(original_paths) - # rubocop:enable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses - else - yield - end + # added to prepend the show theme views into the view_paths + def inject_show_theme_views + if show_page_theme && show_page_theme != 'default_show' + original_paths = view_paths + show_theme_view_path = Rails.root.join('app', 'views', "themes", show_page_theme.to_s) + prepend_view_path(show_theme_view_path) + yield + # rubocop:disable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses + # Do NOT change this line. This is calling the Rails view_paths=(paths) method and not a variable assignment. + view_paths=(original_paths) + # rubocop:enable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses + else + yield end + end end end # rubocop:enable Metrics/ModuleLength diff --git a/app/controllers/hyku/invitations_controller.rb b/app/controllers/hyku/invitations_controller.rb index 2aa11fcac..e08ae7b1a 100644 --- a/app/controllers/hyku/invitations_controller.rb +++ b/app/controllers/hyku/invitations_controller.rb @@ -20,9 +20,7 @@ def create yield resource if block_given? # Override destination as this was a success either way - if is_flashing_format? && resource.invitation_sent_at - set_flash_message :notice, :send_instructions, email: resource.email - end + set_flash_message :notice, :send_instructions, email: resource.email if is_flashing_format? && resource.invitation_sent_at if method(:after_invite_path_for).arity == 1 respond_with resource, location: after_invite_path_for(current_inviter) else @@ -32,8 +30,8 @@ def create protected - def user_params - params.require(:user).permit(:email, :role) - end + def user_params + params.require(:user).permit(:email, :role) + end end end diff --git a/app/controllers/hyku/registrations_controller.rb b/app/controllers/hyku/registrations_controller.rb index fe9a9422a..758cf0afb 100644 --- a/app/controllers/hyku/registrations_controller.rb +++ b/app/controllers/hyku/registrations_controller.rb @@ -15,8 +15,8 @@ def create private - def configure_permitted_parameters - devise_parameter_sanitizer.permit(:sign_up, keys: [:display_name]) - end + def configure_permitted_parameters + devise_parameter_sanitizer.permit(:sign_up, keys: [:display_name]) + end end end diff --git a/app/controllers/hyrax/admin/appearances_controller.rb b/app/controllers/hyrax/admin/appearances_controller.rb index 9130b8b11..dbd0abf41 100644 --- a/app/controllers/hyrax/admin/appearances_controller.rb +++ b/app/controllers/hyrax/admin/appearances_controller.rb @@ -44,47 +44,47 @@ def update private - def update_params - params.require(:admin_appearance).permit(form_class.permitted_params) - end + def update_params + params.require(:admin_appearance).permit(form_class.permitted_params) + end - def require_permissions - authorize! :update, :appearance - end + def require_permissions + authorize! :update, :appearance + end - def add_breadcrumbs - add_breadcrumb t(:'hyrax.controls.home'), root_path - add_breadcrumb t(:'hyrax.dashboard.breadcrumbs.admin'), hyrax.dashboard_path - add_breadcrumb t(:'hyrax.admin.sidebar.configuration'), '#' - add_breadcrumb t(:'hyrax.admin.sidebar.appearance'), request.path - end + def add_breadcrumbs + add_breadcrumb t(:'hyrax.controls.home'), root_path + add_breadcrumb t(:'hyrax.dashboard.breadcrumbs.admin'), hyrax.dashboard_path + add_breadcrumb t(:'hyrax.admin.sidebar.configuration'), '#' + add_breadcrumb t(:'hyrax.admin.sidebar.appearance'), request.path + end - def load_home_theme_names - home_theme_names = [] - @home_theme_information.each do |theme, value_hash| - value_hash.each do |key, value| - home_theme_names << [value, theme] if key == 'name' - end + def load_home_theme_names + home_theme_names = [] + @home_theme_information.each do |theme, value_hash| + value_hash.each do |key, value| + home_theme_names << [value, theme] if key == 'name' end - home_theme_names end + home_theme_names + end - def load_show_theme_names - show_theme_names = [] - @show_theme_information.each do |theme, value_hash| - value_hash.each do |key, value| - show_theme_names << [value, theme] if key == 'name' - end + def load_show_theme_names + show_theme_names = [] + @show_theme_information.each do |theme, value_hash| + value_hash.each do |key, value| + show_theme_names << [value, theme] if key == 'name' end - show_theme_names end + show_theme_names + end - def load_search_themes - { - 'List view' => 'list_view', - 'Gallery view' => 'gallery_view' - } - end + def load_search_themes + { + 'List view' => 'list_view', + 'Gallery view' => 'gallery_view' + } + end end end end diff --git a/app/controllers/hyrax/admin/workflow_roles_controller.rb b/app/controllers/hyrax/admin/workflow_roles_controller.rb index 9e388f66e..a82fabcad 100644 --- a/app/controllers/hyrax/admin/workflow_roles_controller.rb +++ b/app/controllers/hyrax/admin/workflow_roles_controller.rb @@ -43,9 +43,9 @@ def create private - def require_permissions - authorize! :read, :admin_dashboard - end + def require_permissions + authorize! :read, :admin_dashboard + end end end end diff --git a/app/controllers/hyrax/contact_form_controller.rb b/app/controllers/hyrax/contact_form_controller.rb index a420f82d4..c88b44ac3 100644 --- a/app/controllers/hyrax/contact_form_controller.rb +++ b/app/controllers/hyrax/contact_form_controller.rb @@ -79,53 +79,53 @@ def after_deliver; end private - def build_contact_form - @contact_form = model_class.new(contact_form_params) - end + def build_contact_form + @contact_form = model_class.new(contact_form_params) + end - def contact_form_params - return {} unless params.key?(:contact_form) - params.require(:contact_form).permit(:contact_method, :category, :name, :email, :subject, :message) - end + def contact_form_params + return {} unless params.key?(:contact_form) + params.require(:contact_form).permit(:contact_method, :category, :name, :email, :subject, :message) + end - # OVERRIDE: return collections for theming - def collections(rows: 6) - builder = Hyrax::CollectionSearchBuilder.new(self) - .rows(rows) - response = repository.search(builder) - response.documents - rescue Blacklight::Exceptions::ECONNREFUSED, Blacklight::Exceptions::InvalidRequest - [] - end + # OVERRIDE: return collections for theming + def collections(rows: 6) + builder = Hyrax::CollectionSearchBuilder.new(self) + .rows(rows) + response = repository.search(builder) + response.documents + rescue Blacklight::Exceptions::ECONNREFUSED, Blacklight::Exceptions::InvalidRequest + [] + end - # OVERRIDE: Adding to prepend the theme views into the view_paths - def inject_theme_views - if home_page_theme && home_page_theme != 'default_home' - original_paths = view_paths - home_theme_view_path = Rails.root.join('app', 'views', "themes", home_page_theme.to_s) - prepend_view_path(home_theme_view_path) - yield - # rubocop:disable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses - # Do NOT change this line. This is calling the Rails view_paths=(paths) method and not a variable assignment. - view_paths=(original_paths) - # rubocop:enable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses - else - yield - end + # OVERRIDE: Adding to prepend the theme views into the view_paths + def inject_theme_views + if home_page_theme && home_page_theme != 'default_home' + original_paths = view_paths + home_theme_view_path = Rails.root.join('app', 'views', "themes", home_page_theme.to_s) + prepend_view_path(home_theme_view_path) + yield + # rubocop:disable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses + # Do NOT change this line. This is calling the Rails view_paths=(paths) method and not a variable assignment. + view_paths=(original_paths) + # rubocop:enable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses + else + yield end + end - def setup_negative_captcha - @captcha = NegativeCaptcha.new( - # A secret key entered in environment.rb. 'rake secret' will give you a good one. - secret: ENV.fetch('NEGATIVE_CAPTCHA_SECRET', 'default-value-change-me'), - spinner: request.remote_ip, - # Whatever fields are in your form - fields: %i[name email subject message], - # If you wish to override the default CSS styles (position: absolute; left: -2000px;) - # used to position the fields off-screen - css: "display: none", - params: params - ) - end + def setup_negative_captcha + @captcha = NegativeCaptcha.new( + # A secret key entered in environment.rb. 'rake secret' will give you a good one. + secret: ENV.fetch('NEGATIVE_CAPTCHA_SECRET', 'default-value-change-me'), + spinner: request.remote_ip, + # Whatever fields are in your form + fields: %i[name email subject message], + # If you wish to override the default CSS styles (position: absolute; left: -2000px;) + # used to position the fields off-screen + css: "display: none", + params: params + ) + end end end diff --git a/app/controllers/hyrax/dashboard/collections_controller.rb b/app/controllers/hyrax/dashboard/collections_controller.rb index 762252645..67e9de1ec 100644 --- a/app/controllers/hyrax/dashboard/collections_controller.rb +++ b/app/controllers/hyrax/dashboard/collections_controller.rb @@ -46,8 +46,8 @@ class CollectionsController < Hyrax::My::CollectionsController self.membership_service_class = Collections::CollectionMemberSearchService load_and_authorize_resource except: [:index, :create], - instance_name: :collection, - class: Hyrax.config.collection_model + instance_name: :collection, + class: Hyrax.config.collection_model def deny_collection_access(exception) if exception.action == :edit @@ -147,7 +147,7 @@ def update def process_branding process_banner_input process_logo_input - # TODO does this still work? + # TODO: does this still work? process_uploaded_thumbnail(params[:collection][:thumbnail_upload]) if params[:collection][:thumbnail_upload] end @@ -215,7 +215,9 @@ def files work_with_no_files_thumbnail_path = ActionController::Base.helpers.image_path('work.png') response = repository.search(builder.where(params[:q]).query) # only return the works that have files, because these will be the only ones with a viable thumbnail - result = response.documents.reject { |document| document["thumbnail_path_ss"].blank? || document["thumbnail_path_ss"].include?(default_work_thumbnail_path) || document["thumbnail_path_ss"].include?(work_with_no_files_thumbnail_path) }.map do |document| + result = response.documents.reject do |document| + document["thumbnail_path_ss"].blank? || document["thumbnail_path_ss"].include?(default_work_thumbnail_path) || document["thumbnail_path_ss"].include?(work_with_no_files_thumbnail_path) + end .map do |document| { id: document["thumbnail_path_ss"].split('/').last.gsub(/\?.*/, ''), text: document["title_tesim"].first } end reset_thumbnail_option = { @@ -276,14 +278,14 @@ def update_valkyrie_collection return after_update_errors(form_err_msg(form)) unless form.validate(collection_params) result = transactions['change_set.update_collection'] - .with_step_args( + .with_step_args( 'collection_resource.save_collection_banner' => { update_banner_file_ids: params["banner_files"], - banner_unchanged_indicator: params["banner_unchanged"] }, + banner_unchanged_indicator: params["banner_unchanged"] }, 'collection_resource.save_collection_logo' => { update_logo_file_ids: params["logo_files"], - alttext_values: params["alttext"], - linkurl_values: params["linkurl"] } + alttext_values: params["alttext"], + linkurl_values: params["linkurl"] } ) - .call(form) + .call(form) @collection = result.value_or { return after_update_errors(result.failure.first) } process_member_changes @@ -321,8 +323,8 @@ def collection_type def link_parent_collection(parent_id) child = collection.respond_to?(:valkyrie_resource) ? collection.valkyrie_resource : collection Hyrax::Collections::CollectionMemberService.add_member(collection_id: parent_id, - new_member: child, - user: current_user) + new_member: child, + user: current_user) end def uploaded_files(uploaded_file_ids) @@ -473,9 +475,9 @@ def collection_params form_class.model_attributes(params[:collection]) else params.permit(collection: {})[:collection] - .merge(params.permit(:collection_type_gid) + .merge(params.permit(:collection_type_gid) .with_defaults(collection_type_gid: default_collection_type_gid)) - .merge(member_of_collection_ids: Array(params[:parent_id])) + .merge(member_of_collection_ids: Array(params[:parent_id])) end end @@ -518,15 +520,15 @@ def add_members_to_collection(collection = nil, collection_id: nil) Hyrax::Collections::CollectionMemberService .add_members_by_ids(collection_id: collection_id, - new_member_ids: batch, - user: current_user) + new_member_ids: batch, + user: current_user) end def remove_members_from_collection Hyrax::Collections::CollectionMemberService .remove_members_by_ids(collection_id: @collection.id, - member_ids: batch, - user: current_user) + member_ids: batch, + user: current_user) end def move_members_between_collections @@ -704,10 +706,10 @@ def process_uploaded_thumbnail(uploaded_file) dir_name = UploadedCollectionThumbnailPathService.upload_dir(@collection) saved_file = Rails.root.join(dir_name, uploaded_file.original_filename) # Create directory if it doesn't already exist - unless File.directory?(dir_name) - FileUtils.mkdir_p(dir_name) - else # clear contents + if File.directory?(dir_name) # clear contents delete_uploaded_thumbnail + else + FileUtils.mkdir_p(dir_name) end File.open(saved_file, 'wb') do |file| file.write(uploaded_file.read) @@ -716,16 +718,16 @@ def process_uploaded_thumbnail(uploaded_file) # Save two versions of the image: one for homepage feature cards and one for regular thumbnail image.resize('500x900').format("jpg").write("#{dir_name}/#{@collection.id}_card.jpg") image.resize('150x300').format("jpg").write("#{dir_name}/#{@collection.id}_thumbnail.jpg") - File.chmod(0664,"#{dir_name}/#{@collection.id}_thumbnail.jpg") - File.chmod(0664,"#{dir_name}/#{@collection.id}_card.jpg") + File.chmod(0o664, "#{dir_name}/#{@collection.id}_thumbnail.jpg") + File.chmod(0o664, "#{dir_name}/#{@collection.id}_card.jpg") end ## OVERRIDE Hyrax 3.4.0 handle file locations def process_file_location(f) - if f.file_url =~ /^http/ + if /^http/.match?(f.file_url) f.file.download!(f.file_url) f.file_url - elsif f.file_url =~ %r{^\/} + elsif %r{^\/}.match?(f.file_url) f.file.path else f.file_url diff --git a/app/controllers/hyrax/featured_collection_lists_controller.rb b/app/controllers/hyrax/featured_collection_lists_controller.rb index 29a9e3802..d34251735 100644 --- a/app/controllers/hyrax/featured_collection_lists_controller.rb +++ b/app/controllers/hyrax/featured_collection_lists_controller.rb @@ -13,8 +13,8 @@ def create private - def list_params - params.require(:featured_collection_list).permit(featured_collections_attributes: %i[id order]) - end + def list_params + params.require(:featured_collection_list).permit(featured_collections_attributes: %i[id order]) + end end end diff --git a/app/controllers/hyrax/homepage_controller.rb b/app/controllers/hyrax/homepage_controller.rb index b9130eb9e..4039a14a3 100644 --- a/app/controllers/hyrax/homepage_controller.rb +++ b/app/controllers/hyrax/homepage_controller.rb @@ -91,57 +91,57 @@ def all_collections # Added from Blacklight 6.23.0 to change url for facets on home page protected - # Default route to the search action (used e.g. in global partials). Override this method - # in a controller or in your ApplicationController to introduce custom logic for choosing - # which action the search form should use - def search_action_url(options = {}) - # Rails 4.2 deprecated url helpers accepting string keys for 'controller' or 'action' - main_app.search_catalog_path(options) - end + # Default route to the search action (used e.g. in global partials). Override this method + # in a controller or in your ApplicationController to introduce custom logic for choosing + # which action the search form should use + def search_action_url(options = {}) + # Rails 4.2 deprecated url helpers accepting string keys for 'controller' or 'action' + main_app.search_catalog_path(options) + end private - # Return 6 collections - def collections(rows: 6) - builder = Hyrax::CollectionSearchBuilder.new(self) - .rows(rows) - response = repository.search(builder) - # adding .sort_by to return collections in alphabetical order by title on the homepage - response.documents.sort_by(&:title) - rescue Blacklight::Exceptions::ECONNREFUSED, Blacklight::Exceptions::InvalidRequest - [] - end + # Return 6 collections + def collections(rows: 6) + builder = Hyrax::CollectionSearchBuilder.new(self) + .rows(rows) + response = repository.search(builder) + # adding .sort_by to return collections in alphabetical order by title on the homepage + response.documents.sort_by(&:title) + rescue Blacklight::Exceptions::ECONNREFUSED, Blacklight::Exceptions::InvalidRequest + [] + end - def recent - # grab any recent documents - (_, @recent_documents) = search_results(q: '', sort: sort_field, rows: 6) - rescue Blacklight::Exceptions::ECONNREFUSED, Blacklight::Exceptions::InvalidRequest - @recent_documents = [] - end + def recent + # grab any recent documents + (_, @recent_documents) = search_results(q: '', sort: sort_field, rows: 6) + rescue Blacklight::Exceptions::ECONNREFUSED, Blacklight::Exceptions::InvalidRequest + @recent_documents = [] + end - def ir_counts - @ir_counts = get_facet_field_response('resource_type_sim', {}, "f.resource_type_sim.facet.limit" => "-1") - end + def ir_counts + @ir_counts = get_facet_field_response('resource_type_sim', {}, "f.resource_type_sim.facet.limit" => "-1") + end - # COPIED from Hyrax::HomepageController - def sort_field - "date_uploaded_dtsi desc" - end + # COPIED from Hyrax::HomepageController + def sort_field + "date_uploaded_dtsi desc" + end - # Add this method to prepend the theme views into the view_paths - def inject_theme_views - if home_page_theme && home_page_theme != 'default_home' - original_paths = view_paths - home_theme_view_path = Rails.root.join('app', 'views', "themes", home_page_theme.to_s) - prepend_view_path(home_theme_view_path) - yield - # rubocop:disable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses - # Do NOT change this line. This is calling the Rails view_paths=(paths) method and not a variable assignment. - view_paths=(original_paths) - # rubocop:enable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses - else - yield - end + # Add this method to prepend the theme views into the view_paths + def inject_theme_views + if home_page_theme && home_page_theme != 'default_home' + original_paths = view_paths + home_theme_view_path = Rails.root.join('app', 'views', "themes", home_page_theme.to_s) + prepend_view_path(home_theme_view_path) + yield + # rubocop:disable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses + # Do NOT change this line. This is calling the Rails view_paths=(paths) method and not a variable assignment. + view_paths=(original_paths) + # rubocop:enable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses + else + yield end + end end end diff --git a/app/controllers/hyrax/pages_controller.rb b/app/controllers/hyrax/pages_controller.rb index cdfd8d0a7..2c07c8e99 100644 --- a/app/controllers/hyrax/pages_controller.rb +++ b/app/controllers/hyrax/pages_controller.rb @@ -68,49 +68,49 @@ def update private - def permitted_params - params.require(:content_block).permit(:about, - :agreement, - :help, - :terms) - end + def permitted_params + params.require(:content_block).permit(:about, + :agreement, + :help, + :terms) + end - # When a request comes to the controller, it will be for one and - # only one of the content blocks. Params always looks like: - # {'about_page' => 'Here is an awesome about page!'} - # So reach into permitted params and pull out the first value. - def update_value_from_params - permitted_params.values.first - end + # When a request comes to the controller, it will be for one and + # only one of the content blocks. Params always looks like: + # {'about_page' => 'Here is an awesome about page!'} + # So reach into permitted params and pull out the first value. + def update_value_from_params + permitted_params.values.first + end - def pages_layout - action_name == 'show' ? 'homepage' : 'hyrax/dashboard' - end + def pages_layout + action_name == 'show' ? 'homepage' : 'hyrax/dashboard' + end - # OVERRIDE: return collections for theming - def collections(rows: 6) - builder = Hyrax::CollectionSearchBuilder.new(self) - .rows(rows) - response = repository.search(builder) - response.documents - rescue Blacklight::Exceptions::ECONNREFUSED, Blacklight::Exceptions::InvalidRequest - [] - end + # OVERRIDE: return collections for theming + def collections(rows: 6) + builder = Hyrax::CollectionSearchBuilder.new(self) + .rows(rows) + response = repository.search(builder) + response.documents + rescue Blacklight::Exceptions::ECONNREFUSED, Blacklight::Exceptions::InvalidRequest + [] + end - # OVERRIDE: Adding to prepend the theme views into the view_paths - def inject_theme_views - if home_page_theme && home_page_theme != 'default_home' - original_paths = view_paths - home_theme_view_path = Rails.root.join('app', 'views', "themes", home_page_theme.to_s) - prepend_view_path(home_theme_view_path) - yield - # rubocop:disable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses - # Do NOT change this method. This is an override of the view_paths= method and not a variable assignment. - view_paths=(original_paths) - # rubocop:enable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses - else - yield - end + # OVERRIDE: Adding to prepend the theme views into the view_paths + def inject_theme_views + if home_page_theme && home_page_theme != 'default_home' + original_paths = view_paths + home_theme_view_path = Rails.root.join('app', 'views', "themes", home_page_theme.to_s) + prepend_view_path(home_theme_view_path) + yield + # rubocop:disable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses + # Do NOT change this method. This is an override of the view_paths= method and not a variable assignment. + view_paths=(original_paths) + # rubocop:enable Lint/UselessAssignment, Layout/SpaceAroundOperators, Style/RedundantParentheses + else + yield end + end end end diff --git a/app/controllers/identity_providers_controller.rb b/app/controllers/identity_providers_controller.rb index 28774a0bc..06cedfb20 100644 --- a/app/controllers/identity_providers_controller.rb +++ b/app/controllers/identity_providers_controller.rb @@ -72,27 +72,27 @@ def add_breadcrumbs private - # Use callbacks to share common setup or constraints between actions. - def set_identity_provider - @identity_provider = IdentityProvider.find(params[:id]) - end + # Use callbacks to share common setup or constraints between actions. + def set_identity_provider + @identity_provider = IdentityProvider.find(params[:id]) + end - def ensure_admin! - authorize! :read, :admin_dashboard - end + def ensure_admin! + authorize! :read, :admin_dashboard + end - # Only allow a list of trusted parameters through. - def identity_provider_params - return @identity_provider_params if @identity_provider_params - @identity_provider_params = params.require(:identity_provider).permit( - :name, - :provider, - :options, - :logo_image, - :logo_image_text - ) - @identity_provider_params['options'].presence && - @identity_provider_params['options'] = JSON.parse(@identity_provider_params['options']) - @identity_provider_params - end + # Only allow a list of trusted parameters through. + def identity_provider_params + return @identity_provider_params if @identity_provider_params + @identity_provider_params = params.require(:identity_provider).permit( + :name, + :provider, + :options, + :logo_image, + :logo_image_text + ) + @identity_provider_params['options'].presence && + @identity_provider_params['options'] = JSON.parse(@identity_provider_params['options']) + @identity_provider_params + end end diff --git a/app/controllers/labels_controller.rb b/app/controllers/labels_controller.rb index 7252920bf..df13a1fba 100644 --- a/app/controllers/labels_controller.rb +++ b/app/controllers/labels_controller.rb @@ -23,10 +23,10 @@ def update private - # Never trust parameters from the scary internet, only allow the permitted parameters through. - def site_params - params.require(:site).permit(:application_name, - :institution_name, - :institution_name_full) - end + # Never trust parameters from the scary internet, only allow the permitted parameters through. + def site_params + params.require(:site).permit(:application_name, + :institution_name, + :institution_name_full) + end end diff --git a/app/controllers/proprietor/accounts_controller.rb b/app/controllers/proprietor/accounts_controller.rb index d21986cf1..9f3dd8f86 100644 --- a/app/controllers/proprietor/accounts_controller.rb +++ b/app/controllers/proprietor/accounts_controller.rb @@ -87,41 +87,41 @@ def destroy private - def ensure_admin! - authorize! :read, :admin_dashboard - end + def ensure_admin! + authorize! :read, :admin_dashboard + end - # Never trust parameters from the scary internet, only allow the permitted parameters through. - def edit_account_params - params.require(:account).permit(:name, - :cname, - :title, - :is_public, - :search_only, - *@account.live_settings.keys, - admin_emails: [], - full_account_cross_searches_attributes: [:id, - :_destroy, - :full_account_id, - full_account_attributes: [:id]], - solr_endpoint_attributes: %i[id url], - fcrepo_endpoint_attributes: %i[id url base_path], - data_cite_endpoint_attributes: %i[mode prefix username password]) - end + # Never trust parameters from the scary internet, only allow the permitted parameters through. + def edit_account_params + params.require(:account).permit(:name, + :cname, + :title, + :is_public, + :search_only, + *@account.live_settings.keys, + admin_emails: [], + full_account_cross_searches_attributes: [:id, + :_destroy, + :full_account_id, + full_account_attributes: [:id]], + solr_endpoint_attributes: %i[id url], + fcrepo_endpoint_attributes: %i[id url base_path], + data_cite_endpoint_attributes: %i[mode prefix username password]) + end - def account_params - params.require(:account).permit( - :name, - :search_only, - admin_emails: [], - full_account_cross_searches_attributes: [:id, :_destroy, :full_account_id, full_account_attributes: [:id]] - ) - end + def account_params + params.require(:account).permit( + :name, + :search_only, + admin_emails: [], + full_account_cross_searches_attributes: [:id, :_destroy, :full_account_id, full_account_attributes: [:id]] + ) + end - def deleted_or_new(hash) - hash.detect do |_k, v| - ActiveModel::Type::Boolean.new.cast(v["_destroy"]) == true || v["id"].blank? - end + def deleted_or_new(hash) + hash.detect do |_k, v| + ActiveModel::Type::Boolean.new.cast(v["_destroy"]) == true || v["id"].blank? end + end end end diff --git a/app/controllers/proprietor/users_controller.rb b/app/controllers/proprietor/users_controller.rb index 1aa371c38..c8e160446 100644 --- a/app/controllers/proprietor/users_controller.rb +++ b/app/controllers/proprietor/users_controller.rb @@ -83,44 +83,44 @@ def destroy private - def ensure_admin! - authorize! :read, :admin_dashboard - end + def ensure_admin! + authorize! :read, :admin_dashboard + end - def user_params - # remove blank passwords - params[:user].delete(:password) if params[:user] && params[:user][:password].blank? + def user_params + # remove blank passwords + params[:user].delete(:password) if params[:user] && params[:user][:password].blank? - params.require(:user).permit(:email, - :password, - :is_superadmin, - :facebook_handle, - :twitter_handle, - :googleplus_handle, - :display_name, - :address, - :department, - :title, - :office, - :chat_id, - :website, - :affiliation, - :telephone, - :avatar, - :group_list, - :linkedin_handle, - :orcid, - :arkivo_token, - :arkivo_subscription, - :zotero_token, - :zotero_userid, - :preferred_locale, - role_ids: []) - end + params.require(:user).permit(:email, + :password, + :is_superadmin, + :facebook_handle, + :twitter_handle, + :googleplus_handle, + :display_name, + :address, + :department, + :title, + :office, + :chat_id, + :website, + :affiliation, + :telephone, + :avatar, + :group_list, + :linkedin_handle, + :orcid, + :arkivo_token, + :arkivo_subscription, + :zotero_token, + :zotero_userid, + :preferred_locale, + role_ids: []) + end - def find_user - @user ||= ::User.from_url_component(params[:id]) - raise ActiveRecord::RecordNotFound unless @user - end + def find_user + @user ||= ::User.from_url_component(params[:id]) + raise ActiveRecord::RecordNotFound unless @user + end end end diff --git a/app/controllers/roles_controller.rb b/app/controllers/roles_controller.rb index f3c2a64cd..473a7e95d 100644 --- a/app/controllers/roles_controller.rb +++ b/app/controllers/roles_controller.rb @@ -28,7 +28,7 @@ def update protected - def user_params - params.require(:user).permit(site_roles: []) - end + def user_params + params.require(:user).permit(site_roles: []) + end end diff --git a/app/controllers/sites_controller.rb b/app/controllers/sites_controller.rb index 166f6390f..5dc8efe6b 100644 --- a/app/controllers/sites_controller.rb +++ b/app/controllers/sites_controller.rb @@ -19,36 +19,36 @@ def update private - def set_site - @site ||= Site.instance - end + def set_site + @site ||= Site.instance + end - def update_params - params.permit(:remove_banner_image, - :remove_favicon, - :remove_logo_image, - :remove_directory_image, - :remove_default_collection_image, - :remove_default_work_image) - end + def update_params + params.permit(:remove_banner_image, + :remove_favicon, + :remove_logo_image, + :remove_directory_image, + :remove_default_collection_image, + :remove_default_work_image) + end - def site_theme_params - params.require(:site).permit(:home_theme, :search_theme, :show_theme) - end + def site_theme_params + params.require(:site).permit(:home_theme, :search_theme, :show_theme) + end - REMOVE_TEXT_MAPS = { - "remove_logo_image" => "logo_image_text", - "remove_banner_image" => "banner_image_text", - "remove_directory_image" => "directory_image_text", - "remove_default_collection_image" => "default_collection_image_text", - "remove_default_work_image" => "default_work_image_text" - }.freeze - - def remove_appearance_text(update_params) - image_text_keys = update_params.keys - image_text_keys.each do |image_text_key| - block = ContentBlock.find_by(name: REMOVE_TEXT_MAPS[image_text_key]) - block.delete if block&.value.present? - end + REMOVE_TEXT_MAPS = { + "remove_logo_image" => "logo_image_text", + "remove_banner_image" => "banner_image_text", + "remove_directory_image" => "directory_image_text", + "remove_default_collection_image" => "default_collection_image_text", + "remove_default_work_image" => "default_work_image_text" + }.freeze + + def remove_appearance_text(update_params) + image_text_keys = update_params.keys + image_text_keys.each do |image_text_key| + block = ContentBlock.find_by(name: REMOVE_TEXT_MAPS[image_text_key]) + block.delete if block&.value.present? end + end end diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb index f5cff3c0f..0509c6e40 100644 --- a/app/controllers/users/omniauth_callbacks_controller.rb +++ b/app/controllers/users/omniauth_callbacks_controller.rb @@ -30,7 +30,7 @@ def callback alias saml callback def passthru - render status: 404, plain: 'Not found. Authentication passthru.' + render status: :not_found, plain: 'Not found. Authentication passthru.' end # def failure diff --git a/app/forms/hyrax/forms/admin/appearance.rb b/app/forms/hyrax/forms/admin/appearance.rb index 56000bd98..49428d012 100644 --- a/app/forms/hyrax/forms/admin/appearance.rb +++ b/app/forms/hyrax/forms/admin/appearance.rb @@ -24,7 +24,7 @@ class Appearance # @return [Hash] there should be at least the key "body_font" and # "headline_font" class_attribute :default_fonts, default: { - 'body_font' => 'Helvetica Neue, Helvetica, Arial, sans-serif;', + 'body_font' => 'Helvetica Neue, Helvetica, Arial, sans-serif;', 'headline_font' => 'Helvetica Neue, Helvetica, Arial, sans-serif;' } @@ -33,22 +33,22 @@ class Appearance # @return [Hash] class_attribute :default_colors, default: { 'header_and_footer_background_color' => '#3c3c3c', - 'header_and_footer_text_color' => '#dcdcdc', - 'navbar_background_color' => '#000000', + 'header_and_footer_text_color' => '#dcdcdc', + 'navbar_background_color' => '#000000', 'navbar_link_background_hover_color' => '#ffffff', - 'navbar_link_text_color' => '#eeeeee', - 'navbar_link_text_hover_color' => '#eeeeee', - 'link_color' => '#2e74b2', - 'link_hover_color' => '#215480', - 'footer_link_color' => '#ffebcd', - 'footer_link_hover_color' => '#ffffff', - 'primary_button_hover_color' => '#286090', - 'default_button_background_color' => '#ffffff', - 'default_button_border_color' => '#cccccc', - 'default_button_text_color' => '#333333', + 'navbar_link_text_color' => '#eeeeee', + 'navbar_link_text_hover_color' => '#eeeeee', + 'link_color' => '#2e74b2', + 'link_hover_color' => '#215480', + 'footer_link_color' => '#ffebcd', + 'footer_link_hover_color' => '#ffffff', + 'primary_button_hover_color' => '#286090', + 'default_button_background_color' => '#ffffff', + 'default_button_border_color' => '#cccccc', + 'default_button_text_color' => '#333333', # 'active_tabs_background_color' => '#337ab7', - 'facet_panel_background_color' => '#f5f5f5', - 'facet_panel_text_color' => '#333333' + 'facet_panel_background_color' => '#f5f5f5', + 'facet_panel_text_color' => '#333333' } # @!endgroup Class Attributes @@ -422,43 +422,43 @@ def font_headline_family private - def darken_color(hex_color, adjustment = 0.2) - amount = 1.0 - adjustment - hex_color = hex_color.delete('#') - rgb = hex_color.scan(/../).map { |color| (color.to_i(16) * amount).round } - rgb[0] = (rgb[0].to_i * amount).round - rgb[1] = (rgb[1].to_i * amount).round - rgb[2] = (rgb[2].to_i * amount).round - format("#%02x%02x%02x", *rgb) - end + def darken_color(hex_color, adjustment = 0.2) + amount = 1.0 - adjustment + hex_color = hex_color.delete('#') + rgb = hex_color.scan(/../).map { |color| (color.to_i(16) * amount).round } + rgb[0] = (rgb[0].to_i * amount).round + rgb[1] = (rgb[1].to_i * amount).round + rgb[2] = (rgb[2].to_i * amount).round + format("#%02x%02x%02x", *rgb) + end - def convert_to_rgba(hex_color, alpha = 0.5) - hex_color = hex_color.delete('#') - rgb = hex_color.scan(/../).map(&:hex) - "rgba(#{rgb[0]}, #{rgb[1]}, #{rgb[2]}, #{alpha})" - end + def convert_to_rgba(hex_color, alpha = 0.5) + hex_color = hex_color.delete('#') + rgb = hex_color.scan(/../).map(&:hex) + "rgba(#{rgb[0]}, #{rgb[1]}, #{rgb[2]}, #{alpha})" + end - def default_values - @default_values ||= default_fonts.merge(default_colors) - end + def default_values + @default_values ||= default_fonts.merge(default_colors) + end - def block_for(name, dynamic_default = nil) - ContentBlock.block_for(name: name, fallback_value: default_values[name] || dynamic_default) - end + def block_for(name, dynamic_default = nil) + ContentBlock.block_for(name: name, fallback_value: default_values[name] || dynamic_default) + end - # Persist a key/value tuple as a ContentBlock - # @param [Symbol] name the identifier for the ContentBlock - # @param [String] value the value to set - def update_block(name, value) - ContentBlock.update_block(name: name, value: value) - end + # Persist a key/value tuple as a ContentBlock + # @param [Symbol] name the identifier for the ContentBlock + # @param [String] value the value to set + def update_block(name, value) + ContentBlock.update_block(name: name, value: value) + end - def format_font_names(font_style) - # the fonts come with `Font Name:font-weight` - this removes the weight - parts = font_style.split(':') - # Google fonts use `+` in place of spaces. This fixes it for CSS. - parts[0].tr('+', ' ').html_safe - end + def format_font_names(font_style) + # the fonts come with `Font Name:font-weight` - this removes the weight + parts = font_style.split(':') + # Google fonts use `+` in place of spaces. This fixes it for CSS. + parts[0].tr('+', ' ').html_safe + end end end end diff --git a/app/helpers/shared_search_helper.rb b/app/helpers/shared_search_helper.rb index ef419f6cb..bc96c3cf6 100644 --- a/app/helpers/shared_search_helper.rb +++ b/app/helpers/shared_search_helper.rb @@ -22,15 +22,15 @@ def generate_work_url(model, request) private - def get_url(id:, request:, account_cname:, has_model:) - new_url = "#{request[:request_protocol]}#{account_cname || request[:request_host]}" - new_url += ":#{request[:request_port]}" if Rails.env.development? || Rails.env.test? - new_url += case has_model - when "collections" - "/#{has_model}/#{id}" - else - "/concern/#{has_model}/#{id}" - end - new_url - end + def get_url(id:, request:, account_cname:, has_model:) + new_url = "#{request[:request_protocol]}#{account_cname || request[:request_host]}" + new_url += ":#{request[:request_port]}" if Rails.env.development? || Rails.env.test? + new_url += case has_model + when "collections" + "/#{has_model}/#{id}" + else + "/concern/#{has_model}/#{id}" + end + new_url + end end diff --git a/app/jobs/cleanup_account_job.rb b/app/jobs/cleanup_account_job.rb index 504436f0b..6dcc500e0 100644 --- a/app/jobs/cleanup_account_job.rb +++ b/app/jobs/cleanup_account_job.rb @@ -13,21 +13,21 @@ def perform(account) private - def cleanup_fedora(account) - account.fcrepo_endpoint.remove! - end + def cleanup_fedora(account) + account.fcrepo_endpoint.remove! + end - def cleanup_redis(account) - account.redis_endpoint.remove! - end + def cleanup_redis(account) + account.redis_endpoint.remove! + end - def cleanup_solr(account) - account.solr_endpoint.remove! - end + def cleanup_solr(account) + account.solr_endpoint.remove! + end - def cleanup_database(account) - Apartment::Tenant.drop(account.tenant) - rescue StandardError - nil # ignore if account.tenant missing - end + def cleanup_database(account) + Apartment::Tenant.drop(account.tenant) + rescue StandardError + nil # ignore if account.tenant missing + end end diff --git a/app/jobs/create_solr_collection_job.rb b/app/jobs/create_solr_collection_job.rb index 6d56486eb..536203795 100644 --- a/app/jobs/create_solr_collection_job.rb +++ b/app/jobs/create_solr_collection_job.rb @@ -50,84 +50,84 @@ def to_h private - def transform_entry(k, v) - case v - when Hash - v.map do |k1, v1| - ["#{transform_key(k)}.#{transform_key(k1)}", v1] - end - else - [transform_key(k), v] + def transform_entry(k, v) + case v + when Hash + v.map do |k1, v1| + ["#{transform_key(k)}.#{transform_key(k1)}", v1] end + else + [transform_key(k), v] end + end - def transform_key(k) - k.to_s.camelize(:lower) - end + def transform_key(k) + k.to_s.camelize(:lower) + end end private - def client - Blacklight.default_index.connection - end + def client + Blacklight.default_index.connection + end - def collection_options - CollectionOptions.new(account ? account.solr_collection_options : Account.solr_collection_options).to_h - end + def collection_options + CollectionOptions.new(account ? account.solr_collection_options : Account.solr_collection_options).to_h + end - def collection_exists?(name) - response = client.get '/solr/admin/collections', params: { action: 'LIST' } - collections = response['collections'] + def collection_exists?(name) + response = client.get '/solr/admin/collections', params: { action: 'LIST' } + collections = response['collections'] - collections.include? name - end + collections.include? name + end - def collection_url(name) - uri = URI(solr_url) + name + def collection_url(name) + uri = URI(solr_url) + name - uri.to_s - end + uri.to_s + end - def solr_url - @solr_url ||= ENV['SOLR_URL'] || solr_url_parts - @solr_url = @solr_url.ends_with?('/') ? @solr_url : "#{@solr_url}/" - end + def solr_url + @solr_url ||= ENV['SOLR_URL'] || solr_url_parts + @solr_url = @solr_url.ends_with?('/') ? @solr_url : "#{@solr_url}/" + end - def solr_url_parts - "http://#{ENV.fetch('SOLR_ADMIN_USER', 'admin')}:#{ENV.fetch('SOLR_ADMIN_PASSWORD', 'admin')}" \ - "@#{ENV.fetch('SOLR_HOST', 'solr')}:#{ENV.fetch('SOLR_PORT', '8983')}/solr/" - end + def solr_url_parts + "http://#{ENV.fetch('SOLR_ADMIN_USER', 'admin')}:#{ENV.fetch('SOLR_ADMIN_PASSWORD', 'admin')}" \ + "@#{ENV.fetch('SOLR_HOST', 'solr')}:#{ENV.fetch('SOLR_PORT', '8983')}/solr/" + end - def add_solr_endpoint_to_account(account, name) - account.create_solr_endpoint(url: collection_url(name), collection: name) - end + def add_solr_endpoint_to_account(account, name) + account.create_solr_endpoint(url: collection_url(name), collection: name) + end - def perform_for_normal_tenant(account, name) - unless collection_exists? name - client.get '/solr/admin/collections', params: collection_options.merge(action: 'CREATE', - name: name) - end - add_solr_endpoint_to_account(account, name) + def perform_for_normal_tenant(account, name) + unless collection_exists? name + client.get '/solr/admin/collections', params: collection_options.merge(action: 'CREATE', + name: name) end + add_solr_endpoint_to_account(account, name) + end - def perform_for_cross_search_tenant(account, name) - return if account.full_accounts.blank? - if account.saved_changes&.[]('created_at').present? || account.solr_endpoint.is_a?(NilSolrEndpoint) - create_shared_search_collection(account.full_accounts.map(&:tenant).uniq, name) - account.create_solr_endpoint(url: collection_url(name), collection: name) - account.save - else - solr_options = account.solr_endpoint.connection_options.dup - RemoveSolrCollectionJob.perform_now(name, solr_options, 'cross_search_tenant') - create_shared_search_collection(account.full_accounts.map(&:tenant).uniq, name) - account.solr_endpoint.update(url: collection_url(name), collection: name) - end + def perform_for_cross_search_tenant(account, name) + return if account.full_accounts.blank? + if account.saved_changes&.[]('created_at').present? || account.solr_endpoint.is_a?(NilSolrEndpoint) + create_shared_search_collection(account.full_accounts.map(&:tenant).uniq, name) + account.create_solr_endpoint(url: collection_url(name), collection: name) + account.save + else + solr_options = account.solr_endpoint.connection_options.dup + RemoveSolrCollectionJob.perform_now(name, solr_options, 'cross_search_tenant') + create_shared_search_collection(account.full_accounts.map(&:tenant).uniq, name) + account.solr_endpoint.update(url: collection_url(name), collection: name) end + end - def create_shared_search_collection(tenant_list, name) - return true if collection_exists?(name) - client.get '/solr/admin/collections', params: collection_options.merge(action: 'CREATEALIAS', - name: name, collections: tenant_list) - end + def create_shared_search_collection(tenant_list, name) + return true if collection_exists?(name) + client.get '/solr/admin/collections', params: collection_options.merge(action: 'CREATEALIAS', + name: name, collections: tenant_list) + end end diff --git a/app/jobs/delete_old_guests_job.rb b/app/jobs/delete_old_guests_job.rb index 5ca5e0a40..8af24d850 100644 --- a/app/jobs/delete_old_guests_job.rb +++ b/app/jobs/delete_old_guests_job.rb @@ -12,7 +12,7 @@ def perform private - def reenqueue - DeleteOldGuestsJob.set(wait_until: Date.tomorrow.midnight).perform_later - end + def reenqueue + DeleteOldGuestsJob.set(wait_until: Date.tomorrow.midnight).perform_later + end end diff --git a/app/jobs/embargo_auto_expiry_job.rb b/app/jobs/embargo_auto_expiry_job.rb index 1b7106eb4..7fe83c7d1 100644 --- a/app/jobs/embargo_auto_expiry_job.rb +++ b/app/jobs/embargo_auto_expiry_job.rb @@ -15,7 +15,7 @@ def perform(account) private - def reenqueue(account) - EmbargoAutoExpiryJob.set(wait_until: Date.tomorrow.midnight).perform_later(account) - end + def reenqueue(account) + EmbargoAutoExpiryJob.set(wait_until: Date.tomorrow.midnight).perform_later(account) + end end diff --git a/app/jobs/import_work_from_purl_job.rb b/app/jobs/import_work_from_purl_job.rb index c7dc351aa..9e410926f 100644 --- a/app/jobs/import_work_from_purl_job.rb +++ b/app/jobs/import_work_from_purl_job.rb @@ -35,63 +35,63 @@ def perform(user, druid, log) private - def process_attributes(attributes) - # We're pruning off :form_of_work, :record_origin, :created_attributes, :identifiers - attributes = attributes.slice(*attributes_to_keep) - # rename :location to :based_near - attributes[:based_near] = attributes.delete(:location) + def process_attributes(attributes) + # We're pruning off :form_of_work, :record_origin, :created_attributes, :identifiers + attributes = attributes.slice(*attributes_to_keep) + # rename :location to :based_near + attributes[:based_near] = attributes.delete(:location) - # rename :rights to :license - attributes[:license] = attributes.delete(:rights) + # rename :rights to :license + attributes[:license] = attributes.delete(:rights) - attributes[:collection][:collection_type] ||= Hyrax::CollectionType.find_or_create_default_collection_type + attributes[:collection][:collection_type] ||= Hyrax::CollectionType.find_or_create_default_collection_type - process_collection(attributes) - filenames = attributes.delete(:files) - attributes[:remote_files] = filenames.map do |name| - { url: "https://stacks.stanford.edu/file/druid:#{attributes[:id]}/#{name}", - file_name: name } - end - - attributes + process_collection(attributes) + filenames = attributes.delete(:files) + attributes[:remote_files] = filenames.map do |name| + { url: "https://stacks.stanford.edu/file/druid:#{attributes[:id]}/#{name}", + file_name: name } end - class_attribute :attributes_to_keep - self.attributes_to_keep = %i[title - description - subject - language - resource_type - location - rights - visibility - id - collection - files - collection_type] + attributes + end - def process_collection(attributes) - # rename :collection to :member_of_collection_attributes - collection = attributes.delete(:collection) + class_attribute :attributes_to_keep + self.attributes_to_keep = %i[title + description + subject + language + resource_type + location + rights + visibility + id + collection + files + collection_type] - # Workaround for ActiveFedora #1186 - id = collection[:id] - begin - retries ||= 0 - Collection.create!(collection) unless Collection.exists?(id) - rescue Ldp::Conflict => e - ## Another process has likely beat us to the punch. Wait a bit and try again. - sleep(3) - retry if (retries += 1) < 3 - raise e - end - attributes[:member_of_collection_attributes] = [{ id: id }] - end + def process_collection(attributes) + # rename :collection to :member_of_collection_attributes + collection = attributes.delete(:collection) - # Override this method if you have a different rubric for choosing the model - # @param [Hash] attributes - # @return String the model to create - def model_to_create(_attributes) - GenericWork.model_name.name + # Workaround for ActiveFedora #1186 + id = collection[:id] + begin + retries ||= 0 + Collection.create!(collection) unless Collection.exists?(id) + rescue Ldp::Conflict => e + ## Another process has likely beat us to the punch. Wait a bit and try again. + sleep(3) + retry if (retries += 1) < 3 + raise e end + attributes[:member_of_collection_attributes] = [{ id: id }] + end + + # Override this method if you have a different rubric for choosing the model + # @param [Hash] attributes + # @return String the model to create + def model_to_create(_attributes) + GenericWork.model_name.name + end end diff --git a/app/jobs/lease_auto_expiry_job.rb b/app/jobs/lease_auto_expiry_job.rb index 16f6bcf9c..fe21273ed 100644 --- a/app/jobs/lease_auto_expiry_job.rb +++ b/app/jobs/lease_auto_expiry_job.rb @@ -15,7 +15,7 @@ def perform(account) private - def reenqueue(account) - LeaseAutoExpiryJob.set(wait_until: Date.tomorrow.midnight).perform_later(account) - end + def reenqueue(account) + LeaseAutoExpiryJob.set(wait_until: Date.tomorrow.midnight).perform_later(account) + end end diff --git a/app/jobs/remove_solr_collection_job.rb b/app/jobs/remove_solr_collection_job.rb index a93eebeb9..2efbf2843 100644 --- a/app/jobs/remove_solr_collection_job.rb +++ b/app/jobs/remove_solr_collection_job.rb @@ -15,8 +15,8 @@ def perform(collection, connection_options, tenant_type = 'normal') private - def solr_client(connection_options) - # We remove the adapter, otherwise RSolr 2 will try to use it as a Faraday middleware - RSolr.connect(connection_options.without('adapter')) - end + def solr_client(connection_options) + # We remove the adapter, otherwise RSolr 2 will try to use it as a Faraday middleware + RSolr.connect(connection_options.without('adapter')) + end end diff --git a/app/mailers/hyku_mailer.rb b/app/mailers/hyku_mailer.rb index 924a0834d..9539011d7 100644 --- a/app/mailers/hyku_mailer.rb +++ b/app/mailers/hyku_mailer.rb @@ -8,7 +8,7 @@ def default_url_options private - def host_for_tenant - Account.find_by(tenant: Apartment::Tenant.current)&.cname || Account.admin_host - end + def host_for_tenant + Account.find_by(tenant: Apartment::Tenant.current)&.cname || Account.admin_host + end end diff --git a/app/models/concerns/account_cname.rb b/app/models/concerns/account_cname.rb index 0306a1110..8c13d5630 100644 --- a/app/models/concerns/account_cname.rb +++ b/app/models/concerns/account_cname.rb @@ -12,7 +12,7 @@ module AccountCname # @raise [ArgumentError] if piece contains a trailing dot def default_cname(piece) return unless piece - raise ArgumentError, "param '#{piece}' must not contain trailing dots" if piece =~ /\.\Z/ + raise ArgumentError, "param '#{piece}' must not contain trailing dots" if /\.\Z/.match?(piece) # rubocop:disable Style/FormatStringToken default_host = ENV.fetch('HYKU_DEFAULT_HOST', "%{tenant}.#{admin_host}") # rubocop:enable Style/FormatStringToken @@ -51,7 +51,7 @@ def cname=(value) private - def default_cname(piece = name) - self.class.default_cname(piece) - end + def default_cname(piece = name) + self.class.default_cname(piece) + end end diff --git a/app/models/concerns/account_settings.rb b/app/models/concerns/account_settings.rb index 5cd2458c0..a0fa4eaba 100644 --- a/app/models/concerns/account_settings.rb +++ b/app/models/concerns/account_settings.rb @@ -112,80 +112,80 @@ def live_settings private - def set_type(value, to_type) - case to_type - when 'array' - value.is_a?(String) ? value.split(',') : Array.wrap(value) - when 'boolean' - ActiveModel::Type::Boolean.new.cast(value) - when 'hash' - value.is_a?(String) ? JSON.parse(value) : value - when 'string' - value.to_s - end + def set_type(value, to_type) + case to_type + when 'array' + value.is_a?(String) ? value.split(',') : Array.wrap(value) + when 'boolean' + ActiveModel::Type::Boolean.new.cast(value) + when 'hash' + value.is_a?(String) ? JSON.parse(value) : value + when 'string' + value.to_s end + end - def validate_email_format - return if settings['email_format'].blank? - settings['email_format'].each do |email| - errors.add(:email_format) unless email.match?(/@\S*\.\S*/) - end + def validate_email_format + return if settings['email_format'].blank? + settings['email_format'].each do |email| + errors.add(:email_format) unless email.match?(/@\S*\.\S*/) end + end - def validate_contact_emails - ['weekly_email_list', 'monthly_email_list', 'yearly_email_list'].each do |key| - next if settings[key].blank? - settings[key].each do |email| - errors.add(:"#{key}") unless email.match?(URI::MailTo::EMAIL_REGEXP) - end + def validate_contact_emails + ['weekly_email_list', 'monthly_email_list', 'yearly_email_list'].each do |key| + next if settings[key].blank? + settings[key].each do |email| + errors.add(:"#{key}") unless email.match?(URI::MailTo::EMAIL_REGEXP) end end + end - def initialize_settings - return true unless self.class.column_names.include?('settings') - set_smtp_settings - reload_library_config - end + def initialize_settings + return true unless self.class.column_names.include?('settings') + set_smtp_settings + reload_library_config + end - def set_smtp_settings - current_smtp_settings = settings&.[]("smtp_settings").presence || {} - self.smtp_settings = current_smtp_settings.with_indifferent_access.reverse_merge!( - PerTenantSmtpInterceptor.available_smtp_fields.each_with_object("").to_h - ) + def set_smtp_settings + current_smtp_settings = settings&.[]("smtp_settings").presence || {} + self.smtp_settings = current_smtp_settings.with_indifferent_access.reverse_merge!( + PerTenantSmtpInterceptor.available_smtp_fields.each_with_object("").to_h + ) + end + + def reload_library_config + Hyrax.config do |config| + config.contact_email = contact_email + config.analytics = google_analytics_id.present? + config.google_analytics_id = google_analytics_id if google_analytics_id.present? + config.geonames_username = geonames_username + config.uploader[:maxFileSize] = file_size_limit end - def reload_library_config - Hyrax.config do |config| - config.contact_email = contact_email - config.analytics = google_analytics_id.present? - config.google_analytics_id = google_analytics_id if google_analytics_id.present? - config.geonames_username = geonames_username - config.uploader[:maxFileSize] = file_size_limit - end + Devise.mailer_sender = contact_email - Devise.mailer_sender = contact_email - - if s3_bucket.present? - CarrierWave.configure do |config| - config.storage = :aws - config.aws_bucket = s3_bucket - config.aws_acl = 'bucket-owner-full-control' - end - elsif !file_acl - CarrierWave.configure do |config| - config.permissions = nil - config.directory_permissions = nil - end - else - CarrierWave.configure do |config| - config.storage = :file - config.permissions = 420 - config.directory_permissions = 493 - end + if s3_bucket.present? + CarrierWave.configure do |config| + config.storage = :aws + config.aws_bucket = s3_bucket + config.aws_acl = 'bucket-owner-full-control' + end + elsif !file_acl + CarrierWave.configure do |config| + config.permissions = nil + config.directory_permissions = nil + end + else + CarrierWave.configure do |config| + config.storage = :file + config.permissions = 420 + config.directory_permissions = 493 end - - return unless ssl_configured - ActionMailer::Base.default_url_options ||= {} - ActionMailer::Base.default_url_options[:protocol] = 'https' end + + return unless ssl_configured + ActionMailer::Base.default_url_options ||= {} + ActionMailer::Base.default_url_options[:protocol] = 'https' + end end diff --git a/app/models/concerns/account_switch.rb b/app/models/concerns/account_switch.rb index 7c5a02f00..80fd4c30a 100644 --- a/app/models/concerns/account_switch.rb +++ b/app/models/concerns/account_switch.rb @@ -10,7 +10,7 @@ def switch!(cname_or_name_or_account) account = if cname_or_name_or_account.is_a?(Account) cname_or_name_or_account # is it a domain name? - elsif cname_or_name_or_account =~ DOMAIN_REGEXP + elsif DOMAIN_REGEXP.match?(cname_or_name_or_account) Account.joins(:domain_names).find_by(domain_names: { is_active: true, cname: Account.canonical_cname(cname_or_name_or_account) diff --git a/app/models/featured_collection_list.rb b/app/models/featured_collection_list.rb index 1de617815..394fb8069 100644 --- a/app/models/featured_collection_list.rb +++ b/app/models/featured_collection_list.rb @@ -30,24 +30,24 @@ def featured_collections private - def add_solr_document_to_collections - collection_presenters.each do |presenter| - collection_with_id(presenter.id).presenter = presenter - end + def add_solr_document_to_collections + collection_presenters.each do |presenter| + collection_with_id(presenter.id).presenter = presenter end + end - def ids - @collections.pluck(:collection_id) - end + def ids + @collections.pluck(:collection_id) + end - def collection_presenters - ability = nil - Hyrax::PresenterFactory.build_for(ids: ids, - presenter_class: Hyku::WorkShowPresenter, - presenter_args: ability) - end + def collection_presenters + ability = nil + Hyrax::PresenterFactory.build_for(ids: ids, + presenter_class: Hyku::WorkShowPresenter, + presenter_args: ability) + end - def collection_with_id(id) - @collections.find { |c| c.collection_id == id } - end + def collection_with_id(id) + @collections.find { |c| c.collection_id == id } + end end diff --git a/app/models/hyrax/group.rb b/app/models/hyrax/group.rb index bc33f2d73..9b3d95ab8 100644 --- a/app/models/hyrax/group.rb +++ b/app/models/hyrax/group.rb @@ -85,7 +85,7 @@ def default_group? def description_label label = description || I18n.t("hyku.admin.groups.description.#{name}") - return '' if label =~ /^translation missing:/ + return '' if /^translation missing:/.match?(label) label end @@ -98,22 +98,22 @@ def has_site_role?(role_name) # rubocop:disable Naming/PredicateName private - def can_destroy? - return false if default_group? + def can_destroy? + return false if default_group? - true - end + true + end - def remove_all_members - members.map { |m| m.remove_role(MEMBERSHIP_ROLE, self) } - end + def remove_all_members + members.map { |m| m.remove_role(MEMBERSHIP_ROLE, self) } + end - def sipity_agent - Sipity::Agent.find_by(proxy_for_id: name, proxy_for_type: self.class.name) - end + def sipity_agent + Sipity::Agent.find_by(proxy_for_id: name, proxy_for_type: self.class.name) + end - def create_sipity_agent! - Sipity::Agent.create!(proxy_for_id: name, proxy_for_type: self.class.name) - end + def create_sipity_agent! + Sipity::Agent.create!(proxy_for_id: name, proxy_for_type: self.class.name) + end end end diff --git a/app/models/nil_fcrepo_endpoint.rb b/app/models/nil_fcrepo_endpoint.rb index d72614517..d833c0f42 100644 --- a/app/models/nil_fcrepo_endpoint.rb +++ b/app/models/nil_fcrepo_endpoint.rb @@ -15,7 +15,7 @@ def base_path private - def options - { url: 'http://127.0.0.1:99999/nil_fcrepo_endpoint' } - end + def options + { url: 'http://127.0.0.1:99999/nil_fcrepo_endpoint' } + end end diff --git a/app/models/nil_solr_endpoint.rb b/app/models/nil_solr_endpoint.rb index 7a16634fc..9dd11f166 100644 --- a/app/models/nil_solr_endpoint.rb +++ b/app/models/nil_solr_endpoint.rb @@ -13,16 +13,16 @@ def url private - # Return an RSolr connection, that points at an invalid endpoint - # Note: We could have returned a NilRSolrConnection here, but Blacklight - # makes it's own RSolr connection, so we'd end up with an RSolr connection in - # blacklight anyway. - def connection - RSolr.connect(connection_options) - end + # Return an RSolr connection, that points at an invalid endpoint + # Note: We could have returned a NilRSolrConnection here, but Blacklight + # makes it's own RSolr connection, so we'd end up with an RSolr connection in + # blacklight anyway. + def connection + RSolr.connect(connection_options) + end - # Return options that will never return a valid connection. - def connection_options - { url: 'http://127.0.0.1:99999/nil_solr_endpoint' } - end + # Return options that will never return a valid connection. + def connection_options + { url: 'http://127.0.0.1:99999/nil_solr_endpoint' } + end end diff --git a/app/models/redis_endpoint.rb b/app/models/redis_endpoint.rb index b6899cf98..8003b9e6c 100644 --- a/app/models/redis_endpoint.rb +++ b/app/models/redis_endpoint.rb @@ -34,7 +34,7 @@ def remove! private - def redis_instance - Hyrax::RedisEventStore.instance - end + def redis_instance + Hyrax::RedisEventStore.instance + end end diff --git a/app/models/role.rb b/app/models/role.rb index 4b5c4eefd..f30b58e30 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -21,7 +21,7 @@ class Role < ApplicationRecord def description_label label = description || I18n.t("hyku.admin.roles.description.#{name}") - return '' if label =~ /^translation missing:/ + return '' if /^translation missing:/.match?(label) label end @@ -29,13 +29,13 @@ def description_label def set_sort_value self.sort_value = if name == 'admin' 0 - elsif name =~ /manager/ + elsif /manager/.match?(name) 1 - elsif name =~ /editor/ + elsif /editor/.match?(name) 2 - elsif name =~ /depositor/ + elsif /depositor/.match?(name) 3 - elsif name =~ /reader/ + elsif /reader/.match?(name) 4 else 99 diff --git a/app/models/site.rb b/app/models/site.rb index 777bf1a0b..431315297 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -51,26 +51,26 @@ def admin_emails=(emails) private - # Add/invite admins via email address - # @param [Array] Array of user emails - def add_admins_by_email(emails) - # For users that already have accounts, add to role immediately - existing_emails = User.where(email: emails).map do |u| - u.add_role :admin, self - u.email - end - # For new users, send invitation and add to role - (emails - existing_emails).each do |email| - u = User.invite!(email: email) - u.add_role :admin, self - end + # Add/invite admins via email address + # @param [Array] Array of user emails + def add_admins_by_email(emails) + # For users that already have accounts, add to role immediately + existing_emails = User.where(email: emails).map do |u| + u.add_role :admin, self + u.email + end + # For new users, send invitation and add to role + (emails - existing_emails).each do |email| + u = User.invite!(email: email) + u.add_role :admin, self end + end - # Remove specific administrators - # @param [Array] Array of user emails - def remove_admins_by_email(emails) - User.where(email: emails).find_each do |u| - u.remove_role :admin, self - end + # Remove specific administrators + # @param [Array] Array of user emails + def remove_admins_by_email(emails) + User.where(email: emails).find_each do |u| + u.remove_role :admin, self end + end end diff --git a/app/models/user.rb b/app/models/user.rb index 3f27a488e..a6ef4151e 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -22,7 +22,7 @@ def self.default_scope where(guest: false) end - scope :for_repository, -> { + scope :for_repository, lambda { joins(:roles) } diff --git a/app/presenters/concerns/hyrax/iiif_av/displays_content_decorator.rb b/app/presenters/concerns/hyrax/iiif_av/displays_content_decorator.rb index 6260e456a..7fa98752a 100644 --- a/app/presenters/concerns/hyrax/iiif_av/displays_content_decorator.rb +++ b/app/presenters/concerns/hyrax/iiif_av/displays_content_decorator.rb @@ -22,68 +22,68 @@ def request private - Request = Struct.new(:base_url, keyword_init: true) + Request = Struct.new(:base_url, keyword_init: true) - def image_content - return nil unless latest_file_id - url = Hyrax.config.iiif_image_url_builder.call( - latest_file_id, - request.base_url, - Hyrax.config.iiif_image_size_default, - solr_document.mime_type - ) + def image_content + return nil unless latest_file_id + url = Hyrax.config.iiif_image_url_builder.call( + latest_file_id, + request.base_url, + Hyrax.config.iiif_image_size_default, + solr_document.mime_type + ) - # Serving up only prezi 3 - image_content_v3(url) - end + # Serving up only prezi 3 + image_content_v3(url) + end - def video_display_content(_url, label = '') - width = solr_document.width&.try(:to_i) || 320 - height = solr_document.height&.try(:to_i) || 240 - duration = conformed_duration_in_seconds - IIIFManifest::V3::DisplayContent.new( - Hyrax::IiifAv::Engine.routes.url_helpers.iiif_av_content_url( - solr_document.id, - label: label, - host: request.base_url - ), + def video_display_content(_url, label = '') + width = solr_document.width&.try(:to_i) || 320 + height = solr_document.height&.try(:to_i) || 240 + duration = conformed_duration_in_seconds + IIIFManifest::V3::DisplayContent.new( + Hyrax::IiifAv::Engine.routes.url_helpers.iiif_av_content_url( + solr_document.id, label: label, - width: width, - height: height, - duration: duration, - type: 'Video', - format: solr_document.mime_type - ) - end + host: request.base_url + ), + label: label, + width: width, + height: height, + duration: duration, + type: 'Video', + format: solr_document.mime_type + ) + end - def audio_display_content(_url, label = '') - duration = conformed_duration_in_seconds - IIIFManifest::V3::DisplayContent.new( - Hyrax::IiifAv::Engine.routes.url_helpers.iiif_av_content_url( - solr_document.id, - label: label, - host: request.base_url - ), + def audio_display_content(_url, label = '') + duration = conformed_duration_in_seconds + IIIFManifest::V3::DisplayContent.new( + Hyrax::IiifAv::Engine.routes.url_helpers.iiif_av_content_url( + solr_document.id, label: label, - duration: duration, - type: 'Sound', - format: solr_document.mime_type - ) - end + host: request.base_url + ), + label: label, + duration: duration, + type: 'Sound', + format: solr_document.mime_type + ) + end - def conformed_duration_in_seconds - if Array(solr_document.duration)&.first&.count(':') == 3 - # takes care of milliseconds like ["0:0:01:001"] - Time.zone.parse(Array(solr_document.duration).first.sub(/.*\K:/, '.')).seconds_since_midnight - elsif Array(solr_document.duration)&.first&.include?(':') - # if solr_document.duration evaluates to something like ["0:01:00"] which will get converted to seconds - Time.zone.parse(Array(solr_document.duration).first).seconds_since_midnight - else - # handles cases if solr_document.duration evaluates to something like ['25 s'] - Array(solr_document.duration).first.try(:to_f) - end || - 400.0 - end + def conformed_duration_in_seconds + if Array(solr_document.duration)&.first&.count(':') == 3 + # takes care of milliseconds like ["0:0:01:001"] + Time.zone.parse(Array(solr_document.duration).first.sub(/.*\K:/, '.')).seconds_since_midnight + elsif Array(solr_document.duration)&.first&.include?(':') + # if solr_document.duration evaluates to something like ["0:01:00"] which will get converted to seconds + Time.zone.parse(Array(solr_document.duration).first).seconds_since_midnight + else + # handles cases if solr_document.duration evaluates to something like ['25 s'] + Array(solr_document.duration).first.try(:to_f) + end || + 400.0 + end end end end diff --git a/app/presenters/hyku/admin/group/navigation_presenter.rb b/app/presenters/hyku/admin/group/navigation_presenter.rb index 7afaf6a9c..99d31daf1 100644 --- a/app/presenters/hyku/admin/group/navigation_presenter.rb +++ b/app/presenters/hyku/admin/group/navigation_presenter.rb @@ -20,76 +20,76 @@ def tabs private - attr_reader :group_id, :params + attr_reader :group_id, :params - def edit_tab - Tab.new( - name: I18n.t('hyku.admin.groups.nav.attributes'), - controller: 'admin/groups', - action: 'edit', - path: Rails.application.routes.url_helpers.edit_admin_group_path(group_id), - context: params - ) - end + def edit_tab + Tab.new( + name: I18n.t('hyku.admin.groups.nav.attributes'), + controller: 'admin/groups', + action: 'edit', + path: Rails.application.routes.url_helpers.edit_admin_group_path(group_id), + context: params + ) + end - def members_tab - Tab.new( - name: I18n.t('hyku.admin.groups.nav.members'), - controller: 'admin/group_users', - action: 'index', - path: Rails.application.routes.url_helpers.admin_group_users_path(group_id), - context: params - ) - end + def members_tab + Tab.new( + name: I18n.t('hyku.admin.groups.nav.members'), + controller: 'admin/group_users', + action: 'index', + path: Rails.application.routes.url_helpers.admin_group_users_path(group_id), + context: params + ) + end - def roles_tab - Tab.new( - name: I18n.t('hyku.admin.groups.nav.roles'), - controller: 'admin/group_roles', - action: 'index', - path: Rails.application.routes.url_helpers.admin_group_roles_path(group_id), - context: params - ) - end + def roles_tab + Tab.new( + name: I18n.t('hyku.admin.groups.nav.roles'), + controller: 'admin/group_roles', + action: 'index', + path: Rails.application.routes.url_helpers.admin_group_roles_path(group_id), + context: params + ) + end - def remove_tab - Tab.new( - name: I18n.t('hyku.admin.groups.nav.delete'), - controller: 'admin/groups', - action: 'remove', - path: Rails.application.routes.url_helpers.remove_admin_group_path(group_id), - context: params - ) - end + def remove_tab + Tab.new( + name: I18n.t('hyku.admin.groups.nav.delete'), + controller: 'admin/groups', + action: 'remove', + path: Rails.application.routes.url_helpers.remove_admin_group_path(group_id), + context: params + ) + end - def group_id_key - return :id if params.key?(:id) - return :group_id if params.key?(:group_id) - :key_not_found - end + def group_id_key + return :id if params.key?(:id) + return :group_id if params.key?(:group_id) + :key_not_found + end - class Tab - ACTIVE_CSS_CLASS = 'active' + class Tab + ACTIVE_CSS_CLASS = 'active' - attr_reader :name, :path, :action + attr_reader :name, :path, :action - def initialize(name:, controller:, action:, path:, context:) - @name = name - @controller = controller - @action = action - @path = path - @context = context - end + def initialize(name:, controller:, action:, path:, context:) + @name = name + @controller = controller + @action = action + @path = path + @context = context + end - def css_class - return ACTIVE_CSS_CLASS if context.fetch(:controller) == controller && context.fetch(:action) == action - '' - end + def css_class + return ACTIVE_CSS_CLASS if context.fetch(:controller) == controller && context.fetch(:action) == action + '' + end - private + private - attr_reader :controller, :context - end + attr_reader :controller, :context + end end end end diff --git a/app/presenters/hyku/collapsable_section_presenter.rb b/app/presenters/hyku/collapsable_section_presenter.rb index f513b56a0..da0c2b100 100644 --- a/app/presenters/hyku/collapsable_section_presenter.rb +++ b/app/presenters/hyku/collapsable_section_presenter.rb @@ -15,17 +15,17 @@ def initialize(view_context:, text:, id:, icon_class:, open:, html_options: {}) private - def button_tag - tag.a({ role: 'button', - class: "#{button_class}collapse-toggle", - data: { toggle: 'collapse' }, - href: "##{id}", - onclick: "toggleCollapse(this)", - 'aria-expanded' => open, - 'aria-controls' => id }.merge(html_options)) do - safe_join([tag.span('', class: icon_class, 'aria-hidden': true), - tag.span(text)], ' ') - end + def button_tag + tag.a({ role: 'button', + class: "#{button_class}collapse-toggle", + data: { toggle: 'collapse' }, + href: "##{id}", + onclick: "toggleCollapse(this)", + 'aria-expanded' => open, + 'aria-controls' => id }.merge(html_options)) do + safe_join([tag.span('', class: icon_class, 'aria-hidden': true), + tag.span(text)], ' ') end + end end end diff --git a/app/presenters/hyku/work_show_presenter.rb b/app/presenters/hyku/work_show_presenter.rb index 12427bc41..a734a52fb 100644 --- a/app/presenters/hyku/work_show_presenter.rb +++ b/app/presenters/hyku/work_show_presenter.rb @@ -46,9 +46,7 @@ def display_unfeature_collection_link? def collection_featured? # only look this up if it's not boolean; ||= won't work here - if @collection_featured.nil? - @collection_featured = FeaturedCollection.where(collection_id: solr_document.id).exists? - end + @collection_featured = FeaturedCollection.where(collection_id: solr_document.id).exists? if @collection_featured.nil? @collection_featured end @@ -68,23 +66,23 @@ def iiif_viewer? private - def iiif_media?(presenter: representative_presenter) - presenter.image? || presenter.video? || presenter.audio? || presenter.pdf? - end + def iiif_media?(presenter: representative_presenter) + presenter.image? || presenter.video? || presenter.audio? || presenter.pdf? + end - def members_include_viewable? - file_set_presenters.any? do |presenter| - iiif_media?(presenter: presenter) && current_ability.can?(:read, presenter.id) - end + def members_include_viewable? + file_set_presenters.any? do |presenter| + iiif_media?(presenter: presenter) && current_ability.can?(:read, presenter.id) end + end - def extract_from_identifier(rgx) - if solr_document['identifier_tesim'].present? - ref = solr_document['identifier_tesim'].map do |str| - str.scan(rgx) - end + def extract_from_identifier(rgx) + if solr_document['identifier_tesim'].present? + ref = solr_document['identifier_tesim'].map do |str| + str.scan(rgx) end - ref end + ref + end end end diff --git a/app/presenters/hyrax/admin/users_presenter.rb b/app/presenters/hyrax/admin/users_presenter.rb index 17d2fc0ba..8d49fd538 100644 --- a/app/presenters/hyrax/admin/users_presenter.rb +++ b/app/presenters/hyrax/admin/users_presenter.rb @@ -34,10 +34,10 @@ def show_last_access? private - # Returns a list of users excluding the system users and guest_users - def search - ::User.registered.for_repository.without_system_accounts.uniq - end + # Returns a list of users excluding the system users and guest_users + def search + ::User.registered.for_repository.without_system_accounts.uniq + end end end end diff --git a/app/presenters/hyrax/collection_presenter_decorator.rb b/app/presenters/hyrax/collection_presenter_decorator.rb index c348e5888..3c27b7c4e 100644 --- a/app/presenters/hyrax/collection_presenter_decorator.rb +++ b/app/presenters/hyrax/collection_presenter_decorator.rb @@ -49,19 +49,11 @@ def [](key) # @return String the access label (e.g. Manage, Deposit, View) def managed_access # OVERRIDE: Change check for manage access from :edit to :destroy - if current_ability.can?(:destroy, solr_document) - return I18n.t('hyrax.dashboard.my.collection_list.managed_access.manage') - end + return I18n.t('hyrax.dashboard.my.collection_list.managed_access.manage') if current_ability.can?(:destroy, solr_document) # OVERRIDE: Add label for Edit access - if current_ability.can?(:edit, solr_document) - return I18n.t('hyrax.dashboard.my.collection_list.managed_access.edit') - end - if current_ability.can?(:deposit, solr_document) - return I18n.t('hyrax.dashboard.my.collection_list.managed_access.deposit') - end - if current_ability.can?(:read, solr_document) - return I18n.t('hyrax.dashboard.my.collection_list.managed_access.view') - end + return I18n.t('hyrax.dashboard.my.collection_list.managed_access.edit') if current_ability.can?(:edit, solr_document) + return I18n.t('hyrax.dashboard.my.collection_list.managed_access.deposit') if current_ability.can?(:deposit, solr_document) + return I18n.t('hyrax.dashboard.my.collection_list.managed_access.view') if current_ability.can?(:read, solr_document) '' end @@ -106,9 +98,7 @@ def display_unfeature_collection_link? def collection_featured? # only look this up if it's not boolean; ||= won't work here - if @collection_featured.nil? - @collection_featured = FeaturedCollection.where(collection_id: solr_document.id).exists? - end + @collection_featured = FeaturedCollection.where(collection_id: solr_document.id).exists? if @collection_featured.nil? @collection_featured end diff --git a/app/presenters/hyrax/homepage_presenter.rb b/app/presenters/hyrax/homepage_presenter.rb index 76fe4bf49..2351f1195 100644 --- a/app/presenters/hyrax/homepage_presenter.rb +++ b/app/presenters/hyrax/homepage_presenter.rb @@ -66,9 +66,9 @@ def display_recently_uploaded? private - def user_unregistered? - current_ability.current_user.new_record? || - current_ability.current_user.guest? - end + def user_unregistered? + current_ability.current_user.new_record? || + current_ability.current_user.guest? + end end end diff --git a/app/services/create_account.rb b/app/services/create_account.rb index 1ce61f94e..d756c17dc 100644 --- a/app/services/create_account.rb +++ b/app/services/create_account.rb @@ -53,7 +53,7 @@ def create_defaults def fillin_translations collection_types = Hyrax::CollectionType.all collection_types.each do |c| - next unless c.title =~ /^translation missing/ + next unless /^translation missing/.match?(c.title) oldtitle = c.title c.title = I18n.t(c.title.gsub("translation missing: en.", '')) c.save @@ -87,7 +87,7 @@ def schedule_recurring_jobs private - def initialize_account_data - Site.update(account: account) - end + def initialize_account_data + Site.update(account: account) + end end diff --git a/app/services/group_aware_role_checker.rb b/app/services/group_aware_role_checker.rb index 76b7752bc..d366e46a8 100644 --- a/app/services/group_aware_role_checker.rb +++ b/app/services/group_aware_role_checker.rb @@ -12,16 +12,16 @@ module GroupAwareRoleChecker private - # Check for the presence of the passed role_name in the User's Roles and - # the User's Hyrax::Group's Roles. - def has_group_aware_role?(role_name) # rubocop:disable Naming/PredicateName - return false if current_user.new_record? - return true if current_user.has_role?(role_name, Site.instance) + # Check for the presence of the passed role_name in the User's Roles and + # the User's Hyrax::Group's Roles. + def has_group_aware_role?(role_name) # rubocop:disable Naming/PredicateName + return false if current_user.new_record? + return true if current_user.has_role?(role_name, Site.instance) - current_user.hyrax_groups.each do |group| - return true if group.has_site_role?(role_name) - end - - false + current_user.hyrax_groups.each do |group| + return true if group.has_site_role?(role_name) end + + false + end end diff --git a/app/services/hyrax/manifest_builder_service_decorator.rb b/app/services/hyrax/manifest_builder_service_decorator.rb index 218420566..fdfe796ab 100644 --- a/app/services/hyrax/manifest_builder_service_decorator.rb +++ b/app/services/hyrax/manifest_builder_service_decorator.rb @@ -4,22 +4,22 @@ module Hyrax module ManifestBuilderServiceDecorator private - ## - # @return [Hash] the Hash to be used by "label" to change `&` to `&` - # @see #loof - def sanitize_value(text) - return loof(text) unless text.is_a?(Hash) - text[text.keys.first] = text.values.flatten.map { |value| loof(value) } - text - end + ## + # @return [Hash] the Hash to be used by "label" to change `&` to `&` + # @see #loof + def sanitize_value(text) + return loof(text) unless text.is_a?(Hash) + text[text.keys.first] = text.values.flatten.map { |value| loof(value) } + text + end - ## - # @return [String] the String that gets unescaped since Loofah is too aggressive for example - # it changes to `&` to `&` which will be displayed in the Universal Viewer and manifest - # @see #sanitize_value - def loof(text) - CGI.unescapeHTML(Loofah.fragment(text.to_s).scrub!(:prune).to_s) - end + ## + # @return [String] the String that gets unescaped since Loofah is too aggressive for example + # it changes to `&` to `&` which will be displayed in the Universal Viewer and manifest + # @see #sanitize_value + def loof(text) + CGI.unescapeHTML(Loofah.fragment(text.to_s).scrub!(:prune).to_s) + end end end diff --git a/app/services/hyrax/thumbnail_path_service.rb b/app/services/hyrax/thumbnail_path_service.rb index cccadc9a5..af3851f72 100644 --- a/app/services/hyrax/thumbnail_path_service.rb +++ b/app/services/hyrax/thumbnail_path_service.rb @@ -18,54 +18,54 @@ def call(object) private - def return_path(thumb) - if audio?(thumb) - audio_image - elsif thumbnail?(thumb) - thumbnail_path(thumb) - else - default_image - end + def return_path(thumb) + if audio?(thumb) + audio_image + elsif thumbnail?(thumb) + thumbnail_path(thumb) + else + default_image end + end - def audio?(thumb) - service = thumb.respond_to?(:audio?) ? thumb : Hyrax::FileSetTypeService.new(file_set: thumb) - service.audio? - end + def audio?(thumb) + service = thumb.respond_to?(:audio?) ? thumb : Hyrax::FileSetTypeService.new(file_set: thumb) + service.audio? + end - def fetch_thumbnail(object) - return object if object.thumbnail_id == object.id - Hyrax.query_service.find_by(id: object.thumbnail_id) - rescue Valkyrie::Persistence::ObjectNotFoundError, Hyrax::ObjectNotFoundError - Rails.logger.error("Couldn't find thumbnail #{object.thumbnail_id} for #{object.id}") - nil - end + def fetch_thumbnail(object) + return object if object.thumbnail_id == object.id + Hyrax.query_service.find_by(id: object.thumbnail_id) + rescue Valkyrie::Persistence::ObjectNotFoundError, Hyrax::ObjectNotFoundError + Rails.logger.error("Couldn't find thumbnail #{object.thumbnail_id} for #{object.id}") + nil + end - # @return the network path to the thumbnail - # @param [FileSet] thumbnail the object that is the thumbnail - def thumbnail_path(thumbnail) - Hyrax::Engine.routes.url_helpers.download_path(thumbnail.id, - file: 'thumbnail') - end + # @return the network path to the thumbnail + # @param [FileSet] thumbnail the object that is the thumbnail + def thumbnail_path(thumbnail) + Hyrax::Engine.routes.url_helpers.download_path(thumbnail.id, + file: 'thumbnail') + end - def default_image - Site.instance.default_work_image&.url || ActionController::Base.helpers.image_path('default.png') - end + def default_image + Site.instance.default_work_image&.url || ActionController::Base.helpers.image_path('default.png') + end - def audio_image - ActionController::Base.helpers.image_path 'audio.png' - end + def audio_image + ActionController::Base.helpers.image_path 'audio.png' + end - # @return true if there a file on disk for this object, otherwise false - # @param [FileSet] thumb - the object that is the thumbnail - def thumbnail?(thumb) - File.exist?(thumbnail_filepath(thumb)) - end + # @return true if there a file on disk for this object, otherwise false + # @param [FileSet] thumb - the object that is the thumbnail + def thumbnail?(thumb) + File.exist?(thumbnail_filepath(thumb)) + end - # @param [FileSet] thumb - the object that is the thumbnail - def thumbnail_filepath(thumb) - Hyrax::DerivativePath.derivative_path_for_reference(thumb, 'thumbnail') - end + # @param [FileSet] thumb - the object that is the thumbnail + def thumbnail_filepath(thumb) + Hyrax::DerivativePath.derivative_path_for_reference(thumb, 'thumbnail') + end end end end diff --git a/app/services/hyrax/workflow/permission_grantor.rb b/app/services/hyrax/workflow/permission_grantor.rb index ed93c054a..1efc530eb 100644 --- a/app/services/hyrax/workflow/permission_grantor.rb +++ b/app/services/hyrax/workflow/permission_grantor.rb @@ -36,64 +36,64 @@ def call private - # Force creation of registered roles if they don't exist - def register_default_sipity_roles! - Sipity::Role[Hyrax::RoleRegistry::MANAGING] - Sipity::Role[Hyrax::RoleRegistry::APPROVING] - Sipity::Role[Hyrax::RoleRegistry::DEPOSITING] - end + # Force creation of registered roles if they don't exist + def register_default_sipity_roles! + Sipity::Role[Hyrax::RoleRegistry::MANAGING] + Sipity::Role[Hyrax::RoleRegistry::APPROVING] + Sipity::Role[Hyrax::RoleRegistry::DEPOSITING] + end - def grant_all_workflow_roles_to_creating_user_and_admins! - # The admin group should always receive workflow roles - workflow_agents = [Hyrax::Group.find_by!(name: ::Ability.admin_group_name)] - # The default admin set does not have a creating user - workflow_agents << creating_user if creating_user - workflow_agents |= Hyrax::Group.select { |g| g.has_site_role?(:admin) }.tap do |agent_list| - ::User.find_each do |u| - agent_list << u if u.has_role?(:admin, Site.instance) - end + def grant_all_workflow_roles_to_creating_user_and_admins! + # The admin group should always receive workflow roles + workflow_agents = [Hyrax::Group.find_by!(name: ::Ability.admin_group_name)] + # The default admin set does not have a creating user + workflow_agents << creating_user if creating_user + workflow_agents |= Hyrax::Group.select { |g| g.has_site_role?(:admin) }.tap do |agent_list| + ::User.find_each do |u| + agent_list << u if u.has_role?(:admin, Site.instance) end - - grant_workflow_roles!(workflow_agents: workflow_agents, role_filters: nil) end - def grant_workflow_roles_to_editors! - editor_sipity_roles = [Hyrax::RoleRegistry::APPROVING, Hyrax::RoleRegistry::DEPOSITING] - workflow_agents = Hyrax::Group.select { |g| g.has_site_role?(:work_editor) }.tap do |agent_list| - ::User.find_each do |u| - agent_list << u if u.has_role?(:work_editor, Site.instance) - end - end + grant_workflow_roles!(workflow_agents: workflow_agents, role_filters: nil) + end - grant_workflow_roles!(workflow_agents: workflow_agents, role_filters: editor_sipity_roles) + def grant_workflow_roles_to_editors! + editor_sipity_roles = [Hyrax::RoleRegistry::APPROVING, Hyrax::RoleRegistry::DEPOSITING] + workflow_agents = Hyrax::Group.select { |g| g.has_site_role?(:work_editor) }.tap do |agent_list| + ::User.find_each do |u| + agent_list << u if u.has_role?(:work_editor, Site.instance) + end end - def grant_workflow_roles_to_depositors! - depositor_sipity_role = [Hyrax::RoleRegistry::DEPOSITING] - workflow_agents = Hyrax::Group.select { |g| g.has_site_role?(:work_depositor) }.tap do |agent_list| - ::User.find_each do |u| - agent_list << u if u.has_role?(:work_depositor, Site.instance) - end - end + grant_workflow_roles!(workflow_agents: workflow_agents, role_filters: editor_sipity_roles) + end - grant_workflow_roles!(workflow_agents: workflow_agents, role_filters: depositor_sipity_role) + def grant_workflow_roles_to_depositors! + depositor_sipity_role = [Hyrax::RoleRegistry::DEPOSITING] + workflow_agents = Hyrax::Group.select { |g| g.has_site_role?(:work_depositor) }.tap do |agent_list| + ::User.find_each do |u| + agent_list << u if u.has_role?(:work_depositor, Site.instance) + end end - def grant_workflow_roles!(workflow_agents:, role_filters:) - role_set = if role_filters.present? - Sipity::Role.select { |role| role_filters.include?(role.name) } - else - Sipity::Role.all - end + grant_workflow_roles!(workflow_agents: workflow_agents, role_filters: depositor_sipity_role) + end + + def grant_workflow_roles!(workflow_agents:, role_filters:) + role_set = if role_filters.present? + Sipity::Role.select { |role| role_filters.include?(role.name) } + else + Sipity::Role.all + end - permission_template.available_workflows.each do |workflow| - role_set.each do |role| - Hyrax::Workflow::PermissionGenerator.call(roles: role, - workflow: workflow, - agents: workflow_agents) - end + permission_template.available_workflows.each do |workflow| + role_set.each do |role| + Hyrax::Workflow::PermissionGenerator.call(roles: role, + workflow: workflow, + agents: workflow_agents) end end + end end end end diff --git a/app/services/roles_service.rb b/app/services/roles_service.rb index 7b28747ad..4c93997ec 100644 --- a/app/services/roles_service.rb +++ b/app/services/roles_service.rb @@ -77,9 +77,7 @@ def create_default_roles! def create_default_hyrax_groups_with_roles! # Prevent Hyrax::Groups from being created in the public schema - if Site.instance.is_a?(NilSite) - return '`AccountElevator.switch!` into an Account before creating default Hyrax::Groups' - end + return '`AccountElevator.switch!` into an Account before creating default Hyrax::Groups' if Site.instance.is_a?(NilSite) default_hyrax_groups_with_roles = DEFAULT_HYRAX_GROUPS_WITH_ATTRIBUTES.deep_merge(DEFAULT_ROLES_FOR_DEFAULT_HYRAX_GROUPS) diff --git a/bin/extract_mods_to_spreadsheet b/bin/extract_mods_to_spreadsheet index 302cbaf5f..822c783b6 100755 --- a/bin/extract_mods_to_spreadsheet +++ b/bin/extract_mods_to_spreadsheet @@ -28,9 +28,9 @@ puts 'Starting import...' # Assumption: filename will contain the druid. Example: # hyku-metadata/GSE/druid_wg827ks1643/data/metadata/descMetadata.xml data = Dir.glob("#{base_path}/**/descMetadata.xml").map do |filename| - id = filename.gsub(%r{.*/druid_(\w+)/.*}, '\1') - {id: [id], type: ['ETD']}.merge(Importer::ModsParser.new(filename).attributes) - end + id = filename.gsub(%r{.*/druid_(\w+)/.*}, '\1') + { id: [id], type: ['ETD'] }.merge(Importer::ModsParser.new(filename).attributes) +end # Process the contributor into a flat field and drop 'notes_attributes' and 'collection' data.each do |record| @@ -51,8 +51,8 @@ end uniq_headers = headers.map(&:keys).flatten.uniq # How many columns does each field take up. Look for the widest one. -cols_for_attribute = uniq_headers.each_with_object({}) do |k, h| - h[k] = headers.map{ |header| header[k] }.max +cols_for_attribute = uniq_headers.index_with do |k| + headers.map { |header| header[k] }.max end # Discard fields that aren't used. diff --git a/bin/git-cleanup b/bin/git-cleanup index cd9390421..0b1fc6a35 100755 --- a/bin/git-cleanup +++ b/bin/git-cleanup @@ -1,9 +1,9 @@ #!/usr/bin/env ruby -%x{git fetch -ap} -branches = %x{git branch --merged main}.split("\n").collect {|b| b.gsub('*', '').strip} +`git fetch -ap` +branches = `git branch --merged main`.split("\n").collect { |b| b.delete('*').strip } branches -= ['staging', 'main'] branches.each do |branch| - puts %x{git branch -d #{branch}} + puts `git branch -d #{branch}` end diff --git a/bin/graph b/bin/graph index ee0ef589a..6ff6fa1e3 100644 --- a/bin/graph +++ b/bin/graph @@ -5,9 +5,9 @@ # # Example: bin/graph one_step_mediated_deposit # -# This script requires that you have Graphviz installed and the +# This script requires that you have Graphviz installed and the # ruby-graphviz gem. -# +# # gem install 'ruby-graphviz' # # @@ -31,9 +31,7 @@ unless workflow exit(1) end - class GraphWriter - attr_reader :workflow, :nodes, :initial_state def initialize(workflow) @@ -42,7 +40,7 @@ class GraphWriter # Create a new graph def graph - @g ||= GraphViz.new(:G, :type => :digraph) + @g ||= GraphViz.new(:G, type: :digraph) end def attach_nodes @@ -54,14 +52,14 @@ class GraphWriter end def write_edge(initial, terminal, label) - graph.add_edges( nodes[initial], nodes[terminal], label: label) + graph.add_edges(nodes[initial], nodes[terminal], label: label) end def attach_edges # Create edges workflow.workflow_actions.each do |wa| terminal = wa.resulting_workflow_state_id - if wa.workflow_state_actions.count == 0 + if wa.workflow_state_actions.count == 0 # Initial action write_edge(initial_state.id, terminal, wa.name) end @@ -88,4 +86,3 @@ class GraphWriter end GraphWriter.new(workflow).write - diff --git a/bin/import_from_purl b/bin/import_from_purl index 23ce3b38d..9b6b214d0 100755 --- a/bin/import_from_purl +++ b/bin/import_from_purl @@ -47,7 +47,7 @@ def druids(druid_file) count = 0 File.foreach(druid_file) do |line| # Split in two parts on the first comma - (element, _) = line.split(/,/, 2) + (element,) = line.split(/,/, 2) # remove any namespacing if md = /(druid:)?(.*)/.match(element) yield(md[2]) diff --git a/bin/import_mods_files b/bin/import_mods_files index 1bff5db78..7398057c8 100755 --- a/bin/import_mods_files +++ b/bin/import_mods_files @@ -39,7 +39,6 @@ def load_rails puts 'Starting import...' end - def main(hostname, mods_directory, imagepath) validate_hostname!(hostname) validate_mods_directory!(mods_directory) @@ -56,5 +55,4 @@ def usage $stderr.puts "Usage: #{$PROGRAM_NAME} " end - main(ARGV[0], ARGV[1], ARGV[2]) diff --git a/bin/web b/bin/web index 4d53319bc..2fd50cdf5 100755 --- a/bin/web +++ b/bin/web @@ -1,6 +1,4 @@ #!/usr/local/bin/ruby -if ENV['GOOGLE_OAUTH_PRIVATE_KEY_VALUE'] && !ENV['GOOGLE_OAUTH_PRIVATE_KEY_VALUE'].empty? - %x{echo "$GOOGLE_OAUTH_PRIVATE_KEY_VALUE" | base64 -d > prod-cred.p12} -end +`echo "$GOOGLE_OAUTH_PRIVATE_KEY_VALUE" | base64 -d > prod-cred.p12` if ENV['GOOGLE_OAUTH_PRIVATE_KEY_VALUE'].present? exec "bundle exec puma -v -b tcp://0.0.0.0:3000" diff --git a/bin/worker b/bin/worker index 7698b346e..1ab592264 100755 --- a/bin/worker +++ b/bin/worker @@ -1,9 +1,7 @@ #!/usr/local/bin/ruby -if ENV['GOOGLE_OAUTH_PRIVATE_KEY_VALUE'] && !ENV['GOOGLE_OAUTH_PRIVATE_KEY_VALUE'].empty? - %x{echo "$GOOGLE_OAUTH_PRIVATE_KEY_VALUE" | base64 -d > prod-cred.p12} -end +`echo "$GOOGLE_OAUTH_PRIVATE_KEY_VALUE" | base64 -d > prod-cred.p12` if ENV['GOOGLE_OAUTH_PRIVATE_KEY_VALUE'].present? -if ENV['DATABASE_URL'] && !ENV['DATABASE_URL'].empty? +if ENV['DATABASE_URL'].present? ENV['DATABASE_URL'] = ENV['DATABASE_URL'].gsub('pool=5', 'pool=30') else puts 'DATABASE_URL not set, no pool change needed' diff --git a/config/application.rb b/config/application.rb index 3b4f85fcb..d6356bc09 100644 --- a/config/application.rb +++ b/config/application.rb @@ -48,14 +48,15 @@ class Application < Rails::Application # # This is a value that you want to set in the before_initialize block. class_attribute :user_devise_parameters, instance_accessor: false, default: [ - :database_authenticatable, - :invitable, - :registerable, - :recoverable, - :rememberable, - :trackable, - :validatable, - :omniauthable, { omniauth_providers: %i[saml openid_connect cas] }] + :database_authenticatable, + :invitable, + :registerable, + :recoverable, + :rememberable, + :trackable, + :validatable, + :omniauthable, { omniauth_providers: %i[saml openid_connect cas] } + ] # @!endgroup Class Attributes @@ -99,13 +100,12 @@ def self.path_for(relative_path) Rails.application.configure do process_jobs = ActiveModel::Type::Boolean.new.cast(ENV.fetch('HYKU_ELASTIC_JOBS', false)) config.active_elastic_job.process_jobs = process_jobs - config.active_elastic_job.aws_credentials = lambda { Aws::InstanceProfileCredentials.new } + config.active_elastic_job.aws_credentials = -> { Aws::InstanceProfileCredentials.new } config.active_elastic_job.secret_key_base = Rails.application.secrets[:secret_key_base] end end config.to_prepare do - # By default plain text files are not processed for text extraction. In adding # Adventist::TextFileTextExtractionService to the beginning of the services array we are # enabling text extraction from plain text files. @@ -146,7 +146,7 @@ def self.path_for(relative_path) Rails.application.configure do process_jobs = ActiveModel::Type::Boolean.new.cast(ENV.fetch('HYKU_ELASTIC_JOBS', false)) config.active_elastic_job.process_jobs = process_jobs - config.active_elastic_job.aws_credentials = lambda { Aws::InstanceProfileCredentials.new } + config.active_elastic_job.aws_credentials = -> { Aws::InstanceProfileCredentials.new } config.active_elastic_job.secret_key_base = Rails.application.secrets[:secret_key_base] end end diff --git a/config/environments/development.rb b/config/environments/development.rb index c6cf36d04..448ece68d 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -4,12 +4,11 @@ # In the development environment your application's code is reloaded on # every request. This slows down response time but is perfect for development # since you don't have to restart the web server when you make code changes. - if ENV.fetch('HYRAX_ACTIVE_JOB_QUEUE', 'sidekiq') == 'sidekiq' - config.cache_classes = !!Sidekiq.server? - else - config.cache_classes = false - end - + config.cache_classes = if ENV.fetch('HYRAX_ACTIVE_JOB_QUEUE', 'sidekiq') == 'sidekiq' + !!Sidekiq.server? + else + false + end # Do not eager load code on boot. config.eager_load = false @@ -63,7 +62,7 @@ config.logger = ActiveSupport::TaggedLogging.new(logger) end - config.active_job.queue_adapter = ENV.fetch('HYRAX_ACTIVE_JOB_QUEUE', 'sidekiq') + config.active_job.queue_adapter = ENV.fetch('HYRAX_ACTIVE_JOB_QUEUE', 'sidekiq') # Use an evented file watcher to asynchronously detect changes in source code, # routes, locales, etc. This feature depends on the listen gem. diff --git a/config/environments/production.rb b/config/environments/production.rb index 249a5507b..b6cdf3770 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -19,7 +19,7 @@ config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? config.public_file_server.headers = { 'Cache-Control' => 'public, s-maxage=31536000, maxage=15552000', - 'Expires' => "#{1.year.from_now.to_formatted_s(:rfc822)}" + 'Expires' => 1.year.from_now.to_formatted_s(:rfc822).to_s } config.middleware.insert_before ActionDispatch::Static, NoCacheMiddleware, [/dashboard\/collections\/.*\/edit/, /uploaded_collection_thumbnails/] # Compress JavaScripts and CSS. @@ -51,14 +51,14 @@ config.log_level = :debug # Prepend all log lines with the following tags. - config.log_tags = [ :request_id ] + config.log_tags = [:request_id] # Use a different cache store in production. # config.cache_store = :mem_cache_store # Use a real queuing backend for Active Job (and separate queues per environment) require 'active_job/queue_adapters/better_active_elastic_job_adapter' - config.active_job.queue_adapter = ENV.fetch('HYRAX_ACTIVE_JOB_QUEUE', 'sidekiq') + config.active_job.queue_adapter = ENV.fetch('HYRAX_ACTIVE_JOB_QUEUE', 'sidekiq') # config.active_job.queue_name_prefix = "hyku_#{Rails.env}" if ENV['SMTP_ENABLED'].present? && ENV['SMTP_ENABLED'].to_s == 'true' diff --git a/config/initializers/0db_created.rb b/config/initializers/0db_created.rb index 8564f0161..ffd0e463c 100644 --- a/config/initializers/0db_created.rb +++ b/config/initializers/0db_created.rb @@ -1,3 +1,5 @@ def db_created? - ::ActiveRecord::Base.connection_pool.with_connection(&:active?) rescue false + ::ActiveRecord::Base.connection_pool.with_connection(&:active?) +rescue + false end diff --git a/config/initializers/apartment.rb b/config/initializers/apartment.rb index 53934a77b..6acc1fd12 100644 --- a/config/initializers/apartment.rb +++ b/config/initializers/apartment.rb @@ -9,15 +9,14 @@ # Apartment Configuration # Apartment.configure do |config| - # Add any models that you do not want to be multi-tenanted, but remain in the global (public) namespace. # A typical example would be a Customer or Tenant model that stores each Tenant's information. - config.excluded_models = %w{ Account AccountCrossSearch DomainName Endpoint User UserStat SolrEndpoint FcrepoEndpoint RedisEndpoint GoodJob::Execution GoodJob::Job GoodJob::Process } + config.excluded_models = %w[Account AccountCrossSearch DomainName Endpoint User UserStat SolrEndpoint FcrepoEndpoint RedisEndpoint GoodJob::Execution GoodJob::Job GoodJob::Process] # In order to migrate all of your Tenants you need to provide a list of Tenant names to Apartment. # You can make this dynamic by providing a Proc object to be called on migrations. # This object should yield an array of strings representing each Tenant name. - config.tenant_names = lambda { Account.pluck :tenant } + config.tenant_names = -> { Account.pluck :tenant } # # ==> PostgreSQL only options @@ -41,20 +40,18 @@ # config.persistent_schemas = %w{ hstore } config.persistent_schemas = ['shared_extensions'] - # <== PostgreSQL only options # - end Rails.application.config.after_initialize do # Callbacks from ActiveSupport::Callback: receives ZERO information about object/event. # Instead receives an [Apartment::Adapters::PostgresqlSchemaAdapter] # Therefore cannot be used as effectively as ActiveRecord hooks. - Apartment::Tenant.adapter.class.set_callback :switch, :after, ->() do + Apartment::Tenant.adapter.class.set_callback :switch, :after, lambda { account = Account.find_by(tenant: current) account.switch! if account - end + } end Rails.application.config.middleware.insert_before Warden::Manager, AccountElevator diff --git a/config/initializers/bulkrax.rb b/config/initializers/bulkrax.rb index 1f2d38b28..035ad0f5a 100644 --- a/config/initializers/bulkrax.rb +++ b/config/initializers/bulkrax.rb @@ -53,7 +53,6 @@ # e.g. to exclude date # config.field_mappings["Bulkrax::OaiDcParser"]["date"] = { from: ["date"], excluded: true } - default_field_mapping = { 'abstract' => { from: ['abstract'], split: true }, 'alternative_title' => { from: ['alternative_title'], split: /\s*[|]\s*/ }, @@ -75,7 +74,7 @@ 'parents' => { from: ['parents'], related_parents_field_mapping: true }, 'publisher' => { from: ['publisher'], split: true }, 'related_url' => { from: ['related_url'], split: /\s* [|]\s*/ }, - 'remote_files' => { from: ['remote_files'], split: /\s*[|]\s*/}, + 'remote_files' => { from: ['remote_files'], split: /\s*[|]\s*/ }, 'resource_type' => { from: ['resource_type'], split: true }, 'rights_notes' => { from: ['rights_notes'], split: true }, 'source' => { from: ['source'], split: true }, @@ -84,24 +83,24 @@ } config.field_mappings["Bulkrax::BagitParser"] = default_field_mapping.merge({ - # add or remove custom mappings for this parser here - }) + # add or remove custom mappings for this parser here + }) config.field_mappings["Bulkrax::CsvParser"] = default_field_mapping.merge({ - # add or remove custom mappings for this parser here - }) + # add or remove custom mappings for this parser here + }) config.field_mappings["Bulkrax::OaiDcParser"] = default_field_mapping.merge({ - # add or remove custom mappings for this parser here - }) + # add or remove custom mappings for this parser here + }) config.field_mappings["Bulkrax::OaiQualifiedDcParser"] = default_field_mapping.merge({ - # add or remove custom mappings for this parser here - }) + # add or remove custom mappings for this parser here + }) config.field_mappings["Bulkrax::XmlParser"] = default_field_mapping.merge({ - # add or remove custom mappings for this parser here - }) + # add or remove custom mappings for this parser here + }) # To duplicate a set of mappings from one parser to another # config.field_mappings["Bulkrax::OaiOmekaParser"] = {} diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 6658b94b0..1d86f3c3c 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -298,9 +298,9 @@ identity_provider_id_regex = /\d+/ [:cas, :openid_connect, :saml].each do |provider| - path_prefix = "/users/auth/#{provider}" + path_prefix = "/users/auth/#{provider}" handler = OmniAuth::MultiProvider::Handler.new(path_prefix: path_prefix, - identity_provider_id_regex: identity_provider_id_regex, + identity_provider_id_regex: identity_provider_id_regex, &dynamic_options_generator) static_options = { path_prefix: path_prefix } diff --git a/config/initializers/file_set_derivatives_overrides.rb b/config/initializers/file_set_derivatives_overrides.rb index af88c5318..ace70d032 100644 --- a/config/initializers/file_set_derivatives_overrides.rb +++ b/config/initializers/file_set_derivatives_overrides.rb @@ -4,7 +4,7 @@ Hyrax::FileSetDerivativesService.class_eval do # @see https://github.com/samvera/hydra-derivatives/blob/main/lib/hydra/derivatives/processors/video/config.rb#L59 DEFAULT_VIDEO_SIZE = '320x240' - + # OVERRIDE: increase size of thumbnails for better viewing in Neutral theme home page def create_pdf_derivatives(filename) Hydra::Derivatives::PdfDerivatives.create(filename, @@ -56,4 +56,4 @@ def create_video_derivatives(filename) { label: 'mp4', format: 'mp4', url: derivative_url('mp4') }]) end -end \ No newline at end of file +end diff --git a/config/initializers/hyrax.rb b/config/initializers/hyrax.rb index 1269df850..6cd21a831 100644 --- a/config/initializers/hyrax.rb +++ b/config/initializers/hyrax.rb @@ -113,17 +113,17 @@ # Temporary path to hold uploads before they are ingested into FCrepo. # This must be a lambda that returns a Pathname - config.upload_path = ->() do + config.upload_path = lambda { if Site.account&.s3_bucket "uploads/#{Apartment::Tenant.current}" else ENV['HYRAX_UPLOAD_PATH'].present? ? Pathname.new(File.join(ENV['HYRAX_UPLOAD_PATH'], Apartment::Tenant.current)) : Rails.root.join('public', 'uploads', Apartment::Tenant.current) end - end + } # Location on local file system where derivatives will be stored. # If you use a multi-server architecture, this MUST be a shared volume. - config.derivatives_path = ENV['HYRAX_DERIVATIVES_PATH'].present? ? ENV['HYRAX_DERIVATIVES_PATH'] : File.join(Rails.root, 'tmp', 'derivatives') + config.derivatives_path = ENV['HYRAX_DERIVATIVES_PATH'].presence || File.join(Rails.root, 'tmp', 'derivatives') # Should schema.org microdata be displayed? # config.display_microdata = true @@ -196,9 +196,7 @@ Qa::Authorities::Local.register_subauthority('genres', 'Qa::Authorities::Local::TableBasedAuthority') # set bulkrax default work type to first curation_concern if it isn't already set -if ENV.fetch('HYKU_BULKRAX_ENABLED', 'true') == 'true' && Bulkrax.default_work_type.blank? - Bulkrax.default_work_type = Hyrax.config.curation_concerns.first.to_s -end +Bulkrax.default_work_type = Hyrax.config.curation_concerns.first.to_s if ENV.fetch('HYKU_BULKRAX_ENABLED', 'true') == 'true' && Bulkrax.default_work_type.blank? Hyrax::IiifAv.config.iiif_av_viewer = :universal_viewer diff --git a/config/initializers/mailboxer.rb b/config/initializers/mailboxer.rb index 39bcf7b7d..f244e1996 100644 --- a/config/initializers/mailboxer.rb +++ b/config/initializers/mailboxer.rb @@ -1,21 +1,20 @@ Mailboxer.setup do |config| - - #Configures if you application uses or not email sending for Notifications and Messages + # Configures if you application uses or not email sending for Notifications and Messages config.uses_emails = true - #Configures the default from for emails sent for Messages and Notifications + # Configures the default from for emails sent for Messages and Notifications config.default_from = "no-reply@mailboxer.com" - #Configures the methods needed by mailboxer + # Configures the methods needed by mailboxer config.email_method = :mailboxer_email config.name_method = :name - #Configures if you use or not a search engine and which one you are using - #Supported engines: [:solr,:sphinx] + # Configures if you use or not a search engine and which one you are using + # Supported engines: [:solr,:sphinx] config.search_enabled = false config.search_engine = :solr - #Configures maximum length of the message subject and body + # Configures maximum length of the message subject and body config.subject_max_length = 255 - config.body_max_length = 32000 + config.body_max_length = 32_000 end diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb index 5894028a1..022642dff 100644 --- a/config/initializers/mime_types.rb +++ b/config/initializers/mime_types.rb @@ -5,4 +5,4 @@ Mime::Type.register "application/n-triples", :nt Mime::Type.register "application/ld+json", :jsonld Mime::Type.register "text/turtle", :ttl -Mime::Type.register 'application/x-endnote-refer', :endnote \ No newline at end of file +Mime::Type.register 'application/x-endnote-refer', :endnote diff --git a/config/initializers/rolify.rb b/config/initializers/rolify.rb index 71de17cad..b56270b50 100644 --- a/config/initializers/rolify.rb +++ b/config/initializers/rolify.rb @@ -1,2 +1,2 @@ Rolify.configure do |config| -end \ No newline at end of file +end diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb index 6e88cb0e5..8f26be3c3 100644 --- a/config/initializers/simple_form.rb +++ b/config/initializers/simple_form.rb @@ -171,7 +171,6 @@ config.wrappers :inline, class: :input, hint_class: 'hint', error_class: 'field_with_errors' do |b| - # mix in special behavior using `use :component` b.use :html5 # b.use :placeholder diff --git a/config/routes.rb b/config/routes.rb index b3132ebde..cf42c9caa 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,9 +2,7 @@ # OVERRIDE Hyrax 2.9.0 to add featured collection routes -if ENV.fetch('HYRAX_ACTIVE_JOB_QUEUE', 'sidekiq') == 'sidekiq' - require 'sidekiq/web' -end +require 'sidekiq/web' if ENV.fetch('HYRAX_ACTIVE_JOB_QUEUE', 'sidekiq') == 'sidekiq' Rails.application.routes.draw do # rubocop:disable Metrics/BlockLength resources :identity_providers @@ -18,8 +16,8 @@ authenticate :user, ->(u) { u.is_superadmin || u.is_admin } do queue = ENV.fetch('HYRAX_ACTIVE_JOB_QUEUE', 'sidekiq') case queue - when 'sidekiq' - mount Sidekiq::Web => '/jobs' + when 'sidekiq' + mount Sidekiq::Web => '/jobs' when 'good_job' mount GoodJob::Engine => '/jobs' end @@ -52,8 +50,8 @@ root 'hyrax/homepage#index' devise_for :users, skip: [:omniauth_callbacks], controllers: { invitations: 'hyku/invitations', - registrations: 'hyku/registrations', - omniauth_callbacks: 'users/omniauth_callbacks' } + registrations: 'hyku/registrations', + omniauth_callbacks: 'users/omniauth_callbacks' } as :user do resources :single_signon, only: [:index] diff --git a/config/spring.rb b/config/spring.rb index c9119b40c..9fa7863f9 100644 --- a/config/spring.rb +++ b/config/spring.rb @@ -1,6 +1,6 @@ -%w( +%w[ .ruby-version .rbenv-vars tmp/restart.txt tmp/caching-dev.txt -).each { |path| Spring.watch(path) } +].each { |path| Spring.watch(path) } diff --git a/lib/active_job_tenant.rb b/lib/active_job_tenant.rb index ad99f3b35..1a79e6491 100644 --- a/lib/active_job_tenant.rb +++ b/lib/active_job_tenant.rb @@ -42,19 +42,19 @@ def perform_now private - delegate :non_tenant_job?, to: :class + delegate :non_tenant_job?, to: :class - def current_account - @current_account ||= Account.find_by(tenant: current_tenant) - end + def current_account + @current_account ||= Account.find_by(tenant: current_tenant) + end - def current_tenant - tenant || Apartment::Tenant.current - end + def current_tenant + tenant || Apartment::Tenant.current + end - def switch - Apartment::Tenant.switch(current_tenant) do - yield - end + def switch + Apartment::Tenant.switch(current_tenant) do + yield end + end end diff --git a/lib/hydra/derivatives/processors/image_decorator.rb b/lib/hydra/derivatives/processors/image_decorator.rb index 6c4d610af..4d58b0d8f 100644 --- a/lib/hydra/derivatives/processors/image_decorator.rb +++ b/lib/hydra/derivatives/processors/image_decorator.rb @@ -8,18 +8,18 @@ module Processors module ImageDecorator protected - # When resizing images, it is necessary to flatten any layers, otherwise the background - # may be completely black. This happens especially with PDFs. See https://github.com/samvera/hydra-derivatives/issues/110 - def create_resized_image - create_image do |xfrm| - if size - xfrm.combine_options do |i| - i.flatten - i.resize(size) - end + # When resizing images, it is necessary to flatten any layers, otherwise the background + # may be completely black. This happens especially with PDFs. See https://github.com/samvera/hydra-derivatives/issues/110 + def create_resized_image + create_image do |xfrm| + if size + xfrm.combine_options do |i| + i.flatten + i.resize(size) end end end + end end end end diff --git a/lib/iiif_manifest/v3/manifest_builder/canvas_builder_decorator.rb b/lib/iiif_manifest/v3/manifest_builder/canvas_builder_decorator.rb index 990bd1409..71918666c 100644 --- a/lib/iiif_manifest/v3/manifest_builder/canvas_builder_decorator.rb +++ b/lib/iiif_manifest/v3/manifest_builder/canvas_builder_decorator.rb @@ -8,9 +8,7 @@ module ManifestBuilderDecorator module CanvasBuilderDecorator def apply_record_properties super - canvas.label = if record.to_s.present? - ManifestBuilder.language_map(record['parent_title_tesim']&.first || record.to_s) - end + canvas.label = (ManifestBuilder.language_map(record['parent_title_tesim']&.first || record.to_s) if record.to_s.present?) end end end diff --git a/lib/importer/csv_importer.rb b/lib/importer/csv_importer.rb index 3f2905fd3..97ae96aae 100644 --- a/lib/importer/csv_importer.rb +++ b/lib/importer/csv_importer.rb @@ -27,27 +27,27 @@ def import_all private - def parser - CSVParser.new(@metadata_file) - end + def parser + CSVParser.new(@metadata_file) + end - # @return [Class] the model class to be used - def factory_class(model) - return model if model.is_a?(Class) - if model.empty? - warn 'ERROR: No model was specified' - exit(1) # rubocop:disable Rails/Exit - end - return Factory.for(model.to_s) if model.respond_to?(:to_s) - raise "Unrecognized model type: #{model.class}" + # @return [Class] the model class to be used + def factory_class(model) + return model if model.is_a?(Class) + if model.empty? + warn 'ERROR: No model was specified' + exit(1) # rubocop:disable Rails/Exit end + return Factory.for(model.to_s) if model.respond_to?(:to_s) + raise "Unrecognized model type: #{model.class}" + end - # Build a factory to create the objects in fedora. - # @param [Hash String>] attributes - # @option attributes [String] :type overrides model for a single object - # @note remaining attributes are passed to factory constructor - def create_fedora_objects(attributes) - factory_class(attributes.delete(:type) || @model).new(attributes, @files_directory).run - end + # Build a factory to create the objects in fedora. + # @param [Hash String>] attributes + # @option attributes [String] :type overrides model for a single object + # @note remaining attributes are passed to factory constructor + def create_fedora_objects(attributes) + factory_class(attributes.delete(:type) || @model).new(attributes, @files_directory).run + end end end diff --git a/lib/importer/csv_parser.rb b/lib/importer/csv_parser.rb index 96941486a..fa15dd7c0 100644 --- a/lib/importer/csv_parser.rb +++ b/lib/importer/csv_parser.rb @@ -24,130 +24,128 @@ def each(&_block) private - # Match headers like "lc_subject_type" - def type_header_pattern - /\A.*_type\Z/ - end + # Match headers like "lc_subject_type" + def type_header_pattern + /\A.*_type\Z/ + end - def validate_headers(row) - row.compact! - difference = (row - valid_headers) + def validate_headers(row) + row.compact! + difference = (row - valid_headers) - # Allow headers with the pattern *_type to specify the - # record type for a local authority. - # e.g. For an author, author_type might be 'Person'. - difference.delete_if { |h| h.match(type_header_pattern) } + # Allow headers with the pattern *_type to specify the + # record type for a local authority. + # e.g. For an author, author_type might be 'Person'. + difference.delete_if { |h| h.match(type_header_pattern) } - raise "Invalid headers: #{difference.join(', ')}" if difference.present? + raise "Invalid headers: #{difference.join(', ')}" if difference.present? - validate_header_pairs(row) - row - end + validate_header_pairs(row) + row + end - # If you have a header like lc_subject_type, the next - # header must be the corresponding field (e.g. lc_subject) - def validate_header_pairs(row) - errors = [] - row.each_with_index do |header, i| - next if header == 'resource_type' - next unless header.match(type_header_pattern) - next_header = row[i + 1] - field_name = header.gsub('_type', '') - if next_header != field_name - errors << "Invalid headers: '#{header}' column must be immediately followed by '#{field_name}' column." - end - end - raise errors.join(', ') if errors.present? + # If you have a header like lc_subject_type, the next + # header must be the corresponding field (e.g. lc_subject) + def validate_header_pairs(row) + errors = [] + row.each_with_index do |header, i| + next if header == 'resource_type' + next unless header.match(type_header_pattern) + next_header = row[i + 1] + field_name = header.gsub('_type', '') + errors << "Invalid headers: '#{header}' column must be immediately followed by '#{field_name}' column." if next_header != field_name end + raise errors.join(', ') if errors.present? + end - def valid_headers - GenericWork.attribute_names + %w[id type file] + collection_headers - end + def valid_headers + GenericWork.attribute_names + %w[id type file] + collection_headers + end - def collection_headers - %w[collection_id collection_title collection_accession_number] - end + def collection_headers + %w[collection_id collection_title collection_accession_number] + end - def attributes(headers, row) - {}.tap do |processed| - headers.each_with_index do |header, index| - extract_field(header, row[index], processed) - end + def attributes(headers, row) + {}.tap do |processed| + headers.each_with_index do |header, index| + extract_field(header, row[index], processed) end end + end - def extract_field(header, val, processed) - return unless val - case header - when 'type', 'id' - # type and id are singular - processed[header.to_sym] = val - when /^(created|issued|date_copyrighted|date_valid)_(.*)$/ - key = "#{Regexp.last_match(1)}_attributes".to_sym - # TODO: this only handles one date of each type - processed[key] ||= [{}] - update_date(processed[key].first, Regexp.last_match(2), val) - when 'resource_type' - extract_multi_value_field(header, val, processed) - when type_header_pattern + def extract_field(header, val, processed) + return unless val + case header + when 'type', 'id' + # type and id are singular + processed[header.to_sym] = val + when /^(created|issued|date_copyrighted|date_valid)_(.*)$/ + key = "#{Regexp.last_match(1)}_attributes".to_sym + # TODO: this only handles one date of each type + processed[key] ||= [{}] + update_date(processed[key].first, Regexp.last_match(2), val) + when 'resource_type' + extract_multi_value_field(header, val, processed) + when type_header_pattern + update_typed_field(header, val, processed) + when /^contributor$/ + update_contributor(header, val, processed) + when /^collection_(.*)$/ + processed[:collection] ||= {} + update_collection(processed[:collection], Regexp.last_match(1), val) + else + last_entry = Array(processed[header.to_sym]).last + if last_entry.is_a?(Hash) && !last_entry[:name] update_typed_field(header, val, processed) - when /^contributor$/ - update_contributor(header, val, processed) - when /^collection_(.*)$/ - processed[:collection] ||= {} - update_collection(processed[:collection], Regexp.last_match(1), val) else - last_entry = Array(processed[header.to_sym]).last - if last_entry.is_a?(Hash) && !last_entry[:name] - update_typed_field(header, val, processed) - else - extract_multi_value_field(header, val, processed) - end + extract_multi_value_field(header, val, processed) end end + end - # Faking a typed field for now. - # TODO: support other types of contributors - def update_contributor(header, val, processed) - key = header.to_sym - processed[key] ||= [] - processed[key] << { name: [val.strip] } - end + # Faking a typed field for now. + # TODO: support other types of contributors + def update_contributor(header, val, processed) + key = header.to_sym + processed[key] ||= [] + processed[key] << { name: [val.strip] } + end - def extract_multi_value_field(header, val, processed, key = nil) - key ||= header.to_sym - processed[key] ||= [] - val = val.strip - # Workaround for https://jira.duraspace.org/browse/FCREPO-2038 - val.delete!("\r") - processed[key] << (looks_like_uri?(val) ? RDF::URI(val) : val) - end + def extract_multi_value_field(header, val, processed, key = nil) + key ||= header.to_sym + processed[key] ||= [] + val = val.strip + # Workaround for https://jira.duraspace.org/browse/FCREPO-2038 + val.delete!("\r") + processed[key] << (looks_like_uri?(val) ? RDF::URI(val) : val) + end - def looks_like_uri?(str) - str =~ %r{^https?://} - end + def looks_like_uri?(str) + str =~ %r{^https?://} + end - # Fields that have an associated *_type column - def update_typed_field(header, val, processed) - if header.match(type_header_pattern) - stripped_header = header.gsub('_type', '') - processed[stripped_header.to_sym] ||= [] - processed[stripped_header.to_sym] << { type: val } - else - fields = Array(processed[header.to_sym]) - fields.last[:name] = val - end + # Fields that have an associated *_type column + def update_typed_field(header, val, processed) + if header.match(type_header_pattern) + stripped_header = header.gsub('_type', '') + processed[stripped_header.to_sym] ||= [] + processed[stripped_header.to_sym] << { type: val } + else + fields = Array(processed[header.to_sym]) + fields.last[:name] = val end + end - def update_collection(collection, field, val) - val = [val] unless %w[admin_policy_id id].include? field - collection[field.to_sym] = val - end + def update_collection(collection, field, val) + val = [val] unless %w[admin_policy_id id].include? field + collection[field.to_sym] = val + end - def update_date(date, field, val) - date[field.to_sym] ||= [] - date[field.to_sym] << val - end + def update_date(date, field, val) + date[field.to_sym] ||= [] + date[field.to_sym] << val + end end # rubocop:enable Metrics/ClassLength end diff --git a/lib/importer/factory/object_factory.rb b/lib/importer/factory/object_factory.rb index 228cfe322..2fa0bd1ed 100644 --- a/lib/importer/factory/object_factory.rb +++ b/lib/importer/factory/object_factory.rb @@ -94,64 +94,64 @@ def log_updated(obj) private - # @param [Hash] attrs the attributes to put in the environment - # @return [Hyrax::Actors::Environment] - def environment(attrs) - Hyrax::Actors::Environment.new(@object, Ability.new(User.batch_user), attrs) - end + # @param [Hash] attrs the attributes to put in the environment + # @return [Hyrax::Actors::Environment] + def environment(attrs) + Hyrax::Actors::Environment.new(@object, Ability.new(User.batch_user), attrs) + end - def work_actor - Hyrax::CurationConcern.actor - end + def work_actor + Hyrax::CurationConcern.actor + end - def create_collection(attrs) - @object.attributes = attrs - @object.apply_depositor_metadata(User.batch_user) - @object.save! - end + def create_collection(attrs) + @object.attributes = attrs + @object.apply_depositor_metadata(User.batch_user) + @object.save! + end - # Override if we need to map the attributes from the parser in - # a way that is compatible with how the factory needs them. - def transform_attributes - StringLiteralProcessor.process(attributes.slice(*permitted_attributes)) - .merge(file_attributes) - end + # Override if we need to map the attributes from the parser in + # a way that is compatible with how the factory needs them. + def transform_attributes + StringLiteralProcessor.process(attributes.slice(*permitted_attributes)) + .merge(file_attributes) + end - # Find existing file or upload new file. This assumes a Work will have unique file titles; - # could filter by URIs instead (slower). - # When an uploaded_file already exists we do not want to pass its id in `file_attributes` - # otherwise it gets reuploaded by `work_actor`. - def upload_ids - work_files_titles = object.file_sets.map(&:title) if object.present? && object.file_sets.present? - work_files_titles&.include?(attributes[:file]) ? [] : [import_file(file_paths.first)] - end + # Find existing file or upload new file. This assumes a Work will have unique file titles; + # could filter by URIs instead (slower). + # When an uploaded_file already exists we do not want to pass its id in `file_attributes` + # otherwise it gets reuploaded by `work_actor`. + def upload_ids + work_files_titles = object.file_sets.map(&:title) if object.present? && object.file_sets.present? + work_files_titles&.include?(attributes[:file]) ? [] : [import_file(file_paths.first)] + end - def file_attributes - hash = {} - hash[:uploaded_files] = upload_ids if files_directory.present? && attributes[:file].present? - hash[:remote_files] = attributes[:remote_files] if attributes[:remote_files].present? - hash - end + def file_attributes + hash = {} + hash[:uploaded_files] = upload_ids if files_directory.present? && attributes[:file].present? + hash[:remote_files] = attributes[:remote_files] if attributes[:remote_files].present? + hash + end - def file_paths - attributes[:file]&.map { |file_name| File.join(files_directory, file_name) } - end + def file_paths + attributes[:file]&.map { |file_name| File.join(files_directory, file_name) } + end - def import_file(path) - u = Hyrax::UploadedFile.new - u.user_id = User.find_by_user_key(User.batch_user_key).id if User.find_by_user_key(User.batch_user_key) - u.file = CarrierWave::SanitizedFile.new(path) - u.save - u.id - end + def import_file(path) + u = Hyrax::UploadedFile.new + u.user_id = User.find_by_user_key(User.batch_user_key).id if User.find_by_user_key(User.batch_user_key) + u.file = CarrierWave::SanitizedFile.new(path) + u.save + u.id + end - ## TO DO: handle invalid file in CSV - ## currently the importer stops if no file corresponding to a given file_name is found + ## TO DO: handle invalid file in CSV + ## currently the importer stops if no file corresponding to a given file_name is found - # Regardless of what the MODS Parser gives us, these are the properties we are prepared to accept. - def permitted_attributes - klass.properties.keys.map(&:to_sym) + %i[id edit_users edit_groups read_groups visibility] - end + # Regardless of what the MODS Parser gives us, these are the properties we are prepared to accept. + def permitted_attributes + klass.properties.keys.map(&:to_sym) + %i[id edit_users edit_groups read_groups visibility] + end end end end diff --git a/lib/importer/factory/with_associated_collection.rb b/lib/importer/factory/with_associated_collection.rb index cea1a2cf2..fe9c1f4c5 100644 --- a/lib/importer/factory/with_associated_collection.rb +++ b/lib/importer/factory/with_associated_collection.rb @@ -21,9 +21,9 @@ def update_attributes private - def collection - CollectionFactory.new(attributes.fetch(:collection)).find_or_create - end + def collection + CollectionFactory.new(attributes.fetch(:collection)).find_or_create + end end end end diff --git a/lib/importer/mods_parser.rb b/lib/importer/mods_parser.rb index 6dcc97152..93714d217 100644 --- a/lib/importer/mods_parser.rb +++ b/lib/importer/mods_parser.rb @@ -241,71 +241,71 @@ def notes private - def build_date(node) - finish = finish_point(node) - start = start_point(node) - dates = [{ start: start.map(&:text), finish: finish.map(&:text), label: date_label(node), - start_qualifier: qualifier(start), finish_qualifier: qualifier(finish) }] - dates.delete_if { |date| date.values.all?(&:blank?) } - dates - end + def build_date(node) + finish = finish_point(node) + start = start_point(node) + dates = [{ start: start.map(&:text), finish: finish.map(&:text), label: date_label(node), + start_qualifier: qualifier(start), finish_qualifier: qualifier(finish) }] + dates.delete_if { |date| date.values.all?(&:blank?) } + dates + end - def qualifier(nodes) - nodes.map { |node| node.attributes['qualifier'].try(:value) }.compact - end + def qualifier(nodes) + nodes.map { |node| node.attributes['qualifier'].try(:value) }.compact + end - def finish_point(node) - node.css('[point="end"]') - end + def finish_point(node) + node.css('[point="end"]') + end - def start_point(node) - node.css("[encoding]:not([point='end'])") - end + def start_point(node) + node.css("[encoding]:not([point='end'])") + end - def date_label(node) - node.css(':not([encoding])').map(&:text) - end + def date_label(node) + node.css(':not([encoding])').map(&:text) + end - def untyped_title - mods.xpath('/mods:mods/mods:titleInfo[not(@type)]/mods:title', NAMESPACES).map(&:text) - end + def untyped_title + mods.xpath('/mods:mods/mods:titleInfo[not(@type)]/mods:title', NAMESPACES).map(&:text) + end - def alt_title - Array(mods.xpath('//mods:titleInfo[@type]', NAMESPACES)).flat_map do |node| - type = node.attributes['type'].text - alternative = 'alternative' + def alt_title + Array(mods.xpath('//mods:titleInfo[@type]', NAMESPACES)).flat_map do |node| + type = node.attributes['type'].text + alternative = 'alternative' - node.title.map do |title| - value = title.text - warn_title_transform(type, value) unless type == alternative - value - end + node.title.map do |title| + value = title.text + warn_title_transform(type, value) unless type == alternative + value end end + end - def warn_title_tranform(type, value) - Rails.logger.warn "Transformtion: \"#{type} title\" will be stored as \"alternative title\": #{value}" - end + def warn_title_tranform(type, value) + Rails.logger.warn "Transformtion: \"#{type} title\" will be stored as \"alternative title\": #{value}" + end - def prepend_timestamp(text) - "#{Time.now.utc.to_s(:iso8601)} #{text}" - end + def prepend_timestamp(text) + "#{Time.now.utc.to_s(:iso8601)} #{text}" + end - def strip_whitespace(text) - text.tr("\n", ' ').delete("\t") - end + def strip_whitespace(text) + text.tr("\n", ' ').delete("\t") + end - def subject - query = '//mods:subject/mods:name/@valueURI|//mods:subject/mods:topic/@valueURI' - uris = mods.xpath(query, NAMESPACES).map { |uri| RDF::URI.new(uri) } - return uris unless uris.empty? - mods.subject.map do |sub| - text = sub.css('name namePart').text - secondary = sub.css('topic,genre').text - text += " -- #{secondary}" if secondary.present? - text - end + def subject + query = '//mods:subject/mods:name/@valueURI|//mods:subject/mods:topic/@valueURI' + uris = mods.xpath(query, NAMESPACES).map { |uri| RDF::URI.new(uri) } + return uris unless uris.empty? + mods.subject.map do |sub| + text = sub.css('name namePart').text + secondary = sub.css('topic,genre').text + text += " -- #{secondary}" if secondary.present? + text end + end end # rubocop:enable Metrics/ClassLength end diff --git a/lib/stanford/importer/mods_parser.rb b/lib/stanford/importer/mods_parser.rb index ca9ca47c1..7d61b74de 100644 --- a/lib/stanford/importer/mods_parser.rb +++ b/lib/stanford/importer/mods_parser.rb @@ -30,14 +30,14 @@ def collection_id private - def identifier - id = File.basename(filename, '.mods').sub(/\Adruid_/, '') - { identifier: Array.wrap(id), id: id } - end + def identifier + id = File.basename(filename, '.mods').sub(/\Adruid_/, '') + { identifier: Array.wrap(id), id: id } + end - def open_access - { visibility: Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC } - end + def open_access + { visibility: Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC } + end end end end diff --git a/lib/stanford/importer/purl_parser.rb b/lib/stanford/importer/purl_parser.rb index 4fe36417e..314b32dcf 100644 --- a/lib/stanford/importer/purl_parser.rb +++ b/lib/stanford/importer/purl_parser.rb @@ -159,17 +159,17 @@ def collection_id private - def untyped_title - oai.xpath('./dc:title', DC_NS).map(&:text) - end + def untyped_title + oai.xpath('./dc:title', DC_NS).map(&:text) + end - def prepend_timestamp(text) - "#{Time.now.utc.to_s(:iso8601)} #{text}" - end + def prepend_timestamp(text) + "#{Time.now.utc.to_s(:iso8601)} #{text}" + end - def subject - oai.xpath('./dc:subject', DC_NS).map(&:text) - end + def subject + oai.xpath('./dc:subject', DC_NS).map(&:text) + end end # rubocop:enable Metrics/ClassLength end diff --git a/lib/stanford/importer/purl_retriever.rb b/lib/stanford/importer/purl_retriever.rb index 9977d2a85..373d5f7bb 100644 --- a/lib/stanford/importer/purl_retriever.rb +++ b/lib/stanford/importer/purl_retriever.rb @@ -17,16 +17,16 @@ def get private - def path - "/#{@druid}.xml" - end + def path + "/#{@druid}.xml" + end - def conn - @conn ||= Faraday.new(url: 'https://purl.stanford.edu') do |faraday| - faraday.adapter :httpclient - faraday.use Faraday::Response::RaiseError # raise exceptions on 40x, 50x responses - end + def conn + @conn ||= Faraday.new(url: 'https://purl.stanford.edu') do |faraday| + faraday.adapter :httpclient + faraday.use Faraday::Response::RaiseError # raise exceptions on 40x, 50x responses end + end end end end diff --git a/spec/factories/admin_sets.rb b/spec/factories/admin_sets.rb index fc084b80c..96cde0a62 100644 --- a/spec/factories/admin_sets.rb +++ b/spec/factories/admin_sets.rb @@ -16,9 +16,7 @@ attributes[:manage_groups] = [Ability.admin_group_name] attributes[:deposit_groups] = ['work_editor', 'work_depositor'] attributes[:view_groups] = ['work_editor'] - if evaluator.with_permission_template.respond_to?(:merge) - attributes = evaluator.with_permission_template.merge(attributes) - end + attributes = evaluator.with_permission_template.merge(attributes) if evaluator.with_permission_template.respond_to?(:merge) # There is a unique constraint on permission_templates.source_id; I don't want to # create a permission template if one already exists for this admin_set create(:permission_template, attributes) unless Hyrax::PermissionTemplate.find_by(source_id: admin_set.id) diff --git a/spec/factories/collection_types.rb b/spec/factories/collection_types.rb index 85cb0b3c3..7211b5e0d 100644 --- a/spec/factories/collection_types.rb +++ b/spec/factories/collection_types.rb @@ -117,9 +117,7 @@ # Workaround for upstream issue https://github.com/samvera/hyrax/issues/3136 before(:create) do |collection_type| - if collection_type.title =~ /^translation missing/ - collection_type.title = I18n.t(collection_type.title.gsub("translation missing: en.", '')) - end + collection_type.title = I18n.t(collection_type.title.gsub("translation missing: en.", '')) if /^translation missing/.match?(collection_type.title) end end @@ -128,9 +126,7 @@ # Workaround for upstream issue https://github.com/samvera/hyrax/issues/3136 before(:create) do |collection_type| - if collection_type.title =~ /^translation missing/ - collection_type.title = I18n.t(collection_type.title.gsub("translation missing: en.", '')) - end + collection_type.title = I18n.t(collection_type.title.gsub("translation missing: en.", '')) if /^translation missing/.match?(collection_type.title) end end end diff --git a/spec/factories/collections.rb b/spec/factories/collections.rb index 61583ed9a..ab4ed9e42 100644 --- a/spec/factories/collections.rb +++ b/spec/factories/collections.rb @@ -206,9 +206,7 @@ before(:create) do |collection, evaluator| # force create a permission template if it doesn't exist for the newly created collection - unless evaluator.with_permission_template - CollectionLwFactoryHelper.process_with_permission_template(collection, evaluator, true) - end + CollectionLwFactoryHelper.process_with_permission_template(collection, evaluator, true) unless evaluator.with_permission_template end after(:create) do |collection, _evaluator| @@ -279,9 +277,7 @@ if evaluator.with_permission_template attributes = { source_id: collection.id } attributes[:manage_users] = [evaluator.user] - if evaluator.with_permission_template.respond_to?(:merge) - attributes = evaluator.with_permission_template.merge(attributes) - end + attributes = evaluator.with_permission_template.merge(attributes) if evaluator.with_permission_template.respond_to?(:merge) create(:permission_template, attributes) unless Hyrax::PermissionTemplate.find_by(source_id: collection.id) end end @@ -384,12 +380,8 @@ def self.process_with_permission_template(collection, evaluator, force = false) # OVERRIDE: add default group PermissionTemplateAccess for collection roles attributes[:manage_groups] = group_managers(evaluator.with_permission_template) attributes[:view_groups] = group_viewers(evaluator.with_permission_template) - if evaluator.with_permission_template.respond_to?(:merge) - attributes = evaluator.with_permission_template.merge(attributes) - end - unless Hyrax::PermissionTemplate.find_by(source_id: collection.id) # rubocop:disable Style/GuardClause - FactoryBot.create(:permission_template, attributes) - end + attributes = evaluator.with_permission_template.merge(attributes) if evaluator.with_permission_template.respond_to?(:merge) + FactoryBot.create(:permission_template, attributes) unless Hyrax::PermissionTemplate.find_by(source_id: collection.id) # rubocop:disable Style/GuardClause end # Process the with_nesting_attributes transient property such that... diff --git a/spec/factories/permission_templates.rb b/spec/factories/permission_templates.rb index 5112ef46c..6d02a4312 100644 --- a/spec/factories/permission_templates.rb +++ b/spec/factories/permission_templates.rb @@ -49,24 +49,12 @@ workflow = create(:workflow, active: true, permission_template: permission_template) create(:workflow_action, workflow: workflow) # Need to create a single action that can be taken end - if evaluator.manage_users.present? - AccessHelper.create_access(permission_template, 'user', :manage, evaluator.manage_users) - end - if evaluator.manage_groups.present? - AccessHelper.create_access(permission_template, 'group', :manage, evaluator.manage_groups) - end - if evaluator.deposit_users.present? - AccessHelper.create_access(permission_template, 'user', :deposit, evaluator.deposit_users) - end - if evaluator.deposit_groups.present? - AccessHelper.create_access(permission_template, 'group', :deposit, evaluator.deposit_groups) - end - if evaluator.view_users.present? - AccessHelper.create_access(permission_template, 'user', :view, evaluator.view_users) - end - if evaluator.view_groups.present? - AccessHelper.create_access(permission_template, 'group', :view, evaluator.view_groups) - end + AccessHelper.create_access(permission_template, 'user', :manage, evaluator.manage_users) if evaluator.manage_users.present? + AccessHelper.create_access(permission_template, 'group', :manage, evaluator.manage_groups) if evaluator.manage_groups.present? + AccessHelper.create_access(permission_template, 'user', :deposit, evaluator.deposit_users) if evaluator.deposit_users.present? + AccessHelper.create_access(permission_template, 'group', :deposit, evaluator.deposit_groups) if evaluator.deposit_groups.present? + AccessHelper.create_access(permission_template, 'user', :view, evaluator.view_users) if evaluator.view_users.present? + AccessHelper.create_access(permission_template, 'group', :view, evaluator.view_groups) if evaluator.view_groups.present? end transient do diff --git a/spec/lib/importer/csv_importer_spec.rb b/spec/lib/importer/csv_importer_spec.rb index 249704e17..5a7f699d3 100644 --- a/spec/lib/importer/csv_importer_spec.rb +++ b/spec/lib/importer/csv_importer_spec.rb @@ -11,7 +11,7 @@ let(:fallback_class) { Class.new { def initialize(_argx, _argy); end } } let(:factory) { double(run: true) } - # note: 2 rows do not specify type, 17 do + # NOTE: 2 rows do not specify type, 17 do it 'creates new works' do expect(fallback_class).to receive(:new) .with(any_args).and_return(factory).twice diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index 3f8e94c07..915081436 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -339,7 +339,7 @@ it 'solr_endpoint' do account2 = described_class.new(name: 'other', solr_endpoint: endpoint) expect { account2.save }.to raise_error(ActiveRecord::RecordNotUnique) - # Note: this is different than just populating account2.errors, because it is a FK + # NOTE: this is different than just populating account2.errors, because it is a FK end end end diff --git a/spec/presenters/hyku/admin/group/navigation_presenter_spec.rb b/spec/presenters/hyku/admin/group/navigation_presenter_spec.rb index 79fbf40e6..a6839c78d 100644 --- a/spec/presenters/hyku/admin/group/navigation_presenter_spec.rb +++ b/spec/presenters/hyku/admin/group/navigation_presenter_spec.rb @@ -21,7 +21,7 @@ end it 'has the edit tab marked as active' do - expect(subject.select { |tab| tab.css_class == active_css_class && tab.action == action }.count).to be(1) + expect(subject.count { |tab| tab.css_class == active_css_class && tab.action == action }).to be(1) end end @@ -37,7 +37,7 @@ end it 'has the members tab marked as active' do - expect(subject.select { |tab| tab.css_class == active_css_class && tab.action == action }.count).to be(1) + expect(subject.count { |tab| tab.css_class == active_css_class && tab.action == action }).to be(1) end end @@ -53,7 +53,7 @@ end it 'has the roles tab marked as active' do - expect(subject.select { |tab| tab.css_class == active_css_class && tab.action == action }.count).to be(1) + expect(subject.count { |tab| tab.css_class == active_css_class && tab.action == action }).to be(1) end end @@ -69,7 +69,7 @@ end it 'has the remove tab marked as active' do - expect(subject.select { |tab| tab.css_class == active_css_class && tab.action == action }.count).to be(1) + expect(subject.count { |tab| tab.css_class == active_css_class && tab.action == action }).to be(1) end end end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index efc9ff4e9..33c069b56 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -170,11 +170,9 @@ end config.after do - begin - DatabaseCleaner.clean - rescue NoMethodError - 'This can happen which the database is gone, which depends on load order of tests' - end + DatabaseCleaner.clean + rescue NoMethodError + 'This can happen which the database is gone, which depends on load order of tests' end end diff --git a/spec/views/account_sign_up/new.html.erb_spec.rb b/spec/views/account_sign_up/new.html.erb_spec.rb index 917b0c5c9..ec7282d4d 100644 --- a/spec/views/account_sign_up/new.html.erb_spec.rb +++ b/spec/views/account_sign_up/new.html.erb_spec.rb @@ -4,7 +4,7 @@ before do assign(:account, Account.new( name: "MyString" - )) + )) end it "renders new account form" do diff --git a/spec/views/proprietor/accounts/new.html.erb_spec.rb b/spec/views/proprietor/accounts/new.html.erb_spec.rb index cda7c343e..f61bd90e4 100644 --- a/spec/views/proprietor/accounts/new.html.erb_spec.rb +++ b/spec/views/proprietor/accounts/new.html.erb_spec.rb @@ -4,7 +4,7 @@ before do assign(:account, Account.new( name: "MyString" - )) + )) end it "renders new account form" do diff --git a/spec/views/proprietor/users/new.html.erb_spec.rb b/spec/views/proprietor/users/new.html.erb_spec.rb index 3c071651b..a7b6d3732 100644 --- a/spec/views/proprietor/users/new.html.erb_spec.rb +++ b/spec/views/proprietor/users/new.html.erb_spec.rb @@ -28,7 +28,7 @@ zotero_token: "", zotero_userid: "MyString", preferred_locale: "MyString" - )) + )) end it "renders new proprietor_user form" do diff --git a/spec/views/proprietor/users/show.html.erb_spec.rb b/spec/views/proprietor/users/show.html.erb_spec.rb index a1a8e6a1d..bbcfe9df7 100644 --- a/spec/views/proprietor/users/show.html.erb_spec.rb +++ b/spec/views/proprietor/users/show.html.erb_spec.rb @@ -28,7 +28,7 @@ zotero_token: "", zotero_userid: "Zotero Userid", preferred_locale: "Preferred Locale" - )) + )) end it "renders attributes in

    " do From 6859d739cfd0684622819a703fe2856443759d8d Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Wed, 13 Dec 2023 15:23:35 -0800 Subject: [PATCH 068/126] =?UTF-8?q?=F0=9F=A7=B9=20Autocorrect=20frozen=20s?= =?UTF-8?q?tring=20literals?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ```sh rubocop --only Style/FrozenStringLiteralComment -A ``` --- Rakefile | 2 ++ app/controllers/hyrax/dashboard/collections_controller.rb | 2 ++ bin/bundle | 2 ++ bin/extract_mods_to_spreadsheet | 2 ++ bin/git-cleanup | 1 + bin/graph | 1 + bin/import_from_csv | 1 + bin/import_from_purl | 1 + bin/import_mods_files | 1 + bin/rails | 1 + bin/rake | 1 + bin/setup | 1 + bin/spring | 1 + bin/update | 1 + bin/web | 1 + bin/worker | 1 + config/application.rb | 1 + config/boot.rb | 1 + config/environment.rb | 1 + config/environments/development.rb | 1 + config/environments/production.rb | 1 + config/environments/test.rb | 1 + config/initializers/0db_created.rb | 1 + config/initializers/active_fedora_override.rb | 1 + config/initializers/apartment.rb | 1 + config/initializers/apartment_activejob.rb | 1 + config/initializers/application_controller_renderer.rb | 1 + config/initializers/assets.rb | 1 + config/initializers/backtrace_silencers.rb | 1 + config/initializers/clamav.rb | 1 + config/initializers/cookies_serializer.rb | 1 + config/initializers/devise.rb | 1 + config/initializers/file_set_derivatives_overrides.rb | 1 + config/initializers/filter_parameter_logging.rb | 1 + config/initializers/hydra_config.rb | 1 + config/initializers/hyrax.rb | 1 + config/initializers/iiif_print.rb | 1 + config/initializers/inflections.rb | 1 + config/initializers/mailboxer.rb | 1 + config/initializers/mime_types.rb | 1 + config/initializers/mini_magick.rb | 1 + config/initializers/new_framework_defaults.rb | 1 + config/initializers/redis_config.rb | 1 + config/initializers/riiif.rb | 1 + config/initializers/rolify.rb | 1 + config/initializers/secure_headers.rb | 1 + config/initializers/session_store.rb | 1 + config/initializers/sidekiq.rb | 1 + config/initializers/simple_form.rb | 1 + config/initializers/simple_form_bootstrap.rb | 2 ++ config/initializers/stats_admin.rb | 2 ++ config/initializers/version.rb | 4 +++- config/initializers/wrap_parameters.rb | 2 ++ config/puma.rb | 1 + config/spring.rb | 1 + lib/tasks/rubocop.rake | 1 + 56 files changed, 65 insertions(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index f55260d5d..8f8cb932c 100644 --- a/Rakefile +++ b/Rakefile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Add your own tasks in files placed in lib/tasks ending in .rake, # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. diff --git a/app/controllers/hyrax/dashboard/collections_controller.rb b/app/controllers/hyrax/dashboard/collections_controller.rb index 67e9de1ec..613a34a8a 100644 --- a/app/controllers/hyrax/dashboard/collections_controller.rb +++ b/app/controllers/hyrax/dashboard/collections_controller.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # OVERRIDE Hyrax v3.4.2 # - Fix file upload in logo and banner # - Use work titles for collection thumbnail select & to add an option to reset to the default thumbnail diff --git a/bin/bundle b/bin/bundle index 66e9889e8..282e7d515 100755 --- a/bin/bundle +++ b/bin/bundle @@ -1,3 +1,5 @@ +# frozen_string_literal: true + #!/usr/bin/env ruby ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) load Gem.bin_path('bundler', 'bundle') diff --git a/bin/extract_mods_to_spreadsheet b/bin/extract_mods_to_spreadsheet index 822c783b6..7998f57e8 100755 --- a/bin/extract_mods_to_spreadsheet +++ b/bin/extract_mods_to_spreadsheet @@ -1,3 +1,5 @@ +# frozen_string_literal: true + #!/usr/bin/env ruby # this script is intented to produce a sample spreadsheet from diff --git a/bin/git-cleanup b/bin/git-cleanup index 0b1fc6a35..42fda0768 100755 --- a/bin/git-cleanup +++ b/bin/git-cleanup @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true `git fetch -ap` branches = `git branch --merged main`.split("\n").collect { |b| b.delete('*').strip } diff --git a/bin/graph b/bin/graph index 6ff6fa1e3..939279f7e 100644 --- a/bin/graph +++ b/bin/graph @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true # This script creates png images to visualize a Hyrax workflow # Usage: bin/graph diff --git a/bin/import_from_csv b/bin/import_from_csv index f3fd50dbc..fb4faf3a0 100755 --- a/bin/import_from_csv +++ b/bin/import_from_csv @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true def validate_hostname!(hostname) return if hostname diff --git a/bin/import_from_purl b/bin/import_from_purl index 9b6b214d0..4e0c00463 100755 --- a/bin/import_from_purl +++ b/bin/import_from_purl @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true def validate_hostname!(hostname) return if hostname diff --git a/bin/import_mods_files b/bin/import_mods_files index 7398057c8..dd8cacdfa 100755 --- a/bin/import_mods_files +++ b/bin/import_mods_files @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true def validate_hostname!(hostname) return if hostname diff --git a/bin/rails b/bin/rails index 073966023..dd027b406 100755 --- a/bin/rails +++ b/bin/rails @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true APP_PATH = File.expand_path('../config/application', __dir__) require_relative '../config/boot' require 'rails/commands' diff --git a/bin/rake b/bin/rake index 17240489f..609af7470 100755 --- a/bin/rake +++ b/bin/rake @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true require_relative '../config/boot' require 'rake' Rake.application.run diff --git a/bin/setup b/bin/setup index e620b4dad..ffca742a1 100755 --- a/bin/setup +++ b/bin/setup @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true require 'pathname' require 'fileutils' include FileUtils diff --git a/bin/spring b/bin/spring index 7fe232c3a..99c5cacd8 100755 --- a/bin/spring +++ b/bin/spring @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true # This file loads spring without using Bundler, in order to be fast. # It gets overwritten when you run the `spring binstub` command. diff --git a/bin/update b/bin/update index a8e4462f2..3f81e5496 100755 --- a/bin/update +++ b/bin/update @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true require 'pathname' require 'fileutils' include FileUtils diff --git a/bin/web b/bin/web index 2fd50cdf5..46e648166 100755 --- a/bin/web +++ b/bin/web @@ -1,4 +1,5 @@ #!/usr/local/bin/ruby +# frozen_string_literal: true `echo "$GOOGLE_OAUTH_PRIVATE_KEY_VALUE" | base64 -d > prod-cred.p12` if ENV['GOOGLE_OAUTH_PRIVATE_KEY_VALUE'].present? exec "bundle exec puma -v -b tcp://0.0.0.0:3000" diff --git a/bin/worker b/bin/worker index 1ab592264..b3cb34ce5 100755 --- a/bin/worker +++ b/bin/worker @@ -1,4 +1,5 @@ #!/usr/local/bin/ruby +# frozen_string_literal: true `echo "$GOOGLE_OAUTH_PRIVATE_KEY_VALUE" | base64 -d > prod-cred.p12` if ENV['GOOGLE_OAUTH_PRIVATE_KEY_VALUE'].present? if ENV['DATABASE_URL'].present? diff --git a/config/application.rb b/config/application.rb index d6356bc09..b8a43824d 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true require_relative 'boot' require_relative '../app/middleware/no_cache_middleware' diff --git a/config/boot.rb b/config/boot.rb index 30f5120df..9be337a42 100644 --- a/config/boot.rb +++ b/config/boot.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) require 'bundler/setup' # Set up gems listed in the Gemfile. diff --git a/config/environment.rb b/config/environment.rb index 426333bb4..12ea62f88 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # Load the Rails application. require_relative 'application' diff --git a/config/environments/development.rb b/config/environments/development.rb index 448ece68d..2f2bf2195 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. diff --git a/config/environments/production.rb b/config/environments/production.rb index b6cdf3770..e57bb998e 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. diff --git a/config/environments/test.rb b/config/environments/test.rb index 30587ef6d..416a71c86 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. diff --git a/config/initializers/0db_created.rb b/config/initializers/0db_created.rb index ffd0e463c..8f4e56f85 100644 --- a/config/initializers/0db_created.rb +++ b/config/initializers/0db_created.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true def db_created? ::ActiveRecord::Base.connection_pool.with_connection(&:active?) rescue diff --git a/config/initializers/active_fedora_override.rb b/config/initializers/active_fedora_override.rb index 58ec7fe04..e595997ae 100644 --- a/config/initializers/active_fedora_override.rb +++ b/config/initializers/active_fedora_override.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # Based on https://github.com/samvera/hyrax/issues/4581#issuecomment-843085122 # Monkey-patch to short circuit ActiveModel::Dirty which attempts to load the whole master files ordered list when calling nodes_will_change! diff --git a/config/initializers/apartment.rb b/config/initializers/apartment.rb index 6acc1fd12..e294580f0 100644 --- a/config/initializers/apartment.rb +++ b/config/initializers/apartment.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true if ENV['DB_ADAPTER'] != 'nulldb' && db_created? # You can have Apartment route to the appropriate Tenant by adding some Rack middleware. # Apartment can support many different "Elevators" that can take care of this routing to your data. diff --git a/config/initializers/apartment_activejob.rb b/config/initializers/apartment_activejob.rb index 6f2b410cf..9073c7400 100644 --- a/config/initializers/apartment_activejob.rb +++ b/config/initializers/apartment_activejob.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true require 'active_job' require 'active_job_tenant' diff --git a/config/initializers/application_controller_renderer.rb b/config/initializers/application_controller_renderer.rb index 51639b67a..315ac48a9 100644 --- a/config/initializers/application_controller_renderer.rb +++ b/config/initializers/application_controller_renderer.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # Be sure to restart your server when you modify this file. # ApplicationController.renderer.defaults.merge!( diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index 01ef3e663..9287bcd33 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # Be sure to restart your server when you modify this file. # Version of your assets, change this if you want to expire all your assets. diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb index 59385cdf3..d0f0d3b5d 100644 --- a/config/initializers/backtrace_silencers.rb +++ b/config/initializers/backtrace_silencers.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # Be sure to restart your server when you modify this file. # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. diff --git a/config/initializers/clamav.rb b/config/initializers/clamav.rb index 7cd26d6a2..7dcb60d7e 100644 --- a/config/initializers/clamav.rb +++ b/config/initializers/clamav.rb @@ -1 +1,2 @@ +# frozen_string_literal: true ClamAV.instance.loaddb if defined? ClamAV diff --git a/config/initializers/cookies_serializer.rb b/config/initializers/cookies_serializer.rb index 5a6a32d37..2a7295959 100644 --- a/config/initializers/cookies_serializer.rb +++ b/config/initializers/cookies_serializer.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # Be sure to restart your server when you modify this file. # Specify a serializer for the signed and encrypted cookie jars. diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 1d86f3c3c..cc50f1782 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # Use this hook to configure devise mailer, warden hooks and so forth. # Many of these configuration options can be set straight in your model. Devise.setup do |config| diff --git a/config/initializers/file_set_derivatives_overrides.rb b/config/initializers/file_set_derivatives_overrides.rb index ace70d032..7ae9c0ade 100644 --- a/config/initializers/file_set_derivatives_overrides.rb +++ b/config/initializers/file_set_derivatives_overrides.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # This file contains overrides to Hyrax::FileSetDerivativesService to increase the size of thumbnails # Hyrax v3.5.0 diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb index 4a994e1e7..b7fe1231f 100644 --- a/config/initializers/filter_parameter_logging.rb +++ b/config/initializers/filter_parameter_logging.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # Be sure to restart your server when you modify this file. # Configure sensitive parameters which will be filtered from the log file. diff --git a/config/initializers/hydra_config.rb b/config/initializers/hydra_config.rb index 35f9eccd6..42f406838 100644 --- a/config/initializers/hydra_config.rb +++ b/config/initializers/hydra_config.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # windows doesn't properly require hydra-head (from the gemfile), so we need to require it explicitly here: require 'hydra/head' unless defined? Hydra diff --git a/config/initializers/hyrax.rb b/config/initializers/hyrax.rb index 6cd21a831..6147b7b1f 100644 --- a/config/initializers/hyrax.rb +++ b/config/initializers/hyrax.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # Set nested indexer to graph by default. Remove after Hyrax 4.0 upgrade ENV['HYRAX_USE_SOLR_GRAPH_NESTING'].present? || ENV['HYRAX_USE_SOLR_GRAPH_NESTING'] = "true" diff --git a/config/initializers/iiif_print.rb b/config/initializers/iiif_print.rb index c97d5bd58..b1b90418e 100644 --- a/config/initializers/iiif_print.rb +++ b/config/initializers/iiif_print.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true IiifPrint.config do |config| # NOTE: WorkTypes and models are used synonymously here. # Add models to be excluded from search so the user diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index ac033bf9d..aa7435fbc 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # Be sure to restart your server when you modify this file. # Add new inflection rules using the following format. Inflections diff --git a/config/initializers/mailboxer.rb b/config/initializers/mailboxer.rb index f244e1996..b27f6d083 100644 --- a/config/initializers/mailboxer.rb +++ b/config/initializers/mailboxer.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true Mailboxer.setup do |config| # Configures if you application uses or not email sending for Notifications and Messages config.uses_emails = true diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb index 022642dff..ec9f6f595 100644 --- a/config/initializers/mime_types.rb +++ b/config/initializers/mime_types.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # Be sure to restart your server when you modify this file. # Add new mime types for use in respond_to blocks: diff --git a/config/initializers/mini_magick.rb b/config/initializers/mini_magick.rb index 4d73ff079..7fc113a30 100644 --- a/config/initializers/mini_magick.rb +++ b/config/initializers/mini_magick.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true require 'mini_magick' MiniMagick.configure do |config| diff --git a/config/initializers/new_framework_defaults.rb b/config/initializers/new_framework_defaults.rb index 5c4156533..2543be7c8 100644 --- a/config/initializers/new_framework_defaults.rb +++ b/config/initializers/new_framework_defaults.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # Be sure to restart your server when you modify this file. # # This file contains migration options to ease your Rails 5.0 upgrade. diff --git a/config/initializers/redis_config.rb b/config/initializers/redis_config.rb index 19f95c33d..c1b32817e 100644 --- a/config/initializers/redis_config.rb +++ b/config/initializers/redis_config.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true config = YAML.load(ERB.new(IO.read(Rails.root + 'config' + 'redis.yml')).result)[Rails.env].with_indifferent_access sentinels = config[:sentinel] && config[:sentinel][:host].present? ? { sentinels: [config[:sentinel]] } : {} redis_config = config.except(:sentinel).merge(thread_safe: true).merge(sentinels) diff --git a/config/initializers/riiif.rb b/config/initializers/riiif.rb index 9b7328ee2..9ff19b8ab 100644 --- a/config/initializers/riiif.rb +++ b/config/initializers/riiif.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true Riiif::Image.file_resolver = Riiif::HTTPFileResolver.new Riiif::Image.info_service = lambda do |id, _file| # id will look like a path to a pcdm:file diff --git a/config/initializers/rolify.rb b/config/initializers/rolify.rb index b56270b50..91ab2eaf7 100644 --- a/config/initializers/rolify.rb +++ b/config/initializers/rolify.rb @@ -1,2 +1,3 @@ +# frozen_string_literal: true Rolify.configure do |config| end diff --git a/config/initializers/secure_headers.rb b/config/initializers/secure_headers.rb index bda68ab4d..b0bb7b3e2 100644 --- a/config/initializers/secure_headers.rb +++ b/config/initializers/secure_headers.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true SecureHeaders::Configuration.default do |config| config.cookies = { secure: ActiveRecord::Type::Boolean.new.cast(ENV.fetch('HYKU_SSL_CONFIGURED', false)) || SecureHeaders::OPT_OUT, diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb index d7b7ec0c7..1075162f0 100644 --- a/config/initializers/session_store.rb +++ b/config/initializers/session_store.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # Be sure to restart your server when you modify this file. Rails.application.config.session_store :cookie_store, key: '_hyku_session' diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index dc3a30bae..71c430cf5 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true if ENV.fetch('HYRAX_ACTIVE_JOB_QUEUE', 'sidekiq') == 'sidekiq' config = YAML.load(ERB.new(IO.read(Rails.root + 'config' + 'redis.yml')).result)[Rails.env].with_indifferent_access diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb index 8f26be3c3..8b07d836e 100644 --- a/config/initializers/simple_form.rb +++ b/config/initializers/simple_form.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # NOTE: This is a modified version of simple_form's default config file. # The only changes were to move the input to after the hint and error. diff --git a/config/initializers/simple_form_bootstrap.rb b/config/initializers/simple_form_bootstrap.rb index c5ee0408d..3098be131 100644 --- a/config/initializers/simple_form_bootstrap.rb +++ b/config/initializers/simple_form_bootstrap.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # NOTE: This is a modified version of simple_form's default config file. # The only changes were to move the inputs to after the hints and errors. diff --git a/config/initializers/stats_admin.rb b/config/initializers/stats_admin.rb index 3b6767fb1..b7871feb0 100644 --- a/config/initializers/stats_admin.rb +++ b/config/initializers/stats_admin.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # -*- coding: utf-8 -*- module Hyrax class StatsAdmin diff --git a/config/initializers/version.rb b/config/initializers/version.rb index 65a71d0df..899b92b14 100644 --- a/config/initializers/version.rb +++ b/config/initializers/version.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Hyku - VERSION = '5.1.0'.freeze + VERSION = '5.1.0' end diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb index bbfc3961b..2f3c0db47 100644 --- a/config/initializers/wrap_parameters.rb +++ b/config/initializers/wrap_parameters.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Be sure to restart your server when you modify this file. # This file contains settings for ActionController::ParamsWrapper which diff --git a/config/puma.rb b/config/puma.rb index c7f311f81..14a0f440a 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true # Puma can serve each request in a thread from an internal thread pool. # The `threads` method setting takes two numbers a minimum and maximum. # Any libraries that use thread pools should be configured to match diff --git a/config/spring.rb b/config/spring.rb index 9fa7863f9..240be63ab 100644 --- a/config/spring.rb +++ b/config/spring.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true %w[ .ruby-version .rbenv-vars diff --git a/lib/tasks/rubocop.rake b/lib/tasks/rubocop.rake index 64e964e6d..86de3ac8d 100644 --- a/lib/tasks/rubocop.rake +++ b/lib/tasks/rubocop.rake @@ -1,3 +1,4 @@ +# frozen_string_literal: true begin require 'rubocop/rake_task' From 59626ef4dffb145b2ebf9de2673aac30b629b080 Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Wed, 13 Dec 2023 16:12:57 -0800 Subject: [PATCH 069/126] =?UTF-8?q?=F0=9F=A7=B9=20Rubocop'd=20lengths=20an?= =?UTF-8?q?d=20other=20low=20hanging=20fruit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Various length metrics were disabled in this commit. Also other various cops that were easy to fix. --- app/controllers/catalog_controller.rb | 2 ++ .../concerns/hyrax/works_controller_behavior.rb | 2 ++ app/controllers/hyku/invitations_controller.rb | 2 ++ app/controllers/hyrax/contact_form_controller.rb | 2 ++ .../hyrax/dashboard/collections_controller.rb | 15 +++++++++++---- app/controllers/hyrax/homepage_controller.rb | 2 ++ app/controllers/proprietor/users_controller.rb | 2 ++ app/forms/hyrax/forms/admin/appearance.rb | 2 ++ app/models/account.rb | 2 ++ app/models/concerns/account_settings.rb | 6 ++++++ app/models/concerns/account_switch.rb | 4 +++- .../concerns/hyrax/ability/collection_ability.rb | 6 ++++++ .../hyrax/ability/solr_document_ability.rb | 2 ++ app/models/content_block.rb | 2 ++ .../hyrax/iiif_av/displays_content_decorator.rb | 2 ++ .../hyrax/collection_types/create_service.rb | 2 ++ app/services/hyrax/workflow/permission_query.rb | 12 +++++++----- app/services/roles_service.rb | 8 ++++++++ config/application.rb | 4 ++-- config/environments/development.rb | 5 ++++- config/environments/production.rb | 3 +++ config/initializers/bulkrax.rb | 2 ++ config/initializers/devise.rb | 2 ++ .../file_set_derivatives_overrides.rb | 2 ++ config/initializers/hyrax.rb | 4 +++- config/initializers/redis_config.rb | 2 +- config/initializers/sidekiq.rb | 2 +- config/initializers/simple_form_bootstrap.rb | 2 ++ lib/importer/csv_parser.rb | 3 +++ lib/importer/factory/object_factory.rb | 2 ++ lib/importer/mods_parser.rb | 2 ++ .../provider/metadata_format/hyku_dublin_core.rb | 4 ++++ lib/oai/provider/model_decorator.rb | 2 ++ .../custom_queries/find_ids_by_model_decorator.rb | 3 ++- 34 files changed, 102 insertions(+), 17 deletions(-) diff --git a/app/controllers/catalog_controller.rb b/app/controllers/catalog_controller.rb index ebbb4bf82..ca0ce0738 100644 --- a/app/controllers/catalog_controller.rb +++ b/app/controllers/catalog_controller.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +# rubocop:disable Metrics/ClassLength, Metrics/BlockLength class CatalogController < ApplicationController include BlacklightAdvancedSearch::Controller include BlacklightRangeLimit::ControllerOverride @@ -449,3 +450,4 @@ def show render json: @document.to_h end end +# rubocop:enable Metrics/ClassLength, Metrics/BlockLength diff --git a/app/controllers/concerns/hyrax/works_controller_behavior.rb b/app/controllers/concerns/hyrax/works_controller_behavior.rb index a8f9fa914..8408d7eca 100644 --- a/app/controllers/concerns/hyrax/works_controller_behavior.rb +++ b/app/controllers/concerns/hyrax/works_controller_behavior.rb @@ -333,6 +333,7 @@ def decide_layout # hopefully this can be refactored to be more reusable. # # Add uploaded_files to the parameters received by the actor. + # rubocop:disable Metrics/MethodLength def attributes_for_actor raw_params = params[hash_key_for_curation_concern] attributes = if raw_params @@ -360,6 +361,7 @@ def attributes_for_actor browse_everything_urls attributes end + # rubocop:enable Metrics/MethodLength def after_create_response respond_to do |wants| diff --git a/app/controllers/hyku/invitations_controller.rb b/app/controllers/hyku/invitations_controller.rb index e08ae7b1a..68fe8d21e 100644 --- a/app/controllers/hyku/invitations_controller.rb +++ b/app/controllers/hyku/invitations_controller.rb @@ -10,6 +10,7 @@ def after_invite_path_for(_resource) # override the standard invite so that accounts are added properly # if they already exist on another tenant and invited if they do not + # rubocop:disable Metrics/AbcSize def create authorize! :grant_admin_role, User if params[:user][:role] == ::RolesService::ADMIN_ROLE self.resource = User.find_by(email: params[:user][:email]) || invite_resource @@ -27,6 +28,7 @@ def create respond_with resource, location: after_invite_path_for(current_inviter, resource) end end + # rubocop:enable Metrics/AbcSize protected diff --git a/app/controllers/hyrax/contact_form_controller.rb b/app/controllers/hyrax/contact_form_controller.rb index c88b44ac3..e520429e5 100644 --- a/app/controllers/hyrax/contact_form_controller.rb +++ b/app/controllers/hyrax/contact_form_controller.rb @@ -46,6 +46,7 @@ def new @announcement_text = ContentBlock.for(:announcement) end + # rubocop:disable Metrics/MethodLength, Metrics/AbcSize def create # not spam, form is valid, and captcha is valid @captcha.values[:category] = params[:contact_form][:category] @@ -65,6 +66,7 @@ def create rescue RuntimeError => exception handle_create_exception(exception) end + # rubocop:enable Metrics/MethodLength, Metrics/AbcSize def handle_create_exception(exception) logger.error("Contact form failed to send: #{exception.inspect}") diff --git a/app/controllers/hyrax/dashboard/collections_controller.rb b/app/controllers/hyrax/dashboard/collections_controller.rb index 613a34a8a..072caf38b 100644 --- a/app/controllers/hyrax/dashboard/collections_controller.rb +++ b/app/controllers/hyrax/dashboard/collections_controller.rb @@ -86,7 +86,7 @@ def edit form collection_type # Gets original filename of an uploaded thumbnail. See #update - if ::SolrDocument.find(@collection.id).thumbnail_path.include? "uploaded_collection_thumbnails" and uploaded_thumbnail? + if ::SolrDocument.find(@collection.id).thumbnail_path.include? "uploaded_collection_thumbnails" && uploaded_thumbnail? @thumbnail_filename = File.basename(uploaded_thumbnail_files.reject { |f| File.basename(f).include? @collection.id }.first) end end @@ -209,17 +209,21 @@ def collection # Renders a JSON response with a list of files in this collection # This is used by the edit form to populate the thumbnail_id dropdown # OVERRIDE: Hyrax 2.9 to use work titles for collection thumbnail select & to add an option to reset to the default thumbnail + # rubocop:disable Metrics/MethodLength, Metrics/AbcSize def files params[:q] = '' unless params[:q] builder = Hyrax::CollectionMemberSearchBuilder.new(scope: self, collection: collection, search_includes_models: :works) - # get the default work image because we do not want to show any works in this dropdown that only have the default work image. this indicates that they have no files attached, and will throw an error if selected. + # get the default work image because we do not want to show any works in this + # dropdown that only have the default work image. this indicates that they have + # no files attached, and will throw an error if selected. default_work_thumbnail_path = Site.instance.default_work_image&.url.presence || ActionController::Base.helpers.image_path('default.png') work_with_no_files_thumbnail_path = ActionController::Base.helpers.image_path('work.png') response = repository.search(builder.where(params[:q]).query) # only return the works that have files, because these will be the only ones with a viable thumbnail result = response.documents.reject do |document| - document["thumbnail_path_ss"].blank? || document["thumbnail_path_ss"].include?(default_work_thumbnail_path) || document["thumbnail_path_ss"].include?(work_with_no_files_thumbnail_path) - end .map do |document| + document["thumbnail_path_ss"].blank? || document["thumbnail_path_ss"].include?(default_work_thumbnail_path) || + document["thumbnail_path_ss"].include?(work_with_no_files_thumbnail_path) + end.map do |document| { id: document["thumbnail_path_ss"].split('/').last.gsub(/\?.*/, ''), text: document["title_tesim"].first } end reset_thumbnail_option = { @@ -229,6 +233,7 @@ def files result << reset_thumbnail_option render json: result end + # rubocop:enable Metrics/MethodLength, Metrics/AbcSize private @@ -704,6 +709,7 @@ def after_update_errors(errors) # for valkyrie end end + # rubocop:disable Metrics/MethodLength def process_uploaded_thumbnail(uploaded_file) dir_name = UploadedCollectionThumbnailPathService.upload_dir(@collection) saved_file = Rails.root.join(dir_name, uploaded_file.original_filename) @@ -723,6 +729,7 @@ def process_uploaded_thumbnail(uploaded_file) File.chmod(0o664, "#{dir_name}/#{@collection.id}_thumbnail.jpg") File.chmod(0o664, "#{dir_name}/#{@collection.id}_card.jpg") end + # rubocop:enable Metrics/MethodLength ## OVERRIDE Hyrax 3.4.0 handle file locations def process_file_location(f) diff --git a/app/controllers/hyrax/homepage_controller.rb b/app/controllers/hyrax/homepage_controller.rb index 4039a14a3..67b0690f2 100644 --- a/app/controllers/hyrax/homepage_controller.rb +++ b/app/controllers/hyrax/homepage_controller.rb @@ -44,6 +44,7 @@ def search_builder_class layout 'homepage' helper Hyrax::ContentBlockHelper + # rubocop:disable Metrics/MethodLength def index # BEGIN copy Hyrax prime's Hyrax::HomepageController#index @presenter = presenter_class.new(current_ability, collections) @@ -77,6 +78,7 @@ def index document_export_formats(format) end end + # rubocop:enable Metrics/MethodLength def browserconfig; end diff --git a/app/controllers/proprietor/users_controller.rb b/app/controllers/proprietor/users_controller.rb index c8e160446..bcd44e7a5 100644 --- a/app/controllers/proprietor/users_controller.rb +++ b/app/controllers/proprietor/users_controller.rb @@ -87,6 +87,7 @@ def ensure_admin! authorize! :read, :admin_dashboard end + # rubocop:disable Metrics/MethodLength def user_params # remove blank passwords params[:user].delete(:password) if params[:user] && params[:user][:password].blank? @@ -117,6 +118,7 @@ def user_params :preferred_locale, role_ids: []) end + # rubocop:enable Metrics/MethodLength def find_user @user ||= ::User.from_url_component(params[:id]) diff --git a/app/forms/hyrax/forms/admin/appearance.rb b/app/forms/hyrax/forms/admin/appearance.rb index 49428d012..da3b2802d 100644 --- a/app/forms/hyrax/forms/admin/appearance.rb +++ b/app/forms/hyrax/forms/admin/appearance.rb @@ -371,6 +371,7 @@ def update! end # A list of parameters that are related to customizations + # rubocop:disable Metrics/MethodLength def self.customization_params %i[ body_font @@ -400,6 +401,7 @@ def self.customization_params default_work_image_text ] end + # rubocop:enable Metrics/MethodLength def font_import_body_url body = body_font.split('|').first.to_s.tr(" ", "+") diff --git a/app/models/account.rb b/app/models/account.rb index 449795ac3..eef2a9571 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true # Customer organization account +# rubocop:disable Metrics/ClassLength class Account < ApplicationRecord include AccountEndpoints include AccountSettings @@ -144,3 +145,4 @@ def cache_api? cache_api end end +# rubocop:enable Metrics/ClassLength diff --git a/app/models/concerns/account_settings.rb b/app/models/concerns/account_settings.rb index a0fa4eaba..dcba12122 100644 --- a/app/models/concerns/account_settings.rb +++ b/app/models/concerns/account_settings.rb @@ -3,6 +3,7 @@ # All settings have a presedence order as follows # Per Tenant Setting > ENV['HYKU_SETTING_NAME'] > ENV['HYRAX_SETTING_NAME'] > default +# rubocop:disable Metrics/ModuleLength module AccountSettings extend ActiveSupport::Concern # rubocop:disable Metrics/BlockLength @@ -79,6 +80,7 @@ def setting(name, args) end end + # rubocop:disable Metrics/MethodLength def solr_collection_options { async: nil, @@ -99,6 +101,7 @@ def solr_collection_options snitch: nil } end + # rubocop:disable Metrics/MethodLength end # rubocop:enable Metrics/BlockLength @@ -154,6 +157,7 @@ def set_smtp_settings ) end + # rubocop:disable Metrics/AbcSize def reload_library_config Hyrax.config do |config| config.contact_email = contact_email @@ -188,4 +192,6 @@ def reload_library_config ActionMailer::Base.default_url_options ||= {} ActionMailer::Base.default_url_options[:protocol] = 'https' end + # rubocop:enable Metrics/AbcSize end +# rubocop:enable Metrics/ModuleLength diff --git a/app/models/concerns/account_switch.rb b/app/models/concerns/account_switch.rb index 80fd4c30a..75e46077f 100644 --- a/app/models/concerns/account_switch.rb +++ b/app/models/concerns/account_switch.rb @@ -3,9 +3,10 @@ module AccountSwitch extend ActiveSupport::Concern - DOMAIN_REGEXP = %r{^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,8}(:[0-9]{1,5})?(/.*)?$}ix + DOMAIN_REGEXP = %r{^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,8}(:[0-9]{1,5})?(/.*)?$}ix.freeze class_methods do + # rubocop:disable Metrics/MethodLength def switch!(cname_or_name_or_account) account = if cname_or_name_or_account.is_a?(Account) cname_or_name_or_account @@ -26,6 +27,7 @@ def switch!(cname_or_name_or_account) Rails.logger.info "It looks like we're in single tenant mode. No tenant found for #{cname_or_name_or_account}" end end + # rubocop:enable Metrics/MethodLength end def switch!(cname_or_name_or_account) diff --git a/app/models/concerns/hyrax/ability/collection_ability.rb b/app/models/concerns/hyrax/ability/collection_ability.rb index 3af46e0c2..4f208b412 100644 --- a/app/models/concerns/hyrax/ability/collection_ability.rb +++ b/app/models/concerns/hyrax/ability/collection_ability.rb @@ -3,10 +3,13 @@ # OVERRIDE Hyrax v3.4.2 Alter abilities for Groups with Roles feature module Hyrax module Ability + # rubocop:disable Metrics/ModuleLength module CollectionAbility # rubocop:disable Metrics/MethodLength # rubocop:disable Metrics/BlockLength # rubocop:disable Metrics/AbcSize + # rubocop:disable Metrics/PerceivedComplexity + # rubocop:disable Metrics/CyclomaticComplexity def collection_abilities models = [Hyrax::PcdmCollection, Hyrax.config.collection_class].uniq if admin? @@ -157,6 +160,9 @@ def collection_roles # rubocop:enable Metrics/MethodLength # rubocop:enable Metrics/BlockLength # rubocop:enable Metrics/AbcSize + # rubocop:enable Metrics/PerceivedComplexity + # rubocop:enable Metrics/CyclomaticComplexity end + # rubocop:enable Metrics/ModuleLength end end diff --git a/app/models/concerns/hyrax/ability/solr_document_ability.rb b/app/models/concerns/hyrax/ability/solr_document_ability.rb index 2196f28bd..b3e5616e4 100644 --- a/app/models/concerns/hyrax/ability/solr_document_ability.rb +++ b/app/models/concerns/hyrax/ability/solr_document_ability.rb @@ -4,6 +4,7 @@ module Hyrax module Ability module SolrDocumentAbility + # rubocop:disable Metrics/MethodLength def solr_document_abilities if admin? can [:manage], ::SolrDocument @@ -27,6 +28,7 @@ def solr_document_abilities end end end + # rubocop:enable Metrics/MethodLength end end end diff --git a/app/models/content_block.rb b/app/models/content_block.rb index 5b383f192..5cf86b992 100644 --- a/app/models/content_block.rb +++ b/app/models/content_block.rb @@ -2,6 +2,7 @@ # OVERRIDE Hyrax v3.4.0 to add home_text to registry # and getter/setter methods - Adding themes +# rubocop:disable Metrics/ClassLength class ContentBlock < ApplicationRecord # The keys in this registry are "public" names for collaborator # objects, and the values are reserved names of ContentBlock @@ -159,3 +160,4 @@ def default_terms_text end end end +# rubocop:enable Metrics/ClassLength diff --git a/app/presenters/concerns/hyrax/iiif_av/displays_content_decorator.rb b/app/presenters/concerns/hyrax/iiif_av/displays_content_decorator.rb index 7fa98752a..a3368e897 100644 --- a/app/presenters/concerns/hyrax/iiif_av/displays_content_decorator.rb +++ b/app/presenters/concerns/hyrax/iiif_av/displays_content_decorator.rb @@ -37,6 +37,7 @@ def image_content image_content_v3(url) end + # rubocop:disable Metrics/MethodLength def video_display_content(_url, label = '') width = solr_document.width&.try(:to_i) || 320 height = solr_document.height&.try(:to_i) || 240 @@ -55,6 +56,7 @@ def video_display_content(_url, label = '') format: solr_document.mime_type ) end + # rubocop:enable Metrics/MethodLength def audio_display_content(_url, label = '') duration = conformed_duration_in_seconds diff --git a/app/services/hyrax/collection_types/create_service.rb b/app/services/hyrax/collection_types/create_service.rb index 07891f9b3..16955ac6a 100644 --- a/app/services/hyrax/collection_types/create_service.rb +++ b/app/services/hyrax/collection_types/create_service.rb @@ -208,6 +208,7 @@ def self.create_user_collection_type # The same values can be retrieved directly from a passed in ability. # If calling from Abilities, pass the ability. # If you try to get the ability from the user, you end up in an infinite loop. + # rubocop:disable Metrics/MethodLength def self.add_default_participants(collection_type_id) return unless collection_type_id default_participants = [{ agent_type: Hyrax::CollectionTypeParticipant::GROUP_TYPE, @@ -233,6 +234,7 @@ def self.add_default_participants(collection_type_id) end add_participants(collection_type_id, default_participants) end + # rubocop:enable Metrics/MethodLength ## # @api public diff --git a/app/services/hyrax/workflow/permission_query.rb b/app/services/hyrax/workflow/permission_query.rb index 8ac3f2ecd..6673c46b7 100644 --- a/app/services/hyrax/workflow/permission_query.rb +++ b/app/services/hyrax/workflow/permission_query.rb @@ -73,7 +73,7 @@ def scope_permitted_workflow_actions_available_for_current_state(user:, entity:) # @param role [Object] that can be converted into a Sipity::Role # @return [ActiveRecord::Relation] augmented with # - def scope_agents_associated_with_entity_and_role(entity:, role:) # rubocop:disable Metrics/AbcSize + def scope_agents_associated_with_entity_and_role(entity:, role:) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength entity = Sipity::Entity(entity) role = Sipity::Role(role) @@ -196,7 +196,7 @@ def scope_processing_agents_for(user:) # # @return [ActiveRecord::Relation] # - def scope_entities_for_the_user(user:) # rubocop:disable Metrics/AbcSize + def scope_entities_for_the_user(user:) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength entities = Sipity::Entity.arel_table workflow_state_actions = Sipity::WorkflowStateAction.arel_table workflow_states = Sipity::WorkflowState.arel_table @@ -251,7 +251,7 @@ def scope_entities_for_the_user(user:) # rubocop:disable Metrics/AbcSize # @param entity an object that can be converted into a Sipity::Entity # @return [ActiveRecord::Relation] # - def scope_users_for_entity_and_roles(entity:, roles:) # rubocop:disable Metrics/AbcSize + def scope_users_for_entity_and_roles(entity:, roles:) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength entity = Sipity::Entity(entity) role_ids = Array.wrap(roles).map { |role| Sipity::Role(role).id } user_polymorphic_type = ::User.base_class @@ -347,7 +347,7 @@ def scope_processing_workflow_roles_for_user_and_workflow(user:, workflow:) # @param user [User] # @param entity an object that can be converted into a Sipity::Entity # @return [ActiveRecord::Relation] - def scope_processing_workflow_roles_for_user_and_entity_specific(user:, entity:) + def scope_processing_workflow_roles_for_user_and_entity_specific(user:, entity:) # rubocop:disable Metrics/MethodLength entity = Sipity::Entity(entity) agent_scope = scope_processing_agents_for(user: user) @@ -366,6 +366,7 @@ def scope_processing_workflow_roles_for_user_and_entity_specific(user:, entity:) ) ) end + # rubocop:enable Metrics/MethodLength # @api private # @@ -386,7 +387,7 @@ def scope_processing_workflow_roles_for_user_and_entity_specific(user:, entity:) # @param entity an object that can be converted into a Sipity::Entity # @return [ActiveRecord::Relation] # - def scope_permitted_entity_workflow_state_actions(user:, entity:) + def scope_permitted_entity_workflow_state_actions(user:, entity:) # rubocop:disable Metrics/MethodLength entity = Sipity::Entity(entity) workflow_state_actions = Sipity::WorkflowStateAction permissions = Sipity::WorkflowStateActionPermission @@ -408,6 +409,7 @@ def scope_permitted_entity_workflow_state_actions(user:, entity:) ) ) end + # rubocop:enable Metrics/MethodLength # @api public # diff --git a/app/services/roles_service.rb b/app/services/roles_service.rb index 4c93997ec..49c670aa0 100644 --- a/app/services/roles_service.rb +++ b/app/services/roles_service.rb @@ -98,6 +98,7 @@ def create_default_hyrax_groups_with_roles! # Because each collection role has some level of access to every Collection within a tenant, # creating a Hyrax::PermissionTemplateAccess record (combined with Ability#user_groups) # means all Collections will show up in Blacklight / Solr queries. + # rubocop:disable Metrics/MethodLength def create_collection_accesses! Collection.find_each do |c| pt = Hyrax::PermissionTemplate.find_or_create_by!(source_id: c.id) @@ -130,9 +131,11 @@ def create_collection_accesses! c.reset_access_controls! if pt.access_grants.count != original_access_grants_count end end + # rubocop:enable Metrics/MethodLength # Creating a Hyrax::PermissionTemplateAccess record (combined with Ability#user_groups) # will allow Works in all AdminSets to show up in Blacklight / Solr queries. + # rubocop:disable Metrics/MethodLength def create_admin_set_accesses! AdminSet.find_each do |as| pt = Hyrax::PermissionTemplate.find_or_create_by!(source_id: as.id) @@ -165,6 +168,7 @@ def create_admin_set_accesses! as.reset_access_controls! if pt.access_grants.count != original_access_grants_count end end + # rubocop:enable Metrics/MethodLength # Because some of the collection roles have access to every Collection within a tenant, create a # Hyrax::CollectionTypeParticipant record for them on every Hyrax::CollectionType (except the AdminSet) @@ -247,6 +251,7 @@ def prune_stale_guest_users end end + # rubocop:disable Metrics/MethodLength def seed_superadmin! return 'Seed data should not be used in the production environment' if Rails.env.production? || Rails.env.staging? @@ -270,7 +275,9 @@ def seed_superadmin! user end + # rubocop:enable Metrics/MethodLength + # rubocop:disable Metrics/MethodLength def seed_qa_users! return 'Seed data should not be used in the production environment' if Rails.env.production? || Rails.env.staging? @@ -298,5 +305,6 @@ def seed_qa_users! end end end + # rubocop:enable Metrics/MethodLength end end diff --git a/config/application.rb b/config/application.rb index b8a43824d..060f1df9b 100644 --- a/config/application.rb +++ b/config/application.rb @@ -63,10 +63,10 @@ class Application < Rails::Application # Add this line to load the lib folder first because we need # IiifPrint::SplitPdfs::AdventistPagesToJpgsSplitter - config.autoload_paths.unshift("#{Rails.root}/lib") + config.autoload_paths.unshift(Rails.root.join('lib')) # Add the middleware directory to the eager load paths - config.eager_load_paths << "#{Rails.root}/app/middleware" + config.eager_load_paths << Rails.root.join('app', 'middleware') ## # @api public diff --git a/config/environments/development.rb b/config/environments/development.rb index 2f2bf2195..48d781838 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -1,4 +1,6 @@ # frozen_string_literal: true + +# rubocop:disable Metrics/BlockLength Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. @@ -18,7 +20,7 @@ config.consider_all_requests_local = true # Enable/disable caching. By default caching is disabled. - if Rails.root.join('tmp/caching-dev.txt').exist? + if Rails.root.join('tmp', 'caching-dev.txt').exist? config.action_controller.perform_caching = true config.cache_store = :memory_store @@ -72,3 +74,4 @@ # adding `.` wildcard to allow for subdomains config.hosts << "." + ENV['HYKU_ADMIN_HOST'] end +# rubocop:enable Metrics/BlockLength diff --git a/config/environments/production.rb b/config/environments/production.rb index e57bb998e..9a3560f79 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -1,4 +1,6 @@ # frozen_string_literal: true + +# rubocop:disable Metrics/BlockLength Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. @@ -114,3 +116,4 @@ # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false end +# rubocop:enable Metrics/BlockLength diff --git a/config/initializers/bulkrax.rb b/config/initializers/bulkrax.rb index 035ad0f5a..c5525762d 100644 --- a/config/initializers/bulkrax.rb +++ b/config/initializers/bulkrax.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true if ENV.fetch('HYKU_BULKRAX_ENABLED', 'true') == 'true' + # rubocop:disable Metrics/BlockLength Bulkrax.setup do |config| # Add local parsers # config.parsers += [ @@ -109,6 +110,7 @@ # Properties that should not be used in imports/exports. They are reserved for use by Hyrax. # config.reserved_properties += ['my_field'] end + # rubocop:enable Metrics/BlockLength Bulkrax::CreateRelationshipsJob.update_child_records_works_file_sets = true end diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index cc50f1782..eb1ed09f6 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true # Use this hook to configure devise mailer, warden hooks and so forth. # Many of these configuration options can be set straight in your model. +# rubocop:disable Metrics/BlockLength Devise.setup do |config| # The secret key used by Devise. Devise uses this key to generate # random tokens. Changing this key will render invalid all existing @@ -331,3 +332,4 @@ # so you need to do it manually. For the users scope, it would be: # config.omniauth_path_prefix = '/my_engine/users/auth' end +# rubocop:enable Metrics/BlockLength diff --git a/config/initializers/file_set_derivatives_overrides.rb b/config/initializers/file_set_derivatives_overrides.rb index 7ae9c0ade..2ed39c172 100644 --- a/config/initializers/file_set_derivatives_overrides.rb +++ b/config/initializers/file_set_derivatives_overrides.rb @@ -2,6 +2,7 @@ # This file contains overrides to Hyrax::FileSetDerivativesService to increase the size of thumbnails # Hyrax v3.5.0 +# rubocop:disable Metrics/BlockLength Hyrax::FileSetDerivativesService.class_eval do # @see https://github.com/samvera/hydra-derivatives/blob/main/lib/hydra/derivatives/processors/video/config.rb#L59 DEFAULT_VIDEO_SIZE = '320x240' @@ -58,3 +59,4 @@ def create_video_derivatives(filename) url: derivative_url('mp4') }]) end end +# rubocop:enable Metrics/BlockLength diff --git a/config/initializers/hyrax.rb b/config/initializers/hyrax.rb index 6147b7b1f..f8eced815 100644 --- a/config/initializers/hyrax.rb +++ b/config/initializers/hyrax.rb @@ -2,6 +2,7 @@ # Set nested indexer to graph by default. Remove after Hyrax 4.0 upgrade ENV['HYRAX_USE_SOLR_GRAPH_NESTING'].present? || ENV['HYRAX_USE_SOLR_GRAPH_NESTING'] = "true" +# rubocop:disable Metrics/BlockLength Hyrax.config do |config| config.register_curation_concern :generic_work # Injected via `rails g hyrax:work Image` @@ -124,7 +125,7 @@ # Location on local file system where derivatives will be stored. # If you use a multi-server architecture, this MUST be a shared volume. - config.derivatives_path = ENV['HYRAX_DERIVATIVES_PATH'].presence || File.join(Rails.root, 'tmp', 'derivatives') + config.derivatives_path = ENV['HYRAX_DERIVATIVES_PATH'].presence || Rails.root.join('tmp', 'derivatives').to_s # Should schema.org microdata be displayed? # config.display_microdata = true @@ -189,6 +190,7 @@ uri.sub(/\Ahttp:/, 'https:') end end +# rubocop:enable Metrics/BlockLength Date::DATE_FORMATS[:standard] = "%m/%d/%Y" diff --git a/config/initializers/redis_config.rb b/config/initializers/redis_config.rb index c1b32817e..772ddd2be 100644 --- a/config/initializers/redis_config.rb +++ b/config/initializers/redis_config.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true -config = YAML.load(ERB.new(IO.read(Rails.root + 'config' + 'redis.yml')).result)[Rails.env].with_indifferent_access +config = YAML.safe_load(ERB.new(IO.read(Rails.root + 'config' + 'redis.yml')).result)[Rails.env].with_indifferent_access sentinels = config[:sentinel] && config[:sentinel][:host].present? ? { sentinels: [config[:sentinel]] } : {} redis_config = config.except(:sentinel).merge(thread_safe: true).merge(sentinels) require 'redis' diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index 71c430cf5..1da002934 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true if ENV.fetch('HYRAX_ACTIVE_JOB_QUEUE', 'sidekiq') == 'sidekiq' - config = YAML.load(ERB.new(IO.read(Rails.root + 'config' + 'redis.yml')).result)[Rails.env].with_indifferent_access + config = YAML.safe_load(ERB.new(IO.read(Rails.root + 'config' + 'redis.yml')).result)[Rails.env].with_indifferent_access redis_config = config.merge(thread_safe: true) Sidekiq.configure_server do |s| diff --git a/config/initializers/simple_form_bootstrap.rb b/config/initializers/simple_form_bootstrap.rb index 3098be131..25b4187d9 100644 --- a/config/initializers/simple_form_bootstrap.rb +++ b/config/initializers/simple_form_bootstrap.rb @@ -5,6 +5,7 @@ # Use this setup block to configure all options available in SimpleForm. +# rubocop:disable Metrics/BlockLength SimpleForm.setup do |config| config.error_notification_class = 'alert alert-danger' config.button_class = 'btn btn-default' @@ -150,3 +151,4 @@ time: :multi_select } end +# rubocop:enable Metrics/BlockLength diff --git a/lib/importer/csv_parser.rb b/lib/importer/csv_parser.rb index fa15dd7c0..b992d3ab5 100644 --- a/lib/importer/csv_parser.rb +++ b/lib/importer/csv_parser.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true module Importer + # rubocop:disable Metrics/ClassLength class CSVParser include Enumerable @@ -74,6 +75,7 @@ def attributes(headers, row) end end + # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity def extract_field(header, val, processed) return unless val case header @@ -103,6 +105,7 @@ def extract_field(header, val, processed) end end end + # rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity # Faking a typed field for now. # TODO: support other types of contributors diff --git a/lib/importer/factory/object_factory.rb b/lib/importer/factory/object_factory.rb index 2fa0bd1ed..1a1bbab92 100644 --- a/lib/importer/factory/object_factory.rb +++ b/lib/importer/factory/object_factory.rb @@ -3,6 +3,7 @@ require 'importer/log_subscriber' module Importer module Factory + # rubocop:disable Metrics/ClassLength class ObjectFactory extend ActiveModel::Callbacks define_model_callbacks :save, :create @@ -153,5 +154,6 @@ def permitted_attributes klass.properties.keys.map(&:to_sym) + %i[id edit_users edit_groups read_groups visibility] end end + # rubocop:enable Metrics/ClassLength end end diff --git a/lib/importer/mods_parser.rb b/lib/importer/mods_parser.rb index 93714d217..34c62cccb 100644 --- a/lib/importer/mods_parser.rb +++ b/lib/importer/mods_parser.rb @@ -79,6 +79,7 @@ def common_attributes .merge(relations) end + # rubocop:disable Metrics/MethodLength, Metrics/AbcSize def description { title: untyped_title, @@ -97,6 +98,7 @@ def description description_standard: mods.record_info.descriptionStandard.map(&:text) } end + # rubocop:enable Metrics/MethodLength, Metrics/AbcSize def language mods.language.languageTerm.map do |term| diff --git a/lib/oai/provider/metadata_format/hyku_dublin_core.rb b/lib/oai/provider/metadata_format/hyku_dublin_core.rb index f4c0bde37..e6a996397 100644 --- a/lib/oai/provider/metadata_format/hyku_dublin_core.rb +++ b/lib/oai/provider/metadata_format/hyku_dublin_core.rb @@ -21,6 +21,7 @@ def initialize end # Override to strip namespace and header out + # rubocop:disable Metrics/MethodLength def encode(model, record) xml = Builder::XmlMarkup.new map = model.respond_to?("map_#{prefix}") ? model.send("map_#{prefix}") : {} @@ -41,7 +42,9 @@ def encode(model, record) end xml.target! end + # rubocop:enable Metrics/MethodLength + # rubocop:disable Metrics/MethodLength def add_public_file_urls(xml, record) return if record[:file_set_ids_ssim].blank? @@ -61,6 +64,7 @@ def add_public_file_urls(xml, record) xml.tag! 'file_url', file_download_path end end + # rubocop:enable Metrics/MethodLength def header_specification { diff --git a/lib/oai/provider/model_decorator.rb b/lib/oai/provider/model_decorator.rb index f84e239fb..25835b0d7 100644 --- a/lib/oai/provider/model_decorator.rb +++ b/lib/oai/provider/model_decorator.rb @@ -4,6 +4,7 @@ module OAI module Provider module ModelDecorator # Map Qualified Dublin Core (Terms) fields to PALNI/PALCI fields + # rubocop:disable Metrics/MethodLength def map_oai_hyku { abstract: :abstract, @@ -33,6 +34,7 @@ def map_oai_hyku title: :title } end + # rubocop:enable Metrics/MethodLength end end end diff --git a/lib/wings/services/custom_queries/find_ids_by_model_decorator.rb b/lib/wings/services/custom_queries/find_ids_by_model_decorator.rb index 84e3b2c50..d54534924 100644 --- a/lib/wings/services/custom_queries/find_ids_by_model_decorator.rb +++ b/lib/wings/services/custom_queries/find_ids_by_model_decorator.rb @@ -15,7 +15,7 @@ module FindIdsByModelDecorator # @param ids [Enumerable<#to_s>, Symbol] # # @return [Enumerable] - def find_ids_by_model(model:, ids: :all) + def find_ids_by_model(model:, ids: :all) # rubocop:disable Metrics/MethodLength return enum_for(:find_ids_by_model, model: model, ids: ids) unless block_given? model_name = ModelRegistry.lookup(model).model_name @@ -37,6 +37,7 @@ def find_ids_by_model(model:, ids: :all) )['response'] end end + # rubocop:enable Metrics/MethodLength end end end From 306b89331f6ca82d110cdaf6af4ee20947a24c49 Mon Sep 17 00:00:00 2001 From: Shana Moore Date: Thu, 14 Dec 2023 09:00:25 -0800 Subject: [PATCH 070/126] =?UTF-8?q?=F0=9F=A7=B9=20Remove=20deprecated=20Bl?= =?UTF-8?q?acklight=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit removing the deprecated blacklight code allows the specs to run. We should consider if finding a replacement is necessary in the following ticket: - https://github.com/scientist-softserv/hykuup_knapsack/issues/54 Issue: - https://github.com/scientist-softserv/hykuup_knapsack/issues/35 --- app/controllers/hyrax/contact_form_controller.rb | 1 - app/controllers/hyrax/homepage_controller.rb | 1 - app/controllers/hyrax/pages_controller.rb | 1 - app/controllers/search_history_controller.rb | 1 - 4 files changed, 4 deletions(-) diff --git a/app/controllers/hyrax/contact_form_controller.rb b/app/controllers/hyrax/contact_form_controller.rb index 4e098736b..d0bed0992 100644 --- a/app/controllers/hyrax/contact_form_controller.rb +++ b/app/controllers/hyrax/contact_form_controller.rb @@ -11,7 +11,6 @@ class ContactFormController < ApplicationController # OVERRIDE: Hyrax v3.4.0 Add for theming # Adds Hydra behaviors into the application controller include Blacklight::SearchContext - include Blacklight::SearchHelper include Blacklight::AccessControls::Catalog before_action :build_contact_form layout 'homepage' diff --git a/app/controllers/hyrax/homepage_controller.rb b/app/controllers/hyrax/homepage_controller.rb index 67b0690f2..36f1e794f 100644 --- a/app/controllers/hyrax/homepage_controller.rb +++ b/app/controllers/hyrax/homepage_controller.rb @@ -27,7 +27,6 @@ module Hyrax class HomepageController < CatalogController # Adds Hydra behaviors into the application controller include Blacklight::SearchContext - include Blacklight::SearchHelper include Blacklight::AccessControls::Catalog # OVERRIDE: account for Hyku themes diff --git a/app/controllers/hyrax/pages_controller.rb b/app/controllers/hyrax/pages_controller.rb index 0107739fb..2d54917fe 100644 --- a/app/controllers/hyrax/pages_controller.rb +++ b/app/controllers/hyrax/pages_controller.rb @@ -15,7 +15,6 @@ class PagesController < ApplicationController # OVERRIDE: Hyrax v3.4.0 Add for theming # Adds Hydra behaviors into the application controller include Blacklight::SearchContext - include Blacklight::SearchHelper include Blacklight::AccessControls::Catalog # OVERRIDE: Adding inject theme views method for theming diff --git a/app/controllers/search_history_controller.rb b/app/controllers/search_history_controller.rb index a97b2e3ff..eb6c0983a 100644 --- a/app/controllers/search_history_controller.rb +++ b/app/controllers/search_history_controller.rb @@ -3,6 +3,5 @@ class SearchHistoryController < ApplicationController include Blacklight::SearchHistory helper BlacklightAdvancedSearch::RenderConstraintsOverride - helper BlacklightRangeLimit::ViewHelperOverride helper RangeLimitHelper end From 8b64bf80e33efa5e6d4225c00fa8dcd54fc9d2d2 Mon Sep 17 00:00:00 2001 From: Jeremy Friesen Date: Thu, 14 Dec 2023 11:59:14 -0500 Subject: [PATCH 071/126] =?UTF-8?q?=F0=9F=A7=B9=20Avoid=20`#present=3F`=20?= =?UTF-8?q?in=20non-Rails=20situations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rails provides [`Object#present?`][1], which is a method that is not generally available in Ruby. However in the changed context, the scripts do not have access to Rails methods. By using this adjusted approach we favor baseline Ruby methods. [1]: https://api.rubyonrails.org/classes/Object.html#method-i-present-3F --- bin/web | 2 +- bin/worker | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bin/web b/bin/web index 46e648166..2c4aeae24 100755 --- a/bin/web +++ b/bin/web @@ -1,5 +1,5 @@ #!/usr/local/bin/ruby # frozen_string_literal: true -`echo "$GOOGLE_OAUTH_PRIVATE_KEY_VALUE" | base64 -d > prod-cred.p12` if ENV['GOOGLE_OAUTH_PRIVATE_KEY_VALUE'].present? +`echo "$GOOGLE_OAUTH_PRIVATE_KEY_VALUE" | base64 -d > prod-cred.p12` unless ENV['GOOGLE_OAUTH_PRIVATE_KEY_VALUE'].to_s.strip.empty? exec "bundle exec puma -v -b tcp://0.0.0.0:3000" diff --git a/bin/worker b/bin/worker index b3cb34ce5..f6a61ee83 100755 --- a/bin/worker +++ b/bin/worker @@ -1,11 +1,11 @@ #!/usr/local/bin/ruby # frozen_string_literal: true -`echo "$GOOGLE_OAUTH_PRIVATE_KEY_VALUE" | base64 -d > prod-cred.p12` if ENV['GOOGLE_OAUTH_PRIVATE_KEY_VALUE'].present? +`echo "$GOOGLE_OAUTH_PRIVATE_KEY_VALUE" | base64 -d > prod-cred.p12` unless ENV['GOOGLE_OAUTH_PRIVATE_KEY_VALUE'].to_s.strip.empty? -if ENV['DATABASE_URL'].present? - ENV['DATABASE_URL'] = ENV['DATABASE_URL'].gsub('pool=5', 'pool=30') -else +if ENV['DATABASE_URL'].to_s.strip.empty? puts 'DATABASE_URL not set, no pool change needed' +else + ENV['DATABASE_URL'] = ENV['DATABASE_URL'].gsub('pool=5', 'pool=30') end queue = ENV.fetch('HYRAX_ACTIVE_JOB_QUEUE', 'sidekiq') From 4d291bb46d04e6ea5adddc32e2b8fda02808e6df Mon Sep 17 00:00:00 2001 From: LaRita Robinson Date: Fri, 15 Dec 2023 10:19:55 -0500 Subject: [PATCH 072/126] =?UTF-8?q?=F0=9F=A7=B9=20Get=20Homepage=20Control?= =?UTF-8?q?ler=20specs=20passing=20(#2058)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactor homepage controller to more closely align with Hyrax's homepage controller. Adjust theme views to render `modal` instead of `ajax_modal`. refs: https://github.com/scientist-softserv/hykuup_knapsack/issues/56 --- app/controllers/hyrax/homepage_controller.rb | 54 +++++--- .../layouts/hyrax.html.erb | 2 +- .../layouts/hyrax.html.erb | 2 +- .../hyrax/homepage_controller_spec.rb | 127 ++++++++---------- 4 files changed, 93 insertions(+), 92 deletions(-) diff --git a/app/controllers/hyrax/homepage_controller.rb b/app/controllers/hyrax/homepage_controller.rb index 36f1e794f..45954860c 100644 --- a/app/controllers/hyrax/homepage_controller.rb +++ b/app/controllers/hyrax/homepage_controller.rb @@ -12,15 +12,17 @@ # ######################################################################################### ######################################################################################### -# OVERRIDE: Hyrax v2.9.0 to add home_text content block to the index method - Adding themes -# OVERRIDE: Hyrax v2.9.0 from Hyrax v2.9.0 to add facets to home page - inheriting from -# CatalogController rather than ApplicationController -# OVERRIDE: Hyrax v2.9.0 from Hyrax v2.9.0 to add inject_theme_views method for theming -# OVERRIDE: Hyrax v2.9.0 to add search_action_url method from Blacklight 6.23.0 to make facet links to go to /catalog -# OVERRIDE: Hyrax v2.9.0 to add .sort_by to return collections in alphabetical order by title on the homepage -# OVERRIDE: Hyrax v2.9.0 add all_collections page for IR theme -# OVERRIDE: Hyrax v2.9.0 to add facet counts for resource types for IR theme -# OVERRIDE: Hyrax v. 2.9.0 to add @featured_collection_list to index method + +# OVERRIDE: Hyrax v5.0.0 +# - add home_text content block to the index method - Adding themes +# - add inject_theme_views method for theming +# - add all_collections page for IR theme +# - add facet counts for resource types for IR theme + +# - add facets to home page - inheriting from CatalogController rather than ApplicationController +# - add search_action_url method from Blacklight 6.23.0 to make facet links to go to /catalog +# - add .sort_by to return collections in alphabetical order by title on the homepage +# - add @featured_collection_list to index method module Hyrax # Changed to inherit from CatalogController for home page facets @@ -61,7 +63,7 @@ def index ir_counts if home_page_theme == 'institutional_repository' - (@response, @document_list) = search_results(params) + (@response, @document_list) = search_service.search_results respond_to do |format| format.html { store_preferred_view } @@ -102,26 +104,28 @@ def search_action_url(options = {}) private - # Return 6 collections + # Return 6 collections, sorts by title def collections(rows: 6) - builder = Hyrax::CollectionSearchBuilder.new(self) - .rows(rows) - response = repository.search(builder) - # adding .sort_by to return collections in alphabetical order by title on the homepage - response.documents.sort_by(&:title) + (response, documents) = Hyrax::CollectionsService.new(self).search_results do |builder| + builder.rows(rows) + builder.merge(sort: "title_ssi") + end rescue Blacklight::Exceptions::ECONNREFUSED, Blacklight::Exceptions::InvalidRequest [] end - def recent - # grab any recent documents - (_, @recent_documents) = search_results(q: '', sort: sort_field, rows: 6) + # override to show 6 recent items + def recent(rows: 6) + (_, @recent_documents) = search_service.search_results do |builder| + builder.rows(rows) + builder.merge(sort: sort_field) + end rescue Blacklight::Exceptions::ECONNREFUSED, Blacklight::Exceptions::InvalidRequest @recent_documents = [] end def ir_counts - @ir_counts = get_facet_field_response('resource_type_sim', {}, "f.resource_type_sim.facet.limit" => "-1") + @ir_counts = search_service.facet_field_response('resource_type_sim', "f.resource_type_sim.facet.limit" => "-1") end # COPIED from Hyrax::HomepageController @@ -144,5 +148,15 @@ def inject_theme_views yield end end + + # add this method to vary blacklight config and user_params + def search_service(*args) + Hyrax::SearchService.new( + config: ::CatalogController.new.blacklight_config, + user_params: params.except(:q, :page), + scope: self, + current_ability: current_ability, + search_builder_class: search_builder_class) + end end end diff --git a/app/views/themes/cultural_repository/layouts/hyrax.html.erb b/app/views/themes/cultural_repository/layouts/hyrax.html.erb index 889f1f02f..0b3f706cd 100644 --- a/app/views/themes/cultural_repository/layouts/hyrax.html.erb +++ b/app/views/themes/cultural_repository/layouts/hyrax.html.erb @@ -40,6 +40,6 @@ <%= render 'shared/footer' %> <%= render '/shared/select_work_type_modal', create_work_presenter: @presenter&.create_work_presenter if @presenter&.draw_select_work_modal? %> - <%= render 'shared/ajax_modal' %> + <%= render 'shared/modal' %> \ No newline at end of file diff --git a/app/views/themes/institutional_repository/layouts/hyrax.html.erb b/app/views/themes/institutional_repository/layouts/hyrax.html.erb index b4f8de2e2..3b545a178 100644 --- a/app/views/themes/institutional_repository/layouts/hyrax.html.erb +++ b/app/views/themes/institutional_repository/layouts/hyrax.html.erb @@ -29,6 +29,6 @@ <%= render 'shared/footer' %> - <%= render 'shared/ajax_modal' %> + <%= render 'shared/modal' %> \ No newline at end of file diff --git a/spec/controllers/hyrax/homepage_controller_spec.rb b/spec/controllers/hyrax/homepage_controller_spec.rb index c58db28d4..06a1110e0 100644 --- a/spec/controllers/hyrax/homepage_controller_spec.rb +++ b/spec/controllers/hyrax/homepage_controller_spec.rb @@ -1,8 +1,6 @@ # frozen_string_literal: true - -# Copied from Hyrax v2.9.0 to add home_text content block to the index method - Adding themes -RSpec.describe Hyrax::HomepageController, type: :controller, clean: true do - let(:routes) { Hyrax::Engine.routes } +RSpec.describe Hyrax::HomepageController, type: :controller do + routes { Hyrax::Engine.routes } describe "#index" do let(:user) { create(:user) } @@ -12,17 +10,11 @@ end context 'with existing featured researcher' do - let!(:frodo) do - ContentBlock.create!( - name: ContentBlock::NAME_REGISTRY[:researcher], - value: 'Frodo Baggins', - created_at: Time.zone.now - ) - end + let!(:frodo) { ContentBlock.create!(name: ContentBlock::NAME_REGISTRY[:researcher], value: 'Frodo Baggins', created_at: Time.zone.now) } it 'finds the featured researcher' do get :index - expect(response).to be_success + expect(response).to be_successful expect(assigns(:featured_researcher)).to eq frodo end end @@ -30,7 +22,7 @@ context 'with no featured researcher' do it "sets featured researcher" do get :index - expect(response).to be_success + expect(response).to be_successful assigns(:featured_researcher).tap do |researcher| expect(researcher).to be_kind_of ContentBlock expect(researcher.name).to eq 'featured_researcher' @@ -40,56 +32,41 @@ it "sets marketing text" do get :index - expect(response).to be_success + expect(response).to be_successful assigns(:marketing_text).tap do |marketing| expect(marketing).to be_kind_of ContentBlock expect(marketing.name).to eq 'marketing_text' end end - # override hyrax v2.9.0 added @home_text - Adding Themes - it "sets home page text" do - get :index - expect(response).to be_success - assigns(:home_text).tap do |home| - expect(home).to be_kind_of ContentBlock - expect(home.name).to eq 'home_text' - end - end - it "does not include other user's private documents in recent documents" do get :index - expect(response).to be_success + expect(response).to be_successful titles = assigns(:recent_documents).map { |d| d['title_tesim'][0] } expect(titles).not_to include('Test Private Document') end - it "includes only GenericWork objects in recent documents" do + it "includes only Work objects in recent documents" do get :index - assigns(:recent_documents).each do |doc| - expect(doc["has_model_ssim"]).to eql ["GenericWork"] - end + expect(assigns(:recent_documents).all?(&:work?)).to eq true end context "with a document not created this second", clean_repo: true do + let(:work_1) { { id: 'work_1', has_model_ssim: 'GenericWork', read_access_person_ssim: user.user_key, date_uploaded_dtsi: 2.days.ago.iso8601 } } + let(:work_2) { { id: 'work_2', has_model_ssim: 'GenericWork', read_access_person_ssim: user.user_key, date_uploaded_dtsi: 4.days.ago.iso8601 } } + let(:work_3) { { id: 'work_3', has_model_ssim: 'Image', read_access_person_ssim: user.user_key, date_uploaded_dtsi: 3.days.ago.iso8601 } } + before do - gw3 = GenericWork.new(title: ['Test 3 Document'], read_groups: ['public']) - gw3.apply_depositor_metadata('mjg36') - # stubbing to_solr so we know we have something that didn't create in the current second - old_to_solr = gw3.method(:to_solr) - allow(gw3).to receive(:to_solr) do - old_to_solr.call.merge( - "system_create_dtsi" => 1.day.ago.iso8601, - "date_uploaded_dtsi" => 1.day.ago.iso8601 - ) + [work_1, work_2, work_3].each do |obj| + Hyrax::SolrService.add(obj) end - gw3.save + Hyrax::SolrService.commit end it "sets recent documents in the right order" do get :index - expect(response).to be_success - expect(assigns(:recent_documents).length).to be <= 4 + expect(response).to be_successful + expect(assigns(:recent_documents).length).to eq 3 create_times = assigns(:recent_documents).map { |d| d['date_uploaded_dtsi'] } expect(create_times).to eq create_times.sort.reverse end @@ -97,23 +74,21 @@ context "with collections" do let(:presenter) { double } - let(:repository) { double } - let(:collection) { create(:collection) } - let(:collection_results) { double(documents: [collection]) } + # let(:repository) { double } + let(:collection_results) { double(documents: ['collection results']) } before do - allow(controller).to receive(:repository).and_return(repository) + # allow(controller).to receive(:repository).and_return(repository) allow(controller).to receive(:search_results).and_return([nil, ['recent document']]) - allow(controller.repository).to receive(:search).with(an_instance_of(Hyrax::CollectionSearchBuilder)) - .and_return(collection_results) + allow_any_instance_of(Hyrax::CollectionsService).to receive(:search_results).and_return(collection_results.documents) end it "initializes the presenter with ability and a list of collections" do - expect(Hyrax::HomepagePresenter).to receive(:new).with(Ability, - [collection]) - .and_return(presenter) + expect(Hyrax::HomepagePresenter).to receive(:new) + .with(controller.current_ability, ["collection results"]) + .and_return(presenter) get :index - expect(response).to be_success + expect(response).to be_successful expect(assigns(:presenter)).to eq presenter end end @@ -127,51 +102,63 @@ it "sets featured works" do get :index - expect(response).to be_success + expect(response).to be_successful expect(assigns(:featured_work_list)).to be_kind_of FeaturedWorkList end end it "sets announcement content block" do get :index - expect(response).to be_success + expect(response).to be_successful assigns(:announcement_text).tap do |announcement| expect(announcement).to be_kind_of ContentBlock expect(announcement.name).to eq 'announcement_text' end end - xcontext "without solr" do # skip until and fix with ticket #301 https://gitlab.com/notch8/palni-palci/-/issues/301 + xcontext "without solr" do # skip: see https://github.com/scientist-softserv/palni-palci/issues/154 before do - allow(controller).to receive(:repository).and_return(instance_double(Blacklight::Solr::Repository)) - allow(controller.repository).to receive(:search).and_raise Blacklight::Exceptions::InvalidRequest + allow_any_instance_of(Hyrax::SearchService).to receive(:search_results).and_raise Blacklight::Exceptions::InvalidRequest end it "errors gracefully" do get :index - expect(response).to be_success + expect(response).to be_successful expect(assigns(:admin_sets)).to be_blank expect(assigns(:recent_documents)).to be_blank end end - context 'with theming' do - it { is_expected.to use_around_action(:inject_theme_views) } - end + # specs for Hyku-only features + # override added @home_text - Adding Themes + describe 'Hyku exclusive features' do + it "sets home page text" do + get :index + expect(response).to be_successful + assigns(:home_text).tap do |home| + expect(home).to be_kind_of ContentBlock + expect(home.name).to eq 'home_text' + end + end - context 'with ir stats' do - before do - allow(controller).to receive(:home_page_theme).and_return('institutional_repository') + context 'with theming' do + it { is_expected.to use_around_action(:inject_theme_views) } end - # rubocop:disable RSpec/LetSetup - let!(:work_with_resource_type) { create(:work, user: user, resource_type: ['Article']) } - # rubocop:enable RSpec/LetSetup + context 'with ir stats' do + before do + allow(controller).to receive(:home_page_theme).and_return('institutional_repository') + end + # rubocop:disable RSpec/LetSetup + let!(:work_with_resource_type) { create(:work, user: user, resource_type: ['Article']) } - it 'gets the stats' do - get :index - expect(response).to be_success - expect(assigns(:ir_counts)['facet_counts']['facet_fields']['resource_type_sim']).to include('Article', 1) + # rubocop:enable RSpec/LetSetup + + it 'gets the stats' do + get :index + expect(response).to be_successful + expect(assigns(:ir_counts)['facet_counts']['facet_fields']['resource_type_sim']).to include('Article', 1) + end end end end From 2d00694b07f4f875ae56aceb0e25f41b4c041f0b Mon Sep 17 00:00:00 2001 From: LaRita Robinson Date: Fri, 15 Dec 2023 16:31:45 -0500 Subject: [PATCH 073/126] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Replace=20Homepage?= =?UTF-8?q?=20Presenter=20with=20decorator=20(#2059)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/presenters/hyrax/homepage_presenter.rb | 74 ------------------- .../hyrax/homepage_presenter_decorator.rb | 29 ++++++++ 2 files changed, 29 insertions(+), 74 deletions(-) delete mode 100644 app/presenters/hyrax/homepage_presenter.rb create mode 100644 app/presenters/hyrax/homepage_presenter_decorator.rb diff --git a/app/presenters/hyrax/homepage_presenter.rb b/app/presenters/hyrax/homepage_presenter.rb deleted file mode 100644 index 2351f1195..000000000 --- a/app/presenters/hyrax/homepage_presenter.rb +++ /dev/null @@ -1,74 +0,0 @@ -# frozen_string_literal: true - -# OVERRIDE Hyrax 3.4.0 to add methods to: -# hide featured researcher -# hide featured works -# hide recently uploaded -# hide share button -module Hyrax - class HomepagePresenter - class_attribute :create_work_presenter_class - self.create_work_presenter_class = Hyrax::SelectTypeListPresenter - attr_reader :current_ability, :collections - - def initialize(current_ability, collections) - @current_ability = current_ability - @collections = collections - end - - # OVERRIDE: Hyrax v3.4.0 to removed: @return [Boolean] If the - # display_share_button_when_not_logged_in? is activated, then - # return true since we are utilizing the feature flipper - # Flipflop.show_share_button? in Hyku. - - # @return [Boolean] If the current user is a guest - # and the feature flipper is enabled or if the signed in - # user has permission to create at least one kind of work - # and the feature flipper is enabled. - - def display_share_button? - Flipflop.show_share_button? && current_ability.can_create_any_work? || - Flipflop.show_share_button? && user_unregistered? - end - - # A presenter for selecting a work type to create - # this is needed here because the selector is in the header on every page - def create_work_presenter - @create_work_presenter ||= create_work_presenter_class.new(current_ability.current_user) - end - - def create_many_work_types? - create_work_presenter.many? - end - - def draw_select_work_modal? - display_share_button? && create_many_work_types? - end - - def first_work_type - create_work_presenter.first_model - end - - # changed to add feature flag for featured researcher - def display_featured_researcher? - Flipflop.show_featured_researcher? - end - - # changed to add feature flag for featured work - def display_featured_works? - Flipflop.show_featured_works? - end - - # changed to add feature flag for recently uploaded - def display_recently_uploaded? - Flipflop.show_recently_uploaded? - end - - private - - def user_unregistered? - current_ability.current_user.new_record? || - current_ability.current_user.guest? - end - end -end diff --git a/app/presenters/hyrax/homepage_presenter_decorator.rb b/app/presenters/hyrax/homepage_presenter_decorator.rb new file mode 100644 index 000000000..d75740a20 --- /dev/null +++ b/app/presenters/hyrax/homepage_presenter_decorator.rb @@ -0,0 +1,29 @@ +# # frozen_string_literal: true + +# OVERRIDE Hyrax 5.0 to hide features via flipper +# hide featured researcher +# hide featured works +# hide recently uploaded +# hide share button +module Hyrax + module HomepagePresenterDecorator + def display_share_button? + Flipflop.show_share_button? && current_ability.can_create_any_work? || + Flipflop.show_share_button? && user_unregistered? + end + + def display_featured_researcher? + Flipflop.show_featured_researcher? + end + + def display_featured_works? + Flipflop.show_featured_works? + end + + def display_recently_uploaded? + Flipflop.show_recently_uploaded? + end + end +end + +Hyrax::HomepagePresenter.prepend(Hyrax::HomepagePresenterDecorator) From 1bfe119fb9183aa19ec9d70750ddb1ab6671e3c8 Mon Sep 17 00:00:00 2001 From: LaRita Robinson Date: Fri, 15 Dec 2023 16:37:39 -0500 Subject: [PATCH 074/126] =?UTF-8?q?=F0=9F=A7=B9Get=20CatalogController=20s?= =?UTF-8?q?pecs=20working=20(#2060)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/catalog_controller.rb | 42 ++++++++------------- spec/controllers/catalog_controller_spec.rb | 2 +- 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/app/controllers/catalog_controller.rb b/app/controllers/catalog_controller.rb index ca0ce0738..93d0ddf91 100644 --- a/app/controllers/catalog_controller.rb +++ b/app/controllers/catalog_controller.rb @@ -48,12 +48,9 @@ def self.uploaded_field suggester_name: 'iiifSuggester' } - config.view.gallery.partials = %i[index_header index] - config.view.masonry.partials = [:index] - config.view.slideshow.partials = [:index] - config.show.tile_source_field = :content_metadata_image_iiif_info_ssm config.show.partials.insert(1, :openseadragon) + # default advanced config values config.advanced_search ||= Blacklight::OpenStructWithHashAccess.new # config.advanced_search[:qt] ||= 'advanced' @@ -69,6 +66,7 @@ def self.uploaded_field # Show gallery view config.view.gallery.partials = %i[index_header index] + config.view.masonry.partials = [:index] config.view.slideshow.partials = [:index] # Because too many times on Samvera tech people raise a problem regarding a failed query to SOLR. @@ -97,6 +95,18 @@ def self.uploaded_field config.index.display_type_field = 'has_model_ssim' config.index.thumbnail_field = 'thumbnail_path_ss' + # Blacklight 7 additions + config.add_results_document_tool(:bookmark, partial: 'bookmark_control', if: :render_bookmarks_control?) + config.add_results_collection_tool(:sort_widget) + config.add_results_collection_tool(:per_page_widget) + config.add_results_collection_tool(:view_type_group) + config.add_show_tools_partial(:bookmark, partial: 'bookmark_control', if: :render_bookmarks_control?) + config.add_show_tools_partial(:email, callback: :email_action, validator: :validate_email_params) + config.add_show_tools_partial(:sms, if: :render_sms_action?, callback: :sms_action, validator: :validate_sms_params) + config.add_show_tools_partial(:citation) + config.add_nav_action(:bookmark, partial: 'blacklight/nav/bookmark', if: :render_bookmarks_control?) + config.add_nav_action(:search_history, partial: 'blacklight/nav/search_history') + # solr fields that will be treated as facets by the blacklight application # The ordering of the field names is the order of the display config.add_facet_field 'human_readable_type_sim', label: "Type", limit: 5 @@ -114,31 +124,12 @@ def self.uploaded_field # TODO: deal with part of facet changes # config.add_facet_field solr_name("part", :facetable), limit: 5, label: 'Part' # config.add_facet_field solr_name("part_of", :facetable), limit: 5 - # removed # config.add_facet_field solr_name("file_format", :facetable), limit: 5 - # removed # config.add_facet_field solr_name("contributor", :facetable), label: "Contributor", limit: 5 - # remvode config.add_facet_field solr_name("refereed", :facetable), limit: 5 # Have BL send all facet field names to Solr, which has been the default # previously. Simply remove these lines if you'd rather use Solr request # handler defaults, or have no facets. config.add_facet_fields_to_solr_request! - # TODO: ROB - # # Prior to this change, the applications specific translations were not loaded. Dogbiscuits were assuming the translations were already loaded. - # Rails.root.glob("config/locales/*.yml").each do |path| - # I18n.load_path << path.to_s - # end - # I18n.backend.reload! - # index_props = DogBiscuits.config.index_properties.collect do |prop| - # { prop => index_options(prop, DogBiscuits.config.property_mappings[prop]) } - # end - # add_index_field config, index_props - - # solr fields to be displayed in the show (single result) view - # The ordering of the field names is the order of the display - # show_props = DogBiscuits.config.all_properties - # add_show_field config, show_props - # solr fields to be displayed in the index (search results) view # The ordering of the field names is the order of the display config.add_index_field 'title_tesim', label: "Title", itemprop: 'name', if: false @@ -203,8 +194,7 @@ def self.uploaded_field # since we aren't specifying it otherwise. config.add_search_field('all_fields', label: 'All Fields', include_in_advanced_search: false) do |field| all_names = config.show_fields.values.map(&:field).join(" ") - # TODO: ROB all_names = (config.show_fields.values.map { |v| v.field.to_s } + - # DogBiscuits.config.all_properties.map { |p| "#{p}_tesim" }).uniq.join(" ") + title_name = 'title_tesim' field.solr_parameters = { qf: "#{all_names} file_format_tesim all_text_timv", @@ -446,7 +436,7 @@ def self.uploaded_field # This is overridden just to give us a JSON response for debugging. def show - _, @document = fetch params[:id] + _, @document = search_service.fetch(params[:id]) render json: @document.to_h end end diff --git a/spec/controllers/catalog_controller_spec.rb b/spec/controllers/catalog_controller_spec.rb index f1c3e9c39..0da2bd571 100644 --- a/spec/controllers/catalog_controller_spec.rb +++ b/spec/controllers/catalog_controller_spec.rb @@ -13,7 +13,7 @@ it "is successful" do get :show, params: { id: file_set } expect(response).to be_successful - expect(response.content_type).to eq 'application/json' + expect(response.content_type).to eq "application/json; charset=utf-8" end end From 76010a4c41c059ea1630f8f47c938c071deeb1f1 Mon Sep 17 00:00:00 2001 From: LaRita Robinson Date: Fri, 15 Dec 2023 16:49:08 -0500 Subject: [PATCH 075/126] =?UTF-8?q?=F0=9F=A7=B9=20Hyrax=205=20get=20additi?= =?UTF-8?q?onal=20specs=20passing=20(#2062)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🧹 Get chrome.hyku.test working * 🧹 Get SitesControllerSpecs working File fixtures were broken. Ref https://github.com/scientist-softserv/hykuup_knapsack/issues/56 * 🧹 Remove google analytics from config reload This is a piece of a fix for analytics that came in via https://github.com/scientist-softserv/palni-palci/pull/946 Additional backporting of analytics work is still needed, but this fixes numerous specs so it is being pulled in earlier. * 🧹 Update ruby version for circleci * 🧹 Update rails version for circleci --- .circleci/config.yml | 8 ++++---- app/models/concerns/account_settings.rb | 2 -- spec/rails_helper.rb | 5 ++--- spec/support/fixtures.rb | 13 ------------- 4 files changed, 6 insertions(+), 22 deletions(-) delete mode 100644 spec/support/fixtures.rb diff --git a/.circleci/config.yml b/.circleci/config.yml index 5f08b5735..84e0cf65b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -10,13 +10,13 @@ jobs: parameters: ruby_version: type: string - default: 2.7.8 + default: 3.2.2 bundler_version: type: string default: 2.4.8 rails_version: type: string - default: '5.1.6' + default: '6.1.7.6' solr_config_path: type: string fcrepo_version: @@ -95,6 +95,6 @@ workflows: ci: jobs: - bundle: - ruby_version: "2.7.8" - name: "ruby2-7-8" + ruby_version: "3.2.2" + name: "ruby3-2-2" solr_config_path: 'solr/conf' diff --git a/app/models/concerns/account_settings.rb b/app/models/concerns/account_settings.rb index dcba12122..54d8df829 100644 --- a/app/models/concerns/account_settings.rb +++ b/app/models/concerns/account_settings.rb @@ -161,8 +161,6 @@ def set_smtp_settings def reload_library_config Hyrax.config do |config| config.contact_email = contact_email - config.analytics = google_analytics_id.present? - config.google_analytics_id = google_analytics_id if google_analytics_id.present? config.geonames_username = geonames_username config.uploader[:maxFileSize] = file_size_limit end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 33c069b56..e67ad2d18 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -62,8 +62,7 @@ ENV['WEB_HOST'] ||= `hostname -s`.strip if ENV['CHROME_HOSTNAME'].present? - options = Selenium::WebDriver::Options.chrome(args: ["headless", - "disable-gpu", + options = Selenium::WebDriver::Options.chrome(args: ["disable-gpu", "no-sandbox", "whitelisted-ips", "window-size=1400,1400"]) @@ -105,6 +104,7 @@ RSpec.configure do |config| # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures config.fixture_path = "#{::Rails.root}/spec/fixtures" + config.file_fixture_path = "#{::Rails.root}/spec/fixtures" # If you're not using ActiveRecord, or you'd prefer not to run each of your # examples within a transaction, remove the following line or assign false @@ -132,7 +132,6 @@ # config.filter_gems_from_backtrace("gem name") config.include Devise::Test::ControllerHelpers, type: :controller - config.include Fixtures::FixtureFileUpload config.include FactoryBot::Syntax::Methods config.include ApplicationHelper, type: :view config.include Warden::Test::Helpers, type: :feature diff --git a/spec/support/fixtures.rb b/spec/support/fixtures.rb deleted file mode 100644 index 2843b3645..000000000 --- a/spec/support/fixtures.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -module Fixtures - module FixtureFileUpload - def fixture_file(path) - File.open(fixture_file_path(path)) - end - - def fixture_file_path(path) - Rails.root + 'spec/fixtures' + path - end - end -end From 2cad6b28002fd30c5fa891424c7b7dc8017b421c Mon Sep 17 00:00:00 2001 From: LaRita Robinson Date: Fri, 15 Dec 2023 17:47:21 -0500 Subject: [PATCH 076/126] =?UTF-8?q?=F0=9F=A7=B9Database=20migration=20&=20?= =?UTF-8?q?schema=20update=20(#2063)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For table hyrax_counter_metrics --- ...5705_create_hyrax_counter_metrics.hyrax.rb | 14 +++++++++++++ ...15215706_change_work_id_to_string.hyrax.rb | 5 +++++ ..._indices_to_hyrax_counter_metrics.hyrax.rb | 8 +++++++ ...5708_add_fields_to_counter_metric.hyrax.rb | 8 +++++++ db/schema.rb | 21 ++++++++++++++++++- 5 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20231215215705_create_hyrax_counter_metrics.hyrax.rb create mode 100644 db/migrate/20231215215706_change_work_id_to_string.hyrax.rb create mode 100644 db/migrate/20231215215707_add_indices_to_hyrax_counter_metrics.hyrax.rb create mode 100644 db/migrate/20231215215708_add_fields_to_counter_metric.hyrax.rb diff --git a/db/migrate/20231215215705_create_hyrax_counter_metrics.hyrax.rb b/db/migrate/20231215215705_create_hyrax_counter_metrics.hyrax.rb new file mode 100644 index 000000000..80caf88c1 --- /dev/null +++ b/db/migrate/20231215215705_create_hyrax_counter_metrics.hyrax.rb @@ -0,0 +1,14 @@ +class CreateHyraxCounterMetrics < ActiveRecord::Migration[6.1] + def change + create_table :hyrax_counter_metrics do |t| + t.string :worktype + t.string :resource_type + t.integer :work_id + t.date :date + t.integer :total_item_investigations + t.integer :total_item_requests + + t.timestamps + end + end +end diff --git a/db/migrate/20231215215706_change_work_id_to_string.hyrax.rb b/db/migrate/20231215215706_change_work_id_to_string.hyrax.rb new file mode 100644 index 000000000..1cdb92a36 --- /dev/null +++ b/db/migrate/20231215215706_change_work_id_to_string.hyrax.rb @@ -0,0 +1,5 @@ +class ChangeWorkIdToString < ActiveRecord::Migration[6.1] + def change + change_column :hyrax_counter_metrics, :work_id, :string + end +end diff --git a/db/migrate/20231215215707_add_indices_to_hyrax_counter_metrics.hyrax.rb b/db/migrate/20231215215707_add_indices_to_hyrax_counter_metrics.hyrax.rb new file mode 100644 index 000000000..b71e0977b --- /dev/null +++ b/db/migrate/20231215215707_add_indices_to_hyrax_counter_metrics.hyrax.rb @@ -0,0 +1,8 @@ +class AddIndicesToHyraxCounterMetrics < ActiveRecord::Migration[6.1] + def change + add_index :hyrax_counter_metrics, :worktype + add_index :hyrax_counter_metrics, :resource_type + add_index :hyrax_counter_metrics, :work_id + add_index :hyrax_counter_metrics, :date + end +end diff --git a/db/migrate/20231215215708_add_fields_to_counter_metric.hyrax.rb b/db/migrate/20231215215708_add_fields_to_counter_metric.hyrax.rb new file mode 100644 index 000000000..7b2ec02fa --- /dev/null +++ b/db/migrate/20231215215708_add_fields_to_counter_metric.hyrax.rb @@ -0,0 +1,8 @@ +class AddFieldsToCounterMetric < ActiveRecord::Migration[6.1] + def change + add_column :hyrax_counter_metrics, :title, :string + add_column :hyrax_counter_metrics, :year_of_publication, :integer, index: true + add_column :hyrax_counter_metrics, :publisher, :string, index: true + add_column :hyrax_counter_metrics, :author, :string, index: true + end +end diff --git a/db/schema.rb b/db/schema.rb index f65809e9f..7d5629751 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2023_08_04_073106) do +ActiveRecord::Schema.define(version: 2023_12_15_215708) do # These are extensions that must be enabled in order to support this database enable_extension "hstore" @@ -372,6 +372,25 @@ t.index ["machine_id"], name: "index_hyrax_collection_types_on_machine_id", unique: true end + create_table "hyrax_counter_metrics", force: :cascade do |t| + t.string "worktype" + t.string "resource_type" + t.string "work_id" + t.date "date" + t.integer "total_item_investigations" + t.integer "total_item_requests" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "title" + t.integer "year_of_publication" + t.string "publisher" + t.string "author" + t.index ["date"], name: "index_hyrax_counter_metrics_on_date" + t.index ["resource_type"], name: "index_hyrax_counter_metrics_on_resource_type" + t.index ["work_id"], name: "index_hyrax_counter_metrics_on_work_id" + t.index ["worktype"], name: "index_hyrax_counter_metrics_on_worktype" + end + create_table "hyrax_default_administrative_set", force: :cascade do |t| t.string "default_admin_set_id", null: false t.datetime "created_at", null: false From cd3b05948479b612eaab552870159a0d26e53ac3 Mon Sep 17 00:00:00 2001 From: LaRita Robinson Date: Fri, 15 Dec 2023 19:14:28 -0500 Subject: [PATCH 077/126] =?UTF-8?q?=F0=9F=A7=B9=20Fix=20Hyrax=205=20remain?= =?UTF-8?q?ing=20controller=20spec=20failures=20(#2064)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🧹Remove ActiveFedora monkeypatch * 🧹Fix file fixture --- config/initializers/active_fedora_override.rb | 12 ------------ .../hyrax/generic_works_controller_spec.rb | 4 +++- spec/controllers/hyrax/images_controller_spec.rb | 2 +- 3 files changed, 4 insertions(+), 14 deletions(-) delete mode 100644 config/initializers/active_fedora_override.rb diff --git a/config/initializers/active_fedora_override.rb b/config/initializers/active_fedora_override.rb deleted file mode 100644 index e595997ae..000000000 --- a/config/initializers/active_fedora_override.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true -# Based on https://github.com/samvera/hyrax/issues/4581#issuecomment-843085122 - -# Monkey-patch to short circuit ActiveModel::Dirty which attempts to load the whole master files ordered list when calling nodes_will_change! -# This leads to a stack level too deep exception when attempting to delete a master file from a media object on the manage files step. -# See https://github.com/samvera/active_fedora/pull/1312/commits/7c8bbbefdacefd655a2ca653f5950c991e1dc999#diff-28356c4daa0d55cbaf97e4269869f510R100-R103 -ActiveFedora::Aggregation::ListSource.class_eval do - def attribute_will_change!(attr) - return super unless attr == 'nodes' - attributes_changed_by_setter[:nodes] = true - end -end diff --git a/spec/controllers/hyrax/generic_works_controller_spec.rb b/spec/controllers/hyrax/generic_works_controller_spec.rb index 741963ed2..65d075285 100644 --- a/spec/controllers/hyrax/generic_works_controller_spec.rb +++ b/spec/controllers/hyrax/generic_works_controller_spec.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'rails_helper' + RSpec.describe Hyrax::GenericWorksController do let(:user) { FactoryBot.create(:user) } let(:work) { FactoryBot.create(:work_with_one_file, user: user) } @@ -7,7 +9,7 @@ before do Hydra::Works::AddFileToFileSet.call(file_set, - fixture_file('images/world.png'), + fixture_file_upload('images/world.png'), :original_file) end diff --git a/spec/controllers/hyrax/images_controller_spec.rb b/spec/controllers/hyrax/images_controller_spec.rb index e0b2b42b6..06b48c7c4 100644 --- a/spec/controllers/hyrax/images_controller_spec.rb +++ b/spec/controllers/hyrax/images_controller_spec.rb @@ -12,7 +12,7 @@ before do Hydra::Works::AddFileToFileSet.call(file_set, - fixture_file('images/world.png'), + fixture_file_upload('images/world.png'), :original_file) end From 67f316353c057713c194ce13fc58deb38cee993e Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Fri, 15 Dec 2023 17:42:53 -0800 Subject: [PATCH 078/126] =?UTF-8?q?=F0=9F=A7=B9=20Upgrade=20views=20from?= =?UTF-8?q?=20Bootstrap=203=20to=204?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit is a first swing of upgrading all the views from Bootstrap 3 to 4. There's still a lot of work to be done to make the views look good but this is a good first step. --- app/views/_admin_util_links.html.erb | 16 +- app/views/_logo.html.erb | 20 +-- app/views/_masthead.html.erb | 26 ++-- app/views/_user_util_links.html.erb | 36 +++-- app/views/account_sign_up/new.html.erb | 10 +- app/views/admin/accounts/edit.html.erb | 10 +- app/views/admin/groups/_form.html.erb | 8 +- app/views/admin/groups/_nav.html.erb | 8 +- app/views/admin/groups/_per_page.html.erb | 4 +- app/views/admin/groups/_search.html.erb | 8 +- app/views/admin/groups/index.html.erb | 20 +-- app/views/admin/groups/new.html.erb | 18 +-- app/views/admin/groups/remove.html.erb | 10 +- app/views/admin/groups/roles.html.erb | 119 +++++++-------- app/views/admin/groups/users.html.erb | 28 ++-- app/views/admin/work_types/edit.html.erb | 12 +- .../advanced/_advanced_search_help.html.erb | 34 ++--- ..._index_gallery_collection_wrapper.html.erb | 4 +- .../_index_header_list_collection.html.erb | 8 +- .../_index_header_list_default.html.erb | 16 +- .../_thumbnail_list_collection.html.erb | 2 +- app/views/devise/passwords/new.html.erb | 10 +- app/views/devise/registrations/new.html.erb | 28 ++-- .../registrations/registrations/new.html.erb | 36 +++-- app/views/devise/sessions/new.html.erb | 49 +++--- .../_form_participant_table.html.erb | 74 ++++----- .../admin_sets/_form_participants.html.erb | 24 +-- .../appearances/_banner_image_form.html.erb | 13 +- .../admin/appearances/_color_input.html.erb | 2 +- .../appearances/_custom_css_form.html.erb | 8 +- .../appearances/_default_colors_form.html.erb | 8 +- .../appearances/_default_fonts_form.html.erb | 12 +- .../appearances/_default_images_form.html.erb | 14 +- .../_directory_image_form.html.erb | 12 +- .../admin/appearances/_favicon_form.html.erb | 12 +- .../appearances/_logo_image_form.html.erb | 12 +- .../admin/appearances/_theme_form.html.erb | 22 +-- .../hyrax/admin/appearances/show.html.erb | 56 +++---- .../_form_participants.html.erb | 10 +- app/views/hyrax/admin/stats/show.html.erb | 41 ++--- app/views/hyrax/admin/users/index.html.erb | 14 +- .../hyrax/admin/workflow_roles/index.html.erb | 42 +++--- app/views/hyrax/base/_form_share.html.erb | 8 +- app/views/hyrax/base/_show_actions.html.erb | 18 +-- app/views/hyrax/base/show.html.erb | 24 +-- app/views/hyrax/contact_form/new.html.erb | 33 ++-- app/views/hyrax/content_blocks/_form.html.erb | 102 +++++++------ app/views/hyrax/dashboard/_sidebar.html.erb | 12 +- .../dashboard/collections/_form.html.erb | 54 ++++--- .../collections/_form_branding.html.erb | 45 +++--- .../collections/_form_discovery.html.erb | 10 +- .../collections/_form_share.html.erb | 141 +++++++++-------- .../collections/_form_share_table.html.erb | 75 ++++----- .../collections/_list_collections.html.erb | 4 +- .../_show_add_items_actions.html.erb | 4 +- .../_show_document_list_row.html.erb | 26 ++-- .../_show_parent_collection_row.html.erb | 6 +- .../collections/_subcollection_list.html.erb | 6 +- .../dashboard/sidebar/_activity.html.erb | 142 ++++++++++-------- .../dashboard/sidebar/_configuration.html.erb | 25 ++- .../sidebar/_repository_content.html.erb | 6 +- .../hyrax/dashboard/sidebar/_tasks.html.erb | 9 +- .../dashboard/works/_list_works.html.erb | 9 +- .../homepage/_explore_collections.html.erb | 5 +- .../_featured_collection_fields.html.erb | 24 +-- .../_featured_collection_section.html.erb | 21 ++- .../hyrax/homepage/_featured_fields.html.erb | 4 +- .../hyrax/homepage/_home_content.html.erb | 41 +++-- app/views/hyrax/homepage/_home_text.html.erb | 12 +- .../_sortable_featured_collections.html.erb | 10 +- .../hyrax/my/_collection_action_menu.html.erb | 17 ++- app/views/hyrax/my/_work_action_menu.html.erb | 26 ++-- .../my/collections/_list_collections.html.erb | 4 +- app/views/hyrax/my/works/_list_works.html.erb | 10 +- .../uploads/_js_templates_branding.html.erb | 24 ++- app/views/hyrax/users/_vitals.html.erb | 21 --- app/views/identity_providers/_form.html.erb | 15 +- app/views/identity_providers/index.html.erb | 11 +- app/views/labels/edit.html.erb | 41 +++-- app/views/layouts/hyrax.html.erb | 6 +- app/views/proprietor/accounts/edit.html.erb | 22 +-- app/views/proprietor/accounts/index.html.erb | 12 +- app/views/proprietor/accounts/new.html.erb | 50 +++--- app/views/proprietor/accounts/show.html.erb | 30 ++-- app/views/proprietor/users/edit.html.erb | 4 +- app/views/proprietor/users/index.html.erb | 12 +- app/views/proprietor/users/new.html.erb | 34 ++--- app/views/proprietor/users/show.html.erb | 8 +- app/views/roles/index.html.erb | 12 +- app/views/shared/_footer.html.erb | 12 +- app/views/single_signon/index.html.erb | 35 ++--- app/views/splash/index.html.erb | 12 +- app/views/status/index.html.erb | 16 +- .../_collections_section.html.erb | 6 +- .../cultural_repository/_facets.html.erb | 14 +- ..._featured_works_home_text_section.html.erb | 18 +-- .../cultural_repository/_home_text.html.erb | 2 +- .../themes/cultural_repository/_logo.html.erb | 22 +-- .../cultural_repository/_masthead.html.erb | 47 +++--- .../_recent_works_section.html.erb | 8 +- .../_user_util_links.html.erb | 51 ++++--- .../catalog/_search_form.html.erb | 30 ++-- .../homepage/_explore_collections.html.erb | 22 +-- .../hyrax/homepage/_facet_layout.html.erb | 13 +- .../hyrax/homepage/_featured.html.erb | 16 +- .../hyrax/homepage/_featured_fields.html.erb | 4 +- .../hyrax/homepage/_featured_works.html.erb | 8 +- .../hyrax/homepage/_marketing.html.erb | 8 +- .../hyrax/homepage/_recent_document.html.erb | 11 +- .../homepage/_recently_uploaded.html.erb | 6 +- .../layouts/_share_your_work_row.html.erb | 16 +- .../layouts/homepage.html.erb | 10 +- .../layouts/hyrax.html.erb | 20 ++- .../hyrax/base/_work_title.html.erb | 2 +- .../cultural_show/hyrax/base/show.html.erb | 26 ++-- .../_controls.html.erb | 42 +++--- .../_home_text.html.erb | 6 +- .../_ir_below_stats_layout.html.erb | 8 +- .../institutional_repository/_logo.html.erb | 22 +-- .../_masthead.html.erb | 45 +++--- .../_user_util_links.html.erb | 32 ++-- .../catalog/_search_form.html.erb | 28 ++-- .../homepage/_explore_collections.html.erb | 22 +-- .../homepage/_featured_researcher.html.erb | 4 +- .../homepage/_ir_homepage_stats.html.erb | 6 +- .../hyrax/homepage/_marketing.html.erb | 4 +- .../hyrax/homepage/_recent_document.html.erb | 6 +- .../homepage/_recently_uploaded.html.erb | 4 +- .../homepage/_resource_type_slider.html.erb | 28 ++-- .../homepage/_resource_type_stats.html.erb | 8 +- .../hyrax/homepage/all_collections.html.erb | 8 +- .../layouts/homepage.html.erb | 12 +- .../layouts/hyrax.html.erb | 16 +- .../_featured_carousel.html.erb | 28 ++-- .../neutral_repository/_home_text.html.erb | 6 +- .../_theme_container.html.erb | 56 ++++--- .../homepage/_explore_collections.html.erb | 8 +- .../homepage/_featured_researcher.html.erb | 4 +- .../hyrax/homepage/_featured_works.html.erb | 10 +- .../hyrax/homepage/_recent_document.html.erb | 11 +- .../homepage/_recently_uploaded.html.erb | 2 +- .../layouts/homepage.html.erb | 4 +- .../hyrax/base/_work_title.html.erb | 4 +- .../scholarly_show/hyrax/base/show.html.erb | 28 ++-- 144 files changed, 1558 insertions(+), 1490 deletions(-) delete mode 100644 app/views/hyrax/users/_vitals.html.erb diff --git a/app/views/_admin_util_links.html.erb b/app/views/_admin_util_links.html.erb index 808e1230e..86a76ae03 100644 --- a/app/views/_admin_util_links.html.erb +++ b/app/views/_admin_util_links.html.erb @@ -1,22 +1,24 @@ <% if user_signed_in? %> <% if can? :manage, Account %> -