birds 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6903ae4e8cfca9e4b0d8663336f1ad83ade93a95
4
- data.tar.gz: 284b6418f84970f9b9205a877f243fe8f7bdd9d2
3
+ metadata.gz: 7fe5c975045c5cd3f27f17496e5fe94c89517e2f
4
+ data.tar.gz: 125796780f21a82f7266294d4f3e64a4671b25e4
5
5
  SHA512:
6
- metadata.gz: 8662c707d852a14a8d970c3b829f34c0c2ffcc5e095a72cab3a6bd62af574ac3b2cab19497797df28fc519d6edd8f5e2423859dbe3702f0abfd2fa3e92ec9c0e
7
- data.tar.gz: 340986eb90f47f8a881d4295ecf4c1bc0dea99b478d3214a1100075b6216d7ba43b4dbecf82cb332a01fc7fa847f47694fa72e1bdd80647861e8232a5e9ce6e3
6
+ metadata.gz: 6036a21f6e4b8e32d5fec07ce207fddf108e942ca488e2e29690512af14c5447fbd310866170de79307f5ec8730435646f255880ab30db01b96ba5a9ab3ecde9
7
+ data.tar.gz: f6f880fc852613a626cb2cf8274ab5602bdc05fa03ee62599ce1dd1aa81113df646dfc42dd41066b98478cf3e152be1c6ab6ce6bca7a97c17858f2fd694c4102
data/ChangeLog CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  = Revision history for Birds
4
4
 
5
+ == 0.0.1 [2016-10-12]
6
+
7
+ * Initial release.
8
+
5
9
  == 0.0.0 [2014-03-19]
6
10
 
7
11
  * Birthday :-)
data/README CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  == VERSION
4
4
 
5
- This documentation refers to Birds version 0.0.0
5
+ This documentation refers to Birds version 0.0.1
6
6
 
7
7
 
8
8
  == DESCRIPTION
@@ -25,7 +25,7 @@ RubyGem:: https://rubygems.org/gems/birds
25
25
 
26
26
  == LICENSE AND COPYRIGHT
27
27
 
28
- Copyright (C) 2014-2015 Jens Wille
28
+ Copyright (C) 2014-2016 Jens Wille
29
29
 
30
30
  Birds is free software: you can redistribute it and/or modify it under the
31
31
  terms of the GNU Affero General Public License as published by the Free
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
- require File.expand_path(%q{../lib/birds/version}, __FILE__)
1
+ require_relative 'lib/birds/version'
2
2
 
3
3
  begin
4
4
  require 'hen'
@@ -15,8 +15,8 @@ begin
15
15
  homepage: :blackwinter,
16
16
  extra_files: FileList['*.sample', 'lib/**/{public,views}/*'].to_a,
17
17
  dependencies: {
18
- 'sinatra-bells' => ['~> 0.0', '>= 0.0.2'],
19
- 'solr4r' => ['~> 0.0', '>= 0.0.4'],
18
+ 'sinatra-bells' => '~> 0.4',
19
+ 'solr4r' => '~> 0.3',
20
20
  'unicode' => '~> 0.4'
21
21
  },
22
22
 
@@ -27,19 +27,23 @@ rescue LoadError => err
27
27
  warn "Please install the `hen' gem. (#{err})"
28
28
  end
29
29
 
30
- task c: :_ do
30
+ desc 'Run IRB console'
31
+ task console: :load do
31
32
  require 'irb'; IRB.start
32
33
  end
33
34
 
34
- task r: :_ do
35
+ desc 'Run rackup command'
36
+ task rackup: :load do
35
37
  load Gem.bin_path('rack', 'rackup')
36
38
  end
37
39
 
38
- task :_ do
40
+ task :load do
39
41
  ARGV.clear
40
42
 
41
- b = File.expand_path('~/devel') # XXX
42
- $:.unshift(*%w[birds solr4r sinatra-bells].map { |i| File.join(b, i, 'lib') })
43
+ b = ENV['DEVEL'] and %w[sinatra-bells solr4r].each { |i|
44
+ $:.unshift(File.join(File.expand_path(b), i, 'lib')) }
45
+
46
+ $:.unshift('lib')
43
47
 
44
48
  require 'birds'
45
49
  require 'birds/app'
@@ -5,7 +5,7 @@
5
5
  # #
6
6
  # Birds -- Bibliographic information retrieval & document search #
7
7
  # #
8
- # Copyright (C) 2014-2015 Jens Wille #
8
+ # Copyright (C) 2014-2016 Jens Wille #
9
9
  # #
10
10
  # Birds is free software: you can redistribute it and/or modify it under the #
11
11
  # terms of the GNU Affero General Public License as published by the Free #
@@ -28,8 +28,10 @@ require 'unicode'
28
28
  class Birds::App
29
29
 
30
30
  get '/', render: :index do
31
- result = settings.solr.count
32
- @page_title, @page_title_extra = 'Home', "#{result.to_i} documents"
31
+ @page_title, @page_title_extra = 'Home',
32
+ '%d documents' % count = settings.solr.count.to_i
33
+
34
+ @page_title_query = settings.solr_match_all_query if count > 0
33
35
  end
34
36
 
35
37
  get '/search', render: :index do
@@ -38,9 +40,14 @@ class Birds::App
38
40
  @query, @filter = params[:q] || params[:qq], Array(params[:fq])
39
41
 
40
42
  paginate_query(@query, :results,
41
- facet_params(debug: 'results', fq: @filter))
43
+ highlighting_params(facet_params(debug: 'results', fq: @filter)))
44
+
45
+ @explain = explain_result
46
+ @facets = facet_counts
47
+ @highlighting = highlighting
42
48
 
43
- @explain, @facets = explain_result(@result), facet_counts(@result)
49
+ @spellcheck = spellcheck_collations(
50
+ spell_query(@query, spellcheck_params(fq: @filter))).to_a
44
51
  end
45
52
 
46
53
  get '/browse', render: :browse do
@@ -100,16 +107,17 @@ class Birds::App
100
107
  bad_request if id.empty?
101
108
  not_found unless @document = search_document(id)
102
109
 
103
- @similar = @document.more_like_this(settings.mlt_fields,
104
- debugQuery: true, mlt: { boost: true, mintf: 1, minwl: 4 })
110
+ mlt_fields, @similar, @explain = settings.mlt_fields, {}, {}
111
+ mlt_fields = { nil => mlt_fields } unless mlt_fields.is_a?(Hash)
105
112
 
106
- @explain = explain_result(@similar)
113
+ mlt_fields.each { |key, fields|
114
+ mlt = @document.more_like_this(fields,
115
+ debug: 'results', mlt: { boost: true, mintf: 1, minwl: 4 })
107
116
 
108
- @page_title, @page_title_extra = 'Document', "##{id}"
109
- end
117
+ @similar[key], @explain[key] = mlt, explain_result(mlt) unless mlt.empty?
118
+ }
110
119
 
111
- get 'schema.xml' do
112
- erb :schema
120
+ @page_title, @page_title_extra = 'Document', "##{id}"
113
121
  end
114
122
 
115
123
  end
@@ -5,7 +5,7 @@
5
5
  # #
6
6
  # Birds -- Bibliographic information retrieval & document search #
7
7
  # #
8
- # Copyright (C) 2014-2015 Jens Wille #
8
+ # Copyright (C) 2014-2016 Jens Wille #
9
9
  # #
10
10
  # Birds is free software: you can redistribute it and/or modify it under the #
11
11
  # terms of the GNU Affero General Public License as published by the Free #
@@ -23,84 +23,128 @@
23
23
  ###############################################################################
24
24
  #++
25
25
 
26
- class Birds::App
26
+ class Birds
27
27
 
28
- module Helpers
28
+ class App
29
29
 
30
- module Controller
30
+ module Helpers
31
31
 
32
- def search(params)
33
- settings.solr.json_query(params)
34
- end
32
+ module Controller
35
33
 
36
- def search_query(query, params = {})
37
- search(params.merge(q: query, fl: '*,score', defType: 'edismax'))
38
- end
34
+ def solr_query(path, params = {}, options = {}, &block)
35
+ settings.solr.json_query(params, options, path, &block)
36
+ end
39
37
 
40
- def search_document(id)
41
- search(q: { id: id }).first
42
- end
38
+ def search(params)
39
+ solr_query(settings.solr_select_path, params)
40
+ end
43
41
 
44
- def paginate_query(query, what, query_params = {}, per_page = 20)
45
- return unless query
42
+ def spell_query(query, params = {})
43
+ solr_query(settings.solr_spell_path, params.merge(q: query))
44
+ end
46
45
 
47
- page = params[:page].to_i
48
- page = 1 if page < 1
46
+ def search_query(query, params = {})
47
+ search(params.merge(q: query, fl: '*,score', defType: 'edismax'))
48
+ end
49
49
 
50
- @prev_page, @next_page = page - 1, page + 1
50
+ def search_document(id)
51
+ search(q: { id: id }).first
52
+ end
51
53
 
52
- @result = search_query(query, query_params.merge(
53
- rows: per_page, start: @offset = @prev_page * per_page))
54
+ def paginate_query(query, what, query_params = {})
55
+ return unless query
54
56
 
55
- @page_title_extra = '%d %s, page %d of %d' % [
56
- @result, what, page, @total_pages = (@result.to_i / per_page.to_f).ceil]
57
+ page, per_page = clip(params[:page].to_i),
58
+ clip(Integer(params[:per_page] || settings.default_per_page))
57
59
 
58
- @prev_page = nil if @prev_page < 1
59
- @next_page = nil if @next_page > @total_pages
60
- end
60
+ @prev_page, @next_page = page - 1, page + 1
61
61
 
62
- def facet_params(params = {})
63
- params.merge(f: f = params[:f] || {}, facet: {
64
- field: fields = [], range: ranges = [], mincount: 1
65
- }).tap { settings.facet_fields.each { |facet, (_, options)|
66
- options.nil? ? fields << facet : begin ranges << facet
67
- ((f[facet] ||= {})[:facet] ||= {})[:range] = options
68
- end
69
- } }
70
- end
62
+ @result = search_query(query, query_params.merge(
63
+ rows: per_page, start: @offset = @prev_page * per_page))
71
64
 
72
- def terms(f = @field)
73
- settings.solr.json('terms', terms: { fl: f, limit: -1 }).to_h[f].sort
74
- end
65
+ @page_title_extra = '%d %s, page %d of %d' % [@result, what,
66
+ page, @total_pages = clip(@result.to_i.fdiv(per_page).ceil)]
75
67
 
76
- def explain_result(result)
77
- result % %w[debug explain] if result
78
- end
68
+ @prev_page = nil if @prev_page < 1
69
+ @next_page = nil if @next_page > @total_pages
70
+ end
71
+
72
+ def facet_params(params = {})
73
+ params.merge(f: f = params[:f] || {}, facet: {
74
+ field: fields = [], range: ranges = [], mincount: 1
75
+ }).tap { settings.facet_fields.each { |facet, (_, options)|
76
+ options.nil? ? fields << facet : begin ranges << facet
77
+ ((f[facet] ||= {})[:facet] ||= {})[:range] = options
78
+ end
79
+ } }
80
+ end
81
+
82
+ def highlighting_params(params = {})
83
+ params.merge(hl: {
84
+ fl: settings.highlighting_fields,
85
+ snippets: settings.highlighting_snippets,
86
+ fragsize: settings.highlighting_fragsize,
87
+ mergeContiguous: true,
88
+ preserveMulti: true,
89
+ simple: {
90
+ pre: settings.highlighting_prefix,
91
+ post: settings.highlighting_postfix
92
+ }
93
+ })
94
+ end
79
95
 
80
- def facet_counts(result)
81
- return {} unless result && result.to_i > 1
96
+ def spellcheck_params(params = {})
97
+ params.merge(spellcheck: { collate: true })
98
+ end
82
99
 
83
- exclude, prepare = [@query, *@filter], lambda { |facet_hash, &block|
84
- facet_hash.delete_if { |key, hash|
85
- gap = block[hash] if block
100
+ def terms(f = @field)
101
+ settings.solr.json('terms', terms: { fl: f, limit: -1 }).to_h[f].sort
102
+ end
86
103
 
87
- hash.delete_if { |term,|
88
- exclude.include?(facet_query(key, term, *gap)) }.size < 2
104
+ def explain_result(result = @result)
105
+ result.debug_explain if result && result.debug?
106
+ end
107
+
108
+ def facet_counts(result = @result)
109
+ return {} unless result && result.to_i > 1 && result.facet_counts?
110
+
111
+ exclude, prepare = [@query, *@filter], lambda { |facet_hash, &block|
112
+ facet_hash.delete_if { |key, hash|
113
+ gap = block[hash] if block
114
+
115
+ hash.delete_if { |term,|
116
+ exclude.include?(facet_query(key, term, *gap)) }.size < 2
117
+ }
89
118
  }
90
- }
91
119
 
92
- prepare.(result.facet_fields.to_h).merge(
93
- prepare.(result.facet_ranges.to_h) { |hash|
94
- counts, before, start, gap = hash
95
- .values_at(*%w[counts before start gap])
120
+ prepare.(result.facet_fields.to_h).merge(
121
+ prepare.(result.facet_ranges.to_h) { |hash|
122
+ counts, before, start, gap = hash
123
+ .values_at(*%w[counts before start gap])
124
+
125
+ hash.clear
126
+ hash[-start] = before if before && before > 1
127
+ counts.each { |value, count| hash[value.to_i] = count }
128
+
129
+ hash.singleton_class.send(:define_method, :gap) { gap }
130
+ gap
131
+ })
132
+ end
133
+
134
+ def highlighting(result = @result)
135
+ result.highlighting if result && result.highlighting?
136
+ end
137
+
138
+ def spellcheck_collations(result = @result, limit = nil)
139
+ result.spellcheck_collations(limit) if result && result.spellcheck?
140
+ end
141
+
142
+ private
96
143
 
97
- hash.clear
98
- hash[-start] = before if before > 1
99
- counts.each { |value, count| hash[value.to_i] = count }
144
+ def clip(num, min = 1)
145
+ num < min ? min : num
146
+ end
100
147
 
101
- hash.singleton_class.send(:define_method, :gap) { gap }
102
- gap
103
- })
104
148
  end
105
149
 
106
150
  end
@@ -5,7 +5,7 @@
5
5
  # #
6
6
  # Birds -- Bibliographic information retrieval & document search #
7
7
  # #
8
- # Copyright (C) 2014-2015 Jens Wille #
8
+ # Copyright (C) 2014-2016 Jens Wille #
9
9
  # #
10
10
  # Birds is free software: you can redistribute it and/or modify it under the #
11
11
  # terms of the GNU Affero General Public License as published by the Free #
@@ -23,105 +23,131 @@
23
23
  ###############################################################################
24
24
  #++
25
25
 
26
- class Birds::App
26
+ class Birds
27
+
28
+ class App
29
+
30
+ module Helpers
31
+
32
+ module View
33
+
34
+ def nav_item(path, name, title = nil)
35
+ li_(link_to(name, path, title: title), class: active?(path))
36
+ end
37
+
38
+ def hl(text)
39
+ h(text)
40
+ .gsub(h(settings.highlighting_prefix), settings.highlighting_prefix)
41
+ .gsub(h(settings.highlighting_postfix), settings.highlighting_postfix)
42
+ end
43
+
44
+ def cl(text)
45
+ text
46
+ .gsub(settings.highlighting_prefix, '')
47
+ .gsub(settings.highlighting_postfix, '')
48
+ end
49
+
50
+ def link_to_document(document, highlighting = {})
51
+ label = format_label(settings.document_label) { |k|
52
+ h, d = highlighting.delete(k), document[k]
53
+ h ? d.map { |v| h.find { |w| cl(w) == v } || v } : d
54
+ }
55
+
56
+ label = "##{document.id}" if label.empty?
57
+
58
+ link_to(hl(label), :document, document.id)
59
+ end
60
+
61
+ def link_to_search(text, query, *filters)
62
+ options = filters.last.is_a?(Hash) ? filters.pop : {}
63
+
64
+ link_to(text, :search, options.merge(params:
65
+ query ? query_params(query, filters) : { q: filters.first }))
66
+ end
67
+
68
+ def link_to_filter(text, query, filter)
69
+ link_to_search(hl(text), query, cl(filter), *@filter)
70
+ end
71
+
72
+ def link_to_field(field, value, query = nil)
73
+ link_to_filter(value, query, field_query(field, value))
74
+ end
75
+
76
+ def link_to_facet(field, value, gap = nil)
77
+ link_to_filter(
78
+ gap ? range_label(value, gap) : value,
79
+ @query, facet_query(field, value, gap))
80
+ end
81
+
82
+ def facet_query(field, value, gap = nil)
83
+ gap ? range_query(field, value, gap) : field_query(field, value)
84
+ end
85
+
86
+ def field_query(field, value)
87
+ %Q{#{field}:"#{value}"}
88
+ end
89
+
90
+ def range_query(field, value, gap)
91
+ value < 0 ?
92
+ %Q|#{field}:[* TO #{-value}}| :
93
+ %Q|#{field}:[#{value} TO #{value + gap}}|
94
+ end
95
+
96
+ def range_label(value, gap)
97
+ value < 0 ? "before #{-value}" : "#{value}–#{value + gap - 1}"
98
+ end
99
+
100
+ def query_params(q = @query, fq = @filter)
101
+ { q: q, 'fq[]' => fq }
102
+ end
103
+
104
+ def pagination_for(*args)
105
+ params = args.last.is_a?(Hash) ?
106
+ args.pop.reject { |_, v| v.nil? } : {}
107
+
108
+ ul_([
109
+ [@prev_page, :first, 1],
110
+ [@prev_page, :prev, @prev_page],
111
+ [@next_page, :next, @next_page],
112
+ [@next_page, :last, @total_pages]
113
+ ], class: 'pagination') { |condition, type, page|
114
+ [link_to_if(condition, pagination_icon(type), *args, rel: type,
115
+ params: params.merge(page: page)), class: disabled?(condition)]
116
+ }
117
+ end
118
+
119
+ def pagination_icon(type)
120
+ tag_(:span, glyphicon(*{
121
+ first: [:fast_backward, title: 'First page'],
122
+ prev: [:backward, title: 'Previous page'],
123
+ next: [:forward, title: 'Next page'],
124
+ last: [:fast_forward, title: 'Last page']
125
+ }[type]))
126
+ end
127
+
128
+ def glyphicon(name, options = {})
129
+ name, options = name.to_s.tr('_', '-'), options.dup
130
+
131
+ options[:class] = %W[glyphicon glyphicon-#{name}]
132
+ .push(*options.delete(:class)).compact.join(' ')
133
+
134
+ tag_(:span, options)
135
+ end
136
+
137
+ def values_for(key, document = @document)
138
+ Array(document[key = key.to_s]).dup.tap { |values|
139
+ return if values.empty?
140
+
141
+ if settings.browse_fields.include?(key)
142
+ values.map! { |v| link_to(v = hl(v), :browse, key, v) }
143
+ elsif field = settings.linkable_fields[key]
144
+ values.map! { |v| link_to_field(field, v) }
145
+ else
146
+ values.map!(&method(:hl))
147
+ end
148
+ }
149
+ end
27
150
 
28
- module Helpers
29
-
30
- module View
31
-
32
- def nav_item(path, name, title = nil)
33
- li_(link_to(name, path, title: title), class: active?(path))
34
- end
35
-
36
- def link_to_document(document)
37
- label = format_label(settings.document_label, document)
38
- link_to(h(label), :document, document['id'])
39
- end
40
-
41
- def link_to_search(text, query, *filters)
42
- options = filters.last.is_a?(Hash) ? filters.pop : {}
43
-
44
- link_to(text, :search, options.merge(params:
45
- query ? query_params(query, filters) : { q: filters.first }))
46
- end
47
-
48
- def link_to_filter(text, query, filter)
49
- link_to_search(h(text), query, filter, *@filter)
50
- end
51
-
52
- def link_to_field(field, value, query = nil)
53
- link_to_filter(value, query, field_query(field, value))
54
- end
55
-
56
- def link_to_facet(field, value, gap = nil)
57
- link_to_filter(
58
- gap ? range_label(value, gap) : value,
59
- @query, facet_query(field, value, gap))
60
- end
61
-
62
- def facet_query(field, value, gap = nil)
63
- gap ? range_query(field, value, gap) : field_query(field, value)
64
- end
65
-
66
- def field_query(field, value)
67
- %Q{#{field}:"#{value}"}
68
- end
69
-
70
- def range_query(field, value, gap)
71
- value < 0 ?
72
- %Q|#{field}:[* TO #{-value}}| :
73
- %Q|#{field}:[#{value} TO #{value + gap}}|
74
- end
75
-
76
- def range_label(value, gap)
77
- value < 0 ? "before #{-value}" : "#{value}–#{value + gap - 1}"
78
- end
79
-
80
- def query_params(q = @query, fq = @filter)
81
- { q: q, 'fq[]' => fq }
82
- end
83
-
84
- def pagination_for(*args)
85
- params = args.last.is_a?(Hash) ? args.pop.reject { |_, v| v.nil? } : {}
86
-
87
- ul_([
88
- [@prev_page, :first, 1],
89
- [@prev_page, :prev, @prev_page],
90
- [@next_page, :next, @next_page],
91
- [@next_page, :last, @total_pages]
92
- ], class: 'pagination') { |condition, type, page|
93
- li_(link_to_if(condition, pagination_icon(type),
94
- *args, params: params.merge(page: page)),
95
- class: disabled?(condition))
96
- }
97
- end
98
-
99
- def pagination_icon(type)
100
- tag_(:span, glyphicon(*{
101
- first: [:fast_backward, 'First page'],
102
- prev: [:backward, 'Previous page'],
103
- next: [:forward, 'Next page'],
104
- last: [:fast_forward, 'Last page']
105
- }[type]))
106
- end
107
-
108
- def glyphicon(name, title = nil)
109
- name = name.to_s.tr('_', '-')
110
- tag_(:span, class: "glyphicon glyphicon-#{name}", title: title)
111
- end
112
-
113
- def values_for(key, document = @document)
114
- Array(document[key = key.to_s]).dup.tap { |values|
115
- return if values.empty?
116
-
117
- if settings.browse_fields.include?(key)
118
- values.map! { |v| link_to(v = h(v), :browse, key, v) }
119
- elsif field = settings.linkable_fields[key]
120
- values.map! { |v| link_to_field(field, v) }
121
- else
122
- values.map!(&method(:h))
123
- end
124
- }
125
151
  end
126
152
 
127
153
  end
@@ -5,7 +5,7 @@
5
5
  # #
6
6
  # Birds -- Bibliographic information retrieval & document search #
7
7
  # #
8
- # Copyright (C) 2014-2015 Jens Wille #
8
+ # Copyright (C) 2014-2016 Jens Wille #
9
9
  # #
10
10
  # Birds is free software: you can redistribute it and/or modify it under the #
11
11
  # terms of the GNU Affero General Public License as published by the Free #
@@ -49,38 +49,72 @@ class Birds::App
49
49
  settings.solr_client.new(settings.solr_opts)
50
50
  end
51
51
 
52
- set_hash :display_fields, %w[
53
- title author year abstract language theme subject
52
+ set :solr_select_path do
53
+ settings.solr_client::DEFAULT_SELECT_PATH
54
+ end
55
+
56
+ set :solr_spell_path do
57
+ settings.solr_client::DEFAULT_SPELL_PATH
58
+ end
59
+
60
+ set :solr_match_all_query do
61
+ settings.solr_client::MATCH_ALL_QUERY
62
+ end
63
+
64
+ set_hash :display_fields1, %w[
65
+ editor author title issue source imprint year pages isbn series
66
+ abstract content footnote theme field form object location area aid
54
67
  ], %w[_txt] do |f, l| [f, l.capitalize] end
55
68
 
69
+ set_hash :display_fields2, %w[
70
+ compass lcsh precis rswk bk asb ddc sbb sfb ghbs kab lcc ssd rvk
71
+ ], %w[_txt] do |f, l| [f, l.upcase] end
72
+
73
+ set :display_fields do
74
+ settings.display_fields1.merge(settings.display_fields2)
75
+ end
76
+
56
77
  set_hash :linkable_fields, %w[
57
- author theme subject
78
+ editor author
79
+ theme field object
80
+ compass lcsh precis rswk bk asb ddc sbb sfb ghbs kab lcc ssd rvk
58
81
  ], %w[_txt _ss]
59
82
 
60
83
  set_hash :facet_fields, %w[
61
- author language theme subject
62
- ].insert(2,
84
+ author language type theme subject classification
85
+ ].insert(1,
63
86
  [:year, start: 1900, end: 2100, gap: 10, other: 'before']
64
87
  ) do |f, o| ["#{f}_#{o ? :i : :ss}", ["#{f}s".capitalize, o]] end
65
88
 
66
- set :mlt_fields, %w[
67
- author_txt title_txt abstract_txt subject_txt
68
- ]
89
+ set :mlt_fields,
90
+ author: %w[author_txt],
91
+ content: %w[title_txt abstract_txt subject_txt]
69
92
 
70
93
  set :browse_fields, {
71
- # 'cat' => %w[Category Categories],
72
- # 'manu_exact' => %w[Manufacturer Manufacturers]
94
+ #TODO 'cat' => %w[Category Categories],
95
+ #TODO 'manu_exact' => %w[Manufacturer Manufacturers]
73
96
  }
74
97
 
75
98
  set :scroll_fields, {
76
- # 'author_s' => 'Author'
99
+ #TODO 'author_s' => 'Author'
77
100
  }
78
101
 
79
- set :sample_queries, {
80
- 'Sample query 1' => 'author_txt:fugmann',
81
- 'Sample query 2' => 'fugmann -author_txt:fugmann'
82
- }
102
+ set :highlighting_fields, '*'
103
+
104
+ set :highlighting_snippets, 4
105
+
106
+ set :highlighting_fragsize, 0
107
+
108
+ set :highlighting_prefix, '<mark>'
109
+
110
+ set :highlighting_postfix, '</mark>'
111
+
112
+ set :sample_queries do
113
+ { 'All documents' => settings.solr_match_all_query }
114
+ end
115
+
116
+ set :document_label, '{author_txt:%s: }{title_txt( : )}{year_txt: (%s)}'
83
117
 
84
- set :document_label, '{author_ss:%s: }{title_ss( : )}{year_ss: (%s)}'
118
+ set :default_per_page, 20
85
119
 
86
120
  end
@@ -0,0 +1,6 @@
1
+ <dl class="dl-horizontal<%= ' info-display bg-info' if defined?(info) && info %>">
2
+ <% for key, label in fields; values = values_for(key, document) or next %>
3
+ <dt class="text-muted"><%=h label || key %></dt>
4
+ <dd><%= values.join('<br />') %></dd>
5
+ <% end %>
6
+ </dl>
@@ -1,13 +1,14 @@
1
- <ol start="<%= defined?(start) && start || 1 %>" style="margin-top: 1em"><!-- XXX -->
2
- <% for document in documents; id, score = document['id'], h('%.2f' % document['score']); next if @document && id == @document['id'] %>
1
+ <ol start="<%= defined?(start) && start || 1 %>">
2
+ <% for document in documents; id, score = document.id, h('%.2f' % document.score) %>
3
3
  <li>
4
- <%= link_to_document(document) %>
4
+ <%= link_to_document(document, hl = defined?(highlighting) == 'local-variable' ? highlighting[id] : {}) %>
5
5
  <% unless defined?(explain) && explain %>
6
6
  <span class="badge"><%= score %></span>
7
7
  <% else; eid = h("explain-#{id}") %>
8
8
  <span class="badge toggle-explain" data-toggle="collapse" data-target="#<%= eid %>" title="Toggle score explanation"><%= score %></span>
9
9
  <pre id="<%= eid %>" class="collapse small"><%=h explain[id] %></pre>
10
10
  <% end %>
11
+ <%= partial :display, fields: hl.keys.sort.map { |k| [k, settings.display_fields[k] || k.split('_')[0..-2].join('_').capitalize] }.uniq { |_, l| l }, document: hl, info: true unless hl.empty? %>
11
12
  </li>
12
13
  <% end %>
13
14
  </ol>
@@ -1,9 +1,26 @@
1
- <% position = 0; for facet, (label, _) in settings.facet_fields; counts = @facets[facet] or next; collapse = max = nil %>
1
+ <%
2
+ position = 0
3
+ for facet, (label, _) in settings.facet_fields
4
+ counts = @facets[facet] or next
5
+
6
+ fid = "facet-#{h(facet)}"
7
+ ffid = fid + '-filter'
8
+
9
+ expand = (position += 1) < 4
10
+
11
+ collapse = max = nil
12
+ %>
2
13
  <div class="panel panel-default">
3
14
  <div class="panel-heading">
4
- <h4 class="panel-title toggle-facet" data-toggle="collapse" data-target="#<%= fid = "facet-#{h(facet)}" %>" title="Toggle facet list"><%=h label %></h4>
15
+ <h4 class="panel-title toggle-facet" data-toggle="collapse" data-target="#<%= fid %>, #<%= ffid %>" title="Toggle facet list"><%=h label %></h4>
16
+ <% if counts.size > 8 %>
17
+ <div class="facet-filter collapse<%= ' in' if expand %>" id="<%= ffid %>">
18
+ <div class="pull-right"><%= glyphicon(:remove, title: 'Clear facet filter') %></div>
19
+ <form><input class="form-control" type="text" placeholder="Filter <%=h label.downcase %>" /></form>
20
+ </div>
21
+ <% end %>
5
22
  </div>
6
- <ul class="list-group compact-list-group collapse<%= ' in' if (position += 1) < 4 %>" id="<%= fid %>">
23
+ <ul class="facet-group list-group compact-list-group collapse<%= ' in' if expand %>" id="<%= fid %>">
7
24
  <% if counts.respond_to?(:gap) %>
8
25
  <% for (value, count), index in counts.reverse_each.with_index %>
9
26
  <li class="list-group-item clearfix<%= ' facet-collapse collapse' if collapse ||= index > 2 %>">
@@ -0,0 +1,9 @@
1
+ <ul class="list-inline">
2
+ <li class="text-warning">Did you mean:</li>
3
+ <% for query, hits in @spellcheck %>
4
+ <li>
5
+ <strong><%= link_to_search(h(query), query, *@filter) %></strong>
6
+ <span class="badge"><%=h hits %></span>
7
+ </li>
8
+ <% end %>
9
+ </ul>
@@ -1,12 +1,7 @@
1
- <dl class="dl-horizontal">
2
- <% for key, label in settings.display_fields; values = values_for(key) or next %>
3
- <dt class="text-muted" title="<%=h key %>:"><%=h label || key %></dt>
4
- <dd><%= values.join('<br />') %></dd>
5
- <% end %>
6
- </dl>
1
+ <%= partial :display, fields: settings.display_fields, document: @document %>
7
2
 
8
- <% unless @similar.empty? %>
9
- <h2>Similar documents</h2>
3
+ <% for key, mlt in @similar %>
4
+ <h2>Similar documents<%= " (#{key})" if key %></h2>
10
5
 
11
- <%= erb :_documents, locals: { documents: @similar, explain: @explain } %>
6
+ <%= partial :documents, documents: mlt, explain: @explain[key] %>
12
7
  <% end %>
@@ -16,9 +16,9 @@
16
16
  </form>
17
17
 
18
18
  <% if @filter %>
19
- <ul class="list-inline" style="margin-top: 0.5em"><!-- XXX -->
19
+ <ul class="filter-list list-inline">
20
20
  <% for filter in @filter %>
21
- <li style="line-height: 1.7em"><!-- XXX -->
21
+ <li>
22
22
  <%= link_to_search('&times;', @query, *@filter - [filter], class: 'close', title: 'Remove filter') %>
23
23
  <code><%=h filter %></code>
24
24
  </li>
@@ -27,11 +27,12 @@
27
27
  <% end %>
28
28
 
29
29
  <% if @result %>
30
- <%= erb :_documents, locals: { documents: @result, explain: @explain, start: @offset + 1 } %>
30
+ <%= partial :spellcheck unless @spellcheck.empty? %>
31
+ <%= partial :documents, documents: @result, explain: @explain, highlighting: @highlighting, start: @offset + 1 %>
31
32
  <%= pagination_for(:search, query_params) %>
32
33
  </div>
33
34
  <div class="col-md-3">
34
- <%= erb :_facets %>
35
+ <%= partial :facets %>
35
36
  <% else %>
36
37
  <h2>Query syntax</h2>
37
38
 
@@ -39,7 +39,7 @@
39
39
  <%= nav_item('/scroll', 'Scroll', 'Scroll through indexes') unless settings.scroll_fields.empty? %>
40
40
  </ul>
41
41
  <ul class="nav navbar-nav navbar-right">
42
- <li><a href="<%= url('/help') %>" title="View help pages">Help</a></li>
42
+ <li><a class="btn disabled" href="<%= url('/help') %>" title="View help pages">Help</a></li>
43
43
  </ul>
44
44
  <form action="<%= url('/search') %>" method="GET" class="navbar-form navbar-right" role="search">
45
45
  <div class="form-group">
@@ -56,7 +56,12 @@
56
56
  <% if @code && @error %>
57
57
  <p><big>Oops... <%=h @code %> – <%=h @error %></big></p>
58
58
  <% else %>
59
- <h1><%=h @page_title %><% if @page_title_extra %> <small>(<%=h @page_title_extra %>)</small><% end %></h1>
59
+ <h1>
60
+ <%=h @page_title %>
61
+ <% if pte = @page_title_extra %>
62
+ <small>(<%= @page_title_query ? link_to_search(h(pte), @page_title_query) : h(pte) %>)</small>
63
+ <% end %>
64
+ </h1>
60
65
  <%= yield %>
61
66
  <% end %>
62
67
  </div>
data/lib/birds/version.rb CHANGED
@@ -4,7 +4,7 @@ class Birds
4
4
 
5
5
  MAJOR = 0
6
6
  MINOR = 0
7
- TINY = 0
7
+ TINY = 1
8
8
 
9
9
  class << self
10
10
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: birds
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jens Wille
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-12 00:00:00.000000000 Z
11
+ date: 2016-10-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra-bells
@@ -16,40 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.0'
20
- - - ">="
21
- - !ruby/object:Gem::Version
22
- version: 0.0.2
19
+ version: '0.4'
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
24
  - - "~>"
28
25
  - !ruby/object:Gem::Version
29
- version: '0.0'
30
- - - ">="
31
- - !ruby/object:Gem::Version
32
- version: 0.0.2
26
+ version: '0.4'
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: solr4r
35
29
  requirement: !ruby/object:Gem::Requirement
36
30
  requirements:
37
31
  - - "~>"
38
32
  - !ruby/object:Gem::Version
39
- version: '0.0'
40
- - - ">="
41
- - !ruby/object:Gem::Version
42
- version: 0.0.4
33
+ version: '0.3'
43
34
  type: :runtime
44
35
  prerelease: false
45
36
  version_requirements: !ruby/object:Gem::Requirement
46
37
  requirements:
47
38
  - - "~>"
48
39
  - !ruby/object:Gem::Version
49
- version: '0.0'
50
- - - ">="
51
- - !ruby/object:Gem::Version
52
- version: 0.0.4
40
+ version: '0.3'
53
41
  - !ruby/object:Gem::Dependency
54
42
  name: unicode
55
43
  requirement: !ruby/object:Gem::Requirement
@@ -73,7 +61,7 @@ dependencies:
73
61
  version: '0.8'
74
62
  - - ">="
75
63
  - !ruby/object:Gem::Version
76
- version: 0.8.3.pre1
64
+ version: 0.8.6
77
65
  type: :development
78
66
  prerelease: false
79
67
  version_requirements: !ruby/object:Gem::Requirement
@@ -83,7 +71,7 @@ dependencies:
83
71
  version: '0.8'
84
72
  - - ">="
85
73
  - !ruby/object:Gem::Version
86
- version: 0.8.3.pre1
74
+ version: 0.8.6
87
75
  - !ruby/object:Gem::Dependency
88
76
  name: rake
89
77
  requirement: !ruby/object:Gem::Requirement
@@ -120,8 +108,10 @@ files:
120
108
  - lib/birds/app/helpers/view.rb
121
109
  - lib/birds/app/public/favicon.ico
122
110
  - lib/birds/app/settings.rb
111
+ - lib/birds/app/views/_display.erb
123
112
  - lib/birds/app/views/_documents.erb
124
113
  - lib/birds/app/views/_facets.erb
114
+ - lib/birds/app/views/_spellcheck.erb
125
115
  - lib/birds/app/views/browse.erb
126
116
  - lib/birds/app/views/document.erb
127
117
  - lib/birds/app/views/index.erb
@@ -135,13 +125,13 @@ licenses:
135
125
  metadata: {}
136
126
  post_install_message: |2+
137
127
 
138
- birds-0.0.0 [2014-03-19]:
128
+ birds-0.0.1 [2016-10-12]:
139
129
 
140
- * Birthday :-)
130
+ * Initial release.
141
131
 
142
132
  rdoc_options:
143
133
  - "--title"
144
- - birds Application documentation (v0.0.0)
134
+ - birds Application documentation (v0.0.1)
145
135
  - "--charset"
146
136
  - UTF-8
147
137
  - "--line-numbers"
@@ -162,7 +152,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
162
152
  version: '0'
163
153
  requirements: []
164
154
  rubyforge_project:
165
- rubygems_version: 2.4.8
155
+ rubygems_version: 2.6.6
166
156
  signing_key:
167
157
  specification_version: 4
168
158
  summary: Bibliographic information retrieval & document search.