サブルーチンの確認
perlで自作したおひとり様ActivityPubサーバーはその後も増築改築をちまちま続けていて、例によってその場での思いつき、やっつけ仕事の現物合わせ仕様で、わけわかめ状態となっている。
Activityを約束事どおりに対応するモジュール(pmファイル)で、いったい何をしてるのか。
もうすでに忘れてる自分がいるので、サブルーチンの洗い出し用にテキトーなスクリプトをでっちあげた。という覚え書きが今回のエントリ。
#!/usr/bin/perl
use strict;
use utf8;
use Encode;
my $f = shift(@ARGV);
if(! -e $f ){
printf qq{Not Found pm %s\n}, $f;
exit;
}
open(IN, $f) || die;
my $name; my @buf=<IN>; close(IN);
foreach (@buf){
if( m!^sub (.+) *\{! ){
$name->{$1}++;
}
}
printf qq{sum : %s\n}, scalar( keys %{$name} );
foreach my $sub (sort keys %{$name}){
my $pm = join('', @buf);
my $cnt = $pm =~ s!$sub!!g;
printf qq{%s :\n}, $sub;
my @called; my $zzz;
if( $cnt > 1 ){
my $subname;
foreach (@buf){
if(m!^sub (.+) *\{!){
$subname = $1;
next;
}
if( m!\$self\-\>$sub! && !$zzz->{$subname}++ ){
push(@called, $subname);
}
}
}
printf qq{\t%s\n}, join("\t", sort @called);
}
・サブルーチンの総数
・サブルーチンの名前
・サブルーチンを呼び出しているサブルーチン
ぐらい見えれば、そこそこ役に立つかなあ、と。
文字列検索でひっかけてるだけで、signなんかはサブルーチン呼び出しじゃない部分にもヒットする。本当は動かしながらcaller()でチェックするのが確実…だけど、ざっくり見るだけのためにあちこちにcaller()を仕込むのはうっとーしいんで却下。
使い捨てのつもりで書いたスクリプトだけど、思ったよりちゃんと見えるようにしてくれたので自画自賛&エントリとして書き起こし
10/4、ポケモンGOの対人戦GBLでACEに到達。
初期レートが1984で、ACE到達時のレートは2007。GBLで遊んでいて、ずっと継続してACEにたどり着いてたんだけど、前期初めてACEに到達できず、今期もやべえかなあ、と思ってたので、ほっとひと息。
まる6年続いているゲームで、まだ全然飽きないのがすげーす。
» ローカル環境で電子書籍を作る、Macアプリ・Windows版ツール 「かんたんEPUB3作成easy_epub」
ファイル同期のためのrsyncで使うオプション
仕事で使っているchromebook2台でスクリプトファイル類を同期しておきたい。
そのためにメイン機から更新のあった(タイムスタンプが新しい)ものだけをコピーしたい。
てな時にlinuxだとrsyncが便利。
scpやsftpもあるけどscpもsftpもタイムスタンプを比較できないっぽいので、今回のような場合はrsync一択。
unix系ツールの例に漏れず、rsyncもオプションが豊富ですぐにわけわからなくなってるんで、自分の使う範囲のオプションをメモ。
rsync --include="*.pl" --include="*.pm" --exclude="*" -auv -e "ssh -p 10022" [ローカルディレクトリ] ユーザー名@192.168.0.NN:[リモートディレクトリ]
--incluce="*.pl"
--incluce="*.pm"
同期したい対象ファイルは拡張子が「pl」か「pm」
--exclude="*"
includeしたもの以外は同期対象外
↑これがわかりにくくて、includeとexcludeの順番がだいじ。
まず、対象を指定して、最後にそれ以外全部除外という命令になっている、らしい。
-a
以下全部をまとめて指定
・ディレクトリを再帰的に処理する
・シンボリックリンクをシンボリックリンクのままコピーする
・パーミッションを保持する
・タイムスタンプを保持する
・所有グループをそのまま保持する
・所有者をそのまま保持する(自分以外の所有者を保持するにはroot権限が必要)
・デバイスファイルや特殊ファイルを保持する(「--devices --specials」相当
-u
・更新のあったものだけをコピーする
-v
・転送状況を表示する
-e "ssh -p 10022"
・sshで接続する。ポート番号指定つき
わたしの場合は、以上で意図通りに同期される。実際にrsyncを走らせる前に
-n
--dry-run
↑このふたつは、どちらもrsyncを走らせるけど、実際はコピーをしない。コマンドが意図したものになっているか確認するために使うオプション。
--delete
↑コピー元になくて、コピー先だけあるファイルを削除するオプション。deleteから始まるオプションはあぶないのでよっぽどのことがない限り使わない。
rsyncコマンドはコピー元、リモートのコピー先、両方に必要。
(リモートにインストールしてなくて、コマンドが見つかりませんとハマったのは内緒)
ローカルにあるディレクトリごと、USBメモリなんかに同期させるだけなら
from=/mnt/chromeos/removable/USBDrive/_works
to=/mnt/chromeos/removable/_TMP/_works
if [ -d $from ] && [ -d $to ]; then
rsync -anu --delete --log-file=$to/rsync2usb-works.log $from/ $to/
fi
バックアップというより、持ち出して作業する一時的な扱いなので、こういうのは「--delete」をつけて、ローカルにないファイル・ディレクトリはUSBから削除してくれるので便利…でも、くれぐれも「delete」は要注意
[09/19 00:26:35]追記
ディレクトリ指定に注意が必要だった。
ローカルdir1/ リモートdir1
「/」がついてると、ローカルdir1に配置されているファイルがリモートdir1のファイルと同期される。
ローカルdir1 リモートdir1
「/」がついてないと、「リモートdir1/ローカルdir1」とローカルdir1がディレクトリごとリモートdir1の下にコピーされる。
» ローカル環境で電子書籍を作る、Macアプリ・Windows版ツール 「かんたんEPUB3作成easy_epub」
chromebookでssh
chromebook同士でファイル共有する方法としてニアバイシェアというのがあるけど、なんか思ってたのと違う。なので、sshで繋いでファイルのやりとりを直接やってしまおう、のメモ。
chromebookを2台使っていて、メインとサブという役割分担。
メインで使っていて作業した内容をサブ機にsshで転送・バックアップしておきたい。
まずはchromebookの設定。メイン機のLinux環境からサブ機のLinux環境に繋ぐためにポート転送を設定する。道路を繋ぐための作業、みたいなもの。
サブ機側のポート転送を設定。
「ChromeOSについて→Linux開発環境→ポート転送」
ポート番号はすでに使われている番号以外ならなんでもOK
sudo less /etc/service
↑これで確認できる。とりあえず10001〜10080のあたりが空いてるので「10022」とした
ポート転送を設定することで
1)サブ機のローカルIPアドレス192.168.0.NNにSSHでポート番号を指定してアクセスする
2)サブ機側がポート転送してくれて、サブ機のLinux環境にログインできる
サブ機のLinux環境でsshdサービスを立ち上げる
(サブ機をsshdサーバーにする)
sshdサービスがどうなってるのか確認。
sudo systemctl status sshd.service
この時点では「Active: inactive (dead)」という表示が出ている。ssdは立ち上がっていないので、sshdを立ち上げるために以下の作業。
(sudo、root権限で/etc/以下のファイルを編集することになるので、念のためバックアップを取っておくのが安心安全)
「/etc/ssh/sshd_not_to_be_run」というファイルがあるとsshdが立ち上がらないらしいので削除
sudo rm /etc/ssh/sshd_not_to_be_run
「/etc/ssh/sshd_config」というのがsshdの設定ファイル。
Port 10022
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
PermitRootLogin no
UsePAM no
AcceptEnv LANG LC_*
chromebookのポート転送で指定したポート番号を記載。それ以外は呪文でOK(ルートでアクセス許可するかとか)で、上記以外はデフォルトのままでOK.
設定ファイルを編集したらsshdサービスを立ち上げる
sudo systemctl restart sshd.service
立ち上がってるか確認
sudo systemctl status sshd.service
「Active: active (running)」という表示が見えたら無事sshdのサービスは立ち上がっている。
サブ機のLinux環境のHOMEディレクトリに「.ssh」というディレクトリを作成。
chmod 700 .ssh
として、権限をオーナー限定にしておく。
メイン機でsshの秘密鍵と公開鍵を作る
ホームディレクトリで
ssh-keygen
途中パスフレーズ聞かれて、入力すると「id_rsa」(秘密鍵)「id_rsa.pub」(公開鍵)がHOMEディレクトリの「.ssh」ディレクトリに作られる。公開鍵以外の権限はオーナー限定(0600)
メイン機で作った公開鍵をサブ機のHOMEディレクトリの.sshディレクトリにコピー
scp -P 10022 id_rsa.pub ユーザー名@192.168.0.NN:~/.ssh/.
メイン機で作った公開鍵をサブ機にコピーしたら、サブ機で作業
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
サブ機の.sshディレクトリの「authorized_keys」というファイルに公開鍵を登録(追記コピーしてるだけ)
以上でsshは繋がる。
ssh -p 10022 -i id_rsa.pub ユーザ名@192.168.0.NN
とか
ssh -p 10022 -l ユーザー名 192.168.0.NN
メイン機からサブ機にログインしてごそごそいじったり
scp -P 10022 -r work ユーザ名@192.168.0.NN:work
などとメイン機からサブ機にファイルコピーしたり
sftp ユーザー名@192.168.0.NN:DIR
とか、sftpでログインしてアップしたいディレクトリに移動してから
put -r DIR/
などとメイン機からサブ機にディレクトリごとアップしたり、
ファイル操作がらくちんになった。
とはいえ、コマンドラインなので、上書き事故には気をつけないといけない、よなあ。
ちなみに注意するところがあって。
linux開発環境も、ポート転送も手動。chromebookを立ち上げたり、再起動したら
・Linux開発環境を立ち上げる
・ポート転送をONにする
…というのもあって、どうせ確認するわけだし、IPアドレスも自動割り当てのままにした。
以下のサイトを参考にさせていただきました(多謝
【Chromebook】SSHサーバの設定
ChromebookのLinuxコンテナにSSHでログインする
最近のネタ切れの時の弁当は2色、3色弁当。
なんかこういう手抜きの方が美味しかったりするから、ちょっと悔しい。
» ローカル環境で電子書籍を作る、Macアプリ・Windows版ツール 「かんたんEPUB3作成easy_epub」
ActivityPubの投稿公開範囲
あれ、どうするんだっけ?と忘れがちでしょっちゅう検索してしまう投稿の公開範囲をメモしておこう(間違ってるかもしれない…気がついたら修正)
ActivityPubで、Fediverseに投げ込んだNoteの公開範囲を選べる。
・全公開
誰でも見ることができる。
投稿が流れるタイムライン
→連合、ローカル、ホーム
・未収載
誰でも見ることができる。
投稿が流れるタイムライン
→ホーム
・フォロワー限定
フォロワーだけが見ることができる
投稿が流れるタイムライン
→ホーム
・ダイレクト(DM)
指定したお相手だけが見ることができる
タイムラインには流れない
※「ホーム」というのは、自分・フォロワーの「ホームタイムライン」
「未収載」と「フォロワー限定」がわかりにくいのでメモ
・未収載は
フォロワーのホームに投稿が流れる。自分をフォローしていないユーザーが、フォロワーのホームに流れている自分の投稿を見ることができる。
・フォロワー限定は
フォロワーのホームに投稿が流れる。自分をフォローしていないユーザーが、フォロワーのホームを見ても、自分の投稿は見えない。
投稿の公開範囲と宛先の組み合わせ
(Activityの指定)
公開/宛先 | to | cc |
---|---|---|
全公開 | Public | followers |
未収載 | followers | Public |
フォロワー限定 | followers | なし |
ダイレクト | お相手のinbox指定 | なし |
ActivityPubの約束事として公開範囲については上記で全部。
このほかに、もっと細かく公開範囲を指定できるサーバーもあって。
「Fedibrid」https://fedibird.com
「公開/未収載/フォロワー限定/相互フォロー限定(対応サーバーのみ)/サークル/DM/自分限定」
↑こちらは、今日時点で投稿の公開範囲は7種類から選べる。
公開範囲は意識しておきたいところだけど、うっかりやらかしてしまうので、自戒を込めてのエントリ。
ウチのおひとり様ActivityPubサーバーは。
設定ファイルのpublic_levelで公開か未収載を選択する。
・現在のデフォルトは公開
「to」がPublic、「cc」がわたしのfollowers
・Mentionとダイレクトは「to」がお相手のinbox
・Mentionの「cc」はわたしのfollowers
・ダイレクトの「cc」はなし
神田明神の妖怪展。有名なガシャドクロを始め、規模こそ小さかったけど、面白かった。
常設展もかなり面白かった。オススメ。
» ローカル環境で電子書籍を作る、Macアプリ・Windows版ツール 「かんたんEPUB3作成easy_epub」
小ネタ:pdftotextで文字データを抽出
元データがPDFで、圏点(傍点)やダッシュをPDFから検出する必要にせまられた。
目視確認などありえないんで、テキストデータとして取り出して検索しよう、というのが今回のエントリ…というかエントリにするまでもない内容なんだけど、たぶんそのうち忘れるんで、メモ。
PDFから文字情報だけをひっぱりだすのに定番の「pdftotext」というツールを使う。
perlだけでもできそうなんだけど(PDF::API2あたり)ちょっと時間も押してるんで、外部ツールを間に挟むことにした。
まずは肝腎のpdftotextのインストール。これがpoppler-utilsというパッケージだなんて検索しないとわからなかった(pdftotextというパッケージがあるもんだと思ってた)
以下のコマンドラインでインストール
sudo apt-get install poppler-utils
unix系のツールの例に漏れず、これもいろんなオプションが用意されてるけど、今回必要なのは文字情報だけ。レイアウトデザイン情報やなんかは不要。
rawオプションをつけて利用する。
たとえば「kappa.pdf」の文字情報を抜き出すのは
pdftotext -raw kappa.pdf
こうすると「kappa.txt」に文字情報を吐き出す。ただ、これだとひと文字ずつだあーっと出力されるので、ここからがテキストデータを扱わせたら最強のperlの出番。
pdftotextの出力には改ページがつくので、そこで改行すれば「それっぽい段落」ごとに見えるひとに優しいテキストファイルとなる。
open(P, '-|', 'pdftotext -raw kappa.pdf - ' ) || die;
binmode STDOUT => ":utf8";
open(OUT, '>' , 'kappa.txt') || die;
binmode OUT => ":utf8";
while(<P>){
my $line = Encode::decode('utf8', $_);
$line =~ s!\r?\n!!;
$line =~ s!\x{C}!\n!;
print OUT $line;
}
close(OUT);
close(P);
特筆すべきようなスクリプトじゃないんだけど。
perlは外部コマンドの「標準出力」をパイプで受け取って加工整形できる。
open(P, '-|', 'pdftotext -raw kappa.pdf - ' )
openの
・第2引数で、標準出力を受け取りますよ、という指定
・第3引数はpdftotextの結果を標準出力に出すからね、という指定
これだけでそれっぽい段落にわけたテキストファイルを作ってくれる。
そうしたら、あとは出力されたテキストファイルからダッシュや圏点(傍点)っぽいものをperlで検知するだけ。これはワードで作ったPDFで「、」が圏点となっている。inDesignで作られたデータだと「0」(ゴマ)「4」(ドット)となる。
直接触ってもいいんだけど、一度テキストファイルに吐き出したほうがなにかわからないことが起こった時に便利なので、こういう仕様、段取り。
このスクリプトのおかげで抜け漏れは捕捉できるんでずいぶんラクになった。
以前、目視確認とか無駄なだけだし、んなもんツール作ってやればいいじゃん、とか言ったら、そしたら仕事がなくなる、目視確認手作業修正は必須だ、と言われて心底、呆れた。
カネをもらった上で、人間の作業=ミスが入り込む原因になる工程を入れるって、いろいろ悪質すぎる。
ITといってもピンキリで、こんなのが入り込んでるから要注意。
そもそも、その程度の仕事なんて、なくなっても問題ないし、特に困らない。
» ローカル環境で電子書籍を作る、Macアプリ・Windows版ツール 「かんたんEPUB3作成easy_epub」
電子書籍でエラーになる絵文字の検知
今回のエントリは。
経緯
・電子書籍でエラーになるのが絵文字だった。
・元データから絵文字を検知する必要が出てきた。
結論
・perlを使えば絵文字のチェックも簡単だった。
てことなんだけど、調べてみたらunicodeまわりが魔窟でびっくり。またハマりそうなのでメモ。
以下は、何を今さらという話が無駄に長くて、既知のかたには役に立たない内容です。
電子書籍に求められる基準はほぼ以下のふたつ
・Epubcheckでエラーはない。
・kindle previewerでエラーはない。
epubcheckでエラーがなければEPUB3の電子書籍として問題はないし、kindle perviewerでエラーをチェックするのは最大の配信サイトであるAmazonでエラーがあったら商売上よろしくないから。
上記2つのチェックをクリアしたのに、一部の配信サイトでエラーになるという指摘があって、追いかけてみると、問題になったのが「絵文字」
「😀」←こういうやつ
原稿に絵文字があったんで、あれ?これってイケるんだっけと思って作ってみて、上記2つのチェックにかけてもエラーはなかった。
文字コードがShiftJISの時代ならともかく、今どきはutf8。
utf8のおかげで文字化けなんかを気にする必要はほぼなくなった。機種依存、環境依存文字に神経質にならなくていいのはストレスフリーで、いい時代になったもんだとのんきに感慨深い今日この頃だったのに…。
文字として問題はないんだけど、配信サイトごとにビューワーが違ってたりして、そのビューワーが絵文字に対応してるかどうかのことだと思う。
「EPUB | CSS組版ブログ」
https://blog.antenna.co.jp/CSSPage2/archives/category/epub
↑絵文字なんかについて、縦書きのepub3が始まった頃に議論があったらしい。
(電子書籍元年当時の話が読めるのでオススメ)
「横倒しのまま」にするのか「正立させる」のか。文字の意味的に方向があるものは正立させる?とか。そのあたりのすり合わせが問題になってたっぽい(という理解でいいのかなあ)
これは縦書きの場合、見た目けっこう致命的なので、たぶん、絵文字の対応を見送ったビューワー=配信サイトがあったんじゃないかと思う(憶測)
あるいは、そもそも、絵文字は環境ごとで見え方も違うのでそこが問題なのかもしれない(憶測)
そんなこんなの名残りもあって、面倒なものは却下、ということで今でもエラーにする配信サイトがある、んだろう(めっちゃ憶測)
epubcheckでもkindle previewerでもエラーにならない文字を自前で検知する必要にせまられる事態となった。
電子書籍のボリュームを目で追ってその中から絵文字を見つける、目視で探すなどありえない。必ず漏れが出る。
なもんで、絵文字の文字コードを調べてみて改めて今さらびっくりのunicodeだ。
ちなみに、文字を表示させるためには、以下の2本立てになっている。
・unicodeの文字コード表で文字を指定特定していて
・文字コードをエンコードすることで文字を表現する
これ、けっこう勘違いするんだけど、utf8というのは文字コードではなくてunicodeの文字コードをエンコードする方法の名前のこと。
以下のサイトを読んでまたびっくりすることをおすすめする。
「文字コード再入門 ─ Unicodeでのサロゲートペア、結合文字、正規化、書記素クラスタを理解しよう!」
https://en-ambi.com/itcontents/entry/2020/04/28/103000/
「書記素クラスタ - daiizfeel 2022」
https://isobe-yaki.hateblo.jp/entry/2023/07/20/194803
てのはともかく、読んでも難しいんで、なにか大変なことになってるんだなあ、でOK。
そもそもutf8でエンコードされた、日本語などは、ひと文字を表すのに、そのコードは3バイト使う。
ひとつの文字がアルファベットのように1バイトではないので
たとえば「日本語の文字」の6文字は、1つの文字に3バイトのコードが必要で、文字列の長さをバイト数でいうと18となる。
文字数いくつだっけ?て時に、バイト数の18ではなくて「正しく」6と数えるためにエンコードされている必要がある。
unicodeのコードをエンコードして初めて「文字として認識される」
このエンコードする方法がutf16だったりutf8とか呼ばれて、エンコードすることで初めて「文字として認識された文字を表示する=扱うことができる」という変な日本語。
perlの場合、utf8フラグというのを使うことで問題解決する。
my $str = '日本語の文字'
my $utf8 = Encode::decode('utf8',$str)
print length($str)
→18文字
print length($utf8)
→6文字
perlはこのおかげで、文字の扱いについて、普段はまずほとんど、こんな面倒くさいことを意識する必要はなくて、なもんで、すっかりわけがわからず混乱してしまったのが昨日今日の話、だ(とほほ
unicodeとutf8についてのおさらいができたところで、やっと本題。
じゃあ、絵文字を検知するには絵文字が使ってるコードを見つければいいだけじゃん。簡単だろ、と思ったらまたひと悶着。
ていうか、ここからが今回の本丸、一丁目一番地(死語)
utf8フラグだけでは解決しない「結合文字」というのがあった。
「1つの文字を表示しているのは、1つのunicodeのコードポイント」とは限らない。
ひとつの文字を表示、扱うのに、複数のunicodeのコードポイントを使ってるケースがあって、見た目のひと文字とそれを表すコードは1対1ではない、ということ。
perlでutf8フラグがついていてもutf8の文字コード(←unicodeコード表によるコードではなくてエンコード後の文字コード)2つ結合した文字はlength()では意図通りに取得できない。ひと文字として扱ってほしいのに、たとえば二文字としてカウントされてしまってお手上げ。
実のところ、書記素クラスタというのはこういう結合文字も含めた呼び方で、書記素クラスタに対応すれば「結合文字」も「ひと文字」として扱うことができる。書記素クラスタというのがなんだか「とても面倒くさい」というのはこのあたり。
こうなってくると、電子書籍でエラーをなくすために、なんでこんなことまで調べにゃならんのか。そもそもレアケースだし、配信サイト個別のクレーム対応でいいんじゃないのか。と思わないでもないけど。乗りかかった船だししょうがない。
話がそれた。
perlはこれも解決してくれる。て、テキストを扱わせたらperl最強じゃね?
「絵文字を含む文字列を分割~解説編~」
https://www.lemorin.jp/perl/3b_split_char.html
↑こちらのサイトに知りたいことのすべてがあった(多謝
my $line = Encode::decode('utf8', $_);
my $len = length($line);
print $len . "\n";
my @x = $line =~ m!\X!g;
print scalar(@x) . "\n";
length()では「見た目のひと文字」じゃなくて困ってたところ、perlでは「いい感じに」「ちゃんと」文字として認識できる文字のための正規表現「\X」が用意されてた。
「perlの正規表現」
https://perldoc.perl.org/perlrebackslash#Misc
ということで、やっと本エントリの締めとなります(長っ!
問題のない文字ダネを削除して残った文字を正規表現「\X」で配列に取り出して、「見た目のひと文字」をコードポイントにバラして16進表現して絵文字のコードに検索をかける。検索がヒットしたら、それはイコール絵文字。
「HTMLの絵文字 文字コード表」
https://gray-code.com/html_css/list-of-emoji/
↑絵文字のコードはこちらの一覧から拝借しました。
こちらで掲載されているコードを絵文字判定の対象としました。
これでやっと絵文字検知。
前から言ってるんだけど、人間の目視確認、手作業修正(目grep、手marge)なんて1mmも信用できない。特におれ。なので機械に頼めるなら機械に任せるのが正解。
↓こちらも参考になりました
「Perl 5.26 & Unicode 9.0 で変わる書記素クラスタ(grapheme cluster)のお話」
https://shogo82148.github.io/blog/2017/08/25/unicode9-grapheme-cluster/
「UTF-8の文字コード表」
https://orange-factory.com/dnf/utf-8.html
本エントリとはまったく関係ないけど。
この埼玉県八潮市の資料館はびっくりの充実。行く前は小学校の教室ぐらいなもんだろ、と思っててすみませんでした。
交通アクセスにちょっと難があって、気楽にとはいえないけど、行けるかたはぜひぜひ
https://www.city.yashio.lg.jp/kurashi/shisetsuguide/shiryokan/index.html
[08/25 16:58:54] いろいろ間違えてたので改稿
「文字につかうバイト数」と「コードポイント」を混用していた、という乱暴な理解だった(恥
» ローカル環境で電子書籍を作る、Macアプリ・Windows版ツール 「かんたんEPUB3作成easy_epub」