OmniAICreator/Qiita-1.07M huggingface dataset:
[firebase] cloud functionsが実行出来ない blocked by CORS policy

# 背景
Firebaseで動かしてたサービスがcloud functionsへアクセスが出来なくなる問題に遭遇。
急にアクセス出来ないかつ心当たりなさすぎたのでハマった。一旦治ったのでまとめる

1. cloud functions側でonCallのエンドポイントを作成。
```functions.js
exports.func = functions.https.onCall((data) => {
    // ...
});
```
2. クライアントからfirebase.onRequestで呼び出す。
```client.js
functions.httpsCallable("func");
```

# エラー内容
functions側のlogは出ない。そもそもapiを叩けていない状況

consoleを見るとなんか出てる
cors、、、君だったのか、いやいやでもonCallはcors出ないんじゃなかったの？（詳しくは加筆）
```js
blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
```

# 解決法
こちらの記事の通り。
https://qiita.com/tekunikaruza_jp/items/c068506ca0d6d648cc50

簡単にまとめると権限のエラー
1. gcpで[cloud functions](https://cloud.google.com/functions?hl=ja) 該当の関数にアクセス
1. 権限 > 追加でallusersにすれば良い。
![スクリーンショット 2022-09-28 21.08.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/787586/1d0c8bd4-4d13-caf7-76c5-b052185d64d6.png)

元々allUsersを許容していた関数を作り直した際に権限がリセットされたことが原因？
とりあえず解決するのだが、allUsersってそもそも良いんだっけ？
もうちょっと調査する必要がありそう。
続
【Vue3】アニメーションの開始終了イベントを取得する

# はじめに
軽くハマったので備忘録として書きます。
結論としては **`animationstart/end` ではなく `trasitionstart/end` を使うことで動作しました。**

# 作りたいもの
- 要素の回転するときにアニメーションさせる
- 回転中かどうかを検知して他の要素を制御する

# 間違い
```vue
<template>
  <div
    class="transition"
    :style="{ transform: `rotate(${angle}deg)` }"
    @animationstart="rotating = true"
    @animationend="rotating = false"
  >
    ターゲット
  </div>
  <button @click="angle += 90">回転</button>
  <div v-if="rotating">
    回転中
  </div>
</template>

<script setup>
  const angle = ref(0)
  const rotating = ref(false)
</script>
```

# 正解

```diff_vue
<template>
  <div
    class="transition"
    :style="{ transform: `rotate(${angle}deg)` }"
-   @animationstart="rotating = true"
-   @animationend="rotating = false"
+   @trasitionstart="rotating = true"
+   @trasitionend="rotating = false"
  >
    ターゲット
  </div>
  <button @click="angle += 90">回転</button>
  <div v-if="rotating">
    回転中
  </div>
</template>

<script setup>
  const angle = ref(0)
  const rotating = ref(false)
</script>
```

# 参考
https://stackoverflow.com/questions/34296699/css3-animations-animationstart-event-wont-fire-when-using-transition

https://developer.mozilla.org/ja/docs/Web/API/Element/animationend_event

https://developer.mozilla.org/ja/docs/Web/API/Element/animationstart_event
私の謎ノート

1. https://xxx/へリンクが飛ぶようにしていたが、設定で別ページへ飛ぶようにできる。
1. シボレス認証とLDAP認証https://tech-lab.sios.jp/archives/20661
1. 外部サイトのRSSとは
1. ブラウザアプリへ遷移させるか、そのまま画面上でブラウザを表示させるか。
[CSS]selectboxにplaceholderを作る

htmlの`select`タグにはplaceholderないんですよね〜
ただデザインにplaceholder入ってるやんっ！てなる時あるあるでしょう。
毎回忘れるので忘備録としてメモリます！

https://developer.mozilla.org/ja/docs/Web/HTML/Element/select

# これでok
1. `<select>`にrequiredかける。
1. placeholder用の`<option>`にdisabled,とselectedをかける
1. `select:invalid { color: 色; }`を付ける

```select.html
<label for="id" class="label">
  <select name="select" id="id" class="select" required>
    <option value="" disabled selected>選択してください</option>
    <option value="hoge">hoge</option>
    <option value="fuga">fuga</option>
    <option value="piyo">piyo</option>
  </select>
</label>
```

```select.css
select:invalid {
  color: gray;
}
```
SPRESENSEでNuttXのCANドライバ(MCP2515)を利用するまで (1) 実装計画

![DSC01467.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2595184/dfd5c4d2-5654-4314-acd4-4633a288c77c.jpeg)

自動車向け通信規格のCANは、自動車だけでなく、輸送用機械、工場、工作機械、ロボットなど幅広い分野で利用がはじまっています。SPRESENSEでは、NextStep社製の **「Sony Spresense 用 CAN AddOnボード」** を利用することにより、SPRESENSEをCANネットワークに参加させることができます。実際、SPRESENSEの開発環境には「Arduino IDE」と「SPRESENSE SDK」がありますが、Arduino IDEでの開発方法は下記の記事が最も参考になります。

### 今回入手したボード
https://nextstep.official.ec/items/38434337

### 参考記事｜Arduino IDEでSPRESENSEをCANネットワークへ参加させる
https://qiita.com/kaz19610303/items/c43bdd8134b3a47b0e3e


# 本記事の目的

**SPRESENSE SDK上でCANをアクティベートすることです。**
1回でまとめることが難しいので数回の更新でアウトプットしたいと思います。

### SPRESENSE SDKのCAN対応状況

最初の朗報は、SPRESENSE SDKはNuttXを核としたソフトウエアを生成できる開発環境であり、そのリアルタイムOSである「NuttX」はCANのデバイスMCP2515のドライバを同梱していることです。しかしこれは完全な朗報ではありません（これだけ聞くとコンパイルスイッチを切り替えるだけで使えるように錯覚します）。NuttXに同梱されたデバイスドライバは **「ボード名_bringup.c」** というファイル内で初期化が呼び出されて初めて機能します。SPRESENSEの場合は **[cxd56_bringup.c](https://github.com/shino-ixy/spresense-nuttx/blob/70eb038a2e23def3599b7c407e5a1a23b32bd5bd/boards/arm/cxd56xx/spresense/src/cxd56_bringup.c)** ですが、ここにMCP2515の初期化コードは含まれていません。

デバイスドライバを有効化するコンパイルスイッチ **「CONFIG_CAN_MCP2515」** を検索すると、[stm32f103-minimun の stm32_bringup.c](https://github.com/shino-ixy/spresense-nuttx/blob/70eb038a2e23def3599b7c407e5a1a23b32bd5bd/boards/arm/stm32/stm32f103-minimum/src/stm32_bringup.c#L409)が求めているコードのようですので、この実装を"cxd56_bringup.c"を移植するとよさそうです。

![スクリーンショット 2022-09-28 20.15.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2595184/ea159d88-cc94-f8a9-70fa-f0d2b064dafe.png)


### "/dev/can0" 提供後

無事移植ができると、NuttXのデバイスファイル "/dev/can0" として、CANを利用できるようになるでしょう。このときの利用方法を知る方法には、「[CANdriver APImigration from Classical CAN to CAN FD](https://www.can-cia.org/fileadmin/resources/documents/proceedings/2017_koppe.pdf)」が適当です。また、終端抵抗については「[CAN信号の終端処理を適切に行う](https://monoist.itmedia.co.jp/mn/articles/2006/15/news014.html)」が参考になりました。

# 次回の更新予定

それでは次回は、
stm32を参考にCANの初期化に必要な実装を洗い出していきたいと思います。
SHARP Brain に Linux を入れて遊ぶ(4) - tty あれこれ

[目次](https://qiita.com/nekopro2/items/7eff2eb5e1c4480d3b30)

# 概要
フレームバッファが使えるようになったので、それ以外の雑多な画面周り関連です。
※特に Brainux に限った話ではありません。

## やりたいこと
フレームバッファのアプリを起動に対して
- ログメッセージがうっとうしい
- コンソールのカーソルの点滅を消したい
![tty.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821068/875539db-6d80-1244-39f1-fa6314959864.png)

### ログメッセージがうっとうしい
dmesg で無効化する
~~~
sudo dmesg -D
~~~

再び有効にしたい場合は -E する
~~~
sudo dmesg -E
~~~

## コンソールのカーソルの点滅を消したい
エスケープ シーケンスで消す。
~~~
echo -e "\033[?25l"
~~~

再び表示させたい場合は
~~~
echo -e "\033[?25h"
~~~
TorとWarpにつながるプロキシを組む

# はじめに
匿名化インターネットをしたいわけじゃないけど  
TorとCloudflare WARPの両方にそれぞれソフトウェアを入れず  
クライアントのプロキシ設定だけで接続できると便利だなと思った  
Torの出口ノードってブロックされやすいんだよな、Cloudflareさんに  
じゃあCloudflareのサービスでつないでやるよということです。  
Cloudflare WARPはIP秘匿できないので必要なら他のVPNを使うといいと思う。他にProxyモードがあるVPNサービスを知らないけど。  
Torネットワーク宛のトラフィックはtorサービスに送って、それ以外はCloudflare WARPサービスに送るようにします。  
ついでにPrivoxyの簡易的な広告ブロックが効いてくると思います。  

環境  
OS: Fedora 36  
Cloudflare Warp 2022.8.936  
Tor 0.4.7.10  
Squid 5.6  
Privoxy 3.0.33  

# Torインストール

```
sudo dnf install tor
sudo systemctl enable --now tor
```

# Cloudflare WARPインストール

```
sudo rpm -ivh https://pkg.cloudflareclient.com/cloudflare-release-el8.rpm
sudo dnf install cloudflare-warp
sudo systemctl enable --now warp-svc
```

# Cloudflare WARP設定

以下のコマンド打っていけば設定できちゃいます。簡単ですね。  
今回全てのトラフィックをVPNしちゃうとTorに繋がらないので、プロキシモードにしてます。  

```
warp-cli register
warp-cli set-mode dot
warp-cli set-mode proxy
warp-cli enable-always-on
warp-cli connect
```

# Privoxyインストール
```
sudo dnf install privoxy
```

# Privoxy設定

`sudo nano /etc/privoxy/config`

以下の設定を行う
Privoxyは下のルールが優先されるみたいですね。  
`/`は全てにマッチするルールなので、上に書かないと`.onion`までWARPに送られる。  
WARPは40000ポート、Torは9050ポートで待ち受けています。  

```bash:/etc/privoxy/config
# Everything goes to Cloudflare WARP, except for requests to .onion
forward-socks5 / 127.0.0.1:40000 .
forward-socks5t .onion 127.0.0.1:9050 .
```

自動起動設定してサービスをスタート
```
sudo systemctl enable --now privoxy
```

# 確認

Privoxyの通常アクセスはTorを経由していないか  
`Sorry. You are not using Tor.`ならOK  

```
curl -Ss --proxy http://127.0.0.1:8118 https://check.torproject.org/ |sed -n '/<h1/,/<\/h1>/p'
```

PrivoxyでTorネットワークにはTorで接続できるか  
BBCニュースのWebサイトを取得できるか確認、ステータスコードが`200`ならOK  

```
curl -IL -x http://127.0.0.1:8118 https://www.bbcnewsd73hkzno2ini43t4gblxvycyac5aw4gnv7t2rccijh7745uqd.onion
```

Privoxyの通常アクセスにはCloudflare WARPを使用しているか  
ASNが`CLOUDFLARENET`になっていればOK  

```
curl -L -x http://127.0.0.1:8118 https://ip.gs/json
```

ここまでできれば利用するアプリケーションでプロキシを`127.0.0.1:8118`に設定すれば使えるようになる。  
もし他のデバイスからアクセスしたいなら、Squidを同じサーバーに建てると設定しやすい。  

# （オプション）Squidインストール・設定
今回の目的では必ずしもSquidは要らないのだが、  
もしPrivoxyの高機能な設定に慣れていないので前段にSquidをかますと設定しやすいかもしれない  
私はSquidの設定にも慣れていないが…  

```
sudo dnf install squid
```

Squidのコンフィグを編集するので  
`sudo nano /etc/squid/squid.conf`

以下の設定を注入します  
既存の設定値の先頭に入れておくのがおすすめです  
最後に入れてしまうとうまく反映されないことがあります  

```bash:/etc/squid/squid.conf
# Define Privoxy as parent proxy (without ICP)
cache_peer 127.0.0.1 parent 8118 7 no-query
# Define ACL for protocol FTP
acl ftp proto FTP
# Do not forward FTP requests to Privoxy
always_direct allow ftp
# Forward all the rest to Privoxy
never_direct allow all
```

以下でサービス開始

```
sudo systemctl enable --now squid
```

必要ならファイヤーウォールで許可する。  
デフォルトゾーンに入れますが、必要に応じて変更されたい。  
というかポートを変えるものなのだろうか、LANならデフォルトポートでいいと思うので、そのままサービス名を使ってルール追加。  
もしインターネットに公開したいのならファイヤーウォールだけでなく`squid.conf`も編集しないといけない。  

```
sudo firewall-cmd --add-service=squid --permanent
sudo firewall-cmd --reload
```
【Flutter】Flutterアプリでセキュリティ面で気にすべきこと

インドネシアの[PT.AQ Business Consulting Indonesia](https://aqi.co.id/)でFlutterのエンジニア兼アドバイザーをしております菊池と申します。

本記事はZennで出版しております[flutter chips](https://zenn.dev/tetsukick/books/06ee607e30e243)のchapter2-1の内容の一部になります。(本記事が2,000字程度、Zenn記事が50,000字程度)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/5183aafc-d1d7-534f-f618-031f10790fdc.png)


## センシティブな情報とは
センシティブな情報とは、具体的に、、
- Amazon Web Services（AWS）APIキー
- Facebookトークン
- GitHubトークン
- Google APIキー
- Twitter OAuthトークン
- PayPal APIキー
- Twilio APIキー
- Slack Webフック
- Heroku APIキー
- MailChimpキー
- IPアドレス
- 暗号化鍵

などが考えられます。みなさんハードコーディングしてしまっていませんか。

## センシティブな情報をハードコーディングすることの危険性

> パスワードやIPアドレス、暗号化鍵等センシティブな情報をハードコードすると、それらの情報を攻撃者に晒してしまう可能性がある。クラスファイルにアクセスできる者であれば誰でも、クラスファイルを逆コンパイルし、センシティブな情報を取り出すことができる。したがって、プログラムにセンシティブな情報をハードコードしてはならない。

参考: [MSC03-J. センシティブな情報をハードコードしない](https://www.jpcert.or.jp/java-rules/msc03-j.html)

### 過去に実際に発生したインシデント/事例
- [Androidアプリに大手サービスの「鍵」をハードコード、AWSアカウントにアクセスも](https://www.itmedia.co.jp/enterprise/articles/1701/18/news065.html)
- [1000本以上のAndroidアプリが認証情報を無防備な状態で保存、Comparitechが調査](https://www.atmarkit.co.jp/ait/articles/2104/22/news111.html)
- [JVN#00414047 スマートフォンアプリ「Studyplus(スタディプラス)」に外部サービスの API キーがハードコードされている問題](https://jvn.jp/jp/JVN00414047/index.html)

### 実際に覗いてみた
githubで”aws_accesskey”で検索すると確かにちょいちょい出てきました。
![](https://storage.googleapis.com/zenn-user-upload/1bb80614f9d8cd7bdc8f56ba.png)
![](https://storage.googleapis.com/zenn-user-upload/8db3d8757c6f22108df7aa31.png)
![](https://storage.googleapis.com/zenn-user-upload/642636c107522d0fb92bea29.png)
![](https://storage.googleapis.com/zenn-user-upload/94814f8d3f620bf22c740c00.png)

## Flutter製アプリで懸念すべきこと
Flutter製のアプリで懸念すべきことは主に以下の2点になると思います。
- git上にセンシティブな情報をあげない
- 逆コンパイルされても、センシティブな情報が見つからないようにする/見つかりにくくする。
#### APKファイルの逆コンパイルの方法
APKの逆コンパイルはとても簡単に実行できます。
1. ['apktool'をインストール](https://ibotpeaches.github.io/Apktool/install/)
Macであれば、Homebrewを使ってインストールできます。
```
brew install apktool
```
2. 'apktool d {対象のAPK}.apk'で逆コンパイルされます。
```
apktool d test.apk
```

## 対処法
対策は購入者限定の記事となります。
下記よりアクセス可能です。
[flutter chips](https://zenn.dev/tetsukick/books/06ee607e30e243)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/5183aafc-d1d7-534f-f618-031f10790fdc.png)
【JavaScript】タイトルの変え方

JavaScriptを使用していてtitleタグの要素の取得苦戦したのでメモを残します。
サーバー側の処理はなくhtmlとjsだけで動かします。

機能としてはボタン押下時にブラウザのタイトルが切り替わるようにしたいと思います。
<h1>【titleタグの要素取得/変更】</h1>
//html

```
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>test</title>
</head>
<body>
<button id="button" onclick="changeTitle()">ChangeTitle </button>

<script type="text/javascript" src="./JS/test.js"></script>
</body>
</html>
```

//JavaScript
titleタグの取得は「document.title」になるんですね。
変更する際は「document.titel='○○'」と代入するだけでOKです。

```
"use strict";

function changeTitle(){
    //test→change
    if(document.title=='test'){
        document.title='change';
        return;
    }

    //change→test
    if(document.title=='change'){
        document.title='test';
        return;
    }
}
```
以上、メモでした。
Laravel Sailのtinkerで日本語が表示できない時の対応方法

Sailの環境を構築して、tinkerで日本語を表示すると以下のようになりました。
Dockerfileをカスタマイズすることで、日本語も表示できるようになったので、その時の手順を書いておきます。

```
% sail tinker
Psy Shell v0.11.8 (PHP 8.1.10 — cli) by Justin Hileman
>>> print('あああ')
<E3><81><82><E3><81><82><E3><81><82><E2><8F><8E>
=> 1
```

# 環境
```
% sail artisan -V
Laravel Framework 9.31.0

% sail version   
Docker Compose version v2.10.2
```

# 対応方法
docker-compose.ymlのservices.laravel.test.build.contextで指定したバージョンに対応するDockerfileをカスタマイズします。
ここでは、services.laravel.test.build.contextが`./docker/8.1`になっていることを前提とします。

1\. Dockerfileに、`# 日本語対応　追加ここから`から`# 追加ここまで`の部分を追加
```docker/8.1/Dockerfile
・・・・・・・・・・省略・・・・・・・・・・
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 日本語対応　追加ここから
RUN apt-get update && apt-get install -y language-pack-ja && \
    update-locale LANG=ja_JP.UTF-8

ENV LANG=ja_JP.UTF-8
# 追加ここまで

RUN apt-get update \
    && apt-get install -y gnupg gosu curl ca-certificates zip unzip git supervisor sqlite3 libcap2-bin libpng-dev python2 \
・・・・・・・・・・省略・・・・・・・・・・
```

2\. Dockerイメージを再ビルドしてからSail起動
```
% sail build --no-cache
% sail up -d
```

tinkerで日本語が表示されました。
```
% sail tinker
Psy Shell v0.11.8 (PHP 8.1.10 — cli) by Justin Hileman
>>> print('あああ')
あああ⏎
=> 1
```

# 補足
Sailの環境は、初期状態ではDockerfileが存在しませんでした。
```
sail artisan sail:publish
```
を実行すると、Dockerfileとその他の設定ファイルが、アプリケーションのルートディレクトリ内のdockerディレクトリに配置されます。
https://readouble.com/laravel/9.x/ja/sail.html
Laravel 5.6 コードスニペット集（Modelリレーション編）

親子関係（1対多）にあるテーブルのModelのコード例です。

##### 外部キー制約を使用しないケースで、主テーブルのデータ削除時、従テーブルのID紐づきデータも一括操作したい場合
```php:Model.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Models\Person;

class Person extends Model
{

    /**
     * Bootstrap any application services.
     * 
     * @return void
     */
    public static function boot()
    {
        parent::boot();
        // 親データ削除時：子テーブルのid紐付レコードも削除
        static::deleting(function ($person) {
            $person->schedule()->delete();
            $person->company()->delete();
            $person->position()->delete();
            $person->assessment()->delete();
        });
        // 親データ削除時：従テーブルの親ID欄はnull挿入
        static::deleting(function ($person) {
            $person->schedules()->update(['person_id' => null]);
        });
        // 状態フラグを無効設定時：従テーブルのデータはnull挿入
        static::updating(function ($person) {
            if($person->status_flg === '1') {
                $person->schedules()->update(['person_id' => null]);
            }
        });
    }
```
##### 日付けデータ等、DATE型で保存した値を取得時、常に加工しておきたい場合
```php:Model.php
    /**
     * Get schedule date as 'Y-m-d' format.
     * @param mixed $value
     */
    public function getScheduleDateAttribute() // get...Attribute()の...に取得・加工するカラム名をアッパーキャメル形式で記載
    {
        return date_format(date_create($this->schedule_date), 'Y-m-d');
    }
    /**
     * Get schedule time as 'H:i' format.
     * @param mixed $value
     */
    public function getScheduleTimeAttribute()
    {
        return date_format(date_create($this->schedule_time), 'H:i');
    }

```
###### Modelへのリレーション設定
```php:Model.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Models\Company;
use App\Models\Person;

class Schedule extends Model
{

    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function company()
    {
        return $this->belongsTo(Company::class);
    }
    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function Person() // 記載はModel同様アッパーキャメル形式。belongTo側は単数形、hasMany側は複数形。
    {
        return $this->belongsTo(Person::class, 'person_id', 'id'); // 第2引数以降は、不要。但し、指定する外部キーが●●_id形式以外だったり、特定の外部キーを指定したい場合は必要。
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BlongsTo
     */
    public function schedules()
    {
        return $this->hasMany(Schedule::class, 'company_id', 'id');
    }
```
【シェルスクリプト】コマンドを変数に格納して実行する方法

## コマンドを変数に格納して実行する方法
変数に格納したコマンドの引数にスペースが入っていると想定通りに動作しないことがある。

```zsh:sample.sh
set -x

SAY_HELLO='echo "hello !!"'
$SAY_HELLO
```
上記のように記述して実行すると`echo '"hello' '!!"'`を実行していることになる。
```zsh
$ sample.sh
+ SAY_HELLO='echo "hello !!"'
+ echo '"hello' '!!"'
"hello !!"
```

想定どおり動作させるためには以下のように記述する。
```zsh:sample.sh
set -x

SAY_HELLO='echo "hello !!"'
eval "$SAY_HELLO"
```
```zsh
+ SAY_HELLO='echo "hello !!"'
+ eval echo '"hello' '!!"'
++ echo 'hello !!'
hello !!
```

`echo 'hello !!'`が実行されている。
【MySQL】クエリーに関数や変数の値を使うには

## 背景

カラム名に日付をつけたかったがはまったのでメモ

## お題

ユーザーの日毎の体温を記録する `user_body_temperature` テーブルがある。

`SELECT * FROM user_body_temperature`

|id|user_id|date|temperature|
|-|-|-|-|
|1|1|2022-09-01|36.9|
|2|2|2022-09-01|36.1|
|3|1|2022-09-02|36.6|
|4|2|2022-09-02|36.5|
|5|1|2022-09-03|36.1|
|6|2|2022-09-03|36.5|
|...|...|...|...|

**日付をカラムとして**、user_id が 1 のユーザーが入力した当日の体温を抽出するクエリを作りたい。

SELECT文で動的にエイリアスを指定したいので、に当日の `CURDATE()` を指定すると・・・

```sql
SELECT temperature AS CURDATE() FROM `user_body_temperature` WHERE date = CURDATE() AND user_id = 1;

# => ERROR 1064 (42000) at line 4: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS CURDATE() from Test' at line 1
```

文法エラーとなってしまう・・・
これはエイリアスなどクエリー自体には動的な要素を指定することはできないため。

## 解決方法

CONCAT関数を使い、クエリー自体を文字列化して一旦変数に保存。
その後、EXECUTE文で実行。
IDE標準のフォーマッターや文法チェックは使えず可読性も落ち、デバッグもしづらいがこれで実行可能！

```sql
SET @query = CONCAT('SELECT temperature AS \'', CURDATE(), '\' FROM `user_body_temperature` WHERE date = CURDATE() AND user_id = 1;');
PREPARE dynamic_statement FROM @query;
EXECUTE dynamic_statement;
DEALLOCATE PREPARE dynamic_statement;
```

---

定期的なデータ抽出などには便利かも。

## 参考

- [dynamic_statement in MySql](https://gist.github.com/afrahbezan/e1eb36f22976271c060a41c4cb8e88b9)
- [13.5 Prepared Statements](https://dev.mysql.com/doc/refman/5.6/en/sql-prepared-statements.html)
s3のブロックパブリックアクセス とは

## 勉強前イメージ

見たことあるってレベルで正直良くわかってないの
公開の機能って感じ？

## 調査

### s3のブロックパブリックアクセス とは

s3バケットの機能で、バケットのポリシーが書き換えられてオブジェクトが公開されるのを防ぐ機能です。
パブリックアクセスの機能はアカウントごとでもできますし、バケットごとに設定ができます。

元々はACL、バケットポリシー、IAMを利用してアクセス制御を行っていました。
特にACLとバケットポリシーがオブジェクトの公開に関わるところですが
ACLはバケット単位・オブジェクト単位両方に設定できますが、オブジェクト単位のACLが優先されるのでバケットだけの設定を見れば安全というわけではなく
常にパブリックアクセスの許可がされていないか確認する必要がありました。
バケット単位を優先することも出来ますが、色んな理由で管理しづらいことが多かったです。

ブロックパブリックアクセスはs3バケットのアクセス許可のタブから確認することができます。
実際の設定しているのは以下になります。
この設定だと現在はパブリックアクセスをすべてブロックしています。

![1S3 bucket - Google Chrom.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/df2995bb-88f2-a361-5a7c-d81e1f83186c.png)

項目としては以下5つあり、1をオンにする = 2,3,4,5をオンにする になります。

1. パブリックアクセスをすべてブロック
2. 新しいアクセスコントロールリスト (ACL) を介して付与されたバケットとオブジェクトへのパブリックアクセスをブロックする
3. 任意のアクセスコントロールリスト (ACL) を介して付与されたバケットとオブジェクトへのパブリックアクセスをブロックする
4. 新しいパブリックバケットポリシーまたはアクセスポイントポリシーを介して付与されたバケットとオブジェクトへのパブリックアクセスをブロックする
5. 任意のパブリックバケットポリシーまたはアクセスポイントポリシーを介したバケットとオブジェクトへのパブリックアクセスとクロスアカウントアクセスをブロックする

## 勉強後イメージ

ここをめちゃくちゃいじったことあるってわけじゃないので詳細細かいとこまで知らなかった・・・

## 参考

- [S3で誤ったデータの公開を防ぐパブリックアクセス設定機能が追加されました](https://dev.classmethod.jp/articles/s3-block-public-access/)
OnsenUIのisIPhoneXでiPhone13を判別する方法

# 初めに
AngularでWebアプリを開発している時にOnsenUIのOnsPlatform.isIPhoneXでiPhone13が判定されなかった際の解決策を記載します。
# 実装コード
実行したコードは以下のコードです。
```javascript
 if (onsPlatform.isIPhoneX()) { // iPhone X であるか否かを判定
      // <html> 要素に属性を追加（値として空文字列を設定）
      console.log(onsPlatform.isIPhoneX());
      document.documentElement.setAttribute('onsflag-iphonex-portrait', '');
```
iPhone13miniの場合
```javascript
true
```
iPhone13の場合
```javascript
false
```
どうしてだ？？
# 対処法
とりあえず、iPhoneの判定をどのように行っているかをonsenuiのコードを確認してみました！
```javascript
key: 'isIPhoneX',
    value: function isIPhoneX() {
      return this.isIPhone() && (window.screen.width === 375 && window.screen.height === 812 || // X, XS portrait
      window.screen.width === 812 && window.screen.height === 375 || // X, XS landscape
      window.screen.width === 414 && window.screen.height === 896 || // XS Max, XR portrait
      window.screen.width === 896 && window.screen.height === 414 || 
```
ウィンドウのサイズから判断していることがわかりました。つまり、iPhone13用のサイズを定義すれば、サイズを判定されるはず。ということで以下のようにソースコードを変更しました。
```javascript
key: 'isIPhoneX',
    value: function isIPhoneX() {
      return this.isIPhone() && (window.screen.width === 375 && window.screen.height === 812 || // X, XS portrait
      window.screen.width === 812 && window.screen.height === 375 || // X, XS landscape
      window.screen.width === 414 && window.screen.height === 896 || // XS Max, XR portrait
      window.screen.width === 896 && window.screen.height === 414 || // 12, 12 Pro
      window.screen.width === 390 && window.screen.height === 844 || // portrait
      window.screen.width === 844 && window.screen.height === 390 || // landscape
      window.screen.width === 428 && window.screen.height === 926 || // portrait
      window.screen.width === 926 && window.screen.height === 428 // landscape
```
実行結果
```javascript
true
```
# 最後に
これから、フロントエンドやバックエンドの記事を投稿していきます。ぜひご覧ください
Windows 11非対応のPCを Windows 10からアップグレードする方法

# はじめに
これはクリーンインストールではなく、Windows 10からのアップグレード方法です。

# 1. Windowsのダウンロード

[UUP dump](https://uupdump.net/)からOSをダウンロードしてきてビルドします。
なるべく古いバージョンのWindows 11 がいいですが、ここでは例として`Windows 11 Insider Preview 10.0.22000.160`を[ダウンロード](https://uupdump.net/known.php?q=Windows+11+Insider+Preview+10.0.22000.160)してきます
どれくらい古いバージョンがいいかどうかは４の注意点を参照してください。
[UUP dump 通常バージョン検索結果](https://uupdump.net/known.php?q=Windows+11%2C+version)

ダウンロードしたファイルを展開し、`uup_download_windows.bat`ファイルを管理者権限で実行します。
実行が完了したら、同ディレクトリ内にisoがあるためそれをクリックしてマウントしておきます。
実行は40～50分くらいかかります。

# 2. appraiserres.dllを消す
マウントしたisoの内容を別のディレクトリにすべて移し、`sources/appraiserres.dll`を削除します。
これにより、インストーラはスペックのチェックができなくなります。

# 3. Windows のアップグレード

別のディレクトリに移してファイルを削除した方の`setup.exe`を起動し、`セットアップでの更新プログラムのダウンロード方法の変更` から、`今は実行しない`のほうを選択して、インストールを進める

すると、チェックが飛ばされてインストールできるようになる。

# 4. 注意点

最新のISOビルドだと、スペックのチェックに必要な`appraiserres.dll`がない場合、`チェックができません`と表示されてインストールできなくなっているので、UUP dumpでなるべく古いISOビルドを探してそれを使います。上記の場合はInsider Preview版ですが、普通のバージョンのやつも実行できます。

参考にしたサイトを見た感じに`2022.08.20`に投稿された記事で成功例があるため、それ以前のWindows 11 Buildを使用するといいと思います。

# 参考サイト

https://eizone.info/upgrade-to-windows-11/

https://www.yokoweb.net/2022/08/20/upgrad-non-compatible-to-windows11/
frourio+fastifyでAPI経由のバイナリファイルダウンロード

frourioでAPIにリクエストしたときにバイナリファイルを送信する場合、APIのレスポンスの型を定義しておかないとNext.js側で処理できずに詰まった時の事をまとめます。

# Next.js側での実装

ファイルのダウンロードの方法は色々あるかと思いますが、Blobを使ってみることにしました。
zipファイルをダウンロードすることにします。

サンプルなので雰囲気ですがこんな感じになると思います

```TypeScript
const apiClient = api(aspida());
const res = await apiClient.file.$get();
const blob = new Blob([res], { type: 'application/zip' });
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = `file.zip`;
link.click();
link.remove();
```

こんなわけでBlobオブジェクトを作らないといけないわけですが、コンストラクタに渡すデータはBufferにします。
というわけでAPI側の定義はBufferを返すようにします。

# API側の実装

## 定義したまま値を返す

index.tsではBufferを返すように定義します。

```TypeScript
// index.ts
export type Methods = {
  get: {
    resBody: Buffer;
  };
};
```

でそうするとcontroller.ts側ではBufferを返さないといけないのですが、

```TypeScript
// controller.ts
export default defineController(() => ({
  get: async () => {
    const buffer = await getBuffer();
    return { status: 200, body: buffer };
  },
}));
```

`getBuffer`からBufferを返してもレスポンスがファイルのバイナリと一致しないのでファイルを開くのが失敗してしまいます。

## 定義とは別にBufferを返す

一方、fastifyでバイナリファイルを送信するサンプルはいくらでもあるので、それが使えないかやってみました。
controller.tsの実装を以下のように変えます。

```TypeScript
// controller.ts
export type AdditionalRequest = {
  reply: FastifyReply;
};

export default defineController(() => ({
  get: async ({ reply }) => {
    await getBuffer(reply);
    return { status: 200, body: Buffer.from([])}; // Buffer.fromはダミー
  },
}));
```

getBufferにFastifyReplyを渡したいので、まずAdditionalRequestでFastifyReplyをリクエストに追加するように定義します。
getメソッドでそれを受け取れるのでgetBufferに渡します。
getBuffer内ではFastifyReply.sendを使ってバイナリファイルを送信するようにします。

で、controllerのgetメソッド側ではbodyにBufferを返してあげないと型エラーになってしまうので空のBufferを返します。
実際にはFastifyReply.sendでレスポンスが返されているのでここで返している値は影響しません。

# まとめ

こうすると型定義としてNext.js側ではBufferを受け取ることになり、バイナリファイルがダウンロードできます。
LINE×GAS｜Googleカレンダーの更新をLINEで通知

:::note warn
本記事に記載のコードの中身については、全てを1から私が記載したわけではありません。
こちらの記事は、あくまでも参照元に倣って自分でも作ってみて、つまづいたポイント・自分で追加調査したところ・追加改造を記録した記事です。
:::


# ゴール
Googleカレンダーに予定を登録、登録していた予定を変更・削除したら、LINEに通知がいく。
構成としては、**カレンダーの更新を検知→GASが起動→LINEに通知**という流れ。

### LINEの通知
![LINE.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687068/f33dd9e8-ebe3-590f-8daa-e0a755c63a13.png)

### コード全文
```js:
// LINE notifyのアクセストークンを取得して、***にコピペ
const access_token = '********************'

// calendarIdを取得して、カレンダー更新を通知
function getinfoSchedule(events) {  
  const email = events.calendarId
  lineNotify(`${email}さん\nGoogleカレンダーが更新されました`)
}

// LINEで通知
function lineNotify(message){
  const headers = {
    "Content-Type":  "application/x-www-form-urlencoded",
    'Authorization': 'Bearer ' + access_token,
  };
  const postData = {
    message: message
  };
  const options = {
    "method": "post",
    "headers": headers,
    "payload": postData
  };

  const url = 'https://notify-api.line.me/api/notify'
  UrlFetchApp.fetch(url, options);
}
```


# 使い方
細かいやり方は「参照・参考」に記載の動画・ドキュメントを見てみてください。

1. GASをコピペ
1. LINE notifyのアクセストークンを取得して、*********にコピペ   
1. GASのトリガーを設定
1. 登録した予定を変更するとLINEに通知がいく。



# うまくいかなかった原因
`calendarId`を取得できない原因は、スペルミス！！

`calendarId`ではなく`calendarID`（IDのDが大文字）になっていた。
なんという初歩的なミス。

# 感想・今後の展望
**①満足できてない**
本当は、「夜22時に明日の予定をLINEに通知」みたいなものを作りたかった。
でも、基礎がないから技術不足できないと断念。劣化版を作成。いつかは作りたい。

**②コードは部分だけでなく全体も示してほしい**
参考資料をみながらチクチク作ってたけど、コード全体が公開されてないとやりづらいったらこの上ない！
雑なアウトプットでもいいから、コード全体がわかるようにアウトプットしていこうと思った。
（もしかしてエラーがあったけど部分的にはうまくいったから、その部分だけ載せた、とか・・・・？）

**③GASの実行ログは大事**
今回は解説動画を見ながら、実行ログを見る機会が多かった。実行ログを通じて学ぶこともあった。
でも、表示まで少しラグがあるのね。



# 参照・参考
https://www.youtube.com/watch?v=e8CjjMsZ2Pw

https://qiita.com/hid3/items/f8783bd815568ca22073
【React】axiosエラーハンドリング共通化

# はじめに
今回はHTTP Clientライブラリであるaxiosのエラーハンドリング共通化方法について書いていこうと思います。

# エラーハンドリングとは
エラーハンドリングとは、**プログラムの処理中に処理が妨げられる事象が発生した際、その処理をエラーとして対処する処理のこと**です。
フロントエンドでAPI通信を行なった際、レスポンスがエラーだった場合に何か処理を行うということはよくあると思います。
※例えば、404が帰ってきたらNotFoundページへ遷移させるなど
下記のようにAPI通信を行う箇所全てでエラーハンドリングの処理を書いていたら記述量も多くなり面倒です。
```js
const fetchData = async () => {
  try {
    const response = await axios.get("http://localhost:3000/");

  } catch(err) {
    // エラー時の処理
  }
}
```

# axios エラーハンドリングの共通化
axiosの`Interceptors`を活用する。

`Interceptors`についてはこちら参照：[Interceptors](https://axios-http.com/docs/interceptors)

`Interceptors`を使って、axiosのエラーハンドリングを共通化することでAPI通信を行う箇所全てでエラーハンドリングを行う必要がなくなり、ページごとの独自のエラー処理のみ記述すればよくなります！
```axiosErrorHandler.js
axios.interceptors.response.use(
  (response) => response, // 成功時の処理 今回の例ではresponseを返すだけ
  (error) => {            // エラー時の処理
    switch (error.response?.status) {
      case 422:
　　　　　　　　　　　　　　　　　// ステータスコード別の処理

        // Promise reject オブジェクトを必ずリターンする
        return Promise.reject(error.response?.data);
      case 404:
        // ステータスコード別の処理

        return Promise.reject(error.response?.data);
      case 500:
　　　　　　　　　　　　　　　　　// ステータスコード別の処理

        return Promise.reject(error.response?.data);
      default:
　　　　　　　　　　　　　　　　　// デフォルトの処理

        return Promise.reject(error.response?.data);
    }
  }
);
```
※Tips ： `Interceptors`はaxiosのrequest前処理も共通化することができる

# Tips ： axios エラーハンドリング内で React Hooks を使う
エラーハンドリング共通化処理内でHooksを使用したいことがあると思います。
例 : 404でNotFoundページへ遷移させる為に`useNavigate`を使用するなど
通常React Hooksはコンポーネント内のトップレベルでしか呼び出せません。
参考 : https://qiita.com/tatsumin0206/items/4e1076e2deedf20a9485
その為エラーハンドリング共通化処理内で使用するには少し工夫が必要です。
具体的には、エラーハンドリング用のコンポーネントを作成し、コンポーネント内の`useEffect`で共通化処理を記述します
```jsx
export const AxiosErrorHandleProvider = ({ children }) => {
    const navigate = useNavigate(); // Hooksが使用できる！！

    useEffect(() => {
      // axiosの共通エラーハンドリング記述
      apiClient.interceptors.response.use(
        (response) => response,
        (error) => {
          switch (error.response?.status) {
            case 404:
              navigate('/404'); // navigateを使用してリダイレクト
              return Promise.reject(error.response?.data);
          }
        }
      );
    }, []);

    return <>{children}</>;
  }
);
```
あとは下記のような形でAppコンポーネントを囲います。
```jsx
ReactDOM.render(
  <React.StrictMode>
    <AxiosErrorHandleProvider> # 作成したコンポーネントでAppを囲う
      <App />
    </AxiosErrorHandleProvider>
  </React.StrictMode>,
  document.getElementById("root")
);
```
以上でaxiosエラーハンドリング内でReact Hooksを使用できるようになります！


少しでも参考になれば幸いです。
kintoneでJavaScriptを動かす

▼設定できたこと
一括承認ボタンをつける、
コメント欄をデフォルト非表示にする

見本のサイトがめちゃくちゃ分かりやすいので、何も分からないまま設定出来た！
仕組みは後から調べてみようと思う。

▼一括承認ボタンをつける
https://developer.cybozu.io/hc/ja/articles/211583223-%E3%83%AF%E3%83%B3%E3%82%AF%E3%83%AA%E3%83%83%E3%82%AF%E3%81%A7%E4%B8%80%E6%8B%AC%E6%89%BF%E8%AA%8D%E3%82%92%E3%81%97%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86

▼コメント欄をデフォルト非表示にする
https://zenn.dev/octi/articles/14eed0af5754720ed93d
【PHP】 Range関数に第三引数あったんやね

## 第三引数step

指定した範囲の数字配列を作る時にrangeをよく使います。

第三引数で2づつ増える、３づつ減るなどを指定できるようでした。

```php:昇順
$ranges = range(1,100,2);

array:50 [▼
  0 => 1
  1 => 3
  2 => 5
  3 => 7
  4 => 9
  5 => 11
  6 => 13
  7 => 15
  8 => 17
  9 => 19
  10 => 21
  11 => 23
  12 => 25
......
]
```

```php:降順
$ranges = range(100,1,-3);

array:34 [▼
  0 => 100
  1 => 97
  2 => 94
  3 => 91
  4 => 88
  5 => 85
  6 => 82
  7 => 79
  8 => 76
......
]
```


> 第三引数、-数値でも＋数値でも挙動が変わらなかった。
## 

第三引数あったの知らなかった
Stripe Checkout / Payment Linksで注文時のボタンラベルを[支払う]から[予約]へ変更する方法

施設の予約やアクティビティ・個人レッスンなど、様々なビジネス・サービスで予約・決済システムが利用されています。

StripeのCheckout / Payment Linksで予約注文を受け付けている場合、注文時のラベルを[予約]に変更することができます。

## Payment Linksでボタンラベルを変更する

[Payment Linksの作成](https://dashboard.stripe.com/test/payment-links/create)または作成済みのPayment Linksの編集画面を開きましょう。

[詳細設定]を開くと[行動喚起として]セレクトボックスが表示されます。

![スクリーンショット 2022-09-26 17.14.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366300/f9c41f74-ce8f-c9df-828c-da8654772169.png)

ここで[予約]を選択すると、ボタンラベルが[予約]に切り替わります。

なお、2022/09時点では、サブスクリプション商品を登録した場合、ラベルが「申し込む」固定になります。

もしセレクトボックスが表示されない場合は、商品がサブスクリプションになっていないかを確認しましょう。

### APIを利用して、ラベルを変更する


APIでPayment Linksを作成する場合、`submit_type`で変更できます。

```diff_javascript
    await stripe.paymentLinks.create({
      line_items: [{
        price: 'price_1XXXXXXX',
        quantity: 1
      }],
+      submit_type: 'book',           
    })
```

こちらもサブスクリプションでは指定できませんので、ご注意ください。

## Checkoutでボタンラベルを変更する

Checkoutを利用している場合、`submit_type`パラメータを利用します。

```diff_javascript
    await stripe.checkout.sessions.create({
      line_items: [{
        price: 'price_1XXXXXXX',
        quantity: 1
      }],
      currency: 'jpy',
      mode: 'payment',
      success_url: 'https://example.com',
      cancel_url: 'https://example.com',
+      submit_type: 'book',      
    })
```

`book`の他に`pay`(支払う)や`donate`(寄付)、`auto`が選択できます。

なお、2022/09時点では、サブスクリプション(`mode='subscription'`)や決済情報登録(`mode='setup'`)のみのモードでは利用できません。

以下のエラーメッセージが表示されますので、ご注意ください。

```
You can not pass `submit_type` in `subscription` mode.
```

## 寄付についての注意

日本でStripeで寄付を募る場合、**「個人への寄付」は禁止事項**に該当します。

NPO法人などが利用することを想定しておりますので、ご注意ください。

### 日本で寄付を受けるための情報 (Stripe)

https://support.stripe.com/questions/how-to-accept-donations-through-stripe?locale=ja-JP

https://support.stripe.com/questions/requirements-for-accepting-tips-or-donations

https://stripe.com/jp/legal/restricted-businesses

---

## [PR] Stripe開発者向け情報をQiitaにて配信中！

- [Stripe Updates]：開発者向けStripeアップデート紹介・解説
- ユースケース別のStripe製品や実装サンプルの紹介
- Stripeと外部サービス・OSSとの連携方法やTipsの紹介
- 初心者向けのチュートリアル(予定)

など、Stripeを利用してオンラインビジネスを始める方法について週に２〜３本ペースで更新中です。

-> [Stripe Organizationsをフォローして最新情報をQiitaで受け取る](https://qiita.com/organizations/stripe)
exec user process caused: exec format errorの原因と対処法 (ECS)

Rails+Docker環境にて、ECS側(Fargate使用)のコンテナ起動時に下記エラーに悩まされたのでシェアをしたいと思います。
```
standard_init_linux.go:228: exec user process caused: exec format error
```

## 原因
結論から言うとM1 Macで作成したイメージを、コンテナが動作するFargateのCPUアーキテクチャ側が読み込むことができないのが原因のようです。CPUアーキテクチャとはその名の通りCPU側の設計を指しており、この設計には種類があります。有名どころで言うと、x86(intel)とARM（ARM）が存在します。今回問題だったのは、このCPUアーキテクチャがM1でビルドした際はARMで作成され、FargateのCPUアーキテクチャではARM作成されたイメージは対応できない為でした。
試しにターミナルから下記コマンドで、自分のMac(M1)のCPUアーキテクチャを確認したところ確かにARMであることが確認できました。
```
uname -m
```

## 対策
対策として、以下の2案のどちらかで解決することができます。個人的に②の方が、都度都度buildコマンドを打つときに指定がいらないので良いかなと思いました。

### ①Buildコマンド時にプラットフォームを指定する
ECSにpushする際にbuildすると思いますが、build時のオプションで、下記コマンドのように使用するアーキテクチャを指定することができます。
```
docker build -t image-name --platform linux/x86_64 .
```
x86を指定してイメージをbuildすることで、FargateのCPUアーキテクチャにも対応できるようにします。

### ②Dockerfileでプラットフォームを指定する
DockerfileのFROMでイメージを指定する際に、ここでもオプションで、アーキテクチャを指定することができます。
```
FROM --platform=linux/x86_64 ruby:3.1.2
```
上記であればbuildした際に常にx86でイメージを作成してくれる為、少し楽になるかと思います。

### 終わりに
業務で初めてECSを使用したのですが、そもそもDocker自体の知識が少ないこともあり色々と苦戦しました...
今回のケースのように普段は見ることのないようなエラーに度々直撃し、先輩の助けを借り、なんとか調べながら実装までこじつけました。苦労をした分学ぶことも非常に多かったので、今回のケースに限らず別途記事を作成していきたいなと思っています。
Jose Tate

![josetate.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2842685/56dd7f68-c351-fc1a-36ca-cf6e1ef10611.jpeg)
Hi, My name is Jose Tate. I am a professional SEO. I have three year experience of SEO. I have done many Off-Page SEO of different sites. My first priority is to satisfy my client. Learning and Focusing on opportunities in the IT sector and developing professional and technical skills.  My clients are happy with my SEO services.
https://www.josetate.com
EC2でWindows Server構築時のタイムゾーン設定

# はじめに
EC2でサーバー構築時にタイムゾーンがUTCとなりますが、「ユーザーデータ」という項目を設定することによって、起動時に任意の場所へ自動設定することができます。

# 設定する項目

### タイムゾーンを日本にするPowerShellコマンド
```powershell:
Set-TimeZone -ID "Tokyo Standard Time"
```

https://docs.microsoft.com/ja-jp/powershell/module/microsoft.powershell.management/set-timezone

# まとめ

EC2構築時のユーザーデータとしてセットするには下記のようなXMLで記載します。

```xml:ユーザーデータ
<powershell>
Set-TimeZone -ID "Tokyo Standard Time"
</powershell>
```

毎回GUIで設定していましたが、ひと手間減らすことができました。

# 参考文献

https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-windows-user-data.html
あったら嬉しいWebサイトスタイル変更

個人的な備忘録です。
設定しなくてもいいですが、設定することであのWebサイトがほんの少しだけ見やすくなります。

## 前提条件
サイトデザインを変更できる拡張機能を、ブラウザに追加する必要があります。
私は、[Stylus](https://chrome.google.com/webstore/detail/stylus/clngdbkpkpeebahjckkjfobafhncgmne?hl=ja)を使っています。
`Chrome`と`Brave`で利用できることは確認できています。
他のブラウザでできるかは、各自試してください。

そして、`Stylus`に下記スタイルを適用させていいます。

## Githubのプルリク
`github`でプルリクエストを出してからマージする際に、マージ先を間違えたことありませんか。
下記は、マージ先ブランチを目立たせるための設定です。

```
span.commit-ref.css-truncate.user-select-contain.expandable.base-ref span.css-truncate-target {
    padding-left: 12px;
    padding-right: 12px;
    color: #fff;
    background-color: #e45252;
    font-size: 16px;
    font-weight: bold;
    border: 1px solid #e45252;
    border-radius: 70px;
    animation: Flash 1s infinite;
}
@keyframes Flash{
    50%{
        opacity: 0;
    }
}
```
設定すると、嘘みたいに間違いにくくなります。

## Gmailの受信日時
Gmail一覧画面で、受信し一日以上経過するメールは、`受信日`のみが表示されます。
時刻が表示されないわけです。
下記は、Gmailに受信日時を表示させるための設定です。
`日付`だけでなく`時刻`まで表示されます。
```
/* Gmail Date+Time in Mail List Ver.20180603 by nukumori.org */
/* # space adjustment */
/* ## define */
  :root
  {
    --datetime-width: 14em;
  }

/* ### ja */
  :root:lang(ja)
  {
/*  --datetime-width: 9.25em; */
    --datetime-width: 11.25em;
  }

/* ### Mac */
  :root body[jscontroller="Gz34U"]
  {
    --datetime-width: 13em;
  }

/* ## apply */
  .xX
  {
    width: var(--datetime-width) !important;
    padding-right: 0;
  }

  .xX:lang(ja)
  {
    width: var(--datetime-width) !important;
  }

/* # for vertical split layout*/
  .apt
  {
    padding-right: 0 !important;
  }

  .apm
  {
    margin-right: 0 !important;
  }

/* # show full date+time of title attribute */
  .apm > span:after, /* for vertical split layout */
.xW > span:before
  {
    content: attr(title);
    color: #000;
  }

  .apm > span, /* for vertical split layout */
.xW > span
  {
    color: transparent;
    overflow: hidden;
    float: left;
  }

  .apm > span > b, /* for vertical split layout */
.xW > span > b
  {
    display: none;
  }

/* # sender width for vertical row layout */
/* ******** deleted 2012-01-21 ********
.yX.xY.apy{
  width:20% !important;
}
.yf.xY.apt{
  width:80% !important;
}
*/

/* ******** added 2018-06-03 ******** */

/* # bold unread */
  .zE .apm,
.zE .xW
  {
    font-weight: 700;
  }

/* # new look 2018 */
  body[jscontroller] .Zs .zA > .WA + .yX,
body[jscontroller] .Zs .zA > .bnk + .yX
  {
/* original width: 100% - (header: 76px) - (icon + date/time: 110px) */
    max-width: calc(100% - 76px - var(--datetime-width) - 34px);
  }

/* ******** date time ******** */
  body[jscontroller] .apm, /* for vertical split layout */
body[jscontroller] .xW
  {
    overflow: hidden;
  }

  body[jscontroller] .apm > span, /* for vertical split layout */
body[jscontroller] .xW > span
  {
    overflow: visible;
    width: calc(var(--datetime-width) + 8px);
  }

/* schedule and attachment icon */
  body[jscontroller] .Zs .zA > .yf
  {
    margin-left: 0;
  }

/* ## horizontal split datetime */
  body[jscontroller] .zA > .xW
  {
    max-width: calc(var(--datetime-width) + 8px);
    flex-basis: auto;
  }
```

設定すると、Gmail一覧画面に受信日時が表示されるので、だいぶ見やすくなります。
FlutterでWebRTCアプリを作るときによく使うライブラリ

# FlutterでWebRTCアプリを作る

[iPresence](https://ipresence.jp/)では普段FlutterでWebRTCとテレプレゼンスロボットを使用するアプリケーションの開発を行っています。  
そんな開発をしていく中でデファクトスタンダードとなっているライブラリを紹介していきます。

### [flutter_webrtc](https://pub.dev/packages/flutter_webrtc) . 

FlutterでWebRTCを使用するためのライブラリです。スマホのネイティブアプリやWeb版への対応もされており大体はこれで解決できます。  
カメラの映像音声だけでなく画面共有機能もサポートされており様々機能をWebRTCのビデオ通話に乗せることができます。  

### [riverpod](https://pub.dev/packages/riverpod) / [hooks_riverpod](https://pub.dev/packages/hooks_riverpod)

Flutterでの状態管理をするのに定番となりつつあるライブラリです。  
特に開発ではhooksと連携するhooks_riverpodを使用してアプリ内でも状態管理を行っています。  
以前はreduxを使用していましたがコードの簡略化、Flutter開発での主流に合わせる形でriverpodを使用するようになりました。

### [freezed](https://pub.dev/packages/freezed)

Flutterでデータモデルを作成するライブラリです。  
immutableなオブジェクトを生成し クローンを作為する`copyWith` メソッドなどを提供してくれます。  

[build_runner](https://pub.dev/packages/build_runner) と組み合わせることで強力にかつ簡単にモデルの作成をしてくれます。

### [go_router](https://pub.dev/packages/go_router)

Flutterでデファクトスタンダードとなっているページ遷移を提供してくれるライブラリです。  
riverpodでの状態管理もやりやすく、簡単な記述でルーティングの管理、リダイレクトの制御もできます。  
日本語のドキュメントが多い点も手を付けやすくおすすめです。  

### [shared_preferences](https://pub.dev/packages/shared_preferences)

ローカルストレージにデータを保存するすためのライブラリです。  
基本はFirebaseのFireStoreにてデータを管理していますが、ローカルストレージにデータの保存(アプリの設定等)が必要な場合に使用します。  

### [mockito](https://pub.dev/packages/mockito) 

テストをする際特定のクラスをモック化する場合に使用します。  
特に外部との通信が必要なるコードなどをmockitoを使ってモック化してテストすることが多いです。  

### [firebase fakes](https://firebase.flutter.dev/docs/testing/testing/) 

Firebaseの機能をテスト時にモック化してくれる公式のライブラリです。  
- firestore
- storage
- auth
- sign in
のみの対応ですがテストで使用するには十分の機能です。  

## 終わりに

今回FlutterでWebRTCアプリを作る際によく使うライブラリの紹介でした。  
各ライブラリの実際の使用方法などは今後紹介できたらと思います。
IKS で構成したデリバリー・パイプライン プライベート・ワーカーの更新

#### はじめに

IKS で構成した デリバリー・パイプライン プライベート・ワーカーで 更新の警告表示が出ていたので更新手順を確認しました。


参考：[Delivery Pipeline プライベート・ワーカーの更新](https://cloud.ibm.com/docs/ContinuousDelivery?topic=ContinuousDelivery-private-workers&interface=ui#update_private_workers)

---

#### 環境

・IKS (IBM Cloud Kubernetes Service) で、デリバリー・パイプライン・プライベートワーカーを構成

構成作業は以下で実施。

https://qiita.com/c_u/items/081033188928abfd355d


---

#### 作業


![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517421/eb98f0b0-23a2-aaee-4cd8-ea98c9faedbd.png)

上記はOutdated 状態のため、更新は推奨で必須ではありませんが確認のため実施しています。

IBMCloud へCLIでログイン、対象のIKSのコンテキストを設定し、コマンドを実行します。

```
$ kubectl apply --filename "https://private-worker-service.eu-de.devops.cloud.ibm.com/update"
clusterrolebinding.rbac.authorization.k8s.io/pw-agent-update-role created
serviceaccount/pw-agent-update-role created
job.batch/agent-updater-1664265494626 created
$
```

数分後、プライベート・ワーカーにも反映されていました。

![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517421/7feb9409-35da-1f5f-b8f5-b8a76453ba60.png)




以下のコマンドでも pipeline-private-worker のバージョンが確認できます。
(作業前には実施していないので事前ログ無しです)

```
$ kubectl -n tekton-pipelines describe deploy private-worker-agent
Name:                   private-worker-agent
Namespace:              tekton-pipelines
CreationTimestamp:      Tue, 27 Sep 2022 17:00:11 +0900
Labels:                 app=private-worker-agent
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=private-worker-agent
Replicas:               1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:           app=private-worker-agent
                    name=private-worker-agent
  Service Account:  private-worker-agent
  Containers:
   manager:
    Image:      icr.io/continuous-delivery/pipeline/pipeline-private-worker:0.14.3
    Port:       <none>
    Host Port:  <none>
    Command:
      /manager
    Environment:
      POD_NAME:              (v1:metadata.name)
      POD_SERVICE_ACCOUNT:  private-worker-agent
      POD_NAMESPACE:         (v1:metadata.namespace)
      AUTO_UPDATE:          disabled
      CLEANER_IMAGE:        icr.io/continuous-delivery/pipeline/tekton/ubi:1.12.0
      DAEMONSET_IMAGE:      icr.io/continuous-delivery/pipeline/pipeline-private-worker-util:2.12.0
    Mounts:                 <none>
  Volumes:                  <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   private-worker-agent-866c56f587 (1/1 replicas created)
Events:          <none>
$
```

---

どのくらいの期間で非サポートになるのかは気になりますね..。


以上です。
LinuxでGoogle Driveにおいてある(超)巨大なファイルをダウンロードしたいとき

500 GBくらいある超でかいファイルをLinux(Ubuntu)サーバーに落としたいことってよくありますよね。

普通にコマンドラインからwgetできるかと思っても、巨大なファイルはウィルスチェックが働かない関係でそのままでは無理です。ちょっとググって見つかった、[こういうやつ](https://zenn.dev/masahiro_kaneko/articles/c788bc552862ff)を使っても、よくわかりませんが動きません。[gdown](https://github.com/wkentaro/gdown)というPythonライブラリでもエラーが出てダメでした。　

最終的には、　以下のQuoraにある手法でうまくいきました。

https://www.quora.com/How-do-I-download-a-very-large-file-from-Google-Drive

1. Google DriveのファイルのIDを取得します(仮にXXXXXとします)。

2. [OAuth 2.0 Playground](https://developers.google.com/oauthplayground/)というのにアクセスし、"Select & authorize APIs"から"Drive API v3"というのをクリック、```https://www.googleapis.com/auth/drive.readonly```を選び、自分のアカウントでログイン、許可します。

3. "Exchange authorization code for tokens"を押すと Access tokenが生えるので、それをコピーします(YYYYYとします)。

4. 以下のコードを実行します。ZZZZZはお好きなファイル名。

```shell 
curl -H "Authorization: Bearer YYYYY" https://www.googleapis.com/drive/v3/files/XXXXX?alt=media -o ZZZZZ 
```

SSHで繋いでいるような場合は、```nohup```をつけておきましょう。
【JavaScriptとCSS変数】シンプルなダークモードの実装

Windowsの設定などでおなじみの「ダークモード」。  
背景が黒っぽく、文字が白系統になるこのモードですが、CSS変数とJavaScriptを用いて作成してみました。  
今後コピペして使い回したいと思ったので、最低限のシンプルな実装です。  

## ソースコード

まず先にソースコードの紹介です。  
各箇所の解説は後述します。  

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Light-Dark</title>
  <link rel="stylesheet" href="./style.css">
  <script src="./index.js"></script>
</head>
<body>
  <h1>タイトル</h1>
  <label for="chk">ダークモード</label>
  <input type="checkbox" id="chk" />
  <p>テキストテキストテキストテキスト</p>
  <button class="btn">ボタン</button>
</body>
</html>
```

```css:style.css
/* ライトモード(通常)用の色を設定 */
:root {
  --main-text: #000000;
  --main-bg: #ffffff;
  --btn-color: #a9a9a9;
}

/* ダークモード用の色を設定 */
:root[theme="dark"] {
  --main-text: #ffffff;
  --main-bg: #000000;
  --btn-color: #32ed6a;
}

body {
  color: var(--main-text);
  background-color: var(--main-bg);
}

.btn {
  background-color: var(--btn-color);
}
```

```js:index.js
window.addEventListener('DOMContentLoaded', () => {
  const checkbox = document.getElementById("chk");

  const darkModeMediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
  const isDarkMode = darkModeMediaQuery.matches;

  // 初期状態でどちらのテーマなのかを取得、それに合わせてページのテーマを決める
  if (isDarkMode) {
    document.documentElement.setAttribute("theme", "dark");
    checkbox.checked = true;
  } else {
    document.documentElement.setAttribute("theme", "right");
    checkbox.checked = false;
  }

  // チェックボックスのchangeイベントにライトモード・ダークモードの切り替えを追加
  checkbox.addEventListener("change", (e) => {
    const isChecked = e.target.checked;
    if (isChecked) {
      document.documentElement.setAttribute("theme", "dark");
    } else {
     document.documentElement.setAttribute("theme", "right");
    }
  });
})
```

## コードについて

CSS、JavaScriptのそれぞれのファイルで何を行っているか、順に見ていきましょう。  

### CSS

* [CSS変数(カスタムプロパティ)](https://developer.mozilla.org/ja/docs/Web/CSS/Using_CSS_custom_properties)  

通常モード(ライトモード)とダークモードのそれぞれの色をCSS変数として設定しておきます。  
設定したCSS変数は、`var()`関数を使ってアクセスすることができます。  

今回は`theme`属性を用いて、ダークモードの時はどの色になるかについても設定しておきます。  

```css
/* :root疑似クラスで定義することで、HTML文書全体で適用できるようになる。 */
:root {
  --main-text: #000000;
  --main-bg: #ffffff;
  --btn-color: #0000ff;
}

/* こちらはダークモード用の:root */
:root[theme="dark"] {
  --main-text: #ffffff;
  --main-bg: #000000;
  --btn-color: #32ed6a;
}
```  

### JavaScript

JavaScriptではモードの切り替えメソッドを定義しています。  
ただし、アクセス時にOSでダークモードが設定されていたらそれを反映したいので、[prefers-color-scheme](https://developer.mozilla.org/ja/docs/Web/CSS/@media/prefers-color-scheme)を使用しています。  

```js
// ダークモードに設定されていたら、prefers-color-schemeはdark、そうでなければlight
const darkModeMediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
const isDarkMode = darkModeMediaQuery.matches;
```

## ブラウザで確認

![light-dark-demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780581/5c0bc2bb-c3e6-0ca3-6dff-ecc12b8fab7c.gif)

## おわり

Reactでも書けそう(というか書ける)。  
なのでそのうち書いて投稿してみようと思います。  
たぶん。
laravelのMigrationでidを設定した時に別名を付ける方法

# 環境
- php:8.1
- laravel:9.23.0

# 対象
- laravelのMigrationでidを設定した時に別名を付けたい人
- idに別名をつけてseeder実行してエラーになった人

# 方法
### マイグレーションファイル
- 他と同じように()の中にカラム名を記入してください

```php:create_users_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id('user_id')->comment('ユーザーID');
            $table->string('name')->comment('ユーザー名');
            $table->string('email')->unique()->comment('メールアドレス');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
};
```

### モデル
- $primaryKeyで設定したいカラム名を指定してください　← **これがポイントだと思います**

```php:User.php
<?php

declare(strict_types=1);

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    use HasFactory;
    protected $primaryKey = 'user_id';
    protected $table = 'users';
}
```
github リポジトリ新規作成後のローカルとの設定方法

# github リポジトリ新規作成後のローカルとの設定方法

※sshキー作成前提
~~~
STEP1. 自分のgithubアカウントにリポジトリを作成
STEP2. ローカルにファイルを作成
STEP3. ターミナル　コマンド "cd" でファイル階層に移動
　　　　もしくはvscodeで開く
↓      ターミナルから以下を順番にコマンド
STEP4. git init ※このファイルをgitで使いまっせ～という感じ
STEP5. git remote add origin git@github.com:(ご自身のリポジトリ).git　※SSHがおすすめだと思う、、、
STEP6. git add .　※とりあえず全てステージする
STEP7. git commit -m "(ここはなんでもいい　※カッコ不要)"
STEP8. git branch -M main　※ブランチ名は変えても変えなくてもいいかも
STEP9. git push -u origin main　※最後は上で設定したブランチ名

※STEP5は、STEP8の後でもいい。
~~~
間違いがあればご指摘をくだされ。
CでQueueを使う

以前は検索したらすぐ見つかっていたんだけど  
最近見つかりにくくなったり、C++のページが引っかかったりしているので


# 定義
```c
#include <sys/queue.h>
typedef struct str_point {
    TAILQ_ENTRY(str_point) entry;
    int x;
    int y;
} point_t;

typedef struct {
    TAILQ_HEAD(tq_head, str_point) head;
    int count;
} mng_point_t;

// いろいろ面倒なので可能ならglobalに置いた方が楽
mng_point_t manager;
```

# 初期化
```c
TAILQ_INIT(&manager.head);
```

# 追加
```c
point_t point;
TAILQ_INSERT_TAIL(&manager.head, &point, entry);
```

# 削除
```c
TAILQ_REMOVE(&manager.head, &point, entry);
```

# ループ
```
for (point_t *np = manager.head.tqh_first; np;np = np->entry.tqe_next) {
}
```