レタスのかわをぜんぶむく

ぜんぶむきます

はじめてOSSにコントリビュートした

概要

github.com

上記のリポジトリに出したPullRequestが2つマージされた。
仕事でも使っていたライブラリなのでうれしい!

行った変更

  • テスト設定の変更
  • 依存するライブラリの更新

テスト設定の変更

この変更を入れる前はテストコードの一部がシステムのロケーションに依存していて
いわゆるen_USの環境でないシステム上だとmvn testに失敗するケースのある状態になっていた。

原因はxls(xlsx)ファイルのセル内にある日付形式の文字列 aa/bb/cc を読み込む際に
mm/dd/yyとするか、dd/mm/yyと解釈するかの基準が明示的に指定されていないためだった。

最初にチェックアウトしてまずテストを試した時に、日付文字列の読み込みテストで失敗してしまっていたので
多分ロケーション周りだろうと思って、Macの言語設定やタイムゾーンを色々試して通るようになったのを確認後に
mvn testJVMのパラメータを渡すにはどうすれば良いんだっけという点を調査して対応した。

知らなかったけど、maven-surefire-pluginというものがあるらしい。

https://github.com/takezoe/xlsbeans/pull/12

理由に気がつくと確かに理屈はわかるんだけど、自国以外で動作するようなコードであって
かつ言語設定が絡むようなものを実装したことがなかったので、色々調べながら対応していて勉強になった。

依存するライブラリの更新

こっちが最初解決しようとしていた問題。いわゆるJar地獄問題で
依存するライブラリが別バージョンの同じライブラリを参照していると
不幸な問題が発生することがまれによくある

今回のケースでは内部的に利用しているjavassistのバージョンに問題があった

$ mvn dependency:tree
~略~
[INFO] com.github.takezoe:xlsbeans:jar:1.2.6
[INFO] +- net.sourceforge.jexcelapi:jxl:jar:2.6.12:compile
[INFO] |  \- log4j:log4j:jar:1.2.14:compile
[INFO] +- org.apache.poi:poi:jar:3.6:compile
[INFO] |  \- commons-logging:commons-logging:jar:1.1:runtime
[INFO] |     +- logkit:logkit:jar:1.0.1:runtime
[INFO] |     +- avalon-framework:avalon-framework:jar:4.1.3:runtime
[INFO] |     \- javax.servlet:servlet-api:jar:2.3:runtime
[INFO] +- org.apache.poi:poi-ooxml:jar:3.6:compile
[INFO] |  +- org.apache.poi:poi-ooxml-schemas:jar:3.6:compile
[INFO] |  |  +- org.apache.xmlbeans:xmlbeans:jar:2.3.0:compile
[INFO] |  |  |  \- stax:stax-api:jar:1.0.1:compile
[INFO] |  |  \- org.apache.geronimo.specs:geronimo-stax-api_1.0_spec:jar:1.0:compile
[INFO] |  \- dom4j:dom4j:jar:1.6.1:compile
[INFO] |     \- xml-apis:xml-apis:jar:1.0.b2:compile
[INFO] +- ognl:ognl:jar:3.0.2:compile
[INFO] |  \- javassist:javassist:jar:3.11.0.GA:compile <=ココ
[INFO] \- junit:junit:jar:3.8.1:test

詳しくはPullRequestに記載しているけど、あるバージョン以下のjavassistの機能(?)をJDK8で利用すると
java.io.IOException: invalid constant type: 18というエラーを吐いて死ぬという問題がある。

https://github.com/takezoe/xlsbeans/pull/10

もちろんプロジェクト依存関係の設定側で特定バージョンの使用を強制させるワークアラウンドもあるけど
依存しているライブラリのAPIの互換性に問題がなければ、より色々なバージョンで動作した方がよいでしょう
ということで、古いjavassistを参照しないよう、ognlのバージョンを上げた差分を作ってPullRequestを出した。

オチ

両方調べて解決するのに4時間くらいかかったんだけど実際の差分はpom.xmlの数行だけ。
次回はソース部分の修正で貢献できるようにがんばります。

f:id:uskey:20190211163856p:plain:w400

Mac環境 再構築用メモ

いつも使ってるマシンが急に死んだりしたときリカバリ手順が無いと詰んでしまうので整理。
両方のマシンが生きていて、移行するならツールなりなんなりを使ったほうが良さそう。

優先度をつけて一時的な環境として割り切って使うならフルで実施しなくても大丈夫だった。

普段からやっておくこと

やってないと飛んだ時に詰むので注意する。

  • 鍵ファイルやhome/.*に配置されているファイルのバックアップ
  • ネットワーク設定の把握()

導入するもの

意外といろいろ使ってたので列挙

Chrome

www.google.com

初期ブラウザは普段遣いブラウザを入れるためにある。
ログインするとブックマーク、拡張機能やパスワード管理が使えるので
人によってはこれだけで一通りの環境が戻ってくるかもしれない。

入力関連

  • karabiner-elements

pqrs.org

普段JISキーボード使いなので左CapsLockを潰してControlにするくらいしかしてない。
USキーボードを使うことになったときは、最下段を大胆に変えて対応する。
記号キー周りは使ってるうちに思い出すのでメイン部分はほぼ変えない。

f:id:uskey:20190120081723p:plain:w500
US→嘘JISへのバインディングの様子

www.google.co.jp

システム環境設定>キーボード>入力ソースからデフォルトの設定を外す。

コミュニケーションツール

  • Slack

slack.com

複数ワークスペースに入っている人は個別にドメインを入れて参加するより
メールアドレスから所属済みワークスペースを検索した方が早い。

https://slack.com/get-started#find

  • LINE

開発ツール

  • Git Kraken

www.gitkraken.com

Gitクライアント。イカがかわいいのと体感でSourceTreeより軽い。

  • SDKMAN

sdkman.io

JVM系は一通りこれで入りそう。
メイン言語JavaなのでJavaとGradleなどを導入。

www.jetbrains.com

  • Docker

docs.docker.com

  • Postman

www.getpostman.com

  • iTerm2

www.iterm2.com

その他

  • Inkdrop

inkdrop.app

ノートアプリ。
日々の記録とかいろいろなメモは一旦放り込んで後からタグ付けして整理している。便利。

思い出したら追記する。

githubで脆弱性アラートが出てたので対応した

githubリポジトリが依存しているライブラリなどをスキャンして
脆弱性があるバージョンを使っているとアラートを出してくれる。(知らなかった)

なにげなく前々回の記事で作ったリポジトリを眺めていたときにアラートを発見した。

f:id:uskey:20181204003459p:plain

なるほどなにか脆弱性があるっぽい。

f:id:uskey:20181204004049p:plain

どうやら内部で利用している `requests` というライブラリに脆弱性があるとのこと。

f:id:uskey:20181204004304p:plain

2.19.1以前だとhttpsからhttpにリダイレクトされた際に問題がある模様。

そこまで分かればとりあえずPipfile.lockを更新後動作確認して対応完了。
調べたところどうやらこの仕組みは2017年11月から動作しているもので
現在はJS, Ruby, Python, Java, .NETをサポートしているらしい。


そういうのはメールで通知くれ頼む〜と思って、通知設定を確認したら以下のようになっていた。

f:id:uskey:20181204004842p:plain

もしかすると2017年11月以前に登録したユーザーはデフォルトだと通知が飛ばないようになってるかもしれない。
ので、全部受け取るように変更した。

今回のケースでは特に影響の無いタイプの脆弱性だったため、「ほーん」という感じだったが
CVE追っかけたりするのはかなり大変なのでとても助かる。

Goでカラバリをシュッと生成するCLIツールを作った

作った

github.com

動機

社外の人も参加する勉強会的なイベントで
プレゼンをする機会があり、資料作成にすごい時間がかかり非常につらかった。
人前で喋るのはすごく嫌いというわけじゃない(≠得意)けど、資料作成は苦手。

どうせなら資料きれいな方がよかろ、図も入れたろとなった時に絵心が不在なので
ライセンス的にセーフな素材を色々なところを探しまわる必要がありつらい。

配色・デザインセンスは壊滅的なものの、視認性良くないだろ的な部分は気づいてしまうので
色味調整するために色々いじっていると更にすごい時間がかかってしまいつらい。

他にもいい方法あるかも知れないけど、GIMPダウンロードしてきて色相調整して書き出して…
みたいなことをやっていると、あと2時間後に発表みたいなことになっているのでとてもつらい。

いい感じの素材があったら、それをもとに簡単に別の色のパターンが出てきて欲しい。

機能

画像をひとつ入力に取って色相(彩度、輝度)を変化させた画像を複数出力する。
イメージはこんな感じ。
f:id:uskey:20181204011200p:plain

仕組み

まず入力された画像を内部的にRGBカラーモデルからHSL色空間に変換する。
HSL色空間では、色相(Hue)を極座標系のように扱えるため
色相を少しずつ変えていけば同じ彩度輝度で別の色パターンを簡単に生成できる。
後は出てきて欲しい画像の数に合わせて、色相の分割数を増減してファイルとして出力する。(初期値は10)

(参考)
zemax.seesaa.net

その他細々としたこと

HSL色空間を利用してカラバリを作るにあたって考慮しないといけなかった点はグレースケール画像と白黒の単色画像。
グレースケール画像は彩度が、白黒の単色画像は彩度と輝度が0なので、いくら色相を変化させても元の色のまま。
今回のツールではグレースケールか白黒の単色画像を検出して、その場合は彩度と輝度に適当な値(50%)を入れている。

go内部で色の取り扱いは乗算済みアルファが用いられているので単純なRGBと思っていじるとイメージ通りにならない。
(値域が0 ~ 255ではなく0 ~ 65025 (255*255))
なのでストレートアルファとして扱いたいときは、color.NRGBAを使う必要がある。

(参考)
qiita.com

謝辞

ヒューマンピクトグラム2.0 様
種類すごいたくさんあって改変利用OKで本当に助かりました。
pictogram2.com

物理出勤ボタンを作った

今勤めている会社では最近になって労働形態が裁量労働制からコアあり(12-16)のフレックスになった。
そのため出退勤の記録を(割と)ちゃんとつけるようになったのだが、それがまあまあ面倒。
いや、そこまで言うほど面倒ではないのだけれど、忘れる。忘れるので後から怒られる。

これまで特に記録していなかったのだからまあ仕方ない気もするが、怒られるのは困る。
ということで、ちょっと前に買って持て余していたAWS IoT Enterprise Buttonを使って物理出勤ボタンを作った。

前提

会社では勤怠管理にジョブカンという勤怠管理ツールを使っている。

これまで1ホップ前とか2ホップ前の会社では使っていなかったのだけれど結構導入している企業もある模様。No.1って書いてあった。
公式にSlack連携を提供していて、なんと設定をするとSlackのコマンドで出退勤時の打刻、稼働時間表示、残有給表示などなどができる。
これで気まずい思いをしながら人事のお兄さんお姉さんに残有給を確認したりする必要がなくなった。

それで、今回はIoT Buttonが押されると出退勤時の打刻がされて欲しい。
ジョブカンがAPIを提供していればそこを叩いてもよいのだけど、ちょっと調べた感じだとなかったので
ジョブカンに連携しているSlack側に対してどうにかしてコマンドを実行させる。

構成

f:id:uskey:20181017104005p:plain:w350

IoT Buttonが押されたらそれをトリガにAWS IoTからAWS LambdaでSlackにコマンドを実行する。
スラッシュコマンドでジョブカンが動作して出退勤の打刻がされる。
登場人物少ないしかんたん(そうに見える)。

準備

スクリプトの作成

社が使ってる言語はJava, Ruby, Goだけど、個人的に小さいのを書くのにはPythonを使うことが多いのでPython
前にbotを作るのに使った下記のライブラリを使う。

github.com

APIを利用してコマンドを実行する場合留意する点は2つ。

通常のIncoming Webhooksなどであれば連携用のトークンを生成して利用すればよいのだけど
今回の場合、Slack上でジョブカン連携済みユーザーとして投稿するためレガシートークンを利用する。
(レガシートークンは現在非推奨となっているが、ユーザーになりすまして投稿する必要があるため致し方ない)

  • 非公開APIchat.command を利用する

非公開APIchat.command を利用する。
Slack側のAPIドキュメントには無いが、何故か有志が公開したものが以下にある。

github.com

非推奨のトークンで非公開のAPIを叩いていて非常に治安が悪い。
動作しなくなる可能性もあるので、その場合は諦めて別の実装にするか諦めるかする。

書いた

github.com

書いたコードは20行ちょっと。
Lambdaに上げるために関連するライブラリも含めてzip化している。
こういう時周辺ライブラリが充実してる言語は強いなあと思う。

Lambda側の用意

新たにLambda Functionを作成して、スクリプトはさっきのリポジトリのzipファイルを設定する。
ランタイムは Python 3.6, ハンドラは上記のzipだと slack_slash_command.lambda_handler

ユーザーのレガシートークン、投稿先のチャンネル、発行するコマンド、付随するテキスト(省略可)を環境変数に設定する。
f:id:uskey:20181017105219p:plain:w400

テストして意図したチャンネルに投稿されていればOK。

IoT Buttonのセットアップ

セットアップにはスマートフォン向けアプリがあるのでそれを使う。

iOS : https://itunes.apple.com/us/app/aws-iot-button-dev/id1178216626?mt=8
Android : https://play.google.com/store/apps/details?id=com.amazonaws.iotbutton&hl=ja

f:id:uskey:20181017030447p:plain:w200
起動してログインするとこの画面である。

精神年齢が小学生のままなので、この時点でIoT Buttonの外箱とか捨てちゃっていた。
箱の横にバーコードとかあって、スキャンすると一発らしいけど丁寧にデバイスIDを手打ちしていく。
6, 10, 14文字目を入力すると、バグって二文字入力されるという不具合があって厳しい(自分の環境だけ?)
ここで入力ミスをしたり、次のWifiSSIDやパスワードでミスると最初からやりなおしになる。
入力も楽しい!と思える人以外は素直に箱を残しておいた方がよさそう。

Amazon 1-clickから Lambdaへの連携を設定する

IoT Buttonとの接続に成功すると、AWSコンソールのAWS IoT1-Clickから登録したデバイスの設定が出来るので対応する。
ブラウザからIoT Buttonの残電池容量とか見れるのいい感じ。

プロジェクトを新規作成して名前を設定、デバイス種別をすべてのボタンに設定
アクションをLambda関数の選択として 、さっき作ったLambda Functionを設定する。

プロジェクトを作成後、新規プレイスメントの設定をしてさっき登録したIoTデバイスを選択して終了。
うまくいっていれば、IoT Buttonを押すと3秒~5秒くらいおいてSlackにコマンドが送信される。

オチ

セットアップして早速使おうと思ったらコアタイムに遅刻した。つらい。
(普通にSlackからスラッシュコマンドを手打ちして実行した)
ということでまだちゃんと使ってないけどもこんな感じです。

f:id:uskey:20181017025502j:plain:w350

社のみんなたちは僕の机で見つけても連打しないであげてください。