筆者のアプリは python3 なのに Gio の subprocess を使っていた。
Gjs, Vala, C 等からでも参考になるよう、てか途中まで Gjs 製だった。
JXA では後で Swift をやるかもと NSTask を使っていた。
やらねーし、Xcode デカすぎだし Python のほうが面白いし。
PyObjC 版は Python3 の subprocess モジュールでいいんでね?
17.5. subprocess ? サブプロセス管理 ? Python 3.6.5 ドキュメント
知らない間に subprocess が超単純化されていた。
Popen とか call とか迷わず run だけでいい、破棄も wait もいらない。
unrar, 7za を使うコードを subprocess.run に書き換えしてみる。
#!/usr/bin/env python3 import objc, zipfile, re, subprocess from AppKit import * PICEXT = '\.(jpe?g|png|gif)$' class ComipoliArchive: def __init__(self): self.status = 0 self.namelist = [] self.path = '' def new_archive(self, path, is_unrar, is_7za): self.path = path if re.search(r'\.(cbz|zip)$', path, re.I): self.status = 0 self.namelist.clear() with zipfile.ZipFile(path) as o: l = o.namelist() l.sort() for name in l: if re.search(PICEXT, name, re.I): self.namelist.append(name) elif is_unrar and re.search(r'\.(cbr|rar)$', path, re.I): self.status = 1 self.namelist.clear() cp = subprocess.run(['unrar', 'vt', '-p-', '--', path], stdout=subprocess.PIPE) lines = cp.stdout.decode('utf-8').split('\n') for line in lines: s = line.lstrip() if s.startswith('Name: '): name = s[6:] if re.search(PICEXT, name, re.I): self.namelist.append(name) elif is_7za and re.search(r'\.(cb7|7z)$', path, re.I): self.status = 2 self.namelist.clear() cp = subprocess.run(['7za', 'l', '-slt', path], stdout=subprocess.PIPE) lines = cp.stdout.decode('utf-8').split('\n') for line in lines: if line.startswith('Path'): name = line[7:] if re.search(PICEXT, name, re.I): self.namelist.append(name) else: return False return True def __getitem__(self, num): if self.status == 0: with zipfile.ZipFile(self.path) as o: b = o.read(self.namelist[num]) data = NSData.dataWithBytes_length_(b, len(b)) return NSImage.alloc().initWithData_(data) elif self.status == 1: cp = subprocess.run(['unrar', 'p', '-inul', '-@', '--', self.path, self.namelist[num]], stdout=subprocess.PIPE) data = NSData.dataWithBytes_length_(cp.stdout, len(cp.stdout)) return NSImage.alloc().initWithData_(data) elif self.status == 2: cp = subprocess.run(['7za', 'x', '-so', self.path, self.namelist[num]], stdout=subprocess.PIPE) data = NSData.dataWithBytes_length_(cp.stdout, len(cp.stdout)) return NSImage.alloc().initWithData_(data) def __len__(self): return len(self.namelist)
丸ごと。
unrar の存在確認も subprocess でやろうと思ったけど。
Pythonで外部コマンドの存在チェック(`which`的な) – Qiita
self.is_unrar = shutil.which('unrar') != None
こっちのほうがいいや。
早速試すことにしよう。
WinRAR archiver, a powerful tool to process RAR and ZIP files
から macOS 版 rar のダウンロード。
インストーラーも Makefile も無いので手動でパスを通す。
終わったら cbr にしたい画像の入ったディレクトリで以下を。
rar a test.cbr -- *.jpg
直接 CBR ファイルを作れるよ。
イケた。
Python3 自体の知識が 3.2 くらいで止まっているわ。
最新 Python3 必須になるけど、いやそのほうがいいでしょ普通。
たまには公式サイトも見ることにしよう。