enju_biblio 0.3.11 → 0.3.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/agent_import_results_controller.rb +1 -1
  3. data/app/controllers/agents_controller.rb +0 -6
  4. data/app/controllers/items_controller.rb +15 -10
  5. data/app/controllers/manifestations_controller.rb +68 -76
  6. data/app/controllers/resource_import_results_controller.rb +2 -2
  7. data/app/controllers/series_statements_controller.rb +0 -6
  8. data/app/helpers/manifestations_helper.rb +8 -8
  9. data/app/models/agent.rb +10 -1
  10. data/app/models/form_of_work.rb +1 -1
  11. data/app/models/frequency.rb +1 -1
  12. data/app/models/identifier.rb +1 -1
  13. data/app/models/import_request.rb +2 -3
  14. data/app/models/item.rb +6 -6
  15. data/app/models/item_custom_value.rb +1 -1
  16. data/app/models/manifestation.rb +10 -18
  17. data/app/models/manifestation_custom_value.rb +1 -1
  18. data/app/models/resource_import_file.rb +8 -4
  19. data/app/views/agent_import_results/{index.txt.ruby → index.text.ruby} +0 -0
  20. data/app/views/agent_relationship_types/index.html.erb +3 -3
  21. data/app/views/agents/index.rss.builder +2 -2
  22. data/app/views/items/_item.json.jbuilder +17 -0
  23. data/app/views/items/index.json.jbuilder +5 -0
  24. data/app/views/items/index.text.ruby +13 -0
  25. data/app/views/items/show.html.erb +125 -125
  26. data/app/views/items/show.json.jbuilder +1 -0
  27. data/app/views/layouts/agents.html.erb +2 -2
  28. data/app/views/layouts/manifestations.html.erb +2 -2
  29. data/app/views/manifestations/_carrier_type_facet.html.erb +1 -1
  30. data/app/views/manifestations/_classification_facet.html.erb +2 -2
  31. data/app/views/manifestations/_export_list.html.erb +4 -4
  32. data/app/views/manifestations/_form.html.erb +3 -3
  33. data/app/views/manifestations/_language_facet.html.erb +1 -1
  34. data/app/views/manifestations/_library_facet.html.erb +1 -1
  35. data/app/views/manifestations/_pub_year_facet.html.erb +1 -1
  36. data/app/views/manifestations/_reservable_facet.html.erb +2 -2
  37. data/app/views/manifestations/_show_detail_librarian.html.erb +12 -8
  38. data/app/views/manifestations/_show_detail_user.html.erb +12 -8
  39. data/app/views/manifestations/_title.html.erb +1 -1
  40. data/app/views/manifestations/index.html.erb +7 -7
  41. data/app/views/manifestations/index.rdf.builder +2 -2
  42. data/app/views/manifestations/index.rss.builder +2 -2
  43. data/app/views/manifestations/index.text.ruby +13 -0
  44. data/app/views/manifestations/{show.txt.ruby → show.text.ruby} +0 -0
  45. data/app/views/resource_import_results/{index.txt.ruby → index.text.ruby} +0 -0
  46. data/lib/enju_biblio/version.rb +1 -1
  47. data/lib/enju_biblio.rb +0 -2
  48. data/spec/controllers/items_controller_spec.rb +41 -0
  49. data/spec/controllers/manifestations_controller_spec.rb +2 -21
  50. data/spec/fixtures/items.yml +1 -0
  51. data/spec/fixtures/manifestations.yml +1 -0
  52. data/spec/models/manifestation_spec.rb +11 -66
  53. data/spec/models/resource_import_file_spec.rb +18 -0
  54. data/spec/system/items_spec.rb +6 -0
  55. data/spec/views/agent_import_results/{index.txt.ruby_spec.rb → index.text.ruby_spec.rb} +1 -1
  56. data/spec/views/items/index.json.jbuilder_spec.rb +15 -0
  57. data/spec/views/items/show.json.jbuilder_spec.rb +15 -0
  58. data/spec/views/manifestations/index.html.erb_spec.rb +1 -1
  59. data/spec/views/manifestations/index.rdf.builder_spec.rb +0 -1
  60. data/spec/views/manifestations/{index.txt.ruby_spec.rb → index.text.ruby_spec.rb} +1 -1
  61. data/spec/views/manifestations/{show.txt.ruby_spec.rb → show.text.ruby_spec.rb} +1 -1
  62. data/spec/views/resource_import_results/{index.txt.ruby_spec.rb → index.text.ruby_spec.rb} +1 -1
  63. metadata +37 -34
  64. data/app/views/items/index.txt.erb +0 -4
  65. data/app/views/manifestations/explain.sru +0 -9
  66. data/app/views/manifestations/index.sru.builder +0 -101
  67. data/app/views/manifestations/index.txt.ruby +0 -7
  68. data/lib/enju_biblio/porta_cql.rb +0 -282
  69. data/lib/enju_biblio/sru.rb +0 -85
@@ -1,282 +0,0 @@
1
- require 'strscan'
2
-
3
- class QueryError < RuntimeError; end
4
- class QuerySyntaxError < QueryError; end
5
-
6
- class Cql
7
- def initialize(line)
8
- @logic = nil
9
- @query = split_clause_text(line).collect{|txt| Clause.new(txt)}
10
-
11
- from_day, @query = extract_with_index(@query, /from/io)
12
- @from = comp_date(from_day)
13
- until_day, @query = extract_with_index(@query, /until/io)
14
- @until = comp_date(until_day)
15
- sort_by, @query = extract_with_index(@query, /sortBy/io)
16
- @sort_by = sort_by ? sort_by.terms.first : ''
17
- end
18
-
19
- attr_reader :query, :from, :until, :sort_by, :logic
20
-
21
- def ==(other)
22
- instance_variables.all? do |val|
23
- instance_variable_get(val) == other.instance_variable_get(val)
24
- end
25
- end
26
-
27
- def to_sunspot
28
- (@query.collect{|c| c.to_sunspot} + date_range(@from, @until)).join(" #{@logic} ")
29
- end
30
-
31
- def split_clause_text(line)
32
- clauses = []
33
-
34
- s = StringScanner.new(line)
35
- text = ''
36
- while s.rest?
37
- case
38
- when s.scan(/\s+/)
39
- text << s.matched
40
- when s.scan(/"(?:[^"\\]|\\.)*"/)
41
- text << s.matched
42
- when s.scan(/(AND|OR)/i)
43
- logic = s.matched.upcase
44
- if @logic
45
- raise QuerySyntaxError unless @logic == logic
46
- else
47
- @logic = logic
48
- end
49
- clauses << text.strip
50
- text = ''
51
- when s.scan(/\S*/)
52
- text << s.matched
53
- end
54
- end
55
- clauses << text.strip
56
- clauses.collect{|txt| txt.gsub(/(\A\(|\)\Z)/, '')}
57
- end
58
-
59
- private
60
- def extract_with_index(arr, reg)
61
- element, rest = arr.partition{|c| reg =~ c.index }
62
- [element.last, rest]
63
- end
64
-
65
- def date_range(from_date, until_date)
66
- unless from_date == '*' and until_date == '*'
67
- ["pub_date_dm:[#{from_date} TO #{until_date}]"]
68
- else
69
- []
70
- end
71
- end
72
-
73
- def comp_date(date)
74
- if date
75
- text = date.terms[0]
76
- date_text = case text
77
- when /\A\d{4}-\d{2}-\d{2}\Z/
78
- text
79
- when /\A\d{4}-\d{2}\Z/
80
- (text + '-01')
81
- when /\A\d{4}\Z/
82
- (text + '-01-01')
83
- else
84
- raise QuerySyntaxError, text.to_s
85
- end
86
- begin
87
- Time.zone.parse(date_text).utc.iso8601.to_s
88
- rescue
89
- raise QuerySyntaxError, date.to_s
90
- end
91
- else
92
- '*'
93
- end
94
- end
95
- end
96
-
97
- class ScannerError < QuerySyntaxError; end
98
- class AdapterError < QuerySyntaxError; end
99
-
100
- class Clause
101
- INDEX = /(dpid|dpgroupid|title|creator|publisher|ndc|description|subject|isbn|issn|jpno|from|until|anywhere|porta_type|digitalize_type|webget_type|payment_type|ndl_agent_type|ndlc|itemno)/io
102
- SORT_BY = /sortBy/io
103
- RELATION = /(=|exact|\^|any|all)/io
104
-
105
- MATCH_ALL = %w[title creator publisher]
106
- MATCH_EXACT = %w[dpid dpgroupid isbn issn jpno porta_type digitalize_type webget_type payment_type ndl_agent_type itemno]
107
- MATCH_PART = %w[description subject]
108
- MATCH_AHEAD = %w[ndc ndlc]
109
- MATCH_DATE = %w[from until]
110
- MATCH_ANYWHERE = %w[anywhere]
111
- LOGIC_ALL = %w[title creator publisher description subject anywhere]
112
- LOGIC_ANY = %w[dpid ndl_agent_type]
113
- LOGIC_EQUAL = %w[dpgroupid ndc isbn issn jpno from until porta_type digitalize_type webget_type payment_type ndlc itemno]
114
- MULTIPLE = %w[dpid title creator publisher description subject anywhere ndl_agent_type]
115
-
116
- def initialize(text)
117
- unless text.empty?
118
- @index, @relation, @terms = scan(text)
119
- porta_adapter
120
- @field = @index
121
- else
122
- @index = ''
123
- end
124
- end
125
-
126
- attr_reader :index, :relation, :terms
127
-
128
- def ==(other)
129
- instance_variables.all? do |val|
130
- instance_variable_get(val) == other.instance_variable_get(val)
131
- end
132
- end
133
-
134
- def scan(text)
135
- ss = StringScanner.new(text)
136
- index = ''
137
- relation = ''
138
- terms = []
139
-
140
- if ss.scan(INDEX) or ss.scan(SORT_BY)
141
- index = ss[0]
142
- end
143
- # else
144
- # raise ScannerError, "index or the sortBy is requested in '#{text}'"
145
- # end
146
- ss.scan(/\s+/)
147
- if ss.scan(RELATION)
148
- relation = ss[0].upcase
149
- end
150
- # else
151
- # raise ScannerError, "relation is requested in '#{text}'"
152
- # end
153
- ss.scan(/\s+/)
154
- if ss.scan(/.+/)
155
- terms = ss[0].gsub(/(\A\"|\"\Z)/, '').split
156
- else
157
- raise ScannerError, "search term(s) is requested in '#{text}'"
158
- end
159
-
160
- [index, relation, terms]
161
- end
162
-
163
- def porta_adapter
164
- logic_adapter
165
- multiple_adapter
166
- end
167
-
168
- def logic_adapter
169
- case
170
- when LOGIC_ALL.include?(@index)
171
- raise AdapterError unless %w[ALL ANY = EXACT ^].include?(@relation)
172
- when LOGIC_ANY.include?(@index)
173
- raise AdapterError unless %w[ANY =].include?(@relation)
174
- when LOGIC_EQUAL.include?(@index)
175
- raise AdapterError unless %w[=].include?(@relation)
176
- end
177
- end
178
-
179
- def multiple_adapter
180
- unless MULTIPLE.include?(@index)
181
- raise AdapterError if @terms.size > 1
182
- end
183
- end
184
-
185
- def to_sunspot
186
- case
187
- when MATCH_ALL.include?(@index)
188
- to_sunspot_match_all
189
- when MATCH_EXACT.include?(@index)
190
- to_sunspot_match_exact
191
- when MATCH_PART.include?(@index)
192
- to_sunspot_match_part
193
- when MATCH_AHEAD.include?(@index)
194
- to_sunspot_match_ahead
195
- when MATCH_ANYWHERE.include?(@index)
196
- to_sunspot_match_anywhere
197
- when @index.empty?
198
- @terms.join(' ')
199
- end
200
- end
201
-
202
- def to_sunspot_match_all
203
- term = @terms.join(' ')
204
- case @relation
205
- when /\A=\Z/
206
- unless /\A\^(.+)/ =~ term
207
- "%s_%s:(%s)" % [@field, :text, term]
208
- else
209
- ahead_tarm = $1.gsub("\s", '').downcase
210
- "connect_%s_%s:(%s*)" % [@field, :s, ahead_tarm]
211
- end
212
- when /\AEXACT\Z/
213
- "%s_%s:(%s)" % [@field, :sm, term.gsub(' ', '')]
214
- when /\AANY\Z/
215
- "%s_%s:(%s)" % [@field, :text, multiple_to_sunspot(@terms, :any)]
216
- when /\AALL\Z/
217
- "%s_%s:(%s)" % [@field, :text, multiple_to_sunspot(@terms, :all)]
218
- else
219
- raise QuerySyntaxError
220
- end
221
- end
222
-
223
- def to_sunspot_match_exact
224
- case @relation
225
- when /\A=\Z/
226
- term = @terms.join(' ')
227
- type = @field != 'issn' ? :sm : :s
228
- "%s_%s:(%s)" % [@field, type, term]
229
- when /\AANY\Z/
230
- "%s_%s:(%s)" % [@field, :sm, multiple_to_sunspot(@terms, :any)]
231
- else
232
- raise QuerySyntaxError
233
- end
234
- end
235
-
236
- def to_sunspot_match_part
237
- case @relation
238
- when /\A=\Z/
239
- term = @terms.join(' ')
240
- "%s_%s:(%s)" % [@field, :text, trim_ahead(term)]
241
- when /\AANY\Z/
242
- "%s_%s:(%s)" % [@field, :text, multiple_to_sunspot(@terms, :any)]
243
- when /\AALL\Z/
244
- "%s_%s:(%s)" % [@field, :text, multiple_to_sunspot(@terms, :all)]
245
- else
246
- raise QuerySyntaxError
247
- end
248
- end
249
-
250
- def to_sunspot_match_ahead
251
- "%s_%s:(%s*)" % [@field, :s, @terms.first]
252
- end
253
-
254
- def to_sunspot_match_anywhere
255
- case @relation
256
- when /\A=\Z/
257
- term = @terms.join(' ')
258
- "(%s)" % [trim_ahead(term)]
259
- when /\AANY\Z/
260
- "(%s)" % [multiple_to_sunspot(@terms, :any)]
261
- when /\AALL\Z/
262
- "(%s)" % [multiple_to_sunspot(@terms, :all)]
263
- else
264
- raise QuerySyntaxError
265
- end
266
- end
267
-
268
-
269
- private
270
- def multiple_to_sunspot(terms, relation)
271
- boolean = relation == :any ? ' OR ' : ' AND '
272
- (terms.map{|t| trim_ahead(t)}.join(boolean)).to_s
273
- end
274
-
275
- def trim_ahead(term)
276
- term.sub(/\A\^+/,'')
277
- end
278
- end
279
-
280
- if $PROGRAM_NAME == __FILE__
281
- require 'porta_cql_test'
282
- end
@@ -1,85 +0,0 @@
1
- require 'enju_biblio/porta_cql'
2
-
3
- class QueryArgumentError < QueryError; end
4
-
5
- class Sru
6
- ASC_KEYS = %w(title creator) unless Object.const_defined?(:ASC_KEYS)
7
- DESC_KEYS = %w(created_at updated_at date_of_publication) unless Object.const_defined?(:DESC_KEYS)
8
- SORT_KEYS = ASC_KEYS + DESC_KEYS unless Object.const_defined?(:SORY_KEYS)
9
- MULTI_KEY_MAP = {'title' => 'sort_title'} unless Object.const_defined?(:MULTI_KEY_MAP)
10
- def initialize(params)
11
- raise QueryArgumentError, 'sru :query is required item.' unless params.key?(:query)
12
-
13
- @cql = Cql.new(params[:query])
14
- @version = params.key?(:version) ? params[:version] : '1.2'
15
- @start = params.key?(:startRecord) ? params[:startRecord].to_i : 1
16
- @maximum = params.key?(:maximumRecords) ? params[:maximumRecords].to_i : 200
17
- @maximum = 1000 if 1000 < @maximum
18
- @packing = params.key?(:recordPacking) ? params[:recordPacking] : 'string'
19
- @schema = params.key?(:recordSchema) ? params[:recordSchema] : 'dc'
20
- @sort_key = params[:sortKeys]
21
-
22
- @manifestations = []
23
- @extra_response_data = {}
24
- end
25
-
26
- attr_reader :version, :cql, :start, :maximum, :packing, :schema, :path, :ascending
27
- attr_reader :manifestations, :extra_response_data, :number_of_records, :next_record_position
28
-
29
- def sort_by
30
- sort = {sort_by: 'created_at', order: 'desc'}
31
- unless '1.1' == @version
32
- @path, @ascending = @cql.sort_by.split('/')
33
- else
34
- @path, @ascending = @sort_key.split(',') if @sort_key
35
- end
36
- # TODO ソート基準が入手しやすさの場合の処理
37
- if SORT_KEYS.include?(@path)
38
- if MULTI_KEY_MAP.keys.include?(@path)
39
- sort[:sort_by] = MULTI_KEY_MAP[@path]
40
- else
41
- sort[:sort_by] = @path
42
- end
43
- sort[:order] = 'asc' if ASC_KEYS.include?(@path)
44
- case @ascending
45
- when /\A(1|ascending)\Z/
46
- sort[:order] = 'asc'
47
- when /\A(0|descending)\Z/
48
- sort[:order] = 'desc'
49
- end
50
- end
51
- sort
52
- end
53
-
54
- def search
55
- sunspot_query = @cql.to_sunspot
56
- search = Sunspot.new_search(Manifestation)
57
- role = Role.default_role
58
- search.build do
59
- fulltext sunspot_query
60
- with(:required_role_id).less_than_or_equal_to role.id
61
- paginate page: 1, per_page: 10000
62
- end
63
- @manifestations = search.execute!.results
64
- @extra_response_data = get_extra_response_data
65
- @number_of_records, @next_record_position = get_number_of_records
66
-
67
- @manifestations
68
- end
69
-
70
- def get_extra_response_data
71
- # TODO: NDL で必要な項目が決定し、更に enju にそのフィールドが設けられた後で正式な実装を行なう。
72
- if @search.respond_to?(:erd)
73
- @schema == 'dc' ? @search.erd : {}
74
- end
75
- end
76
-
77
- def get_number_of_records
78
- # TODO: sunspot での取得方法が分かり次第、正式な実装を行なう。
79
- @schema == 'dc' ? [1405, 1406] : [40,11]
80
- end
81
- end
82
-
83
- if $PROGRAM_NAME == __FILE__
84
- require 'sru_test'
85
- end