sync with 1.10.0

This commit is contained in:
David Foucher
2016-07-17 13:11:17 +02:00
34 changed files with 6118 additions and 186 deletions

View File

@@ -6,12 +6,14 @@ import sys
import time
import codecs
import curses
import logging
import tempfile
import webbrowser
import subprocess
import curses.ascii
from curses import textpad
from datetime import datetime
from contextlib import contextmanager
from tempfile import NamedTemporaryFile
import six
from kitchen.text.display import textual_width_chop
@@ -27,6 +29,9 @@ except ImportError:
unescape = html_parser.HTMLParser().unescape
_logger = logging.getLogger(__name__)
class Terminal(object):
MIN_HEIGHT = 10
@@ -58,13 +63,13 @@ class Terminal(object):
@property
def neutral_arrow(self):
symbol = '>' if self.ascii else ''
symbol = 'o' if self.ascii else ''
attr = curses.A_BOLD
return symbol, attr
@property
def timestamp_sep(self):
symbol = 'o' if self.ascii else ''
symbol = '-'
attr = curses.A_BOLD
return symbol, attr
@@ -100,7 +105,14 @@ class Terminal(object):
if self._display is None:
if sys.platform == 'darwin':
# OSX doesn't always set DISPLAY so we can't use this to check
display = True
# Note: Disabling for now, with the hope that if this
# is a widespread issue then people will complain and we can
# come up with a better solution. Checking for $DISPLAY is
# used extensively in mailcap files, so it really *should* be
# set properly. I don't have a mac anymore so I can't test.
# display = True
display = bool(os.environ.get("DISPLAY"))
else:
display = bool(os.environ.get("DISPLAY"))
@@ -350,7 +362,8 @@ class Terminal(object):
'Browser exited with status=%s' % code)
time.sleep(0.01)
else:
raise exceptions.BrowserError('Timeout opening browser')
raise exceptions.BrowserError(
'Timeout opening browser')
finally:
# Can't check the loader exception because the oauth module
# supersedes this loader and we need to always kill the
@@ -383,37 +396,75 @@ class Terminal(object):
except OSError:
self.show_notification('Could not open pager %s' % pager)
@contextmanager
def open_editor(self, data=''):
"""
Open a temporary file using the system's default editor.
Open a file for editing using the system's default editor.
The data string will be written to the file before opening. This
function will block until the editor has closed. At that point the file
will be read and and lines starting with '#' will be stripped.
After the file has been altered, the text will be read back and lines
starting with '#' will be stripped. If an error occurs inside of the
context manager, the file will be preserved. Otherwise, the file will
be deleted when the context manager closes.
Params:
data (str): If provided, text will be written to the file before
opening it with the editor.
Returns:
text (str): The text that the user entered into the editor.
"""
with NamedTemporaryFile(prefix='rtv-', suffix='.txt', mode='wb') as fp:
fp.write(self.clean(data))
fp.flush()
editor = os.getenv('RTV_EDITOR') or os.getenv('EDITOR') or 'nano'
filename = 'rtv_{:%Y%m%d_%H%M%S}.txt'.format(datetime.now())
filepath = os.path.join(tempfile.gettempdir(), filename)
with codecs.open(filepath, 'w', 'utf-8') as fp:
fp.write(data)
_logger.info('File created: %s', filepath)
editor = os.getenv('RTV_EDITOR') or os.getenv('EDITOR') or 'nano'
try:
with self.suspend():
p = subprocess.Popen([editor, filepath])
try:
p.wait()
except KeyboardInterrupt:
p.terminate()
except OSError:
self.show_notification('Could not open file with %s' % editor)
with codecs.open(filepath, 'r', 'utf-8') as fp:
text = ''.join(line for line in fp if not line.startswith('#'))
text = text.rstrip()
try:
yield text
except exceptions.TemporaryFileError:
# All exceptions will cause the file to *not* be removed, but these
# ones should also be swallowed
_logger.info('Caught TemporaryFileError')
self.show_notification('Post saved as: %s', filepath)
else:
# If no errors occurred, try to remove the file
try:
with self.suspend():
p = subprocess.Popen([editor, fp.name])
try:
p.wait()
except KeyboardInterrupt:
p.terminate()
os.remove(filepath)
except OSError:
self.show_notification('Could not open file with %s' % editor)
_logger.warning('Could not delete: %s', filepath)
else:
_logger.info('File deleted: %s', filepath)
# Open a second file object to read. This appears to be necessary
# in order to read the changes made by some editors (gedit). w+
# mode does not work!
with codecs.open(fp.name, 'r', 'utf-8') as fp2:
text = ''.join(line for line in fp2 if not line.startswith('#'))
text = text.rstrip()
return text
def open_urlview(self, data):
urlview = os.getenv('RTV_URLVIEWER') or 'urlview'
try:
with self.suspend():
p = subprocess.Popen([urlview],
stdin=subprocess.PIPE)
try:
p.communicate(input=six.b(data))
except KeyboardInterrupt:
p.terminate()
except OSError:
self.show_notification(
'Could not open urls with {}'.format(urlview))
def text_input(self, window, allow_resize=False):
"""