File indexing completed on 2024-05-05 04:55:40
0001 import os 0002 import sys 0003 import re 0004 import locale 0005 import subprocess 0006 0007 0008 _kid3_cli_path = '' 0009 0010 0011 def kid3_cli_path(): 0012 global _kid3_cli_path 0013 if not _kid3_cli_path: 0014 if sys.platform == 'win32': 0015 craft_root = os.getenv('CRAFTROOT') 0016 if craft_root: 0017 from pathlib import Path 0018 cli_path = Path(craft_root).parent / 'kid3-cli.exe' 0019 if cli_path.exists(): 0020 _kid3_cli_path = str(cli_path) 0021 return _kid3_cli_path 0022 curdir = os.getcwd() 0023 cli_exe = 'kid3-cli' 0024 if sys.platform == 'win32': 0025 cli_exe += '.exe' 0026 while True: 0027 cli_path = os.path.join(curdir, 'src', 'app', 'cli', cli_exe) 0028 if os.path.isfile(cli_path): 0029 _kid3_cli_path = cli_path 0030 if sys.platform == 'win32': 0031 setup_run_environment() 0032 break 0033 else: 0034 cli_path = os.path.join(curdir, cli_exe) 0035 if os.path.isfile(cli_path): 0036 _kid3_cli_path = cli_path 0037 break 0038 parentdir = os.path.dirname(curdir) 0039 if len(parentdir) < 2 or parentdir == curdir: 0040 raise FileNotFoundError(cli_exe) 0041 curdir = parentdir 0042 return _kid3_cli_path 0043 0044 0045 def call_kid3_cli(args): 0046 if isinstance(args, str): 0047 args = [args] 0048 if sys.platform == 'win32': 0049 args.insert(0, '--portable') 0050 out = subprocess.check_output([kid3_cli_path()] + args) 0051 try: 0052 s = out.decode() 0053 except UnicodeDecodeError: 0054 s = out.decode(locale.getpreferredencoding()) 0055 return s.replace('\r\n', '\n') 0056 0057 0058 def setup_run_environment(): 0059 from pathlib import Path 0060 cache_path = Path(_kid3_cli_path).parents[3] / 'CMakeCache.txt' 0061 if cache_path.exists(): 0062 qmake_re = re.compile(r'^QT_QMAKE_EXECUTABLE[^=]*=(.*)qmake') 0063 with open(cache_path, 'r') as fh: 0064 for line in fh: 0065 m = qmake_re.match(line) 0066 if m: 0067 qt_bin_path = Path(m.group(1)) 0068 qt_plugin_path = qt_bin_path.parent / 'plugins' 0069 os.environ['PATH'] += ';' + str(qt_bin_path) + ';' + \ 0070 str(Path('src/core')) + ';' + str(Path('src/gui')) 0071 os.environ['QT_PLUGIN_PATH'] = str(qt_plugin_path) 0072 return 0073 0074 0075 def create_test_file(filename): 0076 ext = os.path.splitext(filename)[1] 0077 if ext == '.m4a': 0078 d = b'\x00\x00\x00\x18ftypM4A \x00\x00\x02\x00isomiso2\x00\x00\x00\x08free\x00\x00\x00!mdat\xde\x02\x00' \ 0079 b'Lavc56.41.100\x00\x020@\x0e\x01\x18 \x07\x00\x00\x02\xcdmoov\x00\x00\x00lmvhd\x00\x00\x00\x00\x00' \ 0080 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xe8\x00\x00\x00\x18\x00\x01\x00\x00\x01\x00\x00\x00\x00' \ 0081 b'\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ 0082 b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ 0083 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00' \ 0084 b'\x01\xf7trak\x00\x00\x00\\tkhd\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01' \ 0085 b'\x00\x00\x00\x00\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00' \ 0086 b'\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00' \ 0087 b'\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$edts' \ 0088 b'\x00\x00\x00\x1celst\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x04\x00\x00\x01\x00' \ 0089 b'\x00\x00\x00\x01omdia\x00\x00\x00 mdhd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xacD' \ 0090 b'\x00\x00\x04\x01U\xc4\x00\x00\x00\x00\x00-hdlr\x00\x00\x00\x00\x00\x00\x00\x00soun\x00\x00\x00\x00' \ 0091 b'\x00\x00\x00\x00\x00\x00\x00\x00SoundHandler\x00\x00\x00\x01\x1aminf\x00\x00\x00\x10smhd\x00\x00' \ 0092 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00$dinf\x00\x00\x00\x1cdref\x00\x00\x00\x00\x00\x00\x00\x01\x00' \ 0093 b'\x00\x00\x0curl \x00\x00\x00\x01\x00\x00\x00\xdestbl\x00\x00\x00jstsd\x00\x00\x00\x00\x00\x00\x00' \ 0094 b'\x01\x00\x00\x00Zmp4a\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00' \ 0095 b'\x10\x00\x00\x00\x00\xacD\x00\x00\x00\x00\x006esds\x00\x00\x00\x00\x03\x80\x80\x80%\x00\x01\x00' \ 0096 b'\x04\x80\x80\x80\x17@\x15\x00\x00\x00\x00\x01\xf4\x00\x00\x00!\x9c\x05\x80\x80\x80\x05\x12\x08V' \ 0097 b'\xe5\x00\x06\x80\x80\x80\x01\x02\x00\x00\x00 stts\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01' \ 0098 b'\x00\x00\x04\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x1cstsc\x00\x00\x00\x00\x00\x00\x00' \ 0099 b'\x01\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x1cstsz\x00\x00\x00\x00\x00\x00' \ 0100 b'\x00\x00\x00\x00\x00\x02\x00\x00\x00\x15\x00\x00\x00\x04\x00\x00\x00\x14stco\x00\x00\x00\x00\x00' \ 0101 b'\x00\x00\x01\x00\x00\x00(\x00\x00\x00budta\x00\x00\x00Zmeta\x00\x00\x00\x00\x00\x00\x00!hdlr\x00' \ 0102 b'\x00\x00\x00\x00\x00\x00\x00mdirappl\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08ilst\x00' \ 0103 b'\x00\x00%free\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01' \ 0104 b'\x01\x01\x01\x01\x01\x01\x01\x01' 0105 elif ext == '.flac': 0106 d = b'fLaC\x80\x00\x00"\x10\x00\x10\x00\x00\x00\x0c\x00\x00\x0c\n\xc4@\xf0\x00\x00\x00\x01\xc4\x10?\x12-\'g|' \ 0107 b'\x9d\xb1D\xca\xe19Jf\xff\xf8i\x08\x00\x00\x1d\x02\x00\x00 \x0c' 0108 elif ext == '.spx': 0109 d = b'OggS\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x0c8_\n\x00\x00\x00\x00\x1a\xb2i\xd1\x01PSpeex 1.2rc1' \ 0110 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00P\x00\x00\x00D\xac\x00\x00\x02' \ 0111 b'\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\xff\xff\xff\xff\x80\x02\x00\x00\x00\x00\x00\x00\x01\x00' \ 0112 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00OggS\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ 0113 b'\x0c8_\n\x01\x00\x00\x00\xe1j\xaf\xc6\x01!\x19\x00\x00\x00Encoded with Speex 1.2rc1\x00\x00\x00' \ 0114 b'\x00OggS\x00\x04\x01\x00\x00\x00\x00\x00\x00\x00\x0c8_\n\x02\x00\x00\x00b\xc6\xa4\xf9\x01Z>\x9d\x1b' \ 0115 b'\x9a \x00\x01\x7f\xff\xff\xff\xff\xff\xdbm\xb6\xdbm\xb6\x89\x00\xbf\xff\xff\xff\xff\xff\xed\xb6\xdbm' \ 0116 b'\xb6\xdbB\x00_\xff\xff\xff\xff\xff\xf6\xdbm\xb6\xdbm\xa1\x00/\xff\xff\xff\xff\xff\xfbm\xb6\xdbm\xb6' \ 0117 b'\xdb;`\xab\xab\xab\xab\xab\n\xba\xba\xba\xba\xb0\xab\xab\xab\xab\xab\n\xba\xba\xba\xba\xb9;`\x00\x00' 0118 elif ext == '.mp3': 0119 d = b'\xff\xfbP\xc4\x00\x03\xc0\x00\x01\xa4\x00\x00\x00 \x00\x004\x80\x00\x00\x04LAME3.99.5UUUUUUUUUUUUUUUU' \ 0120 b'UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU' \ 0121 b'UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU\xff\xfbR\xc4]\x83\xc0\x00\x01\xa4\x00\x00' \ 0122 b'\x00 \x00\x004\x80\x00\x00\x04UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU' \ 0123 b'UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU' \ 0124 b'UUUUUUUUUUUUUUUU' 0125 elif ext == '.wv': 0126 d = b'wvpk`\x00\x00\x00\x07\x04\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x05\x18\x80\x04\xfd' \ 0127 b'\xff\xff\xff!\x16RIFF&\x00\x00\x00WAVEfmt \x10\x00\x00\x00\x01\x00\x01\x00D\xac\x00\x00\x88X\x01\x00' \ 0128 b'\x02\x00\x10\x00data\x02\x00\x00\x00\x02\x00\x03\x00\x04\x00\x05\x03\x00\x00\x00\x00\x00\x00e\x02\x00' \ 0129 b'\x00\x00\x00\x8a\x01\x00\x00\xfd\xff' 0130 elif ext == '.ape': 0131 d = b'MAC \x96\x0f\x00\x004\x00\x00\x00\x18\x00\x00\x00\x04\x00\x00\x00,\x00\x00\x00\x10\x00\x00\x00\x00\x00' \ 0132 b'\x00\x00\x00\x00\x00\x00@\xd6\x946\xc8\xdd\xe3Q\x83\x89\xf63GuM\xef\xd0\x07\x00\x00\x00 \x01\x00\x01' \ 0133 b'\x00\x00\x00\x01\x00\x00\x00\x10\x00\x01\x00D\xac\x00\x00|\x00\x00\x00RIFF&\x00\x00\x00WAVEfmt \x10' \ 0134 b'\x00\x00\x00\x01\x00\x01\x00D\xac\x00\x00\x88X\x01\x00\x02\x00\x10\x00data\x02\x00\x00\x00\x7f\x89\xec' \ 0135 b'\xa0\x01\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00' 0136 elif ext == '.wav': 0137 d = b'RIFFL\x01\x00\x00WAVEfmt \x10\x00\x00\x00\x01\x00\x02\x00D\xac\x00\x00\x10\xb1\x02\x00\x04\x00\x10' \ 0138 b'\x00data(\x01\x00\x00\xd0\xe5l\xe5x\xe5X\xe5\x19\xe5;\xe5\xb6\xe4\x1a\xe5^\xe4\xff\xe4\x06\xe4\xfe' \ 0139 b'\xe4\xbf\xe3\xef\xe4T\xe3\xed\xe4\xf9\xe2\xc7\xe4\x91\xe2\xb2\xe44\xe2\x8a\xe4\xc6\xe1f\xe4d\xe1=' \ 0140 b'\xe4\xf0\xe0\x0b\xe4\x88\xe0\xe0\xe3<\xe0\xb2\xe3\x07\xe0\x8b\xe3\xd4\xdfW\xe3\xb5\xdf2\xe3\xb9\xdf' \ 0141 b'\x06\xe3\xd2\xdf\x03\xe3\xf5\xdf\xf5\xe2!\xe0\xee\xe2R\xe0\xdb\xe2\x96\xe0\xdd\xe2\xc0\xe0\xe7\xe2' \ 0142 b'\xec\xe0\xed\xe2\r\xe1\xea\xe2:\xe1\xf8\xe2X\xe1\x17\xe3s\xe11\xe3\x97\xe1N\xe3\xb3\xe1g\xe3\xd3\xe1' \ 0143 b'\x93\xe3\xd7\xe1\xa6\xe3\xf9\xe1\xad\xe3\x01\xe2\xb4\xe3\x1e\xe2\xb8\xe3&\xe2\xbd\xe3F\xe2\xb5\xe3Z' \ 0144 b'\xe2\xa3\xe3x\xe2\x92\xe3\x97\xe2v\xe3\xb3\xe2w\xe3\xcb\xe2h\xe3\xe8\xe2b\xe3\x0b\xe3O\xe3\x1b\xe3E' \ 0145 b'\xe3-\xe3H\xe3,\xe3C\xe3H\xe3:\xe3;\xe3Q\xe3I\xe3Z\xe3Q\xe3\x84\xe3q\xe3\x9c\xe3\x94\xe3\xdf\xe3\xb5' \ 0146 b'\xe3#\xe4\xe2\xe3f\xe4\x0f\xe4\xb0\xe4O\xe4!\xe5o\xe4\x94\xe5\xa3\xe4\x07\xe6\xbc\xe4X\xe6\xd2\xe4' \ 0147 b'\xc3\xe6\xd6\xe4\x18\xe7\xf1\xe4\x83\xe7\t\xe5\xed\xe7 \xe5_\xe88\xe5\xce\xe8r\xe5C\xe9\xae\xe5\xc9' \ 0148 b'\xe9\xe9\xe5o\xea(\xe6\x06\xeb\x82\xe6\xac\xeb' 0149 elif ext == '.opus': 0150 d = b'OggS\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x91d\x87S\x00\x00\x00\x00\xfb\x1f\xdfC\x01\x13OpusHead' \ 0151 b'\x01\x01d\x01D\xac\x00\x00\x00\x00\x00OggS\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x91d\x87S\x01\x00' \ 0152 b'\x00\x002\xa1\x1d5\x01\x1bOpusTags\x0b\x00\x00\x00libopus 1.1\x00\x00\x00\x00OggS\x00\x04f\x01\x00\x00' \ 0153 b'\x00\x00\x00\x00\x91d\x87S\x02\x00\x00\x00\xe6\xe1CE\x01\x03\xf8\xff\xfe' 0154 elif ext == '.mpc': 0155 d = b'MPCKSH\x0cp\n\xc9\xab\x08\x01\x00\x1b\x0bRG\x0c\x01\x00\x00\x00\x00\x00\x00\x00\x00EI\x07\xa0\x01\x1e' \ 0156 b'\x01SO\x08\x0c\x00\x00\x00\x00AP\x04\x00ST\x06\x01\x12\xb0SE\x03' 0157 elif ext == '.aif': 0158 d = b'FORM\x00\x00\x01VAIFFCOMM\x00\x00\x00\x12\x00\x02\x00\x00\x00J\x00\x10@\x0e\xacD\x00\x00\x00\x00\x00' \ 0159 b'\x00SSND\x00\x00\x010\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xd0\xe5l\xe5x\xe5X\xe5\x19\xe5;\xe4\xb6\xe5' \ 0160 b'\x1a\xe4^\xe4\xff\xe4\x06\xe4\xfe\xe3\xbf\xe4\xef\xe3T\xe4\xed\xe2\xf9\xe4\xc7\xe2\x91\xe4\xb2\xe24' \ 0161 b'\xe4\x8a\xe1\xc6\xe4f\xe1d\xe4=\xe0\xf0\xe4\x0b\xe0\x88\xe3\xe0\xe0<\xe3\xb2\xe0\x07\xe3\x8b\xdf\xd4' \ 0162 b'\xe3W\xdf\xb5\xe32\xdf\xb9\xe3\x06\xdf\xd2\xe3\x03\xdf\xf5\xe2\xf5\xe0!\xe2\xee\xe0R\xe2\xdb\xe0\x96' \ 0163 b'\xe2\xdd\xe0\xc0\xe2\xe7\xe0\xec\xe2\xed\xe1\r\xe2\xea\xe1:\xe2\xf8\xe1X\xe3\x17\xe1s\xe31\xe1\x97' \ 0164 b'\xe3N\xe1\xb3\xe3g\xe1\xd3\xe3\x93\xe1\xd7\xe3\xa6\xe1\xf9\xe3\xad\xe2\x01\xe3\xb4\xe2\x1e\xe3\xb8' \ 0165 b'\xe2&\xe3\xbd\xe2F\xe3\xb5\xe2Z\xe3\xa3\xe2x\xe3\x92\xe2\x97\xe3v\xe2\xb3\xe3w\xe2\xcb\xe3h\xe2\xe8' \ 0166 b'\xe3b\xe3\x0b\xe3O\xe3\x1b\xe3E\xe3-\xe3H\xe3,\xe3C\xe3H\xe3:\xe3;\xe3Q\xe3I\xe3Z\xe3Q\xe3\x84\xe3q' \ 0167 b'\xe3\x9c\xe3\x94\xe3\xdf\xe3\xb5\xe4#\xe3\xe2\xe4f\xe4\x0f\xe4\xb0\xe4O\xe5!\xe4o\xe5\x94\xe4\xa3\xe6' \ 0168 b'\x07\xe4\xbc\xe6X\xe4\xd2\xe6\xc3\xe4\xd6\xe7\x18\xe4\xf1\xe7\x83\xe5\t\xe7\xed\xe5 \xe8_\xe58\xe8' \ 0169 b'\xce\xe5r\xe9C\xe5\xae\xe9\xc9\xe5\xe9\xeao\xe6(\xeb\x06\xe6\x82\xeb\xac' 0170 elif ext == '.jpg': 0171 d = b'\xff\xd8\xff\xdb\x00C\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' \ 0172 b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' \ 0173 b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xdb\x00C\x01\xff' \ 0174 b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' \ 0175 b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' \ 0176 b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc2\x00\x11\x08\x00\n\x00\n\x03\x01"\x00\x02' \ 0177 b'\x11\x01\x03\x11\x01\xff\xc4\x00\x15\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ 0178 b'\x00\x00\x01\xff\xc4\x00\x15\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01' \ 0179 b'\x02\xff\xda\x00\x0c\x03\x01\x00\x02\x10\x03\x10\x00\x00\x01\x80\xaf\xff\xc4\x00\x14\x10\x01\x00\x00' \ 0180 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \xff\xda\x00\x08\x01\x01\x00\x01\x05\x02\x1f\xff' \ 0181 b'\xc4\x00\x14\x11\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xda\x00\x08' \ 0182 b'\x01\x03\x01\x01?\x01\x7f\xff\xc4\x00\x14\x11\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \ 0183 b'\x00\x00\x00\xff\xda\x00\x08\x01\x02\x01\x01?\x01\x7f\xff\xc4\x00\x14\x10\x01\x00\x00\x00\x00\x00\x00' \ 0184 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00 \xff\xda\x00\x08\x01\x01\x00\x06?\x02\x1f\xff\xc4\x00\x14\x10\x01' \ 0185 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \xff\xda\x00\x08\x01\x01\x00\x01?!\x1f' \ 0186 b'\xff\xda\x00\x0c\x03\x01\x00\x02\x00\x03\x00\x00\x00\x10\x0b\xff\xc4\x00\x14\x11\x01\x00\x00\x00\x00' \ 0187 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xda\x00\x08\x01\x03\x01\x01?\x10\x7f\xff\xc4\x00' \ 0188 b'\x14\x11\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xda\x00\x08\x01\x02' \ 0189 b'\x01\x01?\x10\x7f\xff\xc4\x00\x14\x10\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 ' \ 0190 b'\xff\xda\x00\x08\x01\x01\x00\x01?\x10\x1f\xff\xd9' 0191 else: 0192 d = b'' 0193 with open(filename, 'wb') as fh: 0194 fh.write(d)