OmniAICreator/Qiita-1.07M huggingface dataset:
Node.js v11.13.0リリースノート

https://nodejs.org/ja/blog/release/v11.13.0/

# crypto
- Allow deriving public from private keys
    - 秘密鍵から公開鍵が作成できるようになった

# events
- Added a once function to use EventEmitter with promises
    - EventEmmiterでPromiseを使うために、`once()`を追加

# tty
- Added a hasColors method to WriteStream
    - WriteStreamに`hashColors()`を追加
- Added NO_COLOR and FORCE_COLOR support
    - 環境変数に`NO_COLOR`と`FORCE_COLOR`を追加

# v8
- Added v8.getHeapSnapshot and v8.writeHeapSnapshot to generate snapshots in the format used by tools such as Chrome DevTools
    - `v8.getHeapSnapshot()`と`v8.writeHeapSnapshot()`を追加
        - Chrome DevTools等で使用されている形式のスナップショットを生成するため

# worker
- Added worker.moveMessagePortToContext. This enables using MessagePorts in different vm.Contexts, aiding with the isolation that the vm module seeks to provide
    - `worker.moveMessagePortToContext()`を追加
        - 異なるvm.ContextsでMessagePortsが使用可能になる？

# C++ API
- AddPromiseHook is now deprecated. This API was added to fill a use case that is served by async_hooks, since that has Promise support
    - AddPromiseHookが非推奨になった
- Added a Stop API to shut down Node.js while it is running
    - 実行中のNode.jsを終了するためのStop APIをついか
Node.js v11.12.0リリースノート

https://nodejs.org/ja/blog/release/v11.12.0/

# bootstrap
- Add experimental --frozen-intrinsics flag
    - --frozen-intrinsicsオプションが試験的に追加された
        - 配列やオブジェクトの中身も変更不能になるdeep freezeが使用可能になる？

# build
- Enable v8's siphash for hash seed creation
    - hashのシード生成にv8のsiphashが利用可能になった
        - HashWick(hash関数の結果が予測できてしまう脆弱性)への対応

# deps
- Upgrade openssl to 1.1.1b
    - opensslが1.1.1aから1.1.1bに更新された

# process
- Make process[Symbol.toStringTag] writable again
    - process[Symbol.toStringTag]を書き込み可能に戻した

# repl
- Add util.inspect.replDefaults to customize the writer
    - writerをカスタマイズするためにutil.inspect.replDefaultsを追加

# report
- Rename triggerReport() to writeReport()
    - triggerReport()をwriteReport()に名前変更
Node.js v11.11.0リリースノート

https://nodejs.org/ja/blog/release/v11.11.0/

# n-api
- Implement date object
    - Dateオブジェクトが使用可能になった

#util:
- Add compact depth mode for util.inspect()
    - util.inspect()で、文字列にする配列やオブジェクトの要素の深さを指定できるようになった


# worker:
- Improve integration with native addons
    - 複数のNode.jsインスタンスからアドオンを読み込めるようになった？
- MessagePort.prototype.onmessage takes arguments closer to the Web specification now
    - onmessage()の引数がWebの仕様に近いものになった？
Node.js v11.10.1リリースノート

https://nodejs.org/ja/blog/release/v11.10.1/

# http
- Further prevention of "Slowloris" attacks on HTTP and HTTPS connections by consistently applying the receive timeout set by server.headersTimeout to connections in keep-alive mode. (CVE-2019-5737 / Matteo Collina)
    - スローロリス攻撃対策のために、server.headersTimeoutでキープアライブモードでの接続にタイムアウトを設定できるようになった。
Swift：最前面にあるアプリケーションが何かを監視する

# 背景
macOS向け常駐アプリを作っていて，最前面(frontmost)にあるアプリが何であるかを監視し続けたくなった．これまでタイマーを使って定期的に最前面のNSWindowのオーナーを調べるという方法を取っていたが，最前面のアプリが切り替わったタイミングのみで監視対象の更新を行いたかった．

# 実装
```swift:Appdelegate.swift
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    func applicationDidFinishLaunching(_ aNotification: Notification) {	
        NSWorkspace.shared.notificationCenter.addObserver(self,
                                                          selector: #selector(check(_:)),
                                                          name: NSWorkspace.didActivateApplicationNotification,
                                                          object: nil)
    }
    
    @objc func check(_ notification: NSNotification) {
        guard let name = NSWorkspace.shared.frontmostApplication?.localizedName else {
            return
        }
        Swift.print(name)
    }
}
```
`NSWorkspace.didActivateApplicationNotification`の通知タイミングで最前面のアプリケーションを調べれば良い．
IntelliJのPlantUMLプラグインで壮大なシーケンス図書いたら、途中で切れて困ってるかたへ

# はじめに
PhpStorm(IntelliJ)のPlantUMLプラグインを入れて以来、ユースケースやシーケンスさらにワイヤーフレームなど、どんな図もこれで作るようになってきた今日この頃なのですが、ちょっと頑張りすぎて壮大な図を作っちゃったら、下のほうが切れちゃってるじゃないですか。。
そんな凹む場面に出くわして解決を諦めかけてるあなたのための記事です。

# 症状
例えば、下記のようにスクロールしても途中までしか表示できていません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68254/2c755ddb-1cf9-3d7f-6460-8a21a57674d8.png)

# 原因
png画像の最大サイズ(4096)を超えているのが、原因のようです。

# 対処法
Help -> Edit Custom VM Options... で
``-DPLANTUML_LIMIT_SIZE=8192``
って感じでちょっと大きめ(とりあえず２倍)を追記して、PhpStorm(IntelliJ)を再起動してあげましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68254/fa7ec7b1-519c-1d2b-6fa0-87694e570d89.png)

# 結果
ほら！ちゃんと最後まで表示されましたね！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68254/14d3d855-b224-c96c-cc73-6fff32343e56.png)

# 参考
https://www.pospome.work/entry/20160422/1461322513
http://plantuml.com/ja/faq
Vueでwindowのグローバル変数を呼ぶときの話

# 概要
twitterのシェアボタンwidjetをあるオブジェクトがロードされてから表示するようにしたら、
widjetにならなかったので、`twttr.widgets.load()`で呼び出そうとしたら、
うまく呼び出せなくて、呼び出すことができた方法のメモです。

# Twitterウィジェット
https://publish.twitter.com/#
上記のTwitter公式から生成したものですが、下記のように`widjets.js`を読み込んで、`class="twitter-share-button"`を指定すると、aタグがtwitterのシェアボタンウィジェットになります。

```html
<a href="https://twitter.com/share?ref_src=twsrc%5Etfw" class="twitter-share-button" data-show-count="false">Tweet</a>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
```

しかし、最初から表示されてるオブジェクトにしか適用されず、Vueのv-ifディレクティブを使用したりして動的にボタンを表示する場合は適用されません。
この場合、`widjets.js`が読み込まれた際にグローバル変数に追加される`twttr`を利用して、`twttr.widgets.load()`をしてウィジェットを描画する必要があります。
> [非同期で読み込んだFacebook, Twitterボタンを再描画する](https://qiita.com/kzhrk/items/5bc39df48dc1ab8ea850)

# Vueの単一ファイルコンポーネントの場合
このとき、Vueの単一ファイルコンポーネントの場合、下記のようにscriptタグ内で`twttr.widgets.load()`を呼ぼうとすると`twttr`が存在しないと言われてしまいます。
どうやら、グローバル変数に直接アクセスができないことが問題のようでした。

```vue:twitter.vue
...
<script>
export default {
  name: 'Twitter',
  data () {
    return {
    }
  },
  methods: {
    reloadWidgets () {
      twttr.widgets.load()
    }
  }
}
</script>
...
```
ですので、この場合は下記のように`window`からアクセスすることで、`twttr`にアクセスすることができ、`twttr.widgets.load()`を呼ぶことができます.


```vue:twitter.vue
...
<script>
export default {
  name: 'Twitter',
  data () {
    return {
    }
  },
  methods: {
    reloadWidgets () {
      window.twttr.widgets.load()
    }
  }
}
</script>
...
```

# あとがき
色々試行錯誤していたため、書いてる最中に`window`をスクリプトタグから呼べるんじゃないかと気づきました。
試行錯誤中に試してはいたのですが、他の要因からうまくできなかったため、この記事を書いている最中は下記のように、
`main.js`で`Vue.prototype.$twttr`に変数を割り当ててインスタンスプロパティを設定する方法を紹介しようとしていました。
この方法だと、コンポーネント内から`this.$twttr`で参照することができます。

```vue:main.js
Vue.prototype.$twttr = window.twttr
```

ちなみに、スマホから見るとなぜか`widjets`がundefinedと言われて、うまくウィジェット化できなかったため、
実際の実装では`https://twitter.com/intent/tweet`を利用して、見た目は自作しました。
select2のマルチ選択で自動的に候補エリアの位置を調整する

### はじめに
select2でマルチ選択時に項目を多く選択し、その結果改行が発生する場合に、選択済項目の一部が候補エリアの下に隠れてしまい、自分が何を選択したかわからりずらい状況となる。一旦候補エリアを閉じて再度選択しなおせばよいが、コントロールキーを押しながら連続して選択したいにもかかわらず、一旦閉じるのも不便である。この問題の解決のため、select2のソースを修正したのでメモっておく。


### 環境
- Windows10
- select2 4.0.6-rc.1

### 問題となる状況
以下のように県を複数選択した状態で、次にCtrlキーを押しながら「群馬県」を選択したとする。その場合、「北海道」から始まる行の次の行に「群馬県」が選択されて表示されることになるが、候補エリアの表示位置は変わらないため、選択した「群馬県」はその下に隠れて見えない。また「群馬県」を選択すると、候補エリアのスクロール位置が一旦最上部の「北海道」に戻るため、あらためて選択したい項目の位置までスクロールする必要がある。これはストレスになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329816/206bcbdf-b268-61cd-921b-b36896c75c2f.png)

### 対策
select.jsの1111行目付近を以下の通り修正する

```javascript
    container.on('select', function () {
      if (!container.isOpen()) {
        return;
      }

      tmpScrollTop = self.$results.scrollTop();  // 追加
      self.setClasses();
      container.dropdown._positionDropdown();   // 追加
      self.$results.scrollTop(tmpScrollTop);    // 追加
      
      // self.highlightFirstItem();             // 削除
    });

    container.on('unselect', function () {
      if (!container.isOpen()) {
        return;
      }
      tmpScrollTop = self.$results.scrollTop(); // 追加
      self.setClasses();
      container.dropdown._positionDropdown();   // 追加
      self.$results.scrollTop(tmpScrollTop);    // 追加
      //self.highlightFirstItem();              // 削除
    });

    container.on('open', function () {
      // When the dropdown is open, aria-expended="true"
      self.$results.attr('aria-expanded', 'true');
      self.$results.attr('aria-hidden', 'false');

      self.setClasses();
      self.ensureHighlightVisible();
    });

    container.on('close', function () {
      // When the dropdown is closed, aria-expended="false"
      self.$results.attr('aria-expanded', 'false');
      self.$results.attr('aria-hidden', 'true');
      self.$results.removeAttr('aria-activedescendant');
      
      tmpScrollTop = 0;  // 追加
    });
```

### 結果
上の通り修正をすると、先ほどの問題となる状況で「群馬県」を選択した後に以下のように候補エリアの表示位置が下にずれるため、「群馬県」が選択されていることが分かるようになる。また、候補エリアのスクロール位置が先頭に戻らないため、続けて「埼玉県」などを選択することができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329816/973a4b44-7dab-db07-5e65-1c23d67e23c3.png)
モブプロ用にCommit &Pushを1発で出来るスクリプトを作ってみた。

# 前置き
こんにちは、ハッピー佐藤です！

みなさんはモブプロやってますか？
最近開発チームでモブプロを始めましたが、色々と問題が起きました。

- 普段使ってる配列と違うキーボードで混乱
- リモートワーク中に遠隔操作すると、ラグがあってまともにコードを触れない
- IDEやVimといった開発環境の違い

モブプロ自体は全員が肯定的でしたが、開発のパフォーマンスに少し影響がありました。
やはりエンジニアは自分の好きな環境で開発したいですよね！

そこでGitHubを通してスムーズにドライバー（タイピングする人）を交代すべく、Commit &Pushを一発で行うべくスクリプトを作ってみました！
（シェルスクリプト初心者なので、実装が汚いのはお許しください！）

# 必要な機能
・1コマンドでプッシュ出来る
・共同編集者を記録する
複数の人が1つのコミットに関わる為、こちらを参考にメッセージに記録出来るようにしています。

自分が会社で使う事を前提としておりますので、全員のメールドメインが同じという仕様ですがお許しください。

# 完成したもの
```mob.sh
#!/bin/bash

#check current branch
NB=`git rev-parse --abbrev-ref HEAD`

if [[ 'master' = ${NB} ]]; then
    echo 'Not allowed master commit'
    exit 1
fi

#get date
date=`date`

#create commit message
CM="git commit -m 'mob commit
${date}
"
ORG_IFS=$IFS
MOD_IFS=","
IFS=${MOD_IFS}

for i in $1
do
IFS=${ORG_IFS}
CM+="
Co-authored-by: ${i} <${i}@happysato.com>"
IFS=${MOD_IFS}
done
IFS=${ORG_IFS}

CM+="'"

#git commit
eval "${CM}"

#git push
`git push origin HEAD`
```


いい感じに改行出来る方法をご存知方は教えてください！

# 使い方
ドライバー終了時に、以下のようにコマンドを打ち込んで下さい。
. mob.sh happy,sato
そうするとコミットメッセージは次のようになります

```
mob commit
Fri Apr 26 20:53:24 JST 2019

Co-authored-by: happy <happy@happysato.com>
Co-authored-by: sato <sato@happysato.com>
```

GitHubではこのように表示され、共同で編集したメンバーが分かります。

<img width="517" alt="スクリーンショット 2019-05-07 0.17.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253532/db2b9cf8-8dd4-6b75-fe7f-0e9c12e1c065.png">

あとは次のドライバーがpullして、自分の環境で開発を始めてください。

コミットメッセージが荒れて嫌だという方は、プルリクをGitHubでまとめてmergeするSquash and merge等の機能がありますので、ご自身の環境に合わせてお使いください。（[参考](https://qiita.com/ko-he-8/items/94e872f2154829c868df)）

シェルスクリプトに実行権限を与えるなどは、他の記事をご参考下さい！

# 終わりに
こんな方法でモブプロやリモートワークを便利にしてるよ！という事例がありましたら是非教えてください！
Akka HTTPでHTTPS通信する

`Akka HTTP`で(とりあえず)HTTPS通信をするための備忘録。

# Akka HTTPでHTTPS通信をするには？
[公式ドキュメント](https://doc.akka.io/docs/akka-http/10.0.2/scala/http/server-side-https-support.html#using-https)に書いてあるとおりにする。
言われたとおりにするためにPKCS12形式のファイルを作成する。

# PKCS12ファイルの作成

### 秘密鍵の作成
``` bash
# AES128で2048bitの秘密鍵
# このファイルは公開してはいけない
> openssl genrsa -aes128 2048 > sample.key

Generating RSA private key, 2048 bit long modulus
....+++
.........................+++
e is 65537 (0x010001)
Enter pass phrase:
Verifying - Enter pass phrase:
```

### CSR(証明書署名要求)の作成
色々聞かれるけど、任意入力なので無視することも可能。

``` bash
> openssl req -new -key sample.key > sample.csr

Enter pass phrase for sample.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
``` 

### 署名
``` bash
# 有効期限は365000日(1000年)
> openssl x509 -in sample.csr -days 365000 -req -signkey sample.key > sample.crt

Signature ok
subject=C = AU, ST = Some-State, O = Internet Widgits Pty Ltd
Getting Private key
Enter pass phrase for sample.key:
``` 

### PKCS12形式に変換する
``` bash
> openssl pkcs12 -export -inkey sample.key -in sample.crt -out sample.p12

Enter pass phrase for sample.key:
Enter Export Password:
Verifying - Enter Export Password:
```

# あとは
`resources`などのパスが通っている場所にPKCS12ファイルを置けば`Akka HTTP`でHTTPS通信ができるようになる。
Google Cloud Functions (Go1.11) チュートリアル

# お題
Google Cloud Functions（Go1.11）のクイックスタートとチュートリアルを通して各機能を確認していく。
今回は、ひとまずクイックスタート。
あと、Goモジュールを使ったプロジェクトのデプロイに関するチュートリアルだけ。

基本的に以下を参考に進めていく。
https://cloud.google.com/functions/docs/

# 前提
- [GCP](https://cloud.google.com/?hl=ja)は知っている。

以下は済んだ上での作業。

- GCPプロジェクトの作成
- [Cloud SDK](https://cloud.google.com/sdk/docs/)のインストールと初期化・認証

# 開発環境
### # OS
```
$ cat /etc/os-release 
NAME="Ubuntu"
VERSION="18.04.2 LTS (Bionic Beaver)"
```

### # Cloud SDK
```
$ gcloud version
Google Cloud SDK 244.0.0
```

### # Golang
```
$ go version
go version go1.11.4 linux/amd64
```

# 実践
## Quickstart
### 参考
https://cloud.google.com/functions/docs/quickstart


### ソース

```go:[QuickStart/helloworld.go]
package Quickstart

import (
	"fmt"
	"net/http"
)

func HelloWorld(w http.ResponseWriter, r *http.Request) {
	if _, err := fmt.Fprint(w, "Hello, World! (go111)"); err != nil {
		fmt.Println(err)
	}
}
```

### デプロイと動作確認

```
$ pwd
/home/sky0621/work/src/go111/src/github.com/sky0621/tips-go/try/gcp/gcfgo/Quickstart
$
$ gcloud functions deploy HelloWorld --runtime=go111 --trigger-http
Deploying function (may take a while - up to 2 minutes)...done.
　〜〜　省略　〜〜
```

![screenshot-console.cloud.google.com-2019-05-06-21-55-02-520.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180599/b65fa0d3-f95f-7375-40fb-3c8024196698.png)

```
$ curl https://us-central1-【GCPプロジェクトID】.cloudfunctions.net/HelloWorld
Hello, World! (go111)
```

## Structured
### 参考
https://cloud.google.com/functions/docs/writing/

### 留意点
Goランタイムの場合、関数はプロジェクトのルートにあるGoパッケージに含まれている必要がある。
関数を`main`パッケージにするのは不可。
サブパッケージは、Goモジュールを使用している場合にのみサポート。

### ソース

```
$ tree
.
├── function.go
├── go.mod
├── go.sum
└── subpkg
    └── jsonform.go
```

```go:[Structured/function.go]
package Structured

import (
	"Structured/subpkg"
	"encoding/json"
	"fmt"
	"net/http"

	"go.uber.org/zap"
)

var lgr *zap.Logger

func init() {
	var err error
	lgr, err = zap.NewProduction()
	if err != nil {
		panic(err)
	}
}

func StructuredHello(w http.ResponseWriter, r *http.Request) {
	var jf subpkg.JsonForm
	if err := json.NewDecoder(r.Body).Decode(&jf); err != nil {
		lgr.Error(err.Error())
	}
	if _, err := fmt.Fprintf(w, "Hello, %s(%s)", jf.Name, jf.ID); err != nil {
		lgr.Error(err.Error())
	}
}
```

```go:[Structured/subpkg/jsonform.go]
package subpkg

type JsonForm struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}
```

### デプロイと動作確認

```
$ pwd
/home/sky0621/work/src/go111/src/github.com/sky0621/tips-go/try/gcp/gcfgo/Structured
$
$ gcloud functions deploy StructuredHello --runtime=go111 --trigger-http
Deploying function (may take a while - up to 2 minutes)...done.
　〜〜　省略　〜〜
```

![screenshot-console.cloud.google.com-2019-05-06-23-27-58-751.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180599/ba1f393b-9c57-55ab-b610-89c25121f0b0.png)

```
$ curl -X POST \
>   https://us-central1-【GCPプロジェクトID】.cloudfunctions.net/StructuredHello \
>   -H 'Content-Type: application/json' \
>   -H 'cache-control: no-cache' \
>   -d '{
> "id": "001",
> "name": "Sato"
> }'
Hello, Sato(001)
```
juliaをソースからビルドする際のmakeエラー

環境
Ubuntu18.04


---
Juliaを`git clone`してから`make`すると

```
Makefile:60: recipe for target 'julia-deps' failed
make: *** [julia-deps] Error 2
```

のエラーが出る場合の解決策をメモ


### 結論

`$ sh download_cmake.sh`をしないと`make`でエラーが出てしまいます。<br>
以下のようにしましょう。




Juliaのbuild方法

```
$ git clone https://github.com/JuliaLang/julia.git
$ sh ./julia/contrib/download_cmake.sh
$ make -j6
$./julia
```



----
### 参照
[プログラミング/julia/インストール](https://dora.bk.tsukuba.ac.jp/~takeuchi/?%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%2Fjulia%2F%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)
【Git】誤ってcommitしてすぐに戻したいとき

## 結論

作業メモ。結論を先に書く。

以下のコマンドをすぐに打とう。

``` git
git reset --soft HEAD^
```

GW中にhooksでpre-commitの検証を行っているときにアホほど打ったので、覚えてしまった…。


## --soft

--softだと、「commitをしなかった状態」なので、編集していたファイルは残る。つまり、「インデックスにステージングした状態」に戻す。  
間違いがなくて、安心だと思います。

## --hard

これを```git reset --hard HEAD^```にすると、「commit自体をなかったことにして、１つ前のcommitの状態に戻す」ことになるので、_commitしたファイル_ も消えてしまいます。  
一挙にまるまるリセットしたいときは、```--hard```で良いと思いますが、ちゃんと考えてからやったほうが良いでしょうね。  
つまり、以下の流れを一挙にやるイメージです。

 1. ```git reset --soft HEAD^```
 1. ```git reset HEAD .```
 1. 対象ファイルを削除

## --mixed

```git reset --mixed HEAD^``` は、上の箇条書きで言うところの2.に当たる部分までやるという感じです。なんだか中途半間な感じがして、あまり使わない気がします。
【Python】【Django】お天気予報機能1(要件整理)

##はじめに
livedoor提供のお天気Webサービスに興味を持ったため、Djangoを利用したお天気検索ページを作成することにしました。(実装環境はPaizaCloud)

APIの概要：市町村ごとのID(以後、「市町村ID」と呼称)をリクエストパラメータとして引き渡すと、IDに紐づくお天気情報(JSONデータ)が返却されるAPI。
http://weather.livedoor.com/weather_hacks/webservice

以下がサンプルコード。

```
import requests

url = 'http://weather.livedoor.com/forecast/webservice/json/v1'
payload = {'city':'290010'} # 奈良県の市町村ID
tenki_data = requests.get(url, params=payload).json() 
print('地方：', tenki_data['location']['area'])
print('都道府県：', tenki_data['location']['prefecture'])
print('市町村：', tenki_data['location']['city']) 
print()
print(tenki_data['forecasts'][0]['dateLabel'] + ' の天気は ' + tenki_data['forecasts'][0]['telop'] + ' です。')
print(tenki_data['forecasts'][1]['dateLabel'] + ' の天気は ' + tenki_data['forecasts'][1]['telop'] + ' です。')
```

以下が実行結果。

```
地方： 近畿
都道府県： 奈良県
市町村： 奈良

今日 の天気は 曇り です。
明日 の天気は 晴れ です。
```

##作成予定の画面
【1】地域情報一括更新画面
・市町村IDを管理しているxmlを取り込み、テーブルとして管理する為の画面。
xml：http://weather.livedoor.com/forecast/rss/primary_area.xml

・作成するテーブルは「都道府県テーブル(親)」と「市町村テーブル(子)」。「市町村テーブル(子)」で「市町村ID」を管理する。

・画面上の更新ボタンを押下することで以下の処理を行う。
　1. 「都道府県テーブル(親)」、「市町村テーブル(子)」の初期化。
　2. xmlファイル読み込み、解析。
　3. 解析したxmlファイルのデータを「都道府県テーブル(親)」と「市町村テーブル(子)」へ格納する。

【2】お天気検索画面
・画面上の「都道府県プルダウン」「市町村プルダウン」を選択し、確定ボタンが押下されたタイミングで天気情報を画面表示する。「都道府県プルダウン」には「都道府県テーブル(親)」のデータを、「市町村プルダウン」には「市町村テーブル(子)」のデータを設定する。

・「都道府県プルダウン」の選択値に応じて「市町村プルダウン」のデータを制御する。
(例：「都道府県プルダウン」が「奈良県」の場合、「市町村プルダウン」には「奈良、風屋」を選択肢として表示する。)

・《可能であれば》GoogleMapを表示し、選択された市町村の箇所にピン付けする。
(プルダウン選択後か確定ボタン押下後かは検討中。なお、フィジビリティー確認も不十分な為、見送る可能性あり。)

##Next
まずは【1】地域情報一括更新画面を作成します。

↓続き
https://qiita.com/oshiro-pooh/items/2071b38cbe02807c086f
Nuxt.js + Firestore で動的サイトマップ

令和元年記念で5月1日にアップする予定でしたが、GW10連休長過ぎ問題（ほぼ子供のお世話してた）で中断し遅れに遅れたのでとりあえず投稿してしまいます。
この例はブログ記事を想定してます。（動的サイトマップ部分はブログ記事。Firestore の DB　は `articles`）

## Install

- nuxt (v2.6.3)
- firebase (v5.10.1)
- @nuxtjs/sitemap (v1.0.0) 


## nuxt.config.js

（コード一部抜粋）

```javascript
const axios = require('axios')

const API_URL = `https://firestore.googleapis.com/v1/projects/YOUR_PROJECT_ID/databases/(default)/documents/`

function convertObjToSitemapDataArr ({ obj, path, changefreq }) {
  const arr = []
  obj.data.documents.forEach((doc) => {
    const id = doc.name.match(/(\/.+\/)(.+?)$/)[2]
      arr.push({
        url: `${path}/${id}`,
        changefreq: changefreq,
        priority: 1,
        lastmod: new Date(doc.updateTime)
      })
  })
  return arr
}

module.exports = {
  // ...
  modules: [
    '@nuxtjs/sitemap'
  ],
  sitemap: {
    path: '/sitemap.xml',
    hostname: 'https://example.com',
    cacheTime: 1000 * 60 * 60 * 24, // 24 hours
    gzip: true,
    generate: true,
    exclude: [
      '/404',
      '/accounts/**',
      '/articles/new',
    ],
    routes (callback) {
      return Promise.all([
        axios.get(`${API_URL}articles`),
        axios.get(`${API_URL}users`)
      ]).then(([articles, users]) => {
        callback(
          null,
          [
            convertObjToSitemapDataArr({ obj: articles, path: 'articles'}),
            convertObjToSitemapDataArr({ obj: users, path: 'users', changefreq: 'monthly'})
          ].reduce((accumulator, currentValue) => accumulator.concat(currentValue), [])
        )
      })
    }
  }
}
```

### api の取得データ例

```shell

$ curl https://firestore.googleapis.com/v1/projects/${projectId}/databases/(default)/documents/articles
{
  "documents": [
    {
      "name": "projects/YOUR_PROJECT_ID/databases/(default)/documents/articles/xxxxxxxxxxxxx",
      "fields": {
        "title": {
          "stringValue": "article_name01"
        },
        "body": {
          "stringValue": "It is very fine today."
        },
        "tags": {
          "arrayValue": {
            "values": [
              {
                "stringValue": "tag01"
              }
            ]
          }
        },
        "rating": {
          "integerValue": "5"
        }
      },
      "createTime": "2019-04-29T03:09:28.011455Z",
      "updateTime": "2019-04-30T05:55:08.013727Z"
    }
  ]
}
```

## サイトマップにアクセス

`/sitemap.xml` にアクセスすると表示されるはず。

大体こんな感じ


## 参考リンク

https://firebase.google.com/docs/firestore/use-rest-api?hl=ja
https://github.com/nuxt-community/sitemap-module#readme
https://qiita.com/sauzar18/items/2ea958043eb6758c4f83
https://qiita.com/bucchi49/items/d271c4010a3f6c900926
入力項目の意味を調べる

前回書いた以下`hello.go'の中身、特に前半に書いてある以下３つの意味をちゃんと知っておきたい。内容を読めばなんとなく分かるけど、所詮なんとなくなので。

1. `package main`
2. `import "fmt"`
3. `func main() ` 

```
package main

import "fmt"

func main() {
        fmt.Println("hi.this is small step,but will be big one for me.")
    }
```

文言を検索すると色々と解説しているサイトが出てくるが残念ながら自分にはちゃんと理解出来なかった。今日は遠方から戻ってきて疲れたのでまた明日調べ直す。そんな訳でお休みなさい。
vue createからGithub Pagesへ反映させるまで

### はじめに

vue-cliで作ったvueプロジェクトをbuildして、
GithubPagesへデプロイするまでの走り書きです。
GithubPagesがサブパスへのデプロイになるので、
コンパイル設定をする必要があることに気づかなくてちょっと詰まったので残しておきます。
https://github.com/k-karen/test-app
https://k-karen.github.io/test-app/index.html

### 1. repository作成 & git clone
githubでrepositoryを作成。
`git clone https://github.com/k-karen/test-app.git`
とかでCloneしてくる

### 2. vue create ~ build
cloneしたrepository配下までcdしてから

```
# レポジトリ名と同じ名前のアプリでいいなら、vue create . でOK。
# オプションは適当でOKだと思います(babel,PWAをマニュアルで選択して私は行いました)
vue create .

# 下記のファイルを作る
vi vue.config.js

# buildの設定を作ったらbuildする
yarn build

# git add -A & git push origin headとかで適当に今までの変更をgithubへpush
```

```vue.config.js
// publicPathはRepositoryNameにしてください
module.exports = {
 publicPath: 'test-app',
 outputDir: 'docs'
}
```

### 3. githubの設定
github上のSettingsからGitHub Pages の Source を `master branch /docs folder` にする。
https://k-karen.github.io/test-app/index.html
と反映できたことが確認できたかと思います。


### 最後に

vue-cliでのbuild時のコンパイルは、サブパス想定じゃないので、
publicPathを設定する必要があるっぽいです。
詳しくは[こちら](https://cli.vuejs.org/config/)を御覧ください  

outputDirをdocsにしているのは、GithubPageのsourceにdocsのディレクトリを指定できるからです。  
`gh-pages`をいうブランチを作り、そのブランチに、buildしたファイルのブランチを作れば、outputDirを変えなくてもgithubPagesにデプロイできるみたいです。
Googleスライドでアプリアイコンなどの素材を作る

# はじめに
[Googleスライド](https://www.google.com/intl/ja_jp/slides/about/)でアプリアイコンなどの素材を制作する記事になります。
Googleスライドは本来プレゼン用ツールですが、図形描画系のツールも充実しており、簡単なアイコンなどであればサクッと作れちゃいます。

なお、以前に「[PowerPointでアプリアイコンを作る](https://qiita.com/technopocket/items/79feba65362b3f1ead8a)」という記事を書いたのですが、こちらと違いGoogleスライドは無料で使うことができ、基本的にはこちらを使うことをオススメします。

# 要件
- 512 x 512 サイズのアイコンをつくる
- png形式で保存
- 透過処理も可能

# 事前に必要なもの
- Google アカウント

# 手順 
1.[Googleスライド](https://docs.google.com/presentation/u/0/)を開き、**「新しいプレゼンテーションを作成＞空白」**を開く。
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68832/05a3d120-5b97-9785-3852-08a72c68ec59.png)


2.メニューの**「ファイル＞ページ設定」**から以下の設定をし、**「適用」**をクリック。 

- ページサイズ：カスタム
- 幅：512
- 高さ：512
- 単位：ピクセル

![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68832/cecd5f94-a683-4b9e-9264-5d3f20dbc0b4.png)


3.スライドが正方形のサイズになるので、それをベースに図形描画など使いアイコンを作成。
![006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68832/58b55422-4ae9-ad50-660d-83ef0e6ee2ca.png)


4.アイコンが完成したら、スライドを右クリック**「背景を変更」**から以下の設定をし、**「完了」**をクリック。

- 色：透明
 
![007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68832/62050a8a-5cf3-1920-d825-13c854a4d4f6.png)


5.メニューの**「ファイル＞形式を指定してダウンロード＞PNG　画像（.png、現在のスライド）」**をクリック。すると制作したアイコン画像をダウンロードします。


以上でアイコンの製作が完了です。
「Hexo 内部探訪」のご紹介

静的サイト・ジェネレータのひとつである、[Hexo](https://hexo.io/)。
最近、ブログを書くために使い始めました。

![screen-20190506-233803.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391342/4b5bc2ec-dd62-d3ae-affd-f68b70fe3c16.png)

使うというだけでなく、プラグイン機構を活かし、開発もはじめました。
[hexo-tag-google-photos-album 公開しました](https://pages.isnot.jp/2019-04/30-hexo-tag-google-photos-album-is-arrived/)
まだまだ荒削りな部分が残りますが、さしあたり使う分には困らない程度まではできました。

今後、プラグインの開発を進めるにあたり、方法や内部構造などを調べています。
それで、成果（？）をアウトプットしていこうと考え、まとめています。
また、それを知っていただいたり、フィードバックなどを得られたり、ということを期待して、Qiitaにも書いてみようかと思いました。

中身は私のブログに、少しずつ記事をあげてますので、ご興味あればご覧ください。（宣伝乙）

- [カテゴリー hexo](https://pages.isnot.jp/categories/hexo/)
- [Hexo 内部探訪 (1) はじめに](https://pages.isnot.jp/2019-05/05-study-about-hexos-internals-1/)
- [Hexo 内部探訪 (2) 準備 npm linkメモ](https://pages.isnot.jp/2019-05/06-study-about-hexos-internals-2/)
- [Hexo 内部探訪 (3) コンテキストとしての"hexo"変数](https://pages.isnot.jp/2019-05/06-study-about-hexos-internals-3/)
- [Hexo 内部探訪 (4) プラグインのロード](https://pages.isnot.jp/2019-05/06-study-about-hexos-internals-4/)
- [Hexo 内部探訪 (5) ライフサイクル](https://pages.isnot.jp/2019-05/06-study-about-hexos-internals-5/)
- [Hexo 内部探訪 (6) DevToolsを使ったデバッグ](https://pages.isnot.jp/2019-05/06-study-about-hexos-internals-6/)

今後も連載継続予定。
Rails6.0におけるbulk insert

Rails6.0では、bulk insert用に`insert_all` `insert_all!` `upsert_all`という3つのメソッドがActiveRecordに追加されました。

- 参照
 - [Add insert_many to ActiveRecord models](https://github.com/rails/rails/pull/35077)

Rails5.2までのbulk insertは[activerecord-import](https://github.com/zdennis/activerecord-import)というGemを使うのが主流でしたが、それに置き換わるものになりそうです。

# 1. `insert_all`メソッド
`insert_all`メソッドは、その名の通り複数件のレコードを一括でINSERTします。

```ruby:rails/activerecord/lib/active_record/persistence.rb
def insert_all(attributes, returning: nil, unique_by: nil)
  InsertAll.new(self, attributes, on_duplicate: :skip, returning: returning, unique_by: unique_by).execute
end
```
`on_duplicate: :skip`となっているため、`id`(主キー)が重複しているレコードはスキップされます。
例えば

```ruby
User.insert_all([
  { id: 1, name: 'Taro', age: 20 },
  { id: 1, name: 'Jiro', age: 21 }
])
```
とやると、2件目の`{ id: 1, name: 'Jiro', age: 21 }`は無視されて、INSERTされません。

## 1-1. `returning`オプション
`returning`は、PostgreSQLにのみ有効なオプションです。
返り値として得られる、INSERTに成功したレコードの属性を指定することができます。
デフォルトでは、`id`(主キー)が返って来ます。
例えば

```ruby:rails/activerecord/lib/active_record/persistence.rb
returning: %w[ id name ]
```
と指定すると、`id`と`name`が返ってきます。

## 1-2. `unique_by`オプション
`unique_by`は、PostgreSQLとSQLiteにのみ有効なオプションです。
デフォルトでは、`id`(主キー)のみが重複しているとスキップされます。`unique_by`オプションをつけると、重複でスキップするカラムを配列によって追加で指定できます。

```ruby:rails/activerecord/lib/active_record/persistence.rb
unique_by: { columns: %w[ isbn ] }
```
以下のように`columns:`と`where:`を組み合わせることで、部分インデックスを指定することもできます。

```ruby:rails/activerecord/lib/active_record/persistence.rb
unique_by: { columns: %w[ isbn ], where: "published_on IS NOT NULL" }
```

# 2. `insert_all!`メソッド
`insert_all!`メソッドは、`insert_all`メソッドと同様に複数件のレコードを一括でINSERTします。
`insert_all`メソッドとの違いは、id(主キー)が重複しているとスキップするのではなくエラーを返します。

```ruby:rails/activerecord/lib/active_record/persistence.rb
def insert_all!(attributes, returning: nil)
  InsertAll.new(self, attributes, on_duplicate: :raise, returning: returning).execute
end
```
`on_duplicate: :raise`となっているため、id(主キー)が重複していると`raise ActiveRecord::RecordNotUnique`のエラーを返します。
例えば

```ruby
User.insert_all!([
  { id: 1, name: 'Taro', age: 20 },
  { id: 1, name: 'Jiro', age: 21 }
])
```
とやると、2件目の`{ id: 1, name: 'Jiro', age: 21 }`で`raise ActiveRecord::RecordNotUnique`のエラーが発生します。

## 2-1. `returning`オプション
[1-1.`returning`オプション](#1-1-returningオプション)と同じです。

# 3. `upsert_all`メソッド
`upsert_all`メソッドは、まだ存在しないレコードならINSERT、既に存在するレコードならUPDATEします。

```ruby:rails/activerecord/lib/active_record/persistence.rb
def upsert_all(attributes, returning: nil, unique_by: nil)
  InsertAll.new(self, attributes, on_duplicate: :update, returning: returning, unique_by: unique_by).execute
end
```
`on_duplicate: :update`となっているため、id(主キー)が重複しているとupdateします。

## 3-1. `returning`オプション
[1-1. `returning`オプション](#1-1-returningオプション)と同じです。

## 3-2. `unique_by`オプション
[1-2. `unique_by`オプション](#1-2-unique_byオプション)と同じです。
phpの基本を学んでみよう4（オブジェクト指向の基本-クエリ情報とプロパティの紐付け）

#近況報告

エンジニア転職成功しました。YouTubeでエンジニア転職したい方向けに情報発信しています。

https://www.youtube.com/channel/UCcXQG8lu_EdyP2Cbhtz1bcA




phpの基本を学んでみようシリーズ4
今回はオブジェクト指向のクエリ情報とプロパティの紐付けまでです。

#著者略歴
名前：[YUUKI](https://twitter.com/bitcoinjpnnet)
ポートフォリオサイト：[Pooks](https://pooks.herokuapp.com)
現在：Webエンジニア見習い

##クエリ情報

- リンク先に情報を渡す
- URL末尾の「?」以降に「キー名=値」の形で情報を送る
- 「$_GET['キー名']」で値を受け取る

書き方

```php
// 値を送る
<a href="show.php?name=CURRY">
  CURRY
</a>

// 値を受け取る
$_GET['name'];
```


##findByName

- 配列の中から特定のインスタンスを取得するメソッド
- returnは、returnが呼ばれた部分で関数やメソッドの処理を終了させる性質がある
- findByNameメソッドを用いて、**第一引数で指定した配列の値と、第二引数の値が一致したら値を返して処理を終了させる**

書き方

```php
class Menu{
  public static function findByName($menus, $name){
    foreach($menus as $menu){
      // インスタンスのnameプロパティの値と$nameの値が一致したらそのインスタンスを返す
      if($menu->getName() == $name){
        return $menu;
      } 
    }
  }
}
```

##getReviews

- 関連するレビューを表示する
- 最初に空の配列を用意し、**foreachで\$reviewを繰り返し、nameプロパティと一致したら\$reviewの値を配列に代入し、returnで配列を返す**

書き方

```php
class Menu{
  public function setReviews($reviews){
    $reivewsForMenu = array();
      foreach($reviews as $review){
        if($review->getMenuName() == $this->name){
          $reviewsForMenu[] = $review;
        }
      }
    return $reviewsForView;
  }
}
```

##IDプロパティ値を用いてユーザー管理する

- クラスプロパティを用いて、インスタンス生成時に1を足して、プロパティに代入
- ユーザーにそれぞれID値を付与

使い方

```php

class User {
  private $id;
  // クラスプロパティの初期値を設定
  private static $count = 0;

  // インスタンス生成時に1を足して、それぞれのカウントをid値に付与
  public function __construct($name, $gender)
    self::$count++;
    $this->id = self::$count;
  }

  public function getId(){
    return $this->id;
  }
 }
 $user1 = new User('suzuki','male');
 echo $user1->getId();
 $user2 = new User('tanaka','female');
 echo $user1->getId();
}

```
Cに複素数型があるんですねー

```c
#include <stdio.h>
#include <complex.h>
#include <time.h>

typedef struct {
    double re, im;
} C;

#define N 100000000

int main()
{
    clock_t start;

    start = clock();
    for (int i = 0; i < N; i++) {
        double complex a = 1.0 + 3.0*I;
        double complex b = 1.0 - 4.0*I;
        double complex c = a*b;
    }
    printf("%f\n", 1.0*(clock() - start)/CLOCKS_PER_SEC);

    start = clock();
    for (int i = 0; i < N; i++) {
        C a = { 1.0, 3.0 };
        C b = { 1.0, -4.0 };
        C c = {
            .re = a.re*b.re - a.im*b.im,
            .im = a.re*b.im + a.im*b.re
        };
    }
    printf("%f\n", 1.0*(clock() - start)/CLOCKS_PER_SEC);

    return 0;
}
```
結果

```console
$ cc --version
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.5.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
$ cc a.c
$ ./a.out 
0.489901
0.298011
$ !!
./a.out 
0.513582
0.306521
$ !!
./a.out 
0.489888
0.296904
$ !!
./a.out 
0.521009
0.303007
yoshioka-no-MacBook-Pro:tmp ynaoto$ !!
./a.out 
0.486675
0.308325
```
でも遅いみたい。
Sentryを使ってエラー監視

新しい話題ではないですが、エラーログのトラッキングサービスに[Sentry](https://sentry.io/welcome/)というものがあるので使ってみました。導入手順をまとめておきます。

# 環境
Laravel5.5

# Sentryの仕組み
Sentryはアプリケーションサーバに出力されたログファイルを監視するのではなく、アプリケーション側にSentryにエラー情報を送信する仕組みを組み込む方式を取っています。
そのためエラーの情報だけがSentryに蓄積され、それらの傾向を見たり対策を立てることができます。
issueとしてSentry上でタスクとして管理することもできるため、エラー専用のタスク管理ツールとしても活用できます。

ただし、無料プランではプロジェクトの中にメンバーを追加できないため共有アカウントを使う等しないと複数人での利用は難しいです。本格的に使うなら有料プランが必須になりそうでした。

# 導入方法
sign up後、プロジェクトにLaravelを選んで作成します。
<img width="1202" alt="スクリーンショット 2019-05-06 19.42.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13766/e8583d6e-9438-88c3-3bd3-2206f376a595.png">

すると導入に必要なコードが出力されるのでそれに沿って作業を進めます。

```php
composer require sentry/sentry-laravel:1.0.2
```

次にエラー内容を送信する処理を書きます。

```php:App\Exceptions\Handler.php
public function report(Exception $exception)
{
    if (app()->bound('sentry') && $this->shouldReport($exception)){
        app('sentry')->captureException($exception);
    }

    parent::report($exception);
}    
```

次に、Sentryの設定ファイル下記コマンドで生成します。

```
php artisan vendor:publish --provider="Sentry\Laravel\ServiceProvider"
```

最後に、.envにURLを指定します。

```
SENTRY_LARAVEL_DSN=https://XXXXXXXXXXXXXX
```

これで設定は完了です。

# 動作
動作確認のため、エラーを起こして見るとイベントが登録されているはずです。

メソッド名をちょっと変更して存在しないメソッド呼び出しにしたときのエラーです。
<img width="982" alt="スクリーンショット 2019-05-06 22.56.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13766/b20fc8be-b085-2e0e-7eda-90c6a4042965.png">

エラーの箇所と内容をわかりやすく表示してくれています。

stacktraceもしっかり表示してくれます。
<img width="987" alt="スクリーンショット 2019-05-06 23.02.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13766/61173a83-6dec-df31-700e-480fb213f17a.png">


そのほかにもリクエスト送信元の情報もあり

- リクエスト元のipアドレス
- 閲覧に使われたブラウザ
- 稼働中のPHPのバージョン
- 動作環境(stgかproductionか)

などを一箇所で見ることができます。
テキストログを眺めるよりは圧倒的に見やすく、検証の効率は良さそうです。

# 通知
Slackとの連携機能も可能です。
自分が作ったグループの設定ページからIntegrationメニューを選んだ先で選択可能です。

<img width="1338" alt="スクリーンショット 2019-05-06 23.10.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13766/e11d5ef3-fb8e-97d6-70b1-ddf96a6a3a0b.png">

ここで設定したら次いはAlertの設定です。
Laravelのプロジェクトページに移動した後のメニュー画面からAlertの設定画面に行きます。

Alertは基準となるイベントと閾値を選択することで設定できます。

とにかく何かエラーが起きたら通知して見るためには

<img width="1117" alt="スクリーンショット 2019-05-06 23.14.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13766/a547163c-b763-f061-d5fe-1172a3fa72c5.png">

のように設定すれば良いです。これはerrorかfatalなログが送られてきたら発火する設定です。

また、この下にslackの通知設定も出てくるので、そこで通知したいグループを指定したらOKです。

通知内容はTagに含まれる内容であればカンマ区切りで指定可能です。
例えば、

```
environment,level,url,transaction
```
など。取得できる内容はエラー詳細ページにTagの一覧は載ってるのでそこから選べば良いです。

# 最後に
無料枠で試しましたが、Sentryはtextログと比べてエラーの調査をしやすくなるだろうなと思いました。有料版でしか使えない機能もたくさんあるので使える機会があったらいいなあと思った次第です。
capistrano3でデプロイ時にslack通知する

趣味でやってるアプリ開発でcapistrano3でデプロイ実行時にslack通知を導入した際の備忘録です。

# 実現したいこと
自分ひとりでやってたらコンソールのログを見ていたら良いのですが、チーム開発をしてるときにデプロイ状況を確実に共有するために通知を実装しました。
deployに時間がかからないので開始時の通知はしないようにします。

# 使ったgem
[capistrano-slackify](https://github.com/onthebeach/capistrano-slackify)

# 実装方法
Gemfileにslackifyを追加

```:Gemfile
gem "capistrano-slackify"
```

インストール

```bash
bundle install
```

Capfileに1行追加してrequrie

```ruby:Capfile
require "capistrano/slackify"
```

これで使う準備が整いました。

次に、通知の設定を行います。config/deploy.rbに記述するとすべてのdeployに適用されるので、そこに書きます。

```ruby:config/deploy.rb
# 通知
set :slack_url, "https://hooks.slack.com/services/XXXXXXXXXXX"
set :slack_channel, "#your_channel"

# 開始時の通知を除いたリスト
set :slack_notify_events, [:finished, :failed]

# 通知内容カスタム
set :slack_fields, ['status', 'stage', 'branch', 'hosts']

# デプロイ成功時
before 'slack:notify_finished', :deploy_success do
  set :slack_emoji,    ':dancers:'
  set :slack_username, "Deploy成功"
end

# デプロイ失敗時
before 'slack:notify_failed', :deploy_failure do
  set :slack_emoji,    ':imp:'
  set :slack_username, 'Deploy失敗'
end
```

<b>slack_notify_events</b>
通知を行うイベントのリストが入ってるので上書きします。
https://github.com/onthebeach/capistrano-slackify/blob/master/lib/capistrano/tasks/slackify.cap#L86
ここを見ると
開始、成功、失敗の3パターンにデフォルトで通知されます。
開始の通知が必要なかったため、`[:finished, :failed]`と指定しました。

<b>slack_fields</b>
通知に含めるfieldを指定します。
https://github.com/onthebeach/capistrano-slackify/blob/master/lib/capistrano/tasks/slackify.cap#L65
ここを見るとデフォルトで5つ指定されていますが、revisionは必要性を感じなかったので減らしました。
これで通知内容が1行減るので見た目的にはかなりスッキリします。

# 最後に
非常に簡単に通知の実装をすることができるので便利でした。
失敗した時のエラー内容まで反映できたらとても素敵だなとコメントをもらったりもしました。デフォルトのイベントにdeploy:log_revisionってのがあるので、そこで使ってる情報をあれこれしたらできるかもしれないですね。

# 参考
https://www.takedajs.com/entry/2017/11/15/201438
Lubuntu18.10 kimpanel削除後、LubuntuがGUIで起動しない問題

#はじめに
　これはLinux初心者の私がGUIで使っていたLinuxがあるタイミングでCUIしか動かなくなり、途方に暮れたという反省を生かすべく、記録に残すことにしたものです。

#問題
　fcitx-module-kimpanelのパッケージを削除後、LubuntuがGUIで起動しなくなってしまう。

#問題が起きた経緯
　Lubuntu18.10 x86 GUI版を入れた後、日本語入力のためにfcitx-mozcを入れたら、変換候補のボックスが「Ubuntu」とでかでかと書いていた。

　あまり好きではなかったため変えられないかとネットを探したところ、「Fcitx 設定（入力メソッドの設定？）」の「外観」タブからテーマを変えられるとのこと。
　自分の環境だと外観タブを押すと「kimpanelに設定オプションはありません」との一文が表示されるだけで何も変更できる箇所はなかった。

　再度kimpanelについて調べると、同じ症状にあっている方のブログを見るとfcitx-module-kimpanelのパッケージを削除すると外観タブに設定項目が表示されるよう。

　そこで、Lubuntuにプリインストールされていた「Muon Package Manager」を使って該当するパッケージを削除したところ、無事、外観タブにテーマの設定項目が現れた。変換候補のボックスも水色のテーマに変わったので安心していたが、今度は「sudo apt upgrade」をすると膨大の量のパッケージがもう必要とされていないといわれた。

　kimpanelのパッケージを削除した後とupgradeをした間に他に色々作業をしたため、upgradeで表示された不必要なパッケージ群に疑問を抱かなかった。そのまま「sudo apt autoremove」でその600MB近くのパッケージ群を削除してしまった。

　そのあと、またしばらく作業して再起動した際にGUIが動かなくなってCUIのみのログインとなってしまい、今回の問題にいたる。

#状況
・fcitx-module-kimpanelを削除したあと、upgradeをするとすごい量の必要のないパッケージが表示され、apt autoremoveで600MBくらい削除している
・CUIなら起動でき、ログインができる
・GUI以外は結構動く
・xinit、startxが起動しない（xinitのパッケージがないといわれる）
・xinitをインストールしてstartxすると起動したりしなかったり

#原因
　再インストールをし、ある程度同じように設定をしていったところ、kimpanelの削除の際にlubuntu-desktop等のパッケージが削除されるのを不審に思い、一度、lubuntu-desktopごと削除してからupgradeをしたところ、案の定ものすごい量のパッケージが不必要になってしまった。
　そこでそのパッケージ群をみたところ、「Xorg」や「xinit」などのパッケージ達が見えたため、これが原因だろうと確信した。
　手動でlubuntu-desktopのパッケージをインストールしたところ、またfcitx-module-kimpanelも入ってしまうが、一緒に消えたfcitx-ui-qimpanelなども再度インストールされ、
 upgradeをすると不必要なパッケージ群がなくなった。

　今回の問題の原因は、fcitx-module-kimpanelを削除する際に一緒にlubuntu-desktopとfcitx-ui-qimpanelあたりも削除されてしまったために、xinit達との依存関係がなくなったことが原因だと思われる。

#解決方法
　色々消えててほぼ無理じゃないでしょうか...
　次回気を付けるってことで、OS再インストールが早いかも
PDF.jsでネット上のpdfファイルを一瞬にして開くツール

# はじめに
[Mouse Dictionary](https://qiita.com/wtetsu/items/c43232c6c44918e977c9)をpdfで使うために、PDF.jsを用いるという方法がある。[(@kroton様の参考記事)](https://qiita.com/kroton/items/cc38dbcfc4a6fefcd2c0)

しかし、私のようなめんどくさがりは、これすらも面倒くさいので以下のようなツールを作った。

- ワンラインでネット上のpdfをPDF.jsで開く
- ローカルに落としたpdfをわざわざ削除しなくてもよい

# 完成物
https://github.com/monado3/pdfjs-broker

# 開発環境
- Manjaro linux
- Python 3.7.3
- Docker 18.09.5-ce

# 実現方法

1. Dockerコンテナ内にpdfを落とす。
2. そのままDockerコンテナ内でPDF.jsが機能するPHPビルトインサーバを立てる。
3. ローカルのブラウザからDockerコンテナ内のpdfを閲覧する。
4. ダウンロードしたpdfはDockerコンテナが終了すれば(再起動時や明示的にコンテナを停止させた際)自動的に消える。

また、複数のpdfを同時閲覧することを前提とし、自動で動的にDockerコンテナとローカルのポートフォワーディングをするために、Pythonプログラムにコンテナ立ち上げを仲介させることにした。

# 課題点
DockerイメージのEntrypointとなっているシェルスクリプトが終了すると、例え`-d`オプションをつけてrunしてもコンテナはなぜか終了してしまう。
それにより、コンテナ内でPDFのサービングが開始したことをPython側にシンプルに伝える方法がなく、コンテナ内の必要処理が終了する前に、Pythonがブラウザを開いてしまう。

# 最後に
実装があまりスマートではないので、どしどしアドバイスやPR待ってます。
tailwindcssを使ってみた　#GWアドベントカレンダー


 #GWアドベントカレンダー[「使いたかったもの使ってみたカレンダー（1人アドベントカレンダー）」](https://gw-advent.9wick.com/calendars/1)の9日目、5/5記事です。


# tailwindcss使ってみた

[tailwindcss](https://tailwindcss.com/docs/what-is-tailwind/)とは、bootstrapみたいなcssフレームワークの１つです。
bootstrapとの違いは、あくまでcssのみの話にとどまっていて、UI(HTML)には触れてないというところのようです。

style="xxx" と直接書く代わりに class="xxx"とかく、程度のものです。

## 良さそうなところ/面白かったところ


- UIに絡まないので、CSSの知識がそのまま使えてわかりやすい
- 複数のcss属性を組み合わせたコンポーネントを定義できて、それが使いやすい
- コンポーネントをみんなでシェアするエコシステムがある
- レスポンシブが簡単にできる


## あんまりイケてないところ

- css知識が無いと厳しい

## 総合評価

cssがわかっている人が、cssファイル作るのめんどくさいときに使うと良いなというものでした。
css初心者にはbootstrapをオススメしますが、bootstrapっぽさを出したくないサイトの場合は良いかなと思います。
Codesandbox Darksky API CORS

https://darksky.net/dev/docs/faq

Why do I get the error No 'Access-Control-Allow-Origin' header is present on the requested resource when I try to call the API?
We take security very seriously at Dark Sky. As a security precaution we have disabled cross-origin resource sharing (CORS) on our servers.

Your API call includes your secret API key as part of the request. If you were to make API calls from client-facing code, anyone could extract and use your API key, which would result in a bill that you'd have to pay. We disable CORS to help keep your API secret key a secret.

To prevent API key abuse, you should set up a proxy server to make calls to our API behind the scenes. Then you can provide forecasts to your clients without exposing your API key.

Codesandbox上では、使えない。
macOSで隠しファイルを編集する！--Python3をデフォルトで使えるようにする。


[mac:pythonコマンドでpython3を利用する](https://qiita.com/amuyikam/items/721af77cf569df719f65)

ホームディレクトリの中ある".bash_profil"にコードを書いて使えるようにします。このファイルは普段表示されていません。そこで表示させましょう！

"⌘(コマンド)"と"シフト"と　".(ドット)"を表示したいフォルダを開いて、有効になっている時に同時に押してみましょう。

".(ドット)"から始まるファイルが表示されるはずです。こうなれば普通にファイル編集が可能になるので、".bash_profil"などもCotEditerなど通常使っているものを使えます。

今回はmacにデフォルトで入っているPythonは2.7ですがエイリアスを指定してPython 3.7を"python"のコマンドで起動するようにします。

.bash_profilに**alias python=python3** を記述します。これだけです。

ターミナルで"python"と打つと、python3.7が起動しました！
ラベルの一部分の色を変える(Swift)

ラベルの色を部分的に変えたい場合、少し調査が必要だったのでまとめます。
主に2パターンの方法があります。

####その１　StroryBoardを使う

この方法だと、コードを書かなくていいので、設定が簡単にできます

<img width="260" alt="スクリーンショット 2019-05-06 2.17.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239560/257faf43-f16f-a082-5265-47e2ada08d64.png">

対象のラベルを選択した状態にします。

①TextをAttributedにします
②ラベルに表示する文言の色を変えたい部分だけ選択した状態で色を変える(赤枠の部分です)

これだけで部分的に色を変えれます。

####その2　ソースコードで定義する

この方法だとStoryboardの設定は不要ですが、実装が必要です。

まずは、ラベルとソースコードでの定義を紐付けます

<img width="346" alt="スクリーンショット 2019-05-06 2.27.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239560/4d23c53d-44ca-ac3e-fd3b-08d49c2cd67b.png">

上記のように黒い丸が付いていれば紐付けされているはずです。

次に、ラベルの設定をします。

```controller.swift
let attrText1 = NSMutableAttributedString(string: taskLimitLabel.text!)
        
        attrText1.addAttributes([
            .foregroundColor: UIColor.red,
            ], range: NSMakeRange(6, 9))

taskLimitLabel.attributedText = attrText1
```

上の処理では属性を加える文字列を定義して、addAttributesで属性を加えています。
今回はrangeで色を変える文字が何番目かを設定し、foregroundColorで色を設定します。
最後に、属性を追加した文字をラベルに置き換えます。
これで一部分の色が変わります。

今回は2パターン記載しました。
実装でカスタマイズする方法は他にもあると思います。
個人的にはStoryboardを使ったほうが視覚的に見やすいと思いますが、複数人で開発など、ソースで書いた方がいいパターンもあると思うので、場合によって使い分けたいと思います。

#### 参照

[Apple Developer (NSAttributedString)](https://developer.apple.com/documentation/foundation/nsattributedstring)

[Apple Developer (NSMutableAttributedString)](https://developer.apple.com/documentation/foundation/nsmutableattributedstring)
テンプレート作成

# 初めに
前回は生httpでサーバサイドを作成しましたが、今回はテンプレートを使いたいので
express.jsを使用します

# 事前準備
以下のコマンドを実行してexpress.jsをインストールする

npm install express --save

#写真サイトの作成
　ゴールは写真共有サイトの作成になります
　今回は写真を表示する仕組みを作ります

##サーバーサイド作成
やっている事としては、imgディレクトリ配下のjpgファイルを全て取得してテンプレートに渡す

<pre>
// ①HTTPサーバを作成するための必要
const express = require("express");
let app = express();
// ディレクトリ読み込み用
let fs = require('fs');

const IMG_PATH = 'img/img/';

// テンプレートエンジンの指定
app.set("view engine", "ejs");
// 静的ファイルを読み込めるようにする
app.use(express.static('css'));
app.use(express.static('img'));


app.get("/", function(req, res) {

  let fileList = [];
  try {
    // img配下のファイルをすべて読み込む
    let files = fs.readdirSync(IMG_PATH);
    // jpgの画像を絞り込む
    files.filter(function(file) {
      return fs.statSync(IMG_PATH + file).isFile() && /.*\.jpg$/.test(file); //絞り込み
    }).forEach(function(file) {
      fileList.push(file);
    });
    let data = {
      items : fileList
    }
    console.log(data);
    // レンダリングを行う
    res.render("./index.ejs", data);
  } catch (err) {
    // 読み込めない場合エラー画面に繊維
    console.error(err);
    res.render("./error.ejs");
  }
});

// サーバ実行
app.listen(8081);

</pre>

#　テンプレートの作成

・index.ejs

<pre>
&lt;!DOCTYPE html>
&lt;html>

&lt;head>
  &lt;meta charset="UTF-8">
  &lt;title>&lt;/title>
  &lt;header class="header">
    &lt;!-- タイトルとヘッダ画像の挿入 -->
    &lt;h1>写真投稿サイト&lt;/h1>
    &lt;div class="header-img">&lt;img class="img-header" src="header/header.jpg" alt="" /></div>

  &lt;/header>
  &lt;!-- UIkit CSS -->

  &lt;link rel="stylesheet" href="style.css" />
&lt;/head>

&lt;body>
  &lt;!-- 共有する写真のパスを渡して全部表示する -->
  &lt;%- include("./item.ejs", items) %>
&lt;/body>
&lt;/html>
</pre>

・item.ejs

<pre>
&lt;div>
&lt;p>写真一覧&lt;/p>

&lt;!-- 横スライドショーで表示 -->
&lt;ul class="horizontal-list">
  &lt;% for (let item of items) { %>
    &lt;li class="item">
      &lt;!-- クリック時は正規のファイルをダウンロードさせる -->
      &lt;a href="img/<%- item %>" download="img/<%- item %>">
        &lt;!-- 画面に表示するのは小さくした画像（容量削減のため） -->
        &lt;img src="img_mini/s<%- item %>" alt="s<%- item %>">
      &lt;/a>
    &lt;/li>
    &lt;% } %>
&lt;/ul>

※写真全部で２G超えています。取得時はwifi環境で実施してください。<br>
　また、zipファイルのためダウンロード前に解凍環境を確認してください<br>
&lt;a href="136-231570-335954_photo_l_part1_of_2.zip" download>一括ダウンロードその１&lt;/a>&lt;br>
&lt;a href="136-231570-335954_photo_l_part2_of_2.zip" download>一括ダウンロードその２&lt;/a>&lt;br>

</div>
</pre>

・style.css

<pre>

## スタイル
/** ヘッダのスタイル*/
header h1 {
  font-size: 2.0rem;
  line-height: 1.5rem;
  background-color: #7CB342;
  padding: 0px 5%;
  color: #fff;
}


.horizontal-list {
  overflow-x: auto;
  white-space: nowrap;
  -webkit-overflow-scrolling: touch;
}

.item {
  /* 横スクロール用 */
  display: inline-block;
  margin: 16px;
  background: rgba(255, 0, 0, 0.4);
}

/** ヘッダの画像だけは横いっぱいに表示 */
.img-header {
  width: 100%;
  max-width: 100%;
  height: auto;
}

</pre>

# 完成図
 完成図です。顔はマスキングしてますのであしからず


![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402093/4fadd980-8eb8-2b67-b8df-dc160c140ea6.png)


# 総括
って感じで一応見せる用のサイトは作成できました。
シンプルすぎますがw
一応次はドメイン取得して外部公開方法予定です。
AngularDartでwebdevを使おう

 今回はAngularDartで開発する上で必要なツールであるwebdevに関する使い方を紹介したいと思います（ぶっちゃけhelpコマンドで出る情報そのまんまなので内容は薄いです）

# webdevとは
　webdevはDartのWebアプリケーション開発者のためのCLIツールです。なのでAngularDartのためだけに存在するわけではありません。webdevの現時点（2018/05/06）での最新バージョンは`2.0.4`で、webdevを使うことで下記のような事が可能になります。

- ソースコード修正時の自動リロード
- Dart Dev Toolsの使用
- release用のビルド

インストール方法は[前回の記事](https://qiita.com/hayassh/items/f288e29af88e174dd677#webdev)を参照して頂ければと。

## 2つのモード
　webdevには主に2つのビルドモードが存在します。1つ目は`serve`で主に開発時に使用するモードです。

```
webdev serve
```

2つ目は`build`で主にリリース用の成果物を生成するためのモードです。

```
webdev build
```

以下はそれぞれの詳細を見ていこうと思います。


## webdev serveの詳細

#### --auto オプション
　他の言語やツールだとHot DeployとかLive Reloadとか言われるやつですね。webdevでは2つのモードが用意されています。
1つ目は`restart`で、修正したソースコードの差分をreloadし、エントリーポイントであるmain関数を再実行します。この時動作中に変更された状態は破棄されます。

```
webdev serve --auto=restart
```

2つ目は`refresh`で、ソースコードが修正されるとページ全体をrefresh（再リロード）します（F5を押した時と同じ動きになります）

```
webdev serve --auto=refresh
```

---

#### --launch-in-chrome オプション
　chromeのデバッグポートを開いてchromeを新規に起動してアプリケーションを実行します。

```
webdev serve --launch-in-chrome
```

---

#### --debug オプション
　Dart Dev Toolsを有効にします。上記`--launch-in-chrome`オプションと同時に指定する必要があります。
このオプションを指定して実行した状態で`Alt + D`を押すとDart Dev Toolsが立ち上がります。現時点ではFlutterで使用する時に比べて情報が少ない（というかconsole logくらいしか表示されない）ですが、今後はここで様々な情報が得られるようになるはずです。期待したいですね。また、今後はchrome以外でも実行できるようになるみたいです。

```
webdev serve --launch-in-chrome --debug
```

---

#### -r オプション（--release）
　リリースモードでビルドします。AngularDartは開発時は`Dart Dev Compiler`（通称`DDC`）にてコンパイルが行われ、リリースモードでは`dart2js`にてコンパイルが行われます。このオプションを指定する場合は`dart2js`にてコンパイルされ実行されます。自分はこれで実行する事は全然無いですが、使用するケースとしてはリリースモードで実行した場合にだけバグってしまうような時にデバッグ用に実行するとかでしょうか。

```
webdev serve -r
```

---

#### ポートを指定するには
　`webdev serve`で起動する場合はデフォルトで8080のポートでlistenします。このポートを変えたい場合は下記ようにエントリーポイントが存在するディレクトリをポートを指定して起動すればOKです。

```
webdev serve web:8081
```

---

#### -o オプション（--output）
　ビルド後の出力先を指定します。開発時に使う必要性はほぼ無いんじゃないかなぁと。
下記の場合はプロジェクトディレクトリ直下の`out`というディレクトリに成果物を出力して起動します。

```
webdev serve -o out
```

---

#### -v オプション（--verbose）
　指定した場合、ビルド時などのログの詳細を出力するようになります。

```
webdev serve -v
```

---

#### --log-requests　オプション
　サーバーへのリクエストのログをコンソールに出力します。自分はあまり使ってないですねぇ。

```
webdev serve --log-requests
```

---

#### --hostname オプション
　ホスト名を指定して起動します。これも通常の開発ではほとんど使わないのではないでしょうか。他の人のPCから自分のアプリケーションを見たい時とかはこれでIPを指定して起動する必要があります。デフォルトは`localhost`です。

```
webdev serve --hostname=192.168.XX.XX
```

---

### 実際に使っているオプション
　自分は下記コマンドで常に起動しています。

```
webdev serve --auto=restart --launch-in-chrome --debug
```

## webdev buildの詳細
　指定可能なオプションは`-o`、`-r`、`-v`で内容は`webdev serve`と同じですが、`-r`はデフォルトで有効になっていて、`-o`のデフォルト出力先も`build`というディレクトリになっています。なので実際に実行する時は何も考えずに`webdev build`で基本OKのはずです。
　上にも書いているのですがこのモードは`dart2js`にてコンパイルされます。余談ですが、この進化も素晴らしく、以前であれば最終的なjsファイルは余裕で1Mを超えてたりしたんですが最近は200K以下のサイズになっています（どうやってここまで小さく出来たのか、その実現方法とか興味が湧きますね）

## 最後に
　いかがでしょうか。個人的にはDart Dev Toolsの進化に期待しています。DDCやdart2jsの違いだったり今回はあえて触れていない`build_web_compilers`などに関しては次回以降に記事にしたいと思います。