OmniAICreator/Qiita-1.07M huggingface dataset:
Linux Ubuntu aliasは.bash_aliasesに書こう

## 目的

- Ubuntuのaliasを書く際に先輩に教えてもらった事を忘れないようにまとめる。
- aliasの書く場所をまとめる。

## aliasって？

- これを登録しておくとユーザに合わせたコマンドのショートカットの作成が可能になる。
- Ubuntu bashで実行する事のできるコマンド`ll`はすでに`ll`が入力されたら`ls -alF`を実行するようにaliasに登録されている。
- aliasを使いこなすと自分好みのコマンドのショートカットを作成することが可能になる。

## 自分好みのコマンドショートカットを登録したい！どうすればいいの？

- 設定ファイルを直接開き記載してあげる必要がある。
- 設定ファイルは`.bash_profile`や`.bashrc`など複数存在する。
- コマンド`ll`などは`.bashrc`に記載されている。
- 詳しい方法は[mac ターミナル で llコマンドを 実行 できるようにする](https://qiita.com/miriwo/items/a1bf6917dc630fb6d24f)にまとめた通りである。(タイトルはmacになっていますがUbuntuでも同じ方法で実施可能です。)

## aliasは専用の設定ファイルが用意されている

- 実はalias設定のためのファイルがある。
- 初期だと存在しないため、ユーザが作成する必要がある。
- `.bash_aliases`をユーザディレクトリ直下に作成しその中にaliasの設定を記載する事が正しい使い方であるらしい。
- `.bashrc`には`.bash_aliases`がユーザディレクトリ直下に存在したら読む処理が存在していた。(知らなかった)
- 下記に`.bashrc`の一部抜粋した物を記載する。100行目あたりに下記の記載が存在する。

    ```bash
    # Alias definitions.                                                                                                                                                           
    # You may want to put all your additions into a separate file like                                                                                                             
    # ~/.bash_aliases, instead of adding them here directly.                                                                                                                       
    # See /usr/share/doc/bash-doc/examples in the bash-doc package.                                                                                                                                                                                                                                                                                               
    if [ -f ~/.bash_aliases ]; then                                                                                                                                                    
    . ~/.bash_aliases                                                                                                                                                          
    fi 
    ```

## 具体的な実施方法

- shellを先起動させるためのコマンド`exec $SHELL -l`をコマンド`reload`で実行できるようにaliasを`.bash_aliases`に登録する手順を下記に記載する。(※エディタはviをする)

1. 下記コマンドを実行してユーザディレクトリ直下に移動する。

    ```terminal
    $ cd
    ```

2. 下記コマンドを実行してユーザディレクトリ直下に`.bash_aliases`ファイルを作成する。

    ```terminal
    $ vi .bash_aliases
    ```

3. 開いた`.bash_aliases`ファイルに下記の内容を追記する。

    ```
    alias reload='exec $SHELL -l'
    ```

4. terminalで下記コマンドを実行してaliasが登録されていることを確認する。

    ```terminal
    $ reload
    ```

5. 前述のこまんどを実行して`command not found`などが出なければ正常にaliasが登録されている。
Office365のPowerPlatform製品のセルフ購入機能のリリースについて

#はじめに
2019.10.31にMicrosoftからPowerPlatform製品のセルフ購入機能のリリースが発表されましたね。

2019.11.20にPowerShellによる無効化の方法を通知されたので、そちらの内容をまとめます。

#概要
MSCommerce powershell モジュールを用いて、セルフ購入機能の設定状態の表示と無効化ができます。

#必要なもの
・windows10デバイス
・デバイスに対する管理者のアクセス許可
・テナントにおけるグローバル管理者か課金管理者の権限

#全コマンド
####モジュールのインストール

```
Install-Module -Name MSCommerce
```

####モジュールをpowershellセッションにインポート

```
Import-Module -Name MSCommerce
```

####モジュールに接続する（管理権限を持つユーザー名・パスワードが必要）

```
Connect-MSCommerce 
```

####今の有効/無効状態の確認

```
Get-MSCommercePolicy -PolicyId AllowSelfServicePurchase 
```

####全てのセルフサービス購入可の製品の状態と各製品の状態の確認

```
Get-MSCommerceProductPolicies -PolicyId AllowSelfServicePurchase 
```

表　使用可能な製品とProductId

|Product|ProductId|
|---|---|
|Power Apps per user|CFQ7TTC0KP0P|
|Power Automate per user|CFQ7TTC0KP0N|
|Power BI Pro|CFQ7TTC0L3PB|

####特定の製品の設定状態を取得

```
Get-MSCommerceProductPolicy -PolicyId AllowSelfServicePurchase -ProductId CFQ7TTC0KP0N
```

####特定の製品のセルフサービス購入を有効にする

```
Update-MSCommerceProductPolicy -PolicyId AllowSelfServicePurchase -ProductId CFQ7TTC0KP0N -Enabled $True
```

####特定の製品のセルフサービス購入を無効にする

```
Update-MSCommerceProductPolicy -PolicyId AllowSelfServicePurchase -ProductId CFQ7TTC0KP0N -Enabled $False
```


####無効にするコマンド例
モジュールのインストール、インポート、接続をします。

```
Install-Module -Name MSCommerce
Import-Module -Name MSCommerce
Connect-MSCommerce
```

無効にします。'Power Automate'の部分に無効化したいアプリケーション名を入力して実行します。

```
$product = Get-MSCommerceProductPolicies -PolicyId AllowSelfServicePurchase | where {$_.ProductName -match 'Power Automate'}
Update-MSCommerceProductPolicy -PolicyId AllowSelfServicePurchase -ProductId $product.ProductID -Enabled $false
```

もしくは、下記コマンドでもそれぞれの無効化が実行できます

```
Update-MSCommerceProductPolicy -PolicyId AllowSelfServicePurchase -ProductId CFQ7TTC0KP0P -Enabled $False  #PowerApps

Update-MSCommerceProductPolicy -PolicyId AllowSelfServicePurchase -ProductId CFQ7TTC0KP0N -Enabled $False  #PowerAutomate

Update-MSCommerceProductPolicy -PolicyId AllowSelfServicePurchase -ProductId CFQ7TTC0L3PB -Enabled $False  #PowerBIPro
```


#最後に
無効化できたでしょうか。

最後に先述の「全てのセルフサービス購入可の製品の状態と各製品の状態の確認」を実行し、ご確認ください。

```
Get-MSCommerceProductPolicies -(PolicyId) AllowSelfServicePurchase 
```
すぐに役立つRails tutorial メモ　「デバッグ」

##何かわけのわからない挙動やエラーが見受けられた時に役に立つのがdebug メソッド

```
class UsersController < ApplicationController

  def show
    @user = User.find(params[:id])
    debugger
  end

  def new
  end
end
```

**debugger**をshowアクションの中に入れることで、ターミナルにてbyebugプロンプトを確認することができます。

debugをやめたい時にはCtrl-Dを押すとプロンプトから抜け出すことができます。

***debugメソッドを使うにはbyebug gemをインストールしている必要があります！***
設計書をMarkdownで作成し、フィードバックループに乗せる

# 概要
以前、業務で設計書を作成する際に行った改善活動をまとめます。
その現場では、設計書をスプレッドシートで作成するという悪習があったため、
設計書をMarkdownで作成するように変更し、gitで管理できるようにしました。
また、その現場の社内用gitlabではplantumlを画像として表示する機能が提供されていなかったため、
jenkinsを使ってplantumlをsvgに変換、Markdownと共に別サーバに転送し、
docsifyというツールでhtmlとして参照しました。

全体の概要図は次の通りです。
![overview.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534316/8503949a-055c-cd3d-a391-c6e31f134ac6.jpeg)

# 説明
### ①gitへpush
ローカル環境で編集したMarkdownファイルをgitのリモートリポジトリへpushします。

### ②pushにhook
①のpushイベントにhookさせてjenkinsのjobを起動させます。
webhookはgitlabの各リポジトリーの設定画面から設定可能です。
https://docs.gitlab.com/ee/user/project/integrations/webhooks.html

### ③md・puファイル取得
jenkinsのjob内でgitリポジトリーからMarkdownファイルと、
図作成用のpu(plantuml)ファイルをチェックアウトします。

### ④pu→svg変換
puファイルを画像として参照するために、svgファイルに変換します。
jenkinsのslaveサーバにplantuml.jarを配置し、拡張子がpuのファイルに対して変換処理を実施します。
http://plantuml.com/ja/

### ⑤docsifyへdeploy
docsifyが動作しているサーバへ、Markdownファイルとsvgファイルをdeployします。
ファイルのdeployはjenkinsのsshプラグインをjob内で利用します。
https://wiki.jenkins.io/display/JENKINS/SSH+plugin

docsifyはmdファイルをお手軽にhtmlとして参照できるツールです。
https://docsify.js.org/#/

### ⑥参照
レビュアはdocsifyにwebサイトとして公開された設計書を参照します。

### ⑦フィードバック
編集者はレビュアから指摘事項をフィードバックとして受け取り、
設計書の修正を行います。

### フィードバックループ
⑦のフィードバックを得た後に設計書を修正し、gitにpushすることで①～⑦の手順をループさせ、
フィードバックループを用いて設計書を改善していきます。

# 工夫した点
### puファイルの格納フォルダ構成
docsifyではplantumlを画像として認識できないため、
プロジェクトのフォルダ構成を次のようにしました。

```
ページ名(フォルダ)
 └ ページ名.assets(フォルダ)
   └ ignore(フォルダ)
     └ .pu(ファイル)
```

ページ名.assetsフォルダの直下にはファイルは配置しないままpushしておき、
jenkinsのjob内の処理でignoreフォルダ内のpuファイルをsvgファイルに変換します。
変換したsvgファイルはページ名.assetsフォルダ直下に配置し、
ignoreフォルダはフォルダごと削除します。

jenkinsのjobの処理後は次のようなフォルダ構成になります。

```
ページ名(フォルダ)
 └ ページ名.assets(フォルダ)
   └ .svg(ファイル)
```

こうすることでdeploy時に不要なpuファイルを削除し、svgファイルのみが残るようにしました。
Markdownファイルからは上記のフォルダ構成時のsvgファイルを参照します。

~~この工夫についてはgitlabのplantuml参照機能が使えれば気にする必要はないので、
さほど重要ではありません。~~


# 最後に
今回は設計書をMarkdownで書き、plantumlで作図してhtmlとして公開する方法の１例を紹介しました。
概要でも触れましたが、個人的には設計書をエクセルやスプレッドシートで作成するのは、
"バージョン管理"や"別の人が作った図の編集のしにくさ"から考えるとナンセンスだと思っています。

インフラ構成の自動化として"infrastructure as code"という言葉がありますが、
設計書についても同様に"as code"としてgit管理し、修正や参照のしやすい方式を模索していく風潮が
広まれば良いと思います。
github.ioでポートフォリオを作った過程の学び

HTML,CSSについてぼんやり知っていたけど、0からページを作ったことがなかったので、作っていくなかで調べたこと、学んだことを書いていきます。

[今回作ったポートフォリオページ](https://kobayu0902art.github.io)

worksにこれから成果物をいっぱい載せていく予定！
ポートフォリオといいつつ内容がほとんど自己紹介なのは…
これからゴリゴリ開発してここにいろんなもの載せられるように**がんばらなきゃ！！**

#CDN
Content Delivery Networkの略

```html:jQueryの例
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
```

上のようにHTML内に記述するだけでjQueryが使えるようになる。すげぇ

いままで、フォントにしろフレームワークにしろ、ダウンロードしてフォルダに配置して…というのが一般的な導入方法だと思っていたので、あまりの手軽さに感動してしまった。
これはWebエンジニアやりたくなるぞ…
~~作ってる途中で知ったのでBootstrapはダウンロードして使ってしまっている。悔しい~~

#時間がたつとページ遷移するやつ
```html:
<META http-equiv="Refresh" content="3;URL=content/index.html">
```
もっとJavaScriptとかでごにょごにょやってるもんだと思ってた。
かんたん。

```javascript
onLoad=setTimeout("location.href='/content/index.html'",3000)>
```
JavaScript版、タグの中に入れる
#gitブランチの便利さ
github.ioは自分のリポジトリのmasterブランチが勝手にページに反映される。

今回ポートフォリオを作成するにあたって、
　　1.pythonのpelicanを使う
　　2.スクラッチで0からゴリゴリ書く
　　3.テンプレートをダウンロードして加工する
の3つを考えていた。

今回はお勉強の趣旨もあったので2番メインで作成したが、pelicanも気になる…ほかの人が作ったテンプレートの方が絶対見栄えいいな…ということで、
basic_htmlブランチとpelicanブランチ、templateブランチで分けて、公開したいものをmasterブランチにマージする、
ということをしてみた。
いちいちアップロードし直さなくていいのめっちゃ楽！

まだチーム開発のメンバーになったことはないけど、実際の開発プロジェクトでも、リリースバージョンを分けるとかでこういう使い方してるのかなと感じることができた。
バージョン管理もかなり便利だった。

#画像のランダム表示
HTMLとCSSでは乱数を扱えない
↓
JavaScriptとうまく組み合わせよう
↓
jQueryならCSSに追加できるらしい
↓
background-image:の後ろに`url(画像path)`を指定したい…
↓
pathを文字列で配列に入れる
↓
url()の中に文字列結合
↓

```javascript
$('.box').css('background-image', 文字列);
```
でCSSに追加できた！

#感想
**記述量多いなあ～～～!!!!**
まだ技術不足で無駄が多いのか、HTMLなら仕方ないのかどうなんですかね
自分はやっぱりPythonが記述量減らせて好きだなあと再認識
とはいえかなり無駄が多いのも事実なのでこれから無駄な記述をなくせるようにしていきたい



#(関係ないけど)Udemyのブラックフライデーセール
この機会に教材いくつか買ってみたいので、
Web開発、AI・機械学習、Python、開発全般、エンジニアとしての基礎
あたりのキーワードでおすすめがあったら教えてください！
laravelの定数定義

https://qiita.com/Hiraku/items/bb0cb665d830f7cd37ff
constを使って定義することもあるみたいですが、今回の開発はdefineが使われていたのでそちらに合わせました。




```php:config/const.php
define('OFF', 0);
define('ON', 1);
```
こんな感じに定義。

これでどこからでもOFFという定数で０が呼び出せるように。
何らかのカラムを0をオフ、1をオンで管理したいときなどに見やすくて便利です。
Goのテストでヘルパー関数に t.Helper() を忘れない

# はじめに

Goのテストにおいて、[ヘルパー関数は `t.Helper()` を呼ぶことでヘルパー関数だとマークできる](https://golang.org/pkg/testing/#T.Helper)。

この記事では、ヘルパー関数としてマークしないとどういった問題があるか、マークするとどう問題が改善されるか、またマークし忘れを防ぐ方法について説明する。

# ヘルパー関数としてマークしないと

ヘルパー関数 `testChdir()` を用いたテストについて考える。この関数は第２引数に存在しないパスを渡すと `t.Fatalf()` が呼ばれる。 `TestFoo()` は存在しないパスで `testChdir()` を呼ぶため失敗する。

しかし `go test` の出力で失敗の箇所は `b_test.go:22` であり、これは `testChdir()` 内の `t.Fatalf("err: %s", err)` を指している。そのため、なぜテストが失敗しているのかを理解するのにあまり有用ではない。

```go
package b

import (
	"os"
	"testing"
)

func TestFoo(t *testing.T) {
	defer testChdir(t, "/this/directory/does/not/exist")()

	// ...
}

// https://speakerdeck.com/mitchellh/advanced-testing-with-go?slide=30
func testChdir(t *testing.T, dir string) func() {
	old, err := os.Getwd()
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	if err := os.Chdir(dir); err != nil {
		t.Fatalf("err: %s", err) // b_test.go:22
	}

	return func() { os.Chdir(old) }
}
```

```shell-session
$ go test
--- FAIL: TestFoo (0.00s)
    b_test.go:22: err: chdir /this/directory/does/not/exist: no such file or directory
FAIL
exit status 1
FAIL    github.com/ichiban/thelper/testdata/src/b       0.006s
```

# ヘルパー関数としてマークすると

一方、 `testChdir()` の冒頭で `t.Helper()` を呼ぶと `go test` の結果は失敗の箇所を `b_test.go:9` と表示し、これは `TestFoo()` 内の `defer testChdir(t, "/this/directory/does/not/exist")()` を指しているため失敗の原因がわかりやすい。

テストのヘルパー関数では忘れずに `t.Helper()` を呼ぶべきだ。

```go
package b

import (
	"os"
	"testing"
)

func TestFoo(t *testing.T) {
	defer testChdir(t, "/this/directory/does/not/exist")() // b_test.go:9

	// ...
}

// https://speakerdeck.com/mitchellh/advanced-testing-with-go?slide=30
func testChdir(t *testing.T, dir string) func() {
	t.Helper()

	old, err := os.Getwd()
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	if err := os.Chdir(dir); err != nil {
		t.Fatalf("err: %s", err)
	}

	return func() { os.Chdir(old) }
}
```

```shell-session
$ go test
--- FAIL: TestFoo (0.00s)
    b_test.go:9: err: chdir /this/directory/does/not/exist: no such file or directory
FAIL
exit status 1
FAIL    github.com/ichiban/thelper/testdata/src/b       0.006s
```

# マークし忘れを防ぐ

`t.Helper()` の呼び忘れを防ぐには人力ではどうしても漏れがでる。そのため、 [`thelper`](https://github.com/ichiban/thelper) という静的解析ツールを作った。これを使うとマークし忘れたヘルパー関数が見つかる。

```shell-session
$ go get github.com/ichiban/thelper/cmd/thelper
```

```shell-session
$ thelper ./...
/Users/ichiban/src/thelper/testdata/src/b/b_test.go:15:1: unmarked test helper: call t.Helper()
```

# おわりに

ヘルパー関数をマークしないとどういう問題があるか、マークすることでどう改善されるかについて説明し、マークし忘れを防止する静的解析ツールを紹介した。

コードを書く上で気をつけなければいけないが見落としがちなことは静的解析ツールにしてしまうといいんじゃないだろうか。
EC2 Amazon Linuxでcode serverやEclipse Theiaを起動する

# EC2のAmazon Linuxでcode serverやEclipse Theiaを起動する
EC2のAmazon Linuxに、Dockerをインストールして、Docker Imageのcode-serverやEclipse Theiaを起動します。

【参考】[code-server](https://github.com/cdr/code-server)
【参考】[Eclipse theia](https://github.com/eclipse-theia/theia)

# 開発環境
||バージョン|
|---|---|
|OS|Amazon Linux(2018.03.0.20190611)|
|インスタンスタイプ|t3a.medium|
|Docker|18.09.9-ce|

※ EC2のセットアップ方法は省略します。

# Amazon LinuxにDocker(18.09.9-ce)をインストール

```
> sudo yum update -y
> sudo yum install -y docker
```
さらに以下を実行

```
> sudo service docker start
> sudo usermod -a -G docker ec2-user
```

一旦、ログアウトし、再びログインする。
そして、Dockerのバージョンを確認。

```
> docker version
Client:
 Version:           18.09.9-ce
 API version:       1.39
 Go version:        go1.10.3
 Git commit:        039a7df
 Built:             Fri Nov  1 19:01:06 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.09.9-ce
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.3
  Git commit:       039a7df
  Built:            Fri Nov  1 19:02:42 2019
  OS/Arch:          linux/amd64
  Experimental:     false
```

# code-serverを起動する場合

以下を実行しcode-serverを起動する。

```

> sudo docker run -it --user root -p 80:8080 -v "${HOME}/.local/share/code-server:/home/coder/.local/share/code-server" -v "$PWD:/home/coder/project" codercom/code-server:v2 --auth none

```
※ ポートは80にしてます
※ AWSセキュリティグループの「インバウンド」でHTTPの80ポートを忘れずに許可すること

### 動作確認(code server)

ブラウザを開き「http://\<EC2のパブリックDNS\>」にアクセスする。

![code-server.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517406/ca08402c-dbb2-f3ae-79cb-180e8bb52493.png)

## Eclipse Theiaを起動する場合

以下を実行しEclipse Theiaを起動する。
（code serverは、ctrl+cなどで停止させておくこと）

```

> sudo docker run -it --user root -p 80:3000 -v "$(pwd):/home/project:cached" theiaide/theia:next

```
※ ポートは80にしてます
※ AWSセキュリティグループの「インバウンド」でHTTPの80ポートを忘れずに許可すること

### 動作確認(Eclipse Theia)

ブラウザを開き「http://\<EC2のパブリックDNS\>」にアクセスする。

![eclipse-theia.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517406/8f97df24-4912-8572-f5bf-c6b5ba364f4f.png)


# 次回予定

それぞれにVSCodeの拡張機能をインストールしてみる。
BigQueryのDatasetをbqコマンドでコピーする

# はじめに
- [2019年8月に、copying datasetsがβとしてリリース](https://cloud.google.com/bigquery/docs/release-notes#August_30_2019)されました。
- この記事では、bqコマンドを使ってdatasetのコピーを試してみます（コンソールでもできます）。
- Datasetのコピー機能によって、copyやrenameが実現できるようになりました👏
- ドキュメントとしては[ここ](https://cloud.google.com/bigquery/docs/copying-datasets)に全部書いているのですが、あまり親切ではなかったので、qiitaにちょっと起こしてみました。

# 事前準備


- BigQuery Data Transfer Serviceを利用するので、APIの有効化が必要です。詳細は、[こちらのドキュメントに全部書いている](https://cloud.google.com/bigquery/docs/enable-transfer-service)ので、どうぞ。
- また、BigQueryの適切な権限が必要です。権限は[こちらのドキュメント](https://cloud.google.com/bigquery/docs/copying-datasets#required_permissions)を見てください。

# 実行

BigQuery Data Transfer Serviceの有効化が終わっている状態で、bqコマンドを実行してみます。

## サンプルの前提

- project名
    - foo-project
- location
    - asia-northeast1
- ソースdataset名
    - dataset1
- ターゲットdataset名
    - datase2


同一locationでのdatasetコピーを試してみます。

## 実行サンプル

まず、copy先の空のdatasetをつくっておきます。

```
bq --location=asia-northeast1 mk --dataset foo-project:dataset2
```

次にBigQuery Data Transfer Serviceのタスクを登録します

```
bq mk \
--location=asia-northeast1 \
--transfer_config \
--project_id=foo-project \
--data_source=cross_region_copy \
--target_dataset=dataset2 \
--display_name='dataset1 -> dataset2 copy' \
--params='{"source_dataset_id":"dataset1","source_project_id":"foo-project","overwrite_destination_table":"true"}'
```

いくつかパラメータについて補足すると

- overwrite_destination_table
    - 以前にコピーしたテーブルを切り捨ててすべてのデータを更新する

上記を実行すると、下記のようなレスポンスがあります。

```
https://www.gstatic.com/xxx
Please copy and paste the above URL into your web browser and follow the instructions to retrieve an authentication code.
Enter your authentication code here:
```

`https://www.gstatic.com/xxx` にアクセスして、許可すると、authentication code が発行されるので `Enter your authentication code here:` に続けて入力してください。

`Transfer configuration 'projects/xxx' successfully created.` というメッセージが表示されれは、成功です。


上記でレスポンスのあった、リソースIDを指定して、bq showすると、ステータスなどが表示できます。

```
bq show --format=prettyjson \
--transfer_config projects/xxx
```

同様のことは、すべてコンソールからもできるのですが、数が多いときはbqコマンドで実行できたほうが便利ですよね。

# 残った問題

上記の例で実行すると、毎日実行される日次の転送設定として登録されてしまう。
今は、OneShotの実行を行いたい場合は、初回転送実行後、転送設定を消しているけど、もうちょいいいやり方（オプション等）がないか模索中。
Ubuntu18.04でpip install mysqlclientするもエラーが出る場合の解決方法

AWS EC2のUbuntu環境でmysqlを導入していたら、PythonとMySQLを接続するためのパッケージインストールでエラーが出まくったので色々調べて解決。

結論から言うと、CentOS同様にMySQLサーバだけでなく開発ツールを導入しなければいけないようです。

```
$ sudo apt-get install -y mysql-server
$ sudo apt-get install -y libmysqlclient-dev #←これ
```

```
$ pip install mysqlclient
```

これでいけました。

## その他installしたけど関係あるかわからないもの

```
$ sudo apt-get install -y default-libmysqlclient-dev
```

## 環境
OS: Ubuntu18.04
pip 19.3.1
Sourceryでアプリシークレットを管理する方法

# はじめに

個人開発をする中でTwitterやFirebaseなど様々な情報を扱うか模索していて行き着いた一例を紹介します。

やりたいこととしては「各種APIを叩くためのシークレット情報などをアプリに直接ソースコードに持ちたくはないが、参照できること」です。

方法としては、Sourceryを用いてSecret.swiftを自動生成することにしました。
[cocoapods-keys](https://github.com/orta/cocoapods-keys)を利用する方法もありますが、Cocoapodsを利用していないため代替手段を模索することにしました。

以下に、手順を示していきます。

---

# 手順

1. Sourceryの導入
2. テンプレートの作成
3. 設定ファイル作成
4. 自動化スクリプトの追加
5. `.gitignore`に追記

---

##  1. Sourceryの導入

[Sourcery](https://github.com/krzysztofzablocki/Sourcery)はSwift用のコードジェネレータライブラリです。
よくあるEquatableの実装など、何度も書くような実装を自動化してくれます。

Xcode -> File -> Swift Packages -> Add Package Dependency から`https://github.com/krzysztofzablocki/Sourcery`のURLを入力して任意のバージョンを入れます。

--- 

## 2. テンプレートの作成

生成するSwiftファイルのテンプレートを作ります。
今回はTwitterAPIを利用したアプリを制作していたのでその変数をstaticで定義し、値の入力にはargument

```swift:Templates/Secret.stencil
enum Secret {
    static let twitterConsumerKey = "{{argument.twitterConsumerKey}}"
    static let twitterConsumerKeySecret = "{{ argument.twitterConsumerKeySecret }}"
}
```

---

## 3. 設定ファイル作成

`.sourcery.secret.yml`という名前でsourcryファイルを作ります。
`templates` で(2)で追加したファイルを読み込み、
`output`で成果物をGeneratedディレクトリに生成します。

```yml:.sourcery.secret.yml
sources:
  - SampleApp
templates:
  - Templates/Secret.stencil
output:
  path: Generated/ 
  link:
    project: SampleApp.xcodeproj
    target: SampleApp
    group: SampleApp
args:
  twitterConsumerKey: "実際のKey"
  twitterConsumerKeySecret: "実際のSecret"
```

---

## 4. 自動化スクリプトの追加


以下のshell scriptを`Build Phases`に追加します。

```shell
mkdir -p Sourcery
sourcery --config .sourcery.secret.yml
```

追加する前にターミナルで正しく実行されるか確認してみると良いかと思います。

`Compile Sources`の前に追記すると良いでしょう。
<img width="957" alt="Screen Shot 2019-11-22 at 18.43.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69911/12b21e85-1b26-cb23-cb6e-c6312bfb5435.png">


あとは出来上がった`Secret.generated.swift`をプロジェクトに追加すると、`Secret.twitterConsumerKey`などを参照できるようになるかと思います。

---

## 5. .gitignoreに追記

シークレットの情報が入ったファイル群は `.gitignore`に入力して保存されないようにします。

```:.gitignore
.sourcery.secret.yml
Sourcery 
```

---

# おわりに

雑にまとめてみましたが、質問などあればTwitter([@mtfum](https://twitter.com/mtfum))にお願いします！

ymlファイルのoutputでlinkなどを書いていますがきちんと機能しているのかあまりよくわかっていません。。
また、変数の変更時にテンプレート(`Templates/Secret.stencil`)と設定ファイル(`.sourcery.secret.yml`)を変更しなければならないのがまだ冗長的で課題なのでより簡潔になる方法がわかれば追記しようと思います。

ご存知の方がいらっしゃれば教えてください！


# 参考

[Managing secrets within an iOS app](https://www.lordcodes.com/posts/managing-secrets-within-an-ios-app)
【Kotlin】下層のViewのタップイベントを拾ってしまう

androidではタップ時、タップ可能なViewがないと下層のViewのイベントを拾ってしまうそう

なので表示されてるfragmentのConstraintLayoutやRelativeLayoutに

```kotlin
android:clickable="true"
```

を記述してタップ可能にしてやると解決
Laravel 6.xでプロジェクト作成時に認証機能が作成できるようになった

Laravel6の以前では、`make:auth`を実行したら直ぐに認証機能ができました。
Laravel 6のリリースにより、`make:auth`コマンドは別の`laravel/ui`パッケージに移動しました。それにより、手間が多少増えました。

しかし、`--auth`フラグを使用した認証スキャフォールドを含むLaravel Installer v2.3.0の新機能をリリースしたと告知されました。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Just released Laravel Installer 2.3.0... added a new &quot;--auth&quot; flag to create a new project with the authentication scaffolding installed and ready to go! 🔒 <a href="https://t.co/z47NyEmW8E">pic.twitter.com/z47NyEmW8E</a></p>&mdash; Taylor Otwell 🏝 (@taylorotwell) <a href="https://twitter.com/taylorotwell/status/1196556840575938560?ref_src=twsrc%5Etfw">November 18, 2019</a></blockquote> 


#Laravel Installerのupdate

```
composer global update laravel/installer
```

#Laravel プロジェクトの作成
```
laravel new project --auth
```

Laravelのインストールが始まります。
完了すると`laravel\ui`インストール済みで、`web.php`に認証ルートがあるプロジェクトが作成されています。

結局composer経由でプロジェクト作ったり、プロジェクト作ってからすぐに追加できるから`make:auth`は楽だったのでこれは使わなさそう
Railsのヘルパーメソッド

# Railsのヘルパーメソッド備忘録

## 開発環境
- Ruby2.6.3
- Rails6.0.1

## ヘルパーメソッド

### simple_format
**役割**

- 改行等のデータをHTMLへ渡す

**使用例**

```ruby

<div class="card-body">
        <p class="card-text"><%= simple_format(@board.body) %></p>
        <p class="text-right font-weight-bold mr-10" ><%= @board.name %></p>
    </div>
```
`<%= simple_format(モデルから渡されたデータ) %>`
Next.js参考リンク

## Next.js + Typescript

Documentation - Getting Started | Next.js
https://nextjs.org/docs#typescript

空のtsconfig.json置いてyarn devして指示に従うとよしなに設定してくれる。
あとはjs -> tsxに変更。

## Next.js + Material UI

material-ui/examples/nextjs at master · mui-org/material-ui
https://github.com/mui-org/material-ui/tree/master/examples/nextjs

## Next.js + Material UI (Typescript)

material-ui/examples/nextjs-with-typescript at master · mui-org/material-ui
https://github.com/mui-org/material-ui/tree/master/examples/nextjs-with-typescript

## Next.js + redux

next.js/examples/with-redux at canary · zeit/next.js
https://github.com/zeit/next.js/tree/canary/examples/with-redux

A beginner guide for Redux with Next.js - Bhavik Bamania - Medium
https://medium.com/@bhavikbamania/a-beginner-guide-for-redux-with-next-js-4d018e1342b2

## 認証

User Authentication with Next.js - DEV Community 👩‍💻👨‍💻
https://dev.to/jolvera/user-authentication-with-nextjs-4023
５日目の午後。


今日学んだことは
ハッシュ、引数、バグ修正の考え方。

ハッシュについてわからないことが多かったので、すっきりした。

ハッシュとは箱であり、配列にきれいに並んで入っている。
一つ一つに番号がある。
ハッシュから取り出すには、
ハッシュ名[:キー名]
ハッシュに入れるには
ハッシュ名[:キー名]=バリュー名

である。
zshでこの設定は当然もうしてあるよね？①：auto_cd

※タイトルに`①`とありますが，次回以降がある訳じゃない(気が向いたら書く)ので，そのあたりはご了承ください。

みなさん。zshを使っていますか。zshは好きですか。自分は大好きです。
自分がzshを使う理由として，「楽がしやすい」という点がかなり大きいです。
zshには楽をするための機能がたくさんありますが，その中でも自分が特に便利だと感じている機能の `auto_cd`を紹介します。

## auto_cd とは
`auto_cd`は，「ディレクトリ名を入力したら自動でcdしてくれる」機能です。

```zsh
% pwd
/home/stmkza
% ls -F
some_dir1/ some_dir2/ some_dir3/
```

こんな状態で`some_dir1`に移動したいとき，`auto_cd`がOFFの場合は

```zsh
% cd some_dir1
% pwd
/home/stmkza/some_dir1
```

と入力しますが，`auto_cd`がONの場合は

```zsh
% some_dir1
% pwd
/home/stmkza/some_dir1
```

と入力するだけで移動することができます。

## 設定方法
`auto_cd` の設定をするのはとても簡単で，`.zshrc`に

```zsh
setopt auto_cd
```

と書くだけで有効化できます。

## 利点
`cd `の3文字を入力しなくてもすみます。たった3文字ですが，それを1回入力するのに1秒かかり，1時間に5回`cd `コマンドを使って，1日8時間の作業を月22日すると仮定すると，1年で3時間くらい[^1]を節約することができます。

[^1]: 1秒 * 5回 * 8時間 * 22日 * 12ヶ月 = 10560秒 = 2時間54分 ≒ 3時間

## さらに便利な使い方
`auto_cd`は標準ではカレントディレクトリ内のディレクトリしか指定できませんが，どこからでもそこに一瞬で移動できるようにしたいディレクトリなどがありますよね。自分はGitHubからcloneしたディレクトリを`~/repos/github.com/`以下に置いているので，自分のレポジトリである`~/repos/github.com/stmkza/`以下のディレクトリにはどこからでも移動できると便利です。また，ホームディレクトリ直下の場所にも直接移動したいです。
そんなときには環境変数`cdpath`に移動したいディレクトリ名を↓のように書いたらそのディレクトリにも移動できます。

```zsh
export cdpath=(~/repos/github.com/stmkza ~)
```

ただし，この設定をすると，`cd `を使って移動したときにもそのディレクトリに移動してしまうので，そこは注意が必要です。
if・unlessを一行で ❏Ruby❏

後置なんちゃらというやつです。
処理を先に、条件式を後ろにすることでスマートに書けます。

#後置if

```ruby
num = 1
puts "0より大きいよ！" if num > 0
```

#後置unless

```ruby
num = 1
puts "0じゃないよ！" unless num == 0
```

it'sスマート！
ただし、条件式が複雑な時は普通の方を使いましょう。

<br>
ではまた！
IBM Cloud Kubernetes Serviceのクラスターオーナーがインフラストラクチャー権限を失った場合の対処方法

# 問題の経緯

IBM Cloud Kubernetes Service（以下、IKS）では、クラスターのオーナーという概念があります。これは、クラスターをオーダーしたときのIBM Cloudユーザーが自動的に設定されます。オーナーは、例えばマスターやワーカーのバージョンアップや、StorageClassによるIBM Cloud Storageの動的プロビジョニングを行う際に、オーナー自身のインフラストラクチャー権限を使用します（その操作の実行ユーザーではないことに注意）。つまりオーナーが適切なインフラストラクチャー権限を持っていないと、これらの作業は失敗します。

さて、このオーナーになってしまっているユーザーがプロジェクトを離任したので、アカウントから消去されたとしましょう。するとその後誰かがバージョンアップ等を行おうとした場合、権限をもったオーナーがいないため、失敗してしまいます。

そして困ったことに、クラスターのオーナーは後から変更できないとサポートから回答がありました。

というわけで、このような状況になってしまった際の回避策です。

# 対応方法

## 適切なユーザーの準備

今後の保守作業で、着任や離任に影響を受けない、固定IDのユーザーを用意することをお勧めします。用意出来たらそのユーザーをアカウントに招待し、必要なインフラストラクチャー権限を付与してください。

## クラシック・インフラストラクチャー APIキーの生成

そのユーザーでIBM Cloudコンソールにログインし、メニューから「管理」→「アクセス（IAM）」→「IBM Cloud APIキー」に移動します。

すると次のように「クラシック・インフラストラクチャーAPIキーの作成」というボタンがありますので押してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/48ef721c-c709-d755-769a-088ad85fb8c3.png)

もしこのボタンが表示されていない場合は、すでにAPIキーが生成済のはずです。

APIキーが生成されたら、詳細メニューを開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/d097f401-0bfd-eb8f-1b0e-e523d1a1a1a1.png)

APIキーの目玉マークを推すとキーが表示されます。ここで、APIユーザー名とAPIキーの値を控えてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/ffcc18fe-fb2a-3278-68ff-fd5a7bbbac05.png)

## クラスターへのAPIキーの設定

クラスターの管理権限をもつユーザーでIBM Cloud CLIを使用します。次のコマンドを実行します。

```
$ ibmcloud ks credential set classic --infrastructure-api-key ${APIキー} --infrastructure-username ${APIユーザー名}
$ ibmcloud ks api-key-reset
```

最後のapi-key-resetは忘れないようにしてください。これを打たないと反映されません。

## 設定反映の確認

設定はすぐには反映されません。次のコマンドを定期的に実行します。

```
kubectl get secret storage-secret-store -n kube-system -o yaml | grep slclient.toml: | awk '{print $2}' | base64 --decode
```

すると次のように表示されると思います。

```
[Softlayer]
 encryption = true
 softlayer_username = ""
 softlayer_api_key = ""
```

定期的にコマンドを打ち続け、次のような表示になれば設定反映は完了です。体感的には数分～10分近くかかった気がします。

```
[Softlayer]
 encryption = true
 softlayer_username = "${APIユーザー名}"
 softlayer_api_key = "${APIキー}"
 softlayer_endpoint_url = "https://api.service.softlayer.com/rest/v3"
```

これで、これ以降はクラスターのバージョンアップやストレージの動的プロビジョン時には、このAPIキーが使われるようになります。

以上です。
XServer で テスト環境のみBASIC認証をかける方法

### はじめに

サブドメインのディレクトリ内に「.htaccess」を置いて、そこにBASIC認証の記述をするのが最も簡単です。
ですが、私は親元のディレクトリにだけ「.htaccess」を置きたい宗派の人間ですので、方法を記載します。

### 前提

ドキュメントルートの構成が次の通りであること
(XServerでサブドメインを作成したら自動でディレクトリができるはずです)

本番環境 ドキュメントルート

```
/home/{{ サーバID }}/{{ ドメイン名 }}/public_html/

例: www.hogehoge.jp の場合 => /home/hogehoge/hogehoge.jp/public_html/
```

テスト環境 ドキュメントルート

```
/home/{{ サーバID }}/{{ ドメイン名 }}/public_html/{{ サブドメイン名 }}

例: test.hogehoge.jp の場合 => /home/hogehoge/hogehoge.jp/public_html/test/
```

### .htaccess にこれを書く

```:/home/hogehoge/hogehoge.jp/public_html/.htaccess
AuthUserFile /home/hogehoge/hogehoge.jp/htpasswd/.htpasswd
AuthType BASIC
AuthName "Basic Auth"
Require valid-user

Satisfy Any
SetEnvIf Host "^www.hogehoge.jp$" no_auth

Order Deny,Allow
Deny from all
Allow from env=no_auth
```
DockerFileのBuild時に個別のSSL証明書をimportする

ウェブクルー AdventCalendar 1日目の記事です。

今年のウェブクルーアドベントカレンダーは@kouchanne からスタートします
よろしくお願いします!

# About me
@kouchanne はウェブクルーに2017年に新卒で入社した、今年3年目のバックエンドエンジニアです。(業務ではVue.js等も触ってますが…)

カレンダーの作者が何を隠そう私なので、トップバッターを飾らせていただきましたw
1日目は簡単に、今年業務で一番ハマったもと思うものの中から一つ書かせていただければと思います。


# ハマったこと
ウェブクルーでは、バックエンドの実装で scala x play を使って実装しているのですが、
playの[WS](https://www.playframework.com/documentation/2.6.x/ScalaWS)を使い、自社ドメインのAPIへリクエストを送ったときに返り値の **WSRequest** ではないエラーが返ってきた…

## 原因
APIと通信するときに使うSSL証明書(公開鍵)が使用しているJDKにデフォルトで入っていなかった

## 原因を特定するためにやったこと
1. 処理自体を`Try` `catch` で囲んで拾ってみる ⇒ 拾えなかった
2. `JVMOption` に [-Xdebug](http://otndnld.oracle.co.jp/document/products/jrockit/jrdocs/refman/optionX.html)を追加して、拾えるものをとにかく拾ってみる ⇒ APIの通信をしている付近のログで、なにか失敗らしきものを発見
3. 内容を見てみるとSSLの証明書の認証に失敗しているっぽいことが発覚

## 原因を解決するためにやったこと
1. 証明書周りでエラーが起きていることが分かったので `java store 証明書 エラー` で調べてみる ⇒ 「Javaの環境に手動で証明書をインストールする」みたいなものがヒットする
2. local環境のJDKにAPIのドメインで使っている証明書をインストールして実行してみる ⇒ 動いた



**※サラッと書いてますが、ここに到達するのに5日くらいかかりましたｗ**

# 本題
ローカルで動かすまではJDKに直接証明書をインストールするだけなので、良かったのですが
それをDockerFileでやっている人があまりいなかったので、共有します。


## やり方
### 準備
* dockerコンテナが読み取れる場所に `hogehoge.cer` を配置する
    * 私は直接Githubにソースとして配置しています。

### DockerFileに突っ込む
```dockerfile:
RUN keytool -noprompt -storepass changeit -import -alias play -keystore /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/cacerts -file /home/work/hogehoge.cer
```
### option説明
* `-noprompt` オプションでimport時の確認を省略することができる
* `-storepass` パスワードを入力 Javaのkeysotreのデフォルトパスワードは changeit
* `-keystore` keystoreの場所は使用しているimageに合わせてください$JAVA_HOME/jre/lib/security/cacerts とかでも良いかも
* `-file` 突っ込んだ証明書を指定

### ポイント
* 通常のサーバーだと `keystore` ごと書き換えることが一般的らしいが、Dockerでは最新のversionでも対応できるように`keytool` で個別にimportするのが理想
* play等のアプリケーションを起動するユーザーは`root`ではなくユーザーを切り替えるのが一般的ですが、**証明書のインポートは `root`ユーザーしかできないため、ユーザーを切り替える前に対応する必要があります。**


# まとめ
DockerFileでSSL証明書のインポートする手順を書かせていただきました。
基本的に有名所の証明書を使っていれば、デフォルトで入っているのでハマることはないのですが、開発環境用の自己証明書とか比較的お安めの証明書の場合に発生するレアケースなので、あまり使わないかもしれませんが…

SSL証明書系の設定はどちらかというとインフラ寄りだと思いますが、
アプリケーションを開発しているときに、出ると普段あまり触らない領域でハマることになるので**バックエンドエンジニアもインフラの知識は最低限必要**だと言うことをこの体験を通じて痛感しました。

# さいごに
1日目はこんな形で締めくくらせていただきます。

今年のカレンダーはエンジニア以外の方にも記事を書いてもらうので、いろんな内容を楽しんでいただければと思います。
25日までどうかお付き合いよろしくお願いいたします！
Chrome extensionの content_script と background について

ウェブクルー AdventCalendar 2日目の記事です

2日目~~は~~も@kouchanne が担当します！

1日目と一緒だって？…

書きたいこといっぱいあって書いちゃいました！
どうかお付き合いください。

# はじめに
今まで業務で使うchromeのextensionをいくつか自作してきたんですが `content_script` と `background` の片方しか使わないシーンしかなく、違いがパットしていなかったのですが最近作ったアプリで点と点がつながる瞬間があったのでそこについて共有できればと思います。

# chrome extension

## chrome extension とは
この記事を見てくださっている、方は~~InternetExplorerではなく~~ Googleのchromeかfirefoxの方が多数かと思いますが。
これらには拡張機能があります。※今回はchromeのお話ですがfirefoxも似たようなものがあります
chromeでは[拡張機能](https://chrome.google.com/webstore/category/extensions?hl=ja)と呼ばれるウェブブラウジングを便利にしてくれる機能がいっぱいあって、みなさんもお世話になっているかと思います。
公開されているものから使うことが多いと思いますが、実は簡単なjsさえかければ誰でも作れちゃうんです。
※作り方系の記事はいっぱいあるので、今回は初期構築のところはあまり触れません


## `content_script` と `background`
chrome extension には大きく分けて `content_script` と `background` があります。
これらの違いは何かというと

* `content_script` ⇒ 閲覧しているページに対して直接操作する。　ブックマークレットをいい感じにしたやつ
* `background` ⇒ chromeが起動している裏で**仮想のタブが立ち上がっている(見えない)**。 ページ関係なくブラウザ側が持つ機能


### 図で書いてみた
![chrome extension.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206268/32e37d07-1e76-5ed0-2f62-76071c6f43cb.png)

* `background`から閲覧しているページのDOM要素を直接操作することはできない
* `content_script` からchrome側のイベントを検知することができない

そのため、**拡張機能のボタンが押されたら閲覧しているサイトの要素を取得していい感じにするみたいなことができない…**

`content_script` と `background` 間で値のやり取りをしたいときは[sendMessage](https://developer.chrome.com/apps/messaging)を使うことで実現できます。


# 実用例
上の部分を抑えたところで実際に以下の作りたいものを叶えるにはどのように実装できるか例を上げてみます。

## 作りたいもの
chrome 拡張のボタンを押すと、閲覧している対象のページのコンテンツを取得してクリップボードへコピーする

## 作り方
1. `background`側 に ボタンをクリックしたときのイベントトリガーをセットする
2. イベントトリガー内のfunctionで`content_script` 側にメッセージを飛ばす
3. `content_script`側でメッセージを検知したらコンテンツを取得するfunctionを実行する
4. `background`側へ取得した値をメッセージで飛ばす
5. `content_script`側から渡ってきたメッセージをクリップボードにコピーするfunctionを実行する


### ソース
```javascript:background
// 1 イベントトリガー
chrome.browserAction.onClicked.addListener(function (tab) {
  // 2 メッセージの送信
  chrome.tabs.sendMessage(tab.id, "hogehoge");
});

// 5 メッセージを受け取るトリガー
chrome.runtime.onMessage.addListener(
  function(request,sender,sendResponse){
    console.log("クリップボードにコピーします");
    saveToClipboard(request.body);
    sendResponse("finish");
  }
);

function saveToClipboard(str) {
  var textArea = document.createElement("textarea");
  document.body.appendChild(textArea);
  textArea.value = str;
  textArea.select();
  document.execCommand("copy");
  document.body.removeChild(textArea);
}
```

```javascript:content_script
// 3 メッセージを受け取るトリガー
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
  if (request == "hogehoge") {
    var body = copy();
    // 4 取得したコンテンツを値として渡す
    chrome.runtime.sendMessage({body: body},
     function(response){});
  }
});
```

こんな形で、`background` で発動したものを`content_script`で実行できるようになりました。


# さいごに
Chromeの拡張機能はなかなか資料も少なく、初めて触ったときはだいぶ意味がわからなかったですが、
改めてちゃんと実装してみると今回の学びを得ることができ、chrome extension開発でだいぶキーになるポイントだと思ったので共有させていただきました。

chromeはなかなか、商材として扱う機会は少ないですが、業務効率化や個人のちょっとしたツールを作るのには最適なので、作るときのちょっとした参考になればと思います。


明日のアドベントカレンダーは@piwiさんの「わたし定時で帰ります(仮)」です。
興味深いタイトルですね! よろしくおねがいします！
firewall設定方法

##firewallとは？
ネットワークとネットワークの間に立ち、不正アクセスをブロックする設定をするところ

##設定するには？
###firewall -cmdコマンドの利用
ポートを追加するにはadd、削除するにはremoveをそれぞれ用います。
今回はport22を追加、削除する例を記載します。

```
[追加する例]
# firewall-cmd  --zone=drop --add-rich-rule="rule family="ipv4" source address="XXX.XXX.XXX.XXX" port protocol="tcp" port="22"

[削除する例]
# firewall-cmd  --zone=drop --remove-rich-rule="rule family="ipv4" source address="XXX.XXX.XXX.XXX" port protocol="tcp" port="22"
```
追加や削除を行った後は再起動させて確認してください。

```
[再起動コマンド]
# systemctl restart firewalld

[firewallリスト確認コマンド]
# firewall-cmd --list-all
```

##起動確認するには？
###systemctlコマンドの利用

```
[起動確認]
# systemctl status firewalld

[起動させる場合]
# systemctl start firewalld

[停止させる場合]
# systemctl stop firewalld
```


##引用

ファイアウォールとは
>https://boxil.jp/mag/a1288/

Linux firewallの使い方
>https://eng-entrance.com/linux-centos-firewall

firewalldの設定方法
>https://www.server-memo.net/centos-settings/firewalld/firewalld.html#i-8


以上がfirewallの設定方法でした。
最後までお読みいただきありがとうございました！
深層学習の層の数と精度変化の歴史のグラフ

# 深層学習の発展のグラフ
深層学習の発展を表すグラフとしてよくILSVRCにおける精度の変化と層の数の推移を表すグラフを見かけるので作っておきました．

![ilsvrc_winner.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355593/106ed248-15fa-4613-ca04-f477ca3df03b.png)

# pythonのコード

```py
import matplotlib.pyplot as plt


def plot_res():
    plt.rcParams["font.family"] = "Arial"
    plt.rcParams["font.size"] = 18
    fig = plt.figure()

    c = ["skyblue", "blue"] * 5
    depths = [8, 8, 22, 152, 205]
    years = list(range(2012, 2017))
    errors = [16.4, 11.7, 7.3, 6.7, 2.9]
    a = 0.2

    ax1 = fig.add_subplot(111)
    depth_bars = ax1.bar(years, depths, color=c[0], tick_label=years)
    for year, depth in zip(years, depths):
        ax1.text(year, depth, depth if depth < 200 else "200>", ha="center", va="bottom", color="black", fontsize=14)
    ax1.set_ylim(0, 230)
    ax1.set_ylabel("Depth of Neural Networks")

    ax2 = ax1.twinx()
    error_line = ax2.plot(years, errors, color=c[1], linewidth=2)
    for year, error in zip(years, errors):
        ax2.text(year - a, error + 1, error, color="black", fontsize=14)
    ax2.set_ylim(0, 20)
    ax2.set_ylabel("Error Rate")

    plt.title("Winner in ILSVRC")
    plt.tight_layout()
    plt.show()

plot_res()
```
現在のローカルブランチを別名でコピーする方法

# 問題

1. ローカルでspecを回すと重くなるので、リモート上でCIを回して確認したいと考えた
→現在のブランチをgitにpushし、PR(WIP)を作成することでCIを回した

2. CIが回っている間にコードを修正してステージングで確認しようとしたが、
Capistranoでdeployする場合はgit上にあげないといけないことに気づく
→ブランチが同じため、今pushしてしまうとCIがまた1から回ることになってしまう

3. そこで、現在のブランチの内容を別ブランチとしてコピーして、そこで作業したいと考えた
→が、コピーするコマンドがわからず。。

# 対処

gitの公式を見ました。

`git branch`であることはわかっていたので、`git branch`のドキュメントで
`copy`とか`-c`で調べたところ、 `git branch -c` というコマンドがあることがわかりました。

気になる使い方については記載がなかったため、`git branch copy`でググったところ
StackOverflowに `git branch -c FILE_NAME(FROM) FILE_NAME(TO)`という記載があったので、
これを実行したところうまくコピーできました。

<br>
  
ただそれだけです。
ググっても 「`git b -m`を使え！」という記事しかなかったため、
「いや本当はコピーできるコマンドあるんじゃないの？」と思い公式を見たところ、やっぱりありました。

<br>

公式ドキュメントを参照する、大事なことです。
TouchDesigner でのドラッグ&ドロップについて

:::note warn
新しいバージョンでの記事を新しく書いているので以下のリンクをご参照ください
:::
https://qiita.com/joe0hara/items/9d13f77f8b651578e5fe

# 概要
TouchDesignerでのドラッグアンドドロップについて学んでいきます。

#####公式Wiki
https://docs.derivative.ca/Drag-and-Drop

## TouchDesignerでのD&D

####読み込み可能ファイルのインポート
ネットワークエディタに対してTouchDesignerで読み取れるファイル形式をドロップすることで対応するオペレータでそのファイルを読み取れるのはよく知られていると思います。
![drop_movie.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175399/d22618f0-44b0-f49c-4542-35919e5afc76.gif)

#### オペレータをエクスポート
ネットワークエディタ上にあるオペレータをデスクトップなどにドロップすると対応するファイル形式で保存されます。
TOX保存するとき便利！
![drop_op.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175399/4a9cfa4d-1c12-d174-a8c6-202eb7de0213.gif)

#### ほかのTouchDesignerのネットワークエディタにコピー
サンプルファイルから引っ張ってくるときとかに便利
(なぜか接続切れたところがありますが...)
![drop_tdtotd.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175399/aa62903f-32f2-3673-96cb-a6dec0c9195c.gif)

## Panel Components でのD&D
上記の例はネットワークエディタ上で行えるものですが自分で作ったUIに対しては自分でカスタマイズしてドラッグアンドドロップに対する処理を行うことができます。

### Drop Script
COMPのドロップスクリプトは他のCOMPやファイルがドロップされたときに実行されます。

### Drag Script
COMPがドラッグが始まったときに実行されます。

デフォルトでは ```/sys/drag, /sys/drop```になっていますがちょっと解説するには長かったので今回は省略します。


### Setting
Containerを作り、パラメータのDrag&Dropのタブで以下のように変更します。
![par.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175399/f8e2fd65-7a2f-087b-7b05-efb3cea5001c.jpeg)

### 取得できる値
####Drag
| args |  |
|:-:|:-:|
| args[0]  | ドラッグされたオペレータの名前  |
| args[1]  | ドラッグされているオペレータのインデックス  |
| args[2]  | ドラッグされているオペレータの数  |
| args[3]  | オペレータの種類  |
| args[4]  | ドラッグされているオペレータの親のパス  |

####Drop
| args |  |
|:-:|:-:|
| args[0]  | ドロップされたNodeの名前、CHOPのチャンネル名またはファイル名（ドロップされたものによる）  |
| args[1]  | マウスが離されたときのX座標  |
| args[2]  | マウスが離されたときのY座標  |
| args[3]  | ドロップされたもののインデックス  |
| args[4]  | ドロップされたものの総数  |
| args[5]  | オペレータの種類、又は拡張子  |
| args[6]  | ネットワークのフルパス、又は  |
| args[7]  | ドラッグされたCOMP  |

drag, drop ともに、```print(args)```と書き込みドラッグアンドドロップをしてみた例
![DD_example.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175399/7e351b9c-67e0-c38d-bc43-6ce343c7fef3.gif)


##実例
TouchDesignerでUIに動画ファイルやTOXファイルをドラッグアンドドロップして読み込む方法、およびUI上でCOMPをドラッグアンドドロップで操作できるもの

##こんな感じの

![TD_dropBank.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175399/6dedc430-ed84-1138-6323-499b7c3f5640.gif)

#### ファイル
[https://github.com/Joe0hara/TD_DragAndDrop](https://github.com/Joe0hara/TD_DragAndDrop)

###
上で学んだD&Dの知識で実現することができます。
ドロップされたファイルの拡張子やパス、Containerの名前などから行う処理を決めています。
Movie、Toxどちらも対応しているBankになっています。
中身みてよく分からないことやなぜこのようなことをしているかなど質問、意見のある方はTwitterかFacebookよりご連絡ください。
[Twitter](https://twitter.com/Joe0hara)
[Facebbok](https://www.facebook.com/Joe0hara)
AWS Elasticsearch service ではユーザー辞書の登録ができない

タイトルの通りです。
サービスで AWS Elasticsearch service の利用を検討している方は注意してください。

## ユーザー辞書ってなに？
Elasticsearchをあまり知らない人向けに説明しますと、文章を検索可能にする際には形態素解析を行います。
ElasticsearchにおいてはKuromojiというアナライザーを用いてこれを行いますが、これには辞書データが必要なのです。

例えば、
> すもももももももものうち

上記の文章は次のように分解できます。
> すもも　も　もも　も　もも　の　うち

アナライザーが`すもも`と`もも`を認識して分解するためには、これらの単語を知っている必要があります。
このデータソースが辞書データと呼ばれる物です。

あなたが考えている検索が、インターネット上に散らばる最新の単語を含むような場合、
あなたは最新の辞書データを作りつづけ、それをアナライザーの辞書データとして登録する必要があります。

**AWS Elasticsearch service はこれができません**

## じゃあどうすればいいの？

### 選択肢１： 自分でクラスターを構成する
AWSのマネージドElasticsearch serviceを使わず、EC2でElastciseachを構成します。
マネージドではない分管理が大変になりますが、その分対応していないElasticsearchのバージョンが利用できたり、ユーザー辞書の登録ができたりと自由を得られます。

### 選択肢2: N-gramを併用する
辞書データを作成することはそもそも大変です。
次々に生まれる日本語の造語に対応しようとすると、N-gramが選択肢に挙がってきます。
N-gramとは、文章をn個の文字で分割する方法です。必ずしも目的の単語で分割できるとは限りませんが、辞書にない単語でも検索できることがあります。

マッピングの設定では次のように設定することで、KuromojiとN-gramで分割したデータを定義できます。

```yml
textforsearch:
    type: text
    analyzer: kuromoji
    copy_to: textforseach_ng
textforsearch_ng:
    type: text
    analyzer: ja_ngram
```

検索の際は`textforsearch`と`textforsearch_ng`を検索対象に設定することで、ある程度検索を改善できるでしょう。
私が過去に開発に参加したサービスでは、この方法を用いてSNSサービスのインデックスを作成しています。
感想としては、特に問題ない印象です。

## 終わりに
Elasticsearch service でユーザー辞書が使えない件については、いろんな解説記事でわずかに書かれている程度でしたので、思いっきり啓蒙のために書いておきました。

AWSの人にも確認しましたが、申し訳ないが辞書登録出来ないんですごめんなさい！　って言ってました。
散々利用できるようにしてほしいという声はあるようなので、いつか対応することを願います。

利用を検討している人に届くことを願う。

## 参考資料
Elasticsearch の Kuromoji でユーザー辞書を使う
https://qiita.com/kijtra/items/d391179e1ea0be65e3f5

N-gramを作る
https://qiita.com/kazmaw/items/4df328cba6429ec210fb

Elasticsearchの辞書・同義語を調整して『築地銀だこ』の検索をカスタマイズした
https://blog.rista.jp/entry/2018/03/27/100100
独学DTPデザイナーがガッツリ「文字組み」の洗礼を受けた話 （フォトクリエイト Advent Calendar 2019 9日目）



こんにちは。フォトクリエイトでフォトレタッチや紙系デザイン担当の @eno-3 です。
この記事は [フォトクリエイト Advent Calendar 2019](https://qiita.com/advent-calendar/2019/photocreate) の 9日目です


#要約
はじめて「文字組み」をガッツリやった話です。
　・文字組みのチェックすべきポイント
　・作成したものにフィードバックをもらうことではじめてノウハウが得られる

自分のバンドのフライヤーや、PTAの広報になって**「文字をレイアウトしなければならない事態」**に陥った方に少し参考になるかもしれません。
また、弊社のデザインチームはこんなに~~厳しく~~優しく教えてくれるんだよアピールでもあります。

#まえがき
私はもともと建築関連の仕事をしていて、業種替えでDTPデザインの仕事へ。写真販売の会社で、フォトレタッチ、チラシや写真に入れるロゴ、EXPOブースのグラフィックもやらせてもらったりしてきました。つまりWEBじゃないほうのデザイナーです。

グラフィックデザインは**ずっと独学**でやってきましたが、会社の組織変更の動きもあって、ここへきてはじめて、**プロの先輩のディレクション**を受けながら**「文字組み」**を教えてもらう機会がありました。


####文字組みとはなんですか
いわゆる**タイポグラフィ**のことで、

>**「文字をならべて、余白を配置して、活字書体を使いこなす技」**
　by スタンリー・モリスン

のことです。まさに**「文字を組む」**んですね。


タイポグラフィの要素は**「活字」「組版」「余白」**の3つがありまして、それをうまいこと配置して、**文字を読みやすくしたり、雰囲気を伝えたり、目的に合わせた配置をする**というわけです。
（参考：Schoo「ミル文字ヨム文字ミセル文字」）

そして**書体には、文字ごとに隙間がちがうので、ただ文字を打っただけだと、詰まって見えたり、離れて見えたりする**んだなと覚えておいてください。

とはいえこういう座学を学んだのは実践のあとで（笑）
文字組みは**実際に添削を受けないと学べない**ことだろうと感じています。



####文字組みは「やりながら」学ぶ
基本的に単独作業しかしてこなかったのですが、突然？キャンペーンのプロジェクトチームに入り、WEBも紙も同時にチームで進行するという「ああ、オレもデザイナーっぽい☆」という憧れの職種になれたような錯覚を覚えつつ、文字組みの洗礼は始まりました。






***
**前置きが長くなりましいたが、実際に赤入れされたものをみながら振り返ってみます。**（※以下の画像は色を落とし**メモした文字**が読みやすいように調整してあります）



#はじめの一歩

###作るもの
このチラシは、ウェディング写真販売サイト[Gloriare](https://gloriare.jp/) をご利用いただいている式場のプランナー様に宛てたキャンペーンのチラシです。
デザインの方向はざっくりいうと**「すっきりエレガントでお礼も込めた文字主体のキャンペーンチラシ」**で、LPデザイン主導でそれとフィットした**紙チラシ**を制作します。

###最初の洗礼
実はディレクションをされながらデザインするのはこれがほぼ初体験。
![g10_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390630/4d7c60f2-49d1-ccb5-ccd4-756c2ac5c4b6.jpeg)
####＜ここをチェック＞
- 行間がせまい
- 漢字とかなの字間は、そのままではそろわない
- 伸ばし棒「ー」は90％縮小
- 端を揃える


特に「行間」「字間」はベタ組みすることがほとんどだったので、「え、そんなところも気にするの？」という**エディトリアルデザインの奥深さ**を知る旅のスタート。ここで学生になった気持ちになるワタシ。





#中盤戦
![g10_02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390630/3caf2fd0-901e-0751-1bc7-f7e915168395.jpeg)


####＜ここをチェック＞
- 行間がまだせまいかな（1.5～2.0とか）※今回の場合
- トラッキング「自動」をつかってフォントの持つ字間を基本にしてからカーニング調整
- 数字などはカタマリを意識する
- 「く」とか「り」とか注意（両脇が寂しくなりがち）
- フォントサイズは三種類まで（目から鱗）

ほぼ混乱状態になりながら、とにかくディテールを修正していくワタシ。



#最終形態

これがほぼFIXのときのが画像です。
![g10_03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390630/1a9a5b5b-39ab-47aa-e0eb-bf8c5865462a.jpeg)



序盤＞中盤＞最終 をならべてみると・・・
![g10_04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390630/79e29fda-d61c-a33f-90f6-8e37b9baabba.jpeg)

制作物の使用目的によりますが、今回は「すっきりエレガントでお礼も込めた文字主体のキャンペーンチラシ」だったので、すっきりエレガントになったかと思います。
このときは、もはや自分ではよくわからない状態でしたが、振り返ってみるとそうだとわかりますね。


#チェックポイントまとめ
- 漢字とかなの字間は、そのままではそろわない
- 伸ばし棒「ー」は90％縮小
- 端を揃えるとスッキリする
- 行間を1.5～2.0くらいにするとエレガント
- トラッキング「自動」をつかってフォントの持つ字間を基本にしてから調整（Illustrator）
- 数字などはカタマリとして意識する
- 「く」とか「り」とか注意（両脇が寂しくなりがち）
- フォントサイズは三種類までがよい
- 見る人の好みもあるっぽい

（※すべて状況によって異なる場合があります。あくまで目安です。）



なんでしょう、もう**言葉で説明することが不可能**ということはわかますよね。実際に**自分で組んで、フィードバック**をもらわないと、自分ではまったく気づけません。こうやって「センス」というものが身につくのだな、**チームってステキだな**、そう思いました。

また、**後遺症**として、街で見かた広告などの文章をみて、不快感を催したりする期間があるかもしれません（笑）


#さいごに
フォトクリエイトでは、OJTも学習支援制度も、メンバーの成長の機会がたくさんあります。少しでもご興味をお持ちいただけたようでしたら、人事部門の担当者 [twitter: @tetsunosuke](https://twitter.com/tetsunosuke) へお知らせください。
TensorFlowLiteのモデルをEdgeTPU用に変換する

ラズパイに[Coral USBAccelerator](https://coral.withgoogle.com/products/accelerator) を繋いで画像分類などしたいなーと思いモデルの変換方法を調べました。

TensorFlowLiteのモデルからEdgeTPU用のモデルコンパイルは、以前はWebコンパイラーがあってファイルをアップロードするだけで出来たらしいです。

が、今はWebコンパイラーが無く、[公式ページ](https://coral.withgoogle.com/docs/edgetpu/compiler/) ではDebianベースのLinuxを使った手順が書かれています。

RaspbianだってDebianベースだいっ、ということでRaspberryPi 3 Model B(Raspbian Buster)で公式の手順を試してみましたが普通に怒られました。

```
pi@raspberrypi:~ $ sudo apt-get install edgetpu
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
 edgetpu : Depends: edgetpu-compiler but it is not installable
E: Unable to correct problems, you have held broken packages.
```

64bitのARMv8なら大丈夫と公式ページに書かれてあり、RaspberryPi 3(4も)のCPUはハード的にはクリアしているはずですが、Raspbian上では``armv7l``となっているのでOSが対応していないようです。

そんなわけで、普段使いのOSが非Debian系の方は、PC上でDockerを使ってモデルのコンパイルをするのが良さそうです。

```dockerfile
FROM debian

WORKDIR /work

RUN apt-get update

RUN apt-get -y install \
  curl \
  gnupg2

RUN curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -

RUN echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" > /etc/apt/sources.list.d/coral-edgetpu.list

RUN apt-get update

RUN apt-get -y install edgetpu

RUN apt-get clean

CMD command
```

こんな感じのDockerfileを作成し、同じディレクトリにTensorFlowLiteのモデルを置いて以下のコマンドでいけました。

```shell
docker build -t tflite2edgetpu .
```

```shell
docker run -v `pwd`:/work tflite2edgetpu edgetpu_compiler model.tflite
```

（Windowsの方は `` `pwd` ``の部分を絶対パスにするなど適宜変更して下さい）
社内Python勉強会でWEBサーバ側の勉強してみた

社内の初心者向け勉強会（3回目）でWEBサーバ側プログラムを紹介したので、ココにも記述。

環境：windows10、python3.7

Pythonでは簡単なWEBサーバのライブラリを提供しています。
コマンドだけでWEBサーバの起動が出来ます。
※WEBサービスの説明は割愛

今回は、開発が容易なCGIを使って実装します。
CGIとは、ブラウザからの要求に対して処理を行う仕組みです。

コマンド発行したpath以下を公開するので公開したい場所で
以下のコマンドを実行してください。

```
>python -m http.server 8888 --cgi
```
例えば、
d:\work\py_test\
上記pathで実行した場合は
d:\work\py_test\　にhtmlを置き
d:\work\py_test\cgi-bin\　に呼び出されるpythonファイルを置きます。

業務システムの場合、サーバ側へのデータ保管はデータベース（以下DB）を使用しますが、
今回、DBを準備するのは時間がかかる為、ファイルにデータを保管する方法で実装してみました。

Pythonでは、ファイル操作もDB操作も簡単に実装出来ます。
操作は似たようなもので
開く　→　使う　→　閉じる
の手順です。

以下のソースファイルを作成します。

↓　d:\work\py_test\　に置く

```html:file_tesl.html
<html>
	<head><meta http-equiv="content-type" charset="utf-8"></head>
	<body>
	ファイル操作のテスト
	<br>
	<form action="http://localhost:8888/cgi-bin/cgi_file_test.py" method="get">
	    <div>名前を入力<input name="name" id="name" value=""></div>
	    <button>実行</button>
	</form>
	</body>
</html>
```

↓　d:\work\py_test\cgi-bin\　に置く

```python:cgi_file_test.py
import cgi
import os

# パラメータの受け取り
form = cgi.FieldStorage()
str_name = form["name"].value

# ファイルに書き出し（追記モード）
f = open('./data/test.txt','a')
f.write(str_name + "\n")
f.close()

# ファイルから読込
read_str = ""
with open('./data/test.txt','r') as f:
    for row in f:
       read_str = read_str +"<br>"+ row.strip()

# htmlで出力する
print ("Content-Type: text/html")
print ()
print ("<html><body>")
print ("これまでに入力された名前は",read_str,"<br>")
print ("<a href=\"../file_test.html\">戻る</a>")
print ("</body></html>")
```

WEBブラウザに以下のURLを入力して表示して動作を確認します。

```
http://locahost:8888/file_tesl.html
```

WEBブラウザで表示したら、名前入力して「実行」押下してみよう。
画面遷移したら、「戻る」押下し、
名前をドンドン入力してみよう。

追記されていくのが確認できます。

この様にPythonではcgiが簡単に作れるだけでなくファイル操作も超簡単に出来てしまいます。

実業務のWEBシステムではフレームワークを使うので、この様なcgiを書くことはホボ無いですが簡単にWEBシステムを実現できるので色々試してみてはいかがでしょうか。
labelImgが動かない場合の対処法


![Screenshot from 2019-11-22 17_06_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191313/a19f6da1-0741-9d61-8fe7-bbd9cc7f309d.png)

##環境
Ubuntu-14.04


#labelImgの動かし方
labelImgは深層学習を用いた物体検出のアノテーションツールとして有名です．

しかしこちらのlabelImgの公式Github
https://github.com/tzutalin/labelImg
のREADME通りやるとpyqt5まわりでエラーが多発して動かないことが多いです．


##LinuxユーザまたはWindowsユーザの場合
LinuxユーザまたはWindowsユーザであれば，
https://github.com/tzutalin/labelImg
もうこちらは使いません．

代わりに，
https://tzutalin.github.io/labelImg/
の
**Linux_v1.4.3**（投稿時，ページ一番下の最新バージョン）

をダウンロードして，
展開先のディレクトリにターミナルで移動して，

```
./labelimg
```

するだけ．
これで起動できます．


##Macユーザの場合
Macユーザであれば，
https://github.com/tzutalin/labelImg
こちらのリポジトリをクローンしてcdしたあとに，以下を行い，アプリを作成します．

```
brew install python3
pip install pipenv
pipenv --three
pipenv shell
pip install pyqt5 lxml

make qt5py3
rm -rf build dist
python setup.py py2app
cp -rf dist/labelImg.app /Applications
exit
```

これでおしまい．
あとはアプリを叩くだけ．

###P.S.
機械学習，自動運転などをメインに（たまにそれ以外も）発信しているのでぜひ [twitterのフォロー](https://twitter.com/ryosanworld)おねがいします．
Error: net::ERR_CONNECTION_REFUSED : #Docker + #Rails 環境で public ディレクトリにあるファイルを headless Chrome で HTML PDF 変換しようとした時のメモ

# NOTE

- curl では rails の public な URL に接続できる状態。
- rails の publiic directory に HTML file を設置して、headless chrome からアクセスしてPDF変換しようとしたとき。( http://localhost:3000/some.html )
- chrome では localhost が 127.0.0.1 に割り当てられておらず、localhost が使えない場合がありそうだが詳しくは未確認。 http://127.0.0.1:3000/ にアクセスさせると良いかも。
- 最初 node + puppeter を通して実行させていたが、 どうやら chrome 本体の処理で問題が起きていそうだった。
- http://127.0.0.1:3000/some.html に接続しても動かず `Error: net::ERR_CONNECTION_REFUSED` が起こることがあった
- docker container で hostname -i した結果のIPアドレスに対して chrome をアクセスすると動くケースがあった。 ( http://172.26.0.1:3000/some.html )

# コマンド例

```
chromium-browser --headless --no-sandbox --disable-gpu --print-to-pdf http:/xxx/
google-chrome-stable --headless --no-sandbox --disable-gpu --print-to-pdf http:/xxx/
```

# 参考

[ヘッドレス Chrome ことはじめ  |  Web  |  Google Developers](https://developers.google.com/web/updates/2017/04/headless-chrome?hl=ja)

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2752








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->