OmniAICreator/Qiita-1.07M huggingface dataset:
Blocked hostエラーが出た時の対処法

①やりたいこと
Rails6の本番環境でrails sをしたときにBlocked hostエラーが発生しました。

<br>
②エラー内容
![e322b88f1ab7ec7e6f5ef601ef851134.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1962714/b6dd7688-9647-4acd-0858-85a183dbd69c.png)

今回の対処法は以下の記事を参考にさせていただきました！
https://qiita.com/kodai_0122/items/67c6d390f18698950440

https://weseek.co.jp/tech/680/


③原因
DNSリバインディング攻撃を防止する ActionDispatch::HostAuthorization middleware によるものらしい、、（Rails6から追加された機能です）



<br>
④解決策
３つありますが、基本的には一つ目の解決方法でOKです。筆者も一つ目で解決しました。

1. Rails.application.config.hosts に接続先として許可する Host を追加する
development 環境では、 default で Rails.application.config.hosts に下記の Host が登録されています。
これ以外の Host 名として接続しようとすると、ブロックされるため、必要な Host 名を追加します。

```
 Rails.application.config.hosts = [
   IPAddr.new("0.0.0.0/0"), # All IPv4 addresses.
   IPAddr.new("::/0"),      # All IPv6 addresses.
   "localhost"              # The localhost reserved domain.
 ]
```

追加方法は development 環境であれば、 config/environment/deveropment.rbに下記のように記述します。

```
Rails.application.configure do
  config.hosts << "d4e14c8c945545778d2fc824d6ee6181.vfs.cloud9.ap-northeast-1.amazonaws.com"
end
```

２. Rails.application.config.hosts の設定を clear する

Rails.application.config.hosts は、空の場合は Host ヘッダーのチェックが行われないため、ブロックされなくなります。
development 環境以外の環境 (たとえば production ) では、 Rails.application.config.hosts は default で空のため、チェックは行われません。

development 環境で Host ヘッダーのチェックを行わないようにするには、 config/environments/development.rb に下記のように記述します。

```
Rails.application.configure do
    config.hosts.clear
end
```

なお、アプリケーションの前段に Host ヘッダーを識別して振り分けを行う LB 等がない場合は、DNSリバインディング攻撃が防止できなくなるため、 development 環境以外では Rails.application.config.hosts を適切に設定されることをおすすめします。
<br>

３. ActionDispatch::HostAuthorization middleware を使わないようにする

アプリケーションの前段に Host ヘッダーを識別して振り分けを行う LB 等があり、アプリケーション自体でDNSリバインディング攻撃を防止する必要がない場合は、 ActionDispatch::HostAuthorization middleware 自体をロードされないように設定します。

config/application.rb に下記のように記述します。


```
module HogeApp
  class Application < Rails::Application
    onfig.middleware.delete ActionDispatch::HostAuthorization
  end
end
```


<br>
開発環境
mac OS バージョン11.6

Rails 6.1.4.4
Ruby 3.0.0
MYSQL 0.5

エディタ
Cloud9
Hololens2+Unity開発でのアプリ表示名だけ日本語を使いたい


## いきなり結論から

Unityでビルドした`Package.appxmanifest`内の表示名を変える！

## 環境

* Unity: v2019.4.18f1
* MRTK: v2.7.2
* Visual Studio 2019

## 現象

Unityの「Player Settings」内の「Product Name」は日本語に変えることができ、簡単にアプリ名を日本語にすることができます。

[![Image from Gyazo](https://i.gyazo.com/09f9b1b6277e9937dc9856fab1a4262f.png)](https://gyazo.com/09f9b1b6277e9937dc9856fab1a4262f)

ただ、それだとアプリのパスに日本語が混じってしまい、エラーがでることがあります。

自分はHololens2のRemote Renderingを利用するとエラーがでました。（その他にもちらほら発生…）

https://azure.microsoft.com/ja-jp/services/remote-rendering/#overview

### Unity上だと触れない！！

「Publishing Sattings」内のそれっぽい項目の「Package name」は日本語入力すると消えちゃうし、
「Package display name」も「Display name」も変更できないようになってる

[![Image from Gyazo](https://i.gyazo.com/3b51157ab65d24fa8a0c73715c9e3bee.png)](https://gyazo.com/3b51157ab65d24fa8a0c73715c9e3bee)

## 対処方法

冒頭で説明した通り`Package.appxmanifest`内の表示名を変えること

出来る場所は、Unity内の「Build Settings」からのビルドだと、選択したフォルダ内のアプリ名のフォルダ内に、

MRTKのBuild Windowからのビルドはデフォルトだと、プロジェクトルートからBuilds > WSAPlayer > [アプリ名]のフォルダ内に

VisualStudioで開くと

[![Image from Gyazo](https://i.gyazo.com/0f3be2b8ec1d5b2fffe9428408c71eb1.png)](https://gyazo.com/0f3be2b8ec1d5b2fffe9428408c71eb1)

その他テキストエディタだと

[![Image from Gyazo](https://i.gyazo.com/fa21b0ef4072b9550df156beb41f4295.png)](https://gyazo.com/fa21b0ef4072b9550df156beb41f4295)
【laravel】ルーティングを別のファイルに定義したい！

# 概要
laravelで開発を行なっている人であれば、
普段から`web.php`や`api.php`などのルーティング定義ファイルを触ったことがあるかと思います。
皆さんはルーティング定義を`web.php`に定義していますか？
それとも別のファイルに定義していますか？
この記事は`web.php`以外のファイルにルーティングを定義をする為の手順をまとめたものになります。

# 事前知識 
知らなくても実装できますが、知ってた方が良さそうなこと。

https://readouble.com/laravel/8.x/ja/providers.html

https://readouble.com/laravel/8.x/ja/lifecycle.html

https://readouble.com/laravel/8.x/ja/routing.html

# 手順
1. ルーティングを定義したいファイルを作成
2. サービスプロバイダを作成 or 既存のサービスプロバイダを編集
3. 作成した場合はapp.phpに登録

# ルーティングを定義したいファイルの作成
`test.php`というファイルを作成し、そこにルーティングを定義したいとします。

```php:test.php
<?php

// 'test'を返却
Route::get('/example', fn () => 'test');
```

今の状態では、`/example`にアクセスしても404が返却されると思います。

# サービスプロバイダを作成 or 編集

## 編集
既存のサービスプロバイダを編集します。

```php:App\Providers\RouteServiceProvider.php
<?php

namespace App\Providers;

use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Route;

class RouteServiceProvider extends ServiceProvider
{
    // 省略

    /**
     * Define the routes for the application.
     */
    public function map(): void
    {
        $this->mapApiRoutes();

        $this->mapWebRoutes();

        // 追加したメソッドを呼び出す
        $this->mapTestRoutes();
    }

    // このメソッドを追加
    protected function mapTestRoutes(): void
    {
        // mapWebRoutes() などを参考にすればOK。
        // ミドルウェアを設定したくない場合などは省略も可
        Route::prefix('test')
            ->middleware('web')
            ->namespace($this->namespace)
            ->group(base_path('routes/test.php'));
    }

    // 省略
}

```

上記のように設定することで、`routes/test.php`が読み込まれるように定義することができます。
またこのファイルで、`web.php`や`api.php`を読み込む設定が実装されています。


## 作成
作成する場合は、`App\Providers\RouteServiceProvider.php`を継承したサービスプロバイダを作成します。

```php:App\Providers\RouteRegistrarProvider.php
<?php

namespace App\Providers;

use Illuminate\Support\Facades\Route;

class RouteRegistrarProvider extends RouteServiceProvider
{
    public function map(): void
    {
        Route::prefix('test')
            ->middleware('web')
            ->namespace($this->namespace)
            ->group(base_path('routes/test.php'));
    }
}
```

## コマンド補足

```php
        Route::prefix('test')
            ->middleware('web')
            ->namespace($this->namespace)
            ->group(base_path('routes/test.php'));
```
- **`prefix()`でルーティングファイルにプレフィックスを設定できます。**
上記例だと、`routes/test.php`に定義したルーティングに`/test`のプレフィックスがつくようになります。

- **`namespace()`でコントローラーのルートを設定できます。**
デフォルトだと、`App\Http\Controllers`になっていると思います。

- **`group()`でルーティングファイルを設定します。**
`basepath()`でlaravelのインストールされた場所をベースにしたパスを返却するので、引数にはlaravelのルートからルーティング定義ファイルへの相対パスを指定。


# app.phpに登録(プロバイダを作成した場合)
providers 配列の中に作成したプロバイダを追加すればOK

```php:config/app.php
    // 省略
    'providers' => [
        \App\Providers\RouteRegistrarProvider::class,
    ] 
```
ここまでの手順完了後に`/test/example`にアクセスすると、画面に`test`と表示されると思います。(多分)


# まとめ
- 意外と簡単
- 既存のプロバイダを編集して良いし、新たに作成しても良い
- 新しく作成した場合は、app.phpに登録すべし

わかりにくい部分や、間違っているところなどあったら教えていただけるとありがたいです！
【Laravel】Route::resource を使用せずに、同等のルート内容を書くよ(=ﾟωﾟ)ﾉ

Laravel でCRUDを作成する際に便利な `Route::resource` ですが、見た目がシンプルな反面、実際にどうルーティング設定されているのか想像しずらい面が個人的にあります。 

今回は、`Route::resource` を使用せずに同等の書き方を書いてみて、改めて `Route::resource` がどういったルーティングをしているのかを理解していきたいと思います。

## `Route::resource` を使用しない書き方

```php:web.php
<?php

use App\Http\Controllers\BlogController;
use Illuminate\Support\Facades\Route;

// Route::resource('blog', BlogController::class);

// `resource`メソッドと同等の書き方
Route::get('blog', [BlogController::class, 'index'])->name('blog.index');
Route::get('blog/create', [BlogController::class, 'create'])->name('blog.create');
Route::post('blog', [BlogController::class, 'store'])->name('blog.store');
Route::get('blog/{blog}', [BlogController::class, 'show'])->name('blog.show');
Route::get('blog/{blog}/edit', [BlogController::class, 'edit'])->name('blog.edit');
Route::put('blog/{blog}', [BlogController::class, 'update'])->name('blog.update');
Route::delete('blog/{blog}', [BlogController::class, 'destroy'])->name('blog.destroy');
```

 `resource` メソッドと同等の内容になりました。ルーティング内容に沿って、コントローラを作成し CRUD を簡単に作成することが可能です。

 コマンドで `php artisan route:list` を打つと全体のルーティング内容を確認することができるので、`resource メソッド` を `使用した場合` と `そうでない場合` とで確認してみると良いでしょう。

## ルートグループで更に見やすく

ルーティングの際に、グループを定義することで更にリーダブルになります。

```php:web.php
<?php

use App\Http\Controllers\BlogController;
use Illuminate\Support\Facades\Route;

// Route::resource('blog', BlogController::class);

// `resource`メソッドと同等の書き方
Route::prefix('blog')
    ->controller(BlogController::class)
    ->as('blog.')
    ->group(function () {
        Route::get('', 'index')->name('index');
        Route::get('create', 'create')->name('create');
        Route::post('', 'store')->name('store');
        Route::get('{blog}', 'show')->name('show');
        Route::get('{blog}/edit', 'edit')->name('edit');
        Route::put('{blog}', 'update')->name('update');
        Route::delete('{blog}', 'destroy')->name('destroy');
    });
```

上記の例では、`prefix` メソッドでグループ内を対象に、各々のルートへ `blog` プレフィックスを付与します。加えて `as` メソッドでグループ内を対象に、各ルート名の前に`blog.`を付与します。更に、`controller` メソッドでグループ内にコントローラ名を書くことなしにルーティングすることができます。

グルーピングでコードがより見やすくなりました。
【Rails】ルーティングのグループ化(scope / scope module / namespace)

##ルーティングのグループ化のメリット
``namespace``の例を挙げて説明すると、

**①集合を分けることで同じ名前を使うことができる**
たとえば管理者用のログイン機能を実装するときに、``user_sessions_controller``という名前を使おうとする。
しかし、既にサービスのログイン機能の実装の際に、その名前のコントローラー名を使用していると、アプリの挙動がおかしくなってしまう可能性がある。

**②参照が簡単になる**
ディレクトリを見たときに、グループ別でファイルを分けておくと、人間も管理しやすく、アプリケーションもファイルの参照が容易になる（メンテナンスしやすくなる）。

##``namespace`` / ``scope`` / ``scope module``の違い
ルーティングのグループ化には、``namespace`` / ``scope`` / ``scope module``の３つがある。

この３つの大まかな違いは以下の通り。

| | URL| ファイル構成 |
|:-:|:-:|:-:|
|  scope |  指定のパスにしたい | 変えたくない  |
| module  |  変えたくない | 指定のパスにしたい  |
|  namespace | 指定のパスにしたい  | 指定のパスにしたい  |


もっと分かりやすく区別すると、``rails routes``した時に出てくる、`` Prefix/URI/Pattern``この部分の差である。

[![Image from Gyazo](https://i.gyazo.com/6f1d71002fefd47531d89142624be7d3.png)](https://gyazo.com/6f1d71002fefd47531d89142624be7d3)
---
###◆scope
``scope``メソッドを用いてルーティングをグループ化すると、**パスのみグループ化**ができる。
しかし、パスをグループ化しただけで、呼び出すコントローラや``Prefix``はルーティングをグループ化する前と同じ。

```routes.rb
scope :admin do
    resources :boards
end
```
[![Image from Gyazo](https://i.gyazo.com/b720c8e0819729fc084f5e3d388da814.png)](https://gyazo.com/b720c8e0819729fc084f5e3d388da814)

###◆scope module
``scope``メソッドと``module``オプションを用いてルーティングをグループ化すると、呼び出すコントローラのアクションのみグループ化ができる。
``Prefix``やパスに関しては、ルーティングをグループ化する前と同じ。

```routes.rb
scope module: :admin do
    resources :boards
  end
```
[![Image from Gyazo](https://i.gyazo.com/5917bb9db38617b89f6d8ace90af0a9d.png)](https://gyazo.com/5917bb9db38617b89f6d8ace90af0a9d)

###◆namespace
``namespace``メソッド（名前空間）を用いてルーティングをグループ化すると、指定した名前空間名でルーティンングをグループ化することができる。
ターミナルで確認すると、**Prefix, URIパス, Controller#Action**に名前空間名が付与されていることが分かる。
``namespace``メソッドを用いたルーティングのグループ化は、名前空間によって識別されたコントローラのアクションを実行したい時に使用。(例の場合、名前空間名をadminとしている)

```routes.rb
namespace :admin do
    resources :boards
end
```
[![Image from Gyazo](https://i.gyazo.com/8d1642455a0c403bbba2f02a8f9682e8.jpg)](https://gyazo.com/8d1642455a0c403bbba2f02a8f9682e8)

⚠️``namespace``を利用するときは、``Controller``内に実際の``URLパス``と同様のディレクトリ構成を作る必要がある。

またこの例の場合、``admin``の``controller``を作成する際には、管理者用のコントローラを作成するにあたって、「管理系」のカテゴリとして区分したいため、**``Admin::BaseController``**として命名する必要がある。

```ディレクトリ構成.
─ app
　├ controllers
　│└ 【名前空間名】
　│　└ 【コントローラ名】_controller.rb
　└ views
　　└ 【名前空間名】
　　　└ 【コントローラ名】
　　　　└ 【アクション名】.html.erb
```

```
class 【名前空間名】::【コントローラ名】Controller < ApplicationController
   アクション
end
```
---
ルーティングのグループ化についてのまとめは、以下の通りになる。
**namespace**では``Prefix、URI Pattern、Controller#Action``
**scope**では``URI Pattern`` のみ
**scope module**は``Controller#Action``のみ

##参考記事
[Railsのルーティングを学ぼう③](https://diveintocode.jp/blogs/Technology/Routing3)
[【Rails】ルーティングの色々な作成方法をざっくりまとめてみた](https://zenn.dev/yukihaga/articles/69a816962ef6b9)
[Railsのroutingにおけるscope / namespace / module の違い](https://qiita.com/ryosuketter/items/9240d8c2561b5989f049)
[【Ruby on Rails】ルーティング scope と namespace の違い](https://techblog.kyamanak.com/entry/2017/07/30/223113)
[namespace を使ってコントローラーをグループ化する](https://kentarotawara.hatenablog.com/entry/2020/06/24/230520)
【GitHub】 git-flowを使った開発

#git-flowとは
A successful Git branching modelを簡単に行えるように開発されたツール(gitプラグイン)のこと。

ツールを利用することでマージ漏れや作業場所の判断が容易になります。

#ブランチの種類
git-flowでは5つのモデルを利用して開発を進めていきます。

|ブランチ種類|必須|内容|
|:---|:---|:---|
|develop|○|開発を行う主軸となるブランチ。リリース前はこのブランチが最新のブランチになります。リリースの準備ができたらmasterブランチにマージします。|
|feature|○|作業者が作業を行うブランチ。developブランチから各作業者がブランチを作成して開発していく。終わるとdevelopブランチにマージされ、featureブランチは削除される。|
|release||プロダクトをリリースするためのブランチ。featureブランチで各自が作業し、その集約がdevelopブランチとなり、いよいよリリースとなるとまずdevelopブランチからreleaseブランチを作成。リリース前の最終調整をreleaseブランチで行う。releaseブランチでの作業が終わるとその内容が、masterブランチとdevelopブランチにマージされる。マージするとreleaseブランチは削除される。|
|master|○|リリースされた最新情報を管理するためのブランチ。リリースしたタイミングを管理するため、リリースタグも打つ。|
|hotfix||リリースしたプロダクトにバグがあってすぐ直したい場合に使うブランチ。リリースしたけどタイポがあった、とかセキュリティ的にまずいので緊急対応が必要！というときに使う。hotfixブランチはmasterブランチから作成する。作業終了後は、masterブランチとdevelopブランチにマージされ、hotfixブランチは削除する。|

#実際の開発フロー
###1. 最新の developブランチを取得する

リモートから最新情報をローカルに持ってくる

```
git fetch
```

developブランチに切り替える

```
git checkout develop
```

リモートの情報をローカルに適用しながら最新のdevelopブランチを取得する

```
git pull --rebase origin develop
```

###2. developブランチをベースとしたfeatureブランチを作成する
今回は、`feature/add_branch`を作成します。

```
git checkout -b feature/add_branch
```

###3. 実装してコミットする
コミットメッセージは開発担当者が見たときに分かりやすくなるようにする。

###4. 実装完了後、Githubにブランチをプッシュする

```
git push -u origin feature/add_branch
```

###5. Github UI上で、PullRequestを作成する
baseはdevelopブランチとなるようにする。
![スクリーンショット 2022-01-22 18.28.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576859/de823946-a39e-bd4f-72b5-397d0ef7e7e3.png)


###6. レビューを行い問題なければマージする
※検証環境があれば、developブランチで一旦デプロイする。
![スクリーンショット 2022-01-22 18.31.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576859/42dc11e5-159a-5944-c280-0f94045f497a.png)


###7. developブランチをチェックして問題なければPullRequestを作成する
baseはmasterブランチとなるようにする。
![スクリーンショット 2022-01-22 18.34.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576859/3000981d-74f0-baa0-55e4-f4399e1c5eaa.png)


###8. PR作成者以外がレビューを行い、問題なければマージ
![スクリーンショット 2022-01-22 18.31.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576859/ad02aecc-862f-b3ed-a1bb-e78cc94df0a4.png)


###9. 本番環境にmasterブランチをデプロイする。
TableauとTreasuredataの接続ドライバ設定（2022最新）

## ドライバ新しくなってるよ知ってた？
TD-Tableau接続といえばODBCのドライバが過去は標準だったような気がするが、
今日日TableauのメニューにあるPresto(正確にはtrino：Facebookのせいでフォークしたんだっけprestoプロジェクト)でJDBC使って取るのが早い。
そしてTableau onlineからのTreasuredataへの接続がODBCではできなくなっている。
presto経由で接続しないとサーバーからデータソース抽出/更新ができない。
（tableauサーバーも新しいやつは多分そう）知らなかったの俺だけかよって思ったので記す。

### 1．ドライバダウンロードしてtableau用に配置
Trinoのページからドライバをダウンロード(TDのprestoはtrino)
https://trino.io/docs/current/installation/jdbc.html

Windowsなら下記フォルダに配置（macは~/Library/Tableau/Drivers）
`C:\Program Files\Tableau\Drivers`

※Tableauを開いている場合は、配置後Tableau再起動すること
### 2．Tableau Desktopからの接続
Tableauを起動「新しいデータソース」から「Presto」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143512/b1da04f6-2fff-309b-3c3d-563e1024dda3.png)


下記内容を入力しユーザー名はAPIキーを入力「サインイン」
`サーバー：api-presto.treasuredata.com(USリージョンの人)　
api-presto.treasuredata.co.jp(JPNリージョンの人)
ポート：443
カタログ：td-presto
スキーマ：空欄
認証：ユーザー名
ユーザー名：（TDのmasterAPI-KEY）`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143512/93d41b95-aef2-7fa5-2fed-cbf0d1c7e28a.png)

繋がりました。

## だけです
古い人でいまだにODBCでやってる人（俺）。知らんかった・・・これだと結構スピード出ますわ。ODBCでおせーとかエラーでるーとかの方、見直してみてください。
Tableau OnlineでTreasuredataに接続しているデータの抽出の更新ができない方、お試しあれ。幸あれ。
CXL (Compute Express Link) その10 - CXL.ioコマンド

私はメモリデバイスの不揮発性メモリ制御やホストIFなどを扱うソフト屋をやっております。
仕事でCXL(Compute Express Link)まわりの技術に関わっています。
CXL技術に関連するメモ書きを残していこうと思います。
ホストのCPUとOS/Applicationまわりの経験・知識共に乏しいので、親切な方は教えて下さると幸いです。
また、間違い、アドバイス、その他、ご意見やご要望ありましたらお気軽にどうぞ。

# 1. CXL.ioコマンド

CXLの仕様では、CXLメモリデバイスとそのメモリ空間の設定を行うためのコマンドが、CXL.ioを通して実行するコマンドとして定義されています。これらコマンドは、基本的に、ホストシステムがデバイスに対して発行します。
ホストシステムがコマンドを発行する際には、CXLの仕様書で定義されるMailboxレジスタが使用されます。

CXL.memの経路でCXLメモリデバイスのメモリ空間のデータへの読み書きを行い、CXL.ioの経路でCXLメモリデバイスおよびメモリ空間の設定を行う役割分担になっています。
ホストシステムがコマンドを発行する際には、CXLの仕様書で定義されるMailboxレジスタが使用されます。

PCIeの仕様でもMailboxレジスタが定義されていますが、CXLで定義されるMailboxレジスタとは別です。CXLメモリデバイスは、PCIeで定義されるMailboxレジスタと、CXLで定義されるMailboxレジスタの両者に対応する場合、それぞれのMailboxレジスタを持つ必要があります。

恐らくは、一般的なCXLメモリデバイスは、PCIeで定義されるMailboxレジスタとCXLで定義されるMailboxレジスタの両レジスタに対応することが必要になると思われます。
PCIeで定義されるMailboxレジスタは、ホストシステムのSWが、CXLメモリデバイスの性能情報であるCDATを読み出すために使用されます。ホストシステムのSWは、CDATの情報を使用してSRAT/HMATを生成することができます。
ホストシステムのSWは、基本的なCXLメモリデバイスの情報は、性能情報を含めてPCIeで定める仕様の範囲内で取得し、システムのメモリマップを構成し、構成した後、CXLメモリデバイスの持つメモリ空間の制御と読み書きをする際にはCXLで定める仕様に従うアクセスを行うことになると考えています。

CXL.ioを通して実行されるコマンドとして、以下に示す1.1から1.3に示す3つのカテゴリで、それぞれにコマンドセットが定義されています。
CXL.memの経路のコマンドでCXLメモリデバイスのメモリ空間のデータへの読み書きを行い、CXL.ioの経路のコマンドでCXLメモリデバイスおよびメモリ空間の設定を行う役割分担になっています。

## 1.1 CXL Device Command
CXLメモリデバイスの(直接メモリに関わらない)デバイスの制御に使用されるコマンド。

| コマンドセット | 概要 |
|:--|:--|
| Events | CXLメモリデバイスで発生したエラー情報等の取得に関係するコマンドセット。 |
| Firmware Update | CXLメモリデバイスのFWのアップデートに関係するコマンドセット。 |
| Timestamp | CXLデバイスの時間設定に関係するコマンドセット。 |
| Logs | CXLデバイス固有のログの取得に関係するコマンドセット。 |


## 1.2 Memory Device Commands
CXLメモリデバイスのメモリ空間の制御に使用されるコマンド。

| コマンドセット | 概要 |
|:--|:--|
| Identify | CXLメモリデバイスの情報(FWリビジョン、メモリ容量等)の取得に使用されるコマンドセット。 |
| Capacity Config and Label Storage | CXLメモリデバイスのメモリ空間のパーティションに関する情報の設定と取得に使用されるコマンドセット。 |
| Health Info and Alerts | CXLメモリデバイスの寿命情報等の取得に関係するコマンドセット。 |
| Media and Poison Management | CXLメモリデバイスで発生した訂正不可エラーに関するの情報の取得に使用されるコマンドセット。 |
| Sanitize | CXLメモリデバイスのメモリに書き込まれたデータの消去に使用されるコマンドセット。 |
| Persistent Memory Data-at-rest Security | CXLメモリデバイスのアクセスコントロールに使用されるコマンドセット。 |
| SLD QoS Telemetry  | SLD対応のCXLメモリデバイスのQoSの情報を取得するために使用されるコマンドセット。 |

## 1.3 FM API Command
SwitchとMLD対応のCXLデバイスの制御に使用されるコマンド。
FMは、Fabric Managerの略で、ホストシステムにおいてCXLメモリデバイスのメモリ領域管理等の役目を持つものを指しています。

| コマンドセット | 概要 |
|:--|:--|
| Switch Event Notifications | CXLメモリデバイスが、FMに対するイベントの通知に使用されるコマンドセット。 |
| Physical Switch | Switchの情報や状態を取得するために使用されるコマンドセット。 |
| Vitrual Switch | 2つ以上のVCS(Virtual CXL Switch)の機能をサポートするSwitchに使用される。VCSの情報の取得、およびVCSの設定に使用されるコマンドセット。 |
| MLD Port | MLD対応のCXLメモリデバイスをサポートするためにSwitchで使用される。 |
| MLD Components | MLD対応のCXLメモリデバイスを制御するために使用されるコマンドセット。 |

Physical Switch、Vitrual Switch、MLD Portは、いずれもSwitchでサポートするコマンドセットです。MLD Componentsは、MLD対応のCXLメモリデバイスでサポートするコマンドセットです。

---
以上、コマンドセットはCXL2.0で定義されているコマンドセット全てを挙げています。次回以降、今回挙げたコマンドセットからピックアップして詳細について書こうと思っています。
Python3でpip install uuidしてはいけない件


表題の件、正確に言えばPython2.5以降からですが、
uuidは標準ライブラリとしてバンドルされています。

なのでpip install uuidしてしまうと、


```
File "/Users/hoge/.pyenv/versions/3.8.0/lib/python3.8/site-packages/pip/_internal/req/req_install.py", line 9, in <module>
    import uuid
File "/Users/hoge/.pyenv/versions/3.8.0/lib/python3.8/site-packages/uuid.py", line 138
    if not 0 <= time_low < 1<<32L:
```

このようなエラーになります。
どうやらこれは2.5以降に標準ライブラリに含まれているモジュールのバックポートのようです。

##もしインストールしてしまった場合

```
$ pip uninstall uuid
```

するか、
もしできなければ、ここでいうsite-packages内の

```
uuid-1.30.dist-info
uuid.py
```

そこにあるuuid.pyを削除すれば解消できます。
※ちゃんとrequiremetnts.txtからも消しましょう。


##参考
https://docs.python.org/ja/3/library/uuid.html

https://stackoverflow.com/questions/33612977/how-to-use-uuid-lib-with-mod-wsgi
ローカルKeycloak + Google IdP連携方法メモ

* [以前作成したVue + Keycloakのローカル検証環境](https://qiita.com/KWS_0901/items/ae699d42193077e3049f)を外部IdP(Google)連携させる方法についてメモする。



## 1.Keycloak 準備

* [こちら](https://qiita.com/KWS_0901/items/ae699d42193077e3049f)の手順でDocker起動～レルム登録まで行う。

## 2.テスト用Vueアプリ準備

*  [こちら](https://qiita.com/KWS_0901/items/ae699d42193077e3049f#vuejs-%E3%83%95%E3%83%AD%E3%83%B3%E3%83%88%E9%83%A8%E5%88%86%E4%BD%9C%E6%88%90)の手順でテスト用のVueアプリを準備しておく。

## 3.Keycloak IdP(Google)設定

1. 作成したレルムを選択。
2. 「Identity Providers」を選択
3. 「Google」選択
4. 「Redirect URI」を控える。(例：http://localhost:8089/auth/realms/myrealm/broker/google/endpoint)

## 4.Google 設定

※[こちら](https://atmarkit.itmedia.co.jp/ait/articles/1804/14/news004.html)を参考にプロジェクト作成、クライアント登録を行う。

* クライアント設定

  * 種類：ウェブ アプリケーション

  * スコープ：` .../auth/userinfo.email`,`.../auth/userinfo.profile`,`openid`

  * 承認済みの JavaScript 生成元:`http://localhost:8089`

  * 承認済みのリダイレクト URI:`http://127.0.0.1:8089/auth/realms/myrealm/broker/google/endpoint`

    ※Keycloak設定時に出力された値

    ※**KeycloakからGoogleへのリダイレクト時に「localhost」->「127.0.0.1」に変換されてしまったためこのような形としている。**

## 5.Keycloak IdP(Google)設定

1. 4.で発行したクライアントID/シークレットを③のIdP設定に入力する。
2. 「Save」

## 動作確認

**1.起動**

```shell
npm run dev -- --port 3000
```

**2.http://localhost:3000にアクセスする。**
![keycloak_idp_login.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/7b78068d-5304-8b3b-58f0-f2bc8dffd32e.png)

**3.「Google」ボタン押下し、認証・同意を行う。**

**4.Vueアプリにリダイレクトされ、以下の画面が表示される。**
   ![keycloak_idp_redirect.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/83908803-372b-7f29-9ce6-9d6afcb09615.png)


## 参考情報

* [Keycloakで外部アイデンティティー・プロバイダーと連携してみよう](https://atmarkit.itmedia.co.jp/ait/articles/1804/14/news004.html)
* [Keycloakのソーシャル連携（SNS連携）を試してみる](https://qiita.com/tamura__246/items/02b3b75f36a22d0c960a)
AWS Cloud9 - サービス名の由来について

転職活動の息抜きとして記事作成

AWSのCloud9を使う機会があって、実務で開発技術を扱う機会が少ない自分としては「環境準備に手間がかからず便利だなー」、と感心していた

##名称について

ふと「Cloud9」という名称が気になり

「Cloud"9"ってなってるけど、なぜ9？」「なにか由来や意味付けがある？」

と思って調べてみたところ、意外とためになったのでまとめてみた

##「cloud nine」の意味
そもそも「cloud nine」というのは、英語で「非常に幸せな状態」「最高にハッピーな状態」といったようなすごくポジティブな状態を表す慣用表現とのこと
（「be in cloud nine」といった形で使う）

>[weblio英和辞典 - cloud nine](https://ejje.weblio.jp/content/cloud+nine)

「cloud nine」で検索をしてみると、AWS以外の製品や店名なんかでも引っかかってくる

メジャーな表現なんですね、知らなかった、、、

ちなみに、よりポジティブな意味合いを強調するため「cloud ten/eleven...」のように数字を大きくする使い方もあるとのこと

##由来、ルーツ
「cloud nine」の由来、ルーツについては諸説ある様子だが、その内の一つ

+ cloud nineはアメリカの気象予報で積乱雲のことを指す
+ 積乱雲は空高く舞い上がることから、「天にも上る気持ち」という意味へ派生した

なるほどなー

##調べてみて
調べてみるもんですね、好奇心は大事

技術情報だけでなくさらっとこんな周辺知識を出せると面白いかも
【Python】jsonからcsv作成【業務自動化】

### 雑務撃退術🐍

サーバー障害対応スクリプトについて、運用者向けの仕様書を作成するタスク。
ホスト名とログインするために必要な情報を記載した以下のようなjsonファイルがあり、その情報を全て専用のエクセルに貼り付けなければならなかった。
（IPアドレスはもちろん数値である…）

```json
{
    "serverintheruemorgue": {
        "ip_address": "quoth.the.raven.nevermore",
        "user": "edgar",
        "password": "nightpain"
    }
}
```

ホストの数が少なければ手動でコピペして対応できるが、何百個とあると流石に限界である。
Pythonでロジックを組んでなんとか解決できないか考えてみた。

### 🐼の手を借りてみる

最初はクライアント指定のエクセルに直接出力することも考えたが、同じデータを複数のフォーマットに出力したり、そもそもフォーマットの変更等が発生することを考えると、貼り付けは手動で行う方が汎用性が高いだろうと考えた。
結局jsonから読み取ったデータをpandas.DataFrame型に変換して表として扱えるようにし、最終的にCSVファイルに書き出した上で列ごとに手動で目的先のファイルに貼り付ける、という案に落ち着いた。

最終的なコードは以下。

```py:
import json
import pandas

# jsonファイル読み込み
js = open('jsonファイルがあるディレクトリのパス', 'r')
js_file = json.load(js)

# jsonファイルのキーを取得し、リストに格納
hostname_list = list(js_file.keys())

# jsonファイルの値を取得し、リストに格納
values_list = list(js_file.values())

# 取得した要素を格納するためのリストを作成
ip_address_list = []
user_list = []
pw_list = []

# jsonファイルの値からそれぞれの要素を取得し、リストに格納
for i in values_list:
    ip_address_list.append(i["ip_address"])
    user_list.append(i["user"])
    pw_list.append(i["password"])

# それぞれのリストの中身に相当するカラム名を指定し、DataFrameオブジェクト作成
d = {"hostname": hostname_list, "ip_address": ip_address_list, "user": user_list, "password": pw_list}
df = pandas.DataFrame(d)

# csvファイル作成
df.to_csv('CSVファイルを作成したいディレクトリのパス')
```

Python🐍とかpandas🐼とか、絵文字があるのがいい。
（シェル🐚もあるぞ）
【Selenium】同じClassが2つ以上存在した場合に、それらの中から1つだけ抽出する方法

Seleniumでデータスクレイピングをする時に、同じクラス名が複数ある場合最初に1つだけしか取得できないということにハマりました。
今回はその解決策をメモとして保存しておきます。

#今回のケース

```sample.html
<div>
 <p class=food>りんご</div>
 <p class=food>かき</div>
 <p class=food>もも</div>
</div>
```
上記のようなクラス以外に差別化できるものがない場合にどうしたらいいか分からなく時間を使ってしまいました。

#解決策

```test.py
from selenium import webdriver
from selenium.webdriver.common.by import By

apple = driver.find_elements(By.CLASS_NAME, "food")
apple = house_year[0].text
peach = driver.find_elements(By.CLASS_NAME, "food")
peach = house_width[2].text
```
上記で動作しました。
誰かの役に立てれば嬉しいです。
指摘があれば、コメントください
Databricks Notebook上で画像のプレビューをする方法

Databricks上で画像に関する機械学習やデータサインエンスを実施していると、分析対象の画像ファイル、もしくは、画像データをNotebook上でプレビューしたい場合があります。

今回は、その方法について見ていきます。

参考: [この記事のNotebook](https://sajpstorage.blob.core.windows.net/demo-asset-workshop2021/example/ImageData.html)

# 方法1:  DataFrame(`format="image"`) + `display()`


* SparkのDataframe(`format="image"`)で読み込む
* `display()`で表示する

ドキュメント: [Image](https://docs.microsoft.com/ja-jp/azure/databricks/data/data-sources/image)

```python
image_df = (
  spark
  .read
  .format("image")
  .load('/databricks-datasets/cctvVideos/train_images/label=0/Browse2frame000*.jpg')
)

### DataFrameなので、いろいろ補助情報のカラムを追加できる
display(
  image_df
  .withColumn('filename', image_df.image.origin)
) 
```

![df_image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62653/8e95f640-1500-4f90-999c-03b73615f90b.png)

# 方法2: DataFrame(`format="binary"`) + `display()`


* SparkのDataframe(`format="binaryFile"`)で読み込む
* `.option("mimeType", "image/*")`でコンテンツ種別を指定
* `display()`で表示する

ドキュメント: [Binary File](https://docs.databricks.com/data/data-sources/binary-file.html)

```python
image_df = (
  spark
  .read
  .format("binaryFile")
  .option("mimeType", "image/*")
  .load('/databricks-datasets/cctvVideos/train_images/label=0/Browse2frame000*.jpg')
)

display( image_df ) 
```

![df_binary.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62653/eabbef6c-9efc-7684-6b5d-40a7ba80114a.png)


# 方法3: PIL + numpy + matplotlib

* 通常のJupyter Notebook上で実施するのと同じ方法

```python
from matplotlib.pyplot import imshow
import numpy as np
from PIL import Image

pil_im = Image.open('/dbfs/databricks-datasets/cctvVideos/train_images/label=0/Browse2frame0002.jpg', 'r')
imshow(np.asarray(pil_im))
```

![PIL.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62653/37fde435-4db6-e224-c568-dd0641441754.png)
ModelerFlowでICOSのCSVを読んでDb2WHに書き込む

CP4DのModelerFlowでICOSのCSVを読んでDb2WHに書き込んでみます。

テスト環境
CP4D 4.0.4

#1 ICOSデータ読込
データ資産ノードを選び開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/60abaf5f-4c66-747b-6953-05aae2012bc9.png)

データ資産の中からICOSのcsvファイルを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/1e996139-3349-6b45-24ce-feb9e60c7f8f.png)

保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/6060aed1-fedc-9855-2323-0262a014d854.png)

#2 Db2への書き込み
データ資産エクスポートを選び開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/91865073-5682-3e4c-9e3b-e0099d81b5bc.png)

エクスポート先に「接続に保存」を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/bf04255b-0df7-2eb5-3e56-c74fd5a100af.png)

接続にDb2WHの接続（例：DB2WHOC_HDM）を選びスキーマ（例：HKWD）を選んだあとに新規の表名（例：COND4N_E104）を入力し更新ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/813f37ff-a202-dbb2-94dc-921719e06066.png)

選択ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/8e805b2d-52d7-40e9-1552-1eb01861f975.png)

保存ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/4c2a2c70-b0e6-7fdc-3f29-febd73750a2d.png)

データ資産エクスポートを右クリックし実行を行う。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/796f9caa-07af-4760-c6d2-6144c019a0fc.png)

成功しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/ac25d910-37a6-ad51-1f3d-0a94b50e47ae.png)

#3 確認
データ資産ノードをもう一つ選び、開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/67262732-cac5-01e8-c264-c30903501ed6.png)

接続（データ資産はない）から作成した表を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/7b48c254-83b3-37d1-52f7-34e5be9eaddb.png)

選択ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/efb7f80d-49e4-6353-e965-1728270ecc09.png)

保存ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/af961212-90bf-91ae-d49d-6ef6c679962d.png)

プレビューします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/1a7aeae9-1258-591f-2a06-b6199cd8b71c.png)


データが書き込まれていることが確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/2379a471-b12f-781e-a2d5-acbd22034b81.png)
【初投稿】初めてのウェブアプリ

#初めてのwebアプリ
新卒研修でPython講座があり、せっかくならpython使って何かwebアプリでも作ってみようと思った大学卒業前の4年生です。
「何かをするには目的を持て」という信念のもとそのアプリでどんな課題を解決したいか考えた結果、「食料廃棄」だと思いつきました。
そこから食料廃棄マッチングプラットフォームなるものをTodoリストっぽく作りました。
Webアプリの名前は「Zerowaste」です。

#仕様
Djangoで作り、Herokuでデプロイするという形で、Boostrapで簡単にデザインしました。

#必要機能
・会員登録
・ログイン
・ログアウト
・食料投稿
とりあえず上記だけで作成しました。
追加の機能はまた、実装したいと思います。

データベースがmediaファイルが必要なのでCloudinary Storageを仕様しております。

#完成品
herokuアプリ丸出しのURLです。
https://zerowaste00.herokuapp.com/

Githubにソースを公開してみるということも初めてしました。
https://github.com/urabale/new-app/tree/master

#参考記事
最初はUdemyで簡単にDjangoとPythonについて学びました
https://www.udemy.com/share/1022PG3@PrRw6lXSNZaFBU14mVIKCa_URVrIamDMV4SXJ72KO58tc9uUg578TUNwR8dbLxZQ/

その後は色々検索しながらデプロイまで出来ました。
参考記事集：
https://qiita.com/frosty/items/66f5dff8fc723387108c
https://mocomo012.hatenablog.com/entry/2020/03/27/131943
https://qiita.com/knakajima3027/items/34b2a105da7cdb411736

ご丁寧な記事を作成していただき本当にありがとうございました。

#反省
当初はAWSでデプロイ予定だったのですが従量課金に少しビビってしまったので次回新しく実装するときはAWSに挑戦します。
また、Djangoだけでウェブアプリを作成するのは現実的でないことを知り次はVue.jsなどのJavascriptフレームワークを学びDjangoと組み合わせて実装したいと思います。

#その他
初学者かつ独学なので間違えてること常識的にあり得ないことなどありましたらご指摘いただけると非常に幸いです。
【Laravel】メール送信方法についてのメモ

## Mailableクラスを使う場合とNotificationクラスを使う場合がある。

Mailableは基本的にメールを送る専用のクラス。Notificationはメール送信以外にもデータベース通知やSMS通知、slack通知なども行えるクラス。メールだけ送りたいならMailableのほうがわかりやすいかも。拡張性なども考えるならNotificationにしたほうがよさそう。

以下が参考にさせて頂いた記事様です。

https://biz.addisteria.com/mailable_notifications/

　
## Mailableクラスを使って送信する方法

以下記事様がわかりやすくまとめてくださっています。

https://zenn.dev/naoki_oshiumi/articles/d5a36a99e686d3

なお、Mailableクラスを作成しなくてもMailファサードを使用すればメールを送信することは可能です。
（そもそもphpなのでmb_send_mail関数などでも可能だと思いますが）

以下、Mailファサードの使用方法についても書かれている参考サイト様です

https://reffect.co.jp/laravel/laravel-send-email#i

なぜ使わなくても送信できるのにMailableクラスを使うのか？
・単一責任の原則 & コントローラの肥大化を防ぐ
・メール送信のタイミングが複数ある場合に使いまわせるから



　
## Notificationクラスを使ってメール送信する方法

参考サイト様

https://www.ritolab.com/entry/210

公式様

https://readouble.com/laravel/8.x/ja/mail.html

　
## ローカルでメール送信テストしたい場合（2022.10/17追記）

Laravel Sail環境ならmailhogを使用するのが最も簡単。
あらかじめenvとdocker-compose.ymlにmailhogの設定が書かれているので
デフォルトであれば　http://localhost:8025/  にアクセスするだけでメールが確認できる。


Sail環境でない場合はmailtrapも便利

https://mailtrap.io/
WSLのUbuntuからAWSのEC2にSSH接続する方法

取り急ぎメモ程度にまとめる。

①AWSにパブリックサブネットを作り、SSH接続の許可をする
②キーとなるpemファイルをローカルに保存
③WSLのユーザーディレクトリに、ローカルに保存したpemファイルをコピー
WSLのUbuntuから見ると、ローカルのユーザディレクトリは以下の場所にあります。
/mnt/c/Users/ユーザ名/
上記は、C:/Users/ユーザ名/と同じ意味です。

pemファイルは、WSL上のどこかにコピーします。
/home/ユーザ名
以下であればどこでもいいと思います。

pemファイルの実行権限をrootユーザのみ、読み取りかつ書き込み可能に変更
sudo chmod 600 pemファイル

※権限を変更しないと、権限がゆるいとエラーが出て接続できなくなります。

ssh -i pemファイルのパス ec2-user@EC2インスタンスのパブリックIP

これで接続できます。
自作テーマWordPress手順書

#インストール
[日本語版WordPress](https://ja.wordpress.org/download/)

#初期設定画面
###データーベース名
作成したデーターベース名
###ユーザー名
root
###パスワード
root

#管理画面へ
```
/wp-login.php
```
#便利プラグイン
* 入れとくと便利
    * query monitor(なんのテンプレートか教えてくれる)
    * admin bar position(バーを下にしてくれる)

#テンプレートタグ
|  種類  |  タグ  |
| ---- | ---- |
|  タイトル |  <?php the_title(); ?>  |
|  head  |  <?php wp_head(); ?>　※headの一番下  |
|  footer |  <?php wp_footer(); ?>　※bodyの一番下  |
|  日付  |  <?php the_time(get_option('date_format')); ?>  |
|  抜粋  |  <?php the_excerpt(); ?>  |
|  著者名  |  <?php the_author(); ?>  |
|  リンク  |  <?php the_permalink(); ?>  |
|  ファイルパス  |  <?php echo get_template_directory_uri(); ?>  |
|  パーツファイル  | <?php get_template_part('includes/footer') ?>   |
|  本文  |  <?php the_content(); ?  |
|  画像(imgタグ全部)  |  <?php the_post_thumbnail(array(32, 32), array('alt' => 'アイキャッチ画像')); ?>  |
|  画像  |  <?php the_post_thumbnail('full', array('alt' => 'アイキャッチ画像')); ?>  |
|  カテゴリー名表示  |  <?php wp_title(''); ?>  |
|  ホームurl  |  <?php echo esc_url(home_url('/')) ?>  |
|  サイトタイトル  |  <?php bloginfo('name') ?>  |
|  サイトキャッチフレーズ  |  <?php bloginfo('description') ?>  |

#カスタム投稿表示
※functions.phpの設定はこちらを参照↓
[functions.phpでカスタム投稿タイプ作成](https://qiita.com/onishishotaro/items/949bd6f7b191312b2573)

```pug
        <?php $args = array('post_type' => 'news', 'posts_per_page' => 6 );$the_query = new WP_Query($args);if ($the_query->have_posts()) : ?>
        ul.home__news-wrap 
        <?php while ($the_query->have_posts()) : $the_query->the_post(); ?>
          li 
            a(href!="<?php the_permalink(); ?>") <?php the_title(); ?>
        <?php endwhile; ?>
        a.btn__more(href="/news") もっと見る
        <?php endif; ?>

```
```
'post_type' => 'news', 'posts_per_page' => 6
```
post_typeは投稿タイプ名
posts_per_pageは表示件数

#カスタムタグ
```php
<?php $tags = get_the_terms($post->ID, 'news_tag');foreach ($tags as $tag) : ?>
   <span class="tag_name"><?php echo $tag->name; ?></span>
<?php endforeach; ?>
```
#カスタムカテゴリー
```php
<?php $terms = get_the_terms($post->ID, 'news_category');foreach ($terms as $term) : ?>
 <span class="category_name">
   <img src="<?php echo get_template_directory_uri(); ?>/img/<?php echo $term->name; ?>.png" alt="">
 </span>
<?php endforeach; ?>
```

#パーマリンク設定
カスタム構造

```
/%year%/%monthnum%/%post_id%/
```

#お問い合わせフォームプラグイン
###MV WP Form

#カスタムフィールドプラグイン
###Advanced Custom Fields

##表示の仕方
```php
<?php the_field('company'); ?>
<?php the_field('age'); ?>
```
#header.php内でトップページとサブページのデザインを切り分ける
```php
<?php if(is_front_page()){;?>
<!-- トップページ -->
<?php }else{;?>
<!-- トップページ以外 -->
<?php };?>
```
###ページ別
```php
is_page("company")
is_archive("news")
is_single("news")
```

#ユーザー権限プラグイン
User-Role-Editor

#まとめ
自分用ワードプレスメモ
日々更新していきます。

#合わせて読みたい
* WordPress
    * [WordPressで初期投稿タイプを非表示にする](https://qiita.com/onishishotaro/items/34ddc9873d94329945a7)
    * [WordPressでカスタム投稿タイプ作成](https://qiita.com/onishishotaro/items/949bd6f7b191312b2573)
自分サーバーでWebPushをやってみた。

# WebPushって何？
- Android端末とかChromeブラウザで、「通知を受け取る」にしておくと、サーバーサイドから通知をプッシュできる仕組みです。
- これを使って、自分サーバー上に通知サイトを用意して、サーバーからのいろんな通知をスマホで受け取ろうという実験です。
- （たとえば、サーバー障害発生などでZabbixのアラートが上がったら自分のスマホに知らせてくれる、的なものです）

# さっそく実装
- 続きは GitHub で

 https://github.com/iruka-git/WebNotifySample

# インストール前提条件
- 自分サーバーはSSL有効でなければなりません。
- Apache + PHP7 が動いているものとします。
- Apacheの設置先ディレクトリは、説明の都合上、 /public/ とします。

# インストール方法
- （１）まず、 上記 GitHubからコードを拾ってください
- （２）PHPのcomposer を使って、minishlink/web-push をインストールします。

$ composer require minishlink/web-push

- （３）サイト公開鍵と秘密鍵を準備します。
- 以下のサイトを使用して、鍵を作成したのち、
- ---> https://web-push-codelab.glitch.me/
- 公開鍵は mysite.js に、秘密鍵は、PushMessage.php にそれぞれ転記してください。（コメント通り）
- （４）mysite.js と worker.js で https://example.com/ となっている行を、自分のサイトのURLに書き換えてください。
- （５）./log/ ディレクトリのパーミッションを www-data に対して書き込み許可にしてください
以上で設置は終わりです

# 動作チェック
- https://自分のサイトのURL/public/  に、パソコンのChromeもしくはスマホからアクセスします。
- （iPhoneは使えません）
- 「Web通知を許可する」のリンクを踏んで、通知を許可してください。
- 一番下の「Web通知のテスト」ボタンで、１０秒後に通知が届けば成功です。

# サーバー側から通知を送るには・・・
 $ php PushMessage.php "送りたいメッセージテキスト"

- で送れます。（送れるはずです）

# 制限事項など
- 通知先のリスト管理は、昔懐かしいPerlで書かれたBBSのような管理方法を使っています
- （./log/client.txt）
- ですので、通知先となる端末数は多くても１０台以内ということでお願いします。
- セキュリティまわりのチェックをあまりやっていませんので、まさかの実運用に使われる場合は各自で対策、メンテナンスお願いします。
- Zabbixとの連携は、次の課題ということにして先送りいたします。

# 参考にしたサイト
-JSとPHPでWebPushを送信するWebアプリケーションを作ってみる

https://zenn.dev/nnahito/articles/fd2c8b0ad0d19a

上記サイトを参考にさせていただきました。ありがとうございます。
SFTP ファイル転送の自動化を LFTP で行う

# はじめに
Linux 標準の sftp コマンドは自動化させるとパスフレーズ入力が困難だったりします。
そこで高機能なファイル転送プログラムの LFTP を使ってみました。
# 使い方
## インストール
```shell-session
$ sudo dnf install lftp
```

※RHEL 8 互換環境の場合

## 自動化スクリプトファイル設定例
### 認証方式：公開鍵
サーバー：192.168.0.1
ユーザー：fuku
秘密鍵パスフレーズ：inuha
ダウンロードファイル：dog.jpg
フィンガープリントの自動確認：有効

```text:lftp_scitp
set sftp:auto-confirm yes
open -u fuku,inuha sftp://192.168.0.1
get dog.jpg
exit
```

### 認証方式：パスワード
サーバー：192.168.0.1
ユーザー：fuku
パスワード：nekoha
ダウンロードファイル：cat.jpg

```text:lftp_scitp
open -u fuku,nekoha sftp://192.168.0.1
get cat.jpg
exit
```


## 実行
スクリプトファイルを -f オプションで指定するだけで実行できます。
```shell-session
$ lftp -f lftp_script
```
Laravel開発環境構築をdockerを使って構築

###内容
Laravel開発環境を構築する際に積んでしまいかなり時間を取ってしまったので、積んでしまったところを忘れないための備忘録記事です。

Dockerを使ってLaravel環境環境でLaravelのデフォルト画面、データベース接続、マイグレーションまでです。

###環境
・Laravel8.X
・docker20.10.10
・php7.X
・apache
・Mysql8.X

###ディレクトリ構成
```
root/
　├ app(Laravelプロジェクト)/
　├ docker/
　│　└ Dockerfile
　└ docker-compose.yaml
```
###1、Dockerfileの作成
まず最初はDockerfileを作成していきます、元であるベースのイメージを独自にカスタマイズするために必要なファイルです。自分で何か変えたい内容があればこのファイルに記述します。

今回dcokerディレクトリを作成して、dockerディレクトリ配下にファイルを作成します。

```Dockerfile
FROM php:8.0-apache
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
RUN apt-get update && apt-get install -y \
    git \
    && docker-php-ext-install pdo_mysql
    
RUN sed -i 's!/var/www/html!/var/www/app/public!g' /etc/apache2/sites-available/000-default.conf
```

###docker-compose.yamlの作成
larabel-sample-1配下にファイルを作成し、以下の記述をします。

```docker-compose.yaml
version: '3'
services:
  app:
    build: ./docker
    ports:
      - 80:80
    volumes:
      - ./app:/var/www/app
    working_dir: /var/www/app
  db:
    platform: linux/x86_64
    image: mysql:8.0
    ports:
      - 3306:3306
    environment:
      MYSQL_DATABASE: database
      MYSQL_USER: user
      MYSQL_PASSWORD: pass
      MYSQL_ROOT_PASSWORD: password
```
###laravelのインストール
これまでの作業が終わったらコンテナを作成して、laravelを導入していきます。
```docker compose up -d```でコンテナを立ち上げます。

コンテナが立ち上がったら```docker exec app bash```でappコンテナに入ります。
var/dump/appにいる状態で```composer create-project laravel/laravel ./
```でapp配下にぷジェクトを作成します。

###Laravel表示確認
ここまで出来たら、ブラウザ上でlaravelのデフォルト画面が表示できます。
URL```http://localhost:80```から下記の画面が確認できたら、laravel導入完了です。(Laravel8.xのため該当バージョンのデフォルト画面が出てくるとこに注意)

![laravel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1177832/5bbee5d4-f1d0-8e9e-88f0-fc1cf95fdd8e.png)

###データベース接続確認
次にデータベース接続確認を行います。
Laravelからデータベースに接続するには、Laravel内の.envファイルに以下の設定を記述します。（docker-compose.yamlでdbコンテナに設定した値です）

```.env
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=database
DB_USERNAME=user
DB_PASSWORD=pass
MYSQL_ROOT_PASSWORD: password
```

これでデータベース接続が可能なはずですので、```php artisan migrate```でマイグレージョンしてみてください。

```terminal
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (384.65ms)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (197.15ms)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (207.88ms)
Migrating: 2019_12_14_000001_create_personal_access_tokens_table
Migrated:  2019_12_14_000001_create_personal_access_tokens_table (361.04ms)
```

以上です。
Vue-CLIベース publicフォルダにある.jsonファイル を起動直後から使いたい



# 経緯

作業としては、もともとJavascript+jQuery で記述されていたあるWebアプリケーションをモダンなVueにリファクタリングしようとしていました。
このWebアプリケーションは、工場に納品する装置に付随して提供されるもので、納入先ごとにタイトルや、一部機能の有効無効を切り替える必要がありました。

従来の設定ファイルの運用としては、以下のとおり。

1. 大まかに2つの設定ファイル(.json)で構成されていた。
+ 1つは内部的な設定ファイル
+ もう1つは納入先ごとに変更するための設定ファイル

## 新システムの前提条件

+ Vue-CLI で作成した Vue2 のシステム
+ Node.js ver.16.13.x
+ Vuexは利用していない


# 困ったこと

1. publicフォルダに置いた設定ファイルが、mounted()処理までに間に合わない

### 設定ファイルの配置場所

Vue-CLIで作成したプロジェクトでは、主にwebpackでビルド対象となる src/ フォルダと、対象とならない public/ フォルダがある。
内部的な設定ファイル(inner-config.json)は、バンドル対象の src/assets/ へ配置した。
一方、納入先ごとに変更するための設定ファイル(config.json)は、開発者以外が調整する項目なので、webpackのバンドル対象とはできず public/ へ配置した。

```
├ public/　　　　　　←このフォルダの下は、npm run build 後そのままコピーされる
│　├ config.json
│　├ index.html
│　└ favicon.ico
├ src/　　　　　　　　←このフォルダの下は、webpackによりバンドル(1つのファイルにまとめること)の対象となる
│　├ assets/
│　│　└ inner-config.json
│　├ view/
　　　：
　　　：
```

### 設定ファイルのロード
#### inner-config.json → importで即時に取得
src/ 以下にあるファイルは、import文で扱うことができる。webpackでバンドルされているということは、もうメモリ上に展開されているので、ロードに時間がかかるわけもなく、すぐに設定が使える。

``` App.vue
  import innerConfig from '@/assets/inner-config.json'

  innerConfig.paramA ...   // この時点で使える
```

#### config.json → axiosで非同期的に取得
一方、public/ 以下にあるファイルは、axiosを使って読みに行くのが一般的らしい。axiosといえば、非同期で動く。created()時にaxiosでキックしても、mounted()の処理が終わってからようやく読み込み結果が得られる状態だった。

```App.vue
	axios
	.get("config.json")
	.then(response => {
		response.data.paramB    // このthen()に指定した無名関数は非同期で呼ばれる
	})
```

### UIの構築

各コンポーネントは、mounted()をきっかけに設定がある前提でUIを構築した。

### 起こったこと

上記の結果、public/ に配置した設定ファイルが、起動直後に読めず、表示が崩れた。

# 対策

### index.htmlでscriptタグで読み、グローバル変数に用意する（不採用）

深くは検討していないが、従来できていたんだからできるのかもしれない。しかし、せっかくVueを使っているのに、古臭いコードがまぎれると汚くなるし、設計資料も多く残さにゃならないから、却下した。

### UIの構築をaxios読み込み後にする（不採用）

これが、正解なんだろうが、起動までに毎回、若干時間がかかるのが許容できなかった。これも却下。

### axios読み込み後にCookieに設定保存、2回目以降はCookieの設定を使う

以下の手順を採用した。

1. デフォルト設定値用意
1. __< created() > 【Cookieに設定値がある場合】__Cookieの設定値に上書き
1. __< created() >__ axiosで、config.jsonを読み込み開始
1. __< mounted() >__ 設定値をもとにUI構築
1. __< axios.then()のコールバック > 【Cookieの設定値とaxios読み込み設定値が異なる場合】__Cookieに設定値を保存し、リロード

# おわりに

今回は、結構作りこんだあとに対処したため、こんな処理に落ち着いた。webpackバンドルしていない設定値を同期でとる方法が他にあるなら、だれか教えてほしい。いや、本当に。
【IBM Security Verify 】ダウンロードしたレポートのフォーマット定義について

# はじめに
IBM Security Verify のAPIを利用して、レポートをダウンロードできます。
各レポートに含まれるオブジェクトがなにを表しているか確認方法についてご紹介いたします。

# ダウンロードしたレポートの中身について
次のようにJSON形式のデータとなります。

```sample.json
～割愛～
 "data": {
         "sourceinstance": "oidc",
         "subject": "xxxx",
         "origin": "xxxx",
         "cause": "Successful login",
         "devicetype": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:96.0) Gecko/20100101 Firefox/96.0",
～割愛～
```

# 各オブジェクトの意味について

マニュアルにレポートごとにオブジェクトが何を表しているか記載がありました。

【認証レポートの例】

|![qiita1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/e0f197cf-6fc1-2511-8605-e175b39c9511.png)
|:--|

レポートのサブトピックにペイロードとして記載さています
- [認証イベント・ペイロード](https://www.ibm.com/docs/ja/security-verify?topic=report-authentication-event-payload)
- [管理アクティビティー・イベント・ペイロード](https://www.ibm.com/docs/ja/security-verify?topic=report-admin-activity-event-payload)
- [MFA イベント・ペイロード](https://www.ibm.com/docs/ja/security-verify?topic=report-mfa-event-payload)
- [アプリケーション使用 SSO イベント・ペイロード](https://www.ibm.com/docs/ja/security-verify?topic=report-application-usage-sso-event-payload)
- [サービス・イベント・ペイロード](https://www.ibm.com/docs/ja/security-verify?topic=details-service-events-payload)

# 最後に
IBM Security Verifyのレポートのフォーマット定義の確認方法についてご紹介しました。
SequelProのカラム検索のショートカットキー


##カラム検索のショートカットキー

Command（⌘） + option（⌥） + Control（⌃） + N

DBからカラム名を検索したい時は、このショートカット入力後に
表示される、ナビゲーターの検索入力欄にカラム名を入力すればDB内に
存在するか探してくれる。
[py2rb] lxml.etree

# はじめに
移植やってます。
( from python 3.7 to ruby 2.7 )
# lxml.etree (Python)
```python
from lxml import etree

parser = etree.XMLParser(remove_comments=True, ns_clean=True)
tree = etree.parse(source, parser=parser)
```
データをxml形式で取り扱いますので、外部ライブラリである`lxml`が使用されます。

https://lxml.de/apidoc/lxml.etree.html

> classlxml.etree.XMLParser(self, encoding=None, attribute_defaults=False, dtd_validation=False, load_dtd=False, no_network=True, ns_clean=False, recover=False, schema: XMLSchema = None, huge_tree=False, remove_blank_text=False, resolve_entities=True, remove_comments=False, remove_pis=False, strip_cdata=True, collect_ids=True, target=None, compact=True)

|オプション|初期値|備考|
|:--|:--|:--|
|remove_comments|False|コメントを破棄する|
|ns_clean|False|冗長な名前空間宣言をクリーンアップします|

# rexml (Ruby)
まずは、標準ライブラリである`rexml`を調べました。

https://ruby.github.io/rexml/REXML/Element.html#class-REXML::Element-label-Children

```ruby:rexml.rb
xml_string = <<-EOT
<root>
  <ele_0/>
  text 0
  <!--comment 0-->
  <?target_0 pi_0?>
  <![CDATA[cdata 0]]>
  <ele_1/>
  text 1
  <!--comment 1-->
  <?target_0 pi_1?>
  <![CDATA[cdata 1]]>
</root>
EOT
context = {ignore_whitespace_nodes: :all, compress_whitespace: :all}
d = REXML::Document.new(xml_string, context)
root = d.root
root.children.size # => 10
root.each {|child| p "#{child.class}: #{child}" }

"REXML::Element: <ele_0/>"
"REXML::Text: \n text 0\n "
"REXML::Comment: comment 0"
"REXML::Instruction: <?target_0 pi_0?>"
"REXML::CData: cdata 0"
"REXML::Element: <ele_1/>"
"REXML::Text: \n text 1\n "
"REXML::Comment: comment 1"
"REXML::Instruction: <?target_0 pi_1?>"
"REXML::CData: cdata 1"
```
`<!-- -->`を読み込まないか、`"REXML::Comment:`を出力しなければ、目的は達成できそうです。
# メモ
+ Python の lxml.etree を学習した
+ 百里を行く者は九十里を半ばとす
【Python】propertyを使ったgetter/setterの書き方

**property**を使った```getter/setter```の書き方についてメモしておく。
**property**は、クラス外部からはインスタンス変数のように参照することのできる関数のこと。

# 基本的な書き方
**property**を使った```getter/setter```の基本的な書き方は、以下のようになる。

```python
# getterの書き方
@property
def 変数名(self):
    return self.変数名

# setterの書き方
@変数名.setter
def 変数名(self, value):
    self.変数名 = value
```

# サンプル
簡単な```getter/setter```を使ったサンプルプログラム書いてみた。
```getter```だけを記述して、値を変更されないようにしたり、下記のように```setter```に値チェックなどを書くことができる。
また、Pythonでは```__```(アンダースコア2つ)は言語仕様として、privateなメンバを意味する。

```python
class Student:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    @property
    def name(self):
        return self.__name

    @property
    def age(self):
        return self.__age

    @age.setter
    def age(self, age):
        if age < 0:
            raise ValueError("年齢が不正です")
        self.__age = age

student = Student("Ryota",18)
student.age = 20
print(student.name)    # Ryota
print(student.age)     # 20

# ageに不正な値を入れた場合
# student.age = -1 
# ValueError: 年齢が不正です

```
科学的な勉強法

###エビングハウスの忘却曲線
勉強が苦手な筆者は現在英語を学習中であります。
実は英語に対して苦手意識が強く、中学英語から復習を行っている状況であります。

できれば土台を作り上げ、基礎を定着させたいと考えております。

筆者の強みでもあり、弱みでもある__忘れやすさ__とどう向き合えばいいのか...
と言いますと、せっかく学習をしたのに翌日にはほぼ忘れてしまいます。

何かいい学習方法はないのか...!!
諦めるか...
否、まだ諦めるには早い!!

そんな時はコーレッ!!
__エビングハウスの忘却曲線!!__

という訳で改めてこのエビングハウスの忘却曲線とは何ぞやという事で、図を書いてみました!!

![My First Board (7).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2188773/b3dfb73e-16aa-d366-7488-15c4f6ceb194.jpeg)

おわかりいただけただろうか...

つまり
その日に覚えた事は、たった1日経過するだけでもほとんど忘れるよ！という事が
この図から読み取っていただけるかと存じます。

そして経過すればするほど、覚えた事は更に忘れてしまいます...。

ただ、復習をするベストなタイミングというのも
このエビングハウスの忘却曲線の図から読み取る事ができます。


###Googleスプレッドシート
エビングハウスの忘却曲線を活用し、
復習サイクルの仕組みを事前に作ってしまえば
科学的な勉強法と言えるのではないか？

という事で、
誰もが使える便利ツールの1つ
Googleスプレッドシートで復習サイクルを作ります！
例としてまた図を載せておきます！


![2022-01-21 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2188773/b824c902-ad50-85bd-594f-14cacf943dea.png)






筆者は『中学英語をひとつひとつ』という参考書を使用し1から英語の学習中であります。
lesson1,2,3,4,5・・・というセクションがあるので、
2つlessonを1日で学習していくペースで設定しました。

学習したところは塗りつぶしていく事により一目で進捗状況も把握できて、
モチベーションの維持にも繋がるのではないかと考えております。

筆者が学習中である英語を例に
説明をしてきましたが、他の分野の学習にも
『エビングハウスの忘却曲線』と『Googleスプレッドシート』による
復習サイクルは応用できると思います。

実際に筆者がこの方法で英語を覚えられるのかどうかを、
今後TOEIC等を受験し結果報告を行おうかな～と検討中でございます。

これから何か学習、習得をされる誰かのお役に立てれば幸いです。

他にもオススメの勉強方法等があればアドバイスいただけると嬉しいです。
最期までご一読いただきありがとうございました！
Docker in Javaのメモリ消費がコンテナの制限を超えていた話

# 発端
amazoncorretto:11ベースのコンテナでJava(Kotlin)のアプリケーションを稼働させました。
ホストサーバーのメモリは4G(実際に使用できるのは3.9G程度)
コンテナにはcpus: 2、mem_limit: 2.5gでリソースの制限をかけていました。

# 違和感
アプリケーションに負荷がかかるとメモリ使用率が2.5Gどころか3G超に、そしてサーバーが危篤(ピンチ)
危機が過ぎ去った後、開発環境で色々と検証

JDK11なのでUseContainerSupportがデフォルトオンになっているはずと思いこのようなソースを用意してコンテナ内で実行

```A.java
public class A {
  public static void main(String[] args) {
    System.out.println("Version: " + System.getProperty("java.version"));
    System.out.println("availableProcessors: " + Runtime.getRuntime().availableProcessors());
    System.out.println("maxMemory: " + Runtime.getRuntime().maxMemory()/1024/1024 + "M");
  }
}
```

結果は詳細に残すのを忘れてしまったのですが、
maxMemoryは980Mを記録

980M・・・？
2.5Gのコンテナにしては数値が大きいような・・・？
(デフォルトはメモリ/4の数値になる記憶)

ここから色々JVM argsを見直したりDockerfileを見直したりの日々

# 解決
docker-compose.ymlで以下のフォルダをマウントしていたことが原因

```
    volumes:
      - "./sys/fs/cgroup:/sys/fs/cgroup:ro"
```

この部分を削除してからコンテナ再起動
もう一度A.javaを実行

```
bash-4.2# java A
Version: 11.0.14
availableProcessors: 2
maxMemory: 640M
```

```
bash-4.2# java -XX:MaxRAMPercentage=50 A 
Version: 11.0.14
availableProcessors: 2
maxMemory: 1280M
```

```
bash-4.2# java -XX:MaxRAMPercentage=75 A 
Version: 11.0.14
availableProcessors: 2
maxMemory: 1920M
```

お疲れ様でした。

# 終
何故あのディレクトリをマウントしていたのかが思い出せない・・・・
はじめての投稿

初めて投稿する。  
まず挙動確認から。

###Ubuntuコマンドについて
よく利用するUbuntuのコマンドについて。
#### 初回投稿

---
**これはまず最初にすることですね。**

```
sudo apt update && sudo apt upgrade -y && sudo apt autoremove
```

リンクは、  
 [VaccImage](https://github.com/YohYasushi/VaccImage "VaccImage")

などなどです。  
Markdownにも慣れていかないと、ですね。