spotlight-atom 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bdbbd2763c5600927de41dacadcb558ade4e3b27
4
+ data.tar.gz: 8012d2d20656bd4c4fe716091ca189dee1fac779
5
+ SHA512:
6
+ metadata.gz: d453b5be60212c19aa09fbe80dd5ed24404684d6d10a6643cf4815a0efdf340f317e32f9e74099d328dc13fd57042151923fa5505004d7f99510cbac1500f79d
7
+ data.tar.gz: 86a17c6c78a85bbcc0d73203a8574ec07ed499954dfcf7cfd81a5af73a2be05d3f35487682f8d77f171b3dd0802f8be524f71fc254e0149718a8aa0a4c15afc9
@@ -0,0 +1,22 @@
1
+ *.rbc
2
+ *.sassc
3
+ .sass-cache
4
+ capybara-*.html
5
+ .rspec
6
+ .rvmrc
7
+ /.bundle
8
+ /vendor/bundle
9
+ /log/*
10
+ /tmp/*
11
+ /db/*.sqlite3
12
+ /public/system/*
13
+ /coverage/
14
+ /spec/tmp/*
15
+ **.orig
16
+ rerun.txt
17
+ pickle-email-*.html
18
+ .project
19
+ config/initializers/secret_token.rb
20
+ spec/internal
21
+ Gemfile.lock
22
+ jetty
@@ -0,0 +1,18 @@
1
+ notifications:
2
+ email: false
3
+
4
+ rvm:
5
+ - 2.1
6
+
7
+ notifications:
8
+ irc: "irc.freenode.org#blacklight"
9
+ email:
10
+ - exhibits-team@lists.stanford.edu
11
+
12
+ env:
13
+ global:
14
+ - JRUBY_OPTS="-J-Xms512m -J-Xmx1024m"
15
+ - NOKOGIRI_USE_SYSTEM_LIBRARIES=true
16
+
17
+ sudo: false
18
+ language: ruby
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in spotlight-atom-resources.gemspec
4
+ gemspec
@@ -0,0 +1,31 @@
1
+ # Spotlight::Atom
2
+
3
+ Harvest resources in Atom feeds into a Spotlight exhibit
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'spotlight-atom'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install spotlight-atom
20
+
21
+ ## Usage
22
+
23
+ This gem adds a new "Repository Item" form to your Spotlight application. This form allows curators to input a URL to an Atom feed, and the contents of the feed will be harvested as new items in the Spotlight exhibit. Currently, this gem supports harvesting basic metadata from either Blacklight or Omeka feeds.
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/cbeer/spotlight-atom/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
@@ -0,0 +1,45 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ ZIP_URL = "https://github.com/projectblacklight/blacklight-jetty/archive/v4.10.4.zip"
4
+
5
+ require 'jettywrapper'
6
+
7
+ require 'engine_cart/rake_task'
8
+ EngineCart.fingerprint_proc = EngineCart.rails_fingerprint_proc
9
+
10
+ task default: :ci
11
+
12
+ task :ci => ['engine_cart:generate', 'jetty:clean', 'configure_jetty'] do
13
+ ENV['environment'] = "test"
14
+ jetty_params = Jettywrapper.load_config
15
+ jetty_params[:startup_wait]= 60
16
+
17
+ Jettywrapper.wrap(jetty_params) do
18
+ # run the tests
19
+ Rake::Task["spec"].invoke
20
+ end
21
+ end
22
+
23
+ task :configure_jetty do
24
+ FileList['solr_conf/conf/*'].each do |f|
25
+ cp("#{f}", 'jetty/solr/blacklight-core/conf/', :verbose => true)
26
+ end
27
+ end
28
+
29
+ task :server do
30
+ Rake::Task['engine_cart:generate'].invoke
31
+
32
+ unless File.exists? 'jetty'
33
+ Rake::Task['jetty:clean'].invoke
34
+ Rake::Task['configure_jetty'].invoke
35
+ end
36
+
37
+ jetty_params = Jettywrapper.load_config
38
+ jetty_params[:startup_wait]= 60
39
+
40
+ Jettywrapper.wrap(jetty_params) do
41
+ within_test_app do
42
+ system "bundle exec rails s"
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,96 @@
1
+ module Spotlight::Resources
2
+ class AtomHarvester < Spotlight::Resource
3
+ self.weight = -5000
4
+
5
+ after_save :harvest_resources
6
+
7
+ def self.can_provide? res
8
+ is_atom?(res.url) || !!(res.url =~ /.atom/)
9
+ end
10
+
11
+ def self.is_atom? url
12
+ Faraday.head(url) do |req|
13
+ req.headers['Accept'] = 'application/atom+xml'
14
+ end.status == 200
15
+ end
16
+
17
+ def update_index data
18
+ data = [data] unless data.is_a? Array
19
+ blacklight_solr.update params: { commitWithin: 500 }, data: data.to_json, headers: { 'Content-Type' => 'application/json'} unless data.empty?
20
+ end
21
+
22
+ def to_solr
23
+ []
24
+ end
25
+
26
+ def harvest_resources
27
+ items.each do |x|
28
+ h = convert_entry_to_solr_hash(x)
29
+ puts "creating #{h.inspect}"
30
+ Spotlight::Resources::Upload.create(
31
+ remote_url_url: h[:url],
32
+ data: h,
33
+ exhibit: exhibit
34
+ ) if h[:url]
35
+ end
36
+ end
37
+
38
+ def items
39
+ return enum_for(:items) unless block_given?
40
+
41
+ doc = fetch(self.url)
42
+ while doc and doc.xpath('//atom:entry', ns).any?
43
+ h = doc.xpath('//atom:entry', ns).map do |x|
44
+ yield x
45
+ end
46
+
47
+ if doc.xpath('/atom:feed/atom:link[@rel="next"]', ns).any?
48
+ doc = fetch(doc.xpath('/atom:feed/atom:link[@rel="next"]', ns).first.attr('href'))
49
+ else
50
+ doc = nil
51
+ break
52
+ end
53
+ end
54
+ end
55
+
56
+ def convert_entry_to_solr_hash x
57
+ {
58
+ exhibit.blacklight_config.document_model.unique_key.to_sym => compound_id(x),
59
+ title_field => x.xpath('atom:title', ns).text,
60
+ url: x.xpath('atom:link[contains(@rel, "enclosure")]/@href', ns).text
61
+ }
62
+ end
63
+
64
+ def compound_id x
65
+ x.xpath("atom:id", ns).text.parameterize
66
+ end
67
+
68
+ def fetch url
69
+ Nokogiri::XML(Faraday.get(url) do |req|
70
+ req.headers['Accept'] = 'application/atom+xml'
71
+ end.body)
72
+ end
73
+
74
+ def ns
75
+ { atom: "http://www.w3.org/2005/Atom" }
76
+ end
77
+
78
+ def title_field
79
+ Spotlight::Engine.config.upload_title_field || exhibit.blacklight_config.index.title_field
80
+ end
81
+
82
+ def create_sidecars_for *keys
83
+ missing = keys - exhibit.custom_fields.map { |x| x.label }
84
+
85
+ missing.each do |k|
86
+ exhibit.custom_fields.create! label: k
87
+ end.tap { @exhibit_custom_fields = nil }
88
+ end
89
+
90
+ def exhibit_custom_fields
91
+ @exhibit_custom_fields ||= exhibit.custom_fields.each_with_object({}) do |value, hash|
92
+ hash[value.label] = value
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,21 @@
1
+ module Spotlight::Resources
2
+ class BlacklightHarvester < Spotlight::Resources::AtomHarvester
3
+ def convert_entry_to_solr_hash x
4
+ content = atom_content_to_hash(x)
5
+ create_sidecars_for(*content.keys)
6
+ h = {}
7
+
8
+ content.each_with_object(h) do |(key, value), hash|
9
+ h[exhibit_custom_fields[key].field] = value
10
+ end
11
+
12
+ super.merge h
13
+ end
14
+
15
+ def atom_content_to_hash x
16
+ content = Hash[Nokogiri::HTML(x.xpath("atom:content", ns).text).css('dt').map do |dt|
17
+ [dt.text, dt.first.next('dd').text]
18
+ end].reject { |k,v| k.blank? }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,22 @@
1
+ module Spotlight::Resources
2
+ class OmekaHarvester < Spotlight::Resources::AtomHarvester
3
+ def convert_entry_to_solr_hash x
4
+ content = atom_content_to_hash(x)
5
+ create_sidecars_for(*content.keys)
6
+ h = {}
7
+
8
+ content.each_with_object(h) do |(key, value), hash|
9
+ h[exhibit_custom_fields[key].field] = value
10
+ end
11
+
12
+ super.merge h
13
+ end
14
+
15
+ def atom_content_to_hash x
16
+ content = Hash[Nokogiri::HTML(x.xpath("atom:content", ns).text).css('.element').map do |d|
17
+ [d.css('h3').text, d.css('.element-text').text]
18
+ end].reject { |k,v| k.blank? }
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,9 @@
1
+ <%= bootstrap_form_for([current_exhibit, @resource], layout: :horizontal, label_col: 'col-md-2', control_col: 'col-sm-6 col-md-6', html: { class: 'item-upload-form', multipart: true } ) do |f| %>
2
+ <%= f.text_area :url, help: t('.url-field.help') %>
3
+ <div class="form-actions">
4
+ <div class="primary-actions">
5
+ <%= cancel_link @resource, :back, class: 'btn btn-default' %>
6
+ <%= f.submit t('.add_item'), class: 'btn btn-primary' %>
7
+ </div>
8
+ </div>
9
+ <% end %>
@@ -0,0 +1,9 @@
1
+ <%= bootstrap_form_for([current_exhibit, @resource], layout: :horizontal, label_col: 'col-md-2', control_col: 'col-sm-6 col-md-6', html: { class: 'item-upload-form', multipart: true } ) do |f| %>
2
+ <%= f.text_area :url, help: t('.url-field.help') %>
3
+ <div class="form-actions">
4
+ <div class="primary-actions">
5
+ <%= cancel_link @resource, :back, class: 'btn btn-default' %>
6
+ <%= f.submit t('.add_item'), class: 'btn btn-primary' %>
7
+ </div>
8
+ </div>
9
+ <% end %>
@@ -0,0 +1,18 @@
1
+ <div role="tabpanel" class="item-upload-tabs">
2
+ <ul class="nav nav-tabs" role="tablist">
3
+ <% Spotlight::Atom::Resources::Engine.config.resource_partials.each_with_index do |p, i| %>
4
+ <% name = p.split('/').last %>
5
+ <li role="presentation" class="<%= "active" if i ==0 %>">
6
+ <%= link_to t(".#{name}"), "##{name}", role: 'tab', 'data-toggle' => 'tab', 'aria-controls' => 'single' %>
7
+ </li>
8
+ <% end %>
9
+ </ul>
10
+ <div class="tab-content">
11
+ <% Spotlight::Atom::Resources::Engine.config.resource_partials.each_with_index do |p, i| %>
12
+ <% name = p.split('/').last %>
13
+ <%= content_tag :div, id: name, role: 'tabpanel', class: "tab-pane #{"active" if i == 0}" do %>
14
+ <%= render p %>
15
+ <% end %>
16
+ <% end %>
17
+ </div>
18
+ </div>
@@ -0,0 +1,11 @@
1
+ en:
2
+ spotlight:
3
+ resources:
4
+ atom:
5
+ tabbed_form:
6
+ omeka: "Omeka"
7
+ blacklight: "Blacklight"
8
+ blacklight:
9
+ add_item: "Import feed"
10
+ omeka:
11
+ add_item: "Import feed"
@@ -0,0 +1,9 @@
1
+ require 'spotlight/atom/version'
2
+ require 'spotlight'
3
+ require 'faraday'
4
+
5
+ module Spotlight
6
+ module Atom
7
+ require 'spotlight/atom/engine'
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ require 'spotlight/engine'
2
+
3
+ module Spotlight
4
+ module Atom
5
+ class Engine < ::Rails::Engine
6
+ Spotlight::Resources::Engine.config.resource_partials = ['spotlight/resources/atom/blacklight', 'spotlight/resources/atom/omeka']
7
+ initializer "spotlight.dor.initialize" do
8
+ Spotlight::Engine.config.resource_providers << Spotlight::Resources::OmekaHarvester
9
+ Spotlight::Engine.config.resource_providers << Spotlight::Resources::BlacklightHarvester
10
+ Spotlight::Engine.config.resource_providers << Spotlight::Resources::AtomHarvester
11
+ Spotlight::Engine.config.new_resource_partials ||= []
12
+ Spotlight::Engine.config.new_resource_partials << 'spotlight/resources/atom/tabbed_form'
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ module Spotlight
2
+ module Atom
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,159 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <schema name="Hydra" version="1.5">
3
+ <!-- NOTE: various comments and unused configuration possibilities have been purged
4
+ from this file. Please refer to http://wiki.apache.org/solr/SchemaXml,
5
+ as well as the default schema file included with Solr -->
6
+
7
+ <uniqueKey>id</uniqueKey>
8
+
9
+ <fields>
10
+ <field name="id" type="string" stored="true" indexed="true" multiValued="false" required="true"/>
11
+ <field name="_version_" type="long" indexed="true" stored="true"/>
12
+ <field name="timestamp" type="date" indexed="true" stored="true" default="NOW" multiValued="false"/>
13
+
14
+ <dynamicField name="*_bbox" type="location_rpt" stored="true" indexed="true"/>
15
+ <dynamicField name="*_ng" type="text_en_ng" stored="false" indexed="true" multiValued="true"/>
16
+
17
+ <dynamicField name="*_ts" type="text" stored="true" indexed="false" multiValued="false"/>
18
+ <dynamicField name="*_tsm" type="text" stored="true" indexed="false" multiValued="true"/>
19
+ <dynamicField name="*_tsi" type="text" stored="true" indexed="true" multiValued="false"/>
20
+ <dynamicField name="*_tsim" type="text" stored="true" indexed="true" multiValued="true"/>
21
+ <dynamicField name="*_tsiv" type="text" stored="true" indexed="true" multiValued="false" termVectors="true" termPositions="true" termOffsets="true"/>
22
+ <dynamicField name="*_tsimv" type="text" stored="true" indexed="true" multiValued="true" termVectors="true" termPositions="true" termOffsets="true"/>
23
+
24
+ <dynamicField name="*_tes" type="text_en" stored="true" indexed="false" multiValued="false"/>
25
+ <dynamicField name="*_tesm" type="text_en" stored="true" indexed="false" multiValued="true"/>
26
+ <dynamicField name="*_tesi" type="text_en" stored="true" indexed="true" multiValued="false"/>
27
+ <dynamicField name="*_tesim" type="text_en" stored="true" indexed="true" multiValued="true"/>
28
+ <dynamicField name="*_tesiv" type="text_en" stored="true" indexed="true" multiValued="false" termVectors="true" termPositions="true" termOffsets="true"/>
29
+ <dynamicField name="*_tesimv" type="text_en" stored="true" indexed="true" multiValued="true" termVectors="true" termPositions="true" termOffsets="true"/>
30
+
31
+ <dynamicField name="*_ss" type="string" stored="true" indexed="false" multiValued="false"/>
32
+ <dynamicField name="*_ssm" type="string" stored="true" indexed="false" multiValued="true"/>
33
+ <dynamicField name="*_ssi" type="string" stored="true" indexed="true" multiValued="false"/>
34
+ <dynamicField name="*_ssim" type="string" stored="true" indexed="true" multiValued="true"/>
35
+
36
+ <dynamicField name="*_is" type="int" stored="true" indexed="false" multiValued="false"/>
37
+ <dynamicField name="*_ism" type="int" stored="true" indexed="false" multiValued="true"/>
38
+ <dynamicField name="*_isi" type="int" stored="true" indexed="true" multiValued="false"/>
39
+ <dynamicField name="*_isim" type="int" stored="true" indexed="true" multiValued="true"/>
40
+
41
+ <dynamicField name="*_dts" type="date" stored="true" indexed="false" multiValued="false"/>
42
+ <dynamicField name="*_dtsm" type="date" stored="true" indexed="false" multiValued="true"/>
43
+ <dynamicField name="*_dtsi" type="date" stored="true" indexed="true" multiValued="false"/>
44
+ <dynamicField name="*_dtsim" type="date" stored="true" indexed="true" multiValued="true"/>
45
+
46
+ <dynamicField name="*_ls" type="long" stored="true" indexed="false" multiValued="false"/>
47
+ <dynamicField name="*_lsm" type="long" stored="true" indexed="false" multiValued="true"/>
48
+ <dynamicField name="*_lsi" type="long" stored="true" indexed="true" multiValued="false"/>
49
+ <dynamicField name="*_lsim" type="long" stored="true" indexed="true" multiValued="true"/>
50
+
51
+ <!-- double (_db...) -->
52
+ <dynamicField name="*_dbs" type="double" stored="true" indexed="false" multiValued="false"/>
53
+ <dynamicField name="*_dbsm" type="double" stored="true" indexed="false" multiValued="true"/>
54
+ <dynamicField name="*_dbsi" type="double" stored="true" indexed="true" multiValued="false"/>
55
+ <dynamicField name="*_dbsim" type="double" stored="true" indexed="true" multiValued="true"/>
56
+
57
+ <dynamicField name="*_fs" type="float" stored="true" indexed="false" multiValued="false"/>
58
+ <dynamicField name="*_fsm" type="float" stored="true" indexed="false" multiValued="true"/>
59
+ <dynamicField name="*_fsi" type="float" stored="true" indexed="true" multiValued="false"/>
60
+ <dynamicField name="*_fsim" type="float" stored="true" indexed="true" multiValued="true"/>
61
+
62
+ <dynamicField name="*_bs" type="boolean" stored="true" indexed="false" multiValued="false"/>
63
+ <dynamicField name="*_bsi" type="boolean" stored="true" indexed="true" multiValued="false"/>
64
+
65
+ <dynamicField name="*_lls" type="location" stored="true" indexed="false" multiValued="false"/>
66
+ <dynamicField name="*_llsm" type="location" stored="true" indexed="false" multiValued="true"/>
67
+ <dynamicField name="*_llsi" type="location" stored="true" indexed="true" multiValued="false"/>
68
+ <dynamicField name="*_llsim" type="location" stored="true" indexed="true" multiValued="true"/>
69
+
70
+ <!-- you must define copyField source and dest fields explicity or schemaBrowser doesn't work -->
71
+ <field name="all_text_timv" type="text" stored="false" indexed="true" multiValued="true" termVectors="true" termPositions="true" termOffsets="true"/>
72
+
73
+
74
+ </fields>
75
+
76
+
77
+ <!-- Above, multiple source fields are copied to the [text] field.
78
+ Another way to map multiple source fields to the same
79
+ destination field is to use the dynamic field syntax.
80
+ copyField also supports a maxChars to copy setting. -->
81
+
82
+ <copyField source="id" dest="id_ng" maxChars="3000"/>
83
+ <copyField source="full_title_tesim" dest="full_title_ng" maxChars="3000"/>
84
+ <copyField source="*_tesim" dest="all_text_timv" maxChars="3000"/>
85
+ <copyField source="*_ssim" dest="all_text_timv" maxChars="3000"/>
86
+
87
+ <types>
88
+ <fieldType name="string" class="solr.StrField" sortMissingLast="true" />
89
+ <fieldType name="boolean" class="solr.BoolField" sortMissingLast="true"/>
90
+ <fieldType name="rand" class="solr.RandomSortField" omitNorms="true"/>
91
+
92
+ <!-- Default numeric field types. -->
93
+ <fieldType name="int" class="solr.TrieIntField" precisionStep="0" positionIncrementGap="0"/>
94
+ <fieldType name="float" class="solr.TrieFloatField" precisionStep="0" positionIncrementGap="0"/>
95
+ <fieldType name="long" class="solr.TrieLongField" precisionStep="0" positionIncrementGap="0"/>
96
+ <fieldType name="double" class="solr.TrieDoubleField" precisionStep="0" positionIncrementGap="0"/>
97
+
98
+ <!-- The format for this date field is of the form 1995-12-31T23:59:59Z
99
+ Optional fractional seconds are allowed: 1995-12-31T23:59:59.999Z
100
+ -->
101
+ <fieldType name="date" class="solr.TrieDateField" precisionStep="0" positionIncrementGap="0"/>
102
+
103
+ <!-- A specialized field for geospatial search. If indexed, this fieldType must not be multivalued. -->
104
+ <fieldType name="location" class="solr.LatLonType" subFieldSuffix="_coordinate"/>
105
+
106
+ <!-- An alternative geospatial field type new to Solr 4. It supports multiValued and polygon shapes.
107
+ For more information about this and other Spatial fields new to Solr 4, see:
108
+ http://wiki.apache.org/solr/SolrAdaptersForLuceneSpatial4
109
+ -->
110
+ <fieldType name="location_rpt" class="solr.SpatialRecursivePrefixTreeFieldType"
111
+ geo="true" distErrPct="0.025" maxDistErr="0.000009" units="degrees" />
112
+
113
+ <fieldType name="text" class="solr.TextField" omitNorms="false">
114
+ <analyzer>
115
+ <tokenizer class="solr.ICUTokenizerFactory"/>
116
+ <filter class="solr.ICUFoldingFilterFactory"/> <!-- NFKC, case folding, diacritics removed -->
117
+ <filter class="solr.TrimFilterFactory"/>
118
+ </analyzer>
119
+ </fieldType>
120
+
121
+ <!-- A text field with defaults appropriate for English -->
122
+ <fieldType name="text_en" class="solr.TextField" positionIncrementGap="100">
123
+ <analyzer>
124
+ <tokenizer class="solr.ICUTokenizerFactory"/>
125
+ <filter class="solr.ICUFoldingFilterFactory"/> <!-- NFKC, case folding, diacritics removed -->
126
+ <filter class="solr.EnglishPossessiveFilterFactory"/>
127
+ <!-- EnglishMinimalStemFilterFactory is less aggressive than PorterStemFilterFactory: -->
128
+ <filter class="solr.EnglishMinimalStemFilterFactory"/>
129
+ <!--
130
+ <filter class="solr.PorterStemFilterFactory"/>
131
+ -->
132
+ <filter class="solr.TrimFilterFactory"/>
133
+ </analyzer>
134
+ </fieldType>
135
+
136
+ <!-- A text field with defaults appropriate for English an NGrams -->
137
+ <fieldType name="text_en_ng" class="solr.TextField" positionIncrementGap="100">
138
+ <analyzer type="index">
139
+ <tokenizer class="solr.ICUTokenizerFactory"/>
140
+ <filter class="solr.ICUFoldingFilterFactory"/> <!-- NFKC, case folding, diacritics removed -->
141
+ <filter class="solr.EnglishPossessiveFilterFactory"/>
142
+ <!-- EnglishMinimalStemFilterFactory is less aggressive than PorterStemFilterFactory: -->
143
+ <filter class="solr.EnglishMinimalStemFilterFactory"/>
144
+ <filter class="solr.TrimFilterFactory"/>
145
+ <filter class="solr.EdgeNGramFilterFactory" minGramSize="3" maxGramSize="15" />
146
+ </analyzer>
147
+
148
+ <analyzer type="index">
149
+ <tokenizer class="solr.ICUTokenizerFactory"/>
150
+ <filter class="solr.ICUFoldingFilterFactory"/> <!-- NFKC, case folding, diacritics removed -->
151
+ <filter class="solr.EnglishPossessiveFilterFactory"/>
152
+ <!-- EnglishMinimalStemFilterFactory is less aggressive than PorterStemFilterFactory: -->
153
+ <filter class="solr.EnglishMinimalStemFilterFactory"/>
154
+ <filter class="solr.TrimFilterFactory"/>
155
+ </analyzer>
156
+ </fieldType>
157
+ </types>
158
+
159
+ </schema>
@@ -0,0 +1,87 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <config>
3
+ <!-- NOTE: various comments and unused configuration possibilities have been purged
4
+ from this file. Please refer to http://wiki.apache.org/solr/SolrConfigXml,
5
+ as well as the default solrconfig file included with Solr -->
6
+
7
+ <abortOnConfigurationError>${solr.abortOnConfigurationError:true}</abortOnConfigurationError>
8
+
9
+ <luceneMatchVersion>4.10.3</luceneMatchVersion>
10
+
11
+ <directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.StandardDirectoryFactory}"/>
12
+
13
+ <updateHandler class="solr.DirectUpdateHandler2">
14
+ <updateLog>
15
+ <str name="dir">${solr.core0.data.dir:}</str>
16
+ </updateLog>
17
+ </updateHandler>
18
+
19
+ <!-- solr lib dirs -->
20
+ <lib dir="../lib/contrib/analysis-extras/lib" />
21
+ <lib dir="../lib/contrib/analysis-extras/lucene-libs" />
22
+
23
+ <dataDir>${solr.data.dir:}</dataDir>
24
+
25
+ <requestHandler name="search" class="solr.SearchHandler" default="true">
26
+ <lst name="defaults">
27
+ <str name="defType">edismax</str>
28
+ <str name="echoParams">explicit</str>
29
+ <str name="q.alt">*:*</str>
30
+ <str name="mm">2&lt;-1 5&lt;-2 6&lt;90%</str>
31
+ <int name="qs">1</int>
32
+ <int name="ps">2</int>
33
+ <float name="tie">0.01</float>
34
+ <str name="qf">
35
+ id^1000
36
+ full_title_tesim^100
37
+ spotlight_upload_description_tesim^50
38
+ all_text_timv
39
+ </str>
40
+ <str name="pf">
41
+ full_title_tesim^100
42
+ all_text_timv^10
43
+ </str>
44
+
45
+ <str name="fl">
46
+ *, score
47
+ </str>
48
+
49
+ <str name="facet">true</str>
50
+ <str name="facet.mincount">1</str>
51
+ <str name="facet.limit">10</str>
52
+ </lst>
53
+ </requestHandler>
54
+
55
+ <requestHandler name="/get" class="solr.RealTimeGetHandler">
56
+ <lst name="defaults">
57
+ <str name="omitHeader">true</str>
58
+ <str name="wt">json</str>
59
+ <str name="indent">true</str>
60
+ </lst>
61
+ </requestHandler>
62
+
63
+ <requestHandler name="/replication" class="solr.ReplicationHandler" startup="lazy" />
64
+
65
+ <requestDispatcher handleSelect="true" >
66
+ <requestParsers enableRemoteStreaming="true" multipartUploadLimitInKB="2048" />
67
+ </requestDispatcher>
68
+
69
+ <requestHandler name="/analysis/field" startup="lazy" class="solr.FieldAnalysisRequestHandler" />
70
+ <requestHandler name="/update" class="solr.UpdateRequestHandler" />
71
+ <requestHandler name="/admin/" class="org.apache.solr.handler.admin.AdminHandlers" />
72
+
73
+ <requestHandler name="/admin/ping" class="solr.PingRequestHandler">
74
+ <lst name="invariants">
75
+ <str name="q">solrpingquery</str>
76
+ </lst>
77
+ <lst name="defaults">
78
+ <str name="echoParams">all</str>
79
+ </lst>
80
+ </requestHandler>
81
+
82
+ <!-- config for the admin interface -->
83
+ <admin>
84
+ <defaultQuery>search</defaultQuery>
85
+ </admin>
86
+
87
+ </config>
@@ -0,0 +1,83 @@
1
+ ENV["RAILS_ENV"] ||= 'test'
2
+
3
+ require 'factory_girl'
4
+ require 'database_cleaner'
5
+ require 'devise'
6
+ require 'engine_cart'
7
+ EngineCart.load_application!
8
+
9
+ require 'rspec/rails'
10
+
11
+ require 'capybara/poltergeist'
12
+
13
+ if ENV["POLTERGEIST_DEBUG"]
14
+ Capybara.register_driver :poltergeist_debug do |app|
15
+ Capybara::Poltergeist::Driver.new(app, inspector: true, phantomjs_options: ['--load-images=no'])
16
+ end
17
+ Capybara.javascript_driver = :poltergeist_debug
18
+ else
19
+ Capybara.register_driver :poltergeist do |app|
20
+ Capybara::Poltergeist::Driver.new(app, phantomjs_options: ['--load-images=no'])
21
+ end
22
+ Capybara.javascript_driver = :poltergeist
23
+ end
24
+ Capybara.default_wait_time = 10
25
+
26
+ require 'spotlight/atom/resources'
27
+
28
+
29
+ Dir["./spec/support/**/*.rb"].sort.each {|f| require f}
30
+
31
+ FactoryGirl.definition_file_paths = [File.expand_path("../factories", __FILE__)]
32
+ FactoryGirl.find_definitions
33
+
34
+ FIXTURES_PATH = File.expand_path("../fixtures", __FILE__);
35
+
36
+
37
+ RSpec.configure do |config|
38
+ config.infer_spec_type_from_file_location!
39
+
40
+ config.use_transactional_fixtures = false
41
+
42
+ config.before :each do
43
+ if Capybara.current_driver == :rack_test
44
+ DatabaseCleaner.strategy = :transaction
45
+ else
46
+ DatabaseCleaner.strategy = :truncation
47
+ end
48
+ DatabaseCleaner.start
49
+
50
+ # The first user is automatically granted admin privileges; we don't want that behavior for many of our tests
51
+ User.create email: 'initial+admin@example.com', password: 'password', password_confirmation: 'password'
52
+ end
53
+
54
+ config.after do
55
+ DatabaseCleaner.clean
56
+ end
57
+
58
+ if ENV['CI']
59
+ config.filter_run_excluding js: true
60
+ end
61
+
62
+ config.include Devise::TestHelpers, type: :controller
63
+ config.include Devise::TestHelpers, type: :view
64
+ config.include Spotlight::TestViewHelpers, type: :view
65
+ config.include Warden::Test::Helpers, type: :feature
66
+ config.after(:each, type: :feature) { Warden.test_reset! }
67
+ config.include Controllers::EngineHelpers, type: :controller
68
+ config.include Capybara::DSL
69
+ config.include Spotlight::TestFeaturesHelpers, type: :feature
70
+ end
71
+
72
+ def add_new_page_via_button(title="New Page")
73
+ add_link = find("[data-expanded-add-button]")
74
+ within(add_link) do
75
+ expect(page).to have_css("input[type='text']", visible: false)
76
+ end
77
+ add_link.hover
78
+ within(add_link) do
79
+ input = find("input[type='text']", visible: true)
80
+ input.set(title)
81
+ find("input[data-behavior='save']").click
82
+ end
83
+ end
@@ -0,0 +1 @@
1
+ gem "sir_trevor_rails", github: "sul-dlss/sir-trevor-rails"
@@ -0,0 +1,6 @@
1
+ if Rails.env.test? or Rails.env.cucumber?
2
+ CarrierWave.configure do |config|
3
+ config.storage = :file
4
+ config.enable_processing = false
5
+ end
6
+ end
@@ -0,0 +1,30 @@
1
+ require 'rails/generators'
2
+
3
+ class TestAppGenerator < Rails::Generators::Base
4
+ source_root "../../spec/test_app_templates"
5
+
6
+ def add_gems
7
+ gem 'blacklight', ">= 5.4.0.rc1", "<6"
8
+ gem "blacklight-gallery", ">= 0.3.0"
9
+ gem "sir_trevor_rails", github: "sul-dlss/sir-trevor-rails"
10
+ gem "blacklight-spotlight", github: "sul-dlss/spotlight"
11
+ gem "jettywrapper"
12
+ Bundler.with_clean_env do
13
+ run "bundle install"
14
+ end
15
+ end
16
+
17
+ def run_blacklight_generator
18
+ generate 'blacklight:install', '--devise'
19
+ end
20
+
21
+ def add_spotlight_routes_and_assets
22
+ generate 'spotlight:install', '-f --mailer_default_url_host=localhost:3000'
23
+ end
24
+
25
+ def run_spotlight_migrations
26
+ rake "spotlight:install:migrations"
27
+ rake "db:migrate"
28
+ end
29
+
30
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'spotlight/atom/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "spotlight-atom"
8
+ spec.version = Spotlight::Atom::VERSION
9
+ spec.authors = ["Chris Beer", "Jessie Keck"]
10
+ spec.email = ["chris@cbeer.info", "jkeck@stanford.edu"]
11
+ spec.summary = %q{Harvesting atom feeds into Spotlight}
12
+ spec.homepage = ""
13
+ spec.license = "Apache 2"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency "blacklight-spotlight"
21
+ spec.add_dependency "faraday"
22
+
23
+ spec.add_development_dependency "sqlite3"
24
+ spec.add_development_dependency "rspec-rails", "~> 3.1"
25
+ spec.add_development_dependency "capybara"
26
+ spec.add_development_dependency "poltergeist", ">= 1.5.0"
27
+ spec.add_development_dependency "bundler", "~> 1.7"
28
+ spec.add_development_dependency "rake", "~> 10.0"
29
+ spec.add_development_dependency "engine_cart"
30
+ spec.add_development_dependency "jettywrapper"
31
+ end
metadata ADDED
@@ -0,0 +1,212 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spotlight-atom
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Chris Beer
8
+ - Jessie Keck
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-03-31 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: blacklight-spotlight
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: faraday
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: sqlite3
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rspec-rails
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '3.1'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '3.1'
70
+ - !ruby/object:Gem::Dependency
71
+ name: capybara
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: poltergeist
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 1.5.0
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: 1.5.0
98
+ - !ruby/object:Gem::Dependency
99
+ name: bundler
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '1.7'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '1.7'
112
+ - !ruby/object:Gem::Dependency
113
+ name: rake
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - "~>"
117
+ - !ruby/object:Gem::Version
118
+ version: '10.0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - "~>"
124
+ - !ruby/object:Gem::Version
125
+ version: '10.0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: engine_cart
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ - !ruby/object:Gem::Dependency
141
+ name: jettywrapper
142
+ requirement: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ type: :development
148
+ prerelease: false
149
+ version_requirements: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ description:
155
+ email:
156
+ - chris@cbeer.info
157
+ - jkeck@stanford.edu
158
+ executables: []
159
+ extensions: []
160
+ extra_rdoc_files: []
161
+ files:
162
+ - ".gitignore"
163
+ - ".travis.yml"
164
+ - Gemfile
165
+ - README.md
166
+ - Rakefile
167
+ - app/models/spotlight/resources/atom_harvester.rb
168
+ - app/models/spotlight/resources/blacklight_harvester.rb
169
+ - app/models/spotlight/resources/omeka_harvester.rb
170
+ - app/views/spotlight/resources/atom/_blacklight.html.erb
171
+ - app/views/spotlight/resources/atom/_omeka.html.erb
172
+ - app/views/spotlight/resources/atom/_tabbed_form.html.erb
173
+ - config/locales/spotlight-atom-resources.en.yml
174
+ - lib/spotlight/atom.rb
175
+ - lib/spotlight/atom/engine.rb
176
+ - lib/spotlight/atom/version.rb
177
+ - solr_conf/conf/schema.xml
178
+ - solr_conf/conf/solrconfig.xml
179
+ - spec/spec_helper.rb
180
+ - spec/test_app_templates/Gemfile.extra
181
+ - spec/test_app_templates/carrierwave.rb
182
+ - spec/test_app_templates/lib/generators/test_app_generator.rb
183
+ - spotlight-atom.gemspec
184
+ homepage: ''
185
+ licenses:
186
+ - Apache 2
187
+ metadata: {}
188
+ post_install_message:
189
+ rdoc_options: []
190
+ require_paths:
191
+ - lib
192
+ required_ruby_version: !ruby/object:Gem::Requirement
193
+ requirements:
194
+ - - ">="
195
+ - !ruby/object:Gem::Version
196
+ version: '0'
197
+ required_rubygems_version: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ requirements: []
203
+ rubyforge_project:
204
+ rubygems_version: 2.4.5
205
+ signing_key:
206
+ specification_version: 4
207
+ summary: Harvesting atom feeds into Spotlight
208
+ test_files:
209
+ - spec/spec_helper.rb
210
+ - spec/test_app_templates/Gemfile.extra
211
+ - spec/test_app_templates/carrierwave.rb
212
+ - spec/test_app_templates/lib/generators/test_app_generator.rb