Addressed add_comment() issues brought up in #38.

This commit is contained in:
Michael Lazar
2015-03-18 22:24:17 -07:00
parent d1cee10936
commit 9ecf7e10bc
2 changed files with 85 additions and 32 deletions

View File

@@ -1,7 +1,8 @@
import curses import curses
import sys import sys
import time import time
import praw.errors
from praw.errors import APIException
from .content import SubmissionContent from .content import SubmissionContent
from .page import BasePage from .page import BasePage
@@ -21,7 +22,8 @@ class SubmissionPage(BasePage):
else: else:
raise ValueError('Must specify url or submission') raise ValueError('Must specify url or submission')
super(SubmissionPage, self).__init__(stdscr, reddit, content, page_index=-1) super(SubmissionPage, self).__init__(stdscr, reddit, content,
page_index=-1)
def loop(self): def loop(self):
@@ -116,7 +118,7 @@ class SubmissionPage(BasePage):
n_rows, n_cols = win.getmaxyx() n_rows, n_cols = win.getmaxyx()
n_cols -= 1 n_cols -= 1
# Handle the case where the window is not large enough to fit the data. # Handle the case where the window is not large enough to fit the text.
valid_rows = range(0, n_rows) valid_rows = range(0, n_rows)
offset = 0 if not inverted else -(data['n_rows'] - n_rows) offset = 0 if not inverted else -(data['n_rows'] - n_rows)
@@ -231,39 +233,48 @@ class SubmissionPage(BasePage):
""" """
if not self.reddit.is_logged_in(): if not self.reddit.is_logged_in():
display_message(self.stdscr, ["You are not logged in!"]) display_message(self.stdscr, ["Login to reply"])
return return
cursor_position = self.nav.absolute_index data = self.content.get(self.nav.absolute_index)
if (self.content.get(cursor_position)['type'] != 'Comment') \ if data['type'] not in ('Comment', 'Submission'):
& (self.content.get(cursor_position)['type'] != 'Submission'): curses.flash()
display_message(self.stdscr, ['Expand the comments first!'])
return return
# Fill the bottom half of the screen with the comment box
n_rows, n_cols = self.stdscr.getmaxyx() n_rows, n_cols = self.stdscr.getmaxyx()
box_height = n_rows/2 box_height = n_rows // 2
attr = curses.A_BOLD | Color.CYAN attr = curses.A_BOLD | Color.CYAN
for x in range(n_cols):
y = box_height - 1
# http://bugs.python.org/issue21088
if (sys.version_info.major,
sys.version_info.minor,
sys.version_info.micro) == (3, 4, 0):
x, y = y, x
self.stdscr.addch(y, x, curses.ACS_HLINE, attr)
prompt = 'Enter comment: ESC to cancel, Ctrl+g to submit' prompt = 'Enter comment: ESC to cancel, Ctrl+g to submit'
prompt = '-'*((n_cols-len(prompt))/2) + prompt \ scol = max(0, (n_cols // 2) - (len(prompt) // 2))
+ '-'*((n_cols-len(prompt)+1)/2) self.stdscr.addnstr(box_height-1, scol, prompt, n_cols-scol, attr)
self.stdscr.addstr(n_rows-box_height-1, 0, prompt, attr)
self.stdscr.refresh() self.stdscr.refresh()
window = self.stdscr.derwin(box_height, n_cols, window = self.stdscr.derwin(n_rows-box_height, n_cols, box_height, 0)
n_rows-box_height, 0) window.attrset(Color.CYAN)
window.attrset(attr)
comment_text = text_input(window, show_cursor=True, insert_mode=False) comment_text = text_input(window, allow_resize=False)
if comment_text is not None: if comment_text is None:
try: return
if cursor_position == -1: # comment on submission
self.content._submission.add_comment(comment_text) try:
else: # reply on a selected comment if data['type'] == 'Submission':
self.content.get(cursor_position)['object']\ data['object'].add_comment(comment_text)
.reply(comment_text)
except praw.errors.APIException as e:
display_message(self.stdscr, [e.message])
else: else:
time.sleep(0.5) data['object'].reply(comment_text)
self.refresh_content() except APIException as e:
display_message(self.stdscr, [e.message])
else:
time.sleep(0.5)
self.refresh_content()

View File

@@ -114,7 +114,7 @@ def load_config():
return defaults return defaults
def text_input(window, show_cursor=False, insert_mode=True): def text_input(window, allow_resize=True):
""" """
Transform a window into a text box that will accept user input and loop Transform a window into a text box that will accept user input and loop
until an escape sequence is entered. until an escape sequence is entered.
@@ -124,8 +124,16 @@ def text_input(window, show_cursor=False, insert_mode=True):
""" """
window.clear() window.clear()
curses.curs_set(1 if show_cursor else 2)
textbox = textpad.Textbox(window, insert_mode=insert_mode) # Set cursor mode to 1 because 2 doesn't display on some terminals
curses.curs_set(1)
# Turn insert_mode off to avoid the recursion error described here
# http://bugs.python.org/issue13051
textbox = textpad.Textbox(window, insert_mode=False)
# Strip whitespace from the textbox 'smarter' than textpad.Textbox() does.
textbox.stripspaces = 0
def validate(ch): def validate(ch):
"Filters characters for special key sequences" "Filters characters for special key sequences"
@@ -133,6 +141,9 @@ def text_input(window, show_cursor=False, insert_mode=True):
if ch == Symbol.ESCAPE: if ch == Symbol.ESCAPE:
raise EscapePressed raise EscapePressed
if (not allow_resize) and (ch == curses.KEY_RESIZE):
raise EscapePressed
# Fix backspace for iterm # Fix backspace for iterm
if ch == ascii.DEL: if ch == ascii.DEL:
ch = curses.KEY_BACKSPACE ch = curses.KEY_BACKSPACE
@@ -144,11 +155,42 @@ def text_input(window, show_cursor=False, insert_mode=True):
# input. # input.
try: try:
out = textbox.edit(validate=validate) out = textbox.edit(validate=validate)
out = out.strip()
except EscapePressed: except EscapePressed:
out = None out = None
curses.curs_set(0) curses.curs_set(0)
if out is None:
return out
else:
return strip_text(out)
def strip_text(text):
"Intelligently strip whitespace from the text output of a curses textpad."
# Trivial case where the textbox is only one line long.
if '\n' not in text:
return text.rstrip()
# Allow one space at the end of the line. If there is more than one space,
# assume that a newline operation was intended by the user
stack, current_line = [], ''
for line in text.split('\n'):
if line.endswith(' '):
stack.append(current_line + line.rstrip())
current_line = ''
else:
current_line += line
stack.append(current_line)
# Prune empty lines at the bottom of the textbox.
for item in stack[::-1]:
if len(item) == 0:
stack.pop()
else:
break
out = '\n'.join(stack)
return out return out
def display_message(stdscr, message): def display_message(stdscr, message):