end0tknr's kipple - web写経開発

太宰府天満宮の狛犬って、妙にカワイイ

python における package , module , class や、import , class継承

javaや、javascript , perl ,php 等と、 python における package , module , class や、import , class継承 は 実装方法が異なる為、メモ。というか、練習。

ポイントは、init.py における 各moduleのimportと、一括new。

dir構成

caller.py
package/
   __init__.py
   base_module.py
   module_a.py
   module_b.py

各fileの内容

継承関係は、各file内容で確認して下さい

caller.py

#!python
# -*- coding: utf-8 -*-
import os
import sys
sys.path.append( os.path.dirname(__file__) )

import package

def main():
#    print(sys.path)
    print( package.sub_classes['Class1inModuleA'].hoge() )
    print( package.sub_classes['Class1inModuleB'].hoge() )

if __name__ == '__main__':
    main()

package/init.py

import glob
import inspect
import os
import sys
sys.path.append( os.path.dirname(__file__) )

# refer to https://qiita.com/suzuki-kei/items/8fea67655abf216a5013
# __all__ = [
#     os.path.split(os.path.splitext(file)[0])[1]
#     for file in glob.glob(os.path.join(os.path.dirname(__file__), '[a-zA-Z0-9]*.py'))
# ]

import base_module
import module_a
import module_b

sub_classes  = {}
modules_tmp = [module_a, module_b]

for module_tmp in modules_tmp:
    sub_classes_tmp = inspect.getmembers(module_tmp, inspect.isclass)
    
    for sub_class_tmp in sub_classes_tmp:
        sub_class_name = sub_class_tmp[0]
        sub_class      = sub_class_tmp[1]()
        sub_classes[ sub_class_name ] = sub_class

package/base_module.py

import sys

class BaseClass():
    def hoge(self):
        class_name = self.__class__.__name__
        func_name  = sys._getframe().f_code.co_name
        return " ".join(["classname & func name =", class_name,"&",func_name])

package/module_a.py

import sys

class Class1inModuleA():
    def hoge(self):
        class_name = self.__class__.__name__
        func_name  = sys._getframe().f_code.co_name
        return " ".join(["classname & func name =", class_name,"&",func_name])

package/module_b.py

import base_module

class Class1inModuleB(base_module.BaseClass):
    pass

上記の実行結果

正しく継承できていることが分かります。

..\python38\python.exe .\caller.py
classname & func name = Class1inModuleA & hoge
classname & func name = Class1inModuleB & hoge

powershellで、openldapに接続し、検索

$domain = "LDAP://ldap.mile.sexy.co.jp/ou=people,o=sexy-group"
$auth = [System.DirectoryServices.AuthenticationTypes]::FastBind
$root = New-Object System.DirectoryServices.DirectoryEntry($domain,"", "", $auth)

$query = New-Object System.DirectoryServices.DirectorySearcher($root,"(uid=end0tknr)")
$entry = $query.FindOne()
#$entries = $query.FindAll()

$entry | %{$_.Properties}
$entry.Properties.cn
$entry.Properties."cn;lang-en-phonetic"

$entry.Properties.sexysnumber

# byte列で取得されるものは、asciiへ変換
$enc = [system.Text.Encoding]::ASCII
$entry.Properties.sexysnumber | %{$enc.GetString($_)}

↑こう書くと、↓こう表示されます

PS > .\find_ldap_2.ps1

Name                        Value
----                        -----
adspath                     {LDAP://ldap.mile.sexy.co.jp/uid=end0tknr,ou=people,o=sexy-group}
ou2                         { ないしょ byte列 ...
cn;lang-en-phonetic         { ないしょ}
mobilephonenumber           { ないしょ byte列 }
sn                          { ないしょ}
sexyauthdepartment          { ないしょ byte列 }
mail                        {end0tknr@sexy.com}
givenname;lang-ja-phonetic  { ないしょ}
   :
X88882929

phpで、全角スペースを含んだtrim

とりあえず?、以下のように書くと、動くように見えます

function my_trim($org_str){
    //    return trim($org_str,"  \t\r\n\0\x0B");
    //  当初↑こう書きましたが、謎の文字化けが発生した為、以下のようにしました
    return preg_replace('/\A[\p{Cc}\p{Cf}\p{Z}]++|[\p{Cc}\p{Cf}\p{Z}]++\z/u',
                        '',
                        $org_str);
}

phpのPDOによるmysql / postgres接続練習

mysqlの場合

<?php
$db_name = 'mysql:dbname=test;host=localhost';
$db_user = 'root';
$db_pass = 'ないしょ';
//以下のoptionにより、PDOException が発生
$db_opt  = [PDO::ATTR_ERRMODE =>PDO::ERRMODE_EXCEPTION];

try {
    $dbh = new PDO($db_name,$db_user,$db_pass,$db_opt);
} catch (PDOException $e) {
    exit('ERROR fail PDO() ' . $e->getMessage());
}

$sql = 'select * from test_tbl where id<=:id';

try {
    $sth = $dbh->prepare($sql);
    $sth->bindValue(':id', 1);
    $sth->execute();
} catch (PDOException $e) {
    exit('ERROR fail sql ' . $e->getMessage());
}


// $ret_rows = $sth->fetchAll(PDO::FETCH_ASSOC);
// var_dump($ret_rows);

while($ret_row = $sth->fetch(PDO::FETCH_ASSOC)){
    var_dump($ret_row);
}
?>

↑こう書くと、↓こう表示されます

$ php foo_mysql.php 
array(2) {
  ["id"] => string(1) "1"
  ["val"]=> string(4) "VAL1"
}

postgresの場合

と言っても、先程のmysqと比較して、接続時の $db_name が異なる程度です

<?php
//$db_name = 'mysql:dbname=test;host=localhost';
$db_name = 'pgsql:dbname=db_rear_hon host=localhost port=5432';

$db_user = 'ないしょ';
$db_pass = 'ないしょ';
//以下により PDOException が有効化
$db_opt  = [PDO::ATTR_ERRMODE =>PDO::ERRMODE_EXCEPTION];

try {
    $dbh = new PDO($db_name,$db_user,$db_pass,$db_opt);
    $sql = "SET NAMES 'UTF8'";
    $sth = $dbh->prepare($sql);
    $sth->execute();
} catch (PDOException $e) {
    exit('ERROR fail PDO() ' . $e->getMessage());
}

$sql = 'select * from test_tbl where id<=:id';

try {
    $sth = $dbh->prepare($sql);
    $sth->bindValue(':id', 1);
    $sth->execute();
} catch (PDOException $e) {
    exit('ERROR fail sql ' . $e->getMessage());
}


// $ret_rows = $sth->fetchAll(PDO::FETCH_ASSOC);
// var_dump($ret_rows);

while($ret_row = $sth->fetch(PDO::FETCH_ASSOC)){
    var_dump($ret_row);
}
?>

mysqlの"show create table" のpostgresにおける代替は、"pg_dump --schema-only"

以下の通り

mysql> desc test_tbl;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id    | int          | NO   | PRI | NULL    |       |
| val   | varchar(256) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> show create table test_tbl;
+----------+----------------------------------------------------------------------+
| Table    | Create Table                                                         |
+----------+----------------------------------------------------------------------+
| test_tbl | CREATE TABLE `test_tbl` (                                            |
              `id` int NOT NULL COMMENT 'これはtest_tbl.idのcomment',             |
              `val` varchar(256) DEFAULT NULL,                                    |
              PRIMARY KEY (`id`)                                                  |
              ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci  |
          COMMENT='これはtest_tblのcomment'                                   |
+----------+----------------------------------------------------------------------+

上記 mysqlの"show create table" のpostgresにおける代替は、以下。

$ /usr/bin/pg_dump -U postgres --dbname=db_rear_hon \
                   --schema-only --table=test_dbl

ちなみに、mysqlのmysqldumpでは、以下。

$ /usr/bin/mysqldump -u root -p test --no-data test_tbl

mysqlやpostgresにおける tableやcolumnへのコメント追加と確認

コメント関連の操作は、DBMS製品毎に異なる為、以下にメモ

mysql の場合

まずは、テーブル作成

create table test_tbl (
id         int primary key comment 'これはtest_tbl.idのcomment',
val        varchar(256)
)
comment='これはtest_tblのcomment';

上記で作成したコメントは、通常?の desc では表示されない為、 "show table status like ~" または "show create table ~"を使用します。

mysql> desc test_tbl;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id    | int          | NO   | PRI | NULL    |       |
| val   | varchar(256) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
mysql>  show table status like 'test_tbl';
+----------+--------+~+---------------------+~+--------------------------------------+
| Name     | Engine |~| Create_time         |~| Comment                              |
+----------+--------+~+---------------------+~+--------------------------------------+
| test_tbl | InnoDB |~| 2021-01-31 10:15:41 |~| これはtest_tblのcomment              |
+----------+--------+~+---------------------+~+--------------------------------------+

mysql> show full columns from test_tbl;
+-------+--------------+--------------------+------+~+--------------------------------+
| Field | Type         | Collation          | Null |~| Comment                        |
+-------+--------------+--------------------+------+~+--------------------------------+
| id    | int          | NULL               | NO   |~| これはtest_tbl.idのcomment     |
| val   | varchar(256) | utf8mb4_0900_ai_ci | YES  |~|                                |
+-------+--------------+--------------------+------+~+--------------------------------+
mysql>  show create table test_tbl;
+----------+---------------------------------------------------------------------------+
| Table    | Create Table                                                              |
+----------+---------------------------------------------------------------------------+
| test_tbl | CREATE TABLE `test_tbl` (                                                 |
|          |  `id`  int NOT NULL COMMENT 'これはtest_tbl.idのcomment',                 |
|          |  `val` varchar(256) DEFAULT NULL,                                         |
|          |   PRIMARY KEY (`id`)  )                                                   |
|          |   ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci        |
|      |   COMMENT='これはtest_tblのcomment'                                       |
+----------+---------------------------------------------------------------------------+

postgres の場合

まずは、テーブル作成ですが、mysqlと異なり、 "create table"とは別に"COMMENT ON ~"を実施する必要があります

create table test_tbl (
id         int primary key,
val        varchar(256)
);

COMMENT ON TABLE  test_tbl    IS 'これはtest_tblのcomment';
COMMENT ON COLUMN test_tbl.id IS 'これはtest_tbl.idのcomment';

次に "\dt+", "\d+"などで作成したコメントを表示します。

postgres=> \dt+ test_tbl
                           List of relations
 Schema |   Name   | Type  | Owner  |  Size   |       Description       
--------+----------+-------+--------+---------+-------------------------
 public | test_tbl | table | bbuser | 0 bytes | これはtest_tblのcomment
postgres=> \d+ test_tbl
          Table "public.test_tbl"
 Column |          Type          |~| Storage  |~|        Description         
--------+------------------------+~+----------+~+----------------------------
 id     | integer                |~| plain    |~| これはtest_tbl.idのcomment
 val    | character varying(256) |~| extended |~| 
Indexes:
    "test_tbl_pkey" PRIMARY KEY, btree (id)
Access method: heap
postgres=> select pg_stat_user_tables.relname as TABLE_NAME,
postgres->        pg_description.description  as TABLE_COMMENT
postgres-> from   pg_stat_user_tables,
postgres->        pg_description
postgres-> where  pg_stat_user_tables.relname in
postgres->          (select relname as TABLE_NAME
postgres(>           from   pg_stat_user_tables) and
postgres->         pg_stat_user_tables.relid=pg_description.objoid and
postgres->         pg_description.objsubid=0;

 table_name |      table_comment      
------------+-------------------------
 test_tbl   | これはtest_tblのcomment

install postgres12 from AppStream to centos8 by yum

ポイントは「yum module list」等のyumモジュールと「peer認証」かと思います。

install

まずは、postgresqlのモジュール一覧 確認

$ sudo yum module list postgresql
CentOS-8 - AppStream
Name         Stream      Profiles             Summary                                       
postgresql   9.6         client, server [d]   PostgreSQL server and client module           
postgresql   10 [d][e]   client, server [d]   PostgreSQL server and client module           
postgresql   12          client, server [d]   PostgreSQL server and client module           
Hint: [d]efault, [e]nabled, [x]disabled, [i]nstalled

上記のように、defaultでは、postgrs10の為、一旦、resetし、install

$ sudo yum install @postgresql:12/server
Dependencies resolved.
The operation would result in switching of module 'postgresql' stream '10' to stream '12'
Error: It is not possible to switch enabled streams of a module.
It is recommended to remove all installed content from the module,
and reset the module using 'yum module reset <module_name>' command.
After you reset the module, you can install the other stream.

$ sudo yum module reset postgresql

$ sudo yum install @postgresql:12/server
$ sudo yum install @postgresql:12/client

initdb や postgres の起動

$ sudo /usr/bin/postgresql-setup --initdb
 * Initializing database in '/var/lib/pgsql/data'
 * Initialized, logs are in /var/lib/pgsql/initdb_postgresql.log

$ sudo systemctl enable postgresql
$ sudo systemctl start  postgresql

$ /usr/bin/psql --version
psql (PostgreSQL) 12.5

defaultの peer 認証を trustへ変更

defaultでは、"su - postgres" した上で、 "/usr/bin/psql -U postgres"する必要がある為。

$ /usr/bin/psql -U postgres
psql: error: FATAL:  Peer authentication failed for user "postgres"

$ sudo su - 
# pwd
/var/lib/pgsql/data
# cp pg_hba.conf pg_hba.conf.20210131
# vi pg_hba.conf

        #TYPE  DATABASE  USER  ADDRESS  METHOD
   old) local  all       all            peer
   new) local  all       all            trust


$ /usr/bin/psql -U postgres
  psql (12.5)
  Type "help" for help.
  postgres=# 

ユーザ(ロール)追加

$ /usr/bin/psql -U postgres

postgres=# CREATE ROLE testuser LOGIN PASSWORD 'testuser';
postgres=# ALTER  ROLE testuser WITH CREATEDB CREATEROLE LOGIN;

postgres=# \du
                                   List of roles
 Role name |                         Attributes                         | Member of 
-----------+------------------------------------------------------------+-----------
 testuser  | Create role, Create DB                                     | {}
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

PASSWORDロールも追加すると、psqlによるログイン時にパスワード入力を求めれるようです。 (試していませんが)

データベース追加 (create database)

先程の追加ユーザをオーナとする為、以下のように行います。

$ /usr/bin/psql -U testuser postgres

postgres=> CREATE DATABASE db_rear_hon
           ENCODING='EUC_JP' LC_COLLATE='C' LC_CTYPE='C'
           TEMPLATE='template0';
       
postgres=> \l
                                   List of databases
    Name     |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
-------------+----------+----------+-------------+-------------+-----------------------
 db_rear_hon | testuser | EUC_JP   | C           | C           | 
 postgres    | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 template0   | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
             |          |          |             |             | postgres=CTc/postgres
 template1   | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
             |          |          |             |             | postgres=CTc/postgres

本番移行前のSMTP serverから、インターネット上へのメール配信を禁止(postfix)

実は、前回のエントリである  install postfix from package to amazon linux2 - end0tknr's kipple - web写経開発 は、本エントリの為のものです。

で、 本番移行前のSMTP serverから、インターネット上へのメール配信を禁止するには、

  • /etc/postfix/main.cf
  • /etc/postfix/transport を編集し、いずれのドメイン宛のメールを、自身のSMTPサーバで受信すれば、良い気がします。

参考url

準備

## mydestination にて、どのメールも自身で受け取る用に変更
$ sudo vi /etc/postfix/main.cf

old) mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
new) mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain, *

old) 
new) transport_maps = hash:/etc/postfix/transport

## transportファイルにて各メールの配送先、または削除を指定
$ sudo vi /etc/postfix/transport
$myhostname     local:
localhost.$mydomain local:
localhost,      local:
$mydomain       local:
*           local:
#*          discard: "discard received email"


## postfix再起動
$ sudo systemctl restart postfix

テスト

後は、mailコマンドで配信テストを行い、 結果を、Maildirや /var/log/maillog でご確認下さい。

$ echo "TEST MAIL MESSAGE BODY" | \
  mail -v \
     -s "TEST MAIL SUBJECT" \
     -S smtp=smtp://localhost:25 \
     -r test-mail@hogehoge.com \
     ec2-user@gmail.com

install postfix from package to amazon linux2

postfixによるsmtpメール送信の練習メモです

目次

1. 参考url

2. 全体構成

構築の中心は、以下のSMTP serverで、 AWS内の SMTP server(ec2) から、SMTP(port25)で、Gmailのアドレスへメール送信します。

OP25B(Outbound Port 25 Blocking)により、外向けのSMTP(port25)は通常ブロックされますので、 AWSに対しては、以下のurlから制限解除申請を行っています。

https://aws-portal.amazon.com/gp/aws/html-forms-controller/contactus/ec2-email-limit-rdns-request:tile

また、私の場合、自宅でJ:COMをプロバイダとして利用していますが、 AWSのような制限解除申請はないようですので、 AWS内のSMTP client(ec2)へ、一旦、ssh接続した上で、SMTPコマンドを実行しています。

┌Google─────┐
│┌──────┐│
││Gmail       ││
│└──────┘│
└───↑────┘
        │ssh【Port25】
┌AWS ─↓────┐
│┏━━━━━━┓│
│┃SMTP server ┃│
│┗━━━━━━┛│
│      ↑smtp(Port25)
│┌──┴───┐│
││SMTP client ││
│└──────┘│
└───↑────┘
        │ssh
┌J:COM │────┐
│┌──┴───┐│
││自宅PC      ││
│└──────┘│
└────────┘

3. OS関連の確認や、ホスト名、タイムゾーン変更

$ ssh -i ~/.ssh/end0tknr_202008.pem ec2-user@$IPアドレス内緒

amazon linux2 の version 確認

$ cat /etc/os-release 
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"

$ uname --all
Linux ip-172-31-15-199.ap-northeast-1.compute.internal
4.14.209-160.339.amzn2.x86_64 #1 SMP Wed Dec 16 22:44:04 UTC 2020
x86_64 x86_64 x86_64 GNU/Linux

ホスト名や timezone 変更

$ sudo hostnamectl set-hostname mailp.end0tknr.com
$ sudo vi /etc/sysconfig/clock
#ZONE="UTC"
ZONE="Asia/Tokyo"
UTC=true

$ sudo ln -sf  /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

$ sudo reboot

default installedなpostfixや、postfix関連userの確認

いずれも、amazon linux2ではdefault installされています

postfix

$  yum list installed |grep postfix
postfix.x86_64                        2:2.10.1-6.amzn2.0.3             installed
[ec2-user@mailp ~]$

postfixプロセス

# ps -ef | grep -i post
root      2951     1  0 00:40 ?        00:00:00 /usr/libexec/postfix/master -w
postfix   2952  2951  0 00:40 ?        00:00:00 pickup -l -t unix -u
postfix   2953  2951  0 00:40 ?        00:00:00 qmgr -l -t unix -u

# netstat -ln | grep 25
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN

# systemctl stop postfix
# systemctl disable postfix
Removed symlink /etc/systemd/system/multi-user.target.wants/postfix.service.

postfixユーザとグループ

$ id postfix
uid=89(postfix) gid=89(postfix) groups=89(postfix),12(mail)

$ cat /etc/group | grep post
mail:x:12:postfix
postdrop:x:90:
postfix:x:89:

4. DNS登録

AWSのRoute53で、MXレコードを次のように登録しています。

$ nslookup -type=mx end0tknr.com
Non-authoritative answer:
end0tknr.com    mail exchanger = 10 mailp.end0tknr.com.

5. postfix設定変更 - /etc/postfix/main.cf

/etc/postfix/main.cf の編集

$ sudo cp /etc/postfix/main.cf /etc/postfix/main.cf.20210101

$ sudo vi /etc/postfix/main.cf

## 以下の mailp の「p」はpackageの意味です
old) # myhostname = 
new) myhostname = mailp.end0tknr.com

old) # mydomain =
new) mydomain = end0tknr.com

## inet_interfacesは、リモートからの SMTP 接続OKとする為、allに
old) #inet_interfaces = all
old) inet_interfaces = localhost
new) inet_interfaces = all
new) #inet_interfaces = localhost

## inet_interfacesは、リモートからの SMTP 接続OKとする為、
## 0.0.0.0/0 を追加していますが、本来は良くない気がします。
old) #mynetworks = 127.0.0.0/8 172.31.0.167/32
new) mynetworks = 127.0.0.0/8 0.0.0.0/0

new) home_mailbox = Maildir/

## 自host宛のmailとして扱うドメイン?一覧
old) mydestination = $myhostname, localhost.$mydomain, localhost
new) mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain

## SMTP送信自体に直接の関係はありませんが、メールボックスはMaildir形式
old) # home_mailbox = Maildir/
new) home_mailbox = Maildir/

postconf コマンドによる postfix設定内容の確認

/sbin/postconf コマンドを引数なし、または 引数ありで実行すると、 default値を含めた設定内容を表示できます。

$ /sbin/postconf
2bounce_notice_recipient = postmaster
access_map_defer_code = 450
access_map_reject_code = 554
<略:対象に出力されます>
virtual_transport = virtual
virtual_uid_maps =

$ /sbin/postconf mydestination
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain

設定完了後、postfix再起動

$ sudo systemctl restart postfix

6. 動作確認

Gmail等からメール送信し、SMTP serverへの配信確認

Gmail等からメール送信

先程までで、postfixの設定は完了していますので、 試しに ec2-user@endotknr.com 宛にGmail等から、メール送信して下さい。

メールの受信確認

その後、SMTP server へssh接続し、 /home/ec2-user/Maildir/new を見ると、受信したメールのファイルを確認できます。

$ ls -lh /home/ec2-user/Maildir/new
total 4.0K
-rw------- 1 ec2-user 2.4K Jan 14 17:01 1610611306.Vca01I3c00062M491241.mailp.end0tknr.com

/var/log/maillog の確認

配信されたログも確認できますので、以下のようにご確認をお願いします。

$ sudo less /var/log/maillog

SMTP client & server から、Gmailへの配信確認

mailコマンド install

$ sudo yum install mailx
$ which mail
/usr/bin/mail

mailコマンドでメール送信

SMTP clientへ、ssh後、SMTP clientから送信

$ echo "TEST MAIL MESSAGE BODY" | \
  mail -v \
     -s "TEST MAIL SUBJECT" \
     -S smtp=smtp://mailp.end0tknr.com:25 \
     -r test-mail@hogehoge.com \
     ないしょ@gmail.com

SMTP server 自身(localhost)から送信

echo "TEST MAIL MESSAGE BODY" | \
  mail -v \
     -s "TEST MAIL SUBJECT" \
     -S smtp=smtp://localhost:25 \
     -r test-mail@hogehoge.com \
     ないしょ@gmail.com

「/usr/sbin/sendmail -t」のダミーを perlで書く

Postfixの用意までは行いたくない。以下の程度で十分かと思います。

#!/usr/bin/perl
use utf8;
use strict;
use warnings;

my $OUT_FILE = "/tmp/sendmail_dummy";

main(@ARGV);

sub main {
    my ($cmd_opt) = @_;

    if ($cmd_opt ne "-t"){
        print STDERR "USAGE: $0 -t < STDIN  or  echo 'HOGE'| $0 -t\n";
        return;
    }
    
    my @stdin_lines = <STDIN>;

    open(my $fh, ">>", $OUT_FILE) or die "fail open() $OUT_FILE $!";
    print $fh @stdin_lines;
    print $fh "\n\n";
    close($fh) or die "fail close() $OUT_FILE $!";
}

上記に対するテスト実施は以下の通り

$ vi ./test_sendmail.sh

#!/usr/bin/bash

/usr/bin/cat << _EOM_ | /sbin/sendmail -t
From: test-from@example.com
To: test-to@example.com
Subject: TEST SENDMAIL SUBJECT

TEST SENDMAIL SUBJECT
MESSAGE BODY
_EOM_

scriptコマンドで、linux ログインユーザの作業操作ログを typescript へ記録

以下のようにbashで書いて、/etc/profile あたりから実行すれば、OK かと思います。

ざっと書いただけのscriptで殆ど、動作確認していません。 特に「su - 」によるユーザ切替後の出力先ログ等が、少々、心配。

#!/bin/sh

LOG_DIR=/var/log/typescript

#login日時
LOG_DATE=`date +'%Y%m%d_%H%M%S'`

#loginユーザ
LOG_USER=`/usr/bin/id --user --name` 

LOGFILE=$LOG_DIR/logincheck_${LOG_DATE}_${LOG_USER}_$$.log


#端末device
TTY=`tty`
TTY=`echo $TTY | sed -e "s/\/dev\///"`


DATE=`date +'%Y/%m/%d %H:%M:%S'`
echo "Logging Start by $REALNAME at $DATE" >> $LOGFILE
last | /bin/grep -E "$TTY" | head -1 >> $LOGFILE

script -a $LOGFILE
exit
# vi /etc/profile

/opt/my_typescript.sh  #### ADD

PyCaret - 機械学習 自動化ツール by python

メモ。おもしろそう。

hands-onとしては、以下のurlにある「Tableauから始めるデータサイエンス」を 写経するとよさそう。

pycaret.org

github.com

lovedata.main.jp

TODO - 画像認識で検出した物体(図形)の回転角度や反転を求める

画像認識で検出した物体(図形)の回転角度に加え、反転を求めるには、 次の手法のいずれか、または、これらの組み合わせで実現できる気がする。

以下は、改めて調べる為のメモ書きです。

OpenCV の minAreaRect() を利用

領域(輪郭)の特徴 — OpenCV-Python Tutorials 1 documentation

Python - CNNで物体の向き検出|teratail

OpencvのminArearectで回転角度の計算 - how to code something

OpenCVで外接矩形と回転角の算出 - how to code something

OpenCV の matchShapes() を利用

cv::matchShapesによる形状マッチングを試してみた - Qiita

輪郭の探究 - Emotion Explorer

OpenCV - matchShape で輪郭の類似度を計算し、マッチングする方法について - pystyle

テンプレート・マッチング

具体的なurlを見つけることはできませんでしたが、 想定している回転角は、45°毎ですので、左右反転を考慮し、 8枚 x 2 = 16枚のテンプレートを用意し、これとマッチングを行えば、 よい気がします。

その他

OpenCV - 特徴点マッチングで物体検出、移動、回転量を推定する - pystyle