skala 0.3.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -4
- data/Gemfile +10 -1
- data/LICENSE.txt +17 -18
- data/README.md +1 -34
- data/README.primo_adapter.md +42 -0
- data/bin/console +11 -0
- data/config/initializers/skala.rb +5 -0
- data/config/skala.yml +65 -0
- data/db/migrate/20141006133522_create_skala_users.rb +13 -0
- data/db/migrate/20141006133649_create_skala_user_watch_lists.rb +14 -0
- data/db/migrate/20141006135644_create_skala_user_watch_list_entries.rb +13 -0
- data/db/migrate/20141006140435_create_skala_user_notes.rb +16 -0
- data/lib/skala.rb +36 -3
- data/lib/skala/adapter.rb +122 -4
- data/lib/skala/adapter/authenticate_user.rb +4 -0
- data/lib/skala/adapter/create_user_hold_request.rb +7 -0
- data/lib/skala/adapter/create_user_hold_request/result.rb +10 -0
- data/lib/skala/adapter/delete_user_hold_request.rb +7 -0
- data/lib/skala/adapter/get_record_holdable_items.rb +5 -0
- data/lib/skala/adapter/get_record_holdable_items/result.rb +14 -0
- data/lib/skala/adapter/get_record_items.rb +5 -0
- data/lib/skala/adapter/get_record_items/result.rb +14 -0
- data/lib/skala/adapter/get_records.rb +5 -0
- data/lib/skala/adapter/get_records/result.rb +28 -0
- data/lib/skala/adapter/get_user.rb +4 -0
- data/lib/skala/adapter/get_user_former_loans.rb +5 -0
- data/lib/skala/adapter/get_user_former_loans/result.rb +14 -0
- data/lib/skala/adapter/get_user_hold_requests.rb +5 -0
- data/lib/skala/adapter/get_user_hold_requests/result.rb +14 -0
- data/lib/skala/adapter/get_user_inter_library_loans.rb +5 -0
- data/lib/skala/adapter/get_user_inter_library_loans/result.rb +14 -0
- data/lib/skala/adapter/get_user_loans.rb +5 -0
- data/lib/skala/adapter/get_user_loans/result.rb +14 -0
- data/lib/skala/adapter/get_user_transactions.rb +5 -0
- data/lib/skala/adapter/get_user_transactions/result.rb +14 -0
- data/lib/skala/adapter/operation.rb +2 -0
- data/lib/skala/adapter/operation/request.rb +6 -0
- data/lib/skala/adapter/operation/result.rb +7 -0
- data/lib/skala/adapter/renew_user_loan.rb +7 -0
- data/lib/skala/adapter/renew_user_loan/result.rb +7 -0
- data/lib/skala/adapter/renew_user_loans.rb +5 -0
- data/lib/skala/adapter/renew_user_loans/result.rb +9 -0
- data/lib/skala/adapter/search.rb +6 -0
- data/lib/skala/adapter/search/request.rb +91 -0
- data/lib/skala/adapter/search/request/date_histogram_facet.rb +5 -0
- data/lib/skala/adapter/search/request/facet.rb +29 -0
- data/lib/skala/adapter/search/request/histogram_facet.rb +8 -0
- data/lib/skala/adapter/search/request/ids_query.rb +6 -0
- data/lib/skala/adapter/search/request/match_query.rb +7 -0
- data/lib/skala/adapter/search/request/ordered_terms_query.rb +7 -0
- data/lib/skala/adapter/search/request/query.rb +18 -0
- data/lib/skala/adapter/search/request/query_string_query.rb +9 -0
- data/lib/skala/adapter/search/request/range_facet.rb +10 -0
- data/lib/skala/adapter/search/request/range_facet/range.rb +9 -0
- data/lib/skala/adapter/search/request/range_query.rb +8 -0
- data/lib/skala/adapter/search/request/simple_query_string_query.rb +8 -0
- data/lib/skala/adapter/search/request/sort_request.rb +15 -0
- data/lib/skala/adapter/search/request/terms_facet.rb +8 -0
- data/lib/skala/adapter/search/request/unscored_terms_query.rb +7 -0
- data/lib/skala/adapter/search/result.rb +22 -0
- data/lib/skala/adapter/search/result/facet.rb +15 -0
- data/lib/skala/adapter/search/result/histogram_facet.rb +12 -0
- data/lib/skala/adapter/search/result/histogram_facet/entry.rb +8 -0
- data/lib/skala/adapter/search/result/hit.rb +13 -0
- data/lib/skala/adapter/search/result/terms_facet.rb +14 -0
- data/lib/skala/adapter/search/result/terms_facet/term.rb +8 -0
- data/lib/skala/adapter/update_user.rb +4 -0
- data/lib/skala/aleph_adapter.rb +47 -0
- data/lib/skala/aleph_adapter/authenticate_user.rb +27 -0
- data/lib/skala/aleph_adapter/create_user_hold_request.rb +63 -0
- data/lib/skala/aleph_adapter/delete_user_hold_request.rb +29 -0
- data/lib/skala/aleph_adapter/get_record.rb +22 -0
- data/lib/skala/aleph_adapter/get_record_holdable_items.rb +29 -0
- data/lib/skala/aleph_adapter/get_record_items.rb +111 -0
- data/lib/skala/aleph_adapter/get_user.rb +49 -0
- data/lib/skala/aleph_adapter/get_user_former_loans.rb +21 -0
- data/lib/skala/aleph_adapter/get_user_hold_requests.rb +102 -0
- data/lib/skala/aleph_adapter/get_user_inter_library_loans.rb +66 -0
- data/lib/skala/aleph_adapter/get_user_loans.rb +93 -0
- data/lib/skala/aleph_adapter/get_user_transactions.rb +96 -0
- data/lib/skala/aleph_adapter/renew_user_loan.rb +27 -0
- data/lib/skala/aleph_adapter/renew_user_loans.rb +39 -0
- data/lib/skala/aleph_adapter/resolve_user.rb +19 -0
- data/lib/skala/aleph_adapter/update_user.rb +105 -0
- data/lib/skala/common_attributes.rb +19 -0
- data/lib/skala/elasticsearch_adapter.rb +33 -0
- data/lib/skala/elasticsearch_adapter/search.rb +20 -0
- data/lib/skala/elasticsearch_adapter/search/request_transformation.rb +20 -0
- data/lib/skala/elasticsearch_adapter/search/request_transformation/add_aggregations.rb +50 -0
- data/lib/skala/elasticsearch_adapter/search/request_transformation/add_from.rb +10 -0
- data/lib/skala/elasticsearch_adapter/search/request_transformation/add_query.rb +107 -0
- data/lib/skala/elasticsearch_adapter/search/request_transformation/add_size.rb +12 -0
- data/lib/skala/elasticsearch_adapter/search/request_transformation/add_sort.rb +18 -0
- data/lib/skala/elasticsearch_adapter/search/request_transformation/add_version.rb +10 -0
- data/lib/skala/elasticsearch_adapter/search/result_transformation.rb +21 -0
- data/lib/skala/elasticsearch_adapter/search/result_transformation/set_facets.rb +44 -0
- data/lib/skala/elasticsearch_adapter/search/result_transformation/set_hits.rb +18 -0
- data/lib/skala/elasticsearch_adapter/search/result_transformation/set_total_hits.rb +10 -0
- data/lib/skala/engine.rb +14 -0
- data/lib/skala/get_user_result.rb +14 -0
- data/lib/skala/hold_request.rb +24 -0
- data/lib/skala/item.rb +15 -0
- data/lib/skala/loan.rb +18 -0
- data/lib/skala/primo_adapter.rb +34 -0
- data/lib/skala/primo_adapter/get_records.rb +24 -0
- data/lib/skala/primo_adapter/search.rb +13 -0
- data/lib/skala/primo_adapter/search/request_transformation.rb +40 -0
- data/lib/skala/primo_adapter/search/request_transformation/add_queries.rb +97 -0
- data/lib/skala/primo_adapter/search/request_transformation/add_sort_by_list.rb +37 -0
- data/lib/skala/primo_adapter/search/request_transformation/embed_inner_search_request.rb +13 -0
- data/lib/skala/primo_adapter/search/request_transformation/serialize_target_as_xml.rb +11 -0
- data/lib/skala/primo_adapter/search/request_transformation/set_bulk_size.rb +12 -0
- data/lib/skala/primo_adapter/search/request_transformation/set_institution.rb +12 -0
- data/lib/skala/primo_adapter/search/request_transformation/set_languages.rb +15 -0
- data/lib/skala/primo_adapter/search/request_transformation/set_locations.rb +19 -0
- data/lib/skala/primo_adapter/search/request_transformation/set_on_campus.rb +13 -0
- data/lib/skala/primo_adapter/search/request_transformation/set_start_index.rb +12 -0
- data/lib/skala/primo_adapter/search/request_transformation/setup_inner_search_request.rb +33 -0
- data/lib/skala/primo_adapter/search/request_transformation/setup_target.rb +28 -0
- data/lib/skala/primo_adapter/search/request_transformation/toggle_bool_operator.rb +13 -0
- data/lib/skala/primo_adapter/search/result_transformation.rb +30 -0
- data/lib/skala/primo_adapter/search/result_transformation/add_hits.rb +13 -0
- data/lib/skala/primo_adapter/search/result_transformation/doc_transformation.rb +46 -0
- data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_creator.rb +10 -0
- data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_description.rb +10 -0
- data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_edition.rb +10 -0
- data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_fulltext_available.rb +12 -0
- data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_id.rb +11 -0
- data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_identifier.rb +46 -0
- data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_is_part_of.rb +14 -0
- data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_language.rb +10 -0
- data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_metadata.rb +13 -0
- data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_openurl.rb +23 -0
- data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_publisher.rb +10 -0
- data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_source.rb +10 -0
- data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_subject.rb +10 -0
- data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_title.rb +10 -0
- data/lib/skala/primo_adapter/search/result_transformation/doc_transformation/set_year_of_publication.rb +10 -0
- data/lib/skala/primo_adapter/search/result_transformation/fix_primo_facets_bugs.rb +108 -0
- data/lib/skala/primo_adapter/search/result_transformation/parse_search_brief_response.rb +20 -0
- data/lib/skala/primo_adapter/search/result_transformation/set_facets.rb +71 -0
- data/lib/skala/primo_adapter/search/result_transformation/set_total_hits.rb +13 -0
- data/lib/skala/primo_adapter/search/result_transformation/sort_terms_facets_terms.rb +14 -0
- data/lib/skala/primo_adapter/soap_api.rb +15 -0
- data/lib/skala/primo_adapter/soap_api/search_brief.rb +25 -0
- data/lib/skala/record.rb +85 -0
- data/lib/skala/record/identifier.rb +9 -0
- data/lib/skala/record/is_part_of.rb +11 -0
- data/lib/skala/record/link.rb +9 -0
- data/lib/skala/record/relation.rb +9 -0
- data/lib/skala/transaction.rb +13 -0
- data/lib/skala/version.rb +1 -1
- data/skala.gemspec +21 -12
- data/spec/skala/search_request/ordered_terms_query_spec.rb +6 -0
- data/spec/spec_helper.rb +7 -28
- metadata +237 -85
- data/lib/skala/i18n.rb +0 -46
- data/lib/skala/transformation.rb +0 -54
- data/lib/skala/transformation/step.rb +0 -24
- data/spec/assets/locales/de.yml +0 -14
- data/spec/assets/locales/en.yml +0 -9
- data/spec/assets/transformation/some_class.rb +0 -2
- data/spec/skala/adapter/operation_spec.rb +0 -19
- data/spec/skala/adapter_spec.rb +0 -2
- data/spec/skala/i18n_spec.rb +0 -95
- data/spec/skala/transformation/step_spec.rb +0 -36
- data/spec/skala/transformation_spec.rb +0 -89
- data/spec/skala_spec.rb +0 -2
@@ -0,0 +1,96 @@
|
|
1
|
+
require "nokogiri"
|
2
|
+
require "skala/adapter/get_user_transactions"
|
3
|
+
require_relative "../aleph_adapter"
|
4
|
+
require_relative "./resolve_user"
|
5
|
+
|
6
|
+
class Skala::AlephAdapter::GetUserTransactions < Skala::Adapter::GetUserTransactions
|
7
|
+
include parent::ResolveUser
|
8
|
+
|
9
|
+
def call(username, options = {})
|
10
|
+
resolved_user_id = resolve_user(username)
|
11
|
+
|
12
|
+
patron_cash_list = @adapter.restful_api.patron(resolved_user_id).circulationActions.cash.get(view: :full)
|
13
|
+
patron_loan_list = @adapter.restful_api.patron(resolved_user_id).circulationActions.loans.get(view: :full)
|
14
|
+
|
15
|
+
if [patron_cash_list, patron_loan_list].any? { |_response| _response.include?("<error>") }
|
16
|
+
return nil
|
17
|
+
else
|
18
|
+
transactions = []
|
19
|
+
|
20
|
+
# regular credits/debits
|
21
|
+
Nokogiri::XML(patron_cash_list).xpath("//cash").each do |_cash|
|
22
|
+
credit_or_debit = {
|
23
|
+
id: id(_cash),
|
24
|
+
creation_date: creation_date(_cash),
|
25
|
+
record: {
|
26
|
+
id: record_id(_cash)
|
27
|
+
},
|
28
|
+
reason: reason(_cash),
|
29
|
+
type: type(_cash),
|
30
|
+
value: value(_cash),
|
31
|
+
description: description(_cash)
|
32
|
+
}
|
33
|
+
|
34
|
+
transactions << credit_or_debit
|
35
|
+
end
|
36
|
+
|
37
|
+
# unentered debits from loans
|
38
|
+
Nokogiri::XML(patron_loan_list).xpath("//loan").each do |_loan|
|
39
|
+
if fine = _loan.at_xpath("./fine").try(:content).presence
|
40
|
+
transactions << {
|
41
|
+
id: nil,
|
42
|
+
record: {
|
43
|
+
id: record_id(_loan)
|
44
|
+
},
|
45
|
+
reason: :overdue_fine,
|
46
|
+
type: :debit,
|
47
|
+
value: fine.to_f
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
self.class::Result.new(
|
53
|
+
transactions: transactions,
|
54
|
+
source: [patron_cash_list, patron_loan_list]
|
55
|
+
)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def creation_date(cash)
|
62
|
+
if date = cash.at_xpath("./z31/z31-date").try(:content).presence
|
63
|
+
Date.strptime(date, "%Y%m%d")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def id(cash)
|
68
|
+
cash.attr("href")[/[^\/]+\Z/][/\A[^?]+/]
|
69
|
+
end
|
70
|
+
|
71
|
+
def record_id(element)
|
72
|
+
element.at_xpath("./z13/z13-doc-number").try(:content).presence
|
73
|
+
end
|
74
|
+
|
75
|
+
def reason(cash)
|
76
|
+
case cash.at_xpath("./z31/z31-type").try(:content).presence
|
77
|
+
when /Kopierauftrag/ then :photocopy_request
|
78
|
+
when /Überfällig/ then :overdue_fine
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def type(cash)
|
83
|
+
case cash.attr("type")
|
84
|
+
when "credit" then :credit
|
85
|
+
when "debit" then :debit
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def description(cash)
|
90
|
+
cash.at_xpath("./z31/z31-description").try(:content).presence
|
91
|
+
end
|
92
|
+
|
93
|
+
def value(cash)
|
94
|
+
cash.at_xpath("./z31/z31-sum").try(:content).try(:[], /\d+.\d+/).try(:to_f)
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "nokogiri"
|
2
|
+
require "skala/adapter/renew_user_loan"
|
3
|
+
require_relative "../aleph_adapter"
|
4
|
+
require_relative "./resolve_user"
|
5
|
+
|
6
|
+
class Skala::AlephAdapter::RenewUserLoan < Skala::Adapter::RenewUserLoan
|
7
|
+
include parent::ResolveUser
|
8
|
+
|
9
|
+
def call(username, loan_id, options = {})
|
10
|
+
resolved_user_id = resolve_user(username)
|
11
|
+
|
12
|
+
raw_aleph_response = adapter.restful_api.patron(resolved_user_id).circulationActions.loans(loan_id).post
|
13
|
+
reply_code = Nokogiri::XML(raw_aleph_response).at_xpath("//reply-code").try(:content).try(:to_i)
|
14
|
+
|
15
|
+
if reply_code == 0
|
16
|
+
adapter.class::RenewUserLoan::Result.new(
|
17
|
+
source: raw_aleph_response
|
18
|
+
)
|
19
|
+
else
|
20
|
+
if reply_code == 28
|
21
|
+
raise self.class::RenewFailedError
|
22
|
+
else
|
23
|
+
raise adapter.class::RequestFailedError
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "nokogiri"
|
2
|
+
require "skala/adapter/renew_user_loans"
|
3
|
+
require_relative "../aleph_adapter"
|
4
|
+
require_relative "./resolve_user"
|
5
|
+
|
6
|
+
class Skala::AlephAdapter::RenewUserLoans < Skala::Adapter::RenewUserLoans
|
7
|
+
include parent::ResolveUser
|
8
|
+
|
9
|
+
def call(username, loan_ids = nil, options = {})
|
10
|
+
resolved_user_id = resolve_user(username)
|
11
|
+
|
12
|
+
if loan_ids.blank? # renew all
|
13
|
+
raw_aleph_response = adapter.restful_api.patron(resolved_user_id).circulationActions.loans.post
|
14
|
+
successfully_renewed_loans_xpath = "//loan/status[contains(text(), 'success')]/parent::*"
|
15
|
+
|
16
|
+
adapter.class::RenewUserLoans::Result.new(
|
17
|
+
renewed_loans: begin
|
18
|
+
Nokogiri::XML(raw_aleph_response).xpath(successfully_renewed_loans_xpath).map do |_loan|
|
19
|
+
{
|
20
|
+
id: _loan.attr("id"),
|
21
|
+
due_date: new_due_date(_loan)
|
22
|
+
}
|
23
|
+
end
|
24
|
+
end,
|
25
|
+
source: raw_aleph_response
|
26
|
+
)
|
27
|
+
else
|
28
|
+
raise "Unimplemented"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def new_due_date(loan)
|
35
|
+
if date = loan.at_xpath("./new-due-date").try(:content)
|
36
|
+
Date.strptime(date, "%Y%m%d")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative "../aleph_adapter"
|
2
|
+
|
3
|
+
module Skala::AlephAdapter::ResolveUser
|
4
|
+
# @depends_on instance methode #adapter
|
5
|
+
def resolve_user(username, options = {})
|
6
|
+
username = username.upcase
|
7
|
+
user_library = options[:user_library] || adapter.default_user_library
|
8
|
+
|
9
|
+
x_services_result = adapter.x_services.post(
|
10
|
+
op: "bor-by-key",
|
11
|
+
bor_id: username,
|
12
|
+
library: user_library
|
13
|
+
)
|
14
|
+
|
15
|
+
x_services_result.match(/<internal-id>(.*)<\/internal-id>/) do |_match_data|
|
16
|
+
_match_data.captures.first
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require "skala/adapter/update_user"
|
2
|
+
require_relative "../aleph_adapter"
|
3
|
+
require_relative "./resolve_user"
|
4
|
+
|
5
|
+
class Skala::AlephAdapter::UpdateUser < Skala::Adapter::UpdateUser
|
6
|
+
include parent::ResolveUser
|
7
|
+
|
8
|
+
def call(username, options = {})
|
9
|
+
username = username.upcase # ensure that username/id is always upcased
|
10
|
+
valid_update_options = options.select { |_key, _| respond_to?("update_#{_key}", true) }.to_h
|
11
|
+
|
12
|
+
#
|
13
|
+
# Updating multiple properties in one go is a non trivial task, especially
|
14
|
+
# if one of n updates fails, which implies rollbacks or partial update
|
15
|
+
#
|
16
|
+
if valid_update_options.keys.length > 1
|
17
|
+
raise ArgumentError.new("Only one property can be changed within one call!")
|
18
|
+
elsif valid_update_options.keys.length < 1
|
19
|
+
raise ArgumentError.new("Unknown property to update!")
|
20
|
+
end
|
21
|
+
|
22
|
+
property_name, new_value = [valid_update_options.keys.first, valid_update_options.values.first]
|
23
|
+
send("update_#{property_name}", username, new_value, options)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def update_email_address(user_id, new_email_address, options = {})
|
29
|
+
user_library = options[:user_library] || adapter.default_user_library
|
30
|
+
resolved_user_id = resolve_user(user_id)
|
31
|
+
|
32
|
+
raw_aleph_responses = ["01", "02"].map do |_z304_address_type|
|
33
|
+
adapter.x_services.post(
|
34
|
+
op: :update_bor,
|
35
|
+
update_flag: "Y",
|
36
|
+
library: user_library,
|
37
|
+
xml_full_req: <<-XML.strip_heredoc
|
38
|
+
<?xml version="1.0"?>
|
39
|
+
<p-file-20>
|
40
|
+
<patron-record>
|
41
|
+
<z303>
|
42
|
+
<match-id-type>00</match-id-type>
|
43
|
+
<match-id>#{resolved_user_id}</match-id>
|
44
|
+
<record-action>X</record-action>
|
45
|
+
</z303>
|
46
|
+
<z304>
|
47
|
+
<record-action>U</record-action>
|
48
|
+
<z304-id>#{resolved_user_id}</z304-id>
|
49
|
+
<z304-address-type>#{_z304_address_type}</z304-address-type>
|
50
|
+
<z304-sequence>01</z304-sequence>
|
51
|
+
<z304-email-address>#{new_email_address}</z304-email-address>
|
52
|
+
</z304>
|
53
|
+
</patron-record>
|
54
|
+
</p-file-20>
|
55
|
+
XML
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
if raw_aleph_responses.none? { |_raw_aleph_response| _raw_aleph_response[/Succeeded to REWRITE table z304/] }
|
60
|
+
raise Skala::Adapter::Error
|
61
|
+
end
|
62
|
+
|
63
|
+
return true # if no exception was thrown so far
|
64
|
+
end
|
65
|
+
|
66
|
+
def update_password(user_id, new_password, options = {})
|
67
|
+
user_library = options[:user_library] || adapter.default_user_library
|
68
|
+
resolved_user_id = resolve_user(user_id)
|
69
|
+
|
70
|
+
# we have to change the password for all ids
|
71
|
+
[resolved_user_id, user_id].uniq.each do |_user_id|
|
72
|
+
_id_type = (_user_id == resolved_user_id) ? "00" : "01"
|
73
|
+
|
74
|
+
raw_aleph_response = adapter.x_services.post(
|
75
|
+
op: :update_bor,
|
76
|
+
update_flag: "Y",
|
77
|
+
library: user_library,
|
78
|
+
xml_full_req: <<-XML.strip_heredoc
|
79
|
+
<?xml version="1.0"?>
|
80
|
+
<p-file-20>
|
81
|
+
<patron-record>
|
82
|
+
<z303>
|
83
|
+
<match-id-type>#{_id_type}</match-id-type>
|
84
|
+
<match-id>#{_user_id}</match-id>
|
85
|
+
<record-action>X</record-action>
|
86
|
+
</z303>
|
87
|
+
<z308>
|
88
|
+
<record-action>U</record-action>
|
89
|
+
<z308-key-type>#{_id_type}</z308-key-type>
|
90
|
+
<z308-key-data>#{_user_id}</z308-key-data>
|
91
|
+
<z308-verification>#{new_password}</z308-verification>
|
92
|
+
</z308>
|
93
|
+
</patron-record>
|
94
|
+
</p-file-20>
|
95
|
+
XML
|
96
|
+
)
|
97
|
+
|
98
|
+
unless raw_aleph_response[/Succeeded to REWRITE table z308/]
|
99
|
+
raise Skala::Adapter::Error
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
return true # if no exception was thrown so far
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative "../skala"
|
2
|
+
|
3
|
+
module Skala::CommonAttributes
|
4
|
+
include Virtus.model
|
5
|
+
|
6
|
+
attribute :ils_record_id
|
7
|
+
attribute :search_engine_record_id
|
8
|
+
|
9
|
+
attribute :contributor
|
10
|
+
attribute :created
|
11
|
+
attribute :creator
|
12
|
+
attribute :creation_date
|
13
|
+
attribute :edition
|
14
|
+
attribute :language
|
15
|
+
attribute :place_of_publication
|
16
|
+
attribute :publisher
|
17
|
+
attribute :signature
|
18
|
+
attribute :title
|
19
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "active_support"
|
2
|
+
require "active_support/core_ext"
|
3
|
+
require "elasticsearch"
|
4
|
+
require "skala/adapter"
|
5
|
+
|
6
|
+
class Skala::ElasticsearchAdapter < Skala::Adapter
|
7
|
+
require_relative "elasticsearch_adapter/search"
|
8
|
+
|
9
|
+
attr_accessor :hosts
|
10
|
+
attr_accessor :index
|
11
|
+
attr_accessor :timeout
|
12
|
+
attr_accessor :type
|
13
|
+
|
14
|
+
def hosts=(value)
|
15
|
+
@hosts = value.try(:map) { |host| host.deep_symbolize_keys }
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(options = {})
|
19
|
+
HashWithIndifferentAccess.new(options).try do |_options|
|
20
|
+
self.hosts = _options[:hosts] || _options[:host] || _options[:urls] || _options[:url]
|
21
|
+
self.index = _options[:index]
|
22
|
+
self.timeout = _options[:timeout]
|
23
|
+
self.type = _options[:type]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# internal api between adapter and operations
|
29
|
+
#
|
30
|
+
def elasticsearch_client
|
31
|
+
Elasticsearch::Client.new hosts: @hosts
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "skala/adapter/search"
|
2
|
+
require_relative "../elasticsearch_adapter"
|
3
|
+
|
4
|
+
class Skala::ElasticsearchAdapter::Search < Skala::Adapter::Search
|
5
|
+
require_relative "./search/request_transformation"
|
6
|
+
require_relative "./search/result_transformation"
|
7
|
+
|
8
|
+
def call(search_request, options = {})
|
9
|
+
elasticsearch_request = {
|
10
|
+
body: RequestTransformation.new.call(search_request),
|
11
|
+
index: @adapter.index
|
12
|
+
}
|
13
|
+
|
14
|
+
elasticsearch_result = @adapter.elasticsearch_client.search(elasticsearch_request)
|
15
|
+
|
16
|
+
ResultTransformation.new.call(elasticsearch_result, search_request: search_request)
|
17
|
+
rescue Elasticsearch::Transport::Transport::Errors::BadRequest
|
18
|
+
raise Skala::Adapter::BadRequestError
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "transformator/transformation"
|
2
|
+
require_relative "../search"
|
3
|
+
|
4
|
+
class Skala::ElasticsearchAdapter::Search::RequestTransformation < Transformator::Transformation
|
5
|
+
require_directory "#{File.dirname(__FILE__)}/request_transformation"
|
6
|
+
|
7
|
+
def call(source, options = {})
|
8
|
+
options[:target] ||= {}
|
9
|
+
super(source, options)
|
10
|
+
end
|
11
|
+
|
12
|
+
sequence [
|
13
|
+
AddAggregations,
|
14
|
+
AddFrom,
|
15
|
+
AddQuery,
|
16
|
+
AddSize,
|
17
|
+
AddSort,
|
18
|
+
AddVersion
|
19
|
+
]
|
20
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "transformator/transformation/step"
|
2
|
+
require_relative "../request_transformation"
|
3
|
+
|
4
|
+
class Skala::ElasticsearchAdapter::Search::RequestTransformation::
|
5
|
+
AddAggregations < Transformator::Transformation::Step
|
6
|
+
|
7
|
+
def call
|
8
|
+
source.facets.try(:each) do |_facet|
|
9
|
+
target["aggregations"] ||= {}
|
10
|
+
|
11
|
+
elasticsearch_aggregation =
|
12
|
+
if _facet.is_a?(Skala::Adapter::Search::Request::HistogramFacet)
|
13
|
+
{
|
14
|
+
"histogram" => {
|
15
|
+
"field" => _facet.field,
|
16
|
+
"interval" => _facet.interval
|
17
|
+
}
|
18
|
+
.compact
|
19
|
+
}
|
20
|
+
elsif _facet.is_a?(Skala::Adapter::Search::Request::RangeFacet)
|
21
|
+
{
|
22
|
+
"range" => {
|
23
|
+
"field" => _facet.field,
|
24
|
+
"ranges" => _facet.ranges.map do |_range|
|
25
|
+
{
|
26
|
+
"key" => _range.key,
|
27
|
+
"from" => _range.from,
|
28
|
+
"to" => _range.to
|
29
|
+
}
|
30
|
+
.compact
|
31
|
+
end
|
32
|
+
}
|
33
|
+
}
|
34
|
+
elsif _facet.is_a?(Skala::Adapter::Search::Request::TermsFacet)
|
35
|
+
{
|
36
|
+
"terms" => {
|
37
|
+
"field" => _facet.field,
|
38
|
+
"size" => _facet.size,
|
39
|
+
"shard_size" => (_facet.size * 3 if _facet.size)
|
40
|
+
}
|
41
|
+
.compact
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
if elasticsearch_aggregation
|
46
|
+
target["aggregations"][_facet.name] = elasticsearch_aggregation
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require "transformator/transformation/step"
|
2
|
+
require_relative "../request_transformation"
|
3
|
+
|
4
|
+
class Skala::ElasticsearchAdapter::Search::RequestTransformation::
|
5
|
+
AddFrom < Transformator::Transformation::Step
|
6
|
+
|
7
|
+
def call
|
8
|
+
target["from"] = source.from
|
9
|
+
end
|
10
|
+
end
|