Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pod whitelabel #29

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
9997c73
schema refactor changes; change field type for full_text_link field
magibney Oct 21, 2019
2910e8d
add hooks for indexing other institutions records; and actual indexer…
magibney Dec 6, 2019
9966077
was using wrong oclc function for duke cluster_id
magibney Dec 10, 2019
8757c01
added brown indexer, patterned after duke
magibney Dec 10, 2019
114d4cf
add top-level indexing script for brown
magibney Dec 10, 2019
653f6bb
add stanford indexer and top-level script
magibney Dec 10, 2019
717852e
add cornell indexer and top-level script
magibney Dec 10, 2019
9238412
add columbia indexer and top-level script
magibney Dec 10, 2019
f9c28f8
initial facet UI adaptation for 7 record sources
magibney Dec 10, 2019
972081d
TEMPORARY: query faceting (not field) for multi-source format_f
magibney Dec 11, 2019
e9ed6e9
add princeton indexer, facets, and top-level script
magibney Dec 11, 2019
1478c0d
properly namespace Stanford's ids
magibney Dec 11, 2019
90dc3f4
add better label for link to source context
magibney Dec 11, 2019
fb26988
dynamic record source preferences, etc.
magibney Dec 12, 2019
36e3631
change join filter queries to match solr warming
magibney Dec 17, 2019
e2336db
add tiered dedupe respecting asserted encoding level
magibney Dec 18, 2019
cb777b0
temporary(?) disable/reorder some facets for public demo
magibney Dec 19, 2019
ab64f6f
change catalog landing page Franklin text for POD explanation
magibney Dec 20, 2019
b433349
add Harvard
magibney Dec 20, 2019
e68d221
Removed Penn branding and links
Feb 12, 2020
24808ec
Changed references of Franklin to POD
Feb 12, 2020
b444c61
First pass at Ivies+ request button tooltip
Feb 17, 2020
14c8d4c
add Chicago
magibney Feb 12, 2020
087660c
prevent bloated requests by more carefully deduping dedupe params
magibney Feb 12, 2020
8cbaa46
disable bento, etc. (all but catalog)
magibney Feb 19, 2020
971c6cf
remove format facet from whitelabel version
magibney Feb 19, 2020
d08546b
Show Ivies+ Request button on all records
Feb 19, 2020
1075dec
comment out franklinalerts.js on pod whitelabel
magibney May 8, 2020
8459c05
use new tieredDomainDedupe QParser
magibney Sep 9, 2020
4733440
be careful about how join queries are constructed/cached!
magibney Sep 10, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions app/assets/stylesheets/franklin.css.scss
Original file line number Diff line number Diff line change
Expand Up @@ -978,3 +978,57 @@ button.btn-request-options {
border: 2px solid #337ab7;
padding: 0px;
}

/* Tooltip styling for Ivies+ Request button */
// Reference: https://thoughtbot.com/blog/you-don-t-need-javascript-for-that
.tooltip-toggle {
cursor: pointer;
position: relative;

//Tooltip container and image
//You can adjust the position to make the container appear below or beside the element
&::before {
background-color: #fff;
border: 1px solid black;
border-radius: 5px;
color: #fff;
content: url(https://franklin.library.upenn.edu/redir/assets/bdlogo.gif);
height: 120px;
left: -30px; //This centers the container above the element
padding: 1rem;
position: absolute;
text-transform: none;
top: -125px; //This places the container above the element that needs a tooltip
transition: all 0.5s ease;
}

//Tooltip text
//You can adjust the position of this to align nicely with the element that
//needs a tooltip. You can also use `transform` to rotate it to make the
//tooltip work below or next to the element.
// Reference: https://stackoverflow.com/a/4609491
&::after {
content: "Patrons will be able to select their\Ainstitution for authentication";
left: -20px;
position: absolute;
top: -52px;
text-align: center;
white-space: pre;
}

//Setting up the transition
&::before,
&::after {
opacity: 0;
pointer-events: none;
}

//Triggering the transition
&:focus::before,
&:focus::after,
&:hover::before,
&:hover::after {
opacity: 1;
transition: all 0.75s ease;
}
}
101 changes: 83 additions & 18 deletions app/controllers/catalog_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def expire_session
alma_mms_id
score
format_a
full_text_link_text_a
full_text_link_a
isbn_isxn
language_a
title
Expand All @@ -134,7 +134,6 @@ def expire_session
'facet.mincount': 0,
# fq: '{!tag=cluster}{!collapse field=cluster_id nullPolicy=expand size=5000000 min=record_source_id}',
# this approach needs expand.field=cluster_id
fq: %q~{!tag=cluster}NOT ({!join from=cluster_id to=cluster_id v='record_source_f:"Penn"'} AND record_source_f:"HathiTrust")~,
expand: 'true',
'expand.field': 'cluster_id',
'expand.q': '*:*',
Expand Down Expand Up @@ -297,30 +296,96 @@ def expire_session
'Z' => { :label => 'Z', :fq => "{!prefix tag=azlist ex=azlist f=title_xfacet v='z'}"},
'Other' => { :label => 'Other', :fq => "{!tag=azlist ex=azlist}title_xfacet:/[ -`{-~].*/"}
}
config.add_facet_field 'access_f', label: 'Access', collapse: false, solr_params: @@MINCOUNT, query: {
'Online' => { :label => 'Online', :fq => "{!join from=cluster_id to=cluster_id v='{!term f=access_f v=\\'Online\\'}'}"},
'At the library' => { :label => 'At the library', :fq => "{!join from=cluster_id to=cluster_id v='{!term f=access_f v=\\'At the library\\'}'}"}
# config.add_facet_field 'access_f', label: 'Access', collapse: false, solr_params: @@MINCOUNT, query: {
# 'Online' => { :label => 'Online', :fq => "{!join from=cluster_id to=cluster_id v=access_f:Online}"},
# 'At the library' => { :label => 'At the library', :fq => "{!join from=cluster_id to=cluster_id v='{!term f=access_f v=\\'At the library\\'}'}"}
# }
config.add_facet_field 'cluster', label: 'Prioritize your institution', collapse: false, single: :manual, solr_params: @@MINCOUNT, query: {
'Brown' => { :label => 'Brown', :fq => '{!tieredDomainDedupe tag=cluster ex=cluster f=record_source_f joinField=cluster_id v=Brown,Chicago,Columbia,Cornell,Duke,Harvard,Penn,Princeton,Stanford,HathiTrust}'},
'Chicago' => { :label => 'Chicago', :fq => '{!tieredDomainDedupe tag=cluster ex=cluster f=record_source_f joinField=cluster_id v=Chicago,Brown,Columbia,Cornell,Duke,Harvard,Penn,Princeton,Stanford,HathiTrust}'},
'Columbia' => { :label => 'Columbia', :fq => '{!tieredDomainDedupe tag=cluster ex=cluster f=record_source_f joinField=cluster_id v=Columbia,Brown,Chicago,Cornell,Duke,Harvard,Penn,Princeton,Stanford,HathiTrust}'},
'Cornell' => { :label => 'Cornell', :fq => '{!tieredDomainDedupe tag=cluster ex=cluster f=record_source_f joinField=cluster_id v=Cornell,Brown,Chicago,Columbia,Duke,Harvard,Penn,Princeton,Stanford,HathiTrust}'},
'Duke' => { :label => 'Duke', :fq => '{!tieredDomainDedupe tag=cluster ex=cluster f=record_source_f joinField=cluster_id v=Duke,Brown,Chicago,Columbia,Cornell,Harvard,Penn,Princeton,Stanford,HathiTrust}'},
'Harvard' => { :label => 'Harvard', :fq => '{!tieredDomainDedupe tag=cluster ex=cluster f=record_source_f joinField=cluster_id v=Harvard,Brown,Chicago,Columbia,Cornell,Duke,Penn,Princeton,Stanford,HathiTrust}'},
'Penn' => { :label => 'Penn', :fq => '{!tieredDomainDedupe tag=cluster ex=cluster f=record_source_f joinField=cluster_id v=Penn,Brown,Chicago,Columbia,Cornell,Duke,Harvard,Princeton,Stanford,HathiTrust}'},
'Princeton' => { :label => 'Princeton', :fq => '{!tieredDomainDedupe tag=cluster ex=cluster f=record_source_f joinField=cluster_id v=Princeton,Brown,Chicago,Columbia,Cornell,Duke,Harvard,Penn,Stanford,HathiTrust}'},
'Stanford' => { :label => 'Stanford', :fq => '{!tieredDomainDedupe tag=cluster ex=cluster f=record_source_f joinField=cluster_id v=Stanford,Brown,Chicago,Columbia,Cornell,Duke,Harvard,Penn,Princeton,HathiTrust}'},
'HathiTrust' => { :label => 'HathiTrust', :fq => '{!tieredDomainDedupe tag=cluster ex=cluster f=record_source_f joinField=cluster_id v=HathiTrust,Brown,Chicago,Columbia,Cornell,Duke,Harvard,Penn,Princeton,Stanford}'},
# 'Brown-e' => { :label => 'Brown-e', :fq => generate_cluster_fq(0, 6, true)},
# 'Columbia-e' => { :label => 'Columbia-e', :fq => generate_cluster_fq(1, 6, true)},
# 'Cornell-e' => { :label => 'Cornell-e', :fq => generate_cluster_fq(2, 6, true)},
# 'Duke-e' => { :label => 'Duke-e', :fq => generate_cluster_fq(3, 6, true)},
# 'Penn-e' => { :label => 'Penn-e', :fq => generate_cluster_fq(4, 6, true)},
# 'Princeton-e' => { :label => 'Princeton-e', :fq => generate_cluster_fq(5, 6, true)},
# 'Stanford-e' => { :label => 'Stanford-e', :fq => generate_cluster_fq(6, 6, true)},
# 'HathiTrust-e' => { :label => 'HathiTrust-e', :fq => generate_cluster_fq(7, 6, true)},
'Dynamic' => { :label => 'Dynamic', :fq => '*:*'}
}
config.add_facet_field 'record_source_f', label: 'Record Source', collapse: false, solr_params: @@MINCOUNT, query: {
'HathiTrust' => { :label => 'HathiTrust', :fq => "{!join from=cluster_id to=cluster_id v='{!term f=record_source_f v=\\'HathiTrust\\'}'}"},
'Penn' => { :label => 'Penn', :fq => "{!join from=cluster_id to=cluster_id v='{!term f=record_source_f v=\\'Penn\\'}'}"}
config.add_facet_field 'record_source_exclusive', label: 'See exclusively records from', collapse: false, single: :manual, solr_params: @@MINCOUNT, query: {
'Brown' => { :label => 'Brown', :fq => '{!term tag=rsx ex=rsx f=record_source_f v=Brown}'},
'Chicago' => { :label => 'Chicago', :fq => '{!term tag=rsx ex=rsx f=record_source_f v=Chicago}'},
'Columbia' => { :label => 'Columbia', :fq => '{!term tag=rsx ex=rsx f=record_source_f v=Columbia}'},
'Cornell' => { :label => 'Cornell', :fq => '{!term tag=rsx ex=rsx f=record_source_f v=Cornell}'},
'Duke' => { :label => 'Duke', :fq => '{!term tag=rsx ex=rsx f=record_source_f v=Duke}'},
'Harvard' => { :label => 'Harvard', :fq => '{!term tag=rsx ex=rsx f=record_source_f v=Harvard}'},
'Penn' => { :label => 'Penn', :fq => '{!term tag=rsx ex=rsx f=record_source_f v=Penn}'},
'Princeton' => { :label => 'Princeton', :fq => '{!term tag=rsx ex=rsx f=record_source_f v=Princeton}'},
'Stanford' => { :label => 'Stanford', :fq => '{!term tag=rsx ex=rsx f=record_source_f v=Stanford}'},
'HathiTrust' => { :label => 'HathiTrust', :fq => '{!term tag=rsx ex=rsx f=record_source_f v=HathiTrust}'},
}
config.add_facet_field 'format_f', label: 'Format', limit: 5, collapse: false, solr_params: @@MINCOUNT
config.add_facet_field 'record_source_f', label: 'See any records clustered with holdings from', collapse: false, solr_params: @@MINCOUNT, query: {
'Brown' => { :label => 'Brown', :fq => "{!join from=cluster_id to=cluster_id v='{!term f=record_source_f v=Brown}'}"},
'Chicago' => { :label => 'Chicago', :fq => "{!join from=cluster_id to=cluster_id v='{!term f=record_source_f v=Chicago}'}"},
'Columbia' => { :label => 'Columbia', :fq => "{!join from=cluster_id to=cluster_id v='{!term f=record_source_f v=Columbia}'}"},
'Cornell' => { :label => 'Cornell', :fq => "{!join from=cluster_id to=cluster_id v='{!term f=record_source_f v=Cornell}'}"},
'Duke' => { :label => 'Duke', :fq => "{!join from=cluster_id to=cluster_id v='{!term f=record_source_f v=Duke}'}"},
'Harvard' => { :label => 'Harvard', :fq => "{!join from=cluster_id to=cluster_id v='{!term f=record_source_f v=Harvard}'}"},
'Penn' => { :label => 'Penn', :fq => "{!join from=cluster_id to=cluster_id v='{!term f=record_source_f v=Penn}'}"},
'Princeton' => { :label => 'Princeton', :fq => "{!join from=cluster_id to=cluster_id v='{!term f=record_source_f v=Princeton}'}"},
'Stanford' => { :label => 'Stanford', :fq => "{!join from=cluster_id to=cluster_id v='{!term f=record_source_f v=Stanford}'}"},
'HathiTrust' => { :label => 'HathiTrust', :fq => "{!join from=cluster_id to=cluster_id v='{!term f=record_source_f v=HathiTrust}'}"}
}
config.add_facet_field 'elvl', label: 'Encoding Level', collapse: false, solr_params: @@MINCOUNT, query: {
'Full' => { :label => 'Full', :fq => "elvl_rank_isort:0"},
'Other' => { :label => 'Other', :fq => '{!bool must_not=elvl_rank_isort:0}'}
}
# config.add_facet_field 'format_f', label: 'Format', limit: 5, collapse: false, solr_params: @@MINCOUNT, query: {
# 'Book' => { :label => 'Book', :fq => "{!term f=format_f v='Book'}"},
# 'Government document' => { :label => 'Government document', :fq => "{!term f=format_f v='Government document'}"},
# 'Journal/Periodical' => { :label => 'Journal/Periodical', :fq => "{!term f=format_f v='Journal/Periodical'}"},
# 'Microformat' => { :label => 'Microformat', :fq => "{!term f=format_f v='Microformat'}"},
# 'Sound recording' => { :label => 'Sound recording', :fq => "{!term f=format_f v='Sound recording'}"},
# 'Musical score' => { :label => 'Musical score', :fq => "{!term f=format_f v='Musical score'}"},
# 'Video' => { :label => 'Video', :fq => "{!term f=format_f v='Video'}"},
# 'Conference/Event' => { :label => 'Conference/Event', :fq => "{!term f=format_f v='Conference/Event'}"},
# 'Manuscript' => { :label => 'Manuscript', :fq => "{!term f=format_f v='Manuscript'}"},
# 'Thesis/Dissertation' => { :label => 'Thesis/Dissertation', :fq => "{!term f=format_f v='Thesis/Dissertation'}"},
# 'Newspaper' => { :label => 'Newspaper', :fq => "{!term f=format_f v='Newspaper'}"},
# 'Datafile' => { :label => 'Datafile', :fq => "{!term f=format_f v='Datafile'}"},
# 'Image' => { :label => 'Image', :fq => "{!term f=format_f v='Image'}"},
# 'Website/Database' => { :label => 'Website/Database', :fq => "{!term f=format_f v='Website/Database'}"},
# 'Map/Atlas' => { :label => 'Map/Atlas', :fq => "{!term f=format_f v='Map/Atlas'}"},
# 'Archive' => { :label => 'Archive', :fq => "{!term f=format_f v='Archive'}"},
# 'Other' => { :label => 'Other', :fq => "{!term f=format_f v='Other'}"},
# 'Database & Article Index' => { :label => 'Database & Article Index', :fq => "{!term f=format_f v='Database & Article Index'}"},
# '3D object' => { :label => '3D object', :fq => "{!term f=format_f v='3D object'}"},
# 'Projected graphic' => { :label => 'Projected graphic', :fq => "{!term f=format_f v='Projected graphic'}"},
# }
config.add_facet_field 'author_creator_f', label: 'Author/Creator', limit: 5, index_range: 'A'..'Z', collapse: false, solr_params: @@MINCOUNT
#config.add_facet_field 'subject_taxonomy', label: 'Subject Taxonomy', collapse: false, :partial => 'blacklight/hierarchy/facet_hierarchy', :json_facet => @@SUBJECT_TAXONOMY, :top_level_field => 'toplevel_subject_f', :helper_method => :render_subcategories
config.add_facet_field 'subject_f', label: 'Subject', limit: 5, index_range: 'A'..'Z', collapse: false, solr_params: @@MINCOUNT
config.add_facet_field 'language_f', label: 'Language', limit: 5, collapse: false, solr_params: @@MINCOUNT
config.add_facet_field 'library_f', label: 'Library', limit: 5, collapse: false, solr_params: @@MINCOUNT
config.add_facet_field 'specific_location_f', label: 'Specific location', limit: 5, solr_params: @@MINCOUNT
# config.add_facet_field 'library_f', label: 'Library', limit: 5, collapse: false, solr_params: @@MINCOUNT
# config.add_facet_field 'specific_location_f', label: 'Specific location', limit: 5, solr_params: @@MINCOUNT
config.add_facet_field 'publication_date_f', label: 'Publication date', limit: 5, collapse: false, solr_params: @@MINCOUNT
config.add_facet_field 'classification_f', label: 'Classification', limit: 5, collapse: false, solr_params: @@MINCOUNT
# config.add_facet_field 'classification_f', label: 'Classification', limit: 5, collapse: false, solr_params: @@MINCOUNT
config.add_facet_field 'genre_f', label: 'Form/Genre', limit: 5, solr_params: @@MINCOUNT
config.add_facet_field 'recently_added_f', label: 'Recently added', solr_params: @@MINCOUNT, :query => {
:within_90_days => { label: 'Within 90 days', fq: "recently_added_isort:[#{PennLib::Util.today_midnight - (90 * SECONDS_PER_DAY) } TO *]" },
:within_60_days => { label: 'Within 60 days', fq: "recently_added_isort:[#{PennLib::Util.today_midnight - (60 * SECONDS_PER_DAY) } TO *]" },
:within_30_days => { label: 'Within 30 days', fq: "recently_added_isort:[#{PennLib::Util.today_midnight - (30 * SECONDS_PER_DAY) } TO *]" },
:within_15_days => { label: 'Within 15 days', fq: "recently_added_isort:[#{PennLib::Util.today_midnight - (15 * SECONDS_PER_DAY) } TO *]" },
}
# config.add_facet_field 'recently_added_f', label: 'Recently added', solr_params: @@MINCOUNT, :query => {
# :within_90_days => { label: 'Within 90 days', fq: "recently_added_isort:[#{PennLib::Util.today_midnight - (90 * SECONDS_PER_DAY) } TO *]" },
# :within_60_days => { label: 'Within 60 days', fq: "recently_added_isort:[#{PennLib::Util.today_midnight - (60 * SECONDS_PER_DAY) } TO *]" },
# :within_30_days => { label: 'Within 30 days', fq: "recently_added_isort:[#{PennLib::Util.today_midnight - (30 * SECONDS_PER_DAY) } TO *]" },
# :within_15_days => { label: 'Within 15 days', fq: "recently_added_isort:[#{PennLib::Util.today_midnight - (15 * SECONDS_PER_DAY) } TO *]" },
# }

#config.add_facet_field 'example_pivot_field', label: 'Pivot Field', :pivot => ['format_f', 'language_f']
# config.add_facet_field 'example_query_facet_field', label: 'Publish Date', :query => {
Expand Down
2 changes: 1 addition & 1 deletion app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def catalog_results_url(query)
def active_tab_classes(tab_id)

# treat bento as special case; almost everything else falls through to catalog
on_bento_page = (controller_name == 'catalog') && ['landing', 'bento'].member?(action_name)
on_bento_page = false #(controller_name == 'catalog') && ['landing', 'bento'].member?(action_name)

# databases search, falls through to catalog but different tab should be highlighted
on_databases_page = params.dig('f', 'format_f')&.include?('Database & Article Index')
Expand Down
8 changes: 8 additions & 0 deletions app/models/base_indexer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ module RecordSource
PENN = 1
HATHI = 2
CRL = 3
DUKE = 4
CORNELL = 5
BROWN = 6
COLUMBIA = 7
HARVARD = 8
STANFORD = 9
PRINCETON = 10
CHICAGO = 11
end

end
103 changes: 103 additions & 0 deletions app/models/brown_indexer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@

class BrownIndexer < FranklinIndexer

def define_record_source_id
to_field 'record_source_id' do |rec, acc|
acc << RecordSource::BROWN
end
end

def define_record_source_facet
to_field 'record_source_f' do |rec, acc|
acc << 'Brown'
end
end

def get_namespaced_id(rec)
id = get_local_system_id(rec)
id.blank? ? nil : "BROWN_#{id}"
end

def link_to_source_context(rec)
system_id = get_local_system_id(rec)
"https://search.library.brown.edu/catalog/b#{system_id}"
end

def define_mms_id
# no-op
end

def define_id
to_field 'id' do |rec, acc, context|
id = get_namespaced_id(rec)
if id.nil?
context.skip!('Skipping institutional record with bad/no 907a')
end
acc.replace([id])
end
end

def get_001_id(rec)
id = rec.fields('001').first&.value&.strip
id.blank? ? nil : id
end

def define_grouped_id
to_field 'grouped_id' do |rec, acc|
oclc_id = get_oclc_id(rec)
id = get_namespaced_id(rec)

prefix = oclc_id.present? ? "#{oclc_id}!" : ''
acc << "#{prefix}#{id}"
end
end

def get_oclc_id(rec)
candidate = get_001_id(rec)
m = /oc?[mn][^1-9]*([1-9][0-9]*)/.match(candidate)
m ? m[1] : nil
end

def subfield_a_is_system_id(sf)
sf.code == 'a' && sf.value =~ /^\.b[0-9]+/
end

def get_local_system_id(rec)
rec.fields('907')
.select { |f| f.any? { |sf| subfield_a_is_system_id(sf) } }
.take(1)
.flat_map do |field|
field.find_all { |sf| subfield_a_is_system_id(sf) }.map do |sf|
m = /^\s*\.b([0-9]+).*$/.match(sf.value)
if m
m[1]
end
end.compact.first
end.compact.first
end

def define_full_text_link_a
to_field 'full_text_link_a' do |rec, acc|

links = []

links << {
linktext: 'View record in Brown\'s catalog',
linkurl: link_to_source_context(rec)
}

acc << links.to_json

end
end

def get_cluster_id(rec)
get_oclc_id(rec) || begin
id = get_namespaced_id(rec)
digest = Digest::MD5.hexdigest(id)
# first 8 hex digits = first 4 bytes. construct an int out of that hex str.
digest[0,8].hex
end
end

end
Loading