OmniAICreator/Qiita-1.07M huggingface dataset:
Facebook Messenger Bot：ヤマレコAPIで山の情報を検索して返すBot を作成

LINEに続いて、FacebookでもBot作りたいなーと思って調べていたら、ヤマレコがAPIを提供していたので、利用して作成。
Facebookの審査に手間取ってなんだかんだ作ってから1か月くらいかかってしまった。

#概要
山の情報を調べて返すBot
https://www.facebook.com/letsgoclimbing/

Facebookページからアクセス。
ページは、Bot用に作成。

## 
![山の情報を調べて返すBot.png](https://qiita-image-store.s3.amazonaws.com/0/97877/caaa4461-e666-6ba5-3e56-6a749863a174.png)

・フリーワード検索。
・ヤマレコに登録されたエリア・ジャンルから検索。
・地名データの地点情報から、近隣情報検索。

# Facebook Messenger Platform
https://developers.facebook.com/docs/messenger-platform

Botを実現するためのPlatform。
FacebookページへのメッセージをWebhookして、
送信者に規定形式のメッセージをSendできる。

#ヤマレコAPI
ヤマレコ Web API
https://sites.google.com/site/apiforyamareco/

> ※2014年8月19日より、一部のAPIでOAuth認証が不要になり、より簡単に使えるようになりました！

と有り、認証不要でAPIを利用可能に。
地名データ等を取得できる。エリア内検索や、地点情報の近隣検索も。

#構成
Facebookアプリの管理画面から、テストアプリを作成できたので、
テストアプリに開発環境を紐づけ、本番環境と開発環境を分けてみた。

## 本番環境
Heroku(PHP Framework)
※FacebookからのHTTPSリクエストが利用可能

下記の方を参考に。（forkさせて貰った）
Heroku初めて使った。
> これからPHPでFacebook Messenger Botづくりを始める人向けの簡易スターターキット
>  http://qiita.com/tmtysk/items/4ebb25ed927b7dd96399

github からデプロイ。
> https://github.com/nilesflow/yamareco-fbmessengerbot

Configは、Facebook認証情報周り。
SettingsのConfig Variablesから設定。ローカルコンフィグを上書き。
composer で setupスクリプトを定義、デプロイ時に実行。

## 開発環境
AWS Cloudfront + 個人サーバ
※HTTPSオフロードしたい為

上記githubをcloneして配置。
Configは、ローカルファイル（config.json）をsetup。

テストOKなら、github に push。

## 共通
PHP。
Sympony、Silex、Monolog、GuzzleHttpも、fork元の構成を流用して。これらも全部初めて。
ログは、どちらもMonologで出力。

#Bot作成の流れ
Facebookページ作成、アプリ作成、WebHooks登録、ページトークン生成、Subscribe設定等は、
以下等のページを参考にしながら。
> Messengerで簡単なBotつくる(Facebook Messenger Platform from F8)
> http://qiita.com/pochi-sato/items/f3f5598e36c1fa92d840

#Facebookアプリ審査
時間かかったのが、審査。
アプリに対して pages_messaging というアイテムが割り当てられていないので、
アプリ画面で登録した人と作成したテストユーザ以外にメッセージを送信できない。
WebHookまではできる。

審査はテストユーザで、という事になっている（※それ以外も可？）が、
アイテムが無いと、テストユーザにも、メッセージを送信できない。
＃アプリ配下のテストユーザには送れてよいと思うんだけど、駄目なんだろうか。。
という事で、

・テストユーザでページを生成
・ページアクセストークンを取得
　＃更に、有効期限が短いので審査時間を考慮すると、伸ばすことが必要
・Botで利用するトークンを、一時的に上記トークンへ置き換え。
・ページ情報と共に、テストユーザで申請
　＃審査ページでは、正式ページしか選択できないので
といった手順で審査した。

参考にしたのは、以下のページ。
> Latest Response from Facebook
> https://developers.facebook.com/bugs/230322797329131/?hc_location=ufi

pages_messaging の審査は通ったが、この手順で本当に良いんだろうか。
また、Facebookアプリ的には一般的な方法なんだろうか。

テストユーザを指定するんだけど、
ID、パスワード等、全ての情報を教えてくださいとrejectされて、
でも入力欄が無いから、フリーテキストが利用できる、APIの利用手順の所に、
ID、パスワード、e-mail、テストページ等の情報を纏めて書いて送ったら通った。

#その他
## WebHooks Subscription の解除
Facebook MessengerのWebhooksで、
Callback URLが正常応答しないと、アラートが通知され、8時間以内に正常応答を返さないと、
サブスクリプションが解除される。
エラー処理は、極力エラーを捕捉して、
レスポンスで、きっちりステータスコード2XX系を返しておく必要がある。
https://developers.facebook.com/docs/messenger-platform/webhook-reference#webhook_setup

#ソースコード
https://github.com/nilesflow/yamareco-fbmessengerbot

#参考
文中のリンク他、実装にあたっては、以下も参考に。
> Facebook Messenger Platform BETAでできる全ての事を試してみた（LINE BOT APIとの比較あり）
> http://qiita.com/betchi/items/539f5e32cd9a9c8d2db4
cloud-initでCodeCommitからダウンロードする

# 目的
自動化を進めます。
ここではCodeCommitからgit で持って来る際、sshの秘密鍵を用いています。
どんな場所でも検証を続けたいため、このようにしましたが、
秘密鍵をスクリプト中に記載する事になるため、可能であればIPアドレスベースでのアクセスコントールがしたい。
が、まだできていないです
( conditionみたいな所に記述するんでしょうか http://docs.aws.amazon.com/codecommit/latest/userguide/access-permissions.html )

初期セットアップに必要な権限は readonlyですので( git pushは作業用PCから行うので )、
readonly用のアカウントを作成して使いましょう。

# ssh鍵を設定する

```bash:ssh鍵設定例
# ssh用のディレクトリがなければ作る
[[ ! -d /root/.ssh ]] && mkdir /root/.ssh && chmod 700 /root/.ssh

# 秘密鍵を設定 
# ## 事前にssh鍵を作成しておいて、CodeCommit側に登録しておく必要がある ##
if [[ ! -f /root/.ssh/codecommit_readonly.pem ]] ; then
  /bin/cat <<-'EOL' > /root/.ssh/codecommit_readonly.pem
-----BEGIN RSA PRIVATE KEY-----
( 中略 )
-----END RSA PRIVATE KEY-----
EOL
  chmod 600 /root/.ssh/codecommit_readonly.pem
fi

# /root/.ssh/config に git-codecommit用の設定が無かったら追加する
if grep git-codecommit /root/.ssh/config ;then
  :
else
  /bin/cat <<-'EOL' >> /root/.ssh/config
# AWS CodeCommit
# IAM codecommit user
Host git-codecommit.*.amazonaws.com
  User APK*************
  IdentityFile ~/.ssh/codecommit_readonly.pem
EOL
  chmod 600 /root/.ssh/config

# CodeCommitのfingerprintを書き込んでおきます
/bin/cat <<-'EOL' > /root/.ssh/known_hosts
|1|e8DGH1l0mJwyha9fnGNfk9C1GCc=|UsjXS4kK7hIW+dWsQMDYFS/zBPA= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCdut7aOM5Zh16OJ+GOP75O7x5oyHKAiA1ieuySetj/hAq4VrAuZV5R2TypZJcKBaripOtTc/Sr0FOU4YvxUla40PPH8N1lbDp6Pnc4BexKsrt2kz++TqIKx5FHmUQV3mit16kxRwHey3dv030+qXBDo3WPQjm2+JLoq0XcadpnCAMCd3ChaBnDRM+51GZbuEFilpZsxUchUzl0gseC+shYOBd7TqxTlIhj/56d/YF1kq7RMZYrwBnyYdVhpLeUJCeYjyx/O6FPSezNTLiinz5jjioWZATgn+G8feL/hIsk8g+7JoIcb2muUlymdxs+8l2lS+8MXqT0q9ohT+Knhb2j
|1|jfikaPCaQW7Q20IzNkX7jYIVHPc=|jtJtabQNm/0k7QAVueh/BPYTj+c= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCdut7aOM5Zh16OJ+GOP75O7x5oyHKAiA1ieuySetj/hAq4VrAuZV5R2TypZJcKBaripOtTc/Sr0FOU4YvxUla40PPH8N1lbDp6Pnc4BexKsrt2kz++TqIKx5FHmUQV3mit16kxRwHey3dv030+qXBDo3WPQjm2+JLoq0XcadpnCAMCd3ChaBnDRM+51GZbuEFilpZsxUchUzl0gseC+shYOBd7TqxTlIhj/56d/YF1kq7RMZYrwBnyYdVhpLeUJCeYjyx/O6FPSezNTLiinz5jjioWZATgn+G8feL/hIsk8g+7JoIcb2muUlymdxs+8l2lS+8MXqT0q9ohT+Knhb2j
EOL
fi
Amazon Machine Learningについて調べてみよう

これもリンク集です。

クラウド上の機械学習では、いろんな種類のものがあります。
・機械学習の結果を利用するだけのもの
・機械学習をクラウド上で実現できるもの
・指定された入出力形式だけのもの
・指定された入出力だけではなく、プログラム言語で多くの処理が記述可能なもの
そういった部分に何があって、どのくらいの負担で利用できるのか理解していきたいと思っています。



[Amazon Machine Learningのサンプルをちょっとチューニングしてみる](http://qiita.com/tominaga443/items/7c91ab873b2578445614)

[Amazon Machine Learningを理解するために3つの方法で天気予測をしてみた（二項分類編）](http://recipe.kc-cloud.jp/archives/7694)


[Amazon Machine Learning](http://www.slideshare.net/imaifactory/amazon-machine-learning-47400147)

[［チュートリアル］Amazon Machine Learningの使い方](http://itpro.nikkeibp.co.jp/atcl/column/15/091600220/091700007/)


[【AWS】Amazon Machine Learningチュートリアルやってみました](http://kiito.hatenablog.
com/entry/2015/09/23/172931)

[AWSの機械学習サービスAmazon Machine LearningをRedshiftと使ってみた](http://www.flydata.com/ja/blog/review-amazon-machine-learning-with-amazon-redshift-datasource/)


----

[Azure Machine Learning で深層学習(Deep Learning)](http://qiita.com/hiiyan0402/items/0c753bedc3c0407bfdbb)

[Microsoft Azure Machine LearningとDataSpiderの共同ハンズオンセミナー向け情報](http://qiita.com/appresso_mori/items/b1e32a56415978478304)

[Azure Machine Learning 分析アルゴリズムの選択](http://qiita.com/hiiyan0402/items/3e1584b25bfb6f453f52)

[Microsoft Azure IoT系サービスの使い分けメモ](http://qiita.com/hiiyan0402/items/9c93d9673114675a57d4)

[Azure Machine Learningをわかった気になるために細かいことは気にせずに機械学習のことをまとめてみる - ディープラーニング](http://qiita.com/shngt/items/431d7749a67573085aec)


interface 2016年7月号 第1部第7章「はじめてのクラウド型ラズパイ機械学習」Azure Machine Learningを使う例を紹介しています。


-----

[［速報］Google、クラウドで高速にディープラーニングを行う「Cloud Machine Learning」発表、TensorFlowベース。GCP Next 2016](http://www.publickey1.jp/blog/16/googlecloud_machine_learningtensorflowgcp_next_2016.html)

[CLOUD MACHINE LEARNING サービス 高速ですぐに使える機械学習サービス](https://cloud.google.com/products/machine-learning/)

[Googleが自社で使っている「クラウド機械学習」を一般に開放、こんなスゴイことが簡単にできる](http://gigazine.net/news/20160324-google-cloud-machine-learning/)

[Google、Cloud Machine LearningとTensorFlowのα版リリース](https://www.infoq.com/jp/news/2016/04/google-cloud-tensor-flow)

[機械学習システムが作れる」時代が到来しつつある](http://tjo.hatenablog.com/entry/2016/03/24/190000)
Mac の Excel で cvs 出力時に日本語がアンダーバーに成る場合

mac の Excel(Excel 2016) で CSV 出力した際、
日本語が全てアンダーバー（_）になってしまいました。

google先生に聞いてもよくわからなかったのですが、
これは mac の使用言語が English になっていることが原因のようです。

非日本語環境の方は、
System Preference-Language&Region から、日本語を最優先にしてください（macの再起動が必要です）。
Objective-C テキストから文字列を検索し色をつける

# 文章中の文字列を検索する手順
1. (NSRange)rangeOfString:(NSString *)searchString options:(NSStringCompareOptions)mask range:(NSRange)searchRange;を使いNSRangeを取得

2.NSRangeを配列に格納したい

3.NSRangeはオブジェクト型ではないのでNSValueでオブジェクト型に変換

```
-(NSArray*)searchWordWithRange:(NSString*)targetText word:(NSString*)
searchWord
{
    //! rangeオブジェクト(NSValue)の格納配列
    NSMutableArray* arrayRangeValue = [[NSMutableArray alloc] init];
    //! range初期化
    NSRange range = NSMakeRange(0, targetText.length);
    //! targetTextから検索 見つからなかったらwhile文を抜ける
    while ([targetText rangeOfString:searchWord options:NSLiteralSearch
                               range:range].location != NSNotFound) {
        //! 発見したrange
        NSRange rangeDetect = [targetText rangeOfString:searchWord
                                                options:NSLiteralSearch range:range];
        //! NSRangeをNSValueに変換
        [arrayRangeValue addObject:[NSValue valueWithRange:rangeDetect]];
        //! rangeのオフセット変更
        range = NSMakeRange(rangeDetect.location+rangeDetect.length,
                            targetText.length - (rangeDetect.location+rangeDetect.length));
    }
    return arrayRangeValue;
}
```
#NSRange(NSValue)を格納した配列とテキスト本文を引数にして色をつける関数
```
-(NSAttributedString*)highlightStringByRanges:(NSString*)targetText
                                       ranges:(NSArray*)arrayRange
{
    NSMutableAttributedString* stringAttributed = [[
                                                    NSMutableAttributedString alloc] initWithString:targetText
                                                   
                                                   attributes:nil];
    for (NSValue* rangeObject in arrayRange) {
        NSRange range = [rangeObject rangeValue];
        [stringAttributed addAttribute:NSBackgroundColorAttributeName 
                                 value:[UIColor cyanColor] range:range];
    }
    return stringAttributed;
}
```

#ViewDidLoadで上記二つのメソッドを呼び出す
```
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    NSBundle* bundle = [NSBundle mainBundle];
    //! 青空文庫の「こころ」を取得
    NSString* stringPath = [bundle pathForResource:@"kokoro" ofType:@"txt"];
    NSString* stringText = [NSString stringWithContentsOfFile:stringPath encoding:NSShiftJISStringEncoding error:nil];
    //! "私"を検索
    NSArray* arrayRange = [self searchWordWithRange:stringText word:@"私"];
    //! UITextViewのattributedTextに設定すること
    _textview.attributedText = [self highlightStringByRanges:stringText ranges:arrayRange];
    
}
```
#夏目漱石の「こころ」から"私"を検索した結果

<img width="487" alt="スクリーンショット 2016-06-19 22.04.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/58032/6164c4a0-80d1-3db2-f16d-971fbf7f9729.png">
Drupal8 入門の入門（フォーム）

## **TIPS**

### **TIPS.** コンテンツの編集フォームを管理者以外でも管理者のテーマで仕使用したい

- 【ユーザー＞役割】執筆用の任意の役割(Role)を作成する

/admin/people/roles

- 【環境設定＞テキストフォーマットとエディター】作成した権限に対して編集可能なフォーマットを適用する

/admin/config/content/formats

- 【テーマ】「コンテンツの作成・編集時に管理テーマを利用する」にチェックを入れる

/admin/appearance


![screenshot.1466256111.png](https://qiita-image-store.s3.amazonaws.com/0/35665/9dd5bc26-4f77-5665-e04a-d6805b7817a3.png)

- 【ユーザー＞権限】作成したRoleに対して「管理用テーマの閲覧」を有効にする
/admin/people/permissions

![screenshot.1466256058.png](https://qiita-image-store.s3.amazonaws.com/0/35665/a13fa23e-ded6-f26c-6f34-eba6b00d8bd5.png)
Drupal8 入門の入門（カスタムフィールド）

## **カスタムフィールド TIPS**

### TIPS.コンテンツに関連する記事を設定し、記事ページで表示できるようにする

- カスタムフィールドを追加
    参照するアイテムのタイプ：コンテンツ
    値の許容範囲：任意

- フォームディスプレイの管理
/admin/structure/types/manage/article/form-display
    作成したフィールドに対し「自動補完」を選択する

- 表示管理（Default）
/admin/structure/types/manage/article/display
    - フォーマット：描画されたエンティティ
    - ビューモード」ティーザー(例)

- 表示管理（ティーザー）
/admin/structure/types/manage/article/display/teaser
表示内容を編集する

- 作成したフィールドの作成したビュー・モードに対するテンプレートを作成する

```
    例：記事(article)内のfield-recommend-articleフィールド内で描画される記事(ビュー・モード＝ティーザー)
    templates/content/node--article.html.twig
        templates/field/field--node--field-recommend-article.html.twig
            templates/content/node--article--teaser.html.twig
```

> 記事編集時にIDで参照したい！

- IDで参照可能なエンティティ参照Viewを作成する

![screenshot.1466255809.png](https://qiita-image-store.s3.amazonaws.com/0/35665/76c24a6d-eb51-78ef-37e6-3f7c63942387.png)


- フォーマットの「設定」で検索フィールド「コンテンツ：ID」にチェックを入れる

![screenshot.1466255579.png](https://qiita-image-store.s3.amazonaws.com/0/35665/f4f9ab4a-8d3f-8194-38b0-c2476e26385d.png)

- フィールドの編集
参照方法に作成したエンティティ参照Viewを設定する

![screenshot.1466255469.png](https://qiita-image-store.s3.amazonaws.com/0/35665/85bd3fc0-f618-c32c-f6d8-a98f3c0c957c.png)
EC2インスタンスのタグ情報を読み込んで振る舞いを変える

# 目的
インスタンスの起動時、cloud-initで設定したスクリプトの中で
インスタンス自身のタグを読み取り、インスタンス自身が自分の役割を読み取り、振舞いを変える処理を行ってみます。

AWSで検証しましたが、『インスタンス自身が自分のメタデータを取得できる』
というクラウドベンダで『メタデータにRoleを設定する、という運用』
なら流用可能かもしれません( というより、個人的にはクラウドベンダに依存しない運用ができないか探してました )

このスクリプトは『ROLES変数にあるレシピ(role)を実行する』というだけなので、
例えばNIFTY cloudで先に export ROLES="hoge" してから、このセットアップ用スクリプトを流す、という方法にも使えます。

# アイデア元
https://gist.github.com/na0AaooQ/440761480838103a5136
http://need4answer.blogspot.jp/2014/03/blog-post.html

# メタデータ取得用URLに到達可能か確認してタグ取得

```bash:EC2インスタンスのRolesというタグの値を取得
if [ "x" = "x${ROLES}" ] && curl -s -m 1 http://169.254.169.254/ ; then
  # 環境変数 ROLESが空、かつ、AWSのAPIに到達可能であれば
  # タグ Nodesが設定されていないか確認する
  # インスタンス自身からのタグの取得の方法は、クラウドベンダによって異なると思われるが、
  # 現状、AWSのAPIに問い合わせを行っている。別クラウドベンダに対応する場合は別途処理を追加する必要がある
  REGION=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/.$//')
  INSTANCEID=$( curl -s http://169.254.169.254/latest/meta-data/instance-id)
  
  # インスタンス自身から自分のタグを取得するためにはインスタンスプロファイルを作成する必要があります
  ROLES=$(aws ec2 describe-instances --region=${REGION} --filters "Name=instance-id,Values=${INSTANCEID}" --query 'Reservations[].Instances[].Tags[?Key==`Roles`].Value' --output text)
fi
```
# Rolesを実行

```bash:cloneしてRolesを実行
cd /usr/local
git clone ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/chef-repo
cd chef-repo
# 環境変数 ROLES、ないしAWS EC2のNodesタグに何もなければ、 roles/base.json を使ってchefレシピを流す
chef-client -z -r "role[${ROLES:-base}]" -L /var/log/chef.log
```
cloud-initで初回起動時、スクリプトを流す

# 目的
EC2を普通に立ち上げ、ログインして手動でミドルウェアなりアプリケーションをインストール、
できあがったAMIを大切に使い回す、という運用方法もあるかと思いますが、
別のアプローチとしては『まっさらなOSからセットアップする時間、手間を極力減らす』というアプローチもあります。
セットアップが自動化されていれば、OSのバージョンアップの対応コストを減らせます。

インスタンスの初回起動時、--user-data オプションを用いると スクリプトを実行できます。
管理コンソールから Configure Instance Details の下の Advanced Details で設定できます。
( RHELのkickstartで %post 配下にコードを書いていくイメージに近いです )

# 使い方

```bash:例えばこんな--user-dataの使い方
 --user-data file://スクリプトのパス
```

# 立ち上げ例
```bash:インスタンス立ち上げ例
 $ AMIID="ami-f80e0596" TYPE="m4.large" KEY="tin-machine" SECURITYGROUPS_ID="" USER_DATA="../../cloud-init/chef-setup.bash"
 $ aws ec2 run-instances --associate-public-ip-address --count 1 --instance-type "${TYPE}" --image-id="${AMIID}" --key-name="${KEY}" --subnet-id="${SUBNETID}" --security-group-ids ${SECURITYGROUPS_ID} --user-data file://"${USERDATA}" | jq -r '.Instances[].InstanceId'
```

--user-data のオプションに渡すファイルで下記のことをしてみます。
( Amazon Linuxを想定しています )
* git, chef-clientインストール

# bashスクリプトのサンプル

```bash:chef-setup.bash
#!/bin/bash

# /root配下にログ出力
exec 2> /root/cloud-init-chef-client_install.$$.log

echo -e '\n\nネットワークに出れるか、curl -s -m 2 http://google.com で確認します'
# 自分のネットワークで確認した方が望ましいですが
while ! curl -s -m 2 http://google.com > /dev/null 2>&1
do
  echo -n '.'
  sleep 3
done
echo -e '\n\nネットワーク接続を確認'

# chefがインストールされていなければインストールする
[[ ! -d  /opt/chefdk ]] && echo -e '\n\nchefをインストールします' ; curl -L https://www.opscode.com/chef/install.sh | bash -s -- -P chefdk

# CodeCommit用gitインストール
yum -y install git
```
EC2にApacheでPython動かした時の覚書

Hello World!というhtmlを返す＋S3に何か書き出せることだけ確認したときの覚書。

# インストール

```
$ sudo yum install httpd
```

# 設定

/etc/httpd/conf/httpd.conf
を編集

 - Options に ExecCGIを追加
 - DirectoryIndex に index.pyを追加
 - AddHandler cgi-script に.pyを追加

# ソースコード

/var/www/html/
にindex.pyをつくってコード書く

```$ chmod 755 index.py```
して実行できるようにする。


boto3使うので入れる
```$ sudo pip install boto3```

## 書いたコード
（BucketNameは自分のバケット名に書き換え）

``` index.py
#!/usr/bin/python
# coding:utf-8

import boto3
import logging
import datetime
import cgi
import uuid

def main():

    now_s = datetime.datetime.now().strftime('%Y.%m.%d-%H:%M:%S')
    messge = "no-message"
    field = cgi.FieldStorage() # クエリパラメータにmessageがあれば使う
    if field.has_key('message'):
        message = field['message'].value

    # html
    print "Content-Type: text/html\n"
    print "Hello World!"

    # S3
    s3 = boto3.resource('s3')
    key = 'test-folder/{0}-{1}.txt'.format(now_s, uuid.uuid4())
    s3.meta.client.put_object(Bucket='BucketName', Key=key, Body=message)

    # log
    handler = logging.StreamHandler()
    handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
    logger = logging.getLogger()
    logger.addHandler(handler)
    logger.setLevel(logging.INFO)

    logger.error(message)
    logger.info(message)

if __name__ == "__main__":
    main()

```


# Apache Start

```$ service httpd start```


# 確認

httpリクエストして、以下が確認できればOK。

 - 応答が200で、Hello World!というhtmlが返る。
 - S3の指定したバケットのtest-folderに「日付＋日時＋uid.txt」みたいな名前のファイルができている。
 - ログ出力できている。

# その他

PostされたBodyを取得したいとき、それがフィールドとして壊れてたり生データだとcgi.FieldStorageから取れず、not indexableエラーでる。sys.stdin.read()ならとれた。

[How to parse the “request body” using python CGI?](http://stackoverflow.com/questions/3836828/how-to-parse-the-request-body-using-python-cgi)
s3のtokyo regionにつなげる

# amazon s3にファイルをpythonから保存してみる
## とっても安いので、そこにバックファイルを保存できるようにしてみようと思った。
#### doto3というモジュールで簡単にはいる

`# pip install doto3`

configなどを手で設定するが、endpoint errorになってします。
s3.tokyo.....がないとのえエラー。
```
botocore.exceptions.EndpointConnectionError: Could not connect to the endpoint URL: "https://s3.tokyo.amazonaws.com/"
```

よく調べてみると、configでregionを指定するときは、tokyoではだめとのこと。
`.aws/config`の中で、
`region=ap-northeast-1`

ユーザは、amazonのIamUserで設定して認証キーを`~/.aws/confidential`に設定しておく

以下、pythonコマンドラインからの実行（[公式のQuickstart](https://boto3.readthedocs.io/en/latest/guide/quickstart.html)参照）

#### 接続
`s3 = boto3.resource('s3')`

#### read the list
```
for bucket in s3.buckets.all():
    print(bucket.name)
```

#### Upload
```
data = open('test.jpg', 'rb')
s3.Bucket('my-bucket').put_object(Key='test.jpg', Body=data)
```
Autotools管理のライブラリをiOS向けにスマートにビルドする方法

UNIX系OSをターゲットにしたC/C++ベースのライブラリにはAutotoolsの生成した`configure`スクリプトが同梱されているのが普通です。`configure`スクリプトが環境ごとの差分を調査・吸収することで、同じソースコードで多くの環境に対応することができる仕組みになっています。

しかし、そうしたライブラリをXcodeプロジェクトに導入する場合、`configure`に頼らず`*.c`と`*.h`だけをプロジェクトにコピーして手動対応するような事例が存在するようです。iOS開発が長い方々はXcodeとAutotoolsを組み合わせて使う方がハマりそうだ、という直感が働くのかもしれません。

調べてみると、クロスコンパイル対応のビルドツールのパスがXcode付属の`xcrun`コマンドで取り出せるので、これを利用して`CC`や`CFLAGS`を設定すればXcodeプロジェクトでもAutotoolsの恩恵を受けられることがわかりました。たとえば、次のようにすればiOS向けの`*.a`がビルドできます（対象のライブラリ作者がクロスコンパイル対応を考えていない場合など、ビルドに失敗する可能性もあります）。

```
$ make distclean
$ SDKROOT="$(xcrun --sdk iphoneos --show-sdk-path)" \
  CC="$(xcrun --sdk iphoneos -f clang)" \
  CPP="$(xcrun --sdk iphoneos -f cc) -E -D __arm__=1"　\
  CFLAGS="-isysroot $(xcrun --sdk iphoneos --show-sdk-path) -arch armv7 -arch armv7s -arch arm64 -miphoneos-version-min=7.0" \
  RANLIB="$(xcrun --sdk iphoneos -f ranlib)" \
  LIBTOOL="$(xcrun --sdk iphoneos -f libtool)" \
  ./configure \
  --host=arm-apple-darwin \
  --prefix="$(pwd)/build" \
  --disable-shared
$ make
```

実際のプロジェクトに適用するような場合はもうすこし整理してシェルスクリプトなどにするのが良いでしょう。

シミュレータ用のスタティックライブラリも同様に作った上で`lipo`コマンドでユニバーサルライブラリにすれば、Xcodeプロジェクトに取り込むことができます。

## ワークアラウンド

基本的には`xcrun`経由で使えばiOS向けのクロスコンパイルができるはずなのですが、実はCプリプロセッサ`cpp`が単体ではマトモに動きません（`clang`でコンパイルする分には問題ありません）。

普段は`cpp`単体で起動することはほとんど無いと思いますが、`./configure`中では`cpp`のチェックが走るため、次のようなエラーが出たりします。

```
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.3.sdk/usr/include/assert.h:42:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.3.sdk/usr/include/sys/cdefs.h:707:2: error: Unsupported architecture
#error Unsupported architecture
 ^
1 error generated.
```

これは`cpp`のクロスコンパイル対応が中途半端になっていることが原因です。ARM用のヘッダを読み込むくせにマクロ定数`__x86_64__`が定義された状態なので、一部ヘッダの`#error`に引っかかってしまうのです。

これを回避するため、上の例では`cc -E`でマクロ定数`__arm__`を明示的に定義しています。

この問題にAppleの中の人が気づいていないとは思えないんですが、結構昔から修正されていないような気がします。

## 元ネタ

- https://gist.github.com/c0ming/10976661
- https://github.com/szanni/ios-autotools/blob/master/iconfigure
AWS Lambda のバージョン毎に別の Kinesis をセットする方法

# さいしょに

AWS Lambda のバージョンごとに紐付ける Kinesis Stream を切り替える方法について。

## やりたいこと

Kinesis Stream から取得したデータを Lambda で処理するようなシステムを想定。
以下の要件が、本投稿の内容で対応可能。

* Lambda にバージョンを作成したい
  * `Version $LATEST` を開発環境として使用
  * `Version 1, 2` などのバージョンを本番環境として使用
* Lambda の開発環境と本番環境で接続する Kinesis を別にしたい

# どうやるのか

## まずは Lambda のバージョンをつくる

`Actions > Publish new version` を選択して、バージョン詳細を入力して Publish。

![Lambda_Management_Console 2.png](https://qiita-image-store.s3.amazonaws.com/0/68136/b943771d-c614-5e03-83a0-69f52e29dcf9.png)

下記のように `Version 1` が作成される。同様の手順で `Version 2` 以降を作成することができる。

![Lambda_Management_Console 3.png](https://qiita-image-store.s3.amazonaws.com/0/68136/4fd1dd1d-7f00-2bd5-e999-b904e9908e3e.png)

あとは適宜 alias など設定しておくといいだろう。

## 各バージョン毎に Event source を設定する

`Version $LATEST` の `Event source > Add event source` から接続したい Kinesis を選択する。

![Lambda_Management_Console 4.png](https://qiita-image-store.s3.amazonaws.com/0/68136/1aff9228-bc56-3f48-6cc7-a34ce3056aa9.png)

続けて、 `Version 1` の `Event source > Add event source` から接続したい Kinesis を選択する。

![Lambda_Management_Console 5.png](https://qiita-image-store.s3.amazonaws.com/0/68136/e661a05b-b211-fc4a-ec42-3162679694c3.png)

これで Lambda の各バージョン毎に違う Kinesis を接続することができた。

# さいごに

## 全体設定に注意

`Create a Lambda function > Select blueprint`から Kinesis の blueprint から作成した場合など、対象 function 全体の Event source に Kinesis が紐付く場合がある。

この状態で各バージョンの Event source を設定しても、全体設定が優先されてしまうので注意。全体の方を削除すれば各バージョンの Event source が動作するようになる。

![Lambda_Management_Console.png](https://qiita-image-store.s3.amazonaws.com/0/68136/1dd2be21-d0b4-b3f3-ba9a-4798b1e95c36.png)

## alias 毎に Event source を設定する

同様に alias 毎に Kinesis を設定できる。（記事の主役にはしていないが）
バージョンごとだと Publish の度に付け替えが面倒なので、 alias 毎に設定をした方がいいだろう。
Google App EngineでComposerを使う

Google App Engine上のPHPアプリケーションでComposerを使う方法

前回の[Google App EngineでHello, World!(PHP)](http://qiita.com/rshibasa/items/6ea3eff7f210153772da)では、Google App EngineでPHPが動作するところまでを試しました。今回は、より複雑なアプリケーション作成の準備としてComposerでライブラリを使えるようにしてみたいと思います。

# 準備
今回はComposerでインストールしたライブラリがGoogle App Engineで動作する事を確認するのが目的なので、確認が簡単な[Faker](https://github.com/fzaninotto/Faker)を使うことにしました。Fakerは氏名や住所など個人情報のダミーデータを作成するためのライブラリです。

まずは、ソースコードを管理しておくのに適切なディレクトリに`composer.json` を用意します。

```
{
    "require": {
        "fzaninotto/faker": "1.6.*"
    }
}
```

composerでライブラリをインストールする
`composer install`

コマンド実行後、ディレクトリは以下のようになります

```
- composer.json
- composer.lock
- vendor/
   +- autoload.php
   +- composer/..
   +- fzaninotto/...
```

# index.htmlの作成
前回の[サンプル](http://qiita.com/rshibasa/items/6ea3eff7f210153772da)では`app.yaml`や`index.php`がすべて同じディレクトリに保存されていました。複雑なアプリケーションを作成していくのには少々心許無い気がします。今後はユーザーからアクセスされるファイル類は`website`ディレクトリに保存することにします。

今回の`index.php`は以下のように作りました。
Fakerの使い方は[公式のreadme.md](https://github.com/fzaninotto/Faker/blob/master/readme.md)を参照して下さい。

```
<html>
    <head>
        <meta charset="UTF-8">
    </head>
<body>

<?php
require '../vendor/autoload.php';

$faker = Faker\Factory::create('ja_JP');
for ($i=0; $i < 10; $i++) {
  echo $faker->name, '<br />', "\n";
}
```

# app.yamlの作成
前回のapp.yamlを元にしつつ、今回のapp.yamlは以下のようにしました。大きな違いは`skip_files`を指定していることです。skip_filesで指定したファイルは`App Engine`にアップロードされなくなります。
セキュリティ上の懸念になりうるファイル、アプリケーションの動作に無関係なファイルはアップロードしないように設定しておくといいでしょう。
handlersではwebsiteディレクトリ以下の`index.php`を参照するように指定してあります。

```
application: <YOUR_PROJECT_ID>
version: alpha-003
runtime: php55
api_version: 1
threadsafe: true

skip_files:
- ^(.*/)?app\.yaml
- ^README\..*
- ^(.*/)?composer\.(phar|lock|json)$
- \.gitignore
- ^\.git/.*
- ^(.*/)?(.*\.swp)

handlers:
- url: /.*
  script: website/index.php
```

# App Engineにデプロイ
準備が整ったので本番環境へデプロイを行います。
`appcfg.py update ./`

以下のURLで動作確認します。
`http://<YOUR_PROJECT_ID>.appspot.com/`

![スクリーンショット 2016-06-19 20.45.01.png](https://qiita-image-store.s3.amazonaws.com/0/129243/4eb56bfa-f102-bcbc-d93c-7835022f4dd2.png)

Fakeが生成したダミーの氏名が表示されることが確認できました。

# ポイント
Google App Engineだからという事で特筆することもなく、composerでインストールしたライブラリを利用することができましたが、あえてポイントを書くのであれば…

1. composerが生成したディレクトリも含めてアップロードする
2. PHPから`vendor/autoload.php`へのpathを通す

この２点です。今回の最終的なファイル構成は以下のようになっています。

```
- composer.json
- composer.lock
- vendor/
   +- autoload.php
   +- composer/..
   +- fzaninotto/...
- website/
   +- index.php
```

ここまで読んでいただき、ありがとうございました。
Compose.io@BluemixのPostgreSQLがめっちゃ進化してる

久々にPostgreSQLのサービスを覗きに行ったら、**サービスが充実してめっちゃ進化してた**、のお話。
**性能監視、モジュールでの拡張、操作性等々、びっくりするくらい（良い方向に）変わってました。**

クラウドサービスは知らない間にどんどんリニューアルというかバージョンアップしてるから、すごい。どんどん便利になっていくから、浦島太郎状態にならないように気をつけないと・・。

## そもそもComposeって何（復習）
PostgreSQLとかMongoとかOSSのDBを数分で簡単に環境構築できるクラウドサービス。
詳しくはこちら（過去記事）
[概要説明]
http://qiita.com/azzeten/items/29d27af282d9eb185f4a

[PostgreSQLで遊んだときの話]
たくさんあるので数絞りますが・・
http://qiita.com/azzeten/items/c1e72b3fe3cb9421e3ba
http://qiita.com/azzeten/items/a7a786701cf25ef1a087

[MongoDBで遊んだときの話]
http://qiita.com/azzeten/items/2e3901c080aafed078eb

## どの辺が進化？
### **[性能、監視面が充実]**
*・pg_stat_statements（性能とか見れる）が簡単に使える！*
![統計.png](https://qiita-image-store.s3.amazonaws.com/0/119378/58f600d2-4001-2adb-958e-e2edea6bf960.png)

前はこんなのなかった・・・(admin権限でCLI使えないし）でもこれなら性能とかも管理できるので良いかも。

*・ヒット率がひとめでぱっと分かる！*
![スクリーンショット 2016-06-18 16.35.50.png](https://qiita-image-store.s3.amazonaws.com/0/119378/f446b41a-552b-d388-2c2d-a6865a40090d.png)

DB詳しくな人でも、ここさえ見ればOK〜って感じっぽい。便利。

*・セッションの情報が取れる！*
![スクリーンショット 2016-06-18 16.36.04.png](https://qiita-image-store.s3.amazonaws.com/0/119378/66f5cbe9-a20a-407e-f74a-5f677fc9a698.png)

はんぐっちゃった時とか嬉しいかも。
キャプチャ切れてますけど、いまactiveなセッションとかも見れるみたいなので。kill all connectionとかっていうボタンもあるから、（あんまりしたくないけど）、一気に全部セッション終了ってこともこれで一発なんだなーきっと。


### **[操作性も向上してる]**
*・クエリをWEBブラウザから打てるようになった*
![スクリーンショット 2016-06-18 16.41.10.png](https://qiita-image-store.s3.amazonaws.com/0/119378/71916c75-72f3-2c99-d22e-5fe1254f8c0d.png)

テスト的に軽くやりたいなーってときは絶対便利。

### **[機能拡張のバリエーションが増えた]**
*・追加モジュールのインストールOK*
![スクリーンショット 2016-06-18 16.38.49.png](https://qiita-image-store.s3.amazonaws.com/0/119378/fca26044-b36e-6b2b-3d25-6aebdc3565aa.png)

ちょっと一気に増えすぎて謎なんですがｗ、おそらくpostgreSQLで追加で提供されるモジュール（以下URLご参照）が、この画面からクリックひとつでinstallできるっていう機能みたい。いっぱいありすぎる・・・。でもPostgreSQLを今まで使いこなしてきて、こういうモジュールもがんがん使ってますって人にはかなり嬉しいはず。
https://www.postgresql.jp/document/9.5/html/contrib.html
JUnitのアノテーション 使い方メモ

	@BeforeClass
テストクラス実行前に、一度実行する

	@AfterClass
テストクラス実行後に、一度実行する

	@Before
各テストケース実行前に、一度実行する

	@After
各テストケース実行後に、一度実行する

◆注意点
@BeforeClass、@AfterClassは、staticで宣言する
Processingで画像の輝度の数をCSVで書き出す


##筆者環境
|環境|バージョン|
|:--|:-------|
|MacOSX|10.11.5|
|Processing|3.1.1|

##プログラムの流れ
1. 画像をファイル名で指定する
2. 画像のピクセル毎の輝度を取得する
3. 輝度は0~255の範囲で整数値で表す
4. それぞれの輝度がどれくらいあるか数える
5. それぞれの輝度の数をCSVで書き出す

##コード
```Java:BrightnessCSV.pde
void setup() {
  createImageBrightnessCSV();
  exit();
}
 
void createImageBrightnessCSV() {
  PImage pimage = loadImage("sample.jpeg");
  int[] nums = new int[256];
 
  pimage.loadPixels();
 
  /* 輝度の数をそれぞれ数える */
  for (color c : pimage.pixels) {
    nums[int(brightness(c))]++;
  }
 
  /* 輝度の数の表示（確認用） */
  for (int i = 0; i &lt; nums.length; i++) {
    println("nums[" + i + "]:" + nums[i]);
  }
 
  /* 書き出し用のファイル作成 */
  PrintWriter output = createWriter("sample.csv");
 
  /* ファイルにデータを書き込み */
  for (int i = 0; i &lt; nums.length; i++) {
    output.println(i + ",\t" + nums[i]);
  }
 
  output.flush();
  output.close();
}
```

##参考
[b-05 ピクセルを操作する – Processing学習ノート](http://www.d-improvement.jp/learning/processing/2011-b/05.html)
Jetson TX1をVirtualBox上のUbuntu14.04からセットアップする

JetPack2.2を使って仮想マシン上のUbuntu14.04でJetson TX1をセットアップする方法をメモする。

__環境__
- MacBook Pro 15' Mid 2014
- OSX 10.11
- VirtualBox 5.0.22 r108108
- JetPack2.2

基本的にインストール画面の手順に従えばよいが、いくつかMac側で先に設定してあげなければならいことがある。
VirtualBoxにUbuntu14.04がインストール済みである前提で話をすすめる。

## Network Interfaceの割当

Network Layoutを2番目でセットアップすることにする場合、MacのEthernetポートをVirtualBoxに割り当てる必要がある。
この操作はVMをシャットダウンしていないとできないので注意。

まず、Thunderbolt ethernetアダプタをMacに接続する。
次に、VirtualBoxのVMの設定画面から`Network > Adapter2`に`Bridge Adapter`としてMacの設定する。（Adapter1はインターネット用）
Thunderboltポートの名前を確認とEthernetアダプタの指すポートを間違わないように気をつける。

![Screen Shot 2016-06-19 at 7.13.57 PM.png (71.6 kB)](https://img.esa.io/uploads/production/attachments/3607/2016/06/19/11246/058d0f9b-9db1-4387-a028-fdab49e9e342.png)

割り当てると`eth1`としてVM側で認識されるので、下の画像のようにインタフェースを割り当てる。
![Screen Shot 2016-06-19 at 7.11.03 PM.png (278.7 kB)](https://img.esa.io/uploads/production/attachments/3607/2016/06/19/11246/0bb2ca4c-8241-4bba-a1d4-9d7b4bb46823.png)
![Screen Shot 2016-06-19 at 7.15.04 PM.png (283.5 kB)](https://img.esa.io/uploads/production/attachments/3607/2016/06/19/11246/7ed8f421-7591-4020-b52c-c49c721ae761.png)

## USBポートの割当

TX1にイメージを書き込むときにUSBを介して行うので、VM側にUSBポートを認識させてあげる必要がある。
これもNetwork Interface同様、VMをシャットダウンしていないとできない作業なので注意。

Mac側でTX1を認識させる。
まず、電源アダプタを抜き、USB-microBをTX1へ接続する。
次に、MacとTX1をUSBで接続する。
そして、TX1の`POWER BTN`を押して電源を投入したあと、その左隣りの`S3`ボタンを２秒ほど長押しする。
最後にNVIDIA Corp.の文字がなかったら`RST`ボタンを押す。
LEDが2つ点灯したらMac側に認識されているはずなので、VirtualBoxのVMの設定画面から`Ports > USB`の`USBと+の絵`ボタンを押してポートを追加する。

![Screen Shot 2016-06-19 at 7.07.13 PM.png (80.0 kB)](https://img.esa.io/uploads/production/attachments/3607/2016/06/19/11246/75a04ff9-8255-4d41-a448-f6297f9d0490.png)

[ここ](https://www.virtualbox.org/wiki/Downloads)からVirtualBox 5.0.22 Oracle VM VirtualBox Extension Packをダウンロードし、VirtualBoxにインストールしておく。
インストールしておかないとVMでUSB2.0として割り当てができない。

## UbuntuにJetPackをダウンロード

あとは、JetPackを使ったインストール方法と同じである。
[ここ](https://developer.nvidia.com/embedded/downloads)から`JetPack for L4T`をダウンロードする。
ダウンロード後はコマンドラインから`chmod +x`で実行権限を付与し実行すれば良い。

## その他注意点
- ストレージのサイズはデフォルトの8GBでは足りない。
    - Dynamically allocatedで100GBくらい確保しておく。
Git 初期設定

参考サイト
http://qiita.com/wnoguchi/items/f7358a227dfe2640cce3
https://git-scm.com/book/ja/v1/Git-%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA-Git-%E3%81%AE%E8%A8%AD%E5%AE%9A
AWS CLIで’A client error (AuthFailure) occurred when calling the～'なら時刻ずれが怪しい 


１年ほど問題なく使えていたaws cli環境で突然エラーが発生。
必ず発生する訳ではなく、もう一度実行すると成功したりする。

```
$ aws ec2 create-image (以下略)
A client error (AuthFailure) occurred when calling the DescribeImages operation: AWS was not able to validate the provided access credentials
```

最初は認証関連を疑ったけどググッたら時刻ずれで発生するとのこと。
確認したらNTP間違って5分ほどずれていた。NTP修正することで復旧した。

ちなみにバージョンは

```
$ aws --version                                                                                  
aws-cli/1.8.13 Python/2.7.5 Linux/3.10.0-229.14.1.el7.x86_64
```
Elastic Beanstalkで作ったS3のバケットが削除出来なくなった時にやったこと

###i)画面の右にある「アクセス許可」の「バケットポリシーの追加」を押下する
![スクリーンショット 2016-06-19 19.02.46.png](https://qiita-image-store.s3.amazonaws.com/0/63777/334d63ed-fe8f-2531-ef63-335de26ab858.png)

###ii)EffectのDenyをAllowに変更する

```
{          
  "Sid": "????????????????????????????????",
  "Effect": "Deny", ← ここを"Allow"にする
  "Principal": {
    "AWS": "*"
  },
  "Action": "s3:DeleteBucket",
  "Resource": "arn:aws:s3:::<bucketname>"
}
```

###iii)バケットを削除する
Activity#finish() でアプリが終了できないときは

ハマったので覚書。

# TL;DR

Activity#finish() で最後のアクティビティを終了させても、アプリがタスク一覧に残ってしまう。APIレベル21からは [Activity#finishAndRemoveTask()](https://developer.android.com/reference/android/app/Activity.html#finishAndRemoveTask()) というメソッドがあるので、これを呼ぶ。

# 経緯

Android でアプリを終了させようと思って Activity#finish() を呼んだのですが、アクティビティは画面から消えるものの、タスクが消えない。つまり端末の □ ボタンを押すとタスク一覧に空の画面が出っぱなしになります。

んで、ググってみると [「Activity finish does not work」](https://www.google.co.jp/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=Activity+finish+does+not+work) とか [「android アクティビティ finish 終了しない」](https://www.google.co.jp/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=android+%E3%82%A2%E3%82%AF%E3%83%86%E3%82%A3%E3%83%93%E3%83%86%E3%82%A3+finish+%E7%B5%82%E4%BA%86%E3%81%97%E3%81%AA%E3%81%84)で、たくさんワークアラウンドが出て来るので思わず読みふける。むむ、なにプロセスが onDestroy 後も残るとな...。

# 結局
APIレベル21 からは [Activity#finishAndRemoveTask()](https://developer.android.com/reference/android/app/Activity.html#finishAndRemoveTask()) というメソッドがあるので、こいつを呼ぶのが正解なのでした。

検索結果に捕らわれて小１時間ハマりました...。
コマンドラインからSwiftを実行したらImportError: No module named six

コマンドラインからSwiftを実行してみようと思ったら、エラーメッセージが大量に出た

```
$ swift
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python/lldb/__init__.py", line 98, in <module>
    import six
ImportError: No module named six

Traceback (most recent call last):
  File "<string>", line 1, in <module>
NameError: name 'run_one_line' is not defined

　 ・
（省略）上記３行のエラーが繰り返し大量に表示
　　・
　　
Welcome to Apple Swift version 2.2 (swiftlang-703.0.18.8 clang-703.0.30). Type :help for assistance.
  1>  
```

`ImportError: No module named six`でググって、下記のようにしたらエラーメッセージが消えた。

```
$ easy_install six
```

おそらく、どこかでPythonのプログラムが使われていて
sixというPythonのモジュールが足りなかった模様。

参考
[python - ImportError: No module named six - Stack Overflow](http://stackoverflow.com/questions/13967428/importerror-no-module-named-six)
MavenやGradleでProcessingを依存関係に追加する

## <i class="fa fa-question-circle"></i> Processing とは

### <i class="fa fa-wikipedia-w"></i> [Wikipedia](https://ja.wikipedia.org/wiki/Processing)
> Processing（プロセシング）は、キャセイ・レアス（英語版）（Casey Reas）とベンジャミン・フライ（英語版）（Benjamin Fry）によるオープンソースプロジェクトであり、かつてはMITメディアラボで開発されていた。電子アートとビジュアルデザインのためのプログラミング言語であり、統合開発環境である。アーティストによるコンテンツ制作作業のために、詳細な設定を行う関数を排除している。 視覚的なフィードバックが即座に得られるため、初心者がプログラミングを学習するのに適しており、電子スケッチブックの基盤としても利用できる。Java を単純化し、グラフィック機能に特化した言語といえる。

この Processing は、独自のIDEを使った開発ができますが、1つのモジュールとしても使うことができます。
今回は、それを Maven や Gradle の依存関係に追加することで、
IntelliJ IDEA や Eclipse などの統合開発環境でバリバリとコーティングすることを目的とします。

## <i class="fa fa-check-circle-o"></i> Maven の依存関係に追加

`pom.xml` の `dependencies` に、以下を追加しましょう。

```XML
  <dependencies>
    <dependency>
      <groupId>org.processing</groupId>
      <artifactId>core</artifactId>
      <version>2.2.1</version>
    </dependency>
  </dependencies>
```

最後に、Maven プロジェクトを更新しましょう。

## <i class="fa fa-check-circle-o"></i> Gradle の依存関係に追加

`build.gradle` の `dependencies` に、以下を追加しましょう。

```groovy
dependencies {
	compile group: 'org.processing', name: 'core', version: '2.2.1'
}
```

最後に、Gradle プロジェクトを更新しましょう。

## <i class="fa fa-info-circle"></i> Processing リポジトリの確認方法

Processing の Maven リポジトリは、Maven Central リポジトリにあります。
ですので、ライセンスやバージョン等の確認は [こちら](https://mvnrepository.com/artifact/org.processing/core) から行うことができます。

### 　■ Processing のバージョン

　　各バージョンのリンクをクリックすることで、詳細情報を確認できます。

![](https://www.evernote.com/l/As2kf3XT-FJEnL4WB8e-Djireq_fQ0kGYegB/image.png)

### 　■ 依存関係の追加方法

　　各タブをクリックすることで、各プロジェクト用の記述を確認できます。

![](https://www.evernote.com/l/As0EjIMeej9Fd48uYQl_F9dTTZ5HtAEGcbkB/image.png)
古いCentOSにのっているNagiosからSlackに通知を飛ばす

今更だけど、Nagiosの通知をSlackに飛ばすようにした。
参考はここ http://takeshiyako.blogspot.jp/2014/09/slacknagios.html

## 困った事

Nagiosを積んでるCentOSのバージョンがとても古くて Crypt::SSLeay が入らない。
というか入れ方が分からない。

```
$ cat /etc/redhat-release
CentOS release 5.5 (Final)
```

なんでなの…

### 実際に上手く行かなかった失敗事例

#### ①cpanコマンド

これはなんとなくダメそう （`lib::XML` とか昔ハマった記憶が）

```
cpan Crypt::SSLeay
```
色々足りないって怒られる

#### ②openssl-devel をyumで。

これはいけるかもと思ったんだけどダメでした。
[[Perl][CPAN]CentOSでCrypt::SSLeayをインストールする方法 · DQNEO起業日記](http://dqn.sakusakutto.jp/2011/06/perl-cpan-centos-crypt-ssleay.html)

結局色々足りないって怒られる

### 上手くいった方法

結論はこれでした。そんな構文知りませんでした。

```
sudo yum install "perl(Crypt::SSLeay)"
```

ちなみにグーグルの迷宮に迷い込んで、ここで解決しました。
[CentOS 7 に Movable Type 6 をインストールする - Qiita](http://qiita.com/bezeklik/items/f2932649dd670f9b5fef#%E3%81%9D%E3%81%AE%E4%BB%96%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%83%BC)

---------

普段Debian,Ubuntuだけに触れて生きているので、 `apt` だけじゃなく `yum` ももう少しちゃんと知らないといけないと思いました。
時系列DB・可視化のいまむかし

時系列DBの概略

## 歴史的経緯
約10年くらい？前から devopsという考え方がでてきた。そのアクティビティの一つに、可視化、特にアプリケーションメトリクス（例：サイトの現在の閲覧者数）や、インフラのメトリクス（CPU使用率等）を収集し、ほぼリアルタイムな可視化をすること、が盛り上がりを見せていた。

当時それを提唱・実行に移していたのが Etsy というECサイトのメンバで `graphite` と呼ばれる一連のツール(収集：carbon,格納:whisper,可視化:graphiteweb)や、それを効率よく集めるためのツール`statsd`等でそれを見事に体現して見せた。

当時より（graphiteでは）メトリクスは、ドットで区切られる名前空間で識別されており、`host.cpu.idle`のようにCPU使用率を表したり、 `clicks.item813` で商品のクリック数を識別するような形で、`<メトリクス名, 時刻, 数値>`というデータ、すなわち時系列データで表されていた。

運動に盛り上がりが見られた一方で、ツールとしてのgraphiteは開発が止まってしまっており、各種現場で得られたあらたな要求を満たすのが難しくなっているという状況があった。例えば以下のようなことが挙げられる。

* [収集] メトリクス名が多すぎ・長すぎるので構造化したい
* [格納] 過去のデータを後から入れたい
* [格納] 格納効率を上げたい
* [格納] もっとスケールしたい
* [可視化] もっとかっこよく、カスタマイズ可能なダッシュボードがほしい

ここまでが歴史的経緯と、課題観の共有。

## 時系列DB戦国時代

このような背景から、いくつもの時系列DBが提唱され、淘汰されていった。現在でも残っているのは、（個人的に有望と感じるものから順に）以下のようなものが挙げられる。

* influxdb: Go製 graphiteのよき後継者
* prometheus: Go製 Influxdbよりシンプルだが格納効率が高い
* elasticsearch: Java製 時系列DBではないが、時系列DBとしても使える。
* OpenTSDB: 古株。HBaseを利用することによって高い可用性を持つ

それぞれが独自のプロトコル（主にHTTP RESTが多い）を持つが、互換性はない。ただ、どれも簡易なプロトコルであるため、アプリケーションから時系列データを格納するのはそれほど難しくない。どの製品も基本機能は満たし、クラスタリングやレプリケーションなど応用的な機能にフォーカスしている。

時系列DBに格納されたデータを可視化する製品は、時系列DBに付属していることが多い。

* Grafana: Go製 Webサーバ機能を同梱し、単体で動作する. Kibanaからfork
* 各種時系列DBに付属の製品
* Kibana: ElasticSearchの可視化ツール。 Grafanaに多大な影響を与えた

とりわけGrafanaという製品は、前述の時系列DBすべてに対応しており、また開発が活発で機能も充実しているため、事実上のデファクトスタンダードになっている。

## 今とこれから

日本国内ではあまり技術的な資料がないが、Elasticseachに、fluetndで集めたログを送信して、Kibanaで可視化する方法はよく見られる。いわゆる EFKスタック （なお、欧米では fluentdではなく、 logstash を利用するので ELKスタックと呼ばれる）がある。

とはいえ、Elasticsearchはログ分析のソフトであって時系列DBではないし、Kibanaも若干機能性に不足感が否めないため、時代の潮流に乗って、 `influxdb + Grafana` や、`prometheus + Grafana` などに乗り換えるのが吉ではないかと考える
うちの家庭のためにslackで動いているbot機能

#家庭でslackを使う
主な用途は家庭のコミュニケーションです。
ラインやら、Betweenやら、Facebookやら色々使ってみましたが
なんだかんだで機能追加できるslackが一番（僕が）気に入っているので使い続けています。

最近、めっきりコードを書かないのでお勉強ついでに色々と実装しています。

##前提
1.嫁さんと２人暮らし
2.比較的嫁さんは家にいる
3.自分は普通のサラリーマン（非開発者）で外に出かける
4.実装はGoogleAppScriptにて作成
5.bot用のチャンネルを使って動かしてます

##機能一覧
１．親族の誕生日通知機能
　お互いの親族の誕生日の１週間前と当日に連絡してくれます。
　SpreadSheetで管理しているので、必要に応じて管理できます。
　
２．ジム回数メモ
　お互いに同じジム通っているのですが、
　@bot ジム行った−
　と話しかけると今月の行った回数と１回あたりの値段を返してくれます。
　お金のムダがわかって怖いです。

３．記念日からのカウント機能
　はてなカウントを引用して、結婚して何日立ったとか分かるようになってます。

4.位置情報通知
　私が最寄り駅とか会社出た時に位置情報から連動して通知してくれます。
　ただ精度が悪いので厳密には使えないのですが、
　帰る時間教えるのを忘れた時とかに有用らしいです。

5.朝に今日の天気を通知
　Yahoo天気と連動して今日の天気情報を教えてくれます。
　テレビを殆ど見ないので、傘持つかどうかはこれで判断してます。

６．住んでる近くの人気情報を通知
　私は浅草在住なのですが、浅草周りではてブがついた情報を通知しています。
　コミュニケーションのきっかけや、土日のお出かけ先など決めたりするのに使ってます。

７．近くのスーパーのウェブチラシが更新されたら通知
　そのまんまですが、ウェブチラシが更新されたら通知しています。
　嫁さんが食材買う時とかに参考にしているみたいです。

今のところ、こんな感じでしょうか。

実際はコード書いたり、IFTTTのような外部サービス使ったり、
実現方法は色々なので実現方法で気になる事があれば詳しく書きます。
Version Control Strategies


# Version Control Strategies

* Release Branch
   * Epic（の粒度）でブランチを作成して、完了したら trunk(master) にマージする。(subversionとかこんな感じ)
* Trunk based Development
   * trunk(master)にコミットして開発する（プロトタイプとかそんな感じ）
* Integration Feature Branch
   * trunk(master)と開発のブランチ(integration)をの２つのブランチを用意してできた機能をマージする（個別対応とかした場合に）
* Build Feature Branching
   * feature毎にブランチを作成して、マージする
* Git flow
  * [cheet sheet](http://danielkummer.github.io/git-flow-cheatsheet/index.ja_JP.html)
* Github flow
  * [Understanding the GitHub Flow](https://guides.github.com/introduction/flow/index.html)

# 参考

[version control strategies](http://www.alwaysagileconsulting.com/articles/version-control-strategies/)
Android Nのクイック設定タイル(TileService)を使って開発者オプションをサクッと開くやつ


* [Android Nのクイック設定タイル](http://qiita.com/nagasakulllo/items/89736172306f8124576a) を読んで自分でも使ってみた。
* APIリファレンスはこちら: [TileService](https://developer.android.com/reference/android/service/quicksettings/TileService.html), [Tile](https://developer.android.com/reference/android/service/quicksettings/Tile.html)
* 今回の全体コードはこちら [DeveloperOptionsTile | GitHub](https://github.com/ymegane/DeveloperOptionsTile)

環境
---
＊記事更新にあたり最新環境に更新しました。

Android O Developer Preview 4 (API level 26)
Android Studio 3.0.0 Beta2
Nexus 5X

試したところ
---
* `onClick`, `onTileAdded`, `onTileRemoved`, `onStartListening`, `onStopListening`の呼ばれるタイミング
* `getQsTile()`を利用したTileのupdate

Tile
---

### state
`ACTIVE`, `INACTIVE`, `UNAVAILABLE`の3状態。
こんな感じ

| state | icon color | text color | click |
|:------|:------|:------|:------|
| ACTIVE | white  | white | enable |
| INACTIVE | gray | white | enable |
| UNAVAILABLE | gray | gray | disable |


TileServiceの各種コールバック
---
### onTileAdded
ユーザーがタイルをドラッグ&ドロップして追加した時に呼ばれる
### onTileRemoved
ユーザーがタイルを削除した時に呼ばれる
### onStartListening
タイルが追加された状態でNotificationScreenが降りると呼ばれる
### onStopListening
タイルが追加された状態でNotificationScreenが閉じると呼ばれる
### onClick
タイルが追加かつ有効な状態でタイルをタップすると呼ばれる
前述のとおりTileStateがUNAVAILABLEの時は呼ばれない。

作ったコード
---

タイルがクリックされたら開発者オプションを開く。
本当はモードを変えたいところだがSystemAppにしか許されていないのでこれで。

```kotlin:onClick

override fun onClick() {
    val intent = Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS).apply {
        addCategory(Intent.CATEGORY_DEFAULT)
        flags = Intent.FLAG_ACTIVITY_NEW_TASK
    }
    // Activityを開始してNotificationパネルを閉じる
    startActivityAndCollapse(intent)
}
    
```

Listeningを開始したらタイルの状態を更新する
設定変更も監視する

```kotlin:onStartListening&onStopListening
override fun onStartListening() {
    super.onStartListening()
    contentResolver.notifyChange(Settings.Global.getUriFor(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED), developSettingsObserver)
    contentResolver.notifyChange(Settings.Global.getUriFor(Settings.Global.ADB_ENABLED), developSettingsObserver)

    updateAppTile()
}

override fun onStopListening() {
    super.onStopListening()

    contentResolver.unregisterContentObserver(developSettingsObserver)
}

```

設定に応じたタイルの更新
開発者オプションが有効なときはACTIVEになるようにした。
オレ得。

```kotlin:TileUpdate
fun updateAppTile() {
    qsTile?.apply {
        state = tileState()
        updateTile()
    }
}

fun tileState(): Int {
    val enabled = Settings.Global.getInt(contentResolver, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED)
    val adb = Settings.Global.getInt(contentResolver, Settings.Global.ADB_ENABLED, 0)

    return when {
        enabled == 1 && adb == 1 -> Tile.STATE_ACTIVE
        enabled == 1 -> Tile.STATE_INACTIVE
        else -> Tile.STATE_UNAVAILABLE
    }
}

```

まとめ
---

* パネルを閉じてActivity開くところまでAPIが用意されていて簡単（最初気づかなくて自分で閉じてたんだけど。。
* Dialogを開くAPIもあったよ（試してない
* Kotlin本は予約しました。
CloudFrontとS3でHTTPSな独自ドメイン

## CloudFrontを使う理由

S3が独自ドメインのhttpsに対応していないようなので、CloudFrontを挟んでhttpsとして扱えるようにする。

## S3の設定

静的ウェブサイトホスティングを次のように設定しましょう。

```
ウェブサイトのホスティングを有効にする
インデックスドキュメント: index.html
エラードキュメント: error.html
```

## CloudFrontの設定

基本的には流れ通りにやりましょう。注意点は次の通りです。

#### Alternate Domain Names(CNAMEs)

CNAMEsを設定しましょう。
例: media.yoneapp.com

#### SSL Certificate

Request an ACM certificateで`*.yoneapp.com`のようなワイルドカード証明書をリクエストして使うと良いでしょう。

#### Viewer Protocol Policy

`Redirect HTTP to HTTPS`か`HTTPS Only`でいいんじゃないでしょうか。

#### Whitelist Headers

Whitelist HeadersにOriginを設定しましょう。設定しない場合`media.yoneapp.com`アクセス時に`media.yoneapp.com.s3-website-ap-northeast-1.amazonaws.com`にリダイレクトされてしまいました。

#### Status

CloudFrontも新規作成時や設定変更時には一定の時間がかかります。
StatusがInProgressからDeployedに変わるまで待ちましょう。

## Route 53の設定

Route 53でなくてもいいのですが、ドメインとCloudFrontを結びつける必要があるので設定しましょう。
アジャイル再考 にゃ (もうやめよーぜ 結局 実用主義なんだよ)


## ちょー簡易版結論

リームーだから、軽めので行こうぜ


## 	ここでのアジャイルとは？

参考にある、「Agile Limits」にある

```
I believe it is important to separate the notion of iterative construction 
from the notion of a manifesto of extra constraints. 
```

をそのまま流用して、反復のプラクティスとマニフェストの概念を切り分けてアジャイルマニフェストについて取り合げる


## マニフェストの解釈と分解

マニフェストから対応するスキルを上げてみます。

<table>
<tr><th>マニフェスト</th><th>必要なスキル</th></tr>

<tr><td>プロセスやツールよりも個人と対話を</td><td>→ ビジネス要件、開発、ソフトウェアについて会話できる</td></tr>
<tr><td>包括的なドキュメントよりも動くソフトウェアを</td><td>→ 対話から暗黙知をメンバーと共有（言葉に）して開発できる</td></tr>
<tr><td>契約交渉よりも顧客との協調を</td><td>→ 顧客が求めるものを理解・推測できる</td></tr>
<tr><td>計画に従うことよりも変化への対応を</td><td>→ 顧客・メンバーと共通認識を形成・維持できる</td></tr>

</table>

というものが挙げられると思います。またそれぞれを分解してみます。

* 「ビジネス要件、開発、ソフトウェアについて会話できる」
   * ビジネス要件
      * コミュ力
      * 業界知識
   * 開発
      * 体制、人員管理
      * スケジュール管理
      * プラクティス
   * ソフトウェア
      * 言語、開発技法
      * 利用モジュール知識
* 「対話から暗黙知をメンバーと共有（言葉に）して開発できる」
   * 暗黙知
      * 勘所
      * コード化
   * 共有
      * コミュ力
      * 適切な言語選択センス
* 「顧客が求めるものを理解・推測できる」
   * 理解・推測
      * 業界知識
      * コミュ力
* 「顧客・メンバーと共通認識を形成・維持できる」
   * 共通認識を形成・維持
      * コミュ力
      * 気配り系な性格

## 結論

アジャイルをするには、ハイレベルな人が必要になるが、そんな人いないから選択するべきでない筆者の意見だにゃ

重要なのは、下の事でいいんじゃね？ という事らしい、マニフェストでは重厚すぎるので、もっと軽量にしようよというエッセンスがここにも・・・


*翻訳から*

<pre>
なにをすべきか：

        自分のいる場所についてよく考える
        ゴールに対して小さなステップを取る
        学んだことをベースとして理解を調整する
        繰り返す


どうやってすべきか：


    ほぼ同じ価値を生み出せる手段が複数ある場合、将来的な変更ができるだけ少ないパスを選ぶ
</pre>


*原文*
<pre>
What to do:

        Find out where you are
        Take a small step towards your goal
        Adjust your understanding based on what you learned
        Repeat

How to do it:

    When faced with two or more alternatives that deliver roughly the same value,
　　 take the path that makes future change easier.
</pre>

## 参考

* [アジャイルは”再び"死んだ](https://www.infoq.com/jp/news/2016/06/agile-dead-again)
* [Agile is Dead – Again](https://www.infoq.com/news/2016/05/agile-dead-again)
* [Agile is Dead](https://www.linkedin.com/pulse/agile-dead-matthew-kern)
* [Agile Limits](https://www.linkedin.com/pulse/20140704132728-86002769-agile-limits?trk=mp-reader-card)
* [アジャイルは死んだ。しかしアジャリティは滅びんよ、何度でもよみがえるさ！](http://pigya.hatenablog.com/entry/20140313/1394703729)
* [Agile is Dead (Long Live Agility)](https://pragdave.me/blog/2014/03/04/time-to-kill-agile/)
OS X El CapitanでFFTWとopenFrameworksの環境を作ってみる

# 環境
- OS X 10.11.4
- openFrameworks 0.9.3
- FFTW 3.3.4
- Xcode 7.3.1


# 準備
- openFrameworksを[ここ](http://openframeworks.cc/ja/download/)からダウンロード.
- FFTWを[ここ](http://www.fftw.org/download.html)からダウンロード.

# FFTWについて
1. ダウンロードしたtarファイルを解凍する.
2. 解凍先のディレクトリ内で  ```./configure --prefix==${PATH}```を実行する. ${PATH}はライブラリをインストール場所を指す. （普段はつけないが今回はなんとなく指定する.）
3. 最後に, ```make && make install```を実行する.
4. 2で指定したディレクトリにした図のようなファイルが作られる.

![FFTW](http://cl.ly/2V0G1d1J3w1x/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202016-06-19%2016.54.58.png)

# openFrameworksについて
1. ダウンロードしたzipファイルを解凍.
2. 解凍したディレクトリ内の```projectGenerator-osx/projectGenerator```を実行し, アプリケーションの雛形を作る.
3. 作れたら、その雛形の```***.xcodeproj```をクリックしてXcodeを起動させる.
4. Xcode内のプロジェクトファイル（私は"SuperTest"にしている）を選択し、下図のような"SearchPath"を探す.
5. 見つかったら, "Header Search Paths"に上図の"fftw3.h"までのPathを指定する.
6. 次に, "Library Search Paths"に"libfftw3.a"までのPathを指定する.

![of](http://cl.ly/283v2h241z3x/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202016-06-19%2017.06.05.png)
7. 最後に, "Linking"の"Other Linker Flags"に"-lfftw3"を追加する.

![of2](http://cl.ly/2K3c1X3U0m2P/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202016-06-19%2017.19.51.png)



# テスト
![テスト](http://cl.ly/1z2t1M1M2N0A/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202016-06-19%2017.49.32.png)
動作しました！
cloud9にriot.jsプリコンパイル環境を作る

愛機がChromeBookなので開発環境構築に毎度困っていたのですが、cloud９には重宝しています。
riot.jsを勉強してみようと、cloud9上に環境構築してみたのでメモしました。

諸事情あって、プリコンパイル環境を作っています。

#　準備
cloud9のworkspaceはblankで作成します。
プリコンパイルにnode.jsが必要なので`apt-get`します。

```
$ sudo apt-get update
$ sudo apt-get install nodejs npm
$ node -v
v4.4.5
```
riotをインストールします。

```
$ sudo npm install riot -g
$ riot --help
<省略>
Version
  riot-cli:      2.5.0 - https://github.com/riot/cli
  riot-compiler: 2.5.1 - https://github.com/riot/compiler
```
以上で準備はお終いです。

# プリコンパイル方法

ディレクトリ構成は以下

```
workspace
  assets
    js
      sample.js
    tag
      sample.tag
  index.html
  README.md
```

以下のコマンドでコンパイルすることが出来る。
-wオプションを付けると、ディレクトリの変更を監視してtagファイルの編集・追加後に即座にコンパイルしてくれる。
オプションは　`riot --help` で確認できる。　

```
$ riot ./assets/tag/ ./assets/js/
$ riot -w ./assets/tag/ ./assets/js/
```
PaperclipでS3に画像をアップロードする

## Paperclip選定の経緯

carrierwaveが良さそうだって検討したが、ドキュメント周りをうまく拾うことが出来なかったので断念した。
refileも良さそうだったんだけど、同じように設定で戸惑ったので断念した。

## Paperclipの導入

https://github.com/thoughtbot/paperclip を参考に導入する。

Development環境で https://github.com/thoughtbot/paperclip#image-processor の通りに config/environments/development.rb に設定を書き込むのを忘れないようにしましょう。 動かないケースが有ります。

上記URL通りだと、本番にも影響してしまうので以下のように書いてもいいかもしれません。

```rb:config/environments/development.rb
Paperclip.options[:command_path] = "/usr/local/bin/"
```

Paperclip自体は、S3と連携しなくても動くので、DevelopmentでもS3に関係無く開発出来て便利です。

今回は画像だったので、バリデーションを次のように設定した。

```rb
validates_attachment_content_type :content, content_type: ["image/jpg", "image/jpeg", "image/png", "image/gif"]
```

## S3連携

[Uploading Files to S3 in Ruby with Paperclip](https://devcenter.heroku.com/articles/paperclip-s3) を参考に設定を行った。実際にはs3に media.yoneapp.com のようにドメインを当てていたので、このドキュメント通りには事が進まなかった。

最終的には次のような設定を行った。`url`が理解しにくかったのだが https://github.com/thoughtbot/paperclip/blob/95acf3b898bd782f4429d42fd2d8812505390328/lib/paperclip/storage/s3.rb#L159 にあるように実際の`url`ではなく`url`の構成方法を決めるパラメータのようです。

```rb:config/environments/production.rb
config.paperclip_defaults = {
  storage: :s3,
  s3_credentials: {
    access_key_id:     ENV.fetch('AWS_ACCESS_KEY_ID'),
    secret_access_key: ENV.fetch('AWS_SECRET_ACCESS_KEY'),
    s3_region:         "ap-northeast-1",
    bucket:            "media.yoneapp.com",
  },
  s3_host_alias: "media.yoneapp.com",
  path:          "/:class/:attachment/:id_partition/:style/:filename",
  url:           ":s3_alias_url",
  s3_protocol:   "https"
}
```

また`path`を設定せず`:s3_alias_url`を指定すると`Paperclip::Errors::InfiniteInterpolationError`が発生する。