OmniAICreator/Qiita-1.07M huggingface dataset:
Fitbit Web APIとPHP7で心拍数を取得しよう

Fitbit Web APIとPHP7で心拍数をブラウザに表示するサンプルコードを書きました。この記事では、サンプルコードの動作方法を共有します。

サンプルコードはGitHubからダウンロードしてください
GitHub: https://github.com/code-of-design/fitbit-heartrate-php

## 準備するもの
- Fitbit端末
    - 筆者はFitbit Charge 2を使用
- Fitbitアプリ
    - 筆者はiOS版「Fitbit」を使用
    - Android版/Windows10版でもOK
    - ブラウザ版のFitbitダッシュボードはNG（データ同期の都合上）
- ブラウザ
    - 筆者はMacbookのGoogle Chromeを使用 
- ローカルWebサーバ
    - 筆者はDockerを使用
    - XAMPPでもOK


## Fitbitアプリの設定
Fitbit端末とFitbitアプリはBluetooth LEでデータを通信します。この記事では、ほぼリアルタイムで心拍数を取得するので、Fitbitアプリの端末設定で「常に同期」をオンにします。

※「常に同期」状態はFitbit端末のバッテリーを多く消耗するので注意してください。

<img width="300" alt="IMG_0702.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/179909/7a50f4f7-9b26-c825-46a2-5cfcbc2d3512.png">


## dev.fitbit.comで開発用アプリケーションの登録
https://dev.fitbit.com/apps/new にアクセスし、開発用アプリケーションを登録します。

![スクリーンショット 2017-10-09 13.59.41（2）.png](https://qiita-image-store.s3.amazonaws.com/0/179909/d025375f-673d-be80-82b3-028d83dfe888.png)

- Application Name、Description、Application Website、Organization Websiteは適当に入力してください
- OAuth 2.0 Application typeは必ず**Personal**を選択してください
- Callback URLはサンプルコードではhttp://localhost:8888/callback.php にします（XAMPPの場合はhttp://localhost:80/callback.php にしてください）
- Default Access TypeはRead-Onlyにします

「Register」ボタンをクリックすると、Applications I registeredページに移動します。


## OAuth 2.0認証の設定
Applications I registeredページの情報に基づき、サンプルコードのenv.phpファイルを編集します。

![スクリーンショット 2017-10-09 13.59.55（2）.png](https://qiita-image-store.s3.amazonaws.com/0/179909/7b4298a6-f7ff-36cc-5ef4-45b84c9cbb09.png)


![スクリーンショット 2017-10-09 14.00.40.png](https://qiita-image-store.s3.amazonaws.com/0/179909/c179aa45-3dd2-ea5d-ef4f-3d06310ac9e5.png)

- CLIENT_IDはOAuth 2.0 Client IDの値に変更してください
- CLIENT_SECRETはClient Secretの値に変更してください
- CALLBACK_URLはCallback URLの値に変更してください
- AUTH_URL、TOKEN_URLはそのままでOKです

サンプルコードのenv.phpファイルの編集ができたら、Applications I registeredページの　「OAuth 2.0 tutorial page」をクリックしてしてください


## OAuth 2.0 tutorial page
OAuth 2.0 tutorial pageに移動したら、1: Authorize内の- We've generated the authorization URL for you, all you need to do is just click on link below:以下のアドレスをクリックしてください。Fitbit Web APIの認証ページに移動します。

![スクリーンショット 2017-10-09 14.00.58（2）.png](https://qiita-image-store.s3.amazonaws.com/0/179909/8b8e517d-d3e8-3db4-a51e-6775aa81a47c.png)

<br>
Fitbit Web APIの認証ページに移動したら、「認可」ボタンをクリックしてください。

![スクリーンショット 2017-10-09 14.01.09（2）.png](https://qiita-image-store.s3.amazonaws.com/0/179909/7aa37347-39c8-edd8-199c-274e7017d526.png)

認可が完了するとサンプルコードのcallback.phpに移動します。
これでサンプルコードからFitbit Web APIを利用する準備が整いました。

![スクリーンショット 2017-10-09 15.14.42（2）.png](https://qiita-image-store.s3.amazonaws.com/0/179909/16c7bc87-16df-c9da-9cc4-3dcce70abea7.png)

## 心拍数をブラウザに表示する
新しいタブを開き、http://localhost:8888/ にアクセスします。（XAMPPの場合は、http://localhost:80/ ）

![スクリーンショット 2017-10-09 14.01.41（2）.png](https://qiita-image-store.s3.amazonaws.com/0/179909/a7e046f6-a7a4-d832-531f-4d5f47a045dd.png)

最後に同期された時間と心拍数が表示されます。

![スクリーンショット 2017-10-09 14.01.47（2）.png](https://qiita-image-store.s3.amazonaws.com/0/179909/fa1f905f-448b-9ade-2f93-8b897c6e9db7.png)
CISCO 6500/7600 シリーズの初期化でハマったこと

表題どおりです。
CISCOの最上位機種として有名な6500/7600シリーズですが、少々クセがあったようなので個人的メモとして残します。

## やりたかったこと
エンクロージャ型のCISCO 6500シリーズを初期化したい
(startup-configの削除)

## ハマったこと
CISCO通例?のbreakシーケンスを発信してrommonプロンプト上にてconfreg 0x2142コマンドを発行しても
NVRAM上のstartup-configが読み込まれてしまう。

## 解説
上記のconfregに関しては他の方もまとめていらっしゃるようなので省略いたします。
そもそもの前提知識として本製品群の特徴を記します。
Switch Processor(スイッチプロセッサ、以下SP)とRoute Processor(ルートプロセッサ、以下RP)に別れています。
順番としてはSP→RPとなります。

まず、本手順の重要なポイントとしましては、breakシーケンスのタイミングにあります。
SP時にbreakシーケンスを送ってもrommon(ロムモニタ)プロンプトに入れることは入れます。
ただし、ここでconfregコマンドを発行しても最終的にbootされるRPで発行されていないのでコマンドは無効になります。
コマンドを発行すべき"タイミングが異なる"のです。

## 不適切なタイミング
電源を入れてすぐにbreakシーケンスを送りまくる
(Startシリーズなど下位グレードの製品ではこれが正解)

## 最適なタイミング
電源を入れる
↓
ターミナル上にダイアログが表示されるが大人しく待つ
↓
```%OIR-6-CONSOLE: Changing console ownership to route processor```
上記の出力がターミナル上にされたことを確認してbreakシーケンスを発信。
↓
rommonプロンプトに移行したらconfregコマンドを実行

## コンフィギュレーションレジスタの値について
よくコンフィギュレーションレジスタの値を0x2142に変更しろとありますが何を意味しているのかをおさらいします。
 [CISCO公式ページ](https://www.cisco.com/c/ja_jp/support/docs/routers/10000-series-routers/50421-config-register-use.html "CISCO公式ページ")からのコピペですが。
(あまり解説などがされないまま、おまじないとして使われてしまっているので)

そもそも0x2142は下記の内容になります。
- ブレークの無視
- 初期ブートが失敗した場合は ROM へのブート
- 9600 コンソール ボーレート
- Non-Volatile RAM（NVRAM; 不揮発性 RAM）の内容の無視（設定の無視）

上記の設定を行うことにより、NVRAM上のstartup-configを無視する結果となるわけです。

## まとめ
むやみやたらとbreakシーケンスを連打すればいいというのは間違いで、
適切なbootタイミングにて行うことが重要となる。

## 参考先リンク各所
-  [シスコサポートコミュニティ](https://supportforums.cisco.com/t5/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%A4%E3%83%B3%E3%83%95%E3%83%A9%E3%82%B9%E3%83%88%E3%83%A9%E3%82%AF%E3%83%81%E3%83%A3-%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%88/catalyst-6500-%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA%E3%82%B9%E3%82%A4%E3%83%83%E3%83%81-%E3%82%84-cisco-7600-%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA%E3%83%AB%E3%83%BC%E3%82%BF%E3%81%A7%E3%81%AE%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89%E3%83%AA%E3%82%AB%E3%83%90%E3%83%AA/ta-p/3116813 "シスコサポートコミュニティ")
- [シスコトラブルシューティングテクニカルノーツ](https://www.cisco.com/c/ja_jp/support/docs/routers/10000-series-routers/50421-config-register-use.html "シスコトラブルシューティングテクニカルノーツ")
Homebrewで「The GitHub credentials in the macOS keychain may be invalid.」エラー発生

brewコマンド実行時にGitHub周りでエラーが発生したので対処した話。

#エラー内容

```shell-session
$ brew search tree                                                                                                                                 ✘ 1
==> Searching local taps...
mvptree                            pstree                             tree ✔                             treecc                             treefrog
==> Searching taps on GitHub...
Error: GitHub
The GitHub credentials in the macOS keychain may be invalid.
Clear them with:
  printf "protocol=https\nhost=github.com\n" | git credential-osxkeychain erase
Or create a personal access token:
  https://github.com/settings/tokens/new?scopes=gist,public_repo&description=Homebrew
and then set the token as: export HOMEBREW_GITHUB_API_TOKEN="your_new_token"
```

#対応

~~「キーチェーンアクセス」アプリから「github.com」のエントリを削除。~~

コメントでご指摘頂きまして、アプリから手動削除するより以下のコマンドを実行しましょう。

```shell-session
$ printf "protocol=https\nhost=github.com\n" | git credential-osxkeychain erase
```
静的Webサイト検品ガイド 2019


Webサイトを制作後、納品前、公開前に必ず検品を行います。ブラウザチェックは実機が理想ですが、ないものについてはChromeのシミュレータやVirtual Box による仮想環境で確認してください。

## 検品項目一覧

下記項目をチェックし、基準を満たせばかなり質の高いWebサイトであると言えます。

検品項目|概要|合格基準
---|---|---
ブラウザチェック|さまざまなブラウザでの表示、動作チェック|表示崩れや動作バグがないこと
[HTML Validator](https://validator.w3.org/)|HTML品質チェック|エラーがない状態にする(外部ソースは除く)
[CSS Validator](https://jigsaw.w3.org/css-validator/)|CSS品質チェック|エラーがない状態にする(外部ソースは除く)
[Lighthouse](https://chrome.google.com/webstore/detail/lighthouse/blipmdconlkpinefehnmjammfjpmpbjk)|総合チェック|レッドがないこと
[Page Speed Insights](https://developers.google.com/speed/pagespeed/insights/?hl=ja)|パフォーマンス改善|PC, SPともにグリーンスコア
[モバイルフレンドリー](https://search.google.com/test/mobile-friendly?hl=ja)|スマホ対応|エラーがない状態
[シェアデバッカー](https://developers.facebook.com/tools/debug/)|SNSシェア時にサムネイルなど表示するタグ|エラーがない状態
[構造化データテストツール](https://search.google.com/structured-data/testing-tool)|SEO対策|エラーがない状態
[Test My Site](https://testmysite.withgoogle.com/intl/ja-jp)|表示速度と同業比較|要改善でないこと
[AMPテスト](https://search.google.com/test/amp)|AMPの場合|エラーがないこと

### その他見落としがちなチェック項目

- favicon, スマホhome画面用アイコンは設置されているか
- titleは正しく設定されているか
- Sitemapは設置されているか

## ブラウザチェック

理想はネイティブ端末でのチェックですが、環境がない場合は以下のツールを使いましょう。

- [Chrome DevTools](https://developers.google.com/web/tools/chrome-devtools/device-mode/?hl=ja)- とりあえずの端末チェック
- [Xcode](https://developer.apple.com/jp/xcode/) - より正確なiOS端末のチェック
- [Android Studio](https://developer.android.com/studio/?hl=ja) - より正確なAndroid端末のチェック
- [VirtualBox](https://www.virtualbox.org/)([OS](https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/)) - IE系のチェック

## OSバージョン、ブラウザバージョンについて

最近のOSは自動的に最新OS,ブラウザがアップデートされるため、特に定めがない場合最新OS,ブラウザでの検品で良いです。古いブラウザについてはバージョンアップを促すメッセージを表示させるのが理想です。サポート対象外のブラウザを使用することはセキュリティの観点から推奨されないため、適宜クライアントを説得しましょう。幅広い年齢層の不特定多数のユーザーの利用が見込まれるサイト、サービスにおいては下記ページを参考に適宜古いOS、ブラウザ対応を行いましょう。

- [ブラウザ別シェア](https://lab.syncer.jp/Statistic/Browser/2017/10/)
- [iOSシェア](https://developer.apple.com/support/app-store/)
- [Androidシェア](https://developer.android.com/about/dashboards/index.html)
Docker for Mac インストール時に Fatal Error: Communication with networking components failed

# この記事はなに？
表題の問題への対処法を記載します．

# 現象
Docker for Mac をインストールしようとすると，

```
Fatal Error: Communication with networking components failed
```

というエラーでこけることがあります．詳細を表示すると

```
/var/tmp/com.docker.vmnetd.socket does not exist
```

などと出てます．

# 対処法
このエラーを引き起こす原因は2つあります，僕は以下のその1のみ試してその2の存在に気付かなかったためずっと困ってました．

## その1
[この issue](https://github.com/docker/for-mac/issues/107) などを参照し以下のコマンドを走らせます．

```(bash)
$ sudo chown root:wheel /Applications/Docker.app/Contents/Resources/com.docker.vmnetd.plist
$ cd /Library/LaunchDaemons
$ ln -s /Applications/Docker.app/Contents/Resources/com.docker.vmnetd.plist
```

以下のその2の場合を除いてこれで治るかと思います．

## その2
その1を試しても相変わらずエラーを吐くことがあります．結論から言うと，死ぬほどしょうもないのですが `/var/tmp` に `com.docker.vmnetd.socket` を置きたいのにそもそも `/var/tmp` が存在しないことが原因でした．

```
$ ls /var/tmp
```

としてみて，`ls: /var/tmp: No such file or directory` などと出たらビンゴです．以下のように作成することで解消できます．

```
$ sudo mkdir -p /var/tmp
```

# 終わりに
本当にしょうもないのですが意外とハマったので書き残しておきます．そもそも自分の Mac に `/var/tmp` なかったことにも驚きですが，それ以上に sudo 渡してるのにディレクトリ作ってくれない docker 氏…って感じですね．以上です．

# 参照
- https://github.com/docker/for-mac/issues/107
- https://github.com/docker/for-mac/issues/8
githubに間違ってpushしてしまった時の特定のファイル削除法

`git filter-branch -f --index-filter 'git rm --ignore-unmatch ファイル名' HEAD`

コミット履歴から削除したいファイル名の指定。

`git push --force origin master`

このコマンドで削除したいファイルを指定していけば、github上の指定ファイルだけコミット履歴から消えます。便利。助かった。
Cで二次関数の変域を計る

#Cで二次関数の変域を計る
二次関数の変域は`y = ax^2`として、xの変域がpからqである時のyの変域を求めよ。という問題が出ます。
そこで変域を計る公式として

```math

a(p + q)

```

こんなものが存在します。
本当は学校で習わないらしいんですけど、数学の先生がこっそり教えてくれましたw

#プログラムを組む
##変数を宣言
いつものように変数を用意します

```main.c
int a;  //aの部分
int p,q;  //xの変域
int kotae;  //yの変化数
```

##問題のデータを収集
`printf`で入力を促します

```main.c

    printf("y = ax^2 のaを入力してください\n");  //aの入力を促す
    
    printf("a = ");
    scanf("%d", &a);  //aのデータを収集
    
    printf("xの変域を入力してください\n小さい方 = ");  //xの変域の入力を促す
    scanf("%d", &p);  //xのデータを収集
    
    printf("大きい方 = ");  //変域の大きい方の数字を入力を促す
    scanf("%d", &q);  //変域の大きい方のデータを収集

```

もうなんか毎度同じ流れすぎますねw

##本格的な計算
あの公式を使って解いていきます

```main.c

    //公式の計算を実行
    
    kotae = p + q;  //変域をたす
    kotae *= a;  //さらにaをかける

```

##答えを出力
問題を解いたら答えてもらわないと困りますねw

```main.c

printf("yの変域は%dです" , kotae);  //答えを出力

```

筆者はここで凡ミスをしてしまいまぁまぁ面倒なことになりました。

##ソースコード

```main.c

#include <stdio.h>

int main() {
    int a;  //aの部分
    int p,q;  //xの変域
    int kotae;  //yの変化数
    
    printf("y = ax^2 のaを入力してください\n");  //aの入力を促す
    
    printf("a = ");
    scanf("%d", &a);  //aのデータを収集
    
    printf("xの変域を入力してください\n小さい方 = ");  //xの変域の入力を促す
    scanf("%d", &p);  //xのデータを収集
    
    printf("大きい方 = ");  //変域の大きい方の数字を入力を促す
    scanf("%d", &q);  //変域の大きい方のデータを収集
    
    //公式の計算を実行
    
    kotae = p + q;  //変域をたす
    kotae *= a;  //さらにaをかける
    
    printf("yの変域は%dです" , kotae);  //答えを出力
}

```

今回は習いたてほやほやの単元でしたwありがとうございました。
Djangoメモ　環境構築編


##前提条件
・python 3.x のインストール
　－コマンドプロンプトから「python --version」で確認できる

##環境構築

・環境をインストール
```pip install virtualenvwrapper-win```

・プロジェクト用の仮想環境を作成
```mkvirtualenv myproject
workon myproject
```

###Djangoのインストール
```pip install django```
　⇒これで最新versionがインストールできる

####※Djangoが古い場合は削除
```python -c "import django; print(django.__path__)"```


###プロジェクトの作成
コマンドプロンプトでコードを置きたい場所（ドキュメントなど）を指定し、以下を実行。
```django-admin startproject mysite```
※「mysite」部分は任意のプロジェクト名に変更する

###start projectで作成されたファイルの概要
mysite:プロジェクトの名前。好きに変更できる。
manage.py:コマンドラインユーティリティ
mysite/__init__.py:pythonパッケージであることを知らせる空のファイル
mysite/setting.py:設定ファイル
mysite/urls.py:目次、URLを宣言する場所
mysite/wsgi.py:WSGI（Web Server Gateway Interface）。WEBブラウザに表示させるために必要。


###開発用サーバーの起動
```python manage.py runserver```
manage.pyがあるmysiteディレクトリ内で上記コマンドを実行すると開発サーバーが起動する。
http://127.0.0.1:8000/
にアクセスすることができればOK。
Ctrl＋cでサーバーを閉じることができる。



##参考にしたページ
[はじめての Django アプリ作成、その 1](https://docs.djangoproject.com/ja/1.11/intro/tutorial01/)
[Windows での Django のインストール方法](https://docs.djangoproject.com/ja/1.11/howto/windows/)
Array<独自クラス> で特定メンバ変数のsumを出す

## 経緯
Realmで取得したクラスの配列でInt型のメンバ変数の sum を出したかったのですが、
一工夫必要だったのでメモがてら残しておきます

#実例
##前提
sectionData: realmに入れてるデータクラスの配列
gain       : realmに入れてるデータクラスのうち、Intのデータ

## サンプルコード
やっていることとしては、各要素の中で、
必要な値だけの配列を作ってやって、それからreduceをする

```
let gains = sectionData.map{ $0.gain }.reduce(0){
    $0 + $1
}
```
#メモ
###本当はこんな感じでできたらいいのに/できるはず？
```
let gains = sectionData.reduce(0){
    $0.gain + $1.gain
}
```
結構色々調べながら上記のようなreduceのワンライナーでできないか
色々試したのですが、だめでした。
なぜこれでできないのか、後日調査します。

#追記
コメントで頂いた記述がもっとスッキリしていたのでこちらのほうがいいです。

```
let gains = sectionData.reduce(0){
    $0 + $1.gain
}
```
【zsh】curlでURLクエリ付きでGETしようとすると「no matches found」になるとき

- Ubuntu
- zsh
- curl

↓で解決。深入りはしていない。

```
setopt nonomatch
```

【shell】zshでno matches found。 - 訳も知らないで http://shirusu-ni-tarazu.hatenablog.jp/entry/2013/01/18/034233
IFTTTを使ってGoogle HomeからLineを送信する


GoogleHome（Google Assistant）はIFTTTに対応しているため、IFTTTを使ってさまざまなサービスと連携することができる。これはLineによるメッセージ送信の例。


# 概要
## ゴール
GoogleHomeに「LineでXXXと送って」というと、自分宛てにLineを送信する。

## 手順
IFTTTのレシピはif 「this」 then「that」という形式で設定する。
- 「this」側に「GoogleAssistant」を設定
-  「that」側に「Line」を設定
以下のスクリーンショットのとおり、スマホだけで簡単に定義できる。

# 実際の手順

「this」側にGoogleAssistantを選択する。

![IMG_4067.PNG](https://qiita-image-store.s3.amazonaws.com/0/206394/2c70c407-dbfc-45a6-dc01-9e8b00be070c.png)

GoogleAssistantでは４つのトリガを選択することができる。
- 今回は、「Say a phrase with a text ingredient」を選択する。

![IMG_4068.PNG](https://qiita-image-store.s3.amazonaws.com/0/206394/698dfc69-db8c-cb0b-5aad-1c159e8cde81.png)

トリガとなるフレーズ（どのように言ったらこのルールが発動させるか）を登録する。
- ３通りのフレーズを登録できる
- 可変部分は「＄」で表現する

ここでは
-「lineで$と送信」
-「lineに$と送って」
の２通りを登録している。

![IMG_4069.PNG](https://qiita-image-store.s3.amazonaws.com/0/206394/2c28501b-efd0-9bb8-1c29-2b31eed56f9b.png)

GoogleAssistantからの応答文と、言語を選択する。
ここでは
-「lineに$と送信します」と応答させている
- 言語は日本語を選択

![IMG_4070.PNG](https://qiita-image-store.s3.amazonaws.com/0/206394/0dfa650a-fecb-50ec-bedf-78e8d99d271d.png)

「That」側にLineを選択する。
IFTTTとLineの連携設定ができていない場合、初回のみ設定が必要となる。
- Lineに登録したメールアドレスとPWで連携設定する
- Lineにメールアドレスを登録していない場合は、Line側で登録する
![IMG_4072.PNG](https://qiita-image-store.s3.amazonaws.com/0/206394/ad5528b8-3905-f39a-27c6-0dd258b94bf4.png)

Lineに送信するメッセージ内容を指定する。
ここではデフォルトの設定ママとしている。

![IMG_4073.PNG](https://qiita-image-store.s3.amazonaws.com/0/206394/6570fa8c-5b4e-14b0-965b-807693a32f5c.png)

これでレシピが完成。

![IMG_4074.PNG](https://qiita-image-store.s3.amazonaws.com/0/206394/59326783-d10c-8986-68e9-0ba614031af9.png)

GoogleAssistantでの動作確認

![IMG_4075.PNG](https://qiita-image-store.s3.amazonaws.com/0/206394/860014e0-43d9-0088-e0be-6e5658244add.png)

GoogleHomeに話しかけても同じように動作する（動画は割愛）。
SRE本まとめ（16章 サービス障害の追跡）

自分の理解を深めるためにまとめてみました。[15章](https://qiita.com/bassbone/items/11862caadd185c85889b)の続きです。

## 16章 サービス障害の追跡

### Escalator
「Escalator」はSREに対する全てのアラート通知の個人毎の通知の受信確認を追跡している。一定時間後に受信しない場合はプライマリからセカンダリにエスカレーションされる。

### Outalator
「Outalator」では複数のキューを手作業で切り替えることなく、通知の時系列のリストをまとめてひと目で見ることができる。同じ内容の複数のアラートを集約してくれる。タグ付けすることができ、自動的にリンクになる。過去の対応事例が照会できたり、統計によって週／月／四半期毎の集計が可能である。本来の意図とは違う使われ方をされるケースがあり、予想外のメリットが生み出されている。

（[17章](https://qiita.com/bassbone/items/3b7a6e90000a9a602eef)に続く）
.htaccessに<Limit>を書くと古いバージョンのApacheでOptionsBleedの対象となりえる

※ 内容に誤りがあればご指摘お待ちしております。 ※


* [Apache HTTP サーバに存在する脆弱性「OptionsBleed」 | トレンドマイクロ セキュリティブログ](http://blog.trendmicro.co.jp/archives/16069)


> 影響を受ける Apache HTTP サーバのバージョンは、2.2.34 以下の2.2.x、2.4.27 以下の2.4.x です。この脆弱性に対する更新プログラムは、多くの Linux ディストリビューションで既に公開されています。

CentOS 6 だと`yum update`後は
`httpd-2.2.15-60.el6` と、2.2.34より低いが、独自でパッチが当たっているのかな。
CentOS 5 をまだ使っている場合は .htaccessで \<Limit\>ディレクティブを使っていないことを確認。


## OptionsBleedが該当する設定について

`.htaccess` 内に [Limit ディレクティブ](http://httpd.apache.org/docs/2.4/ja/mod/core.html#limit)を記述している場合とのこと。
Limitディレクティブとは以下のようなものです。

```apache:.htaccess
<Limit POST PUT DELETE>
Require valid-user
</Limit> 
```

Limitディレクティブとは、POSTしか受け付けないとか指定ができる項目のこと。
ちなみにメソッド名は 大文字小文字を区別します。


## アクセス制限の記述(Order, Allow, Deny) は今回の対象ではないので誤解しないように。

* [SonicALERT: "OptionBleed" memory disclosure vulnerability in Apache (Sep 22, 2017)](https://www.mysonicwall.com/sonicalert/searchresults.aspx?ev=article&id=1082)などを見ると、
以下のようなサンプルを目にする。

```sh:サンプル
Allow: ,GET,,,POST,OPTIONS,HEAD,,
Allow: POST,OPTIONS,,HEAD,:09:44 GMT
Allow: GET,HEAD,OPTIONS,,HEAD,,HEAD,,HEAD,, HEAD,,HEAD,,HEAD,,HEAD,POST,,HEAD,, HEAD,!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
Allow: GET,HEAD,OPTIONS,=write HTTP/1.0,HEAD,,HEAD,POST,,HEAD,TRACE
```

Allow と目にするとすぐアクセス制限の記述(Order, Allow, Deny)を思い出しますが、今回は関係ないので誤解なきよう。

```sh:.htaccess
order allow,deny
allow from all
deny from ppp01.aaa.ne.jp
deny from .bbb.co.jp
deny from 130.90.
```
proxmox5でnode名を変更する

## 手順

* /etc/hostname
* /etc/hosts
* /etc/aliases
* /etc/postfix/main.cf

のホスト名を修正し、OS再起動。

ホスト名を old から new に変更した場合、以下。


```sh:ダメな例
cp -a /etc/pve/nodes/old/qemu-server/*.conf /etc/pve/nodes/new/qemu-server/
# "file exists"とエラーが出る。
```

* [Proxmox node name change | Proxmox Support Forum](https://forum.proxmox.com/threads/proxmox-node-name-change.14327/)


```sh:qemu-serverのconfを移植
cd /etc/pve/nodes/
cp old/qemu-server/*.conf ~
rm -r old

cp ~/*.conf new/qemu-server/
```
Ethereumの新規ブロックを検出してコールバックする方法。(web3.py)

##やったこと
web3.pyを使用してEthereumのブロックが作成された時にコールバックする方法を確認する。
web3.pyで確認している事例があまりないので記録しておく。

※geth --version 1.70, web3.py  --version 3.15

##[Step1] gethを起動させる。(Light client mode)

gethをLightクライアントモードで起動させる。（同期方法はfastでもいいけど、サイズも重く
同期が長いため。今回は同期が早いLight modeにする。）

```:geth
geth --datadir "~/light" --syncmode "light" console --rpc --rpcaddr "localhost" --rpcport "8545"
```

##[Step2] サンプルを書く。

```py3:sample_filter.py
from web3 import Web3,HTTPProvider,IPCProvider
import time

web3 = Web3(HTTPProvider('http://localhost:8545'))

def new_block_callback(block_hash):
	print("New Block: {0}".format(block_hash))

new_block_filter = web3.eth.filter('latest') #フィルタを作成する。
new_block_filter.watch(new_block_callback) #ブロックが生成されたらコールバックする。

while True: #終了しないように待機する。
	time.sleep(1)

```

##[Step3] 結果の確認

gethのプロンプト上では次のように、新しいブロックが生成されるたびMSGが出力されることを確認する。

```:geth
INFO [10-09|06:45:31] Imported new block headers   count=1   elapsed=6.232ms   number=4348769 hash=82a83d…31d8dd ignored=0
INFO [10-09|06:45:32] Imported new block headers   count=1   elapsed=5.492ms   number=4348770 hash=998bf4…3f41a3 ignored=0

```


```:出力（例）
$ python3 sample_filter.py
New Block: 0x82a83dadf80b59c7137649c3bf4a192bd2981cd51379be1df6539591ac31d8dd
New Block: 0x998bf46e587da0639bba709da59159ba08ebc499227383f263a3d6961e3f41a3

・・・
```


##参考
- https://web3py.readthedocs.io/en/latest/filters.html
- https://github.com/pipermerriam/web3.py/blob/5f651e35fb871aa9b01b23ca104aa5e75dffb638/tests/core/filtering/test_filter_against_latest_blocks.py

- https://web3py.readthedocs.io/en/latest/filters.html

- https://pypi.hotlibs.com/web3/package/3.4.1
npm-run-all とは

# npm-run-all とは
> 公式 : [npm-run-all](https://www.npmjs.com/package/npm-run-all)

## 1. 概要
```diff
- `npm run clean && npm run build:css && npm run build:js && npm run build:html`  
+ `npm-run-all clean build:*`  
```
複数の **npm-scripts** を実行するためのコマンドラインツール

## 2. インストール方法
```bash
npm install node-run-all --save-dev
```

## 3. つかい方
 ```
Usage:
    $ npm-run-all [--help | -h | --version | -v]
    $ npm-run-all [実行タスク] [オプション]

    実行タスクを、並行 or 順次に実行
    
Options:
    -p, --parallel [実行タスク]   - 実行タスクを、並列実行
    -s, --sequential [実行タスク] - 実行タスクを、順次実行
```
node-sass-chokidar とは

# node-sass-chokidar とは
> 公式 : [node-sass-chokidar](https://www.npmjs.com/package/node-sass-chokidar)

## 1. 概要
[gaze](https://www.npmjs.com/package/gaze) の代わりに、[chokidar](https://www.npmjs.com/package/chokidar) を使用した、[node-sass](https://www.npmjs.com/package/node-sass) の軽量化モジュールです。

## 2. インストール方法
```bash
npm install node-sass-chokidar --save-dev
```

## 3. つかい方
```bash
node-sass-chokidar src/ -o src/ --watch --recursive 
```

→ `/src` フォルダ以下の `.sass` ファイルが、`.css` に変換されます。
Laravel(v.5.5) - Directory Structure

# ディレクトリ構成
読んでるのは[ここね](https://laravel.com/docs/5.5/structure)

## イントロ
いわゆるモデルのためのmodelディレクトリはないよ。
っていうのもモデルって言葉が広すぎるから。
ってな訳でデフォルトではappディレクトリにしてるけどどうぞご自由に設定してね。

## ルートディレクトリの中身たち

* app
    * アプリの核となるところ（後述）
* bootstrap
    * フレームワークのブートストラップ
    * パフォーマンス最適化のためのcacheもここにいる
* config
    * 名前の通り設定系ファイル
* database
    * マイグレーションファイルとかseedとかその辺
    * sqliteのデータベースフォルダとしても使える
* public
    * アプリのウェブルートディレクトリ
    * jsとかcssとか画像とかもここに入れるかな
* resources
    * トランスパイルする前のsassとかそういうの入れとくとこ
* routes
    * web.app
        * webページのルーティング
    * api.app
        * apiのルーティング
    * console.app
        * CLIのルーティング（？）
    * channels.php
        * ワカンネ
* storage
    * フレームワークで生成されたやつ格納するフォルダ（Bladeとか）
    * appかframeworkかlogsから作られる
    * public/storageにSL作れる（php artisan storage:link）
* 　tests
    * 　自動化テスト用ファイルのフォルダ
    * 　phpunitコマンドで走る
* 　vendor
    * Composerの依存関係系が入ってる

## Appsの詳細
ざっくりHttpとConsoleとProvidersに分かれてる。
artisanのmakeコマンド実行するとapp内のディレクトリに色々生成される。
※makeコマンドで作成できるのはめちゃ多いっぽい（php artisan list makeで確認できる）
デフォルトであるディレクトリ（Http、Console、Providers）と、コマンドで作るディレクトリがある。
デフォでないやつは今回割愛、名前だけ載せとく。

### デフォであるやつ
* Console
    * Artisanコマンドをカスタマイズできるとこ
* Http
    * いわゆるコントローラー
* Providers
* Exceptions
    * 例外ハンドラ

### デフォでないやつ
* Events
* Jobs
* Listeners
* Mail
* Notifications
* Policies
* Rules

はい[ネクスト](https://qiita.com/tom-ock/items/77780faa7dc6e05e3ce8)。
SSL無料証明書: Let's Encrypt


## 無料でSSL対応したかったので、Let's Encryptを使用した時のメモです

### 証明書の公式サイト
https://letsencrypt.org/

### 環境
OS: Amazon Linux Ami
WebServer: Nginx

### 前提条件

① 下記で自分で取得したドメインの名前解決ができているか確認
http://mgt.jp/t/dns

② サーバーのhttpのポート`80` とhttpsのポート`443`が空いていること。


## 証明書の設定

```
移動
$ cd /usr/local/
リポジトリをクローン
$ sudo git clone https://github.com/certbot/certbot
移動
$ cd certbot
実行
# sudo ./letsencrypt-auto --debug
実行
$ sudo ./certbot-auto -debug
Nginxを停止
$ sudo service nginx stop
SSL証明書を発行。 この後にnginxの1番を選び。自分のドメインを入れる
$ sudo ./certbot-auto certonly
nginxを再起動
$ sudo service nginx restart
```

## Nginxの設定

自分の場合はserver.confに直接書いてあるので、ここを編集するが、 `site-avaiable` に書いてる人が普通そう。
`$ sudo vi /etc/nginx/conf.d/server.conf`

```server.conf
server {
     # コメントアウトする
     # listen 80;

     # SSLのPORTを追加
     listen 443 ssl;
     # 自分のドメインを追加 example.com
     server_name example.com;
     # 先程インストールされた照明書のfullchainがここにあるはずなので追加
     ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
     # 先程インストールされた照明書のprivkeyがここにあるはずなので追加
     ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_set_header Host $http_host;
     proxy_redirect off;
     proxy_max_temp_file_size 0;
     location / {
        proxy_pass http://localhost:8000;
     }
}
# httpにアクセスした時にhttpsにリダイレクトされるように以下を追加する
server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}
```

準備ができたので、ngnixをリスタート! これで完了！
`$ sudo service ngninx restart`

### 証明書の自動更新

cronが起動しているかを確認
```
$ /etc/rc.d/init.d/crond status
crond (pid  xxx) を実行中...
```

cronに登録
`$ sudo vi /etc/cron.d/letsencrypt`

```/etc/cron.d/letsencrypt
# 月1で証明書を自動更新
0 1 1 * * root /usr/local/certbot/certbot-auto renew --force-renewal && service nginx restart
```
TypeScript のテストを Jest と CoffeeScript で書く

## 準備

### 依存パッケージをインストール

```bash
npm i -D coffeescript typescript jest @types/jest ts-jest
```

### テスト前にCoffeeScriptを変換するのに必要なファイルを用意

こんな感じで`package.json`と同じ階層に置いておく。

```js:coffee-preprocessor.js
const coffee = require('coffeescript');

module.exports = {
  process: (src, path) => {
    if (coffee.helpers.isCoffee(path)) {
      return coffee.compile(src, {bare: true});
    }
    return src;
  }
};

```

## 設定

`package.json`の`jest`はこんな感じで。

```json:package.json
{
  "jest": {
    "transform": {
      "^.+\\.coffee$": "<rootDir>/coffee-preprocessor.js",
      "^.+\\.tsx?$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
    },
    "testRegex": "/__tests__/.*\\.coffee$",
    "moduleFileExtensions": [
      "js",
      "jsx",
      "json",
      "coffee",
      "ts",
      "tsx",
    ]
  }
}
```

これで`__tests__/test.coffee`みたいなファイルが対象ファイルになりました。`.coffee`の中で`.ts`ファイルを読み込んだりする想定なので、TypeScriptでJestで書くのと同じ設定も必要になります。

## テスト

ディレクトリ構造はこんな感じです。

```bash
tree -I node_modules
# .
# ├── coffee-preprocessor.js
# ├── package.json
# ├── package-lock.json
# ├── src
# │   ├── __tests__
# │   │   └── add.coffee
# │   └── add.ts
# └── tsconfig.json
```

適当に`add.ts`と`add.coffee`を用意します。

```ts:add.ts
export function add<T extends number>(a: T, b: T): T {
  const c = a + b;
  return c as T;
}

```

```coffee:__tests__/add.coffee
{add} = require '../add'

test 'add', ->
  expect add(1, 1)
    .toBe 2

```

## 実行

```bash
npx jest
#  PASS  src/__tests__/add.coffee
#   ✓ add (5ms)
#
# Test Suites: 1 passed, 1 total
# Tests:       1 passed, 1 total
# Snapshots:   0 total
# Time:        3.351s
# Ran all test suites.
# ✨  Done in 4.30s.
```

通りました🎉
Xcodeで特定プロジェクトのコード補完が効かなくなった時の対処法

# 環境
macOS Sierra バージョン10.12.6
Xcode Version 9.0 (9A235)

# 症状
Xcodeのコード補完が効かなくなった。シンタックスハイライトも一部しか機能していない。
補完が効かないのは特定プロジェクトのみで他プロジェクトは問題なし。
git上ではプロジェクトまわりの変更ファイルも無さそう。

前日までは普通に作業できていたはずだが、Xcode開いた状態でMacが異常終了していた気がするのでその影響かもしれない。

# 対応
インデックス機能のオン/オフやクリーン、Macの再起動など試しても治らなかったので、DerivedDataの削除をすることにした。

場所は `~/Library/Developer/Xcode/DerivedData`

プロジェクトのインデックスやビルド時の生成物、ログなどが入っているフォルダらしい。
中を見てみると他プロジェクトのフォルダもあったので、Xcodeを終了させた状態で該当プロジェクトのフォルダのみ削除。

Xcodeを起動してインデックスが走るとコード補完が復活した。
Laravel(v.5.5) - Installation

Laravelが流行ってるらしい。
で、俺はアプリを作ることになりLaravelを使って開発することに。

知識無さすぎてよくわかんねえ。
とりあえず公式Doc呼んで「こういうことかー」ってことメモするだけの自己満Tips。

ホントに知識雑魚すぎるのでコメントバンバンお待ちしています。

# どこやってるか
[ここね](https://laravel.com/docs/5.5)

## Laravelインストール
方法２つあるらしい↓
1. Laravelインストーラ使う
2. composernのcreate-project使う

1.は何かエラー出て

```
php artsian serve
```

も出来んので2.でやるのをオススメ。
参考にしよっかなって思ってた[リンク](https://laravel10.wordpress.com/2015/02/13/laravelのインストール/#more-13)でもLaravelインストーラバグあるって言ってたからバグかも。
分からん。
とりあえず2.。

## ローカルサーバ立ち上げてみる
作ったディレクトリに移動して、

```
php artisan serve
```

立った。とりあえず安心。

## Laravel設定もろもろ
* ディレクトリルートどこ
    * public
* 設定ファイル関連どこ
    * config
* パーミッション与えてね
    * storage
    * bootstrap/cache
* アプリケーションキー
    * インストール2.でやったら終わってるよやったね
* 他にもいじりたい時
    * config/app.phpをいじるといいよ
        * timezoneとかlocale設定できるよ

## サーバー設定もろもろ
よくわかんないんで一旦放置

というわけで[ネクスト](https://qiita.com/tom-ock/items/894d42b8b9684f06f4af)。
PHPのmemcachedのエラーで1日潰した

# 現象
ページアクセス時に以下のWARNINGが出る

```
using touch command with binary protocol is not recommended with libmemcached versions below 1.0.18, please use ascii protocol or upgrade libmemcached
```

## 環境
CentOS Linux release 7.4.1708
nginx/1.10.2
PHP 7.1.10 (fpm-fcgi)
php-fpm

## やりたいこと

```
php -i | grep memcache
```
でlibmemcachedのバージョンを確認したら```1.0.16```だったのでバージョンを```1.0.18```にあげたい

## ポイント

今までの環境では以下のようにphp-pecl-memcachedをyumでインストールしていたけどこれだと```1.0.16```になってしまう様子

```
yum -y install memcached

yum -y install --enablerepo=remi,remi-php71 php php-devel php-mbstring php-pdo php-gd php-mcrypt php-fpm php-mysqlnd php-opcache php-apcu php-xml php-tokenizer php-openssl php-pecl-memcached
```

## 対応

php-pecl-memcachedを辞めて

```
# memcached

yum -y install memcached

wget https://launchpad.net/libmemcached/1.0/1.0.18/+download/libmemcached-1.0.18.tar.gz
tar xvf libmemcached-1.0.18.tar.gz
cd libmemcached-1.0.18
./configure
make
make install
cd ../

wget http://pecl.php.net/get/memcached-3.0.3.tgz
tar xvf memcached-3.0.3.tgz
yum -y install autoconf
yum -y install zlib-devel
cd memcached-3.0.3
phpize
./configure --with-libmemcached-dir=/usr/local/ --disable-memcached-sasl
make
make install
cd ../

systemctl enable memcached
```

/etc/php.ini　に以下を追加

```
extension=memcached.so
```

## 結果

```
# php -i | grep memcache

memcached
memcached support => enabled
libmemcached version => 1.0.18
memcached.compression_factor => 1.3 => 1.3
memcached.compression_threshold => 2000 => 2000
memcached.compression_type => fastlz => fastlz
memcached.default_binary_protocol => 0 => 0
memcached.default_connect_timeout => 0 => 0
memcached.default_consistent_hash => 0 => 0
memcached.serializer => php => php
memcached.sess_binary_protocol => 1 => 1
memcached.sess_connect_timeout => 0 => 0
memcached.sess_consistent_hash => 1 => 1
memcached.sess_lock_expire => 0 => 0
memcached.sess_lock_max_wait => not set => not set
memcached.sess_lock_retries => 5 => 5
memcached.sess_lock_wait => not set => not set
memcached.sess_lock_wait_max => 2000 => 2000
memcached.sess_lock_wait_min => 1000 => 1000
memcached.sess_locking => 1 => 1
memcached.sess_number_of_replicas => 0 => 0
memcached.sess_persistent => 0 => 0
memcached.sess_prefix => memc.sess. => memc.sess.
memcached.sess_randomize_replica_read => 0 => 0
memcached.sess_remove_failed_servers => 0 => 0
memcached.sess_sasl_password => no value => no value
memcached.sess_sasl_username => no value => no value
memcached.sess_server_failure_limit => 0 => 0
memcached.store_retry_count => 2 => 2
Registered save handlers => files user memcached
session.save_handler => memcached => memcached
```

WARNINGが出なくなりました！
ちょっとずつ読むドメイン駆動設計 第ニ部 モデル駆動設計の構成要素 第六章 ドメインオブジェクトのライフサイクル1(序章) 

# ドメインオブジェクトのライフサイクル

オブジェクトはメモリ上に存在するだけとは限らない。
データベースに格納されたり、アーカイブされたりとメモリ上のオブジェクトより長く存在することが多い。

そういったオブジェクトのライフサイクルをどう管理するかが６章のテーマ。
課題は２つ

> - ライフサイクルを通じて整合性を維持すること
> - ライフサイクルを管理するのが複雑でも、モデルが侵食されないようにすること
> 
> (第二部第六章より)

解決策は３つのパターン

## 1. 集約 

ライフサイクルのすべてのフェーズにおいて集約の単位で整合性を保つ。

## 2. ファクトリ

ライフサイクルの始まり。複雑なオブジェクトや集約を生成したり再構成したりする。

## 3. リポジトリ

ライフサイクルの中期と終わりに対応。永続化されたオブジェクトにアクセスする手段を提供。必要な巨大なインフラストラクチャをカプセル化。

## まとめ
- リポジトリとファクトリはドメインには由来しないが、ドメイン設計においては、意味のある役割を持っている。
- リポジトリとファクトリは集約を対象としている。
- 集約が区切るスコープによって不変条件が維持されなければならない範囲が示される。

明日は、集約の詳細を読みます。
electronでゲームの専ブラを作ろう

##どのゲーム？
現在私が毎日しこしこログインしてプレイしている和風伝奇RPG「一血卍傑」の専用ブラウザを作ります。
DMMから好評配信中！スマホアプリもあるよ！！
![バンケツ_20171008232554209.png](https://qiita-image-store.s3.amazonaws.com/0/190389/9fd06801-816e-6b59-2477-85197f0faadb.png)

##どうして作るのさ
一血卍傑というのは某艦これと比べると（他にまともにプレイしてるブラウザゲームがない）UIはそれなりに親切設計にはなっています。
~~比較対象がよくないとか言わない~~

ホーム画面に遷移すればゲーム中の各種通知を見ることができますし、ミッションの達成度合いも確認できます。
しかし通知は見ることができても、たとえばキャラのライフ回復にかかる残り時間などは見ることができませんし、いわゆるAPの回復時間もわかりません。というかAP自体戦闘の準備画面まで行かないと見ることができません（満タンになったことは通知してくれますが）
~~*あれ？ これ本当に親切設計かな？*~~


そんなわけで痒いところに手が届くブラウザがほしいなと思って作るに至った次第です

##で、どうする
ほしい機能は先ほども上げたものを含めてだいたい以下のとおり

- 魂（ライフです）回復時間取得
- 花廊（例えが難しいけど時間経過でアイテムを得ることができる機能）の生成時間取得
- 遠征（おつかいですね）の残り時間取得
- 紫玉（AP）の回復時間取得
- ゲーム画面のスクショ撮影
- ミュート機能

##実際に作ってみる
さて、ここで問題になってくるのがゲーム中のもろもろの情報をどうやって取得するかです
バンケツは~~艦これのように~~通信を平文で垂れ流していたりはしないのでそう簡単に取得できません。~~いやできなくはないけど~~

というわけで通信を覗き見して各種データを取得する案は没です。
幸いなことにそれぞれの残り時間はゲーム画面に表示されているので、そこから画像認識で持ってくることにします

##OCR
使用したライブラリはこちら→ [tesseract.js](http://tesseract.projectnaptha.com/)
日本語の認識には難があるようですが今回使うのは数字だけなので正確に認識してくれます。
ただ処理には少々時間がかかるようです。まあ仕方ない

画像を渡すところで少々ハマりましたが単純にcapturePageで取得した画像をtoPng()で渡せばいいだけでした。くそぅ

##APの回復時間
さてここまではいいのです。問題は紫玉、APの回復時間です
まずはこの画像をご覧ください

![Screenshot_2017-10-08-23-55-26.png](https://qiita-image-store.s3.amazonaws.com/0/190389/a13918c7-8a72-eac0-28e3-0946ee93795f.png)

画面右側中央の紫の玉が紫玉なのですが、このとおり回復時間が表示されていません。
一応、30分でひとつ回復しておよそ15分経つと画像中の左から2番目のように（「こ」の文字の下ですね）
半分だけ回復した画像になりますがこれもユーザー側からするとおおよその目安でしかありません。
ここでこそ通信から残り時間を取得したかったのですが先述の通りその手は使えません。

なのでどうすることにしたかというと、紫玉の回復状況のサンプル画像と実際の回復状況を比較して
おおよその時間を計算することにしました。

##画像比較
使用したライブラリはこちら↓
[jimp](https://github.com/oliver-moran/jimp)
[hamming-distance](https://github.com/math-utils/hamming-distance)
参考にしたページはこちら→　[Node.jsで類似画像判定がしたいならJimpを使うといいかも](http://eiua-memo.tumblr.com/post/157434381311/nodejs%E3%81%A7%E9%A1%9E%E4%BC%BC%E7%94%BB%E5%83%8F%E5%88%A4%E5%AE%9A%E3%81%8C%E3%81%97%E3%81%9F%E3%81%84%E3%81%AA%E3%82%89jimp%E3%82%92%E4%BD%BF%E3%81%86%E3%81%A8%E3%81%84%E3%81%84%E3%81%8B%E3%82%82)

~~サンプル画像は小さかったのでハッシュ化してソースコードに直書きしてます~~

残り時間の表示には「約」がついてます。実際およその時間しかわからないからね、仕方ないね
*だいたい5～10分くらいは誤差が出る*

そしてここでも画像を渡すところでハマりました、こちらはnew Buffer()にcapturePageをtoPngした画像を渡せばいいのでした

##その他
あとはスクショボタンとミュートを実装して、ついでに時計もつけて
残り時間がゼロになったらデスクトップ通知が出るようにして終わりかなと
ところでelectronからの通知のデザインがクソダサいのですがこれどうにかならないのか（windowsが悪いのか？）
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/190389/b5121827-6cac-c58d-9b14-26f28bf8d4b6.png)
*せめて背景色は白にしたい…*

![無題2.png](https://qiita-image-store.s3.amazonaws.com/0/190389/7183cf72-47ed-e3eb-19f9-e1cb6f45726b.png)
*やたら時間のかかるローディングも味わい深い*

**ここまで作っておいてなんですが一血卍傑の推奨ブラウザはEdgeです！！！！！**
ユーザディレクトリを別のボリュームにする

 
0. [ルートユーザを有効にする](https://support.apple.com/ja-jp/HT204012)
1. 別ボリュームにUsersディレクトリを作成
>`# mkdir /Volumes/data/Users`
>`drwxr-xr-x     2 root      admin        68 11  6 22:50 Users`

2. フォルダ名のローカライズ
>`# touch /Volumes/data/Users/.localized`

3. Usersディレクトリをコピーする
>`# ditto -v -rsrcFork /Users /Volumes/data/Users`

4. システム環境設定でユーザディレクトリを変更
5. 再起動

6. 元のUsersディレクトリを削除する
>`# rm -rf /Users`

7. シンボリックリンク作成
>`# ln -s /Volumes/data/Users /Users`
[メモ]video.jsでHLS配信をやってみた

HLS(HTTP Live Streaming)がどういうものなのか色々読んでみたもの実際やってみた方が面白いし勉強になると思ったので、細かいことは置いておいて、実際にやってみたときのメモです。

# 環境
- Vagrant 1.9.7
- CentoOS 7.3.1611
- Apache 2.4.6
- FFmpeg 2.6.8

# 準備
apacheインストールと自動起動設定

```
sudo yum install -y httpd httpd-devel
sudo systemctl start httpd
sudo systemctl enable httpd
```

# mp4ファイルをHLS配信ができるよう変換する
HLS配信するには.m3u8と.tsファイルという２種類のファイルが必要となります。
HLS配信はクライアントが最初に.m3u8ファイルを読み込み、そこに記載された.tsファイルを順次読み込んで再生していくという仕組みになっています。

## FFmpegをインストール
mp4を変換する方法はいろいろあるみたいですが、今回はFFmpegを使います。

```
sudo yum -y install epel-release
sudo rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.el7.nux.noarch.rpm
sudo yum -y install ffmpeg
```

## FFmpegでmp4ファイルを変換する

- `/var/www/html/`のオーナを変える。

```
sudo chown vagrant:vagrant /var/www/html/
```

- `/var/www/html`にmp4ファイルをアップロードする。

- mp4ファイルを変換する。

```
cd /var/www/html
ffmpeg -i input.mp4 -vcodec libx264 -acodec libfaac output.m3u8
```
変換が正常に行くとoutput.m3u8というファイルとoutput0.ts～output?.tsというファイルが作成される。

output.m3u8の中身は下記みたいになっています。

```output.m3u8
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:9
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:8.333333,
output0.ts
#EXTINF:8.333333,
output1.ts
#EXTINF:4.066667,
output2.ts
#EXTINF:4.200000,
output3.ts
#EXTINF:3.200000,
output4.ts
#EXT-X-ENDLIST
```

# 再生用ページを作成する（その１）
注意：HLS配信にネイティブで対応しているブラウザでしか再生できません。
（ChromeやFirefox等でも再生する方法は次項）
```
vi play.html
```


```html:play.html
<!DOCTYPE html>
<html>
<body>
  <video width="640" height="360" src="output.m3u8" controls />
</body>
</html>
```

# HLS配信にネイティブで対応していないブラウザでも再生できるようにする
前項までの作業でEdgeやSafariでは再生できますが、HLS配信にネイティブで対応していないChromeやFirefox等ではまだ再生できません。再生できるようにするにはvideo.jsというライブラリを利用します。

## video.jsを導入する
video.jsとプラグイン（videojs-contrib-hls、videojs-contrib-media-sources）を導入する。
下記リンク先からダウンロードし`/var/www/html/static/js`と`/var/www/html/static/css`にアップロードする。
[video.min.js, video-js.min.css v6.2.7](https://github.com/videojs/video.js/releases)
[videojs-contrib-media-sources.min.js v4.5.2](https://github.com/videojs/videojs-contrib-media-sources/releases)
[videojs-contrib-hls.min.js v5.11.0](https://github.com/videojs/videojs-contrib-hls/releases)

下記のように配置する。

```
|--output1.ts
|--　・
|--　・
|--　・
|--output.m3u8
|--play.html
|--static
   |--css
   |  |--video-js.min.css
   |--js
      |--videojs-contrib-hls.min.js
      |--videojs-contrib-media-sources.min.js
      |--video.min.js
```

# 再生用ページを作成する（その２）

```
vi play.html
```

```html:play.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Video.js Sample</title>
  <link href="static/css/video-js.min.css" rel="stylesheet">
  <script src="static/js/video.min.js"></script>
  <script src="static/js/videojs-contrib-media-sources.min.js"></script>
  <script src="static/js/videojs-contrib-hls.min.js"></script>
</head>
<body>
<video id="test" class="video-js vjs-default-skin vjs-big-play-centered" controls preload="auto"
 width="640" height="360" data-setup="{}">
  <source src="output.m3u8" type="application/x-mpegURL">
</video>
</body>
</html>
```


# 参考

[video.js で m3u8 形式の動画ファイルをブラウザで再生する](http://blog.toshimaru.net/play-m3u8-video-in-browser/)
RedPen v1.9 の新機能

先日 [RedPen v1.9](http://redpen.cc/docs/latest/index_ja.html) をリリースしました。以下は本バージョンで導入された変更です。

## reStructuredText フォーマットをサポート

[RedPen](https://github.com/redpen-cc/redpen) version 1.9 で [reStructuredText](http://docutils.sourceforge.net/rst.html) フォーマットをサポートしました。reStrucutredText　は Markdown や AsciiDoc と同じく軽量マークアップ言語の一つです。軽量マークアップ言語の中でもreStructuredText の表現能力は高く、本格的な技術文書の作成で利用されてきました。

今まで数多く対応に対するご要望はいただいていたのですが、やっとサポートできました。とはいえ残念ながら、reStructuredText が提供するすべての記法はサポートできていません。今後サポートしてほしい記法などあれば気軽にご連絡ください。

RedPen の [IntelliJ プラグイン](https://plugins.jetbrains.com/plugin/8210)はすでに　reStrcuturedText フォーマットをサポートしています。あわせてご利用ください。

<img width="820" alt="Screen Shot 2017-10-09 at 15.57.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/61252/83cf0ee5-8e3a-453c-758d-cd11f4de0740.png">

## エラーメッセージの言語を起動時に指定

今まで RedPen のエラーメッセージは計算機の `LOCALE` 変数の設定によって決定されてきました。本バージョンからエラーメッセージの言語をコマンドラインパラメタで指定できるようになりました。出力されるエラーメッセージの言語は `--lang` もしくは `-L` で指定します。以下のコマンドでは日本語を指定しています。

```
redpen -L ja -f markdown -c redpen-conf-ja.xml input.md
```

## サーバ UI で作成した設定を出力


今までも　RedPen が提供するサーバ UI では設定を変更しつつ、サンプルに貼り付けられた文書にどういったエラーが発生するのかを検証できました。さらに RedPen v1.9 では UI に Export ボタンが付与され、UI を通して推敲した設定をダウンロードできます。以下の画像は、UI で設定した内容をダウンロード（export）している様子です。


![redpen-conf-export-low.gif](https://qiita-image-store.s3.amazonaws.com/0/61252/5fa5648c-4ccf-33b5-2082-f914550ba3b6.gif)

## JoyoKanji Validator

常用漢字以外の漢字が利用されると、エラーを出力する機能（JoyoKanji）が追加されました。

## 今後の予定

今までRedPen が提供するエラー内容は有用ではあるが対応しきれない場合には設定ファイルから機能を消していました。ただ最終確認の時など、よりくわしく検査したい時に全てのエラーを出力できると便利です。RedPen
 v1.10 ではエラーのレベルを設定できるようになります。以下はレベルを含む設定例となります（`Spelling` と `WordFrequency` のエラーレベルが `info`　に設定されています）。

```
<redpen-conf lang="en">
    <validators>
        <validator name="InvalidSymbol"/>
        <validator name="Spelling" level="info"/>
        <validator name="WordFrequency" level="info"/>
        <validator name="Hyphenation"/>
        <validator name="NumberFormat"/>
    </validators>
</redpen-conf>
```

また、日本語の単語の揺らぎは大きな問題ですが、今までカタカナ単語の揺らぎにしか対応できていませんでした。次のバージョンではカタカナ以外の単語にも対応する予定です。
Google Homeに好きなコマンドを追加したい

Google Home発売になりましたね。日本では一般向けに販売されるスマートスピーカーの第１弾なので試してみようとビックに行ったら、デモ機は無ぇとか言われるので仕方なく買ってきました。しかもminiは予約だとかいいやがります。ええ、買いましたよ、Home。

**予想された流れでしかありません。**

買ってからdisる。それが私です。Chromecastもつけてくれました。もう何個も持ってますが....

## 買ったものの、こいつ役立たずとちゃうんか...そう思っていた時期が私にもありました。今も割とそう思ってますが...

さて、このGoogle Homeさん、Alloでも試せるGoogle Assistantの音声フロントエンドとも言えるもので、実際ほぼ同じ受け答えをします。

が、こいつが言うちゃなんですが役立たず。**「お前は一体何が出来るんだ」**という質問に**「すみません、よくわかりません」**と言い出す始末。わかりきっていたコマンド以外では、好きな呼び名で呼ばせられるぐらいしかオドロキがありませんでした。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">今日のGoogle Home <a href="https://t.co/bhE2TybCCX">pic.twitter.com/bhE2TybCCX</a></p>&mdash; Yayane Kiyohide (@takustaqu) <a href="https://twitter.com/takustaqu/status/916932177178238976?ref_src=twsrc%5Etfw">2017年10月8日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

***(alloのGoogle Assistantでフリーザ様と呼ばせていた事をすっかり忘れていたので、Homeで呼ばせてみた時に普通にびっくりした)***

良い点としては音声トリガーから認識、応答までのスピードが比較的速いこと。ここはSiriと比較にならないので良いのですが、デフォルトで出来ることが大して無く、タイマーの設定、目覚まし、Hueの設定ぐらいにしか今のところ当方には使いみちが見いだせずにいました。**久々に文句の言い甲斐のあるガジェットだなぁ**と思っていたら、一応Google AssistantのIFTTTチャンネルがあったようで、期待を込めてこいつを試してみました。

## IFTTTのGoogle Assistant

結論からいいましょう。このトリガは使えます。**一応。**

ただ、ここには日本語故の難しさがあります。
それは、単体では日本語の認識結果がどうなっているのかを確認する術がない点です。実は最初「嫁さんに ~~~~ とスラック」とトリガを作りました。こいつが認識出来ない。Google Homeさんは「すみません、お役に立てません」みたいなことを繰り返す始末です。

最初このトリガが走ってないのではないかと思ってたんですが、どうも成功している人もいる模様。実際Alloで手入力した場合は走ります。

するとなるともう最も可能性が高いのはこれ。誤認識です。

## 誤認識を特定する

実はどうも、Googleの音声認識は一旦「スラック」という発話を「Slack」と認識するものの、その後この文脈で「スラッグ」と変換してしまいます。

さて、それをどうやって調べたか？最初にいいましたよね、そう、Alloです。
![IMG_1766.jpg](https://qiita-image-store.s3.amazonaws.com/0/61912/ea109248-faf9-8899-ef63-acdf66a4bb0b.jpeg)

Alloの音声入力でどう変換されるのかを見て、トリガを設定すればいいのです。

![IMG_1764.jpg](https://qiita-image-store.s3.amazonaws.com/0/61912/f8bd7c70-21f5-b5ec-b6a5-34f6fcb6087a.jpeg)

ほら、言ったとおりでしょう？

<img width="566" alt="Screen Shot 2017-10-08 at 23.14.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/61912/87167d5d-6185-e186-db37-592c356ef211.png">

あとはこんな具合に設定してやるだけで良いのです。

***【追記】GoogleAssistantのアクティビティが見れるページがあるので、なんでGoogleHomeで認識しないのか？という時に判定結果をここで確認できます。 [https://myactivity.google.com/item](https://myactivity.google.com/item)***

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Google Homeが少し役に立つようになった <a href="https://t.co/3xkRIye1wn">pic.twitter.com/3xkRIye1wn</a></p>&mdash; Yayane Kiyohide (@takustaqu) <a href="https://twitter.com/takustaqu/status/916998258076950529?ref_src=twsrc%5Etfw">2017年10月8日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

-----

さあ、これさえ出来ればもうMakerチャンネルで好き勝手出来ます。実際幾つかDashButtonでやってるタスクをボイスコマンド化してみたりしました。まだ声紋登録がないのであまり危ないタスクを設定できませんが（鍵の解錠とか）、そうであってもGoogleの精度が極めて高い音声認識を使ってボイスコマンドを気軽に使えるのはなかなかに魅力です。

標準の状態では愛すべき役立たずでしかありませんが、今回のこれでminiを買い足して自宅の全室と会社にも置きたいぐらいの感じにはなりました。


とりあえずエアコンの操作とかやってみようかと思います。
Macで最初にすること

#準備
##キーボードの設定を変える．
↓基本はここ参照．
https://asahinablog.com/archives/2029
システム環境設定からキーボード選んで，入力ソースから日本語キーボードを追加．カタカナ，英字，ライブ変換はチェックを外す．
![スクリーンショット 2017-10-08 23.57.56.png](https://qiita-image-store.s3.amazonaws.com/0/198392/4d25eaf6-4848-a2eb-4c67-69dd526fd4fa.png)

##Chromeを入れる
Chromeのページからダウンロードしてインストールするだけ．

##Homebrew入れる
1. app storeからXcodeをインストール
2. Command Line Toolsをインストール
terminalで  
```$ xcode-select --install```
3. Homebrew入れる  
```$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"```

##Java入れる
terminalで
```$ brew update
$ brew cask install java```

#各種アプリ
##python
[こちらを見てやりました．](https://qiita.com/Haji-Fuji/items/9e3d6ca46eb02f3c241f)
##MeCabの入れ方
https://qiita.com/taroc/items/b9afd914432da08dafc8
```$ brew install mecab
$ brew install mecab-ipadic```

```$ brew install git curl xz
$ git clone --depth 1 git@github.com:neologd/mecab-ipadic-neologd.git
$ cd mecab-ipadic-neologd
$ ./bin/install-mecab-ipadic-neologd -n```

##R
```$ brew install R```
[jupyterで使えるようにする](https://irkernel.github.io/installation/)

##Emacs
```$ brew tap railwaycat/emacsmacport
$ brew install emacs-mac
$ brew linkapps```

##Hadoop
```$ brew install hadoop```
###Hadoopのテスト
πを計算
まずはhadoop-mapreduce-examples.jarを探す．
　```$ find /usr/local/Cellar/hadoop | grep jar | grep example````
これで見つかったPATHを使ってπを計算
```$ hadoop jar /usr/local/Cellar/hadoop/2.8.1/libexec/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.8.1.jar pi 5 200```

Word Count
「プログラミングHive」に則り，適当なディレクトリでwc-inを作成．
```mkdir wc-in
  echo "bla bla" > wc-in/a.txt
  echo "bla wa wa" > wc-in/b.txt```
テキストファイルの用意ができたらコマンド実行
```hadoop jar /usr/local/Cellar/hadoop/2.8.1/libexec/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.8.1.jar wordcount ./wc-in/ ./wc-out/```

##Hive
```brew install hive```
C++/MATLAB/Python注意書き

C、MATLAB、Python、VBAを同時進行で使用することが増えて
文法で混乱することが増えてきたのでメモ書き。
※なので、説明はほとんどないです...

自分が文法で混乱したことを
随時書いていこうと思っています。

## 関数定義
###C
```c:
int sample(int a, int b) {
    c = a + b;
    return c;
}
```

###MATLAB
```matlab:
function ret = sample(a, b)
    c = a + b
    ret = c;      % 行末に;を付けても付けなくてもOK
end
```

###Python
```py:
def sample(a, b):
    c = a + b    # 行末に;は不要
    return c
```

###VB
```vbnet:
Function sample(ByVal a As Integer, ByVal b As Integer) As Integer
    Dim c As Integer
    c = a + b　　　　　　　' 行末に;は不要
    sample = c
End Function
```

## if文
###C
```c:
if (a == 0) {
    /* 処理1 */
}
else if (a == 1) {
    /* 処理2 */
}
else {
     /* 処理3 */
}
```

###MATLAB
```matlab:
if (a == 0)
    % 処理1
elseif (a == 1)
    % 処理2
else
    % 処理3
end
```

###Python
```py:
if a == 0:
    # 処理1
elif a == 1:
    # 処理2
else:
    # 処理3
```

###VB
```vbnet:
If a = 0 Then
    ' 処理1
ElseIf a = 1 Then
    ' 処理2
Else
    ' 処理3
End If
```
SRE本まとめ（15章 ポストモーテムの文化：失敗からの学び）

自分の理解を深めるためにまとめてみました。[14章](https://qiita.com/bassbone/items/cb3501fe4bbad4c9b514)の続きです。

## 15章 ポストモーテムの文化：失敗からの学び

### Googleにおけるポストモーテムの哲学
主な目的は、インシデントがドキュメント化されること、影響を及ぼした全ての根本原因が十分に理解されること、再発の可能性や影響を削減するための効果的な予防策が確実に導入されるようにすることである。ポストモーテムを書くことは処罰ではなく、会社全体としての学びの機会である。100％全ての事象に対して書くのは労力がかかるので、以下のような場合に書くようにしている。

- ダウンタイムが一定の閾値を超えた
- データの損失が生じた
- オンコールエンジニアの介入が必要だった
- 解決までに一定以上の時間を要した
- モニタリング自身の障害

ポストモーテムでは絶対に批判を行ってはならない。少しでも批判的になってしまうと、ポストモーテムを書きたくないという文化になってしまい、負のスパイラルに陥ってしまうから。（個人的な見解として）そのためには、各人がプロとして行動しており、お互いがプロとして相手を尊重するような文化が必要。プロとしてやれるだけのことをやって、それでもインシデントが発生してしまったのであれば仕方がないと思えるかどうかかと。ポストモーテムを書くにあたっては、正式なレビューと公表もセットである。以下のような観点でレビューするとよい。

- 後学のためのデータは収集されたか？
- インパクトの分析は完全か？
- 根本原因の分析は十分か？
- アクションプランは適切で、バグ対応の優先順位はつけたか？
- 結果はステークホルダーに共有済みか？

ポストモーテムの文化を根付かせるのは難しく、継続的な育成と強化が必要になる。そのために以下のような活動を行っている。

- 今月のポストモーテム
- Google＋ポストモーテムグループ
- ポストモーテム読書会
- 不運の輪（トレーニングのようなもの）
- ポストモーテムをワークフローに組み込む
- ポストモーテムの質を適切に評価する文化
- 上位のリーダーたちの承認と参加を奨励

ポストモーテムを集約し解析することで、改善すべき共通のテーマや領域を見出すことができる。将来的な取り組みとしては、機械学習による弱点の予測、リアルタイムのインシデント調査の促進、インシデント再発の削減がある。

（[16章](https://qiita.com/bassbone/items/2293952d1ec384c4df38)に続く）
Flaskでアップロードされた画像ファイルをOpenCVで読み込む方法

参考: https://qiita.com/miyahan/items/7d629d00429c9f032a27

- Flaskのrequest.filesから取得したファイル情報は、Werkzeugの[FileStorageオブジェクト](http://werkzeug.pocoo.org/docs/0.12/datastructures/#werkzeug.datastructures.FileStorage)になっている
- FileStorageのstreamはPythonの基本的なバイナリストリームである[io.BufferedIOBase](https://docs.python.jp/3/library/io.html#io.BufferedIOBase)を継承している
- これは要するに```open(FILE_NAME, "rb")```した時に得られるものと同じと考えればいい

OpenCVでこのストリームを読み込むには、次のようにする。

```python
import cv2
import numpy as np
from flask import Flask, request
app = Flask(__name__)

@app.route("/upload", methods = ["POST"])
def upload():
  stream = request.files['file'].stream
  img_array = np.asarray(bytearray(stream.read()), dtype=np.uint8)
  img = cv2.imdecode(img_array, 1)
```

ちなみにimdecodeの第二引数はimreadのそれと同じ意味だが、なぜかこちらは省略できない。
VirtualBoxとVagrantで開発環境構築

#はじめに
直接関わってないけど、最近いろんなPCに開発環境&本番環境を
構築してもらうことがあったので自分でもチャレンジしてみました。

非常に初歩的なことしかやってないので
これを読んでくれた人にはあまり役には立たないかもしれません...

#流れ
1. VirtualBoxとVagrantのインストール
2. Vagrantの初期化
3. Vagrantの起動
4. Vagrantの終了

#1. VirtualBoxとVagrantのインストール
それぞれ[VirtualBox](https://www.virtualbox.org/)と[Vagrant](https://www.vagrantup.com/)からインストールします。

#2. Vagrantの初期化
ここでは↓のことをします。

ここではVM用ディレクトリの作成とVMの構成を記述するVagrantfileを作成します。
1. ディレクトリ作成
2. Vagrantfileの作成
3. VM構成の設定

####2.1. ディレクトリ作成
```
cd ~
mkdir vm/vagrant
cd vm/vagrant
```

####2.2. Vagrantの初期化
```
vagrant init ubuntu/trusty64
```
他のディストリビューションがいいとがあれば
[Discover Vagrant Boxes](https://app.vagrantup.com/boxes/search)から好きなものを選んでください。

####2.3. VM構成の設定
ここではホストOSとの共有フォルダ設定、VMのメモリ容量設定をします。

#####共有フォルダ設定
まずはホストOSにフォルダを作成

```
cd ../
mkdir data
```
Vagrantfileの`config.vm.synced_folder`の設定を有効にします。

```rb:Vagrantfile
  # argument is a set of non-required options.
  config.vm.synced_folder "../data", "/vagrant_data"
```

#####メモリ容量設定
1GMのメモリ割り当てをします。

```rb:Vagrantfile
config.vm.provider "virtualbox" do |vb|
#   # Display the VirtualBox GUI when booting the machine
#   vb.gui = true
#
    # Customize the amount of memory on the VM:
    vb.memory = "1024"
end
```

#3. Vagrantの起動
####起動
```
cd ./vagrant
vagrant up
```

####sshでのログイン
```
vagrant ssh
```

#4. Vagrantの終了
####ログアウト
```
exit
```

####終了
```
vagrant halt
```

#実際やってみて
めちゃめちゃ簡単でした。難しいことしてないし。
以前、VirtualBoxでの仮想環境を構築した時に
ホストPCのログインアカウントごとに共有フォルダの設定/メモリ容量の設定をしてたんですが
Vagrantを使ってればめちゃめちゃ楽だったな...


####参考
- [Mac上に Vagrant + VirtualBox で Ubuntu の環境構築](https://qiita.com/orangeboy/items/cb41e67d787ef60b6dc1)
- [VagrantとDockerについて名前しか知らなかったので試した](https://qiita.com/hidekuro/items/fc12344d36d996198e96)
- [Vagrantの重要ファイル「Vagrantfile」の読み込みとその周りの挙動をちょっと細かく追ってみた](http://at-grandpa.hatenablog.jp/entry/2013/10/01/015501)