OmniAICreator/Qiita-1.07M huggingface dataset:
Apache Shiroでの認証（DB編）

#目的
DBを使ったユーザ認証・権限管理をWebアプリケーションで行いたい。Apache　Shiroでおこなうことを想定した場合、どのように実施するかを明確にすること。

## 注意
やや古い情報を元に書き写しているので、動作確認を実際にする必要があります。

#Apache Shiroの環境準備
pom.xmlに以下を追加して、Mavenを利用する。

```pom.xml
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-core</artifactId>
  <version>1.2.2</version>
</dependency>
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-web</artifactId>
  <version>1.2.2</version>
</dependency>
```
#Apache Shiroの設定
Shiroの設定は、shiro.iniファイルとして記述する。ファイル名は変更可能。

```shiro.ini
[main]
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.permissionsLookupEnabled = true
jdbcRealm.authenticationQuery = SELECT password FROM users WHERE username = ?
jdbcRealm.userRolesQuery = SELECT authority FROM user_roles WHERE username = ?
jdbcRealm.permissionsLookupEnabled = false
ds = com.mysql.jdbc.jdbc2.optional.MysqlDataSource
ds.serverName = localhost
ds.port = 3306
ds.user = ユーザ名
ds.password = パスワード
ds.databaseName = DB名
jdbcRealm.dataSource = $ds
```

## DBへの認証情報の設定
authenticationQuery とuserRolesQuery によって、認証情報をDBからどのように取得するかを設定します。（SQLとして）

### 注意
この例はパスワードを平文で扱っているので、注意が必要です。別途、下にてハッシュ化したパスワードを取り扱う内容を記述しま
す。

### 設定ファイルの特徴
shiroファイルはDIコンテナの設定ファイルと同じような意味を持っており、変数名に対してクラスを設定するとインスタンス変数
のように利用できる。jdbcRealmはその例です。その変数をJavaBeanとしてとらえ、propertyに設定することで設定をおこないます
。いくつか予約名を持っており、その名称を利用して設定することで動作を変更することができます。

#Webアプリケーションへの組み込み
Webアプリケーションで利用するためには、web.xmlにShiroFilterを適用する必要があります。

##web.xmlへの設定
以下のようにFilter設定をおこないます。

```web.xml
<listener>
  <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>
<filter>
  <filter-name>ShiroFilter</filter-name>
  <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
  <init-param>
    <param-name>configPath</param-name>
    <param-value>classpath:shiro.ini</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>ShiroFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
```
この設定では、ClassPathの直下のshiro.iniが読み込まれます。

## 権限管理の仕方
Webアプリケーションの権限管理として、URLベースの権限管理をおこなうことができます。そのためにはshiro.iniに追記します。
Basic認証とForm認証で動作が異なるため、それぞれを記述します。

### Basic認証

```shiro.ini
[urls]
/mnt/** = authcBasic,roles[admin]
```
この例では、Basic認証で/mntの下のアクセスは、認証したユーザのroleがadminでないとアクセスできないことを表しています。

### Form認証

```shiro.ini
[urls]
/mnt/** = authc,roles[admin]
[filters]
authc.loginUrl = /login.jsp
```

設定先のオブジェクト名が、authBasicからauthcに代わります。

これは、authcBasic.authcは予約名で、Basic認証(org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter)、Form認証
(org.apache.shiro.web.filter.authc.FormAuthenticationFilter)をおこなうクラスで定義されています。

## パスワードの符号化
パスワードを平文でDBMSに格納することはセキュリティ上、好ましくないため通常はSHA1などのハッシュアルゴリズムで符号化して格納する。

Shiroを使って、パスワードを符号化するための設定は以下の通りです。
パスワード認証を管理しているのがCredenialMatcherで、
SHA1に対応したCredenialMatcherは
Sha1CredentialsMatcher　です。
そのため、

```shiro.ini
credentialsMatcher = org.apache.shiro.authc.credential.Sha1CredentialsMatcher
credentialsMatcher.storedCredentialsHexEncoded = true
jdbcRealm.credentialsMatcher = $credentialsMatcher
```
と設定することで、対応できます。
svnでマルチプロジェクトを管理している時に各リビジョンが一斉に知りたいなと思った時のメモ



例えば、以下の構成のようなディレクトリで

* workspace
 * jp.sample.project1
 * jp.sample.project2
 * jp.sample.project3

jp.sample.project1〜3の各プロジェクトの最終コミットリビジョンを一斉に書き出したい時は以下のシェルスクリプトで実現できます。

```bash:report.sh
$ cd workspace
$ ls | xargs -I % -n 1 sh -c 'VER=`svnversion -c %`; echo "$VER %"'
```

```結果
5340:8333 jp.sample.project1
5207:8332 jp.sample.project2
5463:8334 jp.sample.project3
```

例えば、jp.sample.project1はリビジョン5340〜8333のファイルを含むことがわかります。
sftp コマンドのオプション指定は一つづつ

#内容

```-o User=user01,Port=8822,IdentityFile=~/.ssh/example.com.ppk``` でいけるかと思ったけど、一つづつみたい。

悲しかった。

```console
$ sftp -o User=user01 -o Port=8822 -o IdentityFile=~/.ssh/example.com.ppk example.com
```

#環境

- CentOS release 6.5 (Final)
capistrano3: cap install後にまずやること

# はじめに
capistrano3使う時、cap installコマンドでディレクトリ構成とかを作りますよね。
その後、installタスクが生きたままだと悲しい事が起きるので、それを無効化しておこうという話です。

# いきなり結論
以下のコマンドでinstallタスクを無効化します。

```
echo "Rake::Task[:install].clear" >> Capfile
```

# 悲しい事？
cap installの実装を見ると、こうなっています。

```capistrano-3.2.1/lib/capistrano/tasks/install.rake
...
 18   file = config_dir.join('deploy.rb')
 19   File.open(file, 'w+') do |f|
 20     f.write(ERB.new(template).result(binding))
 21     puts I18n.t(:written_file, scope: :capistrano, file: file)
 22   end
...
```
"w+"でdeploy.rbを開いてるので、まっさらにしてからテンプレートを書き出す実装ですね。
つまり、deploy.rbに何かを書いた状態でcap installを叩いてしまうと、deploy.rbが初期化されてしまいます。(Capfile/[env].rbも同じくですが)

### そんなことする？
私はやらかしましたorz
具体的には、初回だけ叩くようなタスクをinstallという名前で実装したため、`cap hoge install`と叩いて誤爆してしまいました。
Rakeの仕様として、同名のタスクが定義された場合は、既にあるタスクに処理が追加されるため、意図せずinstallが走ってしまいます。
チームメンバーでQiita☆ダービーをしてみたときのルール

![qiita.jpg](https://qiita-image-store.s3.amazonaws.com/0/3163/fa404437-008e-df1d-8ad0-fe09cb658ba6.jpeg)

7月に、チームメンバーの何人かでQiita☆ダービーをしてみました。

参加メンバーは以下の方々。

http://qiita.com/yanap
http://qiita.com/kkam0907
http://qiita.com/taizo
http://qiita.com/kaznmb
http://qiita.com/corin8823
http://qiita.com/torumiyamon1987
http://qiita.com/ygoto3

# ルール説明

ルールは以下の通りです。

1. 7月中にContribution数が高い人が優勝
2. 記事数や内容に制限は無し。知人からストックをもらってもよし。グロースハックをしてもよし
3. すでにQiitaを使い慣れている人は、ハンデをつける(-30〜-10)。

# 運用のコツ

運用のコツといってもひとつだけ。

## 毎日参加メンバーに進捗を報告する。

1記事の平均被ストック数が5~10くらいなので、
20ストックくらいもらえると一気に逆転します。
そこらへんを把握しやすくするために
毎朝、上の写真のようなグラフをHipchatに貼って
自分の順位や勢いを把握できるようにしました。

# 成果

人気があるものを一部

### yanap

* [これから仕事でAndroidアプリを開発するための参考書籍](http://qiita.com/yanap/items/4480ec48c2d076d6c41a)
* [データ量が多くなった時のredisのkeyの探り方](http://qiita.com/yanap/items/66108468b93ebf37f8c7)

### kkam0907

* [git rebaseと仲良くなろう~part1](http://qiita.com/kkam0907/items/f92dd5288622387409be)
* [知らないとrsyncでもハマるシェル初期化](http://qiita.com/kkam0907/items/d21a775ce250d52b9d0e)

### taizo

* [Gruntの代替ビルドツール。gulpをはじめる。](http://qiita.com/taizo/items/d06387eeb0844069b166)
* [capistrano3のデプロイを把握する
](http://qiita.com/taizo/items/afff46a260bd11588962)

### kaznmb

* [『Don’t Be Scared Of Functional Programming』 JavaScriptで関数型言語に触れてみる。](http://qiita.com/kaznmb/items/1511840cb2aa46ca938b)

### corin8823

* [1年間Ruby on Railsのプロジェクトをやってきた僕がためになった書籍やwebサイト](http://qiita.com/corin8823/items/2d1e66904fab7b5d8b02)
* [RailsのActive Recordで指定した順序通りに取得したい](http://qiita.com/corin8823/items/318220f6f1b14a1bb7ba)

### torumiyamon1987

* [[CSS]BEMの方法論とMindBEMdingという記法](http://qiita.com/torumiyamon1987/items/5c73eb2116190c9a652d)

### ygoto3

* [Famo.us のアニメーションが AngularJS で簡単に追加できる famous-angular を使ってみる](http://qiita.com/ygoto3/items/39da29b70e76278d7d4d)

* [TypeScript 用 MVC Framework な TypeFramework を使ってみる](http://qiita.com/ygoto3/items/fa86ae7305a6fc8d0fe6)

# やってみた感想

Qiita:Teamを入れて
みんなしっかり社内の情報を共有するんだー的な力は入れずに、
思いつきのようにはじめてみたのですが、
これでも十分にみんながどんなことに興味を持っていて、
どんなことが書けるのかがわかるようになってきました。

あと、意外と難しいことではなく、最初の一歩でもきちんと書けば
Contribution数を稼ぐ事ができるので、
ハンデはつけたものの新卒でも十分戦えるので、
年齢関係なく参加するのも問題なさそうです。

盛り上げのひとつとして。
githubやherokuへのブラウザアクセスでSSLエラー

根本原因不明ですが、Safari や Chrome で SSL のエラーが発生するようになりました。
アクセス先は github や heroku。

症状の直接的な原因にはいくつかあるようです。
共通しているのは、おそらく OS が保持している証明書がおかしくなっているらしいこと。
自前で証明書を管理している FireFox では、この SSL エラーが出ないんですよね。

解決策はこのサイトあたりにあります。
[Macのブラウザーで GitHub へアクセスすると SSL 証明書エラーが発生する場合の対処法](http://pc-karuma.net/mac-github-ssl-ssl-certificate-error/)

ですが私の場合、ここで書かれている「ログイン」に期限切れ証明書はありませんでした。
消すものがないので途方に暮れていたのですが、以下の方法で解決。

「証明書」⇒「システムルート」⇒「DigiCert High Assurance EV Root CA」を選択し、右クリックメニューから「書き出し」
cer ファイルが作成されます。保存先はどこでもいいです。

「証明書」⇒「ログイン」へ戻り、「ファイル」メニューの「読み込み」から、先ほどの cer ファイルを読み込む。

こうすると、「DigiCert High Assurance EV Root CA」が「ログイン」にも追加されます。

この状態で Safari や Chrome でアクセスしてみれば、SSL 証明書エラーは解消してると思います。
解消していない場合は、一度ブラウザを再起動してみてください。


SSL 証明書エラーが出ていた時は、heroku や github のサーバ証明書の署名もとである「DigiCert High Assurance EV Root CA」の期限切れが通知されていました。
この有効期限が7/27まになっていたので、7/28になってエラーが出ると。
でもその有効期限の証明書は「キーチェーンアクセス」には見当たらないという不思議な現象。
今回「システムルート」からコピーして来た奴は有効期限は2031年なんですよね。
おかしな現象ですが、まあ直ったんでよしとします。
Gitで複数のリポジトリをまとめる

##やりたいこと
各々gitで管理していた配下のフォルダをまとめて、GitHubで1つのリポジトリとして見たい。

※以下、ご自分のユーザー名、リポジトリで読み替えて下さい

```lang:フォルダ構成
git-tutorial-3
├tutorial1
├tutorial2
:
└tutorial7
```

##GitHubへPUSH
各サブフォルダそれぞれ個別にgitで管理している。
親フォルダでGitHubへPUSHする。

```
$ cd git-tutorial-3
$ git init
$ git add .
$ git commit -m "Initial commit"
$ git remote add origin https://github.com/kwgch/git-tutorial-3.git
$ git push -u origin master
```

するとサブフォルダ（tutorial1～7）のフォルダ名は表示されるが、中身は見えない。

##サブツリーマージ
そこで下記コマンドをtutorial1～7に対して実行する。

```
$ git remote add tutorial1 ./tutorial1
$ git fetch tutorial1
$ git read-tree --prefix=tutorial1/ tutorial1/master
```

COMMIT、PUSHする。

```
$ git add .
$ git commit -m "Merge subtree"
$ git push
```

Githubで各サブフォルダの中身が確認できるようになる。
ただ、各サブフォルダの以前の履歴を見ることはできない（ローカルでは可能）。

##サブフォルダでの作業
```
$ cd tutorial5
$ vim sample.txt
$ cd ..
$ git add .
$ git commit -m "Change tutorial5"
$ git push
```

サブフォルダのファイルを変更して親フォルダでPUSHすると、GitHub上で変更が確認できる。

##参考

こちらのサンプルを利用させて頂きました。
[サルでもわかるGit入門 〜バージョン管理を使いこなそう〜](http://www.backlog.jp/git-guide/stepup/stepup7_1.html)

参考にしました。
[サブツリーマージ](http://git-scm.com/book/ja/Git-%E3%81%AE%E3%81%95%E3%81%BE%E3%81%96%E3%81%BE%E3%81%AA%E3%83%84%E3%83%BC%E3%83%AB-%E3%82%B5%E3%83%96%E3%83%84%E3%83%AA%E3%83%BC%E3%83%9E%E3%83%BC%E3%82%B8)
EC2作成時にまず設定したこと

#アップデート
`yum -y update`

#タイムゾーン変更
`cp -p /usr/share/zoneinfo/Asia/Tokyo /etc/localtime`

#新規ユーザ作成
##ユーザ作成
`# useradd username`
##公開鍵設置
`# su - usrname`
`$ mkdir ~/.ssh`
`$ cp /home/ec2-user/.ssh/authorized_keys ~/.ssh`
`$ chown -R username.username ~/.ssh`
##SSHログイン
作成したユーザでログインできることを確認

#ec2-user削除
不要な場合は削除する
`userdell -R ec2-user`
iOS 7でLINEに画像を送信する

[LINEではカスタムURLを使って外部から情報を送ることができる](http://media.line.me/howto/ja/)。画像を送るには、UIPasteboardに画像を添付し

[NSString stringWithFormat:@"line://msg/image/%@", pasteboard.name]

のようなURLを開けば良い。

[LINEActivity](https://github.com/OopsMouse/LINEActivity)は上記を実装した[UIActivity](https://developer.apple.com/library/ios/documentation/uikit/reference/uiactivity_class/Reference/Reference.html)のサブクラスで、これを使うと簡単にLINEとの共有機能を実装することができる。ところが、iOS7で試したところ、当初うまく行かなかった。

結果から書くと、UIPasteboardの初期化の際に

[UIPasteboard pasteboardWithUniqueName]

となっていたのを

[UIPasteboard generalPasteboard]

のように変更すると無事に写真を共有することが出来た。

iOS7では[UIPasteboard pasteboardWithName:create:] と +[UIPasteboard pasteboardWithUniqueName] で作られるUIPasteboardは同じアプリケーショングループ内のアプリでのデータ共有にのみ使えるように[変更されて](https://developer.apple.com/library/ios/releasenotes/General/RN-iOSSDK-7.0/)おり、それが原因でうまく写真が受け渡せなかったのではないかと考えられる。

ところで、http://media.line.me/howto/ja/ には「iOS7では画像送信をサポートしていません」と書かれているが、上記のやり方で無事に画像の共有を行うことができた。
コンポーネントをどのように作るか

## 最適化を焦らない
えらい人の言葉で

> 「時期尚早な最適化はすべての悪の根源である」

とあるように、はじめから完璧に最適化を意識しすぎてしまうと時間をかけて作ったものが結局使わず無駄になってしまったということがありうる。
必要になるまで機能を追加しない。

## Rules of three
どういったタイミングで最適化すればよいかのガイドライン

> 「3回繰り返したものは、パターンとして成立する」

1. 初めてそのパターンが登場したときには、再利用すること特に考えなくてよい
1. 一度解決したパターンに再び遭遇したときにも、コンポーネント化したくなる気持ちを抑える
1. 3度目になって、パターンとして何が分かっていて、何が分かっていないかを考えてコンポーネント化してリファクタリングをする

こうなる前に心がけること

- 詳細度の高いセレクタを書かない
- クラス名の衝突・スタイルの汚染が無いようにユニークな名前をつける

Rules of three を別の視点で考えるならば

> 「そのコンポーネントが、3つのプロジェクトで使えたならば、他のプロジェクトでも使える可能性がある」


## SOLID CSS

- Single Responsibility Principle / 単一責任の原則
- Open/Closed Principle / オープン・クローズドの原則
- Liskov Substitution Principle / リスコフの置換原則
- Interface Segregation Principle / 依存関係逆転の原則
- Dependency Inversion Principle / インターフェイス分離の原則


### 単一責任の原則
 **構造という責任** と **見た目という責任** は分離して設計する。
具体的にいうと、構造である `position` や `float` と見た目である `border` や `background` は一緒のルールセットにしない。

### 解放／閉鎖の原則
Todo：後ほどまとめる

## 再利用が全てではない
例えば、下記のようなデザインがあるとします。

![4-1_コンポーネントをどのように作るか_01.gif](https://qiita-image-store.s3.amazonaws.com/0/41801/b07e95dd-3d73-18c8-0cfe-05629d0f4127.gif)

```css
.btn {
	display: inline-block;
	border-radius: 5px;
	border: 1px solid #ccc;
	padding: 0.6em;
	line-height: 1;
	text-decoration: none;
	color: #ddd;
}

.heading {
	display: block;
	font-size: 18px;
	font-weight: bold;
}
```

```html
<a href="#" class="btn">ボタン</a>
<h2 class="btn heading">見出し</h2>
```

例のように、同じ装飾であれば class を1つにまとめた方がよいと安直に考えない。
この場合、SMACSS の Theme カテゴリーのようなアプローチで次のように書き換えることができます！

```css
.btn {
	display: inline-block;
	line-height: 1;
	text-decoration: none;
	color: #ddd;
}

.heading {
	display: block;
	font-size: 18px;
	font-weight: bold;
}

.theme-default {
	border-radius: 5px;
	border: 1px solid #ccc;
	padding: 0.6em;
}
```

```html
<a href="#" class="btn theme-default">ボタン</a>
<h2 class="heading theme-default">見出し</h2>
```
ActiveRecordのモデルで集計テーブルの結果を扱う

# ActiveRecordのモデルで集計テーブルの結果を扱う

通常のテーブルのモデルから、別のテーブルでの集計した結果をひもづけて取得したかったので、集計テーブルとモデルでJoinして、取得できるようにした。

## 集計テーブル取得用処理の作成

まず、集計テーブル取得用処理をUserのモデルに実装します。

集計部分は、ActiveRecord的に書く必要も特になかったので、SQL直で記述しています。joinした後の結果の取得時に対象の指定が必要なので、そこは`select`で対象の集計テーブルの名前を指定しておく。

```rb
    def add_item_stats
      item_stats = <<-SQL
      (select
        user_id,
        count(case when is_public = 1 then 1 end) as public_item_count,
        count(1) as all_item_count
      from
        items
      group by user_id)
      SQL
      joins("left outer join #{item_stats} stats on users.id = stats.user_id").select('stats.*')
    end
```

## ActiveRecordのモデルからの利用方法

使用する際は、Userのモデルの取得先を指定した上で、使用します。

例えば、idが1のユーザーに対して、集計テーブルとjoinした結果を取得したい場合は、下記のように書きます。

```rb
user = User.select('users.*').where(id: 1).add_item_stats.first
```

実行されるSQLは下記のようになります。

```irb
> user = User.select('users.*').where(id: 1).add_item_stats.first
  User Load (0.5ms)  SELECT  users.*, stats.* FROM `users` left outer join       (select
        user_id,
        count(case when is_public = 1 then 1 end) as public_item_count,
        count(1) as all_item_count
      from
        items
      group by user_id)
 stats on users.id = stats.user_id WHERE `users`.`id` = 1  ORDER BY `users`.`id` ASC LIMIT 1
```

取得した結果をモデルから結果を取得する場合は、通常のカラム同様、`user.all_item_count`といった形でアクセスできるようになります。
Storm Configについて

#概要

StormにおけるConfigの扱いについてのメモ。
(調査対象はstorm-0.9.2-incubating)

#基本ルール

* プロパティの読み込みは以下の順序。下ほど優先度が高い。

  + `storm-core*.jar`にある`defaults.yaml`。
  + CLASSPAHT以下にある`storm.yaml`もしくは`storm.conf.file`プロパティで指定されたファイル(`storm.conf.file`プロパティを`defaults.yaml`から読ませることはできない点に注意。storm起動時に-Dで渡す必要がある。`storm.yaml`と「`storm.conf.file`プロパティで指定したファイル」両方を読ませることはできないので注意。)

  + `-Dstorm.options`で渡されたプロパティ。(`-Dstorm.options=propertyname1=value1,propertyname2=value2,...` みたいに複数渡せる。)

#ソースコードで確認する際のTIPS

* `storm-core/src/jvm/backtype/storm/Config.java`にStormが利用するプロパティ名がすべて書かれている。

  + Stormが使うプロパティにはスキーマ定義が付随しており、値がこのスキーマに適応していない場合エラーになる。
  + スキーマと符号するかのチェックは`read-storm-config`関数の流れで読み込みとほぼ同時に行われる。

* Stormのソースコード中ではConfigのフィールド名を大文字にして、'_'を'-'にしたものが変数として参照できるようになる。 

```clojure:storm-core/src/clj/backtype/storm/config.clj:L30
   (defn- clojure-config-name [name]
   (.replace (.toUpperCase name) "_" "-"))
    
   ;; define clojure constants for every configuration parameter
   (doseq [f (seq (.getFields Config))]
     (let [name (.getName f)
           new-name (clojure-config-name name)]
       (eval
         `(def ~(symbol new-name) (. Config ~(symbol name))))))
```


  + 例えば、`public static final String STORM_SCHEDULER = "storm.scheduler";`はclojureの中からは`STORM-SCHEDULER`という名前の変数(binding)になる。

  + この大文字varにプロパティ名が入るので以下みたいに使う。(confはclojureのmap構造。)

```clojure:storm-core/src/clj/backtype/storm/config.clj:L71
        (defn cluster-mode
          [conf & args]
          (keyword (conf STORM-CLUSTER-MODE))) <- ここ
```

* yamlファイルには、`Config.java`に記載されているもの以外の任意のプロパティも追加することができる。(Configを持つHashMapに自分のプロパティが追加される。)
  + このMap構造はトポロジからもアクセスできるため、この機能を利用して自身の環境向けの独自 プロパティを渡せる。
  + だが、SCHEMA定義の追加は`Config.java`を改造しないかぎり追加はできない。
  + また、FieldsとしてConfig.java登録されていないプロパティ名は上記のclojureコードは大文字var化をしてくれない。

#ラッパースクリプト(stormコマンド)

*普通stormコマンド経由だからこっちのほうがある意味重要。というかpdbで処理を追ったらいいと思うよ。*

その他のJavaプロダクトと同様に、Stormではjavaコマンドを直接打ち込まずに各種機能の実行ができるようになっている。

具体的には、`bin/storm`というpythonスクリプトがjavaのラッパースクリプトである。
このスクリプトの挙動を設定面に関してメモしておく。

* もし `~/.storm/storm.yaml`が存在した場合、システム共通の`STORM_DIR/conf/storm.yaml`の代わりに、`~/.storm/storm.yaml`のみをCLASSPATHに設定する。
* `STORM_DIR/conf/storm_env.ini`を読み込み、OSの環境変数に設定する。(iniファイルの読み取り先は変更できない。)

  + といっても見た感じ、`JAVA_HOME`と`STORM_JAR_JVM_OPTS`変数しか利用できないようだ。
  
    - `STORM_JAR_JVM_OPTS`には`"-Dproperty1=value1 -Dproperty2=value2"`みたいに書くとたぶんうまくやってくれる。

* `--config`オプションで、`storm.conf.file`の設定が可能。この設定は`/.storm/storm.yaml`や`STORM_DIR/conf/storm.yaml`より優先される。
* `-c property_name=value`のようにオプションを設定することで、propertyを設定可能。

  + ここで設定したオプションがstorm.optionsプロパティに設定されることになる。

#デフォルト値

* `defaults.yaml`が`storm-core*.jar`に含まれており、そこからデフォルト値が読まれる。

* コード的にdefault値が設定されていないとエクセプションを出す部分も多数あり。 デフォルト値があるもの無いものあるので注意が必要。
  (defaults.yamlがあるのでまあ大丈夫だけど。)
Gitでcommit間の変更ファイル一覧を出力

レビューするときに役立つのでメモ。

```shell-session
$ git diff --stat <コミットID A> <コミットID B>
```


個人的に一番よく使うのはコレ。

```shell-session
$ git diff --stat --name-only <コミットID A> <コミットID B>
```

ソースコードレビュー依頼時はファイル一覧を出力する必要があるので使用頻度高い。
iOS8でのsqliteファイルの格納場所

## iOS8でのsqliteファイルの格納場所

Xcode6 Beta版でCoreDataを使ったプログラムを作成中、sqliteファイルの格納場所が変更されていたのでメモ。
iOS8から？正式版は元に戻るのかな？

#### 以前の格納フォルダ
`Users/ユーザー/Library/Application Support/iPhone Simulator/iOSのバージョン/Applications/ランダムな識別子/Documents/`

#### 変更後
`Users/ユーザー/Library/Developer/CoreSimulator/Devices/ランダムな識別子/data/Containers/Data/Application/ランダムな識別子/Documents/`
PHPで同時実行を考慮したmkdirs

PHP標準のmkdirsだと、異なるプロセスやスレッドから新規に複数階層のディレクトリを同時に作成しようとすると後続のmkdirsがエラーになることがあった。
PHPのソースを確認したところ、タイミングによっては、先行するプロセスやスレッドで作成されたディレクトリを後続のプロセスやスレッドが同じディレクトリを作成しようとして失敗し、その結果エラーになる可能性があった。
そこで、ディレクトリ階層のmkdirで失敗してもディレクトリが存在する場合はエラーとしないようにコードを書いてみた。

## サンプルコード

```php:
const DIRECTORY_SEPARATOR = '/';

function mkdirs($path, $mode = 0777) {
  $dirs = explode(DIRECTORY_SEPARATOR, $path);
  $currentPath = '';
  foreach ($dirs as $dir) {
    $currentPath .= _joinDir($currentPath, $dir);
    if (!is_dir($currentPath) && !mkdir($currentPath, $mode)) {
      $error = error_get_last();
      if (!is_dir($currentPath)) {
        return false;
      }
    }
  }
  return true;
}

function _joinDir($currentDir, $dir) {
  if (strlen($dir) <= 0) {
    return DIRECTORY_SEPARATOR;
  }
  if (strlen($currentDir) <= 0 && 0 < strlen($dir)) {
    return $dir;
  }
  if ($currentDir == DIRECTORY_SEPARATOR) {
    return $dir;
  }
  return DIRECTORY_SEPARATOR .$dir;
}
```

## 参考

[同時実行に耐えうるファイル操作の方式検討 (mkdir システムコール直接発行等 · Issue #12 · ToshiyukiTerashita/castoro](https://github.com/ToshiyukiTerashita/castoro/issues/12)
.htaccessでUserAgent判定でファイルをリダイレクトさせる

UserAgentを見て、PCとSPの閲覧するファイルを変更する覚書。
ちょっと自信がないのでサーバーサイドの人がアドバイスくれると嬉しいです。＾＾

```
RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} (iPod|iPhone|iPad|Android|Windows.Phone)
RewriteRule ^index.html index_sp.html [L]
```
PerlでドメインのSSL証明書と中間証明書の有効期限を取得する方法

**Perl**と**Opensslコマンド**を利用して、対象となるドメインの**SSL証明書の有効期限**と**中間証明書の有効期限**を取得する方法のメモです。超ざっくり。
取得した結果を利用して監視なりに利用できるかなと思っています。

ちなみにPerlは初めて書いてみたのでちと後ほど綺麗に修正します‥。
また対象となるドメインはグローバルサインをとりあえず想定しています。

スクリプトはこんな感じ。

```perl:getYuukoukigen.pl
#!/usr/bin/perl

# フラグなどなど
$flgCert = "none";
$i = 0;

# opensslコマンドで証明書を取得
@certfile = `openssl s_client -connect [対象のドメイン]:443 -showcerts < /dev/null 2>/dev/null`;

# 取得した証明書からサーバ証明書と中間証明書を抽出
foreach my $certline (@certfile) {

        # 改行コードを除去
        $certline =~ s/\n//;

        # 証明書コードの始まりと終わりを検出
        if( $certline eq "-----BEGIN CERTIFICATE-----" ){
                $flgCert = "in"
        }elsif( $certline eq "-----END CERTIFICATE-----" ){
                $flgCert = "out"
        }

        # 証明書部分のみ配列に格納 (証明書と中間証明書の2種類あるのでそれぞれを格納)
        if( $flgCert eq "in" ){
                $cert[$i] = $cert[$i].$certline."\n";

        }elsif( $flgCert eq "out" ){
                $cert[$i] = $cert[$i].$certline."\n";
                $flgCert = "none";
                $i++;

        }
}

# サーバ証明書の有効期限情報を取得
$certdetail = `echo "$cert[0]" | openssl x509 -text | sed -e "/Not After/{s/^.* : //;p};d"`;
print "Server Cert -> ".$certdetail;

# 中間証明書の有効期限情報を取得
$chaindetail = `echo "$cert[1]" | openssl x509 -text | sed -e "/Not After/{s/^.* : //;p};d"`;
print "Chain Cert  -> ".$chaindetail;
```

本当はPHPでやりたかったんですけどね‥。
他の方法も探してみたいと思いますよ。
SSHしたVPC経由でNAT配下のDBに接続する

タイトル的に正しいのかイマイチ分かってないですが、DBへの接続が外部ネットワークから実行出来ず、間にVPCを挟んでいる時の接続です。

```bash
ssh -f -L 3306:END_POINT_OF_DB:3306 -N USER_NAME@END_POINT_OF_VPC -i KEY_FILE
```

`END_POINT_OF_DB`: 繋ぎたいDB
`END_POINT_OF_VPC`: 踏み台にしたいVPC
`KEY_FILE`: VPCにsshする時の鍵ファイル（鍵でアクセスするなら）

と言う感じでportfoward出来るみたいです。

## RからDBに接続する

繋ぎに行く前にportfowardしてやればおｋです

```r
openNatPortForward <- function(){
  system('ssh -f -L 3306:END_POINT_OF_DB:3306 -N USER_NAME@END_POINT_OF_VPC -i KEY_FILE')
}

closeNatPortForward <- function(){
  system("kill $(ps aux | grep 'ssh\\ -f\\ -L' | awk '{print $2}')")
}
```

DB使いたいときに`openNatPortFoward()`して接続先を開けてやって、使い終わったら`closeNatPortForward()`で閉じてます。閉じ方は余りいい方法が思いつかなかったのでプロセスをgrepして殺してます。

注意点としては、DBに接続する際は`localhost`ではなく`127.0.01`を指定しないと上手く行きませんでした。（RMySQLだと）

```r
ch <- dbConnect(dbDriver('MySQL'), host='127.0.0.1', dbname='DBNAME', user='USERNAME', password='PASSWORD', port=3306)
```

後はこのchを利用すれば、接続先はlocalhostではなくリモートになってます。
portが違う時とかは適宜変えて下さい。

他にいい方法があれば教えて( ﾟдﾟ)ﾎｽｨ…。
xmlrpc.phpへのアクセスが酷いので・・・


AWSで公開しているサーバが朝から何度かアクセス不能になった。

RDSへのアクセス過多という感じで、MySQLから接続を拒否されていたり、Webサーバが落ちたりしたので、ログを見ると、/xmlrpc.phpへのアクセスが酷い・・・

私自身が、MarsEditorからBlogを更新する為にしか使って無いxmlrpc.phpを有効にしているがために、攻撃を受けるのも嫌なので、/xmlrpc.phpに対するアクセスをApacheで弾くようにしました。

httpd.confに

```httpd.conf
<Location "/xmlrpc.php">
    Order allow,deny
    Deny from all
</Location>
```

と書いて、Apache再起動すれば、直ぐにWebサーバは落ち着きを取り戻しました。
RestSharp.Portable: Task<IRestResponse>をWait()できないのでTaskでラップする



URIをRestSharpでGETする:

```csharp

		public Task<IRestResponse> AsyncRestSharp(string uri)
		{
			var client = new RestClient (uri);
			var req = new RestRequest ("/", HttpMethod.Get);
			var res =  client.Execute (req);

			return res;
		}

```

		
TaskをWait()するとメインスレッドが止まってしまうダメな例(iOS)：

```csharp
		
		[Test]
		public void TestRestSharpWithTask()
		{
          　var call = AsyncRestSharp ("http://www.google.com");
			call.Wait ();
			Console.WriteLine( call.result.RawBytes.ToUtf8() );

		}		
```
		
		
さらに非同期TaskでラップしてWaitすると行ける
		
```csharp

		[Test]
		public void TestRestSharpWithTask()
		{

			var tcs = new TaskCompletionSource<string>();
			Task.Run (async () => {
				var res = await AsyncRestSharp("http://www.google.com");
				tcs.SetResult( res.RawBytes.ToUtf8());
			});
			tcs.Task.Wait();

			Console.WriteLine (tcs.Task.Result);
		}		
```
		

ちなみにToUtf8():

```csharp

	public static class Extensions
	{
		public static string ToUtf8(this byte[] src )
		{
			return System.Text.Encoding.UTF8.GetString (src);
		}
	}
```			

もうちょいコーディグが楽になるようなディレクティブとかできないかな。
boot2dockerでコンテナからホストのファイルを参照する

この投稿は古い内容です。Docker 1.3からはboot2dockerを利用していても何も考えずにホストマシンのボリュームをマウントできるようです。
[boot2dockerでのVolume問題が解決しそう | SOTA](http://deeeet.com/writing/2014/10/08/boot2docker-guest-additions/)

OSXやWindowsからdockerを利用する場合にはboot2dockerを利用します。しかし、boot2dockerがVirtualboxで動作する仮想マシンであるため、`docker run`の際、`-v`オプションでホストのディレクトリをマウントさせようとしても、boot2docker内のディレクトリを参照してしまうため、うまく行きません。

boot2dockerのアップデートでその辺りに対応をしたので、方法のメモ。

## 手順

[boot2docker#folder-sharing](https://github.com/boot2docker/boot2docker#folder-sharing)の情報です。

どうやら、`samba`サーバーとなるコンテナを動作させてsambaの共有フォルダをOSXやWindowsからマウントする方法を取るようです。


```bash
$ docker run -v /data --name my-data busybox 
$ docker run --rm -v /usr/local/bin/docker:/docker -v /var/run/docker.sock:/docker.sock svendowideit/samba my-data
$ boot2docker ip
192.168.59.103
$ docker ps
4aac758ea300        svendowideit/samba:latest   /setup.sh --start my   About an hour ago   Up About an hour    0.0.0.0:137->137/tcp, 0.0.0.0:138->138/tcp, 0.0.0.0:139->139/tcp, 0.0.0.0:445->445/tcp   samba-server         
```

`svedowideit/samba`なるコンテナが動作していることを確認したら、OSXの場合はfinderから`cifs://192.168.59.103`へ、Windowsの場合はExplorerから`//192.168.59.103`に接続します。

`/data`ディレクトリをGuestでマウントします。

OSXなら`/Volumes/data`、Windowsなら`//192.168.59.103/data`に置いたファイルを他のDockerコンテナから参照できるようになりました。

他のDockerコンテナからファイルを参照する際には、コンテナ起動時に


```bash
$ docker run --volumes-from my-data centos su -
```


のように`--volumes-from`を指定してあげると良いようです。

これは便利。
EntourageからOutlook2011への移行メモ

Outlook2011のインストールからメモっていくよ！

#インストール
PCでCD-Rを読み、インストールディスクを起動し、インストールします。
10分くらいかかります。

1. ブラウザやOffice系アプリを閉じるよう指示があります。
2. プロダクトキーを入れます。

#エクスポート
Entourage＞Entourageのバージョンを選びます。私の場合は2004でした。

- フォルダやアドレス帳、署名（署名は消えることもある様子）全て問題なくインポートできます。
- フォルダの振り分け（ルール）が効かない？一度編集を押して、フォルダを選択し直すと直りました。
- 今までフォルダに表示されていたフラグの有無が表示されないみたい？
- 改行やコピペがおかしくなるときがある
- 標準だと既読にするには、メールを開く必要があります
- リンクが改行すると、途中で切れちゃう

#標準のメールフォーマットを変更する。
そのままだとHTMLメールなので、
環境設定＞作成＞「既定では、HTMLメールでメッセージを作成する」のチェックをはずします。
新規作成時にオプションで、書式をテキストにします。

#メールを閲覧ウインドウに出したら、既読にする
環境設定＞表示＞「メールを開封済みにする」で「次の時間閲覧ウインドウに表示されたときXX秒」をチェックして、秒数を設定します。
２秒にしてみました。

#受信したメールの文字化けを直す
ルール＞ルールの編集＞POP＞＋から文字化けするメールの振り分けをします。
差出人などでメールを指定し、「文字セットを変更」で変更したい文字コードを指定します。
すでに受け取ったメールはこれで直らないのですが、設定したあとメールを受け取ると文字化けが直ります。

##すでに受け取ったメールの文字化けを直す
メールを選択して
書式＞エンコード方法＞エンコードの種類を指定します。
一度別のメールに移動した後に戻ると、文字化けが直ります。
Qiita投稿しているみなさんにぜひ



Qiitaを書いていて他のページ情報を引用したい時（に限らず本当に色々な場面で）、
webページのタイトルやURLをコピペする作業が発生すると思います。

これが発生頻度多い割に面倒（※）なので何かツール作ろうと思ったら、もう便利なものがありました。

※ URLだけなら`Cmd+L,C`でokですが。


### Chrome

Copy Fixer
https://chrome.google.com/webstore/detail/copy-fixer/gkpoieconkiifjafemnnohlegmfpipaa


### FireFox

Copy Fixer :: Add-ons for Firefox
https://addons.mozilla.org/ja/firefox/addon/copy-fixer/


任意のページを開いた上で
・何も選択しない状態で`Ctrl+C`もしくは`Cmd+C`
で、ページのタイトルとリンクをコピー出来ます。


他にも似たものはありましたがコマンド（ショートカット）で完結できるこれが良さそうでした。
先人に感謝！

みなさんのQiita&Kobitoライフがちょっと捗りますように。
MySQLでのSlowLogの分析方法

# 概要

サービス開発/運用中に性能問題が発生した際に、DBのSlowLogを見るのは非常に有効なアプローチです。

SlowLogの出し方はRDBMS毎にやり方がありますが、特にMySQLでは単純に遅いQueryを出力するだけでなく、データが取得しやすいようにSlowLogをサマるためのツールが付属しています。

今回はそのツール`mysqldumpslow`の使い方を紹介します。

## SlowLogから分かること
- SlowLogが出ていない場合、性能問題の原因がDBではない事。
- SlowLogが出ている場合、どのQueryが性能問題を引き起こしているのか。
- 出力されるQueryの閾値をゼロとして全Queryを出力させると、Query毎の登場頻度も確認可能。


# mysqldumpslowの使い方

## 準備
この手順では以下の物が必要となります。

1. 分析対象のSlowLog
    - リードレプリカを作ってる場合、複数のDBサーバのSlowLogを以下のように結合して、1つのファイルにまとめてもOK。
        - `cat file1.log >> file2.log`
    - 同じログを何回も分析してもしょうがないので、事前に以下のようにして切り回しておくのがオススメです。
        - `cat ${TARGET_FILE} > ${TARGET_FILE}.${DATE}; echo "" > ${TARGET_FILE}`
        - 分析用には`${TARGET_FILE}.${DATE}`を利用します。

1. `mysqldumpslow`がインストールされている環境
    - Linux系でmysqlクライアントがインストールされていればだいたい入ってます。
        - mysqlサーバがインストールされてなくても大丈夫。

## 手順

以下のコマンドを実行するだけです！

```bash:
$ mysqldumpslow -s t ${SlowLogファイル} > ${出力先ファイル}
```

結果は標準出力に出てしまうので、上記のようにファイルにリダイレクトしてください。

`-s`の部分は結果の表示順を制御しています。設定できる主な値は以下の通りです。

- `at` Queryの平均実行時間
- `c` Queryの出現回数
- `ar` Query内で取得/更新した合計レコード行数
- `t` Queryの合計実行時間

他にもgrepやhost名の指定など便利なオプションがあるので、使いたい人は`--help`してみてください。

## 出力の見方

`mysqldumpslow`の出力は以下のような形になります。
ここに記載しているのは1Query分なので、この出力がQueryの種類の数だけ表示されることになります。
(表示順は、前述のパラメータで指定します。)

```sql:mysqldumpslowの実行結果(Query1種類分)
Count: 100  Time=0.50s (48s)  Lock=0.00s (0s)  Rows=1.0 (100), user[user]@[192.168.1.2]
  SELECT
  *  
  FROM
  student
  WHERE
  name = 'S'
  AND
  weight > N
```

1行目がサマリ情報です。出力の意味は以下の通りです。

- `Count:` 出現回数。
- `Time:` 平均実行時間。カッコの中は、合計実行時間。
- `Lock:` がテーブルをロックした平均時間。カッコの中は合計ロック時間。
- `Rows:` 読取り/更新したレコード数の平均。カッコの中は合計。
- `user[user]@[192.168.1.2]` アクセス元。

2行目以降は、実際のQueryです。
文字列や数値のパラメータはすべて、`N`と`S`で抽象化されて合算されているのがポイントです。

使い方については以上です。

# おまけ

SlowLogはサービスインした後は監視の対象とするなど、**出ない事が前提**となる事が多いと思います。

しかし、開発中は、あえて`long_query_time = 0`として全QueryをSlowLogに出力させるようにしておくと、`mysqldumpslow`を使ってDBのボトルネックが明らかに出来るのでお勧めです(古いのはどんどん捨てないとディスクを圧迫するので、ご注意を…)。
後は、その結果を日次でメールかチケットで送るようにしておくと便利ですね。
学生・生徒のうちに参加、挑戦しておきたいイベントやコンテスト(2014年度)

# 本記事を読む前に
本記事の中には既に応募期間が過ぎているコンテスト、イベントがあります。
それらについては、来年以降の参考としてください。
また、本記事に載っていない学生・生徒向けのコンテストやイベントがあればぜひコメント欄にて教えてください。

# プログラミングコンテスト
## U-22プログラミングコンテスト2014
### 公式サイト
http://www.u22procon.com
### 概要
本コンテストは、「日本のプログラミング学習熱を高めよう」をコンセプトに、自らプログラミングを学び、日本の未来を創る若者を応援するために開催される、歴史あるプログラミング・コンテストです。
### 参加資格
日本国内に居住する西暦1992年4月2日以降に生まれた方
### 応募期間
2014年7月1日(火) ～ 2014年8月22日(金)　午後5時必着

## パソコン甲子園2014
### 公式サイト
http://web-ext.u-aizu.ac.jp/pc-concours/
### 概要
全国の高校生及び高等専門学校生等が、情報処理技術における優れたアイディアと表現力、プログラミング能力等を競い合うことにより、生徒自身のスキルアップを図るとともに、情報化社会を支える人材の裾野を広げることを目的として開催します。
### 参加資格
平成26年度において、日本国内の高等学校及び高等専門学校の3年生まで並びにこれらと同等と認められる学校の者。
### 応募期間
2014年5月12日(月) ～ 2014年7月31日(木)

## あいちゃれ2014
### 公式サイト
http://www.ict-challenger.jp
### 概要
ジャンル不問、開発言語不問，実行環境不問のソフトウェア創作コンテストICT Challenge+R(正式名称： あいちゃれ)は、高校版と大学版(大学生・大学院生)の二本立てで同時開催します。
### 参加資格
#### 高校版
開催年度において、高等学校及び高等専門学校の3年生まで、またこれらと同等と認められる学校の在学生
※国籍は問いません。
※個人・グループのいずれも可とします(グループの場合は、3名までとし、メンバー全員が上記参加資格を満たしている必要があります)。
#### 大学版
開催年度において、大学もしくは大学院に在学しているもの。
個人・グループのいずれも可とします(グループの人数に上限はありませんが、代表者が上記資格を満たした上でメンバー全員が上記参加資格若しくは 25 歳未満の条件を満たしていること)。
※18歳以上の専門学校や高等専門学校など大学相当と考えられるものについても応募可能とします。
### 応募締切
2014年10月13日(月)

## Digital Youth Award
### 公式サイト
https://digitalyouth.jp
### 概要
ITスキルを活かした起業・就職を目指す学生たちが、コンテストを通じてスキルアップすることを目指す。
スキルアップを支援するプログラムとして、学ぶ機会としてのCollege(参加型ワークショップ、座学形式のセミナー、オンラインコンテンツなど)と指南を受ける機会としてのMentorshipを提供。次世代を担う創造力に富んだ人材の創出を支援する。
### 参加資格

* 専門学校・専修学校・高等専門学校・大学に登録されている16歳から29歳までの学生
* 個人もしくは4人までのチーム

### 応募期間
2013年11月18日(月) ～ 2014年3月10日(月)

## 天下一プログラマーコンテスト2014
### 公式サイト
http://tenka1.klab.jp/2014/
### 概要
「天下一プログラマーコンテスト」はガチンコの競技プログラミングコンテストです。今年もジャッジシステムや問題の作成・監修にAtCoder社が全面協力。
最強最速アルゴリズマーは誰だ！？
### 参加資格

* 日本在住
* 学生(中、高、高専、専門、短大、大学、大学院)または既卒3年以内の未就業者
* 天下一プログラマーコンテスト2014において、未だ本戦参加資格を得ていない

### 日程
#### 予選
予選A: 2014/8/9(Sat)　21:00-23:00
予選B: 2014/8/23(Sat)　21:00-23:00
#### 本戦
2014/9/6(Sat)

# その他
## セキュリティ・キャンプ全国大会2014
### 公式サイト
http://www.security-camp.org
https://www.ipa.go.jp/jinzai/camp/2014/zenkoku2014.html
### 概要
4泊5日の合宿形式で行う、サイバ－セキュリティの知識と技術を学ぶキャンプです。
キャンプにかかる費用はすべて主催者側で負担させていただきますので、参加者は無料でご参加いただけます。
### 参加資格
日本国内に居住する、22歳以下の学生・生徒(2015年3月31日時点の年齢)
### 応募締切
2014年6月16日(月)　17:00必着

## SANS NETWARS Tournament 2014
### 公式サイト
http://www.nri-secure.co.jp/event/2014/netwars.html
### 概要
本イベントは、SANS Instituteの協力の下、最先端の情報セキュリティのトピックと世界基準のセキュリティトレーニングを若い世代の皆さまに体感してもらい、自身のスキルアップに役立てるとともに、情報セキュリティへの関心を深めてもらうことを目的としたイベントです。
### 参加資格

1. 未就業の学生であること。(ご本人確認のため、学生証のコピーなど証明書等を提出していただく場合があります。)
2. イベントの全日程2日間を通して参加できること。(1日目のトレーニングのみの参加、2日目のNETWARSトーナメント（CTF）のみの参加はできません。)
3. 情報セキュリティに興味があること。

### 応募締切
2014年8月5日(火)　18:00(JST)
Git submoduleで別プロジェクトのassetsを使いまわす


あ、どうも。

# 経緯

とあるプロジェクトで、別のプロジェクトで使っていたSassのファイルと画像ファイルを使いまわせないか、という話が持ち上がった。
やり方はいくつかありそうだけど、ここはあえて勉強も兼ねて、`git submodule`を使ってみよう、ということになった。

ちなみにいくつかの他の案は以下のとおりだ。

- そもそも使いまわさない
- コピペ

使いまわしたいと言っているのに使いまわさないとかトンチが効いてるし、コピペは死ねと思ってるので、やっぱり最初から解決策は一つしか無かったらしい。無念。

# git submodule add

まず、自分がいるリポジトリのRailsアプリのどこにsubmoduleを突っ込むのかを考えた。
多分vendorだな、ということで、以下のようなファイル構成にしてみた。

```plain
/vendor/assets/other_product
```

早速submoduleを追加しよう。

```sh
$ git submodule add git@github.com:hoge/other_product.git vendor/assets/other_product
```

すると、良く分からないファイルが生成されるはずだ。

- vendor/assets/other_product
- .gitmodule

これらはsubmoduleに関する情報を持っていて、`vendor/assets/other_product`の方はaddした別リポジトリへの参照になっている。
そして`.gitmodule`の方には、追加したsubmoduleに関する情報（具体的にはリモートリポジトリはどこなのかとか、リポジトリ名とか、現在のリポジトリの何処に配置したかとか）が書いてある。

# Railsに読み込ませる

実はここまででもうほぼ終わっている。後はAsset Pipelineのpathsにsubmoduleの中のassetsを追加するだけだ。

```ruby:config/application.rb
module Product
  class Application < Rails::Application
    ...
    ...

    %w(images stylesheets).each do |dir|
      config.assets.paths << Rails.root.join("vendor/assets/other_product/app/assets/#{dir}")
      config.assets.paths << Rails.root.join("vendor/assets/other_product/vendor/assets/#{dir}")
    end
  end
end
```

だいたいこんな感じ。

# まとめ

異なるリポジトリ間で何かを共有したかったりする時に、上位存在を作ってそいつをsubmoduleで読み込んでやるのはある意味得策かもしれないなぁ、とか思った。
でも一番いいのはgemにすることだと思うんだよね！！`bootstrap-sass`みたいにさ！！
CloudStackでインスタンス作成時に自動パス systemdの件

ユーザー会で使用したスライドにコードが収まらなかったから
Qiitaに上げてたんだけど、ベタ書きのまま放置は酷いと思うので手直し。

CentOS 7ではsystemdが導入されているので、サービスの管理が従来CentOSと大きく変わっております。
詳しい内容は解説されているサイト拝見して頂くとして、パス管理で使用する記述内容を紹介します。

```shell-session:cloud-set-client-password.service
# vim /etc/systemd/system/cloud-set-client-password.service
```
```sh
[Unit]
Description=CloudStack Password Modification Script
Requires=NetworkManager-wait-online.service
After=NetworkManager-wait-online.service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/cloud-set-guest-password
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
```
CloudStackでインスタンス作成時に自動パス生成スクリプト

ユーザー会で使用したスライドにコードが収まらなかったから
Qiitaに上げてたんだけど、やっぱり今見ても放置は酷いですねと思うので手直し。

CloudStack公式ドキュメントにある http://cloudstack.org/dl/cloud-set-guest-password は
相変わらずリンク切れ中。やる気を感じます。
cloud-set-guest-password script等でググるとたくさん出てきますので、
そちらをベースにGETして流用していきます。

+ GETしたcloud-set-guest-passwordを編集。

DHCP_FILESの箇所をCentOS7用にするといい感じ。

```sh
DHCP_FILES=`find /var/lib/NetworkManager/ -type f -name \*lease` 
```
+ 実行権限の付与とファイル移動

```sh
chmod +x cloud-set-guest-password

mv cloud-set-guest-password /usr/local/bin/
```
```sh
# vim /usr/local/bin/cloud-set-guest-password
```

```sh:cloud-set-guest-password
#!/bin/bash
#
# Init file for Password Download Client
#
# chkconfig: 345 98 02
# description: Password Download Client

# Modify this line to specify the user (default is root)
user=root
# Add your DHCP lease file here
DHCP_FILES=`find /var/lib/NetworkManager/ -type f -name \*lease`

for DHCP_FILE in $DHCP_FILES
do
        if [ -f $DHCP_FILE ]
        then
                DOMR_IP=$(grep dhcp-server-identifier $DHCP_FILE | tail -1 | awk '{print $NF}' | tr -d '\;')
                break;
        fi
done

password=$(wget -t 3 -T 20 -O - --header "DomU_Request: send_my_password" $DOMR_IP:8080)

if [ $? -ne 0 ]
then
        exit 1
fi

password=$(echo $password | tr -d '\r')

if [ -n "$password" ] && [ "$password" != "bad_request" ] && [ "$password" != "saved_password" ]
then
        echo $password | passwd --stdin $user
        if [ $? -gt 0 ]
        then
                usermod -p `mkpasswd $password 42` $user
                if [ $? -gt 0 ]
                then
                        exit 1
                fi
        fi
        wget -t 3 -T 20 -O - --header "DomU_Request: saved_password" $DOMR_IP:8080
fi

exit 0
```

* systemdにてサーバ起動時のcloud-set-guest-password自動起動化の設定

1. このコマンドでエラーが出なければOKです。
systemctl enable cloud-set-guest-password


1. エラーが出た場合、次のコマンドで状態確認が可能です。
systemctl status cloud-set-guest-password
問題がなければ起動の確認が出来ます。
systemd[1]: Started CloudStack Password Modification Script.
HTMLパーサーメモ

HTMLのテキスト部分だけを抜き出したいとか、特定タグの内容を抽出したいとかいうことを実現するものは、HTMLパーサーと呼ぶらしい。
ライセンス含めて使えそうなのを参考からピックアップする。

## 検討結果

2014-07-31時点で jsoup が良いんじゃないかと思った。
MITライセンスなのと、パーサー機能、使い方も悪くなさそう。最終更新日も割と最近。

## 参考

* [Comparison of HTML parsers](http://en.wikipedia.org/wiki/Comparison_of_HTML_parsers)  
  テーブルでの比較
* [Javaで実装されたHTMLパーサの性能や使い勝手を比べてみるよん | 世界はどこまでもシンプルである](http://daipresents.com/2009/java_html_parser/)  
  たくさんのライブラリへのリンク
* [2007/08/23 日記: Javaで実装された HTML Parser (HTMLパーサ) を調べてみました](http://homepage2.nifty.com/igat/igapyon/diary/2007/ig070823.html)  
  テーブル形式でライセンスまで掲載
* [JavaのHTMLパーサー色々 - ドナドナごとごと](http://d.hatena.ne.jp/TaRO/20110314/1300071165)  
  サンプル付きでリンク紹介（jsoup,NekoHTML,Jericho,HtmlCleaner）
* [メモ捨て場: html parser for GAE](http://hidemon-memo.blogspot.jp/2009/12/html-parser-for-gae.html)
fluentdで集めたログをlogentriesで監視

(2014/08/01 大幅編集しました)
[epeatedly](http://qiita.com/repeatedly)さんからコメントにて`symlink_path`の存在を教えて頂きましたので、大幅修正しました。ありがとうございます！

##fluentdで集めたアクティブなログに固定パスでアクセスできるように

[symlink_path](http://docs.fluentd.org/articles/out_file#symlinkpath)という設定が用意されているのでこちらを使います

```
<source>
  type forward
  port 24224
  bind 0.0.0.0
</source>

<match **.messages>
  type file_alternative
  path /var/log/servers/messages.*.log
  buffer_type file
  buffer_path /var/log/servers/messages.buf
  symlink_path /var/log/servers/messages
  time_slice_format %Y%m%d
  output_include_time false
  output_include_tag true
  output_data_type attr:message
  add_newline true
</match>
```

設定で`symlink_path`を指定すれば現在アクティブなバッファへのシンボリックリンクを作成してくれます。
`symlink_path`を使うには`buffer_type`がfileである必要があり、`buffer_type`がfileの場合は`buffer_path`が必要なので併せて設定。

上記の例でログを集約するとアクティブなログのファイル名はハッシュがついたものとなりますが、そのファイルへのシンボリックリンクも同時に作成されます。

```
messages.buf.20140715.b4ff51f1d0a78b272.log
messages -> /var/log/servers/messages.buf.20140715.b4ff51f1d0a78b272.log
```

このシンボリックリンクはtime_sliceされたりflushされたりして、アクティブなログのファイル名に変更がある度にリンク先を変更してくれるので、単純に一つのパスを指定すれば新しく届いたログを監視する事ができるようになります

##logentriesでの設定

あとはlogentriesのleコマンドでシンボリックリンクのファイルをfollowすればOKです

```
le follow "/var/log/servers/messages"
```

これでログがsliceされて別名になってもログの監視を続ける事ができました

##余談

`symlink_path`を教えて頂くまでは以下のような設定をしてました。

```
le follow "/var/log/servers/messages.*.*.log"
```

ファイル名の一部が変わる場合は以下のようにアスタリスクを設定すればOKでした。
が、fluentd側で対応できるならその方がいいと思います。
iOS公式ドキュメントの場所

## Apple 公式ドキュメント

必要最小限のドキュメントへのリンク

* [日本語ドキュメント - Apple Developer](https://developer.apple.com/jp/devcenter/ios/library/japanese.html)
* [iOSヒューマンインターフェイスガイドライン: UI設計の基本事項](https://developer.apple.com/jp/devcenter/ios/library/documentation/userexperience/conceptual/mobilehig/basicspart/basicspart.html)
* [iOS 7に移行する準備](https://developer.apple.com/jp/devcenter/ios/library/documentation/UserExperience/Conceptual/TransitionGuide/PlanningPart/PlanningPart.html)
Windows7で，TeX MAKER＋TeX LiveでTeXの執筆環境を構築する．

TeX Live 2014とTeX MAKERでTeXの執筆環境を構築してみました．
色々と調べながら作業したので，忘れないようにメモ．
目標は，奥村先生の jsarticle 等を使ってレポートが書けること．

#1. TeX Liveのインストール

http://oku.edu.mie-u.ac.jp/~okumura/texwiki/?TeX%20Live#j0ebf49b
から適当なミラーサーバーを選んで，install-tl.zipをダウンロード．
適当に伸長して，install-windows.batを実行．
待つ！
インストールが正しく終わればオッケー．
終わらなければググって頑張る．
コンソールで，uplatexとか，もろもろのコマンドが使えるか確かめておく．
これがちゃんと通ればオッケー．

#2. TeX MAKERのインストール

http://oku.edu.mie-u.ac.jp/~okumura/texwiki/?Texmaker#q69dea61
ここから探しだして，TeXMAKERの最新版をダウンロード．
日本語化したい人はさっきのサイトで調べて日本語化プラグインのあるバージョンをダウンロード．
で，適当にインストール．

#3. TeX MAKERの設定

http://oku.edu.mie-u.ac.jp/~okumura/texwiki/?Texmaker%2F%E8%A8%AD%E5%AE%9A%2FWindows
このあたり見て適当に設定．
![スクリーンショット 2014-07-31 11.18.31.png](https://qiita-image-store.s3.amazonaws.com/0/49886/54452959-18d6-3c8c-3331-1bb53108fdc1.png)

注意することは，
クイックビルドの設定．
![スクリーンショット 2014-07-31 11.20.01.png](https://qiita-image-store.s3.amazonaws.com/0/49886/65c00952-7308-0626-6506-3268d885129c.png)

LaTeX + dvips + ps2pdf + View PDFとか，最初はLaTeXでタイプセットしてあげないと，
日本語が入っていたりするTeXファイルとか，jsarticleとかがちゃんとタイプセット出来ない．

#4. 書き始める
とりあえず，物理のかぎしっぽさん
http://hooktail.org/computer/index.php?TeX%A5%C6%A5%F3%A5%D7%A5%EC%A1%BC%A5%C8
からテンプレートを拝借してコピペ．

```lang:index.tex
\documentclass[12pt,a4paper]{jsarticle}
```
のところ，UTF-8を使う関係で，
```lang:index.tex
\documentclass[uplatex,12pt,a4paper]{jsarticle}
```
に書き換えるとだいたいオッケー．
![スクリーンショット 2014-07-31 11.33.09.png](https://qiita-image-store.s3.amazonaws.com/0/49886/386a109f-6d38-596a-2590-f45479ee3b4f.png)
AccessVBAでADOを使用しテーブルからデータを取得する

# 概要
AccessVBAでADOを使う

# 説明
ADOでは、コネクション(DB)とレコードセット(SQL)を使用する。

## コネクション ( ADODB.Connection ) 
接続するデータベースを設定する

## レコードセット ( ADODB.RecortSet ) 
SQLを実行し、データを取得する

# サンプル
SQLを実行し出力結果を表示する

```vbnet
Sub sample()
    Dim rs As New ADODB.Recordset
    
    ' SQLを作成
    rs.Open "select * from table", CurrentProject.Connection
    
    With rs
        Do Until .EOF
            Debug.Print "------"
            For i = 0 To .Fields.Count - 1
                Debug.Print .Fields(i).Name & ": " & .Fields(i).Value
            Next
            .MoveNext
        Loop
    End With

    ' 終了処理
    rs.Close

End Sub
```
WindowsとMacでなるべく差異なく環境構築したい。

今までWindows使ってたけどMac使ってみようかな？
今までMacだったのに転職したらWindows使うことになった。
っていう人のための対応表を思いつく限りで書き出してみた。


##対応表

| 種別　　               | Windows                   | Mac                   |
|-----------------------|---------------------------|-----------------------|
| IDE                   | [Netbeans](https://netbeans.org/) | [Netbeans](https://netbeans.org/) |
|                       | [eclipse](https://www.eclipse.org/) | [eclipse](https://www.eclipse.org/) |
|                       | [IntelliJ IDEA](http://www.jetbrains.com/idea/) | [IntelliJ IDEA](http://www.jetbrains.com/idea/) |
|                       | - (※)                    | [XCode](https://developer.apple.com/jp/technologies/tools/) |
| Editor                | [Sublime text](http://www.sublimetext.com/3) (※) | [Sublime text](http://www.sublimetext.com/3) |
|                       | [サクラエディタ](http://sakura-editor.sourceforge.net/) | [CotEditor](http://coteditor.github.io/) |
| パッケージ管理システム   | -                         | [Homebrew](http://brew.sh/) |
|                       | [Chocolatey](https://chocolatey.org/) | [Homebrew cask](http://caskroom.io/) |
| ドキュメントブラウザ     | [zeal](http://zealdocs.org/) | [dash](http://kapeli.com/dash) |
| ランチャ                | [Wox](http://www.getwox.com/) | [alfred](http://www.alfredapp.com/) |
|                        | [iceberg](http://yuin.github.io/iceberg/) | [alfred](http://www.alfredapp.com/) |
| Gitクライアント         | [Git for Windows](http://msysgit.github.io/) ([msysGit](http://msysgit.github.io/)) | [Git](http://git-scm.com/) |
|                       | [GitHub for Windows](https://windows.github.com/) | [GitHub for Mac](https://mac.github.com/) |
|                       | [SourceTree](http://www.sourcetreeapp.com/) | [SourceTree](http://www.sourcetreeapp.com/) |
| SSH                   | [Tera Term](http://sourceforge.jp/projects/ttssh2/) | terminal              |
| SCP                   | [WinSCP](http://winscp.net/) | terminal              |
| CLI shell             | [cmder](http://bliker.github.io/cmder/) (※) | terminal              |

##注釈

### Sublime text

Windows版のSublime Textは日本語入力に若干の不備があるのでIME Supportというプラグインを入れたほうがよいです。
https://github.com/chikatoike/IMESupport

### XCode

Mac appやiOS App開発用という意味で言えばWindowsには代替するものはないと思います。
ほかの目的でなら別のIDE使えば対応可能です。

### cmder

cygwinみたいなxNIXライクなCLIシェルエミュレータです。
見た目も性能もcygwinとかより断然いいのですが、まだ若干不安定なところがあったり
英語以外の言語の取り扱いに癖があったりするのでそこさえ改善されればかなりよくなりそうな感じです。
MacからWindowsになったユーザの方にはお勧めします。
cmderがあればsshやscpも別途アプリケーションをインストールする必要ないです。
パーティショニングされたディスクイメージファイルのmount方法

fsiskで情報確認

```shell-session
usr@host # fdisk -lu vm3-boot
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000babc7

   Device Boot      Start         End      Blocks   Id  System
vm3-boot1   *        2048      524287      261120   83  Linux
Partition 1 has different physical/logical beginnings (non-Linux?):
     phys=(0, 32, 33) logical=(6, 46, 1)
Partition 1 has different physical/logical endings:
     phys=(32, 162, 2) logical=(1608, 39, 2)
```

→start位置=2048 に512を乗じたもの(2048*512=1048576)offsetとして、以下のようにmount

```shell-session
usr@host # mount -o loop,ro,offset=$((2048*512)) /vol1/kvm/vm3/vm3-root /mnt
```
javascript / jQuery の $.proxy で setTimeout() の this を指定する

javascriptのインスタンスメソッドをsetTimeout()のコールバックにしたかったのでググったところ、クロージャ使ってねというものが多かったのでメモしました。

課題は、ハンドラが呼ばれるときにthisがwindowオブジェクトやHTML要素など呼び元のコンテキストになるので、インスタンスメソッドおよびコールバックとして併用したインスタンスメソッドで不都合があるということでした。

解決はthisとインスタンスメソッドを引数にとる関数オブジェクトを介して呼ぶことで、jQueryではイベントハンドラやsetTimeout()にthisをささっと持ち込むための $.proxy があるので、そちらを使っても楽でした。

```js
MyClass.prototype.otherMethod = function() {
  this.method();
  setTimeout( $.proxy(this.method, this), sec*1000 );
}

MyClass.prototype.method = function() {
  this.my_attr = 'awesome!';
}

```
復習: Running Kubernetes Example on CoreOS, Part 1

Running Kubernetes Example on CoreOS, Part 2
https://coreos.com/blog/running-kubernetes-example-on-CoreOS-part-2/
が出たので、

Running Kubernetes Example on CoreOS, Part 1
http://coreos.com/blog/running-kubernetes-example-on-CoreOS-part-1/
を最新状態で、おさらいをしてみました。

```rb:Vagrantfile
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "yungsang/coreos"

  config.vm.provision :shell do |s|
    s.inline = <<-EOT
      git clone https://github.com/kelseyhightower/kubernetes-coreos.git

      sudo cp kubernetes-coreos/units/download-kubernetes.service /etc/systemd/system/

      sudo cp kubernetes-coreos/units/apiserver.service /etc/systemd/system/
      sudo cp kubernetes-coreos/units/controller-manager.service /etc/systemd/system/
      sudo cp kubernetes-coreos/units/kubelet.service /etc/systemd/system/
      sudo cp kubernetes-coreos/units/proxy.service  /etc/systemd/system/

      sudo systemctl start etcd

      sudo systemctl start download-kubernetes

      sudo systemctl start apiserver
      sudo systemctl start controller-manager
      sudo systemctl start kubelet
      sudo systemctl start proxy
    EOT
  end
end
```

```json:redis.json
{
  "id": "redis",
  "desiredState": {
    "manifest": {
      "version": "v1beta1",
      "id": "redis",
      "containers": [{
        "name": "redis",
        "image": "dockerfile/redis",
        "ports": [{
          "containerPort": 6379,
          "hostPort": 6379 
        }]
      }]
    }
  },
  "labels": {
    "name": "redis"
  }
}
```

```
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'yungsang/coreos'...
.
.
.
==> default: Running provisioner: shell...
    default: Running: inline script
==> default: Cloning into 'kubernetes-coreos'...
==> default: Checking connectivity...
==> default: done
$ vagrant ssh
   ______                ____  _____
  / ____/___  ________  / __ \/ ___/
 / /   / __ \/ ___/ _ \/ / / /\__ \
/ /___/ /_/ / /  /  __/ /_/ /___/ /
\____/\____/_/   \___/\____//____/
(stable 367.1.0)
core@localhost ~ $ kubecfg -h http://127.0.0.1:8080 -c redis.json create /pods
I0730 23:03:58.785787 00732 request.go:220] Waiting for completion of /operations/1
I0730 22:37:09.176985 00741 request.go:220] Waiting for completion of /operations/1
I0730 22:37:29.180205 00741 request.go:220] Waiting for completion of /operations/1
.
.
.
Name                Image(s)            Host                Labels
----------          ----------          ----------          ----------
redis               dockerfile/redis    /                   name=redis

core@localhost ~ $ kubecfg -h http://127.0.0.1:8080 list /pods
Name                Image(s)            Host                Labels
----------          ----------          ----------          ----------
redis               dockerfile/redis    127.0.0.1/          name=redis

core@localhost ~ $ 
```
wercker + docker + test-kitchen


タイムアウトをデフォルトの5分から10分に延ばす
5分の場合、`bundle install`でこける


```yml:wercker.yml
box: wercker-labs/docker
no-response-timeout: 10
build:
  steps:
    - script:
        name: rvm install
        code: |
          sudo apt-get update -y
          curl -sSL https://get.rvm.io | bash -s stable
          source $HOME/.rvm/scripts/rvm
          rvm install 2.0.0 --default
          echo "gem: --no-rdoc --no-ri" >> $HOME/.gemrc
    - rvm-use:
        version: 2.0.0
    - bundle-install
    # - script:
    #     name: docker pull
    #     code: |
    #       docker pull tianon/centos:6.4
    #       docker pull tianon/centos:6.5
    - script:
        name: kitchen test
        code: |
          bundle exec kitchen test

```
photo flow 〜写真管理の流れを見直してみました〜

> （お詫び）この投稿は「プログラミングに関する知識を記録、共有する最適なサービス」「プログラマのための技術情報共有サイト」という本来の Qiita のスコープからは、少しはずれている内容かもしれません。
> Google 好きな 1開発者が思いついた「写真管理方法のご紹介」です。

## きっかけ

ハードディスクに保存していた過去の写真が、気がつくと壊れて開けなくなっていました。
別のディスクへバックアップしていたので復旧はできたのですが、バックアップ自体が煩わしく感じていました。

* もう自前で用意したハードディスクが壊れる心配をしたくない。
* バックアップをとる作業から開放されたい。
* カメラからパソコンへ写真を取り込む作業も簡単にしたい。

## photo flow

そこで、写真の流れを見なおして見ました。

![photoflow.png](https://qiita-image-store.s3.amazonaws.com/0/31521/217a4200-615c-5086-5a9b-5216f066bd52.png)
（上の図は、[Cacco × IKONS](http://qiita.com/noc06140728/items/657766da4b7689e8cac0) で描いています）

### 流れの中のポイント

1. Eye-Fi mobi でカメラで撮った写真は、自動でスマートフォンへ転送されます。メディアの抜き差しは必要ありません。
2. スマートフォンの写真は、Google+ の「写真」へ自動バックアップされます。同一アカウントのタブレットなどで閲覧もできます。
3. Google+ の「写真」は Google ドライブの容量を消費しますが、「標準サイズ(長辺が2048ピクセル)」でバックアップするように設定すれば、無料で無制限に保存することができます。
4. スマートフォンのアプリ等から、写真の印刷を注文することができます。もう自宅にプリンタは不要です。自宅への配送以外にコンビニで印刷できるサービスもあるようです。上記の「標準サイズ」でも、一般的な Lサイズ の印刷であれば、問題ないハズです。（未検証）

## まとめ

Eye-Fi から Google+ への自動連携はとても快適です。最近では、Google から「[ストーリー](https://support.google.com/plus/answer/6029803?hl=ja)」という写真を編集・整理してくれるサービスも新しくリリースされているので、一度試してみてはいかがでしょうか？
Firefox一筋なWEBプログラマが手放せないプラグイン一覧

・firebug
https://addons.mozilla.jp/firefox/details/1843
使い慣れてしまったので手放せません。AJAXのデバッグや読み込み状況を簡単に把握できるのでやっぱり便利です。

・Web Developer
http://chrispederick.com/work/web-developer/
JavaScript実行後のソースを見ることもできて、便利。

・Screenshoter Fixed
https://addons.mozilla.org/ja/firefox/addon/screenshoter-fixed/?src=api
ブラウザのウィンドウサイズに関わらず、ページ全体のスクリーンショットがとれる。

・User Agent Switcher
UA切り替え

・HostAdmin
開発サーバーと本番サーバーの切り替えに。

・YSlow
WEB高速化のヒント、アドバイザ・ツール
参考程度に使ってます。
SVGの2次ベジェ曲線の制御点をドラッグで動かすサンプル

# デモ

http://bl.ocks.org/hnakamur/a28ec606848e5d265053

# スクリーンショット

![quadratic-bezier-curve.png](https://qiita-image-store.s3.amazonaws.com/0/3227/8fef1f3c-86ba-526e-5773-0acde5791619.png)

# メモ

## マウスイベント座標をSVG座標に変換

以下の関数で変換します。

```js
function getClientPointInSVG(ev) {
  var p, m;
 
  p = svg.createSVGPoint();
  p.x = ev.clientX;
  p.y = ev.clientY;
 
  m = dragElem.getScreenCTM();
  return p.matrixTransform(m.inverse());
}
```

## ドラッグ開始時にオフセットをとっておく

mousedownイベントで制御点とマウスイベントの点のずれを保存しておきます。mousemoveイベントでは、そのずれを維持しつつ制御点を移動します。

## どの要素にイベントハンドラをセットするか

* mousedown: 制御点(ドラッグ対象)
* mousemove, mouseup: svg要素

mousemoveとmouseupのハンドラをsvg要素ではなく制御点につけてしまうと、マウスを素早く動かして制御点から外れるとドラッグが止まってしまって良くなかったです。

# 参考

以下のページを参考にしました。

* [www.codedread.com/dragtest.svg]( http://www.codedread.com/dragtest.svg )
* [Draggable SVG element | Peter's Website]( http://www.petercollingridge.co.uk/interactive-svg-components/draggable-svg-element )