エンジニアらしく本を整理したい... 「Yahoo Web API を用いたバーコード読み取りによる本整理術」

[株式会社サムザップ](https://www.sumzap.co.jp/)で [SRE](https://ameblo.jp/tech-yoshi/entry-12558857802.html) をしているれおすけです。[サムザップ #2 AdventCalendar 2020](https://qiita.com/advent-calendar/2020/sumzap2) の12/13(日)の記事です。

昨日は[＠ohbashunsuke](https://qiita.com/ohbashunsuke)さんの「[【Unity】シーン、Prefab内に含む任意の文字列を検索するSearchStringInAssetsを作りました](https://qiita.com/ohbashunsuke/private/0ba8ab2d3253f5617a0e)」でした。

# 概要
近々、引越をしようと思っており、我が家にある本を改めて本を整理しようと思い立ちました。しかし、天井まである本棚を3つ... そして、うまくベットの下の空間も活かした収納スペースも埋めつつある本。（そう、私は本の虫... 漫画以外は物理的な本を好みます。）

それでも、デカいモニター下の空間まではみ出ています。
![P_20201207_004835.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145853/fbfd5746-ba5e-49ff-143a-9157a75e244f.jpeg)
どうせ整理するならエンジニアらしく管理してみようと思いました。

# やること
本を以下の種類に分類し、物理的にも電子的にも（目録を作って）管理したいと思います。

|分類|管理方法|備考|
|:-:|:-:|:-:|
|よく読む本 |手元におく||
|たまに読む本|本棚（取り出しやすい位置）||
|たまに見たくなる漫画 |本棚（取り出しやすい位置）||
|読まないけど取っておきたい本 | 段ボール|目録化 必須|
|古い技術書、もう読まない本|処分(したいけど、一旦段ボール)|目録化 必須|

処分するために一旦段ボールと言いつつ、きっととっておいてしまうと思ってします。

# 構成
![Screen Shot 2020-12-12 at 1.44.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145853/80af2d17-b5e0-0c2e-d5da-8e08757991b8.png)
※ 最初はこの方法でやろうと思ったのですが、手入力が辛く... 断念しそうだと思いました。

![Screen Shot 2020-12-12 at 1.38.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145853/5c43a09f-374f-7ae1-37ac-5180a8d6b5f7.png)
※ 幸いにもバーコードリーダーを持っていたので、読み取り作業を簡略化することができました。

## ISBN と ISBN検索
本は全て International Standard Book Number (国際標準本番号)で一意に特定されます。しかし、前述の通り ISBN は手入力しなければならず、面倒ですが最初はそれに気づかず ISBN で検索する方法を探していました。

|API|提供元|参考URL|
|:-:|:-:|:-:|
|Google Books APIs |グーグル合同会社|https://developers.google.com/books/ |
|外部提供インタフェース|国立国会図書館|https://iss.ndl.go.jp/information/api/|
（そして私の保有している本には[ある問題](http://isbn-00-323081-7.blogspot.com/)が...）

## JAN CODE と JAN CODE検索
日本で売買される本のほとんどに JAN CODE（バーコード）がついています。書店で管理に使われるくらい汎用的に普及しており、JAN CODE で商品検索できる API が多数提供されています。

|API|提供元|参考URL|
|:-:|:-:|:-:|
|Yahoo Web API |ヤフー株式会社|https://developer.yahoo.co.jp/appendix/rate.html|
|楽天商品検索API|楽天株式会社 |https://webservice.rakuten.co.jp/api/ichibaitemsearch/|
|Product Advertising API|アマゾンジャパン合同会社（アマゾン合同会社）|https://webservices.amazon.com/paapi5/documentation/|

それぞれのサービスの登録方法も含めて、検討した結果、Yahoo Web API を選択しました。登録も簡単でAPIの呼び出し方もリクエストURLに GET PARAMETER で CLIENT_ID を送るだけなので、とても利用しやすいです。

# ソースコード①
ベースとなるバーコードを受け取り、Yahoo Web API で検索した結果をパースして返すプログラムです。元々、インフラエンジニアのため、最高速度で開発できるのは C言語か bash の shellscript です。今回は扱いやすさを重視して、shellscript を選択しました。
 
``` BarcodeReader.sh
     1	#!/usr/bin/env bash
     2
     3	## for safety
     4	set -u          # undefined variable check
     5	set -e          # interupt at errors
     6	set -o pipefail # interupt at pipe errors
     7
     8	## READER
     9	JAN_CODE=$1
    10	CLIENT_ID='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
    11	URL="https://shopping.yahooapis.jp/ShoppingWebService/V3/itemSearch?appid=${CLIENT_ID}&jan_code=${JAN_CODE}"
    12
    13	#echo $URL
    14	## RESPONCE without Errors
    15	responce=`curl ${URL} 2> /dev/null`
    16
    17	## PARSER
    18	echo $responce  | jq -r '.hits[0]| [.name , .description, .image.medium, .url] |@csv'
```
## 詳細解説
```
     1	#!/usr/bin/env bash
```
よく `#!/bin/bash` と書き始めますが、`/bin/`にあるとは限りません。また、`#!/bin/sh`で bash記法を用いるのはなんとなく嫌なので、きちんと環境に合わせた書き方をします。

```
     3	## for safety
     4	set -u          # undefined variable check
     5	set -e          # interupt at errors
     6	set -o pipefail # interupt at pipe errors
```
開発のおまじないとして、いろいろな保険をきちんと設定しておきます。未定義の変数チェック、パイプやコマンドのエラーがあれば停止するようにしておきます。

```
    11	URL="https://shopping.yahooapis.jp/ShoppingWebService/V3/itemSearch?appid=${CLIENT_ID}&jan_code=${JAN_CODE}"
    12
    13	#echo $URL
```
シンプルに `CLIENT_ID` を GETパラメータに渡すだけで商品検索ができる素敵な仕様のAPIです。必要があれば、echo コマンドで出力結果を確認できるようにしておきます。

```
    14	## RESPONCE without Errors
    15	responce=`curl ${URL} 2> /dev/null`
```
デバッグ時はエラーを表示しますが、稼働中はエラーメッセージは捨てます。curl コマンドでリクエストした結果（JSON）を変数に入れます。

```
    17	## PARSER
    18	echo $responce  | jq -r '.hits[0]| [.name , .description, .image.medium, .url] |@csv'
```
変数に入れたレスポンス（JSON）を jq コマンドで、絞り込みと CSV 変換します。 `.hits[0]` で、レスポンスの1つ目に絞り込みます。1つ目のレスポンスデータを `name（商品名）`、`description（商品説明）`、`image（画像）の中で medium（中くらい）`、`url（商品URL）`という４つの項目に絞り込みます。最後に CSV に変換して出力します。

# ソースコード②
``` Wrapper.sh
     1	#!/usr/bin/env bash
     2
     3	## safe
     4	set -u          # undefined variable check
     5	set -e          # interupt at errors
     6	set -o pipefail # interupt at pipe errors
     7
     8	while IFS='$\n' read -r line; do
     9	    # Search with JAN Code per input
    10	    sh BarcodeReader.sh $line
    11	done
```
入力を単に JAN Code 検索に流すためのラッパーを使います。バーコード読み取りデバイスは汎用ドライバで動き、キーボードとして認識されます。読み取った内容は、バーコードの実際の数値と改行コードとして扱われるので、シンプルに構成することができました。

## 詳細解説
```
     8	while IFS='$\n' read -r line; do
     9	    # Search with JAN Code per input
    10	    sh BarcodeReader.sh $line
    11	done
```
8行目で入力があり続ける間、改行コードをのぞき `$line` という変数に代入します。
10行目で入力された値を `BarcodeReader.sh` に渡して処理します。

# 実行方法
```
sh Wrapper.sh | tee -a result.csv
```
Wrapper.sh を実行した結果を tee コマンドで標準出力に吐きながら、result.csv にも出力します。エラーで中断した後も続きから入力できるように追記モード実行するようにします。毎回同じコマンドで実行することができます。

# 出力サンプル
```
"C言語によるスーパーLinuxプログラミング","本 ISBN:9784797361209 飯尾淳／著 出版社:SBクリエイティブ 出版年月:2011年06月 サイズ:505P 21cm コンピュータ ≫ UNIX [ Linux ] シ-ゲンゴ ニ ヨル ス-パ- リナツクス プログラミング 登録日:2013/04/03 ※ページ内の情報は告知なく変更になることがあります。","https://item-shopping.c.yimg.jp/i/g/dss_9784797361209","https://store.shopping.yahoo.co.jp/dss/9784797361209.html"
```
（大学時代に特別講義で教わった恩師である飯尾先生の本です。とても良本なのでぜひ読んでみてください）

# まとめ
ISBN が一意ではなくなることで弊害が見つかるなど、規格やルールを守ることの大切さを学びました。また、画像処理とか開発に時間のかかることをせず、小一時間でさくっとシステムを作れて良かったです。

サクサクと開発することで、途中で嫌にならずに整理できるシステムを作成しました。エンジニアとしてあるものは利用して開発し、それがピタッとハマって動くと気持ち良いですね。
インプットもアウトプットもシンプルにすることでどんどん目録を作成し、目録を Google SpeadSheet で分類し、それを物理的にも分類できます。

システム作って満足せず、最後まできちんと本を分類したいと思います。


# 最後に
サムザップは今年から [Sumzap Engineering Vision](https://tech.sumzap.co.jp/entry/look-back-sumzap-engineering-vision) を定めました。その中に「積極的な発信」という項目があります。アドベントカレンダーはまさにそれを体現していると思います。

そして、サムザップのアドベントカレンダーは今年も 2つあります。多彩なジャンルに渡って記事がありますので、ぜひ読んでみてください！！
[サムザップ #1 Advent Calendar 2020 - Qiita](https://qiita.com/advent-calendar/2020/sumzap1)
[サムザップ #2 Advent Calendar 2020 - Qiita](https://qiita.com/advent-calendar/2020/sumzap2)

明日は[@Gaku_Ishii](https://qiita.com/Gaku_Ishii)さんの記事です。お楽しみに！


# 参考文献
https://qiita.com/shutokawabata0723/items/d136a04b715de59ade57
https://qiita.com/seihmd/items/4cafe204403ac2889145