From 8823f97254549eb5074276e5f9f19a41cb3a2ce5 Mon Sep 17 00:00:00 2001 From: "OHASHI, Norikazu" Date: Mon, 6 May 2019 11:58:46 +0900 Subject: [PATCH] =?utf8?q?=E6=9B=B8=E7=B1=8D=E6=83=85=E5=A0=B1=E3=81=AE?= =?utf8?q?=E6=8E=A2=E7=B4=A2=E5=85=88=E3=81=A8=E3=81=97=E3=81=A6=E5=9B=BD?= =?utf8?q?=E7=AB=8B=E5=9B=BD=E4=BC=9A=E5=9B=B3=E6=9B=B8=E9=A4=A8=E3=81=A8G?= =?utf8?q?oogleBooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- sinatra/app/models/books_db.rb | 175 +++++++++++++++++++++++++++++---- 1 file changed, 154 insertions(+), 21 deletions(-) diff --git a/sinatra/app/models/books_db.rb b/sinatra/app/models/books_db.rb index 00ea5d2..c74758b 100644 --- a/sinatra/app/models/books_db.rb +++ b/sinatra/app/models/books_db.rb @@ -6,6 +6,7 @@ require 'active_record' require 'mysql2' require 'httpclient' require 'json' +require "rexml/document" require 'digest/sha2' # DB設定ファイルの読み込み @@ -76,6 +77,12 @@ class BookManager # openBDから取得 SEARCH_ON_OPENBD = 2 + # Google Books から取得 + SEARCH_ON_GBS = 3 + + # 国立国会図書館 から取得 + SEARCH_ON_NDL = 3 + # ISBNの文字列から "-" を削除 # @param [String] isbn 処理対象のISBN # @return [String] 変換後のISBN @@ -128,27 +135,50 @@ class BookManager return book_hash end + # 書影のURLを国立図書館のAPIより取得する。 + # @param [String] isbn 対象のISBN + # @return [String] 取得したURI + def self.getCover(isbn) + cover_uri = "https://iss.ndl.go.jp/thumbnail/#{isbn}" + client = HTTPClient.new + res = client.get(cover_uri) + + if (res.status == 200) + return cover_uri + else + return nil + end + end + + # 著者種別から各関係者ハッシュのキーを取得 + # @param [String] job 著者種別 + # @return [Symbol] ハッシュキー + def self.getParsonKey(job) + case job + when "著", "著者", "作者", "作" then + key = :author + when "イラスト", "画", "作画" then + key = :illustrator + when "翻訳", "訳" then + key = :translator + when "原著", "原" then + key = :original_author + when "監修", "監" then + key = :supervisor + else + key = :author + end + return key + end + # openBDの著者情報から各関係者ハッシュを作成 # @param [String] parsons 著者情報 # @return [Hash] 関係者ハッシュ - def self.getParsons(parsons) + def self.getParsonsFromOpenBD(parsons) parsons_hash = {} parsons.split(" ").each do |item| - name, jobs = item.split("/") - case jobs - when "著", "著者", "作者", "作" then - key = :author - when "イラスト", "画", "作画" then - key = :illustrator - when "翻訳", "訳" then - key = :translator - when "原著", "原" then - key = :original_author - when "監修", "監" then - key = :supervisor - else - key = :author - end + name, job = item.split("/") + key = getParsonKey(job) if ( parsons_hash[key] == nil || parsons_hash[key] = "") parsons_hash[key] = name else @@ -176,7 +206,7 @@ class BookManager return nil end book = books[0]["summary"] - parsons = getParsons(book["author"]) + parsons = getParsonsFromOpenBD(book["author"]) book_hash = { search_type: SEARCH_ON_OPENBD, isbn: book["isbn"], @@ -187,10 +217,105 @@ class BookManager original_author: parsons[:original_author], translator: parsons[:translator], supervisor: parsons[:supervisor], - illustrator: book[:illustrator], + illustrator: parsons[:illustrator], publisher: book["publisher"], pubdate: book["pubdate"], - cover_uri: book["cover"] + cover_uri: (book["cover"] != nil) && (book["cover"] != "") ? book["cover"] : getCover(isbn) + } + return book_hash + end + + # 国立国会図書館の著者情報から各関係者ハッシュを作成 + # @param [String] parsons 著者情報 + # @return [Hash] 関係者ハッシュ + def self.getParsonsFromNDL(parsons) + parsons_hash = {} + parsons.each do |item| + splitData = item.split(" ") + name = splitData[0...splitData.size-1].join(" ") + job = splitData[splitData.size-1] + key = getParsonKey(job) + if ( parsons_hash[key] == nil || parsons_hash[key] = "") + parsons_hash[key] = name + else + parsons_hash[key] += ", " + name + end + end + return parsons_hash + end + + # ISBNからopenBDを検索してハッシュで返却 + # @param [String] isbn + # @return [Hash] 書籍情報 + def self.getHashOfNDL(isbn) + client = HTTPClient.new + res = client.get("http://iss.ndl.go.jp/api/sru", + {'operation' => 'searchRetrieve', + 'query' => "isbn=#{isbn}", + 'recordSchema' => 'dcndl'}) + library_param = REXML::Document.new(res.body) + book_num = library_param.elements['//searchRetrieveResponse/numberOfRecords'].text.to_i + if (book_num < 1) + return nil + end + element_str = library_param.elements["//searchRetrieveResponse/records/record[#{book_num}]/recordData"].text + book_xml = REXML::Document.new(element_str) + book = book_xml.elements['//rdf:RDF/dcndl:BibResource/'] + creators = [] + book.elements.each('dc:creator') do |item| + creators << item.text + end + parsons = getParsonsFromNDL(creators) + book_hash = { + search_type: SEARCH_ON_OPENBD, + isbn: isbn, + title: book.elements['dcterms:title'] != nil ? book.elements['dcterms:title'].text : nil, + volume: book.elements['dcndl:volume/rdf:Description/rdf:value'] != nil ? book.elements['dcndl:volume/rdf:Description/rdf:value'].text.gsub(/[^\d]/, "").to_i : nil, + series: book.elements['dcndl:seriesTitle/rdf:Description/rdf:value'] != nil ? book.elements['dcndl:seriesTitle/rdf:Description/rdf:value'].text : nil, + author: parsons[:author], + original_author: parsons[:original_author], + translator: parsons[:translator], + supervisor: parsons[:supervisor], + illustrator: parsons[:illustrator], + publisher: book.elements['dcterms:publisher/foaf:Agent/foaf:name'] != nil ? book.elements['dcterms:publisher/foaf:Agent/foaf:name'].text : nil, + pubdate: book.elements['dcterms:date'] != nil ? book.elements['dcterms:date'].text.gsub(".","-") : nil, + cover_uri: getCover(isbn) + } + return book_hash + end + + # ISBNからGoogleBooksを検索してハッシュで返却 + # @param [String] isbn + # @return [Hash] 書籍情報 + def self.getHashOfGBS(isbn) + client = HTTPClient.new + res = client.get("https://www.googleapis.com/books/v1/volumes", q: "isbn:#{isbn}") + books = JSON.parse(res.body) + + if (books["totalItems"] > 1) + raise FailedGetInstance + end + if (books["totalItems"] < 1) + return nil + end + if (books["items"] == nil || books["items"][0] == nil) + return nil + end + book = books["items"][0]["volumeInfo"] + book_hash = { + search_type: SEARCH_ON_GBS, + isbn: isbn, + title: book["title"], + volume: book["volume"], + series: nil, + author: book["authors"].join(", "), + original_author: nil, + translator: nil, + supervisor: nil, + illustrator:nil, + publisher: book["publisher"], + pubdate: book["publishedDate"], + cover_uri: (book["imageLinks"] != nil) ? book["imageLinks"]["thumbnail"] : getCover(isbn) } return book_hash end @@ -219,8 +344,10 @@ class BookManager end private_class_method :toIsbn, :deleteBookOfCollection, - :getHashOfBooks, :getParsons, :getHashOfOpenBD, - :createBookHash + :getHashOfBooks, :getParsonKey, :getCover, + :getParsonsFromOpenBD, :getHashOfOpenBD, + :getParsonsFromNDL, :getHashOfNDL, + :getHashOfGBS, :createBookHash # 書影情報登録 # @param [String] isbn 画像を登録するISBN @@ -297,6 +424,12 @@ class BookManager if (book_info == nil) book_info = getHashOfOpenBD(isbn) end + if (book_info == nil) + book_info = getHashOfNDL(isbn) + end + if (book_info == nil) + book_info = getHashOfGBS(isbn) + end if (book_info == nil) book_info = {isbn: isbn} end -- 2.19.2