こんなの見つけた。
Zip files: GSF Reference Manual
何だよ、GNOME には ZIP ファイルを扱うライブラリがあったのか。
GLib や Gio ばかり見ていて気が付かなかった。
Fedora 24 には普通に最初から libgsf が入っていますね。
GObject Introspection からも使える、これは使わない手はない。
以下は Vala だけどサンプルコードも見つかった。
Projects/Vala/GSFSample – GNOME Wiki!
早速コードを書いてみたけど色々困った。
gsf_infile_num_children はアーカイブの一階層分しか得ることができない。
階層がある場合は gsf_infile_num_children の戻り値を再帰するしかない。
しかも二階層以下はソートが名前の逆順に。
Python の ZIP ファイルもそうだったけど何故だ?
しかたがないので一階層以降は逆順の再帰で。
ついでに、サイズ取得が何故かプロパティ。
gst_input_size は size_t で size property は int64 だし。
意味ワカンネェけど動いたからいいや。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | #!/usr/bin/env python3 import sys, gi gi.require_version( 'Gtk' , '3.0' ) gi.require_version( 'Gsf' , '1' ) from gi.repository import Gtk, Gio, GdkPixbuf, Gsf PATH = "ziptest.cbz" ; #PATH = "なえコレ.zip" class GsfTest(Gtk.ApplicationWindow): def __init__( self , app): Gtk.ApplicationWindow.__init__( self , application = app) self .datas = [] # unzip f = Gsf.InputStdio.new(PATH) infile = Gsf.InfileZip.new(f) self .read_zipfile(infile) # add fbox = Gtk.FlowBox(valign = Gtk.Align.START, min_children_per_line = 5 ) for data in self .datas: fbox.add(data) self .add(fbox) self .show_all() def read_zipfile( self , infile): num = infile.num_children() for i in range (num): item = infile.child_by_index(i) if item.size = = 0 : self .read_childfile(item) else : self .append_data(infile, item) def read_childfile( self , infile): num = infile.num_children() for i in range (num - 1 , - 1 , - 1 ): item = infile.child_by_index(i) if item.size = = 0 : # recursive function self .read_childfile(item) else : self .append_data(infile, item) def append_data( self , infile, item): data = item.read(item.size) 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) self .datas.append(image) except Exception as e: print (e) class GsfApp(Gtk.Application): def __init__( self ): Gtk.Application.__init__( self ) def do_activate( self ): GsfTest( self ) app = GsfApp() app.run(sys.argv) |
コレでイケたけど。
階層の名前を取り出してソートしたほうが無難だろうか?
それより問題は速度がどうなるかだ。
Comipoli beta3 | PaePoi
の時からどう変わったか Comipoli に組み込んで同じ巨大ファイルを。
あんまり変わんねえヤン…
期待したのに。
せっかく安定して動いているのを変えるべきか悩む。