OmniAICreator/Qiita-1.07M huggingface dataset:
意外と使えるExcelでオートフィルタで表示しているセルだけ取得するVBA


オートフィルタ等で表示しているセルだけ取得し、
非表示セルの情報は無視するコードサンプルです。

オートフィルタを使った処理と組み合わせると、とても便利です。
例えば、欲しい情報だけフィルタリングし、その情報を取得するような処理です。


以下がコードサンプルです。

サンプルでは行番号を取得していますが、この要領で値を取得することもできます。


```vbnet:VBA

Sub Visible_Search()

'変数定義
Dim p As Long , n As Long            'カウンタ変数
Dim r As Range, rr As Range, rs As Range      'Visibleセルを取得する変数
p = 0
n = 2

'Range("A1", Range("A" & Rows.Count).End(xlUp))：A1～データのある最下行
'SpecialCells(xlCellTypeVisible)：表示されているセルのみを対象とする
Set r = Range("A1", Range("A" & Rows.Count).End(xlUp)).SpecialCells(xlCellTypeVisible)
'r：A1～データの存在する最大行セルまでの範囲（表示されているセルのみ）
'rr：A1～データの存在する最大行セルまで、A1から1つずつ格納される
For Each rr In r
    'rsへ選択セルの値を格納
    For Each rs In rr.Areas
        '選択セルの行数を取得
        p = (rs.Row)
        'Visible行の行番号を出力
         Sheets(X).Cells(n, 1).Value = p
         n = n + 1
        End If
    Next
Next

End Sub
```
CentOS6でyumインストールしたphpMyadminのエラーを消す

CentOS6系ではepelリポジトリからyumでphpMyAdminをパッケージインストールすることができます。

```
yum --enablerepo=epel install -y  phpMyAdmin
```


インストール後、/etc/httpd/conf.d/phpMyAdmin.confでログインを許可するIPを設定して、phpMyAdminへログインすると...

```
phpMyAdmin 環境保管領域が完全に設定されていないため、いくつかの拡張機能が無効になっています。理由についてはこちらをご覧ください。
```

と

```
設定ファイルに、暗号化 (blowfish_secret) 用の非公開パスフレーズの設定を必要とするようになりました。
```

のエラーが表示されます。

![スクリーンショット 2016-04-27 21.16.40.png](https://qiita-image-store.s3.amazonaws.com/0/52904/ce7b8e7f-24f0-eb9d-1b0c-91bc396cc2f6.png)



設定ファイル(/etc/phpMyAdmin/config.inc.php)を見てみると、
デフォルトでblowfish_secretが設定されています。

```
$cfg['blowfish_secret'] = '25262116722504531811'; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */
```

でも、エラーは表示されたままです。

ファイルのパーミッションを見てみると

```
ll -a /etc/phpMyAdmin/
drwxr-x---   2 root root 4096 Apr 27 20:57 .
drwxr-xr-x. 71 root root 4096 Apr 27 17:36 ..
-rw-r-----   1 root root 7510 Apr 27 20:57 config.inc.php
```

とrootでしか読み込みができていないため設定が反映されていないため、
所有者をwebサーバの実行ユーザーに変更しましょう。

```
chown -R apache /etc/phpMyAdmin
```

再ログインすると、エラーが消えます。
またjenkinsの設定をバージョン管理してみたい人が現れた

jenkins 2.0をgitでバックアップ・復元する話です。

# jenkinsとバージョン管理

jenkinsはcronの代替品や、エンジニア以外の人にバッチ処理を走らせるための手軽なwebインタフェースとしてはかなり便利です。万が一のために、jenkinsをバックアップ・復元するソリューションもほしいですが、そういった標準機能は未だに存在していません。

大規模のjenkinsならVMイメージやdocker、どちらかと言うとインフラ構成管理のやり方でなんとかなるだろうけど、たった一台のjenkinsの場合、もっと手軽なソリューションがほしくなりますね。できればファイル同期すれば新しいディレクトリーに展開できるようにしたい。というわけで、真っ先にgitに思いつきます。

しかし、jenkinsの設定をgitで管理するには若干強引なところがあります。commitする範囲をファイル名やディレクトリ構造で判断しにくいからです。とはいえ、`.gitignore`で頑張ってファイルを1個ずつ外す人[^1] [^2]もいたので、自分も試してみました。

# 秘伝の.gitignore

というわけで、gitでうまく運用できるかは分からないけど、とりあえずやってみました。自分で一から.gitignoreを作成するのも億劫なので、参考記事[1]のリストを元に、Jenkins 2.0を標準インストールした直後の状態に合わせてみました：

```:.gitignore
# 一般的に除外するもの
*.swp

# jenkins本体
*.jar
war

# ログ、キャッシュ、内部のバックアップ、ローカルの情報
*.log
*.bak
logs/
org.jenkinsci.plugins.github.GitHubPlugin.cache/*
jenkins.model.JenkinsLocationConfiguration.xml

# ユーザ、権限、鍵
.owner
identity.key*
secret.key*
secrets
users

# 更新、プラグインの展開先
plugins/*/
updates

# ジョブ
jobs/*/*
!jobs/*/config.xml
workspace

# 初期化の状態
jenkins.install.*
```

# jenkinsのgitレポジトリ作成とデプロイ

## 既存のjenkinsからgitレポジトリを作る
 1. `$JENKINS_HOME`で`git init`
 2. 上記の.gitignoreを配置し、ignoreされていないものをすべてadd & commitする

## 新しい場所で展開する
jenkins daemonを起動する前に、新しい`$JENKINS_HOME`で下記の作業をする：

 1. `$JENKINS_HOME`で`git clone`
 2. `rm -rf *`
 3. jenkins daemonを起動し、setup wizardを通過する
 4. jenkinsのdashboardが見れるようになったら、`$JENKINS_HOME`で`git reset --hard origin/master`で無理やり最新状態にする
 5. jenkinsを再起動する
    * http://localhost:8080/safeRestart を叩くなど
 6. 再起動が終わったら、ジョブと設定がちゃんと展開されたことを確認する

一度`rm`する理由は、jenkins 2.0は初回起動時に`$JENKINS_HOME`の状態をいろいろ確認したり初期化したりするので、そこで変な依存性を発生させたくないからです。実際、clone後そのまま起動するとsetup wizardが飛ばされます。


# 参考記事
[^1]: VERSION CONTROL YOUR JENKINS SERVER CONFIGURATION WITH GIT https://www.coveros.com/version-control-your-jenkins-server-configuration-with-git/
[^2]: Jenkinsのバックアップとリストアについてメモ http://qiita.com/tq_jappy/items/3654059d09a4896ae598
Ubuntu12.04にインストールしていたJenkinsを2.0にアップデートしたときの手順

Jenkins2.0はJenkins 1.xとの完全な互換性をもっているということなので、
2.0にアップデートしてみました。


# まずはJenkinsを停止

```
$ sudo service jenkins stop
```

# warの置き換え

warの場所は、設定ファイルに書いてあります

```
$ vim /etc/default/jenkins
...
# location of the jenkins war file
JENKINS_WAR=/usr/share/jenkins/jenkins.war
```

warの置き換え

```
# 現在のwarを退避
$ sudo mv jenkins.war jenkins.war.old

# jenkins 2.0をwgetで取得
$ sudo wget http://mirrors.jenkins-ci.org/war/latest/jenkins.war
```

# javaのバージョンをjava7に切り替える

java7以上じゃないと動かないようなので、java7に切り替える

```
$ sudo update-alternatives --config java
There are 6 choices for the alternative java (providing /usr/bin/java).

  Selection    Path                                            Priority   Status
------------------------------------------------------------
  0            /usr/lib/jvm/java-8-oracle/jre/bin/java          1063      auto mode
* 1            /usr/lib/jvm/java-6-openjdk-amd64/bin/java       1061      manual mode
  2            /usr/lib/jvm/java-6-openjdk-amd64/jre/bin/java   1061      manual mode
  3            /usr/lib/jvm/java-6-sun/jre/bin/java             63        manual mode
  4            /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java   1051      manual mode
  5            /usr/lib/jvm/java-7-oracle/jre/bin/java          1062      manual mode
  6            /usr/lib/jvm/java-8-oracle/jre/bin/java          1063      manual mode

Press enter to keep the current choice[*], or type selection number: 5
update-alternatives: using /usr/lib/jvm/java-7-oracle/jre/bin/java to provide /usr/bin/java (java) in manual mode.

$ java -version
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)
```

# jenkinsを起動

```
$ sudo service jenkins start
```

これで正常にアップデートできました。

# トラブルシューティング

うまくjenkinsが起動しない場合は、とりあえずログを確認してみましょう

```
$ tail -f /var/log/jenkins/jenkins.log
```
highchartsのdrilldownで色を個別に設定する方法

# 概要
`activeDataLabelStyle.color`に`''`を設定すれば、個別に設定したデータを引き継ぐことができる。
適当に試して発見した。

# ソース
```js
$(ths).highcharts({
    series: [{
        data: [{
            name: 'データ1',
            drilldown: 'データ1',
            y: 50,
            color: 'red' // ← 個別に設定する色
        }],
    }],
    drilldown: {
        activeDataLabelStyle: {
            color: '', // ← 空を設定する
        },
    }
});
```
JavascriptのaddEventListenerで引数に関数を指定する場合

	<script type="text/javascript">
		document.getElementById('btn').addEventListener('click',result);
		function result(){
			var results = ['大吉','忠吉','小吉','凶','大凶','大狂'];
			var result_num = Math.floor(Math.random()*results.length);//配列の番号をランダムで決める
			document.getElementById('result').innerHTML = results[result_num];
		}
	
	</script>
2行目のように、addEventListener引数に関数を渡す時は関数名のみを書けばいい
◯=>addEventListener('click',result);
×=>addEventListener('click',result());
Flumpt + React-Router

# 概要

Flumpt と React Router の組合せ方。

### 環境

- [React](https://facebook.github.io/react/): 0.14
- [Flumpt](https://github.com/mizchi/flumpt): 0.1.4
- [React Router](https://github.com/reactjs/react-router): 2.3.0

# Router

```js
const routes = (
  <Route path="/" component={Root}>
    <IndexRoute component={IndexPage}/>
    <Route path="/mycomponent" component={MyComponentPage}/>
  </Route>
);

class Routes extends React.Component {
  render() {
    return (
      <Router history={browserHistory} routes={routes}/>
    );
  }
}
```

## 注意

```
<Router history={browserHistory}>
  <Route path="/" component={Root}>
    <IndexRoute component={IndexPage}/>
    <Route path="/mycomponent" component={MyComponentPage}/>
  </Route>
</Router>
```

React Router では上のように書くことができるが、 ```Warning: [react-router] You cannot change <Router routes>; it will be ignored``` という警告が表示されるので、回避策として、```routes``` を ```render()``` の外で定義する必要がある。

# 各ページのコンポーネント

- ```Flumpt.Component``` を継承する。
- ```this.context.emitter.state``` からステートを取得する。

```js
import {Component} from 'flumpt';

class MyComponentPage extends Component {
  componentDidMount() {
    this.dispatch("increment");
  }

  render() {
    const {count} = this.context.emitter.state;

    return (
      <div>
        <Link to="/">Home</Link>
        <hr />
        {count}
        <br />
        <button onClick={() => this.dispatch("increment")}>increment</button>
      </div>
    );
  }
}
```

# App

```<Routes />```を書くだけ。

```js
class App extends Flux {
  subscribe() { // `subscribe` is called once in constructor
    this.on("increment", () => {
      this.update(({count}) => {
        return {count: count + 1}; // return next state
      });
    });
  }

  render(state) {
    return <Routes {...state}/>;
  }
}
```

# サンプルコード

- [yasuhiro-okada-aktsk/sample-flumpt-react-router: Sample: React + Flumpt + React-Router](https://github.com/yasuhiro-okada-aktsk/sample-flumpt-react-router)

# 最後に

Reduxに慣れすぎて、```context.emitter.state``` からステートを取るのに違和感があるので、```react-redux```の```connect```のようなものを作りたい。

# 参考

- [flumpt + react-router sample code.](https://gist.github.com/kajiken/96df11ac4cf843c7b176)
CAKEPHP3 : ログイン後のリダイレクト先の制御

# 記事の対象
1. `AuthComponent` によりアクセス制御を行っている
2. ログインしたら想定してない場所にリダイレクトした
3. (特に) リンクでの移動以外でアクセス(ajaxなど)するアクションに，ログインしていないとアクセスが許可されないものがある

# 本文
## `AuthComponent::redirectUrl()` について
`AuthComponentには redirectUrl()` というメソッドがあり，これは次の優先順位でいずれかのURLを返す．

1. 認証情報ストレージ（デフォルトでは `\App\Auth\Storage\SessionStorage` で，セッションに記録される）の redirectUrl() メソッドで取得できるURL
    - `AuthComponent`によりアクセスを禁止された場合，自動でそのURLがセットされる
    - `AuthComponent::redirectUrl($url)` にてセット可能
2. `AuthComponent`の設定で 'loginRedirect' により設定された URL
3. ホーム

これは次のような遷移を行うのに大変便利である．

1. ログインが必要なアクションに，ログインしていないユーザがアクセスした場合に，ログインページへリダイレクトする
2. ログインする
3. 先ほどアクセスしようとしたページヘリダイレクトする

公式のチュートリアルでも次のように使われている．

```php:ブックマークチュートリアル２より転載
// In src/Controller/UsersController.php
public function login()
{
    if ($this->request->is('post')) {
        $user = $this->Auth->identify();
        if ($user) {
            $this->Auth->setUser($user);
            return $this->redirect($this->Auth->redirectUrl());
        }
        $this->Flash->error('Your username or password is incorrect.');
    }
}
```

## 問題
便利であるが，`redirectUrl()`が最優先で返す「アクセスを禁止されたURL」は何もしなければログインするまで（あるいはストレージの記録が消えるまで）残ったままになっている．
そのため，アクセス禁止後にすぐにログインせずに，別のページを経由して，あらためてログインページからログインした際にも，最後にアクセス禁止されたURLを返す．
この結果，チュートリアルの例では，ユーザや開発者が想定していなかったURLにリダイレクトしてしまうという問題が発生しうる．

## 対策としてこのようにした
`AuthComponent::redirectUrl()` は コールすると，セットされている値を失う．
それを利用して次のようにした．

どのアクションからも経由され，各アクションメソッドを実行したあとに実行される箇所，例えば`AppController::beforRender()` あたりに，次のようにする．

```php:
class AppController extends Controller
{
    public function beforeRender()
    {
        empty($this->protectAuthRedirect) && $this->Auth->redirectUrl();
    }
}
```

そしてログインアクションなどの，アクセスするときにredirectUrlをクリアしたくないアクションでは，コントローラの `$protectAuthRedirect`プロパティにtrueをセットすれば良い．

### さらに面倒な・・・
ajaxで利用するログインしたユーザだけがアクセスできるアクションを用意している場合，問題がもう少し面倒になる．

セッション期限切れなどでajaxのアクセスに403Forbiddenが返ってくるようになり，ユーザがログインページへ直行した場合，この設定だけだと，ログイン直後に ajaxでアクセスしたURLへリダイレクトことになってしまう．

これはもうloginRedirect()の取得値をフィルターに通すしかない気がする．
（だれかもっとスマートなやり方あれば教えて下さい．）
Firebaseのセキュリティ設定をしよう

Firebaseのセキュリティ設定はこのようにすることで誰でも書き込み可能になります。

```js
{
  "rules": {
    ".read": true,
    ".write": true
  }
}
```

これはデータベース中の全てのデータが認証なしに無条件に読み書き削除が可能という最もゆるい状態です。アプリケーションのプロトタイプを作っていく間はこの方が余計なトラブルがなくて良いかもしれませんが、一般公開するシステムでこのような設定になっていると外部からいたずらでデータを改ざんされたり削除されたりする可能性があるので、きちんとセキュリティ設定をしなければいけません。

## 秘密鍵で認証する

一番簡単なセキュリティ設定は、全ての読み書きを秘密鍵で認証されたクライアントのみで行うようにすることです。
まず、セキュリティ設定を全て読み書き不可にします。

```js
{
  "rules": {
    ".read": false,
    ".write": false
  }
}
```

こうすることで、RESTやFirebase SDKを使用したデータベースの読み書きは一切できなくなります。が、管理コンソールからデータをいじる場合と秘密鍵を使って認証した場合は上記のセキュリティ設定に関わらず全てのデータを読み書きできます。
一番堅牢かつシンプルなセキュリティ設定ですが、**秘密鍵が絶対に漏れないように注意しましょう。**

## 特定の変更操作のみを許可する

`".validate"`の記述を使うことで、どのようなデータ変更を許可するかを細く設定することが可能です。例えば以下のようなデータ構造の時に`content.id123.usedCount`にはカウントアップの変更のみを許可したいとします。

```js
{
  "content": {
    "id123": {
      "usedCount": 0,
      "firstUser": "Taro"
    }
  }
}
```

これはセキュリティ設定をこうすれば実現できます。

```js
{
  "rules": {
    ".read": false,
    ".write": false,

    "content": {
      "$id": {
        "usedCount": {
          ".write": true, // 誰でも変更可能
          ".validate": "newData.val() == data.val() + 1" // 前のデータより1大きい値のみ設定可能
        }
      }
    }
  }
}
```

その他、例えば`content.id123.firstUser`にデータがなかった時に新規作成はできるが、更新は不可とするというルールにしたければ次のようになります。

```js
{
  "rules": {
    ".read": false,
    ".write": false,

    "content": {
      "$id": {
        "firstUser": {
          ".write": true, // 誰でも変更可能
          ".validate": "!data.exists()" // 以前のデータが存在しない場合のみ許可
        }
      }
    }
  }
}
```

このようにきちっと書き込みルールを設定しておけば、普通ならサーバー側に隠蔽して行うデータベースアクセス処理でも直接クライアントから行わせられるようになります。

Firebase便利ですね。
seleniumでガラケー環境を構築したい人必見！mac上のseleniumでFireMobileSimulatorを動かす方法はこれだ。

はい。備忘録的な意味合いで。

seleniumでFireFoxのFireMobileSimulatorを実行したい場合、方法として２つあって、一つはselenium実行時に毎回FireMobileSimulatorをインストールするように作る方法と、もう一つは、FireMobileSimulatorがインストールされて且つONになっているプロファイルを作っておいてseleniumに指定する方法がありまーす。後者の方が実行時間てきにもカスタマイズ的にも良さそう（ただし可用性にとぼしい）なので、その方法をここに残します。しかもmacでの方法です。
ポイントはFireMobileSimulatorがインストールされて且つONになっている状態のプロファイルをコピーすることです。なぜならFirefoxを閉じるとFireMobileSimulatorがOffになってしまうからです。

## 方法
１. seleniumで使うFirefoxのプロファイルを生成

```lang:macターミナル
$ /Applications/Firefox.app/Contents/MacOS/firefox -p
```

<img width="395" alt="スクリーンショット 2016-04-27 18.06.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/29779/73604715-0010-a9ea-a5bb-162af8ea2d7f.png">
「新規プロファイルを作成...」で作る

２. そのdefaultのプロファイルでFirefoxを起動して、FireMobileSimulatorをON、且つ、任意のガラケー端末を選択しておく。

３. そのdefaultのプロファイルをselenium用のプロファイルにコピーする。

```lang:macターミナル
cp -r /Users/*******/Library/Application\ Support/Firefox/Profiles/2hzll086.default/* /Users/******/Library/Application\ Support/Firefox/Profiles/ituni81g.selenium_mb/
```

> ※プロファイルパスの取得方法
> FirefoxのURLに「about:support」を入力して「Finderに表示」をクリック。
> Finder上で左クリック（副ボタンクリック）でメニューを表示し、「option」キー押下でメニュー項目が「"****"のパス名をコピー」に変わるのでそれで取得すると吉。
> <img width="500" alt="スクリーンショット_2016-04-27_18_26_58.png" src="https://qiita-image-store.s3.amazonaws.com/0/29779/8c8cc772-448d-fac1-b196-25888d18f3d2.png">


４. seleniumに指定する

```lang:selenium(python)
profile = FirefoxProfile("/Users/********/Library/Application Support/Firefox/Profiles/ituni81g.selenium_mb");
driver = Firefox(firefox_profile=profile)
```
こんな感じでおねがいできれば幸いです。


## お世話になったURL
http://wavetalker.blog134.fc2.com/blog-entry-76.html
 ※Windows環境で指定したい場合はこちらを参照されたし
ottoで構築する環境のubuntuのバージョンを上げる


# 背景
ottoが構築する環境のubuntuのバージョンは12.0４です。

Vagrantのboxに`hashicorp/precise64`を使っています。
https://github.com/hashicorp/otto/blob/master/helper/compile/data/app/dev/Vagrantfile-layer.tpl#L12

ところがprecise64ではdockerコンテナが動きません。
[Unable to provision docker container on precise64 · Issue #496 · hashicorp/otto](https://github.com/hashicorp/otto/issues/496)

依存サービスをdockerで動かせません。
これでは、どこにottoを使う甲斐がありましょうや？

# 対策その1 boxをbento/ubuntu-14.04に変更

issue496のコメントにある
https://github.com/hashicorp/otto/issues/442#issuecomment-212756614
のようにboxを`bento/ubuntu-14.04`に変更します。

これにはottoのソースコードを修正してコンパイルしなおす必要があります。

## ソースコードの修正

```
git clone git@github.com:hashicorp/otto.git
cd otto
```

ソースコードは
https://github.com/hashicorp/otto/blob/master/helper/compile/data/app/dev/Vagrantfile-layer.tpl#L12
の`hashicorp/precise64`を`bento/ubuntu-14.04`に変更します。

## コンパイル

goの開発環境は$HOME/workに設定済みとして、以下のコマンドを実行すると

```
set --export GOPATH $HOME/work
make updatedeps
make dev
```

`~/work/src/github.com/hashicorp/otto/bin/otto`にコマンドができます。


## 実行
```
otto compile
otto dev
```

過去に、otto 0.2で、PC上に別の環境を作っている場合は、これでは上手くいきません。

# 対策その2 PC上のotto環境をクリアする

## 原因
otto 0.2のLayered Development EnvironmentsはVagrantのLinked Cloneを使っています。
ottoは可能な限り、既存のイメージを流用します。

precise64 -> consul -> application のようにコピーして環境構築を行います。

precise64が存在していると対策1で作ったottoコマンドを実行しても、OSは更新されません。

## 既存の仮想環境を削除

```
vagrant global-status
```

を使い関連する仮想環境を`vagrant destroy`コマンドで消します。

## Linked Cloneを削除

Linked CloneのClone元環境はVagrantからは消せないためVirtualboxの管理コンソールから消します。
またVagrantはClone元のidをキャッシュしているます。

```
rm ~/.vagrant.d/boxes/hashicorp-VAGRANTSLASH-precise64/1.1.0/virtualbox/master_id
```

参考: [Vagrant 1.8の新機能 Linked CloneとSnapshotを試してみた ｜ Developers.IO](http://dev.classmethod.jp/tool/vagrant-linked-clone/)

> クローンVMとマスターVMを全て削除するときは注意が必要です。ドキュメントの[Note]にあるようにクローンVMを全て削除してもマスターVMは自動では削除されないので、Virtualbox側で削除する必要があります。 ただ、VagrantはBoxと既存のマスターVMをUUIDで紐付けるメタデータを持っているため、マスターVMを削除するときに以下のメタデータファイルmaster_idも削除する必要があるようです。


## .otto.dを削除
ottoは流用可能なレイヤーを探す際に`~/.otto.d/global-data/vagrant-layered/vagrant-layered.db`の情報を見ています。
https://github.com/hashicorp/otto/blob/master/helper/vagrant/layered.go#L421

このファイルがあるとVgarantのイメージを消しても、消した環境のVagratfileを参照しにいきます。

ひと思いにディレクトリごと消します。
https://github.com/hashicorp/otto/issues/423#issuecomment-176198082

```
rm -rf ~/.otto.d
```

このあとで対策1で作ったottoコマンドを使えば、`ubuntu-14.04`の環境が作れます。
dockerを使いつづけることができます！


# 補足
rubyの環境を作る場合は、上記の問題とは別のエラーが出ます。
[app/ruby: Error on rails preparing database · Issue #393 · hashicorp/otto](https://github.com/hashicorp/otto/issues/393)

環境自体は構築できています。手動で

```
bundle exec rake db:setup || bundle exec rake db:migrate
```
を実行してください。


# 感想
ottoとは、ここまでして使うものか。ちょっと疑問に感じてきました。
Jenkins 2.0 on EC2 セットアップメモ

Jenkins 2.0がリリースされたのでEC2にインストール、セットアップのメモ。
github連携する予定なのででSSL有効にして外部接続を許可する。


## EC2 インスタンス作成
AMIはAmazon Linux
Jenkinsのデフォルトポートの8080をとりあえずセキュリティグループで空けておく。
EIPを割り当てて置く。

## Jenkinsインストール・セットアップ
SSH接続しコマンド実行

```sh
sudo yum update -y
sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
sudo rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key

sudo yum install jenkins
sudo service jenkins start

```
2.0が降ってきます。

## Jenkinsセットアップ

`(割り当てたEIP):8080`にブラウザでアクセス。
![スクリーンショット 2016-04-27 10.21.47.png](https://qiita-image-store.s3.amazonaws.com/0/40221/81c60ab8-9b02-1c8b-2d65-b9ab96a2b16d.png "スクリーンショット 2016-04-27 10.21.47.png")

こんな画面になるので、サーバで	`sudo cat /var/lib/jenkins/secrets/initialAdminPassword`し
表示された文字列をフォームに入れてContinueボタンを押す。

![スクリーンショット 2016-04-27 18.28.56.png](https://qiita-image-store.s3.amazonaws.com/0/40221/f62d712c-8f78-756e-0c76-ef31caed1aa8.png "スクリーンショット 2016-04-27 18.28.56.png")
とりあえず、左側のおすすめプラグインインストールを選択。
![スクリーンショット 2016-04-27 18.31.36.png](https://qiita-image-store.s3.amazonaws.com/0/40221/c1f5dc0b-ecfb-e8ef-8e89-403d193b493d.png "スクリーンショット 2016-04-27 18.31.36.png")
デフォルトユーザ作成しJenkinsの初期設定完了。

## nginx設定
SSL有効化するためにnginxをインストールする。

```
sudo yum install nginx -y
```

[ココらへん](http://d.hatena.ne.jp/rx7/20160205/p1)を参考に証明書をアップロード（もしくはオレオレ証明書を作成し）nginx.conf編集

```nginx.conf
    upstream jenkins {
            server 127.0.0.1:8080 fail_timeout=0;
    }

    server {
            listen 80;
            server_name jenkins.domain.tld;
            return 301 https://$host$request_uri;
    }


    server {
            listen       443;
            server_name _;

            ssl on;
            ssl_certificate /etc/nginx/ssl/server.crt;
            ssl_certificate_key /etc/nginx/ssl/server.key;
            location / {
                    proxy_set_header        Host $host;
                    proxy_set_header        X-Real-IP $remote_addr;
                    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header        X-Forwarded-Proto $scheme;
                    proxy_redirect          http:// https://;
                    proxy_pass http://jenkins;
            }
    }
```

```
sudo service nginx start
```
セキュリティグループ設定で8080ポートを閉じて443ポートを外部公開する。
Route53等でドメイン割当後、Jenkinsの管理>システムの設定のJenkins URLを設定。

# TODO
- github連携
- Dockerビルド
- EC2 Pluginでslave追加
[MAMP] [MySQL] 文字コード設定について

# MAMP MySQL 文字コード設定について

## 設定ファイルを編集

<pre>
$ vim /Applications/MAMP/db/mysql/my.cnf
</pre>


## [mysqld] の項目に
<pre>
skip-character-set-client-handshake
character-set-server = utf8
</pre>

## [mysql] の項目に
<pre>
default-character-set=utf8
</pre>

が追記されていなければ、追記して、MySQLリスタート。

<pre>
mysql> status
--------------
mysql  Ver 14.14 Distrib 5.5.38, for osx10.6 (i386) using  EditLine wrapper

　　　　　　：
　　　　　　：

Server characterset:	utf8
Db     characterset:	utf8
Client characterset:	utf8
Conn.  characterset:	utf8

　　　　　　：
　　　　　　：

--------------
</pre>

となっていればOK。

※ 参考
* http://d.hatena.ne.jp/takenoko1977/20110425
Laravelのマイグレーション


データベースのテーブル作成や編集などを管理する方法として「マイグレーション」ってのがあります。
その方法は大きくわけて２段階。

1. マイグレーションファイルの作成
2. マイグレーション実行

マイグレーションファイルってのは「どんなテーブルを作るか」というテーブルの設計書。
当然設計書を作ったらそれを実行しなければテーブルはできないわけで、この実行にあたるのがマイグレーションです。

今回は実際にフォームで受け取ったデータを格納するテーブルを作っていきます。
[公式ページの **Database:Migrations**](https://laravel.com/docs/5.2/migrations#generating-migrations "公式ページ")のところにあたります。

#マイグレーションファイルの作成

```
$ php artisan make:migration {テーブル名}_table
```

でテーブル作成用のマイグレーションファイルが作成されます。
（ディレクトリの場所は `database/migrations` ）



###追記：オプションについて

```
$ php artisan make:migration create_users_table --create=users
```

上記コマンドのように`--table`と`--create`オプションをつけることができます。
（公式ドキュメント[Generating Migrations](https://laravel.com/docs/5.2/migrations#generating-migrations "Generating Migrations") 参照）

`--create`、`--table`のうしろに`=`でマイグレーションファイルで扱うテーブルの名前を引数として渡すと、
出来上がるマイグレーションファイルはそのテーブル名を含んで雛形が作られます。
（テーブルの作成を行う`Schema::create()`またはテーブルの編集を行う`Schema::table()`）

#マイグレーションファイルの構成

```
<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class Photo extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
    	 // テーブル作成
    	 
    	 /* optionをつけた場合は下のような雛形が最初から作られている  
    	 		 
	        Schema::create('photos', function (Blueprint $table) {
            	$table->increments('id');
            	$table->timestamps();
        	});    	 
    	 */
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
    	 // テーブル削除
    	 
    	 /* optionをつけた場合
    	 
    	    Schema::drop('users');    	 
    	 */
    }
}
```

「up」の中にはテーブル作成時の記述、「down」の中にはテーブル削除時の記述を書きます。
&nbsp;
&nbsp;
「名前(name)」「コメント(comment)」「タグ(tag)」カラムのあるテーブルを作りたいとすると、


```
<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class Photo extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('photo', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('comment');
            $table->string('tag');
            $table->timestamps();
        });

        }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('photo');

        }
}

```

`Schema::`というのはスキーマビルダと呼ばれるもので、テーブルの作成・編集が可能。

`Schema::create`で新規テーブルの作成・編集ができます。
`id`と`timestamps`はデータがテーブルに入るたびに勝手につくので必須。

`Schema::drop`はテーブルを削除します。

`::create`と`::drop`の第一引数である`photo`はテーブル名を意味します。

#マイグレーション実行

```
$ php artisan migrate
```

これでテーブルができます。

#新たにマイグレーションファイルを追加したとき

ただ `php artisan migrate` するのではなく、

```
$ php artisan migrate:refresh
```

としてください。

`refresh`で巻き戻してからじゃないとうまくいかないので。
MacのVagrant上のLaravel5が500 Errorになる。

# Mac Vagrant Laravelで詰まる
会社でMacをもらったので、ニヤニヤしながらLaravelを入れてみたところ500Error。
最初はNginx側の問題だろうと思っていて、confを大分いじってみるもダメ。

そういえばちゃんとエラー見なおそうと思って、見なおしてみたところ

```
2016/04/27 11:23:28 [error] 6326#6326: *89 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught UnexpectedValueException: The stream or file "/var/www/laravel/storage/logs/laravel.log" could not be opened: failed to open stream: Permission denied in /var/www/laravel/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php:97
```

/var/www/laravel/storage/logs/laravel.log" could not be opened: failed to open stream: Permission denied in ...

どうやらlaravel.logを書き込む権限がないみたいなので、chownとかいろいろやってみるとダメで結構詰まった。

# 答え
Windowsでは特に困らなかった気がするが、MacだとVagrantfile上の共有フォルダ部分で権限をもたせる必要があるらしい。

なので、

```
vim Vagrantfile
```

追記

```
config.vm.synced_folder ".", "/vagrant"
↓
config.vm.synced_folder ".", "/vagrant", mount_options: ['dmode=777','fmode=755']
```

共有フォルダにmount_optionsで権限を設定してあげたら動きました！
[CakePHP2]  404エラーの場合に301でリダイレクトする

## CakePHP2で404エラーの場合に301でリダイレクトする

バージョン：CakePHP 2.x
※ baserCMS3系も同様です。

app/Controller/AppController.php

<pre>
class AppController extends Controller {
    function afterFilter() {
        if ($this->response->statusCode() == '404')
        {
            $this->redirect('/', '301');
        }
    }
   :
}
</pre>
[baserCMS] [BurgerEditor] 管理画面で編集できなくなってしまう場合の対応

## パターンその１

画面の下部が崩れて編集ボタンが無くなったり、よく使う項目のところとかが崩れる。

### 原因

管理画面で使ってるクラス名をコンテンツ内で使ってしまっている。

-管理画面で使ってるyuga.js内でrollover処理を行う際に、クラス名がbtn または allbtn、btngroup を指定している要素に対して自動で処理を行う。 
その時に、うまく処理ができず、エラーとなってしまってしまい、管理画面で固定ページが編集できなくなる。-

※ 2系RCにて改修されました

### 対応方法

yuga.jsのrollover処理をやめるか、コンテンツ内のクラスを変更する（管理画面から編集不可の場合はDBを直接編集する）。


## パターンその２

画面の下部が崩れて編集ボタンが無くなったりコンテンツ途中にくっついて表示サれたり、下部フッターがずれたりした。

### 原因

データベースに保存できる文字数の上限を超えた。

### 対応方法

#### MySQLの場合

（その他のDBの場合は不明ですが多分同様の対応で可能かと思います。）

mysite_pages テーブルの contents、draftの型を TEXT型から LONGTEXT型に変更する。
データが中途半端な形で保存されてしまっているので、
データ型の変更後にコンテンツもデータベースを直接編集する。
途中で切れているタグを編集したり削除し、BurgerEditor内で使っている閉じタグなどを追加する。

### 備考

※ データベースを編集した後は、キャッシュクリアを忘れずに！
smartyメモ


すぐ忘れて調べるリスト。

## 数値を3桁毎にカンマ区切りにする

```lang:smarty
{$number|number_format}

```

## smartyでのfor文
たまにやるときある。

```lang:smarty
{section name=hoge start=0 loop=10}
  {$smarty.section.hoge.index}
{/section}
```

## smartyでのcount
配列内を数える時とか。

```lang:smarty
{$array|count}
```

## smartyの日付整形
phpと地味に違って罠。

```lang:smarty
{$data|date_format:'%Y-%m-%d %H:%M:%S'}
/* 表示結果 */
2016-01-01 00:00:00
```

## 指定数で文字を切り捨てる
記事一覧とかに便利。

```lang:smarty
// 200文字で切り捨てる
{$text|truncate:200}

// 200文字で切り捨て、最後に'...'を付ける
{$text|truncate:200:'...'} 

```

## 改行を表示。
与えられた変数内の全ての改行文字`\n`をhtmlの`<br /> `タグに変換。
textareaの値を表示する時とかに。

```
{$text|nl2br}
```

随時更新。
[CakePHP2] イベント（コールバック）無効化

# イベント（コールバック）無効化

DBの値を単純に処理したいのに、プラグインで実装されているイベント処理が予定外に実行されてしまい困ったことがあり、その時に使いました。

## 参照系

### find(beforeFind, afterFind共に無効化)

<pre>
$this->find('first', array(
    'callbacks' => false
));
</pre>

### find(beforeFindのみ有効)

<pre>
$this->find('first', array(
    'callbacks' => 'before'
));
</pre>

### find(afterFindのみ有効)

<pre>
$this->find('first', array(
    'callbacks' => 'after'
));
</pre>

## 更新系

### save(beforeSave, afterSave共に無効化)

<pre>
$this->save($data, array(
    'callbacks' => false
));
</pre>

### save(beforeSaveのみ有効)

<pre>
$this->save($data, array(
    'callbacks' => 'before'
));
</pre>

### save(afterSaveのみ有効)

<pre>
$this->save($data, array(
    'callbacks' => 'after'
));
</pre>

### save(beforeSave, afterSave, validation無効化)

<pre>
$this->save($data, array(
    'callbacks' => false,
    'validate' => false,
));
</pre>

## 参考

http://blog.code-life.net/blog/2013/09/25/cakephp-model-callback/
http://book.cakephp.org/2.0/ja/models/saving-your-data.html

<pre>
save(array $data = null, array $params = array())

$params 配列には、以下のキーを指定できます。

    validate バリデーションの有効または無効について、trueまたはfalseを指定します。
    fieldList 保存する対象のフィールドのリストを指定します。
    callbacks falseをセットするとコールバックを無効にします。他に’before’または’after’を指定して、コールバックを有効にできます。

</pre>
Postfixでメール送信する際に/etc/hostsを参照させる方法

# 目的
vagrantで仮想マシン(CentOS-7.2)を立ち上げ、メール受信時に特定のPHPを実行する開発環境を構築したい。
簡単なメール送信環境を作るため、メール送信用にもう一台仮想マシンを起動。
vagrant間のローカルネットワークなので適当なドメイン作り、メール送信サーバーのhostsに記述したのだが、
/var/log/maillogに `Host or domain name not found` とエラーが出てうまく送信できない。

# 環境
```bash
# uname -r
3.10.0-327.13.1.el7.x86_64
```

```bash
# postconf | grep mail_version
mail_version = 2.10.1
milter_macro_v = $mail_name $mail_version
```

```bash
# alternatives --config mta

1 プログラムがあり 'mta' を提供します。

  選択       コマンド
-----------------------------------------------
*+ 1           /usr/sbin/sendmail.postfix

Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:
```

## メール受信サーバー
+ IP:192.168.33.50
+ ホスト名：postfix

## メール送信サーバー
+ IP:192.168.33.51

```bash:/etc/hosts
192.168.33.50 postfix
```

# 原因
Postfixはデフォルトでは`dns`参照しかせず、サーバーの`/etc/hosts`は参照しない。

# 解決方法
Postfixの設定ファイルに下記を記述。

```bash:/etc/postfix/main.cf
smtp_host_lookup = native
```

Postfixを再起動

```bash:
systemctl restart postfix
```

メール送信の際は先に`/etc/hosts`を参照し、書いていなければ通常通り`/etc/resolv.conf`に指定されたネームサーバーへ問い合わせを行う。

# メール受信時のPHPスクリプト実行
## メール受信サーバー
Postfixの設定ファイルに下記を記述。

```bash:/etc/postfix/main.cf
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
```

PHP実行のためにエイリアスを設定。最終行に追記。
`vagrant: vagrant,`としているのはvagrant宛のメールを残すため。

```bash:/etc/aliases
vagrant: vagrant, "| /usr/bin/php -f phpスクリプトファイルパス"
```

エイリアスを反映。

```bash:
newaliases
```

## メール送信サーバー
`sendmail`コマンドでメール送信。

```bash
# echo Test message! |sendmail vagrant@postfix
```

# 参考
[Postfix に hosts を参照させる](https://aritosato.wordpress.com/2013/03/28/postfix-%E3%81%AB-hosts-%E3%82%92%E5%8F%82%E7%85%A7%E3%81%95%E3%81%9B%E3%82%8B/)
html　改行の仕方

```html
htmlの文章において、改行をしたい時には、<br>タグを使います。
<p>タグや<body>タグと違い、<br>タグは閉じタグ(</br>)が不要です。
（ちなみに<hr>も同様です。）
```

```html
（<br>タグがない場合。)<p>これは、一つ目の段落だよ。ヤッホーーーーー！</p>
（<br>タグがある場合。)<p>これは、一つ目の段落だよ。<br>ヤッホーーーーー！</p>
```

(result)
（`<br>`タグがない場合。)<p>これは、一つ目の段落だよ。ヤッホーーーーー！</p>
（`<br>`タグがある場合。)<p>これは、一つ目の段落だよ。<br>ヤッホーーーーー！</p>
MeshLabで点群データ処理

#MeshLabとは
MeshLabはWindows、Macで使えるフリーの３Dデータ編集ソフトです。
メッシュの処理に特化したソフトであり、三角形メッシュの編集、クリーニング、フィルタリング、レンダリングなどをすることができる優れもの！
また、３次元点群処理も行うことができます！

基本的な処理であったり、プログラムを書かずにメッシュの編集がしたい場合にもってこいです！！

公式サイトより無料でダウンロードできます。
公式サイトURL：http://meshlab.sourceforge.net/

![meshlab.jpg](https://qiita-image-store.s3.amazonaws.com/0/87615/be5d3e02-579b-0b0d-69ac-98edbb8d7860.jpeg)


#MeshLabの使い方
基本的な使い方に関しては[こちら](http://www.pointcloud.jp/blog_n17/)がすごくわかりやすかったので、ご参照ください。

今回は点群データ処理の手順を書いていこうと思います。

###点群データの読み込み
MeshLabが読み込めるデータには　PLY, STL, OFF, OBJ, 3DS, COLLADA, PTX, V3D, PTS, APTS, XYZ, GTS, TRI, ASC, X3D, X3DV, VRML, ALN形式があります。
※PCLから点群を書き出す際にはPCDデータを使用することがありますが、PCDデータはサポートされていないようですので直接MeshLabに読むことはできません。なのでヘッダー部分を除外し、拡張子を「.pcd」→「asc」に変更するなどして読み込ませないといけません。

xyzデータの読み込み
.xyzファイル(下図)をドラックアンドドロップで読み込むことができます。
![new_meshlab02.jpg](https://qiita-image-store.s3.amazonaws.com/0/87615/6ddc29b3-a075-1ac6-1ba0-696384bec22b.jpeg)

UIはこんな感じ
![new_meshlab01.jpg](https://qiita-image-store.s3.amazonaws.com/0/87615/c3bf0dfa-2958-4281-6391-f6fdddf8e5d0.jpeg)


###norm(法線)を計算
目的によっては必要ない場合もありますが、各点群からサーフェスをつくるために法線を計算します。
Filters/Point set/Compute normals for point sets/　を選択し、下図のようなダイアログが出てくるので、Neighbour num (近傍数)を設定し、Applyします。
今回は既定値の10としました。
ちなみに、各処理のパラメータの意味がよくわからなかったら、ダイアログの中にヘルプボタンがあるので押してみるとざっくりですが教えてくれます。
プログレスバーが表示されなくなったら(100%になったら)処理が終了となるので、Render/Show Normal/Curvature を押すと下図のように法線を可視化してくれます。
![new_mesh3.jpg](https://qiita-image-store.s3.amazonaws.com/0/87615/ce9f4ce9-9d33-f64f-2a5e-86c03e32cd3c.jpeg)


###ダウンサンプリング
今回はあまり必要ありませんが、データ数が大きいときにはダウンサンプリングを行います。
Filters/Sampling/Clustered Vertex Subsampling
Cell Sizeを1.0→0.5に変更してApplyします。


###メッシング
点群を法線ベクトルを用いてメッシュを貼ります。
メッシュを貼る方法はいくつかありますが、今回はBall-Pivotingアルゴリズムを使います。
Filters/Remeshing simpleification and Reconstruction/Surface Reconstruction : Ball Pivoting
今回は既定値そのままでApplyしました。
表示をPointsからFlat Linesに変えると以下のように表示されます。
![new_mesh4.jpg](https://qiita-image-store.s3.amazonaws.com/0/87615/ebbd385a-3631-435a-2fed-49a36322d52f.jpeg)

ちなみにメニューバーの左上のほうにある「Show Layer Dialog」で各工程の表示/非表示が切り替えられます。メッシュなどをphotoshopみたいなレイヤーとして扱っています。なので、やり直したいときなどはここからDeleteするしかないっぽいですね。


###スムージング
今回は比較的きれいな点群だったため問題ありませんが、リアルデータはガタガタになることが多いため、スムージングが必要です。
Filters/Smooth ,Fairing and Deformation/Laplacian Smooth
Smoothing steps が大きいほど滑らかになります。
今回は既定値の3としました。
![new_mesh5.jpg](https://qiita-image-store.s3.amazonaws.com/0/87615/7adcaaee-7bc9-9240-dd5d-39655e28229f.jpeg)
なんだか細くなってネズミみたいになっちゃいました…


###欠損の補間
このままでは穴が開いてしまっている部分があるので、それを補間したいと思います。
メニューバーの中央付近に Fill Holeがあるのでそれをクリック。
穴埋めしたい部分をチェックボックスで決めて補間します。（けっこうめんどい）
自動でやる方法もあるはず…
![new_mesh6.jpg](https://qiita-image-store.s3.amazonaws.com/0/87615/f5fc4539-4c81-abee-9992-f045520fe6ab.jpeg)



こんな感じで、点群からメッシュをつくる処理ができます！簡単！便利！
今後は各アルゴリズムの詳細や違いなんかも書いていこうかと思います。
html　一つの段落

```ruby:qiita.rb
<p>これは、一つ目の段落だよ。ヤッホーーーーー！</p>
<p>これは、二つ目の段落だよ。</p>
<p>これは、三つ目の段落だよ。</p>
pがないとこうなるよ。
```

(result)
<p>これは、一つ目の段落だよ。ヤッホーーーーー！</p>
<p>これは、二つ目の段落だよ。</p>
<p>これは、三つ目の段落だよ。</p>
pがないとこなるよ。
SwiftからIRKit経由で赤外線信号を送る

[GetWild退勤的なセンサーアプリを簡単に作れるフレームワークを作ったのでiPhoneに歯痛を心配されたり色々する](http://qiita.com/oubakiou/items/218b6ed08a6faaf5ee8b)
で得た知見シリーズ

[IRKit](http://getirkit.com/)という家電製品のリモコンによる赤外線信号を記録しておいて、スマホ等から操作できるプロダクトがあるのだけれど、IRKitデバイスはそれ自体がHTTP Serverを搭載していて[HTTP API](http://getirkit.com/#IRKit-Device-API)で操作する事ができる。インターネット経由のAPI(api.getirkit.com)も別途存在するが、ここでは同一ネットワークにiOSデバイスとIRKitデバイスがあるものとする。

# IRKitデバイスへ送られた直近の赤外線信号を取得して表示する例

```swift
    @IBOutlet var serverNameTextField: UITextField?
    @IBOutlet var getRecentSignalButton: UIButton?
    @IBOutlet var recentSignalLabel: UILabel?

    @IBAction func getRecentSignal() {
        let request = NSMutableURLRequest(URL: NSURL(string: "http://" + serverNameTextField!.text! + "/messages")!)
        request.addValue("openSensorApp", forHTTPHeaderField: "X-Requested-With")
        request.HTTPMethod = "GET"
        NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: {
            data, response, error in
            (self.recentSignalLabel?.text = String(data: data!, encoding: NSUTF8StringEncoding))!
        }).resume()
    }
```

注意点として、[X-Requested-Withヘッダ](http://maaash.jp/2015/09/irkit-firmware-update/)を付けないと実行できない。

# IRKit経由で任意の赤外線信号を送信する例

```swift
    func request(serverName: String, infraredSignalJson: String) {
        let request = NSMutableURLRequest(URL: NSURL(string: "http://" + serverName + "/messages")!)
        request.addValue("openSensorApp", forHTTPHeaderField: "X-Requested-With")
        request.HTTPMethod = "POST"
        request.HTTPBody = infraredSignalJson.dataUsingEncoding(NSUTF8StringEncoding)
        NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: {
            data, response, error in
        }).resume()
    }
```

任意の赤外線信号と言っても、自宅の家電製品がどんな信号をやりとりしているかを知ってる人はいないと思うので、IRKitで計測したものを取得保存しておきそれを利用する事になるとは思う。

# 問題点

IRKitを持っておらず、赤外線を受け付ける機器も壊れたエアコンしかなく、このコードをテスト出来なくて困ってるので募集中。
S3に追加された画像を自動的にVision APIに投げる

# TL;DR

- Cloud Vision APIを使ってみたかった
- S3 に画像をアップロードしたら背後で自動的に Cloud Vision API に投げて、その結果を SNS に流すようにしてみた

# 背景

とにかく [Cloud Vision API](https://cloud.google.com/vision/) を使ってみたいと思いました。しかしこれといってやりたいことが思い浮かばなかったので、Qiitaに画像をアップロードしたら自動的にCloud Vision APIを実行して、その結果を取り出せるようにしてみることにしました。

# 実装方針

Qiita に画像をアップロードすると実体となる画像ファイルは背後にある S3 バケットに設置されます。 S3 にファイルが追加されるとそれをトリガーにして AWS Lambda を起動できるのでこんな感じにすることにしました:

1. S3 に画像が追加される
2. Lambda が実行されて、その中で Cloud Vision API を叩く
3. API の結果を SNS に流す

3 で SNS に流すことにしたのは、Lambda の中で API の結果をハンドリングすると、新しく機能を追加したいと思った時に毎回既存のものに手を入れなくてはならなくて面倒だからです。その点 SNS だったら、そのトピックを購読する何か（Lambda とか）を新しく追加すればいいだけなので、互いに疎結合になって嬉しそうです。

# 実装

- [GitHub - yuku-t/s3-image-vision-api: Validate images uploaded to AWS S3 with Google Vision API](https://github.com/yuku-t/s3-image-vision-api)

実装した結果、これは汎用的に使いまわせそうだと思ったので、OSSとして公開しました。使い方などはREADMEを読んでください。

# 使ってみた

トピックのメッセージを標準出力するだけの Lambda を登録して

![qiitan.png](https://qiita-image-store.s3.amazonaws.com/0/153/d95fefcb-3d86-6873-c6b6-a4a7c6d8ed6f.png)

↑この qiitan 画像をアップロードしてみた結果

![image](https://qiita-image-store.s3.amazonaws.com/0/153/33f506e1-ba7f-67e7-ee7e-9eda0eb9cc30.png)

ということで、 qiitan は漫画っぽくてアダルド画像ではないことが分かりました。

# 参考

- [Cloud Vision APIの凄さを伝えるべくRasPi botとビデオを作った話 - Qiita](http://qiita.com/kazunori279/items/768c7fdf96cdf45a9d16)
- [Qiitaの画像アップロード機能も簡単に実装できる。そう、S3ならね。 - Qiita](http://qiita.com/yuku_t/items/40b7daf018d3dab48974)
[Java]同一クラスであれば他インスタンスのprivateフィールドにアクセスできるのは何故か？

# 概要

[Javaのprivateフィールドのアクセス権について](http://qiita.com/yu1ro/items/c9d59597373c1a472463)

こちらの投稿を読んで、同じクラスであれば他インスタンスの private フィールドにアクセスできてしまうのは何故か？について気になったので考察してみました。


# 具体例

```java:Main.java
class Main {
  public void static main(String[] args) {
    Something obj1 = new Something("foo");
    Something obj2 = new Something("bar");

    // bar と出力される
    System.out.println(obj1.extractName(obj2));
  }
}
```

```java:Something.java
class Something {
  private String name;

  /**
   * コンストラクタ
   */
  public Something(String name) {
    this.name = name;
  }

  /**
   * 引数に渡されたオブジェクトの private なフィールドを取得する
   */
  public String extractName(Something other) {
    return other.name; // ここで他のインスタンスの private フィールドにアクセスできてしまうことに違和感がある
  }
}
```

# 本質的には Getter で private フィールドを返すのと同じことなんじゃないだろうか？
一般的な Getter は以下のように定義しますが、

```java
class Something {
  private String name;

  public Something(String name) {
    this.name = name;
  }

  public String getName() {
    return this.name;
  }
}
```

ちょっと書き方を変えてみると次のようにも書けます。
※ this を他の変数に格納する、ということはあまりやらないと思いますが問題なく動きます

```java
  public String getName() {
    Something instance = this;
    return instance.name;
  }
```

これは前出の Something#extractName メソッドでやっていることと本質的には変わらない。
どちらも、Something 型のオブジェクトの private フィールドである name にアクセスし、値を返している。


# private フィールドへのアクセスに関する誤解
これまで「private で宣言されたフィールドには this を通して、そのインスタンス自身からしかアクセスできない」というような認識でしたがおそらくそれは正確ではなく、次のように考えれば統一的に理解できます。

- 大前提として、フィールドには `instance.fieldName` という形でアクセスする
- public なフィールドはプログラムのどこでも `instance.fieldName` という形でアクセス可能
- private なフィールドはそのクラス定義内であれば `instance.fieldName` という形でアクセス可能
- this はそのインスタンス自身の参照が入っているだけで他の変数と変わらない

つまり、普段 private フィールドへのアクセスが `this.name` のように記述できているのは、「そのインスタンスのフィールドだから」ではなく、「Something クラス内では `(Somethingクラスのインスタンス).name` という形でのprivateフィールドへのアクセスが許可されているから」である、ということのようです。


# メソッドの場合

試してみたところメソッドでも同じです。
他インスタンスの private メソッドを呼び出せています。

```java:Main.java
public class Main {
    public static void main(String[] args) throws Exception {
        Something obj1 = new Something("foo");
        Something obj2 = new Something("bar");

        // obj2 内の private メソッドが呼び出され、
        // My name is bar と出力される
        obj1.test(obj2);
    }
}
```

```java:Something.java
class Something {
    private String name;
    
    public Something(String name) {
        this.name = name;
    }
    
    private void privateMethod() {
        System.out.println("My name is " + this.name);
    }
    
    public void test(Something other) {
        other.privateMethod();
    }
}
```
【AWS】ebでPython環境構築してみた 開発環境編 【Elastic Beanstalk】

AWSはeb好きみたいです。
だけどeb使ったことなかったのです

http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/create-deploy-python-apps.html
にそって実際に作業してみた記録です
全部できるまで続投する覚悟

[ebでPython環境構築してみた Flaskアプリケーションデプロイ準備編](http://qiita.com/Yuki_BB3/items/db3020c670bad1638ab4)
[ebでPython環境構築してみた Flaskアプリケーションデプロイ編](http://qiita.com/Yuki_BB3/items/344e4e3cef30b813c9bc)

###前提条件

>1.Python 2.7 または 3.4

> 2.ご使用の Python のバージョンに応じた pip ユーティリティ。これは、アプリケーション環境のセットアップ方法を Elastic Beanstalk が判断できるように、プロジェクトの依存関係をインストールし一覧表示するために使用されます。

> 3.virtualenv パッケージ。これは、アプリケーションの開発とテストに使用する環境を作成するために使用されます。これにより、アプリケーションに必要ない余分なパッケージをインストールすることなく、その環境を Elastic Beanstalk がレプリケートできます。

> 4.awsebcli パッケージ。Elastic Beanstalk によるデプロイに必要なファイルを使用して、アプリケーションを初期化するのに使用されます。

> 5.正常に機能する ssh インストール。これは、デプロイの調査またはデバッグが必要なときに、実行中のインスタンスに接続するために使用されます。

とのことです。
簡単に言うと
- pipが使える
- pythonは2.7/3.4使ってる
- virtualenv導入済み
- awscliコマンド使える
- ssh使えるよね

ってことです。
僕はMac使ってます。

---

###仮想環境の設定
ドキュメント以外に参考にさせてもらいました
参考:[Pythonの仮想環境を構築できるvirtualenvを使ってみる](http://qiita.com/H-A-L/items/5d5a2ef73be8d140bdf3)


```:コマンド
virtualenv -p python2.7 /tmp/eb_python_app
```

```:結果
Running virtualenv with interpreter /Users/＊＊＊＊/.pyenv/shims/python2.7
New python executable in /Users/yuki/eb_test_app/bin/python
Installing setuptools, pip, wheel...done.
```

```:確認
ls  /Users/***/eb_test_app/
```

```:結果
bin			lib
include			pip-selfcheck.json
```

環境のインストールが出来ました。

###仮想環境の起動

作成したディレクトリに移動します

```:コマンド
cd /Users/***/eb_test_app/
```

```bash:確認
ｐｗｄ
```

```:結果
/Users/****/eb_test_app
```

```:コマンド
source bin/activate
```

（ディレクトリ名）％ とコンソールの行頭に追加されれば起動しています。

---

###eb用にPythonプロジェクトを設定する

```bash:確認
pwd
```

```:結果
/Users/****/eb_test_app
```

```:コマンド
pip freeze >requirements.txt
```

```pip　freeze``` コマンドで現在インストールされているパッケージを表示します。
それをebが読み込むテキスト「requirements.txt」に書き込むことでebに環境を伝えることができます。

現状は何もインストールされていないと思われるのでテキストを見ても何も出てこないと思います。

例

```:コマンド
pip install Djangp
```

```:確認
pip freeze
```

```:結果
Django==1.9.5
```

こんな感じに。何かインストールされているとその情報が出力されます。

以上が開発環境の作り方編
公開鍵と秘密鍵のペアの作り方と、秘密鍵から公開鍵を再生成する方法

よく使うコマンドなのだけど、たまに迷うことがあるので覚書

- 秘密鍵/公開鍵の作り方

  利用するユーザになってから実行すると間違いが少なめ

- RSA鍵ペア(公開鍵／秘密鍵)作成

※デフォルトの2048bit長が徐々に廃止されてきているため4096bit長を推奨します(2020/07更新)

```
# ssh-keygen -t rsa -b 4096 -N ""
```

- 秘密鍵の属性変更

```
# chmod 600 ~/.ssh/id_rsa
```

※オーナーだけが触れるようにする

- 公開鍵を認証に設定

```
# cp ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys

# ~/.ssh/authorized_keysがある場合は追記

# cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
```

- 公開鍵の属性変更

```
# chmod 400 ~/.ssh/authorized_keys
```

※オーナーだけが触れるようにする

- 秘密鍵の使い方

```
# ssh -i ~/.ssh/id_rsa (ユーザ)@(ホスト名 or IPアドレス)

# scp -i ~/.ssh/id_rsa (転送元) (ユーザ)@(ホスト名 or IPアドレス):(転送先)

# rsync -auz -e ssh -i ~/.ssh/id_rsa (同期元) (ユーザ)@(ホスト名 or IPアドレス):(同期先)
```

- (トラブル対応) 公開鍵を消しちゃった場合で、秘密鍵が残っていれば、秘密鍵から公開鍵を生成することが出来ます

```
# ssh-keygen -y -f ~/.ssh/id_rsa > id_rsa.pub
```

※クライアント側に残してある秘密鍵だけ残っていて、サーバの方がクラッシュした時など
SVGわかるサイト

ハートのサイト：http://mkasumi.com/entry-653.html

元の英語サイト：https://css-tricks.com/svg-line-animation-works/


元の英語サイト2：https://css-tricks.com/svg-line-animation-works/

自転車のサイト：http://2ndidea.com/svg/svg-path-drawing-animation-even-ie/
コマンド

#コントローラー作成
$ php artisan make:controller WelcomeController
→app/Http/Controllers/WelcomeController.php

#コントローラーヘルプ
$ php artisan help コマンド
$ php artisan help make:controller

#DBバージョン管理（マイグレーション）
マイグレーション実行
$ php artisan migrate

ロールバック
$ php artisan migrate:rollback

マイグレーション作成
$ php artisan make:migration マイグレーション名
$ php artisan make:migration create_articles_table

テーブルの作成
$ php artisan make:migration create_articles_table --create=articles

テーブルの変更
$ php artisan make:migration add_published_at_to_articles_table --table=articles

#DB関連コマンド実行
$ php artisan tinker

#モデルの作成
$ php artisan make:model Article

#DBにテストデータや初期値を入れる
$ php artisan db:seed

#HTMLのヘルパー関数の使用
$ composer require laravelcollective/html

#FORM入力値のチェック
$ php artisan make:request ArticleRequest
→app/Http/Requests/ArticleRequest.php
abemaTVが犯した大罪を断罪する

(キャッチーなタイトルをつけてみたかっただけです。そんな大げさなことではありません。すみません。)

##大罪って？
abemaTVですが、今までの動画配信サイトにはない結構痛い不具合があります。
それが、映像の**「見切れ」**これがabemaTVが犯した大罪です。
ほとんどのチャンネルは、多少見切れていても楽しむのにそれほど影響を及ぼしませんが、ただ、海外の特に字幕付きコンテンツとなると話が違ってきます。この見切れにより、字幕部分が見切れてしまい読めなくなってしまっているのです。

###なぜこんなことに
ブラウザーの幅に連動して映像コンテンツのリサイズが行われるのですが高さには連動していません。
ブラウザーのウィンドウを最大化した場合、16:10のモニターでしたら、ブラウザーやシステムの設定にもよりますがChromeの場合、タブやアドレスバー、ブックマークバー、そしてタスクバーの高さを差し引いてもクライアントサイズ(window.innerXxxxx)が16:9に近いものとなり(私の場合ほぼぴったり)、映像のほぼ全体が表示されますので字幕が見切れません。
ただ、16:9以上の横長なアスペクト比のモニターの場合は確実に見切れてしまいます。さらに映像コンテンツのY座標は>=0の範囲で上下し、マイナスとはならず、映像の上部は見切れないですが、下部がその分大幅に見切れてしまいます。
CSSでいうところのbackground-size:coverのようにはみ出し部分が左右もしくは上下が均等になるようなリサイズでしたらまだ救いがあったかもしれませんが・・・。
私は所有しておりませんのでわかりませんが、世の中には21:9という超ワイドなモニターもありますので、これでウィンドウを最大化してabemaTVを見たら3分の2くらいしか見れないのではないでしょうか。
前述のように、横長モニターにおいてはブラウザーの幅を縮めれば映像全体を見ることができますが、abemaTVを見るとき最大化解除するというのはちと面倒です。

###前置きが長くなりましたが
ということで、16:9以上の横長なアスペクト比のモニターでも映像全体を表示する拡張機能(Chrome限定)を作成しました。
これで、字幕が読めるようになります。
[_b_m_TVの見切れを修正する拡張機能](https://chrome.google.com/webstore/detail/hbmmgeclbjfnnmnjodmccibnjhioblhc)
ver 0.0.8で、「新着コメントを表示」を自動クリックする機能を追加しました。また、コメントリストを表示しても映像全体が見れるようリサイズするようにしました。

###あとがき拡張機能を作成するにあたり
ちょっと困ったことがあります。
各チャンネルのアドレスは"https://<span></span>abema.tv/now-on-air/~"で始まるのですが、manifest.jsonのcontent_scriptsのmatchesに"https://<span></span>abema.tv/now-on-air/\*"と設定した場合、直接、"https://<span></span>abema.tv/now-on-air/~"にアクセスすれば拡張機能が発動してくれるのですが、トップページ(https://<span></span>abema.tv)から各チャンネルにアクセスすると拡張機能がなぜか発動してくれません(リロードすれば発動する)。
~~これは今のところ原因がつかめません。~~
**コメントをいただき、pushStateで画面遷移しているのが原因のようです。**
ですので、pushStateをオーバーライドすればいいのではと試してみたのですが、トップページから、各チャンネルページにアクセスできなくなってしまいました。もっと調べればもしかすると行けると思うのですがあきらめました。
スクリプトでURLを判定するコードを書いて実装ししました。

以上
文字列の置換で置換対象と置換文字列をベクトルで指定する（stringr編）


文字列ベクトルの各要素を調べ、「桜」という文字列があれば「桑」に、さらに「ぶどう」があれば「もも」に変換する


```
> library(stringr)
> ## もとの文字列ベクトル
> x <- c("桜の実", "山ぶどう", "たけのこの里", "きのこの山", "水まんじゅう" )
>
> ## 置換対象を名前付きベクトルで与える
> y <- c(桜 =  "桑", ぶどう = "もも")
> 
> str_replace_all (x, y)
[1] "桑の実"     "山もも"    "たけのこの里"    "きのこの山" 

```

余計な文字を切り詰める。「桜の実」なら「桜」に、「たけのこの里」なら「たけのこ」にする。

``` 
> str_replace_all (x, ".*(桜|ぶどう|たけのこ|きのこ).*", "\\1")
> # str_replace_all (x, "(.*)(桜|ぶどう|たけのこ|きのこ)(.*)", "\\2")
[1] "桜"   "ぶどう"   "たけのこ"   "きのこ"   "水まんじゅう"  
  
```
El Capitanでsassとcompassをインストール


OS X 10.11 El CapitanのMac Book Proをもらったからsassとcompassをインストールした。
El Capitanの問題？で従来通りの方法じゃインストールできなくてハマった。


sassはターミナルでカチャカチャすぐインストールできたんだど、
従来通りのコマンドだとcompassがだめみたい。

＜従来通りのコマンド↓＞

RubyGemsアプデ

```lang:filename
sudo gem update --system
```

sassインストール

```lang:filename
sudo gem install sass
```

compassインストール

```lang:filename
sudo gem install compass
```




さっきも書いたけど、sassはインストールできた。
問題はcompassで、

```lang:filename
ERROR:  Error installing compass:
  ERROR: Failed to build gem native extension.
```
英語だからよくわかんないけど、エラーみたい。


なんでや と`compass -v`したけど、`-bash: compass: command not found`

「compass mac インストール　できない」　みたいなキーワードで調べたら、どうやらEL Capitanでは権限の関係でインストールできないらしいよ。
たしかに、「お前そのパーミッションじゃ無理やで」みたいな文字があった気がする。


EL Capitanでcompass使うには、以下のコマンドでインストール先を変えないとだめらしい。

```lang:filename
sudo gem install -n /user/local/bin sass
sudo gem install -n /user/local/bin compass
```
Sublime Text > ファイルの漢字コードがおかしくなった時の対処

```txt:動作確認
Sublime Text 2 on Windows 7
```

ファイルを触っているうちに漢字コードの情報がおかしくなった時の対応.

前提: git管理しているとする（おかしくなる前のファイルをgit でチェックインしているとする）

1. 該当ファイルを消す
2. 新規ファイル作成して日本語テキストを入力して、[Set File Encoding To]で漢字コード(例: ShiftJIS)を選択する。手順2で消したファイル名で保存
3. gitで元のファイルに戻す
4. Sublime Textで該当ファイルを開きなおす

上記のような手順でとりあえず復旧できた。
Jupyter Notebook (*.ipynb)をダブルクリックで開くためのMacアプリケーション

## 概要

[Jupyter Notebook](http://jupyter.org/) (\*.ipynb)をダブルクリックで開くためのアプリケーション**Jupyter Launcher.app**を、MacのAutomatorを使って作成します。buq様のオリジナルのアイデア ([ipython notebook のファイルをダブルクリックで開く @ OS X](http://buq.hateblo.jp/entry/2015/08/19/220453))をもとに、個人的に追加したい機能のためにいくつかの変更を行います。ついでにPythonで書き直しています。

![dock_screenshot.png](https://qiita-image-store.s3.amazonaws.com/0/44000/c2d63cdf-86d9-772e-e41f-0b11e835494b.png)

## 追加機能と変更点

+ アプリ自体をクリックで実行したときはJupyterのツリー画面を表示する
+ Jupyter Notebookのホームを`/`から`~/`に変更する (上記における利便性と安全性のため)

### 細かな改善点

+ Jupyterが確実に起動するまでウェイトする (while文の部分。特にMac起動直後では定数時間のウェイトだと間に合わない場合もあるため)
+ そのため、Jupyterの起動確認はnetstatではなくlsofを使用する (netstatはブラウザが起動しない限りゼロを返し続けてしまうため)

## 作成手順

1. Automator.appを起動し、**新規アプリケーション**を選択し作成開始
2. アクションから**シェルスクリプトを実行**を選択
3. シェルは**/usr/bin/python**を選択
4. 入力の引き渡し方法は**引数として**を選択
5. 以下のPythonスクリプトをウィンドウに入力
6. Jupyter Launcher.appとして/Applicationsに保存
7. お好みでアイコンを設定して完成

![automator_screenshot.png](https://qiita-image-store.s3.amazonaws.com/0/44000/1a43b808-63da-1bd0-fe7a-02c9ef003631.png)

## Pythonスクリプト

**2017.01.14:** スクリプトをアップデート (機能面の変更はなし)

```py:jupyter_launcher.py
# coding: utf-8

"""Script for the Jupyter Launcher Application."""

import os
import sys
import time
import webbrowser
from subprocess import Popen, PIPE


def listened(port):
    """Check if the spacified port is listened or not."""
    cmd = "lsof -i :{} | grep 'LISTEN'"
    proc = Popen(cmd.format(port), stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True)
    return bool(proc.communicate()[0])


def launch_jupyter(port):
    """Launch a Jupyter Notebook Server with the spacified port."""
    cmd = "bash -cl 'jupyter-notebook ~/ --port={} --no-browser &' > /dev/null 2>&1"
    proc = Popen(cmd.format(port), stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True)
    proc.communicate()


if __name__ == '__main__':
    PORT = 8888
    ipynbs = sys.argv[1:]

    if not listened(PORT):
        launch_jupyter(PORT)

    while not listened(PORT):
        time.sleep(0.5)

    if ipynbs:
        for ipynb in ipynbs:
            url = 'http://localhost:{}/notebooks/{}'
            path = os.path.relpath(ipynb, os.environ['HOME'])
            webbrowser.open(url.format(PORT, path))
    else:
        url = 'http://localhost:{}/tree'
        webbrowser.open(url.format(PORT))
```

## References

+ [ipython notebook のファイルをダブルクリックで開く @ OS X - buq's blog](http://buq.hateblo.jp/entry/2015/08/19/220453)
+ [ipython notebook のファイルをダブルクリックで開く：訂正記事 - buq's blog](http://buq.hateblo.jp/entry/2015/08/30/002943)
+ [Macで使っているPortを調べる方法 - Qiita](http://qiita.com/cozycozy/items/972f3e2866b2dfb0f297)
Windows8.1 から Windows10 にUpgrade して発生したvagrantのエラー

### エラー内容

```
...
==> default: Clearing any previously set network interfaces...
There was an error while executing `VBoxManage`, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.

Command: ["hostonlyif", "create"]

Stderr: 0%...
Progress state: E_FAIL
VBoxManage.exe: error: Failed to create the host-only adapter
VBoxManage.exe: error: Code E_FAIL (0x80004005) - Unspecified error (extended info not available)
VBoxManage.exe: error: Context: "int __cdecl handleCreate(struct HandlerArg *,int,int *)" at line 66 of file VBoxManageHostonly.cpp
```

Window10にアップグレードしたことで発生。

世界中のVirtualBox Vagrantユーザが阿鼻叫喚しているようで、
検索するとすぐに原因がわかった。
参考サイト
[Vagrantでのhost-only adapterのエラーを回避する方法 on Windows10](http://d.hatena.ne.jp/kobarn/20150805)

https://www.virtualbox.org/ticket/14040
ここの`VBox-Win10-fix-14040.exe`をダウンロードして実行すればいいようです。

現在、VirtualBoxの最新版(5.0.18)ではこの問題は解決しているようです。
Updateした後に、`vagrant up`すると2回ほど認証を求められるだけで問題なく起動できます。