OmniAICreator/Qiita-1.07M huggingface dataset:
Ruby + RSpec + Guard + terminal-notifier-guard でテストを自動実行し、結果を通知

Ruby + RSpec + Guard + terminal-notifier-guard でテストを自動実行し、結果を通知します

## <i class='fa fa-flask'></i> サンプル
### <i class='fa fa-code'></i> テスト対象
```ruby:sample_spec.rb
require 'spec_helper'

describe "hoge" do
  it "hige" do
    expect(true).to be true
  end
end
```

### <i class='fa fa-wrench'></i> Gemfile
```ruby:Gemfile
# frozen_string_literal: true
source 'https://rubygems.org'

group :development, :test do
  gem 'rake'
  gem 'rspec'
  gem 'guard'
  gem 'terminal-notifier'
  gem 'terminal-notifier-guard'
  gem 'guard-rspec', require: false
  gem 'pry-byebug'
  gem 'rb-readline'
end
```

* bundle install

```sh
$ bundle install
```

### <i class='fa fa-wrench'></i> Guardfile
```ruby:Guardfile
guard :rspec, cmd: 'bundle exec rspec' do
  watch(%r{^spec/.+_spec\.rb$})
  watch(%r{^lib/(.+)\.rb$})     { |m| "spec/#{m[1]}_spec.rb" }
  watch('spec/spec_helper.rb')
end
```

### <i class='fa fa-play-circle'></i> 実行
ファイルの変更を検知して、Gaurdが実行されます

```sh
$ bundle exec guard
21:26:44 - INFO - Guard::RSpec is running
21:26:44 - INFO - Guard is now watching at 'path/to/project'
21:27:01 - INFO - Running: spec/sample_spec.rb
.

Finished in 0.002 seconds (files took 0.09395 seconds to load)
1 example, 0 failures
```

* 通知が表示されます

![success.png](https://qiita-image-store.s3.amazonaws.com/0/43480/b644f5f7-c970-8864-ec67-1b22b731ba3c.png)

* テストケースが失敗するように変更します

```ruby
require 'spec_helper'

describe "hoge" do
  it "hige" do
    expect(true).to be false
  end
end
```

* ファイルの変更を検知して、Gaurdが実行されます

```sh
21:28:18 - INFO - Running: spec/sample_spec.rb
F

Failures:

  1) hoge hige
     Failure/Error: expect(true).to be false

       expected false
            got true
     # ./spec/sample_spec.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.01606 seconds (files took 0.10262 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/sample_spec.rb:4 # hoge hige

```

* 通知が表示されます

![fail.png](https://qiita-image-store.s3.amazonaws.com/0/43480/de2157a8-693e-03da-9d54-9caae5bf1b13.png)

## <i class="fa fa-book" style="font-size:1em;"></i> 外部資料
* [Codaisseur/terminal-notifier-guard - GitHub](https://github.com/Codaisseur/terminal-notifier-guard)
GitBucket+Tomcat8+Nginx環境で大容量をコミット時のエラー回避


Pushしようとした際下記のメッセージが表示されたのでその回避方法
GitBucketだけでなくNginxで動かしている場合はおそらく有効

```
fatal: The remote end hung up unexpectedly
```

Nginxに以下の設定を追加

```
client_max_body_size 100M;
```

サイズは容量によって適宜変更
新しい共有ボタンの形 ーWeb Share APIが公開されましたー

##初めに
観測範囲にコードメインの記事がなかったので書いてみます。けれども、私自身はフロントエンドでバリバリっていう人ではないので、間違いがあったらコメントをお願いします。おまけに、実際にテストしたわけではないのでそこもご了承いただきたく願います。
##Web Share APIとは何ぞや
まずはここから書いていきたいと思います。今まで、WebからほかのサービスへのURL共有といえば、二つの方法がありました。サービスのAPIを使用したシェアボタンと、ブラウザもしくはOSレベルに備え付けられたシェアボタンからとその二つから投稿するものでした。しかし、これは違います。Web上のelementでアクションを起こしたら、OSレベルのシェア機能が呼ばれるのです。そういう関数がChrome 55 Betaから実装されました。
##実際に、どう使うの？
ここが問題です。[Googleによる記事](https://developers.google.com/web/updates/2016/10/navigator-share)を読むと、きちんと書いてあります。[ここ](https://docs.google.com/forms/d/e/1FAIpQLSfO0_ptFl8r8G0UFhT0xhV17eabG-erUWBDiKSRDTqEZ_9ULQ/viewform?entry.1999497328=Web+Share+(Experimenting+until+April+2017))での登録が必須なようです。そして、そこで発行しているトークンを用いて、認証しなければいけないとか書いてあります。

###認証方法

```html:html
<meta http-equiv="origin-trial" content="ここにトークンを記入">
```

この一行を挿入するのみです。

###シンプルなパターン

```js:JavaScript
navigator.share({
    title: document.title,
    text: "Hello World",
    url: window.location.href
}).then(() => console.log('Successful share'))
.catch(error => console.log('Error sharing:', error));
```

URLは必須属性みたいです。もう一つ、タイトルか共有テキストをわたしてあげる必要があると書いてあります。

###URLを正しく共有するパターン

```js:JavaScript
var url = document.location.href;
var canonicalElement = document.querySelector('link[rel=canonical]');
if(canonicalElement !== undefined) {
    url = canonicalElement.href;
}
navigator.share({
    title: document.title,
    text: "Hello World",
    url: url
})
.then(() => console.log('Successful share'))
.catch(error => console.log('Error sharing:', error));
```

こちらでは、URLを変数としてcanoncialリンクも拾うようにしています。この技は応用が利きそうです。
###注意点
先ほど書いた通り、認証が必要になることが一点。そのほかにも、HTTPS環境でなければいけないことや、ユーザーのジェスチャーがトリガーでなければいけないことでイベントを(つまりは自動発火させないこと)。それらに、注意しなければいけません。HTTPS環境が一つハードルになると思います。私もここでリタイヤです。そのほかにも、画像データを共有できません。Web側でOGP対応を済ませていなければ、たいていのwebサービスに画像のみ共有されないことになります。OGP対応をしても、Webサービスによっては画像が共有されないことも考えられます。ただいま、開発中とはされているので首を長くして待ちましょう。
##まとめ
このAPIは今までの常識を変えるものです。今までサービスごとに一つのDOMが必要だったなかで、これ一つで代用できてしまいます。また、ユーザーによっては、そのサービスに共有するためのアプリを入れていないなどの場合が考えられます。そのような場合のフォローをどうするかという議論もありそうです。
自分用: html5とphpを用いた複数ファイルのアップロード

#自分用: html5とphpを用いた複数ファイルのアップロード

タイトルのままの内容です。
html5ではinput要素にmultipleとつけると複数ファイルを簡単に選択出来て送信できます。
送信されたPHP側では、$_FILESという名前で一時保存されています。

参考サイト
[JavaScript プログラミング講座](http://hakuhin.jp/js/upload.html)
[たくあんのチラシ裏　HTML5+PHPで複数ファイルアップロード](http://hakuhin.jp/js/upload.html)
[選択されたファイルの名前を取得する](http://www.openspc2.org/reibun/javascript2/FileAPI/files/0002/)


あとは、accept="image/*"をinputの中に入れると画像だけ保存とか可能らしい



```html:upload.html
<html>
	<head>
	</head>
	<body>
		<form action="upload.php" method="post" enctype="multipart/form-data">
			<input name="userfile[]" type="file" id="upfile" onChange="printfile()"  multiple><br>
			<input type="submit" value="Send">
		</form>
		<div id="result"></div>
		<script>
			function printfile(){
				var fileList = document.getElementById("upfile").files;
				var list = "";
				for(var i=0; i<fileList.length; i++){
				list += fileList[i].name + "<br>";
				}
				document.getElementById("result").innerHTML = list;
			}
		</script>
	</body>
</html>
```

```php:upload.php
<?php
  for ($i=0; $i<count($_FILES['userfile']['name']); $i++) {
    $file_ext = pathinfo($_FILES["userfile"]["name"][$i], PATHINFO_EXTENSION);
    if (/*FileExtensionGetAllowUpload($file_ext) && */ is_uploaded_file($_FILES["userfile"]["tmp_name"][$i])) {
      if(move_uploaded_file($_FILES["userfile"]["tmp_name"][$i], "img/".$_FILES["userfile"]["name"][$i])) {
          echo $_FILES["userfile"]["name"][$i] . "をアップロードしました。<br>";
      } else {
        echo "ファイルをアップロードできません。<br>";
      }
    } else {
      echo "ファイルが選択されていません。<br>";
    }
  }
  //アップロードできるファイルに拡張子の制限をかけたい時
  function FileExtensionGetAllowUpload($ext){
    $allow_ext = array("gif","jpg","jpeg","png","eps");
    foreach($allow_ext as $v){
      if ($v === $ext){
        return 1;
      }
    }
    return 0;
  }
?>
```

| 要素名 | 解説 |
|:-:|:-:|
| name  | アップロードされたファイルの名前  |
| type  | アップロードされたファイルの MIME タイプ  |
| size  | アップロードされたファイルのサイズ |
| tmp_name  | アップロードされたファイルが格納されている一時的なパス名  |
| error  |  エラーが無ければ 0 、エラーがあれば 0 以外の数値 |
git-flowを使ってGitHubにプルリクエストを送ってみる手順

###プロジェクトのルートで下記のコマンドを叩く
git init
git flow init -d
これでdevelopブランチができる
git flow feature start いい感じのブランチ名
git add .
git commit -m "冷たい頬"

git remote
名前の確認　例)origin
git remote -v
自分がpushしたいgithubのリポジトリ

git remote add origin git@github.com:coderstable/comfortable_keeper_sketch.git
リポジトリがないなら追加する

###GitHubへのpushのやり方
git push origin feature/いい感じのブランチ名

###GitHubへちゃんとpushされているかの確認
トップ画面 -> branches　-> Active branches
と進み、pushしたファイルが表示されていればOK

###GitHubへのプルリクエストのやりかた
pushしたファイルが表示されていた画面で、右側の緑のボタン"Clone or Download"
の下にある"Pull request"リンクをクリックし遷移後の画面でメッセージを書く



git flow って何？
git と何が違うの？ gitじゃダメなの？
[GoogleComputeEngine]gcloud compute sshを使わずにローカルマシンからSSHでログインできるようにする。

# 前提条件

gcloud compute sshを使わない前提でご説明します。

macでやってます。windowsの場合はputtygenなどで鍵の作成を行なってください。
予めGCEにてインスタンスを作成しておき、外部IPをメモしてください。

<img width="1280" alt="スクリーンショット 2016-11-10 16.39.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/146205/a24cb312-0bb0-7564-9602-aa943a4b9264.png">


# やり方

## ログインするためのsshキーの作成

ログインを行うためのSSHキーを作成します。
パスフレーズはできるだけ入れたほうがいいかもです

```
rache:.ssh rache$ ssh-keygen -t rsa -b 4096 -C "自分のメールアドレス"
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/rache/.ssh/id_rsa): /Users/rache/.ssh/id_rsa_develop
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 

```

```
rache:.ssh rache$ ls
id_rsa_develop id_rsa_develop.pub
known_hosts
rache:.ssh tokuhiro$ cat id_rsa_develop.pub 
```

## 公開鍵の登録

表示された公開鍵(id_rsa_develop.pub)を「ComputeEngine→メタデータ→SSH認証鍵に登録」

<img width="1278" alt="スクリーンショット 2016-11-10 16.44.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/146205/ce9a9177-ad4d-b8e7-aaea-7adafe8a9b4c.png">


```
rache:.ssh rache$ ssh xxx.xxx.xxx.xxx -i id_rsa_develop
Are you sure you want to continue connecting (yes/no)? yes
[rache@develop ~]$ 
```

これで入れます。

## ちょい補足

以下ファイルを加えると、鍵の管理が複雑にならなくていいかもです。

```~/.ssh/config
Host xxx.xxx.xxx.xxx
  HostName xxx.xxx.xxx.xxx
  User rache
  Port 22
  IdentityFile ~/.ssh/id_rsa_develop
  TCPKeepAlive yes
  IdentitiesOnly yes
```

#　特定のインスタンスのみ入れるようにしたい場合

上記の設定だと、作成したプロジェクト全てにSSHで入れるようになってしまいます。
特定のインスタンスのみに限って入れるようにしたい場合は、
「VMインスタンス」からインスタンスの編集を行い、「SSH認証鍵」欄にて
作成した「id_rsa_develop.pub」の内容を貼り付けてください。

<img width="1279" alt="スクリーンショット 2016-11-10 16.50.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/146205/533aea65-0f1c-b876-3208-4d5947aa1eac.png">
kintone 年月入力プラグイン

年月を入力できるプラグインです。

・ 日付項目に ’YYYY-MM'形式または、'YYYY年MM月'（日中言語指定時）で年月を表示します。
・ 日付項目の設定値は、'YYYY-MM-01' となります。
・ 10年単位に移動できるので、楽に年を選択できます。
・ＰＣ・モバイル対応
・３ヶ国語対応

[rex0220 stores で、販売中です。](https://rex0220.stores.jp/)

# 直近の変更点

※ Ver.7
・年月選択時の初期表示の「月から表示」指定機能を追加
　※月選択表示時に年をクリックすると年選択表示になります。


# 編集後の詳細表示

![2022-05-02_19h50_19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/79f0666c-e480-6870-b6a4-f2621b5029ff.png)

# 一覧画面の年月表示

一覧画面の対象日付も年月表示されます。

![2022-05-02_19h55_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/8209948f-bc6a-221d-812b-5af6a86b3c5e.png)

# モバイル表示

![2022-05-02_19h58_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/caa3960f-df57-ec80-62b8-e21870aa5236.png)

# 英語表示

英語の言語設定時、MMM YYYY 形式で表示します。

![2022-05-02_20h04_56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/59341a6b-c3a3-f659-e20e-98b9b96f6428.png)

# プラグインの追加

![ym11.png](https://qiita-image-store.s3.amazonaws.com/0/100572/e8400ec9-a776-1043-609d-063dec70753c.png)


# プラグインの設定
プラグイン設定画面を開くと、日付項目が表示されますので、対象にする項目をチェックします。
設定後に、「保存する」ボタンをクリックします。

対象アプリのフォームを変更する場合は、フォーム変更を本番環境に反映後に、プラグインを再設定してください。

- プラグイン有効
- 項目のチェック：　対象項目をチェック
- YYYY年MM月：　YYYY年MM月で表示する場合に、チェック（日中言語指定時）
- 月から表示：　月選択表示に指定
　※月選択表示時に年をクリックすると年選択表示になります。

![2025-03-07_09h19_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/76bdcfd9-927e-4665-a2d9-bc0b5ce481c3.png)


#注意事項
- 既に、JavaScript によるカスタマイズを行っているアプリの場合、処理が競合して、エラーになる場合があります。その場合は、該当するアプリでプラグインの使用を中止してください。
- フォームを変更した場合は、プラグインを再設定してください。
TmuxでEmacsのキーバインド

設定したら、今までよりtmuxのコピペモードを使いそうな気がしたので、メモしておく。

```bash:~/.tmux.conf
set-window-option -g mode-keys emacs
bind-key C-t copy-mode
bind-key C-y paste-buffer
bind -n Pageup copy-mode -u
```

これにより

- PREFIX + C-t => コピーモードに入る
- PREFIX + C-y => 貼り付け
- PageUp => 1ページ遡ってコピーモードに入る。ログを見る時など便利

※ PREFIXをC-tに設定している前提
datetimepickerライブラリ、flatpickrで設定しておきたい最小限の設定

### datetimepickerとしてflatpickrを使った時の設定メモ

__datetimepickrとしてシンプルでいい感じなやつです__

__なかなかデフォルトの時間設定ができなかったのでメモ__
__デフォルトでは12:00だが00:00に設定したかった__

### こんな感じ

```html
<link rel="stylesheet" href="https://unpkg.com/flatpickr/dist/flatpickr.min.css">

<input type="text" class="flatpickr">

<script src="https://unpkg.com/flatpickr"></script>
<script>
flatpickr(".flatpickr", {
    enableTime: true,
    time_24hr: true,
    defaultDate: "00:00:00"
});
<script>
```

### 結果(flatpickr.material_blue.min.cssを自分は使っています)

![flatpickr.PNG](https://qiita-image-store.s3.amazonaws.com/0/47896/0022754e-ca10-9915-a424-c6db05987244.png)
zshでその場でbindkey -v（あるいは bindkey -e）する

zsh で普段は bindkey -e だけど突発的にここで20文字右に行きたくなって bindkey -v だったら20lしてるのになあという貴方向けのキーバインド

```zsh
bindkey-e-inline() {
  zle vi-insert
  local pos
  pos=$CURSOR
  zle push-line
  bindkey -e
  zle get-line
  CURSOR=$pos
}

bindkey-v-inline() {
  local pos
  pos=$CURSOR
  zle push-line
  bindkey -v
  zle get-line
  zle vi-cmd-mode
  CURSOR=$pos
}

zle -N bindkey-e-inline
bindkey -M viins "^e" bindkey-e-inline
bindkey -M vicmd "^e" bindkey-e-inline
zle -N bindkey-v-inline
bindkey "^xv" bindkey-v-inline
```

bindkey -e の状態で `C-x v` でカーソル位置そのままで bindkey -v を、 vi モードでは `C-e` で同様に bindkey -e を発行する。
（実際のキーは適当に変更しましょう）
Fedora 24にCUDAなしでChainerをインストール

# 意外と簡単じゃなかった

fedoraなんでcentosといっしょだろと思ってchainer(1.7)をインストールしたんですが、インストールで表示されるログ上は成功していても、

```py
import cupy
```
とやるとエラーが出てしまっていました。
『cupy.coreがロードできないよ』的なエラー

-vvvvによるインストールログを見ていたところ、CUDAオプションがonになっていたので、該当のソースを眺めていたところ、--cupy-no-cudaというオプションを渡せば良いことがわかり、cythonもセットアップに必要そうだったので、追加でインストールすることで、無事にchainerをインストールすることができました。


```
# ソースからのビルド
pip install numpy
pip install six
pip install cython

python setup.py install --cupy-no-cuda
```

```
# pipからインストール
pip install numpy
pip install six
pip install cython
pip install --install-option="--cupy-no-cuda" chainer -vvvv
```
OS X に Vim を Homebrew でインストールして vi で起動する

Homebrew で最新版の Vim を Mac にインストールすることにしたのでその方法をメモっとく。

大したこと書いてないんだけど --with-override-system-vi をつけてインストールすると `vi` コマンドで最新版の Vim が起動できるということを知ったので記事にした。

# 最新版の Vim を Homebrew でインストールする

Homebrew を最新にしてから Vim をインストールする。

```shell-session
$ brew update
$ brew install vim --with-override-system-vi
```

# `vi` コマンドで最新版の Vim が起動できることを確認する

`vi` で `/usr/local/bin/vim` にリンクしていて起動できることを確認する。

```shell-session
$ which vi
/usr/local/bin/vi
$ ls -l /usr/local/bin/vi
lrwxr-xr-x  1 takuya  admin  29 Nov 10 19:06 /usr/local/bin/vi -> ../Cellar/vim/8.0.0071/bin/vi
$ vi --version
VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Nov 10 2016 19:06:33)
.
.
.
```
解決編：jedi-vimのポップアップの表示が壊れている

## 現象

NeoBundleで入れたjedi-vimで、python関数の引数などがサジェストされるポップアップの表示が下記画像のように正常に表示されない。

![スクリーンショット 2016-11-10 18.14.56.png](https://qiita-image-store.s3.amazonaws.com/0/146958/3dff7175-a7a4-c0c2-50dd-51dba3832d97.png)

``=`=jedi=0, =`=          (*_*seconds*_*) =`=jedi=`=`` などと表示されているが、正しくは下記のように表示して欲しい。

![スクリーンショット 2016-11-10 18.12.56.png](https://qiita-image-store.s3.amazonaws.com/0/146958/5a14ccb7-2c46-0e9a-d4c1-7e22817e6189.png)

## 環境

```bash
$ uname -a
Darwin **.local 15.6.0 Darwin Kernel Version 15.6.0: Thu Sep  1 15:01:16 PDT 2016; root:xnu-3248.60.11~2/RELEASE_X86_64 x86_64
$ vim --version
VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Nov 10 2016 16:28:38)
MacOS X (unix) version
Included patches: 1-71
Compiled by Homebrew
```

## 対応

自分の場合、 `~/.vimrc` の中で `syntax on` を `setlocal conceallevel=0`より後に書くことで正常に表示された。
shellコマンドで色々数える


## wc
```
wc hoge
>>> 30 40 150
hogeの行数，単語数，バイト数を表示
```

## ファイルの行数を数える
```
wc -l hoge.txt
```

`\n`の数を数えている


## フォルダ内のファイルの数を数える
### ファイル&フォルダまとめて
```
ls -1 | wc -l
```

### ファイルのみ
```
ls -F | grep -v / | wc -l
```

## 特定単語の数を数える

```
grep -c 検索したい単語 hoge.txt
```

## ファイル内のサイズを数える
### その中のファイル全部に対して調べる
```
du
```

### 特定のフォルダに対して調べる
```
du -s dir/
```

自分の今いるところのサイズなら

```
du -s .
```
Macで書体や大きさ、色等の属性を無視して、ペーストする

##通常の「ペースト」
**command** + **V**

##<font color="maroon">書体や大きさ、色等の属性を無視して、ペーストする</font>
<font color="maroon">**command** + **shift** + **option** + **V**</font>
FreeNASのownCloudでバージョンアップ失敗したので手動バージョンアップした

#概要
タイトルそのまま
社内で公開してるFreeNASの管理画面に久しぶりにアクセスしてみたらアップデートがあったので
ownCloudのプラグインを8.0.2から9.1.0へアップデートしてみた。

プラグインの方ではアップデートが終わり、WEBブラウザでアクセスすると
ブラウザでもアップデートを促されたのでアップデートボタンを押したら

`Updates between multiple major versions and downgrades are unsupported`

等といわれてアップデートに失敗する。
ownCloudのメジャーバージョンていうのは８＞９等ではなくもっと細かかった。
（わかりにくい）

[参考サイト](https://heshsum.wordpress.com/2015/02/20/manually-upgrade-your-owncloud-on-freenas/)

#やったこと
細かく刻まれたバージョンを逐次アップデートしていかないといけないということだった。

結果
8.0.2>8.0.16>8.1.11>8.2.9>9.0.6>9.1.2
という5段階のアップデートを行った

8.0.xから8.1.xはまだしも、8.2.xから9.0.x等は結局英語のチェンジログをきちんと読んで追いかけないと判らないよね。

#実際の手順
参考サイトに従って5回やったけど、全部同じなので一回分だけ書く。
(8.0.2から8.0.16)
1.FreeNASの管理画面でJailsにアクセスしてownCloudのshellを表示する。
2.フォルダのバックアップ
```$cd /usr/pbi/owncloud-amd64/www/
$mv owncloud owncloud_bak
```
3.wgetでアップデートできる次のバージョンのtar.bz2ファイルをゲット
`$wget http://download.owncloud.org/community/owncloud-8.0.16.tar.bz2`
（URLは将来変わると思うので、その際は各自調べてください）

4.tar.bz2を解凍
`$tar -xzvf owncloud-8.0.16.tar.bz2`

5.バックアップからconfig.phpをコピー
`$cp ./owncloud_bak/config/config.php ./owncloud/config/`

6.パーミッションをwwwに変更
`$chown -R www ./owncloud`

7.shellを終了させて、FreeNASの管理画面プラグインタグでowncloudのサービスの状態を一旦OFFにしてまたONに戻す

8.ブラウザでアクセスするとアップデートを促すメッセージとボタンがあるので押す

これでうまく行った。
dockerでCakePHPの開発環境を構築する

##目的
ローカル環境で簡単にCAKEPHP3での開発が始められるようにする！

##まずはmysqlのDBサーバコンテナを作成
まずは、my.confを作って適当な場所に設置します。
デフォルトで文字コードがlatin何とかってのになっているのでutf8に変更をします。

```my.cnf
[mysqld]
character-set-server=utf8
```

このmy.cnfファイルはdocker上のmy.cnfがあるべき場所に共有されるようにマウントしたい！
なので、下のコマンドでコンテナを立ち上げる
-eオプションでrootのパスワードも[root]と設定してます。

```bash
docker run --name mysql -v {my.confを置いたディレクトリパス}:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7
```

実はこのままだと、phpからmysqlからアクセスするときにホストで引っかかって落ちてしまうので
コンテナに入ってアクセス権限のあるユーザを作ります。
下記コマンドで入って

```bash
docker exec -it  mysql bash
```
後はmysql.userテーブルにユーザを追加します。
今回は下記のように追加。dockerで生成されるコンテナのIPは172から始まるようなのでそれを設定

| Host | User |
|--------|--------|
| 172.% | cake |

続いてWebサーバの作成です。

##Webサーバ用のコンテナ
イメージはukt1113/cake3を使います。
(cakephpに必要なPHPエクステンションとmod_rewriteを有効化して、composerでcakephpのインストールをしています。詳細は最下部のdockerfile参照)

下記コマンドでcake3がインストールされたコンテナを作成します。
php.iniとソース設置用ディレクトリはコンテナにマウントします。

```bash
docker run -idt -v {ローカルのsrcを置くディレクトリパス}:/var/www/html -v {ローカルのphp.iniを置くディレクトリパス}:/usr/local/etc/php -p 20080:80 --link mysql:mysql --name cake ukt1113/cake3 "/bin/bash"
```

コンテナを起動してもまだapacheが起動してないので、
コンテナに入って

```bash
docker attach cake 
```

アパッチを起動する

```bash
apache2ctl start
```


最後にhttp://localhost:20080/cake/index.phpにアクセスして
緑色のチェックが全てついていれば準備完了

ですが、Databaseがまだ×がついているはず！
ローカルのsrcを置くディレクトリ/cake/config/app.php
のデータソースを設定した後リロードするとDatabaseにもチェックがついているはず！

| Host | username | Database |
|--------|--------|-----|
| mysql | cake(さっき登録したやつ) | 事前に何か登録しておいてそれを指定 |



#cakeをインストールしたDockerファイル

```Dockerfile
FROM php:7.0-apache
MAINTAINER ukky <ukito.shi@gmail.com>

RUN apt-get update

# Install bz2
RUN apt-get install -y libbz2-dev
RUN docker-php-ext-install bz2

# Install mbstring
RUN docker-php-ext-install mbstring

# Install mcrypt
RUN apt-get install -y libmcrypt-dev
RUN docker-php-ext-install mcrypt

# Install intl
RUN apt-get install -y libicu-dev
RUN pecl install intl
RUN docker-php-ext-install intl

# Install PDO
RUN docker-php-ext-install pdo_mysql


# Install composer
## Register the COMPOSER_HOME environment variable
ENV COMPOSER_HOME /composer
## Add global binary directory to PATH and make sure to re-export it
ENV PATH /composer/vendor/bin:$PATH
## Allow Composer to be run as root
ENV COMPOSER_ALLOW_SUPERUSER 1
## Setup the Composer installer
RUN curl -o /tmp/composer-setup.php https://getcomposer.org/installer \
  && curl -o /tmp/composer-setup.sig https://composer.github.io/installer.sig \
  && php -r "if (hash('SHA384', file_get_contents('/tmp/composer-setup.php')) !== trim(file_get_contents('/tmp/composer-setup.sig'))) { unlink('/tmp/composer-setup.php'); echo 'Invalid installer' . PHP_EOL; exit(1); }"
RUN php /tmp/composer-setup.php --no-ansi --install-dir=/usr/local/bin --filename=composer --version=${COMPOSER_VERSION} && rm -rf /tmp/composer-setup.php

# Install git
RUN apt-get install -y libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev
RUN apt-get install -y git

# Install cakephp
RUN cd /var/www/html
RUN composer config -g repositories.packagist composer https://packagist.jp
RUN composer create-project --prefer-dist cakephp/app cake
```
Windows Mobile用のテキストエディタ

Windows Mobile用のテキストエディタを探してみた。
NoteT Menuが中国語。
Notepad 全画面でない。
Note 4U 使い方不明。
Code Editor free C#のコードをかける。ふーむ。
Modern Notes 背景を画像にできる。全画面でない?
Little Notepad 標準では背景が黒。
MEMO いきなり謝られた。
InNote 手書きメモ。
Note Plus Death Noteのファンらしい。背景には画像を貼れる。
Pin Notes 付箋風。いろいろ選べる? 使ってみた。全画面でない。小さい。
Notes Free カレンダーに紐づけるらしい。めんどうくさそう。
Note+ Thumbnailを表示するのはよい。タイトルがでかい。
myMemo イタリア人? センスいいが鳥ラーむけ。手書きは不要だ。
Notepads Free Notes Freeそっくり。
Action Note 地図とかにlinkできるらしい。高機能だが使うの大変そう。
Notes 4U Note 4Uとそっくり。
BlocNote 付箋風。端がめくれすぎだろう。使ってみた。小さい。広告うるさすぎ。速攻で消した。
Memorize it! デザイン嫌い。
My Dialy Planner 基本カレンダー。日曜起こし。合わない。
MyNotes BlocNoteそっくり。同じか?
NanoMemo 使ってみた。使い方がわからない。枠に文字を書くのは嫌だ。最初にタイトルを入れさせられるのはうんざりだ。
SimpleMEMO ややSimpleすぎる。
シンプルメモ帳 ややSimpleすぎる。
Calendiary コンセプトはよいがGoogleCalendarと連携していない感じ。
Plain Notes 色のセンスなし。
ThinkNote ぴんとこない。
Locked Notes ぴんとこない。
あとは有料のだが、ぜんぜんどれがいいかわからない。
やっぱりいずれは自分で開発するしかない。
[Unity] AudioClipのSerializeFieldに再生ボタンをつける

#内容
SerializeFieldしたAudioClipをその場で再生したい。

![image](https://qiita-image-store.s3.amazonaws.com/0/36154/9ae6550b-7637-79b1-9fc0-565aa57cedfd.png)

こんなように再生ボタンがついてたら
と思ったので付けました。

#環境
Unity 5.4.1p4

#実装
AudioClipのPropertyDrawerをオーバライドする。

```csharp
using UnityEditor;
using UnityEngine;
using UnityEngine.Assertions;

[CustomPropertyDrawer(typeof(AudioClip))]
public class CustomAudioClipPropertyDrawer : PropertyDrawer
{
    const string BUTTON_NAME_PLAY = "P";

    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        label = EditorGUI.BeginProperty(position, label, property);

        GUIContent labelButtonPlay = new GUIContent(BUTTON_NAME_PLAY);
        Vector2 buttonPlaySize = GUI.skin.button.CalcSize(labelButtonPlay);

        Rect contentPosition = EditorGUI.PrefixLabel(position, label);

        EditorGUI.indentLevel = 0;
        contentPosition.width = contentPosition.width - buttonPlaySize.x;
        EditorGUI.PropertyField(contentPosition, property, GUIContent.none);

        contentPosition.x += contentPosition.width;
        contentPosition.width = buttonPlaySize.x;
        contentPosition.height = EditorGUIUtility.singleLineHeight;

        if (GUI.Button(contentPosition, labelButtonPlay))
        {
            AudioClip audioClip = property.objectReferenceValue as AudioClip;

            if (audioClip != null)
                PlayClip(audioClip);
        }

        EditorGUI.EndProperty();
    }

    public static void PlayClip(AudioClip clip)
    {
        Assembly unityEditorAssembly = typeof(AudioImporter).Assembly;
        Type audioUtilClass = unityEditorAssembly.GetType("UnityEditor.AudioUtil");

        MethodInfo method = audioUtilClass.GetMethod("PlayClip", BindingFlags.Static | BindingFlags.Public, null, new System.Type[] { typeof(AudioClip) }, null);
        method.Invoke(null, new object[] { clip });
    }
}
```

注意:
AudioSourceのAudioClipはカスタム表示しているようなので反映されない。
同じような実装しているものには、再生ボタンは表示されない。

#感想
デフォルトでつけてくれればいいのになー！
Ajaxでデータをコントローラ渡すときにJSON::ParserError

#Ajaxから渡されるdataをparseするとJSON::ParserError
```ruby:app/assets/javascripts/user.coffee
UserEvent
  data =
     user:
       name: "hoge"
       age: 25
  $.ajax
    type: 'POST'
    url: /user/create
    data: data
    dataType: 'json'
```
するとこのようなエラーがでる。JSON::ParserError
原因ははっきりわからなかったが、json内の数値がうまくdecodeできていないっぽい?
どなたかわかる方は教えてください
Json.stringifyを利用し、contentTypeを指定すればちゃんとdecodeできるようになる

```ruby:app/assets/javascripts/user.coffee
UserEvent
  data =
     JSON.stringify(
       user:
         name: "hoge"
         age: 25
     )
  $.ajax
    type: 'POST'
    url: /user/create
    data: data
    dataType: 'json'
    contentType: 'application/json'
```
参考URL
http://stackoverflow.com/questions/6410810/rails-not-decoding-json-from-jquery-correctly-array-becoming-a-hash-with-intege
Mac + Vim + Markdownの環境で、クリップボードにコピーした画像を簡単に挿入

## ショートカット一発で、クリップボードにコピーした画像ファイルをMarkdown記法で挿入

![Nov-10-2016 19-23-34.gif](https://qiita-image-store.s3.amazonaws.com/0/54099/d41a37db-705d-2914-02bf-bc9f257fd00e.gif "Nov-10-2016 19-23-34.gif")

これまでAtomを利用していたのですが、色々と訳がありまして、1週間前より、Vimを普段使いするようになりました。
それで日々のメモなんかもAtom+Markdownからvim+Markdownに移行したのですが、いかんせん画像の挿入操作につまずきました。

Atom時代には画像を簡単にコピペができる[image-copipe](https://atom.io/packages/image-copipe)を利用していたのですが、Vimで同様の処理ができるpluginが見つかりませんでした。

なので今回はかなり強引に自作をしてみました。シェルスクリプト+.vimrcです。本来のVim機能拡張(vimスクリプトを利用したvim plugin化)とはまったく異なっているのは、まだVimmerになって1週間程のためです。。。Vimpluginにパッケージングできれば皆様にも利用しやすくなるはずなので、今後の宿題とさせてください！

## 機能実装の方針
今回の機能要件としては、クリップボードにコピーした画像ファイルを、Vimのインサートモード時に、コマンドひとつでMarkdown記法で画像を埋め込むこととしました。

画像の埋め込みは、ローカル環境に画像の実ファイルを保存したうえで、そのファイルのパスを指定することにしました。`[](./images/XXX.png)`  

上記で上げた[image-copipe](https://atom.io/packages/image-copipe)のように画像ファイルをどっかのサービスにアップロードし、そのURLパスをMarkdown記法で指定することも一瞬考えたのですが、クライアントワークの画像を扱うこともあり、セキュリティ上、他人の目に画像が触れるリスクを忌避するため、ローカル環境に保存する方針としました。

## 機能実装①:クリップボードにコピーした画像ファイルを、ローカルの特定のパスに保存する

こちらの機能はpngpasteを利用させていただきました。  
[GitHub - jcsalterego/pngpaste: Paste PNG into files, much like pbpaste does for text.](https://github.com/jcsalterego/pngpaste)

```
$ pngpaste ~/Document/hooray.png
```
とすれば、クリップボードにコピーした画像を、引数に記載したパス/ファイル名でpngファイルを作成してくれます。

## 機能実装②: Vimから呼び出すことを想定して、pngpasteをもとにコマンドファイルを作成する。

シェルスクリプトでコマンドファイルを作成します。

```bash:image_paste_for_vim_markdown

#!/bin/bash

# 引数がある場合には、引数を画像保存先のパスにする。
# 引数がない場合にはカレントフォルダに画像を保存する
if [ -n "$1" ]
then
  IMAGE_PATH="$1/images/"
else
  IMAGE_PATH="./images/"
fi


if [[ ! $+commands[pngpaste] ]]; then
  echo"pngpaste: command not found" >&2
  exit 1
fi

# 画像の保存先が存在するかチェックをする。
# 無い場合は、エラーをはいて処理を終了する。
# ディレクトリーを作成する処理をいれなかったのは、
# フォルダが煩雑になってしまうのを避けたかったためです。
#　特に気にされない方は、`mkdir $IMAGE_PATH`をかわりに記載してください。
if [[ ! -e "$IMAGE_PATH" ]]; then
  echo "No image folder"
  exit 1
fi

IMAGE_NAME=`date "+%Y%m%d_%H%M%S".png`

if [[ -e "$IMAGE_PATH$IMAGE_NAME" ]]; then
  echo "File already existed"
  exit 1
fi

pngpaste $IMAGE_PATH$IMAGE_NAME
RESULT=$?

# 画像が保存できた場合、ファイルへの相対パスを利用して、
# Markdown記法の画像挿入文を掃き出します
if [ $RESULT = 0 ]; then
  RELATIVE_IMAGE_PATH='./images/'
  MARKDOWN_IMAGE_SYNTAX="![]($RELATIVE_IMAGE_PATH$IMAGE_NAME)"
  echo $MARKDOWN_IMAGE_SYNTAX
fi
```

上記実行ファイルは、PATHの通ったフォルダ配下に保存のうえ、実行可能な権限に変更します。
例)
~/usr/local/bin/image_paste_for_vim_markdown

## 機能実装③: Vim上で実行できるよう、.vimrcに記載をする。
Vim上で利用できるように、.vimrcファイルに追記をします。

```vim:~.vimrc
""""""""""""""""""""""""""""""
" Markdown画像挿入自動化
""""""""""""""""""""""""""""""
imap <F2> <C-c>:r! image_paste_for_vim_markdown %:h<CR>lli

""""""""""""""""""""""""""""""
```

今回は`<F2>`にマッピングしました。
コマンドを呼び出すさい、引数に、Vimで開いているファイルのパスを渡します。  
Vimでは、`%:h`を記載することで、Vimで開いているファイルのパスを取得することができるようです。  
最後に`lli`を追加しているのは、`[](./XX.png)`が挿入された後、いい感じにカーソルの位置を整えるためです。

これで指定したショートカットを押下することで、クリップボードにコピーされた画像を簡単に挿入ができるようになりました。
vimファイルと同階層の`./images/`フォルダ内に、画像が作成されていることが確認できるかと思います。

## おわり
とりあえず機能が実現したので、Qiitaに共有させていただきました。
vimplugin化できましたら、再度共有致します！
iptables1

Chain一覧

|chain | mean|table|
|:--:|:--:|:--|
|INPUT|入力パケット| filter mangle|
|OUTPUT|出力パケット|filter nat mangle|
|FORWARD|転送するパケット|filter|
|REROUTING|受信時に宛先アドレスを変換|mangle|
|POSTROUTING|送信時に宛先アドレスを変換|nat|

ターゲット一覧

|target|使用頻度|意味|
|:--|:--|:--|
|ACCEPT|★★★|パケットを許可|
|DROP|★★★|パケットを拒否|
|RETURN|-|チェイン内ルール評価終了|
|MASQUERADE|-|送信元IPとポート番号を書き換える|
|PREROUTING|-|特定ポートにリダイレクト|
|SNAT|-|パケットの送信元アドレスを修正|
|DNAT|-|パケットの送信先アドレスを修正|
webpack で Babel を使ったときに困ったことメモ

どうしてもES2015で書きたくて初めて webpack 導入してみました。険しい道のりだったので躓いたところをメモしておきます。

# 1. jsをコンパイルしてくれない
## 現象
jsファイルのコピー（結合）はしてくれるものの、`()=>{ ... }` がそのままになっているなど、Babel が働いていない様子。コンソールには `Unexpected token import` などと表示されます。

## 解決策
`webpack.config.js`の設定で `loaders` のスペルを間違えて `loders` にしてました（ﾃﾍﾍﾟﾛ
警告が出たりしないので、なんか動かないというときは要チェックです。

# 2. コンパイルが遅い
## 現象
コンパイルに40秒くらいかかってました。  ~~ツイッターがはかどる~~ 仕事が進まず大変ストレスになりますね。

## 解決策

node.js のバージョンを最新にして、さらに node_modules をいったん全部消して`npm install`しなおしたら3秒くらいになりました。（v4 → v6.9.1）

参考：[babel-loader 6 VERY slow in webpack #139](https://github.com/babel/babel-loader/issues/139)

ちなみに、`node_modules` を `exclude` するというのが効果大のようです。（自分はすでに書いていた）

# 3. watcherが動かない（WebStorm）
## 現象
WebStorm はどのタイミングでセーブしてるのかいまいちはっきりしないんですが、待てども待てどもファイルが更新されない。

## 解決策
設定で"safe write"を検索し、チェックボックスを外す。

参考：[File saves in WebStorm don’t trigger the watcher](https://webpack.github.io/docs/troubleshooting.html#file-saves-in-webstorm-don-t-trigger-the-watcher)

# 4. モジュールが足りないと言われる
## 現象

Chromeでは怒られなかったんですが、`const` や `let` をグローバルスコープで宣言はできないみたいです。

```info.js
const info = {
  name: 'noobar'
};
```

```main.js
$(document).ready( () => {
  $('#name').text(info.name); // エラー: info is not declared
});
```

## 解決策
`import` / `export` を使います。


```info.js
const info = {
  name: 'noobar'
};
export default info;
```

```main.js
import info from 'info';

$(document).ready( () => {
  $('#name').text(info.name); // エラー: info is not declared
});
```

参考：[ES6(ES2015)でグローバルに定義したlet,const,classはグローバルオブジェクトのプロパティにならない](http://qiita.com/ConquestArrow/items/8cb01744af15afff33c0)

# 5. import を使うとエラー
##現象
上記の `main.js` で import しようとしているモジュールが見つからないと怒られます。（ブラウザではなくwebpackのコンソールでエラー）

```
 Module not found: Error: Cannot resolve module 'info' in ...
```

##解決策
**方法1: パスを明示的な相対パスにする**

```main.js
/* before */ import info from 'info';
/* after  */ import info from './info';
```

**方法2: 設定ファイルにresolve/rootを定義**

```webpack.config.js
const Path = require('path');
module.exports = {
  ...
  resolve: {
    root: Path.resolve('./src/js')
    // ファイルが./src/js/info.jsにある想定
  }
};
```
どっちでも解決しましたが、方法2の方が今後が楽そうですね。

参考：[Module not found: Error: Cannot resolve module 'components/app'. webpack + reactjs issue](http://stackoverflow.com/questions/40193374/module-not-found-error-cannot-resolve-module-components-app-webpack-react)
同一グループ中で最大のレコードを取得するSQL

備忘録
たまに必要になる。[同一グループ中で最大のレコードを取得するSQL]の取得SQLサンプル。

下記は、updatedの最大レコード情報を取得する場合。

##1.最大値を得るサブクエリから検索
```mysql:
SELECT *
FROM table AS t
WHERE updated= (
    SELECT MAX(updated)
    FROM table AS tmp
    WHERE t.group_id = tmp.group_id
);
```
ただし、同一グループ内に「最大」が複数あると、複数ヒットする。

##2.Sort＋Limit サブクエリから検索
```mysql:
SELECT *
FROM table AS t
WHERE id = (
    SELECT id
    FROM table AS tmp
    WHERE t.group_id = tmp.group_id
    ORDER BY tmp.updated DESC
    LIMIT 1
);
```
ただし、同一グループ内に「最大」が複数あると、いずれか一つが選択される。

##3.他の方法
本来、最大レコードを求めるSQLは上のやり方では無く、
別テーブルや、判定カラムで対応した方がコストが安く、可読性も高い。
FireFoxの開発ツールが便利だった話


今までは、ブラウザでhtml確認してたりする時にふと要素を入れ替えたくなったりした時、エディタで該当の場所を修正して再読込するか、FireBugとか使って要素のコピペとかしてた。
![スクリーンショット 2016-11-10 18.47.11.png](https://qiita-image-store.s3.amazonaws.com/0/40340/61e077a3-e52b-3ccc-fc58-b8e92f723a07.png "スクリーンショット 2016-11-10 18.47.11.png")

FireBugがたまにバグって動かなくなるんだけど、さっきブラウザの再起動めんどくさかったのでFireFoxの標準のやつを使ってたんですよ。

その時ふとこれドラッグ・アンド・ドロップで移動とか出来ねーかなーと思ってたら出来て驚いたって話
![スクリーンショット 2016-11-10 18.45.36.png](https://qiita-image-store.s3.amazonaws.com/0/40340/2db18e71-4beb-7cf9-70ea-8ff407730d47.png "スクリーンショット 2016-11-10 18.45.36.png")
![スクリーンショット 2016-11-10 18.45.47.png](https://qiita-image-store.s3.amazonaws.com/0/40340/4cae99d9-c37c-20c5-064f-62b76c5993a8.png "スクリーンショット 2016-11-10 18.45.47.png")


今まで、要素に付いてるイベントとか簡単に見れるのとか便利だなーとか思ってたけど、今回のこれでFireFoxの標準開発ツール結構便利だなーって思った。
iOS10でiFrameを使いWebViewからデータをネイティブに送信する方法

iOS9までは、ほぼ絶対に実在しないドメイン(`JSBridge://ActionId/`等)を`iframe`のsrcに追加して、ネイティブ側でそのコールをフックして処理をすることができた。
しかし、`iOS１０`からは実在しないドメインを使用している場合は出来なくなった。


# 対策

これが分かりやすかった： [iFrame、JSBridge 升级Xcode8和iOS 10之后的解决方案](http://gold.xitu.io/entry/57e2a3bac4c971006145a253)

## 抜粋:
>3.一直使用的JSBridge不能用了
>开发Hybrid App的同学应该都知道，其实js和native通信关键的就是<iframe>标签，通常的bridge.js会用如下的代码添加和删除<iframe>标签：
>
>var iFrame = document.createElement("IFRAME");  
>iFrame.setAttribute("src","JSBridge://ActionId=" + id);    
>document.documentElement.appendChild(iFrame);    
>iFrame.parentNode.removeChild(iFrame);
>然后会在UIWebView的回调方法-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;中去解析截获的src属性中的ActionId值，但是很不幸在Xcode8打包到iOS 10的设备中，在UIWebView的回调方法中request参数中的URL是空的，什么也没有。这个问题的根本原因是上面动态添加的<iframe>的src属性不符合URL格式规范，正确的URL格式规范应该是协议://host?args,所以上面明显是不符合规范的，只要添加一个自定义的host字符串就可以了，代码改动如下：
>
> iFrame.setAttribute("src","JSBridge://customeHost?ActionId=" + id);
>
> 文／马修王（简书作者）
> 原文链接：http://www.jianshu.com/p/c69d5112b3ae
> 著作权归作者所有，转载请联系作者获得授权，并标注“简书作者”。


## つまり
iframeのsrcに使用しているURLを実在しそうなホストにすればいい。(OLDをNEWにすればいい）
大文字ABCDEFGから小文字のabcdefgにしたのはうまくうごかなかったから。

* OLD: `ABCDEFG://call/id=1` 
* NEW: `abcdefg://project_name.com/call/id=1`


# MEMO

* これに起因する問題は大きく分けて２つおこった
    * LINE@のページを表示させているとき、`line://foo/bar`で、LINEアプリのLINE@を開けなくなった。
        * 対策: `LINE@` 内の`data-href`を書き換えるJSをロード完了時に流し込む形で対応した。

    * 自社サービスのWEBページ内からデータ(イベント/呼び出し)を受け取れなくなった
        * 対策：AndroidとiOS側で呼び出しコールを変えるのは大変だっため、iOS側のネイティブコードで呼び出し方法を変えた。
        * 以下にOLDからNEWに変えるJSを流し込む形で対応した
            * OLD: `ABCDEFG://call/id=1` 
            * NEW: `abcdefg://project_name.com/call/id=1`


# 参考

* [iFrame、JSBridge 升级Xcode8和iOS 10之后的解决方案](http://gold.xitu.io/entry/57e2a3bac4c971006145a253)


# 最後に

書き換えしたいφ('ᴗ'」)
画像を`bin/rake db:seed`で登録する


テーブル構成はこんな感じ

```
  create_table "posts", force: :cascade do |t|
    t.string   "title"
    t.binary   "image"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end
```

今日やりたかったのは、一覧表示の確認をするために予め画像データを登録したかった。
seedでデータと一緒に登録できれば楽だなぁと思って頑張ってみた

```
for num in 1..10 do
  image_path = File.join(Rails.root, "test/sample.jpg")
  image = File.open(image_path, 'rb').read
  Post.create(title: "title#{num}", image: image)
end
```

1. サンプルになる画像を適当な場所に置く
2. `File.open`でファイルを開いて、`rb`モードで開く

※`b`ってのがバイナリモードって意味。いまいち分かってないけどbinary型に登録するんだから付けるんだろうって思ってる。
※`r`は読み込みモードって意味。
※`read`メソッドは一度に読み込んで標準出力するんだって

後は、`bin/rake db:seed`すれば登録できる
a-blog cmsで、地図カスタムフィールド内のGoogleMapsを自動的に起動させる

## 背景

a-blog cmsをかなり利用している人でなければわからないことですが…
a-blog cmsには、Google Maps経由のUIで位置情報を入力できるカスタムフィールドがあります。

![a-blog_cms 2.jpg](https://qiita-image-store.s3.amazonaws.com/0/21117/08881a56-4436-5e7a-465d-a5d32a9032e2.jpeg)

このフィールドは、バージョン2.6.1の時点で、入力された内容によって投稿画面を表示したときの挙動が異なります。

- 新規投稿のとき、またはフィールドが未入力のエントリーを編集するとき
  - スタティックマップを表示し、マップをクリックしたときにダイナミックマップを表示する
- フィールドが入力済のエントリーを編集するとき
  - 自動的に入力内容に沿ったダイナミックマップを表示する

「クリックしなければ起動しない」ということが投稿画面内に明示されていないのが悩ましいところです。

これを自動的に起動するようにできたので、次のバージョンでconfig.jsで選択できるようになることに期待しつつ、参考までにシェアします。

*※a-blog cmsコアの、圧縮されたJavaScriptコードを編集します。荒っぽい方法となるため、内容の完全保証はできません。JavaScriptの知識があり、UX方面で気になった人だけ試してみてください。*

## 手順

下記のファイルをエディタで開いてください。

/js/dispatch/edit/map.js

そして、以下の内容でファイル内を検索してください。8行目あたりでヒットします。

```
if($lat.val().length&&$lng.val().length)activate();else $img.click(function(){if(!$lat.val().length)$lat.val(latlng[0]);if(!$lng.val().length)$lng.val(latlng[1]);if($zoom.size())$zoom.val(zoom);activate()});
```

このコードを展開すると以下のようになります。

```
if($lat.val().length&&$lng.val().length)activate();
else {
    $img.click(function(){
        if(!$lat.val().length)$lat.val(latlng[0]);
        if(!$lng.val().length)$lng.val(latlng[1]);
        if($zoom.size())$zoom.val(zoom);
        activate()
    });
}
```

これを、以下のようにクリックイベントから出した状態にして更新してください（else文から出してはいけません）。

```
if($lat.val().length&&$lng.val().length)activate();
else {
    if(!$lat.val().length)$lat.val(latlng[0]);
    if(!$lng.val().length)$lng.val(latlng[1]);
    if($zoom.size())$zoom.val(zoom);
    activate();
}
```

キャッシュをクリアして投稿画面を表示し、自動的に起動することを確認してください。
Packer + MItamaeでDockerfileのないDockerライフ

前回[Packer + itamaeでDockerfileのないDockerライフ](http://qiita.com/hatappi/items/61f47c48921d6870dfb4)の記事でitamaeを使ってDocker imageを作ることにしました。
ただその時の課題として**対象マシンにitamaeを動かすためにrubyをインストールしないといけないことでした** :cry:

この問題を最近 [k0kubun](https://twitter.com/k0kubun)さんがリリースされたMItamaeが解決してくれそうだったので使ってみました。

## MItamaeとは？
[@k0kubun](https://twitter.com/k0kubun) さんが作成されたmrubyのItamae
http://k0kubun.hatenablog.com/entry/mitamae

## そもそもItamaeは何が問題だったのか
- Itamae ssh経由での適用は遅いのでサーバー側において実行したい
- linuxとかにはrubyが入っていないものもある
    - Itamaeのためだけにruby一式をインストールする?

**シングルバイナリで出来たら便利そうだ**

## MItamae登場
Itamaeの問題からItamae-goが出来たけどやっぱりrubyで書きたいよねってところから
mrubyのMItamaeが登場したそう。

## 何が嬉しいのか？
- 実行にrubyとかgemとかに依存しないので楽
- コンパイル済みのものを使用するので起動が高速

## 実際に試してみた
[Packer + itamaeでDockerfileのないDockerライフ](http://qiita.com/hatappi/items/61f47c48921d6870dfb4)
でやったお題と同じrails serverを動かすものです。

リポジトリは前回と同じ[ここ](https://github.com/hatappi/packer-docker-sample/tree/master/packer)に作りました。

### Itamaeの時との差分に関して
レシピはほぼそのままで動く :smile:
ファイル変更にまだ対応していないので、新規作成にしてあげただけ

大きな変更点としては外部レシピの管理方法がかわったこと
Itamaeの時はGemfileに記載していたけど今回はmrubyを使っているので使えない。
そこで現状はgit submoduleで管理してる
MItamaeのバイナリのディレクトリにpluginsディレクトリをほってそこに追加していく。
詳しくは [ここ](https://github.com/k0kubun/mitamae/blob/master/PLUGINS.md)に書いてある。

```
.
├── cookbooks
│   ├── rails
│   │   ├── default.rb
│   │   ├── files
│   │   ├── hoge.rb
│   │   └── templates
│   └── rbenv
│       ├── default.rb
│       ├── files
│       └── templates
├── mitamae-x86_64-linux // 実行ファイル
├── plugins
│   └── itamae-plugin-recipe-rbenv
│       ├── CHANGELOG.md
│       ├── Gemfile
│       ├── LICENSE.txt
│       ├── README.md
│       ├── Rakefile
│       ├── itamae-plugin-recipe-rbenv.gemspec
│       ├── lib
│       └── mrblib -> lib
└── roles
    └── ubuntu
        ├── default.rb
        ├── files
        └── templates
```

## MItamaeを使ってみて
今回はrubyをいれる題材だったので微妙だったけどelasticearchいれようとかrubyを必要としない環境を構築する時にItamae動かすからrubyいれないといけないとかitamae ssh遅くて辛いみたいな環境構築をする上の葛藤を少し軽減できる気がするので良さそう。
バイナリを対象マシンにアップロードすればすぐ動くのは **快適!!**

現状のItamaeのレシピが無駄になるかというと、そうではなくてファイル編集などまだ対応していないものはあるものの今のレシピをほぼそのまま使用していけるので移行の障壁も低かった。
dashDBへSQLツールでアクセスして表示する

初めてWatson IoT Platformを使ってみよう、というかたのためのガイドです。
[Watson IoT Platformを使ってみる](http://qiita.com/egplnt/items/af867711a7191923b2ff)でIoTアプリを準備しました。
[Watson IoT Platform - 直接dashDBへデータを格納する](http://qiita.com/egplnt/items/2c911b7618517ebe9ba2)などでdashDBに格納したIoTデータをSQLのツールを使ってアクセスし表示します。

# 1. SQLツールをダウンロードします
- dashDBへアクセスするためのツールはSQLが使えるツールであれば何でも構わないです。ネットの検索で有償・無償の様々なSQLツールが見つかります。
- ここではSQLWorkbenchというツールを使ってみます。
[SQLWorkbench](http://www.sql-workbench.net/downloads.html)からダウンロードします。
- ここでは`Download package for MacOS`を選択し、`Workbench-Build121-MacJava8.tgz`というファイルをダウンロードして解凍すると、｀SQLWorkbenchJ｀というファイルが得られます。

# 2. dashDBの接続情報を確認します
- dashDBのダッシュボードを開き、画面左側のメニューから「Connect」⇨ 「Connect Information」を開き、接続のために必要な情報を確認します。
- SQLWorkbenchからの接続に必要な情報として、`Host name`、`Username`(UIDとして表示される)、`Password`（PWDとして表示される）を控えておきます

# 3. DB２のjarファイルを入手する
- `db2jcc.jar ダウンロード`などで検索し、db2jcc.jarのダウンロードサイトを探します。[DB2 JDBC Driver Versions and Downloads](http://www-01.ibm.com/support/docview.wss?uid=swg21363866)などからダウンロード可能です。
- それほど最先端のSQL文を発行するわけではないので、db2jcc.jarのバージョンなどにはそれほど拘らなくても大丈夫です。ダウンロード可能なものを入手します。

# 4. SQLworkbenchを起動します
- 1.で入手したSQLWorkbenchJをダブルクリックで起動します。起動後の初期設定画面で
    - Driver欄は、`IBM DB2 (com.ibm.db2.jcc.DB2Driver)`を指定します
    - URLは`jdbc:db2://hostnameで提供された情報:50000/BLUDB`の形式で指定します。
    - UsernameとPasswordはそのまま指定します
 
![スクリーンショット 2016-11-10 18.39.38.png](https://qiita-image-store.s3.amazonaws.com/0/125842/b1f6fdba-f673-fa6e-3d41-66fb80ee7d36.png)
上記の設定を完了したら、画面左下の`Manage Drivers`ボタンを押します。
![スクリーンショット 2016-11-10 18.49.21.png](https://qiita-image-store.s3.amazonaws.com/0/125842/8be2c1ef-302c-bdd0-e7ec-5daa81302682.png)
- 画面左側のメニューから`IBM DB2`を選択し、画面右側のフォルダーのアイコンから前述3.で入手したdb2jcc.jarを指定します
![スクリーンショット 2016-11-10 18.54.50.png](https://qiita-image-store.s3.amazonaws.com/0/125842/6e3cae83-10b5-0d98-e25d-79e04602fb25.png)
- 「OK」を押して保存します

# 5. SQLを発行してみます
- SENSOR2DBなどの表がある場合、`select * from SENSOR2DB;`等を実行してみます。
- 画面上部の`statement 1`欄にSQL文を指定し、画面左上の「実行」（右向きの三角形）を押して実行します
- SQL文のエラーになる場合、dashDBのダッシュボードにある「Run SQL」メニューなどでSQL文の書き方を練習してみてからこのSQLWorkbenchで実行するのも良いかもしれません。
![スクリーンショット 2016-11-10 19.04.09.png](https://qiita-image-store.s3.amazonaws.com/0/125842/3886d87e-2f8a-d1b5-578f-46eaba324dbc.png)
UnityのスクリプトエディタがVS Code (Visual Studio Code) から戻せなくなったら


## はじめに
UnityとVisual Studio Code（以下VS Code）の連携を試してみたのですが、微妙にしっくり来なかったため、再びMonoDevelopに戻すためにUnityメニューの「Prefereces...」→「External Tools」内の「External Script Editor」でMonoDevelopを選択しました。

![Kobito.TEE3JS.png](https://qiita-image-store.s3.amazonaws.com/0/5879/4ab0318d-4b03-4667-746d-0946d2e8cda9.png "Kobito.TEE3JS.png")

しかし、この状態でC#のスクリプトファイルを開いてもVS Codeで開かれてしまいます。「Save Project」しても設定は反映されず、Unityを再起動すると「External Script Editor」の設定がVS Codeに戻っていました。

![Kobito.HzT5lZ.png](https://qiita-image-store.s3.amazonaws.com/0/5879/e0bffaa8-a707-65ad-e256-60a5e62b4b3d.png "Kobito.HzT5lZ.png")


## 原因
UnityとVS Codeを連携させるときにVS CodeのUnityプラグインを[GitHub](https://github.com/dotBunny/VSCode/)や[Asset Store](https://www.assetstore.unity3d.com/jp/#!/content/45320)からインストールしますが、このUnityプラグインの設定が残ってしまうことが原因でした。
（UnityとVS Codeを連携させる方法は[こちら](https://code.visualstudio.com/Docs/runtimes/unity)を参照)


## 対処方法
Unityメニューの「Prefereces...」→「VSCode」内にある「Enable Integration」のチェックをOFFにします。これによって「External Script Editor」の設定が自動で上書きされることなく、別のスクリプトエディタを使用することができるようになります。

![Kobito.5g8qnf.png](https://qiita-image-store.s3.amazonaws.com/0/5879/cbbeed69-7720-5414-820d-d4e8a54bbe8e.png "Kobito.5g8qnf.png")


## 参考
* [Unity external script editor won't change（Unityのフォーラム）] (http://answers.unity3d.com/questions/1199494/unity-external-script-editor-wont-change.html)
* [Unity Development with VS Code](https://code.visualstudio.com/Docs/runtimes/unity)
Excelの列番号文字列をJavaで作る

やりたいこと
===========

10進数を26進数(アルファベット)に変換したい
Excelとかの列番号文字列を得たいので
(A, B, C, ..., X, Y, Z, AA, AB, AC, ...)

この文字列は以下のように呼ぶらしい
https://en.wikipedia.org/wiki/Bijective_numeration#The_bijective_base-26_system

やったこと
=========

https://gist.github.com/theazureshadow/4a5a032944f1c9bc0f4a をJavaにした

```
public class Bijective {
    static String base26(int n) {
        StringBuilder buf = new StringBuilder();
        while (n != 0) {
            buf.append((char) ((n - 1) % 26 + 'A'));
            n = (n - 1) / 26;
        }
        return buf.reverse().toString();
    }

    public static void main(String[] args) {
        for (int n = 1; n <= 100; n++) {
            System.out.printf("%d - %s%n", n, base26(n));
        }
    }
}
```

編集リクエストいただいた内容(自分では試してない)
===========
POI のCellReferenceでエクセルの列やセルの行列番号文字列を取得できる

```
CellReference ref = new CellReference("sheet1", 0, 0, false, false);
System.out.println(ref.formatAsString());
```

結果：`sheet!A1`

例1：`new CellReference(2, 0).formatAsString()`
　　⇒ `A3`
例2：`new CellReference(2, 0, true, true).formatAsString()`
　　⇒ `$A$3`
例3：`new CellReference("sheet", 2, 0, false, true).formatAsString()`
　　⇒ `sheet!$A3`

http://www.ne.jp/asahi/hishidama/home/tech/apache/poi/cellreference.html
連想配列の最小値の抽出 [nodejs]


# 何がしたい
nodejsを使っているとき、自分はよくデータを連想配列形式にしていろいろな場所に引き回しています。
そんなとき、データセットの中で最新のデータだとか、一番古いものだとかが欲しくなることが多々あります。

```javascript:list
let hashList = [
	{name: 'Maekawa-Miku', age: '15'}
   ,{name: 'Takamori-Aiko', age: '16'}
   ,{name: 'Totoki-Airi', age: '18'}
   ,{name: 'Otokura-Yuki', age: '13'}
];

```
ようは
### このhashListからageが一番小さいデータのnameが欲しい

# 前提条件
map関数を使用します。
あと、現在ES6表記の練習中なのでそっち形式で書いてます。

# 実装

```javascript:sample
const returnLatestdata = req => {
    let hashList = req;
    let tempAgeList = hashList.map(element => {
        return element.age
    });
    let elmNum = tempAgeList.indexOf(Math.min.apply(null, tempAgeList));
    return hashList[elmNum];
};
```

```javascript:結果
console.log(returnLatestdata(hashList));	//{name: 'Otokura-Yuki', age: '13'}
```

# 概要
①Map関数を用いて、要素だけの配列を作成します。
②作成した配列の最小値のデータを取得し、そのデータを使って、元の配列からそれが含まれるデータセットを取得します。

# まとめ
いつもいつも悩んで悩んでたいのですが、map関数に出会って楽に出来てよかった。
PHPメールチェック正規表現

###備忘録。
結構適当なので、使用は気を付ける。
記号もパイプ許可とか外した方が精神的に安心だが。

```php:
preg_match("/^([a-zA-Z0-9])+([a-zA-Z0-9\?\*\[|\]%'=~^\{\}\/\+!#&\$\._-])*@([a-zA-Z0-9_-])+\.([a-zA-Z0-9\._-]+)+$/", $mailaddress)
```

**解説**
下記を確認。

1.英数字
2.英数字 ? * [ |  ] % ' = ~  ^ { } / + ! # & $  . _ -
3.@
4.英数字 _ -
5.ピリオド
6.英数字 . _ -

######※追記
コメント頂いているように生半可なチェックをするぐらいなら下記で判定した方がよいです。

```php
(bool)filter_var($email, FILTER_VALIDATE_EMAIL);
```
Android Animation Libraries

##AndroidViewAnimations
https://github.com/daimajia/AndroidViewAnimations

![alt](https://camo.githubusercontent.com/c41223966bdfed2260dbbabbcbae648e5db542c6/687474703a2f2f7777332e73696e61696d672e636e2f6d773639302f3631306463303334677731656a37356d69327737376732306333306a623471722e676966)

##Rebound
http://facebook.github.io/rebound/
Spring Animations for Android.

##Backboard
https://github.com/tumblr/Backboard
A motion-driven animation framework for Android.

##AnimatorDurationTile
https://github.com/nickbutcher/AnimatorDurationTile

![alt](https://github.com/nickbutcher/AnimatorDurationTile/raw/master/screenshots/duration_scale_toggle_demo.gif)

##Android Animations Actions
https://github.com/dtx12/AndroidAnimationsActions
Actions for android animations. Inspired by libgdx scene2d actions.

![alt](https://camo.githubusercontent.com/2450656ba3353a29e274b8be6ff22fc9fc6b5398/687474703a2f2f692e696d6775722e636f6d2f457565524272702e676966)

##SmallBang
https://github.com/hanks-zyh/SmallBang
twitter like animation.

![alt](https://github.com/hanks-zyh/SmallBang/raw/master/screenshots/demo.gif)

##ViewAnimator
https://github.com/florent37/ViewAnimator
A fluent Android animation library.

![alt](https://camo.githubusercontent.com/0c031aa501e2d450ca7c9ea52a0a58d65c18371b/68747470733a2f2f6a2e676966732e636f6d2f45526c427a572e676966)

##NiftyDialogEffects
https://github.com/sd6352051/NiftyDialogEffects

![alt](https://camo.githubusercontent.com/456687ac516bb07f1076928d635bfddf6b90d5ec/687474703a2f2f696d67302e70682e3132362e6e65742f69433436653162586b55316631724966555a6f3939773d3d2f363539373632303632313938343031393430382e676966)

##EasingInterpolator
https://github.com/MasayukiSuda/EasingInterpolator
Twenty-eight different easing animation interpolators for Android.

![alt](https://github.com/MasayukiSuda/EasingInterpolator/raw/master/art/FPSAnimator1.gif)

##FragmentAnimations
https://github.com/kakajika/FragmentAnimations
Animation examples for support.v4.Fragment transition.

![alt](https://raw.githubusercontent.com/wiki/kakajika/FragmentAnimations/images/cube.gif)
excel & VBAでファイル名を一括リネーム

1. &nbsp;エクセルファイルの<b>A列に「元のファイル名」</b>、<b>B列に「変更後のファイル名」</b>を入力しておき、下記サンプルではデスクトップに「myfolder」というフォルダを作成してある想定です。
2. &nbsp;ファイル右クリックから、プロパティでファイルパスを取得し、ファイルの親パスを指定する
3. &nbsp;実行するとA列の行数分実行されます
- 注：リネーム後の同名のファイルがあるとエラーが出ます。また、リネーム対象のファイルが無い場合もエラーが出ます

##エクセルファイルのA列、B列
| A | B |
|:-:|:-:|
| aaa.pdf | A-001.pdf  |
| bbb.pdf  | A-002.pdf  |
| ccc.pdf  | A-003.pdf  |
| ddd.pdf  | A-004.pdf  |
| eee.pdf  | A-005.pdf  |

###デスクトップのmyfolderというフォルダには以下のファイルがある想定
→　aaa.pdf, bbb.pdf, ccc.pdf, ddd.pdf, eee.pdf

##Visual Basicに標準モジュールを追加して以下を入力し実行

```vbnet
Option Explicit
Sub renamex()
    '保存先
    Const MyFolder$ = "C:\Users\●●●\Desktop\myfolder\"
    Const A& = 1, B& = 2

    Dim con As Long
    con = Cells(Rows.Count, "A").End(xlUp).Row
    For i = 1 To con
        Name MyFolder & Cells(i, A).Value As MyFolder & Cells(i, B).Value
    Next i
End Sub
```

##ThisWorkbook.Pathでパスを取得する場合
**エクセルファイルと同階層に、リネーム対象ファイルがある想定**

```vbnet
Sub renamex()
    '保存先
    MyFolder$ = ThisWorkbook.Path & "\"
    Const A& = 1, B& = 2 

    Dim con As Long
    con = Cells(Rows.Count, A).End(xlUp).Row
    Dim i As Long
    For i = 1 To con
      Name MyFolder & Cells(i, A).Value As MyFolder & Cells(i, B).Value
    Next i
End Sub
```
Interlockedな比較をする

こんなデータ集計用のクラスがあります。

```csharp
class Data{
	long totalvalue {get; private set;}
	long maxvalue {get; private set;}
	long count {get; private set;}

	void update(long value){
		totalvalue += value;
		count++;
		if (maxvalue < value) maxvalue = value;
	}
}
```
これをマルチスレッドで動かす事を考えます。
lockを使うのが簡単ですが、今回はlockより軽いInterlockedを使ってみます。

```csharp
class Data{
	long totalvalue {get; private set;}
	long maxvalue {get; private set;}
	long count {get; private set;}

	void update(long value){
		System.Threading.Interlocked.Add(ref totalvalue, value);
		System.Threading.Interlocked.Increment(ref count)
		if (maxvalue < value) maxvalue = value;
	}
}
```
足し算とインクリメントは専用の関数があるのですが、最大値の更新は関数がありません。
使えそうな関数を探すと、「if (a == b) a = c;」という、同じ値なら値を更新する
CompareExchangeという関数がみつかります。
この関数を使い、比較前の値と異なる値になっていたら、もう一度やり直す、という仕組みをいれます。

```csharp
class Data{
	long totalvalue {get; private set;}
	long maxvalue {get; private set;}
	long count {get; private set;}

	public static long InterlockedCompareExchange(ref long location, long value, Func<long, bool> compare)
	{
	    long initialValue;
	    do
	    {
	        initialValue = location;
	        if (compare(initialValue)) return initialValue;
	    }
	    while (System.Threading.Interlocked.CompareExchange(ref location, value, initialValue) != initialValue);
	    return initialValue;
	}

	void update(long value){
		System.Threading.Interlocked.Add(ref totalvalue, value);
		System.Threading.Interlocked.Increment(ref count)
		InterlockedCompareExchange(ref maxvalue, value, mv => mv < value);
	}
}
```