esaのAlfred WorkflowをGoで作りました
作ったもの
とりあえずtokenとチーム名を登録して記事を検索できるだけです。
注意点
ちなみに、esaのAPIは利用制限があるので検索しすぎにご注意ください
https://docs.esa.io/posts/102#2-3-0
現時点では、ユーザ毎に15分間に75リクエストまで受け付けます。 とのこと
alfred-esa-workflow作ったんだけど、 API利用制限が15分間に75リクエストということで速攻で使えなくなった :innocent: pic.twitter.com/0BRWGTXaM9
— きょこみ@k02 (@k_yokomi) January 28, 2017
参考にしたもの
使ったライブラリ
filterで一覧表示するのがこんなに楽に実装できて感謝
esaのClientすでに作っている方がいてesaのAPI仕様はあまり見ないでもサクッと作れました! 感謝
最初、直接 Open in Finder
したフォルダ内にバイナリを放り込んで開発してたんですが、 普通に xxx.alfredworkflow
をダブルクリックしてInstallして動作確認したかったので、 alfred-workflow-packager
を使うようにしました。(まあ、色々replaceしてzipに固めるだけっぽいですが)
ただ、これはMacでAlfred3がインストールされている前提のコードがあるので、ちょっと書き直してCIで動くようにしようかなと思ってます。
GoでAlfredWorkflowを作る手順(雑メモ)
AlfredWorkflowつくるぞ〜と思ってから最初どうすればいいかわからない具合いが結構すごかったです。
とりあえず自分は、似てるworkflowをinstallして Alfred上で Open in Finder
して中身を漁ってつくりを把握してつくってみました。
思ったより単純な構造で、基本的には以下の流れでつくればいいのかなという理解。
- 普通にCLIツールをGoで作る
-
Script filter
での出力はgo-alfred
等を使ってxmlをPrintする Run Script
してPost Notification
に表示する出力は普通にfmt.Print
でOK
-
- Alfred上でkeywordsとかをとりあえず作成して
./<バイナリ名> search "{query}"
みたいな感じでCLIツールの呼び出しする Open URL
とか適当なActionを紐付けて、とりあえず動くところまでいくOpen in Finder
してicon.png
とinfo.plist
だけコピーしてGoのProjectにコピーする- あとは
alfred-workflow-packager
を使ってxxx.alfredworkflow
を作成して、ダブルクリックしてインストールして動作確認していく感じ
まとめ
Alfred便利なのでどんどん作っていくぞ!!!!!!
昔作ったgaego-initをglide対応した
gaego-initとは以下のように、GAE/Goの開発環境をコマンド一発でgenerateするやつです。
$ gaego-init -app hoge-app $ tree hoge-app/ hoge-app/ ├── Makefile ├── README.md ├── appengine │ ├── app.yaml │ └── init.go └── circle.yml 1 directory, 5 files
以前作ったときは、vendoringの対応をどうするかべきかわからず、結局shellでgoapp getするという荒業をしていたのでそれを修正しました。
# Makefile 22:26:56 APP_ROOT=appengine VENDOR_GOPATH=$(shell pwd)/$(APP_ROOT)/gopath/vendor APP_GOPATH=$(shell pwd)/$(APP_ROOT)/gopath RUN_GOPATH=$(APP_GOPATH):$(VENDOR_GOPATH) install: glide init glide install mkdir -p $(APP_ROOT)/gopath/vendor ln -s $(shell pwd)/vendor/ $(VENDOR_GOPATH)/src run: GOPATH=$(RUN_GOPATH) goapp serve $(APP_ROOT) clean-run: GOPATH=$(RUN_GOPATH) goapp serve --clear_datastore $(APP_ROOT) deploy: GOPATH=$(RUN_GOPATH) goapp deploy $(APP_ROOT)
こちらの記事を参考にglideでのvendoringを行えるようにしました。
感謝 🙏 🙏 🙏 🙏 🙏
Arukasを使って無料でGo製のslackbotを運用する
はじめに
SlackbotをHerokuで一日中動かすと課金が発生するので色々ハックが必要となったりするので、なんとかしたくArukasに出会いました。
今回は、自分が作ったgo製のslackbotを元につくったbotをgithubにpushしてWercker経由でdockerImageを作ってArukasへのDeployを行う方法を紹介します。
今回のコードとか設定をexampleとして公開してますので、よろしければ参考にしていただければと。
Arukasとは?
いまのところ無料でDockerをホスティングできるサービスです。
一応CLIツールも公開されていて、結構便利です。
※注意点としては、CMDで起動したプロセス監視とかは無いので自分でとかgo-server-starterとかを入れてプロセス死んだときに再起動する仕組みを入れる必要があるところです。
流れ
- 以前作ったgo製のslackbotのdockerImageをWerckerで作成する kyokomi.hatenablog.com kyokomi.hatenablog.com
- Arukasのコンソールでアプリケーションを作成し、dockerImageを指定する
- WerckerのworkflowでArukasのrestartを設定する
slackbotのコード自体はDockerとか意識しない形になっているので、wercker.ymlとかを見ていただければと。
example-go-slackbot/wercker.yml at master · kyokomi/example-go-slackbot · GitHub
Werckerの設定
README.md に書いてある通り6つの環境変数の登録が必要です。
- DockerHubまわりは、普通に自分のアカウントとかリポジトリを入れてもらえればOKです
- Arukasまわりは、 https://app.arukas.io/settings/api-keys で発行したAPIKeyとSecretを設定してください
ポイントはdocker-pushのworkflowで github.com/lestrrat/go-server-starter/cmd/start_server
をinstallしてます。
まあ別にバイナリをdonwloadでもいいんですが面倒だったので...
docker-push: box: golang steps: - glide-install - setup-go-workspace - script: name: install deamontools code: | go get github.com/lestrrat/go-server-starter/cmd/start_server - script: name: install application code: | go install - internal/docker-push: username: $DOCKER_HUB_USERNAME password: $DOCKER_HUB_PASSWORD tag: latest repository: $DOCKER_HUB_REPOSITORY registry: https://registry.hub.docker.com
arukas-deployのworkflowでは、 arukasのバイナリをdownloadして適当にPATHを通してstop -> startしてます。
sleep 10
を挟んでいるのは、stopする前にstartするとエラーになるので仕方なくです。
arukas-deploy: box: golang steps: - script: name: install tools code: | sudo apt-get update sudo apt-get -f install sudo apt-get install -y wget unzip curl tree - script: name: arukas install code: | mkdir -p $HOME/lib export PATH=$PATH:$HOME/lib cd $HOME/lib wget https://github.com/arukasio/cli/releases/download/v0.1.2/arukas_v0.1.2_linux_amd64.zip unzip arukas_v0.1.2_linux_amd64.zip rm arukas_v0.1.2_linux_amd64.zip - script: name: arukas restart code: | arukas stop ${ARUKAS_CONTAINER_ID} sleep 10 arukas start ${ARUKAS_CONTAINER_ID}
Arukasの設定
- SlackbotのTokenは、
Bots
かhubot
で作ったTokenを使ってください - docomoのAPIは雑談で使ってます(必須じゃないので不要なら設定しなくてOKです)
- REDISTOGO_URLは、
redis://<id>:<password>@<host>:<port>
の形式で指定します- 雑談のContext保持とCronコマンドの保存に使っています
- Redis To Go のfree planを使うのがおすすめです
- CMDでgo-server-stater経由でbotを起動するように指定してます
おまけ
ちゃんとプロセス死んで再起動するかの動作確認ですが、昔ネタでいれたcommandを実行させるプラグインが役に立ちました。(危険)
何度でも蘇る。
2016年振り返り
主にTwitterの全ツイート履歴を見て振り返る。
振り返り
半分くらいは業務コードと思われる.
開発合宿とかPC持っていく旅行
- 1月: おんやど恵 kyokomi.hatenablog.com
- 2月: 足湯しながら開発
twitter.com足湯しながら開発するぞい pic.twitter.com/DT9Vvbiepo
— きょこみ@公認錬金術師 (@k_yokomi) 2016年2月27日- 7月: 熱海へ(blog書いてなかったな...)
— きょこみ@公認錬金術師 (@k_yokomi) 2016年7月9日
twitter.com- 9月: おふろcafe kyokomi.hatenablog.com
結構同じメンバー何回も開発合宿行ってて、会社が別になっても気軽に集まれる関係なのがいいなと思いました。 来年も行きましょう!!!
各月のサマリー
2〜7月: ひたすらAndroidして退職
- Droidkaigiに行った
- 業務でAndroidエンジニアが居なくて困っていたので、Androidエンジニアにコンバートした
- ひたすらAndroid書いてた。とにかく仕様バグとかクラッシュを削りながらな日々
twitter.comよほどクリティカルなコードじゃない限りテスト書くの諦めてる。
— きょこみ@公認錬金術師 (@k_yokomi) 2016年4月28日
スピード/改善/安全=3/3/4くらいのバランスで維持してる。もう少し落ち着いたらtest書いたりして安全の比率を上げたい。- 去っていた人のコードを当時いた人の気持ちになってリーディングするサイコメトリーをマスターする
twitter.com@axross_ 全身で感じる…! pic.twitter.com/yNv4htPouC
— きょこみ@公認錬金術師 (@k_yokomi) 2016年4月21日
twitter.comば、馬鹿な・・・このソースコードは、サイコメトリーできない。。。
— きょこみ@公認錬金術師 (@k_yokomi) 2016年5月26日- Androidそこそこできるようになったので、Androidエンジニアの採用を頑張っていた
- 制約と誓約を意識して、Goを書かないで全ステータスをAndroidに振っていた
- 7月一杯でGunosyを退職
8月〜9月
- フリーランスとして3社くらい手伝っていた
- この頃からクラスター社でお仕事をしていた
twitter.comなう #cluster #zega #cluster https://t.co/G7AY6zX88u pic.twitter.com/L5mq7tnwNG
— きょこみ@公認錬金術師 (@k_yokomi) 2016年8月31日- 今まで直近の業務にすぐに役立ちそうにないなーと思って積んでいた本をここで一気に消化
- Dockerを使う機会が増える
- Unity再入門
- クラスター株式会社のバックエンドAPIにgoaを導入(それまでは、echoだった)
- ISUCON6予選に出場してギリギリ予選突破
10月〜12月
- クラスター株式会社に入社 kyokomi.hatenablog.com
- HTC VIVEを自宅に導入
twitter.comついに我が家にもHTCViveきました! pic.twitter.com/ZOczCTVeEE
— きょこみ@公認錬金術師 (@k_yokomi) 2016年10月1日- ISUCON6本戦に出場したが敗退 kyokomi.hatenablog.com
- WebAPI書きつつ、AWSメインでterraform書いたり、Lambdaとか触ったりなどなど
- 使っていた折りたたみ自転車のサドルが盗まれたので、これを機にクロスバイクを購入(TREK FX3を買った)
- ついに食洗機を購入
その他
麻雀
2016年は10回くらい打った気がする。役満は1回。 メンツは結構バラバラだったけど、トータル勝ち越した気がする。
twitter.com国士無双上がったぞい pic.twitter.com/jBaLeKmUzh
— きょこみ@公認錬金術師 (@k_yokomi) 2016年3月28日
関係者各位また定期的にやりましょう!!!
個人開発
- GAE/Goでちょっとしたキュレーションシステム
- Androidアプリ2つ(キュレーションのクライアントと、Twitterの画像をひたすら表示するやつ)
- 放置ゲーのAPIサーバーをGAE/Go -> ECSに移行
- 放置ゲーのクライアントをUnityでプロトタイプ作成
相変わらずエターなってるけど、作ったものを自分では使っているのでそこそこ満足している。
まとめ
- 2016年は発表とかブログとかアウトプット少なめで本を読んだり技術検証したりでインプット多めだった気がする
- 温泉行って開発合宿すると疲労を回復しながら、開発が捗るので2017年もやっていきたい
- 2017年はリリースもあるので、Tipsとか開発フローとかについてとか発表したり、ブログでの情報発信とかもしっかりやっていくぞ
werckerでprivate repositoryを含むglide installする方法
手順
- glide.ymlでsshのURLを指定する
- wercker上でApplication Environmentか Organization settings Environmentで
+ Generate SSH Keys
してssh keyを環境変数に登録する - 「2.」で登録したssh keyをgithub上の Settingsの
SSH keys
で登録する - wercker.ymlに
add-ssh-key
とadd-to-known_hosts
を記載する
glide.ymlとwercker.yml
fingerprintはこちらを参考に入力しましょう。
What are GitHub's SSH key fingerprints? - User Documentation
wercker Generate SSH Keys
Application Environment
Organization settings Environment
こっちで指定すると全部のアプリケーションで使いまわせます。
Webラジオのm3u8をdownloadしてffmpegでmp3に変換するツールをGoで書いた
2016/12/15 23:06 追記:
ちなみにffmpegでm3u8 -> mp3変換はできますが、実行時間が20分以上かかって待ってられなかったのでBulkDownloadが含まれてます。
あとm3u8のURLが推測難しく、いちいちブラウザ開いてplaylistをダウンロードして中身のmedia playlistのm3u8のURLを確認して〜がだるかったのでScrapingしてます。
Webラジオのm3u8をScrapingしてtsファイルをBulkDownloadしてffmpegでmp3に変換するツールをGoで書いた
が正確なタイトルですかね。
今期は、ガーリッシュナンバーが結構お気に入りです。
(ちーさまのダメ可愛さがなかなか癖になります)
(そして目玉焼きの服というセンス...圧倒的か...)
なんでこんな話から始まったかと言うと、面白いなーと思った作品のアニメのWebラジオとか結構聴くんですが、なんか専用のアプリがあって使いにくかったり、Webブラウザでしか再生できなかったりと中々不便なので結局ダウンロードすることにしてツールを作りました。
(たとえば、途中まで再生してブラウザ閉じたときに、続きから聴けない...とか)
ここから本編
今回作ったツール
1つのツールにしても良かったんですが、用途考えると別々のほうが使いやすいかなと思って3つに分けました。
はじめに
今回必要なダウンロードの流れは以下になります。
流れ
- 指定したURLのWebページのCrawl
- CrawlしたHTMLから対象のURLをScrapingして抽出
- m3u8のPlaylistのURLを元にtsファイルをBulkDownload
- tsファイルをffmpegでつなぎ合わせてaacを作成
- aacをffmpegを使ってmp3に変換
3〜5のあたり github.com/yyoshiki41/radigo こちらを参考にさせていただきました。
前提条件・事前準備
- Macでしか試してません
- 対象のWebページのURLを用意してださい
- 対象のxpathを適当に調べておく(ChromeDeveloperToolとかで)
- ffmpegをインストールしておく
- Go環境用意しておく
インストールの仕方・それぞれの役割説明
インストール
go get github.com/kyokomi/xcrawl go get github.com/kyokomi/m3u8go go get github.com/kyokomi/ffmpego
役割
- kyokomi/xcrawl : 指定したURLをcrawlして条件のxpathで抽出して出力
- kyokomi/m3u8go : m3u8のmaster playlistからmedia playlistを抽出して出力
- kyokomi/ffmpego : m3u8のURLを元にtsファイルをBulkDownloadしてffmpegを使ってmp3に変換
使い方
xcrawlのオプションで使えるconfig
スマートフォンサイトをCrawlしたいとかのときに使います。
headers: User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Mobile Safari/537.36
実行例
xargsでつなぐと一発で実行できて便利です。
$ xcrawl -c <configファイルのパス> \ -i '<ラジオ再生ボタンがあるWebページのURL>' \ -x '<master playlistのURLが抽出できるxpath>' \ | xargs m3u8go -i \ | xargs ffmpego -o <出力するファイル名> -i
デモ
冒頭にもリンク貼りましたが最近ハマっている、ガーリッシュナンバーの「クズらじ」で試してみます。
$ xcrawl -c config.yaml \ -i 'http://sp.animatetimes.com/radio/details.php?id=gn&a=10&m=a' \ -x '//*[@id="main-contents"]/ul[1]/li[3]/div/div[1]/div/a[1]/@href' \ | xargs m3u8go -i \ | xargs ffmpego -o kuzu3.mp3 -i
これでひとまず満足... ^q^
かなり雑に実装したので、もし自分以外に使う方がいましたら、バグとかあればお気軽に〜(対応するかはわからないが...)
Amazon Lambdaにデフォルトでインストールされているライブラリを最新にして使う方法の1つ
業務でAmazonLambda上でPDFを画像に分割処理を実装したのですが、その時ghostscriptのVersionが古くて、 特定のPDF変換でエラーになるという現象でハマったのでその時調べたことと、 対応策を紹介したいと思います。
前提
- Apex (Go)で動かしてます
- ImageMagickがghostscriptを呼び出している
- ghostscriptが古くてエラー
Apexについては前に書いた記事をご覧ください。
Lambdaのamiについて
Amazon Linux AMI 2014.09 Packages
ghostscript-8.70 ghostscript-fonts-5.50
フォーラムでの質問
https://forums.aws.amazon.com/message.jspa?messageID=611159
AWS Lambda doesn't provide a way for functions to update the Amazon Linux AMI. As has been suggested, you can include alternative versions of libraries, executables, and language runtimes in your function's ZIP file if the default ones available don't address your needs. We'll also be looking at ways to make that process easier in the future through simplified deployment options. Until then, apologies for the inconvenience of having to copy this in with your code.
- AWS LambdaではAMIをupdateする術を提供してない
- もしversionを更新したいならzipに含んで頑張ってくれ
と解釈。/(^o^)\
解決策
- https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs920/ghostscript-9.20-linux-x86_64.tgz をdownloadしてfunction下に入れてzipで一緒に固められるようにする
- もちろんchmod 777とか忘れずに
- 上記をPATHに追加してから
exec.Command("convert")
が呼び出されるようにする
functionの構成
pdf2images ├── bin │ └── gs // 上記のdownloadしたバイナリ └── main.go
コード抜粋
func main() { apex.HandleFunc(func(event json.RawMessage, ctx *apex.Context) (interface{}, error) { os.Setenv("PATH", os.Getenv("LAMBDA_TASK_ROOT")+"/bin"+":"+os.Getenv("PATH")) // TODO: 〜 色々省略 〜 outputLog, err := exec.Command("convert", "/tmp/input/hoge.pdf", "/tmp/output/hoge.png").CombinedOutput() if err != nil { return nil, err } log.Println(string(outputLog)) return nil, nil }) }