Programming」カテゴリーアーカイブ

Gtk Next/Prev Dialog

Fedora を 32 (GNOME 3.36) にして一ヶ月たった。
今更気が付いたんだけーが GtkMessageDialog のバグが直っている。

GNOME 3.34 modal dialog bug | Paepoi Blog

この時に拙作 Comipoli は GtkInfoBar に変更した、そのまんまだ。
コレってフルスクリーンで cbz を見ていた時には解り辛いんだよね。
ダイアログのほうが視覚的に理解しやすいので元に戻すことにした。

戻すだけじゃつまらない、何か機能の追加か変更をしたい。
pixivコミックやニコニコ漫画のように「前の話」機能を追加することに。
って、GtkMessageDialog では YES/NO しか選択できないんだが。

ということで、GtkDialog を使って自作することにした。
Prev のショートカットはどうするか、Enter/Esc は勝手にやってくれるが。
ええい面倒だ、ニーモニックをそのまま描写しちゃえばいいや!

#!/usr/bin/env python3

from gi.repository import Gtk

class ComipolNextDialog(Gtk.Dialog):
    def __init__(self, text):
        Gtk.Dialog.__init__(self)
        self.set_resizable(False)
        # Buttons
        self.add_button('_Cancel (ESC)', Gtk.ResponseType.CLOSE)
        self.add_button('_Next (Enter)', Gtk.ResponseType.YES)
        self.add_button('_Prev (Alt+P)', Gtk.ResponseType.NO)
        self.set_default_response(Gtk.ResponseType.YES)
        # Message
        message = Gtk.Label(label=f'<span bgcolor="#CC0099">Next:</span> {text}', use_markup=True, visible=True)
        self.vbox.pack_start(message, False, False, 30)

こうなった。
YES/NO は最適なものが無いので簡易利用しただけ。
ボタン自体にショートカットが書いてある親切な仕様になってしまった。

んで呼び出し。
一つ前が存在しない時はボタンを無効にする必要があるなと。

dlg = ComipolNextDialog(html.escape(cbzs[next_index]))
dlg.set_transient_for(self)
if next_index < 2:
    dlg.set_response_sensitive(Gtk.ResponseType.NO, False)
res = dlg.run() 
if res == Gtk.ResponseType.YES:
    uri = GLib.filename_to_uri(GLib.build_filenamev([path, cbzs[next_index]]), None)
    self.set_uri(uri)
elif res == Gtk.ResponseType.NO:
    uri = GLib.filename_to_uri(GLib.build_filenamev([path, cbzs[next_index - 2]]), None)
    self.set_uri(uri)
dlg.destroy()

コレでイケた。
どんな感じに表示されるか。

dlg

うーん、GtkMessageDialog よりボタンの大きさが小さいなぁ。
勝手に等間隔にはなるけど長いファイル名だと右に寄ってしまうし。
アクションエリアにアクセスが非推奨ではどうにもできない。
タイトルバーも出るんだね、無しにしたいけど手段が解らない。
iPhone を考えるとあのスタイルが普通になるのよね今後は。

とはいえ動作は問題無しなのでコレでいこう。

bash Color 256

前々回、tree コマンドを Python で自作したんだけど。
「ディレクトリを青色にしたけど tree コマンドとなんか色が違う」
の本家 tree コマンドの色を出力したい。

bash:tip_colors_and_formatting – FLOZz’ MISC

こんなページを発見。
bash ってここまで高機能だったのか、マジで知らなかった!
というか \033 だけじゃなく \e とか \x18 でも良かったのか。
アンダーラインも点滅も反転も、256 色で色指定さえも思いのまま。

しかし文句の付けようがない完璧で解りやすいまとめだなぁ。
こんな有用なページを筆者も作りたい、それは別の話で。

とにかく 256 色に指定するには以下にすればいいのね。

echo -e "\e[38;5;numm***string***\e[0m"

色見本ではドレが tree コマンドの青なのかよくわからない。
自前でソレっぽいのをいくつか選んで出力して確かめてみよう。

#!/bin/bash

for cl in {31..33} {37..39} {73..75} ; do
	echo -e "\e[38;5;${cl}m_texts\e[0m"
done

sh_color

どうやら 33 で正解のようだ。

ところで下方に対応ターミナルの表がありますが。
macOS の Terminal.app でも printf にすればイケます。
おまけに指定は sh でも bash でも zsh でもオケ。

mac_sh

Fedora 32 JavaScript

Fedora 32 は Gjs が ES2019 にフル対応した。
いや、フル対応した SpiderMonkey にアップデートというべきか。
JavaScriptの ES2019で追加された新機能まとめ – Qiita

更に BigInt にも対応、素晴らしい。
Python 屋としては Number の拡張はできなかったのかと言いたい所だけど。

bigint

プライベートフィールド等は駄目でした。
そんなことより Gjs の開発者はかなりがんばったようだ。

ClutterImage PyGObject/Gjs | Paepoi Blog

gjs_speedup

まさかの PyGObject より速くなるとは、誤差の範囲とはいえ。
何をやったか解らないけどコレで Gjs を諦める理由が減った。

Gjs: GdkPixbuf Memory leak | Paepoi Blog

この意味不明メモリリークもやっと起こらなくなった。
やはりメンテを続けていると良くなっていくんだよね。
ただこの実験は Python のガベージコレクションの凄さを思い知るだけだが。
メンテを続けた年期の差ってことで。

ところで JavaScript といえば。
/usr/libexec/webkit2gtk-4.0/jsc
が無くなった、Nautilus の検索機能でも見つからない。
けれど gir に JavaScriptCore-4.0.typelib は残っている。

#!/usr/bin/python

import gi
gi.require_version('JavaScriptCore', '4.0')
from gi.repository import JavaScriptCore

context = JavaScriptCore.Context()
out = context.evaluate('3 + "あ" + 4', -1)
print(out.to_string())

//=> '3あ4'

これは動く。

SpyderMonkey, V8 同様に実体が無くライブラリだけになったみたい。
実験にしか使っていなかったし mac も持っているから別にイイか。

mp4 mov rotate

スマホ動画の回転情報を得て我が Y901x にて正しい回転表示をさせる。
と随分前に書いてずっとサボッていたけどいいかげんに本気出そうと思う。
検索ワードを mov バイナリ 回転 とか mov に決め打ちして探したら。

バイナリエディタで .mov を回転 ? マキシマ文庫

おぉ多分コレだ!
回転情報書き換えなら Mac の QuickTime だけで簡単にできるのは置いておいて。
そこのバイナリを取得すれば回転情報は得られるってことね。

バイナリ取得や書き換えなら C や Python 等で簡単にできるのに。
てか既に沢山ありそう、参考用に探してみよう。

GitHub – danielgtaylor/qtrotate: Tools for handling rotated Quicktime/MP4 files

ズバリをあっさり見つけた。
mdat や trac アトムも取得しているし他にもやることあるみたい。
mov の構造は下記に、ソースコメントのリンク先はもう古いので。

Movie Atoms

試すならサポート終了の Python2 コードなので Python3 に書き換えてね。
print に括弧を付加と割り算を二重スラッシュにするのは毎度のこととして。
atom 比較の所の文字列には全部 b を付けてバイナリ比較に変更するのを忘れずに。
よく解らない人用に筆者が書き換えしたものを一応置いておきます。

qtrotate_py3.zip

どうやら mov と mp4 は同じ回転情報を使うようで mp4 にも適用できる。
とりあえず筆者が iPhone で撮影したり編集した動画は回転情報が得られた。

qtrotate

書き換えも問題無く可能だった。
Nautilus のサムネイルには即時繁栄されないので一旦コピペ。
ただ手持ち mp4 の中には正しくない情報が出るものもあった。
ここらをもう少し調べて Y901x に適用し。。。。。

しまった、Y901x は Gjs で作っていたんだった!
JavaScript はバイナリ編集なんてできないぞ。
GLib を使っても多分 Uint8Array に変換されて劇遅になるだけだ。

ClutterImage PyGObject/Gjs | Paepoi Blog

本気で困った。
Comipoli 同様コイツも PyGObject に書き換えることになりそう。

Python3 socket

Python からの socket アクセス。
http だけなら urllib.request で充分なんですけど。
ssh 等の通信にも使えるようなので使い方は勉強しておこう。

#!/usr/bin/env python3

'''
    http:// version
'''

import socket

HOST = 'palepoli.skr.jp'
FILE = '/suzuki/katana.html'
PORT = 80 # http

output = []

#with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
with socket.socket() as sock:
    sock.connect((HOST, PORT))
    msg = f'GET {FILE} HTTP/1.1\r\nHost: {HOST}\r\nConnection: close\r\n\r\n'
    s.sendall(msg.encode('utf-8'))
    while True:
        res = ssock.recv(4096)
        if not res: break
        output.append(res.decode())

print(''.join(output))

よく見かけるコードを fstring で今っぽく。
AF_INET 等は python3.7 ではデフォルト引数で指定されているので不要。
コピペだけで動くようにファイルは筆者のこのサーバーに置いています。

でもコレでは https でアクセスできないことに気が付いた。
https のポートを調べると 443 番だ、そりゃ 80 番では弾かれる。
でもポートを変更しただけでは駄目、ssl モジュールを使う必要あり。

#!/usr/bin/env python3

'''
    https:// version
'''

import socket, ssl

HOST = 'palepoli.skr.jp'
FILE = '/suzuki/v-strom.html'
PORT = 443 # https

output = []

with socket.socket() as sock:
    context = ssl.SSLContext(ssl.PROTOCOL_TLS)
    with context.wrap_socket(sock, server_hostname=HOST) as ssock:
        ssock.connect((HOST, PORT))
        msg = f'GET {FILE} HTTP/1.1\r\nHost: {HOST}\r\nConnection: close\r\n\r\n'
        ssock.send(msg.encode('utf-8'))
        while True:
            res = ssock.recv(4096)
            if not res: break
            output.append(res.decode())

print(''.join(output))

できた。

ところで実は GNOME ならこんなことができる。

#!/usr/bin/env python3

'''
    GNOME only
'''
 
from gi.repository import Gio
 
f = Gio.file_new_for_uri("https://palepoli.skr.jp/suzuki/burgman.html")
ok, contents, etag_out = f.load_contents()
if ok:
    print(contents.decode());
else:
    print('File not Found')

Gio は Gvfs という仮想ファイルでアクセス可能な URI なら全部扱える。
GNOME 標準アプリは全部 Gio アクセスなので以下みたいなことも。

sasikae

sftp でアクセスしてリモート編集が可能だったりする。
解りやすいようにコマンドで書いたけど Nautilus から sftp でアクセスして W クリックすればコレと同じことになる。
自分でアプリを作る時も Gio を使うだけ、これが GNOME の魅力。
SNS くらいしか使っていないショボイ人だとこの魅力は解らないだろうな。

追記
2020.04.22 添付画像の差し替え。