OmniAICreator/Qiita-1.07M huggingface dataset:
CentOS8とnginxでLet’s Encrypt


[Certbot \- Centosrhel8 Nginx](https://certbot.eff.org/lets-encrypt/centosrhel8-nginx)
に従ってそのままやる。

```
// インストール
# wget https://dl.eff.org/certbot-auto
# mv certbot-auto /usr/local/bin/certbot-auto
# chown root /usr/local/bin/certbot-auto
# chmod 0755 /usr/local/bin/certbot-auto

// ポート開ける
# firewall-cmd --add-service=https --zone=public --permanent
# firewall-cmd --add-service=http  --zone=public --permanent
# firewall-cmd --reload

// いくつかパッケージをインストール要求
# /usr/local/bin/certbot-auto certonly --nginx

// nginx設定編集
# vi /etc/nginx/nginx.conf
        ssl_certificate "/etc/letsencrypt/live/www.hogehoge.com/fullchain.pem";
        ssl_certificate_key "/etc/letsencrypt/live/www.hogehoge.com/privkey.pem";

// 起動してhttpsアクセスできれば成功
# systemctl start nginx

// 自動更新のcron設定（ここはpython3にして設定）
# vi /etc/cron.d/lets-encrypt
0 0,12 * * * root python3 -c 'import random; import time; time.sleep(random.random() * 3600)' && /usr/local/bin/certbot-auto renew >/dev/null 2>&1
```


# 参考

[Let's Encrypt で Nginx にSSLを設定する \- Qiita](https://qiita.com/HeRo/items/f9eb8d8a08d4d5b63ee9)


[CentOS 7に「killall」コマンドをインストールする \| 俺的備忘録 〜なんかいろいろ〜](https://orebibou.com/2016/08/centos-7%E3%81%AB%E3%80%8Ckillall%E3%80%8D%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B/)


こんなメッセージが出てきたらfirewall設定足りてないかも。

```
IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: www.hogehoge.com
   Type:   connection
   Detail: Fetching
   http://www.hogehoge.com.well-known/acme-challenge/xxxxxxxxxxxxxxxxxxxxxx:
   Error getting validation data

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A/AAAA record(s) for that domain
   contain(s) the right IP address. Additionally, please check that
   your computer has a publicly routable IP address and that no
   firewalls are preventing the server from communicating with the
   client. If you're using the webroot plugin, you should also verify
   that you are serving files from the webroot path you provided.
```
今日からのpython

#今日からMacでPythonを使う

この記事ではmac0S10.14.6を使って、python3.7をインストールする方法をみていきます。
###まずはPythonをダウンロード・インストールする。

初めまして、しんちゃんです。今回はPythonのダウンロードについてささっと簡単に解説できればと思います。

[ダウンロード]
1:次のリンクからPythonのダウンロードを行なっていきましょう。ここでは、ダウンロードに伴うネット通信が必要なのでネット接続はマストです。お気をつけてください。
→[Python公式hp](https://www.python.org)

2:Downloadsと書かれたこの部分からMac OS X(マックオーエステン)と書かれた部分をクリック。
<img width="1198" alt="pyhtonDownload.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485454/54bdbf2d-983f-e32d-1289-ef58cec46402.png">

3:ダウンロードが始まったら,右上のアイコンが動き出すので少々お待ちください。
<img width="398" alt="pythonDownload-2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485454/cb751492-ed39-b3ad-7be9-5c8f65ade8ae.png">


4:Downloadが終われば、そのままファイルをクリックすると、Finderの方でインストーラーが起動します。基本的に「続ける」「同意する」で問題ないでしょう。（そうしないと始まらないので）<img width="616" alt="pythonDownload-3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485454/6f4738b3-e9ed-7aee-e549-bdd8c842f164.png">


5:途中インストール先を聞かれますが基本的に変更はなくても問題ございません。（人によって異なるのかもしれませんが、私のインストール先はMacintopsh HD内のapplicationsのところでした。python3.7というファイルにまとまっておりました。）


6:すべて無事にインストールが終われば、次の画面が表示されます。これでインストール完了です。<img width="614" alt="pythonDownload-5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485454/b918158c-e973-8f0c-c25d-6803f95342ed.png">


お疲れ様です。解説をするほどのことでもありませんでしたね。これでPythonを使う準備が整いましたので、ゴリゴリとプログラミングを行なっていきましょ！何かわからないことがあればなんでもご質問ください！
→Twitter(最近作ったので):[@shinchan_tlpu](https://twitter.com/shinchan_tlpu)
→mail : shinchan.tlpu@gmail.com

最後まで見ていただき誠にありがとうございました。私も駆け出しのエンジニアとしてみなさんと知識の共有、是正をしていきたいです。「ご指摘」や「アドバイス」をいただけるのでありますとかなり喜ばしいものです。お手数ですが指南のほどお願いします！

では、またお会いしましょう！
Gitでコンフリクトした時 'This branch has conflicts that must be resolved'  の対処法

##はじめに
Gitの操作をしている時に次のようなエラーが起こりマージができなかったので、その対処法を備忘録として残します。
![picture_pc_c9fe8a8a18b3774717077e036e3a3cce.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438093/0fdb004b-d5ca-bf73-8970-b5290843d63d.png)

##エラーの状況

ファイルがコンフリクトを起こしているので、解決してくださいとのメッセージ。


##対処法

```
$ git checkout branchA  #プルリクしたローカルブランチ(branchA)に切り替える
$ git fetch origin
$ git merge master #コンフリクトを起こしているファイルが表示される
```

表示されたファイルを確認すると以下のような状態になっています。

```Gemfile.
gem 'carrierwave'
gem 'fog'
現在の変更を取り込む｜入力側の変更を取り込む｜両方の変更を取り込む｜変更の比較
<<<<<<< HEAD
=======
gem 'fog-aws'
>>>>>>> master

gem 'coffee-rails', '~> 4.2'
```
必要な変更をクリックする。今回は「入力側の変更を取り込む」を選択しました。

```
$ git add .
$ git commit -m "コンフリクトの修正"
$ git checkout master
$ git merge --no-ff branchA  #コミット画面が開くので「:wq」で抜ける
　Merge made by the 'recursive' strategy.
$ git push origin master
```
以上の処理でプッシュが完了し無事マージされました。



##参考

http://sci.hateblo.jp/entry/pull_request_training
【JavaScript】「CSRF token mismatch.」の回避方法

# クロスサイト・リクエストフォージェリ(CSRF)トークンとは
簡単に言うと許可するリクエストの証明的なもの。

ということで開発中にjavaScripでPOST送信しようとしたときに「CSRF token mismatch.」のエラーが出たときの対処方法。

## javascript

``` javascript
function hoge(value) {
    // form作成
    var form = document.createElement('form');
    // 送信先のURL
    form.action = '/sample/url/';
    // HTTPメソッドはここで指定
    form.method = 'POST';

    // hiddenで引数の値を送信する。
    var send_value = document.createElement('input');
    send_value.type = 'hidden';
    send_value.name = 'key';
    send_value.value = value;
    form.appendChild(send_value);

    // ここからCSRFトークンを送信準備
    var csrf = document.createElement('input');
    // すでに存在しているname="csrf-token"のvalueの値を取得する。
    var token = document.getElementsByName('csrf-token').value;
    csrf.type = 'hidden';
    csrf.name = 'csrf-token';
    csrf.value = token;
    form.appendChild(csrf);
    
    // 送信！
    form.submit();
}
```

## HTML


```html
<a href="#" onclick="hoge('CSRF突破！！')"></a>

<form name="csrf-token" value="1234567890" ></form>

```
grepコマンドとcutコマンドを使って取得したい部分だけを出力させる

#はじめに
これは備忘録です。濃い内容は期待しないでください。

#grepコマンドとは
ファイル内の指定文字列を検索し、その文字列が含まれる行を出力する。
###例

```example.txt
test1 aaa bbb ccc ddd
test2 aaa bbb ccc ddd
test3 aaa bbb ccc ddd
```

```terminal
$ cat example.txt | grep 'test2'
```

```
#出力結果
test2 aaa bbb ccc ddd
```

#cutコマンドとは
ファイル内の各行から指定部分のみ出力する。grepコマンドと似ているが、cutコマンドはより詳しい絞り込みができる（？）

###例
cutコマンドには各種オプションを使い分けて使用する。


```example.txt
test aaa bbb ccc ddd
```

-bオプションはファイルの指定したビット数だけ出力する。例えば-b2-4と指定したら２〜４文字目だけ出力する。

```
$ cat example.txt | cut -b2-4

#出力結果
est
```

-dオプションは、指定した１文字を区切り文字として項目を区切る。基本-fオプションと組み合わせて使用する。
-fオプションは-dで区切られた項目の中から、項目数で指定して出力させたいところだけを出力する。

```
$ cat example.txt | cut -d' ' -f2

#出力結果
aaa
```

#grepコマンドとcutコマンドを使い合わせる
以下のようなファイルがあったとする。

```example.txt
test1 watashi ha tanaka
test2 watashi ha satou
test3 watashi ha suzuki
```

例えば２行目の"satou"の部分のみ出力させたい場合は以下のように打つ。

```
$ cat example.txt | grep 'test2' | cut -d' ' -f4

#出力結果
satou
```
Simple Object Access Protocol Vs. REpresentational State Transfer

**SOAP (Simple Object Access Protocol):**

SOAP is a method of transferring messages, or small amounts of information, over the Internet. SOAP messages are formatted in XML and are typically sent using HTTP (hypertext transfer protocol).

SOAP uses WSDL for communication between consumer and provider, whereas REST just uses XML or JSON to send and receive data.

WSDL defines contract between client and service and is static by its nature.
SOAP builds an XML based protocol on top of HTTP or sometimes TCP/IP.
SOAP describes functions, and types of data.

SOAP is a successor of XML-RPC and is very similar, but describes a standard way to communicate.

Several programming languages have native support for SOAP, you typically feed it a web service URL and you can call its web service functions without the need of specific code.

Binary data that is sent must be encoded first into a format such as base64 encoded.

Has several protocols and technologies relating to it: WSDL, XSDs, SOAP, WS-Addressing.

More on [Spring boot interview questions](http://candidjava.com/tutorial/spring-boot-interview-questions/)


**REST (REpresentational State Transfer):**

Rest is a simple way of sending and receiving data between client and server and it doesn’t have very many standards defined. You can send and receive data as JSON, XML or even plain text. It’s lightweight compared to SOAP.

REST need not be over HTTP but most of my points below will have an HTTP bias.
In case of REST contract between client and service is somewhat complicated and is defined by HTTP, URI, Media Formats and Application Specific Coordination Protocol. It’s highly dynamic unlike WSDL.

REST is very lightweight, it says wait a minute, we don’t need all of this complexity that SOAP created.

Typically uses normal HTTP methods instead of a big XML format describing everything. For example to obtain a resource you use HTTP GET, to put a resource on the server you use HTTP PUT. To delete a resource on the server you use HTTP DELETE.

REST is a very simple in that it uses HTTP GET, POST and PUT methods to update resources on the server.

REST typically is best used with Resource Oriented Architecture (ROA). In this mode of thinking everything is a resource, and you would operate on these resources.
As long as your programming language has an HTTP library, and most do, you can consume a REST HTTP protocol very easily.

Binary data or binary resources can simply be delivered upon their request.
Plain XML or JSON are not RESTful at all. None of them define any controls(i.e. links and link relations, method information, encoding information etc…) which is against REST as far as messages must be self contained and coordinate interaction between agent/client and service.
Goのポインタについて

##Goのポインタについてのまとめ

Javaをやっていてポインタをそこまで意識せずにやっていたので
Goで`＆`と`*`が出てきて混乱しました。

###まずポインタとは
メモリ上の変数が格納されている場所（アドレス）を指す。
アドレスは16進数で表される。

###&(アンパサンド)
これは変数のポインタを**抽出**するもの。
以下の`p`が変数iのポインタ（変数`i`はここにあるよ！）を抽出している。

```go
i := 0
p := &i
```

###*(アスタリスク)
これはポインタが指している実際の変数の中の**値**を示している。
以下の`j`が変数`a`のポインタ(変数`i`)が指す中身の値（0）を示している。

```go
a := 0
i := &a
j := *i
```

###出力してみるとよくわかる

```go
 package main

import "fmt"

func main(){
  i := 0
  fmt.Println(i)
  //結果：0

  p := &i
  fmt.Println(p) //iのメモリの位置
  //結果：0x414020

  j := *i
  fmt.Println(j)
  //結果：エラー（invalid indirect of i (type int)）

  fmt.Println(*p)
  //結果：0
} 
 
```

エラーとなっているのは変数`j`に**ポインタが指す変数の中身の値**が入るはずだが、
変数`i`はそもそも変数で**ポインタではない**ため。

`*`が使えるのは**ポインタを抽出した（&を使った）変数**に対してのみだった
【PHP】cronを使って現在のBTC価格をメールに自動送信する処理

前回の記事に記載した[外部API情報をPHP curlを使ってビットコイン価格だけ取得](https://qiita.com/jyunia0110/items/20bf1ef2f45536f33d62)をcronを使って自動でメール送信する処理をやってみた。

今回も当然ながら自分のメモ用です。
色々ツッコミどころあるかもしれませんが、ご容赦くださいw m(__)m

# 毎日午前10時にメール通知される様にメール送信処理の作成、cronの設定を行う

### まずは
- bitflyerのAPIを使ってBTC取得の処理
- メール送信処理

```php:cron_mail.php
<?php
$url = 'https://api.bitflyer.jp/v1/ticker?product_code=BTC_JPY';

//curlセッション初期化
$ch = curl_init();

//オプション設定
curl_setopt($ch, CURLOPT_URL, $url);//取得するURLを指定
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);//実行結果を文字列で返す

//URLの情報を取得
$result = curl_exec($ch);

//結果の表示
$json = json_decode($result);

//セッションを終了
curl_close($ch);

mb_language("Japanese");
mb_internal_encoding("UTF-8");

$to ='xxxxxx@gmail.com';
$subject = '現在のBTC価格のご案内';
$message = '現在のBTC価格は:' . number_format($json->ltp) . '円です';
$headers = 'From:hogehoge@hoge.co.jp' . "\r\n";

mb_send_mail($to, $subject, $message, $headers);
?>
```

で、次にcron処理。
cronは自動実行するためのもので、以下のプロセスが必要となる。
①phpの場所を確認

```
$which php
/usr/bin/php
```

②`crontab -l` でcron設定を確認(このフローはなくてもOK)

```
$crontab -l
no crontab for name
```

③`crontab -e`でエディタが立ち上がるのでcronの処理内容を記述します。

例えば、1分毎にメール送信する処理する場合は以下のように記述。

```
*/1 * * * * /usr/bin/php /home/www/name/ディレクトリ名/cron_mail.php
```

毎朝10時の場合だと

```
0 10 * * * /usr/bin/php /home/www/name/ディレクトリ名/cron_mail.php
```

となる。

万が一

```
errors in crontab file, can't install.
```

とエラーが表示される場合は記述に問題がある。
よくあるのは`パスの前の日時指定に半角スペースがない場合` がほとんどではないだろうか。

例えば先ほどの処理で

```
010*** /usr/bin/php /home/www/name/ディレクトリ名/cron_mail.php
```
なんてするとエラー表示され、もう一度編集するかどうか聞かれます。
STM32CubeIDEを使ってみよう How To STM32CubeIDE 日本語版 (10) I2Cを使ってみよう3 ssd1306編

STM32CubeIDEを使ってみよう How To STM32CubeIDE 日本語版 (9) I2Cを使ってみよう2 si7020編の続きです。
https://qiita.com/usashirou/items/f59b4b82d7d4086b8936

今回は、OLED　ssd1306を使用してみます。

新しいプロジェクトを立ち上げます。
最初は、前回と一緒です。

新規プロジェクトを立ち上げてI2Cの設定をします。
I2C1をI2Cにします。

![70-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/11d754ca-9e85-61d9-1abd-6a2693dd0c3c.jpeg)
PB8,PB9にI2CのSCLとSDAを割り当てます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/b315c563-db96-91b6-4888-369dcc931719.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/f4b54f18-1efe-9c72-bc8a-5ef54664ab1b.png)

それでは、CodeGenerateしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/9509958a-3087-86df-55f8-4e67081f2dfe.png)

次に、ssd1306のファイルを用意します。
https://github.com/4ilo/ssd1306-stm32HAL

必要なのは
- font.h
- font.c 
- ssd1306.h
- ssd1306.c
です。

GithubのページからClone or Downloadをクリックし
DownloadZipにてZIPファイルをダウンロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/54b65c8a-6766-e03c-7024-cac58dba109f.png)

解凍します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/6b3b6938-32b6-757f-0b9b-b464582a651c.png)

必要なファイルは以下に入れます。
Inc
- font.h
- ssd1306.h

Src
- font.c 
- ssd1306.c

ファイルをSTM32CubeIDE上でコピーします。
コピーするか、Linkするか聞いてきますのでコピーを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/5f07790f-00f4-f6f1-7efb-e80415b4a4bd.png)

次に、コードを追加します。
36行目

```
/* USER CODE BEGIN PD */
#include "ssd1306.h"
#include "fonts.h"
/* USER CODE END PD */
```
100行目

```
  /* USER CODE BEGIN 2 */
  ssd1306_Init();
  HAL_Delay(1000);
  ssd1306_Fill(White);
  ssd1306_UpdateScreen();

  HAL_Delay(1000);

  ssd1306_SetCursor(23,23);
  ssd1306_WriteString("4ilo",Font_11x18,Black);

  ssd1306_UpdateScreen();
  /* USER CODE END 2 */
```
Debugします。
OLEDに4iloと表示されると思います。
<img width="400" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/7cd065f8-a970-94a4-86e7-0b2fac35e040.jpeg">

###コード解説
ssd1306_UpdateScreen();
で表示内容をアップデートします。
ssd1306_Fill(White);
で消去します。
ssd1306_SetCursor(23,23);
は文字の開始点を指します。

109行目の
ssd1306_WriteString("4ilo",Font_11x18,Black);
"4ilo"を書き換えると、表示内容を変更できます。

以上でOLEDが使用可能になりました。
STM32CubeIDEを使ってみよう How To STM32CubeIDE 日本語版 (11) I2Cを使ってみよう4 Si7020+ssd1306編に続きます。
GitHubで誤って削除したリポジトリの復元方法

## 手順

1. ユーザー設定（https://github.com/settings/profile ）
1. 左メニューの `Repositories` をクリック
1. `Deleted repositories` タブをクリック
1. 削除したリポジトリ一覧が表示されるので、復元したいリポジトリの `Restore` ボタン押下

- 《注意》
  - 削除したリポジトリ一覧に表示されるまで、最大1時間くらいかかる場合があるそうです。
  - フォークがないか、フォークされていないリポジトリのみを復元できるそうです。
【SQL】テーブル情報の確認(SQLServer)

たまにしか使わないから忘れがちなやつ

#列情報の確認
列名をデータで取得したい時やデータ型とかを知りたい時に使う
列情報はシステムテーブルのsys.colmunsに格納されていて、
テーブル情報はシステムテーブルのsys.tablesに格納されている。
なので、こんな感じなら調べたいテーブルの列情報を取得できる

```SQL:GetColmunInfo
SELECT * FROM sys.colmuns
   WHERE object_id IN (
      SELECT object_id FROM sys.tables 
         WHERE name = 'first_grader`
   )
   ORDER BY colmun_id
```
AmazonLinux2タイムゾーン、ロケール設定

# 環境
- AmazonLinux2

# 手順
1. タイムゾーンを日本にする

    ```
sudo timedatectl set-timezone Asia/Tokyo
    ```

2. ロケールを日本語設定にする

    ```
sudo localectl set-locale LANG=ja_JP.utf8
source /etc/locale.conf
    ```
2019-10-05 LPC > LPCXpresso54628 > IDE > Project Explorerがある画面に移る > Open Perspective > C/C++ 

```txt:動作環境
OS: Ubuntu 18.04 LTS
基板: LPCXpresso54628
IDE: MCUXpresso IDE v11.0.1 [Build 2563] [2019-09-01]
```

### 概要

- プロジェクトを開始
- Project Explorerがない？
- 表示方法が分からない (Windowのメニューを探したが分からない)

### 対処

1. Open Perspectiveを選択
    - 下図の(1)をクリック
2. C/C++を選択
    - => Project Explorerがある画面になる

![Screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/b4c2a87e-69e7-a053-7f61-4c948c57b9d6.png)

![Screenshot from 2019-10-05 21-53-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/92af5e91-05d1-59d6-90a9-ed2171a0f73a.png)

### 備考

C/C++でないPerspectiveであったようだ。
Pin設定をしようとしていたので、PinのPerspectiveだったのだろう。

IDEの資料を読んでいる途中であるが、こういう概念の説明がなかなか登場しない。
QuickStartの資料があればいいのだが。
mod_ssl の SSLCipherSuite値指定

## 参考

* [Apache(mod_ssl)のSSLCipherSuiteの設定パラメータで有効な暗号化方式と強度を確認する - id:rx7(@namikawa)の技術メモ - 技術日記](https://tech.g.hatena.ne.jp/rx7/20130305/p1)

```apache:
SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5
```

```sh:確認方法
openssl ciphers -v 'HIGH:MEDIUM:!aNULL:!MD5'
```

```sh:version
openssl version
```


## 確認方法

```sh:対応しているもの全部見たい場合
openssl ciphers -v 'ALL'
```

```sh:SSLv3だけを見たい場合
# ! は否定を表す様子
openssl ciphers -v '!ALL:SSLv3'
```

```sh:TSL1.2に対応しているものだけを見たい場合
openssl ciphers -v '!ALL:TLSv1.2'
```

```sh:TSL1.0に対応しているものだけを見たい場合
openssl ciphers -v '!ALL:TLSv1.0'
openssl ciphers -v '!ALL:TLSv1'
```


## SSLProtocol

* [Apache httpd で接続を許すSSL/TLSのバージョンを制限する方法 | WEB ARCH LABO](https://weblabo.oscasierra.net/apache-httpd-sslprotocol/)

```diff:
  ... (略) ...
  SSLEngine on
+ SSLProtocol All -SSLv2 -SSLv3
  SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
  SSLCertificateFile /etc/httpd/conf/ssl/server.crt
  SSLCertificateKeyFile /etc/httpd/conf/ssl/server.key
 ...
```

もしくは以下のように列挙する。 
 
```apache
SSLProtocol -all +TLSv1.2 +TLSv1.0
```
【C#】IMEの入力を受けるユーザーコントロールの作成(補足) 



# はじめに
C#でIMEの入力を受けるユーザーコントロールの作成
https://qiita.com/takao_mofumofu/items/24c060a1d4f6b3df5c73

この記事の補足です。IMEウィンドウの表示位置に加えIMEウィンドウの表示領域の設定方法です。
元のソースに // 追加コード ってところを追加します。

# コード
```C#
// 追加コード
const uint CFS_RECT = 0x0001;

// 変更箇所
case WM_IME_STARTCOMPOSITION: {
    //入力コンテキストにアクセスするためのお約束
    IntPtr hImc = ImmGetContext(this.Handle);

    //コンポジションウィンドウの位置を設定
    COMPOSITIONFORM info = new COMPOSITIONFORM();
    info.dwStyle = CFS_POINT;
    info.ptCurrentPos.x = 10;
    info.ptCurrentPos.y = 10;
    ImmSetCompositionWindow(hImc, ref info);

    // 追加コード(IMEウィンドウ領域の設定)
    info.dwStyle = CFS_RECT;
    info.rcArea._Left = 10;
    info.rcArea._Top = 10;
    info.rcArea._Right = 100;
    info.rcArea._Bottom = 100;
    ImmSetCompositionWindow(hImc, ref info);

    //コンポジションウィンドウのフォントを設定
    //ImmSetCompositionFont(hImc, m_Focus->GetFont()->GetInfoLog());

    //入力コンテキストへのアクセスが終了したらロックを解除する
    ImmReleaseContext(Handle, hImc);

    base.WndProc(ref m);
    break;
```
# 実行結果

## 「CFS_RECT」指定無しの場合

指定した位置から表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494272/afc9f1aa-2005-a67b-f8eb-5fc475c96243.png)

## 「CFS_RECT」指定有りの場合

指定した位置と領域に表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494272/9ddcba4b-eee6-181d-2aa6-0c9b6357421e.png)
Nuxt.jsでのゲッターの使い方

# まずはストアを作ってgettersの中に定義（クラシックモード使用時）
- 練習なのでクラシックモードで。。。
- 今回は`item`（配列）を使う場面を想定

```javascript:index.js
import Vuex from 'vuex';

const store = {
  state: {
    items: [],
  },
  getters: {
    items: state => state.items,
  },

//この辺で実際にitemsの情報をapi通信で取得するイメージ

```

# 画面側で使うとき(値を取得してv-forでぶん回して表示する画面のイメージ)

- １.`<script>`の最初でmapGettersをインポートする
- ２. computedの中でmapGettersヘルパーを使って使いたいゲッターを宣言

- これでv-forの中で`items`が使えるようになる


```javascript:index.vue
<template>
  <section class="container">
    <div>
      <h3>Nuxt.js のタグが付けられた投稿の一覧</h3>
      <ul>
        <li v-for="item in items" :key="item.id">//1.
          <h4>
            <span>{{item.title}} </span>
            <small>
              <span>by </span>
              <nuxt-link :to="`/users/${item.user.id}`">
                {{item.user.id}}
              </nuxt-link>
            </small>
          </h4>
        </li>
      </ul>
    </div>
  </section>
</template>
<script>
import { mapGetters } from 'vuex';
export default {
  async asyncData({ store }) {
    if (store.getters['items'].length) {
      return;
    }
    await store.dispatch('fetchItems');
  },
  computed: {
    ...mapGetters(['items'])
  }
};
</script>

```

次はapi通信について書くぞー。
SwiftUIでForEachを使ったPickerの使い方

住所入力欄を作っているときに、都道府県をPickerで選択式にすることにしました。

しかし、完成までけっこうつまってしまったので備忘録として残しておきます。

##当初書いてみた間違ったやり方
```swift
@State private var selectedPrefecture = 0
```
```swift
Form {
    // Pickerを使う
    Picker(selection: $selectedPrefecture,
            // ラベル部分
            label: HStack {
            Text("都道府県")
            Spacer()
            Text(JapanesePrefecture(rawValue: selectedPrefecture)!.nameWithSuffix)
        }
    ) {
        // 選択部分
        ForEach(JapanesePrefecture.allCases, id: \.self) {
            Text($0.nameWithSuffix)
        }
    }
}
```
今回は都道府県の選択用Pickerなので、都道府県を定義した `JapanesePrefecture` を使っています。
選択した都道府県が分かるようにラベル部分にもTextを追加しています。

しかし、これでは期待通りの動作にはなりません。
いくらPickerで選択してもその選択が反映されないからです。

##期待通りの挙動になった書き方
Picker部分を以下のように書き換えたところ、期待通りの見た目・挙動になりました！

```swift
Picker(selection: $selectedPrefecture,
       label: Text("都道府県")
) {
    ForEach(0..<JapanesePrefecture.allCases.count, id: \.self) { index in
        Text(JapanesePrefecture(rawValue: index)!.nameWithSuffix).tag(index)
    }
}
```

ForEachを個数で繰り返すように書き、indexでtagを付与します。
選択した都道府県はTextを用意しなくても自動で表示されます。

###初期選択を空にしたい場合
このままでは、
`@State private var selectedPrefecture = 0`
と初期値を０に設定しているので「北海道」が選択された状態になっています。
初期選択を空にしたい場合は -1 など該当しない数値を指定することで空にすることができました。

##既知の問題点
都道府県の選択を行う画面では、「東京都」などのラベルをタッチして行いますが、デフォルトでは文字が左寄せになっており、セルの文字が書かれていない部分はタッチして選択することができません。
セルならどこでも選択可能にしたいのですが、ちょっと分からなかったので現段階ではそのままにしてあります。

もしご存知の方がいらっしゃいましたら教えて頂けると嬉しいです。

##参考
都道府県のenumを作成するときはこちらを参考にさせていただきました。
https://qiita.com/EnVacance/items/95dd6b77e962d4723a76
Gradle + Kotlin-DSLでjarを生成

[2021/12/11 追記]

最近だと[Gradle Shadow](https://github.com/johnrengelman/shadow)を使ってjarを生成するのが楽そう．

```build.gradle.kts
plugins {
  id("com.github.johnrengelman.shadow") version "6.0.0" // 使っているGradleのバージョンを指定する
}

...

dependencies {
  // implementation で指定しても大丈夫
  implementation(platform("org.jetbrains.kotlin:kotlin-bom"))

  ...
}

application {
  // Define the main class for the application.
  mainClassName = "package.MainKt"
}

val jar by tasks.getting(Jar::class) {
  manifest {
     attributes["Main-Class"] = "package.MainKt"
  }
}
```

あとは

```bash
./gradlew shadowJar
```

を実行するだけ

追記終わり．以下本文
___

Kotlin-DSLでGradleを使っているのだが，実行可能jarを生成する方法が意外と見つからなかったので備忘録的に書き留めておく．

```build.gradle.kts
plugins {
    application
}

dependencies {
    // 依存ライブラリをjarに固めるためには'compile'で記述する必要がある

    // Use the Kotlin JDK 8 standard library.
    compile("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

    // Use the Kotlin test library.
    testCompile("org.jetbrains.kotlin:kotlin-test")

    // Use the Kotlin JUnit integration.
    testCompile("org.jetbrains.kotlin:kotlin-test-junit")
}

application {
    // Define the main class for the application
    mainClassName = "com.example.MainKt"
}

// 'gradle jar'を使えるようにタスクを定義
val jar by tasks.getting(Jar::class) {
    manifest {
        attributes["Main-Class"] = "com.example.MainKt"
    }

    from(
            configurations.compile.get().map {
                if (it.isDirectory) it else zipTree(it)
            }
    )
    exclude("META-INF/*.RSA", "META-INF/*.SF", "META-INF/*.DSA")
}

```

groovyの記事はいっぱい見つかるんだけどね...

[11/4追記]
この記事の目的とは逸れるが，`./gradlew run`実行時に実行時引数を与える方法も一応書いておく

```build.gradle.kts
import kotlin.text.Regex

val run by tasks.getting(JavaExec::class) {
    if (project.hasProperty("args")) {
        args = (project.property("args") as String).split(Regex("\\s+))
    }
}
```

実行時は

```shell
./gradlew run -Pargs="hoge fuga piyo ..."
```

引数に補完が効かないことに注意
UE4でtrueSKYを使う（導入編）

# 環境
OS:Windows10
UnrealEngineのバージョン:4.22.3（ランチャーからインストールしたバイナリディストリビューション）

# trueSKYってなに？
Simul Software Ltd.が提供している天候のリアルタイムレンダラーです。
エースコンバット7などで使われました。

# 提供形態
スタンドアロンのSDKはもちろん、UnrealEngine4のプラグインやUnityのプラグインも提供されています。

# ライセンス形態
|                                        |Indie Licence|trueSKY Pro Licence|
|:---------------------------------------|:------------|:------------------|
|UE4やUnity Plugin                      |:o:           |:o:                |
|すべてのtrueSKYツールセット              |:o:           |:o:                |
|100,000ポンド以下のアプリケーション       |:o:          |:o:                 |
|trueSKYのすべてのソースコードへのアクセス |:x:           |:o:                |
|料金                                   |1または2のどちらか選択<br>1. 一括で100ポンド<br>2. 毎月15ポンドで10ヶ月（計150ポンド）|要相談|
この他にも30日間のフリーライセンスもあります。

# インストールまで
ライセンスを選択しましょう。この記事では、Indie Licenceを選択したこととして進めます。
ライセンスのBuy Nowボタンを押して、Simulのアカウントを作成します。
諸々完了したら、マイページに移動してライセンス情報を確認しましょう。
![simul.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30831/fec8a44d-9ba3-a236-57a5-27575a97c35d.png)

ライセンス情報の画面の左にある列からEnginesを選択してUnreal Engine >> UE4 Downloadsをクリックします。
今回使用するUE4はバイナリディストリビューションなので、Plugin Installer for Binary Distributionをクリックして、自身のUE4のバージョンとあっているものをダウンロードします。[^1]
ダウンロードしたインストーラを実行しましょう。
[^1]: この記事ではUE4のバージョンは4.22.3を使用していますが、4.22.2のプラグインでも動作するはず（テストしてないけど）とSimulの方から伺っています。

# 使用準備
UE4でブランクテンプレートの新規プロジェクトを作りましょう。
UE4が起動して最初のレベルが表示されたら、メニューバーからウィンドウ >> Initialize trueSKY...をクリックしてtrueSKYを使用する準備をします。
![Window1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30831/0aab5ddf-d201-301e-1fac-c28c530603f6.png)

このとき、すでに配置してあるAtmosphere FogとBP_Sky_Sphereを削除してtrueSKY Sequence ActorとtrueSKYLightを追加する旨のダイアログが出ますので、Initializeをクリックしましょう。

# レジストレーション
アウトライナからTrueSkySequenceActorを選択して、詳細タブにてTrue Sky >> Active Sequenceをダブルクリックします。
出てきたダイアログの上部にレジストレーションの欄があるので必要な情報を入力しましょう。
![lisence.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30831/5eb99b53-aa7e-0742-ed65-a3de32cc467d.png)

お疲れさまでした。以上でUE4へのtrueSKYの導入が完了しました。
![result.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30831/f1c4488a-1fbf-98c9-3cb4-135205e16309.png)
VirtualMotionCaptureのビルド手順

#はじめに
VirtualMotionCaptureをたまにビルドしていじるんですが、手順を忘れるのでメモします。
(2019/10/05時点)

#元
以下のページの手順が問題なく理解できる場合はこのメモを読む必要はありません
https://github.com/sh-akira/VirtualMotionCapture/tree/v0.22basefix

#手順
**1.Unity 2018.1.6f1、Visual Studio 2017を準備します。(2019.1.6fではありません)**
ダウンロードはここから
https://unity3d.com/get-unity/download/archive

Visual Studio 2017(Community)も準備します。
すでに古いバージョンとなっているので、Visual Studio Dev Essentialsからダウンロードが必要です。
https://visualstudio.microsoft.com/ja/dev-essentials/

**2.リポジトリをクローンします**
https://github.com/sh-akira/VirtualMotionCapture/tree/v0.22basefix

Gitの扱いに慣れてない私のような人向け: チェックアウトするブランチはv0.22basefixです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191114/97a7fca6-f53d-ae6d-496a-18c64dc3d757.png)

**チェックアウトするブランチ**と**サブモジュールに再帰**

**2.追加: ColorPickerWPFフォルダが空の場合ColorPickerWPFをダウンロードします**
**サブモジュールに再帰**を入れ忘れた場合。
zipでダウンロードして突っ込む。
無いと、VirtualMotionCaptureControlPanelのビルドに失敗します。
https://github.com/sh-akira/ColorPickerWPF/tree/c6cd9113069cb805a7d37cd43cbc4341d5a834fb

**3.ProjectSettingsフォルダを別の場所にコピーします。**
アセット導入の過程で変更されるためです。

**4.Unity 2018.1.6f1でプロジェクトを開きます**

**4.以下のアセットを導入します。**
Final IK 1.8(アセットストア、有料)

~~SteamVR 1.2.3~~
~~https://github.com/ValveSoftware/steamvr_unity_plugin/releases/tag/1.2.3~~
→現在1.2.3を入れるとラッパーと衝突して起動しません

~~SteamVR Unity Plugin v2.3.2 (sdk 1.4.18)(配布停止)~~
SteamVR Unity Plugin v2.2.0(再生のたびに警告が出ますが動きます)
https://github.com/ValveSoftware/steamvr_unity_plugin/releases/tag/2.2.0
**SteamVR Unity Plugin v2.4.5 (sdk 1.7.15)**ではありません！
ファイル処理が変わっていてエラーが出ます。

UniVRM-0.53.0_6b07.unitypackage
https://github.com/vrm-c/UniVRM/releases

Oculus Lipsync Unity 1.30.0
https://developer.oculus.com/downloads/package/oculus-lipsync-unity/1.30.0/

uOSC v0.0.2
https://github.com/hecomi/uOSC/releases/tag/v0.0.2

MidiJack #71a66c7
https://github.com/keijiro/MidiJack

**5.ExternalPluginsフォルダにアセットを移動します。**
エラーは気にせず。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191114/f6491994-cfd6-1050-ce2a-268b55cd11c8.png)

**5.追加: Assets\Scripts\EyeTrackingフォルダを削除します**
現時点でアイトラッキング環境なんて持ってる人そんなにいないと思うので。
残ってると、今のアセット構成では動作しません。

**6.Unityを終了します**

**7.ProjectSettingsフォルダをコピーしておいたもので上書きします。**

**8.ControlWindowWPF/ControlWindowWPF.slnをVisual Studio 2017で開きます**

**9.VirtualMotionCaptureControlPanelプロジェクトのプロパティを開きデバッグのコマンドライン引数を/pipeName VMCTestにする。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191114/e2eb639f-144a-0366-284f-a8d511d1a189.png)

**10.実行します**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191114/634303f1-2dee-9640-df7c-543a896be11c.png)

起動を確認したら終了します。(Unityとの連携に必要なファイルが生成されます)

**11.Unityを起動します**

**12.起動します**
ScenesフォルダのVirtualMotionCaptureシーンを開き、Unityを再生
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191114/47ab0ef4-a817-6cd4-fbec-e61d11bb7b5a.png)

VisualStudioでVirtualMotionCaptureControlPanelを実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191114/634303f1-2dee-9640-df7c-543a896be11c.png)

注意: boothで配布されているものと比較し、設定ファイルがなかったり、初期値になっていたりするので、
それが困る場合は配布版から設定を持ってきましょう
[Rails]基本的なレスポンシブデザインについて

#はじめに
今回作成している個人アプリで、スマホでも操作しやすいようにしたかった為レスポンシブデザインに挑戦してみました。
####環境
Rails 5.2.3
Ruby 2.5.1
Bootstrap3使用

##レスポンシブデザインとは
レスポンシブデザインとは、PCやスマホ時など画面にあったデザインが最適に表示されている事です。
CSSで調整をする事で一つのHTMLファイルでもそれぞれの画面にあったデザインに調整する事が出来ます。

##導入方法
先ずapplicationファイルに以下の記述を追加します。今回は`Haml`を使用しています。
この記述を追加する事でスマホでもボタンなどのレイアウトが、ある程度は調整された状態で表示されると思います。

```ruby:application.html.haml
省略
    %meta{content: "width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0", name: "viewport"}
省略
```

##`@media`について
後はビューの微調整に`@media`を使用します。私の場合はPCでのサイズでビューを調整していますが、スマホ版とPC版用両方使用しています。理由はこのようにしないと`margin`などのプロパティが**スマホ版で適用されなかった為**です。

今回はログインフォームで使用してる`Bootstrap`のボタンを例に説明します。先ず最初にスマホ版の`SCSS`を検証ツールなどを使用して調整していきます。`@media (max-width: 480px)`はスマホサイズで指定する際に使用します。
通常の記述方法は`@media screen and (max-width: 480px)`になりますが、`application.html.haml`に先程記述したコードのお陰で省略出来るようになっています。

`max-width`や`min-width`の指定、`px`の指定などは状況に合わせて調整して下さい。
スマホ対応、PC対応にそれぞれ指定する事で、同じプロパティでも対応した画面で適用させる事が可能になります。

**調整についての参考資料**
https://creive.me/archives/18736/

####スマホ対応

```scss:media.scss
@media (max-width: 480px){
  .content .btn {
    font-size: 1.2rem;
  }
```

```scss:login.scss
.content {
  background-color: rgba(128, 128, 128, 0.281);　←入力フォーム部分の背景に使用
 }
```

####検証ツール使用時の画像(スマホ画面時)
スマホ画面時に**font-size: 1.2rem**が適用されています。
<img width="1002" alt="スクリーンショット 2019-10-05 20.04.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435517/9d8be402-bf42-8763-0992-b0f18f60a79c.png">


####PC対応
次にPCサイズの調整をします。PCサイズの記述は`@media (min-width: 1080px)`になります。`px`に関しては修正が必要になるかもしれませんので上手くいかなかったら調整して下さい。


```scss:media.scss
@media (min-width: 1080px) {
  .content .btn {
    font-size: 2rem;
  }
```
```scss:login.scss
.content {
  background-color: rgba(128, 128, 128, 0.281);　←入力フォーム部分の背景に使用
 }
```

####検証ツール使用時の画像(PC画面時)
少し見にくいですが、PC画面時には**font-size: 2rem**が適用されています。
<img width="1440" alt="スクリーンショット 2019-10-05 20.03.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435517/6e6586b9-186c-f0fe-1c14-c142a7f78a51.png">



#まとめ
Railsでレスポンシブデザインをするには、`html`に一文記述する、`@media`で調整する事だけ覚えておけば大丈夫かと思います。おそらく上手くいかない部分も出る可能性があるので、後は状況に応じて調整して下さい。

**参考資料**
https://wemo.tech/839#index_id21
husky バージョン3 で git hooks が動かない

`husky`を使った`hooks/pre-commit`の追加がうまくできず詰まりました。

## 原因
`husky`の`CHANGELOG.md`に以下をみつけました。


> Breaking change husky requires now Git >= 2.13.2. If you're already using husky v2 and don't use an old version of Git, you can safely upgrade.

(Breaking changeならreadmeのわかりやすいところに書いといてよ。)

`yarn remove husky`したら上記のメッセージでました。`yarn add`で出してほしいのと、前回`remove`したときはでなかったような。見落としてたかも。

## 解決策

1. `git` のバージョンを`2.13.2`まで上げる。
2. `husky` のバージョンを`2.7`まで下げる。
【Google Apps Script】改良版：チェックボックスでスプレッドシートの特定行の表示／非表示を切り替える

# はじめに

スプレッドシートにチェックボックスを配置し、そのアクティブ状態によって指定行を表示／非表示の切り替えをしたいと要望がありました。
先日[ほぼ同じ記事](https://qiita.com/rf_p/items/8746ed7adba1561cb245)を投稿しましたが、汎用性ある仕様に少し変えたので再投稿。


# 完成図

![movie.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199678/4b16ed76-a57a-1456-75a2-4513c9502103.gif)

# 下準備

スプレッドシートを新規作成。

1.  A1〜A3に「野菜」「肉」「魚」と入力。
2.  B1〜B3にチェックボックスを配置。チェックボックスは挿入→チェックボックスで配置できます。
3.  A6〜A30にカテゴリ、B6〜B30に食材名を入れます。数が多くて面倒なら、各カテゴリ2〜3個でOKです。

<img width="259" alt="excel.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199678/9f95dac4-e3b3-0485-b8d8-0984c29859cc.png">

ツール→スクリプトエディタを選択し、以下コードを貼り付けます。

# コード全文

```javascript
var CHECKBOX_COLUMN = 2; // チェックボックスの列
var CHECKBOX_COUNT = 3; // チェックボックスの数
var HIDDEN_FIELD_START = 6; // 何行目から消すのか
var HIDDEN_FIELD_END = 30; // 何行目まで消すのか

// スプレッドシートの値が変更された時に発火
function changeEvent() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var activeCell = sheet.getActiveCell();
  if (activeCell.getColumn() == CHECKBOX_COLUMN && activeCell.getRow() <= CHECKBOX_COUNT){ // チェックボックス範囲の値が変更された場合
    checkBoxEvent(sheet);
  }
}

// チェックボックスのチェック状態に合わせて表示・非表示を切り替える
function checkBoxEvent(sheet) {
  var rows = sheet.getRange(1, CHECKBOX_COLUMN, CHECKBOX_COUNT, 1).getValues();
  hiddenFields(sheet);
  var dataRows = sheet.getRange(HIDDEN_FIELD_START, 1, HIDDEN_FIELD_END - HIDDEN_FIELD_START + 1, 1).getValues();
  for (var i = 0; i < rows.length; i++) {
    if (rows[i][0] === true) { // チェックが付いている場合、
      var showRow = sheet.getRange(i + 1, CHECKBOX_COLUMN - 1).getValue();
      for (var j = 0; j < dataRows.length; j++) {
        var targetRow = j + HIDDEN_FIELD_START;
        if (dataRows[j] == showRow) {
          sheet.showRows(targetRow); // チェックボックスの1個左のセルの値と一致する行数を表示する
        }
      }
    }
  }
}

// 非表示行エリアを全非表示にする
function hiddenFields(sheet) {
  sheet.hideRows(HIDDEN_FIELD_START, HIDDEN_FIELD_END - HIDDEN_FIELD_START + 1);
}
```

# 動作確認

スプレッドシートのカーソルをB列のどこかに置きます。

```
  if (activeCell.getColumn() == CHECKBOX_COLUMN && activeCell.getRow() <= CHECKBOX_COUNT){ // チェックボックス範囲の値が変更された場合
```

ソースコードで見るとこの部分、B1〜B3の値変更イベントにのみ発火するように設定しているためです。

スクリプトエディタで実行→関数の実行→changeEventを選択。
実行許可のウィンドウが出るので、[過去記事のスクショ](https://qiita.com/rf_p/items/0535ec495df8f9d2b894#1msgbox%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9Fhello-world)を参考にしてください。

スプレッドシートの１０〜３０行目が非表示になり、チェックONになっている左隣のカテゴリのみ表示されれば成功です。

# トリガーの設定

チェックボックス変更した場合、自動的に行の表示／非表示されるように、スプレッドシートの変更イベントをトリガーとしてchangeEvent関数が自動実行されるよう設定します。

スクリプトエディタ「編集→現在のプロジェクトのトリガー」もしくは時計アイコンからトリガー設定画面に飛びます。
右下の「トリガーを追加」から、下記の通り設定します。

<img width="831" alt="s2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199678/f9c4e1f8-7cff-437e-ce7a-9cdad49cc8b9.png">

![movie.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199678/4b16ed76-a57a-1456-75a2-4513c9502103.gif)

# 追記(2019/10/21)

```javascript
function changeEvent() {
```

を、

```javascript
function onEdit() {
```

にするだけで、トリガーを設定しなくとも勝手に動きます。
需要性がないelectron開発備忘録

#はじめに
electronを触るにはすごく初歩的なことから、調べても中々わからなかったりしたすごくマニアックなことをまとめる。
私は二度とこのことについて悩む必要がないので、何日も進捗が0の日がなくなるのでうれしい。
#ファイルのパス
electronをパッケージングしたらファイルの場所が変わるらしい。(何でなんだろ)
なので相対アドレスだと読み込めない...うーん困った。

そこで現れるは```__dirname```
よく考えればelectronはnode.js使えるのね。
これを指定したファイルの前に使えばきちんと読み込んでくれる。うれしい。

以下参考URL
[node.js で絶対パスや相対パスを取得する方法](https://gist.github.com/uupaa/da42698d6b2d2cbb3cca)
#メニュー
メニューはメニューでもTrayのメニュー。通知っていうとバッジの方と混合するんだけどなんて説明が正しいんだろ?サイトによってごちゃごちゃ。
これの何に困ったかってアイコン。大きくわけて二通りのサイトがあった。nativeImageというメソッドを使うか否かというところ。個人的にはファイル移動とかしてパスが変わった時に画像が空だと故意にエラーを吐かせることができるので、デバッグに便利だと思った。**まあ強いエンジニアはそんなことしないんだろうけどな!!(大声)**
でも全体的にどのサイトも曖昧だったので公式リファレンス読んだ。
あとはメニューを触れなくする方法、クリックイベント等も調べた。すっごい簡単なことだった...

以下参考URL
[Tray:Electron](https://electronjs.org/docs/api/tray)
[nativeImage:Electron](https://electronjs.org/docs/api/native-image)
[menu-item:Electron](https://electronjs.org/docs/api/menu-item)
#node_modulesを使う
twitterJSを使いたく思い、一緒に入れてパッケージングしたら消滅したので苦しんだ。
jsファイルを素で置くこともできずに困った。
その時アーカイブ化というものを知った。
標準搭載しとけよ。

その名はasar。配布する時用と書いており、ますます何故標準搭載ではないのかわからない。
まあそれなりの事情があるんでしょう。

以下参考URL
[Electronで作ったアプリを実行ファイル(exeファイル)にする方法](http://pineplanter.moo.jp/non-it-salaryman/2016/02/08/electron-exe-extend/)
#Frameless Window
普通の人はこんなことしませんもんね。わかるよ(圧倒的同意)
色々触れなくなるのでcssでなんとかする。
今回はwindows用を作ってたけどmacやlinuxに対応するには少し書き換えが必要だったりする。

以下参考URL
[Frameless Window](https://imfly.gitbooks.io/electron-docs-gitbook/jp/api/frameless-window.html)
#ipc通信
嫌だ!!めんどくさいことしたくない!!
以下のサイト見て人生の革命が起きた。

以下参考URL
[ElectronのIPCをまとめる](https://qiita.com/maecho/items/cb6eb18be2f4ffae60b5)
#最後に
electron面白いから触ってみよう!!
あとマニアックなところの記事誰か書いて!!古いのしかなくてすごい困ってる!!
serverless framework + typeorm + data-apiでaurora-serverlessへアクセスする。


v0.2.19 - 2019/09/14で対応された

```
yarn add typeorm
yarn add typeorm-aurora-data-api-driver

```

https://github.com/ArsenyYankovsky/typeorm-aurora-data-api-driver

```js
 const connection = await createConnection({
      type: 'aurora-data-api',
      database: 'test-db',
      secretArn: 'arn:aws:secretsmanager:eu-west-1:xxxxxxxxxxxxxx:secret:xxxxxx/xxxxxx/xxxxxx',
      resourceArn: 'arn:aws:rds:eu-west-1:xxxxx:xxxxxx:xxxxxx',
      region: 'eu-west-1',
    })
```

# webpack / serverless-frameworkから使う
v0.2.19の時点だと、webpackだと動かない。
MODULE_NOT_FOUNDが出るので、typeormをちょっと修正する。

https://github.com/typeorm/typeorm/issues/4788

```typeorm/platform/PlatformTools.js
  PlatformTools.load = function(name) {
    // if name is not absolute or relative, then try to load package from the node_modules of the directory we are currently in
    // this is useful when we are using typeorm package globally installed and it accesses drivers
    // that are not installed globally
    try {
      // switch case to explicit require statements for webpack compatibility.
      switch (name) {
        /**
         * mongodb
         */
        case "mongodb":
          return require("mongodb");
          
        ........
        
        
        // type ormへのアクセスを追加　!!!!!!!!!!!!!!!!
        case "typeorm-aurora-data-api-driver":
          return require("typeorm-aurora-data-api-driver");
        /**
         * default
         */
        default:
          return require(name);
```

```src/driver/aurora-data-api/AuroraDataApiDriver.ts

# this.DataApiDriver = PlatformTools.load("typeorm-aurora-data-api-driver");
const driver = PlatformTools.load("typeorm-aurora-data-api-driver");
this.DataApiDriver = driver.default || driver;
```


## 文字コード
クライアント側で指定できないので、RDSのパラメータグループで正しく指定してあげる
character_set_client / character_set_connection / character_set_database / character_set_results / character_set_server

skip-character-set-client-handshake も1にセットしたけど、不要そうな気もする。

これで接続成功しますた。(ﾟдﾟ)
次のバージョンで対応されそうな気がするので、ちゃんと待った方が良さげ。

# 課題点とか

## data-apiで
- datetimeに0が入るとだめっぽい。
iOS13でのモーダル表示

iOS13にすると、iOS12までの全画面モーダル表示ではなく元の画面の上に重なるようなUIに変更されました😙
![Modal0.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508617/366f0ecf-88cf-85dd-a0d0-b21a6a8c8a92.gif)


アプリ開発をしてこのモーダル表示をどうにか出来ないかと思い自分の備忘録も兼ねて投稿😎

# 方法
viewという変数にはモーダルで表示したいViewが入っているものとします。
今回３パターン(実質2パターン)用意してみました!

## (1)これまでのモーダル表示にする(フル画面)
画面を表示させる前(present)にこのコードを書けばこれまでのモーダル表示になります🥳

``` modal1.swift
 view.modalPresentationStyle = .fullScreen
```
![Modal1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508617/f9bb9b5a-c9ac-7e08-97f2-9412a99fd237.gif)

## (2)iOS13からのモーダル表示かつ上から引っ張っても元の画面に戻らないようにする 
(1)同様に画面を表示させる前にこのコードを書けば幸せになります🥰<br>
開発しているアプリがiOS13以上ならこの方法もありだと思います😉

``` modal2.swift
view.isModalInPresentation = true
```
![Modal2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508617/0c14ff3c-b365-67eb-d216-aa7f327f33cb.gif)

## (3)1と2を組み合わせた方法
例えば開発しているアプリがiOS12からだけど、ユーザーがiOS13にした時には(2)の機能を使いたい！って時にオススメです🤩<br>
if文の \#available()って何！？って思った方はこちらの記事が良く分かると思います！
[iOSのバージョン判定をする方法](https://qiita.com/takashings/items/8e167767fad1e4df3fea)

``` modal3.swift

if #available(iOS 13.0, *) {
    // iOS13以上の場合
    view.isModalInPresentation = true
} else {
    // iOS12以前の場合
    view.modalPresentationStyle = .fullScreen
}

```

# 最後に
初めてQiitaに投稿してみました！<br>自分自身Qiitaの多くの記事に助けられながらアプリ開発を行っています。そんなQiitaに自分も記事を投稿して少しでも誰かの悩みの種を無くしていければな！と思っています。未熟者ですがよろしくお願いします。

今回の記事の内容で違っていたりこう治した方が良いなどコメントで下さい！
apple push notification 不正デバイストークンの存在と対策

![pushnotification_pic.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/e331a51f-86ca-b18d-789f-9e928a9c6719.jpeg)
iPhoneアプリ開発にてAPNS(Apple Push Notification Service)を利用したアプリ及び管理サイトサーバの運用で陥った問題の解決策を考察してみる。
前提としてswif側でのDeviceToken取得は問題ないとすると、その取得したDevice tokenを管理サーバにて保存管理するシステムのトラブル対策が必要であるようです。
今回の私達が使用したシステムの概要は上記の様な物です。
現在テスト開発のアプリでAndroidとiOS対応を行なっており、push serviceの機能を付加し開発側からのメッセージやアプリ間でのメッセージ配信によるダイレクトメッセージ網を確立すべく開発しています。
その際の発生するiOSおけるAPNS開発中とリリース版とのデバイストークンで不正デバイストークンによる配信ダウンが起きる問題の解決に際しサイトでの検索結果等で不正なトークンへの配信を絶対にしないと言う方法が求められる様ですが、配信がダウンした際の不正トークンの検出がやはり必要である様思われます。
下記へサーバサイドで一斉もしくは指定したデバイスへの配信をすべくphp pythonにて開発中のコーディングを紹介させて頂き参照された諸氏のご意見をいただければと投稿して行きます。
＃ -*- coding:utf-8 -*-
＃ MySQLdbのインポート
import MySQLdb
＃ device token登録されたDBへ接続
connection = MySQLdb.connect(
host='localhost',
user='root',
passwd='********',
db='******_db',charset='utf8')
cursor = connection.cursor()
import time
from time import sleep
from apns import APNs, Frame, Payload
apns = APNs(use_sandbox=True, cert_file='pushCerDev_TestProject.pem', key_file='pushKey_TestProject.pem')
＃for release
＃apns = APNs(use_sandbox=False, cert_file='pushCer_TestProject.pem', key_file='pushKey_TestProject.pem')
content = "おはようございます！"
content = content.decode('utf-8')
payload = Payload(alert=content, sound="default", badge=1)
＃cursor.execute("SET NAMES UTF8")
＃SQLにてデバイストークンを指定
cursor.execute("SELECT * FROM dvtoken_mst where dvtoken_keyid>1 order by dvtoken_keyid")
result = cursor.fetchall()
for row in result:
    ＃print(row[1])
    token_hex = row[1]
    ＃print(token_hex)
    apns.gateway_server.send_notification(token_hex , payload)

＃ 保存を実行
connection.commit()
cursor.close()
＃ 接続を閉じる
connection.close()
Android StudioOverflow menuを作る 

#menu layoutを作る
まずはres folder->new->Directoryでmenu folderを作る
そしてmenu folder->new->Menu resource file（xml）を作る

#menu layoutを書く
menu layoutのxmlに下記のように（四つの）itemを作る

```html:menu_overflow.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:id="@+id/user" android:title="user"/>
    <item android:id="@+id/login" android:title="login"/>
    <item android:id="@+id/setting" android:title="setting"/>
    <item android:id="@+id/logout" android:title="logout"/>

</menu>
```

#onCreateOptionMenu()でMenuをActivityに産出する
使用者がmenuをタブしたり、Activity.openOptionsMenu()をコールされたりするとonCreateOptionMenu(Menu menu)が呼び出されるらしいです。
AndroidからmenuのLayout情報をmenuとしてパスし、それをparentにして、item情報の入ったxmlをinflateし、もう一度menuを突っ込んだonCreateOptionMenu()をリターンすればいいようです。
*getLayoutInflator(x)getMenuInflator(O)

```java:MainActivity.java

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_overflow,menu);
        return super.onCreateOptionsMenu(menu);
    }
```
ここまですると、すでにmenuができてるはずです。ただし、itemをタブしても反応はしません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505344/6f256e75-e7d0-0d0d-fb00-693bd8174a45.png)


#onOptionsItemSelected()
このmethodで各itemの反応を簡単に設定します。MenuItemのitemで使用者がタブしたitemのIdをgetItemId()で取得し、R.id.itemIdと照らし合わせ、反応を設定します。

```java:MainActvity.java
@Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId())
        {
            case R.id.user:
                Toast.makeText(this,"user_activity",Toast.LENGTH_SHORT).show();
                return true;

            case R.id.login:
                Toast.makeText(this,"user_login",Toast.LENGTH_SHORT).show();
                return true;

            case R.id.setting:
                Toast.makeText(this,"user_setting",Toast.LENGTH_SHORT).show();
                return true;

            case R.id.logout:
                Toast.makeText(this,"user_logout",Toast.LENGTH_SHORT).show();
                return true;

            //defalt will return false if none of the case is meet
            default:
                return super.onOptionsItemSelected(item);

        }

    }
```
以上は現時点の覚書です。
Microbit:DC motor制御その3（無線送受信プログラムの変更）


これまでDFRobotのDFR0548（4chDCモータドライバー）を使ったロボットの無線制御について紹介しました。
 [Microbit:DC motor制御（DFROBOTボード）](https://qiita.com/Gyutan/items/08182be2eea552bbed64)
[Microbit:DC motor制御（DFROBOT DFR0548ボード）その2](https://qiita.com/Gyutan/items/28d1552b87a7bb7dfc8f) 

送信側のコントロールプログラムの変更に伴い、受信側のプログラムも変更しました。
また今回、受信側はオリジナルの基板のものを用いています。（制御用の関数の中身も変わっています。）

送信側の変更点は、
これまで送信側のマイクロビットを傾けると一回だけ送信命令が送られていました。
例えば、ロゴが上になったのイベントが発生すると、一回無線で送信が送られます。
傾けた状態で連続で無線で送信が送られるように変更しました。

### 送信側
![KRCboard_control_v6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165987/eeea72bd-d771-5f44-2c36-d0d913aeb718.png)

#### 送信側コード解説
`最初だけ`のブロック中に`無線グループの設定`を行います。
`ずっと`ブロックでは、マイクロビットの傾きをモニターしていて、その値を右左（X軸）、上下（Y軸）を変数に入れています。その際、-1023から1023を-40から40の値にリスケールしています。
`無線で送信`するときには”名前”と”値”のペアーにして送信します。
上下は、前後に動かす命令なので”go"とし、左右は、左右に曲がるので"turn"、ボタンは、腕を動かすので"arm"という名前にしています。
上下・左右は、入力内にあるブロックを用いてイベントを検知し、その中に`もし・・なら`のWhileループを入れて、傾きの値で判断して、`無線で送る`を使って名前と値を送りつづけます。
ボタンイベントは、これまで通りの1回の無線を送信します。
右側にある`無線で受信した時`は、送信側のマイクロビットの動作テストもかねてのコードです。（受信側では、このコードに命令に対応した関数を入れることになります。）
`もし・・なら`の条件分岐を行います。まず、送信されてきたものの”名前”が異なるので、”名前”で条件分岐します。その後さらに、値で条件分岐をします。


### 受信側
![KRCboard_MDF.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165987/0410ee44-bdad-9111-6d4a-d0d079c938e3.png)

#### 受信側コード解説

`最初だけ`のブロック中に`無線グループの設定`を行います。
動作に対応した関数を作成します。例えば、前進ならば、右モーター、左モーターの回転方向と回転のパワーなどをそれぞれのロボットに合わせて、それぞれのIOポートに出力していきます。
前進、行進、右回り、左回り、停止などの関数を作っていきます。
送信側で作成した`無線で受信した時`と同じものを作成します。その中にそれぞれの命令に対して、動作する関数を配置していきます。

右側にあるボタンイベントは、動作確認用のものです。無線が通信の問題か、それとも動作する関数の問題かを切り分けるためのものです。ご自身のロボットに対応したテストを記述してください。

※なお、今回は、これまで使っていたDFROBOTの基板ではなく、我々の仲間が製作したオリジナルの基板を用いているので、関数の中身が異なっています。（[久喜ロボットクラブ](https://kuki-robot-club.localinfo.jp/)）
オリジナルの基板の特徴は、マイクロビットを取り付ける方向が、DC基板に対して水平にさせること、モータへの出力電圧を可変抵抗で制限できることです。DFROBOTの基板は、入力電圧を制限かけずに出力しているので、モータの定格よりも高い電圧がかかる可能性があります。連続でかけ続けるとモータが焼けてしまいます。制限をかけるには前回の記事（[Microbit:DC motor制御（DFROBOT DFR0548ボード）その2](https://qiita.com/Gyutan/items/28d1552b87a7bb7dfc8f) にあるように、Speedを落として使うことが必要になります。

今回作成したコードは
https://github.com/SGyutan/krc_microbit
に上げています。

### 完成して搭載したロボット
![P_20191005_161544-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165987/2350a568-1ef2-0b91-1862-3a33b5868141.jpeg)
![P_20191005_161606-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165987/63795a5c-6ef8-4e88-6ba8-027099a40996.jpeg)
Rails 6 のAPI を叩いたら "Blocked host: host.docker.internal" と怒られた

## 構成
- Docker
- Rails 6 (APIモード)
- Nuxt.js

## エラーになった
Nuxt 側から Axios でRails のAPIを呼び出すぞ！
と今までと同じように以下の設定をしたけど

```/.env
API_BASE_URL=http://host.docker.internal:8000
```

```nuxt.config.js
  axios: {
    baseURL: process.env.API_BASE_URL
  },
```

こんなエラーが出てしまった🤔

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135266/105718f1-7e7a-f941-7444-cbee6d7f02ce.png)

```
Blocked host: host.docker.internal

To allow requests to host.docker.internal, add the following to your environment configuration:

config.hosts << "host.docker.internal"
```


## 解決法

色合い的に Railsのエラーっぽいなーと調べると、
Rails 6 で新たに追加された `ActionDispatch::HostAuthorization` というミドルウェアで、
許可していないホスト名宛のアクセスは拒否されるようになったみたい。
（ `0.0.0.0` や `localhost` はデフォルトで許可されている）

**Guard against DNS rebinding attacks by permitting hosts**
https://github.com/rails/rails/pull/33145


エラーメッセージの通り、 config に `config.hosts` を追記して解決！

```config/environments/development.rb
Rails.application.configure do
...
    config.hosts << "host.docker.internal"
end
```