OmniAICreator/Qiita-1.07M huggingface dataset:
MacでDockerを入れて自分で作ったイメージを保存するまで

## インストール
```sh
$ brew install docker boot2docker
$ docker -v
Docker version 1.3.1, build 4e9bbfa
$ boot2docker -v
Boot2Docker-cli version: v1.3.1
```
※このバージョンがbrewで入る最新のバージョンのはず。もし最新でなければ以下を実行

```sh
$ brew update
$ brew upgrade docker
$ brew upgrade boot2docker
```

※[VirtualBox](https://www.virtualbox.org/)も入れておく


## 初期設定的なもの

```sh
$ boot2docker init
$ boot2docker up
Waiting for VM and Docker daemon to start...
.......................ooo
Started.
Writing /Users/mapyo/.boot2docker/certs/boot2docker-vm/ca.pem
Writing /Users/mapyo/.boot2docker/certs/boot2docker-vm/cert.pem
Writing /Users/mapyo/.boot2docker/certs/boot2docker-vm/key.pem

To connect the Docker client to the Docker daemon, please set:
    export DOCKER_HOST=tcp://192.168.59.104:2376
    export DOCKER_CERT_PATH=/Users/mapyo/.boot2docker/certs/boot2docker-vm
    export DOCKER_TLS_VERIFY=1
```

上記に出てきた、環境変数を、`.bashrc`なり、`.zshrc`に保存する。

## 自分が必要なDockerイメージをpullする
```sh
docker pull centos:centos6
```

※この時以下のようなエラーが発生した。たぶん、boot2dockerを最新にしたり、上記の環境変数を設定したりしてなおした。。はず。。。。

- http://qiita.com/mokemokechicken/items/ca3b2f22151e0410cd31
- http://mogproject.blogspot.jp/2014/05/docker-pull-from-private-registry.html

## コンテナの起動
`docker run`するimageの確認

```sh
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos              centos6             70441cac1ed5        3 weeks ago         215.8 MB
```

`docker run`

```sh
$ docker run -t -i --name hoge centos:centos6 /bin/bash
[root@612cf98173a6 /]#
```
hogeという名前の、REPOSITORYがcentosで、TAGがcentos6のimageを使うというような意味。

これでコンテナが作成されて、その中にログインされる。ここで必要なものをインストールしたりなんなりしていく。


※[Dockerにおけるコンテナのライフサイクル](http://d.hatena.ne.jp/enakai00/20140628/1403933390)のページがコンテナの事についてわかりやすい図があって、よかった。

## いろいろインストール
テスト用に作ったので何入れるか余り考えてなかったけど、とりあえず、`vim`をインストールしてみるｗ

```sh
[root@612cf98173a6 /]# yum install vim
# いろいろ
[root@612cf98173a6 /]# exit
```

これでvimが入った。

## docker commitでイメージの作成
停止中のコンテナの確認

```sh
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
612cf98173a6        centos:centos6      "/bin/bash"         15 minutes ago      Exited (0) 9 minutes ago                       hoge
```

docker imageの作成

```sh
$ docker commit hoge mapyo/hoge-image:0.0.1
```

imageの確認

```sh
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
mapyo/hoge-image    0.0.1               a68a12549598        12 minutes ago      306.3 MB
centos              centos6             70441cac1ed5        3 weeks ago         215.8 MB
```

作ったimageが出来ている！！


## まとめ
dockerを導入してから、imageを作成する所までを書いた。

次はいろいろインストールするところで、秘伝のタレになってしまわないように、
`Dockerfile`を使いましょうね。という流れになるはずだ。
CentOS 7にdjango-powerdnsをインストール

あまり良くわかっていない。

## 参考

* [PowerDNSとdjango-powerdnsを試す - 偏った言語信者の垂れ流し](http://d.hatena.ne.jp/nullpobug/20110321/1300649944)

## インストール

```bash:mysql側準備
mysql -u root -e "CREATE DATABASE powerdns CHARACTER SET utf8;"
mysql -u root -e "CREATE USER 'powerdns'@'localhost' IDENTIFIED BY 'powerdns';"
mysql -u root -e "GRANT ALL PRIVILEGES ON powerdns.* TO 'powerdns'@'localhost';"
```

```bash:
yum install -y MySQL-python
easy_install django-powerdns
cd /srv
django-admin.py startproject mypowerdns
```

```diff:/srv/mypowerdns/mypowerdns/settings.py
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
+   'powerdns',
)

DATABASES = {
    'default': {
-        'ENGINE': 'django.db.backends.sqlite3',
-        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
+        'ENGINE': 'django.db.backends.mysql',
+        'NAME': 'powerdns',
+        'USER': 'powerdns',
+        'PASSWORD': 'powerdns',
+        'HOST': '',
+        'PORT': '',
    }
}
-LANGUAGE_CODE = 'en-us'
+LANGUAGE_CODE = 'ja'
-TIME_ZONE = 'UTC'
+TIME_ZONE = 'Asia/Tokyo'
```


```diff:/srv/mypowerdns/mypowerdns/urls.py
 from django.conf.urls import patterns, include, url
 from django.contrib import admin
+admin.autodiscover()
 
 urlpatterns = patterns('',
     # Examples:
     # url(r'^$', 'mypowerdns.views.home', name='home'),
     # url(r'^blog/', include('blog.urls')),
 
     url(r'^admin/', include(admin.site.urls)),
 )
```


```bash:
# cd /srv/mypowerdns/
# python manage.py syncdb
Operations to perform:
  Synchronize unmigrated apps: powerdns
  Apply all migrations: admin, contenttypes, auth, sessions
Synchronizing apps without migrations:
  Creating tables...
    Creating table domains
    Creating table records
    Creating table supermasters
  Installing custom SQL...
  Installing indexes...
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying sessions.0001_initial... OK

You have installed Django's auth system, and don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (leave blank to use 'root'):
Email address:
Password:
Password (again):
Superuser created successfully.
```

```bash:django-powerdns起動
python manage.py runserver
```

* http://127.0.0.1:8000/admin にアクセスすると管理画面が表示される。


## powerdns側設定

```bash:/etc/pdns/pdns.conf
launch=gmysql
gmysql-socket=/var/lib/mysql/mysql.sock
gmysql-user=powerdns
gmysql-password=powerdns
gmysql-dbname=powerdns
```

```bash:
systemctl pdns restart
journalctl -u pdns -f -l
```
CentOS 7にPowerDNS/Poweradminをインストール

まだ良くわかっていない。

## 参考

* [CentOS 7にPowerDNS/Poweradminをインストール | Works | URAMIRAIKAN](http://www.uramiraikan.net/Works/entry-2012.html)

## インストール

```bash:
yum install -y pdns{,-backend-mysql,-recursor,-tools} \
  bind-utils wget httpd php{,-cli,-pdo,-mysql,-mcrypt} mariadb-server

systemctl enable mariadb
systemctl start mariadb
systemctl enable pdns
systemctl start pdns
service httpd restart

mysql -u root -e "CREATE DATABASE powerdns CHARACTER SET utf8;"
mysql -u root -e "CREATE USER 'powerdns'@'localhost' IDENTIFIED BY 'powerdns';"
mysql -u root -e "GRANT ALL PRIVILEGES ON powerdns.* TO 'powerdns'@'localhost';"

cd /opt
wget http://downloads.sourceforge.net/project/poweradmin/poweradmin-2.1.7.tgz
tar xzf poweradmin-2.1.7.tgz
mv poweradmin-2.1.7 /var/www/html/poweradmin
cd /var/www/html/poweradmin
chown -R apache:apache .
mysql -uroot powerdns < ./poweradmin/sql/powerdns-mysql-db-structure.sql
mysql -uroot powerdns < ./poweradmin/sql/powerdns-dnssec-mysql-db-structure.sql
```

## WebUI

* http://server-ip/poweradmin/install/ にアクセス。

![1.png](https://qiita-image-store.s3.amazonaws.com/0/25728/fd312c6e-d172-3962-7804-0f1e6e28dfdb.png)
![2-euc.png](https://qiita-image-store.s3.amazonaws.com/0/25728/f7dac3ff-6efb-cf38-6281-e37c3d4c3398.png)
* 文字化けする場合はeuc-jpで表示すること。
![3.png](https://qiita-image-store.s3.amazonaws.com/0/25728/723793a4-78f5-078f-0d41-f414af0613a9.png)
![4.png](https://qiita-image-store.s3.amazonaws.com/0/25728/0fd292ee-2987-aaf7-01f5-585070b63b63.png)
![5.png](https://qiita-image-store.s3.amazonaws.com/0/25728/19dceb57-96f4-62db-a764-5b467a63f7d6.png)
![6.png](https://qiita-image-store.s3.amazonaws.com/0/25728/6a7fd2ff-d5b9-9257-f741-ad60ef628662.png)

## コンフィグ

WebUIのinstall画面が使いづらければ
/var/www/html/poweradmin/inc/config.inc.php を直接編集してもよい。

```php:/var/www/html/poweradmin/inc/config.inc.php
<?php

$db_host		= 'localhost';
$db_user		= 'powerdns';
$db_pass		= 'powerdns';
$db_name		= 'powerdns';
$db_type		= 'mysql';
$db_layer		= 'PDO';

$session_key		= 'Eex3aemiIV1Sheebfix0ja8SeChaep1p';

$iface_lang		= 'ja_JP';

$dns_hostmaster		= '';
$dns_ns1		= '';
$dns_ns2		= '';
```

```bash:
mv /var/www/html/poweradmin/install{,.bak}
```

## ログイン

* admin : パスワードでログイン。

![login.png](https://qiita-image-store.s3.amazonaws.com/0/25728/44ca12e0-34f4-b72f-2490-2f6376cd3c26.png)
![menu.png](https://qiita-image-store.s3.amazonaws.com/0/25728/9a82c2d0-fc75-fc0f-f41b-4b8c36c71d86.png)
メールアドレス、ホスト名など識別名の命名規則についてのまとめ


いわゆるIDの命名規則。

* 短い
* 衝突しにくい
* タイポしにくい
* 口頭で読みやすい
* 実体と強く結び付くもの（ひと、NW機器など）の場合は実体を表しやすい

などが大切。

ひとに帰属する識別名など
=====================

ローマ字変換の規約
--------------------

以下のヘボン式ローマ字の規約に則る。

[PASSPORT_ヘボン式ローマ字綴方表](http://www.seikatubunka.metro.tokyo.jp/hebon/)


ドメインのID
--------------------

[メールアドレスの命名規則にはどういうものがある? | スラッシュドット・ジャパン IT](http://it.slashdot.jp/story/10/05/28/164227/%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AE%E5%91%BD%E5%90%8D%E8%A6%8F%E5%89%87%E3%81%AB%E3%81%AF%E3%81%A9%E3%81%86%E3%81%84%E3%81%86%E3%82%82%E3%81%AE%E3%81%8C%E3%81%82%E3%82%8B) などより。

1. `名前.名字`
 * `ichiro.tanaka`
 * 衝突した場合に`ミドルネーム`, `ランダムな英数`などをドット区切りで任意につける
  * `ichiro.s.tanaka`
1. `名前イニシャル 1文字.名字.ランダム文字 2桁`
 * `i.tanaka.aa`
1. `名前イニシャル 1文字.母方苗字 1文字.名字`
 * `i.s.tanaka`

などが使える。
メールアドレスにそのまま使うことを考えるとランダム文字が入るのは違和感があるので、オーソドックスな1番かな。

メールアドレス
--------------------

上記にドメインをつける。

    ichiro.tanaka@example.com


氏名変更時の対応
--------------------

ドメインのIDは基本、変更不可。メールアドレスは希望があれば可能とする。旧メールアドレスはエイリアスとして残す。

マシン
===========

PCとサーバーを分けて考える。

PC
----

### 家庭内/小規模（ワークグループレベル）

天体名、楽器名、音楽家名、すしネタなど思い入れのあるものにすればいい。ただ、上記の基本ルールを忘れずに。それを踏まえると日本語名称は筋悪と思う。ちなみにうちはフォント名シリーズにしている。

[サーバ名など、たくさんの名前が必要なときに使える「命名シリーズ」まとめ - masahirorの気まま記録簿](http://masahiror.hatenadiary.jp/entry/20060904/naming_matome)

### 中規模

[Mnemonic encoding wordlist](http://web.archive.org/web/20090918202746/http://tothink.com/mnemonic/wordlist.html) から選べばいいと思う。

[ホスト名の命名規則 - tech.hara96.com](http://tech.hara96.com/yodan/hostname)にある`MACアドレスそのまんま`というのはタイポしやすくて発音しにくいので筋悪かなと。

サーバー
--------------------

### 小規模

`用途+シリアルナンバー.環境`でいいんじゃないか。

### 中規模 〜 大規模 （1600前後まで）

[【翻訳】サーバの適切な名前の付け方 | POSTD](http://postd.cc/a-proper-server-naming-scheme/) より。

* AレコードとCNAMEレコードを分ける
 * Aレコードは [Mnemonic encoding wordlist](http://web.archive.org/web/20090918202746/http://tothink.com/mnemonic/wordlist.html) から選ぶ
* CNAMEレコードは `用途+シリアルナンバー.環境.地域.ドメイン`にする
 * 地域は [UN/LOCODE Code List by Country - Trade - UNECE](http://www.unece.org/cefact/locode/service/location.html) の3文字の地域コードから取得する

ネットワーク機器や適切なDNS設定による恩恵についても言及あり。

### 例

Aレコード

    crimson.example.com.   A   192.0.2.11

CNAMEレコード

    web01.prd.nyc.example.com.   CNAME   crimson.example.com.

WiFiのSSID/プリンターなど
--------------------------

用途でつける。

    Organization_an
    Organization_bg
    Organization_guest

### プリンター

`機種ID+シリアルナンバー.機能.地域.ドメイン`がいいと思う。

    mg323001.ptr.nyc.example.com.   A   192.0.2.51

プリンターは比較的移動させやすいので`west.11f.ptr.nyc.example.com.`みたいな場所を表す名前はあまりよくない気がする。で、プリンター本体に`mg323001`と大書きしておけばいいんじゃないか。

ネットワークのワークグループ名
===============================

ドメイン名と同じでいいと思う。
Chromeの複数タブを新しいウィンドウに切り出したり別ウィンドウに移動したり閉じたりする方法

# 複数タブを新しいウィンドウに切り出したり別ウィンドウに移動したりする方法

1. タブを選択する
    - command+click or shift+click で出来る
2. タブをドラッグアンドドロップ
    - 何もないところにドロップすると新しいウィンドウになる
    - 別ウィンドウにドロップするとウィンドウ間の移動になる
        - タブを全部選んでる場合2つのウィンドウを1つのウィンドウにまとめることになる

![demo](http://i.gyazo.com/979a6fbda699994172fb243947bf80ac.gif)

# 複数タブを一度に閉じる方法

1. タブを選択する
    - command+click or shift+click で出来る
2. command+w

# あとがき
タブを複数選択するのってあんまり知られてない気がする。
複数選択出来るのは知ってたけどドラッグアンドドロップ出来るのは知らなくて、複数タブを簡単に別ウィンドウに切り出すために[Chrome拡張書いた](http://takc923.hatenablog.com/entry/2014/10/13/172226)けど完全に無駄だった。
タイトルの横に水平線を引く


いわゆるこういうやつです。

###**ータイトルー**###


これをまあレスポンシブにCSSで書くときの方法を
書き残したいと思います。

全体はこんな感じ

```lang:html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
  <title>Document</title>
</head>

<body>
  <h2 id="ex-title">This is title</h2>
</body>
</html>
```



```lang:css
#ex-title {
    display: -webkit-box;
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-align: center;
    -webkit-align-items: center;
    -ms-flex-align: center;
    align-items: center;
    text-align: center; /* for no-flexbox browsers */
}

#ex-title:before,
#ex-title:after {
    border-top: 1px solid;
    content: "";
    display: inline; /* for IE */
    -webkit-box-flex: 1;
    -webkit-flex-grow: 1;
    -ms-flex: 1;
    flex-grow: 1;
}

#ex-title:before {
    margin-right: 0.5em;
}

#ex-title:after {
    margin-left: 0.5em;
}
```

これはflexboxを使うのが最適だと思います。
左のライン、タイトル、右のラインの３つにafterとbeforeで分けて考えます。
また、`flex-grow: 1`を入れることで確実に左右までラインを伸ばせます。


これくらい覚えよう、自分。
アセンブラ(32bit)でhello world

巷のアセンブリ入門とかを見ると、hello worldするのにlibcのprintfを呼んでいる例が多くて、「それアセンブリちゃうやんけC言語やんけ」という気持ちになってきます。

というわけでwrite(2)を直接叩くhello worldを書いてみました。


```gas
/**
 * Linux i386でのhello world
 * 実行方法:
 * gcc -o hello hello.s
 * ./hello
 *
 */
.file   "hello.s"
        .data
        //ここからスタート
        .global main
main:
        pushl  %ebp
        movl %esp, %ebp
        movb $0x00, -1(%ebp) # \0
        movb $0x0A, -2(%ebp) # \n
        movb $0x6f, -3(%ebp) # o
        movb $0x6c, -4(%ebp) # l
        movb $0x6c, -5(%ebp) # l
        movb $0x65, -6(%ebp) # e
        movb $0x68, -7(%ebp) # h

        movl $4,        %eax   # sys_write
        movl $1,        %ebx   # stdout
        leal -7(%ebp),  %ecx   # address of 'h'
        movl $7,        %edx   # len 7
        int  $0x80             # system call

        popl  %ebb  # おまじない
        ret
```
Drone+fig でCIテストしてみる

アプリケーションをfig化すると
fig upするだけで同じ環境をすぐに構築することが出来ますよね。
つまり、CIでテストする環境もfig使うとそのまま動くのでは…と思い試してみました。


## fig / Droneについてのref
- [fig](http://www.fig.sh/)
- [Docker1.3版 boot2docker+fig入門](http://qiita.com/toritori0318/items/190fd2dad2bf3ce38b88)
- [Drone](http://drone.readthedocs.org/en/latest/index.html)
- [GitLab+DroneでHerokuにCIする、という最高の環境を10分で作る](http://d.hatena.ne.jp/toritori0318/20141115/1416077495)

　  

## 構成概要
OSS版Droneを利用します。
Droneのscript内で普通にfigを実行し、
動的にDockerコンテナ起動した上でテストを実行しています。
Dockerコンテナは普通にDroneと同じく、ホストOS上にコンテナを起動しています。

　  

## サンプルプロジェクト
https://github.com/toritori0318/drone-fig-ci-sample
上記は [fig公式](http://www.fig.sh/) のサンプルアプリケーション＋テストファイルを追加したものです。
fig run.... で直接テストを実行出来るようにしています。

### .drone.yml
**DOCKER_HOST** はホストOS上で実行されているDockerのホストIPを指定します(ifconfigで確認しましょう)。
また、 **FIG_FILE** ではdrone用に少しだけカスタマイズしたfig.ymlを利用しています。
理由は後述。

```.drone.yml
image: toritori0318/dockerfile-fig

env:
  - PATH=$PWD/bin:$PATH
  - DOCKER_HOST=tcp://xxx.xxx.xxx.xxx:4243
  - FIG_FILE=fig-drone.yml

script:
  - echo 'start!'
  - fig ps
  - fig build web                       # docker buildを行う
  - fig up -d                           # dockerコンテナ起動
  - fig run --rm web make test-unit     # テスト実行
  - fig stop                            # コンテナ停止
  - fig rm --force                      # コンテナ削除
  - echo 'end!'
```

### fig-drone.yml
volume同期を行うとエラーになってしまうので、volume部分をコメントアウトしています。
アプリケーションコードは [Dockerfile](https://github.com/toritori0318/drone-fig-ci-sample/blob/master/Dockerfile) でAddしたものをそのまま利用しています。
CIするだけなので同期する必要は無いですしね。

```fig.yml
web:            # サービス名です。この名前でコンテナにアクセスできます
  build: .                  # ./Dockerfileを用いビルドする
  command: python app.py    # ビルド後のコンテナで実行するコマンド
  ports:
   - "5000:5000"            # ポートフォワード設定。フォーマットは <ホスト側ポート>:<コンテナ側ポート>
#  volumes:
#   - .:/code                # ボリューム設定。ローカル「.」を コンテナ「/code」に同期
  links:
   - redis:redis            # リンク設定。フォーマットは <サービス名>:<エイリアス名>
  environment:
   - PYTHONPATH=./
redis:
  image: redis 
```



　  
　  
  
## 実際に行ってみて良いと思ったところ  
### ローカルの環境がそのまま動く
ローカルでDockerコンテナ起動してテストした環境が
なにもせずともCIでほぼ同じ環境で動かせる、というのは良いですね。
### クラスタを考慮した環境も簡単に用意できる
単体のアプリケーションだけでなく、figで複数クラスタを起動して
全体の受け入れテストを動かしてみる、ということも可能です。
### 毎回きれいな環境で動かせる
Dockerコンテナなので、毎回一からきれいな環境を（しかも高速に）構築しつつ
CIを回せるのは◯。

　    

## 実際に行ってみてイマイチと思ったところ
### Drone用のfig.ymlを用意する必要がある（かもしれない）
ローカルで開発するときにはファイル同期したいのでvolumesを指定すると思いますが
Drone上から実行するとエラーになってしまいます。
そのため別にfig.ymlファイルを用意する必要がありますが、それが多少面倒かも。
（figファイル一枚だけで済むと考えれば、それはそれで楽なのですが）
### 途中でエラーになったときにゴミコンテナが残る
figコンテナ起動後にテストエラーになったりfigエラーになったりするとゴミが残ります。
一応、cronなどで定期的にコンテナをクリーンにする、という方法で回避できます。
### テストの詳細が表示されない
現時点の方法だとDroneのログ上にテストの詳細が表示されないので、
テスト失敗時に原因がわからないという…（割とクリティカル）
もしかしたら回避する方法があるかもしれないので、もう少し模索してみます。


　  

　  


## まとめ
Drone+figでCIテストする、というのを試してみました。
せっかくfigでポータブルに環境構築できるので
それをほぼそのまま利用しつつCI出来たらいいな〜、と思いました。

上記に上げたようにいくつか課題も残っていますが、
もう少し検証し使えるところまで持って行けたらな〜と考えています。
Ansibleのインベントリファイルでステージを切り替える

## やりたいこと

Capistranoで

```shell-session
$ cap staging deploy
$ cap production deploy
```

という感じでステージ名を指定してそれに応じて設定を変えるということができますが、それと同じことをAnsibleでやりたい、という話です。

## インベントリファイルとgroup vars

Ansibleはステージごとのホスト一覧を ```-i``` オプションで[インベントリ](http://docs.ansible.com/intro_inventory.html)という概念で指定することができます。

```
$ ansible-playbook -i hostlist playbook.yml
```

このインベントリに[Group Variables](http://docs.ansible.com/intro_inventory.html#group-variables)という形で変数定義をすることができます。

```ini:hostlist
[atlanta]
host1
host2

[raleigh]
host2
host3

[atlanta:vars]
some_server=foo.southeast.example.com
halon_system_timeout=30
self_destruct_countdown=60
escape_pods=2
```

このGroup Variablesの機能を使うとステージごとにイベントリファイルを分けることで冒頭のことを実現できます。

```
$ tree
.
├── staging_hosts
├── production_hosts
└── playbook.yml

$ ansible-playbook -i staging_hosts playbook.yml
$ ansible-playbook -i production_hosts playbook.yml
```

## all:vars と vars_filesをうまく使う

と、ここまでは[how-to-arrange-inventory-stage-vs-production](http://docs.ansible.com/playbooks_best_practices.html#how-to-arrange-inventory-stage-vs-production)に書いてあるのですが、もうちょっとつっこみたい。

上記の情報だと自分的に悩んだのが、

1. group毎ではなくてステージ共通の設定を各```[group:vars]```に書くのダルい
2. [Best Practice](http://docs.ansible.com/playbooks_best_practices.html#directory-layout)にあるように変数はymlでまとめたい（group_vars,host_varsよりもむしろステージ単位の変数のほうがよく使う気がするのだが・・・）

ということで試してできたのがこちら。

```
$ tree
.
├── staging_hosts
├── production_hosts
├── playbook.yml
└── vars
    ├── staging.yml
    └── production.yml
```

#### stagingレベル

```ini:staging_hosts
[web]
stg1.hoge.com
stg2.hoge.com

[all:vars]
stage=staging
```

```yaml:staging.yml
---
val1=hogehoge
```

#### productionレベル

```ini:production_hosts
[web]
web1.hoge.com
web2.hoge.com

[all:vars]
stage=production
```



```yaml:production.yml
---
val1=fugafuga
```

### playbookで vars_files にstage変数を使う

```yaml:playbook.yml
- hosts: all
  vars_files:
  - vars/{{ stage }}.yml
```

ポイントは、

* インベントリに[all:vars] と書くとすべてのグループに対して共通な設定ができる
* stage という変数をインベントリに定義
* stage変数を vars_files で指定するファイルパスに使用する

というところです。
踏み台サーバー経由でSSH接続の覚書き


AWS上のプライベートサブネットに配置したEC2にSSH接続がしかったのでキーファイルを転送しようとしたら、

```
Permission denied (publickey).
lost connection
```

エラーが出てアクセスできなかった。

原因はSCPコマンド使い方が間違っていたみたい。

とりあえず転送できた時のコマンドの覚書です。

```
$ scp -i /Users/my_user/xxx.pem /Users/my_user/xxx.pem ec2-user@[Public DNS]:~/.
```
Scala.jsのFuture/Promiseを使ってAjaxでPOSTするとき

こちらの記事を参考にScala.jsでFuture/Promiseを使ってXMLHttpRequestでPOSTするときにうまくいかないところがあったのでメモ。

http://blog.pab-tech.net/2014/03/07/scala-js-future.html

```
data match {
  case Some(d) => 
    req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded") // これを追記
    req.send(d)
  case None => req.send()
}
```

これを追記しないとRailsとかヘッダーを見るアプリケーションサーバではPOSTとみなしてくれなかった。
[Objective-C] 特定のコーナーだけ角丸を適用する


四隅すべてを角丸にしたい場合は`layer.cornerRadius`に数値を設定してやるだけですが、右上だけ、下端だけ、など想定した場所だけに設定したい場合は若干めんどくさい手順が必要なようです。

利用するクラスなどは以下。

* UIRectCorner
* UIBezierPath
* CAShapeLayer


## UIRectCorner

UIRectCornerはその名の通り、角丸にするコーナーを決めます。
どのコーナーを角丸にするかは以下の値をビット演算で与えてやります。

* UIRectCornerAllCorners
* UIRectCornerTopLeft
* UIRectCornerTopRight
* UIRectCornerBottomLeft
* UIRectCornerBottomRight


## サンプルコード

実際のコード例は以下。

```objc:roundCorner-sample
CGRect frame   = aView.bounds;
CGFloat radius = 4.0;
UIRectCorner corner    = UIRectCornerBottomLeft | UIRectCornerBottomRight; // 下端のみ角丸に
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:frame
                                               byRoundingCorners:corner
                                                     cornerRadii:CGSizeMake(radius, radius)];

CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = frame;
maskLayer.path  = maskPath.CGPath;

// UIViewのlayer.maskに、生成したCAShapeLayerを設定する
aView.layer.mask = maskLayer;
```
SA-IS(Suffix Array - Induced Sorting)を実装した

# SA-ISとは

- SA-ISは接尾辞配列を文字列長の線形時間で求めるアルゴリズム。
- 元論文：[Two Efficient Algorithms for Linear Time Suffix
Array Construction [G Nong, et.al.]](http://libir1.ied.edu.hk/pubdata/ir/link/pub/TC-2009-04-0165-Final.pdf)
- 以下個人的に悩んだところ。

# LMS-substringのrename

- ちょっとだけ悩んだ。
- １回目のinduced sortingの後にLMS-substringがsortされていることを利用して辞書順で小さいLMS-substringから比較していけば良いだけだった。
- renameで得られた新しいアルファベットでLMS-substringがuniqueかどうかの判定ができる。

# renameしたLMS-substringを格納する場所

- $n$ を文字列長、$l$ をLMS-substringの数とする。
- 上のrename処理が辞書順に見ていくので適当に格納すると出現順が崩れて再帰する際の文字列が得られない。配列をもう一つ用意すれば簡単だがメモリ的にうれしくない。
- うまくやるために、以下の性質を使う。
  - $l$ は$\lfloor n/2 \rfloor$以下。
  - LMS-characterの隣はLMS-characterにならない。
- LMS-substringの辞書順が求まったら作業用配列の先頭に辞書順情報だけ格納して、それ以外の値を初期化する。
- rename処理の中で、元の文字列での出現位置が$p$となるLMS-substringに対して、renameした値を作業用配列の($l$+$\lfloor p/2 \rfloor$)の位置に格納する。上記の性質から格納位置は被らないし溢れない。
- 配列の$l$ 以降で初期化されていない値は元の文字列の出現順にLMS-substringがrenameされた値となっているので、ここから新しい文字列を生成して再帰的にinduced sortする。

# ソースコード

- [nel215/sasa](https://github.com/nel215/sasa)

# 実行速度

- 上記のtest.cppに書いてあるLS(Larsson-Sadakane)もどきとの比較
- 条件：文字列長$10^7$、アルファベットサイズ$2$、g++ 4.4.7、i5-4440 3.10GHz

|手法  |実行時間|
|-----|--------:|
|SA-IS| 2.92 [s]|
|LS   |14.74 [s]|

# まとめ

- 速いし、アルゴリズムも理解に苦しむ感じではないので良い。
- データの置き方とかで悩んだので省メモリコーディングの技術が必要。

# その他

- 最初のアルファベットサイズ求めるのにsetとか使っているのでその内直す。
- メモリの使用量を減らしたver.もあるらしいけど読んでない。
google url shortener apiを使用する

# 使用するライブラリ
- [scalaj-http](https://github.com/scalaj/scalaj-http)

# 準備
https://console.developers.google.com/

1. URL Shortener APIを有効にする。
1. googleのAPI KEYを取得。

# URL Shortener APIの使い方
- 送信先url  
https://www.googleapis.com/urlshortener/v1/url?key=[google api key]

上記のurlに対してjsonでリクエストを送る。

# ソースコード

https://github.com/FScoward/TweetAnimeScala/blob/master/src/main/scala/Amazon.scala

```scala
import scalaj.http.{HttpOptions, Http}

/**
* google の URL Shortener API を使用して短縮URLに変換
* */
private def urlShortener(url: String) = {
val json = s"""{\"longUrl\": \"$url\"}"""
val result = Http.postData(s"""https://www.googleapis.com/urlshortener/v1/url?key=${Environment.googleApiKey}""", json)
.header("content-type", "application/json")
.option(HttpOptions.connTimeout(10000))
.option(HttpOptions.readTimeout(50000))
.charset(UTF8_CHARSET)
parse(result.asString) \ "id"
}
```
perlbrew や cpanm と carton 


## perlbrew

[perlbrew](http://perlbrew.pl/)
>
perlbrewは非アドミン環境(ローカル環境)にperlの本体をインストールすることができるツール。OSに付属するperlから(インストールされているライブラリを含む)依存することないperlの環境を作ることができる

とりあえずは perlbrew で最新版の perl の環境を作る

```bash
$ perlbrew available
  perl-5.19.8
  perl-5.18.2
...
  perl5.003_07

$ perlbrew install perl-5.18.2
...
perl-5.18.2 is successfully installed.
$ perlbrew switch perl-5.18.2
```

## cpanm
[cpanm]
(http://search.cpan.org/~miyagawa/App-cpanminus-1.7001/lib/App/cpanminus.pm)
>
cpanminus(コマンドはcpanm)はCPANモジュールをget, unpack, build して install までやってくれる便利なツール。依存関係とかも考慮してくれるのでインストールしたいモジュールを指定することであとはよしなにしてくれる神ツール。


perlbrew 環境下における cpanm はperlbrewのコマンドでインストール可能

```bash
$ perlbrew install-cpanm
$ cpanm
Usage: cpanm [options] Module [...]

Try `cpanm --help` or `man cpanm` for more options.
```

## carton
[carton](http://search.cpan.org/~miyagawa/Carton-v1.0.12/lib/Carton.pm)

>
cartonは開発するアプリケーション単位で必要なPerlモジュールを一括管理、インストール(デプロイ)を行ってくれるこれまた神ツール。特定のディレクトリ以下にアプリケーションで必要なPerlモジュールの構成を構築してくれる。
アプリケーションが使用するPerlモジュール定義を記述するファイルを cpanfile と呼びます。

インストール

```bash
$ cpanm Carton
```

ついでに...  carton 環境下で Plack 動かしてみる


```bash
$ cat cpanfile
requires 'Plack';
```

こんなシンプルなcpanfileをつくる ( cpanfile の詳しい使い方はまた今度勉強する.)

空の作業ディレクトリを作って carton コマンド実行する.

```bash
$ carton
Installing modules using /Users/keisyu/work/MyApp/cpanfile     # つくった cpanfile を読み込んでPlackモジュールを依存モジュールとともにインストール
Successfully installed File-ShareDir-Install-0.08
Successfully installed Devel-StackTrace-1.31
...
Successfully installed Stream-Buffered-0.02
Successfully installed Plack-1.0030
23 distributions installed
Complete! Modules were installed into /Users/keisyu/work/MyApp/local  # モジュールは作業ディレクトリ直下のlocalディレクトリに全部入ったよ。
$ ls
cpanfile          cpanfile.snapshot local   # cpanfile.snapshot は依存関係も含めたインストールしたモジュールのバージョンも含めた詳細情報を記録されてる。
```

## PSGIのHello world

```perl
use strict;
use warnings;

my $app = sub {
    my $env = shift;

    return [
        200,
        [ 'Content-Type'  => 'text/html'],
        [ 'Hello PSGI World!!']
    ];
};
```

って感じのHelloWorldファイルを作って

```bash
$ carton exec -- plackup hello.psgi
HTTP::Server::PSGI: Accepting connections at http://0:5000/
```

でOK. http://localhost:5000/ でちゃんと動いた. (そりゃそうだ)
plackはcartonで入れたんだから当然

```bash
$ plackup hello.psgi
zsh: command not found: plackup
```

では動かない。 **carton exec --** にてlocal以下のモジュールを使うようにしないとね。
findコマンドで秒単位に新旧比較したい

# -mminはあっても-msecはないのか!

findコマンドは、様々な条件でファイル抽出ができて便利。でも時間の新旧で絞り込む機能は弱いと言わざるを得ない。

通常のタイムスタンプ(m:ファイルの中身を修正した日時)において、POSIXで規定されているのは`-mtime`だけであり、しかも後ろには単純な数字しか指定できない。つまり現在から1日（=86400秒）単位での新旧比較しかできない。

* 指定した年月日時分秒より新しい、より古い、等しい
* n秒前より新しい、より古い、等しい

なんて比較はしたくてもできなかった。独自のオプションも使えばある程度できるけどOSによって使えたり使えなかったりするし……。さてどうしよう。

# -newerオプションを活用するのが鍵

しかし`-newer`というオプションを使うと辛うじてこの悩みを解決できる。これは-newerの後ろで指定したファイルをとタイムスタンプ比較を行い、それよりも新しければ真とするという働きを持つオプションだ。

## 1.指定日時との比較

これを使えばまず、指定日時との比較は簡単にできる。

YYYY/MM/DD hh:mm:ssよりも新しいファイルを抽出したいなら、こんなシェルスクリプトを書けばよい。

```bash:
touch -t YYYYMMDDhhmm.ss thattime.tmp
find /TARGET/DIR -newer thattime.tmp
rm thattime.tmp
```

touchコマンドの書式の事情により、mmとssの間にピリオドを挿れないといけない点に注意してもらいたい。

次に「より古い」ものを抽出したいならどうするか。それには基準となる日時の1秒前（`YYYYMMDDhhmms1`とする）のタイムスタンプを持つファイルを作り、-newerオプションの否定形を使えばよい。

```bash:
touch -t YYYYMMDDhhmm.s1 1secbefore.tmp # 基準日時の1秒前
find /TARGET/DIR \( \! -newer 1secbefore.tmp \)
rm 1secbefore.tmp
```

それでは「等しい」としたいならどうすればよいか。それには基準日時のファイルとその1秒前のファイルの2つを作り、「基準日時1秒前より新しい」かつ「基準日時を含むそれ以前」という条件にすればよい。

```bash:
touch -t YYYYMMDDhhmm.ss thattime.tmp
touch -t YYYYMMDDhhmm.s1 1secbefore.tmp
find /TARGET/DIR -newer 1secbefore.tmp \( \! -newer thattime.tmp \)
rm 1secbefore.tmp thattime.tmp
```

## 2.n秒前より新しい、古い、等しい

基準日時との新旧比較のやり方がわかったのだから、あとは現在日時のn秒前、およびn-1秒前という計算ができれば実現できることになる。

それはどうやるのかといえば、[シェルスクリプトで時間計算を一人前にこなす](http://qiita.com/richmikan@github/items/14e32d099bd9bcc7f8e8)にて書いていた。そう、日常時間(YYYYMMDDhhmmss)をUNIX時間に変換して引き算し、それを元に戻せばいいのだ。そしてそのために、[POSIXの範囲で動くコマンド"utconv"](https://gist.github.com/richmikan/8703117)を自作していたのだ。

それでは、1分30秒前より新しい、等しい、古いファイルを抽出するシェルスクリプトを書いてみよう。

```bash:1分30秒前より新しいファイルを抽出
now=$(date '+%Y%m%d%H%M%S')
t0=$(echo $now                |
     utconv                   |
     awk '{print $0-60*1-30}' |
     utconv -r                |
     sed 's/..$/.&/'          )
touch -t $t0 thattime.tmp
find /TARGET/DIR -newer thattime.tmp
rm thattime.tmp
```

```bash:1分30秒前より古いファイルを抽出
now=$(date '+%Y%m%d%H%M%S')
t1=$(echo $now                |
     utconv                   |
     awk '{print $0-60*1-31}' |
     utconv -r                |
     sed 's/..$/.&/'          )
touch -t $t1 1secbefore.tmp
find /TARGET/DIR \( \! -newer 1secbefore.tmp \)
rm 1secbefore.tmp
```

```bash:ぴったりの1分30秒前のファイルを抽出
now=$(date '+%Y%m%d%H%M%S')
t0=$(echo $now                |
     utconv                   |
     awk '{print $0-60*1-30}' |
     utconv -r                |
     sed 's/..$/.&/'          )
t1=$(echo $now                |
     utconv                   |
     awk '{print $0-60*1-31}' |
     utconv -r                |
     sed 's/..$/.&/'          )
touch -t $t0 thattime.tmp
touch -t $t1 1secbefore.tmp
find /TARGET/DIR -newer 1secbefore.tmp \( \! -newer thattime.tmp \)
rm thattime.tmp 1secbefore.tmp
```
macにcool retro termを入れる

#Intro
ブラウン管ライクな昔のターミナルを再現したターミナルソフトです
https://github.com/Swordfish90/cool-retro-term

#前提
xcodeがインストールされてること(初期セットアップ済み)
homebrewがインストールされてること

#手順

on terminal.app

```bash
cd ~
brew install qt5
git clone --recursive https://github.com/Swordfish90/cool-retro-term.git
export CPPFLAGS="-I/usr/local/opt/qt5/include"
export LDFLAGS="-L/usr/local/opt/qt5/lib"
export PATH=/usr/local/opt/qt5/bin:$PATH
cd cool-retro-term
qmake && make
mkdir cool-retro-term.app/Contents/PlugIns
cp -r qmltermwidget/QMLTermWidget cool-retro-term.app/Contents/PlugIns
open cool-retro-term.app

#/Applicationに移動しておく
cd ~
mv cool-retro-term/ /Applications/
```

#できた！
Amber
![スクリーンショット 2014-11-24 23.38.37.png](https://qiita-image-store.s3.amazonaws.com/0/56598/d0c2cccf-c7fb-52f1-b7f0-59301637d412.png)

Apple][
![スクリーンショット 2014-11-24 23.40.23.png](https://qiita-image-store.s3.amazonaws.com/0/56598/ac951a1d-e44a-51f9-d35a-a17da6e620f3.png)

その他7種類くらいありました。

#感想
気分転換に使ってみます
Sublime Text 3 にて Shift-JIS ファイルを開く方法



## インストール

1. package control で
**ConvertToUTF8** をインストール。
2. これだけだと, Shift-JISファイル開くとなんかエラー出る。
3. ググると **Codecs33** もpackage control でインストールせよと書いてある → しかしそんなパッケージ見つからん.
4. https://github.com/seanliang/Codecs33/tree/osx からZipダウンロードして ~/Library/Application Support/Sublime Text 3/Packages に展開(フォルダ名 Codecs33 )
5. Sublime Text を再起動

## 利用法

1. Shift-JISファイルを開くだけ。

## UTF-8に変換

1. Shift-JISフィアルを開いた状態で [File] -> [Set File Encodeing to] -> [UTF-8]
2. Save.
MacOS で Rails(redis-objects)+Redis 使ってみた


危険なほどのスピードで動くという Redis を Rails から触ってみます。
MaxOSX 10.10 (Yosemite) です。

##導入
###インストール
brewで入れます。

```bash
brew install redis
```

###自動起動
```bash
cp /usr/local/Cellar/redis/2.8.17/homebrew.mxcl.redis.plist ~/Library/LaunchAgents/
launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.redis.plist
```

`~/Library/LaunchAgents/` が無い人は `mkdir` で作成してください。

###設定ファイル
`/usr/local/etc/redis.conf` にあります。今回はこのまま。

###ログファイル
`/usr/local/var/log/redis.log`

##起動確認
###クライアントを起動
```bash
redis-cli

127.0.0.1:6379> set hoge fuga
OK
127.0.0.1:6379>
127.0.0.1:6379> get hoge
"fuga"
```

##Rails
```Gemfile
gem 'redis-objects'
```
```bash
bundle
```

```config/initializers/redis.rb
Redis.current = Redis.new(:host => '127.0.0.1', :port => 6379)
```

###簡単なモデルを書いてみる
```hoge.rb
class Hoge < ActiveRecord::Base

  include Redis::Objects
  list :list_value
  hash_key :hash_value

end
```

`Hoge#list_value` と `Hoge#hash_value` が `Redis` で扱えるようになります。

###ハマったところ
```
hoge = Hoge.new
hoge.list_value << 1
hoge.save
```
はダメで、

```
hoge = Hoge.new
hoge.save
hoge.list_value << 1
```
は OK でした。save してから触りましょう。

##どんな型が扱えるのか
https://github.com/nateware/redis-objects
を読んでください。
Mackerelを使ってみる


IDCFクラウドを使うようになり、Mackerelが無料で使えるということだったので、インストール・設定してみました。

### サインアップ
IDCFクラウドのクラウドコンソールのメニューから、Mackerelを選択し、
現在のアカウントでサインアップしておきます。
サインアップが終わったら、適当なオーガニゼーションを作成しておきましょう。

### mackerel-agentインストール
仮想マシンを立ち上げて、[手順](http://help-ja.mackerel.io/entry/howto/install-agent/rpm)を参考にインストールします。
今回はrpmでやってみました。

```
rpm -ivh http://file.mackerel.io/agent/rpm/mackerel-agent-latest.noarch.rpm
```

`/etc/mackerel-agent/mackerel-agent.conf`を編集し、api-keyを設定する必要があります。
ここで登録するapi-keyは **MackerelのAPIキー** なので間違えないように。（IDCFクラウドのAPI Keyではない）
api-keyはMackerel画面のオーガニゼーションのページから確認できます。

設定が終わったら起動。

```
[root@enokido-instance-1 ~]# sudo /etc/init.d/mackerel-agent start
Starting mackerel-agent:                                   [失敗]
[root@enokido-instance-1 ~]#
```

あれ、失敗？

/var/log/mackerel-agent.logがmackerel-agentが吐いているログ

```
2014/11/12 17:45:30 INFO main Starting mackerel-agent version:0.12.3, rev:ed2ae57
2014/11/12 17:45:30 CRITICAL main Apikey must be specified in the command-line flag or in the config file
2014/11/12 17:45:30 ERROR main Failed to remove the pidfile: /var/run/mackerel-agent.pid: remove /var/run/mackerel-agent.pid: no such file or directory
```

あぁすいません、confファイルのapikeyの行がコメントアウトされたままでした。。。
コメントアウト外して再度起動コマンド実行、で起動成功しました。

```/etc/mackerel-agent/mackerel-agent.conf(apikeyはマスクしてます）
# pidfile = "/var/run/mackerel-agent.pid"
# root = "/var/lib/mackerel-agent"
# verbose = false
apikey = "xxxxxxxxx"
```

Mackerelにメトリクス送信されることも確認できました。

### mackerel-agent-plugins
ミドルウェア毎のメトリクスが取れるプラグイン群があるので、こちらもインストールしておきます。

http://help-ja.mackerel.io/entry/howto/mackerel-agent-plugins

```プラグインインストール実行イメージ
root@enokido-instance-1 mackerel-agent]# curl -fsSL https://mackerel.io/assets/files/scripts/setup-yum.sh | sh
This script requires superuser authority to configure Mackerel yum repository:
++ mktemp
+ gpgkey_path=/tmp/tmp.2TxfkfgY6q
+ curl -fsS -o /tmp/tmp.2TxfkfgY6q https://mackerel.io/assets/files/GPG-KEY-mackerel
+ rpm --import /tmp/tmp.2TxfkfgY6q
+ rm /tmp/tmp.2TxfkfgY6q
+ cat
done
To install mackerel-agent type: sudo yum install mackerel-agent
[root@enokido-instance-1 mackerel-agent]# yum install mackerel-agent-plugins
```

試しに、Apacheのメトリクスを取得してみます。

#### Apache向けの設定

Apache向けの設定を`/etc/mackerel-agent/mackerel-agent.conf`に追加します。
元々記述はあるので、コメントアウトを外すだけです。

```/mackerel-agent.conf
# Plugin for Apache2 mod_status
#   By default, the plugin accesses to http://127.0.0.1/server-status?auto
[plugin.metrics.apache2]
command = "/usr/local/bin/mackerel-plugin-apache2"
```

ApacheのServerStatusを有効にしないといけないようなので、こちらを
設定しましょう。

httpd.confにはServerStatus用のLocation設定がコメントアウトされた状態で記述されているので、これを外します。
Allowはlocalhostだけ入れておけばよいか、と思うので追加しておきましょう。

```httpd.conf
<Location /server-status>
    SetHandler server-status
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1
</Location>
```

mackerel-agentを再起動します。

```
/etc/init.d/mackerel-agent restart
```

これだけで、対象となった仮想マシンをMackerel画面で見ると
「Custom Metrics」
という項ができていて、そこにApacheの各種メトリクスが計上されるようになりました。
簡単で、素晴らしいですね。
【解決方法】AndroidのSQLiteではSELECT文が発行できないって本に書いてあったけど

1週間ちょっと前に人生初で完成させたiOSアプリ。

SQLiteをかましてあって、いろいろ検索で取ってくるというのが処理のコアなのだが
急遽これもまた初Androidで開発することに…。

とある参考書をみると、「SQL文のうちSELECT文を発行することができない」とあるのだが
それでは困る！
iOSはすべてSQLで処理をしてきたのだ。。。

ネットで調べてみると以下のことが判明。
query　だと「お仕着せフォーマット」でクエリせざるを得ないのだが
rawQuery　だとSQLがそのまま使えるとな！
http://www.sakc.jp/blog/archives/23657
http://android.roof-balcony.com/shori/strage/select/

有名なコトなのかもしれないけれど、これはありがたい。
誰かの救けになることを信じて、情報共有する。
gif で bug などを伝える


![05l.jpg](https://qiita-image-store.s3.amazonaws.com/289/29618/605290e5-02fe-8be6-e86c-72b1578f1f40.jpeg "05l.jpg")

頻繁に説明している気がするから書く.

## 目的

Web サイトを作っている際に bug や完成状態を動きを含めて共有したいときがある.
そんなときに文章で説明するのは厄介なので, gif で撮って添付するのが楽.

## 手段

### [Gyazo Gif](https://gyazo.com/)
立ち上げて範囲選択するだけで自動的に gif を撮ってくれる.
終わると gyazo に upload してブラウザで開いてくれるので極めて便利.

### [LICEcap](http://www.cockos.com/licecap/)

Gyazo に上げたくないときなどはこちらを使う.
Max FPS: 8 くらいがちょうどいい.

## 実践

### kobito の emoji preview 機能を伝える

![kobitosample.gif](https://qiita-image-store.s3.amazonaws.com/289/29618/3e1c0e5f-4188-64f6-3f3c-e9e3086bc802.gif "kobitosample.gif")

### GitHub の issue に貼り付ける

コメントをするスペースにドラッグアンドドロップ.

![test.gif](https://qiita-image-store.s3.amazonaws.com/289/29618/65fdf763-1107-20f9-a6a6-b8155e7bf02e.gif "test.gif")

## Reference

[岐阜県 緑 地図｜フリー イラスト](http://free-japan-map.com/25gifu/05-gifu.html)
SwiftでHTTPリクエストする

SwiftでシンプルにHTTP-GETするサンプルコードは多数見かけるが、HTTP-POSTする例を見かけないので、HTTP-GET、JSONデータをHTTP-POSTするコードをシンプルに書いてみた。

**環境**
- Xcode 6.1
- iOS 8.1

```swift:ViewController.swift
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
    
    // HTTP-GET
    @IBAction func getAsync(sender: AnyObject) {
        
        // create the url-request
        let urlString = "http://httpbin.org/get"
        var request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
        
        // set the method(HTTP-GET)
        request.HTTPMethod = "GET"
        
        // use NSURLSessionDataTask
        var task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: { data, response, error in
            if (error == nil) {
                var result = NSString(data: data, encoding: NSUTF8StringEncoding)!
                println(result)
            } else {
                println(error)
            }
        })
        task.resume()
        
    }
    
    
    // HTTP-POST
    @IBAction func postAsync(sender: AnyObject) {
        
        // create the url-request
        let urlString = "http://httpbin.org/post"
        var request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
        
        // set the method(HTTP-POST)
        request.HTTPMethod = "POST"
        // set the header(s)
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        
        // set the request-body(JSON)
        var params: [String: AnyObject] = [
            "foo": "bar",
            "baz": [
                "a": 1,
                "b": 20,
                "c": 300
            ]
        ]
        request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: nil)
        
        // use NSURLSessionDataTask
        var task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: {data, response, error in
            if (error == nil) {
                var result = NSString(data: data, encoding: NSUTF8StringEncoding)!
                println(result)
            } else {
                println(error)
            }
        })
        task.resume()
        
    }
        
}
```
Yosemiteにして起動しなくなったrEFItの解決法


## 追記(2015/2/10)

「解決法」の項目のコードを修正しました。
````enable-always.sh````を実行した方が良さそう。

## 超絶便利なrEFIt

Macに複数のOSをインストールしているときに使うと便利なツール、rEFIt。

- [rEFIt - An EFI Boot Menu and Toolkit](http://refit.sourceforge.net/)
- [rEFItを使ったマルチブート【Mac】 - TACATAKATACA BLOG](http://tacatakatca.hatenablog.com/entry/20140501/1398908080)
- [rEFIt ~ 複数のOSの中から起動するOSを選択する(Intel Mac 用) | Basic Werk](http://basicwerk.com/blog/archives/817)

自分はBootcampで入れたWindows 10とのデュアルブートにしてあります。

## YosemiteにしてからrEFItが起動しない

ところが先日やっとこさ重い腰を上げてMacの方をYosemiteにアップグレードしたらrEFItが起動しなくなりました。

optionキーを押しながらMacを起動すれば起動ディスクを選択する画面になってそこからWindowsを起動することはできるのですが、それが面倒でrEFItを入れてるのに本末転倒です。

## 解決法

rEFItを削除したり再インストールしたり色々試したけど解決せず諦めていると解決策を発見。

- [mac - rEFIt boot changed after update to Yosemite - Ask Different](http://apple.stackexchange.com/questions/155008/refit-boot-changed-after-update-to-yosemite)

どうやらYosemiteからはrEFItのインストール後に自分で有効にしなきゃいけないみたいです。

```bash:Terminal
$ cd /efi/refit
$ ./enable-always.sh
```

ちなみにOSX 10.10.1 にアップデートしたらまたしてもrEFItが起動しなくなったので、OSのバージョンが上がったら毎回やらなきゃいけないっぽいです。

多少面倒になったけど、解決法がわかって良かったです。
Chef memo1


[Chef実践入門 ~コードによるインフラ構成の自動化](http://www.amazon.co.jp/dp/477416500X) のまとめノート

# 1 はじめに

## 1.1 なぜChefが注目されているのか

### ビジネス速度の変化

### ソフトウェア開発プロセスの変化
* ウォーターフォールからアジャイルへ

### 開発(dev)と運用(ops)の対立
* 開発者と運用者の考え方の違い
* 開発者は新たな機能を追加して反映にリリースしたい
* 運用者はそのソフトウェアが安定して動作するようになるべく変更はさけたい

### DevOpsの提唱
* DevOpsとは、ソフトウェア開発手法の一つ。開発 (Development) と運用 (Operations) を組み合わせたかばん語であり、開発担当者と運用担当者が連携して協力する開発手法をさす。
* 考え方
  - 尊重
  - 信頼
  - 失敗に対する健全な態度
  - 相手を避難しない
* ツール
  - 自動化されたインフラ
  - バージョン管理システムの共有
  - ワンステップによるビルドとデプロイ
  - フィーチャーフラグ
  - メトリクスの共有
  - IRCとインスタントメッセンジャーのbot

## 1.2 Infrastructure as Code

### Infrastructure as Codeとは
* 自動化されたインフラを実現するための方法。今まで手作業で行っていたインフラの構築作業をコードで記述することで自動化する。

### 従来型のインフラ構築の問題点
* サーバー台数に比例して増える作業時間
* 手順書の陳腐化
* 作業ミス
* 再利用が難しく無駄が発生

### コードによるインフラ記述の優位性
* いわずもがな

### コードによるインフラ構築の実現方法

#### シェルスクリプト
* 制御構文とかいろいろ大変

#### デプロイツール(capistrano, fabric)
* そもそもデプロイ用なので...

#### インフラ構築自動化ツール(Chef)
* Ruby構文で書くので読みやすい書きやすい

```
cookbook_file "#{Chef::Config[:file_cache_path]}/supervisor-3.0.rpm" do
  source "supervisor-3.0a12-2.el6.noarch.rpm"
  mode 00644
end
```
golang JSON API クライアントサンプル


Heroku にある JSON API へアクセスする。


* GET で JSON を取得
`[{"id":1,"name":"MotoGP"},{"id":2,"name":"Moto2"},{"id":3,"name":"Moto3"}]`
* 認証トークンを、リクエストヘッダに入れる
* パースして、`Class` のスライスに格納

```Go
package main

import (
     "encoding/json"
     "fmt"
     "io/ioutil"
     "log"
     "net/http"
)

type Class struct {
     Id   int    `json:"id"`
     Name string `json:"name"`
}

func (class Class) String() string {
     return fmt.Sprintf("Id=%d Name=%s", class.Id, class.Name)
}

func main() {
     url := "https://pure-eyrie-6097.herokuapp.com/classes"

     client := &http.Client{}

     req, err := http.NewRequest("GET", url, nil)
     if err != nil {
          log.Fatal(err)
     }

     req.Header.Add("x-auth-token", "token1")
     res, err := client.Do(req)
     if err != nil {
          log.Fatal(err)
     }

     defer res.Body.Close()

     if res.StatusCode != http.StatusOK {
          log.Fatal(res)
     }

     body, err := ioutil.ReadAll(res.Body)
     if err != nil {
          log.Fatal(err)
     }

     fmt.Println(string(body))

     var classes []Class
     err = json.Unmarshal(body, &classes)
     if err != nil {
          log.Fatal(err)
     }

     for i := 0; i < len(classes); i++ {
          fmt.Println(classes[i])
     }
}
```
ちょっと楽しい、Rubyの数値系のメソッド


数値使うときのメモをいくつか。

# next

+1した値を返します。

```
1.next #=> 2
```

# pred

-1した値を返します。

```
2.pred #=> 1
```

# step

Numericクラスで用意されているメソッドです。
指定した回数だけ繰り返し処理を行うことが出来ます。

```step.rb
1.step(10, 0.5) {|n| p n}
# => 

1.0
1.5

...

9.5
10.0 #10になるまで0.5ずつ足されていく
```

# zero?

0のときtrueを返します。

```
0.zero?
# => true
1.zero?
# => false
```
# nonzero?

0のときnil を返し、0でないとき自分自身の値を返します。

```
a = 0.nonzero?
p a #=> nil

a = 1.nonzero?
p a #=> 1
```
継続タスクで例外発生した場合の挙動

継続タスク途中で未補足な例外が発生しても後続のタスクは実行される。

```csharp
public static class ContinueWithExample
{
    public static void Run() 
    {
        var task = Task.Factory.StartNew(() =>
        {
            Thread.Sleep(500);
            throw new Exception("なんらかのエラー");
        })
        .ContinueWith((t) =>
        {
            //実行される
            Console.WriteLine("IsFaulted:{0}", t.IsFaulted);  //True
            Thread.Sleep(500);
            //throw new Exception("なんらかのエラー2");
        })
        .ContinueWith((t2) =>
        {
            //実行される
            Console.WriteLine("IsFaulted:{0}", t2.IsFaulted);  //False  ※前タスクの結果
            Thread.Sleep(500);
            throw new Exception("なんらかのエラー3");
        });

        try
        {
            task.Wait();
        }
        catch (AggregateException exc)
        {
            Console.WriteLine(exc.Message);
        }
    }
}
```

タスク生成時にTaskContinuationOptionsを渡すことで、

「前タスクがエラー時にだけ実行するタスク」などを作ることができる。

```csharp
public static class ContinueWithExample2
{
    public static void Run()
    {
        var task = Task.Factory.StartNew(() =>
        {
            Thread.Sleep(500);
            throw new Exception("なんらかのエラー");
        })
        .ContinueWith((t) =>
        {
            //実行される
            Console.WriteLine("IsFaulted:{0}", t.IsFaulted);  //True
            Thread.Sleep(500);
            //throw new Exception("なんらかのエラー2");
        })
        .ContinueWith((t2) =>
        {
            //実行される
            Console.WriteLine("IsFaulted:{0}", t2.IsFaulted);  //False  ※前タスクの結果
            Thread.Sleep(500);
            throw new Exception("なんらかのエラー3");
        })
        .ContinueWith((t4) =>
        {
            //実行される
            Console.WriteLine("エラー時タスクを実行します。");
            Console.WriteLine("IsFaulted:{0}", t4.IsFaulted);  //True
        },TaskContinuationOptions.OnlyOnFaulted)
        .ContinueWith((t5) =>
        {
            //前タスクは正常終了した為、実行されない。
            Console.WriteLine("エラー時タスク2を実行します。");
            Console.WriteLine("IsFaulted:{0}", t5.IsFaulted); //False ※前タスクの結果
        }, TaskContinuationOptions.OnlyOnFaulted);

        try
        {
            task.Wait();
        }
        catch (AggregateException exc)
        {
            Console.WriteLine(exc.Message);
        }
    }
}
```
Android Studio 1.0RC1のインストール(Mac)

AndroidStudioの1.0RC1（正式リリース候補1）が出てたので早速手持ちのMacにインストールしてみました。

※あくまでβ以前チャンネルの配信なので、何があるか分かりません。ので業務などクリティカルで使ってる方は要注意。０．８βからGladleプラグインの必須バージョンが変わっているので、この環境で作ったプロジェクトはビルドに(多分)失敗します。

出来るだけクリーンに近い状態で入れてみたかったので、まずやった事

1.古いバージョンの消去（アプリケーションディレクトリから.appを削除）
2.ADTもついでにアプリケーションディレクトリから削除
3.SDKディレクトリの削除（自分のHomeDirの下あたりにあるはず？）
4.古いプロジェクトディレクトリの移動
5.HomeDirの.androidディレクトリの移動（※これやると作ったエミュレータ設定も消し飛ます）

ここまでやって
http://tools.android.com/download/studio/canary
からダウンロードしたZipを解凍、appをアプリケーションディレクトリにコピーしてダブルクリック。

起動するとセットアップが走り、SDKのダウンロードなどが始まります。

※このとき、プロジェクト保存ディレクトリを移動せず、古いバージョンのセットアップを引き継いで、最後の状態がプロジェクトオープン状態だった場合、既存のプロジェクトがセットアップより先にオープンされるかもです。File->CloseProjectすればセットアップが走ります。

ダウンロードが完了したらSDK Managerで必要なものを追加で入れたり、消した場合はエミュレータの設定をちょいと作り直せば完了です。

今現在表に出てる0.8系βはSDKを個別にダウンロードして放り込んだりしなけりゃいけなかったのに比べるとはるかに楽にセットアップ出来るようになってますね、便利です。
Yahoo!ローカルサーチAPIの最大値について

お世話になります。

Yahoo!ローカルサーチAPIのレスポンス結果についての質問です。

例えば、「整骨院」で検索した場合
-Total-36770-/Total-と36770件という結果が返ってきます。
（↑タグ表記は投稿できないようなので<>を--に変更してます）

そして、リクエストに

&results=100
&start=2000


を付加して、リクエストすると
正常にレスポンスが100件分返ってきます。

最大件数が36770件で、
リクエストが100件×2000ページ目なので20万件目となり
レスポンス結果にエラーが起こることを想定していましたが
正常にレスポンスが返ってきます。

-ResultInfo-
-Count-100-/Count-
-Total-36770-/Total-
-Start-2000-/Start-

検索結果件数の最大値を超えたレスポンス結果は
何を意味していますでしょうか？

どうぞよろしくお願いします。
Node.jsでFFI使ったときのメモ、あるいは、FaceTimeカメラを使うには

# まえがき

Node.jsのffiモジュールでOpenCVつかって、Webカメラのキャプチャーをやった。JavaScriptでFFIする際には内部的には型付き配列(Typed Array)が使われてる模様。

今回はOSXで試した。多分UNIX系なら同様に動かせると思う。


# 構造体を使うには

ref-structを入れる。

```js
var Struct = require('ref-struct');
var CaptureVal = Struct({
 
});
var CaptureValPtr = ref.refType(CaptureVal); 
```

# 配列を使うには

ref-arrayを入れる。

## サイズが指定されている配列の宣言

```js
'colorModel': ArrayType('char', 4)
```

# 引数にNULLを渡すには

# char*の扱い

'string'でだいたい扱える

```js
libopencv_highgui.cvSaveImage("snap.jpg",frame,ref.NULL);
```

# まとめ

ffiを応用した、Node.jsからCocoa APIが叩けるNodObjCモジュールを使ってる割には、ffiモジュール関連の知識がなく、今回の作業で、色々学んだ。

# 関連記事

- [Node.jsでFaceTime HDカメラを使う](https://abrakatabura.hatenablog.com/entry/2014/11/24/192128)
- [RustでFaceTime HDカメラやWebカメラを使う](https://abrakatabura.hatenablog.com/entry/2014/10/23/063643)
- [GoでFaceTime HDカメラやWebカメラを使う](https://abrakatabura.hatenablog.com/entry/2014/10/24/065607)
- [だれもがターミナルにWebカメラ映像を表示を使うことができる時代なのに……](https://abrakatabura.hatenablog.com/entry/2019/02/18/213027)
- [gRPCでmojaveに勝利してリモートからWebカメラを利用した](https://abrakatabura.hatenablog.com/entry/2019/03/06/082330)
コード読んでて、思わず調べたRubyの記法いくつか


最近Rubyを書き始めました。Rubyで書かれたプログラムのコードを読んでいると、たまに「何だこれは..」となる記述に出くわすことがあるので、その時調べたもののメモ。

# ||=
値がnilの場合、右辺の値を代入して初期化してくれます。
以下のような動きをします。

```a.rb
hoge = nil
hoge ||= "fuga"
p hoge #=> "fuga"
```

nilでないときは代入しません。

```b.rb
hoge = "piyo"
hoge ||= "fuga"
p hoge #=> "piyo"
```

←[追記]
※falseの時にも代入されます。

```rb
hoge = false
hoge ||= "fuga"
p hoge #=> "fuga"
```


# <=>
「UFO演算子」と呼ばれる比較演算子です。比較結果を数値で返してくれます。

- 左辺が大きければ1を返す
- 右辺が大きければ-1を返す
- 等しければ0を返す

```rb
100 <=> 10 #=> 1
100 <=> 200 #=> -1
100 <=> 100 #=> 0
```

# <<
配列で自信の末尾に破壊的に値を追加してくれます。

```rb
array = [1, 2, 3, 4]
array << 5
p array #=> [1, 2, 3, 4, 5]
```

# ::

定数のスコープ演算子です。```::```を使って定数を呼び出せます。

```a.rb
class Hoge
  FUGA = "piyo"
end

p Hoge::FUGA #=> "piyo"
```

こっちは定数でないので動きません。

```b.rb
class Hoge
  fuga = "piyo"
end

p Hoge::fuga #=> "piyo"
```

# ..
「範囲演算子」というもので、範囲オブジェクトを作ってくれます。

```a.rb
p (0..10).to_a　#=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```
これは「…」だと最大値を含みません。

```b.rb
p (0...10).to_a #=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
```

# ? (メソッド名に付く場合)
慣用的に真偽値を返すメソッド名で使われるようです。

```rb
def foo?
  true
end

p foo? #=> true
# 否定と組み合わせて
p !foo?  #=> false
# これは以下のように書き換えることも出来ます
p foo?.! #=> false 
```

# ! (メソッド名につく場合)
「破壊的メソッド」と呼ばれるのメソッド名などで見かけます。
!が付くか付かないかでは挙動が違うメソッドがいくつかあるので注意が必要です。

例えば```String#chop!```などの破壊的メソッドは、他の変数の参照先についても影響を与えてしまいます。

```chop.rb
hoge = "hoge"
fuga = hoge

hoge.chop
p fuga #=> "hoge"
hoge.chop!
p fuga #=> "hog"
```


# 参考
- [初心者向け] RubyやRailsでリファクタリングに使えそうなイディオムとか便利メソッドとか
http://qiita.com/jnchito/items/dedb3b889ab226933ccf
- Rubyで使われる記号の意味
http://docs.ruby-lang.org/ja/2.0.0/doc/symref.html
nokogiri 基礎

## nokogiriとはなんぞや
ググってください

## ドキュメントの解析
HTMLドキュメントとXMLドキュメントの解析の二つの方法がある。

```rb

doc = Nokogiri::HTML(html_document)
doc = Nokogiri::XML(xml_document)

```

## データ抽出について
nokogiriはドキュメントをツリーデータ構造に変換する。
ツリー構造を頭に置きながら考えると良い感じに抽出できる。

実際に書いてみる

```rb

require 'open-uri'
# URLから持ってくるのに必要
require 'nokogiri'
# スクレイピング用

doc = Nokogiri::HTML(open('http://sadakoa.org/'))
# sadakoa.orgを解析
doc.xpath('//figcaption').each do |sample|
  #figcaption要素を解析して
  puts sample.text
  # 出力
end

```

出力結果

```rb
[desktop] ruby main.rb              21:08:48  ☁  master ☂ ✖ ✭

# sadakoa.org内のfigcaption要素を抽出
Web Design
UI Design
Icon Design
Illust Design
Portfolio Redesign Concept
Dark UI Form
GAMEBOY ADVANCE SP
Red UI Kit
Slack Icon					
Connect

```

タグ要素を全部引っ張ってくるのはだるいので、特定のclassもしくはid属性を持っている奴を引っ張りたい。

```rb

#class属性、id属性はこう
h1[@class = "***"]
p[@id = "***"]

doc.xpath('//div[@class = "about-txt"]/p').each do |sample|
  #div要素のabout-txtというclassが付いているpを解析して
  puts sample.text
  # 出力

```

出力結果

```rb

Thanks for watching :) I'm sadakoa and 20 years old.
I'm Web Designer and Front-end Engineer.
Filed: UI, IA, Icon, Graphic, DTP, Software, and Interaction Design.
Use: Jade / Stylus / CoffeeScript / jQuery / roots / ruby / Rails / vvvv / Sketch3 / Sublime Text 3 /

```

## CSSセレクターの書き方

方法は二つある

```rb
//p/a
# p > a と、CSSでは記述される

p.wow
# class属性にwowの値が含まれていなければならない
# 前述でやってい書き方は、完全に一致する必要があるので厳しい。

```

## まとめ
君だけのスクレイピングで、お気に入りのアダルトサイトからリンクを取得してサイトを作ろう。