ハッカソン素振り成果

マネーフォワードのAPIを提供したハッカソンに技術サポート兼デモサーバーのおもり兼メンター代打として参加してきた。

OAuth2といっても、使い方までいたれりつくせりのtwitter/facebook/github あたりのライブラリしか使ったことなかったので、一定時間で作れる範囲がだいぶ違うなーという感想。そりゃ世間のハッカソンも、ハッカソンという名のチーム戦・短納期デスマーチになるわ。

OAuth2API経由で触ったことないから、素振りしてみないと全部わかりませんで話にならんだろう、ってことで素振り。
ただ、ギョームに追い詰められて、当日含めてもtoken取るところまで疎通確認するのでやっとだった。

ハッカソン後日にようやく出来て、おもしろおかしい成果物animetion gifが撮れてほっとした。
game-with-transactions
おもしろおかしく書いたエントリ: Moneyforward APIで車ゲームを作る | Money Forward Engineers’ Blog

構造を知っている、入出金履歴のデータを引っ張ってくる。
日にちごとにサマリーして、ない日は0で埋める。
それを元データにして座標プロットして、phaserjsのexampleの座標データと差し替える。
たったこれだけやるのに、56 commits / 4,571 ++ / 398 —

仕様はOAuth2でわかりやすい、データ取りに行くはじめのところはsimple-oauth2のexampleからコピペ、ゲーム部分はphaserjsのexampleからコピペ、でほぼ何もしてないのに結構時間はかかるわ、$40の有償プラグイン使うわで、しんどかった。
デモサーバー自体は多分クローズドだから、サーバー立てておいてみんなに遊んでもらうわけにもいかないし。
遊べたとしてもみんなデモデータだからなー。

作り始める時には意図しなかったいいオチが勝手についてくれた幸運と、読んでくれた人は楽しんでくれたみたいなので救われる。

成果物 https://github.com/sanemat/purple-finch とpackage.json(最後)。

ライブラリは提供していないので、simple-oauth2を使い、それを使ってるライブラリを見ながらぱくる。
なぜか手元でdirenvが動かなくて、dotenv使うことにしたのがはまったとこ。
テンプレートにmarkojs使ってみたのは初めて。
https://github.com/marko-js/templating-benchmarks pugかejsか使おうと思ってたところでこれ見て使ってみることにした。
node --inspect --debug-brkってのもおもしろい。サーバー起動すると、websocketのurlが出て、それをchromeで開くと一行目で止まる。
ブレークポイントを入れて、play!
ゲームエンジンphaserjsも、なにかゲームエンジン使ってみたかったので多少は満たされた。カジュアルゲー作れるぐらいの瞬発力は欲しいもん。
github pagesに置いて動くようにしたいところだけど、implicit flowじゃないからだめなんかな。
aws lambdaやamazon api gatewayかそういうの使えばgithub pages + それで出来そうな気がしたけど、気がするところまで妄想しただけで確認していない。こういうのAmazon API Gateway の Custom Authorizer を使い、OAuth アクセストークンで API を保護する – Qiita かな。

package.json

{
  "dependencies": {
    "dotenv": "^2.0.0",
    "express": "^4.14.0",
    "marko": "^3.12.1",
    "moment": "^2.17.0",
    "moment-timezone": "^0.5.9",
    "request": "^2.79.0",
    "request-promise-native": "^1.0.3",
    "simple-oauth2": "^1.0.1",
    "urijs": "^1.18.3"
  },
  "scripts": {
    "start": "node -r dotenv/config app.js",
    "debug": "node --inspect --debug-brk -r dotenv/config app.js",
    "lint": "eslint .",
    "lint:fix": "eslint --fix .",
    "test": "ava",
    "verify": "npm run lint && npm test"
  },
  "devDependencies": {
    "ava": "^0.17.0",
    "eslint": "^3.10.2",
    "eslint-config-airbnb": "^13.0.0",
    "eslint-plugin-import": "^2.2.0"
  }
}

ビットコインとか勉強会 2 で話してきた #暗号通貨読書会

ビットコインとか勉強会#2 – connpassで20分もらって話してきた。

前口上ここから

bitcoin関連で仕事をしているみなさん、ってびりあるさんから話がありました。
ごめんなさい一ミリもしてないです。
働いてるのはマネーフォワードという会社で、普通に家計簿のrailsアプリ書いてます。

今日は2つ話を持ってきました。資料は #暗号通貨読書会

誰向けになんの話するかって言うと、二ヶ月前の俺向けですね。
bitcoinに興味あるけど、bitcoinさわったことない。
mastering bitcoin読んでみたけど、よくわかるようなわからないような。
bitcoin読書会来てみたらAsicBoost マークルルートのコリジョンの話、より効率的にマイニングできるかもしれないの論文の話してて全然わからんぞ、みたいな。
なので、まあこういうアプローチもあるんじゃない的な。

ぼくは自分でやってみないとわからなくて、やってみて学んだので、みなさんがやってみなくても持って帰れるようにしました。

WalletのUXTO (未使用残高)をwallet実装無しで計算するツールを作ろうとした。
現在進行形で作りかけ。
結論は「既存のWalletを使え」なんだけど、そのツールを作る過程でbitcoin HD Walletのしくみを理解してきたので、まとめました。

質問は雑談形式でどんどん投げて話止めてください。

前口上ここまで

発表中反応してくれた方、質問してくれた方、質問をまるなげして答えてくれた方、懇親会で話聞いてくれた方、ちょこちょこいらっしゃったので、自分の発表が手探り感満載だった割にはよかったんじゃないかなーと自画自賛しています。

資料よく読むとろくに実装面ではまだ手が動かせていないというのがわかるので、次次回ぐらいにはちゃんと実装を持っていって、感想を話します。

1個のライブラリにまとめたくなる呪縛

rubyのgemは1個のgemがやろうとすることが多すぎる。npm moduleは1メソッドが1packageぐらいの粒度。だから自分はnpmが好き。

って普段から言ってるのに、似たようなことやるからこのgemにメソッド生えてたほうがいいかな、とメソッド増やそうとしてしまった。気づいたから良かった。packageわけよう。rubyだから、nodejsだから、というわけでもないと思うんだが何なんだこの呪縛は。

shields.ioにmergeされるまでのこぼれ話

shields.ioにchrome web store対応がmergeされるまでの、chrome extensionのバージョンのバッジを表示する | 實松アウトプット こぼれ話。
mergeされたい人は参考にしてくれ。

2015/7

shields.ioでchrome extensionのバッジ出したいな、と思う。
まず思ったのが一番間違っていた。
shields.ioに取り込まれる練習にもなりそうだ、という勘違い。

公式APIがない。

How to get chrome extension’s meta information (e.g. version, name) from Chrome Web Store? – Stack Overflow

みんなwebページをスクレイピングします。…まじっすか。

chrome web storeのhtmlをスクレイピングしてparseするモジュールを書く。

2015/8

Support chrome web store by sanemat · Pull Request #505 · badges/shields

  • htmlスクレイピングは勘弁してくれ
    • ですよね(sanemat)
  • cheerio ぶっこむなんて今までで一番大きい依存だぞ
    • そうですね(sanemat)
    • lodashまるごと使ってるcheerioがわるいだろ…
  • htmlスクレイピングだけど、未来永劫取れるのか? 少なくともオープン当時の2010年のhtmlから取れるならいいけど
    • google にpublicなAPI作ってもらうよう話をするのが正当じゃないの
      • いやまあそりゃ正論はそうだし、いちおうメーリングリストで話しかけては見るけど(sanemat)
    • !???!??! (今2015年だぞ?) web-archiveで2013年のhtmlはparseできるけど、そりゃ明日取れるとは保証できないですね(sanemat)
      • じゃあgoogle の反応待ちだね
        • そうですね(sanemat)
          • 放置

2015/11

じゃあもういいっす close(sanemat)

2016/1

add chrome extension version badge · Issue #636 · badges/shields

  • chrome extensionいれてくれー
    • そういえば前pull request来てたわ
      • なんで入れないの? 壊れたら直せばええやん どうです @sanemat
        • 今も動いてるならいれてやってもいいよ 6ヶ月ごとぐらいに直すの嫌じゃん

2016/4

ここでノコノコ出てくのもシャクではある。が、ノコノコ出て行ってマージされて世に出た。Add chrome extension support #687。めでたしめでたし。
あと、shieldsプロジェクト、nodeっぽくないアプリなんだよね。
クライアントライブラリなど使わずにrequestで全部リクエスト作る自前主義。理屈もあって、リクエストをキャッシュしないとどうにもならないので、そのへんを作りこんだことによって、自前で書かなくてはいけなくなってしまった、ある意味仕方ないともいえる。
まあ(勝手に)頑張ってくれーとは思わなくもない。

理屈もわからなくはなくて、こういうのって導入するときだけみんな頑張りに来て、あとで直すのは自分たちだ、動かなくて文句言われるのも自分たちだ、という実情がある。
ちょっと違うけど、homebrewのsanemat/fonts (ricty) もだいたいそんな感じになって読めないコードになった。なので、そういう文化圏があることは否定しない。

簡単でした(再掲)

chrome extensionのバージョンのバッジを表示する

chrome extensionのバージョンのバッジ(こんなの)
Chrome Web Store
を、例えばGitHubのリポジトリのreadmeに表示する。

TL;DR

<a href="https://chrome.google.com/webstore/detail/do-not-merge-wip-for-gith/nimelepbpejjlbmoobocpfnjhihnpked"><img src="https://img.shields.io/chrome-web-store/v/nimelepbpejjlbmoobocpfnjhihnpked.svg?maxAge=2592000" /></a>

こう指定する。aタグのhrefはまあどこでもいいけど、detailのページに向けてやると親切げ。

必須要素

chrome extensionのdetailぺーじから、謎のIDっぽい文字列を得る。
https://chrome.google.com/webstore/detail/do-not-merge-wip-for-gith/nimelepbpejjlbmoobocpfnjhihnpkednimelepbpejjlbmoobocpfnjhihnpkedコレ。

https://img.shields.io/chrome-web-store/v/nimelepbpejjlbmoobocpfnjhihnpked.svg?maxAge=2592000 vだと バージョン、dだと ダウンロード数、priceだと 金額、ratingだと レーティング、rating-countだと レーティングの数、が表示できる。

詳細は、Shields.io: Quality metadata badges for open source projects 参照のこと。

chrome webstore

これ実はchrome extensionだけではなく、chrome webstore対応なので、chrome app, chrome extension and chrome theme も表示できる。便利ですね。簡単ですね。

簡単ですね

ほぼ一年かかりました。

どこまで、npm, nodejsに寄せるか、どこまでrailsに残すか

特に結論はない。

前提

自分

自分はrailsを中心としたwebエンジニア。ここ1年半ぐらいはnode.jsにベットして活動してる。
node.jsは使われてるところでは使われてるけど、思ったより日本ではこねーな、というのが個人的な感想。
フロントエンドのツールチェーン作るならnode.jsだろうな、という感じ。
だけど、最近はツールチェーン作るならgolangなんじゃないかな、という気もしてきていて、手持ちのツールをgolangで試してみている。
node.js, npmにベットしているけど、特段フロントエンドエンジニアではないし、html, cssが弱い。

マネーフォワード社

マネーフォワード社の基幹技術はサーバーサイドにjava, ruby。クライアントサイドにandroid java, objective-c/swift。
mfクラウドチームでは、pc入力がメインなので、android java, objective-c/swiftがjavascriptに変わる。
javascriptでの開発もそれなりにチーム組んで取り組んでいる。
一方pfm(家計簿)チームは、まずwebから開発をはじめて、その次スマホアプリに全力でかじを切って、いまここというかんじ。

どこまでjavascriptに持っていく?

ここから、どこまでイマドキっぽいフロントエンド開発に持って行こうかな、持って行くべきなのかな、とぼんやり考えている。
イマドキっぽいってなに?

やらないこと

ライブラリはnpmで入れてwebpackでっしょー。railsのassets pipeline今すぐやめようぜ。railsの役割はapiサーバーまでにとどめよう。
みたいなのは、チームの状況を見るに、コストパフォーマンスもメリットも薄いなーと思ってしまう。nodeでサーバーサイドレンダリングやりたくないし。railsでいいじゃん。

やること

dom操作でjqueryでってのを過去分修正するかはともかく、これから作るのは精神に悪影響ありそう。

そのうちやること

rubyのgemでjavascriptをwrapしてますというのは、シシルイルイなのでやめたい。あれ筋悪。
同じ言語のgrunt-*, gulp-*, yeomanのgenerator-*, でもみんなしぬんだぞ。
ワンクッションrails-assetsやらbowerやら挟みたいが、どっちもしんでしまっているからな。
じゃあやっぱりnpm + webpackになってしまうではないか。

思うこと

これでjavascriptが会社の超主要言語なら、超やれ、当たり前だろ、って感じ。
でも、そこまでじゃない。サーバサイドやるならjava, better javaとしてscala, ruby, apiサーバー作りたいならgolang, あたりやるほうがコスパ良さそうに思ってしまう。
それかandroid java, swift。それかビジネス寄りに動いていくとか、データ分析側とか。やるほうがいいんじゃないかなーと思う。
javascriptはそれなりに必要な言語なんだけど、そこまでなあ、うん。

特に結論はない。

conventional-changelog v1.0.0が出てcliのapiが変わった

tl;dr

ふえー

他にもショートハンドのオプションは変わってるのかも。自分はこれだけでひとまず行けた。
https://github.com/dogwalk/firefox-page-for-hatena-bookmark/pull/19/files

これをnpm moduleとgem packageぶんやるのか… やらない…

GitHub Issues/Pull requests を高速に整理する “Triage for GitHub”

TL;DR

GitHub issueとpull requestのやるやらないを、すばやく振り分けていくためのデス
クトップアプリ “Triage for GitHub“を作りました。

triage-for-github

GitHubのIssue, Pull Requestを迅速にさばいていくことが出来ます。

Motivation

Dependency Update as a Service – Tachikoma.io, greenkeeper, deppbot – Automated Dependency Updates を使うことで、ガンガンpull requestを飛ばし、CIやカバレッジなど、GitHubのエコシステムに乗ることが出来るようになりました。

(tachikoma.io 使ってね!)

ただし、数が増えるとpull requestを持て余します。見逃すこともしょっちゅう。

too-many-pull-requests

特に定期ping的に空pull requestでciを起動するような場合、ciが通っていることを
確認したらガンガンpull requestを閉じたい。

Plan A: /pulls

https://github.com/pulls

github-pulls

GitHubには自分のpull request一覧を見るページがあり、これは求めるものに近いものがある。他にも、検索を使ってorganizationのpull request一覧を見る方法もある。しかし、現状どうしてもポチポチクリックしていく必要があり、閉じていくのも面倒くさい。

Plan B: Triage for GitHub

triage-for-github

そこで、ガシガシ閉じていく専用のデスクトップアプリを作りました。
ランチャーみたいなイメージで、気になるのあったら’Jump’してGitHubのUIを開いて確認していく、GitHub Issueのトリアージを実現します。

使い方

セットアップ

Latest releaseから自分の環境のzipをダウンロードします。

settings

settingsに、GitHubのpersonal tokenを入れてください。scopeは repo or public_repoで、つまり、private+public repos or public reposのどちらかのトークンを入れます。

トークン未入力の場合、lyrictenor/example-issuesのissues/pull requestsを表示します。issue立てたり、pull requestを送ったり、自由にどうぞ。雰囲気はつかめると思います。

トークン未入力の場合、GitHubのAPIリクエスト回数制限が極端に少ないです。
https://developer.github.com/v3/#rate-limiting

60 requests per hour.

一定時間IP制限かかるので注意です。

トークンを使っていても、人によっては結構な回数APIリクエストをするアプリなので、過剰な巡回・起動には注意してください。

表示

updated atの新しい順に、5日ぶんのissue/pull requestが並びます。日数はひとまず固定です。

実験的機能 自動巡回

autopilotをonにすると、定期的に自動巡回します。
が、コレはまだ動いたり動かなかったりです。

autopiloting flagがonになったままになってしまうバグが有るため、そうなった場合
はdebug paneから force unlockしてください。

issueの詳細

issue, pull requestの詳細は v っぽいアイコンをクリックしてください。

show-details

まとめ

GitHub issues, pull requestsをガンガン振り分けできる “Triage for GitHub”を作ったのでガンガン整理できる。

使ったnpm modules

力作。package.json

  "dependencies": {
    "classnames": "^2.1.3",
    "crossing": "^1.0.1",
    "crypto-js": "^3.1.5",
    "electron-debug": "0.3.0",
    "electron-open-link-in-browser": "^1.0.1",
    "electron-template-menu": "1.0.3",
    "es6-error": "^2.0.0",
    "is-empty-object": "^1.1.0",
    "level-js": "^2.2.2",
    "level-sublevel": "^6.5.2",
    "levelup": "^1.2.1",
    "lodash": "^3.10.1",
    "material-ui": "0.13.1",
    "moment": "^2.10.6",
    "octokat": "^0.4.11",
    "react": "^0.14.2",
    "react-addons-create-fragment": "^0.14.2",
    "react-addons-pure-render-mixin": "^0.14.2",
    "react-addons-transition-group": "^0.14.2",
    "react-addons-update": "^0.14.2",
    "react-dom": "^0.14.2",
    "react-redux": "^4.0.0",
    "react-router": "1.0.0-rc4",
    "react-tap-event-plugin": "0.2.1",
    "redux": "^3.0.0",
    "redux-batched-updates": "^0.1.0",
    "redux-devtools-dock-monitor": "^1.0.0-beta-3",
    "redux-devtools-log-monitor": "^1.0.0-beta-3",
    "redux-form": "^3.0.0-beta-4",
    "redux-thunk": "^1.0.0",
    "reset-storage": "^1.0.1",
    "rndm": "^1.1.0"
  },
  "devDependencies": {
    "archiver": "^0.16.0",
    "babel": "^5.8.23",
    "babel-core": "^5.8.23",
    "babel-eslint": "^4.1.1",
    "babel-loader": "^5.3.2",
    "babel-plugin-react-transform": "^1.0.3",
    "babel-runtime": "^5.8.20",
    "buffered-spawn": "^1.1.2",
    "conventional-changelog": "^0.5.0",
    "cpy": "^3.4.0",
    "css-loader": "^0.21.0",
    "eclint": "^1.1.1",
    "electron-packager": "^5.0.2",
    "electron-prebuilt": "0.34.2",
    "eslint": "^1.3.1",
    "eslint-config-airbnb": "0.1.0",
    "eslint-loader": "^1.0.0",
    "eslint-plugin-babel": "^2.1.1",
    "eslint-plugin-react": "~3.6.3",
    "espower-babel": "^3.3.0",
    "express": "^4.13.3",
    "extract-text-webpack-plugin": "^0.9.0",
    "fixpack": "^2.2.0",
    "globstar": "^1.0.0",
    "html-webpack-plugin": "^1.6.1",
    "is-travis-ci-build-for-tag": "^1.1.1",
    "json-loader": "^0.5.2",
    "mocha": "^2.3.0",
    "npm-check-updates": "^2.2.0",
    "power-assert": "^1.0.0",
    "react-transform-catch-errors": "^1.0.0",
    "react-transform-hmr": "^1.0.1",
    "redbox-react": "^1.0.5",
    "redux-devtools": "^v3.0.0-beta-3",
    "rimraf": "^2.4.3",
    "silence-chromium": "^2.0.0",
    "style-loader": "^0.13.0",
    "touch": "^1.0.0",
    "webfont-dl": "^0.1.2",
    "webpack": "^1.12.0",
    "webpack-dev-middleware": "^1.2.0",
    "webpack-hot-middleware": "^2.1.0",
    "yargs": "^3.23.0"
  },

nodejs v4対応観察日記 9月10日前後

Topic

  • node-gyp v2.0.2 -> v3.0.1
  • npm v2.14.3, v3.3.2 includes node-gyp v2.0.2
  • fsevents v0.3.8 -> v1.0.0
  • engine.io-parser v1.2.1 -> v1.2.2
  • contextify
  • meta list

node-gyp

node-gypが v3.0.0 に メジャーバージョンアップした。

  • windows用のオプションのデフォルト変更でbreaking change
  • iojsで使おうとするとnodeのv3.3とかを取りに行こうとしてダウンロード失敗してたのを解決するようにした (インパクト的にはぶっちぎりこっちなんじゃないかな)
    use process.release, make aware of io.js & node v4 differences

さっそくnode-sassとかnanとかがpangypからnode-gypに戻ってる。

だから、pangypとか node-pre-gypとかを代替に使ってるproduct多かったのか。納得。

npm includes node-gyp v2.0.2

ただ、まだ npm (v2もv3も)にnode-gypを添付してて、それがv2なので、自分で
node-gyp v3をグローバルに入れても(?) なんかv2が使われる、ケースに遭遇した。ここの意味はよくわからない。というかどのタイミングでnode-gyp rebuildを走らせているのかさっぱりである。

npm定期的にリリースする話は、以前watildeが発表してたの聞いた。それに合わせて依存も突っ込んでるっぽいから、とりあえず待つ。npm v3は作業してるissue見た。v2はどこで作業しているのかわからない。

Update out-of-date modules for this week’s 3.x by iarna · Pull Request #9535 · npm/npm

npm メンテナー

読み応えがある。涙涙っぽい。
npm in 0.10 LTS · Issue #37 · nodejs/LTS
これからだけど。

npm install

npmがnpm modulesに依存しててどうやってインストールするのかな、と前ちょっと思ったのだけど、node_modules以下を同梱してるのね。なるほど。

fsevents

node-gypからnode-pre-gypに変更。これがbreaking change.
fseventsに依存するchokidarがまだ修正中で出てない。だいたいのfsevents使うやつはchokidar経由なのでもうちょっと。

socketio organization

engine.io-parser出た。キタ! nodejs v4対応。 socket.ioちょっとずつ進みはじめた。
engine.ioなんかいくつかリリースしてたけどテストは壊れてるのでこれ動いてるんかな???。 engine.io-client これちょっとengine.ioのmasterが今壊れててよくわからない。

見てるぶんにはジェットコースター。

contextify

たすけてくれ!!って言うとスーパースターが集まってくれる。
Update for NAN@2 (incomplete) by rvagg · Pull Request #181 · brianmcd/contextify
Upgrade NAN for Node 4.0.0 · Issue #180 · brianmcd/contextify

meta list (Added 2015-09-11 2:22)

Packages that currently do not work with Node.js v4.0 [List] · Issue #2798 · nodejs/node

すごい長いリストが。

nan v2対応part3

nan v2対応part2 | 實松アウトプット続き。

iojs v3, nan v2続報。
手元で使ってたので引っかかるmodule。
あと、packages depending on ‘ws’眺めてた。

https://github.com/EyalAr/lwip
https://github.com/strongloop/fsevents
https://github.com/socketio/engine.io
https://github.com/node-inspector/node-inspector

fseventsはmasterはよさそう
デカ目のこれが入ったので様子を見てる? 数日中に出そう
https://github.com/strongloop/fsevents/pull/59

socketioは進捗ないですけどなんていうかがんばってください。

lwipは直して!! ってissue来てるけどpull request出てないからキビシイかも。
ownerはちょっと難しいのでdelayするって言ってる。
https://github.com/EyalAr/lwip/issues/169

node-inspector 頑張ってるけど単純に機能追加とかいろいろ来てて混じってて大変そう。作業中。