OmniAICreator/Qiita-1.07M huggingface dataset:
DynamoDB の Export, Import を行ってみる


DynamoDB は、一度テーブルを作成してしまうとスループットの変更ぐらいしかできず、テーブル名の変更やインデックスの追加を行おうとすると、別テーブルへのデータ移行をしないといけないのが面倒です。

ちゃんと設計しとけよ、という話で済んでしまうけど、どうしても rename したいことがあったのでやってみました。

## 事前準備

### S3 Bucket の準備

データ保存用と、ログ用の2つ作成しておきます。
Bucket 1つにフォルダを作成してもいいです。

> ログは必須ではないですが、トラブル発生時に使うかもしれないので出力した方がいいと思います。

### IAM Role の作成

Data Pipeline を使って S3 に Export しますが、事前に IAM Role を2つ作成しておく必要があります。
作っていない場合は、以下のように作成します。

* IAM に行く
* 左メニューの Roles を選択

#### DataPipelineDefaultRole の作成

* Create New Role ボタンを選択
* Role 名に `DataPipelineDefaultRole` と入力
* AWS Service Roles の中から `AWS Data Pipeline` を選択
* 後は流れに沿ってそのまま作成

#### DataPipelineDefaultResourceRole の作成

* Create New Role ボタンを選択
* Role 名に `DataPipelineDefaultResourceRole` と入力
* AWS Service Roles の中から `Amazon EC2 Role for Data Pipeline` を選択
* 後は流れに沿ってそのまま作成

> Role 名は何でもいいのですが、AWS のドキュメントに記載されている名称がわかりやすいのでそのまま使えばいいでしょう。


## Export

まずは Export です。

DynamoDB のテーブル一覧で、Export/Import ボタンを押します。するとテーブル選択画面になるので、Export したいテーブルにチェックを入れ、Export from DynamoDB を押します。

> 複数のテーブルを同時に並列で Export 可能です。逆に Import は1つ単位でしか設定できません。

すると、Data Pipeline の作成画面になります。

* S3 Output Folder: データ出力先の S3 Bucket/Folder を指定。最後の `/` は付けないほうがよいです。
* S3 Log Folder: ログを保存するなら S3 Bucket/Folder を指定。`s3://` から記述する。最後の `/` は付けないほうがよいです。
* Throughput Rate: 最大どのくらいのスループットを消費するか。まぁ適当で。
* Data Pipeline Role: 事前に作成しておいた `DataPipelineDefaultRole` を指定。
* Resource Role: 事前に作成しておいた `DataPipelineDefaultResourceRole` を指定。

Export は、指定したベースフォルダ以下に `/export/<RegionName>/<TableName>/<ExportDatetime>/` というフォルダが作成され、その中にデータが `<UUID_xxxxxx>` というファイル名で出力されます。

> ログの作成も同様ですが、単純にパス文字列を連結しているようで、ベースフォルダの最後に `/` があると、`base//export/...` のようになり、空のフォルダが生成されてしまいます。別にアクセス可能なのですが、気持ち悪いので最後の `/` は付けないでおきましょう。そのうち修正が入るとは思いますが。。

これで Data Pipeline が作成され、裏で自動的に EMR が起動してデータの出力が行われます。
Export が完了したら、特に用がなければ作成された Data Pipeline を削除しておきます。

## Import

Import も Export とほぼ同様の流れになります。
事前に Import 先のテーブルを作成しておき、チェックを入れて Import to DynamoDB を押します。

Data Pipeline の作成画面まで行ったら、パラメータの入力を行います。

* S3 Input Folder: データ入力元の S3 Bucket/Folder を指定。先ほど Export したフォルダ `s3://<bucket_name>/<base_path>/export/<RegionName>/<TableName>/<ExportDatetime>` を設定します。

他のパラメータは Export と同じです。

> Input Folder の最後の `/` は付けないよう注意してください。読み込み対象のファイルが発見できず、インポートに失敗します。

あとは、Export 時と同様に Data Pipeline が作成され、EMR が動いてそのうち Import が完了します。
Import が完了したら、特に用がなければ作成された Data Pipeline を削除しておきます。

## Import 用データ作成

Export されたデータは比較的シンプルなデータ構造のようですので、自前で生成すれば簡単に DynamoDB に Import できそうです。

http://docs.aws.amazon.com/datapipeline/latest/DeveloperGuide/dp-importexport-ddb-pipelinejson-verifydata2.html
libxml 2.9環境でnokogiri 1.6.3を使うとハマる

libxml 2.9.0以降のバージョンでnokogiri 1.6.3とかを```bundle install```しようとするとハマります。もちろん```gem install```でもハマります。

対策として

```
--with-xml2-include=/usr/include/libxml2/
```

するといいです。

まとめると、bundlerを使うなら

```shell-session
user@local ~$ bundle config build.nokogiri --use-system-libraries --with-xml2-include=/usr/include/libxml2/
user@local ~$ bundle install
```

すればいいです。
unzipコマンドの日本語パッチ

unzipコマンドが日本語ファイル名だと文字化けるので対応。

```shell-session
# cd /usr/local/src/
# wget 'http://sourceforge.jp/frs/g_redir.php?m=jaist&f=%2Finfozip%2FUnZip+6.x+%28latest%29%2FUnZip+6.0%2Funzip60.tar.gz' -O unzip60.tar.gz
# tar zxvf unzip60.tar.gz
# cd unzip60
# yum -y install bzip2-devel.x86_64
# wget http://gist.github.com/raw/573753/unzip-6.0-japanese_charset.patch
# patch -p1 < unzip-6.0-japanese_charset.patch
# make -f unix/Makefile LOCAL_UNZIP="-D_FILE_OFFSET_BITS=64 -DNO_LCHMOD -D_MBCS -DNO_WORKING_ISPRINT" generic_gcc
# make -f unix/Makefile LOCAL_UNZIP="-D_FILE_OFFSET_BITS=64 -DNO_LCHMOD -D_MBCS -DNO_WORKING_ISPRINT" install
# which unzip
/usr/local/bin/unzip
```
Windowsで便利なツール　ショートカットキー

##ショートカットキー

指定領域のキャプチャを撮る
win + s 

新規フォルダ
・フォルダ内
ctrl + shift + F

・デスクトップ
ctrl + shift + N

「ファイル名を指定して実行」ダイアログを開く
win + R 

##ツール

alfredっぽいやつ
Executor
http://wordcloud-design.com/2014/07/windows%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8Bmac%E3%81%AEquicksilver%E3%82%84alfred%E7%9A%84%E3%81%AA%E3%83%A9%E3%83%B3%E3%83%81%E3%83%A3%E3%83%BC/


xtrafinderっぽいやつ
qtTabbar
http://qttabbar-ja.wikidot.com/
YosemiteアップグレードしたらTexShopが動かなくなった場合の解決法

Yosemiteにアップグレードしたら，
Texshopでコンパイルしてもなんかエラーを吐かれる現象に．

原因は`/usr/X11/`->`/opt/X11`と何故か変わってしまっていたこと．

とりあえず，

```shell-session
$ sudo ln -s /opt/X11 /usr/X11

```

これで解決．なんでAppleは動かしたんだろう？
Heroku で Hello World するまでの手順＆エラー対応

WindowsでHeroku で deploy までの手順で、push master するときの
ssh公開鍵関連で手間がかかったので備忘録。

デプロイまでの手順の参考は以下。

[mobage develover blog 初心者でも15分で公開できるHerokuのはじめかた](http://developers.mobage.jp/blog/how-to-use-for-beginners-heroku)


「7. アプリをデプロイ」までは問題なく実行できたあと、
git push heroku masterを実行した時に以下のエラーになった。

> prompt>git push heroku master
The authenticity of host 'heroku.com (50.19.85.154)' can't be established.
RSA key fingerprint is XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'heroku.com,50.19.85.154' (RSA) to the list of known hosts.
Permission denied (publickey).
fatal: Could not read from remote repository.


試した対応方法は以下。

1. 鍵の環境設定 [参考](http://piccagliani.hatenablog.com/entry/2013/03/06/185644)
コマンドプロンプトで実行。鍵は認識していたので解消しなかった。
>set HOME=C:\Users\%USER%

2. keyを初期化して再度追加。[参考](http://stackoverflow.com/questions/20147312/permission-denied-publickey-heroku-gitclone-myapp-on-windows)
以下のコマンドを実行した。
> heroku keys:clear
> heroku keys:add (リストから公開鍵を選択)
> heroku keys (公開鍵を確認)

3. configファイル編集 [参考](http://thinkami.hatenablog.com/entry/20131230/1388353048)
SSH_HOMEがどこかは要確認。(windows7_x64 pro で) C:\Users\%USER%\\.ssh\config ファイルを設定。
>Host heroku.com
User git
port 22
Hostname heroku.com
IdentityFile ~/.ssh/heroku_rsa
TCPKeepAlive yes
IdentitiesOnly yes

上記の後、git push heroku master を実行すると、無事Hello world完了。
bashのヒアドキュメントを活用する

# ヒアドキュメントとは
複数行の文字列を簡潔に記述するための機能です。

これを

```sh
echo 'hoge'
echo 'fuga'
echo 'piyo'
```

こんな風に記述できます

```sh
cat << EOS
hoge
fuga
piyo
EOS
```

ヒアドキュメントはシェルスクリプトの中にちょっとした別のスクリプトを埋め込むときに便利です。
数行のスクリプトのためにわざわざファイルを作る必要がなくなり、見通しがよくなります。

```sh
# ちょっとしたスクリプトを動かすのに便利
# 例) oracleDBのテーブル一覧を出力する
sqlplus -S user/pass@sid << EOS
set pagesize 0
set feedback off

select table_name from tabs
order by table_name;
EOS
```



# 要点
ヒアドキュメントを理解するうえで重要なのは、**ヒアドキュメントは標準入力として扱われる**、ということです。
文字列リテラルでないことに注意してください。

これを把握していれば、最初の例で`cat`にヒアドキュメントを渡していた理由がわかるかと思います。
`cat`はファイルを省略した場合に標準入力から読むため、ヒアドキュメントの内容が標準出力に出ることになります。

逆に下記のように`echo`に渡しても内容が標準出力に出ることはありません。`echo`は標準入力から読まないし、
ヒアドキュメントはリテラルではないからです。

```sh
# 改行が出力されて終わり
echo << EOS
hoge
fuga
EOS
```

# 文法
コマンドに`<< EOS`が渡されると**次の行**から**EOSが単独で現れる行**までの間が
ヒアドキュメントの内容になります。

言い換えれば、コマンドそのものが記載された行に、コマンドの振る舞いを指定し、
そこで標準入力として与える内容を次の行から記載することになります。

`EOS`の部分は任意の文字を使うことができます。`HOGE`でも`_DOC_`でも問題ありません。
「EOSが単独で現れる行」というのは空白やタブなど、一切のほかの文字も含んではいけません。

「次の行から」というのもポイントです。
つまりは以下のようにも書けます。

```sh
# ヒアドキュメントの内容とmyfile.txtの内容を連結してconcat.txtに書き込む
cat - << EOS myfile.txt > concat.txt
hoge
fuga
EOS
```

なおここで、catの直後`-`は、catの仕様として、**ファイル名を指定すると標準入力から読み込まなくなる**ため、
明示的に`-`を指定して、標準入力として渡したい箇所を指定する必要があります。

## 変数展開・コマンド置換
ヒアドキュメントの中でも`""`で括った文字列リテラルと同様、
変数展開やコマンド置換が行われます。

つまり`$MY_VAR`や`$(date)`と書くといつもと同じように展開されます。

これを抑止する(=`''`で括ったときのように扱う)には`EOS`の部分を下記のようにクォートします。

```sh
cat << 'EOS'
    $MY_VAR と書いても展開されない
EOS
```

## 行頭のタブを取り除く
ヒアドキュメントは便利ですが、インデントできないのが難点です。
EOSをインデントしてしまうとヒアドキュメントの終わりとして認識してくれませんし、
ヒアドキュメントの内容にインデントがそのまま反映されてしまいます。

この問題を解決するための機能が用意されていて、`<<`を`<<-`に書き換えるだけで
使用できます。`<<-`でヒアドキュメントを書くと、行頭のタブを無視してくれます。

ただし、タブといっているのは**ハードタブ**のみでスペースは相変わらず取り除いてくれません。
(たぶんヒアドキュメント中でインデントするときのためにこうしていると思うのですが・・・)

```sh
# >--- はハードタブだと思って読んでください
cat <<- EOS
>---    hoge
>---        fuga
>---EOS
```

上記の例は

```sh
    hoge
        fuga
```
と表示されます。

## 変数に代入する
ヒアドキュメントは標準入力なので、変数に入れるにはちょっとした細工が必要です。
以下のようにすれば変数に代入することができます。

```sh
HOGE=$(cat << EOS
hoge
fuga
EOS
)

# もしくは
HOGE=`cat << EOS
hoge
fuga
EOS
`
```
形態素解析のために Wikipedia とはてなキーワードからユーザー辞書を生成し利用する

# 形態素解析エンジンと辞書

[MeCab](http://sourceforge.jp/projects/mecab/) はオープンソースの形態素解析エンジンであり、自然言語処理の基礎となる[形態素解析](http://ja.wikipedia.org/wiki/%E5%BD%A2%E6%85%8B%E7%B4%A0%E8%A7%A3%E6%9E%90)のデファクトとなるツールです。また各言語用バインディングを使うことで Ruby や Python をはじめ多くのさまざまなプログラミング言語から呼び出して利用することもでき大変便利です。

MeCab の仕組みとしては、対象言語の文法の知識を形態素解析用「辞書」 (品詞等の情報付きの単語リスト) という形で用意しこれをもとに自然言語を分解、品詞を判定します。[プロジェクトページ](http://mecab.googlecode.com/svn/trunk/mecab/doc/index.html)には 3 種類の辞書が紹介されています。ほぼそのまま引用ですがまとめると以下の通りです。

|辞書名|説明|
|:--|:--|
|IPA 辞書|IPAコーパス に基づき CRF でパラメータ推定した辞書|
|Juamn 辞書|京都コーパスに基づき CRF でパラメータ推定した辞書|
|Unidic 辞書|BCCWJ コーパスに基づき CRF でパラメータ推定した辞書|

## 形態素解析用辞書の問題点

さて、これらの辞書、たとえばもっともポピュラーと思われる IPA 辞書を利用してみますと、一部の IT 用語など専門用語がうまく解析できません。たとえば以下の通り「クラウド」という言葉はクラとウドに分かれて解析されてしまいます。

```rb
require 'MeCab'
m = MeCab::Tagger.new
print m.parse("クラウド")
#=>
# クラ    名詞,固有名詞,一般,*,*,*,クラ,クラ,クラ
# ウド    名詞,一般,*,*,*,*,ウド,ウド,ウド
# EOS
```

IT 関連の分野におけるテキストマイニングをするにあたり、この精度では色々と支障をきたすことになってしまいます。そこで、辞書を独自に作成し、オリジナルのカスタム辞書を用意することにします。

## ユーザー辞書を作成する

[ここ](http://kzy52.com/entry/2014/10/05/195534)や[ここ](http://sugamasao.hatenablog.com/entry/2014/11/17/000355)を参考にしています。

[Wikipedia](http://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%9A%E3%83%BC%E3%82%B8) や[はてなキーワード](http://d.hatena.ne.jp/keyword/)には最新の IT 関連の語彙も満載ですから、これらを元に MeCab 用のユーザー辞書を作ります。

### キーワードファイルをダウンロードする

curl または wget などでソースとなるキーワードファイルを取得します。

```bash
# はてなキーワード
curl -L http://d.hatena.ne.jp/images/keyword/keywordlist_furigana.csv | iconv -f euc-jp -t utf-8 > keywordlist_furigana.csv
# Wikipedia
curl -L http://dumps.wikimedia.org/jawiki/latest/jawiki-latest-all-titles-in-ns0.gz | gunzip > jawiki-latest-all-titles-in-ns0
```

### 名詞を抜き出して CSV ファイルにする

これらから名詞を抽出して CSV ファイルを生成します。

```rb
require 'csv'

original_data = {
  wikipedia: 'jawiki-latest-all-titles-in-ns0',
  hatena: 'keywordlist_furigana.csv'
}

CSV.open("custom.csv", 'w') do |csv|
  original_data.each do |type, filename|
    next unless File.file? filename
    open(filename).each do |title|
      title.strip!

      next if title =~ %r(^[+-.$()?*/&%!"'_,]+)
      next if title =~ /^[-.0-9]+$/
      next if title =~ /曖昧さ回避/
      next if title =~ /_\(/
      next if title =~ /^PJ:/
      next if title =~ /の登場人物/
      next if title =~ /一覧/

      title_length = title.length

      if title_length > 3
        score = [-36000.0, -400 * (title_length ** 1.5)].max.to_i
        csv << [title, nil, nil, score, '名詞', '一般', '*', '*', '*', '*', title, '*', '*', type]
      end
    end
  end
end
```

これにより custom.csv というファイルが生成されます。

### ユーザー辞書を作成する

こうして出来た CSV ファイルを元に mecab-dict-index コマンドでユーザー辞書 custom.dic を作ります。

```bash
/usr/local/libexec/mecab/mecab-dict-index -d /usr/local/lib/mecab/dic/ipadic -u custom.dic -f utf-8 -t utf-8 custom.csv
```

これでユーザー辞書は完成です。

## ユーザー辞書をプログラム言語から使う

プログラムからユーザー辞書を指定して利用する場合には、インスタンス生成時の引数にユーザー辞書のパスを指定します。

```rb
userdic_path = "./custom.dic"
c = MeCab::Tagger.new("-u #{userdic_path}")
print c.parse("クラウド")
#=>
# クラウド        名詞,一般,*,*,*,*,クラウド,*,*,wikipedia
# EOS
```

今度はうまく「クラウド」という用語がひとつの名詞として解析できました。
Wikipedia に掲載されているような有名な固有名詞の解析もこれでバッチリです。
试用了下Android里的jni

最近在做android开发，需要用到同事写的c++代码。
据说jni（Java Native Interface）可以做到。
简单写了个sample：
https://github.com/jus18tin/jniSample

**步骤1 Android.mk**：
新建一个jni文件夹，里面放下面两个文件：
  Android.mk     <-- make用文件
  jni_sample.cpp <-- 实际代码，用来连接java和你需要调用c++

```mf:Android.mk
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE   := native_sample
LOCAL_SRC_FILES := jni_sample.cpp

include $(BUILD_SHARED_LIBRARY)
```

**步骤2 jni_sample.cpp**：

```cpp:jni_sample.cpp
#include <jni.h>

extern "C" {
	JNIEXPORT jint JNICALL Java_com_example_jnisample_JniSampleActivity_testJni(JNIEnv* env, jobject, jint i)
	{
		return i+1;
	}
}
```
需要注意函数名字 包名_文件名_函数名


**步骤3 Acivity**：
首先需要加载新建的这个模块，这次用模块名是Android.mk里写的native_sample，
定义函数

```java:Activity
static {
    System.loadLibrary("native_sample");
}
private native int testJni(int i);
```

就好了- -
（各种复杂的东西日后有空补充）
32bit と 64bit の差を意識せずに書式文字列で数値を扱うシンプルな方法


# 目的

```NSLog``` や ```NSString``` の ```stringWithFormat:``` で数値を文字列化するときに、32bit 環境と 64bit 環境とでサイズが異なるために、ビルドターゲットによって警告が表示されたりされなかったりします。

それを回避するのに ```"%zd"``` や ```"%tu"``` という書式を使って対応する方法がありますが、数値を単純に表示したいだけなら ```NSNumber``` にラップすると簡単です。


# NSNumber でラップして文字列に変換する

Objective-C では ```@10``` という表記で ```10``` という値を ```NSNumber``` にラップできますが、同じようにして変数も ```NSNumber``` にラップ (正式には Boxing と言うらしい) できます。

```NSNumber``` は書式 ```%@``` に渡すと文字列として置き換えられます。

```objc
NSInteger integerValue = -1;
NSUInteger uintegerValue = 2;
CGFloat floatValue = 3.5;
double doubleValue = 4.5;

NSLog(@"NSInteger = %@", @(integerValue));
NSLog(@"NSUInteger = %@", @(uintegerValue));
NSLog(@"CGFloat = %@", @(floatValue));
NSLog(@"double = %@", @(doubleValue));
```

このようにすることで、NSNumber にラップされるときに bit 環境の違いが中和されるため、警告に煩わされることなく数値を文字列に変換できます。

# サンプルの実行結果

このときの実行結果は次の通りです。

> NSInteger = -1
> NSUInteger = 2
> CGFloat = 3.5
> double = 4.5
関数型の情報を取得する

[キモいstd::functionalのテンプレート引数の渡し方を使う](http://qiita.com/rinse_/items/2bb11ee08c38c135f85c)
これの実際的な使いどころだったりというお話です

今回、関数の呼び出し規約の問題でコンパイラ依存のものが多く出てきてしまっています。
今VisualStudio2014CTPを使っているのでVSの書き方をしていますが、gccやclangをお使いの方は規約の指定を部分を読み替えてください。

まずはお馴染み。
この子を特殊化させていきます。

```
template < class >
function_element
{ // Type must be function-type!
};
```

cdecl用です。
gcc、clangの構文では、`[[cdecl]] Ret( Args... )`　となります。

```
template < class Ret, class... Args >
struct func_element < Ret( __cdecl )( Args... ) >
{
  using type = Ret( __cdecl )( Args... );
  using ret = Ret;
  using args = std::tuple < Args... >;
};
```

stdcall用です。
cdeclと全く変わりません。
gcc、clangの構文では、`[[stdcall]] Ret( Args... )`　となります。

```
template < class Ret, class... Args >
struct func_element < Ret ( __stdcall ) ( Args... ) >
{
  using type = Ret( __stdcall )( Args... );
  using ret = Ret;
  using args = std::tuple < Args... >;
};
```

その他の呼び出し規約についても同じなので割愛させていただきます。
さて、引数についてです。
実は、引数はstd::tupleにくるんでしまいましたので、簡単に引数の情報を得ることができます。

引数の数は、std::tuple_sizeで。

```
// how many arguments
std::tuple_size < typename func_element < Func_type >::args >::value
```

std::tuple_elementで引数の型をゲット。

```
// the first argument
typename std::tuple_element < 0, typename func_element < Func_type >::args >::type;
```

std::tupleではないものに包んだりする場合は、[拡張tuple_element](http://qiita.com/rinse_/items/3cbe2eab54e7c4537a8c)などが参考になるかと思います。

思ったより短くて簡単に済みました。
メンバ関数に応用すれば特定のメンバ関数を持つかどうかでオーバーロードできたりしそうですね。

ではでは。
AWS SNS HTTP Subscription の Source IP

AWS SNS HTTP 通知の際の送信元IPアドレス
----
SNSのサブスクリプションをHTTPにしてEC2サーバで通知を受け取りたい場合、
セキュリティグループの設定とかどうしたらいいんだろか？って場合

https://forums.aws.amazon.com/ann.jspa?annID=2347
上記アドレス帯をセキュリティグループに追加しとくと良いみたいだ。

追記：2014/11/25
* [【AWS発表】AWSのIPアドレスレンジをJSONで提供](http://aws.typepad.com/aws_japan/2014/11/aws-cidr-json.html)
* [AWS IP Address Ranges](http://docs.aws.amazon.com/general/latest/gr/aws-ip-ranges.html)
AWS公式でIPアドレスの範囲を提供してくれるみたいなのでこの情報を利用するといいかも。
明示的に`SNS`のアドレスレンジはなかったので`AMAZON`を利用する事になるのかな？
ただし、最初に書いたフォーラムの記事よりアドレスレンジが広いので開け過ぎになる気はします。
Cygwin, Git, ActivePerl でWindowsで開発を進めるのがお勧めできそうにない

##【追記】この問題は下記の記事で解決されています
http://qiita.com/umiai/items/a17fc4e750bdaa1dc62b

##概要
今までこの組み合わせで開発を進めてきて特に問題無かったのだが、

別のPCからgit cloneして問題無く動作するのかを確認しようと思ったら

http://qiita.com/umiai/items/7564fa745b205171268a

の問題と同時に様々な問題が発生し結構絶望的な事が判ったのでそれに関しての共有。

##とりあえず出た問題一覧
- git cloneしたバッチファイルからperlスクリプトを叩くとパスがUNIX形式に変換される
- perlスクリプトがシェル上で動作している扱いになりコマンドプロンプトのコマンドが実行できない
- pushしたPCではperlスクリプトがコマンドプロンプト上での動作扱いのため統一を取る事が不可能
- 上記の問題の影響でVisual Studioからバッチファイルを通してperlスクリプトを叩いてる箇所が全滅

##git cloneしたバッチファイルからperlスクリプトを叩くとパスがUNIX形式に変換される
理由は不明だがcygwinをインストールしているとperlスクリプトが行う各種処理がシェル上(cygwin上)での動作扱いになっているように見える。
実際に確認できたわけでは無いが少なくとも\\を/とした際にでるcygwin特有のwarningが表示されたあたりcygwin上での動作になっていると予想した。

UNIX形式のパスに変換されてるというのは、例えばperlスクリプトに引数で

> C:\\SVN\\repository

というパスを渡したとする。
しかしperlスクリプト上だと次のように表示されてしっまった。

> /c/SVN/repository

この/c/というのはUNIX形式のパスに変換されてしまっているからで、当然Windows上ではまともに動作しない。

一応ActivePerl側で動作が許容されてる気がしないでもないけどsystem関数で外部アプリケーションをキックしたりしてると死ぬ。
例えば圧縮用アプリケーションにパスを渡す際に

> system "arcive.exe \$targetPath"

みたいなことしてると$targetPathがUNIX形式のパスなので死ぬ。

##perlスクリプトがシェル上で動作している扱いになりコマンドプロンプトのコマンドが実行できない
シェル上での動作扱いになってるので例えば次のコマンドが実行できない。

> \# (perl側のFileパッケージで提供されてるmove使えという話は一先ずスルーして・・・)
> system "move \$src, \$dst"

片っ端からsystem使ってるところを全部置き換えれば良いのだがそうもいかない場合もあるはずなので現実的ではない。

##pushしたPCではperlスクリプトがコマンドプロンプト上での動作扱いのため統一を取る事が不可能
pushしたPC側はperlスクリプトがコマンドプロンプト上での動作扱いなので
上述されてる

> \# (perl側のFileパッケージで提供されてるmove使えという話は一先ずスルーして・・・)
> system "move \$src, \$dst"

のコマンドがまともに動作してしまう。
というより、むしろこれをシェル上での動作扱いでのPCで動くようにしたバージョンが動かない。

割と詰んでる。

##上記の問題の影響でVisual Studioからバッチファイルを通してperlスクリプトを叩いてる箇所が全滅
Visual Studioのビルド後イベントをバッチファイルからPerlスクリプト呼び出してやってたので全滅した。
現状手詰まりでどうしようか悩んでる・・・

##問題は解決するのか？
(Windowsでgit cloneするとアクセス権周りの情報が破壊される問題について)
http://qiita.com/umiai/items/7564fa745b205171268a

で色々と試したけどどうしてもシェル上での動作扱いになるのを防ぐためには「管理者として実行」するしかない。
Visual Studioや各種バッチファイルを毎回管理者として実行するのは面倒過ぎる・・・

唯一あるとすればシェル上での動作扱いで統一した後、pushしたPC側では再度リポジトリをgit cloneしてもらう。
スクリプトファイルはあんまり追加する事は無いだろうからそこまで手間ではないはず。

ただかなり微妙だ・・・
OpenLDAP入門

debianにて実施

```bash:パッケージインストール
apt-get install -y slapd
```

```diff:/etc/ldap/ldap.conf
- TLS_CACERT     /etc/ssl/certs/ca-certificates.crt
+#TLS_CACERT     /etc/ssl/certs/ca-certificates.crt
```

```bash:syntax&nbsp;check
slaptest -u -d 64 -f /etc/ldap/ldap.conf
```

```bash:管理者のパスワード設定
dpkg-reconfigure slapd
```

```bash:
service slapd restart
```

```bash:dnを確認
slapcat | grep ^dn | grep admin
```

ここで表示された`cn=admin,dn=xxxx`を以下にて用いる。

## ldapにログイン

[Apache LDAP Studio](http://directory.apache.org/studio/)を使う。

![スクリーンショット 2014-11-19 13.29.04.png](https://qiita-image-store.s3.amazonaws.com/0/25728/66340a4a-7dfd-dae2-cbc9-5dfd08e46e62.png)

![スクリーンショット 2014-11-19 13.29.32.png](https://qiita-image-store.s3.amazonaws.com/0/25728/bb361ddb-0066-a97b-6a67-f7e545db6767.png)

追加やリネームがGUIで簡単にできる。


## apacheとの連携

後日書く

* [Apacheの基本認証でLDAPとファイル認証を併用すると一部ユーザのアク - あるシステム管理者の日常](http://d.hatena.ne.jp/rougeref/20130524)
* [Squidのプロキシ認証をLDAP+Digestで: 気の向くままに・・・](http://syo.cocolog-nifty.com/freely/2010/09/squidldapdigest.html)
* [認証、承認、アクセス制御 - Apache HTTP サーバ バージョン 2.4](http://httpd.apache.org/docs/2.4/ja/howto/auth.html)

`digest_ldap_auth`を使う。
Windowsでgit cloneするとアクセス権周りの情報が破壊される問題について

##【追記】この問題は下記の記事で解決されています
http://qiita.com/umiai/items/a17fc4e750bdaa1dc62b

##概要
Windowsでgit cloneするとアクセス権周りの情報がおかしくなりバッチファイル等を叩く際にパスが見つからないと言われる事がある。
現状だとバッチファイルを叩けなくなる以外では問題が起きていないがVisual Studioのビルド後イベントでバッチファイルを叩いているとうまく動作しないので問題になる。

##再現状況
[1] githubにリポジトリを作成しバッチファイルをpushする。
[2] [1]を行ったPCと別のPC(共同開発している開発者を想定)で**「cygwinを使って」**git clone
[3] バッチファイルを叩く

##結果
「指定されたデバイス、パスまたはファイルにアクセスできません。アクセス許可がない可能性があります。」
といったエラーが表示されバッチファイルを実行できない。

##原因
全部がとは言えないけどほぼcygwinが原因。
gitをcygwinで叩いてgit cloneするとクローンしたファイルやフォルダのアクセス権が壊れて【再現状況】のような状態になる。

よってとりあえず回避する場合cygwinを使わずコマンドプロンプトからgit cloneすれば良い。

ただしActivePerlを利用したスクリプトを開発に組み込んでいる場合は結構ややこしい問題にぶち当たる。別の記事としてあげるがUNIX形式のパスに勝手に変換されたりシェルスクリプト上で動く為にWinのコマンドプロンプトで利用可能なコマンドがsystem関数を通して使えなかったりしてはっきりいって使い物にならない。

##試したこと
一応試したことを記載しておく。cygwinからgit cloneした後に起きた問題はファイルアクセス権周りなのでその辺りで色々と試した

- アクセス権の変更(右クリックからエクスプローラの機能で変更)
　他の正しいアクセス権のフォルダと見比べながら併せてみてもバッチファイルは実行できず。

- コマンドからアクセス権変更
　そもそもls -lsaで所有者やアクセス権を確認すると何も問題が無い。その後アクセス権を変更するコマンドを打っても「アクセス権は正しく変更されている為何もしない」といったメッセージが出てまぁそりゃそうだよなといったところ。当然バッチファイルは実行できず。

- 管理者実行
　現状唯一の回避策。これだけはまともに動く。

- ファイル本体のアクセス権をフルコントロールに変更
　実はこれなら「一応は」動作した。一応はというのは「サブフォルダ含めた全ファイルのアクセス権変更」を利用した場合は動作せず、あくまでファイル単体で右クリックしてアクセス権を変更するとうまく動作するという意味。
　しかし当然バッチファイル内で別のバッチを叩いている場合それも変更しなければならず、サブフォルダ含めた全ファイルのアクセス権変更」が利用できないので全てのバッチファイルを片っ端から右クリックで変更しなければならないので現実的ではない。おまけに上記の通りコマンドからの変更ではうまく動作しない為詰んでる。

- バッチファイルを実行するアプリケーションのデフォルトを変更
　ファイルの関連付けのアレ。cygwinになっているのでは？と思ってレジストリを削除し初期化してみた。まぁ結果はお察し・・・。
　これを試したもうひとつの理由は、パスが見つからないといわれるバッチファイルをコマンドプロンプトにD&Dして実行すれば一応は動作するという現象に遭遇したからだ(一応はというのは上記の通り別のバッチが以下略)。関連付けがcygwinになってるだけかと思ったときはこれでやっと動作すると内心大喜びしたのにごらんの有様で正直もう疲れた・・・
MacBook Air に TeX 環境を入れなおす

MacBook Air を修理に出して帰ってきたら、いろいろ環境が壊れていたのですが、TeX 環境を再構築していなかったので、してみました。

* 参考: [Mac - TeX Wiki -](http://oku.edu.mie-u.ac.jp/~okumura/texwiki/?Mac)

以前は MacTex を入れていたのですが、そんなに TeX を使い潰していないなと思って、今回は brew で BasicTex を入れました。

```bash
$ brew tap phinze/cask
$ brew install brew-cask
$ brew cask install basictex
```

basictex が入ったら、.bashrc などに path を追加します。

```bash
$ export PATH=/usr/texbin:$PATH
```
最後に、BasicTex をアップデートして、日本語環境のためのパッケージを入れて、サンプルの tex ファイルを作って、動作確認をして、今回は終わりました。

```bash
$ sudo tlmgr update --self --all
$ sudo tlmgr install collection-langjapanese
```
特定のコミットからブランチを切る

master ブランチで作業を続けてシステムを壊してしまったとき、動作確認した暫定版の release ブランチを切っておくべきだった！とあとで気がついたので調べた。
私の git の使い方だと、master ブランチが develop ブランチになっているけれど、どう開発するのがいいんだろう……

```bash
$ git checkout <commit hash> -b <branch>
```

* [gitで特定のコミットからブランチを切りたい（作成したい） - Qiita -](http://qiita.com/wnoguchi/items/dabe6e05388faf75f00c)
Heartbleed 脆弱性対応(2014/04/18 時点での話です)

## 対応
サーバが FreeBSD 10.0 - OpenSSL 1.0.1e 11 Feb 2013 と見事に影響を受けていたので、その対応をしていました。

[FreeBSD-SA-14:06.openssl](http://www.freebsd.org/security/advisories/FreeBSD-SA-14:06.openssl.asc) に対応方法が載っていたので、それに従って対応。

```shell-session
# freebsd-update fetch
# freebsd-update install
# reboot
```

```shell-session
$ uname -r
10.0-RELEASE-p1
```

```shell-session
$ openssl version
OpenSSL 1.0.1e-freebsd 11 Feb 2013
```

OS はアップデートされているけれど、OpenSSL は元のバージョンと変わっていない……？
ここ -> [The FreeBSD Forums](http://forums.freebsd.org/viewtopic.php?f=5&t=45870&p=257020#p257020) に同様の質問があり、元のバージョンと同じ表記らしいけど、脆弱性問題は修正されているらしいです。

## 参考にしたリンク集
* [The Heartbleed Bug](http://heartbleed.com/)
  * 英語だけどHeartbleed についての情報がいろいろまとまっている
* [CVE-2014-0160 OpenSSL Heartbleed 脆弱性まとめ](http://d.hatena.ne.jp/nekoruri/20140408/heartbleed)
  * 日本語でとてもまとまっている
  * 関連リンク集もあって、たどっていくと内容の掘り下げができそうです
* [The FreeBSD Forums](http://forums.freebsd.org/viewtopic.php?f=5&t=45870&p=257020#p257020)
  * # freebsd-update fetch install をして、FreeBSD 10.0-RELEASE-p1 にアップデートしたけれど、OpenSSL のバージョンが 1.0.1e のままという質問に対する解答
* [FreeBSD-SA-14:06.openssl](http://www.freebsd.org/security/advisories/FreeBSD-SA-14:06.openssl.asc)
  * OpenSSL の脆弱性に関するセキュリティ勧告
iptablesの読み方覚え書き

# iptablesの機能を有効化する

```
# service iptables restart
```

# iptablesの機能を自動的に起動する

```
# chkconfig iptables on
```

# 基本パケットの種類
- INPUT（入力）
- OUTPUT（出力）
- FORWARD（転送）

# チェーン
上の３種類のパケットはそれぞれ名前と同じ INPUT, OUTPUT, FORWARD のチェーンを通過し、一番最初にマッチした条件に動作が適用される。
（チェインは自分でも定義ができて、定義したチェインをINPUTなどのチェーンに繋げる事も可能）

# パケットフィルタリング条件の表示

```
# cat /etc/sysconfig/iptables
・
・
COMMIT
*filter
:INPUT DROP [0:0]
・
・
#COMMIT
```

で、iptablesの内容を記述しているファイルを直接見れる。
パケットフィルタリングの条件は *filter から #COMMIT の間に記述されている。

ただ、ファイルを直接見るよりも以下のコマンドで見た方が整形されていて分かりやすい。

```
# iptables -v -L 
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
11835   17M ACCEPT     all  --  any    any     anywhere             anywhere            state RELATED,ESTABLISHED
    3   144 ACCEPT     icmp --  any    any     anywhere             anywhere
    2   120 ACCEPT     all  --  lo     any     anywhere             anywhere
    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere            state NEW tcp dpt:ss
  202 13759 REJECT     all  --  any    any     anywhere             anywhere            reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
・
・
```
Chain毎に空行区切りで表示される。
出力結果の一行目

```
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
```
は INPUT チェーンのデフォルトポリシーが ACCEPT で デフォルトポリシーが適用されたパケットの数とバイト数を表す。
ちなみに、INPUTチェーンの最後に全条件にマッチするREJECTがあるので、デフォルトポリシーが適用されるパケットは 0 packets, 0 bytes　となっている。

その次の行以降にあるカラムはそれぞれ

- target：適用されるアクション(ACCEPT, DROP, REJECT, LOG, ...)
- prot：プロトコル
- opt：オプション
- in：受信するNIC(lo, eth0, ...)
- out：送信するNIC(lo, eth0, ...)
- source：送信元IP
- destination：送信先IP


# 特定のチェインのパケットフィルタリング条件の表示

-L オプションの後に 引数でチェイン名を付けると、
特定のチェインのパケットフィルタリング条件だけを表示できる。

```
# iptables -v -L INPUT
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
11837   17M ACCEPT     all  --  any    any     anywhere             anywhere            state RELATED,ESTABLISHED
    3   144 ACCEPT     icmp --  any    any     anywhere             anywhere
    2   120 ACCEPT     all  --  lo     any     anywhere             anywhere
    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere            state NEW tcp dpt:ssh
  202 13759 REJECT     all  --  any    any     anywhere             anywhere            reject-with icmp-host-prohibited
```
Flowとは ～はじめてのfacebook/flow～

@mizchiさんの [facebook/flowファーストインプレッション](http://qiita.com/mizchi/items/d50fbdd8c2dcd01c38f9)
> 大雑把にはfacebook製のTypeScriptだと思っていれば良いです。

があまりしっくりこなかったので、 [公式About](http://flowtype.org/docs/about-flow.html) を読んでみた。（誤訳あったらすみません。）

# Flowとは（ざっくり）
* JSのための **_static type checker_**
* JSファイルの冒頭に `/* @flow */` を挿入することで型チェック（あるいは、同時にコンバート）が働くようになる。
* 逆に言うと、 `/* @flow */` が無いファイルは無視される。
* 初回はコードベース内の全ファイルに対して解析を行い、その後は **バックグラウンドで** それらのファイル（と依存関係にあるもの）の変更を監視して型チェックする。
* チェックの結果はサーバに蓄積されており、クエリが発行された際に即座に利用できる。
* 故に開発者はコンパイルの遅延を感じなくて済む。


# 公式の結び
* 「まだめっちゃWIPだからみんな力を貸してね！簡単かつ安全にJSの変換と最適化ができる環境を提供したいなって思ってるから。」

# [（余談）Flowにファイル変更を監視させるには](http://flowtype.org/docs/new-project.html#using-the-flow-server)
* `flow start` でバックグラウンドでサーバ起動
* `flow` でサーバに蓄積されている型チェックの結果を取得
* `flow stop` でサーバを停止

# 所感
* 個人的にはAltJSという位置づけより、やはり「static type checker」として使ってみたいなと思うのであった。
Android 4.0系で、テキスト幅が約半分になってしまう問題


どういう条件で起こるのかはまだはっきり調べられてないけど、
たまにAndroid 4.0系でテキストの折り返し位置が明らかにおかしい場合がある。
正しい幅に対して半分くらいの位置で折り返してしまう。

そんなときは、適切な幅を指定したいDOMに対してbackground-colorを指定してあげると良いです。
注意すべき点は、

* 最下層のDOMに対してbackground-color を設定しなければならない。
* backgroundプロパティではダメ。background-color でないといけない。

という２点です。
また、背景に色をおけない状況においては、透明png等を代わりに置くとよいようです。

ちょっとこれは知らないと到底思いつかないハックです。
Homebrew Cask で Mac に Google 日本語入力を導入する手順


技術ネタではありませんが、快適な日本語入力の環境は、エンジニアの業務に欠かせないと思い。Macを入れ替えた時の為に、自分用にメモを残します。

## 環境

`Mac OS X 10.9.5 (Mavericks)`

## 導入手順

Googleのサイト（[http://www.google.co.jp/ime/index-mac.html](http://www.google.co.jp/ime/index-mac.html)）からインストーラをダウンロードしてもいいのですが、気持ちの問題で [Homebrew Cask](http://caskroom.io/) でインストールします。

```shell:
$ brew cask install google-japanese-ime
```

> Homebrew Cask の導入手順はこちらを参考にしてください
> ⇨ [Homebrew Cask で Atom を、apm で Atom のパッケージを導入したメモ](http://qiita.com/hkusu/items/f41f5566e1040147f1fc)

すると Mac のアプリケーション一覧にも表示されます。

![screen4.png](https://qiita-image-store.s3.amazonaws.com/0/35733/0ae882a2-3240-7693-8867-dccefc3fd8fa.png "screen4.png")

[システム環境設定]を開き、

![screen5.png](https://qiita-image-store.s3.amazonaws.com/0/35733/b368b398-b52d-bff4-d66b-5bde7af1d0d5.png "screen5.png")

[入力ソース]タブで [+] ボタンを押下。

![screen3.png](https://qiita-image-store.s3.amazonaws.com/0/35733/68dace04-167b-af96-32ee-fbd7895f7c88.png "screen3.png")

[日本語]を選んで、下図にある4つを選択して追加します。

![screen2.png](https://qiita-image-store.s3.amazonaws.com/0/35733/b41e0f35-420c-63ee-fdeb-cd6ebc66c0bd.png "screen2.png")

次に[英語]を選んで、下図にあるやつを追加します。

> これをやらないと「ことえり」が削除できないので。

![screen1.png](https://qiita-image-store.s3.amazonaws.com/0/35733/90902706-f644-e5c5-4ecf-21a6e77e8bda.png "screen1.png")

「ことえり」は削除します。

![screen6.png](https://qiita-image-store.s3.amazonaws.com/0/35733/b1ad283b-fd42-6063-d5be-752d571bdf3e.png "screen6.png")

必要なら、ここで OS の再起動。

## 使ってみる

:smile:

![screen7.png](https://qiita-image-store.s3.amazonaws.com/0/35733/3a6dd349-59b1-a660-54c7-5f1721ab1a5f.png "screen7.png")
Mailparserでiso-2022-jpのメールを取り扱う場合

[前の投稿](http://qiita.com/khirose/items/a064a6585e569d9ff017)でも書いたのですが、node.jsにはメールの生データからヘッダや内容、添付ファイルまでオブジェクト(JSON)化してくれる[Mailparser](https://github.com/andris9/mailparser)という便利なモジュールがあります

ただ、素でnpm installしたままだと、どうもISO-2022-JPのメールが上手く扱えないということでたまにハマります

[こちら](https://github.com/andris9/mailparser/issues/47)のやり取りやソースを見てもわかるのですが、iconvモジュールがない場合の保険(fallback)としてバンドルされているiconv-liteモジュールがISO-2022-JPを上手く取り扱えないのが原因のようで

node_modules/mailparser/node_modules/encoding

に移動して、npm install iconvして、ガチのiconvを使えるようにしてあげればこちらを使うようになるので上手く扱えるようになります
node_modules/iconvがあればそっちを読み込むのかな？
Xcode 6.2 beta with WatchKit 6.1と共存

Xcode 6.2 beta with WatchKitは、Xcode-Betaなので6.1と共存出来ますよという話。

おまけ
![xxx.png](https://qiita-image-store.s3.amazonaws.com/0/5222/135d7a4f-5232-8f4a-a566-3470a21ceaf5.png "xxx.png")
http://stackoverflow.com/questions/27005132/running-apple-watch-in-ios-simulator-issue
ここに書いてあった。
LVMで論理ボリュームの縮小、論理ボリューム追加をしてみた


## 参考

* [LVMボリュームの拡張・縮小 - GreenLeaf](http://greenleaf.sakuraweb.com/index.php?LVM%E3%83%9C%E3%83%AA%E3%83%A5%E3%83%BC%E3%83%A0%E3%81%AE%E6%8B%A1%E5%BC%B5%E3%83%BB%E7%B8%AE%E5%B0%8F)

## DISKの状況を確認

```bash:lvdisplay
# lvdisplay /dev/pve/data
  --- Logical volume ---
  LV Path                /dev/pve/data
  (略)
  LV Size                105.47 GiB
  (略)
```

```bash:
# df -h /dev/mapper/pve-data
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/pve-data  104G  390M  104G   1% /var/lib/vz
# umount /dev/mapper/pve-data
# fsck -y -f /dev/mapper/pve-data
```

## 縮小

```bash:
# resize2fs /dev/mapper/pve-data 30G
# lvreduce -L 30G /dev/pve/data
  WARNING: Reducing active and open logical volume to 30.00 GiB
  THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce data? [y/n]: y
  Reducing logical volume data to 30.00 GiB
  Logical volume data successfully resized
```

```bash:OS再起動
reboot
```

うまく行かなければ`mkfs.ext4 /dev/mapper/pve-data`すればよい。


## 論理ボリュームを作成

```bash:確認
# vgdisplay
  --- Volume group ---
  VG Name               pve
  (略)
```

```bash:残り全てを割当て
# lvcreate -n pve-drbd -l 100%free pve
  Logical volume "pve-drbd" created
```


```bash:確認
# lvdisplay /dev/pve/pve-drbd
  --- Logical volume ---
  LV Path                /dev/pve/pve-drbd
  LV Name                pve-drbd
  VG Name                pve
  (略)
  LV Size                91.47 GiB
  (略)
```

あとは`/dev/pve/pve-drbd`をフォーマットして利用する。
【Android】AndroidStudioにFabricを入れりんぐ

</br><img style="box-shadow: 0 0 0 10px #F8F6EA;" src="https://g.twimg.com/dev/marketing/fabric/fabric-introducing-fabric.png"/>
<h1>Fabricとは</h1>
<p><a href="https://dev.twitter.com/products/fabric">Fabric</a>はTwitter社が公開しているクラッシュレポートツールのCrashlyticsや広告管理ツールのMopub,無料でSMS認証が使えるDigitsなどのフレームワークの総称です。</p>
<h3>とりあえずアカウントを取得しよう</h3>
<p><a href="http://blog.valeur3.com/?p=1632">前のエントリー</a>にも書きましたが、アカウントを取得してSDKをダウンロードするのに順番待ちする必要があります。まだまだ取得に時間を要するようです。</br><font color="#808080" size=2>※筆者はサポートに何回かメールしたら順番が回ってきました。</font></p>
<h3>SDKのインストール</h3>
<p>AndroidStudioにFabricSDKを入れる場合、主に２つの方法があります。一つはAndroidStudioのプラグインを使う方法。もう一つはGradleなどのビルドツールを使う方法です。前者の方が圧倒的に簡単なのですが、最悪なことにプラグインがぶっ壊れてて機能しなかったので、今回は後者の方法でインストールしました。</p>
<p>基本的には<a href="https://dev.twitter.com/twitter-kit/android/integrate">こちら</a>のドキュメントや、<a href="https://fabric.io/downloads/gradle">こちら</a>のウィザード通りにgradleの設定を進めていけばOKです。ただ非常に分かりにくいポイントがあったのでそこについて解説します。</p>
<h3>APIKeyとBuildSecretどこやねん</h3>
<p>APIKeyとBuildSecretをcrashlytics.propertiesに設定しやがれということなのですが、APIKeyの場所がわかりにくすぎてどハマりしました。APIKeyは</p>
<strong><p>fabricのダッシュボード→Settings→ORGANIZATIONS→<自分のプロジェクト>→プロジェクト名の下にちっこく書いてあるAPIKeyとBuildSecret</p></strong>
<a href="http://blog.valeur3.com/wp-content/uploads/2014/11/sc.png"><img src="http://blog.valeur3.com/wp-content/uploads/2014/11/sc.png" alt="sc" width="724" height="484" class="aligncenter size-full wp-image-1642" /></a>
<p>をクリックするとそれぞれ表示されます。小さすぎ&階層深すぎ；；</p>
<p>この辺りを設定してから、build.gradleのdependenciesに</p>

```java:build.gradle
    // Crashlytics Kit
    compile('com.crashlytics.sdk.android:crashlytics:2.0.1@aar') {
        transitive = true
    }

    // Twitter Kit
    compile('com.twitter.sdk.android:twitter:1.0.1@aar') {
        transitive = true
    }

    // MoPub Kit
    compile('com.mopub.sdk.android:mopub:3.2.2@aar') {
        transitive = true
    }

    // Digits Kit
    compile('com.digits.sdk.android:digits:1.0.0+@aar') {
        transitive = true;
    }
```

<p>この辺を設定してあげればそれぞれのフレームワークが使えるようになると思います。</p>
<p>詳しいフレームワークについてのドキュメントは<a href="https://dev.twitter.com/twitter-kit/android">こちら</a></p>
</br></br>
</br>
</br>
</br>
<a href="http://blog.valeur3.com/">ブログもみてね☆</a>
facebook/flow 実践編

先に書いた[facebook/flowファーストインプレッション - Qiita](http://qiita.com/mizchi/items/d50fbdd8c2dcd01c38f9 "facebook/flowファーストインプレッション - Qiita")では自分でコード書いたりしなかったんだけど、今回はちゃんと手触り込みで。

## Hello World!

```
mkdir flow-playground
cd flow-playground
flow init
vim hello.flow.js
```

```js
/* @flow */

function foo(x) {
  return x * 10;
}

foo('Hello, world!')
```


```
flow check
```

型エラー起こしてみる


```
~/s/flow-playground $ flow check
/Users/mizchi/sandbox/flow-playground/hello.js:4:11,22: number
This type is incompatible with
  /Users/mizchi/sandbox/flow-playground/hello.js:3:37,42: string

Found 1 error
```

たぶんここじゃ伝わらないけど、出力がめっちゃカラフル


### Classes

```
/* @flow */

class A {
  a: number;
  constructor(public prop: number){
  }
}

new A(3);
```

TypeScriptにあるコンストラクタ初期化はない。

```
/Users/mizchi/sandbox/flow-playground/classes.js:5:15,20: Use of future reserved word in strict mode
```


というわけでこれは通る

```
/* @flow */

class A {
  a: number;
  constructor(prop: number){
    this.a = prop;
  }
}

new A(3);
```


### Union and Type Alises


```
/* @flow */

class A {
  a: number;
  constructor(prop: number){
    this.a = prop;
  }
}

class B {
  b: number;
  constructor(prop: number){
    this.b = prop;
  }
}

type T = A | B | string;

var x: T = new A(3);

```

まあ動く。
 
### lambda function

試してたら次のエラーが出た

```
/* @flow */
var _: any = require('lodash');
var arr: number[] =  _.map([1,2,3], (n: number) => n * n);
console.log(_.map([1,2,3], (n) => n * n));
```

```
/Users/mizchi/sandbox/flow-playground/requiring.js:4:39,39: Unexpected token :
```

(n: number) => {}
この構文はまだサポートしてないのかな？

### require 


sub.js

```js
/* @flow */

module.exports = function(n: number): number{
  return n * n;
}
```

main.js

```js
/* @flow */

var sub = require('./sub');
sub('hoge');
```

```
~/s/flow-playground $ flow check

/Users/mizchi/sandbox/flow-playground/main.js:4:5,10: string
This type is incompatible with
  /Users/mizchi/sandbox/flow-playground/sub.js:3:30,35: number

```


ちゃんとrequire先の型をみてくれてる！




### コンパイル


react-toolsつかえとのこと

```
npm install -g react-tools
```

どうでもいいんだけど react-toolsでjsxコマンド入るのなんでや

```
~/s/flow-playground $ jsx --strip-types --harmony classes.js 
built Module("classes")
/* @flow */


            
  function A(prop)        {"use strict";
    this.a = prop;
  }



            
  function B(prop)        {"use strict";
    this.b = prop;
  }


                        


var x    = new A(3);
```

たしかに！！！！！


### hoge.flow.jsをnode環境でrequireできるようにする

nodeでrequireするとき、拡張子がhoge.flow.jsだったら上の変形を書けて読み込むようにする。

でっち上げるためにさっくりcoffeeで書いた。

```coffeescript
fs = require 'fs'
reactTools = require('react-tools')
require.extensions['.flow.js'] = (module, filename) ->
  code = fs.readFileSync(filename).toString()
  transformed = reactTools.transform(code, {harmony: true, stripTypes: true})
  module._compile(transformed)

require './hello.flow.js'
```

これでflow checkしつつnode環境で動かすことが出来そう。
あとで読み込み部分はnpm packageにしておく。
redisの型別 Max size

アプリケーションの設計する上で必要になったので、redisに収容可能なサイズを調べました。

とりあえず膨大なデータを蓄積しないのであれば限界を考えなくても良さそう。

ソース http://redis.io/topics/data-types

## Strings
Stringsの最大容量は512MB

> A String value can be at max 512 Megabytes in length.

## Lists
一つのリストの要素数は最大約40億個

> The max length of a list is 2^32 - 1 elements (4294967295, more than 4 billion of elements per list).

## Sets
Setsの最大メンバー数は約40億個

> The max number of members in a set is 2^32 - 1 (4294967295, more than 4 billion of members per set).

## Hashes
Hashesはkey-valueのペアが最大約40億個

> Every hash can store up to (2^32) - 1 field-value pairs (more than 4 billion).

## Sorted sets

 Sorted setsの最大メンバー数は約40億個

http://www.tutorialspoint.com/redis/redis_sorted_sets.htm

> Maximum length of a list is 2^32 - 1 elements (4294967295, more than 4 billion of elements per set).
AndroidのServiceからアラートダイアログを表示する方法

#問題
Serviceにアラートダイアログの記述をしたところアラートダイアログが表示されませんでした。

```java:MyService.java
@Override
public int onStartCommand(final Intent intent, int flags, int startId) {
    //Context (this)がServiceなのでActivityじゃなきゃ表示されない
    AlertDialog.Builder alertBuilder = new AlertDialog.Builder(this);
    alertBuilder.setTitle("title");
    alertBuilder.setMessage("message");
    alertBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
        }
    });
    alertBuilder.create().show();
}
```
ServiceのContextをビルダークラスのコンストラクタの引数に渡しても表示されないようです。

#解決方法

アラートダイアログ表示用のActivityを作成する。

```java:CallDialogActivity.java
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        String message = getIntent().getStringExtra(MESSAGE);
        setContentView(R.layout.activity_call_dialog);
        AlertDialog.Builder alertBuilder = new AlertDialog.Builder(this);
        alertBuilder.setTitle("title");
        alertBuilder.setMessage("message");
        alertBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                CallDialogActivity.this.finish();//選択をしたら自信のActivityを終了させる
            }
        });
        alertBuilder.create().show();
    }
```

AndroidManifestにthemeとlanchModeの記述を追加
themeはTranslucentにすることでActivityを透明にし、NoTitleBarでタイトルバーを消します。
lanchModeはsingleInstanceにすることでこのActivityがTaskに一つしか存在しなくなります

```xml:AndroidManifest.xml
        <activity
            android:name=".CallDialogActivity"
            android:label="@string/title_activity_call_dialog"
            android:theme="@android:style/Theme.Translucent.NoTitleBar"
            android:launchMode="singleInstance">
        </activity>
```

Serviceからアラートダイアログ用のActivityを起動する

```java:MyService.java
@Override
public int onStartCommand(final Intent intent, int flags, int startId) {
    Intent intent = new Intent(this, CallDialogActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);//新規起動の記述
    startActivity(intent);
}
```
以上でServiceからアラートダイアログを表示する事が出来る。

もしかすると表示したいActivityのContextをServiceに渡してあげれば起動できるのかな？（試してません）
svnブランチの内容をtrunkにマージ


参考: http://cockatiel-cage.hateblo.jp/entry/2012/12/14/122449


ブランチで以下を実行し、起点となるリビジョンを確認

```
$ svn log --stop-on-copy
```

trunk に切り替え

```
$ svn switch svn://host/trunk
```

merge（試行）

```
$ svn merge --dry-run -r xxx:HEAD svn://host/branches/branch_a 
```

merge（本番）

```
$ svn merge -r xxx:HEAD svn://host/branches/branch_a 
```

コミット

```
$ svn commit
```
SOOMLA unity3d-store をソースコードからビルドする


※とりあえあえずiOS向け

git clone する（--recursive重要!!）

```
$ git clone --recursive https://github.com/soomla/unity3d-store.git
```

unity3-store/submodules/soomla-unity3d-core/submodules/soomla-ios-core をビルド

```
$ cd unity3-store/submodules/soomla-unity3d-core/submodules/soomla-ios-core
$ ./build_all
```

unity3-store/submodulessoomla-unity3d-core/soomla-native/projects/unity-soomla-ios-core をビルド

```
$ cd unity3-store/submodulessoomla-unity3d-core/soomla-native/projects/unity-soomla-ios-core
$ ./build_all
```

unity3d-store/submodules/ios-store をビルド

```
$ cd unity3d-store/submodules/ios-store
$ ./build_all
```

unity3d-store/soomla-native/projects/unity-ios-store をビルド

```
$ cd unity3d-store_new/soomla-native/projects/unity-ios-store
$ ./build_all
```

Unity パッケージ作成

```
$ ./create_deploys
```
WatchKit Catalog(サンプルコード)を起動する方法


AppleからWatchKitが発表されました。
![watch_apps_2x.png](https://qiita-image-store.s3.amazonaws.com/0/32832/019d95bb-f761-c369-3503-be31227b8fd3.png "watch_apps_2x.png")



AppleからWatch Kitのプログラミングガイドも公開されています。
[WatchKit Programming Guide](https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/WatchKitProgrammingGuide/index.html#//apple_ref/doc/uid/TP40014969-CH8-SW1)

WatchKitを使うには、Xcode6.2 betaが必要です。
[iOS Dev Center](https://developer.apple.com/devcenter/ios/index.action)

AppleからSample Code[WatchKit Catalog: Using WatchKit Interface Elements](https://developer.apple.com/library/prerelease/ios/samplecode/WKInterfaceCatalog/Introduction/Intro.html#//apple_ref/doc/uid/TP40015046)が公開されているのでダウンロードします。

ダウンロードしたら、Xcode6.2 betaでプロジェクトファイルを起動します。
サンプルプロジェクトには、複数のSchemeが設定されているので「WatchKit Catalog Watch App」を選択して、iPhone5以降のシミュレーターで起動します。

シミュレーターが起動したら、iOS Simulator > Hardware > External Displays > Apple Watchを選択します。
選択すると、Apple Watchのシミュレーターが起動して、UI Catalogを見ることができます。
Macでtmuxを使ってコンソールを共有する

件名の通りです。

割とありふれた内容だけど、いざやろうとした時にググってもLinuxでの内容が多く引っかかって、即座に試せないことが多かったので、備忘を一番の目的に書いておこうと思った次第です。

## 手順

大まかに言って、こんな手順になります。

1. tmuxをインストールする
2. Macのユーザーに適当なのを追加する
3. tmuxを共有用に立ち上げてセッションを作る
4. 誰かに頼んで自分のマシンにログインしてもらう
5. その誰かにセッションにアタッチしてもらう
6. vimを立ち上げてリモートでペアプロの真似事をする
7. \.vimrcの設定についてdisりあって仲が険悪化する

このうち、6と7については任意です。今回の説明からは割愛します。

ここでやろうとしていることは、何も難しいことはなくて大雑把に言うと、以下です

1. tmuxでローカルに共有用のセッションを作る
2. 外から、このマシンに共有用のユーザーにログインしてもらう
3. そのユーザーに、このマシンの中で共有用セッションにアタッチしてもらう

ということです。

## tmuxのインストール

Homebrewで良いです。

```zsh
brew install tmux
```

例によって、tmuxも設定ファイル類でゴニョゴニョ出来るのですが今回の目的からは外れるので割愛します。Qiitaでも設定を変更するための[記事](http://qiita.com/succi0303/items/cb396704493476373edf)とか有るので、そちらをご覧ください。またtmuxでの独特の操作などは[チートシート](https://gist.github.com/takuya71/2184557)とかを見てみると、tmuxってこういうのも出来るんだー等と思ったりするでしょう。

## Macでユーザーを作る

「システム環境設定 => ユーザー」から普通にユーザーを作ります。ここでは「一旦これで良いや」というノリの「セキュリティ意識ゼロ思考停止ユーザー」として、ID:tmux, password: tmuxとかで作ってしまいましょう。あとでユーザーを消すなりパスワードを変更するなりしてください。

それから、環境設定に来たついでに念のため「共有」の項目を見ておきましょう。リモートログインの項目にチェックが入っていることを確認してください。これが入っていないとログインしてもらえません。

## tmuxを共有用に立ち上げて共有セッションを作る

コマンド一発です

```zsh
tmux -S /tmp/kyouyu_session_no_namae_daze
chmod 777 /tmp/kyouyu_session_no_namae_daze
```

/tmp/kyouyu_session_no_namae_daze は、このバカっぽい名前を見て分かるように、この名前じゃないとダメということではありません。分かり易い名前を付けてあげましょう。リモートユーザーは、この名前のファイルにアタッチすることでセッションを共有することになります。二行目のchmod は、ユーザー"tmux"にも読み書きさせたいために行っています。大雑把でバカっぽいパーミッションですが、ここでは深く考えないようにしましょう。

## 誰かに頼んで自分のマシンにログインしてもらう

別の人とやった方が盛り上がるのですが、誰も頼む相手が居ない場合は仕方ないので、ひとりsshしましょう。tmuxを立ち上げたターミナルとは別のターミナルを立ち上げてログインしましょう。

```zsh
ssh -2 tmux@localhost
```

パスワードを聞かれたら、パスワードを入力してログインを完了してください。

## その誰かにセッションにアタッチしてもらう

では、繋いでくれている誰か、もしくは自分で立ち上げた、ひとりsshのターミナルで以下のコマンドを打ちます。

```zsh
tmux -S /tmp/kyouyu_session_no_namae_daze attach
```

これで、ターミナルの共有が出来たと思います。クリティカルなオペレーションをする時等は、これでターミナルを共有してSkypeなどで喋りつつ、コマンドを入力したら実行する前にお互いに確認して時には問い詰めたりしながら楽しく作業出来そうですね。こんなに簡単に出来るのに意外と「ハードル高そうだな」と二の足を踏んでいた君も、サクっと試して楽しいtmuxライフを!
IntelliJIDEAでplay-twenty-threeを追加した時に固まって動かなくなる時の対処法

`libraryDependencies += "com.github.xuwei-k" %% "play-twenty-three" % "0.1.0"`するとIntellijIDEAが固まって動かなくなります。
以下解決策
`~/Library/Preferences/IntelliJIdea14/idea.vmoptions`に

```
-Xmx7500m
-XX:MaxPermSize=2500m
```
を追加します。

これを追加してもしばらく固まって動きませんが、OOMが発生せず何とかなります。
-Xmxとかは各自調整してください。

追記
xuwei-kさんがjarが大きすぎて辛い時に、jarを小さくするものを作ってくださいました。仕事が早過ぎる。
play-twenty-three は、sbt pluginやwebインターフェイス http://scalajb.appspot.com/23?numbers=23 も作ったので、jarが大きすぎて辛い場合はこちらを http://d.hatena.ne.jp/xuwei/20141101/1414853154
RICOH THETA　デベロッパー登録とSDKのダウンロード

RICOH THETAのDevelopersへの登録方法と
SDKのダウンロード方法について紹介していきます。

・Developers登録
https://developers.theta360.com/ja/

開発者登録して開発を始めるをクリックします。![開発者登録.png](https://qiita-image-store.s3.amazonaws.com/0/58763/a9aeb98d-1a6d-7e0b-4169-5d572e816a8e.png)


利用規約を読み、チェックボックスにチェックを入れ、
FacebookもしくはTwitterでログインします。
![利用規約に合意.png](https://qiita-image-store.s3.amazonaws.com/0/58763/4871afd7-1fd4-126a-fe5b-20d8bb8b7d33.png)


開発者登録の画面に移動します。
登録される名前とユーザ名が表示されるので、登録のボタンを押します。
![開発者登録2.png](https://qiita-image-store.s3.amazonaws.com/0/58763/e4cd41d0-2f4a-3671-05b5-9b0be52fe1ad.png)

登録された全天球イメージの一覧表示に関してはON、OFFどちらでも大丈夫です。



・SDKのダウンロード方法

API＆SDKをクリックします。
![メインページ.png](https://qiita-image-store.s3.amazonaws.com/0/58763/b62c88b3-0082-e400-cc9a-5b382b84fbde.png)


SDKをクリックし、右側にあるダウンロードをクリック。
![API＆SDK.png](https://qiita-image-store.s3.amazonaws.com/0/58763/157c0365-6036-eb7e-7cff-c066566ffb57.png)
![ダウンロード.png](https://qiita-image-store.s3.amazonaws.com/0/58763/4680b1ca-7eef-895e-2059-6b8ea6b22fd2.png)


ソフトウェア使用承諾契約条件に合意するを押すと、
iOS、Androidのダウンロードボタンが表示されます。
任意の方をクリックするとダウンロードが開始されます。

以上。
PC と共有するために SD に作った FAT32のパーティションを Raspberry Pi で chmod できない時の対処


#はじめに
恥ずかしながら少しハマってしまったので自分への備忘録としてこのメモを残させていただきます。もしもどなたかの参考になることがありましたら望外に存じます。
以下を参考にさせていただいております
[chmod - not working?](http://www.raspberrypi.org/forums/viewtopic.php?f=91&t=40402)
[Adding a FAT32 partition to Raspbian on a Rasperry Pi](http://www.cenolan.com/2013/03/adding-a-fat32-partition-to-raspbian-on-a-rasperry-pi/)

#結論
FAT32 は chmod できないので、mount 時に必要な権限を umask で与えておく

#はじめに
Raspberry Pi とカメラモジュールを使って動画を撮影して SD カードに保存する Web アプリを作っていて、後から PC でも読めるように FAT32 の領域を用意。そこに Raspivid で movie を出力する shellは正常に動作するのだけれども nginx から起動する PHP からだと何も書いてくれない。例によって nginx が pi アカウントでないこと（これがいろいろなトラブルを起こすので、pi アカウントにしておけばよかったと...）が原因かと思い、FAT32 がマウントされている /media フォルダを見ると案の定

```bash:
pi@raspberrypi /media $ ls -la
total 16
drwxrwxrwx  3 root root 4096 Nov 19 10:04 .
drwxr-xr-x 24 root root 4096 Oct 17 20:26 ..
drwx------  7 pi   pi   8192 Jan  1  1970 MEDIA
```

そこで chmod a+w /MEDIA とするのだけど権限は変わらない。sudo を付けても変わらない。コマンドはエラーになるわけでもないのだが、黙って無視されているのかとにかく変わらなく、これは不思議だなぁと原因がわからずググってみて、前述の参考blog を見つけ...

#原因
FAT32はユーザーとか権限とかそういうものが最初からない（Read Only ぐらいしかないですね）ので、chmod と言われても逆に困りますよね ^^;;;

#対策
automount に任せるのではなく、/etc/fstab で umask を明記してマウントさせるよう一行追加します

```bash:
/dev/mmcblk0p3  /media/MEDIA    vfat    auto,rw,user,users,exec,noatime,uid=1000,gid=1000,umask=000    0    0
```
ここで第一列の /dev/mmcblk0p3 が私の SD での FAT32 の領域です。第二列の/media/MEDIA が私の環境でのマウントポイント、大参列のtype は vfat、第四列のポイントは umask=000 で、これで以下のようにだれでも使える権限になります。

```bash:
pi@raspberrypi ~ $ ls -la /media    
total 16
drwxrwxrwx  3 root root 4096 Nov 19 10:56 .
drwxr-xr-x 24 root root 4096 Oct 17 20:26 ..
drwxrwxrwx  7 pi   pi   8192 Jan  1  1970 MEDIA
```
umask は chmod とは逆で [1 が disabled ](http://en.wikipedia.org/wiki/Umask)なので混乱しますね

尚、SDカードの領域の情報は fdisk -l で確認します

```bash:fdisk
pi@raspberrypi ~ $ sudo fdisk -l

        Device Boot      Start         End      Blocks   Id  System
/dev/mmcblk0p1            8192      122879       57344    c  W95 FAT32 (LBA)
/dev/mmcblk0p2          122880    10362879     5120000   83  Linux
/dev/mmcblk0p3        10362880    30849023    10243072    b  W95 FAT32
```

#結論
わかってしまえば古典的な話だったのでむしろわからなかったのがお恥ずかしいぐらいなのですが...

#追記： それまで読み書きできていた FAT 領域が突然、read-only file system と言われるようになった時

[こちら](https://www.raspberrypi.org/forums/viewtopic.php?f=91&t=97614)が参考になりました、FAT 領域が壊れているようです。

```cat /var/log/messages | grep FAT```

とすると

``` FAT-fs (mmcblk0p1): Volume was not properly unmounted. Some day may be corrupt. Please fun fsck. ```

との事、そこで fsck するも、 fsck.vfat はない、との事なので FAT 用のツールのインストールから

```bash:
sudo apt-get update
sudo apt-get install dosfstools
```

私の場合、FAT を /media にマウントしているので、unmount して fsck して再度 mount

```bash:
sudo umount /boot
sudo fsck -a /boot
sudo mount /boot
```

これで、また正常に書き込めるようになりました
(2015.05.18)
Lolipopアップデートが降りてこないNexusを自力アップデートする

【追記　2015/03/12】
　　Nexus5用にAndroid5.1のアップデートファイルが来ました。
　　http://androidlover.net/android-os/android-5-1-lollipop/nexus5-android-5-1-ota-update-file.html

----

Nexusシリーズにも13日からAndroid5.0(Lolipop)のアップデートが開始されましたが、自分のところになかなか降りてこないので自力でアップデートしてみました。

通常のワイヤレスによるアップデートと同じように、ルート化(アンロック)不要、アプリ・データを引き継いだままアップデート出来ます。
__※但しアップデートは自己責任でお願いします。__

## 1.アップデート用のファイルをダウンロード
http://androidlover.net/android-os/android-5-0-lollipop/nexus5-nexus7-2013-nexus10-android-5-0-lollipop-ota-update-zip.html
Androidの設定からモデル番号を確かめつつ、端末のアップデート用のファイルを落としてきます

## 2.リカバリーモードで起動
端末をPCにつないで
```adb reboot recovery```
でリカバリーモードで再起動します。
倒れたAndroidのアイコンと「コマンドが指定されていません。」という文字が出たら次へ進みます。
PCはつないだままです。

## 3.差分アップデートを適用する
1. apply update from ADB に入る
    * 電源キー+ボリューム上を何回か押すとメニューが出てきます。
    * 何回か押して「apply update from ADB」を選択します
    * 電源ボタンで決定します
    * ```Now send the package you want to apply to the device with "adb sideload <filename>"``` が出たら次へ進みます。
2. adb sideloadでアップデートファイルを送る
    * ```adb sideload "さっきダウンロードしたファイル"``` を実行します
    * ファイルが転送され、状態チェックなどの後にアップデートが始まります。
    * このまま10分ぐらい待てばOSのアップデートが完了します。

## 4.再起動

* ```reboot system now```を選択してリカバリーモードから抜けます。
* Lolipopが起動して、アプリの最適化が始まります(おそらくARTへの変換)

無事最適化が終わればアップデート完了です。
お疲れ様でした。
メールが届いたタイミングでごにょごにょする場合のメモ

node.jsベースで空メールなんかの処理をしたい場合の候補

## [Mailin](http://mailin.io/)を使う
* node.js製のSMTPサーバ
* カスタムで処理を埋め込んだり、webhookを使ってメールが届いた瞬間に何かしらのURLに向けてメールのパース結果をJSONでPOSTしてくれるなどしてくれる
* node.jsのプログラムでルーティングやデータベースへの保存などもできるのはnode.js使いにはメリットといえばメリット
* Wellknownの25番ポートで起動させるにはroot権限が必要
* 他のアプリ(PHPとかRails)などでメールを使う場合のことを考えると、こいつ専用にドーンと1台構えないといけないのは負担かも

## MDAを立てて.forwardや.procmailなどに仕込む
* 個人的には[maildrop](http://www.courier-mta.org/maildrop/)でやってます
* 転送などもMDA任せにできる
* node.jsに限らず使えるので同居アプリに迷惑をかけない

## 結論
Mailinが「わたし、気になります！」だけど、今の私のようにそこまで富豪的にリソースが使えない環境だとMDAにnode.jsのプログラムを仕込ませてもらうのが一番いいのかなあ・・・という感じ
node.jsでいえば[Mailparser](https://github.com/andris9/mailparser)という便利モジュールがあるので、MDAから受け取ったメールのコンテンツをSTDIN経由でパースして、どこぞのサーバに投げる、というwebhook相当なことはできそうだし（一手間はかかるが）