| 155 | return data |
| 156 | |
| 157 | def spawn_external_viewer(self, data, contenttype): |
| 158 | if contenttype: |
| 159 | contenttype = contenttype.split(";")[0] |
| 160 | ext = mimetypes.guess_extension(contenttype) or "" |
| 161 | else: |
| 162 | ext = "" |
| 163 | fd, name = tempfile.mkstemp(ext, "mproxy") |
| 164 | os.write(fd, data) |
| 165 | os.close(fd) |
| 166 | |
| 167 | # read-only to remind the user that this is a view function |
| 168 | os.chmod(name, stat.S_IREAD) |
| 169 | |
| 170 | # hm which one should get priority? |
| 171 | c = ( |
| 172 | os.environ.get("MITMPROXY_EDITOR") |
| 173 | or os.environ.get("PAGER") |
| 174 | or os.environ.get("EDITOR") |
| 175 | ) |
| 176 | if not c: |
| 177 | c = "less" |
| 178 | cmd = shlex.split(c) |
| 179 | cmd.append(name) |
| 180 | |
| 181 | with self.uistopped(): |
| 182 | try: |
| 183 | subprocess.call(cmd, shell=False) |
| 184 | except Exception: |
| 185 | signals.status_message.send( |
| 186 | message="Can't start external viewer: %s" % " ".join(c) |
| 187 | ) |
| 188 | # add a small delay before deletion so that the file is not removed before being loaded by the viewer |
| 189 | t = threading.Timer(1.0, os.unlink, args=[name]) |
| 190 | t.start() |
| 191 | |
| 192 | def set_palette(self, *_) -> None: |
| 193 | self.ui.register_palette( |