app/models/nacsis_cat.rb
# encoding: utf-8
class NacsisCat
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :record
class Error < StandardError
def initialize(raw_result, message = nil)
super(message)
@raw_result = raw_result
end
attr_reader :raw_result
end
class ClientError < Error; end
class ServerError < Error; end
class UnknownError < Error; end
class NetworkError < StandardError
def initialize(orig_ex, message = nil)
message ||= orig_ex.message
super(message)
@original_exception = orig_ex
end
attr_reader :original_exception
end
class ResultArray < Array
def initialize(search_result)
@raw_result = search_result
@total = @raw_result.try(:[], 'total') || 0
if @raw_result.try(:[], 'records')
@raw_result['records'].each do |record|
self << NacsisCat.new(:record => record)
end
end
end
attr_reader :raw_result, :total
end
class << self
def print_log(t)
File.open("#{Rails.root}/log/nacsis_cat_#{Time.now.strftime('%Y%m%d')}.log", "a") do |file|
file.write("#{Time.now} #{t} \n")
end
end
# NACSIS-CAT検索を実行する。検索結果はNacsisCatオブジェクトの配列で返す。
# 検索条件は引数で指定する。サポートしている形式は以下の通り。
# * :dbs => [...] - 検索対象のDB名リスト: :book(一般書誌)、:serial(雑誌書誌)、:bhold(一般所蔵)、:shold(雑誌所蔵)、:all(:bookと:serialからの横断検索)
# * :opts => {...} - DBに対するオプション(ページ指定): 指定例: {:book => {:page => 2, :per_page => 30}, :serial => {...}}
# * :id => '...' - NACSIS-CATの書誌IDにより検索する(***)
# * :bid => '...' - NACSIS-CATの書蔵IDにより検索する(***)
# * :isbn => '...' - ISBN(ISBNKEY)により検索する(***)
# * :issn => '...' - ISSN(ISSNKEY)により検索する(***)
# * :nbn => '...' - NBN(NBN)により検索する(***)#
# * :query => '...' - 一般検索語により検索する(*)
# * :title => [...] - 書名(_TITLE_)により検索する(*)
# * :author => [...] - 著者名(_AUTH_)により検索する(*)
# * :publisher => [...] - 出版者名(PUBLKEY)により検索する(*)
# * :subject => [...] - 件名(SHKEY)により検索する(*)
# * :except => {...} - 否定条件により検索する(*)(**)
#
# (*) :dbsが:bookまたは:serialのときのみ機能する
# (**) :query、:title、:author、:publisher、:subjectの否定形に対応
# (***) 配列で指定することもでき、その場合は指定した複数キーによるOR検索となる
#
# :dbsには基本的に複数のDBを指定する。
# 検索結果は {:book => aResultArray, ...} のような形となる。
# なお、複数DBを指定した場合、すべてのDBに対して同じ条件で検索を行う。
# このため、たとえば :dbs => [:book, :bhold] のように
# まったく違う種類のDBを指定してもうまく動作しない。
def search(*args)
options = args.extract_options!
options.assert_valid_keys(
:dbs, :opts,
:id, :isbn, :issn, :nbn,
:query, :title, :author, :publisher, :subject, :except)
if options[:except]
options[:except].assert_valid_keys(
:query, :title, :author, :publisher, :subject)
end
dbs = options.delete(:dbs) || [:book]
db_opts = options.delete(:opts) || {}
if options.blank? || options.keys == [:except]
return {}.tap do |h|
dbs.each {|db| h[db] = ResultArray.new(nil) }
end
end
if (dbs.include?(:shold) || dbs.include?(:bhold)) &&
options.include?(:id)
options[:bid] = options.delete(:id)
end
query = build_query(options)
search_by_gateway(dbs: dbs, opts: db_opts, query: query)
end
# 指定されたNCIDによりNACSIS-CAT検索を行い、得られた情報からManifestationを作成する
#
# * ncid - NCID
# * book_types - 書籍の書誌種別(ManifestationType)の配列
# (NOTE: バッチ時の外部キャッシュ用で和書・洋書にあたるレコードを与える)
# * nacsis_cat - NacsisCat.searchを既に実行している場合、取得したNacsisCatモデルを設定する
def create_manifestation_from_ncid(ncid, book_types = ManifestationType.book.all, nacsis_cat = nil)
raise ArgumentError if ncid.blank?
if nacsis_cat.nil?
result = NacsisCat.search(dbs: [:book], id: ncid)
nacsis_cat = result[:book].first
end
create_manifestation_from_nacsis_cat(nacsis_cat, book_types)
end
# 指定されたNCIDによりNACSIS-CAT検索を行い、得られた情報からSeriesStatementを作成する。
#
# * ncid - NCID
# * book_types - 書籍の書誌種別(ManifestationType)の配列
# (NOTE: バッチ時の外部キャッシュ用で和雑誌・洋雑誌にあたるレコードを与える)
# * nacsis_cat - NacsisCat.searchを既に実行している場合、取得したNacsisCatモデルを設定する
def create_series_statement_from_ncid(ncid, book_types = ManifestationType.series.all, nacsis_cat = nil)
raise ArgumentError if ncid.blank?
if nacsis_cat.nil?
result = NacsisCat.search(dbs: [:serial], id: ncid)
nacsis_cat = result[:serial].first
end
create_series_with_relation_from_nacsis_cat(nacsis_cat, book_types)
end
# 指定されたNCIDリストによりNACSIS-CAT検索を行い、得られた情報からManifestation, SeriesStatement を作成する
#
# * ncids - NCIDのリスト
# * opts
# * nacsis_batch_size - 一度に検索するNCID数
def batch_create_from_ncid(ncids, opts = {}, &block)
nacsis_batch_size = opts[:nacsis_batch_size] || 50
ncids.each_slice(nacsis_batch_size) do |ids|
result = NacsisCat.search(dbs: [:all], id: ids)
result[:all].each do |nacsis_cat|
if nacsis_cat.serial?
created_record =
create_series_statement_from_ncid(nacsis_cat.ncid, ManifestationType.series.all, nacsis_cat)
else
created_record =
create_manifestation_from_ncid(nacsis_cat.ncid, ManifestationType.book.all, nacsis_cat)
end
block.call(created_record) if block
end
end
end
# NACSISへ情報の登録・更新・削除を行い、結果データ(cat_container)を返却する
#
# * id - 編集対象のモデルの id
# BHOLD : Item.id
# SHOLD : Item.id
# BOOK : Manifestation.id
# SERIAL : SeriesStatement.id
#
# * db_type - NACSISへの編集対象となるDB名
# 図書所蔵 : 'BHOLD'
# 雑誌所蔵 : 'SHOLD'
# 図書書誌 : 'BOOK'
# 雑誌書誌 : 'SERIAL'
#
# * command - NACSISへ送信するコマンド名
# 登録 : 'insert'
# 更新 : 'update'
# 削除 : 'delete' (BOOK,SERIALの場合は実行不可)
#
def upload_info_to_nacsis(id, db_type, command)
return {} unless check_upload_params(id, db_type, command)
req_query = {}
case db_type
when 'BHOLD','SHOLD'
@item = Item.find(id)
req_query[:query] = hold_query(command, db_type)
result_id = @item.nacsis_identifier
when 'BOOK'
@manifestation = Manifestation.find(id)
if @manifestation.series_statement.try(:root_manifestation)
@manifestation = @manifestation.series_statement.root_manifestation
end
req_query[:query] = book_query(command)
result_id = @manifestation.nacsis_identifier
when 'SERIAL'
@series_statement = SeriesStatement.find(id)
@manifestation = @series_statement.root_manifestation
req_query[:query] = serial_query(command)
result_id = @series_statement.nacsis_series_statementid
end
return {} unless req_query[:query]
req_query[:command] = command
req_query[:db_type] = db_type
req_query[:db_names] = [db_type]
result_info = {}
result_info = http_post_value(gateway_upload_cat_url, {:cat_container => req_query})
cat_container = result_info['cat_container']
return {} unless cat_container
if cat_container['catp_code'] == '200'
result_record = cat_container['result_records'].try(:first)
case db_type
when 'BHOLD','SHOLD'
if command == 'insert'
result_record = db_type == 'BHOLD' ? result_record['bhold_info'] : result_record['shold_info']
result_id = result_record['hold_id']
end
hold_id = command == 'delete' ? nil : result_id
@item.nacsis_identifier = hold_id
@item.save!
when 'BOOK'
result_id = result_record['book_info']['bibliog_id']
@manifestation.nacsis_identifier = result_id
@manifestation.save!
when 'SERIAL'
result_id = result_record['serial_info']['bibliog_id']
@series_statement.nacsis_series_statementid = result_id
@series_statement.save!
end
end
{ :return_code => cat_container['catp_code'],
:return_phrase => cat_container['catp_phrase'],
:result_id => result_id }
end
# 指定されたNBN(全国書誌番号)によりNACSIS-CAT検索を行い、得られた情報からManifestationを作成する
def create_manifestation_from_nbn(nbn, book_types = ManifestationType.book.all, nacsis_cat = nil)
raise ArgumentError if nbn.blank?
if nacsis_cat.nil?
result = NacsisCat.search(dbs: [:book], nbn: nbn)
nacsis_cat = result[:book].first
end
create_manifestation_from_nacsis_cat(nacsis_cat, book_types)
end
# 指定されたNBN(全国書誌番号)によりNACSIS-CAT検索を行い、得られた情報からManifestationを更新する
def update_manifestation_from_nbn(manifestation, book_types = ManifestationType.book.all, nacsis_cat = nil, index = nil)
raise ArgumentError if manifestation.blank?
raise ArgumentError if manifestation.nbn.blank?
if nacsis_cat.nil?
result = NacsisCat.search(nbn: manifestation.nbn)
nacsis_cat = result[:book].first
end
if nacsis_cat
print_log "--#{index}-- START to update Manifestation(#{manifestation.id}) IDENTIFIER: #{manifestation.identifier} NBN: #{manifestation.nbn}"
#TODO
catalog = Catalog.where(:display_name => 'NACSIS UPDATE', :name => 'NACSIS UPDATE', :nacsis_identifier => 'NACSIS UPDATE').first_or_create
manifestation.update_attribute('catalog_id', catalog.id)
begin
create_manifestation_from_nacsis_cat(nacsis_cat, book_types, manifestation)
rescue
print_log "Failed to update Manifestation(#{manifestation.id})"
print_log $!
print_log $@
end
end
end
# 指定されたISBNによりNACSIS-CAT検索を行い、書誌を特定できた場合Manifestationを更新する
def update_manifestation_from_isbn(manifestation, book_types = ManifestationType.book.all, nacsis_cat = nil, index = nil)
raise ArgumentError if manifestation.blank?
raise ArgumentError if manifestation.isbn.blank?
if nacsis_cat.nil?
result = NacsisCat.search(isbn: manifestation.isbn)
result[:book].size
end
if result[:book].size > 1
print_log "ISBN(#{manifestation.isbn})の検索結果は #{result[:book].size} 件です。更新できません。"
elsif nacsis_cat = result[:book].first
print_log "--#{index}-- START to update Manifestation(#{manifestation.id}) IDENTIFIER: #{manifestation.identifier} ISBN: #{manifestation.isbn}"
catalog = Catalog.where(:display_name => 'NACSIS UPDATE', :name => 'NACSIS UPDATE', :nacsis_identifier => 'NACSIS UPDATE').first_or_create
manifestation.update_attribute('catalog_id', catalog.id)
begin
create_manifestation_from_nacsis_cat(nacsis_cat, book_types, manifestation)
rescue
print_log "Failed to update Manifestation(#{manifestation.id})"
print_log $!
print_log $@
end
end
end
# 指定されたNBN(全国書誌番号)によりNACSIS-CAT検索を行い、得られた情報からSeriesStatementを作成する。
def create_series_statement_from_nbn(nbn, book_types = ManifestationType.series.all, nacsis_cat = nil)
raise ArgumentError if nbn.blank?
if nacsis_cat.nil?
result = NacsisCat.search(dbs: [:serial], nbn: nbn)
nacsis_cat = result[:serial].first
end
create_series_with_relation_from_nacsis_cat(nacsis_cat, book_types)
end
# 指定されたISBNによりNACSIS-CAT検索を行い、得られた情報からManifestationを作成する
def create_manifestation_from_isbn(isbn, book_types = ManifestationType.book.all, nacsis_cat = nil)
raise ArgumentError if isbn.blank?
if nacsis_cat.nil?
result = NacsisCat.search(dbs: [:book], isbn: isbn) # 複数あるかも
nacsis_cat = result[:book].first
end
create_manifestation_from_nacsis_cat(nacsis_cat, book_types)
end
# 指定されたISBNによりNACSIS-CAT検索を行い、得られた情報からSeriesStatementを作成する。
def create_series_statement_from_isbn(isbn, book_types = ManifestationType.series.all, nacsis_cat = nil)
raise ArgumentError if isbn.blank?
if nacsis_cat.nil?
result = NacsisCat.search(dbs: [:serial], isbn: isbn) #複数あるかも
nacsis_cat = result[:serial].first
end
create_series_with_relation_from_nacsis_cat(nacsis_cat, book_types)
end
private
DB_KEY = {
query: ['_TITLE_', '_AUTH_', 'PUBLKEY', 'SHKEY'],
title: '_TITLE_',
author: '_AUTH_',
publisher: 'PUBLKEY',
subject: 'SHKEY',
id: 'ID',
bid: 'BID',
isbn: 'ISBNKEY',
issn: 'ISSNKEY',
nbn: 'NBN',
}
def build_query(cond, inverse = false)
if inverse
op = 'OR'
else
op = 'AND'
end
except = cond.delete(:except)
segments = cond.map do |key, value|
case key
when :id, :bid, :isbn, :issn, :nbn
rpn_concat(
'OR',
[value].flatten.map {|v| rpn_seg(DB_KEY[key], v) })
when :title, :author, :publisher, :subject
rpn_concat(
op,
[value].flatten.map {|v| rpn_seg(DB_KEY[key], v) })
when :query
rpn_concat(
op,
[value].flatten.map do |v|
rpn_concat(
'OR', DB_KEY[:query].map {|k| rpn_seg(k, v) })
end
)
end
end
if except.blank?
rpn_concat(op, segments)
else
rpn_concat(
'AND-NOT', [
rpn_concat(op, segments),
build_query(except, true)
])
end
end
def rpn_concat(op, cond)
cond.inject([]) do |ary, c|
f = ary.empty?
ary << c
ary << op unless f
ary
end.join(' ')
end
def rpn_seg(key, value)
%Q!#{key}="#{value.to_s.gsub(/[\\"]/, '\\\1')}"!
end
def search_by_gateway(options)
# db_type = db_names = nil
key_to_db = {
all: '_ALL_',
book: 'BOOK',
serial: 'SERIAL',
bhold: 'BHOLD',
shold: 'SHOLD',
}
dbs = options[:dbs].map do |key|
db = key_to_db[key]
raise ArgumentError, "unknwon db: #{key}" unless db
db
end
db_opts = {}
options[:opts].each do |key, v|
db = key_to_db[key]
next unless db
next unless dbs.include?(db)
db_opts[db] = v
end
q = {}
q[:db] = dbs
q[:opts] = db_opts if db_opts.present?
q[:query] = options[:query]
url = "#{gateway_search_url}?#{q.to_query}"
begin
return_value = http_get_value(url)
rescue SocketError, SystemCallError => ex
raise NetworkError.new(ex)
end
case return_value['status']
when 'success'
ex = nil
when 'user-error'
ex = ClientError
when 'gateway-error'
ex = ServerError
when 'server-error'
ex = ServerError
else
ex = UnknownError
end
if ex
raise ex.new(return_value, return_value['phrase'])
end
ret = {}
db_to_key = key_to_db.invert
return_value['results'].each_pair do |db, result|
key = db_to_key[db]
ret[key] = ResultArray.new(result)
end
ret
end
def gateway_config
NACSIS_CLIENT_CONFIG[Rails.env]['gw_account']
end
def gateway_search_url
url = gateway_config['gw_url']
url.sub(%r{/*\z}, '/') + 'records'
end
def http_get_value(url)
uri = URI(url)
opts = {}
if uri.scheme == 'https'
opts[:use_ssl] = true
if gateway_config.include?('ssl_verify') &&
gateway_config['ssl_verify'] == false
# config/nacsis_client.ymlで'ssl_verify': falseのとき
opts[:verify_mode] = OpenSSL::SSL::VERIFY_NONE
else
opts[:verify_mode] = OpenSSL::SSL::VERIFY_PEER
end
end
resp = Net::HTTP.start(uri.host, uri.port, opts) do |h|
h.get(uri.request_uri)
end
JSON.parse(resp.body)
end
def check_upload_params(id, db_type, command)
return unless id
return unless (['BHOLD','SHOLD','BOOK','SERIAL'].include?(db_type))
return unless (['insert','update','delete'].include?(command))
case db_type
when 'BOOK','SERIAL'
return if command == 'delete'
end
return true
end
def hold_query(command, db_type)
return unless @item
return @item.nacsis_identifier if command == 'delete'
query_field = command == 'update' ? ["ID=#{@item.nacsis_identifier}"] : []
query_field += [
"FANO=#{gateway_config['federation_id']}",
"LOC=#{@item.shelf.library.nacsis_location_code}",
]
i = 0
@item.manifestation.subjects.each do |subject|
unless subject.subject_type.note == 'for nacsis data'
i += 1
query_field += [
"LTR=#{subject.term}"
]
end
break if i >= 4
end
if db_type == 'BHOLD'
if @item.manifestation.nacsis_identifier
query_field += ["BID=#{@item.manifestation.nacsis_identifier}"]
else
query_field += ["BID=#{@item.manifestation.series_statement.nacsis_series_statementid}"]
end
@item.manifestation.items.each do |item|
query_field += [
'<HOLD>',
"VOL=#{item.manifestation.vol_string}",
"CLN=#{item.call_number}",
"RGTN=#{item.item_identifier}",
"CPYR=#{item.manifestation.date_of_publication.try(:year)}",
"LDF=#{item.note}",
"CPYNT=#{item.manifestation.note}",
'</HOLD>'
]
end
else
cont = '+' if @item.manifestation.series_statement.publication_status.try(:name) == 'c'
query_field += [
"BID=#{@item.manifestation.series_statement.nacsis_series_statementid}",
"HLYR=#{shold_hl_info[:HLYR]}",
"HLV=#{shold_hl_info[:HLV]}",
"CONT=#{cont}",
"CLN=#{@item.manifestation.items.pluck(:call_number).reject{|c| c.blank?}.join("||")}",
"LDF=#{@item.manifestation.items.pluck(:note).reject{|n| n.blank?}.join("||")}",
"CPYNT=#{@item.manifestation.note}"
]
end
query_field.join("\n")
end
def shold_hl_info
hl_info = {}
hlyr = @item.manifestation.series_statement.manifestations.pluck(:date_of_publication_string).reject{|c| c.blank?}.sort
if hlyr.present?
hl_info[:HLYR] = hlyr[0] + '-' + hlyr[hlyr.count - 1]
end
if hl_info[:HLYR].blank?
hl_info[:HLYR] = '*'
end
hl_info[:HLV] = @item.manifestation.series_statement.manifestations.pluck(:volume_number_string).reject{|c| c.blank?}.join(",")
if hl_info[:HLV].blank?
hl_info[:HLV] = '*'
end
hl_info
end
def book_query(command)
return unless @manifestation
query_field = command == 'update' ? ["ID=#{@manifestation.nacsis_identifier}"] : []
# Common field
query_field += common_field
# Book field
query_field += book_field
query_field.join("\n")
end
def serial_query(command)
return unless @series_statement && @manifestation
query_field = command == 'update' ? ["ID=#{@series_statement.nacsis_series_statementid}"] : []
# Common field
query_field += common_field
# Serial field
query_field += serial_field
query_field.join("\n")
end
def common_field
source = @manifestation.catalog.nacsis_identifier if @manifestation.catalog
if source == 'NACSIS' || source == 'NDL' || source.nil?
source = 'ORG'
end
repro = 'c' if @manifestation.original == true
field = [
"MARCID=", # SOURCE=ORG 以外の場合必須
"SOURCE=#{source}", # [Required]
"ISSN=#{@manifestation.issn}",
"LCCN=#{@manifestation.lccn}",
"GPON=#{get_identifier_number('gpon')}",
"GMD=#{@manifestation.carrier_type.try(:nacsis_identifier)}",
"SMD=#{@manifestation.sub_carrier_type.try(:nacsis_identifier)}",
"CNTRY=#{@manifestation.country_of_publication.marc21}",
"REPRO=#{repro}",
"TTLL=#{get_nacsis_language('title')}",
"TXTL=#{get_nacsis_language('body')}",
"ORGL=#{get_nacsis_language('original')}",
"ED=#{@manifestation.edition_display_value}",
"NOTE=#{@manifestation.note}"
]
# YEAR Group [Required]
field += year_group
# TR Group [Required]
field += tr_group
# VT Group Repeat:16
field += vt_group
# PUB Group [Required] Repeat:4
field += pub_group
# PHYS Group
field += phys_group
# AL Group Repeat:24
field += al_group
# SH Group Repeat:24
field += sh_group
field
end
def book_field
field = []
get_identifier_numbers('ndlcn').each do |number|
field << "NDLCN=#{number}" # Repeat:255
end
get_identifier_other_numbers.each do |other_number|
field << "OTHN=#{other_number[0, 23]}" # Repeat:255
end
nbn_array = @manifestation.nbn.try(:split, ',') || []
nbn_array.each do |nbn_str|
field << "NBN=#{nbn_str}" # Repeat:255
end
# VOLG Group
field += volg_group
# CW Group
field += cw_group
# PTBL Group
field += ptbl_group
# UTL Group Repeat:255
field += utl_group
# CLS Group Repeat:24
field += cls_group
field
end
def get_identifier_other_numbers
return [] unless @manifestation
other_numbers = []
excluded_types = ['isbn','xisbn','issn','nbn','ndlcn','gpon','ndlpn','coden','ulpn']
@manifestation.identifiers.each do |identifier|
unless excluded_types.include?(identifier.identifier_type.name)
other_numbers << "#{identifier.identifier_type.name}:#{identifier.body}"
end
end
other_numbers
end
def serial_field
vlyr = []
@manifestation.manifestation_extexts.where(:name => 'VLYR').each do |extext|
vlyr << extext.value
end
result = [
"NDLPN=#{get_identifier_number('ndlpn')}",
"CODEN=#{get_identifier_number('coden')}",
"ULPN=#{get_identifier_number('ulpn')}",
"PSTAT=#{@series_statement.publication_status.try(:name)}",
"FREQ=#{@manifestation.frequency.try(:nii_code)}",
"REGL=#{}",
"TYPE=#{@manifestation.manifestation_type.try(:nacsis_identifier)}",
"VLYR=#{vlyr[0]}",
"VLYR=#{vlyr[1]}",
"VLYR=#{vlyr[2]}",
"VLYR=#{vlyr[3]}",
"PRICE=#{@manifestation.price_string}"
]
get_identifier_numbers('xissn').each do |xissn|
result << "XISSN=#{xissn}"
end
result
end
def get_identifier_number(type_name)
return unless @manifestation && type_name
identifier_type = IdentifierType.where(:name => type_name).first
if identifier_type
identifier = @manifestation.identifiers.where('identifier_type_id' => identifier_type.id).first
end
identifier.try(:body)
end
def get_identifier_numbers(type_name)
return [] unless @manifestation && type_name
numbers = []
identifier_type = IdentifierType.where(:name => type_name).first
if identifier_type
numbers = @manifestation.identifiers.where('identifier_type_id' => identifier_type.id).pluck(:body)
end
numbers
end
def volg_group # book only
results = []
identifier_type = IdentifierType.where(:name => 'isbn').first
manifestations = @manifestation.series_statement.try(:manifestations)
if manifestations
manifestations.each do |manifestation|
unless @manifestation.series_statement.root_manifestation == manifestation
identifier = manifestation.identifiers.where(:identifier_type_id => identifier_type.id).first
results += [
'<VOLG>',
"VOL=#{manifestation.edition_display_value}",
"ISBN=#{identifier.try(:body)}",
"PRICE=#{manifestation.price_string}",
"XISBN=#{manifestation.wrong_isbn}",
'</VOLG>'
]
end
end
else
identifier = @manifestation.identifiers.where(:identifier_type_id => identifier_type.id).first
results = [
'<VOLG>',
"VOL=#{@manifestation.edition_display_value}",
"ISBN=#{identifier.try(:body)}",
"PRICE=#{@manifestation.price_string}",
"XISBN=#{@manifestation.wrong_isbn}",
'</VOLG>'
]
end
results
end
def year_group
[
'<YEAR>',
"YEAR1=#{@manifestation.pub_date.try(:[], 0, 4)}",
"YEAR2=#{@manifestation.dis_date.try(:[], 0, 4)}",
'</YEAR>'
]
end
def tr_group
alternatives = @manifestation.title_alternative.try(:split, '||') || []
[
'<TR>',
"TRD=#{@manifestation.original_title}",
"TRR=#{@manifestation.title_transcription}",
"TRVR=#{alternatives[0]}",
"TRVR=#{alternatives[1]}",
'</TR>'
]
end
def vt_group
results = []
type_ids = TitleType.where("note = 'for nacsis' and name <> 'UTL'").pluck(:id)
if type_ids.present?
@manifestation.work_has_titles.where(title_type_id: type_ids).each do |wht|
alternatives = wht.manifestation_title.title_alternative.try(:split, '||') || []
results += [
'<VT>',
"VTK=#{wht.title_type.name}",
"VTD=#{wht.manifestation_title.title}",
"VTR=#{wht.manifestation_title.title_transcription}",
"VTVR=#{alternatives[0]}",
"VTVR=#{alternatives[1]}",
'</VT>'
]
end
end
results
end
def pub_group
[
'<PUB>',
"PUBP=#{@manifestation.place_of_publication}",
"PUBL=#{@manifestation.publishers.first.try(:full_name)}",
"PUBDT=#{@manifestation.date_of_publication_string}",
"PUBF=#{}",
'</PUB>'
]
end
def phys_group
phys_array = @manifestation.size.try(:split,'||',-1)
results = []
if phys_array.try(:size) == 4
results += [
'<PHYS>',
"PHYSP=#{phys_array[0]}",
"PHYSI=#{phys_array[1]}",
"PHYSS=#{phys_array[2]}",
"PHYSA=#{phys_array[3]}",
'</PHYS>'
]
end
results
end
def cw_group # book only
results = []
child_manifestations = @manifestation.derived_manifestations || []
child_manifestations.each do |manifestation|
cwvr_array = manifestation.title_alternative.try(:split,'||') || []
results += [
'<CW>',
"CWT=#{manifestation.original_title}",
"CWA=#{manifestation.creators.first.try(:full_name)}",
"CWR=#{manifestation.title_transcription}",
"CWVR=#{cwvr_array[0]}",
"CWVR=#{cwvr_array[1]}",
'</CW>'
]
end
results
end
def ptbl_group # book only
results = []
parent_manifestations = @manifestation.original_manifestations || []
parent_manifestations.each do |manifestation|
if manifestation.nacsis_identifier
parent_nacsis_cat = NacsisCat.search(dbs: [:book], id: manifestation.nacsis_identifier)
parent_nacsis_cat = parent_nacsis_cat[:book].try(:first)
if parent_nacsis_cat
results += [
'<PTBL>',
"PTBID=#{manifestation.nacsis_identifier}",
"PTBK=#{manifestation.children.first.manifestation_relationship_type.try(:name)}",
"PTBNO=#{manifestation.note}",
'</PTBL>'
]
end
end
end
results
end
def al_group
results = []
@manifestation.creators.each do |creator|
if creator.agent_identifier
results += [
'<AL>',
"AID=#{creator.agent_identifier}",
"AF=#{@manifestation.creates.where(:agent_id => creator.id).first.create_type.try(:name)}",
"AFLG=#{}",
'</AL>'
]
else
alternatives = creator.full_name_alternative.try(:split, '||') || []
results += [
'<AL>',
"AHDNG=#{creator.full_name}",
"AHDNGR=#{creator.full_name_transcription}",
"AHDNGVR=#{alternatives[0]}",
"AHDNGVR=#{alternatives[1]}",
"AF=#{@manifestation.creates.where(:agent_id => creator.id).first.create_type.try(:name)}",
"AFLG=#{}",
'</AL>'
]
end
end
results
end
def utl_group # book only
results = []
title_type = TitleType.find_by_name('UTL')
utl_titles = @manifestation.manifestation_titles.where('work_has_titles.title_type_id' => title_type.id)
utl_titles.each do |title|
if title.nacsis_identifier
results += [
'<UTL>',
"UTID=#{title.nacsis_identifier}",
"UTINFO=#{title.note}",
"UTFLG=#{}",
'</UTL>'
]
else
alternatives = title.title_alternative.try(:split, '||') || []
results += [
'<UTL>',
"UTHDNG=#{title.title}",
"UTHDNGR=#{title.title_transcription}",
"UTHDNGVR=#{alternatives[0]}",
"UTHDNGVR=#{alternatives[1]}",
"UTINFO=#{title.note}",
"UTFLG=#{}",
'</UTL>'
]
end
end
results
end
def cls_group # book only
[
'<CLS>',
"CLSK=#{}",
"CLSD=#{}",
'</CLS>'
]
end
def sh_group
results = []
@manifestation.subjects.where(:note => 'for nacsis data').each do |subject|
alternatives = subject.term_alternative.try(:split, '||') || []
results += [
'<SH>',
"SHT=#{'NDLSH'}", # 件名標目表の種類コード表のテーブルが必要
"SHD=#{subject.term}",
"SHK=#{subject.subject_type.name}",
"SHR=#{subject.term_transcription}",
"SHVR=#{alternatives[0]}",
"SHVR=#{alternatives[1]}",
'</SH>'
]
end
results
end
def get_nacsis_language(type_name)
languages = []
language_type = LanguageType.where(:name => type_name)
if language_type
work_has_languages = @manifestation.work_has_languages.where(:language_type_id => language_type)
languages = work_has_languages.map {|whl| whl.language.iso_639_2 }
end
languages.join
end
def gateway_upload_cat_url
"#{gateway_config['gw_url']}cat/gateway.json"
end
def http_post_value(url, query)
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
resp = http.post(uri.path, query.to_query)
JSON.parse(resp.body)
end
def create_manifestation_from_nacsis_cat(nacsis_cat, book_types, manifestation = nil)
return nil if nacsis_cat.blank?
ActiveRecord::Base.transaction do
child_manifestation = nil
child_manifestation = new_root_manifestation_from_nacsis_cat(nacsis_cat, book_types, manifestation)
created_manifestations = []
created_manifestations << child_manifestation
ptbk = {}
# 親書誌情報の登録
nacsis_cat.detail[:ptb_info].each do |ptbl_record|
parent_manifestation = Manifestation.where(:nacsis_identifier => ptbl_record['PTBID']).first
if parent_manifestation
created_manifestations << parent_manifestation
else
parent_nacsis_cat = NacsisCat.search(dbs: [:book], id: ptbl_record['PTBID'])
parent_nacsis_cat = parent_nacsis_cat[:book].try(:first)
if parent_nacsis_cat
created_manifestations << new_root_manifestation_from_nacsis_cat(parent_nacsis_cat, book_types)
else
unless ptbl_record['PTBTR'].nil?
created_manifestations <<
Manifestation.where(:original_title => ptbl_record['PTBTR']).first_or_create do |m|
if m.new_record?
m.nacsis_identifier = ptbl_record['PTBID']
m.title_transcription = ptbl_record['PTBTRR']
m.title_alternative = arraying(ptbl_record['PTBTRVR']).join('||')
m.note = ptbl_record['PTBNO']
end
end
end
end
end
ptbk[ptbl_record['PTBID']] = ptbl_record['PTBK']
end
# 親書誌関係の登録
created_manifestations.reverse.each do |parent|
created_manifestations.each do |child|
break if parent == child
parent.derived_manifestations << child
end
# 構造の種類設定
parent.derived_manifestations.each do |derived|
derived.parents.each do |child|
child.manifestation_relationship_type_id = ManifestationRelationshipType.where(:name => ptbk[parent.nacsis_identifier]).first.try(:id)
child.save!
end
end
end
# 内容著作注記の登録
nacsis_cat.detail[:cw_info].each do |cw_record|
attrs = {}
attrs[:original_title] = cw_record['CWT']
attrs[:title_transcription] = cw_record['CWR']
attrs[:title_alternative] = arraying(cw_record['CWVR']).join('||')
unless cw_record['CWA'].nil?
attrs[:creators] = []
attrs[:creators] << Agent.where(:full_name => cw_record['CWA'].to_s).first_or_create
end
child_manifestation.derived_manifestations << Manifestation.create(attrs)
end
if manifestation
print_log "Updated Manifestation(#{manifestation.id})"
else
print_log "Created Manifestation(#{child_manifestation.id})"
end
child_manifestation
end
end
def new_root_manifestation_from_nacsis_cat(nacsis_cat, book_types, manifestation = nil)
case nacsis_cat.detail[:vol_info].size
when 0,1 # VOLGが0/1件の場合
# NCIDに該当するManifestationが既にある場合は既存のManifestationを更新する
manifestation = Manifestation.where(:nacsis_identifier => nacsis_cat.ncid).first unless manifestation
root_manifestation = new_manifestation_from_nacsis_cat(nacsis_cat, book_types, {}, manifestation)
else # VOLGが2件以上の場合
# NCIDに該当するManifestationが既にある場合は既存のManifestationを更新する
root_manifestation = Manifestation.where(:nacsis_identifier => nacsis_cat.ncid).first
unless root_manifestation
root_manifestation = new_manifestation_from_nacsis_cat(nacsis_cat, book_types, {})
end
series_statement = new_series_statement_from_nacsis_cat(nacsis_cat, root_manifestation)
series_statement.periodical = false
series_statement.root_manifestation = root_manifestation
root_manifestation.series_statement = series_statement
root_manifestation.periodical_master = true
root_manifestation.save!; series_statement.save!
manifestation.series_statement = series_statement if manifestation
nacsis_cat.detail[:vol_info].each do |volg|
volg_manifestation = new_manifestation_from_nacsis_cat(nacsis_cat, book_types, volg)
volg_manifestation.series_statement = series_statement
end
print_log "Updated SeriesStatement(#{series_statement.id})"
print_log I18n.t('nacsis_cat.too_many_vlog_manifestations', :series_statement_id => series_statement.id, :manifestation_ids => series_statement.manifestations.where(:periodical_master => false).map(&:id)) if series_statement.manifestations.where(:periodical_master => false).size > nacsis_cat.detail[:vol_info].size
end
root_manifestation
end
def new_manifestation_from_nacsis_cat(nacsis_cat, book_types, volg_info = {}, manifestation = nil)
return nil if nacsis_cat.blank? # || book_types.blank?
nacsis_info = nacsis_cat.detail
attrs = {}
if nacsis_info[:source].nil?
attrs[:catalog_id] = Catalog.where(:name => 'nacsis').first.id
else
attrs[:catalog_id] = Catalog.where(:nacsis_identifier => nacsis_info[:source]).first.id
end
attrs[:original_title] = nacsis_info[:subject_heading]
attrs[:title_transcription] = nacsis_info[:subject_heading_reading]
attrs[:title_alternative] = nacsis_info[:title_alternative]
attrs[:place_of_publication] = nacsis_info[:publication_place].try(:join, ",")
attrs[:date_of_publication_string] = nacsis_info[:publication_date].try(:join, ",")
attrs[:note] = nacsis_info[:note]
attrs[:marc_number] = nacsis_info[:marc]
attrs[:pub_date] = nacsis_info[:year1]
attrs[:dis_date] = nacsis_info[:year2]
attrs[:lccn] = nacsis_info[:lccn]
attrs[:issn] = nacsis_info[:issn]
attrs[:carrier_type_id] = CarrierType.where(:nacsis_identifier => nacsis_info[:gmd]).first.try(:id)
attrs[:sub_carrier_type_id] = SubCarrierType.where(:nacsis_identifier => nacsis_info[:smd]).first.try(:id)
attrs[:original] = true if nacsis_info[:repro] == 'c'
attrs[:edition_display_value] = nacsis_info[:ed]
if nacsis_info[:size].present?
size_array = [
nacsis_info[:size].try(:[],'PHYSP'),
nacsis_info[:size].try(:[],'PHYSI'),
nacsis_info[:size].try(:[],'PHYSS'),
nacsis_info[:size].try(:[],'PHYSA')
]
attrs[:size] = size_array.join('||')
end
# 出版国がnilの場合、unknownを設定する。
if nacsis_info[:pub_country]
attrs[:country_of_publication] = nacsis_info[:pub_country]
else
attrs[:country_of_publication] = Country.where(:name => 'unknown').first
end
# テキストの言語により、和書または洋書を設定する。
if nacsis_info[:text_language].present?
if nacsis_info[:text_language].first.name == 'Japanese'
attrs[:manifestation_type] = book_types.detect {|bt| /japanese/io =~ bt.name }
attrs[:jpn_or_foreign] = 0
else
attrs[:manifestation_type] = book_types.detect {|bt| /foreign/io =~ bt.name }
attrs[:jpn_or_foreign] = 1
end
else
attrs[:manifestation_type] = book_types.detect {|bt| "unknown" == bt.name }
attrs[:jpn_or_foreign] = nil
end
Manifestation.transaction do
# 関連テーブル:著者の設定
attrs[:creators] = []
af = {}
nacsis_info[:creators].each do |creator|
#TODO 著者名典拠IDが存在する場合、nacsisの著者名典拠DBからデータを取得する。
attrs[:creators] <<
Agent.where(:full_name => creator['AHDNG'].to_s).first_or_create do |p|
if p.new_record?
p.agent_identifier = creator['AID']
p.full_name_transcription = creator['AHDNGR']
p.full_name_alternative = arraying(creator['AHDNGVR']).join('||')
end
end
af[creator['AHDNG']] = creator['AF']
end
# 関連テーブル:出版者の設定
attrs[:publishers] = []
nacsis_info[:publishers].each do |pub|
attrs[:publishers] << Agent.where(:full_name => pub.to_s).first_or_create
end
# 関連テーブル:件名の設定
attrs[:subjects] = []
nacsis_info[:subjects].each do |subject|
subject_type = SubjectType.find_or_create_by_name(subject['SHK'])
if subject['SHD'].present? && subject_type
sub = Subject.where(["term = ? and subject_type_id = ?", subject['SHD'].to_s, subject_type.id]).first
if sub
attrs[:subjects] << sub
else
attrs[:subjects] << Subject.create(:term => subject['SHD'],
:term_transcription => subject['SHR'],
:term_alternative => arraying(subject['SHVR']).join('||'),
:subject_type_id => subject_type.id)
end
end
end
attrs[:identifiers] = []
if nacsis_info[:gpon]
identifier_type = IdentifierType.where(:name => 'gpon').first_or_create
attrs[:identifiers] <<
Identifier.create(:body => nacsis_info[:gpon], :identifier_type_id => identifier_type.id)
end
if nacsis_cat.book?
unless nacsis_info[:vol_info].size >= 1 && volg_info.present?
attrs[:nacsis_identifier] = nacsis_cat.ncid
attrs[:nbn] = nacsis_info[:nbn]
end
attrs[:ndc] = get_latest_ndc(nacsis_info[:cls_info])
# 関連テーブル:版冊次の設定
if volg_info.present?
manifestation = get_volg_manifestation(nacsis_info[:nbn], volg_info['VOL'])
if volg_info['ISBN']
identifier_type = IdentifierType.where(:name => 'isbn').first_or_create
attrs[:identifiers] <<
Identifier.create(:body => volg_info['ISBN'], :identifier_type_id => identifier_type.id)
end
attrs[:edition_display_value] = volg_info['VOL']
attrs[:price_string] = volg_info['PRICE']
attrs[:wrong_isbn] = volg_info['XISBN']
end
if nacsis_info[:ndlcn].present?
identifier_type = IdentifierType.where(:name => 'ndlcn').first_or_create
nacsis_info[:ndlcn].uniq.each do |ndlcn|
attrs[:identifiers] <<
Identifier.create(:body => ndlcn, :identifier_type_id => identifier_type.id)
end
end
nacsis_info[:other_number].each do |othn|
othn_array = othn.split(':')
name = othn_array[0]
val = othn_array[1]
unless name.nil? || val.nil?
identifier_type = IdentifierType.where(:name => name.downcase).first_or_create
attrs[:identifiers] <<
Identifier.create(:body => val, :identifier_type_id => identifier_type.id)
end
end
else # root_manifestation用
attrs[:nacsis_identifier] = nacsis_cat.ncid
nacsis_info[:xissn].each do |xissn|
identifier_type = IdentifierType.where(:name => 'xissn').first_or_create
attrs[:identifiers] <<
Identifier.create(:body => xissn, :identifier_type_id => identifier_type.id)
end
if nacsis_info[:ndlpn]
identifier_type = IdentifierType.where(:name => 'ndlpn').first_or_create
attrs[:identifiers] <<
Identifier.create(:body => nacsis_info[:ndlpn], :identifier_type_id => identifier_type.id)
end
if nacsis_info[:coden]
identifier_type = IdentifierType.where(:name => 'coden').first_or_create
attrs[:identifiers] <<
Identifier.create(:body => nacsis_info[:coden], :identifier_type_id => identifier_type.id)
end
if nacsis_info[:ulpn]
identifier_type = IdentifierType.where(:name => 'ulpn').first_or_create
attrs[:identifiers] <<
Identifier.create(:body => nacsis_info[:ulpn], :identifier_type_id => identifier_type.id)
end
if nacsis_info[:ndlcln]
identifier_type = IdentifierType.where(:name => 'ndlcln').first_or_create
attrs[:identifiers] <<
Identifier.create(:body => nacsis_info[:ndlcln], :identifier_type_id => identifier_type.id)
end
if nacsis_info[:ndlhold]
identifier_type = IdentifierType.where(:name => 'ndlhold').first_or_create
attrs[:identifiers] <<
Identifier.create(:body => nacsis_info[:ndlhold], :identifier_type_id => identifier_type.id)
end
if nacsis_info[:freq]
attrs[:frequency_id] = Frequency.find_by_nii_code(nacsis_info[:freq]).try(:id) || Frequency.find_by_nii_code('u').try(:id)
end
attrs[:manifestation_type_id] = ManifestationType.where(:nacsis_identifier => nacsis_info[:type]).first.try(:id)
attrs[:price_string] = nacsis_info[:price]
end
if manifestation
print_log "update manifestation(#{manifestation.id}) IDENTIFIER: #{manifestation.identifier}"
# TODO 既存のその他の識別子を削除してから新規登録する仕様でよいか?
manifestation.identifiers.destroy_all
manifestation.update_attributes!(attrs)
else
manifestation = Manifestation.create!(attrs)
print_log "create manifestaton(#{manifestation.id}) IDENTIFIER: #{attrs[:identifier]}"
end
manifestation.work_has_languages = new_work_has_languages_from_nacsis_cat(nacsis_cat,manifestation)
manifestation.work_has_titles = new_work_has_titles_from_nacsis_cat(nacsis_cat)
if nacsis_info[:vlyr]
vlyr_ary = []
nacsis_info[:vlyr].each do |vlyr|
vlyr_ary << ManifestationExtext.new(:name => 'VLYR', :value => vlyr)
end
manifestation.manifestation_extexts = vlyr_ary
end
# 関連テーブル:著者 役割表示の設定
manifestation.creates.each do |cre|
cre.create_type_id = CreateType.where(:name => af[manifestation.creators.where(:id => cre.agent_id).first.full_name]).first.try(:id)
cre.save!
end
manifestation
end
end
def create_series_with_relation_from_nacsis_cat(nacsis_cat, book_types)
return nil if nacsis_cat.blank? || book_types.blank?
# 元の雑誌情報作成
series_statement = create_series_statement_from_nacsis_cat(nacsis_cat, book_types)
# 遍歴ファミリーの作成
relationship_family = create_family_from_fid(nacsis_cat.fid)
if relationship_family
# 元の雑誌をファミリーに紐づける
relationship_family.series_statements = []
relationship_family.series_statements << series_statement
nacsis_cat.detail[:bhn_info].each do |bhn|
result_bhn = NacsisCat.search(dbs: [:serial], id: bhn['BHBID'])
nacsis_cat_bhn = result_bhn[:serial].first
# 遍歴の雑誌情報作成
series_statement_bhn = SeriesStatement.where(:nacsis_series_statementid => nacsis_cat_bhn.ncid).first
if series_statement_bhn.nil?
series_statement_bhn = create_series_statement_from_nacsis_cat(nacsis_cat_bhn, book_types)
end
# 雑誌同士の関連情報作成
series_statement_relationship = SeriesStatementRelationship.new(:seq => 1, :source => 1)
if relationship_before?(bhn['BHK'].to_s)
series_statement_relationship.before_series_statement_relationship = series_statement_bhn
series_statement_relationship.after_series_statement_relationship = series_statement
else
series_statement_relationship.before_series_statement_relationship = series_statement
series_statement_relationship.after_series_statement_relationship = series_statement_bhn
end
series_statement_relationship.series_statement_relationship_type = get_relationship_type(bhn['BHK'].to_s)
series_statement_relationship.relationship_family = relationship_family
series_statement_relationship.save!
# 遍歴ファミリーに遍歴の雑誌情報を関連付ける
relationship_family.series_statements << series_statement_bhn
end
end
series_statement
end
def create_series_statement_from_nacsis_cat(nacsis_cat, book_types)
return nil if nacsis_cat.blank? || book_types.blank?
series_statement = SeriesStatement.where(:nacsis_series_statementid => nacsis_cat.ncid).first
if series_statement.nil?
series_statement = new_series_statement_from_nacsis_cat(nacsis_cat)
series_statement.periodical = true
root_manifestation = new_manifestation_from_nacsis_cat(nacsis_cat, book_types)
root_manifestation.periodical_master = true
root_manifestation.save!
series_statement.root_manifestation = root_manifestation
series_statement.manifestations << series_statement.root_manifestation
series_statement.save!
end
series_statement
end
def new_series_statement_from_nacsis_cat(nacsis_cat, root_manifestation = nil)
return nil if nacsis_cat.blank?
series_statement = root_manifestation.series_statement
series_statement = SeriesStatement.where(:root_manifestation_id => root_manifestation.id).first unless series_statement && !root_manifestation
series_statement = SeriesStatement.new unless series_statement
nacsis_info = nacsis_cat.detail
attrs = {}
attrs[:nacsis_series_statementid] = nacsis_cat.ncid
attrs[:original_title] = nacsis_info[:subject_heading]
attrs[:title_transcription] = nacsis_info[:subject_heading_reading]
attrs[:issn] = nacsis_info[:issn]
attrs[:note] = nacsis_info[:note]
attrs[:publication_status_id] = PublicationStatus.find_by_name(nacsis_info[:pstat]).try(:id)
series_statement.assign_attributes(attrs)
return series_statement
end
def new_work_has_languages_from_nacsis_cat(nacsis_cat, manifestation)
return [] if nacsis_cat.blank?
nacsis_info = nacsis_cat.detail
whl_ary = []
{:title_language => 'title', :text_language => 'body', :original_language => 'original'}.each do |lang, type|
nacsis_info[lang].each do |language|
whl = WorkHasLanguage.new
whl.language = language
whl.language_type = LanguageType.find_by_name(type)
whl.work = manifestation
whl_ary << whl
end
end
whl_ary
end
def new_work_has_titles_from_nacsis_cat(nacsis_cat)
return [] if nacsis_cat.blank?
nacsis_info = nacsis_cat.detail
wht_ary = []
nacsis_info[:other_titles].each do |other_title|
wht = WorkHasTitle.new
title = Title.find_by_title(other_title['VTD'])
if title
wht.manifestation_title = title
else
wht.manifestation_title =
Title.create(:title => other_title['VTD'],
:title_transcription => other_title['VTR'],
:title_alternative => arraying(other_title['VTVR']).join('||'))
end
wht.title_type = TitleType.find_or_create_by_name(other_title['VTK'])
wht_ary << wht
end
if nacsis_cat.book?
nacsis_info[:utl_info].each do |utl_info|
wht = WorkHasTitle.new
title = Title.find_by_nacsis_identifier(utl_info['UTID'])
if title
wht.manifestation_title = title
else
wht.manifestation_title =
Title.create(:title => utl_info['UTHDNG'],
:title_transcription => utl_info['UTHDNGR'],
:title_alternative => arraying(utl_info['UTHDNGVR']).join('||'),
:note => utl_info['UTINFO'],
:nacsis_identifier => utl_info['UTID'])
end
wht.title_type = TitleType.find_or_create_by_name('UTL')
wht_ary << wht
end
end
wht_ary
end
def create_family_from_fid(fid)
return nil if fid.nil?
RelationshipFamily.where(:fid => fid).first_or_create do |rf|
rf.display_name = "CHANGE_#{fid}" if rf.new_record?
end
end
def get_latest_ndc(cls_hash)
return nil if cls_hash.blank?
return_val = nil
['NDC9','NDC8','NDC7','NDC6','NDC'].each do |ndc|
if cls_hash[ndc]
return_val = cls_hash[ndc]
break
end
end
return_val
end
def get_volg_manifestation(nbn, vol)
return nil if nbn.blank? || vol.blank?
manifestation = Manifestation.where(:nbn => nbn, :edition_display_value => vol).first
manifestation = Manifestation.where(:nbn => nbn, :volume_number_string => vol).first unless manifestation
volume_numbers = [vol.gsub(I18n.t('nacsis_cat.replace_volume_1'),''),
vol.gsub(I18n.t('nacsis_cat.replace_volume_2'),''),
vol.gsub(/#{I18n.t('nacsis_cat.replace_volume_1')}|#{I18n.t('nacsis_cat.replace_volume_2')}/,'')]
manifestation = Manifestation.where(['nbn = ? AND volume_number_string in (?)', nbn, volume_numbers]).first unless manifestation
return manifestation
end
def get_relationship_type(type_str)
return nil if type_str.nil?
case type_str[0, 1]
when 'C' # 継続
SeriesStatementRelationshipType.where(:typeid => '1').first
when 'A' # 吸収
SeriesStatementRelationshipType.where(:typeid => '2').first
when 'S' # 派生
SeriesStatementRelationshipType.where(:typeid => '3').first
else # 未登録
SeriesStatementRelationshipType.where(:typeid => '30').first
end
end
def relationship_before?(type_str)
return nil if type_str.nil?
if type_str[1, 1] == 'F' # 前誌
true
else # 後誌
false
end
end
def arraying(obj)
case true
when obj.blank?
[]
when obj.is_a?(Array)
obj
else
[obj]
end
end
end
def initialize(*args)
options = args.extract_options!
options.assert_valid_keys(:record)
@record = options[:record]
end
def book?
!serial?
end
def serial?
@record['_DBNAME_'] == 'SERIAL'
end
def item?
@record['_DBNAME_'] == 'BHOLD' || @record['_DBNAME_'] == 'SHOLD'
end
def ncid
@record['ID']
end
def isbn
if book?
map_attrs(@record['VOLG'], 'ISBN').compact
else
nil
end
end
def issn
@record['ISSN']
end
def fid
if serial?
@record['FID']
else
nil
end
end
def nbn
if book?
arraying(@record['NBN']).compact
else
nil
end
end
def class_id_pair
return nil if serial?
hash = {}
arraying(@record['CLS']).each do |cl|
hash.store(cl['CLSK'], cl['CLSD'])
end
hash
end
def manifestation
Manifestation.find_by_nacsis_identifier(@record['ID'])
end
def summary
return nil unless @record
if item?
hash = {
:database => @record['_DBNAME_'],
:hold_id => @record['ID'],
:library_abbrev => @record['LIBABL'],
:cln => map_attrs(@record['HOLD'], 'CLN').join(' '),
:rgtn => map_attrs(@record['HOLD'], 'RGTN').join(' '),
}
else
hash = {
:subject_heading => @record['TR'].try(:[], 'TRD'),
:publisher => map_attrs(@record['PUB']) {|x| [x['PUBL'], x['PUBDT']] },
}
if serial?
hash[:display_number] = [@record['VLYR']].flatten
else
hash[:series_title] =
map_attrs(@record['PTBL']) {|x| [x['PTBTR'], x['PTBNO']] }
end
end
hash
end
def detail
return nil unless @record
{
:subject_heading => @record['TR'].try(:[], 'TRD'),
:subject_heading_reading => @record['TR'].try(:[], 'TRR'),
:title_alternative => map_attrs(@record['TR'], 'TRVR').join('||'),
:other_titles => arraying(@record['VT']),
:publisher => map_attrs(@record['PUB']) {|pub| join_attrs(pub, ['PUBP', 'PUBL', 'PUBDT', 'PUBF'], ',') },
# :publish_year => join_attrs(@record['YEAR'], ['YEAR1', 'YEAR2'], '-'),
:year1 => @record['YEAR'].try(:[], 'YEAR1'),
:year2 => @record['YEAR'].try(:[], 'YEAR2'),
:physical_description => join_attrs(@record['PHYS'], ['PHYSP', 'PHYSI', 'PHYSS', 'PHYSA'], ';'),
:pub_country => @record['CNTRY'].try {|cntry| Country.where(:marc21 => cntry).first },
:title_language => get_languages(@record['TTLL']),
:text_language => get_languages(@record['TXTL']),
:original_language => get_languages(@record['ORGL']),
:author_heading => map_attrs(@record['AL']) do |al|
if al['AHDNG'].blank? && al['AHDNGR'].blank?
nil
elsif al['AHDNG'] && al['AHDNGR']
"#{al['AHDNG']}(#{al['AHDNGR']})"
else
al['AHDNG'] || al['AHDNGR']
end
end.compact,
:subject => map_attrs(@record['SH'], 'SHD').compact.uniq,
:note => arraying(@record['NOTE']).compact.join(" "),
:publication_place => map_attrs(@record['PUB'], 'PUBP').compact.uniq,
:publication_date => map_attrs(@record['PUB'], 'PUBDT').compact.uniq,
:size => @record['PHYS'],
:creators => arraying(@record['AL']),
:publishers => map_attrs(@record['PUB'], 'PUBL').compact.uniq,
:subjects => arraying(@record['SH']),
:marc => @record['MARCID'],
:lccn => @record['LCCN'],
:gpon => @record['GPON'],
:source => @record['SOURCE'],
:gmd => @record['GMD'],
:smd => @record['SMD'],
:repro => @record['REPRO'],
:ed => @record['ED'],
:issn => issn
}.tap do |hash|
if book?
hash[:vol_info] = arraying(@record['VOLG'])
hash[:cw_info] = arraying(@record['CW'])
hash[:nbn] = nbn.join(",")
hash[:ndlcn] = arraying(@record['NDLCN'])
hash[:other_number] = arraying(@record['OTHN'])
hash[:ptb_info] = arraying(@record['PTBL'])
hash[:utl_info] = arraying(@record['UTL'])
hash[:cls_info] = class_id_pair
else
hash[:xissn] = arraying(@record['XISSN'])
hash[:price] = @record['PRICE']
hash[:fid] = fid
hash[:pstat] = @record['PSTAT']
hash[:freq] = @record['FREQ']
hash[:type] = @record['TYPE']
hash[:bhn_info] = arraying(@record['BHNT'])
hash[:ndlpn] = @record['NDLPN']
hash[:coden] = @record['CODEN']
hash[:ulpn] = @record['ULPN']
hash[:ndlcln] = @record['NDLCLN']
hash[:ndlhold] = @record['NDLHOLD']
hash[:vlyr] = arraying(@record['VLYR'])
end
hash[:ncid] = ncid
end
end
def request_summary
return nil unless @record
{
:subject_heading => @record['TR'].try(:[], 'TRD'),
:publisher => map_attrs(@record['PUB']) {|pub| join_attrs(pub, ['PUBP', 'PUBL', 'PUBDT'], ',') }.join(' '),
:pub_date => join_attrs(@record['YEAR'], ['YEAR1', 'YEAR2'], '-'),
:physical_description => join_attrs(@record['PHYS'], ['PHYSP', 'PHYSI', 'PHYSS', 'PHYSA'], ';'),
:series_title => if book?
map_attrs(@record['PTBL']) {|x| [x['PTBTR'], x['PTBNO']].compact.join(' ') }.join(',')
else
nil
end,
:isbn => isbn.try(:join, ','),
:pub_country => @record['CNTRY'], # :pub_country => @record['CNTRY'].try {|cntry| Country.where(:alpha_2 => cntry.upcase).first }, # XXX: 国コード体系がCountryとは異なる: http://www.loc.gov/marc/countries/countries_code.html
:title_language => @record['TTLL'].try {|lang| Language.where(:iso_639_2 => lang).first },
:text_language => @record['TXTL'].try {|lang| Language.where(:iso_639_2 => lang).first },
:classmark => if book?
map_attrs(@record['CLS']) {|cl| join_attrs(cl, ['CLSK', 'CLSD'], ':') }.join(';')
else
nil
end,
:author_heading => map_attrs(@record['AL']) do |al|
if al['AHDNG'].blank? && al['AHDNGR'].blank?
nil
elsif al['AHDNG'] && al['AHDNGR']
"#{al['AHDNG']}(#{al['AHDNGR']})"
else
al['AHDNG'] || al['AHDNGR']
end
end.compact.join(','),
:subject => map_attrs(@record['SH'], 'SHD').join(','),
:ncid => ncid,
}.tap do |hash|
end
end
def persisted?
false
end
private
def map_attrs(str_or_ary, key = nil, &block)
return [] unless str_or_ary
ary = [str_or_ary].flatten
if block
ary.map(&block)
else
ary.map {|x| x[key] }
end
end
def join_attrs(obj, keys, str)
if obj
ary = keys.map {|k| obj[k] }.compact
ary.blank? ? nil : ary.join(str)
else
obj
end
end
def arraying(obj)
case true
when obj.blank?
[]
when obj.is_a?(Array)
obj
else
[obj]
end
end
def get_languages(lang_str)
languages = []
if lang_str.is_a?(String)
lang_str.each_char.each_slice(3).map{|a| a.join}.each do |lang|
#if lang == 'und'
# languages << Language.where(:iso_639_2 => 'unknown').first
#else
languages << Language.where(:iso_639_2 => lang).first
#end
end
end
languages.compact
end
end