Webエンジニアとして最低限の体裁を保つための結婚式入門
Wedding Hack
今年の9月に結婚式を上げました。
Webエンジニアとして長年生きてきた自分は、結婚式でも絶対面白いことをやろう!と思って、 人生で2, 3番目くらいには重要なイベントである結婚式にすらエンジニアとしての最低限のHackをやって来ました。
もし一生をものづくりをする人間として過ごすのなら、人生を振り返ったときに立ち戻る重要な瞬間が必要です。
僕に取ってはそれが「結婚式でWebエンジニアリングをする」でした。
新婚旅行よりもbuildersconを優先したことで一部で有名な僕ですが、 今回は結婚式でのHackを紹介します。
それではいきましょう!
ウェルカムボードでWebエンジニアリングする
最初は、結婚式中のコンテンツとして何かWebやハードウェアと連携するものをと思ったのですが、 流石に結婚式の本番中に失敗してしまっては、親族などに顔向けできません。
やるなら、そもそも失敗ないような設計をするべきです。
ということで僕はウェルカムボードをHackすることにしました。
ウェルカムボードとは、式場の入り口に置く招待者を最初に迎え入れるボードのことです。
人によってはものすごく簡素なものを用意していることもありますが、 新郎新婦の似顔絵だったり、友人につくってもらったり、二人の趣味のものを飾ったりと人それぞれです。
基本的には素通りされるものなので、そもそも失敗自体しづらいです。 弊社の回路エンジニアもウェルカムボードを回路基板で作成してLEDを点灯させたりしていました。
完成品
みんなでつくるWelcome Board
これだけだとよくわからないので、解説。
ディスプレイには予め「Welcome to our wedding reception!」と表示させておき、 基本的には新郎新婦の思い出社員をスライドショーさせておきます。
それだけだとつまらないので、横に置いてあるMacのカメラで写真が取れるようにしておきます。
そこで写真を撮影すると、メインのディスプレイに撮影した人たちが投影される仕組みです。
数秒後には元にスライドショーに戻りますが、このときの写真がどんどん追加されていくイメージです。
必要なのはディスプレイとMac一台と結婚式っぽく見せるための造花。
写真共有サイト
こちらは単純にスマホブラウザから写真のアップロードができるサイトです。他の人がアップロードしたものも見れて、「1分前」 「10分前」など時系列で閲覧できます。
一応複数枚同時アップロードにも対応。
実際どうだった?
待合室にこんな感じで置かれており、うちの共同創業メンバーや同僚が周りの人に紹介してくれたので、結構使ってもらえたみたいです。
※モザイク掛かってない二人はうちの会社の創業メンバー
なんだなんだと眺めていると他の人が撮影した写真が映るので、じゃあ自分もやってみようかという感じで 沢山の人が撮影してくれればいいなと思ってつくりましたが、その結果がこちら。
※人物が特定できないようにかなり解像度を下げてます。
全部で50枚くらい撮影してくれました!会場のスタッフの方が、待合室からさらに披露宴会場の入り口にも移動してくれたので、入退場含めさらに多くの人に使ってもらえました。
またこの時撮影した写真は、これまた結婚式のためのつくったお手製の写真共有サイトに リアルタイムに表示されるようになっていたので、花嫁の準備中に1人で見て(・∀・)ニヤニヤしてました。
やはり自分がつくったサービスが人に使われるのを見るのはうれしいことですね。
そして個人的に嬉しかったのが、嫁の両親が使ってくれていたこと。
しかも笑顔で。これを見た時にはなんというか「一つ認めてもらえたかな」と思えるような、そんな大事な瞬間でした。
どうやってつくったの?
ということで、どうやってつくったか見ていきます。
SAKURAのVPSを準備
元々持っていたのでそれをそのまま使いました。
CentOS 6.5でした。
MySQLじゃなくて、SQLiteでサクッと作るつもりだったので、そうします。
$ yum update -y$ yum install -y git vim make glibc-devel gcc gcc-c++ openssl-devel$ yum install -y sqlite-devel$ yum install -y ImageMagick$ useradd app
Install ruby
[root]$ yum install -y readline-devel [app]$ git clone git@github.com:tagomoris/xbuild.git$ xbuild/ruby-install 2.3.1 ~/local/ruby-2.3.1$ export PATH=$HOME/local/ruby-2.3.1/bin:$PATH※↑は.bashrcにも追記
Setup application
$ cd$ git clone git@bitbucket.org:kazuph/wedding-photo.git$ cd wedding-photo$ bundle install --without development test --path vendor/bundle
Nginx
$ yum install -y nginx
設置
server { listen 80; server_name ore-wedding.com location / { proxy_pass http://localhost:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Client-Verify SUCCESS; proxy_set_header X-Client-DN $ssl_client_s_dn; proxy_set_header X-SSL-Subject $ssl_client_s_dn; proxy_set_header X-SSL-Issuer $ssl_client_i_dn; proxy_read_timeout 1800; proxy_connect_timeout 1800; }}
$ service nginx start$ chkconfig nginx on
起動
productionで起動するための設定
$ echo SECRET_KEY_BASE=`bundle exec rake secret` > .env$ bin/rails db:migrate RAILS_ENV=production$ bin/rails assets:precompile RAILS_ENV=production$ export $(cat .env | xargs) && bundle exec puma -C config/puma.rb -eproduction
exportなんとか〜&&ってやると
.envにある値を全部展開してくれて、プログラム中に使えるようになります。 doenvに頼る必要がないので便利です。
pumaをinitで使う
このままだと、pumaが死んだらそのまま死んだままなので、その辺はinitさんにお願いします。
https://gist.github.com/niwo/4526179
自分はこれを使いました。以下のinstallが必要でした。
$ yum provides /lib/lsb/init-functions$ yum install redhat-lsb-core
設定ファイルはgistにあげてます。
https://gist.github.com/kazuph/b0d84d078cc23b8a6eb605bb15e08b2a
nginx basic auth
開発中はBasic認証で見えないようにしてました。
$ yum install -y httpd-tools$ cd /etc/nginx$ htpasswd -c .htpasswd wedding
/etc/nginx/conf.d/virtual.conf
server { auth_basic "Restricted"; auth_basic_user_file /etc/nginx/.htpasswd;}
wedding photoアプリ
Rails5でつくりました。Versionは5.0.0。
Gemfileにはこれを追加しました。
gem 'carrierwave', '>= 1.0.0.beta', '< 2.0'gem 'mini_magick'gem 'exifr'gem 'materialize-sass'gem 'kaminari'
使ったJSファイルは、
- webcam.js
- material-photo-gallery.js
- lodash.js
だけです。
残念ながらこの時点では僕がReact触ってなかったので、古き良きRailsアプリケーションという形で作成されてます。
ちなみにTurbolinksはONのままやりきりました。やはり画面の遷移がスムーズになるのは気持ちいいですね。
carrierwaveのuploaderは以下のような感じにしました。
app/uploaders/photo_uploader.rb
class PhotoUploader < CarrierWave::Uploader::Base include CarrierWave::MiniMagick storage :file def store_dir "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end # 回転対応 def fix_exif_rotation manipulate! do |img| img.tap(&:auto_orient) end end process :fix_exif_rotation process :resize_to_limit => [2048, 2048] version :normal do process resize_to_fit: [1024, 1024] end version :thumb, from_version: :normal do process resize_to_fit: [200, 200] end def extension_whitelist %w(jpg jpeg gif png) end end
Welcome boardのjsはこんな感じでした。
app/assets/javascripts/welcome.js
$(document).on('turbolinks:load', function(event) { if (controller !== "welcome") { return; } // 画像のローテーション $('#fullscreen').find('img:gt(0)').hide(); var imgAnimation = function() { $('#fullscreen :first-child') .fadeOut(1000) .next('img') .fadeIn(2000) .end() .appendTo('#fullscreen'); } var imgInterval = setInterval(imgAnimation ,3000); Webcam.set({ width: 320, height: 240, dest_width: 640, dest_height: 480, image_format: 'jpeg', jpeg_quality: 90 }); Webcam.attach('#my-camera'); document.addEventListener("keydown" , function(e) { var keyCode = e.keyCode; if ( keyCode === 13 ) { Webcam.snap(function(dataUri) { console.log("Data URL: " + dataUri) // 表示されるようにする $('#fullscreen :first-child').fadeOut(100); $('#fullscreen').prepend(''+dataUri+'" />'); clearInterval(imgInterval); setTimeout(function() { imgInterval = setInterval(imgAnimation ,3000); }, 5000); // Ajaxでサーバーに画像の送信 Webcam.upload( dataUri, '/welcome/create', function(code, text) { }); }); } });});
Webcam.jsに予め撮影画像のuploadメソッドが生えているのが便利でした。
webcamのuploadをrailsで使えるようにする
ただしそのままでは、WebCamで撮影した写真をアップロードできなかったので、Railsが発行しているcsrf-tokenを、 アップロード時のパラメーターに含めるようにだけ修正しました。
vendor/assets/javascripts/webcam.js
var l = new FormData; l.append(s, h, s + "." + i.replace(/e/, "")); // 以下を追加 l.append('authenticity_token', $('meta[name="csrf-token"]').attr('content')); o.send(l)
まとめ
ということで、結婚式にどんなハックをしたのか紹介してみました。
全部で3人日ちょいくらいでしたが、デザインにこだわっていたらもっとかかっていたかもしれません。
マテリアルデザイン便利だなーって思いつつ、当時でいうと久々Rails書けて楽しかったです。
あとpumaも始めてでしたが先人がいいものをたくさん用意してくれていたので、 ほぼ詰まらずにinit化くらいまではいけたかなと思います。あとhot deployも意識せずにできたりと、良いことが色々ありました。
嫁側の両親や親戚や招待した方々に、自分のことを知ってもらうのが目的でつくったので、それは達成できたかなと思います。
あと、自分側については一応僕は大学時代からこんなことをやっていたので「相変わらずだな」って思ってもらえてればいいなぁと。
ということで、当日までは結構ドキドキでしたがうまくいって良かったです。
結婚式がまだな方は是非参考にしてみてください!
Enjoy Wedding Hack!
---
ちなみにトップ画の一升瓶は、地元の酒造が出しているもので、通常の一升瓶が1.8Lに対して、2.5倍の4.5Lの大型サイズのものです。当日は二人の画像を貼るとともに、新郎新婦の場所に来てもらった人達に注ぎまくるという演出をやってました。
大変縁起がいいので、もし良ければこちらもどうぞ。