OmniAICreator/Qiita-1.07M huggingface dataset:
hubotで毎分サイトのステータスを監視する

グローバルからwebサイトの状態を監視するのにhubotが使えそうだったので使ってみた
http responseのstatusが200以外だったらslackに通知する様にした
サンプルはモバイルhttpsのサイト用

### scripts/monitor.coffee

```js
# Description:
#   Monitoring
https = require 'https'
cron = require('cron').CronJob

module.exports = (robot) ->
  https_health_check = (host, path) ->
    https.get {host: host, path: path, port: 443, headers: "User-Agent":"iPhone xxx Bot", method: 'GET'}, (res) ->
      msg = "https://#{host}#{path} is #{res.statusCode}"
      console.log msg
      if res.statusCode != 200
        console.log res.headers
        robot.send {room: "notifications"}, msg

  new cron('0 * * * * *', () =>
    https_health_check('サイトドメイン', 'パス(/から記述)')
  ).start()
```

### 改良版 - 2015/06
* httpsでなくrequestモジュールを使ってみた
* cronをやめてagendaを使ってみた
* EventEmitterを使ってみた

#### 監視用関数

```coffeescript
request = require('request')
module.exports = (robot) ->
  robot.on 'healthcheck:url', (url) ->
    options = {
      url: url
      headers: "User-Agent":"iPhone"
    }
    request.get options, (err, res, body) ->
      msg = "#{url} is #{res.statusCode}"
      robot.logger.info msg
      if err
        robot.logger.error err
        robot.send {room: "notifications"}, err
      else if not res.statusCode == 200
        robot.logger.error res.headers
        robot.send {room: "notifications"}, msg
```

#### 呼び出し側

```coffeescript
Agenda = require('agenda')
agenda = new Agenda({db: { address: process.env.MONGOLAB_URI ? 'localhost:27017/agenda'}})

module.exports = (robot) ->
  agenda.define 'agenda:monitoring', (job, done) ->
    # 複数URL監視
    robot.emit 'healthcheck:url', 'https://xxx.yyy/zzz'
    robot.emit 'healthcheck:url', 'https://xxx.yyy/aaa'
    robot.emit 'healthcheck:url', 'https://zzz.xxx.yyy/aaa'
    done()

  agenda.every('1 minutes', 'agenda:monitoring')
  agenda.start()
```

### npm package
[hubot-healthcheck](https://www.npmjs.com/package/hubot-healthcheck) 公開した(2015/08/24)
JavaScriptでタブメニュー作成

jQueryでは作れるけど、
勉強もかねて、あえてJavaScriptでタブメニューを作成。

不細工かな...

```
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="utf-8">
	<title>タブメニュー</title>
	<meta name="viewport" content="width=device-width; initial-scale=1.0">
	<link rel="stylesheet" media="screen" href="css/style.css" />
</head>
<body>
	<div class="tab">
		<div class="tabBox">
			<h4 class="tabMenu">タブ[1]</h4>
			<p>タブ[1]の内容が入ります</p>
		</div>
		<div class="tabBox">
			<h4 class="tabMenu">タブ[2]</h4>
			<p>タブ[2]の内容が入ります</p>
		</div>
		<div class="tabBox">
			<h4 class="tabMenu">タブ[3]</h4>
			<p>タブ[3]の内容が入ります</p>
		</div>
	</div>

<script>
var tab = document.getElementsByClassName('tab')[0];
var tabBox = document.getElementsByClassName('tabBox');
var tabMenu = document.getElementsByClassName('tabMenu');
var text = [];
var currentNum;
var div = document.createElement('div');
div.className = 'menu';

// .tabMenuのテキスト取得
for(var i=0;i<tabMenu.length;i++){
	text[i] = tabMenu.item(i).firstChild;
}


/* .tabの下に<div class="menu"></div>を配置。
 * また、要素を下記のような並び順に変更
 * <div class="tab">
 *    <div class="menu"></div>
 *    <div class="tabBox"></div>
 *    <div class="tabBox"></div>
 */
tab.appendChild(div);
for(var i=0;i<tabBox.length;i++){
	tab.appendChild(tabBox[0]);
}

/*
 * .menuの子要素に<h4 class="tabMenu"></h4>を移動
 * さらにh4の子要素に<a href="javascript: void(0);></a>を追加
 * aタグのテキストとしてtext[i]で取得していたものを配置する
 */
var menu = document.getElementsByClassName('menu')[0];
var anchor = [];
for(var i=0;i<tabMenu.length;i++){
	menu.appendChild(tabMenu[i]);
	anchor[i] = document.createElement('a');
	anchor[i].setAttribute('href', 'javascript:void(0);');
	anchor[i].appendChild(text[i]);
	tabMenu[i].appendChild(anchor[i]);
}

/*
 * タブ[1]を初期表示として、表示しているタブに色を付ける（class名：currentを与える）
 */
var current = 0;
var show;
for(var i=0;i<tabBox.length;i++){
	if(i == current){
		show = tabMenu[current];
		show.className = 'tabMenu current';
	}else{
		for(var j=0;j<tabBox.length;j++){
			if(i == current) continue;
			tabBox[i].style.display = 'none';
		}
	}
}

/*
 * タブをクリックしたら、表示内容が切り替わるようにクリックイベントを作成
 */
for(var i=0;i<tabMenu.length;i++){
	document.querySelectorAll('.menu a')[i].onclick = function(){
	show.className = 'tabMenu';
	show = this.parentNode;
	show.className = 'tabMenu current';
	for(var j=0;j<tabMenu.length;j++){
		if(tabMenu[j].classList[1] == 'current'){
			currentNum = j;
		}
		tabBox[j].style.display = 'none';
	}
	tabBox[currentNum].style.display = 'block';
};
}
</script>

</body>
</html>

```

```
//style.css

.menu {
	overflow: hidden;
}
.tabMenu{
	float: left;
	width: 200px;
	text-align: center;
	border:1px solid #CCC;
	border-radius: 5px 5px 0 0;
	box-sizing:border-box;
	margin-bottom: 0;
}

.tabBox {
	border: 1px solid #CCC;
	width: 600px;
	box-sizing:border-box;
}


a {
	display: block;
	text-decoration: none;
	padding: 5px;
	box-sizing:border-box;
	border-radius: 5px 5px 0 0;
}

.current {
	background: rgba(255, 100, 200, 0.5);
}
.current > a {
	color: #FFF;
}

```
Visual Studio 2010 CLI DLL + MFC exe = ブレイクポイントが無効

プロジェクトプロパティの構成プロパティ／全般のプラットフォームツールセットの値がDLLとEXEで違う場合にブレイクポイントが無効でデバックできない。
プラットフォームツールセットを同じにしたらブレイクポイントが有効になりデバックできた。
MFCアプリのデフォルトがv100でC++DLLのデフォルトがv90になっていた。
ちなみにCLR コンソールアプリケーションのデフォルトがv90になっていた。

かなり焦ったのでメモだけ…
Ansibleでa2enmod（冪等性）


@hnakamur さんにa2enmodが出来るAnsibleモジュールがあるのを教えて頂きました！こちらを使いましょう！

> a2enmod はapache2_module - enables/disables a module of the Apache2 webserver — Ansible DocumentationというAnsibleモジュールが用意されているのでこちらがお勧めですよ。

[apache2_module - enables/disables a module of the Apache2 webserver — Ansible Documentation](http://docs.ansible.com/apache2_module_module.html)

-------------------

ググっても出てこなかったので。こんな感じでやるとchangedの数が増えなくていい。

```yaml
- name: Apache2 モジュール有効化
  action: command a2enmod {{item}}
  tags: apache2
  register: result
  changed_when: "'already enabled' not in result.stdout"
  with_items:
    - expires
    - headers
```

Ansibleで冪等性を担保した形でa2enmodを叩くのが見当たらなかったので、調べた。

* ```changed_when``` てのが実行結果がchangedかどうかを見る
* ```register``` でmoduleの結果を変数で受け取る
負の剰余

JavaScriptの剰余では、第1オペランドが正のときは正を、負のときは負を返します。

たとえば、

```js
(-5) % 2
```

の計算結果は-1になります。
これが自然だと思う人はそれでいいのですが、
僕はこれが気持ち悪いので、常に正を返すようにします。

```js
function mod(i, j) {
    return (i % j) < 0 ? (i % j) + 0 + (j < 0 ? -j : j) : (i % j + 0);
}
```

iが0のときは[マイナスゼロ](http://ja.wikipedia.org/wiki/%E2%88%920)が返ってくることがあり、それも気持ち悪いので
0を加算してマイナスゼロを避けています。

補足: [このページ](http://0xcc.net/blog/archives/000083.html)によると、
Ruby, Python, Perlでは剰余結果が正になり、
C, Java, PHPでは剰余結果が負になるそうです。
WatchKitのGnalce&Notification起動


以下の記事を参考にWatchKitサンプルアプリを作って見ました。

[WatchKit Catalog(サンプルコード)を起動する方法](http://qiita.com/kuniorock/items/66ee28e51d7a322f8f4c)
[Apple Watchのアプリを開発してみた](http://qiita.com/moriyaman/items/81bb876c20ccf6700e3d)

最初にWatchKit Catalogをビルドしてみた後に自前のサンプルアプリを作ったんですが、WatchKit では起動時のschemeが通常、Glance、Notificationで分かれていたのでそのschemeを作る方法をメモ。

***
# WatckKit ExtensionをビルドするSchemeを作る
メニューからProduct>Scheme>Manage Scheme...からScheme編集画面を起動

![スクリーンショット 2014-11-24 18.25.19.png](https://qiita-image-store.s3.amazonaws.com/0/60457/3bda2ce8-2df6-240b-30ad-d51134cdb795.png "スクリーンショット 2014-11-24 18.25.19.png")

左下の「＋」で新しいScheme作成

![スクリーンショット 2014-11-24 18.14.13.png](https://qiita-image-store.s3.amazonaws.com/0/60457/52cd543d-0959-e72a-26dd-99911de1384e.png "スクリーンショット 2014-11-24 18.14.13.png")

デフォルトが通常のiOSアプリを作成する一番上に選択されているので、「{プロジェクト名} WatchKit Extension」を選択して、OKを押してScheme作成。

![スクリーンショット 2014-11-24 18.14.26.png](https://qiita-image-store.s3.amazonaws.com/0/60457/359eaee3-5198-ad3d-edcb-33a068aacb42.png "スクリーンショット 2014-11-24 18.14.26.png")

# Glanceで起動するScheme設定
Scheme編集画面に戻るので、さきほど作成したSchemeを選択して左下のEditをクリック。

個別のScheme設定画面になるので、RunのExecutableで「Glance」を選択。

![スクリーンショット 2014-11-24 18.37.55.png](https://qiita-image-store.s3.amazonaws.com/0/60457/487d05d8-2dc3-d2a1-92cf-2a9e6c57feb6.png "スクリーンショット 2014-11-24 18.37.55.png")


# Notificationで起動するScheme設定
Glanceの場合と同じようにSchemeを作って最後にExecutableをNotificationにするだけ。
Auto Layout 使用時に、Table View、Scroll Viewの上部に空白が表示されてしまうときの対処法



![screenshot.png](https://qiita-image-store.s3.amazonaws.com/0/39324/b164d048-9ec0-2b07-3200-a3aaa24352e9.png "screenshot.png")

↑のようなのやつです。下記２つの対応で解決しました。

* Constraints を親 View に対してではなく、Top Layout Guide に対して設定する

![constraint.png](https://qiita-image-store.s3.amazonaws.com/0/39324/5fa7159d-da54-b9fe-d62b-f01c34c9a6ec.png "constraint.png")



* コード内で下記指定を行う

```
self.automaticallyAdjustsScrollViewInsets = false
```
Hubot × node-cron で、定刻/定間隔に ○○ をさせる簡単な例


実現したいことはタイトルの通りです。使いどころとしては、例えばお昼や就業時間の定時になったらチャットルームに通知、とかでしょうか。
もしくは開発プロセスにおいて、もし定期的に実施するタスクがあれば通知するとか。タスク自体を Hubot にやらせてもいいですね。

これらは Node.js の node-cron を利用すれば簡単に実現できます。

Hubot の作り方や環境まわり(Heroku や Yeoman)については、以前に書いた投稿を参考にしてください。
⇒ [Hubot を Twitter の公開タイムラインに住まわせる](http://qiita.com/hkusu/items/36ce56f3df4e7a0937cb)
⇒ [Yoeman で Hubot を作成して Heroku へデプロイし Slack と連携する](http://qiita.com/hkusu/items/1dc7db9607ab8cb35150)

cron は、Node.js 用のこれを使います。現時点のバージョンは `1.0.5` です。
⇒ https://github.com/ncb000gt/node-cron

# 手順

## node-cron の npm パッケージを導入

Yoeman で 雛形を作成したら、`package.json` に下記を追記します。

```diff:package.json
{
  "name": "hubot-twibot",
  "version": "0.0.1",
  "private": true,
  "author": "Hiroyuki Kusu <kusu0806@gmail.com>",
  "description": "A simple helpful robot for your Company",
  "dependencies": {
    "hubot": "^2.9.3",
    "hubot-diagnostics": "0.0.1",
    "hubot-google-images": "^0.1.0",
    "hubot-google-translate": "^0.1.0",
    "hubot-help": "^0.1.1",
    "hubot-heroku-keepalive": "0.0.4",
    "hubot-maps": "0.0.0",
    "hubot-pugme": "^0.1.0",
    "hubot-redis-brain": "0.0.2",
    "hubot-rules": "^0.1.0",
    "hubot-scripts": "^2.5.16",
    "hubot-shipit": "^0.1.1",
    "hubot-youtube": "^0.1.2",
+    "cron": "^1.0.5"
  },
  "engines": {
    "node": "0.10.x"
  }
}
```

追記してファイルを保存したら、コンソールで `$ npm install` します。

## cron のジョブと、実行させたいタスクを記載する

`CronJob` クラスを冒頭で require し、これを new でインスタンス化する際に引数で、ジョブの設定を行います。

```scripts/cron_tweet.coffee
CronJob = require("cron").CronJob

taskA = ->
  console.log "This is task A"
  # ..

taskB = ->
  console.log "This is task B"
  #..

taskC = ->
  console.log "This is task C"
  #..

job = new CronJob(
  cronTime: "*/10 * * * * *"
  onTick: ->
    taskA()
    taskB()
    taskC()
    return
  start: false
)
```

`cronTime` キーの値に、スペース区切りで「秒」「分」「時」「日」「月」「週」の設定を書きます。

> 詳しくは node-cron のページを参照ください。
> ⇒ https://github.com/ncb000gt/node-cron

`onTick` キーの値(function)で、実行したいタスクを羅列すればOKです。


もしチャット経由で cron ジョブの開始/停止を指示したい場合は、次のように `robot.respond` を契機として `job.start()` `job.stop()` をすればいいです。

```scripts/cron_tweet.coffee
〜

module.exports = (robot) ->

  robot.respond /start job/i, (msg) ->
    msg.send "Start job.."
    job.start()

  robot.respond /stop job/i, (msg) ->
    msg.send "Stop job.."
    job.stop()
```

もし自動で ジョブを開始したい場合は、`CronJob` クラスのインスタンス化の引数で、`start` キーの値に `true` を指定しておけばOKです。

〜おしまい〜
docker管理用スクリプト

dockerコンテナの上げ下げが面倒になったので適当にスクリプト化してみた。
https://github.com/koitatu/docker.git

###start_all_container.sh
全コンテナ起動用スクリプト(statusがExitになっているコンテナを全て起動)

###stop_all_container.sh
全コンテナ停止用スクリプト(statusがUpになっているコンテナを全て停止)

###run_images.sh 
docker run用スクリプト(引数が3つだとポートマッピングなし。4つだとポートマッピングあり。)
しょっちゅうコマンド忘れるので、シェルスクリプト化しておいた。
コンテナ内の/root/service.shを起動時に実行して、httpd、sshdなどの複数サービスを実行する。
1コンテナ1サービスの原則に反するが、やっておいた方が色々便利そうなのでやってる。

・スクリプト書式

```
run_images.sh [コンテナ名] [コンテナにつけるホスト名] [元にするイメージ名] [ポートマッピング]"
```

・実行例

```
./run_images.sh docker_test99 docker_test99 docker_test 8080:80
```

次はホストのディレクトリをマウントして色々試したい…かな。
タスクでの例外の取り扱いについて

タスク内で発生した例外は、Wait()またはResult呼び出し時に放出される。例外はAggregateExceptionに集約されて、それがスローされる。

## コード例1

```csharp
public class ThrowErrorSample
{
    public static void Run() 
    {
        var task = Task.Factory.StartNew(() =>
        {
            Thread.Sleep(500);
            throw new Exception("なんらかのエラー");
        });

        try
        {
            task.Wait();
        }
        catch (AggregateException exc)
        {
            foreach (var innnerExc in exc.InnerExceptions)
            {
                Console.WriteLine("エラー:" + innnerExc.Message);
            }
        }
    }
}
```


## コード例2 (await使用)

```csharp
class Program
{
    static void Main(string[] args)
    {
        ThrowErrorSample2.Run();
        Console.ReadLine();
    }
}

public class ThrowErrorSample2
{
    public static async void Run()
    {
        var task = Task.Factory.StartNew(() =>
        {
            Thread.Sleep(500);
            throw new Exception("なんらかのエラー");
        });

        try
        {
            await task;
        }
        catch(Exception e)
        {
            //発生したException自体がスローされてくる
            Console.WriteLine("エラー:" + e.Message);
        }
    }
}
```
WindowのFrameのAutosaveと、Storyboardの罠


Xcode 6では、OS X用アプリケーションの開発にStoryboardが使えるようになりました。iOS用のアプリケーション開発ではもうお馴染みですね。OS Xもこれからはxibではなく、Storyboardの方に新機能が追加されていくんでしょう、きっと。

実際にStoryboardを使ってアプリケーションを作ってみたのですが、そのときにハマった罠があったので解決方法と合わせて紹介します。

![storyboard.png](https://qiita-image-store.s3.amazonaws.com/0/8957/f3cbc7f2-aae0-be88-4a39-520b3e2265b5.png)

<dl>
  <dt><strong>ハマったこと</strong></dt>
  <dd>windowのcontentViewControllerのviewを変更すると、windowのframeのautosaveが効かなくなる。</dd>
  <dt><strong>解決方法</strong></dt>
  <dd>windowのcontentSizeと、contentViewControllerのviewのsizeを一致させる。</dd>
</dl>

## WindowのFrameのAutosaveとは

アプリケーションが開いているウインドウのframe(位置、大きさ)が変更されるたびに、最新のframeの値を保存してくれる機能です。加えて、アプリケーションの起動時には、保存されている設定値をもとにウインドウのframeを再現してくれる機能でもあります。

![autosave.png](https://qiita-image-store.s3.amazonaws.com/0/8957/b12cc609-fa7b-d11c-4111-b121d47497db.png)

この機能を有効にしておくことで、ユーザがアプリケーションを一旦終了したあと、次に同じアプリケーションを開いたときにも前回のウインドウのframeが再現されます。
ウインドウを常にたくさん開き、アプリケーションも起動したり終了したり頻繁にする私のようなユーザにとってはたいへん嬉しいことです。

### 有効化する方法

InterfaceBuilderを使った有効化は簡単です。windowを選択した状態で、
Autosave(Autosave Name)を入力すれば完了(※1)です。

![autosave-before.png](https://qiita-image-store.s3.amazonaws.com/0/8957/f9501577-1d3b-a940-1f31-f3c897d731ed.png)

![autosave-after.png](https://qiita-image-store.s3.amazonaws.com/0/8957/914b1433-df73-52fc-bde1-0a81c8f5fed0.png)

## 罠にハマる手順の一例

Autosaveの有効化自体は簡単ですが、いつの間にかAutosaveが効かなくなる、という罠にハマりました。この罠にハマったときの手順を紹介します。

1. Storyboardを使用して新規アプリケーションを作成する
2. windowのautosaveを有効化する
3. アプリケーションを実際に起動し、windowのautosaveが有効化されていることを確認する(ヨッシャ)
4. contentViewControllerのviewを編集する
  * ボタンを置く
  * auto layoutを追加する、など 
5. いろいろ編集する
6. いろいろ編集し終わったのでアプリケーションを実際に起動してみる
7. ア...レ...? auto...saveガ...キイテ......イナイ!?
8. 焦る

## 解決策

原因を切り分けるため、機能を絞り込んで調査した結果、viewControllerのviewのsizeが変更される(を変更する)とautosaveが期待通りに動かなくなることがわかりました。
windowのcontentSizeと,viewのsizeを一致させましょう。

![window-size.png](https://qiita-image-store.s3.amazonaws.com/0/8957/58319386-291f-552a-d09f-abdacffe41af.png)

![view-size.png](https://qiita-image-store.s3.amazonaws.com/0/8957/8cbea7b4-d627-576d-f35b-93a95bfbb7f6.png)

## 原因

いまのところ、今回の解決策で間に合っているのでそれ以上には詳しく調べていません。windowのframeを復元する処理と、windowのsizeをviewに合わせる処理が衝突して、復元に失敗してしまうのかな、と考えています。

## Storyboardを使うと罠にハマる理由

従来のxibファイルを使った手順では、viewはwindowに直接貼られていたので、たいていどんな操作をしてもwindowとviewのサイズは常に同期するようになっていました。そのため、今回の罠にハマることがなかったようです。

一方、新しいStoryboardを使った手順では、テンプレート上にwindowControllerとviewControllerがあらかじめ用意され、それぞれのシーンは綺麗に分離されています。windowのsizeとviewのsizeはInterfaceBuilder上で強制的に同期されることはありません。それにより、windowとviewのsizeの不一致が発生することになり、今回紹介した罠にハマりやすくなっています。

---------

**※1**
Autosaveは、Autosave Nameに設定された名前をkeyとして、User Defaults を使って保存/復元を行います。そのため、Autosave Name は各ウインドウで重複しないように注意する必要があります。
なお、windowにはRestorableという別のオプションがありますが、このON/OFFは今回紹介しているAutosaveの機能には影響がありません。
hubot-github-identifyを使ってみた


hubotでgithub上のユーザやトークンを上手く取り扱うためのライブラリ、[hubot-github-identify](https://github.com/tombell/hubot-github-identity)の紹介です。

# 前提条件

以下が必要です。

* Redis（永続ストアに使用）
* hubotがデプロイされているURL


# hubot-github-identifyとは

以下の機能を提供します。

* チャット上のユーザ名とgithubアカウントを紐付ける機能
* github上のアカウント名に対して、APIトークンを保持・管理する機能


例えば、hubot上からgithubにアクセスするときにhubot自身に登録されたトークンを使うのではなく、ユーザ固有のトークンを使うことができます。

また、チャット上の`mitsukuni` というアカウントがgithub上の`key`というアカウントである場合、githubにアクセスする際は`mitsukuni`から`key`への変換も行うことが出来ます。

hubot-github-identifyはnpmで提供されているので、hubotの`package.json`に追記するだけで使いはじめることが出来ます。


# 使い方

## 環境変数の設定

環境変数に`HUBOT_HOSTNAME`とRedisのアクセス先を登録します。
Redisは生のRedisのほかRedis To GoやRedis CloudのURLを指定することが出来ます。

```bash
export HUBOT_HOSTNAME=http://myawesomehubot.example.org:8888
export REDIS_URL=redis://localhost:6379
```


## Githubユーザ名を登録する

hubotのいるチャットルームで`hubot i am <github username>`と話しかけます。hubotが知らないユーザだと次のように表示されてトークンの登録を促されます。Githubでトークンを取得して、hubotから提示されたURLで登録します。

```text
mitsukuni > hubot i am tombell
Hubot > mitsukuni: Sorry, I don't know of key, maybe you need to register your GitHub username and API token with me at http://myawesomehubot.example.org:8888/github/identity
```


## Githubユーザ名を忘れてもらう

Githubのアカウントを削除するには`hubot forget me`と発言すると忘れられます。

```text
mitsukuni > hubot forget me
Hubot > mitsukuni: Ok, I have no idea who you are anymore.
```


## Githubユーザ名とトークンを忘れてもらう

```text
mitsukuni > hubot forget me
Hubot > mitsukuni: Ok, I have no idea who you are anymore, or who you are on GitHub
```


## hubotのスクリプトでユーザ毎のトークンを取得する

robotオブジェクトにidentityオブジェクトが追加されています。findTokenメソッドにチャットのユーザ名を渡すと、登録済みのGithubのトークンを取得することが出来ます。

```coffeescript
module.exports = (robot) ->

  robot.respond /make some github api request for me/i, (res) ->
    # チャットのユーザ名
    username = res.envelope.user.name

	# Githubトークンを検索
    robot.identity.findToken username, (err, token) ->
      # エラーハンドル
      if err
        switch err.type
          when 'redis'
            res.reply "Oops: #{err}"
          when 'github user'
            res.reply "Sorry, you haven't told me your GitHub username."
      else
        # githubotオブジェクトを任意のトークンで初期化
        github = require("githubot")(robot, token: token)
        github.get "" ...
```
【メモ】rubyで配列の空文字要素を削除する

#map関数などと組み合わせて任意の要素を削除したい場合に使う


```rb
tags = {
  :val1 => "aaa",
  :val2 => "bbb",
  :val3 => "ccc"
}
t = tags.map { |key, value| key unless value == "bbb" }
t -= [nil]
p t
=> [:val1, :val3]
```

##参考URL
http://stackoverflow.com/questions/5878697/how-do-i-remove-blank-elements-from-an-array
文字を文字コードに変換する


# 目的

Swift で ```String``` から取り出した文字を文字コードに変換します。


# 文字を文字コードに変換する

たとえば文字が ```charValue``` に格納されているとき、それを文字コードに変換するには次のようにします。

## Unicode 文字コードに変換する

```Character``` 型の文字を ```Unicode``` 文字コードに変換します。

それには、文字をいったん文字列にした上で ```unicodeScalars``` で文字毎の Unicode コレクションを取得し、その最初の文字の ```value``` を参照します。


```swift
let code:UInt32 = String(charValue).unicodeScalars.first!.value
```

> ```UTF-16``` の文字コードは ```UInt32``` 型で取得できます。2 バイト文字も 4 バイト文字も 1 つの文字として扱われます。

## UTF-8 文字コードに変換する

```Character``` 型の文字を ```UTF-8``` 文字コードに変換します。

それには、文字をいったん文字列にした上で ```utf8``` で 1 バイト毎の ```UTF8.CodeUnit``` コレクション (```String.UTF8View```) を取得します。

```swift
let codes:String.UTF8View = String(charValue).utf8
```

```UTF-8``` の場合、1 文字が 1 バイトとは限らないため、戻り値の ```String.UTF8View``` では複数のバイトデータが含まれることがあります。

その最初の文字コードが欲しければ次のようにします。

```swift
let code:UTF8.CodeUnit = codes.first!
```

```UTF8.CodeUnit``` は ```UInt8``` と同等に扱えます。

---

[詳細] http://ez-net.jp/article/28/7I6PI-lB/27pbsZx7YJG_/
押さえておきたい！「Ruby on Rails」マイグレーションを使ったカラムの変更方法まとめ

#はじめに
「Ruby on Rails」で必ず必要になってくる、マイグレーション系
一度作成したカラムを変更したいときってありますよね。
今回は最低限押さえておきたい、マイグレーションを使ったカラムの変更方法をまとめてみました。


#そもそもマイグレーションって？
マイグレーションとはマイグレーションファイルというものを元にテーブルを新規に作成したりカラムやインデックスの追加といった変更を行なうことが出来ます。
つまりマイグレーションファイルさえあれば、簡単にカラムを変更することが出来るのです。


#マイグレーションファイル実行までの手順
ざっくり説明すると
**マイグレーションファイル作成 →　生成したマイグレーションファイルの編集　→　マイグレーションファイル実行**
これだけです。
では実際に**マイグレーションを使ったカラムの変更方法**をご紹介していきます。

#カラムの追加
```
$ rails generate migration Addカラム名Toテーブル名 カラム名:型名
例:($ rails generate migration AddHogeToHuga hoge:string)
```
「Addカラム名Toテーブル名」のカラム名とテーブル名は先頭を大文字にして記入します。

これでマイグレーションファイルを生成することが出来ます。
あとは

```
$ rake db:migrate
```
で実行してデータベースに反映させます。（生成したマイグレーションを弄らなくても大丈夫）

#カラムの削除
```
$ rails generate migration remove_カラム名_to_テーブル名 カラム名
例:($ rails generate migration remove_hoge_to_huga hoge)
```
これでマイグレーションファイルを生成することが出来ます。
あとは

```
$ rake db:migrate
```
で実行してデータベースに反映させます。（生成したマイグレーションを弄らなくても大丈夫）

#カラムの型変更

```
$ rails generate migration change_カラム名_to_テーブル名
例:($ rails generate migration change_hoge_to_huga)
```
これでマイグレーションファイルを生成することが出来ます。
次に生成したマイグレーションファイルを編集します。

```rb:20141124000000_change_column_to_Huga.rb
class ChangeColumnToHuga < ActiveRecord::Migration
  #変更後の型
  def up
    change_column :Hugas, :hoge, :integer, null: false, default: 0
  end
  
  #変更前の型
  def down
    change_column :Hugas, :hoge, :integer, null: true
  end
end
```
このように編集します。
（「def up」「def down」はマイグレーションファイル生成時記述されていませんが、上書きして大丈夫です）

最後に

```
$ rake db:migrate
```
で実行してデータベースに反映させます。

以上です。カラムの変更は頻繁に行われるのでここは押さえておきたいですね。
rubyのrequire '**'で`mkdir': Permission deniedと出る時の対処法

rubyで、nokogiriでスクレイピングしようとしたら以下のエラーが出た。
open-uriのみ記述の場合はエラーが出ないので、どうやらnokogiriが原因っぽい。

```rb
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/fileutils.rb:245:in `mkdir': Permission denied - /Library/Ruby/Gems/2.0.0/extensions/universal-darwin-14 (Errno::EACCES)
  from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/fileutils.rb:245:in `fu_mkdir'
  from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/fileutils.rb:219:in `block (2 levels) in mkdir_p'
  from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/fileutils.rb:217:in `reverse_each'
  from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/fileutils.rb:217:in `block in mkdir_p'
  from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/fileutils.rb:203:in `each'
  from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/fileutils.rb:203:in `mkdir_p'
  from /Library/Ruby/Site/2.0.0/rubygems/ext/builder.rb:210:in `write_gem_make_out'
  from /Library/Ruby/Site/2.0.0/rubygems/ext/builder.rb:132:in `build_error'
  from /Library/Ruby/Site/2.0.0/rubygems/ext/builder.rb:171:in `rescue in build_extension'
  from /Library/Ruby/Site/2.0.0/rubygems/ext/builder.rb:156:in `build_extension'
  from /Library/Ruby/Site/2.0.0/rubygems/ext/builder.rb:198:in `block in build_extensions'
  from /Library/Ruby/Site/2.0.0/rubygems/ext/builder.rb:195:in `each'
  from /Library/Ruby/Site/2.0.0/rubygems/ext/builder.rb:195:in `build_extensions'
  from /Library/Ruby/Site/2.0.0/rubygems/specification.rb:1436:in `block in build_extensions'
  from /Library/Ruby/Site/2.0.0/rubygems/user_interaction.rb:45:in `use_ui'
  from /Library/Ruby/Site/2.0.0/rubygems/specification.rb:1434:in `build_extensions'
  from /Library/Ruby/Site/2.0.0/rubygems/stub_specification.rb:60:in `build_extensions'
  from /Library/Ruby/Site/2.0.0/rubygems/basic_specification.rb:56:in `contains_requirable_file?'
  from /Library/Ruby/Site/2.0.0/rubygems/specification.rb:925:in `block in find_inactive_by_path'
  from /Library/Ruby/Site/2.0.0/rubygems/specification.rb:924:in `each'
  from /Library/Ruby/Site/2.0.0/rubygems/specification.rb:924:in `find'
  from /Library/Ruby/Site/2.0.0/rubygems/specification.rb:924:in `find_inactive_by_path'
  from /Library/Ruby/Site/2.0.0/rubygems.rb:185:in `try_activate'
  from /Library/Ruby/Site/2.0.0/rubygems/core_ext/kernel_require.rb:132:in `rescue in require'
  from /Library/Ruby/Site/2.0.0/rubygems/core_ext/kernel_require.rb:144:in `require'
  from /Users/sadakoa/Desktop/main.rb:1:in `<main>'

```

## 対処

```rb
% gem update
#もし怒られたら
% sudo gem update
```

結果、治らない。ここで1時間ちょっと頭を悩ます。
gem installした時にrbenvにパスを通すのを忘れていたので、下記コマンドを打ってみる。

```rb
% rbenv rehash
```

解決した。

## 原因
このエラー、前も見たことがあってその時はどう解決したか覚えていないんだけど、rbenv関係のエラーだった気がする。
(間違っていたらすみません)
対処法としては

* gemをアップデートする
* rbenvをrehashする
* zshでPATHが通ってるか確認する。(通ってなかったら通す)
* いっそrbenvでrubyを入れ直す

らへんを試せば治る気がする。
Python で psd ファイルを png に変換する


[kmike/psd-tools](https://github.com/kmike/psd-tools) を使う.
まず以下を pip で入れる.

```bash
pip install psd-tools
pip install Pillow
pip install packbits
```

コマンドラインから path を指定して, 変換してくれると嬉しいのでそのように作る.

```python
from psd_tools import PSDImage
import sys
import os

def isfilepath(path):
    print(path)
    return os.path.isfile(os.path.abspath(os.path.expanduser(path)))

def ispsd(path):
    if path[-3:] == 'psd':
        return True
    return False

def pngpath(path):
    return path[:-3] + 'png'

file_paths = [file_path for file_path in sys.argv if isfilepath(file_path) and ispsd(file_path)]
for file_path in file_paths:
    psd = PSDImage.load(file_path)
    merged_image = psd.as_PIL()
    merged_image.save(pngpath(file_path))
```

これを `psdtopng.py` として保存してコマンドラインから叩く.

```bash
python psdtopng.py ~/Desktop/hoge.psd
```

すると, `~/Desktop/hoge.png` が出力される:congratulations:

[sqrtxx/psdtopng](https://github.com/sqrtxx/psdtopng)
Android Gradle Plugin 0.14.3+でAPKファイル名を変更する


GradleでビルドしたAPKファイルの名前を変更する方法です。
…それだけだと今更の話なのですが、
Android Studio 1.0 RC1もリリースされたようだし、Gradle Pluginも最新化して…と試してみるとGradle Plugin 0.14.3の変更でいくつかの古いプロパティが使えなくなっていました。
自分の場合はAPKファイルのリネーム部分で`Could not find propety 'packageApplication'`等々のエラーが起き、Syncすらできなかったため、改めて新しいAPIでAPKファイル名の変更を試しました。

普通にビルドすると

```
app-[productFlavor]-[buildType].apk
```

のような名前になると思いますが、これを

```
[applicationId]-[productFlavor]-[buildType]-[versionCode]-[versionName]-[gitCommitHash].apk
```

のようにします。

取りあえず以下のようにすればできました。ごちゃごちゃして汚いですが…
(アプリは`app`というサブプロジェクトになっている前提です)
Android Studio 1.0 RC1 + Gradle Plugin 0.14.4 + Gradle 2.1では警告等出ていません。

```groovy:build.gradle
android {
    :
    project.ext.gitHash = "git rev-parse --short HEAD".execute().text.trim()
    applicationVariants.all { variant ->
        def output = variant.outputs.get(0)
        File apk = output.outputFile
        String newName = output.outputFile.name
                .replace(".apk", "-${variant.mergedFlavor.versionCode}-${variant.mergedFlavor.versionName}-${project.ext.gitHash}.apk")
                .replace("app-", "${variant.mergedFlavor.applicationId}-")
        output.outputFile = new File(apk.parentFile, newName)
    }
}
```
letとlet*の括弧の数を減らす

# はじめに
　タイトル通りの機能を自分で書いてみただけです。

# 実装
　パラメータを作る関数を別に用意しました。nilの省略はできません。
　引数の数が偶数でないときは、エラーになります。

```cl:create_param.lisp
(defun create-param (list)
  (labels ((rec (list result)
			 (if (null list)
				 (nreverse result)
				 (rec (nthcdr 2 list)
						  (push (list (first list) (second list)) result)))))
	(if (evenp (length list))
		(rec list nil)
		(error "wrong number of parameters"))))

(create-param '(a 1 b 2 c 3))
;=> ((A 1) (B 2) (C 3))



;; ループ(do*)を使って書いてみました
(defun create-param/do (list)
  (if (not (evenp (length list)))
	  (error "wrong number of parameters")
	  (do* ((copy-list (copy-list list) (nthcdr 2 copy-list))
			(var (first copy-list) (first copy-list))
			(val (second copy-list) (second copy-list))
			result)
		   ((null copy-list) (nreverse result))
		(push (list var val) result))))

(create-param/do '(a 1 b 2 c 3))
;=> ((A 1) (B 2) (C 3))
```

```let.lisp
(defmacro my-let ((&rest param) &body body)
  `(let ,(create-param param)
	 ,@body))

(my-let (x 1
		   y 2
		   z 3)
  (list x y z))
;=> (1 2 3)

(defmacro my-let* ((&rest param) &body body)
  `(let* ,(create-param param)
	 ,@body))

(my-let* (x 1
			y 3
			z (+ x y))
  (list x y z))
;=> (1 3 4)
```

# おわりに
　コードを見てもらうと分かると思いますが、引数のインデントがずれています。
　Emacsでコードを書いているので、インデントのズレを修正する方法を調べてみようと思います。
CentOS7+Ruby2.1.5+Rails4.1.8+nginx1.6.2

## centos7をvagrantで新たに構築したので、メモ代わりに書く

#### 現在インストールされているもの
- vagrant
- virtualbox
- OSX10.10(Yosemite)
- centos7(vagrant)
- Git

#### 今からインストールするもの
- Nginx
- Rbenv
- Ruby
- Rails

### Nginxをインストールする  
- sudo vim /etc/yum.repos.d/nginx.repo

```nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
```

- sudo yum install nginx

### rbenvをインストールする
- sudo yum install zlib-devel openssl-devel sqlite-devel sqlite httpd-devel curl-devel apr-devel apr-util-devel -y
- git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
- echo 'export PATH="\$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
- echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
- exec $SHELL -l
- rbenv --version
- git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
- rbenv install 2.1.5
- rbenv rehash
- rbenv global 2.1.5
- rbenv versions \#バージョン2.1.5に*がついていたら成功

### railsインストール
- gem update
- gem update--system
- gem install bundler
- gem install rails --no-ri --no-rdoc -V #railsのドキュメントはインストールしない
- rbenv rehash
- rails -v

### 以上
*各自環境が異なるので、もしかしたらエラーが出るかもしれません。
[Git] remoteのtagとbranchの名前が同じ場合の消し方

Gitのコマンドメモ

表題どおりの件、リモートリポジトリのタグ名とブランチ名が同名の場合以下の様なエラーが出た

```
error: dst refspec <tag_name> matches more than one.
error: failed to push some refs to 'git@gitlab:<repo_name>.git'
```

こんな時は以下のように指定すれば良いらしい

```bash:tagを消したい場合
git push origin :refs/tags/<tag_name>
```

```bash:branchを消したい場合
git push origin :refs/heads/<branch_name>
```

# 参考
[Remove a Git Tag From Github When There is Also a Branch of the Same Name](http://blogs.perl.org/users/mr_muskrat/2010/10/remove-a-git-tag-from-github-when-there-is-also-a-branch-of-the-same-name.html)
小さいプログラムのためのユニットテストを書きたいのならアドホックなやり方で問題ない

ワンライナーときちんとしたプログラムとの中間のサイズのプログラムを書かないといけないことがあると思う。使い捨てではなく、継続的に使われるちょっとしたプログラムではあるのだけど、たかだか数百行みたいな、どうってこともないプログラムだ。あるいはきちんと育てるつもりのプログラムの開発の初期段階かもしれない。

こういう小規模なプログラムも自明ではないロジックが入っていたりするので、自分の想定しているとおりに動いているのか、小さい単位でユニットテストを書きたくなるのは普通だと思う。

しかしそういう小さいプログラムに対して、きちんとしたユニットテストのフレームワークを持ち込むのは相対的に大げさだったりする。ユニットテストのファイルをコピーしてきてそれをインクルードして、ビルドファイルにユニットテストをコンパイルするターゲットを足して、などというのはちょっと面倒だ。それに、フレームワークを使うと、コードを読む他のプログラマにもフレームワークについての知識があることを前提にすることになってしまう。

ユニットテストの本質は、自分が確認したいと思っていることを小さい単位で実際に実行して確認することだ。その目的さえ達成できればそれ以外は言ってみれば細かい話だ。

第1引数と第2引数を比較して、違ったらエラーを表示して終了する関数を自分で書くのは簡単だ。数行で書ける。小さなプログラムではそういうものを自分で書いてそれをユニットテストに使えばよい。読むのも書くのも簡単だし、大規模な依存関係を持ち込むよりはそちらのほうが簡素でよいと思う。

ユニットテストは別に独立したプログラムである必要もない。1ファイルにプログラム本体とテストを書いて、ある引数が渡されたときだけテストを実行するといった手法を取ることもできる。

とにかくなんでもいいから、自分が確認したいと思っていることが確認できればよい。一番よくないのは面倒だからテストを書かず闇雲に手でテストするというやり方だ（別にそれできちんと動けばいいが大抵時間の無駄になる）。

プログラムが成長してきたらそれなりのやり方に切り替えるほうがよいだろう。フレームワークは確かにいろいろ便利なものを提供している。しかし最初から「きちんとした」やり方を採用する必要はない。必要に応じて途中で切り替えればよい。
mongoDBのワンライナー


```js:mongo

echo 'show dbs;' | mongo
echo 'db.col.find({name: "hoge"});' | mongo dbname

```

--quiteを入れるとlogin時のconnectメッセージとかが省けるので、jq が使える。超見やすい！

```js:mongo+jq

echo 'db.col.find({name: "hoge"});' | mongo dbname --quiet | jq "."

```
* ObjectIdが存在すると、jq動かないので、省きましょう。

```js:mongo+jq+_id_disable

echo 'db.col.find({name: "hoge"}, {_id: 0});' | mongo dbname --quiet | jq "."

```

参考サイト様：
http://d.hatena.ne.jp/naoyes/20110514/1305363160
TrelloのAPIを使ってみる

# キーとトークンの取得
1. trelloにログインする
2. Developer API Keysの取得
    1. https://trello.com/1/appKey/generate にアクセスする
    2. Keyをメモしておく
3. Tokenの取得
    1. 
```
https://trello.com/1/authorize?key=<さっき取得したKey>&name=&expiration=never&response_type=token&scope=read,write
```にアクセスする

    2. Allowをクリック
    3. 表示されたトークンをメモしておく

# TrelloのAPIを実際に使ってみる
## ボードにあるリストを取得
```
https://trello.com/1/boards/<BoardID>/lists?key=<Key>&token=<Token>&fields=name
```

* BoardIDは```https://trello.com/b/HcoG1vhL/susumu-kun```だったら```HcoG1vhL```
添付ファイル名の文字化けをPythonで解読してみる

##添付ファイル名が文字化けする
ごく一部の環境でWindows8のストアアプリのメーラーで日本語名の添付ファイルを受け取ると、`%1B%24%42~.ext`や`%EF%BF%%BA.ext`の様になってしまうことがありました。文字化けというか、元のファイル名がパーセントエンコーディングされたまま扱われてしまうようです。
正しいファイル名で受信するための根本的な対策はわからなかったのですが、とりあえずファイル名だけは調べたいということでPythonを使ってデコードをしてみました。

##Pythonでデコード
Pythonでは`urllib.parse.unquote`を用いることでパーセントエンコーディングをデコードすることが出来ます。ということで、次のコードで変換した結果、

``` python:unquote
import urllib.parse
a = '%1B%24%42%4A%3F%40%2E%1B%28%42%32%37%1B%24%42%47%2F%1B%28%42%2E%70%64%66'
urllib.parse.unquote(a)
```

結果は`\x1b$BJ?@.\x1b(B27\x1b$BG/\x1b(B.pdf`となり読めません。unquoteではデフォルトで`encoding='utf-8'`が指定されているのでutf-8で解釈されるのですが、正常にデコード出来ていないようなので異なる文字コードの様です。

##文字コードを調べる
さて、どの文字コードで表現されていたかを知らないと元の文字列に復元することが出来ないので文字コードを調べる必要があります。文字列を見てみると`%1B%24%42`や`%1B%28%42`といったパターンがあり、これはJISコードで使われるモードを切り替えるコードです。このことから、この文字列はJISコードだろうということが予想できます。

##あらためてPythonでデコード
JISコードはISO-2022-JPとも呼ばれ、（こちらが正式名称っぽい?）Pythonではiso2022-jpという名前で扱われているようです。`encodeing='iso2022-jp'`で文字コードを指定してデコードしてみます。

``` python:unquote
import urllib.parse
s = '%1B%24%42%4A%3F%40%2E%1B%28%42%32%37%1B%24%42%47%2F%1B%28%42%2E%70%64%66'
urllib.parse.unquote(s, encoding='iso2022-jp')
```

`平成27年.pdf`という結果が得られ、無事にファイル名を知ることが出来ました。
jQuery mobileを使わずにtouchemoveに対応する．

mousemoveイベントを検出してお絵かきする画面を，モバイルでtouchmoveに置き換えた時のメモ．
タッチ系のイベントが充実しているjQuery mobileを使った方がスマート．
[jQuery mobileタッチイベント](http://api.jquerymobile.com/?s=touchmove)

今回はモバイル対応で追加実装が多くなかったので，jQueryで対応した．

## 動作環境
Android:4.1.2
Chrome:39.0.2171.59
jQuery:2.1.1

## 実装例
### HTML:タッチ時のスクロールを停止する．
* ~~canvasがVGA以下なので，画面幅はデバイスのサポート範囲まで目一杯取る．~~
* タッチ中に画面移動すると使いづらいので，ユーザスクロールは禁止する．
* canvasはHTML上でサイズ指定しないと，座標がおかしくなる．

```html:canvas.html
<head>
 ...
 <meta name="viewport" 
  content="user-scalable=no">
 ...
</head>
<body>
 ...
 canvas id="canvas" class="canvas" width="640px" height="480px"></canvas>
 ...
</body>
```

### JavaScript:タッチイベントの有無でハンドラを変える
* `'ontouchstart' in window`でタッチイベントの有無を判定してjQueryにtouchmoveハンドラに以下を追加 
`$('#canvas').bind('touchmove', function() { trackingTouch(); })`

* canvas上の座標はタッチ/マウスで取得方法が違う．
  jQueryにtouchmoveハンドラがないので，オリジナルのDOM event objectからcanvasの座標を取得する必要がある．
 * タッチイベント  
 `var rect = event.target.getBoundingClientRect();`  
 `var x = event.changedTouches[0].clientX - rect.left;`  
 `var y = event.changedTouches[0].clientY - rect.top;`
 * マウスイベント  
 `var rect = evt.target.getBoundingClientRect();`  
 `var x = evt.clientX - rect.left;`  
 `var y = evt.clientY - rect.top;`  

```javascript:canvas.js
function init() {
  // オリジナルのDOM objectを取得する
  var canvas = $('#canvas')[0];
  var ctx = canvas.getContext('2d');
  
  ...

  // タッチイベントのサポート可否を調べる
  var isTouch = ('ontouchstart' in window);
  if( isTouch ) {
    $('#canvas').bind('touchmove', function() { trackingTouch(); }); 
  }
  $('#canvas').mousemove(function(evt) { trackingMouse(evt);} );    

}

...

// タッチの軌跡を取得する
function trackingTouch() {
  event.preventDefault();
  // オリジナルのDOM event objectから取得
  var rect = event.target.getBoundingClientRect();
  var x = event.changedTouches[0].clientX - rect.left;
  var y = event.changedTouches[0].clientY - rect.top;

  ...
}

// マウスの軌跡を取得する
function trackingMouse(evt) {
  
  // jQueryのイベントから取得
  var rect = evt.target.getBoundingClientRect();
  var x = evt.clientX - rect.left;
  var y = evt.clientY - rect.top;

  ...

}

window.addEventListener('load', init, false);
```

## 最後に
モバイル系も独自にイベントがあるので，追加実装があったらモバイル用を作ったほうが良さそうです．
MongoDBのCollectionを削除しても容量が減らない対応


MongoDBはデータを削除しても容量は解放されない。再利用されるのかどうかよくワカラナイ *（検証してないので教えてくれたら嬉しい）* 。

節約型でMongoDBを運用していたりすると「ハードディスクやばいよー」ってなる。

何度か実際に対応して問題なさそうだったのでまとめた。

## 環境
* ReplicaSetで3台構成で運用
* MongoDB Versionは 2.4.4, 2.4.8 でやった
* OS debian squeeze

## 一般的な解決策

* サービスをメンテナンスにして大きなサーバに置き換える
* 必要ないデータを削除後、サービスをメンテナンスにして [repairDatabase](http://docs.mongodb.org/manual/reference/command/repairDatabase/) する


## 考えてみる。

### 大きなサーバに置き換え
#### メリット

* シンプル
* 安全そう
* 簡単そう

#### デメリット

* サービス一時停止
* コストアップ

### repairDatabase
#### メリット

* コストキープ
* 他のデータ不整合とかも取れるぽい
* MongoDBぽい

#### デメリット

* サービス一時停止
* 時間がどのくらいかかるのか検証しないといけない
* ブラックボックス
* 空き容量がDB容量＋2GB無いと実行できない

> repairDatabase requires free disk space equal to the size of your current data set plus 2 gigabytes.
> [repairDatabase — MongoDB Manual 2.6.4](http://docs.mongodb.org/manual/reference/command/repairDatabase/)

## やりたくない

* そもそもサービス停止は出来る限りやりたくない。
	* 少しなら仕方ないけど1日とか半日とか死亡フラグ
* よくわからない事は取り返しつかなくなりそうなのでやりたくない
* 当たり前だけどコストはかけないに越したことはない
* マイノリティ根性（もっといい方法は絶対あると信じてた）

## 違う方法でやってみた

1. いらないCollectionを消す
	* これは処理めっちゃ軽いのでバンバン消した
2. しかしやはり容量は解放されず
3. SECONDARYをからっぽにして再度syncさせたらどうなるんだっけ
4. 容量減ったΣ(ﾟдﾟ
5. SECONDARY1台ずつ容量へらしてsyncさせる
6. 全部sync終わったらPRIMARYと入れ替える **（短時間だがアプリ一時停止必要）**
7. 元PRIMARYもからっぽにして再sync
8. あら不思議。メンテナンスは30分ぐらいで完了

## 作業内容詳細

Replicaset構成

<dl>
  <dt>PRIMARY</dt>
  <dd>10.120.41.197</dd>
  <dt>SECONDARY</dt>
  <dd>10.120.41.196</dd>
  <dt>SECONDARY</dt>
  <dd>10.120.41.199</dd>
</dl>


### 1.いらないCollectionを消す

```mongoshell
set:PRIMARY> use dbname;
set:PRIMARY> db.collectionname.drop()
```
一瞬で消えるはず

### 2.SECONDARYをReplicaSetからはずす

```mongoshell
set:PRIMARY> rs.remove("10.120.41.196:27017")
```
外したSECONDARYのログが落ち着くまで見守る

### 3.外したSECONDARYのMongoDBを止める

```mongoshell
set:REMOVED> use admin;
set:REMOVED> db.shutdownServer();
```

### 4.外したSECONDARYのdbpathとlogpathを削除
不安な場合は圧縮してどこかにバックアップとっておけばそのまま戻せるはず **（未確認）**

```sh
$ sudo rm -r /var/lib/mongodb/*
$ sudo rm -r /var/log/mongodb/*
```

### 5.mongoDB復活
各OSのやり方でどうぞ

```sh
$ sudo service mongod start
```

### 6.ReplicaSet追加
<span style="color:red;font-weight:bold">追加する時にどのmemberからsyncしてくるのか設定しないと、PRIMARYからsyncしちゃってサービスに影響でちゃいます。</span>

rs.syncFromは迅速に叩くとそこからsyncになるので毎回急いでる。 **(いい方法ご存知であれば教えてほしい)**

* PRIMARY側作業

```mongodshell
set:PRIMARY> rs.add("10.120.41.196:27017") # 追加するSECONDARY
```

* 追加するSECONDARY側作業

これをPRIMARYでaddされるまで連打してる。OKのログが出ればとりあえず大丈夫
大きいDBであればsyncFromのサーバのログにslow queryとかが出るのでそこからsync出来ている事が明確になる。
もしPRIMARYでログが出てしまった場合には慌てずにrs.removeしよう


```mongoshell
> rs.syncFrom('10.120.41.199:27017') # もう一つのSECONDARY
```

### 7.あとはsyncをまつ。

```mongoshell
set:PRIMARY> rs.status()
```

を実行して追加したSECONDARYが ```"stateStr" : "SECONDARY",``` となってれば完了。

### 8.もう1個のSECONDARYも同じ事やる
そうするとPRIMARY以外は最適化された容量になる。

最後はPRIMARY

### 9.PRIMARYとSECONDARYを入れ替える
これは数秒程度書き込みが出来ないタイミングが出来てしまうので、
メンテナンスにしないとダメ。

とはいえ切り替わるのは数秒なので、経験上メンテナンス時間は30分以上かかったことはない。

* PRIMARY側作業

```mongoshell
set:PRIMARY> rs.freeze(15)
set:PRIMARY> rs.stepDown(1)
```

### 10.あとは元PRIMARYもからっぽにしたら完了
( ´ー｀)ﾌｩｰ．．．


これよりいい方法をご存知でしたら是非教えていただけたら嬉しいです！
エプソン7910

1重要なパラメータ編集

最大印刷寸法：24インチ（A 1 +）

カートリッジ数量：11色カートリッジ

印刷速度：約0 . 8分（普通紙：下書きモード…

最大解像度：2880x1440dpi印刷

ポートタイプ：USB2.0、10Base-T / 100Base-TX（R…

メモリ：本体：256MB、ネット：64MB

媒質のタイプ：巻紙、単ページ

カートリッジ容量：350ml：写真T5971黒、靑T5…

製品サイズ：1356x667x1218mm

制品重量：84.5kg

騒音レベル：小さく50dB（A）

ハードディスク：ハードディスクを確認飾ら[ 1 ]

詳細なパラメータ編集2

基本パラメータ

カートリッジ数11色カートリッジ

印刷寸法最大24インチ（A 1 +）

最大幅610mm印刷

最大解像度2880x1440dpi印刷

印刷速度が約0 . 8分（普通紙：下書きモード）

約1 . 5分（普通紙：一般モード）

約2 . 7分（粗面紙：一般モード）

約4 . 5分（写真：上質紙パターン
<a href="http://www.ink-revolution.jp.net">インクカートリッジ 通販</a>

約6 . 8分（写真用紙：超高品質モード）

メモリ本体：256MB、ネット：64MB

ハードディスクの確認で飾らハードディスク

ネットワーク印刷支持有線ネットワーク印刷

ポートタイプUSB2.0、10Base-T / 100Base-TX（RJ-45ネットワーク）

制御コードESP / P raster、ESC / P 2、ESC / P 3
<a href="http://www.ink-revolution.jp.net/ink/epson/">エプソン インクカートリッジ</a>

性能パラメーター

印刷方式オートヘッド校正技術、自動ノズル検出技術、新しいLUT（色対照表）技術;両方向印刷、一方の印刷

ノズルに配置されたTFPマイクロ圧電ヘッド（使用知能墨の変換技術の合計3600ノズル

カートリッジ容量350ml：

写真T5971 T5972黒、靑、赤T5973鮮洋、黄色T5974

淡靑T5975、淡赤紫色鮮T5976、淡い淡い黒T5977、黒T5979

粗面黒いT5978 T597A、オレンジ、グリーンT597B
Docker Private Registry の WebUI を発見したので試してみました。

- [docker_registry構築@boot2docker - Qiita](http://qiita.com/esmjp/items/3e6a59ab5e5dfaa91494)

- [Dockerのプライベートリポジトリをちょっとだけ使いやすくしてみる - Qiita](http://qiita.com/to_obara/items/f24bb34ddcbab039fef1)

を読ませて頂いた後、[docker-registry-frontend](https://github.com/kwk/docker-registry-frontend) っていうのを Docker 公式ドキュメント [Docker Registry API Client Libraries](https://github.com/docker/docker/blob/master/docs/sources/reference/api/registry_api_client_libraries.md) の中で発見しましたので、試してみました。なかなか良さそうです。

```rb:Vagrantfile
VAGRANTFILE_API_VERSION = "2"

DOCKER_REGISTRY_HOST = "docker-registry"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.define "docker-registry"

  config.vm.box = "yungsang/boot2docker"

  config.vm.network :forwarded_port, guest: 8080, host: 8080

  config.vm.provision :shell do |sh|
    sh.inline = <<-EOT
      sudo echo 'EXTRA_ARGS="--insecure-registry localhost:5000"' > /var/lib/boot2docker/profile
      sudo /etc/init.d/docker restart
    EOT
  end

  config.vm.provision :docker do |d|
    d.run "#{DOCKER_REGISTRY_HOST}",
      image: "registry",
      args: "--restart=always -p 5000:5000"
    d.run "docker-registry-frontend",
      image: "konradkleine/docker-registry-frontend",
      args: "--restart=always -p 8080:80 --link #{DOCKER_REGISTRY_HOST}:#{DOCKER_REGISTRY_HOST} -e ENV_DOCKER_REGISTRY_HOST=#{DOCKER_REGISTRY_HOST} -e ENV_DOCKER_REGISTRY_PORT=5000"
  end
end
```

```
$ vagrant up
$ docker ps
CONTAINER ID        IMAGE                                          COMMAND                CREATED             STATUS              PORTS                           NAMES
8d4d03f327d6        konradkleine/docker-registry-frontend:latest   "/bin/sh -c $START_S   11 minutes ago      Up 11 minutes       443/tcp, 0.0.0.0:8080->80/tcp   docker-registry-frontend
b952b4364782        registry:latest                                "docker-registry"      15 minutes ago      Up 15 minutes       0.0.0.0:5000->5000/tcp          docker-registry
$ docker pull yungsang/busybox
$ docker tag yungsang/busybox localhost:5000/busybox
$ docker push localhost:5000/busybox
$ open http://localhost:8080/#/repository/library/busybox/
```

下記の画面が出てきたら大成功です！

![frontend.png](https://qiita-image-store.s3.amazonaws.com/0/1932/7781eaf3-e653-164e-fd1e-878b52c2e368.png)
serverspecでユーザーを指定してコマンドを実行

# はじめに
serverspecでユーザーを一時的に変更してコマンドを実行する方法を解説します。

# spec_helper.rb
次のメソッドを追記します。

```rb
def user_command(user, cmd)
  command("su -l #{user} -c '#{cmd}'")
end
```

# 使い方
* rbenv_spec.rb

```rb
require 'spec_helper'

describe user_command(:alice, 'rbenv versions') do
  its(:stdout) { should match /system/ }
  its(:stdout) { should match /\* 2.0.0-p353/ }
  its(:stdout) { should match /2.1.3/ }
end
```
CSSのdisplay table と table-cell で横幅を複数カラム分割する

displayのtableとtable-cellを使うと、スマホでありがちな2カラムや3カラムのような均等分割が簡単にできます。

# tableとtable-cellで横幅を複数カラム分割
tableとtable-cellを指定するとそれぞれ、タグのtableとtdとして扱ってくれるようです。

```html:2カラムにしたいHTML
<div class="items">
  <p class="item item--left">aaaa</p>
  <p class="item item--right">bbbb</p>
</div>
```

```css:tableとtable-cellを指定
.items {
  display: table;
  width: 100%;
}
.item {
  display: table-cell;
}
.item--left {
  background: red;
}
.item--right {
  background: blue;
}
```
tableを指定している、外側のitemsクラスにwidthの100%を指定すると、最大幅に広がった形で上手く2カラムに均等分割されます。

# 表示
横幅が分割された表示です。

<img src="https://qiita-image-store.s3.amazonaws.com/0/1624/73857199-562b-eeb4-0eca-af1bbe88635d.png" width="320" alt="tableとtable-cellで2カラム表示" />

displayのtable-cellをあまり使ったことがなかったので試してみました。
bootstrapなどのgridレイアウトクラスを使うよりもこちらのほうが楽な場合がありますねー(☝ ՞ਊ ՞)

# 縦の中央表示
テーブルの中央表示をする場合は、vertical-alignが有効です。

```css:table-cellの縦中央揃えを指定
.item {
  vertical-align: middle;
}
```
Basic認証設定

任意のURLに入ろうとしたときにアクセス制限をかけたい、ということで今回はBasic認証について調べてまとめました。

<環境>
CentOS 6.4
Apache 2.2.15

<h2>Basic認証とは</h2>
サイトやディレクトリへのアクセス制限方法のひとつ。限定されたユーザにのみサイトやページへのアクセスを許可したい場合に用いられる。

<h2>BASIC認証への道</h2>

<h3>ユーザへのパスワード発行</h3>

htpasswdコマンドを使ってユーザにパスワードを発行します。今回は初めて設定するということで以下のコマンドを使用しました。

```
htpasswd -c -b /etc/httpd/conf/.htpasswd ユーザ名 パスワード
```

オプション -c :  新しいパスワードファイルを作成する。既存ファイルがあった場合は上書きされる。

オプション -b :  パスワードを対話式ではなくコマンドライン引数として入力できるようにする。

＊すでにhtpasswdファイルがある場合かつそれに追記したい場合はオプション -c を外してください。


<h3>特定サイトへのBasic認証設定</h3>

エディタでApacheの設定ファイル /etc/httpd/conf/httpd.conf を開いてください。ここではviを使います。

```
vi /etc/httpd/conf/httpd.conf
```

そして最終行に下記を記述してください。

```
<Directory "/var/www/phpMyAdmin/">
      AuthUserFile /etc/httpd/conf/.htpasswd
      AuthGroupFile /dev/null
      AuthName "Basic Auth"
      AuthType Basic
      Require valid-user
</Directory>
```

上記例では phpMyAdmin にアクセスしようとしたときにBASIC認証が行われるように設定しました。


最後に、Apacheを再起動してください。

```
/etc/init.d/httpd restart
```

これでphpMyAdminのBasic認証設定が完了しました。

これで大丈夫！かと思ったらBasic認証は盗聴や改竄が簡単にできてしまうという欠点があるらしいです。これを防ぐためにDigest認証というのがあるみたい。。。後日調べてまとめてみようと思います。

最後までお読みいただきありがとうございました。
Atom: JavaScript in Snippets

#Sample Javascript in Atom's Snippets

```js
'.source.js':
  'Date TODO: insert':
    'prefix': 'datetd'
    'body': """
      TODO: (RAM) $1  -  #{datetime = new Date(); datetime.getFullYear()}-#{(datetime.getMonth()+1)}-#{datetime.getDate()} #{datetime.getHours()}:#{datetime.getMinutes()}
      #{"hello".toUpperCase(); }
      $2
    """
```

#Trigger
While in a file with .js extenstion:
Typing: **datetd**

will result in

```js

TODO: (RAM)   -  2014-11-23 20:55
HELLO
```
```
Java入門：第13回 親クラスのメソッドの実行とstaticメソッドの実行

##親クラスのメソッドの利用

前回は主に継承とオーバーライドについて解説しました。実際のAndroidプロジェクト生成されるコードには次のような記述があります。

```java
           setContentView(R.layout. activity_main);
```

いきなりsetContentView()といメソッドが出てきます。このメソッドはコンテンツ（Cntent）の見た目（View）をセットするということで画面をセットしているということはなんとなく理解できると思うのですが、なぜこのメソッドが利用できるのは余り詳細に説明がないまま話が進むことが多いです。そこで模擬的に作成しているクラスを修正し、このsetContentView()メソッドを実装してみましょう。

```java
public class MyAppActivity extends Activity{
      void onCreate() {
            super.onCreate();
            setContentView( "私の画面の見た目" );
     }
}
```

すると当然、setContentView()メソッドは定義されていないので、コンパイルエラーとなります。なぜ実際のAndroidプロジェクトではこのsetContentView()メソッドが記述できるかというと、これはActivityクラスに定義されているメソッドを利用しているからなのです。模擬的なActivityクラスにsetContentView()メソッドを追加してみましょう。

```java:Activity.java
public class Activity {
     String message = "こんにちは";
      void setContentView(String msg) {
           System. out.println( "画面をセットしました=" + msg);
     }
//～略～
```

mainメソッドが記述されているHelloクラスから呼び出すと次のように表示されます。

```java:Hello.java
public class HelloWorld {
      static public  void main(String [] args) {
           Activity actA = new MyAppActivity();
           actA. message = "おはようございます" ;
           actA.onCreate();
     }
}
```

```java
onCreateです
おはようございます
画面をセットしました=私の画面の見た目
```

このように、継承を行うことによって、
1. メソッドを再定義（オーバーライド）しもともとある動作を変更する
2. 親クラスのメソッドを利用する
の２つを行うことができるようになります。

##staticメソッドの利用

ところで、Androidアプリケーションの開発ではログを利用してアプリケーションの動作を確認することができます。例えば次のように記述します。

```java
            Log.d( "TAG", "ここが実行されました" );
```

これはActivityクラスのメソッドではなくて、Logクラスのd()というメソッドを実行しているのです。そこでLogクラスを作成してd()メソッドを実装してみましょう。

```java:Log.java
public class Log {
      void d(String tag, String msg) {
           System. out.println( "tag=" + tag + ":メッセージ=" + msg);
     }
}
```

Logクラスを作成し、d()メソッドを作成したのですが、エラーが解消されません。Javaでは別のクラスのメソッドを実行する場合は、オブジェクトを生成してから実行しなければなりません。次のように記述する必要があるはずです。

```java:MyAppActivity.java
public class MyAppActivity extends Activity{
      void onCreate() {
            super.onCreate();
           setContentView( "私の画面の見た目" );
           Log log1 = new Log();
           log1.d( "目印" , "出力したいメッセージ" );
     }
}
```
オブジェクトは複数生成可能ですから、次のようにも記述可能です。

```java
           Log log1 = new Log();
           log1.d( "目印" , "出力したいメッセージ" );
           Log log2 = new Log();
           log2.d( "目印" , "出力したいメッセージ" );      
```

しかし、出力される結果は共に

```java
tag=目印:メッセージ=出力したいメッセージ
tag=目印:メッセージ=出力したいメッセージ
```

となります。実際のAndroidプロジェクトではLogCatにメッセージが出力されるだけになります。この場合、オブジェクトをわざわざnew演算子で生成しなくても問題ないように思います。このようなときはメソッドにstatic修飾子をつけるとクラス名を利用してメソッドを実行できるようになります。staticとは静的なという意味で、クラスそのものに属するメソッドになります。

```java:Log.java
public class Log {
      static void d(String tag, String msg) {
           System. out.println( "tag=" + tag + ":メッセージ=" + msg);
     }
}
```

とstaticを付加すると、次のように呼び出すことができます。staticはメソッドの他にフィールドに付加することもできます。

```java
           Log. d("目印" , "出力したいメッセージ" );
```

つまり、クラス名（たいてい大文字で始まる単語）の後にピリオドが続き場合は、そのクラスに属しているメンバ（メソッドやフィールド）にstaticにアクセスしていることになります。

### まとめると

1. 継承している場合、親クラスのメソッドを実行することができる
2. staticなメソッドはオブジェクトを実行することができる

となります。逆に言うと、上記以外はオブジェクトの生成が必要になるということになります。そして、オブジェクトの生成は基本的にnew演算子を利用して生成します。
vimで縦に連番を振る

## 課題

* server01
* server02
* ..
* server07
* server08

を縦に生成したいとする。

## 手順

### 準備

1. server01 を入力、Escを押す。
1. qa でマクロ開始
1. yy
1. p
1. $
1. `<C-a>`
1. q

### 実行

1. 7@a

最後はserver010 になるので手で修正。
Compass で specify を使って特定 Sass ファイルだけをコンパイルさせる Gruntfile

Qiita に書くのが 10 か月ぶりという体たらくなぼくです。

さて、Compass でやってる Sass のコンパイルが段々と遅くなってきたので、specify を使って特定の Sass ファイルだけをコンパイルさせようと思います。監視には esteWatch を使ってます。
なお、以下は sass ファイル内で include してる src/_include.sass を更新した場合のみ common.sass / tablet.sass / mobile.sass をコンパイルし、他のファイルは自分だけをコンパイルするようにしています。適宜、'src' としている監視ディレクトリや .scss などへ変更してください。

```lang:Gruntfile.coffee
# compass 内
dev:
	options:
		config: 'config.rb'
		environment: 'development'
		force: true
		specify: '<%= dir.src %>'

# esteWatch 内
sass: (file) ->
	target = file.split('/')[1].split('.')[0]
	grunt.config.set 'dir',
		setCompassConfig(target)
	return ['compass:dev']

# module.exports 外に書く function
setCompassConfig = (target) ->
	if target is '_include'
		return {src: ['src/common.sass', 'src/tablet.sass', 'src/mobile.sass']}
	else
		return {src: 'src/' + target + '.sass'}
```