OmniAICreator/Qiita-1.07M huggingface dataset:
Wordpress構築の際に「入れてもいい」と思っているプラグイン

*この記事はWanoアドベントカレンダーの8日目です

Wordpressの案件をやっていると

「プラグインのバージョン上げたら動かなくなった」
「プラグインが最新verに対応してないからWordpress自体のバージョン上げれない」
「そもそもプラグイン入れるな」
「プラグイン●ね」

等となんとも殺伐とした会話が良く聞かれます。
これらはそもそも、事業性の案件に対してオープンソースCMSであるWordpressを採用している時点である程度覚悟しなければいけないリスクではあるのですが…
確かにプラグインは便利ではありますが、Wordpress界隈は巨大すぎて玉石混交すぎます。

そこで自分が最近Wordpressの案件に着手する際に、「これらは入れても大丈夫だろう」と思っているプラグインを紹介したいと思います。
想定される案件としては

- 小・中規模のコーポレートサイト
- カスタム投稿タイプを多用するような多ジャンルメディアサイト
- 会員制のコミュニティサイト

等を想定しています。
選定の基準としては便利さ、簡単さよりも

- コアに影響を与えない
- セキュリティパッチ等、最新版のWordpressの動作確認が早い
- 独立性が高い
- **仕様変更、良くある要件に強い**

事がポイントとして見ています。

# まず確実に入れているプラグイン
## Advanced Custom Fields（通称ACF）
https://ja.wordpress.org/plugins/advanced-custom-fields/

- カスタムフィールドのカスタマイズのデファクト的なプラグイン
- **管理画面のカスタマイズの柔軟性**
- カスタムフィールドを制御する事で、顧客が**感覚的に使いやすいインターフェース**を提供し、**クレーム、問い合わせ**を減らす

## ACF Repeater Field 
https://www.advancedcustomfields.com/add-ons/repeater-field/

- 上記ACFのアドオンプラグイン（有料買い切り）
- 繰り返しフィールドを追加出来る
- ギャラリーの追加等、**ありがちな要件**に対応しやすい

# 要件によっては入れるプラグイン
## Google XML Sitemaps
https://ja.wordpress.org/plugins/google-sitemap-generator/

- XMLサイトマップの生成
- 自前でテンプレートを作っても良いが、予算的に厳しい場合はこちらでさっくり入れる

## Custom Post Type Permalinks
https://ja.wordpress.org/plugins/custom-post-type-permalinks/

- カスタム投稿タイプのパーマリンク設定のカスタマイズ
- **ありがちなURL規則**のカスタマイズ
- function.phpで自作しようとするとrewrite_ruleの設定が非常に面倒

## Multi Device Switcher
https://ja.wordpress.org/plugins/multi-device-switcher/

- PC、SPでのテーマの切り替え
- シンプルで独立性が高い

## Simple GA Ranking
http://simple-ga-ranking.org/ja/

- Google Analyticsのレポートデータ配列を取得するプラグイン
- GoogleのAPIとのインターフェースを提供してくれていて、シンプルに配列で返してくれる為フロントエンド側でカスタマイズしやすい

## Theme My Login
https://ja.wordpress.org/plugins/theme-my-login/

- 会員制のサイトを作成する場合に利用
- テンプレートの独立性が高い
- Wordpress自体のユーザー管理を利用する。独自でDBの拡張や管理ツールを提供しない。

# 番外編：見かけるとげんなりするプラグイン
## All in One SEO Pack
https://ja.wordpress.org/plugins/all-in-one-seo-pack/

- きっちり運用すれば良いプラグインだとは思う
- **きっちり運用できている案件を見たことが無い**
- 色々なところでオススメされていて**とりあえず入れている感**がやばい
- ~~これを入れて「SEO対策ばっちりです」と言い張る業者が多い。~~

## キャッシュ系のプラグイン
- キャッシュはサーバーサイドでやったほうが良い
- ~~サーバーサイドのエンジニアが怒り狂う~~


※あくまで中小規模のWordpress開発の一例です。

今後もこれは使えるというプラグインを見つけたら更新していきます。
SourceTreeでBitbucketリモートレポジトリが突然見れなくなったとき

ある日、突然SourceTreeでBitbucketリモートレポジトリが見れなくなった。
OAuthなログイン画面が何度も出てきて、ログインには成功するのに、その先に進めない...
WindowsとMacで使っているのだが、Windowsでは発生していない。
ググるとそれらしい話題があるものの、自分の場合とは何かが違うようだ...

結論から言うと、アカウントの設定に問題があった。

<img width="551" alt="スクリーンショット 2017-12-08 17.33.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/177445/070a9c5d-cc18-9b11-0525-2ad1c7cb5805.png">

レポジトリのウィンドウの右上の方にある歯車のアイコンをクリックすると出てくる「アカウント...」を選択し、問題の生じているアカウントを選択して「編集...」をクリックする。

<img width="449" alt="スクリーンショット 2017-12-08 17.43.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/177445/62017354-9ca4-6179-01ed-248eb88e2066.png">

ここで認証タイプがOAuthになっていればOKで、BasicになっているとNGなのである。

Bitbucketが、いつかのタイミングからBasic認証を避けて、OAuthに切り変わったのだと思う。（自分で設定をいじったのかも...まったく記憶にないのだが）


まあ、コマンドラインからgit/hgを使ってもいいんだけどね...
webpack時代の終わりとparcel時代のはじまり

# 設定不要のビルドツール

parcelというビルドツールが空前の勢いでGitHubスターを集めており、リリース数日で5000スターを超えています。今日だけでも1000スター以上増えており、Googleなどの有名企業リポジトリ以外でこのスピードで人気がでるのは異例です。

https://github.com/parcel-bundler/parcel
https://parceljs.org/

実際に試してみたところ、これはwebpack一強時代を終わらせるレベルの使いやすさだと確信しました。

作者はAdobeのエンジニアで、その他著名エンジニアも続々と参加している様子です。

# webpack疲れ

webpackが出た当初、webエンジニアはgulp/grunt疲れの状態だったことを覚えている方もいるかと思います。
webpackの統合された設定ファイルは、タスクランナーで逐次処理していたものを宣言的にするという点で革新的でした。

しかし、その後バージョンアップのたびに設定ファイルを書き直すことになり、過度にモジュール化されたプラグインによって設定ファイルはカオスになっていきました。
個人的にも、毎回新しいレポジトリを作るために、開発環境の構築という無駄な作業に時間を取られ、webpack疲れを最近感じていました。

# 設定ファイル自体がない
parcelには設定ファイルがありません。（少なくとも私が探した限り存在しませんでした）
ただ単にコマンドラインでエントリポイントを指定するだけです。エントリポイントはHTMLに限らず、JS等も対応しています。

```
parcel index.html
```

これだけで依存しているhtml, js, css等を見つけてきてバンドルしてくれます。
babelの設定ファイル(.babelrc)があれば、勝手に読み込んでトランスコンパイルしてくれます。PostCSSも同様です。

# Reactの例
parcelでReactアプリを書くための手順は驚くほどシンプルです。

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

    ```bash
    npm init -y
    npm install --save react react-dom
    npm install --save-dev babel-preset-react babel-preset-env parcel-bundler
    ```

2. .babelrcを追加する

    ```json:.babelrc
    {
       "presets": ["env", "react"]
    }
    ```

3. package.jsonのstartスクリプトに"parcel <ルートHTMLファイル>"を指定する。

    ```json:package.json
    ...
    "scripts": {
      "start": "parcel index.html"
    },
    ...
    ```
4. html, js, jsx, cssを書く
5. npm startを実行する。
6. http://localhost:1234 にブラウザからアクセスする。

これだけでホットリロードのReact開発環境が完成です。

#TypeScriptは？

今日(12/8)3時ごろTypeScriptサポートのPull Requestがマージされました。 現在npmに上がっているバージョン(v1.0.3)にはまだ反映されていませんが、開発スピードを見る限り数日以内でアップされると思います。
--> 追記: npmにTS対応バージョンv1.1.0がアップされました

Basic TypeScript Support 
https://github.com/parcel-bundler/parcel/pull/84

# Parcelドキュメント概説
## コマンドラインオプション
`-p`: 開発用webサーバーのポート番号指定 (デフォルト1234)
`watch`: HMR(hot module replacement)のみ。開発用webサーバーは起動しない
`build`: 本番環境向けのバンドルのみ行う。HMR, 開発用webサーバーは起動しない。distディレクトリにminifyされた結果が出力される。
`--out-dir` (or `-d`): バンドル出力先の変更(デフォルトdist)

## サポートしている変換機能・形式
- Babel (.babelrc)
- PostCSS (.postcssrc等)
- PostHtml (.posthtmlrc等)
- CSS Module
- LESS
- SASS
- Stylus
gmaps4railsで躓いた点

## gmaps4rails

railsでgooglemapを使う時に便利なこのgem
https://github.com/apneadiving/Google-Maps-for-Rails

しかし普通に入れても、下記のエラーになる。

```
a is not define
```

## 解決法

headerで読み込む前にjavascriptにapplication.jsを読み込ませないとload出来ない。
headerに下記を追加

```application.html.erb
<head>
  <%= javascript_include_tag "application" %>
```
sedで最短一致をする

# 結論
```shell-session
$ less test.txt
{"hoge":"fuga","piyo":"foobar"}
$ less test.txt | sed -r "s/^.*?\"hoge\":\"([^\"]*)\".*$/\1/"
fuga
```
* `[^A]*`(クラスの否定）をうまく活用する。

# やりたかったこと
* 下記のようなjsonでkeyに一致するvalueを抜き出したかった

```json:test.txt
{"hoge":"fuga","piyo":"foobar"}
```

* しかしsedは最長一致のためこうなる

```shell-session
$ less test.txt | sed -r "s/\"hoge\":\"(.+?)\"/\1/"
{fuga","piyo":"foobar}
```

* 違う。そうじゃない。

# なぜ最初のでうまく行くか
* []でクラス化した文字列の否定で、文字列の最初から辿る
* 指定した文字列ではない文字列をすべてスルー
* 目的の文字列があったらそこでサーチをやめる＝最短一致

# 補足
* 大抵の言語で採用されている正規表現は「やりたかったこと」で記載されている正規表現を使えば同じことができる
Kotlinコントリビュートのための環境構築


# はじめに
Kotlinにコントリビュートしようと心に決めてから、まずはハマったのが環境構築だったので
この記事では環境構築の仕方を書き残したいと思います。（2017/12/08現在）
今回環境構築するPCは、
Macbook pro 2016 13inch Touchbarなし
MacOS 10.13.1
です！


# ソースコードを持ってくる
KotlinのソースはGithub上にあります。まずはCloneしましょう。
https://github.com/JetBrains/kotlin

# いざ環境構築
此処から先は、GithubのReadMeを読みながら進めていきます。

## Javaをインストール
Kotlinの開発環境には、JDK1.6, 1.7, 1.8が必要です。
まずはこれらをインストールしましょう。

JDK1.6, 1.7はオラクルの[ダウンロードページ](http://www.oracle.com/technetwork/java/javase/downloads/index.html)には無いです。
JDK1.6は[こちら](https://support.apple.com/kb/DL1572?locale=ja_JP),
JDK1.7は[こちら](http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase7-521261.html)からダウンロードしましょう。
JDK1.7はダウンロード時にプロファイルの作成を求められますので作成しましょう。

その後環境変数に各JDKのPathとJAVA_HOMEを追加します。

```
  JAVA_HOME="path to JDK 1.8"
  JDK_16="path to JDK 1.6"
  JDK_17="path to JDK 1.7"
  JDK_18="path to JDK 1.8"
```


## Apatch antをインストール
Kotlinのビルドのためにはantの1.9.4以上が必要となります。
今回はHomebrewでインストールしました

`brew install ant`

```
ant -version
Apache Ant(TM) version 1.10.1 compiled on February 2 2017
```

##  依存関係をセットアップ
ここまで終わったら

`ant -f update_dependencies.xml`

を叩きます。
ダウンロードや解凍が走ります。
しばらく時間がかかります。
自分の環境では40分ほどかかりました。

## IntelliJ IDEAをダウンロードしておく
2017.3が必要とのことなので、[ここ](https://www.jetbrains.com/idea/whatsnew/)からダウンロードしましょう

# プロジェクトを開く
まずはIntelliJ IDEAを開いて、openを選択します
![スクリーンショット 2017-12-08 16.45.10.png](https://qiita-image-store.s3.amazonaws.com/0/93802/6ac79b31-297b-958f-6cd1-7fb5266fdee3.png "スクリーンショット 2017-12-08 16.45.10.png")

その後、Kotlin配下の`build.gradle.kts`をopen
![スクリーンショット 2017-12-08 16.45.40.png](https://qiita-image-store.s3.amazonaws.com/0/93802/67fcbaa7-918f-be35-c6b1-e0e985b21a5d.png "スクリーンショット 2017-12-08 16.45.40.png")

openAsProjectで開きます
![スクリーンショット 2017-12-08 16.45.50.png](https://qiita-image-store.s3.amazonaws.com/0/93802/c6bcf1a2-548c-70f3-22d0-958262f6b29f.png "スクリーンショット 2017-12-08 16.45.50.png")

`use default gradle wraper` が選択されていることを確認して開きます
![スクリーンショット 2017-12-08 16.46.02.png](https://qiita-image-store.s3.amazonaws.com/0/93802/185ed247-997f-fa20-59ed-3cbce08e6a72.png "スクリーンショット 2017-12-08 16.46.02.png")

そしてIDEAを選択してRunします
![スクリーンショット 2017-12-08 16.58.19.png](https://qiita-image-store.s3.amazonaws.com/0/93802/f8fdf0e6-9ab1-2c31-5ca6-72de331ae9ff.png "スクリーンショット 2017-12-08 16.58.19.png")

buildが終わると、新しくIntelliJが開きます。
この新しく開かれたIntelliJの方には、プロジェクトのKotlinPluginなどが適用されています。

### IssueTracker
KotlinのIssueが[ここ](https://youtrack.jetbrains.com/oauth?state=%2Fissues%2FKT)に上がっています。
ちなみに、j2kとは JavaからKotlinに変換するプラグインの機能のことのようです。

## 躓きポイント
### `ant -f update_dependencies.xml`が終わらない
自分は30分ほど同じところで固まったのでキャンセルしてもう一回走らせたらすんなり通りました。

### JavaHomeが違くてビルド出来ないと言われる
こちらの方法で解決しました。
http://gyamin.hatenablog.com/entry/2017/04/02/103049


# あとがき
とりあえずこれで開発を開始できるかと思います。
それではよいKontribute Lifeを:+1: 

## 参考にさせていただいたサイト
http://shiraji.github.io/blog/2016/07/14/how-to-kontribute/
[Unity]CPU負荷 備忘録

最近行った負荷対策と、それぞれの効果について簡単にまとめました。
※効果については、基本的にプロジェクトによりけり。自身のケースではどのくらいだったかを基準にしてます

# GetComponentの呼び出しを抑える（効果：大）
取得したインスタンスを変数にキャッシュして、呼び出しを最低限に抑えること。
特に、Update内やfor文内で呼ばれるとかなりな処理時間に。メソッド内で使う場合、気付き辛いので注意。

# Distanceやmagnitudeなど、距離やベクトルの長さの計算改善（効果：大）
必然性が無ければ、極力使わないほうがよい。
例えば、2点間の距離の比較であればsqrMagnitude同士を比較することでも可能で、
sqrMagnitudeはmagnitudeやDistanceにくらべ、√の計算をせず、2乗した値のままであるため負荷が低い。

# transformのposition、eulerAnglesへの代入改善（効果：小～中）
可能ならlocalPosition、localEulerAngles（rotation）への代入の方が軽い。
positionなどに代入すると、ローカル座標へ変換する処理が走るらしく、数が増えてくると地味に重くなる。
また、1フレーム内での計算で、transformへの代入が何度もあるとそれも無駄な負荷になるため、最終的な座標や角度のみをtransformに代入するように設計すること。

# Animatorコンポーネント（効果：大）
少ないほど良い。3Dモデルのモーションなどでは使用は避けられないが、単純にくるくる回ったりバウンドするだけのUIやアイテム系であれば、スクリプトで実装してUpdateを回した方が速い。Animatorだとパラメータ管理などでUpdate処理の負荷が膨らむ模様
ボタンのタッチリリースや、点滅、拡縮などの汎用UIアニメーション、3Dオブジェクトの回転などのループ系アニメーションは、必要最低限用意しておいて、AddComponentですぐ使えるようにしておきたい。

# AnimatorのSetBool、SetTrigger（効果：小～中）
値の変化が変わらないのに、Update内で何度もSetメソッドを呼んでいると、無駄な負荷になる。
Set前に比較をして、変わらない場合はSetしない方が軽い。
これはAnimator以外にも、SetStateやSetActive、SetVisibleなどのいろんなSet系メソッドのことで言える。

# Animation付きのfbxのOptimize（効果：中～大）
http://tsubakit1.hateblo.jp/entry/2015/04/30/012956
Unity上で参照が必要ないボーンを隠す機能。Animators.Updateの処理負荷に効果がある。
特にキャラクターモデルのようにボーン数が多いものだと効果が大きい
参照が必要なものは、「Extra Transforms to Expose」で選択しておくこと

# ログの出力負荷（効果：小）
リリースビルドでDebug.Logを消してなければ消す
　┣ namespaceを分けてプロジェクト内で呼ぶDebug.logをオーバーライド
　┣ namespace毎に出すログをON/OFFする
　┗ System.Diagnostics.ConditionalのAttributeを使って整理するのもオススメ
http://d.hatena.ne.jp/nakamura001/20151202/1449029637
自身で入れているLog以外にも、Assetが大量にログを履いていたり、StarckTraceに格納？してたりする場合も

# CanvasRaycasterの負荷（効果：中）
「Canvas Raycaster」が設定されているキャンバスの、UI要素数が多いほど、RaycastAllの処理（EventSystemを使っている以上避けられない処理）の負荷が大きくなる。
「Raycast Target」がtrueになっているUIを極力別のCanvasにまとめることで負荷を減らせる。

# ガベージコレクション（効果：中～大）
明示的に変数を解放せずGCに任せると、一定のタイミングでGCの処理負荷がかかり、FPSが落ちる。
インスタンスを扱うローカル変数の扱いにコーディングルールを決めて対策すること。

# 画面内に映らないUIの負荷（効果：大）
よくあるモノだと、キャラクターの付近に表示するHPゲージや名前、照準などが該当。
3Dオブジェクトを追従して表示するようなUIの場合、画面外にいるときは描画もスクリプトも原則OFFにしておきたい。

# GPU Skinning（効果：小）
GPU負荷よりCPU負荷の方が高い場合に有効。SkinningをGPUに任せる設定をしている。
PlayerSettingsのOtherSettings内で指定可能。

# その他
・ダメージ数字やエフェクト、敵の攻撃の弾など、頻繁に出たり消えたりするオブジェクトを都度生成せず、使いまわすようにしたり、必要なリソースをシーン開始時などにまとめてロードしておくことも重要
・Photonなどでリアルタイム通信をする場合は、出来る限り通信データ量を減らしたり、通信する処理をまとめたりしておく

負荷の原因は他にもいろいろ考えられるので、Profilerで小まめに見ておく！
[メモ用]Word2013をある程度Emacsのキーバインドに対応させるための設定

## はじめに
emacsのキーバインドなしでは生きられない身体になってしまったので、そのたの設定メモです。他の場でも多数紹介されていますが、改行と改段の使い分けが中々見つからなかったので一応。
あくまでメモ用ですので自分が多用するコマンドのみを記述しています。あと私はWordのマクロに詳しい訳ではないので基本的に質問等にはお答えできないと思います。

## 大まかな流れ
簡単な**カーソル移動**(Ctrl+f)や**Undo**(Ctrl+/)はWordの既存コマンドで設定できるのですが、**改行**(Ctrl+m)や**行の切り取り**(Ctrl+k)はマクロを組まないと実装できないので、その2方面から設定をしていきます。

## 既存コマンドから
* Wordのメニューバーから
**ファイル/オプション/リボンのユーザー設定/ユーザー設定/**に移動する。
* 分類からすべてのコマンドを選択。
* 目的のコマンドを探し、キーを割り当てる。

|Emacs|コマンド名|動作|
|:--|:--|:--|
|Ctrl+p|LineUp|カーソルを1行上へ|
|Ctrl+p|LineUp|カーソルを1行上へ|
|Ctrl+n|LineDown|カーソルを1行下へ|
|Ctrl+b|CharLeft|カーソルを1文字左へ|
|Ctrl+f|CharRight|カーソルを1文字右へ|
|Ctrl+a|StartOfLine|カーソルを行頭へ|
|Ctrl+e|EndOfLine|カーソルを行末へ|
|Alt+<|StartOfDocument|カーソルを文頭へ|
|Alt+>|EndOfDocument|カーソルを文末へ|
|Ctrl+/|EditUndo|動作を1つ戻す|
|Ctrl+w|EditCut|切り取り|
|Alt+w|EditCopy|コピー|
|Ctrl+y|EditPaste|貼り付け|
|Ctrl+s|EditFind|文字列検索|
|Alt+%|EditReplace|文字列置換|
|Ctrl+x,f|FileOpen|開く|
|Ctrl+x,s|FileSave|上書き保存|
|Ctrl+x,w|FileSaveAs|名前を付けて保存|
|Ctrl+x,c|FileCloseOrExit|Wordを終了する|

<img width="519" alt="word_command.png" src="https://qiita-image-store.s3.amazonaws.com/0/221826/7e80f562-7aa7-2802-8689-ceb145406f26.png">


## Wordマクロから
* Wordのメニューバーから**表示/マクロの表示/**に移動する。
* マクロ名に任意の名前を入力して作成を押す。
* マクロ入力画面に移るので以下のソースをコピペして保存。（既にマクロを設定している人は追記。）
* **ファイル/オプション/リボンのユーザー設定/ユーザー設定/**に移動する。
* 分類からマクロを選択。
* 対応するマクロにキーを割り当てる。

```
Sub deleteChar()
    ' Deleteキー
    Selection.Delete Unit:=wdCharacter, Count:=1
End Sub
Sub deleteBackwardChar()
    ' Back Spaceキー
    Selection.TypeBackspace
End Sub
Sub newParagraph()
    ' 改段
    Selection.TypeParagraph
End Sub
Sub newLine()
    ' 改行
    Selection.TypeText Text:=vbVerticalTab
End Sub
Sub killLine()
    ' カーソル以降の現在行をカット
    Selection.EndKey Unit:=wdLine, Extend:=wdExtend
    Selection.Cut
End Sub
Sub nextPage()
    ' 下にスクロール
    Selection.MoveDown Unit:=wdScreen, Count:=1
End Sub
Sub previousPage()
    ' 上にスクロール
    Selection.MoveUp Unit:=wdScreen, Count:=1
End Sub
```
<img width="426" alt="word_macro.png" src="https://qiita-image-store.s3.amazonaws.com/0/221826/eda55117-b281-de05-8c14-b7ad1927b1b4.png">

以上で設定は終了になります。快適なWordライフをお楽しみ下さい。
5分で作るChrome拡張機能

[株式会社アンティー・ファクトリー](http://www.un-t.com/)、[株式会社アンティー・システム](http://www.un-tsystem.com/)のXA（マークアップエンジニアチームの名称）メンバーによる[Advent Calendar](https://qiita.com/advent-calendar/2017/unt-xa) __11日目__担当の@k__watanabeです。

普段からなにかとお世話になっている__Chrome拡張機能（エクステンション）__ですが、そういえば自分で作ったことがなかったので、この機会に作ってみました。
[Chrome ウェブストア - 拡張機能](https://chrome.google.com/webstore/category/extensions?hl=ja)

クオリティの高いものを作り込んで、__Chromeウェブストア__に公開するとなると、技術や時間、登録料などもかかり大変そうですが、とりあえずローカルで動かすまでをゴールとしたら5分で作れそうです。
[What are extensions? - Google Chrome](https://developer.chrome.com/extensions)

サンプルが豊富なので助かります。
[Sample Extensions - Google Chrome](https://developer.chrome.com/extensions/samples)

機能の内容は、拡張機能の動作が、かんたんに確認できるものにしたいと思います。
（※以下、見出しの数字は所要時間の目安です。）

##00:00〜01:29 ファイル構成

本当に最低限ですから、まあ、こんなかんじでファイルを用意します。

```
.
├── css
│   └── style.css
├── img
│   └── icon.png
├── js
│   ├── background.js
│   └── jquery-3.2.1.min.js
└── manifest.json
```

## 01:30〜02:29 manifest.json

このファイルだけあればなんとかなるぞ（？）ファイル```manifest.json```の中身を書きます。

```json:manifest.json

{
  "name": "拡張機能の名前",
  "description": "拡張機能の説明",
  "version": "1.0",
  "content_scripts": [{
    "js": ["js/jquery-3.2.1.min.js", "js/background.js"],
    "css": ["css/style.css"],
    "matches": ["http://*/*", "https://*/*"]
  }],
  "browser_action": {
    "default_icon": "拡張機能のアイコン画像",
    "default_title": "ツールバーのアイコンにマウスオーバーで表示されるツールチップ"
  },
  "manifest_version": 2
}
```

本当は、ChromeのAPIの利用やDOM操作、動作状況などに違いのある```content-scripts```や```background```を適切に使い分けたり、```default_popup```でポップアップ用のhtmlを設定したりなど、いろいろありますが、ここでは割愛します。
[JavaScript APIs - Google Chrome](https://developer.chrome.com/extensions/api_index)

## 02:30〜03:29　処理の内容を書く
いよいよ処理の内容を書きます。
動作が確認できればよいので、```CSS```で背景色を変更したり、```JavaScript```で```alert```する程度のものでもよいのですが、```style.css```と```background.js```と```icon.png```はサンプルを用意しておきました。
料理番組でよくある__「…で、半日冷蔵庫で寝かしたのがこちらですね〜」__というアレなのでズルではないです。
https://github.com/p-toro/isaykai

## 03:30〜04:59　Chromeに拡張機能を読み込ませる
Chromeのアドレスバーに```chrome://extensions/```と入力しEnter。
__「デベロッパー モード」__にチェックを入れると、__「パッケージ化されていない拡張機能を読み込む…」__ボタンが出現しますので、それをクリックし、用意したフォルダを選択します。
※サンプルの場合、```build```を読み込んでもらえればオッケーです。

<img width="80%" alt="スクリーンショット_2017-12-08_15_45_42.png" src="https://qiita-image-store.s3.amazonaws.com/0/221915/bec2d55c-8414-3165-7fee-f33b8890895e.png">


## 05:00　完成
なんとか間に合いました。
ツールバーの拡張機能のアイコンが並んだエリアに今回追加したアイコンが追加されていることが確認できると思います。

<img width="313" alt="ツールバー.png" src="https://qiita-image-store.s3.amazonaws.com/0/221915/c099a524-bc98-beb0-58d8-8b6e76cf67b1.png">

今回はアイコンからのオンオフ切り替え機能はなく、常に動作しているだけの仕様なので、__有効__のチェックボックスをチェックして（ツールバーのアイコンをクリックして）好きなサイトを開けば、拡張機能の動作が確認できると思います。

サンプルで試された方は、見慣れたオシャレなあのサイトが、昔懐かしい__愛○会__のようなシンプルで力強いデザインに変更されたのではないでしょうか？

## まとめ
案件によっては気をつけなければならない独自のチェック項目があったりします。
たとえばCMSに取り込むための独特なファイルパスであったり、画面表示だけでは確認しにくい独自データ属性などです。
そういった項目をチェックする拡張機能を作ってチームで共有するというのも、よいかもしれませんね。
SourceTreeを使ってGitHubにSSH接続する (Windows)

今回、GitLFSを利用したかったためSourceTreeからGitHubにssh接続しようとしましたがなかなかうまく行きませんでした、、、
成功したときのやり方を記します。

# **SourceTreeでのSSHキーの作成**
SourceTreeを起動し、【ツール】→【SSHキーの作成/インポート】を選択します。

![ssh1.PNG](https://qiita-image-store.s3.amazonaws.com/0/201396/201bd503-2b9a-6ca5-76ef-2682263e9b18.png)



【Generate】を選択して、緑のゲージの下の空欄で適当にマウスを動かします。
マウスを動かしたランダム性からキーが作成されるようです。

![ssh2.PNG](https://qiita-image-store.s3.amazonaws.com/0/201396/06abb931-7649-c30a-a7e2-c34fef896e35.png)



キーができたら、
1.一番上の「Public key for pasting in to ....」ボックス内の長い文字列を全選択してコピーしてください。あとで使うので、テキストエディタなんかに貼り付けておくといいでしょう。 

2.【Save public ley】を選択し
「rsa_pub」と保存します。
保存場所や名前は任意です（保存場所は覚えておいてください）

3.【Save private key】を選択し
「rsa」と保存します。保存場所や名前は任意です（保存場所は覚えておいてください）
「rsa.ppk」ファイルが出来るはずです。
この時確認メッセージが出ますが、今回はパスフレーズは設定しないためそのまま【OK】を選択してください。

# **Pageantにprivatekeyを追加**
SourceTreeで、【ツール】→【SSHエージェントを起動...】を選択してください。

何も起こらないかもしれませんが、Windowsのツールバーの「^」マーク（隠れているインジケータを表示します）を開くと、下のようなマークの「Pageant」というものがあります。それをクリックしてください。
![pagent.png](https://qiita-image-store.s3.amazonaws.com/0/201396/227906b6-8dbc-4393-4948-e29306d858d0.png)

Pageant Key List が開かれるので、【Add Key】を選択し、先程作成した「rsa.ppk」を選択してください。
キーの詳細が表示されたら【Close】

# **GitHubにSSHキーを設定**
続いて、リモートリポジトリとなるGitHub側の設定です。
ブラウザでGitHubにログインし、【右上の自分のアイコン】→【Settings】を選択してください。

![giyhub1.PNG](https://qiita-image-store.s3.amazonaws.com/0/201396/882057cc-d91e-e70b-a6e7-72999dca25dd.png)



PersonalSettings 内の【SSH and GPG keys】を選択し、【New SSH key】ボタンを選択。
「Title」内には任意の名前を、「Key」には前項**「SourceTreeでのSSHキーの作成」**の**1.**でコピーしたキーの文字列をペーストしてください。

入力できたら【Add SSH key】を選択。「SSH keys」のリストに新たに追加されているのが確認できるはずです。

----

以上で完了です。

あとはGitHubからリポジトリをクローンするときにHTTPSではなくSSHを選択することに注意してください。

（記事更新）
2019年3月時点でもこの方法で大丈夫そうです。不具合があれば教えてください。

# **参考**
- [SourceTree 設定からSSH設定＆リポジトリをcloneするまでの流れ](https://qiita.com/github129/items/b23a24aaa359a0f8eba7)
Raspberry Pi で、mosquitto を使って、AWS IOT に Pub/Sub する

Raspberry Pi の　mosquitto-clientsはバージョンが古いため、mosquitto.orgで公開されているdebをインストールする必要があります。
こちらに、その記述が
[【Raspberry Pi】AWS IoTとRaspberry PiでIoTをやってみよう](http://www.kanenote.org/blog/?p=986)

```bash
wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key
sudo apt-key add mosquitto-repo.gpg.key
get http://repo.mosquitto.org/debian/mosquitto-wheezy.list
sudo cp mosquitto-wheezy.list /etc/apt/sources.list.d/
sudo apt update
sudo apt install mosquitto-clients
```

IOT のブローカーの作り方は、こちらです。
[AWS IOT の簡単な使い方](https://qiita.com/ekzemplaro/items/9b1293428c69cd2025cd)

次が必要です。
　モノの証明書      r10001.cert.pem
　プライベートキー   r10001.private.key
　ルート CA         root-CA.crt

Publish コマンド
エンドポイントは変更して下さい。

```bash
mosquitto_pub --cafile root-CA.crt \
	--cert r10001.cert.pem --key r10001.private.key \
	-h "xxx00iq1d4m00.iot.ap-northeast-1.amazonaws.com" \
	-p 8883 -q 1 -d -t r10001/topic_1 -m "Hello World"
```

Subscribe コマンド
エンドポイントは変更して下さい。

```bash
mosquitto_sub --cafile root-CA.crt --cert r10001.cert.pem \
	--key r10001.private.key \
	-h "xxx00iq1d4m00.iot.ap-northeast-1.amazonaws.com" \
	-p 8883 -q 1 -d -t r10001/topic_1
```

エンドポイントの調べ方

```bash
aws iot describe-endpoint
```

追加
次のファイルを Publish するには

```json:in01.json
{
  "greeting": "Hello World",
  "key1": "aaa",
  "key2": "bbb",
  "key3": "ccc"
}
```

```bash
mosquitto_pub --cafile root-CA.crt \
    --cert r10001.cert.pem --key r10001.private.key \
    -h "xxx00iq1d4m00.iot.ap-northeast-1.amazonaws.com" \
    -p 8883 -q 1 -d -t r10001/topic_1 -f in01.json
```
古い記事に騙されないで！hyperじゃなくreqwestを使ってください

ちょっと煽ってみました
誰も書いていなかったので[`reqwest`][reqwest]について書きます。

# TL;DR
HTTP系crateのデファクトスタンダードであった[`hyper`][hyper]は[`0.11.0`][tag]から[`tokio`][tokio]と[`futures`][futures]を採用した複雑なAPIに変わりました。
simpleでstableなHTTP clientが使いたければ`hyper`の作者でもあるseanmonstar氏の[`reqwest`][reqwest]を使うのがいいです。
もちろん、`reqwest`にデフォルトでついてくる機能がいらない場合や、高次元なcrateを自作したい場合は`hyper`を使うのが正しいです。

# 現在のhyper
clientの公式exampleが[ここ][hyper-ex-1]と[ここ][hyper-ex-2]に載っています。
かなり単純な形でも以下のようになりますね。

```rust
extern crate futures;
extern crate hyper;
extern crate tokio_core;

use std::io::{self, Write};
use futures::{Future, Stream};
use hyper::Client;
use tokio_core::reactor::Core;

let mut core = Core::new().unwrap();
let client = Client::new(&core.handle());

let uri = "http://httpbin.org/ip".parse().unwrap();
let work = client.get(uri).and_then(|res| {
    println!("Response: {}", res.status());

    res.body().for_each(|chunk| {
        io::stdout()
            .write_all(&chunk)
            .map_err(From::from)
    })
});
core.run(work).unwrap();
```
これだとGET Requestを送って結果を書き出すだけにしてはoverkillな気がします。

* extern crateが3つ必要
* この場合Asynchronousである必要がない
* リダイレクトを追うとか、Cookie、TLSなどを扱うとしたらもっと複雑になる

# Reqwest
そこで、`reqwest`です。

```toml
# Cargo.toml
[depenencies]
reqwest = "*"
```

```rust
extern crate reqwest;
use std::io;

let mut res = reqwest::get("http://httpbin.org/ip").unwrap();
res.copy_to(&mut io::stdout()).unwrap();

```
文字数がかなり減りました。

#### POST form data

```rust
let client = reqwest::Client::new();
let res = client.post("url")
    .form(&[ ("foo", "bar"), ("baz", "quux") ])
    .send().unwrap();
```
#### JSONで
`form()`を`json()`で置き換えればできます。`Serialize`をimplしていればなんでもokです。

# 背景
なんでこうなったの？についてはseanmonstarさん本人のブログ記事、[Introducing Reqwest][reqwest-blog]が詳しい。
要約すると、

* リダイレクトの処理、Cookie,コネクションプーリング、JSONペイロードなど、ほとんどのユーザがデフォルトとして望むものをまとめたライブラリが欲しかった
* `hyper`がnon-blocking I/Oを採用するので、blockingでもいいほとんどの人はこっちを使ってほしい（`AsyncClient`のようなものも後から`reqwest`に実装するつもり）
* 同時に`hyper`のAPIががっつり変わるので、その前にstableなものを提供するという位置づけ

[reddit][reqwest-reddit]で本人がまとめていますが、他の言語と比較するとこのような感じになります

|Rust|nodejs|python|Java|
|---|---|---|---|
|hyper|http|urllib2|URLConnection|
|reqwest|request|requests|OkHttpなど|

# まとめ
初心者が`hyper`でつまずかないように書きました。Event loopやfutureについて知るのも大事ですが、まずは`reqwest`から入って自由にリクエストを投げまくってほしい

[hyper]: https://github.com/hyperium/hyper
[tag]:
 https://github.com/hyperium/hyper/releases/tag/v0.11.0
[tokio]: https://github.com/tokio-rs/tokio
[futures]: https://github.com/alexcrichton/futures-rs
[reqwest]: https://github.com/seanmonstar/reqwest
[reqwest-blog]: http://seanmonstar.com/post/153221119046/introducing-reqwest
[reqwest-reddit]: https://www.reddit.com/r/rust/comments/5d48yw/introducing_reqwest/
[hyper-ex-1]: https://hyper.rs/guides/client/basic/
[hyper-ex-2]: https://github.com/hyperium/hyper/blob/master/examples/client.rs
MatchBoxを使ってCoreOS Container Linuxをベアメタルにプロビジョンする全体像

# はじめに

この記事は[Linux Advent Calendar 2017](https://qiita.com/advent-calendar/2017/linux)の8日目の記事です。

CoreOS社の提供するコンテナを稼働させることに特化したOSである、[CoreOS Container Linux](https://coreos.com/os/docs/latest/)(以下CoreOS)というLinuxディストリビューションをベアメタル環境にプロビジョンしようとしたのですが、従来のプロビジョン方法より登場人物が色々増えた上に、なんか公式ドキュメントも散らばってて、どういうことだってばよ？？と10回くらいなったので、その全体像について簡単にまとめます。

# CoreOSインストールの全体像

ざっくり箇条書きで説明します。

- CoreOSは以前プロビジョンツールにcloud-configを使っていました
- 最近ではIgnitionというCoreOSのプロビジョン用に開発されたツールを利用します
- Ignitionとは
  - Redhat系LinuxにおけるKickstartに近い立ち位置のプロビジョンツールです
  - キッティングなどの初回起動時に有効になって一度のみプロビジョン設定を反映します
  - ブートプロセスのかなり早い段階（initプロセスの起動前）で動作します
  - プロビジョン設定はパースが容易なJSON形式の設定を受け付けます
  - しかしJSON形式はプログラムでのパースは容易だが人間が記述するにはツラい形式ですよね
- 実際にはIgnitionの設定はContainer linux config（以下cl）というyaml形式で記述できます
  - clで書いたyamlを専用のトランスパイラでJSONに変換してIgnitionに渡す流れになります
  - JSON形式でもYAML形式でも[バリデータ](https://coreos.com/validate/)で文法チェックができます
- 話は変わってベアメタル環境では通常ネットワークインストールにPXE(or iPXE)を使います
- PXEインストールを実現するには通常以下のようなコンポーネントが必要です
  - TFTP、DHCP、内部DNSの機能を提供するサーバ（PXEサーバとして大体セット）
  - プロビジョン設定を提供するHTTPサーバ（RHELの場合はkickstartファイルを提供）
- CoreOSではプロビジョン設定を提供するHTTPサーバにMatchboxという専用のサーバが用意されています
- Matchboxとは
  - ネットワークブートするサーバのMACやUUIDに応じて渡すclファイルをルーティングできます
  - ルーティングだけでなくサーバ種別に応じたメタデータを定義することができます
  - clをファイルをgoのテンプレート形式で配置できメタデータを元にレンダリングすることができます
  - レンダリングされたclファイルはignition形式にトランスパイルされてブートサーバに渡されます
  - 上記の各種設定をTeraffomにより定義することができます

箇条書きが過剰になったので、最終的にネットワークブートに必要なことをまとめます。

- CoreOSのベアメタルインストールには従来のPXEに加えMatchboxというサーバを用意する必要があります
- このMatchboxの各種設定はTerraformでデプロイします
- Terrafomでデプロイするプロビジョン設定の大部分はgoのテンプレート形式のclファイル(yaml)です
- clファイルは最終的にJSONに変換されてCoreOSに渡りますが変換はMatchboxが勝手にやるので意識は不要です

# おわりに

以上ざっくりですが、CoreOSのベアメタルへのプロビジョンに必要な要素のまとめでした。
実際の環境構築やらプロビジョンについては[MatchBoxを使ってCoreOS Container Linuxをベアメタルにプロビジョンする](https://qiita.com/kanga/items/73e589318a66e6813e15)に記載していますので、興味がでたらそっちも見ていただければなと思います。

また、Matchboxについてですが、以下の資料が見やすく参考にさせて頂きました。
(というか以下のスライドみれば大体万事解決)

36ページくらいからがMatchboxの説明です
https://www.slideshare.net/zembutsu/terraform-on-bare-metal-with-tectonic
mac High Sierra でAptanaを使う

#はじめに
Aptanaを個人的に使っているが、macOSのアップデート毎に動かなくなるので、対処法。
#どうやって
Javaの古いバージョン入れないとダメなので、High Sierraなら下のリンクからダウンロードしてインストール。
https://support.apple.com/kb/DL1572?viewlocale=en_US&locale=en_US

これで動く。
GCEからCloudStrage、CloudSQLに接続する手順

#GCEにCloudStrageのバケットをマウントする
GCP(Google Cloud Platform)のGCE(Google Compute Engine)のCentOSインスタンスにCloudStrageのバケットをマウントする手順について記述します。

##ストレージの作成
まずは、ストレージにバケットを作成します。
すでに存在するバケットを使用する場合は、この手順は必要ありません。

1.GCPコンソール画面の左上のメニューボタンをクリックし、「Storage」を選択します。
<img width="398" alt="スクリーンショット 2017-12-08 14.36.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/3003/3eec384f-afe2-31ad-0745-953a5b01ec47.png">

2.「バケットを作成」をクリックします。
<img width="572" alt="スクリーンショット 2017-12-08 14.34.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/3003/ee6bfc3a-a262-302e-d4c8-7c4873c54c8b.png">

3.「バケット名」に適当なバケット名を入力します。
4.適切なストレージクラスを選択します。
5.適切なロケーション(日本なら「asia-notheast1」)を選択します。
6.「作成」をクリックし、バケットが作成されたことを確認します。
<img width="575" alt="スクリーンショット 2017-12-08 14.38.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/3003/94957e9e-52c8-24be-b611-8fb44ce32fd8.png">

##ストレージのマウント
「ストレージの作成」で作成したストレージのバケットをGCEにマウントします。
GCEでのストレージのマウントにはGoogleが提供する「Cloud Storage FUSE」を使用します。(https://cloud.google.com/storage/docs/gcs-fuse?hl=ja)

ここでは「sample-data」という名前のバケットを、GCEの/mnt/gcs-bucketにマウントする手順に基づいて説明します。
バケット名やマウント箇所はシステム構成に応じて読み替えてください。

GCEからストレージにファイルの書込み、読み込み等する場合には、GCE作成時にストレージアクセス権限：フルを設定する必要があります。
<img width="567" alt="スクリーンショット 2017-12-08 14.40.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/3003/e67f9d40-95ba-79d2-57c5-d9f98251ddbc.png">

1.Cloud Storage FUSEをインストールするため、yumのリポジトリを登録します

```
sudo tee /etc/yum.repos.d/gcsfuse.repo > /dev/null <<EOF
[gcsfuse]
name=gcsfuse (packages.cloud.google.com)
baseurl=https://packages.cloud.google.com/yum/repos/gcsfuse-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
       https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
```

Cloud Storage FUSEをインストールします。

```
sudo yum update
sudo yum install gcsfuse
```

マウントするためのディレクトリを作成します。

```
mkdir /mnt/gcs-bucket
```

Cloud Storage FUSE を使用してバケットをマウントします。

```
gcsfuse sample-data /mnt/gcs-bucket
```


#GCEからCloudSQLに接続する
GCP(Google Cloud Platform)のGCE(Google Compute Engine)のCentOSインスタンスからCloudSQLのMySQLデータベースにCloudSQLProxyを使って接続する手順について記述します。

##GCEのアクセス権設定
GCEからCloudSQLに接続する場合には、CloudSQL：有効を設定する必要があります。
<img width="565" alt="スクリーンショット 2017-12-08 16.39.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/3003/d41dbaec-738f-95ba-99fd-96bf10a1cc56.png">

##CloudSQLProxyによる接続
1.GCEインスタンスにSSH 接続します。
2.MySQLクライアントをインストールします。

```
sudo yum install mysql
```

3.CloudSQLProxyをインストールします。

```
wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.386 
mv cloud_sql_proxy.linux.386 cloud_sql_proxy
chmod +x cloud_sql_proxy
```

4.プロキシを開始します。
※instances の値は GCP コンソールの CloudSQL 画面内「インスタンス接 続名」を参照。

```
./cloud_sql_proxy -instances=secure-medium-xxxxxxx:asia-northeast1:xxxxxxx=tcp:3306
```
<img width="585" alt="スクリーンショット 2017-12-08 16.44.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/3003/f3ced1ab-5b16-3789-b5eb-f3a40d5e4817.png">

5.MySQLに接続します。

```
mysql -u xxxxxxx -p --host 127.0.0.1
```
redashで集約したデータをGoogleSpreadSheetで取り扱う ~ redashをデータAPIとして使う ~


「redash spreadsheet」で検索すると、spreadsheetをredashのデータソースにする方法しか乗っておらず、逆にredashでかき集めたデータをspreadsheetで取り扱う方法を見つけられませんでした。

そこで今回は「既存の管理表にこのデータも紐づけてほしいんだよね〜」みたいなときに使える、『redashを経由してspreadsheetでデータを扱えるようにする方法』をまとめました。

## 1. redash APIの設定

a. クエリを書く
通常どおり、ほしいクエリを書いてsaveします
![query.png](https://qiita-image-store.s3.amazonaws.com/0/68146/25cbbbd5-f3a3-c645-bfd2-2f736f9ffafa.png "query.png")

b. API KEYを取得
メニューの「Show API Key」をクリックして、API KEYを取得します
![api.png](https://qiita-image-store.s3.amazonaws.com/0/68146/eeaad053-4d6f-be79-3ffe-2eb09fe9b297.png "api.png")
![api key.png](https://qiita-image-store.s3.amazonaws.com/0/68146/96bdd4ff-e2db-d1c4-f95f-5e2ffb20f6b0.png "api key.png")

c. urlを生成
作成したクエリのurlからqueryのidを取得して、先ほど取得したAPI Keyと合わせて以下のようなurlを生成します。
（これをブラウザで叩くとcsvをダウンロードできます）

```
https://[redash domain]/api/queries/[queryのid]/results.csv?api_key=[API Key]
```

## 2. google spreadsheetで表示

a. IMPORTDATA関数を用いて、redashのデータを取り込み
新しいシートを作成して、左上のセルに以下の式を埋め込みます

```
=IMPORTDATA("https://[redash domain]/api/queries/[queryのid]/results.csv?api_key=[API Key]")
```

b. vlookupなどで、取り込んだデータと既存のデータを紐付けます

## 最後に
「既存の管理表にこのデータも紐づけてほしいんだよね〜」というときに、真面目にAnalyticsやアプリケーションDBにクエリを投げてもいいですが、redashにデータを統合しているならredashをデータのAPIとして利用すると簡単にspreadsheetにデータを取り込めます

是非やって見てください
bitFlyerの板情報をリアルタイムに取る

# 新APIとPubNub配信の廃止

公式のAPIドキュメントが更新されて、PubNubでの配信は廃止を検討中となっていた。
廃止時期は不明。
[bitflyer Realtime API](https://lightning.bitflyer.jp/docs?lang=ja&_ga=2.73063700.645158987.1527824070-1893271199.1527824070#realtime-api)

- Socket.IO 2.0 (WebSocket)
- JSON-RPC 2.0
の２つが新しく追加されていた。

twitterの評判を眺めた限りだと、JSON-RPCのほうが抜け漏れが少ないらしいので、そちらに移行予定。

# 概要
bitFlyerのリアルタイムAPIをつかって、板情報を取得するのを試したメモ
[価格のサンプル](https://lightning.bitflyer.jp/docs?lang=ja#realtime-api)はあるが、板のサンプルがないため作ってみた

# API情報

bitFlyerのAPIは、PubNubを利用してリアルタイムの更新情報を配信している。
板情報は口座や認証なしで取得が可能
レスポンスの量が多いせいか、2つのチャンネルに分かれている。

- [lightning_board_snapshot_BTC_JPY](https://lightning.bitflyer.jp/docs?lang=ja#板情報-1)
  - 板情報全体が流れてくるチャンネル
  - だいたい10分毎ぐらいにながれてくる。
- [lightning_board_BTC_JPY](https://lightning.bitflyer.jp/docs?lang=ja#板情報の差分)
  - 差分情報がリアルタイムに流れてくるチャンネル　こちらはほぼリアルタイム
- [lightning_ticker_BTC_JPY](https://lightning.bitflyer.jp/docs?lang=ja#ticker-1)
    - 本来は必要ないが、差分の抜け漏れが発生する場合、このチャネルを使って補正する

# 取得サンプル

pubnubのsubscribeで一度にchannelを複数指定できる。

channel名が流れてくるので、スナップショットか差分情報かも判断がつく。
スナップショットを取得した後、差分情報をつかって更新することで板情報を再現できそう。

```javascript
var PubNub = require('pubnub');
var pubnub = new PubNub({
  subscribeKey: 'sub-c-52a9ab50-291b-11e5-baaa-0619f8945a4f'
});
pubnub.addListener({
  message: function (message) {
    // pubnubの配信時刻 unixtime+ナノ秒
    // console.log(message.channel, message.timetoken);
    console.log(message.channel, message.message);
  }                                                                                                                                                                        });

//複数のchannelをsubscribeすることができる
pubnub.subscribe({                                                                                                                                                           
  channels: ["lightning_board_BTC_JPY",
             "lightning_board_snapshot_BTC_JPY"],
});
```


# 消えた価格帯はどうなるか

priceに価格帯、sizeが0として流れてくる

```
lightning_board_BTC_JPY { mid_price: 2150320,
  bids: [ { price: 2147720, size: 0 } ],
  asks: [ { price: 2150632, size: 0.432 }, { price: 2153639, size: 0 } ] }
```

# 罠1
ただし差分の抜け漏れが2017年9月から2017年12月末ごろまで発生していた。
約定して消えたはずの板が残り続ける減少が発生していた。
暫定対策として、tickerのチャネルを受信してbest ask, best bid間の板を消すようにした

## 参考情報
https://twitter.com/bF_TASK/status/911568891960188928
https://twitter.com/ksudo/status/908949830612873216

# 罠2
bitflyerは毎日日本時間の4:00~4:10は定期メンテとなる。
4:11ごろから板寄せが行われる。
(注文はできるが約定しない?)この間もリアルタイムAPIに、データが流れてくる。
加えて、price:0のデータが流れてくる（何を表すものなのか不明）
このデータも差分の抜け漏れが発生することがある

ちなみに、cryptowatchのグラフではこの時間帯はデータなし扱いになっている。

# 残り課題
- 差分の時刻情報がレスポンスにないので、スナップショットの配信が遅延するとずれそうな気がする。。。
    - pubnubの配信時刻(message.timetoken)の値を使うしかなさそう
GoogleTagManagerが全然わからないのでメモをバシバシ貼ってみるテスト

まず
Google タグマネージャ利用規約 が日本語化されていないので怖くてOKが押せない。
のですが
まぁGoogle翻訳で見てみた所　大丈夫そうだったのでOKを押すっ

次に
なんか貼ってと言われたのでなんか貼ってみるっ

次に
何をやるんだろ？
何が出来るのだろう？
関数型言語Elmでテスト駆動開発

Elm アドベントカレンダーの8日目です。

関数型言語Elmでテスト駆動開発シリーズのまとめです。

# インデックス

- [1~4章](https://qiita.com/ababup1192/items/d6ca1af6efcbac8d550f)
    - ドルの定義, timesの定義まで
- [5~7章](https://qiita.com/ababup1192/items/5b9d6293210b1b09015d)
    - フランの定義まで
- [8~11章](https://qiita.com/ababup1192/items/23185f087ba6811a61d0)
    - Money, 通貨, ファクトリメソッドの定義まで
- [12~13章](https://qiita.com/ababup1192/items/4d30016776312344d895)
    - reduceの定義まで
- [14章](https://qiita.com/ababup1192/items/efc8355281a656479f3a)
    - レートを考慮したreduceの定義まで
- [15~16章](https://qiita.com/ababup1192/items/0ab4c6083044f3e45a28)
    - MoneyからExpressionに抽象度を引き上げ、様々なテストの追加まで

# まとめと反省 

今回のシリーズを書ききって改めて、[テスト駆動開発](https://www.amazon.co.jp/dp/4274217884)の素晴らしい書籍だと確信しています。多くの人に向けてJavaで書かれていますが、関数型言語で書かれているテスト駆動の書籍が出版されても良いとも思っています。しっかりした題材があるお陰で当初の予想以上にElmの勉強ができましたし、テスト駆動開発の手法の勉強にもなりました。反省としましては、自分の能力が低かった故に綺麗な道筋に沿ってテスト駆動開発・関数型言語の魅力が十分に伝えられなかった点と、書籍を読んでいらっしゃらない方たちには元コードを上げていない都合上読みづらかったのではないかと悔やんでいます。総合的には個人的には成功だと感じているので、他のオブジェクト指向設計やドメイン駆動開発などにもElmでチャレンジしようかと考えています。シリーズを読んでくださった方、宣伝してくださった方、アドバイスをしていただいた方、本当にありがとうございました。
チェックボックスやラジオボタンの見た目に Font Awesome のアイコンを使う

# 制限事項

サンプルコードの HTML は Bootstrap 4 を導入していることを前提としています。また Bootstrap 4 の [ドキュメント](https://v4-alpha.getbootstrap.com/components/forms/#checkboxes-and-radios) に掲載されている HTML に合わせるため、input 要素に関しては label 要素の中に input 要素を配置する書き方とします。

# ソース

## HTML (Slim)

```slim
.form-check
  label.form-check-label
    input.form-check-input type='checkbox' name='madohomu' value='madoka'
    span.label-name 鹿目まどか
.form-check
  label.form-check-label
    input.form-check-input type='checkbox' name='madohomu' value='homura'
    span.label-name 暁美 ほむら

.form-check
  label.form-check-label
    input.form-check-input  type='radio' name='kyosaya' value='kyoko' checked=true
    span.label-name 佐倉 杏子
.form-check
  label.form-check-label
    input.form-check-input type='radio' name='kyosaya' value='kyoko'
    span.label-name 美樹 さやか
```

## CSS (SCSS)

```scss
input[type='checkbox'] {
  display: none;
  
  & + .label-name::before {
    display: inline-block;
    font-family: FontAwesome;
    margin-left: -1.25rem; // .form-check-label の padding-left を打ち消す。
    margin-left: -1.25rem; 
    width: 1.2rem;
  }
  
  & + .label-name::before {
    content: "\f096"; // fa-square-o
  }
  
  &:checked + .label-name::before {
    content: "\f046"; // fa-check-square-o
  }
}

input[type='radio'] {
  display: none;

  & + .label-name::before {
    display: inline-block;
    font-family: FontAwesome;
    margin-left: -1.25rem;
    width: 1.2rem;
  }

  & + .label-name::before {
    content: "\f10c";
  }

  &:checked + .label-name::before {
    content: "\f05d"; // fa-check-circle-o
  }
}
```

# スクリーンショット

![スクリーンショット 2017-12-08 16.12.24.png](https://qiita-image-store.s3.amazonaws.com/0/6697/39ae43f0-1e93-9905-193a-edf3867f6cb5.png)

# デモ

[Checkbox meets Font Awesome](https://codepen.io/quanon/pen/KyjeLe)
Railsとかでパスワードフィールドに全角入れると勝手に半角になる


```ruby

<input type="password" name="password">

<%= password_field(:password) %>

<%= f.password_field :password %></td>

<%= password_field_tag(:password) %>

```

という形で、パスワードフィールドを生成して実際に全角で色々打ってみると勝手に半角で扱ってくれるっぽい。

入力値|処理値
:-:|:-:
あいうえお|aiueo
！”＃＄％|!\"\#$%
１２３４５|12345
たく|taku

　※コピペした場合はコピーした内容がそのまま送信されるっぽい。

多分Railsがってより、input要素のpasswordタイプの仕様的にそうなるっぽいね。
ちなみに調べてたら出てきたけど、html5だとinput要素の`pattern`属性に色々バリデーション書けるらしいね。

https://qiita.com/ka215/items/795a179041c705bef03b
micro:bit スマホでも開発できるらしいぞ - 解決編

これは [micro:bit Advent Calendar 2017](https://qiita.com/advent-calendar/2017/microbit) の 11 日目の記事です。

さて「[micro:bit スマホでも開発できるらしいぞ](https://qiita.com/CYonezawa/items/9adc90807d0aaa6da366)」で Flash できず力尽きていましたが、結論から言いますと

おおお
![IMG_8858.PNG](https://qiita-image-store.s3.amazonaws.com/0/164551/cc2ac5e3-d388-80a1-63f1-0c9391dcd793.png)

書き込めた！
![IMG_8859.PNG](https://qiita-image-store.s3.amazonaws.com/0/164551/114ef624-08db-dd4f-23b8-5eeb15f4bdc3.png)

のでありました。ばんじゃい！

## 原因
ペアリングのプロセス
![IMG_8853.PNG](https://qiita-image-store.s3.amazonaws.com/0/164551/a1fbbfc4-3027-6802-e2c4-1aea014d2372.png)
で Next をタップすると「ペアリングしますか？」とスマホ側に現れるのですが、このときに PIN の入力を求められませんでした
つまり Bluetooth 端末の登録はできたのですが、PIN が設定されていなかったので Flash の際に接続できなかったのでした
正しいプロセスでは、micro:bit 側で、矢印 ← が現れます
ここで A ボタンを押すと PIN コードが表示されます

## 解決方法
スイッチサイエンスさんの [chibibit FAQ](http://trac.switch-science.com/wiki/chibibit_FAQ) にある「無線の書き込みが失敗したときは、一度有線越しにプログラムを書き込む」ことで解決しました
自分のプログラムを書き込んだときには、解決できなかったのは何故だろうという疑問はありますが、手順は以下です。

1. micro:bit を USB ケーブルを使って PC と接続する
2. [プログラム](https://s3-ap-northeast-1.amazonaws.com/switch-science.public/chibibit_code/chibibit_show_hello.hex) を micro:bit に書き込む
3. 書き込みが成功すると LED 上に「Hello!」の文字列が流れます
4. スマホ側の Bluetooth の設定を解除します
5. micro:bit アプリで、手順どおりペアリングを行ないます
6. スマホのアプリから Flash を行い、プログラムを書き込みます

## 課題
よっしゃーできたぞーってことで、プログラムをちょっと拡張して再度書き込もうと Flash を行なったところ... つながらなくなりました...
再度、解決方法を使ってつなぎなおすと書き込める
でもやっぱり、続けての書き込みができない
結局有線に頼る...
しばらくは思いついたアイデアをささっと作るのに使うだけになりそうですが、その使い方でもいいかなぁ..

今後のアプリのアップデートとかで解決されるのかしらん..
CSSを楽しく書く技術

突然ですがみなさん、CSS楽しいですか？

最近、**「CSSはつらい」「CSSはうんち」**みたいな記事とかつぶやきとか多い気がします。

たしかにCSSのよくない部分もあったりしますが、僕はCSSが好きなのでできるだけ楽しくCSSを書きたいなーと思っています。

そこで、今回はCSSを楽しく書くためのポイントをまとめました。

## AltCSS使う
まあこのご時世、CSS直接書いてる人なんていないと思いますけど。AltCSS使いたいですよね。
PostCSSでもSassでも良いと思います。**僕はStylusが好きです。**

stylusの悪いところはドキュメントが不親切なところですね。
エラーでハマってGitHubのissueを読み漁ることもしばしば…

## 自動化する
楽しく書くためには余計なことには気を使わないのが一番です。
プロパティの順番とかprefixとかは自動化しちゃいましょう。

[CSScomb](http://csscomb.com/)
プロパティの順番をいい感じにしてくれるツール

[Autoprefixer](https://github.com/postcss/autoprefixer)
Web版もある

## Lintツールを使う
Lintのルールに沿ってコーディングするだけで体裁の整ったCSSが書けるようになります。書きながらコードをチェックするのはとても大変なので、ツールに任せてしまうのが良いですね。
やはり適度にルールがあったほうが良いコードが書けます。

[stylelint](https://stylelint.io/)

## 小さく作ってみる
僕はウェブサイトのCSSを書くときも、ボタンとかフォームとかの共通で小さいパーツからスタイルを考えるようにしています。
コンポーネント指向を意識しているというのもありますが、ページを上から実装していくとmarginのもたせ方とかが場当たり的になってしまって、後から書き直すことが多かったというのもあります。

パーツから全体へ視点を広げていくことで、無理のないCSSを書くことができると思います。

## コードを公開する
これよくできたな！って思ったらコードを公開してみるのもいいと思います。
個人的にはCodePenが好きです。

コードを公開することでフィードバックがもらえたり、新しい発見があったりしますしね。
良いことばかり！

## 楽しいCSSライフを送りましょう！
npm WARN npm npm does not support Node.js v9.2.0


`npm i`でエラーが出ました。 環境はLinux(Ubuntu v16.04)です。

```bash
npm WARN npm npm does not support Node.js v9.2.0
npm WARN npm You should probably upgrade to a newer version of node as we
npm WARN npm can't make any promises that npm will work with this version.
npm WARN npm Supported releases of Node.js are the latest release of 4, 6, 7, 8.
npm WARN npm You can find the latest version at https://nodejs.org/
WARNING: You are likely using a version of node-tar or npm that is incompatible with this version of Node.js.
Please use either the version of npm that is bundled with Node.js, or a version of npm (> 5.5.1 or < 5.4.0) or node-tar (> 4.0.1) that is compatible with Node.js 9 and above.
/home/n0bisuke/.nodebrew/node/v9.2.0/bin/node[40699]: ../src/node_zlib.cc:437:static void node::{anonymous}::ZCtx::Init(const v8::FunctionCallbackInfo<v8::Value>&): Assertion `args.Length() == 7 && "init(windowBits, level, memLevel, strategy, writeResult, writeCallback," " dictionary)"' failed.
 1: node::Abort() [npm]
 2: node::Assert(char const* const (*) [4]) [npm]
 3: 0x1255aff [npm]
 4: v8::internal::FunctionCallbackArguments::Call(void (*)(v8::FunctionCallbackInfo<v8::Value> const&)) [npm]
 5: 0xb77f9c [npm]
 6: v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*) [npm]
 7: 0x1131ea0042fd
Aborted (core dumped)
```



## npmとnode.jsを入れ直し

* https://github.com/npm/npm/issues/19019
* [npm WARN npm npm does not support Node.js v9.1.0](https://stackoverflow.com/questions/47226238/npm-warn-npm-npm-does-not-support-node-js-v9-1-0)

この辺みて対応しました。

>It turns out that the current installed npm is not compatible with the new node and has a hard time updating.

>The solution is to uninstall npm and then reinstall node which will contain the correct version of npm.

らしいので、npmを一回消してnodeを再インストールすると良さそう。

```bash
$ npm uninstall -g npm
```

で消せばOKとのことです。nodebrewでインストールしてるNode.jsも一回消して再度入れ直します。

* 削除

```bash
$ nodebrew uninstall 9.2.0
```

* 再インストール

```bash
$ nodebrew install-binary 9.2.0
```

## 再チャレンジ

```bash
$ npm i

npm WARN assets No description
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.1.3 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

added 479 packages in 5.897s
```

問題なく実行できました。
不安なくOrphanブランチを作る方法 by GitHub(リモートgit)


私はOrphanブランチが大好きだ。ドキュメントや資料やウェブページなどはぜひそこで管理していってほしい。

# いきなりやり方

クローンして `checkout --orphan` するのではなく `git remote add origin` して `git push origin master:orphan-doc` しちゃうと楽。

例) `project` というディレクトリとリポジトリで運用しているところに `orphan-doc` というブランチを追加する

```
$ git clone https://github/project.git # これで projectディレクトリができ、普段はこっちで作業
$ mkdir ./project-orphan-doc # ここがドキュメント用ディレクトリ
$ cd project-orphan-doc
$ git init
$ git remote add origin https://github/project.git
$ touch document.doc
$ git add .
$ git commit -m '1st orphan-doc commit'
$ git push origin master:orphan-doc  # ←これでリモートにはブランチ名が orphan-doc でプッシュできるのでエラーがおきない
```


# Orphanブランチとは

`Orphan` とは孤児のこと。普通gitリポジトリといえば基本となるコミットがあるそれを親として差分で管理していく。ブランチをわける、切るというのはこの親から枝分かれすることを指す。親と差分が基本な構造な中、突如として「何も親にもたないブランチ」を実は作ることができる。これが **Orphanブランチ** である。

![スクリーンショット 2017-12-08 15.12.27.png](https://qiita-image-store.s3.amazonaws.com/0/50220/dfdea2e1-2f7d-f3d7-cff0-4bbcb1a21ad0.png "スクリーンショット 2017-12-08 15.12.27.png")

この赤矢印に注目。どのブランチを親にももたないブランチが突如現れている。

# 動機

本質の管理対象であるソースコードをgitリポジトリで管理する以外に、管理したいドキュメントや他リソースというのは必ずでてくる。仕様書やドキュメント、宣伝ページ、密接なデプロイツールなどなどである。これらを別リポジトリ、別エクセル、別フォルダ・・・などで管理してもいいが、だいたいでてくるのは「これ、どの時点の話だ？」というのがわからなくなってしまうという問題である。更新日付を目で追いかけ、脳でソートしながら追いかけないといけないのは大変だ。

これの1つの解決策として「それも同一gitで管理しちゃえばいいじゃん？」という策があるが、自動テストのある昨今、本質の管理対象以外の更新でブランチが伸びることは非常に業務コストがあがってしまうことがある。つまり、余計なコミットはmasterブランチには入れたくない。

そこで出てくるのが「ドキュメント専用ブランチの運用」である。こういったときにOrphanブランチは用いられる。

# 問題

Orphanブランチを作成するのは実は結構ややこしい。その手順は簡単で作業ディレクトリで `git checkout --orphan` でブランチはできるが、孤立したブランチを作ったはいいものの、作業ディレクトリに既存ファイルが残っているので `git rm -rf .` しなくてはならない。

これがコワイのである。

恐怖を克服したとしても、ブランチを移動するとファイルがどーんと消えたり復活したりでとてもコストがでかい。

# 運用

そういうのがコワイので、運用としては例えば『project』というリポジトリだと

```
project
project-orphan-doc
```

とこのように2つのディレクトリに分けて運用し、各ディレクトリではorphanブランチにはスイッチしないという運用をしている。前述したようなタイミングを調べるときにはremoteを経由してfetchしたりし、ツールで確認する。

# やり方

最初に書いた「いきなりやり方」をご参照ください。
WordPress管理画面のサイドバーメニューからカテゴリー、タグを削除


```functions.php
//サイドバーメニューからカテゴリー、タグを削除
function remove_menu() {
	remove_submenu_page('edit.php', 'edit-tags.php?taxonomy=category');
	remove_submenu_page('edit.php', 'edit-tags.php?taxonomy=post_tag');
}
add_action('admin_menu', 'remove_menu');
```
install google-home-notifier

centos7でnpmで入れようとしたところ

```bash
npm install google-home-notifier
```
そもそもnpmで以下のエラーが出た

```
npm: relocation error: npm: symbol SSL_set_cert_cb, version libssl.so.10 not defined in file libssl.so.10 with link time reference
```

これは以下で解決。

```bash
yum update openssl
```

もう一回トライしてみるも、何やら足りないとエラー。

```bash
yum install -y avahi-compat-libdns_sd-devel
```

これで解決してインストールできた。
pip install ibm_dbが失敗する

#始めに
PythonでIBM Cloudで提供されているサービスDB2 on Cloudを利用するときに必要なパッケージibm_dbをインストールするのに戸惑ったので、手順をまとめます。
ibm_dbをインストールするには

```
pip install ibm_db
```

とだけ打てば良いのかと思っていたのですが、そうではありませんでした。
単にpip install ibm_dbだけ実行すると、以下のようなエラーが出てきてインストールに失敗してしまいます。

```
Faild building wheel for ibm-db
```

#環境
Windows7
Python 3.6

#手順
```
pip install ibm_db
```
を実行する前に、DB2のドライバーを先にインストールする必要があります。

１．まずは、DB2のドライバーをこちらのサイトからダウンロードしてインストールします。
（ダウンロードする際に、IBM IDが必要です）
https://www-01.ibm.com/support/docview.wss?uid=swg21385217

ダウンロードするのは下の方にある「IBM Data Server Client」です。
ご利用の機種に合わせてインストーラーをダウンロードしてください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/191958/60eaab8e-0efc-99cf-31ee-b85093ee557b.png)

ドライバーのインストールが完了したら準備です。

２．コマンド・プロンプト等を開いてpip install ibm_dbと入力する
これでibm_dbのインストールに成功するはずです。

#参考
IBM データ・サーバー用の Python 環境のセットアップ
https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_9.5.0/com.ibm.db2.luw.apdv.python.doc/doc/t0054367.html
【zsh】まだhistoryで消耗してるの？コマンド履歴検索が捗るpecoの設定方法【oh-my-zsh】

普段コマンド履歴を遡りたいときは、
`history`
と打つか、
`ctrl + r`
だと思うのですが、
これらを更に使いやすくする方法があってそれがかなり便利だったので紹介させてください。

環境はMacです。

## 設定後はこんな感じになる

通常の状態から、`ctrl + r`を押すと、


![スクリーンショット 2017-12-08 15.23.57.png](https://qiita-image-store.s3.amazonaws.com/0/186346/0f816d01-1248-eb86-e4e4-fa8fab54dcaf.png)


と言うかたちでhistoryコマンドで表示される内容がズラッと表示されます。
この状態で↑や↓、
`ctrl + p`, `ctrl + n`
でマーカーを動かしてエンターを押すとそのコマンドがターミナルに打たれます（実行はされない）
もう一度エンターを押すとコマンド実行となるので、以前打ったコマンドを少し変えて実行したいというケースにも対応できます。

また上記の`ctrl + r`を押した状態で検索したい文字列を入力するとそれフィルタリングしたコマンド履歴を表示してくれるのです。

また、お目当てのコマンドがすぐに見つからなかった場合、エスケープキーですぐに抜けられます。


というわけで設定の仕方です


## 設定方法

### pecoのインストール

`brew install peco`
で入ります。簡単ですね。

### zshrcの編集

`vi ~/.zshrc`
でファイルを開き、最下行あたりに以下を追記します。

```
function peco-history-selection() {
    BUFFER=`history -n 1 | tail -r  | awk '!a[$0]++' | peco`
    CURSOR=$#BUFFER
    zle reset-prompt
}

zle -N peco-history-selection
bindkey '^R' peco-history-selection
```

でOKです。

そしたら、
`exec zsh -l`
でzshを再起動（再ログイン）


これで、
`ctrl + r`
を押すと見事コマンド履歴が素敵な感じで表示されます。

## fc: event not found: -n というエラーが出る場合

zshrcに書いた、

```
BUFFER=`history -n 1 | tail -r  | awk '!a[$0]++' | peco`
```

の部分を、

```
BUFFER=`\\history -n 1 | tail -r  | awk '!a[$0]++' | peco`
```

と書き換えてzshを再起動でいけるはずです。
幸せいっぱいですね。

## ubuntuの場合
この記事はMac前提で書いてますが、自分用のメモとして、
Ubuntuの場合は、

```
BUFFER=`history -n 1 | tail -r  | awk '!a[$0]++' | peco`
```

は

```
BUFFER=`\\history -n 1 | tac | awk '!a[$0]++' | peco`
```

となります。
nginx mrubyとHTTP2対応のDockerfile

# 概要
Dockerfileでngx mrubyとhttp2対応する
OpensslはUbuntu 16.10なら1.0.2gなのでsrc展開不要、openss-devを忘れなければOK

### Dockerfile
```
FROM ubuntu:16.10
LABEL  maintainer "Ryo Tamura Yapodu Inc, <tamura@yapodu.co.jp>"

RUN apt-get -y update
RUN apt-get -y install sudo openssh-server
RUN apt-get -y install git
RUN apt-get -y install curl
RUN apt-get -y install rake
RUN apt-get -y install ruby ruby-dev
RUN apt-get -y install bison
RUN apt-get -y install libcurl4-openssl-dev
RUN apt-get -y install libhiredis-dev
RUN apt-get -y install libmarkdown2-dev
RUN apt-get -y install libcap-dev
RUN apt-get -y install libcgroup-dev
RUN apt-get -y install make
RUN apt-get -y install libpcre3 libpcre3-dev
RUN apt-get -y install libmysqlclient-dev
RUN apt-get -y install build-essential
RUN apt-get -y install ruby-build

WORKDIR /usr/local/src
  RUN wget http://nginx.org/download/nginx-1.13.7.tar.gz \
  && tar zxvf ./nginx-1.13.7.tar.gz

WORKDIR /usr/local/src
  RUN git clone git://github.com/matsumoto-r/ngx_mruby.git \
  && cd ngx_mruby \
  && git submodule init \
  && git submodule update \
  && ./configure --with-ngx-src-root=/usr/local/src/nginx-1.13.7 \
  && make build_mruby \
  && make generate_gems_config

WORKDIR /usr/local/src
  RUN cd nginx-1.13.7 \
  && ./configure --prefix=/usr/local/nginx/ \
  && ./configure --add-module=../ngx_mruby --add-module=../ngx_mruby/dependence/ngx_devel_kit --prefix=/usr/local/nginx/ --with-http_ssl_module --with-http_v2_module  \
  && make \
  && make install
```

## 追加設定 or buid後作業
- HTTP2はSSL通信なのでSSLの設定等を入れる
- コンテナが1GBくらいあるので、ダイエットできるはず
[c++] キャプチャしていないラムダは関数ポインタとして扱える


SIGINT を受けた場合に handler内でステートマシンのイベントを発火しようと考えた。

そのときに、キャプチャの有無によってエラーが発生し、
キャプチャしていないラムダが関数ポインタに渡せることを知ったので残しておく。

[コード](https://wandbox.org/permlink/XN73yPweLjlxqh96)

ただ、SIGINT の handler内でやれることは決まっており、未定義動作が発生しうるとのこと。
-> 生のsignalを使うより libev の ev::sig を使ったほう便利。

# 参照
https://stackoverflow.com/a/11468500/8140946