OmniAICreator/Qiita-1.07M huggingface dataset:
生誕祭。

皆さん、こんばんは！
code for KORIYAMAです。
聖夜にもかかわらず、集まって勉強会をしているなんて信じられますか？

![10877449_718933354891811_182519878_n.jpg](https://qiita-image-store.s3.amazonaws.com/0/61783/6de25b5d-6232-1ddd-6647-9f046a17c855.jpeg)

今日は私たちが作成した「まちあるきマッピングアプリ」「街灯マッピングアプリ」の改善提案をしています。

![10872109_718933384891808_1628809584_n.jpg](https://qiita-image-store.s3.amazonaws.com/0/61783/01166a92-1776-c34b-9374-78d73280bb0c.jpeg)

勉強も大真面目にしていますが、

実は…

今日はそれだけじゃないんです！
裏企画として、我らが代表の大久保の生誕祭を兼ねています☆
もちろん、スタッフからサプライズを用意しておりますよ～！
喜んでくれるかな？(*´∇｀*)

![10863527_718955034889643_394799771_n.jpg](https://qiita-image-store.s3.amazonaws.com/0/61783/74a8b202-de91-9f6b-3dc7-852aea7abbba.jpeg)

ジャーン！！

![10833743_718955051556308_251926738_n.jpg](https://qiita-image-store.s3.amazonaws.com/0/61783/b198a356-f972-fe5f-6fd3-c8698d8010f5.jpeg)


ハニカミながらも喜んでくれましたー！
別会場でクリスマスパーティをしていたみなさんにもお祝いして頂き、サプライズ大成功！


このあとも意見交換をしながら、美味しくケーキを頂きました♪


![new_写真-1.jpg](https://qiita-image-store.s3.amazonaws.com/0/61783/908aa5a4-7e9c-fd70-5931-b8d34fc3ad6b.jpeg)



code for KORIYAMA は来年も頑張っていきます！

みなさん、メリー・クリスマス☆
DockerでRuby-2.2.0の実行環境を作る。

dockerの動作する環境で、
以下のテキストを `Dockerfile` という名前のファイルに貼り付けて
 `$ docker build -t ruby:2.2.0 .` を実行する

Dockerfile:

```
FROM ruby
RUN apt-get update
RUN apt-get install -y bison wget
RUN wget http://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.0-preview2.tar.gz
RUN tar zxvf ruby-2.2.0-preview2.tar.gz
WORKDIR /ruby-2.2.0-preview2
RUN autoconf
RUN ./configure
RUN make
RUN make install
```

遊ぶときは、
`$ docker run --rm -ti ruby:2.2.0 /bin/bash`
で、仮想環境に入れるので、`ruby`コマンドなどを叩いて遊ぼう。
Elixir エコシステムへ貢献するための3つのヒント

先日 Phoenix Framework が [Hacker News で取り上げられて](https://news.ycombinator.com/item?id=8671618)、GitHub でのスター数も 1750(2014/12/25)と盛り上がりを見せつつある Elixir 界隈。乗るしかない、このビッグウェーブに！と思いつつも、後一歩が踏み出せない。。。そんなあなたに Elixir なプロジェクトへ貢献(pull request)するヒントをいくつか紹介してみます。

## 前提

- Elixir インストール済み
- pull request の方法は知っている
- pull request したいプロジェクトは決まっている

## 貢献方法

一般的な pull request と大体一緒です。git リポジトリを fork して、branch 作って、すごい機能を追加して、テストが通ったら pull request です。

ただし、プロジェクトによっては contributing guide などがあるので、まず README は見ましょう。
例えば Phoenix Framework では [CONTRIBUTING.md](https://github.com/phoenixframework/phoenix/blob/master/CONTRIBUTING.md) が用意されています。大きなプロジェクトはスムーズに開発するためのルールとして決めているので、従うのはマナーかなと思います。

その他の小さなプロジェクトであればそういったルールはないと思います。大体以下の流れで対応していただければいいかなと思います。

```
$ git clone awesome_project.git
$ cd awesome_project
$ git checkout -b add_awesome_feature
$ mix deps.get
$ mix test
# add some awesome feature
$ mix test
$ git push origin add_awesome_feature
```

`mix` を使うところが Elixir とその他の言語での違いでしょうか。そう考えるとそこまで敷居の高いものではないように思えてきませんか。


## 貢献するための3つのヒント

とはいえすごい機能なんて思いつかないし、何から貢献できるのかも分からない。確かにおっしゃる通りです。余程の人でない限り、中々すぐに貢献できなそうですよね。私も少し前までそう思っていたのですが、ここ1ヶ月ほど [pull request をする用事](http://24pullrequests.com/)ができ、意外と自分でもできることがあると気づいたので紹介します。

### 1. fix typo

いきなり typo かよと思ったかもしれないですが、始めの一歩としてはいいんじゃないかなと思います。ただあまり小刻みにすると忙しい人に取っては嬉しくないかもしれませんね。そんなときはまとめるなどすればいいかなと思います。

typo さえ見つければ Elixir の contributor にもなれる！ちょろいです(嘘です、すみません。プログラマとして恥にならないようにいつかコードの方でも貢献したい。。)。
https://github.com/elixir-lang/elixir/pull/2854

### 2. テストカバレッジ改善

test は結構狙い目です。Elixir は最初からテストツールの ExUnit がついているので、テストがついているプロジェクトが大半だとは思います。それでも全部が全部テストを書いているわけではないです。さらに、カバレッジの観点で見てみると、そこまで高くないモジュールも中にはあるでしょう。そこを狙います。
試しに fork したプロジェクトに excoveralls を入れて、カバレッジを出力してみると一目瞭然です。
カバレッジの低い部分を見つけて、それをカバーするテストを書く。これだけでも立派な貢献かなと思います。

直近の私の具体例でいうと phoenix に以下のような pull request を送りました。これは local で excoveralls を入れて試してみたものです。test を書いて、excoveralls でチェックするだけなので分かりやすいです。
https://github.com/phoenixframework/phoenix/pull/565

あまり良い観点ではないかもしれないですが、テストコードなので仮に失敗してもそこまで致命的なことにならないという安心感というメリットもあるかもしれないですね。

### 3. issue 一覧をみる

issue なんてみても難しいものしかないのでは？と思うかもしれないですが、意外と簡単にできそうなことが issue に転がっていることもあります。例えばたまたまライブラリつくっている人が忙しくて対応できていないとか。後は長らく放置されていて、なかなか手を付けられていないとか。そういうものに対応できると、作っている人も結構喜んでくれて、こちらとしても達成感があってよいです。

例えば https://github.com/parroty/excoveralls/pull/12 は、長く放置されていたものを対応した pull request です。ちょっとリプライコメントが長い、それだけでも嬉しく思えてきます。


## 最後に

ここひと月くらいでいくつかのプロジェクトへ pull request を送ってみたので、その経験を共有してみました。私のレベルでも貢献できることもあり、それはそれで面白いのですが、もっと技術のある人が Elixir 周りに contribute するようになると益々面白くなってよいだろうなぁというところで書いてみました。

それと Elixir のプロジェクトは親切な人が多くて、そんなところもよいところだなぁと感じてます。

今年の Elixir Advent Calendar はこれでおしまいです。皆様ありがとうございました！

Enjoy!

## Resources

- [excoveralls で Elixir プロジェクトのカバレッジレポートを取る](http://qiita.com/ma2ge/items/8bca27709380f8320d9e) 

## 追記

keithseahus さんの記事では具体的な貢献プロセスが記載されており、次のステップを踏みたい方は参考にされると良いかと思います。

- [オープンソースとしてのElixirエコシステムの歩き方](http://qiita.com/keithseahus/items/5f878c827b08bb52480b)
boot2docker ipの出力からメッセージ部分を取り除く


boot2docker ipの出力に余計なメッセージが出る

```
$ boot2docker ip

The VM's Host only interface IP address is: 192.168.59.103
```

以下のようにするとIP部分だけ取れる.

```
echo $(boot2docker ip 2>/dev/null)
```

けど1.3.3(boot2docker cliのバージョン)以降は余分なメッセージは出なくなるらしい。

https://github.com/boot2docker/boot2docker-cli/releases/tag/v1.3.3
baserJS利用時の baser.min.js.map について


Webサイトと詳しいAPIリファレンスはこちら [baserJS Webサイト](http://baserproject.github.io/baserjs/)

## baser.min.js.map とは

baser.js と baser.min.js を関連付けるソースマップです。

ブラウザの開発用コンソールなどからソースを追うときに ミニファイされた baser.min.js を読み込んでいても、ブラウザが元の baser.js のソースとして表示してくれます。ブレイクポイントなどの設定も Chrome などならすることができます。

## 設置場所

baser.min.js と同階層のフォルダに baser.min.js.map と baser.js を置く必要があります。

また、フォルダに baser.min.js しかない場合にコンソールを開くと、baser.min.js.map を読みに行くので 404エラー を吐いてしまいます。 リファレンスエラーが気になる場合は baser.min.js.map と baser.js を同階層に設置するか、 baser.min.js の中の最後の行に記述されている

```js
//# sourceMappingURL=baser.min.js.map
```

を削除すれば baser.min.js.map を読みに行かなくなります。
Force.com開発者として気を付けなければいけないこと

Salesforce1 がまだしっくりこないので Force.com としてます。

さて、Salesforceは SaaS PaaS 両方の特性を備えており
その両方が非常に優秀な素晴らしいServiceである事は周知の事実でしょう。

今回はその内の1つ、PaaSとしてSalesforceを利用する場合
つまりForce.com開発者の視点に立って
Salesforceの導入時に気を付けなければいけないことを幾つか考えてみます。

Salesforceの導入に関わる開発者の方は、大半がSIerだと思いますので
基本的にその観点での話となります。
( 本当はWave辺りのネタを使いたかったのですが何か出来るほどの情報が… )


## 1. Force.comの特性を理解する
基本中の基本ですね、自分が使うプラットフォームの理解は必須です。

しかし、さきほどFroce.comは優秀だと言ったばかりですが
物事には長所もあれば短所もあります。

特にForce.comの短所は厄介なものが多く、
Force.com に初めて触れるエンジニアは
大体この辺りの改善を求めることが多いと思います。

* マルチテナントなのでリソースの制約が必須( ガバナ制限 )
* ソースコードのバージョン管理が出来ない、対応予定も未定
* Javaで言うところのパッケージの概念も無し、1つのディレクトリに全クラス格納
* 項目自動更新とApexTriggerが絡むとカオス
* LocalのPCに実行環境を構築できないのでテストコード実行が遅くてイライラ
* IDEも微妙でリファクタリングも大変

とりあえず簡単に出てきた物を列挙しましたが、要するに
**一般的な感覚で考えると Force.com での開発は非常に効率が悪く面倒くさい**
ってことです。( いや、便利な部分もありますよ )

この辺りは実際に開発された方なら痛いほど良くご理解されているかと。
Force.comを利用する場合は、ここを理解した上で開発に臨む必要があります。

創意工夫で何とかなるものもありますが
ならないものもありますので、将来のバージョンアップに期待したいところです。


## 2. 新機能のキャッチアップを怠らない
Salesforceの特長の1つに **年3回のバージョンアップ** があります。
詳細は省きますが、このバージョンアップはかなりのボリュームで
相当数の機能追加などが実施されています。

Force.comの開発者としては、これを全て抑えておきたいところですが
正直な話、新機能を全て理解してキャッチアップし続けるのは相当大変です。

ですが、ここに全く触れないのであればForce.comを
活かせるはずがありませんので、全ての内容を完全に理解するのではなく
いくつか関係ありそうな部分だけは最低限抑えておいて
頭の中にIndexを作っておきます。

そうすれば、必要な時に頭の中のIndexを見て、
詳細はそのタイミングで 思い出す or 調べる で大丈夫だからです。

新機能が追加される事で、お客様のビジネス要件を満たせるようになった…
という例はちょこちょこありますので、ここは重要です。


## 3. 新機能を採用するのは手段であって目的ではない
たまにいます。

お客様の要件を満たすために必要ではないのに
**開発者が使ってみたいからと言う理由で**新機能に手を出すパターンです。

新しい機能を試してみたいだけならデペロッパー組織でも作って
そこでやりましょう、実際のプロジェクトで採用するなら
それだけの必要性があるかどうかを充分検討する必要があります。

バージョンアップの頻度も高く、魅力的な新機能もどんどん追加されるので
色々とやってみたいと言う気持ちはわからなくもないですが、それはそれ、です。


## 4. 標準機能と Apex、Visualforce のバランスを考えて設計する
3のパターンに少し近いものではありますが

標準機能で実現出来る事をApexやVisualforceで実装する、
ApexTriggerを採用した方がいいのに標準機能で頑張って実装する。

などです。

また、**個別最適化を優先して全体最適化を疎かにする**ことで
ApexTriggerと項目自動更新の絡み合うオバケが出来上がったり、
設計思想の統一が出来ていない、動く機能を寄せ集めただけみたいな
システムが出来上がったり…と言うことも発生します。

全体最適化を全く考慮していないシステムが及ぼす弊害は
言うまでは無いと思いますが、保守性の低下を確実に招きます。

また、それぞれの依存度が高くなってしまう事により
ユーザ側でのカスタマイズ出来る範囲にも影響が出る可能性があります。


## 最後に
当たり前の事ばかり書いていますが、
この当たり前の事が意外と出来ていないのも、また事実だと思います。

しかし、これ程まで制約が色々あるのにForce.comのデベロッパーは
なぜこのプラットフォームを使い続けるのかな…と、ふと思いました。

制約が多ければ多いほど創意工夫が必要で、知恵を振り絞って解決策を出す必要があります。
そのプロセスが楽しい人もいるのかな…とか、単純に仕事だからやってる人もいれば、
三度の飯よりSalesforceが好きな人もどこかにいるんでしょう( いるのかな？ )

確実に言えることは、まだまだ進化していくこのForce.comと言うプラットフォームが
そのプラットフォーム自身も、そしてそれを取り巻くコミュニティも、
来年以降ますます盛り上がって行くだろう…と言うことです。

***

本来であれば技術ネタをしっかりと書くべきですが、
今回はこんな内容でお茶を濁しつつ
[Salesforce1 Advent Calendar 2014](http://qiita.com/advent-calendar/2014/salesforce1) の最終日を締め括らせていただきます。

***
baserJSの内部モジュール一覧


コーポレートサイトにちょうどいいJavaScriptライブラリ **baserJS** の解説記事です。

Webサイトと詳しいAPIリファレンスはこちら [baserJS Webサイト](http://baserproject.github.io/baserjs/)

## 内部モジュール

こちらの [baserJSの機能一覧](http://qiita.com/YusukeHirao/items/0c167cab002335148faf) にもあるように基本的には jQueryのインスタンスから呼び出すかたちで利用しますが、実際には内部の コンストラクタ からbaserの各モジュールのインスタンスを生成してDOMを操作しています。

## モジュール一覧

|モジュール|要素・機能|
|---|---|
baser.utility.String|文字列操作
baser.utility.Mathematics|算術
baser.ui.AnimationFrames|アニメーションフレームの管理
baser.ui.Box|ボックス要素の操作
baser.ui.Browser|ブラウザの管理・操作
baser.ui.Dimension|要素の幅・高さを管理 (実装予定)
baser.ui.EventDispacher|イベント発火を管理
baser.ui.Scroll|ブラウザのスクロール位置の管理
baser.ui.Timer|時間の管理
baser.ui.Validation|フォームのバリデーションを管理 (実装予定)
baser.ui.element.CheckableElement|チェック可能要素
baser.ui.element.Checkbox|チェックボックス要素
baser.ui.element.Element|要素
baser.ui.element.Form|フォーム要素の管理
baser.ui.element.FormElement|フォーム内要素
baser.ui.element.Map|マップ要素
baser.ui.element.Radio|ラジオボタン要素
baser.ui.element.RadioGroup|ラジオボタンの管理
baser.ui.element.Select|セレクトボックス要素
baser.ui.element.Youtube|YouTube要素

* * *

もっと上手くまとめたいものです。v1.0.0までは内部モジュールについては破壊的にAPIをガンガン変更すると思います。
class_exists でのオートロード

`class_exists` で定義済みクラスを探すときはマニュアルの通り、大文字小文字は区別されませんが（そもそも php の言語仕様としてクラス名の大文字小文字は区別しないはず）、定義されていないクラスを探そうとして、オートロードが走ると、ファイルシステムによってはうまくロードされないことがあります。

例えば下記のような構造で

```
hoge/
├── SampleClass.php
└── main.php
```

```php:hoge/SampleClass.php
<?php

Class SampleClass{}
```

```php:hoge/main.php
<?php

// 単純なオートロードを登録
spl_autoload_register(function ($classname)
{
    $filename = __DIR__ . DIRECTORY_SEPARATOR . $classname . '.php';
    if (file_exists($filename))
    {
        require_once $filename;
    }
});

// 小文字クラス名で class_exists
var_dump(class_exists('sampleclass'));
// 正式なクラス名で class_exists
var_dump(class_exists('SampleClass'));
// もう1回小文字クラス名で class_exists
var_dump(class_exists('sampleclass'));
```

上記を Windows 環境で実行すると下記のようになります。

```
bool(true)
bool(true)
bool(true)
```

Linux 環境で実行すると下記のようになります。

```
bool(false)
bool(true)
bool(true)
```

これは Windows(のファイルシステム) が大文字小文字のファイル名を同一視するからです。  
Windows 環境では最初の `class_exists` で問題なくオートロードされ、以後 `SampleClass` は定義済みクラスとなるので下の2つも `true` になります。  
Linux 環境では小文字のファイル名が存在しないため、1つ目ではロードされず、2つ目の正式クラス名でロードされ、その時点で定義済みとなるため、3つ目は `true` になります。

オートローダの実装にもよりますが、「ファイルが存在するなら読み込む」という動作のオートローダだとエラーすら出てくれません。
たしか composer はそんな感じの動作だったかと。

そもそも普通に考えて `class_exists` に起因した現象などではなく、単純にオートロードに起因しているだけなんですが、
「`class_exists` はオートロードしてくれるから安心だぜぇ」って思考だとハマるかもしれないです。
baserJSの開発環境


Webサイトと詳しいAPIリファレンスはこちら [baserJS Webサイト](http://baserproject.github.io/baserjs/)

## リポジトリ

### [Github](https://github.com/baserproject/baserjs)

もちろんGithubを利用しています。

## タスクランナー

### [Grunt](http://gruntjs.com/)

基本的な処理はすべてGruntに任せています。

[Gulp](http://gulpjs.com/)に乗り換えてもいいかなぁとも思っていますが、一度設定ファイルを作っているので別段不便に思っていないので、たぶんしばらくこのままです。

## 言語

### [TypeScript](http://www.typescriptlang.org/)

言わずと知れたAltJSです。メンテナンス性・設計、クラスの作りやすさから、これを選択しました。型安全であることは副次的効果だと思ってコーディングしています。

### コンパイラ

[grunt-typescript](https://www.npmjs.com/package/grunt-typescript)

### d.ts管理

[tsd](http://definitelytyped.org/tsd/) -> [dtsm](https://www.npmjs.com/package/dtsm)

v0.1.0 では tsd を利用していますが v0.2.0 からは dtsm に乗り換える予定です（開発ブランチでは移行済み）。

## テスト

### フレームワーク

[QUnit](http://qunitjs.com/)

まだまだテスト全然かけてませんが、テストがきちんと通るように開発していきたいです。

### CI

[Travis CI]()

Gruntのビルド時にもQUnitを通しますが、やっぱり証拠としてバッヂ( [![Build Status](https://travis-ci.org/baserproject/baserjs.svg?branch=rc)](https://travis-ci.org/baserproject/baserjs) ) は欲しいので、Githubと連携させています。

## その他

### [bower](http://bower.io/)

bowerのモジュールとしてbaserJS自体を登録していますし、依存のある[jQuery](http://jquery.com/)をテストに利用する際にも使用しています。
会社でGitおじさんになった方法


Git AdventCalendar2014最終日に相応しいか怪しいのですが、今後のgitの利用者増加と、さらなる繁栄を信じて投稿させていただきます。コラムみたいになってしまいましたが、感謝の気持ちが言いたかったので言わせて下さい。NGだったらすみません。

## はじまり
2,3年前のある日、入社したての頃の話です。

プロジェクトでgitを使っていて「こうした方がいいのでは？ああした方がいいのでは？」などと発言しまくっていたら、「デザイナーもやっぱりgit使えたほうが効率いいよね」みたいな話になりまして、「git勉強会」なるものを有志で企画することになりました。

## レベル別勉強会の開催
社内全体で募集を開始して、勉強会を企画することになり、以下の3つのレベルにわけて参加者を募って数回に分けて開催しました。（1枠1~2時間程度を数回行いました。）

- 完全初心者向け（初級）
- SVNなどは使っていた、デザイナー向け（中級）
- すでに使っているエンジニア向け（上級）

以下にざっくりとした内容を記載します。

### 完全初心者向け（初級）
- バージョン管理システムの説明と、なぜ使うのかの説明
- GitとGithubの違い、何ができるかの簡単な説明
- Githubは編集などでも使われているよ！といったイメージ共有
- gitの使い方の概念の説明（[郵便局メソッドの誕生](http://qiita.com/yunico-jp/items/87bdd13971e82833f6bb)）
- 実際にGithubやGitを参加者をチームに見立てて触ってみる

### SVNなどは使っていた、なんとか使えているデザイナー向け（中級）
- SVNとGitの違いの説明
- Gitで混乱しやすい点のわかりやすい説明
- 実際にチームでコンフリクトやPUSHを体験してみる
- 困ったときの対処法などのTips紹介

### すでに使っているエンジニア向け（上級）
- 改めてgitの特徴やメリットを振り返る
- 基本的な考え方の整理、gitで何が悪で何が正義なのか。など
- 運用方法例や、困ったときの対処法などの紹介
- 便利コマンドのTips紹介

## フォローアップ
勉強会をひと通り終えた後は、実際に業務での作業へ。
当時はChatworkを使用していたので、Git部屋なるものを作成して気軽に質問できる雰囲気を提供、「困ったときは俺に直接でもいいですし、チャットで聞いて下さい」みたいに周知しました。

結果、 `こんなエラーがでてpushできないんだけどどうして？` とか `こんな時どうやってマージする？` などのレベル感無視した `git` の情報が活発に流れるチャット部屋が生まれることで、よくわからない人でもなんとなく便利なgit運用方法などを勝手に理解していってくれました。そこそこ大変だったとは思いますが、結果として `デザイナー全員がgitコマンドで基本的な作業は可能になる` ようになりました。

## 気づけばGitおじさんに
「こじてぃならこんなときどうする？」とか「エラーがでてわからない・・・」と相談をうけたときは、自分がイメージできた最適なルートを提案したり案内したりしました。

なるべく、わかりやすく説明したり簡潔に提案したりすることにはかなり注意を払いました。すると、「わかりやすい」とか「なるほどね」などを言ってもらえるのが嬉しくて、詳しくなかった低レベルな部分の勉強を追加でひっそり行っていたりもしましたｗ

そんなことを続けていると、「Gitのこんなエントリがあったよ」とか「このコマンド便利そう！」みたいなGitやGithubの情報をおしえてもらえるようになりました。そういうときはすぐに試してみて評価してフィードバックを行いました。

上記みたいなことを、繰り返していると自分も周りのレベルも勝手に向上していました。そして気づけば社内的には「Gitおじさん」と呼ばれるまでになりました。

おかげさまで、社外の方に勉強会を開催したり説明会を行ったりと多くの機会もいただけました。本当やってよかったと思っています。ありがとうございました。

## おわりに
最初の勉強会などは、正直振り返ってみると結構大変でした。

- レベル別の資料作成
- 講義内容をレベル別で考える
- メンバーのレベルを揃えて最適化しつつ、都度別々に開催する
- 達成感やインセンティブをいかに与えるか。

などなど。

しかし、勉強会を開催したことで以下のメリットが生まれました。

- Gitへの感心や興味が全社的に向上した
- 良くも悪くもデザイナーさんへの強制力が発生した [^1]
- 一緒にスタートする同僚がいることへの安心感
- 「エンジニアではなく、技術を尊敬するマインド」の提供の助け [^2]
- 各人のレベル感の確認が容易に行えて後のフォローアップに役立てた

キッカケとある程度の強制力や気軽さみたいなものは結構重要だと思います。
まだまだ「Gitやってみたい」という人は多いみたいなので、ぜひ挑戦してみてください。挑戦するときは「近くになんでも気軽に相談出来る人がいる」というのは結構重要なのでオススメしておきます。

## 注釈
[^1]: とはいえ、なるべく楽しんでもらう努力はもちろんしてました。
[^2]: 「それ、git pushしちゃうよ〜」みたいな会話がエンジニア以外でも成り立つようになりましたｗ
AppleScriptでOSXファイヤウォールの受信接続許可ボタンを自動的に押す


OSX Mavericksになってからなのか、[Charles.app](http://www.charlesproxy.com/)を立ち上げるたびに次のようなファイヤウォールの確認ダイアログが出るようになった。
![A2924C56-FF0A-4AD4-98B1-037A688D465D.png](https://qiita-image-store.s3.amazonaws.com/0/10682/ce2f03aa-64ce-19de-3038-63e5bee5df6d.png "A2924C56-FF0A-4AD4-98B1-037A688D465D.png")

AppleScript等でCharlesでのログ取りなど自動化をするにあたって、許可ボタンを自動的に押す必要があったので調べた。次のようなAppleScriptを書くと、ダイアログ内のテキストに「Charles.app」があったときだけ、許可ボタンを押すことが出来る。

具体的には、このダイアログはUserNotificationCenterというプロセスが表示しているようなので、そのプロセスに対してAppleScriptを実行している。

```AppleScript
tell application "System Events"
  -- ダイアログはUserNotificationCenterプロセスが表示しているので、まずはUserNotificationCenterプロセスの有無を確認
  if "UserNotificationCenter" is in (get name of processes whose background only is true) then
    tell process "UserNotificationCenter"
      tell window 1
        -- first static textは『アプリケーション"Charles.app"へのネットワーク……』という文字列を保持している
        if value of first static text contains "Charles.app" then
          click button "許可"
        end if
      end tell
    end tell
  end if
end tell
```

実装に当たって、以下のサイトを参考にした。

* [Apple Script to dismiss UPS alert](https://discussions.apple.com/thread/3166227)
* [AppleScriptの構造を上手に調べる](http://allabout.co.jp/gm/gc/80938/3/)
materialized viewのモデル化は・・・

できるんですけどやめたほうがいいですね。（結論

マテビューをまたビューでラップしてやったほうが楽。

どうしても直接使いたいなら
bakeでそもそも一覧に出てこないけどここをこういじると


Cake\Model\Datasource\Database\Postgres.php L169~

```php
$schema = $this->config['schema'];
$sql = "SELECT table_name as name FROM INFORMATION_SCHEMA.table_schema WHERE table_schema = ?";
// 追加コード
$sql .= " UNION SELECT matviewname as name FROM pg_matviews WHERE schemaname = ?";
		$result = $this->_execute($sql, array($schema));
```


マテビューの検索って結構マイナーなんで実はそっちのメモだったり。
UE4 変なマテリアル入門 5（テクスチャサンプリング*N）

# Index
[第1回（準備と簡単な例）](http://qiita.com/nkdtr/items/ca418529a1992ed5ab08)
[第2回（動くマテリアル）](http://qiita.com/nkdtr/items/81dca14e37a34fe32cb0)
[第3回（形を作る）](http://qiita.com/nkdtr/items/e6cf18160a5f3ff2fd18)
[第4回（形を動かす）](http://qiita.com/nkdtr/items/309274646d291ef676fd)
[(イマココ)第5回（テクスチャサンプリング*N）](http://qiita.com/nkdtr/items/6e09446659512c09e4bc)

# 概要
テクスチャを参照する際、本来のピクセルのみならず近隣の（時には遠方の）ピクセルをも参照することによって様々な効果が得られます。
このシリーズとしては珍しく、そのまま使えるものが多いかもしれません。
そのかわり文字列ばっかりです。

# Custom ノードを使用する（重要）
理論的にはTextureSampleを複数使用することにより実現できますが、
サンプル数が増えると大変です
（ループが表現できればよいのですが、生憎無理のようです(Ver4.6現在)）。
従ってCustomノードを使用することになります。
Customノード内でテクスチャサンプリングを行うことになりますが、
それには入力として
TextureObjectノード（TextureSampleではありません）の出力を用い、
コード内でTexture2DSample関数にそれを渡します。
引数は(Texture2D, sampler, float2)の順です。
Texture2D は TextureObject ノードから、
sampler は CustomにTextureObjectノードを接続すると自動的に付加されますが目には見えません（ちょっと暗黒じみている・・・）。なお変数名はTextureObjectを受け入れるのに使用した名前の後ろに"Sampler"を付けたものになります。
例えば、
```Texture2DSample(tex, texSampler, texcoord);```
のように表記することになります。
以下が単純にテクスチャをそのまま貼りつける例です。

![texturesample.PNG](https://qiita-image-store.s3.amazonaws.com/0/61553/20e59d1f-556e-eae9-7362-4bda284b922a.png)


# ブラー
日本語ではぼかしと表現される効果です。
一概にぼかしと言っても参照するピクセルの選び方によって様々な効果が得られます。
基本的には、
（ピクセル色）＝（近隣ピクセル色の加重平均）
となるように計算します。
この際細かくサンプリングするほど「段階」が見えない滑らかなぼかしになりますが、
その分負荷が上昇します。

いくつか例を挙げますが、ノードの組み方はほとんど同じになるのでコードだけ載せます。
謎の変数が出てきた場合は入力を追加するものと思って補完して下さい。

* 一定方向にぼかす

UVを一定の間隔でずらしながらサンプリングします。
![blur01.PNG](https://qiita-image-store.s3.amazonaws.com/0/61553/3dfc36f4-e17b-20c3-7189-e4ca5d3c8feb.png)



* 一点を中心にぼかす（ラジアルブラー）

ある点を中心にUVを拡大/縮小しながら合成します。
![radialblur.PNG](https://qiita-image-store.s3.amazonaws.com/0/61553/2dd76e71-623a-05ed-c928-f4bb24e49e3d.png)



* さらにひねる

複素空間で回転要素を乗算するとか。
カカシ先生的なジツっぽい。
![radialblurplusrot.PNG](https://qiita-image-store.s3.amazonaws.com/0/61553/fd86a916-25fe-ec33-dc5c-f2d789f3b61d.png)


# 差分
隣接ピクセルの差分を見ることで、空間方向の「変化量」を抽出できます。

* エンボスっぽいあれ

![sub01.PNG](https://qiita-image-store.s3.amazonaws.com/0/61553/95e0f5bc-3a5a-c10a-8c06-4c5432a8c8c2.png)


* エッジ抽出っぽいあれ

本来は様々な方向にサンプリングした方がきれいに出ます。
お試しください。
![edge.PNG](https://qiita-image-store.s3.amazonaws.com/0/61553/e5bff863-dd36-0f18-01ed-831544a33264.png)



今回はこのあたりでおしまいにしておきます。
pythonでbasic認証付きのhttpプロキシを経由する時のハマりポイント

# pythonでbasic認証付きのhttpプロキシを経由する時のハマりポイント

2.7.x系です。
urllib2でhttpプロキシを経由する際に、basic認証が掛かってる場合。

## ターゲットのサーバに認証が掛かってる場合

```
client => proxy => target
                ↑ここ
```

これはリファレンスとか普通にググると出てくるやつを真似すればおｋ。

```py
#!/usr/bin/env python

import urllib2

proxy = urllib2.ProxyHandler({
  'http': 'http://username:password@proxy:8080'
})
auth = urllib2.HTTPBasicAuthHandler()
opener = urllib2.build_opener(proxy, auth)
urllib2.install_opener(opener)

conn = urllib2.urlopen('http://target/')
print conn.read()
```

これで、`Proxy-Authorization` ヘッダが付与される。


## プロキシサーバにbasic認証が掛かってる場合

```
client => proxy => target
       ↑ここ
```

この場合、`Proxy-Authorization` ヘッダじゃなくて `Authorization` ヘッダを付与しないとならない。
が、いくら調べても試してもHandler使ったやり方が出てこなかったので、
仕方ないので手でヘッダを計算して付与する事でなんとか解決。

```py
#!/usr/bin/env python

import urllib2
import base64

proxy = urllib2.ProxyHandler({
  'http':'http://proxy:8080'
})
opener = urllib2.build_opener(proxy)
base64string = base64.encodestring('%s:%s' % ("username", "password"))
opener.addheaders = [ ("Authorization", "Basic %s" % base64string) ]

conn = opener.open('http://target/')
print conn.read()
```

Handlerを使ったちゃんとした解決方法無いのかな。


## ちなみに

`pip requests`
使うと
`Proxy-Authorization` の挙動だった。

```py
#!/usr/bin/env python

import requests

proxies = {
    "http": "http://username:password@proxy:8080",
}

ret = requests.get("http://target/", proxies=proxies)
print ret
```
「ロングタップからのスワイプ」を表現するカスタムUIGetureRecognizer


こちらも必要に迫られたので作りました。
[こちら](http://qiita.com/okitsutakatomo/items/8db18e268f2a53d8df5c)と合わせてご確認ください。
あと最初ハマったのでこちらも参照ください。
http://qiita.com/okitsutakatomo/items/37e717f2b34a957cca8f



```
//
//  UIHuttobasuGestureRecognizer.swift
//
//  Created by Takatomo Okitsu on 2014/12/25.
//  Copyright (c) 2014年 Takatomo Okitsu. All rights reserved.
//

import UIKit

var kHuttobasuGestureReturnDistance:CGFloat = 20

class UIHuttobasuGestureRecognizer :UIGestureRecognizer {
    
    var timeOutTimer:NSTimer?
    var longTapTimer:NSTimer?
    var startingPoint:CGPoint?
    var longTapped:Bool = false
    
    override func reset() {
        startingPoint = nil
        longTapped = false
    }
    
    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        self.invalidateTimer()
        
        if touches.count > 1 {
            self.state = UIGestureRecognizerState.Failed
        } else {
            let touch:UITouch = touches.anyObject()? as UITouch
            if touch.tapCount > 1 {
                self.state = .Failed
            } else {
                longTapTimer = NSTimer.scheduledTimerWithTimeInterval(0.3, target: self, selector: "handleLongTapped", userInfo: nil, repeats: false)
                timeOutTimer = NSTimer.scheduledTimerWithTimeInterval(0.8, target: self, selector: "handleTimeOut", userInfo: nil, repeats: false)
                return
            }
        }
    }
    
    override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
        let touch:UITouch = touches.anyObject()? as UITouch
        if self.state == .Possible {
            if self.longTapped {
                if startingPoint == nil {
                    startingPoint = touch.locationInView(nil)
                } else {
                    let point = touch.locationInView(nil)
                    let distance = (point - startingPoint!).length
                    if distance > kHuttobasuGestureReturnDistance {
                        self.state = UIGestureRecognizerState.Ended //event fired
                    }
                }
            }
        } else {
            self.state = .Failed
        }
    }
    
    override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
        self.invalidateTimer()
        self.state = .Failed
    }
    
    override func touchesCancelled(touches: NSSet, withEvent event: UIEvent) {
        self.invalidateTimer()
        self.state = .Cancelled
    }
    
    func invalidateTimer() {
        timeOutTimer?.invalidate()
        timeOutTimer = nil
        
        longTapTimer?.invalidate()
        longTapTimer = nil
    }
    
    func handleTimeOut() {
        self.invalidateTimer()
        self.state = .Failed
    }
    
    func handleLongTapped() {
        self.longTapped = true
    }
}


```
「こする」を表現するカスタムUIGestureRecognizer


必要になったので作ってみました。
必ずしも左右にこすらなくても反応してしまうのはご愛嬌で。
あと最初ハマったのでこちらも参照ください。
http://qiita.com/okitsutakatomo/items/37e717f2b34a957cca8f

```
//
//  UINaderuGestureRecognizer.swift
//
//  Created by Takatomo Okitsu on 2014/12/25.
//  Copyright (c) 2014年 Takatomo Okitsu. All rights reserved.
//

import UIKit

var kNaderuGestureReturnCount = 2
var kNaderuGestureReturnDistance:CGFloat = 20

class UINaderuGestureRecognizer :UIGestureRecognizer {
    
    var timeOutTimer:NSTimer?
    var startingPoint:CGPoint?
    var returnCount:Int = 0
    
    override func reset() {
        startingPoint = nil
        returnCount = 0
    }
    
    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        self.invalidateTimer()
        
        if touches.count > 1 {
            self.state = UIGestureRecognizerState.Failed
        } else {
            let touch:UITouch = touches.anyObject()? as UITouch
            if touch.tapCount > 1 {
                self.state = .Failed
            } else {
                return
            }
        }
    }

    override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
        let touch:UITouch = touches.anyObject()? as UITouch
        if self.state == .Possible {
            if startingPoint == nil {
                startingPoint = touch.locationInView(nil)
                timeOutTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "handleTimeOut", userInfo: nil, repeats: false)
            } else {
                let point = touch.locationInView(nil)
                let distance = (point - startingPoint!).length
                if distance > kNaderuGestureReturnDistance {
                    returnCount++
                    if returnCount >= kNaderuGestureReturnCount {
                        self.state = UIGestureRecognizerState.Ended //event fired
                    } else {
                        startingPoint = point
                    }
                }
            }
        } else {
            self.state = .Failed
        }
    }

    override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
        self.invalidateTimer()
        self.state = .Failed
    }

    override func touchesCancelled(touches: NSSet, withEvent event: UIEvent) {
        self.invalidateTimer()
        self.state = .Cancelled
    }
    
    func invalidateTimer() {
        timeOutTimer?.invalidate()
        timeOutTimer = nil;
    }
    
    func handleTimeOut() {
        self.invalidateTimer()
        self.state = .Failed
    }
}

```
【Git】プロジェクト内のTODOとそれを書いた人を抽出するワンライナー

ファイルリストアップ　⇒　git blame ⇒　grep

```bash
find app/ config/ spec/ <などなど> -type f | xargs -n1 git blame -lf | grep TODO > todoList.txt
```

## 出力結果

```
d9ed83164a0107a504a17819d332915ede412a37 path/to/file1.txt (John Smith 2013-09-11 15:40:17 +0900 120) > TODO: 運用開始前に再度確認、更新すること
c3b87c67b3a45fe18bd6161d4d75e470e075c982 path/to/file3.txt (Maria Smith 2014-02-14 10:33:18 +0900 11) > TODO: コードのマッピングをする
```

ディレクトリ除外も指定できるようになりたいな。findがうまく使えなかった。。。
JavaScriptでFinderのファイルをiTerm 2のvimで開く

最近MacVimからターミナルのvimに切り替えました。
Finderからターミナルのvimで開くにはスクリプトが必要なようですが、[YosemiteからJavaScriptで書けるようになった](http://tonbi.jp/AppleScript/JavaScript/)みたいなので書いてみました。

```javascript
var iTerm = Application("iTerm");
var Finder = Application("Finder");

var names = Finder.selection().map(function(item){
  return item.url();
});

iTerm.activate();
var term = iTerm.currentTerminal();
session = term.launch({session: "Dafault"});
session.write({text: "vim " + names.map(function(i){return '"' + i + '"'}).join(" ")});
```

これをAutomatorでアプリケーションにして関連付けると開けるようになります。

![Screen Shot 2014-12-25 at 18.09.30.png](https://qiita-image-store.s3.amazonaws.com/0/17890/b3a62477-c5bf-b4fe-d35e-7239f39cb073.png "Screen Shot 2014-12-25 at 18.09.30.png")

tmuxのウィンドウを追加できるといいかなと思ったんですがうまくいかなかったのでiTermのセッションを追加しています。

## 参考サイト
- [鳶嶋工房 / AppleScript / JavaScript for Automation (JXA)](http://tonbi.jp/AppleScript/JavaScript/)
- [FinderからiTerm2上でVimを立ち上げファイルを開けるAppleScriptを書いた - ここは匣](http://fimbul.hateblo.jp/entry/2013/11/13/162614)
Cloudfront：カスタムエラーページのキャッシュ時間を正確に理解する


#0.カスタムエラーページとは？
Cloudfrontとは？は今回省略します。

カスタムエラーページは、
>オリジンから特定のHTTPステータスコードが返された時に、
Cloudfront側で任意のコンテンツをレスポンスでき、かつHTTPのステータスコードもいじることができる機能
*例）503が返ってきた時にオリジナルのページをレスポンスし、ステータスコードを200（正常）で返す、など*

です。

このカスタムエラーページも例外なくキャッシュ対象になるので、
それなりのキャッシュコントロールの考慮が必要なのですが、
正しい理解をしていないと誤った設定をすることになるので、書き留めておきます。



#1.通常コンテンツのキャッシュ時間をおさらい

通常コンテンツのキャッシュ時間をコントロールするためには、Cloudfront側の[Beghavior]の`minimum TTL`で設定します。[Behavior]毎に設定するので、URLパターン別に設定可能です。

また、オリジンからのレスポンスヘッダーにcache-controlヘッダーが含まれない場合、CLoudfrontは24時間そのコンテンツをキャッシュしてしまうので、基本的にはオリジン側のキャッシュコントロールが必須になります。

詳細はAWSの[ドキュメント](http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/Expiration.html#ExpirationDownloadDist)や[各種資料](http://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-tech-amazon-cloudfront)に解説がありますが、ざっくり以下のような動きになります。




| 　　　　　　         | cache-control無し     | cache-control有り                          |
|:-------------------|:---------------------|:----------------|
| minimum TTL <= 24H | 24時間キャッシュ       | cache-controlと24Hの長い方キャッシュ         |
| minimum TTL >  24H | minimum TTLキャッシュ  | cache-controlとminimum TTLの長い方キャッシュ |
　




#2.カスタムエラーページの構成方法
例えばS3からカスタムエラーページのコンテンツを配信したい場合、以下の流れになります。
※S3にはコンテンツが配置されている前提です

>①：[Origins]にS3を追加する
>②：[Behavior]に対応するパスを追加する
>③：[Error Pages]にカスタムエラーページ設定を行う



①：[Origins]にS3を追加
![](https://s3-ap-northeast-1.amazonaws.com/kaojitario7/qiita-image/20141225/01_created-origin.png)

②：[Behavior]に対応するパスを追加
![](https://s3-ap-northeast-1.amazonaws.com/kaojitario7/qiita-image/20141225/02_created-Behavior.png)

③：[Error Pages]にカスタムエラーページを設定
![](https://s3-ap-northeast-1.amazonaws.com/kaojitario7/qiita-image/20141225/03_Created-Custom-error-response.png)




#3.Error Caching Minimum TTLの挙動
[Error Pages]では、`Error Caching Minimum TTL`という設定があります。
こいつは、通常コンテンツの[Behavior]で設定する`Minimum TTL`とは少し意味合いが異なります。

`Error Caching Minimum TTL`は、
**最初のエラーレスポンスから次回オリジンにアクセスするまでのCool down period的な意味**
になります。


従って、オリジン側からのレスポンスヘッダーにCache-controlヘッダーが含まれていなくても、
`Error Caching Minimum TTL`経過後には再度オリジンにアクセスしにいってくれます。
つまり、エラーページ自体は[Behavior]の設定にならってCloudfrontにキャッシュされるのですが、
ちゃんと`Error Caching Minimum TTL`経過後はオリジンにフェッチし、エラーが解消していれば正常コンテンツを応答することができるのです。
ここが、通常コンテンツとの差になります。

なお、Defaultの`Error Caching Minimum TTL`は300(Seconds)になっていますので、
最初のエラーレスポンスから5分間はキャッシュされるけど、
5分経過後はオリジンにアクセスし、コンテンツの取得を試みる、という挙動になります。

<br>
**■カスタムエラーページがCloudfrontによってキャッシュされている様子**
 （エラー発生中はキャッシュされるが、`Error Caching Minimum TTL`経過後はオリジンにアクセスされるので心配無用）
![](https://s3-ap-northeast-1.amazonaws.com/kaojitario7/qiita-image/20141225/04_caching-behavior.png)


もちろん、この5分の間もキャッシュさせるかしないか、という議論もあると思うので、
キャッシュさせない、ということであればオリジンのcache-control考慮は必要になります。



#4.まとめ
ユーザ側からは動作確認ベースでしか確認できないので、この仕様を知らないと、
>あれ？Error Caching Minimum TTL=0なのにキャッシュしてる！
>オリジンにcache-control設定いれないと！！！

となってしまうので、要注意ですね。
今回はカスタムエラーページをS3から配信する例だったので、簡単にcache-controlヘッダーを埋め込めますが、
複雑な構成になっているカスタムオリジンのWebサーバだったら、結構インパクトでますよね。
やっても実害はないですけど、楽できるところは楽していきましょう！！！
Yosemite MacBook Pro でiCloud Driveを使おうとしたがFinderに表示されずハマった（解決済）

[2015/01/08追記：解決しました]

環境：MacBook Pro Retina-13inch Mid 2014　Yosemite10.10

#iCloud DriveがFinderに表示されない。
今回は前回の記事のように、Finderを消して再度開いてもサイドバーは変わらず。
http://qiita.com/phptaro/items/ae42b27cdccea008b3cd
なぜ？？？
公共図書館のFree Spot Wi-Fiを使っているせいだろうか？
Qiitaのサイトも、「アクセス禁止サイトです」とのメッセージでフィルタにかけられてしまうし。。。

#iCloud.comのダウンロードはファイルのみ！？
しかたがないので、iCloud.comにサインインして、そこから必要ファイルを持ってこようと思う。
ところが、フォルダをダウンロードできないみたい。
ファイル単位でのダウンロードのみ？
必要なファイルがSwiftのプロジェクトだから、ファイルがいくつもあって面倒。
うーん、使いづらいな！！！Finderに表示されたらなんでもないことなのに！

#Free Wi-Fiが悪いのだろうか？
Free Wi-Fiがいけないのかと思い、今度はiPhoneでテザリングしてみる。
ちなみに、iPhoneもFree Spot Wi-Fiで接続した状態。
アクセス禁止だったQiitaにはアクセスできるようになった。
しかし、Finderは変わらず。
iCloud Driveどこにあるの！？

今度は、iPhoneは通常の４G回線に接続し、そこからMacにテザリング。

その結果…

結局ダメでした。
何が原因なんだろう？

#サインアウトしても、、、
上述の記事でiMacに行ったように、環境設定からiCloudを一度サインアウトしてみる。
それからログイン。
再びiCloud Driveにチェックを入れる。
それでもだめだぁ。。。
メモはiMacと同期をとっていて、こっちはバッチリ表示されてるのに。

ネットで調べても、こういうエラーは見つからず。
iPhoneで使いたい人向けの記事はけっこうあるんだけど。

どなたか、解決策やヒントをお持ちでしたら教えていただけないでしょうか？

##余談
と、ここまで書いて、文章をコピペしてQiitaに投稿しようとしたら、できない、、、なぜ？？
え？？Qiitaって貼り付けできないの？
検索画面でもペーストできない。
タブを閉じて、新しく開きなおしても、できない。。。Chromeだから？
Safariで立ち上げたらできました。
その後、Chromeを再起動したら、ちゃんとペーストできました。
不思議です。こういうのも、原因がきっとあるはずなんだけど、まだまだ知識も経験も勘もなくわかりません。

[2015/01/08追記]
##解決方法
先ほど、Finderの環境設定から解決することが出来ました！

メニューバーのFinder　→　環境設定　→　サイドバー　→
サイドバーに表示する項目　→　iCloud Driveにチェック

ずっとiCloudの環境設定ばかり見ていて、Finderをチェックしてませんでした（反省）。。。
Intent の中身を覗きたくていつもやるアレ

## Intent の中身を見たい

Intent を受け取った時、中に何が入っているか気になることがあります。
自分のアプリ内から飛んでくる Intent なら大したことはありませんが、よそから Intent が飛んできた時、中に何が入っているかがとても気になります。

## toString() の罠

で

世の中便利なもので、どんなオブジェクトも`Object#toString()`によって文字列化することで、オブジェクトを人間に読めるようにすることができます（ただし本当に読み取れるようになるかどうかは実装に依存する）。

便利なので、`Intent#toString()`とか、文字列リテラルで結合して自動で文字列化してもらったりとかするんですが、以下のような文字列が生成されます。

```
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.drivemode.intentlog.app/.MainActivity }
```

Action, Categories, Flag, Component が表示されます。

Action, Categories, Component は、これ以上はないほど親切に表示されますが、Flags は 16 進数になっていて、自分で頑張って計算しないと何がセットされていたのかよく分かりません。

Intent には Extras という、よそから引数みたいなものを渡す仕組みがあります。Intent に Extras が入っている場合、以下のようになります。

```
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10100000 cmp=com.drivemode.intentlog.app/.MainActivity bnds=[481,810][1312,1641] }
```

bnds という謎の項目が増えました。これはロリポップからこうなったようです。OS のバージョンによっては、(has Extras) しか表示されないこともあります。いずれにしても何のことだかさっぱり分かりません。

## 取り出して、確認

Flags の場合、ビット演算でどんなフラグがセットされているか見ることができます。

```java

Intent intent = getIntent();
int flags = intent.getFlags();

if ((Intent.FLAG_ACTIVITY_CLEAR_TOP & flags) != 0) {
    // FLAG_ACTIVITY_CLEAR_TOP が入っている
}
```

Extras の場合、Bundle の keySet を使ってイテレーションしながら、対応する値を取り出すことで中身を見ることができます。

```java

Bundle extras = intent.getExtras();
for (String key : extras.keySet()) {
    Object obj = extras.get(key);
}
```

## ユーティリティへ

https://github.com/Drivemode/IntentLogger

ここに置いておきます。そのうち maven central にも置きます。

ちなみに出力結果はだいたいこんなかんじです。

```
com.drivemode.intentlog.app V/test﹕ Intent[@172e5d96] content:
com.drivemode.intentlog.app V/test﹕ Action   : android.intent.action.MAIN
com.drivemode.intentlog.app V/test﹕ Category : {android.intent.category.LAUNCHER}
com.drivemode.intentlog.app V/test﹕ Data     : null
com.drivemode.intentlog.app V/test﹕ Component: com.drivemode.intentlog.app/com.drivemode.intentlog.app.MainActivity
com.drivemode.intentlog.app V/test﹕ Flags    : 10000001100000000000000000000
com.drivemode.intentlog.app V/test﹕ Flag     : FLAG_RECEIVER_FOREGROUND
com.drivemode.intentlog.app V/test﹕ Flag     : FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
com.drivemode.intentlog.app V/test﹕ Flag     : FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
com.drivemode.intentlog.app V/test﹕ HasExtras: true
com.drivemode.intentlog.app V/test﹕ Extra[profile] :0
```

やったねたえちゃん！Intent の中身全部丸見えだよ！
vimのコマンド(超初心者)


vim使っているけどよく忘れるのでメモっておく


#移動

|キー|動き|
|:--|:--|
|j|下に移動|
|k|上に移動|
|h|左に移動|
|l|右に移動|
|w|右に単語単位で移動|
|W|右に単語単位(記号を除く)で移動|
|b|左に単語単位で移動|
|B|左に単語単位(記号を除く)で移動|
|e|単語の末尾に移動|
|E|次の単語の末尾に移動|
|0|その行の先頭に移動|
|^|その行の先頭(余白を除く)に移動|
|$|その行の末尾に移動|
|f[任意の文字]|後方の任意の文字の場所に移動(faだったらaの場所に移動)|
|F[任意の文字]|前方の任意の文字の場所に移動|
|gg|ファイルの先頭に移動|
|G|ファイルの末尾に移動|
|+|次の行の先頭(空白を除く)に移動|
|-|前の行の先頭(空白を除く)に移動|

//TODO あとで続き書く
Railsでvalidation時に<div class="field_with_errors">が出てスタイルが崩れたら

Railsでvalidationでエラーメッセージを表示した際に```<div class="field_with_errors">```が出てしまいスタイルが崩れてしまった際の対処法メモです。ラジオボタンとかチェックボックスとか崩れやすいですね。

# 対処方

```rb:application.rb
config.action_view.field_error_proc = Proc.new { |html_tag, instance| %Q(#{html_tag}).html_safe }

```

# 参考
Configuring Rails Applications — Ruby on Rails Guides
http://guides.rubyonrails.org/configuring.html#configuring-action-view
ParseQueryでキャッシュポリシーをkPFCachePolicyCacheThenNetworkにした時の挙動


# 背景

## PFQueryのキャッシュポリシー

PFQueryのキャッシュポリシーにはいくつか種類がある。[^1]
そのうち、kPFCachePolicyCacheThenNetworkを指定した場合は、次の順番で処理が実行される。

1. 過去に同じクエリが発行されていれば、そのキャッシュから結果を得る
2. その後にサーバーに対してクエリを発行し、結果を得る

つまり、2回クエリが発行されているような挙動をするのだ。
1.でキャッシュがあるときと無いときの挙動を試してみたので記録しておく。

# 実験

## ソースコード

以下のようなコードで挙動を確認した。

```objc:
NSInteger count = 0;
PFQuery *query = [FPUser query];
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
    count++;
    NSLog(@"timing: %d, error: %@", count, error);
}];
```

## 結果

### キャッシュがあるとき

```txt:second.log
2014-12-24 23:39:17.986 Sample[3232:60b] timing: 1, error: (null)
2014-12-24 23:39:19.058 Sample[3232:60b] timing: 2, error: (null)
```

キャッシュがあるときは、一回目も二回目もエラーはなし。

### キャッシュが無い時

```txt:first.log
2014-12-24 23:38:39.262 Sample[3232:60b] timing: 1, error: Error Domain=Parse Code=120 "The operation couldn’t be completed. (Parse error 120.)" UserInfo=0x14635320 {code=120, error=cache miss}
2014-12-24 23:38:40.009 Sample[3232:60b] timing: 2, error: (null)
```

キャッシュがない時は、一回目がエラーになる模様。
そして2回blockが呼ばれるのは同じ。

## 表でまとめると

| キャッシュの有無 | blockの呼ばれる回数 | エラーの有無 |
|:--------------|------------------:|:----------:|
| 有             |               2回 |   エラーなし|
| 無             |               2回 | 1回目がエラー|

# 参考
[^1]: PFQueryのキャッシュポリシーは6種類ある

>     // kPFCachePolicyIgnoreCache：キャッシュ使わない
    // kPFCachePolicyCacheOnly：キャッシュしか使わない
    // kPFCachePolicyNetworkOnly：Readはネットワークだけでやる。Writeはキャッシュにする。
    // kPFCachePolicyCacheElseNetwork：キャッシュにデータがなかったらネットワークにアクセスする
    // kPFCachePolicyNetworkElseCache：ネットワークにアクセスできなかったらキャッシュを使う
    // kPFCachePolicyCacheThenNetwork：まずキャッシュにアクセスし、その後ネットワークにもアクセスする。callbackが二回呼ばれる

出典: ParseのiOS Guide抄訳５ - 日々精進
http://anton0825.hatenablog.com/entry/20120822/1345798030
Windows8マシンを社内gitサーバにする

# はじめに

Windows8マシンをプライベートなgitサーバにする方法です。

無料で、10〜20人程度が使う、社内プライベートなgitサーバが必要でした。
丁度良くSubversionをホストしていたWindows8マシンが1台あったので、それをgitサーバに変身させました。

ソフトウェアは、調査検討した結果「Gitblit」に落ち着きました。
1年間以上運用していますがトラブルなく使用できています。

Unix系ではなくWindowsでgitをホストしたいんだ！という方の参考になりましたら幸いです。

# JREのインストール

バージョン7以降が必須です。
こちらからダウンロードしインストールします。

https://java.com/ja/download/

32bit版と64bit版があることに気を付けましょう。
動かしているOSのbit数に合わせます。

# Gitblit GO のダウンロードとインストール

こちらより「Gitblit GO」をダウンロードします。

http://gitblit.com/

展開してC:¥直下にgitblitフォルダを作り中身を配置。
パスにスペースが無い方が良いようです。


### data/gitblit.propertiesの編集
propertiesファイルを2行編集します。

```lang:gitblit.properties
(前後略)
server.httpPort 任意のポート:(例) 8050
(中略)
server.storePassword 任意のパスワード
```

### gitblit.cmd実行
コマンドラインよりgitblit.cmdを実行します。
開始をしばし待ちましょう。

### ブラウザで動作確認
http://localhost:8050 (例)

Gitblitの画面が表示されたら成功です。
admin / adminでログインしてください。

# サービス化

サービス化することでWindowsを再起動しても自動で立ち上がってくれます。

### installService.cmd内容確認と実行

ARCH、StartParamsの内容を確認します。

```lang:installService.cmd
@REM Install Gitblit as a Windows service.

@REM gitblitw.exe (prunmgr.exe) is a GUI application for monitoring 
@REM and configuring the Gitblit procrun service.
@REM
@REM By default this tool launches the service properties dialog
@REM but it also has some other very useful functionality.
@REM
@REM http://commons.apache.org/daemon/procrun.html

@REM arch = x86, amd64, or ia32
SET ARCH=amd64

@REM Be careful not to introduce trailing whitespace after the ^ characters.
@REM Use ; or # to separate values in the --StartParams parameter.
"%CD%\%ARCH%\gitblit.exe"  //IS//gitblit ^
		 --DisplayName="gitblit" ^
		 --Description="a pure Java Git solution" ^
		 --Startup=auto ^
		 --LogPath="%CD%\logs" ^
		 --LogLevel=INFO ^
		 --LogPrefix=gitblit ^
		 --StdOutput=auto ^
		 --StdError=auto ^
		 --StartPath="%CD%" ^
		 --StartClass=org.moxie.MxLauncher ^
		 --StartMethod=main ^
		 --StartParams="--storePassword;gitblit;--baseFolder;%CD%\data" ^
		 --StartMode=jvm ^
		 --StopPath="%CD%" ^
		 --StopClass=org.moxie.MxLauncher ^
		 --StopMethod=main ^
		 --StopParams="--stop;--baseFolder;%CD%\data" ^
		 --StopMode=jvm ^
		 --Classpath="%CD%\gitblit.jar" ^
		 --Jvm=auto ^
		 --JvmMx=1024
```

コマンドラインよりinstallService.cmdを実行します。

サービス一覧より確認すると
gitblitのサービスが追加されています。
`
C:\gitblit\amd64\gitblit.exe //RS//gitblit
`

※サービス化のあたりの記録と記憶が少し曖昧です。
動作しなかったら申し訳ないです。

# おわりに
https化の内容は省略しています。

2014/12現在では、GitBucketも良さそうです。
baserJSでマウスオーバーすると半透明になるエフェクトをかける


Webサイトと詳しいAPIリファレンスはこちら [baserJS Webサイト](http://baserproject.github.io/baserjs/)

## マウスオーバーすると半透明になるエフェクトをかける

```js
// href属性をもつa要素が対象とすると
$('a[href]').bcShy();
```

## CSS使いましょう

このメソッドは基本的に **非推奨** です。

理由はCSSでなんとかなるからです。

```css
a[href] {
	opacity: 0.4;
	filter: alpha(opacity=40); /* for IE6/7 */
	-ms-filter: "alpha(opacity=40)"; /* for IE8 */
}
```
getJSONを並行非同期実行する方法

# getJSONを並行非同期実行する方法

for文が実行されるたびにjが生成されるため、想定通りdata_storeに値が代入される。

			for(var i = 0, len = codes.length; i < len; i++) {
				(function(j) {
					$.getJSON("statements/" + codes[j], function(json){ 
						data_store[codes[j]] = json; 
					});
				})(i);
			}


# 悪い例

for文が全部実行されたあとで、匿名関数function(json){~}が実行されるため、iがcodes.lengthの状態でdata_storeに値を代入しようとしている。


			for(var i = 0, len = codes.length; i < len; i++) {
				$.getJSON("statements/" + codes[i], function(json){ 
					data_store[codes[i]] = json; 
				});
			}
"Yahoo!ビッグデータインサイト" を紹介します！

こんにちは、Treasure Data の西澤無我です。今回は、今年の 9 月下旬にローンチしました Yahoo! JAPAN のサービスである「Yahoo!ビッグデータインサイト」の話題を取り上げようと思います。

Yahoo!ビッグデータインサイトとは、大まかに説明しますと、IDCF クラウド上で動いているトレジャーデータのサービスのことです。トレジャーデータは AWS US のリージョン上で数年の間サービスを提供しておりますが、それと同様に IDCF クラウド上でもサービス提供を開始しました。現在、Yahoo!ビッグデータインサイトは、AWS 上の弊社サービスとほぼ同等の機能を提供できています。むしろ、IDCF クラウド上でコンソールや API サーバが動作していますので、日本からアクセスする場合、AWS のと比較しコンソールがサクサク動くのが体感できるかと思います。また、IDCF クラウド上でサービスが提供されていますので、セキュリティポリシー上データを国外に出せないという場合でも安心してご利用いただけます。

ここでは、Yahoo!ビッグデータインサイトの機能を説明していきながら、IDCF クラウドのどのような機能を利用し、トレジャーデータのシステムのポーティングを実現しているのかについて部分的にお話できればと考えています。

* [Yahoo!ビッグデータインサイト, IDCフロンティア](http://www.idcf.jp/bigdata/)
* [ヤフー株式会社の「Yahoo!ビッグデータインサイト」を提供開始, IDCフロンティア](http://www.idcf.jp/pressrelease/2014/20140925001.html)

## 分散ストレージ Riak CS の利用 ##

以下は、Yahoo!ビッグデータインサイトのコンソール上でクエリを発行できるクエリエディタのページです。しっかり Yahoo!ビッグデータインサイトのロゴが入っています。もう少し基本的なサービスの利用方法については、「[Yahoo!ビッグデータインサイトを使ってみた, IDC Frontier Engineers' Blog](http://www.idcf.jp/blog/bigdata/ybi_started/)」を参照してください。

![sample query on YBI](http://i.gyazo.com/4b15c4893a48e1bf0c84aa193ad122b2.png)

このクエリが実際に実行される際に、ユーザの方々からお預かりしているデータは弊社で開発したストレージシステムである PlazmaDB に格納されていますが、PlazmaDB のバックエンドとして、IDCF クラウドが提供する分散ストレージである Riak CS が使われています（PlazmaDB に関する詳しい情報は、「[Treasure Data の PlazmaDB を理解する](http://qiita.com/xerial/items/959d2b928353b595f31e)」を参照してください）。IDCF クラウドに弊社システムをポーティングするにあたり、一番大きな障壁だと思われたのが、PlazmaDB のバックエンドとして IDCF クラウドの Riak CS を利用できるかどうか、でした。PlazmaDB にはそのバックエンドを差し替えられる拡張ポイントがすでに用意されており、理想的には Riak CS も利用できるわけですが、充分な性能が出せるかどうか、もしくは正しく結果が返ってくるのかどうか、については実際に試してみないと分かりません。そのため、想定されるアクセスパターンを利用して Riak CS の性能を測定し、弊社サービスに充分な性能を Riak CS が出せていることを数週間かけて確認しました。また、Riak CS のアーキテクチャ上、不得意と思われるリクエストを送信しないよう PlazmaDB 側を修正したりもしました。

* [Riak CS, Basho Technologies](http://basho.com/riak-cloud-storage/)

## インスタンス管理 ##

弊社システムの特徴上、大量のインスタンスを一度に作成・削除することがしばしばあります。そのためにはインスタンス生成をほぼ自動で行えると便利であり、弊社では IDCF クラウドが提供する CloudStack API を利用しています。CloudStack API をラップしたライブラリがインターネット上にいくつも見受けられます。それらを利用し、AWS 上の弊社システムの既存の運用ツールを拡張し、ほぼ同じインターフェイスで IDCF クラウドのインスタンスを運用できるようにしました。

* [Apache CloudStack: API Documentation](http://cloudstack.apache.org/docs/api/)
* [IDCフロンティア セルフクラウド APIドキュメント](http://www.idcf.jp/cloud/docs/)

また、弊社システムを構成する様々なコンポーネントをどのインスタンスタイプで動かすべきかについても考える必要がありました。AWS 上で充分にノウハウが蓄積されているとはいえ、AWS と IDCF クラウドではコアの性能がそれなりに違うように見受けられましたので、性能/コストのベンチマークを取りつつインスタンスタイプを選んでいく必要がありました。特に、弊社システムでは、クエリエンジンを多数のインスタンス上で実行し、スケールアウトさせて、クエリのレイテンシを向上させることが多いので、コスパの良いインスタンス選びが必須となります。例えば、Hadoop のスレーブノードの場合であれば、コアがなるべく集積されており、1 map/reduce slot を一番低いコストで割り当てられるインスタンスという観点からベンチマークを行いタイプを選びました。

さらに、マシンの環境変数を AWS と IDCF クラウドのインスタンス全体で明示的に揃えることをしています。例えば、タイムゾーンなどです。弊社システムのコードベースは単一ですが、継続デプロイの仕組みを利用し、AWS, IDCF クラウドの両クラウド上にほぼ同時にデプロイが行われます。片方のクラウド上で何か不具合が発生している場合、両クラウドでそれが再現しているかを確認するのが、問題の切り分けの第一歩になります。その際に、両クラウドのインスタンス上で別々のタイムゾーンが利用されていると、両クラウド上の弊社システムのソフトウェアのログ（特に同時刻のログ）をつき合わせて確認するときに不便が生じる可能性があります。

## おわり ##

ここまでつらつらと Yahoo!ビッグデータインサイトとそのポーティングについてお話させていただきましたが、いかがでしょう。また、もし Yahoo!ビッグデータインサイト興味のある方がいらっしゃいましたら、ぜひお試しください。それではメリークリスマスと良いお年を ༼ つ ◕_◕ ༽つ
baserJSでマウスオーバーすると一瞬透明になるエフェクトをかける


Webサイトと詳しいAPIリファレンスはこちら [baserJS Webサイト](http://baserproject.github.io/baserjs/)

## マウスオーバーすると一瞬透明になるエフェクトをかける

```js
// href属性をもつa要素の中のimg要素が対象とすると
$('a[href] img').bcWink();

// オプション (以下デフォルト値)
$('a[href] img').bcWink({
	close: 50, // 透明になるまでの時間(ミリ秒)
	open: 200, // 透明から戻るまでの時間(ミリ秒)
	opacity: 0.4, // 不透明度の下限
	target: null, // 後述
	stopOnTouch: true // タッチイベントではエフェクトを無効にする
});
```

## 注意点

昔からある既知の問題ですが、IE8以前の透過PNGはalphaフィルタを当てるとアルファチャンネルカラーが黒く濁る問題があるので、使用は避けたほうがいいでしょう。

上記の問題を解消するプラグインも多数存在しますが、原因不明の特定の条件下では解消できなかったりということがザラにある（あった）のでお薦めはできません。
Sendmailの送信が異状に遅い場合の対応


vagrantを使った開発環境でPHPからのメール送信が必要だったため、
Sendmailをインストール。

そしたら、送信が異状に遅いのでgoogle先生に教えてもらう。

##コマンドラインでの確認

```
/usr/sbin/sendmail -v hoge@hogehoge.jp < hoge.txt
```

コマンドうった時点で、異様に遅い。しばらくすると、返ってきた。

```
WARNING: local host name (hogehoge) is not qualified; see cf/README: WHO AM I?
hoge@hogehoge.jp... Connecting to [127.0.0.1] via relay...
220 hogehoge ESMTP Sendmail 8.14.4/8.14.4/Debian-2ubuntu2.1; Thu, 25 Dec 2014 16:43:37 +0900; (No UCE/UBE) logging access from: localhost(OK)-localhost [127.0.0.1]
.
.
.
.
```

```host name```がおかしいらしい。

##hostsの設定に追記

```/etc/hosts
127.0.0.1 hogehoge hogehoge.localdomain
```

を追記して対応し、もう一度コマンドをうって確認。

```
/usr/sbin/sendmail -v hoge@hogehoge.jp < hoge.txt
```

OK

***
##参考サイト
[sendmailでのメール送信が異常に遅い場合の対処](http://myboom.mkch.net/modules/pukiwiki/175.html)
Javaのこんなコードは1行にまとめようぜ

Railsのアドベントカレンダーを見てたら、こんなエントリを発見。

- [RubyOnRailsでこんなコードを書いてたら今すぐリファクタリングして１行にまとめちゃおうぜ！small tips!](http://qiita.com/taiyop/items/17b26d79129ac620ccb8)

眺めてたらなんとなく「Javaでも同じようにできるんじゃね？」って気になってきたので、書いとく。

# リファクタリング 1st

true/falseで条件分岐

### Before

``` java
List<Comment> comments;

public boolean hasComments() {
  if(this.comments.size() > 0) {
    return true;
  } else {
    return false;
  }
}
```

Javaとか関係なく、これはワンライナーだよねー

### After

``` java
List<Comment> comments;

public boolean hasComments() {
  return this.comments.size() > 0;
}
```

- 追記

``` java
public boolean hasComments() {
  return !this.comments.isEmpty();
}
```

のほうがいいんじゃない？というリクエストがありましたが、個人的にはnot演算子は見えにくいのと、ぱっと見の読みづらさがあって、好みではないです。好みの問題ですが・・・^^;

# リファクタリング 2nd

commnetsが特定の条件を満たすかどうかの判定を書く場合。

### Before

``` java
private List<Comment> comments;

private int user_id;

public boolean onlyMyComments() {
  for(Comment comment : this.comments) {
    if(comment.getUserId() != this.user_id) {
      return false;
    }
  }
  return true;
}
```

全てが条件を満たすか？の判定はStreamAPIのallMatchを使いましょう。これもワンライナーで。

### After

``` java
private List<Comment> comments;

private int user_id;

public boolean onlyMyComments() {
  return this.comments.stream().allMatch(commnet -> commnet.getUserId() == this.user_id);
}
```

# リファクタリング 3rd

値の存在によって処理を変えるパターン

``` java
String value = "hoge";
...
if(value == null) {
  System.out.println("null!!");
} else {
  System.out.println(value);
}
```

値の存在によって処理を分けるにはOptionalを使いましょう。これもワンライナー。

### After

``` java
Optional<String> value = Optional.of("hoge");  //空にするにはOptional.empty()
...
System.out.println(value.orElse("null!!"));
```

# リファクタリング 4th

ループで回して、その合計を取るパターン。

### Before

``` java
private List<Student> students;

public int total() {
  int result = 0;
  for(Student student :  students) {
    result += student.getScore();
  }
  return result;
}
```

Java8以降では「forを見たらstreamと思え！」という言葉がある（？）ように、streamを使えば美しく書けます。

### After

``` java
private List<Student> students;

public int total() {
  return students.stream().mapToInt(student -> student.getScore()).sum();
}
```

途中のmapToIntでIntStreamに変換するのがポイント。硬派にmapとreduceでやりたい人は

``` java
private List<Student> students;

public int total() {
  return students.stream().map(student -> student.getScore()).reduce(0, (value1, value2) -> value1 + value2);
}
```

# まとめ

Java8以降ではStream APIをガリガリ使えるかどうかが効率の良い、かつ、美しいコードを書くために必須になりますね。皆さんもJavaの美しいワンライナーを見つけてください！
FuelPHPの空プロジェクトを最速構築（カスタマイズ可）

公式ドキュメントの方法だとサンプル的なコントローラーが入っていたりGit管理できなかったり色々手を加えないと開発開始できないので、お好み設定で最速構築してしまおうという手順。

# EmptyAppを用意

https://github.com/goosys/Fuel-Vendor-Enptyapp

* 予めお好みの初期状態にした空プロジェクト(fuel/appとpublic/以下など)をまとめてEmptyAppとしておく。
* 初期設定用のコマンドを用意する。

```sh:copy.sh
cp -f -r fuel/vendor/emptyapp/fuel/* fuel/
cp -f -r fuel/vendor/emptyapp/public .
cp -f -r fuel/vendor/emptyapp/.gitignore .
```

* それをGithubなんかに上げておくと便利。

# composer.jsonを用意

https://github.com/goosys/Fuel-Installer/blob/master/composer.json

* 公式のcomposer.jsonをコピーして利用
* EmptyAppの記述を追加 （省略）※githubに上げなかった場合は不要
* インストール後に実行できるコマンドでEmptyAppで作ったコマンドを実行するよう設定
* ついでに```git init```も追加

```json:composer.json
    "scripts": {
        "post-install-cmd": [
            "bash fuel/vendor/emptyapp/copy.sh",
            "oil r install" ,
            "git init"
        ]
    }
```

# インストール

* 後は、プロジェクトディレクトリ内でインストールするだけ。

```
mkdir PROJECT
cd PROJECT
wget https://raw.githubusercontent.com/goosys/Fuel-Installer/master/composer.json -O composer.json  --no-check-certificate
wget https://raw.githubusercontent.com/fuel/fuel/1.7/master/oil -O oil --no-check-certificate
curl -s http://getcomposer.org/installer | php
php composer.phar install
```

# おわり

上記２つのリポジトリはライセンスフリーです。
Forkでもコピーでもして使ってください。
ただし、masterの状態は保障しません。（突然変わるかもしれません）
node-webkitとは何か



# Node.jsとは
* サーバーサイドで動かすJavaScript
* コマンドラインで動かせるので、ブラウザなしでスクリプト言語としても使える

# node-webkit
* HTML/CSS/JavaScriptでつくられたGUIのデスクトップアプリを作成することができる
 * できるNode.jsとChromiumエンジンで実現
* Node.jsのモジュールも使える

# インストール

```shell-session:
$npm install nodewebkit
```

# サンプル
## 必要なファイル
* package.json : アプリの情報
* htmlファイル : コンテンツ

## package.jsonの例

```javascript:package.json
{
  "name": "nw-demo",
  "main": "index.html",
  "scripts": {
    "start": "./node_modules/nodewebkit/bin/nodewebkit"
  },
  "dependencies": {
    "nodewebkit": "^0.10.5"
  }
}
```


## コンテンツの例
memo.txtの内容を表示する。
(DOMとnodeのモジュールをまぜて使うことが可能)

```
var ret = document.getElementById("ret");
var fs = require("fs");
var data = fs.readFileSync('./memo.txt');
ret.innerHTML = data;
```

## 結果

![nodewebkitsample.png](https://qiita-image-store.s3.amazonaws.com/0/4044/3da19675-b208-15b9-3fdd-4b1abeeb4bb8.png "nodewebkitsample.png")

# Native UI API
* NativeのUI操作のAPIを利用できる
* ```require('nw_gui')```で利用できる
* Windowの最小化等、様々なAPIを定義

# C/C++
* Node.jsのモジュールはC/C++でもかけるので、node-webkitでもモジュール作成可能
＊ C/C++のビルドには、nw-gypが必要

# 参考情報
https://github.com/rogerwang/node-webkit/wiki
http://www.amazon.co.jp/Windows-Desktop-Creation-node-webkit-English-ebook/dp/B00EEYFFVC