def edit_book(self, file_name, progress_frac, selected_text): import subprocess from calibre.ebooks.oeb.polish.main import SUPPORTED from calibre.utils.ipc.launch import exe_path, macos_edit_book_bundle_path try: path = set_book_path.pathtoebook except AttributeError: return error_dialog(self, _('Cannot edit book'), _( 'No book is currently open'), show=True) fmt = path.rpartition('.')[-1].upper().replace('ORIGINAL_', '') if fmt not in SUPPORTED: return error_dialog(self, _('Cannot edit book'), _( 'The book must be in the %s formats to edit.' '\n\nFirst convert the book to one of these formats.' ) % (_(' or ').join(SUPPORTED)), show=True) exe = 'ebook-edit' if ismacos: exe = os.path.join(macos_edit_book_bundle_path(), exe) else: exe = exe_path(exe) cmd = [exe] if selected_text: cmd += ['--select-text', selected_text] from calibre.gui2.tweak_book.widgets import BusyCursor with sanitize_env_vars(): subprocess.Popen(cmd + [path, file_name]) with BusyCursor(): time.sleep(2)
def run(cmd): from calibre.gui2 import sanitize_env_vars with sanitize_env_vars(): p = subprocess.Popen(list(map(encode_arg, cmd)), stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() ret = p.wait() return ret, decode_output(stdout), decode_output(stderr)
def run_program(entry, path, parent): # noqa import re cmdline = entry_to_cmdline(entry, path) flags = win32con.CREATE_DEFAULT_ERROR_MODE | win32con.CREATE_NEW_PROCESS_GROUP if re.match(r'"[^"]+?(.bat|.cmd|.com)"', cmdline, flags=re.I): flags |= win32con.CREATE_NO_WINDOW console = ' (console)' else: flags |= win32con.DETACHED_PROCESS console = '' print('Running Open With commandline%s:' % console, repr(entry['cmdline']), ' |==> ', repr(cmdline)) try: with sanitize_env_vars(): process_handle, thread_handle, process_id, thread_id = CreateProcess( None, cmdline, None, None, False, flags, None, None, STARTUPINFO()) WaitForInputIdle(process_handle, 2000) except Exception as err: return error_dialog( parent, _('Failed to run'), _('Failed to run program, click "Show Details" for more information' ), det_msg='Command line: %r\n%s' % (cmdline, as_unicode(err)))
def kdialog_supports_desktopfile(): ans = getattr(kdialog_supports_desktopfile, 'ans', None) if ans is None: from calibre.gui2 import sanitize_env_vars try: with sanitize_env_vars(): raw = subprocess.check_output(['kdialog', '--help']) except (subprocess.CalledProcessError, FileNotFoundError, OSError): raw = b'--desktopfile' ans = kdialog_supports_desktopfile.ans = b'--desktopfile' in raw return ans
def run(cmd): from calibre.gui2 import sanitize_env_vars if DEBUG: try: print(cmd) except Exception: pass with sanitize_env_vars(): p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() ret = p.wait() return ret, decode_output(stdout), decode_output(stderr)
def run(cmd): from calibre.gui2 import sanitize_env_vars ecmd = list(map(encode_arg, cmd)) if DEBUG: try: print(ecmd) except Exception: pass with sanitize_env_vars(): p = subprocess.Popen(ecmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() ret = p.wait() return ret, decode_output(stdout), decode_output(stderr)
def run_program(entry, path, parent): # noqa cmdline = entry_to_cmdline(entry, path) print('Running Open With commandline:', repr(entry['cmdline']), ' |==> ', repr(cmdline)) try: with sanitize_env_vars(): process_handle, thread_handle, process_id, thread_id = CreateProcess( None, cmdline, None, None, False, win32con.CREATE_DEFAULT_ERROR_MODE | win32con.CREATE_NEW_PROCESS_GROUP | win32con.DETACHED_PROCESS, None, None, STARTUPINFO()) WaitForInputIdle(process_handle, 2000) except Exception as err: return error_dialog( parent, _('Failed to run'), _( 'Failed to run program, click "Show Details" for more information'), det_msg='Command line: %r\n%s' %(cmdline, as_unicode(err)))
def run_program(entry, path, parent): import subprocess cmdline = entry_to_cmdline(entry, path) print('Running Open With commandline:', repr(cmdline)) try: with sanitize_env_vars(): process = subprocess.Popen(cmdline) except Exception as err: return error_dialog( parent, _('Failed to run'), _( 'Failed to run program, click "Show Details" for more information'), det_msg='Command line: %r\n%s' %(cmdline, as_unicode(err))) t = Thread(name='WaitProgram', target=process.wait) t.daemon = True t.start()
def run_program(entry, path, parent): import subprocess cmdline = entry_to_cmdline(entry, path) print('Running Open With commandline:', repr(cmdline)) try: with sanitize_env_vars(): process = subprocess.Popen(cmdline) except Exception as err: return error_dialog( parent, _('Failed to run'), _( 'Failed to run program, click "Show details" for more information'), det_msg='Command line: %r\n%s' %(cmdline, as_unicode(err))) t = Thread(name='WaitProgram', target=process.wait) t.daemon = True t.start()
def run_program(entry, path, parent): # noqa import re cmdline = entry_to_cmdline(entry, path) flags = subprocess.CREATE_DEFAULT_ERROR_MODE | subprocess.CREATE_NEW_PROCESS_GROUP if re.match(r'"[^"]+?(.bat|.cmd|.com)"', cmdline, flags=re.I): flags |= subprocess.CREATE_NO_WINDOW console = ' (console)' else: flags |= subprocess.DETACHED_PROCESS console = '' print('Running Open With commandline%s:' % console, repr(entry['cmdline']), ' |==> ', repr(cmdline)) try: with sanitize_env_vars(): winutil.run_cmdline(cmdline, flags, 2000) except Exception as err: return error_dialog( parent, _('Failed to run'), _( 'Failed to run program, click "Show details" for more information'), det_msg='Command line: %r\n%s' %(cmdline, as_unicode(err)))
def run_program(entry, path, parent): # noqa import re cmdline = entry_to_cmdline(entry, path) flags = win32con.CREATE_DEFAULT_ERROR_MODE | win32con.CREATE_NEW_PROCESS_GROUP if re.match(r'"[^"]+?(.bat|.cmd|.com)"', cmdline, flags=re.I): flags |= win32con.CREATE_NO_WINDOW console = ' (console)' else: flags |= win32con.DETACHED_PROCESS console = '' print('Running Open With commandline%s:' % console, repr(entry['cmdline']), ' |==> ', repr(cmdline)) try: with sanitize_env_vars(): process_handle, thread_handle, process_id, thread_id = CreateProcess( None, cmdline, None, None, False, flags, None, None, STARTUPINFO()) WaitForInputIdle(process_handle, 2000) except Exception as err: return error_dialog( parent, _('Failed to run'), _( 'Failed to run program, click "Show Details" for more information'), det_msg='Command line: %r\n%s' %(cmdline, as_unicode(err)))
def run_file_dialog( parent=None, title=None, initial_folder=None, filename=None, save_path=None, allow_multiple=False, only_dirs=False, confirm_overwrite=True, save_as=False, no_symlinks=False, file_types=() ): from calibre.gui2 import sanitize_env_vars with sanitize_env_vars(): env = os.environ.copy() pipename = '\\\\.\\pipe\\%s' % uuid4() data = [serialize_string('PIPENAME', pipename)] parent = parent or None if parent is not None: data.append(serialize_hwnd(get_hwnd(parent))) if title: data.append(serialize_string('TITLE', title)) if no_symlinks: data.append(serialize_binary('NO_SYMLINKS', no_symlinks)) if save_as: data.append(serialize_binary('SAVE_AS', save_as)) if confirm_overwrite: data.append(serialize_binary('CONFIRM_OVERWRITE', confirm_overwrite)) if save_path is not None: save_path = process_path(save_path) if os.path.exists(save_path): data.append(serialize_string('SAVE_PATH', save_path)) else: if not initial_folder: initial_folder = select_initial_dir(save_path) if not filename: filename = os.path.basename(save_path) else: if allow_multiple: data.append(serialize_binary('MULTISELECT', allow_multiple)) if only_dirs: data.append(serialize_binary('ONLY_DIRS', only_dirs)) if initial_folder is not None: initial_folder = process_path(initial_folder) if os.path.isdir(initial_folder): data.append(serialize_string('FOLDER', initial_folder)) if filename: if isinstance(filename, bytes): filename = filename.decode(filesystem_encoding) data.append(serialize_string('FILENAME', filename)) if only_dirs: file_types = () # file types not allowed for dir only dialogs elif not file_types: file_types = [(_('All files'), ('*',))] if file_types: data.append(serialize_file_types(file_types)) loop = Loop() server = PipeServer(pipename) h = Helper(subprocess.Popen( [HELPER], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, env=env), data, loop.dialog_closed.emit) h.start() loop.exec_(QEventLoop.ExcludeUserInputEvents) def decode(x): x = x or b'' try: x = x.decode('utf-8') except Exception: x = repr(x) return x if h.rc != 0: raise Exception('File dialog failed: ' + decode(h.stdoutdata) + ' ' + decode(h.stderrdata)) server.join(2) if server.is_alive(): raise Exception('Timed out waiting for read from pipe to complete') if server.err_msg: raise Exception(server.err_msg) if not server.data: return () ans = tuple((os.path.abspath(x.decode('utf-8')) for x in server.data.split(b'\0') if x)) return ans
def run_file_dialog( parent=None, title=None, initial_folder=None, filename=None, save_path=None, allow_multiple=False, only_dirs=False, confirm_overwrite=True, save_as=False, no_symlinks=False, file_types=(), default_ext=None ): from calibre.gui2 import sanitize_env_vars secret = os.urandom(32).replace(b'\0', b' ') pipename = '\\\\.\\pipe\\%s' % uuid4() data = [serialize_string('PIPENAME', pipename), serialize_secret(secret)] parent = parent or None if parent is not None: data.append(serialize_hwnd(get_hwnd(parent))) if title: data.append(serialize_string('TITLE', title)) if no_symlinks: data.append(serialize_binary('NO_SYMLINKS', no_symlinks)) if save_as: data.append(serialize_binary('SAVE_AS', save_as)) if confirm_overwrite: data.append(serialize_binary('CONFIRM_OVERWRITE', confirm_overwrite)) if save_path is not None: save_path = process_path(save_path) if os.path.exists(save_path): data.append(serialize_string('SAVE_PATH', save_path)) else: if not initial_folder: initial_folder = select_initial_dir(save_path) if not filename: filename = os.path.basename(save_path) else: if allow_multiple: data.append(serialize_binary('MULTISELECT', allow_multiple)) if only_dirs: data.append(serialize_binary('ONLY_DIRS', only_dirs)) if initial_folder is not None: initial_folder = process_path(initial_folder) if os.path.isdir(initial_folder): data.append(serialize_string('FOLDER', initial_folder)) if filename: if isinstance(filename, bytes): filename = filename.decode(filesystem_encoding) data.append(serialize_string('FILENAME', filename)) if only_dirs: file_types = () # file types not allowed for dir only dialogs elif not file_types: file_types = [(_('All files'), ('*',))] if file_types: data.append(serialize_file_types(file_types)) if default_ext: data.append(serialize_string('DEFAULT_EXTENSION', default_ext)) loop = Loop() server = PipeServer(pipename) with sanitize_env_vars(): h = Helper(subprocess.Popen( [HELPER], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE), data, loop.dialog_closed.emit) h.start() loop.exec_(QEventLoop.ExcludeUserInputEvents) def decode(x): x = x or b'' try: x = x.decode('utf-8') except Exception: x = repr(x) return x def get_errors(): return decode(h.stdoutdata) + ' ' + decode(h.stderrdata) from calibre import prints from calibre.constants import DEBUG if DEBUG: prints('stdout+stderr from file dialog helper:', type('')([h.stdoutdata, h.stderrdata])) if h.rc != 0: raise Exception('File dialog failed (return code %s): %s' % (h.rc, get_errors())) server.join(2) if server.is_alive(): raise Exception('Timed out waiting for read from pipe to complete') if server.err_msg: raise Exception(server.err_msg) if not server.data: return () parts = list(filter(None, server.data.split(b'\0'))) if DEBUG: prints('piped data from file dialog helper:', type('')(parts)) if len(parts) < 2: return () if parts[0] != secret: raise Exception('File dialog failed, incorrect secret received: ' + get_errors()) ans = tuple((os.path.abspath(x.decode('utf-8')) for x in parts[1:])) return ans
def run_file_dialog(parent=None, title=None, initial_folder=None, filename=None, save_path=None, allow_multiple=False, only_dirs=False, confirm_overwrite=True, save_as=False, no_symlinks=False, file_types=(), default_ext=None, app_uid=None): from calibre.gui2 import sanitize_env_vars secret = os.urandom(32).replace(b'\0', b' ') pipename = '\\\\.\\pipe\\%s' % uuid4() data = [serialize_string('PIPENAME', pipename), serialize_secret(secret)] parent = parent or None if parent is not None: data.append(serialize_hwnd(get_hwnd(parent))) if title: data.append(serialize_string('TITLE', title)) if no_symlinks: data.append(serialize_binary('NO_SYMLINKS', no_symlinks)) if save_as: data.append(serialize_binary('SAVE_AS', save_as)) if confirm_overwrite: data.append( serialize_binary('CONFIRM_OVERWRITE', confirm_overwrite)) if save_path is not None: save_path = process_path(save_path) if os.path.exists(save_path): data.append(serialize_string('SAVE_PATH', save_path)) else: if not initial_folder: initial_folder = select_initial_dir(save_path) if not filename: filename = os.path.basename(save_path) else: if allow_multiple: data.append(serialize_binary('MULTISELECT', allow_multiple)) if only_dirs: data.append(serialize_binary('ONLY_DIRS', only_dirs)) if initial_folder is not None: initial_folder = process_path(initial_folder) if os.path.isdir(initial_folder): data.append(serialize_string('FOLDER', initial_folder)) if filename: if isinstance(filename, bytes): filename = os.fsdecode(filename) data.append(serialize_string('FILENAME', filename)) if only_dirs: file_types = () # file types not allowed for dir only dialogs elif not file_types: file_types = [(_('All files'), ('*', ))] if file_types: data.append(serialize_file_types(file_types)) if default_ext: data.append(serialize_string('DEFAULT_EXTENSION', default_ext)) app_uid = app_uid or current_app_uid if app_uid: data.append(serialize_string('APP_UID', app_uid)) from qt.core import QEventLoop, Qt, pyqtSignal class Loop(QEventLoop): dialog_closed = pyqtSignal() def __init__(self): QEventLoop.__init__(self) self.dialog_closed.connect(self.exit, type=Qt.ConnectionType.QueuedConnection) loop = Loop() server = PipeServer(pipename) server.start() with sanitize_env_vars(): h = Helper( subprocess.Popen([HELPER], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE), data, loop.dialog_closed.emit) h.start() loop.exec(QEventLoop.ProcessEventsFlag.ExcludeUserInputEvents) def decode(x): x = x or b'' try: x = x.decode('utf-8') except Exception: x = repr(x) return x def get_errors(): return decode(h.stdoutdata) + ' ' + decode(h.stderrdata) from calibre import prints from calibre.constants import DEBUG if DEBUG: prints('stdout+stderr from file dialog helper:', str([h.stdoutdata, h.stderrdata])) if h.rc != 0: raise Exception( f'File dialog failed (return code {h.rc}): {get_errors()}') server.join(2) if server.is_alive(): raise Exception('Timed out waiting for read from pipe to complete') if server.err_msg: raise Exception(server.err_msg) if not server.data: return () parts = list(filter(None, server.data.split(b'\0'))) if DEBUG: prints('piped data from file dialog helper:', str(parts)) if len(parts) < 2: return () if parts[0] != secret: raise Exception('File dialog failed, incorrect secret received: ' + get_errors()) from calibre_extensions.winutil import get_long_path_name def fix_path(x): u = os.path.abspath(x.decode('utf-8')) with suppress(Exception): try: return get_long_path_name(u) except FileNotFoundError: base, fn = os.path.split(u) return os.path.join(get_long_path_name(base), fn) return u ans = tuple(map(fix_path, parts[1:])) return ans
def __init__( self, title=_('Choose Files'), filters=[], add_all_files_filter=True, parent=None, modal=True, name='', mode=QFileDialog.ExistingFiles, default_dir=u'~', no_save_dir=False, combine_file_and_saved_dir=False ): from calibre.gui2 import dynamic, sanitize_env_vars from calibre.gui2.ui import get_gui gui = get_gui() adapt_menubar = gui.bars_manager.adapt_menu_bar_for_dialog if gui is not None else Dummy() QObject.__init__(self) ftext = '' if filters: for filter in filters: text, extensions = filter extensions = ['*'+(i if i.startswith('.') else '.'+i) for i in extensions] ftext += '%s (%s);;'%(text, ' '.join(extensions)) if add_all_files_filter or not ftext: ftext += 'All files (*)' if ftext.endswith(';;'): ftext = ftext[:-2] self.dialog_name = dialog_name(name, title) self.selected_files = None self.fd = None if combine_file_and_saved_dir: bn = os.path.basename(default_dir) prev = dynamic.get(self.dialog_name, os.path.expanduser(u'~')) if os.path.exists(prev): if os.path.isfile(prev): prev = os.path.dirname(prev) else: prev = os.path.expanduser(u'~') initial_dir = os.path.join(prev, bn) elif no_save_dir: initial_dir = os.path.expanduser(default_dir) else: initial_dir = dynamic.get(self.dialog_name, os.path.expanduser(default_dir)) if not isinstance(initial_dir, string_or_bytes): initial_dir = os.path.expanduser(default_dir) if not initial_dir or (not os.path.exists(initial_dir) and not ( mode == QFileDialog.AnyFile and (no_save_dir or combine_file_and_saved_dir))): initial_dir = select_initial_dir(initial_dir) self.selected_files = [] use_native_dialog = 'CALIBRE_NO_NATIVE_FILEDIALOGS' not in os.environ with sanitize_env_vars(): opts = QFileDialog.Option() if not use_native_dialog: opts |= QFileDialog.DontUseNativeDialog if mode == QFileDialog.AnyFile: with adapt_menubar: f = QFileDialog.getSaveFileName(parent, title, initial_dir, ftext, "", opts) if f and f[0]: self.selected_files.append(f[0]) elif mode == QFileDialog.ExistingFile: with adapt_menubar: f = QFileDialog.getOpenFileName(parent, title, initial_dir, ftext, "", opts) if f and f[0] and os.path.exists(f[0]): self.selected_files.append(f[0]) elif mode == QFileDialog.ExistingFiles: with adapt_menubar: fs = QFileDialog.getOpenFileNames(parent, title, initial_dir, ftext, "", opts) if fs and fs[0]: for f in fs[0]: f = unicode_type(f) if not f: continue if not os.path.exists(f): # QFileDialog for some reason quotes spaces # on linux if there is more than one space in a row f = unquote(f) if f and os.path.exists(f): self.selected_files.append(f) else: if mode == QFileDialog.Directory: opts |= QFileDialog.ShowDirsOnly with adapt_menubar: f = unicode_type(QFileDialog.getExistingDirectory(parent, title, initial_dir, opts)) if os.path.exists(f): self.selected_files.append(f) if self.selected_files: self.selected_files = [unicode_type(q) for q in self.selected_files] saved_loc = self.selected_files[0] if os.path.isfile(saved_loc): saved_loc = os.path.dirname(saved_loc) if not no_save_dir: dynamic[self.dialog_name] = saved_loc self.accepted = bool(self.selected_files)
def __init__(self, title=_('Choose Files'), filters=[], add_all_files_filter=True, parent=None, modal=True, name='', mode=QFileDialog.ExistingFiles, default_dir=u'~', no_save_dir=False, combine_file_and_saved_dir=False ): from calibre.gui2 import dynamic, sanitize_env_vars QObject.__init__(self) ftext = '' if filters: for filter in filters: text, extensions = filter extensions = ['*'+(i if i.startswith('.') else '.'+i) for i in extensions] ftext += '%s (%s);;'%(text, ' '.join(extensions)) if add_all_files_filter or not ftext: ftext += 'All files (*)' if ftext.endswith(';;'): ftext = ftext[:-2] self.dialog_name = dialog_name(name, title) self.selected_files = None self.fd = None if combine_file_and_saved_dir: bn = os.path.basename(default_dir) prev = dynamic.get(self.dialog_name, expanduser(u'~')) if os.path.exists(prev): if os.path.isfile(prev): prev = os.path.dirname(prev) else: prev = expanduser(u'~') initial_dir = os.path.join(prev, bn) elif no_save_dir: initial_dir = expanduser(default_dir) else: initial_dir = dynamic.get(self.dialog_name, expanduser(default_dir)) if not isinstance(initial_dir, basestring): initial_dir = expanduser(default_dir) if not initial_dir or (not os.path.exists(initial_dir) and not ( mode == QFileDialog.AnyFile and (no_save_dir or combine_file_and_saved_dir))): initial_dir = select_initial_dir(initial_dir) self.selected_files = [] use_native_dialog = 'CALIBRE_NO_NATIVE_FILEDIALOGS' not in os.environ with sanitize_env_vars(): opts = QFileDialog.Option() if not use_native_dialog: opts |= QFileDialog.DontUseNativeDialog if mode == QFileDialog.AnyFile: f = QFileDialog.getSaveFileName(parent, title, initial_dir, ftext, "", opts) if f and f[0]: self.selected_files.append(f[0]) elif mode == QFileDialog.ExistingFile: f = QFileDialog.getOpenFileName(parent, title, initial_dir, ftext, "", opts) if f and f[0] and os.path.exists(f[0]): self.selected_files.append(f[0]) elif mode == QFileDialog.ExistingFiles: fs = QFileDialog.getOpenFileNames(parent, title, initial_dir, ftext, "", opts) if fs and fs[0]: for f in fs[0]: f = unicode(f) if not f: continue if not os.path.exists(f): # QFileDialog for some reason quotes spaces # on linux if there is more than one space in a row f = unquote(f) if f and os.path.exists(f): self.selected_files.append(f) else: if mode == QFileDialog.Directory: opts |= QFileDialog.ShowDirsOnly f = unicode(QFileDialog.getExistingDirectory(parent, title, initial_dir, opts)) if os.path.exists(f): self.selected_files.append(f) if self.selected_files: self.selected_files = [unicode(q) for q in self.selected_files] saved_loc = self.selected_files[0] if os.path.isfile(saved_loc): saved_loc = os.path.dirname(saved_loc) if not no_save_dir: dynamic[self.dialog_name] = saved_loc self.accepted = bool(self.selected_files)
def run_file_dialog(parent=None, title=None, initial_folder=None, filename=None, save_path=None, allow_multiple=False, only_dirs=False, confirm_overwrite=True, save_as=False, no_symlinks=False, file_types=()): from calibre.gui2 import sanitize_env_vars with sanitize_env_vars(): env = os.environ.copy() pipename = '\\\\.\\pipe\\%s' % uuid4() data = [serialize_string('PIPENAME', pipename)] parent = parent or None if parent is not None: data.append(serialize_hwnd(get_hwnd(parent))) if title: data.append(serialize_string('TITLE', title)) if no_symlinks: data.append(serialize_binary('NO_SYMLINKS', no_symlinks)) if save_as: data.append(serialize_binary('SAVE_AS', save_as)) if confirm_overwrite: data.append( serialize_binary('CONFIRM_OVERWRITE', confirm_overwrite)) if save_path is not None: save_path = process_path(save_path) if os.path.exists(save_path): data.append(serialize_string('SAVE_PATH', save_path)) else: if not initial_folder: initial_folder = select_initial_dir(save_path) if not filename: filename = os.path.basename(save_path) else: if allow_multiple: data.append(serialize_binary('MULTISELECT', allow_multiple)) if only_dirs: data.append(serialize_binary('ONLY_DIRS', only_dirs)) if initial_folder is not None: initial_folder = process_path(initial_folder) if os.path.isdir(initial_folder): data.append(serialize_string('FOLDER', initial_folder)) if filename: if isinstance(filename, bytes): filename = filename.decode(filesystem_encoding) data.append(serialize_string('FILENAME', filename)) if only_dirs: file_types = () # file types not allowed for dir only dialogs elif not file_types: file_types = [(_('All files'), ('*', ))] if file_types: data.append(serialize_file_types(file_types)) loop = Loop() server = PipeServer(pipename) h = Helper( subprocess.Popen([HELPER], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, env=env), data, loop.dialog_closed.emit) h.start() loop.exec_(QEventLoop.ExcludeUserInputEvents) def decode(x): x = x or b'' try: x = x.decode('utf-8') except Exception: x = repr(x) return x if h.rc != 0: raise Exception('File dialog failed: ' + decode(h.stdoutdata) + ' ' + decode(h.stderrdata)) server.join(2) if server.is_alive(): raise Exception('Timed out waiting for read from pipe to complete') if server.err_msg: raise Exception(server.err_msg) if not server.data: return () ans = tuple((os.path.abspath(x.decode('utf-8')) for x in server.data.split(b'\0') if x)) return ans