OmniAICreator/Qiita-1.07M huggingface dataset:
Pivotal Tracker APIを使って、見積もったポイントの合計を計算する


Gemfile

```rb
source 'https://rubygems.org'

gem 'pivotal-tracker'
```

main.rb

```rb
require 'rubygems'
require 'pivotal-tracker'

PivotalTracker::Client.token = 'api token'
project_id = 12345
label = '見積もる分'

project = PivotalTracker::Project.find(project_id)

sum = 0

project.stories.all(label: label).each do |story|
  next if story.estimate == -1
  sum += story.estimate
end

puts sum
```

story.estimateが-1を返る場合はそのストーリーに見積もりが付いてない状態でした。

## 初期設定

* PivotalTracker::Client.tokenにはapiトークンを設定します。
* project_idには見積もりたいプロジェクトのidを設定します。
* labelには、見積もりたいストーリーに例えば(見積もる分)みたいなラベル名を付けておいたのを設定します。
python > socket > recvfrom() > サンプルプログラム

```txt:動作確認
CentOS 6.5
```

pythonでのノンブロッキングUDP受信をしたい。

とりあえず以下を実行

https://wiki.python.org/moin/UdpCommunication

```151111a.py
import socket

UDP_IP = "127.0.0.1"
UDP_PORT = 5005

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))
 
while True:
  data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
  print "received message:", data
```

１つのターミナルにて以下を実行しておく。

```
$ python 151111a.py
```

同じPCの別ターミナルにて以下を実行する。

```
$ echo "test\n" | nc -u 127.0.0.1 5005
```

そうすると`151111a.py`を実行した方が以下のようになる。

```
$ python 151111a.py 

received message: test\n
```

送信文字列は`test\n`としているが、`test`でも受信できた。
プロセス、スレッドの優先度一覧を取得する(psコマンドを使用)

psコマンドによりプロセスのスレッド毎の優先度を取得する方法について

```shell-session
$ ps -em -o pid,tid,policy,pri,ni,rtprio,comm
  PID   TID POL PRI  NI RTPRIO COMMAND
    1     - -     -   -      - init
    -     1 TS   19   0      - -
    2     - -     -   -      - kthreadd
    -     2 TS   19   0      - -
    3     - -     -   -      - ksoftirqd/0
    -     3 TS   19   0      - -
    4     - -     -   -      - kworker/0:0
    -     4 TS   19   0      - -
    5     - -     -   -      - kworker/0:0H
    -     5 TS   39 -20      - -
    6     - -     -   -      - kworker/u2:0
    -     6 TS   19   0      - -
    7     - -     -   -      - rcu_sched
    -     7 TS   19   0      - -
    8     - -     -   -      - rcuos/0
    -     8 TS   19   0      - -
    9     - -     -   -      - rcu_bh
    -     9 TS   19   0      - -
   10     - -     -   -      - rcuob/0
    -    10 TS   19   0      - -
   11     - -     -   -      - migration/0
    -    11 FF  139   -     99 -
   12     - -     -   -      - watchdog/0
    -    12 FF  139   -     99 -
...
```

`-e` : 全てのプロセスを表示
`-m` : プロセスの後にスレッドを表示
`-o` : 出力フォーマットを指定
`pid` : プロセス ID
`tid` : スレッドのID
`policy` : プロセスのスケジューリングのクラス

- TS ⇒ SCHED_OTHER
- FF ⇒ SCHED_FIFO
- RR ⇒ SCHED_RR

`pri` : カーネルスケジューリングの優先度 1 ~ 139
`ni` : nice 値。19 ~ -20
`rtprio` : リアルタイム優先度。 1 ~ 99
`comm` : 実行コマンド

# メモ

BusyBoxのpsだとオプションが指定できないため、取得できなかった。

# 参考
[Man page of PS](http://linuxjm.osdn.jp/html/procps/man1/ps.1.html)
[Man page of SCHED](http://linuxjm.osdn.jp/html/LDP_man-pages/man7/sched.7.html)
[プロセスの優先度＠CetnOS 5.5 ](http://www.mazn.net/blog/2010/09/18/311.html)
centos > nc > コマンドが見つかりません > # yum install nc nmap

```txt:動作確認
CentOS 6.5
```

ncコマンドを使おうとしたら怒られた。

> bash: nc: コマンドが見つかりません


http://www.intellilink.co.jp/article/column/security-net01.html
> ...このため次のように、yumコマンドで簡単にインストールすることができます。
`# yum install nc nmap`

上記を実行したらncが使えるようになった。
XAMPPのphpMyAdminでcreate_tables.sqlをインポートし、MySQLを再起動しようと思ったら…

会社でXAMPPのphpMyAdminを使っています。

phpMyAdmin内で、「phpMyAdmin の設定保存場所が完全に設定されていないため、
いくつかの拡張機能が無効になっています。理由についてはこちらをご覧ください。」
と表示されていたため、「sql」の中に入っていた「create_tables.sql」をインポートしました。

その後、なぜかMySQLが起動しなくなってしまいました。
![image](https://qiita-image-store.s3.amazonaws.com/0/97725/87191ccb-77ef-0db9-6069-238c51befbb7.png)

エラーログを見てみるとこのようになっていました。
![image](https://qiita-image-store.s3.amazonaws.com/0/97725/cf78ab6a-e2a5-821f-a60d-eb61df8b5a8c.png)

管理者権限で実行するなど、いろいろと調べて試してみましたが駄目でした。
解決策があればよろしくお願い致します。
他のサーバー経由でWebサイトにアクセスする。（SSHポートフォワーディング）

テスト環境からしか接続が許されていないAPIサーバーへローカルの開発環境からアクセスするために多段でSSHポートフォワーディングしてSOCKS5を使用してどうにかしてみました。

![socks5.png](https://qiita-image-store.s3.amazonaws.com/0/32383/db07ab5b-72a6-88cc-95c5-1f958f21f4f7.png)
構成図です。
外部から接続出来るのはremote1のみ、APIサーバーから許可されているのはremote2のみです。
つまり、クライアントからの接続をremote2からのアクセスであるようにしたいわけです。
今回わかりやすいように最終目的地をYahooにしてあります。

## クライアントからremote2の22番へSSHポートフォワーディング
SSHのトンネルを使い、　ローカルの10022番へアクセスしたらremote2の22番へアクセスしたことになるよう設定します。

```bash
ssh -N -f -L 10022:192.168.1.11:22 hoge@222.111.111.xxx
```
これでポートフォワード出来ました。認証はパスワードでも鍵ファイルでも環境に合わせて行って下さい。

オプションは
* -N リモート・ホストでコマンドを実行しない。
* -f バックグランドで実行
* -L ポートフォワーディング

## クライアントからremote2上のSOCKS5サーバーへ接続
SOCKS（Wikipediaより引用）
> ファイアーウォールの背後にあり、外部サーバにアクセスする必要があるクライアントは、代わりに SOCKS プロキシサーバに接続できる。 SOCKS プロキシサーバはクライアントが外部サーバにアクセスする資格を制御し、外部サーバにリクエストを伝える。 SOCKS はまた正反対にも使用することができる。つまり、ファイアーウォールの外側のクライアント（"外部クライアント"）が、ファイアーウォールの内側のサーバ（内部サーバ）に接続することを可能にする。

ということで、リモート上で代わりに外部へ接続しに行ってくれます。これは、特に特別にサーバーを立てなくてもSSHが行ってくれます。

```
ssh -p 10022 -N -f -D 10080 piyo@localhost
```
これで何をやっているかというとremote2の22番につながっているlocalhostの10022番に対してSSH接続しています。そしてその時に-Dオプションをつけてlocalhostの10080番にダイナミックポートフォワーディング（SOCKSを使う）をしています。

これで上図の状態になりました。

## Yahooにアクセスしてみる。

ちょっと種類の違うプロキシができたことになるので使うのは難しくありません。

```bash
curl —socks5 localhost:10080 http://www.yahoo.co.jp/
```

これでremote2経由でアクセス出来ます。`~/.curlrc`へ

```
socks5 = "localhost:10080"
```

を追加してもいいです。ちなみにPHPからcurlでアクセスしたいなら

```php
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
curl_setopt($ch, CURLOPT_PROXY, 'localhost:10080');
```

を追加して下さい。

ブラウザからの接続はよく分かりませんが、プロキシ周りをいじるだけだと思います。
GitLabとdrone.ioのversion 0.4を利用してhiveのCI環境作成にトライする(Part 1)　～環境構築編～

[以前の投稿](http://qiita.com/letusfly85/items/b4e5fc67c9566765b794)で、hiveserver2のdockerイメージを作成しました。

このイメージと、drone 0.4を連携して、hiveクエリのCIができないかな、ということで試してみました。

# 1. 結論

できちゃいそう

# 2. [.drone.yml]

利用した`.drone.yml`は下記の通り、metasotre用のmysqldをスタートしてるあたり、まだこなれてないのですが今後改善予定です。

```yaml
build:
  image: letusfly85/hiveserver2
  commands:
    - sudo /etc/init.d/mysql start
    - hive -e 'create table hoge(name string)'

compose:
  zookeeper:
    image: jplock/zookeeper:latest
```

# 3. drone 0.4の構築について

備忘のためにメモを残します。

## 3-0. 環境情報

Ubuntu 14.04
Docker 1.9
docker-compose 1.5.0
Golang 1.5
GitLab 8.1.2

## 3-1. goenvのインストール

```bash
git clone https://github.com/wfarr/goenv.git ~/.goenv

echo 'export PATH=/root/.goenv/bin:\$PATH' >> ~/.bashrc
echo 'eval "$(goenv init -)"' >> ~/.bashrc
```

## 3-2. Golangのインストール

```bash
goenv install 1.5

echo 'goenv global 1.5' >> ~/.bashrc
echo 'export GOPATH=/root/go' >> ~/.bashrc
echo 'export PATH=$PATH:$GOPATH/bin' >> ~/.bashrc

echo 'export GO15VENDOREXPERIMENT=1' >> ~/.bashrc

source ~/.bashrc
```

## 3-3. drone 0.4のビルド

```
mkdir -p $GOPATH/src/github.com/drone

git clone https://github.com/drone/drone $GOPATH/src/github.com/drone/drone

apt-get install gcc make g++

cd $GOPATH/src/github.com/drone/drone
make deps
./contrib/setup-sassc.sh

make all
```

上記を実行すると「$GOPATH/src/github.com/drone/drone」にdroneという実行可能なバイナリファイルが出来上がります。

## 3-4. GitLab連携

環境変数を用意します。

* /etc/profile.d/drone.shなるものを用意しました。

中身は以下の通り

```bash
export SERVER_ADDR=:80
export REMOTE_DRIVER=gitlab
client_id=*******************************
client_secret=*******************************
export REMOTE_CONFIG="https://gitlab.test.com"
client_id=${client_id}&client_secret=${client_secret}&skip_verify=false&open=false&search=true"
```

## 3-5 drone起動

オプション[--debug]でわらわらとログが出力されます。

```bash
cd $GOPATH/src/github.com/drone/drone

./drone --debug
```

# 4. 実行してみた


[.drone.yml]を、リポジトリに格納して、masterにpushしました。

結果は下記の通り。行けそうですね。

![hive-de-ci.png](https://qiita-image-store.s3.amazonaws.com/0/49547/dcab6de6-8edf-d441-f2e8-4919fde996c3.png)

# 5. 課題

* JDBCドライバとDBUnitつかってテストできるかどうかを検証する
* metastore管理はderbyでいいし、zookeeperも一つのコンテナにまとめれば済むなのでもっとコンパクトに
* 成果物のデプロイ連携をどうするかを検討する
[iOS]中国語対応のために端末の言語環境の値を取得したときにハマったこと


iOSアプリの多言語化対応で簡体字・繁体字の対応を行っていて、端末の言語環境を取得してあれこれしようとしたんだけど、結構ハマった。

なお、この記事で指す端末とはiPhone SimulatorのiPhone6（iOS9.0）とする。

まず、中国語には大きくわけて

* 簡体字
* 繁体字

の二種類が存在する。

iOSでは

* 簡体中文＝zh-Hans
* 繁体中文＝zh-Hant

として分類されているようだ。

設定アプリを開いて
一般＞言語と地域と遷移して表示された画面で
端末の言語環境を確認することが可能だ。

使用言語を変更するときは
**iPhoneの使用言語**
から使用する言語を選択し、
地域を変更する場合は
**地域**
から使用する地域を選択する。


##UIの多言語化対応の場合

こちらは簡単でまずプロジェクトのInfoタブにあるLocalizationsに多言語化対応させたい言語を追加する。
そのあと、StoryboardのFile InspecterのLocalizationに上記で追加した言語が表示されているので、対応したStringsファイルを生成し、使用しているUIの多言語化対応をするだけである。
ざっくりした説明なので、詳しく知りたい人はググるべし。

##コード上で言語によって処理を分岐したい場合

ここでハマった。

下記のコードで端末の言語環境を取得できる。
`[NSLocale currentLocale].localeIdentifier`

だが、この値は端末の言語と地域の組み合わせで、取得できる値が変わってしまうようだ。

####地域が言語と一致しない場合

端末の言語環境は下記とする。

**言語：簡体中文**
**地域：アメリカ合衆国**

取得できる値。
`zh-Hans_US`

####地域が言語と一致する場合 その1

端末の言語環境は下記とする。

**言語：簡体中文**
**地域：中国**

取得できる値。
`zh_CN`

####地域が言語と一致する場合 その2

端末の言語環境は下記とする。

**言語：繁体中文**
**地域：中国**

取得できる値。
`zh-Hant_CN`

####検証した結果

**地域の設定次第で取得できる値が変わる**

困った。
ユーザーの言語環境なんてどうなっているかわからないので、簡体字を使用しているのか、繁体字を使用しているのか、
`[NSLocale currentLocale].localeIdentifier`
の値で判断をするのは難しいようだ。

###対応策

値を取得する方法を変えることにした。
`[[NSLocale preferredLanguages] objectAtIndex:0]`


参考：[iOSの言語設定に応じて設定されるNSLocaleの値について簡単にまとめてみる](http://qiita.com/nomadmonad/items/c3b6d04627df4d966f8e)

####地域が言語と一致しない場合

端末の言語環境は下記とする。

**言語：簡体中文**
**地域：アメリカ合衆国**

取得できる値。
`zh-Hans-US`

####地域が言語と一致する場合 その1

端末の言語環境は下記とする。

**言語：簡体中文**
**地域：中国**

取得できる値。
`zh-Hans-CN`

####地域が言語と一致する場合 その2

端末の言語環境は下記とする。

**言語：繁体中文**
**地域：中国**

取得できる値。
`zh-Hant-CN`

####検証した結果

この方法なら取得した値を見て、簡体字か繁体字かが判別できる。

ただし、下記のような場合はこの方法でも判別がつかなくなるので注意。

####地域が言語と一致する場合 その3

端末の言語環境は下記とする。

**言語：繁体中文**
**地域：台湾**

取得できる値。
`zh-TW`

詳しくは理解できていないのだが、どうやらISOで定義されている組み合わせの場合はそちらを表示して、そうでない場合は良きに計らって表示してくれるらしい。
甚だややこしい話である。

ちなみにiOS9で
`[[NSLocale preferredLanguages]`
が返す値が変更されている点もさらにややこしい。

参考：[iOS 9 での言語の identifier の変更](http://koze.hatenablog.jp/entry/2015/10/06/220000)

###こんな使い方をしてみた

```objectivec
NSString *countryCode = [[NSLocale preferredLanguages] objectAtIndex:0];
if ([countryCode hasPrefix:@"ja"]) {
    NSLog(@"日本語");
}
else if ([countryCode hasPrefix:@"en"]) {
    NSLog(@"英語");
}
else if ([countryCode hasPrefix:@"zh-Hans"] || [countryCode hasPrefix:@"zh_CN"]) {
    NSLog(@"簡体字");
}
else if ([countryCode hasPrefix:@"zh-Hant"] || [countryCode hasPrefix:@"zh_TW"]) {
    NSLog(@"繁体字");
}
```
    
試行錯誤している途中なので、抜け漏れがあったらごめんなさい。

※2015.11.12 追記

**言語：繁体中文（香港）**
**地域：日本**

取得できる値。
`zh-HK`

言語を繁体中文（香港）に設定した場合は、地域は関係なく`zh-HK`を返すようだ。
Atomのwebview内のフォントを変更する


## はじめに

筆者環境の場合、[web-search](https://atom.io/packages/web-search)のようなwebviewを用いたプラグインを使用するとCJKフォントで表示されてしまい、見栄えがあまりよろしくない。
「統」や「字」、「化」辺りを見ていただければ分かりやすいかと思う。

![web-searchでWikipediaを表示したところ](https://bytebucket.org/from_kyushu/qiita_posts/raw/49fa1f52961840d7ca4f83255ac52baab341faa2/images/webview_font/wikipedia_cjk.jpg)

`styles.less`で変更できないかとやってみたがうまくいかなかったので、`init.coffee`でイベントを拾って変更することにした。

APIドキュメントに載っていないものも用いているため、バージョンアップによって利用できなくなる恐れがあることをご注意いただきたい。

## パネルが開かれた際のイベント

APIドキュメントを眺めてもそれらしきものが見つからなかったのだが、[atom/panel-container.coffee at master · atom/atom](https://github.com/atom/atom/blob/master/src/panel-container.coffee)を見ると`onDidAddPanel`といううってつけのイベントが見つかった。
`PanelContainer`のオブジェクトは表示位置ごとに下記のようになっている。

- 上部パネル: `atom.workspace.panelContainers.top`
- 左部パネル: `atom.workspace.panelContainers.left`
- 右部パネル: `atom.workspace.panelContainers.right`
- 下部パネル: `atom.workspace.panelContainers.bottom`
- モーダルパネル: `atom.workspace.panelContainers.modal`

表示位置ごとに同じようなことを書くのは苦痛であるため、下記のように書いた。

```coffeescript
onDidAddPanelEventHandler = (params) ->
  {panel, index} = params
  # イベント発生時の処理

atom.workspace.panelContainers.modal.onDidAddPanel onDidAddPanelEventHandler
atom.workspace.panelContainers.top.onDidAddPanel onDidAddPanelEventHandler
atom.workspace.panelContainers.left.onDidAddPanel onDidAddPanelEventHandler
atom.workspace.panelContainers.right.onDidAddPanel onDidAddPanelEventHandler
atom.workspace.panelContainers.bottom.onDidAddPanel onDidAddPanelEventHandler
```

## webviewへCSSを適用させる

[electron/web-view-tag.md at master · atom/electron](https://github.com/atom/electron/blob/master/docs/api/web-view-tag.md)を読むと、`<webview>.insertCSS()`を使えばwebview内にCSSを追加できるようだ。
webview内にCSSを追加するのであればロードが終わる度に追加する必要があるため、`did-finish-load`イベントを拾うことにした。

```coffeescript
  try
    webview = panel.item.webview
  catch error
    return
  return unless webview
  webview.on "did-finish-load", ->
    this.insertCSS "*{font-family: Meiryo, sans-serif;}"
```

これでwebview内でロードが終わる度にCSSが追加され、指定したフォントで描画されるようになる。
上記指定では例えばGoogle等は一部指定したフォントにならないが、強制的に指定したフォントにしたければ`!important`を加えるとよい。

## 最終的に書いたもの

```coffeescript
onDidAddPanelEventHandler = (params) ->
  {panel, index} = params
  changeWebViewFontFamily panel

changeWebViewFontFamily = (panel) ->
  try
    webview = panel.item.webview
  catch error
    return
  return unless webview
  webview.on "did-finish-load", ->
    this.insertCSS "*{font-family: Meiryo, sans-serif;}"

atom.workspace.panelContainers.modal.onDidAddPanel onDidAddPanelEventHandler
atom.workspace.panelContainers.top.onDidAddPanel onDidAddPanelEventHandler
atom.workspace.panelContainers.left.onDidAddPanel onDidAddPanelEventHandler
atom.workspace.panelContainers.right.onDidAddPanel onDidAddPanelEventHandler
atom.workspace.panelContainers.bottom.onDidAddPanel onDidAddPanelEventHandler
```

## 2016/01/19 追記

web-searchの作者の方にこちらの情報を拾っていただき、フォント設定を追加いただきました。
ご対応いただきありがとうございます。
CircleCIでDocker v1.9.0を使う方法

## 追記

さらに新しいバージョンきてた。

- [Docker 1.10.0 is available (Beta) - Build Environment - CircleCI Community Discussion](https://discuss.circleci.com/t/docker-1-10-0-is-available-beta/2100)

## きっかけ

<blockquote class="twitter-tweet" lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/minodisk">@minodisk</a> 突然失礼します。今日公開された docker-1.9 を使う前提ですが、いまのことろ、<a href="https://t.co/ALENbOAoat">https://t.co/ALENbOAoat</a> こういう方法になると思います。</p>&mdash; mapk0y (@mapk0y) <a href="https://twitter.com/mapk0y/status/661837638052155392">2015, 11月 4</a></blockquote>

Docker1.9では、ビルド時にDockerfileから参照可能な引数を渡せるようになったと。 @mapk0y さんに示して頂いたIssueがまさにやりたいことだった。あと1.9リリース当日でタイムリーすぎ。

## Dockerビルド時に引数を指定する

```Dockerfile:Dockerfile
ARG foo
ENV bar=$foo
RUN echo $bar
```

`docker build --build-arg foo=xxxxx .`すると、コンテナ内で`$bar`に`xxxxx`が設定されていることが確認できる。

```bash
Sending build context to Docker daemon 7.168 kB
Step 1 : FROM debian
 ---> 6845b83c79fb
Step 2 : ARG foo
 ---> Running in 59fed192a17e
 ---> 4f7e91ce9e9b
Removing intermediate container 59fed192a17e
Step 3 : ENV bar $foo
 ---> Running in 289eaf6ed19f
 ---> c991661660b9
Removing intermediate container 289eaf6ed19f
Step 4 : RUN echo $bar
 ---> Running in bb54ee586350
xxxxx
 ---> 942f499a52b2
Removing intermediate container bb54ee586350
Successfully built 942f499a52b2
```

## CircleCIでDocker1.9を使う

現状、CircleCIのDockerは1.8なんだけど1.9を使いたいので[用意があるか聞いてみた](https://github.com/circleci/docker/issues/1#issuecomment-155397173)ら、[Betaだけどある](https://discuss.circleci.com/t/beta-docker-1-9-0-is-available/366)とのこと。

```yaml:circle.yml
machine:
  pre:
    - sudo curl -L -o /usr/bin/docker 'https://s3-external-1.amazonaws.com/circle-downloads/docker-1.9.0-circleci'
    - sudo chmod 0755 /usr/bin/docker
  services:
    - docker
test:
  override:
    - docker -v
```

<img width="424" alt="スクリーンショット 2015-11-11 11.59.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/6752/88e08761-331c-0b6f-9206-fe901652854c.png">

:confetti_ball: 1.9.0きた :confetti_ball:
特にCIの稼働時間が増えた感じしないしカジュアルに使えそう。

## 参考

- [ARG | Dockerfile reference](http://docs.docker.com/engine/reference/builder/#arg)
redis入門＆応用編

# Redis  入門
## まず，Redis よく使うデータ構造は、5種類
- String
- Hash
- List
- Set
- Sorted set


## 下記は、5種類データ属性の性質と応用場面：
- Stringコマンド：set,get,decr,incr,mget 等。
![redis1.png](https://qiita-image-store.s3.amazonaws.com/0/99362/15f2bb7c-96d6-ddf7-f9a5-a34fc41b88ee.png)
>応用場面1：key/valueのキャッシュ用。memcacheみたい。
```$ set [key_name] [value]
$ mset [key_name_1] [value_1] [key_name_2] [value_2] 
$ get [key_name]
$ mget [key_name_1] [key_name_2] [key_name_3] 
```
>応用場面2：incrementとして使う、例えば Web ページのヒット数などを保持したい場合
```$ SET mykey "10"   
$ INCR mykey　　　　　　# return 11.
$ DECR mykey　　　　　　# return 10.
```


- Hashコマンド：hget,hset,hgetall 等。
　HashはFIELDという要素があり、オブジェクト指向っぽいことができそうです。
![redis2.png](https://qiita-image-store.s3.amazonaws.com/0/99362/3282c8b8-bdd1-3403-b55c-cd56d0a7b6c7.png)

>応用場面：ユーザの属性の保存、出力。
>例：ユーザの名前と年齢と誕生日であれば
・ユーザ(Key).名前(Field)=Aさん(value)
・ユーザ(Key).年齢(Field)=35(value)
・ユーザ(Key).誕生日(Field)=19700701(value)


- Listコマンド：lpush,rpush,lpop,rpop,lrange等。
　順番の値の集合。
![redis4.PNG](https://qiita-image-store.s3.amazonaws.com/0/99362/f36c0e44-dba3-c370-bd3c-0a3fa90abc8c.png)

>応用場面：
　1)高頻度の追加、queueとして利用
　2)時系列（追加順）に表示
　3)追加された要素にアクセスが集中
>例：Twitterのタイムライン、
　　ECサイトの現在購入タイムライン、
　　大量アクセスのqueue
```$ rpush [key_name] [member]　　# リストの末尾に値を追加
$ lpush [key_name] [member]　　# リストの先頭に値を追加
$ rpop [key_name]　　　　　　　　# リストの末尾の値を削除
$ lpop [key_name]　　　　　　　　# リストの先頭の値を削除
$ lrange [key_name] 0 3 　　　　# 1番目から4番目まで値を取得
$ lrange [key_name] 0 -1　　　　# 1番目から最後（最後から1番目）までの値を取得
$ lindex [key_name] 2 　　　　　# 3番目の値を取得
$ lindex [key_name] -1　　　　　# 最後の値を取得
$ llen [key]　　　　　　　　　　　# 要素の数を取得
```

- setコマンド：sadd,spop,smembers,sunion 等。
　値の重複を許さない要素の集合。
![redis5.PNG](https://qiita-image-store.s3.amazonaws.com/0/99362/a7149643-0969-8b5a-a050-461cddadbc0c.png)
![redis6.PNG](https://qiita-image-store.s3.amazonaws.com/0/99362/0da36a47-71c4-219e-254a-01c413823b5b.png)

>応用場面：定番の例として「タグ検索」機能。
例：積の集合 SINTER tag:red tag:blue
```$ sadd [key_name] [member]  # 値を追加
$ srem [key_name] [member]  # 値を削除
$ smembers [key_name]  # 値の参照
$ sunion [key_name_1] [key_name_2]  # 和集合の取得
$ sdiff [key_name_1] [key_name_2]   # 差集合の取得
$ sinter [key_name_1] [key_name_2]  # 積集合の取得
```

- Sorted Setコマンド：zadd,zrange,zrem,zcard等。
　基本的にSetと同じ、違うのは、sortされているかどうか。詳細でいうと，SET型の各要素に"score”というものが付与され、sortできる。

>応用場面：
　1)ランキング（PV数やコメント数順）
```$ zadd [key_name] [score] [member]  # 値を追加
$ zrem [key_name] [member]  　　# 値を削除
$ zrange [key_name] 0 3　　　　# scoreの低い順に1番目から4番目の値を取得
$ zrevrange [key_name] 0 3  　　# scoreの高い順に1番目から4番目の値を取得
$ zrank [key_name] [member] 　　# scoreの値の順位を取得(scoreの低い順）
$ zrevrank [key_name] [member]  # scoreの値の順位を取得(scoreの高い順）
```
NSErrorが便利すぎる件 Appleありがとう


NSErrorを返す系のメソッドを使う機会って良くあると思いますが(通信,保存など)、NSErrorの引数にnil以外(エラー)の場合どうしたらいいか分からないということが多々あるのではないでしょうか？

「だって、NSErrorにどういう内容が返ってくるか分からないし、分かったとしても全てのパターンにおいてエラー処理書かないといけないの？」的な。

だからNSErrorにエラーが返ってきたら、何もしない。
落ちるか落ちないかは神のみぞ知る的な。

やっぱりそれじゃちょっとダメプログラマかなと思い、エラーメッセくらい出してあげるか、ということでNSErrorの仕様読んでたらとんでもなく便利なことに気づいたので共有します。


# UIAlertViewに表示する内容を全部『日本語』で返してくれる
※ UIAlertViewはios8からdeprecatedなので注意してね、俺は面倒くさいからUIAlertViewでやってるけどね爆

## NSErrorのプロパティを簡単にご紹介
・localizedDescription
　　→　エラーの概要
・localizedFailureReason
　　→　エラーが発生した理由
・localizedRecoverySuggestion
　　→　復旧方法(NextAction)
・localizedRecoveryOptions
　　→ AlertViewに表示するボタンの名前
　　
これ何が便利かというとこれ全部ローカライズして返してくれるというところです。
普通だと「エラーコードを見て、それに対するメッセージを記述したリストを用意して、そして他言語対応するなら言語毎に用意して…」的なことをやる必要があると思いますが、フレームワーク側でローカライズしてくれるので、NSErrorに入っているプロパティをそのままUIAlertViewに表示してやれば、 **ローカライズ完了** ということになります。

## オススメの方法
UIAlertViewに表示するメッセージのオススメの方法ですが、

UIAlerViewの[title]には復旧方法がかかれている[localizedRecoverySuggestion]を突っ込む。

UIAlertViewの[message]には
[localizedDescription]はエラーの概要といった感じで、[localizedFailureReason]はそれをも少し詳しくといった感じだったので、
[localizedFailureReason]を突っ込む。

UIAlertViewのボタンに設定する文言は
[localizedRecoveryOptions]と思ってしまいますが、これは配列で返ってくるため、そのまま突っ込んでしまうと、ボタンによる処理分けをする必要があります。
そうなると、[localizedRecoverySuggestion]の内容から判断し処理を書かなければなくなり一気に、やらないといけないことが増えるので嫌です。(いや、できればした方がいいですが…)

なので、ここは割り切ってエラーメッセージを出すだけにします。

かつ、
・localizedFailureReason
・localizedRecoverySuggestion
・localizedRecoveryOptions
この３つのプロパティはオプショナル型なので返ってくるかどうか解かりません。

それを踏まえて、実際のコード書きます。

## 面倒くさいエラー処理の応急処置
とりあえず、以下のように書いておけば最低限のエラー処理にはなってるかなという感じです。
どこでも使えるようにUIViewControllerのextensionとして定義したので、良ければコピペってください。

```swift:ShowErrorAlertExtension.swift
import UIKit

extension UIViewController {
    func showErrorAlert(error:NSError){
        var title:String!
        var message:String?
        var btnTitle:String!
        if error.localizedFailureReason == nil{
            message = error.localizedDescription
        }else{
            message = error.localizedFailureReason
        }
        if let suggestion = error.localizedRecoverySuggestion {
            title = suggestion
        }else{
            title = "error"
        }
        if let titles = error.localizedRecoveryOptions {
            btnTitle = titles[0]
        }else{
            btnTitle = "OK"
        }
        
        let alertView = UIAlertView(title: title, message: message, delegate: nil, cancelButtonTitle: btnTitle)
        alertView.show()
    }
}

```

実際に動かした、エラーの画面です。
これは、動画を連続でアルバム内に保存しようとした時に出たエラーです。
[書き込みを再試行]が言葉足らず感が否めないですが、これにプラスで文言を付け加えようとすると、自力でローカライズする必要が出てくるので、あえてやりません。

滅多に起きないという前提ですし、雰囲気伝わるのでいいのではないでしょうか。

![スクリーンショット_2015_11_11_11_41.png](https://qiita-image-store.s3.amazonaws.com/0/45908/32a7332d-2e0a-e60b-e1d0-83504439a376.png "スクリーンショット_2015_11_11_11_41.png")

## この設定も忘れずに
ローカライズしたことがあれば分かると思いますが、[Localizations]に追加した言語以外は英語で表示されるのでローカライズしたい言語を追加してください。
![OtherViews_と_Piconnect_xcodeproj.png](https://qiita-image-store.s3.amazonaws.com/0/45908/f4c10c40-ace7-64b7-dabf-bbb8c494d3e6.png)
sudoしたときにコマンドが見つからない

`yum update` したら `sudo` で一部のコマンドが見つからないというエラーが起きるようになりました。
以下を参照して解決しました。

[sudo実行時に$PATHが通っていない場合の設定 | 黒川仁の文具堂ブログ三昧](http://blog.bungu-do.jp/archives/3525)

デフォルトでは以下のパスしか通っていないようです。
```
Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin
```
`sudo visudo` して必要なパスを加えました。
ユーザー追加(Linux)

※以下手順では「test」というユーザを作成する例
ユーザ名を変更する場合は、関連するディレクトリのパス（/home/testなど）も合わせて変更すること。

① ユーザー作成

```
useradd test
```

② 作成したユーザに変更

```
su - test
```

③ キーペア作成

```
ssh-keygen -t rsa
```

※デフォルトの設定で実行する場合、全て質問に対してエンター。
※コマンド実行後、「/home/test/.ssh」ディレクトリ配下に「id_rsa.pub」と「id_rsa」というファイルが作成される。

```
id_rsa.pub　：公開鍵
id_rsa　　　：秘密鍵
```

2048ビット長のキーペアが作成される。

④ 公開鍵の名称を「authorized_keys」に変更

```
mv /home/test/.ssh/id_rsa.pub /home/test/.ssh/authorized_keys
```

※「/etc/ssh/sshd_config」ファイルの中の「AuthorizedKeysFile」の中で指定されているファイル名に変更。
(通常は「.ssh/authorized_keys」がデフォルトで指定されているため、特に変更していない限りは上記設定で問題ない)

⑤ 公開鍵のパーミッションを「600」に変更

```
chmod 600 /home/test/.ssh/authorized_keys
```

⑥ 秘密鍵(id_rsa)をダウンロード

※ここでダウンロードした秘密鍵をご提供ください。

⑦ インスタンス上のssh秘密鍵は削除

```
rm /home/test/.ssh/id_rsa
```

上記⑥で受領した秘密鍵を使用してSSH接続。

- SSL更新作業においてApacheの停止・起動を伴うためroot権限が必要。
- root権限で実行する許可を追加したユーザに設定する必要がある。

#ルート権限の付与/実行コマンドの制限

下記設定をすると、
例えば「sudo service httpd stop」などのように、
実行するコマンドの前に「sudo」を付与するとroot権限で実行される。

【設定方法】
root権限にて下記を実行

```
passwd test
```

※パスワードを設定。
sudoコマンドの実行にはここで設定したパスワード設定が必要。
但し、sudoコマンド実行時にパスワードを不要にする設定も可能。

```
visudo
```

(下記を追記)

```
test    ALL=(ALL)       ALL
```

※ここでtestユーザがroot権限で実行できる範囲について定義することが可能。
上記はroot権限で全てのコマンドを実行可能となるが、
例えば下記のように3列目にroot権限で実行したいコマンドをカンマ区切りで記載することで、
特定のコマンドのみ（下記例では「sudo service httpd start」、「sudo service httpd stop」のみ）の
root権限で実行できるように設定できます。
実行権限を絞られる場合は個別にカンマ区切りでroot権限で使用するコマンドを
すべて記載する必要がある。

```
test1   ALL=(ALL)       /sbin/service httpd start,/sbin/service httpd stop
```

また、sudoコマンドで実行時にパスワードを聞かれないようにするには下記の様に「NOPASSWD:」を付加して設定してください。

```
test1   ALL=(ALL)       NOPASSWD: /sbin/service httpd start,/sbin/service httpd stop
```

作業完了後、今回作成したユーザの削除およびsudo設定から「test」ユーザの記載行を削除する
Jbuilderで単純にHashをJSONにして返したいときはjson.merge!

```
@re = {
  A: 'a',
  B: {b: 1}
}
```

---

```
json.merge! @re
```

[How to extract all attributes with Rails Jbuilder? - Stack Overflow](http://stackoverflow.com/questions/23027644/how-to-extract-all-attributes-with-rails-jbuilder)
virtualboxが起動シーケンスに入らない

### 経緯
- 突然virtualboxのVMが起動しなくなった。bootシーケンスの前で止まる。
- [これ](http://superuser.com/questions/623989/virtual-box-stuck-at-starting-virtual-machine-0?newreg=cbbe37eebe574d7cba9ede4f91aeaf03)と同じ問題だったのですが、解決策が微妙に異なっており、superuser.comにはreputationが足りなくて投稿できないのでこちらに書いておきます。

### 解決策
- SATAにアタッチされていたvirtual disk fileがなぜか認識されていなかったのでいったん外して付け直す（別のファイルを選んで、また元に戻す)ことで解決した。
- これが発生した場合、一時的にVMの設定>一般>タイプ,バージョンが（指定されているように見えても）無効になっていることがあるので、bootシーケンスに入った直後に以下のようなエラーが出ることがある

```
This kernel requires an x86-64 CPU, but only detected an i686 CPU.
```

- この場合にはタイプ、バージョンをいったん別のやつに切り替えてから戻してあげることで修正できることがある。
このXHR誰が飛ばしたの？ってときのXHR Breakpoints

# はじめに

え、今更？って思われる人も多々いるかと思いますが、今更知りました。
ちゃんとdevtoolsの勉強もしないといけませんよね。。。
業務でBackboneを使っているんですけど、お恥ずかしいことにたまに「このXHR誰が投げてるんだろ？」ってなることがあります。ソースを追えばいいんですけど、Chromeに **XHR Breakpoints**なる便利機能があります。

# XHR Breakpoints

`Developer Tools`を開いて`Sources`タブに行くと、右側のメニューに`XHR Breakpoints`という項目があります。ここに、注目したいXHRのURLに含まれる文字列を指定することで、そのXHRが発火するタイミングBreakしてくれるんです。

![xhr-breakpoints.png](https://qiita-image-store.s3.amazonaws.com/0/38528/695789f9-6775-10de-5bee-25314bbaa809.png)

実際にBreakしたときの例↓

![xhr-breakpoints2.png](https://qiita-image-store.s3.amazonaws.com/0/38528/41022951-3bcc-c31c-adb2-17774473b469.png)

便利ですね！

# 参考
Developer Toolsに関する良記事もあるので、勉強しないとですね！

* [色々なbreakpointを使ったJSデバッグ](http://qiita.com/yaotti/items/1b0d86f3f8e68ccb0d68)
* [Chrome Developer Toolsの説明](http://qiita.com/y_fujieda/items/9266d7f29075e2688e8a)
JAVA getTime() setTime(変数)

<FONT color="#ff0000">■getTime()</font>
**1970年1月1日午前0時からの経過時間をミリ秒で返します**

```java
■例① DateクラスでのgetTime()
import java.util.Date;

public class Test02 {
	public static void main(String[] args) {
		Date now = new Date();
		System.out.println(now);
		System.out.println(now.getTime());
	}
}

■例①実行結果
Wed Nov 11 10:33:57 JST 2015
1447205637038
```
```java
■例② CalendarクラスでのgetTime()
import java.util.Calendar;

public class Test02 {
	public static void main(String[] args) {
		Calendar a = Calendar.getInstance();
		System.out.println(a.getTime());
	}
}

■例②実行結果
Wed Nov 11 10:45:46 JST 2015
```

■補足＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿
**■CalendarクラスでのgetTime()**
現在の日時を返します

**■DateクラスでのgetTime()**
1970年1月1日0時0分0秒らかの経過時間をミリ秒単位の値で取得できます。処理開始直前と直後に経過時間を調べることによって、処理にかかった時間が得られます。 

______________________________________________________

<FONT color="#ff0000">■setTime(変数)</font>
**Dateオブジェクトに、引数で指定された1970年1月1日午前0時からの経過時間(ミリ秒)の日時を指定する**

■Date型の値をCalendar型に変換する

```java
		Date now = new Date();
		Calendar c = Calendar.getInstance();
		c.setTime(now);
```

dateに何か値が入っている場合は上記のようにCalendar型の変数を用意して、 そこにsetTimeでdateの値を代入しcalendar型への変換をすることが出来ます。
CakePHP3 で Error: Class 'App\Controller\SplFileObject' not found と言われる解決方法

CakePHP3でSplFileObjectを使おうとしたらエラーがでました(;´༎ຶω༎ຶ`)

# SplFileObjectが使えません。
コントローラでSplFileObjectをnewしたところ使えませんでした。

```php:こんなコード
$hoge = new SplFileObject($tmp_name);
```
エラーが発生＼(^o^)／

```bash:
Error: Class 'App\Controller\SplFileObject' not found 
```

# SplFileObjectを読み込む
classの手前にuseを書けばいいみたいです。

```php
use \SplFileObject;
```

# 再度確認
エラーがでなくなりました(☝ ՞ਊ ՞)

# 名前空間が定義されているのが原因

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/pugiemonn">@pugiemonn</a> それ名前空間が定義されてるからだよ</p>&mdash; ファガイ@16冬出す予定まん (@fagai) <a href="https://twitter.com/fagai/status/664245932817571841">2015年11月11日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
`@pugiemonn それ名前空間が定義されてるからだよ` っていわれましたどういうことだろう。
Haml記法でunexpected keyword_ensure, expecting end-of-inputのsyntax errorが出た時

##現象

####Rails4

haml記法でコードを書いていたときに、下記のような文法エラーが

```
syntax error, unexpected keyword_ensure, expecting end-of-input
```

エラーが起きているファイルは、`index.html.haml`とのこと。

このsyntax errorは、erbで書いているときは、よく見かけますよね。
だいたい、<% end %>とかが抜けてますよね。

でも、haml記法だと、endとか閉じタグはいらないはずですね。



##原因

実は、hamlで上記のようなendの過不足を訴えるエラーが出た時には、
endがないのではなく、**do**が抜けているときに起きるようなのですね。

例えば、以下のように書くと上記のエラーが出ます！

```haml:
= link_to photo_path(photo.id)
　　= image_tag("#{photo.first.image}")

```
ですので、

```haml:
= link_to photo_path(photo.id) do
　　= image_tag("#{photo.first.image}")

```

こう修正します。

その他、`form_tag`, form_for内の`f.text_field`などの中に入れ子でコードを書くときには、**do**を書かないとエラーが出ますね。
`form_for`とかのdoが抜けてるのはすぐ気付けそうでも、`f.text_field`のdoを抜かしてエラーを出してもなかなか気づかなそうですよね。

閉じタグを気にしなくていいのがhamlの魅力ですが、endはなくて大丈夫でも、doは書き忘れないようにしないといけないんですね。





##参考

http://stackoverflow.com/questions/31679325/haml-error-unexpected-keyword-ensure-expecting-end-of-input
Elixir Ecto: 動的にカラム指定で select する 


# 概要

Ecto で動的に必要なカラムを指定する select を実装します。

# 動機

[GraphQL](http://qiita.com/yasuhiro-okada-aktsk/items/2e4d3878ed0c62688913) のように取得するフィールドを指定できる API の場合、SQL のクエリーでも取得するカラムを制限した方がデータ転送量などで効率化できそうです。
※ キャッシュのヒットなどにも影響する可能性もあるので、楽観的な推測が入ってます。

API からの指定によりカラムを選択して SELECT するマクロを作成します。

# Ecto.Query.select

Ecto でカラムを SELECT するには次のようになります。

```ex:Ecto.Query.select
feed = RssFeed
|> Query.select([f], %{ id: f.id, title: f.title })
|> Query.limit([u], 1)
|> Repo.all
```

```[f], %{ id: f.id, title: f.title }``` の部分を動的に生成すれば、必要な機能は実装できます。

しかし、 ```Ecto.Query.select``` はマクロで、```[f]``` や ```%{ id: f.id, title: f.title }``` は list や map ではなく、list や map の形をした Ecto の DSL です。（[参考](http://qiita.com/yasuhiro-okada-aktsk/items/742f266329960ca0ea20)）
つまり、```Ecto.Query.select``` の外で ```cols = `%{ id: f.id, title: f.title }``` のようなことをやったところでエラーになります。

そこで、```Ecto.Query.select``` の中で呼んでいる ```Ecto.Query.Builder.Select.build``` に AST を渡して実現することにしました。

# パラメータの AST

```[f]``` と ```%{ id: f.id, title: f.title }``` の AST は次のようになります。

```ex:f
[{:f, [], nil}]
```

```ex:id_title
{:%{}, [],
 [id: {{:., [], [{:f, [], nil}, :id]}, [], []},
  title: {{:., [], [{:f, [], nil}, :title]}, [], []}]}
```

```[f]``` は固定値なので動的に生成する必要ありません。

```%{ id: f.id, title: f.title }``` は ```id``` なら ```[id: {{:., [], [{:f, [], nil}, :id]}, [], []}]``` を作ってマージしていけばよく、動的に作るのはキーの ```id:``` と値のタプルに含まれる ```:id``` の２つの Atom のみです。

# 拡張版 select マクロ

拡張版の ```select``` は次のように使う仕様とします。

```ex:select_ex
cols = ["id", "title"]

feed = RssFeed
|> QueryEx.select(cols)
|> Query.limit([u], 1)
|> Repo.all
```

```Query.select([f], %{ id: f.id, title: f.title })``` の代わりに ```QueryEx.select(["id", "title"])``` に置き換えるだけで ```Ecto.Query.select``` と同じように動作します。
また、```["id", "title"]``` を変数に代入しておいて、変数を渡すことでカラムを指定できます。

完成はこちらです。

```ex:queryex.ex
defmodule QueryEx do
  defmacro select(query, cols) do
    quote do
      Ecto.Query.Builder.Select.build(unquote(query), [{:f, [], nil}], QueryEx.make_select(unquote(cols)), __ENV__)
      |> Code.eval_quoted
      |> elem(0)
    end
  end

  def make_select(cols) do
    {:%{}, [], make_col([], cols)}
  end

  defp make_col(cols, [col|tl]) do
    cols = Keyword.put(cols, String.to_atom(col), {{:., [], [{:f, [], nil}, String.to_atom(col)]}, [], []})
    make_col(cols, tl)
  end

  defp make_col(cols, []) do
    cols
  end
end
```

実行確認はこちらの[サンプルコード](https://github.com/yasuhiro-okada-aktsk/sample_elixir_ecto_select/tree/queryex)でできます。

# 最後に

こういった内部の関数を呼び出して無理やり実現したときに、公開されたインタフェースでさくっと実現できる方法を見落としているのではないかと、常に気になります。


# 参考

* [Ecto.Query – Ecto v1.0.6](http://hexdocs.pm/ecto/Ecto.Query.html)
Debian(Wheezy)をdocker(/sbin/init)で起動

# dockerの実行
以前からdockerで最後bash等のシェルで起動するのは抵抗があったんです。
本当は常駐する、apacheとかpostfixとか起動するのが正しいのでしょうけど、自分の場合、個人利用が多いので利用する単位でコンテナ作ったりします。 :sweat_smile: 


```text:Dockerfile
   :
ENTRYPOINT ¥
   service apache2 start && ¥
   service postfix start && ¥
   bash --login
```

このように書いてもいいのですけど、なんかすっきりしないですよね。


## debian + apache2 + php5
シンプルな構成でウェブサーバーにPHPをインストール。

```text:Dockerfile
FROM debian:7.9

MAINTAINER takara

WORKDIR /root/

ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get -y install apache2 php5
RUN sed -i -e 's/^\([1-6]:.\+\)/#\1/g' /etc/inittab 
ENV DEBIAN_FRONTEND dialog

EXPOSE 80

CMD ["/sbin/init", "3"]
```

### ビルド

```
$ docker build -t deb_init:7.9 .
```

### 常駐実行

```
$ docker run -itd --name deb_init -h deb_init deb_init:7.9
```

### 中身のプロセス
中に入ってプロセスを覗いてみます。

```
$ docker exec -it deb_init /bin/bash
root@deb_init:~# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.4  0.1  10660  1640 ?        Ss   10:52   0:00 init [3]    
root      1364  0.1  1.4 134560 15360 ?        Ss   10:52   0:00 /usr/sbin/apache2 -k start
www-data  1379  0.0  0.6 134584  6884 ?        S    10:52   0:00 /usr/sbin/apache2 -k start
www-data  1380  0.0  0.6 134584  6884 ?        S    10:52   0:00 /usr/sbin/apache2 -k start
www-data  1382  0.0  0.6 134584  6884 ?        S    10:52   0:00 /usr/sbin/apache2 -k start
www-data  1383  0.0  0.6 134584  6884 ?        S    10:52   0:00 /usr/sbin/apache2 -k start
www-data  1385  0.0  0.6 134584  6884 ?        S    10:52   0:00 /usr/sbin/apache2 -k start
root      1414  2.6  0.3  17856  3156 ?        S    10:52   0:00 /bin/bash
root      1419  0.0  0.1  15320  1908 ?        R+   10:52   0:00 ps aux
```

起動プロセスが割りとシンプル(笑)
最初に起動した```/sbin/init```と```apache```だけ :notes: 
で中に入ったときの```bash```と```ps```ですから。良い感じ。

最初起動した際には```getty```が起動していのでdockerであれば直接繋がってる端末もないので```/etc/inittab```から```sed```でコメントアウト

### 動作確認
ホスト側から「docker inspect deb_init」でIPを調べアパッチへアクセス。

```
$ wget -O- 172.17.1.66
--2015-11-10 19:55:46--  http://172.17.1.66/
172.17.1.66:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 177 [text/html]
`STDOUT' に保存中

 0% [                                                                               ] 0           --.-K/s              <html><body><h1>It works!</h1>
<p>This is the default web page for this server.</p>
<p>The web server software is running but no content has been added, yet.</p>
</body></html>
100%[==============================================================================>] 177         --.-K/s 時間 0s      

2015-11-10 19:55:46 (25.1 MB/s) - stdout へ出力完了 [177/177]
```

apacheの初期状態のページ「It works!」がでてますね。
サーバーに来たPush通知をローカルマシンで受け取る

## 前置き

Webサーバーを開発するとき、別のサービスから変化があった時にPushを受け取りたいことがあります。

例えば、Google Drive APIには[Push Notifications](https://developers.google.com/drive/web/push)という機能があり、予め外部からアクセスできるURLをGoogleのサーバに登録しておくことで、ファイルに変化があったらそのURLを呼び出してくれるというものです。
でもそのためには**外部に公開されているURLが必要**。

![figure1.png](https://qiita-image-store.s3.amazonaws.com/0/39529/de39c43f-79fe-799a-123b-377078da38d3.png)

開発効率を考えたら、**少しコードを変更して、サーバにデプロイ→修正→繰り返し、、、とか、メンドイ**。手間。ヤダ。

そこで[SSHポートフォファード](http://qiita.com/wf9a5m75/items/a78262532ac4823104f0)を使って、サーバーで受け取ったHTTP GETをローカルのHTTPサーバに転送します。



## HTTPサーバ (ローカル)

まずはローカルでHTTPサーバを動かしてください。Apacheでもなんでもいいです。
私は手抜きなので、node.jsで以下の簡単なHTTPサーバを動かします。

```js
var express = require('express');

var app = express();

app.get('/*', function (req, res) {
  return res.send("now : " + ((new Date()).toString()));
});

var port = 20000;
console.log("Start listening the port at " + port);
app.listen(port);
```

ちゃんと http://localhost:20000 でアクセスできることを確認しましょう。

![Screen Shot 2015-11-10 at 3.11.55 PM.png](https://qiita-image-store.s3.amazonaws.com/0/39529/4e3ccaf7-d00f-ba19-e360-8de8a656e556.png)


## リモートSSHポートフォファード

サーバー内で3000番ポートにアクセスしたら、ローカルの20000番ポートに転送されるようにします。
ポート番号を変えているのは説明の上で、どことどこのポートがつながっているか、分かりやすくするためだけです。

sshのリモートポートフォファード(-Rオブプション) を No command(-N -C)でバックグラウンド(-f)で実行します。

```shell-session
local $> ssh -f -N -C -i ~/.ssh/id_rsa -R 3000:localhost:20000 admin@myserver.com
```

これで**SSHサーバー内から http://localhost:3000 にアクセス**したらブラウザに表示されるはずです。
もちろん、curlでもいいです。

```shell-session
server $> curl localhost:3000
now : Wed Nov 11 2015 08:15:34 GMT+0900 (JST)
```

でもこれだとローカルから http://myserver.com:3000 にアクセスしても表示されないはず。
なぜかというとリモートSSHポートフォファードは、接続した先のコンピューターからのアクセスしか受け付けないから。
つまりブラウザから http://myserver.com:3000 は外部から接続しているので、転送されないわけです。

![Screen Shot 2015-11-10 at 3.14.46 PM.png](https://qiita-image-store.s3.amazonaws.com/0/39529/6398d06c-bc4e-8bc6-1471-7b80a99be432.png)


## サーバー内でローカルSSHポートフォファード

サーバの外部からアクセスをサーバー内の3000番ポートに転送する必要があります。
そこで、myserver.comの3001番をmyserver.com:3000番に転送します。
このときに**-gオプション**を付けると、外部からのアクセスも許可するようになります。gはglobalですね。

```shell-session
server $> ssh -f -N -C -g -L 3001:localhost:3000 admin@localhost
```

サーバーにログインしたくなければ、下記でも出来ます。

```shell-session
local $> ssh -f -i ~/.ssh/id_rsa admin@myserver.com -t ssh -f -N -C -g -L 3001:localhost:3000 admin@localhost
```

![figure2.png](https://qiita-image-store.s3.amazonaws.com/0/39529/da2eeb5f-9ee2-ebad-1a60-cec709b0b0d9.png)

こうすれば、どこからでもブラウザで http://myserver.com:3001 とすれば表示されるはずです。
![Screen Shot 2015-11-10 at 3.16.36 PM.png](https://qiita-image-store.s3.amazonaws.com/0/39529/314c9536-6ede-3a5c-1d7e-53e0c10a8e8f.png)

## SSH-Agentを使えば、この2行だけ。

`-A`はSSH-Agentを使うオプションです。
SSH-AgentはIdentityファイルをキャッシュしてくれるサービスで、Macなら標準でインストールされているはず。

```shell-session
local $> ssh -f -N -C -A -R 3000:localhost:20000 admin@myserver.com
local $> ssh -A -f admin@myserver.com -t ssh -f -N -C -g -L 3001:localhost:3000 admin@localhost
```

## 当然ですけど

外部向けのポート（例では3001番）はファイヤーウォールで開けておかないと、サーバーにはアクセスできません。

## ちなみに

今回はローカル上でHTTPサーバーだったが、FTPでもProxyServerでもできます。
python > キーワード引数 > hoge(**{'a': 1, 'b': 2, 'c': 3})

http://qiita.com/ukyo/items/0273a89fa49f6f1f62e2
にある

```test.py
hoge(**{'a': 1, 'b': 2, 'c': 3})
```

自分の投稿
http://qiita.com/7of9/items/618634ac35a1e27e03eb

C#では `名前付き引数渡し`
RubyやFortranでは`キーワード引数`

pythonでも`キーワード引数`という、のであっている?
http://atkonn.blogspot.jp/2008/02/python-python26.html

> pythonではキーワード引数なるものが使える。
プロキシ環境下でdocker buildするときにbuild-time argumentsを利用する

# 従来のdocker build
プロキシ環境下でDockerfileをビルドするときは
Dockerfile内にプロキシ設定を埋め込んで対応していた。

```lang:Dockerfile
  FROM ubuntu:14.04

  ENV HTTP_PROXY http://proxy.example.com:8080

  RUN apt-get -y update && apt-get -y install nginx
```

しかし当然ながら、このDockerfileから構築したイメージには
プロキシ設定が埋め込まれる。

プロキシ環境下でしか使わないのであれば問題無いが、
それ以外の環境に持ち出す可能性がある場合は
トラブルの元なので、できれば避けたい。

# build-time argumentsの利用
build-time argumentsはdocker engine 1.9から実装された機能で
Dockerfileのビルド時にパラメータを設定することができる。

- [Announcing Docker 1.9](https://blog.docker.com/2015/11/docker-1-9-production-ready-swarm-multi-host-networking/)

build-time argumentsを利用することで、
docker run時に-eオプションなどで設定するのと同様に
docker build時に環境変数を設定できる。

```
docker build --build-arg HTTP_PROXY=http://proxy.example.com:8080 .
```
このようにビルドするとプロキシ環境下でもパケージのアップデート等は実行可能だが
ビルドイメージにはプロキシ設定は含まれない。

# もう少し詳しいbuild-time arguments
詳細は公式ドキュメントの
DockerfileにおけるARG命令に記載されている

- [Dockerfile reference](http://docs.docker.com/engine/reference/builder/#arg)

要約すると以下の通り

- Dockerfile内でARG命令で定義した変数の値を--build-argオプションで指定できる
- 初期では、HTTP_PROXYやno_proxyなど8つの変数が定義済み
- ARG命令で変数を定義するときデフォルト値を設定することも可能
- 未定義の変数を--build-argオプションで指定するとエラー
- Dockerfile内においてARG命令は定義された行から有効になる、それ以前の行では未定義
- ENV命令で定義された変数はARG命令とは異なりビルドイメージでも有効
技術英語 > is not consistent with > The signature of the radiation is not consistent with Federation propulsion systems.

@ Star Trek Voyager > INITIATIONS

ある宇宙空間において失踪した船の探索中、ある放射現象を見つけた。それらの議論にてTuvokが言った言葉

> The signature of the radiation is not consistent with Federation propulsion systems.

訳すとすると以下のような感じか。
「放射の特長は連邦の推進システムのものに合致しない」

特長? 特徴? 日本語むずかしい。

<hr>
使う場面を考えてみた

The signature of the handwriting is not consistent with my friend.

with my friend.
なのか
with my friend's.
なのか
with my friend's one.
なのか、未消化。

<hr>
> with Federation propulsion systems.

となっていた字幕だが

> with Federation propulsion system's.

なのかもしれない。
Raspberry Piでradiko録音をやってみよう

## 経緯

- いつも録音していたWindows機が破壊された
- 週に4日は深夜ラジオを録音している
- 物理的にダウンサイジングしたかった
- 放置してたRaspberry Pi 1 Model Bを思い出した

## 準備
- Raspberry Pi 1 Model B
- OS導入済み
- すでに以前からの前提として、ローカルLAN内で固定IP化
- 無線LANアダプタは導入済み
 - 実はWiFiアダプタがなかなか認識しなかった
 - スリープ防止の意味もありwireless-power offにしておく（`/etc/network/interfaces` の編集）

### 必要なものをインストール

```
$ sudo apt-get install rtmpdump swftools libxml2-utils ffmpeg
```

ホームディレクトリの下にbinディレクトリを作成するとパスが通るので作成。

スクリプト自体は下記参照しつつ、一部変更。

```
$ mkdir ~/bin
$ cd ~/bin
$ wget https://gist.github.com/raw/3956266/0dc83895770e26a7c37104d896a150c8bb1dffbb/rec_radiko.sh
$ chmod +x rec_radiko.sh
```

rec_radiko.shの行頭を変更

```
#!/bin/sh
↓
#!/bin/bash
```

ファイル名に使う日付の時間部分もコロンだと化けるので変更。

```
date=`date '+%Y-%m-%d-%H:%M'`
↓
date=`date '+%Y-%m-%d-%H_%M'`
```

ビットレートも

```
ffmpeg -y -i "/tmp/${channel}_${date}" -acodec libmp3lame -ab 128k "${outdir}/${channel}_${date}.mp3"
↓
ffmpeg -y -i "/tmp/${channel}_${date}" -acodec libmp3lame -ab 32k "${outdir}/${channel}_${date}.mp3"
```


### 録音テスト

1分間だけTBSを録音してみる。
保存ファイルは `/home/pi/radiko`以下に

```
rec_radiko.sh TBS 1 ~/radiko
```

## 録音ファイルをDropboxにアップロード

容量の関係もあるので、Dropboxにアップロード。しかも自動で。

Dropbox-Uploaderをダウンロードします。

```
$ cd
$ git clone https://github.com/andreafabrizi/Dropbox-Uploader.git
$ cd Dropbox-Uploader
$ chmod 755 dropbox_uploader.sh
$ mv dropbox_uploader.sh ~/bin/
```

### Dropbox側にアプリの登録

スクリプトの準備はできても、Dropbox側にアプリ登録をしないと使えません。
[https://www.dropbox.com/developers/apps](https://www.dropbox.com/developers/apps)

- CreateAppをクリック
- Dropbox APIを選択
- 必要なアクセス権を選択（App folderかFull Dropboxか）
- App名を記入
- App keyとApp secretを確認

### Dropbox-Uploaderの初期設定

起動します

```
$ ./dropbox_uploader.sh
```

先ほど確認したApp keyとApp Secretを聞かれるので、順に入力します。
指定されたURLをコピってブラウザでアクセスし、許可します。

Raspberry Piの画面に戻ってEnterで完了。

### アップロードテスト

```
$ dropbox_uploader.sh upload [local_file] [remote_file]
```

## 自動化

[こちらの偉大なる先人のスクリプト](http://shinyamatsuyama.blogspot.jp/2013/06/raspberrypiradiko.html)を参考にさせてもらいました。

ファイル名を`rec-and-upload.sh`として、ファイルに実行権をつけておきます。

### cron作成

```
$ crontab -e
```

編集します

```
0 1 * * 2 /home/pi/bin/rec-and-upload.sh TBS 120
```

これで月曜深夜（正確には火曜 AM1:00〜3;00）にTBSラジオ録音→Dropboxへアップロード→削除が自動で出来るようになりました。

あとは録音する番組分を設定。

これで快適な深夜ラジオのある生活に。

### 2015/11/17 追記
rec_radiko.shを一度でも実行したあと、swfplayerのバージョンを変えた場合、
player.swfを一旦削除したほうが良さげです。

```
/tmp/player.swf is not a valid SWF file or contains errors.
failed get keydata
```

のエラーが出た場合、/tmp/player.swfを削除。
DateIntervalとDatePeriodを使って指定期間内で日付を刻みながらforeachでイテレートする

例えば1/1から1/10までを1日おきに刻むには下記のようにします。

```php
$begin = new DateTime('2016-01-01');
$end = new DateTime('2016-01-10');

$interval = new DateInterval('P1D');
$daterange = new DatePeriod($begin, $interval ,$end);

foreach($daterange as $date){
    echo $date->format("Y-m-d H:i:s") . "\n";
}
```

結果

```
2016-01-01 00:00:00
2016-01-02 00:00:00
2016-01-03 00:00:00
2016-01-04 00:00:00
2016-01-05 00:00:00
2016-01-06 00:00:00
2016-01-07 00:00:00
2016-01-08 00:00:00
2016-01-09 00:00:00
```

終端(この例だと1/10)が含まれないので注意が必要です。

１時間刻みにしたい場合は`P1D`の代わりに`PT1H`と書きます。
DateIntervalの詳しい仕様はこちら。

http://php.net/manual/ja/dateinterval.construct.php
phpでcronもatも使わず簡単background処理

画面表示だけ先にして、実際の処理はあとでゆっくり実行する。
cronもatも使わずに。な方法です。

下記そのままです。
http://php.net/manual/en/features.connection-handling.php
`Content-Encoding: gzip` だとうまくいかないみたいです。


```php:php

function init_background_process(){
	ob_end_clean();
	header("Connection: close\r\n");
	header("Content-Encoding: none\r\n");
	ignore_user_abort(true);
	ob_start();
}

function start_background_process(){
	$size = ob_get_length();
	header("Content-Length: $size");
	ob_end_flush();
	flush();
	ob_end_clean();
}

//画面表示の前に実行
init_background_process();

echo 'メール送信を受け付けました';

//バックグラウンド処理の直前に実行
start_background_process();

sleep(5);

for($i = 1; $i < 100; $i++){
  mb_send_mail('hoge@fuga.com', 'test', 'test', 'From: fuga@hoge.com');
}




```
Unityのエディタ拡張でカスタムウィンドウを作る。

# 概要
表題ままですが、Unityのエディタ拡張機能を使用してオリジナルのウィンドウを作成する方法を綴ります。

以前投稿した「[UnityのInspectorを拡張する。](http://qiita.com/sango/items/b705980ada56ba8ffa04)」と併せて読むといい感じです。

# 実践
## 1. カスタムウィンドウ用クラス作成
[Project]以下のEditorという名前のフォルダの下に、任意のクラスを作成してね。
![ss_110.png](https://qiita-image-store.s3.amazonaws.com/0/97611/da744887-ab61-de2d-3c22-46fa1cf35f40.png)

※Editorフォルダがない場合は新しく作ってね！
※Project(Assets)直下でなくてもOK!

## 2. メニューへの追加とウィンドウの作成

### コードはこんな感じ

```csharp:SampleWindow.cs
using UnityEngine;
using System.Collections;
using UnityEditor;	//!< UnityEditorを使うよ！

public class SampleWindow : EditorWindow	//!< EditorWindowを継承してね！
{
	//! MenuItem("メニュー名/項目名") のフォーマットで記載してね
	[MenuItem("Custom/SampleWindow")]
	static void ShowWindow()
	{
		// ウィンドウを表示！
		EditorWindow.GetWindow<SampleWindow>();
	}
}

```

### 実行画面はこんな感じ
![ss_107.png](https://qiita-image-store.s3.amazonaws.com/0/97611/213750be-3df0-03a4-cfd0-6773901c7d8c.png)
メニューに、[Custom] -> [SampleWindow] が追加されるよ！

![ss_108.png](https://qiita-image-store.s3.amazonaws.com/0/97611/0496e1a6-6702-04a9-1df7-82626007e8b7.png)
空っぽのウィンドウが開かれたら成功！

### 解説
- `MenuItem()` でUnityの上部に並ぶアイテム名を指定しているよ
- その下のstatic関数で `EditorWindow.GetWindow<>()` を呼ぶことでウィンドウが開かれるよ

とっても簡単ね！

## 3. ウィンドウの中身を描画
### 描画関数を追記してね

```csharp:SampleWindow.cs
using UnityEngine;
using System.Collections;
using UnityEditor;	//!< UnityEditorを使うよ！

public class SampleWindow : EditorWindow	//!< EditorWindowを継承してね！
{
	//! MenuItem("メニュー名/項目名") のフォーマットで記載してね
	[MenuItem("Custom/SampleWindow")]
	static void ShowWindow()
	{
		// ウィンドウを表示！
		EditorWindow.GetWindow<SampleWindow>();
	}


	/**
	 * ウィンドウの中身
	 */
	void OnGUI()
	{
		if( GUILayout.Button( "ボタン" ) )
		{
			Debug.Log( "押された！" );
		}
	}
}

```

### 実行画面はこんな感じ
![ss_109.png](https://qiita-image-store.s3.amazonaws.com/0/97611/1a5691e1-1f7b-bfbc-30bf-de72dc46b9ea.png)

これでもうカスタムウィンドウの作り方はマスターしたね！

ウィンドウの中身の描画方法については「[UnityのInspectorを拡張する。](http://qiita.com/sango/items/b705980ada56ba8ffa04)」も参考にしてみてね！

# 参考
- [Unity - マニュアル: エディターウィンドウ](http://docs.unity3d.com/ja/current/Manual/editor-EditorWindows.html)
PhotoshopExtensionのつくりかたとか

PhotoshopExtensionを作ろうと思った時まとまった情報が少なくて困ったのでまとめました。
こちらのブログ大変参考になりました！ありがとうございます。 http://rarihoma.xvs.jp/2014/08/23/1/

# 作り方

PhotoshopExtensionには様々な形式があります。

## ExtensionScript

![image](https://qiita-image-store.s3.amazonaws.com/0/40921/169acdd6-305f-fcd7-f8e3-194f4525c860.png)

JSからPhotoshopのAPIを利用して動作する。ちなみにExtensionScriptが記述されたファイルの拡張子は.jsx。
PhotoshopのScriptsディレクトリ以下にExtensionScriptを記述したファイルを置くことで実行できるようになる。
お手軽に拡張機能を作りたい人向け。これから説明する他の開発形式でもjsxを呼び出すことはできるので、PhotoshopExtensionを作ろうと思ったら知ってないといけないやつっぽい。



### ドキュメント
英語(本家): http://www.adobe.com/devnet/photoshop/scripting.html
日本語: http://www.openspc2.org/book/PhotoshopCS6/
fyi) StringとかFileとかのめっちゃ基盤的な部分の日本語ドキュメント: http://www.openspc2.org/reibun/AdobeJS/CS6/index.html

本家にも載っていないAPIがあったりするが、Scripting Listener Plug-inというプラグインを動作させた状態でPhotoshopを操作すると、操作がどのAPIで行われたかのログを見ることができるらしいのでそれで頑張る。さっきの[本家documentページ](http://www.adobe.com/devnet/photoshop/scripting.html)からダウンロードできる。 
## Generator

![image](https://qiita-image-store.s3.amazonaws.com/0/40921/13f3884a-27aa-619b-b305-ee19bf442fd9.png)

Photoshopと、ローカルに立てたNodeJSのサーバで通信して動作する。サーバに配信されるPhotoshopのイベントをハンドルして処理を記述していく。リアルタイムで画像書き出しとかしたい人向け。

### ドキュメント

ないらしい。
[githubの公式リポジトリ](https://github.com/adobe-photoshop)のサンプルが豊富なのでコードから察する。

開発を始めるための手順をまとめたブログ
日本語: http://codezine.jp/article/detail/7545
英語: http://tomkrcha.com/?p=3896

## Custom Panel

![image](https://qiita-image-store.s3.amazonaws.com/0/40921/0e2f7aca-d1d9-3d1a-2f96-01e413f0e88e.png)

カスタムパネルを作れる。GUIに特化できるのでそういう系をやりたい人向け。htmlで作れる。


### ドキュメント

開発を始めるための手順をまとめたブログ
日本語: http://aphall.com/2014/08/cep-5-getting-started/

## develop by SDK

Generatorとは違って、Photoshopを外部デバイスから制御できるらしい。Cで書いたりするんだと思う。
ダウンロードはこちらhttp://www.adobe.com/devnet/photoshop/sdk.html


# リリース方法

AdobeExchangeという、Adobe製品のためのテンプレートとかスクリプトを配布できるサイトを通して行う。

開発者用アカウント登録をして、ダッシュボードからプラグインのパッケージをアップロードする。無料アカウントだと年に10個公開できる。内有料は2つ。

プラグインをパッケージ化するためのAdobe Exchange Packagerはリソースページで配布されてるのを使う。
https://www.adobeexchange.com/resources

パッケージをアップロードした後必要な項目の入力が完了するとレビューに入る。レビューが終わるとメールが届いてストアに公開できるらしい。

# おまけ: 副産物

Photoshopの更新内容をSlackにリアルタイム反映させるGenerator形式プラグインを書きました。

![slackShare.gif](https://qiita-image-store.s3.amazonaws.com/0/40921/7ca1707a-2d89-b765-5f9a-bdd5d666ada1.gif)

あとで申請してみたい