OmniAICreator/Qiita-1.07M huggingface dataset:
qmakeを使ってQtアプリのソースからIDやKEYを秘匿してみる

Twitterクライアントやその他公開されてるAPIにアクセスするアプリを作る時、サービス側にアプリを登録してIDやKEYを発行してそれをクライアント側に組み込むなんてのはよくある話だけど、GitHubとかでソースを公開する時にこれが丸々公開されちゃうのはあまりうまくない。

そんなことは言うまでもないのでみんないろいろな方法で公開されたソースコードに直接IDやKEYが載らないように工夫してるんだと思うんだけど、QtCreator使ってQt(QML)アプリを書くにあたって使える方法の一つを試してみた。

#qmakeの追加オプションでID/KEYを指定する
IDやKEYに限らず、ソースのあちこちで使う可能性があって且つ後で変更する可能性があるような定数は\#defineで定義しちゃったりするのかなと思う。

```cpp:
#define ID 'foo'
#define KEY 'bar'
```
これはgccの-Dオプション等、ビルド時コンパイラに渡すことで直接ソースに書かなくても指定できる。

```
gcc -DID=¥"foo¥" -DKEY=¥"bar¥"
```
で、Qtの場合qmakeでMakefileを生成する（という説明で合ってるのかな?）ので、qmakeにそういうオプションを付けろという指示をしてあげる事になる。
その手のことはいちいちコマンドラインオプションで書くのは大変なので、原則はプロジェクトファイル(*.pro)に書くんだけど、今回の目的は「公開されているソースに載せない」ことなので、コマンドラインオプションとして追記する。

```
qmake 'DEFINES+=ID=¥¥¥"foo¥¥¥" KEY=¥¥¥"bar¥¥¥"'
```
注意するのは「"」の受け渡し。文字列としてコンパイラオプションに渡す時には「¥"」で囲まないとダメっぽいので「¥」と「"」をそれぞれエスケープして「¥¥」「¥"」として渡す。

#QtCreatorで使うとき
プロジェクトを開いた状態で「プロジェクト」→「ビルドステップ」→「qmake」を開いて「追加の引数」にDEFINESを書いとけばいい。上に書いたように複数渡す時にはスペース入れたりするから、全体を「'」で囲んで書いておこう。

```
'DEFINES+=ID=¥¥¥"foo¥¥¥" KEY=¥¥¥"bar¥¥¥"'
```
#うまくいかないとき
OSやQt(QtCreator)のバージョンに依っては単純に上の文字列を追加しても¥や"が意図した通りに処理されなくて「-DID=foo」とか「-DID="foo"」のようになり、C++のソース側でちゃんと文字列として扱ってもらえなくなるケースがあった。そんな時はプロジェクトファイルに

```
DEFINES += ID=¥¥¥"$$_ID¥¥¥" ¥
                   KEY=¥¥¥"$$_KEY¥¥¥"
```
のようにしておいて、qmakeへのオプションは

```
_ID="foo" _KEY="bar"
```
としておけばうまく渡せるっぽい。

#渡したID/KEYをQMLで使う
C++で書く分にはID、KEYという定数として使えばいいんだけど、QtQuickアプリで使いたいならQQmlContextを使って渡せばいいらしい。

```cpp:main.cpp
...
#include <QQmlContext>
...
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("app_id", ID);
engine.rootContext()->setContextProperty("app_key", KEY);
```
こうしておくと、QML側で「app_id」「app_key」というプロパティが使えるようになる。

#QtCreatorでqmakeに渡す追加オプションはどこに保存される？
プロジェクトファイル(*.pro)とは別に個別の環境で生成されるユーザファイル？(*.pro.user)があって、こっちに他のローカル設定と一緒に保存されてる。プロジェクト生成時にバージョン管理を指定しても（手動で明示的に追加しない限りは）gitの管理範囲外になるし、環境毎に生成されるファイルだから公開されるソースに含まれていなくても全く支障はない（というか、普通は公開しないファイルだし）。

#〆
とゆーことで、わりと簡単にソースコードから生のID/KEYを取り除くことができた。
ただ、GitHubから取得したソースでは当然ビルドが通らなくなるから、どうやってID/KEYを指定すればいいかreadme.txtなりソース中のコメントなりで説明しといた方がいいと思う。
ffmpegで複数のflvを結合してmp4にする方法

いつも魔法の呪文を忘れるので

```
ffmpeg -i file1.flv -i file2.flv -filter_complex "concat=n=2:v=1:a=1" output.mp4
```

* -filter_complex オプションで連結の指定  
 concat=  
   - n=連結するファイル数（デフォルト: 2）
   - v=ビデオ ストリーム数（デフォルト: 1）
   - a=オーディオ ストリーム数（デフォルト: 0）
LTEモデムを繋いだラズパイにSSH接続したいのでVPNを使う

![VPS_VPN.png](https://qiita-image-store.s3.amazonaws.com/0/133915/582cf7ef-d87b-0ae5-ab68-b0eb7d747fea.png)


LTEモデムでインターネットにラズパイを接続するのですが、自分の使用しているSIMでは外部からSSH接続は出来ないです。
~~面白そう~~という訳でOpenVPNを使います。([SORACOM Gate](https://soracom.jp/services/gate/)も使ってみたいのですが、、、)

#LTEモデムの導入
まずはLTEモデムの導入ですが、L02Cがあるのでそれを使用します。
導入は下記の記事を参考にさせていただきました。
[MVNOの格安SIMを使ってRaspberry PiでLTE3Gモバイルルータを作ってみよう！](http://sideb.hatenablog.com/entry/mvno_kakuyasu_sim_raspberry_pi_lte_3g_mobile_router)
上記サイトの手順以外の方法でも良いので、起動時にモデムの自動接続するようにしておきます。

#OpenVPNの導入
自動でLTE接続ができるようになったところで、今度はVPN接続を行います。
[OpenVPN](https://www.openvpn.jp/document/how-to/)を使用します。
自宅のラズパイをVPNサーバにしても良いのですが、ハイポートを指定するにしても環境を開ける事にちょっと抵抗があるので、今回はconohaのVPSにLTE回線のラズパイと自宅のラズパイからVPN接続します。
導入手順は下記が参考になりました。
[VPNサーバー構築(OpenVPN)](https://centossrv.com/openvpn.shtml)


##VPNサーバ側の設定
デバイスはtunを使用。
クライアント同士の接続を許可します。

```server.conf
port 1194
proto udp
dev tun
ca /etc/openvpn/ca.crt
cert /etc/openvpn/server.crt
key /etc/openvpn/server.key
dh /etc/openvpn/dh.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
client-config-dir /etc/openvpn/ccd
client-to-client #クライアント同志での接続を許可
duplicate-cn
keepalive 10 120
tls-auth ta.key 0
cipher AES-256-CBC
comp-lzo
user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log
log-append  openvpn.log
verb 3
explicit-exit-notify 1
management localhost 7505
crl-verify /etc/openvpn/crl.pem
```

アクセス環境の設定についてはopenvpn-start.shなど設定スクリプトは用意せずにiptablesの設定ファイルに直接書き込みiptablesの自動起動時に設定されるようにします。

```txt:iptables
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
#接続が確立したものについては通信を許可
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#ループバックアドレスからの接続を許可
-A INPUT -i lo -j ACCEPT
#特定環境からのSSH接続を許可
-A INPUT -s XXX.XXX.XXX.XXX/32 -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
#VPN接続を許可
-A INPUT -m state --state NEW -m udp -p udp --dport 1194 -j ACCEPT
#VPNの接続許可
-A INPUT -i tun+ -j ACCEPT
#vpnの転送許可設定
-A FORWARD -o tun+ -j ACCEPT
COMMIT
```

クライアントのIP固定方法(クライアント毎に証明書などを用意する必要があります。)
サーバの`/etc/openvpn/ccd`配下にクライアント毎に下記のファイルを作成
今回は自宅のラズパイをclient1にして`10.8.0.5`のIPを付与、LTE回線側のラズパイをclient2にして`10.8.0.9`に固定IPを付与します。

```txt:client1
ifconfig-push 10.8.0.5 10.8.0.6
```

```txt:client2
ifconfig-push 10.8.0.9 10.8.0.10
```

##VPNクライアント側の設定(自宅のラズパイとLTE回線側のラズパイ)
クライアント証明書・秘密鍵はパスフレーズ無しで自宅のラズパイ、LTE回線側のラズパイの2台分作成しておきます。

```client.conf
client
dev tun
proto udp
remote XXX.XXX.XXX.XXX 1194　#ここはVPNサーバのアドレス
resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun
ca /etc/openvpn/ca.crt
cert /etc/openvpn/clientX.crt
key /etc/openvpn/clientX.key
tls-auth /etc/openvpn/ta.key 1
cipher AES-256-CBC
comp-lzo
verb 3
```

LTE回線側ラズパイのiptables設定

```txt:rules.v4
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
#接続が確立したものについては通信を許可
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#ループバックアドレスからの接続を許可
-A INPUT -i lo -j ACCEPT
#VPNローカルアドレスからのSSH接続の許可
-A INPUT -m state --state NEW -p tcp -s 10.8.0.0/24 --dport 22 -j ACCEPT
COMMIT
```

書いてませんが、サーバ側のVPN、SSHポートはハイポートにしておくといいです。
これで自宅の環境からラズパイにSSH接続を行う事が可能となります。
[失敗]V-USBでADB USB変換

Arduinoで使われているAVRでソフトウエアでUSBをサポートするための[V-USB](https://www.obdev.at/products/vusb/index.html)というコードがあり時々使っているが、これを使ってAppleが昔作っていたADB(Apple Desktop Bus)のキーボードを使えるようにする変換モジュールを作ってみたがうまくできなかったので、メモを残しておきます。

ADBはApple IIgsから使われるようになった低速のキーボードなどをコンピュータにつなぐためのインターフェースです。MachintoshはSEから採用しました。このインターフェースは4線で数珠つなぎに接続する事ができました。Appleは初代iMacでUSBを採用してADBを止めました。

ADBはパソコンからキーボードなどの機器にコマンドを送ってキーボードの状態を拾いだしています。


![ADB FIG1.png](https://qiita-image-store.s3.amazonaws.com/0/104066/0a056d3a-f76b-3997-1294-bb45a87ed565.png)


Guide to the Macintosh®Family Hardwareより

コマンドは1bitおおよそ100uSで全体で1mSくらいとなりデータも1バイト1mSくらいとなります。

1はLoが35uSでHiが65uSで0がLoが65uSでHiが35uSとなります。

キーボードは1バイトのTalkコマンドで2バイトのデータが返ってくるので3mSくらいの処理になります。

この処理を実装してみたのですが、ときどき化けてしまいます。1と0の差が30uSなので10uS程度のバッファがあるのですがV-USBの割り込みがこれを越えてしまう事があるようです。100文字入力して1文字が化けるような状態で実用になりません。

githubに[adb-v-usb](https://github.com/gblargg/adb-v-usb)という実装があって、V-USBの割り込みを待って処理するように実装されているようです。これのREADMEにV-USBには100uSな割り込み処理があるって書いてあります。コードはかなり複雑になってしまっています。

V-USBでタイミングクリティカルな実装は上記のように頑張んなければいけなくあまり向いていないのかもしれません。

ADB USB変換は製品や、オープンソースのいろいろな実装がありますが、adb-v-usbの人がUSBのハードウエアサポートがあるAVRで[adb-usb](https://github.com/gblargg/adb-usb)というコードも作られていて、こちらはとくにトリッキーな事はしていなくて、AT90USB162で作ってみて、実用的に使えました。

![写真（2024-11-04 10.57） #2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/c620f35d-e69b-79f7-c662-ad33a88f61ef.jpeg)

Macintosh Classicに付いていたApple Keyboard IIが使えないので調べてみました。

Apple Keyboard IIはナショナルセミコンダクタのワンチップマイコンのINS8048を使っていて、DB0-DB7にパルスを発生してそれをP10-P17,P20-P26で受けてキーをスキャンします。クロックはセラロックで6MHzです。T1とP27がトランジスターを挟んでADBの信号線に接続されています。T0はジャンパーでスイッチになってます。

どうもINS8048が起動しなくなっているような感じです。まれにスキャン信号がでることもあるのですが、ほとんどダメです。経年劣化で故障してしまったのかもしれません。
Arduino Yunの使い始め方が変わったと思ったら古いバージョンだった

2016年9月末現在、仕様が変わってたっぽく、自分の買ったArduino Yunが古いのか、やり方が違ったのでメモ。
ざっくりとまとめると最初"arduino"という名前を使ってなく、"linino"を使用しています。

# Arduino Yunとは、とこれまでの使い方
参考先
http://qiita.com/shozaburo/items/fa07bbb2c24ea6bd371b

# 公式URL
http://www.arduino.org/learning/getting-started/getting-started-with-arduino-yun

# 更新後の使い方
参考先がわかりやすかったので、その書き方で公式URLの日本語化
<li> Micro USBで電源供給する
<li>しばらくすると自分のPCにWifiのSSID "Linino-XXXXXXXX"が見えるので選択
<li>繋いだらブラウザで "http://linino.local/" にアクセス
確かsafariはだめだった
<li>パスワードは"doghunter"
<li>"CONFIGURE"を押すと、無線LANの設定画面にいくので、そこから繋ぎたい無線LANのSSIDを選択、パスを入力して”configure & restart”
タイムゾーン設定もあり
<li>Arduinoに設定したものと同じネットワークにPCを繋ぎなおし、再度 "http://linino.local/" にアクセス。きちんとつながれば設定終了

その後、公式ではSSH接続からアップデートを行っています。
そのアップデートを行った場合、参考URLと同じSSIDが見え、同じ設定ができます。
つまり冒頭でも書いた通り古いバージョンだっただけだが、wifiで"Arduino-XXXX"のものが見つからず焦るというお話でした。
Promiseを直列実行するちょっとしたhack

## やりたいこと

* `Promise`を一つずつ順番に実行する (並列ではなく直列に実行)
* `Promise`の開始は非同期で行う (メイン側のコードは止まらない)

## サンプルとなるPromise

``` js
const create = v => new Promise(resolve => {
    console.log(`create ${v}`)
    setTimeout(() => {
        console.log(`done ${v}`)
        resolve(v)
    }, 1000)
})
```

`create`は、1秒待つという`Promise`を生成する関数だ。これを実際の処理、たとえばHTTPを取ってくる`Promise`だったりとかに置き換える事になる。

## 今回の目的を果たす関数

``` js
/**
 * creator()が生成するPromiseを非同期かつ直列的に実行する
 * var creator  Promiseを返すコールバック
 * return       creatorが生成したPromise
 */

let p = Promise.resolve()
const doSerial = creator => p = p.then(creator)

```

`p`は、直列に実行する為の`Promise`を保持をする為の変数だ。実行時に書き換える必要があるので`const`ではなく`let`で定義している。

``` js
doSerial(() => create('p1')).then(res => console.log(res))

doSerial(() => create('p2')).then(res => console.log(res))

doSerial(() => create('p3')).then(res => console.log(res))
```

`doSerial(creator)`は`creator`の生成する`Promise`が帰ってくるので、そこに`then`をつなげることで処理ができる。

## ポイント

`create()`を実行する、つまり`new Promise()`でインスタンスを生成した段階ですでに`setTimeout()`が走ってしまう。そのため、直列に実行しようと思うと、そもそも`create()`自体を制御の中で直列実行する必要がある。そのため、`doSerial(creator)`の`creator`引数で、`Promise`生成関数を渡すという、多少面倒な事をしなければならない。

次に、`Promise`にぶら下げる`then`は、実は平行でぶら下げることができる。その場合複数ぶらさげた`then`はそれぞれ平行で走ることになる(JSの仕組み上順列はあるにせよ)。つまり、`setTimeout`を待つ`Promise`ならば、`setTimeout`が完了してから、それらの`then`が並列で走る。

``` js
const p = Promise.resolve()

const p1 = p.then(() => create('p1'))
p1.then(res => console.log(res))

const p2 = p1.then(() => create('p2'))
p2.then(res => console.log(res))
```

展開するとしたら、このようなコードになる。`p1`は、`create('p1')`を行う`Promise`だ。元々`Promise.resolve()`で生み出されてるので、待ちが発生せずにいきなり`create('p1')`が実行される。そして`p1`には二つの`then`がぶら下がっている。まずは`p1.then(res => console.log(res))`という、本来実行したかった処理の方だ。もちろんこの後にさらにいくつもの`then`や`catch`をつなげることもできる。

もう一つの`then`は `const p2 = p1.then(() => create('p2'))` というもので、`p1`の結果を待って、次の`create('p2')`を行うものだ。

## おさらい

``` js
const create = v => new Promise(resolve => {
    console.log(`create ${v}`)
    setTimeout(() => {
        console.log(`done ${v}`)
        resolve(v)
    }, 1000)
})

let p = Promise.resolve()
const doSerial = creator => p = p.then(creator)

doSerial(() => create('p1')).then(res => console.log(res))
doSerial(() => create('p2')).then(res => console.log(res))
doSerial(() => create('p3')).then(res => console.log(res))
```
SendGrid Web API v3をrubyから使って、複数人にメールを送る方法


こちらのgemを使って複数人に同じ内容のメールを送る方法です。
https://github.com/sendgrid/sendgrid-ruby

githubのREADMEには一人に送る例しか書かれていなかったため、以下のサンプルコードを見ながら書いてみました。
https://github.com/sendgrid/sendgrid-ruby/blob/master/examples/helpers/mail/example.rb

```ruby
mail = SendGrid::Mail.new
mail.from = SendGrid::Email.new(email: 'test@example.com')
mail.subject = 'title'

personalization = SendGrid::Personalization.new
personalization.to = SendGrid::Email.new(email: 'test1@example.com', name: 'test1 user')
personalization.to = SendGrid::Email.new(email: 'test2@example.com', name: 'test2 user')
personalization.to = SendGrid::Email.new(email: 'test3@example.com', name: 'test3 user')

mail.personalizations = personalization

sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'], host: 'https://api.sendgrid.com')
response = sg.client.mail._('send').post(request_body: mail.to_json)
```

Personalizationオブジェクトを作ってそこにメールアドレスを登録していきます。
ccやbccの登録も同様にPersonalizationオブジェクトに対して行います。

```ruby
personalization.cc = SendGrid::Email.new(email: 'test_cc@example.com', name: 'test cc user')
personalization.bcc = SendGrid::Email.new(email: 'test_bcc@example.com', name: 'test bcc user')

```
MyBatisのLazy Load + Jacksonでシリアライズエラーになる件の回避方法

MyBatisのLazy Loadが適用されているオブジェクト(MyBatis内蔵のJavassistのProxyオブジェクト)を、Jacksonを使ってJSONにシリアライズしようとすると以下のようなエラーが発生することが報告されています。(https://github.com/mybatis/mybatis-3/issues/570)

```
com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.apache.ibatis.executor.loader.javassist.JavassistProxyFactory$EnhancedResultObjectProxyImpl and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: org.apache.ibatis.submitted.javassist.User_$$_jvst15a_0["handler"])

	at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:284)
	at com.fasterxml.jackson.databind.SerializerProvider.mappingException(SerializerProvider.java:1110)
	...
```

> **Note:**
>
> MyBatisは、JavassistをMyBatisのJarの中に内蔵するスタイルを採用しており、パッケージもMyBatis配下のパッケージ(`org.apache.ibatis.javassist`)にリパッケージしています。なので・・・本投稿の中で出てくるJavassistのインタフェースのパッケージは`org.apache.ibatis.javassist`であるという点に注意してください！！



これは、Proxyオブジェクトの中で保持している`MethodHandler`型の`handler`プロパティ(Proxyのメソッドを呼び出した時のハンドリングを行うためのオブジェクト＝Lazy Load処理を制御するオブジェクト)を、JSONにシリアライズしようとして発生しています。
原因はスタックトレースにも出力されている通り、`MethodHandler`の実装クラス(`org.apache.ibatis.executor.loader.javassist.JavassistProxyFactory$EnhancedResultObjectProxyImpl`)をシリアライズするためのクラスが見つからなかったためです。

解決方法はいくつかありそうですが・・・本投稿では、

* `@JsonIgnore`を付与したインタフェースを作り
* `@JsonIgnore`を付与したインタフェースをJavassistの`Proxy`インタフェースにMix-inさせる

ことで、シリアライズが不要な`handler`プロパティをシリアライズ対象から除外する方法を紹介したいと思います。

# 動作検証バージョン

* MyBatis 3.4.2
* Javassist 3.21.0-GA (MyBatis内蔵のJavassist)
* Jackson 2.8.5 (2.4.4+が必須)

# `@JsonIgnore`を付与したインタフェースを作る

まず、`@JsonIgnore`を付与したインタフェースを作ります。

```java
public interface MyBatisJavassistProxyMixIn {
	@JsonIgnore MethodHandler getHandler(); // @JsonIgnoreを付与してhandlerプロパティをシリアライズ対象外に指定する
}
```

> **Note:**
>
> メソッドの返り値の型は、実はあまり意味がなく・・・`Object`や`void`でも動作します。ここでは実体にあわせて`MethodHandler`にしています。

# `Proxy`インタフェースに`@JsonIgnore`を付与したインタフェースをMix-inする

次に、`@JsonIgnore`を付与したインタフェースをMyBatis内蔵のJavassistの`Proxy`インタフェースにMix-inします。

```java
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.addMixIn(Proxy.class, MyBatisJavassistProxyMixIn.class); // Mix-in !!
```

こうすると・・・・
MyBatis内蔵のJavassistの`Proxy`インタフェースを実装したクラスの`handler`プロパティを、シリアライズ対象から除外することができます。


# まとめ

特にないのですが・・・:sweat_smile:
Jacksonに限らず・・・MyBatisのLazy Loadが適用されているオブジェクトをJSONにシリアライズする場合は、同様の問題が起こる可能性がありそうな気がするので、特定のプロパティをシリアライズ対象から除外する方法を事前に調べておくとハマらなくてすみそうです。
あと・・・MyBatisはCGLIBを使ったProxyもサポートしてるけど、今回は未検証です（あしからず・・・）。

# 参考サイト

* https://github.com/mybatis/mybatis-3/issues/570
* http://qiita.com/rch850/items/30825e6ff0811fdc011d
ショートカットを活用しよう - 7 - Win + L

# <kbd><kbd>Win</kbd> + <kbd>L</kbd></kbd> の効果
* <kbd><kbd>Win</kbd></kbd>はWindowsのロゴマークのキーのことです。（大抵のキーボード配列で左下の<kbd><kbd>Ctrl</kbd></kbd>のとなりにありますよね。）

Windowsをロックします。ちょっと席を離れる際などに。
職場によっては必須行為とされているところもあるのではないかと思います。

以上

|前回|方針|次回|
|:--|:--:|--:|
|[<kbd><kbd>Win</kbd> + <kbd>E</kbd></kbd>](http://qiita.com/rrryutaro/items/60fc01ec753a25ffecf8)|[記事の方針](http://qiita.com/rrryutaro/items/74d60a6e31ff149c5710)|[<kbd><kbd>Shift</kbd> + <kbd>F10</kbd></kbd>](http://qiita.com/rrryutaro/items/306247e6e878fb155462)|
Emacsで認証付きProxy越しにパッケージ管理する

``HTTP_PROXY``環境変数だけでなんとかしたい。

# 背景
認証付きのProxyサーバー越しに、MelpaなどのPackage Repositoryにアクセスする場合、下記のリンクのような方法をとるのがよく見られるような気がする。

- [Proxy経由でEmacsのパッケージ管理を使う](http://yoshimov.com/tips/emacs-package-list-with-proxy/)
- [プロキシ環境と非プロキシ環境でEmacsのpackage.el設定を共有する](http://qiita.com/ytoda129/items/9252678c65187296b9a3)

しかし、他の多くのソフトウェア（例えば、gitやyumなど）は、環境変数``HTTP_PROXY``を参照して、アクセスしてくれるのに、なんとなくemacsだけこのような方法を取るのが、気になってきた。

因みに、認証なしの場合は、``HTTP_PROXY``の設定だけでアクセスが可能である。 
正確には、認証付きの場合でも、認証情報を含めないURLを``HTTP_PROXY``に設定しておいて（username:passwordの部分を含めないで）おけば都度（起動ごと？）にユーザーIDとパスワードを聞かれるので入力すれば可能である。

# やったこと

というわけで、やったこととしては、起動時に``HTTP_PROXY``の設定の有無を確認して、URLをパースして設定するようにしました。

```lisp:init.el
;; Proxy setting
(cond ((getenv "HTTP_PROXY")
       (let* ((url_ (url-generic-parse-url (getenv "HTTP_PROXY")))
              (auth_ (if (and (url-user url_) (url-password url_) )
                         (base64-encode-string
                          (format "%s:%s" (url-user url_) (url-password url_)))
                       nil))
              (host_ (format "%s:%s" (url-host url_) (url-portspec url_))))

         (defvar url-proxy-services
               (list (cons "no_proxy"  "^\\(localhost\\|10.*\\)")
                     (cons "http" host_)))
         (if auth_
             (defvar url-http-proxy-basic-auth-storage
               (list (list host_ (cons "Proxy" auth_)))))
         )))

```

一応これで、動いているっぽい。

書いていて、迷ったというか妥協したところ。

* 認証なしのURLがHTTP_PROXYがに設定されている場合、ちゃんと動くかわからないが、手元にそういう環境がないため、気にしないことにする
* 参考リンクだと、`url-proxy-services`への設定は``setq``でおこなっているのだが、flycheckを使っていると"assignment to free variable `url-proxy-services'"というWarningがでる。そういう場合は``defvar``にしろと書いてあったので、そうしたが、正しい対処法だろうか？
    * もしかして: ``setq-default``

# 別解答

[CNTLM](http://stackoverflow.com/questions/2783267/how-to-configure-emacs-behind-an-authenticated-http-proxy)などを使って、ローカルに認証を回避するProxyサーバーを立てるという解も考えられるかと思います。前述の通り、認証がなければもともとHTTP_PROXYだけで行けるはずなので。

環境変数設定だけでできる方がポータブルかな？と思ったのですが、URLにパスワードの平文を埋め込む方式だと.zshrcなどに記述すると、社外のリポジトリなどに置くのがためらわれるという難点もあるため、この方法も良さそう。
OpenCV入りJupyter NotebookのDockerfile

# Anaconda最高！！

Anacondaに感動したので、
メモをかねて残そうかと思いました。
(知るのがちょっと遅かった。。。)

昔OpenCV入れるのに、
gitからソース取ってきて、cmakeして...っていう通常の流れをして、
(VM上で行っていたこともあり)リソース足りなくて失敗した、とか
成功しても非常に時間がかかった、という辛い経験があったのですが
Anaconda(conda)だと簡単に入れられました。

Anacondaのインストールの際には
ほかにもnumpy,scipy等々絶対使うだろ！ってものも入ってくるのですね！

# Dockerfile

Dockerfile書いたので
同じように辛い思いをした方がいれば参考になれば幸いです。

```bash
FROM ubuntu:16.04

RUN apt-get update && \
                    # for Anaconda
    apt-get install -y wget bzip2 \
                    # for OpenCV
                       libgtk2.0-0

# Anaconda3-4.2.0 install
RUN wget https://repo.continuum.io/archive/Anaconda3-4.2.0-Linux-x86_64.sh && \
    bash Anaconda3-4.2.0-Linux-x86_64.sh -b && \
    rm -f Anaconda3-4.2.0-Linux-x86_64.sh

ENV PATH $PATH:/root/anaconda3/bin

# OpenCV install
RUN conda install -c https://conda.anaconda.org/menpo opencv3

# make jupyter directory
RUN mkdir /opt/jupyter/ && \
    jupyter notebook --generate-config && \
    sed -i -e "s/#c.NotebookApp.ip = 'localhost'/c.NotebookApp.ip = '*'/" /root/.jupyter/jupyter_notebook_config.py

CMD cd /opt/jupyter/ && \
    jupyter notebook
```

# 起動

蛇足かもしれませんが、ビルド&起動のコマンドです。

#### ビルド
```bash
docker build -t <image_name> <dockerfile_directory>/.
```

#### 起動
```
docker run -d --name <container_name> -p 8888:8888 <image_name>
```
PHPのAMP変換ライブラリ

#AMPのタグ変換が面倒臭い！
imgはamp-imgとかscriptタグとかstyle属性とかとかとか！
こんな変換処理いちいち書きたくないなー、誰かもうやってないかなーと思ったらありました。

## AMP PHP Library
https://github.com/Lullabot/amp-library

- DrupalのAMPモジュールで使われてるライブラリ。
- PSRにも対応してて、コマンドラインインターフェイスもある。HTMLまるっと変換できる。
- licenseはApache2

利用実績もDrupalであるし、使いやすそうでライセンス的にも問題なかったので、[concrete5 Ver5.6系のアドオン](http://c5blog.xross-cube.com/concrete5-ver-56-amp-add-on/)に使った。

## HTML to AMP HTML
https://github.com/paulredmond/html-to-amp

- licenseはGPL。これを確認した瞬間に候補から外したので中身あんまり見てない。
- タグの変換やTwitter、youtube、Instgramとかの埋め込みにも対応してるっぽい
- もちろんPSR対応。テストはspec

***
他になんかあったら教えてください。
複数の jpg ファイルをアスペクト比を保存したまま余計な余白も入れずに pdf へ変換する方法

Mac のプレビューアプリでやろうとすると余計な余白入ってしまうし、Calibre でやろうとするとあらかじめ規定された印刷サイズに合わせてアスペクト比が変わってしまうので、どうしたものかと思ってたら ImageMagick を使えばやりたいことが簡単に実現できた。便利。

```
convert image1.jpg image2.jpg image3.jpg images.pdf
```
[さくっと] dockerでお気軽mysql

# 目的

「さくっとローカルで検証したい」って時に使えるかも。

# 環境

+ Max OS EL Capitan 
+ [Docker for Mac](https://docs.docker.com/engine/installation/mac/) (Version 1.12.5)

基本的にはDockerが動く環境で使えます。

※ 記事内ではsudo無しでdockerを使ってますが、環境によって異なるのでよしなに書き換えてください。

# (早速)結果

+ runするコマンド

```text:cmd
$ docker run --name ${CONTAINER_NAME} -e MYSQL_ROOT_PASSWORD=${MYSQL_PASSWORD} -d mysql/mysql-server:5.7
```

このワンライナーで[Docker Hub](https://hub.docker.com/)から、[mysql-server 5.7](https://hub.docker.com/r/mysql/mysql-server/)をpullして、バックグランドで動かしてくれます。

+ 立ち上がったコンテナにmysql loginするコマンド

```text:cmd
$ docker exec -it ${CONTAINER_NAME} mysql -uroot -p${MYSQL_PASSWORD}
```

### 実際のデモ

コンテナ名 = iganari-db
password = hogehoge

で実際にやってみる。

```
$ docker run --name iganari-db -e MYSQL_ROOT_PASSWORD=hogehoge -d mysql/mysql-server:5.7
Unable to find image 'mysql/mysql-server:5.7' locally
5.7: Pulling from mysql/mysql-server
acdfbb1a4f2d: Pull complete
0879db9c7538: Pull complete
c47bf518d00d: Pull complete
4b2092301be6: Pull complete
Digest: sha256:06d85ad36068257137d113ede1d37623da19e91b7971068e838e8e7e1258a726
Status: Downloaded newer image for mysql/mysql-server:5.7
3b1fae616ee0763caee1b397a8ad87402529274ab30f3a15156f2d395b195260
$
$
$ docker exec -it iganari-db mysql -uroot -phogehoge
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.17 MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
```

# IPを付与して、Mysql remote login

上記だとちょっとreadmeそのままなので、コンテナにIPアドレスを付与して、プログラムからremote login出来るようにしておく。(ついでに名前解決もしてみる。)

### docker用のネットワーク(192.168.56.0/24)を作成

```
$ docker network create --subnet=192.168.56.0/24 user_defined_nw
```
+ IP:192.168.56.100のIPを固定して、docker run

```
$ docker run --name iganari-db -e MYSQL_ROOT_PASSWORD=hogehoge --net=user_defined_nw --ip=192.168.56.100 -d mysql/mysql-server:5.7
```

+ 参考
[Dockerで固定IPアドレスを使う。](http://qiita.com/paihu/items/17aa47906dd2bf935a25)


# まとめ

本当にさくっと使いたいときだけ。
ただ、ローカル開発環境のDBはこれに少し手を入れたもをimageとして固めて於いて、必要な時にrunすれば十分かな〜という感じでした。

# 追記(2017/01)

上記の「お気軽mysql」はdbが日本語入力に対応していません。
また環境変数の関係でそもそもコンソールが日本語を受け付けません。

お気軽mysqlしたいけど、日本語はもちろん対応してるよね！って方は下記を参照して下さい。

[[さくっと] dockerでお気軽mysql [日本語対応]](http://qiita.com/iganari/items/f6ef13b3ea1e47b20c65)
PowerShellでパスワード生成

新年早々、社内システムのログインパスワードを忘れてしまい、危うくロックアウトされるところでした。  

それ自体は何とかなりましたが、あと数か月もするとパスワード更新時期になります。新しいパスワード考えるの面倒だな。。。  

ということで本題。PowerShellでパスワードを生成するスクリプトを作ってみました。  

## パスワード生成といえば乱数生成
必要な桁数分、任意の文字を発生させればいいですね。PowerShellで乱数を発生させるコマンドレットは`Get-Random`になります。  

`Get-Random`はプログラム言語によくある`rand()`関数とかと違って、整数を返してくれるので便利。黙って起動すれば0から2,147,483,647までのいずれかの整数が返ってきます。  

```
(*'-') >> Get-Random
1674970342
```

生成範囲は`-Minimum`パラメーターと`-Maximum`パラメーターを使って任意に設定することができます。たとえば8から16までの任意の数を生成したければ。。。  

```
(*'-') >> Get-Random -Minimum 8 -Maximum 16
13
```

といった按配。  

更に`-InputObject`パラメーターを使うことで指定した値のリストから選択して返してくれる。自分で変換しなくていい！  

```
(*'-') >> Get-Random -InputObject "Pen","Apple","Pineapple"
Pen
```

らくちん！  

## foreachループを使ったパスワード生成
というわけで8桁から16桁までの英小文字または数字を組み合わせた任意の文字列を生成するコードはこちら。  

```
$passwd=""
foreach ($n in 1..$(Get-Random -min 8 -max 16)) {
  $passwd=$passwd+$(Get-Random -input 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z)
}
$passwd
```

パラメーター名は省略形を使っています。  

## Countパラメータを使ったパスワード生成
`-Count`パラメーターを使うとワンライナーで生成できます。  

```
(*'-') >> Write-Host (Write-Host -NoNewLine -Separator "" (Get-Random -Count (Get-Random -min 8 -max 16) -input 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z))
tubleg8fc30zra
```

ただし出力が縦に並んでしまうので、`Write-Host`コマンドレットの`-NoNewLine`パラメータと`-Separator`パラメータを使って１行に整形した後、もう一度`Write-Host`コマンドレットで行末を改行しています。ちょっとカッコ悪いですね。  

…と思ったら`-Join`演算子を使って解決できました。[stknohg](http://qiita.com/stknohg)さん、ご指摘ありがとうございました。

```
(*'-') >> -Join (Get-Random -Count (Get-Random -min 8 -max 16) -input 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z)                                                                                          
uzcfkhxd8qsj
```

いずれにしてもどちらかのコードを`$profile`あたりに関数定義しておけばいいでしょう。  

問題はパスワード更新の時期までこのことを覚えているかどうかだな。。。(´Д｀*)  

注）-Countパラメータは-Inputパラメータで指定した以上の数を出力することができません。繰り返し回数が多い場合はforeachでループさせましょう。
Proxmox VE 4.4 で KVMの起動オプションを追加 (floppy追加しXP + virtioでインストール)

## 参考

* [Floppy support [hack] | Proxmox Support Forum](https://forum.proxmox.com/threads/floppy-support-hack.3711/)

```diff:/etc/qemu-server/xxx.conf
+ args: -fda /tmp/virtio-win-1.1.16.vfd
```

## XP + virtio

* [Windows XP の準仮想化環境 | おたくの日記帳](https://turukiya.wordpress.com/2012/02/10/windows-xp-%E3%81%AE%E6%BA%96%E4%BB%AE%E6%83%B3%E5%8C%96%E7%92%B0%E5%A2%83/)
    * [virtio-win-1.1.16.vfd](https://github.com/OpenStackCookbook/OpenStackCookbook/blob/master/virtio-win-1.1.16.vfd) を使えば良いとのこと。

F6 を押して、 S 押し以下選択画面で Enter

![virtio.png](https://qiita-image-store.s3.amazonaws.com/0/25728/6d92b263-94ba-ad7a-7483-1b4039693674.png)

![virtio2.png](https://qiita-image-store.s3.amazonaws.com/0/25728/a5b08b16-2102-854b-3c17-5730e0b6ddfa.png)
Gitbookのカスタムドメインを試してみた

Gitbookでカスタムドメインを試してみました。
無料で、カスタムドメインを設定できました。

以下の通り
- 火の型 With Scratch (ゲームプログラム入門)  http://firebook.firefirestyle.net/
- 炎の型 With Scratch (ゲームプログラム入門)  http://firefirebook.firefirestyle.net
- 炎の型 (漫画版) 第１巻 Scratchでプログラム入門 Tennis For Twoを作ってみよう!! http://firefiremanga00.firefirestyle.net/


# 設定方法

DNSとGitbookの設定が必要です。そんなに複雑ではないです。


### (1) DNSの設定

ドメインを取得したレジストラー等でDNSを変更してください
cname firefirebook www.gitbooks.io.
cname firebook www.gitbooks.io.
cname firefiremanga00 www.gitbooks.io.

**※ アドレスの部分は読み変えてください。**

### (2) GitBook側の設定

Gitbook側にの利用するカスタムドメインを設定します。

https://www.gitbook.com/@kyorohiro
に移動後、各々の本の設定画面に移動する
**※ kyorohiro の部分は読み変えてください。**

##### 1. Settingをクリック  
![a0.png](https://qiita-image-store.s3.amazonaws.com/0/54192/afda6b2b-9a13-31bf-b0ad-6e9e2f1a9823.png)

##### 2. Domainをクリックすると、Custom Domains のページが表示されるので、カスタムドメインを入力 
![a1.png](https://qiita-image-store.s3.amazonaws.com/0/54192/8dfaa68d-5973-1706-8c4e-b519d49de36b.png)

firefirebook.firefirestyle.net と入力する。
これで、登録ができました。


# PS

Gitbookのユーザーページへの移動が、分かりにくくなるので、
誘導するリンクを追加した方が良いかも知れません

私はの場合、以下のページに誘導しにくくなった
印象を受けました。
https://www.gitbook.com/@kyorohiro
Elasticsearch 5系で距離を算出するscriptをpainlessで書く

メモ代わりなので背景などの説明は雑にします。

## やりたいこと
Elasticsearchの5.1.1でsearchをしたときに、`geo_point`型のフィールドとクエリで指定した地点との距離も算出して返して欲しい。2系＆Groovyではやり方を知っていたけど、5系＆Painlessになったから直す必要がある

### なぜ？
Elasticsearchの5.0.0以降ではGroovyが廃止され、Painlessという新しく開発された言語がデフォルトになりました。なので、まずpainlessに変更する必要があります。
また、2.0で使えたいろいろなヘルパーメソッドが廃止されたので代替の処理を書く必要があります。


## 修正内容
pythonクライアントで使っていたので例がPythonのdict型になっていますが、inlineの中身は共通だと思いますので、REST APIでそのまま使う or 他の言語のクライアントからアクセスする場合は主にinlineとparamsの中身だけ見れば良い気がします。

`location_field`は`geo_distance`型のフィールド, `latitude_value`と`longitude_value`はそれぞれ緯度と経度の値が入った変数です。

### Before

```py3
{
    "distance": {
        "script": {
            "lang": "painless",
            "inline": "doc[\"location_field\"].distanceInKm(lat, lon)",
            "params": {
                "lat": latitude_value
                 "lon": longitude_value
            }
        },
    }
}
```

### After

```py3
{
    "distance": {
        "script": {
            "lang": "painless",
            "inline": "doc[\"location_field\"].arcDistance(params.lat, params.lon) * 0.001",
            "params": {
                "lat": latitude_value,
                "lon": longitude_value
            }
        },
    }
}
```

### 違い
`distanceInKm`が廃止されたので`arcDistance`を使います。
ただ、これだと単位が米になるので0.001をかけてkmに変換しています。

もう一点、`params`で定義した変数を以前は定義した名前そのままで使えていたのに、なぜか5系では（painlessでは？）`params.`を頭に付ける必要がありました。


## 感想
Groovyもそもそも使ったことないですが、基本文法はだいたい同じだし、複雑なことはあまりやらないと思うので、Documentを読めばなんとかなりそうです。ただ、廃止されたヘルパーメソッドを５系のために書き換えるのは割と大変だなと思いました...（ヘルパーメソッドの処理内容はElasticsearchのドキュメントを読んでもわからないし、painlessでどのヘルパーメソッドが使えるか分からないので）

デバッグできる方法もドキュメントに書かれていましたが、たった１行の処理を書くのに読むのが面倒なのでやりませんでした（**結果、割とこの１行のinlineを直すのに１時間近くかかった**）

文句垂れ流しエントリになってしまいましたが、ちゃんとドキュメントを読み込めば良いだけで僕が悪い可能性が高いので、また深夜テンションを脱したら読み返してみます
技術英語 > If your program spends most of its time calculating things (the technical term is [CPU-bound]), ...

@ Introducing Python: Modern Computing in Simple Packages by Bill Lubanovic
(No. 353 / 12833)

> If your program spends most of its time calculating things (the technical term is <font color=red>**CPU-bound**</font>), ...

boundは「bound for Namba」のような電車の行先のアナウンスで聞いたことはあった。

あとはbounding boxのような画像(UI?)関連などで時々見かける。


以下を見つけた。

http://d.hatena.ne.jp/yohei-a/20120205/1328432481
> CPUバウンドとI/Oバウンド

2005年頃の話。MPIなどの並列計算をした場合、プロセス同士の通信のためか効率がCPU数ほど上がらなかった。そのため、プロセス個別で別パラメータでの処理を行うようにして、最後に結果をまとめるように処理をしたところ、ほぼCPU数のパフォーマンスゲインが得られた。
CUDAのSM(Streaming Multiprocessor)での処理はこちらに近い感じがする。

共同の仕事が増えていくに従い、コミュニケーションが増えてしまい、個人の作業時間確保が難しくなる。しかしながら、部屋にこもってコーディングだけすると共同者の作業が滞る。バランスを考えて作業をしないといけない (仕事中の雑談は減らしたい)。

自分ができる一つの対策は、作業中断後にすぐに再開できる仕組みを準備しておくこと。
それにはQiitaとTODOリストが非常に役立っている。
grub にWindows10起動メニューを追加する（Boot-Repairを利用する）

誤ってWindows10起動用パーテーションを削除してしまった時の回復方法
grubでLinuxが起動できることが条件


sudo add-apt-repository ppa:yannubuntu/boot-repair
sudo apt-get update
sudo apt-get install -y boot-repair

boot-repairを起動
推奨リペアを実行する


以上
WP-CLI のコマンド補完を設定すると超便利！


WP-CLI は Bash のコマンド補完に対応していて、タブキーを押すとさくさくとサブコマンドや利用可能なオプションを補完してくれます。

```
$ wp p
package     plugin      post        post-type
```

とか

```
$ wp core 
check-update        install             multisite-convert   update-db 
config              is-installed        multisite-install   verify-checksums 
download            language            update              version 
```

とかコマンドの途中でタブを2回押すと続きを勝手に入力してくれるんですね。

`wp core verify-checksums` とか一生スペルを覚えられそうもないので、とても助かります。

この機能、ちょっと前まではあまり使い勝手がいいものではありませんでしたが、現在のバージョンでは劇的に改善されておりまして、気持ちよく使うことができるようになっています。

ちなみにこの補完機能の実態はこんな感じのサブコマンドなんですけどね。

```
$ wp cli completions --line="wp co" --point=10
comment 
core 
```

テストも入念に行われています。

https://github.com/wp-cli/wp-cli/blob/master/features/cli-bash-completion.feature

あっ、よくできてるなと思ったら作ったのは僕でした。えへへ。

![](https://www.evernote.com/l/ABUK6GPoMRFFDbMP7dfOngM8D7PtG_K0O78B/image.png)

## コマンド補完の有効化方法

そもそも WP-CLI をまだインストールしてない方は以下の URL をどうぞ。
http://qiita.com/miya0001/items/acaf047395f018f3ab4a

まさかの「4いいね」で拡散力つけようって思った。。。

### Homebrew の場合

Homebrew の場合はあらかじめ必要なファイルはインストール済みなので、`~/.bash_profile` の最後の方に以下のように記述するだけです。

```
source /usr/local/etc/bash_completion.d/wp-completion.bash
```

これが終わったら `source ~/.bash_profile` ってコマンドを実行するかターミナルを再起動するかしてください。

### Homebrew 以外の方法でインストールしている人向け

以下の URL から `wp-completion.bash` を任意の場所にダウンロードしてください。

https://raw.githubusercontent.com/wp-cli/wp-cli/master/utils/wp-completion.bash

ダウンロードしたら、先ほどと同じく `~/.bash_profile` に記述。

```
source /FULL/PATH/TO/wp-completion.bash
```

終わったら `source ~/.bash_profile` ってコマンドを実行するかターミナルを再起動するのをお忘れなく。

### VCCW の場合

VCCW ではあらかじめプリインストールされています。すぐに快適な WP-CLI ライフをお楽しみいただけます。

ちなみに VCCW にプリインストールされている WP-CLI は、nightly バージョンなので、最新版よりもさらに少しだけ改善されています。

たとえば、以下のようにグローバルオプションも補完されたりとか。

```
$ wp plugin list --
--color           --http=           --require=        --url=
--debug=          --no-color        --skip-packages   --user=
--field=          --path=           --skip-plugins=   
--fields=         --prompt=         --skip-themes=    
--format=         --quiet           --ssh= 
```

あと、SSH エイリアスに以下のような感じでホスト名風な記述をすることもできます。

https://firegoby.jp/archives/6689

```
@example.com:
  ssh: user@example.com/var/www/html
@example.jp:
  ssh: user@example.jp/var/www/html
```

nightly バージョンは、毎日更新されている上に、開発環境で利用するには十分に安定していますのでおすすめです。
Pythonを使って、Google Speech APIv2による音声ファイル認識

Googleのサービスを使って音声ファイルの音声認識をします。

#環境
・AnacondaによるPython3.5 64bits
・Win10
・音声ファイルは、WAV。別にsoxで変換すればよいだけなんですが。

#インストールするパッケージ
##SpeechRecognition https://github.com/Uberi/speech_recognition
いろんな音声認識クラウドサービスを使いやすくしてくれるパッケージです。高機能。
##pyaudio
SpeechRecognitionの動作に必要なようです。
##google-api-python-client
SpeechRecognitionのサンプルソースを流用するときに、使われているパッケージですので、インストールしておきます。
##pydub
無音区間で音声ファイルを区切るために使用します。
pip install pydub
です。
##FFMPEG
インストールしないといけない理由がよくわかりませんが、
http://chachay.hatenablog.com/entry/2016/10/03/215841
に書いているとおりにやっています。

#Google のSpeech API v2を使うためには
おおよそ、
http://qiita.com/lethe2211/items/7c9b1b82c7eda40dafa9
のとおりかと思います。MLに加入しないと出てこないあたりが面倒ですね。

#注意点
音声ファイルが長すぎると、どこ要因かは分かっていない（2017/01/11現在）のですが、エラーになります。私の環境では、10秒程度の音声ファイルの結果は返ってくるのですが、20秒になるとエラーになります。

SpeechRecognitionのサンプルを使う場合には、
`audio = r.record(source, duration=10`のように、durationで時間を調整して結果を確認してみてください。長いとエラーになりますよね？

#無音部分でのファイル分割
基本的に、
http://chachay.hatenablog.com/entry/2016/10/03/215841
のとおりです。

Google Speech APIv2で音声認識しようとしたとき、ファイルが大きいと、（どこ要因か不明ですが）エラーになるので、ファイルを分割して認識にかけるために無音部分で分割しようとする試みです。


#音声認識実行時のソース
いろんなライブラリを利用して、その間のデータ変換をwavファイル経由でやっているので、無駄が多いかと思いますが、ソース載せます。

import、無駄なものがあると思うので適宜省いてください。

```.py
import speech_recognition as sr
from os import path
from googleapiclient import discovery
import httplib2
import base64, json
import urllib
import os
from pydub import AudioSegment
from pydub.silence import split_on_silence


if __name__ == '__main__':
    r = sr.Recognizer()
    audio_data = []
    sound = AudioSegment.from_file('./filename.wav', format='wav')
    chunks = split_on_silence(sound, min_silence_len=1500, silence_thresh=-30, keep_silence=500)
    
    for chunk in chunks:
        chunk.export('./temp.wav', format='wav')
        AUDIO_FILE = path.join(path.dirname(path.realpath(__file__)), "temp.wav") 

        with sr.AudioFile(AUDIO_FILE) as source:
            audio = r.record(source)
            audio_data.append(audio)
    for audio in audio_data:
        try:
            print("Google Speech Recognition thinks you said " + r.recognize_google(audio,key='your API key', language='ja'))
        except sr.UnknownValueError:
            print("Google Speech Recognition could not understand audio")
        except sr.RequestError as e:
            print("Could not request results from Google Speech Recognition service; {0}".format(e))

```

#参考サイト
http://chachay.hatenablog.com/entry/2016/10/03/215841
https://pypi.python.org/pypi/SpeechRecognition/
Sierraでbundle installはまったところメモ

# rmagick

Ref: http://qiita.com/hidechae/items/56e8cca8a77610aa0ab4

```
$ curl https://raw.githubusercontent.com/Homebrew/homebrew-core/f6b47796d0fc3a05cc00d62fc68556b77ad5a1dc/Library/Formula/imagemagick.rb >! /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/imagemagick.rb
$ brew install imagemagick
```

# libv8

Ref: http://qiita.com/ooyabuh/items/32e7086917e29356b532

```
$ gem install libv8 -v '3.16.14.11' -- --with-system-v8
$ bundle config build.libv8 --with-system-v8
```

# mysql2

Ref: http://nekonenene.hatenablog.com/entry/2016/10/31/061350

```
bundle config build.mysql2 --with-opt-lib=/usr/local/opt/openssl/lib --with-opt-include=-I/usr/local/opt/openssl/include
```

# eventmachine

Ref: http://qiita.com/nownabe/items/c62574b63fd55ee31ed6

```
bundle config build.eventmachine --with-cppflags=-I/usr/local/opt/openssl/include
```
windows10でopencv開発環境構築しました

windowsでopencvの開発環境をつくったので、そのメモです。NuGetとかCMakeとか色々方法があるらしいのですが、おそらくオーソドックスなOpenCVのサイトからダウンロードする方法で構築しました。

ほとんど[イメージングソリューション様のサイト](http://imagingsolution.net/program/opencv/opencv3-1visual-studio-2015-64bitos/)を参考にすれば問題ないのですが、一部やり方を変えたり、問題がおきたのでメモとして残しておこうと思います。

##環境
- windows10 pro 64bit
- visual studio community 2015 
- OpenCV version 3.2
- visual c++ での開発

##事前準備
###OpenCV
http://opencv.org/
トップページからDLしてきます。特にインストールはなく解凍するだけです。配置するパスには日本語を含めないようにしてください。自分は
*c:\lib\opencv*
に配置しました。

##とりあえず空のプロジェクトを作ろう
新規プロジェクトでVisualC++ -> Win32コンソールアプリケーションを作成します。

##プロジェクトの設定
プロジェクトのプロパティを開きます。
![プロパティ](https://qiita-image-store.s3.amazonaws.com/0/65391/faaf19f5-761d-320d-973c-8e65bec69a97.png)

###構成とプラットフォームを確認
構成が「すべての構成」、プラットフォームが「アクティブ（x64）」であることを確認してください。（僕はプラットフォームがアクティブ（win32）だったので、構成マネージャーからプラットフォームをx64に変更しました。）
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/65391/e76c49c0-51ef-9b1b-e53f-5b20a231db8e.jpeg)

###インクルードパス指定
C/C++を選択して、追加のインクルードディレクトリに
*c:\lib\opencv\build\include*
を追加します

###ライブラリパス指定
リンカー -> 全般を選択して、追加のライブラリディレクトリに、
*c:\lib\opencv\build\x64\vc14\lib*
を追加します

###依存ファイルのパス指定
ここで、構成(ReleaseとかDebug)ごとに設定する必要があります。リンカー -> 入力を選択して、追加の依存ファイルにパスを追加します。
追加するパスですが、構成ごとに変えなければいけません。

**Debugの場合**
まず、構成を「すべての構成」から「Debug」に変更します。その後、追加の依存ファイルパスに、
*opencv_world320d.lib*
を追加します。デバッグ用なので320dらしいです。

**Releaseの場合**
構成を「Release」にして
*opencv_world320.lib*
を追加します。

##環境変数にOpenCVのライブラリパスを指定
###環境変数設定画面を開く
コントロールパネル -> システムとセキュリティ -> システム -> システムの詳細設定を押して、システムのプロパティ画面をひらきます。一番下にある「環境変数（N）...」ボタンを押します。

###ライブラリパスをPathに追加
システム環境変数のリストの中にあるPathという環境変数の最後に
*c:\lib\opencv\build\x64\vc14\bin*
を追加します

##さてサンプルプロジェクトを動かしてみよう
元画像と、白黒２値化した画像を表示するサンプルを実行してみます。(ここのコードもイメージングソリューション様のコードを参考にしています)

```c++:プロジェクト名.cpp
#include "stdafx.h"
#include <opencv2/opencv.hpp>
 
int main()
{
 // 処理前画像
 cv::Mat src = cv::imread("C:\\Mandrill.BMP", CV_8UC1);
 cv::Mat dst;
 
 //二値化
 cv::threshold(src, dst, 0, 255, cv::THRESH_OTSU);
 
 //画像を表示
 cv::imshow("SrcImage", src);
 cv::imshow("DstImage", dst);
 
 //キー入力待ち
 cv::waitKey(0);
 
 return 0;
}
```

##厳しすぎる警告を一部OFFにする
これでビルドすると私の環境では以下のようなエラーがでました

*C4996 'fopen': This function or variable may be unsafe. 
Consider using fopen_s instead. To disable deprecation, 
use _CRT_SECURE_NO_WARNINGS. See online help for details. opencv\build\include\opencv2\flann\logger.h 66*

fopenは危険だと言ってくれているようですが、もみ消したいです。ですので、stdafx.hの先頭に
`#define _CRT_SECURE_NO_DEPRECATE`
を追加します。


以上で私の環境では画像を表示することができました。windowsでの開発経験がほとんどないため色々と間違いがあるかもしれません。何か問題がありましたらご指摘ください。また、流用させていただいたコード等問題ありましたら削除いたします。
ブランチ切り忘れて master でコミットしちゃったときの 2ステップ

よくやる作業なのでテクニックとして紹介

# やりたいこと
![3__minecraft-git__tig_--all__zsh_.png](https://qiita-image-store.s3.amazonaws.com/0/40717/2a8615af-8588-d81c-bb63-658034c263ff.png "3__minecraft-git__tig_--all__zsh_.png")


ブランチを切り忘れて `master` で作業しちゃったこの状態から

![3__minecraft-git__tig_--all__tig_.png](https://qiita-image-store.s3.amazonaws.com/0/40717/c611d510-6f80-b7c3-c0d2-72c728279843.png "3__minecraft-git__tig_--all__tig_.png")


`master` は remote と同じ位置に戻して、そこから `make-first-house` ブランチが伸びている状態にしたい。

# やりかた
以下の 2コマンドで実行する。

```sh
$ # 先にブランチ作ってチェックアウト
$ git checkout -b make-first-house
$ # master を移動
$ git branch -f master origin/master
```

# やりかた2(追記)
@egtra さんのやり方が1コマンドでほぼやりたいこと満たしていたのでオススメします。

```sh
$ # ブランチをリネーム
$ git branch -m make-first-house
```

一時的に local の `master` はなくなるけど ``` git checkout master ``` すれば問題ない。

## ※注意
やりかた2 では upstream が origin/master (元のもの)のままになってしまうので注意です。
(upstream 一覧は ``` git branch -vv ``` で確認できます)
js 二つの文字列を一つにする

##お題
与えられる二つの引数(アルファベット文字列)を以下の条件を満たしつつ一つに結合する。
・アルファベットを順番に並べかえる
・重なった文字は省略する

```js
function longest(s1, s2) {
 //write your code.
}
longest("xyaabbbccccdefww", "xxxxyyyyabklmopq") // "abcdefklmopqwxy"
```

##出力結果　例

```js
longest("aretheyhere", "yestheyarehere")// "aehrsty"
longest("loopingisfunbutdangerous", "lessdangerousthancoding")// "abcdefghilnoprstu"
longest("inmanylanguages", "theresapairoffunctions")// "acefghilmnoprstuy"
```

##つかったもの
split()
sort()
filter()
join()

##考え方
・引数を合わせてから文字ごとに分割する。
・sort()で並べ替えて、filterで重複したものを省く。
(filterの条件を工夫する)
・join()でfilter後の文字を一緒にして返しておわり。

##コード

```js
function longest(s1, s2) {
  s3 = s1 + s2;
  s4 = s3.split("");
  s4 = s4.sort().filter(function(element, index, array){
    return element !== array[index - 1];
  });
  return s4.join("");
}
```

ES6

```js
function longest(s1, s2) {
  return Array.from(new Set(s1 + s2)).sort().join('');
}
```



```js
const longest = (s1, s2) => [...new Set(s1+s2)].sort().join('');
```

###他にもコードが浮かんだ方、コメントお待ちしております
Google Spreadsheet上の日付と時間からシリアル値を得る関数

# Google スプレッドシートの別々のセルにある日付と時間からシリアル値を得る関数
　ある日時とある日時の大小を比較する時，シリアル値を合成して比較できると便利。

```java:テンプレート

function main(){
  途中略
  var date = getValue(masterSheet, row1, column1);//セルでは「2017/01/13」
  var time = getValue(masterSheet, row2, column2);//セルでは「13:13:00」
  
  var serial = getSerial(date,time);//シリアル値を日付と時間からゲット
  var date2 = getDate(serial);//日付をシリアル値から取り出す, Fri Jan 13 2017
  var time2 = getTime(serial);//時刻をシリアル値から取り出す, 13:13:00
}



function getSerial(date,time){//日付と時間からシリアル値をゲット
  var serial = new Date(date.toString().slice(0,16)+time.toString().slice(16));
  return serial;
}

function getTime(serialValue){//シリアル値から時間を取り出す，シリアル値は「1899年12月30日午前0時」からの経過ミリ秒（のはず）
  var str = serialValue.toString();//（例：'Sat Oct 29 2016 16:05:42 GMT+0900 (JST)'）
  var strings = str.split(' ');
  return strings[4];
}

function getDate(serialValue){//シリアル値から年月日を取り出す
  var str = serialValue.toString();//（例：'Sat Oct 29 2016 16:05:42 GMT+0900 (JST)'）
  var strings = str.split(' ');
  return strings[0] +' '+ strings[1] +' '+ strings[2] +' '+ strings[3];
}

```
SierraにRMagickを入れる

RMagickを入れるのに何度やっても毎回困っているのでメモ。

## 古いバージョンのimagemagickのインストール

普通に`brew install imagemagick`でインストールされるversionには対応していないため、古いversionのimagemagickをインストールする必要がある。

以下のリンクのように、homebrewのリポジトリから古いものをcheckoutすれば良さそう
http://qiita.com/satosystems/items/8587527b185a91abfb37

だが、手元で見ると何故か古いログを取得できず断念（これなんでか分かる人教えて欲しい）


なので、githubから直接ファイルを持ってくる
https://github.com/Homebrew/homebrew-core/blob/f6b47796d0fc3a05cc00d62fc68556b77ad5a1dc/Library/Formula/imagemagick.rb

これを`/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/imagemagick.rb` に上書きする

```
$ curl https://raw.githubusercontent.com/Homebrew/homebrew-core/f6b47796d0fc3a05cc00d62fc68556b77ad5a1dc/Library/Formula/imagemagick.rb >! /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/imagemagick.rb
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  4096  100  4096    0     0  25149      0 --:--:-- --:--:-- --:--:-- 25283
```

すると欲しいversionのimagemagickがインストールできる

```
$ brew install imagemagick
==> Installing dependencies for imagemagick: pkg-config
==> Installing imagemagick dependency: pkg-config
==> Downloading https://homebrew.bintray.com/bottles/pkg-config-0.29.1_2.sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring pkg-config-0.29.1_2.sierra.bottle.tar.gz
🍺  /usr/local/Cellar/pkg-config/0.29.1_2: 10 files, 627.5K
==> Installing imagemagick
==> Using the sandbox
==> Downloading http://www.imagemagick.org/download/releases/ImageMagick-6.9.0-10.tar.xz
######################################################################## 100.0%
==> ./configure --disable-osx-universal-binary --prefix=/usr/local/Cellar/imagemagick/6.9.0-10 --enable-shared --disable-static --with-modules --disable-openmp --without-gslib --without-perl --with-gs-font-dir=/usr/local/share/ghostscript/fonts --without-pango --without-o
==> make install
🍺  /usr/local/Cellar/imagemagick/6.9.0-10: 1,450 files, 17.6M, built in 2 minutes 18 seconds
```

これで必要なimagemagickはインストールできたので、RMagickもインストールできる

```
$ gem install rmagick
Building native extensions.  This could take a while...
Successfully installed rmagick-2.16.0
Parsing documentation for rmagick-2.16.0
Installing ri documentation for rmagick-2.16.0
Done installing documentation for rmagick after 5 seconds
1 gem installed
```
UnityでOculus Touchのhandを非表示・表示を制御する

Oculus Touchが届いてからほぼ1か月がたち、試しにVRを弄ろうかなとUnityを始めてみました。

とりあえずやっぱり銃を撃ってみる動きを作ってみようとしたところ、Touchを使って握ると、
手が変な感じです。

![hand_hen.png](https://qiita-image-store.s3.amazonaws.com/0/75491/f3d9b437-9b5a-dcc2-758c-328e2987e077.png)

GOROmanさんの[VR におけるプレゼンスの維持と破壊](https://medium.com/@GOROman_1661/vr-%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%97%E3%83%AC%E3%82%BC%E3%83%B3%E3%82%B9%E3%81%AE%E7%B6%AD%E6%8C%81%E3%81%A8%E7%A0%B4%E5%A3%8A-5d9858f44ef6#.63rnq22xq)によると、

> 物を掴んだ時は手の表示を消してしまうテクニック(Job Simulator)

という方法があるそうです。

これだ！
というわけで、手を消す方法を調べてみました。

OVRAvatarHandには、SetAlphaというメソッドがありましたので、これに0fを設定してみたところ、ダメでした。
OVRAvatarにShowRightControllerというメソッドがあったので試したところ、これはTouchのコントローラー自体を表示するもので、手とは関係ありませんでした。
Oculus.AvatarのCAPIを見てみましたが、該当しそうなメソッドは見つけられず……。

そんな時、凹さんの [Oculus Avatar SDK を使って自分のアバターを Unity で利用する方法を調べてみた](http://tips.hecomi.com/entry/2016/12/25/142057)を読んでいたところ、実行中のAvatarは、コンポーネントを持つそうです。

![2017-01-11 (8).png](https://qiita-image-store.s3.amazonaws.com/0/75491/9683d348-5363-599a-38ed-aacfe0a3f81d.png)

なるほど！
そんなわけで、以下のような方法で実装しました。

```C#:HandController.cs
public class HandController : MonoBehaviour {
    public OvrAvatarHand hand;
    void Update () {
        SkinnedMeshRenderer mesh = hand.transform.GetComponentInChildren<SkinnedMeshRenderer>();
        mesh.enabled = false;
    }
}
```

これで手を消せました。
MacBook Pro / Touch Bar (2016) の使い心地とか初期設定など

# 所感
  （13インチ 2.9GHz 標準仕様を購入）

- 良い点
    - Totch ID なのでロック解除がとてもラク！（これはすばらしい）
    - ディスプレイ解像度が高いとか性能アップとかは当たり前ですね...
    - キーボード大きくて打ちやすい！（ちょっと打音がうるさい）
- 悪い点
    - Escボタン廃止（やっぱこれ辛い）  
    　一応、CapsボタンにEsc割り当ててますが慣れないです。
    - MagSafe電源アダプターが廃止になった　（なんで！？）
    - USB-Cのみ
- その他
    - SierraがデフォルトOSなので、KarabinerとxTraFinderが現時点では未対応（ツライ）  
    　やはりCtrl+c,v,xは使いたいですし、MacのFinderは使いづらいのでカスタマイズしたいです

# 初期設定

- システム環境設定
    - トラックパッド（全部にチェック！）
        - 一本指でタップ
        - アプリケーションをexpose
    - 一般　→　サイドバーのアイコンサイズを小
    - ディスプレイ
        - 輝度の自動調整 :Off
        - バッテリー使用時に暗くする :Off
    - キーボード
        - ひらがな　カタカナの入力ソース　チェック外す
        - 数字を全角入力　チェック外す
        - ユーザ辞書　英字入力中にスペルを自動変換　チェック外す
        - 修飾キー　Caps → Esc、 Ctrl → Command
    - Dock　→　でかすぎなのでお好みに
    - PCロック　→　お好みで
        - スクリーンセーバとPCロックのタイミングを5分に
    - ユーザとグループ
        - 画像変更するのにちょっとハマりましたw  
        （アイコンに直接ドラッグすると変更できます）
    - 時計　→　24h表記、日付も表示

## ツールとか
  （ブラウザとかターミナルとか開発ツールは好みがあるので割愛して特徴的なもの）

- GoogleFontに変更  
→Sierraになってかなり良くなりましたが、まだちょっと...
- Karabiner（現時点ではSierra未対応）
- XtraFinder（現時点ではSierra未対応）
    - 右クリックで新規ファイル作成
    - Enterでファイルを開く  
    …など
- git初期設定
- .bashrc  
```
        source /Applications/Xcode.app/Contents/Developer/usr/share/git-core/git-prompt.sh
        source /Applications/Xcode.app/Contents/Developer/usr/share/git-core/git-completion.bash
        GIT_PS1_SHOWDIRTYSTATE=true
        export PS1='\h\[\033[00m\]:\W\[\033[31m\]$(__git_ps1 [%s])\[\033[00m\]\$ '
```
- Mobile Mouse Server (有料)  
 → プレゼン用

## エディタ（Atom）
（私はこの仕事始めてずっとViコマンドだったのでViがマスト条件）

- Package
    - japanse-menu : 日本語化
    - japanese-wrap : 改行
    - vim-mode : Vi
    - ex-mode : %sなどコマンドが利用可能になる
- editor setting
    - Ricty Diminished　(Ricty Diminished サイトのZipをダウンロードしてダブルクリックでOK)
    - インデントガイド表示
    - 不可視文字表示
- Theme
    - OneLight/OneLight

# おまけ
## 管理職の仕事もMac一本で大丈夫になってきた
 会社の規模と役割にもよりますが、エンジニアといえども管理職をメインでやると
 どうしてもOfficeでの仕事が多いのでWindows PCが手放せません。
 PL,予算などをエクセルで全社管理していると尚更ですよね...
 Office 2011 の時はコピーすると固まったり正直使えるものではなかったですが、
 Office 2016 になって改善されているのでほぼ大丈夫です。
 （ただ、ファイルサーバで外部参照などガシガシ使っているPLとかはちょっと厳しいかも）

## Windowsとのショートカットキーの違いメモ
- 通常  
  PrintScreen(範囲選択)　:  Command + Shift + 4
- Office 365 (Excel 2016)  
  Ctl + 1 : Command + 1  
  F2 : Ctrl + U  
  Alt + Enter : Option + Command + Enter  
  Ctrl + d : 無い！  
  「オブジェクトの選択」の矢印が無い！
Securing OpenAM 実践Ⅱ

前回の続きから、記録。

# デフォルト deployment URI の変更

> When installing OpenAM, do not use /openam or /opensso as the deployment URI.

ダウンロードしたOpenAM-13.0.0.warをopenam.warやopensso.war以外の名前に変更します、(iam.warとか)、以上。

# デフォルト管理者 amadmin の変更

> Create an administrator in the Top Level Realm with a different ID than the default amadmin.

Administration Guideの↓に記載がありました。
https://backstage.forgerock.com/docs/openam/13/admin-guide#change-amadmin-uid

しかし、Warningのところを読むと、openamのソースコードの中に、amadminでハードコーディングしている部分があるとのこと。改善を計画されているらしく、それまではamadminを使うことを推奨しているようです。

でも、せっかくドキュメントに記載されているので、とりあえずやってみました。
## 1.代わりのユーザを作成
[TopLevelRealm]-[Subjects]-[新規]からamadminに代わるユーザを作成します。

![create_superroot.jpg](https://qiita-image-store.s3.amazonaws.com/0/116278/062c3383-17b6-195e-4615-9ec29657b2c3.jpeg)

## 2.管理者ユーザの設定変更(com.sun.identity.authentication.super.user)
[CONFIGURATION]-[サーバーおよびサイト]-[*サーバ名*]-[セキュリティー]-[高度]に以下のように1.で作成ユーザのDNを設定します。

> com.sun.identity.authentication.super.user ：
> uid=superroot,ou=people,dc=openam,dc=forgerock,dc=org

![superuser.jpg](https://qiita-image-store.s3.amazonaws.com/0/116278/c5bebec7-08a5-a06b-0a8e-ee8abd28bb53.jpeg)

## 3.OpenAM再起動

amadminでログインしてみると

![amadmin.jpg](https://qiita-image-store.s3.amazonaws.com/0/116278/8a67a224-550f-8beb-00f6-f68fed025a9a.jpeg)

superroot(代わりのユーザ)でログインしていると

![superroot.jpg](https://qiita-image-store.s3.amazonaws.com/0/116278/d6f59f6d-4784-ba02-84f7-a0082571e15c.jpeg)

確かに変更できているみたいですね。

##　メモ

OpenAM13.0で試してみましたが、13.5のAdministration Guide↓がどうなっているのか気になったので、調べてみました。

https://backstage.forgerock.com/docs/openam/13.5/admin-guide#amadmin-changes

一文目にハードコーディングのことは書いていますが、com.sun.identity.authentication.super.userの設定に関する記載がなくなっているように見えますね。別の章に記載が移動したのかな。。。