quick_search-core 0.0.1.test

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +168 -0
  4. data/Rakefile +6 -0
  5. data/app/assets/images/quick_search/askus.gif +0 -0
  6. data/app/assets/images/quick_search/favicon.ico +0 -0
  7. data/app/assets/images/quick_search/greybox.png +0 -0
  8. data/app/assets/images/quick_search/homescreen-icon-64x64.png +0 -0
  9. data/app/assets/images/quick_search/ncsu-library-logo-white.png +0 -0
  10. data/app/assets/javascripts/quick_search/appstats.js +8 -0
  11. data/app/assets/javascripts/quick_search/event_tracking.js.erb +257 -0
  12. data/app/assets/javascripts/quick_search/google_analytics.js.erb +8 -0
  13. data/app/assets/javascripts/quick_search/opensearch.js +2 -0
  14. data/app/assets/javascripts/quick_search/pages.js.coffee +3 -0
  15. data/app/assets/javascripts/quick_search/quicksearch.js +33 -0
  16. data/app/assets/javascripts/quick_search/realtime.js.erb +12 -0
  17. data/app/assets/javascripts/quick_search/search.js +3 -0
  18. data/app/assets/javascripts/quick_search/xhr_search.js +82 -0
  19. data/app/assets/javascripts/quick_search.js.erb +20 -0
  20. data/app/assets/stylesheets/foundation_and_overrides.scss +1327 -0
  21. data/app/assets/stylesheets/quick_search/appstats.css.scss +7 -0
  22. data/app/assets/stylesheets/quick_search/opensearch.css.scss +3 -0
  23. data/app/assets/stylesheets/quick_search/pages.css.scss +3 -0
  24. data/app/assets/stylesheets/quick_search/quick_search.css.scss +248 -0
  25. data/app/assets/stylesheets/quick_search/search.css.scss +3 -0
  26. data/app/assets/stylesheets/quick_search.css.scss.erb +7 -0
  27. data/app/controllers/concerns/quick_search/auth.rb +22 -0
  28. data/app/controllers/concerns/quick_search/doi_trap.rb +43 -0
  29. data/app/controllers/concerns/quick_search/encode_utf8.rb +12 -0
  30. data/app/controllers/concerns/quick_search/on_campus.rb +43 -0
  31. data/app/controllers/concerns/quick_search/query_filter.rb +25 -0
  32. data/app/controllers/concerns/quick_search/query_parser.rb +54 -0
  33. data/app/controllers/concerns/quick_search/searcher_concern.rb +101 -0
  34. data/app/controllers/concerns/quick_search/searcher_config.rb +16 -0
  35. data/app/controllers/quick_search/application_controller.rb +7 -0
  36. data/app/controllers/quick_search/appstats_controller.rb +210 -0
  37. data/app/controllers/quick_search/opensearch_controller.rb +9 -0
  38. data/app/controllers/quick_search/pages_controller.rb +18 -0
  39. data/app/controllers/quick_search/search_controller.rb +250 -0
  40. data/app/helpers/quick_search/application_helper.rb +68 -0
  41. data/app/helpers/quick_search/appstats_helper.rb +2 -0
  42. data/app/helpers/quick_search/opensearch_helper.rb +2 -0
  43. data/app/helpers/quick_search/pages_helper.rb +2 -0
  44. data/app/helpers/quick_search/search_helper.rb +2 -0
  45. data/app/models/event.rb +2 -0
  46. data/app/models/search.rb +11 -0
  47. data/app/searchers/quick_search/best_bets_searcher.rb +102 -0
  48. data/app/searchers/quick_search/searcher.rb +43 -0
  49. data/app/views/layouts/quick_search/_best_bets.html.erb +18 -0
  50. data/app/views/layouts/quick_search/_common_searches.html.erb +15 -0
  51. data/app/views/layouts/quick_search/_found_types.html.erb +13 -0
  52. data/app/views/layouts/quick_search/_google_analytics.html.erb +24 -0
  53. data/app/views/layouts/quick_search/_more_options.html.erb +10 -0
  54. data/app/views/layouts/quick_search/_page_title.html.erb +8 -0
  55. data/app/views/layouts/quick_search/_related_topics.html.erb +8 -0
  56. data/app/views/layouts/quick_search/_search_form.html.erb +19 -0
  57. data/app/views/layouts/quick_search/_spelling_suggestion.html.erb +13 -0
  58. data/app/views/layouts/quick_search/_topic_snippet.html.erb +5 -0
  59. data/app/views/layouts/quick_search/application.html.erb +40 -0
  60. data/app/views/quick_search/appstats/_click_count_table.html.erb +23 -0
  61. data/app/views/quick_search/appstats/_datatables.html.erb +12 -0
  62. data/app/views/quick_search/appstats/_date_range.html.erb +15 -0
  63. data/app/views/quick_search/appstats/_menu.html.erb +16 -0
  64. data/app/views/quick_search/appstats/_top_spot_report_table.html.erb +33 -0
  65. data/app/views/quick_search/appstats/clicks_overview.html.erb +20 -0
  66. data/app/views/quick_search/appstats/index.html.erb +31 -0
  67. data/app/views/quick_search/appstats/module_click_detail.html.erb +32 -0
  68. data/app/views/quick_search/appstats/realtime.html.erb +15 -0
  69. data/app/views/quick_search/appstats/top_searches.html.erb +38 -0
  70. data/app/views/quick_search/appstats/top_spot.html.erb +14 -0
  71. data/app/views/quick_search/appstats/top_spot_detail.html.erb +35 -0
  72. data/app/views/quick_search/kaminari/_first_page.html.erb +12 -0
  73. data/app/views/quick_search/kaminari/_gap.html.erb +11 -0
  74. data/app/views/quick_search/kaminari/_last_page.html.erb +12 -0
  75. data/app/views/quick_search/kaminari/_next_page.html.erb +12 -0
  76. data/app/views/quick_search/kaminari/_page.html.erb +13 -0
  77. data/app/views/quick_search/kaminari/_paginator.html.erb +25 -0
  78. data/app/views/quick_search/kaminari/_prev_page.html.erb +11 -0
  79. data/app/views/quick_search/opensearch/opensearch.xml.builder +11 -0
  80. data/app/views/quick_search/pages/about.html.erb +9 -0
  81. data/app/views/quick_search/pages/home.html.erb +6 -0
  82. data/app/views/quick_search/pages/realtime.html.erb +15 -0
  83. data/app/views/quick_search/search/_citation.html.erb +18 -0
  84. data/app/views/quick_search/search/_module.html.erb +37 -0
  85. data/app/views/quick_search/search/_module_with_paging.html.erb +14 -0
  86. data/app/views/quick_search/search/_no_results.html.erb +11 -0
  87. data/app/views/quick_search/search/_result.html.erb +17 -0
  88. data/app/views/quick_search/search/_result_details.html.erb +45 -0
  89. data/app/views/quick_search/search/_result_no_thumbnail.html.erb +3 -0
  90. data/app/views/quick_search/search/_result_title.html.erb +4 -0
  91. data/app/views/quick_search/search/_result_with_thumbnail.html.erb +21 -0
  92. data/app/views/quick_search/search/_search_error.html.erb +9 -0
  93. data/app/views/quick_search/search/_see_all.html.erb +11 -0
  94. data/app/views/quick_search/search/_xhr_response.html.erb +15 -0
  95. data/app/views/quick_search/search/_xhr_response.json.erb +14 -0
  96. data/app/views/quick_search/search/_xhr_response_with_paging.html.erb +1 -0
  97. data/app/views/quick_search/search/index.html.erb +100 -0
  98. data/config/application.rb +25 -0
  99. data/config/best_bets.yml +86 -0
  100. data/config/boot.rb +4 -0
  101. data/config/database.yml.example +31 -0
  102. data/config/locales/en.yml +30 -0
  103. data/config/quicksearch_config.yml.example +69 -0
  104. data/config/routes.rb +81 -0
  105. data/db/migrate/20140130202859_create_events.rb +11 -0
  106. data/db/migrate/20140130202944_create_searches.rb +9 -0
  107. data/db/migrate/20140225145441_add_page_to_searches.rb +5 -0
  108. data/db/schema.rb +31 -0
  109. data/db/seeds.rb +7 -0
  110. data/lib/benchmark_logger.rb +2 -0
  111. data/lib/capistrano/tasks/access_check.cap +10 -0
  112. data/lib/generators/quick_search/install_generator.rb +49 -0
  113. data/lib/generators/quick_search/templates/kaminari.rb +5 -0
  114. data/lib/generators/quick_search/templates/post_install.txt +8 -0
  115. data/lib/generators/quick_search/templates/quick_search_config.yml +58 -0
  116. data/lib/quick_search/engine.rb +16 -0
  117. data/lib/quick_search/version.rb +3 -0
  118. data/lib/quick_search.rb +12 -0
  119. data/lib/tasks/best_bets.rake +29 -0
  120. data/test/controllers/appstats_controller_test.rb +7 -0
  121. data/test/controllers/concerns/doi_trap_test.rb +19 -0
  122. data/test/controllers/concerns/on_campus_test.rb +19 -0
  123. data/test/controllers/concerns/query_parser_test.rb +47 -0
  124. data/test/controllers/opensearch_controller_test.rb +13 -0
  125. data/test/controllers/pages_controller_test.rb +7 -0
  126. data/test/controllers/search_controller_test.rb +15 -0
  127. data/test/fixtures/events.yml +11 -0
  128. data/test/fixtures/searches.yml +7 -0
  129. data/test/helpers/appstats_helper_test.rb +4 -0
  130. data/test/helpers/opensearch_helper_test.rb +4 -0
  131. data/test/helpers/pages_helper_test.rb +4 -0
  132. data/test/helpers/search_helper_test.rb +4 -0
  133. data/test/integration/catalog_search_test.rb +8 -0
  134. data/test/integration/google_analytics_test.rb +23 -0
  135. data/test/integration/landing_page_test.rb +8 -0
  136. data/test/integration/searching_test.rb +40 -0
  137. data/test/integration/smart_subjects_test.rb +8 -0
  138. data/test/integration/website_search_test.rb +8 -0
  139. data/test/models/event_test.rb +7 -0
  140. data/test/models/search_test.rb +7 -0
  141. data/test/searcher/best_bets_test.rb +35 -0
  142. data/test/searcher/catalog_test.rb +35 -0
  143. data/test/searcher/ematrix_database_test.rb +27 -0
  144. data/test/searcher/ematrix_journal_test.rb +27 -0
  145. data/test/searcher/faq_test.rb +27 -0
  146. data/test/searcher/smart_subjects_test.rb +27 -0
  147. data/test/searcher/summon_test.rb +13 -0
  148. data/test/searcher/website_test.rb +34 -0
  149. data/test/support/vcr_test.rb +40 -0
  150. data/test/test_helper.rb +42 -0
  151. metadata +366 -0
@@ -0,0 +1,7 @@
1
+ // Place all the styles related to the Appstats controller here.
2
+ // They will automatically be included in application.css.
3
+ // You can use Sass (SCSS) here: http://sass-lang.com/
4
+
5
+ #appstats-date-filter {
6
+ display: none;
7
+ }
@@ -0,0 +1,3 @@
1
+ // Place all the styles related to the opensearch controller here.
2
+ // They will automatically be included in application.css.
3
+ // You can use Sass (SCSS) here: http://sass-lang.com/
@@ -0,0 +1,3 @@
1
+ // Place all the styles related to the pages controller here.
2
+ // They will automatically be included in application.css.
3
+ // You can use Sass (SCSS) here: http://sass-lang.com/
@@ -0,0 +1,248 @@
1
+ @mixin text-badge {
2
+ padding: 1px 5px 2px 5px;
3
+ border-radius: 2px;
4
+ color: #FFF;
5
+ }
6
+
7
+ //element overrides
8
+ #content {
9
+ #main-content {
10
+ #quicksearch {
11
+
12
+ .twitter-typeahead {
13
+ width: 100%;
14
+
15
+ img {
16
+ max-width: 79.578125px;
17
+ }
18
+ .space-container {
19
+ max-width: 438.3125px;
20
+ }
21
+
22
+ .bestbet-container {
23
+ padding: 0;
24
+ }
25
+
26
+ }
27
+
28
+ h3 {
29
+ padding-top: 0;
30
+ font-weight: normal;
31
+ }
32
+
33
+ ol, ul {
34
+ margin-left: 0;
35
+ }
36
+
37
+ li {
38
+ list-style-type: none;
39
+ }
40
+
41
+ em {
42
+ font-style: normal;
43
+ font-weight: bold;
44
+ }
45
+
46
+ #website {
47
+ margin-bottom: 2.5em;
48
+ }
49
+
50
+ // class overrides
51
+
52
+ .prefix.button {
53
+ height: 2.3rem
54
+ }
55
+
56
+ @media only screen and (max-width: 766px) {
57
+ .prefix.button {
58
+ height: 2.76rem
59
+ }
60
+ }
61
+
62
+ input[type="text"] {
63
+ -webkit-appearance: none;
64
+ border-radius: 0;
65
+ font-size: 1rem;
66
+ }
67
+
68
+ input[type="search"] {
69
+ margin: 0;
70
+ }
71
+
72
+ // custom classes
73
+
74
+ .about {
75
+ float: right;
76
+ }
77
+
78
+ .result-types {
79
+ margin: 10px 0 0 0;
80
+ li {
81
+ margin: 0 20px 0 0;
82
+ }
83
+ }
84
+
85
+ .trying_again {
86
+ padding-bottom: 20px;
87
+ }
88
+
89
+ .clear-search-box {
90
+ display: none;
91
+ }
92
+
93
+ .title {
94
+ font-size: 1.25em;
95
+ margin-bottom:0;
96
+ margin-top: 1em;
97
+ }
98
+
99
+ .result {
100
+ p {
101
+ margin-bottom: 0;
102
+ }
103
+ }
104
+
105
+ .see-all-results {
106
+ margin-bottom: 2.5em;
107
+ margin-top: 2em;
108
+ font-weight: bold;
109
+ }
110
+
111
+ .search-error-message {
112
+ margin-top: 1em
113
+ }
114
+
115
+ .with-thumbnail {
116
+ margin-bottom: 0.9em;
117
+ }
118
+
119
+ .no-thumbnail {
120
+ margin-bottom: 0.9em;
121
+ }
122
+
123
+ .link {
124
+ display: none;
125
+ word-break: break-word;
126
+ }
127
+
128
+ .query {
129
+ font-weight: bold;
130
+ word-break: break-word;
131
+ }
132
+
133
+ .display-link {
134
+ word-break: break-all;
135
+ }
136
+
137
+ .highlight {
138
+ @include text-badge;
139
+ background: #edb802;
140
+ @media only screen and (max-width: 640px) {
141
+ display: none;
142
+ }
143
+ }
144
+
145
+ .result-types-highlight {
146
+ @media only screen and (max-width: 640px) {
147
+ display: none;
148
+ }
149
+ }
150
+
151
+ .available {
152
+ color: #090;
153
+ }
154
+
155
+ .unavailable {
156
+ color: #C00;
157
+ }
158
+
159
+ .section-description {
160
+ text-transform: none;
161
+ margin-top: 1em;
162
+ }
163
+
164
+ .side-bar {
165
+ span.total {
166
+ display: none;
167
+ }
168
+ }
169
+
170
+ .thumbnail {
171
+ border: 1px solid #555555;
172
+ }
173
+
174
+ .citation {
175
+ .publisher {
176
+ font-style: italic;
177
+ }
178
+ }
179
+
180
+ .date {
181
+ font-weight: normal;
182
+ }
183
+
184
+ .search-error-rescue {
185
+ display: none;
186
+ }
187
+
188
+ .website {
189
+ .link {
190
+ display: block;
191
+ color: #006621;
192
+ }
193
+ }
194
+
195
+ .summon {
196
+ .description {
197
+ display: none;
198
+ }
199
+ }
200
+
201
+
202
+ .faq {
203
+ .total {
204
+ display: none;
205
+ }
206
+ }
207
+
208
+
209
+ .related-topics {
210
+ ul {
211
+ column-count: 2;
212
+ -moz-column-count: 2; /* Firefox */
213
+ -webkit-column-count: 2; /* Safari and Chrome */
214
+ }
215
+ }
216
+
217
+ .journals-databases, .faq {
218
+ h3 {
219
+ font-size: 1.1em;
220
+ }
221
+ li {
222
+ margin-bottom: 0;
223
+ }
224
+ }
225
+
226
+ .appstats-show {
227
+ .total {
228
+ font-weight: bold;
229
+ }
230
+ }
231
+ }
232
+ }
233
+ }
234
+
235
+
236
+ // hide google analytics debug
237
+
238
+ #quicksearch-ga-debug {
239
+ display: none;
240
+ }
241
+
242
+ // .hidden {
243
+ // display: none;
244
+ // }
245
+
246
+ .feedback-form {
247
+ display: none;
248
+ }
@@ -0,0 +1,3 @@
1
+ // Place all the styles related to the search controller here.
2
+ // They will automatically be included in application.css.
3
+ // You can use Sass (SCSS) here: http://sass-lang.com/
@@ -0,0 +1,7 @@
1
+ @import "<%= QuickSearch::Engine::APP_CONFIG['theme'] %>";
2
+ @import "quick_search/quick_search";
3
+ @import "quick_search/pages";
4
+ @import "quick_search/search";
5
+ @import "quick_search/appstats";
6
+ // @import "typeahead";
7
+ //
@@ -0,0 +1,22 @@
1
+ require "digest/md5"
2
+
3
+ module QuickSearch::Auth
4
+ extend ActiveSupport::Concern
5
+
6
+ SALT01 = SecureRandom.hex(512)
7
+ SALT02 = SecureRandom.hex(512)
8
+ REALM = "Please enter the username and password to access this page"
9
+ USERS = {"#{QuickSearch::Engine::APP_CONFIG['user']}" => Digest::MD5.hexdigest(["#{QuickSearch::Engine::APP_CONFIG['user']}",REALM,"#{QuickSearch::Engine::APP_CONFIG['password']}"].join(":"))}
10
+ SALTY = SALT01 + Digest::MD5.hexdigest(["#{QuickSearch::Engine::APP_CONFIG['user']}",REALM,"#{QuickSearch::Engine::APP_CONFIG['password']}"].join(":")) + SALT02
11
+
12
+ def auth
13
+ authenticate_or_request_with_http_digest(REALM) do |username|
14
+ unless SALT01.blank? or SALT02.blank? or USERS[username].blank?
15
+ if SALT01 + USERS[username] + SALT02 == SALTY
16
+ USERS[username]
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ end
@@ -0,0 +1,43 @@
1
+ module QuickSearch::DoiTrap
2
+ extend ActiveSupport::Concern
3
+
4
+ include QuickSearch::EncodeUtf8
5
+
6
+ private
7
+
8
+ def doi_trap
9
+ unless params_q_scrubbed.nil?
10
+ if is_a_doi?(doi_query)
11
+ Event.create(category: 'doi-trap', action: doi_query, label: '')
12
+ redirect_to doi_loaded_link
13
+ # Alternately insert a loaded link into the results interface
14
+ # @doi_loaded_link = loaded_link
15
+ # @doi_callout = "Searching for a DOI? Try this: "
16
+ end
17
+ end
18
+ end
19
+
20
+ def is_a_doi?(query)
21
+ if doi_regex.match(query)
22
+ true
23
+ else
24
+ false
25
+ end
26
+ end
27
+
28
+ def doi_regex
29
+ /^(?:(?:doi:?\s*|(?:http:\/\/)?(?:dx\.)?(?:doi\.org)?\/))?(10(?:\.\d+){1,2}\/\S+)$/i
30
+ end
31
+
32
+ def doi_loaded_link
33
+ QuickSearch::Engine::APP_CONFIG['doi_loaded_link'] + CGI.escape(doi_regex.match(doi_query)[1])
34
+ end
35
+
36
+ def doi_query
37
+ query = params_q_scrubbed
38
+ query.strip!
39
+ query.squish!
40
+ query
41
+ end
42
+
43
+ end
@@ -0,0 +1,12 @@
1
+ module QuickSearch::EncodeUtf8
2
+ extend ActiveSupport::Concern
3
+
4
+ private
5
+
6
+ def params_q_scrubbed
7
+ unless params[:q].nil?
8
+ params[:q].scrub
9
+ end
10
+ end
11
+
12
+ end
@@ -0,0 +1,43 @@
1
+ module QuickSearch::OnCampus
2
+ extend ActiveSupport::Concern
3
+
4
+ private
5
+
6
+ # Search for "Nucleation and growth mechanism of ferroelectric domain wall motion"
7
+ # To test this. Result should not show up in Summon results off campus.
8
+
9
+ ### WHY THIS IS HERE ###
10
+ # There is a subset of Summon results that cannot be shown unless a person is
11
+ # on campus or authenticated. So that we can show all results to people
12
+ # searching QuickSearch from on campus we're checking IP addresses. If the IP is a
13
+ # known campus IP we set the s.role=authenticated parameter in the Summon API request.
14
+
15
+ def ip
16
+ request.env['HTTP_X_FORWARDED_FOR'] || request.remote_ip
17
+ end
18
+
19
+ def on_campus?(ip)
20
+ ip = remote_ip(ip)
21
+ ip_range_check(ip)
22
+ end
23
+
24
+ # To spoof ON and OFF campus for development
25
+ def remote_ip(ip)
26
+ if ip == '127.0.0.1'
27
+ '204.84.244.1' #On Campus
28
+ #'127.0.0.1' #Off Campus
29
+ else
30
+ ip
31
+ end
32
+ end
33
+
34
+ def ip_range_check(ip)
35
+ QuickSearch::Engine::APP_CONFIG['on_campus'].each do |on_campus_ip_regex|
36
+ if on_campus_ip_regex === ip
37
+ return true
38
+ end
39
+ end
40
+
41
+ return false
42
+ end
43
+ end
@@ -0,0 +1,25 @@
1
+ module QuickSearch::QueryFilter
2
+ extend ActiveSupport::Concern
3
+
4
+ include ActionView::Helpers::TextHelper
5
+
6
+ private
7
+
8
+ def filter_query(query)
9
+ if query.match(/ -$/)
10
+ query = query.sub(/ -$/,"")
11
+ end
12
+ query.gsub!('*', ' ')
13
+ query.gsub!('!', ' ')
14
+ query.gsub!('-', ' ') # Solr returns an error if multiple dashes appear at start of query string
15
+ query.gsub!('\\', '')
16
+ # query.gsub!('"', '')
17
+ query.strip!
18
+ query.squish!
19
+ query.downcase! # FIXME: Do we really want to downcase everything?
20
+ query = truncate(query, length: 100, separator: ' ', omission: '', escape: false)
21
+
22
+ query
23
+ end
24
+
25
+ end
@@ -0,0 +1,54 @@
1
+ module QuickSearch::QueryParser
2
+ extend ActiveSupport::Concern
3
+
4
+ private
5
+
6
+ def extracted_query(unfiltered_query)
7
+ @unfiltered_query = unfiltered_query
8
+ if extracted_query_and_scope
9
+ query = extracted_query_and_scope[:query]
10
+ else
11
+ query = unfiltered_query
12
+ end
13
+ query
14
+ end
15
+
16
+ def extracted_scope(unfiltered_query)
17
+ @unfiltered_query = unfiltered_query
18
+ if extracted_query_and_scope
19
+ scope = extracted_query_and_scope[:value]
20
+ else
21
+ scope = ''
22
+ end
23
+ end
24
+
25
+ def extracted_query_and_scope
26
+ if regex_matches = prefix_scope_multi_regex.match(@unfiltered_query)
27
+ regex_matches
28
+ elsif regex_matches = suffix_scope_multi_regex.match(@unfiltered_query)
29
+ regex_matches
30
+ elsif regex_matches = prefix_scope_regex.match(@unfiltered_query)
31
+ regex_matches
32
+ elsif regex_matches = suffix_scope_regex.match(@unfiltered_query)
33
+ regex_matches
34
+ end
35
+ regex_matches
36
+ end
37
+
38
+ def prefix_scope_regex
39
+ /^(?<option>scope):(?<value>\S+)\s?(?<query>.*)$/
40
+ end
41
+
42
+ def prefix_scope_multi_regex
43
+ /^(?<option>scope):\((?<value>.*?)\)\s?(?<query>.*)$/
44
+ end
45
+
46
+ def suffix_scope_regex
47
+ /(?<query>.*)\s(?<option>scope):(?<value>\S+)/
48
+ end
49
+
50
+ def suffix_scope_multi_regex
51
+ /^(?<query>.*)\s(?<option>scope):\((?<value>.*)\)$/
52
+ end
53
+
54
+ end
@@ -0,0 +1,101 @@
1
+ module QuickSearch::SearcherConcern
2
+ extend ActiveSupport::Concern
3
+
4
+ include QuickSearch::OnCampus
5
+ include QuickSearch::QueryParser
6
+ include QuickSearch::EncodeUtf8
7
+ include QuickSearch::SearcherConfig
8
+ require 'benchmark_logger'
9
+
10
+ private
11
+
12
+ def search_all_in_threads(primary_searcher = 'defaults')
13
+ benchmark "%s server ALL" % CGI.escape(query.to_str) do
14
+ search_threads = []
15
+ @found_types = [] # add the types that are found to a navigation bar
16
+
17
+ primary_searcher_config = ''
18
+
19
+ if primary_searcher == 'defaults'
20
+ searchers = QuickSearch::Engine::APP_CONFIG['searchers']
21
+ else
22
+ searcher_config = searcher_config(primary_searcher)
23
+ if searcher_config and searcher_config.has_key? 'with_paging'
24
+ searchers = searcher_config['with_paging']['searchers']
25
+ else
26
+ searchers = [primary_searcher]
27
+ end
28
+ end
29
+
30
+ searchers.shuffle.each do |search_method|
31
+ search_threads << Thread.new(search_method) do |sm|
32
+ benchmark "%s server #{sm}" % CGI.escape(query.to_str) do
33
+ begin
34
+ klass = "QuickSearch::#{sm.camelize}Searcher".constantize
35
+ http_client = HTTPClient.new
36
+ update_searcher_timeout(http_client, search_method)
37
+ # FIXME: Probably want to set paging and offset somewhere else.
38
+ # searcher = klass.new(http_client, params_q_scrubbed, QuickSearch::Engine::APP_CONFIG['per_page'], 0, 1, on_campus?(request.remote_ip))
39
+ if sm == primary_searcher
40
+ if primary_searcher_config.has_key? 'with_paging'
41
+ per_page = primary_searcher_config['with_paging']['per_page']
42
+ else
43
+ per_page = 10
44
+ end
45
+ searcher = klass.new(http_client, query, per_page, offset(page, per_page), page, on_campus?(ip), scope)
46
+ else
47
+ searcher = klass.new(http_client, query, QuickSearch::Engine::APP_CONFIG['per_page'], 0, 1, on_campus?(ip), scope)
48
+ end
49
+ searcher.search
50
+ unless searcher.is_a? StandardError or searcher.results.blank?
51
+ @found_types.push(sm)
52
+ end
53
+ instance_variable_set "@#{sm}", searcher
54
+ rescue StandardError => e
55
+ # logger.info e
56
+ logger.info "FAILED SEARCH: #{sm} | #{params_q_scrubbed}"
57
+ instance_variable_set :"@#{sm.to_s}", e
58
+ end
59
+ end
60
+ end
61
+ end
62
+ search_threads.each {|t| t.join}
63
+ end
64
+ end
65
+
66
+
67
+ def page
68
+ if page_in_params?
69
+ page = params[:page].to_i
70
+ else
71
+ page = 1
72
+ end
73
+ page
74
+ end
75
+
76
+ def offset(page, per_page)
77
+ (page * per_page) - per_page
78
+ end
79
+
80
+ def query
81
+ extracted_query(params_q_scrubbed)
82
+ end
83
+
84
+ def scope
85
+ extracted_scope(params_q_scrubbed)
86
+ end
87
+
88
+ def update_searcher_timeout(client, search_method, xhr=false)
89
+ timeout_type = xhr ? 'xhr_http_timeout' : 'http_timeout'
90
+ timeout = QuickSearch::Engine::APP_CONFIG[timeout_type]
91
+
92
+ if QuickSearch::Engine::APP_CONFIG.has_key? search_method and QuickSearch::Engine::APP_CONFIG[search_method].has_key? timeout_type
93
+ timeout = QuickSearch::Engine::APP_CONFIG[search_method][timeout_type]
94
+ end
95
+
96
+ client.receive_timeout = timeout
97
+ client.send_timeout = timeout
98
+ client.connect_timeout = timeout
99
+ end
100
+
101
+ end
@@ -0,0 +1,16 @@
1
+ module QuickSearch::SearcherConfig
2
+ extend ActiveSupport::Concern
3
+
4
+ private
5
+
6
+ def searcher_config(searcher)
7
+ # Best Bets searcher is available in QuickSearch core, use app_config
8
+ if searcher == 'best_bets'
9
+ QuickSearch::Engine::APP_CONFIG['best_bets']
10
+ else
11
+ #TODO: test for the existence of this?
12
+ "QuickSearch::Engine::#{searcher.upcase}_CONFIG".constantize
13
+ end
14
+ end
15
+
16
+ end
@@ -0,0 +1,7 @@
1
+ module QuickSearch
2
+ class ApplicationController < ::ApplicationController
3
+ # Prevent CSRF attacks by raising an exception.
4
+ # For APIs, you may want to use :null_session instead.
5
+ protect_from_forgery with: :exception
6
+ end
7
+ end