OmniAICreator/Qiita-1.07M huggingface dataset:
【初心者向け】文字コードをなぜ知っておく必要があるのか

<!--

## 技術記事のタイトル

最も伝えたいこと。
簡潔かつ分かりやすく過不足ないタイトルを考えましょう。

### 【 】(墨付き括弧)

- 【言語やサービス】
    - 例1.【Python】すぐにpytestで単体テストを実行するまでの手順
- 【言いたいこと】
    - 例1.【必見】Objectはどこに消えた？
- 【前提】
    - 例1.【個人開発】○○を○○できるサービスをリリースしました
    - 例2.【初心者向け】Reactとはそもそも何なのか説明します
- 【続き物の番号】
    - 例1.【2024年版】新入社員向け研修資料を公開します
    - 例2.【環境構築編】Windows11でPythonを実行するまで

【前提】詳しいタイトル【言語やサービス】のように、複数を併用するパターンもあります。

-->

## はじめに
<!--
何についての記事なのか、誰に向けた記事なのかを簡単に説明しましょう。
-->
「上司から文字コードは頭に入れといた方がいいよ〜」と言われていた理由が最近分かったので忘備録として記事にしました。


### この記事でわかる・できること
<!--
読んだら何がわかるようになるのか、何ができるようになるのかを書きましょう。
-->

- そもそもなぜ文字コードを知らないといけないか


### この記事の対象者
<!--
誰に向けた記事なのかを明確にすることで読者に選んでもらいましょう。
-->

- 初心者





## 文字コードを知っておかなければならない理由
<!--
章全体の要約や、何について書くのかをここに書きます。
記事が長い時や資料として作るときは番号を振ることをおすすめします。
章を増やすときは章から項までをコピーしてください。
-->
早速ですが結論です。
・環境によって文字コード（改行コードも）は変わるから！
（文字コード、改行コードが変わることで、文字化けが起きてしまっていないか、（テストの時など）想定通りの内容になっているかを気にしないといけないらしいです。）



### 
<!--
記事の主要な部分です。ここに思い思いの内容を書いていってください。

画像やGIFがあると分かりやすいです。
画像があるとUIが変わったとしても読者がアタリをつけて対応しやすくなります。

コードを記載する場合は必ずコードブロックを使いましょう。
バッククオート3つで囲んでください。
```python:表示名

    print('Hello World')
    
```
-->
#### 具体例
　私が業務上遭遇した場面だと、テストに使うテキストファイルをWindous上で作成しUNIXにアップロードする際、文字コード、改行コードをUNIXに合わせてテキストファイルを作成する必要がありました。
私の使用している環境だと以下の設定になっていました。

「Windows 　文字コード：Shift-JIS　改行コード：CRLF」
「UNIX　　　文字コード：UTF-8　改行コード：LF」

Shift-JISをUTF-8にCRLFをLFに、といった感じでUNIXに設定を合わせることを行いました。

<!--
より詳細な内容を書いたり、事例を挙げたりするときに使います。
- 節の内容の列挙
- 節の補足事項
- 例外
-->





## おわりに
<!--
どちらかを書きます。あってもなくても良いです。
-->
超初歩的な内容かもしれませんが私は調べる際に切り口、キーワードも分からないということが多々あるので、同じような状況の方にとって今回の内容が少しでもヒントになればと思います。
SQSの概要　SAA範囲内

# SQS

## 暗号化

サーバー側の暗号化を設定することができる

デフォルトでは有効になっている

### キーのタイプが選択することができる

SQS自体が作成、管理、使用する暗号化キーと

KMSと連携して暗号化を自分で管理することも可能

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/0fc15814-c513-64f5-9901-c092ecd84c80.png)


## SQSアクセスポリシー

ベーシックタイプとアドバンストがある

ベーシックタイプはシンプルな設定です。

キュー所有者のみにアクセスを許可したり、

指定したAWSアカウントを設定するだけであれば、ベーシックを使います。

アドバンストについては、IAMポリシーのようにJSONオブジェクトを使用して、高度なアクセスポリシーを定義することが可能です。

アクセスポリシーを設定する際は、

キュー自体に送信できるユーザー

キューを受診できるユーザー

それぞれに定義します。

## デットレターキューの設定

### デットレターキューとは

デッドレターキュー（Dead Letter Queue, DLQ）とは、メッセージキューシステムにおいて、正常に処理できなかったメッセージを特別に保存しておくための専用キューのことです。メッセージが複数回リトライされても処理に失敗した場合や、一定の保持期間を超えた場合などに、そのメッセージは通常のキューからデッドレターキューに移動されます。これは、メッセージ処理の障害やエラーの分析、再処理のために使用されます。

### 各種設定

許可ポリシーの再実行では、この作成しているキューをデットレターキューとして使用できるソースキューを特定する画面です。

デットレターキューは、有効にした場合、処理に失敗したものを他のキューに送るための設定です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/7c47913e-e1d3-e872-611c-100e2fd7865d.png)


## 基本的なユースケース

サービスの疎結合に役立つことが大きな役割です。

LambdaやEC2でアプリケーションを構築して、処理の前にSQSを挟むことで、アプリケーション側でエラーが発生してもSQSでメッセージを保持することができるので、処理内容の情報を失うことを防ぐことができます。

SNSを使って、SQSにメッセージを送ることができます。
１つのメッセージで複数のマイクロサービスが動く場合、サービスごとにSQSを構築して
１つのSNSでメッセージを同時に複数のSQSにパブリッシュすることで、同時にサービスがSQSからポーリングして処理をすることができます。


AWSの試験でも、lambdaと連携してマイクロサービスを構築することや
SNSとの連携もよく出るので、試験を受ける際も押さえておきましょう。


今度はlambdaを使って、疎結合の簡易的なアプリケーションでも作りたいなと思ってます。
macでPythonを使うための環境構築 バージョン管理

macでPythonを利用するときのバージョンの切り替えの手順をまとめました。

Homebrewは、macOSで使えるパッケージ管理ツールです。
pyenvは、Pythonのバージョン管理ツールです。

シェル：`zsh`
別のシェルを使っている方は、設定ファイル`.zshrc`を適宜読み替えてください。

## Homebrewでpyenvをインストール

Homebrewを久々に使う場合
`brew update`
`brew list`
`brew uninstall <package>`
`brew upgrade`

Homebrewでpyenvをインストール
`brew install pyenv`

## pyenvのPATHを通す
nano ~/.zshrc
```
export PATH="$HOME/.pyenv/bin:$PATH" #追加
eval "$(pyenv init --path)" #追加
eval "$(pyenv init -)" #追加
```

## シェルを再起動
`exec "$SHELL"` または `source ~/.zshrc`

## pyenvでPythonのバージョン切り替え
```
% pyenv versions
* system (set by /Users/a/.pyenv/version)

% pyenv install 3.12.0

% pyenv versions
* system (set by /Users/a/.pyenv/version)
  3.12.0

% pyenv global 3.12.0
  system
* 3.12.0 (set by /Users/a/.pyenv/version)
```

# Pythonのバージョン確認

`python -V`
zsh: no such file or directory: /usr/local/bin/python3

なぜか別のディレクトリを指していました。

`which python`
python: aliased to /usr/local/bin/python3

エイリアスが設定されてそうなので、削除します。

## エイリアス削除
`alias python`
`unalias python`

### 設定ファイルにエイリアスを追加する設定がある場合も削除します。
nano ~/.zshrc
```
alias python=/user/local/bin/python3 #削除
```
削除しないと再読み込みするたびに、エイリアスがつきます。

## Pythonのバージョン確認

`python -V`
Python 3.12.0

pyenvで追加したバージョンが使えるようになりました。

## 補足
`pyenv global system`
systemでPythonを利用する時は、python3を明確に指定しないとエラーになります。

```
% python -V

pyenv: python: command not found

The `python' command exists in these Python versions:
  3.12.0

Note: See 'pyenv help global' for tips on allowing both
      python2 and python3 to be found.
```

```
% python3 -V
Python 3.9.6
```
【機械学習/深層学習】G検定（ジェネラリスト検定）の振り返りについて

G検定（ジェネラリスト検定）を、受けた際の振り返りの学びを備忘としてメモします。
色々な考え方があり、繰り返し復習して案件/プロジェクトに還元していきたいです。

## 公平性（Fairness）
機械学習モデルが特定のグループや個人に対して偏りなく、公平に機能することを指します。モデルのバイアスを検出し、修正することで、公平性を確保します。

## 次元圧縮（Dimensionality Reduction）
高次元データを低次元に変換し、データの本質的な特徴を保持しつつ、計算効率を向上させる手法です。主成分分析（PCA）やt-SNEなどが代表的な手法です。

## BERTの事前学習（Pre-training）
BERTは、大量のテキストデータを用いて、マスク化言語モデル（MLM : Masked Language Model）と次文予測（Next Sentence Prediction）のタスクで事前学習されます。これにより、文脈を理解する能力を獲得します。

##  ゼロショット学習（Zero-shot Learning）
学習時に見たことのないクラスやタスクに対しても、既存の知識を活用して対応する能力を指します。例えば、BERTのようなモデルは、事前学習で得た知識を活用して、新しいタスクにも適応できます。
IBM

## Colaboratory（Colab）
Googleが提供するクラウド上のJupyterノートブック環境で、Pythonコードの実行や機械学習モデルの開発・実験が可能です。

## RLHF（Reinforcement Learning from Human Feedback）
人間からのフィードバックを活用して、強化学習エージェントの行動を最適化する手法です。これにより、エージェントの意思決定が人間の期待に沿うように調整されます。

## SGD（Stochastic Gradient Descent）
機械学習モデルの最適化手法の一つで、ランダムに選ばれたデータサンプルを用いて勾配を計算し、モデルのパラメータを更新します。計算効率が高く、大規模データセットにも適しています。

## NeRF（Neural Radiance Fields）
ニューラルネットワークを用いて、3Dシーンの視覚的表現を生成する手法です。異なる視点からの2D画像を入力として、3D構造を再構築します。

## AdaBoost（Adaptive Boosting）
複数の弱い学習器（精度の低いモデル）を組み合わせて、高精度な予測を行うアンサンブル学習手法です。各学習器の誤分類に重点を置いて次の学習器を訓練し、全体の性能を向上させます。

## バッチ正規化（Batch Normalization）
ニューラルネットワークの各層において、ミニバッチごとに入力を正規化する手法です。これにより、学習の安定性が向上し、収束が速くなります。

## ドメインランダマイゼーション（Domain Randomization）
シミュレーション環境で、環境のパラメータをランダムに変化させることで、モデルの汎化性能を高める手法です。これにより、実世界での予測精度が向上します。

## トリプレット損失（Triplet Loss）
アンカー、ポジティブ、ネガティブの3つのサンプル間の距離関係を学習する損失関数です。アンカーとポジティブの距離を縮め、アンカーとネガティブの距離を広げることで、効果的な埋め込み空間を構築します。

## F値（F-measure）
分類モデルの性能評価指標で、精度（Precision）と再現率（Recall）の調和平均を取ったものです。モデルのバランスの良さを評価する際に用いられます。

## VAE（Variational Autoencoder）
生成モデルの一種で、データの潜在変数を確率的にモデル化し、新しいデータの生成やデータの圧縮に利用されます。

## コントラスト損失（Contrastive Loss）
類似したサンプル間の距離を縮め、異なるサンプル間の距離を広げることで、効果的な特徴表現を学習する損失関数です。

## CLIP（Contrastive Language-Image Pre-Training）
OpenAIが開発したモデルで、画像と言語のペアを用いて事前学習を行い、ゼロショットでの画像分類や画像検索など、多様なタスクに対応可能です。
namespaceとは

# Namespace
Namespaceと検索すると名前空間という言葉が出てきた。
### 名前空間とは？
p265
>クラス名の予期せぬ衝突を防ぐ`「名前空間（ネームスペース）」`を作る場合によく使われます。たし、`名前空間を作る場合はクラスよりもモジュールが使われることが多い`です。名前空間やモジュールについては第８章で説明します。
* 名前空間とnamespaceは同じのようだ。
* 名前空間はクラスよりもモジュールが使われることが多いです。

# 名前空間を分けて名前の衝突を防ぐ
> 自分だけ使う小さなプログラムを書いているうちはあまり問題になりませんが、大規模なプログラム>や外部に公開するライブラリを作ったりするときはクラス名の重複が問題になることがあります。例えば、ある人が「野球の二塁手」という意味でSecondクラスを定義したとします。
>```rb
>class Second
>  def initialize(player, uniform_number)
>    @player = player
>    @uniform_number = uniform_number
>  end
>end
>```
>またある人は「時計の秒」という意味でSecondクラスを定義しました。
>```rb
>class Second
>   def initialize(digits)
>     @digits = digits
>   end
> end
>```

* 同じ名前のクラスを同時に使用する場合に区別する必要がある

p304
>こんな時に登場するのが「名前空間（ネームスペース）」としてのモジュールです。`モジュール構文の中にクラス定義を書くと「そのモジュールに属するクラス」という意味`になるため、同名のクラスがあっても外側のモジュール名さえ異なっていれば名前の衝突が発生しなくなります。
>
>```rb
> module Baseball
>   class Second
>     def initialize(player, uniform_number)
>       @player = player
>       @uniform_number = uniform_number
>     end
>   end
> end
>=> :initialize
> module Clock
>  class Second
>     def initialize(digits)
>       @digits = digits
>    end
>   end
> end
>=> :initialize
> Baseball::Second.new("Alice", 13)
>=> #<Baseball::Second:0x0000000106a8d318 @player="Alice", @uniform_number=13>
> Clock::Second.new(13)
>=> #<Clock::Second:0x0000000106498598 @digits=13> module Baseball

* モジュールを使うことによってクラスを同じ名前にしても判別に問題なくなる

# 名前空間でグループやカテゴリを分ける
>名前空間は名前の衝突を防ぐためだけではなく、クラスのグループ分け／カテゴリ分けをする目的で使われる場合もあります。クラスが何十、何百もあるような大きなプログラムになってくると、カテゴリ別にモジュール（名前空間）を作って整理しないと、どれがなんのクラスなのかパッと把握しにくくなるためです。
...
このように、大規模なプログラムや不特定多数の開発者が利用する外部ライブラリでは、モジュールは名前空間を作成する目的でもよく使われています。

* 用途によってrailsのモジュールで名前空間を守る
* なんのクラス、モジュールをどうするかをわかりやすくしている。

# ネストなしでも名前空間つきのクラスを定義する
>名前空間として使うモジュールがすでにどこかで定義されている場合は、モジュール構文やクラス構文をネストさせなくても、”モジュール名::クラス名"のような形でクラスを定義することもできます。
>```rb
> module Baseball
> end
> 
> class Baseball::Second
> ...
> end
>```

https://gihyo.jp/book/2017/978-4-7741-9397-7

# 感想
rails apiを調べるとnamespaceという言葉が出てきたので理解しかった。

rails apiにおいて例えばActionDispatchをみるとnamespaceの欄にいつくものモジュールとクラスがある。つまりそれらの名前の衝突を防ぎ、カテゴリ・グループ分けしていることがわかった。
【React】スクロールバーのあるDrawerをスクロールして閉じた後、再表示時に先頭に戻っているようにしたい

## 背景

クマの出没場所を全国規模で登録できるアプリを作成中の事象です。

https://kumapdigital.com/

下のgifのように、スクロールバーが表示されるDrawerメニューを実装したところ、下までスクロール → 登録ボタン押下 → 再表示時した後に、先頭に戻らせたい…という願望が生じました。

（登録したデータはテスト環境のもので、実際に起きたことではありません）
![scroll is not good.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3927117/5fc67ec1-1bd3-ba83-0d33-3eea53076250.gif)

## 動作環境

* node.js　ver 18.18.2
* next.js　ver 14.0.3
* react　ver 18
* mui/material　ver 5.16.7 


## 試したこと

* Drawerの初期表示時に `scrolTo` でトップに戻させる
* 閉じるボタン、登録ボタンを押したときに、 `scrllTo` でトップに戻させる

いずれも再表示時、トップに戻るようにはなりませんでした。同期処理で表示 → スクロール の順序を確定させれば可能かもしれませんが、そこまで難しく考えたくない…という願望もありました。

## 解決策

keyを用いたコンポーネントの再レンダリングを利用します。
参考：https://ja.react.dev/learn/preserving-and-resetting-state#resetting-a-form-with-a-key

```jsx
type Props = {
    onRegisterClick: () => void;
    onClose: () => void;
};

export function PlaceDrawer(props: Props) {
    const drawerKey = useRef<number>(0);

    return (
        <>
            <Drawer key={drawerKey.current}>
                <Box>
                    <Grid container spacing={2} sx={{ marginTop: "24px" }}>
                        <Grid item xs={6}>
                            <Button
                                onClick={() => {
                                    props.onClose();
                                    // HACK: クリック時にスクロールをトップに戻すのが困難なため、コンポーネント自体の再レンダリングで対応
                                    drawerKey.current = drawerKey.current + 1;
                                }}
                            >
                                地図に戻る
                            </Button>
                        </Grid>
                        <Grid item xs={6} sx={{ textAlign: "right" }}>
                            <Button
                                onClick={async () => {
                                    props.onRegisterClick();
                                    // HACK: クリック時にスクロールをトップに戻すのが困難なため、コンポーネント自体の再レンダリングで対応
                                    drawerKey.current = drawerKey.current + 1;
                                }}
                            >
                                登録する
                            </Button>
                        </Grid>
                    </Grid>
                </Box>
            </Drawer>
        </>
    );
}
```

（登録したデータはテスト環境のものです）
![scroll is so good.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3927117/17572277-102f-5ea7-9033-91c6f9433ddf.gif)

keyが変更された際、コンポーネントは再レンダリングされる（違うものとして扱われる）ため、 `PlaceDrawer` が再表示された時には先頭に戻った状態になります。
再レンダリングがパフォーマンスに影響を与える可能性（要検証）もありますが、個人開発のレベルであれば上のような方法でも良いのかなと思います。
関西kaggler会体験記

# 自己紹介

普段は趣味で競技プログラミングや機械学習をしている大学生です。現在B2です。

日本語力が乏しいのでもしかしたらかなり読みにくい文章になってしまっているかもしれません。すみません

# 本題
LT会は三部構成でした。

第一部は初心者にもわかりやすいような（？）内容でした。自作キーボードの話から、コンペの取り組み方、社内でのkaggle普及方法の提案など内容は多岐にわたりました。

次に第二部ではGMの方の発表が多く、各コンペへの参加感想だったり、特定のコンペの振り返りなどがメインでした。まだ僕は開始から終了まで気をいれてコンペに取り組まないといけないよなという気持ちになりました。

第三部はスポンサーの紹介でした。懇親会費を負担していただいてありがとうございます。
インターンいきたいなあという気持ちがわいてきました。（実力をつけないとです）

その後の懇親会でも多くの人とkaggleの話やそうではない話、就活の話など、いろんなお話ができてよかったです。僕とお話してくれた方ありがとうございます。

#  ここからは今回の関西kaggler会で学んだことについて今後の自分の戒めのために書いておきます。

まず、kaggle本をかえという話。いままで毎回図書館で本を借りて済ましていたので、昨夜おふとんのなかでぽちりました。今日届く予定です。この本で勉強します。

次に過去コンペについて振り返るという話。これはほんとにそうで、自分は振り返りをあまりしない癖があります。Atcoderでもコンテスト中に解けなかった問題はなかなかコンテスト後にupsolveしようとするきになれないんですね。これはkaggleも同じでコンペ後に上位解法を知ろうとする気になれなくって、昨月のTablegroundシリーズも放置してしまっています。反省します
少し時間ができた時や、今取り組んでいるコンペの類似コンペについてはしっかりと自分でリサーチして上位解法については理解できるようになりたいです。すらすらと他人のコードを読めるようになりたい（願望）

最後に就活のためならsignateのほうがよいのでは？という話。日経企業就職を目指しているのでkaggleよりもsignateの比重を大きくして、学生コンペには積極的に取り組んでいきたいと思いました。現在もSMBCコンペがひらかれているようなので、時間があればやりたいですね笑

# まとめ
今回の関西kaggler会が初参加でしたが、授業を切って参加してほんとによかったと思います。次回は春休み中に開催されそうなので、次回も参加しようと思います。
それまでに何かしらメダルをとっておきたいなあ、なんて思っています。

以上です。ここまで読んでいただきありがとうございます。
AWS S3 学習メモ

# 目次
1. [オブジェクトロック](#オブジェクトロック)
1. [署名付きURL](#署名付きURL)


# 1. オブジェクトロック
<details><summary>詳細</summary>

## 概要
S3オブジェクトロックは有効にすることで、S3オブジェクトが一定期間または無制限に上書きまたは削除されることを防ぐことができる機能。
バケット全体ではなくオブジェクトに対してのロックなので注意！！

バケットの設定でオブジェクトロックをオンにすると、バケット内の全てのオブジェクトに対してオブジェクトロックが有効になる。

## オブジェクトロックを使用する条件
・バージョニングが有効になっていること
　⇒オブジェクトロックは特定のバージョンのオブジェクトに対して上書きまたは削除されることを防ぐ
 　⇒オブジェクトの新しいバージョンを作成することが阻害されたり、オブジェクトの上に追加される削除マーカー（これがあると実際には削除されていないが、S3はこのオブジェクトが削除されたようにふるまう）が削除されることはありません

## 保持期間
オブジェクトロックが有効化されると、設定された保持期間の間オブジェクトが上書きまたは削除されることを防ぐことができる。
S３バケットにデフォルトの保持期間を設定しておくこともできる。
## リーガルホールド
保持期間と同様にオブジェクトが上書きまたは削除されるのを防ぐことができるが、保持期間と異なりオブジェクトロックが削除されるまでの間は永久的に有効。
保持期間とは独立しているため、保持期間とリーガルホールドの両方が設定されているオブジェクトにおいて片方のみが解除されたとしてももう片方の設定が有効であれば、オブジェクトロックが有効に
## 2つのモード
###### ・コンプライアンスモード
AWSのrootユーザーを含めてあらゆるユーザーによるオブジェクトの上書きまたは削除を防ぐことができるモード
一度設定するとモードの変更や保持期間を既存より短い設定に変更することができなくなる
保持期間中にオブジェクトを削除する唯一の方法は対象のオブジェクトに関連するAWSアカウントが全て削除された場合のみ
###### ・ガバナンスモード
AWSのrootユーザーなど特定の権限を持っているユーザー以外によるオブジェクトの上書きまたは削除を防ぐことができるモード
必要に応じて一部のユーザーにオブジェクトの保持設定や、削除をするアクセス権限を付与できる
### 参考
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/object-lock.html
</details>

# 2. 署名付きURL
<details><summary>詳細</summary>
S3バケットのバケットルールを変更せずに一時的にS３バケットへのアクセスをできるようすることができる
認証権限はURLを作成したユーザーのものが使用される
</details>


# 3. ACL(アクセスコントロールリスト)
<details><summary>詳細</summary>
### 参考
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/acl-overview.html
</details>

# 4. S3イベント通知
<details><summary>詳細</summary>

## 概要
S3で特定のイベントが発生した時に通知を受領することができる。

##### 対象のイベント
・新しいオブジェクトの作成イベント
・オブジェクトの削除イベント
・オブジェクトイベントの復元
・低冗長化ストレージ (RRS) オブジェクトの紛失イベント
・レプリケーションイベント
・S3 ライフサイクルの有効期限イベント
・S3 ライフサイクルの移行イベント
・S3 Intelligent−Tiering 自動アーカイブイベント
・オブジェクトのタグ付けイベント
・オブジェクト ACL PUT イベント

##### イベントの送信先
・Amazon Simple Notification Service (Amazon SNS) のトピック
・Amazon Simple Queue Service Amazon SQS キュー
・AWS Lambda 関数
・Amazon EventBridge

## イベントの順序付けと重複について
S3イベント通知は各イベントの発生毎に最低でも一回の通知を保証しているが、通知の送信順がイベントの発生順になることは保証していない。
また、場合によっては同じオブジェクトのS3イベント通知が複数回発生してしまうこともある。
同じオブジェクトに対する複数の処理が短い間に発生し、S3イベント通知が発生順でない順で送信された場合はイベント通知に用いられるJsonオブジェクト内にあるシーケンサーの16進数値が大きい方がS3で後に発生したオブジェクトとして認識されます。

### 参考
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/EventNotifications.html
https://qiita.com/zumax/items/3d453d2e76beb011b6d9
https://aws.amazon.com/jp/blogs/storage/manage-event-ordering-and-duplicate-events-with-amazon-s3-event-notifications/
https://docs.aws.amazon.com/AmazonS3/latest/userguide/notification-content-structure.html
</details>

# 5. サーバーアクセスログ
<details><summary>詳細</summary>
### 参考
</details>

# 6. CloudTrailとCloudWatch
<details><summary>詳細</summary>
### 参考
</details>

# 7. マルチパートアップロード
<details><summary>詳細</summary>
### 参考
</details>
SpringBootでschema.sqlに書いた初期化用SQLが実行されない

## 状況
schema.sqlの内容
``` sql
--テーブル作成などのSQLを記述する用のファイル
CREATE TABLE IF NOT EXISTS tasklist (
     id   VARCHAR(8)  PRIMARY KEY,
     task VARCHAR(256),
     deadline VARCHAR(10),
     done BOOLEAN
 );
 ```

 ## 解決方法
application.propertiesの設定が間違ってました
どうやら参考にしていた学習書に記載されていた設定方式が古かったらしい、、
springboot2.5以降で記載形式が変わった模様
``` properties
#修正前
spring.datasource.initialization-mode=always
#修正後
spring.sql.init.mode=always
```
[Flutter] warning: The iOS deployment target ‘IPHONEOS_DEPLOYMENT_TARGET’ is …でビルドエラー

筆者の作業環境

:::note info
mac OS 15.1
flutter 3.22.3
xcode 16.1
androidstudio 2024.2.1 Patch 2
:::
## 1.XcodeでmininumDeploymentsを設定する
Targets/project/Generalの欄、**Mininum Deployments**を任意のversionに上げます。![スクリーンショット 2024-11-09 15.29.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2428088/3cd3e104-f122-70d4-b338-66cfdd3033b9.png)
xcode16からはminimumDeployments = iOS Deployment Targetになっていました。(xcode15の時は個別で選べた記憶があるのですが)
![スクリーンショット 2024-11-09 15.30.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2428088/a700f493-dd2b-9046-d26f-90c4944b45b1.png)

ちなみにmininumDeploymentsはアプリがインストール出来る最小のOSversionを指定する値です。

# 2 Podfileの修正
Firebase関連のライブラリを使用している場合、**BoringSSL-GRPC**の修正も必要になります。
以下のように修正してください。


```ruby:podfile
post_install do |installer|
  project_deployment_target = installer.pods_project.build_configurations.first.build_settings['IPHONEOS_DEPLOYMENT_TARGET']

  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)

    target.build_configurations.each do |config|
      # デプロイメントターゲットを Xcode プロジェクトの設定と一致させる
      old_target = config.build_settings['IPHONEOS_DEPLOYMENT_TARGET']
      new_target = project_deployment_target
      if old_target != new_target
        puts "Updating deployment target for #{target.name}: #{old_target} -> #{new_target}"
        config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = new_target
      end
    end

    # 特定のターゲット 'BoringSSL-GRPC' の設定
    if target.name == 'BoringSSL-GRPC'
      target.source_build_phase.files.each do |file|
        if file.settings && file.settings['COMPILER_FLAGS']
          # '-GCC_WARN_INHIBIT_ALL_WARNINGS' フラグを除外
          flags = file.settings['COMPILER_FLAGS'].split
          flags.reject! { |flag| flag == '-GCC_WARN_INHIBIT_ALL_WARNINGS' }
          file.settings['COMPILER_FLAGS'] = flags.join(' ')
        end
      end
    end
  end
end
```

このように修正することで、podfileの**iOSDeploymentTarget**とXcodeの**DeploymentTarget**が同期されるのでプロジェクトの整備性が高まるかと思います。

あとは、いつもの
```ruby:
flutter clean
flutter pub get  
```
でビルドでOKです😀
BrainF*ckとcowを理解した中学生(!?)

どうもAtsu1209です。
実は最近`BrainF*ck`と`Cow`に出会ってしまいました。
おもろそうだなと見ていたら、いつの間にか原理を理解しました。

# BrainF*ckとCowとは
口で説明するより、コードを見たほうがいいと思うので例として
`Hello`を出力するコードを書きましょう。

```:BrainF*ck
++++++++[>+++++++++<-]>.>++++++++++[>++++++++++<-]>+.>++++++++++[>++++++++++<-]>++++++++.>++++++++++[>++++++++++<-]>++++++++.>++++++++++[>++++++++++<-]>+++++++++++.
```
```cow
MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO Moo MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO Moo MoO MoO MoO MoO MoO MoO MoO Moo Moo MoO MoO MoO Moo OOO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO Moo MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO Moo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo MOo Moo MOo MOo MOo MOo MOo MOo MOo MOo Moo MoO MoO MoO Moo MOo MOo MOo MOo MOo MOo Moo MOo MOo MOo MOo MOo MOo MOo MOo Moo OOO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO MoO Moo
```
は?と思いますよね? でも原理は意外と簡単です。

| BrainF*ck| Cow |動き |
|:-:|:-:|:-:|
|  > |moO|ポインタを右にずらす   |
|  < |mOo|ポインタを左にずらす   |
| +|MoO | ポインタの値を1増やす |
|-|MOo|ポインタの値を1減らす|
|.|OOM|ポインタの値を出力する(ASCII)|
|[|MOO|ポインタの指す値が0なら、]まで飛ぶ|
|]|moo|ポインタの指す値が0でなければ、[まで飛ぶ|
|,|oom|入力から1バイト読み込んで、ポインタが指す値に代入|

##### 参考

https://qiita.com/TomoShiozawa/items/25dcce1540085df71053

https://ja.wikipedia.org/wiki/COW_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9E)

# なんで文字が書けるのか?
原理としては`ASCIIコード`を使っています。
例えば、`A`のASCIIコードは`65`なので、`+`を65個書いて`.`で出力すればいいことになります。 Cowも同様に対応した文字を入れればいいのです。

# 楽に出力
でも`+`や`MoO`を何個も書くのはめんどくさいですよね。
そんなときに`[`や`]`を使います。

# おすすめサイト
BrainF*ckを書くのにいいサイトがあります。

https://kachikachi.net/brainfuck/?Agoogle.com

ブラウザ上で動かすことができます。
また、メモリーの値やポインタを可視化してくれるので使いやすいです。

# 最後に
みんなも職場や学校でBrainF*ck使ってみてね
おわり
VScode：Emotionでstyled-components的に書く際のコード補完

# やりたいこと
- エディタ：VScode
- 使用ライブラリ：Emotion
  - [styled-componentsの書き方](https://emotion.sh/docs/styled)でCSSをあてる

この環境下で、スタイルを書く際にコード補完をしたい。

# 結論
styled-components用のコード補完拡張機能が使用できた。
- 名前: vscode-styled-components
  - ID: styled-components.vscode-styled-components
  - 説明: Syntax highlighting for styled-components
  - バージョン: 1.7.8
  - パブリッシャー: Styled Components
  - VS Marketplace
  - リンク:https://marketplace.visualstudio.com/items?itemName=styled-components.vscode-styled-components

## 使っている様子

![スクリーンショット 2024-11-09 15.30.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249420/6e5d7869-425a-13a1-20de-69092a793f11.png)

---
たのしい！
NVMe(PCIe-SSD)を束ねて大きなストレージとして使う

# 1TBのSSDが余り始めた...

最近、yoctoで自前のLinuxディストリビュージョンをビルドするときなど、広いストレージが必要になることが増えてきました。ここ最近は2TBのNVMe-SSDもかなり安価になっており、そちらを買うことが多いと思いますが、すると1TBのNVMe-SSDが余り始め...とはいえビルド環境は常に容量が必要で...

## それなら、mdadmで2TBのパーティションを作ろう

`mdadm` はソフトウェアRAIDを構築できるLinuxの機能です。`mdadm`は物理パーティションを複数束ねて`md`と呼ばれる論理パーティションを作成することができます。複数のNVMe-SSD上の物理パーティションを、デバイスをまたいで結合できますので、余った1TB-SSDを2本使って2TBのパーティションを作ることができます。

### その他の解決方法

実はソフトウェアRAIDを使わなくても、Intelの「インテルVMD(ボリューム・マネジメント・デバイス)」を使えばチップセットでハードウェアRAIDが組めるので、より簡単に解決することができます。ただし、安価なマザーボードはVMD対応のチップセットが載っていませんので、どこにお金をかけるか悩みどころですね。

https://www.intel.co.jp/content/www/jp/ja/products/docs/chipsets/desktop-chipsets/z790-chipset-brief.html

# Ubuntu18.04でmdadmを使ってみた

多くの方々のQiitaを参考に1TB NVMe-SSD 2本から2TBのetx4パーティションを作成し、自身のホームディレクトリ以下`/home/shino/yocto`にマウントしてみました。

### mdadmのインストール

```
$ sudo apt update
... (パッケージが格納されているサーバ情報を更新する)
$ sudo apt upgrade
... (パッケージをすべて最新にする)
$ sudo apt install mdadm
... (mdadmパッケージをインストールする)
```

### まとめるための物理パーティションを作成する

今回は`/dev/nvme0n1`と`/dev/nvme1n1`上に物理パーティションを作成して結合しました。

```
$ sudo fdisk /dev/nvme0n1
p
... パーティションテーブルを表示
n
... パーティションを作成
w
... パーティションを保存

$ sudo fdisk /dev/nvme1n1
p
... パーティションテーブルを表示
n
... パーティションを作成
w
... パーティションを保存

$ ls /dev/nvme?n1*
/dev/nvme0n1  /dev/nvme0n1p1  /dev/nvme0n1p2  /dev/nvme1n1  /dev/nvme1n1p1
... 今回は「/dev/nvme0n1p2」と「/dev/nvme1n1p1」を結合します
```

### mdadmコマンドで論理パーティションを作成する

``` 
$ mdadm --create /dev/md0 --level=raid0 --raid-devices=2 /dev/nvme0n1p2 /dev/nvme1n1p1
... 論理パーティション「/dev/md0」を作成する
$ sudo mkfs.ext4 /dev/md0
... 論理パーティションをext4でフォーマットする
$ mkdir -p /home/shino/yocto 
... マウントするディレクトリを作成する
$ sudo mount /dev/md0 /home/shino/yocto
... マウントする
$ ls /home/shino/yocto
$ mount 
/dev/md0 on /home/shino/yocto type ext4 (rw,relatime,stripe=256)
```

### 再起動後も自動でRAIDが組まれるよう設定ファイルに追記する

```
$ sudo mdadm --detail --scan 
ARRAY /dev/md/shino-Ubu18:0 metadata=1.2 name=shino-Ubu18:0 UUID=6b0193ab:61df0053:7f03ae60:4cb82e2b
... 現在の設定情報を確認する
$ sudo vi /etc/mdadm/mdadm.conf
# mdadm.conf
# ...
# This configuration was auto-generated on Sat, 09 Nov 2024 13:08:54 +0900 by mkconf
ARRAY /dev/md/shino-Ubu18:0 metadata=1.2 name=shino-Ubu18:0 UUID=6b0193ab:61df0053:7f03ae60:4cb82e2b
... 最後の行に設定情報を追記する
```

### 再起動してmdを確認する

```
$ sudo reboot
... 再起動
$ sudo mdadm --detail --scan
ARRAY /dev/md/shino-Ubu18:0 metadata=1.2 name=shino-Ubu18:0 UUID=6b0193ab:61df0053:7f03ae60:4cb82e2b
... /dev/md/shino-Ubu18:0 という論理パーティションが作られている
```

### /etc/fstabで自動マウント

```
$ sudo vi /etc/fstab
... 以下を追記
/dev/md/shino-Ubu18:0 /home/shino/yocto ext4 defaults 0 0
$ sudo reboot
... 再起動
$ mount | grep "/home/shino/yocto"
/dev/md127 on /home/shino/yocto type ext4 (rw,relatime,stripe=256)
... マウントされていることを確認できます
```

## まとめ

以上がソフトウェアRAIDを使った、物理デバイスよりも大きな論理パーティションを作る方法です。手順自体は簡単なのですがハマりやすいポイントとしては、RAIDの名前のエイリアスがたくさんできることでしょうか(`/dev/md127`とか`/dev/md/shino-Ubu18:0`とか)。少し設定したら再起動してどうなっているか調べる...と進めていくことと手戻りは少なそうですね。

またこのあたりがクリアになりましたら更新しようと思います。
スマートウォッチのアプリ開発にチャレンジしてみた

# はじめに
エニプラボでは、今期はスマートウォッチのアプリ開発を行っています。
コーディング経験の浅いメンバーがコーディング経験を積むという目標のもとでアプリ開発に一からチャレンジしています。

# 活動概要
会社説明会で使用する内製アプリの開発を行っています。
配信されたスケジュールに合わせてスマートウォッチに通知が飛び、シフトの時間を逃さないようにする、といった機能を実装します。

開発はアプリケーション開発1名とインフラ構築1名で行っています。
アプリケーション開発はAndroid Studioで、インフラ構築はTerraformで行っています。Terraformはインフラをコードで構築することができるツールです。
それぞれの開発を通じて、実践的な開発経験を身につけています。
現在はモックの開発まで進みました。

### アプリの構成
Androidアプリからスケジュールを取得するAPIを呼び出し、取得した時間に応じてアラームを鳴らします。
APIはAPI GatewayでLambdaを呼び出し、LambdaからDynamoDBにあるスケジュールを取得して返却します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3329734/381c9344-eb62-bae3-375d-142f5155e2b6.png)


# 今後の取り組み
まずはアプリの完成を目指して開発を進めていきます。
ゆくゆくはアプリからスケジュールを確認できる、などの機能拡充を進めていきたいと思っています。
Raspberry PiでCloudflareにDDNSをする話

## 背景
- Unifiのルーターを導入した．
- UnifiにはNECなどと違いDDNSサービスが存在しない．
- お家ネットの契約上，固定IPがコロコロ変わる．
- 外部からVPNを張る際に困る．
- そのため，RasPiを使い，自分のドメインに対してDDNSをすることにした．

## 要件
### HW
- 任意のRaspberry Piなどサーバ
- 固定IPの付いている回線

### SW
- cloudflare DNS（独自ドメインが登録されている状態）
- ddclient

## 準備
### ddclientをインストール
~~~sh
apt install ddclient
~~~
設定をいろいろ求められるが，後ほどconf fileに直接書くので全部適当でおk．

### CloudflareにAレコードを入力
DDNSしたいURLと任意の適当なIPをAレコードとして登録しておく．
これがないと後程エラーを吐きます．

### CloudflareからAPIKEYを入手

webコンソールの ` /アカウント管理/アカウントのAPIトークン ` を開く．すると，以下のような画面が表示される．

![スクリーンショット 2024-11-09 14.45.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291593/1fba8991-7aa7-9367-9689-9e74c48ca261.png)

『ゾーンDNSを編集する』のテンプレートを使用する．
![スクリーンショット 2024-11-09 14.46.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291593/a03ae315-e419-e5f9-7180-6d8d7bb251d1.png)

編集したいゾーンリソースを選択する．
次の画面に表示されるAPIを保存しておく．後ほど設定に使う．
![スクリーンショット 2024-11-09 14.46.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291593/30864dca-96c9-5c57-a7df-040ef90c1337.png)


## 設定
### ddclientの設定
設定内容はこちら．
先述のCloudflareのHPから入手したAPIKEYやメールアドレスなどを登録．
~~~sh
$ sudo vim /etc/ddclient.conf
~~~

~~~conf
# Configuration file for ddclient generated by debconf
#
# /etc/ddclient.conf

protocol=cloudflare \
use=web, web=https://api.ipify.org/ \

zone=example.com \
login=your.cloudflare.registerd.mail \
password='PleaseTypeHereYourAPIKEY' \

hogehoge.example.com,
~~~

更新できるか試す．
~~~sh
sudo ddclient
~~~


## 確認
以下のコマンドで確認ができる．

~~~sh
sudo ddclient -v
~~~


## 落とし穴
エラー：`FAILED:   updating home-router.feles.dev: Could not connect to api.cloudflare.com/client/v4.`
解決方法：DNSにDDNSで使用するURIを入力していないのが原因．Aレコードを追加する．
欧州CRA解説 第3回：セキュリティ要件/脆弱性対応

## セキュリティ関連要件への適合の義務化
第一回では、欧州CRAの概要と制定の背景。第二回は、欧州CRAの対象となる製品の種類、及び適合性評価についてそれぞれ説明しました。第三回は、欧州CRAで求められる要件のうちのセキュリティ要件を中心に説明します。

#### 【第13条で規定された製造者の義務（概要）】
- デジタル要素を含む製品を市場に出す場合、必須要件に従って設計、開発、製造されていることを保証しなければならない
- サイバーセキュリティリスクのアセスメントを実施
- サイバーセキュリティリスクアセスメントは文書化サポート期間中に適宜更新
- 第三者から提供されたコンポーネントを統合する際、当該コンポーネントがデジタル要素製品のサイバーセキュリティを損なわないよう、十分な注意を払わなければならない
- 各セキュリティ更新プログラム最低10年間補償
- 技術文書を作成、適合性評価手続を実施、CEマーキングを貼付
## セキュリティ特性要件と脆弱性処理要件
EU内に流通させる製品は、セキュリティ特性要件と脆弱性処理要件を満たすことが必須となります。

製造者はそのセキュリティ特性要件を満たすように設計・開発・製造を行わなければならず、さらに製品に対して「適合性評価」を行い、セキュリティ特性要件を満たしていることを証明しなくてはなりません。また市場にリリースした後5年間は脆弱性への対応を行う必要があり、脆弱性への対応の手続きを定めることや脆弱性発見時には速やかに対応することなどが求められています。

欧州CRAの別紙には「セキュリティ特性要件」及び「脆弱性処理要件」が具体的に記載されています。

#### 【セキュリティ特性要件】
- リスクに基づいて適切なサイバーセキュリティを確保するよう設計・開発・生産されていること
- 悪用可能な脆弱性が含まれないこと 
- リスクベースアセスメントに基づいて以下を満たすこと 
1.製品を元の状態にリセット可能であるなどの安全な構成 
2.適切な制御メカニズムによる、不正アクセスからの保護 
3.最先端の暗号化などによる、データの機密性の保護 
4.データ・プログラム等の完全性に係る許可されていない操作からの保護
5.必要なデータに限定した処理の実施（データの最小化）
6.DoS攻撃からの回復・緩和など、重要な機能の可用性観点での保護 
7.他の機器やネットワークからの自信（製品）への影響の最小化
8.外部インターフェース等の攻撃対象領域を制限した設計・開発・製造 
9.インシデントの影響を軽減する設計・開発・製造 
10.アクセス等の活動の記録・監視及びセキュリティ情報の提供 
11.自動更新などのセキュリティアップデートによる脆弱性対応の実施

#### 【脆弱性処理要件】
- 製品に含まれる脆弱性とコンポーネントの特定・文書化
※読み取り可能な形式でのSBOM作成を含む
- セキュリティアップデートの提供など、遅滞なく脆弱性に対処・緩和すること 
- 効果的かつ定期的なテストとレビューを行うこと 
- 脆弱性情報の公開及び修正を行うこと 
- 脆弱性開示ポリシーを導入し、実施すること
- 製品やサードパーティコンポーネントの潜在的な脆弱性に関する情報共有を行い、連絡先を提供すること 
- 悪用可能な脆弱性が適時に修正・緩和されるように安全にアップデートを配布するメカニズムを提供すること
- セキュリティパッチや更新プログラムが遅滞なく無料で配布され、ユーザーへの助言メッセージも添付すること 

---
今回の投稿では、欧州CRAのセキュリティ要件と脆弱性対応について解説しました。次回は、当局への報告の義務化の詳細について、解説を行う予定です。

:::note warn
※本内容は記事作成時点での最新のCRA法を参照していますが、今後法律が修正され内容が変更、もしくは新たな記載が追加される可能性があります。また、法律の専門家ではないため、法の解釈が誤っている可能性もあります。本法の内容について参照する際は必ずご自身で内容をご確認ください。
:::
【Next.js 15】動的ルーティング設定時に発生したエラーについて

# はじめに
Next.jsで個人開発を進めている駆け出しエンジニアです。

開発を進めるにあたって、ページのルーティング設定をはじめにしておこうと思いました。自分が開発しようとしているWebサービスではユーザーにいくつか質問をしてもらう機能があるので、質問ごとにページが変わるようにしたいなと思いました。そこで調べていくと、どうやら「動的ルーティング」がよさそうとのことが判明。

Youtubeで動的ルーティングについて分かりやすく解説してくれている人がいたのでそちらを参考にやってみました。

画面表示まではすんなり行けたのですが、動画内にある`console.log(params);`で意図した出力がされない。。。
Youtubeで紹介されているコードと同じように書いたのになぜなんだろうと思い調べました。なんとか解決できたので、その原因と解決策について記録しておきます。

## 参考資料
参考にした動画はこちらです：[Next.js Routing Guide](https://www.youtube.com/watch?v=Wk7WX0aD8lk)
App Routerについて知りたい方：[【完全版】App Routerで最初に知っておくとよさそうな基礎を全部まとめてみた](https://rakuraku-engineer.com/posts/nextjs-app/)

## 修正前のコード

```typescript
import React from "react";

const page = ({ params }: { params: { id: string } }) => {
  console.log(params);
  return (
    <div>質問: {params.id}</div>
  );
};

export default page;
```
## エラー
```
Error: Route "/questions/[id]" used params.id. params should be awaited before using its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis
    at id (webpack:///src/app/questions/[id]/page.tsx?6239:6:21)
  4 |     console.log(params);
  5 |   return (
> 6 |     <div>質問: {params.id}</div>
    |                     ^
  7 |   )
  8 | }
  9 |
  ```
  
## 原因
Next.jsのバージョンが15になってから、`params`の処理が非同期（`async`）になったため、直接的に値を取得しようとするとエラーが発生するそうです。参考にしたYoutubeの方の解説はNext.js 14で自分のバージョンは15だったので、そこで差が出てました。
Next.js公式ドキュメント：[Dynamic APIs are Asynchronous](https://nextjs.org/docs/messages/sync-dynamic-apis)

## 対策
非同期ということで`async`と`await`を使用することで、`params`のプロパティを利用できるとのこと。

## 修正後のコード
以下のようにasync関数にし、awaitを使用してparamsのプロパティを取得するように修正しました。

```typescript
import React from "react";

const page = async ({ params }: { params: { id: string } }) => {
  const { id } = await params;
  console.log({ id });
  return <div>質問: {id}</div>
};

export default page;
```
## 気になる点
~~上記のように修正したところ、VSコードでawaitを記載したところ、注意書きで「awaitはこの式の型に関しては効果がありません」と出ている。
↑実際動いているのでそこまで気にしなくてもいいのか、それとも改善した方がいいのか良く分からない。。。~~
↑`params`に`Promise<...>` を付けることで解決しました。

## 再修正コード
```typescript
import React from "react";

const page = async ({ params }: { params: Promise<{ id: string }> }) => {
  const { id } = await params;
  console.log({ id });
  return <div>質問: {id}</div>
};

export default page;
```
詳しくは@honey32さんからコメントいただいていますので、そちらをご確認ください。

## 最後に
まだ、開発を始めたばかりで難しいなと感じていることが多々あります。
エラーにもビリビリまくりですが、今回は公式ドキュメントを読む→ChatGptに聞いてみる→修正するみたいな感じでやると修正できました。
はじめから生成AIに聞くのもいいですが、公式ドキュメントを読んだ方が最初にAIに聞くより早いなと思いました。
今やっている開発が世に出せるように挫けず頑張っていきたいと思います。応援よろしくお願いします！！
WezTerm + fish でコマンドが完了したら通知する

## 裏で動いているコマンドが完了したら通知が欲しい

<img width="524" alt="スクリーンショット 2024-11-09 15.05.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8880/12ec0421-0923-10f4-0942-af4cf89706d5.png">

小ネタ。

長く掛かる作業、例えば、コンパイルとかデプロイとか大きなファイルの圧縮とか、そういう作業を開始した後、待つ間に別のタブやアプリで作業を行う、こういうことは良くあると思います。その時に、開始しておいた作業が完了したら何らかの通知が欲しいです。

こういうソリューションはすでにあり、fish を使うなら [franciscolourenco/done](https://github.com/franciscolourenco/done) が有名です。僕もこれ使ってたのですが、一度動かなくなった時に理由が分からず、コードを見ようとしたら複雑過ぎて断念したので代替策を探していました。

すると、↓こちらの記事に同じような課題感から独自に機能を実装してるコードがあり、これを修正して僕の環境で動くようにしました。

> [Fish Shellの設定ファイルを見直して起動時間を 470ms -> 14.7ms に短縮した話](https://zenn.dev/ryoppippi/articles/de6c931cc1028f)

## 「裏」で動いているかどうか判定する

先に載せた記事のコードには一点不満があり、それは、「現在まさに WezTerm で作業中のコマンドが完了した場合も通知が来る」というものでした。Neovim で文書を書いていて、それを終了させた時も通知が来ます。終了させたのは自分ですから通知は必要ありません。通知は「裏側」で動いているコマンドが終了した時のみにしたいのです。

僕は表題の通り、[WezTerm](https://wezfurlong.org/wezterm/index.html) を使っています。WezTerm で上記の問題を解決するなら以下のような方法を使えば良さそうです。

* コマンドが実行された pane の ID とアクティブな pane の ID が異なる時だけ通知する。

これだけですね。

しかし、一つ問題があります。僕はセッションを永続化するために [Multiplexing](https://wezfurlong.org/wezterm/multiplexing.html) 機能も利用しており、平たく言うなら [tmux](https://github.com/tmux/tmux/wiki) のような使い方をしています。

この場合何が困るかと言うと、「アクティブな pane を判定するのが難しい」という点です。WezTerm は [`wezterm cli`](https://wezfurlong.org/wezterm/cli/cli/index.html) コマンドにより起動したシェルから様々な情報を取得できるようになっています。しかし、Multiplexing 機能を使っている関係上、一つのシェルが複数の WezTerm クライアントで表示される訳で、「今どのクライアントのどの pane がアクティブになっているか」は、シェルから知ることができません。

### OS の機能で「アクティブ」か判定する

また、別の問題もありました。いくら WezTerm 上でアクティブな pane だとしても、別のアプリで作業中の時は通知が欲しいです。ウィンドウ自体が見えなくなってるかも知れませんからね。

これらの理由から、OS の機能を使って「アクティブ」かどうかを判定することにしました。「アクティブ」ということは GUI ウィンドウが最前面に来ているはずですから、そのウィンドウを開いているプロセスが何か分かれば良いです。このために僕の完成版スクリプトは macOS 限定のものになっています（元の記事のスクリプトは Linux でも動きます）。

ChatGPT に「最前面にあるウィンドウのプロセス番号を知りたい」と聞いたら一発で教えてくれました。Apple Script は良く知らないので助かります。

```bash
# 最前面のウィンドウを表示しているプロセスの ID を得る
osascript -e 'tell application "System Events" to get the unix id of first process whose frontmost is true'
```

このプロセス番号で [`wezterm cli list-clients`](https://wezfurlong.org/wezterm/cli/cli/list-clients.html) を検索すれば、「アクティブな pane の ID」が分かります。もし WezTerm が最前面でないなら、結果は空になる訳です。

```bash
# 指定したクライアントが表示しているアクティブな pane の ID を得る
wezterm cli list-clients | perl -anle 'print $F[$#F] if $F[2] == '$active_pid
```

:::note info

この記事の初稿ではアクティブな pane の ID を得るために `$F[5]`（6 番目のフィールド）としていたのですが、Workspace が空文字列でない時にエラーになることが分かりました。そのため必ず最後のフィールドを取得する表現 `$F[$#F]` に修正しています。

:::

## 完成版のスクリプト

長くなりましたが、以下のスクリプトが完成版です。これを `config.fish` に書いておけば、5 秒以上掛かったコマンドについて通知が来ます。

https://github.com/delphinus/dotfiles/blob/556c76aaddbf8b965d0c455678f97567dc87c290/.config/fish/config.fish#L211-L225

https://gist.github.com/delphinus/d1280fd9c9f32218f2c65477ec3640db

## 既知の問題

かなりレアなパターンですが、別の端末で接続しているクライアントのプロセス番号が現在の端末の最前面のウィンドウと一致すると、「裏側」なのに通知が出ちゃいますね。厳密にやるならばホスト名も含めて比較すべきでしょう。これは宿題にしときます。


## 終わりに

WezTerm、多機能ですが痒い所に手が届く作りになっていていいですね！
Django REST frameworkをmodwsgi + apacheでデプロイするときはVirtualHostを設定した方が良いみたい



症状が発生してなんとか直ったけど、何故なのか良く分からなかった
という備忘録的な記事です


## 1. 症状と対処


以下のようにAPIをデプロイしました
・Django REST frameworkで作成したAPI
・mod_wsgiを使ってapacheサーバーにより公開
・WSL2環境にdockerでデプロイ
・dockerイメージはubuntuを使用


以下のような症状が出ました
・JavaScriptでfetchコマンドを使ってGETするとAPIが応答しなくなる
・最初にfetchコマンドを使ったときには結果を正常に受け取れる
・PythonのrequestsパッケージでGETしても止まらない
・ブラウザでAPIのURLを叩いていても何かの拍子に応答しなくなることがある
・応答が止まるとapacheのaccess.logもerror.logも書きだされなくなる
・応答が止まるとブラウザでURLを開いても応答しない
・docker exec -it xxxxx bashで入るとbashは正常に動いている
・docker statsで見ても負荷はほとんどかかっていない
・python manage.py runserverで実行しているときはこの症状は出ない


対処と結果
・デフォルトサーバーでを<VirtualHost *:80>で記載した
・応答しなくなる不具合がまったく発生しなくなった
・全体にレスポンスが早くなった


## 2. apache.conf


問題が発生していたapache.conf


```apache:apache.conf
WSGIRestrictStdout Off

ServerName localhost:80

Define project_dir /var/web
Define project_name mysite
Define python_path /var/web/mysite

WSGIPassAuthorization On

WSGIDaemonProcess ${project_name} python-path=${python_path} inactivity-timeout=300
WSGIProcessGroup ${project_name}

WSGIScriptAlias / ${project_dir}/${project_name}/${project_name}/wsgi.py

ErrorLog /dev/stderr
CustomLog /dev/stdout combined

<Directory ${project_dir}/${project_name}/${project_name}>
<Files wsgi.py>
  Require all granted
</Files>
</Directory>

Alias /static/ ${project_dir}/${project_name}/static/
<Directory ${project_dir}/${project_name}/static>
  Require all granted
</Directory>
```


問題が直ったapache.conf


```apache:apache.conf
WSGIRestrictStdout Off

<VirtualHost *:80>
  ServerName localhost
  ServerAlias 127.0.0.1

  Define project_dir /var/web
  Define project_name mysite
  Define python_path /var/web/mysite

  WSGIPassAuthorization On

  WSGIDaemonProcess ${project_name} python-path=${python_path} inactivity-timeout=300
  WSGIProcessGroup ${project_name}

  WSGIScriptAlias / ${project_dir}/${project_name}/${project_name}/wsgi.py

  ErrorLog /dev/stderr
  CustomLog /dev/stdout combined

  <Directory ${project_dir}/${project_name}/${project_name}>
    <Files wsgi.py>
      Require all granted
    </Files>
  </Directory>

  Alias /static/ ${project_dir}/${project_name}/static/
  <Directory ${project_dir}/${project_name}/static>
    Require all granted
  </Directory>
</VirtualHost>
```


## 3. 原因の推測


原因が分からなかったのでChatGPTに聞いてみたら以下のように回答されました


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277233/f1347355-c73d-25f8-fda1-ec46a210f2b7.png" width=70%>


「VirtualHostブロックで設定することで、WSGIProcessGroupのライフサイクルが明確に管理されて繰り返しのリクエストや並行リクエストで安定性が向上する」んだそうです


Django公式にそんなこと書いてあったかな？というのを確認しましたが、VirtualHostブロックを使って複数アプリをデプロイできるという記載はあるものの、繰り返しリクエスト時の安定性などについての記載はないようです
https://docs.djangoproject.com/ja/5.1/howto/deployment/wsgi/modwsgi/


## 4. 結論


apache自体あまり分かっていないのでそこから勉強したいと思います
もし原因が分かる方がいらっしゃいましたら教えてください
Ubuntu18.04にUSB-WiFiを認識させる(0bda:b812)

# Ubuntu22.04で認識できたUSB-WiFiをUbuntu18.04でも利用したい

開発の都合で、Ubuntu22.04で動作していたPCをダウングレードしたところ、`ip addr` の一覧からUSB-WiFiが消えていました。22系で自動でインストールされるドライバが、18系の時代は含まれていないようです。調べて、使えるようにしてみました。

## 認識できなかったデバイス

認識できなかったデバイスは以下

```
$ lsusb

Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 002: ID 0bda:b812 Realtek Semiconductor Corp. <<-- これ
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 25a7:fa61
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
```

[Amazonで購入しました](https://www.amazon.co.jp/gp/product/B09ZP5NXBV)

### 今回参考にしたサイト

https://www.gadgets-today.net/?p=7663

# RTL88x2buドライバの導入

このWi-Fiデバイスを使うには「RTL88x2buドライバ」と呼ばれるものが必要なようです。このドライバはGitHubで配布されていますので、まずはgitを使えるようにします。

```
$ sudo apt install git -y
```

gitコマンドが使えるようになったら、以下を実行し、ドライバのソースコードを入手します。

```
$ git clone https://github.com/RinCat/RTL88x2BU-Linux-Driver.git
...
$ ls -l
drwxrwxr-x 8 shino shino 4096 11月  9 13:48 RTL88x2BU-Linux-Driver
```

次にドライバのソースコードをビルドし、ドライバ（カーネルモジュール形式）を生成。ドライバをインストールします。

```
$ cd RTL88x2BU-Linux-Driver
$ make clean
... (古い生成物が削除されます)
$ make KSRC=/lib/modules/$(uname -r)/build -j 16
... (カーネルモジュールがビルドされます)
$ sudo make install
... (カーネルモジュールをインストールします)
```

最後にドライバを読み込むことで、デバイスが認識できるようになります。`rtw_switch_usb_mode=1`はUSB3.0を設定する指定子です。

```
$ sudo modprobe 88x2bu rtw_switch_usb_mode=1
... (カーネルモジュールをロードします)
$ nmcli device
DEVICE           TYPE      STATE     CONNECTION
enp0s31f6        ethernet  接続済み  有線接続 1
wlx90de80815163  wifi      接続済み  xinolinx_5G <<-- これが見えればOK
lo               loopback  管理無し  --
```

### 再起動後もカーネルモジュールがロードされるようにする

カーネルモジュールを起動時に自動的にロードするよう設定します。これには`/etc/modules`を使います。

```
$ sudo vi /etc/modules
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
88x2bu rtw_switch_usb_mode=1
(上の行を追記)
```

念のため、再起動した後も認識できるか試しておきましょう。

```
$ sudo reboot
```

### WiFiのアクセスポイント選択など

無線LANの設定は、Ubuntuデスクトップにあるネットワークの設定画面を利用することが簡単でしょう。わたしの自宅では`xinolinx_5G`というアクセスポイントが立っているので、そこに接続しています。

## まとめ

以上が、WiFi(`0bda:b812`)の利用方法です。
また他のデバイスにぶつかったら都度追記予定です！
VSCodeでマインドマップを作る

マインドマップを作成したいものの、クラウドサービスでは無料プランの範囲内で作成できるマップ数に制限があることが多く、ローカルで動作するツールを探していた際に、参考になる記事を発見しました。

参考記事:
https://karaage.hatenadiary.jp/entry/2022/08/31/073000

ただし、記事内で紹介されている拡張機能が見つからず、同様の拡張機能をいくつか試した結果、以下のものが該当する可能性が高いと判断しました。
https://marketplace.visualstudio.com/items?itemName=oorzc.mind-map

この拡張機能では、デフォルト設定のままだと日本語の漢字が中国語のフォントに近い表示になるため、Sans-Serifフォントに変更することで日本語表示が改善されます。
ChatGPT APIをPythonで利用するぞ -OpenAIのライブラリインストール編-

## まずはじめに
### 著者について
・情報系学部卒
・学部時代の研究はコーディング要素皆無
・IT系（サイバーセキュリティ系）の仕事
・社会人修士
・コード書けない
・コード書いたのは学部の講義くらい
・数学できない
・学部時代に習ったことは忘れている

という初心者&初学者が、研究で「ChatGPTのAPIを使って自動化しよう！」となり、冷や汗をかいている

### 記事の目的
わからないなりに苦戦したあれこれを記録する

## OpenAIのライブラリインストールができない
[公式のAPIリファレンス](https://platform.openai.com/docs/api-reference/introduction)を参照して、`% pip install openai`を実行したところ、エラー

環境は
`% python3 --version`
`Python 3.11.6`

以下サイトを参考に`python3 -m pip install`を実行したところ、インストールできた

https://zenn.dev/shimouta/articles/c81de05cafe6d2

https://packaging.python.org/ja/latest/tutorials/installing-packages/

## さいごに
一行目からつまずいたけど解決できてよかった
この調子でインターネットの助けを借りまくりながら頑張りたい
Arm CPU の Azure Cobalt 100 仮想マシンを作成してみた

Arm CPU の Azure Cobalt 100 が GA したので、試しに Azure CLI で仮想マシンを作成してみました。x86 CPU よりも安く性能が高いようなので、そのうち何かの案件で使う日がくるかもしれません。

## 検証用仮想マシンを作成

```zsh:zsh
prefix=mnrc100
region=japaneast

az group create \
  --name ${prefix}-rg \
  --location $region

az vm create \
  --resource-group ${prefix}-rg \
  --name ${prefix}-vm \
  --os-disk-name ${prefix}-vmOSDisk \
  --image canonical:ubuntu-24_04-lts:server-arm64:latest \
  --size Standard_D2pls_v6 \
  --admin-username azureuser \
  --generate-ssh-keys \
  --nsg-rule NONE \
  --public-ip-address-dns-name ${prefix}
```

## NSG に SSH を追加

```zsh:zsh
az network nsg rule create \
  --resource-group ${prefix}-rg \
  --name AllowSSH \
  --nsg-name ${prefix}-vmNSG \
  --priority 100 \
  --source-address-prefixes $(curl -s inet-ip.info) \
  --destination-port-ranges 22 \
  --access Allow \
  --protocol Tcp
```

## 検証用仮想マシンに SSH 接続

```zsh:zsh
ssh azureuser@${prefix}.$region.cloudapp.azure.com
```

## CPU 情報を確認

```bash:bash
$ lscpu
Architecture:             aarch64
  CPU op-mode(s):         32-bit, 64-bit
  Byte Order:             Little Endian
CPU(s):                   2
  On-line CPU(s) list:    0,1
Vendor ID:                ARM
  Model name:             Neoverse-N2
    Model:                0
    Thread(s) per core:   1
    Core(s) per socket:   2
    Socket(s):            1
    Stepping:             r0p0
    BogoMIPS:             2000.00
    Flags:                fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm j
                          scvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm uscat ilrcpc flag
                          m ssbs sb paca pacg dcpodp sve2 sveaes svebitperm svesha3 svesm4 flagm2 frint sv
                          ei8mm svebf16 i8mm bf16
Caches (sum of all):      
  L1d:                    128 KiB (2 instances)
  L1i:                    128 KiB (2 instances)
  L2:                     2 MiB (2 instances)
  L3:                     128 MiB (1 instance)
NUMA:                     
  NUMA node(s):           1
  NUMA node0 CPU(s):      0,1
Vulnerabilities:          
  Gather data sampling:   Not affected
  Itlb multihit:          Not affected
  L1tf:                   Not affected
  Mds:                    Not affected
  Meltdown:               Not affected
  Mmio stale data:        Not affected
  Reg file data sampling: Not affected
  Retbleed:               Not affected
  Spec rstack overflow:   Not affected
  Spec store bypass:      Mitigation; Speculative Store Bypass disabled via prctl
  Spectre v1:             Mitigation; __user pointer sanitization
  Spectre v2:             Mitigation; CSV2, BHB
  Srbds:                  Not affected
  Tsx async abort:        Not affected
```

## 後片付け

```zsh:zsh
az group delete \
  --name ${prefix}-rg \
  --yes
```

## 参考

https://azure.microsoft.com/en-us/blog/azure-cobalt-100-based-virtual-machines-are-now-generally-available/
【AWS App Runner】初心者必見！AWS App RunnerでサクッとコンテナWebアプリを公開しよう！


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806193/20b1b19c-9333-9b83-f229-c3c83fa331c2.png)

## 一言でいうと

::: note info
AWS App Runnerは、インフラやコンテナの知識無くても**WebアプリケーションやAPIを簡単にデプロイし、スケーリングも自動化できるAWSのサービス**です。
:::

インフラ管理の知識がなくても、App Runnerを使えば、コンテナ化されたアプリケーションをスムーズに稼働させられます。これで、開発に集中でき、手間のかかるインフラ設定は不要になります！


---

## もう少し詳しく

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806193/3f69ee21-e196-adab-3e76-7b4e5240acf7.png)

ここから、App Runnerの基本的な構成要素をわかりやすく見ていきましょう。

## 基本の構成要素とキーワード説明

### 1. ソースコードやコンテナのリポジトリ
App Runnerは、デプロイしたいアプリケーションの「ソースコード」や「コンテナイメージ」を管理するリポジトリにアクセスして、その内容をもとにアプリケーションをデプロイします。

- **ソースコード**：アプリのプログラムファイル（例：GitHub上のプロジェクト）
- **コンテナイメージ**：アプリケーションを実行するための必要な環境をまとめたパッケージ（例：Amazon ECRに保存されるイメージ）

### 2. 自動デプロイ
App Runnerは、ソースコードやコンテナイメージに変更があるとその更新を検知し、自動で新しいバージョンのアプリケーションをデプロイします。これにより、アップデート作業がスムーズになり、常に最新の状態でアプリケーションを提供できます。

- **デプロイ**：アプリを稼働可能な状態にセットアップしてユーザーが利用できるようにすること
- **自動化**：App Runnerが、手動作業なしで更新からデプロイまでを自動で行ってくれる仕組み

### 3. オートスケール
トラフィックが増加したときに、App Runnerは自動でコンテナの数を増やし、逆にトラフィックが減るとコンテナ数を減らすことでリソースを効率的に利用します。これにより、トラフィック量に合わせてアプリケーションが安定して稼働します。

- **スケーリング**：必要なリソースの増減を調整すること
- **コンテナ**：アプリケーションが動く環境をまとめた仮想的な実行環境

## 具体例：To-Doリストアプリをデプロイしてみよう

例えば、簡単なTo-Doリストアプリを開発したとしましょう。このアプリをAWS App Runnerを使って公開する手順を解説します。

1. **ソースコードやコンテナの指定**  
   GitHubやAmazon ECRに保存してあるアプリのソースコードやコンテナイメージをApp Runnerに指定します。App Runnerはここからコードやイメージを取得し、アプリのデプロイ準備をします。

2. **自動デプロイ設定**  
   アプリケーションのソースコードに変更があった場合に、App Runnerが自動的に更新を検知し、新しいバージョンをデプロイするよう設定します。これにより、To-Doリストアプリが常に最新の状態で提供されます。

3. **スケーリング設定**  
   App Runnerでは、トラフィックの状況に応じてコンテナ数を自動調整できます。これにより、ユーザー数が増加してもアプリの負荷が分散され、アプリが安定して動作します。

このように、App Runnerを活用すれば、コードをリポジトリに配置し、自動デプロイとスケーリングを設定するだけで、迅速かつスムーズにアプリケーションを運用できます。初心者でも簡単にインフラ管理ができ、プロダクト開発に集中できるのが魅力です。

---
## 神様仏様、BulidersOnlineさま
**「欲しかったのはこのAWS AppRunnerでした」** という熱い言葉から始まります。
アメリカン！
いつもお世話になっております。ちょうどこのあたりからAppRunnerのお話。

<iframe width="560" height="315" src="https://www.youtube.com/embed/0PVxNWn2blQ?si=C8MgPT6V98B6ty_t&amp;start=659" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

## まとめ

AWS App Runnerは、インフラ管理に時間をかけずにWebアプリケーションをAWS上で稼働させるためのサービスです。開発者はApp Runnerの自動化機能を活用して、インフラの管理負荷を減らしつつ、サービスの拡張性を確保できます。手軽にWebアプリをAWS上にデプロイしたい方は、ぜひApp Runnerを試してみてください！
wordpressでPDFを埋め込む

## 完成イメージ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882753/6dd9af8f-36b1-982d-e68b-c298ea5d76b6.png)

もくじがあって下にPDFを埋め込む。
もくじをクリックしたらそのPDFのページに飛ぶ。

### worpressでプラグインインストール
インストール有効化
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882753/0af9f483-a209-da93-6076-406c441c0437.png)

メディアライブラリでpdfアップロード

wordpressのPDF埋め込みたい　固定ページか投稿ページの編集画面いく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882753/e41ed30c-d1ca-bb02-ba59-2277bc576fc8.png)

+を押す
ファイル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882753/c141d517-dbed-1971-862e-da1204100d7b.png)

任意のPDFを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882753/a1621356-e36c-f8bf-eda8-6352a548cce6.png)

wordpress上で表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882753/284c6147-6ee2-c63c-6ec1-e8cc0d2de8b6.png)

## 目次作成
もくじを書きたい記事の編集画面へ遷移
カスタムHTMLで書く。
```
<a href="your-pdf-url.pdf#page=10" target="_blank">10ページへ移動</a>
```
your-pdf-url.pdf これは開いてほしいPDFを書く

例えば：http://192.168.0.199:8000/wp-content/aaa/uuu/aaaw　aiueo.pdf
ローカルホストで動かすdocker wordpressで動画を埋め込む。別の物理サーバもしくはストレージに動画を参照させる方法。

## 方法
①wordpressの記事投稿or編集画面からメディアアップロードで動画をUPする。
②webサーバーを使い、そこに動画を置く。wordpressはそこを参照する。

①だと問題点がありますので、②を試す記事になります。

## メディアアップロードで動画を上げると、wordpressを稼働しているストレージがパンパンになる

イメージこれ↓

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882753/d8a124f1-fe16-df09-a7e3-8fa2d26fa81c.png)
【想定されるケース】
512GBが一杯になってきましたので、外付けで512GBを買います。もしくはほかのサーバーに動画を移したい。

外付けのパターン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882753/409e70da-ca16-31f6-8a1b-40af335394fb.png)

他の物理サーバのパターン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882753/6338f99b-96ef-2f90-edf6-cf3ae464d791.png)

どっちのパターンでもdockerの上にwebサーバをたてる。↓たてかた　他の物理サーバの場合はdockerインストール終わらせとくように。
### ディレクトリ作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882753/e95ece2b-4011-f77f-1973-96472a3a5312.png)
### docker-compose.yml作成
```

version: '3'
services:
  apache-server:
    image: httpd:latest
    ports:
      - "8082:80" # ポート8082でアクセス可能に
    volumes:
      - D:\Docker_app\docker_wordpress_videos:/usr/local/apache2/htdocs
```


再生させたい.mp4ファイルをD:\Docker_app\docker_wordpress_videosディレクトリに保存します。

### WordPressで動画を埋め込む
```
<video width="640" height="360" controls>
    <source src="http://192.168.0.199:8082/2_01331.mp4" type="video/mp4">
    お使いのブラウザは動画再生に対応していません。
</video>
```

## 注意点とまとめ
.MTSはブラウザで再生できないので、XMedeaRecodeなど拡張子変換ソフトを使って.MTS→.mp4に変換します。
mp4になった動画をwebサーバーにおきます
※webページは直接パソコンのディレクトリを覗きにいけないので、webサーバーをパソコンの中にたててwebサーバを参照しに行かせる必要があります。
webサーバにおいた動画ファイルのリンクをwordpressの記事に埋め込んで終わりっ！