OmniAICreator/Qiita-1.07M huggingface dataset:
EC2@ubuntuインスタンス作成後にやったインストールのあれこれ

# はじめに
* よくする操作だとおもうので書いておきます！
* 以下をするのにした必要な作業をメモしていきます
 * railsアプリをgit clone
 * アプリの起動
 * seleniumを使ってブラウザ(Firefox)テスト

# Ruby(RVM)のインストール

```
$ curl -L get.rvm.io | bash -s stable
$ source ~/.rvm/scripts/rvm
$ rvm install 1.9.3
$ rvm rubygems latest
$ rvm use --default 1.9.3
```

* デフォルトでは1.8.6が入っていた
* curlは最初から入っていた

# gitのインストール

```
$ sudo apt-get install git-core
$ sudo apt-get install connect-proxy

$ ssh-keygen #ノーパスワードでOK
```

* この手順はssh経由のgit cloneをする場合で、http経由でするのであれば.~/netrcを作成すればよい
 * 参考：http://qiita.com/t-sagiri/items/79535fc5a8f0c89409f7

### ~/.ssh/config作成

```:~/.ssh/config
Host github.com
  User git
  Hostname ssh.github.com
  Port 443
  IdentityFile ~/.ssh/id_rsa
```

### githubに公開鍵を追加
 * https://github.com/settings/ssh に~/.ssh/id_rsa.pubの中身をぺたっと

# bundlerのインストール

```
$ sudo apt-get install bundler
```

# Firefoxのインストール

```
$ sudo apt-get remove firefox #一応、古いFirefoxを削除する手順
$ sudo apt-get install firefox
$ firefox -v

Mozilla Firefox 30.0
```

* 最初から入ってなかったので要インストール

# Xvfb(仮想フレームバッファサーバ)のインストール

```
$ sudo apt-get install xvfb
```

* Headlessでテストを実行する場合には入れておかないと、以下のようなエラーがでる
 * Xvfb not found on your system (Headless::Exception)
* 入れるとCUIだけでもFirefoxが使えるようになる

# 以下は必要であれば
## vimのインストール

```
$ sudo apt-get install vim
```

## sshのインストール

```
$ sudo apt-get install ssh
```

# おわりに
* 以上でgit clone/サーバー起動/テストができる環境が備わった

# ～ただの宣伝～
* [全国のSeleniumer必読](http://qiita.com/oh_rusty_nail/items/b8ba525d31ea7c522856)
* Seleniumerといっていますが、Selenium, SauceLabs, Travis, Jenkinsに関するノウハウ書いているのでよかったら参考にしてみてください
Cybozu ガルーン API を golang で叩いてみる


golangで叩く
===========

[前回](http://qiita.com/yamasaki-masahide/items/fff1c84e65043ac4caf7)は手動で叩いたので、golangで叩く部分を書いてみる

golangには良さげなSOAPライブラリが無いので、
XMLの組み立ては手を抜いてtemplateエンジンを使うことに。

###リクエストbodyのテンプレートを用意

```go:
const SOAPRequest = `<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
 xmlns:base_services="http://wsdl.cybozu.co.jp/base/2008">
 <SOAP-ENV:Header>
  <Action SOAP-ENV:mustUnderstand="1" xmlns="http://schemas.xmlsoap.org/ws/2003/03/addressing">{{.Action}}</Action>
  <Security xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility"
   SOAP-ENV:mustUnderstand="1"
   xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext">
   <UsernameToken wsu:Id="id"><Username>{{.Username}}</Username><Password>{{.Password}}</Password></UsernameToken>
  </Security>
  <Timestamp SOAP-ENV:mustUnderstand="1" Id="id"
   xmlns="http://schemas.xmlsoap.org/ws/2002/07/utility">
   <Created>2037-08-12T14:45:00Z</Created>
   <Expires>2037-08-12T14:45:00Z</Expires>
  </Timestamp>
  <Locale>jp</Locale>
  </SOAP-ENV:Header><SOAP-ENV:Body>
  <{{.Action}}>
  {{.Parameters}}
 </{{.Action}}>
</SOAP-ENV:Body></SOAP-ENV:Envelope>
`

type APIParameters struct {
        Username, Password, Action, Parameters string
}

```

###Postしてみる

```go:
func main() {
        var api_parameters = APIParameters{"ID", "パスワード", "ScheduleGetEvents", `<parameters start="2014-01-01T08:00:00" end="2014-01-30T20:00:00" ></parameters>`}
        var url = "https://ほげほげほげ/grn.cgi/cbpapi/schedule/api?"

		//リクエストbodyのテンプレートを適用
        t := template.Must(template.New("SOAPRequest").Parse(SOAPRequest))
        body := bytes.NewBufferString("")
        err := t.Execute(body, api_parameters)
        if err != nil {
                log.Panicf("template.Execute: %#v", err)
        }
		
		// Postする
        response, err := http.Post(url, "text/xml; charset=utf-8", body)
        if err != nil {
                log.Panicf("http.Post: %#v", err)
        }

		//レスポンスを読み込んで表示
        b, err := ioutil.ReadAll(response.Body)
        response.Body.Close()
        if err != nil {
                log.Panicf("ioutil.ReadAll: %#v", err)
        }
        fmt.Printf(string(b))
        return
}

```

取れた。後はXMLをパースするだけ
Consulの名前解決にDNS Forwardingを使う方法

# BIND の DNS Forward で名前解決
## 概要
BIND の設定を変更し、特定ゾーン (.consul) に対しての問い合わせを Consul に対しておこなえるように変更します。通常の名前解決と Consul の名前解決を同時に行う事ができるため、アプリケーションやインフラ環境に加える必要はありません。また、[dnsmasq を併用する手法](http://pocketstudio.jp/log3/2014/05/01/consul_with_dnsmasq_name_resolution/)が使えない環境でも、容易に名前解決が可能です。

## Consul の名前解決と課題
[Consul](http://www.consul.io/) には名前解決をおこなうために、DNS インターフェースを備えています。しかし、通常の Consul が提供するインターフェースは、Port 8600 です。そのため、dig やアプリケーション側ではポート番号を明示する必要があります。

```
$ dig @sakura1.pocketstudio.net -p 8600 web.service.sakura.consul
(略)
;; QUESTION SECTION:
;web.service.sakura.consul.     IN      A

;; ANSWER SECTION:
web.service.sakura.consul. 30   IN      A       192.168.39.11
web.service.sakura.consul. 30   IN      A       192.168.39.13
```
しかし、アプリケーションで Consul の名前解決をおこなうためには、ポート番号を明示するようプログラム側の追加が必要です。また、通常の名前解決とはわける必要があるため、環境依存の問題が発生してしまう懸念もあります。

そこで、既存の名前解決と Consul の名前解決を BIND の DNS Forward 機能を使って解決します。通常の名前解決は BIND がおこないますが、Consul の管理するドメイン（トップレベルドメイン .consul. ）に対してのみ、Consul のインターフェースに問い合わせます。

この方法であれば、既存の名前解決環境に変更を加える必要がなく、利用者にとっては Consul の存在を気にする必要はありません。また、dnsmasq を使えないようなグローバルなネットワークでも、名前解決が利用出来ます。

## 準備
Consul 側の設定変更はありません。デフォルトの DNS ポート ( 8600 ) をインターフェースとで用いているものとします。

## BIND の設定

まずはじめに /etc/named.conf を開き、DNSSEC を無効にし、consul 用の config ファイルを読み込む (inlcude) 設定を追加します。DNSSEC を無効にしないと、BIND と Consul は通信が出来ないので注意してください。

以下は変更例です：


```named.conf
options {
        listen-on port 53 { 127.0.0.1; };
        listen-on-v6 port 53 { ::1; };
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        memstatistics-file "/var/named/data/named_mem_stats.txt";
        allow-transfer { 153.121.46.159; };
        allow-query     { localhost; };
        recursion yes;

        dnssec-enable no;
        dnssec-validation no;

};

include "/etc/named/consul.conf";
```
`dnssec-enable` と、`dnssec-validation` を、どちらも `no` にします。また `include "/etc/named/consul.conf"` 追記します。

次に、consul.conf を編集します。

``` /etc/named/ocnsul.conf
zone "consul" IN {
    type forward;
    forward only;
    forwarders { 127.0.0.1 port 8600; };
};
```
ここではローカルで動作する Consul を想定しているため、`127.0.0.1` と書きましたが、任意の IP アドレスを指定できます。

最後に、named の 再起動をおこないます。`rndc reload` または `service rndc reload` を実行します。

実行後に `dig` で動作確認をおこなうと、Consul の DNS インターフェースを指定しなくても、名前解決が出来る事がわかります。

```
$ dig @127.0.0.1 web.service.sakura.consul
(略)
;; QUESTION SECTION:
;web.service.sakura.consul.     IN      A

;; ANSWER SECTION:
web.service.sakura.consul. 30   IN      A       192.168.39.11
web.service.sakura.consul. 30   IN      A       192.168.39.13
```

## 参考
* Forwarding - Consul
 * http://www.consul.io/docs/guides/forwarding.html
* 実用 BIND 9で作るDNSサーバ（最終回）：BIND 9を徹底活用するためのTips集 (2/2) - ＠IT
 * http://www.atmarkit.co.jp/ait/articles/0405/15/news015_2.html
Windows8.1でVagrant


## Rubyのインストール

[Ruby Installer Download](http://rubyinstaller.org/downloads/)

2.0.0-p481 (x64)を入れた。

コマンドプロンプトで``ruby -v``で確認。


## Gitのインストール

[Git for Windows](http://msysgit.github.io/)

SSHクライアントのために入れる。
他にも``git clone``とか出来ないと何かと不便なので、入れておくべき。

インストーラーで色々と設定がいじれるけど、[Windows環境でGitを使う](http://www.02.246.ne.jp/~torutk/git/gitonwindows.html)を参考にして入れた。コミット時の改行コード設定のところはUnixスタイルにしておいたほうがいいと思う。
![commit.png](https://qiita-image-store.s3.amazonaws.com/0/2492/bcd4a8e5-1e6f-27db-d63e-5a54d6cd0ee8.png)

以降はコマンドプロンプトの代わりにGit Bashが使えるようになるので、こっちを使う。


## VirtualBoxのインストール

[Download VirtualBox](https://www.virtualbox.org/wiki/Downloads)

現時点の最新版は4.3.12。インストーラーを使って普通に入れた。

途中で仮想ネットワークデバイスを追加する関係で、ドライバのインストールが必要。たぶんAdministrator権限が無いとダメ。


## Vagrantのインストール

[DOWNLOAD VAGRANT](https://www.vagrantup.com/downloads.html)

最新版の1.6.3を入れた。インストール後に一度再起動がかかる。
ちょっと前まではgemでも提供されていたけど、今はインストーラー推奨。

``vagrant -v``で確認。

## 動作確認

[GETTING STARTED](https://docs.vagrantup.com/v2/getting-started/index.html)の手順を参考に仮想マシンを立てる。

```bash
$ mkdir vagranttest
$ cd vagranttest

$ vagrant init hashicorp/precise32

$ vagrant up

$ vagrant ssh
Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic-pae i686)

 * Documentation:  https://help.ubuntu.com/
Welcome to your Vagrant-built virtual machine.
Last login: Fri Sep 14 06:22:31 2012 from 10.0.2.2
vagrant@precise32:~$
```

Ubuntu12.04が立ち上がるみたい。
Amazon AWS 上でのホスト情報取得

Amazon AWS 上で ELB+AutoScaling を利用している場合など、ホスト情報が頻繁に変わってしまうのでホスト情報を取得するためのスクリプトです。
*aws* コマンドを実行して **running** 状態のインスタンス情報を出力しているだけですが結構便利です。

| Key | Value |
|:-----------|------------:|
| Name       |       ホスト名|


というタグが設定されている必要があります。

```:sh
region="--region ap-northeast-1"
output="--output text"
query="--query Reservations[*].Instances[*].[Tags[?Key==\`Name\`].Value,InstanceId,PublicIpAddress,PrivateIpAddress]"
filter="--filter Name=instance-state-name,Values=running"
aws="/usr/bin/aws ec2 describe-instances ${region} ${output} ${query} ${filter}"

${aws} | awk '{ if(NR % 2) ip = $0; else printf "%s     %s\n", $0, ip; }'
```
Heroku + PHP で Redis（Redis To Go）をセッションストレージに利用する


Heroku 環境で、PHP のセッションストレージとして、Redis（Redis To Go）を利用する手順です。

## Redis To Go アドオンを追加

Redis サーバとして、Redis To Go アドオンを利用します。（無料プラン（Nano）あり: 接続数上限=10 / データベース=1 / インスタンスサイズ=5MB）

[https://addons.heroku.com/redistogo](https://addons.heroku.com/redistogo)

```bash
$ heroku addons:add redistogo
```

## composer.json に redis 拡張を追加

Heroku 上の PHP で、redis 拡張を使うために `composer.json` に `redis` を追加しておきます。

```
{
  "require": {
    "ext-redis": "*"
  }
}
```

## 環境変数から接続情報を取得

Redis To Gos アドオンを追加すると、Redis To Go への接続情報が環境変数`REDISTOGO_URL`にセットされます。

`REDISTOGO_URL`の内容は下記のような URL の形式になっています。

```
REDISTOGO_URL=redis://redistogo:xxxxxxxxxxxxxxxxxxxxxxxx@xxxxx.redistogo.com:PORT/
```

これを PHP の`parse_url()`でパースします。

```php
<?php
$url = parse_url(getenv('REDISTOGO_URL'));
```

スクリプトを実行すると、`$url`の各要素には下記のようになります。

* $url['host'] = 接続ホスト名
* $url['port'] = 接続ポート
* $url['pass'] = 接続パスワード

この内容を接続情報として利用します。

## セッションハンドラに設定する

redis 拡張のセッションハンドラを`ini_set`で設定します。`session.save_path`には、環境変数から取得した値を元に接続情報を記載します。

パスワードを`auth=PASS`のようにクエリストリングで指定するのがポイントです。

```php
<?php
const SESSION_KEY = 'count';

$url = parse_url(getenv('REDISTOGO_URL'));

$redisServer = sprintf('tcp://%s:%d?auth=%s', $url['host'], $url['port'], $url['pass']);

ini_set('session.save_handler', 'redis');
ini_set('session.save_path', $redisServer);

// session
session_start();

if (empty($_SESSION[SESSION_KEY])) {
    $_SESSION[SESSION_KEY] = 0;
}

$_SESSION[SESSION_KEY]++;

var_dump($_SESSION);

```


## Laravel で接続する

まず、Redis サーバへの接続情報を`app/config/database.php`に接続情報をセットしています。

```php
<?php

$redisUrl = parse_url(getenv('REDISTOGO_URL'));

return [
    'redis' => [
        'cluster' => false,
        'default' => [
            'host' => $redisUrl['host'],
            'port' => $redisUrl['port'],
            'database' => 0,
            'password' => $redisUrl['pass'],
        ],
    ],
];
```

次に、`app/config/session.php`で、ドライバを、redis に設定します。

```php
<?php

return [
    'driver' => 'redis',
];
```

また、`app/config/cache.php`で、ドライバを redis にしておけば、キャッシュも Redis サーバに保存されます。

```php
<?php

return [
    'driver' => 'redis',
];
```
Simple Form を Bootstrap 3 に対応させる

概要
======

Simple Form をインストールした。
Bootstrap 3 もちゃんと設定した。
ボタンなどはちゃんと Bootstrap 3 のスタイルが適用されているのだけれども、
テキスト入力のエラーなどのスタイルが適用されていなくてツライ。

原因
=====

Simple Form が Bootstrap 3 に対応していない。

対応
=====

1. Simple Form のバージョンを上げる。
    
   ```Gemfile
gem 'simple_form', '>= 3.1.0rc'
    ```

   ```bash
% ./bin/bundle install
    ```

2. 初期化

    conflict すると思うので適宜上書きを。

    ```bash
% ./bin/rails generate simple_form:install --bootstrap
    conflict  config/initializers/simple_form.rb
Overwrite /.../config/initializers/simple_form.rb? (enter "h" for help) [Ynaqdh] Y
       force  config/initializers/simple_form.rb
    conflict  config/initializers/simple_form_bootstrap.rb
Overwrite /.../config/initializers/simple_form_bootstrap.rb? (enter "h" for help) [Ynaqdh] Y
       force  config/initializers/simple_form_bootstrap.rb
       exist  config/locales
    conflict  config/locales/simple_form.en.yml
Overwrite /.../config/locales/simple_form.en.yml? (enter "h" for help) [Ynaqdh] Y
       force  config/locales/simple_form.en.yml
   identical  lib/templates/haml/scaffold/_form.html.haml
===============================================================================

  Be sure to have a copy of the Bootstrap stylesheet available on your
  application, you can get it on http://getbootstrap.com/.

  Inside your views, use the 'simple_form_for' with one of the Bootstrap form
  classes, '.form-horizontal' or '.form-inline', as the following:

    = simple_form_for(@user, html: { class: 'form-horizontal' }) do |form|
===============================================================================
    ```


参考
=====

- [plataformatec/simple_form](https://github.com/plataformatec/simple_form)
- [Update the bootstrap generator to work with Bootstrap 3 · 4963374 · plataformatec/simple_form](https://github.com/plataformatec/simple_form/commit/4963374e7b448b25a98ee34aec1d9bf16a6c9028)
linuxコマンド備忘録

## 起動中のサービス確認
`systemctl list-units`でsystemdが管理するユニットを表示する。`--type`には`service`のほかに`socket`, `mount`, `device`を指定できる。

    systemctl list-units --type=service

## ファイルの文字コード変換
iconvコマンドを使うやり方。オプションは、-fが元の文字コード、-tが変換する文字コード、-oが出力するファイル名。
ex.) example.txtをsjisからutf-8にする。

    $ iconv -f sjis -t utf-8 example.txt -o example.txt

## xargsの引数の場所を指定する
通常はコマンドの最後の引数になるが、-iオプションを使うと、{}に引数を割り当てられる。
ex.）パスにoriginalを含むファイルを../bkにコピー。

    $ find . -type d | grep original | xargs -i mkdir -p ../bk/{}
    $ find . -type f | grep original | xargs -i cp -p {} ../bk/{}

## 空白を含むファイルのfind
findの結果に対してxargsで処理をさせるときに、ファイル名に空白を含む場合、エラーが発生する。
（空白を複数ファイルの区切り文字として扱うため）
オプションで`find -print0`、`xargs -0`とすると、区切り文字を空白でなく、\0で扱うため、問題を回避できる。

    $ find . -type f -print0 | xargs -0 md5sum | sort

## コマンド繰り返し
コマンドをsleep秒ごとに繰り返す。
`ctl + c`で終了。

    $ while true; do [コマンド]; sleep 1; done;

## cronでsudoを許可
デフォルトは、cronの処理中でのsudoは許可されていない。
Defaults requirettyをコメントにすると、許可される。

    $ sudo visudo
    
    #
    # Disable "ssh hostname sudo <cmd>", because it will show the password in clear.
    #         You have to run "ssh -t hostname sudo <cmd>".
    #
    #Defaults    requiretty

## psからプロセスをkill
ex.) tomcatをkill
pgrep：プロセスidをかえす
--no-run-if-empty：引数がない場合、実行しない

    $ pgrep -f tomcat | xargs --no-run-if-empty kill -9

## psの結果からgrepを除く
ex.) tomcatプロセスだけを表示

    $ ps -ef | grep tomcat | grep -v grep

## 秘密鍵作成
ex.) rsa方式暗号方式で鍵を作成

    $ ssh-keygen -t rsa

公開鍵は認証側サーバのauthorized_keysに追加。
.sshは権限700、authorized_keysは権限600とする。
バッチ処理等でssh接続を使う場合、パスフレーズの入力を求められて動かなくなるので、特別な理由がない限り、設定しないほうがいいと思う。

    $ mkdir ~/.ssh
    $ chmod 700 ~/.ssh
    $ cat id_rsa.pub >> ~/.ssh/authorized_keys
    $ chmod 600 ~/.ssh/authorized_keys

## ホストキーの削除
sshログインするとき、接続先サーバのホストキー（公開鍵のフィンガープリント）を保存し、照合するので、接続先サーバのIPアドレスが変わったりすると、不一致になり、sshログインできなくなる。
そんなときは、ホストキーを削除すると、再度ログイン可能になる。

    $ ssh-keygen -R [ホスト名]

## ディレクトリを再帰的にgrep
ex.) カレントディレクトリ以下のディレクトリのファイル「*.html」から文字列「height」を含むファイルを探す

    $ find . -name "*.html" | xargs grep height
express ではなく express-generator

node.jsを勉強し始めようと思い、入門書を読んだり、サイトを調べたりしました。
たいていの文献では、node本体をインストールした後、expressを導入すべし、と書いてあります。
手順はこうです。
c:\>npm install -g express

諸々のメッセージが出て、いかにも上手くインストールされたような感じです。
が、

c:\>express 
とたたくと、

'express' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
と出ます。

そりゃそうです。
expressが導入されたと思われる、下記のディレクトリを見ると、
C:\Users\xxxxxx\AppData\Roaming\npm\node_modules\express
express.exe とか express.cmd とか express.bat　とかが作成されていません。

で、色々と調べると、最近は express-generatorというのを導入すべきらしいです。

c:\>npm install -g express-generator

とやると、上手くいきました。

こちらのサイトを参考にしました。
http://yutapon.hatenablog.com/entry/2014/04/29/124657
laravel4 CustomValidator 

#CustomValidator

##拡張フォルダの作成

```zsh
%cd laravel/project/path
%cd app
%mkdir extensions
%cd extensions
```

##composerのautoload追加

```zsh
%cd laravel/project/path
%vi composer.json
```

```composer.json
    "autoload": {
        "classmap": [
            "app/commands",
            "app/controllers",
            "app/models",
            "app/database/migrations",
            "app/database/seeds",
            "app/tests/TestCase.php",
    　      "app/extensions"   //<-追加
        ]
```

###dump-autoloadを実行
```zsh
%composer dump-autoload
```

##CustomValidatorを作成

```zsh
%vi CustomValidator.php
```

```CustomValidator.php
<?php

class CustomValidator extends Illuminate\Validation\Validator {

    /*
    *   半角英字&空白
    */
    protected function validateAlphaSpace($attribute, $value)
    {
        return preg_match('/^[\pL\s]+$/',$value);
    }
    /*
    *  半角英字バリデーション　オーバーライド
    *  uオプション(unicode)を外す。
    */
    protected function validateAlpha($attribute, $value)
    {
        return preg_match('/^\pL+$/', $value);
    }
}
```

##カスタムバリデーターリゾルバーを登録する

```zsh
%cd laravel/project/path
%cd app/start
%vi global.php
```

```global.php
/*
*  カスタムバリデーターリゾルバー登録
*/

Validator::resolver(function($translator, $data, $rules, $messages)
{
    return new CustomValidator($translator, $data, $rules, $messages);
});
```
を追加

##エラーメッセージを追加

```zsh
%cd laravel/project/path
%cd app/lang/en
%vi validation.php
% diff validation.php validation.php.20140618
21d20
<       "alpha_space"      => ":attributeにはアルファベット、空白以外使用できません。",
```

##参考
http://laravel4.kore1server.com/docs/validation
http://qiita.com/ytake/items/f45c9a6e17daa12828f2
http://io.laravel.jp/forum/06-13-2014-alpha
KobitoをDropboxで共有するためのMakefile


~/Libray/Kobitoの中身をDropboxに入れて、シンボリックリンクでそのファイルを参照するようにしておけばいい。

昔のKobitoではKobito.dbだけあれば動いたが、いつからか仕様変更でKobito 1.9.1 では Kobito.db-shm, Kobito.db-walがないと動かなくなっていた。


# 使い方

1) Kobitoを終了する

2) これらをDropboxに放り込む

```console
$ cp -r ~/Library/Kobito ~/Dropbox/kobito
```

* CSS
* Kobito.db
* Kobito.db-shm
* Kobito.db-wal

3) このMakefileをDropbox内のKobito.dbがあるディレクトリで実行する


Makefileでは、各ファイルに対してシンボリックリンクを張るようにしている。Kobitoディレクトリに対してシンボリックリンクしたいところだが、そうするとKobitoがエラーで起動しなくなる。

```console
$ cd ~/Dropbox/kobito
$ vi Makefile
$ make
```

```mf:Makefile
CURRENT_DIR := $(shell pwd)
INSTALL_DIR := $(HOME)/Library/Kobito

all: cui

.PHONY: install
cui: install

install:
	test -d $(INSTALL_DIR) && mv -v $(INSTALL_DIR) ~/.Trash || true
	mkdir -p $(INSTALL_DIR)
	mkdir -p $(CURRENT_DIR)/CSS
	ln -fns $(CURRENT_DIR)/CSS $(INSTALL_DIR)/CSS
	ln -fns $(CURRENT_DIR)/Kobito.db $(INSTALL_DIR)/Kobito.db
	ln -fns $(CURRENT_DIR)/Kobito.db-shm $(INSTALL_DIR)/Kobito.db-shm
	ln -fns $(CURRENT_DIR)/Kobito.db-wal $(INSTALL_DIR)/Kobito.db-wal
```


4) Kobitoを起動する

以上で同期されるようになる。
Elasticsearchのmappingのkey名とtype名は合わせること


Elasticsearchでは、あるtypeのmappingを以下のようなAPIで定義できるが、
type名（article）とjsonのkey名を一致させる必要があるらしい。

```shellscript
# test1というindexにarticleというtypeを定義
$ curl -XPUT 'http://localhost:9200/test1/article/_mapping' -d '@article.json'
```

つまり

```javascript
//これはOK
// article.json
{
    article : {
        properties : {
            article_id : {
                type : "string",
                index : "not_analyzed"
            },
            title : {
                type : "string"
            }
        }
    }
}

//これはNG
// article.json
{
    hoge : {
        properties : {
            article_id : {
                type : "string",
                index : "not_analyzed"
            },
            title : {
                type : "string"
            }
        }
    }
}
```



#### 検証ログ
```shellscript
$ elasticsearch -v
Version: 1.0.0, ...
 
# jsonのpropertiesの親のkeyはhoge
$ cat article.json
{
    hoge : {
        properties : {
            article_id : {
                type : "string",
                index : "not_analyzed"
            },
            title : {
                type : "string"
            }
        }
    }
}
 
# test1というindexに、articleというtypeを定義
$ curl -XPUT 'http://localhost:9200/test1/article/_mapping' -d '@article.json'
{"ok":true,"acknowledged":true}
 
# 定義できてない。。
$ curl -XGET 'http://localhost:9200/test1/article/_mapping'
{
    "test1":{
        "mappings":{
            "article":{
                "properties":{}
            }
        }
    }
}
 ```

#### 0.90系での検証
https://gist.github.com/ise/d0afdcb43dc02338a0ad
GitHub multiple account 設定


#github の複数アカウント作成

github での複数アカウントの登録をしたときのメモです。

##新しいアカウント用の SSH Key をつくる

まずは `.ssh` ディレクトリに移動して、

```
$ cd ~/.ssh/
```

SSH Key を作成します。

```
$ ssh-keygen -t rsa -C 'mail-address@example.com'
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/me/.ssh/id_rsa): /Users/me/.ssh/id_rsa_second
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/me/.ssh/id_rsa_second.
Your public key has been saved in /Users/me/.ssh/id_rsa_second.pub.
The key fingerprint is:
7d:34:b3:a5:9e:b8:13:d4:d8:a9:4c:fc:ae:1d:a2:d1 mail-address@example.com
The key's randomart image is:
+--[ RSA 2048]----+
|                 |
|                 |
|           o+... |
|         ...=*o  |
|        S..++o   |
|          .=o..  |
|          o.N..  |
|          .+ o.. |
|          o....  |
+-----------------+
```

どこに key を保存するかを途中で聞かれるので、現在使っている key とは別の名前になるように、ファイル名を指定してください。

```
Enter file in which to save the key (/Users/me/.ssh/id_rsa): /Users/me/.ssh/id_rsa_second
```

##新しい SSH key を GitHub に登録

GitHub の2つ目のアカウントに、新しく作った SSH key を登録します。

```
$ cat id_rsa_second.pub
```

public key をコピーして、
GitHub の Acount settings の SSH keys ページから登録します。

##SSH 接続する際のパスワード入力を省略

`ssh-agent` を使って秘密鍵を登録して、
次回から SSH 接続するときにパスワードを入力する手間を省いておきます。

```
$ eval `ssh-agent`
Agent pid 4586

$ ssh-add ~/.ssh/id_rsa_second
Enter passphrase for id_rsa_second:
Identity added: id_rsa_second (id_rsa_second)
```


##それぞれの SSH key のホスト名を設定

`~/.ssh/config` ファイルにホスト名を設定します。
ファイルがなかったら作ってあげてください。

```
$ touch ~/.ssh/config
```

以下のようにホスト名を設定します。

```
$ vi ~/.ssh/config
```

```
# github first account
Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_rsa
  IdentitiesOnly yes

# github second account
Host github.com-second
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_rsa_second
  IdentitiesOnly yes
```

ホスト名 `Host github.com` `Host github.com-second` のところは、
自分が区別がつく名前であればOKです。


##GitHub に別アカウントとして認識されているかを確認

それぞれのホスト名を使って、GitHub に SSH 接続をしてみます。

```
$ ssh -T git@github.com
Hi user_name! You've successfully authenticated, but GitHub does not provide shell access.

$ ssh -T git@github.com-second
Hi second_name! You've successfully authenticated, but GitHub does not provide shell access.
```

上記のように表示されれば大丈夫です。

##アカウントを指定して git コマンドを使う

git コマンドでの操作は、それぞれ以下のようになります。
先ほどのホスト名を指定してあげるだけで OK です。

新しくリモートリポジトリを登録するとき：

```
$ git remote add origin git@github.com-second:hoge/repo_name.git
```

既存のリポジトリをクローンしてくるとき：

```
$ git clone git@github.com-second:hoge/repo_name.git
```

現在のリポジトリの置き場所（リモートリポジトリの URL）を変更するとき：

```
$ git remote set-url origin git@github.com-second:hoge/repo_name.git

$ git config -l | grep url
remote.origin.url=git@github.com-second:hoge/repo_name.git
```



（記事は、2012/05/18 時点での内容です）
***

[参考にしたURL]

★Quick Tip: How to Work with GitHub and Multiple Accounts - net.tutsplus.com
http://net.tutsplus.com/tutorials/tools-and-tips/how-to-work-with-github-and-multiple-accounts/


★githubで複数ユーザを使い分ける - 文殊堂
http://d.hatena.ne.jp/monjudoh/20110411/1302521587

参考にさせていただきました。ありがとうございます。
CloudWatch でディスク容量の監視

CloudWatch には標準では EC2 インスタンスのディスク容量チェック用のmetricsが存在しませんが、EC2 からディスク容量情報を CloudWatch に通知する事により CloudWatch で監視する事が可能です。

EC2 から CloudWatch へのディスク容量情報の通知は、Amazon Linux では標準で搭載されている *aws* コマンドを利用します。

当初は Java により記述された */opt/aws/bin/mon-put-data* コマンドを利用していましたが、 *aws* コマンドであれば **IAM role** にも対応しているので *aws* コマンドを利用しています。

**IAM role** の対象ではない EC2 インスタンスで *aws* コマンドを利用する場合はアクセスキーやシークレットキーを保存するために

```
$ aws configure
```

を実行してアクセスキーやシークレットキーを保存する必要がありますが、 **IAM role** の対象となっている EC2 インスタンスではそれらの設定は不要です。

```
$ aws configure
```
を実行してデフォルトのリージョンと出力フォーマットを指定する事もできますが、どちらもコマンドラインから指定可能ですので、今回はコマンドラインから指定します。

以下のコマンドを実行する事で CloudWatch の **System/Linux** というネームスペースにディスク容量を通知できます。
CloudWatch では  **System/Linux** から **FreeSpaceMBytes** もしくは **UsedSpacePercent** という Metrics を指定する事で監視ができます。


```:sh
#!/bin/sh

# ディスク容量を取得するパス
path=${1:-/}

# EC2 のインスタンス ID を取得
instanceid=`wget -q -O - http://169.254.169.254/latest/meta-data/instance-id`

# コマンド定義
region="--region ap-northeast-1"
namespace="--namespace System/Linux"
dimensions="--dimensions InstanceId=${instanceid},Path=${path}"
aws="/usr/bin/aws cloudwatch put-metric-data ${region} ${namespace} ${dimensions}"

# ディスク容量を MB 単位で取得
${aws} ${monput} --unit Megabytes --metric-name "FreeSpaceMBytes"  --value `df --block-size=1M ${path} |
	awk '$NF == "'${path}'" { print $(NF-2) }'`
# ディスク容量を % 単位で取得
${aws} ${monput} --unit Percent --metric-name "UsedSpacePercent" --value `df --block-size=1M ${path} |
	awk '$NF == "'${path}'" { print substr($(NF-1), 1, length($(NF-1)-1)) }'`
```

*cron* に登録する等で定期的にディスク容量を取得して CloudWatch に通知すると良いでしょう。
ImageMagick で 画像リサイズと画質落としつつ gif アニメーションを作る

何も考えない場合

```bash
convert -delay 25 -loop 0 ( 01.jpg 02.jpg 03.jpg 04.jpg ) out_1.gif
```

50%にリサイズする場合

```bash
convert -delay 25 -loop 0 ( 01.jpg 02.jpg 03.jpg 04.jpg ) ( -resize 50% ) out_2.gif
```

50%にリサイズ＆32色に落とす場合

```bash
convert -delay 25 -loop 0 ( 01.jpg 02.jpg 03.jpg 04.jpg ) ( -resize 50% -colors 32 ) out_3.gif
```

```( )``` を使うことでグルーピングが可能。最後の例では 01.jpg～04.jpg に対して リサイズ＆色数変更 を行った後 gifに変換。

PHP使って簡単なベンチマーク取った。高画質のjpeg画像からgifアニメーション作るコストは結構高い。一見余計なリサイズ＆画質変換処理を加えたほうが短時間で済む。

```php
<?php
 
// imagemagick バージョン情報出力
exec( "convert --version", $version );
echo implode( "\n", $version ), "\n";
 
// 通常
$s = microtime( true );
exec( "convert -delay 25 -loop 0 \( 01.jpg 02.jpg 03.jpg 04.jpg \) out_1.gif" );
$e = microtime( true );
echo "#1 : ", ($e-$s), "\n";
 
// 50%リサイズ
$s = microtime( true );
exec( "convert -delay 25 -loop 0 \( 01.jpg 02.jpg 03.jpg 04.jpg \) \( -resize 50% \) out_2.gif" );
$e = microtime( true );
echo "#2 : ", ($e-$s), "\n";
 
// 50%リサイズ＆32色
$s = microtime( true );
exec( "convert -delay 25 -loop 0 \( 01.jpg 02.jpg 03.jpg 04.jpg \) \( -resize 50% -colors 32 \) out_3.gif" );
$e = microtime( true );
echo "#3 : ", ($e-$s), "\n";
```

```
Version: ImageMagick 6.8.1-0 2012-12-17 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2013 ImageMagick Studio LLC
Features: OpenMP
 
#1 : 1.4550831317902
#2 : 0.72604203224182
#3 : 0.45802593231201
```
PowerDNS recursorが内向きDNSサーバで設定一番簡単

# インストール

## 1. インストール

```bash:インストール
$ sudo apt-get install -y pdns-recursor
```

```bash:macの場合
$ brew install pdnsrec
# 設定ファイルは /usr/local/etc/powerdns/recursor.conf
```

## 2. 設定

[PowerDNS Authoritative Serverで再帰問い合わせを有効にする。 — ペンギンと愉快な機械の日々](http://d.palmtb.net/2012/06/19/enable_recoursion_pdns-server.html)が詳しい。

```diff:/etc/powerdns/recursor.conf
+export-etc-hosts=on # /etc/hosts をDNS登録する。
-local-address=127.0.0.1
+local-address=0.0.0.0 # 他のサーバからも問い合わせられるようにする。
+recursor=8.8.8.8 # DNS再帰問い合わせ先
```

```bash:IPアドレス帯に応じて以下も修正する。
allow-from=127.0.0.0/8, 10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fe80::/10
```

## 3. restart

```bash:
$ sudo /etc/init.d/pdns-recursor restart
```

# 問い合わせ

* 192.168.0.52がpdns-recursorが稼働しているサーバとする。

## /etc/resolv.confを修正

```bash:pdns-recursorが稼働しているサーバの場合
search local
nameserver 127.0.0.1
```

```bash:その他のサーバの場合
search local
nameserver 192.168.0.52
```

## 他のサーバから動作確認

```bash:192.168.0.52の/etc/hostsの内容が問い合わせられることを確認。
$ nslookup
> dnssv
Server:		192.168.0.52
Address:	192.168.0.52#53

Non-authoritative answer:
Name:	dnssv.local
Address: 192.168.0.52
> 192.168.0.52
Server:		192.168.0.52
Address:	192.168.0.52#53

Non-authoritative answer:
52.0.168.192.in-addr.arpa	name = dnssv.
52.0.168.192.in-addr.arpa	name = dnssv.local.

Authoritative answers can be found from:
```

```bash:/etc/hosts以外のも問い合わせられることを確認。
$ nslookup
> google.co.jp
Server:		192.168.0.52
Address:	192.168.0.52#53

Non-authoritative answer:
Name:	google.co.jp
Address: 173.194.126.239
Name:	google.co.jp
Address: 173.194.126.247
Name:	google.co.jp
Address: 173.194.126.248
```

# /etc/hosts修正の反映

```bash:リスタートすればよい
$ sudo /etc/init.d/pdns-recursor restart
```
Javaで日付だけを比較

```java
import java.util.Date;
import java.text.SimpleDateFormat;

// 今日と特定の日を比較したい
Date today = new Date(); // 比較対象1 Wed Jun 18 08:52:41 JST 2014
String certainDay = "2014-06-18"; // 比較対象2

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date cdDate = sdf.parse(certainDay);

// 時刻を気にせずに、日付だけ比較したいが・・・
System.out.println(today.after(cdDate)); // falseになってほしいがtrue
System.out.println(today.before(cdDate)); // false
System.out.println(today.compareTo(cdDate)); // 0になってほしいが1
```

予期した結果が出ないのは、
todayは現在時刻を指しているのに、
certainDayは6月18日の00時00分00秒を指しているから。

DBの値と現在時刻を比較する必要があるような時、
DBの値が「yyyy-MM-dd」(時分秒を持っていない)の形式の日付型だった場合、
現在時刻を取得した後は時分秒を取り除いてから比較する必要があります。

そこで

```java
import java.util.Date;
import org.apache.commons.lang.time.DateUtils;

Date now = new Date(); // 2014-06-18 09:53:12
Date truncYear = DateUtils.truncate(now, Calendar.YEAR); // 2014-01-01 00:00:00
Date truncMonth = DateUtils.truncate(now, Calendar.MONTH); // 2014-06-01 00:00:00
Date truncDay = DateUtils.truncate(now, Calendar.DAY_OF_MONTH); // 2014-06-18 00:00:00

```

参考
http://javatechnology.net/java/dateutils-truncate/


ちなみに、Joda-Timeというライブラリもあるらしい。

```java
import org.joda.time.DateTime;
import org.joda.time.DateTimeFormat;

DateTime tdy = new DateTime(); // 2014-06-18T09:12:35.776+09:00
today = tdy.toString("yyyy-MM-dd"); // 2014-06-18

DateTimeFormat.forPattern("yyyy-MM-dd").parseDateTime("2011-10-31");
```


参考
http://www.mwsoft.jp/programming/java/joda_time_sample.html
Re: Dongri's Blog - docker-sharing

[Dongri's Blog - docker-sharing](http://dongri.github.io/articles/2014/06/17/docker-sharing/) 用の Vagrantfile はこんな感じでどうでしょうか？

```ruby:Vagrantfile
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.define "boot2docker"

  config.vm.box = "yungsang/boot2docker"

  config.vm.network :forwarded_port, guest: 2375, host: 4243, disabled: true

  config.vm.network :private_network, ip: "192.168.33.10"

  config.vm.synced_folder ".", "/var/app", type: "nfs"

  # Fix busybox/udhcpc issue
  config.vm.provision :shell do |s|
    s.inline = <<-EOT
      if ! grep -qs ^nameserver /etc/resolv.conf; then
        sudo /sbin/udhcpc
      fi
      cat /etc/resolv.conf
    EOT
  end

  # Adjust datetime after suspend and resume
  config.vm.provision :shell do |s|
    s.inline = <<-EOT
      sudo /usr/local/bin/ntpclient -s -h pool.ntp.org
      date
    EOT
  end

  config.vm.provision :shell do |s|
    s.inline = <<-EOT
      docker rm -f nodejs || true
    EOT
  end

  config.vm.provision :docker do |d|
    d.build_image "/var/app/node/", args: "-t dongri/node"
    d.run "nodejs", image: "dongri/node", args: "-p 3000:3000"
  end

  config.vm.network :forwarded_port, guest: 3000, host: 3000
end
```

```
$ git clone git@github.com:dongri/Dockerfiles.git
$ cd Dockerfiles
$ edit Vagrantfile
$ vagrant up
$ open http://localhost:3000
```

あとはコードを修正したら `vagrant provision` をやる感じで。
ChromeでPDFを表示する（ダウンロードウィンドウを表示しない方法）

##PDFはChromeですぐに見たい
PDFのビューワはChromeに設定しています。
Ad●be ReaderよりChromeでPDFを見た方が軽い＆早いと個人的には思っています。

WebでPDFを見ようとするとダウンロードウィンドウが表示されることがあります。
もぅﾏﾁﾞ無理。 ﾘｽｶしょ・・・

##レスポンスヘッダを書き換える
Chromeのオレオレ拡張で、ダウンロードを強制させるレスポンスヘッダを書き換えます。
PDFがそのままChromeで表示されて、うれしい！楽しい！大好き！抱いて！となります。

```js:background.js
handler = function (details) {
	
	// Content-Disposition : attachmentを書き換える
	for (var i = 0, l = details.responseHeaders.length; i < l; ++i) {
		var header = details.responseHeaders[i];
		if (header.name === 'Content-Disposition' && header.value === 'attachment') {
			header.value = 'inline';
			break;
		}
	}
	
	return { responseHeaders: details.responseHeaders };
};

chrome.webRequest.onHeadersReceived.addListener(handler, {
	urls: [ "<all_urls>" ], 
	types: ["main_frame", "sub_frame"]
},  [ "responseHeaders", "blocking" ]);

```

###注意
上記をそのままコピペするとPDF以外のContent-Dispositionもinlineになってしまいます。
使用の際はご自分にあわせた制限をおかけください。
MySQL備忘録

## キャッシュのクリア

    mysql> RESET QUERY CACHE; 

## キャッシュの確認
Qcache_queries_in_cacheがキャッシュに登録されたクエリ数なので、この値が0になっていれば、キャッシュはクリアされている。

    mysql> SHOW STATUS LIKE 'Qcache%';


## インデックスの確認

    mysql> show index from [テーブル名];

## sql結果のcsv出力
postgresはコマンド実行時にオプション指定できるのだけど、mysqlはsqlに出力ファイルとセットで組み込まないといけないので残念。
`into outfile`　出力ファイル名
`fields terminated by`　セパレータ
`optionally enclosed by`　文字列型の囲み文字（数値型は囲われなかった）

    mysql> select * from hoge into outfile "/tmp/hoge.csv" fields terminated by ',' optionally enclosed by '"';

## auto_incrementの変更
確認：AUTO_INCREMENTカラムの値を確認

    mysql> show table status like '[テーブル名]';

変更：設定した値が次に割り当てられる数。

    mysql> alter table [テーブル名] auto_increment=[数字];


## ファイルのsql実行（mysqlコマンドで）
※-pのあとはスペースしない
　-pのあとにパスワードを入力しない場合、対話形式でパスワードを入力する
※utf-8の場合

    $ mysql -h [ホスト名] -u [ユーザ名] -p[パスワード] --default-character-set=utf8 [データベース名] < [入力ファイル名]

## ファイルのsql実行（mysqlコマンド後）

    mysql > source [ファイル名]

## エクスポート
※-pのあとはスペースしない
　-pのあとにパスワードを入力しない場合、対話形式でパスワードを入力する

    $ mysqldump -h [ホスト名] -u [ユーザ名] -p[パスワード] [データベース名] > [出力ファイル名]

## コマンドラインからSQL実行
※-pのあとはスペースしない

    $ mysql -u [ユーザ名] -p[パスワード] [データベース名] -e [クエリ]

## ログイン
※-pのあとはスペースしない
　-pのあとにパスワードを入力しない場合、対話形式でパスワードを入力する

    $ mysql -h [ホスト名] -u [ユーザ名] -p[パスワード] [データベース名]
サーバの基礎: httpd(apache)の認証設定

# httpdの認証設定

## 認証方式
* BASIC認証
  - HTTPプロトコルの基本認証とも言われる
  - ほぼ全てのWebサーバ/クライアントが対応
  - ユーザー名とパスワードがそのままネットワーク上を流れるので改ざん・盗聴される可能性あり
  - ユーザー登録コマンド(htpasswd)は対話形式 or コマンド1発 
* DIGEST認証
  - BASIC認証から安全性を高めた認証方式
  - ユーザー名とハッシュ(パスワードやランダム文字列から算出)を用いるため、第3者によるパスワードの推定が困難
  - ユーザー登録コマンド(htdigest)は対話形式

# BASIC認証の設定
http://HOSTNAME/aaa/bbb 対してBASIC認証を有効にする手順を説明する
以下操作はrootユーザーで実施する

## httpdの設定ファイル編集

下記を記述した /etc/httpd/conf.d/auth_basic.conf を作成

 ~~~apacheconf:/etc/httpd/conf.d/auth_basic.conf
 <Location /aaa/bbb>
    # 認証方式
    AuthType Basic
    # 認証時の表示メッセージ
    AuthName "Auth Test1"
    # 認証用パスワードファイル
    AuthUserFile /var/www/.htpasswd
    # 認証を許可するユーザー (valid-userなら登録された全ユーザー許可).
    Require valid-user
 </Location>
 ~~~

## パスワードファイルの作成
下記コマンドで /var/www/.htpasswd (auth_basic.confで指定した場所) にパスワードファイルを作成


 ~~~bash
 $> htpasswd -cb /var/www/.htpasswd <ユーザー名> <パスワード>
 ~~~

更にユーザーを追加する場合は下記コマンドを実施.

 ~~~bash
 $> htpasswd -b /var/www/.htpasswd <ユーザー名> <パスワード>
 ~~~

※ パスワードファイルは **サーバ外部からアクセスできない場所** に配置すること


## 設定反映
下記コマンドでhttpdに設定内容を反映

 ~~~bash
 $> /etc/init.d/httpd reload
 ~~~

## 動作確認
http://HOSTNAME/aaa/bbbをブラウザで表示して認証ダイアログ出たら以下を確認.

* 登録済ユーザー名 & 正しいパスワード => 認証OK
* 登録済ユーザー名 & 間違いパスワード => 認証NG
* 未登録ユーザー名 & テキトーなパスワード => 認証NG


# DIGEST認証
http://HOSTNAME/ccc/ddd に対してDIGEST認証を有効にする手順を説明する.
以下操作はrootユーザーで実施する.

## httpdの設定ファイルの編集

下記内容を記述した /etc/httpd/conf.d/auth_digest.conf を作成.

~~~apacheconf:/etc/httpd/conf.d/auth_digest.conf
<Location "/ccc/ddd">
  # 認証方式
  AuthType Digest
  # 認証時の表示メッセージ
  AuthName "Auth Test2"
  # 認証用パスワードファイル
  AuthUserFile /var/www/.htdigest
  # 認証を許可するユーザー (valid-userなら登録された全ユーザー許可)
  Require valid-user
</Location>
~~~

## パスワードファイルの作成
下記コマンドで /var/www/.htdigest (auth_digest.confで指定した場所) にパスワードファイルを作成

~~~bash
$> htdigest -c /var/www/.htdigest "Auth Test2" <ユーザー名>
   (*) "Auth Test2" の部分はauth_digest.confのAuthNameと同じ.

>> 以下対話形式でパスワードを入力
Adding user ユーザー名 in realm Authorization
New password:         << パスワード入力
Re-type new password: << パスワード入力 (確認用)
~~~

更にユーザーを追加したい場合は以下コマンドで追加

~~~bash
$> htdigest /var/www/.htdigest "Auth Test2" <ユーザー名>

>> 以下対話形式でパスワード入力
~~~

※ BASIC認証同様、このパスワードファイルも **外部からアクセスできない場所** に配置すること.


## 設定反映
下記コマンドでhttpdに設定を反映.

~~~bash
$> /etc/init.d/httpd restart
~~~

## 動作確認
http://HOSTNAME/ccc/dddをブラウザで表示して認証ダイアログが出たら以下を確認.

* ダイアログの表示メッセージ = auth_digest.conf の AuthName
* 登録済ユーザー名 & 正しいパスワード => 認証OK
* 登録済ユーザー名 & 間違いパスワード => 認証NG
* 未登録ユーザー名 & テキトーなパスワード => 認証NG
xcode6βでアプリを実機で実行する方法

自分も最初なんでだろうと思いつつ注意していなかった部分なのでまとめる。
iOS開発が初心者の人はここでつまずいたりということもあると思います。
実機でアプリを動かすにはその実機のOSのバージョンにアプリを合わせなくてはいけません。
じゃあそれはどうやるのか。

#Deployment Targetを実機のOSのバージョンに合わせる
xcodeの左側のNavigationバー（ソースファイルとかが見えるバー）の一番上のプロジェクト名の青いアイコンのところをクリックします。
すると各種設定の画面が出て、タブにGeneral, Capabilities, Info...と出るのでGeneralを開きます。(出ない場合はTargetsのプロジェクト名のところをクリック)
その中のDeployment InfoのDeployment Targetがプルダウンになっていてデフォルトが8.0になっていると思われます。
自分の実機のOSバージョンに合わせると実機で実行が可能になります。

OSをβ版の8.0にもうアップデートしたよ！って人は問題無いかと思いますが、まだ移行している人はこの手順を踏む必要があります。
条件が満たされるまで待機の条件(ExpectedConditions)を増やす

##条件クラス(ExpectedConditions)
Seleniumで「特定の条件が満たされるまで待機する」をよく使います。
locatorが見えるまで待機するコードはこんな感じ。簡単。

```csharp:Test.cs
public void WaitUntilElementIsVisible(By locator)
{
    wait.Until(ExpectedConditions.ElementIsVisible(locator));
}
```

##locatorが見えなくなる条件クラス
C#版だと条件クラス(ExpectedConditions)が貧相なので、新たにメソッドを作りました。

※Javaにはnot(ExpectedCondition)メソッドがいるので不要です。（[Java: ExpectedConditions](http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html)）

```csharp:ExpectedConditionsEx.cs
public static Func<IWebDriver, IWebElement> ElementIsInvisible(By locator)
{
    return (driver) =>
    {
        try
        {
            // 探す
            ReadOnlyCollection<IWebElement> elements = driver.FindElements(locator);
            
            // 見えてる要素に絞り込む
            List<IWebElement> result = elements.Where(e => e.Displayed).ToList();
            
            // なくなる or 全部見えなくなるはず
            if (result.Count == 0)
                // ダミーとしてページのルート要素を返す
                return driver.FindElement(By.CssSelector(":root"));
            else
                return null;
        }
        catch (StaleElementReferenceException)
        {
            return null;
        }
    };
}

```
ExpectedConditions.ElementIsInvisibleはデフォルトでいてもよいと思う。
[C#: ExpectedConditions](http://selenium.googlecode.com/svn/trunk/docs/api/dotnet/html/AllMembers_T_OpenQA_Selenium_Support_UI_ExpectedConditions.htm)



##条件をひっくり返すメソッド Not(ExpectedCondition)　
条件を否定してTrue/Falseを入れ替えるメソッド
JavaのNot(ExpectedCondition)をC#でも作れば良いのでは。

```csharp:ExpectedConditionsEx.cs
public static Func<IWebDriver, IWebElement> Not(Func<IWebDriver, IWebElement> condition)
{
    return (driver) =>
    {
        IWebElement e = condition.Invoke(driver);
        return e == null ? driver.FindElement(By.CssSelector(":root")) : null;
    };
}

public static Func<IWebDriver, bool> Not(Func<IWebDriver, bool> condition)
{
    return (driver) => !condition.Invoke(driver);
}

```

##ページがロードされるまで待つ
指定されたタイトルが現れるまで待ち、処理を開始します。便利。

```csharp:ExpectedConditionsEx.cs
public static Func<IWebDriver, bool> TitleIs(string title)
{
    return (driver) =>
    {
        try
        {
            return driver.Title == title;
        }
        catch (Exception)
        {
            return false;
        }
    };
}

public static Func<IWebDriver, bool> TitleStartsWith(string title)
{
    return (driver) =>
    {
        try
        {
            return driver.Title.StartsWith(title);
        }
        catch (Exception)
        {
            return false;
        }
    };
}
```

##アラートが表示されるまで待つ
※ブラクラ複数アラート状態で使うと、おそらく想定通りに動きません。

```csharp:ExpectedConditionsEx.cs
public static Func<IWebDriver, bool> AlertIsVisible()
{
    return (driver) =>
    {
        try
        {
            driver.SwitchTo().Alert();
            return true;
        }
        catch (NoAlertPresentException)
        {
            return false;
        }
    };
}
```

##雑感
ダミーのIWebElementを返すには何が良いのだろう。
javascriptで末尾再帰をやってみて覚えたこと

# はじめに

@phi さんの「[[JavaScript] 再帰呼出しで階乗(Factorial)を求めてみよう](http://qiita.com/phi/items/ccfc8b3f7958e7c0d8d6)」のエントリーで、[末尾再帰](http://ja.wikipedia.org/wiki/%E6%9C%AB%E5%B0%BE%E5%86%8D%E5%B8%B0)というやつを思い出して、
もともと自分は[OCaml](http://qiita.com/tags/ocaml)を去年いじり始めてで知った再帰呼び出しを思い出して、JavaScriptでもやってみた。正直、消化できていない

# 階乗を末尾再帰で実装してみる

```js
// forked from phi's "再帰呼出しで階乗(Factorial)を求めてみよう" http://jsdo.it/phi/4X8T
// 階乗
var factorial = function(num,acc) {
    acc = acc||1
    return (num <= 0) ? acc : (factorial(num-1,acc*num));
};

console.log( factorial(0) );    // 1
console.log( factorial(5) );    // 120
console.log( factorial(6) );    // 720
console.log( factorial(7) );    // 5040
```

[jsdo.itのコード](http://jsdo.it/kjunichi/a4EI)

# 覚えたこと

JavaScriptでのデフォルト引数の実装

```js
acc = acc||1
```

これで、引数の指定が無ければ、1が設定される。
ただし、[JavaScript言語自体にデフォルト引数がサポートされている
訳ではないので、必ずしも意図した動きになるとは限らないケースも
あるとのこと](http://qiita.com/VoQn/items/3a4a8c0ad11e45c64907)。

# まとめ

ということで、OCamlでシダをはやそうとしていることがバレないうちに今回のまとめ。

JavaScriptだと効果があるのか、@phi さんのと、較べて、多少早い結果も出たようにも見えたが、イマイチベンチマークテストは苦手なので、よくわからないw

[Pythonなんかだと末尾再帰の形にできると、通常だとスタックオーバーフローするコードが実行出来るようになったりメリットが出ることもある模様](http://wasabiz.hatenablog.com/entry/20110118/1295335821)

# Link
CentOS7 public QA のインストール手順

* [seven.centos.org](http://seven.centos.org) にて公開されています。
* バグ報告は[こちら](http://bugs.centos.org/my_view_page.php)。
* リポジトリが混み合っているのか遅いです。

# インストール手順

## 1. isoをダウンロード

* [boot.iso](http://buildlogs.centos.org/centos/7/os/x86_64-20140614/images/)をダウンロード
* VirtualBoxなどで起動。

## 2. ネットワークを有効化

* eth0ではなく、enp0s3と表示される。

![スクリーンショット 2014-06-18 6.28.11.png](https://qiita-image-store.s3.amazonaws.com/0/25728/ae44545f-08c4-99e1-dcfe-6edc110c749e.png)

## 3. リポジトリの設定

![スクリーンショット 2014-06-18 6.28.06.png](https://qiita-image-store.s3.amazonaws.com/0/25728/180c9781-da4e-14f1-455b-220c5680055d.png)

* http://buildlogs.centos.org/centos/7/os/x86_64-20140614/
  を指定する。
* http://buildlogs.centos.org/centos/7/os/x86_64-latest
  が存在しなかったのでちょっとハマった。
* ミラーがほしい

## 4. ソフトウェアの選択

![スクリーンショット 2014-06-18 6.27.49.png](https://qiita-image-store.s3.amazonaws.com/0/25728/5ad0af4f-f461-e6c3-0568-e7d59078b7c3.png)

お好きに。

## 5. あとはガイドに従いインストール。

## 6. インストール後、リポジトリの追加

```bash:/etc/yum.repos.d/CentOS-Base.repo
[centos-qa-04]
name=CentOSQA
baseurl=http://buildlogs.centos.org/c7.00.04/
```

contribがないのでパッケージあまりないです。

---

# kickstartサンプル

* https://git.centos.org/summary/sig-core!livemedia.git
自分的Docker用エイリアス

[Dockerを便利に使うためのalias | SOTA](http://deeeet.com/writing/2014/03/30/docker-alias/) を参考にさせていただきながら自分なりのエイリアスを作ってみた。

```bash:.bashrc
# ------------------------------------
# Docker aliases
# ------------------------------------

alias d="docker"

# Get the latest container ID
alias dl="docker ps --latest --quiet"

# List containers
alias dps="docker ps"

# List containers including stopped containers
alias dpa="docker ps --all"

# List images
alias di="docker images"

# List images including intermediates
alias dia="docker images --all"

# Tree images including intermediates
alias dit="docker images --tree"

# Get an IPaddress of a container
alias dip="docker inspect --format '{{ .NetworkSettings.IPAddress }}'"

# Run a daemonized container
alias drd="docker run --detach --publish-all"

# Run an interactive container 
alias dri="docker run --interactive --tty --publish-all"

# Remove all containers
alias drm='docker rm $(docker ps --all --quiet)'

# Remove all images
alias drmi='docker rmi $(docker images --quiet)'

# Remove all containers and images by force
alias dclean='docker kill $(docker ps --all --quiet); drm; drmi;'

# List all aliases relating to docker
dalias() { alias | grep 'docker' | sed "s/^\([^=]*\)='\(.*\)'/\1 	=> \2/"| sed "s/'\\\'//g"; }
```

※) 最後の `/\1    =>` の部分は `スペース1＋タブ1` にしてみました。

```bash
$ dalias
alias d 		=> docker
alias dclean 	=> docker kill $(docker ps --all --quiet); drm; drmi;
alias di 		=> docker images
alias dia 		=> docker images --all
alias dip 		=> docker inspect --format '{{ .NetworkSettings.IPAddress }}'
alias dit 		=> docker images --tree
alias dl 		=> docker ps --latest --quiet
alias dpa 		=> docker ps --all
alias dps 		=> docker ps
alias drd 		=> docker run --detach --publish-all
alias dri 		=> docker run --interactive --tty --publish-all
alias drm 		=> docker rm $(docker ps --all --quiet)
alias drmi 		=> docker rmi $(docker images --quiet)
```
この残酷な世界で、TDDのメリットを少しでも享受する2つのルール（仮）

ユニットテストが通ったコードに対する安心感は、結構ある。実際にバグもだいぶ予防できている気がする。

ただ、人は面倒くさがりなもので、「テストコードをたくさん書いたら、メンテ対象のコード量がその分増える。めんどい。」みたいな気持ちが起こってきて、当初のTDDへの意気込みが薄れてくる。

面倒くさいという感情一つで、100の理屈も吹っ飛んで、当初の夢のプランが脆くも崩れ去る。我々はそんな残酷な世界を生きている。

ただ、そんな世界でも生きねばならないので、ちょっとでも対抗したい。そのために、次の2つのシンプルなルールを適用してみてはどうかと考えた。

----

1. 自分のコードがちゃんと動くかどうか不安を感じたら・・・
    * テストできるようにリファクタリングして、
    * テストケースを書け。
2. クロスレビューを必ずやって、そのとき他人のコードがちゃんと動くか不安を感じたときには・・・
    * コードの行数範囲を明示した上で、「テストできるようにリファクタリングして、テストケースを書け。」ととりあえずコメントしろ。

プロジェクトリーダーは、ユニットテストをやるためのツールセットを用意し、何度か繰り返してクロスレビューをやる計画を立てておく。クロスレビューでは、上記のルールを設定して実施する。

----

まだちょっとしか実践していないから、ルールの過不足は不明。

下記のようなものになんとか対抗したいというのが意図。

* 他人の指摘がないと、リファクタリングやテストケース書きなどやる気がおこらない。大抵の人は、自分に甘く他人に厳しい。
* カバレッジとかの簡単すぎる基準を設けて無理にやらせると、本質を捉えてちゃんとやってる人まで罰することになる可能性がある。これはやる気を絶望的に低下させる。
* 必要と感じられないようなテストコードをメンテし続けるのは苦痛。
* ちゃんと動くか不安になるようなコードは、大抵関係ないコードとごちゃ混ぜになって長いコードになっている。そういうバグの温床をピンポイントで攻撃すれば、費用対効果は高い。

TDDのいいところは、コードに対して網羅的にやらなくても効果があること。部分的にやったとしても、やった分だけバグの可能性が減る。

必要だと自分で思ったところだけをやるんだったら、面倒くさいという感情にも対抗しやすいのではないかというのがミソ。（特に面倒だと思わないのなら、それはすごい！そういう人は全部ちゃんとやってもらってOK、大丈夫。）

`sed -e 's/面倒くさい/コスト/g' < this.md`

Test Driven Bugfix...
vbs....

うん、わかりにくい。

```vbnet
str = "hoge"
ret = str = "hoge"
```

()でくくってあげないとわからんよ。

```vbnet
str = "hoge"

'こんな書き方はまじ嫌
If str = "hoge"
  ret = True
Else
  ret = False
End If

'こっちの方がまだ見やすい
ret = (str = "hoge")
WScript.echo ret  'True(-1)

ret = (str = "fuga")
WScript.echo ret   'False(0)

```
Apacheログのエスケープされた日本語を元に戻す

Apacheのログはセキュリティ強化のためマルチバイト文字がURIエスケープされています。

おかげで日本語のパスにアクセスしたログがそのままでは読めないのでPerlのURI::Escapeモジュールで復号化するためのワンライナーを書きました。

```
% tail -f /var/log/httpd/ssl_access_log | perl -ne 'use URI::Escape; print uri_unescape($_);'
```
hub pull-request -i n -b branch が失敗する


## 現象

なんどやっても失敗するんですね．

``` 
$ hub pull-request -i 9 -b develop
Warning: Issue to pull request conversion is deprecated and might not work in the future.
Error creating pull request: Unprocessable Entity (HTTP 422)
Not allowed to change field "issue"
```

とか，develop のところを upstream である sasarky/ipuhubot とかいろいろ変えてみましたが状況は変わらず...

## 原因
githubアカウントを2つ持っているのですが，hub コマンドを想定と異なるユーザと連携していました...orz

今回の操作の場合，issue を発行したユーザでなければ，PullRequest に付け替えることができないので Not allowed なんですね．

hub コマンドは初回実行時にアカウントとパスワードを聞かれると思います．パスワードは保存されませんが，アカウントとOAuthトークンは ~/.config/hub に保存されています．

## 対処

~/.config/hub　を削除するともう一度ログインを尋ねられるので，

```
rm ~/.config/hub
```
でいったん削除してから hub コマンドを実行すると正しく動作しますた

```
$ hub pull-request -i 9 -b sasarky:ipuhubot/develop
github.com username: isseium
github.com password for isseium (never stored):
deprecated and might not work in the future.
https://github.com/sasarky/ipuhubot/pull/9
```
Unfolding Maps(Processing)のインストール方法

Processingのライブラリに地図に関するものがあったので、とりあえずそのインストール方法。

Unfolding Maps(http://unfoldingmaps.org/)

ProcessingのInstallでインストール後、サンプルを張り付ければ下図のようなのがサクッと作れます。

サンプル：https://github.com/tillnagel/unfolding/blob/master/examples-processing/GeoRSSMarkerApp/GeoRSSMarkerApp.pde

![無題の画像.png](https://qiita-image-store.s3.amazonaws.com/0/30304/de400de8-edb9-5d9c-bc8a-6e8e0ff73fc6.png)

コードを見ると、一からでもすごく簡単に作れそうなので、いろいろ試してみたくなる。

# Install手順
PDEでメニューからSketch＞Import Library...＞Add Library...
![無題の画像1.png](https://qiita-image-store.s3.amazonaws.com/0/30304/fc93a823-ff37-32f7-1d92-be8eea51bc5b.png)

対象ライブラリ(Unfolding Maps)を選択してInstallをクリック
![無題の画像2.png](https://qiita-image-store.s3.amazonaws.com/0/30304/64b30eef-e679-3285-2abb-e2275a6e9f77.png)

サクッと終わる。
![無題の画像3.png](https://qiita-image-store.s3.amazonaws.com/0/30304/73347291-beae-4f09-513a-23b20eb5ff9e.png)

あとはコードで必要な機能をimportすればよい。
grepぷりん :: grepだけで複雑な検索を

What is this?
==============
最近マイブームの "grep -Prin" について・・・

* あるディレクトリ以下(サブディレクトリを含む)の *.c *.h *.s から特定の文字列を検索したい。
* 報告書を短くまとめたいので、コマンド文字列も短くしたい。
* 特定の文字列とは実のところアセンブラニモニックなのでキャピタル（大文字小文字）を区別せず検索したい。
* 後方不一致条件とか付加したいので、PerlやTclの正規表現と等価のものを使いたい。

・・・上記は秀丸エディタからならできるが、自動化したいのでコマンドラインから呼び出せるものにしたい・・・

調べた結果、
`grep -Prin --include='*.c' --include='*.s' --include='*.h' <Reg-exp> <TopDir>`
で目的達成したのでメモ。(Cygwin32/ubuntu)

Grep Options
==============

-P :: Perl-regexp
--------------------
このオプションで、パターン指定文字列にPerlの正規表現拡張構文を使用可能となります。
具体的には

```
(?<![a-zA-Z0-9"_-])
```

のような後方一致系表記が使用可能になります。

-r :: Recursive
--------------------
これは有名？
サブディレクトリも検索するオプションです。

-i :: Ignore-case
--------------------
大文字小文字の区別をしなくなります。

-n :: line-Number
---------------------
パターン一致した行番号を表示するようになります。

--include=<GLOB> 
-----------------------
GLOBと一致したファイル名をもつファイル内から検索します。
man page には明記されていませんでしたが、このオプションを複数指定することで重ねがけできました。

Examples
=============

MIPS32: LD, SD 命令をインライン使用している箇所を検索する
-------------------------------------------------------

```
$ grep -Prin --include='*.c' --include='*.s' --include='*.h' '(?<![a-zA-Z0-9"()_-])[LS]D(?![A-Z0-9"()_-])' ./
./alchemy/devboards/db1200.c:329:/* SD carddetects:  they're supposed to be edge-triggered, but ack
./boot/elf2ecoff.c:140:         fprintf(stderr, "%s: Can't allocate %ld bytes.\n", name,
./boot/elf2ecoff.c:568:                                         "Intersegment gap (%ld bytes) too large.\n",
./boot/elf2ecoff.c:573:                                 "Warning: %ld byte intersegment gap.\n",
./include/asm/asm.h:244:#define REG_S           sd
./include/asm/asm.h:245:#define REG_L           ld
     <<<<<途中省略>>>>>
```

MIPS32: Branch と Jump 命令の検索
--------------------------------------------
```
$ grep -Prin --include='*.s' '(?<=\s)(B\C|BEQ|BGE|BGT|BLE|BLT|BNE|J\C|JAL|JR)' ./
```