OmniAICreator/Qiita-1.07M huggingface dataset:
fabric8を使ってKubernetes上にLoggingとMetrics環境を構築する

## はじめに
このエントリーは[Kubernetes Advent Calendar 2016](http://qiita.com/advent-calendar/2016/kubernetes)の6日目の投稿になります。Kubernetes上にログ収集と監視の仕組みを構築します。

## 事前準備
事前に[fabric8を使ってKubernetes環境をローカルに構築する](http://qiita.com/muraken720/items/1c4525f7f0dd35a43b2c)に従って、ローカルにminikube環境が構築できているものとします。

## Loggingの構築

fabric8ではログ収集の仕組みとして[Logging](https://fabric8.io/guide/logging.html)というマニフェストを公開しており、簡単にKubernetes上にデプロイすることができます。Loggingは内部的には、[Elasticsearch](https://www.elastic.co/products/elasticsearch)、[Fluentd](http://www.fluentd.org/)、[Kibana](https://www.elastic.co/products/kibana)によって構成されています（残念ながら、Elasticseaarch、Kibanaは最新版のVer.5ではありません）。

LogstashではなくFluentdなのは、FluentdがDockerのlogging driverに対応しており、logging driverを使ってdockerコンテナのstdoutをそのまま流せる仕組みがあるためのようです。

### 手順

[fabric8のマニフェストが公開されているページ](http://fabric8.io/manifests/kubernetes.html)から、loggingのyamlを確認し、次のようにコマンドを実行します。

```
kubectl apply -f http://central.maven.org/maven2/io/fabric8/platform/packages/logging/2.4.5/logging-2.4.5-kubernetes.yml
```

elasticsearchはpersisent volumeが必要になるので、次のコマンドを実行し、persisent volumeを生成します。

```
gofabric8 volumes
```

これで手順は完了で、各pod、serviceの起動が完了したら、Kibanaのサービスにアクセスしてください。

## Metricsの構築

fabric8で監視の仕組みとして[Metrics](https://fabric8.io/guide/metrics.html)というマニフェストを公開しており、簡単にKubernetes上にデプロイすることができます。Metricsは内部的には、[Prometheus.io](https://prometheus.io/)、[Grafana](http://grafana.org/)によって構成されています。

fabric8-maven-pluginによってspring-boot アプリケーションをデプロイしている場合は[Jolokia](https://jolokia.org/)によりJMX Metricsをとれるようになります。

### 手順

[fabric8のマニフェストが公開されているページ](http://fabric8.io/manifests/kubernetes.html)から、metricsのyamlを確認し、次のようにコマンドを実行します。

```
kubectl apply -f http://central.maven.org/maven2/io/fabric8/platform/packages/metrics/2.4.5/metrics-2.4.5-kubernetes.yml
```

Prometheusもpersisent volumeが必要になるので、次のコマンドを実行し、persisent volumeを生成します。

```
gofabric8 volumes
```

これで手順は完了で、各pod、serviceの起動が完了したら、Grafanaのサービスにアクセスしてください。

## おわりに

というわけで、fabric8を使ってKubernetes上にElaasticseaarch-Fluentd-KibanaによるLogging環境の構築とPrometheus-GrafanaによるMetrics環境を構築することが簡単にできました。このエントリーでは単に触れる環境を構築しただけですが、まずは触ってみて、実際の運用にどのように使えるか、また足りない部分は何なのかを検証することができると準備は整いました。この環境をもとにあれこれ検証してみます。
(メモ) Djangoにおけるテンプレートファイルの探索順序


完全にメモ。

```text:テンプレートの探索順序例
django.template.loaders.filesystem.Loader: /Users/01013548/repositories/evolve/django_training/mysite/templates/index.html (Source does not exist)
django.template.loaders.app_directories.Loader: /Users/01013548/.pyenv/versions/3.5.2/lib/python3.5/site-packages/django/contrib/admin/templates/index.html (Source does not exist)
django.template.loaders.app_directories.Loader: /Users/01013548/.pyenv/versions/3.5.2/lib/python3.5/site-packages/django/contrib/auth/templates/index.html (Source does not exist)
django.template.loaders.app_directories.Loader: /Users/01013548/repositories/evolve/django_training/mysite/myapp/templates/index.html (Source does not exist)
```

探索先としては
1. Djangoプロジェクト(mysite)直下のtemplateディレクトリ内部
2. pythonのライブラリやらのパス(まあ、これはあんまり使わないか...用途が見えない)
3. Djangoプロジェクト内のアプリケーション(myapp)のtemplate内


1についてはsetting.py内部のTEMPLATE.DIRSでos.path.join(BASE_DIR, 'templates')を
指定しているので、出ている模様。

2, 3については同じくsetting.py内部のTEMPLATES.APP_DIRSでTrueをしているので探索できている模様。(Falseにすると探索しなくなった)
rustupでRustをインストールして動かす

[インストールドキュメント](https://www.rust-lang.org/en-US/install.html)をみるとRustをインストールするにはrustupを使うのが推奨されているみたい。rustupはRustのToolchain management toolとのこと。ホスト側のOSのアーキテクチャ用のRust用のツールのインストールをやってくれたり、ツールチェーンのバージョン管理をやってくれるみたい。他のアーキテクチャ向けのツールチェーンを管理する事で、クロスコンパイルとかも簡単にできるようにしてあるっぽい。

rustupを使ってRustをインストールして簡単なアプリケーションを動かすところまでやってみる。

# 検証環境
```
vagrant@vagrant:~$ uname -a
Linux vagrant 3.13.0-92-generic #139-Ubuntu SMP Tue Jun 28 20:42:26 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
vagrant@vagrant:~$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.4 LTS"
```

# インストール
[インストールドキュメント](https://www.rust-lang.org/en-US/install.html)に従ってインストールしてみる。

```|bash
$ curl https://sh.rustup.rs -sSf | sh
...
$ source $HOME/.cargo/env
$ which rustc
$ which rustc
/home/vagrant/.cargo/bin/rustc
$ ls ~/.cargo/bin/
cargo      rustc      rustdoc    rust-gdb   rust-lldb  rustup

```
ユーザ領域にRustの関連バイナリをインストールしてくれた。
**簡単！！！**

# アプリケーションを動かしてみる
```
$ cargo new test_app --bin
$ cat src/main.rs
fn main() {
    println!("Hello, world!");
}
$ cargo build
$ cargo run
$ cargo run
    Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/test_app`
Hello, world!
```
**動いた！！！**

# まとめ
rustupを使うとRustのツールチェーンを簡単に入れる事ができた
fabric8を使ってKubernetes環境をローカルに構築する

## はじめに
このエントリーは[Kubernetes Advent Calendar 2016](http://qiita.com/advent-calendar/2016/kubernetes)の2日目の投稿になります。[1日目のエントリー](http://qiita.com/muraken720/items/8416271eb9fe350dfa61)の最後で[fabric8](https://fabric8.io/)のmaven pluginを使ったローカル環境の構築方法を紹介したのですが、その後のバージョンではそのままだと期待通りに動かない部分があるので、そのフォローアップを行います。

## 環境条件
今回説明する環境は macOS Sierra(ver 10.12.2) を前提とします。また、次のソフトウェアをインストールしているものとします。

- java (1.8.0_112)
- go (go1.7.4 darwin/amd64)
- homebrew
- maven (Apache Maven 3.3.9)
- xhyve (via homebrew)
- docker (via homebrew)
- docker-machine (via homebrew)
- docker-machine-driver-xhyve (via homebrew)

## 問題点

[1日目のエントリー](http://qiita.com/muraken720/items/8416271eb9fe350dfa61)では次のコマンドを実行するだけでローカル環境にminikube環境を構築できることを紹介しました。

```
mvn io.fabric8:fabric8-maven-plugin:3.2.7:cluster-start
```

しかし、このfabric8-maven-plugin 3.2.7くらいから、minikube環境の構築はできるものの、構築完了時に自動的にfabric8のdashboard画面が以前は開いたのですが、そのままではタイムアウトエラーがでるようになりました。これは、Kubernetes上にデプロイされているサービスに外部からアクセス可能にするためのexposecontrollerというモジュールがデフォルトではデプロイされなくなったために、Kubernetesの外からそのままではアクセスできないことが原因です。

fabric8のdashboardへのアクセスがタイムアウトしてから、Kubernetesのdashboardにアクセスして、fabric8 dashboardのService定義（yaml）のtype属性をNodePortに変更するという泥臭いやり方もあるのですが、それではあんまりなので、もう少しスマートに回避する方法を紹介します。

## 手順

まずは必要なソフトウエアをまとめてインストールするために次のコマンドを実行します。

```
mvn io.fabric8:fabric8-maven-plugin:3.2.11:install
```

これにより、gofabric8、minikube、kubectlが `~/.fabric8/bin` 以下にインストールされます。

次にminikube環境を構築します。

```
gofabric8 start --console --open-console=false --memory=8192 --vm-driver=xhyve --batch
```

gofabric8コマンドはminikube環境を構築し、fabric8モジュールをデプロイしてくれます。ポイントは `--open-console=false` の部分で、これで構築完了時に自動的にfabric8 dashboardを開かないようにしています。

次のコマンド実行すると、minikube+fabric8環境が構築できているか確認してくれます。

```
gofabric8 validate
```

チェック項目がグリーンでチェック印がつけば正常に構築できています。次にexposecontrollerをデプロイします。

```
kubectl apply -f http://central.maven.org/maven2/io/fabric8/devops/apps/exposecontroller/2.2.298/exposecontroller-2.2.298-kubernetes.yml
```

これでfabric8 dashboard(console)に外部からアクセスできるようになりましたので、次のコマンドを実行するとコンソールを開くことができます。

```
gofabric8 console
```

または

```
minikube service fabric8
```

上記はどちらも同じ意味で、fabric8 dashboard(console)を開きます。

クラスタを停止するには、次のコマンドを実行します。

```
gofabric8 stop
```

## おわりに

というわけで、もともとは1コマンドで構築が完了する予定なのですが、fabric8は絶賛開発中ということもあり、問題が発生するのを回避したい場合には上記の手順によって環境を構築することができます。環境が作れれば、いろいろと試せて面白い環境ですので、ぜひお試しください。
Codeigniterの環境設定メモ

#設定ファイルのロード
1. グローバルな設定ファイル(/application/config/内)
2. 現在の環境の設定ファイル(/application/config/環境名/内)

設定ファイルは上記の順にロードされる。
環境別ディレクトリ配下には、必要なファイルのみを置けばよい。
他はグローバル設定ファイルの内容が適用される。

#環境切り替え
$_SERVER['CI_ENV']の値もしくはpublic/index.phpの定数ENVIRONMENTの値設定で行う。
デフォルトはdevelopment。

ちなみに$_SERVER['CI_ENV']は apacheのSetEnvで設定できる。

```httpd.conf
<Directory "/var/www/html">
SetEnv CI_ENV development
</Directory>
```

##影響：エラーレポート
- development = エラーレポートがブラウザに表示される。
- production = エラーレポートは表示されない。

#影響：設定ファイル
/application/config/<環境名>/配下の設定ファイルもロードされる。

#複数環境の設定

1 . 開発用(application/config/development/)ディレクトリと製品用(application/config/production/)ディレクトリを作成。必要に応じてテスト用(application/config/testing/)ディレクトリも作成。

```bash:ディレクトリ構成
application/
└ config/　(直下はデフォルトの設定ファイル)
   ├ autoload.php
   ├ config.php
   ├ constants.php
   ├ database.php
   ├ ...
   │
   ├ production/  (製品用)★作成
   ├ development/ (開発用)★作成
   │

```
2 . 各ディレクトリ内に,環境によって変えたい設定ファイルをapplication/config内よりコピペして、設定内容を変更。

```bash:ディレクトリ構成
application/
└ config/
   ├ autoload.php
   ├ config.php
   ├ constants.php
   ├ database.php
   ├ ...
   │
   ├ production/  (製品用)
   │  ├ autoload.php ★作成
   │  ├ config.php   ★作成
   │  ├ database.php ★作成
   │  └ routes.php   ★作成
   │
   ├ development/ (開発用)
   │  ├ autoload.php ★作成
   │  ├ config.php   ★作成
   │  ├ database.php ★作成
   │  └ routes.php   ★作成
   │

```
3 . public/index.phpの設定を以下のように設定。

```php:public/index.php
if($_SERVER["SERVER_NAME"]=="localhost"){
    // localhost -> development
    define('ENVIRONMENT', isset($_SERVER['CI_ENV']) ? $_SERVER['CI_ENV'] : 'development');
}else{
    // Others -> production
    define('ENVIRONMENT', isset($_SERVER['CI_ENV']) ? $_SERVER['CI_ENV'] : 'production');
}
```

4 . .gitignoreにapplication/config/development/\*、application/config/production/\*を記述して、管理から外す。
（database.phpのみを外すのでもOk。とりあえず、パスワードをコミットしちゃわないように。)

```bash:.gitignore
/application/config/production/*
/application/config/development/*

#database.phpのみの場合
/application/config/production/database.php
/application/config/development/database.php
```



#参考リンク
- [設定クラス - CodeIgniter](http://codeigniter.jp/user_guide/3/libraries/config.html)
- [複数環境への対応 - CodeIgniter](http://codeigniter.jp/user_guide/3/general/environments.html)
- [codeigniter3 で複数環境への対応を設定する - カバの樹](https://www.kabanoki.net/846)
- [[初心者向け]Codeigniter導入時にやっておいたら便利なtips5つ - rdlabo](https://rdlabo.jp/codeigniter-332.php)
AWS S3の画像等のデータをCloudFront経由で配信する

今までS3に配置した画像や音声データをアプリから直接参照していたが、CloudFrontでやっても値段もそんなに変わらないし、早くなるということで実装してみました。

# CloudFrontとは
Amazon CloudFront はグローバルなコンテンツ配信ネットワーク (CDN) サービスで、お客様のウェブサイト、API、動画コンテンツ、またはその他のウェブ資産の配信を高速化できます。他のアマゾン ウェブ サービス製品と統合されたこのサービスを利用すると、開発者や事業主は、簡単にエンドユーザーに対してコンテンツを高速化できます。最低利用量の条件はありません。
(AWS公式サイトより)

要はGlobalなCacheサービスっていうことですかね？
S3に配置したコンテンツをwebサイトやアプリから呼び出すと、S3に配置してあることが丸わかりだから少しやだなぁとも思っていたので、ちょうど良かったです。(S3で直接配信する時のpermissionの設定等は[AWS S3でのコンテンツ配信](http://qiita.com/THHacker/items/eb377926afc2d1b1101e)で書きました。)
ただ、単純にCloudFront経由にすると ~.cloudfront.net/XXX.png みたいなURLになってしまうので、Route53で独自ドメインをつけてあげる必要があります。

## 手順
1. S3でバケットを作成（この時、permissionの設定等は不要）
2. CloudFrontでDistributionを作成
    3. [CreateDistribution]を押し、[Web]の方の[Get Started]を押す
    4. [Origin Settings]
        5. [Origin Domain Name]にカーソルを合わせると上記で作成したS3のバケットが選択肢に出てくるので選択
        6. [Origin Path]は付けたければ
        7. [Origin ID]は[Origin Domain Name]選択で自動付加
        8. [Restrict Bucket Access]を[yes]にする（S３のアドレスで直接アクセスを許さなくする）
        9. [Origin Access Identity]は[Create a New Identity]を選択
        10. [Comment]はわかりやすいもの（自動でもつく）
        11. [Grant Read Permissions on Bucket]は[yes]にする
        12. [Origin Custom Headers]は付けたければ
    12. [Default Cache Behavior Settings]
        13. 設定不要
    13. [Distribution Settings]
        14. [Alternate Domain Names(CNAMEs)]にはS3にコンテンツアクセス時に付けたいドメインを設定
        15. [SSL Certificate]は独自ドメインであればcustomの証明書を選択
        16. [log]は付けたければ
3. Route53
    4. [Create Record Set]を押す
    5. [Name]は上記4-1で設定したドメイン名を入力
    6. [Type]は[CNAME-Canonical name]を選択
    7. [Value]は上記で作成したCloudFrontの[Domain Name]　(generalから確認可能)


上記で4-1で設定したドメイン+S3バケットのファイルパスで表示可能になる

ちなみにCORSでエラーが出た場合は、
[Forward Headers]を[Whitelist]に変更し、[Whitelist Headers]でOriginヘッダを[Add>>]ボタンで追加すればOK

何かご指摘、ご意見あればお願い致します。
pandasのTimeGrouperで時系列の集計を便利に

pandasのGroupByの拡張のようなTimeGrouperについて情報がなかったので備忘録として。
もっとデファクトスタンダードな方法があれば教えてください！

## 用例:特定の期間内での集計をしたい場合に有用
例

* 毎月の値を持つデータから6か月ごとに集計する
* 毎日の値をもつデータから1か月毎の集計をする
* タイムスタンプで取引記録を持つようなデータから日毎の集計をする


## 関連するstackoverflow
* [How to groupby time series by 10 minutes using pandas?](http://stackoverflow.com/questions/32147224/how-to-groupby-time-series-by-10-minutes-using-pandas) [1]

* [timegrouper-pandas](http://stackoverflow.com/questions/14569223/timegrouper-pandas)

## 用例1:毎月の値を持つデータから6か月ごとに集計する ([1]より)

```python
ts = pd.date_range('7/1/2008', periods=30, freq='MS') 
df = pd.DataFrame(pd.Series(range(len(ts)), index=ts))
df[0] += 1
df # 2008/7/1から始まる月ごとのデータフレームができる
```
![Screen Shot 2017-01-04 at 23.18.06.png](https://qiita-image-store.s3.amazonaws.com/0/99549/4d0c0ca2-a805-e1b9-1a37-a5dac3bf1a83.png)

```python
df2 = pd.DataFrame([0], index = [df.index.shift(-1, freq='MS')[0]])
df2
```
![Screen Shot 2017-01-04 at 23.21.24.png](https://qiita-image-store.s3.amazonaws.com/0/99549/09fa24f3-e198-cc0d-5ba3-c7b978e415f3.png)

df2には6か月ごとの集計ができる
```python
df2.append(df).groupby(pd.TimeGrouper(freq='6M')).aggregate(np.sum)[1:] 
```

![Screen Shot 2017-01-04 at 23.21.32.png](https://qiita-image-store.s3.amazonaws.com/0/99549/2473b294-9d95-ae65-10bd-e1fcdf0e882b.png)


## 用例2:タイムスタンプで取引記録を持つようなデータから日毎の集計をする

```python
rng = pd.date_range(start = '2014-01-01',periods = 100, freq='H')
df_original = pd.DataFrame({'Volume' : np.random.randint(100,2000,len(rng))}, index=rng)
df_original
```

```
Out[148]: 
	Volume
2014-01-01 00:00:00	1484
2014-01-01 01:00:00	1635
2014-01-01 02:00:00	984
2014-01-01 03:00:00	1239
2014-01-01 04:00:00	785
2014-01-01 05:00:00	871
2014-01-01 06:00:00	614
2014-01-01 07:00:00	119
2014-01-01 08:00:00	933
2014-01-01 09:00:00	624
...	...
2014-01-04 19:00:00	1832
2014-01-04 20:00:00	1996
2014-01-04 21:00:00	1040
2014-01-04 22:00:00	1867
2014-01-04 23:00:00	1098
2014-01-05 00:00:00	1397
2014-01-05 01:00:00	1996
2014-01-05 02:00:00	610
2014-01-05 03:00:00	1242
100 rows × 1 columns
```

```python
df_tmp = pd.DataFrame({'Volume':[0]}, index = [df_original.index.shift(-1, freq='D')[0]])
df_daily=df_tmp.append(df_original).groupby(pd.TimeGrouper(freq='D')).aggregate(np.sum)[1:] 
df_daily
```

![Screen Shot 2017-01-05 at 00.07.58.png](https://qiita-image-store.s3.amazonaws.com/0/99549/befa7a03-e4a3-961c-7ec6-b02f20e9c643.png)


### P.S
Qiitaでjupyterの埋め込みしたい
blog記事にGitHubのAvatar(Profile picture)を表示する。

最近、いくつかのサイトをGitHub Pages+Jekyllに移行したのですが、blog記事の投稿者としてGitHubのAvatar(Profile picture)を表示したいなと思い、やり方を見つけましたので、メモとして残しておきます。

blog記事に、"author"としてGitHubのアカウント名が記載されていることが前提の内容になっていますが、要はGitHubのアカウント名が取得できればいいので、そのあたりは適宜読み替えて自分が使いやすい形にカスタマイズしていただければと思います。
私はJekyllサイトでつかっていますが、Jekyllサイト以外でも利用できます。

## GitHubのAvatar取得方法
GitHubのAvatarは、以下のURLで取得可能です。
```
https://avatars.githubusercontent.com/{username}
```
この{username}の部分を自分のユーザー名に変えればOK。私の場合は、"kwaka1208"なので、以下のURLになります。
```
https://avatars.githubusercontent.com/kwaka1208
```
これを表示させるとこのようになります。
![GitHubのAvatar](https://avatars.githubusercontent.com/kwaka1208)

## Avatarの表示
Avatar画像が取得できれば後は、簡単です。記事のAuthor情報は、"{{ page.author }}で取得できますので、これと前述のURLを組み合わせるだけ。
```
<img src="https://avatars.githubusercontent.com/{{ page.author }}">
```
これをJekyllのlayoutファイルに記述すればAvatarが表示されます。

## Avatar画像を丸くする。
ついでに、このAvatar画像を丸くする方法も書いておきます。
CSSで画像の大きさを指定し、一辺の長さ（正方形なので縦横どちらでもOK）にの半分を半径とした"border-radius"を指定すれば画像が丸く切り取られます。

例えば、Avatarの大きさを縦横それぞれ128pxにした場合、border-radiusの値は64pxを指定します。
```
<img src="https://avatars.githubusercontent.com/{{ page.author }}" style="border-radius: 64px; width: 128px;">
```
ここで実際に表示させてみようと思ったのですが、Qiita上ではstyle指定が効かないようですので、実際にこの方法で表示させているこちらのサイトをご覧ください。

http://coderdojo-nara-ikoma.github.io/blog/computer-science-for-all/
---
2018年5月17日時点でこの方法は有効でした。
macOS SierraにhomebrewでPHP7を導入したメモ

anyenv + phpenvではApache環境の構築がどうにも上手くいかず、homebrewでの導入に切換。

```
brew tap homebrew/dupes
brew tap homebrew/versions
brew tap homebrew/hoembrew-php
```
brew tap homebrew/hoembrew-phpがcloneでエラーになる場合は、手動で
```
git clone https://github.com/Homebrew/homebrew-php.git /usr/local/Homebrew/Library/Taps/homebrew/homebrew-hoembrew-php
```
として対応

```
brew install php70 --with-apache
```
最後の--with-apacheがミソ。これをしないとlibphp*.soが作られない。
上記の例だと、
```
/usr/local/opt/php70/libexec/apache2/libphp7.so
```
に生成されるので、Server.app（macOS Server）環境の場合、
```
/Library/Server/Web/Config/httpd_server_app.conf
```
素のmacOS Sierraの場合、
```
/private/etc/apache2/httpd.conf
```
を編集し、
```
LoadModule php5_module libexec/apache2/libphp5.so
```
から
```
LoadModule php7_module /usr/local/opt/php70/libexec/apache2/libphp7.so
```
に。もともとPHPを有効にしてない場合は＃でコメントアウトされてるので消すのも忘れずに。

次に、Server.app（macOS Server）環境の場合は同じファイル、素のmacOS Sierraでは、
```
/etc/apache2/other/php5.conf
```
の、
```
<IfModule php5_module> 
```
を
```
<IfModule php7_module> 
```
に変更。

その後、Apacheを再起動します。ちなみに、
```
apachectl restart
```
とするだけではエラーは出ないけど再起動はされずしばらく悩みました。
```
sudo /usr/sbin/apachectl restart
```
としないとダメです。

phpenvより切換えの手間はやや多いですが、一応いつでも5.xにも戻れそうだし、これでいいじゃん、と。
RxSwiftでUITextFiledのtextのオブザーバーがSwift3から変わっていた


Eメールの形式のバリデーションをSwift2では以下のように書いていた。

```swift
let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,20}"
let emailValid = emailTextField.rx_text
    .map() { text in
        
        return NSPredicate(format:"SELF MATCHES %@", emailRegEx).evaluateWithObject(text)
        
}.shareReplay(1)

```

`rx_text`プロパティがオブザーバーでそれでTextFieldのテキストをサブスクリプトしていた。


Swit3からこんな風に変更する必要がある。

```swift
let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,20}"
let emailValid = emailTextField.rx.text.orEmpty
.throttle(0.3, scheduler: MainScheduler.instance)
    .map({ text in
         return NSPredicate(format:"SELF MATCHES %@", emailRegEx).evaluate(with: text)
    }).shareReplay(1)

```

`rx`プロパティが追加された。`rx.text`のように使う。
`orEmpty`が追加された。空文字やnilはオブザーブしないらしい。
`throttle `が追加された。時間を指定するとそれ以下の入力をオブザーブしないでくれるらしい。

いろいろ変わったなー
Webpack2でpostcssを使う

# 課題
webpack2でビルドしてるプロジェクトでautoprefixerを使いたくなった.　またcssは別抽出してまとめたい.
postcssとExtractTextWebpackPluginで対応しようとした.

webpack2(2.1.0-beta.26)でこれをしようとしたら色々とはまったのでそのときのまとめ.

**以下手順**

# 0.必要パッケージインストール

```bash
npm install --save-dev postcss postcss-loader autoprefixer 
```
postcssとwebpackからつかうloader加えてautoprefixerを入れる.
**extract-text-webpack-pluginは@betaを付与して新しいのを入れる.**

```bash
npm install --save-dev extract-text-webpack-plugin@beta
```


# 1.Loader設定

postcssを通すようにcssに関するruleを設定する.

[参考サイト](https://github.com/postcss/postcss-loader/issues/92)

```js:webpack.base.conf.js
const ExtractTextPlugin = require('extract-text-webpack-plugin')

// ...

rules: [
      {
        test: /\.(css|scss)$/,
        loader: ExtractTextPlugin.extract({
          fallbackLoader: 'style-loader',
          loader:[
            'css-loader',
            'sass-loader',
            'postcss-loader'
          ]
        })
      },
      // other rules
      // ...
]
```

# 2.postcssの設定

postcss.config.jsを作り配置して動かそうとするとpostcss.config.jsを読めないのかエラーが出た. なかなか解決できなかったので別の方法を模索した
結果,webpack.LoaderOptionsPluginを利用しpostcssの設定を渡せるらしい.　

そこでpostcssの設定をこれで渡す.

```js:webpack.base.conf.js
 plugins: [
    new webpack.LoaderOptionsPlugin({
      options: {
        postcss: [
          require('autoprefixer')({
            browsers: ['last 2 versions']
          })
        ]
      }
    }),
    // other plugins
    // ...
  ]
```

# 3.ExtractTextPluginの設定
出力時の設定をpluginsの中に追加

```js:webpack.base.conf.js
plugins: [
  new ExtractTextPlugin({ filename: '[name].[hash].css', disable: false, allChunks: true }),
  // other plugins
  // ...
]
```


# まとめ
上記設定をwebpackに書けばwebpack2でpostcssが使えた.
autoprefixerしか今回は入れていないが必要になったら色々入れていきたい.
[JavaScript] 外部ライブラリなし拙速日付書式（年4桁、月2桁、日2桁）

外部ライブラリなしで、とにかく拙速に日付を書式化しようというだけです。

年4桁、月と日は0パディングして２桁にします。

```js:
var formatDate = function(d) {
	return ''
	    + d.getFullYear()
	    + ('0' + (d.getMonth() + 1)).substr(-2, 2)
	    + ('0' + d.getDate()).substr(-2, 2);
};
```

こういう簡単すぎるネタは如何なものかと考えるプライドを振り切っての投稿です。
（言い訳がましい）
DjangoのMultipleChoiceFieldでchoicesが更新されない

Django:1.10

以下の記事を書いた後、「追記　2016/11/26」に書いた問題を見つけました。

DjangoでIN演算子を使ったクエリを生成する方法
http://qiita.com/nakkun/items/86a94e65fe6785325f54

MultipleChoiceFieldで著者を選択する入力フィールドを作成する際に、データベースから選択できる著者一覧を取得してchoicesに渡したのですが、著者を追加してもサーバ再起動しないと画面に反映されません。

Viewで代入することはできますが、FormのことはFormにやらせたい。

まだPythonのclassは勉強していなかったので、アプリケーションスコープになるからなのかなとなんとなく思っていました。

年末年始にPython本を読み進めてみると、なるほど、classオブジェクト生成時に値が代入されるからですね。
つまり、Javaでいうstaticフィールドになるわけですね。

なので、インスタンス生成時にchoicesを代入するように修正しました。

```python:forms.py
class SearchForm(forms.Form):

    author = forms.MultipleChoiceField(label='著者', widget=forms.CheckboxSelectMultiple, required=False)

    def __init__(self, param):
        forms.Form.__init__(self, param)
        self.fields['author'].choices = [(author.id, author.name) for author in Author.objects.all()]
```

これで、ブラウザリロードだけで著者追加が反映されるようになりました。

# 追記　2017/01/09
コメントでご指摘をいただき、もっと簡単にできることがわかりました。

```python:forms.py
class SearchForm(forms.Form):

    author = forms.ModelMultipleChoiceField(
        label='著者', widget=forms.CheckboxSelectMultiple, required=False,
        queryset=Author.objects.all(), to_field_name='name')
```

これだけでできます！

# 追記　2017/01/11
さらにコメントいただきました。
ModelMultipleChoiceFieldを使わなくても、choicesにcallableなオブジェクトを渡すことで更新されるようになりました。

```python:forms.py
class SearchForm(forms.Form):

    author = forms.MultipleChoiceField(
        label='著者', widget=forms.CheckboxSelectMultiple,
        choices=lambda: [(author.id, author.name) for author in Author.objects.all()], required=False)
```

これでもできます！
macOS Sierra で ssh-agent の鍵をすぐ忘れられちゃうのめんどくさいんじゃこらーの対処法


Sierra 以前では、ssh-agent を使う時には以下のようにすればオッケーでした。

```
$ ssh-add -K ~/.ssh/id_rsa
```

Sierra では、 `~/.ssh/config` に以下のように追加してください。

```
Host *
   AddKeysToAgent yes
   UseKeychain yes
   IdentityFile ~/.ssh/id_rsa
```

以上！

http://apple.stackexchange.com/questions/254468/macos-sierra-doesn-t-seem-to-remember-ssh-keys-between-reboots/264974#264974
[Unity]コルーチンでNowLoading...のアニメーションをつける

ロード画面でNowLoadingと表示されるゲームが多いが、何かしらのアニメーションがないとフリーズしていると勘違いされることもあるため、アニメーションを付けることにした。
アニメーションといっても、ただ単にNowLoading...の...の数が変化していくというものである。

#実装

uGUIのテキストに表示するという前提で以下のようにコードを作成した。
ここでの`nowLoading`は、あらかじめ`Text nowLoading;`と宣言しておく必要がある。

```
void Start(){
        StartCoroutine("displayNowLoading"); // コルーチン呼び出し
}

IEnumerator displayNowLoading(){ // ここでNowLoading表示とアニメーション
		while(true){
			nowLoading.text = "NowLoading";
			yield return new WaitForSeconds(0.5f);
			nowLoading.text = "NowLoading.";
			yield return new WaitForSeconds(0.5f);
			nowLoading.text = "NowLoading..";
			yield return new WaitForSeconds(0.5f);
			nowLoading.text = "NowLoading...";
			yield return new WaitForSeconds(0.5f);
		}
}
```

displayNowLoading()では、0.5秒ごとに...の数が変化するという仕組みになっている。
0.5秒のdelayは、`yield return new WaitForSeconds(0.5f)`で実装できる。
...の表示速度を変えるには、0.5fを別の値に変更すればよい。
また、whileループでそれらを囲うことで、
NowLoading
NowLoading.
NowLoading..
NowLoading...
NowLoading(戻る)
NowLoading.
NowLoading..
NowLoading...
NowLoading
という感じにアニメーションを作成できる。

割とゴリ押しコードだが、簡単に実装できて良いと思う。
node.jsでlocalhostに簡単なチャットシステムを作成する


Macでnode.jsの勉強のためにチャットシステムを立ち上げて見ました。

## node.jsのダウンロードとインストール
まず、node.jsをダウンロードし、インストールします。
[こちらのサイト](https://nodejs.org/ja/)からダウンロードしてください。
そのまま、インストールします。
ターミナルを起動して、node.jsのバーキョンを確認します。

```ターミナル
$ node -v
```
※この表記で使用している「$」はターミナルを開くとすぐに表示される「$」になります。なので、「$」自体は記述しないで大丈夫です。

「v0.11.11」というようなバージョンが表示されればOKです。

## npm で簡単インストール
node.jsをインストールすると、npmというコマンドが手に入ります。
これがめちゃめちゃ使えます。というか使っていきます。
node.jsはよくわからないのですが、簡単にいうとサーバーサイドがJSのスクリプトで動かせるということらしいです。

チャットシステムを構築するために、このnpmを使ってガンガンインストールしていきましょう。

### socket.ioのインストール
socket.ioはサーバーサイドとクライアントを繋げるものらしいです。もちろんjsです。
再度ターミナルで次のコマンドを叩きます。

```ターミナル
 $ npm install socket.io
```
たったこれだけで「socket.io」がインストールされます。
enterを押すと緑文字で「http」と文頭にある行がいくつも出てきます。
エラーの場合は「ERRE」と赤文字で表示されます。
2017年1月の段階では、socket.ioは問題なくインストールできました。

### expressのインストール
expressはWebアプリを作成するためのフレームワークだそうです。
こちら、検索すると色々なインストール方法があるようですが、一般的にある「-g」を使用したものだと、うまくインストールできませんでした。
参考のサイトなどもリンクが切れているようなので、発行元が変わってしまったようです。
ただ、socketの時と同じように、単純にインストールしたらうまくできたような気がします。

```ターミナル
 $ npm install express
```

## チャットシステムの構築
ここまでできたら、実際にjsとHTMLを記述していきます。
こちらのページを参考にさせてもらいました。
[node.jsとsocket.ioで簡易チャットを作成する](http://blog.webcreativepark.net/2015/12/09-210844.html)

### app.jsの実装
ファイル名は適当で大丈夫です。

```javascript:app.js
var path = require('path');
var express = require('express');
var app = express();

var http = require('http').Server(app);
var io = require('socket.io')(http);

app.use(express.static(path.join(__dirname, 'htdocs')));

io.on('connection', function(socket){
  socket.on('send_message', function(text){
	io.sockets.emit('receive_message',text);
  });
});

http.listen(3000);
console.log('Server started: http://localhost:3000/');
```
このスクリプトのポイントは6行目に記述した「htdocs」の部分です。
こちらがディレクトリをしてしています。この場合は、「htdocs」というフォルダ内のindex.htmlを読みにいきます。このファイル「app.js」と同じ階層のファイルを読みにいきたい場合は「./」を設定します。
さらに、最後から２行目のもの「http.listen(3000);」がポートを設定しています。

こちらで、ターミナルに「Server started: http://localhost:3000/」が表示されたら成功です。
ブラウザで「http://localhost:3000/」にアクセスするとindex.htmlが表示されます。

### index.htmlの設定
indexの設定は先ほどご紹介したサイトのHTMLをそのまま使用できます。
[node.jsとsocket.ioで簡易チャットを作成する](http://blog.webcreativepark.net/2015/12/09-210844.html)
AnsibleをUbuntuで初めて使ってつまづいた点をまとめた

# AnsibleをUbuntuで初めて使ってつまづいた点をまとめた

UbuntuでAnsibleを使ってプロビジョニングをやってみたくなったので、初めて触った人のつまづいた点をまとめておきます。

## 環境
OS: Ubuntu 14.04
Vagrant box: ubuntu/trusty64

## つまづいた点
1. SSHで接続できない
2. root権限なくてパッケージインストールできない


## SSHで接続できない
VagrantでAnsibleのテストをしているので、普通にRLoginとかでSSHで接続できる(秘密鍵無しでと思い込んで)のに、`Permission denied`が出てきてました。  
これは自分は何度も経験しているので、何度か試行錯誤しているうちに、サーバ側(AnsibleのPlaybookによってプロビジョニングされるマシン)に公開鍵を登録しておかないと行けないんだと気が付きました。  
早速`ssh-keygen`で仮の秘密鍵と公開鍵を作成。サーバ側に登録。  
`ansible -m ping all`
を打って秘密鍵のパスワード打って無事pingの結果`pong`が返ってくる。

よって、AnsibleではSSH接続をしてプロビジョニングを行うため、サーバ側に公開鍵を事前に登録しておく必要があることがわかりました。

## root権限なくてパッケージインストールできない
SSH接続できて、次の壁にぶつかります。「パッケージがインストールできない」

ネットをいろいろ波乗りしていると、みなAnsibleとかChefとかでもCentOSでプロビジョニングを説明するので、Ubuntuで説明しているページが少ないです。  
これって、あまりサーバとしてUbuntuが人気じゃないんでしょうか? 個人的には、Ubuntu大好きなんですけどね。  

CentOS用のPlaybookの中に`remote_user: root`という記述があります。  
ですが、Ubuntuにはrootというユーザは実在しないはずです。  
だから上のコードで実行すると「お前はrootじゃね」とdpkgとかのコマンドを実行しようとするときに怒られます。

困った、CentOSにできて、Ubuntuにできないわけがない。

`sudo`コマンドは権限昇格(Privilege Escalation)をするためのコマンドであるという定義をすっ飛ばしていたので、いい勉強になりました。  
よって、Ubuntuに実在するユーザで権限昇格をしてパッケージをインストールすればいいので、`become: true`と`remote_user: root`の代わりに入力します。

これで、Playbookを実行するコマンドを走らせて。。。完了!

## 実際に試してみたPlaybookです
```yaml:setup.yml
---

- hosts: host1
  become: true
  tasks:
    - name: install nginx
      apt:
        name: nginx
        state: present
      notify: restart nginx

  handlers:
    - name: restart nginx
      service: name=nginx state=restarted
```

## あと気になる点
YAMLでPlaybookを記述するんですが、どうやらまだ理解していない模様なので、しっかり復習したいと思います!


## 参考文献
- [構成管理ツールAnsibleを使ってみよう - ConoHa](https://www.conoha.jp/guide/ansible.php)
- [How to Install and Configure Ansible on Ubuntu 16.04 - DigitalOcean](https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-ansible-on-ubuntu-16-04)
- [初めてのAnsible(2章:Playbook:始めてみよう) - Qiita](http://qiita.com/c0tt0n-candy/items/36b4eb2717447071ad21)
- [Become - Ansible Documentation](http://docs.ansible.com/ansible/become.html)
【実装編】会社玄関ドアの開閉を検知してEC2のインスタンスの起動停止を行う

# 部品は手に入れた
手っ取り早く手に入れたかったので、Amazonで手に入るものはAmazonで仕入れました。
おそらく相場よりも少し高いんだと思うけど~~会社の金なので関係ないです~~。磁石は近所の100均で。
# センサ動作確認
## テスト回路を組む
とりあえずは、ホールセンサのOutputをESPr Developerのアナログ入力に入れて、コンソールログに計測値を出力するためのスケッチを作成しました。
また、回路は磁石が近づいた時にLEDを点滅させるために、13PINにLEDをつないでいます。

```c:sample
extern "C" {
  #include "user_interface.h"
}

void setup() {
  Serial.begin(115200);
  delay(10);

  pinMode(13,OUTPUT);
  pinMode(14,OUTPUT);

  digitalWrite(13,HIGH);
  delay(500);
  digitalWrite(13,LOW);

}

void loop() {
 digitalWrite(14,HIGH);
 delay(10);
 int val = system_adc_read();
 digitalWrite(14,LOW);
 
 Serial.println(String(val));

 if(val == 1024){
  digitalWrite(13,HIGH);
  delay(100);
  digitalWrite(13,LOW);
  delay(100);
 }
    
}

```

## 特性
Amazonで購入したホールセンサでは動作せず・・・
調べてみるとホールセンサには特性があり、特性によって動作が異なるようです。とりあえず以下のホールセンサを千石電商さんで追加で購入しました。それぞれのスペックシートを見てみると概要に以下のように書かれていました。どちらも無接点スイッチに向いてると書いてます。回路的にはDN6851の方にプルアップ抵抗が入ってるくらいの違いです。

| 型番 | 概要 |
|:-----|:-----|
| DN6851 | DN6851は、ホール効果を利用した半導体集積回路です。特に低電源電圧で交番磁界により動作するように設計されています。各種センサ、無接点スイッチなどに好適です。 |
| DN6952 | DN6852は、ホール効果を利用した半導体集積回路です。特に低電源電圧で一方向磁界により動作するように設計されています。各種センサ、無接点スイッチなどに好適です。 |

## 計測
テスト回路のホールセンサをDN6851とDN6852、それぞれ差し替えながらコンソールの値を計測します。結果的にDN6851を使うことで目的の動作結果を得ることができました。
![IMG_6335.gif](https://qiita-image-store.s3.amazonaws.com/0/54521/c1089a53-f352-0481-cd5a-e73ddcb20c26.gif)

この時のシリアルモニタの出力値。磁石が寄るとHIGH(1024)に近くなります。
![IMG_6336.gif](https://qiita-image-store.s3.amazonaws.com/0/54521/2fce86a5-bbbc-ccdb-ccdc-58bd66490a40.gif)

ちなみに同様の回路でDN6852だと動作せず、DN6851の様にVccとVoutの間にプルアップ抵抗(20k)を挟むと、何もしていない時にHIGHで、磁石を近づけるとLOWになる動作をしました。

理論的なところは理解できていませんが、結果オーライとします。

# データ送信
## WiFi接続
先程のスケッチにWiFi接続のコードを足して、センサでの取得値を記録します。
記録には[Ambidata.io](https://ambidata.io)というサービスを利用しました。
ドアが開いた時に「1」閉じた時に「0」を送信しています。
![スクリーンショット-2017-01-.png](https://qiita-image-store.s3.amazonaws.com/0/54521/3a572269-0d43-ddef-611a-886b737a9655.png)

ほぼ毎日同じ時間に出社して帰宅しているので、ノコギリの刃の様な形になっているのが分かるかと思います。間が飛んでるところはメンテしててデータが取れてません。

コードを載せたいのですが、途中のコードが残っていなくて現在改修中のコードしか手元にありません・・・【実稼働編】では載せられるかと思うのでそれまでお待ち下さい。

次回【テスト稼働編】では、DEEP SLEEPモードを使った省エネ化に触れたいと思います。
Nginx+PHP70(fpm)+MySQL56+Wordpressするitamae

# この文章はなに

itamaeでWordpressを1台のサーバに複数インストールしたかった人生だった。

# 結論

作って公開したので使えると思う。
https://github.com/foursue/xxv-server
ライセンスはMIT

# 使い方

Rubyのバージョンをよく変えるのでREADMEでの実行環境はdockerを前提にしているが、ローカルにrubyがいるなら普通に実行できるはず。

```
docker run --rm -v $HOME/projects/xxv-server:/usr/src/app -w /usr/src/app ruby:2 sh -c 'bundle install --path vendor/bundle && bundle exec itamae ssh entry.rb --host {{アドレス}} -u root -i secure/{{PEMファイル}} -y nodes/{{nodeファイル}} -n'
```

普通にbundle叩くなら、下記のような感じ。
```
bundle install --path vendor/bundle && bundle exec itamae ssh entry.rb --host {{アドレス}} -u root -i secure/{{PEMファイル}} -y nodes/{{nodeファイル}} -n
```

# 解説

## Nginx

```
cookbooks/nginx/default.rb
```
インストールしてるだけです。

## php70

```
cookbooks/php7-fpm/default.rb
```
インストールしつつ、`/etc/php-fpm.d/www.conf`のuser,groupをapacheからnginxに変更してます。

## mysql56

```
cookbooks/mysql/default.rb
```
インストールしてるだけです。

## Wordpress

```
cookbooks/wordpress/default.rb
```
ドメイン1つごとにWordpressのダウンロード・解凍・設置、DBの作成と設定、wp-config.phpの作成をしてます。
下記を参考にしました。
https://github.com/masawada/itamae-wordpress

## nodeファイル

下記サンプルのようなnodeファイルを用意してください。
`site1.example.com,site2.example.com`を設定してます。サンプルでは`/usr/share/nginx`を利用してますが、他のディレクトリを利用する場合は`cookbooks/wordpress/default.rb`の該当箇所を見てみてください。

```nodes/sample.yml
roles:
  - wordpress
multi_wordpress:
  - server_name: site1.example.com
    root: /usr/share/nginx/site1
    db_name: wordpress_site1_db
    db_user: wordpress_site1_user
    db_password: password1
  - server_name: site2.example.com
    root: /usr/share/nginx/site2
    db_name: wordpress_site2_db
    db_user: wordpress_site2_user
    db_password: password2
```

## roles

```
roles/wordpress.rb
```
これはcookbooksを順番に読み込んでいるだけです。

# 何か希望があれば

とりあえず作ってみたものなので、ツッコミがあればお手数ですが、どしどしお願いします。
Alamofire4でExtra argument 'method' in call

Swift3移行に伴い、Alamofireのバージョンもあげた際に表題のようなエラーが発生しました。

StackOverflowにあったものですが、今後Swift3でプロジェクトを作る際に忘れないようメモします。
やりたいことはJSONを返すAPIにURL`http://example.com/?param1=1&param2=2`でリクエストすることです。

```
Alamofire.request(self.baseUrl, method: .get, parameters: parameters, encoding: String.Encoding.utf8, headers: self.headers)
// ↓
Alamofire.request(self.baseUrl, method: .get, parameters: parameters, encoding: JSONEncoding.default, headers: self.headers)
```

http://stackoverflow.com/questions/39571812/extra-argument-method-in-call

encodingをJSONEncoding.defaultにすればコンパイルエラーは確かに解消されましたが、なんかうまくリクエストされていない気がする...。
と思って`print(response.request.URL)`すると、そこにはbaseUrlの内容のみが記載されていました。

## 解決
そもそもrequestメソッドにおけるencodingについて理解していませんでした。
URLパラメータのencodingの指定のようです。

```
Alamofire.request(self.baseUrl, parameters: parameters)
```

GETリクエストの場合はencodingとmethodはデフォルトで指定されているので、最終的にこれだけでOKみたいです。
textlintで文書チェックしながらMarkdownを書く


AtomでMarkdownのテキストを書くときにtextlintでチェックしながらするといい感じだった。

# 環境構築
## textlintのインストール

プロジェクトファイル直下に移動し、npmからtextlintをインストールする。

```bash:textlintのインストール
$ npm install --save-dev textlint
```

今回は[JTF日本語標準スタイルガイド（翻訳用）](https://www.jtf.jp/jp/style_guide/styleguide_top.html)に適しているかチェックする。
JTF日本語標準スタイルガイドのプラグインをインストールする。

```bash:JTF日本語標準スタイルガイドプラグインをインストール
$ npm install --save-dev textlint-rule-preset-jtf-style
```

設定ファイルの.textlintrcを以下のように記述し、textlintをインストールしたディレクトリの直下におく。

```json:.textlintrc
{
    "rules": {
        "preset-jtf-style": true
    }
}
```

これでtextlintの設定はOK。

## Atomの環境構築

Atomのパッケージ[Linter](https://atom.io/packages/linter)と[linter-textlint](https://atom.io/packages/linter-textlint)をインストール。
Swift5でDocumentディレクトリのファイルにアクセスする


Documentディレクトリ内のファイルへアクセスする必要があったので、メモします。

## Documentディレクトリのパスを取得
Documentディレクトリを検索します。
iPhone内のDocumentディレクトリを探して、そのパスを取得します。

```swift
let documentPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].absoluteString
```

## ファイル一覧を取得
`FileManager.default.contentsOfDirectory`にてディレクトリ内のファイルを全て取得できます。
ただし、取得できるのは **ファイル名**のみなので注意が必要です。

```swift
guard let fileNames = try? FileManager.default.contentsOfDirectory(atPath: documentPath) else {
    return nil
}
```

## ファイルのデータを取得
ファイルの中身が欲しいので、取得したファイル名とDocumentディレクトリのパスをつなげてファイルを取得します。

```swift
return fileNames.compactMap { fileName in
    guard let content = try? String(contentsOfFile: documentPath + "/" + fileName, encoding: .utf8) else {
        return nil
    }
    return content
}
```

## まとめ
* DocumentDirectoryのパスを取得
* ファイル名の一覧を取得
* 結合してファイルの中身を取得

```swift

let documentPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].absoluteString
guard let fileNames = try? FileManager.default.contentsOfDirectory(atPath: documentPath) else {
    return []
}
        
return fileNames.compactMap { fileName in
    guard let content = try? String(contentsOfFile: documentPath + "/" + fileName, encoding: .utf8) else {
        return nil
    }
    return content
}
```
Safari submit の後処理がうまくいかない件

今現在も原因がわかりません。
もし何かわかる方がいらっしゃれば、教えてください。

# やりたかったこと
テキストボックスに入力後、submitするとその入力したワードで検索し、検索結果を返す画面を表示する。検索する処理が重いため、submitしたら「Now Loading...」のテキストを画面の上下中央に表示したい。

# 再現性
Mac Safari, iPhone Safari のどちらでも再現。
一方、Google chromeやFirefox、IE11では再現せず。

# なにが起きているか
もともとはsubmit後、bodyにdomをappendし、そのdomをオーバーレイ風にふわっと表示させたかった。appendがダメなのか？単にbodyのstyleを変更するだけなら、、で試してみたがダメだった。それが下記。

```html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title>Document</title>
  <style>
  form {
    margin-bottom: 60px;
  }
  p {
    margin: 10px 0;
  }
  </style>
</head>
<body>

  <h2>Javascript</h2>
  <form id="form1" method="" action="">
    <label>form1：<input type="text"></label>
    <p>Enterでsubmitすると、safariは背景色がピンクに変わってくれない。</p>
  </form>
  <form id="form2" method="" action="">
    <label>form2：<input type="text"></label>
    <p>ちょっと処理をずらす対応を入れた。</p>
  </form>
  <hr />

  <h2>jQuery</h2>
  <form id="form3" method="" action="">
    <label>form3：<input type="text"></label>
    <p>Enterでsubmitすると、safariは背景色が黄色に変わってくれない。</p>
  </form>
  <form id="form4" method="" action="">
    <label>form4：<input type="text"></label>
    <p>ちょっと処理をずらす対応を入れた。</p>
  </form>

<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
(function(){
  var elem1 = document.getElementById('form1');
  elem1.addEventListener('submit', function() {
    document.body.style.backgroundColor = 'pink';
    console.log('form1 submit');
  });

  var elem2 = document.getElementById('form2');
  elem2.addEventListener('submit', function(e) {
    //submitをキャンセルにして
    e.preventDefault();
    document.body.style.backgroundColor = 'pink';
    //ちょっとずらしてsubmit
    setTimeout(function(){
      elem2.submit();
    }, 300);
    console.log('form2 submit');
  });
}());

$(function(){
  $('#form3').submit(function(){
    $('body').css('background-color', 'yellow');
    console.log('form3 submit');
  });

  $('#form4').submit(function(e){
    e.preventDefault();
    $('body').css('background-color', 'yellow');
    setTimeout(function(){
      $('#form4').off('submit');
      $('#form4').submit();
    }, 300);
    console.log('form4 submit');
  });
});
</script>
</body>
</html>
```

demo（Safariで開いてみてください。）
http://snjssk.com/temp/qiita_formtest/


# 回避策
回避策と言って良いのか微妙。
無理やり感があるため、ブラウザー判定を入れて、Safariだけはちょっと処理をずらすみたいなことにしておけばいいのかなぁー。。

いろいろ調べてみると、submitと同時に何かさせるとダメみたい？
ちょっと処理をずらすと良いみたい？
http://stackoverflow.com/questions/9934803/show-div-upon-form-submit-works-in-chrome-ff-ie-but-not-safari

http://qiita.com/tomtoma/items/920f6e74358593612b08
pythonのrequestsを使用してredmineのAPIでチケットを登録する

# 概要

pythonのrequestsモジュールを使って、redmineのAPIを使用して
チケット登録をする。

# どうしてこの記事を書いたのか

[python-redmine](http://python-redmine.readthedocs.io/)を使用した例は簡単に見つかるものの、
requestsを使用したものはあんまりなくて、curlでやる要領でやってたら
つまづいたので、他の誰かがつまづかないようになればと思って書いた。

## どうして[python-redmine](http://python-redmine.readthedocs.io/)ではダメだったのか。

チケット登録後にそのチケットを親チケットにして次々と子チケットを　　
登録するようにしたかったのだが、上のライブラリだとチケット登録後の　　
レスポンスはブール値で帰ってくるため、　　
登録したチケットIDを取得することが~~できなかったため。~~
~~（できるよ！って方は教えてください！）~~
コメントで方法を教えてもらいました。
また、[公式](https://python-redmine.com/) を見ると書いてます。
ドキュメント読もう(自戒)

# 前提

- APIキーは準備済み  
何はともあれAPIを利用してチケットを登録するときは必要なので、  
用意しましょう。
- requestsはインストール済み  
importの仕方もわかる。使い方もまぁ大体はわかる。

# チケット登録の方法

## headerの準備
以下の感じでmyheadersという変数にheaderの情報を格納します。

```
myheaders = {
    'Content-Type': 'application/json',
    'X-Redmine-API-Key': 'APIキー'
}

入力例
myheaders = {
    'Content-Type': 'application/json',
    'X-Redmine-API-Key': 'asdfghjklzxcvbnm'
}
```

## チケットの値を準備

```
payload = {
    "issue": {
        "project_id": プロジェクトのID,
        "subject": "チケットの件名",
        "status_id": ステータスのID,
        "tracker_id": トラッカーのID,
        "parent_issue_id": "親チケットにしたいチケットがあるならそのチケットID",
        "due_date": "期日（2017−01−01とか)",
        "description": "# 概要\n　バックスラッシュnで改行できる。",
        "custom_fields": [
            {"id": カスタムフィールドのID, "value": "登録したい値", "name": "カスタムフィールドの名前"},
            {"id": カスタムフィールドのID, "value": ["一つのフィールドに", "登録したい値が複数あるときは", "こうやって分ける"], "name": "カスタムフィールドの名前"}
        ]
    }
}

入力例
payload = {
    "issue": {
        "project_id": 10,
        "subject": "チケットの件名",
        "status_id": 15,
        "tracker_id": 8,
        "parent_issue_id": "10000",
        "due_date": "2017−01−01",
        "description": "# 概要\n　バックスラッシュnで改行できる。",
        "custom_fields": [
            {"id": 1, "value": "かぼちゃ", "name": "好きな野菜"},
            {"id": 2, "value": ["D", "F","G","H"], "name": "好きなサイズ"}
        ]
    }
}
```

## requestsでチケット登録！
以下の感じでチケット登録！

```
redmineurl = 'http://redmineのURL'　　
requests.post(redmineurl,headers=myheaders,data=json.dumps(payload))
```
SonarQubeをGradleから起動する


# はじめに

自分のソースをレビューしてもらう為に静的解析ツールを利用しようと思っていました。
導入まで時間かかると見積もって居たので正月休み最終日にチャレンジしてみましたのでまとめます。

# 更新履歴

|日付|内容|
|:--|:--|
|2017.01.03|初版|
|2018.02.27|OS入れ替えに伴い再インストール|

# 動作環境

~~2017/01/03時点で以下の環境で実行しました~~
2018/02/27時点で以下の環境で実行しました
・MacOs Sierra -> HighSierra
・CakeBrew
・Gradle 3.2.1 -> 4.5.1
・SonarQube 6.1 -> 7.0
・MySql 5.7.16 →　5.7.17
・IntelliJ IDEA

# 参考サイト

[SonarQubeでPHPのコードを静的解析する](http://qiita.com/kadoyau/items/70f4a403b42847e4ed00) 
[SonarQubeでプログラムの品質管理をはじめる（インストール）](http://qiita.com/sh-ogawa/items/4966afaaed72b444ab80) 


# 導入

1. CakeBrewよりSonarQube 7.0をダウンロード
2. MySqlを立ち上げ、ユーザーとデータベースを作成する
3. SonarQube設定ファイルを修正
4. build.gradleにSonarQubeプラグインを導入
5. SonarQubeを立ち上げる
6. IntelliJ IDEAよりGradle越しにSonarQubeを動かす

## MySql

ターミナルよりMySqlを起動し、データベースへログインする。
ログイン後、ユーザーとデータベースを作成する。

```lang:コマンド
CREATE DATABASE sonar;
CREATE USER 'sonar'@'localhost' IDENTIFIED by 'sonar';
GRANT ALL PRIVILEGES ON sonar.* TO 'sonar'@'localhost';
FLUSH PRIVILEGES;
```

## SonarQube設定ファイル

Finder越しにファイルを追いたい為、ターミナルに下記コマンドを入力する

```lang:コマンド
open -a Finder /usr/local/Cellar/sonarqube/
```

```lang:/usr/local/Cellar/sonarqube/7.0/libexec/conf/sonar.properties
下記設定値を有効化し修正する。
sonar.jdbc.username
sonar.jdbc.password
sonar.jdbc.url
```
## build.gradle

```groovy:build.gradle
plugins {
    id "org.sonarqube" version "2.6.2"
}

sonarqube {
    properties {
        property "sonar.host.url", "http://localhost:9000/"
        property "sonar.jdbc.driverClassName", "com.mysql.jdbc.Driver"
        property "sonar.jacoco.reportPath", "${project.buildDir}/jacoco/test.exec"
    }
}
```

## SonarQubeの立ち上げ

```lang:コマンド
sonar start
```

 [http://localhost:9000](http://localhost:9000)でアクセスできる

*MySqlが立ち上がっていなかったり、プラグインの関係で立ち上がらなかったりします。

## ユーザーログイン
初回ユーザー＆パスはadmin/admin

## IntelliJ IDEA → Gradle → SonarQube

IntelliJ IDEAのGradleツールより、sonarqubeをダブルクリック

![スクリーンショット 2017-01-04 21.52.16.png](https://qiita-image-store.s3.amazonaws.com/0/106929/3218b3a1-751c-179d-696c-6d153f6c8355.png "スクリーンショット 2017-01-04 21.52.16.png")

# SonarQubeをカスタマイズ

SonarQube6.1はデフォルトでC,Java,javascriptを解析できるよう。
→　プラグイン導入で他言語も解析できます。

追加で導入してみたプラグインは下記

プラグイン名       |                
:---------- | -------------------:
CSS / Less      |     
Checkstyle      | 
Findbugs      | 
Groovy      | 
JSON       | 
Japanese Pack     | 
Java Properties      | 
Web      | 
XML      |     

導入方法は管理者権限でログイン(デフォルトでadmin,admin)
システム設定よりアップデートセンターでプラグインをインストール、SonarQubeをリスタート

# 苦労したこと

MySqlを5.7.17にあげたらMySqlが素直に立ち上がらないという事態に陥りました。
現在も不要な手順を踏んで立ち上げております。
どうしたものか。。。
[wip] tweetstream gem が Ruby 2.4.0 でインストールできない

備忘録。

tweetstream gem をたまに使っていたが Ruby 2.4.0 に上げたらインストールできない。

tweetstream の依存関係は

```ruby
gem 'twitter', '~> 5.5'
```

となっているが twitter gem 5 系は `'json', '~> 1.8'` になっていて Ruby 2.4 ではインストールできないというやつ。
（素直に twitter gem のバージョンを上げられるのかはまだ試してない）

cf:

- https://www.hsbt.org/diary/20160829.html
- https://github.com/tweetstream/tweetstream/issues/202
ES6でできること覚書

Javascript ES6 Cheatsheet - the best of JS ES6
https://www.youtube.com/watch?v=AfWYO8t7ed4

:arrow_up: こちらに載っていたコードの写経のようなものです。
なんとなく何やっているのかを見出しとして書いていますが、不適切な可能性がありますので コードを読んで理解してください。:bow:

# トランスパイラ

[babeljs.io](http://babeljs.io) を使おう（[traceur](https://github.com/google/traceur-compiler)ってのもあるよ）

# ES6

## プロパティを別な変数に切り出す

### オブジェクトから

```javascript
var foo = {
  bar: 1,
  baz: 2
};

// before
var bar = foo.bar;
var baz = foo.baz;

// after
var { bar, baz } = foo;
```

### 配列から

```javascript
var tenses = ["me", "you", "he"];
var [firstPerson, secondPerson, thirdPerson] = tenses;
```

### `Promise` と併用

```javascript
Promise.all([promise1, promise2]).then(function(results) {
  var [ results1, results2 ] = results;
});

// 引数の時点で展開させることもできる
Promise.all([promise1, promise2]).then(function([results1, results2]) {

});
```

### 宣言済みの変数を挿入する

```javascript
var foo = 2;

var obj = {
  bar: 1,
  foo
};
```

```javascript
var name = "will";
var age = 34;

// before
some.method({
  name: name,
  age: age
})

// after
some.method({ name, age });
```

### オブジェクトのキー名の `[]` の中で文字列を展開できる

```javascript
var name = "will";
var obj = {
  ["name" + name]: "some value"
}
obj["name"+name] = "some value" // これもOK
```

### 引数にオブジェクトを使う（？）

元コード

```javascript
function calcBmi(weight, height, max, callback) {
  var bmi = weight / Math.pow(height, 2);
  if (bmi > max) {
    console.log("you're overweight");
  }
  if (callback) {
    callback(bmi);
  }
}
calcBmi(weight, height, 25);
calcBmi(weight, height, null, function() {});
```

引数をオブジェクト化

```javascript
function calcBmi({ weight, height, max, callback }) { // options.weightとかやらなくて済む
```

初期値

```javascript
function calcBmi({ weight, height, max = 25, callback }) {
```

順番を気にしなくてよい

```javascript
function calcBmi({ height, weight, max = 25, callback }) { // weightとheightを逆にした
```

ラベル貼れる

```javascript
function calcBmi({ weight: w, height: h, max = 25, callback }) {
```

必要な引数だけ使える

```javascript
calcBmi(weight, height, max: 25); // callbackをundefinedに
calcBmi(weight, height, callback: function() {}); // maxをundefinedに
```

## Template Strings

```javascript
var name = "will";
var thing = "party";

// before
var greet = "hi, my name is " + name + "and I like to " + thing + ".";
// after
var greet = `hi, my name ${name} and I like to ${thing}!`;
```

後半: https://www.youtube.com/watch?v=LmL0Gh193M0 （そのうちこっちも訳す）
WeakなSubscribe

#どーいうことか?

ReactiveExtensionsにおいて､Iobservable.SubscribeはIDisposableを戻り値となるから､こいつを使っていにしえから有るEventよっか相当ましなリソース制御が出来るようにゃなった｡
けど､状況によっちゃDispose出来るタイミングが無かったりすることがあるので､Subscribeの結果が強参照を持たない様に何とかしてみたので､おつきあい頂ければ幸い｡

#この問題のゴール

今回､以下のような目標が有ると言うことで一つ｡

 1. Subscribeの結果､IObservableにIObserverの強参照を持たせない｡
 2. IObserverが開放されたら自動的にDisposeを実行して､サブスクライブの自動開放を行う｡
 3. ↑のタイミングはOnNext,OnCompleted,OnErrorの呼ばれたタイミングを使う｡

#で何をしたのか


何をしたかってーと､WeakSubscribeメソッドと言う拡張メソッドを作成した｡まぁ､その中で一服盛ってる｡
内部に､WeakObserverを抱えており､こいつが結構キモとなる｡以下実装

```csharp

public static class WeakSubscriber
{
	private class WeakObserver<T> : IObserver<T>
	{

		private readonly WeakReference<IObserver<T>> _observer;
		private IDisposable _disposable;
		public WeakObserver(IObserver<T> observer)
		{
			if (observer == null) throw new ArgumentNullException(nameof(observer));
			_observer = new WeakReference<IObserver<T>>(observer);
		}

		//This method is not protected from multi thread.
		public void SetDisposable(IDisposable disposable)
		{
			if (disposable == null) throw new ArgumentNullException(nameof(disposable));
			if(_disposable!=null) throw new InvalidOperationException();

			_disposable = disposable;

		}

		public void OnNext(T value)
		{
			IObserver<T> obs;

			if (_observer.TryGetTarget(out obs))
			{
				obs.OnNext(value);
			}
			else
			{
				Exchange(ref _disposable, null)?.Dispose();
			}

		}

		public void OnError(Exception error)
		{
			if (error == null) throw new ArgumentNullException(nameof(error));
				

			IObserver<T> obs;

			if (_observer.TryGetTarget(out obs))
			{
				obs.OnError(error);
			}
			else
			{
				Exchange(ref _disposable, null)?.Dispose();
			}

		}

		public void OnCompleted()
		{
			IObserver<T> obs;

			if (_observer.TryGetTarget(out obs))
			{
				obs.OnCompleted();
			}
			else
			{
				Exchange(ref _disposable, null)?.Dispose();
			}
		}

	}
}
```

こいつが何をしてるかというと､ラップしてる元のIObserverを弱参照化させて､Subscribeされた結果が強参照化しないようにしてる｡
また､IDisposableを保持しており､参照先が消えて無くなったら､Subscriptionを開放するようになってる｡

また､保持してたIDisposableオブジェクトも､一度Disposeメソッドを読んだ後さっさと開放するようにしてある｡

で､こいつを元に､以下のような拡張メソッドをこさえた｡

```csharp

public static class WeakSubscriber
{


	public static IDisposable WeakSubscribe<T>(this IObservable<T> observable, IObserver<T> observer)
	{
		if (observable == null) throw new ArgumentNullException(nameof(observable));
		if (observer == null) throw new ArgumentNullException(nameof(observer));

		var weak = new WeakObserver<T>(observer);

		var token = observable.Subscribe(weak);
		weak.SetDisposable(token);

		return token;

	}
}

```

こっちは比較的単純｡IObservableのSubscriptionの引数に､先のWeakObserverを渡して､貰ってきたIDisposableを設定したら元のIDisposableを返しているだけ｡


#積み残し

こんなの作っておけば､概ね便利に使える反面､以下の問題は積み残している｡

 1. On~~が呼ばれないと開放されない
 2. そもそも､On~~の中でDisposeするって言う少し行儀の悪いことをしてる
 3. コンシューマーが検知できない形でDisposeメソッドが複数回呼ばれる可能性がある

1.に関しちゃ､重くなるけど､内部でタイマなり走らせて､生存確認することで対応出来るとは思う｡
3.にかんしては､Disposeメソッドを複数回呼ぶとマズい設計はあんまり良くないと思う(と逃げておくw)
2.が結構問題で､この辺割り切らないと駄目かなぁと思いました｡

最後に､ロックフリーで､CompareExchange使っていた部分で､Exchange使っても同じ事が出来ると教えてくださった､@Temarinさん有り難うございました!