eel

この間、図書館へ行ったら、1年以上貸し出しが無かった(不人気な)本のコーナーが出来ていた。バッファーの容量制限が有るので、LRUのアルゴリズムによって解放する積りなんだな。

掘り出し物は無いかと漁っていたら、昔良く読んだ著者の手になる小説が有った。KATANAって小説。裏表紙に帯が張り付けられているんで、しげしげと見たよ。看板ですからね。

推薦人は、有名な池上彰さんと、手嶋龍一さん。余りに有名過ぎ。「民間軍事ビジネス」は、戦争を請け負う影の組織だって。そそらしてくれるじゃない。借りてきたのは言うまでもない。

アメリカでは、修正憲法2条により、個人での銃の所持が合法化されてる。時々銃の乱射事件があり、その度に規制をしようとするけど、2条を盾に取り、規制される風には見えない。 何でも、年間で3万人もの銃の犠牲者がいるそうな。

ある軍事アナリストによると、1000人が武器で殺傷される事案は、戦争になるとか。その論だと、米国内で年間30もの戦争が発生してる事になる。狂ってるね。

日本は、豊臣秀吉が刀狩りにより、平民が武器を所持する事を禁止された。それがずっと続いているかと思ったら違った。太平洋戦争の後、占領軍がやって来て、武装解除の号令により、銃器を召し上げられた。おかげで、銃による殺傷は極めて少なくなっている。

非合法に持ってる人は、その筋に方々。まれに、3Dプリンターで作っちゃう人は居るか。それと、おもちゃのピストルで、車を狙った人もいたな。まあ、安全と言って良いだろう。

で、小説の筋だけど、アメリカで殺傷能力のある銃は禁止しよう。でも2条との兼ね合いで、護身の為に命を繋ぐ銃は許可しよう。殺すんじゃなくて、スタンガンみたいに相手の攻撃を一時的に麻痺させる物は許可しよう。(ああ、近未来の話ね)

それと、民間軍事ビジネスがどう繋がってくるか? 読んでの楽しみです。ネタバレは反則ですから開陳しません。

eel

前回は滅多に取り上げないブラウザーの利用例を挙げた。juliaから3行入力するだけで、ブラウザーが開くと言う奴。すわ、juliaでもブラウザーが開発されたかと心を躍らせたが、違った。

elecronと言うハブ屋さんが開発したフレームワークの単なるラッパーだった。だから、juliaのパッケージ内にelecronと言う環境が内蔵されてた訳。

juliaから起動すると、めっぽう遅い。ならば、juliaをすっ飛ばして直接electronを起動すれば速くなるかと思たら、そうでもなかった。嫌味ったらしく、elctron 遅いで検索したら、こんなのが引っかかってきた。

Electron 重いし Eel 使ってみない?ってお話

この方は遅いじゃなくて重いってのに焦点を当ててるのね。ともかく、eel(ウナギ)と言うのを紹介されたので、庶民は食べられない物を試食してみる事にした。

EEL A little Python library for making simple Electron-like HTML/JS GUI apps

例を例によって実行。基本的な試食だな。日本だと、かば焼きだけど、外国ではどうよ? 世界のうなぎ料理、所変われば食べ方色々、だな。

(base) cent:01 - hello_world$ python hello.py
Hello from Python World!
Hello from Javascript World!

起動すると、直ぐにpythonからご挨拶があって、chromeの大きい画面が一瞬 表示され、サイズが程良い大きさになってから、javascriptからの挨拶があった。

この時のps図を挙げておく。

python hello.py
/usr/bin/google-chrome --app=http://localhost:8000/hello.html
cat
cat
/opt/google/chrome/chrome-sandbox /opt/google/chrome/chrome --type=zygote
/opt/google/chrome/chrome --type=zygote
/opt/google/chrome/chrome-sandbox /opt/google/chrome/nacl_helper
/opt/google/chrome/nacl_helper
/opt/google/chrome/chrome --type=zygote
/opt/google/chrome/chrome --type=gpu-process --field-trial-handle=16142305167655505377,8868076352919971185,131072 --gpu-preferences=
/opt/google/chrome/chrome --type=utility --field-trial-handle=16142305167655505377,8868076352919971185,131072 --lang=en-US --service
/opt/google/chrome/chrome --type=renderer --field-trial-handle=16142305167655505377,8868076352919971185,131072 --lang=en-US --enable
/opt/google/chrome/chrome --type=renderer --field-trial-handle=16142305167655505377,8868076352919971185,131072 --lang=en-US --enable

appってオプションは何? アドレスバー等の装飾を削ぎ落して、あたかも普通のアプリっぽく見せるやつらしい。

chrome --type=zygote ?

webOS Open Source Edition の観察(4)

Headless Chromeを起動したときのChromeのオプション設定

で、ウナギの成分は? 誕生の秘密は、setup.py に、遺伝情報が記されていた。

    install_requires=['bottle', 'bottle-websocket', 'future', 'whichcraft'],
    python_requires='>=2.6',

python 2.6とは、随分と古代な環境でもOKなのね。そして、ボトルって、plamoの人が紹介してたやつだな。 後は、うなぎの解剖が残っているな。盛大に解剖するよりも、骨と肝だけを見極めておきたい。。731よろしく、生体解剖だな。

まあ、 オイラーは、うなぎパイ(浜松名物)より、うなぎ煎餅(骨を焼いたやつ)が大好きであった。

ここが過去形ってのが辛い! 昔は、クライアントの接待で、よくうなぎ屋へ連れて行ってもらった。(あの頃営業を担当してたYさん、ありがとう。ああ、徹夜々で、体力落ちてたから、頑張って働けって事だったんか。)

python -m pdb

しましょ。これがオイラーの生きる道。

at emacs M-x pdb

Run pdb (like this): python3 -m pdb hello.py

or

(base) cent:fuga$ python -m pdb hello.py
> /tmp/fuga/hello.py(1)<module>()
-> from __future__ import print_function        # For Py2/3 compatibility
(Pdb) n
> /tmp/fuga/hello.py(2)<module>()
-> import eel
(Pdb) n
> /tmp/fuga/hello.py(5)<module>()
-> eel.init('web')

ここからステップ実行で潜ります。

(Pdb) s
--Call--
> /home/sakae/anaconda3/lib/python3.7/site-packages/eel/__init__.py(56)init()
-> def init(path, allowed_extensions=['.js', '.html', '.txt', '.htm', '.xhtml']):
  :
> /tmp/fuga/hello.py(9)say_hello_py()->None
-> print('Hello from %s' % x)
(Pdb)
> /tmp/fuga/hello.py(12)<module>()
-> eel.say_hello_js('Python World!')   # Call a Javascript function
(Pdb)
--Call--
> <string>(1)<lambda>()

何時もの事ながら、ごちゃごちゃしてて、追うのが面倒過ぎる。特に __xxx__ とかみたいなの、わけわかめ。

クラス利用時の特殊メソッド一覧

マジックメソッド(特殊関数)

突き詰めるとクラス嫌いなんだな。

vmware update

前回、VMWAREを強制アップデート(古いのを削除、新しいのをインストールって手順だけど)させられた。vboxで言うゲスト・アデションに相当するのがVMWAREにも有ったので、どんな陣容か調べてみた。

sakae@atom:/mnt/c/Program Files (x86)/VMware/VMware Player$ ls -l *.iso
-rwxrwxrwx 1 sakae sakae 58591232 Oct  7 14:39 linux.iso*
-rwxrwxrwx 1 sakae sakae 54939648 Oct  8 06:14 linuxPreGlibc25.iso*
-rwxrwxrwx 1 sakae sakae   540672 Oct  8 06:15 netware.iso*
-rwxrwxrwx 1 sakae sakae 16906240 Oct  8 06:15 solaris.iso*
-r-xr-xr-x 1 sakae sakae  1548288 Sep 16 18:55 VirtualPrinter-Linux.iso*
-r-xr-xr-x 1 sakae sakae 29917184 Sep 16 18:55 VirtualPrinter-Windows.iso*
-rwxrwxrwx 1 sakae sakae 14090240 Oct  8 06:13 winPre2k.iso*
-rwxrwxrwx 1 sakae sakae 87752704 Oct  8 06:14 winPreVista.iso*

なんで今更ネットウェアが有るの。Windowsは手厚いな。ソラリスが有るって事は、まだ生きて動いてるやつが有るんだな。(仮想で動かして、延命策だな)いずれにしろ、BSD系は綺麗さっぱり、蚊帳の外でした。

試しに、OpenBSDが入るかやってみた。OSの種類は、その他大勢の部類ね。64Bitでも32BitでもOKだった。

一度入れたOSをUpdateする時はCDからの起動が必要。はてどうやる? 調べてみたら、仮想PCなんで、BIOS画面を呼び出して、boot deviceを指示して下さいとな。ごもっともな事です。

To force the machine to enter the BIOS setup once (but continue booting
normally on subsequent start-ups), add bios.forceSetupOnce = "TRUE" to
VM's .vmx file.

あるいは、

Alternatively, quickly press F2 while booting. To make this easier, set
bios.bootDelay = "xxxx" in the .vmx file, where xxxx is the number of
milliseconds during which the VM will wait for the F2 signal.

どちらでもいいそうだ。

emacs は、重いのか?

真っ新なOpenBSDに、gtk2版のemacsを入れてみた。何時もはnox11の方を入れているので、お試しに重さを測ってみます。

こんなに沢山、付属品が付いてきました。無茶重いじゃん!! オイラーの知らないパッケージが多数やって来てる。gtk2がらみなのかな。

ob65$ cd /var/db/pkg
ob65$ ls -d *
ImageMagick-6.9.10.36                   lcms2-2.9
anthy-9100hp2                           libcroco-0.6.12
atk-2.30.0                              libffi-3.2.1p5
bzip2-1.0.6p10                          libiconv-1.14p3
cairo-1.16.0                            libidn2-2.0.0p0
dbus-1.12.12p0v0                        libnettle-3.4.1p0
desktop-file-utils-0.23p10              libotf-0.9.16
djvulibre-3.5.27p5                      libraw-0.18.13p1
emacs-26.1p5-gtk2                       librsvg-2.44.13
fftw3-3.3.7                             libtasn1-4.13p0
fftw3-common-3.3.7                      libunbound-1.9.1
fribidi-1.0.5                           libunistring-0.9.7
gd-2.2.5p1                              libwebp-1.0.0
gdk-pixbuf-2.38.1                       libxml-2.9.8p1
gettext-0.19.8.1p3                      lzo2-2.10p0
giflib-5.1.6                            m17n-db-1.8.0
glib2-2.58.3p9                          m17n-lib-1.8.0
gmp-6.1.2p3                             openjp2-2.3.0p0
gnome-icon-theme-3.12.0p5               p11-kit-0.23.15p0
gnome-icon-theme-symbolic-3.12.0p3      pango-1.42.4p2
gnutls-3.6.7                            pcre-8.41p2
graphite2-1.3.13                        png-1.6.35p0
gtk+2-2.24.32p2                         python-3.6.8p0
gtk-update-icon-cache-3.24.7            quirks-3.124
harfbuzz-2.4.0                          shared-mime-info-1.10p5
hicolor-icon-theme-0.17                 sqlite3-3.27.2p0
intel-firmware-20190514p0v0             tiff-4.0.10
jasper-2.0.14                           xdg-utils-1.1.3p1
jbigkit-2.1                             xz-5.2.4
jpeg-2.0.2v0

パッケージ群は、/usr/local下に入るので、総体重を測るのは簡単。

ob65$ du -sh /usr/local/
747M    /usr/local/
ob65$ df -k
Filesystem  1K-blocks      Used     Avail Capacity  Mounted on
/dev/wd0a    11342910   1962910   8812856    18%    /

ついでに、Diskの使用量も確認したよ。

swap /tmp mfs rw,nodev,nosuid,-s=2048000 0 0

そして何時ものお約束、OpenBSD版用のRAMDISK

上でBIOSの呼び出し方法を知ったものだから、一度だけ呼び出す方法を試してみた。ISOファイルを指定しておいて起動。BIOSの画面が出てくるので、bootを選択。

Removable Medea
HDD Disk
CD

とかなってる。RemovableってUSBの事だな。CDを選んで+を叩いて、優先順位を上げる。そしてF10を押してSave。これでCDからbootしたよ。

これ一度きりなんで、次回の起動時にはHDDが選ばれる。vboxだと、メニューから簡単にboot deviceを選べるから、ちと楽だな。いや、VMWAREの方がより実在のパソコンに近いと思うぞ。 どちらがいいかは、各自の好み。

eel on OpenBSD

emacsを入れると、もれなくpythonが付いてくる。拒否するとemacsはインストール出来ない。 (自分でコンパイルすれば、余計な物は必要無いだろうけど)

折角pythonが入っているなら、上でやった鰻を飼ってみるか。pipが必要なんだな。

ob$ doas pkg_add py3-pip
doas (sakae@ob.localdomain) password:
quirks-3.124 signed on 2019-10-07T12:22:46Z
py3-pip-9.0.3:py3-setuptools-40.0.0v0: ok
py3-pip-9.0.3: ok
--- +py3-pip-9.0.3 -------------------
If you want to use this package as default pip, as root create a
symbolic link like so (overwriting any previous default):
    ln -sf /usr/local/bin/pip3.6 /usr/local/bin/pip

ちとpipが古いけど我慢。

ob$ pip  install --user eel
Collecting eel
  Downloading https://files.pythonhosted.org/packages/bb/22/d790af88f1cb12d30e38
2060c6806c8dfb2b43c96698f7d9775782496a26/Eel-0.10.4.tar.gz
Collecting bottle (from eel)
  :
Installing collected packages: bottle, greenlet, gevent, gevent-websocket, bottle-websocket, future, whichcraft, eel
  Running setup.py install for greenlet ... done
  Running setup.py install for gevent ... done
  Running setup.py install for bottle-websocket ... done
  Running setup.py install for future ... done
  Running setup.py install for eel ... done
Successfully installed bottle-0.12.17 bottle-websocket-0.2.9 eel-0.10.4 future-0.17.1 gevent-1.4.0 gevent-websocket-0.10.1 greenlet-0.4.15 whichcraft-0.6.1
You are using pip version 9.0.3, however version 19.2.3 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

pipのhelpに --user が列挙されないのは、いかがなものかと思うぞ。隠しコマンドか。そして、何時ものお約束の新しいpipが有るよと言う余計なお世話。そんなお世話を焼く前に、大事なオプションをきちんと説明せんかい。全く腐ってるぞ。

userサイドに入れたやつは、.localと.cacheの下を汚してくれるのね。(なんか、汚物的な物言いだな)

ob$ python3 hello.py
Hello from Python World!
Traceback (most recent call last):
  File "hello.py", line 14, in <module>
    eel.start('hello.html', size=(300, 200))    # Start
  File "/home/sakae/.local/lib/python3.6/site-packages/eel/__init__.py", line 10, in start
    brw.open(start_urls, options)
  File "/home/sakae/.local/lib/python3.6/site-packages/eel/browsers.py", line 3, in open
    chm.run(options, start_urls)
  File "/home/sakae/.local/lib/python3.6/site-packages/eel/chrome.py", line 18,
in run
    "Can't find Chrome or Chromium installation")
OSError: Can't find Chrome or Chromium installation

chromeは駄目でも、自由版は有るだろう。

ob$ doas pkg_add chromium
ob$ which chrome
/usr/local/bin/chrome

chromeって名前で呼び出せるんだけど、鰻はそれを見つけられないみたいだ。上と同じエラー。が出て来る。こういう環境に弱い生物だから、絶滅危惧種に指定されちゃうんだな。

それとも、日本語フォントがまだ入っていなくて、豆腐になるんで、嫌われちゃったかな? ja-sazanami-ttf-20040629p3 とか言うちょいと古いfontを入れたよ。

python debug

ソースをざっと見すれば、不良個所が一目瞭然なんだけど、debugしてみる。pdbでBPを貼ろうとすると、フルパスでスクリプトを指定して、コロンを置いて行番号ってやらないといけないので面倒。

そんな訳でipythonを動かし、裏側にpdbを仕込んでから、ターゲットを走らせる。まあ、ipythonってのはジュピターノートブック嫌いな人の逃げ場ですから。(それより、OpenBSDにジュピターノートブックなんて用意されてるのか?)

In [1]: import pdb

In [2]: run hello.py
    :
/home/sakae/.local/lib/python3.6/site-packages/eel/chrome.py in run(options, start_urls)
     16     else:
     17         raise EnvironmentError(
---> 18             "Can't find Chrome or Chromium installation")
     19
     20

OSError: Can't find Chrome or Chromium installation

すると、お約束通りに落ちてくれる。で、pm()を使ってトレースバックの事後解析デバッギングに入る。

In [3]: pdb.pm()
> /home/sakae/.local/lib/python3.6/site-packages/eel/chrome.py(18)run()
-> "Can't find Chrome or Chromium installation")
(Pdb) p options
{'mode': 'chrome-app', 'host': 'localhost', 'port': 8000, 'chromeFlags': []}
(Pdb) p start_urls
['http://localhost:8000/hello.html']

run()関数の入力を取り合えず確認。それから、バックトレース。

(Pdb) bt
  :
-> exec(compiler(f.read(), fname, 'exec'), glob, loc)
  /tmp/fuga/hello.py(14)<module>()
-> eel.start('hello.html', size=(300, 200))    # Start
  /home/sakae/.local/lib/python3.6/site-packages/eel/__init__.py(120)start()
-> brw.open(start_urls, options)
  /home/sakae/.local/lib/python3.6/site-packages/eel/browsers.py(35)open()
-> chm.run(options, start_urls)
> /home/sakae/.local/lib/python3.6/site-packages/eel/chrome.py(18)run()
-> "Can't find Chrome or Chromium installation")

これぐらいが、よくお目にかかるエラーの確認方法ですかね。

(Pdb) ll
  3     def run(options, start_urls):
  4         chrome_path = get_instance_path()
  5
  6         if chrome_path is not None:
  7             if options['mode'] == 'chrome-app':
  8                 for url in start_urls:
  9                     sps.Popen([chrome_path, '--app=%s' % url] +
 10                                options['chromeFlags'],
 11                                stdout=sps.PIPE, stderr=sps.PIPE, stdin=sps.PIPE)
 12             else:
 13                 args = options['chromeFlags'] + start_urls
 14                 sps.Popen([chrome_path, '--new-window'] + args,
 15                            stdout=sps.PIPE, stderr=sps.PIPE, stdin=sps.PIPE)
 16         else:
 17             raise EnvironmentError(
 18  ->             "Can't find Chrome or Chromium installation")

llコマンドで、今居る関数のリストを表示出来る。任意の所を見るなら、l from,to とやれば良い。

後は、upとかで、上のフレームに登って、リストを確認するなりご自由に。わざわざemacsからpdbを起動するより、よっぽど楽である。

素のpythonしか入っていない出先ではどうするか?

ob$ python3
Python 3.6.8 (default, Apr 13 2019, 18:58:09)
[GCC 4.2.1 Compatible OpenBSD Clang 7.0.1 (tags/RELEASE_701/final)] on openbsd6
Type "help", "copyright", "credits" or "license" for more information.
>>> import pdb
>>> import hello
Hello from Python World!
Traceback (most recent call last):
  :
OSError: Can't find Chrome or Chromium installation
>>> pdb.pm()
> /home/sakae/.local/lib/python3.6/site-packages/eel/chrome.py(18)run()
-> "Can't find Chrome or Chromium installation")

hello.pyをモジュールと見做して、パイ無しでimportすれば、走って落ちてくれる。そこですかさず臨場ですな。

カッコよい臨場方法

ob$ python3 -m pdb hello.py
> /home/sakae/Eel/examples/01 - hello_world/hello.py(1)<module>()
-> from __future__ import print_function        # For Py2/3 compatibility
(Pdb) c
  :
OSError: Can't find Chrome or Chromium installation
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
> /home/sakae/.local/lib/python3.6/site-packages/eel/chrome.py(18)run()
-> "Can't find Chrome or Chromium installation")
(Pdb) a
options = {'mode': 'chrome-app', 'host': 'localhost', 'port': 8000, 'chromeFlags': []}
start_urls = ['http://localhost:8000/hello.html']
(Pdb) help a
a(rgs)
        Print the argument list of the current function.

落ちると検視モードでdebuggerが眼を覚ます。すかさず a したよ。

臨場と言うより、今回は鰻の養殖もとえ移植の技術確認だな。僻地のOSは何かと自助努力が必要だからね。これで、取り合えずの技術が確立したって事でいいかな。

次は、うなぎじゃなくてナマズだな。ああ、あちらはperlが生息地だったかな? 何分にも昔の事で忘れてしまったわい。どこかにナマズの痕跡が無いかな?

OpenBSD用に修正

4行目で、chromeのフルパスを得ている。後はそれを使ってパイプでブラウザーとやり取りって仕組み。

問題はフルパスを得る関数の中にある。世の中にはWindowsとMacとLinuxしかないと作者は考えているんだな。BSD何それって態度。よってそんな役に立たない関数は呼び出ししないで、OpenBSDでのchromeのパスを直接与えちゃう。

def run(options, start_urls):
#    chrome_path = get_instance_path()
    chrome_path = '/usr/local/bin/chrome'
    if chrome_path is not None:
        if options['mode'] == 'chrome-app':

これで動いた。鰻も住み心地良さそうです。

ob$ python hello.py
Hello from Python World!
Hello from Javascript World!
ob$

まあ、大体こんな物よ。気になるのは、OpenBSDのパッケージ、chromiumってパッケージ名なのに、実体がchromeって、どうよ? パッケージャに小一時間問い詰めてみたいぞ。

etc

OpenSSH 8.1 release

出ましたね。これとほぼ同期して、OpenBSDが出てくるので、作業は順調なんでしょうな。人が少なくて、一部のプラットフォーム版の作業が遅れているかも?

ob$ ssh -V
OpenSSH_8.0, LibreSSL 2.9.1

これが8.1となるのは何時?