OmniAICreator/Qiita-1.07M huggingface dataset:
fetchmail + maildrop + mutt で(gmailの)メール受信環境構築

# イントロ
最近大学から重要なメールがよく届くようになりました。

というのも、来年度から研究室に配属されるので、その講座配属に関する結構重要な情報がメールで来てました。

で、頻繁にブラウザ開いてgmail行ってログインして見てたんですけど、これ結構時間かかるのですよね、それで、なんとかできないかなぁとか思ってました。

そこで、もうCUIで操作できるmailer環境構築しちゃおうかなと思いやってみました。
ディストロは archlinux でやってます。


## メール受信

### fetchmail

インストールは、以下で

```
# pacman -S fetchmail
```

まず、fetchmailでgmail上にあるメールをPOP3経由で取得するための設定をします。
設定ファイルは ~/.fetchmailrc です

``` .fetchmailrc
  poll pop.gmail.com                # gmailのpop3サーバ
    protocol pop3                   # 使用するプロトコル
    port 995                        # gmailpop3サーバのポート
    uidl                            # pop3サーバから重複したメールを受取らない仕組み(UIDL)を使用
    flush                           # メールを受取ったらgmail側でメールを削除
    no rewrite                      # ヘッダーを書き換えない設定
    no mimedecode                   # 文字化けしないようにする設定
    user "your.address@gmail.com"   # 受け取りたいメールサーバのアドレス
    pass "Your gmail password"      # メールサーバのパスワード
    ssl                             # ssl通信をするという宣言
    mda "maildrop"                  # maildropをmdaに指定
```
以上でuserで指定したgmail宛に来たメールを取得できます。ですが、まだ、ユーザが見れるような状態ではないので、その辺を maildrop にやらせます。

### maildrop

インストールは、

[http://www.courier-mta.org/download.html#maildrop]

からダウンロードして、ビルドします。

```
$ tar jxvf /path/to/download/maildrop.tar.gzip
$ cd maildrop
$ ./configure
$ ./make
# ./make install
```
で、インストールできます。

maildropは、フィルターと呼ばれるスクリプトで、

```
if( 件名にhogeを含むなら ) {
  hogeボックスへ
}
if( Fromメールアドレスが*@example.comなら ) {
  example.comボックスへ
}
```
と言うようにメールの振り分けを行います。

設定ファイルは ~/.mailfilter です。

``` .mailfilter
MAILDIR = "$HOME/Maildir"
DEFAULT = "$MAILDIR/"

to "$MAILDIR/"    # 何も指定しない場合は $DEFAULTに飛ばされるので 実際は必要ない
```
ほんとは

```
if (/^From:.*@example.com/)
{
    to "$MAILDIE/example.com"
}
```
とかやって振り分けるんですが、今は特に振り分けなくていいかなということで全部同じとこにぶち込んでます。


ここまでやったら、maildropで振り分けたメールを保存するディレクトリ、メールディレクトリを作成します(maildropはMaildir方式です)。

```
$ maildirmake $MAILDIR
```
コマンドでmaildirのディレクトリを作成するとができます。

ここまでやれば、

```
$ fetchmail
```
コマンドでメールを取得できるはず。
でも、maildir形式のデータ構造なので、テキストエディタとかで見ようと思って見れないことはないけどまともに見れません。

そこで、 mutt を今回使いました。

### mutt

インストールは、以下で

```
# pacman -S mutt
```

muttはCUIで操作できるメールクライアントです。
主に、メールの閲覧に使うつもりです。
設定ファイルは ~/.muttrc です。

``` .muttrc
set mbox_type =   Maildir # 
set folder    = ~/Maildir # 
set spoolfile = ~/Maildir # 

set assumed_chareset = "iso-2022-jp:euc-jp:shift_jis:utf-8" # 文字符号化方式を使われていない場合のcharset
set charset          = "utf-8"  # muttでデータを入出力する際のcharset
```

こんな感じでfetchmailで取ってきて、maildropで振り分けたメールを閲覧できるようになります。

## 参考になるページ

[http://www.uetyi.com/server-const/linux-server/entry-72.html:title]

[http://www.mutt.org/doc/manual/:title]
cssで境界に画像を挿入する方法

```css
border-bottom: #fff url(images/kyokai.png) repeat-x;
```
じゃダメなので調査中……

```css
background: #fff url(images/kyokai.png) repeat-x;
```
で表示されるからあるんだけどな……

```css
padding-bottom: #fff url(images/kyokai.png) repeat-x;
```
でも無い……orz
Windows10のWinSCPでネットワークドライブを認識しない問題対応

私はWinSCP使ってないんですが、同じチームの非エンジニアの方に相談を受けて対処したときのメモです。

レジストリの以下のパスに、
> \HKEY_CURRENT_USER\Software\Microsoft\Command Processor

以下の値を追加する。

|名前|種類|値|
|:---:|:---:|:---:|
|DisableUNCCheck|DWORD|1|

※ 私が対処したケースでは、これでネットワークドライブが認識されました。自己責任でどうぞ
mysql command における localhost と 127.0.0.1 の違いについて

```
mysql -u USERNAME -p -h localhost
```
は

```
mysql -u USERNAME -p -h localhost -P 3306 --protocol=SOCK
```

で、

```
mysql -u USERNAME -p -h 127.0.0.1
```

は、

```
mysql -u USERNAME -p -h 127.0.0.1 -P 3306 --protocol=TCP
```

である。
find 特定ディレクトリ以下の uid,gid の数値のペアがどんなものがあるか探す

# 概要

特定のディレクトリ以下の、uidとgidの数値のペアでどんなものがあるか調べたい


# 結論

`/tmp/` いかを調べたいときはこんな感じ

```
find /tmp/ -exec ls -lnd {} \; | \
 awk  '{print $3,$4;}' |  sort | uniq
```
## １行にすると

```
find /tmp/ -exec ls -lnd {} \; | awk  '{print $3,$4;}' |  sort | uniq
```


数字でなくて、名前にしたいならば `ls` のオプションを変更して `n` をはずす

```
find /tmp/ -exec ls -ld {} \; | \
 awk  '{print $3,$4;}' |  sort | uniq
```

## 1行にすると

```
find /tmp/ -exec ls -ld {} \; | awk  '{print $3,$4;}' |  sort | uniq
```


# そもそも

あるディレクトリ以下の uid と gid を変更する必要があったが
全部同じ uid, gid でかきかえてよいのかを確認したかった
Hash.new { |h, k| h[k] = ... } イディオムの意味

HashでキーごとにArrayやHashのデフォルト値を持ってそれを破壊的に変更して使いたい時、なぜ`Hash.new { |h, k| h[k] = ... }`と書かないとけないのか、知ってたつもりだったけど老人すぎて忘れたのでメモしておく。

### Hash.new の引数に渡すと全てのキーから同じオブジェクトが共有されてしまう
```rb
hash = Hash.new([]) # この行で生成されたオブジェクトが全てのキーから参照される
hash[:a] << 1 #=> [1]
hash[:b] << 2 #=> [1, 2]
hash[:a] #=> [1, 2]
```

### 単にブロックでオブジェクトを作って戻り値にするだけだと、どこにも参照が保存されないので、デフォルト値の破壊的変更によって値を書き変えても結果が失われてしまう
```rb
hash = Hash.new { [] }
hash[:a] << 1 #=> [1]
hash[:a] #=> []

# 代入されない限り常に別のオブジェクトが返る
hash[:a].object_id #=> 47040537710560
hash[:a].object_id #=> 47040542091400

# 単なる破壊的変更ではなく、キーに対する代入をすればこれでも使える
hash[:a] += [1] #=> [1]
hash[:a] #=> [1]
hash[:b] #=> []
```

### デフォルト値を作った後そのキーに対して代入をしておけば、キーごとに、最初に参照した時のオブジェクトが使われるようになる
```rb
hash = Hash.new { |h, k| h[k] = [] }
hash[:a] << 1 #=> [1]
hash[:b] << 2 #=> [2]
hash[:a] #=> [1]
hash[:b] #=> [2]
```

普段あんまり深く意識して使わないけど、ArrayやHashをデフォルト値に持つHashに関して、大抵の場合人間が欲しいものは最初に参照した時に作られたオブジェクトをキーごとに参照し続けられるHashなので、`Hash.new { |h, k| h[k] = ... }`のように書いておくと良い。
MySQLのスキーマをリネームする方法について

MySQLでは、「RENAME DATABASE」構文がサポートされていません。
そのため、スキーマ名を変更したい場合は以下のような手順で行うことが出来ます。

###### 1. 以下の get_rename_sql.txt を適当なところに配置

```
$ cat /tmp/get_rename_sql.txt  
CREATE DATABASE IF NOT EXISTS <new_schema_name>;

SELECT DISTINCT CONCAT(
'RENAME TABLE ', 
t.table_schema,'.', t.table_name, 
' TO ', 
"<new_schema_name>", '.', t.table_name, 
';' ) 
as rename_table INTO OUTFILE "/tmp/rename_<old_schema_name>_tables.sql"
FROM information_schema.tables as t WHERE t.table_schema="<old_schema_name>"
AND t.table_type = "BASE TABLE";
```

###### 2. get_rename_sql.txt 内の \<old_schema_name> と \<new_schema_name>を目的の名前に変更

###### 3. 以下のコマンドを実行
`$ mysql -u root -p < /tmp/get_rename_sql.txt   `

※ /tmp/直下に、RENAME TABLE文をまとめたクエリが作られる

```
$ cat /tmp/get_rename_sql.txt  
RENAME TABLE old_db.t1 TO new_db.t1;
RENAME TABLE old_db.t3 TO new_db.t3;
```

###### 4. 作成されたsqlファイルを実行
`$ mysql -u root -p < /tmp/rename_old_db_tables.sql`

これで対象スキーマのリネームが出来るはずです。なお、手順4.でRENAME TABLEを実行した後は、
旧スキーマからテーブルが無くなってしまう点には注意が必要です。

【参考URL】
http://qiita.com/tuboc/items/06add22b692a25bd19b5

=========================================================

【補足】「VIEW」はスキーマを跨いでのRENAME TABLEが実行できません。

>http://stackoverflow.com/questions/5475473/how-to-rename-a-view-in-mysql
>
> If it's within the same database, it's OK, but contrary to tables,
> MySQL does not support moving views from one database to another.
> Thus, DROP+CREATE is a more general approach.

そのため、VIEWに関しては以下のようにmysqldumpを使った方法を推奨します。

###### 1. 以下のコマンドで、VIEWのテーブル名のみを抽出（半角スペース区切り）
```
$ mysql -u root -sN -p -e "SELECT GROUP_CONCAT( DISTINCT t.table_name SEPARATOR ' ' ) \
FROM information_schema.tables as t WHERE t.table_schema='book' AND t.table_type='VIEW';"
Enter password: 
test_view test_view2   # VIEWのテーブル名が出力される
```

###### 2. VIEWのみのdumpファイルを出力
`$ mysqldump -u root -p <old_schema> test_view test_view2 > /tmp/rename_<old_schema>_views.sql`

###### 3. 新スキーマにdumpファイルをインポート
`$ mysql -u root -p <new_schema> < /tmp/rename_<old_schema>_views.sql`

ちなみに、新スキーマにテーブルがないとVIEWの作成が出来ないので、
上記の手順は冒頭のスキーマのリネームが完了してから行って下さい。
Outlookの振り分けルール(代理で送信しましたを振り分ける)

社内でちらほら使われているOutlook

また面倒な仕様があったのでメモを

##### ～の代理で送信しました問題
+ メールヘッダにSenderがあると～の代理で送信しましたと表示される

これ自体はいい機能だとおもうのだけど、振り分けをしようとするときに問題が発生

仕訳けルールを作成しようとしても

+ 送信元を選ぶところではSenderしかでてこない
+ Fromなんて信用できないね！ってスタイル

##### カスタムルールを作成する

1. とりあえずReturn-Pathを仕訳けルールに
2. メッセージのソースを表示[（参考）](https://support.office.com/ja-jp/article/%E9%9B%BB%E5%AD%90%E3%83%A1%E3%83%BC%E3%83%AB-%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8-%E3%83%98%E3%83%83%E3%83%80%E3%83%BC%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B-cd039382-dc6e-4264-ac74-c048563d212c)し、Return-Pathの行をコピー
3. カスタムの仕訳ルール(特定のヘッダが含まれる場合)を使用しルールに貼り付ける
4. 動作確認

という手段で作成してみました…。他のメーラみたいにカスタムルールの場合ヘッダ一覧がポンと出てこの行つかう～ってインタフェースがあればこんな手間かけなくていいのに…
【SalesForce】外部CSVをレコードとして取り込む

こんにちは。

SalesForceにCSVファイルを取り込みます。
そして、レコードとして環境内に新規作成します。

まずVFに操作用のテーブルを作ります。

```html
<table border="0" style="width: 100%;">
  <tr>
    <td><apex:inputFile filename="{!cv.Title}" value="{!cv.VersionData}"/></td>
    <td>
      <apex:commandButton value="取込" action="{!ImportBtn}" />
    </td>
  </tr>
</table>
```

そしてApexにCSVを取り込む記述をします。
これがメインとなるクラスです。

```java
/** 入力ファイル */
public ContentVersion cv {get; set;}

/** ボタン押した時のメソッド */
public PageReference ImportBtn(){

    // CSVリスト化してオブジェクトを作成しInsert
    List<List<String>> strListLists = new List<List<String>>();

    // 取込みCSV
    String csvFile = this.cv.VersionData.toString();
    //文字列からCSV行毎のリストを作成
    List<String> rowList = csvFile.split('\r\n', 0);
    //CSV行毎のリストから項目のリストを作成
    for(Integer i = 1 ; i < rowList.size() ; i++){
        // 項目単位にリスト化し、取込みCSVリストに追加
        List<String> strLists = rowList[i], ',';
        strListLists.add(strLists);
    }

    // リスト作成
    List<Target__c> targetList = insertCreator(strListLists);

    // 新規作成
    insert targetList;

    return null;
}
```

そしてこれはCSV内の文字列をリストに変換する処理

```java
public List<Target__c> insertCreator(List<List<String>> targetStringList) {

    // 更新用のリストを作成
    List<Target__c> insertList = new List<Target__c>();

    // 対象の番号を付けてMapに保存
    numberCounter = 0;
    Map<Integer,String> targetStringMap = new Map<Integer,String>();
    for (String targetString : stringList) {
        targetStringMap.put(numberCounter,targetString);
        numberCounter += 1;
    }

    // Mapの値を取得して更新用リストに詰める
    for (List<String> stringList : targetStringList) {
        Target__c target = new Target__c();
        target.Name = targetStringMap.get(0);
        insertList.add(target);
    }

    return insertList;
}
```

これで読み込みたいCSVファイルを選択して、ボタン押したら取込み出来ます。

ついでに出来上がったことをメールにして誰かに送りつけてやりましょう。

まずメールの送信設定の中を書き換える必要があります。
設定⇒メール管理⇒送信⇒アクセス権を『すべてのメール』に設定。
※設定してあったらそのままで。

```JAVA
private void sendMail() {

    // メールアドレス設定(送り先・送り主)
    String labelAddress = 'watachan@test.jp';
    String userAddress = UserInfo.getUserEmail();
    String[] address =labelAddress.split(',');
    address.add(userAddress);

    // 件名
    String subject = '';

    // メール本文
    String body = '';

    // ログオブジェクト
    BatchLog log = new BatchLog();

    // メールを新規作成
    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

    // 件名
    subject = '【 成功のお知らせ 】\r\n';
    body += '成し遂げたぜ。\r\n';

    // メール設定
    mail.setToAddresses(address);
    mail.setSubject(subject);
    mail.setPlainTextBody(body);

    // メール送信
    Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});

}
```

以上です。
git stashのpopがうまくいかなかったお話

gitのstashを使って一時的に退避させていた内容をpopしたかったのですが、うまくいかなかった現象に対するメモ。

`$ git stash pop stash@{0}`

> fatal: ambiguous argument 'stash@0': unknown revision or path not in the working tree.
> Use '--' to separate paths from revisions, like this:
> 'git <command> [<revision>...] -- [<file>...]'

こうすれば解決。

`$ git stash pop stash@\{0\}`

エスケープするだけで解決するんですね。

＜参照＞
http://helen.hatenablog.com/entry/2015/11/16/190338
JavaScriptでHSVからRGBに変換

以下のようなカラーサンプルを作りたかったので、[HSL and HSV（wikipedia）](https://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV)の計算式を参考にHSVからRGBに変換するプログラムをJavaScriptで書いてみました。

![colorsample.png](https://qiita-image-store.s3.amazonaws.com/0/128670/3e29cc44-62e3-8dec-ab14-3b6476c233b7.png)

## 実際の計算式は？
[HSL and HSV（wikipedia）](https://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV)で公開されている計算式は以下のような感じです。
>![1](https://wikimedia.org/api/rest_v1/media/math/render/svg/39feca9ead1dd384e53968a11d33bd5e301278a6)
![2](https://wikimedia.org/api/rest_v1/media/math/render/svg/6b3b4e608fd86da9301cddd28c42c642d960ca37)
![3](https://wikimedia.org/api/rest_v1/media/math/render/svg/0bdde005f30098d63995d4808efbf87d18089830)
![4](https://wikimedia.org/api/rest_v1/media/math/render/svg/e9ec6e3ee363f7bb8cc58d083eb204b3eb38d6aa)
（「[HSL and HSV](https://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV)」（5 Feb 2017, at 22:40 UTC）『ウィキペディア』より引用）

計算式中の「if 0 ≤ H' ≤ 1」の部分ですが、[HSV色空間（ウィキペディア日本語版）](https://ja.wikipedia.org/wiki/HSV%E8%89%B2%E7%A9%BA%E9%96%93#HSV.E3.81.8B.E3.82.89RGB.E3.81.B8.E3.81.AE.E5.A4.89.E6.8F.9B)では「if 0 ≤ H' ＜ 1」なっていましたので、今回は「if 0 ≤ H' ＜ 1」を使うことにしました。それがどれほどの影響を与えるのかは正直よくわかりませんが…。

## HSVからRGBへの変換プログラム

```js:hsvToRgb
function hsvToRgb(H,S,V) {
	//https://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV

	var C = V * S;
	var Hp = H / 60;
	var X = C * (1 - Math.abs(Hp % 2 - 1));

	var R, G, B;
	if (0 <= Hp && Hp < 1) {[R,G,B]=[C,X,0]};
	if (1 <= Hp && Hp < 2) {[R,G,B]=[X,C,0]};
	if (2 <= Hp && Hp < 3) {[R,G,B]=[0,C,X]};
	if (3 <= Hp && Hp < 4) {[R,G,B]=[0,X,C]};
	if (4 <= Hp && Hp < 5) {[R,G,B]=[X,0,C]};
	if (5 <= Hp && Hp < 6) {[R,G,B]=[C,0,X]};

	var m = V - C;
	[R, G, B] = [R+m, G+m, B+m];

	R = Math.floor(R * 255);
	G = Math.floor(G * 255);
	B = Math.floor(B * 255);

	return [R ,G, B];
}
```

## カラーサンプルのプログラム

実際のカラーサンプルを描くプログラムは以下のような感じです。

```js
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 360;
canvas.height = 101;
for(var s=0;s<=100;s++) {
	for(var h=0; h<=359; h++){
		ctx.fillStyle = 'rgb(' + hsvToRgb(h, s/100, 1).join(",") + ')';
		ctx.fillRect(h, s, 1, 1);
	}
}
document.body.appendChild(canvas);
```

## 関連リンク
- [JavaScriptでRGBからLab色空間への変換](09caabe6bec46a2a0858)
- [JavaScriptでCIEDE2000色差計算](860f061a2ab7a4f2d06f)
- [JavaScriptでCIE94色差計算](3488df50b7082d4fcffb)
- [JavaScriptでCIE76色差計算](cda9b95395468ee7e0f8)
- [JavaScriptでユークリッド色差計算](28c7b61d6b8ca54c5b94)
- [色差アルゴリズムの違いをビジュアル化してみた](98c218bc5616eaaba9a0)
エンジニア立ち居振舞い：何やってるのか分かるようにする（転載）

[Odai「エンジニア立ち居振舞い」](http://blog.hatena.ne.jp/-/odai/10328749687193803821)
への回答

過去に一度ブログに書いたネタだが、エンジニアが見る場所に書くほうが誰かの為になるかもしれないので忘れる前に転載しておく。不適切だと思ったら消すかも

## 転載元
http://satzz.hatenablog.com/entry/2016/11/14/165246

## 以下転載

> うまく整理できるかわからないが面白そうなので、思いつくままに書きなぐってこっそり差し込んでおく。 チーム構成によってメンバーへの接し方を変えるのがよいという当たり前の話になりそう。ときどきできてないこともある。


## チーム構成が固くて分担できる場合

> 自分がマネージャーになる場合は、適宜タスク整理、チームのガイドライン整備、PRのレビュー、忙しそうなメンバーのサポートをする。 チームだからできることというのも多いので、うまくメンバーの能力にレバレッジをかけていく。

> 例えばドキュメンテーションの経験が長い人からはその話をちゃんと聞いて、現状とすり合わせてよさそうな方法を一緒に考える。 技術習得に熱心なメンバーがいる場合は、自分がやりたいのをこらえて「こういうのが主流みたいなんだけど着手できてないんだよねー」「このへん読むとなんかよさそうなんだよねー」みたいな感じでヒントを出しておくと自分よりもいい感じで調べて整理してくれたりすることがある。 自分にフロントエンド経験が全くなかったときは、より豊富なメンバーに完全にお任せしていた。

> ただしいずれにしても、各メンバーの裁量でどうにもならないところは自分が引き受ける。 要件ヒアリング、外注先対応、他チームとの調整（ミーティングアサイン含む）、SlackやQiitaやConfluenceなどチームにあったコミュニケーションツールの選定、スクラム・リリースフローの調整、アクセス権限整理、リソースのコスト管理、メンバーの手に負えない技術調査、他社の事例調査などがこれにあたる。

> メンバーの強化したい領域も推移していくし、のっぴきならない事情で自分が引き継がないといけない場合もあるので、分担は暫定と考えて、折を見て各メンバーから話は聞いておく。 他人がやってくれるからと上流に行き過ぎて手が動かなくなるとチームの価値発揮・自分のエンジニアキャリア双方危うくなることがあるので、それは避けるようにする。同様に、自分のやったこともちゃんとどこかに残す。再現性重要。あとチームの冗長化重要（とくに自分が休暇とって動けなかったりするとき）。

## エンジニアメンバー（あるいはエンジニアの理解者）が少ない場合

> チームに自分が入った時点でドキュメントがない場合はひとまず要件・業務フロー・全体の構成・シーケンスあたりをざっと書いて整理するところから始める。 その後は、何やってるか外から見てわからない感じにならないことが意外と重要かも。 「よく知らないけどこれくらいでできるんじゃないの」と言われたら、「あーまたわかってないな」と言いたくなるのを我慢して、後で潰すことも考えてとりあえず設計して実装して何かしらの目に見える進捗を見せる。 プロトタイプと割り切って、書いたコードにあまり思い入れないようにする。 少し落ち着いた時にコツコツリファクタしたりインフラの置き換えをやるというように、緩急つける。 もし可能であれば、スタックは自分が使いやすいもの、あるいは将来新しい人が入ってきてもググれば分かるくらいのよく使われるものにしておく。

## その他

> いつかのRebuild.fmで「自分が技術的にはやりがいがないと思う仕事ほど、逆に感謝されたりする」という話があったような気がする。 自分の興味と周りの要望のバランスはどうしてもとらざるを得ない。 とはいえ、こういう理由からエンジニアはふとしたきっかけで虚しくなったり孤独になりやすいような気がする。 ということで、自分が何をやってるのかわかるようにすることは、チームだけでなく自分のためにもなる。 一緒に盛り上がれるエンジニアが周りにいない場合は、他の環境のエンジニアとランチするだけでも結構救われたりする（隣の庭の芝生は青くみえることも時々あるけど）ので、そういうのを避けないで参加するとよいと思う。
Rubyのヒアドキュメントでインデントを綺麗にするいくつか



### <<~ or String#strip_heredoc

Ruby2.3以降であれば`<<~`とを使うといい。

```rb
def foo
  puts <<~STR
    foo
      bar
        baz
  STR
end
```

もしくはActiveSupportの`String#strip_heredoc`でも同様のことができるが、素直にRuby2.3以降にバージョンアップして`<<~`のが良い。

```rb
if options[:usage]
  puts <<-USAGE.strip_heredoc
    This command does such and such.
 
    Supported options are:
      -h         This message
      ...
  USAGE
end
```


### String#squish

長い1行の記述を書くときには`String#squish`が便利。ヒアドキュメント中は80行や120行などで改行いれて書くけど結果は1行になる。

```rb
def lock!(lock = true)
  if persisted?
    if changed?
      ActiveSupport::Deprecation.warn(<<-MSG.squish)
        Locking a record with unpersisted changes is deprecated and will raise an
        exception in Rails 5.2. Use `save` to persist the changes, or `reload` to
        discard them explicitly.
      MSG
    end
    reload(lock: lock)
  end
  self
end
```

ヒアドキュメントの戻り値は以下のとおり1行になる(冒頭と末尾のホワイトスペース、連続したホワイトスペースは1つのスペースに変換される)

```rb
=> "Locking a record with unpersisted changes is deprecated and will raise an exception in Rails 5.2. Use `save` to persist the changes, or `reload` to discard them explicitly."
```
UTC -> JSTへの時刻変換

# TL;DR

UTCで食わせて、JST(Asia/Tokyo)で出力する。

# コード

```groovy
def dateFormat = "yyyy-MM-dd HH:mm:ss"

// UTCで食わせて
jst = (new Date()).parse(dateFormat, "2017-02-09 13:24:33", TimeZone.getTimeZone("UTC"))

// JSTで出力する
println jst.format("yyyy-MM-dd HH:mm:ss", TimeZone.getTimeZone("Asia/Tokyo"))
```

```shell-session:output
2017-02-09 22:24:33
```

あるいは、安直に9時間足したいならこんなイメージ。

```groovy
jst.set(hourOfDay: jst[java.util.Calendar.HOUR_OF_DAY] + 9)
```

参考：http://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/Date.html#set(java.util.Map)

# thanks for
大元のネタはこちら。(結局原型が残らなかったけど。。)
「[Groovy|Java]タイムゾーンに関するメモ」
http://qiita.com/saba1024/items/15f2515b2a26fbf2a5ce
macOSのリカバリ

macOS（10.12.4 Developer Beta）バージョンアップのreboot時にpanic発生

![スクリーンショット 2017-02-09 11.41.56.png](https://qiita-image-store.s3.amazonaws.com/0/163369/ef7c113f-a325-1e77-7896-5c024b9cf754.png)


![946f8a41-fa53-6989-5d26-57c75a150b5e.png](https://qiita-image-store.s3.amazonaws.com/0/163369/05a7052f-08ff-b14f-021a-140f70cc2d69.png)

---
簡単に説明すると

1.リカバリモードでboot
2.怪しい拡張システムを削除

---

reboot時にキーボードの`command+R`を押下しながら起動すると
リカバリウインドウが開きます。（一安心）

_*「怪しい拡張システム」*_
パニックのメッセージ(com.kaspersky.kext.kllf)から`kaspersky`が怪しいと判断。


macのメニューからterminalを開き、拡張システムパスへ移動
   `cd '/Volume/Macintosh HD/System/Library/Extensions'`　

![スクリーンショット 2017-02-09 12.22.51.png](https://qiita-image-store.s3.amazonaws.com/0/163369/4c48f5ab-2f84-1938-0572-65613ad5b146.png)

kext の内部(Contents/Info.plist) を確認[^1] 　klif.kext klnke.kext の２つが
kaspersky 関連らしいと判断。いちおうバックアップし削除。 


   `rm -rf klif.kext klnke.kext`

念の為、アプリケーションもバックアアップして削除。

   `rm -rf '/Application/Kaspersky Anti-Virus For Mac.app'`
      
無事回復いたしました。（カペルスキーが死にましたが・・・）

今日(2/9/2017)の午前中の仕事＆初投稿でした。ご参考まで

---
[macOS 復元について](https://support.apple.com/ja-jp/HT201314)
[macOS Sierra stuck on Apple Logo & won’t Boot? Here’s How to Fix It](http://appletoolbox.com/2016/10/macbook-will-not-start-macos-sierra-update-fix/)
---

[^1]: 参考にしたページに　kextstat kextfind など使用していましたがシステム内に見つからずインストールされた日付などを参考に感で探しました。
Python > list > コピー方法3つ > .copy() / list() / [:] > Python3では動く / Python2では.copy()でエラー > 全てshallow copyでした

@ Introducing Python: Modern Computing in Simple Packages by Bill Lubanovic
(No. 1424 / 12833)

listのコピーの方法3つあるようだ。

試してみた。

```py
a = [ 'I am clone ' ]
b = a.copy()
c = list(a)
d = a[:]
 
a = [ 'I am original']
print(a)
print(b)
print(c)
print(d)
```


### Python 3

http://ideone.com/Pmchv0

```txt:結果
['I am original']
['I am clone ']
['I am clone ']
['I am clone ']
```

### Python 2

http://ideone.com/l5flEA

```txt:結果
Traceback (most recent call last):
  File "prog.py", line 2, in <module>
AttributeError: 'list' object has no attribute 'copy'
```

### docs

Python 3 
https://docs.python.org/3.6/tutorial/datastructures.html

Python 2 
https://docs.python.org/2/tutorial/datastructures.html

Python 3にはlist.copy()の記述があり、Python 2にはない。

### 追加で学習した事項

@shiracamus さんに[コメント](http://qiita.com/7of9/items/b3ff11b6076df13ebdb4#comment-0a64ca88f333bab23b11)いただいたように、上記のコピーはすべてshallow copyでした。
MacOSX EL Capitan 10.11.6 で "dyld: Library not loaded: /usr/local/opt/readline/lib/libreadline.6.dylib"

環境: Mac OSX EL Capitan 10.11.6

## 現象

エラーは以下のようなもの。
rbenv installに合わせて行われる、ruby-buildのconfigureの際に発生。

```
configure: creating ./config.status
config.status: creating GNUmakefile
dyld: Library not loaded: /usr/local/opt/readline/lib/libreadline.6.dylib
  Referenced from: /usr/local/bin/awk
  Reason: image not found
./config.status: line 1009: 52105 Done                    eval sed \"\$ac_sed_extra\" "$ac_file_inputs"
     52106 Trace/BPT trap: 5       | $AWK -f "$ac_tmp/subs.awk" > $ac_tmp/out
config.status: error: could not create GNUmakefile
```

どこかでbrew updateした際にバージョンが替わってしまったのだろうか、
libreadline.6.dylibがないと怒られるので `brew list readline` で見てみると
readlineは7.0.1となっていた。


## 解決方法

調べてみるとbashをupdateせよ、直接readlineをソースダウンロードせよ
などを言われているがどれも解決には繋がらなかった:(

結局強引にシンボリックを貼って解決（？）とした。

```
ln -s /usr/local/opt/readline/lib/libreadline.dylib /usr/local/opt/readline/lib/libreadline.6.dylib
```
FcitxのプレエディットをIntelliJでもインライン表示できるようにする

## 変換前のひらがなが変な位置に表示される

Ubuntu16.4 + IntelliJで開発していたら...

![outline_hiragana.png](https://qiita-image-store.s3.amazonaws.com/0/126701/67f61933-5e3c-15ff-0124-d7998779ef09.png)

日本語文字列を入力しようとすると、変換前の文字列（ひらがな）が、入力中のカーソルの位置に挿入されるのではなく、ウインドウの左下に表示されます。
これでも使えないこともないけれど、違和感が強いのでなんとかしたいところです。

## しらべた
https://wiki.ubuntulinux.jp/UbuntuTips/JapaneseEnvironment/Fcitx
そのものずばりな情報があったのでこちらを参考にしました。

### 原因
> Unity DashやWineで動作するアプリケーションなど、XIMを使用する場合はウィンドウの左下に未確定文字列（プレエディット）が表示されます。

IMEの都合のようですが、設定でなんとかできるようです。

### 設定の変更

> Fcitxの[設定]-[アドオン]-[拡張]（チェック）-[Fcitx XIM Frontend]-[設定]-[XIMでOn The Spotスタイルを使う(起動中は変更できません)]（チェック）-[OK]で、Fcitxの[再起動]をクリックすると次からインラインで表示するようになります。

できました。

![inline_hiragana.png](https://qiita-image-store.s3.amazonaws.com/0/126701/ac738ec5-f905-b249-84af-307a96a50633.png)

変換候補は相変わらずウインドウ左下に表示されるのですが、とりあえずプレエディットはインライン表示されるようになったので充分使いやすくなったかと思います。
Vagrant+VirtualBoxで作成した仮想マシンにPHPライブラリテスト用環境を構築する【2】

[Vagrant+VirtualBoxで作成した仮想マシンにPHPライブラリテスト用環境を構築する【1】](http://qiita.com/ss_watanabe/items/4bb3b86951ca82d71815)
Vagrant+VirtualBoxで作成した仮想マシンにPHPライブラリテスト用環境を構築する【2】 ←イマココ
[Vagrant+VirtualBoxで作成した仮想マシンにPHPライブラリテスト用環境を構築する【3】](http://qiita.com/ss_watanabe/items/22c406b84783e2ac2d14)
[Vagrant+VirtualBoxで構築した仮想マシンをBox化して復元する](http://qiita.com/ss_watanabe/items/d15f890af58fa16447f6)

# Webサーバー（Apache）の設定

## インストール
```
[vagrant@localhost ~]$ sudo yum -y install httpd
```
確認

```
[vagrant@localhost ~]$ httpd -v
Server version: Apache/2.4.6 (CentOS)
Server built:   Nov 14 2016 18:04:44
```
入ってるー

## 起動
```
[vagrant@localhost ~]$ sudo /etc/init.d/httpd start
```
確認

```
[vagrant@localhost ~]$ sudo /etc/init.d/httpd status
httpd (pid  2278) を実行中...
```
動いてるー

# 共有フォルダの設定
仮想マシン上の「/vagrant」フォルダとローカル上のvagrantfileを置いているフォルダ（今回は「libTestCentOSVM」）は共有されている！

```
[vagrant@localhost vagrant]$ ls
Vagrantfile                        <-----
[vagrant@localhost vagrant]$ logout      | 共有
libTestCentOSVM $ls                      | されている
Vagrantfile                        <-----
```

変更をlocalhostで即見れるようにするため、 webサーバーのドキュメントルートとシンボリックリンクを貼っておきます。

```
[vagrant@localhost ~]$ sudo rm -rf /var/www/html
[vagrant@localhost ~]$ sudo ln -fs /vagrant /var/www/html
```

以下のサイトを参考にSELinuxを無効にする
http://little-braver.com/552/

# PHP5.6の設定
こちらを参考に設定。
http://qiita.com/ozawan/items/caf6e7ddec7c6b31f01e

確認

```
[vagrant@localhost html]$ php --version
PHP 5.6.30 (cli) (built: Jan 19 2017 07:57:06) 
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
```
OK:thumbsup:

# MySQL5.7の設定
こちらを参考に設定。
http://qiita.com/UmedaTakefumi/items/924cdce7cfff083bf492

確認

```
[vagrant@localhost html]$ mysqld --version
mysqld  Ver 5.7.17 for Linux on x86_64 (MySQL Community Server (GPL))
```
:clap:

php-mysqlのインストールも忘れずに！

```
sudo yum --enablerepo=remi,remi-php56 install -y php-mysql
```

<br><br><br>サーバー側の環境設定はこれで終わりー:neutral_face:
長くなるので別記事へ続く！！
[Vagrant+VirtualBoxで作成した仮想マシンにPHPライブラリテスト用環境を構築する【3】](http://qiita.com/ss_watanabe/items/22c406b84783e2ac2d14)
Rails + PostgreSQLでIndexを利用した中間一致検索する

ショッピンサイトなどを開発していると中間一致で検索したくなりますよね。

でも、Elasticsearch入れるほどでも無いし...という場合の簡単な方法を紹介します。

試した環境は

* Ubuntu 16.04
* Ruby 2.3.3
* Rails 5.0.0
* PostgreSQL 9.5.5 (apt-get install)

です。

# pg_trgmの有効化

まずはサクッとpg_trgmを有効にしましょう。PostgreSQLに接続するユーザはSUPERUSER権限を持つ必要があります。

なければ、

```
psql -U postgres -c 'ALTER USER USER_FROM_RAILS WITH SUPERUSER'
```

こんな感じで権限与えます。

Railsでpg_trgmを有効にするには`rails g migration EnablePgTrgmExtension `して、

``` db/migrate/yyyyMMddhhmmss_enable_pg_trgm_extension.rb
class Hoge < ActiveRecord::Migration[5.0]
  def change
    enable_extension 'pg_trgm'
  end
end
```

からの、`rake db:migrate`ください。

# インデックス作成

これも`rails g migration AddIndexProductsOnName`して、

``` db/migrate/yyyyMMddhhmmss_add_index_to_product_on_name.rb
class AddIndexProductsOnName < ActiveRecord::Migration[5.0]
  def up
    add_index :products,
              'name gist_trgm_ops',
              using: :gist,
              name: :index_products_on_name
  end

  def down
    remove_index :products,
                 name: :index_products_on_name
  end
end
```

からの、`rake db:migrate`ください。

# 中間一致検索してみる

Likeで検索するだけです。サンプルでは小文字大文字無視したいのでiLikeで検索します。`rails c`で試してみて下さい。

``` ruby
Product.where("name ilike ?", "%silk%")
```

like検索なんだからあたりまえ?そうですね、index使っているか確認しましょう。


``` ruby
Product.where("name ilike ?", "%silk%").explain
  Product Load (0.5ms)  SELECT "products".* FROM "products" WHERE (name ilike '%silk%')
=> EXPLAIN for: SELECT "products".* FROM "products" WHERE (name ilike '%silk%')            
                                        QUERY PLAN                                                   
------------------------------------------------------------------------------------------           
 Bitmap Heap Scan on products  (cost=4.17..12.63 rows=4 width=152)                              
   Recheck Cond: ((name)::text ~~* '%silk%'::text)                                                   
   ->  Bitmap Index Scan on index_products_on_name  (cost=0.00..4.17 rows=4 width=0)            
         Index Cond: ((name)::text ~~* '%silk%'::text)                                               
(4 rows)                                                                                             
```
Bitmap Index ScanなのでIndex検索できてますね！

# 注意

簡単にできそうと紹介してましたが、pg_trgmで英数字以外をIndexするには

* [KEEPONLYALNUM オプションを OFF にしてモジュールをリビルドする](http://lets.postgresql.jp/documents/technical/text-processing/3#contains
)
* [lc_ctypeをC.UTF-8にしてinitdbする](http://www.clear-code.com/blog/2016/5/9.html)

のいずれかが必要です。
iOSアプリでTwitter認証させる際の注意点

Ionicを使ってAndroid/iOSのアプリを書く日々なわけですが、今年に入ってiOS版で異変が生じました。ちょっとしたバグフィックスをリリースしたのですが、Androidは即日Google Play Storeに公開されたのに、iOS版はRejectを食らったのです。

そのアプリはSubscription課金する関係上、認証をする必要があったのですが、いまさらこちら側でID/Password管理するなんて面倒くさくてやってられないのでTwitter認証で逃げていたわけですね。利用者が許可すればアプリの内容をTweetして宣伝してもらおうという狙いもあったわけですが。

で、突然iTunesにRejectされた際のお知らせがこちらになります。

> From Apple
5. 1.1 LEGAL: PRIVACY - DATA COLLECTION AND STORAGE

> We noticed that your app uses Twitter login for authentication purposes but does not include account-based features offered by that site.

> In order to use Twitter for authentication, your app must include significant account-specific functionality from Twitter.

「あんさんのアプリはTwitter認証しているけど、Twitter認証させる意味ってあんの？　Twitter認証してすげー嬉しい、みたいな機能がないとあかんで」

みたいなことを言っております。

これに対して私は「本人確認できるしー　あと、アプリの情報をシェアできるからいいんでねーの？　そもそも去年はRejectしてなかったじゃん」とiTunesの中の人に反論したのですが「あかん」と言われてRejectでした。

Androidは何も文句言わないのにね。うーん。

で、今回「逃げる方法」を発見しました。こちらのアプリを御覧ください。

* [The Best Kitten Photo (Google Play)](https://play.google.com/store/apps/details?id=com.msushi.thebestkittenphoto)

* [The Best Kitten Photo (iTunes)](https://itunes.apple.com/us/app/the-best-kitten-photo/id1203220721?mt=8)

このアプリは

1. 猫の写真をアップロードする
2. アップロードされた猫の写真が並んで表示されるのでどちらが可愛いか選ぶ
3. 可愛いとされた写真上位10を閲覧する

だけの簡単なフィーチャなのですが、

* 「1, 2, 3すべてをTwitter認証済ユーザに許可する」→却下
* 「1, 2をTwitter認証済ユーザに許可する」→却下
* 「1のみ、Twitter認証済ユーザに許可する」→承認！！

どうやらゲスト利用者にも多くの機能を開放しておき「ここだけはTwitter認証しないとダメよ」というくらいの制約にしておくのが良いようです。

[Appleのガイドライン](https://developer.apple.com/app-store/review/guidelines/#data-collection-and-storage)にも書かれてました。

> 5.1.1 Data Collection and Storage
> (ii) If your app doesn’t include significant account-based features, let people use it without a log-in. Apps may not require users to enter personal information to function, except when directly relevant to the core functionality of the app or required by law. If your core app functionality is not related to a specific social network (e.g. Facebook, WeChat, Weibo, Twitter, etc.), you must provide access without a login or via another mechanism. Pulling basic profile information, sharing to the social network, or inviting friends to use the app are not considered core app functionality.

ということで、今回承認されたアプリのように__Continue as a Guest__という選択肢を作っておくのが重要みたいですね。

Happy Coding! そんじゃーね
TableView + カスタム TableViewCell でフォームを作るときにセルのtextFieldの値を知るにはどうすりゃいいんだとちょっとなやんだ。

# やろうとしていること

iPhoneアプリでフォーム画面を作りたい。
ユーザの住所氏名を入力してもらい、NavigationControllerの「Done」を押すと内容を保存する。

* UITableView
    * 複数セクション
        * 氏名
        * 住所
        * 電話番号
        * ...
* UITableViewCell
    * ラベル
        * UILabel (`cell.textLabel?.text`)
    * テキストフィールド (UITextField)

# つまったこと

どうやって子供セルのテキストフィールドにある値を親のTableViewControllerに伝播するか

### 試そうとしたこと

* RxSwiftでリアルタイムで情報を更新できるようにする
    * RxSwiftよくわかんなくて挫折した
* セルのプロパティにindexPathをもたせてテキストフィールドの内容が更新されたら親にindexPathとテキストフィールドの値を教えるようにする
    * セルのindexPathをセル自体に持たせるのは（責務の関係上）よくない
* ライブラリを使う
    * [xmartlabs/XLForm](https://github.com/xmartlabs/XLForm) とか・・・

うーん

# TL; DR

「送信」が押された時に全てのテキストフィールドをなめに行く。

### 解決策

リアルタイムで更新できる必要がなければ、ユーザがDoneを押したタイミングや、そのビュー自体が消えるタイミングで最終的に全テキストフィールドの中身を総なめしていってその時の値セットで更新をかければ問題ない。
docker コンテナ + capybara-webkit でウェブサイトのスクリーンショットを撮影する

## 準備

Dockerfile 作成。

```
$ vi Dockerfile
```

内容はこんな感じ。

```
FROM ruby
RUN apt-get update && apt-get install -y libqt4-dev libqtwebkit-dev xvfb fonts-ipafont fonts-ipafont-gothic fonts-ipafont-mincho
RUN gem install capybara-webkit --no-ri --no-rdoc
ADD fonts.conf /etc/fonts/fonts.conf
ADD /capture.rb /capture.rb
ADD /capture.sh /capture.sh
RUN chmod +x /capture.sh
ENTRYPOINT ["/capture.sh"]
```

libqt4-dev と libqtwebkit-dev はヘッドレスブラウザを立ち上げるために必要なやつ。
xvfb はヘッドレスな X Window System サーバーを立ち上げるために必要なやつ。
ipafont, fonts-ipafont-gothic, fonts-ipafont-mincho はヘッドレスブラウザ上で日本語を含むサイトを正しく表示するために必要なやつ。
という感じっぽい。

次に、コンテナ内で実行させるスクリプトを作成する。
自作の Web サービス用に書いた処理からコピペしたもので、オプションとかは適当。

```
$ vi capture.rb
```

```ruby
require "capybara-webkit"

if ARGV.size < 2
  abort "Usage ruby capture.rb URL OUTPUT_PATH"
end

url, output_path = ARGV[0], ARGV[1]
driver = Capybara::Webkit::Driver.new('web_capture')
browser = driver.browser
browser.visit(url)
browser.window_resize(browser.get_window_handle, 500, 500)
browser.render(output_path, 500, 500)
```

`ruby capture.rb URL OUTPUT_PATH` のように実行すると URL を見にいってスクショを OUTPUT_PATH に保存するようにしている。

ラッパーのシェルスクリプトも作成しておく。今回も [docker で xvfb\-run しようとしたときに Xvfb failed to start というエラーが出てしまう現象の解決方法 \- Qiita](http://qiita.com/tily/items/9958f7e70b8d31cdff25) のワークアラウンドを入れた。
(実行するコマンドが長いのでこうしてるけど、ださいのでもっといい感じにしたかった…。)

```
$ vi capture.sh
```

```sh
#!/bin/sh
rm /tmp/.X99-lock || echo 'Lock not found, continuing normal setup' && xvfb-run ruby /capture.rb $@
```

あと、フォントにアンチエイリアスを効かせるために fonts.conf を用意する必要があるんだけど、長いので [prgrphs/fonts\.conf at f91624e3ea2c02eb3c85e5c1763f5d85ab23ebe2 · tily/prgrphs](https://github.com/tily/prgrphs/blob/f91624e3ea2c02eb3c85e5c1763f5d85ab23ebe2/fonts.conf) を参照してください。

```
$ vi fonts.conf
```

デフォルトの fonts.conf を編集して、`<fontconfig>` タグの直下に下記の設定を追加してる感じです。

```
<match target="font">
	<edit name="antialias" mode="assign">
		<bool>true</bool>
	</edit>
</match>
```

## 実行

まずはイメージをビルド。

```
$ docker build -t capture .
```

実行。

```
docker run -v $(pwd):/data/ -ti capture http://ja.wikipedia.org/ /data/test.png
rm: cannot remove '/tmp/.X99-lock': No such file or directory
Lock not found, continuing normal setup
[DEPRECATION] Capybara::Webkit::Driver#browser is deprecated.
WARNING: The next major version of capybara-webkit will require at least version 5.0 of Qt. You're using version 4.8.6.
Request to unknown URL: http://ja.wikipedia.org/
(略)
```

(略) の部分に capybara-webkit のワーニングが出まくるけど、スクショ自体はうまく撮影できた。

```
$ ls -l test.png 
-rw-r--r-- 1 root root 1319199  2月  9 02:36 test.png
$ file test.png 
test.png: PNG image data, 821 x 6364, 8-bit/color RGBA, non-interlaced
```

クラウド上のサーバーで作業していたので、Web サーバーを立ち上げて確認する。

```
$ python -m SimpleHTTPServer 3000
Serving HTTP on 0.0.0.0 port 3000 ...
```

`http://www.example.com:3000/test.png` で画像を表示して確認した。
縦長になってしまったのでだいぶトリムしたけどこんな感じのスクショがとれる。

![](https://i.gyazo.com/093557bf596df795388ecd93d5f06817.png)

## まとめ

docker コンテナ + capybara-webkit でウェブサイトのスクリーンショットを撮影することができた。フォントがまだいまいちな気がするので、他のフォントを入れてためしてみたいなー。
Rails5のtimezone設定は普通にapplication.rbでよかった

これまでアプリケーションで共通の設定は``config/application.rb``に記述していたが、Rails5からは

```ruby:config/application.rb
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
```

とあるように、``config/initializers/``以下に個別にファイル作ってそこで設定しようという方針になっているようだ。

そこで``config/initializers/time_zone.rb``というファイルを新規作成し

```ruby
Rails.application.config.time_zone = 'Tokyo'
```

としたが、``Time.zone``はUTCのままでViewでレンダリングされるcreated_atも変わらず。。

ググったところ以下の情報が見つかった。

http://rono23.com/posts/upgrading-to-rails-5/ 
>But you shouldn't assign some values such as time_zone in an initializer. Because  Rails.application.config.time_zone will work, but Time.zone won't. Time.zone_default is assgined before the initializer.

どうやら``initializers/*.rb``が走る前に``Time.zone_default``が初期化されているらしい。該当のソースコードは[こちら](https://github.com/rails/rails/blob/912ae0b34bf541f18d051c8a274a54aef91a5e04/activesupport/lib/active_support/railtie.rb#L25)

ということで結局Rails5以前と同じように``config/application.rb``に``config.time_zone = 'Tokyo'``を追記することでタイムゾーン設定を変更できた。
HttpClient 4.3 で CookieSpec をセットする


```java

RequestConfig ignoreCookiesRequestConfig = RequestConfig.custom()
		.setCookieSpec(CookieSpecs.IGNORE_COOKIES).build();

... // 略

	// HTTPClient の生成
	client = HttpClients.custom() //
			.setDefaultRequestConfig(ignoreCookiesRequestConfig) //
			.setDefaultCredentialsProvider(credentialsProvider) //
			.setConnectionManager(mgr) //
			.build(); //


```
Centos7でHerokuからgit cloneする方法

VirtualBox上のCentos7でHerokuからgit cloneしようと思ったときに少しハマったのでメモ。

## 最初にやったこと
普通に、

```
git clone https://○○○○/○○.git
```

とするとAuthenticateエラーがでた。

```
git clone https://username:password@○○○○/○○.git
```
としてもダメだった。
パスワードを思いつくのすべて試したり、アカウント設定からnameを変えてみたりしたけどダメだった

## 解決した
落ち着いてもう一回herokuを見ていると、そういえば heroku cliってのがあったのを思い出す。
以下インストール方法。
heroku cliのダウンロード（herokuに載っているのとは少し違い、linux-amd64用のを使う←ここでもハマった）

```
$ wget https://cli-assets.heroku.com/branches/stable/heroku-linux-amd64.tar.gz
```

以下は公式と同じ。手元の環境ではsudoを付けないと権限がないと言われた。

```
$ sudo mkdir -p /usr/local/lib /usr/local/bin
$ sudo tar -xvzf heroku-linux-amd64.tar.gz -C /usr/local/lib
$ sudo ln -s /usr/local/lib/heroku/bin/heroku /usr/local/bin/heroku
```

```
$ heroku login
$ heroku git:clone -a リポジトリ名
```
めでたくcloneできた。
対応ブラウザが気になるリスト

フロントエンド実装するときに
「あれ？これ今回使えるんだっけ？」ってなってしまうものたち
随時更新予定


## Web Audio API
☓ IE **~11** 
☓ Android 標準ブラウザ **4.3 - 4.4**
[Can I use… Support tables for HTML5, CSS3, etc](http://caniuse.com/#feat=audio-api)

## CSS3 Flexbox
☓ IE **~9** (10, 11はprefixつきで◯） 
[Can I use… Support tables for HTML5, CSS3, etc](http://caniuse.com/#feat=flexbox)

## CSS Filter Effects
```css
filter: drop-shadow(16px 16px 20px blue);
filter: brightness(0.4);
filter: sepia(60%);
```

☓ IE **~11** 
☓ Android 標準ブラウザ **4.3**
[Can I use… Support tables for HTML5, CSS3, etc](http://caniuse.com/#feat=css-filters)

## Fetch API
☓ IE **~11** 
☓ Safari **10.1以前** 
☓ iOS Safari **全てのバージョン** 
☓ Android 標準ブラウザ **- 4.4.4**
[Can I use… Support tables for HTML5, CSS3, etc](http://caniuse.com/#feat=fetch)

-> Polyfillで
Safari 6.1+, Internet Explorer 10+ は対応可
https://github.com/github/fetch
文系卒社会人が統計入門でのモヤモヤを克服した話

#統計入門のつまづき
文系卒のエンジニアである筆者が統計と機械学習を学ぼうとしましたが、まずは数式で躓きました。このあたりの内容は[「文系卒社会人が統計・機械学習を理解するための数学勉強方法」](http://qiita.com/FukuharaYohei/items/0a66c37091dc27c71fe6)にも記載しています。
今まで、簿記やERP、Webなどいろいろなことを学んできましたが、**ここまで内容が理解できずにもやもやしたのは初めて**で、がっかりすると同時にワクワクする自分もいました。

2年ほど勉強をして、統計学にフォーカスしたおすすめ勉強方法を[「文系卒社会人が統計入門する最短学習法」](https://qiita.com/FukuharaYohei/items/27d1ed76d770a19da323)に書きました。

#大雑把な流れ
つまづきとその克服の大雑把な流れです。
###1. 仕事でデータサイエンス系のデモシナリオを検討
 正直、たいしたデモシナリオを作れなかったです。それっぽくは仕上げましたが、私の理解度が足りないなので、自信を持って語れないし、応用も利きません・・・
業務分析にしろ、統計の業務への組込にしろ、今までやってきた仕事にないアプローチだったので大きな魅力と可能性を感じました。これを機にデータサイエンス系を学ぼうと決意しました。
###2. 機械学習を学ぶ
機械学習の入門本を何点か読みましたが、理解できない点が多くモヤモヤ:disappointed_relieved: 手法やポイントはある程度おさえたつもりですが、より基礎的な内容を勉強しようと決意。
###3. 統計入門を学ぶ
著名な通称「赤本」と呼ばれる[統計学入門 (基礎統計学) ](http://amzn.asia/cwsf0Cr)を読みましたが、**「入門」ですら理解度が低い**・・・**仕方なくさらに基礎から勉強**をすることに決めました。
###4. 高校数学を復習
高校数学をゼロから復習しました。復習は時間がかかる根気のいる学習でしたが、それなりの効果がありました(115時間かけました)。しかし、まだ統計入門への理解としては足りません。
復習内容は前記事[「文系卒社会人が統計・機械学習を理解するための数学勉強方法」](http://qiita.com/FukuharaYohei/items/0a66c37091dc27c71fe6)を参照ください。そして、長い高校数学復習を終えたときの気持ちは[高校数学復習を終えると統計学の入門ができるのか？](http://qiita.com/FukuharaYohei/items/8cb8915b310aa5763303)に書いています。
###5. 大学基礎数学を学習
大学基礎数学として、主に微分・積分を中心に学習しました。偏微分など高校で回帰分析で必要な内容も学び、**ようやく統計学を理解できた**と感じました!:star:
定着するほど勉強できていないのが現状ですが、**χ二乗検定や正規分布の公式が理解できたときには、感動しました**。
いずれ、この内容についてもう少し細かく書こうかと思います。
#今後
今は、統計学入門で理解した内容を支えに、R言語の勉強をしています。まだ、あまり進められていませんが、同じく始めようとしている方は以下の記事を参考にしてください。
[R言語インストール(2020年 Windows)](http://qiita.com/FukuharaYohei/items/8e0ddd0af11132031355)
[RStudioインストール(2020年 Windows)](http://qiita.com/FukuharaYohei/items/8e0ddd0af11132031355)
RedHatをVirtualBoxにインストールする

1. Register as RedHat 
2. Download ISO 3.7GB
1. Add subscription for your product https://access.redhat.com/management/
1. Install Redhat your Virtualbox
1. Set network as bridge mode on Virtualbox settings.
1. Set dynamic IP address with following command.

```bash
sudo dhclient -v
# Confirm connection
ping yahoo.com
```

1. Register your product to Redhat server

```bash
# Login with Redhat credential
subscription-manager register
# Get pool id
subscription-manager list --available
## Pool Id:                 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
subscription-manager subscribe --pool=xxxxxxxxxxxxxxxxxxxxxxxxxx

sudo yum update
```
2. Install redhat developer tool set
[Guide link](https://access.redhat.com/documentation/en-US/Red_Hat_Developer_Toolset/3/html/User_Guide/sect-Red_Hat_Developer_Toolset-Install.html)
1. Install other developer library

```bash
sudo yum install kernel-devel
sudo yum install gcc 
sudo yum install -y git-core zlib zlib-devel gcc-c++ patch readline readline-devel libyaml-devel libffi-devel openssl-devel make bzip2 autoconf automake libtool bison curl sqlite-devel
sudo yum install vsftpd
sudo yum install git
sudo yum install vim
sudo yum install postgresql-server
sudo yum install postgresql-libs
sudo yum install postgresql-devel

```

1.Install lsb, postgresql

```bash
sudo yum install lsb
```
Vagrant+VirtualBoxで作成した仮想マシンにPHPライブラリテスト用環境を構築する【1】

Vagrant+VirtualBoxで作成した仮想マシンにPHPライブラリテスト用環境を構築する【1】 ←イマココ
[Vagrant+VirtualBoxで作成した仮想マシンにPHPライブラリテスト用環境を構築する【2】](http://qiita.com/ss_watanabe/items/6b79dfc0362eb5c5c44b)
[Vagrant+VirtualBoxで作成した仮想マシンにPHPライブラリテスト用環境を構築する【3】](http://qiita.com/ss_watanabe/items/22c406b84783e2ac2d14)
[Vagrant+VirtualBoxで構築した仮想マシンをBox化して復元する](http://qiita.com/ss_watanabe/items/d15f890af58fa16447f6)

# はじめに
PHPの色々なライブラリが入ったプロジェクトのテストを本番に近い環境で行いたい。
なのでVagrant+VirtualBoxで作成した仮想マシンにPHPライブラリテスト用環境を構築する。

# 実施環境
| 項目 | 詳細 |
|:-:|:-:|
| MacOS  | Sierra  |
| Vagrant | 1.9.1  |
| VirtualBox  | 5.1.14  |

# 目標仮想マシン環境
LAMP

| 項目 | 詳細 |
|:-:|:-:|
|Linux  | CentOS6.6  |
| Apache | 2.4.6  |
| MySQL | 5.7  |
| PHP  |  5.6 |
| FW  | Codeigniter3  |

今回テストしたいライブラリはImage_Barcode2

# 事前準備
以下をインストールする。

- [Vagrant](https://www.vagrantup.com/downloads.html)
- [VirtualBox](http://www.oracle.com/technetwork/server-storage/virtualbox/downloads/index.html?ssSourceSiteId=otnjp)

# 仮想マシンの準備

## Boxの取得
Boxとは仮想マシンのテンプレート。
以下のコマンドで取得できる。

```
$ vagrant box add {title} {url}
```

[Vagrantbox.es](http://www.vagrantbox.es/)より目的にあったイメージを選択し、Boxを取得する。
今回は「CentOS 6.6 x64」のBoxを取得するので以下のようになる。（titleはなんでもいい）

```
$ vagrant box add CentOS6 https://github.com/tommy-muehle/puppet-vagrant-boxes/releases/download/1.0.0/centos-6.6-x86_64.box
```

完了後、以下のコマンドで取得できているか確認ができる。

```
$ vagrant box list
CentOS6     (virtualbox, 0)
```
入ってる入ってる。

**【追記】**
現在はVagrantが公式でBoxを用意してくれているようなので、以下の記事を参考した方がいい！
[Vagrantの正しいはじめ方](http://qiita.com/alfa/items/dd9e704ebc86b957b174)

## 仮想マシンの初期化
仮想マシンごとにディレクトリが必要なので、作成して移動。

```
$ mkdir libTestCentOSVM
$ cd libTestCentOSVM
```

初期化

```
libTestCentOSVM $ vagrant init CentOS6
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.
```
成功したら、Vagrantfileが作成される。

```
libTestCentOSVM $ ls
Vagrantfile
```

## 仮想マシンの起動

```
libTestCentOSVM $vagrant up
```
完了すると、VirtualBox上でも起動を確認できる。
<img width="882" alt="スクリーンショット 2017-02-09 10.58.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/147005/f822ff4a-1ac2-a9ab-d23e-b75c77e66820.png">

※停止･再起動･削除などはググってください。

## 仮想マシンに接続

```
libTestCentOSVM $vagrant ssh
Last login: Thu Jul 16 08:48:31 2015 from 10.0.2.2
Welcome to your Vagrant-built virtual machine.
[vagrant@localhost ~]$ 

```
できましたー:beers:

<br><br><br>Vagrantの設定はこれで終わりー:neutral_face:
次はサーバー側の環境構築
長くなるので別記事へ続く！！
[Vagrant+VirtualBoxで作成した仮想マシンにPHPライブラリテスト用環境を構築する【2】](http://qiita.com/ss_watanabe/items/6b79dfc0362eb5c5c44b)
linux shellのよく使う物をまとめたコピペ元

#linux shellのよく使う物をまとめたコピペ元
自分がよく使うしょっちゅう使う決まり文句をまとめてみた

##日付取得
```lang:
today=`date "+%Y%m%d"`
yesterday=`date --date "-1 day" "+%Y%m%d"`
```

##ファイル：ディレクトリ存在チェック＋容量までみるパターン
ファイル存在チェック

```lang:
if [ ! -f ファイルのパス ]; then
  echo "ファイル作成失敗" | mail -s "失敗" メールアドレス
  return 2
fi
```

ディレクトリ存在チェック

```lang:
if [ ! -d フォルダのパス ]; then
  echo "ディレクトリ作成失敗" | mail -s "失敗" メールアドレス
  return 2
fi
```

容量までチェック。tarなど失敗しても小さなファイルを作ってしまうので。

```lang:
if [ $? -ne 0 ] || [ `ls -l ファイル | awk '{print $5}'` -lt 1000 ]; then
  echo "失敗" | mail -s "【garoon_backup.sh】失敗" メールアドレス
  return 3
fi
```

##前のコマンドが成功したか

```lang:
if [ $? -ne 0 ]; then
  echo "処理失敗" | mail -s "失敗" メールアドレス
fi
```
##sshで他サーバーのシェルを起動

秘密鍵をヒアドキュメントで記載するパターン

```lang:
cat <<EOF > $RSA_KEY_FILE
-----BEGIN RSA PRIVATE KEY-----
秘密鍵
-----END RSA PRIVATE KEY-----
EOF

ssh -i $RSA_KEY_FILE -p ポート -l ユーザ  ホスト名 コマンド >> ログファイル 2>&1
```
※コマンドは下記を使用すれば特定の物に絞ることもできる。
その場合はコマンドを記載しなくてもよい。セキュリティを高めたい場合はそちらを使用。
http://qiita.com/kite_999/items/8f986e77bb17a391d09b

##ファイル暗号化
バックアップファイルなどを他サーバーに置く場合には万が一の為暗号化しておいた方がいいだろう。

```lang:
openssl enc -e -aes-256-cbc -salt -k パスワード -in 対象ファイル -out 吐き出し先
```

こんなのも可能

```lang:
tar cz -C /home hoge | openssl enc -e -aes-256-cbc -salt -k パスワード -out 吐き出し先
```

##sftpでのファイル転送
ヒアドキュメントを使ったファイル転送

```lang:
sftp -oPort=ポート -oIdentityFile=パスでもヒアドキュメントでも ユーザ@ホスト << EOF
cd /db
put ファイルアップロードしたいローカルの元パス
cd /web
get ファイル名 保存したいローカルのパス
quit
EOF
```
##SQLの実行
Postgresqlのsql実行と結果の取得

```lang:
DATE_TIME=`date --date '10 day ago' +%Y/%m/%d`
psql --no-align --tuples-only --username=hoge --dbname=hogehoge > tmpファイル <<EOF
select count(*) from hoge  where time > '$DATE_TIME';
EOF

TMP_COUNT=`cat tmpファイル`

if [ "0" -lt "$TMP_COUNT" ]; then
```
原始人でもわかるGit入門

# まえがき
私が新人類になった（と思う）ので原始人だったあの頃の私に向けて

#わたしはサルじゃない
サルでもわかるGit入門
http://www.backlog.jp/git-guide/
非常にわかりやすい作り。（ヌーラボ様いつもお世話になっております。この場を借りて謝辞）
ただし、私はサルじゃない＝SVNは利用したことがある=原始人

# GitとSVN
##違うことと違わないこと
どちらもバージョン管理ツール

違いはただ一つ**文化が違う**

ざっくり表にしてみる

| tool | 主構成 |   振る舞い  |マージ|たいせつにしたいもの|
|:----:|:-----:|:-----------:|:---:|:------:|
|SVN   |trunk  |ソースロック  |ファイル|ファイル履歴|
|Git   |branch |コードレビュー|すべて|分岐&統合の履歴|

## 主構成
SVNはtrunkが絶対である、厳密な運用をしているプロジェクトであれば結合テストが通らなければコミットすらできないというコード運用をしている。
Gitはすべてbranchである。trunkなんてものはなく、branchをどんどん統合&分岐を繰り返してうねうねと運用していく

## 振る舞い
### どんなプロジェクトでも簡単に侵しては行けない領域と言うものが存在する。ではそれをどうやって運用するか
SVNはソースをロックすることで明示的に誰も触れなくしてしまう。
Gitは基本的にコミットは可能だ、だがコードレビューが利用できる。だれにも触ってほしくなければすべてのコードレビューでNOと言えるようになろう。

## マージ
マージを実施すると
SVNではマージとはマージ先のファイルの更新である。マージ元に至っては何も影響がない。
Gitではすべてがマージされる。マージ元とマージ先は同じリビジョンになる

## たいせつにしたいもの
SVNではファイルの履歴がすべて。
Gitではブランチ&マージの履歴がすべて。

# 参考サイト
SVN Tutorial
http://www.tutorialspoint.com/svn/
サルでもわかるGit入門
http://www.backlog.jp/git-guide/
SVN脳患者から見たGit
http://qiita.com/kaityo256/items/81e7951a1ca2706955a4
SVNからGitに移行して分かった、今すぐSVNを捨てるべき3つの理由
http://catcher-in-the-tech.net/806/

# あとがき
Gitの次はなんだろうと思った。AWSに代表されてる強固な堅牢性とほぼ無限なデータ容量の波はずっと続くだろう、となると既存のファイルシステムとGitが統合していくような気がする。もしかしたら境目はなくなってしまうかもしれない。となると分散型は再度失われて、集中管理型のVCSとローカルで強力なファイルシステムで構成される次世代のVCSができるのかもしれない。
Node.jsからjenkinsAPIを実行する（jenkins-api）

# 概要
Node.jsからjenkinsのREST APIを叩く。今回は **[jenkins-api](https://github.com/jansepar/node-jenkins-api)** を使用。


## <i class="fa fa-pencil-square-o" aria-hidden="true"></i>  初期化

```js
var jenkins = jenkinsapi.init("http://user:token@url/");
```

## <i class="fa fa-pencil-square-o" aria-hidden="true"></i> job実行

```js
var jobName = 'testjob';

jenkins.build(jobName, function(err, data) {
  if (err){ return console.log(err); }
  console.log(data)
});
```

## <i class="fa fa-pencil-square-o" aria-hidden="true"></i> job名が日本語の場合はエスケープ
job名が日本語の場合、`encodeURIComponent`を通す。
そもそも日本語のjob名はよろしくないのでASCIIで統一しましょう。

```js
var jobNameJapanese = 'テスト job02';

jenkins.build(encodeURIComponent(jobNameJapanese), function(err, data) {
  if (err){ return console.log(err); }
  console.log(data);
});
```


## <i class="fa fa-pencil-square-o" aria-hidden="true"></i> パラメータの指定方法
実際にjenkinsにてジョブ作成などを行った経験がない場合、どれをkey-valueに設定するかがわかりづらい気がする。


「job名」 > 「設定」

![jenkinsapi_001.jpg](https://qiita-image-store.s3.amazonaws.com/0/103753/21f25b6b-4c9f-cd8a-022e-e643d697a070.jpeg)


パラメータ指定
![jenkinsapi_002.jpg](https://qiita-image-store.s3.amazonaws.com/0/103753/54946cf3-d5f6-c8d5-abec-365f8cf0988e.jpeg)


上図の場合だと実装は以下のようになる。keyは文字列指定ではないので注意。

```js
jenkins.build('JOB_BUILD_SERVER', {server: 'server01'}, function(err, data) {
  if (err){ return console.log(err); }
  console.log(data);
});
```

## <i class="fa fa-pencil-square-o" aria-hidden="true"></i> 参考

[GitHub] - jenkins-api
https://github.com/jansepar/node-jenkins-api
Botkitのインストールと、任意のコマンドを実行例

## nodejs v6.x のインストール

ubuntu 16.04 標準リポジトリでは nodejs v4が配布されている。
しかし現在のLTSはv6のようなのでv6を選択した。

* [Installing Node.js via package manager | Node.js](https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions)

```
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
sudo apt-get install -y nodejs
```

```
$ nodejs -v
v6.9.5
```

```bash:npmのアップデート
sudo npm update -g npm
```

## botkitのインストール

```
mkdir ~/slackbot && cd ~/slackbot
npm init -y
npm install botkit --save
```

## 使い方

```bash:~/slackbot/run.sh
export token=xxxxxxxxx
node index.js
```

* `sh run.sh`

```bash:slackからbotへダイレクトメッセージ
sh df -h | grep G
sh ip a s | grep glo
sh sudo whoami
exit
```

* sudoは以下必要

```bash:/etc/sudoers
user1    ALL=(ALL:ALL) NOPASSWD:ALL
```

## 任意のコマンドを実行

* 命令を受け付けるユーザーを制限しているので、

`var allow_user = "ユーザ名";`を修正してください。

```javascript:~/slackbot/index.js
const Botkit = require('botkit');

if (!process.env.token) {
  console.log('Error: Specify token in environment');
  process.exit(1);
}

const controller = Botkit.slackbot({
    debug: false
});

controller.spawn({
    token: process.env.token
}).startRTM(function(err){
    if (err) {
        throw new Error(err);
    }
});

// 実行可能ユーザーの制限
function is_allow_user(bot,message) {
    var allow_user = "ユーザ名";
    bot.api.users.info({user:message.user},function(error,response){
        if(response.user.name != allow_user){
            return false;
        }
    });
    return true;
}

// コマンド実行
controller.hears('sh (.*)',['direct_message'],function(bot,message) {

    if(!is_allow_user(bot,message)) {
        bot.reply(message,'your access denied.');
        return false;
    }

    var matches = message.text.match(/^sh (.*)/);
    var command = matches[1];

    const execSync = require('child_process').execSync;
    try {
        const result =  execSync(command).toString();
        bot.reply(message,result);
    } catch(error) {
        bot.reply(message,error.toString());
    }
});

// exit で終了
controller.hears('exit',['direct_message'],function(bot,message) {
    process.exit(0);
});
```
MacBook(2015〜)、MacBook Pro(2016〜)で充電開始音を消す

## こんなことありませんか？
MacBook(Pro)を充電開始したら、スピーカーからiOSの充電開始と同じ音が出た！

↑いらない

よって消します。

## 充電開始音を消したいときに打つコマンド
```defaults write com.apple.PowerChime ChimeOnAllHardware -bool false; killall PowerChime```

## もし充電開始音を復活させたくなったら打つコマンド
```defaults write com.apple.PowerChime ChimeOnAllHardware -bool true; open /System/Library/CoreServices/PowerChime.app & ```

## 参考
[Macで充電開始の合図のサウンドを出す方法](http://ryomac.blog.fc2.com/blog-entry-104.html)