OmniAICreator/Qiita-1.07M huggingface dataset:
SlackからGoogle Calendarを操作するBotを社内で運用してみた

この記事は 「[Slack Advent Calendar 2018](https://qiita.com/advent-calendar/2018/slack)」 の21日目の記事です。

## はじめに

皆さん、Slackは活用していますでしょうか。
私の所属している会社では毎日（平日）Slackでの会話が盛り上がっていてお前らいつ仕事してるんだ？と感じる程です。
また[独自の文化やBot](https://medium.com/@katzchang/voyage-group-happy-slacking-guide-a0da65efd758)もどんどん社員が勝手に導入してカオスな空間になっています。

話変わって、独自の文化という文脈で弊社では全社員が編集権限を持つGoogle CalendarのCalendarに他の人も自由に参加してほしい予定を作り参加してもらうと言う文化（？）があります。
勉強会だったり、またちょっとした社内の催しがカレンダーに追加されたら、そのゲストに自分を追加して…みたいな運用が行われています。

しかしこの自分をゲストに追加するという作業が地味にひと手間であったり、オペレーションミスでイベントを削除してしまったり、ゲストから他の人を除外してしまったりという事故が起こったりします。
こういったオペレーションミスを起こさないために必要なのはユーザーに対して一定の操作規制をかけるのが手っ取り早いです。
しかし外部サービスのUIを変えたり、各ユーザの操作権限を制御するなんてことは出来ません。

ということで、社内でコミュニケーションツールとして、またある種のインフラとして活用されているSlackのBotにその操作を行わせることで解消できるのではないかと考えたため、Google Calendarを操作するBotを作ってみました。

## 制作から完成まで

当初Google CalendarのUI上で行っていた、自分をゲストに加える操作をそのまま形にしようと実装を行いました。
SlackのOutgoing Webhooksを使ったもので、イメージとしては
`コマンド名 add カレンダーのイベントURL`
を対象のイベントに参加したい人が叩いてもらう運用です。

しかしこの方法では対象のイベントのURLを参加する各個人が知る必要があり、それを知っているのであればGoogle Calendarでミスが生じるかもしれなくても操作するほうが、タイプ数も少なくて済むという本当に使われるのか？みたいな状態になっていました。

そのため更にユーザの負担を減らし、楽にイベントに参加申請をする方法を模索しました。
そこで目をつけたのが[Message Attachments](https://api.slack.com/docs/message-attachments)と、そのActionをハンドルすることでした。
Message AttachmentsはSlackのメッセージをカスタマイズする機能で、装飾を行ったり、メッセージに対してボタンを付与したりすることが出来る機能です。
この機能を使いイベントを作った人にSlackでコマンドを叩いてもらって、そのコマンドに反応したBotが送信したMessageのボタンからイベントに参加申請するというフローを作りました。

以下が実際に使われている様子です。
<img width="505" alt="スクリーンショット 2018-12-21 23.29.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/104085/df7f3586-9390-9ee4-07bf-aad093e42f50.png">

この様にユーザに行わせる操作を限定することで、特定の目的を果たすことが容易になりました。
またこれを普段から使っていて馴染みのあるツールに導入するということで、様々なハードルが下がるのではないかと考えられます。

## 技術に関すること

今回はAzure FunctionsとC#を使用しました。
この技術の選定理由としては、

* Google CalendarやSlackなど複数のAPIの結果を組み合わせて使う場合、SQLの様にテーブルをガッチャンコする感じでListの操作が出来るLINQがあると便利だなと思った
* Azure Application Insightsのログ機能が優秀で、エラーで落ちた場合どのリクエストが走ってどこで落ちたのかがわかりやすい

という点があったからです。 ~~（本音を言うとC#が大好きだし会社でC#はやらせられないかなーとか思ったから）~~


もちろん今回行ったことはC#に限らず、様々な言語でSlackやGoogleの提供しているAPIのライブラリが提供されているため好きな言語で、また好きなホスティング環境で実施することが出来ます。

参考までに今回使用したコード（の一部）を公開いたします。
https://github.com/yamachu/calman

READMEなど一切なく、またボタンを押して参加する機能が社内リポジトリのコードにしか無くて不完全なところもありますが、参考にしてみてください。

## おわりに

SlackはBotを作って遊んでみる、というのが本当に簡単にできるプラットフォームであるので、是非とも活用していってほしいです。
Unixのtouchコマンドとは

以下のコマンドによって、ファイルが新規に作られる。

```
$ touch app/views/static_pages/about.html.erb
```

touchコマンドは本来、ファイルやディレクトリのタイムスタンプだけを更新するためのコマンドだが、ファイルが存在しない場合には空ファイルを作成するという一種の副作用がある。

参考：[Railsチュートリアル](https://railstutorial.jp/)
Ubuntu Server 18.04のWindows 10とのデュアルブートインストールで詰まったところ

# ディスクイメージ
Ubuntu Server 18.04からは新しいインストーラであるSubiquityが採用されている。
これには既存のストレージのパーティションが見えず、パーティションを追加するなどの操作が行えないため、
既存のパーティションを残したままインストールするためには、従来のインストーラを採用したディスクイメージが必要だった。

ダウンロードボタンの下にalternative downloadsというリンクがあるので、
そこからたどれば従来のインストーラを採用したディスクイメージがダウンロードできる。

Subiquity版：ubuntu-18.04.1.0-live-server-amd64.iso
Alternative版：ubuntu-18.04.1-server-amd64.iso

# Secure Boot
UEFIの設定でSecure Bootをオフにしておく。
必要かどうかわからないが、公式によるとオフにしておいたほうが無難らしい。

そのほか、Fast bootもオフにしておく必要があるが、筆者が試したマシンはFast bootの設定がなかった。

# インストール時の言語
インストール開始直後に言語を選択するが、その時日本語を選択するとパーティション読み込み時にフリーズする。
フリーズする場所が場所なので、別の問題を疑ったが、結果的には選択言語の問題だった。英語を選択すればインストールできた。

# ブートローダのパーティション
512MBでファイルタイプにEFS (EFI File System)を指定するパーティションを作ると、
マウントポイントが/boot/efiとなりブートローダがインストールされる。

このブートローダからWindowsも選択できるようになるので、UEFIの設定で
Ubuntu側のブートローダをデフォルトに指定すれば、WindowsとUbuntuがデュアルブートできるようになる。
Djangoのmigrationでエラーが出た時に試したこと

# はじめに

Pythonで、ある程度しっかりした（データベースを含めた）webアプリケーションを作ろうと思ったら、Djangoが選択肢に入ってくると思います。

Djangoはデータベースの変更や追加の作業が楽にできる仕組みが備わっていますが、エラーが発生した場合は、どのように対処すれば良いのか途方に暮れてしまいそうになることも多々あるのではないでしょうか？

最終的に、直接データベースをいじってやるしか解決策がない場合もあるのかもしれませんが、僕は今までのところ、そうせずになんとか解決してきました。

「もうイラつくから、python manage.py flushで全て消し去ってやる！」と実行に移す前に試してみると、もしかしたら解決するかもしれない、そんな方法を２つ紹介します。


# １、migrations/以下のファイルを削除する

そもそも

```python
python manage.py makemigrations
python manage.py migrate
```
で、それぞれ何が行われているかというと、基本的には

```python
python manage.py makemigrations
```

で、まず現在のデータベースの状態との差分をまとめたファイルを

プロジェクトディレクトリ / 各appディレクトリ / migrations /

以下に作成し、次に

```python
python manage.py migrate
```

で、先ほどのファイルの中身を元に、データベースの変更を実行する、という流れだと思います。

データベースに対してどのような操作が行われる予定なのかは、makemigrationsした後に
migrations/
以下のファイルの中身をのぞいてみれば、なんとなくわかるはずです。


差分ファイルを作成する際になんらかの原因で、現状が正しく反映されていない差分ファイルが作成されてしまうと、migrateを実行してもエラーが起こってしまいます。

なので、自分の意図した通りにdbを変更したいなら、差分ファイルを直接編集してしまえば良い（<b>これも解決策の１つ</b>）のですが、結構めんどくさいと思います。

もちろん、他にやりようがなく、これで解決できるならその手間なんて惜しくない！という状況ならアリですが、その前に以下のことを試してみる価値があると思います。

すなわち、

<b>migrations/ 以下の、\_\_init__.py以外のファイルを削除してから、makemigrations, migrateを再実行する</b>

ことです。
migrations/ 以下の差分ファイルを削除してしまえば、makemigrationsした際に正しく差分ファイルが作成される可能性があるので、そこに期待しようというわけです。


# ２、models.py（もしくはmodels/any_table.py）の変更部分を元に戻す→変更後に戻す

```
Unknown column 'なんちゃら' in 'field list'
```

特に上記のようなエラーが出た時はこの手段で解決するかもしれません。

考え方としては先ほどと似ていて、できることなら正しい差分ファイルを自動で作り直してもらうことを狙っています。

このエラーが出た時は、１番の方法では解決できないことがありました。
そんな時どうやって解決したかというと、以下の手順。

<b>
１、まずモデル定義ファイル（models.pyなど）の変更部分を元に戻す
２、その状態でmakemigraions, migrateを実行
３、変更したい部分を編集（変更後の記述に戻す）
４、その状態でmakemigraions, migrateを実行
</b>

これは力ずくなやり方な気がしますが、要はなんらかの変更が加えられたと認識させて、正常にmigrateしてから、変更したい部分を正常にmigrateするのが目的です。

# 終わりに

私自身はDjangoの専門家というわけではないですし、今回紹介したやり方を積極的に推奨して良い気は全くしないのですが、今までのところ、この方法で問題なくやっています。

Djangoのデータベース変更で悩んでいる初心者の方の助けになれば幸いです。
Elm全く触れたことなかったけどTDD + モブプロやった話

本当に全くElmに触れたことのなかった人が、一時間くらいレクチャーを受けた後にTDDモブプロ（ハンズオン）やった話です。しかも講師役。
何が言いたい記事かというと、 **Elmってシンプルで読みやすいし始めやすいぞ** という話です。感想を述べます。
Elmに関する知識は、別の記事を参考にしてください。

## ことの始まり
きっかけは、Elmエバンジェリストを名乗る友人Mでした。
M「今度学生向けにElmのハンズオンイベントやるので、手伝ってください！」
僕「Elm全然触ったことないんですけど大丈夫ですか...？」
M「大丈夫です！ **Elmの文法なんて [コレ](https://elm-lang.org/docs/syntax) しかないんですよ！** すぐ出来るようになります！」
僕「え、でもElmって、関数型採用しているフロントの言語ですよね...？僕関数型プログラミングもちゃんとできないし、HTMLもまともに書けませんよ...？」
M「 **大丈夫です！なんとかなります！** 」
M「いやー、Emlの良いところはですね、、、」（この後30分くらい語られる）

## やったこと
- プログラミング経験のある学生に、ElmのハンズオンをTDD + モブプロで行う際の講師をしました（一応Elmが書ける人に相談できた）
- Elmについては、学生と一緒に最初に一時間くらい講義を受けたのと、事前にハンズオンの回答のコードを軽く見てきた程度でした。

## できたこと
- Elmの書き方が分からなかったらとりあえずできる人に聞くかググレって言うこと
- TDDの基本的な考え方、モブプロの簡単なやり方を伝えること
- TDDそのものに興味を持ってもらうこと
- Elmに対してポジティブな印象を持ってもらうこと

## できなかったこと
- Elmの書き方をマスターしてもらうこと
    - あんまり聞かないでもググればElm書けるようになる程度にはしてあげられなかった
- ハンズオンを終わらせること
    - 質問しながら個人でやると十分に終わるレベル、量のハンズオンだったのに...

## やりたかったこと
Elmが書けるようにしたかったんじゃない。Elmを楽しく書くきっかけを作りたかったんだ。
だからオッケー。

## やってよかったこと
- 僕自身、Elmの世界に足を踏み入れられた
    - 感想は後述
- TDDやモブプロの考え方を言葉にすることで、改めて整理できた

## Elmのよかったこと
- 全く触れたことがなくても、 [Application flow](https://www.elm-tutorial.org/en/02-elm-arch/04-flow.html) を知れば大体何してるか読める
- 文法を一通りさらうのがとても簡単
- コードの書き方に種類が少ないので、サンプルコードがあれば大体書ける
- いい感じにフォーマットしてくれるプラグインがあるから綺麗になる

## ちょっとハマったこと
演算子っぽいものを使った書き方をちゃんと理解するまでに少し時間がかかりました。
（[こちらを参考にしています](https://github.com/elm-community/elm-test)）
特に
コレ


```
<|
```
とコレ

```
\_ ->
```
なんじゃこれって思ってましたが、 **これは難しい文法なんかじゃなくて、あらかじめ定義された関数を使っているだけなんだな** と理解すれば、そのあとは瞬殺でした。
mysql2 gemがld: library not found for -lsslでインストールできないときのbundle config

結論から言うとこの値を指定すればOK。

```
bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl/lib --with-cppflags=-I/usr/local/opt/openssl/include"
```

エラーログの中で大事なのはこの辺。

```
linking shared-object mysql2/mysql2.bundle
ld: library not found for -lssl
```

他のgemの場合は似たような下記の指定でうまくいくことがあるが、mysql2 gemの場合はうまくいかない。

```
LDFLAGS="-L/usr/local/opt/openssl/lib" CPPFLAGS="-I/usr/local/opt/openssl/include" PKG_CONFIG_PATH="/usr/local/opt/openssl/lib/pkgconfig"
```

エラーログ全文は下記の通り。

```
Fetching mysql2 0.5.2
Installing mysql2 0.5.2 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    current directory: /Users/username/Repositories/records_rip/.bundle/ruby/2.5.0/gems/mysql2-0.5.2/ext/mysql2
/Users/username/.rbenv/versions/2.5.3/bin/ruby -r ./siteconf20181221-9919-15kib33.rb extconf.rb
checking for rb_absint_size()... yes
checking for rb_absint_singlebit_p()... yes
checking for rb_wait_for_single_fd()... yes
-----
Using mysql_config at /usr/local/bin/mysql_config
-----
checking for mysql.h... yes
checking for errmsg.h... yes
checking for SSL_MODE_DISABLED in mysql.h... yes
checking for SSL_MODE_PREFERRED in mysql.h... yes
checking for SSL_MODE_REQUIRED in mysql.h... yes
checking for SSL_MODE_VERIFY_CA in mysql.h... yes
checking for SSL_MODE_VERIFY_IDENTITY in mysql.h... yes
checking for MYSQL.net.vio in mysql.h... yes
checking for MYSQL.net.pvio in mysql.h... no
checking for MYSQL_ENABLE_CLEARTEXT_PLUGIN in mysql.h... yes
checking for SERVER_QUERY_NO_GOOD_INDEX_USED in mysql.h... yes
checking for SERVER_QUERY_NO_INDEX_USED in mysql.h... yes
checking for SERVER_QUERY_WAS_SLOW in mysql.h... yes
checking for MYSQL_OPTION_MULTI_STATEMENTS_ON in mysql.h... yes
checking for MYSQL_OPTION_MULTI_STATEMENTS_OFF in mysql.h... yes
checking for my_bool in mysql.h... yes
-----
Don't know how to set rpath on your system, if MySQL libraries are not in path mysql2 may not load
-----
-----
Setting libpath to /usr/local/Cellar/mysql/5.7.21/lib
-----
creating Makefile

current directory: /Users/username/Repositories/records_rip/.bundle/ruby/2.5.0/gems/mysql2-0.5.2/ext/mysql2
make "DESTDIR=" clean

current directory: /Users/username/Repositories/records_rip/.bundle/ruby/2.5.0/gems/mysql2-0.5.2/ext/mysql2
make "DESTDIR="
compiling client.c
compiling infile.c
compiling mysql2_ext.c
compiling result.c
compiling statement.c
linking shared-object mysql2/mysql2.bundle
ld: library not found for -lssl
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mysql2.bundle] Error 1

make failed, exit code 2

Gem files will remain installed in /Users/username/Repositories/records_rip/.bundle/ruby/2.5.0/gems/mysql2-0.5.2 for inspection.
Results logged to
/Users/username/Repositories/records_rip/.bundle/ruby/2.5.0/extensions/x86_64-darwin-18/2.5.0-static/mysql2-0.5.2/gem_make.out

An error occurred while installing mysql2 (0.5.2), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/'` succeeds before bundling.

In Gemfile:
  mysql2
```
[Java EE] WebSocketでClientを実装

最近、Qiita記事が進捗報告になってまいりました。
今回も、[こちら](https://qiita.com/Kakky/items/27fa8940016428ee71f6)の記事の続きになります。

# tyrus-standalone-clientの追加
普通にクライアントプログラムを書いて実行すると、次のようなエラーが発生します。

```
Exception in thread "main" java.lang.RuntimeException: Could not find an implementation class.
	at javax.websocket.ContainerProvider.getWebSocketContainer(ContainerProvider.java:73)
	at Main.main(Main.java:46)
```
stackoverrunによると、websocketはClientのインターフェースは提供しているものの、実装を提供していないようです。
そこで、glassfishにあるtyrus-standalone-clientを導入します。
[StandardWebSocketClientクラスにWebSocketContainerを実装する方法](https://stackoverrun.com/ja/q/8620474)

具体的には、build.gradleのdependenciesに追加します。

```groovy
dependencies {
    // 前回説明した
    compileOnly 'javax:javaee-api:8.0'
    // 今回追加するのがこれ
    compile group: 'org.glassfish.tyrus.bundles', name: 'tyrus-standalone-client', version: '1.14'
}
```

# ClientEndPointを記述する
では、今回は早速プログラムを書いていきましょう。
<プロジェクト名> -> src -> main -> java 内(の適当なパッケージ)に、.javaファイルを作成します。

```java

import javax.websocket.*;
import java.net.URI;
import java.util.Scanner;

// このアノテーションを付けるとクライアントのEndpointだと認識される
@ClientEndpoint
public class Client {

    public Client() {
        super();
    }

    // セッション確立時の処理
    @OnOpen
    public void onOpen(Session session) {
        System.out.println("[セッション確立]");
    }

    // メッセージ受信時の処理
    @OnMessage
    public void onMessage(String message) {
        System.out.println("[受信]:" + message);
    }

    // メッセージ受信時の処理
    @OnError
    public void onError(Throwable th) {
        System.err.println(th.getMessage());
    }

    // セッション解放時の処理
    @OnClose
    public void onClose(Session session) {
        System.out.println("[切断]");
    }

    static public void main(String[] args) throws Exception {

        // 初期化のため WebSocket コンテナのオブジェクトを取得する
        WebSocketContainer container = ContainerProvider
                .getWebSocketContainer();
        // サーバー・エンドポイントの URI
        URI uri = URI
                .create("ws://localhost:8080/<プロジェクト名>/<リンク>");
        // サーバー・エンドポイントとのセッションを確立する
        // 実行されているクライアントから、引数に渡したクラスと同一の物を探して接続する？
        Session session = container.connectToServer(Client.class, uri);

        while (!session.isOpen()) {
            Thread.sleep(500);
        }

        System.out.println("open");

        try (Scanner s = new Scanner(System.in)) {
            String str;
            System.out.println("start loop");
            while (true) {
                str = s.nextLine();
                if(str.equals("exit")) break;
                //strの内容を送信
                session.getBasicRemote().sendText(str);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}
```

面倒なので今回はEndpointクラス内にmainを書きましたが、分けた方がいいような気がします。

# 実行
まず、tomcatRunなどで、Clientの入ったサーバーを立ち上げ、その後、別窓でmainを実行します。
今年のクリスマスはガジェットリースを作ろう

# TL;DR

* ガジェット＋クリスマスリース＝ガジェットリース
* ガジェットリースの作り方の一例を紹介
* GitHubは[こちら](https://github.com/iwathi/gadget_wreath)

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ガジェットリース1号をリリース<a href="https://twitter.com/hashtag/%E3%82%AC%E3%82%B8%E3%82%A7%E3%83%83%E3%83%88%E3%83%AA%E3%83%BC%E3%82%B9?src=hash&amp;ref_src=twsrc%5Etfw">#ガジェットリース</a> <a href="https://t.co/wPLySEiRJd">pic.twitter.com/wPLySEiRJd</a></p>&mdash; iwathi (@iwathi) <a href="https://twitter.com/iwathi/status/1075982244567629825?ref_src=twsrc%5Etfw">December 21, 2018</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# ガジェットリースとは

### ガジェット(電子機器等)＋クリスマスリース＝ガジェットリース

という定義のもと新たに考えた概念です。

　クリスマスにいたるところで売っているクリスマスのリース・または家に余っているケーブルを、Arduino・RaspberryPiなどの電子機器を使ってガジェット化しよう（または、家にあるだけで転がっているArduinoなどを使って家を明るくしよう！）、というプロジェクトです。

### 参加方法は簡単ガジェットリースを作って#ガジェットリースでつぶやくだけ!!

　イメージは冒頭に載せたツイートのような感じで、リースを使っていれば何をくっつけてもガジェットリースなので、難しい決まりはまったくありません。お好きなガジェットをリースにくっつけてガジェットリースとしてリリースしましょう。


### 決まりは特に無し！

　決まりはまったくないので好きなものを#ガジェットリースと名付けてつぶやけばOK！

* かっこよさを追求して電子部品でコテコテにすることを目的に部品をひたすらくっつけまくってもOK！
* 実際に動くことが重要だ！と言って、LEDでビカビカに光らしてもOK！
* リースよりも大きいものをくっつけて、それはもう違うものでは？というものもOK！

　それぞれ思い思いのガジェットリースを作りましよう！

それでは誰でもできる簡単なガジェットリースの作成方法を紹介していきます！

# 簡単なガジェットリースの作り方

　基本的に必要な工程は３つです。

1. リースの土台を用意する
2. お気に入りのガジェットを貼り付ける
3. Tweetする

以上！

それでは少しだけ詳しく説明していきます。

## リースの土台を用意する

　２つの方法があります。

1. １００均でリース本体を買ってくる
2. 余っているケーブルでリースを作る

1に関しては最も簡単で１００均で売っているの買ってきましょう！

こんなやつです。

![63C50015-192C-4D40-944B-4A1D457AACE1.jpeg](https://qiita-image-store.s3.amazonaws.com/0/170821/1281c987-12b9-2616-aff1-0bcbeb394b0d.jpeg)


### もしくは

* 家に腐るほど使ってないケーブルがある
* 電子部品の配線をスッキリさせたい

という人は家にあるケーブルを使って簡単にリースを自作しちゃいましょう。

　今回はLANケーブルでリースの土台となる部分を作ってみました。
この様な感じです。

![CF7424D1-CE9F-4DEF-83AE-A13509CB7474.jpeg](https://qiita-image-store.s3.amazonaws.com/0/170821/7bf887b3-b68f-5bb2-2202-ee0b121424ed.jpeg)

この溢れ出るリース感、やばくないですか？

## お気に入りのガジェット（電子部品）を貼り付ける

　リースが準備できたら次は装飾としてガジェット（電子部品）をくっつけていきましょう！
実際に、壁にかける予定が無ければ乗っけるだけでもOKです。
今回はリースに配線も絡ませてみました。

![3013E671-95B8-44C7-880D-6D0150862D27.jpeg](https://qiita-image-store.s3.amazonaws.com/0/170821/0972e47b-9447-bbbf-4ba5-e3bdaf9ae068.jpeg)


ここにArduinoやRaspberryPiを載せるとこのような感じです。

![BA361E80-B844-40FC-B90D-967B3031B8AB.jpeg](https://qiita-image-store.s3.amazonaws.com/0/170821/3ca27bf1-25d8-b60b-4921-691242414eed.jpeg)

なんかすごくゴチャゴチャしてますね。

## Tweetする

　そうしたら最後に自慢のガジェットリースを撮影をして下のハッシュタグからつぶやきましょう！

<a href="https://twitter.com/intent/tweet?button_hashtag=ガジェットリース&ref_src=twsrc%5Etfw" class="twitter-hashtag-button" data-show-count="false">Tweet #ガジェットリース</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### これでガジェットリース完成です！

　上記のように簡単にガジェットリースをリリースできますので、クリスマスの暇つぶし、もしくは恋人と一緒にぜひ、ガジェットリースをリリースしてみましょう！

　一応、今回のツイートで使ったLチカ（Arduino）のコードを[GitHub](https://github.com/iwathi/gadget_wreath)にのせておきます。ガジェットリース関連でのコントリビュートをお待ちしております！

# まとめ

* ガジェット＋クリスマスリース＝ガジェットリース
* ガジェットリースの作り方の一例を紹介
* Githubは[こちら](https://github.com/iwathi/gadget_wreath)
Qiitaをきれいに書くためのMarkdown記法まとめ

Qiitaで勉強したことをアウトプットしていましたが、*Markdown*の書き方をちゃんと理解していなかったので、*Markdown*の書き方を学びました。
学習にはドットインストールの「*Markdown*記法入門」を使いました。
1時間くらいでさっと終わるのでおすすめですよ。
ここでは、よく使う*Markdown*記法を紹介します！

##よく使う*Markdown*記法

1. 見出し
↑の「よく使う*Markdown*記法」は見出し(h2)で書かれています。
見出しは
#h1
から
######h6
まであり、サイズが異なります。
また、h1とh2には、自動で下にボーダーが引かれます。
見出しなので改行が必要なことに注意してください。

1. 引用文
「>」を文章の前に打つと引用文にしてくれます。
>Q&Aサイトやブログで何かを引用してコメントを付けることはよくありますね。

1. 強調
文字を「*」か「_」で囲うと斜体に、「**」か「___」で囲うと、濃くしてくれます。
斜体は英数字に有効です。

*syatai*

**強調**

1. リスト
HTMLで言う箇条書きリスト(ul)や連番リスト(ol)も簡単に書けます。
「* 文章～」で箇条書きリストになります。
「数字. 文章～」で連番リストになります。
空白は半角なので気を付けてください。
 * 文章～  

1. リンク
HTMLで言う*a*タグです。
[Qiita](https://qiita.com/ "ｷｲﾀｯﾀ")
↑リンクを押せばQiitaのホームページに跳べます。
テキスト名は[]で、アドレスは()でくくっています。
title属性も仕込めるのでチャレンジしてみてください。

　　
その他にもたくさん書き方があります。
*Markdown*を使いこなして、Qiitaの記事をきれいに書いてみてください。
SceneKitのパーティクルシステムの使い方

3D体験をよりリッチにしてくれる、パーティクルシステムについて紹介します。

# パーティクルシステムとは

>パーティクル・システム（英: particle system）はコンピュータグラフィック技術のひとつで、運動する粒子により構成される事象を表現するために使われる。

>一般にパーティクル・システムを用いて模擬される事象の例としては、炎、爆発、煙、流水、火花、落葉、雲、霧、雪、埃、流星、毛髪、毛皮、草地、あるいは光跡や呪文の視覚効果などが挙げられる。
https://ja.wikipedia.org/wiki/%E3%83%91%E3%83%BC%E3%83%86%E3%82%A3%E3%82%AF%E3%83%AB%E3%83%BB%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0

# SceneKitデフォルトのパーティクルシステム

デフォルトでこんなに用意されています。これらのパラメータを調整したり、粒の色、形、画像を変えたりして様々な表現が可能です。

|bokeh|confetti|fire|rain|reactor|smoke|star|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|<img src="https://github.com/kboy-silvergym/ARKit-Emperor/raw/master/images/bokeh.gif" width=140>|<img src="https://github.com/kboy-silvergym/ARKit-Emperor/raw/master/images/confetti.gif" width=140>|<img src="https://github.com/kboy-silvergym/ARKit-Emperor/raw/master/images/fire.gif" width=140>|<img src="https://github.com/kboy-silvergym/ARKit-Emperor/raw/master/images/rain.gif" width=140>|<img src="https://github.com/kboy-silvergym/ARKit-Emperor/raw/master/images/reactor.gif" width=140>|<img src="https://github.com/kboy-silvergym/ARKit-Emperor/raw/master/images/smoke.gif" width=140>|<img src="https://github.com/kboy-silvergym/ARKit-Emperor/raw/master/images/star_particle.gif" width=140>|

# パーティクルを作ろう

## ファイルの作成

パーティクルシステムのファイルは、`NewFile -> SceneKit Particle System File`の順に選択し、作成します。

<img width="1280" alt="2018-12-20 10 13 55" src="https://user-images.githubusercontent.com/17683316/50346183-ed793680-0574-11e9-82ef-530829227358.png">

先に紹介したデフォルトのパーティクルの中からテンプレートを選択します。

<img width="1280" alt="2018-12-20 10 14 09" src="https://user-images.githubusercontent.com/17683316/50346184-ed793680-0574-11e9-8de9-6be5b23188c7.png">


右側のタブからBirth RateやSpeed, Shapeなど色々調整できます。

<img width="1280" alt="2018-12-21 22 47 35" src="https://user-images.githubusercontent.com/17683316/50345798-a474b280-0573-11e9-8f9a-2078a530b6ed.png">

具体的な調整方法は無限大なので今記事では割愛します。

## コード

空間のrootNodeにパーティクルシステムを発生させる場合、以下のように、SCNNodeを作成しaddParticleSystemするだけです。

物体からパーティクルシステムを発生させたい場合は物体のNodeに対してaddParticleSystemしましょう。

```swift
let particle = SCNParticleSystem(named: particle.rawValue + ".scnp", inDirectory: "art.scnassets")
let particleNode = SCNNode()
particleNode.addParticleSystem(particle!)
sceneView.scene.rootNode.addChildNode(particleNode)
```

# ペチャバトの必殺技にもパーティクル

私の現在開発している[ペチャバト](https://itunes.apple.com/jp/app/id1444974380?mt=8)でも、炎、雷、煙などがパーティクルシステムによって作られています。

<img src="https://d2l930y2yx77uc.cloudfront.net/production/uploads/images/8897766/picture_pc_dfcdada5c096a6c91fd9c6adae778a59.gif" width=300>

# サンプルコード

https://github.com/kboy-silvergym/ARKit-Emperor のParticleにあります！
EKSのpodログをfluentdでcloud watchに送る

以前にhelmを利用した方法を書いたけど、使ってるうちにfluentdの使い方を理解してきて、結局カスタマイズしたいよねという気持ちになった。helm使わなくても入れられそうだったので、利用したyamlを備忘録として記載する。

# IAMの設定
- CWにログを送れるようにWorkerNodeのロールにポリシーを割り当てる

# ソース
- [reinvent2018-dev303-code/deploy/monitoring at master · aws-samples/reinvent2018-dev303-code](https://github.com/aws-samples/reinvent2018-dev303-code/tree/master/deploy/monitoring)
    - fluentd-cloudwatch-configmap.yaml
        - AWSのリージョン指定する部分あるので適宜変更
    - fluentd-cloudwatch-daemonset.yaml

# stream名を変更する
[ここ](https://github.com/aws-samples/reinvent2018-dev303-code/blob/master/deploy/monitoring/fluentd-cloudwatch-configmap.yaml#L63)の「container_name」を「pod_name」にすればstream名をpod名にできる
ApplicationCommands.DeleteはTextBoxに対応していない

ApplicationCommands.Deleteを実行してもTextBoxの内容は削除できない。（カット、コピー、ペースト、アンドゥ、リドゥは問題ない。）かわりにEditingCommands.Deleteを使う。

ただし、EditingCommands.Deleteをメニューアイテムに指定した場合、InputGestureTextが表示されない。（表示されないだけで、キー入力自体は有効。）

```xml:XAML
<Window x:Class="Sample.MainView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:Sample"
        Title="MainView" Height="300" Width="300">
    <Grid>
        <Menu>
            <MenuItem Header="編集">
                <MenuItem Header="元に戻す" Command="ApplicationCommands.Undo"/>
                <MenuItem Header="やり直し" Command="ApplicationCommands.Redo"/>
                <MenuItem Header="切り取り" Command="ApplicationCommands.Cut"/>
                <MenuItem Header="コピー" Command="ApplicationCommands.Copy"/>
                <MenuItem Header="貼り付け" Command="ApplicationCommands.Paste"/>
                <!--InputGestureTextを指定する-->
                <MenuItem Header="削除" Command="EditingCommands.Delete" InputGestureText="Delete"/>
            </MenuItem>
        </Menu>
    </Grid>
</Window>
```
ツールチップにバインドすると内容が空でも表示されてしまう

内容が空の場合はツールチップを表示しないようスタイルを指定する。

```xml:XAML
<Window x:Class="Sample.MainView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:Sample"
        Title="MainView" Height="300" Width="300">
    <Grid>
        <TextBlock Text="{Binding Value}" ToolTip="{Binding ToolTipText}">
            <TextBlock.Resources>
                <Style TargetType="ToolTip">
                    <Style.Triggers>
                        <Trigger Property="Content" Value="{x:Static sys:String.Empty}">
                            <Setter Property="Visibility" Value="Collapsed" />
                        </Trigger>
                        <Trigger Property="Content" Value="{x:Null}">
                            <Setter Property="Visibility" Value="Collapsed" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </TextBlock.Resources>
        </TextBlock>
    </Grid>
</Window>
```
form_forをform_withにリファクタする

# はじめに
Railsの5.1以降は`form_with`が推奨され`form_for`、`form_tag`に別れていたのが`form_with`に統合されます。自社サービスファ`form_for`のままだったので`form_with`にリファクタする課程で調べたノウハウを記載していきます。
まだ着手したばかりなので、追記していくかもしれません。

# やったこと
元々の実装

```ruby
form_for @model, url: action_path do |f|
```

form_withに変更

```ruby
form_with model: @model, url: action_path, local: false do |f|
```

- 第一引数に指定していたオブジェクトを`model`オプションに設定
- デフォルトが非同期通信になったため、`local`オプションに`false`を設定

非同期通信を多用しているサービスなら、デフォルトが`local: true`で良いと思いますが、参画しているサービスはあまりなかったため、デフォルトを`false`にしたいということで、以下を`config/environment/*.rb`に設定しました。

```
config.action_view.form_with_generates_remote_forms = false
```

configレベルでの設定になるんですね。

ここで`checkbox`が`label`と紐づいてないことに気づきました。`label for=""`のことです。

```
config.action_view.form_with_generates_ids = true
```

1個ずつidを割り振ると対応が大変なのですが、`config`に常軌を設定すると自動でidの発行・紐づけをしてくれます。

# 最後に
リファクタを進めてわかった点は追記していこうと思います。
`config`周りはトラップな印象を受けました。廃止された時、リファクタ対応をしておかなければ対応が大変だったと思いました。先に着手しておいてよかったです。
【文系PMの作る】nuxt+netlify+firebaseで作る最高の睡眠を記録するwebアプリ（後編）

# 前回のあらすじ

前回のqiita

「【文系PMの作る】nuxt+netlify+firebaseで作る最高の睡眠を記録するwebアプリ（前編）」
https://qiita.com/you8/items/7b604f91fabe46871b1c

nuxtで睡眠快適度を送ってグラフ化するアプリで前回は入力まで。今回はchart.jsを使ってグラフにします。と思ったんですが躓いて間に合わなかったのでおまけ的に作ってた機能で。chart.jsはまたこんど記事に書くぞ（泣）

# 入力する数値によって表情を変える

ちょっとオマケ機能になりますが入力する睡眠快適度によって表情を変える機能を実装しました。コード的には下記。

```html
  <div v-if="note_content > 80">
    <img src="~/assets/img/status5.png" />
  </div>
  <div v-else-if="note_content > 60">
    <img src="~/assets/img/status4.png" />
  </div>
  <div v-else-if="note_content > 40">
    <img src="~/assets/img/status2.png" />
  </div>
  <div v-else-if="note_content >= 0">
    <img src="~/assets/img/status1.png" />
  </div>
  <div v-else>
    <img src="~/assets/img/status3.png" />
  </div>
  <p><b-form-input v-model="note_content" type="range"></b-form-input></p>
  <p><button @click="saveContent(note_content)">おはよー！！</button></p>
```

こんな感じで変わる。

![kururkuru.gif](https://qiita-image-store.s3.amazonaws.com/0/193389/2a2144d4-25df-4642-8c92-eaf585d00df9.gif)

## 絵文字

絵文字はemojioneがいい感じだった

https://www.emojione.com/

かわいい

![スクリーンショット 2018-12-21 22.57.37.png](https://qiita-image-store.s3.amazonaws.com/0/193389/e4b829f3-982a-ee72-5c0a-367abc3fee02.png)


# 趣味プログラミングのすすめ

とまあ非エンジニアの趣味エンジニアリングをまとめてきました。プログラミング覚えると日曜大工的にモノづくりを楽しめておすすめです。しかもプログラミングは日曜大工と違って材料費かからないのでお得。
WAMs(Web Audio Modules)について紹介してみる

https://adventar.org/calendars/3353 の23日目エントリーです。

# WAMsって何？

WAMs(Web Audio Modules)とは、[Oli Larkin](https://github.com/olilarkin)によって提案された、Web Audio APIでVSTプラグインのように扱えるプロセッサー・モジュールの仕様です。
公式サイト: https://www.webaudiomodules.org/


# サンプル

いくつかのサンプルが公式サイトに掲載されています。
そのほとんどは元々VSTプラグインだったものをWAMsに移植したものです。
Web MIDI APIの入力を受けられるので、MIDIキーボードから演奏することができます。
https://www.webaudiomodules.org/wamsynths/
![image.png](https://qiita-image-store.s3.amazonaws.com/0/93566/6c1895b9-eed2-eaa3-8256-fc6f74755fea.png)

# API仕様

API仕様も公式サイトから確認することができます。
https://www.webaudiomodules.org/docs/wampaper-smc2015.pdf

概要をざっくり解説すると、DSPを実装するWAM.Processorと、GUIを実装するWAM.Controllerとがあり、このうちWAM.Processorに対して、Web Audio APIからのコールバックを受けて信号処理を実行するという仕組みのようです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/93566/bf1a764b-c327-2da5-d697-2025cbe71437.png)


# SDKについて

WAMsのSDKはGithubにて公開されています。[リンク](https://github.com/webaudiomodules/api)
WAMs SDKはC言語で書かれています。
WAMsのAPIが定義されたCインターフェースを実装し、EmscriptenでWeb Assembly化することで、JavaScriptにロードさせるという仕組みになっています。

# ADC2018でのセッション

開発者のOli LarkinとJari KleimolaがADC2018で行ったセッション動画が公開されています。

Oli Larkin - Bringing VirtualCZ to the Web
[![ビデオが開けなかった場合に表示されるテキスト](http://img.youtube.com/vi/IRLxMhksUZ0/0.jpg)](https://www.youtube.com/watch?v=IRLxMhksUZ0)

Jari Kleimola - JUCE plugins for web browsers
[![ビデオが開けなかった場合に表示されるテキスト](http://img.youtube.com/vi/ORIpeFQqR9c/0.jpg)](https://www.youtube.com/watch?v=ORIpeFQqR9c)
git pushのオプション -u とは

## 背景
Railsチュートリアルで

```
git push -u origin master
```

というのが出てくるが、「-u」というオプションが気になったので調べてみた。

## 概要

-u と --set-upstream が同じ意味とのこと。このオプションをつけるとローカルリポジトリの現在のブランチの上流をorigin master に規定したことにる。
このオプションをつけると、次からは git push だけで上記のコマンドと同じことを実施できる。さらに、git pull だけでも git pull origin master と同じ意味になる。

まとめると、

```
git push -u origin master
```
このコマンドでoriginにマスターブランチをpushし、ローカルブランチの上流がorigin masterへと移ることになる。
Clova開発オレオレ標準テンプレート

## はじめに
こんにちは。
この投稿は [LINEBot&Clova Advent Calendar 2018](https://qiita.com/advent-calendar/2018/linebot)の21日目の投稿です。

皆様、Clovaのスキル開発にいそしんでいらっしゃいますでしょうか。
Clovaのスキルに限りませんが開発をゼロから始めるのは、労力もそれなりにかかり
意外とハードルが高くなってしまうものです。

そこでゼロから作らなくても済むよう開発テンプレート的なのを用意しました。
（元ネタはハンズオンで使ったものになります。）
手前味噌で恐縮ですが、紹介していきたいと思います。
皆様の労力を少しでも軽くできますように。

## ハンズオン資料
[![ハンズオン資料](https://qiita-image-store.s3.amazonaws.com/0/121860/0ee9d51c-385b-7dac-ac4a-148b13876c13.png)](https://speakerdeck.com/mochan_tk/line-boot-awardsgong-shi-xia-qi-jiang-xi-hanzuonzi-liao)

https://speakerdeck.com/mochan_tk/line-boot-awardsgong-shi-xia-qi-jiang-xi-hanzuonzi-liao

こちら当時のハンズオン資料をSpeakerDeckに上げ直しました。こちらの**資料に従って作業を進めると
Clovaのスキルが開発できる**ようになってるんですね。１度ハンズオンでも使った実績の有る資料ですので安心してお使いください！
（でも少し情報が古いかもしれないので、適宜読みかえていただけると！）

ちなみに資料の中で使用しているコードは下記のGithubリポジトリに置いてあります。
https://github.com/mochan-tk/clova-handson-20180904

ここから下は少し雑な資料になりますがご容赦くださいませ。

## 開発応用編
ここからは応用編になります。
Clovaの開発をもっと楽にしていきましょう！

### Typescriptテンプレート
https://github.com/mochan-tk/clova-handson-20180904/tree/typescript

ハンズオン資料で使用しているjavascriptのコードを**TypeScriptに置き換えた**ブランチになります。
Node.jsでの開発の場合、javascriptでプログラミングすると思いますが
Node.jsやるならTypescriptを私は推したいです。

Typescriptのメリットについては下記の記事が参考になります。
https://furien.jp/columns/279/

### Lambda テンプレート
https://github.com/mochan-tk/clova-handson-20180904/tree/lambda-layers

AWS Lambdaで動かすことを前提にしたブランチです。

ちなみにAWS Lambda Layersをご存知でしょうか？ LambdaのLayer機能を使うとさらにClovaの開発が楽になります。
詳細は下記を見ていただくとして、ざっくり言うと共通のコードを別途配置しておくことができる機能ですね。
（今年はLambda関連の新機能がたくさん発表されました。**待ってるだけで開発が勝手に楽になっていく、そうAWSならね**。）

[![AWS Lambda Layers](https://qiita-image-store.s3.amazonaws.com/0/121860/91a38642-491e-c163-ea55-88e84d4b5c42.png)](https://speakerdeck.com/mochan_tk/line-bot-and-clova-cekkai-fa-zhe-2018da-wang-nian-hui-lt)

https://speakerdeck.com/mochan_tk/line-bot-and-clova-cekkai-fa-zhe-2018da-wang-nian-hui-lt

## エコシステム構築編
やはり開発が込み入ってくると、開発周りのエコシステムもちゃんと構築しておいた方が幸せになれるんですね。
開発者がやることはコードを修正してGithubにPUSHするだけにして、余計な労力をできる限り削る、これが後々効いてきます。
（お仕事の合間や土日などでClovaスキル開発をやられる場合、ちょっとした手順もシンドイと感じてきます。また多忙で開発からしばらく離れてしまうと手順を忘れたりと。。）

デプロイされるコードが必ずGitHubリポジトリの最新から持ってくることが約束されている点も良いポイントです。
手動デプロイだと間違えて一世代前のコードをデプロイしてました（汗）なーんてこともあるのではないでしょうか。
そんな状態で動作確認をしても完全に無駄になってしまいます。（ちょっとしたパニックになりますね 笑）

### AWSを用いたエコシステム（Lambda）
https://github.com/mochan-tk/clova-handson-20180904/tree/lambda-deploy

AWS環境でCI/CDができる方法を記載しています。
**GitHubに修正したコードをPUSHすると自動的にLambdaにデプロイ**されます。
AWS CodeStarを用いて構築の難易度を下げる工夫を入れています。

### GCPを用いたエコシステム（GAE）
https://github.com/mochan-tk/clova-handson-20180904/tree/gae-cloud-build-type

GCPのCloud Build を使って CI/CDを実現しています。
実は自分が公開している**「動物鳴き声クイズ」スキルはGCPのテクノロジーによって支えられている**んですね。

## まとめ
いかがでしたでしょうか。
こういった既に動いた実績のあるコードをベースに自分のやりたいことにコードを置き換えていくと
労力を抑えて効率よく開発ができると思っています。

私が公開しているリソースに関してはどんどん使っていただいて大丈夫ですので**是非パクってください!**
*（テンプレートは数ヶ月前からあまりメンテナンスできていないので、もしよろしければUPDATEしていただけると助かります 笑）*
エンジニアこそ説明力を磨かないといけない

エンジニアをやっていると、誰かから「それすごいね、私にも教えて！」と言われる機会もあるかと思いますが、説明ってすごく難しいです。特に技術関連の説明は本当に難しい。専門用語を初心者でもわかるようにアナロジーを用いて如何に説明するかについてはいつも頭を悩ませています。

これからの時代は(すでに)あらゆる業界にITが入ってきており、技術がわかる人は、技術がわからない人に対して、説明をする機会も増えていく気がしています。特に、技術にとても詳しいエンジニアこそ、説明力を磨かないといけないと思います。

自分は、主に初心者を対象にした、プログラミング関連の講師を約1年間担当していたので、普段からいかに人にわかりやすく伝えるかを意識する機会は多くありました。今回は教える関連の知識をある程度体系化できた気がするので、メモとして残しておきます。

## 説明対象者の事前状況の確認
<img width="730" alt="スクリーンショット-2018-11-24-10.49.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/124924/7c060084-8db5-e6aa-61d4-4f49e1e9d98d.png">


説明する時って最初から説明しちゃいけないんですよね。まずしなきゃいけないのは説明対象者が、説明対象についてどれくらい理解しているのかを確認することです。説明対象Aを理解するために前提知識として何が必要かを自分の頭の中で確認した後に、相手にその知識があるかどうかを確認して、ない場合には前提知識を相手に共有しなければいけません。「説明する前に、〇〇について知ってますか？」という風に、基本的には問答式で相手の理解力を確認し、その知識について説明をしてから本題の説明をする必要があるのです。

具体的に自分が前提知識を共有する際には、「前提として～」というフレーズをよく使っています。

## 範囲の確認(説明対象の確認)
<img width="730" alt="スクリーンショット-2018-11-24-10.50.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/124924/775fc8f2-335a-15a4-067b-96940e34f798.png">

前提知識を共有することができたら、次にすることは、自分の説明の範囲、すなわち説明対象を確認することです。自分は今から何について話すのかを相手に共有することによって、相手の頭の中で準備が行われて、スムーズに説明を聞いてくれるようになります。逆に共有がない状態だと、説明対象者の頭の中には「今何話しているんだろう」という疑問が生まれてしまって、説明がうまく伝わらないケースが多い気がします。

具体的に自分が説明対象を確認するときには「今から話すことは～についてなんですけど～」っというフレーズをよく使っています。

## 説明ポイントを分けて、わかりやすく説明
<img width="730" alt="スクリーンショット-2018-11-24-10.50.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/124924/ea69f9a2-58cf-b4ad-dd23-dfe97a61424a.png">

説明対象の確認ができたら、次にすることは説明対象を説明するために、わかりやすく説明ポイントを分けることです。

### 説明ポイントを分ける
例えば、四則演算を人に説明するときに一気に説明することって難しいですよね。足し算、引き算、掛け算、割り算に説明のポイントを分けて説明することになると思います。
要は説明対象を因数分解して、ポイントを作り、そのポイントを順に説明していくことができれば良いです。

自分が説明する時は「〜を理解するためには重要なポイントが〜個あって〜」みたいな感じで使います。ただ、各ポイントを説明する際に気をつければいけないポイントがいくつかあります。

### 基本的には定義→何ができるか→例示
説明をするときには基本的には上記の順番でやるとうまくいきます。特に例示の部分が重要で、これは各個人に合った形で最も最適なアナロジーを用いないといけません。相手の地頭の良さや理解度、バックグラウンドをしっかりと確かめて説明する必要があると思います。個人的に説明するときに相手の理解度に大きな影響を与えるのはこの部分だと思っています。

### 情報量を意識すること
情報量は意識しないといけません。相手に必要以上の情報を与えると、相手の理解が追いつかなくなり、逆に何も伝わらなくなる可能性があります。自分の場合は、説明対象の新知識の理解が前提知識となる新規の知識についてはその場では説明をせず、「今はひとまず理解できなくていいよ」と言ってスキップしています。

### スピードの調整をすること
話すスピード意識しないといけません。説明が早いと、相手が理解に追いつかず、結果何も理解できなかったという事態が起こりかねません。相手の表情や雰囲気を感じ取った上で、適宜スピードは調整しましょう。

### わかりやすい言葉を使うこと
相手が理解できないカタカナや、四字熟語はあまり使わないようにしたいですね。よく言われることですが、小学生でも理解できるレベルの言葉を使うように心がけるといいと思います。

### 理解度の確認は忘れない
説明している最中に、相手の理解度を確認をすることは非常に大切です。基本的には問答式で確認するのがいいと思います。自分の場合は「～についてどう思います？」って感じで相手にひたすら考えさせることを意識して説明したりしています。

## 最後に簡単にまとめる
<img width="730" alt="スクリーンショット-2018-11-24-10.51.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/124924/30d81fda-a1b6-79c4-7ff0-40dc8cdd7e54.png">

最後に簡単に説明したことをまとめます。以下のようにまとめればうまくいくかと。

- 説明対象の再確認
- 重要だったポイントについて
- 質問を聞く

最後に説明を体系的にまとめてあげて、質問がないかどうかを確認します。自分の経験則的に上記のように説明をすると、うまくいく気がしています。

もちろん現在も、上記の説明プロセスはブラッシュアップをしています。また何か気づきがありましたら、追記したいと思います。
elasticsearch6ではまったところメモ



# ディスク容量が敷地を超えるとread-onlyになった

read-onlyの解除

```
$ curl -XPUT -H "Content-Type: application/json" http://localhost:9200/_all/_settings -d '{"index.blocks.read_only_allow_delete": null}'
```

以下の記事を参考にしました。
https://qiita.com/micci184/items/5d8a4abd3dafc045d29c

# Xmxの値を変更したら動かなくなった・・

XmxとXmsは同じにしないとダメなようだ

https://www.elastic.co/guide/en/elasticsearch/reference/current/heap-size.html

# offset 10000以上を指定するとエラーになる

10000以上を返したい場合は以下のパラメータ設定を変える必要あり

index.max_result_window

https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html
docker-nginx-rtmpとiPhoneでお手軽マルチカメラライブストリーミング配信環境の構築

# はじめに

[呉高専 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/kurekosen) 22日目の記事です。

始めまして？、呉高専のVue.jsが大好きなkobakazu0429です。

「ライブストリーミング配信をする（かもしれない）」ということで、dockerを使って簡単に環境構築をしてどんなものかを試してみたいと思います。

> 本来は Vue.js + Vuex + OpenLayersで記事を書こうと思ったんですけど、思ったより書くことがなかったので変更です...

ざっくりとしたアーキテクチャはこんな感じです
<img width="80%" alt="プレゼンテーション1.png" src="https://qiita-image-store.s3.amazonaws.com/0/197122/a375cfad-7782-c742-7328-9325023267e0.png">

今回使用するURLは以下の通りです

|パス|ストリームキー|用途|
|---|---|---|
|/live|test|配信用|
|/live|iphone1|iPhone 1の映像送信用|
|/live|iphone2|iPhone 2の映像送信用|
|/live/iphone1||iPhone 1の映像受信用|
|/live/iphone2||iPhone 2の映像受信用|

# 実行環境
```
MacBook Pro (15-inch, 2017)
プロセッサ ： 3.1 GHz Intel Core i7
メモリ ： 16 GB 2133 MHz LPDDR3
グラフィックス ： Radeon Pro 560 4096 MB, Intel HD Graphics 630 1536 MB
```

```shell
$ docker -v
Docker version 18.06.0-ce, build 0ffa825
```
# nginx-rtmp
Docker for Macの導入は飛ばします。
Mac以外をお使いの方は適宜読み替えていただけたらと思います。

今回はDocker Hubで公開されている[tiangolo/nginx-rtmp](https://hub.docker.com/r/tiangolo/nginx-rtmp/)を使います。
tiangoloさんに感謝です！

次の1行を実行するだけでサーバー構築は終了です。
お手軽ですね！

```shell
$ docker run -d -p 1935:1935 --name nginx-rtmp tiangolo/nginx-rtmp
```

# OBS Studio
次は[OBS Studio](https://obsproject.com/ja)を環境に合わせてインストーラーをダウンロードし導入しましょう

OBS(Open Broadcaster Software) Studioは、各種ライブ配信サイトで使用できる無料の配信ソフトです。
また、それだけでなく、複数の動画の合成、テロップ、画像の挿入などをリアルタイムに配信しながら配信することができます。

## 配信設定
設定→配信から「配信種別：カスタムストリーミングサーバー」を選択
URLは`rtmp://<IP Address>/live/`です。
ストリームキーは自由に設定してください。これは後から配信を見るときに使われます。
<img width="982" alt="スクリーンショット 2018-12-21 15.37.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/197122/e6275f90-53ea-1e13-ea11-9fab4f4c5872.png">


## 配信用カメラ設定
今回はiPhoneの映像をWi-Fi経由で受け取り、それを配信します。
メディアソースを新規追加し、ローカルファイルのチェックを外します。
入力に先ほどのURLと末尾に名前を適当につけます。
このURLはあとでiPhone側の設定で使うので覚えておいてください。
入力フォーマットは`rtmp/mp4`です。
<img width="682" alt="スクリーンショット 2018-12-21 14.24.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/197122/80dd52c6-e4cc-6cc2-f532-b309174354e3.png">

このメディアソースは使いたいiPhoneの数だけ追加します。

# Switcher Studio
今回はお試しなので[Switcher Studio](https://www.switcherstudio.com/)というアプリを入れます。
会員登録、ログインをしたら
`Use as Swicther`を選択
設定→Outputs→Custom RTMP、新規作成をします

<img src="https://qiita-image-store.s3.amazonaws.com/0/197122/a7b61e8c-d67a-b859-12d9-a4498926e88a.jpeg" width="40%">

`STREAM KEY/ID`はさっきOBSで設定した通りにしてください。

※ 複数カメラを用いる場合は、`Remote Camera Mode`を選択し、一つの端末に映像を集約するか、
それぞれを別アカウントにして、OBS側で処理するかの2択になると思います。
同一アカウントを使ってログインすると片方のアカウントが自動でログアウトされてしまいます。

# VLC(再生プレイヤー)
今回はwebではなくVLCを使って再生します。
RTMPサーバーからストリーミングで受信できればどのプレイヤーでも構いません。
ネットワークから、OBSの配信設定で設定したURL`192.168.137.62/live`を使って受信します。
<img width="607" alt="スクリーンショット 2018-12-21 15.44.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/197122/9f89b647-c1f5-be2b-ce0a-c4fb2c0770be.png">

これで再生できたら成功です！

# 最後に
お疲れ様でした！
駆け足の記事なってしまいましたがいかがだったでしょうか？

これで誰でもお外からライブニュースごっこができますね！

それでは明日のeuglena1215先輩による「つくったものの紹介」を楽しみに！


P.S. 何かあればコメント等でお願いします🙇‍♂️🙇‍♂️🙇‍♂️
Dockerでrunしたnginxにアクセスできない

#はじめに
docker触り初めでしてしまったミスがあったのでメモ。

```
$ docker pull nginx:latest
latest: Pulling from library/nginx
Digest: sha256:5d32f60db294b5deb55d078cd4feb410ad88e6fe77500c87d3970eca97f54dba
Status: Image is up to date for nginx:latest

$ docker run -d -p 8080:80 --name test nginx
<id~>
```
そしてlocalhost:8080にアクセスしたところ「localhost で接続が拒否されました」と表示されました。
#原因
dockerでコンテナを起動しアクセスする場合dockerのアドレスにアクセスする必要があります
#解決法
以下のコマンドでIPを確認。その後アクセスします。

```
$ docker-machine env
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://~~"
export DOCKER_CERT_PATH="C:\Users\tiger\.docker\machine\machines\default"
export DOCKER_MACHINE_NAME="default"
export COMPOSE_CONVERT_WINDOWS_PATHS="true"
# Run this command to configure your shell:
# eval $("C:\Program Files\Docker Toolbox\docker-machine.exe" env)

$ docker-machine ip
<ip>
```
そして「表示されたアドレス+:8080」にアクセスすると無事表示されました
VRChatでアバターがPersonalに出ないとき【解決】

#前提
まずは下の画像左側、上のAVATARタブを選択した状態なのですが、「Public」「Find more avatar」しか欄がありませんね？VRChatへアバターをアップロードしたのに、何らかの理由で「Personal」表示が出ない。そこで躓いている人向けの記事です。
![名称未設定13.jpg](https://qiita-image-store.s3.amazonaws.com/0/175472/1b4fc29d-888d-a71f-2f55-6034916cd82d.jpeg)
※
導入モデルは違いますが、このあたりの記事が通常のアップロードでは参考になります。
http://keiki002.com/vr/booth-vrchat/#Unity

#状況
私の場合、購入した ”そのままVRChatにアップロードできます。" と書いてあったunitypackageファイルをUnity 5.6.3p1 (64-bit)で開きVRChatへアップロード。が、うまくいかない！UnityからVRChatへ登録まではされているのに！
![名称未設定-12.jpg](https://qiita-image-store.s3.amazonaws.com/0/175472/a45debbd-b1f1-6b65-39d2-3c6f9a53ded4.jpeg)

モデルが準備できている状態から一つ目に試したのはBluePrintIDの空欄化です。UnityのAdd componentからVRC Pipeline ManagerでDetachを押すとこの画像の状態になります。
![名称未設定14.jpg](https://qiita-image-store.s3.amazonaws.com/0/175472/ee9f8ea9-a277-a051-0963-b7256a18e169.jpeg)
ですがこれで解決しませんでした。


##VRChatへVRChatアカウントでログインする
解決方法はTwitterに呟きがありました。VRChatへのログインを「Steamアカウント」でしてしまっていたようです。（日本wikiにもその旨書いてありました…）アカウント変更はゲームログインした状態で行うため、Non-VR modeがやりやすいでしょう。SteamアカウントでVRChatにログインしている場合、VRChatアカウントにアップロードしたアバターは使えず、メニューを開くと以下の表示になります。Steamアカウントでのログインはアカウントネームの後ろに４文字、ランダムナンバーが割り振られていますのでこれでログイン中のアカウントを判断してください。
![名称未設定15.jpg](https://qiita-image-store.s3.amazonaws.com/0/175472/3d638dea-a241-4c77-257d-febbdea77ca3.jpeg)
Steamアカウントでログインしている事が確認できたら、以下の画像のようにログアウト、VRChatアカウントで再ログインします。
![名称未設定16.jpg](https://qiita-image-store.s3.amazonaws.com/0/175472/ae80b9a2-ceb5-5a4f-27bc-29f58805aac5.jpeg)

VRChatアカウントでログインすると、アップロードしたアバターがPersonal欄に表示されるはずです！
![名称未設定-3.jpg](https://qiita-image-store.s3.amazonaws.com/0/175472/51fd5452-dc85-7151-e36f-0cffd124ac3d.jpeg)

PS
公式はよく読みましょうorz
[VRChatはsteamのアカウントでもログイン可能ですが、アバター/ワールドをアップロードする為にVRChatのアカウントが必要です。]https://vrchatjp.playing.wiki/d/%bd%e9%bf%b4%bc%d4%a5%ac%a5%a4%a5%c9%20%28%a4%e4%a4%eb%bb%f6%a4%de%a4%c8%a4%e1%29
アップロードのために必要というか、VRChatアカウントでログインした時しか自作アバターは使えません、という感じです。

お疲れさまでした！
徐々に増えていた擬似クラスの世界

ひょんな拍子に[MDNの擬似クラスのページ](https://developer.mozilla.org/ja/docs/Web/CSS/Pseudo-classes)を覗いてみたら、思いの外大量にありました。

## 入力フォーム関係

`:checked`はチェックボックスやラジオボタンがチェックされている場合に有効となります。ラベルなどで自前描画している場合には便利です。

`:required`や`:optional`は、入力フォームの必須状態に依存する擬似クラスです。「必須なフォームだけ色を付ける」としてもいいかもしれません。

`:valid`、`:invalid`、`:in-range`、`:out-of-range`は、フォームバリデーションに関する値です。隣接セレクタと絡めれば、「`invalid`なときだけ文言を表示」ということも、CSSだけで可能です。

## 複雑なセレクタを構築する

まだあまり普及していませんが、`:is()`というセレクタがあって、カッコの中にカンマ区切りでセレクタを並べることで、「どれか1つ」を表現することができます。

```scss
h1, h2, h3, h4, h5, h6 {
  a{
    /* 内容は省略 */
  }
}

/* :isを使えば、SCSSなしで同じものを書ける */

:is(h1, h2, h3, h4, h5, h6) a{
  /* 内容は省略 */
}
```

IE11が非対応なこと、Firefoxが`:-moz-any`という名前でないと動かないことなど、実用にはちょっとステップが必要そうですが、セレクタの組み合わせ爆発を回避できそうなのは便利です。

## まだ実装はないけれど

提案中で使える環境はないのですが、`:has(セレクタ)`として、**子孫要素を条件として**親要素を選べるセレクタも、将来的には実装されるかもしれません。
Cloud Native Computing FoundationとMicrosoft、そしてCNABのコンセプト

## はじめに

今年も年末で残すところあと僅かですがいかがお過ごしでしょうか？年末最後のイベントとしてConnect();２０１８に少しだけ（５分ｗ）登壇してきました。その内容も踏まえて記事を書こうと思います。

## Cloud Native Computing Foundation（ https://www.cncf.io/ ）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/55285/392fd6a1-0fbf-fd53-6f45-abebab8e1061.png)

もうこちら皆さんもご存知かと思いますが、略してCNCFは、マイクロサービスアーキテクチャの一部であるオープンソースのコンテナエコシステムを持続的に構築することを目的としていますね。マイクロサービスアーキテクチャといえば、非常に難解で運用も難しいと揶揄されますが、KubernetesやService Fabliｃ、Java Springなどだけではなく、構築、運用に必要な要素/コミュニティを支援してきていますよね。
その様子は、CNCF landscape（　https://landscape.cncf.io/ ）をご覧になると良いと思います。いつの間にかlandscapeがinteractiveになって公開されていますね。更新が早くこちらをで更新していくのが良いとされたのでしょうか？（もしかして昔からあった？）もちろんgithubの方には、pdf、ai、tiff、jpgなどで画像がuploadされております。（ https://github.com/cncf/landscape ）

## Microsoft
そして、最近のMicrosoftはGitHubを買収するなど、いろいろと話題なることが増えましたよね。Open Sourceの取り組みを加速していったけっか、GitHub上のactivityでも上位に登るなど凄まじい勢いで変化を続けています。（社内の情報（出せない情報も含む）を見てると肌でそのことを感じます）

## CNCF x Microsoft
先程landscapeをMicrosoftで抽出するといくつかのものが出てきますね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/55285/669a6807-d430-5397-d421-82e792ae0a55.png)

OSSのものでいうと

- `ACS Engine`( https://github.com/Azure/acs-engine )  / `AKS Engine`(https://github.com/Azure/aks-engine )
`Azure/AzureStack`で`Kubernetes`環境を構築するためインストーラ
- `Azure Service Fabric`( https://github.com/Microsoft/service-fabric )  
Microsoft謹製のMicroservice（Container）オーケストレーションソリューション
- `Brigade`（https://github.com/Azure/brigade ）  
JavaScript Scriptingと設定可能なWebhook、パイプラインなどの定義ができるもの、後ほど紹介するCNABと似たような部分もあり。
- `Draft`（https://github.com/Azure/draft ）  
`kubernetes`用のArtifactの作成とリリースを担うもの、後ほど紹介するCNABと似たような部分もあり。

## Cloud Native Application Bundle(CNAB)
`Connect2018();`の日本イベントにて少しお話しましたが、CNABというものが発表されました。

`Azure DevOps（VSTS）`/`Azure Pipeline`などを使って複数のOSSツールを組み合わせてなにかシステムを構築すること(Pipelineを設定し、デプロイすること)、アップデート（ソースコードを変更してPush、CIまわして、CDとか）することも可能です。例えば、`Azure DevOps` + `Jenkins` + `Maven` + `Azure WebApp`とかも簡単にできます。

さて、Micro Serviceな場合はどうでしょうか？Kubernetesクラスタを作ったり、`Kubernetes`で使う、`Persistent Volume`の
ためにManaged Serviceを使ったりVM上にansibleでMySQLクラスタを構築したり、いろいろと手順的にまとめる＝パイプライン化するのは、難しかったりします。

また、それぞれ誰がそのxxx as Codeを作ったのか責任を持つことは少々難しかったです。


CNABではそれを下記のような方法で回避します。

1. それぞれのツールを`bundle.json`でまとめる
2. PGPを使い、`bundle.json`にsignして`bundle.cnab`とする

PGPという公開証明書基盤を使ってSigningするということで安全を担保したりします。厳密に言えば、誰というか、誰のコンピュータで作られたかということですね。もし、このPGPを強固にしたければ`YubiKey`などを使うと良いでしょう。（`YubiKey`が無いとSingできないなど）

つづく（時間がなくてここまでしかまとまりませんでした（汗）)
開発の人からテストの人になってわかったこと

### はじめに

私は10年以上、開発をやってきて、急に思い立って、3年前にテストを専門で行う会社にキャリアチェンジした人です。開発者として、プログラマーから始まり、要件や仕様を決め、設計をするエンジニア、プロジェクトを率いるプロジェクトマネージャーと、一通りのロールを経験してきました。エンプラ系に特化しているものの、新規開発からリリース、その後のエンハンスというように、一通りの開発を経験してきました。というバックグラウンドを持っています。

開発経験はあるものの、今の会社に入った時には、テストを専門でやってきている同僚に囲まれてやっていけるのか、という不安がありました。実際の仕事の中で、テスト設計やマネジメントの話をする中でも、同僚たちと自分との間で、ちょっとしたことが考え方が違うなーという違和感も感じていました。

そういう不安があったので、入社してしばらくは、周りの同僚の発言や考え方を観察してみることにしました。自分の考えとの違いを知って、微調整していけば、それっぽくなるのではないかな、と思いました。
そうすると、なんとなく、開発者とテストエンジニアの考え方の違いがわかってきました。

今回、私の気づいたことを紹介したいと思います。

ちなみに、開発の人とテストの人のどちらがいいとか言っているわけではありません

### なぜこれを書くか

　開発エンジニアからテストエンジニア、開発マネージャーからテストマネージャーへのキャリアチェンジをした人、または、キャリアチェンジをしたい人は、結構いるように感じます。
　その一方で、開発の人とテストの人のテストの考え方は違う、と聞くことがあります。しかし、具体的にどういう違いがあるのか、ということについて、直接的に語られている投稿が少ないように感じたため、私の気づいたことが誰かの参考になればと思って、今回紹介したいと思います。

### 読んでもらいたい人

- 開発の人からテストの人へキャリアチェンジを考えている人

### テストの人はここが違う！

私自身の気づきが多かった、

- テスト設計
- テストマネジメント

の２つの活動について、あー、テストの人ってこういう風に考えるのか！、と気づいたことを紹介します。
他の話も探せば色々あると思うけど、私の気づきが大きかったものを挙げます。

ちなみに、ここでの「テスト設計」は、JSTQBのFLの「テストの分析と設計」らへんの活動を意図しています。

### テストの人のテスト設計

 1. テスト対象を色々な視点で見る
 テスト対象を単に仕様書に書いてある機能単位とか、業務単位で見るだけで終わらせず、自分たちの独自の視点で切り取って表現していると思います。それは、モデリングを使ったり、マインドマップに書いたりとまとめ方はいろいろだけど、そこには自分はテスト対象をこういう風に理解しています。が入っているように感じました。
 私が開発をやってた時は、何の疑いもなく、開発する単位（機能の単位とか）のただ１つの視点でとらえて、テスト設計をしていたので、ここは違うなと思いました。

 1. 抽象度の上げ下げができる
　テスト対象を表現するときや、テスト観点を挙げるときなど、抽象的⇔具体的の調整を意識してやっていると感じます。初めてこのような考え方に触れたときには、そんなに気にするのことなのか？と必要性がよくわかっていなかったけど、とらえたいことを正しくというか、意図したとおりに表現するには、同じ抽象度で表現することが必要なんだろうと理解しています。

 1. テストケースの目的を考える
　１つ１つのテストケースの目的というか何を確認したいのか、をはっきりさせるというのも、やっている人が多かったです。テストケースの目的がはっきりしていないと、そのテストケースがOKだったら、何がOKといえるのかがよくわからなくなり、周りに説明ができないということなのだろうと理解しています。これも入社したてのころは、「確かにテストケースの目的ははっきりさせたほうが良さそうけど、どんな良いことがあるの？、やらないとまずいことがあるの？」ということが腹落ちしていなくて、モヤモヤしている時期がありました。

### テストの人のテストマネジメント

　開発マネージャーの立ち位置としてのテストと、開発チームとは別のテストチームのマネージャーという立ち位置の違いは、裁量でどうにかできる部分が多いか少ないか、だと思います。
テストマネージャーの場合、自分の配下のテストチーム以外の要因で、良くも悪くもなる部分が大きいです。例えば、開発チームが作成した成果物の出来栄えとか、環境構築担当の進捗度合とか。
そういう中、周りのテストマネージャーたちは、プロジェクトマネジメントの活動の中でも、この2つの要素を重視していました。

 1. リスクマネジメント
　自分のテストチーム以外が担当する活動に関するものに対して、リスクを上げて、テストの計画に織り込めるかどうか。
 自分のチームの外の話だから、情報を取りに行って、リスクがあるか、そのリスクの影響などを考えて、計画に織り込んでいくという、自ら動いていくということです。
 
 2. コミュニケーション
　上のリスクマネジメントと同じく、自分のテストチーム以外のチームに情報を取りに行き、テストに関する活動に活かしていくということです。たとえば、テスト設計をするには、プロダクトやシステムの情報を開発チームから入手するだろうし、テスト実行の準備をしているときには、開発チームや環境構築チームの作業の進捗状況も気にするということ。

　開発プロジェクトのプロジェクトマネージャーの経験があれば、テストチームのマネージャーもできるんじゃ・・・と思う人もいるようだけど、その人の得意分野、不得意分野によっては、「テストチームのマネージャーのほうが難しいなー」という人もいると私は思います。

　ということで、ニッチなテーマではありますが、開発の人からテストの人にキャリアチェンジした私が気づいたことを紹介しました。個人の見解ではあるけど、誰かの参考になればうれしいです。読んでいただいて、ありがとうございました。
`cannot connect to X server` が出たときの確認することと直し方

### 背景

Ubuntu 18.04 (Server)に LXDE+XRDP環境を作り、WindowsからRDP接続した上で、GUI操作を行うプログラムを実行しようとした際に掲題のエラーが発生した。

じゃあ今このPCからリモートデスクトップ接続して見えている画面は何なんだよ！と思いながら調べた。

原因は環境変数のDISPLAYと実際の仮想ディスプレイ番号があっていないからだった。なぜ合わなくなったのかはわからない。ただ、環境変数を合わせれば動くようになったので、その直し方を書いておく。


### 直し方

- **CUI操作ではない**ことを確認する（SSH接続の場合、`env | grep DISPLAY`等で環境変数DISPLAYが設定されていない）
- 以下のいずれかを確認し、操作に使っているディスプレイ番号を把握する
    - `ps -ef | grep Xorg` で自分が実行者のプロセスがあり、そこから確認する（引数に`:10`の存在が確認できれば、10がディスプレイ番号になる）
    - `ls -l /tmp/.X11-unix` で自分が所有者のUNIX Domain Socketのファイルがあり、そこから確認する（例えば`X10`があり、その所有者が自身であれば10がディスプレイ番号になる）
- 環境変数 `DISPLAY` があり、上記の2つのいずれかで表示されたディスプレイ番号が指定されているか確認する（例: ディスプレイ番号=10ならば、`:10`もしくは`:10.0`など）

環境変数 `DISPLAY` が正しく設定されていない場合、`export DISPLAY=:10` という形で設定してからプログラムを実行する。


### 蛇足

`export DISPLAY=:0` をやれば解決した、というだけの記事をしばしば見かけたが、解決できなかったので調べて書いた。

X Window Systemについては`man X`で結構色々書かれてる。全然読み解けなかった。分かったのは下記ぐらい。

- X Window SystemはUNIX domain socket接続（ローカル接続）、TCP接続（リモート接続）を選べる。
- 環境変数`DISPLAY`のフォーマットは`hostname:displaynumber.screennumber`で、hostnameとscreennumberは省略可能。`:displaynumber`が最小限必要で、hostnameは空文字列扱いでUnix domain socket接続となり、screennumberは0と同じ意味だそうだ。

xorgは X Window System の実装の一つなので、`ps -ef | grep Xorg` で確認できない環境があるかもしれない。（xorg以外というとwaylandとか？使ったことが無いので分からない。）
webスクレイピングを色々試したらseleniumに行きついた。

#背景
nokogiriやmechanizeでパースしてからxpathを指定で要素を抜き出そうとすると、そのまま動くときと空の配列が返ってくるときがある。
そして、悪いことに目的のサイトでは空の配列が返ってきてしまうパターンだった。

なので色々と調べたところ、目的のサイトでjavascriptが動いているのが良くないらしく、nokogiriとmechanizeでサイトをパースする段階ではjavascript実行前のソースを読み込んでおり、chromeのdevtoolなんかで取得できるxpathは、javascript動作後の動的にhtmlタグが変更された後のものであることが判明。
→存在しないxpathを指定することになるので、空の配列が返ってくるのは期待された動作ということみたい。

p agent.get.bodyを見る限り、欲しい情報はすでに含まれていたので以下の二通りのやり方を検討した。
1.ソースコードから欲しい情報をどうにか指定して抜き出す
2.javascript動かしたあとのhtmlをパースして、chromeなんかで拾えるxpath使う

ざっくり検索かけると、2.のパターンの情報のが多く楽なやり方っぽい。
つまり、seleniumを使うといいらしい。

#seleniumで書いたコード


```ruby:test.rb

#! ruby -Ku
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome
driver.navigate.to '目的のサイトのログインページ'

id = driver.find_element(:xpath,'//*[@id="login_box"]/form/dl/dd[1]/input')
pass = driver.find_element(:xpath,'//*[@id="login_box"]/form/dl/dd[2]/input')

id.send_keys("自分のID")
pass.send_keys("自分のパスワード")

driver.find_element(:xpath,'//*[@id="mainsubmit"]').click
wait = Selenium::WebDriver::Wait.new(timeout: 3)

driver.navigate.to '目的のページ'
wait = Selenium::WebDriver::Wait.new(timeout: 3)

sinchaku = driver.find_elements(:xpath,'//*[@id="main"]/form/table/tbody/tr[1]/td[2]/a')
sinchaku.each do |i|
    puts i.text
end

```

ほとんど拾い物のコードだけど、javascriptで描画されるサイトで期待通りに動作することを確認できた。
ブラウザで操作する順番で、上からそのまま書いていき、操作したい要素はchromeのdevtoolなんかで見れるxpathで指定していくだけだから簡単。
上記の例だと最後に新着情報の一覧をfind_elementsでとってくるのだけど、そのまま.textメソッドを繋げると配列に対してはundefined methodだと怒られるので、eachで一個づつ要素を取り出して.textメソッドを繋げるとうまくいった。
expectコマンドを使用してpg_dumpのパスワード入力を自動化する

# はじめに

環境は以下のとおり
- Centos6.7
- PostgreSQL9.4.6

# やりたいこと

以下のPostgreSQLのダンプ処理をシェルで実行させたい。

```shell-session
sudo pg_dump -a -Fc -h xxx.xxx.xxx.xxx -p 5432 -U db_user sample -n public -f /tmp/dump.sql
```

# expectコマンドによる実現

上記のダンプ処理を実行する場合、バッチ実行ユーザ(batch_user)とPostgreSQLユーザ(db_user)の両方のパスワードの入力が必須となる。

```shell-session
[sudo] password for batch_user:
パスワード:
```

このパスワード入力について、省略もしくは自動入力化する必要がある。

PostgreSQLユーザのパスワードを省略したい場合、[パスワードファイル](https://www.postgresql.jp/document/9.4/html/libpq-pgpass.html) を使用するやりかたもあるが、今回はバッチ実行ユーザのパスワード入力も省略させたい。

なので今回は、以下のようにexpectコマンドを使用し、２つのパスワードの自動入力を実現させた。

```sh:/tmp/auto_dump.sh
#!/bin/bash

#バッチ実行ユーザのパスワード
USER_PWD="xxx"
#PostgreSQLユーザのパスワード
DB_USER_PWD="yyy"

#dump実行
expect -c "
set timeout 5
spawn sudo pg_dump -a -Fc -h xxx.xxx.xxx.xxx -p 5432 -U db_user sample -n public -f /tmp/dump.sql
expect \"\[sudo\] password for batch_user:\"
send \"${USER_PWD}\n\"
expect \"パスワード:\"
send \"${DB_USER_PWD}\n\"
sleep 2
expect \"\n\"
send \"exit\n\"
"
```

# 実行してみる

```shell-session
# ダンプシェルの実行
sh /tmp/auto_dump.sh
spawn sudo pg_dump -a -Fc -h xxx.xxx.xxx.xxx -p 5432 -U db_user sample -n public -f /tmp/dump.sql
[sudo] password for batch_user:
パスワード:

# ダンプファイルの確認
ls /tmp
dump.sql
```