OmniAICreator/Qiita-1.07M huggingface dataset:
CORS: OPTIONSリクエスト（preflight request）を避ける

![image.png](https://qiita-image-store.s3.amazonaws.com/0/77729/e64c6a61-36e0-32b7-2795-12c537b03a89.png)


`ajax`など、ブラウザ経由で`GET`, `POST`, `DELETE`リクエストを投げると、実際のリクエストが走る前に`OPTIONS`リクエストが送信されることがあります。
一度しかリクエストを送信していなくても、実際は`OPTIONS`と`GET`など、２回リクエストが走っています。

APIによっては、`OPTIONS`リクエストを受け付けないため、`Response to preflight request doesn't pass access control check`のようなエラーが返ってくる場合があります。この`OPTIONS`リクエストは`CORSプリフライト（preflight requests）`と呼ばれていて、これが通らないと、実際の`GET`, `POST`, `DELETE`などのリクエストは送信されません。

このプリフライト・リクエストとは何なのか、`OPTIONS`リクエストを回避する方法はあるのか調べてみました。

## プリフライト・リクエストとは
![image.png](https://qiita-image-store.s3.amazonaws.com/0/77729/13965bd5-05d2-aeb2-54ee-cd33d46bc556.png)
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Preflighted_requests

実際のリクエストを送信する前に、そのリクエストが安全かどうか、前もって`OPTIONS`リクエストを送信して確かめる仕様です。
これはプリフライト・リクエスト（`preflight request`）と呼ばれていて、ブラウザのCORS仕様の一部です。
ブラウザ経由でリクエストを送信するときにしか起こりません。
preflightという言葉からもわかるように、本番前のテスト飛行のようなイメージです。

ブラウザ上のリクエストは「単純リクエスト(`simple request`)」とその他のリクエストに分けられていて、単純リクエストの場合はアクセストークンなどのセンシティブな情報が含まれている可能性が低いと判断されるため、`OPTIONS`は送信されません。

## 単純リクエストとは
単純リクエストの定義、つまり、**`OPTIONS`リクエストが飛ばない条件**は以下の通りです。

1. `GET`, `HEAD`, `POST`のうちいずれか
2. ヘッダーに含まれるのが以下のうちいずれか
  - ユーザーエージェントによって自動的に設定されたヘッダー
  - Accept
  - Accept-Language
  - Content-Language
  - Content-Type
3. Content-Typeのヘッダーが以下のうちいずれか
  - application/x-www-form-urlencoded
  - multipart/form-data
  - text/plain
4. リクエストに使用されるどの XMLHttpRequestUpload にもイベントリスナーが登録されていないこと。
5. リクエストに ReadableStream オブジェクトが使用されていないこと。

ほとんどのリクエストは1 ~ 10の条件に当てはまるため、`OPTIONS`は飛びませんが、
REST APIのために`Content-Type: application/json`ヘッダーをつけたり、ユーザー情報の取得のために`Authorization`ヘッダーをつけたりすると、「非・単純」なリクエストと見なされて、`OPTIONS`リクエストが飛びます。

## OPTIONSリクエストを避ける方法
リクエストが上の条件に当てはまるようにして、**単純リクエストになるように**します。

`GET`、`POST`などでニュースのエントリを取得するなど、センシティブな情報のリクエストを含まない場合は、単純リクエストにするのはさほど問題ないかと思います。

ただし、ユーザー情報の取得のために`Authorization`ヘッダーを使っている場合など、どうしても単純リクエストにできないこともあるかと思います。
プリフライト・リクエスト（OPTIONS）はブラウザだけの仕様なので、その場合はサーバーサイドからリクエストを投げるのが吉です。

## まとめ
- `OPTIONS`は、実際のリクエストを投げる前のテスト飛行
- `OPTIONS`が飛ばないようにするには、「単純リクエスト」の条件にあてはまるようにする
- どうしても「単純リクエスト」にできない、かつAPIが`OPTIONS`に対応していない場合は、サーバーサイドからリクエストする

## 公式ドキュメント
https://developer.mozilla.org/ja/docs/Web/HTTP/CORS
Ubuntu 16.04 LTS でSambaサーバーを立てるときのメモ事項

# 自宅でギャルゲ用に使用していたPCが低スペックすぎたのでサーバー化することにしました...
自宅にあるCeleron N3040のPCをギャルゲ用に使用していましたが...重いゲームだと少しカクついていたり、無駄にWindows 10 proをなぜか使っているという状態であったので、サーバー用に変更することにしました。
今回、ファイルサーバーとしてSambaサーバーを立てる際の手順についてまとめようと思います。

## HDD/SSDをフォーマットする
### パーティションの作成
```
sudo parted /dev/sdc

GNU Parted 3.2
Using /dev/sdc
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) mklabel
New disk label type? gpt
Warning: The existing disk label on /dev/sdc will be destroyed and all data on
this disk will be lost. Do you want to continue?
Yes/No? y
(parted) mkpart
Partition name?  []? KURUMI_NAS
File system type?  [ext2]? xfs
Start?
Start? 0
End? 3001GB
Warning: The resulting partition is not properly aligned for best performance.
Ignore/Cancel? I
(parted) quit
Information: You may need to update /etc/fstab.
```

### フォーマット
```
sudo mkfs.xfs /dev/sdc1
```

## ファイルサーバーに使用するHDD/SSDを自動マウントするように設定
### HDD/SSDの情報確認
```
sudo blkid
```

### 自動マウントしたいパーティションの設定を追記する
```
sudo vi /etc/fstab
```

## Sambaサーバーの構築
### インストール
```
sudo apt update
sudo apt dist-upgrade
sudo apt -y install samba
```

### 共有するディレクトリの作成
```
sudo mkdir /media/share
sudo chmod 777 /media/share 
```

### ファイルサーバーの設定
```
sudo vi /etc/samba/smb.conf
```

```
smb.comf

# 25行目：以下2行追記
unix charset = UTF-8
dos charset = CP932

# 30行目：必要があれば変更 (Windows側に合わせる)
workgroup = WORKGROUP

# 51行目：コメント解除しアクセス許可IP追記
interfaces = 127.0.0.0/8 192.168.0.0/24

# 58行目：コメント解除 & 追記
bind interfaces only = yes

# 最終行に追記
[Share]# 任意の共有名称を指定
   path = /home/share# 共有フォルダ指定
   writable = yes# 書き込みOK
   guest ok = yes# ゲストユーザーOK
   guest only = yes# 全てゲストとして扱う
   create mode = 0777# フルアクセスでファイル作成
   directory mode = 0777# フルアクセスでフォルダ作成
```

### ファイルサーバーを起動
```
sudo systemctl restart smbd
sudo systemctl enable smbd  #自動起動設定
```

以上、自分用のメモになります(*‘ω‘ *)
Kotlin 文法メモ　－変数関連ー

#はじめに
Udemyで勉強したKotlinの文法のメモです。
コースはhussein Al Rubayeさんの[The Complete Android Kotlin Developer Course](https://www.udemy.com/the-complete-kotlin-developer-course/)をお手本にしています。

#変数の定義
変数の定義は`var`または`val`でします。Kotlinは型推論をしてくれるので変数の型は指定しなくても大丈夫です。
ですが、変数の定義の際には型を指定することも可能です。

`var`は変数への再代入が可能ですが`val`は再代入ができません。

```
var number1 = 5   //整数型
var number2:Int = 10 //型指定での定義
val Message:String = "Hello World" //再代入不可での定義
number1 = 15    //OK
Message = "Hello Kotlin" //エラー(valが再代入不可のため）
```



#NULLの扱い
KotlinでNULLを扱うときには少し注意が必要です。
例えば、以下のコードで変数にnullを入れようとするとエラーが起きます。

```
var number1:Int = null    //エラー
```

なのでnullを代入するときには変数の後に`?`を入れます。

```
var number1:Int? = null    //OK
```

変数の値を出力するときにnullかそうではないかを確かめるには出力したい変数の後に`!!`を入力する必要があります。
`!!`を追加することでnullの可能性がある値をnullの可能性がない値に変更してくれます。

```
var name:String? = null
print(name!!)    //エラー（nameがnullなので）
```
Ubuntu16.04 LTS をCUIで起動するときのメモ書き

# デスクトップをインストールしなかった場合、画面が真っ黒になるときの対処について
Ubuntuを起動するたびに画面が真っ黒の状態から始まってしまう状態になりました。毎回Ctrl + Alt + F1を押せば操作できるのでいいのですが...起動できているかどうか判別がしにくいということもあり、自動でCUIになるように設定する方法についてメモしておきます。

### grubの設定変更  
#### まず設定ファイルを開く
```
sudo vi /etc/default/grub
```

次に、設定ファイルに以下の記述を追記、または変更する      

```
GRUB_CMDLINE_LINUX_DEFAULT="systemd.unit=multi-user.target quiet nosplash"
```

編集が終了したら設定内容を反映させる    

```
sudo update-grub
```

上記の作業が終了したら再起動して設定どおりにCUIで起動するかを確認する    

```
sudo reboot
```

以上となります
header Locationで「Warning: Cannot modify header information」がでた

# php.iniを設定して解決
## 何が起きたか？
どこのページを見ても
「Warning: Cannot modify header information」

。。。

グーグル先生に聞いたら一発で解決策を教えてくれた！

参考：http://kotori-blog.com/php/cmhi_error/
この方のページを見ながら、php.iniで設定を変更すれば細かいことは気にしないで
正常に動くとのことで、いざ実践。



## 設定ファイルが見つからない！

grep でどこに設定が置いてあるのか確認

```
$ php -i | grep php.ini
$ onfiguration File (php.ini) Path => /etc

```
。。。あれ？ etcに「php.ini」がない・・・
ということで、作成します。

現状とりあえず動作を確認できれば良いので、


```php.ini
; php.ini
default_charset = UTF-8
mbstring.internal_encoding = UTF-8
output_buffering = On  
```
上記で新しく「php.ini」を作成して、ビルドインサーバーを動かす際に、
読み込み先を指定しました。

```
php -S localhost:8000 -c php.ini
```


無事、「Warning: Cannot modify header information」が表示されなくなりました。

これから php の開発をメインに行っていくと思うので、
php についてもっと理解を深めていこうと思います。
AtlasでSparkのLineageを表示

```scala
    val path = paths.map(_.path) mkString ", "
    val clustername = System.getProperty("cluster.name")
    val absolutebasepath = System.getProperty("absolute.base.path")
    val upath = path.replace(absolutebasepath,"")
    new EndpointDataset(name, qualifiedName, attributes, new FileEndpoint(upath, upath+"@"+ clustername), EndpointType.file, EndpointDirection.input, st)
```


```scala
    spark-shell  --master yarn  --driver-java-options='-Dspline.persistence.factory=za.co.absa.spline.persistence.atlas.AtlasPersistenceFactory' --files /usr/hdp/2.6.4.0-91/kafka/conf/producer.properties --conf 'spark.driver.extraJavaOptions=-Datlas.kafka.bootstrap.servers=hdp264-0.field.hortonworks.com:6667 -Dbootstrap.servers=hdp264-0.field.hortonworks.com:6667 -Dspline.persistence.factory=za.co.absa.spline.persistence.atlas.AtlasPersistenceFactory -Datlas.kafka.auto.commit.enable=false -Datlas.kafka.hook.group.id=atlas -Datlas.kafka.zookeeper.connect=hdp264-0.field.hortonworks.com:2181 -Datlas.kafka.zookeeper.connection.timeout.ms=30000 -Datlas.kafka.zookeeper.session.timeout.ms=60000 -Datlas.kafka.zookeeper.sync.time.ms=20 -Dcluster.name=hdp264 -Dabsolute.base.path=hdfs://hdp264-0.field.hortonworks.com:8020'
    import za.co.absa.spline.core.SparkLineageInitializer._
    spark.enableLineageTracking()
    import org.apache.spark.sql.SaveMode
    val sourceDS = spark.read.option("header","true").option("inferSchema","true").csv("/user/nifi/data/wikidata.csv").as("source").filter($"total_response_size" > 1000).filter($"count_views" > 10)
    val domainMappingDS =spark.read.option("header","true").option("inferSchema","true").csv("/user/nifi/data/domain.csv").as("mapping")
    val joinedDS = sourceDS.join(domainMappingDS, $"domain_code" ===$"d_code","left_outer").select($"page_title".as("page"),$"d_name".as("domain"), $"count_views")
    joinedDS.write.mode(SaveMode.Overwrite).format("orc").save("/user/nifi/sparkoutput")
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/133516/af76d37f-aacd-58ba-dac4-06dd9d16df88.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/133516/73ac3b01-b9ba-ae17-605f-9f7b2aa897f9.png)
macOS の terminal の tab キー補完の不具合発生について（調査中）

こんにちは。
macOS の terminal.app を使っており、新規タブを開き、tab キー補完（key completion）が動いています。

しかし多くのコマンドを発行して作業しているうち、tab キー補完機能が停止してしまう現象に気がつきました。何が原因・きっかけ(?)なのか調査しようと思います。また、そのタブ内で tab キー補完機能を復活させる方法も見つかっていません。

```console
$ echo $SHELL
/bin/bash
```
spring-bootでxmlを返す際にXML declarationを追加

spring-bootでxmlをHTTPレスポンスとして返す際に下みたいなXML宣言を追加する。

```xml
<?xml version='1.0' encoding='UTF-8'?>
```

# ソースコード
```xml:pom.xml
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.3.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
		</dependency>

		<dependency>
			<groupId>com.fasterxml.jackson.dataformat</groupId>
			<artifactId>jackson-dataformat-xml</artifactId>
		</dependency>
```

```java:Application.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;

@SpringBootApplication
@RestController
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @GetMapping(value = "/xml", produces = { MediaType.TEXT_XML_VALUE })
    public XmlResponse xml() {
        return new XmlResponse();
    }

    @Bean
    public MappingJackson2XmlHttpMessageConverter mappingJackson2XmlHttpMessageConverter(Jackson2ObjectMapperBuilder builder) {
        XmlMapper xmlMapper = builder.createXmlMapper(true).build();
        xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true);
        return new MappingJackson2XmlHttpMessageConverter(xmlMapper);
    }
}

```

```xml
<?xml version='1.0' encoding='UTF-8'?>
<XmlResponse>
    <id>aa</id>
</XmlResponse>
```

[How to add XML declaration in the xml returning from the end-point
](https://stackoverflow.com/questions/39069772/how-to-add-xml-declaration-in-the-xml-returning-from-the-end-point) のほぼコピペ。
PowerBIで，UTC時刻のカラムをJSTにする

## TL;DR
```
[列名] + #duration(0,9,0,0)
```

## やりたいこと
- タイトルの通り．

## 背景
- 業務でPowerBI触り始めたのだが，数時間触ればもう完璧だろとイキってたら，意外と癖が強くてこんな**UTCをJSTに直すなんてググれば3秒でわかりそうな本件**だけで1時間溶かしてしまったので戒めのための執筆．<b>ムカっ腹立つぜちくしょ～</b>
- azure blob storageのtimestampとか，大体のストレージやDBってデフォUTCなので誰かの参考になれば．

## 手順
- 新規にデータを追加する．
- データを編集する．
- 列の追加 -> カスタム列
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/132469dc-3188-8422-e7a5-3a1ab1b976b6.png)
- 新規列名を入力し，数式を入力 -> OK  

```
[列名] + #duration(0,9,0,0)
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/a2ae9279-e06d-cfc2-19f5-f0ba0ea46717.png)

- きちんと9時間足されている．
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195903/0c0f1906-c968-1385-73a1-a404285bd9f6.png)

## 解説
- [ここに全てのってます．](https://docs.microsoft.com/en-us/powerquery-m/sharpduration)

以上．
VirtualBox上のminikubeにhttp://localhost:xxxxでアクセスする

Minikube in VirtualBox on Windows10 な環境で、Minikubeに`http://localhost:xxxx`でアクセスできるようにしたメモ

# 長いよ！
* `minikube addons enable ingress`
* `nginx.ingress.kubernetes.io/ssl-redirect: "false"`
* VMの80にポートフォワード

# 環境
* Windows 10 Home 1809
* virtualBox v5.2.22
* minikube v0.30.0

アプデさぼってるな...

# 発端
普通にMinikubeのGetting Startをやっていると、`type: NodePort`なServiceにアクセスするために`minikube service <service-name> --url`でURLを払い出す記述がどこかで見つかると思う。
ここで吐き出されるIPアドレスはたぶん`192.168.99.100`で、後ろに適当な30000番台のポート番号がくっついていることだろう。
このURLを叩けばアクセスできることにはできるのだけれど、困る。

というのも、どこの馬の骨とも知れぬプライベートIPアドレスとlocalhostとではブラウザ様の挙動に雲泥の差があるからだ。
具体的には、HTTPであってもlocalhostはセキュアなものとして扱ってくれる。今日のWebはHTTPSが基本。各種Web APIもセキュアな環境でないと動いてくれないとかよくあるのでマジ重要なのだ。

なのでlocalhostでアクセスしたい。こういうときはVirtualBoxのVMの設定でポートフォワードすればいいというのはふんわりと知っていたのだけれど、いかんせん適当に吐き出されるポート番号相手にどうしたものか分からず苦戦した。
"Minikube windows virtualbox localhost"といった検索ワードでggり倒したけれどそれらしい情報が全然見つからず辛い思いをした。

ふと`type: LoadBalancer`なる記述に踊らされ、関連してIngressという単語を拾い検索ワードを弄っていると、[Minikube で快適に Ingress を利用する][qiita-minikube-ingress]という記事を見つけ、参考になった。

# Ingress
Ingressが何か全くわからなかったためちょっと調べた。

[K8s on Vagrant, NGINX Ingress Controller の利用][qiita-nginx-ingress]を参考にすると、クラスタ外部からクラスタ内のサービスにアクセスを橋渡しして、ロードバランシングやSSLの終端を担う存在らしい。k8sでのリバースプロキシみたいな存在なのかな。

# MinikubeのIngressアドオン
[Minikube で快適に Ingress を利用する][qiita-minikube-ingress]に立ち返り、書かれている手順に倣ってIngressを導入する。

まずはMinikubeにIngressアドオンを入れる。`minikube addons enable ingress`を打ってお茶を淹れてくるだけ。

まったりしている間にnginx-ingress-controllerやらの展開が終わったのを確認して、Ingressの設定を投げる。

ほぼコピペだったけれど、ちょこちょこ弄っている。

```yml:k8s-nginx-ingress.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
  rules:
  - host: localhost
    http:
      paths:
      - backend:
          serviceName: nginx-service
          servicePort: 80
```

実のところどういう意味かは執筆時点で全然理解できていないけれどこれで動いたのでヨシ。

元記事の定義との変更点は、片方はannotationの`nginx.ingress.kubernetes.io/ssl-redirect: "false"`。
デフォルトの動作だとHTTPSにフォースリダイレクトされてしまったため、[ユーザーガイド][nginx-ingress-tls]に従って動作を変更した。
ConfigMapで行う方法とannotationで行う方法が示されていて、今回は後者。ConfigMapはaddonが勝手に入れているようだけれど、弄れるのか？

もう一つの変更はホストの指定。
参考にした記事の設定では`nginx.minikube.dev`というホスト名を設定し、dnsmasqでそのホスト名で名前解決するようにしていたけれど、今回はlocalhostからポートフォワードして入るため、こんな記述にしてみている。
nginxの知識もIngressの知識も無く、ホスト名の設定がどこにどう利くのかよく理解できていないから、これでいいのかは分からない。どうせホビープロジェクトだし困ってから考える。

あとはVMでポートフォワードの設定をし、ブラウザから`http://localhost:xxxx`にアクセスして指定したServiceに案内されたら成功。
ブラウザのキャッシュを無効化せずに叩いてhttpsに案内されたのにハマったのは内緒だ。一度httpsに通されると勝手にhttps向くんだね。

# 最後に
k8s全然わかんない


[qiita-minikube-ingress]:https://qiita.com/superbrothers/items/13d8ce012ef23e22cb74
[qiita-nginx-ingress]:https://qiita.com/MahoTakara/items/cdfa379f2280a58fdd6d
[nginx-ingress-tls]:https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/tls.md#server-side-https-enforcement-through-redirect
自社サービスを開発し起業を目指す新人エンジニアの自己紹介

どうもこんにちは。
タイトルの通りの自己紹介になります。

起業への第一歩として、独学ではありますがwebサービスの開発を始めたわけなのですが、
どうせならQiitaに悩んだ箇所だったりを投稿しようと考えました。
その前に一旦自己紹介と考えていることを発信したいという気持ちから、今カタカタとキーボードを叩いています。

多少長くなってしまうと思いますが、お付き合いください。
まぁ極々僅かな人しかページを開かなそうなんですけどね。

#自己紹介
現在、大阪の中小Sier(社員30人前後)に勤めている、20代前半の男です。

小中高と特に何も考えず適当に過ごし、一年浪人するも途中でだらけて誰でも入れるような短大に進学。
その後、付き合っている彼女を追いかけ大坂で就活を始めました。
一番最初に内定をもらったのが弊社で、まぁそこまで悪くもなさそうだったので他の面接を全部蹴り入社したという感じですね。

自分でもドン引きするくらいノープランです・・・。
そんなこんなで2019年の4月にようやく入社して1年となるわけです。


#起業したいと考えたきっかけ

そもそもなぜこの業界を選んだかというと、単純に理系で他の仕事のイメージが思い浮かばなかったからです。
「プログラミングかっこいい！」みたいなことも思ってましたし、実際にやってみたら楽しかったですしね。

内定を取って後に「SES」、「客先常駐」という言葉を知りました。弊社が主に行っている事業がそれであることも。
インターネットで上記の単語を調べると9割近くが悪い話だったため、入社前から不安しかなかったです。
最近でもTwitterではSESの良し悪しについて多くの方が意見を話していますね。

実際に入社して1年近く経ちますが、感想としては「あれ？そこまでSES悪くないじゃん」でした。
ネット上で見るような奴隷のような扱いを受けるだとかはなかったですね。(新人ということでテスト作業は多かったけど)
会社としてもそこまで悪くないのかな？って感じでした。
先輩方も良い人が多く、同じ客先で働いている先輩も技術力等が高いようで評判がいいです。

だが、恐ろしく仕事がつまらない。
部分部分で面白いところはあります。プログラムが思い通りに動いたときやソースを綺麗にまとめられたときなどですね。

それでもつまらないと思ってしまう理由としては、エンドの会社に作ってと言われたものをその通りに作り、
完成したら「はい、ご苦労様」って感じで終わるところです。

そこにアイデア性もなければクリエティブな感じもしません。
私が仕事に求めているのは感謝と評価なのです。この辺りは上流工程に関われれば変わってくるのかもしれませんね。

それでも私は自分あるいチームで考えたサービスなどを開発し、大勢の人間からの評価を受けたいと考えているため
Sierには向いていないのかなと考えました。

会社への不満としては、全体的に「まぁこんなもんじゃね？」という考えで何かを変えようだとか、挑戦する気持ちが全くないことです。
色々な先輩に話を聞いてみたところ、彼らが思っているのは「辛くもないけど楽しくもない。給料が良いわけでもないが、悪くもない。まぁこんなもんでしょ。」と考えているようです。

私は「どうせ何十年も働くなら楽しいほうがいいだろう」という考えなので、理解はできても同意はできませんでした。
そんなこんなでやりたいことをやるために起業したいという考えに至りました。

#まとめ
結構長くなってしまったので、あまり詳しく書けませんでした。(一応自己紹介なので)

起業したいと言うだけであれば誰でも言うことができますし、こんなことを書いたところで誰も応援などしないでしょう。
私は自分の意見をどんどん発信していきたい人間なので、ここに書いているわけですが書いているだけでは意味がないので行動をしたいと思っています。

冒頭でちらっと書いたwebサービスの開発がそれです。
そのサービスで起業したいと思ってますが、まぁ無理でしょう。
やるからには本気でやりますが、そんなに甘くないことも理解しています。
ただ、自身でサービスを作ったという自信は今後の人生において無駄ではないと思います。

今回書けなかった思いなどはサービス等が成功してビジネス書等を出すときにとっておきます笑。

だらだらと書いてしまったのでここまで読んでくれている方はいないかもしれませんが、要はこれから色々投稿するからよろしくお願いしますということです。
まだまだ未熟なので最初のうちはしょうもない投稿が多いかと思いますが、技術力と共に投稿内容の質もあげていきます。
devise使用時、usersにimageカラムを追加して画像を表示

#カラム追加

```:ターミナル
rails g migration AddImageToUsers image:string
```

```:ターミナル
rails db:migrate
```

データベースにimageカラムを追加しました

```application_controller.rb
def configure_permitted_parameters
  devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :image]) 
end
```
ストロングパラメーターに、imageを追加

#carrierwaveの設定

もうすでに追加してる人は飛ばしましょう。

```:Gemfile
gem 'carrierwave'
```
```:ターミナル
bundle install
```

gem 'mini_magick'なんかもインストールしとくと元の画像をリサイズできます。


```:ターミナル
rails g uploader Image
```
上のコマンドで、app/uploaders/image_uploader.rbを生成。

```app/models/user.rb
mount_uploader :image, ImageUploader
```
を追加。gemを入れた時は’rails s’し直しましょう
これで、'carrierwave'の設定は一旦終了です。
（参考：https://qiita.com/ttaka66/items/264dcb85e41f9135685c ）

#ファイル選択ボックス設置
```registrations/new.html.erb
<div class="field">
  <%= f.label :image %><br/>
  <%= f.file_field :image %>
</div>
```
新規登録画面に、ファイル選択ボックスを設置。
これで新規作成画面から、画像をDBに保存できるようになります。

#アイコンの表示

```:users/index.html.erb 
<img src=<%= @user.image %> class = "icon_image">
```

```users.scss
.icon_image {
  width: 200px;
  height: 200px;
  //サイズ指定
  border-radius: 100px;
  //画像を丸くする
  object-fit: cover;
  //タテヨコ比を変えないままトリミング
}
```


終わり。
PHP で超簡単に Mackerel のサーバーメトリクスを増やす

Mackerel 楽でいいですね。

サーバー上で変化する数値ならだいたい何でもグラフになります。ただ、データ取得方法が自社サービス固有のなにかだった場合、既存のプラグインでは対応できません。

そんなときは Mackerel に独自のメトリクスを増やします。難しそう? Go で書かないとだめ? いやいや、ほんと超簡単ですから。

というわけで、PHP のアプリケーション開発を例に、どれだけ簡単にできるかを説明しましょう。コード例は Symfony ですが、CLI コマンドをサポートする任意のフレームワークで同じ方法が通じます。(じっさい自分が運用してるのは Yii で動いてます)

まずは [ちょっと便利なライブラリ](https://github.com/phplucidframe/console-table) を Composer で追加します。

```shell
composer require phplucidframe/console-table
```

CLI コマンドを追加します。

```php
<?php
namespace App\Command;

use LucidFrame\Console\ConsoleTable;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class MackerelDemoCommand extends Command
{
    public static $defaultName = 'app:mackerel-demo';

    protected function configure()
    {
        $this->setDescription("Describes the easiest way to create Mackerel plugin");
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        // Prepare random demo data...
        $data = [
            'app.mackerel-demo.sample' => time() % 10000,
            'app.mackerel-demo.2nd-sample' => mt_rand(0, 99999) / 100.0,
            'app.mackerel-demo.3rd-sample' => mt_rand(0, 9999) / 100.0,
        ];

        // Output them to STDOUT.
        $output->write($this->format($data), time());

        return 0;
    }

    private function format(iterable $data, int $timestamp): string
    {
        ob_start();
        $t = new ConsoleTable();
        foreach ($data as $k => $v) {
            $t->addRow([$k, $v, $timestamp]);
        }
        $t->hideBorder()->display();
        return ob_get_clean();
    }
}
```

はい実装おしまい。

ちょっと冗長なところはありますが、重要なのは `$data =` に何を入れるかと、そのフォーマット方法だけです。(ConsoleTable できれいな出力を心がけてますが、ぶっちゃけ半角スペースで区切られた3ワードの項目名+数値+タイムスタンプなら何でもOK)

```
$ bin/console app:mackerel-demo
 app.mackerel-demo.sample      1735    1552545393
 app.mackerel-demo.2nd-sample  545.49  1552545393
 app.mackerel-demo.3rd-sample  23.8    1552545393
```

Mackerel のプラグインというのは実は、実行可能で標準出力にこういう形式の出力をするものなら何でもありです。自社サービス固有のなにかを、固有の方法で取得して、ここでいう `$data` に突っ込めばいいのです。PHP配列が「順序ありキーバリュー」になってるところがスマートですね。

このコマンドを `mackerel-agent.conf` に追加してやれば、独自コマンドをポーリングして Mackerel のコンソールに定期報告が来るというわけです。

```:/etc/mackerel-agent/mackerel-agent.conf
apikey = "XXXXXXXXXXXXXXXXXXXXXXXXX"
  :
 (略)
  :
[plugin.metrics.app]
command = "/app/current/bin/console app:mackerel-demo"
```

mackerel-agent デーモンの再起動はお忘れなく。

サーバーの負荷と連動する種類のビジネスの動きを、同じグラフで見ることができると便利です。負荷アラートが出てしまう前に、ユーザーの動向を察知するアラートで予告してくれるとかもできて、かっこいいですよ。

ぱっと考えられるのは、直近のアクティブユーザー数とか、分速で何個いいねが付いてるかとか... SQL の集計関数で(インデックスさえ適切なら)サクッと出せそうです。

難しい技術は不要。フレームワークがあるならほんの少し、やりたいことをコードにするだけ。独自 Mackerel プラグインは、何を計測すると便利かというアイデアの勝負なので、そのあたり PHP で軽快にやる人と相性良さそうな気がします。

もちろん Ruby なら Rake タスクでも! あと以下略
background imageをプリロードする方法

ページにCSS animationを設定した際に、backgroundのロードに時間がかかってしまい、アニメーションが不自然になってしまったので、背景画像を先にプリロードしたいと思います。

```ruby:html
<head>
  <link rel="preload" as="image" href="background.png">
  <link rel="stylesheet" href="style.css">
</head>
```

これで、background.pngをプリロードできるので、cssのanimationが動く前に画像を読み込むことができます。
PWA Nightめも

ものすごく個人的なメモです。

# 開催概要
https://pwanight.connpass.com/event/116944/
ハッシュタグは#pwanight

# 開催挨拶
- これから毎月開催するよ
- ロゴ爆誕

# 自己紹介タイム
10秒ってめっちゃ短い

## 気になったこと
- 「分析の部分が闇」

# PWAの今とこれから（仮） by 宍戸さん@Google
## はじめに
スタバのサイトはPWAとして完成度が高い。
- ログインの自動化、決済まで

Google Map、Search、PhotoがPWA化してる。

## 特徴
- 高速な表示
- 信頼性
- エンゲージメント性

### パフォーマンス
日経電子版とかめっちゃ早くなったよ。

### 信頼性
- デバイスのキャッシュを有効に利用する
ServiceWorkerを利用する。
Workboxを使うと簡単。

- オフラインの時はフォールバックページを返す
これもServiceWorkerでできる。

- ホームスクリーンに追加
ホームに追加するプロンプトを表示するタイミングを制御できる
BeforeInstallPrompt

- プッシュ通知
アクセスしてすぐにプッシュ通知の許諾を求めるのはUX的に良くない

- ログイン、支払いを簡単に

## What is Next
実はまだまだデスクトップも伸びている。
Cross Browser、Cross OS

Web ViewはブラウザのCookieを共有していない
PWAはCrome Custom Tabを使用しているのでcookieを共有している

# PWA はビジネス的に美味しいか？ by 橋本さん@パラダイスウェア
実際にビジネスで使ってみた経験のお話。
[https://speakerdeck.com/paradisemaker/pwa-habizinesude-nimei-wei-siika](https://speakerdeck.com/paradisemaker/pwa-habizinesude-nimei-wei-siika)

## メリット
- ネイティブアプリよりも低工数(開発/運用)
 - ネイティブアプリを2チーム回すより安い
- 体制を張りやすい
- フレームワークがすごい(爆速！)
 - 感覚的にネイティブの1/3
- 後からアプリ化できる
- 「担当者ガチャ」リスク回避
- 「Apple/Goolge税」問題回避

## PWAの向いているところ
B2Bに向いてる
### 新規事業あるある
要件定義に時間がかかる、要件/仕様変更が多い、システム間連携･･･
遅延でコスト増
コレジャナイ
IT投資見直し

### PWAを使うとどうなるか
早期に動くものを作れて触れる
- データが乗っている画面が動く
- 意思決定が早い
- 要件/仕様の祖語の早期発見
- フロントとサーバサイドを分離しやすくコレジャナイを防げる

### プロトタイピングでおすすめの構成
vue.js + Firebase + twilio
スクラム/カンバンとの親和性も高い


# リーンスタートアップとPWA～Webサービス立上げ時こそPWAを検討したい！～ by 角谷さん@TAM
## リーンスタートアップの中での活用
プロトタイプやオズの魔法使いで使えそう

## なんで向いているのか
- 新しい取り組みは予算も人員も少ない
- MVPを作り、検証しながら少しずつ育てる戦略がおすすめ
- ネイティブアプリに比べて改修のサイクルを早められる
 - ネイティブアプリはすべてがダブルコストな上にリリースの度に審査が必要

## ネイティブとのすみわけ
Webで訪問者を増やしPWAでリピーターを増やしてAppdeロイヤルユーザーを掴む

- パフォーマンスを高めるなら
最初から考慮して作っていれば問題ない

## 注意
URL設計ミスるとGoogle検索でインデックスされなくなる

# PWA×CMS活用アイデア by 早瀬さん@シックス・アパート
## PWA対応に必要なこと
- サイトの常時SSL化
- ウェブアプリのマニュフェストファイルの作成
- ServciceWorkerの作成
- Webプッシュ通知の実装
など

## ユーザー事例
- 英語教育のサイト
 - 受講者向けと運営向けに提供しているサイトの受講者向けサイトをPWA化
- 陽光台小学校PTA
 - ITリテラシーが低い人にもプッシュ通知が送れる！

## PWAが思ったより普及していない理由
- iOSの対応がまだ不完全
クラス名の文字列を使わずにDynamic Feature ModuleのActivityを呼び出す

アプリケーションからDynamic Feature Module形式のモジュールに含まれるクラスは見えないので、Activityを呼び出す際には

```kotlin:app/src/main/java/com/example/app/MainActivity.kt
startActivity(
    Intent().setClassName(
        this,
        "com.example.dynamic_feature.DynamicFeatureActivity"
    )
)
```

のようにクラス名の文字列を指定することになりますが、補完が効かず、Activityのクラス名を変更した際に追随してくれません。
またNavigationでActivityへの遷移を定義している場合は、モジュールがインストールされていない状態だとアプリケーションがクラッシュしてしまいます。
これを何とかする方法です。

> 以下のコードはPlay Consoleのinternal test trackを使った検証はしていませんのでご注意下さい。

`activity-alias`を使います。

まず、アプリケーション側で以下のようなsealed classを作ります。

```kotlin:app/src/main/java/com/example/app/ActivityAlias.kt
package com.example.app

import android.app.Activity

sealed class ActivityAlias : Activity()
sealed class DynamicFeatureActivityAlias : ActivityAlias()
```

ActiivtyAliasクラスがActivityを継承しているのは、Navigationのクラス存在チェックを回避するためです。
DynamicFeatureActivityAliasをsealed classとして定義しているのは、インスタンス化を防ぐためです。

さらに、ProGuard/R8でリネームされないように、アプリケーションのproguard-rules.proに以下の設定を追加しておきます。

```app/proguard-rules.pro
-keep class * extends com.example.app.ActivityAlias
```

最後に、対象モジュールのAndroidManifest.xmlに`activity-alias`を追加し、上記で作成したDynamicFeatureActivityAliasのクラス名を`android:name`に指定します。

```xml:dynamic_feature/src/main/AndroidManifest.xml
<activity-alias
    android:name="com.example.app.DynamicFeatureActivityAlias"
    android:targetActivity=".DynamicFeatureActivity" />
```

モジュールからアプリケーション側のクラスは見えるので、`android:name`の値は補完が効き、クラス名の変更にも追随してくれます。

これで、以下のように`Intent(Context, Class)`を使ってIntentを生成することができるようになります。

```kotlin:app/src/main/java/com/example/app/MainActivity.kt
startActivity(Intent(this, DynamicFeatureActivityAlias::class.java))
```

Nagivationを使う場合は、以下のように`android:name`にDynamicFeatureActivityAliasのクラス名を指定することができます。

```xml:app/src/main/res/navigation/nav_graph.xml
<activity
    android:id="@+id/dynamic_feature"
    android:name="com.example.app.DynamicFeatureActivityAlias" />
```

DynamicFeatureActivityAliasはActivityのサブクラスなので、エラーにはなりません。

以上です。


### 参考
マルチモジュールとNavigation
https://medium.com/@star_zero/%E3%83%9E%E3%83%AB%E3%83%81%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E3%81%A8navigation-c7aaffbfd76
PlantUMLのすすめ

# はじめに
本稿では、PlantUMLについてご紹介します。
使い方について詳しくは記載していません。
主に以下の内容について書いていきます。

- PlantUMLとは何か
- 簡単な使い方
- メリット・デメリット

# PlantUMLとは
PlantUMLとは、UMLダイアグラムをテキストで作成できる言語のことです。
以下のようなコードが。。

```
@startuml

skinparam sequence {
  ArrowColor #648CD5
  ParticipantBackgroundColor #orange
}

title 新規会員登録

actor ユーザー  as user #blue
participant 会員登録機能 as 会員登録
participant メール配信機能 as メール配信
database 会員 #B3CC90

user -> 会員登録:新規会員登録
会員登録-> メール配信:メール配信処理
メール配信 -> user:メール送信
user -> 会員登録:リンククリック
user <- 会員登録:会員登録画面
user -> 会員登録:会員情報入力
alt 入力情報不備
  break
       会員登録 -> user:エラー
  end
else 入力情報OK
  会員登録 -> 会員:会員情報登録
end
user <- 会員登録:マイページ画面

@enduml
```
ドドーンと、こんな感じのシーケンス図になっちゃいます。
![新規会員登録.png](https://qiita-image-store.s3.amazonaws.com/0/206898/256be46f-5196-ffa9-41bc-52fbe9a1c8f8.png)

シーケンス図を例として載せていますが、他のUMLも作成することができます。

# 導入方法
以下のサイトを参考に進めさせていただきます。
http://yohshiy.blog.fc2.com/blog-entry-152.html


私はWindows8ですが、PlantUMLはクロスプラットホームで使えるため、
他の環境でも利用できるかと思います。
必要なものは以下です。

- java
既に入っている方が多いと思いますが、無い場合は以下のサイトからインストールしてください。
https://www.java.com/ja/

- PlantUML
以下のサイトから「plantuml.jar」をダウンロードします。
http://plantuml.com/ja/download

これで準備OKです。

# 使い方
まずは図の元となるコードを書いていきます。

```test.txt
@startuml test.png
Bob -> Michael :message
Bob <- Michael
@enduml
```
次に、「plantuml.jar」ファイルをクリックして、PlantUMLを起動します。
作成した「test.txt」があるディレクトリを指定します。
すると、このようにシーケンス図が作成されます。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/206898/661375b9-2d91-ebf2-8dd9-e9c47816031e.png)

シーケンス図って素敵。

また、Eclipseのプラグインもあります！
Eclipse上であれば、プレビューを見ながら図を作成することができて、とても良いです！
(以下サイト参考)
http://plantuml.com/ja/eclipse


# メリット・デメリット
テキストによる作図のメリット・デメリットは以下です。

- メリット
    - テキストで作成するため、差分がわかりやすい。
    - 図に対してグレップできる。
    - メンテナンスがしやすい。  
      　⇒Excelだと少し修正したいだけでも図形をたくさん移動する必要があったりして少し大変。。
 
- デメリット
    - 記法を勉強する必要がある。
    - レイアウトの調整が難しい。  
      　⇒図の大きさや図と図の間隔等の調整は難しい。。

# 最後に
デメリットに、「記法を勉強する必要がある」と上げましたが、
直感的にわかりやすい記法だと思いますので、簡単な図であればすぐに書けると思います。
また、レイアウトの調整が難しいというデメリットがあるため、
細かい調整が必要であればExcel等、不要であればPlantUMLというように
使い分けていくのが良いかと思います。
functions.phpのテストを書く

functions.phpのテストコードを書きたいが、ローカルにWordPressを入れていないので、 `functions.php` を `require` すると、WordPressの関数を実行するところで `Call to undefined function` がでる。なので、スタブを作って `include` する。

```php:wp_global_functions.php
<?php

//functions.phpで使用されるWordPressの関数を定義しておく

function add_action()
{
    return true;
}

function add_filter()
{
    return true;
}

function add_shortcode()
{
    return true;
}
```

```php:functionsPHPTest.php
<?php
namespace TestCase;

include_once __DIR__ . '/wp_global_functions.php';
require_once __DIR__ . '/functions.php';

class functionsPHPTest extends \PHPUnit\Framework\TestCase
{
    function testHoge()
    {
        $hoge = functionInFunctionsPHP();
        $this->assertNotNull($hoge);
    }
}
```

名前やパスはそれぞれの環境にあわせてよしなにする。

なんかもっと良い方法があったら教えてください。
RedHat 系 OS のログの流れ

自分用にまとめます。

# ログ転送概観
ログはおおむね `/var/log/messages` で見れる。
何かあったらまずは messages をみよう。

RHEL7(CentOS7)以降のログ転送の構成は以下

``` 
カーネル(printk(9)) -> /dev/kmsg -> systemd-journald -> rsyslog --+--> /var/log/messages 　
　　　　　　    　　                         　↑　 　　　       　  +--> /var/log/cron.log
ユーザApp(syslog(3),logger(1)) -> /dev/log ---+                   +--> etc.
```

上記ですべてではなく、ほかにもログの経路は存在する。

syslog の仕組みを介さず、アプリケーション独自で採取しているログは上記の構成に則らない。
※たとえば httpd のアクセスログ（/var/log/httpd/access_log）など

# printk(9)
カーネル関数。もちろんカーネル内、もしくはカーネルモジュール内でしか使えない。
カーネルがログを出力する際に利用される関数で、実態としては /dev/kmsg に書き込みを行う関数。
引数に与えるログ文字列の先頭に”<¥d>”と記述することでログレベルを指定できる。
printk() によって出力されたカーネルログは journald や rsyslog に渡されるとともに、dmesg コマンドなどでも確認できる。

# syslog(3)
libc ライブラリ関数。同名のシステムコール  syslog(2) とは全く異なるもの。
ユーザ空間のアプリケーションがログを出力する際に利用されら関数で、実態としては /dev/log に書き込む関数。
openlog() でファシリティ、プログラム名を指定してログを開き、syslog() でプライオリティを指定してログ出力、closelog() でログを閉じる。なお、glibc では、ファシリティに kern を指定すると勝手にファシリティが user に置き換えられるようになっており、カーネルログを吐けないようになっている。

# logger(1)
標準コマンド。実態としては /dev/log に書き込む。

# rsyslog
rsyslog は従来のログ集計・転送アプリケーション。

rsyslog のログ飛ばし先設定は `/etc/rsyslog.conf` に記載あり。
以下は rsyslog-8.24.0-16.el7_5.4 インストール直後の設定内容。
mail、authpriv、cron以外のファシリティの、info 以上のプライオリティを持つログを `/var/log/messages` に出力する、というような内容が読み取れる。

```
*.info;mail.none;authpriv.none;cron.none                /var/log/messages
authpriv.*                                              /var/log/secure
mail.*                                                  -/var/log/maillog
cron.*                                                  /var/log/cron
*.emerg                                                 :omusrmsg:*
uucp,news.crit                                          /var/log/spooler
local7.*                                                /var/log/boot.log
```

# systemd-journald

RHEL7（CentOS）以降で導入されたログ集計アプリケーション。
rsyslog なしで、journald だけ運用することもできる。

/dev/log 、/dev/kmsg その他諸々からログを一括に収集する。

rsyslog は単にテキストベースでログを集計、分類、転送していたが、journald はログを吐いたプロセスやプライオリティなどをメタデータとして保有している。
そのため、journaldにはjournalctlコマンドによる高度なログ検索機能があり、rsyslogのようなログファイル分割機能はそもそも必要とされず、存在しない。
DockerでPostgreSQLのコンテナ起動時にPANIC:  could not locate a valid checkpoint recordが出た時

`docker-compose up`を実行した時以下のエラーが出力されてPostgreSQLのコンテナが起動しない現象があった。

```shell

db   | LOG:  invalid primary checkpoint record
db   | LOG:  invalid secondary checkpoint record
db   | PANIC:  could not locate a valid checkpoint record
db   | LOG:  startup process (PID 22) was terminated by signal 6: Aborted
db   | LOG:  aborting startup due to startup process failure
mother_db exited with code 1
```

`docker-compose down --rmi`でイメージごと削除して再度`docker-compose build`&`docker-compose up`してもだめ。

解決方法が見つからず自分がPANICになったが、以下の記事で助かった。
[PANIC: could not locate a valid checkpoint record (Docker and Postgres)](https://medium.com/@lynzt/panic-could-not-locate-a-valid-checkpoint-record-docker-and-postgres-2f74d8cdfdfd)

`docker volume ls`で対象のボリュームを探して`docker volume rm  <volume-name>`をして再度`docker-compose up`するとうまくいった。
どうやらコンテナもイメージも削除してもボリュームというものが残るらしい。

ボリュームとはデータを永続化できる場所のことみたいですね。
[Docker、ボリューム(Volume)について真面目に調べた](https://qiita.com/gounx2/items/23b0dc8b8b95cc629f32)

Dockerの理解がなさすぎていつも躓くので精進します。。
皆様のお役に立てれば幸いです。
【Ruby on Rails】production環境でデータベースを作成する際にPostgreSQLにログインできない場合の対処法

Ruby on Railsでproduciton環境でデータベースを作成する際にいくつかハマりポイントがあったのでメモ

# まずはmaster.keyで
作業するディレクトリを変えたかった関係でcloneしていたのでまずここでつまずきました。
Rails5.2から追加された機能のようですね。
こちらの記事を参考にさせていただいた結果この現象についてはすぐに解決。
[Rails 5.2 で ActiveSupport::MessageEncryptor::InvalidMessage](https://qiita.com/scivola/items/cc06ddbfd94d3118f693)

#Peer認証
PostgreSQLにログインできるかどうか試してみる。

```
$ psql -U taskcontrol
psql: FATAL:  Peer authentication failed for user "taskcontrol"
```
どうやらPeer認証というPostgreSQLの機能でOSのユーザー名とPostgreSQLのユーザー名が違うとログインをはじいてしまう仕組みがあり、この機能がデフォルトでオンになっていた模様。
[PostgreSQLのPeer認証と他の認証方法への変更](http://www.utsushiiro.jp/blog/archives/327)
こちらの記事を参考に/etc/postgresql/10/main/pg_hba.confを編集し、最下部のpeerとなっている部分をすべてmd5に変更。

```pg_hba.conf
# Database administrative login by Unix domain socket
local   all             postgres                                md5

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     md5
# IPv4 local connections:
host    all             all             127.0.0.1/32            md5
# IPv6 local connections:
host    all             all             ::1/128                 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     md5
host    replication     all             127.0.0.1/32            md5
host    replication     all             ::1/128                 md5
```
もう一度ログインしようとすると同じエラー。PostresSQLを再起動する必要があった。

```
$ sudo service postgresql stop
$ sudo service postgresql start
```

再度ログイン

```
$ psql -U taskcontrol
Password for user taskcontrol:
psql: FATAL:  database "taskcontrol" does not exist
```
またログインできていないのかと思ったが、データベースをまだ作成していないだけだったので、production環境でのデータべース作成を実行。

```
$ RAILS_ENV=production bin/rails db:create db:migrate
```
```
== 20190212064526 CreateTasks: migrating ======================================
-- create_table(:tasks)
   -> 0.0223s
== 20190212064526 CreateTasks: migrated (0.0234s) =============================
(中略)
== 20190215013543 AddUserIdToTasks: migrating =================================
-- execute("DELETE FROM tasks;")
   -> 0.0011s
-- add_reference(:tasks, :user, {:null=>false, :index=>true})
   -> 0.0120s
== 20190215013543 AddUserIdToTasks: migrated (0.0153s) ========================
```

#まとめ
なんとかproduction環境でデータベースを作成できました。
何か捕捉の情報や修正などありましたら、コメント欄にてご指摘頂けますと幸いです。
sayコマンドでいろいろ

sayコマンドで遊ぶためのメモ書き

# say 英語
発音確認したいときに便利！

```shell
say -v Alex Hello world!
```
# say ドイツ語（他）
喋る人（言語）はオプション```v```で変更できます．
どんなボイスがあるかは```say -v '?'```で確認できます．
発音確認したいときに便利！！

```shell
say -v Anna Gott ist todt!
```
# say 葬送行進曲
ボイスの中にはあらかじめ音程が設定してあるものがあります．
Bad Newsは葬送行進曲を歌ってくれます．

```shell
say -v Bad ah na ta gah o sa gah shi no file wa mi tsu ka ri ma sen de shi tah
```
威風堂々を歌ってくれるGood Newsというボイスもあります．
ボイスがない場合はシステム環境設定>アクセシビリティ>スピーチからダウンロードしましょう．
![Screen Shot 2019-02-18 at 19.05.45.png](https://qiita-image-store.s3.amazonaws.com/0/356727/724850d5-dc14-9dd6-3c71-f5406aad89d2.png)

# say 伯方の塩
音素モードで入力すればいろいろ歌わせられます．
pmod: 抑揚
rate: 音の長さ
pbas: 音程（MIDIノートナンバー）
inpt: モード（TEXT or PHON）

```shell
say -v Fred "[[pmod 0; rate 100; inpt PHON]][[pbas 50]]hAA, kAA, tAA,[[pbas 52]]nAO,[[rate 200; pbas 47]]sIY,[[pbas 43]]AO"
```
管理画面より不要なメニューを削除する

WordPressの管理画面を他のメンバーにも触らせたいが、
メニューが多すぎて混乱する、設定を変更してしまってサイトを壊してしまうといったことが懸念される。
記事の投稿などを行うユーザを、投稿権限で分離して、安全なサイト運用を行おう

## 権限を制限したユーザの作成

管理画面で「ユーザ＞新規追加」でユーザ作成画面を開く。
ユーザ名、メールアドレスは必須項目なので入力。
権限グループを「編集者」にして、「新規ユーザを追加する」をクリックする。

作成した「編集者」のアカウントでログインすると、左メニューは下記のようになっている。
<img width="123" alt="editor.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/109315/588d8a57-6343-bb65-3740-44112d79d237.png">
これだけでもある程度管理画面で使用できる項目が制限されていてありがたい。
管理者だとこんな感じ
<img width="119" alt="kanri.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/109315/3d96e31a-ee3f-9817-65b5-63ea4b32baf1.png">
外観やプラグイン管理が消えているので、WordPress自体の設定変更ができなくなっている。

なお、削除されたメニュー項目に、編集者のアカウントでアクセスするとこうなる。
<img width="680" alt="nopermission.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/109315/501c0517-400f-d1f9-801c-1dc82f0ca202.png">
ちゃんとアクセス制限がかかっていることがわかる。

## 権限の編集

デフォルトで権限を制限してくれることは分かったが、この権限設定を自分のサイトに都合がいいように制御したい。
そんなときは、function.phpに下記のコードを追加する。

```
function remove_menus () {
	global $menu;
	//管理者以外のユーザに関しては、下記メニュー削除
	if (!current_user_can('level_10')) { 
		unset($menu[5]);//投稿
	}
}
add_action('admin_menu', 'remove_menus');
```
上記の場合、投稿が削除される。カスタム投稿でブログを作っている場合、
投稿は使用しないケースも多いので消したいことがほとんどだろう。
unsetで消したいメニューの項目を削除すれば、指定の権限で該当のメニューは出なくなる。
具体的に$menuの何番目の値を消せばメニューから削除できるかについては、
列挙するよりもvar_dumpで$menuを出力してみるほうが早いだろう。
awkで大量のテストデータを作成

100万件越えのCSVファイルをawkコマンドだけで簡単に準備する方法を紹介します。

##環境・前提

- awkが実行できる
- 重要なのはデータ件数
- データの内容はこだわらない（下記程度）
    - 連番
    - パターン
    - 乱数

##awkスクリプトを準備
```awk:gen.awk
BEGIN {
        srand();
        printf("f1,f2,f3,f4\n");
        for(i=1; i<=1000000; i++){
                printf("%d,固定文字%08d,%d,%d\n",
                i,
                i+9000000,
                i%3,
                substr(rand(), 3) );
        }
}
```

####やってること

- 100万行のデータ
- ヘッダ行あり
- 4列CSV

| 列  |       目的|    用途    |
|:----:|:------------------:|:------------------:|
| 1   |  連番(1～) |        primary key        |
| 2   |  固定文字+連番(開始位置調整) |  氏名など       |
| 3   |  パターン |  性別や所属など         |
| 4   |  乱数 |      電話番号など        |

##実行
```
$ awk -f gen.awk > 1000k.csv
```

##確認
```
# 行数
$ wc -l 1000k.csv
1000001 1000k.csv

# 先頭3行
$ head -3 1000k.csv
f1,f2,f3,f4
1,固定文字09000001,1,576777
2,固定文字09000002,2,465325

# 最後3行
$ tail -3 1000k.csv
999998,固定文字09999998,2,29666
999999,固定文字09999999,0,412693
1000000,固定文字10000000,1,603937
```


簡単に速くテストデータを作成できました。
PerlやPythonで丁寧に書くまでもなく、DBもないような場合にいかがでしょうか。
Ionic4で modal 系をAndroid Hardware Back Button で閉じる方法

ionicを使って、Androidアプリを開発していて、Android Hardware Back Buttonのハンドリングに苦労した為、知見をまとめて置きます。
ionic4の[ion-modal](https://ionicframework.com/docs/api/modal)には、単純に使おうとするとURLが振られておらず、バックボタンが押された時にアプリが閉じていまいます。

今回は、cordova等を使わない純粋なWeb APIで閉じるようにします。
Web APIの[History](https://developer.mozilla.org/ja/docs/Web/API/History)を使って、動作を再現する必要があります。



```js
// 追加　自分自身のページをストックする。
history.pushState(null, null, '');
// 閉じる
history.back();
```

ion-modalように実装すると以下のようになり、正しく閉じることが可能です。

```js

constructor() {
  // Fake history の追加 (Android hardware back 対策)
  window.addEventListener('ionModalDidPresent', () => {
    history.pushState(null, null, '');
  });
  // 画面操作で閉じられた場合は消えないので事前 にFake history を消す
  window.addEventListener('ionModalWillDismiss', () => {
    // Fake history は null で判定可能
    if (history.state === null) {
      history.back();
    }
  });
}
```

モーダル以外のコンポーネントででも判定可能です。
実装ベースでは、Did、WillのタイミングとFake historyの値に気をつけて実装してあげましょう。
VirtualBox6.0のLinuxでGuest Additionsが効かない問題をディスプレイ設定で解決した

#解くべき問題
VirtualBox6.0に入れたLinux Mintで，画面サイズ（解像度）が自動可変にならない
（Guest Additionsをインストールしたのに）

※Linux Mintと書いたが他のディストリビューションでも似た現象があった

#原因
仮想マシンのディスプレイ設定：Graphics ControllerがVMSVGAだった

- VMSVGAとは[VirtualBox6で追加された](https://www.virtualbox.org/wiki/Changelog-6.0#v0)3Dグラフィックス用の設定らしい
- ~~よくわからんが~~ディスプレイ設定がVMSVGAだと画面サイズの自動可変ができない
- VBoxVGAにしたら自動可変した（だいたい3秒以内に変わってくれる）
- 要するに設定の問題なので，他のLinuxディストリビューションでも同じ現象は起こり得る
- 初期設定がVMSVGAだったので，仮想マシンを作った時は一々変える必要がある
タイトルの画像が表示されない Udemy 【3日でできる】はじめての Django 入門　レクチャー41

# はじめに
[【3日でできる】はじめての Django 入門 ( Python 3 でウェブアプリを作って AWS EC2 で公開！）](https://www.udemy.com/django-beginner/)レクチャー41でタイトルの下に画像を表示しようとするも、表示されない。

# 結論
「settings.py」に問題があった。
※Q&Aに解決策が載っている

```
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [''],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
```
↓

```
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': ['templates'],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
```
『DIRS』に『'templates'』を入力する必要がある。

## 原因
テンプレートファイル側の

```
{% load static %}
```
が効いていない状態らしい。

## その他確認事項
解決にあたり以下の項目の確認をしてくださいと先生が言っていた。

myblogapp直下のurls.pyでdjangoのstaticをインポートしているか？

```
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static　←←←←←←←←←←←←←←←←←←←←
from django.conf import settings
from posts import views
'''

settings.pyで
１．staticfilesがINSTALLED_APPSにあるか

```
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',　←←←←←←←←←←←←←←←←←←←←
    'posts.apps.PostsConfig'
]
```

２．STATIC_URLが定義されているか

```
STATIC_URL = '/static/'
```
CoqIDEをMacに入れたかった（本買った）

#本買った

店頭で見つけた定理証明支援系に関する書籍を衝動買いしてしまいました。

####Coq/SSReflect/MathCompによる定理証明:フリーソフトではじめる数学の形式化 単行本（ソフトカバー） – 2018/4/18 萩原 学 (著), アフェルト・レナルド (著)
https://www.amazon.co.jp/Coq-SSReflect-MathComp%E3%81%AB%E3%82%88%E3%82%8B%E5%AE%9A%E7%90%86%E8%A8%BC%E6%98%8E-%E3%83%95%E3%83%AA%E3%83%BC%E3%82%BD%E3%83%95%E3%83%88%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E6%95%B0%E5%AD%A6%E3%81%AE%E5%BD%A2%E5%BC%8F%E5%8C%96-%E8%90%A9%E5%8E%9F/dp/4627062419

早速インストールだけしてしまおうと思ったのですが、本文にはwinへの導入だけが例示されていたのでmaxosxへの導入については自力でググり続けることに。

#Coqとは

以下のことがなんとなく理解できました。

- Coqと言うのが定理証明支援系の名前らしい
- SSreflect/MathCompと言うので拡張しないといけないらしい。
- どっちもopamと言うバージョン管理システムでいける。
- CoqIDEと言うのがあるからemacs使いじゃなければ使ったらいいお。

#OPAMとは

- brewとかcondaみたいにバージョン管理（OCamlの？)をしてくれる。
- そもそもOCamlがなんなのかよくわかったない。
- 多分brewでopamがインストールできる。

#なぜbrew cask installしなかったのか
そもそも

```
brew cask install coqide
```

で全てがうまくいくはずだった。それなのに、

```p.17
From mathcomp
Require Import ssreflect.
```

が正しく動作しなかった。どうも拡張がうまくいってないらしい。しかしどうあがいても一旦入れてしまったcoqideを後から拡張することができない。そこでopamで全てを済ませることが必要らしいと言う暗礁に乗り上げることになったのである。

#opamへの道
ここで救世主現る。そう、結城氏である。
###Installing CoqIDE 8.7.0 to MacBook(結城浩のブログ)

https://snap.textfile.org/20180421154441/

自分の環境に

```
$ brew install opam
```

した後はこの方のやった事に追随させていただいた。気になるのはopamのversionが2系に私はなっていたことくらいだが、ありがとうございました。今度本買います。

#brewが死んだ
`brew link`をどうにかしろとか言うエラーが頻出するようになった。この辺りでhome brew関連の設定というか理解を怠っていたツケが回ってきた。とりあえず、

```
$ brew doctor
```

というコマンドを知った。これにより、

- いらないファイルが置いてあるから`rm`すべき旨
- 適切な`brew link hoge`がなされていないからちゃんとすべき旨

を承知した。

#coqideが死んだ
`$ opam install coqide.8.7.0`でこけた。盛大に。
エラー文的に、一番近かったのは次の記事だった。

###CoqIDE 8.7.0 incompatible with LablGTK 2.18.6 and OCaml 4.06.0 #6140
https://github.com/coq/coq/issues/6140

`$ opam switch 4.05.0`で進めていたので完全には一致しないが、とにかくバージョンに関する問題が発生していると思われるので、結局、

```
$ opam install coqide.8.7.1
```

でインストール完了した。

#原因は？
もはや正確にはわからないが、opamのバージョンが2だったからいけなかった（結城氏と同じ状況にならなかった）というのが一番怪しい。確かめる気力を失ってしまったのでとりあえず本を読み進めている。

#私は何を分かっていない？
そもそもここまで買いてみて分かったが、私相当時間を無駄にしているけど理路整然と一個一個理解を深めていけばこんなに回り道しないでいけたのでは？　教えて偉い人！

#現状
- coqideを毎回terminalから開いている（なぜ？）
- Modus Ponensとかやったわあ、学部のとき論理学基礎論でやったわあ
- ﾀﾉｼｲ！
Swiftで気軽に.noneを作ってはいけない

既にある `enum` の値を比較したかったのですが、思った挙動にならなくて少しハマったので備忘録として書いておきます。

定義としては

```swift
enum Foo: Int, Codable {
    case none // サーバーで0番で定義されているので必須
    case bar
}
```

みたいな `enum` です。 `bar` 以外にも沢山あるんですが一旦これで大丈夫です。

クラスのプロパティはこんな感じ

```swift
struct Baz: Codable {
    var foo: Foo? // 値自体も `Optional`
}
```

サーバーからJSONとか何かしらのデータを受けとってインスタンス化してBarの値が `.none` かそうじゃないかをハンドリングしたかったので

```swift
let data = ...
let baz = try! JSONDecoder().decode(Baz.self, from: data)
if baz.foo == nil || baz.foo == .none {
    // データが無いよって言う
} else {
    // データがあるよって言う
}
```

としたんですが `baz.foo` の値が `.none` なのに `.none` と判定してくれませんでした。
ここでようやく `Optional` の存在を思い出しました。

**あ...**

と言うわけで

```diff
-if baz.foo == nil || baz.foo == .none {
+if baz.foo == nil || baz.foo == Foo.none {
    // データが無いよって言う
} else {
    // データがあるよって言う
}
```

に変更したら思った挙動になりました。

# まとめ

`Optional` でラップされている値に `.none` で比較してしまうと `Optional.none` として比較されてしまい、思った挙動にならないので安易に `.none` という命名はしない方が良いなという教訓になりました。
esa.ioの記事をまとめてScrapbox形式に変換

# 前置き
esa.ioからScrapboxにできるだけ楽にデータ移行するため、いろいろ試してみました。

とはいっても1記事1ファイルの.txtに変換するところまでです。
Scrapboxのインポート機能はJSON形式のファイルが入れられるけど、そこまで頑張る気力がありませんでした。誰か助けて。

# 流れ
esaの管理画面から記事をzipファイルでエクスポートできる
https://hoge.esa.io/team/admin

解凍してフォルダに入る。中はディレクトリで区切られて、記事がmdファイルになっている

```
$ cd 2019-00-00-hogehoge
```

## MarkdownのファイルをScrapbox形式に変換

MarkdownをScrapboxに変換してくれるパッケージ、md2sbをインストールする
 https://github.com/pastak/scrapbox-converter/tree/master/packages/md2sb

```
$ npm i -g md2sb
```

フォルダの中にファイル変換用シェルスクリプトを書いて置いておく

```shell:henkan.sh
#!/bin/sh
echo $1;
newname="${1}.txt";
cat "${1}" | md2sb > $newname;
```

実行できるようにする

```
$ chmod 744 ./henkan.sh
```

mdファイルをまとめて変換用スクリプトに流し込むワンライナーを実行する

```
$ find . -type f -name "*.md" -print0 | xargs -0 -L 1 ./henkan.sh
```

## ファイル名を1行目に入れる

Scrapboxは1行目がタイトルになるので、ファイルの1行目にタイトルを入れておく必要がある。
Macの場合、sedがGNU版じゃないと使いにくいのでgnu-sedをインストール

```
$ brew install gnu-sed
```

`sed`の代わりに`gsed`でつかえる。

フォルダの中にファイル名をファイルの1行目に追加するスクリプトを入れておく

```shell:namae.sh
#!/bin/sh

echo $1;
title=`basename $1 | gsed "s/\.md\.txt//"`;
gsed -i "1s/^/${title}\n/" ${1};
# Macじゃない人はgsedじゃなくsedでいいはず
```

実行できるようにする

```
$ chmod 744 ./namae.sh
```

同じ要領で流し込むワンライナーを実行する

```
find . -type f -name "*.md.txt" -print0 | xargs -0 -L 1 ./namae.sh
```


# 後処理
テキストファイルを開いてちまちまScrapboxの新規ページに貼り付けます。

`#`で始まる行が`[****** hoge]`みたいになってしまうなど若干直したいところが出てくるので、そこはgrepとかで頑張る。
[mastodon] PgBouncerを導入する


PgBouncerはPostgresqlへのコネクションをプールしてくれるやつですが、負荷軽減のため導入してみました。

公式ガイドだけではハマってしまうポイントがあり苦労したので、そのへんをまとめておこうと思います。
https://docs.joinmastodon.org/administration/scaling-up/#transaction-pooling-with-pgbouncer

なにか認識が間違っていることなどがあれば、教えていただけると助かります。

追記: 本家のガイドが結構いいかんじになっていました。
https://docs.joinmastodon.org/admin/scaling/

### 前提
- ubuntu 18.04
- PostgreSQL 11.1

## ハマったポイント
- admin_usersに設定するユーザの権限に注意が必要
- PostgreSQLの認証方式の変更が必要

## admin_usersに設定するユーザの権限
CREATEDBじゃ全然駄目で、SUPERUSERの権限を与えるとうまくいきました。

ガイドに書いてある通り、`pgbouncer`ユーザを作ってパスワードを設定して、CREATEDBの権限を付与しました。
（まぁAdminって書いてるけどSUPERUSER与えるのはなんか嫌だし、CREATEDBの権限くらいあればいいんじゃないかなって思って）

```:ユーザ作成
CREATE USER pgbouncer WITH CREATEDB PASSWORD 'password'
```

全然だめだったのでSUPERUSERも付与したところうまくいきました。

```:SUPERUSER付与
ALTER ROLE pgbouncer WITH SUPERUSER;
```


## PostgreSQLの認証方式の変更
ガイド通りに進めても*Debugging that it all works*のところで、認証エラーで全くつながらないことがあります。

>**Debugging that it all works**
You should be able to connect to PgBouncer just like you would with Postgres:
`psql -p 6432 -U mastodon mastodon_production`

PostgreSQLの認証方式を見直す必要があります。

### peer→md5へ変更
pg_hba.confを確認するとpeer認証になっていました。

```/etc/postgresql/11/main/pg_hba.conf
# "local" is for Unix domain socket connections only
local   all             all                                     peer
```
この状態ではログインユーザがPostgreSQLのユーザと一致していないと入れないため、使用するユーザの認証方式をmd5にしてやる必要があるみたいです。
（ソケットで通信してるつもりはなかったですけど。。）

mastodonユーザと自分の場合はpgbouncerユーザをadmin_userとしたいのでその2つを追加してみました。

```/etc/postgresql/11/main/pg_hba.conf
# Database administrative login by Unix domain socket
local   all             postgres                                peer
# ↓2つ追加
local   all             mastodon                                md5
local   all             pgbouncer                               md5

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     peer
```

## 導入にあたって注意
PgBouncerを通して`db:migrate`ができないため、アップデートの際は`RAILS_ENV=production DB_PORT=5432 bundle exec rails db:migrate`などと`DB_PORT=5432`を指定して実行するようにしましょう。
ミスったらどうなるんだろう…。
>Gotcha: You cannot use pgBouncer to perform db:migrate tasks. But this is easy to work around. If your postgres and pgbouncer are on the same host, it can be as simple as defining DB_PORT=5432 together with RAILS_ENV=production when calling the task, for example: RAILS_ENV=production DB_PORT=5432 bundle exec rails db:migrate (you can specify DB_HOST too if it’s different, etc)


## まとめ
公式ガイド通りやっているのにうまくいかないときの絶望感。
なんとか導入することができたのでよかったです。

mastodonはメモリ1GBのさくらのVPSで運用しているのですが、最近uptimeが長くなってくるとメモリがカツカツで厳しい。。。
同時にjemallocも導入してみたので効果があれば嬉しいな。

#### 参考
[peer認証の関係でpsqlログインできない時の対処法](https://qiita.com/tomlla/items/9fa2feab1b9bd8749584)
[mastodonへのpgbouncer導入ガイド(非Docker)](https://qiita.com/motiakoron/items/9542f78d5c925c376aab)