[python] [Gracenote Web API] pygnをちょこっとカスタマイズ

QiitaにこんなAPI扱ってる人いねーだろうと思いつつも投稿します。
技術ブログだから関連してたら何書いてもOKでしょ。
別にここで今日の晩飯について言及するようなことはありません。

## 2020/11/17 追記
Gracenote WebAPIが無料公開されなくなってしまったのでしょうか？
[https://developer.gracenote.com/web-api](https://developer.gracenote.com/web-api) が **NotFound** になってしまっています。
（そもそもGracenoteに登録してcliantIDとuserIDを取得することができない？）

Gracenote WebAPIが非公開になったか確認できるまで、当記事は過去ログとして放置しておきます。

## そもそもGracenoteとは？
iPodやらiPhoneを使ってる人の中では知らない人はいないであろうiTunesですが、CDを入れて楽曲のタグ付けをする際に使われているのがこのGracenote APIです。
古今東西ありとあらゆる楽曲が登録されていて、殊更日本においては同人音楽やらエロゲの予約特典のドラマCDまで認識する始末。
誰が登録してるんですかね？本当・・・（もうやだこの国・・・）

そんな優れもののAPIですが、iTunesに入ってるのはGNSDKといい何でもできるもの（C言語です）。
Web APIは簡易版ですが、結構細かい内容を返してくれます。
XMLを投げたらXMLで返してくれます。
（個人的にはJSONのほうが好きですが、）[ラッパー](https://developer.gracenote.com/web-api#wrappers)があるので何とかなります。

## 簡単な使い方
私はPythonistaなのでpygnしか使いません。（Pythonが一番好きだけど、C#とNode.jsも興味があるので暇があったら投稿するかも・・・）
予め、Gracenoteに登録してcliantIDとuserIDは取得しておいて下さい。

超流しで書きます。
今日の本題ではないので。

```py:test.py
import pygn, json

clientID = 'XXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
userID = 'XXXXXXXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'

def beautiful(gn_obj): 
   data = json.dumps(gn_obj, sort_keys=True, indent=4, ensure_ascii=False)
   return data

res = beautiful(pygn.search(clientID=clientID, userID=userID, album='オー！リバル', artist='ポルノグラフィティ'))
print(res)

```

`./test.py > res.json`とでもして保存して下さい。

## 本題
pygnを\<LANG\>ja\</LANG\>に対応させただけです。
パッチファイルです。

```diff:pygn.patch
--- /home/hoge/Download/pygn-master/pygn.py	2015-05-15 17:06:08.436636117 +0900
+++ /usr/local/lib/python3.4/dist-packages/pygn.py	2015-05-15 04:04:38.551710764 +0900
@@ -7,6 +7,8 @@
 
 You will need a Gracenote Client ID to use this module. Please contact 
 developers@gracenote.com to get one.
+
+<LANG>オプション対応版
 """
 
 from __future__ import print_function
@@ -100,7 +102,8 @@
 # Added by Fabian in order to cover the Rhythm API
 # Returns a list of gnmetadata dictionaries 
 
-def createRadio(clientID='', userID='', artist='', track='', mood='', era='', genre='', popularity ='', similarity = '', count='10'):
+def createRadio(clientID='', userID='', lang='', artist='', track='', mood='', era='', genre='',
+                popularity ='', similarity = '', count='10'):
     """
     Queries a Radio playlist
     """
@@ -117,6 +120,7 @@
     
     # Build the user header 
     query.addAuth(clientID, userID)
+    query.addLang(lang)
     
     query.addQuery('RADIO_CREATE')
     
@@ -228,7 +232,7 @@
 
 #***********************************************************************************************************************
 
-def search(clientID='', userID='', artist='', album='', track='', toc=''):
+def search(clientID='', userID='',lang='', artist='', album='', track='', toc=''):
     """
     Queries the Gracenote service for a track, album, artist, or TOC
     
@@ -247,6 +251,7 @@
     query = _gnquery()
     
     query.addAuth(clientID, userID)
+    query.addLang(lang)
     
     if (toc != ''):
         query.addQuery('ALBUM_TOC')
@@ -432,7 +437,7 @@
 
 
 
-def get_discography(clientID='', userID='', artist='', rangeStart=1, rangeEnd=10):
+def get_discography(clientID='', userID='', lang='', artist='', rangeStart=1, rangeEnd=10):
     """
     Queries the Gracenote service for all albums containing an artist
     """
@@ -449,6 +454,7 @@
     query = _gnquery()
 
     query.addAuth(clientID, userID)
+    query.addLang(lang)
     query.addQuery('ALBUM_SEARCH')
     query.addQueryTextField('ARTIST', artist)
     query.addQueryOption('SELECT_EXTENDED', 'COVER,REVIEW,ARTIST_BIOGRAPHY,ARTIST_IMAGE,ARTIST_OET,MOOD,TEMPO')
@@ -534,7 +540,7 @@
 
     return discography
     
-def fetch(clientID='', userID='', GNID=''):
+def fetch(clientID='', userID='', GNID='', lang=''):
     """
     Fetches a track or album by GN ID
     """
@@ -551,6 +557,7 @@
     query = _gnquery()
 
     query.addAuth(clientID, userID)
+    query.addLang(lang)
     query.addQuery('ALBUM_FETCH')
     query.addQueryGNID(GNID)
     query.addQueryOption('SELECT_EXTENDED', 'COVER,REVIEW,ARTIST_BIOGRAPHY,ARTIST_IMAGE,ARTIST_OET,MOOD,TEMPO')
@@ -721,6 +728,10 @@
         client.text = clientID
         user.text = userID
     
+    def addLang(self, language):
+        lang = xml.etree.ElementTree.SubElement(self.root, 'LANG')
+        lang.text = language
+        
     def addQuery(self, cmd):
         query = xml.etree.ElementTree.SubElement(self.root, 'QUERY')
         query.attrib['CMD'] = cmd
```

これでそれぞれのパラメータにlangオプションが追加されます。

先の例でいくと・・・

```py
res = beautiful(pygn.search(clientID=clientID, userID=userID, lang='ja' album='オー！リバル', artist='ポルノグラフィティ'))
```

的な感じです。
日本語で返ってきたからといってもムードとかそこら辺が日本語になるだけなんですがね・・・
タブ挿入がうまくいかないので、多分これをあててもまともに動かないと思います。
その場合は手書きで追加して下さい。