昨日の投稿の続き
送った内容をコンソールでなく、ブラウザ上で確認したい。
検索等の実装も可能なようだ。
先ずは、一覧を表示できないと話にならないので、サンプルを作成してみる。
PHPサンプル list_messages.php
<?php
require("/autoloadが置いてあるでぃてくとりをフルパスで指定/autoload.php" );
use Twilio\Rest\Client;
//定義
$sid = "アカウントのSID";
$token = "アカウントのAUTHTOKEN";
$twilio = new Client($sid, $token);
$messages = $twilio->messages
->read(array(), 20);//取り合えず20個まで
foreach ($messages as $record) {
print($record->to);//toで送信先の番号
print($record->body);//送信メッセージの内容
}
?>
送信結果を取りたいのであれば、
body
date_sent
status
to
body
で十分な気がする。
取得できる配列は以下のようだ。
JSON APIの記載があった。
"account_sid": "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"api_version": "2010-04-01",
"body": "testing",
"date_created": "Fri, 24 May 2019 17:18:27 +0000",
"date_sent": "Fri, 24 May 2019 17:18:28 +0000",
"date_updated": "Fri, 24 May 2019 17:18:28 +0000",
"direction": "outbound-api",
"error_code": 30007,
"error_message": "Carrier violation",
"from": "+12019235161",
"messaging_service_sid": "MGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"num_media": "0",
"num_segments": "1",
"price": "-0.00750",
"price_unit": "USD",
"sid": "MMXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"status": "sent",
"subresource_uris": {
"media": "/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Messages/SMb7c0a2ce80504485a6f653a7110836f5/Media.json",
"feedback": "/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Messages/SMb7c0a2ce80504485a6f653a7110836f5/Feedback.json"
},
"to": "+18182008801",
"uri": "/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Messages/SMb7c0a2ce80504485a6f653a7110836f5.json"
2019/11/22
2019/11/21
PHP SMS APIサービスのテスト Twilio 登録から送信テスト完了まで
SMS APIサービスの実装テストにあたりTwilioさんのトライアル版を試してみた。
アカウント取得
ブラウザがchromeでないと上手くいかなかった。
https://jp.twilio.com/try-twilio/kddi-web
2019年に業務提携があったようで、トライアルアカウント取得のページが
複数存在するようだ。ここで、取得できた。
性、名、メールアドレス、パスワード(14文字以上)
を入力してトライアルアカウント作成をすると
ログインする。
その後、2段階式の認証が入り、SMSが有効な電話番号を求めてくるので、
入力して送信すると、認証数列がSMSに届くので、
それを入力して登録完了。
PHPへの実装
composerにてtwilio-phpのライブラリを取得
任意のフォルダにて
$ composer require twilio/sdk
処理されて
Generating autoload files
サンプルプログラム sms_send.php
<?php
require("/autoloadが置いてあるでぃてくとりをフルパスで指定/autoload.php" );
use Twilio\Rest\Client;
$account_sid = 'ダッシュボードのアカウントSIDを記載';
$auth_token = 'ダッシュボードのAUTH TOKENを記載';
$twilio_number = '+120********';//取得したTwilioの電話番号テストは+120のみ許容
$client = new Client($account_sid, $auth_token);
$client->messages->create(
'+8190********',//090の場合日本は+81なので090が+8190となる。トライアル時は登録した電話番号のみ許容される。
[
'from' => $twilio_number,
'body' => 'SMS送信テスト'
]
);
?>
実行してみる
$ php sms_send.php
PHP Fatal error: Uncaught exception 'Twilio\Exceptions\RestException' with message '[HTTP 426] Unable to create record: Upgrade Required' in /var/www/html/vendor/twilio/sdk/Twilio/Version.php:85
Stack trace:
#0 /var/www/html/vendor/twilio/sdk/Twilio/Version.php(219): Twilio\Version->exception(Object(Twilio\Http\Response), 'Unable to creat...')
#1 /var/www/html/vendor/twilio/sdk/Twilio/Rest/Api/V2010/Account/MessageList.php(70): Twilio\Version->create('POST', '/Accounts/AC5c4...', Array, Array)
#2 /var/www/html/maildistributer/test/twilio_test.php(20): Twilio\Rest\Api\V2010\Account\MessageList->create('+8190********', Array)
#3 {main}
thrown in /var/www/html/vendor/twilio/sdk/Twilio/Version.php on line 85
ん?
426エラーが返ってきたので、
twilioの仕様を確認したところ、tls1.2を強要とのこと
phpinfoで知らべたところ稼働中のサーバは
opensslは1.2対応していたが、
cURLのNSSが/3.15でTLS1.2に対応していなかった。(3.283.19.1-6以降以上を要求らしい)
手っとり早い方法を探したところ、NSS/3.28以上のパッケージをインストールしてから
curlをアップデートするのが最速とのことだったので、
# yum install -y https://rpms.southbridge.ru/rhel7/stable/x86_64/southbridge-stable-release-1.0-el7.southbridge.noarch.rpm
# yum update curl
依存処理に結構時間がかかったが、何とか処理完了
# systemctl restart httpd.service
phpを再起動
これも、壊したか?と不安になる位 えらく時間がかかった・・・。
再度テスト
$ php sms_send.php
届いた!
登録から送信完了まで作業時間が約1時間半だった。
2018-9月にTLS1.3がリリースされたので、
近いうちにTLS1.3(openssl 1.1.1)にアップデートが必要になるものと
推測される。
なにやら攻撃を受ける可能性があるなどの情報もありもう少し様子見しようかな
と思っているが、そろそろ、PHPも7.2に引き上げが必要だろう。
動作確認とか大変だなぁ
アカウント取得
ブラウザがchromeでないと上手くいかなかった。
https://jp.twilio.com/try-twilio/kddi-web
2019年に業務提携があったようで、トライアルアカウント取得のページが
複数存在するようだ。ここで、取得できた。
性、名、メールアドレス、パスワード(14文字以上)
を入力してトライアルアカウント作成をすると
ログインする。
その後、2段階式の認証が入り、SMSが有効な電話番号を求めてくるので、
入力して送信すると、認証数列がSMSに届くので、
それを入力して登録完了。
PHPへの実装
composerにてtwilio-phpのライブラリを取得
任意のフォルダにて
$ composer require twilio/sdk
処理されて
Generating autoload files
サンプルプログラム sms_send.php
<?php
require("/autoloadが置いてあるでぃてくとりをフルパスで指定/autoload.php" );
use Twilio\Rest\Client;
$account_sid = 'ダッシュボードのアカウントSIDを記載';
$auth_token = 'ダッシュボードのAUTH TOKENを記載';
$twilio_number = '+120********';//取得したTwilioの電話番号テストは+120のみ許容
$client = new Client($account_sid, $auth_token);
$client->messages->create(
'+8190********',//090の場合日本は+81なので090が+8190となる。トライアル時は登録した電話番号のみ許容される。
[
'from' => $twilio_number,
'body' => 'SMS送信テスト'
]
);
?>
実行してみる
$ php sms_send.php
PHP Fatal error: Uncaught exception 'Twilio\Exceptions\RestException' with message '[HTTP 426] Unable to create record: Upgrade Required' in /var/www/html/vendor/twilio/sdk/Twilio/Version.php:85
Stack trace:
#0 /var/www/html/vendor/twilio/sdk/Twilio/Version.php(219): Twilio\Version->exception(Object(Twilio\Http\Response), 'Unable to creat...')
#1 /var/www/html/vendor/twilio/sdk/Twilio/Rest/Api/V2010/Account/MessageList.php(70): Twilio\Version->create('POST', '/Accounts/AC5c4...', Array, Array)
#2 /var/www/html/maildistributer/test/twilio_test.php(20): Twilio\Rest\Api\V2010\Account\MessageList->create('+8190********', Array)
#3 {main}
thrown in /var/www/html/vendor/twilio/sdk/Twilio/Version.php on line 85
ん?
426エラーが返ってきたので、
twilioの仕様を確認したところ、tls1.2を強要とのこと
phpinfoで知らべたところ稼働中のサーバは
opensslは1.2対応していたが、
cURLのNSSが/3.15でTLS1.2に対応していなかった。(
手っとり早い方法を探したところ、NSS/3.28以上のパッケージをインストールしてから
curlをアップデートするのが最速とのことだったので、
# yum install -y https://rpms.southbridge.ru/rhel7/stable/x86_64/southbridge-stable-release-1.0-el7.southbridge.noarch.rpm
# yum update curl
依存処理に結構時間がかかったが、何とか処理完了
# systemctl restart httpd.service
phpを再起動
これも、壊したか?と不安になる位 えらく時間がかかった・・・。
再度テスト
$ php sms_send.php
届いた!
登録から送信完了まで作業時間が約1時間半だった。
2018-9月にTLS1.3がリリースされたので、
近いうちにTLS1.3(openssl 1.1.1)にアップデートが必要になるものと
推測される。
なにやら攻撃を受ける可能性があるなどの情報もありもう少し様子見しようかな
と思っているが、そろそろ、PHPも7.2に引き上げが必要だろう。
動作確認とか大変だなぁ
2019/11/14
CSPRでの乱数生成 (暗号論的疑似乱数生成関数)
この度、セキュリティポリシーの高い
パスワードの自動生成が必要になり、
疑似乱数生成(PR)によりパスワードの生成をしようとしたころ、
安全な乱数でないと駄目です。とNGをもらった。
安全な乱数なんて量子コンピュータでもないと出来ないよ~~
とか、
エントロピーの無駄使いだ!!
とか言っても解決しないので、簡単な方向を模索してみる。
稼働サーバのPHPが5.4なので、当初randメソッドやmt_randメソッドを
SHA256で包括して、SEEDをハッシュ値で生成するから
疑似じゃないでしょ?で行こう思っていたが、
駄目っぽい雰囲気だったので、もう少し調べてみたところ、
PHP5.4でもライブラリを実装するとPHP7からの
CSPRNGである「random_int」メソッドが使えたので、オボエガキ。
ライブラリは、いつものGitHub様から取得
公式からもリンクされるという素晴らしさ!!
https://github.com/paragonie/random_compat
適宜配置
実際のソース
<?php
//ライブラリ読み込み
require_once "./php_lib/random.php";
// 利用可能な文字列の指定
$chars = 'ABCDEFGHIJLKMNOPQRSTUVWXYZ0123456789';
// 変数初期化
$passwd = '';
// ランダムに文字列を生成(12文字)
for ($i = 0; $i < 12; $i++) {
$passwd .= $chars[random_int(0, 35)];//$charsの文字数を修正時は、必ず揃え、35を修正する。
}
//無限ループ注意!! 数字のみ英大文字のみを許容しない
while ( (preg_match('/^[0-9]+$/', $passwd) || preg_match('/^[A-Z]+$/', $passwd)) ){
$passwd = '';//一旦 $passwd をまっさらにする
for ($i = 0; $i < 12; $i++) {
$passwd .= $chars[random_int(0, 35)];//条件充足までループ
}
}
//文字列表示
echo $passwd;
?>
こんな感じ
やっぱり、困ったら一人で頑張らないで、公式サイトのメソッドを見るべきだ
と感じた。
パスワードの自動生成が必要になり、
疑似乱数生成(PR)によりパスワードの生成をしようとしたころ、
安全な乱数でないと駄目です。とNGをもらった。
安全な乱数なんて量子コンピュータでもないと出来ないよ~~
とか、
エントロピーの無駄使いだ!!
とか言っても解決しないので、簡単な方向を模索してみる。
稼働サーバのPHPが5.4なので、当初randメソッドやmt_randメソッドを
SHA256で包括して、SEEDをハッシュ値で生成するから
疑似じゃないでしょ?で行こう思っていたが、
駄目っぽい雰囲気だったので、もう少し調べてみたところ、
PHP5.4でもライブラリを実装するとPHP7からの
CSPRNGである「random_int」メソッドが使えたので、オボエガキ。
ライブラリは、いつものGitHub様から取得
公式からもリンクされるという素晴らしさ!!
https://github.com/paragonie/random_compat
適宜配置
実際のソース
<?php
//ライブラリ読み込み
require_once "./php_lib/random.php";
// 利用可能な文字列の指定
$chars = 'ABCDEFGHIJLKMNOPQRSTUVWXYZ0123456789';
// 変数初期化
$passwd = '';
// ランダムに文字列を生成(12文字)
for ($i = 0; $i < 12; $i++) {
$passwd .= $chars[random_int(0, 35)];//$charsの文字数を修正時は、必ず揃え、35を修正する。
}
//無限ループ注意!! 数字のみ英大文字のみを許容しない
while ( (preg_match('/^[0-9]+$/', $passwd) || preg_match('/^[A-Z]+$/', $passwd)) ){
$passwd = '';//一旦 $passwd をまっさらにする
for ($i = 0; $i < 12; $i++) {
$passwd .= $chars[random_int(0, 35)];//条件充足までループ
}
}
//文字列表示
echo $passwd;
?>
こんな感じ
やっぱり、困ったら一人で頑張らないで、公式サイトのメソッドを見るべきだ
と感じた。
2019/08/18
apache SELinuxがEnforcingの時、特定のフォルダで読み書きを可能にしたい。
安否確認を自主作成している際、PHPでファイルを読み書きできない状況になったので
調べたところ、コンテキストをいじるには
policycoreutils-python がインストールされていることが条件
yum list policycoreutils-python で調べてなければ、インストールのこと
/var/www/html/test 配下を許容するには
# semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html/test/(/.*)?"
# restorecon -R /var/www/html/test/
でSELinuxの例外を追加する必要がある。
ls -alFZ /var/www/html/test
で確認できる。
嵌ったパターン
既にファイルを生成していて、ディレクトリの属性を
httpd_sys_rw_content_tに変えてrestoreconをしても、
既にあるファイルの属性は変わらない 仕様である。
これが分からず、さんざん悩んだ挙句、
ls -alFZ /var/www/html/対象がいるディレクトリ/
で調べたところ、案の定 rwの属性になっていなかった・・・。
個別に属性付与か、いったん削除して再度scp等でアップするなりが必要。
調べたところ、コンテキストをいじるには
policycoreutils-python がインストールされていることが条件
yum list policycoreutils-python で調べてなければ、インストールのこと
/var/www/html/test 配下を許容するには
# semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html/test/(/.*)?"
# restorecon -R /var/www/html/test/
でSELinuxの例外を追加する必要がある。
ls -alFZ /var/www/html/test
で確認できる。
嵌ったパターン
既にファイルを生成していて、ディレクトリの属性を
httpd_sys_rw_content_tに変えてrestoreconをしても、
既にあるファイルの属性は変わらない 仕様である。
これが分からず、さんざん悩んだ挙句、
ls -alFZ /var/www/html/対象がいるディレクトリ/
で調べたところ、案の定 rwの属性になっていなかった・・・。
個別に属性付与か、いったん削除して再度scp等でアップするなりが必要。
2019/07/01
シェルスクリプトが動かない場合
プログラムを書いて試験して
予定通りに動いたので、cronで自動化をしようと
シェルスクリプトを記載したが、
うまく動かなかった。
logを取ると、プログラムが無いといわれる。
症状を調べると、改行がLFでなくCRLFになっていた。
最近エディタにatomを使っているのだが、
Windowsでatomを使うとデフォルトではCRLFを改行コードに
しているとのことだった。
atomの設定で、
Core Packages ⇒ line-ending-selector に
LF CRLF OS Default があるので、これを
LFにしてあげれば良い。
30分くらい嵌ってしまった。
予定通りに動いたので、cronで自動化をしようと
シェルスクリプトを記載したが、
うまく動かなかった。
logを取ると、プログラムが無いといわれる。
症状を調べると、改行がLFでなくCRLFになっていた。
最近エディタにatomを使っているのだが、
Windowsでatomを使うとデフォルトではCRLFを改行コードに
しているとのことだった。
atomの設定で、
Core Packages ⇒ line-ending-selector に
LF CRLF OS Default があるので、これを
LFにしてあげれば良い。
30分くらい嵌ってしまった。
2019/06/17
PDF解像度変更と一部のページ除去 gsコマンド(GhostScript)
表題の操作をスキャン後のファイルに自動処理で行いたい。
不要なページの削除方法
◆pdftkコマンドを使う
今回はスキャナの為の台紙である一枚目を取り除きたいので、
$ pdftk origin.pdf cat 2-end output modify.pdf
となる。
2枚目だけを取り除きたい場合は、
$ pdftk origin.pdf cat 1 3-end output modify.pdf
オプションの詳細
解像度の変更
◆gsコマンドを使う
オプションが非常に長いが、中途半端に記載すると
処理に時間がかかったので、ファイルサイズ軽減に係るところは全部表記した。
$ gs -q -sOutputFile="/home/user0463/out.pdf" -sDEVICE=pdfwrite -dNOPAUSE -dBATCH -dSAFER -dQUIET -dCompatibilityLevel=1.4 -sColorConversionStrategy=GRAY -dProcessColorModel=/DeviceGray -dGrayImageDownsampleType=/Bicubic -dGrayImageResolution=72 -dMonoImageDownsampleType=/Bicubic -dMonoImageResolution=72 -dColorImageDownsampleType=/Bicubic -dColorImageResolution=72 -dEmbedAllFonts=false -dSubsetFonts=false -dPDFSETTINGS=/printer /home/user0463/moto.pdf
解説
-q 実行時にメッセージを出力しない。
-sOutputFile="出力先ファイル記述"
-sDEVICE=pdfwrite pdf以外の設定 gs -hで確認できる。
-dNOPAUSE ページごとに処理に一時停止をさせない。(これを書かないと遅くなる)
-dBATCH 一連処理させる。
-dSAFER deletefileとrenamefileオペレータを無効
-dQUIET 標準出力への情報を表示しない。
-dCompatibilityLevel=1.4 1.3~1.6まで定義可
-sColorConversionStrategy=GRAY GRAY,CMYK,RGBを指定
-dProcessColorModel=/DeviceGray DeviceGray,DeviceCMYK,DeviceRGBを指定
-dGrayImageDownsampleType=/Bicubic /Subsample, /Average, /Bicubicを指定
-dGrayImageResolution=72 解像度を指定 dpiを指定デフォルト72
-dMonoImageDownsampleType=/Bicubic /Subsample, /Average, /Bicubicを指定
-dMonoImageResolution=72 解像度を指定 dpiを指定デフォルト72
-dColorImageDownsampleType=/Bicubic /Subsample, /Average, /Bicubicを指定
-dColorImageResolution=72 解像度を指定 dpiを指定デフォルト72
-dEmbedAllFonts=false フォントを埋め込むか? true,falseを指定
-dSubsetFonts=false 標準フォントを埋め込むか? true,falseを指定
-dPDFSETTINGS=/printer /screen, /ebook, /printer, /prepress, /defaultを指定
PDFSETTINGS は 低解像度← screen,ebook,printer,prepress →高解像度
defaultは元データを参照するようである。
あとは、シェルスクリプトに記載して、cron や inotifywait
で 自動処理させれば良い。
gsコマンドは端折って記載するより全部書いたほうが早いと云うのが面白い。
不要なページの削除方法
◆pdftkコマンドを使う
今回はスキャナの為の台紙である一枚目を取り除きたいので、
$ pdftk origin.pdf cat 2-end output modify.pdf
となる。
2枚目だけを取り除きたい場合は、
$ pdftk origin.pdf cat 1 3-end output modify.pdf
オプションの詳細
解像度の変更
◆gsコマンドを使う
オプションが非常に長いが、中途半端に記載すると
処理に時間がかかったので、ファイルサイズ軽減に係るところは全部表記した。
$ gs -q -sOutputFile="/home/user0463/out.pdf" -sDEVICE=pdfwrite -dNOPAUSE -dBATCH -dSAFER -dQUIET -dCompatibilityLevel=1.4 -sColorConversionStrategy=GRAY -dProcessColorModel=/DeviceGray -dGrayImageDownsampleType=/Bicubic -dGrayImageResolution=72 -dMonoImageDownsampleType=/Bicubic -dMonoImageResolution=72 -dColorImageDownsampleType=/Bicubic -dColorImageResolution=72 -dEmbedAllFonts=false -dSubsetFonts=false -dPDFSETTINGS=/printer /home/user0463/moto.pdf
解説
-q 実行時にメッセージを出力しない。
-sOutputFile="出力先ファイル記述"
-sDEVICE=pdfwrite pdf以外の設定 gs -hで確認できる。
-dNOPAUSE ページごとに処理に一時停止をさせない。(これを書かないと遅くなる)
-dBATCH 一連処理させる。
-dSAFER deletefileとrenamefileオペレータを無効
-dQUIET 標準出力への情報を表示しない。
-dCompatibilityLevel=1.4 1.3~1.6まで定義可
-sColorConversionStrategy=GRAY GRAY,CMYK,RGBを指定
-dProcessColorModel=/DeviceGray DeviceGray,DeviceCMYK,DeviceRGBを指定
-dGrayImageDownsampleType=/Bicubic /Subsample, /Average, /Bicubicを指定
-dGrayImageResolution=72 解像度を指定 dpiを指定デフォルト72
-dMonoImageDownsampleType=/Bicubic /Subsample, /Average, /Bicubicを指定
-dMonoImageResolution=72 解像度を指定 dpiを指定デフォルト72
-dColorImageDownsampleType=/Bicubic /Subsample, /Average, /Bicubicを指定
-dColorImageResolution=72 解像度を指定 dpiを指定デフォルト72
-dEmbedAllFonts=false フォントを埋め込むか? true,falseを指定
-dSubsetFonts=false 標準フォントを埋め込むか? true,falseを指定
-dPDFSETTINGS=/printer /screen, /ebook, /printer, /prepress, /defaultを指定
PDFSETTINGS は 低解像度← screen,ebook,printer,prepress →高解像度
defaultは元データを参照するようである。
あとは、シェルスクリプトに記載して、cron や inotifywait
で 自動処理させれば良い。
gsコマンドは端折って記載するより全部書いたほうが早いと云うのが面白い。
2019/05/17
raspberrypi3のカメラを使ってメール応答型のスクリプト node.jsを活用
やりたいこと
メールを受信すると、raspberrypi3のカメラで撮影し、
メールに添付して指定のメールアドレスに送信するスクリプト。
子供や愛犬の見守りなど目的は同じになるが、
玄関の施錠をしたか?を最寄りの駅で気になった場合に
万が一の為に戻りたくないので作成。
玄関が開き戸だったら、もっといろいろな仕掛けができたのだが・・・。
補足
メール部分は自分でサーバ建てるのが大変なので、
Gmailを利用し、node.jsを使ってメールの送信を常に監視し、
監視中にメールが来るとそれをトリガーにして
カメラで撮影、メールを送信する。
node.jsは『非同期スクリプト』であるため、
fs等を使う場合は、同期させた処理を行う必要がある。
ここで、嵌ってしまった・・・。
カメラの処理に時間がかかり、ファイルが生成される前に
メール送信のためのファイル加工が動作してしまい、
エラーが返って来てしまうので、
別々に動作確認が終わったら、promise 等で同期処理をさせる。
前提
・raspberry-pi3のカメラモジュールを認識済み
・Gmailのアカウント取得、安全性の低いアプリの許可」を有効にしてある。
・nodeが動かせること
◆◆◆成果物◆◆◆
'use strict';
var inbox = require('inbox');
//var nodemailer = require('nodemailer');
//var iconv = require('iconv');
//var conv = new iconv.Iconv("UTF-8", "UTF-8");
const simpleParser = require('mailparser').simpleParser;
var client = inbox.createConnection(false, 'imap.gmail.com', {
secureConnection: true
,auth: {
user:'Gmailアカウント@gmail.com'
,pass:'Gmailパスワード'
}
});
client.on('connect', function() {
console.log('connected');
client.openMailbox('INBOX', function(error) {
if (error) throw error;
});
});
client.connect();
client.on("new", function(message) {
console.log('日時:' + message.date);
console.log('送信者:' + message.from.name + '-' + message.from.address);
console.log('タイトル:' + message.title);
var stream = client.createMessageStream(message.UID);
simpleParser(stream)
.then(mail=> {
console.log('本文(HTMLテキスト):' + mail.textAsHtml);
})
.catch(err=> {
console.log(err);
});
//node.jsはデフォルトで非同期処理を行うため、
//asyncを用いてカメラがsnap.jpgを生成するのを待ち
//Gmailの送信(snap.jpgの添付)、snap.jpgの削除を行っている
//pi-cameraでは上書き保存ができないため、メール送信後に削除しておく。
const async = require('async'); //同期処理のためasync呼び出す
async.series([
function(callback) {
console.log('カメラの処理開始');
//pi-camera の動作ここから
const PiCamera = require('pi-camera');
const myCamera = new PiCamera({
mode: 'photo',
output: `${ __dirname }/snap.jpg`,
width: 640,
height: 480,
nopreview: true,
});
myCamera.snap()
.then((result) => {
// Your picture was captured
})
.catch((error) => {
// Handle your error
});
//pi-camera の動作ここまで
//安全をみて7秒ディレイ
setTimeout(callback, 7000);
}, function(callback) {
console.log('メールの返信開始');
//Gmailで送信ここから
var nodemailer = require('nodemailer')
var fs = require('fs');
// メッセージ内容
var message = {
from : '送信元@gmail.com',
to : '送信先@gmail.com',
subject : 'Reply to request',
text : 'Reply to request,Picture of the Pi-Camera !',
attachments : [{
filename: 'snap.jpg',
content: fs.readFileSync('snap.jpg') //カメラのデータ生成待ち
}]
};
var smtpConfig = {
host: 'smtp.gmail.com',
port: 465,
secure: true, // SSL
auth: {
user : 'Gmailアカウント@gmail.com',
pass : 'Gmailパスワード'
}
};
var transporter = nodemailer.createTransport(smtpConfig);
transporter.sendMail(message, function(err, response) {
console.log(err || response);
});
//ファイル削除
try {
fs.unlinkSync('snap.jpg');
console.log('snap.jpgを削除しました。');
} catch (error) {
throw error;
}
//Gmailで送信ここまで
setTimeout(callback, 1000);
}, function(callback) {
return console.log('処理終了');
}
], function(err, results) {
if (err) {
return console.log('err[' + err + ']');
}
});
}); // client.connect() を閉じる。
コマンド自体はプロンプト状態なので停止はcrtl+Zにて行う。
sshで操作する場合は、forever等で動かさないと、ターミナル閉じた瞬間に
Killされるので注意が必要。
◆◆動作部分解説◆◆
◆メール受信トリガー部分◆
node.jsのパッケージインストール
$ npm install inbox
$ npm install mailparser
まんま、@hideito2000様の掲載内容を使わせていただいた。
//ソース
client.on("new", function(message) {
console.log('日時:' + message.date);
console.log('送信者:' + message.from.name + '-' + message.from.address);
console.log('タイトル:' + message.title);
var stream = client.createMessageStream(message.UID);
simpleParser(stream)
.then(mail=> {
console.log('本文(HTMLテキスト):' + mail.textAsHtml);
})
.catch(err=> {
console.log(err);
});
//この部分にカメラ処理とメール送信を組み込む
});
//ソースここまで
◆pi-cameraのインストール◆
メールを受信すると、raspberrypi3のカメラで撮影し、
メールに添付して指定のメールアドレスに送信するスクリプト。
子供や愛犬の見守りなど目的は同じになるが、
玄関の施錠をしたか?を最寄りの駅で気になった場合に
万が一の為に戻りたくないので作成。
玄関が開き戸だったら、もっといろいろな仕掛けができたのだが・・・。
補足
メール部分は自分でサーバ建てるのが大変なので、
Gmailを利用し、node.jsを使ってメールの送信を常に監視し、
監視中にメールが来るとそれをトリガーにして
カメラで撮影、メールを送信する。
node.jsは『非同期スクリプト』であるため、
fs等を使う場合は、同期させた処理を行う必要がある。
ここで、嵌ってしまった・・・。
カメラの処理に時間がかかり、ファイルが生成される前に
メール送信のためのファイル加工が動作してしまい、
エラーが返って来てしまうので、
別々に動作確認が終わったら、promise 等で同期処理をさせる。
前提
・raspberry-pi3のカメラモジュールを認識済み
・Gmailのアカウント取得、安全性の低いアプリの許可」を有効にしてある。
・nodeが動かせること
◆◆◆成果物◆◆◆
'use strict';
var inbox = require('inbox');
//var nodemailer = require('nodemailer');
//var iconv = require('iconv');
//var conv = new iconv.Iconv("UTF-8", "UTF-8");
const simpleParser = require('mailparser').simpleParser;
var client = inbox.createConnection(false, 'imap.gmail.com', {
secureConnection: true
,auth: {
user:'Gmailアカウント@gmail.com'
,pass:'Gmailパスワード'
}
});
client.on('connect', function() {
console.log('connected');
client.openMailbox('INBOX', function(error) {
if (error) throw error;
});
});
client.connect();
client.on("new", function(message) {
console.log('日時:' + message.date);
console.log('送信者:' + message.from.name + '-' + message.from.address);
console.log('タイトル:' + message.title);
var stream = client.createMessageStream(message.UID);
simpleParser(stream)
.then(mail=> {
console.log('本文(HTMLテキスト):' + mail.textAsHtml);
})
.catch(err=> {
console.log(err);
});
//node.jsはデフォルトで非同期処理を行うため、
//asyncを用いてカメラがsnap.jpgを生成するのを待ち
//Gmailの送信(snap.jpgの添付)、snap.jpgの削除を行っている
//pi-cameraでは上書き保存ができないため、メール送信後に削除しておく。
const async = require('async'); //同期処理のためasync呼び出す
async.series([
function(callback) {
console.log('カメラの処理開始');
//pi-camera の動作ここから
const PiCamera = require('pi-camera');
const myCamera = new PiCamera({
mode: 'photo',
output: `${ __dirname }/snap.jpg`,
width: 640,
height: 480,
nopreview: true,
});
myCamera.snap()
.then((result) => {
// Your picture was captured
})
.catch((error) => {
// Handle your error
});
//pi-camera の動作ここまで
//安全をみて7秒ディレイ
setTimeout(callback, 7000);
}, function(callback) {
console.log('メールの返信開始');
//Gmailで送信ここから
var nodemailer = require('nodemailer')
var fs = require('fs');
// メッセージ内容
var message = {
from : '送信元@gmail.com',
to : '送信先@gmail.com',
subject : 'Reply to request',
text : 'Reply to request,Picture of the Pi-Camera !',
attachments : [{
filename: 'snap.jpg',
content: fs.readFileSync('snap.jpg') //カメラのデータ生成待ち
}]
};
var smtpConfig = {
host: 'smtp.gmail.com',
port: 465,
secure: true, // SSL
auth: {
user : 'Gmailアカウント@gmail.com',
pass : 'Gmailパスワード'
}
};
var transporter = nodemailer.createTransport(smtpConfig);
transporter.sendMail(message, function(err, response) {
console.log(err || response);
});
//ファイル削除
try {
fs.unlinkSync('snap.jpg');
console.log('snap.jpgを削除しました。');
} catch (error) {
throw error;
}
//Gmailで送信ここまで
setTimeout(callback, 1000);
}, function(callback) {
return console.log('処理終了');
}
], function(err, results) {
if (err) {
return console.log('err[' + err + ']');
}
});
}); // client.connect() を閉じる。
コマンド自体はプロンプト状態なので停止はcrtl+Zにて行う。
sshで操作する場合は、forever等で動かさないと、ターミナル閉じた瞬間に
Killされるので注意が必要。
◆◆動作部分解説◆◆
◆メール受信トリガー部分◆
node.jsのパッケージインストール
$ npm install inbox
$ npm install mailparser
まんま、@hideito2000様の掲載内容を使わせていただいた。
//ソース
client.on("new", function(message) {
console.log('日時:' + message.date);
console.log('送信者:' + message.from.name + '-' + message.from.address);
console.log('タイトル:' + message.title);
var stream = client.createMessageStream(message.UID);
simpleParser(stream)
.then(mail=> {
console.log('本文(HTMLテキスト):' + mail.textAsHtml);
})
.catch(err=> {
console.log(err);
});
//この部分にカメラ処理とメール送信を組み込む
});
//ソースここまで
◆pi-cameraのインストール◆
$ npm install pi-camera
作成者のページのサンプルをそのまま使う
//ソース
const PiCamera = require('pi-camera');
const myCamera = new PiCamera({
mode: 'photo',
output: `${ __dirname }/snap.jpg`,
width: 640,
height: 480,
nopreview: true,
});
myCamera.snap()
.then((result) => {
// Your picture was captured
})
.catch((error) => {
// Handle your error
});
//ソースここまで
◆nodemailer でメールを送信させるので、インストール◆ $ npm i -D nodemailer
ソースは皆さまの内容を参照させていただいた。
ありがとうございます。
//ソース
var mailer = require('nodemailer');
mailer.SMTP = {
host: 'smtp.gmail.com',
port: 465,
secure: true, // SSL
auth: {
user : 'Gmailのid@gmail.com,
pass : 'Gmailのパスワード'
}
};
fs.readFile("./snap.jpg", function (err, data) {
mailer.send_mail({
sender: '送信元@gmail.com',
to: '送信先@gmail.com',
subject: 'snapshot-Ent!',
body: 'Snapshot of the Entrance !',
attachments: [{'filename': 'snap.jpg', 'content': picture}]
}), function(err, success) {
if (err) {
// Handle error
}
}
});
//ソースここまで
◆ファイルの削除◆
try {
fs.unlinkSync('snap.jpg');
console.log('snap.jpgを削除しました。');
} catch (error) {
throw error;
}
fsは非同期だが、同じコマンドであれば記載の順に動くようだ。
駄目な場合は、 async の回数を増やせば良い。
◆同期処理◆
async.series([
function(callback) {
console.log('処理開始');
このcallback間にメソッドを記載
setTimeout(callback, 1000);
}, function(callback) { console.log('処理2開始');
setTimeout(callback, 1000);
});
}, function(callback) {
return console.log('処理終了');
}
],
期待した動きができたので、満足。
2019/05/08
CentOS(RedHat系) rootパスワードが分からない際の対策
CentOS7以降、レスキューモード(旧シングルユーザモード)、エマージェンシーモード
ともにrootパスワードを要求される。
しかし、管理者が不慮のアクシデントで対応できない状況となった際に、
どうしてもrootパスワードが必要なことが生じることがある。
今回、どうにもならない状況になってしまったため、操作した。
Procedure 25.6. Resetting the Root Password Using rd.break
いくつか手順を発見したので、残しておく
1.GRUB(ブートするOSを選択する画面)で「e」を押す。
2.rhgb quiet LANG*** を消して、systemd.debug の後ろにrw init=/bin/bashを加える。
3.Ctrl+x でboot開始
としてパスワードを強制上書きできるが、リラベリングに、えらく時間がかかった。
以下の手順でも再設定はできたので、間違いではないと思われる。
mozcの設定がうまくいっていなかったのかもしれないが、自分で構築していないので
どうにもならなかった・・・。
1.GRUB(ブートするOSを選択する画面)で「e」を押す。
2.rhgb quiet を消して、 rd.break enforcing=0 を書き加える。
(linux16の行と書いてあるが、同じ位置で問題なかった。)
※ enforcing=0はSELinuxの制御をオミットする意味とのこと。
3.Ctrl+x でboot開始
4.switch_root:/# mount -o remount,rw /sysroot を入力しエンター
※ファイルシステムを書き換え可能にする。
5.switch_root:/# chroot /sysroot を入力しエンター
※ファイルシステムをroot管理にする
6.sh-4.2# passwd でrootパスワードを設定する。
7.sh-4.2# exit を入力しエンター
8.switch_root:/# exit を入力しエンター
9.再起動し通常のユーザでログイン後ターミナルで新しいパスワードでroot化する。
10.# restorecon -v /etc/shadow を入力しエンター
※rd.breakで操作したrootパスワード格納のshadow定義をデフォルトにする。
※上記をしないと、再起動時にパスワードを誰も読めずログインできなくなる。
11.# setenforce 1 を入力しエンター
※SELinuxを有効にしておく。
以降は、再起動しても問題ない。
一般ユーザのパスワードはそのままで、rootは新しいパスワードが有効になる。
LUKS(Linux Unified Key Setup)を利用している場合は、
上記の操作を開始する時点でパスワードやファイルによる解除が必要となるそうだが、
LUKS は、膨大な (RHEL 7 では 512 文字) 平文テキストのパスフレーズと、非常に大きな (RHEL 7 では 8 MiB) のキーファイルを許可しているそうなので、
導入には、配慮が必要と改めて感じた。
ともにrootパスワードを要求される。
しかし、管理者が不慮のアクシデントで対応できない状況となった際に、
どうしてもrootパスワードが必要なことが生じることがある。
今回、どうにもならない状況になってしまったため、操作した。
Procedure 25.6. Resetting the Root Password Using rd.break
いくつか手順を発見したので、残しておく
1.GRUB(ブートするOSを選択する画面)で「e」を押す。
2.rhgb quiet LANG*** を消して、systemd.debug の後ろにrw init=/bin/bashを加える。
3.Ctrl+x でboot開始
4.bash-4.2# touch /.autorelabel でSELinuxを有効にする
5.bash-4.2# passwd でrootパスワードを設定する。
6.bash-4.2# exec /sbin/init 通常モードへ移行する。
6.bash-4.2# exec /sbin/init 通常モードへ移行する。
考察
switch_root:/# exit の再起動がうまくないようだ。
switch_root:/# exit の再起動がうまくないようだ。
rd.break enforcing=0 と宣言しなくとも、SELinuxは無効化される様子。
passwd <管理ユーザ>としてパスワードを強制上書きできるが、リラベリングに、えらく時間がかかった。
以下の手順でも再設定はできたので、間違いではないと思われる。
mozcの設定がうまくいっていなかったのかもしれないが、自分で構築していないので
どうにもならなかった・・・。
1.GRUB(ブートするOSを選択する画面)で「e」を押す。
2.rhgb quiet を消して、 rd.break enforcing=0 を書き加える。
(linux16の行と書いてあるが、同じ位置で問題なかった。)
※ enforcing=0はSELinuxの制御をオミットする意味とのこと。
3.Ctrl+x でboot開始
4.switch_root:/# mount -o remount,rw /sysroot を入力しエンター
※ファイルシステムを書き換え可能にする。
5.switch_root:/# chroot /sysroot を入力しエンター
※ファイルシステムをroot管理にする
6.sh-4.2# passwd でrootパスワードを設定する。
7.sh-4.2# exit を入力しエンター
8.switch_root:/# exit を入力しエンター
9.再起動し通常のユーザでログイン後ターミナルで新しいパスワードでroot化する。
10.# restorecon -v /etc/shadow を入力しエンター
※rd.breakで操作したrootパスワード格納のshadow定義をデフォルトにする。
※上記をしないと、再起動時にパスワードを誰も読めずログインできなくなる。
11.# setenforce 1 を入力しエンター
※SELinuxを有効にしておく。
以降は、再起動しても問題ない。
一般ユーザのパスワードはそのままで、rootは新しいパスワードが有効になる。
LUKS(Linux Unified Key Setup)を利用している場合は、
上記の操作を開始する時点でパスワードやファイルによる解除が必要となるそうだが、
LUKS は、膨大な (RHEL 7 では 512 文字) 平文テキストのパスフレーズと、非常に大きな (RHEL 7 では 8 MiB) のキーファイルを許可しているそうなので、
導入には、配慮が必要と改めて感じた。
2019/01/17
NTT αNXⅡ v4.00 webシステム設定 のjava
NTT αNXⅡ v4.00 webシステム設定
会社がNTTのネットコミュニティシステムαNXⅡを利用しているのだが、
ブラウザ上で電話帳や電話機の名称等の設定ができる。
javaのバージョンによっては動作しないので、
少し調べてみたので、オボエガキ
少し古い、αNX typeLのマニュアルの200ページくらいに
「次世代のJava Plug-inを有効にする 」設定を無効にする必要があると書いてある。
ところが、Oracleで確認すると、
末尾に
とあり、 Java Pluginが利用できなくなっている。
あわせて、次世代のJava Plug-inを有効無効の制御ができなくなったようだ。
一度、古めの6をインストールして、Webシステム設定を動作できる状況にしてから、
JDK8等をインストールすると両立できた。
会社がNTTのネットコミュニティシステムαNXⅡを利用しているのだが、
ブラウザ上で電話帳や電話機の名称等の設定ができる。
javaのバージョンによっては動作しないので、
少し調べてみたので、オボエガキ
少し古い、αNX typeLのマニュアルの200ページくらいに
「次世代のJava Plug-inを有効にする 」設定を無効にする必要があると書いてある。
ところが、Oracleで確認すると、
Changes in Java SE 6u171 b31
Please note that fixes from prior BPR (6u161 b32) are included in this version.末尾に
Known Issues
deploy
Windows - There is a non-functional Java icon in control panel after installing 6u171 or 7u161
Deployment features in 6u171 and 7u161 have been removed. Installing a
version of the JRE that has deployment technologies support AFTER
having installed the current JRE will cause the Windows Control Panel to
display a non-functional Java Control panel icon.
JDK-8185373 (not public)
とあり、 Java Pluginが利用できなくなっている。
あわせて、次世代のJava Plug-inを有効無効の制御ができなくなったようだ。
一度、古めの6をインストールして、Webシステム設定を動作できる状況にしてから、
JDK8等をインストールすると両立できた。
2018/11/16
postfix メールキューのエラー 大量のメールを誤送信してしまい、遅延がひどい場合の措置
サーバ内のメール転送プログラム実行中にエラーが生じた際に、
エラー警告メールを送信し、エスケープする処理を盛り込んだのだが、
エスケープの記述をしくじり、エンドレス送信が生じてしまった。
2時間程経過した際に以上に気づき、即座にプログラムは停止させ、/var/spool/mail/配下の指定アドレスの中身は処理したのだが、
postfixのキューに大量の残骸が残ってしまった。
遅延の遅延の遅延を繰り返し、頑張って送ってきてはいるが、
1万数千単位のメールが何時までも送られてくるため、当該ユーザの
通常のメールにも遅延が生じてしまっている状態。
そこで、postfixのキューを何とかして、通常の状態に戻してみた。
幸い、該当のメールのサイズが2kBと非常に小さいもので、他の遅延が殆どなかったので、
さらっと内容を確認して、該当のメールだけを削除する。
qmgr キューマネージャーにてメッセージはキューを通過する。
格納されている先
既に、 /var/spool/mail/配下の指定アドレスの中身は処理済みの場合、
問題は、
これで、正常な状態に戻っている(はず)
小生の環境では、これで正常に配信されるようになった。
この方の解説が非常にわかりやすかった。ありがとうございます。
kazupon.com様
エラー警告メールを送信し、エスケープする処理を盛り込んだのだが、
エスケープの記述をしくじり、エンドレス送信が生じてしまった。
2時間程経過した際に以上に気づき、即座にプログラムは停止させ、/var/spool/mail/配下の指定アドレスの中身は処理したのだが、
postfixのキューに大量の残骸が残ってしまった。
遅延の遅延の遅延を繰り返し、頑張って送ってきてはいるが、
1万数千単位のメールが何時までも送られてくるため、当該ユーザの
通常のメールにも遅延が生じてしまっている状態。
そこで、postfixのキューを何とかして、通常の状態に戻してみた。
幸い、該当のメールのサイズが2kBと非常に小さいもので、他の遅延が殆どなかったので、
さらっと内容を確認して、該当のメールだけを削除する。
qmgr キューマネージャーにてメッセージはキューを通過する。
格納されている先
/var/spool/postfix/incoming リモート受信した最新のメッセージ格納 /var/spool/postfix/active 処理中メッセージ /var/spool/postfix/bounce 配信できなかったメールID毎のログ /var/spool/postfix/corrupt postfixの形式に則ってないメッセージ格納
/var/spool/postfix/deferred 配信不能だがリトライする。 /var/spool/postfix/hold 無期限保存する際利用 /var/spool/postfix/defer 一時的に配送不能なメッセージリトライする。
既に、 /var/spool/mail/配下の指定アドレスの中身は処理済みの場合、
問題は、
deferredとdeferに残骸が有ると、何度もリトライを繰り返してしまう点にある。
そこで、 defer配下をfindしてファイルサイズ2kのものをxargsで渡して削除
# find /var/spool/postfix/defer/ -size 2k | xargs rm -rf
マジで全部消えるので、ほんとにそのサイズで大丈夫か?を確認すること
※ -execだとファイルの数だけコマンドを投げる仕様のようで、時間がかかってしまう。
今回1万数千回の実行は xargs の方が向いている。
同様に、deferredでも行う。
# find /var/spool/postfix/deferred/ -size 2k | xargs rm -rf
その後、 残った問題の無いものを強制送信。
# postfix flush
最後にキューをきれいにする
# postsuper -d ALL
キューがきれいになったか確認
# postqueue -p Mail queue is empty
これで、正常な状態に戻っている(はず)
小生の環境では、これで正常に配信されるようになった。
この方の解説が非常にわかりやすかった。ありがとうございます。
kazupon.com様
2018/11/06
SUBARU XV DBA-GT7 CADデータ
現行のSUBARU(スバル)XVのCADデータが見つからず・・・。
平面図が欲しかったが、SUBARUさんも3面図のみの掲載・・・。
平面図を作成するために、結局全部書いてしまった・・・。
誰トク?なCADデータだが、約2,500台/月の販売実績だし、
ちょっとリコール出てるけど、車に問題はないし、
オーナー様にご利用頂ければと思い、公開。
FC2に「SUBARU_XV_DBA_GT7.zip」でアップロードしてます。(JW_CAD)
SUBARU(スバル)XV 2017年5月~ DBA-GT7型 2.0i-Sアイサイト
平面図が欲しかったが、SUBARUさんも3面図のみの掲載・・・。
平面図を作成するために、結局全部書いてしまった・・・。
誰トク?なCADデータだが、約2,500台/月の販売実績だし、
ちょっとリコール出てるけど、車に問題はないし、
オーナー様にご利用頂ければと思い、公開。
FC2に「SUBARU_XV_DBA_GT7.zip」でアップロードしてます。(JW_CAD)
SUBARU(スバル)XV 2017年5月~ DBA-GT7型 2.0i-Sアイサイト
PHP 日本語メールの環境依存文字 文字化け対策
先般、SPF問題の解決の為、PHPMAILERにてメール送信を行うように仕様変更したが、
まだ、JIS-2022-JPの7bit問題が解決していない。
問題点としては、さまざまな環境のメールサーバやOSがアンドロイドでないフィーチャーフォン
(所謂ガラケー)では、8bitを許容していないようだが、ほとんどの動作環境下でUTF-8が
利用できるようになってきている。
と思われる。
そこで、今までは、JIS-2022-JP(7bit)の制約を受け、環境依存文字や半角カナ
が文字化けを起こす環境で運用を行っていたが、さすがに、ガラケーのみで
運用をするユーザが現役社会人である可能性は、万が一くらいでいいだろうと判断した。
前段が長くなってしまったが、
UTF-8でPHPMAILERのインスタンスを生成する際の記載をオボエガキ
前回との変更箇所をオレンジ表記
$mail->AddAttachment('./hogefile.pdf');日本語は極力使わない!!
大分後になって
$mail->CharSet = "UTF-8";
$mail->Encoding = "base64";
と宣言をするよりも、
$mail->CharSet = "iso-2022-jp";
$mail->Encoding = "7bit";
として、愚直に
mb_encode_mimeheader(mb_convert_encoding($fromname,"JIS","UTF-8"))
としたほうが、エンコード率が高いことが分かった。
まだ、JIS-2022-JPの7bit問題が解決していない。
問題点としては、さまざまな環境のメールサーバやOSがアンドロイドでないフィーチャーフォン
(所謂ガラケー)では、8bitを許容していないようだが、ほとんどの動作環境下でUTF-8が
利用できるようになってきている。
と思われる。
そこで、今までは、JIS-2022-JP(7bit)の制約を受け、環境依存文字や半角カナ
が文字化けを起こす環境で運用を行っていたが、さすがに、ガラケーのみで
運用をするユーザが現役社会人である可能性は、万が一くらいでいいだろうと判断した。
前段が長くなってしまったが、
UTF-8でPHPMAILERのインスタンスを生成する際の記載をオボエガキ
前回との変更箇所をオレンジ表記
smtp送信テストPHP(UTF-8送信)<?
require_once("/置いた所/vendor/autoload.php" ); //これを忘れると動かない!! require_once("/置いた所/vendor/phpmailer/phpmailer/class.phpmailer.php"); //これを忘れると動かない!!
mb_language("japanese");
mb_internal_encoding("UTF-8");
$to = "XXXX@gmail.com"; $subject = "SMTP587テスト"; $body = "smtpサーバ経由のメールテスト";
$from = "hoge@hogehoge.com"; $fromname = "送信テスト君"; $mail = new PHPMailer();//インスタンス生成 $mail->CharSet = "UTF-8";//UTF-8の宣言をすること $mail->Encoding = "base64";//記述しないと正しく認識しないサーバが存在するらしい。 $mail->IsSMTP(); //smtp利用宣言 $mail->SMTPAuth = TRUE;//smtp認証宣言 $mail->Host = 'mail.xxxx.jp:587'; // ホストアドレス:ポート25or587 $mail->Username = 'hoge'; //smtp認証ユーザ $mail->Password = 'hogehoge'; //smtp認証パス $mail->AddAddress($to);
$mail->From = $from;
$mail->FromName = $fromname;
$mail->Subject = $subject; $mail->Body = $body;
//メールを送信 if (!$mail->Send()){ echo("Failed to send mail. Error:".$mail->ErrorInfo); }else{ echo("Send mail OK."); }
?>
大分後になって
$mail->CharSet = "UTF-8";
$mail->Encoding = "base64";
と宣言をするよりも、
$mail->CharSet = "iso-2022-jp";
$mail->Encoding = "7bit";
として、愚直に
mb_encode_mimeheader(mb_convert_encoding($fromname,"JIS","UTF-8"))
としたほうが、エンコード率が高いことが分かった。
2018/10/24
composerで配置したPHPMailerの アクセス権限について
昨日、home直下のユーザディレクトリで作業を行ない、
/home/user/vendorという状況でテストを行ったが
例えば、/ver/www/htmlの配下から
/home/user/vendorにリクエストをする際に、パーミッションエラーが起こり
phpのプログラムが止まってしまった。
autoload.phpが正しくrequireされているかを確認するのが、厄介だった。
また、home以下のディレクトリのパーミッションを流石にすべて777にしたくないので、
/ver/www/html側に
composerから再度PHPMailerを配置し、お茶を濁した。
/home/user/vendorという状況でテストを行ったが
例えば、/ver/www/htmlの配下から
/home/user/vendorにリクエストをする際に、パーミッションエラーが起こり
phpのプログラムが止まってしまった。
autoload.phpが正しくrequireされているかを確認するのが、厄介だった。
また、home以下のディレクトリのパーミッションを流石にすべて777にしたくないので、
/ver/www/html側に
composerから再度PHPMailerを配置し、お茶を濁した。
2018/10/23
メールの到達率を高める。 SPF逆引き対策
受付完了のメールなどを、社内のサーバから送信しているのだが、
セキュアな対策を行っているメールサーバを利用している方に、メールが届かない
というケースが生じてきた。
SPF(Sender Policy Framework) という技術だそうで、
FORMのIPアドレスがDNSの逆引きで実在するかをチェックするという動きのようだ。
わざわざレンタルサーバ上でメールを作成して送信も手間なので、
今までは、特段気にしていなかったが、基幹システム化しつつあるため、そうも言ってられなくなった。
要は、実在するSMTPサーバを経由してメールを送ればいいので、少し調べた所
いくつか方法があった。
1.
1.は設定変更等が生じた際に面倒な気がしてならないので、保留。
2.は魅力的だが、php7.0以降でサポートしていないようなので、後ろ髪惹かれつ第2候補に
というわけで、PHPMailerをインストールしてみる。
依存関係を考慮しつつライブラリを使えるようにしてくれる
composerという PHPのパッケージ管理システムを使って
PHPMailerを導入してみる。
セキュアな対策を行っているメールサーバを利用している方に、メールが届かない
というケースが生じてきた。
SPF(Sender Policy Framework) という技術だそうで、
FORMのIPアドレスがDNSの逆引きで実在するかをチェックするという動きのようだ。
わざわざレンタルサーバ上でメールを作成して送信も手間なので、
今までは、特段気にしていなかったが、基幹システム化しつつあるため、そうも言ってられなくなった。
要は、実在するSMTPサーバを経由してメールを送ればいいので、少し調べた所
いくつか方法があった。
1.
postfixのmain.cf にリレーさせる
2.Qdsmtpというhal456さんが作成したライブラリを利用させて頂き、smtpサーバ経由にする。
3.PHPMailerという老舗のライブラリを利用させて頂きsmtpサーバを経由にする。
1.は設定変更等が生じた際に面倒な気がしてならないので、保留。
2.は魅力的だが、php7.0以降でサポートしていないようなので、後ろ髪惹かれつ第2候補に
というわけで、PHPMailerをインストールしてみる。
依存関係を考慮しつつライブラリを使えるようにしてくれる
composerという PHPのパッケージ管理システムを使って
PHPMailerを導入してみる。
# mkdir comp 適当な作業ディレクトリを作成。
# cd comp
# php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
# php composer-setup.php
All settings correct for using Composer
Downloading...
Composer (version 1.7.2) successfully installed to: /root/composer.phar
Use it: php composer.phar
# rm -f composer-setup.php もう要らないので、消す
# mv composer.phar /usr/local/bin/composer システム全般で使えるように移動
セキュリティホールになるからルートで使うなと言われるらしいので、 一般ユーザで確認
$ composer
でロゴとか出れば、OK
続けて、ライブラリ
phpmailer
を入れる。
任意のユーザの任意のディレクトリで行うこと
$ composer require phpmailer/phpmailer
Using version ^5.2 for phpmailer/phpmailer
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
- Installing phpmailer/phpmailer (v5.2.26): Downloading (100%)
phpmailer/phpmailer suggests installing league/oauth2-google (Needed for Google XOAUTH2 authentication)
Writing lock file
Generating autoload files
何処に置いたか忘れたら、これで探すようかな?
$ find -name vendor -type d
smtp送信テストPHP<?
require_once("/置いた所/vendor/autoload.php" ); //これを忘れると動かない!! require_once("/置いた所/vendor/phpmailer/phpmailer/class.phpmailer.php"); //これを忘れると動かない!!
mb_language("japanese");
mb_internal_encoding("UTF-8");
$to = "XXXX@gmail.com"; $subject = "SMTP587テスト"; $body = "smtpサーバ経由のメールテスト";
$from = "hoge@hogehoge.com"; $fromname = "送信テスト君"; $mail = new PHPMailer();//インスタンス生成 $mail->CharSet = "iso-2022-jp"; $mail->Encoding = "7bit"; $mail->IsSMTP(); //smtp利用宣言 $mail->SMTPAuth = TRUE;//smtp認証宣言 $mail->Host = 'mail.xxxx.jp:587'; // ホストアドレス:ポート25or587 $mail->Username = 'hoge'; //smtp認証ユーザ $mail->Password = 'hogehoge'; //smtp認証パス $mail->AddAddress($to);
$mail->From = $from; $mail->FromName = mb_encode_mimeheader(mb_convert_encoding($fromname,"JIS","UTF-8"));
$mail->Subject = mb_encode_mimeheader(mb_convert_encoding($subject,"JIS","UTF-8")); $mail->Body = mb_convert_encoding($body,"JIS","UTF-8"); //メールを送信 if (!$mail->Send()){ echo("Failed to send mail. Error:".$mail->ErrorInfo); }else{ echo("Send mail OK."); }
?>
テスト送信が届いたら、
念のため、SMTPサーバの/var/log/maillog も確認し、上手くいってるようだ。
稼働中のプログラムの置き換えをして完了。
明日できれば置き換えよう
うん、がんばろう・・・。
2018/10/10
tesseractの数字と一部の記号のみ識字させる方法
https://code-examples.net/ja/q/4b73be
此処に記載があった。
outputbase digits のオプションでは、何故か上手く行かなかったので、
此処に記載があった。
outputbase digits のオプションでは、何故か上手く行かなかったので、
少し調べてみたところ
標準出力にオプションでキャラクタの設定が出来るとあった。
標準出力にオプションでキャラクタの設定が出来るとあった。
stdout -c tessedit_char_whitelist=指定したい内容
これは上手くいったので、一旦標準出力させたものを無理やりファイル出力させた。
正規の方法は、学習させることだと思うが、
数字とハイフンのみ識別させればよかったので、この方法を採った。
数字の認識のみさせるであれば余程特殊なフォントでなければ、かなりの精度で認識した。
ファイル出力する場合
$ tesseract test.png stdout -c tessedit_char_whitelist=0123456789- >test.txt
ファイル出力する場合
$ tesseract test.png stdout -c tessedit_char_whitelist=0123456789- >test.txt
このようにすると良い。
デフォルトのライブラリを通すと、~や#に誤認識することが有り、
上手くなかったので、探してみたところ有益な情報が見つかったので、オボエガキ
2018/09/12
MSSQLへPHPで接続(PDO接続)
表題の、PHPでMSSQLへの接続時のオボエガキ
もともとは、mssql_connectにてMS SQLServerに接続していたが、
サーバの仕様変更と、php7から利用できなくなることもありPDO(PHP Data Objects の略)
接続へ切り替えた。
設定は、/etc/odbc.iniにてODBCのIDとfreetdsドライバーを関連付
/etc/odbcinst.iniに freetdsドライバーを追加
[freetds]
Description = MS SQL database access with Free TDS
Driver = /usr/local/lib/libtdsodbc.so
UsageCount = 1
Trace = Yes
freetdsをリポジトリからインストールするとSSLサポートされないので、
手動でインストールが必要だった。
https://stackoverflow.com/questions/39395548/how-to-configure-pymssql-with-ssl-support-on-ubuntu-16-04-lts/39395549
先駆者様ありがとうございます。
python-pip と libssl-dev をインストール後、
freeTDSは0.95のtar.gzを展開し、ディレクトリ内でmakeインストールする。
# ./configure --with-openssl=/usr/include/openssl --with-tdsver=7.3
# make
# make install
freetdsで接続する際に参照される接続先の定義は、/home/ユーザ名/.freetds.confに記載する。
##.freetds.confの中身##
# $Id: freetds.conf,v 1.12 2007-12-25 06:02:36 jklowden Exp $
#
# This file is installed by FreeTDS if no file by the same
# name is found in the installation directory.
#
# For information about the layout of this file and its settings,
# see the freetds.conf manpage "man freetds.conf".
# Global settings are overridden by those in a database
# server specific section
[global]
# TDS protocol version
; tds version = 4.2
# Whether to write a TDSDUMP file for diagnostic purposes
# (setting this to /tmp is insecure on a multi-user system)
; dump file = /tmp/freetds.log
; debug flags = 0xffff
# Command and connection timeouts
; timeout = 10
; connect timeout = 10
# If you get out-of-memory errors, it may mean that your client
# is trying to allocate a huge buffer for a TEXT field.
# Try setting 'text size' to a more reasonable limit
text size = 64512
# A typical Sybase server
[hoge] ←この変数を 'odbc:hoge' で読み込む。
host = hoge-sql.database.windows.net
port = 1433
tds version = 7.3
database = DEMODB
encryption = require
【PHPの中身】
//MSSQLにPDO接続
//基本:$pdo = new PDO($dsn, $username, $password, $driver_options);
try {
$pdo = new PDO('odbc:hoge','ログインユーザ名@hoge-sql.database.winwdows.net','パスワード');
$pdo->exec('SET CHARACTER SET utf8');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}catch(PDOException $Exception){
die('接続エラー:' .$Exception->getMessage());
}
//クエリ取得
try{
$sql= "select * from [テーブル名] where 条件";
$stmh = $pdo->prepare($sql);
$stmh->execute();
}catch(PDOException $Exception){
die('接続エラー:' .$Exception->getMessage());
}
while($col = $stmh->fetch(PDO::FETCH_ASSOC)){
print($col['カラム名']);
//変数等を定義する場合も普通に行える。
}
}//クエリの取得終了
//sqlServerの接続を解除
$pdo = null;
もともとは、mssql_connectにてMS SQLServerに接続していたが、
サーバの仕様変更と、php7から利用できなくなることもありPDO(PHP Data Objects の略)
接続へ切り替えた。
設定は、/etc/odbc.iniにてODBCのIDとfreetdsドライバーを関連付
/etc/odbcinst.iniに freetdsドライバーを追加
[freetds]
Description = MS SQL database access with Free TDS
Driver = /usr/local/lib/libtdsodbc.so
UsageCount = 1
Trace = Yes
freetdsをリポジトリからインストールするとSSLサポートされないので、
手動でインストールが必要だった。
https://stackoverflow.com/questions/39395548/how-to-configure-pymssql-with-ssl-support-on-ubuntu-16-04-lts/39395549
先駆者様ありがとうございます。
python-pip と libssl-dev をインストール後、
freeTDSは0.95のtar.gzを展開し、ディレクトリ内でmakeインストールする。
# ./configure --with-openssl=/usr/include/openssl --with-tdsver=7.3
# make
# make install
$ tsql -C
Compile-time settings (established with the "configure" script)
Version: freetds v0.95
freetds.conf directory: /usr/local/etc
MS db-lib source compatibility: no
Sybase binary compatibility: no
Thread safety: yes
iconv library: yes
TDS version: 7.3
iODBC: no
unixodbc: yes
SSPI "trusted" logins: no
Kerberos: no
OpenSSL: yes ←ここが重要
GnuTLS: no
freetdsで接続する際に参照される接続先の定義は、/home/ユーザ名/.freetds.confに記載する。
##.freetds.confの中身##
# $Id: freetds.conf,v 1.12 2007-12-25 06:02:36 jklowden Exp $
#
# This file is installed by FreeTDS if no file by the same
# name is found in the installation directory.
#
# For information about the layout of this file and its settings,
# see the freetds.conf manpage "man freetds.conf".
# Global settings are overridden by those in a database
# server specific section
[global]
# TDS protocol version
; tds version = 4.2
# Whether to write a TDSDUMP file for diagnostic purposes
# (setting this to /tmp is insecure on a multi-user system)
; dump file = /tmp/freetds.log
; debug flags = 0xffff
# Command and connection timeouts
; timeout = 10
; connect timeout = 10
# If you get out-of-memory errors, it may mean that your client
# is trying to allocate a huge buffer for a TEXT field.
# Try setting 'text size' to a more reasonable limit
text size = 64512
# A typical Sybase server
[hoge] ←この変数を 'odbc:hoge' で読み込む。
host = hoge-sql.database.windows.net
port = 1433
tds version = 7.3
database = DEMODB
encryption = require
【PHPの中身】
//MSSQLにPDO接続
//基本:$pdo = new PDO($dsn, $username, $password, $driver_options);
try {
$pdo = new PDO('odbc:hoge','ログインユーザ名@hoge-sql.database.winwdows.net','パスワード');
$pdo->exec('SET CHARACTER SET utf8');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}catch(PDOException $Exception){
die('接続エラー:' .$Exception->getMessage());
}
//クエリ取得
try{
$sql= "select * from [テーブル名] where 条件";
$stmh = $pdo->prepare($sql);
$stmh->execute();
}catch(PDOException $Exception){
die('接続エラー:' .$Exception->getMessage());
}
while($col = $stmh->fetch(PDO::FETCH_ASSOC)){
print($col['カラム名']);
//変数等を定義する場合も普通に行える。
}
}//クエリの取得終了
//sqlServerの接続を解除
$pdo = null;
2018/08/09
postfixのTLS設定
gmailで暗号化されていないと赤い鍵が表示されて何か気になるので対策してみる。
ファイアーウォールは適宜解放のこと
25、587、465
ローカルのSSL/TLSの設定は行っているが、
postfixのサーバ間の接続については、細かく設定していなかった。(MTA間通信)
これをTLSやS/MIMEに対応させていないと、gmailで赤い鍵が表示されてしまう仕様のようだ。
postfixの設定見直しはSMTP関連は次のようにしておく
赤い鍵が消えた。よかった。
ファイアーウォールは適宜解放のこと
25、587、465
ローカルのSSL/TLSの設定は行っているが、
postfixのサーバ間の接続については、細かく設定していなかった。(MTA間通信)
これをTLSやS/MIMEに対応させていないと、gmailで赤い鍵が表示されてしまう仕様のようだ。
postfixの設定見直しはSMTP関連は次のようにしておく
# nano /etc/postfix/master.cf 頭の方に記載がある
【中身】
smtp inet n - n - - smtpd
↑必須 submission inet n - n - - smtpd ↑587ポートを使う場合
-o smtpd_tls_security_level=may
↑587の時これをencriptにすると、STARTTLSをしてから送れ、と言われてしまうので、どっちも許容のmayがよい
-o smtpd_sasl_auth_enable=yes
↑SMTP認証を使う場合はyesにする
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
↑SMTP-AUTHを通ったものを許可する。rejectは細かく指定するとそこは蹴れる。
# nano /etc/postfix/main.cf TLSは末尾に記載されているので、そこを編集
【中身】
## TLS
# Transport Layer Security
#
smtpd_use_tls = yes
smtp_use_tls = yes
#smtpd_tls_auth_only = yes
↑これを有効にするとTLSでないと蹴るので、コメントアウトのままにしておく smtpd_tls_key_file = /usr/local/ssl/private/キーファイル.key smtpd_tls_CAfile = /usr/local/ssl/crt/SSL証明書ファイル.crt smtpd_tls_loglevel = 3
↑これを1にすると、ログにTLSの事が記載されるらしい。
smtpd_tls_received_header = yes
tls_random_source = dev:/dev/urandom
smtpd_tls_security_level=may
↑25ポートからのSTARTTLSを使う場合は、master.cfでなく、main.cfに記載するとの事。postfixを再起動して内容反映
# systemctl restart postfix
オレンジ色の部分を記載すると、
相手がTLSを受け付けてくれる場合は、MTA間通信をSSL/TLSにて行える
2018/06/27
指定ディレクト配下のPDFのファイル名を変更する。
はじめに、OCRをさせる為、Tesseract-OCRをmake installする
その事前準備のライブラリをインストールする
途中のmakeでmakeでICU(文字コード変換ライブラリ)が必要になるらしいが、
パッケージが無いので、
Leptonica という画像解析ライブラリも必要なので、
こちらも、makeからインストール 1.76が最新
tesseract-ocrと辞書のインストール
# mv 3.04.01.tar.gz tesseract3.01.01.tar.gz
# tar -zxvf tesseract3.01.01.tar.gz
# cd tesseract-3.04.01/
$ pdftoppm /storage1/scanedPdf/20180613133511305.pdf -f 1 -l 1 -mono -x 110 -y 45 -W 140 -H 35 -png /storage1/scanedPdf/mono
こんな感じで使う。
mono-1.pngをocrに掛ける。
$ tesseract /storage1/scanedPdf/mono-1.png /storage1/scanedPdf/mono
mono.txtが生成されるので、
これをトリミングして、
欲しい部分だけにする。
$ cat ./mono.txt|tr -d '\n''' > ./mono0.txt
$ cat ./mono0.txt|tr -d ' ' > ./mono1.txt
これで、mono1.txtには
10xx-1XXXXXX が記載されている。
これを使って元のPDFのリネームを行いたい。
ハイフンの全角「ー」と「-」半角を認識する様で、
全角で読み込んでしまうことが有ったので、
nkf コマンドですべて半角にしてしまう事にする。
# yum install nkf
コマンドの際は、
cat $filename-0.txt|nkf -Z4 > $filename.txt
シェルスクリプトの例
#!/bin/bash
#tesseractのパスを通す
export PATH="/usr/local/bin:$PATH"
#ディレクトリ移動
echo "ディレクトリを移動"
cd /storage1/scanedPdf/
#while用にディレクトリ内のファイル数をカウント
count=$(ls | wc -w)
echo "ディレクトリ内のファイル数:"$count
#カウントが0以上なら、ループ処理を行う。
#-ne not equal
while [ $count -ne 0 ]
do
#一行づつ処理するために念のため仕掛ける。いきなり変数でも問題ない。
for file in `\find . -maxdepth 1 -name '*.pdf'| head -n1`; do
basename $file .pdf
done
#変数定義
filename=$(basename $file .pdf)
#pdftoppmでpdfデータの左上(0,0)基準の座標(100,45)から座標(290,80)までを切り出しモノクロのpngを生成する。
pdftoppm $filename.pdf -f 1 -l 1 -mono -x 100 -y 45 -W 190 -H 35 -png /storage1/scanedPdf/$filename
#上記のpngをOCRで読み取り、テキストファイルを生成する。
#-1は「ファイル名-1.png」が生成されてしまうため、この-1が必要となる。
tesseract $filename-1.png -psm 6 $filename-1
#テキストデータ内の半角スペースを削除する
cat $filename-1.txt|tr -d ' ' > $filename-2.txt
#テキストデータ内の全角―を半角-に書き換える
cat $filename-2.txt|nkf -Z4 > $filename.txt
#変数定義
pdfname=$(head -n 1 $filename.txt)
echo $pdfname
#pdfの名称を1xxx-1xxxxxの形に変更して、/storage1/pdf/に移動
mv ./$filename.pdf /storage1/pdf/$pdfname.pdf
#作業ファイルを削除
rm $filename*
#カウントのデクリメント
count=$(( count -1))
done
上手く動いた。
当初、パスを通していなかったため、上手く動かなかったが、cronでも問題なく動いた。
複合機で一つ一つのファイルを開いて中身を確認して名称を付けるのは非常に面倒くさいし、もの凄い時間を浪費する。
これは、かなり便利だと思う。
その事前準備のライブラリをインストールする
# yum install autoconf automake libtool # yum install libpng-devel libjpeg-devel libtiff-devel zlib-devel # yum install libicu-devel # yum install pango-devel
途中のmakeでmakeでICU(文字コード変換ライブラリ)が必要になるらしいが、
パッケージが無いので、
icu4c をmakeからインストールする
# cd /usr/local/src/ # sudo wget http://download.icu-project.org/files/icu4c/56rc/icu4c-56_rc-src.tgz # tar zxf icu4c-56_rc-src.tgz # cd icu/source/ # ./configure # make # make install
Leptonica という画像解析ライブラリも必要なので、
こちらも、makeからインストール 1.76が最新
# cd /usr/local/src/# wget http://www.leptonica.com/source/leptonica-1.76.0.tar.gz
# tar -xzvf leptonica-1.76.0.tar.gz # cd leptonica-1.76.0 # ./configure # make # make install
tesseract-ocrと辞書のインストール
# cd /usr/local/src/# wget https://github.com/tesseract-ocr/tesseract/archive/3.04.01.tar.gz
# mv 3.04.01.tar.gz tesseract3.01.01.tar.gz
# tar -zxvf tesseract3.01.01.tar.gz
# cd tesseract-3.04.01/
#./autogen.sh
# LDFLAGS="-L/usr/local/lib" CFLAGS="-I/usr/local/include" ./configure --with-training-tools
# make
# make install
# ldconfig
更に、設定ファイルを定義
取敢えず英語の場合、
tesseract-ocr-3.02.eng.tar.gzをどこからか探してくる。
/usr/local/share/tessdate/配下に 中身をコピーする。
これで、ようやくocrが使える。
# pdftoppm 0000.pdf 0000out これで、0000ont.ppmが生成されるので、
これをocrに掛ける。
画像が大きい場合は、optionでトリミングしたりする。
$ pdftoppm /storage1/scanedPdf/20180613133511305.pdf -f 1 -l 1 -mono -x 110 -y 45 -W 140 -H 35 -png /storage1/scanedPdf/mono
こんな感じで使う。
mono-1.pngをocrに掛ける。
$ tesseract /storage1/scanedPdf/mono-1.png /storage1/scanedPdf/mono
mono.txtが生成されるので、
これをトリミングして、
欲しい部分だけにする。
$ cat ./mono.txt|tr -d '\n''' > ./mono0.txt
$ cat ./mono0.txt|tr -d ' ' > ./mono1.txt
これで、mono1.txtには
10xx-1XXXXXX が記載されている。
これを使って元のPDFのリネームを行いたい。
ハイフンの全角「ー」と「-」半角を認識する様で、
全角で読み込んでしまうことが有ったので、
nkf コマンドですべて半角にしてしまう事にする。
# yum install nkf
コマンドの際は、
cat $filename-0.txt|nkf -Z4 > $filename.txt
-Zで 全角⇒半角だが、 helpによると-Z4は
JISX0208 Katakana to JISX0201 Katakanaとなっており、
どうもこの方が精度が良いようなので、-Z4でやってみる。
#!/bin/bash
#tesseractのパスを通す
export PATH="/usr/local/bin:$PATH"
#ディレクトリ移動
echo "ディレクトリを移動"
cd /storage1/scanedPdf/
#while用にディレクトリ内のファイル数をカウント
count=$(ls | wc -w)
echo "ディレクトリ内のファイル数:"$count
#カウントが0以上なら、ループ処理を行う。
#-ne not equal
while [ $count -ne 0 ]
do
#一行づつ処理するために念のため仕掛ける。いきなり変数でも問題ない。
for file in `\find . -maxdepth 1 -name '*.pdf'| head -n1`; do
basename $file .pdf
done
#変数定義
filename=$(basename $file .pdf)
#pdftoppmでpdfデータの左上(0,0)基準の座標(100,45)から座標(290,80)までを切り出しモノクロのpngを生成する。
pdftoppm $filename.pdf -f 1 -l 1 -mono -x 100 -y 45 -W 190 -H 35 -png /storage1/scanedPdf/$filename
#上記のpngをOCRで読み取り、テキストファイルを生成する。
#-1は「ファイル名-1.png」が生成されてしまうため、この-1が必要となる。
tesseract $filename-1.png -psm 6 $filename-1
#テキストデータ内の半角スペースを削除する
cat $filename-1.txt|tr -d ' ' > $filename-2.txt
#テキストデータ内の全角―を半角-に書き換える
cat $filename-2.txt|nkf -Z4 > $filename.txt
#変数定義
pdfname=$(head -n 1 $filename.txt)
echo $pdfname
#pdfの名称を1xxx-1xxxxxの形に変更して、/storage1/pdf/に移動
mv ./$filename.pdf /storage1/pdf/$pdfname.pdf
#作業ファイルを削除
rm $filename*
#カウントのデクリメント
count=$(( count -1))
done
上手く動いた。
当初、パスを通していなかったため、上手く動かなかったが、cronでも問題なく動いた。
複合機で一つ一つのファイルを開いて中身を確認して名称を付けるのは非常に面倒くさいし、もの凄い時間を浪費する。
これは、かなり便利だと思う。
2018/06/19
リモートデスクトップ接続が出来ない(windowsアップデートによる)
WindowsServer2012へリモートデスクトップ接続を行なおうとすると、
認証エラー
要求された関数はサポートされません
サーバ:192.168.0.xxx
のダイアログが表示されて接続できない。
環境
サーバ
Windows 2012R2
クライアント
windows7 Home(セキュリティパッチのみ)
2018 年 5 月の更新プログラム適用によるリモート デスクトップ接続への影響
https://blogs.technet.microsoft.com/askcorejp/2018/05/02/2018-05-rollup-credssp-rdp/
4-2. リモート デスクトップ接続元 (クライアント) での回避策
リモートデスクトップ接続元にて以下レジストリを手動もしくは REG ADD コマンドで追加いただくことでも回避策 1 と同様の効果が得られます。
レジストリ パス : HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters
値 : AllowEncryptionOracle
データの種類 : DWORD
値 : 2
REG ADD コマンドで追加いただく場合には以下のコマンド ラインとなります。
REG ADD HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters /v AllowEncryptionOracle /t REG_DWORD /d 2
とのこと。
コマンドプロンプトを監理者権限で起動し、
REG ADD HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters /v AllowEncryptionOracle /t REG_DWORD /d 2
を叩くと接続できた。
根本的な解決は、サーバ側に更新プログラムを適用させろ
との事なので、早めにやろう。
2018/06/04
postgresql 初期化と接続 外部からのdump
postgresqlがインストールされているか確認。
pgsql --version
psql (PostgreSQL) 9.2.18
起動テストをしてみる。
# systemctl start postgresql.service
Job for postgresql.service failed because the control process exited with error code. See "systemctl status postgresql.service" and "journalctl -xe" for details.
初期化が必要だった。
# service postgresql initdb
Hint: the preferred way to do this is now "postgresql-setup initdb"
Initializing database ... OK
動かしてみる。
# systemctl start postgresql.service
[root@localhost ~]# systemctl status postgresql.service
● postgresql.service - PostgreSQL database server
Loaded: loaded (/usr/lib/systemd/system/postgresql.service; disabled; vendor preset: disabled)
Active: active (running) since 月 2018-06-04 18:54:47 JST; 12s ago
Process: 1627 ExecStart=/usr/bin/pg_ctl start -D ${PGDATA} -s -o -p ${PGPORT} -w -t 300 (code=exited, status=0/SUCCESS)
Process: 1619 ExecStartPre=/usr/bin/postgresql-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
Main PID: 1630 (postgres)
CGroup: /system.slice/postgresql.service
tq1630 /usr/bin/postgres -D /var/lib/pgsql/data -p 5432
tq1631 postgres: logger process
tq1633 postgres: checkpointer process
tq1634 postgres: writer process
tq1635 postgres: wal writer process
tq1636 postgres: autovacuum launcher process
mq1637 postgres: stats collector process
6月 04 18:54:46 localhost.localdomain systemd[1]: Starting PostgreSQL database server...
6月 04 18:54:47 localhost.localdomain systemd[1]: Started PostgreSQL database server.
動いた。
一旦停止して、外部からのアクセスが出来るようにする。
# nano /var/lib/pgsql/data/postgresql.conf
L60位のlisten_addressを許容
listen_addresses = '*' # what IP address(es) to listen on;
# nano /var/lib/pgsql/data/pg_hba.conf
末尾にIPアドレスの設定
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 trust
# Allow replication connections from localhost, by a user with the
# replication privilege.
#local replication postgres trust
#host replication postgres 127.0.0.1/32 trust
#host replication postgres ::1/128 trust
# for server
host all all 192.168.xxx.0/24 password
host all all 192.168.xxx.0/24 password
host all all 192.168.xxx.0/24 password
# for vendor
host all all xxx.xxx.xxx.xxx/28 password
firewallを開放
# firewall-cmd --add-service=postgresql --permanent
success
# systemctl restart firewalld.service
再度起動
恐らく問題なく接続できている。
pg_dumpで外部サーバに接続する場合は、同じユーザを作成し、ルートに .pgpass を作成
書き方は
192.168.0.XXX:5432:DB名:ユーザ名:パスワード
複数のDBがある時は、
192.168.0.xxx:5432:*:user:password でOK
$ chmod 600 .pgpass パーミッションは600指定
パーミッション600にしないと、エラーになった。
$ pg_dump -Ft -h 192.168.0.xxx -p 5432 -U user -w dbName > /home/user/dbName_`date '+%y%m%d%H%M'`
-wがパスワード請求無しのオプション
こんな感じでdump出来るので、これをシェルスクリプトにして、crontabに書いて終了。
pgsql --version
psql (PostgreSQL) 9.2.18
起動テストをしてみる。
# systemctl start postgresql.service
Job for postgresql.service failed because the control process exited with error code. See "systemctl status postgresql.service" and "journalctl -xe" for details.
初期化が必要だった。
# service postgresql initdb
Hint: the preferred way to do this is now "postgresql-setup initdb"
Initializing database ... OK
動かしてみる。
# systemctl start postgresql.service
[root@localhost ~]# systemctl status postgresql.service
● postgresql.service - PostgreSQL database server
Loaded: loaded (/usr/lib/systemd/system/postgresql.service; disabled; vendor preset: disabled)
Active: active (running) since 月 2018-06-04 18:54:47 JST; 12s ago
Process: 1627 ExecStart=/usr/bin/pg_ctl start -D ${PGDATA} -s -o -p ${PGPORT} -w -t 300 (code=exited, status=0/SUCCESS)
Process: 1619 ExecStartPre=/usr/bin/postgresql-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
Main PID: 1630 (postgres)
CGroup: /system.slice/postgresql.service
tq1630 /usr/bin/postgres -D /var/lib/pgsql/data -p 5432
tq1631 postgres: logger process
tq1633 postgres: checkpointer process
tq1634 postgres: writer process
tq1635 postgres: wal writer process
tq1636 postgres: autovacuum launcher process
mq1637 postgres: stats collector process
6月 04 18:54:46 localhost.localdomain systemd[1]: Starting PostgreSQL database server...
6月 04 18:54:47 localhost.localdomain systemd[1]: Started PostgreSQL database server.
動いた。
一旦停止して、外部からのアクセスが出来るようにする。
# nano /var/lib/pgsql/data/postgresql.conf
L60位のlisten_addressを許容
listen_addresses = '*' # what IP address(es) to listen on;
# nano /var/lib/pgsql/data/pg_hba.conf
末尾にIPアドレスの設定
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 trust
# Allow replication connections from localhost, by a user with the
# replication privilege.
#local replication postgres trust
#host replication postgres 127.0.0.1/32 trust
#host replication postgres ::1/128 trust
# for server
host all all 192.168.xxx.0/24 password
host all all 192.168.xxx.0/24 password
host all all 192.168.xxx.0/24 password
# for vendor
host all all xxx.xxx.xxx.xxx/28 password
firewallを開放
# firewall-cmd --add-service=postgresql --permanent
success
# systemctl restart firewalld.service
再度起動
恐らく問題なく接続できている。
pg_dumpで外部サーバに接続する場合は、同じユーザを作成し、ルートに .pgpass を作成
書き方は
192.168.0.XXX:5432:DB名:ユーザ名:パスワード
複数のDBがある時は、
192.168.0.xxx:5432:*:user:password でOK
$ chmod 600 .pgpass パーミッションは600指定
パーミッション600にしないと、エラーになった。
$ pg_dump -Ft -h 192.168.0.xxx -p 5432 -U user -w dbName > /home/user/dbName_`date '+%y%m%d%H%M'`
-wがパスワード請求無しのオプション
こんな感じでdump出来るので、これをシェルスクリプトにして、crontabに書いて終了。
登録:
投稿 (Atom)