OmniAICreator/Qiita-1.07M huggingface dataset:
GASでオンライン人狼的な何かを作る #1

[次回 》](http://qiita.com/TakumaKawashiro/items/2b8a56d6f09da76ed8d5)
　何パートかに分けてGoogle Apps Scriptでオンライン人狼ウェブアプリを作ります。

# そもそも
　なんでGoogle Apps Scriptでやるんだと言いますと、最近学校のGoogle Apps for EducationでGASをいじってたのでその延長です。GASはサーバを組んだりしなくても簡単にウェブアプリが作れる上、Googleアカウントを活用できるので、GASを使おうと思いました。

# Google Apps Scriptとは
　Googleが提供する GoogleドライブやGoogleサイトとかを操作できる、とてつもなく強いやつです。**サーバサイドスクリプト(?)である**っていうのが特徴です。HTMLを使ってウェブアプリとして動かすことができます。

# とりあえず開きましょう
　あーだこーだ言ってないで、とりあえずエディタを開いちゃいましょう。[scripr.google.com](https://script.google.com/)にアクセスします。なんかエディタっぽいのが出ましたよね？はい、これがエディタです。(Googleアカウントでログインしてくださいね。)
![script.google.com](https://98234cd82ec58ffed0b982e5fd3862b173cc95a2.googledrive.com/host/0B3kxjwKeIe_3bXFCRktpUE56Tm8/script_google_com.jpeg)

# ベースはJavaScript
　GASはJavaScriptで記述します。ただし、普通のJavaScriptのようにブラウザで動かすわけではないので、クラスやメソッドはGAS独自のものがあります。構文やifとかforとかwhileは普通のJavaScriptと同じように使えます。

# 早速なんか書いてみましょう
　百聞は一見に如かず。書きましょう。以下のコードを書いてみてください。

```lang:コード.gs
function myFunction() {
  Logger.log("初めてのGoogle Apps Script");
}
```

　Loggerクラスのlogメソッドで、ログを記録することができます。

## 実行...の前に
　実行してみましょう。実行ボタン(ツールバーの「▶︎」)をクリックしてください。あ、保存しろって怒られましたね。プロジェクトの名前を入力して保存しましょう。
![save](https://98234cd82ec58ffed0b982e5fd3862b173cc95a2.googledrive.com/host/0B3kxjwKeIe_3bXFCRktpUE56Tm8/save.jpeg)
　あ、ちなみに私はiPadでスクリプトを書いてます。え？どうでもいいですか？あっはい、そうですね。

## 気を取り直して
さて、名前を付けたらもう一度実行しましょう。
![launching](https://98234cd82ec58ffed0b982e5fd3862b173cc95a2.googledrive.com/host/0B3kxjwKeIe_3bXFCRktpUE56Tm8/launching.jpeg)

上の「関数 myFunction を実行中...」という表示が消えたら、ツールバーの 表示＞ログ をクリックします。
![firstLog](https://98234cd82ec58ffed0b982e5fd3862b173cc95a2.googledrive.com/host/0B3kxjwKeIe_3bXFCRktpUE56Tm8/firstLog.jpeg)

　こうなってたら大成功。見事、GASでログを取ることができました。

# というわけで、
　今回はここで止めておきます。次回はHTMLの表示について、その次から実際にオンライン人狼もどきを作っていきます。
　今後の更新、お楽しみに〜

(ちなみに初投稿でございます。これからよろしくお願いいたします。)

[次回 》](http://qiita.com/TakumaKawashiro/items/2b8a56d6f09da76ed8d5)
Hyperloopモジュールを試す（1）セットアップ編

[モジュール版Hyperloop](https://labs.appcelerator.com/project/55f74a9f421c44837717716b/Hyperloop-Module)とは、2年くらい前に[Appcelerator](http://www.appcelerator.com/)社から打ち出された、JSからObj-CやJavaのコードを生成することでネイティブ開発との機能面でのギャップやパフォーマンスの飛躍的な向上を狙った野心的な[Hyperloopプロジェクト](https://github.com/appcelerator/hyperloop)が軌道修正されて、既存の資産を活かしやすいモジュールとしてその一部の機能が利用可能になったものです。これにより、Titanium側でAPIを用意していない機能はこれまで中間層となるモジュールの仲介が必要だったのが、JavaScriptで記述するだけで直接Obj-C/Javaへのブリッジを用意することができるようになります。

Hyperloopを試すための資料が古いマニュアルと噂話とソースコードしかないのでここにメモしておきます。

## モジュールの取得

マニュアルに記載されたリンクは死んでいる（！）のでこちらのサンプルプロジェクトから取得します。
https://github.com/appcelerator/hyperloop-examples

## モジュールとプラグイン

チェックアウトしたサンプルプロジェクトから`modules/{iphone,android}/hyperloop`ディレクトリをコピーして自分のプロジェクトの同じく`modules/{iphone,android}/`以下に設置します。

それから`plugins/hyperloop`も同じくプロジェクトの`plugins`以下にコピーしましょう。

## tiapp.xmlの設定

次にtiapp.xmlですが、現在のマニュアルは古いのでそのまま従わず、以下のようにします。

### プラグイン

```xml
  <plugins>
    <plugin version="1.0">ti.alloy</plugin>
    <plugin>hyperloop</plugin>
  </plugins>
```

### モジュール

```xml
  <modules>
    <module platform="commonjs">ti.cloud</module>
    <module>hyperloop</module>
  </modules>
```

### SDK

```xml
<sdk-version>5.4.0.v20160406101605</sdk-version><!--5.4.x以上-->
```

### その他

```xml
<property name="run-on-main-thread" type="bool">true</property><!--追加-->
  <ios>
    <use-jscore-framework>true</use-jscore-framework><!--追加-->
    <enable-launch-screen-storyboard>true</enable-launch-screen-storyboard>
```

## appc.js

マニュアルではオプションのような扱いですがこれがないとビルド出来ませんでした。

```js
module.exports = {
  hyperloop: {
    ios: {
    }           
  }
};
```

まだ何も使っていないのでこんな感じで空でも大丈夫です。

この時点で`appc ti build -p ios`でシミュレータが起動すれば成功です。

[Hyperloopモジュールを試す（2）動かしてみよう](http://qiita.com/yagi_/items/5abadef39f689c8f48c7)へ続く
小ネタ：git diffの大きな差分をTextEditorで見る

gitはCLI派です。
しかし差分が大きいと見にくいので、そこはエディタなどに移して確認したい。

```bash
$ git diff --color | pbcopy
```
でTextEditorにコピーするとANSIコードが色として解釈されない。
なので一旦以下の方法でやることにしました。

```bash
$ git diff --color > diff.txt
$ # Cmd + K
$ cat diff.txt
$ # コピペ
```

もっと良い方法あったら教えてください。
備忘録 Web Extensions 周りでメタなところの各ブラウザーの違いの調査

EdgeのInsider Preview版にもWeb Extensionsが実装され、Safariを除く(SafariにおいてはWebkitのステータスリストにすら載っていない)主要ブラウザーにおいてWeb Extensionsで拡張機能を実装できるようになりました。そこでWeb Extensionsで拡張機能開発のメタ的なところを中心に調べてみた。

##Edge
#### # manifest.json  
 authorキーが必須。また、backgroundを使用する場合は、persistentサブキーが必須になる。
 Firefoxではapplicationsキーでブラウザーの対象バージョンを指定しているが、Edgeの場合はminimum_edge_versionキーで指定する。

```json
{
  "minimum_edge_version": "37.14316.1000.0"
}
```

#### # Extension APIオブジェクト  
 chromeオブジェクトではなくbrowserオブジェクトがEdgeでのExtension APIのルートオブジェクトとなる

```js
 let chrome = chrome || browser;
```
 を最初に書けばChromeと同じコードで実装できる
#### # 開発版インストール方法  
 about:flagsにアクセスし、開発者向け設定のEnableExtension developer featuresにチェックを入れる
 メニューに拡張機能という項目が追加されるのでそこから、フォルダ選択によってインストールできる
#### # ストア  
 ストアはアプリストアになる予定。

##Firefox
#### # manifest.json
applicationsキーがないとインストールすることができない。
 
```json
{
  "applications": {
    "gecko": {
      "id": "borderify@mozilla.org",
      "strict_min_version": "45.0"
    }
  }
}
 ```

 ただ、このapplicationsの設定のまま状態でChromeなどにインストールしようとするとUnrecognizedエラーが発生するため、Chromeにもインストールさせる場合、manifest.jsonを別々に用意しなければならない。
#### # Extension APIオブジェクト 
 Chromeと同じように、chromeがExtension APIのルートオブジェクトとなる。
#### # 開発版インストール方法
about:debuggingにアクセスし、"一時的なアドオンを読み込む"ボタンからmanifest.jsonを選択する
"一時的なアドオンを読み込む"で読み込んだものはFirefoxを終了するとアンインストールされる。
(開発版ではないが未署名のものをインストールするにはabout:configにアクセスし、xpin.signatures.requiredの値をfalseにする)
#### # ストア
公式でAMOと略している[addons.mozilla.org](https://addons.mozilla.org/ja/firefox/)が公開サイトとなる。
AMOに登録するには署名する必要があるみたいで、署名方法がちょっと調べた限りわからなかった。
#### # その他
[Are we WebExtensions yet?](http://arewewebextensionsyet.com/)でAPIサポート状況を見ることができる。
Web Extensionsが実装されるのはバージョン48からだそうで、48がリリースされるのは8月らしい。

##Opera
ストアちがうだけでChromeと同じ
#### # ストア
[Operaアドオン](https://addons.opera.com/ja/)というサイトが公開サイトとなる。
Chromeウェブストアでは拡張機能の場合はアイコンやスクリーンショットは登録不要だが、Operaアドオンでは拡張機能でもアイコンとスクリーンショット(最低1つ)を登録しなければならない。
ただ、Chromeの場合デベロッパーモードでインストールすると、Chrome再起動時に、"デベロッパーモードの拡張機能を無効にする"というポップアップが表示されるが、Operaでは、開発者モードでインストールした場合、(今のところ)Operaを再起動してもそういったポップアップが表示されない。なので、野良な拡張機能をインストールしても何らかのアクションが起きることなくブラウザーを使用することができる。

##Vivaldi
ストアもChromeウェブストアとなり、そのほかもChromeと同じ。
違うのは、Operaと同じで、デベロッパーモードでインストールしても、再起動時に拡張機能を無効にするポップアップが表示されない。

#あとがき
コードレベルではほぼワンソースでマルチブラウザー展開できるようになったけど、ストアへの登録(公開)方法がもうちょっと統一的なものになってほしいと願う。
YoutubePlayerAPIで一つの動画をループ

1,2年くらい前に使ったときは違ったかも？と思ったのでメモ。

この間、YoutubePlayerAPIでサイトの背景として動画をループさせたい時がありました。

YT.Playerのインスタンスを作る際に、 playerVarsに loop: 1 を指定すれば動くと思っていたらループしてくれなかったのでよくよくドキュメントを読んでみたらplaylistにもvideoIDの指定が必要でした。

```
const player = new YT.Player(elementID, {
  width: 640,
  height: 480,
  videoID: videoID, // 動画のID
  playerVars: {
    loop: 1,
    playlist: videoID // playlistにもvideoIDと同じ動画のIDを指定
  }
});
```

[YouTube 埋め込みプレーヤーとプレーヤーのパラメータ](https://developers.google.com/youtube/player_parameters?hl=ja#listtype)
ネタとかメモとか にゃ

# これは！？

* 書きたいことを、書く前にメモったり、していくためのページ
* とりま、ネタをパクっていただいて、各自シェアしていただいて構いません

## ネタ系

* GW企画 コワーキング旅行＋ITイベント野良参加
    * [企画中](http://qiita.com/YooWaan/items/1185418bccfe911867d1)
* DSLやってみた

## メモ系

* チーム系
* OSS ビジネスモデル系
* ネットワーク系

## 参考リンク置き場


特にない
【今更感】AndroidAnnotations導入

# 公式サイト
http://androidannotations.org/

# 導入手順
自分はGradleで導入したので、ここではGradleでの導入方法を書きます。
> 公式のGet Startedはこちら
https://github.com/excilys/androidannotations/wiki/Configuration

## build.gradle(Project)に色々追加
- buildScriptのrepositoriesの向き先をjcenter()からmavenCentral()に変更
- dependenciesに「android-aptを追加」

```
buildscript {
    repositories {
        mavenCentral() // 追加
        // jcenter() ※コメントアウト
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.5.0'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' // 追加
    }
}
```

## build.gradle(Module)に色々追加
- android-aptをapply
- dependenciesに「androidannotations」と「androidannotations-api」を追加

```
apply plugin: 'com.android.application'
apply plugin: 'android-apt' // 追加
def AAVersion = '4.0.0' // 追加

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "~~~"
        minSdkVersion 19
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.2.1'
    compile 'com.android.support:design:23.2.1'
    apt "org.androidannotations:androidannotations:$AAVersion"
    compile "org.androidannotations:androidannotations-api:$AAVersion"
}
```

これでGradleをSyncしたらandroidannotationsを利用できるようになっていると思います。
試しにActivityをEActivityで書いてみましょう。

...続きは後で書きます。
centos7 drupal8 構築メモ

vagrantインストール
自分でチェック

vachalboxインストール
自分でチェック

apacheインストール
http://weblabo.oscasierra.net/apache-installing-apache24-yum-centos7-1/

mysqlインストール
http://weblabo.oscasierra.net/installing-mysql57-centos7-yum/

phpインストール
http://centos.server-manual.com/centos5_apache2_php5.html

vagrant ssh
sudo yum -y install git
git clone https://github.com/dotinstallres/centos65.git
cd centos65
./run.sh
PHPをアーカイブ版からビルドするときはbisonのバージョンなんて関係なかったんや…という話

PHPをソースコードからビルドする場合に、`./configure`で次のような警告が出ることがあります。

```
configure: WARNING: This bison version is not supported for
 regeneration of the Zend/PHP parsers (found: 2.3, min: 204,
 excluded: ).
```

この警告に対応するため、bisonのバージョンを気にして別バージョンのものを用意している人が多いかと思います。でも、アーカイブ版のPHP(http://php.net/downloads.php) では折角用意したbisonが使われていないことに気づきました。


```
$ ls -la Zend/zend_language_parser.?
-rw-r--r-- 1 hnw wheel 256140  4 29 03:13 Zend/zend_language_parser.c
-rw-r--r-- 1 hnw wheel   8148  4 29 03:13 Zend/zend_language_parser.h
-rw-r--r-- 1 hnw wheel  46862  4 29 03:12 Zend/zend_language_parser.y
```

アーカイブ版のPHPってbisonが生成するファイルも同梱してるんですよね。上の警告では「このbisonだとパーサが再生成できないかも」って言ってるんですが、そもそも生成後のファイルの方が新しいので、通常であれば再生成されることはありません。ビルド後にこれらのファイルの更新日時を確認すればbisonが仕事をしていないことを確認できます。

ビルド前に`.c`と`.h`を明示的に削除するなり、`.y`をtouchするなりすればbisonに仕事をさせることもできます。
Log4netでハマったとき

あるプロジェクトでLog4netを使い始めるとき、同じことで何度もハマったことがあるので、メモしておく。

## 設定が読まれていない？

AssemblyInfo.csにXmlConfiguratorを記述してConfigFileを指定するとき、ディレクトリセパレータはバックスラッシュではなくスラッシュを使おう。

## ログが出力されない？

Cドライブ直下をログファイルの出力先に指定すると、権限が足りずに出力できないことがある。そのときにエラーが出ないことがあるのでハマる。c:/users/ユーザ名/Documents/プロジェクト.logのような出力先を指定してみると、あっさり解決したりする。
MyBatis-Spring 1.3からSpringのトランザクションタイムアウト値が連携される！！

MyBatis-Spring 1.2系(+MyBatis 3.3系)までは、Spring側で指定したトランザクションタイムアウト値が無視されていましたが、MyBatis-Spring 1.3(+MyBatis 3.4)からタイムアウト値がMyBatisが発行するクエリーのタイムアウト値に連携されるように改善されました :+1: 

# 動作検証バージョン

* MyBatis 3.4.0
* MyBatis Spring 1.3.0
* Spring Framework 4.2.5.RELEASE
* Spring Boot 1.3.3.RELEASE

# Springのトランザクションタイムアウト値ってどう使われるのか？

まず、Springのトランザクションタイムアウト値がどのように使われるのかを、Spring純正の`JdbcTemplate`を使った時の動作を例に説明しましょう。なお、SpringのトランザクションマネージャーにはJDBC(`java.sql.Connection`)のAPI(`commit`,`rollback`)を使ってトランザクションを管理する`DataSourceTransactionManager`を使用します。

> **Note: JTAを使う場合は・・・**
> トランザクションマネージャーとしてJTAを使う場合は、JTAが提供しているタイムアウト検知の仕組みが利用されます。今回の記事では扱いません。

![transactionTimeout.png](https://qiita-image-store.s3.amazonaws.com/0/117313/c7781eb5-c04b-5352-0174-1a4d6be89d5b.png)

| 項番 | 説明 |
| :---: | --- |
| ① | Controllerからトランザクション境界のメソッド(Proxyオブジェクトのメソッド)を呼び出す。Proxyオブジェクトのメソッドを呼び出すと、トランザクションの制御を行うクラス(`TransactionInterceptor`)が呼び出される。 |
| ② | `TransactionInterceptor`は、`DataSourceTransactionManager`のメソッドを呼び出してトランザクションを開始する。`DataSourceTransactionManager`は、`@Transactional`からタイムアウト値を読み取り、`ConnectionHolder`(トランザクション内で共有する`java.sql.Connection`を保持する領域)に設定する。 |
| ③ | `TransactionInterceptor`は、トランザクション開始後にServiceのメソッドを呼び出す。 |
| ④ | Serviceは、`JdbcTemplate`のメソッドを呼び出してデータアクセスする。 |
| ⑤ | `JdbcTemplate`は、`DataSourceUtils`のメソッドを呼び出して`java.sql.Statement`のクエリータイムアウトにトランザクションタイムアウトの残り時間を設定する。 |
| ⑥ | `JdbcTemplate`は、`Statement`のメソッドを呼び出してSQLの実行を依頼する。 |
| ⑦ | `Statement`は、データベースにSQLを実行する。 |


# MyBatis-Spring 1.3はどうやってSpringのトランザクションタイムアウト値を連携しているのか？

基本的な流れはSpring純正の`JdbcTemplate`使用時と同じですが、MyBatisの場合は、MyBatisが独自に提供しているトランザクションを抽象化するインタフェース(`org.apache.ibatis.transaction.Transaction`)から取得したタイムアウト値を`Statement`に設定する仕組みになっています。タイムアウト値を取得するためのメソッド(`getTimeout`)はMyBatis 3.4から追加されたメソッドで、MyBatis-Spring 1.3からこのメソッドが実装されています。

![transactionTimeoutOnMyBatis.png](https://qiita-image-store.s3.amazonaws.com/0/117313/0219c093-b19c-a939-eb03-83acdb25923f.png)


# MyBatis側のクエリータイムアウト値はどう扱われるのか？

MyBatisには、クエリータイムアウト値を指定する仕組みがもともと用意されており、設定値はSQL単位に指定することができます。（省略した場合はMyBatisの設定で指定したデフォルト値が適用されます）
Springのトランザクション管理下でMyBatis側にクエリータイムアウト値が指定されていた場合は、**トランザクションタイムアウトの残り時間より短い場合は、MyBatis側の設定が有効**になります。


# トランザクションコミット時のタイムアウト検知について

クエリーの発行時にはトランザクションタイムアウトにならなかったが、コミットする時にトランザクションタイムアウトになっているケースはどのような動作になるのでしょうか？
すくなくても投稿時点(2016/4/30時点)では、`DataSourceTransactionManager`を使う場合はタイムアウトは検知できません。この事象の詳細や対処方法については、@yoshidan さんの[記事「Spring Bootとmybatisでトランザクションタイムアウトが効かない」](http://qiita.com/yoshidan/items/7ce240ead835d48ce2a1)をご覧ください。


# まとめ
`@Transactional`で指定したタイムアウト値がMyBatis側にも連携されていると勘違いしているエンジニアは多いのではないのでしょうか？（直感的には連携されてほしいし、私自身も連携されているものだと決めつけていた一人です・・・ :sweat_smile: ）
MyBatis-Springユーザーの方は、ぜひMyBatis-Spring 1.3 + MyBatis 3.4へのバージョンアップを検討してみてください。


# 参考サイト

* [Spring Bootとmybatisでトランザクションタイムアウトが効かない](http://qiita.com/yoshidan/items/7ce240ead835d48ce2a1)
BigQuery UDFでJSONのデータを扱う

BigQueryで、カラムにJSON文字列で格納されたデータを扱います。

データ例(tab区切り):

```
id	family
1	{"father":"taro","children":[{"name":"ichiro","age":7},{"name":"jiro","age":6},{"name":"saburo","age":5}]}
2	{"father":"masayuki","children":[{"name":"genzaburo","age":19},{"name":"genjiro","age":17}]}
3	{"father":"Micheal","children":[{"name":"John","age":10},{"name":"Paul","age":9},{"name":"George","age":8}]}
```

## JSON関数

BigQueryのクエリにはJSONを扱う関数が用意されています。
https://cloud.google.com/bigquery/query-reference#jsonfunctions

関数を使うとJSONPathライクな表現でJSON内のデータを抽出できます。

例：fatherを抽出

```
SELECT id,  JSON_EXTRACT_SCALAR(family, '$.father') as children FROM [test.families]
```

例：長男の名前を抽出

```
SELECT id,  JSON_EXTRACT_SCALAR(family, '$.children[1].name') as children FROM [test.families]
```

## UDF

例えば、末っ子の名前一覧を取得したいとします。

JSONPathだと、```$.children[(@.length-1)].name```の様に書けるのですが、これはBigQueryだとエラーになります。
リファレンスによると残念ながら"bracket notation is not supported. "とのことです。

そこでUDF(User Defined Functions)使ってみます。
https://cloud.google.com/bigquery/user-defined-functions

UDFを使うと、行の抽出ロジックをjavascriptで書くことが出来ます。

BigQuery UIのクエリ入力エリア右上のタブでUDF入力エリアを表示できます。

<img width="464" alt="スクリーンショット 2016-04-30 11.24.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/31437/1d89a882-7c25-72fa-e851-84a2657ce6b4.png">

UDF:

```
bigquery.defineFunction(
  'getYoungestChildName', // 関数名
  ['id', 'family'], // 入力カラム名
  [{name: 'id', type: 'INTEGER'},{name: 'youngest_child_name', type: 'STRING'}], // 出力スキーマ定義
  function(row, emit) {
    var family = JSON.parse(row.family);
    var name = family.children.length > 0 ? family.children[family.children.length - 1].name : null;
    emit({id:row.id, youngest_child_name:　name});
  }
);
```

UDFで定義されたfunctionは1行を受け取って、何らかの処理（変換や抽出）を行って1 or 0行を返します。
引数に渡されるemit関数を呼んで結果行を返します。行を結果に含めない場合はemitを呼ばなければOKです。

Query:

```
SELECT id,  youngest_child_name FROM (
  getYoungestChildName([test.families])
)
```

上の例ではgetYoungestChildNameパラメータにテーブルを渡していますが、サブクエリを渡すことも出来ます。

```
SELECT id,  youngest_child_name FROM (
  getYoungestChildName(select * from [test.families])
)
```

<img width="217" alt="スクリーンショット 2016-04-30 10.54.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/31437/00c1414e-0d4c-ac6d-1db8-ab7fb221d45c.png">

**抽出できました！**
**＼(^o^)／**

## 応用

この記事の例でもう少し汎用的にやるのなら、末っ子情報をJSONで返して、呼び出し側でJSON関数で扱える様にしてもいいかもしれません。

UDF:

```
bigquery.defineFunction(
  'getYoungestChild',
  ['id', 'family'],
  [{name: 'id', type: 'INTEGER'},{name: 'youngest_child', type: 'STRING'}],
  function(row, emit) {
    var family = JSON.parse(row.family);
    var child = family.children.length > 0 ? family.children[family.children.length - 1] : null;
    emit({id:row.id, youngest_child:　JSON.stringify(child)});
  }
);
```

Query:

```
SELECT 
  id,  
  JSON_EXTRACT_SCALAR(youngest_child, '$.name') as name, 
  JSON_EXTRACT_SCALAR(youngest_child, '$.age') as age, 
FROM (
  getYoungestChild([test.families])
)
```

## 感想

UDFはクエリのスカラー関数を自分で定義できるものかな、と勝手に想像していたのですがちょっと違ってました。
とは言え、スカラー関数相当の処理は（少し面倒ですが）実現できるし、他に出来ることも多いので、とても有用だと思いました。

UDFによってMap-ReduceのMap処理に相当するものをjavascriptで記述できて、処理は勝手に大量のGoogleサーバーに分散されて短時間で完了します。
ある程度のMap-ReduceはBigQueryだけで完結させることができそうです。
Xamarinをプレビュー版（Alphaチャネル）に切り替える　（iOS Simulator for Windowsのエントリーへのリンク追加）

先日、アメリカで行われたXamarin Evolve 2016は本当に衝撃的でしたね。
すぐにでも利用したい機能が大量にありました。
まだ見ていない方は、具体的にどんな内容だったかは、XLsoftの田淵さんのブログをご覧になってみてください。

> 【速報】Evolve 2016 で発表されたエキサイティング情報まとめ
> [http://ytabuchi.hatenablog.com/entry/evolve2016](http://ytabuchi.hatenablog.com/entry/evolve2016)

さて、非常に魅力的な機能が山盛りですが、基本的に（たぶんほとんど全て）はまだStableには下りてきておらず試すことができません。
試してみるにはXamarinをAlphaチャネルに切り替える必要があります。
本エントリーはその方法の簡単な解説になります。

また本エントリーはもともとEvolveで発表のあったiOS Simulator for Windowsの設定方法を書くにあたってその事前準備として書きました。
Visual Studio使いとしては非常に魅力的な機能です。
ぜひ以下のエントリーもご覧ください。

> Xamarin で iOS Simulator for Windowsを導入する方法
> [http://nuits.hatenadiary.jp/entry/2016/04/30/130725](http://nuits.hatenadiary.jp/entry/2016/04/30/130725)

# はじめに
XamarinのAlphaチャネルは非常にバギー（バグがてんこ盛り）です。  
Xamarinのお偉いさんがEvolveで言い切っちゃうくらいバギーです。
なので、あくまでも自己責任のもと実施してください。

# Xamarin for Visual Studioの場合
まずVisual Studioを起動し、以下のように「ツール」→「オプション」を開いてください。

![0000.png](https://qiita-image-store.s3.amazonaws.com/0/99262/473fb8ea-1499-75f6-ef55-079b8ac93e5d.png)

開かれたオプションダイアログの中で下のほうにある「Xamarin」→「Other」を開いてください。

![0001.png](https://qiita-image-store.s3.amazonaws.com/0/99262/8e80cb86-0cca-0126-690f-ee2a2a113f75.png)

その後、③のプルダウンから「Alpha」を選択し、④の「Check Now」を開いてください。
すると以下のようなダイアログが開かれますので、「Download」ボタンを押下してください。

![0002.png](https://qiita-image-store.s3.amazonaws.com/0/99262/519253fc-2658-8d94-bb0e-42ef2bf9d899.png)

なお、画面では「Stable」が選ばれていますが、私の環境がすでに「Alpha」が入っているため、ダウンロード画面が開けないための苦肉の策です。
実際には「Alpha」を選んでください。
またバージョンもやや異なりますが、気にしないでください。

ダウンロードが完了すると、インストーラが起動します。
後はインストーラに従って実行すれば完了です。

# Xamarin Studioの場合

まずXamarin Studioを起動し、メニューの「Xamarin Studio」から「Check for Updates...」を選択してください。

![0003.png](https://qiita-image-store.s3.amazonaws.com/0/99262/4a9283b7-e336-aa1b-e64b-e34b9e59189c.png)

開かれた以下のダイアログでUpdate Channelを「Alpha」に変更します。

![0004.png](https://qiita-image-store.s3.amazonaws.com/0/99262/da2c4ffe-de17-6bef-4cb3-ad65319ad554.png)

すると以下のように対象のリストが表示されます。
（ここでは「Stable」になっていますが、「Alpha」が正しいです。）

![0005.png](https://qiita-image-store.s3.amazonaws.com/0/99262/19d38e53-bb7a-8408-653e-08785f1ebb94.png)

上の画面で、「Switch channel」を押下するとダウンロードが開始されます。
ダウンロードが完了すると、インストーラが起動します。
後はインストーラに従って実行すれば完了です。

以上です。
バギーだけど魅力的なXamarin Alphaをお楽しみください！
CentOSにGo言語をインストール。Hello Worldまで。


CentOSは以下を使用

```
cat /etc/system-release
CentOS release 6.5 (Final)
```

### Go言語をインストール

[こちら](https://golang.org/dl/)のリンクから最新版のURLを取得してください。
今回は1.6.2を使用

```
cd /usr/local/src
sudo wget https://storage.googleapis.com/golang/go1.6.2.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.6.2.linux-amd64.tar.gz
```

パスを読み込みます。
今回はbashの例で。

```~/.bashrc
export PATH=$PATH:/usr/local/go/bin
```

```
source ~/.bashrc
```

これで準備は終了です。

### Go言語でHello World

```hello.go
package main

import "fmt"

func main() {
    fmt.Printf("hello, world\n")
}
```

では実行してみます。

```
go run hello.go
hello, world
```
失敗しないプロジェクト管理：3. 話をよく聞く

コミュニケーションを必要な人と適切にとる

もっとも大事なのはプロジェクトオーナーとのコミュニケーションです。
もちろんメンバーのモチベーションアップ、進捗管理なども重要ですが、成功の必要条件かいうとそうではありません。
やはり、プロジェクトの成功・失敗の判断をするお客様 ( 社内でのプロジェクトをやっている方も あなたが会社から給料をもらっている以上は上司や経営層は”お客様”です）が最も大切です。
 
 
以上これら３つのポイントはITプロジェクトの規模の大小を問わず、いかなる場合において重要かつ成功のための必須条件です。裏を返せば、この３つはいかなる状況においても妥協してはいけません。
「今回はプロジェクトの範囲があいまいでみんなの認識がずれてるような、、」
「期間も長めのプロジェクトだし、リスクは起きてから考えよう、、」
「いろいろ意見聞いてもうるさいから、俺に任せておけばいいものができる！」
こんなプロジェクトは１００％失敗します。(繰り返しますが失敗か成功を決めるのはプロジェクトマネジャーのあなたではなくプロジェクトオーナーであることを忘れないように。)
また、「変更管理表を作る」「ＷＢＳをきちんと詳細に作る」「ドキュメントを整備する」などは”葉”の部分であり、成功のための必要条件ではありません。プロジェクトを成功させる秘訣は、３つのポイント＝”幹”の部分を必ずやり抜くことです。
Kubuntu16.04でpeercast

# 前置き
去る4月21日、ubuntu16.04がリリースされ、更新しようとしたら、日本語対応がまだなのか、自分が悪いのかわからないけれど、ともかく、デスクトップ環境が死んだ。更に自分でゴチャゴチャにいろいろ消滅した。ということで、peercast環境を再構築する機会となりました。

# 概要
## 視聴に使うもの
* PeerCastStation
  * mono
* QPeercastYP
  * build-essential
  * libqt4-dev
* PurePlayer
  * mplayer
  * qt4-default
  * g++


peercast本体と、チャンネルリストを見るもの、配信を見る動画プレイヤーが揃えれば快適なpeca生活が送れます。これはubuntuでも同じです。

## 配信に使うもの
* obs-studio
  * ffmpeg
* bbiff
  * libnotify-bin

エンコーダーとレス表示があったらいいでしょう。

## 問題点
初期の状態で
* 音が出ない
* 日本語の入力ができない
という状態だと困る。

# Kubuntuをインストールした直後から
Kubuntuではkonsoleという端末があるので、alt+spaceから出る窓などを使ってkonsoleを起動させましょう。なにはともあれ、

```
sudo apt-get update
sudo apt-get upgrade
```

をしておきましょう。
peercast関係のものを入れたり、ソースを入れたりする場所がないとゴチャゴチャするので、peercast関係のディレクトリを作っておくのがいいと思います。自分は~/pecaにいれてます。

## PeerCastStation
[http://www.pecastation.org/](http://www.pecastation.org/)から安定版もしくは開発版の最新のzipをDLし展開。更新ごとに何度もリンクを開くのが嫌な人は自分でスクリプトを用意しておくといいと思います。起動にはmonoが必要なので、

```
sudo apt-get install mono-complete
```

でインストールしましょう。

```
mono PeerCastStation.exe
```

で動きます。止めるときはctrl+cで止めます。たまに中々終了しないこともあるので、その時はkillします。

## QPeerCastYP
githubにソースがあるので、コンパイルして使ってます。ソースはgitで取ってくるのが良さそうなので

```
sudo apt-get install git-core
```

で入れましょう。githubのREADMEにあるように

```
sudo apt-get install build-essential libqt4-dev
git clone https://github.com/bookdraft/QPeerCastYP.git
cd QPeerCastYP
./configure
make
sudo make install
```
これにより、パスが通っているであろうところにインストールされるので、

```
qpeercastyp
```

だけで起動させることができるようになります。


## PurePlayer
ソースはgithubにあります（https://github.com/nelkana/PurePlayer_As.git）
まず必要なものを入れましょう

```
sudo apt-get install mplayer qt4-default g++
```

g++あたりはすでに入っているかもしれません。

```
git clone https://github.com/nelkana/PurePlayer_As.git
cd PurePlayer_AS
qmake
make
```

という順でコンパイルが通れば、pureplayerという実行ファイルができるので、qpeercastの設定のプレイヤで指定してください。
種類は wmv|ogm|nsv|flv で、引数は $STREAM_URL としておけばokです。

windowsのときと同様に、YPの設定とPeerCastStationの帯域の設定などが済めば、ソフトは揃ったと言えるでしょう。

## 問題の解決
### 音
環境によって違うので特定の解決策がないと思われる。いろいろいじったが、kmixを入れ、これ実行して出るアイコンをクリックしてMixerと書いてあるボタンを押して出てくるものをいじって、音が出る環境を探すしかないように思われる。

### 日本語入力
mozcを使います。

```
sudo apt-get install fcitx-mozc
```

その後、右下のキーボードのアイコンを右クリックからRestartして、使えるようになります。使い方は、ctrl+spaceを押すと、キーボードのアイコンが「あ」と書かれたアイコンに変わります。この状態だと、日本語入力ができます。この状態で、英数ボタンを押すと、アルファベットが入力できます。もう一度ctrl+spaceを押してもアルファベットが入力できます。英数ボタンを使うと最初は戸惑うことがありそうなので、ctrl+spaceを使うといいと思います。

ここまでいけば、リスナーとして楽しめるでしょう。

# 配信するには

## OBS
OBSがubuntuでも使えるので、これを使うといいでしょう。
ffmpegを入れて、obs-studioをppaからインストールする。後は、少し見た目が違うけれど、windowsと同様の設定をする。
ppaを使うために

```
sudo apt-get install software-properties-common
```

で add-apt-reopsitory を使えるようにします。
ffmpegは単に

```
sudo apt-get install ffmpeg
```

公式サイトの14.04用の説明に出てくるようなffmpegのppaの登録を間違ってすると、インストールできないので、注意してください。

obsはppaを使って

```
sudo add-apt-repository ppa:obsproject/obs-studio
sudo apt-get update && sudo apt-get install obs-studio
```

でインストールできます。起動は

```
obs
```

でできます。

## bbiff
notify-sendを利用したレス通知。ruby製。gemとして公開されている。
notify-sendを使うために

```
sudo apt-get install libnotify-bin
```

して、bbiffのインストールは

```
gem i bbiff
```

で、

```
bbiff スレッドのURL レス通知を始める番号
```

のように使う。二度目からの起動では指定しなくても続きのレスを通知してくれる。
技術英語 > as really a preemptive measure in case ...

@ LOE > April 4, 2003

http://loe.org/shows/shows.html?programID=03-P13-00014
> simply as really <font color=red>a preemptive measure</font> in case someone gets sick in the office

http://eow.alc.co.jp/search?q=pre-emptive&ref=wl
> 1. 先手を取る、先制攻撃の

http://eow.alc.co.jp/search?q=measure
> 11. 手段、方策

a preemptive measure
で「予防措置」というような意味なのだろう。(正確な和訳は不明)。

<hr>
RTOS の preemptive は少し意味合いが違うように思う。

https://en.wikipedia.org/wiki/Preemption_(computing)
RedHat LinuxにてMACアドレスが変更となった場合の対応方法

# 1.インタフェース設定ファイルの編集
MACアドレスが変更となった場合、まず /etc/sysconfig/network-scripts/ 配下にあるインターフェース設定ファイル内に記載されているMACアドレスの編集をします。

```ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
BOOTPROTO=none
IPADDR=192.168.0.53
HWADDR=00:0C:29:5D:0B:58 ⇦ ここを変更後のMACアドレスを変更
```


# 70-presistent-net.rules

/etc/udev/rules.d フォルダ配下にある「70-presistent-net.rules」に角NICの設定が記載されています。
このファイルの古いMACアドレスに関する行を削除し、変更後のMACアドレスが書かれれている行のNAMEを"eth0"に変更して、再起動します。
OpenCVをCondaで簡単にインストール

OpenCVをインストールする際にはまったので、備忘録がてら書いていきます。

#やりたいこと
- python (spyder) 上で OpenCVを使えるようにする。
- Open CV のバージョンには特にこだわらない。
- できるだけ簡単に。

#環境
Ubuntu 14.04
Python 2.7
Anaconda

#やったこと
こちらのサイト [pythonでOpenCVを使う一番簡単な方法]
(http://qiita.com/ru_pe129/items/8a1a75cdf713d4fa6bc8) を参考にしました。ありがとうございます。
すでにAnacondaの環境はあるので、Condaを使ってインストール。
terminal 開いて、下記の１行コマンド入力するだけ。
`conda install -c https://conda.binstar.org/jjhelmus opencv`

あっさりインストール完了。簡単すぎます。サンプルコードで動作確認。

```
import numpy as np
import cv2
img = cv2.imread('sample.jpg')
cv2.imshow('sample', img)
cv2.waitKey(0)
```

imshowのところで、下記のエラーで怒られる。依存関係が足りないらしい。
そのため、画像の読み込みや保存はうまくいくけど、どうも別Windowを立ち上げるような動作ができない。

```
error: -------src-dir-------/opencv-2.4.10/modules/highgui/src/window.cpp:501:
error: (-2) The function is not implemented. Rebuild the library with Windows, 
GTK+ 2.x or Carbon support.
If you are on Ubuntu or Debian, 
install libgtk2.0-dev and pkg-config, 
then re-run cmake or configure script in function cvShowImage
```

んで、apt-getで、libgtk2.0-devとpkg-configをインストール。
ところが、どっちもすでにインストール済の様子。**じゃあなんで????**
ググっていろいろやってみたけど、解決せず。

んで、辿り着いたのがこの[Anacondaのサイト](https://anaconda.org/menpo/opencv)。
さきほどインストールしたopencvを一旦アンインストール。
`conda uninstall opencv`

それで、こっちのOpenCVをインストール。
`conda install -c menpo opencv=2.4.11`

Windowもちゃんと出ました。何が原因かはわかりませんが、とりあえず動いたから良しとする。
Git の初期設定

Git の初期設定

Git を使う上で、自分が使う最低限の設定が以下になります。

#### コンソールでカラー表示を有効にする設定
```shell
$ git config --global color.ui true
```

#### 名前とEメールの設定
```shell
$ git config --global user.name "YOUR NAME"
$ git config --global user.email "YOUR@EMAIL.COM"
```
Docker上でcronからrubyを実行しようとしてハマった

Docker上でrubyで作ったbotをcronで動かそうとしたらハマりました。

## 最終的なDockerfile

```bash
FROM ruby:latest

MAINTAINER ABCanG <abcang1015@gmail.com>

RUN apt-get update && apt-get install -y cron

# timezone
RUN cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

RUN mkdir -p /app
WORKDIR /app

COPY Gemfile /app/
COPY Gemfile.lock /app/
RUN bundle install --deployment

COPY . /app

RUN env > /env

CMD echo '30 * * * * cd /app; env - `cat /env` ruby ./script.rb' | crontab - && cron -f
```

以下の事を実行しています

* cronをインストール
* タイムゾーンを日本に変更
* アプリをコンテナ内にコピーしてbundle install
* dockerコンテナ内の環境変数をファイルに書き出し
* cronで実行するスクリプトの登録とcronの実行

それぞれの説明は以下で

## cronのインストール
`ruby:latest`はdebianなので、apt-getでcronをインストールします。

## タイムゾーンを日本に変更
デフォルトではUTCになっているので日本時間に変更しています。
時間が関係ないスクリプトならスキップしても問題ないと思います。


## アプリをコンテナ内にコピーしてbundle install
デプロイするので`--deployment`を付けて`bundle install`してます。

## dockerコンテナ内の環境変数をファイルに書き出し
ハマリポイントその1です。
cronでは最低限の環境変数しか設定されません。
`ruby:latest`では環境変数にbundleやその設定ファイルのパスを設定するため、cronでbundleを実行したときと挙動が変わってしまいます。
これを防ぐため、先に環境変数をファイルに書き出しておき、cronでスクリプトを実行するときに環境変数を利用するようにしています。

## cronで実行するスクリプトの登録とcronの実行
ハマリポイントその2です。
echoの出力を`crontab -`に流し込むことで設定します。
その後`cron -f`でcronを起動させています。

下のようにcronの設定は分けたかったのですが、どうも上手く動かないのでしぶしぶこの方法に。
何がマズイんでしょうね…(納得していない)

```bash
RUN echo '30 * * * * cd /app; env - `cat /env` ruby ./script.rb' | crontab -
CMD ["cron", "-f"]
```

## おわりに
cronを使う時は注意が必要ですね。
もうちょっといい方法とかあれば教えてもらえるとうれしいです。
zfs send recvの差分転送を楽にする

zfs send recvは手で書くと面倒なものです。関数を用意しました。

```
#!/bin/bash
send_recv_new () { #初回
    local from=${1} &&
    local to=${2} &&
    local snapshot=${3} &&
    local temp=${4} &&
    echo "${from} -> ${to} @${snapshot}" &&
    zfs snapshot "${from}@${temp}" &&
    zfs send     "${from}@${temp}" | zfs recv "${to}" &&
    zfs rename   "${from}@${temp}" "@${snapshot}" &&
    zfs rename   "${to}@${temp}" "@${snapshot}"
}
send_recv_new '<fromfs>' '<tofs>' '<fromfs>_to_<tofs>' 'temp'


inner_send_recv () { #内部処理
    local from=${1} &&
    local to=${2} &&
    local snapshot=${3} &&
    local temp=${4} &&
    echo "${from} -> ${to} @${snapshot}" &&
    zfs send -i "@${snapshot}" "${from}@${temp}" | zfs recv -F "${to}" && #-iで増分を送る
    zfs destroy "${from}@${snapshot}" &&
    zfs rename  "${from}@${temp}" "@${snapshot}" &&
    zfs destroy "${to}@${snapshot}" &&
    zfs rename  "${to}@${temp}" "@${snapshot}"
}
send_recv () { #2回目以降
    local from=${1} &&
    local to=${2} &&
    local snapshot=${3} &&
    local temp=${4} &&
    zfs snapshot "${from}@${temp}" &&
    inner_send_recv ${from} ${to} ${snapshot} ${temp}
}
send_recv '<fromfs>' '<tofs>' '<fromfs>_to_<tofs>' 'temp'

send_recv_r () { #2回目以降（再帰）
    local from=${1} &&
    local to=${2} &&
    local snapshot=${3} &&
    local temp=${4} &&
    zfs snapshot -r "${from}@${temp}" &&
    for fs in $(zfs list -H -r -o name ${from}); do
        local unique=${fs#${from}} &&
        inner_send_recv "${from}${unique}" "${to}${unique}" "${snapshot}" "${temp}"
        if [ $? -ne 0 ]; then
            return 1
        fi
    done
}
send_recv_r '<fromfs>' '<tofs>' '<fromfs>_to_<tofs>' 'temp'
```
Proxmox VEのZFS Rootの複製

#事前にProxmox VEをインストールし、一つのパーティションだけ書き戻す方法（成功）
```
# NAS4Free
zpool import -f -d /dev/gptid -R /mnt/rpool rpool

zfs destroy -f rpool/ROOT/pve-1
zfs snapshot <tank>/pve-1@temp
zfs send     <tank>/pve-1@temp | zfs recv rpool/ROOT/pve-1
zfs destroy  <tank>/pve-1@temp
zfs destroy  rpool/ROOT/pve-1@temp

zfs set mountpoint=/ rpool/ROOT/pve-1
zpool export rpool

# Proxmox VE(ext4 root)
# インポートできるプールを確認
zpool import

# rpoolをインポート・アンマウント
zpool import -f -R /mnt/rpool rpool && zfs unmount rpool

# ACLを有効にする
zfs set acltype=posixacl rpool/ROOT && zfs set xattr=sa rpool/ROOT

# rpool/ROOT/pve-1を削除
zfs destroy rpool/ROOT/pve-1

# バックアップからrpool/ROOT/pve-1を復旧
zfs send tank20160418/pve-1@rpool_to_tank20160418 | zfs recv rpool/ROOT/pve-1

# マウントポイントを設定
zfs set mountpoint=/ rpool/ROOT/pve-1

# rpoolをエクスポート
zpool export rpool
```

#一からパーティションを作る方法（失敗）
もともと、下記のようなコードでProxmox VEのZFS Rootの複製ができるかと思ったのですが、zpoolのguidが変わるとブートできなくなるようでした。

ZFS Rootでブート中にやろうとするとrpoolが重複するため、MBR、BIOS boot partitionおよびrpool/ROOT/pve-1を一度HDDにコピーし、NAS4Freeでブートするという前提です。

```
#NAS4Free
#調査
geom disk list
gpart list
gpart show da1

#パーティション消去・作成
gpart destroy da1
gpart create -s gpt da1
gpart add -t bios-boot      -b 34 -s 2014    da1
gpart add -t '\!<partuuid>' -b 2048 -l 'zfs' da1
gpart set -a bootme -i 1 da1

#zpool作成
gnop create -S 4096 da1p2
zpool create rpool da1p2.nop
zfs set compression=lz4 rpool
zfs set atime=off rpool
zfs set sync=standard rpool

#zfs作成
zfs create rpool/ROOT
zfs create -V 2G -b 4K -o primarycache=metadata -o sync=always -o com.sun:auto-snapshot=false rpool/swap

#zpoolエクスポート・インポート
zpool export rpool
gnop destroy da1p2.nop
zpool import -d /dev/gptid -R /mnt/rpool rpool

#本体zfsコピー
zfs snapshot <tank>/<fs>@temp
zfs send     <tank>/<fs>@temp | zfs recv rpool/ROOT/pve-1
zfs destroy  <tank>/<fs>@temp
zfs destroy  rpool/ROOT/pve-1@temp

#確認
zpool list
zfs list

#zpool・zfs設定
zpool set bootfs=rpool/ROOT/pve-1 rpool
zfs set mountpoint=/ rpool/ROOT/pve-1
zfs set mountpoint=/rpool rpool

#zpoolエクスポート
zpool export rpool

#mbr・bios_bootコピー
dd if=/mbr1 of=/dev/da1 bs=512 count=1
dd if=/bios_boot1 of=/dev/da1p1
```
docker.el: docker 操作を magit/dired っぽく。

# docker.el

magit/dired みたいに、サクサクと docker 操作をしたいぜ、がモチベーションの elisp-package. `docker` コマンドが正しく実行できる場所から実行できる。 TRAMP してても実行できる。


# インストール

MELPA からインストール。そのままでもいいけれど、

```el
(docker-global-mode)
```

を実行しとくと便利。


# 使い方の例: container 操作について

`C-c d c c` で下のようなバッファが作成される。

![images.png](https://qiita-image-store.s3.amazonaws.com/0/62111/25794fd9-8f69-d7d3-6c1d-e59c5d4952ac.png)

何かと言うと、今実行している container のリスト。リストに対する操作でじゅうようなのは、 `m` でマーク、 `u` で解除、 `U` で全解除、など。 `tablist-mode` の操作もろもろが基本的に使える。

選択した container に対して、コマンドを実行する。今の所、 container に対してのコマンドでサポートしているのは以下。

* `S`: start                                                                                                               
* `O`: stop                                                                                                                
* `R`: restart                                                                                                             
* `P`: pause/unpause                                                                                                       
* `I`: inspect                                                                                                             
* `L`: logs                                                                                                                
* `D`: rm    

# その他いろいろな機能

README がしっかりしてるので、本家を参照するのがいいです。また、 issue や PR も積極的に解消されていくので、足りない機能をガシガシ追加していける感じです。

-> https://github.com/Silex/docker.el
mochaとは？

# mochaとは？

* JSのテスティングフレームワークの１つ。
アサーションの機能は用意されていない。
* ブラウザとNode.jsどちらでも実行できる。


## テスティングフレームワークとは？
テストの実行プログラムの作成、テスト結果の判定、集計などの機能を提供するもの。


## アサーションとは？
プログラムの前提として満たされるべき条件を記述し、実行時にそれが満せてない場合にエラーや例外を発生させる機能。

上記に記述した通りmochaはアサーションの機能はないため、今回はアサーションライブラリとしてchai.jsを使用する。

## install
### mochaのinstall
https://github.com/mochajs/mocha
に一通りファイルがある。
今回はpackage.jsonをローカル環境にコピペして

```
npm install
```
でinstallした。

### chaiのインストール

```
npm install chai
```

###　テスト
今回はブラウザでテスト結果を確認する。

以下のようなテストを書いた。

sample.html

```
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="node_modules/should/node_modules/should-format/tests/browser/mocha.css" />
    <title>テスト</title>
    <script type="text/javascript" src="node_modules/chai/chai.js"></script>
    <script type="text/javascript" src="node_modules/should/node_modules/should-format/tests/browser/mocha.js"></script>
    <script type="text/javascript">
      //TDD
      mocha.setup('tdd');
      // 各アサーションモジュールの読込み
      // assertの機能を読み込み
      var assert = chai.assert;
      // テスト対象のメソッド
      var testfunc = function(n) {
          return n;
      }
      suite('メソッドのテスト', function(){
        suite('testfunc()のテスト', function(){
          test('そのままreturnすることを確認',function() {
            assert.equal("3",testfunc(3),'引数を3');
          });
        });
      });
    </script>
  </head>
  <body>
    <div id="mocha"></div>
  </body>
  <script type="text/javascript">
  mocha.run();
  </script>
</html>
```

ブラウザで確認

```
open sample.html
```

![スクリーンショット 2016-04-30 1.57.12.png](https://qiita-image-store.s3.amazonaws.com/0/122149/27d98f36-0531-1a25-5e96-cbd9618acd0c.png)


成功時は問題なかった。assertionが正しくない時に失敗することも確認する。
前述のsample.htmlのassertの箇所を以下に変更

```
 assert.equal("4",testfunc(3),'引数を3');
```

![スクリーンショット 2016-04-30 2.01.27.png](https://qiita-image-store.s3.amazonaws.com/0/122149/864b3cdf-f1d0-ce4a-afd8-e3298abe77f1.png)

失敗することが確認できた。
go1.6.2のインストール

注意：goをソースからビルドするにはgo1.4以降が必要です。

Go 1.5 以降のビルド手順 - Qiita
http://qiita.com/orociic/items/b285cf205f75b7291a9d

go1.5のインストール - Qiita
http://qiita.com/ymko/items/649dc1a450855526cec7

# ビルド実行

```bash
$ cd ~/
$ curl -O https://storage.googleapis.com/golang/go1.6.2.src.tar.gz
$ tar xf go1.6.2.src.tar.gz
$ mv go go1.6.2
$ cd go1.6.2/src/
$ ./make.bash
Installed Go for linux/amd64 in /home/ymko/go1.6.2
Installed commands in /home/ymko/go1.6.2/bin

$ echo "PATH=\$PATH:\$HOME/go1.6.2/bin" >> ~/.bashrc
$ echo "PATH=\$PATH:\$HOME/.go/bin" >> ~/.bashrc
$ echo "export GOPATH=$HOME/.go" >> ~/.bashrc
$ source ~/.bashrc

ログオンし直す
$ which go
~/go1.6.2/bin/go
```

# ビルド時にgo1.4が自動的に検出されているのはなぜ？

GOROOT_BOOTSTRAPが定義されていない場合はホーム直下のgo1.4を使ってビルドする指定となっている。

```go:buildtool.go
func bootstrapBuildTools() {
  goroot_bootstrap := os.Getenv("GOROOT_BOOTSTRAP")
  if goroot_bootstrap == "" {
    goroot_bootstrap = pathf("%s/go1.4", os.Getenv("HOME"))
  }
  xprintf("##### Building Go toolchain using %s.\n", goroot_bootstrap)
```
nginx1.10.0+PHP7+pukiwikiでwindows上にローカルなpukiwikiを作る


# 前置き

Webサーバ系の知識殆ど無い状態からはたしてローカルにサクッとpukiwikiを置くことはできるのかという感じで始めたので色々間違ってる可能性があります　あしからず

# nginxのインストール

なんか色々できるらしいWebサーバ（雑）

http://nginx.org/en/download.html
から「nginx/Windows-1.10.0」をクリックしてダウンロード
終わったら適当な場所に（筆者の場合はドライブの直下に）解凍してインストールおわり　簡単

# PHP7のインストール

pukiwikiはphpで動くのでこいつを入れないといけません

http://windows.php.net/qa/
ここから「VC14 x64 Thread Safe」のzip版を選んでダウンロード
（筆者環境が64bitだったので64bit版にしました）
終わったら適当な場所に解凍して配置
（筆者の場合はドライブの直下に「php7」という名前のフォルダを作って解凍後のファイル群を放り込みました）

# nginxの起動

http://changineer.info/network/windows_setup/windows_httpd_nginx

こちらを参考にしながら（というか、以下の作業はだいたいこのページ準拠です）
nginxをインストールしたフォルダでコマンドプロンプトを開いて
「start nginx」
を行いnginxを起動
もしnginxプロセスが立ち上がっていない場合、
エラーログを確認しつつSkypeによるポート80などの専有を疑う

# PHP設定ファイルの作成

phpインストールフォルダ内にある
`php.ini-development`というファイルをコピペして`php.ini`として保存する
作法だそうです

# php-cgiを起動

コマンドプロンプトでphpをインストールしたフォルダに移動し、
`stat /b php-cgi.exe -b 127.0.0.1:9123 -c php.ini`
を実行

# nginxとphp-cgiの連携

nginx内の.phpにリクエストが送られた場合、
バックエンドで動作しているphp-cgiにそれを転送するための連携設定を行う
nginxインストールフォルダ/conf/nginx.confを開き

```nginx
location / {
    root  html;
    index index.html index.htm;
}
```

など書かれている項目の下辺りに以下の設定を入力する

```nginx
location ~ \.php$ {
    fastcgi_pass 127.0.0.1:9123;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include       fastcgi_params;
}
```

終わったら保存する
変更した設定を反映させるにはnginxを再起動させる必要があるので
コマンドプロンプトで
`nginx -s reload`
を入力しプロセスを再起動

nginxに.phpを一つ配置し、動作確認を行う
以下の記述を行ったファイルをnginxのhtmlフォルダに`index.php`という名前で保存する

```php
<?php
    phpinfo();
?>
```

ブラウザで以下のURLを閲覧し、情報が表示されることを確認する

`http://localhost/index.php`

終わったらpukiwikiつっこむために一旦別の場所に`index.php`ファイルは避けておく（削除してもよい）

# pukiwikiのインストール

本題

https://pukiwiki.osdn.jp?cmd=read&page=PukiWiki%2FDownload%2F1.5.1

ここから`pukiwiki-1.5.1_utf8.zip`をダウンロード
解凍後、中のファイル群をまとめてnginxのhtmlフォルダに放り込む

入れ終わったら`http://localhost/index.php`にアクセスしてpukiwikiが動作するか確認する
FrontPageがちゃんと表示されれば勝利

何かしら編集しようとすると凍結解除を要求されるので
管理者パスワードを使って凍結解除を行う
（管理者パスワードについてはpukiwikiの説明を読んでください）
凍結解除後、FrontPageとか編集して保存できたらもう大丈夫なはず　たぶん

# ひとりごと

あまり小難しい設定が特にいらなかった（ポート周りで手間取った程度）のでかなり雑な知識でもとりあえず手順さえわかれば導入自体は簡単に出来ました
外部公開していこうとか考えだすと色々設定気にしないといけないと思いますがまぁローカルってことでとりあえず動いたので満足

そしてnginx、かなり手軽に入れれるし動かせるので何かとwebサーバ系の勉強が捗りそうです
何かCGIゲームでも突っ込んで動かせないものか…SoSⅡとか…
gulpの基本機能で、除外ファイルを指定する

「一括で処理するけど、これは書き出ししたくない。」というとき、gulp-ignoreなどのnpm moduleを使うのも良いですが、シンプルなものであれば基本機能でまかなうことができます。

## `!`で除外

```js
gulp.src(['client/*.js', '!client/b*.js'])
```

このように'! (エクスクラメーションマーク)'をつけることで該当するファイルを除外できます。

## `_`で除外

また、このようにすることでも除外できます。

```js
gulp.task('less', function() {
    return gulp.src('less/[^_]*.less')
    .pipe(less())
    .pipe(gulp.dest('assets/css'))
});
```
OpenPGP(実際はGnuPGなど)の活用事例

# 序
最近、GithubでのOpenPGPの署名サポートの話題がありましたね。

この地味に使われているが、知名度的には高くないOpenPGPの利用事例(主としてオープンソース界隈)についての散文です。

なんか気付いたら追記していきます。

# 事例
* Gitのコミット類(タグなども)における署名
    * git-secret での秘匿情報の管理[^1]
* rpmやdebパッケージにおける署名(分散なので、WoTなOpenPGPがフィットする)
* メール暗号化
    * クライアントorプラグイン
        * [Enigmail](https://addons.mozilla.org/ja/thunderbird/addon/enigmail/)
        * [eM Client](https://emclient.jp/)
        * [sylpheed](https://sylpheed.sraoss.jp/ja/)
        * [chrome拡張機能Mailvelope](https://chrome.google.com/webstore/detail/mailvelope/kajibbejlbohfaggdiogboambcijhkke)
    * メールサービス
        * [Secure email: ProtonMail is free encrypted email\.](https://protonmail.com/)
* [Password-store](https://www.passwordstore.org/) という Unix的CLIでのパスワード管理ツール
    * Windowsでのツール : [Pass4Win](https://chocolatey.org/packages/pass4win)
    * Windowsでのツール : [pass-winmenu](https://chocolatey.org/packages/pass-winmenu)
    * クロスプラットフォーム : [QtPass GUI for pass, the standard UNIX password manager](https://qtpass.org/)
    * Go実装CLI : [gopasspw/gopass: The slightly more awesome standard unix password manager for teams](https://github.com/gopasspw/gopass)
    * __Emacsのauth-source(後述)相当がVimにないことに業を煮やして、Vimのプラグイン作った(そこまで大層なことではない)__[^2]
* AndroidだとOpenKeychainなどでPGPを利用できる。このツールだと、K-9、上記のPassword-store(のモバイル版)、Conversations(XMPPチャット)などで暗号化をサポートなんてのがあったり
* Emacsにおけるスクリプト内での秘密情報の埋め込み(gnus/auth-source.el を使う)、外部にOpenPGPで暗号化して保持し、スクリプト利用時に(主にagentを活用して)デコードして動かす
* 文書の暗号化、署名[^3]

K-9,Enigmailだと自動的に暗号メール(のための鍵交換の)やりとりができる[AutoCrypt](https://autocrypt.org/)に対応したらしい

[^1]: [Gitリポジトリ暗号化のススメ \- git\-secret \- \- Qiita](https://qiita.com/jqtype/items/9b0524baa4b7fe6dbde0)
[^2]: [Vim で auth\-source ライクなパスワード秘匿プラグインを作った \- Qiita](https://qiita.com/tsuyoshi_cho/items/a610272027ad3ec35352)
[^3]: [LibreOfficeで文書に電子署名](https://qiita.com/tsuyoshi_cho/items/4cf78f8f1d0a0dd94018)
Zabbixローレベルディスカバリで作成されたトリガーは、プロトタイプ上で無効にしても既存設定には反映されない

ローレベルディスカバリで作成されたアラートのうち、
アラートの深刻度が「致命的な障害」であるものを消すことになった。
以下のディスカバリ設定上のトリガーを「無効」にすることでまとめて反映させるようとしたが、
1台も反映されなかった。
`Free disk space is less than 5% on volume `

実は、プロトタイプ上のトリガーステータス(トリガーの有効無効)は、変更しても各サーバーに更新が反映されない。
このトリガーステータスについては、イメージ的には初期設定でしかないようだ。[チケット](https://support.zabbix.com/browse/ZBX-6083)で議論されている。

ステータスは無理でもアイテムの中身の変更は全台反映できるので、
今回は致命的な障害のレベルを下げることで対応した。
なおディスカバリールールの更新間隔を一時的に下げると、すぐ全台反映することができる。
Node 6.0.0でrnpmを実行するとエラーが出る。

## エラー

```
    Object.keys(pjson.dependencies || {}),
                ^

ReferenceError: pjson is not defined
    at e (/Users/ko/.nvm/versions/node/v6.0.0/lib/node_modules/rnpm/src/findPlugins.js:22:17)
    at Array.map (native)
    at findPlugins (/Users/ko/.nvm/versions/node/v6.0.0/lib/node_modules/rnpm/src/findPlugins.js:35:31)
    at getCommands (/Users/ko/.nvm/versions/node/v6.0.0/lib/node_modules/rnpm/src/getCommands.js:16:7)
    at Object.<anonymous> (/Users/ko/.nvm/versions/node/v6.0.0/lib/node_modules/rnpm/bin/cli:7:47)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:456:32)
    at tryModuleLoad (module.js:415:12)
    at Function.Module._load (module.js:407:3)
```

## 対策
Node 5.11.0なら動きます

## 感想
React Native周りにNode6.0.0を使用するのは危険だなぁ、と。
EC2接続時に運用・保守に必要な情報が表示されるよう設定

# EC2接続時に運用・保守に必要な情報が表示されるよう設定
## ■目的
・障害対応など運用保守を迅速に行うため
SSH接続時にインスタンスを特定出来る情報を出力したい
またその際、注意が必要なミドルウェアが実装されているかもあわせて把握したい

(例: 変更監視が動いているかどうかを事前に把握する)
→ 余計なアラートを挙げない、もしくは前もって周知出来る

## ■参考
・EC2インスタンスのbashプロンプトに便利情報を表示する
http://qiita.com/y13i/items/2d2c5b6f79e3aefd5de8
→　同僚のブログに触発されて、本件試してみました。

## ■前提
・AWS CLIが使える環境であること
・配置先は「/etc/profile.d/」配下、もしくは「~./bashrc」に追記

## ■実装例
```bash
# vim /etc/profile.d/motd.sh
------------
#!/bin/sh

# インスタンス情報取得
instance_id=$(curl -s 169.254.169.254/latest/meta-data/instance-id)
availability_zone=$(curl -s 169.254.169.254/latest/meta-data/placement/availability-zone)
region=${availability_zone%?}
public_ipv4=$(curl -s 169.254.169.254/latest/meta-data/public-ipv4)
tags_name=$(aws ec2 describe-instances --region $region --instance-ids $instance_id --query 'Reservations[].Instances[].[Tags[?Key==`Name`].Value]' --output text)

echo "------------------------------------------------------------------------------------"

# ミドルウェア実装状況確認
if rpm -qa | grep -i ds_agent; then
  echo -e " \e[1m\e[33mこのホストにはds_agentが入っています。\e[m\n"
else
  echo -e " \e[1m\e[33m ds_agent isn't installed \e[m\n"
fi

echo "Instance-id: $instance_id"
echo "public-ip: $public_ipv4"
echo "Tags-Key: $tags_name"
echo "------------------------------------------------------------------------------------"
```

## ■確認
・下記のようにSSH接続時、オペレーションに必要な情報を確認できました。

```bash
% ssh mitzi_dev
Last login: Fri Apr 29 23:07:11 2016 from ***.***.***.***

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2014.09-release-notes/
90 package(s) needed for security, out of 262 available
Run "sudo yum update" to apply all updates.
Amazon Linux version 2016.03 is available.
------------------------------------------------------------------------------------
  ds_agent isn't installed

Instance-id: i-********
public-ip: 54.***.***.***
Tags-Key: develop
------------------------------------------------------------------------------------
[ec2-user@mitzi_develop ~]$
```

以上になります。
MarshalJSONをオーバーライドしてオリジナルJSONへエンコーディング

## はじめに
Go言語でカスタマイズされたJSONの生成方法を実例を交えて説明します
RestFulAPIを実装する等の場合に使います

## やる内容
```go
type MyTime struct {
	Time time.Time `json:"time"`
}
```

上記の`time.Time`型を持つ構造体`MyTime`から

```json
{"time":"2016-04-30 01:30:54"
```
というような形式のJSONへとエンコードすることが目的です。

## そのまま構造体をJSONへエンコードすると

```go:plane.go
package main

import (
	"fmt"
	"time"
	"encoding/json"
)

type MyTime struct {
	Time time.Time `json:"time"`
}

func main() {
	// MyTime初期化
	dt, _ := time.Parse("2006/01/02 15:04:05", "2016/04/01 05:21:33")
	mt := &MyTime{Time:dt}
	
	// JSON変換
	m_bytes, _ := json.Marshal(mt)
	
	// 出力
	fmt.Println(string(m_bytes))
}
```

```json:出力
{"time":"2016-04-01T05:21:33Z"}
```
このTとZが今回は不要です。

ちなみに、timeパッケージの公式を見ると

>```go:time#MarshalJSON
func (t Time) MarshalJSON() ([]byte, error)
```
> MarshalJSON implements the json.Marshaler interface. The time is a quoted string in RFC 3339 format, with sub-second precision added if present.

とあり、TとかZは、RFC3339という表記の規格によるもので、time.Time`型はデフォルトではこの規格ということです。

このままでは希望通りの形式にならないので、`MarshalJSON`をオーバーライドしてJSONをカスタマイズします。

## MashalJSONをオーバーライドする

```go:overrideMarshalJSON.go
package main

import (
	"fmt"
	"time"
	"encoding/json"
)

type MyTime struct {
	Time time.Time `json:"time"`
}

// @Override
func (m *MyTime) MarshalJSON() ([]byte, error) {
	return []byte(fmt.Sprintf("{\"time\":\"%s\"}", m.Time.Format("2006-01-02 15:04:05"))), nil
}


func main() {
	// MyTime初期化
	dt, _ := time.Parse("2006/01/02 15:04:05", "2016/04/01 05:21:33")
	mt := &MyTime{Time:dt}
	
	// JSON変換
	m_bytes, _ := json.Marshal(mt)
	
	// 出力
	fmt.Println(string(m_bytes))
}
```

```json:出力
{"time":"2016-04-01 05:21:33"}
```

`time.Time`で定義されていた`MarshalJSON`メソッドがオーバーライドされて希望通りになりました！
xfceにアプリケーションメニューを追加する

$HOME/.local/share/applications

参考URL
https://docs.oracle.com/cd/E19957-01/817-6000/6mldto81l/index.html

<div class="highlight"><pre>
[Desktop Entry]
Type=Application                          # 上述のタイプを指定します
Version=1.0                               # ファイルが準拠しているデスクトップエントリ仕様のバージョン
Name=displayAppName                       # アプリケーションの名前
Comment=displayChip                       # コメントはツールチップとして使われます
Path=/opt/app                             # 実行ファイルが存在するフォルダのパス
Exec=executable                           # アプリケーションの実行可能ファイル
Icon=icon.xml                             # エントリを表示するときに使われるアイコンの名前
Terminal=false                            # アプリケーションをターミナルで実行する必要があるかどうかを記述
Categories=Education;Languages;Java;      # エントリを表示するカテゴリを記述
</pre></div>


categoriesの一覧
<div class="highlight"><pre>

Categories=X-XFCE;X-Xfce-Toplevel;Utility;

X-Xfce-Toplevel
Settings
Accessibility
Core
Legacy
Utility
Development
Education
Game
Graphics
Audio
Video
AudioVideo
Network
Office
System
</pre></div>


例
FireFoxをインストールしたときは、下記のとおり指定すればインターネットの中に表示されるようになる
Categories=Network;
Browserify で含まれてるファイルのサイズを確認する


出力ファイルのサイズがデカすぎる。でもどのモジュールがデカいのかよくわからない。そういう時の確認方法です。

`browserify` の `--list` オプションで含まれているファイル名のリストを出力できるので、それを使います。

```sh
$ ./node_modules/.bin/browserify -t babelify --list src/index.js > deps.txt
```

もっとオシャレなプラグインとかあるかもしれませんが、特に何もインストールせずに Mac のターミナルで見てみます。

## 大きなファイル トップ 10

ファイル名からサイズを取得するのには `stat` を使います。`%z` は byte 単位のファイルサイズ、`%N` はファイル名です。

```sh
$ cat deps.txt | xargs stat -f "%z %N" | sort -nr | head
142469 /Users/shuhei/work/js/babel-angular2-app/node_modules/angular2/src/core/linker/element.js
129640 /Users/shuhei/work/js/babel-angular2-app/node_modules/angular2/src/core/di/injector.js
128361 /Users/shuhei/work/js/babel-angular2-app/node_modules/angular2/src/compiler/template_parser.js
97656 /Users/shuhei/work/js/babel-angular2-app/node_modules/angular2/src/core/change_detection/parser/parser.js
97584 /Users/shuhei/work/js/babel-angular2-app/node_modules/angular2/src/compiler/view_compiler.js
89995 /Users/shuhei/work/js/babel-angular2-app/node_modules/angular2/src/core/change_detection/differs/default_iterable_differ.js
84577 /Users/shuhei/work/js/babel-angular2-app/node_modules/angular2/src/core/metadata/directives.js
82614 /Users/shuhei/work/js/babel-angular2-app/node_modules/angular2/src/core/metadata.js
81478 /Users/shuhei/work/js/babel-angular2-app/node_modules/angular2/src/compiler/html_lexer.js
78188 /Users/shuhei/work/js/babel-angular2-app/node_modules/angular2/src/core/change_detection/proto_change_detector.js
```

## 合計サイズ

ひとまず全部の合計。合計の仕方は [http://stackoverflow.com/questions/450799/shell-command-to-sum-integers-one-per-line](http://stackoverflow.com/questions/450799/shell-command-to-sum-integers-one-per-line) から。

```sh
$ cat deps.txt | xargs stat -f "%z" | awk '{x+=$0}END{print x}'
4621015
```

特定のディレクトリに含まれる/含まれないファイルの合計。`grep` または `grep -v` を使います。

```
$ cat deps.txt | grep '/angular2/' | xargs stat -f "%z" | awk '{x+=$0}END{print x}'
4584326
$ cat deps.txt | grep -v '/angular2/' | xargs stat -f "%z" | awk '{x+=$0}END{print x}'
36689
```
Ansibleでsudoパスワード対話入力を止める方法とansible.cfgの上書き方法

Ansible実行自体を自動化したい、でもsudoパスワードを対話入力したくない。
そんなときは、`ansible_become_pass`変数にパスワードを設定する必要があります。

ただし、`ansible.cfg`で`become_ask_pass`が`True`になっていると、パスワードを対話入力する必要があります。
この変数は残念ながら実行オプション`--extra-vars`やその他ansible内で上書きしても効果がありません。
コマンド中に実行される`__init__.py`の早い段階でこの変数が使われるためです。

パスワードを聞かれないようにするため、環境ごとに`ansible.cfg`を上書きしたり、
別の`ansible.cfg`を読み込ませる方法もありますが、
環境変数`ANSIBLE_BECOME_ASK_PASS`を使って上書きする方法が簡単です。

`ansible.cfg`の内容はほとんどが環境変数で上書きすることができます。
上書きできる変数の種類は今のところドキュメントがなく、
ソースコード(`constants.py`)に書いてあるだけなので、必要な変数を探しましょう。
URLは以下です。
https://github.com/ansible/ansible/blob/devel/lib/ansible/constants.py


参考URL
[ansible.cfgの公式ドキュメント](https://docs.ansible.com/ansible/intro_configuration.html)