べにやまぶろぐ

技術寄りの話を書くつもり

DevLOVE関西 『農業の「現場」から生まれた業務改善サービス「houren.so」の話を聞いてみる』聴講メモ #DevKan

農業 IT の取り組み事例について勉強したいという事で、大阪で開催された下記イベントに参加してきました。

devlove-kansai.doorkeeper.jp

スライドも公開されています。

www.slideshare.net

農作業などの現場で、写真による 1. 簡単で、2. 十分に内容が伝わる 必要最低限の報告を可能にしたのが 現場を強くする報告連絡相談ツール「houren.so(ホウレンソウ)」 です。

農業 IT の事例という視点だけでなく、シンプルながら現場に必要なソリューションを提供するというものづくりの方法論として参考になったと思います。

スライドに書かれている事とほとんど重なりますが、以下、聴講メモです。

  • 発表者 : 株式会社日本情報化農業研究所 斎藤 毅 様
    • 細胞生物学専攻 : 遺伝子組み換えなどの研究をやっていた
  • houren.so : 2週間前に正式リリース
    • 建築・宿泊・食品・農業など「現場」に特化した、現場の問題をスムーズに解決するツール
    • IT をほとんど触れない人向けのグループウェア
  • 写真を投稿するだけでオーナーと従業員の両方の要件を満たすことができる
    • 小さい会社だと従業員がトイレを掃除する
    • 汚いと会社の好感度が下がるので上司が気になる
    • 掃除後の写真を撮影して投稿する事で (Exif から) 誰がいつどこの箇所を掃除したかを知る事ができる
    • houren.so では矢印をつけて気になる点にコメントを残す事ができる
  • 写真一枚で報告するアプリが開発された経緯
    • 農家で勉強させてもらっていた7年前はずっと畑にいて栽培と出荷をしていた
    • 日々の作業が終わった後、業務アプリに本日の作業(日報)をまとめるのがきつすぎた
    • ブログ形式で自由に記述をしていたため(思い出した)時間も適当だった
    • 一般的な業務報告アプリも負担だった
    • 誰も読まないのに出さないとサボりとみなされるので日報自体が不毛な作業になり、睡眠時間も削られていった
    • 農業は前に向かって転倒すると死ぬような機械があったりするので睡眠不足は致命傷・死亡事故につながる
    • 雨の日はメモはとれないし、寒い日は手袋を外したくない。そもそも水回りの作業が多すぎてメモは現実的ではない
    • 真夏の農薬散布は8月でも重装備が求められる(散布する人が一番危ない・年間5人は中毒事故がおきる)
    • 情報を保持しているものとしてデジカメに着目してみた
    • 農業従事者は写真を見ると大体の広さがわかる
    • 使用した機械と作業開始前後の写真を見せただけで責任者はほとんどのことがわかった
      • 大事な事は写真だけで大半が伝わるということがわかった
    • 写真を見ただけで技術を習得できた人もいた
    • 丁寧に作業日報を投稿されても真剣に読まないし、販促で使える写真が合った方が現状把握よりも遥かに有利
      • テキストではなく写真のデータの方が欲しくなった
    • どんな写真が使えるかはわからないので日報を兼ねて写真を撮ってもらった
    • 何となく撮った写真でも問い合わせが合ったりした。ちょっとした写真が使えたりした。
  • houren.so では写真を並べて日付だけ出すような形にしている
    • 同じ日に撮影した写真を並べて作成する簡易的な日報機能がある
    • 業務報告アプリは管理者の欲しい情報ではなく作業者の投稿のしやすさを優先することで真価を発揮する
    • 写真内の Exif を使っているので後日投稿しても情報は落ちない
  • 肥料を与えたのに元気の無いニラがあった
    • 写真一枚である程度わかった
    • 矢印とコメントで指示することができた
    • 熟練者は問題の早期発見ができる
      • 追加で写真をとるこてより追求する事ができる
      • 熟練者が目をつけているところがログに残る
    • 機械いじりが得意な人はメータを撮り始める
    • ノウハウが貯まり始めると強い
    • 投稿のハードルを下げた事でメンバーの特徴が見えてきて、それを共有する事で個々人が意識すると有利な視点を鍛える事ができた
    • 負の要因を一つ一つ見ていくと強いものになる
  • 農場の事務作業の低減の取り組みは SOY Shop
  • 個人に紐づく情報はほとんどない(名前とアイコンくらい)
  • 天気情報は欲しいと考えている
  • 公開前に自社で1年動かしていた、ベータ稼働していたのも半年

Nginx で http も https も IP 直打ちのアクセスを弾きたい

XXX.XXX.XXX.XXX mysite.com という A レコードを持つサイトを運用していて、http と https でのアクセスを受け付けているとします。

Nginx では下記のようなサーバブロックがあるイメージです。

server {
    listen 80;
    server_name mysite.com;
    return 301 https://$server_name$request_uri; #https にリダイレクト
}

server {
    listen 443 ssl;
    server_name mysite.com;
…
}

そして IP 直指定で飛んでくる不審なリクエストには応答したくないので Nginx 内の公式ドキュメント Server names を参考に下記のようなサーバブロックを追加してみます。

server {
    listen       80  default_server;
    server_name  _;
    return       444;
}

このとき、当然 http://XXX.XXX.XXX.XXX へのリクエストには 444 が返るのですが、https://XXX.XXX.XXX.XXX は SSL 証明書の警告が出るもののアクセスできてしまいます。

How nginx processes a request によれば

もし “Host” ヘッダがどのサーバ名ともマッチしない場合、またはリクエストにこのフィールドがまったく含まれていない場合は、nginxはこのリクエストをデフォルトサーバに振り向けます。上記の設定ではデフォルトサーバは最初のもので、これは nginx の標準的なデフォルトの挙動です。

ということで 443 に対するディレクティブが mysite.com のものしかない場合、https へのリクエストは全て mysite.com のサーバブロックで処理してしまうようです。

では、80 に加えて 443 に対する default_server も足してみると良さそうです。

server {
    listen       80  default_server;
    server_name  _;
    return       444;
}

server {
    listen       443  ssl default_server;
    server_name  _;
    ssl_certificate /path/to/mysite.crt
    ssl_certificate_key /path/to/mysite.key
    return       444;
}

最初、https://mysite.com へのリクエストまでもが 444 でドロップしてしまっていたのですが ssl_certificate と ssl_certificate_key を記載していなくて

no "ssl_certificate" is defined in server listening on SSL port while SSL handshaking, client: x.x.x.x, server: 0.0.0.0:443

とエラーになっていただけでした。このデフォルトサーバの証明書はオレオレでも構わないと思います。

あるいは

stackoverflow.com

の回答にあるような

server {
    listen 443;
    server_name mysite.com;

    if ($host != "mysite.com") {
        return 444;
    }
    ...
}

でも IP 直のアクセスを落とすことができますが、server_name を指定しているのにもう一度チェックしていて若干冗長な感じがあります。

あとこちらでは前段に HAproxy を置いてそこで落としているようです。

security.stackexchange.com

今回のサイトは IP とドメインが1対1なので SNI 云々については気にする必要がありませんでしたが、複数ドメインをホストするようなサービスだと default_server での直 IP リクエストドロップが良さそうです。

Colored Hashtag for Trello を v1.0.5 に更新しました

どうも Trello のデザインが変わったせいか動作しなくなっていたので Colored Hashtag for Trello を更新しました。

chrome.google.com

Chrome プラグインだと公開するだけで勝手にユーザの環境も更新されるから開発者的には有難いですね。気軽にバグ修正ができます。

この Colored Hashtag for Trello ですが、Plus for Trello というプラグインと一緒に使っても動作するように作っています(チームで導入しているため)。

chrome.google.com

このプラグインを使うと下図のようにハッシュタグが強調表示されるのですが、デザインが変更されるということは DOM の構成、または属性が変更されるということなのでセレクタを使う場合はそこを意識してあげる必要があります。

f:id:beniyama:20150321131156p:plain

実際、Plus for Trello 使用前後を比較してみると

<div class="list-card-details u-clearfix">
  <div class="list-card-labels u-clearfix js-card-labels"></div>
  <a class="list-card-title js-card-name" href="/c/XXXX/1-101">
    <span class="card-short-id hide">#1 </span>#101 プラグインの更新記事を書く
  </a>  
  ...
</div>

という DOM(一部抜粋)が下記のようになっていることがわかります。

<div class="list-card-details u-clearfix">
  <div class="list-card-labels u-clearfix js-card-labels"></div>
  <a class="list-card-title js-card-name agile_hidden" href="/c/XXXX/1-1-story-1">
    <span class="card-short-id hide">#1 </span>#101 プラグインの更新記事を書く
  </a>
  <a class="list-card-title js-card-name agile_clone_title" href="/c/XXXX/1-1-story-1">
    <span class="card-short-id hide">#1 </span> プラグインの更新記事を書く
  </a>
  ...
  <span class="agile_hashtags"><span class="badge agile_badge agile_badge_hashtag_primary">101</span></span>
  ...
</div>

元々一つしか無かった .list-card-title が二つになり、オリジナルは .agile_hidden クラスが付加されて不可視に、ハッシュタグ部分を別 span に分離したクローン(.agile_clone_title が付加されている)がその後ろに差し込まれています。

Colored Hashtag for Trello では(どうせ DOM 操作によるスタイル変更を行うので) Trello API を使わずにタイトル中のテキスト(上図で言うと「#101 プラグインの更新記事を書く」の部分)からハッシュタグを検出しているのですが、ここでオリジナルのものを破壊されてしまうと Plus for Trello の有無で処理を変えないといけません。しかしながら、ちゃんと元の構造のまま残してくれているのでその必要はなく、代わりに .list-card-title で引いたときに最初のもの(オリジナル)だけ取得するようにすれば良いだけです。この辺は、他のプラグインのことも考えて Plus for Trello は作られているなと関心しました。

v1.0.4 までは first-child 疑似クラスで .list-card-title 要素を指定していた(つもりだった)のですが、http://web-dd.net/?p=278 でも書かれているように .list-card-title:first-child としても「最初の .list-card-title 要素」が選択されるのではなく、「最初の要素が .list-card-title だったときのみマッチする」のでその前に他の要素が同レベルで現れるとひっかかりません。今回はおそらく .list-card-labels の div が差し込まれるようになったために first-child.list-card-title でなくなったことが原因かなと考えています。

結局、今回は代わりに first-of-type 疑似クラスを使う事で解決しました。E:first-of-type-CSS3リファレンス によれば

E:first-childの場合には、種類に関係なく要素を数えるため、 最初に来る要素がE要素であった場合にスタイル適用の対象になります。

一方、E:first-of-typeの場合には、途中で別の種類の要素が入る場合にはそれを数えずに、 指定した種類の要素のみを数えるため、最初に来るE要素がスタイル適用の対象になります。

とのことで、これでめでたく最初の .list-card-title だけ取得することができるようになりました。

デブサミ 2015 での講演の感想など #devsumi #devsumiB

先日の記事で書いた通り、去る 2/20(金)に Developers Summit 2015 の公募セッション枠で講演をさせていただきました。

個人的には非常に貴重な体験をさせていただいたと思う一方、もう少し来場された方の関心を引けなかったか?明日の業務に持ち帰れるような情報を提供できなかったか?と我が身の至らなさも身に染みました。例えそれが二日目の朝一でも来たいと思えるようなコンテンツを提供できるよう精進していきたいと思います。

そして下は ぼっち The Speaker の様子です。同じ枠の他の登壇者の方に行列できてると一段と寂しい…

f:id:beniyama:20150220111319j:plain:w250

さて、忘れないうちに Speaker として参加した所感を徒然と書いておきたいと思います。

スタッフの方達が素敵

当日朝一のセッションで直前だと心許なかったので水曜日の夜に一回リハさせていただいたのですが、会場スタッフの方達の対応や気遣いがとても丁重で驚きました。もちろんリハーサルだけでなく会期を通して懇切丁寧に対応していただき、余計なストレスなどなく万全の状態で講演に臨むことができました。

f:id:beniyama:20150218184521j:plain:w400

ちなみに事前案内では Mac の VGA ケーブルアダプタなどは持参とあったのですが、会場には VGA アダプタは元より有線 LAN とケーブル用アダプタ、ピンマイク、レーザーポインタ付きプレゼン用リモコンもあってマシン(資料)だけあれば後は OK な感じでした。ドングルなど指しましたが接続設定・問題共に全くなし。

講演中の写真撮影

こちらはイベント中も注意などあったようですが、自戒も込めて確かに無音カメラで撮るような配慮は必要かもしれません。登壇している側からすると音は余り気にならなかったのですが、撮る仕草はよく見えるので聴講されている方がカメラ構えた瞬間・またはまだ撮影してないのにスライド変えちゃって良いものかと変な心配をしていました。この辺、講演慣れされている方はスルーできるんでしょうか。

自分も冒頭で資料は後日公開する旨伝えてはいましたが、それでも撮影される方は多かったように思います(ちなみにその資料)。関心を持っていただけているというのは素直に嬉しいのですが。

広い会場での講演

f:id:beniyama:20150220101444j:plain:w400

先述の通り2ブロック目くらいまでは聴講している方の顔や仕草が見え、目線を意識しながら喋れたのは良かったかなと思います。ただ慣れないリモコンを使ったために何回かスライドの移動が前後してしまったり、反応しなかったり(リモコンとドングルの間に体が入る位置になるとダメだった)して見苦しかったのは反省点です。これは慣れたのを持ち込んだ方が良さそうです。

あとせっかくピンマイクがあったのでできる限り前に出て話したかったのですが、PC が演台の上にあるので今何がスクリーンに出ているか振り返らないとわからず、位置取りの難しさを感じました。ただ、その後のセッションで舞台中央に小さな台を置いてそこに PC を置かれている方もいらっしゃったので、それであれば一々振り向いたり演台に戻る必要もなさそうで良いなと思いました。

あとは、リモコンが届く限り舞台を降りて歩き回るというのも、いつか機会があれば試してみたいです。

Developers Night

運良く参加させていただいた 2月19日 Developers Night powered by AWS(東京都) では知り合い0のぼっち状態で飛び込みましたが色々な方とお話させていただいたり、あとは LT、特に竹迫さんの『ドットコムバブルの再来~アセンブラ短歌を一句~』は素晴らしいの一言でした(デモ動画有り )。

あと珍しくじゃんけん大会で2位になり、システムテスト自動化 標準ガイド (CodeZine BOOKS) を 有難く頂戴しました。

f:id:beniyama:20150219205344j:plain:w250

デブサミと自分

デブサミという言葉を知ったのはそもそもこの業界に転職しようと活動していたとき、とある企業様の合同説明会のときで、

担『弊社も明日からのデブサミに出展しますので、いつでもお声がけください〜』

担『ちなみにデブサミ参加される方いらっしゃいますか?』

(会場ちらほら手を挙げる)

自分(デブサミって何…)

他の志望者『はい、10年後も通用するエンジニアでいたいですから!』

自分(なにそれ意識高い…)

という感じで、この業界では常識なイベントなんだなと劣等感と一緒に刻まれたのがきっかけでしたがそれから デブサミ2014 、夏サミと参加してしこしこ講演メモを書き、そうこうしているうちに今年演者として参加できたのは不思議な感じがしています。

また機会があれば何か発表したいのはもちろんですが、それでなくても聴講者として次回以降も参加していこうと思います。

まずは、今年の聴講メモも早いうちに書きます。

f:id:beniyama:20150219094928j:plain:w250

システムテスト自動化 標準ガイド (CodeZine BOOKS)
Mark Fewster Dorothy Graham テスト自動化研究会 伊藤 望 玉川 紘子 長谷川 孝二 きょん
翔泳社
売り上げランキング: 31,243

Keynote で作ったスライドを slideshare に上げる時に表紙を画像にするようになった話

以前、

で書いたように日本語フォントを含むスライドを slideshare に上げるとサムネが真っ白になってしまうことがあります。上記エントリー中では "Save as Adobe PDF" で回避する策について書いたのですが、これだと

f:id:beniyama:20150223011337p:plain

のようにプリントの用紙サイズとスライドのサイズが合わずに余計な余白・線が入ってしまいます(あと気のせいでなければそもそも Acrobat Pro が必要な気がする)。

そこで最近はもう潔く一枚目だけ画像にして PDF 化しています。

ただしポイントが2点あり、

  1. Keynote の「(画像)書き出し」を使わないで スライドショーで画面最大化したものをMac のスクリーンキャプチャで画像化する。

  2. 元のスライドを差し替えるのではなく、元のテキストを残して上から画像を被せる(↓こんな感じ)

f:id:beniyama:20150223011349p:plain

ということをしています。

1は Keynote の画像書き出しよりスクリーンキャプチャの方が画質が良い(気がする)ためで、2は下図のように slideshare の Transcript の方に文字が残るから、という理由です(未検証だけど画像だけだと文字は表示されないはず)。

f:id:beniyama:20150223011400p:plain

こんなことしなくても問題ないのが一番良いんですけどね…

デブサミ 2015 【20-B-1】「『GMOプライベートDMP』の開発にあたって取り組んできた DevOps、更にその反省点と現在進行中のカイゼン事例の紹介」 の講演資料を公開しました #devsumi #devsumiB

今回のデブサミでは有難くも公募セッションにて採択していただき、業務開発の中で行っている DevOps の取り組み事例についてお話しすることができました。

『GMOプライベートDMP』の開発にあたって取り組んできた DevOps、更にその反省点と現在進行中のカイゼン事例の紹介

会期中の様子や講演メモなどは別のエントリーで書こうと思いますが、取り急ぎ講演資料をアップしたのでそのお知らせです。

今回は生まれて初めてプレゼン資料に萌えキャラ?を入れるという試みをしましたが、詳しくは下記のサイトをご覧いただければと思います。

あと、「機能横断」と言おうとして「職務横断」と書いてしまっていた事に今頃気づきましたが、もう終わったことなのでそのままにしておきます orz

Firefox で mousemove イベントが発火しなくなったときは preventDefault を確認しよう

自前のドラッグアンドドロップを実装していて、Chrome や Safari では発火している mousemove イベントが Firefox では定常的に上がってこないという事象に悩まされました。

色々調べてみたところ下記の stackoverflow で同じような質問をしている人が。

You should call evt.preventDefault(); in all the mouseXXX handlers. Firefox has default drag/drop handling and you don't want that. It's not a bug in Firefox that it does that.

イベント処理はブラウザによって独自の処理に入ってしまうため、互換性も考えた上でpreventDefault()stopPropagation() をきちんと意識して書かないといけないということを学びました。

ちなみに d3.js の場合は d3.event.sourceEvent.preventDefault() を呼ぶことになります。