def collect_output(self, buffer): iter = buffer.get_end_iter() buffer.place_cursor(iter) if not self.driver.solver.ready: sels = self.driver.solver.selections buffer.insert_at_cursor("Can't run:\n{reason}".format( reason=self.driver.solver.get_failure_reason())) return uncached = self.driver.get_uncached_implementations() if uncached: buffer.insert_at_cursor( "Can't run: the chosen versions have not been downloaded yet. I need:\n\n- " + "\n\n- ".join([ '%s version %s\n (%s)' % (x[0].uri, x[1].get_version(), x[1].id) for x in uncached ])) return sels = self.driver.solver.selections doc = sels.toDOM() self.hide() try: gtk.gdk.flush() iter = buffer.get_end_iter() buffer.place_cursor(iter) # Tell 0launch to run the program doc.documentElement.setAttribute('run-test', 'true') payload = doc.toxml('utf-8') if sys.version_info[0] > 2: stdout = sys.stdout.buffer else: stdout = sys.stdout stdout.write(('Length:%8x\n' % len(payload)).encode('utf-8') + payload) stdout.flush() reply = support.read_bytes(0, len('Length:') + 9) assert reply.startswith(b'Length:') test_output = support.read_bytes(0, int(reply.split(b':', 1)[1], 16)) # Cope with invalid UTF-8 import codecs decoder = codecs.getdecoder('utf-8') data = decoder(test_output, 'replace')[0] buffer.insert_at_cursor(data) finally: self.show()
def collect_output(self, buffer): iter = buffer.get_end_iter() buffer.place_cursor(iter) if not self.policy.ready: missing = [ iface.uri for iface in self.policy.implementation if self.policy.implementation[iface] is None ] buffer.insert_at_cursor( "Can't run: no version has been selected for:\n- " + "\n- ".join(missing)) return uncached = self.policy.get_uncached_implementations() if uncached: buffer.insert_at_cursor( "Can't run: the chosen versions have not been downloaded yet. I need:\n\n- " + "\n\n- ".join([ '%s version %s\n (%s)' % (x[0].uri, x[1].get_version(), x[1].id) for x in uncached ])) return from zeroinstall.injector import selections sels = selections.Selections(self.policy) doc = sels.toDOM() self.hide() try: gtk.gdk.flush() iter = buffer.get_end_iter() buffer.place_cursor(iter) # Tell 0launch to run the program doc.documentElement.setAttribute('run-test', 'true') payload = doc.toxml('utf-8') sys.stdout.write(('Length:%8x\n' % len(payload)) + payload) sys.stdout.flush() reply = support.read_bytes(0, len('Length:') + 9) assert reply.startswith('Length:') test_output = support.read_bytes(0, int(reply.split(':', 1)[1], 16)) # Cope with invalid UTF-8 import codecs decoder = codecs.getdecoder('utf-8') data = decoder(test_output, 'replace')[0] buffer.insert_at_cursor(data) finally: self.show()
def collect_output(self, buffer): iter = buffer.get_end_iter() buffer.place_cursor(iter) if not self.driver.solver.ready: sels = self.driver.solver.selections buffer.insert_at_cursor("Can't run:\n{reason}".format( reason = self.driver.solver.get_failure_reason())) return uncached = self.driver.get_uncached_implementations() if uncached: buffer.insert_at_cursor("Can't run: the chosen versions have not been downloaded yet. I need:\n\n- " + "\n\n- " . join(['%s version %s\n (%s)' %(x[0].uri, x[1].get_version(), x[1].id) for x in uncached])) return sels = self.driver.solver.selections doc = sels.toDOM() self.hide() try: gtk.gdk.flush() iter = buffer.get_end_iter() buffer.place_cursor(iter) # Tell 0launch to run the program doc.documentElement.setAttribute('run-test', 'true') payload = doc.toxml('utf-8') if sys.version_info[0] > 2: stdout = sys.stdout.buffer else: stdout = sys.stdout stdout.write(('Length:%8x\n' % len(payload)).encode('utf-8') + payload) stdout.flush() reply = support.read_bytes(0, len('Length:') + 9) assert reply.startswith(b'Length:') test_output = support.read_bytes(0, int(reply.split(b':', 1)[1], 16)) # Cope with invalid UTF-8 import codecs decoder = codecs.getdecoder('utf-8') data = decoder(test_output, 'replace')[0] buffer.insert_at_cursor(data) finally: self.show()
def collect_output(self, buffer): iter = buffer.get_end_iter() buffer.place_cursor(iter) if not self.policy.ready: missing = [iface.uri for iface in self.policy.implementation if self.policy.implementation[iface] is None] buffer.insert_at_cursor("Can't run: no version has been selected for:\n- " + "\n- ".join(missing)) return uncached = self.policy.get_uncached_implementations() if uncached: buffer.insert_at_cursor( "Can't run: the chosen versions have not been downloaded yet. I need:\n\n- " + "\n\n- ".join(["%s version %s\n (%s)" % (x[0].uri, x[1].get_version(), x[1].id) for x in uncached]) ) return from zeroinstall.injector import selections sels = selections.Selections(self.policy) doc = sels.toDOM() self.hide() try: gtk.gdk.flush() iter = buffer.get_end_iter() buffer.place_cursor(iter) # Tell 0launch to run the program doc.documentElement.setAttribute("run-test", "true") payload = doc.toxml("utf-8") sys.stdout.write(("Length:%8x\n" % len(payload)) + payload) sys.stdout.flush() reply = support.read_bytes(0, len("Length:") + 9) assert reply.startswith("Length:") test_output = support.read_bytes(0, int(reply.split(":", 1)[1], 16)) # Cope with invalid UTF-8 import codecs decoder = codecs.getdecoder("utf-8") data = decoder(test_output, "replace")[0] buffer.insert_at_cursor(data) finally: self.show()
def get_selections_gui(iface_uri, gui_args, test_callback = None, use_gui = True): """Run the GUI to choose and download a set of implementations. The user may ask the GUI to submit a bug report about the program. In that case, the GUI may ask us to test it. test_callback is called in that case with the implementations to be tested; the callback will typically call L{zeroinstall.injector.run.test_selections} and return the result of that. @param iface_uri: the required program, or None to show just the preferences dialog @type iface_uri: str @param gui_args: any additional arguments for the GUI itself @type gui_args: [str] @param test_callback: function to use to try running the program @type test_callback: L{zeroinstall.injector.selections.Selections} -> str @param use_gui: if True, raise a SafeException if the GUI is not available. If None, returns DontUseGUI if the GUI cannot be started. If False, returns DontUseGUI always. (since 1.11) @param use_gui: bool | None @return: the selected implementations @rtype: L{zeroinstall.injector.selections.Selections} @since: 0.28 """ if use_gui is False: return DontUseGUI if 'DISPLAY' not in os.environ: if use_gui is None: return DontUseGUI else: raise SafeException("Can't use GUI because $DISPLAY is not set") from zeroinstall.injector import selections, qdom from io import BytesIO from os.path import join, dirname gui_exe = join(dirname(__file__), '0launch-gui', '0launch-gui') import socket cli, gui = socket.socketpair() try: child = os.fork() if child == 0: # We are the child (GUI) try: try: cli.close() # We used to use pipes to support Python2.3... os.dup2(gui.fileno(), 1) os.dup2(gui.fileno(), 0) if use_gui is True: gui_args = ['-g'] + gui_args if iface_uri is not None: gui_args = gui_args + ['--', iface_uri] os.execvp(sys.executable, [sys.executable, gui_exe] + gui_args) except: import traceback traceback.print_exc(file = sys.stderr) finally: sys.stderr.flush() os._exit(1) # We are the parent (CLI) gui.close() gui = None while True: logger.info("Waiting for selections from GUI...") reply = support.read_bytes(cli.fileno(), len('Length:') + 9, null_ok = True) if reply: if not reply.startswith(b'Length:'): raise Exception("Expected Length:, but got %s" % repr(reply)) reply = reply.decode('ascii') xml = support.read_bytes(cli.fileno(), int(reply.split(':', 1)[1], 16)) dom = qdom.parse(BytesIO(xml)) sels = selections.Selections(dom) if dom.getAttribute('run-test'): logger.info("Testing program, as requested by GUI...") if test_callback is None: output = b"Can't test: no test_callback was passed to get_selections_gui()\n" else: output = test_callback(sels) logger.info("Sending results to GUI...") output = ('Length:%8x\n' % len(output)).encode('utf-8') + output logger.debug("Sending: %s", repr(output)) while output: sent = cli.send(output) output = output[sent:] continue else: sels = None pid, status = os.waitpid(child, 0) assert pid == child if status == 1 << 8: logger.info("User cancelled the GUI; aborting") return None # Aborted elif status == 100 << 8: if use_gui is None: return DontUseGUI else: raise SafeException("No GUI available") if status != 0: raise Exception("Error from GUI: code = %d" % status) break finally: for sock in [cli, gui]: if sock is not None: sock.close() return sels
def read_chunk(): l = support.read_bytes(0, 8, null_ok = True) logger.debug("Read '%s' from master", l) if not l: return None return support.read_bytes(0, int(l, 16))