OmniAICreator/Qiita-1.07M huggingface dataset:
今更だけどRails4から実装されたStrongParameterをまとめてみる

## はじめに
Rails3系からさすがに脱出しないとね、ということでRails3系とRails4系の違いについてよく調べる今日この頃。
そこで出てきたStrongParameterについて、なるほどと思ったのでまとめてみます。

## Strong Parameterとは
MassAssignment機能を使う時に起こるかもしれない脆弱性に対する対策の１つ。

じゃあ、MassAssingmentとは？
これは、モデルの生成や更新の時にRubyのHashura酢を使って一括で属性を設定できる仕組み。
要は、更新する属性を書き換えた後に```user.save```ってするのではなく、```user.update```を使って一括更新する方法のことを指すらしい。

複数の属性の設定をカンタンにかける一方で、意図しない属性の変更を一般のユーザができてしまうので、脆弱性につながる。

例えばこんなメソッドがあった時↓

```
def update
  user = current_user
  user.update(params[:user])
end
```
このパラメータに不正なユーザの名前やパスワード、メールアドレスなどを送付してきた場合、意図しないユーザのデータが上書きされてしまう。
これを防ぐためにStrong Parameterを使います。

## Strong Parameterの使い方
いきなり例を書くとこんな感じで使う↓

```
def update
  user = current_user
  user.update(user_params)
end

private
  def user_params
    params.require(:user).permit(:name, :email)
  end
end

```

このようにuser.updateの引数はparams[:user]ではなく、privateに設定したuser_paramsというメソッドの返り値を設定するようにする。
user_paramsメソッドの中では、まず、```.require(:user)```で:userというkeyをもつもの確認し、```.permit(:name, :email)```で更新をしてもいい属性を指定することができる

## おわりに
まだ理解しきれていない部分が多いので、そのうち追記すると思います。
今回はパーフェクトRuby on Railsを参考にまとめました。
Firebase Console からトピックに対して通知を送りたい

簡単にトピックを送信する方法（裏技？）があるが、ドキュメントに書いてなかったのでここにメモしておいた。

# Firebase Console からトピックを送る上での問題
Firebase の通知管理画面は以下のような感じになっていて、ラジオボタンからトピックを選び、矢印のところからトピックが選択できる

![Firebase_Console.png](https://qiita-image-store.s3.amazonaws.com/0/7869/b34f5254-320e-027a-173a-9149be833040.png)

一見便利そうに見えて不便なところがある。

 * セレクトボックスとなっているので、選択式になっていて入力することができない。
 * ここには反映されるまでに時間がかかる（１日ぐらい待たされる感じがする）ので、ストレスが溜まる。

# 代替手段 
そこで以下のように「単一の端末」を選んでトピック欄に「/topic/トピック名」と入力して送信すると、特定のトピックに送信することができる。
![Firebase_Console.png](https://qiita-image-store.s3.amazonaws.com/0/7869/e2a4cd16-2c6e-76c2-20b7-9c358c613317.png)

# この仕様は何？
Firebase Notification も裏側の実装は FCM であることを考えると、これは納得がいく仕様であることが理解できる。

FCM で単一の端末に対して通知を送る際は以下のような感じで API に対して json を送信する。

```json
{
  "to" : "個別の端末のTOKEN",
  "notification": {
    "title": "タイトルです",
    "body": "メッセージです",
    "content_available": true,
  },
  "priority" : "normal",
  "data": {
    "hoge": "foo"
  }
}
```

これに対し、FCM でトピックに対して通知を送る際は以下のような感じで API に対して json を送信する。

```json
{
  "to" : "/topics/topic_name_daaa",
  "notification": {
    "title": "タイトルです",
    "body": "メッセージです",
    "content_available": true,
  },
  "priority" : "normal",
  "data": {
    "hoge": "foo"
  }
}
```

そう、to の中身が変わっただけだ。たぶん Firebase console の裏側の実装も to を置き換えているだけだから、このような動きをするのだと思われる。


ちなみに送信するときに使用した curl はこんな感じ

```bash
curl --header "Authorization: key=MYKEYYYYYY" --header Content-Type:"application/json" https://fcm.googleapis.com/fcm/send -d @info.json
```
Leaflet(R版)で地理院地図を使用する

LeafletでデフォルトになっているOpenStreetMapは非常に便利なのですが、実は厄介な問題があります。それは現在隣国と領土問題になっている竹島・尖閣諸島に関する記述が日本国の見解と異なる、ということです。

プログラム書いている人は「関係ないや～」と思われるかもしれませんが、ここら辺細かく見ている○○○な人から「おまえら非国民か」と脅されたりする可能性がありますので、サービスのレベルに応じたきめ細かい対応が必要です。（某OSSプロジェクトで実際にありました）

で、RでLeafletをたたく場合には以下のように **urlTemplate** に地理院地図のタイルデータを指定することでさっくり動かすことができます。
`leaflet() %>% addTiles(urlTemplate = "http://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png")`

<img width="1029" alt="スクリーンショット 2016-11-02 18.23.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/103775/daaf5046-a770-a8f5-9435-859de18b5008.png">
Swiftで、CSVファイルをURLから読み込み


#初めに
Swiftで、CSVファイルをDropBoxから読み込みたいなーって調べてた時、
出てきた記事の多くがCSVファイルをプロジェクトに突っ込んでから読み込んでたので、DropBoxから読み込むための覚え書き。


#開発環境
Xcode 8.1
iOS 10.1
Swift 3.0


#DropBox上のCSVファイルを読み込む
```swift

//最終的にデータを格納する配列
var fileData:[[String]] = []

//DropBox上のファイルデータを突っ込む変数
var csvString = ""
        
let pathURL = NSURL(string: "（DropBox上のファイルリンク）")
        
do {
   //ここでは文字コードをUTF16で指定
   csvString = try NSString(contentsOf: pathURL as! URL, encoding: String.Encoding.utf16.rawValue) as String
} catch let error as NSError {
   print(error.localizedDescription)
}

//","区切りで配列に追加
csvString.enumerateLines { (line, stop) -> () in
   fileData.append(line.components(separatedBy: ","))
}

```

<h1>DropBoxのリンクについて</h1>
DropBox上のファイルを使用する際、普通にリンクをコピーするとダメなようです。

コピーしたリンクの

```
www.dropbox.com
```

この箇所を

```
dl.dropboxusercontent.com
```

に変えると良いようです。




#最後に
このようにすることでDropBox上のファイルを読み込み、","区切りで配列に格納することができました。
まだまだ勉強中の身なので、間違いや蛇足な部分があるかもしれませんがご容赦ください。


#参考
[Swift 2.0 でファイルの読み込みと保存](http://qiita.com/itoru257/items/6d31ba75cbc0f4c645f7)
DjangoでServer-Sent Eventsを行う方法

DjangoでWebSocketやるには時間が足りないけどサーバーサイドpushをしたかったので、ゴリ押しでSSRを使って対処することにしました
修正点があれば指摘していただけると幸いです

# 注意
ローカルサーバーで実験した所、接続を中断させた時に[ConnectionAbortedError: [WinError 10053] 確立された接続がホスト コンピューターのソウトウェアによって中止されました。]というエラーメッセージが出ます
恐らく無害だと思いますが、気持ち悪いので扱う時は気をつけて下さい

# そもそもServer-Sent Eventsって何よ
ざっくり言うとすごいCometです。つまりゴリ押しサーバーサイドpushみたいなものです
WebSocketの方が優秀かもしれませんが、実装コストが低いのがメリットです
詳しく知りたい方は調べて下さい。

# コード内容概要
SSEをするだけ。他のIDなどの機能は一切省く

# コード
## Python側
ストリーミング配信を行う

```python:views.py
from django.views.decorators.http import condition
from django.http import StreamingHttpResponse
from django.views.generic import UpdateView, DetailView, FormView, TemplateView, DeleteView
import time


@condition(etag_func=None)
def stream_response(request):
    resp = StreamingHttpResponse(stream_response_generator(), content_type='text/event-stream')
    return resp


def stream_response_generator():
    while(True):
        yield "data: %s\n" \
              "retry:1000\n\n" % 0
        time.sleep(1)


class DevSSETemplate(TemplateView):
    template_name = "stream.html"

```

```python:urls.py
    url(r'^stream/$', views.stream_response, name='stream_response'),
    url(r'^stream/template/$', DevSSETemplate.as_view(), name='stream_response_template'),
```

## JavaScript側
取得してリストに加えるだけ

```html:stream.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id ="log"></div>
</body>
<script>

window.onload = function() {
  var evtSource = new EventSource("{% url 'accounts:stream_response' %}");
  var eventList = document.getElementById("log");

  evtSource.onmessage = function(e) {
      console.log(e);
      var newElement = document.createElement("li");

      newElement.innerHTML = "message: " + e.data;
      eventList.appendChild(newElement);
  };
}

</script>
</html>
```

# 解説
@.condition(etag_func=None)
ETag（キャッシュ周り）を無効化する？
StreamingHttpResponse
このメソッドを使うとストリーミング配信が出来る。普段はPDFなどを送信する時に使うそうです
これを含め、Djangoには機能なものが多く、痒い所に手が届くのはありがたいです

# 感想
これで一応動きました
SSEは実装コストが低く、WebSocketのサポートが進んでないフレームワークでは有用であると思われるが、~~恐らくダサいから~~何故か流行らないのが不思議です
Visual Studio2015でDirectX9の環境を構築する

新しいPCを購入してVisual Studio 2015をインストールしたところ
昔DirectX9を使って作ったソリューションをビルドしたらエラーになりました。
というわけでVisual Studio 2015でDirectX9を動作させるための環境設定について覚書。

# 事前準備
- Visual Studio 2015をインストールしている。
- DirectX SDK (June 2010)をインストールしている。
- Visual Studio 2015で新しくWin32プロジェクトを作っている。(下記に手順記載)
    - VS2015を起動 → 新しいプロジェクト → Visual C++ → Win32プロジェクトを選ぶ
    - アプリケーションの種類 → Windows アプリケーション
    - 追加のオプション → 空のプロジェクトにチェック
    - Security Development Lifecycle(SDL)にチェック


# とりあえず最低限のコード書いて動作確認
```cpp:sample.cpp
#include <windows.h>

///*--------------------------------------------
//メイン
//---------------------------------------------*/
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
{
	return 0;
}

```

何もしてないので、ビルドは通る。
ここでビルドがうまくいかない場合はそもそも何かおかしい。


# DirectX9のヘッダとかライブラリを読み込む

```cpp:sample.cpp
#include <windows.h>
#include <d3dx9.h>
#include <dxerr.h>

#pragma comment( lib, "d3d9.lib" )
#if defined(DEBUG) || defined(_DEBUG)
#pragma comment( lib, "d3dx9d.lib" )
#else
#pragma comment( lib, "d3dx9.lib" )
#endif
#pragma comment( lib, "dxerr.lib" )

///*--------------------------------------------
//メイン
//---------------------------------------------*/
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
{
	return 0;
}
```

何も設定してないのでヘッダが読み込めないとか、リンクエラーとかが出る。

プロジェクトのプロパティを開き、構成プロパティのVC++ ディレクトリを選択
インクルードディレクトリに`$(DXSDK_DIR)Include;`を追加
ライブラリディレクトリに`$(DXSDK_DIR)Lib\x86;`を追加

これでビルドは通る。
ここでビルドが通らない場合はSDKのインストールがうまくいってないかも。

# DxErr.hの機能を使おうとするとリンクエラー
いつも通り設定して普通にビルド通り、問題なしと思いきや
ログ出力マクロの「DXTRACE_ERR」を使った瞬間リンクエラーが出ました。


> エラー	LNK2019	未解決の外部シンボル __vsnwprintf が関数 "long __stdcall StringVPrintfWorkerW(unsigned short *,unsigned int,unsigned int *,unsigned short const *,char *)" (?StringVPrintfWorkerW@@YGJPAGIPAIPBGPAD@Z) で参照されました。

__vsnwprintf関数がないとのことだが
VS2015から、上記関数は別のライブラリに移動されたようです。

プロジェクトのプロパティを開き、　構成プロパティのリンカー → 入力 を選択
追加の依存ファイルに`legacy_stdio_definitions.lib`を追加してあげて解決。

と、ここまでやってひとまずは動きそうな感じでした。
(少なくとも新規プロジェクト作成でやった場合は)


# 過去にDirectX9で作られたソリューションを動かす場合
VS2015でVS2010などの古いソリューションを開くと
最初にプロジェクトの形式が古いのでアップコンバートする確認が出ると思うのでOKします。

あとは上記に記載したプロジェクトと同様にインクルードディレクトリの設定を見直し。
リンカー → 入力 に 追加の依存ファイル`legacy_stdio_definitions.lib`の追加をすればある程度動くかと。

動かない場合は、今回作成したプロジェクトと
当時のプロジェクトの差分を見て足りないものを追加していくとよさそうです。
(VC++ ディレクトリのインクルードディレクトリに違いがないかなど)


# おまけ
DirectXの機能はWindows VistaからWindowsの標準SDKに含まれたため
今回のようにDirectX SDKを別途インストールして使用する場合に下記の警告が多発することがあると思います。


> c:\program files (x86)\microsoft directx sdk (june 2010)\include\dxgitype.h(12): warning C4005: 'DXGI_STATUS_OCCLUDED': マクロが再定義されました。

この警告がうっとおしい場合は下記のように、一時的にC4005の警告を無視するなどがよさそうです。
(根本的なことを言えばDirectX9とか前時代的なものを使うなというところなのでしょうが)

```cpp:sample.cpp
#pragma warning(push)
#pragma warning(disable:4005)
#include <d3dx9.h>
#pragma warning(pop)
```

# おわり
今後はDirectX SDKを使わなくなり、これらの情報も無意味になるのかもしれませんが
昔のプログラムを動かしたいという場合はここらへん注意してみればいいと思います。
MacOS Serriaにしてからbrew install できなくなった

# brew install できない
```brew install```
としてもエラーが出る。Serriaになってから、userなどのディレクトリの制限が変わったらしい。アップデートしてエラーが出るのはマジではやめてくれ泣
エラーを読むと
```sudo chown $(whoami):admin /usr/local```
をすればいいらしい。

# chown: command not found　てでた
調べてみると、以下のコマンドを打てばchownが使えるようになるらしい。
```export PATH="$PATH:/usr/sbin"```
これを打つとパスを通すらしい（参考文献）。こういう時のために、pathとかシェルの基本的な知識を身につけていたら・・・
# 再び　chown
```sudo chown $(whoami):admin /usr/local```
できた。
# 再び　brew install
```brew install```
なんかエラーでた。エラーメッセージを残さなかったが、最新のxcode(8.1)をダウンロードしろみたいなことを言ってる。

# App Storeから最新のXcode(8.1)をダウンロードする
待ち時間3時間? Fuck Up
# 三度brew install 
なんかxcodeを認証してくれ見たいなエラーがでた！でも親切に
```sudo xcodebuild -license accept```
をすればいいよと書いてくれた。homebrew大好き。
# sudo xcodebuild -license accept　からの brew install
やっとできた。

# 総評
Picture in Pictureにつられてアップデートするんじゃなかった。

### 参考文献
http://stackoverflow.com/questions/23714097/sudo-chown-command-not-found
Koaで構築したサーバをHTTPS/HTTP2化する

# Koa とは

Node.js 用の Web フレームワークです
Node.js 用の Web フレームワークと言えば express が有名ですが、そのメンバーが作っているようです
Generator が使えるのが特徴です


# サンプル

[公式サイト](http://koajs.com/)にあるサンプルソースです

```app.js
const koa = require('koa');
const app = koa();

app.use(function *(){
  this.body = 'Hello World';
});

app.listen(3000);
```

`node app.js` を実行し、「 http://localhost:3000 」にアクセスすると

![HelloWorld.png](https://qiita-image-store.s3.amazonaws.com/0/54850/d52e088a-3c21-2f55-0246-4736948a7bcc.png)

このように「Hello World」が表示される
このサンプルを HTTPS/HTTP2化 していきたいと思います

# 証明書の作成

今回はローカル環境を対象にしますので、オレオレ証明書でいきます
OpenSSL がインストールされていることが前提です

## 秘密鍵の作成

```
openssl genrsa 2048 > server.key

# 秘密鍵をパスフレーズで保護する場合、暗号化するためのオプションを追加する
# -des, -des3, -aes128, -aes192, -aes256 等が選択可能
```

## CSR（証明書の基になる情報）の作成

```
openssl req -new -sha256 -key server.key -out server.csr
```

証明書の署名アルゴリズムに SHA-1 を使っている場合、2017年以降通信できなくなるので
`-sha256` を指定する

## 証明書（公開鍵）の作成

```
openssl x509 -in server.csr -out server.crt -req -signkey server.key -sha256 -days 3650
```

`-days` で証明書の有効期限を設定します
オレオレなので10年にしました

# HTTPS化

HTTPS化する場合は、すでにモジュールが Node.js に組み込まれているので前準備は必要ありません

```app.js
const koa = require('koa');
const app = koa();
const https = require('https');
const fs = require('fs');

const options = {
  key: fs.readFileSync('server.key'), // 作成した秘密鍵のパスを指定し読み込む
  cert: fs.readFileSync('server.crt') // 作成した証明書のパスを指定し読み込む 
};

app.use(function *(){
  this.body = 'Hello World';
});

https.createServer(options, app.callback()).listen(3000);
```

`app.callback()` を呼ぶと `createServer` に渡す callback を返してくれます

また、秘密鍵をパスフレーズで保護している場合は下記のように指定します

```js
const options = {
  key: fs.readFileSync('server.key'),
  cert: fs.readFileSync('server.crt'),
  passphrase: '秘密鍵作成時に指定したパスフレーズ'
};
```

`node app.js` を実行し、「 https://localhost:3000 」にアクセスすると

![HelloWorld-https.png](https://qiita-image-store.s3.amazonaws.com/0/54850/17d6c351-35b8-385a-6704-e89b63ea522c.png)

https 接続できていることがわかります

# HTTP2化

基本は HTTPS と同じですが、`http2` モジュールのインストールが必要です

```
npm install http2
```

これで準備完了です

```app.js
const koa = require('koa');
const app = koa();
const http2 = require('http2');
const fs = require('fs');

const options = {
  key: fs.readFileSync('server.key'),
  cert: fs.readFileSync('server.crt')
};

app.use(function *(){
  this.body = 'Hello World';
});

http2.createServer(options, app.callback()).listen(3000);
```

`https` の部分が `http2` に変わっただけですね

`node app.js` を実行し、「 https://localhost:3000 」にアクセスし、Developer Tools で確認すると

![HelloWorld-http2.png](https://qiita-image-store.s3.amazonaws.com/0/54850/d0d99263-459f-56d0-9b27-e2bd3329904f.png)

http2 接続できていることがわかります
WordPressを本番にデプロイするためにwp cliでデータベース内のドメインを置換する

## WP CLIについて

コマンドラインからWPを操作できる便利なもの
http://wp-cli.org/ja/


### ひとまず試しに置換の結果を見てみる

以下のコマンドで、既存のデータベースを変更すること無く、結果変更された箇所と数を確認することが可能。
※ URLはシングルクォーテーションで囲む
※ **最後のスラッシュは必ずつけない**

```
wp search-replace 'http://hogehoge.com' 'http://hugahuga.com' --dry-run
```


### データベースのバックアップ

以下のコマンドで現在のDBをダンプし任意の名前で保存できる。

```
wp db export hogehoge.sql
```

## 置換したデータベースのエクスポート

以下のコマンドで既存のデータベースを変更すること無く、ドメイン置換後のsqlをダンプし、任意の名前で保存できる

```
wp search-replace 'http://hogehoge.com' 'http://hugahuga.com' --export=hogehoge.sql
```


## データベースのインポート

以下のコマンドで任意のsqlファイルをWPのデータベースにインポート可能(既存のものは上書き削除される

```
wp db import hogehoge.sql
```
ネットワークドライブに割り当てたフルパスを取得する方法


右クリックから取得。などできたら良かったができなかった。power shellとかにコマンドが有るかもしれない。(未調査）

苦し紛れの対策

1. フルパスを指定してディレクトリにアクセス
2. フォルダのアイコンをドラッグ・アンド・ドロップしてショートカットを作成
3. フルパスが欲しいときはそのショートカットからディレクトリに移動
4. パスをコピーする
inspect.pyを作るとjupyterのカーネルが落ちる

jupyterにて「Dead Kernel」とカーネルが勝手に落ちる現象があって、
原因がわからず苦労したのでメモしておきます。

![image](https://qiita-image-store.s3.amazonaws.com/0/109458/2861c555-15bf-be49-534f-96263e4a63d7.png)


＜エラーの内容＞

```
Traceback (most recent call last):
  File "C:\Anaconda3\lib\runpy.py", line 174, in _run_module_as_main
    mod_name, mod_spec, code = _get_module_details(mod_name, _Error)
  File "C:\Anaconda3\lib\runpy.py", line 133, in _get_module_details
    return _get_module_details(pkg_main_name, error)
  File "C:\Anaconda3\lib\runpy.py", line 109, in _get_module_details
    __import__(pkg_name)
  File "C:\Anaconda3\lib\site-packages\ipykernel\__init__.py", line 2, in <module>
    from .connect import *
  File "C:\Anaconda3\lib\site-packages\ipykernel\connect.py", line 13, in <module>
    from IPython.core.profiledir import ProfileDir
  File "C:\Anaconda3\lib\site-packages\IPython\__init__.py", line 48, in <module>
    from .core.application import Application
  File "C:\Anaconda3\lib\site-packages\IPython\core\application.py", line 23, in <module>
    from traitlets.config.application import Application, catch_config_error
  File "C:\Anaconda3\lib\site-packages\traitlets\__init__.py", line 1, in <module>
    from .traitlets import *
  File "C:\Anaconda3\lib\site-packages\traitlets\traitlets.py", line 944, in <module>
    class HasDescriptors(six.with_metaclass(MetaHasDescriptors, object)):
  File "C:\Anaconda3\lib\site-packages\six.py", line 808, in __new__
    return meta(name, bases, d)
  File "C:\Anaconda3\lib\site-packages\traitlets\traitlets.py", line 726, in __new__
    if inspect.isclass(v) and issubclass(v, TraitType):
AttributeError: module 'inspect' has no attribute 'isclass'
```


原因はinspect.pyというファイルを作ったことにありました。
適当なinspect.pyを作って、同じフォルダで.ipynbファイルを動かすとカーネルが落ちます。
inspect.pyは標準のライブラリにあるらしく、重複したためエラーが出たようです。
Bootstrapで、xsのカラム数をファブレットとスマートフォンで分ける方法

# 困ったこと

Bootstrap3のグリッドシステムでは、```col-xs-6```のように、クラス名に特殊な接頭辞と数字を組み合わせて、レスポンシブなレイアウトを簡単に構築することができます。

しかし、768px以下の場合のxsサイズのレイアウトを実際に見てみると、

- 400pxくらいのスマートフォンで見た場合
- 700pxくらいのファブレット（あるいはそれくらいの幅のブラウザ）で見た場合

ひとつのレイアウトで表現しようとすると違和感があることがあります。

例えば、400pxの場合、以下の表示とします。

<img width="231" alt="350px.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/6813/f9af7e5b-4a78-abcd-5d70-9d9165987f51.png">


これを680pxくらいに広げるとこうなりました。

<img width="488" alt="680px_before.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/6813/cea88cb5-10eb-034f-2359-2d27d25236a6.png">


画像の右側が空いていて、無駄な感じがします。

しかし、

```html
<div class="col-xs-6">
      <img class="img-responsive" src="/image/dummy.jpg"> 
</div>
```

のように、グリッドシステムで```col-xs-6```を指定しているので、画像の右側に要素を配置することが出来ません。

xsの下に、xxsみたいなサイズ指定が出来れば……

# これで解決してみた

Bootstrapを拡張して```col-xxs-3```みたいなxsの下のサイズを定義できれば楽だと考えたので、以下のようなJavaScriptを書いてみました。

簡単に説明すると、スマートフォンとファブレットサイズでグリッドサイズを分けたいクラスに、```custom-col-xs```を定義し、そのタグにデータ属性```data-xs```と```data-xxs```を定義します。

画面のロード時やウィンドウ幅変更時に、データ属性の値を読み取って```custom-col-xs```のクラス属性を```col-xs```のクラスに動的に書き換えます。

```javascript
/**
 * bootstrap-expand.js
 * HTMLでのロード順は、
 * jQuery -> 本ファイル -> bootstrapにすること
 */
$(function(){
  
	$(window).on('load resize', function(){
		applyCustomColXs();
	});
	
	function applyCustomColXs() {
	    var THRESHOLD = 420;
	    if ($(window).width() > THRESHOLD) {
	    	applyPhablet();
	    } else {
	    	applySmartphone();
	    }
	}

	// ファブレット用表示に切り替える
	function applyPhablet() {
		$(".custom-col-xs").each(function(){
			// data-xs属性の値を使って、新しくcol-xs-*　クラス属性を追加する
			updateColXsClass($(this), $(this).attr('data-xs'));
		});
	}

	// スマートフォンサイズ用の表示に切り替える
	function applySmartphone() {
		$(".custom-col-xs").each(function(){
			// data-xxs属性の値を使って、新しくcol-xs-*　クラス属性を追加する
			updateColXsClass($(this), $(this).attr('data-xxs'));
		});
	}

	function updateColXsClass($elem, val) {
		var cls = $elem.attr("class");
		var class_arr = cls.split(" ");
		// 一旦、col-xs-* のクラス属性を削除する
		$elem.removeClass (function (index, css) {
		    return (css.match (/(^|\s)col-xs-\S+/g) || []).join(' ');
		});
		$elem.addClass('col-xs-' +  val);
	}

});
```

先のHTMLはこうなります。

```html
<!-- ファブレットサイズでは3カラム、スマートフォンサイズでは6カラム使用することを意味する -->
<div class="custom-col-xs" data-xs="3" data-xxs="6">
      <img class="img-responsive" src="/image/dummy.jpg"> 
</div>
```

こうすることで、680pxでの表示が、

<img width="490" alt="680px_after.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/6813/5f8a4123-7fa7-ed49-3eab-d72634e6df8e.png">


いい感じになりました。

デザイナがいない現場ということもあり、正攻法で無い気がしますが、他によい方法などあれば知りたいです。
Mobile Vision APIを使ってカメラ映像を表示する

Android Lで非推奨になってしまった[Camera API](https://developer.android.com/reference/android/hardware/Camera.html)は使いたくない。かといって[Camera2 API](https://developer.android.com/reference/android/hardware/camera2/package-summary.html)はめんどくさい。
やりたいことはカメラのプレビューを表示するだけなのに、何か良い方法はないかと考えていた時に[Google Play ServiceのMobile Vision API](https://developers.google.com/vision/)でカメラ映像のプレビューができることを発見しました。
しかしMobile Vision APIのドキュメントには顔検出やバーコードリーダーとして使う方法しか書いておらず（当たり前）、カメラ映像のプレビュー表示だけを行うことはできないのかなぁと思って試行錯誤してみたところ上手く行ったので、その方法をまとめます。

まず、以下の二つのクラスを作成します。

```java:DummyDetector.java
import android.util.SparseArray;

import com.google.android.gms.vision.Detector;
import com.google.android.gms.vision.Frame;

public class DummyDetector extends Detector<Void> {
    @Override
    public SparseArray<Void> detect(Frame frame) {
        return null;
    }
}
```

```java:DummyProcessor.java
import com.google.android.gms.vision.Detector;

public class DummyProcessor implements Detector.Processor<Void> {
    @Override
    public void release() {
    }

    @Override
    public void receiveDetections(Detector.Detections<Void> detections) {
    }
}
```

Mobile Vision APIはカメラの映像から何かのオブジェクトを検出してアプリケーションに受け渡すためのフレームワークなのですが、**「何も処理をしない」ということが考慮されていません。**
なので、「何も検出しない」「何も処理しない」というダミーの`Detector`と`Processor`の実装を作成して、これを利用します。

あとは、これを使って`CameraSource`を作成して、`CameraSource.start()`を呼び出せばプレビューが開始します。プレビュー画像サイズやフレームレート等は必要に応じて設定してください。

```java
DummyDetector dummyDetector = new DummyDetector();
dummyDetector.setProcessor(new DummyProcessor());

cameraSource = new CameraSource.Builder(getContext(), dummyDetector)
        .setRequestedPreviewSize(640, 480)
        .setFacing(CameraSource.CAMERA_FACING_BACK)
        .setRequestedFps(30.0f)
        .setAutoFocusEnabled(true)
        .build();

cameraSource.start(surfaceHolder);
```

`surfaceHolder`は、`SurfaceView`などから取得します。
Amazon Linux のDockerイメージをローカルで使う時、RPMパッケージをEC2上のプロキシ経由で取得

Amazon Linuxが公式にDockerイメージを配布しだしました。

[Introducing New Amazon Linux Container Image for Cloud and On-Premises Workloads](https://aws.amazon.com/jp/about-aws/whats-new/2016/11/introducing-new-amazon-linux-container-image-for-cloud-and-on-premises-workloads/)

個人的にはなんでも良いのだけど、これをベースにして欲しいという要望がちらほらある。
で、これ結構空っぽなのよね。curlが入っているので、中身の構築自体はなんとでもなりそうだけど、ちょっと触ってみる分にはrpmのパッケージくらいは取れるとよいよね。

> Amazon Linux用RPMのリポジトリはAWSのネットワークからしか取得<del>できないので、EC2に取らせてみた。</del>できなかった気がしたが、気のせいだったかもしれない。


## 適当なEC2インスタンスでフォワードプロキシを起動

> 追記： もうプロキシなくてもつかえる模様

まずEC2のインスタンスを起動します。squidあたりでフォワードプロキシ(全開け)をして試してみます。

```
$ sudo yum install squid -y
$ sudo sed 's/http_access deny all/http_access allow all/g' /etc/squid/squid.conf -i
$ sudo service start squid
```

とりあえずこれで、デフォルトの`TCP/3128`でHTTPプロキシが起動。あとはこれを指定と。

## ローカルのDockerコンテナ内からyum

ECRからpullしておいた`amazonlinux`をrunして、yumしてみる。

```
$ docker run -it --rm 137112412989.dkr.ecr.ap-northeast-1.amazonaws.com/amazonlinux:latest 

## 以降Dockerコンテナ内

bash-4.2# http_proxy=http://54.199.xxx.xx:3128 yum install tar
Loaded plugins: priorities, update-motd, upgrade-helper
Resolving Dependencies
--> Running transaction check
---> Package tar.x86_64 2:1.26-31.22.amzn1 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

===============================================================================================================================================================================================================
 Package                                     Arch                                           Version                                                    Repository                                         Size
===============================================================================================================================================================================================================
Installing:
 tar                                         x86_64                                         2:1.26-31.22.amzn1                                         amzn-main                                         1.1 M

Transaction Summary
===============================================================================================================================================================================================================
Install  1 Package

Total download size: 1.1 M
Installed size: 2.7 M
Is this ok [y/d/N]: 
```

OK。tarくらいは使えるほうがいいな。
公式に持ち出し禁止だった時はしなかったけど、もうこれやってもいいってことだよねぇ？


## buildとか


ビルドの時は`build-arg`で`http_proxy`を渡してもいいし、yumの設定に書いても良い。
EC2でプロキシする以外、他にも色々やり方はありそうなんで、何が一番コストかからないか試してみるのもいいかもね。
[調査中] Outlook > インライン変換ができなくなり、システムライン変換になる > 対処 >Escを押す

```txt:動作環境
Outlook 2013
Windows 10 
```

Outlookを使っていて漢字変換処理が左上に表示されるようになるという報告を受けた。

症状としては「システムライン変換」になっているようだ。

以下が詳しい。
[日本語入力中にインライン変換ができなくなる。](http://answers.microsoft.com/ja-jp/msoffice/forum/msoffice_imeditor-mso_other/%E6%97%A5%E6%9C%AC%E8%AA%9E%E5%85%A5%E5%8A%9B/f70fc8ab-40f9-4803-8c60-93a4fef326ce?msgId=d8197d6a-80af-4ef3-a620-c36d51fd3ae0)

### 対応方法

Escキーを押す。

確実な対応方法かどうかは数回の再現を待つことになる。

<hr>
(追記 2016/11/08)

answers.microsoft.comの記事にてEscキーでは回復しなかったという報告があった。

次回発生時に何がトリガで回復できたかもう少しみることになりそう。
Androidでバイブレーター動作

Androidでバイブレーターを動作させるサンプルという名のメモ。
昔からあるままなので、広い範囲のバージョンで動作可能なはず・・・。

# パーミッションの追加

マニュフェストファイルに以下のように追加。

```xml:AndroidManufest.xml
<uses-permission android:name="android.permission.VIBRATE"/>
```


# インポート

```java
import android.os.Vibrator;
```


# 初期処理

動作を行いたいクラスのメンバを追加しておく。

```java
private Vibrator mVibrator;
```

インスタンスはgetSystemServiceを使ってシステムから取得する。
onCreateあたりで実施すれば良い。

```java
mVibrator = (Vibrator)getSystemService(VIBRATOR_SERVICE);
```


# 動作
## 一定時間駆動
 Vibrateクラスのvibrateを利用する。引数は時間[ミリ秒]。
 1,000ms駆動の場合、以下のようになる。
 
```java
mVibrator.vibrate(1000);
``` 
 
 
## パターンでの駆動
long型配列でパターンを指定する。

```java
// オンとオフの時間[ms]を交互に指定する
long pattern[] = {1000, 500, 2000};

// パターンと繰り返し回数を指定　下記例は1回繰り返し、つまり2回実行
mVibrator.vibrate(pattern, 0);
```


## 即時停止

```java
mVibrator.cancel();
```

# リンク
[(Android Developers) Vibrator](https://developer.android.com/reference/android/os/Vibrator.html)
[java]Mapクラスのオブジェクトの中身を全て確認するコード

備忘録として記入

```
public static void main(String arg[]) {
    Map<String, String> map = new HashMap<>();
    map.put("key1", "val1");
    map.put("key2", "val2");
 
    for (String key : map.keySet()) {
        System.out.println(key + ":" + map.get(key));
    }
}
```

[参考リンク](http://javatechnology.net/java/map-keyset/)
CloudFrontはLocationヘッダー値を問答無用でURLエンコードする

CloudFront使用時に, GETパラメータをいろいろくっつけたURIにリダイレクトすると想定しているパラメータじゃない値がくっついていて困りました.
しかもこれマニュアルに載ってなくない!? ということでさらに困っています.

# 何が起きているのか
CloudFrontはオリジンからのレスポンスヘッダのLocation値をURLエンコード(パーセントエンコード)を行った値で上書きしてからクライアントにレスポンスを返しているようです.

## CloudFrontを通さずアクセスした場合
WebサーバでURLエンコードしてあるので `hoge=%E3%81%82` が末尾に付いたURLがLocationヘッダーに設定されています.
ちなみに`%E3%81%82`は`あ`です.
![Developer_Tools_-_https___app001-test_h-navi_jp_area_admin_facilities_50665_edit_search_options_5Bcategory_id_5D_5.png](https://qiita-image-store.s3.amazonaws.com/0/48596/03f5b546-f452-b631-f081-bf765272f078.png)

## CloudFrontを通してアクセスした場合
`%`がエンコードされて`%25`になっています.
もちろん`%25E3%2581%2582`はデコードしても`あ`にならないので困ります.
![Developer_Tools_-_https___test_h-navi_jp__hoge__25E3_2581_2582.png](https://qiita-image-store.s3.amazonaws.com/0/48596/38c387ef-2f53-3e33-0e6e-963b00421ee3.png)

# マニュアルに載ってない!?
AWSのマニュアル[CloudFront が削除または更新する HTTP レスポンスヘッダー](http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomOrigin.html#ResponseCustomRemovedHeaders)には, 「Locationヘッダーを書き換えるよ」という話は載ってません.
載ってないということは対処法もわからないので困っています.

「エンコード必要な文字が含まれてるURLにリダイレクトするなバカ」「Webサーバがエンコードしなければいいだけの話だろタコ」等の話はもっともですが, めんどくさいからCloudFrontがLocationヘッダーをエンコードしないようにする方法無いかなあというのが正直なところです.
matplotlib, seabornの日本語表示

# pythonで作るグラフの日本語表示

事前にIPAなどの日本語対応フォントをインストールしておくこと。
zipダウンロードしたら解凍して.ttfファイルを右クリックからインストールでOK.
[独立行政法人　情報処理推進機構](http://ipafont.ipa.go.jp/old/ipafont/download.html)

デフォルトのフォントである`sans-serif`から`IPAGothic`や`IPAMincho`などにしなければならない。

やり方は以下の二つ

* ~/.matplotlib/matplotlibrcを弄る
* スクリプトの最初でフォント変更の宣言





# ~/.matplotlib/matplotlibrcを弄る

matplotlibrcとは、matplotlibの設定ファイルのこと。
`import matplolib`を行ったときに実行される。
`~/.matplotlib`以下のディレクトリに`matplotlibrc`の名前で保存しておくと、`matplotlib`のインポート時に読み込んでくれる。

どのrc設定ファイルが有効であるかは、次のコードで調べる。

```python:どのmatplotlibrcが有効か調べる
>>> import matplotlib as mpl
>>> mpl.matplotlib_fname()
'C:\\Users\\python\\.matplotlib\\matplotlibrc'
```

書き込む内容は以下の通り。
最初にも書いたようにこの場合はIPA明朝がインストールされていること。
それ以外のフォントでもできるはず。名前は調べてください。

```python:~/.matplotlib/matplotlibrc
font.family : IPAMincho
```





## startup.ipyに注意
スタートアップ時に`matplotlib.pyplot`と同時に`seaborn`を起動している場合は以下の操作も行う。


# seabornの設定
seabornインポートしているときは、`C:\tools\Anaconda3\Lib\site-packages\seaborn\rcmod.py`の`rcmod.py`のset関数のデフォルト値の`font`を"sans-serif"から"IPAMincho"などに変更する。

```
def set(context="notebook", style="darkgrid", palette="deep",
        font="IPAMincho", font_scale=1, color_codes=False, rc=None):
```





# スクリプトの最初でフォント変更の宣言


```python:スクリプトの最初でフォントの変更(matplotlib.pyplot)
import matplotlib as mpl
mpl.rcParameters['font.family'] = 'IPAMincho'
```

```python:スクリプトの最初でフォントの変更(seaborn)
sns.set(font=['IPAMincho'])
```


# フォントキャッシュの更新

設定をちゃんとしたのになんかうまくいかんな、ってときは以下のコマンドでフォントキャッシュを更新するとうまく行くことがある。

```python
import matplotlib as mpl
matplotlib.font_manager._rebuild()
```

参考: [Updating the Matplotlib Font Cache](https://bastibe.de/2016-05-30-matplotlib-font-cache.html)
Androidアプリ開発でログイン情報を端末に保存する方法（パスワードはAES暗号化）

Androidアプリでまずログインが必要な場合、ユーザにとってパスワード等のアカウント情報は次回以降自動入力にしてほしいところ。
SharedPreferencesという、端末内に入力データを保存、取得できる仕組みを用い実現できるようです。
その方法を紹介します。といいますかメモです。
ログイン成功時にパスワードはAESで暗号化し保存、次回以降ログイン画面表示時にAESで複合化し表示という処理になります。


【アカウント情報の保存】

```java
   // ログイン成功時処理

   // ログインIDとログインパスワードのビューオブジェクトを取得
   EditText editTextLoginAccount = (EditText)findViewById(R.id.editTextLoginAccount);
   EditText editTextLoginPass = (EditText)findViewById(R.id.editTextLoginPass);

   // 「pref_data」という設定データファイルを読み込み
   SharedPreferences prefData = getSharedPreferences("pref_data", MODE_PRIVATE);
   SharedPreferences.Editor editor = prefData.edit();

   // パスワードは暗号化
   SecretKeySpec keySpec = new SecretKeySpec("abcdefg098765432".getBytes(), "AES"); // キーファイル生成
   Cipher cipher = Cipher.getInstance("AES");
   cipher.init(Cipher.ENCRYPT_MODE, keySpec);
   byte[] encrypted = cipher.doFinal(editTextLoginPass.toString().getBytes()); // byte配列を暗号化
   String up = Base64.encodeToString(encrypted, Base64.DEFAULT); // Stringにエンコード

   // 入力されたログインIDとログインパスワード
   editor.putString("account", editTextLoginAccount.getText().toString());
   editor.putString("pass", up);

   // 保存
   editor.commit();
```



【アカウント情報の取得と設定】

```java
   // ログイン画面表示処理

   // 「pref_data」という設定データファイルを読み込み
   SharedPreferences prefData = getSharedPreferences("pref_data", MODE_PRIVATE);
   String account = prefData.getString("account", "");
   String pass = prefData.getString("pass", "");

   // パスワード複合化処理
   String up = "";
   SecretKeySpec keySpec = new SecretKeySpec("abcdefg098765432".getBytes(), "AES"); // キーファイル生成 暗号化で使った文字列と同様にする
   Cipher cipher = null;
   try {
       cipher = Cipher.getInstance("AES");
       cipher.init(Cipher.DECRYPT_MODE, keySpec);
       byte[] decByte = Base64.decode(pass, Base64.DEFAULT); // byte配列にデコード
       byte[] decrypted = cipher.doFinal(decByte); // 複合化
       up = new String(decrypted); // Stringに変換
   } catch (NoSuchAlgorithmException e) {
       e.printStackTrace();
   } catch (NoSuchPaddingException e) {
       e.printStackTrace();
   } catch (InvalidKeyException e) {
       e.printStackTrace();
   } catch (BadPaddingException e) {
       e.printStackTrace();
   } catch (IllegalBlockSizeException e) {
       e.printStackTrace();
   }

   // 空チェック
   if (account != null && account.length() > 0) {
       // 保存済の情報をログインID欄に設定
       this.editTextLoginAccount.setText(account);
   }
   if (up != null && up.length() > 0) {
       // 保存済の情報をログインパスワード欄に設定
       this.editTextLoginPass.setText(up);
   }
```



他にももっと簡単な方法があるのかもしれないけど、
ログイン以外にも様々なケースで使えると思うのでメモです。
簡単な方法知っている方いらっしゃったらぜひおしえてください！
RealmデータをwatchOSとiOSとの間でやりとりする(2)

#はじめに
([RealmデータをwatchOSとiOSとの間でやりとりする(1)](http://qiita.com/hsylife/items/c21f19b80c5c81f32fb8)の続きになります。)

watchOSとiOSとの間でRealmのデータをやりとりする実装方法について述べます。
watchOS2+、iOS9+、Swift 3を前提に話を進めます。
動作するコードを[サンプルプロジェクト](https://github.com/hsylife/SampleRealmOnWatchOS3)としてGitHubに公開しました。実機でランすれば、速度感を体験できます。


#CocoaPodsでRealmを導入
RealmSwiftを利用したいので、CocoaPods 1.0.0以降では、Podfileを次のように記述します。

```.rb
target 'SampleRealmOnWatchOS3' do
dynamic frameworks
  use_frameworks!
  pod 'RealmSwift'
end

target 'SampleWatchApp_Extension' do
  use_frameworks!
  platform :watchos, '2.0'
  pod 'RealmSwift'
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['SWIFT_VERSION'] = '3.0'
    end
  end
end
```

サンプルでは、`SampleRealmOnWatchOS3`がiOSアプリのターゲット名、`SampleWatchApp_Extension`がwatchOSアプリのものとなっています。

ターミナルから`pod install`を実行して、正常終了すれば準備完了です。

これで、iOS/watchOSの双方でRealmSwiftをimportできるようになりました。

#Realmのデータモデルのソースファイルを共有する
iOS/watchOSでRealmのデータをやりとりするために、データモデルのSwiftファイルを共用できるようにする手順を見ていきます。

##1. publicでデータモデルを共用できるようにする
まず、データモデルをiOSアプリのターゲット向けに作成します。
サンプルでは、データモデルのクラス`Field`について、`Field.swift`をiOSアプリのターゲット`SampleRealmOnWatchOS3`向けに作成し、次のように定義しています。

```Field.swift
import RealmSwift

public class Field: Object {
    public dynamic var text: String?
}

```

[アクセスコントロール](http://qiita.com/hironytic/items/6cc68ca93b428ba9194e)を`public`にしています。iOSアプリのターゲット`SampleRealmOnWatchOS3`とwatchOSアプリのターゲット`SampleWatchApp_Extension`は別のモジュールなので、この垣根を超えてソースを共用するために指定しています。

##2. Compile Sourcesに追加する
1.で作成した.swiftファイルはiOSアプリのターゲット`SampleRealmOnWatchOS3`に帰属しています。ソース共用のためには、watchOSアプリの(正確にいうと、それが包含するエクステンションの)ターゲット`SampleWatchApp_Extension`にもソースを帰属させる必要があります。

TARGETS→`SampleWatchApp_Extension`→Build Phases→Compile Sources項目の中に、Field.swiftファイルをドラッグドロップして追加します。

<img width="800" alt="screenshot.png" src="https://qiita-image-store.s3.amazonaws.com/0/84185/c9de0c1c-fa19-f2a8-e5a4-39e66e2590d9.png">

これで、iOS/watchOSアプリが同じソースファイルをしてデータモデルを利用できるようになりました。

#関連記事
[RealmデータをwatchOSとiOSとの間でやりとりする(3)](http://qiita.com/hsylife/items/986a47a173a4b8ad5672#_reference-f0ff9aa9187a276769cc)
RubyからGoogleSpreadsheetに書く - お手軽編

必要ライブラリインストール
========================

https://github.com/gimite/google-drive-ruby をインストール

```
# cat /etc/redhat-release
CentOS release 6.7 (Final)
# ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
# gem -v
2.5.1
# gem install google_drive
～略～
# gem list | grep google_drive
google_drive (2.1.1)
```

GoogleDrive接続設定ファイル作成
=============================

以下のrbファイルを作成する

```setup.rb
require "google_drive"

# 初回実行時は、表示されるURLにGoogleログイン済のブラウザでアクセスし、表示された文字列を入力する必要あり
GoogleDrive::Session.from_config("google_drive_config.json")
```

上記を実行すると、URLが表示され、入力待ちになる

```
$ ruby setup.rb

1. Open this page:
https://accounts.google.com/o/oauth2/auth?access_type=offline&client_id=～略～

2. Enter the authorization code shown in the page:
```

上記URLにGoogleログイン済ブラウザでアクセスすると以下の画面が表示される

![ブラウザ画面その1](https://qiita-image-store.s3.amazonaws.com/0/112363/93c4d4a9-fff6-7a9f-a1b8-523359ed05a4.png)


許可ボタンを押下すると以下の画面が表示される

![ブラウザ画面その2](https://qiita-image-store.s3.amazonaws.com/0/112363/577be7b7-19ed-d735-95c8-646453abe714.png)


当該文字列を先程の「2. Enter the authorization code shown in the page:」に入力

google_drive_config.jsonファイルが作成される

ワークシート取得クラス
====================

```google_drive_wrapper.rb
require "google_drive"

class GoogleDriveWrapper
  # ワークシート取得
  # (フォルダ/スプレッドシート/ワークシートがなければ作成)
  def self.get_worksheet(folder_name, spreadsheet_name, worksheet_name)
    session = GoogleDrive::Session.from_config("google_drive_config.json")

    folders = session.collections("q" => ["name = ? and trashed = false", folder_name])
    folder = nil
    if folders.length == 0
      folder = session.root_collection.create_subcollection(folder_name)
      puts "フォルダ '" + folder_name + "' を作成しました。"
    else
      folder = folders[0]
    end

    spreadsheets = folder.files("q" => ["name = ? and mimeType = 'application/vnd.google-apps.spreadsheet' and trashed = false", spreadsheet_name])
    worksheet = nil
    if spreadsheets.length == 0
      # スプレッドシートをrootに作成、指定フォルダに追加、rootから削除
      spreadsheet = session.create_spreadsheet(spreadsheet_name)
      folder.add(spreadsheet)
      session.root_collection.remove(spreadsheet)
      puts "スプレッドシート '" + spreadsheet_name + "' を作成しました。"
      # ワークシートを追加、元からあった1シート目は削除
      worksheet = spreadsheet.add_worksheet(worksheet_name)
      spreadsheet.worksheets[0].delete
      puts "ワークシート '" + worksheet_name + "' を作成しました。"
    else
      spreadsheet = spreadsheets[0]
      worksheet = spreadsheet.worksheet_by_title(worksheet_name)
      if worksheet.nil?
        worksheet = spreadsheet.add_worksheet(worksheet_name)
        puts "ワークシート '" + worksheet_name + "' を作成しました。"
      end
    end
    worksheet
  end
end
```

呼び出し側
=========

```xxx.rb
require 'google_drive'
require './google_drive_wrapper'

worksheet = GoogleDriveWrapper.get_worksheet("フォルダ1", "スプレッドシート1", "ワークシート1")
worksheet[1, 4] = "xxx" # 1行目4列目に書き込み
worksheet.save # 保存
```

TODO
====

お手軽じゃない方法
　Java編 http://qiita.com/pilot/items/85bae4e5d5e35ffa7019 をやってみたら
　本記事の内容はあまり良くない方法だった
　(利用ライブラリ内のsecretを使っていたり)
Rails5 + pumaのローカル環境でSSL/HTTPSを有効にする


# RailsのローカルだってSSL/HTTPSにしたい

サードパーティなJSライブラリを入れると、HTTPS環境もしくはlocalhostじゃないと動かないよとか、ServiceWorkerを動かしたいけどlocalhost以外の名前でアクセスしたいよとか、色々と要望はあると思います。なので、Rails5 + pumaで設定してみました。簡単です。

## 証明書の作成

プロダクション用の本物証明書を使ってもいいですし、ローカルでHTTPSになっていれば良いやって言う場合はオレオレ証明書を作ってブラウザで例外追加してもいいです。オレオレ証明書は下記コマンドでさくっと作れます。

```
$ openssl genrsa 2048 > server.key
$ openssl req -new -key server.key > server.csr
$ openssl x509 -days 3650 -req -signkey server.key < server.csr > server.crt
```

## pumaの設定

`config/puma.rb` を編集します。SSLで必要な証明書などのパスを設定するだけです。

### config/puma.rb

```ruby
if "development" == ENV.fetch("RAILS_ENV") { "development" }
  ssl_bind '0.0.0.0', '9292', {
    key: "/file_path/server.key",
    cert: "/file_path/server.crt",
    ca: "/file_path/ca", # オレオレ証明書の場合は必要ないです／中間証明書が必要な場合は指定してください
    verify_mode: "none"
  }
end
```

## pumaの起動

通常は `rails s` とやると思いますが、puma.rbを反映させたいので下記のコマンドにします。

```
$ bundle exec pumactl start
```

これで `https://local.example.com:9292/` でアクセスが出来ると思います。

### 問題

通常の `rails s` ではアクセスログがダーッとコンソールに流れてきますが、これだと流れてきません。`log/development.log` には入ってくるのでそっちをtailすれば支障はないですが、ちょっと面倒くさいですね…。
httpd2.4 Apacheでもういっこ・・・あ\_(ˇωˇ」∠)_

<i class="fa fa-exclamation-triangle" aria-hidden="true"></i>基本的におれよう覚書デス\_(ˇωˇ」∠)_


コメントはしょり

```/etc/httpd/conf/httpd.conf

ServerRoot "/etc/httpd"


Listen www.example.com:80
Listen www.example.com:8080

Include conf.modules.d/*.conf

User apache
Group apache

ServerAdmin root@localhost

ServerName www.example.com


<Directory />
    AllowOverride All
    Require all denied
</Directory>

<Directory "/var/www">
    AllowOverride All
    # Allow open access:
    Require all granted
</Directory>

<Directory "/var/www/laratsk/public">
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>


<Directory "/var/www/caketsk">
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

NameVirtualHost www.example.com:80
NameVirtualHost www.example.com:8080

<VirtualHost www.example.com:80>
    ServerName www.example.com
    DocumentRoot /var/www/laratsk/public
</VirtualHost>

<VirtualHost www.example.com:8080>
    ServerName www.example.com
    DocumentRoot /var/www/caketsk
</VirtualHost>

<IfModule dir_module>
    DirectoryIndex index.html index.php
</IfModule>

<Files ".ht*">
    Require all denied
</Files>

ErrorLog "logs/error_log"

LogLevel warn

<IfModule log_config_module>
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common

    <IfModule logio_module>
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    </IfModule>

    CustomLog "logs/access_log" combined
</IfModule>

<IfModule alias_module>

    ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"

</IfModule>


<Directory "/var/www/cgi-bin">
    AllowOverride None
    Options None
    Require all granted
</Directory>

<IfModule mime_module>
    TypesConfig /etc/mime.types

    AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz

    AddType text/html .shtml
    AddOutputFilter INCLUDES .shtml
</IfModule>

AddDefaultCharset UTF-8

<IfModule mime_magic_module>
    MIMEMagicFile conf/magic
</IfModule>

EnableSendfile on

IncludeOptional conf.d/*.conf


```
VMware Player 7.1.4 のインストール

# VMware Playerをインストールする

世間的にはもうVMware Workstation Playerの12が出ておりそちらが主流なのかも知れないのですが、まだまだVMware Playerを使いたい人。いっぱいいるのでは無いかと思います。

しかしながら、VMwareのサイト上からインストーラーをダウンロードするのはいつも一苦労です。

またいつかインストールする日のために、メモしておきます。

## ダウンロード
https://my.vmware.com/jp/web/vmware/free#desktop_end_user_computing/vmware_player/7_0|PLAYER-714|product_downloads

すごくわかりづらいところにありました。
一応サイトTOPから辿ると、

* ダウンロード
 * すべてのドライバおよびツールのダウンロード
https://my.vmware.com/jp/web/vmware/downloads
   * Desktop & End-User Computing
   * VMware Workstation PlayerDownload Product
https://my.vmware.com/jp/web/vmware/free#desktop_end_user_computing/vmware_workstation_player/12_0

ここでメジャー バージョンを7.0に指定
Autodesk backburnerのアップデート用バッチファイル

Autodesk backburnerのバージョンを更新するバッチファイルです。Autodesk backburnerについてはこちらを参照してください。

https://knowledge.autodesk.com/ja/support/3ds-max/troubleshooting/caas/CloudHelp/cloudhelp/2016/JPN/Installation-3DSMax/files/GUID-F6732A30-821C-4547-9FAA-E46BCA13392A-htm.html

コマンドラインでジョブ投入できるのでAutodesk製品以外でもネットワークレンダリングに使用できます。

backburnerは下記URLでAutodesk Accountを作成すれば誰でもダウンロードできます。
https://accounts.autodesk.com/LogOn?theme=light

環境は以下の通り。

ドメイン名: MyDomain
作業ユーザー: backburner(インストール先ホストのadministrator権限あり)
パスワード: backburner
共有フォルダのあるサーバー: server01(MyDomainに参加)
インストーラのある場所: \Setup\backburner

ターゲットのサーバーが5台あり、ホスト名がrender01〜05だとします。その場合下のようなリストファイルを作成します。

```hosts_list.txt
render01
render02
render03
render04
render05
```

現在既にbackbuner 2015がインストールされていて、2017に更新する場合、\\\\server01\Setup\backburner\2015にアンインストールするbackburnerのインストーラ(backburner.msi)、\\\\server01\Setup\backburner\2017にインストールするbackburnerのインストーラを置きます。

```batch:bb_updata.bat
@echo off

set INSTUSER=backburner
set UNST_VER=2015
set INST_VER=2017
set SVR_PATH=\\server01\Setup\backburner

set UNST_PATH=%SVR_PATH%\%UNST_VER%
set INST_PATH=%SVR_PATH%\%INST_VER%

set DEST_PATH=C:\Users\%INSTUSER%\Desktop
set USERNAME=backburner
set PASSWORD=backburner
set DOMNAME=MYDOMAIN

IF "%1"=="" GOTO NOHOST
IF NOT EXIST "%1" GOTO NOHOSTFILE

FOR /F %%A IN (%1) DO (
rem uninstall backburner %UNST_VER%

call psexec \\%%A -u %DOMNAME%\%USERNAME% -p %PASSWORD%  xcopy %UNST_PATH% %DEST_PATH%\%UNST_VER% /S /Y /I
call psexec \\%%A -u %DOMNAME%\%USERNAME% -p %PASSWORD% msiexec /x   %DEST_PATH%\%UNST_VER%\backburner.msi /qn

rem install backburner %INST_VER%

call psexec \\%%A -u %DOMNAME%\%USERNAME% -p %PASSWORD%  xcopy %INST_PATH% %DEST_PATH%\%INST_VER% /S /Y /I
call psexec \\%%A -u %DOMNAME%\%USERNAME% -p %PASSWORD% msiexec /i   %DEST_PATH%\%INST_VER%\backburner.msi /qn

)

GOTO END

:NOHOST
echo  ホストファイルを指定してください。
GOTO END

:NOHOSTFILE
echo ホストファイル%1が見つかりません。

:END
```

あとは下のようにホストのリストファイルを引数にバッチファイルを起動すればターゲットのホストのbackburner 2015がアンインストールされてbackburner 2017がインストールされます。

```
C:\Users\backburner> bb_update.bat hosts_list.txt
```
FFmpegでH265からVP9&Opus動画へのエンコード実験

たぶん2016/11/02現在では最先端のコーデック(対抗でMozillaのDaalaもありますが)である、VP9(映像)&Opus(音声)エンコードの実験をしてみました。
Windows10上でVirtualBoxを使い、ubuntu-16.10-desktop-amd64を動かしています。

特に記事にするつもりはなかったので、正確な手順は残していないです。apt-getでlibavutilをremoveして再installしてみたりもしたのですが、影響があるかはわかりません。

では手順。
最新のソースを持ってきます。
```
git clone https://github.com/FFmpeg/FFmpeg
git clone https://chromium.googlesource.com/webm/libvpx
git clone https://git.xiph.org/opus.git
```

コンパイル。
libvpxは普通の手順で、opusはautogen.shを実行しないとconfigureスクリプトが生成されなかったような気がしますが、特に問題なく入りました。
FFｍpegは実験用ということで、以下のオプションでconfigureしています。
```
../configure --enable-shared --disable-gpl --enable-libvpx --enable-libopus --enable-avresample --enable-swresample
```
sharedはあってもなくても良かったのですが、とりあえずenable、
gplは試しにdisable、
vpxとopusを指定、
「swresampleよかavresampleの方が良いぜ」って見た記憶があるんですが、avresampleだけだとインストール後の実行時にオーディオ関連で「'aresample' filter not present」というエラーが出てしまうため、swresampleも指定しました。

なお、
--enable-pic
は、
--enable-shared
と連動するので指定不要なはず。

そしてコンパイルして
```
ffmpeg
```
を実行すると、共有ライブラリ(～～.so)にav_vdpau_get_surface_parametersが無いとか言われます。
もう少し調べると該当コードの複数ディスプレイ対応に問題がある模様。ソースを調べると該当部分が、
MAKE_ACCESSORS
と言うマクロ(?)に変わっていました。
なので呼び出し側であるlibavcodec/vdpau.cのav_vdpau_get_surface_parametersをMAKE_ACCESSORSに変更したところ、コンパイルできました。
ただし、何が変わっているのかまでは調べていません。

```
ffmpeg -i input.mp4 -c:v libvpx-vp9 -pass 1 -b:v 0 -crf 33 -threads 8 -speed 4 \
  -tile-columns 6 -frame-parallel 1 \
  -an -f webm /dev/null
```
で1パス目のエンコードが始まります。例示されていた設定をそのまま使ったので、不適切な部分もあるかと思います。

パフォーマンスはinputがhrvcの4.5mbps(2704x1520)、core i-7 4770k、通常画質で1パス目が3fps程度。
VirtualBoxを1コアで使っているので、4コア全部割り当てれば12fpsくらいになるのでしょうか?
現時点(2016年)での最新最強環境でも、1CPUでリアルタイムエンコードは難しいですね。
しかも、これまだ1パス目だし。

続いて2パス目
```
ffmpeg -i input.mp4 -c:v libvpx-vp9 -pass 2 -b:v 1400K -crf 23 -threads 8 -speed 2 \
  -tile-columns 6 -frame-parallel 1 -auto-alt-ref 1 -lag-in-frames 25 \
  -c:a libopus -b:a 64k -f webm output.webm
```
0.9fpsでした。リアルタイムどころか、実用性すら危ぶまれる数字ですね。今後の改良に期待しましょう。GPUを使えば、いきなり処理能力が1000倍になったりすることもありますし。GPUが使えるアルゴリズムなのかまでは調べていませんが、この手の処理ならば使えないことはないと思いますし、Googleなら何か手は打っているでしょう。それが有料クラウド利用が前提だったりする可能性は十分にありますが。

結果、ファイルサイズは423MBから713MBに、って増えてるじゃねーかっ。どうやら元のファイルよりビットレートが高い設定になっていたようです。

デコードはエンコードした環境(VirtualBox)で画像は出るものの、何故か再生ができない(シークはできて、画像もシークした所に更新される)状態になっていました。
WindowsからMPC-HCで再生した場合は正常に再生され、CPU負荷は8%程度でした。

画質はブロックノイズが乗らない分、元ファイルより良くなったように感じるところもありました。ブロックノイズが乗っていた所がぼかされていたため、内部に「ブロックノイズ除去フィルタ処理」みたいなのが入っているのかもしれません。

現状はエンコードのパフォーマンスが問題ですね。YouTubeの様に一回エンコードして、あとは配信するだけという用途になら、エンコード速度はそれほど重視されないかもしれませんが、軽いに越したことはないでしょう。今後の改良を期待したいところです。
Yocto ビルド並列数の調整方法

Yoctoビルドが重いので、CPUの制限方法を残します。

local.conf に以下を記述する。
※ `bitbake` コマンドを行うディレクトリの下に `conf/local.conf` であります。

```bash:local.conf
BB_NUMBER_THREADS = '2'
PARALLEL_MAKE = '-j 2'
```

### BB_NUMBER_THREADS:
並列するレシピ数を指定します。

### PARALLEL_MAKE:
コンパイル時に使用するコア数を指定します。
スタートアップ時にインポート中のモジュールを表示

ご存知の通りホームディレクトリ上の
`~\.ipython\profile_default\startup\startup.ipy`
なるものにpythonコード入れておくと、IpythonやJupyter起動したときに自動的に実行してくれる。

その際、よく入れるコマンドとしてnumpyやpandasのインポートを行う。

```python:startup.ipy(改良前)
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns  # <- matplotlibの強化版
```


しかしながらいくつもインポートしてると、インポートに時間がかかったりして今何をインポートしているのか見えづらいのが少し気にかかった。
そこで、`import`を`exec`で実行してやって、インポート中のモジュールを`print`するように改造した。

```python:startup.ipy(改良後)
__modules__ = ('numpy',
           'pandas',
           'matplotlib.pyplot',
           'seaborn')
__standfor__ = {'numpy': 'np',
            'pandas': 'pd',
            'matplotlib.pyplot': 'plt',
            'seaborn': 'sns'}

for __module__ in __modules__:
    __execution__ = 'import %s as %s' % (__module__, __standfor__[__module__])
    print(__execution__)
    exec(__execution__)
```

こうすることで、Ipython立ち上げる時に、真っ暗画面の裏でpythonが何をやっているのかわからない状態によるストレスから解放されました。
おしまい。



更新2016/11/12
`__hogehoge__`のようにアンダーバー二つでくくると外部から見えなくなる。
影響ないと思うけど、後になって「指定した覚えのないmoduleとかstandforとかいう変数ナンダ？？？」ってならないようにする措置。
AWS CLIをMACにインストールする


## はじめに
自分のMACにAWS CLIを設定した時のメモになります。
詳しくはここの通り。そのまま実行しただけです。

http://docs.aws.amazon.com/cli/latest/userguide/installing.html#install-bundle-other-os

## 概要

1. pythonバージョンの確認
2. ダウンロード
3. インストール
4. パスを通す
5. コンフィグ設定

## 詳細
----
#### 1. pythonバージョンの確認
Python使用するみたいですのでバージョンの確認をします。
```
$ python --version
Python 2.7.10
```

----
#### 2. ダウンロード

ダウンロードしてunzipをします。

```
$ wget https://s3.amazonaws.com/aws-cli/awscli-bundle.zip
$ unzip awscli-bundle.zip
Archive:  awscli-bundle.zip
  inflating: awscli-bundle/install   
  inflating: awscli-bundle/packages/awscli-1.11.11.tar.gz  
  inflating: awscli-bundle/packages/jmespath-0.9.0.tar.gz  
  inflating: awscli-bundle/packages/simplejson-3.3.0.tar.gz  
  inflating: awscli-bundle/packages/ordereddict-1.1.tar.gz  
  inflating: awscli-bundle/packages/s3transfer-0.1.9.tar.gz  
  inflating: awscli-bundle/packages/rsa-3.4.2.tar.gz  
  inflating: awscli-bundle/packages/futures-3.0.5.tar.gz  
  inflating: awscli-bundle/packages/docutils-0.12.tar.gz  
  inflating: awscli-bundle/packages/colorama-0.3.7.zip  
  inflating: awscli-bundle/packages/argparse-1.2.1.tar.gz  
  inflating: awscli-bundle/packages/pyasn1-0.1.9.tar.gz  
  inflating: awscli-bundle/packages/virtualenv-13.0.3.tar.gz  
  inflating: awscli-bundle/packages/botocore-1.4.68.tar.gz  
  inflating: awscli-bundle/packages/python-dateutil-2.5.3.tar.gz  
  inflating: awscli-bundle/packages/six-1.10.0.tar.gz  
```
----
#### 3. インストール

AWS CLIをインストールします。
```
$ sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws
Password:
Running cmd: /usr/bin/python virtualenv.py --python /usr/bin/python /usr/local/aws
Running cmd: /usr/local/aws/bin/pip install --no-index --find-links file:///Users/hara/awscli-bundle/packages awscli-1.11.11.tar.gz
You can now run: /usr/local/bin/aws --version
```
----
#### 4. パスを通す

実行しやすいようにパスを通します。
```
$ vim ~xxx/.bash_profile
export PATH=/usr/local/aws/bin:$PATH
$ source ~xxx/.bash_profile
$ aws help
```

----
#### 5. コンフィグ設定

AWS CLIのコンフィグを設定します。
```
$ aws configure
AWS Access Key ID [None]: XXXXXXXXXXXXXXXXXXX
AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXXX
Default region name [None]: ap-northeast-1
Default output format [None]: ENTER
```
Smarty3でnl2brしつつXSSを避ける書き方 の処理について、自己解釈


[Smarty3でnl2brしつつXSSを避ける書き方](http://qiita.com/suin/items/52c4a653cba7acb694b4)をみて、なるほどって思ったので、どういう風に自己解釈したのか書く。

## 書いたコード
確認で、こんな感じのコードを書いた。

```php:index.php
<?php
$smarty = new Smarty();
$smarty->default_modifier = ['escape'];

$smarty->assign('a', '<h1>title</h1>
this is summary
');

$smarty->display('index.tpl');
```

```smarty
{{$a}|nl2br nofilter}
{*
  1. $a with default_modifire
  2. nl2br whithout default_modifier
*}
```

1. 内側から処理されるっぽい。
2. まず、`{$a}` を処理する。
    * このとき、`nofilter` はないので、普通に`default_modifier`が適用される。
    * 結果、`<h1>`とかはエスケープされる。
3. 次に、`nl2br`される。
    * この結果に対しては、`nofilter` が指定されているので、エスケープされない。
    * 結果、改行コードは`<br />`に置換される。