やっと application/x-cbr を展開する方法が解った。
コマンドから取得するしかないんだから unrar のヘルプを見る。
引数無しで unrar と打つとヘルプが出るのね、知らなかった。
えっと、オプションの使い方がよくわかんないんですけど。
つーことで file-roller のソースを落として見る。
fr-command-rar.c を見つける。
<Commands> はハイフン無し、ファイル名の前にハイフン 2 つ。
なるほど、jjs と同じなんだね。
ファイルに展開はコイツで解ったけどメモリ上に展開させる手段がワカンネ。
ええい最後の手段だ、mcomix のソースを見る、筆者のも GPL だからいいよね。
見ないままココまでやってきたけど筆者の技術ではもう無理だ。
ああ Python2 だ、今となっては懐かしい。
unrar p -inul -@ -- test.cbr 111.jpg > a.jpg
なんだ、p オプションにするだけだった。
上記でメモリ展開されたファイルをリダイレクトするとファイルにもなる。
つまり最初にファイル名のリストを取得して一つずつ抜き出せばいいのね。
よしこんだけ理解すればなんとかなるぞ。
#!/usr/bin/env python3
import sys, os, gi, subprocess
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib, Gio, GdkPixbuf
class CbrTest(Gtk.ApplicationWindow):
def __init__(self, app):
Gtk.ApplicationWindow.__init__(self, application=app)
self.datas = []
self.pixbuf = []
# add
button = Gtk.Button(label="show CBR")
button.connect("clicked", self.on_button_clicked)
self.fbox = Gtk.FlowBox(valign=Gtk.Align.START, max_children_per_line=6, min_children_per_line=6)
sc = Gtk.ScrolledWindow()
sc.add(self.fbox)
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
vbox.pack_start(button, False, False, 0)
vbox.pack_start(sc, True, True, 0)
self.add(vbox)
self.resize(600, 300)
self.show_all()
def on_button_clicked(self, button):
# listup filename
result, output, error, status = GLib.spawn_command_line_sync("unrar vt -p- -- test.cbr")
lines = output.decode("utf-8").split("\n")
for line in lines:
s = line.lstrip()
if s.startswith('Name: '):
name = s[6:]
ext = os.path.splitext(name)[1].lower()
if ext == ".jpg" or ext == ".jpeg" or ext == ".png":
# error: output is gchar*
#result, output, error, status = GLib.spawn_command_line_sync("unrar p -inul -@ -- test.cbr {0}".format(name))
with subprocess.Popen(["unrar", "p", "-inul", "-@", "--", "test.cbr", name], stdout=subprocess.PIPE) as proc:
output = proc.stdout.read()
self.append_data(output)
def append_data(self, data):
try:
stream = Gio.MemoryInputStream.new_from_data(data)
p = GdkPixbuf.Pixbuf.new_from_stream(stream)
minp = p.scale_simple(80, 100, GdkPixbuf.InterpType.BILINEAR)
image = Gtk.Image(pixbuf=minp)
image.show()
self.fbox.add(image)
except Exception as e:
print(e)
return False
class CbrApp(Gtk.Application):
def __init__(self):
Gtk.Application.__init__(self)
def do_activate(self):
CbrTest(self)
app = CbrApp()
app.run(sys.argv)
おぉ。
なんとかなったけど GLib.spawn_command_line_sync には困った。
output に \0 が含まれているとソコでバイナリが途切れてエラーになる。
そりゃまあ C での定義は gchar* だし当然かもしれないけど。
しかたがないので subprocess を使う、Gjs だとお手上げかも。