def spawn_external_viewer(self, data, contenttype): if contenttype: contenttype = contenttype.split(";")[0] ext = mimetypes.guess_extension(contenttype) or "" else: ext = "" fd, name = tempfile.mkstemp(ext, "mproxy") os.write(fd, data) os.close(fd) # read-only to remind the user that this is a view function os.chmod(name, stat.S_IREAD) cmd = None shell = False if contenttype: c = mailcap.getcaps() cmd, _ = mailcap.findmatch(c, contenttype, filename=name) if cmd: shell = True if not cmd: # hm which one should get priority? c = os.environ.get("PAGER") or os.environ.get("EDITOR") if not c: c = "less" cmd = shlex.split(c) cmd.append(name) self.ui.stop() try: subprocess.call(cmd, shell=shell) except: signals.status_message.send(message="Can't start external viewer: %s" % " ".join(c)) self.ui.start() os.unlink(name)
def test_mock_getcaps(self): # Test mailcap.getcaps() using mock mailcap file in this dir. # Temporarily override any existing system mailcap file by pointing the # MAILCAPS environment variable to our mock file. with test.support.EnvironmentVarGuard() as env: env["MAILCAPS"] = MAILCAPFILE caps = mailcap.getcaps() self.assertDictEqual(caps, MAILCAPDICT)
def __init__(self): self.hooks = None self._mailcaps = mailcap.getcaps() self._notmuchconfig = None self._theme = None self._accounts = None self._accountmap = None self._notmuchconfig = None self._config = ConfigObj() self._bindings = None
def test_system_mailcap(self): # Test mailcap.getcaps() with mailcap file(s) on system, if any. caps = mailcap.getcaps() self.assertIsInstance(caps, dict) mailcapfiles = mailcap.listmailcapfiles() existingmcfiles = [mcf for mcf in mailcapfiles if os.path.exists(mcf)] if existingmcfiles: # At least 1 mailcap file exists, so test that. for (k, v) in caps.items(): self.assertIsInstance(k, str) self.assertIsInstance(v, list) for e in v: self.assertIsInstance(e, dict) else: # No mailcap files on system. getcaps() should return empty dict. self.assertEqual({}, caps)
def get_viewer_cmd(aMimeType = None, aFileName = None, aToken = None): """Return command for viewer for this mime type complete with this file""" if aFileName is None: _log.error("You should specify a file name for the replacement of %s.") # last resort: if no file name given replace %s in original with literal '%s' # and hope for the best - we certainly don't want the module default "/dev/null" aFileName = """%s""" mailcaps = mailcap.getcaps() (viewer, junk) = mailcap.findmatch(mailcaps, aMimeType, key = 'view', filename = '%s' % aFileName) # FIXME: we should check for "x-token" flags _log.debug("<%s> viewer: [%s]" % (aMimeType, viewer)) return viewer
def test_backwards_compatible(self): os.environ['MAILCAPS'] = TRIVIAL d = mailcap.getcaps() d_lineno = mailcap_fix.getcaps() # Note: Both of these cases should not break, but they will exhibit the # old, incorrect behavior and return the second entry # Call the patched findmatch() using an dict without ``lineno`` command, entry = mailcap_fix.findmatch(d, 'image/jpeg', filename='a') self.assertEqual(command, 'eog a') # Call the original findmatch() using a dict with the added ``lineno`` command, entry = mailcap.findmatch(d_lineno, 'image/jpeg', filename='a') self.assertEqual(command, 'eog a')
def get_editor_cmd(mimetype=None, filename=None): if filename is None: _log.error("You should specify a file name for the replacement of %s.") # last resort: if no file name given replace %s in original with literal '%s' # and hope for the best - we certainly don't want the module default "/dev/null" filename = """%s""" mailcaps = mailcap.getcaps() (editor, junk) = mailcap.findmatch(mailcaps, mimetype, key = 'edit', filename = '%s' % filename) # FIXME: we should check for "x-token" flags _log.debug("<%s> editor: [%s]" % (mimetype, editor)) return editor
def run_viewer(file_): """Run PDF viewer on given file. Run it on a remote station if requested in configuration and the remote station is available. Arguments: file_ -- tempfile.NamedTemporaryFile instance """ import subprocess file_name = file_.name viewer = config.postscript_viewer remote = (config.rpc_remote_view and pytis.remote.client_available()) if remote: suffix = (os.path.splitext(file_name)[1] or '.pdf') try: remote_file = pytis.remote.make_temporary_file(suffix=suffix) if remote_file is None: remote = False except: remote = False if remote: try: f = open(file_name) while True: data = f.read(10000000) if not data: break remote_file.write(data) f.close() finally: remote_file.close() pytis.remote.launch_file(remote_file.name()) elif viewer: call_args = viewer.split() subprocess.call(call_args + [file_name]) else: import mailcap match = mailcap.findmatch(mailcap.getcaps(), 'application/pdf')[1] if match: command = match['view'] % (file_name,) os.system(command) else: from pytis.form import run_dialog run_dialog(Error, _("No PDF viewer found."))
def _getEditorOrViewerForType(path, type, preferEdit): caps = mailcap.getcaps() alt1 = alt2 = alt3 = None if type in caps: for cap in caps[type]: if 'test' in cap and cap['test']: if os.system(cap['test']) != 0: continue text = ('needsterminal' in cap or 'copiousoutput' in cap) if 'edit' in cap: if text: if preferEdit: if alt1 is None: alt1 = EditorViewer(cap['edit'] % path, True, True) else: if alt3 is None: alt3 = EditorViewer(cap['edit'] % path, True, True) else: if preferEdit: return EditorViewer(cap['edit'] % path, True, False) else: if alt2 is None: alt2 = EditorViewer(cap['edit'] % path, True, False) if 'view' in cap: if text: if preferEdit: if alt3 is None: alt3 = EditorViewer(cap['view'] % path, False, True) else: if alt1 is None: alt1 = EditorViewer(cap['view'] % path, False, True) else: if preferEdit: if alt2 is None: alt2 = EditorViewer(cap['view'] % path, False, False) else: return EditorViewer(cap['view'] % path, False, False) if alt1 is not None: return alt1 elif alt2 is not None: return alt2 elif alt3 is not None: return alt3 return None
def open_file(filename): if not os.path.isfile(filename): msg = 'File %s not found.' % filename raise Exception(msg) # Add mime types that may not be officially recognized mimetypes.add_type('text/csv', '.csv', strict=False) mime_type = mimetypes.guess_type(filename, strict=0)[0] if not mime_type: raise Exception( 'File type has no association. Check your mailcap file.' ) cap = mailcap.findmatch( mailcap.getcaps(), mime_type, filename="'%s'" % (filename) ) command = cap[0] os.system(command + ' &')
def __init__(self, alot_rc=None, notmuch_rc=None): """ :param alot_rc: path to alot's config file :type alot_rc: str :param notmuch_rc: path to notmuch's config file :type notmuch_rc: str """ self.hooks = None self._mailcaps = mailcap.getcaps() self._config = ConfigObj() self._notmuchconfig = None self._theme = None self._accounts = None self._accountmap = None bindings_path = os.path.join(DEFAULTSPATH, 'default.bindings') self._bindings = ConfigObj(bindings_path) if alot_rc is not None: self.read_config(alot_rc) if notmuch_rc is not None: self.read_notmuch_config(notmuch_rc)
def __init__(self, alot_rc=None, notmuch_rc=None, theme=None): """ :param alot_rc: path to alot's config file :type alot_rc: str :param notmuch_rc: path to notmuch's config file :type notmuch_rc: str :theme: path to initially used theme file :type theme: str """ self.hooks = None self._mailcaps = mailcap.getcaps() theme_path = theme or os.path.join(DEFAULTSPATH, 'default.theme') self._theme = Theme(theme_path) self._bindings = ConfigObj() self._config = ConfigObj() self._accounts = None self._accountmap = None self.read_config(alot_rc) self.read_notmuch_config(notmuch_rc)
def __init__(self, alot_rc=None, notmuch_rc=None): """ :param alot_rc: path to alot's config file :type alot_rc: str :param notmuch_rc: path to notmuch's config file :type notmuch_rc: str """ assert alot_rc is None or (isinstance(alot_rc, basestring) and os.path.exists(alot_rc)) assert notmuch_rc is None or (isinstance(notmuch_rc, basestring) and os.path.exists(notmuch_rc)) self.hooks = None self._mailcaps = mailcap.getcaps() self._config = ConfigObj() self._notmuchconfig = None self._theme = None self._accounts = None self._accountmap = None self.alot_rc_path = alot_rc self.notmuch_rc_path = notmuch_rc self._notmuchconfig = None self._config = ConfigObj() self._bindings = None self.reload()
def GetMimeCommands(self, mimeType = None, ext = None): """ """ cdict = dict() view = 'view' if mimeType == None: mimeType = self.GetMimeType(extension = ext) # We only care about mapping view to Open caps = mailcap.getcaps() # This always returns a tuple, so this should be safe if mimeType != None: match = mailcap.findmatch(caps, mimeType, view)[1] else: return cdict if match != None: cdict['Open'] = match[view] return cdict
def displayFile(self, filerec): """Uses a new method of file storage with blobs""" #now we just get the blob from the filerecord object... from PILView import PILViewer from PEATDB.Record import FileRecord #check class if not type(filerec) is FileRecord: return False myblob = filerec.blob ext = filerec.ext mtype = filerec.mimetype print 'mimetype is', mtype if myblob != None: f = myblob.open("r") filename = f.name f.close() else: return False if self.currplatform == 'Linux': #try using mailcaps on linux system import mailcap, os d=mailcap.getcaps() print mtype, filename f=mailcap.findmatch(d, mtype)[1] os.system(f['view'] %filename) return else: import os, tempfile, shutil tempname = os.path.normpath(os.path.join(tempfile.gettempdir(), filerec.name)) if not os.path.exists(tempname): #os.remove(tempname) shutil.copy(filename, tempname) os.startfile(tempname) return True
def getUnixHandler(self, mime_types): ## in case the type has more than one mime-type, only use ## the first one for now... mime_type = mime_types[0] import mailcap caps = mailcap.getcaps() match = mailcap.findmatch(caps, mime_type) if match == (None, None): return "<None>" else: try: cmd = match[0] exec_path = cmd.split() exec_file = os.path.split(exec_path[0])[1] except: return "<None>" if len(exec_path) > 2: return exec_file + " " + ' '.join(exec_path[1:-1]) else: return exec_file
def keypress(self, size, key): if key == "tab": if self.viewing == self.REQ: self.view_response() else: self.view_request() elif key in ("up", "down", "page up", "page down"): # Why doesn't this just work?? self.w.body.keypress(size, key) elif key == "a": self.flow.accept_intercept() self.master.view_connection(self.flow) elif key == "A": self.master.accept_all() self.master.view_connection(self.flow) elif key == "b": self.binary = not self.binary self.master.refresh_connection(self.flow) elif key == "e": if self.viewing == self.REQ: self.master.prompt_onekey( "Edit request ", ( ("header", "h"), ("body", "b"), ("url", "u"), ("method", "m") ), self.edit ) else: self.master.prompt_onekey( "Edit response ", ( ("header", "h"), ("body", "b"), ), self.edit ) key = None elif key == "r": r = self.state.replay(self.flow, self.master.masterq) if r: self.master.statusbar.message(r) self.master.refresh_connection(self.flow) elif key == "R": self.state.revert(self.flow) self.master.refresh_connection(self.flow) elif key == "S": if self.viewing == self.REQ: self.master.prompt("Save request: ", self.save_connection) else: self.master.prompt("Save response: ", self.save_connection) elif key == "v": if self.viewing == self.REQ: conn = self.flow.request else: conn = self.flow.response if conn.content: t = conn.headers.get("content-type", [None]) t = t[0] if t: ext = mimetypes.guess_extension(t) or "" else: ext = "" fd, name = tempfile.mkstemp(ext, "mproxy") os.write(fd, conn.content) os.close(fd) t = conn.headers.get("content-type", [None]) t = t[0] cmd = None shell = False if t: c = mailcap.getcaps() cmd, _ = mailcap.findmatch(c, t, filename=name) if cmd: shell = True if not cmd: c = os.environ.get("PAGER") or os.environ.get("EDITOR") cmd = [c, name] ret = subprocess.call(cmd, shell=shell) # Not sure why, unless we do this we get a visible cursor after # spawning 'less'. self.master.ui._curs_set(1) self.master.ui.clear() os.unlink(name) return key
def handle_meta(self, errcode, errmsg, headers): if not self.handle_meta_prelim(errcode, errmsg, headers): return # This updates the attributes in the bookmarks database. try: bkmks = self.last_context.app.bookmarks_controller except AttributeError: pass else: last_modified = None if headers.has_key("last-modified"): try: last_modified = ht_time.parse(headers["last-modified"]) except ValueError: pass bkmks.record_visit(self.url, last_modified) content_encoding, transfer_encoding = get_encodings(headers) if headers.has_key('content-type'): content_type = headers['content-type'] if ';' in content_type: content_type = string.strip( content_type[:string.index(content_type, ';')]) else: content_type, encoding = self.app.guess_type(self.url) if not content_encoding: content_encoding = encoding real_content_type = content_type or "unknown" real_content_encoding = content_encoding if (transfer_encoding and not transfer_decoding_wrappers.has_key(transfer_encoding)) \ or (content_encoding and not content_decoding_wrappers.has_key(content_encoding)): # XXX provisional hack -- change content type to octet stream content_type = "application/octet-stream" transfer_encoding = None content_encoding = None if not content_type: content_type = "text/plain" # Last resort guess only istext = content_type and content_type[:5] == 'text/' \ and not (content_encoding or transfer_encoding) if self.show_source and istext: content_type = 'text/plain' parserclass = self.find_parser_extension(content_type) if not parserclass and istext: if content_type != 'text/plain': # still need to check for text/plain parserclass = self.find_parser_extension('text/plain') if not parserclass: parserclass = TextParser if not parserclass: # Don't know how to display this. # First consult mailcap. import mailcap global caps if not caps: caps = mailcap.getcaps() if caps: plist = [] # XXX Should be taken from Content-type header command, entry = mailcap.findmatch( caps, content_type, 'view', "/dev/null", plist) if command: # Retrieve to temporary file. import tempfile self.save_mailcap = command self.save_filename = tempfile.mktemp() self.save_content_type = content_type self.save_plist = plist self.save_file = open(self.save_filename, "wb") # remember the original click location self.app.global_history.remember_url(self.url) self.viewer.remove_temp_tag(histify=1) return # No relief from mailcap either. # Ask the user whether and where to save it. # Stop the transfer, and restart when we're ready. context = self.last_context # TBD: hack so that Context.rmreader() doesn't call # Viewer.remove_temp_tag(). We'll call that later # explicitly once we know whether the file has been saved # or not. context.source = None self.stop() context.message("Wait for save dialog...") encoding = '' if real_content_encoding: encoding = real_content_encoding + "ed " if encoding[:2] == "x-": encoding = encoding[2:] encoding_label = "MIME type: %s%s" % (encoding, real_content_type) import FileDialog fd = FileDialog.SaveFileDialog(context.root) label = Label(fd.top, text=encoding_label) label.pack(before=fd.filter) # give it a default filename on which save within the # current directory urlasfile = string.splitfields(self.url, '/') fn = fd.go(default=urlasfile[-1], key="save") if not fn: # User canceled. Stop the transfer. self.viewer.remove_temp_tag() return self.viewer.remove_temp_tag(histify=1) self.app.global_history.remember_url(self.url) # Prepare to save. # Always save in binary mode. try: self.save_file = open(fn, "wb") except IOError, msg: context.error_dialog(IOError, msg) return TransferDisplay(context, fn, self) return
:returns: a command line to be applied upon keypress :rtype: str """ cmdline = self.get(mode + '-maps', key) if not cmdline: cmdline = self.get('global-maps', key) return cmdline config = AlotConfigParser() config.read(os.path.join(os.path.dirname(__file__), 'defaults', 'alot.rc')) notmuchconfig = FallbackConfigParser() notmuchconfig.read(os.path.join(os.path.dirname(__file__), 'defaults', 'notmuch.rc')) mailcaps = mailcap.getcaps() def get_mime_handler(mime_type, key='view', interactive=True): """ get shellcomand defined in the users `mailcap` as handler for files of given `mime_type`. :param mime_type: file type :type mime_type: str :param key: identifies one of possibly many commands for this type by naming the intended usage, e.g. 'edit' or 'view'. Defaults to 'view'. :type key: str :param interactive: choose the "interactive session" handler rather than the "print to stdout and immediately return" handler
def open_mimetype(tag, keywords, val=None): """Simulate double-clicking on the filename in a file manager. Order of preference is: 1) @string mime_open_cmd setting 2) _mime_open_cmd, defined per sys.platform detection 3) open_func(fpath), defined per sys.platform detection 4) mailcap file for mimetype handling """ global open_func c = keywords.get("c") p = keywords.get("p") if not c or not p: return if p.h.startswith("@mime"): fname = p.h[6:] # honor @path d = c.scanAllDirectives(p) path = d.get("path") fpath = g.os_path_finalize_join(path, fname) # stop here if the file doesn't exist if not g.os_path_exists(fpath): g.error("@mime: file does not exist, %s" % fpath) return True # user-specified command string, or sys.platform-determined string mime_cmd = c.config.getString("mime_open_cmd") or _mime_open_cmd if mime_cmd: if "%s" not in mime_cmd: mime_cmd += " %s" open_func = exec_string_cmd(mime_cmd) # no special handler function specified (unknown platform), # try mailcap/mimetype entries explicitly if open_func is None: (ftype, encoding) = mimetypes.guess_type(fname) if ftype: caps = mailcap.getcaps() (fullcmd, entry) = mailcap.findmatch(caps, ftype, filename=fpath, key="view") if fullcmd: # create a function which merely executes the fullcmd in # a shell for e.g. PATH access open_func = exec_full_cmd(fullcmd) else: g.error("@mime: no mailcap entry for %s: %s" % (ftype, fname)) g.trace("mailcap command:", fullcmd) else: g.error("@mime: unknown file type: %s" % fname) # use the custom open_func to open external file viewer if open_func: open_func(fpath) else: g.error("@mime: no known way to open %s" % fname) # block execution of e.g. vim plugin return True # not an @mime node return val
""" import logging as _logging import mailcap as _mailcap import mimetypes as _mimetypes import shlex as _shlex if not hasattr(_shlex, "quote"): # Python < 3.3 import pipes as _pipes _shlex.quote = _pipes.quote import subprocess as _subprocess _LOG = _logging.getLogger(__name__) _CAPS = _mailcap.getcaps() def mailcap_view(path, content_type=None, background=False): if content_type is None: content_type, encoding = _mimetypes.guess_type(path) if content_type is None: return 1 _LOG.debug("guessed {} for {}".format(content_type, path)) match = _mailcap.findmatch(_CAPS, content_type, filename=_shlex.quote(path)) if match[0] is None: _LOG.warn("no mailcap viewer found for {}".format(content_type)) raise NotImplementedError(content_type) _LOG.debug("view {} with: {}".format(path, match[0])) process = _subprocess.Popen(match[0], shell=True) if background: