OmniAICreator/Qiita-1.07M huggingface dataset:
MacOSXパッケージ関連コマンドまとめ

Qiita初投稿です

## コマンドまとめ

pkgutil: \*.pkgで入れたものに関するユーティリティ
installer: システムソフトウェア/パッケージインストーラツール

### pkgutil

#### データベース系

+ `--pkgs` : 今入っているパッケージのIDリスト
	+ `--pkgs=REGEXP` : 正規表現にマッチしたものの出力
		+ cf: `man 7 re_format`
	+ `--pkgs-plist` : plist形式での出力
+ `--files PKGID` : インストールしたファイルのリストを出力
+ `--export-plist` : 全情報をplist形式で出力
+ `--verify PKGID` : パッケージのファイルシステムのパーミッションやフラグの確認
	+ cf: `man 8 repair_packages`
+ `--repair PKGID` : `--verify`の修復版
	+ cf: `man 8 repair_packages`
+ `--pkg-info PKGID` : パッケージ情報を出力する
	+ `--pkg-info-plist PKGID` : plist形式での出力
+ `--forget PKGID` : 管理データベースからPKGIDに関して消す
+ `--file-info PATH` : PATHの情報を表示
	+ `--file-info-plist` : plist形式での出力
	+ pkgから入れたものであればpkgidとか出てくる

#### ファイル系

+ `--expand PKG-PATH DIR-PATH` : PKG-PATHの中身をDIR-PATHに展開する
	+ DIR-PATHは新しく作られるので`.`は指定できない
+ `--flatten DIR-PATH PKG-PATH` : `--expand`の逆 DIR-PATHの中身をPKG-PATHにまとめる
+ `--bom PKG-PATH` : PKG-PATHからBOMファイルを `/tmp` の下に展開する
	+ BOMファイルは`lsbom`で中身を見れる
	+ cf: `man lsbom` `man 5 bom`
+ `--payload-files` : インストールされるファイルの出力

### installer

+ `-dominfo` : インストール先のドメインの表示
	+ この場合のドメインはローカルシステムかユーザのホームディレクトリかなど
+ `-volinfo` : インストール出来るボリュームの表示
+ `-pkginfo` : インストールされるパッケージのリスト
	+ メタパッケージならサブパッケージの出力

## アンインストールについて

### 消したいファイルがわかっている場合
1. `pkgutil --file-info file_path`でpkg-idを取得
	+ バージョンによっては古いパッケージのものが出てくるかもしれない
2. 似たようなパッケージ名が無いか調べる
	+ 重複しているのがあるかもしれない
3. ファイルを消す
	+ 長いので以下のコマンド節のものを参考に
4. パッケージ情報を消す
	+ `pkgutil --forget PKG-ID`

### pkgファイルがあるとき

1. pkgファイルを展開する
	+ `pkgutil --expand PKG-PATH DIR-PATH`
2. DistributionとかPackageInfoとか見てpkg-idを取得
	+ Distribution : `pkg-ref`タグの`id`プロパティを見るのが良さそう
	+ PackageInfo : ルートタグの`identifier` プロパティがそれっぽい
3. 消したいファイルがわかっている時の2に行く

## コマンド

+ インストールされているディレクトリを取得
	+ `pkgutil --pkg-info PKG-ID |grep -e "volume:" -e "location:" | grep -v "(null)" | cut -d' ' -f 2 | paste -s -d "\0" -`
		1. `pkgutil`でPKG-IDに関する情報を取得
		2. `volume:` と `location:` コマンドが入っている行だけ抽出
		3. `volume: /`みたいな形式になっているのでcutコマンドで2個目の値だけ取る
			+ フォーマットが崩れると死ぬ
		4. `paste`で区切り無しで連結
+ パッケージからインストールしたファイルの内存在するファイルかシンボリックリンクを取得
	+ `root=$( pkgutil --pkg-info $PKG_ID |grep -e "volume:" -e "location:"| grep -v "(null)"  | cut -d' ' -f 2 | paste -s -d "\0" -) ;pkgutil --files $PKG_ID | while read f ; do file=${root%/}/$f ; [[ -e $file || -L $file ]] && echo $file ; done`
+ パッケージからインストールしたファイルの削除
	+ `root=$(pkgutil --pkg-info $PKG_ID | grep -e "volume:" -e "location:" | grep -v "(null)" | cut -d ' ' -f 2 | paste -s -d "\0" -); pkgutil --files $PKG_ID | sort -r | while read f; do file=${root%/}/$f ; [[ -L $file ]] && { [[ ! -e $file ]] && sudo unlink $file } || { [[ -f $file ]] && sudo rm $file ; [[ -d $file ]] && sudo rmdir $file ; } done`

## 参考文献

+ [blog.niw.at Mac OSXのパッケージファイルを操作する](http://blog.niw.at/post/16690761384)
+ `man pkgutil`
+ `man 5 plist`: plist形式について
+ `man 7 re\_format`: 使われている正規表現について
+ `man 8 installer`
+ `man zshmisc`
	+ conditional expressions の節
webpackでsource-mapを表示できるようにする

# はじめに
備忘録も兼ねて、webpackでsource-mapを表示する設定を説明します。

# devtoolにinline-source-mapを指定しましょう
こんな感じにwebpack.config.jsを設定します。すごい簡単ですね。

```js
{
  devtool: 'inline-source-map'
}
```

ちなみに上記の設定は、ビルドしたjavascriptにsource-mapを書き出すというものです。source-mapの出力先を書かないで済み、手軽なのがいいです。公式サイトを見ると、他にも色々な指定ができるようなので、用途に応じて使い分けるといいと思います。

https://webpack.github.io/docs/configuration.html#devtool

# おわりに
手前味噌になりますが、自作ゲームでsource-mapの設定をしたところです。このゲームではgrunt-webpackを使っているので厳密にはwebpack.config.jsではありませんが、大体同じなのでわかると思います。

ソースはここ
https://github.com/kaidouji85/gbraver/blob/e732f88190669adb31a86ebda6cb1cab58667af0/grunt/webpack/index.js

プロジェクト全体のソースはここ
https://github.com/kaidouji85/gbraver/tree/e732f88190669adb31a86ebda6cb1cab58667af0
PHP+Redisを使って簡単にアクセスランキングを実装


ブログなどでよく見かけるアクセスランキング。
Redisを使えば以下の流れで簡単にアクセスランキングを実装することができます。

※2016/11/29追記 ライブラリ化しました！
https://github.com/YuzuruS/redis-ranking

packagistに登録もしてあるので、composerを使って簡単にインストールできます。

```composer.json
{
    "require": {
       "yuzuru-s/redis-ranking": "1.0.*"
    }
}
```

### PVカウントアップ
記事にアクセスがあったらzincrbyで一部日付を持ったキーのスコアをインクリメント

```count.php
// 記事ID $article_id にアクセスがあったら、スコアをインクリメント
$key = date('Ymd') . ':article:pv';
$Redis->zincrby($key, 1, $article_id);

// keyが溜まり続けるので、1ヶ月後に削除する
$Redis->setTimeout($key, 60 * 60 * 24 * 30);

```

### 集計
1週間(もしくは1ヶ月)分のデータをzUnionで合算
アクセスランキングを作成します。
日時バッチ等で実行してください。

```collect.php
// 1週間分のPVを集計
$keys = [];
for ($i = 1;$i <= 7;$i++) {
	$keys[] = date('Ymd', strtotime("-{$i} day")) . ':article:pv';
}
$Redis->zUnion('weekly_article_pv', $keys);

```


### アクセスランキングの取得
zRevRangeでアクセスランキングを取得

```getRanking.php
// アクセスランキングを取得
$ranking = $Redis->zRevRange('weekly_article_pv', 0, -1);
```
gruntでコマンドライン引数を取得する

# はじめに
この記事ではgruntでコマンドライン引数を取得する方法を説明します。

# grunt.optionを使いましょう
gruntにコマンドライン引数を渡すには、以下のようにします

    grunt タスク名 引数名=値

そして、これをgrunt内で受け取るには、Gruntfile.jsで以下のように書きます。

```js
grunt.option('引数名')
```

元ネタ
http://gruntjs.com/api/grunt.option

# おわりに
手前味噌ですが、自作ゲームでgruntへのコマンドライン引数引き渡しをやってみました。コードはこんな感じです。

https://github.com/kaidouji85/gbraver/blob/e732f88190669adb31a86ebda6cb1cab58667af0/Gruntfile.js

プロジェクト全体のコードはここです。
https://github.com/kaidouji85/gbraver/tree/e732f88190669adb31a86ebda6cb1cab58667af0
Gruntで環境ごとに設定を変える

# はじめに
この記事では、環境によりGruntfile.jsの設定を変える方法を説明します。

# grunt.mergeを使いましょう
以下のように共通設定はgrunt.initConfig、環境ごとに異なる設定はgrunt.mergeを使いましょう。ちなみにですが、

```js
module.exports = function(grunt) {
    
    grunt.initConfig({
　　　　　　　　　　　　// 全環境での共通設定はここに書く
　　　　　　　　});

    // ここから下は、環境ごとの設定を書いていく
    // サンプルコードではenvに環境名が入っているとする
    // 環境名に入るのは、test、productionを想定
    
　　　　　　　　if (env === 'test') {
        grunt.merge({
          // テスト環境の設定
        });
    }

　　　　　　　　if (env === 'production') {
        grunt.merge({
          // 本番環境の設定
        });
    }


```

grunt.merge
http://gruntjs.com/api/grunt.config#grunt.config.merge

# おわりに
今まで環境ごとにGruntfile.jsを用意していましたが、これからは1つのファイルで大丈夫になりました。手前味噌ですが、自作ゲームでこれを試してみました。

https://github.com/kaidouji85/gbraver/blob/e732f88190669adb31a86ebda6cb1cab58667af0/Gruntfile.js

プロジェクト全体のコードはここです。
https://github.com/kaidouji85/gbraver/tree/e732f88190669adb31a86ebda6cb1cab58667af0
Git Extensions起動バッチファイルをパスの通ったフォルダに置いたらはかどった話

Visual Studio Codeには、Git機能が内蔵されています。しかしながら、サブモジュールの操作など込み入った操作はここでは行うことができません。

その場合、コマンドプロンプトを開いてGitコマンドを使うことになりますが、本来Gitコマンドに慣れていないわたしとしては、なるべくGUIツールを使いたい。

ということで、Visual Studio CodeからGit Extensionsを起動できるようにしたら、色々はかどったという話です。

# Git Extensions起動用のバッチファイルを作る
Git Extensions起動用のバッチファイルを作ります。引数が受け取れて、GUIプロセスが起動できれば何でもいいかとは思いますが、今回は気軽に使えるということでバッチファイルを選びました。

```bat:gite.bat
@"C:\Program Files (x86)\GitExtensions\GitExtensions.exe %*
```

ファイルをパスが通っているフォルダに保存します。自分は`C:\cmdtools`にコマンドライン向けのスクリプトを配置しているのでそこに置きました。

# Shell拡張をインストールする

Visual Studio Codeの拡張、Shellをインストールします。

# 任意のフォルダでGit Extensionsを起動する
ファイルを開いていて、ふとコミットやサブモジュールの操作などを行いたくなったときは、コマンドパレットを開き「>Shell Run Command at Active File Location」またはCtrl+Shift+Rを実行し、コマンドで`gite(先ほど作ったバッチファイル)`を選択します。

すると、Git Extensionsが、現在開いているファイルのあるフォルダで起動します。たったこれだけのことですが、たとえばサブモジュール内のファイルを開いている状態でこれをした場合はサブモジュールの操作を行えるため、使い勝手はよいと思います。

# 注意点

ただし、注意点として、このGit Extensionsは**Visual Studio Codeの子プロセスとして動作**します。そのため、**Visual Studio Code自体の操作を行ったり、ワークフォルダを切り替えるなどする前に、必ず終了**してください。プロセスが落とせなくなり、Visual Studio Codeの再起動が必要になる場合があります。
bash tip - ファイル名末尾に、そのファイルの最終更新日時を付加する

ファイルのバージョン管理は、バージョン管理ツールを使うのが正しい。とはいえ、そうはいかない事も多々あります。大人の事情であったり、子供っぽい事情であったり、理由は様々ですが。

そういう時によくやる手としては「ファイル名末尾に元ファイルである事を表す語尾を付けてコピーを作る」というのがあります。例えば…

```
$ mv file.txt file.txt.org
$ cp -p file.txt.org file.txt
```

とかいうヤツですね。ちょっと気を利かせたい時には .org ではなくてファイル更新日にします。

```
$ ls -l file.txt
$ mv file.txt file.txt.20160502
```

日に数回やる可能性があるなら時刻もくっつけたい。

```
$ ls -l file.txt
$ mv file.txt file.txt.20160502_2302
```

要求が細かくなると、人間の手作業では誤りの恐れがあります。うっかり日時を打ち間違う可能性が出てきますね。それを防ぐ為の一行野郎 one liner がこちら。

```
$ (read f; mv $f $f.`date -r $f +%Y%m%d_%H%M`) <<< file.txt
```

うっかりミス防止の他にも効能は色々。

- 自動化が楽。
- わかってない人への指示が楽。
- 疲れた人間の頭を使わなくて済むので楽。

注意点としては、ヒアストリングはbash独自の構文の模様。また```date```コマンドの```-r```オプションはGNU独自拡張のようです。その辺で引っかかる場合は修正が必要です。
CROSS2017実行委員会コアメンバー募集

**🔳　CROSSってなによ？**

こんにちは！
皆さんは、CROSSというイベントをご存知でしょうか？

![DSC07192.JPG](https://qiita-image-store.s3.amazonaws.com/0/53445/29e03ed5-f71d-8264-bc8e-5a1da28cf2b9.jpeg)


CROSSは、WEB・ITに携わる様々な人が一同に会し、職種や役職、世代を超えてひとつのテーマに沿って多くのセッションが同時に行われるイベントです。
参加者は毎回約1,000名！！
様々な勉強会の延長として実施されているイベントとしては、国内で最大級のものではないでしょうか。

2012年から毎年開催され、今年は9月8日に横浜で6回目の開催を予定しております！
CROSSはどこかの企業が運営しているのではなく、広く一般から集まった実行委員会で運営されています。
その実行委員の募集になります！



**🔳　メンバー募集に際して**

◯運営チーム
昨年までは、分業をしっかりするために、下記のようなチームに分けて運営をしておりました。

| チーム名　| 役割　　　　　 | 備考　　　　　 |
|:-------------|:------------|:------------|
| 事務局 　      | 定例会招集/議事取りまとめ | 全体をみるならここ |
| プログラム     | プログラムの取りまとめ | 構成検討/セッションオーナー調整 |
| 会場/受付       | 会場設備と受付フロー等検討 | オペレーション検討 |
| スポンサー |スポンサーの募集とクロージング | スポンサーを知ろう、説明資料作成 |
| プロモーション |　造作、WEBやTwitter、Facebookページの運営|WEB力/デザイン力があると素敵！|
| 会場ネットワーク　|会場ネットワークの確立ヒートマップ作成|CONBUチームと共創|

でも、このチーム体制では、分業が進みすぎていて他のチームが何をしているのかわからないという意見も多くあったので今年は、下記のようなチームにしたいと思っています。

|チーム名　　　　　| 役割　　　　　 | 備考　　　　　 |
|:-------------|:------------|:------------|
|事務局| 定例会招集/議事取りまとめ | 全体をみる |
|プログラム委員 | CROSSのコンテンツの構成をまとめ各チームにわかりやすく情報提供 | プログラム成立と魅力増加に関する全部 |
|開催委員 | そもそものイベントを成立させるために必要な対応のすべてを実行 | 会場やスポンサー、その他イベントなどに関すること全部 |


簡単にいえば、チームを中身チームと外身チームに分けた感じですね。
中身チームは今年の旬の開発や運用、成長や育成や採用、経営といったものを今年のテーマに沿った切り口で構成し、外身チームはそれらを効果的に見せ、参加しやすくするための仕組みを作っていくようなイメージです。

今年は、IoT/AI、VR/ドローン/フィンテック/分散型サービスなどが実際に利用されるようになり、大きな盛り上がりを見せている一方で、それらのテクノロジーが活かされる今までの市場や分野から、様々な提案が寄せられていると思っています。

ある意味で完成された世界に、最近の技術要素が入っていって新しい市場を作っていくそんな世界をみんなで見つめなおして、新しい発見ができればと思っています。

と、いうわけでみんなでCROSSをしませんか？！！

***
🔳CROSS２０１７実行委員会　開催スケジュール

基本的には、毎月第3水曜日に開催します。

　場所は各社持ち回りになっていますので、会場を貸してくださる方はぜひお願い致します。
　参加希望の方は、[こちら](http://goo.gl/forms/szRFcIHUpy)からご連絡ください。
　情報共有　Slack　および　Facebook　を利用しますので、招待を受けたら承諾してください。

🔳Facebook
https://www.facebook.com/engineersupportCROSS/
Azure PowerShellで仮想マシンV2を作成する (Sysprepしていない既存のVHD)

Sysprepされていない既存のVHDから仮想マシンV2を作成するサンプルスクリプトになります。

```ps1:
# コピーしたVHDから仮想マシンを作成する

$subscriptionId =  '[サブスクリプション名]'
$storageAccountName = '[ストレージアカウント名]'
$vhdUri = '[VHDが格納されているストレージURI https://xxxx.blob.core.windows.net/vhds/base.vhd]'

# ログイン
Login-AzureRmAccount

# サブスクリプション 確定
Select-AzureRmSubscription -SubscriptionId $subscriptionId

# ストレージアカウント 取得
$storageAccount = Get-AzureRmStorageAccount | ? StorageAccountName -EQ $storageAccountName
if(-not $storageAccount) {  
    throw "ストレージアカウント '$storageAccountName' が存在しません。"
}

$VerbosePreference = 'Continue'
$ErrorActionPreference = 'Stop'

$resourceGroupName = '[リソースグループ名]'
$location = $storageAccount.Location

$vmName = '[VM名]'
$vmSize = '[VMサイズ Standard_D1]'
$nicName = '[NetworkInterface名]'
$ipName = '[PublicIpAddress名]'
$vnetName = '[Virtual Network名]'
$diskName = '[OSディスク名]'

# Virtual Network 作成
Write-Verbose 'Creating Virtual Network'  
$vnetDef = New-AzureRmVirtualNetwork -ResourceGroupName $resourceGroupName -Location $location -Name $vnetName -AddressPrefix '10.0.0.0/16'
Write-Verbose 'Adding subnet to Virtual Network'  
$vnet = $vnetDef | Add-AzureRmVirtualNetworkSubnetConfig -Name 'Subnet-1' -AddressPrefix '10.0.0.0/24' | Set-AzureRmVirtualNetwork

# Virtual Network がすでに構築済みの場合はこちら
#Write-Verbose 'Get Existing Virtual Network'
#$vnet = Get-AzureRmVirtualNetwork -Name $vnetName -ResourceGroupName $resourceGroupName
#if(-not $vnet) {  
#    throw "Unable to find virtual network '$vnetName'. Cannot continue."
#}

# Public IP Address 作成
Write-Verbose 'Creating Public IP'  
$pip = New-AzureRmPublicIpAddress -ResourceGroupName $resourceGroupName -Location $location -Name $ipName -AllocationMethod Dynamic

# Network Interface 作成
Write-Verbose 'Creating NIC'  
$nic = New-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName -Location $location -Name $nicName -PublicIpAddressId $pip.Id -SubnetId $vnet.Subnets[0].Id 

# VM名とサイズの決定
Write-Verbose 'Creating VM Config'  
$vm = New-AzureRmVMConfig -VMName $vmName -VMSize $vmSize

# VMにNetwork Interfaceを関連付け
$vm = Add-AzureRmVMNetworkInterface -VM $vm -Id $nic.Id

# OSディスク設定
$vm = Set-AzureRmVMOSDisk -VM $vm -Name $diskName -VhdUri $vhdUri -CreateOption Attach -Windows

# VM 作成
Write-Verbose 'Creating VM...'  
$result = New-AzureRmVM -ResourceGroupName $resourceGroupName -Location $location -VM $vm

if($result.Status -eq 'OK') {  
    $result
    Write-Verbose ('仮想マシン ''{0}'' は正常に作成されました。' -f $vmName)
} else {
    Write-Error '仮想マシンは正常に作成されませんでした。'
}
```
Visual Studio Codeの「これはいい」とおもった拡張リスト(随時更新)

Visual Studio Codeを使ってて、「これはいいぞ」とおもった拡張をリストアップしていきます。

# 言語系

言語の強調、コンパイルツールなど

## [Twig](https://marketplace.visualstudio.com/items?itemName=whatwedo.twig)

PHPのテンプレートエンジンTwigの強調が行える拡張。拡張子はtwigに対応しています。

## [Easy LESS](https://marketplace.visualstudio.com/items?itemName=mrcrowl.easy-less)

AltCSSの1つ、LESSを保存時に自動コンパイルしてくれる拡張です。

# 汎用系

その他汎用的なツール

## [GitLens — Git supercharged \- Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens)

Git上のファイルを編集しているとき、現在行が最後にコミットされたときのコメントを行末に表示してくれるほか、サイドバーに現在開いているファイルおよび、行の更新履歴一覧を一覧できるGitLensバーを追加する拡張。

Git管理のフォルダを編集しているとすごく便利です。

## [npm](https://marketplace.visualstudio.com/items?itemName=fknop.vscode-npm)

npmコマンドを使えるようになる拡張。実行されるのはワークフォルダのルート。下記Shell拡張で代用できなくもないが、コマンドを全部覚えてない人はこれを使うと良さそう。

## [Shell](https://marketplace.visualstudio.com/items?itemName=bbenoist.shell)

ワークフォルダのルートをカレントディレクトリとした状態で任意のコマンドを実行できる拡張。インストーラやテストツール実行などのバッチファイルをルートフォルダに置いておくと捗ります。
ただし、コマンドプロンプトなどと違って入力補完は利かないので注意。

詳しくは紹介ページの動画を見ると分かりやすいです。

## [CodeBing](https://marketplace.visualstudio.com/items?itemName=SirTobi.code-bing)

名の通り任意の単語のBing検索ページを、関連付けられたブラウザで開く拡張機能。文字列を選択した状態だと、その単語をそのまま検索することもできます。
自分の場合言語の不明点など頻繁に検索することがあるので、入れておくとそこそこ便利。

同じような拡張はいくつかあるようですが、単語が選択した単語に限定されてしまう、ブラウザにEdgeを指定できないなどイマイチ使い勝手が良くないので、結局これに落ち着きました。
ヘルプを見る限り、別の検索エンジンで検索することも可能なようです。

## [Vscode Google Translate](https://marketplace.visualstudio.com/items?itemName=funkyremi.vscode-google-translate)

選択した文字列を任意の言語に翻訳する拡張。
オープンソースプロダクトなど英語でコメントやコミットログを書かねばならないときにとても便利

## [Open in GitHub, Bitbucket, Gitlab, VisualStudio\.com \! \- Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=ziyasal.vscode-open-in-github)

現在開いているプロジェクトをGithubやBitbucketで開くオプションコマンドを追加します。Issueなどワンクリックではアクセスできない場所を使っている場合、地味に便利。

## [Settings Sync \- Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=Shan.code-settings-sync)

Visual Studio Codeの基本設定や拡張などの設定をバックアップ・手持ちの複数PCで同期してくれる拡張。かなり便利です。

## [Windows Explorer Context Menu \- Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=electrotype.windows-explorer-context-menu)

ファイルエクスプローラのメニューから、Windowsのコンテキストメニューを開けるようにする拡張です。意外とここからしか使えないメニューがあったりするので、あると重宝します。
【メモ】XMLHttpRequestのイベントについて

**(2021/08/29 追記)**

既に fetch を使っても問題なくなっているので XMLHttpRequest の代わりにそちらを利用することをおすすめします。

https://developer.mozilla.org/ja/docs/Web/API/Fetch_API

----

# この記事について

XMLHttpRequest(以下、XHR)のイベントの仕様って、そういえばきちんと把握してないなと思ったので少し調べてみました
その結果をつらつらと書いていきます

# 通信の終了/成功or失敗の調べ方

本題のイベントに入る前におさらいです
後々必要になります

## readyState

`xhr.readyState`は以下のいずれかの値を持ちます

|値     |定数              |状態                              |
|-------|-----------------|---------------------------------|
|0	|UNSENT	          |XHRオブジェクトの作成直後              |
|1	|OPENED	          |`open()`メソッドの呼び出し後           |
|2	|HEADERS_RECEIVED |レスポンスヘッダの受信後               |
|3	|LOADING          |レスポンスボディを受信中（繰り返し実行される）|
|4	|DONE             |XHR通信の完了後                    |

`readyState`が4なら通信終了です

## status

レスポンスのHTTPステータスです
`readyState`が2以上の時アクセス可能で、4になった時に最終的な値が確定します
0なら通信に失敗、0以外なら通信に成功したことを表します
ただし、`status`が0以外であってもサーバーへのリクエストが成功したとは限りません(404, 500など)

# XHRのイベント

XHRが通信中に起こすイベントは以下の8個

- `onreadystatechange`
- `onloadstart`
- `onprogress`
- `onloadend`
- `onload`
- `onerror`
- `onabort`
- `ontimeout`

## onreadystatechange

もっとも古くから存在する(?)イベントです
`readyState`の値が更新されるたびに呼び出されます

## onloadstart

`open()`メソッドが呼ばれたタイミングで呼び出されます
つまり、下の二つは同じです

```js
xhr.onloadstart = function() {
  // do something
}
```

```js
xhr.onreadystatechange = function() {
  if(xhr.readyState === 1) {
    // do something
  }
}
```

## onprogress

レスポンスボディの受信中に繰り返し呼び出されます
つまり、下の二つは同じです

```js
xhr.progress = function() {
  // do something
}
```

```js
xhr.onreadystatechange = function() {
  if(xhr.readyState === 3) {
    // do something
  }
}
```

## onloadend

受信が終了した時に呼び出されます
`onloadend`は受信の成功or失敗に関わらず呼び出されるので、後述する`onload`と`onerror`を合わせたものだとも言えます
つまり、以下の3つは同じです

```js
xhr.onloadend = function() {
  // do something
}
```

```js
xhr.onload = function() {
  // do something
}
xhr.onerror = function() {
  // do something
}
```

```js
xhr.onreadystatechange = function() {
  if(xhr.readyState === 4) {
    // do something
  }
}
```

## onload

受信が成功した時に呼び出されます
つまり、以下の2つは同じです

```js
xhr.onload = function() {
  // do something
}
```

```js
xhr.onreadystatechange = function() {
  if(xhr.readyState === 4 && xhr.status !== 0) {
    // do something
  }
}
```

## onerror

受信が失敗した時に呼び出されます
つまり、以下の2つは同じです

```js
xhr.onerror = function() {
  // do something
}
```

```js
xhr.onreadystatechange = function() {
  if(xhr.readyState === 4 && xhr.status === 0) {
    // do something
  }
}
```

## onabort

通信が`abort()`メソッドによって中断された場合に呼び出されます
これは`onreadystatechange`では代用できません

## ontimeout

接続がタイムアウトした場合に呼び出されます
一応、`setTimeout`やらを使えば`readystatechange`で代用は可能ですが割愛します

# その他

以下の4つのイベントは同時に発火することがありません

- onload
- onerror
- onabort
- ontimeout

よって、**4つ全て指定しないと通信の終了を取りこぼす可能性があります**
ちなみに、それぞれのイベントでの`readyState`と`status`は以下のようになります

|イベント|readyState|status|
|---|---|---|
|onload|4|0以外(レスポンスによる)|
|onerror|4|0|
|onabort|通信の進行度による|0|
|ontimeout|通信の進行度による|0|

そもそも、`onerror`ってどんなときに発火するのかについてですが、例えばXHRのCross-Origin制約に引っかかった場合やネットワーク接続ができない場合など、サーバーとの接続ができなかった場合にerrorとなるようです

# まとめ

通信の終了を検知したい場合は, 上記の4つのイベントを見ていれば大丈夫なようです
プログレスバーを実装したい場合は、`onprogress`を使ってイベントオブジェクトから総バイト数と受信済みバイト数が取得可能なようなので、それで事足りそうです
phpredisの使い方まとめ


[phpreids](https://github.com/phpredis/phpredis)の使い方の日本語の情報が少なかったのでまとめます。

### 前準備

- Redisのインストール
- phpredisのインストール

環境によってインストールの方法が異なってくるのでここでは省きます。

```test.php
<?php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

echo $redis->ping();
```

+PONG と出力されればOK。

### Redisで扱えるデータ型

- String
- List
- Set
- Sorted Set
- Hash

#### String
文字列や数値など、Keyに対して1つに定まる値。

```test.php
<?php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

// hogeというkeyにhugaという値をセット
$redis->set('hoge', 'huga');

// 値を取得する
$value = $redis->get('hoge');

// 表示
echo $value; // huga
```


#### List
順番を持った値の集合

```test.php
<?php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

// lPushは先頭、rPushは末尾に値をpush
$redis->rPush('hoge', 'a');
$redis->rPush('hoge', 'b');
$redis->lPush('hoge', 'c');
$redis->lPush('hoge', 'd');

// 値をすべて取得する -1はすべて
$value = $redis->lRange('hoge', 0, -1);

// 表示
var_dump($value);

array(4) {
  [0] =>
  string(1) "d"
  [1] =>
  string(1) "c"
  [2] =>
  string(1) "a"
  [3] =>
  string(1) "b"
}
```


#### Set
順不同の値の集合。重複を許さない

```test.php
<?php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

// 値を追加
$redis->sAdd('hoge1' , '1');
$redis->sAdd('hoge1' , '2');
$redis->sAdd('hoge2' , '2');
$redis->sAdd('hoge2' , '3');
$redis->sAdd('hoge2' , '4');

// 和、積、差を取得する
$union = $redis->sUnion('hoge1', 'hoge2');
$inter = $redis->sInter('hoge1', 'hoge2');
$diff  = $redis->sDiff('hoge1', 'hoge2');

// 表示
var_dump($union);
var_dump($inter);
var_dump($diff);

/*
array(4) {
  [0] =>
  string(1) "1"
  [1] =>
  string(1) "2"
  [2] =>
  string(1) "3"
  [3] =>
  string(1) "4"
}
array(1) {
  [0] =>
  string(1) "2"
}
array(1) {
  [0] =>
  string(1) "1"
}
*/
```


#### Sorted Set
セット型と同様の特徴に加え、個々の値がスコアを持つ。

```test.php
<?php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

// スコアと値を追加
$redis->zAdd('hoge' , 10, 'a');
$redis->zAdd('hoge' , 20, 'b');
$redis->zAdd('hoge' , 30, 'c');
$redis->zAdd('hoge' , 40, 'd');
$redis->zAdd('hoge' , 50, 'e');
$redis->zAdd('hoge' , 60, 'f');

// ソート済のスコアを取得
$value = $redis->zRangeByScore('hoge', 0, 60);

// 表示
var_dump($value);

/*
array(6) {
  [0] =>
  string(1) "a"
  [1] =>
  string(1) "b"
  [2] =>
  string(1) "c"
  [3] =>
  string(1) "d"
  [4] =>
  string(1) "e"
  [5] =>
  string(1) "f"
}
*/
```


#### Hash
Fieldとvalueを1セットとする値の集合

```test.php
<?php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

// 値をセット
$redis->hSet('hoge', 'hoge1', 1);
$redis->hSet('hoge', 'hoge2', 2);
$redis->hSet('hoge', 'hoge3', 3);

// 値を取得
$value1 = $redis->hGet('hoge', 'hoge1');
$value2 = $redis->hGet('hoge', 'hoge2');
$all = $redis->hGetAll('hoge');

// 表示
var_dump($value1);
var_dump($value2);
var_dump($all);

/*
string(1) "1"
string(1) "2"
array(3) {
  'hoge1' =>
  string(1) "1"
  'hoge2' =>
  string(1) "2"
  'hoge3' =>
  string(1) "3"
}
*/
```
HTML,CSS勉強メモ#23 ～Bootstrap3.0入門終了～

本日の勉強。

##**進度**##
<dl>
<dt>Bootstrap3.0入門終了</dt>
<dd>18:カルーセルを使ってみよう</dd>
</dl>

##**メモ**##
まだ17の問題が残っていますが、ひとまず最後までやりました。
ちなみに実家のPCなのでCloud9を使って勉強しています。

###Bootstrap4のカルーセル
さて今回のカルーセルですが、画像が反映されなくてハマりました。
原因は間違えてBootstrap4をコピペしていたこと。
もちろん４でも動くのですが、こちらのテンプレートはこうなってるんですね。

```html

    <div class="carousel-item active">
      <img data-src="..." alt="First slide">
    </div>


```

これを

```html

    <div class="carousel-item active">
      <img src="..." alt="First slide">
    </div>

```
と、普通の`src`属性にしたところちゃんと反映されました。
`data-`とは独自データ属性で、既存の属性の中で適切なものがないときに自分で属性を作れるやつですが、
でもなんでこれで反映されなかったのでしょうか？
ちらっと調べたのですが、マークアップとJavaScriptはコードを明確に分けることが基本で、
そのためにマークアップの方にはコード制御のためのパラメーターや文字列情報のみを記入するとのこと。
そこで`data`属性を使ってJavaScriptで使われるパラメーターの情報を用意します。
ということは、JavaScriptの方でこの`data-src`の値が取得できていないということでしょうか？
まさかそんなこと・・・
ちょっと詳しく確認していないので原因は定かではありませんが、とりあえず`src`属性に直したら使えました。
もう少しちゃんと調べてみようと思います。

ちなみに、Bootstrap3の方はちゃんと間違えずにコピペしたら普通に使えました。
TypeScript で動的にプロパティを定義するライブラリに型をつける

Indexed DB の wrapper として [Dexie.js](https://github.com/dfahlander/Dexie.js) を使っています．

Dexie.js では次のようにしてデータベースを生成し，各テーブルにアクセスすることができます． (README.md より)

```js
//
// Declare Database
//
var db = new Dexie("FriendDatabase");
db.version(1).stores({
  friends: "++id,name,age"
});

//
// Manipulate and Query Database
//
db.friends.add({name: "Josephine", age: 21}).then(function() {
    return db.friends.where("age").below(25).toArray();
}).then(function (youngFriends) {
    alert ("My young friends: " + JSON.stringify(youngFriends));
}).catch(function (e) {
    alert ("Error: " + e);
});
```

僕は TypeScript を使って書いているのですが，1点問題があります．Dexie.js では `db.friends` のようにテーブルがデータベースオブジェクトのプロパティとして生えてくるのですが，TypeScript のコンパイラはもちろん `db.version(1).stores(...)` のスキーマ情報を見てそれを判断してくれません．結果として `friends` というプロパティは（静的に）無いよとエラーになります．

こういった動的にプロパティを生やすライブラリは JavaScript ではよくあると思うので，今回行った対処法をメモしておきます．

```ts
// スキーマの型を定義
interface Friend {
    id: number;
    name: string;
    age: number;
}

interface TypedDexie extends Dexie {
    friends: Dexie.Table<Friend, number>;
}

var db = new Dexie("FriendDatabase") as TypedDexie;

// `.friends` の型が `Dexie.Table<Friend, number>` だと TypeScript のコンパイラは知っているのでエラーにならない
db.friends.where("age").below(25).each(...);
```

インターフェースがクラスを継承しているのは不思議な感じがするかもしれませんが，これで `Dexie` というクラスに `friends` というプロパティがあるという追加の情報を付けることができます．

あとは `new Dexie` でインスタンスを生成するときにプロパティを付加した型 `TypedDexie` にキャストしてやります．親クラスから子インターフェースへの変換ですので，これは安全で問題なくキャストできます．また，インターフェースであってクラスではないので追加のオーバーヘッドも無いはずです．
超うす味のCSSフレームワーク『LightTaste』を作りました！

~~タイトル通り**超うす味CSSフレームワークを作りたいな！**って気持ちで書いています。~~

タイトル通り**超うす味CSSフレームワークを作りました！（5月3日）**。

自分でいうのもなんですが、かなり自由度高くて使いやすいです！
ぜひお試し有れ！（githubにstarつくとテンション上がります。気に入ったらよろしくお願いします！笑）

**LightTaste.css**
https://github.com/maru-3/LightTaste

------------

自分はRailsエンジニアでサーバー側を書く事が多いのですが、自分の趣味サービスを作る時などはがっつりデザインまでやるのでフロント側もよく触ります。

いつもはskeleton.cssを使って土台作りしてあとは自分でcssを書いて、サービス作りをしているんですが、**サイドバーとか作ってると12分割のgridが意外と嫌**だったり（僕だけ？）、**無駄に色とか付けないでよ！と**か、**listに装飾いらないよ！**とかそういう我がままのたぐいが生まれてきました。（実際めっちゃ使いやすいので、こんな風におもうのは自分だけかもしれない笑）

Skeleton.css
http://getskeleton.com/


もはや、初期化用のcssに**ちょっとだけかっこ良くするだけの超うす味な**CSSフレームワークがあったらいいなと僕は思いました。

## 僕がCSSフレームワークに求めるもの

僕がCSSフレームワークに求めるものは以下の２つです

 - 簡単にそれなりの見た目になること（layoutとかformとか）
 - 凝ろうと思えば**気持ちよく**作業出来る事

## 今流行のCSSフレームワークの現状

 『簡単にそれなりの見た目になる事』についてはすごい楽しいです

でも、やっぱり**ちょっと辛くなるのは、『凝ろうと思えば気持ちよく作業出来る事』のほう…**

## シンプルなCSSはもちろんある

skeleton.css
http://getskeleton.com/

minimal.css
http://minimalcss.com/

workless.css
http://workless.ikreativ.com/

kube.css
https://imperavi.com/kube/

skyblue.css
http://stanko.github.io/skyblue/

ただ、やはりちょっと味付けが濃いなーと思う

簡単なレイアウト、その他諸々がまあ見れるくらいの完成度に味付け出来るような超うす味CSSフレームワークを作りたい

**目的はひとつ!
自分のWEBサービス作成を楽にしたい…**

## 超うす味CSSフレームワーク『LightTaste.css』

**LightTaste.css**
https://github.com/maru-3/LightTaste


**お好みで味付け出来るCSSフレームワーク**を目指しています。

絶賛作成中
手探り進行中です笑

## 現在の進捗（5月2日開始 ~ 5月3日現在）

### css
- [x] Layouts
- [x] Positions
- [x] Forms
- [x] Links
- [x] Buttons
- [x] Lists
- [x] Margins
- [x] Paddings
- [x] Fonts

### sample page
- [x] grid
- [x] Forms
- [x] Buttons
- [x] Lists

## ダメな作り方やマナー違反等あったら教えてください！
Goの開発環境を10分で作る

* Mac OSX 10.11.4
* homebrewは使える前提

## Go本体のインストール
```
$ brew install go
```

## $GOPATH,$PATHの設定

(どこでもよい)

```
$ mkdir -p $HOME/go
```

`.bash_profile` `.zshrc` などに書く。

```
GOROOT=/usr/local/go
export GOROOT
GOPATH=$HOME/go
export GOPATH
export GO15VENDOREXPERIMENT=0
PATH=$PATH:$GOROOT/bin:$GOPATH/bin
```

```
$ source .bash_profile
```

## 確認
```
$ go version
go version go1.6.2 darwin/amd64
```

## go get してみる
```
$ go get -u github.com/tools/godep
$ godep version
godep v62 (darwin/amd64/go1.6.2)
```

実体が配置される場所

```
$ cd $GOPATH/src/github.com/tools/godep
```
windowsにkerasをインストールする

windowsにpython用の深層学習ライブラリであるkerasをインストールする方法です。
pythonのバージョンは2.7の場合です。(試したのは64bit環境です。)

##WinPythonのインストール
最新のWinPython2.7をダウンロード＆インストールします。
https://sourceforge.net/projects/winpython/files/WinPython_2.7/

##numpyとscipyのアップグレード
WinPythonには既にkerasがインストールされていますが、最新のKerasにアップグレードするために、まずnumpyとscipyをアップグレードします。ただし、pip install だとコンパイルが必要となり上手くいかないので、こちらからダウンロードしたwhlを利用します。

http://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy
http://www.lfd.uci.edu/~gohlke/pythonlibs/#scipy

WinPython Command Prompt.exeを開いてダウンロードしたwhlをインストールします。こんな感じ。
```
pip install numpy-1.11.0+mkl-cp27-cp27m-win_amd64.whl
pip install scipy-0.17.0-cp27-none-win_amd64.whl
```
##kerasのアップグレード
最後に、kerasをアップグレードします。Theanoもアップグレードされます。
```
pip install --upgrade keras
```
##実行できるか確認
kerasのexampleファイルを取ってきて実行してみます。
```
wget --no-check-certificate https://raw.githubusercontent.com/fchollet/keras/master/examples/mnist_mlp.py 
python mnist_mlp.py
```

問題なければ、Test accuracy:0.9856　などと出て終了します。
Docker for Macでlocalhostでアクセス可能になった

## Version 1.11.0-beta8まで

Docker for Mac のBeta版では、これまで下記のように `docker.local` でアクセスする必要がありました。

```
$ docker run -d redis:3.0.7-alpine
$ redis-cli -h docker.local
```

イケてない。。
`dokcer-machine+Virtualbox` 向けに作ってきたシェルスクリプトなどでは
`localhost` 向けが前提になっていて、資産が活用できませんでした。
ので、 docker-machine + Virtualboxのまま移行できず悶々とする日々。。

## docker-machine + Virtualbox の問題点
docker toolbox をダウンロード、インストールすればすぐ使える、この組み合わせはとても手軽でよいのですが、
いくつか不満点がありました。

* eval "$(docker-machine env default)" が必要
* 動作がちょっと重い
* ポートフォワーディングの設定が必要

特にポートフォワーディング設定については、忘れたころにハマリポイントになっていて、地味にコストでした。
設定が正しければredisへは以下でアクセスできます。

```
$ redis-cli
```

docker for macでも同じようにアクセスしたいのだけど、技術力不足のためできず。。

## Version 1.11.0-beta9から

docker for macの `Version 1.11.0-beta9` でVPNモードがデフォルトになりました。
これにより、以下の様に変更されます。

```
- docker.local will no longer work in Beta 9 or later
- When you expose a port, it will be available at localhost
```

(意訳)

```
- docker.localはそのうち消えるよ
- exposeしたポートはlocalhostでアクセスできるよ
```

つまり、redisへのアクセスはこれだけになりました。

```
$ redis-cli
```

こ！れ！は！

## docker-machine + VirtulaBox 資産を活用できる

今回の変更で、これまでの資産をそのまま流用できることになったので、docker for macへ移行します。
Virtualboxさん、今まで大変お世話になりました。
Rails | ハッシュのキーを全てシンボルに変える ( symbolized_keys / deep_symbolize_keys  )

表題のとおり。

```rb
{ 'a' => 1, 'b' => 2, 'c' => 3 }.symbolize_keys

# => {:a=>1, :b=>2, :c=>3}
```

# ハッシュの階層が深い時

`deep_symbolize_keys` なら、階層を問わず、ぜんぶシンボルに変えてくれる。（ Rails4 ）

```rb
{ 'a' => 1, 'b' => 2, 'c' => { 'd' => 3 } }.deep_symbolize_keys

# => {:a=>1, :b=>2, :c=>{:d=>3}}
```

## すごいぞ deep_symbolize_keys

`deep_symbolize_keys` なら、たとえば途中に配列があっても気にしない。

```rb
{'a' => 1, 'b' => 2, 'c' => [ {'d' => [ { 'e' => 3 } ] } ] }.deep_symbolize_keys

# => {:a=>1, :b=>2, :c=>[{:d=>[{:e=>3}]}]}
```

# 補足

- 破壊的メソッドもある。 ( `symbolize_keys` / `deep_symbolize_keys!` )
- 「Rails / すべて / シンボルに」でググってもヒットしなかったので投稿。

# 環境

- Rails 4.2.6



<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# メンター受付


https://menta.work/user/5694

<!-- Update From Qiita API -->
Rails | ハッシュのキーを全てシンボルから文字列に変える ( stringify_keys / deep_stringify_keys  )

表題のとおり。

```rb
{ a: 1, b: 2, c: 3 }.stringify_keys

# => {"a"=>1, "b"=>2, "c"=>3}
```

# ハッシュの階層が深い時

`deep_stringify_keys` なら、階層を問わず、ぜんぶシンボルに変えてくれる。（ Rails4 ）

```rb
{ a: 1, b: 2, c: { d: 3 } }.deep_stringify_keys

# => {"a"=>1, "b"=>2, "c"=>{"d"=>3}}
```

## すごいぞ deep_stringify_keys

`deep_stringify_keys` なら、たとえば途中に配列があっても気にしない。

```rb
{ a:1, b: 2, c: [ { d: [ { e:3 } ] } ] }.deep_stringify_keys

# => {"a"=>1, "b"=>2, "c"=>[{"d"=>[{"e"=>3}]}]}
```

# 補足

- 破壊的メソッドもある。 ( `stringify_keys!` / `deep_stringify_keys!` )
- stringfy ではなく stringify 。タイポに注意。
- 「Rails / すべて / シンボル / 文字列に」でググってもヒットしなかったので投稿。

# 環境

- Rails 4.2.6



<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# メンター受付


https://menta.work/user/5694

<!-- Update From Qiita API -->
Android用CI環境をBitriseで構築

もともと社内ではJenkinsによるCI環境を作成していたのだが、HockeyAPPと連携したり最新のAndroidSDKに対応しつつ
古いSDKと共存したりとあんまりLinuxに明るくない私にとって要件が厳しくなりだしたので、アプリ用のCI環境を
提供しているBitriseに乗り換えてみた。

# 前提条件
- gradlewファイルによるGradleビルドができること。

Bitriseに限らずCI環境を作成する上では割と重要だと思う。ローカル環境のAndroidStudioでは無視しているエラーが
あったりするとビルドで失敗するので、適宜ソースを修正する必要がある。


- Bitbucketで管理されていること。

GitHubでもできるはず。私はBitBucket上のdevelopブランチにPushされたタイミングでビルドしてほしかったので、
そのやり方も書きます。

- HockeyAPPでアップする先があること。

HockeyAPPと連携する必要がないのなら必要ないです。

# ビルドするまでの準備

１. Bitriseにログインし【ADD NEW APP】をクリック

２. 【Connect your repository】で対象のレポジトリを選択

３. 【We generated an SSH keypair for you!】で対象レポジトリにSSH接続用の公開鍵を登録

GitHubなら【Auto-add This Key】でいけるかもしれないが、プライベートレポジトリのBitBucketではエラーになるので、
手動で公開鍵を登録する必要がある。
BitBucketのWebサイトにログインし対象レポジトリのSettings ⇒ デプロイ鍵の順で遷移する画面で登録する。
公開鍵はBitrise上に表示される【ssh-rsa】から始まる文字の羅列を登録する。
BitBucketでの公開鍵登録が終わったら、Bitriseに戻って、【I added the Public Key】をクリック。

４. Specify your default branchでデフォルトブランチを登録

developを対象としたいので、developでよいはず。

５. テスト用のビルドが始まるのでしばらく待機

ちゃんとAndroid Studio に対応しているプロジェクトなら、ここはすんなり突破できるが、
ここでエラーが出るようなら色々修正する必要がある。

６. Select Gradle Fileで本プロジェクトのbuild.gradleを選択。

ちゃんとAndroid Studio に対応しているプロジェクトならこの選択肢が出る。ここで出ないプロジェクトはいったん構築した後に色々手を加えてやる必要ある。

７. Select gradle task でassembleDevelopを選択。

テスト用のアプリを作成したいので、assembleDevelopを選択。
ちゃんとAndroid Studio に対応しているプロジェクトならこの選択肢が出る。ここで出ないプロジェクトはいったん構築した後に色々手を加えてやる必要ある。

８. Webhook setupはスキップ

あとで、設定できる。
ここまで進めば、準備が整うはず。

# Tips

## コンパイルに必要なAndroidSDKがなくてビルドできない。
いったん準備を終えたら、まず、WorkFlowタブを選択し、【MANAGE WORKFLOWS】を選択し、WorkflowEditorに遷移する。
Bitrise上で動作するワークフローをカスタマイズできるので、ビルドが始める前に
android update sdk　コマンドで必要なアドオンをインストールすればよい。

コマンドの登録の仕方は各ステップの間にある【+】を押すとその間に登録できる。
下記のステップを選択する。

![bitrise_script.png](https://qiita-image-store.s3.amazonaws.com/0/115635/46b378ab-9335-cf01-67bb-3b9cb861a5bc.png)

登録したら、下記の記述はScript contentに記述する。
--filter に指定するパラメータは【android list sdk --all -e】で取得できる。

```sh
#!/bin/bash
echo y | android update sdk --no-ui --all --filter addon-google_apis-google-23,addon-google_apis_x86-google-19,android-16
```

## BitBucketにソースがPushされたときにビルドしてほしい。
CodeタブのWEBHOOKS欄でBitBucketを選択すると表示されるURLをBitBucket側に登録すればよい。
BitBucketのWebサイトで対象レポジトリのSettings ⇒ Webhooksの順で遷移する画面で登録する。

ちなみにこれだけをやると、全てのブランチに対して、Pushされたときに勝手にビルドしてしまうので、
対象ブランチをdevelopに絞る。
WorkFlowEditorでTriggersを選択すると、デフォルトでは対象パターンがアスタリスク、対象ワークフローがprimaryのトリガーが
登録されているのが見えるので、対象パターンがdevelop、対象ワークフローがprimaryのトリガーを作成し、
既存のトリガーは削除する。

## ビルドしたアプリをHockeyAPPにアップロードしたい。

WorkFlowEditorで最後のステップとしてHockeyAPPへのアップロードをするステップを追加する。
![bitrise_hockeyapp.png](https://qiita-image-store.s3.amazonaws.com/0/115635/b08c7e89-94e2-379f-b108-e2b0d3382a52.png)

以下の項目に対して設定する。

- mapping.txt file path

【$BITRISE_MAPPING_PATH】でよいはず。

- API Token

Hockey APPのAccount Settings画面⇒API Token 画面で作成する。
APP IDではないので、注意。

- HockeyApp: App ID

HockeyAPPのアプリごとの画面にあるAPP ID（Secretではない方）を登録する。
JSON APIをカジュアルにテストするやつ

JSONを吐くWeb APIを書く毎日を過ごす中で、テストをしたい
→Controllerのテスト書いたり（サボったり）する
→web serverとかポートとか諸々含めて導通してるのかもテストしたい
→Postmanで叩いたりする
→あるエンドポイントのResponseからある値をコピって次のエンドポイントのパラメータにペーストしてとかめんどい

のでそのへんをカジュアルにテストしたくてツールをつくった

ソースはこちら
https://github.com/maruware/endo

## 使い方

```bash
$ gem install endo
```

してインストール

最小限だと

```rb:sample_project/endo/sample.rb
base_url 'http://localhost:3000'

get '/articles'

get '/articles/:article_id' do
  param :article_id do
    from :get, '/articles', -> { self[0][:id] }
  end
end

post '/articles' do
  param 'article[title]', 'hello'
  param 'article[content]', 'Hello, world!'
end

get '/articles/:article_id' do
  param :article_id do
    from :post, '/articles.json', -> { self[:id] }
  end
end
```

みたいにDSLで書いてendoコマンドを実行すると

```bash
sample_project $ endo
🍺 GET /articles [256ms]
🍺 GET /articles/1 [25ms]
🍺 POST /articles[24ms]
🍺 GET /articles/56 [19ms]
```

のようにシナリオ的にAPIを叩くことができる。


expectも微妙に対応していて

```rb
get '/articles/:article_id' do
  param :article_id do
    from :post, '/articles', -> { self[:id] }
  end

  expect(header: 'Content-Type').to eq 'application/json'
  expect(body: -> { self[:title] }).to eq 'hello'
end
```

とか書くと

```bash
sample_project $ endo
🍺 GET /articles [19ms]
🍺 POST /articles [11ms]
👮 GET /articles/2 [expected: "application/json" actual: "application/json; charset=utf-8"]
```

と表示される。割と便利。

その他

* GET, POST, PATCH, PUT, DELETEに対応してる
* Basic認証に対応してる

## TODO

* rubyわからない人には軽くつらい記法なのでなんとかしたい
* expectはやりすぎないレベルでもうちょっと充実させたい
PHPのSESSION管理はRedisではなくRedis Clusterを使いたいという方にだけこっそり教えます



はい。。大げさなタイトルですみません。
PHPのSESSION管理でRedis Clusterを指定したい場合の方法です。

環境はこちら。
redis 3.0.5、phpredis、apache 2.2.15
# Redis Cluster を指定する

phpで直接指定するにはこんな感じ。

```:php
ini_set('session.save_handler', 'rediscluster');
ini_set('session.save_path', 'seed[]=192.168.1.100:6379&seed[]=192.168.1.110:6379&seed[]=192.168.1.120:6379&timeout=3&read_timeout=3&failover=error');
```

apacheのextensionに書くにはこんな感じ。

```redis.ini:
extension = redis.so
session.save_handler = rediscluster
session.save_path = 'seed[]=192.168.1.100:6379&seed[]=192.168.1.110:6379&seed[]=192.168.1.120:6379&timeout=3&read_timeout=3&failover=error'
```

# (おまけ) Redis を指定する

```:php
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://host1:6379, tcp://host2:6379?timeout=2.5, tcp://host3:6379');
```

```redis.ini:
extension = redis.so
session.save_handler = redis
session.save_path = "tcp://host1:6379, tcp://host2:6379?timeout=2.5, tcp://host3:6379"
```

ちなみにですが、Redis ClusterにRedisとしてPHP Sessionを指定すると下記のようにエラーが出ます。

```
[06-Apr-2016 16:48:04 Asia/Tokyo] PHP Warning:  Unknown: Failed to write session data (redis). Please verify that the current setting of session.save_path is correct (tcp://127.0.0.1:7001,127.0.0.1:7002,127.0.0.1:7003
```



## 参考URL
https://github.com/phpredis/phpredis/issues/620
https://github.com/phpredis/phpredis/issues/664
MySQL, postgreSQL, SQLiteへのSQLアクセスを5分でAPI化するPHPアプリケーションを作ってみた

MySQL, postgreSQL, SQLiteへのSQLアクセスを簡単にAPI経由でできるようにするPHPアプリケーションを作ったので、公開してみました。
https://github.com/harasho2016/simple-API-Maker

このアプリケーションをサーバーに設置して、設定ファイルにDBへのアクセス情報を設定すれば、SelectとかDeleteとかInsertとかUpdateとかそういうよくある操作であれば、特に何の設定もなくAPI経由で操作できるようになります。

たぶん似たようなものがあるかもしれないですが、とりあえず試しで作ってみました。使っていただけると幸いです。あと改良点とか似たもの知っているよとかいう人がいれば、どんどん指摘してくれると嬉しいです。  

Simple API Maker
https://github.com/harasho2016/simple-API-Maker


## A). 目的  
#### DBへの負荷軽減/高速化  
- 想定①　アプリケーションレベルでゴリゴリ実装  
- 想定②　Squid、リバースプロキシと併用  

#### 開発速度の向上  
- SPA開発における高速開発化(javascriptからまるでDBを直接操作できるかのように)  

#### 車輪の再開発(再発明)を防ぐ  
- データのCRUDを行うだけの単純なAPIなら、これ一つで十分としたい

## B). 設定方法  
#### 0. 前提条件  
	a. MySQL/PostgreSQL/SQLiteが入っていること
	b. DB,TABLEが存在していること

#### 1. ドキュメントルートに設置
	e.g /var/www/html
  
#### 2. DB接続先を記述
	設定ファイル置き場所: ./sys/var_{pf_type}.php
	※ pf_typeは./sys_preference.iniに記述
	設定箇所: DBの接続先, UserId, Pass
	
#### 3. 設定完了！
	使い方は、下記の「使い方」参考にしてください


## C). 使い方  
#### 呼び出し方  
	/{VersionInfo}/{DBName}/{TableName}?{columnName}=val&set_{columnName}=val&{FunctionName}=val  

#### Version Info  
	- 定義されていればどんな値でも可能  
	- e.g. v0.1~v999.99  

#### DBName  
	- 設定ファイル(var.php)に記述している値を優先  
		- その場合、URLにはどんな値を埋め込んでも良い  
	- 記述がない場合は、URLに埋め込まれている値を参照する  

#### TableName  
	- DBに存在するテーブル名  

#### QueryMethod(All)  
	- MethodName = Select, Insert, Update, Delete  
		-　メソッド名  
	- {columnName}  
		if SELECT, UPDATE, DELETE  
			- "Where" Selecter  
		else if insert  
			- "Insert" Target  

#### QueryMethod(only UPDATE Method)  
	- set_{columnName}  
		- "UPDATE(SET)" Target  

#### QueryMethod(only SELECT Method)  
	- numCountBool=true, false(default)  
		- trueの場合Select count(*) from {tableName}  
		- defaultはfalse  
	- orderBy=RAND, DESC, ASC  
		- ソート順  
		- DESCとASCを指定した場合はorderByTarget={columnName}を指定する必要アリ  
		- defaultは無指定  
	- limit=1  
		- 返却数  
		- 無指定の場合は50が  


## D). 値例  
#### SELECT  
	http://127.0.0.1/{VersionInfo}/{DBName}/{TableName}  
	=> SELECT * FROM DBName.TableName LIMIT 50  
	http://127.0.0.1/{VersionInfo}/{DBName}/{TableName}?{colName1}=val1&{colName2}=val2&OrderBy=DESC&OrderByTarget={colName1}&MethodName=SELECT&qm_limit=15  
	=> SELECT * FROM DBName.TableName WHERE {colName1}=val1 AND {colName2}=val2 Order by {colName1} DESC LIMIT 15  

#### INSERT  
	http://127.0.0.1/{VersionInfo}/{DBName}/{TableName}?qm_methodName=INSERT&{colName1}=val1&{colName2}=val2  
	=> INSERT DBName.TableName (colName1, colName2) VALUE('val1', 'val2');  

#### UPDATE  
	http://127.0.0.1/{VersionInfo}/{DBName}/{TableName}?{colName1}=val1&{colName2}=val2&methodName=UPDATE&set_{colName1}=val3  
	=> UPDATE DBName.TableName SET  {colName1}=val3  WHERE {colName1}=val1 AND {colName2}=val2 LIMIT 10  

#### DELETE  
	http://127.0.0.1/{VersionInfo}/{DBName}/{TableName}?{colName1}=val1&MethodName=DELETE  
	=> DELETE FROM DBName.TableName WHERE {colName1}=val1;
CentOS7を仮想マシン上にインストール (DBの構築準備)

画像認識タスクや
DeepLearningにデータは多いに越したことがありません。
DB上に画像データを保管しておきたいので
環境構築の為にCentOS7を仮想マシン上にインストールします。[^1]
[^1]:



申し訳ありませんが設定を自分の頭に残す事がメイン目的なので
手順の説明として丁寧とは言えません。
興味持ってくれる人の為になればいいと思います。

環境:MacMini 2011  Vsphere ESXi 5.1
仮想マシン：CentOS 7

CentOSのISOイメージは下記の公式ページのMirrorリストから選択します。
DVDの64bit版イメージを選びました。

[CentOS公式ページ：www.centos.org](http://http://isoredirect.centos.org/centos/7/isos/x86_64/CentOS-7-x86_64-DVD-1511.iso)


1.VSphere ClientからESXiに接続し
ダウンロードしたISOイメージをESXiのデータストアにアップロードしてください。

2.仮想マシンを作成
![DB4.png](https://qiita-image-store.s3.amazonaws.com/0/104856/98fcec55-9475-119a-ad4c-1ff55cf653dd.png)

3.設定は下記の通り
![VB7.png](https://qiita-image-store.s3.amazonaws.com/0/104856/f5c2e53c-ffa6-5a8e-74a5-1b6cb80e7335.png)

4.仮想マシン作成後　仮想マシンの設定から

->CD/DVDドライブ
->デバイスタイプ->データストアISOファイルにチェック
->参照から上記手順でアップロードしたCentOS7 ISOイメージを選択
->起動時に接続をチェック->OK押す
->仮想マシンの起動
でVM上でインストーラーが起動します。
![Cent_Install1.png](https://qiita-image-store.s3.amazonaws.com/0/104856/eb3bc23a-e269-1d2a-e039-83d6b93d7522.png)

5.流れどおりにインストールを進めます。
言語の設定をした後
インストールパーティションを選択[^2]

![Cent_Install3.png](https://qiita-image-store.s3.amazonaws.com/0/104856/62a9f5a1-d755-4140-33fc-c3032603eaa3.png)

6.インストールするパッケージを選択します[^2]
[^2]:
![Cent_Install4.png](https://qiita-image-store.s3.amazonaws.com/0/104856/523fd930-14b2-880c-505e-43ec9267a5dc.png)

7.今回はDB系に必要と思われるパッケージ&個人的に挙動を確認しておきたいものを導入しました
![Cent_Install5.png](https://qiita-image-store.s3.amazonaws.com/0/104856/21174fdc-6899-4f8c-5c2c-4cfbcc702827.png)

8.rootパスワードとユーザー作成はインストール時に
行いました。


9.再起動指示後に再起動実施
ログイン画面で出てきてログインできれば
仮想マシンへのインストールは完了
![Cent_Install6.png](https://qiita-image-store.s3.amazonaws.com/0/104856/2e23fcce-d2cb-1979-9b2d-b82c8f8250ae.png)




脚注：
1.私の自宅の仮想化環境はMacMini上にインストールしたESXi 5.1となります。
公式にはサポートされていないマシンなのでやり方はここを参考にしました。
http://www.virtuallyghetto.com/apple(英語)




2.上記の様にESXi5.1だと仮想マシンコンソールの画面の解像度がおかしくなる場合がある様です。
その場合は下記の回答を参考に解像度を設定して下さい。
https://communities.vmware.com/thread/462600?start=0&tstart=0

>svga.maxWidth = 800
>svga.maxHeight = 600
>数字は画面のサイズです。
 
>VMを右クリックして
>「設定の編集」→ 「オプション」タブ → 「詳細」配下>の「全般」で「構成パラメータ」を開き、
>「行の追加」で上記2つを入力します。
play framework で hivemall

play frameworkからhivemall呼び出して使うのどうすればいいかいろいろ調べたのでメモ。

```build.sbt
resolvers += "Spark Packages Repo" at "http://dl.bintray.com/spark-packages/maven"

libraryDependencies += "maropu" % "hivemall-spark" % "0.0.6"
```

を追加。

そのあと、使うControllerとかで

```HogeControllers.scala
import org.apache.spark.sql.hive.HivemallOps._
import org.apache.spark.sql.hive.HivemallUtils
import org.apache.spark.sql.hive.HivemallUtils._
```

ここらへん書いて試してみて、読み込まれるようになってた。

超手探り…。
javascript print part of window(iframe)

```html
<!DOCTYPE html>
<html>
<script src="http://code.jquery.com/jquery-1.7.js"></script>
<body>

<p>Click the button to change the location of the first iframe element (index 0).</p>

<button onclick="myFunction()">Try it</button>
<br><br>

<iframe src="http://www.w3schools.com" style="display: none;"></iframe>
<iframe src="http://www.w3schools.com"></iframe>

<script>
function myFunction() {
    window.frames[0].document.body.innerHTML = "<h1>lallalala</h1>"
    window.frames[0].print();
}
</script>

</body>
</html>

```
ノートPCにVagrant、Docker環境を構築してみる。

ノートPCにVagrant、Dockerの環境を構築してみる。
過去の投稿記事をなぞって構築。
2016/5/2 実施時点で、各バージョンは以下の通り。

| OS | Vagrant | VirtualBox | Docker |
|:---|:---|:---|:---|
| Windows7 Professional バージョン 6.1 | 1.8.1 | 5.0.20 | 1.11.1 |


# 1. [ VagrantとDockerについて名前しか知らなかったので試した ](http://qiita.com/hidekuro/items/fc12344d36d996198e96)
 - [x] VirtualBoxのインストール
 - [x] Vagrantのインストール
 - [x] Vagrantの起動/停止方法

[注意] : vagrant ssh しても、sshコマンドがインストールされていない場合はログイン不可。2. のSSHログイン方法を実施。

# 2. [ Windows上でVirtualBox+Vagrant+CentOSによる仮想環境構築 ](http://qiita.com/hiroyasu55/items/11a4c996b0c62450940f)
 - [x] Vagrant初期設定(IPアドレス設定)
 - [x] TeraTerm

# 3.[ ドットインストール Vagrant入門 ](http://dotinstall.com/lessons/basic_vagrant)
 - [x] #1～#13の動画を参考に。
Raspberry pi 3のセットアップメモ

インストール完了後の作業をメモ程度に．．．

# 無線LANアクセスの設定をする
```shell-session
# vi /etc/wpa_supplicant/wpa_supplicant.conf
... 最後尾に追加する
network={
        ssid="SSID名"
        scan_ssid=1  # ステルスAPに接続する
        key_mgmt=WPA-PSK
        proto=WPA2
        pairwise=CCMP TKIP
        group=CCMP TKIP
        psk="アクセスキー"
}
```

# 無線LANに固定IPアドレスを設定する
```shell-session
# vi /etc/dhcpcd.conf
... 最後尾に追加
interface wlan0
static ip_address=192.168.1.20/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1
```

# 公開鍵認証にする
## 鍵ペアを作る
macでの例

```shell-session
% ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/userName/.ssh/id_rsa): "ENTER(鍵ペアの生成場所を変えるときはパスを入力）"
Enter passphrase (empty for no passphrase): "パスフレーズ"
Enter same passphrase again: "パスフレーズの再入力"
Your identification has been saved in /Users/userName/.ssh/id_rsa.
Your public key has been saved in /Users/userName/.ssh/id_rsa.pub.
...略
```

指定したパスに鍵ペア「id_rsa」「id_rsa.pub」ができる。

## 公開鍵をraspberry piに転送する
scpを使って「id_rsa.pub」をraspberry piのログイン対象ユーザホームディレクトリ配下に転送する。 

```shell-session
% cd ~/.ssh
% scp ./id_rsa.pub userName@192.168.1.20:
```

## rasberry piでssh設定をする
ログイン対象ユーザで公開鍵を設定する。

```shell-session
$ cd ~/
$ ls
id_rsa.pub
$ mkdir .ssh
$ mv id_rsa.pub .ssh/authorized_keys
$ chmod 700 .ssh/
$ chmod 600 .ssh/authorized_keys
```

## sshdの設定
sshdの設定を修正してサービスを再起動する

```shell-session
$ sudo vi /etc/ssh/sshd_config
...以下の設定を探し、修正する
PermitRootLogin no
RSAAuthentication    yes
PubkeyAuthentication yes
AuthorizedKeysFile   %h/.ssh/authorized_keys
PasswordAuthentication no

$ sudo /etc/init.d/ssh restart
```
※ 念のため、今開いているsshコンソールはログアウトせずに置く

## sshクライアント側の設定
macの~/.ssh/configを設定

```shell-session
% vi ~/.ssh/config
... raspiのセクションを追加する
Host raspi
HostName  192.168.1.20
Port      22
User      userName
IdentityFile ~/.ssh/id_rsa
```

## loginの確認

```shell-session
% ssh raspi
Last login: Mon May  2 09:32:45 2016 from 192.168.1.11
userName@hostName:~ $
```
Cakephp 2系 php5系 auth認証(twitter、facebook)

cakephp のauth認証 (Twitter、Facebook)でのログインのサンプルをgithubにあげました。
以前作成したものですが、意外と検索してもいいサンプル見つけづらいので誰かの助けになりますと幸いです。

https://github.com/kuboshizuma/auth-login-for-cakephp

以下、READMEを転載します。以下の設定だけでサンプルを動かすことが出来ます。（php5系)

# 初期設定

## databaseの設定
app/Config/database.phpを設定する。
app/Config/database.php.default.phpをコピーして、database.phpを作成する。
その後、自分の環境に合わせて設定する。

## core.phpの設定
app/Config/core.phpを設定する。
app/Config/core.php.defaultをコピーして、core.phpを作成する。

## facebookの設定
app/Config/facebookConfig.phpを作成する。(適宜、値は用意）

```php:facebookConfig.php
<?php
$config['facebookId'] = '9348594754389823423';
$config['facebookSecret'] = 'ewf9v4ijfi943if9ei023ie';
$config['callback'] = 'http://dev.login.com/facebook/fb_callback';
?>
```

## twitterの設定
app/Config/core.phpの最下部に下記を記述。(適宜、値は用意)

```
/*Twitter-login設定*/
define('CONSUMER_KEY', 'fjkejfowjedsajfaskdjf');
define('CONSUMER_SECRET', 'sdfkajsdfviojdifoejwkdsjdk');
define('OAUTH_CALLBACK', 'http://dev.login.com/twitter/tw_callback');
```

## Debug.kitの設定
直下にpluginsを作成して「DebugKit」フォルダを作成する。

下記URLからDebugKitをダウンロード
https://github.com/cakephp/debug_kit/tree/2.2

## Virtual Hostの設定
### 1. httpd.confの編集
Virtual Hostの設定を可能にするため以下のコメントアウトをはずす。
/Applications/MAMP/conf/apache/httpd.conf

(変更前)

```
# Virtual hosts
# Include /Applications/MAMP/conf/apache/extra/httpd-vhosts.conf
```

(変更後)

```
# Virtual hosts
Include /Applications/MAMP/conf/apache/extra/httpd-vhosts.conf
```

### 2. httpd-vhosts.confの編集
バーチャルホストのドメインやポートを指定するために、/Applications/MAMP/conf/apache/extra/httpd-vhosts.confに追記。

```
<VirtualHost *:80>
    DocumentRoot "/Applications/MAMP/htdocs/login"
    ServerName dev.idearoom.com
    ErrorLog "logs/dev.login.com-error_log"
    CustomLog "logs/dev.login.com-access_log" common
</VirtualHost>
```

### 3. hotsの編集
バーチャルホストを有効にするために、/etc/hostsに以下を記述。

```
127.0.0.1 dev.login.com
```

### 4. MAMPでサーバーを再起動
再起動後、
http://dev.login.com
にアクセス可能になる。
Ubuntu14.04 + InfiniBand で MPI を動かす

ipoib で動かします
# apt で入れるパッケージ
```
apt install opensm libmlx4-1 openmpi-bin libopenmpi-dev
```

# 設定

/etc/modules

```
lp
rtc
mlx4_ib
ib_umad
ib_uverbs
ib_ipoib
```

/etc/security/limits.conf

```
* soft memlock unlimited
* hard memlock unlimited
```

子ノードに親ノードのssh公開鍵を追加しログインできるようにする

終
Youtubeで360度ライブストリーミングをしてライブVR体験をする方法

　Youtubeが360度のライブストリーミングに対応したので、試しにTHETA Sを使って配信して、ライブVR体験をしてみたメモです。

# 必要なもの
・THETA S（360度動画が撮影可能なカメラ）
・ハイスペックなPC（高性能なビデオカードとUSB帯域が大きいPCが必要）
・GOOGLE CARDBOARD（スマホ差し込み型VRゴーグル）とスマホ
https://www.google.com/get/cardboard/

# 設定
## 1.ライブストリーミング用アプリのインストール
・THETA公式サイトから『ライブストリーミング用アプリ』をダウンロードしてPCにインストールします。360度カメラで撮ると全天球映像（球体の形をした映像）になりますが、これをリアルタイムで平面映像に変換してくれます。
https://theta360.com/ja/support/download/
![001.png](https://qiita-image-store.s3.amazonaws.com/0/61168/4c8c131d-a58c-1bb4-9640-427bcea9fc26.png)
・THETAの電源を切った状態で、PCにUSBで接続します。THETAをPCに『登録』します。
![004.png](https://qiita-image-store.s3.amazonaws.com/0/61168/73960160-123f-c70d-bdf5-2fad2694f488.png)


## 2.THETAをライブストリーミングモードで起動
・THETAとPCをUSB接続したままの場合は外します。
・THETAの『電源ボタン』と『撮影モードボタン』を同時押しして、『ライブストリーミングモード』で起動します。『LIVE』という文字が光ります。
・THETAとPCをUSBで接続します。

## 3.Flash Live Media Encoder（FLME）のインストール
・Youtubeでライブ配信するためのソフトをPCにインストールします。
http://www.adobe.com/jp/products/flash-media-encoder.html
・インストールしたらFLMEを起動して、Video設定のDeviceのところで『THETA UVC Blender』を選びます。
　※ここで『status:0x800705AA』というエラーが出て映像が画面に出てこない場合は、PCを一度再起動してください。それでも同じエラーになる場合はPCのスペックが足りてない可能性があります（うちで使っているかなりスペックの高いゲーミングノートPCで映像が出なくて、デスクトップ型の最新世代のコアを積んだマシンだと映像が出てきたので、かなりのハイスペックマシンが必要の模様）。
![007.png](https://qiita-image-store.s3.amazonaws.com/0/61168/816584df-d5c8-d6d6-8312-60934b515a67.png)



## 4.Youtubeでライブストリーミング
・Youtubeのクリエイターツールにある「ライブストリーミング」から、「新しいライブイベント」を作成して、「詳細設定」のところにあるチェックボックス『このライブストリームは360°です』にチェックをする。
![youtube001.png](https://qiita-image-store.s3.amazonaws.com/0/61168/aa8439ea-14d8-9380-15ec-ecf42f5539a8.png)
・作成したライブイベントのサーバURL（たぶんみんな同じならこれ→rtmp://a.rtmp.youtube.com/live2）とストリームキーをFLMEの『FMS URL』と『Stream』のところに設定。
・FMLEのVideoのBit Rateはとりあえず1500kbps、Output Sizeは1280x720にする（Youtube側のカメラ設定に依存）。その他AudioなどはYoutubeの推奨環境を参照。
https://support.google.com/youtube/answer/2853702?hl=ja

※追記
動画フォーマットはH.264じゃないとYoutubeは受け付けてくれないので、FLMEのFormatのところでH.264を選択する。（H.264がセレクトボックスの上側に隠れているので、△を押して選択）
![h264.png](https://qiita-image-store.s3.amazonaws.com/0/61168/339fc5b0-9daa-3c40-df12-d9822c88f650.png)


・FMLEの「スタート」ボタンを押す。Youtubeのライブストリーミングコントロールルームで映像の受信状況を確認して配信開始する。

## 5.VR体験
・スマホにYoutubeアプリをインストールしておく。
・配信中のYoutubeアドレスにブラウザでアクセスする。
・Youtube配信画面の右下に出るゴーグル様アイコンをタップする。スマホ画面が左右二分割になる。
![Screenshot_20160502-174135s.png](https://qiita-image-store.s3.amazonaws.com/0/61168/c577a2fb-6442-f774-ec43-7357584a0f6e.png)
・あとはダンボール製のVRゴーグルにスマホを入れて覗けば、楽しいライブVRを体験ができます。おわり。

# 所感
体験的にはカメラを設置してある場所の周辺360度を、離れた場所から上下左右自由に見ることができるので、まるでその場に今いるような感覚でけっこうおもしろいです。しかし画質とfpsが低いので、少々臨場感には欠けます。もっと臨場感を出すにはやはり4Kカメラを何個か使ってリアルタイムでVR映像に変換できる機材（Vahana VRとかOrah 4iがいいかも）が必要かと思いました。