textlintを使ってAWS用語をチェックしてみる #aws #textlint #golang
最近のアップデート
Cloud Automator のアップデートでログイン中の操作画面にマニュアルのリンクが表示されるようになりました。
もちろんマニュアルだけでも閲覧できますので、気になった方は無料トライアルでCloud Automator を試してみてください。
Cloud Automator – 株式会社サーバーワークス サポートページ
https://support.serverworks.co.jp/hc/ja/categories/115001305127
ドキュメントを充実させるには
ドキュメントを充実させていくには、地道に書いていくしかないわけで・・・Cloud Automator についても開発メンバーで分担しながら作っています。
その際ちょっと気になってくるのが表記のゆれ
です。
これは多人数でなくても1人で書いていても、書いている時期が異なると表現が異なるとかありますしね。
細かい言い回しならそこまで気にする必要もなさそうなのですが、Cloud Automator の使い方や機能を説明していくと当然ながらAWSについても言及する必要が出てきます。
AWS用語
で表記のゆれ
が出てしまうとユーザーは気になりますし、検索する場合にヒットせず困ることも出てきそうです。
そこでAWSの公式ドキュメント
に載っている日本語のAWS用語
を利用して、表記のゆれ
をチェック行ってみます。
アマゾン ウェブ サービス : AWS の用語集
https://docs.aws.amazon.com/ja_jp/general/latest/gr/glos-chap.html
ツールを探してみる
表記のゆれ
をチェックできるツールとして知っているのは以下2つ。
今回は対象のファイルがMarkdown
ファイルであるのと、手元で手軽に動かしたたいので、npmでインストールできるtextlint
を利用してみます。
また、prh形式のYAMLでルールを指定できるように次のツールも利用してみます。
ルールを作ってみる
チェックを行うためにはルールを作る必要があります。
AWS用語
については公式にドキュメントとしてまとまっているので、これを利用するために次のような簡単なコマンドラインツールをgolangで作ってみました。
できることは単純で、日本語のAWS用語
ページをスクレイピングしてprhで使える形式のYAMLファイルを出力します。
詳細はGitHub上のREADME.md
ファイルを参照してください。
スクレイピングにはgoquery
というgolangの便利なライブラリを利用しています。
実際のYAMLファイルを見てもらえば分かりますが、単純に用語をそのまま抜き出しているものと、半角スペースで分解して単語単位で抜き出してものがあります。
たとえばAmazon Simple Workflow Service
を登録する場合、
- expected: 'Amazon Simple Workflow Service' - expected: 'Amazon' - expected: 'Simple' - expected: 'Workflow' - expected: 'Service'
の5種類を登録しています。
これは実際にチェックする際により多くのパターンにマッチさせたかったためで、利用してみてマッチしすぎる場合は必要のない部分を削除して使う形にしました。
作ったルールを利用してみる
作ったルールを実際に利用するには.textlintrc
というtextlintの設定ファイルに、作成したaws_words.yml
ファイルのパスを記載するだけです。
{ "rules": { "prh": { "rulePaths": [ "./aws_words.yml" ] } } }
試しに次のようなMarkdown
ファイルに、上記の設定でtextlint
を実行すると、
# AWS用語のチェック - awsはダメ。 - Amazon Web Serviceも間違い。 - 日本語なので正解はアマゾン ウェブ サービス。 - 同じくAWS Management Consoleは英語なのでダメ。
のような結果になり、ルールにしたがってチェックされていることが確認できます。
$ textlint test.md /Users/uchimanajet7/self-work/github/awr/test.md 3:3 ✓ error aws => AWS prh 4:5 ✓ error Amazon Web Service => アマゾン ウェブ サービス prh 4:5 ✓ error => Amazon prh 4:7 ✓ error 違い => AZ prh 4:16 ✓ error ェブ サービス => service prh 4:16 ✓ error service => Service prh 7:6 ✓ error AWS Management Console => AWS マネジメントコンソール prh 7:6 ✓ error でダメ => AWS prh 7:10 ✓ error 同じくAWS マネジ => Management prh 7:21 ✓ error ントコンソール => console prh ✖ 10 problems (10 errors, 0 warnings) ✓ 10 fixable problems. Try to run: $ textlint --fix [file]
いくつか余計と思われる部分が指摘されていますが、これはルールを機械的に作り出しているために起こっているので、取り除きたい場合にはルールのaws_words.yml
ファイルを編集します。
もうちょっと便利に
これでMarkdown
ファイルに書かれている内容について、なんとなくですがtextlint
を利用してチェックできるようになりました。
しかし、実際にドキュメントを書く作業をしてみるともうちょっと便利にできそうな感じがするので試してみることにします。
私の場合ドキュメントを公開するまでに、
Markdown
形式でドキュメントを書く。textlint
でチェックし、修正があればなくなるまで繰り返す。Zendesk Guide
にドキュメントを反映するためにMarkdown
形式からHTML
形式に変換する。Zendesk Guide
にHTML
形式でドキュメントを反映し、画像の追加や装飾などを行う。- チームメンバーにレビューをしてもらい、指摘があればなくなるまで修正を繰り返す。
の定型作業を行っているので、この作業を効率化したいわけです。
最終的にはZendesk Guide
にHTML
形式で記載することになります。
ですので、最初からHTML
形式で書く方が効率的なの気もしますが・・・
個人的にはMarkdown
形式の方が書きやすいので、Zendesk Guide
がMarkdown
に対応してくれるとうれしいなぁー
と言っても、そこはどーにもならないので次のような簡単なコマンドラインツールをgolangで作ってみました。
できることは単純で、Markdown
形式からHTML
形式に変換できます。加えて、この変換作業の前後で任意のコマンドを実行できるので、今回はtextlint
を実行する形にしています。
ただし、textlint
は別のプログラムなので事前にtextlint
のインストールや設定は必要となります。
詳細はGitHub上のREADME.md
ファイルを参照してください。
Markdown
形式からHTML
形式への変換にはblackfriday
というgolangのライブラリを利用しています。v2への移行が進んでいますが、今回利用したのはv1になります。
出力するHTML
ファイルにclassを動的に追加したいなら、v2に追加されたParseを利用して実現できそうな気がします。時間ができたら要確認かなぁ。
また、何度もチェックして変換する工程を繰り返すことが予想されるので、fsnotify
というgolangのライブラリを利用して、ファイルの変更検知をできるようにしてあります。ファイルの変更を検知してチェックと変換を繰り返し実行します。
CLI化するのには有名なので説明不要だと思われるcobra
というgolangのライブラリを利用しています。
作ったものを使ってみる
せっかく作ったので使ってみるわけですが、前述したとおり変換前と変換後に外部コマンドを実行できます。
今回は変換前にtextlint
を実行してAWS用語
のチェックを行い、変換後にはHTML
を実行環境のデフォルトブラウザで表示してレイアウトの確認を行います。
設定ファイルには次のように実行するコマンドと置換する文字列を記載してあります。
{ "Page": true, "CSS": "style.css", "PreCommands": [["textlint", "%INPUT_PATH%"]], "PostCommands": [["open", "%OUTPUT_PAGE_PATH%"]], "ReplaceTexts": [ "<blockquote", "<blockquote class=\"is-colored\"", "<ol", "<ol class=\"list-colored\"", "<img", "<img class=\"image-with-border\"", "<table", "<table class=\"table table--bordered table--color-header\"" ] }
これで変更検知をする次のコマンドを実行して、ドキュメントを更新するとtextlint
を実行して変換後のファイルを実行環境のデフォルトブラウザで表示できているはずです。
現状は変化前、変換後のコマンド実行でエラーがあってもそのまま実行を続ける仕様ですので、textlint
で指摘があってエラーが表示されていても実行は継続します。
また、openコマンドでデフォルトブラザを開いているだけですので、ブラウザが複数立ち上がるってしまう可能性があります。
まとめ
textlint
を使って表記のゆれ
をチェックできる- 人のレビューを受ける前に機械的にチェックできるのはありがたい
- 頑張ってprh形式のYAMLファイルを用意すれば、任意のルールでチェック可能
AWS用語
は公式サイトにまとめられているので利用できる- ただし、日本語へのローカライズで問題ありそうな文言もあるので注意が必要
- あと、誤表記やTypoを発見したらAWSへ積極的にフィードバックしておきましょう!そのうちきっと修正してもらえるハズ
アマゾン ウェブ サービス : AWS の用語集 - EBSbacked
https://docs.aws.amazon.com/ja_jp/general/latest/gr/glos-chap.html#EBSbacked
Zendesk Guide
にMarkdown
形式が追加されてほしい- そー考えるとHatena Blogすごい書きやすいんだなーとあらためて思った
- golangは相変わらず便利、そしてちょー楽しい
blackfriday
はv2を使っていないので今後使ってみたいfsnotify
は便利だったので今後も使っていきたい- 当然このblogも
Markdown
で書いているのでtextlint
を使ってチェックした
以上になります。
Visual Studio Codeに拡張機能がインストールできない場合の対処方法 #vscode #docker
アップデートエラー
Visual Studio Code(以下VS Code
)の拡張機能でDocker
がありますが、この拡張機能の0.0.19
へのアップデートで
end of central directory record signature not found
というエラーが出てアップデートができなくなりました。
拡張機能のDocker
をアンイストールして、再インストールしようとしても同じ結果に・・・
調べてみると
GitHubにissueが上がっていて
次のissueと同様の対応をすると解決するとのことなので
解決方法が載っているというissueを読んでみると
と書かれており、つまりは拡張機能をブラウザを使ってダウンロードして、ダウンロードしたローカルファイルからインストールすれば解決すると。
さっそく試してみる
拡張機能インストールファイルのダウンロード
issueには拡張機能のPythonをダウンロードできるURLが記載されていて、Google先生で調べるとこのダウンロード用のURLを自分で編集してインストールパッケージをダウンロードすると書かれたBlogが多数ヒットします。
しかし、上記のリンクを確認すればわかりますが、拡張機能の個別ページにはパッケージをダウンロードできるリンクが存在します。
Download Extension
をクリックすれば、インストール用のパッケージがダウンロードされます。今回のDocker
であればPeterJausovec.vscode-docker-0.0.19.vsix
というファイルになります。
ローカルファイルからの拡張機能インストール
ダウンロードしたPeterJausovec.vscode-docker-0.0.19.vsix
を利用して、拡張機能インストールします。
[表示] → [コマンドパレット]でコマンドパレット
を表示します。コマンドパレット
のメニューから拡張機能: VSIX からのインストール
を選択します。
するとファイル選択のダイアログが表示されるので、先ほどのファイルPeterJausovec.vscode-docker-0.0.19.vsix
を選択するとインストールが開始されます。
インストールが正常に完了すると、再読み込みをうながすメッセージが表示されますので今すぐ再度読み込む
ボタンをクリックして再読み込みを行います。
インストール済みの拡張機能一覧にDocker
の表示があればインストールが正常に完了したことになります。
まとめ
- 特に何もしていないのに急にアップデートできずエラーになった
- 調べてみたら同じような人がいた
- 対処はインストールパッケージをローカルにダウンロードして、ローカルファイルからインストールを実行するだけ
- いろいろ複雑に書いてあるBlogもあるが、たぶん情報が古い
- もし同じような症状の人がいるなら参考にしてほしい
- 原因がわからないので再発しないといいなぁー
以上になります。
Raspberry Pi 3+Gmail APIでメールを受信して音声合成してみた #raspberrypi #gmail #golang
メールで
仕事では殆どメールを見る機会はないのですが、通知系のメールに気が付かなかったという経験をしたことがある人は多いはず。
今回はGmail のAPI を使ってメールを定期的に受信して、条件に合うメールの場合は音声で通知できる仕組みを Raspberry Pi 3
とGamil API
を利用して作ってみたいと思います。
Gamil API
利用を開始するまでにはいくつかステップがあって、いろいろなBlogで書かれていますが上記の公式サイトにあるQuickstart
で、利用する言語毎に書かれているドキュメントの通りに進めるのをおすすめします。公式ドキュメントが充実しているのと最新の情報が記載されているため、手戻りすることなく進めることができます。
今回は当然大好きなgolang
を利用するので以下に沿って進めていきます
Go Quickstart | Gmail API | Google Developers
https://developers.google.com/gmail/api/quickstart/go
準備
Google Developers Console
まずはGoogle Developers Console
にアクセスして
Google API Console
に移動します。
表示されたAPIの一覧からGmail API
を選択します。
プロジェクトが存在しないとAPIを有効化できないので、先にプロジェクトを作成します。
既存のプロジェクトでAPIを有効かする場合には、当然ですが新規にプロジェクトを作成する必要はありません。
APIを有効化しただけでは利用ができません。認証情報を作成する必要があります。
OAuth クライアントIDを取得するのですが、先に同意画面の設定が必要になります。
クライアントIDのアプリケーションの種類はその他を選択します。
設定が完了すると認証に必要な情報をJSONファイルとしてダウンロードすることができるので、ダウンロードして保存します。
詳細は以下の公式ドキュメントに書かれています
Authorizing Your App with Gmail | Gmail API | Google Developers
https://developers.google.com/gmail/api/auth/about-auth
Implementing Server-Side Authorization | Gmail API | Google Developers
https://developers.google.com/gmail/api/auth/web-server
Choose Auth Scopes | Gmail API | Google Developers
https://developers.google.com/gmail/api/auth/scopes
golang packages
次にgolangで必要になるパッケージを以下のコマンドを実行して取得します
$ go get -u google.golang.org/api/gmail/v1 $ go get -u golang.org/x/oauth2/...
実際に取得されるのは以下のパッケージになります。
パッケージの利用方法は、それぞれのパッケージに用意されているドキュメントを確認してください。 サンプルについてもパッケージのリポジトリにあるので参考になるかと思います。
動作確認
続けて動作と認可の確認を行います。
Go Quickstart | Gmail API | Google Developers
https://developers.google.com/gmail/api/quickstart/go#step_3_set_up_the_sample
上記のサンプルコードをそのまま利用するのですが、最初の工程でダウンロードしたGmail APIのクライアントIDのJSONファイルが必要になります。
サンプルコードをビルドして実行すると、コンソールに
Go to the following link in your browser then type the authorization code:
のメッセージと一緒にURLが表示されます。このURLが認可ページのURLになるのでブラウザにコピペしてページを表示します。
ブラウザに表示したら認可を与えるアカウントを選択します
認可の内容を確認します。今回は読み取りのみを指定しています。
問題がなければ許可をして、その後の画面に表示されるコードをターミナルに貼り付けます
これで次回の動作からはクライアント側に保存されたtokenを利用してアクセスすることができるようになります。
作ったもの
実際に作ってみたものは以下の写真のような感じに
使ったのは
- Raspberry Pi 3 MODEL B
- USB電源スピーカー(MS-UP201BK)
- USB電源LEDライト(100円ショップ)
ぐらいで、ラズパイはAmazon Echoもどきで遊んだ時のやつを再設定して利用しましたし、LEDライトは100円ショップで適当に買ったやつですし、唯一スピーカーが手元になかったので700円ぐらいのものを買った感じですね。
ラズパイだと情報も多いですし、選択肢もいろいろとあるんですが手間もかけずに適当に作れるのはいいですねー
Raspberry Pi 3 MODEL B
特別なことは何もしておらず、普通にRaspbianのLITEをインストールしてsshで接続できるように設定しました。
hub-ctrl
USBの電源をON/OFFするために、以下を参考して
Raspberry Pi B+ turn usb power off - Raspberry Pi Forums
https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=93463
hub-ctrl をインストールしてあります。
ラズパイ3だとUSBの個別ポートで電源のON/OFFができると記載されている 記事も目にしましたが、手元のラズパイだと
pi@raspberrypi:~ $ hub-ctrl Hub #0 at 001:000 INFO: ganged switching. WARN: Port indicators are NOT supported. Hub #1 at 001:000 INFO: ganged switching. WARN: Port indicators are NOT supported.
pi@raspberrypi:~ $ lsusb -v Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter Couldn't open device, some information will be missing Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 255 Vendor Specific Class bDeviceSubClass 0 bDeviceProtocol 1 bMaxPacketSize0 64 idVendor 0x0424 Standard Microsystems Corp. idProduct 0xec00 SMSC9512/9514 Fast Ethernet Adapter bcdDevice 2.00 iManufacturer 0 iProduct 0 iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 39 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xe0 Self Powered Remote Wakeup MaxPower 2mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 3 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 0 bInterfaceProtocol 255 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0010 1x 16 bytes bInterval 4 Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. Couldn't open device, some information will be missing Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 9 Hub bDeviceSubClass 0 Unused bDeviceProtocol 2 TT per port bMaxPacketSize0 64 idVendor 0x0424 Standard Microsystems Corp. idProduct 0x9514 bcdDevice 2.00 iManufacturer 0 iProduct 0 iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 41 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xe0 Self Powered Remote Wakeup MaxPower 2mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 9 Hub bInterfaceSubClass 0 Unused bInterfaceProtocol 1 Single TT iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0001 1x 1 bytes bInterval 12 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 1 bNumEndpoints 1 bInterfaceClass 9 Hub bInterfaceSubClass 0 Unused bInterfaceProtocol 2 TT per port iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0001 1x 1 bytes bInterval 12 Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Couldn't open device, some information will be missing Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 9 Hub bDeviceSubClass 0 Unused bDeviceProtocol 1 Single TT bMaxPacketSize0 64 idVendor 0x1d6b Linux Foundation idProduct 0x0002 2.0 root hub bcdDevice 4.09 iManufacturer 3 iProduct 2 iSerial 1 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 25 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xe0 Self Powered Remote Wakeup MaxPower 0mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 9 Hub bInterfaceSubClass 0 Unused bInterfaceProtocol 0 Full speed (or root) hub iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0004 1x 4 bytes bInterval 12
な感じなんですが、個別のON/OFFは残念ながらできませんでした。
USBの規格としてPer-port power switching
というのに対応していると個別のON/OFFが可能みたいです。調べた限りだと
スゴイハブ USB2-HUB4Xシリーズ 製品情報
http://www.system-talks.co.jp/product/sgc-4x.htm
が動作実績がありそうな感じでした。
AquesTalk Pi
日本語を音声合成するためのTTSとして、以下のAquesTalk Piをインストールしてあります
AquesTalk Pi - Raspberry Pi用の音声合成
https://www.a-quest.com/products/aquestalkpi.html
今回はなるべく手軽に実現したかったのでAquesTalk Piを選択しましたが、他にも
Open JTalk
http://open-jtalk.sourceforge.net/
なんかを利用している人が多いようです。
また、クラウドサービスを使って音声合成をすることももちろん可能なのですが、今後家のネットワーク以外の例えばSORACOM Air
なんかを利用したい場合を考えると、ラズパイ側で処理できるなら処理した方が良いかなーと。
クラウド側で処理する場合は
あたりが定番でしょうか?
意外だったのはGoogleにはTTSのAPIがなさそということでしょうか・・・音声認識はあるので、内部的には当然あるんでしょうけど。
あとは、crontabで作ったプログラムの定期実行と起動時のUSBのコントロールを行っているぐらいです
pi@raspberrypi:~ $ crontab -l # Edit this file to introduce tasks to be run by cron. # # Each task to run has to be defined through a single line # indicating with different fields when the task will be run # and what command to run for the task # # To define the time you can provide concrete values for # minute (m), hour (h), day of month (dom), month (mon), # and day of week (dow) or use '*' in these fields (for 'any').# # Notice that tasks will be started based on the cron's system # daemon's notion of time and timezones. # # Output of the crontab jobs (including errors) is sent through # email to the user the crontab file belongs to (unless redirected). # # For example, you can run a backup of all your user accounts # at 5 a.m every week with: # 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/ # # For more information see the manual pages of crontab(5) and cron(8) # # m h dom mon dow command # ggm */3 * * * * /home/pi/ggm/ggm #set init @reboot amixer set PCM 100% @reboot sudo hub-ctrl -h 0 -P 2 -p 0
golang program
やっていることはGmailをAPI直接ではなく、golangのSDKを利用して受信しているだけです。
特に変わったこともしていないので、何の参考にもならないかもしれませんが・・・
動作の設定で記述が必要なのは.ggm/user_config.json
ファイルだけです。
{ "LastDate": 1504243346130, "LastTotal": 749, "UserEmail": "test@example.com", "SpeakCommands": [["/home/pi/aquestalkpi/AquesTalkPi", "-s", "120", "%s"],["aplay"]], "UsbCommands": [["sudo", "hub-ctrl", "-h", "0", "-P", "2", "-p", "%d"]], "Filters": [ { "From": "user1@example.com", "Subjects": ["test","user1"] }, { "From": "user2@example.com", "Subjects": null } ] }
SpeakCommands
には音声合成するためのコマンドを記載しますが、配列で1つのコマンドを表して、配列を配列に入れることでパイプでつないで実行します。なので、上記の例だと
$ /home/pi/aquestalkpi/AquesTalkPi -s 120 %s | aplay
のコマンドを実行していることになります。コマンド中の%s
にはGmailの受信した内容が入ります。
UsbCommands
にはUSB電源管理するためのコマンドを記載します。形式は前述の通りです。コマンド中の%d
はON/OFFの数値が入ります。
Filters
には音声合成対象のメール条件を記載します。From
には送信元のメールアドレスを、Subjects
には配列で件名を記載します。特に指定がされていない場合にはすべてのメールが対象となります。
cross compile
Raspberry Pi 3 用にgolangをコンパイルする際には
Installing Go from source - The Go Programming Language
https://golang.org/doc/install/source#environment
を参考にして環境変数を指定するわけですが、$GOARM
に指定する値はラズパイ上で以下のコマンドを実行すると確認できます。
pi@raspberrypi:~ $ uname -m
armv7l
どうやらv7らしいので
$ GOOS=linux GOARCH=arm GOARM=7 go build -v
とすれば、今回の利用するライズパイ上で動作するバイナリがビルドできることになります。
動作デモ
で、実際に動作するとどうなるのか?というと・・・
twitter.com音声合成できたー楽しい pic.twitter.com/ZRDM7dXPoG
— Manabu Uchida (@uchimanajet7) 2017年9月6日
な、感じになりました。思ったよりちゃんと音声合成できていて個人的には十分かなぁーと思いました。
まとめ
- Raspberry Pi 3 は結構サクサク動く
- これだけ動けばgolangでちょっとしたことは余裕そう
- 今回は簡単にやってみたかったので複雑なのは却下した
- Gmailだとpush通知を利用した方が良いかもしれない
Push Notifications | Gmail API | Google Developers
https://developers.google.com/gmail/api/guides/push
- SORACOM Airを利用したい場合、USBドングルを使うことになるのでUSB電源をOFFにする動作が微妙
- 前述した
Per-port power switching
に対応したUSBハブを導入して回避する - USBをON/OFFしている理由は、雑音が聞こえることがあるのとUSBライトを受信時にだけに光らせたいから
- 予算や手間を気にしないならCrystal Signal Pi みたいなのを導入するのもありかもしれない
- 雑に扱っても大丈夫というのが1つの目的だったので自作はなるべくなし
- golangはいろいろできて楽しい
- 急に喋り出すので若干びっくりする
- 特に夜中とか怖いw
- 要望は叶えられたので便利にはなった
- また機会があればぜひなんかやってみたい
以上になります。
Cloud Automator のAPI に後処理が追加されたのでCLIにも追加した件 #cloudautomator #golang #swx
気がついたら
Cloud Automator
のAPIが後処理に対応していました。
Cloud Automator API | /post_processes
https://cloudautomator.com/api_docs/v1/api.html#後処理
APIの詳細は上記の公式サイトを確認してもらうとして、数も多くなさそうなので作ったCLIにも追加しようと思います。
追加した
というわけでv0.1.1
でCloud Automator
APIの後処理に対応するコマンドを追加しました。
下記のようなコマンドでsqs
の後処理を新規に追加することができます。
$ ./ca post-process create \ --name "後処理テスト" \ --service sqs \ --parameters sqs_aws_account_id=1\ ,sqs_queue="example-queue"\ ,sqs_region=ap-northeast-1
--parameters
はobject
型ですので、他のobject
型と同様に
“APIのパラメータ名=値” の形で指定して、パラメータ同士は",“で繋いで表現してください。また、配列を表現する場合は”APIのパラメータ名=値,値,値“のように値を”,“で繋いで表現してください。
まとめ
- 数が多くないので手作業でもなんとかなったが、やっぱりAPI定義から自動で作れるような仕組みは必要
- 今回もAPIドキュメントにTypoがあり、コピペしてそのまま使ったら404で少しハマった・・・
- APIドキュメントのどの部分が更新されたのかわからないので、とりあえず全部目を通して変更点を探す必要があった
- 新規追加はわかりやすいが、既存のAPIにパラメータの追加とかは数が多くなったら見て確認するのは難しい
- テストがないので既存のコード変更後の確認が大変だった
- 足りないところやできていないところを何とかしたい
以上になります。
OneTab のTabリストを整理するCLI をgolang で作ってみた #golang #onetab
便利な
みんな知ってるGoogle Chrome 拡張機能のOneTab
ちょー便利なのでよく使うんですが、気軽に使えすぎてOneTab
のリストがどんどん膨れ上がってきませんか?
・・・と、こんな感じでどんどん増えて行くわけですが
OneTab
に同じURLが登録されているOneTab
側にリストを整理するような個別な機能がない- UI上でマウスを使って移動や削除はできる
- 数が多くなるとこの操作も大変
- リストの登録件数が多くなると重くなる
- PCのスペックにもよるが手元だと2,000件ぐらいから重い
- 登録や削除が重くなる
というわけで、他に需要があるとは思えないCLIを作ってみました。 自分でも使ったのも1回きりというね・・・
作ったのは
使い方は簡単でOneTab
からURLの書き出しで出力されるリストをファイルに保存して
コマンドラインで保存したファイルを指定してコマンドを実行するだけ
$ ./tlc run "your_file_path" -w
-w
オプションでHTTPリクエストでURLがアクセス可能かどうかをチェックします。
やってること
すごい単純なことしかやってませんが
OneTab
から書き出したURLリストを保存したファイルを読み込む- 読み込んだファイルからURLをキーにして
URL文字列が完全一致
するものを削除 - URLで削除したリストを今度は
名称文字列が完全一致
するものを削除 -w
オプションが指定されていた場合、URLがアクセス可能か(status == 200)かどうかチェックする
だけなので、当然ですが
- URL文字列が異なり同じWebページだった場合は違うとみなされる
- 例えばSNSからのリンクがわかるようなパラメータ付きとパラメータ無しのページなど
- 名称文字列が同一でURLが異なる場合は、同一とみなさせる
- すべてのページで同じ名称がつけられているページなど
- URLのアクセスチェックでステータス200以外の場合はアクセスできないとみなされる
- ブラウザと同等の判定はしていないため、ブラウザで見れるのNGと判定される場合がある
という制限?問題点?はあります。
ダメだったこと
簡単にできそうで、できなかったことを書いておこうかと。
- URLからHTMLの内容を取得して、取得した内容をハッシュ値で比較
- セッションIDや広告IDなどのアクセスするたびに異なる値がHTMLに含まれることがある
- これによりハッシュ値が同一のページでも毎回異なる
- URLにアクセスできるかをブラウザと同等の判断で行う
- ブラザと同等となるとブラザそのものでチェックした方が早い
- 現状ではCDNでJSを使ったリダイレクトなどしていると上手く判定できない
- リダイレクト回数が多い場合に上手く判定できない
そもそもよく考えたら、どれもダメだよねーとw
まとめ
- とりあえず動くところまでは出来ている
- golangって便利ですなぁ
- リストの重複を除く仕組みをもうちょっと考える必要がある
- 今ならGoogle Chromeのヘッドレスモードを利用できるならした方が良さそう
- CLIにしたけどWebでできた方が手軽そう
- というか
OneTab
側になんか整理する機能があってもいい気がする - そもそもこんな使い方している人が他にいないかもしれないw
以上になります。
GitHub のREADME にgif 画像を表示する1番簡単な方法 #github #gif
画像を
GitHubのREADMEにgif画像を貼り付けたいってことってありますよね。今回作ってみたこれ↓でも1枚だけ貼り付けたい感じになりました。
当然Google先生でgithub readme gif
とか入力して調べてみるわけですが
github readme gif
https://www.google.co.jp/search?q=github+readme+gif
どーやら↓の2つの方法が主流っぽい感じ?
1
の方法は確かに手軽だけど、それだけのためにbranchが残り続けるのが個人的には好きじゃないので却下。これするなら素直にmaster branchに画像ファイル追加するなぁ
2
の方法は利用したこともあるし、Wiki使ってドキュメント書くならアリだと思うんですが・・・今回はファイル1個なのが迷うところ。
2
と似てるけどGitHub Pages
でも同じようなことは出来ますよね。こっちもページ公開するならアリだと思うけど、今回はファイル1個・・・
もっと手軽に
画像1個で画像自体のバージョン管理が必要ないので、もっと簡単に出来ないかなぁーと。そこで思いついたのが以下の方法になります。
- GitHubのリポジトリにissueを起こして、そのissueに画像を貼り付ける
- issueの画像はMarkdown記法でリンクが記述されているのでそれをコピー
- 画像を貼りたいREADMEにこのリンクを張り付ければOK
今回はこの方法を利用しているので、実際にissueに貼った画像を使ってREADMEに画像を貼り付けています
この方法の良いところ
- issueを作って画像を貼り付けるだけなので手軽
- 余計なbranchが残り続けることもない
- issueなので、そのissueのためにbranch切ってpull request起こせば、なんでこうなってるのかがあとからもわかる
- そもそもREADMEを更新するのでpull requestを起こすはず
- issueなので対応が終わったらcloseしちゃえば良い
- 画像を差し替えたい場合も、差し変えるためのissueを起こせば同様の手順でOK
- issueの画像リンクがMarkdown記法なので、そのままコピペできる
- 何と言っても手軽
ということで、手軽で良い感じかと。 何かの参考になれば。
以上になります。
日経Linux2017年9月号にちょっとだけ載った件 #ITpro #swx #aws
きっかけは
先日↓退職Blogをアップしていたおねーさんが
社内Slackで
「Amazon AIネタで雑誌に書いてみませんかー?締め切り近いけどw」
的な募集をかけていました。なんてゆるいw 素敵すぎる!
Amazon Pollyなら以前にアドベントカレンダーでネタにしたこともあるのでワンチャン!と思いとりあえず手を挙げてみました。
そしたらありがたいことに執筆させてもらえることになりました。
書いたのは
記事を書いたのは↓の「日経Linux2017年9月号」で、内容はAWSのAIサービスについてになります。
実際にはAmazon PollyとAWSの概要についてを担当しました。
書いてみて
- 書くのにあたってAWSサイトを色々見たけど、ドキュメントが多くてしっかり書いてあるのを再認識
- というか、これWebが見らえる環境ならわざわざ紙にする必要があるのかどうか気にするレベル
- 規定の文字数にまとめるのは大変
- 雑誌という限定される中で、編集の方がいろいろ工夫されているのがわかった
- どの業界でもユーザーにどうやって価値を届けるのか?に違いはないんだなぁーと
- こちらが雑誌という媒体に慣れてないため、何度か手間を取らせてしまった
- 次回からもうちょっと色々考えてこちらから提案できるようにしたい
- 知ってるつもりでも、まとめたり再度調べなおしたりすると色々と発見もあり自分でも大変勉強になった
- とにかく良い機会だった
まとめ
- 気になったら是非お手にとっていただければ!
- 日経Linuxに小さいけど自分の名前が載るとかテンション上がる!
- おねーさんと最後にお仕事っぽいことが出来てよかった!
- 雑誌編集の人の雑誌に対する姿勢にいろいろ学べた
- 雑誌だろうと、Webサービスだろうとやっぱりユーザー視点ってすげー大事だなと
- もっと他の業種の人とも一緒に仕事できると、こういう気づきがありそうなので機会があれば積極的にやっていきたい
- 文章書くのに慣れてないから時間がかかった
- けど楽しいので文章書くのも機会があれば積極的にやっていきたい
- こういう良い機会に関われてよかった
- ↑少しですがちゃんと
Cloud Automator
の宣伝もしておりますw
以上になります。