code width is now consistent
unused imports removed
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import locale
|
import locale
|
||||||
import logging
|
import logging
|
||||||
@@ -6,7 +5,6 @@ import logging
|
|||||||
import praw
|
import praw
|
||||||
import praw.errors
|
import praw.errors
|
||||||
import tornado
|
import tornado
|
||||||
import requests
|
|
||||||
from requests import exceptions
|
from requests import exceptions
|
||||||
|
|
||||||
from . import config
|
from . import config
|
||||||
@@ -28,6 +26,7 @@ _logger = logging.getLogger(__name__)
|
|||||||
# ptrace_scope to 0 in /etc/sysctl.d/10-ptrace.conf.
|
# ptrace_scope to 0 in /etc/sysctl.d/10-ptrace.conf.
|
||||||
# http://blog.mellenthin.de/archives/2010/10/18/gdb-attach-fails
|
# http://blog.mellenthin.de/archives/2010/10/18/gdb-attach-fails
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"Main entry point"
|
"Main entry point"
|
||||||
|
|
||||||
@@ -77,7 +76,8 @@ def main():
|
|||||||
subreddit = args.subreddit or 'front'
|
subreddit = args.subreddit or 'front'
|
||||||
page = SubredditPage(stdscr, reddit, oauth, subreddit)
|
page = SubredditPage(stdscr, reddit, oauth, subreddit)
|
||||||
page.loop()
|
page.loop()
|
||||||
except (exceptions.RequestException, praw.errors.PRAWException, RTVError) as e:
|
except (exceptions.RequestException, praw.errors.PRAWException,
|
||||||
|
RTVError) as e:
|
||||||
_logger.exception(e)
|
_logger.exception(e)
|
||||||
print('{}: {}'.format(type(e).__name__, e))
|
print('{}: {}'.format(type(e).__name__, e))
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
|||||||
@@ -21,8 +21,10 @@ oauth_client_id = 'E2oEtRQfdfAfNQ'
|
|||||||
oauth_client_secret = 'praw_gapfill'
|
oauth_client_secret = 'praw_gapfill'
|
||||||
oauth_redirect_uri = 'http://127.0.0.1:65000/'
|
oauth_redirect_uri = 'http://127.0.0.1:65000/'
|
||||||
oauth_redirect_port = 65000
|
oauth_redirect_port = 65000
|
||||||
oauth_scope = ['edit', 'history', 'identity', 'mysubreddits', 'privatemessages',
|
oauth_scope = ['edit', 'history', 'identity', 'mysubreddits',
|
||||||
'read', 'report', 'save', 'submit', 'subscribe', 'vote']
|
'privatemessages', 'read', 'report', 'save', 'submit',
|
||||||
|
'subscribe', 'vote']
|
||||||
|
|
||||||
|
|
||||||
def build_parser():
|
def build_parser():
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
@@ -51,6 +53,7 @@ def build_parser():
|
|||||||
help='Remove any saved OAuth tokens before starting')
|
help='Remove any saved OAuth tokens before starting')
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
def load_config():
|
def load_config():
|
||||||
"""
|
"""
|
||||||
Attempt to load settings from the local config file.
|
Attempt to load settings from the local config file.
|
||||||
@@ -74,6 +77,7 @@ def load_config():
|
|||||||
|
|
||||||
return config_dict
|
return config_dict
|
||||||
|
|
||||||
|
|
||||||
def load_refresh_token(filename=TOKEN):
|
def load_refresh_token(filename=TOKEN):
|
||||||
if os.path.exists(filename):
|
if os.path.exists(filename):
|
||||||
with open(filename) as fp:
|
with open(filename) as fp:
|
||||||
@@ -81,10 +85,12 @@ def load_refresh_token(filename=TOKEN):
|
|||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def save_refresh_token(token, filename=TOKEN):
|
def save_refresh_token(token, filename=TOKEN):
|
||||||
with open(filename, 'w+') as fp:
|
with open(filename, 'w+') as fp:
|
||||||
fp.write(token)
|
fp.write(token)
|
||||||
|
|
||||||
|
|
||||||
def clear_refresh_token(filename=TOKEN):
|
def clear_refresh_token(filename=TOKEN):
|
||||||
if os.path.exists(filename):
|
if os.path.exists(filename):
|
||||||
os.remove(filename)
|
os.remove(filename)
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import praw
|
|||||||
import requests
|
import requests
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from .exceptions import SubmissionError, SubredditError, SubscriptionError, AccountError
|
from .exceptions import (SubmissionError, SubredditError, SubscriptionError,
|
||||||
|
AccountError)
|
||||||
from .helpers import humanize_timestamp, wrap_text, strip_subreddit_url
|
from .helpers import humanize_timestamp, wrap_text, strip_subreddit_url
|
||||||
|
|
||||||
__all__ = ['SubredditContent', 'SubmissionContent', 'SubscriptionContent']
|
__all__ = ['SubredditContent', 'SubmissionContent', 'SubscriptionContent']
|
||||||
@@ -112,7 +113,8 @@ class BaseContent(object):
|
|||||||
"selfpost" or "x-post" or a link.
|
"selfpost" or "x-post" or a link.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
reddit_link = re.compile("https?://(www\.)?(np\.)?redd(it\.com|\.it)/r/.*")
|
reddit_link = re.compile(
|
||||||
|
"https?://(www\.)?(np\.)?redd(it\.com|\.it)/r/.*")
|
||||||
author = getattr(sub, 'author', '[deleted]')
|
author = getattr(sub, 'author', '[deleted]')
|
||||||
name = getattr(author, 'name', '[deleted]')
|
name = getattr(author, 'name', '[deleted]')
|
||||||
flair = getattr(sub, 'link_flair_text', '')
|
flair = getattr(sub, 'link_flair_text', '')
|
||||||
|
|||||||
@@ -24,17 +24,18 @@ def clean(string, n_cols=None):
|
|||||||
http://nedbatchelder.com/text/unipain.html
|
http://nedbatchelder.com/text/unipain.html
|
||||||
|
|
||||||
Python 2 input string will be a unicode type (unicode code points). Curses
|
Python 2 input string will be a unicode type (unicode code points). Curses
|
||||||
will accept unicode if all of the points are in the ascii range. However, if
|
will accept unicode if all of the points are in the ascii range. However,
|
||||||
any of the code points are not valid ascii curses will throw a
|
if any of the code points are not valid ascii curses will throw a
|
||||||
UnicodeEncodeError: 'ascii' codec can't encode character, ordinal not in
|
UnicodeEncodeError: 'ascii' codec can't encode character, ordinal not in
|
||||||
range(128). If we encode the unicode to a utf-8 byte string and pass that to
|
range(128). If we encode the unicode to a utf-8 byte string and pass that
|
||||||
curses, it will render correctly.
|
to curses, it will render correctly.
|
||||||
|
|
||||||
Python 3 input string will be a string type (unicode code points). Curses
|
Python 3 input string will be a string type (unicode code points). Curses
|
||||||
will accept that in all cases. However, the n character count in addnstr
|
will accept that in all cases. However, the n character count in addnstr
|
||||||
will not be correct. If code points are passed to addnstr, curses will treat
|
will not be correct. If code points are passed to addnstr, curses will
|
||||||
each code point as one character and will not account for wide characters.
|
treat each code point as one character and will not account for wide
|
||||||
If utf-8 is passed in, addnstr will treat each 'byte' as a single character.
|
characters. If utf-8 is passed in, addnstr will treat each 'byte' as a
|
||||||
|
single character.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if n_cols is not None and n_cols <= 0:
|
if n_cols is not None and n_cols <= 0:
|
||||||
@@ -124,7 +125,8 @@ def check_browser_display():
|
|||||||
|
|
||||||
# Use the convention defined here to parse $BROWSER
|
# Use the convention defined here to parse $BROWSER
|
||||||
# https://docs.python.org/2/library/webbrowser.html
|
# https://docs.python.org/2/library/webbrowser.html
|
||||||
console_browsers = ['www-browser', 'links', 'links2', 'elinks', 'lynx', 'w3m']
|
console_browsers = ['www-browser', 'links', 'links2', 'elinks', 'lynx',
|
||||||
|
'w3m']
|
||||||
if "BROWSER" in os.environ:
|
if "BROWSER" in os.environ:
|
||||||
user_browser = os.environ["BROWSER"].split(os.pathsep)[0]
|
user_browser = os.environ["BROWSER"].split(os.pathsep)[0]
|
||||||
if user_browser in console_browsers:
|
if user_browser in console_browsers:
|
||||||
@@ -138,7 +140,8 @@ def check_browser_display():
|
|||||||
|
|
||||||
def wrap_text(text, width):
|
def wrap_text(text, width):
|
||||||
"""
|
"""
|
||||||
Wrap text paragraphs to the given character width while preserving newlines.
|
Wrap text paragraphs to the given character width while preserving
|
||||||
|
newlines.
|
||||||
"""
|
"""
|
||||||
out = []
|
out = []
|
||||||
for paragraph in text.splitlines():
|
for paragraph in text.splitlines():
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ def history_path():
|
|||||||
Create the path to the history log
|
Create the path to the history log
|
||||||
"""
|
"""
|
||||||
HOME = os.path.expanduser('~')
|
HOME = os.path.expanduser('~')
|
||||||
XDG_CONFIG_HOME = os.getenv('XDG_CACHE_HOME', os.path.join(HOME, '.config'))
|
XDG_CONFIG_HOME = os.getenv('XDG_CACHE_HOME',
|
||||||
|
os.path.join(HOME, '.config'))
|
||||||
path = os.path.join(XDG_CONFIG_HOME, 'rtv')
|
path = os.path.join(XDG_CONFIG_HOME, 'rtv')
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
os.makedirs(path)
|
os.makedirs(path)
|
||||||
|
|||||||
10
rtv/oauth.py
10
rtv/oauth.py
@@ -7,7 +7,7 @@ from tornado import gen, ioloop, web, httpserver
|
|||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
|
|
||||||
from . import config
|
from . import config
|
||||||
from .curses_helpers import show_notification, prompt_input
|
from .curses_helpers import show_notification
|
||||||
from .helpers import check_browser_display, open_browser
|
from .helpers import check_browser_display, open_browser
|
||||||
|
|
||||||
__all__ = ['OAuthTool']
|
__all__ = ['OAuthTool']
|
||||||
@@ -18,6 +18,7 @@ oauth_error = None
|
|||||||
|
|
||||||
template_path = os.path.join(os.path.dirname(__file__), 'templates')
|
template_path = os.path.join(os.path.dirname(__file__), 'templates')
|
||||||
|
|
||||||
|
|
||||||
class AuthHandler(web.RequestHandler):
|
class AuthHandler(web.RequestHandler):
|
||||||
|
|
||||||
def get(self):
|
def get(self):
|
||||||
@@ -27,12 +28,14 @@ class AuthHandler(web.RequestHandler):
|
|||||||
oauth_code = self.get_argument('code', default='placeholder')
|
oauth_code = self.get_argument('code', default='placeholder')
|
||||||
oauth_error = self.get_argument('error', default='placeholder')
|
oauth_error = self.get_argument('error', default='placeholder')
|
||||||
|
|
||||||
self.render('index.html', state=oauth_state, code=oauth_code, error=oauth_error)
|
self.render('index.html', state=oauth_state, code=oauth_code,
|
||||||
|
error=oauth_error)
|
||||||
|
|
||||||
# Stop IOLoop if using a background browser such as firefox
|
# Stop IOLoop if using a background browser such as firefox
|
||||||
if check_browser_display():
|
if check_browser_display():
|
||||||
ioloop.IOLoop.current().stop()
|
ioloop.IOLoop.current().stop()
|
||||||
|
|
||||||
|
|
||||||
class OAuthTool(object):
|
class OAuthTool(object):
|
||||||
|
|
||||||
def __init__(self, reddit, stdscr=None, loader=None):
|
def __init__(self, reddit, stdscr=None, loader=None):
|
||||||
@@ -46,7 +49,8 @@ class OAuthTool(object):
|
|||||||
|
|
||||||
# Initialize Tornado webapp
|
# Initialize Tornado webapp
|
||||||
routes = [('/', AuthHandler)]
|
routes = [('/', AuthHandler)]
|
||||||
self.callback_app = web.Application(routes, template_path=template_path)
|
self.callback_app = web.Application(routes,
|
||||||
|
template_path=template_path)
|
||||||
|
|
||||||
self.reddit.set_oauth_app_info(config.oauth_client_id,
|
self.reddit.set_oauth_app_info(config.oauth_client_id,
|
||||||
config.oauth_client_secret,
|
config.oauth_client_secret,
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ class Navigator(object):
|
|||||||
self.page_index += (self.step * (n_windows-1))
|
self.page_index += (self.step * (n_windows-1))
|
||||||
self.inverted = not self.inverted
|
self.inverted = not self.inverted
|
||||||
self.cursor_index \
|
self.cursor_index \
|
||||||
= (n_windows-(direction<0)) - self.cursor_index
|
= (n_windows-(direction < 0)) - self.cursor_index
|
||||||
|
|
||||||
valid = False
|
valid = False
|
||||||
adj = 0
|
adj = 0
|
||||||
@@ -565,7 +565,8 @@ class BasePage(object):
|
|||||||
if not valid:
|
if not valid:
|
||||||
curses.flash()
|
curses.flash()
|
||||||
|
|
||||||
# Note: ACS_VLINE doesn't like changing the attribute, so always redraw.
|
# Note: ACS_VLINE doesn't like changing the attribute,
|
||||||
|
# so always redraw.
|
||||||
self._draw_content()
|
self._draw_content()
|
||||||
self._add_cursor()
|
self._add_cursor()
|
||||||
|
|
||||||
@@ -575,7 +576,8 @@ class BasePage(object):
|
|||||||
if not valid:
|
if not valid:
|
||||||
curses.flash()
|
curses.flash()
|
||||||
|
|
||||||
# Note: ACS_VLINE doesn't like changing the attribute, so always redraw.
|
# Note: ACS_VLINE doesn't like changing the attribute,
|
||||||
|
# so always redraw.
|
||||||
self._draw_content()
|
self._draw_content()
|
||||||
self._add_cursor()
|
self._add_cursor()
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from .page import BasePage, Navigator, BaseController
|
|||||||
from .submission import SubmissionPage
|
from .submission import SubmissionPage
|
||||||
from .subscription import SubscriptionPage
|
from .subscription import SubscriptionPage
|
||||||
from .content import SubredditContent
|
from .content import SubredditContent
|
||||||
from .helpers import open_browser, open_editor, strip_subreddit_url
|
from .helpers import open_browser, open_editor
|
||||||
from .docs import SUBMISSION_FILE
|
from .docs import SUBMISSION_FILE
|
||||||
from .history import load_history, save_history
|
from .history import load_history, save_history
|
||||||
from .curses_helpers import (Color, LoadScreen, add_line, get_arrow, get_gold,
|
from .curses_helpers import (Color, LoadScreen, add_line, get_arrow, get_gold,
|
||||||
@@ -105,7 +105,8 @@ class SubredditPage(BasePage):
|
|||||||
"Select the current submission to view posts"
|
"Select the current submission to view posts"
|
||||||
|
|
||||||
data = self.content.get(self.nav.absolute_index)
|
data = self.content.get(self.nav.absolute_index)
|
||||||
page = SubmissionPage(self.stdscr, self.reddit, self.oauth, url=data['permalink'])
|
page = SubmissionPage(self.stdscr, self.reddit, self.oauth,
|
||||||
|
url=data['permalink'])
|
||||||
page.loop()
|
page.loop()
|
||||||
if data['url_type'] == 'selfpost':
|
if data['url_type'] == 'selfpost':
|
||||||
global history
|
global history
|
||||||
@@ -120,7 +121,8 @@ class SubredditPage(BasePage):
|
|||||||
global history
|
global history
|
||||||
history.add(url)
|
history.add(url)
|
||||||
if data['url_type'] in ['x-post', 'selfpost']:
|
if data['url_type'] in ['x-post', 'selfpost']:
|
||||||
page = SubmissionPage(self.stdscr, self.reddit, self.oauth, url=url)
|
page = SubmissionPage(self.stdscr, self.reddit, self.oauth,
|
||||||
|
url=url)
|
||||||
page.loop()
|
page.loop()
|
||||||
else:
|
else:
|
||||||
open_browser(url)
|
open_browser(url)
|
||||||
@@ -162,7 +164,8 @@ class SubredditPage(BasePage):
|
|||||||
time.sleep(2.0)
|
time.sleep(2.0)
|
||||||
# Open the newly created post
|
# Open the newly created post
|
||||||
s.catch = False
|
s.catch = False
|
||||||
page = SubmissionPage(self.stdscr, self.reddit, self.oauth, submission=post)
|
page = SubmissionPage(self.stdscr, self.reddit, self.oauth,
|
||||||
|
submission=post)
|
||||||
page.loop()
|
page.loop()
|
||||||
self.refresh_content()
|
self.refresh_content()
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import curses
|
import curses
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from .content import SubscriptionContent
|
from .content import SubscriptionContent
|
||||||
@@ -10,9 +8,11 @@ from .curses_helpers import (Color, LoadScreen, add_line)
|
|||||||
__all__ = ['SubscriptionController', 'SubscriptionPage']
|
__all__ = ['SubscriptionController', 'SubscriptionPage']
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class SubscriptionController(BaseController):
|
class SubscriptionController(BaseController):
|
||||||
character_map = {}
|
character_map = {}
|
||||||
|
|
||||||
|
|
||||||
class SubscriptionPage(BasePage):
|
class SubscriptionPage(BasePage):
|
||||||
|
|
||||||
def __init__(self, stdscr, reddit, oauth):
|
def __init__(self, stdscr, reddit, oauth):
|
||||||
@@ -44,7 +44,8 @@ class SubscriptionPage(BasePage):
|
|||||||
def store_selected_subreddit(self):
|
def store_selected_subreddit(self):
|
||||||
"Store the selected subreddit and return to the subreddit page"
|
"Store the selected subreddit and return to the subreddit page"
|
||||||
|
|
||||||
self.selected_subreddit_data = self.content.get(self.nav.absolute_index)
|
self.selected_subreddit_data = self.content.get(
|
||||||
|
self.nav.absolute_index)
|
||||||
self.active = False
|
self.active = False
|
||||||
|
|
||||||
@SubscriptionController.register(curses.KEY_LEFT, 'h', 's')
|
@SubscriptionController.register(curses.KEY_LEFT, 'h', 's')
|
||||||
|
|||||||
Reference in New Issue
Block a user