Exemple #1
0
    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)
Exemple #2
0
 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)
Exemple #3
0
 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
Exemple #4
0
 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)
Exemple #5
0
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')
Exemple #7
0
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
Exemple #8
0
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."))
Exemple #9
0
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
Exemple #10
0
 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 + ' &')
Exemple #11
0
 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)
Exemple #12
0
    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)
Exemple #13
0
 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()
Exemple #14
0
    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
Exemple #15
0
    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
Exemple #17
0
    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
Exemple #18
0
    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
Exemple #19
0
        :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
Exemple #20
0
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
Exemple #21
0
"""

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: