Clean handling of lack of $EDITOR

Problem: If EDITOR is not set, and vim is not installed, rbt post exits with
just "CRITICAL: [Errno 2] No such file or directory" as an error message, which
does not indicate where the problem lies nor how to solve it.

vim is not installed by default on many distributions, or is installed as "vi".
Moreover, EDITOR is traditionally used for a line editor (remember those?),
with VISUAL being the environment variable of choice for a full-screen or GUI
editor. If neither is set, we should fall back to the editor most likely to be
installed in the base distribution.

Solution: Prefer $VISUAL over $EDITOR over "vi". Offer a helpful error message
on failure.

Reviewed at https://reviews.reviewboard.org/r/5790/
import os
import subprocess
from distutils.util import strtobool

from rbtools.utils.filesystem import make_tempfile


def confirm(question):
    """Interactively prompt for a Yes/No answer.

    Accepted values (case-insensitive) depend on distutils.util.strtobool():
    'Yes' values: y, yes, t, true, on, 1
    'No' values: n, no , f, false, off, 0
    """
    while True:
        try:
            answer = raw_input("%s [Yes/No]: " % question).lower()
            return strtobool(answer)
        except ValueError:
            print '%s is not a valid answer.' % answer


def edit_text(content):
    """Allows a user to edit a block of text and returns the saved result.

    The environment's default text editor is used if available, otherwise
    vi is used.
    """
    tempfile = make_tempfile(content.encode('utf8'))
    editor = os.environ.get('VISUAL') or os.environ.get('EDITOR') or 'vi'
    try:
        subprocess.call([editor, tempfile])
    except OSError:
        print 'No editor found. Set EDITOR environment variable or install vi.'
        raise

    f = open(tempfile)
    result = f.read()
    f.close()

    return result.decode('utf8')

import os
import subprocess
from distutils.util import strtobool

from rbtools.utils.filesystem import make_tempfile


def confirm(question):
    """Interactively prompt for a Yes/No answer.

    Accepted values (case-insensitive) depend on distutils.util.strtobool():
    'Yes' values: y, yes, t, true, on, 1
    'No' values: n, no , f, false, off, 0
    """
    while True:
        try:
            answer = raw_input("%s [Yes/No]: " % question).lower()
            return strtobool(answer)
        except ValueError:
            print '%s is not a valid answer.' % answer


def edit_text(content):
    """Allows a user to edit a block of text and returns the saved result.

    The environment's default text editor is used if available, otherwise
    vim is used.
    """
    tempfile = make_tempfile(content.encode('utf8'))
    editor = os.environ.get('EDITOR', 'vim')
    subprocess.call([editor, tempfile])
    f = open(tempfile)
    result = f.read()
    f.close()

    return result.decode('utf8')
