OmniAICreator/Qiita-1.07M huggingface dataset:
Android（Java）での簡単な正規表現バリデーション

--
inputTypeは便利だけど、入力制限だけ（ですよね？）。
バリデーションにはやはり正規表現。String.matchesを使えばいい。
一字ずつ処理チェックしたい場合はEditTextのaddTextChangedListenerを使えば良いみたい。

正規表現は、\の扱いにちょっと癖があるな。.は\\.ではなく\\\.みたい（Markdown上だと１本おおい）。


```MyActivity.java
public class MyActivity extends Activity {

    private EditText etEmail;
    private String email;
	//パターン（\\に注意）
    private String email_pattern = "[a-zA-Z0-9._-]+@[a-z]+\\.+[a-z]+";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        //email
        etEmail = (EditText)findViewById(R.id.etEmail);

    }
	
	//XMLのonClickで設定
    public void onClick(View v){

        String email = etEmail.getText().toString();
        if(email.matches(email_pattern)){
			//match
            Toast.makeText(getApplicationContext(),"match",Toast.LENGTH_SHORT).show();

        }else{
			//unmatch
            Toast.makeText(getApplicationContext(),"un match",Toast.LENGTH_SHORT).show();

        }
    }
```
Git 1ファイルだけ別のブランチから持ってくる


マージとかで使える

# 確認

```
git show <ブランチ名>:<ファイル名>
```

# 取ってくる

```
git checkout <ブランチ名> -- <ファイル名>
```

# ディレクトリもいける

```
git checkout <ブランチ名> <ディレクトリ名>
tree #確認
```
少しだけ実用的な DigitalOcean 用 Vagrantfile

[本家のドキュメント](https://github.com/smdahlen/vagrant-digitalocean)を参考に、少しだけ実用的な設定ファイルを書いてみました。
Vagrant 初心者なので、不備があったら指摘してください。

(追記) config.vm.define を override.vm.hostname に修正しました。

```rb:Vagrantfile
Vagrant.configure('2') do |config|
  config.vm.provider :digital_ocean do |provider, override|
    override.ssh.private_key_path = '~/.ssh/id_rsa'
    override.ssh.username = 'myname'

    override.vm.box = 'digital_ocean'
    override.vm.box_url = 'https://github.com/smdahlen/vagrant-digitalocean/raw/master/box/digital_ocean.box'
    override.vm.hostname = 'MyDroplet'
 
    provider.token = 'My Token'
    provider.image = 'ubuntu-14-04-x64'
    provider.region = 'sgp1'
    provider.size = '512mb'
    provider.ssh_key_name = 'My SSH Key'
  end
end
```

* __override.ssh.username__ で、作成された VM にユーザーを作成する
    * デフォルトだと root ユーザーのみなので、ユーザーを作る手間を省略できる
* __override.vm.hostname__ で、Droplet の名前を変更する
    * デフォルトだと default という Droplet が作られてしまい、複数作ると被ってしまいます
* __provider.region__ は sgp1
    * 日本からならシンガポールがいいですよね
* __provider.ssh_key_name__ で、DigitalOcean に登録する鍵の名前を変更する
    * 変更しないと Vagrant という名前で作成されてしまい、どの端末かわからなくなる
    * また、既に鍵を登録している場合はその名前にしないとエラーになる

これに加えて dotenv プラグインをインストールして、Devenv.load を呼んで provider.token とかの中身を .env ファイルに分離すると良いかもしれません。
scss -> sass の変換


先日、
**Jade + Sass (or Stylus) のススメ** という記事が話題になっていました。

http://umai-bow.hateblo.jp/entry/2014/10/05/222040

要はJadeを使っているならそれと同じインデントスタイルのSassを使うべきだ。Scssを使うな！って話で、ああ確かになと思ったので僕もscssからsassに移行しようと試みました。

そこで、これまで使っていたreset.scssなどをSassの書式にちまちま書き直す作業をしていたのですが、調べてみるとScssからSassに変換する便利なコマンドがあったようです。


```
sass-convert hogehoge.scss hogehoge.sass
```


これをコマンド上で打つだけでscssからsassへ簡単に変換することができます。

ちなみにsassでは、
@mixin は、= で
@include は + で
表されるそうです。coolですね。
css縦グラデの書き方を整理する

[デモ](http://jsdo.it/ksk1015/hfum)

cssプリプロセッサ使ってればあまり細かいこと考えなくていいかもしれませんが、
prefix、fallbackばっちり書くと記述量大杉なので、整理する。
なお方向を指定しない場合、先に記述する色が上、後が下になります。
-webkit-gradientはグラデのタイプと共に方向の指定は必須となります。

フルフルに書くと

```lang:css
.linear-gradient1 {
	background: silver; /* fallback */
	*filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='silver', endColorstr='gray'); /* IE8 */
	-ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='silver', endColorstr='gray')"; /* IE9 */
	background: -webkit-gradient(linear, left top, left bottom, from(silver), to(gray)); /* Chrome9以前, Safari5以前, iOS Safari4.3以前 Android2.x Android3.x */
	background: -webkit-linear-gradient(silver, gray); /* Chrome25以前, Safari6以前, iOS Safari6.1以前, Android4.3以前 */
	background: -moz-linear-gradient(silver, gray); /* Firefox15以前 */
	background: -o-linear-gradient(silver, gray); /* Opera12以前 */
	background: linear-gradient(silver, gray); /* IE10以降, Firefox16以降, Chrome25以降, Safari6.1以降, Opera12.1以降, iOS Safari7以降, Android4.4以降 */
}
```

filterで古いIEに対応するのやめて、
-moz-gradientや-o-gradientもなくていい気するのでこれも削れば、
以下のように書けます。

```lang:css
.linear-gradient2 {
	background: silver; /* fallback */
	background: -webkit-gradient(linear, left top, left bottom, from(silver), to(gray));
	background: -webkit-linear-gradient(silver, gray);
	background: linear-gradient(silver, gray);
}
```

方向を指定する場合
上から下は、-webkit-linear-gradient は top 、prefix無いのは、 to bottom
下から上は、-webkit-linear-gradient は bottom 、prefix無いのは、 to top 
と書きます。下記は下から上のサンプル。

```lang:css
.linear-gradient3 {
	background: silver; /* fallback */
	background: -webkit-gradient(linear, left bottom, left top, from(silver), to(gray));
	background: -webkit-linear-gradient(bottom, silver, gray);
	background: linear-gradient(to top, silver, gray);
}
```

Android2系のサポートしなければ、-webkit-gradient もとっていいかな。
あと時々散見される-ms-gradientなんてないです。

参考サイト http://caniuse.com/#feat=css-gradients
Elixir Module attributes

# Elixir Module attributes

## 概要
Elixir の Module attributes について。

## Module Attributes の役割
* ユーザーやVMに知らせるアノテーション情報
* 定数
* 一時保存

## ユーザーやVMに知らせるアノテーション情報
VMのコンパイル前後へのフックの設定や、
ドキュメンテーション用の情報などを設定できる。
ドキュメントは ExDoc で出力可能です。

* [ExDoc GitHub](https://github.com/elixir-lang/ex_doc)

具体的なアノテーションには  

* @after_compile : モジュールのコンパイル後のフック
* @doc : function, macro のドキュメンテーションコメント用
* @moduledoc : module のドキュメンテーションコメント用

などがあります。

詳しくは公式ドキュメントの Module の attributes 参照。
[Module](http://elixir-lang.org/docs/stable/elixir/Module.html)

### サンプルコード

@on_definition アノテーションを試してみます。

~~~
defmodule Hook do
  def on_def(_env, kind, name, args, guards, body) do
    IO.puts "kind: #{kind}"
    IO.puts "name: #{name}"
    IO.puts "guards: "
    IO.inspect guards
    IO.puts "args: "
    IO.inspect args
    IO.puts "body: "
    IO.puts Macro.to_string(body)
  end
end

defmodule HookUser do
  @on_definition {Hook, :on_def}

  def hoge(msg) do
    IO.puts msg
  end

  def hoge_with_guard(list) when is_atom(list) or is_list(list) do
    IO.inspect list
  end
end
~~~

### 出力

~~~
kind: def
name: hoge
guards:
[]
args:
[{:msg, [line: 17], nil}]
body:
IO.puts(msg)
kind: def
name: hoge_with_guard
guards:
[{:__op__, [line: 21],
  [:orelse,
   {{:., [], [:erlang, :is_atom]}, [line: 21], [{:list, [line: 21], nil}]},
   {{:., [], [:erlang, :is_list]}, [line: 21], [{:list, [line: 21], nil}]}]}]
args:
[{:list, [line: 21], nil}]
body:
IO.inspect(list)
~~~

## 定数
### サンプルコード

~~~
defmodule Months do
  @january 1
  @february 2
  @march 3
  @april 4
  @may 5
  @june 6
  @july 7
  @august 8
  @september 9
  @october 10
  @november 11
  @december 12

  def months, do: [@january, @february, @march, @april, @may, @june, @july, @august, @september, @october, @november, @december]
end

IO.inspect Months.months
~~~

### 出力

~~~
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
~~~

## 一時保存
下記ページ参照
[As temporary storage](http://elixir-lang.org/getting_started/14.html#14.3-as-temporary-storage)

## 参照
* [Elixir getting_started 14](http://elixir-lang.org/getting_started/14.html)
* [ExDoc GitHub](https://github.com/elixir-lang/ex_doc)
octpressでmaterial design風味のblogをつくる

# どうやるか

- [octopress](https://github.com/octopress/octopress)

- [octostrap3](https://github.com/kAworu/octostrap3)

- [bootstrap-material-design](https://github.com/FezVrasta/bootstrap-material-design)

を使う

# 前提

- git
- Node
- npm
- ruby

※最低限のバージョンは調べてない。動かなかったら最新入れてください。

# 準備

### hubがなければ入れる

なくてもいいです。

```zsh
% gem install hub
```

### bowerがなければ入れる

```zsh
% npm install -g bower
```

# やりかた

### octopressを入れる

```zsh
% mkdir my_octopress
% hub clone imathis/octopress my_octopress
% cd my_octopress
% bundle
```

### octostrap3を入れる

```zsh
% hub clone kAworu/octostrap3 .themes/octostrap3
% rake 'install[octostrap3]'
% rake generate
```

### bootstrap-material-designを入れる

```zsh
% echo '{"directory": "source/assets"}' > .bowerrc
% bower i bootstrap-material-design
```

### htmlの調整

```diff:source/_includes/custom/head.heml
+ <link href="{{ root_url }}/assets/bootstrap-material-design/dist/css/material.min.css" rel="stylesheet" type="text/css">
```

navbar-defaultがあるとタイトルとか見えないので、外す

```diff:source/_includes/custom/navigation.html
- <nav class="navbar navbar-default" role="navigation">
+ <nav class="navbar" role="navigation">
```

### 確認
```zsh
% rake new_post['test']
% echo '#hoge\n<!-- more -->\nfuga' >> source/_post/yyyy-mm-dd-test.markdown # 操作日で
% rake preview
```

[http://localhost:4000](http://localhost:4000)で確認

![screenshot-octopress.png](https://qiita-image-store.s3.amazonaws.com/0/54295/73a501ec-df43-4e49-b346-e144ced2673d.png)

「READ ON」のボタンがそれっぽくなるだけなんですけどね... :stuck_out_tongue:
Virtualbox のホストオンリーアダプター設定メモ

ホストオンリーアダプターの設定メモ

ホスト OS は Mac
ゲスト OS は CentOS 6.5

# ネットワークの追加

Virtualboxの「環境設定」->「ネットワーク」->「ホストオンリーネットワーク」
にてネットワークを追加する。

これを実行することで、ホスト OS 側に「vboxnet0」というネットワークアダプターが追加される。
設定ウィンドウに表示されている「IP アドレス」と「サブネットマスク」を覚えておく。

# ゲスト OS 側のネットワークアダプター追加

仮想マシンの「設定」->「ネットワーク」
にてホストオンリーネットワークアダプターを追加する。

設定ウィンドウに表示されている「MAC アドレス」を覚えておく。

ゲスト OS を再起動し、コンソールからゲスト OS にログインする。
```/etc/sysconfig/network-scripts/ifc-eth1```
を追加する。

「IP アドレス」と「MAC アドレス」を追加し、```/etc/init.d/network restart``` を実行する。
風の動きを可視化した地図サイト

**[2015/03/10]
[地図を使ったWebサービスや可視化サイトのリンク集](http://goo.gl/huCuAj)をまとめました。
ここで紹介しているearthと東京風速もそちらにまとめてあります。**

---

風の動きを地図上で可視化したサイト。
d3.jsを使ってるらしい。

earth
http://earth.nullschool.net/jp/

Tokyo Wind Map(東京風速)
http://air.nullschool.net/

Github
https://github.com/cambecc/earth
https://github.com/cambecc/air

![台風.png](https://qiita-image-store.s3.amazonaws.com/0/35192/c2b3d7dc-463b-a8f6-bb2e-0cfddd259907.png)
Vagrant環境下でbundle installが止まる／遅い場合はNFSの設定を確認する


Vagrant環境でRailsアプリをガシガシ開発していると、なぜか`bundle install`が妙に遅い、もしくは途中で完全に止まってしまう現象にぶち当たって悩んでいた所、諸悪の根源はどうやらNFSの設定だった模様。

なお、`bundle install`が止まっている場合、IOWaitが100%になってて、全く動作していない感じ。

# 対処方法

対処方法は非常に簡単。

- NFSを設定していたら、OFFにしましょう。

…って言っても、NFSをOFFにしたらRailsアプリ重くて死ぬって言うこともあると思うので、ONにしたいよね。というわけで、もう少し調べて行ったら、どうやら複数のVagrantをNFSで動かしていて、しかもIPがかぶった場合？に動作がおかしくなるっぽい。

完全に確認したわけじゃないので、これが正しいかどうかは分からないが…

- Vagrant環境には被らないIPを設定し、NFSを有効にする

これが今のところの対処法。

# VagrantのNFS設定

そもそものVagrantでNFSを有効にする方法。さくっと設定するなら、こんな感じでしょう。

```Vagrantfile
config.vm.synced_folder ".", "/vagrant", nfs: true
```

vagrant upするとrootパスワードを求められて、入力すれば自動的にNFSが設定されているはず。

```bash:command
# vagrant起動
$ vagrant up

# NFSの稼働状況確認
$ sudo nfsd status
nfsd service is enabled
nfsd is running (pid 2009, 8 threads)
```

さらに言うと、ホスト側の`/etc/exports`にNFS対象ディレクトリ情報も記載されている。

```/etc/exports
# VAGRANT-BEGIN: 501 1c00c97c-5834-4a02-886d-90921fdf091e
"/Users/zaru/Sites/rails_proj" 192.168.33.17 -alldirs -mapall=501:20
# VAGRANT-END: 501 1c00c97c-5834-4a02-886d-90921fdf091e
```

ここまでは至って普通。

問題は、`192.168.33.17`このIPが指定されている他のVagrant環境がある場合に、おかしくなると思われる。まぁ、そりゃそうなんだろうけど、気が付かぬうちにIPがかぶっていることもある。なので、別のIPをちゃんと割り当ててあげればOK。

開発環境にはなるべくIPを固定で割り当てたいんだけど、ここは真面目に手動で管理するしかないのかな…。
vSphere環境での仮想ディスクサイズの縮小

## 概要

vSphere環境上の仮想マシンに対して、仮想ディスクのサイズを縮小するためには、vCenter Converter StandaloneによるV2Vを行う。

## 詳細

vSphere環境上の仮想マシンへの、仮想ディスクサイズの変更方法は、[VMware KB: Growing, thinning and shrinking virtual disks for VMware ESX and ESXi (1002019)](http://kb.vmware.com/kb/1002019)にまとめられている。以下の3点が説明されている。

* 仮想ディスクサイズの拡張（Expanding）
* 仮想ディスクサイズの縮小（Shrinking）
* 仮想ディスクファイルの実使用量への収縮（Thinning）

ここでは仮想ディスクサイズの縮小を説明する。なお、シンプロビジョン（vSphereでのシンプロビジョニング、VMware Workstation等での自動拡張）された仮想ディスクサイズを、肥大化した際に実使用量まで戻す収縮（Thinning）と混同しないこと。

### vCenter Converter Standaloneを使用した縮小方法

仮想ディスクのサイズを縮小するためには、[vCenter Converter Standalone](http://www.vmware.com/jp/products/converter)によるV2Vを行う。このツールは、物理マシンから仮想マシンへのコンバートであるP2Vツールとして知られているが、仮想マシンから仮想マシンへの変換であるV2Vでも訳にたつ。

Converterによる仮想マシンの変換（V2V）では、実施ウィザードの途中で、変換後の仮想ハードウェアの構成を指定できる。この際に(1)変換対象にするディスク（≒ドライブ）の指定や、(2)変換後のディスクサイズも指定できる。

変換操作手順の詳細は、使用するバージョンに対応した[VMware vCenter Converter Standaloneのドキュメント](http://www.vmware.com/jp/support/support-resources/pubs/converter_pubs/)を参照すること。例えばConverter 5.5.2、および5.1.1のユーザーズガイドであれば、「Organize the Data to Be Copied on the Destination Machine」の項にこの手順が説明されている。

### その他の縮小方法

公式には、その他の縮小方法はない。前述のナレッジは、以下のようにConverterを使用する方法だけを挙げている。

> Virtual disk shrinking is supported in VMware Converter.
> Note: You cannot shrink virtual disks using vmkfstools in ESX 3.0.x at this time.

より直接的には、「[HOW TO: Shrink a VMware Virtual Machine Disk (VMDK) in 15 minutes](http://www.experts-exchange.com/Software/VMWare/A_12938-HOW-TO-Shrink-a-VMware-Virtual-Machine-Disk-VMDK-in-15-minutes.html)」が以下のように表現している（訳文は本投稿筆者）。

> However, although there is a down arrow present, you cannot shrink the disk in this way, it's not supported. The only supported method of shrinking a VMware virtual machine disk (VMDK) is to use VMware vCenter Converter Standalone and create a virtual to virtual (V2V) conversion, a similar process to a Physical to Virtual (P2V) conversion.

>（下向きの矢印はあるものの、この方法（仮想マシン編集画面からの仮想ディスクサイズ変更）ではディスクを縮小することはできない。これはサポートされていない。VMwareの仮想マシンディスク（VMDK）を縮小する唯一のサポートされた方法は、VMware vCenter Converter Standaloneを使って、物理から仮想への変換（P2V）と同様の手順で仮想から仮想へ変換（V2V）することだ。）

なお、Coverter自体は無償で利用できるツールだが、vCenterのライセンスおよびサポートを購入しているか、インシデント単位の有償サポートを購入すれば、VMware社のサポートも受けられる。一般に、業務システムの本番環境にも適用できるツールと見なせると思われる。

## 参考

* [VMware KB: Growing, thinning and shrinking virtual disks for VMware ESX and ESXi (1002019)](http://kb.vmware.com/kb/1002019)
* [HOW TO: Shrink a VMware Virtual Machine Disk (VMDK) in 15 minutes](http://www.experts-exchange.com/Software/VMWare/A_12938-HOW-TO-Shrink-a-VMware-Virtual-Machine-Disk-VMDK-in-15-minutes.html)
* [VMware vCenter Converter Standaloneのドキュメント](http://www.vmware.com/jp/support/support-resources/pubs/converter_pubs/)

本投稿内容も、本文中に説明しているように、上記参考先の情報に基づいて作成した。正確な情報が必要な場合には、必ずこれらの一次情報を確認すること。
Lessでつかっている細かすぎるMixinの記録

思いつきで追加していく。


## 画像URLのパス解決をする係のMixin

lessファイルとcssファイルが同じレベルの階層に保存してあれば、画像URLは相対パスでそのまま書いて大丈夫。なのだけど、lessファイル自体が多階層になっていて、子lessファイルがサブディレクトリに保存してあったりすると、画像のパス入力時にエディタのオートコンプリートの恩恵にあずかれない。

そこで、"../../img/" も "../../../img/" も "../img/" に置換してしまう係の人を用意した。

`````css
/**
 * @url: 画像の相対パス
 * @imageRoot: 画像ディレクトリへの相対パス
 */
.background-image(@url, @imageRoot: "../img"){
	@_url: `@{url}.replace(/^(\.\.\/)+img\//, @{imageRoot})`;
	background-image: e(%("url(%s)", @_url));
}

.foo {
	.background-image(../../../img/foo.png);
	// => background-image: url(../img/foo.png);
	.background-image(../../img/bar.png);
	// => background-image: url(../img/bar.png);
}
`````

## フォントサイズを相対的に調整する係のMixin

ピクセル指定をemにする為だけのMixin。

`````css
/**
 * @size: 指定したいフォントサイズ（px）
 * @baseSize: ベースとなるフォントサイズ
 * @point: 小数点以下桁数
 */
.font-size(@size, @baseSize: 16, @point: 2){
    @_size: round(@size / @baseSize, @point);
    font-size: e("@{_size}em");
}

.foo {
    .font-size(13, 16, 2);
    // => font-size: 0.81em;
    .font-size(24, 16, 4);
    // => font-size: 1.5em;
}
`````
VolleyのPOST

---
###下準備
・Volleyを取り込む
・PermissionでINTERNETを許可

###コード
```MyActivity.java
public class MyActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        //queue
        RequestQueue queue = Volley.newRequestQueue(this);

        //url
        final String url = "http://www.bluecode.jp/test/res.php";

        //Request
        StringRequest postRequest = new StringRequest(Request.Method.POST,url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String s) {
                        Log.v("tama","RESPONSE=" + s);
                    }
                },
                new Response.ErrorListener(){
                    @Override
                    public void onErrorResponse(VolleyError error){
                        //error
                    }
                }){
                    @Override
                    protected Map<String,String> getParams(){
                        Map<String,String> params = new HashMap<String,String>();
                            params.put("name","hoge");
                            params.put("age","44");
                        return params;
                    }
        };

        queue.add(postRequest);
    }
```
こんな感じ。
###参考
・[ここ](http://www.itsalif.info/content/android-volley-tutorial-http-get-post-put)シンプルな書き方
・[ここ](http://blog.zaq.ne.jp/oboe2uran/article/940/)分けた書き方
VolleyでのJSON処理　その２

---
###発展版
・サーバのコード（PHP）
・階層かつ配列のJSONを取得

###前提
・mysqlにtestdb->members tableがある。
・members tableにはnameとageというカラムがある。

###サーバ側
DBの値を取得して返す、典型例。

```json.php
<?php

	$dbh = new PDO("mysql:host=localhost;dbname=testdb","user","pass");

	$stmt = $dbh->prepare("SELECT * FROM members");
	$stmt->execute();
	
	//response用
	$response = array();

	//dbデータ格納用
	$db_data = array();

	foreach($stmt->fetchAll(PDO::FETCH_ASSOC) as $row){
		$db_data[] = array(
				'name'=>$row['name'],
				'age'=>$row['age']
			);
	}
	
	//responseの準備
	$response['status'] = "OK";
	$response['members'] = $db_data;

	//JSON出力
	header("Content-type: application/json; charset=UTF-8");
	echo json_encode($response);
```

###JSON
こういうのが返ります。よくあるパターン。

```sample.json
{
	"status":"OK",
	"members":[
				{"name":"hoge","age":"56"},
				{"name":"foo","age":"34"}
			]
}
```

###android側

###追記

なお、最新環境で下記のコードを実行すると「JsonObjectRequestの参照はあいまいです」的なエラーが出ます。
以前より、引数の型が厳しくなったようです（以下は修正済）。

>new JsonObjectRequest(Method.GET, url, null, 

のところを、

>new JsonObjectRequest(Method.GET, url, (String)null, 

とすることで回避できます。

```MyActivity.java
public class MyActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        //queue
        RequestQueue queue = Volley.newRequestQueue(this);

        //url
        String url = "http://www.bluecode.jp/test/json.php";

        //request生成
        JsonObjectRequest jsonRequest = new JsonObjectRequest(Request.Method.GET,url,(String)null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject jsonObject) {

                        //JSONの処理
                        try{

                            //１階層目は普通に
                            String status = jsonObject.getString("status");
                            //出力
                            Log.v("tama", "status=" + status);

                            //2階層目（配列）
                            JSONArray members = jsonObject.getJSONArray("members");
                            //ループ
                            for(int i=0;i<members.length();i++){

                                //JSONObjectとして１つ１つ取得
                                JSONObject member = members.getJSONObject(i);
									//明日を取得（ListViewとかに追加）
                                String name = member.getString("name");
                                String age = member.getString("age");

                                //出力
                                Log.v("tama","name=" + name);
                                Log.v("tama","age=" + age);
                            }

                        }catch(Exception e){
                            e.printStackTrace();
                        }

                    }
                },
                new Response.ErrorListener(){
                    @Override
                    public void onErrorResponse(VolleyError error){

                    }
                }
        );

        //Queueに追加
        queue.add(jsonRequest);
    }
}
```
FacebookとGoogleだけ、やたら遅い場合の対処


犯人は、フレッツ光です。(ということらしいです。2014年10月現在)

最近、IPv6対応サイトが増えて来た所為か、特定のサイトだけアクセスしにくくなるケースが増えています。「GitHubは普通に繋がるのに、なんでFacebookとGoogleに繋がらないの??」ということないですか? 「天下のGoogleがそんなにしょっちゅう落ちてる訳ない!」と思いつつも、「海外サイトが繋がらないのはプロバイダのIPがBANされてるのかな...」とか、「ルータの調子が悪くなることもあるよね」とかあきらめてませんか?

対策は簡単でした。フレッツ止めるか、「IPv6を使わない」こと。

- ブラウザのIPv6機能をオフにする
- OSレベルでIPv6の機能をオフにする

のどちらか。後者の方が確実ですが、AirDropが使えないとか、Bonjourが使えないとかの問題もあるので、ケースバイケースで。(業務用ルータであれば、他の手もあるはず。念のため)

![http---ipv6.whatismyipv6.com- is not available.png](https://qiita-image-store.s3.amazonaws.com/0/1858/4b9b06f0-a230-d640-dbab-32dd5524ccd9.png "http---ipv6.whatismyipv6.com- is not available.png")


## ブラウザのIPv6機能をオフにする

Chromeの場合、設定項目がないのですが、起動オプションを付けるとオフにできます。

```bash
$ /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --disable-ipv6
```

長ったらしいので、毎回使うならエイリアス設定を。

```bash
$ echo "alias chrome='/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --disable-ipv6'" >> ~/.profile
```


## OSレベルでIPv6の機能をオフにする

Mac OS 10.9 では、GUIからIPv6を切ることができないので、次のコマンドを実行します。

```bash
$ networksetup -setv6off Wi-Fi
```

これだけです。ちなみに、元に戻すときは、次のコマンド。

```bash
$ networksetup -setv6automatic Wi-Fi
```


## IPv6がオフになっているか確かめる

次のサイトにアクセスしてみましょう。

- http://ipv6.whatismyipv6.com/

即座に、"This webpage is not available"と表示されれば、設定成功です。


## まとめ

IPv6について、動作しない場合はIPv4にフォールバックされるはずと高をくくっていましたが、ルーティング途中のエラー要因が複数ある場合は、ブラウザのフォールバックが効かない、非常に遅いという事態がありえるようです。少し古いですが、[IETFの資料](http://www.ietf.org/proceedings/80/slides/v6ops-12.pdf)を参考に挙げておきます。フォールバックを並列で行う[Happy Eyeballs](http://tools.ietf.org/html/rfc6555)がRFCにありますが、[各社のブラウザの実装はまちまち](http://www.potaroo.net/ispcol/2012-05/notquite.html)。

この問題、数年前から指摘されていたものの、最近になってIPv6対応サイトが増えて顕在化して来たみたいですね。フレッツ光のルーティングがなんでこんなことになってるかは、[当時書かれたページ](http://www.geekpage.jp/blog/?id=2012/4/8/1)ほかに譲ります。


## 補足

[アップルからサポート情報](http://support.apple.com/kb/HT5656)を見る限り、IPv6の手動設定を行えば良いということのようですが、該当情報が手元の環境では[プロバイダから提供されてない](http://support.nifty.com/support/manual/internet/setvalue.htm?dial)ため、断念。[IPv6接続オプション](http://qa.nifty.com/cs/catalog/faq_nqa/qid_14076/1.htm)を申し込めば送られてくるのかしら...?


## 参考

- [BフレッツのIPv6アドレス割り当てに関する注意事項](https://flets.com/customer/ipv6_setting.html) (フレッツ公式見解)
- [一部のサイトだけ、表示が遅い、または表示できない場合](http://support.nifty.com/support/information/ipv6fuka.htm) - @nifty 会員サポート
- [World IPv6 LaunchとNTT IPv6閉域網を巡る駆け引き - DNSでのAAAAフィルタ](http://www.geekpage.jp/blog/?id=2012/4/8/1)
- [AirPort base station: IPv6 Tunnel Error after installing firmware 7.6.3 in router/NAT mode](http://support.apple.com/kb/HT5656)
- [Experiences of host behavior in broken IPv6 networks](http://www.ietf.org/proceedings/80/slides/v6ops-12.pdf) - IETF
- [List of Chromium Command Line Switches](http://peter.sh/experiments/chromium-command-line-switches/#disable-ipv6)
- [How to Disable IPv6 in Mac OS X](http://osxdaily.com/2014/04/18/disable-ipv6-mac-os-x/) - OSXDaily
apt-get upgradeとdist-upgradeの違い


```
$ sudo apt-get upgrade # パッケージ構成を変えない範囲でアップグレードする
$ sudo apt-get dist-upgrade # パッケージ構成の変更に追随してアップグレード
```

### Ubuntuのバージョンとカーネルのバージョンの対応表

|Version|CodeName|KernelVersion|
|:-----------|------------:|:------------:|
|12.04 LTS|	Precise	| 3.2     |
|12.10    |	Quantal| 3.5|
|13.04    |	Raring | 3.8|
|13.10    |	Saucy  | 3.11|
|14.04LTS |	Trusty |3.13|
Ubuntu Desktopの画面がフリーズしたときの対処法


Ctrl+Alt+F1キーを押して仮想コンソール(tty1)を起動する

* lightdmの再起動(Ubuntu 11.10以降:lightdm使用)

```
$ sudo service lightdm restart
```

* gdmの再起動(Ubuntu 11.04以前:gdm使用)

```
$ sudo service gdm restart
```

* 再起動

```
$ sudo reboot
```

* シャットダウン

```
$ sudo shutdown -h now
```
ISUCON4予選の問題で31万点を出すためにやったこと

[perlで36万点出してる記事](http://nihen.hatenablog.com/entry/2014/10/01/092938)があり、面白そうなのでできるところまでチューニングしてみることにした。
↑の記事のhtml minifyとかtcp fast openはやってない。なお、benchmarker-v2でスコアを計測している。

書いたコードは [k0kubun/isucon4-qualifier](https://github.com/k0kubun/isucon4-qualifier) においてある。

## Ruby
出場したチームメンバーが共通で書けるのがRubyなので、まずはRubyで解き直してみた。

|score|workload|やったこと|
|----:|:-------|:--------|
|1,385|1|Rubyの初期状態にNewRelicをいれた状態 |
|1,411|1|nginxとunicorn, アプリとmysqlの間をunix domain socketでつないだ|
|2,588|1|login_logに(user_id, succeeded)でインデックスを張る|
|7,116|1|login_logに(ip, succeeded)でインデックスを張る|
|10,263|1|静的ファイルをnginxで配信|
|26,667|15|workloadを上げるため、limits.confでファイルディスクリプタの上限を変える。sysctl.confでtcp_tw_recycleとtcp_fin_timeoutを小さくしてローカルポートが枯渇しないようにする。|
|28,055|15|innodb_buffer_pool_sizeを1Gにする|
|28,860|15|unicorn worker_processes 10 -> 4|
|29,229|15|なんかfailするのでnginxの各プロセスのファイルディスクリプタ上限(worker_rlimit_nofile)を4096にする|
|41,777|15|NewRelicを外す|
|42,433|10|nginxのworker_processes 1 -> 4|
|41,728|10|login_logの処理をRedisに載せ、usersはハッシュでメモリに載せる（なぜかスコアが上がらない…）|
|48,054|10|トップページへのリダイレクトでflashの種類ごとにquery stringを変え、nginxでトップページのhtmlを配信する|
|50,429|8|redisとの通信にunix domain socketを使う|
|123,958|8|img tagとcssのlink tagをscriptタグから追加するようにし(自身のタグを取り除く)、ベンチマークで静的ファイルにリクエストが飛ばないようにする。[元ネタ](http://d.hatena.ne.jp/sfujiwara/20140929/1411972115)|

この辺で飽きた。
アプリのコードに手をいれなくとも4万点行くので、4万点くらいなら1時間かけずにいけることになる。
Redisに載せる実装でスコアが上がらなかったのはなんか僕の実装がおかしいだけだと思う…


## Go
1人でやるなら最初からGoで取り組む気マンマンだったのであんまりRubyのほうは真剣にやってない。
ここからGoで解き直した。

### 戦略
オンメモリで作りたいが、「ベンチマーク実行時にアプリケーションに書き込まれたデータは、再起動後にも取得できること。」を違反しないように作らなければならない。

そのため、普通に起動するとmysqlにクエリを吐くモードで動作させ、init.shを叩いたらオンメモリで動作するベンチ用モードになるようにする。
このモードの間必要なデータはmap型変数に入れ、INSERTクエリはキューにためておいて/reportでjson書き出す直前でBULK INSERTする。これが終わったら通常のモードに戻す。

これにより、ベンチ中以外の任意のタイミングで再起動してもデータの整合性がとれる実装になる。
ベンチを実行中に異常終了して再起動するようなチェックは流石にないだろうという想定に基づいている。


|score|workload|やったこと|
|----:|:-------|:--------|
|23,875|9|OS, DBの設定やインデックスを少し引き継いだままGoの初期実装にいれかえた|
|33,181|9|nginxで静的ファイルを配信|
|90,072|9|scriptタグを使ってタグを挿入しベンチマーク時に静的ファイルにリクエストが飛ばないようにする|
|102,326|9|martiniをやめてginにする|
|115,306|9|ipのban判定をオンメモリで行う|
|126,098|9|login時のusersのSELECTをオンメモリに変える|
|144,124|9|userのlock判定をオンメモリで行う|
|163,962|9|ベンチのGOGCを上げる([元ネタ](http://dsas.blog.klab.org/archives/52171878.html))。currentUserをオンメモリに変える|
|170,140|9|LastLoginをオンメモリで取得する|
|213,948|9|INSERTを/reportでまとめて発行するようにし、ベンチ実行中のINSERTの発行をやめる|
|241,866|9|トップページをginで処理(query stringで分岐して文字列を返す)できるようにする。nginxをstopしginで80番を受ける。|
|271,130|10|mypageをtemplateではなくfmt.Sprintfで処理するようにする|
|315,232|15|gin.Default()ではなくgin.New()を使い、ログを書き出すミドルウェア等を外す|

RubyでデータをRedisに乗っけてたときはスコアがなぜか上がらなくて辛かったが、こっちは毎度順調に上がってよかった。
RubyでもRedisじゃなくて普通にHashでメモリに乗せればよかったかもしれない。

## RubyとGoで実装してみた感想
Goだと最終的にワンバイナリで全て受けられるようにできるのは大きいと思う。
Rubyで書くとタイムアウトするやつがGoだと普通にすぐ終わったりするし、Rubyだとどうしても1ms切れないやつがGoだと数十μsで返ったりするので、これくらい単純な予選の問題だと結構言語が重要になるかもしれない。
Androidアプリ環境構築メモ

Androidアプリ開発を始めようと思い、とりあえず環境構築をしたのでそのメモ。

# 使用する開発ツールとバージョン
**Java Development Kit (JDK) 6.0 (Java SE 6 Updte 43)**
  http://www.oracle.com/technetwork/java/javase/downloads/index.html

**Eclipse 4.2 Juno Pleiades All in One**
http://mergedoc.sourceforge.jp/

**Android SDK (installer_r21.1-windows.exe)**
http://developer.android.com/sdk/index.html

**Android Development Tools (ADT)**
Eclipse起動→[ヘルプ(H)]→[新規ソフトウェアのインストール]→[追加(A)]→
ロケーションに「https://dl-ssl.google.com/android/eclipse/」 と入力→[OK]→
[開発ツール]をチェック→[次へ]
vim-coffee-scriptを使うときの.vimrc

#vim-coffee-scriptを使う際の.vimrc設定
- https://github.com/kchmck/vim-coffee-script
- 上記Vimプラグインを使う際の`.vimrc`設定方法
- [こちらの記事](http://qiita.com/alpaca_taichou/items/fb442cfa78f91634cfaa)は古いためか、そのままの設定ではエラーが起きるため、Github上のReadmeを参考し、改修した


##必要条件
- vim 7.4　以降
- coffeescript 1.2.0　以降

##インストール方法（NeoBundle）
1. 下記を.vimrcに追記する

```vim

Bundle 'kchmck/vim-coffee-script'
```
2. vim内コマンドモードで下記コマンドを実行する

```vim

:BundleInstall
```


##.vimrc
```vim

Bundle 'kchmck/vim-coffee-script'

" vimにcoffeeファイルタイプを認識させる

au BufRead,BufNewFile,BufReadPre *.coffee   set filetype=coffee
" インデント設定
autocmd FileType coffee    setlocal sw=2 sts=2 ts=2 et
" オートコンパイル
  "保存と同時にコンパイルする
autocmd BufWritePost *.coffee silent make! 
  "エラーがあったら別ウィンドウで表示
autocmd QuickFixCmdPost * nested cwindow | redraw! 
" Ctrl-cで右ウィンドウにコンパイル結果を一時表示する
nnoremap <silent> <C-C> :CoffeeCompile vert <CR><C-w>h

```

##参考文書
- https://github.com/kchmck/vim-coffee-script
npm ERR! peerinvalid The package generator-karma does not satisfy its siblings' peerDependencies 



# 問題
express-generatorを入れようとしたら

```
$ npm install -g express-generator
```

下記のようなエラーがでた

```
npm ERR! peerinvalid The package generator-karma does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer generator-angular@0.9.2 wants generator-karma@>=0.8.2
npm ERR! peerinvalid Peer generator-angularexpress@0.0.5 wants generator-karma@~0.6.0

npm ERR! System Darwin 13.4.0

npm ERR! node -v v0.10.32
npm ERR! npm -v 1.4.28
npm ERR! code EPEERINVALID
npm ERR!
npm ERR! Additional logging details can be found in:

npm ERR! not ok code 0

```

依存するgenerator-karmaのバージョンが古いようです

# 対応

generator-karmaを消して

```
$ npm uninstall -g generator-karma
unbuild generator-karma@0.8.3
```

再実行で入れ直します

```
$ npm install -g express-generator
~/.npm-packages/bin/express -> ~/.npm-packages/lib/node_modules/express-generator/bin/express
express-generator@4.9.0 ~/.npm-packages/lib/node_modules/express-generator
├── commander@1.3.2 (keypress@0.1.0)
└── mkdirp@0.5.0 (minimist@0.0.8)
```	

ok!

[参考](https://github.com/yeoman/generator-karma)
Supervisor を利用して Go アプリケーションをデーモン化する


## 環境
Amazon Linux

## Supervisor をインストールする

Amazon Linux の場合、既に easy_install がインストールされている。

```
sudo easy_install supervisor
```

## 開発した Go アプリケーションをデプロイする

手順はお好きなように。
後述の設定ファイルに起動コマンドを指定するため、`go build` はしておくこと。

## Supervisor の設定ファイルを作成する

`/etc/supervisord.conf` に Supervisor 自身の設定と、
開発した Go アプリケーションの設定を記述する。


※ 設定内容については以下のサイトを参考にさせて頂きました
https://github.com/astaxie/build-web-application-with-golang/blob/master/ja/ebook/12.3.md

```
;/etc/supervisord.conf
[unix_http_server]
file = /tmp/supervisor.sock
chmod = 0777
chown= root:root

[inet_http_server]
port=9001
username = admin
password = yourpassword

[supervisorctl]
serverurl = unix:///tmp/supervisor.sock

[supervisord]
logfile=/var/log/supervisord/supervisord.log
logfile_maxbytes=50MB
logfile_backups=10
loglevel=info
pidfile=/var/run/supervisord.pid
nodaemon=true
minfds=1024
minprocs=200
user=root
childlogdir=/var/log/supervisord/

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

; 自分が開発したアプリケーションの設定
[program:yourapp]
command=/path-to-path/yourappname
autostart = true
startsecs = 5
user = root
redirect_stderr = true
stdout_logfile = /var/log/supervisord/blogdemon.log
```

## Supervisor を起動

`supervisord` を叩いて Supervisor を起動する。

```
supervisord
```

正常に起動すると、以下の様なログが出力される。
以降は `supervisorctl` で起動・停止等の操作を行うことができるようになる。

```
2014-10-05 15:11:27,197 CRIT Set uid to user 0
2014-10-05 15:11:27,206 INFO RPC interface 'supervisor' initialized
2014-10-05 15:11:27,207 INFO RPC interface 'supervisor' initialized
2014-10-05 15:11:27,207 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2014-10-05 15:11:27,207 INFO supervisord started with pid 23899
2014-10-05 15:11:28,209 INFO spawned: 'yourappname' with pid 23902
2014-10-05 15:11:33,225 INFO success: yourappname entered RUNNING state, process has stayed up for > than 5 seconds (startsecs)
```

## Supervisor の自動起動設定

```
git clone git://github.com/Supervisor/initscripts.git
cd initscripts/
cp redhat-init-jkoppe /etc/init.d/supervisord
cp redhat-sysconfig-jkoppe /etc/sysconfig/supervisord
chkconfig --add supervisord
chkconfig supervisord on
```
スレッドセーフについて


備忘録的投稿です。

## std::mapの利用でスレッドセーフを犯していた
mapへの要素の追加\[\]=、削除erase()については最低限mutexを使っていたが、
当然のことながら、同時に起こりうる読み込み操作においてもmutexを使用しないといけない。


## 書き込みは稀で、ほとんどが読み込みなんですけど...
全て読み込み操作ならば、スレッドセーフ。
１００回中、９９回が読み込みで１回が書き込みのような場合、
この「１回」のためにmutexを使わないといけないのはばかばかしい。

こういう細かい対応については、ライブラリに頼らず自分で実装したほうがよい。
例えば、要素のインデックスを管理するものと、要素をそれぞれ別のオブジェクトとして作る。
追加、削除に関してのみ管理オブジェクトをmutexを使って変更すればよい。
**ある要素のポインタ（アドレス）が他の要素が追加されようが削除されようが不変なら**各スレッド間でその要素を自由に読んでよいし、さらに
**要素が１つのスレッドからしかアクセスされないならば**、mutexを使わずに値を変更してもよい。

## 結論

結局の所、この辺の最適化はケースバイケースであってこれといった正解はない。
とにかく、実装がわからないものに対してはスレッドセーフを忠実に守るようなコードを書かなくてはいけないというのが本日の教訓。
Linux OOM Killerについて

#### OOMとは?
Linuxは、メモリが不足してシステムが停止する恐れがある際、メモリリソースを多く消費しているプロセスを強制的に殺します。これをOOM Killerといいます。重要なプロセスでも問答無用で殺しにきます。

いるはずのプロセスがある日消えていたのなら、それはOOM Killerに殺されたのかもしれません

#### 確認方法(CentOS)

5789のrubyのプロセスが殺されたことが分かります

```
$ sudo cat /var/log/messages | grep Killed
Oct  1 11:11:54 ip-xx-xx-xx-xx kernel: [1983378.957901] Killed process 5789 (ruby) total-vm:4957320kB, anon-rss:2717004kB, file-rss:0kB

```

Ubuntuなら/var/log/syslog

#### 殺される可能性の高いプロセス
dstatの--top-oomオプションで簡単に候補を確認できます
これは/proc/PID/oom_scoreを見ています

```
$ dstat --top-oom
--out-of-memory---
    kill score
mysqld        484
mysqld        484
mysqld        484

```


#### 対応策
mysqldとかを殺されるとさすがに困るので、強制終了するプロセスの優先度を決めることもできます

/proc/PID/oom_adjに（優先度低）-16から+15（優先度高）の値を設定することで優先度を設定できます

また、-17を設定するとOOM Killerの対象外になります

```
$ cat /proc/3333/oom_score 
2000

$ echo -4 > /proc/3333/oom_adj
	
$ cat /proc/3333/oom_score
100
```

#### 参考図書

[Linuxカーネル Hacks ―パフォーマンス改善、開発効率向上、省電力化のためのテクニック](http://www.amazon.co.jp/gp/product/4873115019?tag=konpyuamz0a-22)
rsyncで擬似TimeMachineを構築

# はじめに

TimeMachineはMacのデータをHDDにバックアップしてくれますが、別々のTimeMachineを個別に運用する事はできません。例えば「iTunes や iPhoto は HDD-A」「開発フォルダは HDD-B」「ホームディレクトリは HDD-C」といった運用です。TimeMachineに紐づいたHDD自体は複数存在出来ますが、TimeMachineとして複数存在する事は出来ません。
特にiTunesのようなデータは容量が膨大なので、通常のTimeMachineとは分離して運用したいところです。

そこで、rsync コマンドを使ってこれをどうにかしてみようと思います。


# rsync

単純にコピーを生成しますが、オプションにより挙動が変わります。SSHを使ってリモート経由でバックアップすることも可能ですが、今回は外付けHDDに対してコピーを作ることを前提とします。

```shell-session
$ rsync -auE --delete <バックアップ元ディレクトリ/> <バックアップ先ディレクトリ/>
```

|オプション|意味|
|---|---|
|-a, --archive|基本オプション詰め合わせ (-rlptgoD)|
|-u|更新されたファイル、ディレクトリのみをコピー|
|-E|拡張属性を維持。リソースフォークもコピー。Finderの属性などを残したい場合はこれ|
|-r|再帰的にコピー|
|-l|シンボリックリンクをそのまま維持|
|-p|パーミッションを維持|
|-t|タイムスタンプを維持|
|-g|グループを維持|
|-o|オーナーを維持|
|-D|特殊なファイルをコピー|
|-n, --dry-run|実際に変更は行わず、結果の出力だけ行う|
|--delete|元にない、あるいは削除されたファイルを先でも削除。つまり同期する|
|--link-dest=|変更が無いファイルのハードリンクを作成|

--delete オプションやディレクトリを/で閉じるか閉じないかは割と鬼門のようなので、使用には気をつけるべきです。

詳しい説明は省きます。


# TimeMachine風スクリプト

同じ事を考えている人はいるもので、探してみると目的にあったスクリプトを公開してくれている人が見つかります。どちらも --hard-link オプションでハードリンクを生成することにより最低限の容量しか消費しないようになっています。また、バックアップ時点のフォルダを作るので、スナップショット的に運用する事も可能になっています。
今回は rsync-time-machine を少し改造して使う事にしました。

## rsync-time-machine
https://github.com/samdoran/rsync-time-machine

## rsync-time-backup
https://github.com/laurent22/rsync-time-backup


# rsync-time-machineを改造する

rsync-time-machineは記事執筆時点では引数で入力を取ってくれません。ディレクトリパスの指定はスクリプトを書き換えろとのことです。これだと少々面倒なので改造してみます。

## Finder属性を維持する

-E を追加して、Finderの「ラベル」や「属性」を維持するようにします。

```shell-session
RSYNC_OPTIONS="-auE --partial --progress --human-readable"
```

## 引数を取れるようにする

```shell-session
# 引数1, バックアップもとディレクトリ
SOURCE="${1%/}"
# 引数2, バックアップ先ディレクトリ
DESTINATION="${2%/}/$HOST"
# 引数3, 除外定義ファイル. 未指定でも可（新規追加）
EXCLUDEDFILES="${3%/}"
```

```shell-session
# --exclude-from=$SOURCE/.rsync/exclude \
--exclude-from=$EXCLUDEDFILES \
```

第3引数で除外設定ファイルを指定するようにしてみました。


# 運用

とりあえずいまは手動でいいので適当なところにスクリプトファイルを置いて、適当なときに実行します。

```
sh rsync-time-machine.sh /Volumes/HDDA/iTunes/ /Volumes/HDDB/bk_iTunes/
```

実行する度にフォルダが作られ、変更が無いファイルはハードリンクが設定されます。一見、同一ファイルの複製が大量に作られているようにも見えますが、それはたんなるリンクで実態は同じです。これでバックアップ先の容量も節約出来ます。
必要に応じて自動化も検討してみたいと思います。

![list.png](https://qiita-image-store.s3.amazonaws.com/0/3603/01ce494f-ef4b-cfb7-fb83-c87714a627ba.png)


# 資料

http://samdoran.com/2013/04/09/rsync-time-machine/
http://news.mynavi.jp/column/osxhack/044/
Pythonでシェルのコマンドを実行する


シェルコマンドを利用したスクリプトを書くときってみなさんはどうしてるんですかね？
僕はPHPerなんで、phpで書きたくなるんですが今回はPythonで遊んでみました。


Pythonにはどうやらshってライブラリがあるらしくてそれを今回は利用してみました。

- sh https://github.com/amoffat/sh


``` shtest.py
# -*- coding: utf-8 -*-
from sh import ls
from sh import sort
from sh import cat
from sh import cd


cd("./texts")
ls1 = ls.bake('-1')

# ls -1
print(ls1())
# 実行結果
# mike_oldfiled.txt
# miles_davis.txt
# pink_floyd.txt

# ls -1 | sort -rを実行
contents = map(lambda (i,f): "(%d)%s: %s"%(i+1,f.strip().rjust(20),cat(f.strip()).strip()),enumerate(sort(ls1(),'-r')))
for content in contents:
  print content

# [実行結果]
# (1)      pink_floyd.txt: Echoes(16:31)
# (2)     miles_davis.txt: So What(9:08)
# (3)   mike_oldfiled.txt: Amarok(1:00:03)

```

気軽にshel使えるところがいいですね。
bakeとかでオプション最初から設定出来るし。

基本的に書きやすいしいいんだけど、lamdbaが1行ってのはつらいお・・・
Redisコマンド覚え書き

ホスト（-h）・ポート（-p）指定・マルチバイト対応（--raw）で接続
`redis-cli -h xxx.xxx.xxx.xxx -p 6380 --raw`

データベースの1番を指定して接続
`redis-cli -n 1`

**以降のコマンドはredis-cliで接続中の場合はredis-cliは不要**

有効期限を確認
`redis-cli ttl [key]`

有効期限付きで登録
`redis-cli setex [key] [ttl(sec)] [value]`

有効期限なしで登録
`redis-cli set [key] [value]`
Pythonの仮想環境を構築できるvirtualenvを使ってみる


virtualenvはPythonの仮想的な環境を作ることができるパッケージ。
プロジェクトごとにPythonのバージョンを変えたり、必要なパッケージを分けてインストールして動かす事ができるようになります。

##インストール
###virtualenvをインストールする
```console
$ sudo easy_install virtualenv
```

```text
・・・
Installed /Library/Python/2.7/site-packages/virtualenv-1.11.6-py2.7.egg
Processing dependencies for virtualenv
Finished processing dependencies for virtualenv
$
```
このようなログが出たら成功。

##使い方
###仮想環境 作成
プロジェクトのディレクトリを作る。

```console
$ mkdir PythonTest
```

virtualenvコマンドを実行

```console
$ virtualenv --no-site-packages PythonTest
```
```text
New python executable in PythonTest/bin/python
Installing setuptools, pip...done.
$
```
成功するとこのようなログが出ます。
これで仮想環境が作成されます。
###仮想環境 起動

作成したディレクトリ内のbin/activateに対してsourceコマンドを実行すると、仮想環境を利用することができます。

```console
$ cd PythonTest
$ source bin/activate
```
```console
(PythonTest)%
```
仮想環境を起動できた場合、上記のような **(ディレクトリ名)%**というコンソールが起動します。必要なパッケージのインストールなどはこのコンソールで行います。

###仮想環境 終了
```console
(PythonTest)% deactivate                                                         
%
```
**deactivate**と入力することで、仮想環境を終了することができます。

###パッケージのインストール
```console
(PythonTest)% pip install パッケージ
```
Ruby | 「ツー」といえば「カー」と返す Aun gem に原典フィルタ機能追加(ver 0.0.2) #ruby #aun

# Ruby | 「ツー」といえば「カー」と返す Aun gem に原典フィルタ機能追加(ver 0.0.2)
## 概要
Ruby | 「ツー」といえば「カー」と返す Aun gem に原典フィルタ機能追加(ver 0.0.2)

## Aun gem って何？という方は
まずはこちらを御覧ください。
[Ruby | Aun | 阿吽の呼吸。「ツー」といえば「カー」など A に呼応して B のメッセージを返却するための Aun gem を作成（出来心。用途なし） #ruby #aun](http://qiita.com/tbpgr/items/6da52d3a18ecc82402fd)

## 追加仕様
### origin でのフィルタ
任意の原典のみを対象にする。
複数原典に同じ阿吽のキー（阿）があった場合に対応するため、原典によるフィルタを追加。
CLIは未対応。
CLIは、DSLを用意しようかと思ってます。

## サンプルコード

デフォルトメッセージの中に、阿吽の阿のキーが重複しているものを登録しました。
原典を絞らない場合、どちらかがランダムに出力されます。
原典を絞れば任意の原典のみ出力されます。

~~~ruby
      Message.new('ゆ・・・ゆるさん・・・', 'ぜったいにゆるさんぞ虫ケラども!!!', owner: 'フリーザ', origin: 'ドラゴンボール'),
      Message.new('ゆ・・・ゆるさん・・・', 'ぜったいにゆるさんぞ虫ケラども!!!', owner: '山田 太郎', origin: '珍遊記')
~~~

~~~ruby
require 'aun_core'

finder = Aun::Finder.new
print finder.talk_with_origin('ゆ・・・ゆるさん・・・'), "\n"
print finder.talk_with_origin('ゆ・・・ゆるさん・・・'), "\n"
print finder.talk_with_origin('ゆ・・・ゆるさん・・・'), "\n"
print finder.inspect_all, "\n"

puts "!!! ver 0.0.2. 原典フィルタ !!!"
print finder.talk_with_origin('ゆ・・・ゆるさん・・・', 'ドラゴンボール'), "\n"
print finder.talk_with_origin('ゆ・・・ゆるさん・・・', 'ドラゴンボール'), "\n"
print finder.talk_with_origin('ゆ・・・ゆるさん・・・', 'ドラゴンボール'), "\n"

print finder.inspect_all('ドラゴンボール'), "\n"
~~~

## 出力

~~~
山田 太郎「ぜったいにゆるさんぞ虫ケラども!!!」 from [珍遊記]
山田 太郎「ぜったいにゆるさんぞ虫ケラども!!!」 from [珍遊記]
フリーザ「ぜったいにゆるさんぞ虫ケラども!!!」 from [ドラゴンボール]
阿:君名前は？ 吽:田原年彦  発言者:田原年彦  原典:行け!稲中卓球部,  ユーザー定義:false
阿:山 吽:川 発言者:unknown 原典:unknown, ユーザー定義:false
阿:ぬるぽ 吽:ガッ  発言者:unknown 原典:unknown, ユーザー定義:false
阿:もうおわりだ  吽:戸棚のウラはネズミの卵でいっぱいだー！ 発言者:二階堂昭夫 原典:動物のお医者さん,  ユーザー定義:false
阿:オス  吽:オラ悟空  発言者:孫悟空 原典:ドラゴンボール, ユーザー定義:false
阿:今度は木っ端微塵にしてやる。あの地球人のように 吽:クリリンのことか───────っ!!!!! 発言者:孫悟空 原典:ドラゴンボール, ユーザー定義:false
阿:ゆ・・・ゆるさん・・・ 吽:ぜったいにゆるさんぞ虫ケラども!!!  発言者:フリーザ  原典:ドラゴンボール, ユーザー定義:false
阿:ゆ・・・ゆるさん・・・ 吽:ぜったいにゆるさんぞ虫ケラども!!!  発言者:山田 太郎 原典:珍遊記, ユーザー定義:false
!!! ver 0.0.2. 原典フィルタ !!!
フリーザ「ぜったいにゆるさんぞ虫ケラども!!!」 from [ドラゴンボール]
フリーザ「ぜったいにゆるさんぞ虫ケラども!!!」 from [ドラゴンボール]
フリーザ「ぜったいにゆるさんぞ虫ケラども!!!」 from [ドラゴンボール]
阿:オス  吽:オラ悟空  発言者:孫悟空 原典:ドラゴンボール, ユーザー定義:false
阿:今度は木っ端微塵にしてやる。あの地球人のように 吽:クリリンのことか───────っ!!!!! 発言者:孫悟空 原典:ドラゴンボール, ユーザー定義:false
阿:ゆ・・・ゆるさん・・・ 吽:ぜったいにゆるさんぞ虫ケラども!!!  発言者:フリーザ  原典:ドラゴンボール, ユーザー定義:false
~~~

## 参照
[Ruby | Aun | 阿吽の呼吸。「ツー」といえば「カー」など A に呼応して B のメッセージを返却するための Aun gem を作成（出来心。用途なし） #ruby #aun](http://qiita.com/tbpgr/items/6da52d3a18ecc82402fd)
[Aun GitHub](https://github.com/tbpgr/aun)
[Aun RubyGems](http://rubygems.org/gems/aun)
三種類の境界線


準備段階のほうが長いってどういうことだろう。とりあえず、面倒だった。

```rb:hena26.rb
#!/usr/bin/env ruby
#http://qiita.com/Nabetani/items/8a973a47633558f54ba8
#http://nabetani.sakura.ne.jp/hena/ord26tribo/

#赤線=[0,1]
#緑線=[1,0]
#青線=[-1,1]
A=('a'..'y').map{|e|
	t_col=e.ord-'a'.ord+1
	row=1
	row_cells=1
	while t_col>row_cells
		t_col-=row_cells
		row+=1
		row_cells=row*2-1
	end
	row=row #-1
	col=t_col-1
	f=col%2
	col/=2
	#終点の座標
	f==0 ?
		[[row-col-1,col+1],[row-col,col],[row-col-1,col+1]] :
		[[row-col-1,col+1],[row-(col+1),col+1],[(row-1)-col-1,col+1]]
}

if $0==__FILE__
	STDOUT.sync=true
	while gets
		idxes=$_.chomp.split('').map{|e|e.ord-'a'.ord}
		puts A.each_with_index.select{|e,i|idxes.include?(i)}.map(&:first).transpose.map{|e|
			h=Hash.new(0)
			e.each{|f|h[f]+=1}
			h.count{|k,v|v==1}
		}*','
	end
end
```
ClojureからMacの通知センターを利用する

なんていうか
http://qiita.com/manuluu/items/cfba3e7734036e389768
見て試しただけです。

```clj:notification.clj
(use '[clojure.java.shell :only [sh]])
(sh "osascript" "-e" "display notification \"FScoward\" with title \"通知\" subtitle \"サブタイトル\"")
```

LightTableでInstarepl立ち上げて試してるとチョイチョイ出てきて~~ウゼェ~~簡単に確認できる！
cocos2d-x 3.2 のプロジェクト作成〜iOS版リリース〜Android版リリースまでの流れ


cocos2d-xでゲームを作成してリリースするまでの流れをまとめます。

1.プロジェクトの作成
2.Xcodeでプログラミング
3.iOS版のリリース
4.Eclipseでapkファイルをエクスポート
5.Android版のリリース

ちなみに、現在の私の開発環境はこのようになっています。

||バージョン|
|:---|:---|
|OS X|10.9.5|
|cocos2d-x|v3.2|
|Xcode|6.0.1|
|Eclipse|4.2.1|

# 1.プロジェクトの作成

cocosコマンドでプロジェクトを作成します。

```Bash:プロジェクトの作成
$ cocos new MyGame -p edu.self.sample -l cpp -d ~/Desktop/Products/
$ cd ~/Desktop/Products/MyGame
$ git init
$ git add .
$ git commit -m 'initial commit'
```

上記の例のようにしてプロジェクトを作成すると、~/Desktop/Products/MyGameフォルダにファイルがいろいろ作成されます。
gitでソースコードの履歴を見れるようにしておきます。

# 2.Xcodeでプログラミング

Xcodeを使ってプログラミングしていきます。
Xcodeのプロジェクトは、proj.ios_macフォルダに入っています。
上記の例ですと、~/Desktop/Products/MyGame/proj.ios_mac/MyGame.xcodeprojファイルになります。

# 3.iOS版のリリース

XcodeでTARGETS->Generalの Version と Build に適切な値を入れます。
リジェクトされて再提出する場合は、Buildを一つ上げてアップロードし直します。

||内容|
|:---|:---|
|Version|ユーザが目にするリリースバージョンです。例：1.0|
|Build|iTunesで管理するビルドバージョンです。例：1.0.0|

iTunesにアップロードするときは、XcodeでiOS Deviceを選択しProduct->Archiveを実行します。

このあたりのリリースで必要な作業はこちらのページが参考になります。

http://amarron.hatenablog.com/entry/2014/02/12/152505

http://www.tamurasouko.com/?p=1354

# 4.Eclipseでapkファイルをエクスポート

Eclipseにcocos2d-xのプロジェクトを読み込みます。
File->New->Project...でAndroid->Android Project from Existing Codeで下記のようにandroidプロジェクトを読み込みます。
上記の例で行きますと、こちらの2つのプロジェクトになります。

* ~/Desktop/Products/MyGame/cocos2d/cocos/platform/android/java
* ~/Desktop/Products/MyGame/proj.android

何かエラーが出る場合は、NDK_ROOTとかの環境変数の設定が必要になります。

この辺は、いろいろいじっていましたので、どれが正解か覚えていません。

下記のページなどを参考にしてビルドできるようにしてみてください。
Eclipseは私にとっては敷居が高いようです。

http://dev.classmethod.jp/smartphone/cocos2d-x-3-build-eclipse/

### Classesフォルダに入っているcppファイルをビルドに自動的に追加する

```:Android.mk
(変更前)
LOCAL_SRC_FILES := hellocpp/main.cpp \
                   ../../Classes/AppDelegate.cpp \
                   ../../Classes/HelloWorldScene.cpp

(変更後)
CPP_FILES := $(shell find $(LOCAL_PATH)/../../Classes -name *.cpp)
LOCAL_SRC_FILES := hellocpp/main.cpp
LOCAL_SRC_FILES += $(CPP_FILES:$(LOCAL_PATH)/%=%)
```

### その他変更点

```:Application.mk
(アプリが強制終了してしまう場合は、追加してみる)
APP_ABI := armeabi armeabi-v7a x86
```

### apkファイルのエクスポート

AndroidManifest.xmlファイルのversionCodeとversionNameを適切な値に設定します。

||内容|
|:---|:---|
|versionCode|Google Playで管理する番号になります。1から順番に値を大きくしていけばいいです。例：1|
|versionName|ユーザが目にするバージョン番号です。例：1.0|


File->Export...からExport Android Applicationを選択後、keystoreを作成し、apkファイルをエクスポートします。
2回目以降は、keystoreファイルを使い回せます。

# 5.Android版のリリース

Google Playでリリースする方法は下記のページを参考にしてください。

http://dev.classmethod.jp/smartphone/android/android-app-how-to-release/

http://techacademy.jp/magazine/2255

以上
sd_notifyの通信方法

systemdのマネージャ(デーモンプロセス)は、起動プロセスの最後の方で[`sd_notify`](http://www.freedesktop.org/software/systemd/man/sd_notify.html)という関数を用いて、起動が完了したことをsystemd本体(PID=1)に通知する。(注：`sd_notify`は実際にはもっと汎用的なステータス通知に使える。)

マネージャとsystemdとの通信方法には、抽象名前空間を用いるUnixドメインソケットが使用される。このソケットは、[unix(7)](http://man7.org/linux/man-pages/man7/unix.7.html)にある通り、ファイルシステムを用いないLinux独自のUnixドメインソケットのことである。ファイルパスの先頭を`\0`にすることで作成できる。

systemdは`sd_notify`のために`/org/freedesktop/systemd1/notify`という名前のソケットを作成する。マネージャには`NOTIFY_SOCKET`という環境変数を通して、この名前を伝える。

systemdが動いているマシン上で`netstat --protocol=unix |grep systemd`などとするとソケットが確認できるはずである。

```shell-session
$ netstat --protocol=unix |grep systemd
unix  2      [ ]         DGRAM                    8979     /run/systemd/shutdownd
unix  2      [ ]         DGRAM                    35790    @/org/freedesktop/systemd1/notify
unix  5      [ ]         DGRAM                    1197     /run/systemd/journal/socket
unix  2      [ ]         DGRAM                    8939     /run/systemd/journal/syslog
unix  3      [ ]         STREAM     CONNECTED     13547    /run/systemd/journal/stdout
unix  3      [ ]         STREAM     CONNECTED     13553    /run/systemd/journal/stdout
unix  3      [ ]         STREAM     CONNECTED     12938    /run/systemd/journal/stdout
unix  3      [ ]         STREAM     CONNECTED     13555    /run/systemd/journal/stdout
unix  3      [ ]         STREAM     CONNECTED     13591    /run/systemd/journal/stdout
unix  3      [ ]         STREAM     CONNECTED     13554    /run/systemd/journal/stdout
unix  3      [ ]         STREAM     CONNECTED     13999    /run/systemd/journal/stdout
unix  3      [ ]         STREAM     CONNECTED     13565    /run/systemd/journal/stdout

```

また適当なマネージャの環境変数を見てみると`NOTIFY_SOCKET`が設定されているのが分かる。

```shell-session
$ sudo cat /proc/$(pidof systemd-journald)/environ |tr -s '\0' '\n'
BOOT_IMAGE=/vmlinuz-3.14.17-100.fc19.x86_64
LANG=en_US.UTF-8
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
NOTIFY_SOCKET=@/org/freedesktop/systemd1/notify
LISTEN_PID=170
LISTEN_FDS=3
```
Ansibleでユーザを追加


* `/etc/sudoers` の更新をミスると `sudo` できなくなるので rollback の準備をしてからやる


## 使用するモジュール

* ユーザの追加: [user](http://docs.ansible.com/user_module.html)
* sudoユーザの追加: [lineinfile](http://docs.ansible.com/lineinfile_module.html)


## パスワード生成

生パスワードは使えないので以下で変換する。

```bash
openssl passwd -salt hoge -1 fuga
```


## 設定ファイル

```:hosts
[target]
192.168.43.52
```

```ansible.cfg
[defaults]
hostfile = ./hosts
```

```playbook.yml
---
- hosts: all
  sudo: true
  vars:
    password: ****
  tasks:
    - name: add a new user
      user: name=kiarina password={{password}} state=present
    - name: add a sudo user
      lineinfile: "dest=/etc/sudoers backup=yes state=present regexp='^kiarina' line='kiarina ALL=(ALL) NOPASSWD: ALL'"
```


## 実行

```bash
ansible-playbook playbook.yml
```


## 参考

* [ansibleでsudo可能なユーザを追加する](http://qiita.com/suin/items/155ca2b98c485935db1b)
* [sudo可能なユーザ追加: lineinfile](https://u.osu.edu/hasnan.1/2013/11/22/ansible-add-a-new-user-as-sudoers/)
* [Ansibleのツボ](http://inforno.net/articles/2013/10/15/ansible-tips)
nginxのログ出力変更

# Webサーバ、nginx
nginxのaccess.log。デフォルトだと、POSTされたデータのMessageBodyが出力されない…。
何がPOSTされたのか見たい！ということがあったので、調べてみた。

## 設定ファイルの場所
/etc/nginx/nginx.conf

## ログファイルの場所
/var/log/nginx/access.log

## 設定ファイル変更！
設定ファイル内のhttpコンテキストを変更します。
設定ファイルの中身は以下のURLを参考にさせていただきました。
[参考URL](http://heartbeats.jp/hbblog/2012/02/nginx03.html)

```
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    tcp_nopush     on;
    keepalive_timeout  65;
    gzip  on;
    include /etc/nginx/conf.d/*.conf;
}
```

この中の、
log_formatディレクティブが、ログの出力フォーマットを定義しています。
ので、この定義に、ちょちょいと。

```
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" "$request_body"';
```

最後に**"$request_body"**を追記するのみ。
(ログの最初に出力したい場合は、ディレクティブの先頭に追記する)

## nginx再起動
設定を変更した後は、nginxを再起動。

service nginx stop
service nginx start

すると、上記で書いた場所のaccess.logに、POSTされたデータのMessageBodyが出力されるようになります。