OmniAICreator/Qiita-1.07M huggingface dataset:
カジュアルユーザのためのMySQL

この記事は [MySQL Casual Advent Calendar 2015](http://qiita.com/advent-calendar/2015/mysql-casual) の2日目です。

最近 MySQL Casual Talks vol.8 で小規模な環境について特集したわけですが、実は初参加という人が半数近くいらっしゃいました。
そういう事もあって、これからMySQLを使ってみようという人も実は増えてきているのではと勝手に思っています。

そういう人にとって、自分でMySQLをセットアップして運用するのは大変な作業だと思います。
かと言って、RDSのようなサービスはちょっと大鉈過ぎるので、気軽に使えて安い(できれば無償)MySQL環境には一定の需要があるかなと。

そんなわけでこのエントリではカジュアルユーザのためのMySQL環境構築について書きます。

# 無償で使える MySQL as a Service

- 上記のとおり、MySQLを自分でインストールしてウンヌンするのはカジュアルユーザにとっては大変です。そこで欲しくなるのがMySQL as a Serviceなわけですが、[ClearDB](https://www.cleardb.com/) を使うとお気楽です。
- ClearDBのサービスを使うと、コマンドかUIからポチッとやるだけでMySQLの環境が手に入ります。
- ClearDBを直接使うのもいいのですが、クラウド各社がサードパーティ製として提供しているものにはFreeプランがあるのでそれを使うとお金がかからないのでより気軽でしょう。

## 代表的な各サービスでの提供形態
- Heroku
 - addonにてClearDBが提供されています。
 - Igniteというプランで *5MB* まで無料です。
 - それ以上使う場合、10GBまでを上限としたプランもあるので、ちょっと増えても安心です。

- BlueMix
 - サードパーティサービスとしてClearDBが提供されています。
 - Spark DBというプランで *5MB* まで無料です。
 - が、このプランしかなく、これ以上必要になる場合はUpgrade先がないのが残念です。

- Azure
 - UIに統合されて "MySQLデータベース" メニューとして提供されています。
 - 火星プランが *20MB* まで無料です。
 - 共有型と占有型があり、最大1TBまでのプランがあるので、大きくなっても受け入れられるようにはなっています。

と、各社いろいろあるわけですが、DBaaSとしてMySQLを使いたい場合実はAzureが無料で20MBまで使えるのでお買い得(どれも無料だけど)になっていますね。
そんなわけで今回はAzureでどうやるかをスクショ交えてまとめます。

# AzureでMySQLを使う

- ポータルに "MySQL データベース" という名前でメニューがあるので開きます
 - <img width="868" alt="Screen Shot 2015-12-02 at 13.48.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/6835/e5dfef9b-9911-b1bd-072a-36677c757e07.png">

- 必要項目を入力しつつ、"火星"を選択(なんでTitanだけTitanなのかは謎)して作成
 - <img width="880" alt="Screen Shot 2015-12-02 at 13.49.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/6835/2d23cc14-2653-d098-0ed5-41f18d724b16.png">

- 作成するとダッシュボードにリンクができます
 - <img width="947" alt="Screen Shot 2015-12-02 at 13.49.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/6835/5dba1e11-4af1-8474-1285-2ac2dc859257.png">

- こんな感じに
 - <img width="207" alt="Screen Shot 2015-12-02 at 13.58.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/6835/be7114b0-1bcf-24b2-8ec6-20848716000a.png">

- ダッシュボードのリンクを開くと利用状況が見られます
 - <img width="905" alt="Screen Shot 2015-12-02 at 13.58.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/6835/3011b1fc-cb80-50b4-66e4-f96d2b48cc1f.png">

- 接続文字列とかもコピペ出来るようになってるのがカジュアルです＾＾
 - <img width="622" alt="Screen Shot 2015-12-02 at 13.59.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/6835/6947b126-1013-83e7-10fc-51e86da501d6.png">

- ターミナルから接続してみると、こんな感じです。
 - <img width="476" alt="Screen Shot 2015-12-02 at 15.16.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/6835/f81b542b-f8b9-9d5d-2345-c0dcb4a8722d.png">


# 終わりに
- インストールせず、運用せず使えるMySQLはカジュアルユーザにとても優しいので初心者も安心ですね。
- MySQL始めの一歩を踏み出したいという方は、こういうやり方で触り始めるのがいいと思います。
- 次の記事は決まっていません。。。是非こういうゆるい感じで構わないので奮ってご参加頂けると嬉しいです！
 - 参加登録はこちら -> [MySQL Casual Advent Calendar 2015](http://qiita.com/advent-calendar/2015/mysql-casual)
single serverでのインストール方法(rubygems)

とりあえずまずは使ってみたいという方用の、single serverにinstallする手順です。
(実際の本番環境では複数台でクラスターを組むことを推奨します)

# 条件
server: 1台
storage type : memory
ruby version : v2.1
ROMA version : v1.2.0
Installation type : rubygems

# 手順
## 1. install ROMA
```
gem install roma
```

## 2. make instance(Cluster)
```
mkroute localhost_10001 localhost_10002 --replication_in_host
ls -l
  -rw-r--r-- 1 root root 35693 Dec  2 05:35 localhost_10001.route
  -rw-r--r-- 1 root root 35693 Dec  2 05:35 localhost_10002.route
```
- `mkroute`コマンドはROMAのクラスター構成ファイル(routing file)を作成します。
- `--replication_in_host`オプションは同一サーバ内でのデータ複製を許可するオプションです。通常はdebug用にsingle serverで構成するときのみ使用します。

## 3. booting ROMA
```
romad localhost -p 10001 -d --replication_in_host
romad localhost -p 10002 -d --replication_in_host
```
- `romad`コマンドのusage  
`romad <address> [options]`
- `-p`オプションはROMAのport No.を指定します
- `-d`オプションはROMAをdaemonモードで起動します  
他のオプションに関しては[ROMA Commands](http://roma-kvs.org/commands.html#dist-jump-link-romad) をご参照ください

# 挙動確認
```
telnet localhost 10001
> version
  VERSION ROMA-1.2.0

> stat node
  stats.run_receive_a_vnode {}
  routing.nodes.length 2
  routing.nodes ["localhost_10001", "localhost_10002"]
  routing.vnodes.length 512
  routing.short_vnodes 0
  routing.lost_vnodes 0
  routing.version_of_nodes {"localhost_10001"=>66048, "localhost_10002"=>66048}
  END

> set foo 0 0 3
  bar
  STORED

> get foo
  VALUE foo 0 3
  bar
  END

> balse
  Are you sure?(yes/no)
> yes
  {"localhost_10002"=>"BYE", "localhost_10001"=>"BYE"}
  Connection closed by foreign host.

```
- `stat node` コマンドはROMAの基本的なstatus情報を表示します
- `set`コマンドのusage 

```
set <key> 0 <expt> <value length>\r\n
<value>\r\n
```
- `balse` コマンドはROMA Clusterを終了させるコマンドです  
(`shutdown`コマンドも同様の動きをします)

# 参照URL
ROMA Getting Started : http://roma-kvs.org/getting_started.html
ROMA commands page : http://roma-kvs.org/commands.html
ROMA FAQ page : http://roma-kvs.org/learn/faq.html
Linuxコマンドで重複している行（だけ）を見つけたいとき （sortとuniqコマンド）

## 【こんな貴方の助けになれば】
・Excelの機能で重複削除すると、重複してた行が消えてしまうから、**何が重複してたのか**、知りたい。（関数使えばわかるけど、そんなの面倒）

・そもそも、Excel使いたくないし、Linuxサーバ上だけで完結させたい。

##【ポイント】
重複関連は、uniqコマンドで、いける。

ただ、uniqコマンドは、ソートしていないとダメらしい。
（ここは、Excelのvlookup関数と一緒ですね）
なので、先にsortコマンドを使用します。


##【コマンド例】
uniqの -d オプションで、重複行を標準出力することができます。
>sort *"重複見つけたい.txt"* | uniq -d

* * * 
もちろん、リダイレクトすればファイルに出力されます。
下記は、**重複している行だけ**、出力されます。
>sort *"重複見つけたい.txt"* | uniq -d > *"重複してる行だけになる.txt"*


* * * 
下記は、重複していない行だけ、出力されます。（重複削除後のファイルを生成）
>sort *"重複見つけたい.txt"* | uniq > *"重複してない行だけになる.txt"*

##【コマンド実行例】
■元のファイル
> $ cat hogehoge.txt
AAAAA
BBBBB
19000
BBBBB
AAAAA
19000
9000

■重複行を削除した結果を表示
> $ sort hogehoge.txt | uniq
19000
9000
AAAAA
BBBBB

■重複している行だけを表示
> $ sort hogehoge.txt | uniq -d
19000
AAAAA
BBBBB

## 【注意点】
当たり前ですが、ファイルサイズが大きいものを実施する際は、メモリやCPUにご注意ください。
安全かつ正確な動作を保障しきれませんので、ご了承ください。
MacOSXでUSBにISOイメージを書き込む


基本パターンは以下の通り。

```
$ hdiutil convert -format UDRW -o destination_file.img source_file.iso
$ diskutil list
$ diskutil partitionDisk /dev/disk2 1 "Free Space" "unused" "100%"
$ sudo dd if=destination_file.img.dmg of=/dev/disk2 bs=1m
$ diskutil eject /dev/disk2
```

1行目 isoをUDRWに変換
source_file.iso:ISOイメージファイル
destination_file.img:ISOから変換するファイル名（変換後は勝手に.dmgが付加されるが問題ない）

2行目 USBメディアデバイス名を確認
3行目 USBメディアをフォーマット
/dev/disk2:diskutil listで確認したUSBデバイス名
4行目 ddで書き込み
5行目 イジェクト処理


参考
https://blog.tinned-software.net/create-bootable-usb-stick-from-iso-in-mac-os-x/
せんせい、あのね

#IDCFクラウドとぼく　やまがたいちりつだいさんしょうがっこう　６年２組　かわい　まさひろ

せんせい、あのね、ぼくは１ねんまえからIDCFクラウドをつかっています。どうしてぼくがつかいたかったのか、せつめいしようと思います。

##IDCFクラウドをどうしてつかったのか？

IDCFクラウドをつかったりゆうは、むかしからおともだちだったからです。それから、あまぞんというがいこくのさーばーよりもやすかったからです。ためにしつかったときに、ものすごくはやくさーばーのせっとあっぷがおわりました。SSDをつかっていないのにHDDだけであのすぴーどはほんとすごかったです。

##IDCFクラウドのつかいかた

ぼくは、じぶんの会社のほーむぺーじをうごかしています。わーどぷれすというCMS上でうごいています。てんぷれーともただだけどつかいやすいものをえらびました。

##IDCFクラウドをつかってよかった！

とにかくやすいです。いちねんかんぐらいずっとおかねをIDCFさんにわたしていません。ほんとうにありがとうとかんしゃしています。らいねんはちゃんとおかねをはらうぐらいつかいたいたいです。

##牛丼１杯でクラウドたいけん！
わーどぷれすをいんすとーるするには、ぎゅうどんいっぱいぶんの５００えんあれば１っかげつまんぷく、いえまんぞく。さくさくさくさくうごきます。
２だんかいていがくみたいなねっとわーくはうれしかったです。
あとSSH-keyもとてもかんたんにつくれました。

##おわり
ぼくがつかってもかんたんにわーどぷれすがつかえました。ぎじゅつしゃじゃなくてもかんたんにつかえるところがみりょくてきです。これからもつかっていきたいとおもいました。
Tweetボタンとスマホアプリに関する問題

スマートフォンでTweetボタンをクリックした時、URLが付属せずに記事タイトルだけがツイートされてしまう現象があることに気づきました。

![image](https://qiita-image-store.s3.amazonaws.com/0/30743/2e618064-2881-7e60-d0a7-3d550a699dac.png)

この現象は、例えば以下の様な環境で発生します。

* AndroidスマートフォンにTwitter公式アプリをインストールしている
* Tweetボタンに、HTML data-* 属性を利用している

# HTML data-*属性によるTweetボタン

　data-* 属性を使ったTweetボタンはTwitter公式にも記載されている正式な機能です。
[Tweet Button Parameter Reference | Twitter Developers](https://dev.twitter.com/web/tweet-button/parameters)

```html
<a class="twitter-share-button"
  href="https://twitter.com/share"
  data-size="large"
  data-url="https://dev.twitter.com/web/tweet-button"
  data-via="twitterdev"
  data-related="twitterapi,twitter"
  data-hashtags="example,demo"
  data-text="custom share text">
Tweet
</a>
```

こんな感じで記載すると、このようなツイートを行う事ができるリンクを表示することができます。

![image](https://qiita-image-store.s3.amazonaws.com/0/30743/fb3c7963-ffef-4b55-92db-25462a9dbecb.png)

data属性を使うとURLエンコードしなくていいので楽だし、URLやハッシュタグを明確に分けることができてプログラマ好みなので、できれば使いたいですよね。

(2015-12-03追記)
コメント欄でご指摘いただいたのですが、Twitterとしては、data-属性を書けばいいと言っているわけではなくて、[twitterのJavaScriptコード](https://dev.twitter.com/web/javascript/loading)で置き換えることを前提として、data-*属性でパラメタを指定できるよ、という意図のようです。
[Tweet Button | Twitter Developers](https://dev.twitter.com/web/tweet-button)

なので、data属性で書いときゃ動くだろ、という認識は誤りですね。
(追記おわり)

# Androidのディープリンク機能

　Androidでは、ディープリンクという機能があって、例えば「 https://twitter.com/ 」で始まるURLはTwitter公式アプリで開く、というような設定が可能です。

[App Indexing  |  Google Developers](https://developers.google.com/app-indexing/android/app?hl=ja)

このおかげで、例えばFacebookで紹介されていたTwitterのURLをクリックした場合でも、ブラウザで開くのではなくて、Twitterアプリで該当のツイートを見ることができます。

Tweetボタンも、ブラウザでTweetボタンをクリックした瞬間Twitterアプリが立ち上がって、アプリからツイートすることができるようになります。ログインとかしなくて良くて先進的ですね。

しかし、ディープリンクは、URLに対して処理が行われるものなので、今のところdata属性までは見てくれません。このため、data-* 属性に書かれたURL部分は、Twitterアプリにわたらなくなってしまいます。結果として、href部分に書かれたテキストだけが引き渡され、なんだか実用性の薄いTweetボタンになってしまいます。

![image](https://qiita-image-store.s3.amazonaws.com/0/30743/2e618064-2881-7e60-d0a7-3d550a699dac.png)

# 対策

　data属性を付ける場合でも、href部分にはパラメタを埋め込んでおくのが良さそうです。

```html
<a class="twitter-share-button" 
  href="https://twitter.com/share?text=custom+share+text&url=https%3A%2F%2Fdev.twitter.com%2Fweb%2Ftweet-button" 
  data-url="https://dev.twitter.com/web/tweet-button" 
  data-text="custom share text">
Tweet
</a>
```

それじゃなんのためのdata属性だよ、という気もしますが、AndroidにTwitter公式アプリが入っている環境というのは決して少数派じゃないので、GoogleかTwitterかどっちかが対策するまではしょうがないんじゃないかな。

(2015-12-03追記)
ということで、hrefに手作業で書く必要はなくて、[Tweet Button | Twitter Developers](https://dev.twitter.com/web/tweet-button) の指定通り、JavaScriptで置き換えるのが正解ですね
(追記おわり)
nendのネイティブ広告を実装してみた


## 実装手順書

nendの場合は一般に広く公開されていて審査も通りやすく、一度はみんな使うと思う。
手順書やSDKはgithubにあるよ [こちらからどうぞ](https://github.com/fan-ADN/nendSDK-iOS/wiki/%E3%83%8D%E3%82%A4%E3%83%86%E3%82%A3%E3%83%96%E5%BA%83%E5%91%8A%E5%AE%9F%E8%A3%85%E6%89%8B%E9%A0%86)

## 感想
2015/12/02現在 広告枠の承認待ちのため広告が出ないのでなんとも言えない

## 実装やドキュメントみながらボヤく
### 手順はこれ
大きく分けて3つのステップがある [こちらからどうぞ](https://github.com/fan-ADN/nendSDK-iOS/wiki/%E3%83%8D%E3%82%A4%E3%83%86%E3%82%A3%E3%83%96%E5%BA%83%E5%91%8A%E5%AE%9F%E8%A3%85%E6%89%8B%E9%A0%86#%E3%83%8D%E3%82%A4%E3%83%86%E3%82%A3%E3%83%96%E5%BA%83%E5%91%8A%E5%AE%9F%E8%A3%85%E6%89%8B%E9%A0%86)

### 名称が分かりにくい

下記の名称は重要で、後々 `制限事項` 時に問題になってくるので気をつける必要がある。
[こちらからどうぞ](https://github.com/fan-ADN/nendSDK-iOS/wiki/%E3%83%8D%E3%82%A4%E3%83%86%E3%82%A3%E3%83%96%E5%BA%83%E5%91%8A%E5%AE%9F%E8%A3%85%E6%89%8B%E9%A0%86#%E5%BA%83%E5%91%8A%E6%83%85%E5%A0%B1%E3%82%92%E3%83%AC%E3%82%A4%E3%82%A2%E3%82%A6%E3%83%88%E3%81%97%E3%81%9Fview%E3%82%92%E5%AE%9A%E7%BE%A9)

- 広告明示
- 広告見出し
- 広告文
- プロモーション名
- 表示URL
- アクションボタン
- 広告画像
- ロゴ画像

### 制限事項が分かりにくい
名称の説明と制限事項の説明の間に、サンプルソースが入ってしまい、分かりにくくしている。
広告には最低限必要なフォーマットが存在し、それらを実装しなければ不正とみなすって意味ぽい。

[こちらからどうぞ](https://github.com/fan-ADN/nendSDK-iOS/wiki/%E3%83%8D%E3%82%A4%E3%83%86%E3%82%A3%E3%83%96%E5%BA%83%E5%91%8A%E5%AE%9F%E8%A3%85%E6%89%8B%E9%A0%86#%E5%88%B6%E9%99%90%E4%BA%8B%E9%A0%85)

### NADNativeClient
細かい説明はないが、想像するにこいつがImpression管理をしているとおもわれ。
こいつがimp通知をした後は、同じインスタンス上は広告が更新されることが無いのだとおもわれる。

initとloadにわかれているが、この辺は広告枠が承認されないと、なんとも言えない。

## nendログを眺める
何かが出てるな・・・

```
2015-12-02 17:22:09.857 weather_hacker[3891:3634765] [nendSDK Debug] Check frame of child view: {{35, 165}, {250, 30}}, parent: {{0, 0}, {320, 62}}
2015-12-02 17:22:09.857 weather_hacker[3891:3634765] [nendSDK Warn] Label is not located on the inside of the parent view.
2015-12-02 17:22:09.857 weather_hacker[3891:3634765] [nendSDK Warn] View must include PR label.
```

## 広告が表示されるまでの旅路
### 広告と枠のサイズをvalidationしてる？
```
2015-12-02 17:42:30.849 weather_hacker[3911:3641271] [nendSDK Debug] Check frame of child view: {{0, 250}, {320, 256}}, parent: {{0, 0}, {320, 300}}
```
![Slack for iOS Upload.png.jpeg](https://qiita-image-store.s3.amazonaws.com/0/4107/ca1b996f-8d04-47d5-3578-6f13ff01fa1f.jpeg "Slack for iOS Upload.png.jpeg")
広告が表示されない。。。

## まとめ
### いい感じに普通
広告タグ側の導入に対し、視覚的に対応できることが増えた反面、広告SDK側の対応は普通だった。
ネイティブ広告の実装は、各社がデベロッパーに対し、便利なものを提供しようとすればするほど、
実装が複雑になる気がするので、nendくらいなのがちょうどいいかも。

### NADNativeImageViewなど
他の広告と自分で混ぜて使うにはUIImageViewではないところが、使いにくいなとおもった。
xibを作成するにも、いちいち指定しないとけないし。
Go言語でRedshiftとつなぐ（というかただのPostgreSQL）

# ゴール

- Go言語からRedshiftにつないでクエリとかする

# Redshiftとは

- [Amazon Redshift および PostgreSQL](http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/c_redshift-and-postgres-sql.html)

Redshiftへの接続およびクエリはPostgresだと思ってだいたい問題ないっぽいです。（一度、`ISNULL`使っててRedshiftには`ISNULL`無いので`COALESCE`使う、みたいなつまずきがありましたが...）

# Go言語からPostgresにつなぐ

どこにでもあるGoでsql使うサンプルです

```go
package main

import (
	"database/sql"
	"log"

	_ "github.com/lib/pq"
)

// User 適当に
type User struct {
	Name string `sql:"username"`
}

func main() {
	db, err := sql.Open("postgres", "postgres://user:pass@host:port/dbname")
	if err != nil {
		log.Fatalln("つなぐの", err)
	}
	defer db.Close()

	row, err := db.Query("SELECT username FROM users WHERE username LIKE $1 LIMIT $2", "otiai%", 10)
	if err != nil {
		log.Fatalln("クエリするの", err)
	}

	for row.Next() { // 行があるまでtrue
		user := new(User)
		err := row.Scan(&user.Name)
		if err != nil {
			log.Fatalln("結果をスキャンするの", err)
		}

		log.Printf("%+v\n", user)
	}
	if err := row.Err(); err != nil {
		log.Fatalln("イテレーション中の", err)
	}
}
```

上記の、`postgres://user:pass@host:port/dbname`に該当するところを、お使いの（RDSなり）Redshiftのインスタンスであるところの`foo.bar.region.redshift.amazonaws.com:5439`とかにすれば、普通に動くはずです。

# めんどいのでORMつかおう

もはやRedshift関係無いんですが、Goの`database/sql`十分可愛いけど、row.Nextとかrow.Scanとかめんどいので、そのへんもいい感じにマッピングしてくれるやつ使う。

今回はgormで

```diff
 package main

 import (
-	"database/sql"
 	"log"

+	"github.com/jinzhu/gorm"
 	_ "github.com/lib/pq"
 )

 // User 適当に
 type User struct {
-	Name string `sql:"username"`
+	Name string `gorm:"column:username"`
 }

 func main() {
-	db, err := sql.Open("postgres", "postgres://user:pass@host:port/dbname")
+	db, err := gorm.Open("postgres", "postgres://user:pass@host:port/dbname")
 	if err != nil {
 		log.Fatalln("つなぐの", err)
 	}
 	defer db.Close()

-	row, err := db.Query("SELECT username FROM users WHERE username LIKE $1", "otiai%")
+	users := []User{}
+	err = db.Where("username LIKE ?", "otiai%").Limit(10).Find(&users).Error
 	if err != nil {
-		log.Fatalln("クエリするの", err)
-	}
-
-	for row.Next() { // 行があるまでtrue
-		user := new(User)
-		err := row.Scan(&user.Name)
-		if err != nil {
-			log.Fatalln("結果をスキャンするの", err)
-		}
-
-		log.Printf("%+v\n", user)
-	}
-	if err := row.Err(); err != nil {
-		log.Fatalln("イテレーション中の", err)
+		log.Fatalln("クエリしてスキャンするの", err)
 	}
+	log.Printf("%+v\n", users)
 }
```

すげー楽。gormが、Findとかで渡すstructのtype名見て、この場合勝手に`users`というテーブル名を入れます。発行されるSQLを生で見たい場合は

```go
db.LogMode(true)
```

と、どっかにはさめばstdoutに出ます。

- https://github.com/jinzhu/gorm


# というか

ぜんぜんRedshiftの記事じゃなかった...
Vagrant+CentOS7+Ansibleで手短にDocker環境を構築したい


# 必要ソフトウェア

* [x] Vagrantをインストールしておく
* [x] Virtualboxをインストールしておく


# vbguestをインストールしておく

事前にVirtualBox Guest Additionsプラグインをインストールしておく。
これがないと、hashicorpのCentOS7 boxでは、synced_folderが指定できない。

```
vagrant plugin install vagrant-vbguest
```

# Vagrantfileを作る

最低限、こんなかんじ。

```ruby:Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "centos/7"
  config.vm.network "private_network", ip: "192.168.11.11"
  config.vm.provision "shell", :path => "provision.sh"
  config.vm.synced_folder ".", "/home/vagrant/sync", disabled: true
  config.vm.synced_folder ".", "/vagrant"
end
```

# プロビジョン時にAnsibleをインストールする

AnsibleはゲストOS、つまりCentOS7上で動かすようにする。そのために、Ansibleをプロビジョニング時にインストールする。

```bash:provision.sh
#!/usr/bin/env bash

set -eux

if ! [ `which ansible` ]; then
  sudo yum install -yq epel-release
  sudo yum install -yq ansible sshpass
fi

ansible-playbook -i /vagrant/ansible/hosts /vagrant/ansible/playbook.yml
```

# AnsibleのPlaybookをつくる

次の2つのファイルを作る。

* ./ansible/host
* ./ansible/playbook.yml


```text:ansible/host
127.0.0.1 ansible_connection=local
```

Playbookはこんなかんじに。

```yaml:ansible/playbook.yml
---
- hosts: 127.0.0.1
  connection: local
  sudo: yes
  tasks:
    - name: Docker group should exist
      group: name=docker state=present

    - name: Vagrant should be a member of docker group
      user: name=vagrant groups=docker state=present

    - name: Docker should be installed
      yum: name=docker state=present

    - name: Docker should be running
      service: name=docker state=started enabled=yes

    - name: docker-compose command should be installed
      get_url: url=https://github.com/docker/compose/releases/download/1.5.1/docker-compose-Linux-x86_64 dest=/usr/local/bin/docker-compose mode=755 sha256sum=5b9b6287c95103a553f8902e1e607bf4cdae74466f66a78d25195252ba380b0e
```

あとは、Vagrantを起動するだけ。

```
vagrant up --provider=virtualbox
```
Linuxデスクトップ環境を Gifに記録する

Windowsや MacOSXだと [Licecap](http://www.cockos.com/licecap/)やその他様々なツールで作業などを Gifで記録することができるのですが, Linuxだとそのようなツールがあまりありません. 動画形式で記録しそれを gifに変換というのがわりといろいろなところで書かれている印象ですが, そうやって作成した Gifは綺麗でないわりにファイルサイズがやたらでかいものとなることが多いです.

Linux環境にまともなものないんかいと思っていたところに見つけたのが [byzanz](https://git.gnome.org/browse/byzanz/)です. これで作成した Gifはサイズが小さめなわりに品質は高く Githubの README.mdにも問題なく貼れます.

## インストール

Debian系は以下のとおりです. (注: 古い Ubuntuだと PPAから取得する必要があります)

```
% sudo apt install byzanz
```

Redhat系は以下のとおりです(Fedoraにはパッケージがあるようです.)

```
% sudo yum install byzanz
```

## 使い方

以下のようになります.

```
% byzanz-record --duration=15 --x=200 --y=300 --width=700 --height=400 out.gif
```

いちいち座標を指定するのが面倒ですね. そこで拙作の [byzanz-window](https://github.com/syohex/byzanz-window)です.


## byzanz-window

上述の通りコマンドラインからすべて操作するのは面倒なので, byzanzには byzanz-window.pyという Pythonで書かれたユーティリティが付属していました. しかしそれは Python2でしか動かないもので, Python3をメインに使っている私の環境では動きませんでした. そこでそれを Goで書き直し, マウスでドラッグした範囲を撮影する機能を追加しました.


### リポジトリ

https://github.com/syohex/byzanz-window

### 事前準備

Debian系の場合

```
sudo apt install byzanz xdotool x11-utils libx11-dev
```

Redhad系の場合

```
sudo yum install byzanz xdotool xorg-x11-utils libx11-devel
```

### インストール

一応[バイナリ](https://github.com/syohex/byzanz-window/releases)もおいていますが, あまり確認していないのでソースからインストールした方が確実かと思います.

```
% go get -u github.com/syohex/byzanz-window/cmd/byzanz-window
```

### 利用方法

基本的には以下のようになります.

```
% byzanz-window --duration=30 --delay=5 output.gif
```

`--duration`で取る時間(単位: 秒), `--delay`で何秒後から撮影を開始するか, 最後に出力するファイル名を指定します. 基本はこれらのオプションと後述するモード指定のためのオプションで十分と考えます. その他のオプションは `--help`や [README.md](https://github.com/syohex/byzanz-window)を参照してください.

撮影モードは 2つあり, 指定したウインドウを記録する Windowモード(デフォルト)と特定の領域を記録する rectangleモード(`--rectangle`モードを指定)
 
#### Windowモード

操作は以下のようになり,

![window-mode1](https://github.com/syohex/byzanz-window/raw/master/image/window-capture1.gif)

出力される Gifは以下のようになります.

![window-mode2](https://github.com/syohex/byzanz-window/raw/master/image/window-capture2.gif)

## Rectangleモード

操作は以下のようになり,

![rectangle-mode1](https://github.com/syohex/byzanz-window/raw/master/image/rectangle-capture1.gif)

出力される gifは以下のようになります.

![rectangle-mode2](https://github.com/syohex/byzanz-window/raw/master/image/rectangle-capture2.gif)


## おわりに

Linuxデスクトップ環境で作業を Gifで記録するための byzanzとそのユーティリティである拙作の byzanz-windowを紹介しました. 他にいいツールをご存知の方がいればぜひ教えていただければと思います.
aws-cliを使って、ELBとCloudFrontにSSL証明書アップロード

毎回調べてしまうんで、忘れないように書いておきます。

## ELB
```
aws iam upload-server-certificate --server-certificate-name demo-ssl-elb --certificate-body file://<パブリック証明書> --private-key file://<プライベート証明書> --certificate-chain file://<中間証明書>
```

## CloudFront
```
aws iam upload-server-certificate --server-certificate-name demo-ssl-cloudfront　--path /cloudfront/ --certificate-body file://<パブリック証明書> --private-key file://<プライベート証明書> --certificate-chain file://<中間証明書>
```

## 参考リンク
- [AWSのELBにSSL証明書をインストールする方法](http://qiita.com/yutaro1985/items/7dd5818cc22d10894922)
- [CloudFrontで独自ドメインSSL設定](http://qiita.com/n0bisuke/items/a2a7d5efdc1311dc479a)
Python勉強1日目前半 Bottleで簡単なWebアプリ

#ケーススタディ
Webアプリの練習にPythonを勉強したい
Python3.4
Bottle
IntelliJ
今回はローカル実行

#簡単なコード
##HelloWorld
Pythonのインストール等は簡単なので調べて下さい
基本的に　brewやyumで簡単に入ります

virtualenvを使うとPython環境を汚さず便利というので
IntelliJでvirtualenvを使う方法は下記を参考に
http://qiita.com/todogzm/items/973f35e4f7f269062b8e

```py3:HelloWorld
import bottle
from bottle import route, run

@route('/hello')
def hello():
    return "Hello World!"

run(host='localhost', port=1046, debug=True, reloader=True)
```

http://localhost:1046/hello
にアクセスすると HelloWorld! が表示されます

とてもシンプルですが見たまんま　
`@route`でURLルーティングを指定し、実行してます
もちろん、動的ルーティングも出来るし
`@get` `@post` `@put` `@delete`にすれば、各メソッドに対応できます

非常に簡単


##テンプレートエンジン
Bottleではjinja2 が人気らしいので使ってみます

importでjinja2を指定し、テンプレートのパスも指定します
今回は動的ルーティングのテストとして /hello/&lt;name&gt; と nameを取りテンプレートに渡してみます
templateフォルダを作り以下に base.j2とhello.j2 のテンプレートを作ります

```py3:test.py
import bottle
import jinja2
from bottle import route, run
from bottle import TEMPLATE_PATH, jinja2_template as template

TEMPLATE_PATH.append("./template")

@route('/hello/<name>')
def hello(name):
    return template('hello.j2', name=name)

run(host='localhost', port=1046, debug=True, reloader=True)
```

```html:template/base.j2
<html>
    <head>
        <title> test </title>
    </head>
    <body>
        {% block content %} {% endblock %}
    </body>
</html>
```

```jinja:template/hello.j2
{% extends "base.j2" %}

{% block content %}
    Hello {{ name }}!
{% endblock %}
```

```bash
$ python test.py
```

で実行し、 localhost:1046/hello/hoge
でアクセスすると
Hello hoge!
と表示されるはず

フィーリングで読めると思いますが
test.pyから　template関数で hello.j2を呼ぶ
引数に ダイナミックルーティング　nameを渡す
hello.j2は base.j2を継承しており　contentという変数にて　bodyタグ内に埋め込まれる

よくある　テンプレートエンジンの動作ですね！


実行すると

```
/xxx/pyenv/python3.4/lib/python3.4/site-packages/bottle.py:3325: DeprecationWarning: Absolute template path names are deprecated.
  fname = self.search(name, self.lookup)
```

などと表示されます

```py3:

        if os.path.isabs(name) and os.path.isfile(name):
            depr('Absolute template path names are deprecated.') #0.12
            return os.path.abspath(name)
```

どうやらここでメッセージ出ているみたいですが、よくわかりません。
おそらくbottle0.12から 仕様が変わったんでしょう
現状動いているので　とりあえず放置・・・



#モジュール作成
pythonには　モジュールと、モジュールをまとめたパッケージとがあるらしい
とりあえず簡単なほう、モジュール化をしてみます

メインの方は簡単に

```py3:main.py
import Sub

# 変数を使う
print(Sub.text)

# 関数を呼ぶ
Sub.printHoge()

# Classを使う
sub = Sub.Sub()
sub.printFoo()

```

```py3:Sub.py

# 変数
text="TEXT"

# 関数
def printHoge():
  print("Hoge")

# class
class Sub:
  def __init__():
    pass
  def printFoo():
    print("Foo")

```

とりあえず、これぐらい知識があれば、ちょっとしたものなら作れそうですね

つぎはTwitterでも叩いてみようと思います
内容が大きく変わるので
１日目前半おわり




##おまけ　if __name__ == "__main__":

よくpythonコードで

```py3
if __name__ == "__main__":
```

を見かけるが、ひとことで言うと、コマンドから実行された場合のみこの文がTrueになる
逆に言えば、モジュールとしてimportした場合にはFalseになっているので
モジュールとして使われた場合には実行したくないコードを書く事になる
apacheバーチャルホスト設定メモ（複数ユーザー対応）

複数のサイトをホストするwebサーバを構築する際のメモ
ユーザーの作成・ホームディレクトリの設定・バーチャルホストの設定などごちゃごちゃしがちなのでまとめておく。

※　注意事項
SELINUXが動作している場合は、ホームディレクトリを読み込めないので一旦OFFにしておく
SELINUX有効にしつつ動作させる方法は後述

```
setenforce 0  #　←　一時的に無効
```

##目標
1.　複数のユーザー（デザイナ等）がそれぞれのサイトを個別に編集できる
2.　バーチャルホストで複数サイトが運営できる


##ユーザーの作成

1.ここではuser1という名前のユーザーを作成

```
sudo useradd user1
sudo passwd user1
```

2.ホームディレクトリの設定

作成したユーザーで作業

```
su - user1 　←　user1にチェンジ
```

public_htmlディレクトリを作成して、自分以外が編集できないよう(chmod)
apacheが読み込みるようホームディレクトリとコンテンツディレクトリに実行許可

```
mkdir /home/user1/public_html
chmod 701 /home/user1/public_html
chmod +x /home/user1
```

3.ユーザーディレクトリにテスト用のindex.htmlファイルを作成

```
cd public_html
vi /home/user1/public_html/index.html
```

作業完了

```
exit
```


##apacheの設定

ホームディレクトリを使用できるようuser.confファイルを編集

```
vi /etc/httpd/conf.d/user.conf

```

```
#
# UserDir: The name of the directory that is appended onto a user's home
# directory if a ~user request is received.
#
# The path to the end user account 'public_html' directory must be
# accessible to the webserver userid.  This usually means that ~userid
# must have permissions of 711, ~userid/public_html must have permissions
# of 755, and documents contained therein must be world-readable.
# Otherwise, the client will only receive a "403 Forbidden" message.
#
<IfModule mod_userdir.c>
    #
    # UserDir is disabled by default since it can confirm the presence
    # of a username on the system (depending on home directory
    # permissions).
    #
    #UserDir disabled       #　←　コメントアウト
     UserDir enabled user1  #　←　追記　
    #
    # To enable requests to /~user/ to serve the user's public_html
    # directory, remove the "UserDir disabled" line above, and uncomment
    # the following line instead:
    #
    UserDir public_html    #　←　コメントを外す
</IfModule>

#
# Control access to UserDir directories.  The following is an example
# for a site where these directories are restricted to read-only.
#
<Directory "/home/*/public_html">
    AllowOverride All      # ←　個別設定の許可
    Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
    Require method GET POST OPTIONS
</Directory>
```

##動作確認

http://（サーバ名）/~user1 にアクセスして確認


##バーチャルホストを設定

1.バーチャルホスト設定ファイルvhost.confを作成

```
sudo vi /etc/httpd/conf.d/vhost.conf
```

```
NameVirtualHost *:80
<VirtualHost *:80>
        DocumentRoot    /var/www/html/
        ServerAdmin     root@localhost
        ServerName      www.servername.com
        ErrorLog        /var/log/httpd/servername-error_log
        CustomLog       /var/log/httpd/servername-access_log common
</VirtualHost>
<VirtualHost *:80>
        DocumentRoot    /home/user1/public_html
        ServerAdmin     user1@servername.com
        ServerName      vhost1.servername.com
        ErrorLog        /var/log/httpd/vhost1-error_log
        CustomLog       /var/log/httpd/vhost1-access_log common
</VirtualHost>
```

2. apacheを再起動

```
systemstl restart httpd.service
```

3. 動作確認

作業PCのHOSTSファイルを書き換えて、確認！


##SELINUXの再有効化
作成したユーザーディレクトリに対してrootユーザーで下記のコマンドを実行

```
restorecon -R /home/user1/public_html
setenforce 1
```
EL CAPITANのrootless(SIP)の話

今作っているアプリがライブラリなども使っていなくて、特に意識しなかったんだけど
最近OSを EL CAPITAN にアップデートしました
ついでに、ライブラリ使おうと思って、cocoaPodsを入れてみた。
その時にrootlessではまったのでメモ

## CocoaPodsとは？

iosアプリのライブラリ管理ツールです。
npmやjspmやらそんな位置づけですね。

## rootlessとは？
[管理者権限を持つユーザー(rootなど)であっても、Appleが定める特定の重要なファイルにはアクセス出来ない]
EL CAPITAN で導入されたセキュリティ強化によるものだそうです。

対象ディレクトリは以下のコマンドで確認できます。
`$cat /System/Library/Sandbox/rootless.conf`

上記対象ディレクトリに書き込みを行おうとすると
”Operation not permitted"
メッセージが出てきて実行できませんでした。

## cocoaPodsのインストール
通常の手順通り、以下のコマンドを実行しました。

`sudo gem update --system`
`sudo gem install cocoapods`

`sudo gem update --system`
を実行した段階で早速 
”Operation not permitted"のメッセージが出てました

##  rootlessの無効化
権限変更などの手法もあるかもしれませんが、
あまり設定を変えると思わぬとこに影響しそうなので
以下の手順を試しました。

1. rootless無効化
2. cocoaPodsインストール
3. rootless有効化

**無効化する手法を調べたところ2パターンあるそうです。**

1. コマンドで対応
2. リカバリーモードでrootlessを無効設定にする 

## コマンドで対応
簡単そうだったので、まずこちらを試してみました。
`$sudo nvram boot-args=“rootless=0”`
上記コマンドの後、PC再起動

そのあと状態を　`$csrutil status` で確認したところ
System Integrity Protection status: enabled (Custom Configuration).
のままだったので、この方法だと自分の環境ではうまくいきませんでした。

## リカバリーモードでrootlessを無効設定にする
ちょっと手順はめんどくさいですが以下の手順を試します。
1. `command + R` を押しながらマシンを再起動
2. OS X ユーティリティ画面が表示される

    * TimeMachine　バックアップから復元
    * OS X を再インストール
    * ヘルプ情報をオンラインで取得
    * ディスク・・・

とか出てきて、ちょっと緊張しますが、落ち着いて次の作業を


1. ツールバーから[ユーティリティ] - [ターミナル]でターミナルを起動
2. `$csrutil disable`
Succesfully ・・・が表示される
3. ターミナルを閉じ、通常モードで再起動

PCが上がってきたら、ターミナルで以下を確認する
`$csrutil status
System Integrity Protection status: disabled (Custom Configuration).
`
これでrootlessが無効になっているハズ

再度cocoapodsのインストールを開始
`$sudo gem update --system`
'`sudo gem install cocoapods`
正常にインストールできました。

## リカバリーモードでrootlessを有効設定にする

必要な設定を、終えたのでrootlessの設定を有効化します
無効化設定と同じ手順で `$csrutil disable` を `$csrutil enable` にするだけ

再起動したら,ターミナルから
`$csrutil status
System Integrity Protection status: enabled (Custom Configuration).`
になっている事を確認しておきましょう。

# まとめ

今回の対応はEl Capitanから発生するものなので、
もしOS アップデートをまだしていなければ、アップデート前にインストールしておく方が
楽だと思います。()brewとかも多分エラーになると思うので)

思わぬところで時間使ってしまったので、ガンプラ制作が少し遅れそうです(ToT)
fabric を使って環境構築


#fabricを使って環境構築

新しい環境を作りたいが、chefの使い方を忘れてしまい思い出すのが大変そうだった。
その時に、[Chefに挫折したあなたへ。Fabricのすすめ - Takahiro Hozumi](http://hozumi.github.io/2013/03/chef-fabric-ja.html)の記事を見て面白そうだったので試してみた

参考

* [Chefに挫折したあなたへ。Fabricのすすめ - Takahiro Hozumi](http://hozumi.github.io/2013/03/chef-fabric-ja.html)
* [今日からすぐに使えるデプロイ・システム管理ツール Fabric 入門] (http://shiumachi.hatenablog.com/entry/20130414/1365920515)
* [Welcome to Fabric’s documentation! &mdash; Fabric  ドキュメント](http://fabric-ja.readthedocs.org/ja/latest/index.html)

##環境
* OSX Yosemite 10.10.5
* Python 2.7.10

### fabric インストール

```zsh
%sudo easy_install fabric
```

###sample コード

fabfile.pyを作成

```zsh

%vi fabfile.py
```

```fabfile.py
def hello():
    print("Hello world!")
```

実行と結果

```zsh
% fab hello 
Hello world!
Done.
```

成功

##作成したいmiddleware

* Ruby
* Git

##できあがった fabfile.py

```fabfile.py
from fabric.api import *

env.user = 'vagrant'
env.hosts = ['*.*.*.*']

def ruby():
    sudo('yum install -y ruby')

def git():
    sudo('yum install -y git')

def deploy():
    ruby()
    git()
```

実行

```zsh
%fab deploy
```

検証

```bash
[vagrant@vagrant-centos65 ~]$ which ruby
/usr/bin/ruby
[vagrant@vagrant-centos65 ~]$ which git
/usr/bin/git
```

インストールされた OK


##まとめ
手軽に使えて、そんなに細かい事を考えずに環境ができた。
シンプルに使えるからわかりやすいと思う
もっと色々と活用方法があるそうなので、引続きやっていきたいと思う
Twitterの高度な検索コマンド

今回は、Twitterの検索をもっと高度にする方法を教えます。
今回は、専用のコードを使います。なので、コードが苦手な方はhttps://Twitter.comのTwitter searchで検索し、オプションから高度な検索から、出来ます。多分https://twitter.com/search-advanced だと思います。
只今、記事を書いてます。お待ち下さい
→続き
長く書くのが苦手なんですぐに結果を書きますがその結果は演算子を使ってできるそうです。
8.3形式の短いファイル名を表示させるwindowsコマンド【dir /x】

8.3形式ってなんだ？という疑問から。
windowsは昔、ファイル名に拡張子以外に8バイト、拡張子に3バイトまでしか使えなかった。
それを8.3形式と言う。
windows95以降は長い形式のファイル名も使えるようになった。が、今でも8.3形式のファイル名は自動でつけられている。
つまり普段自分でつけているファイル名以外にもう一つ別の名前がファイルには存在する。

なぜこれをqiitaにメモろうかと思ったかというと、以前、他人から受け取ったcssファイルが消せなくなったことがあった。
原因は「~.css 」と拡張子の後ろにスペースが1つ入ってしまっていたことが原因ぽかった。
ゴミ箱に入れようとすると入らない。
deleteで消そうとしても消えてくれない。
途方にくれているときに出会ったのがこのコマンド。

【dir /x】

対象のファイルがあるディレクトリで↑のコマンドを打ち込むと8.3形式のファイル名が表示される。
あとは8.3形式のファイル名に対して削除コマンドを打てば問題解決。
他愛もないことだったけど、このコマンド操作を知るまではゴミファイルが残ってしまって邪魔だったので助かりました。

参考サイト
[ファイルの内容をバイナリ・ダンプで確認する](http://www.atmarkit.co.jp/fwin2k/win2ktips/775hexdump/hexdump.html)
[8.3形式の短いファイル名を表示させる](http://www.atmarkit.co.jp/fwin2k/win2ktips/606dirx/dirx.html)
javaで当日の日付の下一桁を取得

日付の下一桁をStringで取得するなら一行で行けた。intにするなら、これにInter#parseIntを使うか。

* JodaTime

`DateTime.now().toString("d");`

* java8 

`LocalDate.now().format(DateTimeFormatter.ofPattern("d"))`


最初は`toString("dd").subString(1)` としたけど、d一個なら下一桁を返してくれる模様

`DateTime.now().toString("d d");` とすると、下一桁目_下一桁目と表示される。
rabbitmq_managementを使うとRabbitMQの起動ができない

# 環境
* CentOS 7.1
* Erlang R16B03
* RabbitMQ 3.2.1

# 問題
RabbitMQを`systemctl`で起動しようとすると失敗する。

`systemctl`でのメッセージはこんな感じ。

```bash
$ sudo systemctl status rabbitmq-server
rabbitmq-server.service - LSB: Enable AMQP service provided by RabbitMQ broker
   Loaded: loaded (/etc/rc.d/init.d/rabbitmq-server)
   Active: failed (Result: exit-code) since 火 2015-12-01 22:40:20 EST; 20min ago
  Process: 965 ExecStart=/etc/rc.d/init.d/rabbitmq-server start (code=exited, status=1/FAILURE)

12月 01 22:40:10 localhost systemd[1]: Starting LSB: Enable AMQP service provided by RabbitMQ broker...
12月 01 22:40:10 localhost su[1049]: (to rabbitmq) root on none
12月 01 22:40:12 localhost su[1616]: (to rabbitmq) root on none
12月 01 22:40:12 localhost su[1638]: (to rabbitmq) root on none
12月 01 22:40:20 localhost rabbitmq-server[965]: Starting rabbitmq-server: FAILED - check /var/log/rabbitmq/startup_{log, _err}
12月 01 22:40:20 localhost rabbitmq-server[965]: rabbitmq-server.
12月 01 22:40:20 localhost systemd[1]: rabbitmq-server.service: control process exited, code=exited status=1
12月 01 22:40:20 localhost systemd[1]: Failed to start LSB: Enable AMQP service provided by RabbitMQ broker.
12月 01 22:40:20 localhost systemd[1]: Unit rabbitmq-server.service entered failed state.
```

`/var/log/rabbitmq/startup_log`のログはこんな感じ。

```bash
 cat /var/log/rabbitmq/startup_log

              RabbitMQ 3.2.1. Copyright (C) 2007-2013 GoPivotal, Inc.
  ##  ##      Licensed under the MPL.  See http://www.rabbitmq.com/
  ##  ##
  ##########  Logs: /var/log/rabbitmq/rabbit@localhost.log
  ######  ##        /var/log/rabbitmq/rabbit@localhost-sasl.log
  ##########
              Starting broker...

BOOT FAILED
===========

Error description:
   {could_not_start,rabbitmq_management,
                    {could_not_start_listener,[{port,15672}],eacces}}

Log files (may contain more information):
   /var/log/rabbitmq/rabbit@localhost.log
   /var/log/rabbitmq/rabbit@localhost-sasl.log

{"init terminating in do_boot",{rabbit,failure_during_boot,{could_not_start,rabbitmq_management,{could_not_start_listener,[{port,15672}],eacces}}}}
```

# 原因
selinuxでした。

# 解決策
selinuxを無効化してやればいいです。

```bash
$ sudo setenforce 0
$ sudo sed -i "/SELINUX/s/enforcing/disabled/g" /etc/selinux/config
```
AppVeyor 設定項目 - Environment編

# AppVeyor
.NET開発者向けのCI&デプロイツール
[Continuous Integration and Deployment service for Windows developers - Appveyor](http://www.appveyor.com/)

[AppVeyor 設定項目 - General編 - Qiita](http://qiita.com/shoooo/items/3137a93c355f3ca07656)

## SETTINGS
GUIでの設定項目について概要をまとめます。
リポジトリの種類により設定項目が一部異なります。
今回は、GitHubのプロジェクトの場合について記載します。

### Environment
環境設定

#### Operating system
ビルド環境のVMテンプレート

- Default Azure
- MinGW
- Visual Studio 2013～
- Windows Server 2012 R2
- WMF 5

などの中から複数選べる

```ps1
$x64items = @(Get-ChildItem "HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall")
$x64items + @(Get-ChildItem "HKLM:SOFTWARE\wow6432node\Microsoft\Windows\CurrentVersion\Uninstall") `
   | ForEach-object { Get-ItemProperty Microsoft.PowerShell.Core\Registry::$_ } `
   | Sort-Object -Property DisplayName `
   | Select-Object -Property DisplayName,DisplayVersion
```
これを`Before build script`に設定すると、インストールされているものが確認できる
`Windows Server 2012 R2`と`Visual Studio 2015`では特に違いがわからなかった
`Default Azure`とではIISのバージョンやVisual Studio 2015インストールの有無に違いがあった
参考：[Build Worker Installed Software - Appveyor](http://www.appveyor.com/docs/installed-software)


#### Clone directory
リポジトリをクローンするディレクトリ
ビルドのルートパスになる
デフォルト：`c:\projects\{プロジェクト名}`

#### Environment variables
環境変数を設定
グローバルな環境変数とグループ分け(build matrix)した環境変数がある
グループ分けした場合、それぞれビルドが実行される
以下のようにDB毎に分けたりできる

```yaml
matrix:
 - db: mysql
   provider: mysql

 - db: mssql
   provider: mssql
   password:
     secure: $#(JFDA)jQ@#$
```

既定の環境変数については以下を参照
[Environment variables - Appveyor](http://www.appveyor.com/docs/environment-variables)
#### Services
サービスの追加

- SQL Server
- MySQL
- PostgreSQL
- MongoDB
- IIS
- Microsoft Message Queuing Services

から選択

#### Hosts
drivers\etc\hostsに記載する内容

#### Cached directories and files
キャッシュするディレクトリ、ファイルの指定
AppVeyorはビルドのたびにVMを作っているので毎回ライブラリのダウンロードなどが必要
NuGetの`packages`や`node_modules`、`gem`などなどを指定し、毎回ダウンロードしないようにできる

#### Init script
一番初めに実行するスクリプトを記述
PowerShellかCmdが選べる

#### Install script
クローン完了時に実行するスクリプトを記述
PowerShellかCmdが選べる
MithrilのチュートリアルをTypeScriptで写経してみる

## 概要
ぼんやりとしか把握していないTypeScriptが色々とバージョンアップしたらしいので[Mithrilのチュートリアル](http://mithril-ja.js.org/getting-started.html)をTypeScriptで写経して学びます。タイトルそのまんまです。

[追記]
*[こちら](http://qiita.com/heyhachi/items/9925acf4aa61544da7cb)でコンパイルエラーを修正してみました。*

## 環境
 * TypeScript 1.6.2
 * Mithril 0.2.0
 
```
root
├ server.js
├ client
│  ├ app.js    <-app.tsをコンパイルしたファイル
│  ├ mithril.min.js
│  └ index.html
├ client-src
│  └ app.ts
└ typings
　 └mithril
 　　└mithril.d.ts
```

## まずは下準備
チュートリアルを参考にindex.htmlを用意。

```html:index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>ToDoアプリケーション</title>
  <script src="mithril.min.js"></script>
  <script src="app.js"></script>
</head>
<body>
  <div id="root"></div>
</body>
</html>
```

後は適当なWebサーバーを起動しておきます。とりあえずnodeで用意しました。

```javascript:server.js
var express = require("express");

var app = express();
app.use(express.static("client"));
console.log("start listening at 3773");
app.listen(3773);

```

## 写経したものがこちら
以下の通りに書いてみました。可能な限り型を明示したつもりです。しかし、最後のm.mountするところでTS2345エラーが発生しているので調査中。エラー出てるくせにapp.jsが生成されて、アプリケーション自体は実行できているのが謎ですが…。

```javascript:app.ts
/// <reference path="../typings/mithril/mithril.d.ts" />
import MithrilProperty = _mithril.MithrilProperty;

/**
 * Model
 */
class Todo {
  description: MithrilProperty<string>;
  done: MithrilProperty<boolean>;

  constructor(description:string) {
    this.description = m.prop<string>(description);
    this.done = m.prop<boolean>(false);
  }
}
//ビュー・モデルは表示されているTodoのリストを管理し、
//作成が完了する前のTodoの説明を格納したり、
//作成が可能かどうかを判定するロジックや、
//Todoが追加された後にテキスト入力をクリアする責務を持つ
namespace todoVM {
  //新しいTodoを作成する前の、入力中のTodoの名前を保持するスロット
  export var description: MithrilProperty<string>;
  //アクティブなTodoのリスト
  export var todoList: MithrilProperty<Todo[]>;
  //export var done: MithrilProperty<boolean>;
  /**
   * 初期化
   */
  export function init () {
    todoVM.todoList = m.prop<Todo[]>([]);
    todoVM.description = m.prop<string>("");
    //todoVM.done = m.prop<boolean>(false);
  }

  /**
   * Todoの追加をしてdescriptionをクリア
   */
  export function add () {
    if (description()) {
      todoVM.todoList().push(new Todo(description()));
      todoVM.description("");
    }
  }
}
/**
 * Controller
 * コントローラは、モデルの中のどの部分が、現在のページと関連するのかを定義している
 * この場合は１つのビュー・モデルですべてを取り仕切っている
 */
function controller() {
  todoVM.init();
}
/**
 * View
 * @returns {any}
 */
var view = () => {
  return m("html", [
    m("body", [
      m("input", {onchange: m.withAttr("value", todoVM.description), value: todoVM.description()}),
      m("button", {onclick: todoVM.add}, "追加"),
      m("table", [
        todoVM.todoList().map((task: Todo, index: number) => {
          return m("tr", [
            m("td", [
              m("input[type=checkbox]", {onclick: m.withAttr("checked", task.done), checked: task.done()})
            ]),
            m("td", {style: {textDecoration: task.done() ? "line-through" : "none"}}, task.description()),
          ])
        })
      ])
    ])
  ]);
};

window.onload = () => {
  m.mount(document.getElementById("root"), {controller: controller, view: view});
};
```

まだまだ理解の甘いところだらけ。変換後のapp.js、TypeScript、Mithrilのドキュメントと照らしあわせて勉強中。
google Feed API はどうやらサポートが終わったらしい。

# google Feed APIとは
簡単に言うと、RSS Feed を読み込んで、解析を行うAPIのことある。


# APIサービスが終了した？
こちらのAPIを使用したプログラムを利用していたのだが、
先日以下のエラーが表示され機能しなくなった。

"this api is no longer available."

どうやらこちらのapiのサポートが終了したらしい。
公式サイトでは2015年4月20日までのサポートとのこと。


#まとめ
google Feed APIに変わる別の方法を模索していく必要がある。
解決策が分かりましたらまた更新いたします。

#（更新）代替案
もうすでに知られている方法ではあるが、phpの以下の関数を用いて実現可能である。

simplexml_load_file($path)

以下に具体的な使い方がのっていたので記載いたします。
記事を書いてくれた方、ありがとうございました。

https://www.softel.co.jp/blogs/tech/archives/4105
AndroidStudio2.0 Preview + kotlinでmixiのAndroidTrainingをやった話 2 改め 何かアプリを作ってみる(仮)


前回のエントリーは[こちら](http://qiita.com/T-N0121/items/a7a42dd1e4d9c873fc33)から

基本的にkotlinで書いてみたい！がモチベーションなのでxmlでレイアウトファイルや
リソースファイル作るみたいな部分はすっ飛ばします。
というより私がここでグダグダと説明するよりmixiのページを見たほうが間違いなくわかりやすいです。

なので今回は2.基礎編の2.ActivityとFragmentについてやっていきます。

##1.ライフサイクル周り

まずはライフサイクル周りから

プロジェクトは[前回のエントリー](http://qiita.com/T-N0121/items/a7a42dd1e4d9c873fc33)で作成したものを使用します。

######・Activity
まずは前回のままの状態でMainActivity.ktを開くと

```MainActivity.kt

	override fun onCreate(savedInstanceState: Bundle?)
	
```
がオーバーライドされています。
他のライフサイクルメソッドは以下になります

```ActivityLifeCycle

	onRestart()
	
	onStart()
	
	onResume()
	
	onPause()
	
	onStop()
	
	onDestroy()

```

######・Fragment
一方Fragmentでは

```MainActivityFragment.kt
	override fun onCreateView(inflater: LayoutInflater?,
								container: ViewGroup?,
					　savedInstanceState: Bundle?): View?
```

がオーバーライドされています。
FragmentのライフサイクルメソッドはほぼActivityと同じですが以下になります

```FragmentLifeCycle
	
	onAttach()
	
	onCreate()
	
	onActivityCreted()
	
	onRestart()
	
	onStart()
	
	onResume()
	
	onPause()
	
	onStop()
	
	onDestroyView()
	
	onDestroy()
	
	onDetach()

```

各ライフサイクルメソッドの役割はmixiのページやAndroid Developerの[サイト](https://developer.android.com/intl/ja/guide/components/activities.html)に詳しく書かれていますのでそちらをご覧下さい。


。。。つまんないですねコレ

一応Javaとの記述方法の比較をすると

Javaでは

	@Override
    protected void onCreate( Bundle savedInstanceState ) {
        super.onCreate( savedInstanceState );
    }
    
	とOverrideアノテーションを記述して
	@Override
	アクセス修飾子 戻り値の型　メソッド名( 引数の型　引数名 ) {
	 	// 処理を記述
	}
となっています。

一方kotlinでは

	override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

	override fun メソッド名( 引数名: 引数の型): 戻り値の型 {
		// 処理を記述
	}
	
となっています。

違いを文章で説明すると
1.オーバーライドアノテーション部分を宣言の初めに記述するようになっている
2.アクセス修飾子がない
3.funと記述している
4.引数の宣言がJavaでは( 引数の型　引数名 )になっているのに対し、kotlinでは( 引数名: 引数の型)になっている
5.戻り値の型の記述方法が違う

といったところでしょうか。

1については見たまんまなのでわかりやすいですね、2のアクセス修飾子については
kotlinではオーバーライドしているメソッドは省略してもスーパークラスのアクセス修飾子がそのまま適用されるみたいです、書きたかったら書いても問題ないです。
3についてはkotlinでメソッドを定義するときには必要なおまじないです。
4は書き方が逆になっているのとkotlinでは引数名の後にセミコロンが記述してあります
5についても記述する位置とセミコロンを記述するという違いにですね。

あともう一つ、記述方法とは関係ないですが、kotlinの引数の型の後ろに「?」が付いていますね。
これはNullable型といいます。
kotlinは型安全な言語なので値がnullになる事が嫌いです極力排除しようとしています、ですがそれでは成り立たないこともあります。
?をつけることでnullを許容することができるようになり上記の例では引数の中身がnullの場合もあるということを明示しています。
iOSの開発言語のSwiftにもOptionalという名前で同じようになっています。

なので上記の場合には引数を使用する前にチェック処理が必要になります。

	if (savedInstanceState != null) {
		// 引数を使用して処理をする
	}

または
	
	if (savedInstanceState == null) {
		// 中身がnullなので処理を終了
		return
	}

みたいな感じですかね。

##2.課題をやってみる？

とりあえずトレーニングページをさらっと一読したので、いざkotlin!と課題をやってみようかと思いましたが、どうやらmixiのプロジェクトを使わないといけないっぽく、ちょっとめんどくさくなりました。

##3.mixiトレーニングやめるってよ
申し訳ありません、やめます！
が、
kotlinの勉強をしたいので引き続き記事は書いて行きたいと思います。
何をするかはまだ決まっていませんが、せっかくなので何かアプリを作りたいです。
次回からはタイトルを変更してお送りしたいと思います、しょうもないエントリーでごめんなさい

では！
WatchConnectivity Interactive Messagingの調査

アプリ道場 Advent Calender 2015の二番煎じではなくて二番手の@sohichiroです。

せっかく記事を書くということで前から気になっていたwatchOS2においての通信部分の速度について調べてみました。

# iPhone - Apple Watchとの通信に使うWatch Connectivityについて
iPhoneとApple Watchがデータを送信しあうには、以下のAPIを用います。

```swift:WCSession.h
public func sendMessage(message: [String : AnyObject], replyHandler: (([String : AnyObject]) -> Void)?, errorHandler: ((NSError) -> Void)?)
public func sendMessageData(data: NSData, replyHandler: ((NSData) -> Void)?, errorHandler: ((NSError) -> Void)?)
```

これらは、APIをコールすると、その場でデータを送信し、通信の成否によってクロージャを実行します
即座にデータを送信することを、「Interactive Messaging」とAppleは表現しています。

上記に対して、送信するタイミングが、システムの状態(OSの都合)に依存するのが以下の3つのAPIになります。

```swift:WCSession.h
public func updateApplicationContext(applicationContext: [String : AnyObject]) throws
public func transferUserInfo(userInfo: [String : AnyObject]) -> WCSessionUserInfoTransfer
public func transferFile(file: NSURL, metadata: [String : AnyObject]?) -> WCSessionFileTransfer
```

これらは、APIをコールすると、データをキューイングし、OSの都合の良いタイミングで、データを送信していきます。
Interactive Messagingで使用するAPIよりも比較的大きなデータを送受信するときに使用します。

ここでは、Interactive Messagingでデータを送信する際の制約について調査してみました。
なお今回の検証は、iPhoneからApple Watchへのデータ送信のみとなっています。

# 送信できるデータサイズは？
これは、実際どれくらいまで大きなデータが送信できるのかを、実際に送って確認してみました。
まずは、sendMessage()において確認。

送信するデータは、Stringに何文字入るか？というところで確認してみたところ。。

65525文字！

65525といえば、、2バイトデータよりちょっとだけ少ない。。


続いて、sendMessageData()。
こちらはStringをNSDataにエンコーディングして何文字のデータが送れるか？というところで確認してみたところ。。

65536文字!!

この数字は、文字数(1から始めてる)ですので、sendMessageData()に送信可能なデータ量は、2バイトで表されるデータ量ということのようです。
sendMessage()の方は、DictionaryのKeyの領域が割り当てられているでしょうか。。


# 送信にかかる時間は？
iPhone6Plus + Apple Watch 38mmの環境において確認しました。

送信時間は、データの大きさに依存します。
sendMessage()、sendMessageData()いずれの場合も、最も大きなデータ量(65525or65536文字)を送信した際は、約1.1sかかっています。まれに1.2sとかもあるので、1.5sぐらいがセーフティなところでしょうか。。
それに対し、データ量を最小にした場合は、約0.3sかかっています。

# 終わりに

確認に使用したコードを以下にアップしておきます。
ご参考になれば幸いです。
(コード汚いorz..)
https://github.com/sohichiro/watchConnectivityTime
python > ファイルownerを変更する > os.chown("path/to/file", uid, gid)

作成したファイルをroot以外のownerに変更したい。

http://stackoverflow.com/questions/25791311/creating-a-file-with-python-using-sudo-makes-its-owner-root

```chOwn1.py
import os
os.chown("path/to/file", uid, gid)
```

```chOwn2.py
import os

uid = int(os.environ.get('SUDO_UID'))
gid = int(os.environ.get('SUDO_GID'))

os.chown("path/to/file", uid, gid)
```

SUDO_UIDやSUDO_GIDの部分をどうユーザpiに対応するかは未確認。


https://www.raspberrypi.org/forums/viewtopic.php?f=44&t=73924
/etc/passwdを確認すればいいのかも。
Hyに入門してみた

この記事は、Lispっぽいけど一応[Python その2 Advent Calendar 2015](http://qiita.com/advent-calendar/2015/yet_another_python)の2日目の記事です。

## Hyとは？
[Hy](http://docs.hylang.org/en/latest/)とはPythonで実装されたLispインタプリタです。

- http://hylang.org/
- https://github.com/hylang/hy

プログラミングのすべての道はLispに至るので、その途中のステップとしてHyに入門してみます。

## インストール
`pip`で簡単にインストールできます。

```shell-session
pip install hy
```

起動してみました。

```shell-session
% hy
hy 0.11.0 using CPython(default) 2.7.6 on Linux
=> (print "Hello, World")
Hello, World
```

## Pythonモジュールを呼び出す
まず気になるのはPython標準モジュールや、Pythonの定番ライブラリを呼び出すにはどうすればよいかということなので、試してみます。

`datetime.datetime`オブジェクトを取得。

```shell-session
=> (import datetime)
=> (datetime.datetime.now)
datetime.datetime(2015, 12, 2, 3, 25, 37, 20456)
```

`re`で正規表現マッチ。

```
=> (re.findall r"([a-zA-Z]+)" "Spam Egg Ham")
[u'Spam', u'Egg', u'Ham']
=> (.groups (re.match r"([a-zA-Z]+)" "Spam Egg Ham"))
(u'Spam',)
```

`requests`でHTTPリクエストを送る。事前に`pip install requests`する必要があります。

```
=> (import requests)
=> (requests.get "https://ticketcamp.net/")
<Response [200]>
```

Lispの構文に慣れていれば、ごく普通に使えますね。

## 関数を定義する
`defn`を使います。

```
=> (defn plus2 [x] (+ 2 x))
=> (plus2 1)
3L
```

## map, filter
よくLispの入門書で使われている[`inc`](http://docs.hylang.org/en/latest/language/core.html#inc), [`odd?`](http://docs.hylang.org/en/latest/language/core.html#odd), [`even?`](http://docs.hylang.org/en/latest/language/core.html#even)については事前に定義されていました。これらを使って、`map`, `filter`を試してみます。

まずは`map`。

```
=> (map inc [1 2 3])
<itertools.imap object at 0x7fb7b0193f50>
=> (list (map inc [1 2 3]))
[2L, 3L, 4L]
```

次に`filter`。

```
=> (filter odd? [1 2 3])
<itertools.ifilter object at 0x7fb7b13f59d0>
=> (list (filter odd? [1 2 3]))
[1L, 3L]
```

`->>`マクロも使えそうだったので、[ClojureのTransducersの例](http://clojure.org/transducers)にある処理を試してみます。

```
=> (def coll [1 2 3])
=> (->> coll (filter odd?) (map inc) (take 1))
<itertools.islice object at 0x7fb7b0199cb0>
=> (list (->> coll (filter odd?) (map inc) (take 1)))
[2L]
```

## `dict`
Pythonの`dict`に相当するオブジェクト。(Lispでなんて言うんだっけ？)

```
=> (def data {:spam 1 :egg 2 :ham 3})
=> (:spam data)
1L
```

## 最後に
いろいろ試してみて、最近個人的によく触っているClojureとおなじ感覚で触れるなという印象を持ちました。が、すべてのプログラミングはLispに至るとはいえ、これを使って何かを作るというところまで想像が及びません。

次回はHyの使いどころについて考察してみたいと思います。
Bashで自身の関数名と呼び出し元の関数名を取得する

シェルスクリプトでログを出力する際などに、自身の関数名を取りたい時がある。

その場合は `${FUNCNAME[0]}` を使用すれば良い。
また `${FUNCNAME[1]}` では呼び出し元の関数名を知ることも出来る。

```bash:test.sh
#!/bin/bash

echo $0

func_hoge() {
        echo 'func_hoge(): ${FUNCNAME[0]} = '${FUNCNAME[0]}
        echo 'func_hoge(): ${FUNCNAME[1]} = '${FUNCNAME[1]}
}

func_fuga() {
        func_hoge

        echo 'func_fuga(): ${FUNCNAME[0]} = '${FUNCNAME[0]}
        echo 'func_fuga(): ${FUNCNAME[1]} = '${FUNCNAME[1]}
}

func_fuga

echo 'main: ${FUNCNAME[0]} = '${FUNCNAME[0]}
echo 'main: ${FUNCNAME[1]} = '${FUNCNAME[1]}
```

```shell-session:実行結果
$ bash test.sh 
test.sh
func_hoge(): ${FUNCNAME[0]} = func_hoge
func_hoge(): ${FUNCNAME[1]} = func_fuga
func_fuga(): ${FUNCNAME[0]} = func_fuga
func_fuga(): ${FUNCNAME[1]} = main
main: ${FUNCNAME[0]} = 
main: ${FUNCNAME[1]} =
```

func_fugaの呼び出し元は `$0` の結果ではなく、`main` になる様子。
しかしながら関数外で直接 `${FUNCNAME[0]}` を見た場合は `main` ではなく空文字列が返った。

# 参考
[メモOFF: シェルスクリプトで&#12289;現在の関数名と呼び出し元の関数名を参照する](http://memo-off.blogspot.jp/2014/12/blog-post.html)
python > 固定のIPアドレスを設定する > os.system('sudo ifconfig eth0 192.168.1.10') など

固定のIPアドレスをpythonから設定したい。

参考
https://www.raspberrypi.org/forums/viewtopic.php?f=32&t=71293

```setIP.py
import os
os.system('sudo ifconfig eth0 down')
os.system('sudo ifconfig eth0 192.168.1.10')
os.system('sudo ifconfig eth0 up')
```

ネットワーク未接続でDHCPでの割当てが失敗した時にこれで固定IPを割当てできる。
markdownファイルをサクッとpdfに変換してくれるgem


何かの作業マニュアルなんかを思わずmarkdownで作成したものの、
いざ送る段階になって送る相手が非エンジニアだったことを思い出したりするのはよくあることです。

そういうときはpdfなんかに変換してあげるととても親切ですね。

markdownエディタの中にはexport機能つきのものもありますが、コマンドラインでサクッとやりたい。

てなわけで探したらやっぱりありました。

[gimli https://github.com/walle/gimli](https://github.com/walle/gimli)


## インストール

```
gem install gimli
```

終わり。

## 使い方
変換したい.mdファイルの置いてあるディレクトリに移動して

```
gimli
```

以上。

ファイルを指定したいときは

```
gimli -f hoge.md
```

以上。簡単簡単。

ここでは割愛しますが、もちろんcssを指定したりとか、
他のmdファイルを表紙として指定したりだとかいろいろできるようです。

## 関連リンク
[gimli https://github.com/walle/gimli](https://github.com/walle/gimli)