OmniAICreator/Qiita-1.07M huggingface dataset:
Ubuntu 20.04 LTSをちょっと使ってみる

##概要
ubuntu20.04がリリースされたのでVirtualBox を使ってちょっと使ってみる
ついでに少し詰まった場所をメモします
CPU　AMD2700X
メモリ　32g

## 最初に（CPUがAMDの場合）
VirtualBoxを使うの久しぶりなので詰まるだろうと思ったら案の定だった。
ダウンロード、インストール、そして新しく仮想マシンの作成をしたところ、以下のエラーが吐かれた（コピペ）

Not in a hypervisor partition (HVP=0) (VERR_NEM_NOT_AVAILABLE). AMD-V is disabled in the BIOS (or by the host OS) (VERR_SVM_DISABLED). 終了コード : E_FAIL (0x80004005) コンポーネント: ConsoleWrap インターフェース: IConsole {872da645-4a9b-1727-bee2-5585105b9eed}


これはbiosでCPUの設定を変えることで直せた。

解決法
1.biosに入る
2.Advancedを選ぶ
3.CPU Configuationを選ぶ
4.SVMをdisableからenableにする

参考元
https://qiita.com/walk_to_work/items/71e120fa39b25b0dff22

## VirtualBoxを起動
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258846/fcf27bde-d231-8acb-b164-309eb73dec75.png)
改めて新規から新しい仮想マシンを作成、名前は適当「u01」
タイプ(T):Linux
バージョン(V):Ubuntu(64-bit)
を選択する（初期はwindowsなのでそのままだとダメ）
メモリを8g、ストレージを30gに設定した。
それ以外は初期設定のままだ。

もちろんubuntu20.04LTSを入手しておく
https://jp.ubuntu.com/downloadから
『ubuntu-20.04-desktop-amd64.iso』をダウンロードし、
これを最初の起動ハードディスクを選択でえらぶ
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258846/1234ac47-c053-6dff-6f79-4af48c0d4e5b.png)

ここからはubuntuの設定に入る

## Ubuntu初期設定
・・・ぶっちゃけ後は今までのUbuntu 初期設定の方法とあまり変わらないはずだ。
言語を日本語、キーボードタイプはJapanese、時間をTokyoにした。

シンプルなモードを導入したらpythonが最初からついてこなかった。
あれ？Ubuntu に最初からあるんじゃなかったっけ？
と思ったらpython3　で起動できた。
バージョンは確認したところ3.8.2、ライブラリを追加するなら
sudo pip3 apt install python3-pip
でpip3がインストールできる。

ここからubuntuでpythonを弄る作業に入ろう
LaravelのWebpackの速度改善

#watchがおそすぎる

* CPU負荷が常に大きい場合は監視対象が多すぎる可能性が高い
* `/node_modules/`をwatchの監視対象から外す

```webpack.mix.js
const mix = require('laravel-mix')
mix.webpackConfig({
  watchOptions: {
    ignored: /node_modules/
  }
})
```
参考：
[WebpackでHot Module Replacementを使用する時のCPU使用率を改善する](https://pc.atsuhiro-me.net/entry/2018/01/25/212842)
[How to ignore node_modules when running the watcher in Laravel Mix & Nuxt.js](https://journal.simondepelchin.be/2019/07/18/how-to-ignore-node_modules-when-running-the-watcher-in-laravel-mix-nuxt-js/)

# コンパイルが遅い

* HardSourcePluginをインストールする

```bash
# インストール
npm install --save hard-source-webpack-plugin

# アンインストールの場合
npm uninstall hard-source-webpack-plugin --save
```

```webpack.mix.js
var HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
mix.webpackConfig({
    plugins: [
        new HardSourceWebpackPlugin()
    ]
})
```
参考：
[Webpackのコンパイル速度改善HardSourcePlugin](https://qiita.com/ktr1211/items/6aff7e907ff2fff62784)
Apex 设计模式

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/2d85a618-ff46-ad54-4027-dc57cff1dbb0.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/3bea0499-709a-bf82-b6a0-a190a9ab8027.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/3b778f8a-9b0c-be24-af70-2ab667339e27.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/eaf09233-f43d-7130-4342-c04e031fbc65.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/0b6dd634-852a-b4a4-7abf-022aa3b14655.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/ec130112-3f7e-9c63-79ae-056d53608164.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/3076333b-0641-752b-d92a-5dc6f3a189f6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/23d1af9d-26e5-7ab4-3d2d-c1f6d4ecdb90.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/f927112c-5e34-b6e0-0f3b-cc1beabd4041.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/58435a56-cb0a-3857-1b87-9fa23109d7f1.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/422cca9f-38af-7b42-528a-623a90f168ae.png)
【Github Actions】独自の環境変数設定方法

## 概要

ymlファイルに書きたくないTokenなどをGithub ActionsのJobで使いたい時の方法

## 変数をGithubの設定に追加

Github Actionsを設定したいrepoのSettings > Secretsにアクセスします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19716/f06444bd-7350-25be-e738-68aa6b6b3ea9.png)

アクセスをしたら、<b>Add a new secret</b>をクリックして、変数を追加出来ます。
> 変数名は大文字で登録しましょう。

## job定義ファイルで環境変数を使用する

Githubのsettinsで設定した環境変数はymlファイルに以下のような形で展開できます。
例： `HOGE_TOKEN`のような環境変数を設定したとします。


```yml
run: hoge --token=${{ secrets.HOGE_TOKEN }}
```

のようにして使用することが出来ます。
Visual Studio Code インストール JavaScript / VBScript編

Windows の開発環境も、やっと無料で構築できるようになりました。
Visual Studio Code は、非常に軽く使いやすいようです。

私は、Excel、Access を使って、Officeアプリを作っているのですが、Web関連の開発を Visual Studio Code を利用するようにしました。

このページは、開発環境構築用の備忘録です。

## Visual Studio Code のインストール
Visual Studio Code(以下、VSCode)をインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93227/5b1d0ddd-f056-b149-c3a2-268287aabdc3.png)


## VSCodeを日本語化
Japanese Language Pack
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93227/cde5b9fd-b1a8-8819-38e4-2cb915cbeec3.png)


ここまでの環境は、誰でも必要ですが、
ここからは、開発する言語により、インストールする拡張機能が違います。

## JavaScript を開発するために必要な環境
Vetur
Vue.jsコードのシンタックスハイライトやコード補完
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93227/2baebb73-f70f-70c1-4844-3ad3f3fe2421.png)

Live Server

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93227/2d08e013-50bb-e872-d3e8-a2322a395de3.png)


## VBScript を開発するために必要な環境
Code Runner
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93227/27846c9f-a724-5298-b56c-b36f578ca9d2.png)
LaTeX WorkshopでSumatraPDFを使う

Wiki等のものをコピペしても動かなかったので調べました．
#設定
settings.json に以下のものを追加します．

```
"latex-workshop.view.pdf.viewer": "external",
"latex-workshop.view.pdf.external.viewer.command": 
        "C:\\(pathが入る)\\Local\\SumatraPDF\\SumatraPDF.exe",
"latex-workshop.view.pdf.external.viewer.args": [
        "-reuse-instance",
	    "%PDF%"
],
"latex-workshop.view.pdf.external.synctex.command": 
        "C:\\(pathが入る)\\SumatraPDF\\SumatraPDF.exe",
"latex-workshop.view.pdf.external.synctex.args": [
        "-reuse-instance",
        "-forward-search",
        "%TEX%",
        "%LINE%",
        "%PDF%"
],
```
これでforward searchとpdfの表示ができました．inverse searchはTeX Wikiのもので動きました．
参照：
James-Yu/LaTeX-Workshop View
https://github.com/James-Yu/LaTeX-Workshop/wiki/View,
TeX Wiki : SumatraPDF との synctex 連携
https://texwiki.texjp.org/?Visual%20Studio%20Code%2FLaTeX#g142ea7e
RaspberryでGPIOをサポートしAzureEdgeで動かす場合にエラーが/dev/gpiomem: Permission deniedが出るときの対処

# AzureEdge on Raspberry with GPIO
AzureIotでデバイス部分を担当するサービスであり、Dockerが動作するので自分で好きなコードを書き、データをAzureHubに送ることができます。
Iotなのでセンサーのデータを送りたいと思い、まずGPIOでタクトスイッチが押されたときにメッセージを投げるという[プログラム](https://qiita.com/k-yamamoto/items/056ec8c6adbf55cb9365)を書いてみました。

# 現象
AzureEdgeのサンプルプログラムを作成しGPIOのコードを組み込んだところ、
wiringPiSetup: Unable to open /dev/mem or /dev/gpiomem: Permission denied.
  Aborting your program because if it can not access the GPIO
  hardware then it most certianly won't work
  Try running with sudo?
というエラーが発生しました。
[前回](https://qiita.com/k-yamamoto/items/056ec8c6adbf55cb9365)この現象が出ていたので、さっそくdeploment.template.jsonにあるcreateOptionsに

```json
"HostConfig": {
   "Privileged": true
}
```
を追加しましたが、エラーは解消せず。

# 対処
ネットを見回りしていたところ[これ](https://sandervandevelde.wordpress.com/2020/02/09/iot-edge-docker-module-with-gpio-support-on-rpi/)が発見されました。
みたところDockerfile(ラズパイなのでDockerfile.arm32v7)に

```dockerfile
RUN useradd -ms /bin/bash moduleuser
USER moduleuser
```
がいけないことが判明。これはmoduleuserという一般ユーザを作成し、そのユーザで動作させるといったようです。
この２行をコメントアウトしたら動作しました。

# 結果
* createOptionsにPrivilegedを記載
* moduleuserを無効にする

AzurwIorサイコー！！
TypeScriptでPromiseの型が複数の時の書き方

# TypeScriptでPromiseの型が複数の時の書き方

表題の件、検索しても有益な情報が見つからなかったので記載
単純にPromiseの型定義でパイプでつなぐだけ

## 確認環境
Typescript 3.8.3
MacOS 10.14.6


## sample
以下の例だとFlileReaderからreadAsTextで読み込み完了したとき、resultの型である
`string|ArrayBuffer|null`をPromiseに定義するだけ

~~~ typescript
export async function readFile(file: File, ):Promise<string | ArrayBuffer | null> {
    return new Promise<string | ArrayBuffer | null>((resolve, reject) => {
        const reader: FileReader = new FileReader();
        reader.onloadend = () => resolve(reader.result);
        reader.readAsText(file);
    });
}
~~~
IPアドレスとは

# IPアドレスは何のために必要なのか
結論から言うと、**WEBサーバーが情報を送ったりもらったりするために必要**なもの。
WEBサーバーって何なのって思っている人は、以下の記事を読んでください！
[サーバーって何？？] (https://qiita.com/Nyanmaru-12/items/c1f7ed517227206d347a)


# IPアドレスは一体何なのか
**サーバーやコンピューターに設定された住所**みたいなものです。
つまりこれを設定していないとどこに届ければいいのかが分からないというわけです。
もうちょっと具体的に掘り下げましょう。
『郵便局は皆さん宛に荷物を届けてくれます。
配達員の皆様は住所を見て、荷物を届けます。』
**この仕組みがIPアドレス**と似ているのです。
・郵便局＝インターネット
・荷物＝情報
・配達員＝WEBサーバー
・住所＝IPアドレス
上記のように組み換えて読んでみよう。
『**インターネット**は皆さん宛に**情報**を届けてくれます。
**WEBサーバー**の皆様は**IPアドレス**を見て、**情報**を届けます。』

# IPアドレスの種類
以下、２種類あります。
・グローバルIPアドレス
・プライベートIPアドレス
それぞれの特徴を見ていきます。

## グローバルIPアドレス
これが上記でいうところの住所になります。
**つまり、世界で１個しかありません。**
例えば、東京都、〇〇区、□□町、△△ー△、××マンションは世界に１個しかありませんよね。
また数字は「数字.数字.数字.数字」と４つ続きます。
(数字は３桁だったり、二桁だったりします。)

## プライベートIPアドレス
上記のマンションの例でいうところの部屋番号になります。
「〜号室」の部分になりますね。
注意しておきたいのが、ここにも「数字.数字.数字.数字」が入ります。
つまり、**グローバルIPアドレスとかけ合わさると数字列が８個連続**になるということです。

# まとめ
- [x] WEBサーバーが情報を送受信するのに必要なのがIPアドレス。
- [x] IPアドレスには２種類ある。
- [x] 平たく言えばIPアドレスは居場所を示しているようなもの＝住所
【MySQL】データベースとユーザーの作成

# 目的
スクレイピングのデータを格納する場所を作る。

### 手順
rootユーザーとしてサーバーに接続

```
$ mysql -u root -p'パスワード'
```

データベースを作成

```
mysql> CREATE DATABASE 'データベース名' DEFAULT CHARACTER SET utf8mb4; 
```

ユーザー、パスワードの作成
パスワードは英数字と特殊文字の指定が必要

```
mysql> CREATE USER '任意のユーザー名'@localhost IDENTFIED BY '任意のパスワード'
```

作成したユーザーにデータベースの読み書き権限を付与する。

```
mysql> GRANT ALL ON 'データベース名'.*TO 'ユーザー名'@localhost; 
```

以 上
IQ Bot トラブルシューティング：ログイン画面で「Register IQ Botのエラーメッセージが出たとき

IQ Botのログイン画面を起動した際、以下のエラーが出たときの対処方法です。

![Register IQ Bot.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/dcc32392-38de-c1d7-8a7c-6d2cb5ba3b89.jpeg)
このエラーは状況によって多様な原因で起こるのですが、候補となる対処方法をいくつか挙げてみます。

##①CRにIQ BotのURLが登録されていない

IQ Botをインストールしたら、CRの設定画面でIQ BotのURLを登録する必要がありますが、それをやっていない場合にこのエラーが出ます。
![CRの登録画面.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/d402dc28-d387-1eb1-ca8a-ed8c17d48423.jpeg)

上記が登録されていなかったら、「編集」を押して登録しましょう。
登録されているのにやっぱりIQ Bot側でエラー……という場合は次へ。

##②CRがまだ立ち上がっていない

サーバを起動したてのときなど、CRが立ち上がっていないタイミングでIQ Botを起動した場合もこのエラーが出ます。
CRでBat Gatewayが出る場合なども同様です。

この場合は、CRが立ち上がるのを待ってからもう一度IQ Botを起動しましょう。

それでもやっぱりエラーが解消しない場合は、次へ。

##③IQ Botにアクセスしたブラウザのキャッシュクリア

IQ Botにアクセスした端末のブラウザのキャッシュにエラーが出たときの接続情報が残ってしまっている可能性があります。

キャッシュクリアのやりかたは以下のリンクを参考にしてください。

Chromeの場合：
https://support.google.com/accounts/answer/32050?co=GENIE.Platform%3DDesktop&hl=ja

Internet Explorerの場合：
https://cs.myjcom.jp/knowledgeDetail?an=000004278

それでもやっぱりエラーが解消しない場合は、以下へ。

##④CRサーバのリバースプロキシサービスの再起動

CRサーバのサービスにエラーの接続情報が残ってしまっている可能性もあるので、該当サービスを再起動します。

Windowsの「サービス」から、「Automation Anywhere Control Room Reverse Proxy」を右クリックして再起動します。

![対処方法.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/f226a142-3277-3ed0-9fb6-11befe4b9eba.jpeg)

##⑤Configurations配下の.batファイルを使ったリブート

IQ BotのConfigurationsフォルダ（デフォルトから変えていなければ`C:\Program Files (x86)\Automation Anywhere IQ Bot A2019\Configurations`）の中にある、以下の.batファイルを順に右クリック→管理者として実行し、しばらく待ちます。

- stopanduninstallallservices.bat
- installandstartallservices.bat

※この処理をかけた直後は、②の原因で同じエラーが出続ける場合があるので、実行してからしばらく待ちます。

経験上99％はここまでで解決するはずなのですが、これでも解決しないときは以下へ。

##⑥DBとの接続にWindows認証を使っている場合

IQ Botのインストール時に、DBとの接続設定でWindows認証を使っている場合、ログインの「NT AUTHORITY/SYSTEM」がsysadmin権限を持っている必要があります。権限がついていなければ、つけた上で⑤を実施します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/140dc375-68df-4cb2-233b-39e7a341ba0f.png)

上記のトラブルシューティングは、公式ドキュメントサイトの以下のページに準拠しています。

https://docs.automationanywhere.com/jp-JP/bundle/iq-bot-v6.5/page/iq-bot/topics/iq-bot/install/custom-mode-installation.html

##⑦DBが変

ごく稀に、インストールの際に、IQ Botの登録情報がDBにうまく反映されない場合があるようです。
筆者は一度だけこのパターンを経験しました。

IQ BotのDBサーバでConfigurations＞dbo.Configurationsの中身を確認します。
（下図の「dbo.Configurations」を右クリックして「上位１０００行を表示」を選択すると結果が出ます）

###V11.3.5以降およびA360の場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/60266a77-cda4-55d5-9504-16f2c82ee43e.png)

###V11.3.4以前の場合

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/322c5161-df96-8f52-73b3-1fb9af61d7c2.png)


上記の図では「appRegistered」がtrueになっていますね。これがあるべき姿です。

この項目がごく稀にfalseになっている場合があるので、その場合は手動でtrueに直します。
（上図の「dbo.Configurations」を右クリックして「上位２００行を編集」を選択すると、表の中身を編集できます）

#まとめ

以上が筆者が知る限りの「Register IQ Bot」のエラーの対処方法ですが、他にもわかった情報があれば都度追記します。

<検索用> not registered
Google Maps APIのPolyLineをデコードする関数(Python3)

以下のページを参考に作らせていただきました。感謝。
https://www.codeproject.com/Tips/312248/Google-Maps-Direction-API-V3-Polyline-Decoder

ビット演算とか全然やったことなかったので、勉強になりました。

```python
def decode_polyline(enc: str):
"""
    Parameters
    ----------
    enc : str
        encoded string of polyline, which can be aquired via Google Maps API.

    Returns
    -------
    result : list
        each element in `result` contains pair of latitude and longitude.
"""
    if enc == None or enc == '':
        return [[0, 0]]

    result = []
    polyline_chars = list(enc.encode())
    current_latitude = 0
    current_longitude = 0
    try:
        index = 0
        while index < len(polyline_chars):
            # calculate next latitude
            total = 0
            shifter = 0

            while True:
                next5bits = int(polyline_chars[index]) - 63
                index += 1
                total |= (next5bits & 31) << shifter
                shifter += 5
                if not(next5bits >= 32 and index < len(polyline_chars)):
                    break

            if (index >= len(polyline_chars)):
                break

            if((total & 1) == 1):
                current_latitude += ~(total >> 1)
            else:
                current_latitude += (total >> 1)

            # calculate next longitude
            total = 0
            shifter = 0
            while True:
                next5bits = int(polyline_chars[index]) - 63
                index += 1
                total |= (next5bits & 31) << shifter
                shifter += 5
                if not(next5bits >= 32 and index < len(polyline_chars)):
                    break

            if (index >= len(polyline_chars) and next >= 32):
                break

            if((total & 1) == 1):
                current_longitude += ~(total >> 1)
            else:
                current_longitude += (total >> 1)

            # add to return value
            pair = [current_latitude / 100000, current_longitude / 100000]
            result.append(pair)

    except:
        pass
    return result
```
.ebextensions で環境変数を扱う方法

Elastic Beanstalkで.ebextensionsの中で、デプロイ環境毎に切り替えたいプロパティや、コード中にいれたくないプロパティを設定したいことは多いと思います。
その場合は、下記のように、関数 `Fn:GetOptionSetting` を使用して、環境プロパティを参照することができます。


```yml:.ebextensions/00.option.config
option_settings:
  aws:elasticbeanstalk:environment:
    LoadBalancerType: application

  aws:elbv2:loadbalancer:
    IdleTimeout: 300

  aws:elbv2:listener:443:
    DefaultProcess: default
    ListenerEnabled: 'true'
    Protocol: HTTPS
    SSLCertificateArns:
      "Fn::GetOptionSetting":
        Namespace: "aws:elasticbeanstalk:application:environment"
        OptionName: "ACM_CERT_ARN"
        DefaultValue: ""
```

あとはeb環境作成時に、環境プロパティを設定すればOKです。

```bash
$ eb create --envvars "ACM_CERT_ARN=${cert_arn}" newenv
```

`Fn:GetOptionSetting` ではネームスペースや、オプション名の選択で、他の各種設定も取得できます。

https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/command-options.html
テレワーク監視ツールだって！？とんでもねえ！

# テレワークが始まったら監視ツールが導入された

テレワークの開始と同時に、マウス・キーボードイベントを定期的に収集する監視ツールが導入されてしまった...

## 監視されてまでテレワークしたくない！

**マウスイベントを定期的に送信すればいいんじゃね？**

## 作ってみた

https://github.com/MasatoHanayama/CounterHooker

## CounterHooker

WindowsのMOUSEEVENTF_MOVEを3~10秒間隔で送信します。
アプリケーションは最小化時にタスクトレーに格納されます。
GPLライセンスなので自由に使ってください。
CSSのサイズ指定 px,%,rem,emについて調べてみた【個人メモ】

[CSSでのサイズ指定はどれがいい?「px」「%」「em」「rem」の違い](https://www.sejuku.net/blog/75559)

上記で学習。

rem は rootのem ? と覚えればいいのか？
MySQLのログインパスワードを忘れた場合

## 開発環境
macOS Catalina 10.15.4
mysql 8.0.17

## 前提
homebrewでmysqlをinstall済み

# エラーの内容
以下を実行しログインを実行

```
$ mysql -u root 
```

すると..以下のようなエラーが発生

```
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

```

## 解決方法
パスワードを変更したらうまく行った。

### セーフモードで起動

```
mysqld_safe --skip-grant-tables &
```

### Mysqlを起動

```
$ mysql
```

### 新しいパスワードを設定
```
mysql> SET PASSWORD FOR user = '新しいパスワード'
```

### 新しいパスワードを入力して実行

```
mysql -u root -p'新しいパスワード'
```

うまく行った！
アカウント登録で使用したカスタムバリデーションと正規表現のメモ

以下のような、入力フォームによくある条件でバリデーションかけたいときのメモ
・アカウント名は半角英数記号もしくは以下の記号のみ有効（ _ - . ）


```ruby:models/user.rb
  # バリデーションを自作
  def valid_account_name
    if account_name !~ /^[a-zA-Z0-9\-_\.]+$/
        errors.add(:account_name, "の内容が不正です")
      end
  end
```
※１ 今回モデルに直書きしていますが、カスタムバリデーションはActiveModel::EachValidatorを継承してカスタムバリデータを実装するほうがいい。
https://railsguides.jp/active_record_validations.html#%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E3%83%90%E3%83%AA%E3%83%87%E3%83%BC%E3%82%BF

※２ check_account_nameみたいな名前はよく使われるけど、何をチェックしているか実装見ないとわからないので、今回の場合だと「有効なアカウント名」みたいなメソッド名のほうがいい。

## 正規表現部分解説

### メタ文字
```
( ) [ ] { } . ? + * | \
```
上記の記号はメタ文字といい、正規表現内で特殊な働きをする。

## !~
正規表現のメソッド =~ の否定。マッチが失敗したらtrueを返す。
上記のコードでマッチが失敗したらバリデーションに引っかかるように。

## / 
/で始まり/で終わっているが、これは正規表現の条件はここからここまでだよという範囲を明示するためのもの。
調べてみると/は何の意味も持たない記号で、実際はどの文字でもいいけど慣習的に「/」を使うことが多いそう。

## ^
/^だと行頭という意味に。
[^のように[]の中で使うと否定形の意味となる。

## $
行末という意味に。

## [ ]
いくつかの文字列の中から1文字にマッチさせたいとき[]を使う。

## -
ハイフン(-)は文字の範囲を表すメタ文字。
文字クラス内に別の文字クラスを含めることができる。（ [a-z[0-9]] は [a-z0-9]と同じ意味を持つ。）

## a-z
小文字英字

## A-Z
大文字英字

## 0-9
1桁数字

## \
直後の文字を通常文字として扱うと行った文字エスケープの意味を持つ。
メタ文字を文字として利用したいときに使う。

## +
繰り返しのメタ文字で、１回以上の意味を持つ。(0回以上だと*)


# \A と \z（追記）
上記の正規表現では行頭行末を^と$で記載しているが、Rubyでは \A と \z に置き換えたほうがいい。（エラーは出ないが警告がでる）

---


以下参考にした記事
https://qrunch.net/@hikey/entries/HZv7DnkeDThTjl5b
正規表現はRubyリファレンスから
https://docs.ruby-lang.org/ja/latest/doc/spec=2fregexp.html
Visual Studio CodeでCompareする【編集中】

【不明点あればコメントからご質問ください】
[VS Codeでファイルを比較し、差分（diff）を表示するには](https://www.atmarkit.co.jp/ait/articles/1806/08/news028.html)
上記記事に従って実施。


①Ctrl+Shift+P でコマンドパレットを開く
コマンドパレットを開く方法はこちら
[Visual Studio Code でコマンドパレットを開く方法](https://medium.com/@yohhatu/visual-studio-code-%E3%81%A7%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%83%91%E3%83%AC%E3%83%83%E3%83%88%E3%82%92%E9%96%8B%E3%81%8F%E6%96%B9%E6%B3%95-928bf6441206)

ファイルを
エンジニアブログ移転のお知らせ

日頃より記事をご覧いただき、誠にありがとうございます。

クイックガードエンジニアブログとしてQiitaの更新を続けてまいりましたが、
この度社内エンジニアブログの全面リニューアルに伴い
Qiitaで記事の更新を終了し、「QG Tech Blog」へ移転することに致しました。


URLはこちらになります。
**「QG Tech Blog」**
**https://tech.quickguard.jp/**


お手数をおかけいたしますが、お気に入り・リンク等のご変更をよろしくお願い致します。
また、これまでQiitaに掲載しておりました記事も、「QG Tech Blog」へ移行済みですので引き続きご覧いただくことができます。


今後とも「QG Tech Blog」を、どうぞよろしくお願い致します。
06.Heroku Connect 紹介

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/f0153e81-32f8-417a-5aa4-905f67eb5433.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/dd117ee1-0f5d-842f-5f52-b7332a42a73b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/a395df6c-9846-02bd-beda-6c48e803649f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/f0334b9a-87e3-7d0b-60ff-f1aab284edf3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/7cfc161a-35ab-dc7b-d4cc-a4d340ebda93.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/5a23340b-5b79-838f-702a-9e8807736c6f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/d7896531-1bd0-52fc-16b6-4ffa02678a19.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/4799593c-dba7-a8ac-cb2d-2c53132690e9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/d8978e57-a149-9489-ce5f-c9b5de58aa38.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/c339cd66-20d6-31df-882b-df6ded51ff33.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/28c520ea-7e48-5ff0-951f-4f6990c118c7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/d3353811-bcdc-001e-4c70-4d9398086c39.png)
05.Salesforce と Heroku のインテグレーション方法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/c8900517-f997-1621-ece0-70a389d9031d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/207f11cf-2a80-ba04-0f8c-5c7df5975e14.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/d824caa8-05f4-6f90-e578-7227ebc4ccb0.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/68b98abc-9273-8941-15e8-96ce4c1851c1.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/bf78ef11-9e7f-0728-48e9-c5dad92306f9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/016963c0-e78b-c4a4-daef-2ff55a6b0e55.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/f826c1b1-bc59-3e04-50de-4bd97804a1f2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/43449339-feb0-020d-a795-c3e88644520a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/c400759b-461f-76b9-661b-7248b4dcce11.png)
04.Heroku を使用した 継続的インテグレーションと継続的デプロイ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/f42e7bb8-51f1-e506-0d94-b6f854c18649.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/769a1f3b-c7eb-344f-887f-3b2eae33889c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/04d27fcd-8af6-58f4-c387-d4dde6272497.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/56fde012-ff24-215a-0599-1464d57e2cda.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/7f6f672a-35ca-add4-3ce9-fb5be28af6a8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/fec74207-d069-e803-c3d7-32cf461ea55b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/e784d815-e0b9-0059-9460-a3551a706b3d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/27541882-fb28-8990-44a8-20822133cb46.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/3d22362f-4e30-d95d-3790-80a3a60da9e3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/be55af7b-c9ed-fd04-1036-8244a6bf1088.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/9d246628-67ca-fc83-58ab-3eac1ede9e33.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/dcd84bc7-8977-bf12-f2cd-ed184d6b4042.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/d1a68d55-b0c1-e751-b59b-69ce6e9a4b89.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/6d42c815-918d-813b-1ac5-022600b1423d.png)
DjangoのModelでleft outer join

# きっかけ
地味にDjangoのORMでLeft outer joinの情報が見つかりにくかったのでメモ。

# DjangoのORMで結合といえば

よく`select_related()` と `prefetch_related()`なんかを使ってモデルが外部キー指定している項目は引っ張ってこれる。

```
class User(models.Model):
    name = models.CharField()

class Comment(models.Model):
    user = models.ForeignKey(User, null=True)
    content = models.CharField()
```

例えばこんなモデルが定義されている場合、次のように引っ張れる。

```
comment = Comment.objects.select_related().first()
print(comment.user.name)
```

1データを基準にするだけなら逆引きもできるらしい。

```
comments = User.objects.get(pk=1).comment_set.all()
# id=1のUserを保持するCommentを抽出できる
```

↑のようなことをやっているとDjangoの結合は大体Inner joinであることが分かってくる。
集計系の操作をやり始めて、outer joinってどうするの？ってなってくる。

# left outer joinやり方

```
comments = Comment.objects.filter(user__isnull=True)
```

だそうです。

# まとめ

一回調べたのに忘れたからメモった。
結合するには項目が`models.ForeignKey()`で宣言されていることが重要。
（でないとcomment.user.nameみたいなこともできない）
03.Heroku+Node.jsの使い方

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/cd89951d-871e-9bd8-045a-bac4cdfb1a91.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/3e90e533-1733-c94f-876b-a89842f88d58.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/5c327cf8-9d8f-6563-1925-9d2fb69c322f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/2838dfa2-e1a7-e66f-fd05-09d90c749312.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/2b911c89-2bfe-8189-8c88-b04492af584c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/96711d1e-906c-0ff5-9646-c4a922d7fc1b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/8c2ccaae-2370-96b3-9cfe-b226525f162f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/2b4a3a03-b6d5-338d-77ae-39a131a17309.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/1e2f9de6-ae79-828b-b725-3e66e180bb68.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/c58ee836-50cf-4a9c-c92b-9961996452dd.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/2e2d8426-5373-778c-c2e9-d6d2569a2cb9.png)
AppGoat：その他の脆弱性


# エラーメッセージからの情報漏えい
エラーメッセージ出力を有効にしたままウェブサイトを運用することで、エラー発生時のメッセージからファイルやデータベースなど攻撃のきっかけとなる情報を提供してしまう問題、セキュリティ上の脆弱性。

## 脆弱性の原理
エラーメッセージをページ上に出力する際の設定に問題がある。
そのため、エラーが発生する入力を受けた際に公開するべきではない情報を提供してしまう。

## 脆弱性が悪用された際の影響
直接の影響はないが、ファイルやデータベースなどの情報が漏洩してしまい、別の手段による攻撃のきっかけとなりうる。

## 検査方法
エラーを出力するようなリクエストを送り、発生したエラーメッセージを確認する。
不正なURLの指定、想定しない入力などを行うとよい。
重要な情報がエラーメッセージを確認できる場合、脆弱性がある。


## 対策方法
エラー出力時の設定が問題なので、余計な情報を表示しないように設定するとよい。

- 実行環境設定によるエラー出力に関連する項目を無効化する。
- デバッグオプションによるデバッグ出力を無効化する。


# オープンリダイレクト
正規サイトのリダイレクト先を不正なものに書き換える不正なスクリプトにより、ユーザが想定しないページに飛ばされ被害を受ける脆弱性。


## 脆弱性の原理
正規サイトからリダイレクト可能なページを設定していないことが原因である。
正規サイトから罠ページへ飛ばされるような不正なリクエストをユーザが実行してしまった場合、攻撃者が用意した巧妙な罠ページにより情報を窃取される可能性がある。


## 脆弱性が悪用された際の影響
・ログイン情報などの窃取（ここから更に悪用される可能性がある）

## 検査方法
入力欄やクエリストリング中に格納されたリダイレクト先のURLのドメインを別ドメインのものに変更し、問題なくジャンプできる場合は脆弱性がある。

しかし、以下の2つを同時に満たす場合は、オープンリダイレクトの脆弱性とはならない。

- ウェブサイトの管理者以外の人が指定した、任意の外部のドメインに移動することを許可する仕様であること。
- ユーザがウェブサイトの管理者以外の人が指定した、任意の外部ドメインに移動することを認識していること。

この場合、ユーザ側にもリダイレクト先を確認する責任が伴い、安全かどうかをハンダする必要がある。

## 対策方法
根本的な対策となるのは、リダイレクト先のURLを固定化する、リダイレクト先のURLに番号を振り選択することで別ドメインの介入を許さない、などである。

どうしてもできない場合は、リダイレクト先のドメイン名のチェックを行う必要がある。
02.Git＆GitHubの紹介

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/3bc9b121-c687-3c26-2538-cf7b88d4d381.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/2b2d8cd0-555f-c581-6ce8-d50255cef958.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/32a5c359-bdf5-104f-0d6c-9b5b3c6c3cb5.png)
bundlerのバージョンが2.0.1以上だとDockerでエラーが出てしまう場合の対処法

## はじめに
既存のRailsアプリの開発環境にDockerを導入しようとしたところ、bundle installがなかなか上手くいかずに困ったので、その時の対処法について書こうと思います。

今回は、表題の件についてのみ書きますので、既存のRailsアプリにDockerを導入する方法については割愛いたします。

## 環境
- Rails 5.2
- Ruby 2.5.1
- bundler バージョン 2.1.4

## 今回のケース
DockerでRailsの環境を構築する際に、bundlerのバージョンが2.0.1以上だとbundle installに失敗してしまうようです。

こちら、bundle installが上手くいかなかった時のDockerfileになります。

```:Dockerfile
※失敗バージョン

FROM ruby:2.5.1

RUN apt-get update && \
    apt-get install -y mysql-client nodejs vim --no-install-recommends && \
    rm -rf /var/lib/apt/lists/*

RUN mkdir /myapp

WORKDIR /myapp

COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock

RUN gem install bundler
RUN bundle install

COPY . /myapp
```

今回はホストで開発したアプリを、後からコンテナ化した為、コンテナ側にコピーするGemfile.lockには既にホスト側のbundlerのバージョンが記載されていました。
そのバージョンが 2.1.4 だった為、エラーが出てしまったようです。

## 対処法
ver 2.0.1 以上のbundlerを使用する場合、環境変数でbundlerのバージョンを指定する事で、エラーを回避できるようです。

さっそく試してみました。

```:Dockerfile

※成功バージョン

FROM ruby:2.5.1

RUN apt-get update && \
    apt-get install -y mysql-client nodejs vim --no-install-recommends && \
    rm -rf /var/lib/apt/lists/*

RUN mkdir /myapp

WORKDIR /myapp

COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock

ENV BUNDLER_VERSION=2.1.4　  ← 追記です！！！

RUN gem install bundler
RUN bundle install

COPY . /myapp
```

１行だけ追記しました。

```
ENV BUNDLER_VERSION=2.1.4
```
このように、
ENVでbundlerのバージョンを環境変数で指定したところ、上手く行きました！！

## NG例（おまけ）
Dockerでは、bundlerのバージョンを指定する際、環境変数で指定しなければならないようです。
私は環境変数を設定する前に、

```
RUN gem install bundler -v 2.1.4
```
こちらの方法でbundlerのバージョンを指定しようとしましたが、上手く行きませんでした。

ご参考までに！！！
element UI

#横並びにするデザイン
```

     <div style="text-align:  center !important;">
          <el-row>
                        <el-col :lg="{span: 4, offset: 6}" :sm="24">
                          /*lgの場合だけ6空ける

                            <div class="circle">
                                <p>会員登録</p>
                                <h3>無料！</h3>
                            </div>


                        </el-col>
                        <el-col :lg="{span: 4}" :sm="24">
                            <div class="circle">
                                <p>会員登録</p>
                                <h3>無料！</h3>
                            </div>
                        </el-col>

                        <el-col :lg="{span: 4}" :sm="24">
                            <div class="circle">
                                <p>会員登録</p>
                                <h3>無料！</h3>
                            </div>
                        </el-col>

                    </el-row>
</div>


中心に丸を３つ並られる。
01.Herokuの概要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/496c9503-3d19-ca87-4d24-0ee79c48de36.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/88d7e850-1c78-e115-0b5b-9db22b87b062.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/16eafd81-f9b0-d740-deb5-282aac533eb9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/c90465d7-5f4e-a913-b200-88ca1fe7d2e8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/688f5298-7216-4de2-cc3e-c7bd03c05878.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/4b7b2ccc-94df-f710-8d89-f3721976ae7c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/cba12342-2a2e-2d8e-03ae-964031f6bcba.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/e01a17a0-2107-131c-58a8-a09880139786.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332907/5bc1af2a-c723-48da-04e0-413a7acaf07a.png)
GitHub使い方-備忘録-

## 公開鍵の作成  
https://git-scm.com/book/ja/v2/Git%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC-SSH-%E5%85%AC%E9%96%8B%E9%8D%B5%E3%81%AE%E4%BD%9C%E6%88%90
## GitHubとのSSH接続
https://help.github.com/ja/github/authenticating-to-github/connecting-to-github-with-ssh
## リモートレポジトリの使用
```
git remote add origin https://github.com/ユーザー名/レポジトリ名.git
``` 
## 初めのpush
```
git push -u origin --all
```
## リモートレポジトリの消去
```
git remote rm origin
```
セッション管理

##はじめに
　railsチュートリアルをやっていて、そもそもセッション管理の概念とか用語の意味が分からなかったので、ざっくりまとめた。

##セッション管理とは？
　一言でいえば`サーバー`が`ユーザー１人１人のセッション情報を管理すること`。

　セッション情報とは、ユーザーとザーバーがやりとりした記録


##具体的にまとめる

ユーザーがサーバーへ接続する
↓
サーバーは、はじめてきたユーザーのセッション情報を作り、暗号化してサーバーへ保存する。
同時に、暗号化したセッション情報を含むcookieをユーザーへ返す。
↓
次に同じユーザーがアクセスしてきたときは、暗号化されてるセッション情報をサーバーで復号化して、さっきのユーザーが来たことをサーバーが把握する。
↓
データが更新されれば、またセッション情報を暗号化して、クライアントへcookie(更新され暗号化されたセッション情報を持つ)を返す。

##参考
・セッション管理についてスライド資料となっていてわかりやすい
https://www.slideshare.net/carotene4035/sessionrailscookie-store

・cookieの仕組みが図解でわかりやすい
https://saruwakakun.com/it/web/cookie-cache
手元にswagger.yamlがある時にdockerでswagger-uiを手軽に見る


http://editor.swagger.io/#/
このサイトにyaml突っ込めばすぐ見れるが、クソ長yamlだと動作が重いこともあるのでlocalhostでサクサク見たい人は以下のdockerコマンドを叩いて渡れ最上川


#### コマンド

初回コンテナ立ち上げ
`docker run -d -p 8040:8080 -e API_URL=your-api.yaml --name your-api-swagger -v /絶対パス/your-api.yaml:/usr/share/nginx/html/your-api.yaml swaggerapi/swagger-ui:v3.0.5
`

その他コマンド
`docker stop your-api-swagger`
`docker run your-api-swagger`
`docker rm your-api-swagger`

#### アクセス
http://localhost:8040
zabbix4.4のメディアSlackでchat.getPermalinkが失敗する件

# zabbix4.4のメディアSlackでgetPermalinkが失敗する件

zabbixからslackに通知をしたいと、4.4のデフォルトのメディアを使うと、chat.getPermalinkのgetリクエストで、レスポンスの解析(JSON.parse(req.Get(url)))に失敗するので、非常に悩んだ末に解決した話

# エラー
テストすると、「Slack notification failed : SyntaxError: invalid json (at offset 1)」と。。。

# エラー箇所

```
function getPermalink(channelId, messageTimestamp) {

	var req = new CurlHttpRequest();
	req.AddHeader('Content-Type: application/x-www-form-urlencoded; charset=utf-8');

    // ここで落ちる
    var resp = JSON.parse(req.Get(
        '{0}?token={1}&amp;channel={2}&amp;message_ts={3}'.format(
            Slack.getPermalink,
            params.bot_token,
            channelId,
            messageTimestamp
        );
    ));
	if (req.Status != 200 && !resp.ok) {
		throw resp.error;
	}

	return resp.permalink;
}
```

# 正解

辿り着いたのはこのissue
https://support.zabbix.com/browse/ZBX-17518

「response = request.Get(url);」だとエラーを返すよ！

「response = request.Get(url, '');」だと成功するよ！

CurlHttpRequest#getには、第二引数を渡すべし！

```
function getPermalink(channelId, messageTimestamp) {

	var req = new CurlHttpRequest();
	req.AddHeader('Content-Type: application/x-www-form-urlencoded; charset=utf-8');

    var resp = JSON.parse(req.Get(
        '{0}?token={1}&channel={2}&message_ts={3}'.format(
            Slack.getPermalink,
            params.bot_token,
            channelId,
            messageTimestamp
        ), "" // 第２引数を！
    ));
	if (req.Status != 200 && !resp.ok) {
		throw resp.error;
	}

	return resp.permalink;
}
```


# 参考
https://www.zabbix.com/integrations/slack

テンプレートはこれ
https://git.zabbix.com/projects/ZBX/repos/zabbix/browse/templates/media/slack/media_slack.xml

# テスト実行時の最小限のパラメータ


- zabbix_url
`http://zabbix.hogehoge.com/zabbix`

- bot_token
`Bot User OAuth Token`

- channel
`#zabbix`

- slack_mode
`alarm`

- slack_as_user
`true`

- slack_endpoint
`https://slack.com/api/`

- event_tags
`{EVENT.TAGS}`

- event_name
`{EVENT.NAME}`

- event_nseverity
`{EVENT.NSEVERITY}`

- event_ack_status
`{EVENT.ACK.STATUS}`

- event_value
`1`

- event_update_status
`1`

- event_date
`{EVENT.DATE}`

- event_time
`{EVENT.TIME}`

- event_severity
`{EVENT.SEVERITY}`

- event_opdata
`{EVENT.OPDATA}`

- event_id
`1`

- event_update_message
`{EVENT.UPDATE.MESSAGE}`

- trigger_id
`{TRIGGER.ID}`

- trigger_description
`{TRIGGER.DESCRIPTION}`

- host_name
`{HOST.NAME}`

- host_ip
`{HOST.IP}`

- event_update_date
`{EVENT.UPDATE.DATE}`

- event_update_time
`{EVENT.UPDATE.TIME}`

- event_recovery_date
`{EVENT.RECOVERY.DATE}`

- event_recovery_time
`{EVENT.RECOVERY.TIME}`

- event_source
`3`

- host_conn
`{HOST.CONN}`

# 非常に参考になったサイト（感謝！）

https://devlog.arksystems.co.jp/2021/07/27/13746/
指紋認証の使い方 for KDE

# はじめに
ノートパソコン等の指紋リーダ（Fingerprint）をLinuxのKDEで有効にする方法を紹介します。
本記事では、ログインマネージャはSDDMを想定しています。
また、ディストリビューションによっては設定方法が異なる場合もあります。

# Login時の指紋認証設定（SDDM）
`/etc/pam.d/sddm`の一番上に`auth sufficient pam_fprint.so`を追加します。

```terminal
#%PAM-1.0

auth		sufficient	pam_fprintd.so
auth		include		system-login
-auth   	include		pam_kwallet5.so
-auth		optional	pam_gnome_keyring.so

account		include		system-login

password	include		system-login
-password	optional	pam_gnome_keyring.so use_authtok

session		optional	pam_keyinit.so force revoke
session		include		system-login
-session  	optional	pam_kwallet5.so auto_start
-session	optional	pam_gnome_keyring.so auto_start
```
設定後は、パスワード入力欄が空の状態で一度エンターを押すと指紋認証が有効になります。

# ロックスクリーンでの指紋認証設定
sleep後などのロックスクリーンはSDDMではなくKDE側で認証が行われています。
`/etc/pam.d/kde`の一番上に`auth sufficient pam_unix.so try_first_pass likeauth nullok`と`auth sufficient pam_fprint.so`を追加します。

```terminal
#%PAM-1.0

auth 			sufficient  	pam_unix.so try_first_pass likeauth nullok
auth            sufficient      pam_fprintd.so
auth            include         system-login

account         include         system-login

password        include         system-login

session         include         system-login
```
設定後は、SDDMと同様にパスワード入力欄が空の状態で一度エンターを押した後に指紋認証でアンロックできます。

### おまけ（sleep復帰ができないときのトラブルシューティング）
初期設定ではsleep状態から復帰できないことがあります。
ブートローダにGRUBを使っている場合の解決方法を紹介します。

まず、`/etc/default/grub`を開きます。
一部違う部分はあると思いますが、だいたい下のような内容になっていると思います。
そのうち、一番下にある`GRUB_CMDLINE_LINUX=""`を`GRUB_CMDLINE_LINUX="nouveau.modeset=0"`に書き換えます。

```terminal
# GRUB boot loader configuration

GRUB_DEFAULT=0
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="Arch"
GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet"
GRUB_CMDLINE_LINUX=""
```

書き換えたら、`sudo grub-mkconfig -o /boot/grub/grub.cfg`を実行し、先程の設定変更を反映します。
一度再起動すると、sleepから復帰できるようになります。

# sudoでの指紋認証設定
`/etc/pam.d/sudo`の一番上に`auth sufficient pam_fprintd.so`を追加します。

```terminal
#%PAM-1.0
auth		sufficient	pam_fprintd.so
auth		include		system-auth
account		include		system-auth
session		include		system-auth
```

# おわりに
ログイン画面とロックスクリーン、sudoで指紋認証を有効にする方法を紹介しました。

# 参考
- [Ubuntu 18.04 won't wake after screen lock and blank / suspend / sleep - Unix & Linux Stack Exchange](https://unix.stackexchange.com/questions/442057/ubuntu-18-04-wont-wake-after-screen-lock-and-blank-suspend-sleep)
- [SDDM - ArchWiki](https://wiki.archlinux.org/index.php/SDDM#Using_a_fingerprint_reader)
Symfonyの構造　routeとcontroller

```terminal
.
├── bin
│   └── console
├── composer.json　// ここからプロジェクトが始まる
アプリに必要なすべてのサードパーティライブラリがリストされています。
├── composer.lock
├── config // configファイルが格納される
│   ├── bootstrap.php
│   ├── bundles.php
│   ├── packages
│   ├── routes
│   ├── routes.yaml
│   └── services.yaml
├── public // document root(front controllerと言われ、webサーバーによって実行されるファイル
│   └── index.php
├── src // PHP コードが格納される
│   ├── Controller
│   └── Kernel.php
├── symfony.lock
├── var
│   ├── cache
│   └── log
└── vendor
    ├── autoload.php
    ├── bin
    ├── composer
    ├── psr
    └── symfony
```


webFrameworkにある大切な２つの要素、routeとcontroller。

- route
    - ページのURLを定義する。
- controller
    - HTMLやJSONのように、そのページを作成するためのPHPコードを記述する場所。



##コントローラーを使ってみる
###routes.yamlを編集
初期からわかりやすく書かれています。

```routes.yaml
#index:
#    path: /
#    controller: App\Controller\DefaultController::index
```

下記に書き換え

```routes.yaml
index:
    path: /
    controller: App\Controller\QuestionController::homepage
```

###コントローラーを作成
Controllerの中に新しいファイルを作ります。これはActionと言われるファイルです。ページを構築するための作業をさせることができます。データベースのクエリの作成、APIとの通信等々、、。

srcディレクトリに作成するクラスには、namespaceが必須です。
namespaceはApp\以下に作成する必要があります。
use Symfony\Component\HttpFoundation\Response;も必須です。

```terminal
touch src/Controller/QuestionController.php
```


```/src/Controller/QuestionController.php
<?php

namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;

class QuestionController
{
    public function homepage()
    {
        return new Response('Hello World');
    }
}
```

これでサーバーを立ち上げてページを表示してみると、Hello Worldと表示されているはずです。


##参考
Route, Controllers & Responses! > Charming Development in Symfony 5 | SymfonyCasts
https://symfonycasts.com/screencast/symfony/route-controller#play
AppGoat：メールヘッダ・インジェクション


# メールヘッダ・インジェクションとは
メールヘッダを改ざんされ、送信先などの情報や本文を改ざんされうる脆弱性。

# 脆弱性の原理
メールを送信できるウェブアプリケーションの入力欄から改行を含む入力を受け、意図しない宛先や本文の改変を受け入れてしまうことで発生する。
入力受付時のチェックが甘いために発生する脆弱性である。

# 脆弱性が悪用された際の影響

- 意図しない宛先へのメール送信
- メール内容の改ざん
- メールの第三者中継

# 検査方法
メール送信機能を持つウェブアプリケーションのFROM欄などに、改行を含めた値を入れてリクエストを送信する。
このとき、メール本文の改ざんが見られる場合、脆弱性がある。

GET方式を採用している場合、URLのクエリストリングに入っているヘッダの情報も検査の対象となる。

# 対策方法
改行コードが入力されている場合、メールの送信を受け付けないようにする。
AppGoat：HTTPヘッダ・インジェクション


# HTTPヘッダ・インジェクションとは
悪意のあるレスポンス内容の書き換えによりHTTPレスポンスヘッダの出力処理で発生する脆弱性。
クロスサイト・スクリプティングと共通の影響がある。

# 脆弱性の原理
ユーザが入力可能な欄からのリクエストによってレスポンスヘッダの書き換えが行われることにより発生する。
URLの入力欄は対象になりやすい。

具体的には、改行コードを認識してしまうことにより、入力された内容ので悪意のある改変が可能となっている。



# 脆弱性が悪用された際の影響

クロスサイト・スクリプティングと共通の影響がある。

- 任意のCookie発行
- 表示内容改ざん（ニセのフォームの作成、JavaScriptを用いたCookieの盗難にもつながる）
- キャッシュサーバの汚染（ウェブページの改ざんとなり、サーバ側の被害が大きい）



# 対策方法
PHP5.4以降は改行コードを認識しないため、ヘッダの書き換えが発生しない。
そのため、新しいバージョンのPHPを利用することが対策となる。

それ以前のバージョンを使う場合、改行コードが異なるので実装の際は注意する必要があるが、主な対策の方針は以下のとおりである。

- レスポンスヘッダに外部からのパラメータを出力しない。
- 専用APIを用いてリダイレクトやCookie出力を行う。
- ヘッダを生成する外部からのパラメータの改行文字をチェックする。
next.jsで絶対パスを使用する方法(TypeScript)

# babel-plugin-module-resolverをインストール

- babel-plugin-module-resolver: https://github.com/tleunen/babel-plugin-module-resolver

```
$ npm install --save-dev babel-plugin-module-resolver
```

or

```
$ yarn add --dev babel-plugin-module-resolver
```

# `.babelrc`にカスタムルート、エイリアスを設定(`.babelrc`がなければ作成する)


```json:.babelrc
{
    "presets": [
        "next/babel"
    ],
    "plugins": [
        [
            "module-resolver",
            {
                "root": [
                    "."
                ],
                "alias": {
                    "@": "./src"
                }
            }
        ]
    ]
}
```

# `tsconfig.json`にbaseUrlとパスを設定

```json:tsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
  }
}
```


これで`import Button from '@/components/button'`のように使用できる


### package.json
```json:package.json
"dependencies": {
    "next": "latest", (9.3)
    "react": "^16.9.0",
    "react-dom": "^16.9.0",
    "react-redux": "^7.1.0",
    "redux": "^3.6.0",
    "redux-devtools-extension": "^2.13.2"
  },
  "license": "ISC",
  "devDependencies": {
    "@types/node": "^13.13.1",
    "@types/react": "^16.9.34",
    "babel-plugin-module-resolver": "^4.0.0",
    "typescript": "^3.8.3"
  }
```
Firebase、JQueryで作成したサイトがスマホブラウザで表示されない件の調査【調査中】

Firebase、JQueryで作成した下記サイトがスマホブラウザで表示されない件を調査
[あやりちゃんのお世話になっているルームのイベント情報](https://sisterroom-ed073.firebaseapp.com/)

①下記サイトのように変更したがNG

[PCブラウザでjqueryやjsが動いてスマホで動かない場合の対処法](https://webcreator.webmeo.org/blog/365/)

```変更前.js

$(function() {
・・・中略
})
```

```変更後.js
$(window).on('load', function(){
・・・中略
})
```

[javascript、jqueryスマホで動かない：速解決する](https://kiraku-space.com/?p=1307)
上記に記述されてるように、jsの設定を</body>の手前としてがこれもNG
AppGoat：クリック・ジャッキング


# クリック・ジャッキングとは
罠ページの上に正規のウェブサイトを透明にして重ねることで、正規サイト上でユーザの意図しない操作を誘発する攻撃、それを実装されうる脆弱性のことを指す。

# 脆弱性の原理
罠サイトのフレーム内に正規サイトを表示できることが原因。
攻撃者がユーザに罠ページのリンクを踏ませることで、ユーザのブラウザ上に偽装された罠ページが表示される。
正規サイトが透明な状態でレイヤーされているため、ユーザは意図していなくても正規サイトは正規なリクエストとして処理を行ってしまい、被害につながる。

# 脆弱性が悪用された際の影響
主にユーザがログインしていないと利用できないサービスが攻撃の対象となる。

- ログイン後のユーザのみが利用可能なサービスの悪用
- ログイン後のユーザのみが編集可能な設定の変更

# 検査方法

検査ツールから ```X-Frame-Options``` を確認し、```ORIGIN``` か ```DENY``` になっていない場合は脆弱性が疑われる。
# 対策方法
他のサイトでフレーム内にウェブページを表示させないようにすることが対策となる。
```frame```、```iframe``` で表示させないように ```X-Frame-Options``` を ```ORIGIN``` か ```DENY``` に設定する。
AWS初心者が在宅勤務中にAWSの資格を取る記録

# 自己紹介
インフラエンジニアとして4年勤めてました。
主に基本設計～構築、テスト等が担当分野でした。

得意なのは以下です。
・Windows Server（AD周り）
・仮想化技術（VMware vSphere/Hyper-V）
・ストレージ設計/構築（ONTAP）
・ウイルス対策設計/構築（VBCorp）
・キッティング系（クローンとか）

資格取得のための学習は、高校生の時に取得した応用情報技術者以来なので、感覚を取り戻しつつやってます。

# 取得する経緯
・AWSのエンジニアとして働いていきたい！
・給与に反映される→お金もらえる！
・研修の時間を不意に過ごしたくない！

# 取得する予定の資格
・AWSクラウドプラクティショナー
・AWSソリューションアーキテクト

取得するかつ現場で知識を活用できるように努めたい。

#学習方法
①参考書を斜め読み
②Web問題集テストを解答かつ復習
③Udemyを用いたハンズオンや講座の受講

#ざっくりスケジュール
4/20～4/24　参考書を斜め読み時間にあてる+Web問題集に手を付ける（CLF）
4/27～5/1　Web問題集（CLF）+Udemyで模擬問題（CLF）
5/7～5/8　解いてきた問題をひたすら復習
5/11～ Udemyで合格講座的なのを受講
5/28or5/29 受験予定

# その他
参考書を読むことは読むが、ハンズオン形式でないと頭に入ってこないので、以下の割合を意識して進めたいと思う。

Udemy 70%
Web問題集 20%
参考書 10%

参考書で足りない部分を補完する。
ETERNUS用HDDをx86サーバで再利用する

#背景
富士通製ストレージ機器であるETERNUSがお役御免となった。
彡(^)(^)「大容量HDDが大量にあるやんけ！再利用したろ！」

#事象
SASの大容量HDDなので、検証用サーバ等にぶっこんで再利用を計画した所、Raidコントローラが正常にHDDを認識しなかった

#原因
520byteでフォーマットされていた
どうも検証用サーバのRaidカード(P410i)では520byteフォーマットのHDDは読み込めない模様

#対処方法
512byteで再フォーマット
手持ち検証機ではSAS HDDをHBA接続できるものがなかったため、SAS HBAカードを購入

HBAカードにHDDを接続後、OS(CentOS7)を起動しdmesgを確認

```
sd 7:0:0:0: [sdc] 520-byte physical blocks
```

520byteでフォーマットされている事が分かる


sg3_utilsをインストール後、512byteでフォーマット

```
sg_format --format --size=512 /dev/sg3
```


これで再利用可能になる

#520Byteでフォーマットされていた理由


・データ保全性コード　　
　　　　DIF (Data Integrity Field: データ・インテグリティー・フィールド)
　　　　PI(Protection Information：保護情報 )などと呼ばれる

512Byte+トレーラー情報として8byte分追加しデータ信頼性を確保
所謂ストレージベンダーと言われる会社の製品は、一般的にトレーラー
情報を追加し、エンド・ツー・エンドデータ整合性を取って入る模様

ZFSなんかはソフトウェアでやってるよね。正直理解できていません。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624314/26570152-2464-c2c1-bbc3-679fee12006c.png)
syntax error, unexpected 'GET' (T_STRING), expecting ')'で悩んだ件

#はじめに

https://laraweb.net/crud/elementary/
のCRUDアプリの作成を行い、githubにRepositoryを作って、アップロードしたものの、
<img width="1414" alt="スクリーンショット 2020-04-23 16.59.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343721/abd43127-b3c2-f54c-a710-48423b63b9eb.png">

`syntax error, unexpected 'GET' (T_STRING), expecting ')'`
が出てしまい、試行錯誤の末、何とか解消できたので、解決策を記す

#どういった時にエラーとなるか。

1.確認画面遷移時
2.削除しようとする時

ということで確認画面遷移時については、バリデーションで何かおかしいと推測できる
もうひとつについては、formの中かがおかしいを推測できる。

#確認画面遷移時のエラー
##どうやって見つけた？
1,2についてはバリデーションのrequestを渡すところの
`new_confirm(\App\Http\Requests\CheckStudentRequest $req){`
を
`new_confirm(Request $req){`
に
したところ問題なく動いたので
`App/Http/Requests/CheckStudentRequest`に何か問題があることを断定

##原因
上述したように、`App/Http/Requests/CheckStudentRequest`に何か問題があると思い、そこを重点的に見たのだが、エラーを見つけることはできなかった。
それもそのはず、別のところにあったのだから。

##結局どこにあったの？

`/laravel/crudSample/vendor/laravel/framework/src/Illuminate/Routing/Redirector.php`にありました。

`public function home($status = 302)
{
    return $this->to($this->generator->route('student/list), $status);
}`
にあった。
お分かりだろうか？

`'student/list`の後ろに`'`がないのだ。
ここに`'`を入れたらうまく動きました。


#削除しようとする時
削除の時も上をやったら動くようになりました✌️

#最後に

エラーが出たときは、まずは、エラーとなっているコードを見ることをお勧めします。
出ないと半日が簡単に吹っ飛んでいきますから笑

いやほんと笑い事じゃなくてね


作ったソースはこちら
https://github.com/tnatsume/crudSample
Flutter: Could not resolve the package 'google_fonts' in 'package:google_fonts/google_fonts.dart'. （Googleフォントパッケージが機能しない）

#エラー内容
**Googleフォントのパッケージ**を使用するため、**main.dart**に以下のコードを記述しました。

```main.dart
import 'package:google_fonts/google_fonts.dart';
```

```main.dart
Text(
  'This is Google Fonts',
  style: GoogleFonts.pacifico(),
),
```

しかしホットリロードしようとしたところ以下のエラーが発生しました。

```
Could not resolve the package 'google_fonts' in 'package:google_fonts/google_fonts.dart'.
```

翻訳すると、「**'package:google_fonts/google_fonts.dart'パッケージを解決できませんでした。**」という意味です。

#解決策
**pubspec.yaml**ファイルに**google_fonts**のバージョンを入れます。

```pubspec.yaml
dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^0.1.3
  google_fonts: ^1.0.0　//←この行を追加
```

※2020/4/24現在ではバージョン1.0.0が最新ですが、頻繁に更新されておりますので各自以下のサイトよりご確認ください。
[google_fontsバージョン](https://pub.dev/packages/google_fonts/versions)

Terminalにてコマンドを実行します。

```
flutter packages get
```

するとエラーが解消され、Googleフォントが使えるようになります。
![スクリーンショット 2020-04-24 7.57.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578233/f70bab48-4bf7-3faf-d6e0-999713f5abe8.png)

参考記事[[stackoverflow](https://stackoverflow.com/questions/59446354/the-google-fonts-package-in-flutter-app-is-not-working)]
Mapping Data Flowの処理時間の内訳

## 処理時間がいまいち合わない
全体の処理時間は6分（Mapping data flowのみのパイプラインです）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/469aa274-dc03-e2bf-1961-4c8fa6b9ec62.png)
Mapping Data flowの処理は4分半（クラスターセットアップ時間＋処理時間）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/02e79e8c-cf86-8596-6464-6bde862a3a5a.png)

##サポートに確認してみました
仕様を確認した結果では、Data Factoryは以下の順番で処理を進めています。

 1. ExecuteDataFlowアクティビティを実行開始
 2. クラスター作成開始
 3. クラスター作成確認
 4. クラスタージョブ送信
 5. クラスタージョブ完了確認

これらの3、5における確認が約30秒間隔で行われているそうです。
したがって、実際の処理時間とクラスターセットアップ時間とは1～2分程度の時間差が発生するという結果でした。
（2020/4現在）