Docstring wordings, refactored /r/me handling, updated README.
This commit is contained in:
21
README.rst
21
README.rst
@@ -61,7 +61,8 @@ RTV currently supports browsing both subreddits and individual submissions. In e
|
||||
:``a``/``z``: Upvote/downvote the selected item
|
||||
:``ENTER`` or ``o``: Open the selected item in the default web browser
|
||||
:``r``: Refresh the current page
|
||||
:``?``: Show the help message
|
||||
:``u``: Login and logout of your user account
|
||||
:``?``: Show the help screen
|
||||
:``q``: Quit
|
||||
|
||||
**Subreddit Mode**
|
||||
@@ -71,7 +72,7 @@ In subreddit mode you can browse through the top submissions on either the front
|
||||
:``►`` or ``l``: View comments for the selected submission
|
||||
:``/``: Open a prompt to switch subreddits
|
||||
:``f``: Open a prompt to search the current subreddit
|
||||
:``p``: Post a Submission to the current subreddit
|
||||
:``p``: Post a new submission to the current subreddit
|
||||
|
||||
The ``/`` prompt accepts subreddits in the following formats
|
||||
|
||||
@@ -79,7 +80,7 @@ The ``/`` prompt accepts subreddits in the following formats
|
||||
* ``/r/python/new``
|
||||
* ``/r/python+linux`` supports multireddits
|
||||
* ``/r/front`` will redirect to the front page
|
||||
* ``/r/me`` will show you your submissions on all subs
|
||||
* ``/r/me`` will display your submissions
|
||||
|
||||
**Submission Mode**
|
||||
|
||||
@@ -87,7 +88,7 @@ In submission mode you can view the self text for a submission and browse commen
|
||||
|
||||
:``◄`` or ``h``: Return to subreddit mode
|
||||
:``►`` or ``l``: Fold the selected comment, or load additional comments
|
||||
:``c``: Comment/reply on the selected item
|
||||
:``c``: Post a new comment on the selected item
|
||||
|
||||
-------------
|
||||
Configuration
|
||||
@@ -104,10 +105,20 @@ Example config:
|
||||
[rtv]
|
||||
username=MyUsername
|
||||
password=MySecretPassword
|
||||
|
||||
|
||||
# Log file location
|
||||
log=/tmp/rtv.log
|
||||
|
||||
# Default subreddit
|
||||
subreddit=CollegeBasketball
|
||||
|
||||
# Default submission link - will be opened every time the program starts
|
||||
# link=http://www.reddit.com/r/CollegeBasketball/comments/31irjq
|
||||
|
||||
# Enable unicode characters (experimental)
|
||||
# This is known to be unstable with east asian wide character sets
|
||||
# unicode=true
|
||||
|
||||
RTV allows users to compose comments and replys using their preferred text editor (**vi**, **nano**, **gedit**, etc).
|
||||
Set the environment variable ``RTV_EDITOR`` to specify which editor the program should use.
|
||||
|
||||
|
||||
@@ -45,6 +45,9 @@ def load_config():
|
||||
if config.has_section('rtv'):
|
||||
defaults = dict(config.items('rtv'))
|
||||
|
||||
if 'unicode' in defaults:
|
||||
defaults['unicode'] = config.getboolean('rtv', 'unicode')
|
||||
|
||||
return defaults
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import textwrap
|
||||
import praw
|
||||
import requests
|
||||
|
||||
from .exceptions import SubmissionError, SubredditError
|
||||
from .exceptions import SubmissionError, SubredditError, AccountError
|
||||
from .helpers import humanize_timestamp, wrap_text, strip_subreddit_url
|
||||
|
||||
__all__ = ['SubredditContent', 'SubmissionContent']
|
||||
@@ -114,18 +114,12 @@ class BaseContent(object):
|
||||
|
||||
|
||||
class SubmissionContent(BaseContent):
|
||||
|
||||
"""
|
||||
Grab a submission from PRAW and lazily store comments to an internal
|
||||
list for repeat access.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
submission,
|
||||
loader,
|
||||
indent_size=2,
|
||||
max_indent_level=4):
|
||||
def __init__(self, submission, loader, indent_size=2, max_indent_level=4):
|
||||
|
||||
self.indent_size = indent_size
|
||||
self.max_indent_level = max_indent_level
|
||||
@@ -138,13 +132,7 @@ class SubmissionContent(BaseContent):
|
||||
self._comment_data = [self.strip_praw_comment(c) for c in comments]
|
||||
|
||||
@classmethod
|
||||
def from_url(
|
||||
cls,
|
||||
reddit,
|
||||
url,
|
||||
loader,
|
||||
indent_size=2,
|
||||
max_indent_level=4):
|
||||
def from_url(cls, reddit, url, loader, indent_size=2, max_indent_level=4):
|
||||
|
||||
try:
|
||||
with loader():
|
||||
@@ -165,10 +153,9 @@ class SubmissionContent(BaseContent):
|
||||
|
||||
elif index == -1:
|
||||
data = self._submission_data
|
||||
data['split_title'] = textwrap.wrap(data['title'],
|
||||
width=n_cols -2)
|
||||
data['split_title'] = textwrap.wrap(data['title'], width=n_cols -2)
|
||||
data['split_text'] = wrap_text(data['text'], width=n_cols - 2)
|
||||
data['n_rows'] = len(data['split_title']) + len(data['split_text']) + 5
|
||||
data['n_rows'] = len(data['split_title'] + data['split_text']) + 5
|
||||
data['offset'] = 0
|
||||
|
||||
else:
|
||||
@@ -233,9 +220,8 @@ class SubmissionContent(BaseContent):
|
||||
|
||||
|
||||
class SubredditContent(BaseContent):
|
||||
|
||||
"""
|
||||
Grabs a subreddit from PRAW and lazily stores submissions to an internal
|
||||
Grab a subreddit from PRAW and lazily stores submissions to an internal
|
||||
list for repeat access.
|
||||
"""
|
||||
|
||||
@@ -251,7 +237,7 @@ class SubredditContent(BaseContent):
|
||||
# there is is no other way to check things like multireddits that
|
||||
# don't have a real corresponding subreddit object.
|
||||
try:
|
||||
content.get(0)
|
||||
self.get(0)
|
||||
except (praw.errors.APIException, requests.HTTPError,
|
||||
praw.errors.RedirectException):
|
||||
raise SubredditError(display_name)
|
||||
@@ -259,8 +245,6 @@ class SubredditContent(BaseContent):
|
||||
@classmethod
|
||||
def from_name(cls, reddit, name, loader, order='hot', query=None):
|
||||
|
||||
name = name if name else 'front'
|
||||
|
||||
if order not in ['hot', 'top', 'rising', 'new', 'controversial']:
|
||||
raise SubredditError(display_name)
|
||||
|
||||
@@ -268,7 +252,7 @@ class SubredditContent(BaseContent):
|
||||
if name.startswith('r/'):
|
||||
name = name[2:]
|
||||
|
||||
# Grab the display type e.g. "python/new"
|
||||
# Grab the display order e.g. "python/new"
|
||||
if '/' in name:
|
||||
name, order = name.split('/')
|
||||
|
||||
@@ -276,57 +260,50 @@ class SubredditContent(BaseContent):
|
||||
if order != 'hot':
|
||||
display_name += '/{}'.format(order)
|
||||
|
||||
if name == 'front':
|
||||
dispatch = {
|
||||
'hot': reddit.get_front_page,
|
||||
'top': reddit.get_top,
|
||||
'rising': reddit.get_rising,
|
||||
'new': reddit.get_new,
|
||||
'controversial': reddit.get_controversial
|
||||
}
|
||||
else:
|
||||
subreddit = reddit.get_subreddit(name)
|
||||
dispatch = {
|
||||
'hot': subreddit.get_hot,
|
||||
'top': subreddit.get_top,
|
||||
'rising': subreddit.get_rising,
|
||||
'new': subreddit.get_new,
|
||||
'controversial': subreddit.get_controversial
|
||||
}
|
||||
if name == 'me':
|
||||
if not self.reddit.is_logged_in():
|
||||
raise AccountError
|
||||
else:
|
||||
submissions = reddit.user.get_submitted(sort=order)
|
||||
|
||||
if query:
|
||||
elif query:
|
||||
if name == 'front':
|
||||
submissions = reddit.search(query, subreddit=None, sort=order)
|
||||
else:
|
||||
submissions = reddit.search(query, subreddit=name, sort=order)
|
||||
|
||||
else:
|
||||
if name == 'front':
|
||||
dispatch = {
|
||||
'hot': reddit.get_front_page,
|
||||
'top': reddit.get_top,
|
||||
'rising': reddit.get_rising,
|
||||
'new': reddit.get_new,
|
||||
'controversial': reddit.get_controversial,
|
||||
}
|
||||
else:
|
||||
subreddit = reddit.get_subreddit(name)
|
||||
dispatch = {
|
||||
'hot': subreddit.get_hot,
|
||||
'top': subreddit.get_top,
|
||||
'rising': subreddit.get_rising,
|
||||
'new': subreddit.get_new,
|
||||
'controversial': subreddit.get_controversial,
|
||||
}
|
||||
submissions = dispatch[order](limit=None)
|
||||
|
||||
return cls(display_name, submissions, loader)
|
||||
|
||||
@classmethod
|
||||
def from_redditor(cls, reddit, loader, order='new'):
|
||||
submissions = reddit.user.get_submitted(sort=order)
|
||||
display_name = '/r/me'
|
||||
content = cls(display_name, submissions, loader)
|
||||
try:
|
||||
content.get(0)
|
||||
except (praw.errors.APIException, requests.HTTPError,
|
||||
praw.errors.RedirectException):
|
||||
raise SubredditError(display_name)
|
||||
return content
|
||||
|
||||
def get(self, index, n_cols=70):
|
||||
"""
|
||||
Grab the `i`th submission, with the title field formatted to fit inside
|
||||
of a window of width `n`
|
||||
of a window of width `n_cols`
|
||||
"""
|
||||
|
||||
if index < 0:
|
||||
raise IndexError
|
||||
|
||||
while index >= len(self._submission_data):
|
||||
|
||||
try:
|
||||
with self._loader():
|
||||
submission = next(self._submissions)
|
||||
@@ -342,4 +319,4 @@ class SubredditContent(BaseContent):
|
||||
data['n_rows'] = len(data['split_title']) + 3
|
||||
data['offset'] = 0
|
||||
|
||||
return data
|
||||
return data
|
||||
@@ -66,8 +66,11 @@ def show_help(stdscr):
|
||||
"""
|
||||
Overlay a message box with the help screen.
|
||||
"""
|
||||
show_notification(stdscr, HELP.split("\n"))
|
||||
|
||||
curses.endwin()
|
||||
print(HELP)
|
||||
raw_input('Press Enter to continue')
|
||||
curses.doupdate()
|
||||
|
||||
class LoadScreen(object):
|
||||
|
||||
|
||||
18
rtv/docs.py
18
rtv/docs.py
@@ -2,7 +2,9 @@ from .__version__ import __version__
|
||||
|
||||
__all__ = ['AGENT', 'SUMMARY', 'AUTH', 'CONTROLS', 'HELP']
|
||||
|
||||
AGENT = "desktop:https://github.com/michael-lazar/rtv:{} (by /u/civilization_phaze_3)".format(__version__)
|
||||
AGENT = """\
|
||||
desktop:https://github.com/michael-lazar/rtv:{} (by /u/civilization_phaze_3)\
|
||||
""".format(__version__)
|
||||
|
||||
SUMMARY = """
|
||||
Reddit Terminal Viewer is a lightweight browser for www.reddit.com built into a
|
||||
@@ -28,22 +30,22 @@ HELP = """
|
||||
Global Commands
|
||||
`UP/DOWN` or `j/k` : Scroll to the prev/next item
|
||||
`a/z` : Upvote/downvote the selected item
|
||||
`r` : Refresh the current page
|
||||
`q` : Quit the program
|
||||
`ENTER` or `o` : Open the selected item in the default web browser
|
||||
`u` : Log in
|
||||
`r` : Refresh the current page
|
||||
`u` : Login/logout of your user account
|
||||
`?` : Show this help message
|
||||
`q` : Quit the program
|
||||
|
||||
Subreddit Mode
|
||||
`RIGHT` or `l` : View comments for the selected submission
|
||||
`/` : Open a prompt to switch subreddits
|
||||
`f` : Open a prompt to search the current subreddit
|
||||
`p` : Post a Submission to the current subreddit
|
||||
`p` : Post a new submission to the current subreddit
|
||||
|
||||
Submission Mode
|
||||
`LEFT` or `h` : Return to subreddit mode
|
||||
`RIGHT` or `l` : Fold the selected comment, or load additional comments
|
||||
`c` : Comment/reply on the selected item
|
||||
`c` : Post a new comment on the selected item
|
||||
"""
|
||||
|
||||
COMMENT_FILE = """
|
||||
@@ -59,7 +61,7 @@ SUBMISSION_FILE = """
|
||||
# and an empty field aborts the submission.
|
||||
#
|
||||
# The first line will be interpreted as the title
|
||||
# Following lines will be interpreted as the content
|
||||
# The following lines will be interpreted as the content
|
||||
#
|
||||
# Posting to /r/{name}
|
||||
"""
|
||||
"""
|
||||
@@ -1,23 +1,31 @@
|
||||
class SubmissionError(Exception):
|
||||
"""Submission could not be loaded"""
|
||||
class EscapeInterrupt(Exception):
|
||||
"Signal that the ESC key has been pressed"
|
||||
|
||||
|
||||
class RTVError(Exception):
|
||||
"Base RTV error class"
|
||||
|
||||
|
||||
class AccountError(RTVError):
|
||||
"Could not access user account"
|
||||
|
||||
|
||||
class SubmissionError(RTVError):
|
||||
"Submission could not be loaded"
|
||||
|
||||
def __init__(self, url):
|
||||
self.url = url
|
||||
|
||||
|
||||
class SubredditError(Exception):
|
||||
"""Subreddit could not be reached"""
|
||||
class SubredditError(RTVError):
|
||||
"Subreddit could not be reached"
|
||||
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
|
||||
class ProgramError(Exception):
|
||||
"""Problem executing an external program"""
|
||||
class ProgramError(RTVError):
|
||||
"Problem executing an external program"
|
||||
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
|
||||
class EscapeInterrupt(Exception):
|
||||
"""Signal that the ESC key has been pressed"""
|
||||
|
||||
22
rtv/page.py
22
rtv/page.py
@@ -12,7 +12,6 @@ __all__ = ['Navigator']
|
||||
|
||||
|
||||
class Navigator(object):
|
||||
|
||||
"""
|
||||
Handles math behind cursor movement and screen paging.
|
||||
"""
|
||||
@@ -87,6 +86,7 @@ class Navigator(object):
|
||||
|
||||
def flip(self, n_windows):
|
||||
"Flip the orientation of the page"
|
||||
|
||||
self.page_index += (self.step * n_windows)
|
||||
self.cursor_index = n_windows
|
||||
self.inverted = not self.inverted
|
||||
@@ -103,7 +103,6 @@ class Navigator(object):
|
||||
|
||||
|
||||
class BaseController(object):
|
||||
|
||||
"""
|
||||
Event handler for triggering functions with curses keypresses.
|
||||
|
||||
@@ -153,7 +152,6 @@ class BaseController(object):
|
||||
|
||||
|
||||
class BasePage(object):
|
||||
|
||||
"""
|
||||
Base terminal viewer incorperates a cursor to navigate content
|
||||
"""
|
||||
@@ -192,6 +190,7 @@ class BasePage(object):
|
||||
|
||||
def clear_input_queue(self):
|
||||
"Clear excessive input caused by the scroll wheel or holding down a key"
|
||||
|
||||
self.stdscr.nodelay(1)
|
||||
while self.stdscr.getch() != -1:
|
||||
continue
|
||||
@@ -210,7 +209,7 @@ class BasePage(object):
|
||||
data['object'].upvote()
|
||||
data['likes'] = True
|
||||
except praw.errors.LoginOrScopeRequired:
|
||||
show_notification(self.stdscr, ['Login to vote'])
|
||||
show_notification(self.stdscr, ['Not logged in'])
|
||||
|
||||
@BaseController.register('z')
|
||||
def downvote(self):
|
||||
@@ -225,13 +224,13 @@ class BasePage(object):
|
||||
data['object'].downvote()
|
||||
data['likes'] = False
|
||||
except praw.errors.LoginOrScopeRequired:
|
||||
show_notification(self.stdscr, ['Login to vote'])
|
||||
show_notification(self.stdscr, ['Not logged in'])
|
||||
|
||||
@BaseController.register('u')
|
||||
def login(self):
|
||||
"""
|
||||
Prompt to log into the user's account. Log out if the user is already
|
||||
logged in.
|
||||
Prompt to log into the user's account, or log out of the current
|
||||
account.
|
||||
"""
|
||||
|
||||
if self.reddit.is_logged_in():
|
||||
@@ -252,9 +251,7 @@ class BasePage(object):
|
||||
show_notification(self.stdscr, ['Logged in'])
|
||||
|
||||
def logout(self):
|
||||
"""
|
||||
Prompt to log out of the user's account.
|
||||
"""
|
||||
"Prompt to log out of the user's account."
|
||||
|
||||
ch = self.prompt_input("Log out? (y/n):")
|
||||
if ch == 'y':
|
||||
@@ -264,7 +261,8 @@ class BasePage(object):
|
||||
curses.flash()
|
||||
|
||||
def prompt_input(self, prompt, hide=False):
|
||||
"""Prompt the user for input"""
|
||||
"Prompt the user for input"
|
||||
|
||||
attr = curses.A_BOLD | Color.CYAN
|
||||
n_rows, n_cols = self.stdscr.getmaxyx()
|
||||
|
||||
@@ -397,4 +395,4 @@ class BasePage(object):
|
||||
for row in range(n_rows):
|
||||
window.chgat(row, 0, 1, attribute)
|
||||
|
||||
window.refresh()
|
||||
window.refresh()
|
||||
@@ -24,9 +24,9 @@ class SubmissionPage(BasePage):
|
||||
|
||||
self.controller = SubmissionController(self)
|
||||
self.loader = LoadScreen(stdscr)
|
||||
if url is not None:
|
||||
if url:
|
||||
content = SubmissionContent.from_url(reddit, url, self.loader)
|
||||
elif submission is not None:
|
||||
elif submission:
|
||||
content = SubmissionContent(submission, self.loader)
|
||||
else:
|
||||
raise ValueError('Must specify url or submission')
|
||||
@@ -35,6 +35,8 @@ class SubmissionPage(BasePage):
|
||||
content, page_index=-1)
|
||||
|
||||
def loop(self):
|
||||
"Main control loop"
|
||||
|
||||
self.active = True
|
||||
while self.active:
|
||||
self.draw()
|
||||
@@ -43,6 +45,8 @@ class SubmissionPage(BasePage):
|
||||
|
||||
@SubmissionController.register(curses.KEY_RIGHT, 'l')
|
||||
def toggle_comment(self):
|
||||
"Toggle the selected comment tree between visible and hidden"
|
||||
|
||||
current_index = self.nav.absolute_index
|
||||
self.content.toggle(current_index)
|
||||
if self.nav.inverted:
|
||||
@@ -53,20 +57,24 @@ class SubmissionPage(BasePage):
|
||||
|
||||
@SubmissionController.register(curses.KEY_LEFT, 'h')
|
||||
def exit_submission(self):
|
||||
"Close the submission and return to the subreddit page"
|
||||
|
||||
self.active = False
|
||||
|
||||
@SubmissionController.register(curses.KEY_F5, 'r')
|
||||
def refresh_content(self):
|
||||
url = self.content.name
|
||||
"Re-download comments reset the page index"
|
||||
|
||||
self.content = SubmissionContent.from_url(
|
||||
self.reddit,
|
||||
url,
|
||||
self.content.name,
|
||||
self.loader)
|
||||
self.nav = Navigator(self.content.get, page_index=-1)
|
||||
|
||||
@SubmissionController.register(curses.KEY_ENTER, 10, 'o')
|
||||
def open_link(self):
|
||||
# Always open the page for the submission
|
||||
"Open the current submission page with the webbrowser"
|
||||
|
||||
# May want to expand at some point to open comment permalinks
|
||||
url = self.content.get(-1)['permalink']
|
||||
open_browser(url)
|
||||
@@ -74,11 +82,12 @@ class SubmissionPage(BasePage):
|
||||
@SubmissionController.register('c')
|
||||
def add_comment(self):
|
||||
"""
|
||||
Add a comment on the submission if a header is selected.
|
||||
Reply to a comment if the comment is selected.
|
||||
Add a top-level comment if the submission is selected, or reply to the
|
||||
selected comment.
|
||||
"""
|
||||
|
||||
if not self.reddit.is_logged_in():
|
||||
show_notification(self.stdscr, ["Login to reply"])
|
||||
show_notification(self.stdscr, ['Not logged in'])
|
||||
return
|
||||
|
||||
data = self.content.get(self.nav.absolute_index)
|
||||
@@ -100,19 +109,19 @@ class SubmissionPage(BasePage):
|
||||
curses.endwin()
|
||||
comment_text = open_editor(comment_info)
|
||||
curses.doupdate()
|
||||
|
||||
if not comment_text:
|
||||
curses.flash()
|
||||
return
|
||||
|
||||
try:
|
||||
if data['type'] == 'Submission':
|
||||
data['object'].add_comment(comment_text)
|
||||
else:
|
||||
data['object'].reply(comment_text)
|
||||
except praw.errors.APIException as e:
|
||||
show_notification(self.stdscr, [e.message])
|
||||
except praw.errors.APIException:
|
||||
curses.flash()
|
||||
else:
|
||||
time.sleep(0.5)
|
||||
time.sleep(2.0)
|
||||
self.refresh_content()
|
||||
|
||||
def draw_item(self, win, data, inverted=False):
|
||||
@@ -248,4 +257,4 @@ class SubmissionPage(BasePage):
|
||||
text, attr = GOLD, (curses.A_BOLD | Color.YELLOW)
|
||||
win.addnstr(text, n_cols - win.getyx()[1], attr)
|
||||
|
||||
win.border()
|
||||
win.border()
|
||||
@@ -3,7 +3,7 @@ import time
|
||||
import requests
|
||||
import praw
|
||||
|
||||
from .exceptions import SubredditError
|
||||
from .exceptions import SubredditError, AccountError
|
||||
from .page import BasePage, Navigator, BaseController
|
||||
from .submission import SubmissionPage
|
||||
from .content import SubredditContent
|
||||
@@ -33,6 +33,8 @@ class SubredditPage(BasePage):
|
||||
super(SubredditPage, self).__init__(stdscr, reddit, content)
|
||||
|
||||
def loop(self):
|
||||
"Main control loop"
|
||||
|
||||
while True:
|
||||
self.draw()
|
||||
cmd = self.stdscr.getch()
|
||||
@@ -40,13 +42,14 @@ class SubredditPage(BasePage):
|
||||
|
||||
@SubredditController.register(curses.KEY_F5, 'r')
|
||||
def refresh_content(self, name=None):
|
||||
"Re-download all submissions and reset the page index"
|
||||
|
||||
name = name or self.content.name
|
||||
if name == 'me' or name == '/r/me':
|
||||
self.redditor_profile()
|
||||
return
|
||||
try:
|
||||
self.content = SubredditContent.from_name(
|
||||
self.reddit, name, self.loader)
|
||||
except AccountError:
|
||||
show_notification(self.stdscr, ['Not logged in'])
|
||||
except SubredditError:
|
||||
show_notification(self.stdscr, ['Invalid subreddit'])
|
||||
except requests.HTTPError:
|
||||
@@ -56,36 +59,30 @@ class SubredditPage(BasePage):
|
||||
|
||||
@SubredditController.register('f')
|
||||
def search_subreddit(self, name=None):
|
||||
"""Open a prompt to search the subreddit"""
|
||||
"Open a prompt to search the given subreddit"
|
||||
|
||||
name = name or self.content.name
|
||||
prompt = 'Search this Subreddit: '
|
||||
prompt = 'Search:'
|
||||
query = self.prompt_input(prompt)
|
||||
if query is not None:
|
||||
try:
|
||||
self.nav.cursor_index = 0
|
||||
self.content = SubredditContent.from_name(self.reddit, name,
|
||||
self.loader, query=query)
|
||||
except IndexError: # if there are no submissions
|
||||
show_notification(self.stdscr, ['No results found'])
|
||||
if query is None:
|
||||
return
|
||||
|
||||
try:
|
||||
self.content = SubredditContent.from_name(
|
||||
self.reddit, name, self.loader, query=query)
|
||||
except IndexError: # if there are no submissions
|
||||
show_notification(self.stdscr, ['No results found'])
|
||||
else:
|
||||
self.nav = Navigator(self.content.get)
|
||||
|
||||
@SubredditController.register('/')
|
||||
def prompt_subreddit(self):
|
||||
"""Open a prompt to type in a new subreddit"""
|
||||
"Open a prompt to navigate to a different subreddit"
|
||||
prompt = 'Enter Subreddit: /r/'
|
||||
name = self.prompt_input(prompt)
|
||||
if name is not None:
|
||||
self.refresh_content(name=name)
|
||||
|
||||
def redditor_profile(self):
|
||||
if self.reddit.is_logged_in():
|
||||
try:
|
||||
self.content = SubredditContent.from_redditor(
|
||||
self.reddit, self.loader)
|
||||
except requests.HTTPError:
|
||||
show_notification(self.stdscr, ['Could not reach subreddit'])
|
||||
else:
|
||||
show_notification(self.stdscr, ['Log in to view your submissions'])
|
||||
|
||||
@SubredditController.register(curses.KEY_RIGHT, 'l')
|
||||
def open_submission(self):
|
||||
"Select the current submission to view posts"
|
||||
@@ -110,19 +107,18 @@ class SubredditPage(BasePage):
|
||||
|
||||
@SubredditController.register('p')
|
||||
def post_submission(self):
|
||||
# Abort if user isn't logged in
|
||||
"Post a new submission to the given subreddit"
|
||||
|
||||
if not self.reddit.is_logged_in():
|
||||
show_notification(self.stdscr, ['Login to reply'])
|
||||
show_notification(self.stdscr, ['Not logged in'])
|
||||
return
|
||||
|
||||
subreddit = self.reddit.get_subreddit(self.content.name)
|
||||
|
||||
# Make sure it is a valid subreddit for submission
|
||||
# Strips the subreddit to just the name
|
||||
# Make sure it is a valid subreddit for submission
|
||||
subreddit = self.reddit.get_subreddit(self.content.name)
|
||||
sub = str(subreddit).split('/')[2]
|
||||
if '+' in sub or sub == 'all' or sub == 'front':
|
||||
message = 'Can\'t post to /r/{0}'.format(sub)
|
||||
show_notification(self.stdscr, [message])
|
||||
if '+' in sub or sub in ('all', 'front', 'me'):
|
||||
show_notification(self.stdscr, ['Invalid subreddit'])
|
||||
return
|
||||
|
||||
# Open the submission window
|
||||
@@ -131,19 +127,22 @@ class SubredditPage(BasePage):
|
||||
submission_text = open_editor(submission_info)
|
||||
curses.doupdate()
|
||||
|
||||
# Abort if there is no content
|
||||
# Validate the submission content
|
||||
if not submission_text:
|
||||
curses.flash()
|
||||
return
|
||||
|
||||
if '\n' not in submission_text:
|
||||
show_notification(self.stdscr, ['No content'])
|
||||
return
|
||||
|
||||
try:
|
||||
title, content = submission_text.split('\n', 1)
|
||||
self.reddit.submit(sub, title, text=content)
|
||||
except praw.errors.APIException as e:
|
||||
show_notification(self.stdscr, [e.message])
|
||||
except ValueError:
|
||||
show_notification(self.stdscr, ['No post content! Post aborted.'])
|
||||
except praw.errors.APIException:
|
||||
curses.flash()
|
||||
else:
|
||||
time.sleep(0.5)
|
||||
time.sleep(2.0)
|
||||
self.refresh_content()
|
||||
|
||||
@staticmethod
|
||||
@@ -197,4 +196,4 @@ class SubredditPage(BasePage):
|
||||
text = clean(u' {subreddit}'.format(**data))
|
||||
win.addnstr(text, n_cols - win.getyx()[1], Color.YELLOW)
|
||||
text = clean(u' {flair}'.format(**data))
|
||||
win.addnstr(text, n_cols - win.getyx()[1], Color.RED)
|
||||
win.addnstr(text, n_cols - win.getyx()[1], Color.RED)
|
||||
Reference in New Issue
Block a user