メモ置き場

いろんなメモを置いておく場所。自分用ですが、誰かの助けにもなるかも。

Raspberry Pi 再セットアップ (02)

ssh関連。

ssh接続してみる(Macにて)

Macからssh接続してみる。

$ ssh pi@192.168.**.**
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
f6:db:56:79:**:**:**:**:**:**:**:**:**:**:**:**.
Please contact your system administrator.
Add correct host key in /Users/****/.ssh/known_hosts to get rid of this message.
Offending RSA key in /Users/****/.ssh/known_hosts:2
RSA host key for 192.168.**.** has changed and you have requested strict checking.
Host key verification failed.

Mac上に、先代RasPiへの接続情報が残っているからWarningが出たっぽいので、該当行を削除してリトライ。

$ ssh pi@192.168.**.**      # -> Mac
pi@192.168.**.**'s password:
pi@raspberrypi ~ $          # -> RasPi

OK。

authorized_keysファイル作成

$ cd
$ mkdir .ssh
$ chmod 700 .ssh
$ cd .ssh
$ touch authorized_keys
$ chmod 600 authorized_keys
$ vi authorized_keys

Mac側で用意しておいたid_rsa.pubの内容をコピペする。

sshd設定&再起動

$ su -
# cd /etc/ssh
# cp -ip sshd_config sshd_config.bkup
# vi sshd_config
  Port 22                                           # -> 好みのポート(nnn)に変更
  PermitRootLogin yes                               # -> PermitRootLogin no に変更
  PubkeyAuthentication no                           # -> PubkeyAuthentication yes に変更
  PermitEmptyPasswords no                           # -> PermitEmptyPasswords yes に変更
  #AuthorizedKeysFile      %h/.ssh/authorized_keys  # -> 頭の#を取る
# /etc/init.d/ssh restart

ssh接続(再)

$ ssh pi@192.168.**.** -p nnn  # -> Mac
pi@raspberrypi ~ $             # -> RasPi

パスワード入力なしで接続できるようになった。


以降次回。


Raspberry Pi 再セットアップ (01)

Raspberry Piの環境を再構築したので、そのメモ。

環境

  • 作業環境はMac OS X (10.8.5)
  • セットアップ対象は2014-09-09-wheezy-raspbian
  • 使用するSDカードはClass 10 16GB(メーカ不明)

下準備

SDカードの予備が見当たらなかったので、今動いているRasPiを消して入れ替えることに。
念のため、Macにて、RasPi入りのSDカードをimg化する。
[tech][raspberrypi] Raspberry Pi の SD カードを Mac でバックアップ | Wed, Jan 15. 2014 - 氾濫原 [HANRANGEN]

終わったらSDカードを一旦フォーマット。

Raspbianのダウンロードとインストール

本家からイメージを持ってくる。
Downloads | Raspberry Pi
zipを解凍してimgファイルを作っておく。3.3GBくらいになった。

そのimgファイルを、「RPi-sd card builder v1.2」というツールで楽にインストールできる。

SD card setup – Raspberry Pi – Mac | All the (*)Ware
起動して、imgファイル選んで、待つだけ。簡単。

初回起動

最初はssh使えないので、USBキーボードをつけて起動。画面はHDMI出力で。
下記設定を済ませたら再起動。

  • ディスク使用量最適化
  • piユーザのパスワード設定(多分あとでユーザ消すけど)
  • オーバークロックをMediumに
  • Localeをja.UTF-8
  • TimezoneをTokyoに
  • sshを有効に

rootパスワード設定

$ sudo sh
# passwd
新しいUNIXパスワードを入力してください:
新しいUNIX パスワードを再入力してください:
passwd: パスワードは正しく更新されました
# exit

アップデート

ssh接続してからでもいいけど、このタイミングでアップデートしておく

$ sudo apt-get update
$ sudo apt-get upgrade


以降次回。

写真のEXIFを抽出してCSVにする

  • たくさんの写真のEXIF情報から、必要な情報(シャッタースピードF値ISO感度)だけ抜き出して一覧化したい。
  • テキストデータを出力し、後に集計やグラフ化を行いたい。(自分が撮影する写真の傾向などがわかって面白いかもしれない)

と思うことがあったので、試してみた。環境はMac OS X(10.8.5)。

1. ImageMagickのインストール

pkgが配布されているので、それを使用する。
ImageMagick installer for Mac OS X

/opt/ImageMagick配下にインストールされる。環境変数PATHの設定は自動でされないので、必要であれば自分でやる。今回は見送った。

2. identifyの使用

ImageMagickには「identify」というツールが含まれていて、メタデータなどが参照できる。

$ /opt/ImageMagick/bin/identify -verbose XXXXXXXX.JPG
  Format: JPEG (Joint Photographic Experts Group JFIF format)
  Mime type: image/jpeg
  Class: DirectClass
  Geometry: 2560x1920+0+0
  Resolution: 350x350
  Print size: 7.31429x5.48571
  Units: PixelsPerInch
  Type: TrueColor
  Endianess: Undefined
  Colorspace: sRGB
  Depth: 8-bit
  …

このうち、今回欲しいEXIF情報は下記3つ。

シャッタースピード exif:ExposureTime
F値 exif:FNumber
ISO感度 exif:ISOSpeedRatings

なので、下記コマンドで(ファイル名と)必要な情報のみ抜き出して表示する。

$ /opt/ImageMagick/bin/identify -format "%[filename], %[Exif:ExposureTime], %[Exif:FNumber], %[Exif:ISOSpeedRatings]\n" XXXXXXXX.JPG

3. バッチ化

指定したフォルダ内の写真ファイルすべてに対して処理を行わせる。lsとxargsの組み合わせかなと思ったが、xargsはファイルへのリダイレクトに対応していないらしいので、forで実現。私が使うカメラ(OLYMPUS E-M1)が出力するJpegは、拡張子が大文字で「JPG」なので、*.JPGで抽出。

$ for file in `ls *.JPG`; do /opt/ImageMagick/bin/identify -format "%[filename], %[Exif:ExposureTime], %[Exif:FNumber], %[Exif:ISOSpeedRatings]\n" $file >> exif.csv; done

そのディレクトリに「exif.csv」という名前で、見出しも何も無いCSVファイルができる。

とあるJavascriptを特定のページ(とあるcontrollerのとあるaction)でだけロードして実行したい

いろいろハマったので、メモ。Railsは4.1.1。初級者なので、個々の用語や表現は厳密ではない(かもしれない)のでご注意を。

やりたいこと

とあるJavascriptを特定のページ(とあるcontrollerのとあるaction)でだけロードして実行したい。

本稿執筆時点のRailsには以下2機能が存在し、デフォルトで有効になっている。

  1. Asset Pipeline
    • 複数javascriptcssのファイルをマージ・圧縮し、読み込みを高速化する機能
  2. Turbolinks
    • ページ遷移をAjaxに置き換えて表示を高速化する機能

とても便利な機能だが、「とあるJavascriptを特定のページでだけロードして実行したい」という望みとの相性が悪い。というのも、

  1. Asset Pipeline
    • jsファイルを小分けにしても、一つのファイルにマージされてしまう。
  2. Turbolinks
    • ページ遷移時はheadとbodyをJavascriptにて書き換えており、linkタグなどが再解釈されて読み込まれるわけではない。

という動作のため。(あくまでイメージということで…)

対策

下記すべての合わせ技で実現する。

  1. 読み込ませたいjsファイルを、Asset Pipelineの対象から外す
  2. 読み込ませたいjsファイルを、precompile対象に追加する
  3. 読み込ませたいjsファイルを、Turbolinksの対象から外す
  4. app/views/layouts/application.html.erbにて、「特定のページのときだけ」対象のjsファイルをincludeする記述を追加する

読み込ませたいjsファイルを、Asset Pipelineの対象から外す

まず、読み込ませたいjsファイル(以下、hoge.js)を、app/assets/javascript/配下に置く。
そして、app/assets/javascript/application.jsに下記を追記する。

//= stub hoge

読み込ませたいjsファイルを、precompile対象に追加する

config/initialize/assets.rbに、hoge.jsについての記述を追加する。

Rails.application.config.assets.precompile += %w( hoge.js )

こうすることで、view側でjavascript_include_tagで読み込めるようになる。

読み込ませたいjsファイルを、Turbolinksの対象から外す

「data-turbolinks-track」オプションを付与することで実現可能。
おそらく、これが含まれているタグがあるページヘの遷移は、Ajaxじゃなく通常遷移するような作りになっているのではないかと推測(調べていない)。

<%= javascript_include_tag "hoge", 'data-turbolinks-track' => true %>

app/views/layouts/application.html.erbにて、「特定のページのときだけ」対象のjsファイルをincludeする記述を追加する

上記javascript_include_tagに、適当な条件を付与する。方法は色々。今回は最後の手法を用いてみた。作法的には良くないのかもしれないけど、provideを使った。

  • app/views/layouts/application.html.erbのbodyタグのidやclassにcontroller名、action名を付与するようにし、狙った組み合わせになったときにだけ読み込ませるようにする。
  • ルーティングに基いて、狙ったルートのときだけ読み込ませるようにする。
  • とある変数が定義されていたときだけ読み込ませるようにする。

まず、app/views/layouts/application.html.erbを下記のように変更、

<%= javascript_include_tag "hoge", 'data-turbolinks-track' => true if content_for?(:use_hoge) %>

次に、対象のviewの先頭に下記を追加。

<% provide(:use_hoge, true) %>

Ruby on RailsによるWebアプリ開発記(03)

Ruby on RailsによるWebアプリ開発記(03)

前回
Ruby on RailsによるWebアプリ開発記(01) - メモ置き場
Ruby on RailsによるWebアプリ開発記(02) - メモ置き場

ルールは決まったけど、やっぱりちょっとやりにくい

これまで、「作業が完了したらPull Requestを作成してコードレビュー」という方針で実施してきたが、下記の問題が多々発生した。

  1. Pull Requestが作成されるまでは、各自の作業状況が把握しにくい
    • commitログを見ればどんな変更を行っているかは一応把握できるが、全作業の何%が終わっているのかがわからない。
  2. 意識相違やミスがキャッチできない
    • Pull Requestでのソースレビュー時に「ここはこういう書き方にすべき」などの指摘が入った場合、大きな手戻りが発生してしまう。
  3. (その機能実装についての)悩みや疑問がうまく共有できない
    • 質疑応答や議論は、別途「CircleBoard」で行っていたが、質問内容が分散したり、また後々になって探す手間がかかったり、細かい悩みはあった。(CircleBoard自体は優秀な掲示板ツールではある)

WIP PR導入

「WIP PR(Work In Progress Pull Request)」という方式がイイという噂を聞き、試しに導入してみたところ、とても素晴らしかったので、本格導入することになった。

WIP PRとは

git commit --allow-empty を使った WIP PR ワークフロー - Qiita」にあるように、“作業途中で出すPull Request”を使うワークフローとのこと。
通常のPRに比べ、レビューを早期に行えるので、修正コストが低かったり、作業進捗が把握しやすかったりするメリットがある。デメリットとしては、commitやpushに一工夫必要なので、慣れないうちは少し難しい、くらいであると感じた。

やりかた

作業開始時

1. ブランチ作成
$ git cehckout master
$ git pull
$ git checkout -b ブランチ名
$ git commit --allow-empty -m '作業開始っぽいメッセージ'
$ git push origin ブランチ名
2. タイトル頭に「[WIP]」をつけ、Pull Requestを作成

作業中

1. 聞きたいことや言いたいことがあれば、作成したPull Request上にコメントを残していく
  • 他のメンバーにはGitHubから通知が行くので、(おおむね)すぐに気づいてもらえる
2. いつも通りcommit&pushを行う
  • 高頻度で行う(前回記事参照)

作業終了時

1. Pull Request名変更
  • Pull Request名から「[WIP]」を外し、レビューを依頼
2. masterへのmerge(レビュー完了後)

commit履歴の整理(作業開始時/作業完了時以外にcommitを行った場合、masterにmergeする際に邪魔になるので、消去)

$ git log                    # ブランチ作成時の最初のコミット番号を控える(xxxxxxx)
$ git rebase -i xxxxxxx      # 最新のコミットのみ「pick」のこりは「squash」を選択する
$ git push -f origin ブランチ名

GitHub画面からのmerge

  • conflictにより自動mergeできない場合、ローカルで実施する
$ git checkout master
$ git pull
$ git merge ブランチ名      # -> CONFLICT (content): Merge conflict in xxxxxx と出たものを、エディタで修正
$ git commit -m 'ブランチmergeっぽいメッセージ'
$ git push origin master
3. ブランチ削除
$ git checkout master
$ git branch -d ブランチ名            # ローカルブランチ削除
$ git push --delete origin ブランチ名 # リモートブランチ削除

導入後

ちょっとわかりにくい内容ではあるが、やってみるとこれがかなり便利であると実感した。

  • ひとりひとりの作業が独立している
  • 対面で話す機会が少ない
  • 個々の能力があまり高くない(ので、指摘が多い)

といったプロジェクトには、かなり効果が高いのではないだろうか。

Ruby on RailsによるWebアプリ開発記(02)

前回
Ruby on RailsによるWebアプリ開発記(01) - メモ置き場

Ruby On Railsって何?そもそもRubyって何?

という疑問がまずあったので、「Ruby on Rails チュートリアル:実例を使って Rails を学ぼう」でお勉強。

のそれぞれの基本は学べた。ただし、解説は執筆時点のバージョンで行われている。一部、最新バージョンでは別の書き方をするものもあるので、そのへんは注意が必要。
まだまだ謎は多かったが、疑問が発生したらその都度調べれば良いと判断したため、作業に着手することにした。

GitHub Flowって何?

ソースコード管理にGitHubを使用することにしたため、開発手法もGitHub Flowというものを使用することになった。解説サイトは多数存在するが、個人的にもっともわかりやすいと思ったのが「Github-flowを分かりやすく図解してみた - pyar.bz」。
開発当初、「GitHub Flowを使おう」とだけ決めており、下記については決めなかったせいで、いろいろと混乱してしまった。

  1. どの単位でbranchを作るか?
  2. どの単位でcommitするか?
  3. どの単位でpushするか?
  4. branch名に規約を作るか?
  5. commitメッセージに規約を作るか?

というのも、今回のツール開発は

  • 複数人で作業を実施する
  • 対面で話す機会が少ない
  • ほぼ全員が未経験者

という事情があったので、「Aはこうやってたけど、Bはこうやってた、じゃあ私はどうやればいいの?」と疑問に思っても、相談しにくい環境だった。
また、開発初期は「Aが担当する機能Xを実装しないと、Bが担当する機能Yを実装できない。機能Yを実装しないと、Cが担当する機能Zが実装できない」ということも起こった。(今にして思えば、作業分担をもっとしっかり検討するべきだったが、素人集団にはそこまで考慮できていなかった)

作業のルール化

開発も中盤になり、細かい機能の実装が作業の中心になってきたこと、作業者が小慣れてきたことなどから、前記1〜3については下記のとおりルールを決めた。

  1. どの単位でbranchを作るか?
    • 実装する機能の単位。
  2. どの単位でcommitするか?
    • 作業の区切りが良いとき。(全テストがpassしていること。どうしても通らない場合はpendingやコメントアウトで。)
  3. どの単位でpushするか?
    • commitと同じタイミング。


ルールは決まったが、まだ課題はあった。それは次回。

Ruby on RailsによるWebアプリ開発記(01)

はじめに

2014年、春。
私を含め、IT業界で働く友人ら数名で、身内向けWebアプリを開発することになった。私自身の仕事はとある銀行の勘定系アプリ作成なので、Webアプリなんてものは完全に未知の領域だったが、言い出しっぺということもあり、なぜか私が仕切る(&もちろんコードも書く)ことになった。
それを通していろいろと学ぶこと−−主に反省点−−が多かったので、記録として残しておくことにする。(まだ完成していないけど)

何を作るか

  • xxxの代金は、Aさんがまとめて払ってくれました
  • yyyの代金は、Bさんがまとめて払ってくれました
  • zzzの代金は、Cさんがまとめて払ってくれました

といったことが積み重なり、“結局誰が誰にいくら渡せばいいんだっけ?”という把握が煩わしくなったので、それを支援してくれるようなツールが欲しくなった。
いろいろ検索してみるが、細かい要望にドストライクなツールは見当たらなかったので、作ることにした。

何で作るか

私がMacユーザということもあり、最初はiOSアプリでつくろうと考えた。が、以下の理由により断念。

  1. 仲間内で使うだけのツールなのに、開発者登録(有料)が必要
  2. 仲間全員がiOSユーザではない
  3. Objective-Cが意味不明

しばらく悩んだが、“仲間全員が簡単に使えること”を重視した結果、Webアプリという回答に辿り着いた。しかし、Webアプリと言ってもその実現方法は多岐にわたると聞く。何で作るか相談し、結局Ruby on Railsで、という結論に至った。以下理由。

  1. 開発メンバーの一人(A氏)が、仕事で使い始めたから
  2. 流行っているから
  3. フレームワークとしてある程度しっかりしているので、初心者でも比較的とっつきやすいらしいから
  4. ベース言語のRubyは日本人が作っただけあって、日本語ドキュメントも多く、理解しやすいはずだから

3番めに関しては真偽のほどは定かではないが、メンバーがそんなことを言っていた気がするので信じることにした。
4番めも信じることにしたが、他言語に比べて多いのかどうかは知らない。

どうやって作るか

経験者であるA氏のアドバイスにより、下記ツールたちを使って進めていくことになった。

ソース管理

GitHub

画面遷移図、ER図(検討用)

cacoo

会議

Skype

掲示板(進捗報告や議論など)

CircleBoard

その他(議事メモ・作業メモなどの記録場所)

仲間が身内向けに立てているサーバ上のTrac Wiki


とりあえず、道具は揃えたように見えた。知識と技術はこれから身につけることになるが、ひとまず作るツールの仕様について検討を始めることにした。

Git関連のコマンドなど

本当は開発環境導入から順番に書きたいところだが、コマンドを投入する機会があったので、忘れないうちにメモ。

commit

$ git commit -m 'メッセージ'

メッセージを複数行にわたって書きたいときは、 -m で改行するイメージで書く

$ git commit -m 'メッセージ1行目' -m 'メッセージ2行目'

push

$ git push origin ブランチ名

pull…のかわりにfetchとmerge

pullというのは、fetchとmergeを一気に行うことらしい。
http://qiita.com/osamu1203/items/cb94ef9da02e1ec3e921
個人的には、2段階にわけておいたほうが安心(だし、理解しやすい)ので、fetchとmergeで実施する。

$ git fetch
$ git merge FETCH_HEAD

取り消し関連

commitやpushを取り消したいときは、その目的に応じてコマンドを使い分ける必要がある。
http://www.d-wood.com/blog/2014/02/09_5497.html

当面の予定

現時点で、書こうかなーと思っている内容一覧。

IT技術(プログラミング)関連

  • Raspberry Pi環境構築
  • Ruby On RailsでのWebアプリの作りかたメモ

サバゲ関連

  • WA M4A1 GBB 整備・カスタム記録

カメラ&写真関連

書くこととくに無し。気が向いたら愛機OLYMPUS E-M1について書く。

このブログについて

以下について書こうと思っています。

  • IT技術(主にアプリのプログラミング)について
  • サバゲーやエアガンなどについて
  • カメラ・写真について

ただし上記通りとは限りません。
Twitterじゃ字数が足りない、とか、あとで見るようにまとまっていたほうがいいな、と思ったことを書きます。