birds 0.0.0 → 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.