OmniAICreator/Qiita-1.07M huggingface dataset:
Edisonでmraaを違うディレクトリに入れたい

Sparkfunのチュートリアル通りにubilinuxを入れたIntel Edisonにmraaを入れていたところつまずいたのでメモ．

https://learn.sparkfun.com/tutorials/installing-libmraa-on-ubilinux-for-edison

#起こったこと 1
Export Library Path for Pythonに示されているexportの文を.bashrcに書いて読み込んだらなんだか怒られた．

```bash:.bashrc
#いろいろな中身
export PYTHONPATH=$PYTHONPATH:$(dirname $(find /usr/local -name mraa.py))
```

怒られた内容としてはこんな感じ

```
$ source .bashrc
dirname: extra operand `/usr/local/lib/python2.7/site-packages/mraa.py'
Try `dirname --help' for more information.
```

#応急処置

よくわからないけどdirnameのoperandがextraらしい．とりあえずdirnameに渡している値を確認してみる．

```
$ find /usr/local -name mraa.py
/usr/local/lib/i386-linux-gnu/python2.7/site-packages/mraa.py
/usr/local/lib/python2.7/site-packages/mraa.py
```

なんかmraa.pyが２ついるっぽい！
どっちを使えばいいのかよくわからないけれど，とりあえずふたつ目のほうが一般的っぽいディレクトリにいるのでこちらを.bashrcに直打ちしておく．．．！

```bash:.bashrc
#いろいろな中身
export PYTHONPATH=$PYTHONPATH:/usr/local/lib/python2.7/site-packages/mraa.py
```

そしてもう一度読み込み．今度はうまく行ったけどいいのかなぁ．

```
$ source .bashrc
```


(そういえばpythonのインストールディレクトリを~/.local以下に設定した気がするけどmraaはここにいていいのだろうか・・・！参考にしたのは[この記事](http://qiita.com/yoneken/items/dda4fdbb9f415a0db3e9))


#応急処置ではmraaが読めない
そらきたpythonからmraaが読めていない．

```
Python 2.7.3 (default, Mar 14 2014, 11:57:14)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mraa
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named mraa
```

やはり~/.local以下へ入れないといけない気がする.

#~/.local以下へのmraaの入れなおし

ただ，入れてしまったmraaはmake uninstallしてもそんなのないって言って消えてくれない．
インストールした時の表示を見てちまちまと消していく．．消したのは下記のとおり．

/usr/local/include/mraa.h
/usr/local/include/mraa.hpp
/usr/local/include/mraa
/usr/local/lib/i386-linux-gnu/pkgconfig/mraa.pc
/usr/local/lib/i386-linux-gnu/libmraa.so.0.8.1
/usr/local/lib/i386-linux-gnu/libmraa.so.0
/usr/local/lib/python2.7/site-packages/_mraa.so
/usr/local/lib/python2.7/site-packages/mraa.py
/usr/local/share/mraa

で．これが~/.local/以下に展開されるようにしたい．
調べてみると，cmakeの引数でこの辺り指定できたりするらしい．build/以下を消してもう一度cmakeやり直し．

```
$ rm -r build
$ mkdir build && cd $_
$ cmake .. -DBUILDSWIGNODE=OFF -DCMAKE_INSTALL_PREFIX=$HOME/.local
```

あとはmake, make installしたところ，さっきのファイルたちがうまいこと~/.local/以下に展開された．
たとえば /usr/local/include/mraa.h -> ~/.local/include/mraa.h

あとは，もともとPYTHONPATHに入れていたディレクトリなので.bashrcに書き加えたexportの一文を削除．

インタプリタで確認すると，ちゃんとインポートできる．

```
$ python
Python 2.7.3 (default, Mar 14 2014, 11:57:14)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mraa
>>> 
```

めでたしめでたし．
Hubot環境構築ログ

#環境
アルバイト先ThinkPadのVM上Ubuntu 15.04
#参考
Hubot のインストール
http://qiita.com/bouzuya/items/11c0c6da2b3ad54b827f
#ログ

##Hubot編

`sudo npm install -g yo generator-hubot`
`npm`がないと怒られる

`sudo apt-get install npm
sudo npm install -g yo generator-hubot`
`node`がないみたいな感じで怒られる。

`sudo update-alternatives --install /usr/bin/node node /usr/bin/nodejs 10
sudo npm -g yo generator-hubot`
無事通ったぽい。
`
mkdir hubot
cd hubot
sudo yo hubot`
で進めていくと大量にエラーをはかれた。
ゲストからホストのディレクトリにアクセスしていろいろやってたけど空じゃないディレクトリを削除できないとかで怒られた。
ゲストのホームディレクトリで実行すると`.npm`ディレクトリに`mkdir`できないとかなんとかで怒られる。
`chmod`で権限あげると通ったぽい。

`./bin/hubot -a shell -n manabukk`

##Heroku編
- Slack Teamの管理者権限
- Herokuアカウント
- Heroku toolbeltのインストール

が必要。
今回はUbuntuなので
`wget -O- https://toolbelt.heroku.com/install-ubuntu.sh | sh`
でインストール
`パッケージ heroku-toolbelt がみつかりません`と言われる。
E: GPG エラー: http://toolbelt.heroku.com ./ InRelease: クリアサインされたファイルが有効ではなく、'NODATA' を得ました (認証にネットワークが必要?)

`sudo apt-get update`すら`E: GPG エラー: http://toolbelt.heroku.com ./ InRelease: クリアサインされたファイルが有効ではなく、'NODATA' を得ました (認証にネットワークが必要?)`ってエラーが出るようになった。

###解決方法
heroku toolbeltがインストールできない gpgエラー
http://qiita.com/nakayama_yasuhiro/items/94b8c80b4d1b2c089fd7

/etc/apt/sources.list.d/heroku.listのhttpをhttpsに変更する。
→無事解決。
→と思いきやapt-getは通るがherokuが相変わらず無いと言われる。
→`wget -O- https://toolbelt.heroku.com/install-ubuntu.sh | sh`をもう一度実行
→同様のエラーは出るがなんか通る。
→apt-getが通らなくなったからまたhttpをhttpsに変えておく
→解決（？）

#Herokuにデプロイ

`
git init
git add -A
git commit -m "intial commit"
heroku create
git push heroku master
`

#Slackでintegration

SlackでHubotをadd integrationする

Hubot側でも
`
heroku config:set \
\> HUBOT_SLACK_TOKEN=go7CWIlD19muTtqBflqnw3Mk \
\> HUBOT_SLACK_TEAM=bouzuya \
\> HUBOT_SLACK_BOTNAME=uran
`

ってな感じで設定する。

slackで話しかけると無事反応してくれた。
11/24

次回
第２回　Heroku上でHubotを動かす
http://qiita.com/manabukk/items/158a2dd00ffc36bf5b98
GitをWindowsにインストールしたら動かない

Gitをインストールしてみたところ、入門サイトの通り設定しても動かなかったので、共有。

AWSのlambda(python)をローカルで動かそうとしたところ、「pip -install」が動かず。なんでだ？と思っていました。

原因は、「パスの日本語が文字化けしているから」でした。

私の場合、ユーザ名が日本語であったため、インストールが全般的に動かなくなっていました。

解決は開発用のユーザを別途作成しました。

今思えば自宅用のPCだからと言って、初めてoutlook認証にしたときに間違えて日本語にしてしまったままにしていたことがいけなかった。。
Python,OpenCVのカメラキャプチャ

基礎的なことであるが忘備録として

#使用環境
Mac OSX El Capitan
OpenCV3.0.0
Python2.7.10

変更予定


#capture.py

    import numpy as np
    import cv2

    # カメラ指定
    cap = cv2.VideoCapture(0)

    while(True):
    
    # Capture frame-by-frame
    ret, frame = cap.read()
    
    # Our operations on the frame come here
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
    # Display the resulting frame
    cv2.imshow('frame',rad)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

    # When everything done, release the capture
    cap.release()
    cv2.destroyAllWindows()
line monitor > 情報表示部分 (151124) > LEDの点滅処理 / 電流値の計算

```txt:動作確認
Raspberry Pi2
7セグメントLED : C-361SR
抵抗 : 1.1kΩ
```

7セグメントLEDの表示処理をさせるため、GPIOの動作を学ぶ。

[C-361SRのデータシートPDF](https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwja--e1hqnJAhUnW6YKHfrgBK0QFggeMAA&url=http%3A%2F%2Fwww.para.com.tw%2Fuploads%2Fpdf%2FC-361SR%2520BR.pdf&usg=AFQjCNHOy93J7ypbU3jTesUPSD2q9r0mqQ&sig2=S52ZQoid-r9eehkirKih7g&bvm=bv.108194040,d.dGY)


参考になったのは以下のページ。
http://make.bcde.jp/category/5/

上記ページの`$ sudo apt-get install python-rpi.gpio`は使用しているraspbianにおいては`python-rpi.gpio is already the newest version.`で不要であった。

実行したプログラムは以下。

```151124a.py
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BOARD)
GPIO.setup(3, GPIO.OUT) # GPIO02
while True:
    GPIO.output(3, True)
    time.sleep(3)
    GPIO.output(3, False)
    time.sleep(3)
```

[RPi2 GPIO @ element14](http://www.element14.com/community/docs/DOC-73950/l/raspberry-pi-2-model-b-gpio-40-pin-block-pinout)にあるGPIOの番号を参考に、Pin#03をON/OFFさせた。

RPi2のPin#03(赤線)からブレッドボードへ接続し、同じ列に7セグメントLEDの8番目を接続した。
また、7セグメントのコモンからリード線を出してなかったので、ピン延長ケーブル(黒線)をRPi2のPin#39に挿して、反対を写真のように接触させた状態で確認した。

プログラム通り3秒ごとにON, OFFをする動作を確認できた。

![DSC_0003.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/db35e842-70c1-2af0-66cb-8b9ba3a4ba63.jpeg)

## 電流計算

LEDの電流を計算してみる。

- C-361SRのデータシートより VF : TYP 1.8V
- 今回の使用抵抗は1.1kΩ。
- RPi2のGPIOは3.3Vらしい。

(3.3V - 1.5V) / 1.1kΩ = 1.36mA.

この電流値とデータシートのどの値を見比べるのがいいのかいまいち理解していない。

IAF(Continuous Forward Current)は30mA. 連続点灯の場合は30mA以下にしなさい、ということなのか？
FORMエレメント以外でfocusイベントを発生させる方法

例えば`<div>`でfocusイベントを発生させたい場合。
これやりたくて先日小一時間悩んだ。
解は簡単で、`tabindex`属性をつければOK。`<div tabindex="0">`みたいに。そうすればそのエレメントで`focus`,`blur`イベントが発生するようになる。

`tabindex`属性はグローバル属性なので、すべてのエレメントにつけることができる。

以上
MySQLのint(?)の?の意味

勘違いしてたというか、よくわかってなかったのでメモしておく.

一言でいうと、?は表示できる文字(数字)列幅のこと.
?の数字に関係なくintなら4バイトの数値型なので、int(4)だろうと、int(11)だろうと、
-2147483648(Min) ~ 2147483647(Max)の間の数であることに変わりはない.

thanks:
http://blog.clouder.jp/blog/2005/04/26/mysqlint1111/
WebStorageについて調べたよ

# WebStorage？

- HTML5で使えるブラウザのローカル(オフライン)でつかえるKVS(5MB)。
- IE8以降、iOS5以降、Android3以降 で使用可能。
- ただし、Safariのプライベートモード時は使えない。

# WebStorageの種類は2つ

#### localStorage
- ブラウザを閉じてもずっと残り続ける(そのかわり同じオリジン間でしか使えない)

#### sessionStorage
- ブラウザを閉じるまで使える,異なるタブだと別々の* sessionStorageになる

# WebStorageを使う

- Storageのイベントを使うとタブ間でイベントを共有できる。
- 例えば、あるタブでStorageが変更されると、他のタブで同じページを開いているとそれを検知して変更される。
- JSONオブジェクトを保存したいときはJSON.stringify(obj)をつかってJSONオブジェクトを文字列化する。
- 反対に取り出すときはJSON.parse(localStorage.getItem("hoge"))lとやると良い。
JSONってJavaScriptと何が違うのん？


「JSONってJavaScriptの連想配列か何かでしょ？」と思っていたそこのあなた！(はい、私です。。)
JSONを扱うときに気をつけたいことについてまとめてみます。

- JavaScriptでは文字列リテラルを書くのは''でも""でもいいが、JSONでは""のみ
- JSONではプロパティ名にも""が必須になっている
- JavaScriptにはNaNやundefinedなどの値が存在するが、JSONには存在しない
- JSONではコメントが使えない
    - cf. http://qiita.com/guimihanui/items/f9a10edf2315be0a2a64
    - コメント的なものを書くHackもある
    - http://libitte.hatenablog.jp/entry/20141129/1417254311
- JSONでは;を挟んではいけない
Cookieについて実はよく知らなかったので調べた

いんたーねっつを使い始めた中学生の頃からよく聞く"Cookie"という仕組み。
「パソコン側にデータを持っておく仕組みでしょ？」程度しか理解していなかったので、ちょっと整理してみました。

# Cookieとは？
- クライアント側に一時的にデータを持たせておくことができる仕組み。
- ユーザーに関する情報、訪れた日時、訪問回数などを記録しておける。
- 1つのCookieには4KBのデータが記録でき、最大で300個のCookieを保存できる。
- ただし、1つのサーバ(ドメイン)につき20個までにしか発行することができない。

# よく聞く"Cookie盗まれた！"っていうのは？

Cookieは盗難されるとなりすましが出来るようになってしまう。
対策として
- secure属性：HTTPS時のみクッキーを送信する
- expire属性：Cookieの有効期限を指定する
- domain属性,path属性：CookieのアクセスできるWebサイトを制限する
が挙げられる。
JSONPのことをよく知らなかったので調べてみた

JSをいじってるとよく出てくるキーワード "JSONP"
JSONとの違いなどについてまとめてみました。

```
JSON: {'blog': 'ほげぶろぐ', 'author' : 'sseze'}
JSONP: callback({"blog": "ほげぶろぐ", "author" : "sseze"});
```

# なにが違う？
- JSONはテキストデータ、JSONPはscript
- クロスドメインでJSONを読み込む時は、JSONではなくJSONPが使われる(WebAPI等)
  - JSONではクロスドメインの壁を越えられない(XMLHttpRequestメソッドの制約)
  - scriptタグsrc属性を使うとデータが取得できる(ここでJSONPが使われる)

# セキュリティ制約
- CSRFに気をつけろ！
- scriptタグを使う方法はsame-origin-policyが適用されない
- 機密情報、個人情報をJSONPのデータに含めないこと
- JSONPはある意味、JavaScriptの仕様の穴を突いているような仕様と言える
- JSONPを利用することは、そのAPIの提供元にJavaScriptの実行権限を与えることに等しい
- 信用できないサービスのJSONP APIは利用しないようにすること
- JSONPの結果を安易にHTMLとして解釈するとXSSのリスクがある


### 参考：
* http://tadtak.jugem.jp/?eid=58
* http://tsujimotter.info/2013/01/03/jsonp/
* http://ja.wikipedia.org/wiki/JSONP
* http://gihyo.jp/dev/serial/01/crossbrowser-javascript/0011
Hive関数のPARSEとかCONCATのことをよく知らなかったので調べた

CONCATはSQLで文字列を連結させる関数なので、例えば

```sql
PARSE(CONCAT('http://mixi.jp', url), 'PATH')
```

みたいのがあったら `CONCAT('http://mixi.jp', url)` は `http://mixi.jp/home.pl` とかそういうのが入っているってこと。(この場合 `url` には `/home.pl` が入っている。)

urlはリクエストURIというのが入っているらしく、/home.plみたいの以外にも `/view_bbs.pl?id=XXXXXX&comm_id=XXXXXX` みたいなquery stringがくっついたのも一緒に入っていることもある。
ここからパスだけを抜き出したい、クエリだけを抜き出したいという場合にPARSE関数を使う。例えば、直上のquery stringを含んだリクエストURIがurlに入っている場合、パスを取り出すなら↑のようなHiveクエリを書けばいいし、クエリを取り出したいのであれば

```sql
PARSE(CONCAT('http://mixi.jp', url), 'QUERY', 'id')
```

と書けばidの値(XXXXXX)が取得できる。
Could not resolve host などと表示された時の解決方法

MacのVagrantにあるCentOSで開発をしていたところ謎のエラーがでて困りました。

# AWSのSDKが動かない
AWSのクラスは読み込めているのにPutObjectがないと言われます。

```
Error executing "PutObject" on "https://s3-ap-northeast-1.amazonaws.com/pugiemonn/pugi-wapu.png"; AWS HTTP error: cURL error 6: Could not resolve host: s3-ap-northeast-1.amazonaws.com; Unknown error (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)
```
awsのsdkがオカシイのかな？と考えました。

# composer update しようとして失敗
SDKがおかしいのかなと考え、composer updateをしようとしたところうまく動きませんでした。

```
[Composer\Downloader\TransportException]                                                                                                         
 The "https://packagist.org/packages.json" file could not be downloaded: php_network_getaddresses: getaddrinfo failed: Name or service not known  
 failed to open stream: php_network_getaddresses: getaddrinfo failed: Name or service not known
```
だめです＼(^o^)／
composerも失敗しました。

つまり、SDKは存在しているがAWSへのアクセスで失敗しているということみたいです。

# 結論
MacのDHCPがおかしかったみたいです。

Wifiを切るを選択して再度繋ぎ直したところ動くようになりました(☝ ՞ਊ ՞)
[Unity]マウスによる球体座標のカメラ移動


- モデル見たり、TPSなゲームを作るのにマウスを使った球体軌道なカメラがあると便利なんだけど、よく作り方を忘れるのでスクリプトごとここに張り付けておく。
- 球体座標でググれば理論とか出てくるので本当にスクリプトだけ張ります。

- 使い方は簡単で、Cameraにこのスクリプトを入れて、targetに注視したいオブジェクトをドラックアンドドロップ。もし何も入ってなかったら"Player"タグを自動で探して入れます。

```CameraController.cs
using UnityEngine;
using System.Collections;

public class CameraController : MonoBehaviour {
    [SerializeField]Transform target;
    [SerializeField]float spinSpeed = 1.0f;

    Vector3 nowPos;
    Vector3 pos = Vector3.zero;
    Vector2 mouse = Vector2.zero;
    // Use this for initialization
    void Start () {
        // Canera get Start Position from Player
        nowPos = transform.position;

        if(target == null)
        {
            target = GameObject.FindWithTag("Player").transform;
            Debug.Log("player didn't setting. Auto search 'Player' tag.");
        }

        mouse.y = 0.5f; // start mouse y pos ,0.5f is half
	}
	
	// Update is called once per frame
	void Update () {

        // Get MouseMove
        mouse += new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y")) * Time.deltaTime * spinSpeed;
        // Clamp mouseY move
        mouse.y = Mathf.Clamp(mouse.y, -0.3f + 0.5f, 0.3f + 0.5f);

        // sphere coordinates
        pos.x = Mathf.Sin(mouse.y * Mathf.PI) * Mathf.Cos(mouse.x * Mathf.PI) ;
        pos.y = Mathf.Cos(mouse.y * Mathf.PI) ;
        pos.z = Mathf.Sin(mouse.y * Mathf.PI) * Mathf.Sin(mouse.x * Mathf.PI) ;
        // r and upper
        pos *= nowPos.z;
        
        pos.y += nowPos.y;
        //pos.x += nowPos.x; // if u need a formula,pls remove comment tag.

        transform.position = pos + target.position;
        transform.LookAt(target.position);
    }
}

```
完全にフリーなので自由に使ってください。
MySQLについて復習してみたまとめ

# ストレージエンジン

## ストレージエンジンとは？
  - プランナ、オプティマイザ
    - SQL文のパースが終わった後、次にデータをどのように処理するかを決める機能。
    - インデックスの有無、テーブルの接合方法を決定する。
    - *explainがやってるのはオプティマイザの処理のdumpと考えればよい？*
  - データの処理方法が決まり、実データがどのように格納されているかを扱う部分がストレージエンジン部。

## よく聞くMyISAMとInnoDBって？
  - MySQL≒Pluggable Storage Engine Architecture(ストレージエンジンを抜き差しできるアーキテクチャ)。
  - MySQLではtableごとにストレージエンジンを選択することが可能。

### MyISAM
  - テーブル単位のファイルによるデータ構造を持ち、トランザクション機能をサポートしていない。
  - テーブル単位で何件データを保持しているか、内部で持ってる。(⇔InnoDBは...)
  - テーブルスキャンの速度が早い。

### InnoDB
  - テーブルスペース内に複数のテーブルやインデックスを格納するデータ構造を持ち、トランザクション機能をサポートしている。
  - 障害発生時にデータ損失がない(ACID準拠なら)
  - ホットバックアップ(サーバ無停止で完全なバックアップ)が可能⇔MyISAMは...
  - 行ロックができるのはInnoDBの方。(同時並列処理性能がこれで高くなる！)

# カーディナリティについて
  - データのバラツキ度合いの指標。直訳すると「濃度」のこと。
  - カーディナリティが大きい＝データのバラツキ度合いが大きい≒データがユニーク
  - ex) 性別はカーディナリティがとても低い
  - カーディナリティが低いときはindexを使わず上から舐めていく。

# インデックスについて
  - InnoDBにはPRIMARY KEY, SECONDARY KEY(KEY)の2種類が存在。

## PRIMARY KEY
  - 1テーブルに1つしか存在しないKEY
  - リレーショナルモデルの一意制約を守るためにある
    - 集合モデルのため、同じ要素が2つあってはいけない
    - PRIMARY KEYを指定しない場合でも、暗黙的な隠しカラムが作られる
  - InnoDBはprimary keyがデータそのもの(クラスターインデックス)
    - データ自体がインデックスに含まれる

## SECONDARY KEY
  - 複数作成可能
  - ノンクラスターインデックス
    - インデックスを辿ってくとデータ(primary key)へのリファラがある。
  - リーフノードにデータを持たないということは...
    - データを探すときにSECONDARY KEY->PRIMARY KEYの複数のIOが走る
      - primary keyによる検索より時間がかかる
      - 負荷もかかる
    - ノンクラスターインデックスの中にprimary keyを持つ
      - primary keyのサイズが大きいと、KEYのサイズが膨らむ

## KEYの構造は、どちらもB+tree構造
  - B木についてはまた後程...
  - 合わせて読みたい。
  - http://qiita.com/kiyodori/items/f66a545a47dc59dd8839
MacでJavaアプレットを動かす

昔に作られた割と重要なサイトがJavaアプレットで作られているけど最近だとセキュリティの設定でうまく動かないので面倒くさくなって見るのを辞めた人もいると思います。

Macだと以下の方法で見えます。

0. 前提としてOracleのJavaがインストールされているとします。
1. System Preferences -> Javaを開きます。
2. Java Control PanelでSecurityタブを選択します。
3. Exception Site Listに見たいJavaアプレットがあるサイトを追加します。
4. ブラウザ(Safari)を再起動するとJavaアプレットが見えるはずです。

※注意
- Chromeだと見えません。
- SafariのJavaプラグインの設定だとなぜかうまく動きません。
composer update で a lack of memory and not having swap configured と言われた時の解決方法。

環境を変えてcomposer updateをしたところ失敗して困りました。

# composer update が失敗
composer updateが失敗しました。

```
composer update
You are running composer with xdebug enabled. This has a major impact on runtime performance. See https://getcomposer.org/xdebug
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Installing aws/aws-sdk-php (3.11.2)
The following exception is caused by a lack of memory and not having swap configured
Check https://getcomposer.org/doc/articles/troubleshooting.md#proc-open-fork-failed-errors for details
```
memory不足みたいなことが書いてあります。

# composer update をオプションをつけて実行

```
sudo composer update -vvv --profile
```
成功しました(☝ ՞ਊ ՞)

# 参考
https://laracasts.com/discuss/channels/laravel/composer-update-error-5
JavaScriptとJavaで正規表現マッチング

Javaの正規表現マッチングを書く時にいつも「こうだったかなぁ…」と手探りになってしまうので、JavaScriptと比較してみた。

## JavaScript

```js
var str = 'abcdefg';
var regexp = /abc(.+)/;
var matchRes = str.match(regexp);
if (matchRes) {
  var result = matchRes[1]; // result = defg
}
```

## Java

```java
String str = "abcdefg";
Pattern pattern = Pattern.compile("abc(.+)");
Matcher matcher = pattern.matcher(str);
if (matcher.find()) {
  String result = matcher.group(1); // result = defg
}
年月日時分（YYYYMMDDhhmm）の妥当性チェック

シェルスクリプトで年月日時分(YYYYMMDDhhmm)までの日付を扱う時に、
入力された値が妥当な値(※)であるかをチェックする方法。

※
201504351020 = 2015年04月35日10時20分
201504012500 = 2015年04月01日25時00分
等の存在しない年月日時分をエラーとする。


入力が年月日(YYYYMMDD)であれば

> date -d 20150401 >/dev/null 2>&1
> echo $?  # 0:OK 1:NG

のようにdateに食わせてチェック可能。

また、"201504011530"を"20150401 15:30"のように形式を変えて

> date +'%Y%m%d %H:%M' -d "20150401 15:30"
> echo $?  # 0:OK 1:NG

のように12桁をバラせばdateに食わせて同じように判定に使えるようだが、
作成の都合上バラしたくない。（というかめんどくさかった。）

結局、12桁の値を"touch -t"に渡して適当なファイル(/tmp/_datetimecheck)の
タイムスタンプに設定して、設定が成功するかどうかで判定させることに。

```main
# SetDate (YYYYMMDDhhmm)
echo -n -e " \"Set DateTime (YYYYMMDDhhmm)\" > "
read DATETIME

datetime_check $DATETIME

if [ $? -gt 0 ]; then
    echo -e " \"$DATETIME is NG. Set Correct DateTime (YYYYMMDDhhmm)\""
    exit 1
    fi

# datetime_check() - 年月日時分チェック
# $1 : $DATETIME
# $? : 0:OK 1:NG(日付時刻異常)
function datetime_check() {
    touch -t $1 /tmp/_datetimecheck >/dev/null 2>&1
    return $?   #"0"ならOK。"1"ならNG。
}

#その他のチェック(桁数チェック、数字以外の文字などが入力されてないか)については割愛
```

もっとスマートな方法があればどなたか教えてください。
というか、当初使うつもりだったdateコマンドでの方法が、
> date +'%Y%m%d%H%M' -d 201504011530
> date: invalid date `201504011530'
> 
と言う風に"invalid date"と言われてしまうのか未だに分からずモヤモヤしています。
gulpコマンドで Error: The `libsass` binding was not found と表示された時の解決方法。

gulpを実行したらエラーがでました。

# gulpでエラー
エラーがでます＼(^o^)／

```bash:
gulp

/Users/pugiemonn/Documents/workspace/pugiemonn.com/node_modules/gulp-sass/node_modules/node-sass/lib/extensions.js:158
    throw new Error([
          ^
Error: The `libsass` binding was not found in /Users/pugiemonn/Documents/workspace/pugiemonn.com/node_modules/gulp-sass/node_modules/node-sass/vendor/darwin-x64-14/binding.node
This usually happens because your node version has changed.
Run `npm rebuild node-sass` to build the binding for your current node version.
    at Object.sass.getBinaryPath (/Users/pugiemonn/Documents/workspace/pugiemonn.com/node_modules/gulp-sass/node_modules/node-sass/lib/extensions.js:158:11)
    at Object.<anonymous> (/Users/pugiemonn/Documents/workspace/pugiemonn.com/node_modules/gulp-sass/node_modules/node-sass/lib/index.js:16:36)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at Object.<anonymous> (/Users/pugiemonn/Documents/workspace/pugiemonn.com/node_modules/gulp-sass/index.js:176:21)
    at Module._compile (module.js:460:26)
```

# node-sass を rebuild
node-sassをrebuildします。

```bash:
npm rebuild node-sass
```

# 再度gulpを実行
今度は成功しました(☝ ՞ਊ ՞)
Milkcocoaの認証について（2015年11月バージョン）

#はじめに

以下の３つについて説明することでMilkcocoaの認証について説明します。

- 認証済みクライアント以外を接続不可にする機能
- API Key認証
- トークン認証

## 「認証済みクライアント以外を接続不可にする」とは？

<img width="775" alt="スクリーンショット 2015-10-29 1.20.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/20848/43a66e4d-68b2-28e9-b458-25861f8b6a91.png">

これをONにすると、「認証」を行っていないクライアントのすべてのAPIアクセスを拒否します。同時接続数にも加算されません。「認証」には以下の２つの方法があります。

- API Key認証
- トークン認証

###API Key認証とは

<img width="794" alt="スクリーンショット 2015-10-29 1.26.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/20848/0d521ca4-10cc-df41-464c-cf41a9cfa1e7.png">

API KeyとSecretのペアを生成して、それを使って認証します。JavaScriptのソースコードは以下です。

```
var milkcocoa = MilkCocoa.connectWithApiKey('{appid}.mlkcca.com', 'API_Key', 'API_Secret');
```

###トークン認証とは

シークレットキーを使ってJSON-Web-Tokenを生成し、それを使って認証します。

<img width="874" alt="スクリーンショット 2015-11-24 19.33.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/20848/dd57def8-6320-79dc-dffb-2476eaf0237e.png">

例えば、Facebook認証を実装し、上のシークレットトークンを使い、JSON-Web-Tokenを生成します。

実装サンプル：https://github.com/milk-cocoa/auth/
JWT生成をしているコードの場所：https://github.com/milk-cocoa/auth/blob/master/server/token.js

```
var jwt = require('jsonwebtoken');
var token = jwt.sign({
	sub :'user id',  //<-facebook認証で得たユーザIDを入れる
	iss : 'foo.com',  //<-自分のホスト
	aud : 'mlkcca.com'
}, "{Secret Key}", {expiresIn : 30 * 60});
```

そのトークンをクライアント側に返し、authWithTokenメソッドを使いMilkcocoaに認証します。

```
MilkCocoa.authWithToken(token, function(user) {console.log("auth", user)});
//結果："auth" {sub:'user id', ...}
```

これによりuserメソッドで、ユーザ情報が取得できるようになります。

```
MilkCocoa.user(function(user) {console.log("user", user)});
//結果："user" {sub:'user id', ...}

```
OSX EL CapitanのSafariユーザー一撃でやっつける

FFでこの投稿を書いているので大丈夫だけど、Safariの方はきっとこの記事を読めないはず。最近自分のサービスのユーザーの投稿でSafariが落ちるという現象が起こるようになって調べてみた。

以下のページ、OSX Capitan Safariで開くと落ちる。
https://ja.wikipedia.org/wiki/Unicode%E4%B8%80%E8%A6%A7_0000-0FFF
unicode 0b00-0bffの範囲が悪さしていることはわかった。

例えば、

୧と ⃛の間にスペース無しだと以下のようになる。
この組み合わせだと、Safariが死ぬ。

```python
print u'\u0b67\u20db'
୧⃛
```

୧と ⃛の間にスペースありだと問題はない

```python
print u'\u0b67 \u20db'
୧ ⃛
```

あと不思議なのが、
https://ja.wikipedia.org/wiki/Unicode%E4%B8%80%E8%A6%A7_0000-0FFF
のページでSafariが落ちる。

上記ページには例にある組み合わせは見当たらない。
何かが原因でこうなる。

Safariのbugreportもしてみたが、誰かこの辺りに詳しい人がいたら教えて欲しい。

落ちる組み合わせの文字をSlackに投稿したら、Capitanユーザーであれば各自に落とせるからやらないほうが良いよ！と言いながらいたずらでやってみたら、大変なことになった。

キャッシュとか全部消さないといけないから復旧めんどいことになる。
実践的なrsyncを使ったbackup

rsyncで毎日あるフォルダをバックアップしたい。
そんなあなたに。

## 要約

毎日rsyncしてzipでアーカイブする。
フォルダ階層はこんな感じ。

```
backup/
|-- 20151120.zip
|-- 20151121.zip
|-- 20151122.zip
`-- 20151123.zip
```

### 方法

以下、バックアップスクリプト。
`/path/to`な箇所を書き換える。
src_dir: バックアップ元。ssh先のバックアップOK。(例: `hoge.com:/path/to/dir` )
dest_dir: バックアップ先

```bash
#/bin/sh

src_dir="/path/to/dir"
dest_dir="/path/to/dir"

backup_dir=`date +'%Y%m%d'`

mkdir -p ${dest_dir}/${backup_dir}
rsync -a ${src_dir} ${dest_dir}/${backup_dir}

# zip archive
cd ${dest_dir} && zip -rm ${backup_dir}.zip ${backup_dir}
```

### 定期実行

毎日実行するなら `/etc/crontab` にでも書いておこう。

```bash
# everyday backup at 22:10
10 22 * * * root /path/to/basic_backup.sh >> /path/to/backup.log
```

### 参照

gistも置いておいたから自由に使ってね！
https://gist.github.com/Yuji-Kuroko/e585859307f7477c6447
JMeterで.NET製WebServiceへ負荷をかける。

一般的なJMeterの使い方とほとんど変わらない。

##概要

.NETのWebサービスはSOAPでクライアントとサーバ間の通信を行っている。
JMeterでは、WebServiceの通信は通常のWebアプリと同じく
HTTPプロキシサーバでHTTPリクエストをキャプチャできる。

純粋にSOAPの通信のみをとるなら、Webサービス用のサンプラーがある。
プログラムから実行したときはSOAP over HTTPなので、
HTTPリクエストのほうが実際のプログラムの動きに近いのでこちらで実行。


##インストール

**1.JMeterインストール**
最新版を以下からダウンロード
[Apache JMeter](http://jmeter.apache.org/)

**2.JREインストール**
JDKでなければ、動かないプラグインがあるらしい。
[Java](https://java.com/ja/download/)

**3.Standard Plugin導入**
入れておいたほうがいろいろ楽。
ダウンロードしたらlib/extフォルダにすべてコピーするだけ。

[JMeterプラグイン](http://jmeter-plugins.org/downloads/all/)

**4.複数台エージェントに設定**
1台だけだと、クライアントがボトルネックになって
想定負荷かからないかもなので、複数台から実行させよう。
> こちらのサイトを参考
> [複数台のJMeterサーバで負荷試験を行う方法](http://www.checksite.jp/jmeter-remote-test/)
>

##キャプチャ
**1.%JmeterROOT%/bin/Jmeter.bat実行**

**2.スレッドグループを追加**
テスト計画を右クリック スレッド　> スレッドグループを追加

実施するテストシナリオに沿ったプロパティ値を設定する。

```
<スレッドプロパティについて>
スレッド数：≒maxユーザ数
Ramp-up期間：総スレッド数になるまでにかかる時間
ループ回数：スレッドを何回ループするか

```

もしくは　スレッド > jp@gc Stepping Thread Groupを追加する。

こちらは時間ごとにスレッドグループの実行数を視覚的に作成することができるので楽

**3.HTTPプロキシサーバ追加**

ワークベンチを右クリック　追加　> Non-Testエレメント > HTTPプロキシサーバ

ポート:適当（8088とでもしておきましょ。）　…localhostでプロキシするポートなので
対象となるコントローラ:2で作成したスレッドを選択する。

これで「開始」をクリックして、キャプチャするアプリケーションを実行すれば、
スレッドグループに自動でリクエストが記録される。




------------------------------------------------------
...念のため、SOAPのとり方も記録する。(※)1,2は同じ。

**3.サンプラー追加**

スレッドグループを右クリック　＞　追加　＞サンプラー　から
Webサービス（SOAP）リクエストを追加する。

※これは、ver2.13ではデフォルトで選択できない。
/bin/jmeter.propertiesのnot_in_menuから削除。

**4.サンプラー設定**
WSDLにURLを設定してWSDLボタンをクリック。
web methodで接続するメソッドを選択し、設定ボタンをクリック。
=> 自動でプロトコルなどが設定される。
SOAPレスポンス読込

**5.SOAPキャプチャ**
Fiddler2などキャプチャツールを起動して、SOAPの通信を取得する。
TextViewを確認すると、通信時に発生したXMLが記載されているので、
それをSoap/XML-RPCデータにコピペする。

オプションの「メモリーキャッシュ」、「SOAPレスポンス読み込み」にはチェックを入れておく。

　...他のキャプチャ方法ないのだろうか？？

##ボディの一部の値を変数化

変数化してリクエストを動的に変えて、
より実際のプログラムに近い状態に負荷をかける。

設定エレメント（ユーザ定義変数、カウンタ、CSVDataSet）で値を生成、
変更する箇所は_${変数名}_で置き換える。
変数を使うサンプラーに設定エレメントをぶらさげる。


##結果を測定
測定するスレッドグループにリスナーを追加する。

**使いやすいリスナー**

- 統計レポート                    ... csvファイルに出力
- 結果をツリーで表示              ... リクエストとレスポンスの中身を確認可能。　
- jp@gc Response Times Over Time
- jp@gc Hits per Seconds
- jp@gc PerfMon Metrics Controller

PerfMonを使用するには、Server Agentを別途導入しておく。
startAgent.batを実行すると、デフォルトポート4444でサーバ情報を取得できる。
[Server Agent](http://jmeter-plugins.org/wiki/PerfMonAgent/)

##結果を解析
結果を整理するだけ。

- 統計レポートで出力したcsvからピボットテーブルなどで、集計してグラフを作成する。
- パフォーマンスカウンタにて取得した情報から整理。
Swift2 での iCloud Notification の問題

Swiftが1.2から2になって型のチェックが更に厳しくなりました。それによって、iCloud の Notificaiton が従来のコードだとうまく動かないことがわかりました。
iCloud にKeyValueStoreでデータを保存していて、変化をNSNotification で受け取る場合、まずどこかでNotificationCenter にAddObjectで`NSUbiquitousKeyValueStoreDidChangeExternallyNotification` を登録します。
例えば、Viewdid Load であれば、


```Swift:
    override func viewDidLoad() {
        super.viewDidLoad()
        // iCloudのデータに変更があった時の通知を受け取る
        let center = NSNotificationCenter.defaultCenter()
        center.addObserver(self,
            selector: "ubiquitousDataDidChange:",
            name: NSUbiquitousKeyValueStoreDidChangeExternallyNotification,
            object: nil)
    }
```

といった感じです。
そして、データ変更の処理メソッドを定義するわけですが、Swift1.2であれば、


```Swift:
    func ubiquitousDataDidChange(notification: NSNotification) {
        let store = NSUbiquitousKeyValueStore.defaultStore()
        // 通知オブジェクトから渡ってくるデータを取得
        if let info = notification.userInfo as? [String: [String]] {
            if let keys = info[NSUbiquitousKeyValueStoreChangedKeysKey] {
                for key in keys {
                    let num = store.doubleForKey(key)
                    self.label.text = "\(num)"
                }
            }
        }
    }
```


でOKでしたが、Swift2ではこれだと、info はいつも nil になります。
NSNotificationで渡されるuserInfoは、[NSObject: [AnyObject]] であり、[String: [String]] にキャストしようとすると、最初のデータは、
["NSUbiquitousKeyValueStoreChangeReasonKey" : Int32(0)]のようであり、nil となります。
Swift2の場合には、次のように実際に使うところでキャストするようにしないとうまく動作しません。

```Swift:
    func ubiquitousDataDidChange(notification: NSNotification) {
        let store = NSUbiquitousKeyValueStore.defaultStore()
        // 通知オブジェクトから渡ってくるデータ取得
        if let info = notification.userInfo {
            if let keysrow = info[NSUbiquitousKeyValueStoreChangedKeysKey] {
                let keys = keysrow as! [String]
                for key in keys {
                    let num = store.doubleForKey(key)
                    label.text = "\(num)"
                }
            }
        }
    }
```
MyBatis、XMLのつまづきポイント

今日のハマりポイント


# Mapper.XML
- DB項目名称と、変換した項目名称の誤り
プロジェクトの設定(？)によるのかもしれないけど、
今のプロジェクトのGENERATORではスネークケースをキャメルケースに置換するようにしているため、
Mapper.javaの項目を使う場合は次のような名前でアクセスする必要がある
\#{item.PRODUCT_ID} ⇒ #{item.productId}

- 変数の使い方
foreachで、繰り返しの変数を設定できる(index="index")と記載あるが、どうアクセスするのか戸惑った。
結果⇒ダラーで囲って「${index}」

# Mapper.java(インターフェイス)
パラメータへの@Paramの記載漏れ。名前指定をしていないとMapper.xmlで#{xxx}でのアクセスができない。

```java:Mapper.java
/* @Paramでオブジェクトの名前を指定が必要 */
List<Integer> selectByXX(@Param("condition") Object obj);
```

```xml:Mapper.xml
<foreach item="item" index="index" collection="condition"> <!-- collectionに@Paramで指定した名前を使う -->
	AND (TABLE.ID = #{item.hoge} AND TABLE.VAL #{item.huge})
</foreach>
```
iptables周りの備忘録

### 現状登録されている設定内容を行番号付きで確認する

```
$ /sbin/iptables -L -n --line-number
```

### 指定した行番号へiptablesの設定追加する

```
# /sbin/iptables -I INPUT {行番号} -s {IP/サブネットマスク} -p tcp -m tcp --dport {ポート番号} -j ACCEPT
$ /sbin/iptables -I INPUT 11 -s xxx.xxx.xxx.xxx/255.255.255.255 -p tcp -m tcp --dport 443 -j ACCEPT
```

### iptablesのコンフィグにも保存（再起動した際も反映するようにするため）

```
$ /etc/init.d/iptables save
```

### iptablesのコンフィグにも設定保存されてることを確認する

```
$ cat /etc/sysconfig/iptables
```

### 間違えて設定入れた時に行番号指定して消すコマンド

```
# /sbin/iptables -D INPUT {行番号}
$ /sbin/iptables -D INPUT 15
```

### iptablesを再起動した際に、iptablesモジュールをunloadしないようにする設定
window scale optionを無効にする

```
# 現状のwindow scale optionの確認
[test-user@hoge ~]$ cat /proc/sys/net/ipv4/tcp_window_scaling
1
 
# iptablesのコンフィグ確認
[root@hoge ~]# grep UNLOAD /etc/sysconfig/iptables-config
IPTABLES_MODULES_UNLOAD="yes"
 
# IPTABLES_MODULES_UNLOADをnoにする
[root@hoge ~]# vim /etc/sysconfig/iptables-config
IPTABLES_MODULES_UNLOAD="no"

# iptablesの再起動（iptablesモジュールの取り外しが行われなくなる）
[root@hoge ~]# /etc/init.d/iptables restart
```
macでnginxを使う

#### install

```
macbook:~ user$ brew install nginx
```

#### 確認

```
macbook:~ user$ which nginx
/usr/local/bin/nginx
```


#### dirに移動

```
cd /usr/local/etc/nginx/
```


#### backup

```
cp nginx.conf nginx.conf.org
```


#### 俺俺証明書
```
openssl genrsa -des3 -out server.key 1024
openssl req -new -key server.key -out server.csr
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
```

#### confFileを配置
``` nginx.conf
#user  nobody;
worker_processes  1;

#pid        logs/nginx.pid;
events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;

        location / {
            root   /Users/user/www;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }

    # HTTPS server
    #
    server {
        listen       443 ssl;
        ssl on;
        server_name  localhost;
        ssl_certificate /usr/local/etc/nginx/server.crt;
        ssl_certificate_key /usr/local/etc/nginx/server.key;
        location / {
            root   /Users/user/www;
            index  index.html index.htm;
        }
    }
    include servers/*;
}

```


#### html配置
```
mkdir $USER/www
touch $USER/www/test.html #中身は適当に
```

#### reboot
```
sudo nginx
```

#### access
```
https://localhost/test.html
```

#### みれたらおわり
無料SSLのLet's Encryptを使ってみた（CentOS7+Apache)

HTTPSなサイトを作るためには普通はSSL証明書を購入するか、オレオレ証明書を作成する必要があるが、コストやブラウザに警告が表示されるなど悩ましい。

そこで現在はクローズドベータ中ですが無償で利用できるSSL証明書発行サービスLet'sEncryptを試してみることにします。(ちなみに2015年12月3日にはパブリックベータとなるようです。)

![le.png](https://qiita-image-store.s3.amazonaws.com/0/98711/ecebd731-5e29-115a-1073-204c3c4b84d5.png)


自分メモに近いので、読みにくい個所はご容赦を。


##ベータプログラムに参加
https://community.letsencrypt.org/t/beta-program-announcements/1631

にアクセスして「join the Beta,sign up here」をクリックします。
![betaprogram.jpg](https://qiita-image-store.s3.amazonaws.com/0/98711/47c2a3d7-af6e-a973-9624-c2fa7a97c281.jpeg)

ベータプログラム参加のための登録フォームが表示されるので、必要な項目を入力します。
1.　証明書を取得したいドメイン名
2.　連絡先メールアドレス。

![beta.jpg](https://qiita-image-store.s3.amazonaws.com/0/98711/86e771b9-17f0-fda4-2d5f-d395e3471b57.jpeg)

送信すると数日（？）でアナウンスのメールが届きますので、それにしたがって設定を行います。


##設定

###検証環境
・CentOS7

1.準備

必要なパッケージをインストールします。

```
#webサーバ環境
yum install httpd mod_ssl openssl

#git
yum install git

```

httpdの必要な設定等は割愛（80番ポートはあけておき、httpdのサービスはストップしておく）

2. Let’Encrypt

```
$ sudo git clone https://github.com/letsencrypt/letsencrypt

$ cd letsencrypt

$ sudo ./letsencrypt-auto --agree-dev-preview --server https://acme-v01.api.letsencrypt.org/directory auth
※-d（サーバ名）のオプションをつけてもOK

```

上記コマンドを実行すると必要なライブラリなどを自動的にインストールしてくれる。

画面がブルーバックに切り替わり
・Emailアドレスの入力
・サーバ名の入力
・使用許諾の確認
などが表示されるので、そのまま答えていく。

最後にこのようなメッセージが表示されれば完了。

```

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/test.hogehoge.com/fullchain.pem. Your cert
   will expire on 2016-02-22. To obtain a new version of the
   certificate in the future, simply run Let's Encrypt again.
```

メッセージにあるように
「/etc/letsencrypt/live」ディレクトリ内に以下のファイルが生成される。

```
#サーバ証明書＋中間証明書
/etc/letsencrypt/live/test.hogehoge.com/fullchain.pem
#サーバ証明書
/etc/letsencrypt/live/test.hogehoge.com/cert.pem
#中間証明書
/etc/letsencrypt/live/test.hogehoge.com/chain.pem
#サーバ秘密鍵
/etc/letsencrypt/live/test.hogehoge.com/privkey.pem
```


あとはssl.confに証明書等を登録してやればOK

```
#/etc/httpd/conf.d/ssl.conf

SSLCertificateFile /etc/letsencrypt/live/test.hogehoge.com/cert.pem

SSLCertificateKeyFile /etc/letsencrypt/live/test.hogehoge.com/privkey.pem

SSLCertificateChainFile /etc/letsencrypt/live/test.hogehoge.com/chain.pem


```

httpdを再起動してブラウザ等でアクセスすると、成功！

証明書チェーンを確認してみると
　　　　　－DST Root CA X3
　　　　　　　－Let's Encrypt Authority X1
　　　　　　　　　－test.hogehoge.com
となっておりほとんどのブラウザで警告なしに表示可能かと思われます。


##注意

なにしろLet'sEncryptのサービスがベータ版なので、有効期間が90日となっています。
今のところ定期的な更新が必要なのでご注意を！
「Object(連想配列).lengthとか無いし終わった」って時

※IE9から対応しています。

連想配列(オブジェクト)の要素数は
Object.keys(hoge).length
でとれます。


```hoge.js
var hoge = {
	"name":"わたなべ",
	"gender":"male"
	"job":"ヒモ"
}
 
console.log(Object.keys(hoge).length); // 3 

```

めでたしめでたし
Mac OS X El Capitan で NTFSフォーマットのディスクに書き込み可能にする。

Mac OS X El Capitan で NTFSフォーマットのディスクに書き込み可能にする。

##概要

Mac OS Xに標準搭載されているNTFSサポート機能ではファイルの読み込みしかできないため、Mac FUSEのNTFSサポート機能を利用して書き込みや検索に対応する。

ただし、Mac OS X El Capitanには、System Integrity Protection (SIP)機能が搭載されたため、これをオフにしない限りrootユーザでも /sbin 内を変更できないので、一時的にSIP機能をオフにして作業する必要がある。

また、Mac FuseをHome Brewからインストールするとファインダー上でディスクが表示されなかったりファイル検索ができなかったりするなどの不都合があるため、Mac Fuseのインストールdmgをダウンロードしてきてインストールする必要がある。

##方針

0. Mac Fuseのインストールdmgをダウンロードしてインストールする
0. Home Brewでntfs-3gをインストールする
0. Mac OS XのSystem Integrity Protection機能を一時的にオフにする
0. /sbin/mount_ntfsのリンク先を変更する
0. Mac OS XのSystem Integrity Protection機能をオンに戻す
0. fstabを編集する

##作業手順

### 1. Mac Fuseのインストールdmgをダウンロードしてインストール

https://github.com/osxfuse/osxfuse/releases

### 2. ntfs-3gをインストール
（HomeBrewがすでにインストールされていることが前提）

#### 2-1. ターミナルに下記のコマンドを入力してEnterキーを押す

    brew install homebrew/fuse/ntfs-3g

### 3. System Integrity Protection機能を一時的にオフにする

#### 3-1. Mac OS Xをシステム終了する。
#### 3-2. 起動時に commandキーとRキーを押しながら電源ボタンを押す。（電源ボタンから手を離したあともcommandキーとRキーは押したまま待つ）
#### 3-3. リカバリーモードが起動したらcommandキーとRキーから手を離す
#### 3-4. メニューバーから ユーティリティー ＞ ターミナルを選択
#### 3-5. ターミナルに下記のコマンドを入力してEnterキーを押す

####

    csrutil disable


#### 3-6. システムを再起動する

### 4. /sbin/mount_ntfsのリンク先を変更する

#### 4-1. ターミナルを起動し、下記のコマンドを入力してEnterキーを押す

    sudo mv /sbin/mount_ntfs /sbin/mount_ntfs.original
    sudo ln -s /usr/local/sbin/mount_ntfs /sbin/mount_ntfs

### 5. System Integrity Protection機能をオンにする

#### 5-1. Mac OS Xをシステム終了する。
#### 5-2. 起動時に commandキーとRキーを押しながら電源ボタンを押す。（電源ボタンから手を離したあともcommandキーとRキーは押したまま待つ）
#### 5-3. リカバリーモードが起動したらcommandキーとRキーから手を離す
#### 5-4. メニューバーから ユーティリティー ＞ ターミナルを選択
#### 5-5. ターミナルに下記のコマンドを入力してEnterキーを押す

####

    csrutil enable

#### 5-6. システムを再起動する

### 6. fstabを編集する

####
    sudo nano /etc/fstab

####
    LABEL=ディスク名  none    ntfs    rw,auto,nobrowse

（ディスク名にスペースが含まれる時はバックスラッシュでエスケープする）
例: ディスク名が IMPORTANT HDD の場合、IMPORTANT\ HDD とする

作業は以上で完了。

### 7. 確認

HDDを接続してマウントされること、書き込みができること、検索ができることを確認する。


参考）
https://gist.github.com/bjorgvino/f24e5c079b92f921b765
http://learnaholic.me/2013/11/11/enable-ntfs-write-on-mac-os-x-mavericks/
CakePHP2.xとBehatとSelenium2とPhantomJSでJavascriptアラートをテストする方法


Behat(Bddプラグイン)とSeleniumでJavascriptのアラートをチェックする方法がやっとわかったので、メモ。
情報はボチボチでていたものの、タイトルに有るような環境でのビッタリな答えが見つけられなかったので、自分なりに試行錯誤した結果です。

結果から言うと、「テストは可能だがちょっと無理やり感がある」って感じでした。
Selenium2だけだと、Javascriptのアラート関係に対応していなかったので、
ヘッドレスブラウザのPhantomJSで実現します。


## インストールするもの
* Behat
* Mink
* Selenium2WebDriver
* PhantomJS


## 手順
### 1 初期化します

```
$ app/Console/cake Bdd.story
```

### 2 featureを書きます

```gherkin
  もし jsで "/xxxx/xxxx/" を表示している
  ならば jsでアラートの文字が "名前を入力して下さい" となっているかチェックする
```

### 3 ステップファイルを作ってコードを書く（steps/step_xxx.php）

```php
$steps->Given('/^jsでアラートの文字が "([^"]*)" となっているかチェックする$/', function($world, $arg1) {
    if(!$world->checkAlertMessage($arg1)) {
        // テストが通らなかったら、エラーを投げる
        throw new ErrorException();
    }
});
```

### 4 実際の処理を[bootstrap/FeatureContext.php]に書きます

function __constructに以下を。

```php
// ドライバの初期化
$host = CI_HOST . ":8910/wd/hub";
$browser = "phantomJS";
$this->gui = new Mink(array(
'javascript' => new Session(new Selenium2Driver($browser, null, $host)),
));
```


適当な場所に以下の2つのメソッドを書く。

```php
// Javascriptでアラートの文字を拾う準備をする
public function presetGetAlertMessage()
{
    // Alertの文字を拾う（クリックの前に入れておく）
    $this->gui->getSession('javascript')->getDriver()->evaluateScript(
    "
    (function () {
        var lastAlert = undefined;
        window.alert = function (message) {
            lastAlert = message;
        };
        window.getLastAlert = function () {
            var result = lastAlert;
            lastAlert = undefined;
            return result;
        };
    }());
    "
    );
}

// Javascriptのアラートメッセージをチェック
public function checkAlertMessage($message)
{
    $getMessage = $getMessage = $this->gui->getSession('javascript')->getDriver()->evaluateScript(
        "return window.getLastAlert()"
    );
    // チェック
    if($getMessage === $message) {
        return true;
    } else {
        return false;
    }
}
```

### 5 PhantomJSを起動する

```
$ phantomjs --webdriver=8910
```

phantomjsは、バックグランド実行するか、別窓コンソールで実行する


### 6 Behatを実行する

```
$ ./app/Console/cake Bdd.story
```


##ポイントはブラウザの切り替え

ブラウザの概念がわからなかったのですが、要は、もともとあったテスト用ブラウザ（Firefoxかな？）と、PhantomJSというブラウザの２枚があり、前者だと、Javascriptがうまく使えない。なので、都度ブラウザをPhantomJSに変えましょう、ということらしい。

今回だと、「jsで〜」とつけたものはPhantomJSで実行するように作った。
ブラウザが変わると、もちろんデータ等は保持されないので、エラーがでまくる。
その辺がわからずにずっとハマってしまっていました。



## 参考書籍・サイト
* CakePHPで学ぶ継続的インテグレーション（これを元に構築しています）

* [Selenium 使いのための PhantomJS 解説 - Qiita](https://qiita.com/okitan/items/00b677df1a941a1e0ba0)
Windows > これらのファイルは、コンピューターに害を及ぼす可能性があります... > IPアドレス追加する

```txt:動作確認
Windows 7pro
```

あるサーバーからファイルをコピー時に以下のメッセージが出るようになった。

> これらのファイルは、コンピューターに害を及ぼす可能性があります。
...

対応の参考
http://oshiete.goo.ne.jp/qa/5483498.html

コントロールパネル > インターネットオプション > セキュリティ > ローカルイントラネット > サイト > 詳細 > このWebサイト... にサーバのIPアドレスを追加する。
S3＋EC2でBasic認証を設定をする

#やりたかった事
S3にBasic認証をかけてみたかったので、試してみました。
S3＋EC2構成で、Basic認証を行います。

![Untitled (1).png](https://qiita-image-store.s3.amazonaws.com/0/46632/bbb07f05-87b7-4cb5-0e93-9e922ece3114.png)


# 今回の環境
・EC2（　Amazon Linux AMI release 2015.09　）
　自分が接続する拠点からの、http（80番）・SSH（22番）のアクセスを許可

・S3バケット
　S3バケットを1つ作成する（今回は s3.k-staging.com というバケット名で作成）
　ウェブサイトのホスティングを有効にしておく

・Route53
　ドメイン「 s3.k-staging.com 」を発行する
　TypeはCNAMEで、Valueには上記EC2のPublic DNSを設定する


# S3バケット設定
バケットポリシーを以下のように設定します。

```
{
	"Version": "2012-10-17",
	"Id": "PolicyXXXXXXXXXXXXX",
	"Statement": [
		{
			"Sid": "StmtXXXXXXXXXXXXX",
			"Effect": "Allow",
			"Principal": "*",
			"Action": "s3:GetObject",
			"Resource": "arn:aws:s3:::s3.k-staging.com/*",
			"Condition": {
				"IpAddress": {
					"aws:SourceIp": [
						"52.XX.XX.XX/32(EC2のIPアドレスを記述）"
					]
				}
			}
		}
	]
}
```
※「aws:SourceIP」にEC2のIPアドレスを記述する事により、EC2以外からS3バケット（ s3.k-staging.com.s3-website-ap-northeast-1.amazonaws.com ）を直接参照できないようにしてます。


# EC2設定
まずNginxとhttpd-toolsをインストールします。

```
$ sudo yum install nginx
$ sudo yum install httpd-tools
```

下記手順で、.htpasswdファイルを作成します。

```
$ sudo htpasswd -c /etc/nginx/.htpasswd "Basic認証で利用するユーザー名（今回は k-staging と入力）"
  New password: "Basic認証で利用するパスワードを入力"
  Re-type new password: "再度パスワードを入力する"
  Adding password for user k-staging
```


Nginxのconfigを、以下のとおり作成します。

```lang:/etc/nginx/conf.d/proxy.conf
server {
    listen       80;
    server_name  s3.k-staging.com;

    location / {
        auth_basic "Basic Auth";
        auth_basic_user_file /etc/nginx/.htpasswd;
        proxy_pass http://s3.k-staging.com.s3-website-ap-northeast-1.amazonaws.com;
    }
}
```

Nginxを起動し、自動起動設定をONにします。

```
$ sudo service nginx start
$ sudo chkconfig nginx on
```

これで s3.k-staging.com に対するBasic認証が設定できました。
動作確認してみます。

#動作確認
ブラウザに「 s3.k-staging.com 」を入力し、Basic認証が出来るか確認します。
![qiita201511240906.png](https://qiita-image-store.s3.amazonaws.com/0/46632/8542ac7f-e9cc-53f5-e6e6-ef4df7dc6414.png)


↓

![qiita201511240040.png](https://qiita-image-store.s3.amazonaws.com/0/46632/b550d7c2-e18e-dfd0-f605-2a240025a689.png)



Basic認証がかかってますね。
念のため、S3に直接アクセスできないかどうかも確認してみます。
ブラウザにS3のURL（ s3.k-staging.com.s3-website-ap-northeast-1.amazonaws.com ）を入力します。

![qiita201511240052.png](https://qiita-image-store.s3.amazonaws.com/0/46632/ac51bf95-f373-8ba4-788f-1c6a6ea29a3f.png)

アクセスできませんね！
docker exec /bin/bashでコンテナに入るとvimが文字化けする

docker execでコンテナに入ることができるが、入った先でvimが文字化けしてしまう現象に遭遇した。


# 文字化けの現象

```
sudo docker exec -it myapp /bin/bash
vim index.html
```

<figure>
<figcaption>UTF-8が文字化けしている様子</figcaption><br>
<img width="272" alt="文字化けの様子" src="https://qiita-image-store.s3.amazonaws.com/0/889/175d1231-976e-d4c8-a644-9ba2ef5d3dd9.png">
</figure>

`:e ++enc=utf8`などしても改善せず。


# 解決するにはlocale環境変数を設定する

こういう場合は、localeがUTF-8じゃない可能性がある。dockerのコンテナに入った状態でロケールを調べる:

```console
$ locale
LANG=
LANGUAGE=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=
```

もし、LANGが未設定であれば、コンテナに入った状態で、LANGを設定する。

```
export LANG=en_US.UTF-8
```


これでvimで文字化けなく開けるようになる。

関連: [Docker: コンテナのlocaleを設定したい - Qiita](http://qiita.com/suin/items/856bf782d0d295352e51)
Azureストレージにファイルのアップロード(Ruby)

これまでバックアップ先にAmazon S3を使っていた部分をAzureストレージに置き換えたのでメモ。BLOBストレージを使用。

## ファイルサイズ制限
BLOBストレージは64MBまでのファイルならば一つのファイルとしてアップロードすることができるけど、それよりも大きい場合は最大4MBのブロックとしてアップロードしてからコミットしなければならない。
今回対象となるファイルは800MBくらいあるのでブロックとしてアップロードする必要がある。


## Gemfile
GemfileにSDKを追加。

```Ruby
gem 'aws-sdk'
```


## Azureストレージとの接続
Azureストレージの管理画面下のアクセスキーの管理ボタンで作成したアクセスキーを使う。
ActiveDirectoryを使えばAmazonIAMみたいに局所的な権限の割当とかできるんですかね。

```Ruby
require 'azure'

Azure.storage_account_name = "<STORAGE_ACCOUNT_NAME>"
Azure.storage_access_key = "<STORAGE_ACCESS_KEY>"
```


## 実装
ファイルを開いて4MB読み出し毎にブロックの作成のAPIを叩くだけの単純な実装。

```Ruby
File.open(file, 'rb') do |f|
  i = 0
  block_ids = []

  loop do

    # 4MBずつ処理
    content = f.read(4 * 1024 * 1024)
    break if content.nil?

    # ブロックIDの生成
    i += 1
    block_id = "%07d"%[i]
    block_ids << [block_id]

    # ブロックのアップロード
    Azure.blobs.create_blob_block(container_name, blob_name, block_id, content)

  end

  # アップロードしたブロックのコミット
  Azure.blobs.commit_blob_blocks(container_name, blob_name, block_ids)

end
```



## ブロックの残骸？
ある時から、アップロードしようとすると **The specified blob or block content is invalid** なるエラーが出るようになってしまった。どうも、途中で中断をして未コミットのブロックが残った状態になると、同名のBLOBをアップロードしようとするとエラーになるっぽい。

ということでアップロード前に削除することにした。ファイルの存在確認をしようかとも思ったけど、面倒だったので強制削除でファイルがない例外の場合は無視するようにした。

既存のアップロードファイルを上書きする場合は削除したもののアップロードも失敗するということも起こりえるのでサーバ側でリネームしておくなりの対応が必要。

```Ruby
# 同名のファイルを削除しておく
begin
  Azure.blobs.delete_blob(container_name, blob_name)

rescue ::Azure::Core::Http::HTTPError => e

  # 同名のファイルがない場合は無視
  raise e if e.type != "BlobNotFound"
end

```

## 感想
AmazonS3みたいに自動で期限切れに出来ないのつらい。
分割アップロードに対応してくれるのは良いけどSDK側で勝手にやってほしい。
LaravelのQueryBuilderやEloquentを素のPHPで使う


Laravelで利用できる便利ツールであるQueryBuilderやEloquentを素のPHPや他のフレームワークで利用する方法。

##前提

* composerはインストールされている
* Mac El Capitan（じゃなくてもいいですが）

##インストール

composerで本体のilluminate/databaseと、依存関係にあるilluminate/eventsをインストールします。

```bash
mkdir test
cd test

composer require illuminate/database
composer require illuminate/events
```

###dbconfig.php

基本的には[本家サイト](https://github.com/illuminate/database)の通りにすればいいですが、設定部分は外部ファイルにしてみました。

```php
<?php

	require_once 'vendor/autoload.php';
	
	use Illuminate\Database\Capsule\Manager as Capsule;

	$capsule = new Capsule;

	$capsule->addConnection([
	    'driver'    => 'mysql',
	    'host'      => 'localhost',
	    'database'  => 'testdb',
	    'username'  => 'root',
	    'password'  => 'root',
	    'charset'   => 'utf8',
	    'collation' => 'utf8_unicode_ci',
	    'prefix'    => '',
	]);

	// Set the event dispatcher used by Eloquent models... (optional)
	use Illuminate\Events\Dispatcher;
	use Illuminate\Container\Container;

	$capsule->setEventDispatcher(new Dispatcher(new Container));

	// Make this Capsule instance available globally via static methods... (optional)
	$capsule->setAsGlobal();

	// Setup the Eloquent ORM... (optional; unless you've used setEventDispatcher())
	$capsule->bootEloquent();
```

###test.php

dbconfig.phpを読み込んで処理を書きます。

QueryBuilderは何もしなくても利用できます。

EloquentはModel Classを定義することで使えます。既存のテーブルを利用する場合は、public $timestamps = false;とします。

>もちろんshopsというテーブルがあることが前提です。

```php
<?php

	require 'dbconfig.php';

	//--- QueryBuilder ------------

	$shops = $capsule::table('shops')->get();

	print_r($shops);

	//--- Eloquent ----------------

	class Shop extends Illuminate\Database\Eloquent\Model
	{
		public $timestamps = false;
	}

	//select
	$shops = Shop::all();

	print_r($shops);

	//insert
	$shop = new Shop();

	$shop->name = "Poo";

	$shop->save();
```

ほとんどLaravelと同じです。

##その他

あとは、Laravelのリファレンスを見ればいいでしょう。

* [QueryBuilder](http://laravel.com/docs/5.1/queries)
* [Eloquent](http://laravel.com/docs/5.1/eloquent)
docker startコマンド

##| はじめに

ここでは[公式リファレンス](http://docs.docker.com/v1.7/docker/reference/commandline/start/)を参考に説明しています。
ただ、バージョンや環境等により若干挙動が異なるかもしれませんが、その点についてはご容赦ください。
また、その他のdockerサブコマンドについては[こちら](http://qiita.com/kooohei/items/8acb82c6c0bf00bfb9bb)に記載していますので、もしよければ参考にしていただければと思います。

##| 使い方

停止しているdockerコンテナを起動させます。

```:使い方
使い方： docker start [OPTIONS] CONTAINER [CONTAINER...]
```

"CONTAINER"に入る値は`docker ps`で表示される"CONTAINER ID"または"NAMES"のどちらでも指定可能です。

```bash:デフォルト
$ docker start 67e46a979b6b
67e46a979b6b

または

$ docker start happy_sammet
happy_sammet

$ docker ps 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
67e46a979b6b        ubuntu              "/bin/bash"         3 days ago          Up 2 seconds                            happy_sammet
```


###・-a, --attach

起動と同時にコンテナへアタッチします。
このオプションで起動した場合はアタッチするのみでコマンド操作などはできません。
そのためアタッチ後は"control + C"でコンテナから抜ける必要があります。

```bash:例.-a,--attach
$ docker start -a happy_sammet
root@67e46a979b6b:/# 
```


###・-i, --interactive

起動と同時にコンテナへアタッチします。
このオプションで接続した場合はインタラクティブモードとなるため、継続してコマンド操作などが可能です。

```bash:例.-i,--interactive
$ docker start -i happy_sammet
root@67e46a979b6b:/# 
```

また、"CONTAINER ID"は全て入力する必要はなく、そのコンテナが特定できるところまでの文字を先頭から入力すればOKです。

```:例.
$ docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
67e46a979b6b        ubuntu              "/bin/bash"         3 days ago          Exited (0) 9 minutes ago                       happy_sammet

$ docker start 6
6

$ docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
67e46a979b6b        ubuntu              "/bin/bash"         3 days ago          Up 1 seconds                            happy_sammet
```

ここでは、停止しているコンテナが１台しかなため、先頭の"6"という数字のみ指定して起動ができていることがわかります。

以上です。
Slack Lita Integration の 'First & Last Name' には飼い主と違う名前を設定しよう

タイトルどおりだけど、とつぜん返事してくれなくてハマったのでメモ。

SlackのLita Integrationを設定するとき、'First & Last Name' に飼い主とまったく同じ名前を設定すると、messageがdispatchされなくなる。設定するときは注意しよう。
Xamarin Stadioで日本語がつかえなくなってね？？

あ、いやタイトル以上に書くことはないんだけど
Xamarin　Stadio5.9.7ではちゃんと日本語入力できてたんですけど、最近アップデートするとできなくなっていた・・・

ぼくはUnityを使っている日本人なのでモノデベロップでなくざまりんを使う理由なんて日本語入力以外なかったので。とても悲しい
Homebrewのまとめノート

#Homebrewとは

- Mac OS X上でUNIXコマンドを使うことを可能にするパッケージ管理システム。
- Ubuntuのaptのようなコマンドベースのパッケージ管理機能が使えるようになる。
- Mac OS XへUNIXコマンドを簡単に追加できるようになる。
- PHP、Python、Rubyなどのプログラミング言語やMySQLなどの開発ライブラリなども簡単な手順で追加することができる。

##導入条件
- JRE（Java SE Rutime Environment）がインストール済みであること。
- Xcode + Command Line Tools、あるいはCommand Line Tools for Xcodeがインストール済みであること。

#手順

- Home brewを入れる

```rb
ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"
```

#gitを入れる

```shell-session
brew install git
```


#うまくいったか環境チェックする

```shell-session
brew doctor
```

#homebrewをアップデートする

```shell-session
brew update
```

#gitのバージョンを確認する

```shell-session
git --version
```

#homebrewのバージョン確認

```shell-session
brew -v
```

#インストール先

## /usr/local/ 以下に全て入る

- PATHを追加せずともコマンドが利用できる
- インストール先のパーミッションが自分に変更されるため、sudoを使わなくともbrewコマンドでパッケージを追加できる


#補足--JAVAについて

- JRE : Java で作られたプログラムを実行するとき必要
- JDK(Java SE Development Kit): Java でプログラムを作るとき必要(JDKにはJREが含まれている)
  http://java.com/ja/download/help/mac_install.xml
  jre-7u7-macosx-x64.dmg

開発するときには実行してみる必要があるため、JDKにはJREが含まれている


#インストール参照
http://qiita.com/livejam_db/items/b70caccdeece036a3797
#エラー
http://roboneco.hateblo.jp/entry/2015/03/13/124536


#Homebrewのクリーンアップ

```shell-session

brew cleanup
```

#RubyGemsのクリーンアップ

```
gem clean
```

参照
http://gatespace.jp/2013/10/31/mac-web-setup-use-terminal/