OmniAICreator/Qiita-1.07M huggingface dataset:
【CasperJS】Facebookをスクレイピングして近況を投稿してみる

#概要

簡単に理解すると、PhantomJSという中身がwevkitの仮想ブラウザがあって、それをより簡単に使うためのツールがCasperJSです。
そのCasperJSを使用してFacebookにログインして近況を投稿してキャプチャを撮るところまでをやってます。

CasperJSの詳しい話は公式サイトで　( [CasperJS](http://casperjs.org/ "CasperJS") )

Casper（カスパー）と言えば、あの映画で有名なキャラクターを思い出しますが、公式サイトで見たやつは随分イメージが違ってて、一言で言えばカスパー劣化版みたいでした.


#CasperJSを導入する(mac)

phantomjsとcasperjsを導入する必要があります。
どちらもnpmでインストール可能です。グローバル環境にインストールします。

```
$ npm install -g phantomjs
$ npm install -g casperjs

```

#処理の流れ

* Facebookにログイン
* 近況の投稿
* 結果をキャプチャする


では、sample.jsを作成してコードを書きます。
CasperJSでは各種コマンドのCSSのパスでの記述が可能なので、そのあたりも見てやってください。

```js:sample.js

var casper = require("casper").create();

//フェイスブックにログインする

casper.start("https://ja-jp.facebook.com/", function(){
  //ログイン
  this.fill('.menu_login_container > form', 
{ email: 'フェイスブックの登録メールアドレス', pass: 'フェイスブックのパスワード' }, true);

});

//近況を投稿

casper.then(function(){
	casper.wait(5000, function() {
	    this.evaluate(function() {
	        document.querySelector('#u_0_11').value = 'お化けがでたよー by CasperJS';
	        document.querySelector('#u_0_x > div > div._1dsp > div > ul > li:nth-child(2) > button').click();
	    });
	});
});

//結果のキャプチャを撮る

casper.wait(10000, function() {
        this.capture('result.png');
});


casper.run();


```
キャプチャされた画像は、sample.jsと同一ディレクトリに出力されます。

ロード時間に引っかからないようにwait()系で、投稿とキャプチャに入る前に時間に余裕を持たせました。（時間は適当です）
投稿の部分も.fill()系でやろうと思いましたが、少しパターンを変えて、evalute内でDOMを操作してみました。

セレクターを指定する際は、Chrome Developer Toolsで右クリックのCSSのパスをコピーすると間違いが無く便利です。


#実行

```

$ casperjs sample.js

```


結果はこんな感じ

![result.png](https://qiita-image-store.s3.amazonaws.com/0/67591/8f919055-b5c1-4912-7524-cecf58fff2ef.png)
(※キャプチャの一部を切り取ってます)


タイムカードで出社と退社ボタンを押すようにして、cronでまわせば「忘刻」というのも無くなりますね。
2015/05/01 時点の apm list と一行コメント

Atom を触り始めて約一週間の時点の記録

Output my `apm list` on 2015-05-01
[D] Disabled

```
├── Clean@0.10.0
 # Zen をベースにした、集中モードヘルパ。TreeとかTabを一時的に隠す
├── aligner@0.11.0
 # 範囲選択しなくても適当に Align してくれる。
├── atom-alignment@0.12.0
 # [D] Algigner の方を使っている。
├── atom-beautify@0.24.1
 # 綺麗にしてくれる
├── autocomplete-plus@2.12.1
 # [D] まだ使ってない。
├── clipboard-history@0.6.4
 # 過去の Clipboard の内容を貼り付け
├── color-picker@1.7.0
 # 便利。ビジュアルUIでに色を選択
├── file-icons@1.5.4
 # ファイルにアイコンつけてくれる。
├── fold-comments@0.3.0
 # コメントエリアを folding してくれる。コメント多いコード、コード読みたいときは邪魔なので折りたたむ。
├── github-web@1.1.0
 # [D] github style syntax
├── incremental-search@4.3.0
 # [D] 試した時は動きが微妙で使うのやめた。
├── isotope-ui@2.1.3
 # UI
├── jumpy@2.0.6
 # eazymotion style jump, across Pane でやれるのはなかなか。しかしあんま使わん。
├── key-peek@0.2.5
 # これは便利。デフォルトの keymap resolver は候補全部出るが、これは最終 resolve 結果だけが出るのでうるさくない。出しっぱなしに出来る。
├── language-lua@0.9.2
 # lua サポート
├── last-cursor-position@0.9.0
 # 完璧ではないが、vim-mode の C-i, C-o にマップして使っている。実装は改善出来そう。
├── linter@0.12.1
├── local-history@3.1.0
 # つかってない。
├── minimap@4.8.0
├── monokai@0.14.0
├── one-tab@0.4.0
 # [D] tab がひとつの場合は、tab を消す。
├── pdf-view@0.22.0
├── pen-paper-coffee-syntax@0.8.3
├── pigments@0.2.0
 # #ffffff とかのカラー定義に色付けしてくれる。
├── preview@0.13.8
 # cofffee を js にコンパイルした結果をリアルタイムプレビューしたりできる。Coffee のお勉強に便利。
├── project-manager@1.15.5
 # よく使うプロジェクトを登録しておいて選んで開く。
├── regex-railroad-diagram@0.7.4
 # [D] Regex の視覚表現
├── run-in-atom@1.0.2
 # 選択範囲や、Buffer を Atom のコンテキストで評価。Chrome DevToolを開いて続きのTry&Erroがやれる。
├── script@2.19.0
 # quickrun みたいなもん。まだまだ改善の余地あり。
├── seti-ui@0.6.3
├── spacegray-dark-syntax@0.2.0
├── spacegray-dark-ui@0.8.0
├── symbols-tree-view@0.9.2
├── unity-ui@2.0.7
├── vim-mode@0.45.0
 # かなり良く出来ていると思う。試しに送った textobj-paragraph の PRs が通った！うれい！
├── web-browser@1.4.4
 # [D] web ひらくやつ？ 
└── web-view@0.3.0
 # [D] web ひらくやつ？
```
seedbankを使って柔軟な初期投入データ構成を実現する

## db/seeds.rbのつらみ

Railsのdb/seeds.rbは開発初期にはそのまま使っても問題がないのですが、サービスが大きくなったり、運用が始まったりするとなかなかつらみが出てきます。つらい点を上げると以下のようになるでしょうか。

- 準備すべき初期データが増えるため、ファイルが肥大化する。
- モデル間の依存関係を考慮しなくてはならなくなってくる（例：市区町村データの前に都道府県データが入っていないといけない。）
- 環境毎に投入するデータを分けるため、分岐が発生する（例：開発環境ではテストデータを入れておきたいが、本番環境では登録したくない。）
- 運用開始後、一部のseedだけ本番環境に適用したい場合、手動で切り出すしかない。（例：`Prefecture`モデルだけが存在していたところに`City`モデルを追加して市町村データをDBに流し込む場合）。

## seedbankでseeds.rbを分割する

[seedbank](https://github.com/james2m/seedbank)は上記の問題を解決してくれるgemです。

### ファイルの肥大化を防ぐ

gemのREADMEにあるように、seedbankは `db/seeds` 以下に分割された `.seeds.rb` で終わるファイルを読み込み、データベースに流し込んでくれます。このため、`db/seeds.rb` にある初期データを適切なファイル名で分割していくことができます。`db/seeds.rb` は最終的にseedbankを使っていることを書いたコメントだけ残しておくと新しくプロジェクトに参加した人にわかりやすいでしょう。

### データ間の依存関係を解決する

seedbankでは `after :table_name do ... end ` のように記述することで、読み込むデータの順番を制御することができます。上記の市区町村と都道府県の例であれば、先に都道府県のデータを登録しておいた上で、

```rb
# in db/seeds/cities.seeds.rb
after :prefectures do
  # PrefectureモデルにCityモデルを紐付けて登録
end
```

のようにできます。

### 環境毎に利用するseedファイルを切り分ける

seedbankでは、`db/seeds/development/` のようにenvironment名毎にフォルダを切ることで、その環境だけで読み込まれるseedファイルを作ることができます。これにより、開発環境だけで使うテストユーザの設定や独自の初期データなどを設定することが出来ます。

### 本番環境に途中から一部のseedを追加する

seedbankは`db/seeds`以下のseedファイルに対応したrake taskを作ってくれます。たとえば、`db/seeds/prefectures.seeds.rb` というファイルがあった場合、`rake db:seed:prefectures` を実行することで該当するデータだけ読み込みができます。seedbank gemをproductionやstagingでも有効にすることで、追加の初期データ投入が楽になるでしょう。今日開発環境でseedbankを使ったばかりで、本番でまだ使ったことがないですが...。
postgresqlでXOR（排他的論理和）とNAND（否定論理積）の演算子を定義する

postgresqlはリレーショナル・データベースなのにXORとNANDが使えない。
ので、オペレータを定義した。

```lang:sql(XOR)
CREATE FUNCTION xor(bool,bool) RETURNS bool AS '
SELECT ($1 AND NOT $2) OR (NOT $1 AND $2);
' LANGUAGE 'sql';
CREATE OPERATOR ~| (PROCEDURE='xor',LEFTARG=bool,RIGHTARG=bool);
```
http://snowland.net/nucleus/item/738 の丸パクリ。


```lang:sql(NAND)
CREATE FUNCTION nand(bool,bool) RETURNS bool AS '
SELECT NOT ($1 AND $2);
' LANGUAGE 'sql';
CREATE OPERATOR ^& (PROCEDURE='nand',LEFTARG=bool,RIGHTARG=bool);
```

こんな感じで使う。

```lang:sql(sample)
-- yoshikiとtoshiのいずれか
SELECT * FROM xjapan WHERE yoshiki ~| toshi;

--pataでない、かつhideでない
SELECT * FROM xjapan WHERE pata ~| hide;
```

追記
こちらの方法の方がスマートである。。
http://cs.hatenablog.jp/entry/2013/07/19/154215
docker で使ってないイメージを全部消す時の Tips

# TL;DR

```shell-session
> docker rmi --no-prune=true $(docker images -a -q)
```

最高

# ｋｗｓｋ

使ってない(現在起動中のコンテナが依存していない)イメージを全部消すには

```shell-session
> docker rmi $(docker images -a -q)
```

が便利ですが、これだと tag も消えてしまって、結果出てくるのは

```shell-session
> docker images -a
REPOSITORY                  TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
<none>                      <none>              c395172a74e5        8 hours ago         1.151 GB
<none>                      <none>              05a17381460b        8 hours ago         1.151 GB
<none>                      <none>              eb3ce0796961        8 hours ago         1.141 GB
...
```

こんな感じのなんのこっちゃわからない出力になります。イメージが削除されない場合でも Untagged だけはされてしまうので、本当に無名のイメージがぞろぞろ並ぶ不気味な光景です。

なので、イメージの一括削除時には

```shell-session
> docker rmi --no-prune=true $(docker images -a -q)
```

と実行すると、 tag が削除されなくて安心です。よかったですね。

![aa114938.png](https://qiita-image-store.s3.amazonaws.com/0/4384/1d9a7be5-c148-bd35-006c-f57e1107da3a.png)
コマンドの結果を空白で区切って配列に格納。

```
[root@testsv ~]# curl -Lk http://google.com -o /dev/null -w '%{http_code}\t%{time_total}\n' -s
200     0.133
[root@testsv ~]# 
```
例えば、↑な感じでcurlでHTTPの応答コードと、応答時間を拾って監視したい場合、普段だったら

```
[root@testsv ~]# HOGE=`curl -Lk http://google.com -o /dev/null -w '%{http_code}\t%{time_total}\n' -s`
[root@testsv ~]# echo $HOGE
200 0.157
[root@testsv ~]# echo $HOGE |awk '{print $1}'
200
[root@testsv ~]# echo $HOGE |awk '{print $2}'
0.157
[root@testsv ~]# RES_CODE=`echo $HOGE |awk '{print $1}'`
[root@testsv ~]# RES_TIME=`echo $HOGE |awk '{print $2}'`
[root@testsv ~]# echo $RES_CODE
200
[root@testsv ~]# echo $RES_TIME
0.157
[root@testsv ~]#
```
こんな風に分けて変数に代入してたけど、配列使うともっと簡単に同じことが実現できた。


```
[root@testsv ~]# arr=(`curl -Lk http://google.com -o /dev/null -w '%{http_code}\t%{time_total}\n' -s |awk '{print}'`)
[root@testsv ~]# echo ${arr[*]}
200 0.124
[root@testsv ~]# 
[root@testsv ~]# echo ${arr[0]}
200
[root@testsv ~]# echo ${arr[1]}
0.124
[root@testsv ~]# 
```
こんな感じで配列に格納する。

これで、シェルスクリプト内でいい感じにできそう。

```
[root@testsv ~]# cat  test.sh
#!/bin/sh
arr=(`curl -Lk http://google.com -o /dev/null -w '%{http_code}\t%{time_total}\n' -s |awk '{print}'`)
echo "google.comからの応答番号は${arr[0]}でした。"
echo "応答時間はecho ${arr[1]}(sec)でした。"
[root@testsv ~]# 
[root@testsv ~]# sh  test.sh
google.comからの応答番号は200でした。
応答時間はecho 0.230(sec)でした。
[root@testsv ~]# 
```
しょぼいけど、こんな感じ？
awkの-Fでセパレータ指定してやれば、わりと何でもいけそう。

ワンラインでやりたいって言ってくれた先輩に感謝。
スマホ再生できるビデオをエンコードする時の注意

#はじめに
ユーザ向き合いのサービスをする中で「ビデオ」というコンテンツの重要性は
日に日に高まっているように思います。
それにつられてビデオフォーマットで問題が起きて調べる、なんてことも多くなってきました。
今回は、そのあたりで調べたことをシェアしたいと思います。

```
私は先行する巨人の肩には積極的に乗る派なので、
他の私の投稿と同じく、勉強させてもらった他サイトのリンク多めです。
予めご了承ください。
```

#そもそもビデオって
基本理解として読んでおくと良いのが、以下。
http://note.chiebukuro.yahoo.co.jp/detail/n335817
簡単にまとめておくと、

- 一つの動画ファイルには「映像ファイル」と「音声ファイル」が含まれる
- 「mp4」「wav」などは、映像、音声をまとめたコンテナ形式の一つ
- 映像、音声それぞれの圧縮技術（コーデック）の規格として「h.264」や「aac」というのがある

これ以上は、上記URLやwikiを読んでもらうのが良いでしょう。
ともあれ、一つのビデオファイルには映像と音声が別々に含まれていて、
個別に圧縮技術がある、ということです。

#スマホ対応するビデオのフォーマット
実は、OSや機種によって、それぞれ対応しているものが決まっています。
何でも良いという訳ではないのです。
たとえば、

- [iphone6](https://support.apple.com/kb/SP705?viewlocale=ja_JP&locale=ja_JP)
- [Android（日本語翻訳サイト）](http://www.techdoctranslator.com/android/appendix/media-formats)

ここを見ると分かるのですが、選択肢はそれほど多くないのです。
幅広いユーザを考えて、、となると自ずと選択肢はしぼられていて、だいたいは、

```
フォーマット：mp4
映像コーデック：h.264
音声コーデック：AAC
```
このあたりに落ち着くことが多いように思います。（実際これでの納入がすごく多い）

#mp4エンコード
上述のように、端末やOSの制限で、NGな組み合わせのエンコードが存在します。
実際聞かれたときの調べ方と、注意ポイントを記載してみます。
　＃以下は個人的な例ですので、もっと良い方法があったらぜひ教えてください

###解析ツール
- [Media.info](http://mediaarea.net/ja/MediaInfo/Download) 

これが鉄板だと思います。
ほとんどのファイルを解析できて、一般的な設定内容は大体出てきますし、
結果をtxtやxmlで出力したり、といったこともできて、非常に便利です。
使い方は、[このあたり](http://www.gigafree.net/media/mediainfo.html)が詳しいです。
これでOK/NGファイルを調べて、結果をdiffで取れば、概ね見当はつけられるはず。

###つまずきポイント例
- プロファイルとレベルの指定
- ref-frameとB-frame
- 最大ビットレート

結構色々なサイトを参考にさせてもらったので、列挙します。
各種エンコード設定の説明で参考になったのが、この三つ。
http://minamaro.blogspot.jp/2011/11/x264.html
http://www57.atwiki.jp/handbrakeguide/pages/25.html
http://movie.geocities.jp/ketsudan00/H264-01.html

細かい技術理解としては、このあたり。
http://d.hatena.ne.jp/leafcage/20120626/1340713483
http://ja.wikipedia.org/wiki/フレーム間予測
https://msdn.microsoft.com/ja-jp/library/ee341432(v=expression.40).aspx
http://freesoft.tvbok.com/movie_encode/mencoder/h264-main-high.html

現状（20150501時点）ですと、

```
Base Profile @3.1
ref-frames 3 / B-frames 0（MainProfileなら最大でref6 B3くらい）
最大ビットレート　1000kbps程度
```
このくらいが再生可能なものとして、割と見かけるようです。
とくにframe設定は、再生側の負荷に大きく関わるので、結構重要なようです。
（実際ヘンテコな値でエンコードすると、古め端末だと再生できないことが多々ある）

#最後に
最近、本当にビデオフォーマットが増えたと思います。
一昔前はFlashが多かった印象ですが、技術的なオ●コンぶりからでしょうか、
変わりつつあるように感じます。
html5が広がったのと、手っ取り早くスマホでも素材を撮れる、見せられるというのも
影響しているのでしょうかね。

それにしても動画のエンコード技術は調べるとかなり奥が深く興味をそそられました。
また暇があったら調べてみようと思います。
case文の条件で正規表現を使って内部でマッチ部分を使いたいとき

タイトルが意味不明なのでとりあえず下のコードを見て欲しいです。

まずrubyではcase文の条件に正規表現が使えます。
そこで、caseでStringを渡し、whenを正規表現で表し、さらに分岐後にそのマッチ部分を使いたいといったとき以下のように書いていました。

```rb
message = "2015年05月01日"

case message
when /\d{4}年\d{2}月\d{2}日/
  m = message.match(/(\d{4})年(\d{2})月(\d{2})日/)
  puts "#{m[1]}/#{m[2]}/#{m[3]}" # => 2015/05/01
else
  puts "not match."
end
```

これだと正規表現の部分が冗長だし、なにより全然rubyっぽくない。
そこで、\$1, $2, ... という特殊変数はキャプチャーされた部分文字列が格納されるので、これを使うことでかなりシンプルになります。

```rb
message = "2015年05月01日"

case message
when /(\d{4})年(\d{2})月(\d{2})日/
  puts "#{$1}/#{$2}/#{$3}" # => 2015/05/01
else
  puts "not match."
end
```

他にも良い書き方がありましたらコメントでお知らせください。

# 参考

http://docs.ruby-lang.org/ja/2.2.0/doc/spec=2fregexp.html
文書IDの見方

#文書IDの見方

文書のプロパティで確認できる情報

例
>1　ID: OF0000039D:3836C29F 
2　　ON85255DC9:0056FB94 
3　　SD00255DF4:0057B8FA-SN00000003 
4　　DB85255CD9:00567287 
5　　NT0000C092

## １行目（OF～）
OF = Originator ID.File
OIDのDatabase ID部分

## ２行目（ON～）
ON = Originator ID.Note
OIDのNote ID部分

１行目＋２行目でUNIDになる

## ３行目（SD～、SN～）
SD = Sequence Time / Date
SN = Sequence Number
更新日時と、バージョン番号

１行目～３行目でOIDになる

## ４行目（DB～）
DB = Database ID
GUIDのDatabase ID

## ５行目（NT～）
NT = Note ID
GUIDのNote ID
VisualStudioCodeでエディタの背景に画像を設定する

# 概要
独自テーマの作成はまだできないようですが、自分でCSSいじってUIを変えることはできます。(自己責任で)

# 参考資料
Visual Studio Code のテーマを変更する + プロ生ちゃんを表示
http://pronama.azurewebsites.net/2015/04/30/visual-studio-code-theme/

# 手順
win8.1だとAppData\Localの中にCodeがインストールされてると思うので、その中からnative.main.cssというファイルを探してください。
作業前に一応バックアップ取っといた方がいいかもですね。

Dark Themeの場合、6670行あたりに「.monaco-editor.vs-dark」という箇所があり、そこの「.zone-widget .monaco-edhitor」の中をいじるとエディタのUIがいじれるようです。

``` lang:native.main.cssの6670行あたり
.monaco-editor.vs-dark .zone-widget .monaco-editor {		
	color: #BBB;
	background: #1E1E1E;
	/*以下追記*/
	background: url('画像のパス') no-repeat;
	background-size: contain;
	background-position: right bottom;
	/*以上追記*/
}
```

こんなんなりました↓
![無題の画像.png](https://qiita-image-store.s3.amazonaws.com/0/30304/35a5f239-7c43-c57b-b08a-2786e1580dbe.png)
(その辺から拾ってきた画像使っちゃってますスンマセン)
画像はgifやjpg、pngは使えるの確認しました。

# まとめ
エディタに画像を表示するとけっこうテンション上がりますね。ただ、画像はちゃんと選ばないと非常に邪魔になります。とりあえず透過は必須、肌色多めだと見づらいです。
あと、gifアニメーションもちゃんと動くので、隅に小さく表示して動かすと面白いかもしれないですね。
PythonでメールアドレスからMXレコードを引いて直接メールを送信する

#概要

メールサーバーの指定をしなくてもいいプログラムを作ってみたかったので書いてみました。

最初にMXレコードを引くためのモジュールを入れます。

```
pip install dnspython
```

#実行

引数に宛先と差出人のメールアドレスを渡す。

```
python sendmail.py to@example.com from@example.com
```

#実装

sendmail.py

```
# -*- coding: utf-8 -*-

import smtplib
from email.MIMEText import MIMEText
from email.Header import Header
from email.Utils import formatdate
import sys
import dns.resolver

if __name__ == "__main__":

    argvs = sys.argv

    if len(argvs) != 3:
        print 'Usage arg1 = to_address, arg2 = from_address'
        quit()

    to_address   = argvs[1]
    from_address = argvs[2]
    to_list = to_address.split('@')

    to_address = '<' + to_address + '>'
    from_address = '<' + from_address + '>'

    if len(to_list) < 2:
        print 'format error to_address'
        quit()

    domain = to_list[1]
    mailserver = dns.resolver.query(domain, 'MX')

    if len(mailserver) < 1:
        print 'not found mx recored'
        quit()

    mailserver = mailserver[0].to_text().split(' ')
    mailserver = mailserver[1][:-1]
    print mailserver

    charset = "ISO-2022-JP"
    subject = u"this is Python test mail!"
    text    = u"this is Python test mail!"

    msg = MIMEText(text.encode(charset),"plain",charset)
    msg["Subject"] = Header(subject,charset)
    msg["From"]    = from_address
    msg["To"]      = to_address
    msg["Date"]    = formatdate(localtime=True) 

    smtp = smtplib.SMTP(mailserver)
    smtp.sendmail(from_address,to_address,msg.as_string())
    smtp.close()
```


Gmailはスパム対策なのか、なんらかの制限をかけているようで、送信すると下記のようなエラーが出る可能性があります。

```
smtplib.SMTPServerDisconnected: Connection unexpectedly closed: [Errno 54] Connection reset by peer
```
OpenStack on CentOS7 引っかかりリスト

CentOS7にOpenStackをインストールしたときに、エラーが出た箇所のメモ書きです。

##イメージ作成時エラー（virt-install）
**Problem:**

```text:
ERROR ネットワークが見つかりませんでした: 'default' に一致する名前を持つネットワークがありません
```

**Answer:**

```text:
(bash)# virsh net-define /usr/share/libvirt/networks/default.xml
(bash)# virsh net-autostart default
(bash)# virsh net-start default
```

##ダッシュボード開けない
**Problem:**

```text:/var/log/httpd/error_log
ImportError: Could not import settings 'openstack_dashboard.settings' (Is it on sys.path? Is there an import error in the settings file?): No module named angular_cookies
```

**Answer:**

```text:
(bash)# pip install XStatic_Anglar_Cookies
```

##novncが127.0.0.1に繋ごうとする
**Problem:**
コントローラ以外のクライアントでダッシュボード上のコンソールを開こうとすると、127.0.0.1:6080に繋いでいる。


**Answer:**
以下、追加する。

```py:/etc/nova/nova.conf(compute_node)
vnc_enabled=True
novncproxy_base_url=http://Controller_IP:6080/vnc_auto.html
vncserver_listen=0.0.0.0
vncserver_proxyclient_address=Controller_IP
#Controller_IPは適宜変更のこと
```

##インスタンス起動時エラー
**Problem:**
ダッシュボードにて

```text:
エラー: インスタンス "ins01" の起動に失敗しました: 後からもう一度お試しください [エラー: Build of instance 5e9fcc9c-1b2f-44ad-af6f-b51d7637696b aborted: Failed to allocate the network(s), not rescheduling.]
/var/log/nova/nova-copute.log in node01
Instance fails to spawn with Unexpected vif_type=binding_failed [closed]
```

**Answer:**
openvswitchを入れ直す、またはbr-intを作り直す。

##noVNCエラー
**Problem:**
ダッシュボードのnoVNCが繋がらない。

**Answer:**

```text:/etc/nova/nova.conf(compute.node)
vncserver_listen = 0.0.0.0
```

##外部ネットワーク接続
**Problem:**
インスタンスが外部ネットワークに届かない。

```text:
Error: External network b7169915-050a-4c67-83fc-9ed28ae7dc0f is not reachable from subnet b7169915-050a-4c67-83fc-9ed28ae7dc0f. Therefore, cannot associate Port 4cd7cc7c-db9f-4fcc-86d4-a05607f0eb74 with a Floating IP.
```

**Answer:**

```text:/etc/neutron/l3-agent.ini
[DEFAULT]
…
gateway_external_network_id = EXTERNAL_NETWORK_ID
external_network_bridge = br-ex
…

```

```text:/etc/neutron/plugins/ml2/ml2_conf.ini
[ml2]
…
type_drivers = vxlan,vlan,flat
tenant_network_types = vxlan,vlan
mechanism_drivers =openvswitch
…
[ml2_type_flat]
flat_networks = external
…
[ovs]
bridge_mappings = external:br-ex
```

```text:
(bash)# neutron net-create public --router:external --provider:physical_network external --provider:network_type flat

(bash)# neutron subnet-create public 192.168.0.0/24 --name public-subnet   --allocation-pool start=192.168.0.101,end=192.168.0.200   --disable-dhcp --gateway 192.168.0.1

(bash)# neutron router-create external_router
(bash)# neutron router-gateway-set external_router public
```

##どこかがおかしくなりました！
**Problem:**
タイムアウトするとダッシュボードに入れない。

**Answer:**
Cookieを消去します。

　　

メモ書き随時追加予定。
ノーツ文書IDまとめ

#ノーツ文書IDのまとめ

##UNID (Universal Note ID)
* 文書毎に割当てられる固有のID
* 全てのレプリカで同一
* 文書を更新しても変化しない

##OID（Originator ID）：
* 文書毎に割当てられる固有のID
* 全てのレプリカで同一
* 文書を更新するとIDも更新される

##GNID（Global Note ID）
* 文書毎に割当てられる固有のID
* 同一の文書でもレプリカ間でIDが異なる
* 文書を更新しても変化しない

##NID（Note ID）
* 文書毎に割当てられるID
* 文書を更新しても変化しない

各々のIDは全く独立したIDではなく、包含関係にある
例えば、UNIDに更新日時情報とバージョン情報を含めたものをOIDと言う。など

プロパティ画面からの確認はこちらから
http://qiita.com/disapalt/items/b4d396009384a3cffbd3
rubyのselfの意味と使い方

# Ruby の self とは？

ruby自体が持っている式らしい。（トップレベルではメソッドではないらしい）

# どういうものを返してくるのか？

## 以下実行

```ruby:sample.rb
# coding:utf-8

puts self
```

## 結果

>
% ruby sample.rb
main

へー。なんかわからないけど main というオブジェクト（？）を返してくる。

# 親はなんだろう？

## 先ほどのソースを修正

```ruby:sample.rb
# coding:utf-8

puts self
puts self.class
```

## 結果

>
% ruby sample1.rb
main
Object

やっぱりオブジェクトなんだ（当たり前かw）

# クラスを作成して確認する

## ソース

```ruby:sample2.rb
# coding:utf-8

class Sample2
    def my_self
        puts self
    end 
end

sample = Sample2.new

sample.my_self
```

## 結果

>
% ruby sample2.rb
\#\<Sample2:0x007fe4990a4a30>

クラスを返してくる。

# 特異メソッドで使ってみる

self付きのメソッドのことをそう呼ぶらしい。

## ソース

```ruby:sample3.rb
# coding:utf-8

class Sample3
    def my_self
        puts 'my_self!'
    end 

    def self.my_self_by_sample3
        puts 'self.my_self_by_sample3'
    end 
end

Sample3.my_self_by_sample3

begin
    Sample3.my_self
rescue Exception => e
    puts e
end

sample = Sample3.new

begin
    sample.my_self_by_sample3
rescue Exception => e
    puts e
end

sample.my_self
```

## 結果

>
% ruby sample3.rb
self.my_self_by_sample3
undefined method \`my_self' for Sample3:Class
undefined method \`my_self_by_sample3' for #\<Sample3:0x007f6f4464aa18>
my_self!

なんとなく分かった気がする！（気だけw）

特異クラスってのもあるらしい。同じような考えなのかな？（そのうちちゃんと見てみよう）

# まとめ？

普通に自分自身を返すものとして認識していいのかなぁ？
特異メソッドとして使う場合は、使っているクラス（モジュールも？）のメソッドとして動くって感じかな。
まとまりきれてないけど、ひとまずはそんな感じで認識しておこう。

# 参考
http://blog.keit.me/20130906/156/
オレオレ証明書・秘密鍵・CSR全部まとめて作るワンライナー

よく忘れるっていうか覚えられないので。

```
openssl req -nodes -newkey rsa:2048 -keyout server.key -out server.csr -subj "/C=JP/ST=Hokkaido/L=Sapporo/O=Example INC./OU=IT Department/CN=example.com" && openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt
```

`subj`,`days`は適宜変更する。
sqlのorder byでid=100の人だけ優先する

やー、なんかこんなorder byってありなんすね。
今日初めて知った。
`ORDER BY id`するんだけど、自分はid=100なんで自分だけ優先で特別に一番に並べたいって時に

```sql
ORDER BY id=100 DESC
```

とする。
いいね、これ。
ルールを無視してる感じがすごくいい。
【Swift】使っている端末の情報を取得



**Swift**で端末情報を取得する方法です。

`Bridge-Header`に`#import <sys/utsname.h>`を追加しておいてください。

```swift:UIDeviceExtension.swift
import Foundation

private let DeviceList = [
    /* iPod 5 */          "iPod5,1": "iPod Touch 5",
    /* iPhone 4 */        "iPhone3,1":  "iPhone 4", "iPhone3,2": "iPhone 4", "iPhone3,3": "iPhone 4",
    /* iPhone 4S */       "iPhone4,1": "iPhone 4S",
    /* iPhone 5 */        "iPhone5,1": "iPhone 5", "iPhone5,2": "iPhone 5",
    /* iPhone 5C */       "iPhone5,3": "iPhone 5C", "iPhone5,4": "iPhone 5C",
    /* iPhone 5S */       "iPhone6,1": "iPhone 5S", "iPhone6,2": "iPhone 5S",
    /* iPhone 6 */        "iPhone7,2": "iPhone 6",
    /* iPhone 6 Plus */   "iPhone7,1": "iPhone 6 Plus",
    /* iPad 2 */          "iPad2,1": "iPad 2", "iPad2,2": "iPad 2", "iPad2,3": "iPad 2", "iPad2,4": "iPad 2",
    /* iPad 3 */          "iPad3,1": "iPad 3", "iPad3,2": "iPad 3", "iPad3,3": "iPad 3",
    /* iPad 4 */          "iPad3,4": "iPad 4", "iPad3,5": "iPad 4", "iPad3,6": "iPad 4",
    /* iPad Air */        "iPad4,1": "iPad Air", "iPad4,2": "iPad Air", "iPad4,3": "iPad Air",
    /* iPad Air 2 */      "iPad5,1": "iPad Air 2", "iPad5,3": "iPad Air 2", "iPad5,4": "iPad Air 2",
    /* iPad Mini */       "iPad2,5": "iPad Mini", "iPad2,6": "iPad Mini", "iPad2,7": "iPad Mini",
    /* iPad Mini 2 */     "iPad4,4": "iPad Mini", "iPad4,5": "iPad Mini", "iPad4,6": "iPad Mini",
    /* iPad Mini 3 */     "iPad4,7": "iPad Mini", "iPad4,8": "iPad Mini", "iPad4,9": "iPad Mini",
    /* Simulator */       "x86_64": "Simulator", "i386": "Simulator"
]

extension UIDevice {
    
    var modelName: String {
        var systemInfo = utsname()
        uname(&systemInfo)
        
        let machine = systemInfo.machine
        let mirror = reflect(machine)
        var identifier = ""
        
        for i in 0..<mirror.count {
            if let value = mirror[i].1.value as? Int8 where value != 0 {
                identifier.append(UnicodeScalar(UInt8(value)))
            }
        }
        return DeviceList[identifier] ?? identifier
    }
}
```

で端末のOSのバージョンは`UIDevice.currentDevice().systemVersion`で取得できるので、

```swift
let deviceName = UIDevice.currentDevice().modelName
let deviceVersion = UIDevice.currentDevice().systemVersion
println("device = \(deviceName)(\(deviceVersion))")
```

で出力された内容は

```
iPhone 6 Plus(8.3)
```

となりました。

## 参考

[iOS: How to determine iphone model in Swift? - Stack Overflow](http://stackoverflow.com/questions/26028918/ios-how-to-determine-iphone-model-in-swift)
まちがって更新してしまったファイルの一覧表示

なんというか、リリース作業とかやってて必ずやらかすんだが、アップしなくていいファイルをアップしてしまったりする。
だから夜中に作業するのはやめようって言ったじゃん。
で、どのファイルだよ？
となった時、確かあれは21:30くらいだったよな〜
ということで。

```bash
touch -m -d '2015/05/01 21:30:00' newer
```

としてから、

```bash
find . -type f -newer newer
```

とする。いやあ、便利便利。
助かるって、ほんとに。

参照：http://blog.hello-world.jp.net/linux/1255/
webサービス系のjsonのレスポンス


**jsonの形式サンプル**

```lang:instagramAPI

{
  "data" : [
    {
      "attribution" : null,
      "caption" : {//投稿時の状況
        "created_time" : "1430464513",
        "from" : {
          "full_name" : "CHARA夢WINNY ♐️典型人馬座女生",
          "id" : "1403999",
          "profile_picture" : "https://igcdn-photos-e-a.akamaihd.net/hphotos-ak-xfp1/t51.2885-19/11055456_1536139393316956_764906015_a.jpg",
          "username" : "chara_winny"
        },
        "id" : "975129471524700186",
        "text" : "小肥肥一族～～ #blackcat #cat #cats #cute #lovelife #貓 #猫  #黑貓 #貓咪貓事多 #貓奴貓事多"//投稿時のコメント
      },
      "comments" : {//コメント関連
        "count" : 0,
        "data" : []
      },
      "created_time" : "1430464513",//投稿時間
      "filter" : "Ludwig",//利用したフィルタ
      "id" : "975129470065083161_1403999",
      "images" : {//投稿画像
        "low_resolution" : {
          "height" : 306,
          "url" : "https://scontent.cdninstagram.com/hphotos-xta1/t51.2885-15/s306x306/e15/11186848_885045841534774_499862765_n.jpg",
          "width" : 306
        },
        "standard_resolution" : {
          "height" : 640,
          "url" : "https://scontent.cdninstagram.com/hphotos-xta1/t51.2885-15/e15/11186848_885045841534774_499862765_n.jpg",
          "width" : 640
        },
        "thumbnail" : {
          "height" : 150,
          "url" : "https://scontent.cdninstagram.com/hphotos-xta1/t51.2885-15/s150x150/e15/11186848_885045841534774_499862765_n.jpg",
          "width" : 150
        }
      },
      "likes" : {//いいね
        "count" : 0,
        "data" : []
      },
      "link" : "https://instagram.com/p/2IWxYpPoMZ/",//instagram上のURL
      "location" : {//撮った場所
        "latitude" : 22.319064472,
        "longitude" : 114.216478775
      },
      "tags" : [//タグ
        "貓咪貓事多",
        "cute",
        "黑貓",
        "猫",
        "lovelife",
        "cat",
        "貓",
        "cats",
        "貓奴貓事多",
        "blackcat"
      ],
      "type" : "image",//投稿の種類　images　movie
      "user" : {//ユーザー情報
        "full_name" : "CHARA夢WINNY ♐️典型人馬座女生",
        "id" : "1403999",
        "profile_picture" : "https://igcdn-photos-e-a.akamaihd.net/hphotos-ak-xfp1/t51.2885-19/11055456_1536139393316956_764906015_a.jpg",
        "username" : "chara_winny"
      },
      "users_in_photo" : []
    }
  ],
  "meta" : {ステータスコード
    "code" : 200
  },
  "pagination" : {//次のページ以降取得用パラメータ
    "deprecation_warning" : "next_max_id and min_id are deprecated for this endpoint; use min_tag_id and max_tag_id instead",
    "min_tag_id" : "975129470065083161",
    "next_max_id" : "975129444444184116",
    "next_max_tag_id" : "975129444444184116",
    "next_min_id" : "975129470065083161",
    "next_url" : "https://api.instagram.com/v1/tags/cats/media/recent?count=1&access_token=&callback=jQuery1102030976749677211046_1430400028095&min_id=820941049276132937_2582298&client_id=507e0b3d1e9e48b991a7d3da78e988d8&max_tag_id=975129444444184116&_=1430400028096"
  }
}

```
MDWikiを導入してみてわかったこと

# MDWikiを導入してみてわかったこと
前回、[MarkDownで書いたファイルを置くだけでWiki化できるMDWikiを導入してみた。](http://qiita.com/nusa/items/8b07a8d75abc2044fa87)
という記事を書きましたが、今回は実際に運用してみて気付いたところなどを書きます。
MDWiki : http://dynalon.github.io/mdwiki/

## 良かったところ
導入するまでのハードルが低いので時間がかからなかった。
技術情報をみんなで共有して蓄積できる場所ができた。
MarkDown形式のテキストを書くだけなので、記事を書かなそうな人が書いてくれた。

## 悪かったところ
検索機能がないので記事検索ができない。
ユーザー管理機能がないので書いた人が誰だかわからない。
投稿記事をメンバーへ通知できない。

## 今後について
現在では特定のグループだけで投稿する仕組みにしましたが、
そのグループに負荷がかかるのでイマイチな感じでした。

個人でWikiを作って蓄積したいという用途ならば最高のWikiですが、
社内情報Wikiとしてやるのはあまりお勧めできません。

今のところ候補にあがっているのは、
[Confluence](https://www.atlassian.com/ja/software/confluence)、[QiitaTeam](https://teams.qiita.com/?utm_source=qiita&utm_medium=header_news)、[Ghost](https://ghost.org/)ですが、
ConfluenceとQiitaTeamは値段が高いので提案資料を作らなくてはならず、
Ghostは無料ですがただのブログにという悩ましい状況です。

## 2015.10.21追記
結局、Googleサイトになりました。あー、使いづらい。
QUnit導入方法

JavaScript用のテストフレームワーク「QUnit」の導入方法。備忘録。
環境はEclipse。
<br>
#ダウンロード
https://qunitjs.com/
→「qunit-1.18.0.js」を右クリック→名前を付けてリンク先を保存
→「qunit-1.18.0.css」を右クリック→名前を付けてリンク先を保存
<br>
#コーディング
```html:hello.html
<!DOCTYPE HTML>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
  </head>
  <body>
    <script src="hello.js"></script>
    <script type="text/javascript">
      var greeting = new Greeting();
      alert( greeting.hello("Taka") );
    </script>
  </body>
</html>
```

```js:hello.js
var Greeting = function() {
	this.hello = function(name) {
		return 'Hello, ' + name;
	};
};
```

テスト用

```html:hello_qunit.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>QUnit Example</title>
    <link rel="stylesheet" href="qunit-1.18.0.css">
  </head>
  <body>
    <div id="qunit"></div>
    <div id="qunit-fixture"></div>
    <script src="qunit-1.18.0.js"></script>
    <script src="../src/hello.js"></script>
    <script src="hello_qunit.js"></script>
  </body>
</html>
```

```js:hello_qunit.js
var greeting = new Greeting();

QUnit.test('JavaScript QUnit Tests', function(assert) {
	assert.equal(greeting.hello('Mike'), 'Hello, Mike');
	assert.equal(greeting.hello('Janet'), 'Hello, Janet');
	assert.equal(greeting.hello('David'), 'Hi, Ted');
});
```

配置
![image](https://qiita-image-store.s3.amazonaws.com/0/60528/86eaed07-e64c-61d3-ea49-dc162af7834c.png)

<br>
#表示
hello_qunit.html
![image](https://qiita-image-store.s3.amazonaws.com/0/60528/17198653-8f3f-66f7-714c-7737e6805286.png)




<br>
参照
http://easyramble.com/how-to-use-qunit.html
NSTableView 列追加、削除

##最初に
StoryBoard及び、コードの両方から列の追加、削除する方法です
最低限の使い方は、他の方がいくらでも情報載せていただいているのでそちらをご覧ください

##Storyboard
TableViewを選択し、Columnsを変更
![Main_storyboard_—_Edited.png](https://qiita-image-store.s3.amazonaws.com/0/46546/f143e827-39db-947d-ee51-8ad5ab31ace1.png)

TableColumnが追加されている事を確認
![Main_storyboard_—_Edited2.png](https://qiita-image-store.s3.amazonaws.com/0/46546/84306db7-1940-5503-339a-f7c2105eb5d1.png)

引き伸ばしてから追加すると見えない位置に生成されるので
**追加したカラムの一つ上のカラム**のWidthを狭める
![Main_storyboard_—_Edited3.png](https://qiita-image-store.s3.amazonaws.com/0/46546/747d9a0c-65a1-1d1c-3b6c-ecf67c9096a8.png)

##コード
見て貰えば早いです。

```swift:ViewController.swift
//
//  ViewController.swift
//  TestTableView
//

import Cocoa

class ViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource {

    @IBOutlet weak var tableView: NSTableView!

    let columnName: [String] = ["column0", "column1", "column2"]
    let data: [[String]] = [
        ["TEST00", "TEST01", "TEST02"],
        ["TEST10", "TEST11", "TEST12"]
    ]

    override func viewDidLoad() {
        super.viewDidLoad()
        // 一旦、全部削っちゃう
        let tableColumns = tableView.tableColumns as! [NSTableColumn]
        for tc: NSTableColumn in tableColumns {
            tableView.removeTableColumn(tc)
        }

        for _id in columnName {
            var tc: NSTableColumn = NSTableColumn(identifier: _id)
            tc.title = _id
            tableView.addTableColumn(tc)
        }
    }

    override var representedObject: AnyObject? {
        didSet {
        }
    }

    func numberOfRowsInTableView(tableView: NSTableView) -> Int {
        return data.count
    }

    func tableView(tableView: NSTableView, objectValueForTableColumn tableColumn: NSTableColumn?, row: Int) -> AnyObject? {
        if let tc: NSTableColumn = tableColumn {
            return data[row][find(columnName, tc.identifier)!]
        }
        return ""
    }
}
```
このコードの注意点として、StoryBoardから作って、IBOutletで取得して、デリゲートとデータソースはUtilitiesから設定しています。
また、セルにコードから入力する際は、Content ModeをView Basedから
![スクリーンショット_2015-05-01_15_28_32.png](https://qiita-image-store.s3.amazonaws.com/0/46546/a79e10d2-dc9b-9752-9206-471278ce7f40.png)

Cell Basedにしてください
![スクリーンショット_2015-05-01_15_29_59.png](https://qiita-image-store.s3.amazonaws.com/0/46546/cc4b84ab-d164-5f1a-2ef8-b78a635a7714.png)

##おわりに
コードから列の追加、削除する方法がなかなか見つからなかったので投稿しました。
Swiftで書きましたが、Objective-Cでもできます。

それではまたどこかで
ansibleで、AWSインスタンスを作成し、EIPの取得して、アタッチし、Route53を登録するまでを行う

インスタンスを作成し、EIPの取得して、アタッチし、Route53を登録するまでを行う、playbookを作成してみました。

```yaml:sample.yml

# Instance
   - name: Launch Instance
     ec2:
       aws_access_key: "{{ aws_access_key }}"
       aws_secret_key: "{{ aws_secret_key }}"
       region: "{{ region }}"
       key_name: "{{ keypair }}"
       instance_type: "{{ instance_type }}"
       image: "{{ ami }}"
       wait: "{{ instance_running_wait }}"
       group: "{{ security_group }}"
       count: 1
       vpc_subnet_id: "{{ vpc_subnet_id }}"
       assign_public_ip: "{{ assign_public_ip }}"
       instance_tags:
          Name: "{{ instance_name }}"
          User: "{{ user_name }}"
          Group: "{{ group_name }}"
       volumes:
          - volume_size: "{{ ebs_volume_size }}"
            device_name: "{{ ebs_device_name }}"
            delete_on_termination: true
     register: ec2

# Elastic IP
   - name: associate new elastic IPs with each of the instances
     ec2_eip:
       aws_access_key: "{{ aws_access_key }}"
       aws_secret_key: "{{ aws_secret_key }}"
       instance_id : "{{ item }}"
       region: "{{ region }}"
       in_vpc: yes
     with_items: ec2.instance_ids
     register: eip

# Route53
   - name: Add new route53 record
     route53:
      aws_access_key: "{{ aws_access_key  }}"
      aws_secret_key: "{{ aws_secret_key  }}"
      command: create
      zone: "{{ r53_zone }}"
      record: "{{ r53_record }}"
      type: "{{ r53_type }}"
      ttl: "{{ r53_ttl }}"
      value: "{{ item.public_ip }}"
      overwrite: yes
     with_items: eip.results
```

# ec2の解説
assign_public_ip：パブリックIPをアサインするかどうか（yes/no）
delete_on_termination：インスタンス削除と同時にEBSを削除するかどうか（true/false）

# Elastic IP
in_vpc：VPC内かどうか（yes/no）

# Route53
overwrite：上書きするかどうか（yes/no)
Webサイトをスクレイピングする時のちょっとしたコツ

仕事で色々なサイトをスクレイピングしていたのですがそこで自分なりに得た知見があるのでまとめてみました。

先にポイントを書くと

- データーの解析にあたるスクレイピングは**スマホファーストな時代なのでUserAgentもスマートフォンのものに変更する**と捗る
- 自分なりのクローリングパターンを確立する
- 精神的にツライ点もあるので自分なりの気分転換方法を確立する

という感じです。

## 想定してる読者

- [Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例](http://www.amazon.co.jp/dp/4797380357)を読み終えて自分で何か作ってみようと考え始めた方
- クラウドワークスとかランサーズでそれっぽいカテゴリの仕事を受注しようとしてる方

なお、考え方についてまとめたので、具体的なコードは出てきません。


## データーの解析にあたるスクレイピングスマホファーストな時代なのでUserAgentもスマートフォンのものに変更すると捗る

これは完全に主観ですがPC向けのサイトの場合

- サイトの特質上特にビジュアル的な所を重視
- 運営母体がお金をそれなりにかけられそう

という条件が揃ってると、JavaScriptで動的にページを生成するケースの割合が高い印象があります。

こういうサイトのスクレイピングを真正面からやろうとすると、ヘッドレスブラウザの力を駆使してやることになるので正直大変になるかと思います。

一方で、最近のモバイルファーストの流れを受けてか、PCだけではなくスマートフォン向けサイトを準備してるケースも結構あり、少なくとも自分が関わったサイトではほぼ100%の確率でそうなってました。

スマートフォン向けの場合には、マークアップが綺麗でスクレイピングするにはもってこい（？）なのでそれを利用して処理をしたほうが作業がとても捗るかと思います。


### 参考までにWebブラウザの設定変更でスマートフォンサイトにアクセスする

- Safariの場合

メニューの中から **開発** → **ユーザーエージェント** と進むことでiOSなやつを選択できます。

![safari.jpg](https://qiita-image-store.s3.amazonaws.com/0/10187/0ff5d065-2559-82f2-d076-cbc9545f63d6.jpeg)


- Chromeの場合

[Google Chromeでユーザエージェントを変更する](http://qiita.com/azusanakano/items/d9b5d9b7012ab222135d)が参考になるかと思います。


## 自分なりのクローリングパターンを確立する

[もぎゃさんが５年位前に作ったスライド](http://www.slideshare.net/mogya/ss-3836905)の[29枚目のスライド](http://www.slideshare.net/mogya/ss-3836905/29)で一覧ページ→詳細ページという形でのアプローチを紹介されてます。

自分がお手伝いしていた会社のやり方も、一覧ページ→詳細ページという形で対処しておりそれにならって自分も書いてました。

ただ、サイトによっては画面左側や上部にカテゴライズされたメニューがあって、そこをたどることで一覧ページ→詳細ページへ遷移するケースも有るのですがそこがすぐに見つからなかったり、把握しづらいサイトというのもあるのでその場合には

- トップページのカテゴリ情報を手がかかりにする
- 検索キーワードからカテゴリを推測する

という形で対処します。

これは具体的なサイトを例にしながら書いたほうが良さそうな気がするので、気が向いたらまとめます

## 精神的にツライ点もあるので自分なりの気分転換方法を確立する

これは実際あったのですが、順調にスクレイピング進んでこれでイケる・・・と思ったら何故か特定のページだけエラーになりました。

ひとまず問題の切り分けのため同じカテゴリの別ページでは問題なくスクレイピング出来てたので、もう少し突っ込んだ切り分けするために成功するページと失敗するページのHTMLを見てみたら、失敗したページにはなぜか余計なタグが含まれてました。

推測というか、完全に妄想なのですが、何らかのCMSとか独自の管理ページなどを通じて商品情報を登録しているのかなと思うのですが、もしかしたらその機能で簡易なHTMLタグを埋め込める機能があって作業者が間違ってしまった箇所があったためにこういうことが生じたのかもしれませんが、まぁこういう意図しないことが割りとよく出てきます。

同じことをひたすらやってると、精神的にツラくなるケースが出てくるかもしれないので、そういう時の気分転換方法を確立しておくと作業が捗ると思います。

なお、自分の場合には

- 子供と折り紙したり、積み木をして遊ぶ
- 料理をする（特にひたすら刻むような調理のもの）

あたりをすると脳の違う所が刺激される感じで割りと気分転換になりました。

たぶんこれはスクレイピングに限らず、コード書いてる時全般なんでしょうね(^_^;)
Filemakerからmysqlへテーブル構造コピー

# 背景
* 社内業務で使っているFilemakerデータベースをmysqlに置き換える案件
* テーブル構造をコピーしたい
* フィールド数が500もあるだと！手でやりたくない
* htmlエクスポートから整形してsql文を作る→方法1
* Filemakerスクリプトでテーブル構造を作るsql文を作る→方法2
* ODBC接続を使ってFilemakerスクリプトでテーブルを作る→方法3
* ODBC接続を使ってFilemakerスクリプトでフィールド追加→方法4
* テーブル構造ができあがってればcsvエクスポートでデータコピーできる
* うちの環境:Filemaker pro 11 advanced
* もっと簡単な方法あるかも

# 方法1　htmlエクスポートから整形してsql文を作る
* htmlエクスポートで`<TH>`に囲まれたフィールド名の羅列が出力される
* テキストエディタで整形してsql文を作る
* 手動なので面倒
* 変なところでエラーすることがない
* フィールド名は日本語、型はtext、あとで好きなように変える

````html
<HTML>
<HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=x-sjis"></HEAD>
<BODY><TABLE BORDER=1>
<TR>
<TH>商品番号</TH>
<TH>商品名</TH>
<TH>販売価格</TH>
<TH>登録日時</TH>
<TH>修正日時</TH>
<TH>販売停止</TH>
</TR>
...
````
````sql
CREATE TABLE 商品 (
 商品番号 text,
 商品名 text,
 販売価格 text,
 登録日時 text,
 修正日時 text,
 販売停止 text,
)
````


# 方法2　Filemakerスクリプトでテーブル構造を作るsql文を作る
* スクリプトを走らせるだけでsql文ができる単機能
* 出力用のテキストフィールドをグローバルで用意
* お手軽
* ODBC使わないのでシンプル

![1.png](https://qiita-image-store.s3.amazonaws.com/0/53376/a57fdbdf-3543-56a7-4f65-6edbebbc93dd.png)


````
変数を設定 [ $sql; 値:"CREATE TABLE 商品 (¶" ]
レコード/検索条件/ページへ移動 [ 最初の ]
フィールドへ移動 [ ローカル::商品番号 ]
Loop
変数を設定 [ $sql; 値:$sql & Get ( アクティブフィールド名 ) & " text" ]
次のフィールドへ移動
Exit Loop If [ Get ( アクティブフィールド名 ) = "sql" ]
変数を設定 [ $sql; 値:$sql & ",¶" ]
End Loop
フィールド設定 [ ローカル::sql; $sql & "¶)" ]
````
````sql
CREATE TABLE 商品 (
商品番号 text,
商品名 text,
販売価格 text,
登録日時 text,
修正日時 text,
販売停止 text
)
````

##準備
* 10万件500フィールドもあると操作の度にまたされるので事前準備しておく
* 1レコードだけ表示しておく
* フィールド設定でsqlをグローバルで追加
* レイアウト編集　新規レイアウト　リスト　折り返し　全フィールド
* フォーム形式表示　全フィールドが出てるのを確認
* スクリプトを編集
* スクリプト実行
* 計算フィールドは除外されるようだ

# 方法3　ODBC接続を使ってFilemakerスクリプトでテーブルを作る
* OSのODBC接続設定する
* FM内の外部データソース設定する
* こんな設定やって手間取るより方法2のが簡単確実
* データが全て数値であればint型にするとか複雑なスクリプト処理をさせたい時
* レコードのコピーも書けばできる

````
変数を設定 [ $sql; 値:"CREATE TABLE 商品 (¶" ]
レコード/検索条件/ページへ移動 [ 最初の ]
フィールドへ移動 [ ローカル::商品番号 ]
Loop
変数を設定 [ $sql; 値:$sql & Get ( アクティブフィールド名 ) & " text" ]
次のフィールドへ移動
Exit Loop If [ Get ( アクティブフィールド名 ) = "sql" ]
変数を設定 [ $sql; 値:$sql & ",¶" ]
End Loop
変数を設定 [ $sql; 値:$sql & "¶)" ]
SQL を実行 [ ODBC データソース: 「fm2sql」; 計算済みの SQL テキスト: $sql ]

````


# 方法4　ODBC接続を使ってFilemakerスクリプトでフィールド追加
* ALTER TABLE ADDを使う
* フィールド数がとんでもない場合など一発書きが危ういとき

````
SQL を実行 [ SQL テキスト: CREATE TABLE 商品 ( dummy INT ) ]
レコード/検索条件/ページへ移動 [ 最初の ]
フィールドへ移動 [ ローカル::商品番号 ]
Loop
変数を設定 [ $sql; 値:"ALTER TABLE 商品 ADD " & Get(アクティブフィールド名) & " TEXT;" ]
SQL を実行 [ ODBC データソース: 「fm2sql」; 計算済みの SQL テキスト: $sql ]
次のフィールドへ移動
Exit Loop If [ Get ( アクティブフィールド名 ) = "sql" ]
End Loop
````
jasmine導入方法（個人用）

JavaScript 用のテスティングフレームワークである Jasmine の使い方のメモ。個人用備忘録。
eclipseへの導入方法。
<br>

##ダウンロード
https://github.com/jasmine/jasmine
→「Download ZIP」
→  すべて展開

必要なライブラリ 4つ
　･jasmine.js
　･jasmine-html.js
　･boot.js
　･jasmine.css
　(･jasmine_favicon.png) ←ファビコン用
<br>

##コーディング
```html:sample.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    
    <script src="jasmine.js"></script>
    <script src="jasmine-html.js"></script>
    <script src="boot.js"></script>
    <link rel="stylesheet" href="jasmine.css" />
    <link rel="shortcut icon" type="image/png" href="jasmine_favicon.png" />
    
    <script src="app.js"></script>
    <script src="app-test.js"></script>
  </head>
  <body>
  </body>
</html>
```

```js:app.js
function add(a, b) {
    return a + b;
}
```

```js:app-test.js
describe('add 関数のテスト', function() {
    it('1 + 1 は 2', function() {
        expect(add(1, 1)).toBe(2);
    });
  
    it('1 + 4 は 5', function() {
        expect(add(1, 4)).toBe(5);
    });
  
    it('10 + 2 は 12', function() {
        expect(add(10, 2)).toBe(5); // わざと失敗させている
    });
});
```

配置
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/60528/dc1635fb-8c59-efff-a675-5436437052be.jpeg)
<br>
##表示
![jasmine.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/6f00ac1b-fb9a-9c16-7bc2-884eee8d771a.jpeg)

![jasmine.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/a03c7386-5ba6-55a3-89e3-629eb0bc0c29.jpeg)







<br>
参照
http://qiita.com/opengl-8080/items/cf3acafda9756f4b04c9
IPアドレスが指定した範囲内にあるかどうか判別する

アクセスしてきたIPアドレスが、サブネットマスクを含んだ指定のIPアドレスに該当するものかどうかを判断します。

```php
$accept = '203.0.113.0/24';
$remote_ip = $_SERVER['REMOTE_ADDR'];

list($accept_ip, $mask) = explode('/', $accept);
$accept_long = ip2long($accept_ip) >> (32 - $mask);
$remote_long = ip2long($remote_ip) >> (32 - $mask);
if ($accept_long == $remote_long) {
    echo 'acceptable';
} else {
    echo 'not acceptable';
}
```

`ip2long()`で変換したものをビットシフトし、サブネットマスク部分同士(上の例だと上位24ビット)が同じかどうかを比較しています。

[PHPマニュアル - ip2long](http://php.net/manual/ja/function.ip2long.php)
[PHPマニュアル - ビット演算子](http://php.net/manual/ja/language.operators.bitwise.php)
末尾のホワイトスペースを保存時に消す


# やりたいこと
末尾のホワイトスペースを保存時に消したい
ホワイトスペースの消す忘れをなくしたい

# 手順

## 選択

Preferenses > Packages
`whitespace`で検索する。
(whitespaceはデフォルトパッケージ)

![Settings_-__Users_innova_Documents_work_innova_phoenix_-_Atom.png](https://qiita-image-store.s3.amazonaws.com/0/2432/16b9c1f0-bdcd-5902-7e6d-cb45c52e060d.png)

## 設定

`Ignore Whitespace On Current Line`のチェックをはずす

![Settings_-__Users_innova_Documents_work_innova_phoenix_-_Atom_と_削除したときに、一緒に消えるデータのテストケースを書く.png](https://qiita-image-store.s3.amazonaws.com/0/2432/ae6b0cfb-7a20-c799-9128-9b9294a172b0.png)
エラーを検査する


> NOTE: この記事は [Inspecting Errors](http://dave.cheney.net/2014/12/24/inspecting-errors) を翻訳したものです。
> 原文に従い、 [Creative Commons](http://creativecommons.org/licenses/by-nc-sa/4.0/) ライセンスで公開します。

`error` インターフェイス型の値を返す関数の一般的な契約は、呼び出し側はその `error` をチェックする前にそれ以外のいかなる戻り値も利用してはいけないというものです。

多くのケースにおいて、関数が返した error 値は呼び出し元にとって不透明であるべきです。 error が nil かどうかチェックすることで呼び出しが成功したかどうかを知ることができ、そしてそれ以上のことはしません。

少ないケースにおいて、主にネットワークなどプロセス外の世界とやりとりする場合に、呼び出し側がエラーの種別を調べて、操作をリトライするべきかどうかを決める必要があります。

パッケージ作者に対して、呼び出し側がエラーの型を判別して利用できるように返すエラー型を公開して欲しいという要求がよくなされます。しかし、私はこの方法が幾つもの不幸な結果に繋がると信じています:

* 公開されたエラー型はパッケージのAPIの表面積を大きくする
* 実装を新しくした時、インターフェイスを定義したエラー型がもう実装にフィットしていないとしても、その型の値しか返せなくなる
* パッケージを公開した後は、互換性を壊さずにエラー型を変更したり廃止することができない。これは脆いAPIにつながります

呼び出し側は、 `error` が特定の型かどうか検査することを、 `Error()` メソッドが返す文字列が特定のパターンにマッチするかどうか検査するより便利だと思うべきではありません。

代わりに、パッケージの作者と利用者が、実装と呼び出し側を密結合することなく関心事についてコミュニケーションする方法を提案します。


## error を型ではなく振る舞いで検査する

error の値が特定の型であるかどうかを検査する代わりに、その値が特定の振る舞いを実装しているかどうかを検査してください。

この方法は、継承ベースの言語の *is a [subtype of]* よりも、 Go の暗黙のインターフェイスの *has a* 文化にうまくフィットします:

```go
func isTimeout(err error) bool {
        type timeout interface {
                Timeout() bool
        }
        if te, ok := err.(timeout); ok {
                return te.Timeout()
        }
        return false
}
```

呼び出し側はこの `isTimeout()` を使って、 error が `timeout` インターフェイスを持っているか判別し、持っているならそのメソッドに問い合わせることで、その error がタイムアウトであるかどうかを判別することができます。
この方法なら実際の型やその error 値の出自について一切知る必要がありません。

(よくライブラリがエラーの発生したパスを注釈するために行う) エラーのラッピングもこの方法で可能です。
ラップされるエラーが実装しているインターフェイスを、ラップする側にも実装します。

これは非現実的な方法に思えるかもしれません。しかし、実際には一般的に使われるインターフェイスメソッドは比較的少なくて、 `Timeout() bool` と `Temporary() bool` だけで多くのユースケースをカバーできます。

## 結論

error を型ではなく振る舞いで検査してください。

パッケージの作者は、もし一時的なエラーを返すのであれば、それに応じたメソッドを返すエラーの型に実装してください。もしエラー値をラップして返すのであれば、ラップするエラー値が実装しているインターフェイスをラッパーにも実装してください。

パッケージのユーザーは、エラーを検査する必要がある場合、エラーの型ではなく、エラーが期待する振る舞いをもっているかをインターフェイスを使って検査してください。パッケージの作者にパブリックなエラー型を追加するように依頼しないでください。かわりに Timeout() や Temporary() メソッドを適切に実装して一般的なインターフェイスに従うように依頼してください。
Swiftでdelay/force


`@autoclosure`が使えない所で`@autoclosure`的なことを実現してみた備忘録．

### @autoclosureを書けないが式を評価して欲しくない例
次のような関数`f`で，気分としては`h`の第二引数を`@autoclosure`的にしたいときがある．

```swift
func f<T,U,V>(x: T, g: T -> U, h: (T, U) -> V) -> V {
	return h(x, g(x))    // ここでg(x)を評価せず，hの中で評価したい
}

let v = f(0, {...}, {...})    // 直接クロージャを渡してfを呼ぶ
...
```
(注)：クロージャ定義では`@autoclosure`は書けない．

### delay/forceの導入
そこで，schemeなどにあるdelay/forceの仕組みを作る．

```swift
func delay<T>(@autoclosure(escaping) f: () -> T) -> () -> T {
    return f
}
```
関数`delay`は`@autoclosure`を使って引数を評価せずにそのまま返すだけ．
関数`f`は，

```swift
func f<T,U,V>(x: T, g: T -> U, h: (T, () -> U) -> V) -> V {
	return h(x, delay(g(x)))
}

let v = f(0, {...}, { ...$0,... $1() })    // $1()でdelayしたものをforceする
...
```
delayを受け取れるようにhのタイプを`(T, U) -> V`から`(T, () -> U) -> V`へ変更する．
force処理はfの第3実引数であるクロージャ内で`()`つけて起動すればよい．そのクロージャの第二引数(`$1`)がdelayされた評価待ちの式（クロージャ）である．

### 動作確認

```swift
func f(x: Int, g: Int -> Double, h: (Int, () -> Double) -> String) -> String {
	print("f ")
	return h(x, delay(g(x)))
}

let g0 = {(x: Int) -> Double in print("g "); return Double(x) * 2 }
let h0 = {(x: Int, k: () -> Double) -> String in print("h "); return "\(Double(x) + k())" }

print(f(1, g0, h0))    // f h g 3.0
```
ちゃんと"f h g"の順番で表示され，gの評価が遅延されてることが分かる．

### 利用例
こんなの必要なの？という疑問が湧くので，便利そうな例を挙げておこう．

```swift
func foldr<G: GeneratorType, T>(var gen: G, initVal: T, f: (G.Element, () -> T) -> T) -> T {
    if let v = gen.next() {
        return f(v, delay(foldr(gen, initVal, f)))
    }
    return initVal
}

func reduce<S: SequenceType, T>(seq: S, initVal: T, f: (S.Generator.Element, () -> T) -> T) -> T {
    return foldr(seq.generate(), initVal, f)
}
```
この`reduce`は組み込みのものと違い，シーケンスを全スキャンしないような処理が可能である．
例として，シーケンスの中に条件に合うものがある場合に真を返す関数`hasElement`を定義してみよう．

```swift
func hasElement<S: SequenceType>(seq: S, pred: S.Generator.Element -> Bool) -> Bool {
    return reduce(seq, false) { pred($0) ? true : $1() }
//    return reduce(seq, false) { pred($1) ? true : $0 }  // 組み込みのreduce
}
```
要素が見つかった場合，`$1()`が実行されないので，シーケンスのスキャンはそこでストップする．

```swift
for e in seq {
	if pred(e) {
		return true
	}
}
return false
```
と同等の動作をするのがこの`reduce`である．たった一行で書けてしまう．
ログオン・ログオフ時にPowerShellを起動しSlackへ通知する【Windows7】

[PowerShellからSlackに通知する方法](http://qiita.com/mikage014/items/2d8fff56eb84a6a751ea)が投稿されていたので、出社・退社をログオン・ログオフでSlackに記録したいなー。
手動でSlackに入れていたら見事に3日坊主でした。

# PowerShellの準備
動作環境は
[【メモ】PowerShell書き始めるまで](http://qiita.com/khsk/items/808c2a71976c4dbcc2b8)
使用するプログラムは
[PowerShellからSlackに通知する方法](http://qiita.com/mikage014/items/2d8fff56eb84a6a751ea)
で紹介されているままのプログラムでOK。
最初は固定メッセージで2個作ってましたが、登録時にパラメーターを設定できるので引数でメッセージを変えられます。

# ログオン・ログオフ時の登録
調べればすぐに出ますが…
1. スタートメニューからポリシーで検索
2. グループポリシーの編集

* ユーザーの構成
    * Windowsの設定
        * スクリプト(ログオン/ログオフ)
        * 右窓のログオン/ログオフをダブルクリック
            * ログオン/ログオフのプロパティ
            * PowerShellスクリプト タブ
            * 追加
                * スクリプト名：参照から作成したプログラム
                *  スクリプトのパラメーター：通知したいメッセージ

# Slack APIを使用する
Slackに通知はできたが、Incoming WebHooksでは(名前を同じにしても)BOTが行った通知になってしまう。
できれば既存のユーザーが通知したことにしたい。
調べたら２月頃にSlack APIに`as_user`なるオプション追加が追加されたらしい。
任意のユーザーではなく、「Slack APIのトークンを発行したユーザー」として通知できるらしい。
全員で使うには全員がトークン発行しなければならない……
トークンの発行は権限に関係なくできるのかな？(未調査)
まぁ、今は一人なので無問題ですが。

## トークンのとーろく
[Slack APIを使ってプッシュ通知を受け取ろう](http://www.bunnyhop.jp/lab-20141020/)
を見てその通りに。

1. IntegrationsからSlack APIを選択
2. 左メニューからWeb APIを選択
3. 最下層にトークン発行ボタン「Create token」があるのでおもむろにクリック

Slack APIに飛んだらSlack APIの説明画面でちょっと面食らいます。
トークン発行もその画面で出来ないので慌ててぐぐりました。

### TOPIC:`chat.postMessage`のテスト
slackに通知する主機能？な`chat.postMessage`のドキュメントから[動作テストのページに飛べます](https://api.slack.com/methods/chat.postMessage/test)
トークン発行後なら実際にSlackへ通知することができるので、どんな動作やURLになるかなど、軽い検証ができます。

## Slack API PawerShell
Slack APIになり、メソッドが`POST`から`GET`になりました。
よって、パラメーターはJSONからURLに付加する形になります。

```ps1:Slack_API版
$utf8Bytes = [System.Text.Encoding]::UTF8.GetBytes($args)
$text = [System.Text.Encoding]::GetEncoding('UTF-8').GetString($utf8Bytes);
$channel = "xxx" # #ramdom
$token = "xxx"
$text = [System.Web.HttpUtility]::UrlEncode($text)

Invoke-RestMethod -Uri "https://slack.com/api/chat.postMessage?token=$token&channel=$channel&as_user=true&text=$text" -Method Get

```

参考にしたIncoming WebHooks版と比較して、
1. 入力をURLエンコードしている
2. バイト文字列から文字列への変換時のコードを`ISO-8859-1`から`UTF-8`に変更

2に関してはなぜこうしなければならないのか、が最初の`UTF-8`バイト文字列での取得から理解していないので調査しておきます。
`ISO-8859-1`では文字化けが起こりました。


~~Slack API版はシェル上では成功してますが、ログオン・ログオフ時の動作は未検証です。明日にでも問題なくこの文章を消せたらいいな。~~
***

**追記**
今さらですが、うまく動いています。
BOT表記もなくなっているので、見た目では自分が発言しているように見えます。
ただし、環境によっては(スタートアップ量？)PowerShellの実行優先度が低いのか、ログインから数分以上あとに発言されることも…
Slack上では遅刻魔に！みたいなこともあるかもしれません。

***

今は毎回同じメッセージなので、複数のパラメーターを渡してランダムに通知してくれるようにしたい。
Python+NetworkX+ソーシャルデータで最短経路を解いてみる


![graph解析.png](https://qiita-image-store.s3.amazonaws.com/0/1418/7517fb52-5e88-9d57-2d7c-5507066ceb03.png "graph解析.png")


## やったことや目的など
私は[TalentBase](https://talentbase.io?cn=qiita "TalentBase")というタレントマイニングサービスを開発・運営をしており、膨大なソーシャルデータを解析しています。

そんな中で、人間関係を把握する意味でグラフ解析の一環として「この人とこの人はどれくらいの距離感の関係？」ってことを解析することに。

## 環境構築
Python, NetworkX
がインストールされていれば、すぐに実装できます。

## データの準備
データはSNSの有向グラフデータを使い、人と人の最短経路問題として距離を仮想的に図ってみることにしました。

データがMySQLに保存されていた関係で、mysql-connectorを使ってDBに接続して有向グラフデータを取得して、それをNetworkXで計算するというスキームで実装しました。

## 実装・計算
```main.py
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    import networkx as nx
    import mysql.connector
    
    db_config = {
      'user': 'USERNAME',
      'password': 'PASSWORD',
      'host': 'HOST',
      'database': 'DATABASE',
      'port': 'PORT'
    }
    
    connect = mysql.connector.connect(**db_config)
    cur=connect.cursor(buffered=True)
    
    g = nx.DiGraph()
    
    cur.execute("select FROM_USER_ID,TO_USER_ID,WEIGHT from TABLE_NAME")
    rows = cur.fetchall()
    
    for row in rows:
      if row[0] == row[1] or row[0] is None or row[1] is None:
        continue
      g.add_node(str(row[0]))
      g.add_node(str(row[1]))
      g.add_edge(str(row[0]),str(row[1]), weight=int(row[2]))
    
    # ダイクストラ法で最短経路を探す
    print nx.dijkstra_path(g, 'NODE1', 'NODE2') # NODE1からNODE2への最短経路を出力
    #出力例 => ['NODE1','NODE9','NODE3','NODE7','NODE5','NODE2']
    print nx.dijkstra_path_length(g, 'NODE1', 'NODE2') # NODE1からNODE2への最短経路の距離を出力(weightが全て1だったらNODEを渡った数が距離になる)
    #出力例 => 8
```


## 考察
大容量のグラフデータを扱い始めると、今回行った計算は結構時間がかかってしまうので、
次回はNeo4jなどを代表するGraphDBを使って解析してみたいと思います。