Vue.jsで体感余命みえる君を作った

f:id:hogesuke_1:20160509041023p:plain

体感余命みえる君
http://life.hogesuke.net

体感余命みえる君 とは

体感余命がみえるWebアプリケーションです。

ジャネーの法則

歳をとるにともなって、1年の経過がどんどんはやく感じるようになっていませんか?
この現象をポール・ジャネーという人が心理学的に説明していて、ジャネーの法則って呼ばれているようです。

すでに人生はどれくらい終わっているか

歳をとるごとに1年の体感はどんどん短くなっていくので「寿命までの残り年数=体感の残り人生」とはなりません。体感余命みえる君では、ジャネーの法則に則って、すでに人生のナンパーセントが終了しているかを計算します。

例として25歳の若者の場合、現在何パーセントの人生が終わっているかを見てみます。

f:id:hogesuke_1:20160509040911p:plain

なんと、63%もすでに終了しているようです。おそろしい。
※ 真偽の程は定かじゃないのでジョークとして捉えてください

Vue.js

このWebアプリケーションにはVue.jsを使用しています。GWの課題として今回はじめて取り組みました。
触って感じたことを箇条書きにしてみます。

  • 学習コストが低いという評判を良く目にしたけど、そうでもないように感じた。
    学習コストの面ではReactが圧倒的に優位な気がする。
  • ただ、Angular1系ほど覚えるのが大変という感じはなかった。
  • Reactに比べ、バインディグやレンダリングに関する補助機能は充実しているのでラクできる部分は多そう。
  • Reactと同じで、中・大規模なアプリケーションを構築する場合は別のライブラリ(Reduxとか)と組み合わせないと崩壊しそう。
  • 簡素なSPAで、細かい制御を必要としない場合には、ラクにシンプルに実装できて良さそう。

終わりに

GW終わるのつらい…

体感余命みえる君 github.com

Slackに気を取られすぎる問題とその解決

この記事は「さくらインターネット Advent Calendar 2015」の20日目の記事です。

Slackは非常に気の利いたチャットツールで、とても便利に使っています。

問題

しかし、このツールにも問題があります。
ジョインしているチャンネルが多くなると未読のメッセージがつぎつぎに溜まり、未読を消化したい欲と仕事に集中したい欲を常に戦わせる状態となります。
(そして、だいたい未読を消化したい欲が勝ちます)

解決

仕事の効率を高めるはずのツールで仕事の集中力を欠いてしまっては仕方がないので、この問題を2つのツールを使って解消します。

Slack Silencer

github.com

まず、Slack Silencerというツールを使います。
このツールは指定したチャンネルをミュートにしてくれます。ミュート状態のチャンネルはリスト上に薄く表示され、メッセージの未読を伝える白文字の表示になりません。また、メンションされた場合にはバッジが付きますが、通知は飛ばなくなります。

f:id:hogesuke_1:20151219213501p:plain

ジョインしておきたいけどリアルタイムでウォッチする必要がないチャンネルをミュートすることで、未読を消化したい欲に振り回されることがぐっと少なくなります。

使い方

1. SlackのAPI tokenを作成
Slack Web API | Slackより作成可能です。

2. tokenを環境変数に設定

export SLACK_API_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

3. Slack Silencerをgit clone

git clone git@github.com:dopin/slack-silencer.git

4. コマンドラインよりプログラムを実行

# foo, barのチャンネルがミュートされる
/path/to/slack-silencer/mute.rb foo bar

ちなみに自分は、就業時間の09:30-18:30の間だけミュートするため、以下のようにcrontabに設定しています。

# 9:30からミュート
30 9 * * * /path/to/slack-silencer/mute.rb foo bar
# 18:30にミュート解除
30 18 * * * /path/to/slack-silencer/mute.rb

Slack Reporter

github.com

Slack Silencerを使うことで未読により集中力を削がれることはなくなりました。
しかし、ミュートにしている間に投稿されたメッセージは既読扱いにされてしまうため、就業後にゆっくりメッセージを読もうとすると探しだすのが大変という新たな問題が発生します。

そこで、この問題を解決するため、Slack Reporterというツールを作成しました。 このツールは指定の期間に投稿されたメッセージをレポートにまとめてくれるツールです。

f:id:hogesuke_1:20151219221858p:plain レポートのサンプル

使い方

1. SlackのAPI tokenを作成 (※ Slack Silencerで実施済みの場合スキップ)
Slack Web API | Slackより作成可能です。

2. tokenを環境変数に設定 (※ Slack Silencerで実施済みの場合スキップ)

export SLACK_API_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

3. Slackのユーザ名を環境変数に設定(オプション)
設定するとSlackのダイレクトメッセージでレポートのパスをお知らせします。

export SLACK_USER=xxxxxxxxxx

4. Slack Reporterをgit clone

git clone git@github.com:hogesuke/slack-reporter.git

5. コマンドラインよりプログラムを実行

# 9:30から18:30のメッセージを対象にする場合
/path/to/slack-reporter/reporter.rb 0930 1830
# 現時刻から1時間前までのメッセージを対象にする場合
/path/to/slack-reporter/reporter.rb 60

これもcrontabに設定し、自動実行させると便利でしょう。

# 18:30にレポート作成
30 18 * * * /path/to/slack-reporter/reporter.rb 0930 1830

レポートファイルは/path/to/slack-reporter/contents/ディレクトリにhtmlファイルとして生成されます。

一件落着(?)

Slack Reporterについては、このAdventCalendarを書いている直前までコーディングしていたため、まだ運用できていません…

追記

ブクマコメントにて、最近Slackに実装されたdo not disturbで良いのでは?というご意見を複数いただいたので、ちょっと追記します。

do not disturbを設定すると、メンションされた際の通知は飛ばなくなりますが、未読の状態は分かってしまいます。具体的には、チャンネルリストに白太文字で表示され、Slackアプリのアイコンに赤丸で未読が存在することが分かる表示になります。

インボックスゼロ派の自分としては、この状態が目に入ると未読を消化せずにはいられないので、上で紹介しているツールでサイレントな環境を作っています。

追記2

ブコメで使ってみるって書いてくださってる方、ありがとうございます!
ただ、実のところSlack Reporterに関しては、メンションやリンク、Botによる投稿などの表示が不完全で一部見づらいものになっています。これについては、使いながら徐々に改善していく予定です。

また、PullRequestも歓迎してます。よかったらPR送ってください。

Slack入門 [ChatOpsによるチーム開発の効率化]

Slack入門 [ChatOpsによるチーム開発の効率化]

YAPC::Asia 2015 は最高のフェスだった

yapcasia.org

こんな面白いカンファレンスは初めてで、めっちゃ楽しかった。 今回が初めての参加で、もっと早くからYAPCを知っていればと思ってしまいます。

会場ではTwitterで絡んでる人とオフで話せたし、こういう大規模なカンファレンスによっていつもとは違った体験できるのも魅力だよなと感じました。

これが最後のYAPCになってしまうのは本当に残念。
もし、次があるなら僅かながらにも力になれることがあればいいな、と思います。

今回のYAPCスタッフと過去代々のスタッフの皆様、本当にありがとうございました。

Raspberry PiとOpenCVでスプラトゥーンの勝敗を自動記録する仕組みを作ってみた

f:id:hogesuke_1:20150802040434p:plain ikashot.net
※ 現在、IEで画像が表示できない不具合があります。お手数ですがIE以外でのアクセスをお願い致します…すみません。

何を作ったか

スプラトゥーンではバトルの履歴を見れないようになっているので、勝率がわかりません。自分の勝率がどの程度なのか知りたいなーと思ったので、勝敗を自動記録する仕組みを作ってみました。

仕組み

以下のような流れで処理しています。

  • Raspberry Piのpicameraで、TV画面をキャプチャする
  • キャプチャ画像のなかにWIN or LOSEの結果が表示されているかOpenCVを使って判定する
  • WIN or LOSEが検出されたら、WebAPIを通して結果画面のイメージと勝敗をアップロードする

f:id:hogesuke_1:20150802131319j:plain:w400
不格好ですが、こんな具合にラズパイをセットしてTV画面をキャプチャしてます。

OpenCVの画像認識について

WIN or LOSEの判定はOpenCVを使用して行っています。
画像認識できるようにするまでの手順はだいたい以下のような感じです。

  • サンプル画像の取得
  • 特徴の抽出
  • 検出器の生成
  • OpenCVの画像認識コードの実装

サンプル画像の取得

まず、検出対象の「WIN」と「LOSE」のポジティブサンプルと、どちらでもないネガティブサンプルを用意する必要があります。
今回はWINサンプルを400、LOSEサンプルを300、またどちらでもないネガティブサンプルを3万用意しました。精度の高い検出をするには、数千単位でサンプルを用意する必要があるみたいですが、そこまでやるのは辛いので妥協しています。
f:id:hogesuke_1:20150715212348j:plain:w180 f:id:hogesuke_1:20150715213014j:plain:w180 f:id:hogesuke_1:20150710195159j:plain:w180
左: WINサンプル 中央: LOSEサンプル 右: ネガティブサンプル

特徴の抽出

特徴抽出っていうのは、ここが目でここが鼻でここが口みたいなのを示してあげることです(たぶん)。

難しいことはよく分からなかったので、今回は結果画面の「WIN」「LOSE」っていうのはここのことだよっていう座標を示しています。
これにはTrainingAssistantというツールを使用しました。 github.com

このツールを使うとブラウザで簡単にポジティブサンプルとネガティブサンプルの分類と、特徴の抽出(検出対象座標の記録)ができます。
f:id:hogesuke_1:20150802143253p:plain:w400
こんな具合です。詳しくは作者さんのブログ記事に記載されています。
OpenCV 2.4.2で分類器を作る - shkh's blog

検出器の生成

ツールを使って生成されたポジティブ、ネガティブの分類と特徴点が示されたテキストファイルをもとに検出器を生成します。 これにはOpenCVのコマンドを使用します。

これもTrainingAssistantの作者さんのブログ記事を参考に実行しました。
OpenCV 2.4.2で分類器を作る - shkh's blog

この工程が一番時間がかかります。Core i5、メモリ16GBのMacBookProで完了まで丸2日かかりました。
ただ今回はネガティブサンプルが3万とポジティブサンプルに比べて多すぎたことが原因かもしれません。減らせばもうちょい速くなりそう。

OpenCVの画像認識コードの実装

生成された検出器を使って実際に画像認識するコードを実装します。 これは検索するとたくさんサンプルコードが出てくるので、それを参考にすると簡単に実装可能です。

自分はこのQiitaの記事を参考に実装しました。
python+OpenCVで顔認識をやってみる - Qiita

f:id:hogesuke_1:20150802145617j:plain f:id:hogesuke_1:20150802145621j:plain f:id:hogesuke_1:20150802174714g:plain
こんな具合に検出してくれます。

一応、検出してくれますが精度は悪いです。部屋が暗いと認識されずらかったり、WINをLOSEと間違えたりします。
この精度の悪さを補うため実際のコードでは、20フレーム中に3フレーム以上認識したら正しい検出として画像をアップロードする、といったようなワークアラウンドを埋め込まんでます。
精度が悪い原因はポジティブサンプル数が少ないことだと思うので、しばらくしてサンプルが集まったら検出器を作りなおそうかと思います。

以上!

以上で、簡単な画像認識を実現できました。ツールやサンプルコードを上げてくれている方がけっこういるので、その恩恵にあずかると割と簡単に実現できますね。ほんとう、みなさんには圧倒的感謝です。

Raspberry Piについて

最近、ラズパイ2がでて性能が飛躍的に上がりましたが、自分は間違って古いモデルを買ってしまいました。

この古いモデルは、CPU1コア、メモリ512MBというスペックで、OpenCVのビルドに6時間、Pythonのビルドに2時間かかります。けっこう厳しいです。picameraでのキャプチャについても5fpsぐらいしか出ていなくて、だいぶカクカクです。
ラズパイを購入する際は、まちがって古いモデルを買わないようにご注意ください…

ラズパイのセットアップについても情報はネットにたくさんあるので、困ることはありませんでした。OSもRaspbianというDebian系のLinuxなのでDebianUbuntuの情報を転用でき、情報がなくて困るということはまずないかなぁという気がしています。

もし使ってみたい方がいたら…

GitHubで検出器を含めてソースコードを公開していますので、自由に使っていただくことが可能です。
github.com github.com

しかながら、インストール手順をまったく書けていません…
もし、使ってみたいという方がいましたら@hogesuke_1までメンションください。まじめにインストール手順を書こうと思います。

ところで

いま、さくらインターネットRapidSSLを1年無料で使えるキャンペーンをやっています。イカショットもこのキャンペーンを利用してhttps化してみました。
さくらのサービスを使っている方は利用されてみてはいかがでしょうか(イカだけに)。 ラピッドSSL提供開始記念キャンペーン! | さくらインターネット

【さくらのクラウド】Minecraftサーバをコマンド操作なしで簡単構築

さくらのクラウドには、スタートアップスクリプトという機能があり、サーバ作成時に任意のスクリプトを実行することができます。Minecraftサーバを構築するスクリプトを指定すれば、簡単にコマンド操作なしでマルチユーザで遊べる環境を構築できます。

とはいうものの、さくらのクラウド公式ではMinecraftサーバ構築のスクリプトは提供されていません。今回、自分のメモを兼ねて、構築に必要な手順をスクリプトにまとめたのでそれを公開します。

これをコピペすれば、すぐに遊べる環境が構築できるはずです。

Minecraftサーバ構築スクリプト

#!/bin/bash
# @sacloud-once
# @sacloud-desc Minecraft Serverをセットアップします。
# @sacloud-desc (このスクリプトは、CentOS6.XもしくはScientific Linux6.Xでのみ動作します)
# @sacloud-require-archive distro-centos distro-ver-6.*
# @sacloud-require-archive distro-sl distro-ver-6.*

#---------iptablesの設定---------#
cat <<'EOT' > /etc/sysconfig/iptables
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:fail2ban-SSH - [0:0]
-A INPUT -p tcp -m multiport --dports 22 -j fail2ban-SSH 
-A INPUT -p TCP -m state --state NEW ! --syn -j DROP
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A INPUT -p icmp -j ACCEPT 
-A INPUT -i lo -j ACCEPT 
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p udp --sport 123 --dport 123 -j ACCEPT
-A INPUT -p udp --sport 53 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT 
-A INPUT -p tcp -m tcp --dport 25565 -j ACCEPT 
-A fail2ban-SSH -j RETURN
COMMIT
EOT
service iptables restart
#---------iptablesの設定終わり---------#
#---------Javaのインストール---------#
yum install -y java-1.8.0-openjdk
#---------Javaのインストール終わり---------#
#---------Minecraft Serverのインストール---------#
wget -P ~/minecraft https://s3.amazonaws.com/Minecraft.Download/versions/1.8.7/minecraft_server.1.8.7.jar

# 一度起動し、eula.txtファイルを生成させる
java -Xms1024M -Xmx1024M -jar minecraft_server.1.8.7.jar nogui
echo eula=true > ~/minecraft/eula.txt

# upstartの設定ファイルを作成
cat <<'EOT' > /etc/init/minecraft.conf
description "Minecraft server"
chdir /root/minecraft
exec java -Xms1024M -Xmx1024M -jar minecraft_server.1.8.7.jar nogui
start on startup
EOT

# 起動
start minecraft
#---------Minecraft Serverのインストール終わり---------#

注意点

Minecraftサーバを利用するにあたって、ライセンス利用規約に同意する必要があります。
スクリプト上ではこの利用規約に承認する処理が組み込まれているため、利用規約を確認し承認したうえで上記のスクリプトを使用するようにしてください。
https://account.mojang.com/documents/minecraft_eula

スタートアップスクリプトの登録方法

  1. コンパネ右上のユーザ名表示部のプルダウンをクリック
  2. プルダウンメニューの「設定」をクリック
  3. 左サイドのメニューからスクリプトを選択
  4. 画面上部の「+追加」ボタンをクリック
  5. 上記のスクリプトをすべてコピー&ペーストし作成

以上の操作によりスクリプトが追加可能です。
追加したスクリプトサーバ作成画面->ディスク修正->配置するスタートアップスクリプトで選択してください。

最小サーバスペック

CPU: 1コア
メモリ: 2GB
OS: CentOS 6.X, Scientific Linux6.X

Minecraftサーバの起動には最低1GBのメモリが必要となるため、1GBより大きいサイズのメモリが必要となります。

2万円クーポン

キャンペーンをやっているようなので、今なら無料で試せますよ。

ニコニコ動画の再生画面を少しだけシンプルにするChrome拡張を作ってみた

ニコニコ動画の再生画面、いろんな情報がひっきりなしに目に飛び込んできて動画に集中できない。 なので、これを少しシンプルにして集中できるようにしてみました。

ニコニコ動画 Light - Chrome ウェブストア

before

f:id:hogesuke_1:20150508125445p:plain

after

f:id:hogesuke_1:20150508125448p:plain

なにが違うの?

  • 動画上部のニュース表示部を削除
  • 動画下部のオススメ動画一覧を削除

リンク

chrome.google.com

AngularJSを使ってタグベースのはてブビューアを作ってみた

f:id:hogesuke_1:20150330180058p:plain

はてブビューア Skimii
http://skimii.net

作ったもの

タグベースのはてブビューアを作りました。
ウォッチしたいキーワードをタグとして登録すると、ブックマークされたエントリをタグごとに一覧表示します。

Skimii

作った理由

自分の興味対象にピンポイントでアクセスしたいという理由です。 はてなブックマーク公式では、かなり大きなくくりでのカテゴリ分けなので、ウォッチしたい対象にピンポイントでアクセスしにくいなぁと感じていました。

タグごとにエントリを表示できるので、対象を絞ることができノイズの少ない情報を得られるかと思います。

しかしながら…

インタレスト機能 - はてなブックマークヘルプ
すでに公式で同じものが提供されています。作成途中で気づいた…

ただ、公式には無い機能もあります。

  • ブックマーク数の閾値設定
  • すでに読んだエントリを表示しない設定

構成

  • フロントエンド:AngularJS1.3、Bootstrap3
  • バックエンド:Ruby + Sinatra
  • サーバ:さくらVPS 1G
  • DB:MySQL
  • HTTPサーバ:Nginx
  • APサーバ:Unicorn

AngularJSの感想

Angularの最初の印象は、便利すごい最高って感じで完全に浮かれてた。これがあれば何でも簡単に作れると感じた。ただ、どんなものでもそうだけど正しい使い方をしなければだんだんと辛みが積もってくる。

自分の場合、Angularの正しい使い方がよく分からなくて、だいぶ右往左往した。そして、少し前の反Angular的なノリに便乗して、自分ワルクナイ、Angularワルイみたいな言い訳をしていた。

ただ、辛みが頂点に達して、どうにか改善しようと調べ始めるとだいたい解決策が存在して、それを適用するとかなり改善されるというブレイクスルーを何度か経験した。やっぱり自分が悪かったんや…。
しかし、これはかなり初心者的な話しなので、Angularはやっぱり最強だってことじゃなくて、最初の取っ付きやすさに反してAngularもそれなりに習得大変だなという感想。

ただ、ほんとにミニマムなツールであれば、辛みに気づく前に完成するので、そういうところで使うと最強であるかもしれない。

Angularで2つ作ったので、次はAngular2の正式リリースまで冬眠しようと思う。

Sinatraの感想

シンプルでいい。前にRailsに取り組んだときは覚えること多くてかなり辛かった思い出があるので、このシンプルさは本当にうれしい。

ただ、規模が大きくなったり複数人で開発するとなった場合は、Railsのレールが大いに機能するのだろうと思う。その点、sinatraは大規模な開発は弱いかもしれない。 だけど、自分が趣味で作る規模であればSinatraで十分だし、情報も多く転がってるのでこれからもお世話になりそう。

次に向けて

このWebアプリ作るのに4ヶ月かかっていて、ちょっと時間かかりすぎだなぁって思ってる。2ヶ月目ぐらいで雑に動くものはできてるんだけど、そこから詰めるのにさらに2ヶ月かかっている。
次は、ミニマムで雑だけど使えるものを目指して短時間での開発を意識したい。Reactで何か作る。1ヶ月でリリースしたいなぁ。

参考

はてブAPIでwebサービスを作りたい全ての人に向けて書きました
作成にあたり参考にしました。ありがとうございます。