OmniAICreator/Qiita-1.07M huggingface dataset:
RubyでLinuxコマンドの再実装(tree編)


Rubyの勉強にRubyで有名ドコロのLinuxコマンドたちを再実装してみたいとおもいます。

少しずつ追記する形にできればと思っています。よりよい実装方法などありましたらぜひご教授いただけると幸いです。

[RubyでLinuxコマンドの再実装(ls編) - Qiita](http://qiita.com/agatan/items/af0c3bbc881f60667c85)
[RubyでLinuxコマンドの再実装(tree編) - Qiita](http://qiita.com/agatan/items/4c50554ae22aa4181cc1)

## tree
`tree`コマンドに挑戦します。
`tree`コマンドは, 指定したディレクトリ以下のファイルを木構造にして表示してくれます。

![スクリーンショット 2014-10-16 16.16.08.png](https://qiita-image-store.s3.amazonaws.com/0/39030/b3ca62be-bc22-ec39-a836-70032b76521d.png "スクリーンショット 2014-10-16 16.16.08.png")

```tree.rb
#! /usr/bin/env ruby -w
#
# tree: 引数で指定されたディレクトリ以下のファイルを
#       再帰的に木構造として表示する.

require 'optparse'

options = ARGV.getopts('aF')

# parentは絶対パス.
def display_entries(parent, prefix, options)
  # '.', '..'を除く. 無限に再帰することを防ぐ
  entries = Dir.entries(parent).delete_if do |entry|
    entry == '.' or entry == '..' or !options['a'] && entry.start_with?('.')
  end

  entries.each_with_index do |entry, index|
    fullpath = File.join(parent, entry)
    entry = f_option(parent, entry) if options['F']
    # 最後の要素かどうか
    if index == entries.size - 1
      puts "#{prefix}└── #{entry}"
      next_prefix = prefix + '    '
    else
      puts "#{prefix}├── #{entry}"
      next_prefix = prefix + '│   '
    end
    if File.directory? fullpath
      display_entries(fullpath, next_prefix, options)
    end
  end
end

def f_option(parent, entry)
  case File.ftype(File.join(parent, entry))
  when "file"
    if File.executable? File.join(parent, entry)
      "#{entry}*"
    else
      entry
    end
  when "directory"
    "#{entry}/"
  when "link"
    "#{entry}@"
  else
    entry
  end
end

target = ARGV[0] || '.'
target_fullpath = File.absolute_path target
init_prefix = ''

puts target
display_entries target_fullpath, init_prefix, options
```

ファイルのタイプを調べる際の処理をls編とちょっとだけ変えてみました。
シンボリックリンクのリンク先を表示する修正が必要ですね...
`color`は`ls`のときとほとんど変わらないので省きました。
`File.ftype`では実行可能ファイルかどうかは判定できないんですかね??そこがちょっと気になります。
あとはオプションのあたりなど複雑になってしまっているので綺麗にしたいです。
pry使ってknifeを流す

rubyやってる人には当然のことでしょうけど自分は知らなかったのでメモ

10台ぐらいまでなら手動でもいいのかもしれないけど増えてくると大変だろうからpryを使って一気に流す

```
# pry
> nodes = (1..4).map {|n| "hostname-role-#{n}"}
> nodes.reject do |node|
>   system "knife solo prepare #{node}"
> end
> nodes.reject do |node|
>  system "knife solo cook #{node} --why-run"
> end
エラーになるホストがなければ下を実施
> nodes.each do |node|
>  system "knife solo cook #{node}"
> end
```

- 配列はnodes=%w()で改行しながら入力でも可  

```
> nodes = %w(
> hostname-role-1
> hostnmae-role-2
> )
```

- rejectは戻り値がFalseだったものを表示する
- eachはnodesの分だけ繰り返す
EC2上にChasen環境をつくる

AWS EC2上にChasenをインストールするメモ。

# 0. instance立ち上げ

EC2上にinstanceを立ち上げる。
とりあえず、お試しならt1.microでも良いかも。

AWS t1.micro
OS: Aamzon Linux

ツール、データはS3上に上げておくと、外部からダウンロードするより少し早いし、お財布にも少し優しい。


# 1. yum update

```bash
$ sudo yum update
```

# 2. swap設定

EC2instanceがt1.microのときswap領域を設定する

```bash
$ sudo dd if=/dev/zero of=/swap.img bs=1M count=2048
$ sudo chmod 600 /swap.img
$ sudo mkswap /swap.img
$ sudo vi /etc/fstab
```

以下を追加

```
/swap.img    swap    swap    defaults    0    0
```

swapを有効にする

```bash
$ sudo swapon -a
```

# 3. 日本時間に設定

```bash
$ sudo vi /etc/sysconfig/clock
```
ZONE="Asia/Tokyo"
に書き換える。

```bash
$ sudo ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
$ sudo reboot
```

# 4 .  epelリポジトリの有効化

Amazon Linux AMIでEPELの設定だけはすでに行われている。
EPELを使いたいパッケージのところでyum --enablerepo=epel install -y xxxxと実行する。
というのを確認したら、次のステップへ。

# 5. S3ツールのインストール (S3を利用しない場合は、不要)

```bash
$ sudo yum install gem
$ sudo yum install rubygem-aws-sdk
$ sudo yum -y --enablerepo epel install s3cmd
$ s3cmd --configure
```
 
Access KeyとSecret Keyを設定する
httpsを使うにyes

s3cmdで日本語を正しく扱うための設定

```bash
$ sudo vi /usr/lib/python2.6/site-packages/sitecustomize.py
```

```py:/usr/lib/python2.6/site-packages/sitecustomize.py
import sys
sys.setdefaultencoding('utf-8')
```

# 6. 開発環境インストール

```bash
$ sudo yum -y install gcc*
$ sudo yum -y install make
$ sudo yum -y install ruby-devel
```
# 7. Dartsインストール

```bash
$ wget http://chasen.org/~taku/software/darts/src/darts-0.32.tar.gz
$ gtar xvzf darts-0.32.tar.gz
$ cd darts-0.32
$ ./configure
$ make
$ make check
$ sudo make install
```

# 8. ChaSenインストール

```bash
$ wget http://iij.dl.sourceforge.jp/chasen-legacy/56305/chasen-2.4.5.tar.gz
$ tar xzf chasen-2.4.5.tar.gz
$ cd chasen-2.4.5
$ sudo ./configure
$ sudo make
$ sudo make install
$ sudo vi /etc/ld.so.conf.d/usr-local.conf
$ cat usr-local.conf
/usr/local/lib
$ sudo ldconfig
```

# 9. ipadic をインストール

```bash
$ wget http://jaist.dl.sourceforge.jp/ipadic/24435/ipadic-2.7.0.tar.gz
$ tar zxf ipadic-2.7.0.tar.gz
$ cd ipadic-2.7.0
$ ./configure
```

辞書ファイルをUTF-8に変換

```bash
$ vi convert.sh
```

```bash:convert.sh
#!/bin/sh
for file in *.dic *.cha
do
if [ -f $file ]; then
echo $file
iconv -f euc-jp -t utf-8 $file > tmpfile
mv tmpfile $file
fi
done
exit
```

```bash
$ sh ./convert.sh
$ `chasen-config --mkchadic`/makemat -i w
$ `chasen-config --mkchadic`/makeda -i w chadic *.dic
$ sudo make install
```

# 10. chasenrcもUTF-8に変換

```bash
$ cd /usr/local/etc
$ sudo cp -p chasenrc chasenrc.orig
$ iconv -f euc-jp -t utf-8 chasenrc > /tmp/chasenrc.tmp
$ sudo mv /tmp/chasenrc.tmp chasenrc
$ sudo chown root:root chasenrc
```

# 11. テスト

```bash
$ chasen -iw
今日の天気は雨です。
今日     キョウ     今日     名詞-副詞可能
の     ノ     の     助詞-連体化
天気     テンキ     天気     名詞-一般
は     ハ     は     助詞-係助詞
雨     アメ     雨     名詞-一般
です     デス     です     助動詞     特殊・デス     基本形
。     。     。     記号-句点
EOS
``` 
 


# 参考URL：
Python - ChaSenのインストール - Qiita [キータ] http://qiita.com/yss44@github/items/cfc05860523d673d9000
VMware製品へのPOODLE脆弱性の影響情報

## 概要

VMware社からナレッジ「[VMware KB: VMware Products and CVE-2014-3566 (POODLE) (2092133)](http://kb.vmware.com/kb/2092133)」が発行されており、ブラウザでSSL v3を無効化することを提案している。

## 詳細

VMware製品への影響は、関連ナレッジおよびセキュリティ･アドバイザリで確認する。以下に筆者の確認した範囲でリンク等をまとめる。

### 背景

2014年10月15日に、National Vulnerbility Databaseに[CVE-2014-3566](http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-3566)が登録されている。この問題は、[Google Online Security Blog](http://googleonlinesecurity.blogspot.co.uk/2014/10/this-poodle-bites-exploiting-ssl-30.html)や[openssl.org](https://www.openssl.org/~bodo/ssl-poodle.pdf)が呼称した「POODLE」の通称でも情報が広まっている。

### VMware社からの発信情報

POODLEのVMware製品への影響については、VMware社から(1)VMware社製品に関する影響調査状況のナレッジが出されている。

1. [VMware KB: VMware Products and CVE-2014-3566 (POODLE) (2092133)](http://kb.vmware.com/kb/2092133)

影響の有無、および対応方法（パッチリリースの有無など）は上記のナレッジおよびセキュリティ・アドバイザリを確認すればよい。ナレッジおよびセキュリティアドバイザリは随時更新されるので、確認時には何月何日時点の情報であったかも押さえておき、定期的に再確認することをお勧めする。

### 関連ナレッジの和訳

KB 2092133については、KB 2092877で和訳が公開されている。ただし訳文は原文に比べて、情報更新が遅れることがしばしばあるので注意すること。

* [VMware KB: VMware 製品と CVE-2014-3566 (POODLE)(2092877)](http://kb.vmware.com/kb/2092877)

### 対策

ナレッジでは、以下の対策を提示している。

> To mitigate this issue, disable SSL v3 in your browser. Please review or contact the browser vendor for documentation on how to disable SSL v3.（私訳：この問題を軽減するには、ブラウザでSSL v3を無効化します。SSL v3の無効化方法に関するドキュメントは、ブラウザベンダーにお問い合わせください。）

2014年10月16日16時時点（日本時間）時点での、上記ナレッジの記載に基づく。

## 参考

本脆弱性の内容。

* [National Vulnerbility Database:CVE-2014-3566](http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-3566)
* [Google Online Security Blog: This POODLE bites: exploiting the SSL 3.0 fallback](http://googleonlinesecurity.blogspot.co.uk/2014/10/this-poodle-bites-exploiting-ssl-30.html)
* [openssl.org "This POODLE Bites: Exploiting The SSL 3.0 Fallback" (PDF)](https://www.openssl.org/~bodo/ssl-poodle.pdf)

VMware社からの発信情報。

* [VMware KB: VMware Products and CVE-2014-3566 (POODLE) (2092133)](http://kb.vmware.com/kb/2092133)
* [VMware KB: VMware 製品と CVE-2014-3566 (POODLE)(2092877)](http://kb.vmware.com/kb/2092877)

VMware社のナレッジやセキュリティアドバイスは、随時更新されるので、適宜、原文を確認されたい。

----

本ページ内容は筆者が参照の便のためにある持点でまとめた個人的なメモです。内容を保証するものではなく、また筆者の所属組織等とは一切かかわりがありません。
【PHP】処理にかかる時間を計測して時間・分・秒で表示

# まずはじめに
[【PHP】割り算の切り上げ、切り捨て、四捨五入](http://qiita.com/fantm21/items/8a4de4fa4109cf0d9937)の続きです。
もっと言えば、上記の記事の内容を調べるきっかけになったものです。

# 処理する時間を計測して時間・分・秒で表示

`hoge1.php`の中で『0から1000までの数を表示させる処理をする`hoge2.php`』を呼び出すことで今回は計測しました。

## プログラム

```php:hoge1.php
<!DOCTYPE html>
<html lang="ja">
	<head>
		<meta charset="utf-8">
		<title>処理時間を計測</title>
	</head>
	<body>
		<?php
			$link_time = time();
			require('hoge2.php');
			$time = $get_time - $link_time;
			if($time>=60){
				$minute = floor($time/60);
				$second = $time - $minute*60;
				if($minute>=60){
					$hour = floor($minute/60);
					$minute = $minute - $hour*60;
					echo "<p>TIME:".$hour."[h]".$minute."[min]".$second."[s]</p>";
				}else{
					echo "<p>TIME:".$minute."[min]".$second."[s]</p>";
				}
			}else{
				echo "<p>TIME:".$time."[s]</p>";
			}
		?>
	</body>
</html>
```

```php:hoge2.php
<?php
echo "<ul>";
for($i=0;$i<=1000;$i++){
	echo "<li>".$url."</li>";
}
echo "</ul>";
$get_time=time();
```

## 解説
解説というほどでもないのですが、
まずはじめに**hoge1.php**が呼び出された時間を`time()`関数を使って取得して`$link_time`に格納しました。**hoge2.php**を呼び出して、次に1から1000までを計算をした後、`$get_time=time();`として処理が終わった時間を取得。
そして、`$get_time`から`$link_time`を引くことで処理時間を取得しました。

今回は秒までの処理時間しか考えない予定だったので、
`microtime()`関数は使わなかったです。
【PHP】割り算の切り上げ、切り捨て、四捨五入

# まずはじめに
ちょっとあることをしている処理にかかる時間を計測して時間・分・秒に変換する際に調べることになったので記録。

『処理にかかる時間を計測して時間・分・秒に変換して表示するというのを行う』というのは後で違う記事として掲載しておきます。

#本題
## 切り捨て
`floor(x/y)`

## 切り上げ
`ceil(x/y)`

## 四捨五入
`round(x/y)`
【Git】不要ローカルブランチを、[特定のもの以外]全削除するワンライナー

```bash
git branch | egrep -v 'ここに残したいブランチ名' | xargs git branch -D
```

* ポイント：**残したい**ブランチ名。  
  （間違って消したいものを指定しちゃったら　⇒　[誤って必要だったブランチを消してしまい、涙目なあなたへ。](http://qiita.com/shimomai@github/items/50b62dd2b3d92170f1f3)）
* egrepの-vオプションを外すと、消したいブランチ名を指定 に早変わり。間違えると涙目。
* `|`で複数指定可。

### 実行例

```bash
実行前：
(feature/test1)$ git branch
  develop
* feature/test1
  feature/test2
  feature/aiueo
  test/foobar
 
実行：
(feature/test1)$ git branch | egrep -v 'develop|feature/aiueo' | xargs git branch -D
Deleted branch feature/test2 (was af9115a).
Deleted branch test/foobar (was 7cf8c30).
error: branch '*' not found.
error: Cannot delete the branch 'feature/test1' which you are currently on.
 
実行後：
(feature/test1)$ git branch
  develop
* feature/test1
  feature/aiueo
```


### エイリアス例
```
alias dallbranch="git branch | egrep -v 'develop' | xargs git branch -D"
```
自分が今いるブランチは消えないし、結局develop以外全部消したいことの方が多いから、まるごとaliasに入れて快適快適。
ohaiのhostnameの利用方法について


awsのインスタンスのデフォルトのホスト名は`ip-10.x.x.x`みたいな感じだけど、覚えられないしzabbixとかの監視側から分かりづらすぎるのでインスタンス作成時につけたタグからchefでホスト名変えています。
`base_setting`というcookbookがあって、`renamehost.rb`というレシピを以下のような感じで書いてます。

```
cookbook_file "/usr/local/sbin/renamehost" do
  source "renamehost"
  owner 'root'
  group 'root'
  mode 0750
end

prd = Chef::EncryptedDataBagItem.load("awskeys","hoge")
prd_id = prd["aws_access_key_id"]
prd_key = prd["aws_secret_access_key"]
prd_region = prd["region"]
dev = Chef::EncryptedDataBagItem.load("awskeys","fuga")
dev_id = dev["aws_access_key_id"]
dev_key = dev["aws_secret_access_key"]
dev_region = dev["region"]

ohai "reload" do
  plugin "hostname"
end

environment = node.chef_environment
role = ("#{node.roles}"[/[\w_-]+/])
if "#{environment}" == 'mng' || "#{environment}" == 'prod' || "#{environment}" == 'test'
  bash "exec-renamehost" do
    not_if { node[:hostname] =~ /^#{role}/ }
    notifies :reload, "ohai[reload]", :immediately
    notifies :restart, "service[rsyslog]", :immediately
    code <<-EOC
      /usr/local/sbin/renamehost `echo #{prd_id} #{prd_key} #{prd_region}`
    EOC
  end
else
  bash "exec-renamehost" do
    not_if { node[:hostname] =~ /^#{role}/ }
    notifies :reload, "ohai[reload]", :immediately
    notifies :restart, "service[rsyslog]", :immediately
    code <<-EOC
      /usr/local/sbin/renamehost `echo #{dev_id} #{dev_key} #{dev_region}`
    EOC
  end
end

include_recipe "base_setting::hosts"
```

クレデンシャルはdata_bagsにencryptedで入れてます。
renameしてるbashリソースのnotifiesにrsyslogのrestartしてるのはログに出るホスト名変えるためです。
role名がhost名の頭につくことになってるので、not_ifでrole名から始まらなかったら実行されるというガード付けてます。
bashリソース内で実行されてるrenamehostはただのシェルスクリプトで、cookbook_fileで置いてるだけで、
処理内容的には自ホストのメタデータからタグ内容取得して`hostname`コマンドでホスト名変えて`/etc/sysconfig/network`の`HOSTNAME`の値を差し替えてます。

hostsはohaiのreloadがimmediatelyで終わった後のタイミングでtemplateで配っています。
（immediatelyつけなかったらどうなるかというと全てのレシピが流れたあとに実行されるようです。
　参考：`http://www.engineyard.co.jp/blog/2013/chef-recipe-lifecycle/`）
たとえば以下のようなファイル。

```
127.0.0.1  localhost <%= node['hostname'] %> localhost.localdomain localhost4 localhost4.localdomain4
<%= node['ipaddress'] %>	<%= node['hostname'] %> localhost
```

zabbix_agentd.confとかのHostnameも変えた値が入るようにrunlist的に後ろのほうになってます。

今のところこんな感じです。

Ohaiのプラグインの話は「Chef活用ガイド」の3章あたりに色々のってました。
UILabelを上寄せにしたいとき

UILabelを上寄せにしたいときにとった解決策をメモ

UILabelには左・中央・右寄せはあるものの、上(下)寄せは無く自動的に中央に揃えられる。
単に上寄せしたいだけだったので、高さを調節することで上寄せしたように見せかける。
高さのみを調整したかったので以下のような方法で実装した。

```objc
    CGRect rect = _label.frame;
    [_label sizeToFit];
    rect.size.height = CGRectGetHeight(_label.frame);
    _label.frame = rect;
```

受け取った文字列を表示するような場合、受け取る文字列の長さによって２行になったり３行になったりするので、自動的に上寄せしてくれるときれいに見せることができる。
Scala source code compatible with both scala/scalac


scala/scalac両対応なScalaソース

This is the defacto standard of **executable** Scala script, using shebang (little bit verbose for explanation below).
これは **実行可能な** Scalaソースの標準です。本来不要なobjectとか付いていますが以下の説明のためです。

```scala
#!/usr/bin/env scala
!#
object hello extends App{
	println("Hello World");
}
hello.main(args)
```
Note: `!#` does not seem to be required if your Scala is 2.10(?)
2.10では`!#`は不要なようです(?)。

Actually hello.main(args) is verbose. Because (cited from `scala -help`:

```
A file argument will be run as a scala script unless it contains only
self-contained compilation units (classes and objects) and exactly one
runnable main method.  In that case the file will be compiled and the
main method invoked.  This provides a bridge between scripts and standard
scala source.
```

So let's strip it.
hello.main(args)は不要なので取り除きましょう。

```scala
#!/usr/bin/env scala
!#
object hello extends App{
	println("Hello World");
}
```

Now the scala command is dumb. We need explicit main method. Unfortunately App trait cannot be used.
scalaコマンドは何も出力しなくなってしまいました。mainメソッドを明示しなければなりません。残念ながらApp traitは使えないのです。

```scala
#!/usr/bin/env scala
!#
object hello{
	def main(args: Array[String]){
		println("Hello World");
	}
}
```

Finally, to satisfy scalac, let's use http://qiita.com/ando-masaki/items/323c6b08e07ec4538c3d trick (`//usr/bin/env go run $0 $@;exit`).
scalacを満足させるため、「Go言語でshebang」のトリックを使います。

```scala
//usr/bin/env scala $0 $@;exit
object hello{
	def main(args: Array[String]){
		println("Hello World");
	}
}
```

Great. Now this source is compatible with both scala/scalac.
素晴らしい！このソースはscala/scalac互換になりました。

Finally, don't forget that there must be only one class/object or this trick won't work anymore.
最後に、このトリックを使うにはclass/objectは複数置けないことに留意してください。


---

I have found that similar technique can be applied to F#.
Make the file extention `.fsx` and make the first line `//usr/bin/env fsharpi $0 $@;exit`.
milkcocoaで作ったアプリをチーム内限定で利用する方法

今回は特定の誰かのみに、milkcocoaのデータを扱えるようにしてみましょう！

##はじめに

現状のmilkcocoaのサンプルアプリの多くは、パブリックに利用することが前提となっています。今回は特定のユーザのみがデータにアクセスできるようにするにはどうすればいいかについて説明します。

例として付箋アプリを使います。
付箋アプリを自分のサイトにホストし、特定のメンバーのみ利用できるようにしましょう。
http://fusen.mlkcca-app.com/

![スクリーンショット 2014-10-16 14.36.02.png](https://qiita-image-store.s3.amazonaws.com/0/54243/cbac0e82-3acf-f819-29c4-d633b26b43cd.png)

今回のソースコードはこちらです。
https://github.com/milk-cocoa/fusen/tree/private

## さっそくやってみましょう

こちらのソースコードでは、すでにログインダイアログや新規登録ダイアログを実装済みです。このソースコードをダウンロードして、まずはindex.htmlの18行目の{your-appid}の部分を、自分で作ったappidに書き換えてください。

```
$(function(){
  fusen.init("https://io-{your-appid}.mlkcca.com");
})
```

　またmilkcocoaのアプリの管理画面側でいくつか設定を行います。まずセキュリティルールですが、以下を貼付けて更新ボタンを押してください。allow_usersのruleのところの"admin @foo.com"は、あなた自身のメールアドレスにしてください。
　以下のルールについて少し説明しますと、allow_usersデータストアにEmailアドレスが格納されている人だけ、fusenデータストアにアクセスできます。またallow_usersデータストアにアクセスできるのは、"admin @foo.com"さんだけです。

```css
fusen {
  permit : all;
  rule : dataStore("allow_users").exist({email : account.email});
}

allow_users {
  permit : all;
  rule : account.email == "admin@foo.com";
}
```

## ホスティングしてみましょう。

　この時点でどこかにホスティングするか、ローカルでホストし付箋アプリを開いてみてください。秘密にしたい情報を他のドメインで取り出せないようにするため、管理画面の「設定タブ」で許可オリジンの設定も行ってください。ローカルホストならば"localhost:*"でOKです。また例えば "http://example.com/" で公開するならば"example.com"でOKです。
　URLを開くと以下のようなログイン画面が出ると思います。ダイアログの左下の「新規登録しますか？」というところをクリックしてください。すると新規登録ダイアログが出ますので、先ほど"admin @foo.com"の代わりに登録したメールアドレスで新規登録してください。確認用リンクがメールで届きますので、リンクをクリックしてください。最初のログインダイアログに戻り、ログインしてください。

![スクリーンショット 2014-10-16 14.00.34.png](https://qiita-image-store.s3.amazonaws.com/0/54243/e9d832c7-f66f-a29c-7d1d-d24b52e1f1a1.png)

ログイン完了後に、milkcocoaのアプリの管理画面の「データストア」タブを開き、以下のように付箋を触ることのできるユーザを追加します。

![スクリーンショット 2014-10-16 14.02.43.png](https://qiita-image-store.s3.amazonaws.com/0/54243/7e0dd261-f74e-2568-7b23-5a3cac151db6.png)

Enterを押すと追加できます。自分を追加して、付箋を貼れることを確認してみてください。

## まとめ

今回はソースコードはサンプルを利用し、milkcocoaの設定について主に触れました。
**18日に渋谷で行われるmilkcocoaハッカソンでも紹介しますので、よろしくお願いします！**

http://connpass.com/event/9150/
"Error: Cannot retrieve metalink for repository: epel. Please verify its path and try again" と言われてコケる


`yum update` やら何やっても "Error: Cannot retrieve metalink for repository: epel. Please verify its path and try again" と言われコケる。

`URLGRABBER_DEBUG=1 yum check-update 2> debug.log` を叩き、debug.log の末尾あたりを見る。

```debug.log
2014-10-16 13:58:10,040 attempt 1/10: https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=x86_64
INFO:urlgrabber:attempt 1/10: https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=x86_64
2014-10-16 13:58:10,041 opening local file "/var/cache/yum/x86_64/6/epel/metalink.xml.tmp" with mode wb
INFO:urlgrabber:opening local file "/var/cache/yum/x86_64/6/epel/metalink.xml.tmp" with mode wb
* About to connect() to mirrors.fedoraproject.org port 443 (#0)
*   Trying 66.35.62.166... * connected
* Connected to mirrors.fedoraproject.org (66.35.62.166) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* NSS error -8092
* Closing connection #0
* SSL connect error
2014-10-16 13:58:11,053 exception: [Errno 14] problem making ssl connection
INFO:urlgrabber:exception: [Errno 14] problem making ssl connection
2014-10-16 13:58:11,054 retrycode (14) not in list [-1, 2, 4, 5, 6, 7], re-raising
INFO:urlgrabber:retrycode (14) not in list [-1, 2, 4, 5, 6, 7], re-raising
Error: Cannot retrieve metalink for repository: epel. Please verify its path and try again
```

mirrors.fedoraproject.org に接続する時にSSL connect error が起きている。

epel リポジトリのミラー、 https://mirrors.fedoraproject.org/ のSSL証明書？が更新されちゃてるのが原因。

# 対応

`yum update -y ca-certificates` をしたらいいと思います。
外部jsのロードが完了してからfunctionを実行する

外部js内に関数が定義されていて、それが定義されてから実行する方法。
document.writeなどで動的にscriptタグが書き出されたときに、scriptの実行順序が逆になっても対応が可能。

```js:javascript
// src: 外部jsのパス
// handler: jsのロード完了後に実行する関数
var call = function(src, handler){
	var base = document.getElementsByTagName("script")[0];
	var obj = document.createElement("script");
	obj.async = true;
	obj.src= src;
	if(obj.addEventListener){
		obj.onload = function () {
		handler();
		}
	}else{
		obj.onreadystatechange = function () {
			if ("loaded" == obj.readyState || "complete" == obj.readyState){
				obj.onreadystatechange = null;
				handler();
			}
		}
	}
	base.parentNode.insertBefore(obj,base);
};

call("http:xxxxxxx/xxx.js", function(){/*ここに処理を記載*/})
```
CoreOSでのDockerイメージの格納場所変更


Docker on ubuntu なイメージの格納場所変更の方法は調べると出てくるんですけど、CoreOSでの変更方法が出てこなかったのでメモ。
状況としては、以下のような感じで変更に至りました。

1. CoreOSの動いてるディスクそんなに大きくない（60GB程度）
1. Dockerデフォルトのまま動かしてる（/var/lib/docker, btrfsで動いてる）
1. ちょっとサイズのでかいコンテナ作った
1. コミットしようとしたらスペースないよって怒られた
1. 別にディスクくっつけてそっちに出さなきゃ！

`docker commit` するときはコミット時の差分の容量は空き容量としてないとコミットできないんですね(；´Д｀)（当たり前だろ）


## 設定変更

`/etc/systemd/system/docker.service` のServiceセクションの `ExecStart` の起動コマンドを変更します。


``` 変更前
ExecStart=/usr/bin/docker -d -s=btrfs -r=false -H fd://
```

```変更後
ExecStart=/usr/bin/docker -d -s=btrfs -r=false -H fd:// -g 変更したいパス
```

## 再起動

```
systemctl daemon-reload
systemctl restart docker
```

## トラブル

CoreOSはファイルシステムがbtrfsで、Dockerのストレージドライバもbtrfsがデフォルトになってるんですが、変更先をNFSにしちゃってました。
そのせいで再起動しても以下のようにログが出て動きませんでした。

```
Oct 16 10:51:08 DOCKER01 docker[32381]: 2014/10/16 01:51:08 docker daemon: 1.1.2 d84a070; execdriver: native; graphdriver: btrfs
Oct 16 10:51:08 DOCKER01 docker[32381]: [c3e1ee15] +job serveapi(fd://)
Oct 16 10:51:08 DOCKER01 docker[32381]: [c3e1ee15] +job initserver()
Oct 16 10:51:08 DOCKER01 docker[32381]: [c3e1ee15.initserver()] Creating server
Oct 16 10:51:08 DOCKER01 docker[32381]: 2014/10/16 01:51:08 Listening for HTTP on fd ()
Oct 16 10:51:08 DOCKER01 docker[32381]: prerequisites for driver not satisfied (wrong filesystem?)
Oct 16 10:51:08 DOCKER01 docker[32381]: [c3e1ee15] -job initserver() = ERR (1)
Oct 16 10:51:08 DOCKER01 docker[32381]: 2014/10/16 01:51:08 prerequisites for driver not satisfied (wrong filesystem?)
```

あー、ごめんなさい。
というわけで変更先もbtrfsにして解決しましたとさ。

### devicemapperにすればよかったんじゃ？

そうなんですが、既に作っていたイメージ達が`/var/lib/docker/btrfs`とかでできていたのでどうやって移行したらいいのかわからずこういう感じにしちゃいました。
たぶんもうちょいちゃんと調べればそこらへんの移行方法もわかると思います。（エクスポートすればいいのかな）
Availability to get comments, stars on google photos

## picasa api
☓　picasa stars
○　picasaweb goods(by Photo-based feed api)
○　picture's comments(by Photo-based feed api)
☓　g+ post comments with pictures
☓　image files with exif
△　exif data(by Photo-based feed api)

## g+ api
☓ private data
○ private data
SSLv3で問題になるフィーチャーフォンの対応

SSLv3で問題になるの、Windows XP IE6だけでしょ？と思ってるそこのあなた、ガラケー向けサイトってのが存在することをご存じでしょうか。そう、ガラケーむけにHTTPS通信を提供しているサービスっていうのが存在するんですよ。

SSLv3問題については下の記事に書きましたよ。

- [nginx - 我々はどのようにして安全なHTTPS通信を提供すれば良いか - Qiita](http://qiita.com/harukasan/items/fe37f3bab8a5ca3f4f92#poodle-attack)

# 各キャリアの対応情報

- docomo: https://www.nttdocomo.co.jp/service/developer/make/content/ssl/spec/index.html
- au: http://www.au.kddi.com/ezfactory/web/
  - TLS対応については[2012年5月24日から開始されたケータイアップデート(PDF)](http://www.au.kddi.com/ezfactory/web/pdf/sha-2_update.pdf)に記載されています 
- softbank: http://creation.mb.softbank.jp/mc/tech/tech_web/web_ssl.html

# 各フィーチャーフォンの対応状況

| キャリア |                     | 対応バージョン        |
|:--------|:--------------------|:---------------------|
| **docomo** | iモードブラウザ2.0以降 | SSLv2 SSLv3 TLSv1.0 |
|        | iモードブラウザ2.0以前 | SSLv2 SSLv3         |
| **au**     |                   | SSLv3 TLSv1.0  |
| **softbank** |                    | SSLv3 TLSv1.0       |

docomoのiモードブラウザ1.0の機種を除き、殆どの場合TLSv1.0に対応しているようです。ただしコメント欄にもありますが、docomoに関しては、らくらくホンがiモードブラウザ1.0との記載がありますので、継続して注意が必要です。

TLSv1.0もそれほど使いたい規格ではないため「TLSv1.1以降にも対応しているよ！」みたいな情報引き続きお待ちしております。

## 更新履歴

- 2014/10/31: コメント欄にてauのすべての機種がTLSv1.0に対応している(ただしTLS拡張にはアップデートにより対応)ことを教えてもらったので修正しました。
新しいバージョンのMonoをインストールする方法

#Ubuntuでのmonoバージョン
Ubuntuの公式パッケージサーバーにホストされているmonoのバージョンは、ちょっと古いバージョンで止まっています。
C#好きの私としては悲しいですが、Linuxの世界では、C#はあまり人気が無いんでしょうね。
この情報は、Raspberry Piで、HttpClientクラスを使うC#コードを動かしたくて調べた情報です。
マイクロソフト嫌いな方もLinuxにC#をインストールして試して貰える切っ掛けになったら幸いです。

#外部パッケージリポジトリを利用する
[directhex](https://launchpad.net/~directhex)さんが公開しているパッケージリポジトリを更新サーバーに追加します。
[Monoxide experimental Mono packages PPA](https://launchpad.net/~directhex/+archive/ubuntu/monoxide)
[directhex](https://launchpad.net/~directhex)さんのビルドしたパッケージが、どの程度信用できるかは分かりませんが、Raspberry Piなど非力なマシンで、monoをコンパイルするのは、かなり時間が掛かるので、手っ取り早く新しいバージョンのmonoを試したい時には重宝します。

```bash
$ sudo apt-get install python-software-properties
$ sudo add-apt-repository ppa:directhex/monoxide
$ sudo apt-get update
```

#ソースコードからインストールする
http://www.mono-project.com/docs/compiling-mono/linux/
公式ページに公開されている方法をコマンドで打っていけば、インストールできます。
gitから最新ソースコードを取得する方法も紹介されていますが、コンパイルエラーが発生することもあるようなので、リリースされた最新版をビルドする方が無難です。

```bash
$ sudo mkdir /opt/mono/
$ sudo chown -R `whoami` /opt/mono/
$ sudo apt-get install git autoconf libtool automake build-essential mono-devel gettext
$ wget http://download.mono-project.com/sources/mono/mono-3.10.0.tar.bz2
$ tar xvf mono-3.10.0.tar.bz2
$ cd mono-3.10.0
$ ./configure --prefix=/opt/mono/
$ make
$ sudo make install
$ PATH=/opt/mono/bin:$PATH
```

#バージョンごとにインストール場所を変える

```bash
$ tar xvf mono-3.12.0.tar.bz2
$ cd mono-3.12.0
$ ./configure --prefix=/opt/mono/3.12
$ make
$ sudo make install
$ PATH=/opt/mono/3.12/bin:$PATH
```
MySQLでUserID、注文番号(or 日付等)に応じてそのユーザが何回目の注文かの連番を振るSQL


はじめに
=========

昔書いた懐かしいTipsを発掘したので投稿します。
MySQL5.1の頃だと思いますが、今でも一応動くのではないかと。

前置き
-------

MySQL では、「変数」がつかえて、Update文において、変数をUpdateしながらレコードを更新するということができます。
たとえば、単純に「点数(score)」の大きい順に、順位(rank)をつけるというSQLは、以下のように書けます。

```
SET @r := 0;
UPDATE 対象テーブル SET rank = (@r := @r + 1) ORDER BY score DESC;
```

ただしこれは「同点は同順位」とかは考慮されていません。
今は「同点は同順位」をどう記述するかは今は置いておきます。面倒そうだし。

ここまでは、割と一般的に既知です。

本題
====

例えば、ECなどで、「この顧客は何回目の注文なのか」を知りたい場合があります。
もちろん、プログラムを書けば、ぼちぼちカウントもできますが、
分析系のBATCH処理は、SQLで書けるなら書いてしまいたい場合があります（ありました）。

例
-----------
例として、以下のようなテーブル`seq_user_order`を考えます。
`seq_user_order`は、注文履歴のようなテーブルから特定の列を抜いたもの、です。

* member_id： 会員番号
* order_day: 注文日
* user_seq_no: 何回目の注文か（←ここを埋めたい）

このuser_seq_no を

* **同じ「会員番号」の人が、 *同じ*「注文日」** ならば、 **同じ番号を振る(初回は1)**
* **同じ「会員番号」の人が、 *違う*「注文日」** ならば、 **番号を１つ増やす**

というロジックで埋めたいとします。

このような、以下のようなSQLで書けます。

```
SET @r := 0, @id := 0, @day=0;
UPDATE seq_user_order SET user_seq_no = (
CASE 
WHEN member_id = @id AND order_day = @day THEN @r
WHEN member_id = @id THEN (@r := @r + 1) + 0*LENGTH(@day := order_day)
ELSE (@r := 1) + 0*LENGTH(@id := member_id)*LENGTH(@day := order_day)
END)
ORDER BY member_id, order_day;
```

工夫した点は、`0*LENGTH(...)` で変数値の代入をやっているところです。
条件が一致すれば変数値を更新したいが、ほかの書き方ではなかなか難しい。

ただし、この構文は「代入の順序は保証されない」というMySQLの仕様に逆らっています（たぶん）。

一応、

* 「`CASE WHEN` は手前から評価され、一致すれば後の部分は評価されない」
* 「条件部分がTrueにならなければ、それ以降のTHENは評価されることは大抵ない」

という一般的な実装を期待しているので、それほど危険な書き方でもないかのかな、と。

一時的な集計、遊びで使う分には問題ないかと思います。

さいごに
=====

MySQLの変数はちょっとしたことには便利です。
あまりトリッキーなことはやめておいたほうが良いんですがね。。
github.comにSSH公開鍵と間違えて秘密鍵を登録することはできない

github.comの「Settings」「SSH keys」に知識不足でSSH秘密鍵を登録する人がいるのではないか？と心配する声を聞いたことがあります。たしかに、github.comは登録したSSH公開鍵を全世界に公開するため、まちがって秘密鍵を登録してしまう人がいるなら問題です。


しかし、実際にgithub.comで秘密鍵を登録できるかどうか試してみると、次のようにエラーが表示されました。

```
Key is invalid. It must begin with 'ssh-ed25519', 'ssh-rsa', 'ssh-dss', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', or 'ecdsa-sha2-nistp521'. Check that you're copying the public half of the key
```

よかった、秘密鍵を登録した人はいなかったんだ。
MacPortsからDovecotとPostfixをインストールして開発環境でメール配信のテストをする


サービス開発中に、メール送信のテストをしたいけど、
外には送信したくない、もしくは送信できない場合、
ローカルにメールサーバーを構築するといいです。

DovecotとPostfixが扱いやすいのでこの2つを選びます。

# Portsの更新
まずはportsを更新しておきましょう。

```bash
$ sudo port selfupdate
```

# Dovecot
ではDovecotから。

## Dovecotインストール
```bash
$ sudo port install dovecot2
```

## Dovecot設定
設定ファイルをexampleディレクトリからコピー

```bash
$ sudo cp /opt/local/share/doc/dovecot/example-config/dovecot.conf /opt/local/etc/dovecot
$ sudo cp /opt/local/share/doc/dovecot/example-config/conf.d /opt/local/etc/dovecot
```
conf.dには各種インクルードファイルがおいてあるのでそのままコピーしておくといいです。

Dovecotを設定しましょう

```/opt/local/etc/dovecot/dovecot.conf
protocols = imap
 
#!include conf.d/*.conf
!include conf.d/10-master.conf
!include conf.d/10-auth.conf
 
#!include_try local.conf
 
ssl = no
 
mail_location = maildir:~/Maildir
```
プロトコルはimapだけでいいと思います。
10-master.confには基本動作に必要な設定が書かれているのでインクルード。
10-auth.confではプレーンテキストでのログインとauth-system.conf.extがインクルードされているので必要。
sslの設定は面倒なので利用不可にしてしまいます。

## pamの設定
今回重要なのがpamの設定です。

```/opt/local/etc/dovecot/conf.d/auth-system.conf.ext
passdb {
  driver = pam
  # [session=yes] [setcred=yes] [failure_show_msg=yes] [max_requests=]
  # [cache_key=] []
  #args = dovecot
  args = login
}
```
デフォルトではdovecot用にユーザーを登録したりしなければいけないですが、面倒なのでMacのユーザーをそのまま使います。
Postfox側も（表現は正確ではないけど）Macのユーザーでメール送受信するのでこの方法が都合がいいです。
「args = login」としてmacの認証機構を利用するようにします。

## Dovecot起動
では起動しましょう。

```bash
$ sudo port load dovecot2
```
最近のMacPortsは「port load」でlaunchctlのloadとstartまでやってくれます。（前からそうだった？）

これでひとまずimap接続が出来るようになりました。

# Postfix

次にPostfixをいれます。
標準でもPostfixはインストールされていますが、
Dovecotに合わせて開発環境用にはMacPortsのものを使います。

## Postfixインストール
```bash
$ sudo port install postfix
```

## aliasデータベース作成
このまま起動するとaliasデータベースが無いよと怒られるので

```bash
$ cd /opt/local/etc/potfix
$ sudo newaliases
```

## Maildir形式の設定
dovecotに合わせてMaildir形式で扱うようにします

```/opt/local/etc/potfix/main.cf
home_mailbox = Maildir/
```

## sendmailコマンドへのリンク
このまま起動してもPHPなどから呼び出される/usr/sbin/sendmailコマンドは、標準でインストールされているPostfixのもの（？）が使われてしまいます。
そうすると、SMTP経由ではMaildir形式に入ったのに、PHP経由等でsendmailコマンドを使った時はmbox形式になったりと、統一されない動きになります。

コマンドを置き換えてしまいましょう。

```bash
$ sudo mv /usr/sbin/sendmail /usr/sbin/sendmail.org
$ sudo ln -s /opt/local/sbin/sendmail /usr/sbin/sendmail
```
Linuxディストリだと設定ファイルで切替ができるのにMacPortsは/opt配下だけに対象を限定するのが基本だからでしょうかね。
port upgradeする度にこれをやらなければいけないのが面倒。

## Postfix起動
では起動

```bash
$ sudo port load postfix
```

# あとがき
以上でMac上でPHPなどを使ったメール送信のテスト環境が出来上がりました。

うまく動かないときは/var/log/maillogを見るとわかるかもしれません。

ちなみに私は、通常のメールにはMail.appを使いますが、
テストのメールにはThunderbirdを使ってメールを閲覧しています。

# 検証環境
Mac OS X 10.9.5 (Mavericks)
MacPorts 2.3.1
dovecot 2.2.13
postfix 2.11.1


# 補足
ブログからの転載です
http://blog.genieframe.com/2011/09/26/macportsからdovecotとpostfixをインストールしてメール環境を作/
カーネルパニック時に自動で再起動させる


開発環境でカーネルパニックを起こす事が度々あったので、自動で再起動がかかるように設定。

##設定ファイルの編集

`/etc/sysctl.conf`を開く

```/etc/sysctl.conf
kernel.panic = 10
```

`/etc/sysctl.conf`に上記内容を追加。もしくは修正する。
数字に関しては、何秒後に再起動を行うかを指定する。

##設定の反映

```
sysctl -p
```

で設定を反映させる。

```
sysctl kernel.panic
```

で設定が反映されている事を確認。

##一時的な対応

`/proc/sys/kernel/panic`内に秒数を入れて再起動する事も可能だけど、1度再起動すると値が戻ってしまい次回再起動は行わない。

***
##参考サイト
* [Linuxでカーネルパニックさせる方法](http://linux.just4fun.biz/%E9%80%86%E5%BC%95%E3%81%8DUNIX%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89/Linux%E3%81%A7%E3%82%AB%E3%83%BC%E3%83%8D%E3%83%AB%E3%83%91%E3%83%8B%E3%83%83%E3%82%AF%E3%82%92%E7%99%BA%E7%94%9F%E3%81%95%E3%81%9B%E3%82%8B%E6%96%B9%E6%B3%95.html)
deploy:rollbackした後のこといろいろメモ

メモ。
結構もやもやしたから。

***

###ミスcommitをpushしたときのワークツリーの動き

gitでpushする⇒デプロイする⇒ミスった。

```lang:デプロイの履歴
deploy A(正しい)
deploy B(間違えた)←シンボリックリンク
```

```lang:ワークツリー
commit A1(deploy Aのcommit)
commit A2(deploy Aのcommit)
commit B1(deploy Bのcommit)
```
　
戻す⇒デプロイは変化するが、ワークツリーは変化しない。

```lang:rollback
bundle exec cap [環境] deploy:rollback
```

```lang:デプロイの履歴
deploy A(正しい)←シンボリックリンク
deploy B(間違えた)
```

```lang:ワークツリー
commit A1(deploy Aのcommit)
commit A2(deploy Aのcommit)
commit B1(deploy Bのcommit)
```

　
直した⇒ワークツリーにcommitが追加。

```lang:ワークツリー
commit A1(deploy Aのcommit)
commit A2(deploy Aのcommit)
commit B1(deploy Bのcommit)
commit C1(deploy Cのcommit)
```

　
pushもした(コマンド省略)

```lang:updateと再起動
bundle exec cap [環境] deploy:update
bundle exec cap [環境] deploy:graceful_restart
```

※個人的な都合でこうしてる。再起動を気にしなければdeployのみで可。

```lang:デプロイの履歴
deploy A(正しい)
deploy B(間違えた)
deploy C(修正した)←シンボリックリンク
```

```lang:ワークツリー
commit A1(deploy Aのcommit)
commit A2(deploy Aのcommit)
commit B1(deploy Bのcommit)
commit C1(deploy Cのcommit)
```

gitのワークツリーがコピーされるため、修正後は気にせず最新のワークツリーをデプロイしてしまえばよい。

***

###rollbackしたときテーブル修正があるか

もう一つ。

deploy:migrateとかやってた場合、deploy:rollbackしてもDBは戻らない。
そのときのやり方メモ。(こっちは実際にやってないのでコマンドなし)

```lang:テーブルに修正がない場合
・気にせずrollbackしてコード修正。
・気にせずdeployして反映。
```

```lang:テーブルに修正がある場合
・rollbackする。
・作ったテーブルをdropするマイグレーションファイルを作成。
・再度deploy:migrateをして、テーブルをdropする。
・コード修正。
・普通にdeployして反映。
```
ページから特定部分だけを取り除く

### 背景

テンプレートの一覧から、ヘッダの部分を一気に置き換えたかったんですが、
手でやるのはあまりにも面倒だったのでPHPでやってみました。

### やりたかったこと

* 修正前のテンプレート (例)

```html
<html>
<head>
<title>テスト</title>
</head>

<body>
<!--contents -->
<div>

<!-- header -->
<div>

<div>
ヘッダ画像
</div>

<div>
ナビゲーションバーとか
</div>

</div>
<!-- /header -->

コンテンツの内容

<!-- contents -->
```

これのヘッダ部分(`<!-- header -->` ~ `<!-- /header -->`)をごそっと他のテンプレートをincludeする形に変えて、
↓みたいな感じにしたかった。

* 修正後のテンプレート (例)

```html
<html>
<head>
<title>テスト</title>
</head>

<body>
<!--contents -->
<div>

<!-- header -->
{include file='hoge.tpl'}
<!-- /header -->

コンテンツの内容

<!-- contents -->
```

### 作ったスクリプト

```php
<?php

$targetFiles = glob("*.tpl");

foreach ($targetFiles as $targetFile) {
    $newBody = replaceHeaderTag($targetFile);

    saveNewFile('out/'.$targetFile, $newBody);
}


// ヘッダ部分を置換したHTMLを返す
function replaceHeaderTag($targetFile)
{
    $body = file_get_contents($targetFile);
    
    $p1 = strpos($body, '<!-- header -->');
    $p2 = strpos($body, '<!-- /header -->');
    
    $upperBody = substr($body, 0, $p1+strlen('<!-- header -->'));
    $underBody = substr($body, $p2);

    return sprintf("%s\n{include file='hoge.tpl'}\n%s", $upperBody, $underBody);
}

// 置換したHTMLを保存する
function saveNewFile($targetFile, $body)
{
    $fp = fopen($targetFile, "w");
    fwrite($fp, $body);
    fclose($fp);
}
```

これで、カレントディレクトリ直下の`tpl`ファイルを全て対象にして、
ヘッダ部分を置換したファイルがoutディレクトリ配下に保存されます。
アプリがバージョンアップしたときの手続きをアノテーションを使って整理する

アプリのバージョンを上げた時、何かしら互換性を保つための作業が必要なことがあります。
たとえば、データベースのマイグレーションをしたり、その他永続化したデータを書き換えたり、など。時間のかかるものもあれば、かからないものもあります。

王道なやり方としては、`Application#onCreate()`でバージョンを覚えておいて、次に`Application#onCreate()`に来た時に覚えておいたバージョンと PackageManager から取ってきたバージョン情報を突き合わせて、バージョンが変わっていたら、バージョンごとに必要な処理をする、と言った感じでしょうか。

```java
public class MyApp extends Application {
  @Override
  public void onCreate() {
    super.onCreate();

    if (isVersionChanged()) {
      doUpdateProcedure(getStoredVersionCode(), getCurrentVersionCode());
    }
  }

  private boolean isVersionChanged() {
    int current = getCurrentVersionCode();
    int stored  = getStoredVersionCode();
    return stored < current;
  }

  private void doUpdateProcedure(int from, int to) {
    if (from < 10 && to == 12) {

    }
    // if ...
    // if ...
    // if ...
  }

  private int getCurrentVersionCode() {
    // retrieve current version code from package manager.
  }

  private int getStoredVersionCode() {
    // retrieve memorized version from shared preferences or local file.
  }
}
```

ここで面倒なのは、単純にこのバージョンではこうする、だけではなく、どのバージョンからアップデートしたかも重要になるものがあるということです。そして単純に実装すると、どんどん if 文が増えていき…

はぁー、その辺のロジック、VersionCode を引数に持ったアノテーションをメソッドにつけて、そのメソッドが VersionCode に応じて勝手に呼ばれてくれたら幸せだなぁと思ったので、作りました。

## [Fit](https://github.com/KeithYokoma/Fit)

https://github.com/KeithYokoma/Fit

ライブラリ側で`@OnVersion`アノテーションを定義しており、引数に VersionCode を渡します。そうすると、バージョンアップ時に、前のバージョンから現在のバージョンまでの間の VersionCode が含まれたものを、バージョンアップ処理の時に呼び出します。

```java

public class MyModule implements VersionModule {
    @OnVersion({1, 2, 3})
    public void foo() {

    }

    @OnVersion(4)
    public void bar() {

    }
}
```

こうすることで、もし以前のバージョンでした処理をもう一度したいときに、わざわざメソッドを分けなくても、アノテーションの引数に渡す VersionCode を増やすだけで対応出来ます。

あとは、`Application`クラスで以下の準備をして、バージョンアップ時の手続きを走らせるだけです。

```java

public class MyApp extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Fit.initialize(this, new MyModule());
    }
}
```

手続きの実行は、今のところ同期的な呼び出ししかありませんが、標準の非同期処理の仕組みと簡単に組み合わせられるので、それほど大変な作業にはならないはずです。

`Fit.getInstance().execute();`
IMGKitでhtmlの任意の位置を切り取る

# 概要

htmlから画像を作成する[IMGKit](https://github.com/csquared/IMGKit) で小さめの画像がほしい。

htmlタグにwidth, heightをあててもうまくいかなかった。

# Answer

wkhtmltoimageのドキュメント(http://madalgo.au.dk/~jakobt/wkhtmltoxdoc/wkhtmltoimage_0.10.0_rc2-doc.html )によると、`--crop-h`, `--crop-w`等のオプションがあるので、試しにIMGKitにそのまま渡してみたらうまくいった。

`kit = IMGKit.new(html, :'crop-w' => 505, :'crop-h' => 230)`
windowsでsftpクライアントはWinSCPがオススメ

## 鍵

* WinSCP (パスワード有りppkに対応)
* FileZilla (パスワード無しppkのみ対応)
* CyberDuck (OpenSSHの秘密鍵(pem)をそのまま使える)
* FFFTP (SFTPは現在未実装)

## 秘密鍵

* パスワード付き鍵を設定したいため、[puttygen.exe](http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html)を使う。

# 規定のプログラムで開く設定

![kitei.png](https://qiita-image-store.s3.amazonaws.com/0/25728/4b379544-03d2-f45f-0a53-324c23e7f849.png)

![hiraku.png](https://qiita-image-store.s3.amazonaws.com/0/25728/a3a536e8-3a63-b180-48fa-f4a438118a30.png)
SplFileInfo::openFile error の対処

permmissionの問題で以下のようなエラーがでる。

```
Warning: SplFileInfo::openFile(/www/app/tmp/cache/persistent/cake_core_cake_console_) [splfileinfo.openfile]: failed to open stream: Permission denied in /www/lib/Cake/Cache/Engine/FileEngine.php on line 292
```

これは、上記ファイルの所有者とpersisitentの所有者が異なる時に発生する。
presisitentディレクトリの所有者とファイルの所有者を同じにすれば、解決する。もしくは、以下の設定でもOKのよう。

参考：http://www.iwaking.com/20121210/740/
ドライブレターが勝手に変わってWindowsのブートが途中で停止した！

発生した状況
----

* マシン： ThinkPad T420s
* 外付けHDDを1台接続
* ブートしたOS：Windows 8.1
* 過去の更新プログラムは全部適用済み
* __BIOSが起動した後、Windowsのロゴが表示し、少しくるくるした後ブートが停止した(ﾟдﾟ)__
* 2014年10月の更新プログラムをインストールして再起動をかけたときにこの現象が発生


原因
----
* SYSTEM_DRVのドライブレターがCになっていた
* WindowsのブートはデフォルトではCドライブから行われるので起動できないのは当然だった
* 他のドライブも今のOSをインストールした時と違うドライブレターがassignされていた


復旧方法
----
コマンドプロンプトを使って、グシャグシャになったドライブレターを戻してあげます。

参考： [ドライブ文字の割り当て、変更、または削除を行う - Microsoft Developer Network](http://msdn.microsoft.com/ja-jp/library/cc757491(v=ws.10).aspx)

1. インストールDVD（今回Windows 8を使用）からブートし、「トラブルシューティング」→「詳細オプション」→「コマンドプロンプト」より、__コマンドプロンプトを起動する__

2. 次のコマンドを実行して、ドライブレターを変更するツールを起動する
` diskpart `

3. DISKPART プロンプトで、ボリューム一覧を表示する。
` list volume `

1. ボリュームを選択する。n はリストで表示されたボリュームの番号。
` select volume n ` （volumeの後にスペース必要）

1. 選択したボリュームのボリュームラベルを変更する。例ではLを割り当てている。
` assign letter=L `

1. もう一度`list volume`を実行すると変更が確認できる。
YouTube の動画をコマンドラインからダウンロードできる youtube-dl をUbuntuに入れる

ゲーム実況動画を愛してやまない日々が続いております。皆様いかがお過ごしでしょうか？YouTubeの動画をどうんロードしてサーバー側でごにょごにょするために、コマンドラインから簡単にダウンロードできる youtube-dl をインストールしてみます。

## Ubuntu 12.04 系に入れるよ

超簡単です。

```
$ sudo apt-get install youtube-dl
```

おしまい。

## つかいかた

```
$ youtube-dl https://www.youtube.com/watch?v=e6xuxo6Xrs0
```

https://www.youtube.com/watch?v=e6xuxo6Xrs0

↑おすすめです。ステマじゃないよ

某AppBankのひとがパズドラにチャレンジするゲーム実況動画です。こういう動画が数時間で30万再生されてるんです。Qiitaに投稿されているクソみたいなノウハウ記事の1万倍とかそんな感じなわけですよ。ゲーム実況動画、楽しいです。

### コマンドラインオプションも使ってみる

このままだとダウンロードしたファイル名に日本語が入ってしまって使いにくいので、YouTubeのvideoIdがファイル名になるようにするの

```
$  youtube-dl -o "%(id)s.%(ext)s" https://www.youtube.com/watch?v=e6xuxo6Xrs0
```

-o っていうオプションでファイル名を指定できます。

### 動画のファイル形式を指定する

-F ってゆうオプションでダウンロードできるファイルのフォーマットが一覧できる。x720にしたいので、22を選ぶ感じ。

```
 youtube-dl -F https://www.youtube.com/watch?v=e6xuxo6Xrs0
[youtube] Setting language
[youtube] e6xuxo6Xrs0: Downloading webpage
[youtube] e6xuxo6Xrs0: Downloading video info webpage
[youtube] e6xuxo6Xrs0: Extracting video information
[info] Available formats for e6xuxo6Xrs0:
format code extension resolution  note
140         m4a       audio only  DASH audio , audio@128k (worst)
160         mp4       192p        DASH video
133         mp4       240p        DASH video
134         mp4       360p        DASH video
135         mp4       480p        DASH video
136         mp4       720p        DASH video
17          3gp       176x144
36          3gp       320x240
5           flv       400x240
43          webm      640x360
18          mp4       640x360
22          mp4       1280x720    (best)
```

-f オプションでフォーマットの優先順位を指定できるので

```
$ youtube-dl -f 22/17  -o "%(id)s.%(ext)s" https://www.youtube.com/watch?v=e6xuxo6Xrs0
```

とすることで、720が優先DLできておしまい。

## 参考

youtube-dl: Documentation - http://goo.gl/Jid0U7
reStructured Text 記法で HTML を直接書く

reStructured Text 記法で HTML を直接書くには

```
.. raw:: html
```

を使うと良いみたい。
以下、例。

```
.. raw:: html

   <iframe src="//www.slideshare.net/slideshow/embed_code/13918388" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/yumi-uniq-ishizaki/css-13918388" title="ご存知、ないのですか？CSSの優先順位" target="_blank">ご存知、ないのですか？CSSの優先順位</a> </strong> from <strong><a href="//www.slideshare.net/yumi-uniq-ishizaki" target="_blank">Yumi Ishizaki</a></strong> </div>
```
GrapeでApache POIのMicrosoft Office 2007以降対応を記述する方法

普通にGrabを書いてもSAXのエラーが出て上手く動かない。excludeにxml-apisを追加したら特に問題なく動いた。

```groovy
@Grapes([
    @Grab("org.apache.poi:poi-ooxml:3.+"),
    @GrabExclude("xml-apis:xml-apis"),
])
```

POIのバージョンに依存すると思うが、どのバージョンだとこうする必要があるのかは未検証。
[Lua] rawset は別に速くなかった

# table.insert

```Lua:bench1.cmd
::rem:: --[[ vim:set ft=lua:
@lua "%~f0" %* & exit /b
]]--
t = {}
for i=1,100000 do
    table.insert(t,"x")
end
print(os.clock())
```

```
$ bench1
0.018
```

# 普通にテーブルアクセス

```Lua:bench2.cmd
::rem:: --[[ vim:set ft=lua:
@lua "%~f0" %* & exit /b
]]--
t = {}
for i=1,100000 do
    t[i] = "x"
end
print(os.clock())
```

```
$ bench2
0.006
```

# rawset

```Lua:bench3.cmd
::rem:: --[[ vim:set ft=lua:
@lua "%~f0" %* & exit /b
]]--
t = {}
for i=1,100000 do
    rawset(t,i,"x")
end
print(os.clock())
```

```
$ bench3
0.015
```

# 結論

- 関数コールが入るとやはり遅い
- 人間素直に生きよう
- そんなに気にするんだったら、LuaJIT 使えば？
[Rails 4.x] 画像を保存する為にCarrierWave + RMagick を使おうとして、インストールする際に起こりがちなエラーへの対処

CarrierWave + RMagickの組み合わせは、Railsで画像をリサイズしてアップロードするのに便利です。
しかしインストール時にめんどくさいエラーがよく起きたので対処法をメモします。

インストール

rmagickは画像をリサイズしたりするのに必要です。

# インストール

下記の様にGemfileに追記してbundle installをかけるのが一般的かと思います。

```rb:Gemfile
gem 'carrierwave'
gem 'rmagick'
```

```rb
$ bundle install
```

# エラー

下記の様なエラーがよく出ました。

```rb:抜粋
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

checking for Ruby version >= 1.8.5... yes
checking for gcc... yes
checking for Magick-config... no
Can't install RMagick 0.0.0. Can't find Magick-config in -----

*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may need configuration options.
```

# 原因

どうやら、ImageMagickをイントールしていないと出るエラーの様です。
なので、ImageMagickと関連モジュールを入れればOKです。

# 対応例

CentOSにImageMagickをインストールするには下記。

```rb
$ sudo yum -y install libjpeg-devel libpng-devel
$ sudo yum -y install ImageMagick ImageMagick-devel
```
DockerコンテナがWindows Serverでも動くように！（と理解）

これまでLinux限定だったDocker。
に、[Docker Engine for Windows Serverが登場](https://blog.docker.com/2014/10/docker-microsoft-partner-distributed-applications/)

AWS Elastic Beanstalkに続き、Azure IaaSでDockerコンテナが動く…はず。
クラウド間のポータビリティの向上に期待。
Ubuntu でスワップファイルを追加する方法 - Killed とか (x _ x)ひえー

# 同情するならサーバーをおくれ

お金も無くサーバーを借りるのも一苦労な日々を送っております。RubyなんてVMだけで50MBとかかかるから、512MBの借りてるサーバーだともう大変なんです。Apacheとかも動かしているからメモリが無いんです。四畳半でつつましく暮らしている感じです。

## Amazon さんとかサーバー無料チケットとかくれないかなー |ω・`）チラ

動画をディプラして楽しめる仕組みが出来上がったら使わせてあげるから、AWSの無料クーポン1年分とかくれないかなー |ω・`）チラ |ω・`）チラ

## Ubuntu はスワップが割り当てられて無いの

Rubyにするなよって言われそうなんですが、みんながつくったライブラリーとかそういうエコシステム的なものを活用させていただけることがありがたくて、ほんとみんなありがとう。

つくった処理をcronでまわしてたら、途中で止まってて、コマンドラインで実行したら途中で

```
Killed
```

って、 

(x _ x)ひえー 


これはOOM Killerというやつですか？良く知らないのですが。殺されちゃったんです。

```
$ top
```

したら、swap がゼロになってて、メモリも ruby が 30% とか取っててそれが二つとかあって、もうカツカツだったんです。で、念のためプロセスも確認すると

```
$ ps -elf | grep ruby
```

どう見ても、わたしの書いたスクリプトがばっちりメモリ使ってるんです。とにかくメモリを何とかしなきゃ（増やすという結論はありません）なので

```rb
GC.start
```

とか入れて、CPUの負担増やしてもメモリを無理やり解放しようと試みるも、最近のがーべっじコレクターなんてわたしより賢いんだから、効果なんて無いんです。CPU使用率が無駄に30%とか上がっただけでした。

## Ubuntu でスワップファイルを追加しよう

スワップファイルつくろうということで、ググってみたらありましたありました。まずは

### スワップ状態の確認

```
$ sudo cat /proc/swaps
```

### スワップファイル作成

```
$ sudo mkdir /var/swap/
$ sudo dd if=/dev/zero of=/var/swap/swap0 bs=2M count=2048
$ sudo chmod 600 /var/swap/swap
```

2Mのブロックサイズのものを2048個つくるよ。借りてるサーバーのディスクが20GBしかなくて、最初間違えて 2M x 4096 って作りすぎてひえーってなりました。ディスクサイズを考えてスワップサイズは計画的にね。

### スワップファイルをスワップに割り当て

```
sudo mkswap /var/swap/swap0
sudo swapon /var/swap/swap0
```

### 起動時にスワップファイルとして設定されるようにする

```
$ sudo vi /etc/fstab
```

/var/swap/swap0 swap swap defaults 0 0
↑を最終行に追加
## 参考サイト

Ubuntu スワップファイルの追加方法 - http://goo.gl/DyIkA3
[Rails 4.1.x] Rails 4.1.xをgem install しようとするとエラーがすごい

# 問題
gem install railsだと最新が入る
でもerrorがすごい


```rb
$ gem install rails --no-document
---
ERROR:  While executing gem ... (Gem::RemoteFetcher::UnknownHostError)
    no such name (https://api.rubygems.org/api/v1/dependencies?gems=mime-types)
---
```

↑これはネットワークの問題の様で、softbankの4G回線をテザリングすると起きた。


```rb
$ gem install rails --no-document
---
Fetching: i18n-0.6.11.gem (100%)
Successfully installed i18n-0.6.11
Fetching: actionview-4.1.6.gem ( 94%)ERROR:  While executing gem ... (Gem::RemoteFetcher::FetchError)
    too many connection resets (https://au-m.rubygems.org/gems/actionview-4.1.6.gem)
---
```

↑これも多分ネットワークの問題なんだと思うけど、具体的な原因はよくわからない。


↓とりあえず解決策を。

# インストールするRailsのバージョンを4.0にする

## とりあえずインストール可能なものを探します

```rb
$ gem search -r rails
```

4.0ならインストールできました。

```rb
$ gem install rails --version="~>4.0.0”
--
Done installing documentation for tzinfo, multi_json, activesupport, rack, rack-test, builder, actionpack, tilt, hike, sprockets, sprockets-rails, thor, railties, mime-types, mail, actionmailer, activerecord-deprecated_finders, arel, activemodel, activerecord, rails after 422 seconds
21 gems installed
```


## その後やること

後ほど、RailsプロジェクトのGemfileにて、Railsのバージョンを4.1.6にGemfileを書き換えてbundle updateする。
（bundle updateでネットワークトラブルが起きないことを祈ります）
Atom Shellをしゃべらせる

# 背景

<blockquote class="twitter-tweet" lang="ja"><p>Atom Shellがしゃべれるようになったみたい。 <a href="https://twitter.com/hashtag/%E6%97%A9%E3%81%8F%E5%B8%B0%E3%81%A3%E3%81%A6%E8%A9%A6%E3%81%97%E3%81%9F%E3%81%84?src=hash">#早く帰って試したい</a> apmのバージョン指定があって、NodObjCがまた動かなくならないといいが。。 / “Release atom-shell v0.18.0 · atom…” <a href="http://t.co/2omdrekn0x">http://t.co/2omdrekn0x</a></p>&mdash; kjunichi (@kjunichi) <a href="https://twitter.com/kjunichi/status/522244705212329984">2014, 10月 15</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

# 最速でしゃべらせる

DevTool開いて

```
location.href="http://jsrun.it/kjunichi/mqjx"
```
Jekyll と pygments.rb で Auto-regeneration が遅い

2年ぶりに [Jekyll](http://jekyllrb.com/) を 0.11 から 2.4 へアップグレードしてみました。表題の通り、[Pygments](http://pygments.org/) を利用した場合のビルドで問題があり、調査してみました。

利用バージョンは以下の通りです。

* jekyll-2.4.0
* pygments.rb-0.6.0

## pygments.rb

Jekyll ではシンタックスハイライトに Pygments が選択できます。エンジンには [pygments.rb](https://github.com/tmm1/pygments.rb) が採用されています。

```yaml:_config.yml
highlighter: pygments
```

pygments.rb は Python-2.x 系さえ入っていれば、Pygments をインストールしなくても、ローカル gem 内の <code>vendor/pygments-main</code> にビルドして、それを利用してくれます。</p>

```
% ls vendor/bundle/ruby/1.9.1/gems/pygments.rb-0.6.0/vendor/pygments-main/
...
ez_setup.py
pygmentize
pygments
...
```

pygments.rb は、[python プロセス](https://github.com/tmm1/pygments.rb/blob/v0.6.0/lib/pygments/mentos.py)を立ち上げたままにしておき、プロセス間でやりとりして変換を行っています。これにより変換の度に外部コマンドとして `pygmentize` を起動する場合と比較して、高速に変換できることが特徴です。あたかも Ruby 単体で動作しているように使えます。

```ruby
html = Pygments.highlight(code, :lexer => lang)
```

## Auto-regeneration での問題

Jekyll では `--watch` オプションにより、ファイル更新を検知して自動再生成 _(= Auto-regeneration)_ を行なってくれます。ソースを更新する度にコマンドを叩く必要がないので、非常に便利なのですが、pygments.rb を経由すると、初回以降の再構築がとても遅いことに気づきました。

利用している `pygments.rb-0.6.0` のソースを追って計測してみたところ `Pygments::Popen.alive?` というメゾッドで、プロセスが生きているかをチェックする際に `Process.kill` を利用しており、これがボトルネックになっていました。

* https://github.com/tmm1/pygments.rb/blob/v0.6.0/lib/pygments/popen.rb#L87

計測すると、一回につき 0.1sec 程度かかっており、100 個のコードブロックを変換するためには、最低 10sec はかかってしまうことになります。Pygments モジュール内で、python 子プロセス ID 値を保持して死活監視をしているので、Jekyll 側で改善をすることは難しそうです。

かなり強引ですが、保持しているプロセスID値が `nil` でなければ、プロセスは生きているものと信頼し、`Process.kill` をスキップするように [Pygments::Popen](https://github.com/tmm1/pygments.rb/blob/v0.6.0/lib/pygments/popen.rb) にパッチを当てれば、速度面での問題は解決します。Jekyll プラグインとして `_plugins/converter.rb` 等にパッチを記述しておけば、`jekyll` コマンド実行時に読み込んでくれます。

```ruby:_plugins/converter.rb
require 'pygments'

module Pygments
  module Popen
    def alive?
      !!@pid
    end
  end
end
```

子プロセスが終了していたり、pygments.rb 自体の実装が変わってしまえば、この方法は使えませんが、開発時の暫定的なものであれば許容できると思います。

## Auto-regeneration を無効にする

Jekyll は、都度すべてのソースから作り直します。更新により影響のあるファイルのみをビルドする仕組みではないので、更新を検知して再生成する制作サイクルは、リソースの無駄使いの面もあります。

無理にパッチを当てても、ファイル数が多ければ、結果的には足かせになってしまうので、手動コマンドでビルドするほうが無難だと思います。

開発サーバを起動する `jekyll serve` は、デフォルトで _Auto-regeneration_ が有効です。無効にするには `--no-watch` を指定します。

```
% jekyll serve --no-watch
```