OmniAICreator/Qiita-1.07M huggingface dataset:
【TypeScript】Next.jsにNProgressを導入する方法

#NProgressをインストールする
必要なモジュールをインストールします。

```
npm i nprogress @types/nextjs-progressbar
```

#NProgess用のCSSをstaticフォルダに配置

以下から取ってこれます。
https://github.com/rstacruz/nprogress/blob/master/nprogress.css

```CSS:/static/css/nprogress.css
/* Make clicks pass-through */
#nprogress {
  pointer-events: none;
}

#nprogress .bar {
  background: rgb(79, 214, 255);

  position: fixed;
  z-index: 1031;
  top: 0;
  left: 0;

  width: 100%;
  height: 3px;
}

/* Fancy blur effect */
#nprogress .peg {
  display: block;
  position: absolute;
  right: 0px;
  width: 100px;
  height: 100%;
  box-shadow: 0 0 10px rgb(79, 214, 255), 0 0 5px rgb(79, 214, 255);
  opacity: 1;

  -webkit-transform: rotate(3deg) translate(0px, -4px);
  -ms-transform: rotate(3deg) translate(0px, -4px);
  transform: rotate(3deg) translate(0px, -4px);
}

/* Remove these to get rid of the spinner */
#nprogress .spinner {
  display: block;
  position: fixed;
  z-index: 1031;
  top: 15px;
  right: 15px;
}

#nprogress .spinner-icon {
  width: 18px;
  height: 18px;
  box-sizing: border-box;

  border: solid 2px transparent;
  border-top-color: rgb(79, 214, 255);
  border-left-color: rgb(79, 214, 255);
  border-radius: 50%;

  -webkit-animation: nprogress-spinner 400ms linear infinite;
  animation: nprogress-spinner 400ms linear infinite;
}

.nprogress-custom-parent {
  overflow: hidden;
  position: relative;
}

.nprogress-custom-parent #nprogress .spinner,
.nprogress-custom-parent #nprogress .bar {
  position: absolute;
}

@-webkit-keyframes nprogress-spinner {
  0% {
    -webkit-transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
  }
}
@keyframes nprogress-spinner {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

```

#Routerにイベントを追加

CSSを読み込み、Routerにイベントを追加します。
共通Appバーにこの処理を書けば、全ての画面遷移でプログレスバーが表示されます。

```TypeScript:AppBar.tsx

import React from "react";
import Router from "next/router";
import NProgress from "nprogress";
import Head from "next/head";

NProgress.configure({ showSpinner: false });

Router.events.on("routeChangeStart", () => {
  NProgress.start();
});

Router.events.on("routeChangeComplete", () => {
  NProgress.done();
});

Router.events.on("routeChangeError", () => {
  NProgress.done();
});

export default function Bar() {
  return (
    <div>
      <Head>
        <link
          rel="stylesheet"
          type="text/css"
          href="/static/css/nprogress.css"
        />
      </Head>
    </div>
  );
}

```
VivaldiでのChrome拡張機能の設定方法【画像つきで解説 / 動作検証済み】

VivaldiブラウザでのChrome拡張機能（Extensions）の設定方法と、前回ご説明したGoogle Analyticsから自分自身のアクセス数を除外するためのChrome拡張機能`Google Analytics Opt-out Add-on (日本語)Google アナリティクス オプトアウト アドオン`もVivaldi上で動きましたよという報告です。

>【参考】
[Google Analytics利用開始時にやること（自分自身のアクセスの除外）【PC & Androidでの手軽で無難な設定方法】](https://qiita.com/fuku_up/items/2460ff57ad57d2d7b18f)

#VivaldiでのChrome拡張機能の設定方法
知っている人は知っているブラウザVivaldiですが、私も普段メインブラウザとして活用しています。キーボードショットカットが自由度高く設定できたり、Webページの読み込みが早かったりと色々便利なのですが、Chromeの拡張機能も使えます。

Chrome拡張機能の追加記事は、Chromeブラウザでの設定とほぼ同じです。今回は、`Google Analytics Opt-out Add-on (日本語)Google アナリティクス オプトアウト アドオン`を例に上げて、拡張機能の追加方法から、実際にその拡張機能が期待通りに動いているかというところまでまとめています。

#VivaldiブラウザでのChrome拡張機能設定方法
それでは、まず[chrome web store](https://chrome.google.com/webstore/category/extensions)へアクセスして、検索窓から追加したい拡張機能を検索して『追加』を選びます。

![vivaldi_how_to_add_chrome_extension_add.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609490/1d889ccc-b644-c105-19c0-49ea4f09ad89.jpeg)

<img width=100% alt="vivaldi_how_to_add_chrome_extension_check-1024x302.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609490/baee510d-def9-5d8e-4e0f-c0bea66abb82.jpeg">

拡張機能の一覧を確認するために、メニューから「Extensions」を選択する。
<img width=100% alt="vivaldi_how_to_add_chrome_extension_confirm-1024x263 (1).jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609490/588fe327-65eb-b9dc-28cc-1df027ea50ae.jpeg">

画像の通り、`Google Analytics Opt-out Add-on (日本語)Google アナリティクス オプトアウト アドオン`が、一覧の中に組み込まれており且つそれらが有効になっていることが確認できます。このようにブラウザは`Vivaldi`ですが、拡張機能（Extensions）の追加に関してはChromeでの導入とほぼ同じです。

#Chrome拡張機能が期待通り動いているか動作確認
拡張機能「Google Analytics Opt-out Add-on (日本語)Google アナリティクス オプトアウト アドオン」がうまく動作していれば、Google Analyticsのアクセス数から自分自身のアクセスが除外されるようなります。

実際に以下は、別ウィンドウで自身のブログをアクセスしている状態で、Google Analyticsを確認しているときのキャプチャになりますが、しっかりと（~~皮肉にも~~）来訪者は0人になっているので、拡張機能は正常に動作していることがわかります。

![vivaldi_how_to_add_chrome_extension_result.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609490/6d9d0f55-73a2-d9e2-9419-8b1fe2f229e5.jpeg)

---
VivaldiブラウザでChrome拡張機能をどのように導入するか、加えて、`Google Analytics Opt-out Add-on (日本語)Google アナリティクス オプトアウト アドオン`がVivaldiでも正常に動作していることをご説明しました。

Chromeの拡張機能も使えて、その他の自由度も高くWebアクセスも早い(~~更には玄人感をちょっと醸し出せる…~~)Vivaldiは個人的にはとてもおすすめなので、そちらもよかったらぜひ試してみてください。
【RSpec】gem "factory_bot_rails"でNameError:uninitialized constant FactryBot

## 環境
ruby  2.6.3
Rails 5.1.1

```ruby
gem "rspec-rails", '~> 3.6.0'
gem "factory_bot_rails", "~>4.11.0"
```

## 発生した状況

```ruby:spec/factories/users.rb
FactoryBot.define do
  factory :user do
    first_name {"Aaron"}
    Last_name {"Sumner"}
    email {"tester@example.com"}
    password {"password"}
  end
end
```

```ruby:spec/models/user_spec.rb
RSpec.describe User, type: :model do

  it "has a valid factory" do
    expect(FactoryBot.build(:user)).to be_valid
  end

end
```
## 発生したエラー

```zsh
$ bin/rspec
#略
Failures:

  1) User has a valid factory
     Failure/Error: expect(FactryBot.build(:user)).to be_valid

     NameError:
       uninitialized constant FactryBot
     # ./spec/models/user_spec.rb:9:in `block (2 levels) in <top (required)>'
     # -e:1:in `<main>'

Finished in 0.49794 seconds (files took 0.46908 seconds to load)
13 examples, 1 failure

Failed examples:

rspec ./spec/models/user_spec.rb:8 # User has a valid factory
```

## 対処
初めてFactoryBotを使用したので設定が悪いのかな〜？と調べてみて次の記事などを参考にするも解決せず
[RSpecを導入した時、詰まったこと(NameError: uninitialized constant)](FactoryBothttps://qiita.com/blackpeach7/items/fae79ba209499de4bdff)

試しに次のようにコードを変更するとメッセージが変わった

```ruby:spec/models/user_spec.rb
RSpec.describe User do　# type: :model を削除

  it "has a valid factory" do
    expect(FactoryBot.build(:user)).to be_valid
  end

end
```
```zsh
$ bin/rspec
#略
Failures:

  1) User has a valid factory
     Failure/Error: expect(FactoryBot.build(:user)).to be_valid

     NoMethodError:
       undefined method `Last_name=' for #<User:0x00007f9d1c450428>
       Did you mean?  last_name
                      last_name?
                      first_name=
     # ./spec/models/user_spec.rb:9:in `block (2 levels) in <top (required)>'
     # -e:1:in `<main>'

Finished in 0.51206 seconds (files took 0.36496 seconds to load)
13 examples, 1 failure

Failed examples:

rspec ./spec/models/user_spec.rb:8 # User has a valid factory
```

はい！単なるスペルミスです！
最初に疑うべきでしたね...

修正後がこちら

```ruby:spec/factories/users.rb
FactoryBot.define do
  factory :user do
    first_name {"Aaron"}
    last_name {"Sumner"} #Last_nameになっていた
    email {"tester@example.com"}
    password {"password"}
  end
end
```

## 後書き
記事に残すまでも無いような内容ですが検索して1件もヒットしなかったので一応...
あと自分への戒めですね。。

describe で type: :model を削除するとエラーメッセージが変わったのは不思議でしたがまた使えそう？なので覚えておこうと思います。
理由が分かる方がいましたら是非コメントで教えてください！
受託Webサイト制作の時の開発環境

今回の開発環境の備忘録と次点として生かそうと思い投稿しておきます。

# 前提
### 案件
ボリューム：20ページくらい
納期：2週間くらい
備考：レスポンシブ（SP版のデザインはなく良い感じに）

### 業務フロー
コーディング→ローカル確認→テスト環境アップ（WebサーバにFTPソフトで）

### 開発環境（マシン、サーバ）
MacOS
MAMP

### 開発リソース
php
css
js
assets（image, font, etc）

### コンパイル
Macのシェルスクリプトでコピーやsassを走らせて成果物を作る。
具体的には、CPコマンドやインストールしたsassコマンドでsrcディレクトリからdistディレクトリに吐き出していく。watch機能もつけた。

### ディレクトリ構成

```
site/
- dist/
  - index.php(home)
  - _section.php(home)
  - detail/(page)...etc
  - css
    - home.css...etc
  - js
    - home.js...etc
  - common
    - header.php
    - footer.php...etc
- src/
  - assets/
  - js/
    - common/
      - lib/
        - bxSlider.js...etc
    - page/
      - home
  - scss/
    - common/
    - page/
      - home
        - style.scss
        - _section.scss...etc
  - template/
    - common/
    - page/
      - home/
        - index.php
        - _section.php...etc
- compile.sh
- watch.sh
```

# 考察
まずコンパイルについては、
sass以外は、ほとんどコピーなので、コンパイルする必要性がなかった。
わかりやすくするためにcss以外のリソースも一緒にコンパイルしていたが、最初から必要はなかった。そのためコンパイルに余計な時間が取られたと思う。
ただ、個人的には開発リソースと成果物は分けるべきとは思っているので、今回のコンパイルは悪くないと思っている。
実際、jsの圧縮やphpテンプレートに自動でリソースパスを渡すなどの機能もつけやすくなると思っている。
一つ悪いポイントは、納期がパツパツ過ぎたため、余計なこと考える余裕もないし、実装する時間もないため、余計な機能になってしまったことだと思う。
実務ではそこも重要なポイントであるので、設計はほんとむずいと改めて思った。

phpは、受託制作に関しては優秀であると再認識した。
正直特にphpの機能を使いこなした訳ではないが、includeと変数だけで、テンプレートを細分化できるので良い。1ページでだいたい処理が完結する（ページ単位でのスコープで良い）ので十分と思っています。

sassはここで言うまでもなくとても良い。コンパイルで変更したファイルだけを見れるようにできたら良いと思った。なんかありそうな気はしてるが。

jsはほぼプラグイン。圧縮するほどの量もないが、がっつりした案件が来た時改め考えたい。もしできるなら、webpackを使ってcssModulesを使いたいのだが、そもそもWebサイト受託でそこまでやることあるかまだ疑問に思っているので保留。

# 次点
受託制作は、スピード重視かつ壊しやすい設計も必要なので、コンパイルはsassのみで、phpはそのまま編集が良いかなと思いました。
あと、スピード重視のため、cssはflexをめっちゃ多用すべきと思いました。
flexのポリフィルを入れればIE8までは対応できるので、今の時代なら大丈夫な範囲だと思ってます。
あとは、スライダーやスライドショーでbxSlider。

# まとめ
- コンパイルはsassだけで良い
- phpとcssのflexはスピード開発に良い
- bxSliderとflexibility.js

大して参考になるお話ではないと思いますが、アプリ開発とサイト制作の違いがあり、どちらにも効率的なやり方があるのだなーと思ったので、残した記事でした。
Android Status Barのカラーの変更

Windowクラスに各種設定することでカラーの変更だけでなく色々と実現可能となっているようです。
#Status Barの色の変更
```kotlin
window.statusBarColor = ContextCompat.getColor(this, R.color.Black)
```

#Full Screen表示,解除する
Full Screen表示

```kotlin
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
```
Full Screen解除

```kotlin
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
```

#Status Barのアイコンのカラーを変更する
```kotlin
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
```
AWS EC2からFTP アクティブモードでファイル転送する

# 問題になる部分
昨今では使われることもなくなってきたと思われるFTPですが、このFTPは環境によって微妙に使いにくいプロトコルであります。
その原因としてはアクティブとパッシブの2つのモードの存在があります 
違いは以下のページが分かりやすいです。
https://www.infraexpert.com/study/tcpip20.html  

アクティブモードは環境によって使えないケースが多く(特に所謂NAT越えの場合)、AWS EC2インスタンスからインターネット上のFTPサーバーに通信する時もうまくいきません。
パッシブモードで使えればいいのですが、アクティブモードしか受け付けていないサーバーというのもあるので、どんな状態になっているかちょっと調べてみました。

# パケットのキャプチャ
EC2インスタンスにログイン
まずは普通にログインします。

その後、FTPの通信を確認する為にtcpdumpを実行

```
sudo tcpdump -A -p host xxx.xxx.xxx.xxx
```

オプション -A はAsciiで出力。文字列で読めるところは文字列になります。  
-p は自ホストに関連する通信のみ出力。
host でターゲットのIPを指定。
そうするとこんな表示が出てくるところがあります。

```
PORT 192,168,1,1,228,200
```

前半4個の数字がIPアドレス、後ろ2つがポート番号。
ポート番号は最初の数字に256をかけて次の数字と足したものになる。
この場合は
228 * 256 + 200 = 58568 

今回の問題はIPアドレスの方です。

# 送信できない原因
EC2インスタンスに割り当てられたプライベートIPを送っているのですが、AWSがこの辺りをよしなに変換してくれるということはなく、相手側は送られたプライベートIPに接続しようとします。  
その結果、当然接続できないので通信が正常に行えないという事になるのでした。

PORTコマンドのIPを外に出て行くときのグローバルIPに変更すれば接続できそうですが、よく入っているFTPクライアントでは変更ができません。

# 他のコマンドで対応してみる
この状態でFTP転送する場合、コマンドレベルであればlftpというコマンドを使うのが便利です。
インストールはyumで可能です。

```
sudo yum install lftp
```

使い方はこんな感じ

```
# まずは接続先を指定
lftp example.jp
# userコマンドでユーザー指定
user hogehoge
# パスワードを聞かれるので入力
Password:
# パッシブモードをオフにする
set ftp:passive-mode off
# 相手に送るグローバルIPを指定
set ftp:port-ipv4 xx.xx.xx.xx
```

これでアクティブモードで使えました。
From(フォーム)

#From(フォーム)
webページに入力したデータをサーバーサイドプログラムに送信
入力項目のまとまり

```php:記述
<form action="送信先" method="リクエストメソッド">...</from>
```

##リクエストメソッド
GETリクエスト
新しい情報(Webページ等)を取得

POSTリクエスト
フォームに入力した情報を登録

###テキストボックス

```php:記述
<input type="text" name="部品名">
```

###パスワード

```php:記述
<input type="password" name="部品名">
```

###ラジオボタン

```php:記述
<input type="radio" name="部品名" value="値">
```

###送信ボタン

```php:記述
<input type="submit" value="送信">
```

##リクエストパラメータ取得方法
APサーバによってHttpServletRequestインスタンスに格納されて送信先のサーブレットクラスまたはJSPファイルに渡される

###文字コードの指定

```php:記述
request.setCharacterEncoding("送信元HTMLの文字コード");
```

###取得

```php:記述
String xxx = request.getParameter("リクエストパラメータの名前");
```
[WIP]「Kubernetesで実践するクラウドネイティブDevOps」 学習ログ

オライリーの本を読んだので、ツール調査などしつつまとめた。
今後、実践して知見が溜まってきたら更新する。
https://t-akzw.github.io/blog/3a2785c2-7104-5aa5-85b0-0b210653d98c
AWS AppSync用にaws-appsync-codegenでiOS(Swift)のソースコードを生成する

AWS AppSyncでiOS(Swift)用のコードを生成する時に勘違いしていたことがあったので、それについて公式のサンプルから理解できるように細かく書いておきます。私自身がAppSync歴1日なので正確に理解できているかもわかりませんので、その点についてはお手数おかけいたしますがコメントなどでご指摘よろしくお願いします。

また、現状（2020年）ではAppSyncの公式ドキュメントはAmplifyを使うことが前提とされており、Amplifyを使わない場合はやり方を探すのはかなり難しい。難しいので書き残しておきますというモチベーションです。

サンプルはAWS AppSync公式で説明されている[サンプルスキーマ「イベントアプリ」](https://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/quickstart-launch-a-sample-schema.html)からです。

# 最初に結論

おそらくこのページを見ている方が最も知りたいのはコード生成のコメント`aws-appsync-codegen`についての使い方でしょうから最初に書いておきます。

```
# aws-appsync-codegen generate tmp/*.graphql --schema tmp/schema.json --target swift --output tmp/GraphQLAPI.swift
```

- tmp/*.graphql
    - GraphQL リクエスト用のクエリを指定
        - `*`にしているのはリクエストが複数ある場合にそれをtmpディレクトリに置いているためです
        - 後述の「クエリ画面」からコピペしてファイルにします
- tmp/schema.json
    - GraphQLのための仕様
        - 後述の「スキーマ画面」から「スキーマをエクスポート」でschema.jsonを選びます
            - **注意: jsonを選びましょう。schema.graphqlではありません**
- `--target`はswiftを指定
    - 省略できますがこの説明のため丁寧に書いておきます


# 画面での説明

## クエリ画面

![スクリーンショット 2020-03-27 17.45.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16400/64578aa4-dd5d-c371-d215-e948ea685d4d.png)


## スキーマ画面

![スクリーンショット 2020-03-27 16.45.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16400/2bdfc4f4-1d81-81da-fe5e-4c2761862d65.png)

# aws-appsync-codegenの導入

npmをmacにDockerで入れることについて書いておきます。

iOSアプリ開発者的には、仕事でnpmの情報を追っているわけではなくバージョンの違いによる動作の違いを把握していないためシステムにnpm自身を入れたくないですし、なにか環境によるエラーが出た場合に面倒というのが強いです。

おそらくnpmをバージョン別に入れてそれを切り替えて使う方法（nodeenv?nodebrew?）もあるんでしょうが、そこはnpmをそこまで使うわけではないので考えたくないです。


## nodeのimageをダウンロード

```
$ docker pull node
```

## docker runしてコンソールでnpmを利用する

nodeのコンテナを起動し、コンソールに入ります

```
$ docker run -v (pwd)/graphql:/tmp -it --rm node /bin/bash
```

- `-it`
  - インタラクティブにターミナルを起動
- `-v`
    - ローカルとコンテナ内のボリュームを共有し、GraphQL リクエスト用のクエリとschema.jsonをコンテナ内でも使えるようにします
    - (pwd)
        - fishなので(pwd)
        - bashだと$(pwd)かも

## コンテナ内でnpmを使いaws-appsync-codegenをインストール

コンテナ内なのでグローバルにインストールしても良いかな、という感じです

```
# npm install -g aws-appsync-codegen
```

## aws-appsync-codegenでコード生成する

```
# aws-appsync-codegen generate tmp/queries.graphql --schema tmp/schema.json --target swift --output tmp/GraphQLAPI.swift
```

- コード生成した結果も共有のボリュームに出力しています
【XCode】：（警告ログ）UIAlertView is deprecated.

~~~:警告ログ
'UIAlertView' is deprecated: first deprecated in iOS 9.0 - UIAlertView is deprecated. Use UIAlertController with a preferredStyle of UIAlertControllerStyleAlert instead
~~~

お世話になっております。

現在、XCodeのバージョンアップ対応を行なっているのですが、

|項目|バージョン|
|:--|:--|
|Xcode||
|旧バージョン|Xcode10.2|
|↓↓↓↓↓↓↓↓↓|↓↓↓↓↓↓|
|新バージョン|Xcode11.3|
|iOS||
|旧バージョン|iOS12|
|↓↓↓↓↓↓↓↓↓|↓↓↓↓↓↓|
|新バージョン|iOS13|

これの作業がいつしかしないとなって思ってたのでそろそろこの記事の出番です。

そもそもXcode8.0の時からガラリと変更されております。

- [ ]  [UIAlertView と UIActionSheet が deprecated になった](https://dev.classmethod.jp/references/ios8-uialertcontroller/)
- [ ]  [UIAlertView first deprecated IOS 9](https://stackoverflow.com/questions/32690086/uialertview-first-deprecated-ios-9/34151288)
- [ ]  [UIAlertView is deprecated](https://stackoverflow.com/questions/41439783/uialertview-is-deprecated-first-deprecated-in-ios-9-0-uialertview-is-depreca) この記事がそのものですね。

ということで、この上記の記事から UIAlertController に書き換えてね！！
っていう流れなのでしょう。

ただ、UIAlertView → UIAlertController の変更してねというのは、簡単にいうけども
UIAlertViewDelegate とかの対応をどうするねんというツッコミがあるとは思うのでここではそのような変更が起きた時の対応までの過程を頑張って書いていきますのでどうぞよろしくお願いたします。


## 関連記事

【About】(http://qiita.com/sunstripe) - サンストライプ

---

## 制作チーム：サンストライプ

[![sunstripe_logo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80600/322f2d60-f19d-af9e-2b6f-7290ca546848.png)](http://sunstripe.main.jp/)
http://sunstripe.main.jp/

(月１WEBコンテンツをリリースして便利な世の中を作っていくぞ！！ボランティアプログラマー/デザイナー/イラストレーター/その他クリエイター声優募集中！!)

### 地域情報 THEメディア
THE メディア 地域活性化をテーマに様々なリリース情報も含め、記事をお届けしてます！！
https://the.themedia.jp/

### ゼロからはじめる演劇ワークショップ
多様化の時代に向けて他者理解を鍛える

https://workshop.themedia.jp/

### プログラミングワークショップ・ウェブ塾の開講！！！
様々なテーマでプログラミングに囚われずに取り組んでいきます。
詳しくはこちら　↓　↓　↓　↓　↓　↓　↓　↓
[プログラミングサロン 月１だけのプログラミング学習塾](https://workshop.themedia.jp/posts/7057553?fbclid=IwAR32CfRQ7RvDOhvuogoSwqxDLMOU7Jvuzljlnx-TMc27qBPX1BnWsfLcBR8
)

### 協力応援 / 支援者の集い
## チーム：サンストライプ
#### プログラミングラボ
https://twitter.com/sunstripe2011

一緒にポートフォリオを作りませんか？現場の体験やそれぞれの立場から年齢関係なく作品を作りたい方々と一緒にチームを作って、作品を作っています。現場に行きたい人には、職場紹介や職場の体験や悩み相談なども受けております。
様々な職種からプログラミングの知識を得たい、デザインの知識を得たい、データーベースの知識を得たいという人が集まっております。
週１のミーティングにそれぞれの近況と作業報告して、たまにリモート飲み会などをしております！！

興味がある方は、DMに話しかけてみてください。

## トラストヒューマン
http://trusthuman.co.jp/
私たちは何よりも信頼､人と考えてます｡

｢コンサルティング｣と｢クリエイティブ｣の両角度から｢人材戦略パートナー｣としてトータル的にサポートします！！

キャリア教育事業
広域学習支援プラットフォーム『のびのび日和』
https://slc-lab.amebaownd.com/

#スポンサー募集


## ネリム
https://nerim.co.jp/
配信事業などを映像コンテンツなどの制作しております

## ビヨンドXプロジェクト

[ビヨンドXプロジェクト全体会議](https://www.youtube.com/playlist?list=PLaR6-YWiGWkYhEHWnt8f1z-JC0g3nwwC9)
Goの門をくぐってみる(GoとGinのQuickStart)

なんとなく触ってみたいなと前々から思ってたので、チャレンジ。普段はJavaを書いています。なので、型が欲しいという思いでGoに触れてみます。僕はGoについての知識0なので、どこまで簡単に作れるのかもみていきたいです。

いろんな規則や、わからないことがあれば、以下の2つのサイトを探りながら書いていきたいと思います。

- https://golang.org/doc/effective_go.html
- http://go.shibu.jp/effective_go.html

# 事前準備

## homebrew
[この](https://brew.sh/)サイトからinstallできます

## go
コマンド打つだけ、簡単

```
brew install go
```

versionは1.14

```.sh
ri2kku~:$: 
->> go version
go version go1.14 darwin/amd64
```

# 何がともあれGoのQuickStart
Go公式のQuickStartを参考に世界に挨拶してみます
https://golang.org/

ファイル作成 -> コード書く -> 動かす、まで一気に

```.sh
ri2kku~/sandbox/go/go-sample:$: 
->> vi hello_world.go
```
```hello_world.go
package main

import "fmt"

func main() {
  fmt.Println("Hello, World")
}
```
```
ri2kku~/sandbox/go/go-sample:$: 
->> go run hello_world.go 
Hello, World
```

### 雑感
10分ほどで世界に挨拶できました！こんなに簡単なら早く触っておけばよかったです。シンタックス等はJavaと結構違っているのかな？セミコロンがないことにすごく違和感を感じていました。

# Gin
次はFWを使って簡単なアプリを作成してみます
一番使われてそうなFWを選びました
https://github.com/gin-gonic/gin

## インストール

Goのversionは**1.1**以降が必要らしいです

```
go get -u github.com/gin-gonic/gin
```

## GinのQuickStart

書いて動かすところまで

```exmaple.go
package main

import "github.com/gin-gonic/gin"

func main() {
  r := gin.Default()
  r.GET("/ping", func(c *gin.Context) {
    c.JSON(200, gin.H{"message": "pong",})
  })
  r.Run()
}
```

localhost:8080でlistenしてる

```
ri2kku~/sandbox/go/gin-sample:$: 
->> go run example.go
GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:	export GIN_MODE=release
 - using code:	gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /ping                     --> main.main.func1 (3 handlers)
[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on localhost:8080
```

`http://localhost:8080/ping`にアクセスすると、`pong`が返ってくるようになっているのを確認できました

```
ri2kku~/sandbox/go/gin-sample:$: 
->> curl http://localhost:8080/ping
{"message":"pong"}
```

### 雑感
すごく簡単に作れる模様？インストールがすごく楽ですぐに何かを試したい！という時にはさらっとかけそうな印象を持ちました、この時点では。まだ海面に触れたようなものなので、次はもう少し深く潜って簡単なWebアプリを作成したいと思います。
Sign in With AppleのHIG(Data Management)から見るAppleのサインインの取り組み

# はじめに
Sign in With Appleを実装するにあたり、レビューガイドラインを一読されている方は多いと思いますが、HIGのData Managementに言及されている方はあまりいらっしゃらないのかなと感じました。
ここでは、そのData Managementを読むことでAppleのサインインに関する考え方が読み取れると感じ、実装する際の参考にしてもらえばと思います。

# 結論
この文章を読めば全て解決します。
https://developer.apple.com/design/human-interface-guidelines/sign-in-with-apple/overview/data-management/

# 要約した内容が欲しい人向け
Sign in with Appleをプライバシーと利便性のために使う

## できるだけ早くサインインを終わらせ、人々を新しいアカウントに歓迎する
ユーザーに新しいアカウントをすぐに登録できるようにする - 不要な情報を問い合わせて、ユーザーエクスペリエンスを遅らせないようにしましょう

## その情報は必須なのか登録した方が良いのか、明確にしよう
データが法律上や契約上必要なのであれば、その情報が必要であることをユーザーが理解しているか、確認するようにしてください。
データが必須でないけど、ユーザーエクスペリエンスが向上するのであれば、情報が必須でないことをユーザーに伝え、その情報があることでユーザーにどんな利点があるのかを伝えるようにしましょう。

## パスワードの入力を求めない
Sign in with Appleを使う主な利点は、サービスごとのパスワードを入力する必要がないことです。Sign in with Appleが使えないようになっていない限り、パスワードの入力を求めないでください。

## ユーザーがプライベートメールアドレスを使う場合、ユーザーのメールアドレスを問い合わせない
Sign in with Appleを使うと、ユーザーはプライベートメールアドレスを使ってメールを受信することができます。ユーザーがパーソナルメールアドレスを使いたくないという選択を尊重してください。メールアドレスを一意なIDとして利用している場合、以下の方法を使うことができます（本文省略）

## オプショナルなデータを求める前に、ユーザーがアプリを使用できる機会を提供しましょう
ユーザーがアプリを使うことで、ユーザーがより多くの情報を共有してくれ、ユーザーが私たちの手助けをしてくれます。ユーザーがオプショナルなデータを提供しないことを選んだときに、アカウントを制限したりアプリの全ての機能を使えなくすることはしないでください。

# 最後に
GAFAの中でも個人情報の収集に否定的なAppleらしい、とにかくユーザーのことを考えた（？）ガイドラインになっていますね。
集める必要がないからこそユーザー目線のガイドラインを打ち出せるのかもしれません。
ここで翻訳した内容は、私見も多く入っているため内容の保証はできません。間違っているものに関しては指摘していただけると幸いです。
この記事に限らず、できる限り一次ソースを見にいく方が良いと思います。
NXP SE050検証(証明書プロビジョニング)(NXP SE050 certificate provisioning)

#はじめに#
2019/12/14に開かれた　IoTSecJPにてお時間をいただき
[セキュアエレメントとIoTデバイスセキュリティ](https://www.slideshare.net/KentaroMitsuyasu1/secure-element-for-iot-device)
と題してお話させていただきました。
その内容をベースにまとめていきたいと思います。

#証明書の書き込み#
SE050を使ってWEBサーバーへつなぐテストを行いたいが、SE050で生成したパブリックキーへ署名して、証明書を作成し、書き戻してTLSセッションで利用できるようにしなくてはならない。

前回、[NXP SE050検証(証明書読み出し)(NXP SE050 cerificate extraction by using ESP32)]( https://qiita.com/kmitsu76/items/91829a15025ee2afa925)でプリセットされていた証明書を読み込んだが、今回は同様に証明書を作成し書き戻してみる。

ユーザーが使えるObjectIDはex_sss_objid.hに定義されている。

```
#define EX_SSS_OBJID_CUST_START             0x00000001u
#define EX_SSS_OBJID_CUST_END               0x7BFFFFFFu
```

この範囲で、下記のように定義してみた。

```
#define OBJID_usr_key (EX_SSS_OBJID_CUST_START + 0x10000002u)
#define OBJID_usr_cert (EX_SSS_OBJID_CUST_START + 0x10000003u)
#define OBJID_signer_cert (EX_SSS_OBJID_CUST_START + 0x10000004u)
#define OBJID_root_cert (EX_SSS_OBJID_CUST_START + 0x10000005u)
```

OBJID_usr_keyはPrime256v1のキーペア
OBJID_usr_certは上記の公開鍵を署名してできた証明書
OBJID_signer_cert、OBJID_root_certはそれぞれ中間証明書、ルート証明書となり、すべての証明書チェーンをSE050内に収めてみる。

Linuxだとssscliというものがあるが、これらをシリアル通信で設定できるcliツールを作ってみた。
ソースは[NXP-SE050-provisioning-cli]( https://github.com/kmwebnet/NXP-SE050-provisioning-cli)

#cliツール概要#

最低必要なのは、デバイスから公開鍵を取り出すコマンドと、証明書を書き戻すコマンド。
DERエンコードのバイナリはシリアル通信で送れないのでPEMに直してやり取りする。

Rでレディ状態確認。通信できるかの確認に使う
qでアプリケーション終了。
sでシリアル番号をbase64で出力。コモンネームに使ったりできるユニークな番号
kでパブリックキーをpemで出力
rでルートCA証明書の受領モード(pem)
cでSigner CA証明書の受領モード(pem)
vでデバイス証明書の受領モード(pem)

Windows10のTeraTermで動作確認ができた。

```
I (338) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
       App:INFO :PlugAndTrust_v02.12.04_20200228
       App:INFO :If you want to over-ride the selection, use ENV=EX_SSS_BOOT_SSS_PORT or pass in command line arguments.
       sss:INFO :atr (Len=35)
      00 A0 00 00    03 96 04 03    E8 00 FE 02    0B 03 E8 08
      01 00 00 00    00 64 00 00    0A 4A 43 4F    50 34 20 41
      54 50 4F
I (805) uart: queue free spaces: 10
Ready.
BABQAV5rfvqyOR0EfpAKlGaAReady.
Ready.
-----BEGIN PUBLIC KEY-----
MFkwEwYH….
……………….HyTtI43wIldXw==
-----END PUBLIC KEY-----
```

抜き出したパブリックキーに署名し、各証明書の書き込みモードにし、pemの文字列をTeraTermで「貼り付け」を行うと書き込まれる。
これを使ってテストWEBサーバーへ接続テストを行ってみる。
Gemfileの中身を見てみる

# Gemfileの初期状態
```ruby:Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.5.1'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.2.4', '>= 5.2.4.2'
# Use mysql as the database for Active Record
gem 'mysql2', '>= 0.4.4', '< 0.6.0'
# Use Puma as the app server
gem 'puma', '~> 3.11'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'mini_racer', platforms: :ruby

# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.2'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.5'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use ActiveStorage variant
# gem 'mini_magick', '~> 4.8'

# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.1.0', require: false

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '>= 3.0.5', '< 3.2'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
  # Easy installation and use of chromedriver to run system tests with Chrome
  gem 'chromedriver-helper'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
```

# 変更

```
gem 'slim-rails'
gem 'simple_form'
```
flutter 初心者

そもそも
https://flutter.dev/docs/development/

ディレクトリ構成
---
lib 
 └　mai.dat　はじめに表示させる画面

pubspec.yaml パッケージ管理システム　バージョン記載



---

#Dart
##変数定義
static/final/const

接頭語　|　説明　|　使用例
---|---|---
final|プログラム開始後のある時点で一回だけ初期化され、初期化以降は、代入などを通じて変更されない　|int i = 0;
const |コンパイル時に確定している値であることを示すための指定　|  const int i = 0;
static| モジュールローカル　は無い！　[int _num][class _SomeClass] 　のように　先頭にアンダースコアをつけて見れなくすることができる|　final int _Pｖ = 0;

>https://qiita.com/uehaj/items/7c07f019e05a743d1022


画像

>https://qiita.com/yu124choco/items/a2710ec004d3425a2a0b


body 
https://qiita.com/coka__01/items/dedb569f6357f1b503fd
特定のEC2インスタンスを起動停止するだけのアカウントをもっと簡単に作成する

[AWSで特定のEC2インスタンスの起動停止だけ出来るIAMアカウントを作成する](https://qiita.com/Hotspring_r/items/8b4c228e93d211c1f689) で特定のEC2インスタンスだけ起動停止できるアカウントの作り方をご紹介しましたが、アカウント作成までの手順をCloudFromationで自動化しました。

https://ap-northeast-1.console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stacks/create/review?templateURL=https://s3-ap-northeast-1.amazonaws.com/static.bmscr.com/qiita/ec2boot.template&stackName=EC2Boot
を開くと CloudFormation のテンプレートが既にセットされた状態でスタックの作成画面が表示されます。
ログインパスワードを入力しIAMリソースが作成されることの同意のチェックを入れ、スタックの作成をクリックするだけでポリシーとユーザが作成できます。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153956/6968a839-faab-c660-6caf-e64d61dff6b3.png)
|:-:|

<font color="Red">注：テンプレートは https://s3-ap-northeast-1.amazonaws.com/static.bmscr.com/qiita/ec2boot.template で確認することが出来ます。
改竄等されないように万全を期しますが改竄の無いことを保証は出来ません。
万一このページや上記テンプレートが改竄され悪意のあるCloudFormationテンプレートを適用してしまった場合アカウントが乗っ取られる等の恐れがありますが私は一切責任を負いません。</font>

`EC2Boot`の名前でユーザーが作成されます。
ユーザー作成以降のEC2インスタンスの設定、アカウントID確認、ログイン後の操作等は [AWSで特定のEC2インスタンスの起動停止だけ出来るIAMアカウントを作成する](https://qiita.com/Hotspring_r/items/8b4c228e93d211c1f689) を参考に設定を行ってください。

CloudFormationのスタックにEC2Bootというスタックが作成されるのでこれを削除すると作成されたポリシーとユーザーも削除されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153956/f0891722-583e-08ef-06dc-1ef7b0774c58.png)
Googleカレンダーの祝日に色をつける方法（PC用）

## Chromeの拡張機能を入れる
[G-calize - Chrome ウェブストア](https://chrome.google.com/webstore/detail/g-calize/piiljfhidimfponnkjlkecnpjhdijfde?hl=ja)

## G-calizeの設定
1. `祝日の設定` -> 祝日のカレンダーを選択 -> カレンダーIDから `japanese__ja@holiday.calendar.google.com` -> 選択（インポートされる）
2. 祝日の色 -> `色を有効` をONにする
3. 保存

![スクリーンショット 2020-03-27 17.30.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69067/730ecc9a-bdc4-d16b-756f-8dd06d96af4c.png)


## Googleカレンダーを開く
既に開いている場合はリロードすると色がついている
![スクリーンショット 2020-03-27 17.30.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69067/fd9aa32e-a268-f738-7401-435a634112f9.png)
APNGKitを利用してiOSでAPNGアニメーションを実装する。


こんにちはrenです。
皆様はAPNGというファイル形式をご存知でしょうか？

APNGとはアニメーションするPNG画像のことで、GIFに取って代わる新しい画像形式です！

# 対象読者

iOSアプリ開発者

# APNGを利用するメリット
GIFよりも表現の幅が広い

### GIF
 - 256 色まで
 - アルファチャンネルなし（完全な透明か完全な不透明かのいずれかのみ）

### APNG
 - フルカラー
 - アルファチャンネルあり(半透明が使える)

# 使い方
APNGKitというライブラリを利用すると簡単に導入できます！
https://github.com/onevcat/APNGKit

### 1. APNGKitをインストール
CocoaPods、Carthage、Swift Package Manager などを利用し、ライブラリをインストールします。
今回はSwift Package Managerを利用します。

`File` -> `Swift Package` -> `Add Package Dependency...`
<img width="562" alt="スクリーンショット 2020-03-26 20.00.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234348/27e28317-f009-496b-2919-c0c48bcc4164.png">

`APNGKit` で検索
<img width="720" alt="スクリーンショット 2020-03-26 19.31.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234348/34165267-be77-0e68-1719-fd718d5d5317.png">

`Version`は適当に設定
<img width="720" alt="スクリーンショット 2020-03-26 19.31.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234348/f773c23d-0583-e9c0-be74-b5c3f76a62f6.png">

`APNGKit` にチェックを入れる
<img width="720" alt="スクリーンショット 2020-03-26 19.32.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234348/90b78318-8765-b3e0-2352-db18bfce15bd.png">

こんな感じになっていればOK
<img width="1113" alt="スクリーンショット 2020-03-26 19.32.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234348/080cd99a-0ebe-bcad-c00a-00f2a476366c.png">


### 2. APNGのファイルをプロジェクトに追加
<img width="271" alt="スクリーンショット 2020-03-26 20.11.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234348/56dc0f03-f821-d46b-c58f-ccc2b1954f0f.png">


### 3. StorybordにImageViewを作成
<img width="265" alt="スクリーンショット 2020-03-26 19.37.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234348/d0b9000e-3063-fa59-33d3-aa611da6a8fb.png">


### 4. `ImageView`をカスタムクラス`APNGImageView`に置き換える
<img width="260" alt="スクリーンショット 2020-03-26 19.37.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234348/286502c0-d3da-0663-e154-18beaee4aa55.png">


### 5. ViewControllerを下記のように変更

```swift

import UIKit

import APNGKit

class ViewController: UIViewController {

    // APNGを表示するためのImageView
    @IBOutlet private weak var imageView: APNGImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
        setupImageView()
    }

    private func setupImageView() {
        // APNGファイルのパスを取得
        guard let path = Bundle.main.path(forResource: "elephant", ofType: "apng") else { return }
        
        // APNGのファイルを取得
        let image = APNGImage(contentsOfFile: path)
        
        // imageViewにAPNGを代入
        imageView.image = image
        
        // アニメーションの実行
        imageView.startAnimating()
        
    }

}

```

### 6. Run！
アニメーションの動画を貼りたかったけど、色々面倒だったので省略

## サンプルプロジェクト
https://github.com/renchild8/APNGKitSample
Mediawikiをv1.31.6からv1.31.7に更新した時のメモ

# はじめに

以前にMediawiki 1.31.0にメジャーアップグレードする時の手順を掲載していたので、今回はマイナーアップデートを行なった時のメモを残しておきます。

* https://qiita.com/YasuhiroABE/items/407833197966ef84b875

このメモ自体は別途環境で管理しているものを転載しているので、一部サーバー名などは変更しています。

Mediawikiは古いものから更新する時には、MySQLのスキーマも含めて対応する必要があるので、LTS版を利用しながら小まめに更新することをお勧めします。

# 環境

* HW: PC Engines APU (Mem: 4GB, Disk: 256GB)
* OS: Ubuntu 18.04.4 amd64版
* Web Server: nginx (from deb package)

# 手順

以下は別途mediawikiで管理している手順書のコピー（一部改変済み）です。

## 1.31.7へのマイナーアップグレードについて
※ 1.31.6への手順をコピーし、1.31.5→1.31.6, 1.31.6→1.31.7へ書き換えて確認する。

1.31.7のリリースノートで更新手順に変更がないかも念のため確認する。

## 準備作業

あらかじめ example.com 上の安全なディレクトリで、mediawiki 1.31.7 の tarball を展開し、/var/www/html/mediawiki/ ディレクトリとの差分を確認する。

```bash
  $ mkdir ~/mediawiki-1.31.7
  $ cd ~/mediawiki-1.31.7
  $ wget https://releases.wikimedia.org/mediawiki/1.31/mediawiki-1.31.7.tar.gz
  $ tar xvzf mediawiki-1.31.7.tar.gz
  $ ln -s /var/www/html/mediawiki .
  $ ls mediawiki/extensions/|wc -l
   26
  $ ls mediawiki-1.31.7/extensions/|wc -l
   23
  $ rsync -nrvc --delete mediawiki-1.31.7/. mediawiki/. | grep deleting
  deleting LocalSettings.php
  deleting extensions/MultiUpload/...
  deleting extensions/LdapAuthentication/...
  deleting extensions/GraphViz/
  deleting images/...
  ## 後ほどextensions以下の3ディレクトリとimagesディレクトリ全体をmediawiki-1.31.7以下にコピーする
  $ rm mediawiki
```

この結果から、3つのextensionsとimagesだけが不足していることが分かる。 
※ 常にextensionsは最新である事を確認すること。

## 現在使用しているextensionsの最新版の確認
公式のMediawiki extensions Downloadページを確認し、 現時点で使用している上記3つのextensionsのバージョンを確認し、最新であれば、現行のディレクトリをそのままコピーして使用する。

Security Fixが出ない限りは、1.31.xでは以下のバージョンが提供されているはずなので、これを確認する。

* GraphViz-REL1_31-9abad17.tar.gz
* LdapAuthentication-REL1_31-b19888c.tar.gz
* MultiUpload-REL1_31-0a2cae4.tar.gz

## example.com 上での作業手順
サービスを停止しても問題はないので、完全にnginxとDBを停止して、計5つのディレクトリ、ファイルをコピーする手順を考える。

## 更新手順

```bash
 $ sudo /etc/init.d/apache2 stop
 $ sudo /etc/init.d/mysql stop
 $ cd /var/www/html/
 ## バックアップの作成
 $ sudo mv mediawiki mediawiki-1.31.6
 $ ls -l   ## mediawikiディレクトリがない事を確認する
 ## 新しいmediawiki tarballの展開
 $ sudo tar xvzf ~/mediawiki-1.31.7/mediawiki-1.31.7.tar.gz
 $ sudo mv mediawiki-1.31.7 mediawiki
 $ cd mediawiki
 ## 必要なファイルのコピー
 $ sudo rsync -av ../mediawiki-1.31.6/images/. images/.
 $ sudo rsync -av ../mediawiki-1.31.6/extensions/MultiUpload extensions/.
 $ sudo rsync -av ../mediawiki-1.31.6/extensions/LdapAuthentication extensions/.
 $ sudo rsync -av ../mediawiki-1.31.6/extensions/GraphViz extensions/.
 $ sudo cp -ip ../mediawiki-1.31.6/LocalSettings.php .
 ## ファイル&ディレクトリパーミッションの変更
 $ sudo chmod -R a+rX,g-w,o-w ./
 $ sudo chown -R www-data:www-data ./
 $ sudo chmod 600 LocalSettings.php
 ## 作業完了後に、サービスを起動する
 $ sudo /etc/init.d/mysql start
 $ sudo /etc/init.d/apache2 start
```

##確認

https://example.com/mediawiki/ にアクセスし、ログインできること、編集作業ができる事などを確認する。

ここまで転載分
chromeで401レスポンスが返ってきたときの不具合

# 背景

https://www.nnn.ed.nico/questions/14833
n予備校の教材の通りに実装を進めていたところ、このリンクと同じ状況に遭遇


# 問題

chromeに限り、以下のコードで表示されるはずの"ログアウトしました"という文とリンクが表示されない。


```javascript
 function handleLogout(req, res) {
   res.writeHead(401, {
    'Content-Type': 'text/html; charset=utf-8'
   });

   res.end('<!DOCTYPE html><html lang="ja"><body>' +
     '<h1>ログアウトしました</h1>' +
     '<a href="/posts">ログイン</a>' +
     '</body></html>'
   );
 }
```

# 原因
chromeのバグ
https://bugs.chromium.org/p/chromium/issues/detail?id=992639

# 解決

- とりあえず別のステータスコードを変える

```javascript

function handleLogout(req, res) {
  console.log('handleLogout');
  res.writeHead(400, {
    'Content-Type': 'text/html; charset=utf-8'
  });
  res.end('<!DOCTYPE html>'+
   '<html lang="ja"><body>' +
    '<h1>ログアウトしました</h1>' +
    '<a href="/posts">ログイン</a>' +
    '</body></html>');
}
```


- (ブラウザを変える)


### 追記
教材にこのエラーについての解決方法が追記されていた。
解決方法は、ステータスコードを302に書き換えること。

https://developer.mozilla.org/ja/docs/Web/HTTP/Status
より、
>302 Found
このレスポンスコードは、リクエストされたリソースの URI が一時的に変更されたことを示します。
SQLite3を簡単に使ってみる

SQLiteは，小規模なデータベースをサクっと作りたいときに使われるデータベースマネジメントシステム（DBMS）のひとつです．

# データベースとは

データを登録したり，削除したり，検索したりするシステムのこと．

参照：[データベースのきほん](https://qiita.com/tantan1009/items/0d8e89800428961bd45d)
[いまさら聞けないデータベースとは？](https://www.sejuku.net/blog/8763)

# データベースの種類

- MySQL
- PostgreSQL
- SQLite
- Oracle DB

などがあります．（参照：[MySQL、PostgreSQL、SQLite、Oracle DBの比較](https://algorithm.joho.info/programming/sql-db/mysql-postgresql-sqlite-oracle-db/)）

中でも，[SQLite3](https://docs.python.jp/3/library/sqlite3.html)はPythonの標準ライブラリに既に入っていて，機能が少なく，手軽に使えます．

# SQLite3の使い方

pythonとは別に，SQLを書く必要があります．

```python
#インポート
import sqlite3

#データベースに接続
filepath = "test2.sqlite"
conn = sqlite3.connect(filepath) 
#filepathと同名のファイルがなければ，ファイルが作成されます

#テーブルを作成
cur = conn.cursor()
cur.execute("DROP TABLE IF EXISTS items")

cur.execute("""CREATE TABLE items(
    item_id INTEGER PRIMARY KEY,
    name TEXT UNIQUE,
    price INTEGER
)""")
conn.commit()

#単発でデータを挿入
cur.execute('INSERT INTO items (name , price) VALUES (?,?)',("Orange", 520))
conn.commit()

#連続でデータを挿入
cur = conn.cursor()
data = [("Mango",770),("Kiwi", 400), ("Grape",800),("Peach",940),("Persimmon",700), ("Banana",400)]
cur.executemany(
    "INSERT INTO items (name, price) VALUES (?,?)", data)
conn.commit()
```

以上でデータベースの構築と，データの登録ができました．`conn.commit()`を実行しないと，データベースにコマンドが反映されないことに注意．

全データを表示してみます．

```python
#全データを抽出する
cur = conn.cursor()
cur.execute("SELECT item_id, name, price FROM items")
items_list = cur.fetchall()
items_list
```

```output
[(1, 'Orange', 520),
 (2, 'Mango', 770),
 (3, 'Kiwi', 400),
 (4, 'Grape', 800),
 (5, 'Peach', 940),
 (6, 'Persimmon', 700),
 (7, 'Banana', 400)]
```

for文で１つずつ表示してみます．

```python
#全データを抽出する（for文使用）
cur = conn.cursor()
cur.execute("SELECT item_id, name, price FROM items")
items_list = cur.fetchall()
for fr in items_list:
    print(fr)
```

```output
(1, 'Orange', 520)
(2, 'Mango', 770)
(3, 'Kiwi', 400)
(4, 'Grape', 800)
(5, 'Peach', 940)
(6, 'Persimmon', 700)
(7, 'Banana', 400)
```

検索をかけてみます．

```python
#400-700円のデータを抽出して表示
cur = conn.cursor()
price_range = (400, 700)
cur.execute(
    "SELECT * FROM items WHERE price >=? AND PRICE <=?", price_range
)
fr_list = cur.fetchall()
for fr in fr_list:
    print(fr)
```

```output
(1, 'Orange', 520)
(3, 'Kiwi', 400)
(6, 'Persimmon', 700)
(7, 'Banana', 400)
```

以上
Nuxt.jsを始める時の行動2

脳死で`Nuxt.js`始めるメモ。
新しめの`Node.js`がインストールされてるMacが前提。
`Node.js`はググれば出てくるので今回は、省略します。

```shell
$ npx create-nuxt-app nuxt-sample

create-nuxt-app v2.15.0
✨  Generating Nuxt.js project in nuxt-sample
```
何か聞かれてるので、適当に返答していく。

```
? Project name 
  nuxt-sample
? Project description
  My first-class Nuxt.js project
? Author name 
  DaisukeNishi
? Choose programming language 
  JavaScript
? Choose the package manager 
  Yarn
? Choose UI framework 
  Element
? Choose custom server framework 
  Express
? Choose Nuxt.js modules
  Axios
? Choose linting tools 
  ESLint
? Choose test framework
  None
? Choose rendering mode 
  Universal (SSR)
? Choose development tools 
  None
```
全部をインストールする時間は、1分くらいです。

```shell
$ cd nuxt-sample
$ yarn dev
```
localhostを立ち上げてると、そのターミナルは入力できなくなるので、
ターミナルを別タブにしておく。(cmd+T)

```shell
$ open http://localhost:3000
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216132/82dc8fda-f7f8-1480-9258-8dd2b0032b72.png)

一旦ブラウザは閉じる。
devサーバーの止め方はターミナルで`cmd+C`です。

VScodeで「nuxt-sample」フォルダを開く。

まずは文字が真っ白になってないか？みる。
文字が真っ白の場合はvueファイルのシンタックスハイライトをするプラグインを
入れる。プラグインでvueで検索すると說明に「Syntax highlight」って書いてあるやつが出てくるから
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216132/48b692e3-7f53-c3ff-0857-616a569975da.png)

なるべくターミナルを使わないで開発した方が
みんなに「黒い画面」のトラウマを植え付けないので、
`vue-cli-ui`を使っていく。`vue-cli`もググれば出てくるから省略します。

```
$ vue ui
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216132/521f0b30-f5b7-ee97-48f6-32517d17d9dd.png)

正確には「vueプロジェクト」ではないと思いますが、インポートして開いてみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216132/06821769-9716-145d-5510-0b040bc9f594.png)

ソースツリーでローカルリポジトリを作成する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216132/db509fc6-b7a5-517e-cef2-cf6a8518eea5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216132/b7ad9284-62ae-0613-2c56-c6d6e2022972.png)

bitbucketにリモートリポジトリを作る。もちろんGithubでいいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216132/5ee4889e-2b5b-b8bc-92ce-a4d545cc49f7.png)

.gitignoreを開いて、「.history」とかかく。
ん〜nuxt.jsは、最初からコミット不要なものは書いてあるので
特に気にする必要もないみたい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216132/0211207f-5a44-06f8-1648-80effd1f7b8c.png)

コミットしてプッシュする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216132/5d5e955e-5b7e-f0a7-9936-3a62e70dfff0.png)

リモートを見てみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216132/dcefb347-5ed4-1f62-635e-c35d6791806b.png)

bitbucketに上がってる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216132/04bd6ecf-a006-aff2-179b-c6cb17c14421.png)

ローカルにdevサーバーもある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216132/028c27ef-1818-3b4e-bcc6-4045717410b3.png)

開発するのめっちゃ楽だし、困る事ほぼない。
ソースコードも確認してもらうとわかりますが、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216132/273eb8fc-7d80-4613-3f5f-5f9ef710d34d.png)

`Nuxt.js`快適すぎて鼻水出るレベル。。
CloudTrailで操作ログを設定する

今回はCloudTrailを使って操作ログを設定する。CloudTrailは無料だけど、ログが記録されるS3は少し料金が発生するのでお金をかけたくない場合は無視でOK。

#操作ログの設定
マネジメントコンソールでCloudTrailを検索。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/31e40db1-590f-cedc-727b-2ae2df5606ed.png)
「証跡の作成」を選択。最近のイベントでログを確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/0fc9a9be-f9ed-6007-f97a-d52fb49156ab.png)
認証名を設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/d6f74f77-f7cb-1b94-85c6-19cb057c9d48.png)
下までスクロールして、S3バケットを設定。ログファイルを入れるフォルダみたいなもの。グローバルで一意な名前にしなければならない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/ffcb2c8e-ff21-ae3a-a3e6-fd1eb8a4115a.png)
一番右下の「作成」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/45eeba2d-7e98-10e2-70c8-bb6a0b971cf6.png)
作成完了！！赤枠を選択すると実際のログフォルダに移動する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/740f67c8-7f18-a530-ab6a-c662d06bbd0b.png)
Render PropsとHooksで処理中を管理する

# Render PropsとHooksでローディング処理を管理する

ローディングや処理中を管理する方法として `useState` を使うことは多いと思います。
しかし複数のフォームやコンポーネントが処理中である・・・等管理したい場合に `useState` だけではの管理では気持ち悪かったので、それの対策っぽい記事を書きます


### こんなかんじ

```tsx:LoadingProvider.tsx

import React, {useState, FC, ReactElement} from 'react';

type RenderProps = {
  loading: boolean
  setLoading: (bool: boolean) => void
}

type Props = {
  initialValue?: RenderProps['loading']
  children: (props: RenderProps) => ReactElement
}

export const LoadingProvider: FC<Props> = ({children, initialValue = false}) => {
  const [loading, setLoading] = useState(initialValue);

  return children({loading, setLoading})
};

```

```tsx:ProductPage.tsx

export const ProductPage: FC<> = ({ products actions }) => {
 return (
    {products.map(product => (
       <LoadingProvider>
        {({loading, setLoading}) => {
            <Product
              product={product}
              addToCart={async () => {
                setLoading(true)
                actions.addToCart(product.id)
                setLoading(false)
              }
                // 処理中のprops
                processing={loading}
             />
          }}
         </LoadingProvider>
    ))}
 )
} 
```

以上！
これなら複数のComponetが処理中でも脳死で使えるきがする。

最初はContextAPIを使おうと思ったが、今回のケースだとこれくらいの実装が最適かなと。
LoadinProviderで `loading === true` だったら、Loadingのグルグルを表示させるComponentに差し替える。みたいなのを実装するのもよさそう。

むやみにRenderPropsを使うのは微妙そうだけど、こういうケースでは有用だなーとおもいました。 まる。
CDKを使ってAPI Gatewayに任意のドメインを設定する

# 概要
API Gatewayの作成、カスタムドメインの設定、ホストゾーンにエイリアスレコードを追加するところまでCDKで設定します。

# 前提
CDKをある程度触ったことがあるのを前提とした記事です。

## 用意しておくもの
- ホストゾーン
    - ホストゾーンID
    - ドメイン名
- SSL証明書
    - ARN

## 環境
- Typescript 6.13.7
- CDK 1.3.0
    - @aws-cdk/core
    - @aws-cdk/aws-apigateway
    - @aws-cdk/aws-certificatemanager
    - @aws-cdk/aws-route53
    - @aws-cdk/aws-route53-targets

# CDKを書いていく
今回はサンプルとして `api.example.com` にGETリクエストを送ると500エラーが返ってくる環境を作ります。
以降のコードはCDKの `lib/cdk-stack.ts` のconstructor()内に記述していきます。
最低限の設定を行なうため、必要に合わせてパラメータを追加・変更してください。
[サンプルコード](https://github.com/ishizakit/sample-cdk-custom-domain-api)

## RestAPIの作成とカスタムドメインの設定

### RestAPIを作成
CDKではデフォルトで、prodというステージが作成され、デプロイされます。
別のステージや自動デプロイさせたくない場合は第三引数にパラメータを追加しましょう。

```ts:cdk-stack.ts
const restAPI = new apigateway.RestApi(
  this,
  'APIGateway',
  {
    restApiName: 'Example',
    endpointTypes: [apigateway.EndpointType.REGIONAL],
  },
);
```

### リソースを作成
正しく設定できたか確認するために、Mockのリソースを作成しておきます。
デプロイする時にリソースが一つ以上ないとエラーになるため、リソースは忘れずに作成しましょう。

```ts:cdk-stack.ts
restAPI.root
      .resourceForPath('')
      .addMethod('GET');
```

### SSL証明書を取得
事前に用意しておいたSSL証明書を取得します。
第三引数にはSSLのARNを設定します。

```ts:cdk-stack.ts
const certificate = certificatemanager.Certificate.fromCertificateArn(
    this,
    'RestAPICertificate',
    'arn:aws:acm:ap-northeast-1:000000000000:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', // 証明書のARN
),
```

### APIにカスタムドメインを設定
RestAPIを作成する際にステージの設定を行なっていない場合は、カスタムドメインのマッピング先のステージは自動でprodになります。
domainNameはAPIに使用したいドメインにしてください。

```ts:cdk-stack.ts
restAPI.addDomainName(
  'CustomDomain',
  {
    domainName: 'api.example.com',
    certificate: certificate,
    securityPolicy: apigateway.SecurityPolicy.TLS_1_2,
    endpointType: apigateway.EndpointType.REGIONAL,
  }
);
```

## カスタムドメインのエイリアスレコードの作成
先ほど作成したAPI Gatewayに向いてくれるようにDNSを設定します。

### ホストゾーンを取得
hostedZoneId, zoneNameは事前に用意しておいたホストゾーンに合わせて変更してください。

```ts:cdk-stack.ts
const hostZone = route53.PublicHostedZone.fromHostedZoneAttributes(
  this,
  `HostZone`,
  {
    hostedZoneId: 'XXXXXXXXXXXXXXXXXXXX',
    zoneName: 'example.com',
  }
);
```

### エイリアスレコードを作成
先ほど取得したホストゾーンにAレコードを追加します。
recordNameはAPIに使用したいドメインにしてください。

```ts:cdk-stack.ts
new route53.ARecord(
  this,
  'ARecord',
  {
    zone: hostZone,
    recordName: 'api.example.com',
    target: route53.RecordTarget.fromAlias(
        new route53Tragts.ApiGateway(restAPI),
    ),
  }
);
```

# 環境が正しく作られたか確かめる
以上が書けたらCDKをデプロイしてください。
デプロイでエラーが出なかった場合は実際にリクエストを送って、レスポンスが返ってくるか確かめましょう。

以下のコマンドを叩いて

```bash
curl https://api.example.com/
```

こちらのレスポンスが返って来れば正しく設定されています。

```json
{"message": "Internal server error"}
```
【GoogleAppsScript】Google Formsでアップロードされるファイル名の変更方法

`Google Forms`でファイルアップロード機能を活用した場合に、アップロードされくるファイル名を任意の文字列にする方法をご説明です。
#ファイルアップロードのデフォルトの挙動
![google_forms_change_uploaded_file_name_sample.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609490/ea4f8d65-e972-54c4-1b0f-ac4c25a6f16d.jpeg)
今回は以下のように①名字、②名前、③写真というサンプルのフォームを作りました。且つ、滝廉太郎さんという方が写真をアップロードすることを考えます。
デフォルトのまま使うと以下のように`{元のファイル名} – {ユーザ名}.{元のファイル拡張子}`という名前になることがわかります。
#Google Script Editorを用いたファイル名変更方法

ということで早速スクリプトエディタを開きます。
![google_forms_change_uploaded_file_name_script_editor.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609490/4625ed16-5120-1940-1f2f-5ea5d89d5dd7.jpeg)

![google_forms_change_uploaded_file_name_edit.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609490/49afc065-7a50-963b-9277-a3093d3ee173.jpeg)

スクリプトエディタを開いたら、もともと記載されている文章を全て削除して、以下のコードをコピペして保存してください。今回は`{名字欄に入力した文字列}_{名前欄に入力した文字列}`をファイル名として設定するという内容にしております。

```js:script.js
function myFunction(e) {
  var itemResponse;
  var fileName;
  var photo;
  
  // フォームの回答結果を取得(設問順に配列に格納される)
  itemResponses = e.response.getItemResponses();
  
  // 名字_名前の順番で文字列を連結させてファイル名を作成する
  itemResponse = itemResponses[0];
  fileName = itemResponses[0].getResponse() + '_' + itemResponses<img class="ranking-number" src="https://tagutasu.com/wp-content/themes/jin/img/rank01.png" />.getResponse();
  
  // アップロードされた写真の名前を設定
  photo = DriveApp.getFileById(itemResponses<img class="ranking-number" src="https://tagutasu.com/wp-content/themes/jin/img/rank02.png" />.getResponse());
  photo.setName(fileName);
}
```
その後は時計マークのアイコンを開いて、トリガーを設定していきます。
<img width=100% alt="google_forms_change_uploaded_file_name_trigger-1024x570.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609490/394172fa-b118-a91b-56d6-ed9467824ca1.jpeg">
このように「イベントの種類を選択」を、「フォーム送信時」に設定してください。これによって、フォームが送信されたときに、先ほどコピペしたコードを実行するという設定にすることができます。
<img width=100%alt="google_forms_change_uploaded_file_name_certificate-1024x379.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609490/a94e6c25-1e24-ddfe-eeef-8e093314802f.jpeg">

自身が開発社になるのでその点は問題がないと思いますので、詳細を押して当該のアプリに移動してください。その後、アプリがgoogleドライブにアクセスできるように権限を設定するよう促されるので「許可」をして進めてください。なお、この過程で設定済みのgmailアドレスに、本人確認のセキュリティチェックが入るのでこちらもOKで進めていくようにしてください。
*`個人情報など重要なデータを取り扱う際には、組織のセキュリティーポリシーを踏まえた上でご判断をお願いいたします。`*
#アップロードされた画像ファイル名
上記の手順を全て行った上で、Google Formで冒頭の例と同じ入力を行うと、ファイル名が`{名字欄に入力した文字列}_{名前欄に入力した文字列}`になっていることが確認でききました。
![google_forms_change_uploaded_file_name_changed_name.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609490/cc2f1181-ac16-670e-cea8-1072cf9465f0.jpeg)
Docker 個人的まとめ



docker run [OPTIONS] IMAGE [COMMANDS]
ドッカーを走らせる

docker run -it -d IMAGE
-it:入力＆ターミナル表示
-d:バックグラウンド

docker pull [image]
imageをダウンロード

docker ps
動いているcontainerを表示

docker ps -a
全てのcontainerを表示

docker stop [ID or tag]
containerを止める

docker rm [container]
containerを削除

docker rmi [ID or tag]
imageを削除