Python __getitem__

自作 comicbook archive ビューアがまだまだ気に入らない。
ページが多い場合にとにかく遅い、理由は解っているけど。
全ページをメモリに展開し更にリサイズして配列に格納していたらそりゃ遅い。

マルチスレッド化とか色々試したけど Python じゃ無理だ。
サムネイル表示時にもう一度リサイズするとかなんか無駄なことしているし。

ページめくり高速化の為に全部読み込んでいたけど都度読み込みのほうが良さげ。
ということでクラスを作ったけど今まで配列から取り出ししていたんだよなぁ。
全部の処理を関数に書き換えするのが面倒臭いし間違えるのが怖い。

いや、コイツは Python で作っている。
__getitem__ を使えばいいじゃないか。

#!/usr/bin/env python3

from gi.repository import GLib, Gio, GdkPixbuf
import os, zipfile

class ComipoliArchive:
    def __init__(self):
        self.status = 0
        self.namelist = []

    def new_cba(self, uri, is_unrar, is_7za):
        self.arc = Gio.file_new_for_uri(uri)
        self.path = self.arc.get_path()
        ext = os.path.splitext(self.path)[1].lower()
        if ext == ".cbz":
            with zipfile.ZipFile(self.path) as o:
                l = o.namelist()
                l.sort()
                for name in l:
                    if GLib.Regex.match_simple("\.(jpe?g|png|gif)$", name, GLib.RegexCompileFlags.CASELESS, 0):
                        self.namelist.append(name)
        elif is_unrar and ext == ".cbr":
            self.status = 1
            result, output, error, status = GLib.spawn_command_line_sync('unrar vt -p- -- "{0}"'.format(self.path))
            lines = output.decode("utf-8").split("\n")
            for line in lines:
                s = line.lstrip()
                if s.startswith('Name: '):
                    name = s[6:]
                    if GLib.Regex.match_simple("\.(jpe?g|png|gif)$", name, GLib.RegexCompileFlags.CASELESS, 0):
                        self.namelist.append(name)
        elif is_7za and ext == ".cb7":
            self.status = 2
            result, output, error, status = GLib.spawn_command_line_sync('7za l -slt "{0}"'.format(self.path))
            lines = output.decode("utf-8").split("\n")
            for line in lines:
                if line.startswith('Path'):
                    name = line[7:]
                    if GLib.Regex.match_simple("\.(jpe?g|png|gif)$", name, GLib.RegexCompileFlags.CASELESS, 0):
                        self.namelist.append(name)
        else:
            return 1
        return 0

    def __getitem__(self, num):
        stream = None
        if (self.status == 0):
            with zipfile.ZipFile(self.path) as o:
                data = o.read(self.namelist[num])
                stream = Gio.MemoryInputStream.new_from_data(data)
        elif (self.status == 1):
            sp = Gio.Subprocess.new(["unrar", "p", "-inul", "-@", "--", self.path, self.namelist[num]], Gio.SubprocessFlags.STDOUT_PIPE)
            stream = sp.get_stdout_pipe()
        elif (self.status == 2):
            sp = Gio.Subprocess.new(["7za", "x", "-so", self.path, self.namelist[num]], Gio.SubprocessFlags.STDOUT_PIPE)
            stream = sp.get_stdout_pipe()
        p = GdkPixbuf.Pixbuf.new_from_stream(stream)
        stream.close()
        return p

    def __len__(self):
        return len(self.namelist)

イケるやん!

これで今まで配列から GdkPixbuf を取り出ししていたように都度展開だ!
この機能はどんな時に使うんだ?と思っていたけどこういう場合なのね、ふむふむ。
yield なんていらなかったんや!まあ勉強になったしイイけど。

どうでもいいけど beta11 は arcive と誤字していた、次で直す。