OmniAICreator/Qiita-1.07M huggingface dataset:
私が本当に業務で行った要件定義の作成手順 - 後編

# はじめに

- もともとは新規Webサービスを立ち上げる際に１からつくったもので、業務の中でドキュメントを作成しました。
- 再利用性を求めてフォーマット化しましたので、二次利用に使うなり、勉強資料などに役立てらればとおもいます。
- 今回は前編、中編、後編の３部で記載しておきたいとおもいます。
- [前回](http://qiita.com/neriai/items/530d7329404d69921301)に続いて、今回は後編となります。

# 前提
- 要件定義を作成する上で、企画書や仕様書など記載する上での前提の資料が必要になってくるかと思います。
- 図を作成する上で、Caccoを利用しております。

# 目次

1. サービスの目的
2. サービス概要
3. サービスに関連する人物
4. サービスに関連する人物がサービスにどのように関わっているのか
5. サービスの利用フローや業務フロー
6. サービスの状態変化
7. **機能要件**
8. **非機能要件**

※太字の部分が今回記載することです。

# 後編の概要

- さて、いよいよシステムを作る上での機能要件です。
- なんか前段色々図書いて、ここに辿り着くまでに大した説明なかったですが、サービス -> システム -> 機能　までのボトムダウンが自身の理解の中で行われていればOKです。
- もし、不明な機能が突然現れたら、中編の洗い出しが粗いか不足しています。もう一度ヒアリングして見直してみましょう。

# 機能要件

- まず、機能要件は細かに機能を出していくのではなく、システムを構成する主軸となる機能を出しましょう。
- 次に機能概要、スコープ、処理フロー、機能一覧、データ要件など一つ一つ詳細化していきましょう。

## 例

### 商品表示機能

##### 機能概要

- 商品のコンテンツ情報を掲出するために提供される機能である。
- また、当機能から商品の予約を行う導線としても用いられる。

![処理フロー.png](https://qiita-image-store.s3.amazonaws.com/0/90598/5e597957-3818-9584-5b9b-71aef9e51f4e.png)

#### スコープ

- 商品情報の表示
- 商品のお気に入り登録

#### 処理フロー

|#|フロー|
|:---|:---|:---|:---|
|1|商品画面にアクセスする|
|2|基本情報を要求する|
|3|基本情報を取得する|
|4|基本情報を出力する|

#### 機能一覧

|#|機能名称|機能区分|機能説明|
|:---|:---|:---|:---|
|1|基本情報の表示|基本情報表示|商品の基本情報を出力します|
|2|販売元情報の表示|販売元情報表示|販売元情報を出力します|
|3|写真情報|写真情報表示|写真情報をスライド式に出力します|
|4|金額情報|金額情報表示|商品の金額情報を出力します|

#### データ要件

- 商品システムに登録された情報のうち、掲載している商品情報に対してデータを取得する。
- 以下の情報を取得する。

```
- 基本情報
- 販売元情報
- 写真情報
- 金額情報
```

# 非機能要件

- 信頼性要件、性能要件、セキュリティ要件、移行要件、運用要件の計５種類を記述します。

## 信頼性要件

### 例

- 本システムは原則24時間365日稼動すること
- システムメンテナンスが必要の際は、ディレクター判断の元のみ実施すること
- システムメンテナンス中は、メンテナンス中画面を出力させること
- システムメンテナンス時間は、最大8時間までとし、AM10時までにはシステムの稼動を再開させること
- フロントエンド画面のシステムメンテナンスは、原則各ページを出力状態とし、予約フォームへの遷移のみ制限をかけるものとする

## 性能要件

### 例

- 原則、1画面におけるレスポンス時間は1秒以内とすること。また、やむをえない場合についてはユーザビリティの観点に基づく処置を行うこと
- 品質管理会社による審査を1回以上実施し、認可されること

## セキュリティ要件

### 例

原則、[IPA](http://www.ipa.go.jp/security/)に明記された情報セキュリティ規約に基づくものとする

- 公開すべきでないファイルを公開しないこと
- 不要なエラーメッセージを返していないこと
- ログを記録していること
- 不正アクセスを防止する対策が施されていること
- プライバシーマーク制度に順ずる対策が施されていること（SQLインジェクション、クロスサイトスクリプティングなど）
- クロスサイトリクエストフォージェリを防止する対策が施されていること

## 移行要件

### 例

- 移行時に掲載する商品データを移行すること
- 移行前に掲載する商品データを作成するためのツールを作成すること
- 移行を実施する際には、移行計画書および移行手順書を作成すること
- 移行前に1回以上のリハーサルを実施すること

## 運用要件

- 以下の運用要件が発生する

```
商品カテゴリマスタの更新
予約数ランキングの抽出
```

- 運用を実施する際には、運用計画書および運用手順書を作成すること

# まとめ

- 今回、駆け足で書いてしまいました。要件定義の書籍などからは外れている部分があるかもしれませんが、書籍がサービスやプロジェクトを支えてくれるわけではなく、それに関わる人に還元できるものになっていればよいかと思ってます。
- Web業界だけではないかもしれませんが、何かを作る時に一番最初に出てくるのは視覚的なイメージです。ただ、それどおりに作っても良いサービスはできません。サービスを利用する人に対して本当に必要なものを届けることを一番にこのような要件定義をしていけば、そのサービスの存在意義が見いだせると思います。

# シリーズページリンク
- [私が本当に業務で行った要件定義の作成手順 - 前編](http://qiita.com/neriai/items/817df489008561a25dd1)
- [私が本当に業務で行った要件定義の作成手順 - 中編](http://qiita.com/neriai/items/530d7329404d69921301)
- [私が本当に業務で行った要件定義の作成手順 - 後編](http://qiita.com/neriai/items/7ebfa50736fd7c075931)
Java Day Tokyo 2017のおもひで

#セッションスケジュール
![図1.png](https://qiita-image-store.s3.amazonaws.com/0/48666/1369e133-2c30-6585-21ac-35328724163e.png)

#参加セッション
![図2.png](https://qiita-image-store.s3.amazonaws.com/0/48666/53fd6816-b5bf-93ec-608b-c0cd23301b35.png)

##Panamaを先取り！？　JVMCIでJITと遊ぶ

###ご本尊
- [Panamaを先取り！？　JVMCIでJITと遊ぶ](https://www.slideshare.net/YaSuenag/panamajvmcijit)

###What’s JVMCI?
>JEP 243: Java-Level JVM Compiler Interface
>
>Summary
>Develop a Java based JVM compiler interface (JVMCI) enabling a compiler written in Java to be used by the JVM as a dynamic compiler

要約：Javaで書いたコンパイラをJVMで動かせるようにする。
→　Javaで(機械語)コンパイラを書く。

**すごいじゃあくをかんじる**

###邪悪ポイント
- Write once, run anywhere
 - CPU毎に命令セットとにらめっこしてbyte[]書いてください
- Java API
 - 機械語レベルにそんなものはない(呼べなくはない)
- JITによる最適化
 - お前がそれを書くのだ

###見方を変えよう
- Write once, run anywhere
 - JDKのセットなのでアプリではなくプラットフォーム側
- Java API
 - 機械語側じゃなくてそのコンパイラで使う
- JITによる最適化
 - **お前がそれを書くのだ**

###面白ポイント
- JITの状態を取得できるAPIがついてる
- JITの状態を制御できるAPIもついてる
- JITのプロファイル情報を取得できるAPIまでついてる
- JNIとか使わなくてもシステムコールとかできる
- JVM系言語を作成する際にJITと連携した別の最適化構造を導入できる
- JVMの仕様に沿ったデータをアセンブラで取り扱うとかいう偉業ができる

###感想文
- JDK必須だし通常のアプリケーションレイヤで活用されることはほぼないはず
- 調査、検証の用途では十分に使いどころはある
- JVM言語系では使いどころが多そう
[iOS] そもそもの元画面(rootViewController)を切り替える方法

AppDelegateではなく、起動後にきれいさっぱりrootViewControllerを替えたかった。
調べたら、以下の方法があったので共有しておきます。


```swift:SwitchRootViewController.rb
// アニメーション
let vc = UIViewController() // 元画面にしたいビューコントローラ
UIApplication.shared.keyWindow?.rootViewController = vc

// アニメーションあり
UIView.transition(with: window, duration: 0.3, options: .transitionCrossDissolve, animations: {
    UIApplication.shared.keyWindow?.rootViewController = vc
}, completion: { completed in
    // maybe do something here
})
```

参考サイト
https://stackoverflow.com/questions/41144523/swap-rootviewcontroller-with-animation
AMIMOTO AMI でアップロードファイルの上限サイズを変更する

# ０．はじめに

以前、

AMIMOTO AMI を使って WordPress を立ち上げたんですが、

その続きというか、なんというか…

* [AMIMOTO AMI を使って、WordPress を立ち上げて、接続先を RDS に変更してみる \- Qiita](http://qiita.com/kusokamayarou/items/58d550b82b960c321c3a)

# １．AMIMOTO AMI でアップロードファイルの上限サイズを変更する
1. 以下のサイトを参考に、関係する chef のファイルを探します。
    * [WordPress から大きいファイルをアップロードしたい – FAQ & SUPPORT](https://amimoto-ami.zendesk.com/hc/ja/articles/228398927-WordPress-%E3%81%8B%E3%82%89%E5%A4%A7%E3%81%8D%E3%81%84%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E3%81%97%E3%81%9F%E3%81%84)

    すると、
    以下のものが引っかかりました。

    <ul>
    <li>/opt/local/chef-repo/cookbooks/amimoto/attributes/</li>
    </ul>
    ```bash
    01_web_server.rb.ORG:default[:nginx][:config][:client_max_body_size] = '4M'
    03_php.rb:default[:php][:config][:upload_max_filesize] = node[:nginx][:config][:client_max_body_size]
    03_php.rb:default[:php][:config][:post_max_size] = node[:php][:config][:upload_max_filesize]
    ```
    <ul>
    <li>/opt/local/chef-repo/cookbooks/amimoto/templates/default/php/php.ini.erb</li>
    </ul>
<br>　
1. chef 関連の設定ファイルを修正します。

    <ul>
    <li>/opt/local/chef-repo/cookbooks/amimoto/attributes/01_web_server.rb</li>
    </ul>
    ```bash
    $ diff 01_web_server.rb.ORG 01_web_server.rb
    29c29
    < default[:nginx][:config][:client_max_body_size] = '4M'
    ---
    > default[:nginx][:config][:client_max_body_size] = '10M'
    ```
    <ul>
    <li>/opt/local/chef-repo/cookbooks/amimoto/templates/default/php/php.ini.erb</li>
    </ul>
    ```bash
    $ diff php.ini.erb.ORG php.ini.erb
    52c52
    < upload_max_filesize = 4M
    ---
    > upload_max_filesize = 10M
    ```
<br>
1. 現状の各種設定ファイルを修正します。

    <ul>
    <li>/etc/nginx/nginx.conf</li>
    </ul>
    ```bash
    $ diff /etc/nginx/nginx.conf.ORG /etc/nginx/nginx.conf
    43c43
    <     client_max_body_size    4M;
    ---
    >     client_max_body_size    10M;
    ```

    <ul>
    <li>/etc/php.ini</li>
    </ul>
    ```bash
    $ diff /etc/php.ini.bak201707281842 /etc/php.ini
    52c52
    < upload_max_filesize = 4M
    ---
    > upload_max_filesize = 10M
    ```
<br>
1. 以下のコマンドを実行し、でサービスを再起動します。

```bash
$ nginx -s stop
$ service httpd stop
$ service nginx stop
$ nginx
$ service httpd start
$ service nginx start
```

# ９９．ハマりポイント

* chef の設定の反映タイミングがよくわからないので、ちょっと調べないといけないかな、と思っています。サーバの再起動時は必ず反映されると思うんですが、それ以外にも反映されたりする気がするんですよね…。ちょっとよくわからないので、どこかで調べて投稿しようかと思っています。

# ＸＸ．まとめ

特に無いです。

ありがとうございました。
Visual Studio CodeでFlowTypeのエラーを表示する

FlowTypeが気になっているので、Visual Studio CodeでFlowの型チェックを表示する方法を調べました。プラグインをインストールすると、Flowのエラーをエラーパネルに表示できます。

1\. [View]→[Command Pallet]でコマンドパレットを開き、「Extensions」と入力して[Extensions : Install Extensions]を矢印カーソルで選び、エンターキーで決定する。

2\. 拡張機能の一覧画面が表示されるので、「flow」と入力し、「Flow Language Support」をクリックする。

3\. [Install]ボタンを押し、インストールする。

4\. [Code]→[Preferences]→[Settings]→[WORKSPACE SETTINGS]をクリックする。[.vscode/settings.json]の編集ができるので、`Flow`が使用できるように設定を次のように書き換える。

```js
{    
  "flow.useNPMPackagedFlow": true,
  "javascript.validate.enable": false 
}
```

  - `flow.useNPMPackagedFlow` ローカルプロジェクト(`プロジェクトフォルダ/node_modules/`)にインストールしているflowを使用するフラグ
  - `javascript.validate.enable` JavaScriptのバリデートをオフにする(JavaScriptの記述とは違うためflowのコードチェックと重複するため）
   

![170707_flow_vscode_preference.png](https://qiita-image-store.s3.amazonaws.com/0/1423/5b922f36-0b5a-a06e-9892-81a0e0696f55.png)


6\. Visual Studio Codeのアプリを一度閉じ、再起動する。

7\. Visual Studioで`.flowconfig`が存在するフォルダをルートにして、フォルダーを開く
私が本当に業務で行った要件定義の作成手順 - 中編

# はじめに

- もともとは新規Webサービスを立ち上げる際に１からつくったもので、業務の中でドキュメントを作成しました。
- 再利用性を求めてフォーマット化しましたので、二次利用に使うなり、勉強資料などに役立てらればとおもいます。
- 今回は前編、中編、後編の３部で記載しておきたいとおもいます。
- [前回](http://qiita.com/neriai/items/817df489008561a25dd1)に続いて、今回は中編となります。

# 前提
- 要件定義を作成する上で、企画書や仕様書など記載する上での前提の資料が必要になってくるかと思います。
- 図を作成する上で、Caccoを利用しております。

# 中編の概要
- UMLの知識が多少必要になってきますが、他者に説明して理解してもらうのは文章より図が一番効果的です。
- UMLガチガチになぞらなくてもよいとおもいます。他者が理解しやすければOK。
- もし、[前編](http://qiita.com/neriai/items/817df489008561a25dd1)で行ったサービスからシステムに落とし込んでいく中で、ちぐはぐな箇所や矛盾を感じ始めたらここで潰していきましょう。

# 目次

1. サービスの目的
2. サービス概要
3. サービスに関連する人物
4. **サービスに関連する人物がサービスにどのように関わっているのか**
5. **サービスの利用フローや業務フロー**
6. **サービスの状態変化**
7. 機能要件
8. 非機能要件

※太字の部分が今回記載することです。

# サービスに関連する人物がサービスにどのように関わっているのか

- UMLを書く上で、いわゆるユースケースと呼ばれるものです。
- これをベースに要求の中で必要な機能が見えてきたりします。
- 人物と書いてありますが、時にはシステム自体もサービスがどのように関わっているのか書いたりもします。

## ユースケース

### 例

![ユースケース図.png](https://qiita-image-store.s3.amazonaws.com/0/90598/55ee508c-14e6-f235-44c1-c57de69e3d2a.png)

# サービスの利用フローや業務フロー

- サービスや各システムのユーザの利用フローや業務フローを記載します。
- 初めはの頃は、具体的なイメージがないため難しいかもしれません。何度もやり直しになるかもしれません。しかしながら、ここは手を抜いてはいけないところとなります。（後々無駄な機能を作ったりしないためにも）
- UMLを書く上で、いわゆるアクティビティと呼ばれるものです。

## 業務フロー

### 例

![業務フロー図.png](https://qiita-image-store.s3.amazonaws.com/0/90598/3815b16f-a3b0-1a23-41c2-35ce88b6aad4.png)

# サービスの状態変化

- ユーザのアクションを起こした際に変化するシステム内のデータの状態変化や、システム内の決められた機能の実行によるデータの状態変化を記載します。

## 状態遷移

### 例

![状態遷移図.png](https://qiita-image-store.s3.amazonaws.com/0/90598/b7129a14-2ac5-f365-1704-30bbabb71abc.png)

# シリーズページリンク
- [私が本当に業務で行った要件定義の作成手順 - 前編](http://qiita.com/neriai/items/817df489008561a25dd1)
- [私が本当に業務で行った要件定義の作成手順 - 中編](http://qiita.com/neriai/items/530d7329404d69921301)
- [私が本当に業務で行った要件定義の作成手順 - 後編](http://qiita.com/neriai/items/7ebfa50736fd7c075931)
簡易バックアップスクリプト

定期バックアップ用スクリプトをちゃちゃっと書いた。
荒いけど、まぁ個人用なのでこんなもんで。

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

NUM=4
DATE=`date +%Y%m%d`

cd /backup

[ -d ${DATE} ] && exit 1
mkdir ${DATE}

cp -a /etc /home ${DATE} || exit $?

for i in `ls -d [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | sort -nr | sed "1,${NUM}d"`; do
    rm -r $i
done
```
Selenium WebDriverでHTTP refererを設定する方法をご教授下さい。

Selenium WebDriverでHTTP refererを設定する方法をご教授下さい。
chromeを使用しています。

■やりたい事
http://referer.com/ → http://target.com/

■実装イメージ
options->AddArgument("--referer=http://referer.com/");
driver->Navigate()->GoToUrl("http://target.com/");

■環境
Win7 64bit
visual studio
Chrome driver
RoR SQLインジェクションについて

#始めに
Sequelを使ったクエリ発行でSQLインジェクションが発生しないか確認してみました

#環境
Jruby 9.12
Oracle12C
Rails 4.2.9

#確認したこと

##入力文字列
正しくエスケープ処理されないとSQLインジェクションが起こる文字列をブラウザで入力し、サーバー側に送り込んでみる

![image.png](https://qiita-image-store.s3.amazonaws.com/0/136860/80c2b6ce-7040-0509-b414-2a46b286518e.png)

##発行されたSQLをV$SQLから取得する

![image.png](https://qiita-image-store.s3.amazonaws.com/0/136860/97de1f21-dddb-c892-96e1-9286bcbd5a38.png)

V$SQLで発行されたSQLを確認すると、" ' "がエスケープされていて、ブラウザからの入力が文字列として扱われている

#終わりに
Rails側かSequel側のどちらかは分かりませんが、SQL発行時に埋め込み文字列に対してエスケープ処理はなされているみたいです
なので、安心して、今後積極的に生SQLを使っていきます
golangでCognito認証（ただしSecure Remote Password(SRP)プロトコルではない）

# 参考
http://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/amazon-cognito-user-pools-authentication-flow.html
https://github.com/aws/aws-sdk-go/blob/master/service/cognitoidentityprovider/api.go

# 構成
ユーザ情報：Amazon Cognito ユーザープール
↑
認証機能：Amazon Cognito フェデレーテッドアイデンティティ
↑
golang：github.com/aws/aws-sdk-go/service/cognitoidentityprovider
↑
golang：実装

# version
```
$ go version
go version go1.8 darwin/amd64
```

https://github.com/aws/aws-sdk-go/tree/v1.10.17

# 事前準備
AWS Credentialの設定をしておく

# ライブラリのインストール
```
$ go get -v github.com/aws/aws-sdk-go/aws/session
$ github.com/aws/aws-sdk-go/service/cognitoidentityprovider
```

# ログイン、初期パスワードの変更、ログアウト
```go
package main

import (
	"fmt"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/cognitoidentityprovider"
)

func main() {
	username := "USERNAME"
	password := "PASSWORD"
	clientId := "CLIENTID" // ユーザープールの管理画面で確認
	userPoolId := "ap-northeast-1_USERPOOLID" // ユーザープールの管理画面で確認

	svc := cognitoidentityprovider.New(session.New(), &aws.Config{Region: aws.String("ap-northeast-1")})

	// ログイン
	params := &cognitoidentityprovider.AdminInitiateAuthInput{
		AuthFlow: aws.String("ADMIN_NO_SRP_AUTH"),
		AuthParameters: map[string]*string{
			"USERNAME": aws.String(username),
			"PASSWORD": aws.String(password),
		},
		ClientId: aws.String(clientId),
		UserPoolId: aws.String(userPoolId),
	}

	resp, err := svc.AdminInitiateAuth(params)
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	fmt.Println(resp)

	// パスワード変更
	session := resp.Session
	newPassword := "NEWPASSWORD"
	r_params := &cognitoidentityprovider.AdminRespondToAuthChallengeInput{
		ChallengeName: aws.String("NEW_PASSWORD_REQUIRED"),
		ChallengeResponses: map[string]*string{
			"NEW_PASSWORD": aws.String(newPassword),
			"USERNAME": aws.String(username),
		},
		ClientId: aws.String(clientId),
		Session: session,
		UserPoolId: aws.String(userPoolId), 
	}

	r_resp, err := svc.AdminRespondToAuthChallenge(r_params)
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	// ログアウト by AccessToken
	o_params := &cognitoidentityprovider.GlobalSignOutInput{
		AccessToken: aws.String(*resp.AuthenticationResult.AccessToken),
	}
	o_resp, err := svc.GlobalSignOut(o_params)
	if err != nil {
		fmt.Println(err.Error())
		return
	}
}
```
私が本当に業務で行った要件定義の作成手順 - 前編

# はじめに

- もともとは新規Webサービスを立ち上げる際に１からつくったもので、業務の中でドキュメントを作成しました。
- 再利用性を求めてフォーマット化しましたので、二次利用に使うなり、勉強資料などに役立てらればとおもいます。
- 今回は前編、中編、後編の３部で記載しておきたいとおもいます。
- 今回は、前編となります。

# 前提

- 要件定義を作成する上で、企画書や仕様書など記載する上での前提の資料が必要になってくるかと思います。
- 図を作成する上で、[Cacco](https://cacoo.com/)を利用しております。

# 前編の概要

- 要件定義をドキュメント化する最大の目的は、サービスやシステム概要を記載することも大事ですが、「なぜシステムを作るのか、なぜサービスを作るのか、サービスを作ると本当に利益があげられるのか」などを明確にしておくことです。
- なぜなら、もしサービスを作っていく上で息詰まったり、サービスとは関係なさそうな要求がきたりなどした場合に、全員で原点に戻って見つめ直すためです。
- サービスは個人の欲求のみで作ることはないと思うので、本当にサービスが成功するのかといった視点で「そもそも」な疑問点を洗い出しておきましょう。

# 目次

1. **サービスの目的**
2. **サービス概要**
3. **サービスに関連する人物**
4. サービスに関連する人物がサービスにどのように関わっているのか
5. サービスの利用フローや業務フロー
6. サービスの状態変化
7. 機能要件
8. 非機能要件

※太字の部分が今回記載することです。

# サービスの目的

- サービスの目的とは、サービスを立ち上げる上でどのような背景や戦略の元システム化しなければならないのかを簡潔に書きます。
- 文章表現では理解しづらい部分を踏まえて、マインドマップのような図にしてみましょう。

## 要件定義ツリー

- 要件定義ツリーは、主に戦略的要求、業務的要求、システム的要求、情報的要求の４種類に分けています。
- 下記の例では上記の種類毎に分割してますが、実際には[戦略的要求] -> [業務的要求] -> [システム的要求] -> [データ的要求]までがすべてつながっている状態のものを作成してください。
- 下記の例では、今回文字列として記載してますが、実際には[Cacco](https://cacoo.com/)を使って作成しました。

### 戦略的要求

戦略的要求とは、サービスを立ち上げるまでの背景や目的を記載します。

#### 例

```
[現在の事業売上が頭打ちである] -> [業種を広げれば200兆円市場である] -> [競合が存在しないのでサービス化]
```

### 業務的要求

業務的要求とは、サービスのウリとなる部分に、背景や理由を記載します。

#### 例

```
[収益に即時反映される] -> [来客成果を見える化する] -> [手数料モデルにする]

[◯◯をテーマとしたサービス] -> [新サービスなのでブランド力を上げたい] -> [ユーザにサービス価値の根付かせる] -> [豊富な情報を提供する]
```

### システム的要求

システム的要求とは、業務的要求をどのようにシステム化するのかを記載します。

#### 例

```
[商品の予約をする] -> [予約時に手数料が発生する] -> [手数料を売上に計上する]

[商品を検索する]

[商品を入力する]
```

### データ的要求

データ的要求とは、システム化した部分にどのような情報が必要化を記載します。

#### 例

```
[商品情報]

[予約情報]

[売上情報]
```

# サービスの概要

- サービス全体の概要を記載します。
- 文章表現では理解しづらい部分を踏まえて、ツリーのような図にしてみましょう。
- 人物、用途、サービス、システムこれらが１枚の図になっているようなイメージです。
- 人物、用途、サービス、システムなどの名称は、サービス内での統一言語として作成しましょう。

## 概要図

### 例

![サービス概要図.png](https://qiita-image-store.s3.amazonaws.com/0/90598/844bc381-ae6f-ed72-d59e-99ce8066b3ad.png)

# サービスに関連する人物

- UMLを書く上で、いわゆるアクターと呼ばれるものです。
- サービスへどのように関わっている人物がいるかをグループ化します。
- また、グループ化した中で細かいカテゴライズが行える場合は、より登場人物を明確化します。
- それぞれの人物やグループをどのように呼称するかは、いわゆる用語を決める役割も果たします。

## サービスに関連する登場人物と役割

### 例

![アクター図.png](https://qiita-image-store.s3.amazonaws.com/0/90598/57b83db2-2e58-85a3-fa24-7dfe7fc6b1f6.png)

# シリーズページリンク
- [私が本当に業務で行った要件定義の作成手順 - 前編](http://qiita.com/neriai/items/817df489008561a25dd1)
- [私が本当に業務で行った要件定義の作成手順 - 中編](http://qiita.com/neriai/items/530d7329404d69921301)
- [私が本当に業務で行った要件定義の作成手順 - 後編](http://qiita.com/neriai/items/7ebfa50736fd7c075931)
AnsibleでWordpress操作　①wp-cliインストール編

# AnsibleでWordpress操作シリーズ
1. wp-cliインストール編
2. [初期構築編](http://qiita.com/bakira/items/06058ef2abb621e10a98)

# 関連記事

[wp-cli　コマンド一覧(随時追記)](http://qiita.com/bakira/items/fac5a3c552b0f656e2f9)

# やりたかったこと

- Wordpressの環境構築構築
- Wordpressの初期設定
- 出来る限りのWordpress設定をコマンドで行いたい
- ~~GUIを使わずに黒い画面でコマンドを「**ッターーン!**」してかっこつけたい~~

# やったこと

## 前提

- CIサーバー(`ansible`実行サーバー)構築済み
- CMSサーバー(`wp-cli`実行サーバー)構築済み
- `Ansible`インストール済み
- `MySQL`インストール済み
- `Apache`インストール済み
- `PHP`インストール済み
- 各サーバーへのSSH接続設定済み

※ `${~}`は各環境に合わせて値を設定してください。

## 作業フロー

1. wp-cliのインストール

```bash:command
ansible-playbook -i inventory/production install-wp-cli.yml
```


## ディレクトリ構成
```text

├── ansible.cfg
├── install-wp-cli.yml
├── inventory
│   └── production
│       └── inventory
├── roles
│   └── install-wp-cli
│       └── tasks
│           └── main.yml
└── vars
    └── all.yml
```

## Ansible構成ファイル

### inventory

```ini:inventory/production/inventory
[ciservers]
${CIサーバーホスト}

[cmsservers]
${CMSサーバーホスト}

[all:vars]
ENV=production

```

### vars

```yaml:vars/all.yml
GET_URL_TEMP_DIRECTORY: /tmp

WORDPRESS:
  CLI:
    PHAR_URL: https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
    PHAR_NAME: wp_cli
    COMMAND_NAME: wp
    SSH_DIRECTORY_NAME: .wp-cli
```


### playbook

```yaml:install-wp-cli.yml
- hosts: cmsservers
  roles:
    - install-wp-cli
  vars_files:
    - vars/all.yml
```

### tasks

```yaml:role/install-wp-cli/tasks/main.yml
- name: Get wp-cli
  get_url:
    url: "{{ WORDPRESS.CLI.PHAR_URL }}"
    dest: "{{ GET_URL_TEMP_DIRECTORY }}/{{ WORDPRESS.CLI.PHAR_NAME }}"
    mode: 0755

- name: Move wp-cli
  shell: "mv {{ GET_URL_TEMP_DIRECTORY }}/{{ WORDPRESS.CLI.PHAR_NAME }} /usr/local/bin/{{ WORDPRESS.CLI.COMMAND_NAME }}"
  
- name: Create Symlink
  file: 
    src: /usr/local/bin/{{ WORDPRESS.CLI.COMMAND_NAME }}
    dest: /usr/bin/{{ WORDPRESS.CLI.COMMAND_NAME }}
    owner: root 
    group: root
    state: link
```


これでCMSサーバー上で

```bash:command
wp help
```

と打つことでhelpが表示されます。

## 終わりに

これでwp-cliを使える環境が整いました。

次は、実際にwordpressの初期構築部分をwp-cliで行っていこうと思います。

じゃあの。
Azure WebJobs で PowerShell から日本語での標準出力を文字化けさせない関数


```
function Write-OutputByNativeEnc($message) {

	# UTF-8 としてバイト配列化し、コンソールのネイティブなエンコードに変換
	[Console]::OutputEncoding.GetString([Text.Encoding]::UTF8.GetBytes($message))

}
```
*※ ps1 ファイルが UTF-8 の場合*


C#アプリの場合は `Console.OutputEncoding = System.Text.Encoding.UTF8;` をおまじないすると、以後は `Console.Write{Line}();` で文字化けせず。

*.bat, *.cmd の `echo` と、 *.js(node) の `console.log();` は、そもそも文字化けせず。
[PHP]POSTした値が全て取得できない

#現象
Laravelで1000件以上のPOSTをしたところ、途中で値がなくなってしまっていた。
フォーム画面では500レコード表示されているのに、POSTしたデータは250件ほどしかない、といった具合だ。
Laravel側の設定かと思いきや、PHPの設定の問題とのこと。

#原因
phpinfo()から設定を確認してみる。
![001.png](https://qiita-image-store.s3.amazonaws.com/0/165355/4353dd59-9e29-b432-abb5-286fa7bbd400.png)

``max_input_vars``の項目が最大POST数とのことで、今回は4カラムをPOSTしていたため、1000/4=250レコードしかPOSTできていなかった。
この値を書き換えることでより多くの値をPOST出来るようになる。

#Laravel側の対応
１．``/etc/php/7.1/fpm``内に``php.ini``ファイルがあるので、ルート権限で編集する（``sudo vim /etc/php/7.1/fpm/php.ini``）。

```ini:/etc/php/7.1/fpm/php.ini
; max_input_vars = 1000
; コメントを外して任意の値に書き換える
max_input_vars = 10000
```

２．反映させるために一度``vagrant provision``コマンドを実行する。

３．再度phpinfoを確認して反映されていることを確認。

#所感
だからって一度に大量のデータをPOSTするのもちょっとアレな感じではある。
ログイン毎に異名をつけるプロンプト

* [Regalias]
* [letla/regalias: Elona-like alias generator for Python, with CLI.]
* [ローグライクRPG『Elona』の異名生成アルゴリズムを Python で実装、オープンソースの異名ジェネレータ『Regalias（レガリアス）』として GitHub で公開しました - Qiita]


Python2系で無理やり使う。

# インストール

```sh
curl -kL https://bootstrap.pypa.io/get-pip.py | python
pip install regalias
# Python2対応 更新に注意
sed -i -E "s/      allow_abbrev=False\)  # yapf: disable/      \)/" /usr/lib/python2.7/site-packages/regalias/__main__.py
```

[16.4. argparse — コマンドラインオプション、引数、サブコマンドのパーサー — Python 3.6.1 ドキュメント]

>バージョン 3.5 で変更: allow_abbrev 引数が追加されました。

2.7ではないので削除してやることで動く。
無理やり動かした副作用として、引数(名前)を渡した異名の固定生成時に返り値がUnicode文字列のままなので残念。

# プロンプト

```sh
function fish_right_prompt
    if [ $status -eq 0 ]
        set_color magenta
        echo "(ﾟーﾟ*)  "
    else
        set_color blue
        echo "(＝ω＝.) "
    end
    if not set -q __fish_prompt_regalias
        # グローバルにしないと毎回変わるよ
        set -g __fish_prompt_regalias (regalias)
    end
    set_color cyan
    echo "$__fish_prompt_regalias"
    set_color yellow
    echo -n $USER
    set_color normal
    echo -n '@'
    set_color red
    hostname
end
```

右プロンプトを最近知って遊んでいるが、何を入れれば便利かよくわからない。

![penctions.gif](https://qiita-image-store.s3.amazonaws.com/0/62354/4df1440c-c6eb-9741-0e07-5011aa4a0117.gif)

お遊び要素といっぱい開いた時の識別にでも。


[Regalias]:http://ylvania.org/jp/letlafox
[letla/regalias: Elona-like alias generator for Python, with CLI.]:https://github.com/letla/regalias
[ローグライクRPG『Elona』の異名生成アルゴリズムを Python で実装、オープンソースの異名ジェネレータ『Regalias（レガリアス）』として GitHub で公開しました - Qiita]:http://qiita.com/letla/items/6d4de12332dc0ccec1fe
[16.4. argparse — コマンドラインオプション、引数、サブコマンドのパーサー — Python 3.6.1 ドキュメント]:https://docs.python.jp/3/library/argparse.html#argumentparser-objects
GO Template Engineでhtmlをエスケープしないで表示する

`string`または`[]byte`を`template.HTML`に変換することによって、GO Template Engine側でhtmlのエスケープ処理が走らなくなる。

Revelで使用する際のサンプル

```go:app.go
func (c *revel.Controller) Show() revel.Result {
	escape_html := "<h1>Hello World</h1>"
	raw_html    := template.HTML(escape_html)
	return c.Render(escape_html, raw_html)
}
```

```html:show.html
{{escape_html}}  <!-- &lt;h1&gt;Hello World&lt;/h1&gt; -->
{{raw_html}}     <!-- <h1>Hello World</h1> -->
```
【Java】privateによるフィールドのアクセス制限はオブジェクト単位ではなくクラス単位

Javaの仕様の話。


Javaのドキュメントには、下記のように書いてある。

```
The private modifier specifies that the member can only be accessed in its own class.
```
https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

つまり、同じクラスに属する異なるオブジェクトからはアクセスできる。（勘違いしがちな部分）

### 例１

引数に同じクラスのオブジェクトを受け取ることで、そのprivateフィールドを直接操作することができる。(getter, setterは不要)

```java
public class Foo {
    private int num;

    public void setNumToAnotherFoo(Foo foo, int num) {
        foo.num = num;
    }
}
```

### 例２

フィールドに同じクラスのオブジェクトをもつとき、そのprivateフィールドは直接操作することができる。

```java

public class Bar {
    private Bar barField;
    private int num;

    public void setBarFieldNum(int num) {
        barField.num = num;
    }
}
```

## 参考文献
 * ケン・アーノルド、ジェームズ・ゴスリン、デビッド・ホームズ（2014）『プログラミング言語Java　第4版』柴田芳樹訳、東京電機大学出版局
    * 2.6.6 アクセス制御のためのメソッド使用
Lubuntu16のテーマをClearlooksに変更する

Lubuntuではルック＆フィールの設定ツール（Preferences -> Customize Look and Feel）でテーマを簡単に変更できます。Lubuntuのインストール直後は「Lubuntu-default」のテーマが選択されているのですが、それを「Clearlooks」に変更した時のメモです。

## そんなのテーマ変えるだけじゃないの？
実は私も「そんなのPreferences -> Customize Look and Feelで「Clearlooks」を選ぶだけじゃん！」と思っていたのですが、現実は甘かったんです。

実際に試してみると分かります。

「Clearlooks」のテーマを選択した直後は気づかないのですが、しばらく使い続けると「Clearlooks」のテーマにならないアプリがある事に気づくと思います。例えば「Firefox」や「Synapticパッケージマネージャー」「Evince（ドキュメントビュワー）」あたりがそうです。

私も詳しいことは分からないのですが、GTK2とGTK3というのがあって「Clearlooks」のテーマにはGTK3の情報が含まれていないため、GTK2のアプリは「Clearlooks」になるものの、そうでないGTK3のアプリはデフォルトのテーマ（「Lubuntu-default」に似ていますが少し違う）が採用されてしまい、2つのテーマが混じった状態になってしまうようです。

## Clearlooksのいいころ
なんでそこまでしてClearlooksにこだわるのか？その理由は大きく３つです。１）スクロールバーに上下ボタンがついている、２）スクロールバーが細くなったりしない、３）見慣れていて心が落ち着く、です。

もちろんどんなテーマでも設定ファイルをいじればスクロールバーの上下ボタンを表示させたり、スクロールバーが細くならないようにすることは可能なんですが、そんな事をしなくてもいい所が「Clearlooks」のいいところかなと思います。

## 実はそれほど難しくなかった
当初はGTK3用のClearlooksテーマを自分で作ろうとがんばって思考錯誤していたのですが、そんな事はしなくても既に「Clearlooks-Phénix」という名前で作っている方がいる事を知ったため、今回はそれを使う方法を紹介したいと思います。

## Let's GO!
まずはClearlooks-Phénixのサイトにアクセスします。URLは https://github.com/jpfleury/clearlooks-phenix です。

v1からv7まであるので、自分の環境に適したものをダウンロードします。私の場合はv7では思った通りの結果にならなかったのでv6を使用しています。

ダウンロードしたファイルを解凍します。

```console:解凍
$ unzip clearlooks-phenix-6.zip
```

インストールします。インストールと言ってもコピーするだけです。

```console:インストール
$ sudo cp -rf clearlooks-phenix-6 /usr/share/theme/Clearlooks-Phenix
```

Preferences -> Customize Look and Feel で「Clearlooks-Phenix」を選択します。

終わりです。

## 実はもっと簡単だった！
この記事を書いている途中でUbuntuのパッケージの中に「clearlooks-phenix-theme」というパッケージがある事を発見しました。以下のようにしてインストールするだけで「Clearlooks-Phenix」のテーマをインストールできるようです。なんてこった。

```console:clearlooks-phenix-themeのインストール
$ sudo apt-get install clearlooks-phenix-theme
```

## （おまけ）UIの確認方法
テーマによるUIを確認する方法ですが「awf」というツールを使うと確認しやすいです。

```console:awfのインストール
sudo apt-add-repository ppa:flexiondotorg/awf
sudo apt-get update
sudo apt-get install awf
```

インストールが終わると「awf-gtk2」と「awf-gtk3」というコマンドが使えるようになります。実行するとUIを確認することができます。

## やっぱりClearlooksが好き！
使ってみるとやっぱりClearlooks素敵です！Clearlooksが使えるようになったことでLubuntuも好きになりそうです。

めでたしめでたし。
日本語版WordPressコンテナ内からメールを送信する

# 大前提
出来るだけ楽してWordpressコンテナを作成して行きたい。＝ Dockerfileを1から書くのは苦痛なので公開されているものをなんとかして使いたい。

# 目的
[bakudankun/wordpress-ja](https://github.com/Bakudankun/wordpress-ja)を使用してWordpressコンテナを立ち上げたが、パスワードリセットが出来ない(mail()が動かない)のでなんとかする。
日本語情報が全然なかったのでメモにする。

# 参考
[githubのissue](https://github.com/docker-library/php/issues/135)
[日本語版WordPressのテーマ開発環境をサクっと立ち上げるdocker-compose.yml](http://qiita.com/y_hokkey/items/bbd213cc3e18026fe169)を参考にコンテナを立ち上げているのでdocker-compose.ymlについてはそちらを参照してください。

# メール用設定変更シェルを作成する
```shell-session:mail_config.sh
#!/bin/sh
host=$(hostname)
line=$(cat /etc/hosts |grep [1]27.0.0.1)
echo "$line localhost localhost.localdomain $host" >> /etc/hosts
#sed -i -e "s/$line/$line noreply@yourdomain.com $host/g" /etc/hosts
echo "$host" >> /etc/mail/relay-domains
m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
sendmail -bd
```

# 追加のphp.iniを作成する
```ini:sendmail.ini
sendmail_path = /usr/sbin/sendmail -t -i
```

# Dockerfileの作成

```ruby:Dockerfile
FROM bakudankun/wordpress-ja:latest

# 必要なツール郡をインストール
RUN apt-get update \
    && apt-get upgrade -y sendmail \
    && rm -rf /var/lib/apt/lists/*

# コンテナからメール送れるように
COPY ./mail_config.sh /var/www
COPY ./sendmail.ini /usr/local/etc/php/conf.d/
RUN chmod +x /var/www/mail_config.sh

# CMDでmail_config.sh実行する
CMD /var/www/mail_config.sh && apache2-foreground
```

# docker-compose.ymlの修正
```yaml:docker-compose.yml
# image: bakudankun/wordpress-ja:4.5.2-apacheの部分を修正する
wp:
  # Dockerfileを作成した場所を指定する。
  build: .
  links:
    - mysql:mysql
  ports:
    - "80:80"
  volumes:
    - "${PWD}/wp-content/:/var/www/html/wp-content"
  environment:
    # wp-configのデバッグ機能を有効化
    - WORDPRESS_DEBUG: "true"
```

# おわりに
上記のファイル群を作成することでコンテナ内からメールを送ることができるようになった。
ググって全然日本語情報出ないの辛いですよー本当にー。
Stackdriverを使ってみた


## 概要
AppEngineの特定ログを検知し、Stackdriverを用いてメール送信する

## 対象
Stackdriverを使ったことがない人向け。

## 前提条件
Stackdriverアカウントの設定が完了していること

## 対応内容

1. GCPコンソールメニューの「ロギング」から検知したいログを検索する。
2. 「指標を作成」ボタンを押し、指標を作成する。
3. 「ログベースの指標」画面を表示し、2で作成した指標のメニューボタンを押す。メニュー内の「指標に基づいて通知を作成する」を選択する。
4. Stackdriverの画面が表示されるので、閾値の設定を行う。ログの検知をするだけであれば、以下の設定を行えばほぼ問題ない。私はいつもTHRESHOLD->「0.01」、FOR->「most recent value」の設定で使うことが多いです。こうすることで特定のログを検知した時にすぐエラーとして検知できます。
  - THRESHOLD・・・閾値。設定した値を超えた場合、通知される。
  - FOR・・・何分継続して閾値を超えた場合、通知を行うか設定する。
5. 最後にメールアドレスの設定を行う。
Bash on Windowsで真面目に開発環境を整備する

# 序章

皆さん、アプリケーション開発マシンのOSは何をお使いでしょうか？
想像ですが、Windowsアプリ開発でない限り恐らくMacが最も優勢であろうと思います。

私は一時期頑なにWindowsで頑張っていました。
しかし今作っているサービスで使うライブラリや周辺ツールがどうしてもWindowsでは正しく動かず、かといってMacを調達するのも色々辛く、ググりまくるのに疲れたこともあり遂にギブアップ。

Windowsの入ったSSDを窓から投げ捨て、今は平穏にCentOS+KDEで開発をしています。
なぜUbuntuじゃないのかといえば単に慣れていたのと、Desktop用途といえばUbuntuみたいな流れに反抗してみたかったという単なる自己満足です。
更に蛇足としては、SUSEとかGentooみたいなOSも触ってみたくはありましたがあまり趣味に走りすぎるとそれはそれでトラブルの元であり、仕事に支障を来たしては元も子もないためある程度は妥協したのです。
Officeなんかは月に1度、主に月末の事務手続き系くらいにしか使わないのでその時だけ古いWindowsマシンを引っ張り出してきてチャチャっとやっつけることにしました。

閑話休題。

さて昨年からBash on WindowsがBetaテストを開始していたのは皆様ご存知かと思いますが、つい先日この秋から正式版になることが発表されました。
これによりWindowsでもLinuxネイティブのバイナリーをBash上で動かすことが可能になり、私が七転八倒したWindows機での開発がいよいよ現実的なものになりました。

家が建つような大金を積んでZenBook3(512GP)を購入したこともあり、Windowsで真面目に開発環境を構築した際に困ったポイントとその解決法をナレッジとしてここに共有させて頂くことで、迷える窓を救う一助になれればと思います。

# テキストエディターをどうやって動かすか

「え、そんなの単純にWindowsでエディターを起動して`AppData\lxss`配下をちょいちょいのパッパッといじればいいんじゃないの？」と思った貴方、ヤバいです。
まず大事な基礎知識として、Bash on Windows内部のファイルをWindowsから編集するとファイルが **あぼーん** してしまいます。

[詳細はこちらを参照のこと](https://www.kaitoy.xyz/2016/11/19/bow-do-not-change-linux-files-from-windows/)

この問題があるため、迂闊にBash側ファイルを触るわけにはいかないのです。
そしてBash on WindowsにはGUI環境がありません。
なのでAtom等を起動することができないため、何とかしてこれを回避する必要があります。
（GUIが要らないテキストエディターをお使いの方は特に問題ありません）

## やや強引にでも動かすには

エディターがちゃんと動くのならばX11 Server系のアプリで何とかするのが手っ取り早いと思います。
MobaXtermなんかが色々便利で手っ取り早いのでおススメです。

[MobaXtermの紹介はこちらの記事を参照](http://qiita.com/mkasahara/items/c029154b5436913b20e0)

でも全部が全部動くというわけでもないようで、実際のところ私の環境でAtomはなぜかKernelPanicを起こしてしまい起動できませんでした。
xeyesあたりはちゃんと動くからイケると思ったんだけどなぁ……。

# ファイル破壊問題の回避

Bash on WindowsではWindows側のドライブを`/mnt/c`といった形でマウントしています。
そしてこの中身はちゃんと配慮されているようで、どちらから触っても壊れることはありません。
なのでWindowsアプリケーションから触りたいファイルだけここに配置します。

## /mnt配下に移動するのは面倒、違和感を何とかしたい

安全策で行くのならばそれ用のディレクトリを作った上で`/home/username`に`/mnt/c/Users/username/BoW`という具合にエイリアスを張るのがよいでしょう。
（BoWディレクトリは他の場所や名前でも大丈夫）

私はちょっと思い切ってWindows側で`/etc/passwd`のホームディレクトリを`/mnt/c/Users/username/BoW`配下に変更してしまいました。
こんな感じです。

```/etc/passwd
username:x:1000:1000:"",,,:/mnt/c/Users/username/BoW:/bin/bash
```

## パーミッションが全部777になっている

仕様ですので諦めるしかないです。
Gitを使う場合パーミッションが全部変わって惨事が起こる可能性があるため、パーミッション変更を無視するように設定しておきましょう。

```bash
$ git config --global core.filemode false
```

## .sshの鍵が読めない

パーミッションを400とかにしておかないとsshコマンドで怒られるアレですが、ホームを`/mnt/c`配下にした場合は777固定になってしまうためそのままでは直しようがありません。
`/mnt/c`配下以外のどこか適当な場所に置き直すことで妥協しました。

## Atomで目的のディレクトリを開くのがめんどい

Bash側からWindowsのファイルを実行することができるので以下のエイリアスを張ります。
ちゃんと引数も受け取ってくれるのでBash on Windows側のディレクトリを指定して開けます（勿論`/mnt/c`配下のみ）。

```bash
$ alias atom='cmd.exe /c "C:\Users\username\AppData\Local\atom\bin\atom.cmd"'
```

ちなみに`/mnt/c`以外の場所（例えば`/etc/`とか）で起動しようとすると正しく開けずWindows側のデスクトップに飛ばされます。

```bash
$ cd /etc
$ atom .
現在の作業ディレクトリを変換できません。C:\Users\username\Desktop を使用します
```

# まとめ

* WindowsからBash on Windowsのファイルを直接操作するのは厳禁
* Windowsから編集したいファイルは`/mnt/c`配下に配置する
    * アクセスがめんどい場合はエイリアスやホームディレクトリ変更で何とかする
* GUIでしか動かないLinuxアプリはX Serverでなんとかできるかも
hidesBottomBarWhenPushed=trueした後に遷移すると一瞬余白がでてしまう問題

# 問題
tabbarを消して画面遷移したいとき、以下のように書くことがある

```swift
viewController.hidesBottomBarWhenPushed = true
show(viewController, sender: self)
```

この方法で遷移すると、遷移中に一瞬tabbar分の高さの余白が見えてしまうことがある。

# 解決方法
結論から言うと、遷移先の画面のautolayoutの設定の問題の可能性が高い。

## 問題が発生する制約
下の制約に、 `Vertical Spacing to Bottom Layout Guide` を使用していた。
<img width="431" alt="スクリーンショット 2017-07-31 2.22.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/111677/0423b9b3-e0a1-aa14-6dac-92a3826ab015.png">

## 問題が発生しない制約
上の画像に表示されているポップアップが出ている状態で、`Alt`を押し続けると `Bottom Space to Container Margin` という選択肢が現れるので、それを使用する。

# 参考
[constrain view.bottom to superview.bottom not bottomLayoutGuide in storyboard](https://stackoverflow.com/questions/29021129/constrain-view-bottom-to-superview-bottom-not-bottomlayoutguide-in-storyboard/33432500#33432500)
Jenkinsビルド設定 for Android

# はじめに
Githubで管理しているAndroidプロジェクトをJenkinsで自動ビルドしてDeployGateにアップロードしてみようの巻

[こちら](http://qiita.com/yutaka_izumaru/items/c1e28ed416af5eee3ac3)でJenkinsのインストールが完了していることが前提。

# 新規ジョブの作成
<img width="834" alt="a.png" src="https://qiita-image-store.s3.amazonaws.com/0/188928/524dde48-c7ff-5847-a3c5-b3e82bd4fcc0.png">
「新規ジョブ作成」を選択。

<img width="808" alt="スクリーンショット 2017-07-31 0.48.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/188928/f01a8a63-28e6-582c-2aa3-53854a005430.png">
任意の名前を入力し、「フリースタイル・プロジェクトのビルド」を選択して、「OK」

# 設定詳細
デフォルト設定からいじるところは以下。設定項目はお好みで。

### General
プロジェクト名：任意
古いビルドの破棄：チェックオン
　　ビルドの保存日数：任意
　　ビルドの保存最大数：任意
ビルドを並行実行：チェックオン

### ソースコード管理
Gitを選択
リポジトリURL：対象リポジトリのURL
認証情報：追加を選択。ダイアログからGithubのユーザー名/パスワードを入力して、選択。
ビルドするブランチ：任意

### ビルド・トリガ
SCMをポーリング：チェックオン
　スケジュール：crontabと同じ書式やで。ここでは「H/15 * * * *」としました。これで15分毎に実行されます。

### ビルド環境
コンソール出力にタイムスタンプを追加する：チェックオン

### ビルド
ビルド手順の追加→シェルの実行でシェルスクリプトに以下を。
今回はプロジェクト直下にgradlewがある想定ですが、パスは環境に応じて変えてくださいねー。

```bash
./gradlew build
```

### ビルド後の処理
・成果物の保存
　ビルド後の処理の追加→成果物を保存を選択
　保存するファイル：**/app-debug.apk
　高度な設定
　　ビルドが成功した場合のみ保存：チェックオン

・Upload to DeployGate
　ビルド後の処理の追加→Upload to DeployGateを選択し、API KeyとUsernameを入力。

最後のApplyして保存して終了でございます。
あとはビルドすればおk。

# 番外編
初回ビルド時に以下のエラーが出ることがあります。

```
You have not accepted the license agreements of the following SDK components:
[ConstraintLayout for Android 1.0.2, Solver for ConstraintLayout 1.0.2].
Before building your project, you need to accept the license agreements and complete the installation of the missing components using the Android Studio SDK Manager.
```

おもむろに以下を実行しておきましょう。
それでもだめだったらAndroid Studioからがんばりましょう。

```bash
$ mkdir "$ANDROID_HOME/licenses" || true
$ echo -e "\n8933bad161af4178b1185d1a37fbf41ea5269c55" > "$ANDROID_HOME/licenses/android-sdk-license"
$ echo -e "\n84831b9409646a918e30573bab4c9c91346d8abd" > "$ANDROID_HOME/licenses/android-sdk-preview-license"
```

[株式会社Arrvis](http://www.arrvis.com)
SSE(Server-Sent-Event)のサンプルを docker 上で実行する

https://dzone.com/articles/jax-rs-21-sse-client-api-using-glassfish-5-on-dock

```bash
$ git clone https://github.com/abhirockzz/javaee8-jaxrs-sse-client.git

$ cd javaee8-jaxrs-sse-client
$ mvn clean install
$ docker build -t javaee8-jaxrs-sse-client

# 実行(一度目は例外が発生したが、再度実行したら成功した)
$ docker run --rm --name javaee8-jaxrs-sse-client -it -p 8080:8080 javaee8-jaxrs-sse-client
```
docker の mongodb イメージを導入して spring-boot から接続する


https://www.javacodegeeks.com/2017/07/spring-boot-justice-league.html

```bash
# mongodb の image をダウンロード
$ docker pull mongo

# mondodb を起動
$ docker run -p 27017:27017 -d mongo

# spring-boot のサンプルをクローン
$ git clone https://github.com/dinukadev/justiceleague_management_system/tree/master/src/main/java/com/justiceleague/justiceleaguemodule

$ cd justiceleaguemodule

# ビルド
$ mvn clean install

# 実行
$ java -jar target/justiceleaguemodule-0.0.1-SNAPSHOT.jar

# API確認
$ curl -H "Content-Type: application/json" -X POST -d '{"name":"Hatimiti","superPower":"super speed","location":"Central City"}' http://localhost:8080/justiceleague/addMember

```

## 参考
* https://hub.docker.com/_/mongo/
Heroku で ポート指定しないタイプの Node.js アプリをデプロイする時につまづいたこと

# 状況
- 去年とあるきっかけで Amazon EC2 でインスタンスを立てた
- 放っておくのももったいないしなと思い、半年前に Twitter bot を作った
 - RSS フィードやスクレイピングで更新を検知してツイートするだけの機能
 - Express などの Web フレームワークは使っていない
- EC2 の無料枠がそろそろ終わるので Heroku へ移行しようと思った

# つまづいた
Heroku へのデプロイ、起動までは問題なく進んだのですが、その後ログを見ると

```
heroku[web.1]: Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
```

と R10 エラーを吐いて止まっていました。
上の記事にあるように、Heroku ではポート番号を明示的に指定する必要がありますが、自分の作ったアプリで使っている [cheerio-httpcli](https://www.npmjs.com/package/cheerio-httpcli) にも [feedparser](https://www.npmjs.com/package/feedparser) にもポートを指定する機能がありません。

# 解決法
このような場合は **worker プロセスで走らせる**ことで解決できます。

Procfile を作成し、以下の内容を記載。

```text:Procfile
worker: node app.js
```

コンソールで以下のコマンドを実行。
(Heroku Toolbelt がインスコされていることが前提)

```
heroku scale web=0 worker=1
```

自分の場合はこの後何故か「package.json に起動時のコマンドねえぞ」と怒られたので以下の通り修正。

```json:package.json
"scripts": {
    "start": "",
    "test": "echo \"Error: no test specified\" && exit 1"
}
```

これで無事に Heroku 上で Twitter bot を動かすことができました。

# 参考リンク
[Process Types and the Procfile | Heroku Dev Center](https://devcenter.heroku.com/articles/procfile)
[Heroku：(Application Errorにならないための)Node.jsアプリのデプロイ入門 - Qiita](http://qiita.com/oden/items/9341b672917afb43a817)
CloudWatchのデータをAWS CLIで取得する


検索したらrubyスクリプトの例が多かったのでメモ

## やりたいこと

* S3の課金額をシェルスクリプトで取得したい

## 参考資料

* だいたい以下の記事のまんまです
    * [AWSのCloudWatchで取得できるBillingの情報を毎日Slackに通知させて費用を常に把握する](http://blog.kenjiskywalker.org/blog/2015/04/20/aws-cloudwatch-billing-chatops/)
    * [『AWSのCloudWatchで取得できるBillingの情報を毎日Slackに通知させて費用を常に把握する』 x 『AWS CLIの処理をAWS Data Pipelineで自動化する』](http://qiita.com/sawanoboly/items/56d6f191d18d7f207873)


## スクリプト

* Mac向け。他環境の場合はdateコマンド周りを読み替えてください
* 値だけ欲しかったので適当にcutしてます
* jqコマンドはない前提

```bash
aws cloudwatch --region us-east-1 get-metric-statistics \                                                                                           
--namespace 'AWS/Billing' \
--metric-name EstimatedCharges \
--start-time "$(date -v-1d +'%Y-%m-%d 00:00:00')" \
--end-time "$(date +'%Y-%m-%d 00:00:00')" \
--period 86400 \
--statistics 'Sum' \
--dimensions 'Name=Currency,Value=USD' | grep Sum | awk '{print $2}' | cut -d"," -f1
#=> 10.000000000000001 といった感じで表示される

```

## 引っかかったところ

* 「--dimensions」はリファレンス上は非必須だが指定しないと値が取れない模様
[PDCAアプリを作る] ③PDCAアプリのリリース

スマホでPDCAサイクルを実行できるアプリをionicで作成しました。
------------
 
 IOS版:Itunes: https://itunes.apple.com/jp/app/pocketpdca/id1175913707?mt=8

「pocketPDCA」サイト:https://openlist.sakura.ne.jp/cord/
「pocketPDCA」youtube  : https://www.youtube.com/watch?v=IXzjpDS4K7c&t=9s

![cycle_iphone6splus_qiita.png](https://qiita-image-store.s3.amazonaws.com/0/118986/2ae31be1-05a7-bdef-56c8-d1078b2278f5.png)

ionicのスキルをつけ始めたのが早かったため、今更ionic V1でのアプリですが様々なUIや機能を実装しています。
余裕を見てionic現行バージョンにする予定です。まだ出たばかりでV1.0.4が最新です。今後隠し機能系を表にだしてバージョンアップしてゆく予定です。
ハイブリッドですがまずはios版を出しています。android版を現在テスト中です。

PDCAアプリを作成した理由
---
現代にPDCAというのは古くてどうか、PDCAなんて一生回せるか。めんどくさい。というのは直観ですが、スマホのアプリにおいて、これまでtodoリストやカレンダー系のアプリは存在しましたが、本当に本格的なPDCAサイクルを回すためのアプリはありませんでした。無いものは作ってしまおうという理由で作成しました。１つきちっとしたものを作れば他に応用できますし。

ionicで様々なUI,機能を実現しました。
-------------------------------------------------------
■ionic basicなUIほぼ全て＋いろいろな工夫を凝らしてUXを作成。
 ※標準機能＋かなり苦労して望むUXを実現。まだまだ発展途上。

■DB系
主dbとしてはwebsqldbを使用
メニューのフラグ的にlocalstorageを一部に使用

■cordova系 
1.in app purchase(アプリ内課金)
2.tts(音声合成)
3.mail,device,他

■angular系
1.angular translate 多言語化のための翻訳機能を持っています。
2.angular $http  良くあるpost/get data to server 
(アプリからpostし、サーバ側のphpで、mysql にinstall)

■隠し実装（コードはすでに入れているが現バージョン表示していないもの)
●Material UI
●Floating UI (button系)
●cordova push notification(タスクに対してAIコンシェルジュ的な役割を持たせる）
●tts(音系の機能の充実)
●カレンダー表示系


■今後追加予定の機能
●コンシェルジュ的な機能を強化（明日の予定はｘｘｘです。今日はｘｘｘです）としゃべるアプリ。

■今後追加するかもしれない機能
●シェア系・・・PDCAをシェアする。可能であればコンテンツ課金化
しかしコンテンツ作成者に還元する仕組みが無い。(ios11から実装されるとか？)
●web版の機能・・・やっぱりwebと連携していたほうが使いやすいかも。
●AI系・・・PDCAで何をAIできるのか？流行りものですが使い道があれば。


アプリの課金方法
----------
まずはインストール無料で、アプリ内課金で製品版へとアップグレードするスタイルにしました。

qiitaに書いた理由
----
音声コンシェルジュ的な機能をもたせようとしている以外、アプリとして特筆すべき技術的な機能はありませんが、アプリをionicで作成されている方にはぜひ見ていただきたいと思い、アプリについて書きました。

インストールは無料です。ionicで開発されている方、またはハイブリッドに興味がある方、一般のアプリ開発者、ぜひアプリをインストールいただき、サポートやアプリのユーザの声からでも、ご意見をいただければと思います。

よろしくお願いいたします。
[tips]代入演算子とif文　例えばjs 例えばruby


jsで、
xとyが等しいかどうかを条件にするときは以下のようなコードになる。

```js
if(x==y){省略}
```

以下のコードのように書いてもエラーにはならない。
しかし以下のコードは単なる代入式なので、yの値がブーリアンに変換されて真偽がチェックされる。

```js
if(x=y){省略}
```

ちなみに、rubyでも同じようになる。

```rb
x = true
y = false
if x=y then "T" end
#=> nil

x = true
y = false
if y=x then "T" end
#=> T
```

パーフェクトjavascript曰く、
代入演算子で頻発する間違えらしいです:hugging_face:
[メモ]javascriptのbreak、continueで使うラベル

javascript勉強中の修行僧です:innocent:

jsにはfor文やwhile文でラベルというものが使えます。
これを使えば指定のループまでcontinue,breakでジャンプすることができます。

# ラベルを使ってみる
外側のwhile文にouter_loopというラベルを付けます。
ラベルを使えば、入れ子のループを同時に抜けることができます。

```js
outer_loop:
while(true){
  "outer_loop";
  while(true){
    "inner_loop";
    break outer_loop;
  }
}
```

jsにはこんなのがあるんですね:hugging_face:
なんかElmコードは引数書かないほどイケてるっぽい


趣味で[Elm](http://elm-lang.org/)触ってて、よく分かんないけどなんか動くみたいな感じでやってる、関数型素人のダイナミックHTMLコーダーである私目線の内容ですので、あまり深い内容ではないことを予めご了承ください:bow:

さて本題に入りますが、
JSのこんなコードがあるとします

```js
const args = [1, 2]
const func = arg => arg * 2
args.map(func) // [2, 4]
```

これをElmで書くとこうなります

```hs
args = [1, 2]
func arg = arg * 2
List.map func args -- [2, 4]
```

JSでも引数1個の場合は`()`使わなくても関数定義できますが、
Elmだと何個でも`()`使わないですし、関数適用のときも使いません。
じゃあどこまでがその関数の区切りだと判別するんだよ、という話は、
[どうやらElmコードは`()`使わないほどイケてるらしい](http://qiita.com/boiyaa/items/7b4ac2d69ca7508f7f35)をご参照ください。

次にJSでこんな感じで、

```js
const args = [1, 2]
const func1 = arg => arg * 2
const func2 = arg => arg + 2
args.map(arg => func1(func2(arg))) // [6, 8]
```

無名関数使って関数合成するのは、Elmだとこう書けます。

```hs
args = [1, 2]
func1 arg = arg * 2
func2 arg = arg + 2
List.map (\arg -> func1 <| func2 arg) args -- [6, 8]
```

（`<|`については[上記記事](http://qiita.com/boiyaa/items/7b4ac2d69ca7508f7f35)にあります。）
`\`は無名関数の文法です。`func arg = arg`と`func = \arg -> arg`は同じものみたいです。
話戻すと、こうは書けるんですが、熟練のElmersはこう書かないみたいなんですよね。
どうやら関数合成には並々ならぬこだわりがあるようで、それ用のスペシャルな関数が用意されています。

### [(<<)](http://package.elm-lang.org/packages/elm-lang/core/5.1.1/Basics#<<) : (b -> c) -> (a -> b) -> a -> c

よくわからん記号の関数シリーズ。そしてこれも中置関数。なんかたぶん記号で関数定義すると中置できるっぽい。

でこれは、「任意型bを引数にとって任意型cを返す関数」と「任意型aを引数にとって同じ型bを返す関数」と「同じ型a」を引数にとって「同じ型c」を返す関数です。（あんま詳しくないですが型の見方も[上記記事](http://qiita.com/boiyaa/items/7b4ac2d69ca7508f7f35)でちょっと説明してます。）

言っている意味はよくわからないが、とりあえず使ってみると、
`(<<) func1 func2 1`は、`(\arg -> func1 <| func2 arg) 1`になるみたいで、`6`が返ってきます。

これを中置したいんだけど、引数が3つあったらどこに中置すればいいんだろうって感じなんですが、
関数の部分適用ってやつがあるらしくて、この関数でいうと、`b -> c`と`a -> b`の関数だけ渡すと`a -> c`の関数が返ってくるみたい。

つまり`func1 << func2`は`\arg -> func1 <| func2 arg`と同じようです。
さきほどmapに渡した関数と同じ形ですね。なのでこう書けます。

```hs
args = [1, 2]
func1 arg = arg * 2
func2 arg = arg + 2
List.map (func1 << func2) args -- [6, 8]
```

引数消えた！うーむ、不思議。けどなんかシンプルでいいかも。
ちなみにこの引数消せるシリーズは他にもあって、よく見かけるやつを紹介します。


### [(>>)](http://package.elm-lang.org/packages/elm-lang/core/5.1.1/Basics#>>) : (a -> b) -> (b -> c) -> a -> c

逆版。
`List.map (func2 >> func1) args`と書ける。


### [identity](http://package.elm-lang.org/packages/elm-lang/core/5.1.1/Basics#identity) : a -> a

引数をそのまま返していいとき使う。JSで

```js
const args = [1, 2]
args.map(arg => arg) // [1, 2]
```

これはElmだとこうだけど、

```hs
args = [1, 2]
List.map (\arg -> arg) args -- [1, 2]
```

identity使う方が通みたいです。

```hs
args = [1, 2]
List.map identity args -- [1, 2]
```


### [always](http://package.elm-lang.org/packages/elm-lang/core/5.1.1/Basics#always) : a -> b -> a

引数を使わないでいいとき使う。JSで

```js
const args = [1, 2]
args.map(arg => 0) // [0, 0]
```

これはElmだとこうだけど、

```hs
args = [1, 2]
List.map (\arg -> 0) args -- [0, 0]
```

always使う方が通みたいです。

```hs
args = [1, 2]
List.map (always 0) args -- [0, 0]
```


# まとめ

`<<`と`<|`、つまり合成と適用って全然違うみたいですけど、私には何が違うのかよく分からないところに、私の頭脳の限界を感じていますが、
とりあえずモテりゃどうでもいいや。
MySQL 5.7 on CentOS7 で起動時にこける問題

## 起きた問題

MySQL の起動に失敗する

```
$ sudo systemctl start mysqld.service
Job for mysqld.service failed because the control process exited with error code. See "systemctl status mysqld.service" and "journalctl -xe" for details.

$ sudo journalctl -b | tail -n 100 | grep ERROR
# 以下のエラーメッセージがみつかる
# [ERROR] --initialize specified but the data directory has files in it. Aborting.
```

`data` ディレクトリにファイルがあって失敗してることがわかる（本来は空っぽの状態から実行されている必要がある）

## 結論

以下の形で MySQL 起動前に初期化を明示的に行う (`--initialize` は後述の理由で起動に失敗する)

```
mysqld --initialize-insecure
```

## 何が起きてたのか

- MySQL 5.7.6 から従前の `mysqld_install_db` から `mysqld --initialize` に変更された
  - もうひとつのオプションとして `mysqld --initialize-insecure` が存在する
- CentOS7 では systemd を経由し起動前に起動前初期化スクリプト `/usr/bin/mysqld_pre_systemd` を実行する
  - そのスクリプトは `datadir` に `mysql` ディレクトリがない場合 `mysqld --initialize` を直指定して実行するもの
  - `mysql` ディレクトリは `MySQL` 自体の情報を格納する重要なデータベースだからであろう
- `mysqld --initialize` だと証明書関連のファイル `*.pem` が作られてしまうためディレクトリが空の状態にならず起動に失敗する
- つまり起動前に `mysqld --initialize` が実行されてファイルが作られてしまうがために「起きた問題」のエラーが発生した

## 参考資料

- https://dev.mysql.com/doc/mysql-security-excerpt/5.7/en/data-directory-initialization-mysqld.html
  - MySQL のデータディレクトリ初期化に関する公式資料
- https://yoku0825.blogspot.jp/2015/03/mysql-576-mysqlinstalldbmysqld.html
  - 5.7.6 以降の MySQL の初期化の挙動に関する説明の記事
OpenCVのGstreamerバックエンドで高度な動画キャプチャを実現する


# はじめに

OpenCVのキャプチャ機能(VideoCaptureクラス)は対応形式がとても多く、Wifiウェアラブルカメラなどのストリーミングも扱うことができて面白いです。しかし、デコード関連の柔軟性が乏しいところもありもう一つと感じることもあります。
最近になってgstreamerバックエンドを使ってみたところ、非常に便利だったので紹介したいと思います。

2018/05/22追記：インストール方法の関連ライブラリの一覧を追記。その他細かい修正。

# 準備
OpenCVの公式配布バイナリでは、動画の入出力にffmpegバックエンドが使われており、gstreamerバックエンドは有効化されていません。使うには自前でビルドする必要があります。

* **2020/04/19追記：現在Linux向けのOpenVINOに含まれるOpenCVが、gstreamerを含んでおり、ビルドに慣れていない方はこれを使うのが一番良い選択肢だと思います（WindowsとMacについては未確認です）。**

* Ubuntu/Macではgstreamer1.0と関連ライブラリをインストールしてある状態でcmakeを実行すれば、自動的に有効化されます。（ 関連ライブラリ：libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-libav ）

* Windowsでは自動解釈はされないので、少し手を加える必要があります。といってもgstreamer1.0と関連ライブラリをインストールした状態で、cmakeオプションGSTREAMER_DIRを正しく指定すればOKです（ググるとpkg-configを入れてCMakeListにパッチを当てるとか出てくるんですが、調査の結果それは不要で、上記の方法で十分でした）。

# gstreamerについて
基本的な使い方の記事は他にもありますので割愛しますが、まずはgst-launch-1.0コマンドでパイプライン書いて色々試せるぐらいの理解度で大丈夫だと思います。SDKを使いこなすところまでは不要です。OpenCVとの連携においてはcapsフィルター(video/x-raw,...のような部分)を抑えておくと理解しやすいと思います。
なおgstreamer0.10系とgstreamer1.0系でパイプラインの記述方法が違う部分があります。gstreamerとだけ書いてある場合は0.10系の場合があるので、情報収集の際は気をつけましょう。

# 基本形
まずは基本的です。Pythonで書いていますがC++でも同様のコードで使えます。
gst-launch-1.0などと大体同じパイプラインが動きます。最後のsinkエレメントをappsinkとすればOKです。

```py3:gstreamer_display.py
import cv2

cap = cv2.VideoCapture("videotestsrc ! videoconvert ! appsink")

while True:
    ret, img = cap.read()
    if not ret:
        break

    cv2.imshow("",img)
    key = cv2.waitKey(1)
    if key==27: #[esc] key
        break
```

# 便利な使いかたいろいろ

### ネットワークカメラのレイテンシーを制御する

```
"rtspsrc location=rtsp://ip_address/stream latency=0 ! decodebin ! videoconvert ! appsink"
```

素のffmpegにはレイテンシーを制御するようなオプションがあったと思いますが、VideoCaptureクラスからそれらオプションを指定する方法はありません。

gstreamerバックエンドでは上記のようにlatency=0とすることで解決できます。
 
### 画像サイズやフレームレートを制御する

```
"filesrc location=test.mp4 ! decodebin ! videoscale ! video/x-raw,width=320,height=240 ! videorate ! video/x-raw,framerate=1/1 ! appsink"
```

画像認識などでは、画像サイズやフレームレートを落とすことが常套手段ですが、これがリアルタイム処理を行うときに厄介です。とくに正確なフレームレートの制御が案外ややこしく、waitKey()で時間を指定すれば処理時間分だけズレてしまいますし、フレームをスキップするにしても1フレームの処理が33ms以上かかる場合に予測しにくい動きになります。マルチスレッドにすれば解決できますが煩雑です。

gstreamerバックエンドを使えばスマートに解決できます。

### 無駄な色変換を抑制する（OpenCV3.3から）

```
"filesrc location=test.mp4 ! decodebin ! video/x-raw,format=I420 ! appsink"
```

YUVを直接扱いたい場合に有用です。
BGRでキャプチャしてからYUVに変換する場合、デコード直後の色変換も含めると無駄な色変換をしているので、効率化のため直接YUVでキャプチャしたいところです。
appsinkの対応フォーマットは、OpenCV3.2まではBGR,GRAY８,BAYER,JPEGでしたが、OpenCV3.3からはUYVY,YUY2,YVYU,NV12,NV21,YV12,I420,BGR,GRAY8に対応しています。
ドキュメントがないので細かい部分を確認したい場合はソースコードを参照してください：
https://github.com/opencv/opencv/blob/master/modules/videoio/src/cap_gstreamer.cpp
互換性のためフォーマットを明示しない場合はBGR,GRAY8が優先的につかわれるようにしています。画像サイズ・チャンネル数についてはcvtColor関数の実装を参考にして決めています。

### ハードウェアデコーダーを指定する

```
"filesrc location=test.mp4 ! qtdemux ! omxh264dec ! videoconvert ! appsink"
```

これまでの例ではdecodebinに任せていたデコード処理ですが、より細かく書くこともできます。例えばRaspberryPiにおけるomxh264decプラグインを使えば、ハードウェアデコーダーを明示的に利用することができます。

# その他

gstreamerは様々なプラグインの組み合わせで機能を構成できますし、実はVideoWriterクラスにもgstreamerパイプラインを書くことができますので、これも組み合わせるといろいろ面白い使い方ができるのではないでしょうか。
面白い利用例やプラグインがありましたらお気軽にコメントください。
本当はいらない著作権表記

著作権表記について調べたのでメモしておきます。
法律の知識が無い人間が適当にググって調べた程度の内容なので、あまり鵜呑みにしないでください。
あくまで参考程度に。

## 著作権表記の必要性

著作権表記については「万国著作権条約」で規定されています。
著作権に関しては「ベルヌ条約」で規定されています。
万国著作権条約では「著作権を表記すれば守る」と規定されており
ベルヌ条約では「何も書かなくても守る」という規定されています。

日本を含むほとんどの国が両方に加盟しています。
両方加盟している場合はベルヌ条約が優先させるので、著作権表記が無くても著作物は守られます。
つまり、著作権表記は不要！


## それでも著作権表記を残す理由

理由は以下が考えられます。

- 習慣
    - みんな書いてるから
    - 書かないと何かが物足りなくて気持ち悪い
- 著作者が判断できる
    - 裁判で有利になる可能性がある
    - 著作物に関する連絡が容易になる
- 無断使用の抑止
    - 条約を知らない人にも権利で守られていることを主張できる
    - 「善意の侵害者」対策 (※)
- 万国著作権条約のみ加盟している国でも権利を主張できる
    - ただし2015年8月現在、ベルヌ条約に非加盟で万国著作権条約のみ加盟しているのはカンボジアのみ

※ 善意の侵害者
アメリカ合衆国では、著作権があることを知らずに権利を侵害しても法的責任(損害賠償責任)は問われません。
ベルヌ条約で著作権表記が無くても著作権を認める一方で、著作権表記が無い場合の「善意の侵害者」も認めているためです。
著作権表記があった場合は、この「善意の侵害者」は認められません。


## 表記ルール

一般的には以下のように表記されています。

Copyright © 2011-2017 Increments Inc. All right reserved.

これは間違いではありませんが、冗長です。
万国著作権条約では「©」「最初の発行年」「著作者」の３つの表示のみ義務づけられているので、このルールに則ると以下のように書けます。

© 2011 Increments Inc.

Copyright

- © が Copyright を意味しているので重複。
- 環境によっては © が表示できない場合もあるので (c) や (C) と表示することもある。
- (c) でも (C) でも Copyright でも Copr. でも問題ないと思われる(・・・たぶん)。

更新年

- 不要。
- ただし、発行年は必要なので注意。

All rights reserved.

- 不要。
- ブエノスアイレス条約で定められているルールでは必要だが、現在はブエノスアイレス条約に加盟している国は全てベルヌ条約にも加盟しているので、書かなくても保護される。
- なお、日本はブエノスアイレス条約に加盟していないので完全に無意味。

３つの必須情報は自由な順番で記述できるので、以下のように書いても全く問題ありません。

2011 Increments Inc. ©  

余分な情報を加えることで権利が保護されないということはないので、最初の長いコピーライト文でも間違いではありません。


## 有名ウェブサイトの表記(2017/07/20現在)

プログラミング系サイト

- Qiita
    - © 2011-2017 Increments Inc.
- Stackoverflow
    - © 2017 Stack Exchange Inc
- Teratail
    - © 2014-2017 Leverages Co., Ltd.
- GitHub
    - GitHub © 2017

ビッグ４

- Apple
    - Copyright © 2017 Apple Inc. All rights reserved.
- Microsoft
    - © 2017 Microsoft
- Google ヘルプ
    - ©2017 Google
- Amazon
    - © 1996-2017, Amazon.com, Inc. or its affiliates

日本代表

- Toyota
    - ©1995-2017 TOYOTA MOTOR CORPORATION. ALL RIGHTS RESERVED.
- NTT
    - Copyright © 1999 日本電信電話株式会社
- docomo
    - © NTT DOCOMO, INC. All Rights Reserved. 
- Softbank
    - Copyright © Softbank All right reserved.

SNS系

- Youtube
    - © 2017 YouTube, LLC
- Twitter
    - © 2017 Twitter
- Facebook
    - Facebook © 2017

さすがに「©」と「著作者」は、みんな表記してますね。
ただ、「最初の発行年」ルールに関しては守ってないサイトも多いです。
アメリカの企業は守らない傾向が強いです。
国ごとでルールが違うのでしょうか？？？
docomo と Softbank は発行年どころか更新年すら表記されていませんが、大丈夫なんでしょうか？
ここまで忠実に守られていないと、今回調べたルールが本当に正しいのかすら疑わしく感じます。
もしくは、ウェブサイトは微妙にルールが違うのかな？


## 参考

[著作権表示 @ Wikipedia](https://ja.wikipedia.org/wiki/%E8%91%97%E4%BD%9C%E6%A8%A9%E8%A1%A8%E7%A4%BA)