Amazon Dash ボタンで Get Wild を流す by Google Play Music（Chromebookで失敗編）

このエントリは、[#ssmjp参加者 Advent Calendar](http://www.adventar.org/calendars/2042) 18日目（といいつつ遅れに遅れた）です。

## TL;DR
- Chromebook上のUbuntuとAmazon Dash ボタンでGoogle Play Music上のGet Wild流そうとしたけど
- Chromebook上のサウンドデバイスをpythonから触る方法がわからず途中で断念したぞ

## いきさつ
あっやばい GetWild駆動開発 流行ってる
↓
あっやばい Amazon Dash ボタン 出た
↓
これはボタンでGet Wild流すしか無いぜﾋｬｯﾊｰ
↓
[そりゃ出た瞬間やる方いらっしゃるよね](http://qiita.com/TAKA1111/items/87f053498e80bf69ad9d)
↓
結局クソ悩んだけどやっぱりGet Wild忘れられない… ← このエントリ

## 動作環境
- Chromebook Flip C100PA
- crouton導入、Ubuntu trusty
- node.js v7.2.1 (`npm install n` 後、`n stable` で導入)
- `npm install dasher`
- python & pip
- `pip install python-vlc gmusicapi flask`
- Amazon Dash ボタン
- Amazon Dash ボタンを設定できるスマホ等の端末

## Chromebookへの環境の導入
croutonもtrusty上でのnode.js stable導入もpip導入もそんなに難しくないから割愛!
詰まるところは以下。
- libvlc-dev, vlcをapt-getしておかないとpython-vlc導入できない
- libpcap-devをapt-getしておかないとdasherのビルドでコケる

## Amazon Dash ボタンの検出とGETリクエスト発行まで
### Amazon Dash ボタンをHookするためのサーバアプリ導入
node.jsに、dasherという、node-dash-buttonのラッパーがあります。
これ導入すればOKです。

```
git clone https://github.com/maddox/dasher.git
cd dasher
npm install
```

### Amazon Dash ボタンの設定
AmazonアプリでAmazon Dash ボタンを設定して、商品選択前に×押してキャンセル。
これはDashボタンを導入しているエントリをご覧ください。

### dasher付属のスクリプトでDashボタン検出
`./script/find_button` を実行してください。MACアドレスを特定できます。
ManufacturerがAmazonか、Unknownのどちらかがボタンです。
Chromebookだとarpで検出されるようなので、ズラズラ出てくるのを何回かDashボタンを押して特定してください。

### config設定
`./config/config.json` に、以下を設定します。
addressは先程検出したMACアドレスです。
後ほど、localhostの3000番ポートにAPIを立てるので、そこを指定します。

```
{"buttons":[
  {
    "name": "getwildandtough",
    "address": "xx:xx:xx:xx:xx:xx",
    "interface": "wlan0",
    "timeout": "60000",
    "url": "http://127.0.0.1:3000/getwild",
    "method": "GET",
    "json": true
  }
]}
```

### dasher起動
`sudo npm run start` で起動します。
ここでDashボタン押しちゃうとエラー吐いちゃうのでこのまま。


## REST風API作成とGoogle Play Musicへのリクエスト、音の再生
Google Play Musicは2016/12/25現在、公式APIがありません。
ということで、[非公式API](https://github.com/simon-weber/gmusicapi)を使います。python実装のようなので、
あんまり触ってないpythonで実装します。

- REST風API作成
    - Flaskで実装します。GETだけしか準備してません。エラー処理もしてません。
- Google Play Musicへのリクエスト
    - [gmusicapi](https://github.com/simon-weber/gmusicapi)を使用します。
- python-vlcでの音の再生
    - 音再生しようとしました…サウンドデバイスの設定方法が分かりません…
    - audio_output_device_enum したいけど、libvlc-dev 2.2.0より古い…
        - croutonからやり直すのつらく諦めの境地である

結局、以下のようになりました。
どなたかvlcで音を出す方法を教えてください。非同期でやりたいです。
APIの返事返さないといけないので…

あと言い訳ですが、dict型で返ってきたjsonをいきなりobject_hookでattribute形式にする方法が分かりませんでした。
正直dictのアクセスはjson触ってると書きづらくて泣きそうになりますのでなんとかしたい。
今回は一度strに戻して、再度dictにしています。

```
# -*- coding: utf-8 -*-
from flask import Flask, jsonify, abort, make_response
from gmusicapi import Mobileclient
import json
import vlc

# JSON attribute
class D(dict):
    __getattr__ = dict.__getitem__ 

# flask init
api = Flask(__name__)

@api.route('/getwild', methods=['GET'])
def getwild():
    # gmusic client
    mobilecli = Mobileclient()
    mobilecli.login('ログインユーザのgmailアドレス', 'パスワード', Mobileclient.FROM_MAC_ADDRESS)

    results = mobilecli.search('Get Wild',1)
    resultjson = json.dumps(results)
    resultjson = json.loads(resultjson, object_hook=D)

    songurl = mobilecli.get_stream_url(resultjson.song_hits[0].track.storeId)
    print(songurl)

    # vlc...I do not know how to detect audio devices...
    p = vlc.MediaPlayer(songurl)
    p.play() # do not play "Get Wild"... 

    result = {
        "result":True
    }
    return make_response(jsonify(result))

if __name__ == '__main__':
    api.run(host='127.0.0.1', port=3000)
```

## まとめ
全然わからんぜ…古いライブラリだとできないのはキツいぜ…
ただ、非公式Google Play Musicクライアントが思いのほか使えたので、
これはこれでかなり捗るのではと思っています。
あと「Get Wild」でサーチしたら、一発目で当然のようにTMNが当たるので、さすがとしか言いようがありませんでしたな。
上のコードだと当たった一発目しか持ってきてないので、TMNじゃなかったらそのGet Wildが流れるんだぜ…

やり始めたらPython分からなくても、node.jsもあんまり触ったことなくても、6時間くらいでAPI立ててGoogle Play Musicにアクセス出来てDashボタンもHookできるので、すごく良い世の中になったなあと思いました。（調査3時間くらい、実装1時間くらい、出来なくて再調査1時間くらい、このエントリ1時間くらい…）
遅くなってホント申し訳ありませんでした。しかもできんかった…orz