OmniAICreator/Qiita-1.07M huggingface dataset:
NetCommons2で共通コンポーネントのコンストラクタで、他の共通コンポーネントがセットできずnull問題に対応

旧会社HPからの転記です。

共通コンポーネントのコンストラクタで、他の共通コンポーネントを参照したけどnullのままで使えない問題を対応しました。

### \webapp\modules\fruit\action\dicon.ini (OKパターン) 
 
```ini
ichigoCommonView = "ichigo.view"
remonCommonView = "remon.view"
remonCommonAction = "remon.action"
```
 
### \webapp\modules\fruit\action\dicon.ini (NGパターン)
 
```ini
remonCommonView = "remon.view"
remonCommonAction = "remon.action"
ichigoCommonView = "ichigo.view"
```
 
### \webapp\components\remon\Action.class.php
 
```php
class Remon_Action {
 var $_db = null;
 var $_container = null;
 var $_request = null;
 var $_remonCommonView = null;
 var $_ichigoCommonView = null;

 /**
 * コンストラクター
 *
 * @accesspublic
 */
 function Remon_Action() {
 $this->_container =& DIContainerFactory::getContainer();
 $this->_db =& $this->_container->getComponent("DbObject");
 $this->_request =& $this->_container->getComponent('Request');
 $this->_remonCommonView =& $this->_container->getComponent('remonCommonView');
 $this->_ichigoCommonView =& $this->_container->getComponent('ichigoCommonView');
 var_dump($this->_ichigoCommonView);

 // var_dump出力　OKパターン：object(Kyomu_View)
 // var_dump出力　NGパターン：null
 }
}
```
 
NGパターンの場合、ichigoCommonViewのクラス生成前に、remonCommonActionのクラス生成が始まるため、nullのままと推察。
 
ichigoCommonViewのメソッドを呼び出そうとしたけど、nullのため、下記エラーが発生した。

```
Fatal error: Call to a member function getXXXX() on a non-object
```

問題解決の参考になれば幸いです。
NetCommons2で既存モジュールをコピーしてカスタマイズ

旧会社HPからの転記です。
リンク先で参照してください。<br><br>

<div style="margin-bottom: 5px;"><strong> <a title="Netcommonsアドオンモジュールセミナー第7回" href="//www.slideshare.net/mitsurumutaguchi/netcommons7-14760717" target="_blank" rel="noopener noreferrer"> Netcommonsアドオンモジュールセミナー第7回 </a> </strong> from <strong> <a href="//www.slideshare.net/mitsurumutaguchi" target="_blank" rel="noopener noreferrer"> Mitsuru Mutaguchi </a> </strong></div>
NetCommons2でmaple.iniのvalidateフィルターにエラーメッセージ時下書き時の注意

旧会社HPからの転記です。

NetCommons2のmaple.iniに記載するvalidateフィルター [ValidateDef] にエラーメッセージを時下書きしていたら、エラーメッセージが正しく表示されない動作をしました。

以下回避策です。

* エラーメッセージにlangを指定する場合は、langを使うように統一する
* エラーメッセージ時下書き時は、時下書きのみで統一する
 
### lang指定統一 - OK
```ini
[ValidateDef]
no.required = "1:lang._required,番号"
name.required = "1:lang._required,名前"
mount.numeric = "1:lang.numeric,金額"
```
#### エラーメッセージ
```
番号を入力してください。
名前を入力してください。
金額は数値を入力してください。
```

### 時下書き - OK
```ini
[ValidateDef]
no.required = "1:番号を入力してください。"
name.required = "1:名前を入力してください。"
mount.numeric = "1:金額は数値を入力してください。"
```

#### エラーメッセージ 
```
番号を入力してください。
名前を入力してください。
金額は数値を入力してください。
```

### 混在 - NG
```ini
[ValidateDef]
no.required = "1:lang._required,番号"
name.required = "1:名前を入力してください。"
mount.numeric = "1:lang.numeric,金額"
```
#### エラーメッセージ
```
番号を入力してください。
名前を入力してください。
名前を入力してください。
```

以上です。
NetCommons2でファイルダウンロード処理を自作した場合の、IEファイル名文字化け対応

旧会社HPからの転記です。

ここが参考になります。

Uploads_Viewコンポーネント _headerOutput() function
https://github.com/netcommons/NetCommons2/blob/develop/html/webapp/components/uploads/View.class.php#L337-L356

以上です。
データーベースとは

##データベース(DB)とは
データを格納する入れ物
検索や蓄積が容易にできるよう整理された情報の集まり
すべてのシステムがデータを取り扱っている。
データを取り扱う手段として、ほぼ全てのシステムが何かしらの、データベースを使用。

##データベースが必要な理由
データがプログラムに依存しない
システム間でデータを共有できる
データを一元管理できる（矛盾がない・整合性）
バックアップが容易
データベースの障害時に、バックアップを利用してデータを復旧できる



##参考記事
データベースの開発をするなら　どのプログラミング
https://programming-gakkou.com/archives/993
シェルでマッチした部分を取り出したい

具体例

mawkの場合

```
ip a s wlo1 | mawk '$0 ~ /^ * inet6 .* scope global dynamic /{print $2}' | mawk 'BEGIN{FS="/"} {print $1}'
alias myipv6='ip a s wlo1 | mawk '\''$0 ~ /inet6 .* scope global dynamic/{print $2}'\'' | mawk '\''BEGIN{FS="/"} {print $1}'\'''
```

基本的に、空白を区切り文字として、それ以外の文字を取り出す。

１、 wlo1インターフェースのネットワーク情報を表示
２、標準入力の各行で、正規表現にマッチしている部分を取り出す。
ipv6のグローバルアドレスにマッチする行を取り出して、その２番めのグローバルアドレス部分を標準出力へ。
空白で区切るので、１番目はinet6。３番めはscopeが入っている。
３、区切り文字に’/’を指定して、アドレスとプレフィクスを、さらに分けて、取り出します。
ipv6でプライバシーを優先されている場合、global dynamicではマッチせず、一時的なアドレスしかない場合もあるかもしれません。


gawkの場合

```
ip a s wlo1 | awk 'match($0,/inet6 (.*)\/[0-9][0-9] scope global/, a){ print a[1]}'
alias myipv6='ip a s wlo1 | awk '\''match($0,/inet6 (.*)\/[0-9][0-9] scope global/, a){ print a[1]}'\'''
```
#### 解説
ipコマンドでアドレスを表示させ、ipv6のglobalなアドレスのみ取り出します。

1. ip address show コマンドでインターフェースwlo1（wifiインターフェース）を表示しています。
上記では省略形を使っています。ip a s \<interface\>

2. gawkを使って、正規表現で、アドレス部分にマッチする部分のみを取り出します。
matchで、標準入力$0、この場合は、ip a s wlo1 の結果を受けとり、マッチ結果をaに代入します。
一致した部分の中でも、括弧でくくられた部分を取り出すことができます。
今回は括弧でくくった部分が一つなので、1番目ということで、 a[1] をprintして、表示しています。
マッチしたn番目の要素を取り出したい、といった時に使えます。

#### 補足
正規表現の
/inet6 (.*)\/[0-9][0-9] scope global/ 
は、ipv6でglobalアドレスを示す行を取り出すために指定した正規表現です。

私の環境ではprefixが64ですので、
/inet6 (.*)\/64 scope global/
でも問題ありません。2桁の数字を想定しています。

aliasに指定する場合の書式は、クォーテーションがちょっとわかりにくいかもしれません。
NetCommons2で開発中はsmartyのコンパイルを自動にする

旧会社HPからの転記です。

忘れるのでメモ。
NetCommons2で使っているテンプレートエンジン smarty。
smartyは一度、phpに変換をするコンパイルが必要。

通常は、モジュール管理からモジュールをアップデートすると、
対象モジュールのsmartyがコンパイルされる。

開発中は、smartyテンプレートを変えたら、すぐに画面に反映して欲しいので、自動コンパイルさせたい。
NetCommons2だと、下記パラメータにすればOK

```php5:\html\webapp\config\maple.inc.php
define('SMARTY_FORCE_COMPILE',     true);
```

maple.inc.php - github
https://github.com/netcommons/NetCommons2/blob/e89bfb7c3e9253c07c34ac16999b44428473b51e/html/webapp/config/maple.inc.php#L55

本番リリース時は、パフォーマンスが落ちるので、**false** を推奨。
「user :id 」と「 user.id 」の違い

#はじめに

Rubyの学習中よく「 :~ 」と「 .~ 」の使い方の違いで混乱していたので、

今回 「 :id 」と「 .id 」を例にまとめていきたいと思います。


##「 :~ 」
__「 :~ 」__はparamsの__キー__を指しており、
そのキーの値(バリュー)を格納するために記述する。

また、「 :~ 」はDBのカラムと__一致させる__ハッシュのキー(一致するとDBに保存可)で、
これはビューファイルでハッシュのキーを指定する



###例1）コントローラーで「 :~ 」を記述する場合

```ruby
def show
    @post = Post.find(params[:id])
end
```
↑
__[ :id ]__は__params = { :id => “バリュー”}__の:__id(キー)__の部分を指している。

__params[:id]__は__「id」__という__キー__の、値を格納するための記述！




###例2）ビューファイルで「 :~ 」を記述する場合

```html.erb
<%= f.text_area :first_name_kana, class: "input-name", id: "first-name-kana", placeholder: "例)サトウ " %>
```

↑
__「:first_name_kana」__はハッシュの__キー__を指しており、ここに「 f.text_area」によって入力されたデータ(バリュー)が入る！

params = { :first_name_kana => 入力されたデータ}
　　　　　　　　キー　　　　　　　バリュー




###例3)DBに値が保存される仕組み

レコード {text :  ”こんにちは”} があると仮定

```
params[:text]
```
DBのカラムにおいて　

textカラムが__ある場合__ 　"こんにちは"を__保存可能__ 
textカラムがない場合 　　　　　保存できない


※viewファイルからparams(キー: バリュー)は送られてくる。



##「.~ 」
__「 . 」__はほぼ全てメソッド


###例)

```
user.id
```

user.idは__「userオブジェクトのidメソッドの呼び出し」__です。




###スクエアブラケット

・__[ ]__のこと

#おわりに

ちなみに「 :id 」と「 .id 」と混合しやすい__「 _id 」__は外部キーだそうです。

今後はparamsについての理解をもっと深めていきたいです。
【ColdFusion】セッションの破棄

こちらの記事が参考になりました。
[SessionInvalidate for JEE Sessions](https://www.petefreitag.com/item/913.cfm)

ColdFusionセッションを破棄するには sessionInvalidate() を使えばよいですが、J2EEセッションを利用している場合にはこれで破棄できません。

以下の書き方で、ColdFusionセッションとJ2EEセッションの両環境に対応できます。

```cfscript
if (!isNull(getPageContext().getSession())) {
    getPageContext().getSession().invalidate();
} else {
    sessionInvalidate();
}
```
NetCommons2のファイルアップロード時にでてくるダイアログについて

旧会社HPからの転記です。

ファイルアップロード時に、アップロード処理の時間が長いと<br />「アップロードが失敗したか、タイムアウトになった可能性があります。処理を続行しますか?」<br />
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109904/2e18f260-7db8-1540-8096-4673c5e385ed.png)
<br />とダイアログが出る事がありますが、<br />カスタマイズ時に非表示にできないか調べました。<br /><br /><a href="https://github.com/netcommons/NetCommons2/blob/537e08b7a2892bacd2eed5dbac3ea45792de0f36/html/webapp/modules/common/files/js/common.js#L2451" target="_blank" rel="noopener noreferrer">https://github.com/netcommons/NetCommons2/blob/537e08b7a2892bacd2eed5dbac3ea45792de0f36/html/webapp/modules/common/files/js/common.js#L2451</a><br />

```js:webapp/modules/common/files/js/common.js
/*timeout_flag:0の場合、タイムアウトチェックをしない     */
/*********************************************************/
sendAttachment: function(params_obj) {
```
上記パラメータをセットすれば、できる。

<h2>サンプルJS</h2>
```js
    /**
     * ファイルアップロード
     */
    uploadFile: function() {

        var messageBody = new Object();
        messageBody["action"] = "custummodule_action_main_import";

        var option = new Object();
        option["param"] = messageBody;
        option["top_el"] = $(this.id);
        option["timeout_flag"] = 0;            // タイムアウトチェックをしない
        option["callbackfunc"] = function(response) {
            commonCls.alert("インポートしました。");
            commonCls.sendRefresh(this.id);
        }.bind(this);
        option["callbackfunc_error"] = function(file_list, res){
            commonCls.alert(res);
        }.bind(this);
        commonCls.sendAttachment(option);
    },
```

ではでは。
CentOS7 /PostgreSQL10 に ODBC接続をした話

Windows10 Proの端末に仮想サーバー(CentOS7)を立てて、Postgres10をインストールし、Windows側のMicrosoft AccessとODBC接続でリンクテーブルができる検証環境を作ることがあったのですが、初見のことばかりでしたので、備忘として書き残しておきます。

#筆者のスペック
CentOS　「はじめまして。Unixさんのご親戚なんですね…。まぁ、お奇麗なUIで…。」
PostgreSQL　「はじめまして。フリーでSQLサーバーをされているなんて、ご立派なんですねぇ…。」
ODBC　「生きとったんか！ワレ！！10何年ぶりかのぅ…。元気してたか？」


#設定作業
各設定については、以下の記事を主に参照しました。

*  [Hyper-Vの仮想マシン新規作成手順](https://qiita.com/bitterrich/items/7003a3b2e09e38b656c0)
*  [Hyper-Vの仮想マシンにCentOS7をインストール](https://www.giblock.jp/labo/hyperv_centos.html)
*  [CentOSへのPostgreSQLのインストールと初期設定](https://qiita.com/9ryuuuuu/items/9bc80396cbd6b4b2fc95)
*  [PostgreSQL 10 を CentOS 7 に yum インストールする手順](https://weblabo.oscasierra.net/postgresql10-centos7-install/)

CentOS/Postgresの記事は少なくないのですが、バージョンによってディレクトリ構成が異なったり、コマンドが使用できなくなっていたりで、情報を見つけても即時に使えないこともあって、そのあたりが不便でした。

また、Hyper-Vはリモートデスクトップのようにホスト⇔ゲストでクリップボード貼り付けやファイル交換ができないため、CentOSを起動した後の作業はTeraTermで行いました。（PostgreSQLの設定文書を修正するときは、CentOSのメモ帳で行うほうが快適でしたので、Hyper-V経由で作業しました。）

#ODBC接続
環境構築後にODBC接続をしましたが、接続はできませんでした。

ODBCのエラーログを見ても、接続が切られました…と英語で書いているだけで役に立たなくて困っていたのですが、[Windowsでポートが開いているか確認する](https://qiita.com/takao-takass/items/09574d6ccc13d7b43a5f)の記事から、PowerShellのTest-NetConnectionコマンドを利用して、CentOSのポート状況を確認して、PostgreSQLで使用しているポートが閉じた状態であることを確認。CentOS側の問題で接続できないことが切り分けできて、ポートの開放を行いました。

ポートを解除した後も、IPアドレスが正しくない、ident認証が行われていない…などのエラーが続き、そのたびに原因を調査したのですが…。結論から言えば、PostgreSQLの設定文書（postgresql.conf/pg_hba.conf）をカスタマイズしていなかったことが原因でした。接続ができるようになってから見返すと、[CentOS7にPostgreSQLを構築する方法](https://qiita.com/m-eno/items/4a4f8f6f0b2d38709641) の設定どおりにしておけば、大丈夫なはずです。

私の場合は、pg_hba.confで赤枠の部分（ident）を修正することに気付かないで時間がかかりました。
![memo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/983034/697d346f-1b42-1fe8-a739-92c88795e5af.png)
ident認証をするためにはIdentサーバーを設置しておかないといけないですが、検証環境に設置していません。そのため、認証サーバーを必要としない md5 に変更したら、接続できるようになりました。

#リンクテーブルが作成できない！　（うっかりミス）
ODBC接続が完了して、やっとリンクテーブルを作成できる…と思ったら、リンクテーブルに何も表示されません。
そうです。createdbでデータベースを作っただけで、テーブルもデータも作成していなかったからです。PostgreSQLにデータを作成したら、普通にリンクテーブルが作成できるようになりました。
NetCommons2 使用しているテンプレート名をphpで取得する

旧会社HPからの転記です。

php側でテンプレート名を使ってプラグラムの動きを変えたかったので、<br />やり方を調査しました。<br /><br />下記PHPで実現できます。
componentsの場合

```php5
$container =& DIContainerFactory::getContainer();
$block =& $container->getComponent("blocksView");
$block_id = intval($request->getParameter("block_id"));
$block_obj = $block->getBlockById($block_id);

// $block_obj['temp_name'];    //←テンプレート名が取得できる
```
<p>(2018/09/28追記)</p>
<p>view・actionの場合</p>
<p>PHP</p>
```php5
 var $block_id = null;
 var $blocksView = null;

 function execute()
 {
     $block_obj = $this->blocksView->getBlockById($this->block_id);
     $block_obj['temp_name']; //←テンプレート名が取得できる
 }
```
<p>maple.ini</p>
```ini
[Action]
blocksView = "ref:blocksView"
```
参考になれば幸いです。
ではでは。
【Cloud9】Ruby on Railsでrails sしたときにBlocked hostが表示された時の対処法

## 環境
- Ruby on Rails6.×
- Cloud9

## エラー概要

以下のコマンドを実行した際に、`Blocked host`と表示され、Railsのデフォルトページが表示されない場合があります。

```bash
rails server
```
<img width="555" alt="" src="https://i.gyazo.com/b9c2436ef6730636293e098ffb852e1a.png">

## 結論
`config/environments/development.rb`を以下のように修正してください。

```ruby:config/environments/development.rb
Rails.application.configure do
  config.hosts << "<許可したいホスト名>"
  
  #=====中略=====
  
end
```

`<許可したい表示名>`には、「Blocked host:」のあとに表示されている「～.vfs.cloud9.us-east-2.amazonaws.com」で終わる文字列を入力してください。

## 動作確認
再度アプリケーションを起動します。

```bash
rails server
```
<img width="555" alt="" src="https://i.gyazo.com/9dc28f9247f4c5944c451bf1079f0d84.png">

上記のような画面が表示されたら、右上の「Pop Out New Windows」をクリックして下さい。

以下のようにRailsのデフォルトページが表示されます。

<img width="555" alt="" src="https://i.gyazo.com/3fe94b844867fd126607f7513ec6648a.png">

※本記事は[Techpit](https://www.techpit.jp/)の記事を一部修正したものです。
NetCommons2のPHPMailerを最新版に差し替える

旧会社HPからの転記です。

<p>最新版(2016/12/28時点) PHPMailer 5.2.19(70d041b6f5ed4e2ed8e2330b8c5b0f6926fc9781).zip に差し替えてメール飛びました。<br />すべての動作確認をしたわけではないので、参考程度の情報です。</p>
<h2>PHPMailer最新版に差し替える</h2>

* PHPMailerの最新版をGithubからzipをダウンロードする
<ul>
<li><a href="https://github.com/PHPMailer/PHPMailer/releases" target="_blank" rel="noopener noreferrer">https://github.com/PHPMailer/PHPMailer/releases</a></li>
</ul>
</li>
<li>ダウンロードしたzipを解凍して以下を変更する</li>
<li>class.phpmailer.phpに1行追加
<ul>
<li>require_once("PHPMailerAutoload.php");</li>
</ul>
</li>
</ul>
<h2>確認動作</h2>
<ul>
<li>掲示板に投稿してメールが飛びました</li>
<li>システム管理画面から、会員登録後にメールが飛びました</li>
</ul>
<h2>確認環境</h2>
<ul>
<li>NC2.4.2.1</li>
<li>XAMPP</li>
<li>PHP 5.6.12 (VC11 X86 32bit thread safe)</li>
<li>PHPMailer 5.2.19(70d041b6f5ed4e2ed8e2330b8c5b0f6926fc9781)</li>
</ul>
<h2>NC2.4.2.1の状態</h2>
<ul>
<li>NC2のメール送信は、PHPMailer</li>
<li>バージョン : Version: 2.0.0 rc3 　※ [<a href="https://github.com/netcommons/NetCommons2/blob/develop/html/maple/includes/mail/phpmailer/class.phpmailer.php#L5" target="_blank" rel="noopener noreferrer">class.phpmailer.php</a>]参照</li>
<li>NCに影響あり</li>
<li>パス : <a style="background-color: #ffffff;" href="https://github.com/netcommons/NetCommons2/tree/develop/html/maple/includes/mail/phpmailer" target="_blank" rel="noopener noreferrer">\html\maple\includes\mail\phpmailer</a></li>
</ul>
<h2>参考</h2>
<p><a href="https://github.com/netcommons/NetCommons2/issues/134" target="_blank" rel="noopener noreferrer">https://github.com/netcommons/NetCommons2/issues/134</a></p>
<p>以上です。</p>
AWSのEC2でwebサイトを公開するまで


#1. VPC構築

参考サイト
https://qiita.com/nago3/items/f5badeb4f7e5c32b0540

#2. RDS構築

参考サイト
https://qiita.com/nago3/items/1cd6daa5ad6377e325ed
#####補足
 - データベースの設定でDBの名前を設定していますが、設定項目がない場合は設定しなくて大丈夫です。

#3. １・２が完了したらSSHでEC2のインスタンスに接続する

### ・ターミナルでインスタンスに接続して下記の作業を実行
- OSのアップデート

```
sudo yum update
```

- phpのインストール
（参考サイト：https://qiita.com/miriwo/items/7d94303e7185e4118f52 ）

- Apacheのインストール

```
sudo yum install httpd
```

- phpMyAdminのインストール
 （参考サイト：https://qiita.com/s_Pure/items/2bf5bafffdbb6f20422a ）

- MySQLのインストール

```
sudo yum -y install mysql

MySQLに接続
[ec2-user@ip-xx-x-x-xx ~]$ mysql -h <エンドポイント> -P 3306 -u <ユーザー名> -p
Enter password: -> <パスワード>
```

- githubのインストール
 （参考サイト：https://qiita.com/miriwo/items/8d5b35950232c1126d36 ）

```
sudo yum install git
```

### ・デフォルト設定だとec2-userでは/var以下にアクセスできないのでec2-userに対象ディレクトリの書き込み権限を与えてあげる。

```
# ec2-userでssh接続
sudo su - #root昇格
chmod -R 755 /var/www/html #フォルダのアクセス権限を変更
chown -R ec2-user /var/www/html #一応オーナーも変更
```

### ・パブリック IPv4 アドレス（もしくはElastic IP）をブラウザに入力してApacheのTestPageが表示されるか確認
うまくいかなかったら下記をチェック
https://ti-tomo-knowledge.hatenablog.com/entry/2018/05/26/202413

#4. ドメインの設定

```
Elastic IPでグローバルIPを固定
↓
ドメインの取得(今回はFreenomを利用)
↓
Route 53でDNSの設定
↓
FreenomでNS（ネームサーバー）を設定
↓
DNSの設定確認
↓
取得したドメインでブラウザに表示されるかを確認
(/var/www/html/にindex.htmlが無いとエラーになるので何かファイルを置く。)
```

参考サイト
https://avinton.com/academy/route53-dns-vhost/
https://qiita.com/yuichi1992_west/items/e842d8ee50c4afd88775

# 5. https化
参考サイト
https://dev.classmethod.jp/articles/aws-web-server-https-for-beginner/

#####※ 「ターゲットグループ」の「ターゲット」のタブのステータスが「healthy」にならない場合は/var/www/html/にindex.htmlが無い可能性があるので要チェック。
#####※「ロードバランサーのDNS名をDNSに追加する」の項目が、説明されている方法でできなかったので補足。
 
```
Route53へアクセス
↓
ホストゾーン
↓
ドメイン名を選択
↓
レコードを作成
↓
レコード名は空白
※ここに名前をつけるとhttps化できても安全性の警告が出ます。
例）
ドメイン名：hoge.com
レコード名：blog.hoge.com
証明書は「https://hoge.com」で照会されるので、レコード名を変更してしまうと、
「https://blog.hoge.com」からのアクセスと認識し、「なりすましかもしれない」という判断で警告画面を表示してしまいます。
↓
エイリアスをON
↓
Application Load BalancerとClassic〜を選択
↓
リージョンは設定したリージョンを選択（us-east-2など）
↓
「ロードバランサーを選択」でロードバランサーの説明にあるDNSを選択できるはず
↓
レコードを作成
（レコードを作成する時に既に存在するという警告が出た場合は他のAレコードの「レコード名」を変更もしくは削除してください）
```
![スクリーンショット 2021-01-29 2.51.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1061654/6f5d4dde-a7bf-f1d8-bf3c-a384b86e739a.png)

#####httpsでアクセスできたら完了。
https://<あなたのドメイン>
Gravio 4で温度をLINEに通知してみる

[前回][Prev]は[Gravio]でSlack通知しましたが、個人で使うにはやっぱりLINEですよね。
Gravio 4でもLINENotifyコンポーネントがありますので試してみます。

# 使用環境

* Windows 10 20H2 (19042.746)
* Gravio HubKit v4.1.4049.0
* Gravio Studio v4.1.5432.0

# 事前準備
以前、[「おうちハック Vol.1 郵便が届いたのをLINEに通知してみた」][Gravio-LINE]で[LINE Notify][LINENotify]でトークンを取る方法を紹介してますので、準備しておいてください。

# 手順
## LINE Notifyコンポーネントを配置
新しくアクションを作成し、 **LINE Notify**コンポーネントを配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/39b6bc46-6538-5087-7519-e2d384ff5866.png)
メッセージには[Slackで投稿したときと同様][Prev]に、Pre Mappingsで `cp.Message`に`"現在の温度は" + tv.Data + "℃です"`と設定しておきましょう。
注意するのは、`cp.Text`ではなく`cp.Message`である点です。LINE Notifyではメッセージプロパティは`cp.Message`なので気をつけてください。

| プロパティ | 値 | 例 |
|:-----------|:------------|:---|
|メッセージ  |投稿したいメッセージ|Pre Mappingsで`cp.Message`に`"現在の温度は" + tv.Data + "℃です"`を設定|
|トークン   |LINE Notifyで取得したトークン||

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/2a9742d0-87ae-62da-f4eb-9a7fa8ecc4dc.png)

## 実行

実行してみます。このようにLINE Notifyのアイコンで投稿されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/f7757e23-c159-43c6-6f73-bef60abd817b.png)

## 
[Slackのときと同じ][Prev]ように、トリガーを設定して温度を通知してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/e7a0a291-f8e1-92bb-59fc-f6778dd36127.png)


# ポイント
* LINEに通知するには、[LINE Notify][LINENotify]サービスを使って、**LINE Notify**コンポーネントで通知する
* メッセージを合成するにはPre Mappingsを使って`cp.Message`に渡す。Slackとはプロパティ名が違うので注意
* センサーからの温度を埋め込むには`tv.Data`を使う

# 参考
* [Gravio][]
* [LINE Notify Component](https://doc.gravio.com/manuals/gravio4/1/ja/topic/line-notify-action-component)
* [アクション内で利用できる変数と変数型](https://doc.gravio.com/manuals/gravio4/1/ja/topic/available-variables-in-action)
* [アクション内でObject型の変数の値を参照する方法
](https://doc.gravio.com/manuals/gravio4/1/ja/topic/read-variables-in-action)
* [Pre Mappings / Post Mappingsでの式の記述の仕方](https://doc.gravio.com/manuals/gravio4/1/ja/topic/premappings-postmappings)
* [Pre Mappings / Post Mappingsの式の中で利用できる関数](https://doc.gravio.com/manuals/gravio4/1/ja/topic/pre-mappings-post-mappings)
* [LINE Notify][LINENotify]

[Prev]:https://qiita.com/zrock/items/0b0b74e9985fadf2502c
[Gravio-LINE]:https://qiita.com/zrock/items/fc397dcc34edb4bcff4a
[Gravio]:https://www.gravio.com/jp
[LINENotify]:https://notify-bot.line.me/ja/
Raspberry Pi 4でお手軽に高性能な顔認識をしたい

# はじめに
Pythonでお手軽に高性能な顔認識ができる[face_recognition](https://github.com/ageitgey/face_recognition)というライブラリがあります．画像や動画内の顔を認識するだけではなく，顔のランドマーク（目，鼻，口など）の認識や人物の識別などが数行のプログラムでできるようになっています．しかも様々なハードウェアやOSに対応しているようです．

もちろんWindowsにも対応しており，以前私のメインPC（Windows10）でセットアップしようとしてみたのですが，どうしてもうまく行かず諦めてしまいました．ちなみにそのときはface_recognitionの代わりに[mtcnn](https://github.com/ipazc/mtcnn)というライブラリを使いました．

今回はまた改めてface_recognitionを使ってみたくなったので，Raspberry Pi 4でセットアップしてみました．

# 環境
- Raspberry Pi 4 ModelB 4GB
- Raspbian Buster
- Python 3.7.3

# セットアップ
## dlibインストール
まず`dlib`というライブラリをインストールする必要があるようです．

この動画を参考にインストールしました．
[How to install dlib on Raspberry Pi 4 or Linux](https://www.youtube.com/watch?v=_foXmeFnrU8)

まずパッケージを更新します．

```
sudo apt update && sudo apt upgrade
```

`dlib`のインストールに必要なパッケージをインストールします．

```
sudo apt install build-essential cmake pkg-config
```

次に[dlib.net](http://dlib.net/)に行き，左下の"Download dlib"と書いてある青いボタンからdlibをダウンロードします．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320225/2d589634-e6ba-a384-14ef-4cb7c3289ef2.png)

`dlib-19.21.tar.bz2`という名前のファイルがダウンロードされるので，エクスプローラから展開します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320225/9d73b8be-1e8d-6a91-b710-f620e95d17b0.png)

すると`dlib-19.21`というフォルダができます．中身は画像のようになっています．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320225/3e156466-0fab-92a7-0a62-28d0fbae7792.png)

次にターミナルからこのフォルダに移動し，`dlib`のビルド・インストールを行います．

まずビルドします．10~20分くらいかかります．
Python3で実行するように注意します．

```bash
sudo python3 setup.py build
```

インストールします．これも10~20分くらいかかります．

```bash
sudo python3 setup.py build`
```

以上でインストールが完了しているはずです．Pythonから簡単に確認してみます．
`dlib`をインポートしてみて特にエラーが出なければ大丈夫です．

```
$ python3
Python 3.7.3 (default, Jul 25 2020, 13:03:44) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import dlib
>>> dlib.__version__
'19.21.0'
```

## face_recognitionのインストール
`pip`でインストールするだけです．

```
pip3 install face_recognition
```

# 使ってみる
簡単な顔認識プログラムを書いてみました．

```script.py
import face_recognition
from PIL import Image, ImageDraw

image = face_recognition.load_image_file("image.jpeg")

face_locations = face_recognition.face_locations(image)
print(f"{len(face_locations)} faces detected.")

pil_image = Image.fromarray(image)
draw = ImageDraw.Draw(pil_image)

for loc in face_locations:
    top, right, bottom, left = loc
    draw.rectangle((left, top, right, bottom), width=8)
    
pil_image.save("./output.jpg")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320225/229b2336-4611-8e65-922d-742287de437f.png)

すごくお手軽です．
ただ処理に結構時間がかかります．測定してみたらみたら17秒でした．人数が多いせいもあるかもしれません．

```bash
$ time python3 ./script.py
9 faces detected.

real	0m17.715s
user	0m15.845s
sys	0m1.625s
```

face_recognitionの使い方についてはGitHubを見てください．
[face_recognition](https://github.com/ageitgey/face_recognition)

近いうちにカメラモジュールで顔認識を試してみたいです．
NetCommons2 loggerでデバッグログをファイル出力する

旧会社HPからの転記です。

<p>NetCommons2 にはloggerの仕組みがありますが、初期状態は画面出力のため、ファイル出力されず、インストール時の確認やデバッグ時には不便な場合があります。</p>
<p>そこでloggerの出力をファイル出力に変更する方法を記載します。</p>
<h1>1. <a href="https://github.com/netcommons/NetCommons2/blob/develop/html/webapp/config/global-config.ini#L22" target="_blank" rel="noopener noreferrer">html\webapp\config\global-config.ini</a> を変更</h1>
```
;;DEFAULT_LOGGER = viewDisplayManage
DEFAULT_LOGGER = simpleFile
```
<h1>2. <a href="https://github.com/netcommons/NetCommons2/blob/develop/html/webapp/config/define.inc.php#L259" target="_blank" rel="noopener noreferrer">html\webapp\config\define.inc.php</a> の末尾に追記</h1>
<pre>define('LOG_LEVEL', LEVEL_ERROR);</pre>
<p>すると、下記ディレクトリにログが出力されます。</p>
<h2><a href="https://github.com/netcommons/NetCommons2/tree/develop/html/webapp/logs" target="_blank" rel="noopener noreferrer">html\webapp\logs\</a>maple.log</h2>
```
[2019/06/02 02:23:57] [error] 存在しないコンポーネントが指定されました : dicon://Session - DIContainerInitializer#doValueBeforeParse
[2019/06/02 02:24:53] [error] 存在しないコンポーネントが指定されました : dicon://Session - DIContainerInitializer#doValueBeforeParse
[2019/06/02 02:24:55] [error] 存在しないコンポーネントが指定されました : dicon://Session - DIContainerInitializer#doValueBeforeParse
```
参考になれば幸いです。
<h1>参考リンク</h1>
<a href="http://allcreator.net/jo0c73c3b-294/?block_id=294&amp;active_action=journal_view_main_detail&amp;post_id=154&amp;comment_flag=1" target="_blank" rel="noopener noreferrer">http://allcreator.net/jo0c73c3b-294/?block_id=294&amp;active_action=journal_view_main_detail&amp;post_id=154&amp;comment_flag=1</a>
<a href="https://nc2.netcommons.org/bbjx36jrx-6666/#_6666" target="_blank" rel="noopener noreferrer">https://nc2.netcommons.org/bbjx36jrx-6666/#_6666</a>
<p>&nbsp;</p>
Pythonで大量の画像をPowerPointに綺麗に貼り付ける

## はじめに
弊社で使用している業務アプリにて、機器の計測値や分析結果をダッシュボード形式で表示する機能があるのですが、ある測定範囲での結果をまとめてほしいとの要望が来ました。
しかし**貼り付ける画像の量が膨大で(数百枚ある)**、手作業でひとつひとつ位置やサイズを揃えようにもめっちゃ大変だったので自動化することにしました。

## 完成予想図
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289210/e02f4961-440e-f6c9-e31a-9e9a26ef9ea0.png" width=300px>

こんな感じ。

## python-pptxライブラリ
pythonでPowerPointファイルを操作できるライブラリで`pptx`というものがあるらしく、さっそくインストール

```
pip install python-pptx
```

`pip install pptx`ではありませんのでご注意を。

## 基本的な使い方
[公式リファレンスの"Getting Started"のページ](https://python-pptx.readthedocs.io/en/latest/user/quickstart.html)を見ながら、サンプルコードを改造する形でコーディングしていきます。

記載のあるサンプルは以下の通り。

* `Hello World! example`
  * 最もシンプルで基本的なpptxの使い方
* `Bullet slide example`
  * 箇条書きの入れ子になっているサンプル。テキストのみ
* `add_textbox() example`
  * テキストボックスを追加したい時のサンプル
* `add_picture() example`
  * 画像を追加したい時のサンプル
  * 今回は主に**このサンプルを参考に**しました
* `add_shape() example`
  * 基本図形を追加したい時のサンプル
* `add_table() example`
  * 表を追加したい時のサンプル
* `Extract all text from slides in presentation`
  * スライド内のテキストを全て抽出する

## 使ってみる
公式のサンプルコードを参考に、以下のようなコードを記述

```python:makeSlide.py
from pptx import Presentation
from pptx.util import Inches


prs = Presentation()

# スライドサイズをA4に指定
prs.slide_height = Inches(11.69)
prs.slide_width = Inches(8.27)

# 白紙スライドを追加
blank_slide_layout = prs.slide_layouts[6]
slide = prs.slides.add_slide(blank_slide_layout)

# 見出し
text_width = Inches(4)
text_height = Inches(0.5)
txBox = slide.shapes.add_textbox(
    left=Inches(0.5),
    top=Inches(0.3),
    width=text_width, height=text_height
)
txFrame = txBox.text_frame
txFrame.text = "見出し"

# ヘッダ画像
header_path = "./images/header.png"
slide.shapes.add_picture(
    header_path,
    left=Inches(3.5), top=Inches(1),
    width=Inches(3.5), height=Inches(2.5)
)

# 画像1-6
image_width = Inches(3.3)
image_height = Inches(2.3)
images_top = Inches(4)  # 画像群,上部の座標

for index in range(6):
    image_path = f"images/image_{str(index+1).zfill(2)}.png"
    # 中央寄せで描画
    slide.shapes.add_picture(
        image_path,
        left=(prs.slide_width/2)-image_width+(index%2)*image_width,
        top=images_top+int(index/2)*image_height,
        width=image_width, height=image_height
    )

prs.save('output.pptx')
```

ディレクトリ構成はこんな感じ

```
│  makeSlide.py
└─images
        header.png
        image_01.png
        image_02.png
        image_03.png
        image_04.png
        image_05.png
        image_06.png
```

## 実行結果
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289210/537feb39-579b-1689-b270-f8929b553301.jpeg" width=600px>


ちゃんとPowerPointスライドが生成されました。
1枚できれば、残りの作業はほぼ同じなので簡単に実装できそうです。

また、このPowerPointファイルを開いた状態で書き込み（プログラム実行）しようとすると、`Permission Error`となるのでご注意ください。

## 参考・リンク
[公式リファレンス](https://python-pptx.readthedocs.io/en/latest/index.html)
+819070091448 からのSMS

# 09070091448 からのSMS一覧
？？？のSMS送信サービスを利用しているため
この番号からのSMSには複数の業者が並ぶことがある
非常に紛らわしいので一覧を作成することにしたが
自分の使ってるサービスには限界があるので**コメントをいただければアップデート**します(多分)
ご協力お願いします

## +81 90 7009 1448、09070091448 からのSMS一覧

| 利用業者 | 通知内容 |
|:-:|:-:|
| Amazon | ログイン通知(確認URL含む) |
| Netflix | 確認コード |
| Clubhouse | 確認コード |
| ConoHa | 確認コード |
| Tiktok | 確認コード |
| Wirex | 確認コード |
| WeChat | 確認コード |
|  |  |
PHPで素数判定

何かで素数判定がどうちゃらこうちゃらみたいな記事を読んだので、自分も作ってみようと思ってパパッと`1〜100`までの素数判定プログラム書いてみました。

#素数とは
そもそも素数とは*`1とその数自身以外に約数がない正の整数`*らしいです。
`1`と`その数自身`でしか割り切れないということで約数を`2つ`しか持ちません。
この性質を使ってプログラムを組んでいこうと思います。

#コード
まずは大まかな流れです。

```
for ($i = 1; $i <= 100; $i++) {
  if ($iが素数なら) {
    echo $i
  }
}
```
次に、`$i`が素数かどうかを判別する方法ですが
ここで約数を2つしか持たない性質を使います。

```
for ($i = 1; $i <= 100; $i++) {

  $point = 0;

  for ($j = 1; $j <= $i; $j++) {
    if ($i % $j == 0) {
      $point += 1;
    }
  }

  if ($point == 2) {
    echo $i . "\n";
  }

}
```
`$i`が`$j`で割り切れる度に`$point`に1を加算していくので、 `$i`が素数であるなら`$point`の値は`2`になります。出力結果は以下です。

```
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
59
61
67
71
73
79
83
89
97
```

#まとめ
調べてみたら素数を判定するのにも色々な方法があるんですね。今はあまり気が乗らないので時間ある時にでも見てみようと思います。
library not found for -lSystem

#library not found for -lSystem
MacOS Big Sur 11.1にアップデートをした。
g++でコンパイルすると以下のエラーが発生した。(この時VScode上では、bits/stdc++.hのincludeエラーが出ていた)

```
ld: library not found for -lSystem
collect2: error: ld returned 1 exit status
```

#解決法

```
brew upgrade gcc
```
再インストールでも大丈夫っぽい。
ちなみに[このサイト](https://stackoverflow.com/questions/56156520/gfortran-error-ld-library-not-found-for-lsystem-when-trying-to-compile)に載っていた以下の方法を先に試したが何も起きなかった。

```
export LIBRARY_PATH="$LIBRARY_PATH:/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib"
```

※追記
Bis Sur 11.2にアップデートしたら、普通にincludeエラーがまた発生したので、[ここ](https://teratail.com/questions/286637)を参照して以下のコードを実行したら治った。

```
sudo rm -r /Library/Developer/CommandLineTools
xcode-select --install
```
vagrant up時のエラー対応方法

# 結論
エラーの修正提案内容に沿って対応(`vagrant plugin repair`など)したがだめだった。
`vagrant plugin update`したら、すぐ修正できた。

# 経緯

vagrantをバージョンアップ。
その後、`vagrant up`しようとするとエラーが発生。

```shell

Vagrant failed to initialize at a very early stage:

The plugins failed to initialize correctly. This may be due to manual
modifications made within the Vagrant home directory. Vagrant can
attempt to automatically correct this issue by running:

  vagrant plugin repair

If Vagrant was recently updated, this error may be due to incompatible
versions of dependencies. To fix this problem please remove and re-install
all plugins. Vagrant can attempt to do this automatically by running:

  vagrant plugin expunge --reinstall

Or you may want to try updating the installed plugins to their latest
versions:

  vagrant plugin update

Error message given during initialization: Unable to resolve dependency: user requested 'vagrant-bindfs (= 1.1.4)'
```

エラーに沿って、
`$ vagrant plugin repair`
`$ vagrant plugin expunge --reinstall`
`$ vagrant plugin update`
を実行するが、以下エラー

```shell

$ vagrant plugin expunge --reinstall

This command permanently deletes all currently installed user plugins. It
should only be used when a repair command is unable to properly fix the
system.

Continue? [N]: y

All user installed plugins have been removed from this Vagrant environment!

Vagrant will now attempt to reinstall user plugins that were removed.
Installing the 'vagrant-bindfs' plugin. This can take a few minutes...
Fetching (※省略※)
Fetching vagrant-hostsupdater-1.2.1.gem
Fetching (※省略※)
 (※省略※).....

Vagrant failed to properly resolve required dependencies. These
errors can commonly be caused by misconfigured plugin installations
or transient network issues. The reported error is:

Unable to resolve dependency: user requested 'vagrant-hostsupdater (= 1.1.1.160)'

```

`Unable to resolve dependency: user requested 'vagrant-hostsupdater (= 1.1.1.160)'`
ここで引っかかっているラシイ。

`Fetching vagrant-hostsupdater-1.2.1.gem`だが、
 user requestedは `'vagrant-hostsupdater (= 1.1.1.160)'`ラシイ。

で、
`vagrant plugin update`
したら、

```shell
$ vagrant plugin update
Updating installed plugins...
Updated 'vagrant-hostsupdater' to version '1.2.1'!
```

この後、`vagrant up`したら、無事に起動できました。
typeORMでセキュアなカラムをselectさせない

typeORMで、パスワード等のカラムを扱う時にうっかりapiのレスポンスに値を含め無い様にする仕組みが用意されています。


# 何もしない場合

```typescript
@Entity()
export class User {
  @PrimaryGeneratedColumn()
  readonly id: number;

  @Column({
    name: 'name',
    length: 255,
  })
  name: string;

  @Column('varchar', { name: 'password'})
  password: string;
}
```

selectすると全カラムが普通に取得されます。うっかりそのままAPIのレスポンスに含めるとまずいです。


# 除外する


```typescript
@Entity()
export class User {
  @PrimaryGeneratedColumn()
  readonly id: number;

  @Column({
    name: 'name',
    length: 255,
  })
  name: string;

  @Column('varchar', { name: 'password', select: false}) // ここ
  password: string;
}
```

`{select: false}` というオプションをつければOKです。SQLレベルで除外されます。

ちなみに何かしらの理由で敢えて取得したい場合は、明示的に書けばOKです。

```typescript
    const user = await this.userRepository.find({
      select: ['password']
    });
```


# 参考

[TypeORM \- Amazing ORM for TypeScript and JavaScript \(ES7, ES6, ES5\)\. Supports MySQL, PostgreSQL, MariaDB, SQLite, MS SQL Server, Oracle, WebSQL databases\. Works in NodeJS, Browser, Ionic, Cordova and Electron platforms\.](https://typeorm.io/#/select-query-builder/hidden-columns)

[typeorm \- Is it possible to 'protect' a property and exclude it from select statements \- Stack Overflow](https://stackoverflow.com/questions/43726739/is-it-possible-to-protect-a-property-and-exclude-it-from-select-statements)
【pip3】pip3 install opencv-pythonが永遠と終わらない問題

<h1>背景</h1>
よっしゃpip3でopencv install してやるぞと思ったら、一向に終わる気配なし
まただよ。python嫌いになりそう

<h1>環境</h1>
ubunutu18
python3.6
pip3


<h1>手順</h1>
1 とりあえず普通にinstallしてみる

```
pip3 install opencv-python
```

2 永遠と終わらない場合はpip3をupdateしてみる

```
pip3 install -U pip
```

3 scikit-imageが必要らしい

```
pip3 install scikit-image
```

4 もう一度installしてみる

```
pip3 install opencv-python
```
[PHP] 親クラスで定義した変数を呼ぶ

子クラス共通の変数を扱いたい場合、下記のように親クラスで定義する必要があります。

```php
class TestCase extends Illuminate\Foundation\Testing\TestCase
{
    protected static $userId = 1;
}
```

このように定義した後、下記のように子クラスで呼び出します。

```php
class ControllerTest extends \TestCase
{

    public function setUp(): void
    {
        $this->user = User::find(self::$userId);
    }
}
```

このようにself::$userIdと書くことにより、extendsしているクラスなら扱うことができます。

##参照
[【PHP】継承とprotectedと参照パターン](https://qiita.com/miyapei/items/6c43e8b38317afb5fdce)

##会社の紹介
私は現在、[株式会社ダイアログ](https://www.dialog-inc.com/)という物流×ITの会社に勤務しております。
様々な職種を募集しているので、[Wantedly](https://www.wantedly.com/companies/company_3244501)のページをご覧ください。
Vagrant up時のname already existsの対処法

vagrant up時に下記のようなエラーが出て詰まったので共有します。

```
The name of your virtual machine couldn't be set because VirtualBox
is reporting another VM with that name already exists. Most of the
time, this is because of an error with VirtualBox not cleaning up
properly. To fix this, verify that no VMs with that name do exist
(by opening the VirtualBox GUI). If they don't, then look at the
folder in the error message from VirtualBox below and remove it
if there isn't any information you need in there.

VirtualBox error:

VBoxManage: error: Could not rename the directory '/hoge/hoge/VirtualBox VMs/centos-6.9-x86_64_1606986844683_9972' to '/hoge/hoge/VirtualBox VMs/hoge' to save the settings file (VERR_ALREADY_EXISTS)
VBoxManage: error: Details: code NS_ERROR_FAILURE (0x80004005), component SessionMachine, interface IMachine, callee nsISupports
VBoxManage: error: Context: "SaveSettings()" at line 3249 of file VBoxManageModifyVM.cpp
```

/hoge/hoge/VirtualBox VMs/hogeが、既に存在しているということなので、消す必要があります。

```
sudo rm -rf /hoge/hoge/VirtualBox VMs/hoge
```
もしくは、Macの場合FinderでVirtualBox VMsファイルから該当ファイルを削除。

##参照
[vagrant upで A VirtualBox machine already exists.とでる解決方法](https://qiita.com/pugiemonn/items/92f234b7894bd4709f72)

##会社の紹介
私は現在、[株式会社ダイアログ](https://www.dialog-inc.com/)という物流×ITの会社に勤務しております。
様々な職種を募集しているので、[Wantedly](https://www.wantedly.com/companies/company_3244501)のページをご覧ください。
MySQL のテーブルから Spring の Model(Entity) を作成する（JPA Entities from Tables）

MySQL のテーブル群をそのまま Spring の Entity に移したいというときがあると思います。
その際結構スタックしたので記事にしようと思います。

### 初投稿
2021/1/29

### エディタ
Eclipse

## プロジェクトを作る際
・JPA を DI してください
・SQL > MySQL Driver を DI してください（h2もした方がいいかも）

## 手順
1. project を JPA project にコンバートする
2. JPA Entities from Tables

## Convert to JPA project
いきなり JPA Entities from Tables としても、JPA project の選択画面で選択肢がないままです。
（New から JPA を選べない場合は、project を作る際に JPA を選んでいないためです。プロジェクトを作り直してください。）
![スクリーンショット (258).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501146/65798a3b-f584-a953-f555-1b49565321d5.png)

そこで、プロジェクトを右クリック、configure から Convert to JPA project.. を選択してください。
Project Facets : Java と JPA にチェックがついていることを確認してください。

`Next >` で進むと JPA Facet の画面に来ます。
![スクリーンショット (263).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501146/ca58b45c-1194-71a7-94ce-4f8ad5cff506.png)

JPA implementation の Type を `Disable Library configuration` にして進んでいる記事もあったのですが、次のことをすると Warning が出なくなります。

右の Manage Library から New → 適当な名前を付けます。

これにjarファイルを追加するのですが、これは
https://www.eclipse.org/eclipselink/releases/2.5.php
からダウンロードします。
jlib 内の `eclipselink.jar` と
その jpa 内の jarファイルを全て追加してください。

続いて（作ったLibraryにチェックを入れて）Connection から Add connection → MySQL を選択します。
→ New Driver Difinition → System Version 5.1 の MySQL JDBC Driver を選択 → 上のタブから JAR List を選択
→ 既にある mysql-connector-java-5.1.0-bin.jar を削除（謎ですよね）→ https://dev.mysql.com/downloads/connector/j/5.1.html から mysql-connector-java-5.1.49.zip をダウンロード → 解凍 → mysql-connector-java-5.1.49.jar を選択。
→ properties で MySQL の名前やURL, user name, password を入力して ping が通ったら Finish

これで `JPA Entities from Tables` ができるようになっています。
![スクリーンショット (265).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501146/ddb5e81c-e043-41b3-83e5-d25560002900.png)
reactのmaterial-tableで一部カラムのみを編集可能にする

# Material-table
https://material-table.com/#/
Material-uiに則ったテーブルレイアウトを簡単に作成できるライブラリ。一部のカラムを編集できるデータの一覧表を実装したくて採用。

# 編集可能にしてみる
https://material-table.com/#/docs/features/editable
には「Row Editing」（行単位の一括編集）と「Cell Editing」（セル単位での編集）について記載があった。「Row Editing」の方は行の全カラムが編集可能になってしまい、編集可能にする必要のないカラムがあることから、「Cell Editing」の方かなと思い実装してみる。

```
const columnList = [
  { title: "ID", field: "id" },
  { title: "name", field: "name" },
  { title: "description", field: "description" },
];

const dataList = [
  { id: 1, name: "aaa", description: "xxxxxxxxxx" },
  { id: 2, name: "bbb", description: "yyyyyyyyyy" },
  { id: 3, name: "ccc", description: "zzzzzzzzzz" },
];

<MaterialTable
  columns={columnList}
  data={dataList}
  cellEditable={{
    onCellEditApproved: (newValue, oldValue, rowData, columnDef) => {
      return new Promise(() => {
        // do something
      });
    },
  }}
></MaterialTable>
```

結果、セル単位での編集にはなったものの、全セルが編集可能になってしまった。（ID列は編集させたくない）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376864/c8ddd9aa-0d44-7e65-14b5-ae09dda95bfc.png)


# 一部のセルだけ編集可能にするには…

```
const columnList = [
  { title: "ID", field: "id", editable: "never" },
  { title: "name", field: "name" },
  { title: "description", field: "description" },
];
```

**editable: "never"**

をカラムの定義につけてあげると、そのカラムは編集不可になった。（ID列をクリックしても編集欄が表示されないけど、それ以外の列は編集可能）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376864/0e4e5621-c468-8b5f-d6ac-08a9bb820ff7.png)

参考になれば幸いです。
【VSCode】VSCodeをubuntuにinstallする簡単な方法

<h1>環境</h1>
ubuntu18

<h1>インストール</h1>
1 debian packageをdownload
https://code.visualstudio.com/

2 install

```
$ sudo apt install .
$ sudo apt install -y apt-transport-https
$ sudo apt update
```

3 起動

```
$ code
```



<h1>参考文献</h1>
https://qiita.com/grgrjnjn/items/85aa7cab1475bf1aea54
【JMESPath】`foo[*][0]` と`foo[*] | [0]` の違い

## はじめに

AWS CLI の query で、パイプ(|)の挙動が分かりにくかったので整理した。

## サンプルデータ

```json
{
  "foo": [
    ["one", "two"],
    ["three", "four"],
    ["five", "six"]
  ]
}
```

## 結論

プロジェクション`foo[*]`[^1]に対し [Index Expression](https://jmespath.org/specification.html#index-expressions)(配列)でアクセスする場合、以下のように挙動が変わる。

- `foo[*][0]`
  - `["one", "three", "five"]`
- `foo[*] | [0]`
  - `["one", "two"]`

## 詳細

※<https://jmespath.org/>で実際にパスを入力しながら進めると、理解が早い。

[^1]: (JSON) document に対し、何らかの式(Expression)を反映させた結果のことを、[公式](https://jmespath.org/specification.html#wildcard-expressions)に則りプロジェクション(projection)と呼ぶ。

### 前提: foo と foo[\*]

`foo`と`foo[*]`の結果は、両方とも以下のようになる。

```json
[
  ["one", "two"],
  ["three", "four"],
  ["five", "six"]
]
```

### foo[\*][0]

`foo[*][0]`は、`foo[*]`で投影(projected)された各要素に対して`[0]`でアクセスを行う。
`foo[*]`は、`配列fooの全ての子要素を投影`するため、子要素である`["one", "two"]`, `["three", "four"]`, `["five", "six"]`が投影されている形になる。

つまり、上述したように`foo[*]`の投影結果は`foo`と同様に以下のようになる。
しかし、`foo`がこの 2 重配列全体を指しているのに対し、`foo[*]`が投影しているのはそれぞれの子配列要素である。
(複数の配列要素を投影しているで、2 重配列として表現されているに過ぎない)

```json
[
  ["one", "two"],
  ["three", "four"],
  ["five", "six"]
]
```

`foo[*][0]`は、これら 3 つの配列要素の 0 番目の要素を 1 つの配列にマージする。
そのため、結果として`["one", "three", "five"]`が投影される。

参考: [Flatten Operator](https://jmespath.org/specification.html#flatten-operator)

### foo[\*] | [0]

`|`(パイプ)を使用すると、投影された各要素を無視して、結果自体に右側の式を適用する。

`foo[*] | [0]`は、以下の`foo[*]`の投影結果全体における 0 番目の要素を返す。

```json
[
  ["one", "two"],
  ["three", "four"],
  ["five", "six"]
]
```

つまり、上の 2 重配列における 0 番目の要素である`["one", "two"]`が返る

参考: [Pipe Expressions](https://jmespath.org/specification.html#pipe-expressions)

## 蛇足と言う名の応用

上記を踏まえた上で、 `foo[*][0][0]` と`foo[*][0] | [0]`の結果がどう変わるか考えてみる。

上述したとおり、`foo[*][0]`は以下の通り。

```json
["one", "three", "five"]
```

<details><summary>答えはこちら</summary><div>

### `foo[*][0][0]`

#### 結果

[]

#### 解説

`foo[*][0]`が投影しているのは、`"one", "three", "five"`という 3 つの文字列要素である。
文字列要素に`[0]`でアクセスしても`null`になる。
投影された値を 1 つの配列にマージする際、`null`は無視されるため、結果として空配列`[]`が返る。

### `foo[*][0] | [0]`

#### 結果

"one"

#### 解説

`["one", "three", "five"]`という配列全体に対して、`[0]`でアクセスしたため、0 番目の要素である`"one"`が返る。

</div></details>

参考: [Slices](https://jmespath.org/specification.html#slices)

## 参考

- [Index Expressions | JMESPath Specification](https://jmespath.org/specification.html#index-expressions)
- [JMESPath で配列から要素を抽出するにはパイプを用いる](https://qiita.com/cold-wisteria/items/15f0369544b9de5d3952)
%matplotlib inline に関するエラー

# はじめに

今回初めてPythonを触った初心者。Visual Studio Codeを使用。

以下の記事「pythonで一から画像処理 (5)フーリエ変換」を実践しようとする。
https://qiita.com/fugunoko/items/41c33ca163c7bb52d283

エラーでつまづいたが、最終的には実行できた。
その過程の記録。

# 出現したエラー
## 諸々インストールしていないエラー

### OpenCV
```python:script.py
import cv2
```
を実行するためにOpenCVをインストール

```
pip install opencv-python
```
### NumPy

```python:script.py
import numpy as np
```
を実行するためにNumPyをインストール

```
pip install opencv-python
```

## 問題の「%matplotlib inline」
SyntaxError: invalid syntaxが出る

### 最終的な解決法→この一文を消す
この「%matplotlib inline」というのは開発環境である<b>「Jupyter Notebook」</b>というものを使っていない場合には必要ない様子。

これを消したらうまく行きました！

### 過程での対処
途中でいろいろエラーが出て、それに対する打ち手ももしかしたら影響しているかもしれない…？
最初は

```
ModuleNotFoundError: No module named 'matplotlib'
```
というエラーだったのでまずはこれをインストールするところから。

```
pip install matplotlib
```

それでもエラーが出たりしたので一旦「%matplotlib inline」を

```
from IPython import get_ipython
get_ipython().run_line_magic('matplotlib', 'inline')
```
というコードに書き換えました（どこかのネットの記事を参照したのにその参照元を忘れてしまいました…）
するとこういうエラーが出るのでまたインストール

```
ModuleNotFoundError: No module named 'IPython'
```

```
pip install ipython
```
しかしまだまだこんなエラーが出てきて…

```
get_ipython().run_line_magic('matplotlib', 'inline')
AttributeError: 'NoneType' object has no attribute 'run_line_magic'
```

このエラーが解決できずに結局どうしようもないとなってしまい、元々のプログラムに戻して再度エラーを確認し、調べ直すことに。

そしたら答えが見つかりました！
（英語だったけど）
https://stackoverflow.com/questions/39449549/python-syntaxerror-invalid-syntax-matplotlib-inline/39449990

使用する環境によって書いたり書かなかったりするコードがあるんですね。メモメモ。
これにて最初に書いた通り、%matplotlib inlineを消すことで一見落着です。

# 終わりに
Python難しいなと思ってたけど、意外にどうにかなるものでした。
まだまだ勉強を続けていきますー
【git】terminalにbranch名を常に表示する設定

<h1>背景</h1>
git使ってると自分が今どのbranhにいるんだっけ?っと良くなる。

たまにdevelopで開発してたと思ったら、masterのままだったとか良くある。

branch名をterminalに表示しておけば間違えないよって言われた。

よくそんな事知ってるな～

<h1>設定</h1>

gedit ~/.bashrc


以下のおまじないを加える

```
GIT_PS1_SHOWDIRTYSTATE=true
export PS1='\[\033[32m\]\u@\h\[\033[00m\]:\[\033[34m\]\w\[\033[31m\]$(__git_ps1)\[\033[00m\]\n\$ '
```

source ~/.bashrc
【VSCode】clang-formatで自動 format 

<h1>背景</h1>
以前formatしないでcodingしてたら、怒られました(笑)

VSCodeにはsave時にformatする機能があると教えてもらって、とても便利だったのでメモメモ


<h1>環境</h1>
ubuntu18
vscode
C++

<h1>インストール & 設定</h1>

1 clang formatをinstallする


```
apt install clang-format-6.0
```


2 vscodeのextensionでclang-formatをinsatllする


3 setting.jsonを設定する


gedit ~/.config/Code/User/settings.json

```
{
    "editor.formatOnSave": true,
    "editor.formatOnType": true,
    "clang-format.executable": "/usr/bin/clang-format-6.0",
    "C_Cpp.updateChannel": "Insiders",
    "workbench.editor.enablePreview": false,
    "window.zoomLevel": -1,
    "[cpp]": {
        "editor.defaultFormatter": "ms-vscode.cpptools"
    },
    "cmake.configureOnOpen": true,
}
```


5 codeをsave(ctrl+s)するたびformatされる
Nginx と Gin の連携

こちらのサンプル example.go を Nginx 経由でアクセスできるようにします。
リバースプロキシで、ポートフォワードをします。

直接　Gin にアクセスする場合

```bash
curl http://localhost:8080/ping
```

Nginx 経由でアクセスする場合

```bash
curl http://localhost/ping
```

Nginx の設定

```text:/etc/nginx/nginx.conf
（省略）
location   ^~ /ping {
        proxy_pass   http://127.0.0.1:8080/ping;
}
（省略）
```

設定が正しいことの確認

```bash
sudo nginx -t
```

Nginx の再起動

```bash
sudo systemctl restart nginx
```

次のようなエラーが出ることがあります。

```text:/var/log/nginx/error.log
(13: Permission denied) while connecting to upstream
```

次で解決します。

```bash
sudo setsebool -P httpd_can_network_connect 1
```
EC-CUBE4 環境構築 〜プラグインの反映〜

## 前提

[EC-CUBE4 環境構築（ローカル編）](https://qiita.com/applexco/items/1fb28de5173721d1e61b) などで構築した別の環境に対して、プラグインを反映するときの手順です。

## ファイル一式を別の環境にコピー

`composer.json` `composer.lock` を含む全ファイルを別の環境にデプロイします。
※ gitignore しているファイルは除く。

## インストール

```bash
# 依存ライブラリのインストール ※1
docker compose exec --user apache composer install --no-scripts --no-plugins --no-autoloader --prefer-dist
docker compose exec --user apache composer dumpautoload --no-scripts --no-plugins

# EC-CUBEプラグインのダウンロード
docker compose exec --user apache web ./bin/console eccube:composer:install

# キャッシュ削除 ※2
docker compose exec web chown -R apache:apache ./var
docker compose exec web chmod -R 777 ./var
docker compose exec --user apache web php -d memory_limit=-1 ./bin/console cache:clear --no-warmup

# EC-CUBEプラグインの有効化
docker compose exec --user apache web ./bin/console eccube:plugin:enable --code=EC_CUBE_PLUGIN_CODE
```

※1 `composer install` をせずに `eccube:composer:install` を動かすと、Customize領域でPluginのクラスをDIしている部分で `Cannot autowire service` のエラーが発生しました。
※2 キャッシュ削除せずに、EC-CUBEプラグインの有効化をすると、正しく認識されていないためか、エラーになりました。
npm run watch-pollがエラーになった

Laravel初心者です。
以下環境でアプリを作成しています。

|                | バージョン     |
|:---------------|------------:|
| Docker         | 20.10.2     |
| Docker-compose | 1.27.4      |
| PHP            | 7.4.14      |
| Laravel        | 8.24.0      |
| mysql          | 8.0.23      |


## npm run watch-pollでファイルの変更を反映

cssなどを変更してブラウザをリロードしても反映されず、
この場合はDockerコンテナ内で

```PHP:コンテナ
npm run watch-poll
```

を入力するとファイルの変更を監視してくれて
リアルタイムでコンパイルされるのだそうです。

入力すると
![スクリーンショット 2021-01-29 10.25.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1051152/27bceaf7-db45-835a-cf26-46f26dfd6657.png)

ターミナルがこのような画面になりブラウザに変更が反映されます。

ちなみに

```PHP
npm run watch
```

との違いは
`npm run watch`はファイルの変更を監視しているため特定のシステムの場合はうまくいかないようです。
`npm run watch-poll`は変更を1秒単位で確認するようです。



## npm run watch-pollでエラーが出た

ここからが本題です。
いつものように`npm run watch-poll`をしようとしたところ

![スクリーンショット 2021-01-28 0.16.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1051152/065415ba-3c57-56b3-aa52-5859a103cc9d.png)

このようにエラーになってしまいました。

どこがエラー文なのかわからないけど

```PHP:ターミナル
Local package.json exists, but node_modules missing, did you mean to install?
```

って出てるので`package.json`と`node_modules`がなんかおかしいのかなと推測。


## 解決

[こちら](https://qiita.com/kuroro_ru/items/d50212a1919308cc1480)の記事がとても分かりやすくて助かりました！
ありがとうござます。

>一般的な解決策としてnode_modulesとpackage-lock.jsonを消してキャッシュをクリアにし、再度npmをインストールしたあと、実行しなおすという手があります

とのこと。
あ、なんかこれっぽいと思って

```PHP:コンテナ
rm -rf node_modules && rm package-lock.json && npm cache clear --force && npm cache clean --force && npm i
```


とした後に再度

```PHP:コンテナ
npm run watch-poll
```

で無事に解決しました！


ありがとうございました！
Android TWRP（Team Win Recovery Project）を起動しようとするとエラーが発生する

# 目的

- Android TWRP（Team Win Recovery Project）を起動しようとするとエラーが発生する問題を解決したときのメモをまとめる

# 情報

- 筆者のAndroidタブレットはNexus7である。

# 問題発生までの経緯

- 下記方法を参考にカスタムリカバリTWRPをインストールした。
    - [https://docs.google.com/presentation/d/1R4579XdRbk09mISQSJb3VUzE40RbtzPTDbS6tLEKF5U/edit#slide=id.g404823a961_0_124](https://docs.google.com/presentation/d/1R4579XdRbk09mISQSJb3VUzE40RbtzPTDbS6tLEKF5U/edit#slide=id.g404823a961_0_124)

# 問題

- 下記のような文字列が出力されてリブートを繰り返す

```
Could not mount /data and unable to find crypto footer. Failed to mount '/data' (Invalid argument) Unable to recreate /data/media folder. Updating partition details... Failed to mount '/data' (İnvalid argument) ...done Unable to mount storage Failed to mount '/data' (Invalid argument) Full SELinux support is present. Unable to mount /data/media/TWRP/.twrps Running Recovery Commands Failed to mount '/data' (Invalid argument) Formatting Cache using make_ext4fs... Done processing script file Renamed stock recovery file in /system to prevent the stock ROM from replacing TWRP.
```

# 問題解決までの経緯

1. PCとAndroidタブレットをUSBケーブルで接続した。
1. 下記コマンドをコマンドプロンプトで実行する。

    ```
    adb reboot bootloader
    ```

1. 下記コマンドをコマンドプロンプトで実行する。

    ```
    fastboot oem lock
    ```

1. 充電が切れるまで本体を放置する。（再起動を繰り返しAndroidタブレットの充電が切れるのを待つ）
1. 本体を充電し電源を入れる。
1. 下記コマンドをコマンドプロンプトで実行する。

    ```
    adb reboot bootloader
    ```

1. タブレットの画面上で「Recovery mode」を音量ボタンで選択して画面ロックボタンで決定する。
1. 正常にTWRPが起動した。
普段使用しないSOQL

<b>レコードタイプID:</b>
```
SELECT RecordTypeId, RecordType.Name, RecordType.DeveloperName FROM xx
```
<b>ログ削除:</b>
```
SELECT Id, StartTime, LogUserId, LogLength, Location FROM ApexLog
```
<b>プロファイル:</b>
SELECT Profile.Name, Count(Name) Cnt FROM User WHERE IsActive = true GROUP BY Profile.Name ORDER BY Profile.Name
<b>プロファイル:</b>
```
SELECT Name FROM Profile WHERE Id IN ( SELECT ProfileId FROM User WHERE IsActive = true ) ORDER BY Name
```
<b>スケジュール監視:</b>
```
SELECT Id（jobId）,CronExpression,CronJobDetailId,EndTime, NextFireTime, OwnerId, PreviousFireTime, StartTime,State,TimesTriggered,TimeZoneSidKey FROM CronTrigger
```
<b>ジョブ詳細:</b>
```
SELECT Id, Name, JobType FROM CronJobDetail
レコードタイプID:SELECT Name, Id, SobjectType FROM RecordType Where SobjectType='Account'
```