OmniAICreator/Qiita-1.07M huggingface dataset:
【Flutter for web】firebaseパッケージのstorage().ref()がエラーとなる問題の解決法

Flutter for webでFirebase storageを使う際に[firebase_storage](https://pub.dev/packages/firebase_storage)がweb未対応だったため、[firebase](https://pub.dev/packages/firebase)を用いて実装したら、`storage().ref()`が上手くいかなかったので対応しました。

## 結論

ルートパスを参照する場合でも明示的に`'/'`を渡すことで解決します。  
🙅‍♂️：`storage().ref()`
🙆‍♂️：`storage().ref('/')`

## 環境

- Flutter 1.19.0-1.0.pre • channel dev 
-  Dart 2.9.0 (build 2.9.0-7.0.dev 092ed38a87)
- firebase: ^7.3.0
- (firebase_storage: ^3.1.6)

## 問題

`ref()`を参照する際に、firebase_storageパッケージでは以下のように参照できます。

```dart
import 'package:firebase_storage/firebase_storage.dart';

void main() {
  final storageReference = FirebaseStorage.instance.ref();
}
```

firebaseパッケージでも同様のことをすると例外が吐かれました。

```dart
import 'package:firebase/firebase.dart' as firebase;

void main() {
  try {
    final storageReference = firebase.storage().ref();
  } catch(e,s) {
    print(e);  // => [object Object]
    print(s);  // => Non-error `[object Object]` thrown by JS does not have stack trace. Caught in Dart at: ...
  }
}
```

## 解決法

firebaseパッケージを使う際は、ルートを参照する場合でも明示的に`'/'`を渡しましょう。

```dart
import 'package:firebase/firebase.dart' as firebase;

void main() {
  try {
    final storageReference = firebase.storage().ref('/');  // 明示的にルートパスを指定
  } catch(e,s) {
    print(e);
    print(s);
  }
}
```

この`ref`の内部実装は以下のようになっており、`ref()`と呼び出すと`jsObject.ref(null)`が呼ばれてしまいます。

```dart
/// Returns a [StorageReference] for the given [path] in the default bucket.

StorageReference ref([String path]) =>
  StorageReference.getInstance(jsObject.ref(path));
```

この`jsObject.ref(path)`というのは以下の`StorageJsImpl`の`ref`なので、dartでの`firebase.storage().ref()`はjsでの`firebase.storage().ref(null)`を呼んでいることになります。

```dart
@JS('Storage')
abstract class StorageJsImpl {
  ...
  external ReferenceJsImpl ref([String path]);
  ...
}
```

ちなみにChromeのコンソールで確認してみると、`firebase.storage().ref(null)`はエラーとなっているのがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266157/1ac8dbc4-d223-b143-3e4d-fd197da09880.png)
mysqlの移行

# バックアップ

```
mysqldump --single-transaction -u DBユーザ名 -p DB名　テーブル名1 テーブル名2 > 出力先ファイル名
```

```
mysqldump -u DBユーザ名 -p -h DB名 > 出力先ファイル名
```

# 復元
```
mysql -u ユーザー名 -p データベース名 < dumpファイル名
```
【Rails】devise

先日ログイン認証の実装でdeviseを導入したので記録を残します。

## deviseとは
ログイン認証機能を導入するためのgemパッケージ。
サインイン、サインアウト、サインアップ(メール認証可)など簡単に実装することができます。

### 実際の使い方を説明します。

## インストール
deviseをインストールします。Gemfileに追記し、bundle installを実行。

```ruby:Gemfile
gem 'devise'
```

```ruby
$ bundle install
```

インストールが終わったらファイルの作成をします。`rails g devise:install`を実行すると関連ファイルが作成されます。

```ruby
$ rails g devise:install
```
実行するとこのように表示されます。

```ruby
1. Ensure you have defined default url options in your environments files. Here
is an example of default_url_options appropriate for a development environment
in config/environments/development.rb:

config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

In production, :host should be set to the actual host of your application.

2. Ensure you have defined root_url to *something* in your config/routes.rb.
For example:

root to: "home#index"

3. Ensure you have flash messages in app/views/layouts/application.html.erb.
For example:

<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>

4. You can copy Devise views (for customization) to your app by running:

rails g devise:views
```
簡単にまとめると
1.URLの設定
2.ルーティングの設定
3.通知やアラートの表示
4.deviseのviewファイルをコピーし、カスタマイズできる。

とりあえず3の通知とアラートのメッセージを表示させるようにします。
`application.html.erb`に
`<p class="notice"><%= notice %></p>`
`<p class="alert"><%= alert %></p>`を追記。

```ruby:application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>App</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <p class="notice"><%= notice %></p>
    <p class="alert"><%= alert %></p>
    <%= yield %>
  </body>
</html>
```
## 認証モデルの作成
`rails g devise モデル名`で認証用モデルとマイグレーションファイルを作成。

```ruby
$ rails g devise user
```

モデルとマイグレーションファイルが作成できたら`rails db:migrate`を実行。

```ruby
$ rails db:migrate
```
これで完了です。deviseを使った認証機能を使用できるようになりました。

viewファイルを編集する場合には

```ruby
$ rails g device:views
```
これを実行するとビューが作成されるので必要に応じて編集することができます。
技術質問をする際に注意したいこと


質問をする際に、こんな感じのコードですと
よく画像を載せたりするのですが、回答者目線でのアドバイスを見かけて参考になりましたので
共有します。

##回答者が答えやすい環境を整える

1. ソースコードのリポジトリ（githubのurl）を載せる
2. ログやエラー文などをコピペできるように提供する
3. 画像を貼る際は、起こっている事象の説明に使うときにする。
  (例)レイアウトが意図したものにならない

ソースコードを画像で貼る場合は、
「ココでこうなってしまうから困るのように原因がほぼ特定できているが
なぜこうなるかわからない。」
といった具体的にココ！という断定ができている場合にすると良い。

##質問の型について

基本的な質問の型については、下記の記事に記載しています。
https://qiita.com/ki-ku/items/578df32a517722c81477
Rails アプリケーションで unicorn を nginx と共に使わなければならない理由

Rails アプリケーションを本番環境で稼働させる際、unicorn + nginx という組み合わせがメジャーです。github も、その様な構成になっています。色々な Rack サーバーがありますが、github での採用によって、unicorn が流行った感じがあります。
しかし、その一方で、unicorn 単体で利用される例は見かけません。nginx を利用する事のメリットは多くあり、**nginx を挟んだ方がよい**のですが、**unicorn を nginx と共に使わなければならない**理由は何でしょうか？

## Slow Client Attack による障害

DoS Attack の手法の一つに、**Slow Client Attack** (あるいは Slow Rate Attack)という手法があります。これは、クライアントがサーバーに接続して、ファイルをリクエストする時に、クライアントの速度を遅くすることによって、サーバーとの接続を永続的に保持するというものです。沢山のクライアントが永続的にコネクションを保持してしまうと、新しいクライアントが接続できなくなってしまいます。これは悪意のある攻撃者でなくても、4GやWifiなどの遅い回線において成り立つので、ウェブ・サーバー設計の一つの課題です。

unicorn は unix 思想に基づき「一つの事を上手くやる」ように設計されており、Slow Client を考慮していません。技術的には、**ブロッキングIO**を利用している為に、遅いクライアントによる永続的な接続がリソースを専有してしまいます。これは、unicorn のバグではなく、ウェブ・サーバーの設計方針の一つであって、悪いものではないです。しかし、この設計方針により、unicorn は、ローカル・ネットワーク以外からのアクセスを許可してはいけません。

## unicorn は keep alive も pipeline も実装していない

unicorn は永続的な接続を回避するために、keep alive も pipeline も実装されていません。これらをクライアントに提供するためには、対応したリバースプロキシが必要です。

## unicorn は静的ファイルを効率的に配信できない

unicorn は静的ファイルを効率的に配布する実装にはなっていません。nginx は、ユーザ空間でのデータ・コピーを最小にするために、静的ファイルを sendfile というシステムコールを使って配信します。

## nginx が最適なリバースプロキシである理由

unicorn は高速で単純に実装されており、幾つかのウェブサーバーに必須の機能を持っていません。これは設計上のトレードオフです。unicorn 単体で公開することも可能ですが、前述の弱点があるために、現実的ではありません。unicorn 単体では Slow Client Attack に対して脆弱です。

リバースプロキシを先頭に置くと、一旦、リバースプロキシがリクエストをバッファリングし、それをウェブ・サーバーに食べさせます。これは Spoon Feeding と呼ばれるウェブ・サーバーの高速化の手法です。親が赤ちゃんにスプーンで食べさせてあげる様から、過保護にするという意味らしいです。これによって、Slow Client からウェブ・サーバーを保護します。

その他、unicorn に実装れてない機能を nginx は有します。unicorn を ngixn と一緒に**使ったほうが良い**理由なら沢山ありますが、以上が unicorn を nginx と共に**使わなければならない**理由です。nginx は unicorn の弱点を完全にカバー出来るリバースプロキシです。

## Puma は単体で機能するウェブ・サーバー

Heroku では unicorn ではなく、Puma の利用が推奨されています。これは Heroku のアーキテクチャ的に、nginx を先頭に置くのが難しいためです。Heroku の前段には、リバースプロキシとロードバランサーがありますが、unicorn の弱点をすべてカバーするだけの機能はありません。


## 参考

* https://stackoverflow.com/questions/8739871/why-does-unicorn-need-to-be-deployed-together-with-nginx
* https://yhbt.net/unicorn/DESIGN.html
* https://yhbt.net/unicorn/PHILOSOPHY.html
* https://wiki.squid-cache.org/SpoonFeeding
* https://devcenter.heroku.com/articles/rails-unicorn
How to read virtual pin's value(I NEED Blynk.virtualRead)

There is no method like 'Blynk.virtualRead' in Blynk. So I used global variable and `Blynk.synkAll()` method.

```
int value;

BLYNK_WRITE(V10) 
{
  value = param.asInt(); 
}

BLYNK_CONNECTED() {
    Blynk.syncAll();
}

BLYNK_WRITE(V0) 
{
  int pinData = param.asInt(); 
  Serial.println(pinData);
  if(pinData == 1) {
    Serial.println(value);
  }
}
```

It works because when `BLYNK_WRITE()` event happens when `Blynk.syncAll()` or `Blynk.syncVirtual(vPin)` is called.

[docs.blynk.cc/#blynk-firmware-blynktimer-blynksyncall](http://docs.blynk.cc/#blynk-firmware-blynktimer-blynksyncall)
rails generate が全然動かない！時に試すこと

# railsでコントローラーを作ろうと思ったら...
Rails 6.0.3.1 にて
いいね機能を実装すべく、`likes_controller.rb`を作りたくて以下のコマンドを実行しました。

```
$ rails g controller likes
```

...うんともすんとも言わない:cry:

止めよう（^Cぽち）

```
^CTraceback (most recent call last):
	16: from bin/rails:3:in `<main>'
	15: from bin/rails:3:in `load'
	14: from /リポジトリ名/bin/spring:15:in `<top (required)>'
	13: from /Users/ユーザー名/.rbenv/versions/2.7.1/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:72:in `require'
	12: from /Users/ユーザー名/.rbenv/versions/2.7.1/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:72:in `require'
	11: from /Users/ユーザー名/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/spring-2.1.0/lib/spring/binstub.rb:11:in `<top (required)>'
	10: from /Users/ユーザー名/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/spring-2.1.0/lib/spring/binstub.rb:11:in `load'
	 9: from /Users/ユーザー名/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/spring-2.1.0/bin/spring:49:in `<top (required)>'
	 8: from /Users/ユーザー名/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/spring-2.1.0/lib/spring/client.rb:30:in `run'
	 7: from /Users/ユーザー名/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/spring-2.1.0/lib/spring/client/command.rb:7:in `call'
	 6: from /Users/ユーザー名/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/spring-2.1.0/lib/spring/client/rails.rb:24:in `call'
	 5: from /Users/ユーザー名/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/spring-2.1.0/lib/spring/client/command.rb:7:in `call'
	 4: from /Users/ユーザー名/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/spring-2.1.0/lib/spring/client/run.rb:35:in `call'
	 3: from /Users/ユーザー名/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/spring-2.1.0/lib/spring/client/run.rb:42:in `warm_run'
	 2: from /Users/ユーザー名/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/spring-2.1.0/lib/spring/client/run.rb:62:in `run'
	 1: from /Users/ユーザー名/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/spring-2.1.0/lib/spring/client/run.rb:117:in `verify_server_version'
/Users/ユーザー名/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/spring-2.1.0/lib/spring/client/run.rb:117:in `gets': Interrupt

```

うわ
どうやら[spring](https://github.com/rails/spring)というのが怪しい:thinking_face:

# 解決方法

`spring`を止めちゃいます。:upside_down:

```
$ spring stop
Spring stopped.
```

止まります。
`rails g` を再度実行！

```
$ rails g controller likes
Running via Spring preloader in process 23035
      create  app/controllers/likes_controller.rb
      invoke  erb
      create    app/views/likes
      invoke  test_unit
      create    test/controllers/likes_controller_test.rb
      invoke  helper
      create    app/helpers/likes_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    scss
      create      app/assets/stylesheets/likes.scss
```

できた:raised_hands:

# ちなみに
さっき止めた`spring`ですが、ステータスを確認するとしっかり動いていると思います。:runner_tone2:

```
$ spring status
Spring is running:
```

# 参考
https://stackoverflow.com/questions/25027284/ruby-on-rails-console-is-hanging-when-loading
マルチモジュールでxibやstoryboardでCustom Classの参照するモジュールの誤りを自動チェックする(Swift限定)


# 概要

昔、IBLinterにcontributeしたマルチモジュールでxibやstoryboardでCustom Classの参照するモジュールの誤りを自動チェックしてくれる機能を紹介します

[IBLinter](https://github.com/IBDecodable/IBLinter) とはInterface Builder(以降はIB)に対するLintツールです。

その中の ```custom_module``` と言うルールを作りました。
```custom_module``` ルールに対応しているのは、Swiftファイルで定義したCustom Classだけなので注意してください


IBでCustom Classに下記のように【Module】と言う蘭があります。ここは普段Class蘭の方にクラス名を入力すると自動的に
探し出して対象のモジュール名が自動入力されるのですが

<img width="800" alt="ib_module.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308423/1debab34-331d-9bfc-076f-6357d62d7073.png">

このClassこっちのモジュールに移動しよう！！

とかなった時に単純にClassを移動させた場合、悲劇が起こりやすいです。
xibやstoryboardのxml内に設定されている【Module】蘭の情報は単純にClassを移動させた場合などは自動更新されないので、xibやstoryboardから移動させたClassを参照ができなくなるのですが、
なんとビルドエラーにならずビルドが通ってしまいます！！

そうするとxibやstoryboardから参照できなかった場所はCustom Classではなく単なる標準のClass(UIView)とかになって
【何も表示されない！！】と言う悲劇を招きやすいです。

そこでチェックする機構をIBLinterにcontributeして ```custom_module``` ルールを作りました。

# 設定方法

[IBLinterのセットアップ](https://github.com/IBDecodable/IBLinter#xcode) 後、```.iblinter.yml```の```custom_module_rule```に下記のように自分の環境に合わせてに設定することでルールに従っていない場合はビルドエラーとすることができます。IBLinterのルールの適用外としたいフォルダは```excluded ```を設定すれば良いです

```
excluded: #IBLinterのルールの適用外としたいフォルダ(再帰的に配下のフォルダは全て対象外になります)、ここの指定以外のxibやstoryboardは全て対象になります
  - App/Classes/Config/Generated
custom_module_rule:
  - module: HogeUIComponents #【Module】蘭から参照されるモジュール名
    included: # Custom Classの定義されたSwiftファイルがあるフォルダ(再帰的に配下のフォルダは全て対象になります)
      - HogeUIComponents/Classes
      - HogeUIComponents/Other
    excluded: # ↑のincluded内から対象外としたいフォルダ(再帰的に配下のフォルダは全て対象外になります)
      - HogeUIComponents/Classes/Config/Generated
      - HogeUIComponents/Classes/Config/Another
  - module: FugaUIComponents #複数登録可能
    included:
      - FugaUIComponents/Classes
    excluded:
      - FugaUIComponents/Classes/Config/Generated
```

上記のような設定をすれば

例えば```HogeUIComponents```と言う名前のモジュールに

```
HogeUIComponents/Classes/AAA.swift

class HogeView {
   ...
}
```

と言うクラスを定義しており

```
App/Classes/FugaView.xib
```

で```FugaView.xib```内で```HogeView```をCustom Classで指定しているが、【Module】蘭が```HogeUIComponents```じゃないとビルドエラーとしてくれます。

なので```AAA.swift(HogeView)```を```HogeUIComponents```→```FugaUIComponents```にTarget変更し、```FugaUIComponents/Classes/```配下に移した場合

xibやstoryboard内で```HogeView```をCustom Classで参照している箇所は【Module】蘭を```HogeUIComponents```→```FugaUIComponents```に修正しないとビルドエラーになるようにできるのです！


これで【Module】蘭の誤りをチェックできます
MS Learnのビジネスフローのモジュールがわかりにくかったので詰まりポイント解説してみた

#概要

こちらのモジュールの詰まりポイント解説します。

【Power Automate におけるビジネス プロセス フローの高度な概念を理解する】
https://docs.microsoft.com/ja-jp/learn/modules/advanced-business-process-flows/?fbclid=IwAR3vePtShKGRF_we9VhGZehy60684VJJ62FCAoXiZa4eBSPbD6iwnbKyeVw

# 詰まりポイント

## 最初に
このモジュールは

【Power Automate でイマーシブ ビジネス プロセス フローを作成する】
https://docs.microsoft.com/ja-jp/learn/modules/create-immersive-flow/

をやっていることが前提になってきますので、まだ行っていない場合はこちらから学習を開始しましょう。このモジュールで作成されるビジネスプロセスフローがあることが前提となってきます。

## エンティティのフィールド名は日本語の設定は不可能

> 二次空気供給装置は購入時のものか - 2 つのオプション - 既定値として [はい] を設定
PVC バルブは購入時のものか - 2 つのオプション - 既定値として [はい] を設定
エキゾースト ヘッダーの改造 - 2 つのオプション - 既定値として [いいえ] を設定

上記のようにフィールドを作成する指示がありますが、名前に対して日本語を設定することはできません。半角英数等でわかりやすいものを設定しましょう。

## コンポーネント タブの下にある条件フロー制御を選択した後...

赤枠で囲まれているのはデータステップですが、正しくは条件になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/fb51779a-e5ee-2fab-56a0-410be567d9db.png)

## リボンのコネクタを選択し、接続オプションを選択します。
ここを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183354/53ce4fa7-d23d-a395-5c4a-7cdb15490630.png)




# Tips

## 2つのビジネスプロセスフロー

ビジネスプロセスフローは以下の2つに分類される。

１．イマーシブビジネスプロセスフロー
２．埋め込みビジネスプロセスフロー
https://docs.microsoft.com/ja-jp/power-automate/business-process-flows-overview
Twitter Direct Message APIでチャットボット実装するのに使用したドキュメント一覧

## 概要
Twitter上で初回問い合わせへの対応を行うチャットボットを作成するために、Direct Messageに関係するAPIの関連性を調べました。
これはそれをまとめたものです。
サンプルコードは記述しませんが、実装の手助けになれば幸いです。

※ 2019年末のドキュメントをQiita転載したものになります。情報が古い恐れがあります、ご容赦ください。

## Direct Message API
基本的なドキュメントはここ
https://developer.twitter.com/en/docs/direct-messages/api-features

### 関連するドキュメント
Sending and receiving events
https://developer.twitter.com/en/docs/direct-messages/sending-and-receiving/overview
基本的なDMの送受信はこのAPIを使用する
オプションとしてQuick ReplyとButtonを定義することで，ユーザーに対して選択肢による返信を実装することが可能

Welcome Messages
https://developer.twitter.com/en/docs/direct-messages/welcome-messages/overview
初めてDM画面を開いたときに表示されるメッセージを設定することができる
ユーザーに対してこちらから情報を提示するために使用する

Quick Reply
https://developer.twitter.com/en/docs/direct-messages/quick-replies/overview
Quick Replyは文字列による選択肢を提供する
ユーザーは提供された選択肢を選ぶことで，選ばれた文字列をDM送信する

Button
https://developer.twitter.com/en/docs/direct-messages/buttons/overview
Buttonは所謂Call To Action(CTA)と呼ばれるもので，DM送信以外のアクションを選択肢として提供する
ユーザーは提供された選択肢を選ぶことで，選ばれたアクションが実行される(フォローを行うや，特定のURLに遷移させる)

QuickReplyを使用しPythonで実装されたドキュメント
https://medium.com/@torufurukawa/chatbot-with-twitter-direct-message-api-74fc46dca5d1
https://medium.com/@torufurukawa/twitter-direct-message-api-beta-2128bf0b2269

## DMへの誘導
TweetからDMへ誘導するのに有効と思われるもの

### ダイレクトメッセージカード
https://business.twitter.com/ja/help/campaign-setup/Create_DM_Card.html
※現在個人広告主は利用ができないため要問合せ

### CTA
ツイートにもCTAを使用することができる
https://business.twitter.com/ja/help/campaign-editing-and-optimization/public-to-private-conversation.html
https://gist.github.com/citrusui/b1acfa1bc13a0dcdbe8307668fa18f21
yarnをバージョンダウンする方法

# yarnのバージョンダウンと検索しても意外と出てこない
- だから書きました。
- Dockerでの記載になっていますが、[こちらの方の記事](https://qiita.com/FumiyaShibusawa/items/627f0c806b49e364c3db)を参考にさせて頂きました。a lot of 感謝。

# 環境
- ubuntu18.04

# たったこれだけ
- これだけです。
- 1.10.1の場合

```
wget https://github.com/yarnpkg/yarn/releases/download/v1.10.1/yarn_1.10.1_all.deb
sudo dpkg -i yarn_1.10.1_all.deb
```
DKIM対応のメール中継サーバーを作った

https://github.com/netebakari/ubuntu-postfix-opendkim

# 何ができるか
* 任意（とりあえずTCP 25番と1025番）のポートで待ち受ける
* **認証なし**でメールを受け取るとそのまま外部へメールを転送する
* 送信元アドレス(header-from)があらかじめ設定されたドメインだったら**DKIM署名を付加**
* 次の2種類のログを残す
  * 送信元・送信先・表題など（タブ区切り）
  * ヘッダを含めたメール本文全体（メール1件に対してファイル1個）

# 新しいPostfixでできること
2020/6/5現在、[Postfix](http://www.postfix.org/announcements.html)の最新バージョンは3.5.2です。
CentOS 8でも（リポジトリを追加しないと）デフォルトで落ちてくるのは2.3なので素直に2.x系を使っている人が多いようなのですが、新しいバージョンでは色々と便利な機能が増えています。特に3.4ではコンテナサポートということで、

* `maillog_file = /dev/stdout` でログを標準出力に吐き出せるようになった
  * maillogではなくDockerのログとして残せる
* `postfix start-fg` がサポートされた
  * サービスを起動した後で無限に待ち受けをしてくれる
  * 何らかの理由でPostfixが落ちたらコマンドが終了→コンテナも終了→docker-composeが再起動するようにできる

という2点により、Postfix + OpenDKIMのみの構成であればSupervisorも不要になっています。

# いまどきAWS SESで良くない？
まあ……はい……
【超基本】カウントアップで学ぶ②AVFoundationで効果音をつける。

## はじめに
本記事はプログラミング初学者の筆者が、備忘録として作成した記事であり、興味本位で試してみたい機能についてのメモである。

前回の続きです。
[【超基本】カウントアップで学ぶ①if文](https://qiita.com/mashishift/items/a6fcc79e845d5cc1f2a8)
## ゴール
・AVFoundationを用いて、アプリに効果音を付ける。

##内容
・前回作成したカウントアップアプリに効果音を付ける。
・AVFoundationを用いて、Labelが"7"の時にハッピーな効果音を流す。
・↑と同時にimageViewに"犬"の画像を表示し、"祝福の言葉"をLabelに表示させる。

##完成：Simulator画像
・"7"の時、効果音が鳴る。
・犬に祝ってもらう。
<img width="375" alt="Simulator Screen Shot - iPhone SE (2nd generation) - 2020-06-05 at 16.07.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642055/17ebbde6-6a9a-d26a-5120-5a5c596f396a.png">

##備考
前回のコードから追加した箇所は「//追加」のようにコメントアウトしております。そのほかの部分は、前回と同様のものです。

##完成：実際のコード
```php:countUp.Swift
import UIKit
import AVFoundation //追加

class ViewController: UIViewController {
    
    
    @IBOutlet weak var countLabel: UILabel!
    @IBOutlet weak var imageView: UIImageView!
    
    var count = 0

    //音源ファイルを指定する。
    let lucky7Music = Bundle.main.bundleURL.appendingPathComponent("音楽ファイル名")
    //音楽プレイヤーインスタンスを作成する。
    var lucky7Player = AVAudioPlayer()


    override func viewDidLoad() {
        super.viewDidLoad()

        countLabel.text = "0"

    }
    
    @IBAction func UPButton(_ sender: Any) {
        
        count = count + 1
        countLabel.text = String(count)
        
        if count >= 10  {
            countTextColer()
        }
            else if count == 5 {
            redTextColor()
            imageView.image = UIImage(named: "画像ファイル名")
            }
            //7の場合を追加
            else if count == 7 {
            do {
            //音楽プレイヤーに音楽(lucky7music)をセット。
            lucky7Player = try AVAudioPlayer(contentsOf: lucky7Music, fileTypeHint: nil)
            //音楽プレイヤ〜を再生。
            lucky7Player.play()
            } catch {
                print("エラー発生")
            }
            countLabel.text = String("Labelに表示したい言葉")
            imageView.image = UIImage(named:"犬の画像")
        }
        
    }
    
    @IBAction func DOWNButton(_ sender: Any) {
        
        count = count - 1

        countLabel.text = String(count)
        
        if count <= 0 {
            resetTextColor()
            imageView.image = UIImage()
            
        }
            else if count == 5 {
            redTextColor()
            }

        
    }
    @IBAction func ResetButton(_ sender: Any) {
        resetButton()
    }
    func countTextColer() {
        countLabel.textColor = .yellow
        
    }
    func  resetTextColor(){
        countLabel.textColor = .black

    }
    func redTextColor(){
        countLabel.textColor = .red
    }
    func resetButton(){
        imageView.image = UIImage()
        count = 0
        countLabel.text = String(0)
        countLabel.textColor = .black
    }
    
}

```
##結果
・AVFoundationを使い、アプリに音楽を挿入できるようになる。
・犬に祝ってもらえる。
Oracle PL/SQL プロシージャとファンクション

#はじめに
OracleのPL/SQLの復習のため、記事として残します。

#プロシージャ(PROCEDURE)
プロシージャとはOracleではPL/SQLと呼ばれているもので、事前にデータベースにコンパイルしておき、使用する時はそれを呼び出すだけという使い方をします。

プロシージャでは1つのSQL文では記述することができない複雑な処理を書くことができます。また、アプリケーションとデータベースの行き来する回数が少なくて済むため、ネットワークの負荷を少なくする、処理が高速になるというメリットがあります。

##プロシージャ 基本形
```
CREATE [OR REPLACE] PROCEDURE
  ストアドプロシージャ名[(引数名 {IN | OUT | INOUT} データ型,...)]
IS
  宣言部
BEGIN
  処理部
EXCEPTION
  例外処理部
END
;
```

##プロシージャ 例文
ログを出力する処理

```
CREATE PROCEDURE PLSQL_LOG(LOGMSG CHAR)
IS
FILE_HD UTL_FILE.FILE_TYPE;
BEGIN
	FILE_HD:=UTL_FILE.FOPEN('D:\LOG\PLSQL','_'||USERENV('TERMINAL')||'_'||SYS_CONTEXT('USERENV','MODULE')||'_'||TO_CHAR(SYSDATE,'YYMMDD')||'.TXT','a'); 

	UTL_FILE.PUT(FILE_HD,TO_CHAR(SYSDATE,'HH24:MI:SS')||','||LOGMSG);
	UTL_FILE.FCLOSE(FILE_HD);

	DBMS_OUTPUT.PUT_LINE(LOGMSG);
EXCEPTION WHEN OTHERS THEN
	DBMS_OUTPUT.PUT_LINE('ログ出力エラー:'||SQLERRM||'('||SQLCODE||')');
END;
```

#ファンクション(FUNCTION)
戻り値を返したい場合は、ファンクションで記述します。

##ファンクション 基本形
```
CREATE [OR REPLACE] FUNCTION ファンクション名(引数 IN データ型[, ...])
    RETURN 戻り値の型
  IS
    宣言部
  BEGIN
    処理部
  END
;
```

##ファンクション 例文
引数に渡した数値を2倍して返す処理

```
CREATE FUNCTION DOUBLE_NUMBER(IN_NUM IN NUMBER) RETURN NUMBER
IS
OUT_NUM NUMBER;
BEGIN
	OUT_NUM := IN_NUM * 2;
	RETURN OUT_NUM;
END;
```
#PL/SQL確認方法メモ
##shared_poolの確認方法
```
SELECT *  FROM V$DB_OBJECT_CACHE;
```
##全てのオブジェクトを調べる
```
SELECT * FROM USER_OBJECTS;
```
##PL/SQLのエラーを調べる
```
SELECT * FROM USER_ERRORS;
```
##PL/SQLのソースを調べる
```
SELECT * FROM USER_SOURCE;
```
Androidアプリをコマンドラインで起動、終了する

## Activityを起動する
### Syntax
am start -a android.intent.action.MAIN -n ***PackageName***/.***ActivityName***

e.g.
`am start -a android.intent.action.MAIN -n com.xxx.xxxApp/.MainActivity`


## Activityを終了する
### Syntax
am force-stop ***PackageName***

e.g.
`am force-stop com.xxx.xxxApp`
[メモ]Squidでプロキシを試してみる

# EC2にSquidをインストールする
以下参考にさせて頂きました。
[AWS EC2にプロキシサーバを構築して海外向けサイトを国内から閲覧する]
(https://haloechoes.com/server-operations/build-proxy-servers-for-overseas-sites/)

## Proxy 接続テスト
ブラウザーにプロキシ設定を追加してアクセス。送信元IPがEC2のIPになる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162167/b44d56d4-5933-9e7d-f373-b090ddff41e0.png)

### ログ
googleにアクセスした際のSquidアクセスログ

```
[05/Jun/2020:05:19:46 +0000] "GET http://google.com/ HTTP/1.1" 301 653 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:65.0) Gecko/20100101 Firefox/65.0" TCP_MISS:HIER_DIRECT
[05/Jun/2020:05:19:47 +0000] "POST http://ocsp.pki.goog/gts1o1 HTTP/1.1" 200 826 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:65.0) Gecko/20100101 Firefox/65.0" TCP_MISS:HIER_DIRECT
```

## リバースProxy接続テスト
以下参考にさせて頂きました。
[Squidをリバースプロキシサーバーとして使う](https://kazuhira-r.hatenablog.com/entry/2019/10/07/234239)

### ログ
Squidアクセスログ

```
[05/Jun/2020:07:18:17 +0000] "GET http://xxx.ap-northeast-1.compute.amazonaws.com:3128/test.html HTTP/1.1" 304 405 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36" TCP_REFRESH_UNMODIFIED:FIRSTUP_PARENT
```

Nginxアクセスログ

```
127.0.0.1 - - [05/Jun/2020:07:21:18 +0000] "GET /test.html HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36" "220.215.xxx.xxx"
```
WikiExtractor.py の使い方

自然言語処理で学習用のサンプルが必要になった等の理由で Wikipedia の生文が必要になる場面があるかもしれません.
Wikipediaが提供しているダンプデータから記事本文を抽出する [wikiextractor](https://github.com/attardi/wikiextractor) というOSSがあるので使い方をメモします.

## How to Use
まず https://github.com/attardi/wikiextractor をクローンして `WikiExtractor.py` を作業するディレクトリにコピーなりする.

### 基本

```
python WikiExtractor.py <path_to_the_wikipedia_dump_file>
```



ダンプファイルは解凍せずに直接`jawiki-latest-pages-articles.xml.bz2`などを指定して良い模様.

Wikipedia の xml ダンプファイルは

```
curl https://dumps.wikimedia.org/jawiki/latest/jawiki-latest-pages-articles.xml.bz2 -o jawiki-latest-pages-articles.xml.bz2
```

などで取ってくる. 年次を詳しく指定したりしたい場合はここから取ってくる : [https://ja.wikipedia.org/wiki/Wikipedia:%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89](https://ja.wikipedia.org/wiki/Wikipedia:データベースダウンロード) 

約400万タイトルの処理状況が標準log に吐き出されます. 処理には数十分〜数時間かかります.

### 出力形式

`text` というディレクトリが作成され, 次のような構造でファイルが作成される.

```
/text
├─/AA
│ ├─wiki_00
│ ├─wiki_01
│ :
│ └─wiki_99
├─/AB
│ ├─wiki_00
| :
│ └─wiki_99
:
├─/AZ
| ├─wiki_00
| :
├─/BA
| ├─wiki_00
: :
```

`AA` から順にWkipediaの記事がABC順(日本語Wikiなら五十音順) で入っている.

各 `wiki_XX`はプレーンテキストで書式は以下のようになっている.Json 形式でも出力可能(後述). 

```
    <doc id="" revid="" url="" title="">
        ... (記事本文)
        </doc>
```



### おすすめオプション

```
python WikiExtractor.py <input_path> --processes <process_num> -o <output_path> --json -b <n[KMG]>
```

- --processes: `--processes 8` のように指定し, CPUのコア数を指定してマルチプロセスで処理. 

- --json: 出力を 毎行 json で出してくれる.

```
{"id": "", "revid": "", "url":"", "title": "", "text": "..."}
```

- -b: デフォルトでは各`wiki_XX`ファイルは1MBごとに区切られるようになっています. `-b 1G`のように指定して制限を緩和できます. 出力を1ファイルにしたい場合は `-b 5G` のようにすると1ファイルに出力される.

### 出力を1ファイルにしたい

自然言語処理で用いたりする場合は1ファイルのテキストファイルがあった方が都合が良いかもしれない.

```
cat text/*/* > jawiki.txt
```



## 参考

- https://github.com/attardi/wikiextractor
- http://ankaji92.hatenablog.com/entry/2016/11/27/212507
SFDXプロジェクトから変更セットを自動作成する

# はじめに

これからはUnlocked Package（ロック解除済みパッケージ）を使いましょうという話だとは思うのですが、お客様組織でDevHubを有効にしてもらうなどハードルも高く、まだまだ変更セットを使っている方がほとんどだと思います。

しかし、変更セットの作成はなかなかの苦行です。GUIでぽちぽちとコンポーネントを追加する必要があります。追加し忘れて、変更セットのリリースがエラーになった経験のある方もきっと多いでしょう。

この記事ではSFDXプロジェクト形式で管理しているソースコードから変更セットを自動作成する方法を説明します。

**※追記2020/06/05 22:12**
Salesforce CLIにメタデータAPIのdeployあるのを忘れていて、最初jsforceでデプロイしてたのですが、思い出したので、4-1.を書き換えました。

# 概要

実は自動作成は嘘で、正確には**半自動作成**です。

変更セットは[メタデータAPIのdeploy](https://developer.salesforce.com/docs/atlas.ja-jp.api_meta.meta/api_meta/meta_deploy.htm)で更新することができるのですが、変更セットの作成自体を行なうAPIはありません。変更セットの作成だけ手動で行なう必要があります。

基本的な流れとしては、`sfdx force:source:convert`でメタデータAPI形式のファイルにして、上記の`deploy`メソッドで変更セットにコンポーネントを追加するという方法で半自動化することができます。

# 手順

## 1. 空の送信変更セットを作成する

Sandbox組織で適当な名前をつけて空の送信変更セットを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27267/1e4afebf-c084-828f-81c6-c877e3d3aa91.png)

## 2. メタデータAPI形式に変換する

`sourcepath`に変更セットに入れたいコンポーネントが入っているディレクトリを指定し、`packagename`に先ほど作った変更セット名を指定します。

```
sfdx force:source:convert \
--sourcepath <変更セットに入れたいコンポーネントが入っているディレクトリ> \
--packagename <変更セット名> \
--outputdir mdapioutput
```

イメージとしては以下のようなディレクトリ構成を想定しています。そして、`package1/main/module1`とか`package2`とかを`sourcepath`に指定します。

```
.
├── package1
│   └── main
│       ├── module1
│       ├── module2
│       └── module3
├── package2
│   └── main
│       ├── module1
│       ├── module2
│       └── module3
└── sfdx-project.json
```

`mdapioutput/package.xml`は以下のようになり、パッケージ名として変更セット名が入っているのがポイントです。

```
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
  <types>
    <name>AuraDefinitionBundle</name>
    <members>XXX</members>
  </types>
  <types>
    <name>ApexClass</name>
    <members>XXX</members>
  </types>
  <version>48.0</version>
  <fullName>変更セット名</fullName>
</Package>
```

`mdapioutput`フォルダに変換したファイルを出力するので、`.gitignore`に追加しておくとよいです。

## 3. zipファイルを作成する

メタデータAPI形式のファイルをフォルダごとzipファイルにします。

```
zip -r ./dist/changeset.zip mdapioutput/
```

`dist`も`.gitignore`に追加しておくとよいでしょう。

## 4. 変更セットにコンポーネントを追加する

CLIかWorkbenchの２つの方法があります。

### 4-1. CLIで実行

Sandbox組織にログインします。

```
sfdx force:auth:web:login -a my-sandbox -r https://test.salesforce.com
```

`force:mdapi:deploy` コマンドでデプロイします。

```
sfdx force:mdapi:deploy --zipfile dist/changeset.zip -w 15
```

### 4-2. Workbenchで実行

メタデータAPIのdeployを実行できればいいので、[Workbench](https://workbench.developerforce.com)でも実行できます。
[migration] > [Deploy]から以下のようにzipファイルを選択し、Nextボタンを押し、指示通りにすすめるとデプロイできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27267/74d902ac-0fe1-44ba-61bb-17941967c204.png)

## 5. 送信変更セットに追加されたことを確認

ちゃんと送信変更セットにコンポーネントが追加されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27267/bccbc283-71f2-fa8e-24ad-c6c3ccbecfb8.png)

# 終わりに

本番組織に直接デプロイするのと何が違うんだって言われるとそんなに違わないのですが、強いて言えば変更セットを介することで本番組織へのリリース作業をエンジニアでなくてもできるというところはメリットでしょう。あとなんかちょっと安心感がある。
Unlocked Packageが普及するまでのつなぎにはなるのではないかと思います。
Google Calendar APIを使ってみた

さぁ、始まりました！使ってみたシリーーーズ
今回はGoogle Calendar APIで予定（日本の休日）を取得してみる。

# 準備

- [Google Cloud Platform](https://console.cloud.google.com/)にアカウントを作ってログインする。
- プロジェクトを作成する。
- [APIとサービス]-[ライブラリ]で`Google Calendar API`を選択して[有効にする]をクリックする。
- 認証情報を作成で`サービス アカウント`を選択する。
- キーを作成でキータイプJSONを選択して[作成]をクリックする。

サービスアカウントのJSONファイルがダウンロードされる。

# Google Client Libraryをインストール

[PHPクイックスタート](https://developers.google.com/calendar/quickstart/php)

[composer](https://getcomposer.org/)がインストールされていない場合はインストールする。

```sh
$ brew install composer
```

プロジェクトフォルダを作成してGoogle Client Libraryをインストールする。

```sh
$ mkdir myproject; cd myproject
$ composer require google/apiclient:^2.0
```

`vendor`フォルダと`composer.json`、`composer.lock`ファイルが作成される。

# 実装

日本の祝日カレンダーを取得する。

```php
require_once 'vendor/autoload.php';

$timeMin = new DateTime('-1 month');
$timeMax = new DateTime('+1 month');

$credentials = 'credentials.json'; # サービスアカウントのJSONファイル
$calendarId = 'ja.japanese#holiday@group.v.calendar.google.com';

$client = new Google_Client();
$client->setApplicationName('My App');
$client->setScopes(Google_Service_Calendar::CALENDAR_READONLY);
$client->setAuthConfig($credentials);

$service = new Google_Service_Calendar($client);
$optParams = array(
    'orderBy' => 'startTime'
  , 'singleEvents' => true
  , 'timeMin' => $timeMin->format('c')
  , 'timeMax' => $timeMax->format('c')
);
$events = $service->events->listEvents($calendarId, $optParams);

foreach ($events->getItems() as $event) {
  echo $event->start->date . ': ' . $event->getSummary();
}
```
【Docker】schema.rbがない、作っても中身がない、から解決へ


#はじめに
Rails(API) ✕ Dockerの環境で開発を進めていく中で、テーブルの構造を確認する為、schema.rbを確認するも、存在しなかった。
原因がわからず、途方に暮れたがなんとか解決できたので、まとめておく。


#schema.rbが作成されるタイミング
`rails db:migrate`したタイミングで、通常であれば
`db/schema.rb`とDBディレクトリ直下に作成される。

「schema.rb　無い」で検索して発見した、
[【おまけ】rails db:schema:dump で db/schema.rb 作成](https://r17n.page/2019/08/05/rails-with-existing-database-readonly/#%E3%80%90%E3%81%8A%E3%81%BE%E3%81%91%E3%80%91rails-db-schema-dump-%E3%81%A7-db-schema-rb-%E4%BD%9C%E6%88%90)

こちらの記事を参考にさせて頂いて、
`rails db:schema:dump`を行うも、自分の環境で作成されたのは、中身が空っぽの`schema.rb"だった。

#Dockerコンテナ内でファイルの有無の確認
`docker-compose run api bash`でDockerコンテナ内に入り、
`cd db` でDBディレクトリに移動し、`ls`　とすると、

```shell
migrate  schema.rb  seeds.rb
```

あった。。

なぜVScode上ではないのか、と思い再起動するもやっぱりない。

#原因・解決

docker-compose.ymlのvolumesの書き方を間違えていた。

```yaml:docker-compose.yml
volumes:
      - .:/my_app
```

`- .:/app`とすべき所を、

`- ./app`としていた為、ローカルのホスト機とDockerコンテナの変更が同期されていない状態だった。

###volumesの書き方について
.（ピリオド）が`docker-compose`を行ったカレントディレクトリ示し、：（コロン）を挟んだ右側に、Dockerコンテナ内でのパスを書くことで、同期される。

`[ホスト機のパス]: [Dockerコンテナ内でのパス]`
という形にすることで、ローカルのプロジェクトディレクトリをアタッチ、Dockerのコンテナが起動（docker-compose）する際にカレントを見る＝ローカルのプロジェクトディレクトリを見るという設定を行うことができる。


逆に、`：（コロン）`をつけずに、

```yaml
    volumes:
      - /home/vagrant/opt/mysql:/var/lib/mysql
```
などの形にすると
ホスト機のディレクトリでは無く、Dockerの中でvolume領域を作って、それをアタッチする形になり、ローカルのホスト機とDockerコンテナの変更は同期されない。


###終わりに。
最後まで読んで頂きありがとうございます:bow_tone1:
転職の為、未経験の状態からRailsを学習しております。正しい知識を着実に身に着け、実力のあるエンジニアになりたいと考えています。継続して投稿していく中で、その為のインプットも必然的に増え、成長に繋がるかと考えています。
今現在、初心者だからといって言い訳はできないですが、投稿の内容に間違っているところや、付け加えるべきところが多々あるかと思いますので、ご指摘頂けると幸いです。この記事を読んで下さりありがとうございました。
M5Atom LiteでLチカと複数回ボタンクリックをマルチタスクでこなす

## 経緯

どうしても仕事でM5Atomを使ったPOCをしなくてはならなく結構演算ループが込み入りそうなので、上手いこと掲題の周辺操作をマルチタスクにできないかと思っていろいろ調べたところ、FreeRTOSみたいな怖い単語が出てきて、よわよわプログラマ※としては萎えて諦めそうになったのですが、割と簡単にできそうなコードを発見したのでそれをベースに書いてみました。
※本職はデータ屋です

## 動作

M5Atom Liteは非常にシンプルで安価で素晴らしいデバイスです。こいつの良さを最大限引き出すには1つのボタンで複数種類の操作をさせられるようにすること、LEDの点灯パターンを増やせるようにすることが重要です。サンプルでは以下のようにクリック回数で点灯パターンが変えられます。

- クリック1回で全色400ms点灯
- クリック2回(を600ms以内で実施)で青200msの2回点灯

## コード

```
#include "M5Atom.h"

//LED表示バッファ
uint8_t DisBuff[2 + 5 * 5 * 3];

//LED表示バッファへの値セット
void setBuff(uint8_t Rdata, uint8_t Gdata, uint8_t Bdata)
{
  DisBuff[0] = 0x05;
  DisBuff[1] = 0x05;
  for (int i = 0; i < 25; i++)
  {
    DisBuff[2 + i * 3 + 0] = Rdata;
    DisBuff[2 + i * 3 + 1] = Gdata;
    DisBuff[2 + i * 3 + 2] = Bdata;
  }
}

//LED点灯タスクを渡す変数
int ledTask = 0;

//LEDの点灯をコントロール
void ledControl(void* arg) {
  while (1) {
    if(ledTask == 1){
      ledTask = 0;
      setBuff(0x20, 0x20, 0x20);
      M5.dis.displaybuff(DisBuff);
      delay(400);
      setBuff(0x0, 0x0, 0x0);
      M5.dis.displaybuff(DisBuff);   
      
    } else if(ledTask == 2){
      ledTask = 0;
      setBuff(0x0, 0x0, 0x30);
      M5.dis.displaybuff(DisBuff);
      delay(200);
      setBuff(0x0, 0x0, 0x0);
      M5.dis.displaybuff(DisBuff);   
      delay(200);
      setBuff(0x0, 0x0, 0x30);
      M5.dis.displaybuff(DisBuff);   
      delay(200);
      setBuff(0x0, 0x0, 0x0);
      M5.dis.displaybuff(DisBuff);
      
    } else {
      //適度に待つ
      delay(100);
    }
  }
}

//ボタンの複数回クリックコントロール
unsigned long tsStart = 0;
unsigned char sequentialButtonPressedCount = 0;

//複数回クリックを管理するタスク
void multiClickControl(void* arg) {
  while (1) {
    //
    unsigned long ts = millis();
    
    if(M5.Btn.wasPressed()) {
      //初回
      if(sequentialButtonPressedCount == 0)
      {
        tsStart = ts;
      }
      sequentialButtonPressedCount++;
    }
  
    //初回クリックから指定ミリ秒経過したら
    if(ts - tsStart > 600 && sequentialButtonPressedCount > 0)
    {
      if(sequentialButtonPressedCount == 1){
        ledTask = 1;
      }
      if(sequentialButtonPressedCount == 2){
        ledTask = 2;
      }
  
      sequentialButtonPressedCount = 0;
    }
    M5.update();
    delay(40);
  }
}

void setup() {
  M5.begin(true, false, true);
  delay(10);

  //タスクの設定
  xTaskCreatePinnedToCore(ledControl, "LEDTask0", 4096, NULL, 1, NULL, 1);
  xTaskCreatePinnedToCore(multiClickControl, "ClickTask0", 4096, NULL, 1, NULL, 1);
}

void loop()
{
  delay(2000);
}
```

## 参考

[M5Stackでマルチタスク処理を実行する](https://qiita.com/nnn112358/items/733b5f52957980bb9fb1)
Xcode のバージョンを上げたあとでXVim2を復活させるときの備忘録

## Xcode のバージョンを上げると XVim2 が効かなくなっている...

あるあるなので備忘も込めてこちらにメモします。新規にインストールするケースではなく、既存のものの再インストール方法になります。

毎回README読みにいくのが面倒なので、ここにある **内容をスクリプト化** しちゃうと楽かもしれません。

## 対象読者

- **XVim2** ユーザー(導入済み)

## ざっくり

現在(2020/09/07時点)確認されている方法をまとめておきます。
何かうまく行かない場合は、[こちら](#確認場所)で更新されていないか確認します。

1\. 署名

```bash
# 5分くらいかかります
sudo codesign -f -s XcodeSigner $(xcode-select -p)/../..
```

※ 以下のエラーが出る場合は、[こちらの2.のステップ](https://github.com/XVimProject/XVim2/blob/master/SIGNING_Xcode.md)を実行してください。自己証明書の有効期限が切れている可能性が高いです。

```text
error: The specified item could not be found in the keychain.
```

2\. インストール

```bash
# XVim2 のリポジトリへ移動(git clone 済の前提)
cd XVim2
make
```

## 確認場所

変更があるかもしれないので、そういう場合の確認場所をまとめておきます。

1\. 署名

https://github.com/XVimProject/XVim2/blob/master/SIGNING_Xcode.md

2\. インストール

https://github.com/XVimProject/XVim2
ブラウザがwebp対応か確認する手っ取り早い方法

# TL;DR

多分これが一番早いと思います

```
        //webp環境のチェック
        function checkWebP() {
          return new Promise(res => {
            const webP = new Image();
            webP.src = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';
            webP.onload = webP.onerror = function () {
              res(webP.height === 2);
            };
          })
        };
        checkWebP().then((result) => {
          if (!result) {
             //結果の確認
             console.log('webp:' + result)
          }
        });

```


# 解説

ポイントは二つ。

* webp画像を直接生成する  
  大きさ2ドットのwebp画像を直接生成する(```const webP～ webP.onloadの部分 ```) 。   
  実際にサンプル用のwebp画像を用意して読み込めるかを確認しても良いが、こちらほうが画像をロードする時間がかからず、高速。
* Promiseを使う    
  Image().onloadは非同期に実行する必要がある。  

# 実行結果


* chromeの場合

```
webp:true
```
* safariの場合

```
webp:false
```
Linuxでディレクトリ配下のファイル内容を一括置換する最も簡単な方法

しばしば忘れるので、自身の備忘録として…

# ファイルの拡張子を指定しない場合

- 対象の確認

```
$ find ./ -type f | xargs grep "foo"
```

- 置換実行

```
$ find ./ -type f | xargs sed -i -e "s/foo/bar/g"
```

- 置換後の確認

```
$ find ./ -type f | xargs grep "bar"
```

# ファイルの拡張子を指定する場合

- 対象の確認

```
$ find ./ -type f -name "*.php" | xargs grep "foo"
```

- 置換実行

```
$ find ./ -type f -name "*.php" | xargs sed -i -e "s/foo/bar/g"
```

- 置換後の確認

```
$ find ./ -type f -name "*.php" | xargs grep "bar"
```

# sed のオプションについて

### -i オプション

ファイルを直接上書きする。

これを付けないと、ディストリビューションによりバックアップファイルが自動作成されることがあります。
バックアップを明示的に指定する場合は `-i.bak` のように指定。

### -e オプション

`–expression=スクリプトコマンド` のこと。
基本的には、 "s/foo/bar/g" や "s/foo/d" になります。

Fin ❤︎
STS(SpringToolSuite)の半角スペースを「u」から「・」に変更する

SpringFrameworkの学習をするために、STSを導入したが半角スペースがuで非常に見づらいため変更の手順をメモとして残しておきます。
基本的にはEclipseの場合と同じ手順です。

# STSバージョン
Spring Tool Suite 4 
Version: 4.6.0.RELEASE

## 手順
STSのインストール先パス（人によるけど参考までに）
`"C:\Applications\sts-4.6.0.RELEASE\dropins\MergeDoc\eclipse\plugins\jp.sourceforge.mergedoc.pleiades\conf\pleiades-config.xml"`

```
			$3	= $3.equals("·" ) ? "ᴜ"	// 半角空白 例：▫ᵁᐡᶸᓑᴜՍ
                <!-- ↓↓ 下記へ変更する ↓↓ -->
            $3	= $3.equals("" ) ? "ᴜ"	// 半角空白 例：▫ᵁᐡᶸᓑᴜՍ
```
以上です。それでは良いコーディングライフを。お疲れ様でした。

## 参考URL
[eclipseの半角スペース表示をuから・に変更する](https://qiita.com/laikuaut/items/0ea390cfe6144d5b5e29)
JuliaでNeural ODE (DiffEqFluxライブラリ)


2018年のNeurIPSで話題になった[NeuralODE](https://arxiv.org/abs/1806.07366)ですが、Juliaで簡単に出来るパッケージ「DiffEqFlux.jl」が出たようです。

論文：https://arxiv.org/abs/1902.02376
GitHub：https://github.com/SciML/DiffEqFlux.jl
ドキュメント：https://diffeqflux.sciml.ai/dev/
Juliaの公式ブログ記事：https://julialang.org/blog/2019/01/fluxdiffeq/

# Juliaのセットアップ
筆者はJuliaの開発環境にJunoを用いています。
MATLABのような感じで動かせるので便利です。

セットアップはこちらの記事が参考になります。
https://qiita.com/SatoshiTerasaki/items/3dda33ece801b75e248c

# DiffEqFlux.jlはどんなライブラリか
Juliaの機械学習ライブラリは以下の記事にあるのように色々とあります。
https://opensourceforu.com/2019/03/the-best-machine-learning-libraries-in-julia/
この中でも、「[Flux.jl](https://github.com/FluxML/Flux.jl)」ライブラリは有名です。
また、微分方程式を解くライブラリとしては「[DifferentialEquations.jl](https://github.com/SciML/DifferentialEquations.jl)」ライブラリがあります。
この２つを組み合わせできたのが、今回の「DiffEqFlux.jl」ライブラリのようです。

DiffEqFlux.jlはNeural ODEだけではなく、確率微分方程式や偏微分方程式を使用したニューラルネットワークを作ることも出来るようです。(Universal neural differential equations)
また、GPUの使用にも対応しています。

# DiffEqFlux.jl試してみる

環境は以下です。
Ubuntu
Julia 1.4.2
Juno

## インストール

ライブラリのインストールはJuliaの対話環境で以下のように行います。

```julia
Pkg.add("DiffEqFlux")
```

## デモを動かす

[ドキュメントにNeural ODEのデモがありました。](https://diffeqflux.sciml.ai/dev/examples/neural_ode_sciml/)
これを動かしてみましょう。

実行すると、予測値がデータにフィッティングされていく様子がplotで分かります。

最初のplot
![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521288/17d3dedb-3900-c796-3c20-5753e19fe9de.png)

トレーニング後のplot
![test2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521288/26ed040c-69e7-aec1-f2f8-f440b2704792.png)


# 終わりに
使いこなすにはJuliaやFluxライブラリの知識が必要になりそうです。
これから勉強していきたいと思います。
【UiPath】「ワークフローとして抽出」すると型のエラーが起きる

# はじめに
使用バージョン：UiPath Studio Community版 2020.4.1

「ワークフローとして抽出」は既存のワークフローの一部から新しいワークフローファイルを抽出できる機能だが、不具合があるようなのであまり使わないほうがいいかもしれない。
不具合が起きた後の解消は知識があれば可能だが、非ITエンジニアにとっては難しいと思われる。

# 現象
「ワークフローとして抽出」したワークフローファイルの「インポート」が大量に欠落することがある。
その結果、抽出前では問題なかった記述が、名前空間の欠落でエラーになる。例：`型 'xxx' が定義されていません。`

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424975/903a98fc-1d90-9251-063a-4d1ba1e7e750.png)

# 解消方法
インポートが欠落している様子はUiPath Studio上から確認できる。ここで足りない名前空間を1つずつ足しても良いが手間がかかる。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424975/3573878a-0ba1-bd58-0cd2-9ca5fcd13f43.png)

なので、抽出前と後のxamlファイルをテキストエディタで開き、下記タグとその中身を丸ごとコピーして貼り付ける。
`<TextExpression.NamespacesForImplementation>`
`<TextExpression.ReferencesForImplementation>`

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424975/01253a1f-72fa-8c21-b7f9-eb5d229dd82e.png)

抽出後ファイルを保存した後、UiPath Studioで開きなおせばエラーが解消される。
Let's Encrypt のDNS-01認証で作成した証明書の手動での更新方法

# 背景

特定場所からのみ接続が許可されている開発サーバーに対して Let's Encrypt による証明書の発行を行いたい。
発行・更新には DNS-01 というDNSレコードにトークンを埋め込むことで発行者側に正しく設定できていることを伝える方法があるのでこれを使う。
大抵調べても詳細を忘れるのでメモ。

# コマンド

ドメインが `www.example.com` の場合。 
これで対話式の手作業でDNSの更新・新規登録作業が行える。

```bash
sudo certbot certonly --manual -d www.example.com --preferred-challenges dns
```

証明書を更新した後は、nginx/apache などの再起動をお忘れなく。

## 補足

`renew` コマンドで（自動化した）証明書の更新を行う場合、DNSレコードの値を設定・削除できる必要がある。
この場合、 `--manual-auth-hook` で指定したスクリプトで DNS に値を設定し、`--manual-cleanup-hook` で指定したスクリプトで不要なレコードを削除する。


# 参考(というか答え)

- https://www.codingstock.jp/letsencrypt_dns01_autorenew/
- https://wordpress.8940.ml/ssl/2019/01/wildcard_ssl_certificate_extension/
ツイッター背景画像とアイコン作成

●ツイッターのアイコン画像作成
[LOGO MAKER](https://logo-maker.stores.jp/)で作成
●ツイッターのアイコン背景画像作成
・パーソナル編集長（既に持っているツールで作成）で作成
[Twitter　ヘッダー画像の変更方法・サイズ・作り方&便利ツール](https://mag.app-liv.jp/archive/84654/)
・上記よろ画像サイズは1500×500が良いがパーソナル編集長の制限で480×160で作成
ALB+Apache WEBサーバ(EC2)で502 BadGatewayになる問題

# 概要
AWSでSSL化したWEBサーバーを立てたかったので作成したところ、『502 Bad Gateway』が表示されてハマったのでその記録。

結論から言うと、Apacheの再起動でOKでした。
（ただし、これが正解かどうかは不明）

# 環境
AWSにてWEBサーバーの構築。
ドメインをSSL化したかったのでALB-EC2単体の構成にしてます。

- EC2
- ALB
- Route53
- ACM(AWS Certificate Manage)

EC2上ではApacheを動かしてます。

環境の作成は下記サイトを参照して行いました。

[EC2+ACM+ALB+お名前.comで設定をしてサブドメインでhttps接続できるようになるまでひととおり](https://owani.net/aws/ec2-acm-alb/768/)

# エラー現象
AWS側の設定も完了して、ブラウザでアクセスするとApacheの画面になった。
![apache_start.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562723/bd0c35ea-afa5-c1bb-ad82-d8af3fe448e6.png)

よっしゃ！ということで、PHPのソースをアップロードして接続確認してみたところ…

「502 Bad Gateway」

なんでやねん。
確かにALBのログを見ると、ある時点からエラーが上がっている。

![CloudWatchログ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562723/a0a57951-83e6-b6a4-a3e5-dddc4e7767bf.png)

ターゲットグループを確認しても確かにunhealthyになっている。

```
Health checks failed with these codes: [502]
```

下記画像は別のものですが、unhealthyが表示されていて、「説明」の項目に上記のエラーが表示されていたはずです。
（スクショ忘れたので参考として…）
![ターゲットグループ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562723/da2cdebf-5efe-7e4d-5677-ab836c2686f0.png)



ALB側の問題か、WEBサーバ上の問題か、わからずにハマってました。。。

# Apacheのエラーログに出力があった
サーバー上でApacheを動かしてるわけですが、そもそもここまでアクセスがきていないとダメなわけで。
ログ(`/etc/httpd/logs/error_log`)を確認したところ、変なエラーが出てるんです。


```
[core:notice] [pid 3628] AH00052: child pid 3643 exit signal Segmentation fault (11)
```

もちろん、 `/etc/httpd/logs/access_log`の方にはなにも出力されていない。

ということは、ALB→WEBサーバーへはアクセスOK。WEBサーバー→ALBへの返却がNGということ。

#  対応したこと

上記エラーログをググったりしたんですが、有効な解決策は見当たらず。

とりあえずApache再起動するかー

と思ってやってみたところ……アクセスできた！！


Apache再起動コマンド↓↓

```
service httpd restart
```

# まとめ

ターゲットもhealthyになり、HTTPステータスも200が返答されるようになりました。

WEBサーバにロードバランサー（ALB）をつなぎこむとApacheの再起動が必要なのだろうか？

再起動って大事だね。
Laravel アプリのローカルサーバの起動に失敗する

# 目的

- git cloneした直後のLaravelアプリのローカルサーバ起動コマンド(`$ php artisan serve`)の実行に失敗したので原因と解決方法を記載する。

# 実施環境

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.5) |
| ハードウェア | MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) |
| プロセッサ | 2 GHz クアッドコアIntel Core i5 |
| メモリ | 32 GB 3733 MHz LPDDR4 |
| グラフィックス | Intel Iris Plus Graphics 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHP バージョン | 7.4.3 | Homwbrewを用いて導入 |
| Laravel バージョン | 7.0.8 | commposerを用いて導入 |
| MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いて導入 |

# 原因

- composer installコマンドが実行されていない。

# 解決策

- アプリ名ディレクトリで下記コマンドを実行する。

    ```terminal 
    $ composer install
    ```
Git - warning: Pulling without specifying how to reconcile divergent branches is discouraged

`git pull`で警告が表示されたのでそれについて調べた記録

# 事象
`git pull`をすると下記の警告が表示された。

```
warning: Pulling without specifying how to reconcile divergent branches is
discouraged. You can squelch this message by running one of the following
commands sometime before your next pull:

  git config pull.rebase false  # merge (the default strategy)
  git config pull.rebase true   # rebase
  git config pull.ff only       # fast-forward only

You can replace "git config" with "git config --global" to set a default
preference for all repositories. You can also pass --rebase, --no-rebase,
or --ff-only on the command line to override the configured default per
invocation.
```

# 環境
* macOS 10.14.6 (Mojave)
* git version 2.27.0

# 原因
`2.27.0`から警告を表示するようになったらしい。

> "git pull" learned to warn when no pull.rebase configuration exists, and neither --[no-]rebase nor --ff-only is given (which would result a merge).

↓Google翻訳+修正

> "git pull"は、pull.rebase設定が存在せず、--[no-]rebaseも--ff-onlyも指定されていない場合に警告するようになりました（結果はマージになります）。

# 対応
警告文にある通り、configを設定するか、pullオプションを使用する。

# 経緯
> Often novice Git users forget to say "pull --rebase" and end up with an unnecessary merge from upstream. What they usually want is either "pull --rebase" in the simpler cases, or "pull --ff-only" to update the copy of main integration branches, and rebase their work separately. The pull.rebase configuration variable exists to help them in the simpler cases, but there is no mechanism to make these users aware of it.
>
> Issue a warning message when no --[no-]rebase option from the command line and no pull.rebase configuration variable is given. This will inconvenience those who never want to "pull --rebase", who haven't had to do anything special, but the cost of the inconvenience is paid only once per user, which should be a reasonable cost to help a number of new users.

↓Google翻訳+修正

> 多くの場合、初心者のGitユーザーは "pull --rebase"と言うのを忘れて、アップストリームからの不要なマージが発生します。彼らが通常望んでいるのは、より単純なケースでは"pull --rebase"、またはメインの統合ブランチのコピーを更新し、作業を個別にリベースする"pull --ff-only"のいずれかです。 pull.rebase構成変数は、より単純な場合にそれらを支援するために存在しますが、これらのユーザーにそれを認識させるメカニズムはありません。
>
> コマンドラインから--[no-]rebaseオプションがなく、pull.rebase構成変数が指定されていない場合、警告メッセージを発行します。これは、特別なことを何もする必要がなかった、"pull --rebase"をしたくない人には不便ですが、その不便さの代償は1ユーザーにつき1回しか支払われません。これは、多くの新しいユーザーを助けるために妥当なコストでなければなりません。

# 情報ソース
https://github.com/flutter/flutter/issues/54983
https://public-inbox.org/git/20200304022931.2469455-1-alexhenrie24@gmail.com/
https://github.com/git/git/blob/master/Documentation/RelNotes/2.27.0.txt
laravelのルート定義メソッドと各HTTPリクエストの内容について解説

HTTPリクエストに対して定義できるメソッドの基本項目は以下です。

```php
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);
```

## GET

```php
Route::get($uri, $callback);
```

GETリクエストに対してのルーティングを定義します。
主に通常のURL遷移やフォームのGETリクエストに対して用います。
WebブラウザからWebサーバに渡す値をURLの後ろにくっつけて送るやり方
指定したURIの情報を取得する


## POST

```php
Route::post($uri, $callback);
```

POSTリクエストに対してのルーティングを定義します。
主にフォームのPOSTリクエストに対して用いられます。
WebブラウザからWebサーバに渡す値を見えないところにくっつけて送るやり方
リソース名はサーバ側で割り振られる。
以下の用途がある。

1. 子リソースの作成
2. リソースへのデータの追加
3. ほかのメソッドでは対応できない処理


## PUT

```php
Route::put($uri, $callback);
```

putリクエストに対してのルーティングを定義します。
リソース名を指定して行われる

1. 指定したリソースがなかったら新規作成
2. 指定したリソースがあったら置換


## PATCH

```php
Route::patch($uri, $callback);
```


patchリクエストに対してのルーティングを定義します。
リソースを部分変更する
記事のタイトルだけ変更するとか。



## DELETE

```php
Route::delete($uri, $callback);
```

deleteリクエストに対してのルーティングを定義します。
指定したリソースを削除する


## OPTIONS

```php
Route::options($uri, $callback);
```

optionsリクエストに対してのルーティングを定義します。
サーバーが対応しているリクエストメソッドを調べるために使う


## 参考

ファサードについては以下の記事が参考になります。

- [Laravelのファサードが全然わからなかったので自分なりに色々と調べた事 - Qiita](https://qiita.com/yousan/items/18dab4dbac4a27ce3662)

HTTPリクエストについてはこちらがわかりやすい。リクエストに対してレスポンスも踏まえて、解説されている。

- [HTTPメソッド(CRUD)について【保存版】 | クマノロジー.com](https://kumanology.com/notes/197/#HTTP)