OmniAICreator/Qiita-1.07M huggingface dataset:
Amazon AthenaでCloudFrontのログにクエリを投げたメモ

※当記事は[個人ブログ](https://tech.tsukapah.com/athena-cloudfront/)に移行しました

AWS re:Invent 2016 で発表された新サービス Amazon Athenaを早速(?)使ってみました。
S3にログを置いたままサーバレスでクエリが発行できるので集計等が捗ります。
すでに同様の記事も見かけましたが、デリミタの指定でうまくいかずにハマったのでメモ。
なお、CloudFrontのLogging設定はこの記事では触れません。

# Databaseの作成
```sql
CREATE DATABASE CloudFrontLogs;
```

# Tableの作成
マネージメントコンソール上でも定義できますが、
DDL書くほうが楽な気がしたので、2つくらいカラム定義したあたりでそっとキャンセルしました。

```sql
CREATE EXTERNAL TABLE IF NOT EXISTS <TableName> (
  date DATE,
  time STRING,
  xEdgeLocation STRING,
  scBytes INT,
  cIp STRING,
  csMethod STRING,
  csHost STRING,
  csUriStem STRING,
  scStatus INT,
  csReferer STRING,
  csUserAgent STRING,
  csUriQuery STRING,
  csCookie STRING,
  xEdgeResultType STRING,
  xEdgeRequestId STRING,
  xHostHeader STRING,
  csProtocol STRING,
  csBytes INT,
  timeTaken INT,
  xForwardedFor STRING,
  sslProtocol STRING,
  sslCipher STRING,
  xEdgeResponseResultType STRING,
  csProtocolVersion STRING
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES (
  'serialization.format' = "\t",
  'field.delim' = "\t"
) LOCATION 's3://<LogBacketName>/<LogPrefix>/'
;
```

CloudFrontのログフォーマットはTSVです。
`serialization.format`と`field.delim`を`'  ' --タブ文字`みたいに表記している記事がいくつかありましたが、[ドキュメント](http://docs.aws.amazon.com/athena/latest/ug/ddl/create-table.html)を見たら普通に`"\t"`でよいと書いてありました。
カラム名はお好みに合わせてよしなに変更してください。

# Queryの発行
```sql
SELECT * FROM <TableName> limit 10;
```
期待通りResultsが返ってくればOK。
プログラミングでダイエット - イブに向けて無駄に -

# プログラムってなんすか？
プログラム
って
どんなものなのか
全くもって想像がつかない
という
**デジハリに行く前の長尾**
のような方必見です


# 「ダイエット」を日本語で表してみる
ダイエット女子の行動パターンを日本語で書いてみます

目標体重を決める
↓
今の体重を記録する
↓
ウォーキングにいく
↓
ご飯食べる
↓
半身浴する
↓
冷蔵庫を開ける
↓
もし、ケーキがあったら
↓
もし、体重が目標に達してたら
食べる
 


# 「ダイエット」をプログラムで表してみる
次に、ダイエット女子のパターンをプログラムで書いてみます

```
var mokuhyoTaiju: Int
var imanoTaiju: Int
var hasCake = true




mokuhyoTaiju = 40
imanoTaiju = 44
doWalk()
doGohan()
doHanshinyoku()

if(openReizoko()) {
    if(imanoTaiju < mokuhyoTaiju) {
        eatCake()
    }
}



func
doWalk() {
    imanoTaiju - 1
}

func
doGohan() {
    imanoTaiju + 1
}

func
doHanshinyoku() {
    imanoTaiju - 1
}

func
openReizoko() -> Bool {
    return hasCake
}

func
eatCake() {
    hasCake = false
}
```

# 雰囲気は伝わったかと
音楽未経験の人がいきなり楽譜読む
に比べたら
プログラミング未経験者がいきなりプログラム読む
のほうが楽だと思います

ダイエット中は目標体重いってないのにケーキ食べたらダメですよ
それバグです
とりあえずサイト作ってって言われたとき、始める前にきくことチェックシート（html/css）

## 確認必須

* 対応ブラウザ（IEとAndroid標準はバージョンまで貰うこと）
* 文字コード
* htmlのバージョン
* ブラウザ対応ポリシー、非対応環境の扱い  
（後から非対応環境でも見栄えは気にしないが機能の提供は必要といわれて死ぬケースが稀によくあるため。）
* レスポンシブの場合、ブレイクポイントはどこか、タブレットはどう扱うのか、ていうか何種類作るのか

## 重要

* スマホ/タブレット/PCはどのように対応するのか。
* 複数端末対応の場合、端末の判断基準は何か。UA？画面幅？
* 読み込み必須のCSSやjsの有無
* メタ言語全般の使用可否
* フォルダ構成
* パス指定のルール

## 確認しておくと安心

* リンク遷移基本ルール（target="_blank"をどう扱うか）
* svg/アイコンフォントの使用可否
* プリントアウト表示調整の重要度

思い出したら増やす。
さくらのクラウドのWindows Server 2016でSQL Server for Dockerを動かした

さくらのクラウドがWindows Server 2016の提供を開始したそうなので早速サーバを作ってWindows コンテナーでDockerしてみました。

[さくらのクラウドにおける「Windows Server 2016」の提供開始について](http://cloud-news.sakura.ad.jp/2016/12/08/ws2016/)

サーバの作成自体はこれまで同じく、リモートコンソールから利用規約に同意しAdministratorのパスワードを設定して終わり。


作成が完了したWindows Serverに対してリモートデスクトップで接続したらここからの作業はPowershell上行っていきます。

## Windows上でDockerを使うための準備
まずはPowershellのためのパッケージ管理用のモジュールのインストール

```ps1
Install-Module -Name DockerMsftProvider -Repository PSGallery -Force
```

これが完了したら最新のDockerをインストールします。

```ps1

Install-Package -Name docker -ProviderName DockerMsftProvider
```

インストール完了したらここで一旦サーバの再起動を行います。
ただ、仮想環境なので再起動早い！


再度リモートデスクトップで接続し、再度PowerShellを起動します。
試しにdockerと入力してどのように表示されるかを確認してみましょう。

![img01.PNG](https://qiita-image-store.s3.amazonaws.com/0/100935/470a2ca6-ac4c-c1dc-a392-0f3ff061368f.png)

ちゃんとDockerコマンドが認識されています！

## SQL Server for Windows コンテナを利用するための準備
さて、今度はSQL Serverのコンテナを準備します。
Microsoftが公式にDocker hubに公開しているものを活用します。

[microsoft/mssql-server-windows](https://hub.docker.com/r/microsoft/mssql-server-windows/)

具体的にはこのコマンド

```
docker run -d -p 1433:1433 -e sa_password=****** -e ACCEPT_EULA=Y microsoft/mssql-server-windows
```
ちなみにファイルサイズは12GB位あるので気長に待ちます。

```ps1
> docker images
REPOSITORY                       TAG                 IMAGE ID            CREATED             SIZE
microsoft/mssql-server-windows   latest              307f05c5da18        3 weeks ago         12.8 GB
```

### SQL Server Management Studioのインストール
この待ち時間にSQL Server Management Studio (SSMS)をインストールしておきましょう。最近はSQL Server本体とは独立してSSMSだけでもアップデートされるようになったんですね。
[SQL Server Management Studio (SSMS) のダウンロード](https://msdn.microsoft.com/ja-jp/library/mt238290.aspx)


## コンテナに接続するための準備
さて、SQL Serverのコンテナのダウンロードが完了し実行状態になっているかと思います。

```ps1
> docker ps
CONTAINER ID        IMAGE                            COMMAND                  CREATED             STATUS              PORTS                    NAMES
60ac2328f725        microsoft/mssql-server-windows   "cmd /S /C 'powers..."   About an hour ago   Up About an hour    0.0.0.0:1433->1433/tcp   grave_feynman
```

ではここにSSMSで接続。。。。しようと思ってもできません。
※私のやり方悪いだけできっと正しい方法はあると思います。教えてくださいm(_ _)m

SSMSで接続するためにコンテナに割り当てられているIPアドレスを確認する必要があります。

```ps1

> docker exec -it 60ac2328f725 powershell
```
`60ac2328f725` は上記docker psで確認したコンテナIDです。
するとちょっと配色のおかしなPowerShellの画面が表示差れます。

![img03.PNG](https://qiita-image-store.s3.amazonaws.com/0/100935/ef54919a-22f6-d2af-083a-29273e4c3142.png)

`ipconfig` コマンドでIPv4を確認します。
今回であれば `172.20.194.39` が割り当てられていることが確認できました。

## SSMSからコンテナ内のSQL Serverへの接続
先程インストールしたSSMSに戻って実際にDockerコンテナ上のSQL Serverに接続をしてみます。
![img04.PNG](https://qiita-image-store.s3.amazonaws.com/0/100935/83d6192c-931a-714d-57b9-1e29d6c0f7b5.png)

確認したIPアドレスをサーバ名にインストールして、SQL Server認証でログインに`sa`を設定し、コンテナ起動時に設定したパスワードを入力します。


![img05.PNG](https://qiita-image-store.s3.amazonaws.com/0/100935/f68b07c9-c820-2e67-afe3-aaf9cf9f3fe2.png)

無事コンテナ上で動作しているSQL Serverに接続できました。
コンテナのサイズは巨大ですが都度インストールなどの手間を考えれば随分楽。Dockerを動かしているWindows Server 2016のデータベースファイルを参照させることもできるみたいですので、活用の幅広がりそう！
【ゲリラアドカレ】UE4ゲーム実装　進捗報告 4日目(エンカウント演出)

【非公式】某会社設立記念ゲリラ Advent Calendar 2016 8日目の記事です。

FlashゲームをUE4で再実装するゲリラアドカレです。

エンカウント演出が出来たので進捗報告します。

![エンカウント演出.png](https://qiita-image-store.s3.amazonaws.com/0/104377/0fe78bc5-b571-9e94-9b9b-44ef7c64d49e.png)


・注意
許可を取ってないので通常業務の空いた時間を利用して作成するため、作成中のゲーム、及びアドカレは完成保証がなければ、ゲーム自体もリリースされる保証も皆無なので、あんまり期待しないでください。

#エンカウント演出

またUIアニメーションで実装しました。

まずは素材を配置します。真ん中の黄色いのは無限スクロール用に作られているので、不自然な動きにならないようにimageを配置しています。この素材では４個、imageを置いています。
![エンカウント.png](https://qiita-image-store.s3.amazonaws.com/0/104377/4e16ff9e-5aa1-d6b7-052e-b3c9d894df0c.png)

あまり細かく設定しすぎると挙動がおかしくなって（タイム0～1.0で960の位置から、0の位置に行くようにしたら、何故か0.75あたりで-0.5と突き抜けてから0に戻るなど）、毎フレームごとに調整が必要になる地獄をみるのでなるべくキーは少なめで想定の動作をするように調整したほうが幸せです。

![タイムライン1.png](https://qiita-image-store.s3.amazonaws.com/0/104377/ee49f4f2-1cbc-58e1-b1e1-97a3c84fc4ab.png)

![タイムライン.png](https://qiita-image-store.s3.amazonaws.com/0/104377/51e94c53-5adb-d751-5b3d-16d4f1cbd092.png)

とりあえず参考までに

#スクリプト実装

スクリプトを実装します。
まずはエンカウント演出の再生スクリプトです。
![UIスクリプト.png](https://qiita-image-store.s3.amazonaws.com/0/104377/7da26be1-3758-317f-8e95-03d377b09bce.png)

とりあえず今は進んだ時に必ずエンカウント演出を出すようにして、再生し終わったら消すようにしています。
![UIスクリプト2.png](https://qiita-image-store.s3.amazonaws.com/0/104377/da93fe68-02ce-930e-7356-d986c37ecb64.png)

これでエンカウント演出の実装が終わりました。

#エンカウント演出完成

エンカウント演出が完成しました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">エンカウント演出が出来た。UIアニメーションのみでこのぐらいは出来るみたい。<br>UIのアニメーション、タイムラインで細かくやりすぎると挙動がおかしくなるのがつらい <a href="https://twitter.com/hashtag/UE4Study?src=hash">#UE4Study</a> <a href="https://t.co/KcrZ6gBZx2">pic.twitter.com/KcrZ6gBZx2</a></p>&mdash; 荻野雄季＠クルーズから出荷された豚 (@YuukiOgino) <a href="https://twitter.com/YuukiOgino/status/807142929835835392">2016年12月9日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

今の段階では十分な感じです。
クエスト画面で必要なモノが出来たので、次からいよいよ仕様すら決めていない、一番工数的にヘビーなバトル画面の実装に入ります。

作業量が多すぎる気もするけとりあえず頑張ってみる
Electronで作ったアプリケーションをRaspberryPiで動かす方法

この記事は諸事情により、[このリンク先](https://sublimer.hatenablog.com/entry/2016/12/09/000000)に移行しました。
This article has moved to [this link](https://sublimer.hatenablog.com/entry/2016/12/09/000000) due to various reasons.
PayPal アカウント（個人）の作り方＆決済情報登録の仕方

オンライン決済できるサービス、PayPalのアカウント（個人用のパーソナルアカウント）を作る方法をメモってみます。
以下、スマホでやることを想定。

#### 1.PayPalサイトに行く。

https://www.paypal.com/jp/home

![QRcode (1).gif](https://qiita-image-store.s3.amazonaws.com/0/56701/a4c507f9-264c-8bb4-361e-77fcc05202d3.gif)

#### 2.「新規登録」→「パーソナルアカウント」を選び、メールアドレス、任意のパスワードを設定する

![0.PNG](https://qiita-image-store.s3.amazonaws.com/0/56701/14a9b331-6ee7-08b2-2dfc-84010639c8ef.png)
　　▼▼▼▼▼▼▼▼▼▼▼▼▼
![1.PNG](https://qiita-image-store.s3.amazonaws.com/0/56701/9569a2d9-3d80-29b6-43bc-32026cf75a11.png)
　　▼▼▼▼▼▼▼▼▼▼▼▼▼
※パスワードは英数ミックスで8文字以上

![2.PNG](https://qiita-image-store.s3.amazonaws.com/0/56701/bb9e1b10-f2b2-bb83-5db9-4f0c665695bd.png)

#### 3.名前、生年月日、郵便番号、住所、電話番号を入れて、規約に同意してアカウント開設する

![3.PNG](https://qiita-image-store.s3.amazonaws.com/0/56701/1f718711-ff40-08a8-b1f8-fb766c899f19.png)
　　▼▼▼▼▼▼▼▼▼▼▼▼▼
![4.PNG](https://qiita-image-store.s3.amazonaws.com/0/56701/c1f4a788-7b18-ad89-fabd-060f4856dde5.png)

#### 4.カード情報を登録しろと言われるが、ここではいったん「後で実行」でOK

![5.PNG](https://qiita-image-store.s3.amazonaws.com/0/56701/88b98d76-2495-cc4d-d892-a67af64ca3b5.png)

#### 5.登録が終わったので、「アカウントに進む」を選ぶ

![6.PNG](https://qiita-image-store.s3.amazonaws.com/0/56701/41ede0f1-ba52-6639-f365-4ae7be3434f1.png)

#### 6.メールアプリを立ち上げて、PayPalから届いたメールのアカウント認証を済ませる

![8.PNG](https://qiita-image-store.s3.amazonaws.com/0/56701/78e24a45-dfdc-c67c-45b3-d479fad755a2.png)

※最初に登録したパスワードを忘れずにここで入力！

![9.PNG](https://qiita-image-store.s3.amazonaws.com/0/56701/80efebcc-84cd-76af-7d27-5f1b6a930794.png)

#### 7.PayPalのホームに戻り、銀行またはカード情報を登録する

![7.PNG](https://qiita-image-store.s3.amazonaws.com/0/56701/db54577c-c455-d7ec-868e-49b7c73f0666.png)
　　▼▼▼▼▼▼▼▼▼▼▼▼▼
![10.PNG](https://qiita-image-store.s3.amazonaws.com/0/56701/fd0325bd-26dc-2a05-621c-eae6cbb23c36.png)

#### 8.例としてここでは「カードの登録」からクレジットカードを選ぶ

![11.PNG](https://qiita-image-store.s3.amazonaws.com/0/56701/6c6364cf-f29c-7c17-f579-dbf29b91536b.png)

※クレジットカード番号には - (ハイフン)は不要。15桁または16桁数字を半角でそのまま打つ。
※既にほかのPayPalアカウントで登録済みのカードは使えない。

![12.PNG](https://qiita-image-store.s3.amazonaws.com/0/56701/6eb417f9-d4ec-6e2e-950e-268dc238db2e.png)

#### 9.正しくカード情報が入れられると、登録済みカードが表示される

![13.PNG](https://qiita-image-store.s3.amazonaws.com/0/56701/cce673aa-50ea-9ff2-8efa-984714083151.png)

以上で完了です。お疲れ様でした。
一般的なWEBサービスのAWSネットワーク構成

#一般的なWEBサービスのAWSネットワーク構成
AWSでの小規模～中規模のWEBサービスにおいてのネットワーク構成を考えてみた。

下記最終図案
この他にアップロードファイルをスケール対応する為、S3を増やす予定。

![AWS Design2.png](https://qiita-image-store.s3.amazonaws.com/0/56889/415bba4c-622a-3000-6abd-e5cf2bd9ce2f.png)

上記の図の詳細を説明する

##VPC
10.1.0.0/16

##サブネットでネットワークを区切る
マルチAZ構成にする。
更に下記のように三回層に区切る

###フロントエンド
インバウンド、アウトバウンド共にインターネットとの接続を許可する。
具体的にはルートテーブルにインタネットゲートウェイを追加する。

【具体例】
図上のearth_frontend_left,rightに該当する。
踏み台サーバやNAT、ELBなどをここに設置する。
ELBを使わない場合はEC2のWEBサーバなど。

サブネットのネットワーク10.1.10.0/24,10.1.11.0/24

```lang:ルートテーブルの一例
10.1.0.0/16 local
0.0.0.0/0 igw-**********
```

igwは事前に作っておくといいと思う。

###アプリケーション
インターネットからのインバウンドは必要ないが
wgetとかyumとかで
外のインターネットにつなげたいようなユースケースに該当するサーバを入れる。
具体的にはルートテーブルにNATへの接続を追加する。

【具体例】
図上のearth_application_left,rightに該当する。
PHP-FPMサーバ、tomcatサーバなどなど。
ELBを使う場合はWEBサーバもなどもここに入れて良いと思う。

サブネットのネットワーク10.1.20.0/24,10.1.21.0/24

```lang:ルートテーブルの一例
10.1.0.0/16 local
0.0.0.0/0 nat-**********
```

natは事前に作っておくといいと思う。

###プライベート
インターネットと完全に切り離してもいいような領域。
RDSなどのフルマネージドサービスでインも必要ないユースケース。


【具体例】
図上のearth_datastore_left,rightに該当する。

サブネットのネットワーク10.1.30.0/24,10.1.31.0/24

```lang:ルートテーブルの一例
10.1.0.0/16 local
```

##セキュリティグループの記述が楽
サブネットを役割ごとに小分けにしておけばセキュリティグループの記載が楽。
下記のようにできる。

```lang:databaseセキュリティグループの一例
MySQL/Aurora (3306) 10.1.20.0/23
すべての トラフィック sg-*****
```

##踏み台サーバ
SSHのみ空けているサーバ、セキュリティグループをおいておきましょう。
普段は停止しておくといいと思います。
何か操作したい場合はコンソールから起動して。という形式で。
更にコンソール操作ユーザをMFA認証対応にしておけば尚グッドかと。

##参考
http://dev.classmethod.jp/server-side/network/vpc-knowhow/
AWS S3のバケットポリシー設定～リファラーでの制限～

めもです。

# やりたかったこと

S3にバケットを用意して、
特定のリファラーでのみ、使用可能にしたい。
（要は、特定のWEBアプリ以外からのアクセス・操作を拒みたいという話です）

## 最初にやっちまってた書き方

Getは行けるんです。
ただ、Putが上手くいかず・・・
Conditionの設定を外すとPutが成功するので、Conditionの書き方でまずってるんだなぁと。

```json
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "Public Read Bucket Objects",
			"Effect": "Allow",
			"Principal": "*",
			"Action": "s3:*",
			"Resource": "arn:aws:s3:::xxxx.xxxx.xx/*",
			"Condition": {
				"StringLike": {
					"aws:Referer": [
						"http://sitea.xxx/*",
						"http://siteb.xxxxx/*"
					]
				}
			}
		}
	]
}
```

## （たぶん）正しい書き方

[こちら](https://kosukety.org/prevention-hotlinking-aws-s3-backet-policy/)を参考にさせて頂きました！

最初にS3に対するアクセスを全て許可して
特定のリファラ以外からのアクセスが拒否だよ～

ってしてるわけですね。

```json
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "Public Read Bucket Objects",
			"Effect": "Allow",
			"Principal": "*",
			"Action": "s3:*",
			"Resource": "arn:aws:s3:::xxxx.xxxx.xx/*"
		},
		{
			"Sid": "Referer Deny",
			"Effect": "Deny",
			"Principal": "*",
			"Action": "s3:*",
			"Resource": "arn:aws:s3:::xxxx.xxxx.xx/*",
			"Condition": {
				"StringNotLike": {
					"aws:Referer": [
						"http://sitea.xxx/*",
						"http://siteb.xxxxx/*"
					]
				}
			}
		}
	]
}
```
CocoaBitでLED点滅させるシンプルなコード

この記事は、<a href="http://qiita.com/advent-calendar/2016/littlebits" title="littleBits Advent Calendar 2016 - Qiita" target="_blank">littleBits Advent Calendar 2016</a>の9日目の記事です。前日は @mfunaki さんの<a href="http://qiita.com/mfunaki/items/8fdd3559455b29d7569b" title="littleBitsでレジっぽく商品をスキャンする - Qiita" target="_blank">littleBitsでレジっぽく商品をスキャンする</a>でした。

さて、今回はlittleBitsを簡単にインターネットとつなげる開発中のボード CocoaBit でLED点滅させるシンプルなコードを書いて動かしてみます。

# CocoaBitとは

CocoaBitは、わみさん（ @wamisnet ）の記事 <a href="https://dotstud.io/blog/cocoabit-littlebits-milkcocoa-nefry/" title="電子回路を簡単に学べるlittleBitsをインターネットに繋げよう！「CocoaBit」を開発中 | dotstudio" target="_blank">電子回路を簡単に学べるlittleBitsをインターネットに繋げよう！「CocoaBit」を開発中 | dotstudio</a> にあるように、CocoaBitを使えばlittleBitsが簡単にインターネットとつながるようになります。

![image](https://qiita-image-store.s3.amazonaws.com/0/56170/a648c013-ffb7-9aaa-b833-d4d96311d2c1.png)

# その他関連記事

その他関連記事としては、私のブログで恐縮ですが以下のような情報もあります。

* <a href="http://www.1ft-seabass.jp/memo/2016/09/03/cocoabit-koshianbit-first-contact/" title="CocoaBitとKoshianBitの連携をしてみるメモ – 1ft-seabass.jp.MEMO" target="_blank">CocoaBitとKoshianBitの連携をしてみるメモ</a>
* <a href="http://www.1ft-seabass.jp/memo/2016/08/17/cocoabit-milkcocoa-freeboard/" title="CocoaBitでMilkcocoaのfreeboardでお手軽にグラフ可視化してみるメモ – 1ft-seabass.jp.MEMO" target="_blank">CocoaBitでMilkcocoaのfreeboardでお手軽にグラフ可視化してみるメモ</a>
* <a href="http://www.1ft-seabass.jp/memo/2016/08/16/iot-lt-vol-18-cocoabit-resume/" title="IoT縛りの勉強会 ! vol.18 でCocoaBitな登壇をしてきました – 1ft-seabass.jp.MEMO" target="_blank">IoT縛りの勉強会 ! vol.18 でCocoaBitな登壇をしてきました</a>

ご参考までに。

# CocoaBitでLED点滅させる

さて、インターネットにつなげられるCocoaBitですがArduinoでプログラムが可能でして、Lチカ（LEDを点滅させること）をやってみましょう。

CocoaBitでLED点滅させるシンプルなコードを書きます。

コードは以下のとおりです。

```c:SimpleBlink.ino
#include <Nefry.h>

void setup() {
  pinMode(D3,OUTPUT);
}

void loop() {
  Nefry.println("ON");
  digitalWrite(D3,LOW);
  Nefry.ndelay(1000);
  Nefry.println("OFF");
  digitalWrite(D3,HIGH);
  Nefry.ndelay(1000);
}
```

こちらを<a href="https://dotstud.io/blog/cocoabit-littlebits-milkcocoa-nefry/" title="電子回路を簡単に学べるlittleBitsをインターネットに繋げよう！「CocoaBit」を開発中 | dotstudio" target="_blank">さきほどの記事</a>のアップロード方法で「Upload Sketch」でアップロードします。

USB POWERモジュールから電源を入れてみます！<a href="http://www.1ft-seabass.jp/memo/2016/12/06/littlebits_powermodule_memo/" title="littleBitsのUSB POWERモジュールとPOWERモジュールの挙動についてのメモ – 1ft-seabass.jp.MEMO" target="_blank">littleBitsのUSB POWERモジュールとPOWERモジュールの挙動についてのメモ</a>を意識して、安定して電流が流すためにUSB POWERモジュールを使う意識です。

すると、このように認識されてLEDが1秒ごとに点滅します。

![image](https://qiita-image-store.s3.amazonaws.com/0/56170/9f05a8c6-b032-89ce-2ca3-8fd4e7d2c967.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/56170/8f002d75-2ed5-6741-6bba-6bee2716c47a.png)

littleBitsが簡単にインターネットとつながるようになるCocoaBitですが、インターネットにつながなくてもこのようにArduinoのコードで動作を作ることができます！

まだ開発中ではありますが、ひきつづきTIPをお披露目できたらと考えています。
S3のRedirect Ruleを使ってみたメモ


##やりたかったこと

http://old.example.com/blog/post1 -> http://new.example.com/post1
http://old.example.com/blog/post2 -> http://new.example.com/post2
http://old.example.com.blog/ ->  http://new.example.com/

のような子ディレクトリは一括リダイレクト、孫ディレクトリは個別リダイレクトという設定

##ダメだったパターン

子ディレクトリのキーでリダイレクトかけると、孫も同じリダイレクトになる。
多分優先順位とかあるんだろうけど、調べる気力がなかったので誰か検証plz


```xml
<RoutingRules>
    <RoutingRule>
        <Condition>
            <KeyPrefixEquals>blog/post1</KeyPrefixEquals>
        </Condition>
        <Redirect>
            <HostName>new.example.com</HostName>
            <ReplaceKeyWith>post1/</ReplaceKeyWith>
            <HttpRedirectCode>301</HttpRedirectCode>
        </Redirect>
    </RoutingRule>
    <RoutingRule>
        <Condition>
            <KeyPrefixEquals>blog/</KeyPrefixEquals>
        </Condition>
        <Redirect>
            <HostName>new.example.com</HostName>
            <ReplaceKeyWith>/</ReplaceKeyWith>
            <HttpRedirectCode>301</HttpRedirectCode>
        </Redirect>
    </RoutingRule>
</RoutingRules>
```



##対応
http://old.example.com.blog/ は実質http://old.example.com.blog/index.htmlを参照している。
なのでindex.htmlを削除して、S3からは404を返すようにした。
その上で以下のように404時のリダイレクトルールを設定する。

```xml
<RoutingRules>
    <RoutingRule>
        <Condition>
            <KeyPrefixEquals>blog/post1</KeyPrefixEquals>
        </Condition>
        <Redirect>
            <HostName>new.example.com</HostName>
            <ReplaceKeyWith>post1/</ReplaceKeyWith>
            <HttpRedirectCode>301</HttpRedirectCode>
        </Redirect>
    </RoutingRule>
    <RoutingRule>
        <Condition>
            <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
        </Condition>
        <Redirect>
            <HostName>new.example.com</HostName>
            <ReplaceKeyWith>/</ReplaceKeyWith>
            <HttpRedirectCode>301</HttpRedirectCode>
        </Redirect>
    </RoutingRule>
</RoutingRules>
```

とりあえずこれで動く。
メール送信で固定IPアドレスを利用すると何がうれしいのか

[SendGrid Advent Calendar 2016](http://qiita.com/advent-calendar/2016/sendgrid)の9日めの記事です。

先日、[Amazon SESで固定IPアドレスが使えるようになった](https://aws.amazon.com/jp/blogs/ses/amazon-ses-now-offers-dedicated-ip-addresses/)とアナウンスがありましたがメール配信時に固定IPアドレスが何故必要になるのでしょうか。今回はそのあたりをまとめてみたいと思います。

## 送信元IPアドレス
通常メールが届くまでは以下のような経路を通ります。(複数のサーバを経由することもありますがシンプルにしています)
![流れ.png](https://qiita-image-store.s3.amazonaws.com/0/24785/c629459c-5078-711c-ab89-a6cbd5063e51.png)

送信元IPアドレスというのは図で言うところの送信元サーバのIPアドレスで、メールヘッダのReceived:で確認することが可能です。Gmailに届いていたメールのヘッダを見てみると以下のようになっていました。

	Received: from sender.example.com (sender.example.com. [xxx.xxx.xxx.xxx])
	        by mx.google.com with ESMTPS id xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
	        for <hoge@hoge.com>

このxxx.xxx.xxx.xxxが送信元IPアドレスです。
初日に紹介した[IPレピュテーション](http://qiita.com/nakansuke/items/cbdf3a3ba130431be466)はこの送信元IPアドレスのもつレピュテーションを意味しています。

## 固定 or 共有 IPアドレス
固定IPアドレスを使って送信するということはこれを固定し必ず同じIPアドレスから送信するということです。
逆に固定IPアドレスでない場合は他の人と同じIPアドレスを共有して利用します(共有IPアドレス)。共有IPアドレスの送信形式の場合は、複数のIPアドレスをプールしておき、プール内のアドレスのいずれかがランダムに割り当てられて送信するというケースが多いようです。なので毎回送信元IPアドレスが変わります。

## それぞれのメリット・デメリット
それぞれメリットデメリットがあるので、送信用途にあわせて固定か共有かを選択する必要があります。

#### 固定IPアドレス
レピュテーションを自分でコントロールすることができ、他人の影響を一切受けません (ウォームアップは必要ですが)。
多くのISPでは時間あたりに同一IPアドレスから受信できる通数に制限を設けていますが、この制限がきつい場合は固定IPアドレスを追加する必要があります。
ちなみに、大体1つのIPアドレスから1日で送信可能なメールの量は[SendGridは40万通程度](https://sendgrid.com/docs/assets/IPWarmupSchedule.pdf)、[Mandrillは50万通程度](https://mandrill.zendesk.com/hc/en-us/articles/205582337-Should-I-use-a-dedicated-IP-)と見ているようなので、この辺を超えてくると固定IPアドレスを複数使う必要が出てきます。

#### 共有IPアドレス
健全な送信者のみで共有されているならばレピュテーションが高くなっているはずなので、いきなり大量の送信が可能ですし、少量しか送らないような場合も既に構築されたレピュテーションに乗っかることができるので、例えば固定IPを使っているが送信実績が殆ど無いという状態になるよりは共有IPを使うほうが安全かもしれません。
また、毎回送信元IPが変わるので、時間あたりの受信上限がきびしいISPへの送信がやりやすくなります。

ただ、もし同じIPを利用しているユーザがバウンスやスパム報告を大量に発生させ共有IPアドレスのレピュテーションが下がったときにはその影響を受けてしまいます。スパマーでなくても古いリストを使ったり、テストをミスったりすると大量にバウンスしてしまうので、割りとよくある話だと思います。それをどうコントロールするかがサービス提供社の腕の見せ所ですね。
SESはバウンス、苦情の管理を非常に厳しくしているのできっちりしている印象です。（[ここ](http://www.slideshare.net/AmazonWebServicesJapan/aws-30934799/51)ではバウンス率5%、苦情率0.1%を下回るよう推奨しています）
SendGridも異常だと判断した場合は[アカウントをサスペンドすることがあります](https://support.sendgrid.kke.co.jp/hc/ja/articles/203392245)。

## おいくら？
ユーザに提供する前にはクリーニングをする必要がありますし、どのサービスでもやっぱりある程度のお金がかかります。以下は全部月額
[SendGrid](https://sendgrid.kke.co.jp/plan/)：2,500円 Silverプラン以上はデフォルトで固定IPアドレスを1つ付与
[Amazon SES](https://aws.amazon.com/jp/ses/pricing/)：24.95 USD
[mailgun](http://www.mailgun.com/pricing)：$59.00
[Mandrill](http://www.mandrill.com/pricing/)：$29.95

## まとめ
固定IPアドレスを利用してうれしいのは、レピュテーションを自分で独占、他者の影響を受けない、というところに尽きると思います。日に数万通単位での送信をしている場合は積極的に利用していきたいですね。

Happy Sending!!
PostgreSQLの立ち上げ準備

> 自分用メモです。
> 何か間違えがあればご指摘頂けると有り難いです。

# PostgreSQL下準備
yum install -y postgres postgresql-server
sudo emacs /var/lib/pgsql/data/pg_hba.conf ( 81行目の最後を trust )に変更
sudo service postgresql start
createdb -U postgres データベース名 ( なにかしらデータベースが無いと接続できない可能性あり )
psql -U postgres

# ダンプファイル作成
pg_dump -h ホスト -U ユーザ --create --schema-only DB名 > dump_database.sql

# ダンプファイルの読み込み
psql -U postgres -f ダンプファイル

# pg_hba.conf
- TYPE  
local・host・hostssl・hostnosslを指定する
- DATABASE  
PostgreSQLのデータベース名( 接続できるデータベース絞る場合に指定、全てを許可するなら「all」 
- USER  
PostgreSQLのユーザー名( 接続できるユーザを絞る場合に指定、全てを許可するなら「all」 )
- CIDR-ADDRESS  
クライアントのIPアドレス( アドレス/ネットマスク )
- METHOD  
認証方式( trust: 無条件での接続許可 )  

参考文献: DBOnline - pg_hba.confファイル [http://www.dbonline.jp/postgresql/ini/index2.html]
Atomの検索で特定のディレクトリを除外する方法

# Atomの検索で特定のディレクトリを除外する方法

検索配下にnode_modulesとかがあると、ファイル数が多くて検索終了までに時間が掛かるので、検索しないディレクトリを指定する方法。
方法は大きく2つ。

## 特定のディレクトリを常に除外する場合

Settingから変更可能。config.csonを直接変更してもよい。

### SettingsのCore内の「Ignored Names」に除外したいフォルダ名を追加する
複数の場合はカンマ区切りで追加する。

<img width="1052" alt="スクリーンショット_2016-12-09_16_53_30.png" src="https://qiita-image-store.s3.amazonaws.com/0/27083/36f787fd-2e86-30d0-56ce-d82bac038f2b.png">

### config.csonのcore.ignoredNamesに以下を除外したいフォルダ名を追加する

複数の場合は配列で追加する。

```cson:config.cson
core:
  'ignoredNames': [
    '.git'
    'node_modules'
  ]
```

## 特定のディレクトリを検索時に指定して除外する場合

### 検索ディレクトリに不要なディレクトリ名の頭に「!」を付けて追加する

<img width="1474" alt="スクリーンショット_2016-12-09_17_11_19.png" src="https://qiita-image-store.s3.amazonaws.com/0/27083/d35a3e6b-9f21-55be-745c-f07dd855a987.png">


([There's no way to exclude paths from a search #149](https://github.com/atom/find-and-replace/issues/149) より引用）
CentOS7 で Caps Lock に Ctrl を割り当てる

#はじめに

GUIのない最小構成のCentOS7でCaps LockにControlを割り当てようとしたらつまづいたのでメモを残しておきます．

CentOSのバージョンは 7.1.1503 です．

```
cat /etc/redhat-release
CentOS Linux release 7.1.1503 (Core)
```

Linuxにあまり詳しくないため，間違いがある場合やより良い方法をご存知の方はコメントをお願いいたします．

#変更方法

変更方法ですが，Caps_LockにControlを割り当てたkeymapを用意し，loadkeysコマンドで変更を反映します．

使用するコマンドの一覧は次の通りです．

```
showkey    #keycodeの確認
dumpkeys   #現在のkeymapを出力する
loadkeys   #keymapをloadする
```


##keycodeを調べる
まずは showkey コマンドによって現在しようしているキーボードのkeycodeを取得します．
showkey コマンドは押した（離した）キーのkeycodeを出力するコマンドです．
また，最後にキーを押した10秒後にコマンドが終了します．

```
$ showkey
kb mode was UNICODE
[ if you are trying this under X, it might not work
since the X server is also reading /dev/console ]

press any key (program terminates 10s after last keypress)...
keycode  28 release    #showkeyコマンド実行時に押したEnterを離した
keycode  58 press      #Caps Lockを押した
keycode  58 release    #Caps Lockを離した
keycode  29 press      #左下のControlを押した
keycode  29 release    #左下のControlを離した
```

以上により，Caps Lockは58，Controlは29であることがわかりました．


##keymapをダンプする

dumpkeysコマンドで現在使用しているkeymapの情報をダンプすることができます．

まずはバックアップをとります．

```
$ dumpkeys > backup.kmap
```

ダンプされたkeymapには 

```
keymaps 0-127
keycode    1 = Escape
...
```

のように keycode 128個の割り当てが設定されています．

keyshowコマンドによってCaps_Lockのkeycodeが58であることが分かったため，keycode 58を変更すれば良いことがわかります．

それでは Caps Lock に　Control を割り当てたkeymapを作成します．

```
$ cp backup.kmap caps_to_ctrl.kmap
$ vim caps_to_ctrl.kmap
```

caps_to_ctrl.kmap の keycode 58 の項目を見てみると次のように書いてあります．

```
keycode  58 = CtrlL_Lock
```

keyshowコマンドでは Control のkeycodeが29であることも分かったため，そちらも確認します．

```
keycode  29 = Control
```

以上より、keycode 58を次のように変更します．

```
keycode  58 = Control
```

あとは変更したkeymapであるcaps_to_ctrl.kmapを読み込むだけです．

#keymapの読み込み

keymapの読み込みは loadkeys で行います．

```
$ sudo loadkeys caps_to_ctrl.kmap
```

以上で割り当ての変更は完了です．

#実行時に自動的に割り当てを変更する

ログイン時に毎回 sudo loadkeys を実行するのは面倒なので，自動的に実行するように設定します．

まずは caps_to_ctrl.kmap を次のディレクトリに移動します．
（任意のディレクトリで問題ありませんが，ユーザのディレクトリ以下に配置するとroot権限でなくても簡単に削除等ができてしまうため，以下が無難だと思います．）

```
$ sudo mkdir /usr/share/keymaps
$ sudo mv caps_to_ctrl.kmap /usr/share/keymaps
```

次に，/etc/rc.local に次の一文を追記します．
rc.local は　boot 時に実行されます．

```
/usr/bin/loadkeys /usr/share/keymaps/caps_to_ctrl.kmap
```

ここで注意ですが，rc.localを良く見ると次のような記述があります．

```
# Please note that you must run 'chmod +x/etc/rc.d/rc.local' to ensure
# that this script will be executed during boot.
```

/etc/rc.d/rc.local に実行権限を与えないと rc.localが実行されず，loadkeysも実行されません．

したがって，次のコマンドを実行します．

```
$ sudo chmod +x /etc/rc.d/rc.local
```

これで設定は完了です．

#まとめ

CentOS7 で Caps Lock に Ctrl を割り当てました．

rc.local に loadkeys を記述したことによって，起動時に自動的に変更が適用されます．

もし変更の際に予想外のミスをしてしまった場合は，最初に作成したバックアップ backup.kmap を loadkeys することで元の keymap に変更することができます．

#参考

以下のサイトが大変参考になりました．

http://lambdalisue.hatenablog.com/entry/2013/09/27/212118
http://superuser.com/questions/290115/how-to-change-console-keymap-in-linux
TECH::CAMP  VRコース受講体験記

#この記事について

この投稿はプログラミングスクールの**[TECH::CAMP](https://tech-camp.in/)**で提供されている、
**[VRコース](http://vr.tech-camp.in/)の受講体験**をまとめたものです。
筆者がコースを受講して得たもの、気づいたものを記事にする事で、
受講を迷われてる方やVR学習に興味のある方の、判断材料の一つになれば幸いです。

#結論
・UnityやC#の開発経験が無い
・VRコンテンツの開発に興味がある
**上記二点の条件を満たす方には受講をお勧めします。**

#１、受講前の理解範囲
・Unity、C#は未経験
・html/css、JSの実務経験あり
・JavaによるAndroidアプリ開発経験が少し（でもオブジェクト指向の理解が曖昧なレベル）



#２、受講した成果
・[オリジナルVRゲーム](https://play.google.com/store/apps/details?id=com.hoge.ZombieShooting)をリリース出来ました。
基礎カリキュラム（後述）を終え、10日程で完成。ゲームアプリを実装する上で必要な最低限のプログラミング知識は、カリキュラムの中で体得出来たので、それを復習しつつ繋げたイメージ。

・Unity、C#の理解が深まった。
初心者向けの書籍に書かれている内容が、「あ〜、アレのことね。」と何となくは解るようになります。今後のコンテンツ作成をする上で必要となる、取っ掛かりを得ることが出来ました。

・メンターの方との人脈を得た。
受講中何人かメンター（講師）の方とFacebookで連絡先交換しました。~~独学中にどうしても解らなかった時は泣き付こうと思います。~~　

#３、受講中の詳細
以下実際に受講中していた時の詳細です。

##３−１、受講期間
１ヶ月コースです。ほぼ毎日渋谷校に通学。

##３−２、カリキュラム範囲
・大きく分けて基礎と応用の2種類です。これらの学習範囲を1ヶ月以内に習得することが目標とのことです。
・教材はTECH::MASTERと呼ばれるWebサイト内に表示されます。

- 基礎カリキュラム(想定学習時間・・・・64時間)
    1. Unity基礎
    2. C#基礎、
    3. 3Dゲーム開発(VR非対応）、
    4. Ray操作（視点対応）
    
- 応用カリキュラム(想定学習時間・・・106時間)
    1. スマホVR対応
    2. 2Dゲームと数学
    3. コルーチン
    4. ライティング
    5. OculusRift対応
    6. HTC-Vive対応
    7. ビルド方法

##3-3、カリキュラムの解りやすさ
・gifアニメーションでの解説で、手順を正しく実装出来る
解りやすさは可もなく不可もなくといったところ。しかしWeb上に教材がある為、重要な点はgifアニメーションを用いて解説されています。それによって学習中に操作手順が解らない、といった事は無かった気がします。

・C#の解説はかなり急ぎ足
変数やメソッドの解説等は解りやすかったですが、基本的に作りながら覚えさせる方針のよう。受講終了後に書籍等で復習した方が良いかもしれません。

・情報量の多さをメンターの解説で補える
全体的に情報量が多く途中で混乱することも。しかし文面が頭に入ってこなくても、メンターに「ここからここの範囲がどういう事か解らない...」とヘルプを出せば、より詳細な解説をしてくるので、不明点が出ても消化しつつ進めます。

##３−4、メンター（講師）の対応
受講者が納得出来るまできちんと分かりやすく解説してくれます。
カリキュラムに関係の無い発展したテーマでも尋ねると快く応対してくれました。

##３−5、実際の学習進捗
以下大体1日8時間ほど学習しているペースでの話です。
・基礎カリキュラムは10日ほどで終了しました。
・応用の内、手をつけたのはスマホVR対応、コルーチン、ライティングの３つ。その3つを3日で終了させました。
・その後はオリジナルゲームアプリの作成へ。10日かけて完成。
・アプリ開発終了後は全体の復習に充てました。

#４、改善を望む点

・リリースについての詳細な手順を追記してほしい
カリキュラムの説明がアプリのビルドまでしか無い。実際にStoreに反映するにはどうすれば良いのかが不明確だった。
※メンターの方にマンツーマンで教えてもらい解決。

・バージョン管理(Github）の概念をセットで
コードを書かせるからにはバージョン管理の概念をセットで教える必要があると思います。特に初心者なら尚更。プログラミング初心者の方に向けて「こんな仕組みもあるよ」っていうレベルでも共有してあげるとより一層親切かと思いました。

・ネットワーク機能やサーバ連携の実装方法を知りたかった
応用カリキュラムにネットワーク対応やサーバ連携させるための実装手順を追記して欲しかったです。
実際追記しようとするとボリュームの都合も出てくるとは思いますが、概要だけでも記載してもらえると嬉しかったです。


#５、有意義に活用する為に
・直接教室に行って、メンターと一緒に学習する
TECH::CAMPではSkypeを利用したリモート相談も利用可能です。
しかし、いざリモート相談しようとすると中々億劫なもの。（実際そうでした）
教室に居れば、エラー解消方法が解らない時や、より詳細な説明を聞きたくなる時に、気軽に何度も尋ねられます。それによって学習スピードを高めることが出来ます。

・基礎カリキュラム+スマホVR対応の学習範囲を速攻で終わらせ、オリジナルゲームを作る
基礎カリキュラム（Unity操作やC#）と応用カリキュラムの一部（スマホVR対応）で身につけた知識があれば、簡単なVRゲームが作れます。出来れば一週間前後で終わらせて、早めにオリジナルゲーム作成に入った方が良いと思います。オリジナルを作ろうとすると全体の復習にもなりますし、何よりも楽しみながら開発出来ます。

#６、まとめ

・ゼロから独学するよりは、[TECH::CAMP](https://tech-camp.in/)の[VRコース](http://vr.tech-camp.in/)へ
受講したことでVRコンテンツ作成に必要な技術を、段階を踏んで、最短距離で取得出来ました。
UnityやC#を触ったことがない、でもVRコンテンツを作りたい！そんな人にお勧めです。

・Unity経験者は下記の書籍で足りるかも
[UnityによるVRアプリケーション開発　作りながら学ぶバーチャルリアリティ入門](https://www.oreilly.co.jp/books/9784873117577/)
オライリーから出版されているVR開発の入門書です。
VRコースを設立した際の参考書籍のようです。
DirectX9とC++11のマルチスレッドを使用して裏画面ロードを実装する話

##今回作るもの
裏で処理しながらローディング画面を出す

## なぜDirectX"9"なのか。
「課題要件」です

## 環境
Visual Studio 2015
DirectX SDK (June 2010)
Intel® Core™ i7-4810MQ 

## 準備
まずはThreadが使用できなければ始まりません。
スレッド数は```std::thread::hardware_concurrency()```で確認できます。
快適なデバックを行うにはmain+VisualStudio+osで3スレッド必要です。
今回専有しないので考慮しませんが、スレッドを専有する場合はosなどの他のプログラムを考慮する必要があります。

```main.cpp
auto count = std::thread::hardware_concurrency();
if (count < 3)
{
    //Err
}
```

## 裏処理
マルチスレッドで処理を行う場合、複数スレッドに跨るデータをスレッドセーフにする必要があります。
今回だとロードの終了を通知するフラグを、スレッドセーフに扱う関数を定義します。

```main.cpp
bool isLoaded = false;
std::mutex isLoadedMutex;

void SetLockFlag(bool _)
{
	std::lock_guard<std::mutex>  lock(isLoadedMutex);
	isLoaded = true;
}

bool GetLockFlag()
{
	std::lock_guard<std::mutex>  lock(isLoadedMutex);
	return isLoaded;
}

void AsyncLoad()
{
    //ダミーで10秒待つ
	auto sleepTime = std::chrono::seconds(10);
	std::this_thread::sleep_for(sleepTime);

	SetLockFlag(true);
}
```

## Thread起動
このステートメントを実行すると同時に非同期関数が起動します。

```main.cpp  
std::thread th(AsyncLoad);
```

## 完了通知
```main.cpp

if (!GetLockFlag())
{
	//ロード中
}
else
{
	//ロード完了
}
```
## 後始末
Threadはそのデストラクタが呼ばれる前に、joinまたはdetachを呼ぶ必要があります。
今回はjoinを行いスレッドが終了するのを待機していますが、detachにすると
Threadのデストラクタ後も関数が走り続けます。

``` main.cpp
th.join();
```

##注意点

・データ競合
データの書き込みと読み込みが同時に行われると発生します。
運が良ければどこかでクラッシュとして拾われますが、悪ければ顕著化せずに埋もれてしまい探し出すのに非常に労力を要します。

・DirectX9のデバイスについて
残念ですが、DirectX9のデバイスはスレッドセーフではありません。
そのため、レンダリングしながら裏で（デバイスを使用した）ロードと言うのは不可能です。

## 参考文献
・DirectXのデバイスのスレッドセーフ性について：
https://msdn.microsoft.com/ja-jp/library/ee422106(v=vs.85).aspx
・データ競合：
http://yohhoy.hatenablog.jp/entry/2013/12/15/204116
・C++11のスレッド:
http://www.slideshare.net/hotwatermorning/c-38563753

## 今回のプロジェクト
https://github.com/Himatyu/Qiita/tree/master/BackGroundTextureLoadDx9
Ansibrest の紹介

この記事は[Ansible Advent Calendar](http://qiita.com/advent-calendar/2016/ansible)の9日目です

うちのチームでは現在、環境の共有も含めて Docker / Ansible を利用しています。
また、新しくサービスを作る際もなるべく docker-compose.yml を最初に作ることで、開発初期から適切な分担で作業をすることができるので、オススメです。
とはいえ、サーバすべてを Docker で運用することはないのでやっぱり ansible は不可欠です。

## Ansible の悲しみ
* Ops/Deploy 用のサーバの ansible と手元の ansible のバージョンの差異
    * サービス A の Ops サーバとサービス B の Ops サーバの ansible でバージョンが違ったりの両方を対応できない
* 実行は Ops または手元のマシンから実行するしか無いが、わざわざ Ops サーバに入りたくない

## Ansibrest
上記を解決するために、以前[ブログ](http://muddydixon.hatenablog.com/entry/2016/03/08/004951)にも書きましたが、 [Ansibrest](https://github.com/muddydixon/ansibrest) というツールを作りました。

[ansible tower](https://www.ansible.com/tower) の機能が少なく、アンオフィシャルバージョンくらいの認識でいいです

その後、社内の開発環境に入れて Mattermost と連携して遊んだりしていたのですが、別件で多忙になり、放置していました。
気がつくと社内ではパッとしないままにもかかわらず「[さくらのナレッジ](http://knowledge.sakura.ad.jp/knowledge/4794/)」で紹介されたりしていました(こないだ知った)。

使ってくださる方がいるなら、と重い腰を上げて、社内での本格利用も検討しながら、必要な機能を追加していきました

* 全面的なリファクタリング
    * lib/ansible.js
* Error メッセージの表示改善
* ExtraVars 対応
* WebSocket による「長い Playbook」に対応
    * こいつがコードを汚くしているのでもう一度リファクタかけ直す予定
* ansible 1.X 系 / 2.X 系の対応
* Dockerize (ansible 2系 同梱)

結構色々、変更したのでぜひお試しください。

## 使い方
### GUI

```zsh
% docker run -d -p 2400:2400 -v $ANSIBLE_PATH:/opt/ansible muddydixon/ansibrest
% docker run -d -p 2400:2400 -v $YOURANSIBRRESTFILE:/opt/ansibrest/.ansibrest \
                           -v $ANSIBLE_PATH:/opt/ansible \
                           muddydixon/ansibrest
```

こんな感じで、 playbook があるディレクトリをボリュームマウントするだけで試すことができるはずです。

![image](https://qiita-image-store.s3.amazonaws.com/0/3379/b4ee413b-d2cb-dfae-ec5a-be1a9c9db26f.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/3379/d3cb8d7f-cba9-e5e4-4695-f2dc71da0917.png)

ちゃんと `ExtraVars` として `{"version": 2}` と入力して実行すると

![image](https://qiita-image-store.s3.amazonaws.com/0/3379/54bf8101-ccef-754f-e088-07955f7454fd.png)

の最後のタスクできちんと反映されています！

### CUI

ansib"rest"の名前をつけているので curl 等で playbook を実行できるようにしてあります。

```zsh
curl -X POST "http://dev.docker.com:2400/api/playbooks/sample1.yml"
{"stdout":"\nPLAY [Sample 1 tasks 1] ********************************************************\n\n\nTASK [setup] *******************************************************************\n\nok: [localhost]\n\n\nTASK [debug] *******************************************************************\n\nok: [localhost] => {\n    \"inventory_hostname\": \"localhost\"\n}\n\n\nPLAY [Sample 1 tasks 2] ********************************************************\n\n\nTASK [setup] *******************************************************************\n\nok: [localhost]\n\n\nTASK [debug] *******************************************************************\n\nok: [localhost] => {\n    \"inventory_hostname\": \"localhost\"\n}\n\n\nPLAY RECAP *********************************************************************\n\nlocalhost                  : ok=4    changed=0    unreachable=0    failed=0   \n\n\n","stderr":""}%       
```

ちゃんと叩けますので、例えば(というかこちらがメインの目的だったのですが)、 Ops サーバにこれをインストールしておくことで、 Slack Command などでデプロイができるようになるのです。勝つる！！！

## 今後
ansible tower に有るような認証用の設定がまだ残念でマウントまたは playbook 内にごにょごにょする必要があるところを直したいと思っています。
強制的に保存するチャンスを得る方法

某所で公開したやり方と全く同じですがこちらにも転載。
**CC2014限定**です。

サンキュー[ねいじ](https://twitter.com/neige_)氏。

***

1.After Effects CC2014を起動する

2.メニューよりヘルプを選択し、「ログを有効にする」にチェック
![AE_chance.png](https://qiita-image-store.s3.amazonaws.com/0/71974/6d450f67-f96c-5e01-218b-c9273c9afd21.png)

3.AEを再起動する

4.メニューよりウィンドウを選択し、「Console」を開く
![AE_chance2.png](https://qiita-image-store.s3.amazonaws.com/0/71974/aa3b1e43-1fff-1404-a7bc-a1ed4a1064a6.png)

5.コンソールウィンドウのCommandフォームに「egg.crash」と入力し、エンターキーを押す
![AE_chance3.png](https://qiita-image-store.s3.amazonaws.com/0/71974/0fb52525-0560-e7bb-879e-1d4a7cf45c6f.png)

6.何回かエラーダイアログが出てくるのでOKを押していってください。そのうち出現します。
![AE_chance4.png](https://qiita-image-store.s3.amazonaws.com/0/71974/409f7d45-171e-a810-1c72-8c1f47aa99b9.png)


以上、お疲れ様でした。
windowとHTMLElementのスクロールの最大値を取得する

それぞれscrollWidthとclientWidthとの差、scrollHeightとclientHeightとの差がスクロールの最大値となります。ここらへん古いブラウザではもうちょっと複雑だったけど今時のブラウザはこれで大丈夫だった。ただしiOS Safariでuser scaleを変化させるとずれます。

[デモ](http://jsdo.it/ksk1015/ElDs)

```javascript:scrollMax.js
// windowなら
var winScrollMaxX = document.documentElement.scrollWidth - document.documentElement.clientWidth;
var winScrollMaxY = document.documentElement.scrollHeight - document.documentElement.clientHeight;

//scrollできる要素なら
var elemScrollMaxX = element.scrollWidth - element.clientWidth;
var elemScrollMaxY = element.scrollHeight - element.clientHeight;
```

Firefoxでは window.scrollMaxX, window.scrollMaxY というプロパティがあり、polyfillっぽく書くと

```javascript:windowScrollMax-polyfill.js
// window.scrollMaxX, window.scrollMaxY polyfill
'scrollMaxX' in window || Object.defineProperties(window, {
    scrollMaxX: {
        enumerable: true,
        get: function(){
            return document.documentElement.scrollWidth - document.documentElement.clientWidth;
        },
    },
    scrollMaxY: {
        enumerable: true,
        get: function(){
            return document.documentElement.scrollHeight - document.documentElement.clientHeight;
        },
    }
});
```

HTMLElementにはFirefoxにもいないので、polyfillというかscrollMaxなプロパティを追加するなら

```javascript:htmlElementScrollMax.js
// add scrollMaxX, scrollMaxY to HTMLElement
'scrollMaxX' in HTMLElement || Object.defineProperties(HTMLElement.prototype, {
    scrollMaxX: {
        enumerable: true,
        get: function(){
            return this.scrollWidth - this.clientWidth;
        },
    },
    scrollMaxY: {
        enumerable: true,
        get: function(){
            return this.scrollHeight - this.clientHeight;
        },
    }
});
```
Laravel5を使う上での個人的メモ

# インストール

```bash
$ laravel new projectname
```

# コントローラ

```bash
$ php artisan make:controller SiteController
```

```bash
$ php artisan make:controller SiteController --resource
```

コントローラ名については単数系で良い様子。

```
x SitesController (複数形)
o SiteController (単数形)
```

[Laravel 5.3 コントローラ: リソースコントローラ](https://readouble.com/laravel/5.3/ja/controllers.html#restful-naming-resource-routes)


# マイグレーション
## 作成

参考: [データベース:マイグレーション](https://laravel.com/docs/5.3/migrations)

```bash
$ php artisan make:migration create_sites
```

```php:projectname/database/migrations/2016_12_09_064707_create_sites.php
public function up()
{
  // テーブルを更新
  // php artisan make:migration add_hogehoge_column_kigyos_table --table=kigyos
  Schema::create('sites', function (Blueprint $table) {
   $table->increments('id');
   $table->string('name', 256)->default(''); // サイト名
   $table->string('url', 1024); // サイトURL
   $table->timestamps();

  });
}

public function down()
{
  Schema::dropIfExists('sites');
}
```

## 更新

スケルトンファイル作成

```bash
$ php artisan make:migration sites_add_email
```

マイグレーションファイル編集

```php:app/database/migrations/2016_12_15_055527_sites_add_email.php
 public function up()
 {
   Schema::table('sites', function (Blueprint $table) {
     $table->string('email')->after('email');
     $table->index( ['name', 'url'] );
   });
 }

 public function down()
 {
   Schema::table('sites', function (Blueprint $table) {
     $table->dropColumn('email');
     // Laravelで作られるインデックスは テーブル名、カラム名、indexをアンダーバーで繋げた文字列
     // 全て小文字
     $table->dropIndex( 'sites_name_url_index' );
   });
 }
```

マイグレーション実行

```bash
$ php artisan migrate
```


## シード
```bash
$ php artisan make:seeder SitesTableSeeder
```

```php:projectname/database/seeds/SitesTableSeeder.php
public function run()
{
  DB::table('kigyos')->insert(
    [
      [
        'name' => 'test1',
        'url'  => 'http://example.com',
      ],
      [
        'name' => 'test2',
        'url'  => 'http://test2.example.com',
      ],
    ]
 );
}
```

# テスト

```bash
$ php artisan make:test SiteTest
```
```php:/tests/SiteTest.php
    /**
     * A basic test example.
     *
     * @return void
     */
    public function testExample()
    {
	    $this->visit('/sites')
	         ->see('index');
    }
```
Laravelで電話番号のバリデーションエラーメッセージの重複を避ける


電話番号など、フォームの項目が分かれている場合、以下のようにバリデーションをかけるとエラーメッセージが重複してしまうので、viewで`array_unique()`で重複メッセージをなくす。

```php
  public function rules()
  {
    return [
      'tel_00' => 'required|numeric|regex:/\A0\d{1,3}\z/',
      'tel_01' => 'required|numeric|digits_between:2,4',
      'tel_02' => 'required|numeric|digits:4',
    ];
  }
  
  public function messages()
  {
    return [
      'tel_00.*' => '・「お電話番号」が無効です。',
      'tel_01.*' => '・「お電話番号」が無効です。',
      'tel_02.*' => '・「お電話番号」が無効です。',
    ];
  }

```

viewはこんな感じ

```php
@if ($errors->any())
    @foreach (array_unique($errors->all()) as $error)
      <p>{{ $error }}</p>
    @endforeach
@endif

```
コマンドラインで不要なBigQueryのテーブルを消す

## あらすじ

検証環境で、不要なテーブルを大量に作ってしまったので一斉に削除したかった。Web画面では、1つづつしか削除できなそう。

## コマンド

検証環境でしかTryしてないので、くれぐれも注意です。awkで正規表現まっち

```
# 削除対象を確認
bq ls -n 1000 dataset | awk '/フィルタ条件/{ print "dataset."$1 }' 

# 削除
bq ls -n 1000 dataset | awk '/フィルタ条件/{ print "dataset."$1 }' | xargs -n 1 -t bq rm -f
```
#ローカル開発環境の作成(LAMP)

# practice_cake

##Vagrant と virtualBox でローカル開発環境を作ることはじめ
php7.0
mariadb
centos7
を想定して作るときのメモ書き。

アプリケーションとしては、
vagrant 
virtualbox
で作成いたします。

## setting php

### make git project
    echo "# [ project name ]" >> README.md
    git init
    git add README.md
    git remote add origin https://github.com/[ User Name ]/[ Project Name ].git
    git push -u origin master

### setting on terminal
*terminal*

    project_dir   $ pwd
    */project_dir
    project_dir   $ mkdir dev

### vagrant setting
*Vagrantfile*

    config.vm.box = "centos/7"
    config.vm.network "private_network" ,ip:"192.168.33.10"
    config.vm.network "forwarded_port" ,guest: 80 ,host: 8181
    config.vm.synced_folder "./dev" , "/vagrant_dev"

*on terminal*

    project_dir $ vagrant up
    project_dir $ vagrant ssh

    vagrant@localhost $ sudo su -
    root@localhost    $ timedatectl set-timezone Asia/Tokyo
    root@localhost    $ yum -y install httpd.service
    root@localhost    $ systemctl start httpd.service
    root@localhost    $ getenforce
        Enforcing
    root@localhost    $ setenforce 0
    root@localhost    $ cd /etc/selinux
    root@localhost    $ vi config
    root@localhost    $  yum -y install epel-release.noarch
    root@localhost    $ rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
    root@localhost    $ rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
    root@localhost    $ yum -y install php70.x86_64
    root@localhost    $ yum -y install php70-php.x86_64
    root@localhost    $ yum -y install php70-php-mysqlnd.x86_64
    root@localhost    $ yum -y install mariadb.x86_64 
    root@localhost    $ yum -y install mariadb-server.x86_64


*/etc/selinux/config*

    # This file controls the state of SELinux on the system.
    # SELINUX= can take one of these three values:
    #     enforcing - SELinux security policy is enforced.
    #     permissive - SELinux prints warnings instead of enforcing.
    #     disabled - No SELinux policy is loaded.
    # SELINUX=enforced
    SELINUX=permissive
    # SELINUXTYPE= can take one of three two values:
    #     targeted - Targeted processes are protected,
    #     minimum - Modification of targeted policy. Only selected processes are protected. 
    #     mls - Multi Level Security protection.
    SELINUXTYPE=targeted
S3上にあるgzファイルをIOに乗せて処理

```ruby
s3_cli = Aws::S3::Client.new(region: 'れぎおん', endpoint: "えんどぽいんと")
IO.pipe do |read_io, write_io|
  write_io.binmode
  Thread.new do
    begin
      s3_cli.get_object(bucket: 'ばけっと', key: 'ふぁいるぱす') do |chunk|
        write_io.write(chunk)
      end
    rescue => ex
      write_io.close
      raise ex
    end
  end
  gz = Zlib::GzipReader.new(read_io)
end
```

あとはgzを好きなようにすれば良い。
/tmpとかにDL→解凍→readってやるのがなんか気に食わない場合とかにぜひ。
Ruby on Rails アプリケーションを Dockerで動かす


# 前提
- Alpine 3.4
- Ruby 2.3.3
- Rails 5.0.0.1

Railsアプリケーションと、GemfileとGemfile.lockは、事前に用意してあるものとします。

# Dockerfile
```
FROM ruby:2.3.3-alpine
MAINTAINER Shigeru Nakajima <shigeru.nakajima@gmail.com>

ENV BUILD_PACKAGES="curl-dev ruby-dev build-base bash" \
    DEV_PACKAGES="zlib-dev libxml2-dev libxslt-dev tzdata yaml-dev sqlite-dev postgresql-dev mysql-dev" \
    RUBY_PACKAGES="ruby-json yaml nodejs"

# Update and install base packages and nokogiri gem that requires a
# native compilation
RUN apk update && \
    apk upgrade && \
    apk add --no-cache --update\
    $BUILD_PACKAGES \
    $DEV_PACKAGES \
    $RUBY_PACKAGES && \
    mkdir -p /usr/src/app

# Copy the app into the working directory. This assumes your Gemfile
# is in the root directory and includes your version of Rails that you
# want to run.
WORKDIR /usr/src/app
COPY . /usr/src/app
EXPOSE 3000
RUN bundle config build.nokogiri --use-system-libraries && \
            bundle install && \
            bundle clean

CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]
```

## 実行

```
docker build -t hogehoge .
docker run --rm hogehoge
```

で起動します(hogehogeは適当です)。


## どのようにして作ったか？
[alpine-rails/Dockerfile at master · alim/alpine-rails](https://github.com/alim/alpine-rails/blob/master/Dockerfile)を元にしました。

### 変更点
#### ベースイメージ
Ruby 2.3.3にします。

```
FROM ruby:2.3.3-alpine
```
[centurylink/alpine-rails](https://hub.docker.com/r/centurylink/alpine-rails/)をベースイメージにすることも考えましたが`alpine:3.2`だったのでやめました。


### apkパッケージのインストール方法
[Alpine Linux で軽量な Docker イメージを作る - Qiita](http://qiita.com/pottava/items/970d7b5cda565b995fe7)

> Alpine Linux は 3.3 から apk で --no-cache というオプションが使えます。

`apk add`に`--no-cache`オプションを追加します。

```
rm -rf /var/cache/apk/*
```
を削除します。

### onbuildをなくす
直接docker buildするために22行目以降の`ONBUILD`指定を消します。
消さないとGemfileがコピーされていないので、`docker run`時に次のエラーが出ます。

```
Could not locate Gemfile or .bundle/ directory
```



### 実行コマンドを修正
bundler経由で起動したいので

```
CMD ["rails", "server", "-b", "0.0.0.0"]
```
を

```
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]
```
に修正します。

修正前は、`docker run`時に次のエラーが出ます。

```
docker: Error response from daemon: invalid header field value "oci runtime error: container_linux.go:247: starting container process caused \"exec: \\\"rails\\\": executable file not found in $PATH\"\n".
```


# 参考情報
- [Dockerでruby/alpineを使ってrails+mysql+redisの環境作成 - Qiita](http://qiita.com/magaya0403/items/ee4d4aac629e83d84288)
- [DockerfileのONBUILD | SOTA](http://deeeet.com/writing/2014/03/21/docker-onbuild/)
- [Running a Rails Development Environment in Docker | via @codeship](https://blog.codeship.com/running-rails-development-environment-docker/)
[Linux][RPM] RPMパッケージの情報を確認する

rpmのインストール後のパッケージの依存調査とかで毎回調べるのでまとめました。
他にもコンフィグやドキュメントの抽出条件などもありましたが、基本的に使わないと思われるので省略してます。

# よく使うコマンド例
## インストール済みのパッケージ一覧を表示

```console:環境にインストール済みのパッケージ一覧を表示
$ rpm -qa
```

## パッケージの情報を表示

```console:パッケージの情報を表示
$ rpm -qi {package name}
```

## パッケージでインストールされたファイル一覧を表示

```console:パッケージでインストールされたファイル一覧を表示
$ rpm -ql {package name}
```

## ファイルがどのRPMパッケージに入っているかを調べる

```console:ファイルがどのRPMパッケージに入っているかを調べる
$ rpm -qf {file path}
```

# 関連
[RPMをインストールせずにカレントディレクトリ以下に展開する - Qiita](http://qiita.com/koara-local/items/90c0f2d7bd3865d55cdc)

# 参考
[RPMパッケージの情報を調べるには](http://www.atmarkit.co.jp/flinux/rensai/linuxtips/050inforpm.html)
[- 株式会社エスロジカル - 技術ドキュメント Linux：rpmによってインストールされたファイル一覧を確認する](https://www.slogical.co.jp/tech/rpm_showfiles_installedbyrpm.html)
[個人的によく使うrpmコマンド逆引き ｜ Developers.IO](http://dev.classmethod.jp/server-side/rpm-reverse-search/)
Amazon Dash Buttonは低い受信レートが有効なWi-Fiアクセスポイントでないと繋がらない

## 結論

受信レート 1Mbps, 2Mbps, 5.5Mbps のいずれかが有効でないと繋がらない。

## WLX302の受信レート設定について

某所設置のAmazon Dash ButtonがヤマハWLX302にWi-Fi接続できなかった。
/WPA2?-PSK/ で接続可能な普通のVAPを設定しているのにおかしいなあと思ってたが、よく考えると受信レートをいじっていたのだった。

Web管理画面で言うと `無線設定` → `2.4GHz詳細` → `受信レート` のところ。`1Mbps` `2Mbps` `5.5Mbps` のどれか1つ以上を `Basic Rate` または `Option Rate` のいずれかに設定すれば動く。
![pasted_image_at_2016_12_09_11_55.png](https://qiita-image-store.s3.amazonaws.com/0/46275/01a8d54b-343b-4909-52f4-dc242d46a652.png)

コマンドで言うと、例えば以下の通り。(これがデフォルトのはず)

```text:WLX302
airlink select module1
 airlink mode 11b+g+n
 airlink channel auto
 airlink receive rate basic 0 1 2 3 4 5  # ココ
airlink enable module1
```

おそらくAmazon Dash Buttonは低消費電力化するために低ビットレートでのみ通信できるように作ってあるのだろう。

## 教訓

よく理解しないまま「詳細」項目のデフォルト設定をいじってはならない。

## 参考

[WLX302 遅い端末の接続を拒否する設定例 | ヤマハの音とネットワーク製品を語る](http://projectphone.lekumo.biz/blog/2016/02/wlx302-d708.html)