月別アーカイブ: 2015年3月

Linux でエロ本

今日は Linux でエッチな本を楽しむ方法の紹介だよ。
CBR, CBZ と言っても HONDA のバイクじゃないよ。

エッチなサイトを廻っているとたまに D○M のサンプル本が置いてあるよね。
紳士であるみんなはついつい zip を落としてしまうよね。
男の子だもん、しかたがないよ。
ということで、そのまま拡張子を *.cbz に変更してみよう。

ero1

あれ?圧縮したまま Nautilus でサムネイル表示されちゃった。
コレをそのまんまドキュメントビューアー(evince)で開くよ。

ero2

なんと今の Linux では何も入れなくてもエロ本を楽しめちゃう。
ファイルが一つで中身がサムネイルで解るので管理も簡単。
サムネイルを表示したら困るなんて女々しい男はいないよね。
まさしく男の中の男のための OS でありました。

でも evince だと快適機能が何もない、でも大丈夫。
世界中の男子なプログラマーが MComix ってアプリを作っている。
コイツなら見開きページもバッチリさ(スクショは自粛)
もうプロパティからデフォルトアプリにしてしまえ。

ero3

いや、本当は自作か自分でスキャンしたもの用なんでしょうけど。
スマホや iPad の観覧アプリも結構あるんだよ。

ちなみに MComix は Python 製です、PyGtk ですが。
もし「もっとこう…」とか思ったらソースを参考に自作してみよう。
/usr/lib/python2.7/site-packages/mcomix にあるよ。

PyGObject ならおじさんがチップスを書いているよ。
PyGObject Tips – L’Isola di Niente
せっかく作り変えたけどアクセス少なくてションボリだよ。

GFileMonitor

最近 GUI をやっていない。
コマンドラインばかりじゃつまんない。

で、実用的かもしれないディレクトリ内容の変更を監視し出力するウインドウを。
いや、随分前にやって上手くいかなかったのだが原因がやっと解ったので。
GUI は C では面倒すぎなので Python で。

#!/usr/bin/env python3

"""
    $HOME を監視するサンプル
"""

from gi.repository import Gtk, Gio, GLib

class Win(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        self.view = Gtk.TextView()
        self.view.set_editable(False)
        sw = Gtk.ScrolledWindow()
        sw.add(self.view)
        self.add(sw)
        #
        # ファイル監視も同様、現在存在していない場合でも監視してくれる
        #f = Gio.File.new_for_path(GLib.get_home_dir() + "/test.txt")
        f = Gio.File.new_for_path(GLib.get_home_dir())
        #
        # GFileMonitor は他メソッドで使わなくても必ずアトリビュートにする
        # しないと __init__ 抜けた時点で破棄されてしまう
        #
        self.monitor = f.monitor(Gio.FileMonitorFlags.NONE)
        #self.monitor = f.monitor(Gio.FileMonitorFlags.SEND_MOVED)
        self.monitor.connect("changed", self.on_monitor)
        # self
        self.connect("delete-event", Gtk.main_quit)
        self.resize(300, 200)
        self.show_all()

    def on_monitor(self, monitor, f, other_f, event):
        """
            ディレクトリ監視は隠しファイルの変更も感知します
            ( /.bash.history 等 )
        """
        buf = self.view.get_buffer()
        s = f.get_path()
        if event == Gio.FileMonitorEvent.CHANGED:
            # ファイルの内容が変更された時
            buf.insert_at_cursor("CHANGED: {0}\n".format(s))
        elif event == Gio.FileMonitorEvent.CHANGES_DONE_HINT:
            # ファイルの情報が変更された時
            buf.insert_at_cursor("CHANGES_DONE_HINT: {0}\n".format(s))
        elif event == Gio.FileMonitorEvent.DELETED:
            # 削除(リネーム、移動含む)された時
            buf.insert_at_cursor("DERETED: {0}\n".format(s))
        elif event == Gio.FileMonitorEvent.CREATED:
            # 作成(リネーム、移動含む)された時
            buf.insert_at_cursor("CREATED: {0}\n".format(s))
        elif event == Gio.FileMonitorEvent.ATTRIBUTE_CHANGED:
            # パーミッションが変わった時
            buf.insert_at_cursor("ATTRIBUTE_CHANGED: {0}\n".format(s))
        elif event == Gio.FileMonitorEvent.PRE_UNMOUNT:
            # Gio.FileMonitorFlags.WATCH_MOUNTS 指定時のみ
            buf.insert_at_cursor("PRE_UNMOUNT: {0}\n".format(s))
        elif event == Gio.FileMonitorEvent.UNMOUNTED:
            # Gio.FileMonitorFlags.WATCH_MOUNTS 指定時のみ
            buf.insert_at_cursor("UNMOUNTED: {0}\n".format(s))
        elif event == Gio.FileMonitorEvent.MOVED:
            # Gio.FileMonitorFlags.SEND_MOVED 指定時のみ
            buf.insert_at_cursor("MOVED: {0}\n".format(s))
        # Gio.FileMonitorFlags.WATCH_MOUNTS 指定時に、あれ?
        if other_f:
            buf.insert_at_cursor("other: {0}\n".format(f.get_path()))

Win()
Gtk.main()

gfilemonitor

で、結論。
GFileMonitor のインスタンスは self のアトリビュートにする必要がある。

今迄は他メソッドから参照する必要が無いものは self にはくっつけなかった。
すると全然シグナルが飛んでこない、バグだとずっと思っていた。
しかし今日 self を付けただけであら不思議。

よく考えたらガベージコレクションだから当然である。
GUI 部品なら親ウインドウにくっついているのだから何かしら参照がある。
しかしメインループで動いているだけの部品はどこからも参照されていない。
結果ガベージコレクタの破棄対象に、何かで参照しないといけない。

PyGObject を作っている皆様、コッソリ疑っていてごめんなさい。

もしかしてアレも、と思い付くのがチラホラ。

しかしファイル監視は存在しないファイルを指定してもいいんだね。
新規作成で CREATE と CHANGES_DONE_HINT のシグナルが飛んでくる。
CHANGES_DONE_HINT はちょっとうっとうしい。

それと $HOME を監視したまま gnome-terminal を終了すると解るけど。
~/.bash_history とかの隠しファイルへの書き出しにも反応する。
コレはハンドラ側で見分け等をする、でいいのかな。

gfilemonitor2

SEND_MOVED 指定も試してみた、なるほどそうなるか。
ディレクトリ移動だと結局 DELETED になる、リネームしか意味が無い。
しかし *other_file 引数は何だろう?

それよりリネーム後のファイル名が得られないと困るんだが。
バ…いやいや、コレも手段が悪いだけなのかもしれないし。
というか、使い道が思いつかないしどうでもいいかなと。

おまけで、GDataOutputStream での上書き保存のみ。

#!/usr/bin/env python3
 
from gi.repository import Gio

f = Gio.file_new_for_path("output_stream.txt")
fstream = f.replace("", False, Gio.FileCreateFlags.NONE)
dstream = Gio.DataOutputStream.new(fstream)
dstream.put_string("BKB BKB")
fstream.close()

output_stream

OutputStream ってこんなことをやっていたの!
当然の話だが Gedit の上書き保存もまったく同じ。
いやいや、監視してみると色々面白いことが解るNE!