Squashed commit of the following:
Updated the supported python versions list.
Fixed regression in displaying xposts. #173.
Fixing a few style things.
Added a more robust test for the tornado handler.
Trying without pytest-cov
Updated travis for coverage.
Remove python 3.2 support because no unicode literals, following what praw supports.
"Side effect is not iterable."
Added requirements for travis.
Renamed travis file correctly.
Adding test configurations, got tox working.
Adding vcr cassettes to the repo.
Renamed requirements files.
Split up tests and cleaned up test names.
Tests done, still one failure.
Treat cassettes as binary to prevent bad merging.
Fixed a few broken tests.
Added a timeout to notifications.
Prepping subreddit page.
Finished submission page tests.
Working on submission tests.
Fixed vcr matching on urls with params, started submission tests.
Log cleanup.
Still trying to fix a broken test.
-Fixed a few pytest bugs and tweaked logging.
Still working on subscription tests.
Finished page tests, on to subscription page.
Finished content tests and starting page tests.
Added the test refresh-token file to gitignore.
Moved functional test file out of the repository.
Continuing work on subreddit content tests.
Tests now match module names, cassettes are split into individual tests for faster loading.
Linter fixes.
Cleanup.
Added support for nested loaders.
Added pytest options, starting subreddit content tests.
Back on track with loader, continuing content tests.
Finishing submission content tests and discovered snag with loader exception handling.
VCR up and running, continuing to implement content tests.
Playing around with vcr.py
Moved helper functions into terminal and new objects.py
Fixed a few broken tests.
Working on navigator tests.
Reorganizing some things.
Mocked webbrowser._tryorder for terminal test.
Completed oauth tests.
Progress on the oauth tests.
Working on adding fake tornado request.
Starting on OAuth tool tests.
Finished curses helpers tests.
Still working on curses helpers tests.
Almost finished with tests on curses helpers.
Adding tests and working on mocking stdscr.
Starting to add tests for curses functions.
Merge branch 'future_work' of https://github.com/michael-lazar/rtv into future_work
Refactoring controller, still in progress.
Renamed auth handler.
Rename CursesHelper to CursesBase.
Added temporary file with a possible template for func testing.
Mixup between basename and dirname.
Merge branch 'future_work' of https://github.com/michael-lazar/rtv into future_work
py3 compatability for mock.
Beginning to refactor the curses session.
Started adding tests, improved unicode handling in the config.
Cleanup, fixed a few typos.
Major refactor, almost done!.
Started a config class.
Merge branch 'master' into future_work
The editor now handles unicode characters in all situations.
Fixed a few typos from previous commits.
__main__.py formatting.
Cleaned up history logic and moved to the config file.
This commit is contained in:
3
.coveragerc
Normal file
3
.coveragerc
Normal file
@@ -0,0 +1,3 @@
|
||||
[run]
|
||||
source = rtv
|
||||
omit = *__main__.py
|
||||
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
tests/cassettes/* binary
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,3 +4,4 @@
|
||||
build
|
||||
dist
|
||||
rtv.egg-info
|
||||
tests/refresh-token
|
||||
|
||||
15
.travis.yml
Normal file
15
.travis.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
language: python
|
||||
python:
|
||||
- "2.7"
|
||||
- "3.3"
|
||||
- "3.4"
|
||||
- "3.5"
|
||||
before_install:
|
||||
- pip install coveralls pytest coverage mock
|
||||
- pip install git+https://github.com/kevin1024/vcrpy.git
|
||||
install:
|
||||
- pip install .
|
||||
script:
|
||||
- coverage run -m py.test -v
|
||||
after_success:
|
||||
- coveralls
|
||||
@@ -1,6 +0,0 @@
|
||||
tornado
|
||||
praw>=3.3.0
|
||||
six
|
||||
requests
|
||||
kitchen
|
||||
futures
|
||||
@@ -1,5 +0,0 @@
|
||||
tornado
|
||||
praw>=3.3.0
|
||||
six
|
||||
requests
|
||||
kitchen
|
||||
@@ -1,3 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from .__version__ import __version__
|
||||
|
||||
__title__ = 'Reddit Terminal Viewer'
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import sys
|
||||
import locale
|
||||
import logging
|
||||
|
||||
import praw
|
||||
import praw.errors
|
||||
import tornado
|
||||
from requests import exceptions
|
||||
|
||||
from . import config
|
||||
from .exceptions import RTVError
|
||||
from .curses_helpers import curses_session, LoadScreen
|
||||
from .submission import SubmissionPage
|
||||
from . import docs
|
||||
from .config import Config
|
||||
from .oauth import OAuthHelper
|
||||
from .terminal import Terminal
|
||||
from .objects import curses_session
|
||||
from .subreddit import SubredditPage
|
||||
from .docs import AGENT
|
||||
from .oauth import OAuthTool
|
||||
from .__version__ import __version__
|
||||
|
||||
__all__ = []
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
# Pycharm debugging note:
|
||||
@@ -35,57 +34,66 @@ def main():
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
|
||||
# Set the terminal title
|
||||
# TODO: Need to clear the title when the program exits
|
||||
title = 'rtv {0}'.format(__version__)
|
||||
sys.stdout.write("\x1b]2;{0}\x07".format(title))
|
||||
sys.stdout.write('\x1b]2;{0}\x07'.format(title))
|
||||
|
||||
# Fill in empty arguments with config file values. Parameters explicitly
|
||||
# typed on the command line will take priority over config file params.
|
||||
parser = config.build_parser()
|
||||
args = parser.parse_args()
|
||||
# Attempt to load from the config file first, and then overwrite with any
|
||||
# provided command line arguments.
|
||||
config = Config()
|
||||
config.from_file()
|
||||
config.from_args()
|
||||
|
||||
local_config = config.load_config()
|
||||
for key, val in local_config.items():
|
||||
if getattr(args, key, None) is None:
|
||||
setattr(args, key, val)
|
||||
# Load the browsing history from previous sessions
|
||||
config.load_history()
|
||||
|
||||
if args.ascii:
|
||||
config.unicode = False
|
||||
if not args.persistent:
|
||||
config.persistent = False
|
||||
if args.clear_auth:
|
||||
config.clear_refresh_token()
|
||||
# Load any previously saved auth session token
|
||||
config.load_refresh_token()
|
||||
if config['clear_auth']:
|
||||
config.delete_refresh_token()
|
||||
|
||||
if args.log:
|
||||
logging.basicConfig(level=logging.DEBUG, filename=args.log)
|
||||
if config['log']:
|
||||
logging.basicConfig(level=logging.DEBUG, filename=config['log'])
|
||||
else:
|
||||
# Add an empty handler so the logger doesn't complain
|
||||
logging.root.addHandler(logging.NullHandler())
|
||||
|
||||
# Construct the reddit user agent
|
||||
user_agent = docs.AGENT.format(version=__version__)
|
||||
|
||||
try:
|
||||
print('Connecting...')
|
||||
reddit = praw.Reddit(user_agent=AGENT.format(version=__version__))
|
||||
reddit.config.decode_html_entities = False
|
||||
with curses_session() as stdscr:
|
||||
oauth = OAuthTool(reddit, stdscr, LoadScreen(stdscr))
|
||||
if oauth.refresh_token:
|
||||
term = Terminal(stdscr, config['ascii'])
|
||||
with term.loader(catch_exception=False):
|
||||
reddit = praw.Reddit(
|
||||
user_agent=user_agent,
|
||||
decode_html_entities=False,
|
||||
disable_update_check=True)
|
||||
|
||||
# Authorize on launch if the refresh token is present
|
||||
oauth = OAuthHelper(reddit, term, config)
|
||||
if config.refresh_token:
|
||||
oauth.authorize()
|
||||
|
||||
if args.link:
|
||||
page = SubmissionPage(stdscr, reddit, oauth, url=args.link)
|
||||
page.loop()
|
||||
subreddit = args.subreddit or 'front'
|
||||
page = SubredditPage(stdscr, reddit, oauth, subreddit)
|
||||
with term.loader():
|
||||
page = SubredditPage(
|
||||
reddit, term, config, oauth,
|
||||
name=config['subreddit'], url=config['link'])
|
||||
if term.loader.exception:
|
||||
return
|
||||
|
||||
page.loop()
|
||||
except (exceptions.RequestException, praw.errors.PRAWException,
|
||||
RTVError) as e:
|
||||
except Exception as e:
|
||||
_logger.exception(e)
|
||||
print('{}: {}'.format(type(e).__name__, e))
|
||||
raise
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
finally:
|
||||
# Try to save the browsing history
|
||||
config.save_history()
|
||||
# Ensure sockets are closed to prevent a ResourceWarning
|
||||
reddit.handler.http.close()
|
||||
if 'reddit' in locals():
|
||||
reddit.handler.http.close()
|
||||
# Explicitly close file descriptors opened by Tornado's IOLoop
|
||||
tornado.ioloop.IOLoop.current().close(all_fds=True)
|
||||
|
||||
sys.exit(main())
|
||||
sys.exit(main())
|
||||
@@ -1 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
__version__ = '1.6.1'
|
||||
|
||||
198
rtv/config.py
198
rtv/config.py
@@ -1,38 +1,30 @@
|
||||
"""
|
||||
Global configuration settings
|
||||
"""
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
import codecs
|
||||
import argparse
|
||||
from six.moves import configparser
|
||||
|
||||
from . import docs, __version__
|
||||
|
||||
HOME = os.path.expanduser('~')
|
||||
PACKAGE = os.path.dirname(__file__)
|
||||
XDG_HOME = os.getenv('XDG_CONFIG_HOME', os.path.join(HOME, '.config'))
|
||||
CONFIG = os.path.join(XDG_HOME, 'rtv', 'rtv.cfg')
|
||||
TOKEN = os.path.join(XDG_HOME, 'rtv', 'refresh-token')
|
||||
|
||||
unicode = True
|
||||
persistent = True
|
||||
|
||||
# https://github.com/reddit/reddit/wiki/OAuth2
|
||||
# Client ID is of type "installed app" and the secret should be left empty
|
||||
oauth_client_id = 'E2oEtRQfdfAfNQ'
|
||||
oauth_client_secret = 'praw_gapfill'
|
||||
oauth_redirect_uri = 'http://127.0.0.1:65000/'
|
||||
oauth_redirect_port = 65000
|
||||
oauth_scope = ['edit', 'history', 'identity', 'mysubreddits',
|
||||
'privatemessages', 'read', 'report', 'save', 'submit',
|
||||
'subscribe', 'vote']
|
||||
HISTORY = os.path.join(XDG_HOME, 'rtv', 'history.log')
|
||||
TEMPLATE = os.path.join(PACKAGE, 'templates')
|
||||
|
||||
|
||||
def build_parser():
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
prog='rtv', description=docs.SUMMARY, epilog=docs.CONTROLS+docs.HELP,
|
||||
prog='rtv', description=docs.SUMMARY,
|
||||
epilog=docs.CONTROLS+docs.HELP,
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
parser.add_argument(
|
||||
'-V', '--version', action='version', version='rtv '+__version__,
|
||||
)
|
||||
'-V', '--version', action='version', version='rtv '+__version__)
|
||||
parser.add_argument(
|
||||
'-s', dest='subreddit',
|
||||
help='name of the subreddit that will be opened on start')
|
||||
@@ -40,57 +32,163 @@ def build_parser():
|
||||
'-l', dest='link',
|
||||
help='full URL of a submission that will be opened on start')
|
||||
parser.add_argument(
|
||||
'--ascii', action='store_true',
|
||||
'--ascii', action='store_const', const=True,
|
||||
help='enable ascii-only mode')
|
||||
parser.add_argument(
|
||||
'--log', metavar='FILE', action='store',
|
||||
help='log HTTP requests to a file')
|
||||
parser.add_argument(
|
||||
'--non-persistent', dest='persistent', action='store_false',
|
||||
'--non-persistent', dest='persistent', action='store_const',
|
||||
const=False,
|
||||
help='Forget all authenticated users when the program exits')
|
||||
parser.add_argument(
|
||||
'--clear-auth', dest='clear_auth', action='store_true',
|
||||
'--clear-auth', dest='clear_auth', action='store_const', const=True,
|
||||
help='Remove any saved OAuth tokens before starting')
|
||||
return parser
|
||||
|
||||
|
||||
def load_config():
|
||||
class OrderedSet(object):
|
||||
"""
|
||||
Attempt to load settings from the local config file.
|
||||
A simple implementation of an ordered set. A set is used to check
|
||||
for membership, and a list is used to maintain ordering.
|
||||
"""
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
if os.path.exists(CONFIG):
|
||||
config.read(CONFIG)
|
||||
def __init__(self, elements=None):
|
||||
elements = elements or []
|
||||
self._set = set(elements)
|
||||
self._list = elements
|
||||
|
||||
config_dict = {}
|
||||
if config.has_section('rtv'):
|
||||
config_dict = dict(config.items('rtv'))
|
||||
def __contains__(self, item):
|
||||
return item in self._set
|
||||
|
||||
# Convert 'true'/'false' to boolean True/False
|
||||
if 'ascii' in config_dict:
|
||||
config_dict['ascii'] = config.getboolean('rtv', 'ascii')
|
||||
if 'clear_auth' in config_dict:
|
||||
config_dict['clear_auth'] = config.getboolean('rtv', 'clear_auth')
|
||||
if 'persistent' in config_dict:
|
||||
config_dict['persistent'] = config.getboolean('rtv', 'persistent')
|
||||
def __len__(self):
|
||||
return len(self._list)
|
||||
|
||||
return config_dict
|
||||
def __getitem__(self, item):
|
||||
return self._list[item]
|
||||
|
||||
def add(self, item):
|
||||
self._set.add(item)
|
||||
self._list.append(item)
|
||||
|
||||
|
||||
def load_refresh_token(filename=TOKEN):
|
||||
if os.path.exists(filename):
|
||||
with open(filename) as fp:
|
||||
return fp.read().strip()
|
||||
else:
|
||||
return None
|
||||
class Config(object):
|
||||
|
||||
DEFAULT = {
|
||||
'ascii': False,
|
||||
'persistent': True,
|
||||
'clear_auth': False,
|
||||
'log': None,
|
||||
'link': None,
|
||||
'subreddit': 'front',
|
||||
'history_size': 200,
|
||||
# https://github.com/reddit/reddit/wiki/OAuth2
|
||||
# Client ID is of type "installed app" and the secret should be empty
|
||||
'oauth_client_id': 'E2oEtRQfdfAfNQ',
|
||||
'oauth_client_secret': 'praw_gapfill',
|
||||
'oauth_redirect_uri': 'http://127.0.0.1:65000/',
|
||||
'oauth_redirect_port': 65000,
|
||||
'oauth_scope': [
|
||||
'edit', 'history', 'identity', 'mysubreddits', 'privatemessages',
|
||||
'read', 'report', 'save', 'submit', 'subscribe', 'vote'],
|
||||
'template_path': TEMPLATE,
|
||||
}
|
||||
|
||||
def save_refresh_token(token, filename=TOKEN):
|
||||
with open(filename, 'w+') as fp:
|
||||
fp.write(token)
|
||||
def __init__(self,
|
||||
config_file=CONFIG,
|
||||
history_file=HISTORY,
|
||||
token_file=TOKEN,
|
||||
**kwargs):
|
||||
|
||||
self.config_file = config_file
|
||||
self.history_file = history_file
|
||||
self.token_file = token_file
|
||||
self.config = kwargs
|
||||
|
||||
def clear_refresh_token(filename=TOKEN):
|
||||
if os.path.exists(filename):
|
||||
os.remove(filename)
|
||||
# `refresh_token` and `history` are saved/loaded at separate locations,
|
||||
# so they are treated differently from the rest of the config options.
|
||||
self.refresh_token = None
|
||||
self.history = OrderedSet()
|
||||
|
||||
def __getitem__(self, item):
|
||||
return self.config.get(item, self.DEFAULT.get(item))
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
self.config[key] = value
|
||||
|
||||
def __delitem__(self, key):
|
||||
self.config.pop(key, None)
|
||||
|
||||
def update(self, **kwargs):
|
||||
self.config.update(kwargs)
|
||||
|
||||
def from_args(self):
|
||||
parser = build_parser()
|
||||
args = vars(parser.parse_args())
|
||||
# Filter out argument values that weren't supplied
|
||||
args = {key: val for key, val in args.items() if val is not None}
|
||||
self.update(**args)
|
||||
|
||||
def from_file(self):
|
||||
config = configparser.ConfigParser()
|
||||
if os.path.exists(self.config_file):
|
||||
with codecs.open(self.config_file, encoding='utf-8') as fp:
|
||||
config.readfp(fp)
|
||||
|
||||
config_dict = {}
|
||||
if config.has_section('rtv'):
|
||||
config_dict = dict(config.items('rtv'))
|
||||
|
||||
# Convert 'true'/'false' to boolean True/False
|
||||
if 'ascii' in config_dict:
|
||||
config_dict['ascii'] = config.getboolean('rtv', 'ascii')
|
||||
if 'clear_auth' in config_dict:
|
||||
config_dict['clear_auth'] = config.getboolean('rtv', 'clear_auth')
|
||||
if 'persistent' in config_dict:
|
||||
config_dict['persistent'] = config.getboolean('rtv', 'persistent')
|
||||
|
||||
self.update(**config_dict)
|
||||
|
||||
def load_refresh_token(self):
|
||||
if os.path.exists(self.token_file):
|
||||
with open(self.token_file) as fp:
|
||||
self.refresh_token = fp.read().strip()
|
||||
else:
|
||||
self.refresh_token = None
|
||||
|
||||
def save_refresh_token(self):
|
||||
self._ensure_filepath(self.token_file)
|
||||
with open(self.token_file, 'w+') as fp:
|
||||
fp.write(self.refresh_token)
|
||||
|
||||
def delete_refresh_token(self):
|
||||
if os.path.exists(self.token_file):
|
||||
os.remove(self.token_file)
|
||||
self.refresh_token = None
|
||||
|
||||
def load_history(self):
|
||||
if os.path.exists(self.history_file):
|
||||
with codecs.open(self.history_file, encoding='utf-8') as fp:
|
||||
self.history = OrderedSet([line.strip() for line in fp])
|
||||
else:
|
||||
self.history = OrderedSet()
|
||||
|
||||
def save_history(self):
|
||||
self._ensure_filepath(self.history_file)
|
||||
with codecs.open(self.history_file, 'w+', encoding='utf-8') as fp:
|
||||
fp.writelines('\n'.join(self.history[-self['history_size']:]))
|
||||
|
||||
def delete_history(self):
|
||||
if os.path.exists(self.history_file):
|
||||
os.remove(self.history_file)
|
||||
self.history = OrderedSet()
|
||||
|
||||
@staticmethod
|
||||
def _ensure_filepath(filename):
|
||||
"""
|
||||
Ensure that the directory exists before trying to write to the file.
|
||||
"""
|
||||
|
||||
filepath = os.path.dirname(filename)
|
||||
if not os.path.exists(filepath):
|
||||
os.makedirs(filepath)
|
||||
147
rtv/content.py
147
rtv/content.py
@@ -1,28 +1,27 @@
|
||||
import logging
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import praw
|
||||
import requests
|
||||
import re
|
||||
from datetime import datetime
|
||||
|
||||
from .exceptions import (SubmissionError, SubredditError, SubscriptionError,
|
||||
AccountError)
|
||||
from .helpers import humanize_timestamp, wrap_text, strip_subreddit_url
|
||||
import six
|
||||
import praw
|
||||
from kitchen.text.display import wrap
|
||||
|
||||
__all__ = ['SubredditContent', 'SubmissionContent', 'SubscriptionContent']
|
||||
_logger = logging.getLogger(__name__)
|
||||
from . import exceptions
|
||||
|
||||
|
||||
class BaseContent(object):
|
||||
class Content(object):
|
||||
|
||||
def get(self, index, n_cols):
|
||||
raise NotImplementedError
|
||||
|
||||
def iterate(self, index, step, n_cols):
|
||||
def iterate(self, index, step, n_cols=70):
|
||||
|
||||
while True:
|
||||
if step < 0 and index < 0:
|
||||
# Hack to prevent displaying negative indices if iterating in
|
||||
# the negative direction.
|
||||
# Hack to prevent displaying a submission's post if iterating
|
||||
# comments in the negative direction
|
||||
break
|
||||
try:
|
||||
yield self.get(index, n_cols=n_cols)
|
||||
@@ -63,8 +62,8 @@ class BaseContent(object):
|
||||
retval.append(item)
|
||||
return retval
|
||||
|
||||
@staticmethod
|
||||
def strip_praw_comment(comment):
|
||||
@classmethod
|
||||
def strip_praw_comment(cls, comment):
|
||||
"""
|
||||
Parse through a submission comment and return a dict with data ready to
|
||||
be displayed through the terminal.
|
||||
@@ -89,7 +88,7 @@ class BaseContent(object):
|
||||
|
||||
data['type'] = 'Comment'
|
||||
data['body'] = comment.body
|
||||
data['created'] = humanize_timestamp(comment.created_utc)
|
||||
data['created'] = cls.humanize_timestamp(comment.created_utc)
|
||||
data['score'] = '{} pts'.format(comment.score)
|
||||
data['author'] = name
|
||||
data['is_author'] = (name == sub_name)
|
||||
@@ -100,8 +99,8 @@ class BaseContent(object):
|
||||
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
def strip_praw_submission(sub):
|
||||
@classmethod
|
||||
def strip_praw_submission(cls, sub):
|
||||
"""
|
||||
Parse through a submission and return a dict with data ready to be
|
||||
displayed through the terminal.
|
||||
@@ -114,7 +113,7 @@ class BaseContent(object):
|
||||
"""
|
||||
|
||||
reddit_link = re.compile(
|
||||
"https?://(www\.)?(np\.)?redd(it\.com|\.it)/r/.*")
|
||||
'https?://(www\.)?(np\.)?redd(it\.com|\.it)/r/.*')
|
||||
author = getattr(sub, 'author', '[deleted]')
|
||||
name = getattr(author, 'name', '[deleted]')
|
||||
flair = getattr(sub, 'link_flair_text', '')
|
||||
@@ -124,12 +123,12 @@ class BaseContent(object):
|
||||
data['type'] = 'Submission'
|
||||
data['title'] = sub.title
|
||||
data['text'] = sub.selftext
|
||||
data['created'] = humanize_timestamp(sub.created_utc)
|
||||
data['created'] = cls.humanize_timestamp(sub.created_utc)
|
||||
data['comments'] = '{} comments'.format(sub.num_comments)
|
||||
data['score'] = '{} pts'.format(sub.score)
|
||||
data['author'] = name
|
||||
data['permalink'] = sub.permalink
|
||||
data['subreddit'] = str(sub.subreddit)
|
||||
data['subreddit'] = six.text_type(sub.subreddit)
|
||||
data['flair'] = flair
|
||||
data['url_full'] = sub.url
|
||||
data['likes'] = sub.likes
|
||||
@@ -146,7 +145,9 @@ class BaseContent(object):
|
||||
data['url'] = 'self.{}'.format(data['subreddit'])
|
||||
elif reddit_link.match(url_full):
|
||||
data['url_type'] = 'x-post'
|
||||
data['url'] = 'self.{}'.format(strip_subreddit_url(url_full)[3:])
|
||||
# Strip the subreddit name from the permalink to avoid having
|
||||
# submission.subreddit.url make a separate API call
|
||||
data['url'] = 'self.{}'.format(url_full.split('/')[4])
|
||||
else:
|
||||
data['url_type'] = 'external'
|
||||
data['url'] = url_full
|
||||
@@ -165,11 +166,51 @@ class BaseContent(object):
|
||||
data['type'] = 'Subscription'
|
||||
data['name'] = "/r/" + subscription.display_name
|
||||
data['title'] = subscription.title
|
||||
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
def humanize_timestamp(utc_timestamp, verbose=False):
|
||||
"""
|
||||
Convert a utc timestamp into a human readable relative-time.
|
||||
"""
|
||||
|
||||
class SubmissionContent(BaseContent):
|
||||
timedelta = datetime.utcnow() - datetime.utcfromtimestamp(utc_timestamp)
|
||||
|
||||
seconds = int(timedelta.total_seconds())
|
||||
if seconds < 60:
|
||||
return 'moments ago' if verbose else '0min'
|
||||
minutes = seconds // 60
|
||||
if minutes < 60:
|
||||
return '%d minutes ago' % minutes if verbose else '%dmin' % minutes
|
||||
hours = minutes // 60
|
||||
if hours < 24:
|
||||
return '%d hours ago' % hours if verbose else '%dhr' % hours
|
||||
days = hours // 24
|
||||
if days < 30:
|
||||
return '%d days ago' % days if verbose else '%dday' % days
|
||||
months = days // 30.4
|
||||
if months < 12:
|
||||
return '%d months ago' % months if verbose else '%dmonth' % months
|
||||
years = months // 12
|
||||
return '%d years ago' % years if verbose else '%dyr' % years
|
||||
|
||||
@staticmethod
|
||||
def wrap_text(text, width):
|
||||
"""
|
||||
Wrap text paragraphs to the given character width while preserving
|
||||
newlines.
|
||||
"""
|
||||
out = []
|
||||
for paragraph in text.splitlines():
|
||||
# Wrap returns an empty list when paragraph is a newline. In order
|
||||
# to preserve newlines we substitute a list containing an empty
|
||||
# string.
|
||||
lines = wrap(paragraph, width=width) or ['']
|
||||
out.extend(lines)
|
||||
return out
|
||||
|
||||
|
||||
class SubmissionContent(Content):
|
||||
"""
|
||||
Grab a submission from PRAW and lazily store comments to an internal
|
||||
list for repeat access.
|
||||
@@ -194,13 +235,8 @@ class SubmissionContent(BaseContent):
|
||||
def from_url(cls, reddit, url, loader, indent_size=2, max_indent_level=8,
|
||||
order=None):
|
||||
|
||||
try:
|
||||
with loader():
|
||||
url = url.replace('http:', 'https:')
|
||||
submission = reddit.get_submission(url, comment_sort=order)
|
||||
except (praw.errors.APIException, praw.errors.NotFound):
|
||||
raise SubmissionError('Could not load %s' % url)
|
||||
|
||||
url = url.replace('http:', 'https:')
|
||||
submission = reddit.get_submission(url, comment_sort=order)
|
||||
return cls(submission, loader, indent_size, max_indent_level, order)
|
||||
|
||||
def get(self, index, n_cols=70):
|
||||
@@ -214,8 +250,8 @@ class SubmissionContent(BaseContent):
|
||||
|
||||
elif index == -1:
|
||||
data = self._submission_data
|
||||
data['split_title'] = wrap_text(data['title'], width=n_cols-2)
|
||||
data['split_text'] = wrap_text(data['text'], width=n_cols-2)
|
||||
data['split_title'] = self.wrap_text(data['title'], width=n_cols-2)
|
||||
data['split_text'] = self.wrap_text(data['text'], width=n_cols-2)
|
||||
data['n_rows'] = len(data['split_title'] + data['split_text']) + 5
|
||||
data['offset'] = 0
|
||||
|
||||
@@ -226,7 +262,7 @@ class SubmissionContent(BaseContent):
|
||||
|
||||
if data['type'] == 'Comment':
|
||||
width = n_cols - data['offset']
|
||||
data['split_body'] = wrap_text(data['body'], width=width)
|
||||
data['split_body'] = self.wrap_text(data['body'], width=width)
|
||||
data['n_rows'] = len(data['split_body']) + 1
|
||||
else:
|
||||
data['n_rows'] = 1
|
||||
@@ -270,17 +306,19 @@ class SubmissionContent(BaseContent):
|
||||
|
||||
elif data['type'] == 'MoreComments':
|
||||
with self._loader():
|
||||
# Undefined behavior if using a nested loader here
|
||||
assert self._loader.depth == 1
|
||||
comments = data['object'].comments(update=True)
|
||||
comments = self.flatten_comments(comments,
|
||||
root_level=data['level'])
|
||||
if not self._loader.exception:
|
||||
comments = self.flatten_comments(comments, data['level'])
|
||||
comment_data = [self.strip_praw_comment(c) for c in comments]
|
||||
self._comment_data[index:index + 1] = comment_data
|
||||
|
||||
else:
|
||||
raise ValueError('% type not recognized' % data['type'])
|
||||
raise ValueError('%s type not recognized' % data['type'])
|
||||
|
||||
|
||||
class SubredditContent(BaseContent):
|
||||
class SubredditContent(Content):
|
||||
"""
|
||||
Grab a subreddit from PRAW and lazily stores submissions to an internal
|
||||
list for repeat access.
|
||||
@@ -300,11 +338,8 @@ class SubredditContent(BaseContent):
|
||||
# don't have a real corresponding subreddit object.
|
||||
try:
|
||||
self.get(0)
|
||||
except (praw.errors.APIException, requests.HTTPError,
|
||||
praw.errors.RedirectException, praw.errors.Forbidden,
|
||||
praw.errors.InvalidSubreddit, praw.errors.NotFound,
|
||||
IndexError):
|
||||
raise SubredditError('Could not reach subreddit %s' % name)
|
||||
except IndexError:
|
||||
raise exceptions.SubredditError('Unable to retrieve subreddit')
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, reddit, name, loader, order=None, query=None):
|
||||
@@ -322,11 +357,11 @@ class SubredditContent(BaseContent):
|
||||
display_name = '/r/{}'.format(name)
|
||||
|
||||
if order not in ['hot', 'top', 'rising', 'new', 'controversial', None]:
|
||||
raise SubredditError('Unrecognized order "%s"' % order)
|
||||
raise exceptions.SubredditError('Unrecognized order "%s"' % order)
|
||||
|
||||
if name == 'me':
|
||||
if not reddit.is_oauth_session():
|
||||
raise AccountError('Could not access user account')
|
||||
raise exceptions.AccountError('Could not access user account')
|
||||
elif order:
|
||||
submissions = reddit.user.get_submitted(sort=order)
|
||||
else:
|
||||
@@ -375,25 +410,27 @@ class SubredditContent(BaseContent):
|
||||
try:
|
||||
with self._loader():
|
||||
submission = next(self._submissions)
|
||||
if self._loader.exception:
|
||||
raise IndexError
|
||||
except StopIteration:
|
||||
raise IndexError
|
||||
else:
|
||||
data = self.strip_praw_submission(submission)
|
||||
data['index'] = index
|
||||
# Add the post number to the beginning of the title
|
||||
data['title'] = u'{}. {}'.format(index+1, data['title'])
|
||||
data['title'] = '{0}. {1}'.format(index+1, data['title'])
|
||||
self._submission_data.append(data)
|
||||
|
||||
# Modifies the original dict, faster than copying
|
||||
data = self._submission_data[index]
|
||||
data['split_title'] = wrap_text(data['title'], width=n_cols)
|
||||
data['split_title'] = self.wrap_text(data['title'], width=n_cols)
|
||||
data['n_rows'] = len(data['split_title']) + 3
|
||||
data['offset'] = 0
|
||||
|
||||
return data
|
||||
|
||||
|
||||
class SubscriptionContent(BaseContent):
|
||||
class SubscriptionContent(Content):
|
||||
|
||||
def __init__(self, subscriptions, loader):
|
||||
|
||||
@@ -403,14 +440,14 @@ class SubscriptionContent(BaseContent):
|
||||
self._subscriptions = subscriptions
|
||||
self._subscription_data = []
|
||||
|
||||
try:
|
||||
self.get(0)
|
||||
except IndexError:
|
||||
raise exceptions.SubscriptionError('Unable to load subscriptions')
|
||||
|
||||
@classmethod
|
||||
def from_user(cls, reddit, loader):
|
||||
try:
|
||||
with loader():
|
||||
subscriptions = reddit.get_my_subreddits(limit=None)
|
||||
except praw.errors.APIException:
|
||||
raise SubscriptionError('Unable to load subscriptions')
|
||||
|
||||
subscriptions = reddit.get_my_subreddits(limit=None)
|
||||
return cls(subscriptions, loader)
|
||||
|
||||
def get(self, index, n_cols=70):
|
||||
@@ -426,6 +463,8 @@ class SubscriptionContent(BaseContent):
|
||||
try:
|
||||
with self._loader():
|
||||
subscription = next(self._subscriptions)
|
||||
if self._loader.exception:
|
||||
raise IndexError
|
||||
except StopIteration:
|
||||
raise IndexError
|
||||
else:
|
||||
@@ -433,7 +472,7 @@ class SubscriptionContent(BaseContent):
|
||||
self._subscription_data.append(data)
|
||||
|
||||
data = self._subscription_data[index]
|
||||
data['split_title'] = wrap_text(data['title'], width=n_cols)
|
||||
data['split_title'] = self.wrap_text(data['title'], width=n_cols)
|
||||
data['n_rows'] = len(data['split_title']) + 1
|
||||
data['offset'] = 0
|
||||
|
||||
|
||||
@@ -1,368 +0,0 @@
|
||||
import os
|
||||
import time
|
||||
import threading
|
||||
import curses
|
||||
from curses import textpad, ascii
|
||||
from contextlib import contextmanager
|
||||
|
||||
from . import config
|
||||
from .docs import HELP
|
||||
from .helpers import strip_textpad, clean
|
||||
from .exceptions import EscapeInterrupt
|
||||
|
||||
__all__ = ['ESCAPE', 'get_gold', 'show_notification', 'show_help',
|
||||
'LoadScreen', 'Color', 'text_input', 'curses_session',
|
||||
'prompt_input', 'add_line', 'get_arrow']
|
||||
|
||||
# Curses does define constants for symbols (e.g. curses.ACS_BULLET)
|
||||
# However, they rely on using the curses.addch() function, which has been
|
||||
# found to be buggy and a PITA to work with. By defining them as unicode
|
||||
# points they can be added via the more reliable curses.addstr().
|
||||
# http://bugs.python.org/issue21088
|
||||
ESCAPE = 27
|
||||
|
||||
|
||||
def get_gold():
|
||||
"""
|
||||
Return the gilded symbol.
|
||||
"""
|
||||
|
||||
symbol = u'\u272A' if config.unicode else '*'
|
||||
attr = curses.A_BOLD | Color.YELLOW
|
||||
return symbol, attr
|
||||
|
||||
|
||||
def get_arrow(likes):
|
||||
"""
|
||||
Return the vote symbol to display, based on the `likes` paramater.
|
||||
"""
|
||||
|
||||
if likes is None:
|
||||
symbol = u'\u2022' if config.unicode else 'o'
|
||||
attr = curses.A_BOLD
|
||||
elif likes:
|
||||
symbol = u'\u25b2' if config.unicode else '^'
|
||||
attr = curses.A_BOLD | Color.GREEN
|
||||
else:
|
||||
symbol = u'\u25bc' if config.unicode else 'v'
|
||||
attr = curses.A_BOLD | Color.RED
|
||||
return symbol, attr
|
||||
|
||||
|
||||
def add_line(window, text, row=None, col=None, attr=None):
|
||||
"""
|
||||
Unicode aware version of curses's built-in addnstr method.
|
||||
|
||||
Safely draws a line of text on the window starting at position (row, col).
|
||||
Checks the boundaries of the window and cuts off the text if it exceeds
|
||||
the length of the window.
|
||||
"""
|
||||
|
||||
# The following arg combinations must be supported to conform with addnstr
|
||||
# (window, text)
|
||||
# (window, text, attr)
|
||||
# (window, text, row, col)
|
||||
# (window, text, row, col, attr)
|
||||
|
||||
cursor_row, cursor_col = window.getyx()
|
||||
row = row if row is not None else cursor_row
|
||||
col = col if col is not None else cursor_col
|
||||
|
||||
max_rows, max_cols = window.getmaxyx()
|
||||
n_cols = max_cols - col - 1
|
||||
if n_cols <= 0:
|
||||
# Trying to draw outside of the screen bounds
|
||||
return
|
||||
|
||||
text = clean(text, n_cols)
|
||||
params = [] if attr is None else [attr]
|
||||
window.addstr(row, col, text, *params)
|
||||
|
||||
|
||||
def show_notification(stdscr, message):
|
||||
"""
|
||||
Overlay a message box on the center of the screen and wait for user input.
|
||||
|
||||
Params:
|
||||
message (list): List of strings, one per line.
|
||||
"""
|
||||
|
||||
n_rows, n_cols = stdscr.getmaxyx()
|
||||
|
||||
box_width = max(map(len, message)) + 2
|
||||
box_height = len(message) + 2
|
||||
|
||||
# Cut off the lines of the message that don't fit on the screen
|
||||
box_width = min(box_width, n_cols)
|
||||
box_height = min(box_height, n_rows)
|
||||
message = message[:box_height-2]
|
||||
|
||||
s_row = (n_rows - box_height) // 2
|
||||
s_col = (n_cols - box_width) // 2
|
||||
|
||||
window = stdscr.derwin(box_height, box_width, s_row, s_col)
|
||||
window.erase()
|
||||
window.border()
|
||||
|
||||
for index, line in enumerate(message, start=1):
|
||||
add_line(window, line, index, 1)
|
||||
window.refresh()
|
||||
ch = stdscr.getch()
|
||||
|
||||
window.clear()
|
||||
window = None
|
||||
stdscr.refresh()
|
||||
|
||||
return ch
|
||||
|
||||
|
||||
def show_help(stdscr):
|
||||
"""
|
||||
Overlay a message box with the help screen.
|
||||
"""
|
||||
|
||||
show_notification(stdscr, HELP.splitlines())
|
||||
|
||||
|
||||
class LoadScreen(object):
|
||||
|
||||
"""
|
||||
Display a loading dialog while waiting for a blocking action to complete.
|
||||
|
||||
This class spins off a separate thread to animate the loading screen in the
|
||||
background.
|
||||
|
||||
Usage:
|
||||
#>>> loader = LoadScreen(stdscr)
|
||||
#>>> with loader(...):
|
||||
#>>> blocking_request(...)
|
||||
"""
|
||||
|
||||
def __init__(self, stdscr):
|
||||
|
||||
self._stdscr = stdscr
|
||||
|
||||
self._args = None
|
||||
self._animator = None
|
||||
self._is_running = None
|
||||
|
||||
def __call__(
|
||||
self,
|
||||
delay=0.5,
|
||||
interval=0.4,
|
||||
message='Downloading',
|
||||
trail='...'):
|
||||
"""
|
||||
Params:
|
||||
delay (float): Length of time that the loader will wait before
|
||||
printing on the screen. Used to prevent flicker on pages that
|
||||
load very fast.
|
||||
interval (float): Length of time between each animation frame.
|
||||
message (str): Message to display
|
||||
trail (str): Trail of characters that will be animated by the
|
||||
loading screen.
|
||||
"""
|
||||
|
||||
self._args = (delay, interval, message, trail)
|
||||
return self
|
||||
|
||||
def __enter__(self):
|
||||
|
||||
self._animator = threading.Thread(target=self.animate, args=self._args)
|
||||
self._animator.daemon = True
|
||||
|
||||
self._is_running = True
|
||||
self._animator.start()
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
|
||||
self._is_running = False
|
||||
self._animator.join()
|
||||
|
||||
def animate(self, delay, interval, message, trail):
|
||||
|
||||
start = time.time()
|
||||
while (time.time() - start) < delay:
|
||||
if not self._is_running:
|
||||
return
|
||||
|
||||
message_len = len(message) + len(trail)
|
||||
n_rows, n_cols = self._stdscr.getmaxyx()
|
||||
s_row = (n_rows - 3) // 2
|
||||
s_col = (n_cols - message_len - 1) // 2
|
||||
window = self._stdscr.derwin(3, message_len + 2, s_row, s_col)
|
||||
|
||||
while True:
|
||||
for i in range(len(trail) + 1):
|
||||
|
||||
if not self._is_running:
|
||||
window.clear()
|
||||
window = None
|
||||
self._stdscr.refresh()
|
||||
return
|
||||
|
||||
window.erase()
|
||||
window.border()
|
||||
window.addstr(1, 1, message + trail[:i])
|
||||
window.refresh()
|
||||
time.sleep(interval)
|
||||
|
||||
|
||||
class Color(object):
|
||||
|
||||
"""
|
||||
Color attributes for curses.
|
||||
"""
|
||||
|
||||
_colors = {
|
||||
'RED': (curses.COLOR_RED, -1),
|
||||
'GREEN': (curses.COLOR_GREEN, -1),
|
||||
'YELLOW': (curses.COLOR_YELLOW, -1),
|
||||
'BLUE': (curses.COLOR_BLUE, -1),
|
||||
'MAGENTA': (curses.COLOR_MAGENTA, -1),
|
||||
'CYAN': (curses.COLOR_CYAN, -1),
|
||||
'WHITE': (curses.COLOR_WHITE, -1),
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def init(cls):
|
||||
"""
|
||||
Initialize color pairs inside of curses using the default background.
|
||||
|
||||
This should be called once during the curses initial setup. Afterwards,
|
||||
curses color pairs can be accessed directly through class attributes.
|
||||
"""
|
||||
|
||||
# Assign the terminal's default (background) color to code -1
|
||||
curses.use_default_colors()
|
||||
|
||||
for index, (attr, code) in enumerate(cls._colors.items(), start=1):
|
||||
curses.init_pair(index, code[0], code[1])
|
||||
setattr(cls, attr, curses.color_pair(index))
|
||||
|
||||
@classmethod
|
||||
def get_level(cls, level):
|
||||
|
||||
levels = [cls.MAGENTA, cls.CYAN, cls.GREEN, cls.YELLOW]
|
||||
return levels[level % len(levels)]
|
||||
|
||||
|
||||
def text_input(window, allow_resize=True):
|
||||
"""
|
||||
Transform a window into a text box that will accept user input and loop
|
||||
until an escape sequence is entered.
|
||||
|
||||
If enter is pressed, return the input text as a string.
|
||||
If escape is pressed, return None.
|
||||
"""
|
||||
|
||||
window.clear()
|
||||
|
||||
# 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)
|
||||
textbox.stripspaces = 0
|
||||
|
||||
def validate(ch):
|
||||
"Filters characters for special key sequences"
|
||||
if ch == ESCAPE:
|
||||
raise EscapeInterrupt
|
||||
if (not allow_resize) and (ch == curses.KEY_RESIZE):
|
||||
raise EscapeInterrupt
|
||||
# Fix backspace for iterm
|
||||
if ch == ascii.DEL:
|
||||
ch = curses.KEY_BACKSPACE
|
||||
return ch
|
||||
|
||||
# Wrapping in an exception block so that we can distinguish when the user
|
||||
# hits the return character from when the user tries to back out of the
|
||||
# input.
|
||||
try:
|
||||
out = textbox.edit(validate=validate)
|
||||
except EscapeInterrupt:
|
||||
out = None
|
||||
|
||||
curses.curs_set(0)
|
||||
return strip_textpad(out)
|
||||
|
||||
|
||||
def prompt_input(window, prompt, hide=False):
|
||||
"""
|
||||
Display a prompt where the user can enter text at the bottom of the screen
|
||||
|
||||
Set hide to True to make the input text invisible.
|
||||
"""
|
||||
|
||||
attr = curses.A_BOLD | Color.CYAN
|
||||
n_rows, n_cols = window.getmaxyx()
|
||||
|
||||
if hide:
|
||||
prompt += ' ' * (n_cols - len(prompt) - 1)
|
||||
window.addstr(n_rows-1, 0, prompt, attr)
|
||||
out = window.getstr(n_rows-1, 1)
|
||||
else:
|
||||
window.addstr(n_rows - 1, 0, prompt, attr)
|
||||
window.refresh()
|
||||
subwin = window.derwin(1, n_cols - len(prompt),
|
||||
n_rows - 1, len(prompt))
|
||||
subwin.attrset(attr)
|
||||
out = text_input(subwin)
|
||||
|
||||
return out
|
||||
|
||||
|
||||
@contextmanager
|
||||
def curses_session():
|
||||
"""
|
||||
Setup terminal and initialize curses.
|
||||
"""
|
||||
|
||||
try:
|
||||
# Curses must wait for some time after the Escape key is pressed to
|
||||
# check if it is the beginning of an escape sequence indicating a
|
||||
# special key. The default wait time is 1 second, which means that
|
||||
# getch() will not return the escape key (27) until a full second
|
||||
# after it has been pressed.
|
||||
# Turn this down to 25 ms, which is close to what VIM uses.
|
||||
# http://stackoverflow.com/questions/27372068
|
||||
os.environ['ESCDELAY'] = '25'
|
||||
|
||||
# Initialize curses
|
||||
stdscr = curses.initscr()
|
||||
|
||||
# Turn off echoing of keys, and enter cbreak mode,
|
||||
# where no buffering is performed on keyboard input
|
||||
curses.noecho()
|
||||
curses.cbreak()
|
||||
|
||||
# In keypad mode, escape sequences for special keys
|
||||
# (like the cursor keys) will be interpreted and
|
||||
# a special value like curses.KEY_LEFT will be returned
|
||||
stdscr.keypad(1)
|
||||
|
||||
# Start color, too. Harmless if the terminal doesn't have
|
||||
# color; user can test with has_color() later on. The try/catch
|
||||
# works around a minor bit of over-conscientiousness in the curses
|
||||
# module -- the error return from C start_color() is ignorable.
|
||||
try:
|
||||
curses.start_color()
|
||||
except:
|
||||
pass
|
||||
|
||||
Color.init()
|
||||
|
||||
# Hide blinking cursor
|
||||
curses.curs_set(0)
|
||||
|
||||
yield stdscr
|
||||
|
||||
finally:
|
||||
|
||||
if stdscr is not None:
|
||||
stdscr.keypad(0)
|
||||
curses.echo()
|
||||
curses.nocbreak()
|
||||
curses.endwin()
|
||||
19
rtv/docs.py
19
rtv/docs.py
@@ -1,5 +1,5 @@
|
||||
__all__ = ['AGENT', 'SUMMARY', 'CONTROLS', 'HELP', 'COMMENT_FILE',
|
||||
'SUBMISSION_FILE', 'COMMENT_EDIT_FILE']
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
AGENT = """\
|
||||
desktop:https://github.com/michael-lazar/rtv:{version}\
|
||||
@@ -49,7 +49,7 @@ Submission Mode
|
||||
`SPACE` : Fold the selected comment, or load additional comments
|
||||
"""
|
||||
|
||||
COMMENT_FILE = u"""
|
||||
COMMENT_FILE = """
|
||||
# Please enter a comment. Lines starting with '#' will be ignored,
|
||||
# and an empty message aborts the comment.
|
||||
#
|
||||
@@ -57,19 +57,26 @@ COMMENT_FILE = u"""
|
||||
{content}
|
||||
"""
|
||||
|
||||
COMMENT_EDIT_FILE = u"""{content}
|
||||
COMMENT_EDIT_FILE = """{content}
|
||||
# Please enter a comment. Lines starting with '#' will be ignored,
|
||||
# and an empty message aborts the comment.
|
||||
#
|
||||
# Editing your comment
|
||||
"""
|
||||
|
||||
SUBMISSION_FILE = u"""{content}
|
||||
SUBMISSION_FILE = """
|
||||
# Please enter your submission. Lines starting with '#' will be ignored,
|
||||
# and an empty field aborts the submission.
|
||||
# and an empty message aborts the submission.
|
||||
#
|
||||
# The first line will be interpreted as the title
|
||||
# The following lines will be interpreted as the content
|
||||
#
|
||||
# Posting to {name}
|
||||
"""
|
||||
|
||||
SUBMISSION_EDIT_FILE = """{content}
|
||||
# Please enter your submission. Lines starting with '#' will be ignored,
|
||||
# and an empty message aborts the submission.
|
||||
#
|
||||
# Editing {name}
|
||||
"""
|
||||
@@ -1,3 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
class EscapeInterrupt(Exception):
|
||||
"Signal that the ESC key has been pressed"
|
||||
|
||||
|
||||
224
rtv/helpers.py
224
rtv/helpers.py
@@ -1,224 +0,0 @@
|
||||
import sys
|
||||
import os
|
||||
import curses
|
||||
import webbrowser
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
from tempfile import NamedTemporaryFile
|
||||
|
||||
# kitchen solves deficiencies in textwrap's handling of unicode characters
|
||||
from kitchen.text.display import wrap, textual_width_chop
|
||||
import six
|
||||
|
||||
from . import config
|
||||
from .exceptions import ProgramError
|
||||
|
||||
__all__ = ['open_browser', 'clean', 'wrap_text', 'strip_textpad',
|
||||
'strip_subreddit_url', 'humanize_timestamp', 'open_editor',
|
||||
'check_browser_display']
|
||||
|
||||
|
||||
def clean(string, n_cols=None):
|
||||
"""
|
||||
Required reading!
|
||||
http://nedbatchelder.com/text/unipain.html
|
||||
|
||||
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 any of the code points are not valid ascii curses will throw a
|
||||
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 curses, it will render correctly.
|
||||
|
||||
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 not be correct. If code points are passed to addnstr, curses will
|
||||
treat each code point as one character and will not account for wide
|
||||
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:
|
||||
return ''
|
||||
|
||||
if not config.unicode:
|
||||
if six.PY3 or isinstance(string, unicode):
|
||||
string = string.encode('ascii', 'replace')
|
||||
return string[:n_cols] if n_cols else string
|
||||
else:
|
||||
if n_cols:
|
||||
string = textual_width_chop(string, n_cols)
|
||||
if six.PY3 or isinstance(string, unicode):
|
||||
string = string.encode('utf-8')
|
||||
return string
|
||||
|
||||
|
||||
def open_editor(data=''):
|
||||
"""
|
||||
Open a temporary file 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.
|
||||
"""
|
||||
|
||||
with NamedTemporaryFile(prefix='rtv-', suffix='.txt', mode='wb') as fp:
|
||||
fp.write(clean(data))
|
||||
fp.flush()
|
||||
editor = os.getenv('RTV_EDITOR') or os.getenv('EDITOR') or 'nano'
|
||||
|
||||
curses.endwin()
|
||||
try:
|
||||
subprocess.Popen([editor, fp.name]).wait()
|
||||
except OSError:
|
||||
raise ProgramError('Could not open file with %s' % editor)
|
||||
curses.doupdate()
|
||||
|
||||
# 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 open(fp.name) as fp2:
|
||||
text = ''.join(line for line in fp2 if not line.startswith('#'))
|
||||
text = text.rstrip()
|
||||
|
||||
return text
|
||||
|
||||
|
||||
def open_browser(url):
|
||||
"""
|
||||
Open the given url using the default webbrowser. The preferred browser can
|
||||
specified with the $BROWSER environment variable. If not specified, python
|
||||
webbrowser will try to determine the default to use based on your system.
|
||||
|
||||
For browsers requiring an X display, we call webbrowser.open_new_tab(url)
|
||||
and redirect stdout/stderr to devnull. This is a workaround to stop firefox
|
||||
from spewing warning messages to the console. See
|
||||
http://bugs.python.org/issue22277 for a better description of the problem.
|
||||
|
||||
For console browsers (e.g. w3m), RTV will suspend and display the browser
|
||||
window within the same terminal. This mode is triggered either when
|
||||
1. $BROWSER is set to a known console browser, or
|
||||
2. $DISPLAY is undefined, indicating that the terminal is running headless
|
||||
|
||||
There may be other cases where console browsers are opened (xdg-open?) but
|
||||
are not detected here.
|
||||
"""
|
||||
|
||||
if check_browser_display():
|
||||
command = "import webbrowser; webbrowser.open_new_tab('%s')" % url
|
||||
args = [sys.executable, '-c', command]
|
||||
with open(os.devnull, 'ab+', 0) as null:
|
||||
subprocess.check_call(args, stdout=null, stderr=null)
|
||||
else:
|
||||
curses.endwin()
|
||||
webbrowser.open_new_tab(url)
|
||||
curses.doupdate()
|
||||
|
||||
|
||||
def check_browser_display():
|
||||
"""
|
||||
Use a number of methods to guess if the default webbrowser will open in
|
||||
the background as opposed to opening directly in the terminal.
|
||||
"""
|
||||
|
||||
display = bool(os.environ.get("DISPLAY"))
|
||||
|
||||
# Use the convention defined here to parse $BROWSER
|
||||
# https://docs.python.org/2/library/webbrowser.html
|
||||
console_browsers = ['www-browser', 'links', 'links2', 'elinks', 'lynx',
|
||||
'w3m']
|
||||
if "BROWSER" in os.environ:
|
||||
user_browser = os.environ["BROWSER"].split(os.pathsep)[0]
|
||||
if user_browser in console_browsers:
|
||||
display = False
|
||||
|
||||
if webbrowser._tryorder and webbrowser._tryorder[0] in console_browsers:
|
||||
display = False
|
||||
|
||||
return display
|
||||
|
||||
|
||||
def wrap_text(text, width):
|
||||
"""
|
||||
Wrap text paragraphs to the given character width while preserving
|
||||
newlines.
|
||||
"""
|
||||
out = []
|
||||
for paragraph in text.splitlines():
|
||||
# Wrap returns an empty list when paragraph is a newline. In order to
|
||||
# preserve newlines we substitute a list containing an empty string.
|
||||
lines = wrap(paragraph, width=width) or ['']
|
||||
out.extend(lines)
|
||||
return out
|
||||
|
||||
|
||||
def strip_textpad(text):
|
||||
"""
|
||||
Attempt to intelligently strip excess whitespace from the output of a
|
||||
curses textpad.
|
||||
"""
|
||||
|
||||
if text is None:
|
||||
return text
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
def strip_subreddit_url(permalink):
|
||||
"""
|
||||
Strip a subreddit name from the subreddit's permalink.
|
||||
|
||||
This is used to avoid submission.subreddit.url making a separate API call.
|
||||
"""
|
||||
|
||||
subreddit = permalink.split('/')[4]
|
||||
return '/r/{}'.format(subreddit)
|
||||
|
||||
|
||||
def humanize_timestamp(utc_timestamp, verbose=False):
|
||||
"""
|
||||
Convert a utc timestamp into a human readable relative-time.
|
||||
"""
|
||||
|
||||
timedelta = datetime.utcnow() - datetime.utcfromtimestamp(utc_timestamp)
|
||||
|
||||
seconds = int(timedelta.total_seconds())
|
||||
if seconds < 60:
|
||||
return 'moments ago' if verbose else '0min'
|
||||
minutes = seconds // 60
|
||||
if minutes < 60:
|
||||
return ('%d minutes ago' % minutes) if verbose else ('%dmin' % minutes)
|
||||
hours = minutes // 60
|
||||
if hours < 24:
|
||||
return ('%d hours ago' % hours) if verbose else ('%dhr' % hours)
|
||||
days = hours // 24
|
||||
if days < 30:
|
||||
return ('%d days ago' % days) if verbose else ('%dday' % days)
|
||||
months = days // 30.4
|
||||
if months < 12:
|
||||
return ('%d months ago' % months) if verbose else ('%dmonth' % months)
|
||||
years = months // 12
|
||||
return ('%d years ago' % years) if verbose else ('%dyr' % years)
|
||||
@@ -1,70 +0,0 @@
|
||||
import os
|
||||
|
||||
|
||||
__all__ = ['load_history', 'save_history']
|
||||
|
||||
|
||||
def history_path():
|
||||
"""
|
||||
Create the path to the history log
|
||||
"""
|
||||
HOME = os.path.expanduser('~')
|
||||
XDG_CONFIG_HOME = os.getenv('XDG_CACHE_HOME',
|
||||
os.path.join(HOME, '.config'))
|
||||
path = os.path.join(XDG_CONFIG_HOME, 'rtv')
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
return os.path.join(path, 'history.log')
|
||||
|
||||
|
||||
def load_history():
|
||||
"""
|
||||
Load the history file into memory if it exists
|
||||
"""
|
||||
path = history_path()
|
||||
if os.path.exists(path):
|
||||
with open(path) as history_file:
|
||||
# reverse the list so the newest ones are first
|
||||
history = [line.strip() for line in history_file][::-1]
|
||||
return OrderedSet(history)
|
||||
return OrderedSet()
|
||||
|
||||
|
||||
def save_history(history):
|
||||
"""
|
||||
Save the visited links to the history log
|
||||
"""
|
||||
path = history_path()
|
||||
with open(path, 'w+') as history_file:
|
||||
for i in range(200):
|
||||
if not history:
|
||||
break
|
||||
try:
|
||||
history_file.write(history.pop() + '\n')
|
||||
except UnicodeEncodeError:
|
||||
# Ignore unicode URLS, may want to handle this at some point
|
||||
continue
|
||||
|
||||
|
||||
class OrderedSet(object):
|
||||
"""
|
||||
A simple implementation of an ordered set. A set is used to check
|
||||
for membership, and a list is used to maintain ordering.
|
||||
"""
|
||||
|
||||
def __init__(self, elements=[]):
|
||||
self._set = set(elements)
|
||||
self._list = elements
|
||||
|
||||
def __contains__(self, item):
|
||||
return item in self._set
|
||||
|
||||
def __len__(self):
|
||||
return len(self._list)
|
||||
|
||||
def add(self, item):
|
||||
self._set.add(item)
|
||||
self._list.append(item)
|
||||
|
||||
def pop(self):
|
||||
return self._list.pop()
|
||||
170
rtv/oauth.py
170
rtv/oauth.py
@@ -1,127 +1,143 @@
|
||||
import os
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import time
|
||||
import uuid
|
||||
|
||||
import praw
|
||||
from tornado import gen, ioloop, web, httpserver
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
from . import config
|
||||
from .curses_helpers import show_notification
|
||||
from .helpers import check_browser_display, open_browser
|
||||
|
||||
__all__ = ['OAuthTool']
|
||||
class OAuthHandler(web.RequestHandler):
|
||||
"""
|
||||
Intercepts the redirect that Reddit sends the user to after they verify or
|
||||
deny the application access.
|
||||
|
||||
oauth_state = None
|
||||
oauth_code = None
|
||||
oauth_error = None
|
||||
The GET should supply 3 request params:
|
||||
state: Unique id that was supplied by us at the beginning of the
|
||||
process to verify that the session matches.
|
||||
code: Code that we can use to generate the refresh token.
|
||||
error: If an error occurred, it will be placed here.
|
||||
"""
|
||||
|
||||
template_path = os.path.join(os.path.dirname(__file__), 'templates')
|
||||
|
||||
|
||||
class AuthHandler(web.RequestHandler):
|
||||
def initialize(self, display=None, params=None):
|
||||
self.display = display
|
||||
self.params = params
|
||||
|
||||
def get(self):
|
||||
global oauth_state, oauth_code, oauth_error
|
||||
self.params['state'] = self.get_argument('state', default=None)
|
||||
self.params['code'] = self.get_argument('code', default=None)
|
||||
self.params['error'] = self.get_argument('error', default=None)
|
||||
|
||||
oauth_state = self.get_argument('state', default='placeholder')
|
||||
oauth_code = self.get_argument('code', default='placeholder')
|
||||
oauth_error = self.get_argument('error', default='placeholder')
|
||||
self.render('index.html', **self.params)
|
||||
|
||||
self.render('index.html', state=oauth_state, code=oauth_code,
|
||||
error=oauth_error)
|
||||
|
||||
# Stop IOLoop if using a background browser such as firefox
|
||||
if check_browser_display():
|
||||
ioloop.IOLoop.current().stop()
|
||||
complete = self.params['state'] and self.params['code']
|
||||
if complete or self.params['error']:
|
||||
# Stop IOLoop if using a background browser such as firefox
|
||||
if self.display:
|
||||
ioloop.IOLoop.current().stop()
|
||||
|
||||
|
||||
class OAuthTool(object):
|
||||
class OAuthHelper(object):
|
||||
|
||||
def __init__(self, reddit, stdscr=None, loader=None):
|
||||
def __init__(self, reddit, term, config):
|
||||
|
||||
self.term = term
|
||||
self.reddit = reddit
|
||||
self.stdscr = stdscr
|
||||
self.loader = loader
|
||||
self.http_server = None
|
||||
self.config = config
|
||||
|
||||
self.refresh_token = config.load_refresh_token()
|
||||
self.http_server = None
|
||||
self.params = {'state': None, 'code': None, 'error': None}
|
||||
|
||||
# Initialize Tornado webapp
|
||||
routes = [('/', AuthHandler)]
|
||||
self.callback_app = web.Application(routes,
|
||||
template_path=template_path)
|
||||
# Pass a mutable params object so the request handler can modify it
|
||||
kwargs = {'display': self.term.display, 'params': self.params}
|
||||
routes = [('/', OAuthHandler, kwargs)]
|
||||
self.callback_app = web.Application(
|
||||
routes, template_path=self.config['template_path'])
|
||||
|
||||
self.reddit.set_oauth_app_info(config.oauth_client_id,
|
||||
config.oauth_client_secret,
|
||||
config.oauth_redirect_uri)
|
||||
self.reddit.set_oauth_app_info(
|
||||
self.config['oauth_client_id'],
|
||||
self.config['oauth_client_secret'],
|
||||
self.config['oauth_redirect_uri'])
|
||||
|
||||
# Reddit's mobile website works better on terminal browsers
|
||||
if not check_browser_display():
|
||||
if not self.term.display:
|
||||
if '.compact' not in self.reddit.config.API_PATHS['authorize']:
|
||||
self.reddit.config.API_PATHS['authorize'] += '.compact'
|
||||
|
||||
def authorize(self):
|
||||
|
||||
self.params.update(state=None, code=None, error=None)
|
||||
|
||||
# If we already have a token, request new access credentials
|
||||
if self.refresh_token:
|
||||
with self.loader(message='Logging in'):
|
||||
self.reddit.refresh_access_information(self.refresh_token)
|
||||
return
|
||||
if self.config.refresh_token:
|
||||
with self.term.loader(message='Logging in'):
|
||||
self.reddit.refresh_access_information(
|
||||
self.config.refresh_token)
|
||||
return
|
||||
|
||||
# https://github.com/tornadoweb/tornado/issues/1420
|
||||
io = ioloop.IOLoop.current()
|
||||
|
||||
# Start the authorization callback server
|
||||
if self.http_server is None:
|
||||
self.http_server = httpserver.HTTPServer(self.callback_app)
|
||||
self.http_server.listen(config.oauth_redirect_port)
|
||||
self.http_server.listen(self.config['oauth_redirect_port'])
|
||||
|
||||
hex_uuid = uuid.uuid4().hex
|
||||
state = uuid.uuid4().hex
|
||||
authorize_url = self.reddit.get_authorize_url(
|
||||
hex_uuid, scope=config.oauth_scope, refreshable=True)
|
||||
state, scope=self.config['oauth_scope'], refreshable=True)
|
||||
|
||||
# Open the browser and wait for the user to authorize the app
|
||||
if check_browser_display():
|
||||
with self.loader(message='Waiting for authorization'):
|
||||
open_browser(authorize_url)
|
||||
ioloop.IOLoop.current().start()
|
||||
if self.term.display:
|
||||
# Open a background browser (e.g. firefox) which is non-blocking.
|
||||
# Stop the iloop when the user hits the auth callback, at which
|
||||
# point we continue and check the callback params.
|
||||
with self.term.loader(message='Opening browser for authorization'):
|
||||
self.term.open_browser(authorize_url)
|
||||
io.start()
|
||||
if self.term.loader.exception:
|
||||
io.clear_instance()
|
||||
return
|
||||
else:
|
||||
with self.loader(delay=0, message='Redirecting to reddit'):
|
||||
# Provide user feedback
|
||||
# Open the terminal webbrowser in a background thread and wait
|
||||
# while for the user to close the process. Once the process is
|
||||
# closed, the iloop is stopped and we can check if the user has
|
||||
# hit the callback URL.
|
||||
with self.term.loader(delay=0, message='Redirecting to reddit'):
|
||||
# This load message exists to provide user feedback
|
||||
time.sleep(1)
|
||||
ioloop.IOLoop.current().add_callback(self._open_authorize_url,
|
||||
authorize_url)
|
||||
ioloop.IOLoop.current().start()
|
||||
io.add_callback(self._async_open_browser, authorize_url)
|
||||
io.start()
|
||||
|
||||
if oauth_error == 'access_denied':
|
||||
show_notification(self.stdscr, ['Declined access'])
|
||||
if self.params['error'] == 'access_denied':
|
||||
self.term.show_notification('Declined access')
|
||||
return
|
||||
elif oauth_error != 'placeholder':
|
||||
show_notification(self.stdscr, ['Authentication error'])
|
||||
elif self.params['error']:
|
||||
self.term.show_notification('Authentication error')
|
||||
return
|
||||
elif hex_uuid != oauth_state:
|
||||
# Check if UUID matches obtained state.
|
||||
# If not, authorization process is compromised.
|
||||
show_notification(self.stdscr, ['UUID mismatch'])
|
||||
elif self.params['state'] != state:
|
||||
self.term.show_notification('UUID mismatch')
|
||||
return
|
||||
|
||||
try:
|
||||
with self.loader(message='Logging in'):
|
||||
access_info = self.reddit.get_access_information(oauth_code)
|
||||
self.refresh_token = access_info['refresh_token']
|
||||
if config.persistent:
|
||||
config.save_refresh_token(access_info['refresh_token'])
|
||||
except (praw.errors.OAuthAppRequired, praw.errors.OAuthInvalidToken):
|
||||
show_notification(self.stdscr, ['Invalid OAuth data'])
|
||||
else:
|
||||
message = ['Welcome {}!'.format(self.reddit.user.name)]
|
||||
show_notification(self.stdscr, message)
|
||||
with self.term.loader(message='Logging in'):
|
||||
info = self.reddit.get_access_information(self.params['code'])
|
||||
if self.term.loader.exception:
|
||||
return
|
||||
|
||||
message = 'Welcome {}!'.format(self.reddit.user.name)
|
||||
self.term.show_notification(message)
|
||||
|
||||
self.config.refresh_token = info['refresh_token']
|
||||
if self.config['persistent']:
|
||||
self.config.save_refresh_token()
|
||||
|
||||
def clear_oauth_data(self):
|
||||
self.reddit.clear_authentication()
|
||||
config.clear_refresh_token()
|
||||
self.refresh_token = None
|
||||
self.config.delete_refresh_token()
|
||||
|
||||
@gen.coroutine
|
||||
def _open_authorize_url(self, url):
|
||||
def _async_open_browser(self, url):
|
||||
with ThreadPoolExecutor(max_workers=1) as executor:
|
||||
yield executor.submit(open_browser, url)
|
||||
ioloop.IOLoop.current().stop()
|
||||
yield executor.submit(self.term.open_browser, url)
|
||||
ioloop.IOLoop.current().stop()
|
||||
554
rtv/objects.py
Normal file
554
rtv/objects.py
Normal file
@@ -0,0 +1,554 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
import time
|
||||
import curses
|
||||
import signal
|
||||
import inspect
|
||||
import weakref
|
||||
import logging
|
||||
import threading
|
||||
from contextlib import contextmanager
|
||||
|
||||
import six
|
||||
import praw
|
||||
import requests
|
||||
|
||||
from . import exceptions
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@contextmanager
|
||||
def curses_session():
|
||||
"""
|
||||
Setup terminal and initialize curses. Most of this copied from
|
||||
curses.wrapper in order to convert the wrapper into a context manager.
|
||||
"""
|
||||
|
||||
try:
|
||||
# Curses must wait for some time after the Escape key is pressed to
|
||||
# check if it is the beginning of an escape sequence indicating a
|
||||
# special key. The default wait time is 1 second, which means that
|
||||
# http://stackoverflow.com/questions/27372068
|
||||
os.environ['ESCDELAY'] = '25'
|
||||
|
||||
# Initialize curses
|
||||
stdscr = curses.initscr()
|
||||
|
||||
# Turn off echoing of keys, and enter cbreak mode, where no buffering
|
||||
# is performed on keyboard input
|
||||
curses.noecho()
|
||||
curses.cbreak()
|
||||
|
||||
# In keypad mode, escape sequences for special keys (like the cursor
|
||||
# keys) will be interpreted and a special value like curses.KEY_LEFT
|
||||
# will be returned
|
||||
stdscr.keypad(1)
|
||||
|
||||
# Start color, too. Harmless if the terminal doesn't have color; user
|
||||
# can test with has_color() later on. The try/catch works around a
|
||||
# minor bit of over-conscientiousness in the curses module -- the error
|
||||
# return from C start_color() is ignorable.
|
||||
try:
|
||||
curses.start_color()
|
||||
except:
|
||||
pass
|
||||
|
||||
# Hide the blinking cursor
|
||||
curses.curs_set(0)
|
||||
|
||||
Color.init()
|
||||
|
||||
yield stdscr
|
||||
|
||||
finally:
|
||||
if 'stdscr' in locals():
|
||||
stdscr.keypad(0)
|
||||
curses.echo()
|
||||
curses.nocbreak()
|
||||
curses.endwin()
|
||||
|
||||
|
||||
class LoadScreen(object):
|
||||
"""
|
||||
Display a loading dialog while waiting for a blocking action to complete.
|
||||
|
||||
This class spins off a separate thread to animate the loading screen in the
|
||||
background. The loading thread also takes control of stdscr.getch(). If
|
||||
an exception occurs in the main thread while the loader is active, the
|
||||
exception will be caught, attached to the loader object, and displayed as
|
||||
a notification. The attached exception can be used to trigger context
|
||||
sensitive actions. For example, if the connection hangs while opening a
|
||||
submission, the user may press ctrl-c to raise a KeyboardInterrupt. In this
|
||||
case we would *not* want to refresh the current page.
|
||||
|
||||
>>> with self.terminal.loader(...) as loader:
|
||||
>>> # Perform a blocking request to load content
|
||||
>>> blocking_request(...)
|
||||
>>>
|
||||
>>> if loader.exception is None:
|
||||
>>> # Only run this if the load was successful
|
||||
>>> self.refresh_content()
|
||||
|
||||
When a loader is nested inside of itself, the outermost loader takes
|
||||
priority and all of the nested loaders become no-ops. Call arguments given
|
||||
to nested loaders will be ignored, and errors will propagate to the parent.
|
||||
|
||||
>>> with self.terminal.loader(...) as loader:
|
||||
>>>
|
||||
>>> # Additional loaders will be ignored
|
||||
>>> with self.terminal.loader(...):
|
||||
>>> raise KeyboardInterrupt()
|
||||
>>>
|
||||
>>> # This code will not be executed because the inner loader doesn't
|
||||
>>> # catch the exception
|
||||
>>> assert False
|
||||
>>>
|
||||
>>> # The exception is finally caught by the outer loader
|
||||
>>> assert isinstance(terminal.loader.exception, KeyboardInterrupt)
|
||||
"""
|
||||
|
||||
HANDLED_EXCEPTIONS = [
|
||||
(exceptions.SubscriptionError, 'No Subscriptions'),
|
||||
(exceptions.AccountError, 'Unable to Access Account'),
|
||||
(exceptions.SubredditError, 'Invalid Subreddit'),
|
||||
(praw.errors.InvalidSubreddit, 'Invalid Subreddit'),
|
||||
(praw.errors.InvalidComment, 'Invalid Comment'),
|
||||
(praw.errors.InvalidSubmission, 'Invalid Submission'),
|
||||
(praw.errors.OAuthAppRequired, 'Invalid OAuth data'),
|
||||
(praw.errors.OAuthException, 'Invalid OAuth data'),
|
||||
(praw.errors.LoginOrScopeRequired, 'Not Logged In'),
|
||||
(praw.errors.ClientException, 'Reddit Client Error'),
|
||||
(praw.errors.NotFound, 'Not Found'),
|
||||
(praw.errors.APIException, 'Reddit API Error'),
|
||||
(praw.errors.HTTPException, 'Reddit HTTP Error'),
|
||||
(requests.HTTPError, 'Unexpected HTTP Error'),
|
||||
(requests.ConnectionError, 'Connection Error'),
|
||||
(KeyboardInterrupt, None),
|
||||
]
|
||||
|
||||
def __init__(self, terminal):
|
||||
|
||||
self.exception = None
|
||||
self.catch_exception = None
|
||||
self.depth = 0
|
||||
self._terminal = weakref.proxy(terminal)
|
||||
self._args = None
|
||||
self._animator = None
|
||||
self._is_running = None
|
||||
|
||||
def __call__(self, delay=0.5, interval=0.4, message='Downloading',
|
||||
trail='...', catch_exception=True):
|
||||
"""
|
||||
Params:
|
||||
delay (float): Length of time that the loader will wait before
|
||||
printing on the screen. Used to prevent flicker on pages that
|
||||
load very fast.
|
||||
interval (float): Length of time between each animation frame.
|
||||
message (str): Message to display
|
||||
trail (str): Trail of characters that will be animated by the
|
||||
loading screen.
|
||||
catch_exception (bool): If an exception occurs while the loader is
|
||||
active, this flag determines whether it is caught or allowed to
|
||||
bubble up.
|
||||
"""
|
||||
|
||||
if self.depth > 0:
|
||||
return self
|
||||
|
||||
self.exception = None
|
||||
self.catch_exception = catch_exception
|
||||
self._args = (delay, interval, message, trail)
|
||||
return self
|
||||
|
||||
def __enter__(self):
|
||||
|
||||
self.depth += 1
|
||||
if self.depth > 1:
|
||||
return self
|
||||
|
||||
self._animator = threading.Thread(target=self.animate, args=self._args)
|
||||
self._animator.daemon = True
|
||||
self._is_running = True
|
||||
self._animator.start()
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, e, exc_tb):
|
||||
|
||||
self.depth -= 1
|
||||
if self.depth > 0:
|
||||
return
|
||||
|
||||
self._is_running = False
|
||||
self._animator.join()
|
||||
self._terminal.stdscr.refresh()
|
||||
|
||||
if self.catch_exception and e is not None:
|
||||
# Log the exception and attach it so the caller can inspect it
|
||||
self.exception = e
|
||||
_logger.info('Loader caught: {0} - {1}'.format(type(e).__name__, e))
|
||||
# If an error occurred, display a notification on the screen
|
||||
for base, message in self.HANDLED_EXCEPTIONS:
|
||||
if isinstance(e, base):
|
||||
if message:
|
||||
self._terminal.show_notification(message)
|
||||
break
|
||||
else:
|
||||
return # Re-raise unhandled exceptions
|
||||
return True # Otherwise swallow the exception and continue
|
||||
|
||||
def animate(self, delay, interval, message, trail):
|
||||
|
||||
# The animation starts with a configurable delay before drawing on the
|
||||
# screen. This is to prevent very short loading sections from
|
||||
# flickering on the screen before immediately disappearing.
|
||||
with self._terminal.no_delay():
|
||||
start = time.time()
|
||||
while (time.time() - start) < delay:
|
||||
# Pressing escape triggers a keyboard interrupt
|
||||
if self._terminal.getch() == self._terminal.ESCAPE:
|
||||
os.kill(os.getpid(), signal.SIGINT)
|
||||
self._is_running = False
|
||||
|
||||
if not self._is_running:
|
||||
return
|
||||
time.sleep(0.01)
|
||||
|
||||
# Build the notification window
|
||||
message_len = len(message) + len(trail)
|
||||
n_rows, n_cols = self._terminal.stdscr.getmaxyx()
|
||||
s_row = (n_rows - 3) // 2
|
||||
s_col = (n_cols - message_len - 1) // 2
|
||||
window = curses.newwin(3, message_len + 2, s_row, s_col)
|
||||
|
||||
# Animate the loading prompt until the stopping condition is triggered
|
||||
# when the context manager exits.
|
||||
with self._terminal.no_delay():
|
||||
while True:
|
||||
for i in range(len(trail) + 1):
|
||||
if not self._is_running:
|
||||
window.erase()
|
||||
del window
|
||||
self._terminal.stdscr.touchwin()
|
||||
self._terminal.stdscr.refresh()
|
||||
return
|
||||
|
||||
window.erase()
|
||||
window.border()
|
||||
self._terminal.add_line(window, message + trail[:i], 1, 1)
|
||||
window.refresh()
|
||||
|
||||
# Break up the designated sleep interval into smaller
|
||||
# chunks so we can more responsively check for interrupts.
|
||||
for _ in range(int(interval/0.01)):
|
||||
# Pressing escape triggers a keyboard interrupt
|
||||
if self._terminal.getch() == self._terminal.ESCAPE:
|
||||
os.kill(os.getpid(), signal.SIGINT)
|
||||
self._is_running = False
|
||||
break
|
||||
time.sleep(0.01)
|
||||
|
||||
|
||||
class Color(object):
|
||||
|
||||
"""
|
||||
Color attributes for curses.
|
||||
"""
|
||||
|
||||
RED = curses.A_NORMAL
|
||||
GREEN = curses.A_NORMAL
|
||||
YELLOW = curses.A_NORMAL
|
||||
BLUE = curses.A_NORMAL
|
||||
MAGENTA = curses.A_NORMAL
|
||||
CYAN = curses.A_NORMAL
|
||||
WHITE = curses.A_NORMAL
|
||||
|
||||
_colors = {
|
||||
'RED': (curses.COLOR_RED, -1),
|
||||
'GREEN': (curses.COLOR_GREEN, -1),
|
||||
'YELLOW': (curses.COLOR_YELLOW, -1),
|
||||
'BLUE': (curses.COLOR_BLUE, -1),
|
||||
'MAGENTA': (curses.COLOR_MAGENTA, -1),
|
||||
'CYAN': (curses.COLOR_CYAN, -1),
|
||||
'WHITE': (curses.COLOR_WHITE, -1),
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def init(cls):
|
||||
"""
|
||||
Initialize color pairs inside of curses using the default background.
|
||||
|
||||
This should be called once during the curses initial setup. Afterwards,
|
||||
curses color pairs can be accessed directly through class attributes.
|
||||
"""
|
||||
|
||||
# Assign the terminal's default (background) color to code -1
|
||||
curses.use_default_colors()
|
||||
|
||||
for index, (attr, code) in enumerate(cls._colors.items(), start=1):
|
||||
curses.init_pair(index, code[0], code[1])
|
||||
setattr(cls, attr, curses.color_pair(index))
|
||||
|
||||
@classmethod
|
||||
def get_level(cls, level):
|
||||
|
||||
levels = [cls.MAGENTA, cls.CYAN, cls.GREEN, cls.YELLOW]
|
||||
return levels[level % len(levels)]
|
||||
|
||||
|
||||
class Navigator(object):
|
||||
"""
|
||||
Handles the math behind cursor movement and screen paging.
|
||||
|
||||
This class determines how cursor movements effect the currently displayed
|
||||
page. For example, if scrolling down the page, items are drawn from the
|
||||
bottom up. This ensures that the item at the very bottom of the screen
|
||||
(the one selected by cursor) will be fully drawn and not cut off. Likewise,
|
||||
when scrolling up the page, items are drawn from the top down. If the
|
||||
cursor is moved around without hitting the top or bottom of the screen, the
|
||||
current mode is preserved.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
valid_page_cb,
|
||||
page_index=0,
|
||||
cursor_index=0,
|
||||
inverted=False):
|
||||
"""
|
||||
Params:
|
||||
valid_page_callback (func): This function, usually `Content.get`,
|
||||
takes a page index and raises an IndexError if that index falls
|
||||
out of bounds. This is used to determine the upper and lower
|
||||
bounds of the page, i.e. when to stop scrolling.
|
||||
page_index (int): Initial page index.
|
||||
cursor_index (int): Initial cursor index, relative to the page.
|
||||
inverted (bool): Whether the page scrolling is reversed of not.
|
||||
normal - The page is drawn from the top of the screen,
|
||||
starting with the page index, down to the bottom of
|
||||
the screen.
|
||||
inverted - The page is drawn from the bottom of the screen,
|
||||
starting with the page index, up to the top of the
|
||||
screen.
|
||||
"""
|
||||
|
||||
self.page_index = page_index
|
||||
self.cursor_index = cursor_index
|
||||
self.inverted = inverted
|
||||
self._page_cb = valid_page_cb
|
||||
|
||||
@property
|
||||
def step(self):
|
||||
return 1 if not self.inverted else -1
|
||||
|
||||
@property
|
||||
def position(self):
|
||||
return self.page_index, self.cursor_index, self.inverted
|
||||
|
||||
@property
|
||||
def absolute_index(self):
|
||||
"""
|
||||
Return the index of the currently selected item.
|
||||
"""
|
||||
|
||||
return self.page_index + (self.step * self.cursor_index)
|
||||
|
||||
def move(self, direction, n_windows):
|
||||
"""
|
||||
Move the cursor up or down by the given increment.
|
||||
|
||||
Params:
|
||||
direction (int): `1` will move the cursor down one item and `-1`
|
||||
will move the cursor up one item.
|
||||
n_windows (int): The number of items that are currently being drawn
|
||||
on the screen.
|
||||
|
||||
Returns:
|
||||
valid (bool): Indicates whether or not the attempted cursor move is
|
||||
allowed. E.g. When the cursor is on the last comment,
|
||||
attempting to scroll down any further would not be valid.
|
||||
redraw (bool): Indicates whether or not the screen needs to be
|
||||
redrawn.
|
||||
"""
|
||||
|
||||
assert direction in (-1, 1)
|
||||
|
||||
valid, redraw = True, False
|
||||
forward = ((direction * self.step) > 0)
|
||||
|
||||
if forward:
|
||||
if self.page_index < 0:
|
||||
if self._is_valid(0):
|
||||
# Special case - advance the page index if less than zero
|
||||
self.page_index = 0
|
||||
self.cursor_index = 0
|
||||
redraw = True
|
||||
else:
|
||||
valid = False
|
||||
else:
|
||||
self.cursor_index += 1
|
||||
if not self._is_valid(self.absolute_index):
|
||||
# Move would take us out of bounds
|
||||
self.cursor_index -= 1
|
||||
valid = False
|
||||
elif self.cursor_index >= (n_windows - 1):
|
||||
# Flip the orientation and reset the cursor
|
||||
self.flip(self.cursor_index)
|
||||
self.cursor_index = 0
|
||||
redraw = True
|
||||
else:
|
||||
if self.cursor_index > 0:
|
||||
self.cursor_index -= 1
|
||||
else:
|
||||
self.page_index -= self.step
|
||||
if self._is_valid(self.absolute_index):
|
||||
# We have reached the beginning of the page - move the
|
||||
# index
|
||||
redraw = True
|
||||
else:
|
||||
self.page_index += self.step
|
||||
valid = False # Revert
|
||||
|
||||
return valid, redraw
|
||||
|
||||
def move_page(self, direction, n_windows):
|
||||
"""
|
||||
Move the page down (positive direction) or up (negative direction).
|
||||
|
||||
Paging down:
|
||||
The post on the bottom of the page becomes the post at the top of
|
||||
the page and the cursor is moved to the top.
|
||||
Paging up:
|
||||
The post at the top of the page becomes the post at the bottom of
|
||||
the page and the cursor is moved to the bottom.
|
||||
"""
|
||||
|
||||
assert direction in (-1, 1)
|
||||
assert n_windows >= 0
|
||||
|
||||
# top of subreddit/submission page or only one
|
||||
# submission/reply on the screen: act as normal move
|
||||
if (self.absolute_index < 0) | (n_windows == 0):
|
||||
valid, redraw = self.move(direction, n_windows)
|
||||
else:
|
||||
# first page
|
||||
if self.absolute_index < n_windows and direction < 0:
|
||||
self.page_index = -1
|
||||
self.cursor_index = 0
|
||||
self.inverted = False
|
||||
|
||||
# not submission mode: starting index is 0
|
||||
if not self._is_valid(self.absolute_index):
|
||||
self.page_index = 0
|
||||
valid = True
|
||||
else:
|
||||
# flip to the direction of movement
|
||||
if ((direction > 0) & (self.inverted is True))\
|
||||
| ((direction < 0) & (self.inverted is False)):
|
||||
self.page_index += (self.step * (n_windows-1))
|
||||
self.inverted = not self.inverted
|
||||
self.cursor_index \
|
||||
= (n_windows-(direction < 0)) - self.cursor_index
|
||||
|
||||
valid = False
|
||||
adj = 0
|
||||
# check if reached the bottom
|
||||
while not valid:
|
||||
n_move = n_windows - adj
|
||||
if n_move == 0:
|
||||
break
|
||||
|
||||
self.page_index += n_move * direction
|
||||
valid = self._is_valid(self.absolute_index)
|
||||
if not valid:
|
||||
self.page_index -= n_move * direction
|
||||
adj += 1
|
||||
|
||||
redraw = True
|
||||
|
||||
return valid, redraw
|
||||
|
||||
def flip(self, n_windows):
|
||||
"""
|
||||
Flip the orientation of the page.
|
||||
"""
|
||||
|
||||
assert n_windows >= 0
|
||||
self.page_index += (self.step * n_windows)
|
||||
self.cursor_index = n_windows
|
||||
self.inverted = not self.inverted
|
||||
|
||||
def _is_valid(self, page_index):
|
||||
"""
|
||||
Check if a page index will cause entries to fall outside valid range.
|
||||
"""
|
||||
|
||||
try:
|
||||
self._page_cb(page_index)
|
||||
except IndexError:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
class Controller(object):
|
||||
"""
|
||||
Event handler for triggering functions with curses keypresses.
|
||||
|
||||
Register a keystroke to a class method using the @register decorator.
|
||||
>>> @Controller.register('a', 'A')
|
||||
>>> def func(self, *args)
|
||||
>>> ...
|
||||
|
||||
Register a default behavior by using `None`.
|
||||
>>> @Controller.register(None)
|
||||
>>> def default_func(self, *args)
|
||||
>>> ...
|
||||
|
||||
Bind the controller to a class instance and trigger a key. Additional
|
||||
arguments will be passed to the function.
|
||||
>>> controller = Controller(self)
|
||||
>>> controller.trigger('a', *args)
|
||||
"""
|
||||
|
||||
character_map = {}
|
||||
|
||||
def __init__(self, instance):
|
||||
|
||||
self.instance = instance
|
||||
# Build a list of parent controllers that follow the object's MRO to
|
||||
# check if any parent controllers have registered the keypress
|
||||
self.parents = inspect.getmro(type(self))[:-1]
|
||||
|
||||
def trigger(self, char, *args, **kwargs):
|
||||
|
||||
if isinstance(char, six.string_types) and len(char) == 1:
|
||||
char = ord(char)
|
||||
|
||||
func = None
|
||||
# Check if the controller (or any of the controller's parents) have
|
||||
# registered a function to the given key
|
||||
for controller in self.parents:
|
||||
if func:
|
||||
break
|
||||
func = controller.character_map.get(char)
|
||||
# If the controller has not registered the key, check if there is a
|
||||
# default function registered
|
||||
for controller in self.parents:
|
||||
if func:
|
||||
break
|
||||
func = controller.character_map.get(None)
|
||||
return func(self.instance, *args, **kwargs) if func else None
|
||||
|
||||
@classmethod
|
||||
def register(cls, *chars):
|
||||
def inner(f):
|
||||
for char in chars:
|
||||
if isinstance(char, six.string_types) and len(char) == 1:
|
||||
cls.character_map[ord(char)] = f
|
||||
else:
|
||||
cls.character_map[char] = f
|
||||
return f
|
||||
return inner
|
||||
516
rtv/page.py
516
rtv/page.py
@@ -1,257 +1,47 @@
|
||||
import curses
|
||||
import time
|
||||
import six
|
||||
import sys
|
||||
import logging
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import sys
|
||||
import time
|
||||
import curses
|
||||
from functools import wraps
|
||||
|
||||
import praw.errors
|
||||
import requests
|
||||
from kitchen.text.display import textual_width
|
||||
|
||||
from .helpers import open_editor
|
||||
from .curses_helpers import (Color, show_notification, show_help, prompt_input,
|
||||
add_line)
|
||||
from .docs import COMMENT_EDIT_FILE, SUBMISSION_FILE
|
||||
|
||||
__all__ = ['Navigator', 'BaseController', 'BasePage']
|
||||
_logger = logging.getLogger(__name__)
|
||||
from . import docs
|
||||
from .objects import Controller, Color
|
||||
|
||||
|
||||
class Navigator(object):
|
||||
def logged_in(f):
|
||||
"""
|
||||
Handles math behind cursor movement and screen paging.
|
||||
Decorator for Page methods that require the user to be authenticated.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
valid_page_cb,
|
||||
page_index=0,
|
||||
cursor_index=0,
|
||||
inverted=False):
|
||||
|
||||
self.page_index = page_index
|
||||
self.cursor_index = cursor_index
|
||||
self.inverted = inverted
|
||||
self._page_cb = valid_page_cb
|
||||
self._header_window = None
|
||||
self._content_window = None
|
||||
|
||||
@property
|
||||
def step(self):
|
||||
return 1 if not self.inverted else -1
|
||||
|
||||
@property
|
||||
def position(self):
|
||||
return (self.page_index, self.cursor_index, self.inverted)
|
||||
|
||||
@property
|
||||
def absolute_index(self):
|
||||
return self.page_index + (self.step * self.cursor_index)
|
||||
|
||||
def move(self, direction, n_windows):
|
||||
"Move the cursor down (positive direction) or up (negative direction)"
|
||||
|
||||
valid, redraw = True, False
|
||||
|
||||
forward = ((direction * self.step) > 0)
|
||||
|
||||
if forward:
|
||||
if self.page_index < 0:
|
||||
if self._is_valid(0):
|
||||
# Special case - advance the page index if less than zero
|
||||
self.page_index = 0
|
||||
self.cursor_index = 0
|
||||
redraw = True
|
||||
else:
|
||||
valid = False
|
||||
else:
|
||||
self.cursor_index += 1
|
||||
if not self._is_valid(self.absolute_index):
|
||||
# Move would take us out of bounds
|
||||
self.cursor_index -= 1
|
||||
valid = False
|
||||
elif self.cursor_index >= (n_windows - 1):
|
||||
# Flip the orientation and reset the cursor
|
||||
self.flip(self.cursor_index)
|
||||
self.cursor_index = 0
|
||||
redraw = True
|
||||
else:
|
||||
if self.cursor_index > 0:
|
||||
self.cursor_index -= 1
|
||||
else:
|
||||
self.page_index -= self.step
|
||||
if self._is_valid(self.absolute_index):
|
||||
# We have reached the beginning of the page - move the
|
||||
# index
|
||||
redraw = True
|
||||
else:
|
||||
self.page_index += self.step
|
||||
valid = False # Revert
|
||||
|
||||
return valid, redraw
|
||||
|
||||
def move_page(self, direction, n_windows):
|
||||
"""
|
||||
Move page down (positive direction) or up (negative direction).
|
||||
"""
|
||||
|
||||
# top of subreddit/submission page or only one
|
||||
# submission/reply on the screen: act as normal move
|
||||
if (self.absolute_index < 0) | (n_windows == 0):
|
||||
valid, redraw = self.move(direction, n_windows)
|
||||
else:
|
||||
# first page
|
||||
if self.absolute_index < n_windows and direction < 0:
|
||||
self.page_index = -1
|
||||
self.cursor_index = 0
|
||||
self.inverted = False
|
||||
|
||||
# not submission mode: starting index is 0
|
||||
if not self._is_valid(self.absolute_index):
|
||||
self.page_index = 0
|
||||
valid = True
|
||||
else:
|
||||
# flip to the direction of movement
|
||||
if ((direction > 0) & (self.inverted is True))\
|
||||
| ((direction < 0) & (self.inverted is False)):
|
||||
self.page_index += (self.step * (n_windows-1))
|
||||
self.inverted = not self.inverted
|
||||
self.cursor_index \
|
||||
= (n_windows-(direction < 0)) - self.cursor_index
|
||||
|
||||
valid = False
|
||||
adj = 0
|
||||
# check if reached the bottom
|
||||
while not valid:
|
||||
n_move = n_windows - adj
|
||||
if n_move == 0:
|
||||
break
|
||||
|
||||
self.page_index += n_move * direction
|
||||
valid = self._is_valid(self.absolute_index)
|
||||
if not valid:
|
||||
self.page_index -= n_move * direction
|
||||
adj += 1
|
||||
|
||||
redraw = True
|
||||
|
||||
return valid, redraw
|
||||
|
||||
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
|
||||
|
||||
def _is_valid(self, page_index):
|
||||
"Check if a page index will cause entries to fall outside valid range"
|
||||
|
||||
try:
|
||||
self._page_cb(page_index)
|
||||
except IndexError:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
@wraps(f)
|
||||
def wrapped_method(self, *args, **kwargs):
|
||||
if not self.reddit.is_oauth_session():
|
||||
self.term.show_notification('Not logged in')
|
||||
return
|
||||
return f(self, *args, **kwargs)
|
||||
return wrapped_method
|
||||
|
||||
|
||||
class SafeCaller(object):
|
||||
|
||||
def __init__(self, window):
|
||||
self.window = window
|
||||
self.catch = True
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, e, exc_tb):
|
||||
|
||||
if self.catch:
|
||||
if isinstance(e, praw.errors.APIException):
|
||||
message = ['Error: {}'.format(e.error_type), e.message]
|
||||
show_notification(self.window, message)
|
||||
_logger.exception(e)
|
||||
return True
|
||||
elif isinstance(e, praw.errors.ClientException):
|
||||
message = ['Error: Client Exception', e.message]
|
||||
show_notification(self.window, message)
|
||||
_logger.exception(e)
|
||||
return True
|
||||
elif isinstance(e, requests.HTTPError):
|
||||
show_notification(self.window, ['Unexpected Error'])
|
||||
_logger.exception(e)
|
||||
return True
|
||||
elif isinstance(e, requests.ConnectionError):
|
||||
show_notification(self.window, ['Unexpected Error'])
|
||||
_logger.exception(e)
|
||||
return True
|
||||
class PageController(Controller):
|
||||
character_map = {}
|
||||
|
||||
|
||||
class BaseController(object):
|
||||
"""
|
||||
Event handler for triggering functions with curses keypresses.
|
||||
class Page(object):
|
||||
|
||||
Register a keystroke to a class method using the @egister decorator.
|
||||
#>>> @Controller.register('a', 'A')
|
||||
#>>> def func(self, *args)
|
||||
def __init__(self, reddit, term, config, oauth):
|
||||
|
||||
Register a default behavior by using `None`.
|
||||
#>>> @Controller.register(None)
|
||||
#>>> def default_func(self, *args)
|
||||
|
||||
Bind the controller to a class instance and trigger a key. Additional
|
||||
arguments will be passed to the function.
|
||||
#>>> controller = Controller(self)
|
||||
#>>> controller.trigger('a', *args)
|
||||
"""
|
||||
|
||||
character_map = {None: (lambda *args, **kwargs: None)}
|
||||
|
||||
def __init__(self, instance):
|
||||
self.instance = instance
|
||||
|
||||
def trigger(self, char, *args, **kwargs):
|
||||
|
||||
if isinstance(char, six.string_types) and len(char) == 1:
|
||||
char = ord(char)
|
||||
|
||||
func = self.character_map.get(char)
|
||||
if func is None:
|
||||
func = BaseController.character_map.get(char)
|
||||
if func is None:
|
||||
func = self.character_map.get(None)
|
||||
if func is None:
|
||||
func = BaseController.character_map.get(None)
|
||||
return func(self.instance, *args, **kwargs)
|
||||
|
||||
@classmethod
|
||||
def register(cls, *chars):
|
||||
def wrap(f):
|
||||
for char in chars:
|
||||
if isinstance(char, six.string_types) and len(char) == 1:
|
||||
cls.character_map[ord(char)] = f
|
||||
else:
|
||||
cls.character_map[char] = f
|
||||
return f
|
||||
return wrap
|
||||
|
||||
|
||||
class BasePage(object):
|
||||
"""
|
||||
Base terminal viewer incorporates a cursor to navigate content
|
||||
"""
|
||||
|
||||
MIN_HEIGHT = 10
|
||||
MIN_WIDTH = 20
|
||||
|
||||
def __init__(self, stdscr, reddit, content, oauth, **kwargs):
|
||||
|
||||
self.stdscr = stdscr
|
||||
self.reddit = reddit
|
||||
self.content = content
|
||||
self.term = term
|
||||
self.config = config
|
||||
self.oauth = oauth
|
||||
self.nav = Navigator(self.content.get, **kwargs)
|
||||
self.content = None
|
||||
self.nav = None
|
||||
self.controller = None
|
||||
|
||||
self.active = True
|
||||
self._header_window = None
|
||||
self._content_window = None
|
||||
self._subwindows = None
|
||||
@@ -260,101 +50,114 @@ class BasePage(object):
|
||||
raise NotImplementedError
|
||||
|
||||
@staticmethod
|
||||
def draw_item(window, data, inverted):
|
||||
def _draw_item(window, data, inverted):
|
||||
raise NotImplementedError
|
||||
|
||||
@BaseController.register('q')
|
||||
def loop(self):
|
||||
"""
|
||||
Main control loop runs the following steps:
|
||||
1. Re-draw the screen
|
||||
2. Wait for user to press a key (includes terminal resizing)
|
||||
3. Trigger the method registered to the input key
|
||||
|
||||
The loop will run until self.active is set to False from within one of
|
||||
the methods.
|
||||
"""
|
||||
|
||||
self.active = True
|
||||
while self.active:
|
||||
self.draw()
|
||||
ch = self.term.stdscr.getch()
|
||||
self.controller.trigger(ch)
|
||||
|
||||
@PageController.register('q')
|
||||
def exit(self):
|
||||
"""
|
||||
Prompt to exit the application.
|
||||
"""
|
||||
|
||||
ch = prompt_input(self.stdscr, "Do you really want to quit? (y/n): ")
|
||||
if ch == 'y':
|
||||
if self.term.prompt_y_or_n('Do you really want to quit? (y/n): '):
|
||||
sys.exit()
|
||||
elif ch != 'n':
|
||||
curses.flash()
|
||||
|
||||
@BaseController.register('Q')
|
||||
@PageController.register('Q')
|
||||
def force_exit(self):
|
||||
sys.exit()
|
||||
|
||||
@BaseController.register('?')
|
||||
def help(self):
|
||||
show_help(self._content_window)
|
||||
@PageController.register('?')
|
||||
def show_help(self):
|
||||
self.term.show_notification(docs.HELP.strip().splitlines())
|
||||
|
||||
@BaseController.register('1')
|
||||
@PageController.register('1')
|
||||
def sort_content_hot(self):
|
||||
self.refresh_content(order='hot')
|
||||
|
||||
@BaseController.register('2')
|
||||
@PageController.register('2')
|
||||
def sort_content_top(self):
|
||||
self.refresh_content(order='top')
|
||||
|
||||
@BaseController.register('3')
|
||||
@PageController.register('3')
|
||||
def sort_content_rising(self):
|
||||
self.refresh_content(order='rising')
|
||||
|
||||
@BaseController.register('4')
|
||||
@PageController.register('4')
|
||||
def sort_content_new(self):
|
||||
self.refresh_content(order='new')
|
||||
|
||||
@BaseController.register('5')
|
||||
@PageController.register('5')
|
||||
def sort_content_controversial(self):
|
||||
self.refresh_content(order='controversial')
|
||||
|
||||
@BaseController.register(curses.KEY_UP, 'k')
|
||||
@PageController.register(curses.KEY_UP, 'k')
|
||||
def move_cursor_up(self):
|
||||
self._move_cursor(-1)
|
||||
self.clear_input_queue()
|
||||
|
||||
@BaseController.register(curses.KEY_DOWN, 'j')
|
||||
@PageController.register(curses.KEY_DOWN, 'j')
|
||||
def move_cursor_down(self):
|
||||
self._move_cursor(1)
|
||||
self.clear_input_queue()
|
||||
|
||||
@BaseController.register('n', curses.KEY_NPAGE)
|
||||
def move_page_down(self):
|
||||
self._move_page(1)
|
||||
self.clear_input_queue()
|
||||
|
||||
@BaseController.register('m', curses.KEY_PPAGE)
|
||||
@PageController.register('m', curses.KEY_PPAGE)
|
||||
def move_page_up(self):
|
||||
self._move_page(-1)
|
||||
self.clear_input_queue()
|
||||
|
||||
@BaseController.register('a')
|
||||
@PageController.register('n', curses.KEY_NPAGE)
|
||||
def move_page_down(self):
|
||||
self._move_page(1)
|
||||
self.clear_input_queue()
|
||||
|
||||
@PageController.register('a')
|
||||
@logged_in
|
||||
def upvote(self):
|
||||
data = self.content.get(self.nav.absolute_index)
|
||||
try:
|
||||
if 'likes' not in data:
|
||||
pass
|
||||
elif data['likes']:
|
||||
if 'likes' not in data:
|
||||
self.term.flash()
|
||||
elif data['likes']:
|
||||
with self.term.loader():
|
||||
data['object'].clear_vote()
|
||||
if not self.term.loader.exception:
|
||||
data['likes'] = None
|
||||
else:
|
||||
else:
|
||||
with self.term.loader():
|
||||
data['object'].upvote()
|
||||
if not self.term.loader.exception:
|
||||
data['likes'] = True
|
||||
except praw.errors.LoginOrScopeRequired:
|
||||
show_notification(self.stdscr, ['Not logged in'])
|
||||
|
||||
@BaseController.register('z')
|
||||
@PageController.register('z')
|
||||
@logged_in
|
||||
def downvote(self):
|
||||
data = self.content.get(self.nav.absolute_index)
|
||||
try:
|
||||
if 'likes' not in data:
|
||||
pass
|
||||
elif data['likes'] or data['likes'] is None:
|
||||
if 'likes' not in data:
|
||||
self.term.flash()
|
||||
elif data['likes'] or data['likes'] is None:
|
||||
with self.term.loader():
|
||||
data['object'].downvote()
|
||||
if not self.term.loader.exception:
|
||||
data['likes'] = False
|
||||
else:
|
||||
else:
|
||||
with self.term.loader():
|
||||
data['object'].clear_vote()
|
||||
if not self.term.loader.exception:
|
||||
data['likes'] = None
|
||||
|
||||
except praw.errors.LoginOrScopeRequired:
|
||||
show_notification(self.stdscr, ['Not logged in'])
|
||||
|
||||
@BaseController.register('u')
|
||||
@PageController.register('u')
|
||||
def login(self):
|
||||
"""
|
||||
Prompt to log into the user's account, or log out of the current
|
||||
@@ -362,138 +165,105 @@ class BasePage(object):
|
||||
"""
|
||||
|
||||
if self.reddit.is_oauth_session():
|
||||
ch = prompt_input(self.stdscr, "Log out? (y/n): ")
|
||||
if ch == 'y':
|
||||
if self.term.prompt_y_or_n('Log out? (y/n): '):
|
||||
self.oauth.clear_oauth_data()
|
||||
show_notification(self.stdscr, ['Logged out'])
|
||||
elif ch != 'n':
|
||||
curses.flash()
|
||||
self.term.show_notification('Logged out')
|
||||
else:
|
||||
self.oauth.authorize()
|
||||
|
||||
@BaseController.register('d')
|
||||
def delete(self):
|
||||
@PageController.register('d')
|
||||
@logged_in
|
||||
def delete_item(self):
|
||||
"""
|
||||
Delete a submission or comment.
|
||||
"""
|
||||
|
||||
if not self.reddit.is_oauth_session():
|
||||
show_notification(self.stdscr, ['Not logged in'])
|
||||
return
|
||||
|
||||
data = self.content.get(self.nav.absolute_index)
|
||||
if data.get('author') != self.reddit.user.name:
|
||||
curses.flash()
|
||||
self.term.flash()
|
||||
return
|
||||
|
||||
prompt = 'Are you sure you want to delete this? (y/n): '
|
||||
char = prompt_input(self.stdscr, prompt)
|
||||
if char != 'y':
|
||||
show_notification(self.stdscr, ['Aborted'])
|
||||
if not self.term.prompt_y_or_n(prompt):
|
||||
self.term.show_notification('Aborted')
|
||||
return
|
||||
|
||||
with self.safe_call as s:
|
||||
with self.loader(message='Deleting', delay=0):
|
||||
data['object'].delete()
|
||||
time.sleep(2.0)
|
||||
s.catch = False
|
||||
with self.term.loader(message='Deleting', delay=0):
|
||||
data['object'].delete()
|
||||
# Give reddit time to process the request
|
||||
time.sleep(2.0)
|
||||
if self.term.loader.exception is None:
|
||||
self.refresh_content()
|
||||
|
||||
@BaseController.register('e')
|
||||
@PageController.register('e')
|
||||
@logged_in
|
||||
def edit(self):
|
||||
"""
|
||||
Edit a submission or comment.
|
||||
"""
|
||||
|
||||
if not self.reddit.is_oauth_session():
|
||||
show_notification(self.stdscr, ['Not logged in'])
|
||||
return
|
||||
|
||||
data = self.content.get(self.nav.absolute_index)
|
||||
if data.get('author') != self.reddit.user.name:
|
||||
curses.flash()
|
||||
self.term.flash()
|
||||
return
|
||||
|
||||
if data['type'] == 'Submission':
|
||||
subreddit = self.reddit.get_subreddit(self.content.name)
|
||||
content = data['text']
|
||||
info = SUBMISSION_FILE.format(content=content, name=subreddit)
|
||||
info = docs.SUBMISSION_EDIT_FILE.format(
|
||||
content=content, name=subreddit)
|
||||
elif data['type'] == 'Comment':
|
||||
content = data['body']
|
||||
info = COMMENT_EDIT_FILE.format(content=content)
|
||||
info = docs.COMMENT_EDIT_FILE.format(content=content)
|
||||
else:
|
||||
curses.flash()
|
||||
self.term.flash()
|
||||
return
|
||||
|
||||
text = open_editor(info)
|
||||
text = self.term.open_editor(info)
|
||||
if text == content:
|
||||
show_notification(self.stdscr, ['Aborted'])
|
||||
self.term.show_notification('Aborted')
|
||||
return
|
||||
|
||||
with self.safe_call as s:
|
||||
with self.loader(message='Editing', delay=0):
|
||||
data['object'].edit(text)
|
||||
time.sleep(2.0)
|
||||
s.catch = False
|
||||
with self.term.loader(message='Editing', delay=0):
|
||||
data['object'].edit(text)
|
||||
time.sleep(2.0)
|
||||
if self.term.loader.exception is None:
|
||||
self.refresh_content()
|
||||
|
||||
@BaseController.register('i')
|
||||
@PageController.register('i')
|
||||
@logged_in
|
||||
def get_inbox(self):
|
||||
"""
|
||||
Checks the inbox for unread messages and displays a notification.
|
||||
"""
|
||||
|
||||
if not self.reddit.is_oauth_session():
|
||||
show_notification(self.stdscr, ['Not logged in'])
|
||||
return
|
||||
|
||||
inbox = len(list(self.reddit.get_unread(limit=1)))
|
||||
try:
|
||||
if inbox > 0:
|
||||
show_notification(self.stdscr, ['New Messages'])
|
||||
elif inbox == 0:
|
||||
show_notification(self.stdscr, ['No New Messages'])
|
||||
except praw.errors.LoginOrScopeRequired:
|
||||
show_notification(self.stdscr, ['Not Logged In'])
|
||||
message = 'New Messages' if inbox > 0 else 'No New Messages'
|
||||
self.term.show_notification(message)
|
||||
|
||||
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
|
||||
self.stdscr.nodelay(0)
|
||||
|
||||
@property
|
||||
def safe_call(self):
|
||||
"""
|
||||
Wrap praw calls with extended error handling.
|
||||
If a PRAW related error occurs inside of this context manager, a
|
||||
notification will be displayed on the screen instead of the entire
|
||||
application shutting down. This function will return a callback that
|
||||
can be used to check the status of the call.
|
||||
|
||||
Usage:
|
||||
#>>> with self.safe_call as s:
|
||||
#>>> self.reddit.submit(...)
|
||||
#>>> s.catch = False
|
||||
#>>> on_success()
|
||||
"""
|
||||
return SafeCaller(self.stdscr)
|
||||
with self.term.no_delay():
|
||||
while self.term.getch() != -1:
|
||||
continue
|
||||
|
||||
def draw(self):
|
||||
|
||||
n_rows, n_cols = self.stdscr.getmaxyx()
|
||||
if n_rows < self.MIN_HEIGHT or n_cols < self.MIN_WIDTH:
|
||||
window = self.term.stdscr
|
||||
n_rows, n_cols = window.getmaxyx()
|
||||
if n_rows < self.term.MIN_HEIGHT or n_cols < self.term.MIN_WIDTH:
|
||||
# TODO: Will crash when you try to navigate if the terminal is too
|
||||
# small at startup because self._subwindows will never be populated
|
||||
return
|
||||
|
||||
# Note: 2 argument form of derwin breaks PDcurses on Windows 7!
|
||||
self._header_window = self.stdscr.derwin(1, n_cols, 0, 0)
|
||||
self._content_window = self.stdscr.derwin(n_rows - 1, n_cols, 1, 0)
|
||||
self._header_window = window.derwin(1, n_cols, 0, 0)
|
||||
self._content_window = window.derwin(n_rows - 1, n_cols, 1, 0)
|
||||
|
||||
self.stdscr.erase()
|
||||
window.erase()
|
||||
self._draw_header()
|
||||
self._draw_content()
|
||||
self._add_cursor()
|
||||
@@ -503,20 +273,26 @@ class BasePage(object):
|
||||
n_rows, n_cols = self._header_window.getmaxyx()
|
||||
|
||||
self._header_window.erase()
|
||||
attr = curses.A_REVERSE | curses.A_BOLD | Color.CYAN
|
||||
self._header_window.bkgd(' ', attr)
|
||||
# curses.bkgd expects bytes in py2 and unicode in py3
|
||||
ch, attr = str(' '), curses.A_REVERSE | curses.A_BOLD | Color.CYAN
|
||||
self._header_window.bkgd(ch, attr)
|
||||
|
||||
sub_name = self.content.name.replace('/r/front', 'Front Page')
|
||||
add_line(self._header_window, sub_name, 0, 0)
|
||||
self.term.add_line(self._header_window, sub_name, 0, 0)
|
||||
if self.content.order is not None:
|
||||
add_line(self._header_window, ' [{}]'.format(self.content.order))
|
||||
order = ' [{}]'.format(self.content.order)
|
||||
self.term.add_line(self._header_window, order)
|
||||
|
||||
if self.reddit.user is not None:
|
||||
# The starting position of the name depends on if we're converting
|
||||
# to ascii or not
|
||||
width = len if self.config['ascii'] else textual_width
|
||||
|
||||
username = self.reddit.user.name
|
||||
s_col = (n_cols - textual_width(username) - 1)
|
||||
s_col = (n_cols - width(username) - 1)
|
||||
# Only print username if it fits in the empty space on the right
|
||||
if (s_col - 1) >= textual_width(sub_name):
|
||||
add_line(self._header_window, username, 0, s_col)
|
||||
if (s_col - 1) >= width(sub_name):
|
||||
self.term.add_line(self._header_window, username, 0, s_col)
|
||||
|
||||
self._header_window.refresh()
|
||||
|
||||
@@ -543,7 +319,7 @@ class BasePage(object):
|
||||
start = current_row - window_rows if inverted else current_row
|
||||
subwindow = self._content_window.derwin(
|
||||
window_rows, window_cols, start, data['offset'])
|
||||
attr = self.draw_item(subwindow, data, inverted)
|
||||
attr = self._draw_item(subwindow, data, inverted)
|
||||
self._subwindows.append((subwindow, attr))
|
||||
available_rows -= (window_rows + 1) # Add one for the blank line
|
||||
current_row += step * (window_rows + 1)
|
||||
@@ -571,7 +347,7 @@ class BasePage(object):
|
||||
self._remove_cursor()
|
||||
valid, redraw = self.nav.move(direction, len(self._subwindows))
|
||||
if not valid:
|
||||
curses.flash()
|
||||
self.term.flash()
|
||||
|
||||
# Note: ACS_VLINE doesn't like changing the attribute,
|
||||
# so always redraw.
|
||||
@@ -582,14 +358,14 @@ class BasePage(object):
|
||||
self._remove_cursor()
|
||||
valid, redraw = self.nav.move_page(direction, len(self._subwindows)-1)
|
||||
if not valid:
|
||||
curses.flash()
|
||||
self.term.flash()
|
||||
|
||||
# Note: ACS_VLINE doesn't like changing the attribute,
|
||||
# so always redraw.
|
||||
self._draw_content()
|
||||
self._add_cursor()
|
||||
|
||||
def _edit_cursor(self, attribute=None):
|
||||
def _edit_cursor(self, attribute):
|
||||
|
||||
# Don't allow the cursor to go below page index 0
|
||||
if self.nav.absolute_index < 0:
|
||||
@@ -599,7 +375,7 @@ class BasePage(object):
|
||||
# This could happen if the window is resized and the cursor index is
|
||||
# pushed out of bounds
|
||||
if self.nav.cursor_index >= len(self._subwindows):
|
||||
self.nav.cursor_index = len(self._subwindows)-1
|
||||
self.nav.cursor_index = len(self._subwindows) - 1
|
||||
|
||||
window, attr = self._subwindows[self.nav.cursor_index]
|
||||
if attr is not None:
|
||||
@@ -609,4 +385,4 @@ class BasePage(object):
|
||||
for row in range(n_rows):
|
||||
window.chgat(row, 0, 1, attribute)
|
||||
|
||||
window.refresh()
|
||||
window.refresh()
|
||||
@@ -1,47 +1,33 @@
|
||||
import curses
|
||||
import sys
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import time
|
||||
import logging
|
||||
import curses
|
||||
|
||||
from . import docs
|
||||
from .content import SubmissionContent
|
||||
from .page import BasePage, Navigator, BaseController
|
||||
from .helpers import open_browser, open_editor
|
||||
from .curses_helpers import (Color, LoadScreen, get_arrow, get_gold, add_line,
|
||||
show_notification)
|
||||
from .docs import COMMENT_FILE
|
||||
|
||||
__all__ = ['SubmissionController', 'SubmissionPage']
|
||||
_logger = logging.getLogger(__name__)
|
||||
from .page import Page, PageController, logged_in
|
||||
from .objects import Navigator, Color
|
||||
from .terminal import Terminal
|
||||
|
||||
|
||||
class SubmissionController(BaseController):
|
||||
class SubmissionController(PageController):
|
||||
character_map = {}
|
||||
|
||||
|
||||
class SubmissionPage(BasePage):
|
||||
class SubmissionPage(Page):
|
||||
|
||||
def __init__(self, stdscr, reddit, oauth, url=None, submission=None):
|
||||
def __init__(self, reddit, term, config, oauth, url=None, submission=None):
|
||||
super(SubmissionPage, self).__init__(reddit, term, config, oauth)
|
||||
|
||||
if url:
|
||||
self.content = SubmissionContent.from_url(reddit, url, term.loader)
|
||||
else:
|
||||
self.content = SubmissionContent(submission, term.loader)
|
||||
|
||||
self.controller = SubmissionController(self)
|
||||
self.loader = LoadScreen(stdscr)
|
||||
if url:
|
||||
content = SubmissionContent.from_url(reddit, url, self.loader)
|
||||
elif submission:
|
||||
content = SubmissionContent(submission, self.loader)
|
||||
else:
|
||||
raise ValueError('Must specify url or submission')
|
||||
|
||||
super(SubmissionPage, self).__init__(stdscr, reddit, content, oauth,
|
||||
page_index=-1)
|
||||
|
||||
def loop(self):
|
||||
"Main control loop"
|
||||
|
||||
self.active = True
|
||||
while self.active:
|
||||
self.draw()
|
||||
cmd = self.stdscr.getch()
|
||||
self.controller.trigger(cmd)
|
||||
# Start at the submission post, which is indexed as -1
|
||||
self.nav = Navigator(self.content.get, page_index=-1)
|
||||
|
||||
@SubmissionController.register(curses.KEY_RIGHT, 'l', ' ')
|
||||
def toggle_comment(self):
|
||||
@@ -50,9 +36,9 @@ class SubmissionPage(BasePage):
|
||||
current_index = self.nav.absolute_index
|
||||
self.content.toggle(current_index)
|
||||
if self.nav.inverted:
|
||||
# Reset the page so that the bottom is at the cursor position.
|
||||
# This is a workaround to handle if folding the causes the
|
||||
# cursor index to go out of bounds.
|
||||
# Reset the navigator so that the cursor is at the bottom of the
|
||||
# page. This is a workaround to handle if folding the comment
|
||||
# causes the cursor index to go out of bounds.
|
||||
self.nav.page_index, self.nav.cursor_index = current_index, 0
|
||||
|
||||
@SubmissionController.register(curses.KEY_LEFT, 'h')
|
||||
@@ -63,88 +49,93 @@ class SubmissionPage(BasePage):
|
||||
|
||||
@SubmissionController.register(curses.KEY_F5, 'r')
|
||||
def refresh_content(self, order=None):
|
||||
"Re-download comments reset the page index"
|
||||
"Re-download comments and reset the page index"
|
||||
|
||||
order = order or self.content.order
|
||||
self.content = SubmissionContent.from_url(
|
||||
self.reddit, self.content.name, self.loader, order=order)
|
||||
self.nav = Navigator(self.content.get, page_index=-1)
|
||||
url = self.content.name
|
||||
|
||||
@SubmissionController.register(curses.KEY_ENTER, 10, 'o')
|
||||
with self.term.loader():
|
||||
self.content = SubmissionContent.from_url(
|
||||
self.reddit, url, self.term.loader, order=order)
|
||||
if not self.term.loader.exception:
|
||||
self.nav = Navigator(self.content.get, page_index=-1)
|
||||
|
||||
@SubmissionController.register(curses.KEY_ENTER, Terminal.RETURN, 'o')
|
||||
def open_link(self):
|
||||
"Open the current submission page with the webbrowser"
|
||||
"Open the selected item with the webbrowser"
|
||||
|
||||
data = self.content.get(self.nav.absolute_index)
|
||||
url = data.get('permalink')
|
||||
if url:
|
||||
open_browser(url)
|
||||
self.term.open_browser(url)
|
||||
else:
|
||||
curses.flash()
|
||||
self.term.flash()
|
||||
|
||||
@SubmissionController.register('c')
|
||||
@logged_in
|
||||
def add_comment(self):
|
||||
"""
|
||||
Add a top-level comment if the submission is selected, or reply to the
|
||||
selected comment.
|
||||
"""
|
||||
Submit a reply to the selected item.
|
||||
|
||||
if not self.reddit.is_oauth_session():
|
||||
show_notification(self.stdscr, ['Not logged in'])
|
||||
return
|
||||
Selected item:
|
||||
Submission - add a top level comment
|
||||
Comment - add a comment reply
|
||||
"""
|
||||
|
||||
data = self.content.get(self.nav.absolute_index)
|
||||
if data['type'] == 'Submission':
|
||||
content = data['text']
|
||||
body = data['text']
|
||||
reply = data['object'].add_comment
|
||||
elif data['type'] == 'Comment':
|
||||
content = data['body']
|
||||
body = data['body']
|
||||
reply = data['object'].reply
|
||||
else:
|
||||
curses.flash()
|
||||
self.term.flash()
|
||||
return
|
||||
|
||||
# Comment out every line of the content
|
||||
content = '\n'.join(['# |' + line for line in content.split('\n')])
|
||||
comment_info = COMMENT_FILE.format(
|
||||
# Construct the text that will be displayed in the editor file.
|
||||
# The post body will be commented out and added for reference
|
||||
lines = ['# |' + line for line in body.split('\n')]
|
||||
content = '\n'.join(lines)
|
||||
comment_info = docs.COMMENT_FILE.format(
|
||||
author=data['author'],
|
||||
type=data['type'].lower(),
|
||||
content=content)
|
||||
|
||||
comment_text = open_editor(comment_info)
|
||||
if not comment_text:
|
||||
show_notification(self.stdscr, ['Aborted'])
|
||||
comment = self.term.open_editor(comment_info)
|
||||
if not comment:
|
||||
self.term.show_notification('Aborted')
|
||||
return
|
||||
|
||||
with self.safe_call as s:
|
||||
with self.loader(message='Posting', delay=0):
|
||||
if data['type'] == 'Submission':
|
||||
data['object'].add_comment(comment_text)
|
||||
else:
|
||||
data['object'].reply(comment_text)
|
||||
time.sleep(2.0)
|
||||
s.catch = False
|
||||
with self.term.loader(message='Posting', delay=0):
|
||||
reply(comment)
|
||||
# Give reddit time to process the submission
|
||||
time.sleep(2.0)
|
||||
if not self.term.loader.exception:
|
||||
self.refresh_content()
|
||||
|
||||
@SubmissionController.register('d')
|
||||
@logged_in
|
||||
def delete_comment(self):
|
||||
"Delete a comment as long as it is not the current submission"
|
||||
|
||||
if self.nav.absolute_index != -1:
|
||||
self.delete()
|
||||
self.delete_item()
|
||||
else:
|
||||
curses.flash()
|
||||
self.term.flash()
|
||||
|
||||
def draw_item(self, win, data, inverted=False):
|
||||
def _draw_item(self, win, data, inverted=False):
|
||||
|
||||
if data['type'] == 'MoreComments':
|
||||
return self.draw_more_comments(win, data)
|
||||
return self._draw_more_comments(win, data)
|
||||
elif data['type'] == 'HiddenComment':
|
||||
return self.draw_more_comments(win, data)
|
||||
return self._draw_more_comments(win, data)
|
||||
elif data['type'] == 'Comment':
|
||||
return self.draw_comment(win, data, inverted=inverted)
|
||||
return self._draw_comment(win, data, inverted=inverted)
|
||||
else:
|
||||
return self.draw_submission(win, data)
|
||||
return self._draw_submission(win, data)
|
||||
|
||||
@staticmethod
|
||||
def draw_comment(win, data, inverted=False):
|
||||
def _draw_comment(self, win, data, inverted=False):
|
||||
|
||||
n_rows, n_cols = win.getmaxyx()
|
||||
n_cols -= 1
|
||||
@@ -158,73 +149,65 @@ class SubmissionPage(BasePage):
|
||||
|
||||
attr = curses.A_BOLD
|
||||
attr |= (Color.BLUE if not data['is_author'] else Color.GREEN)
|
||||
add_line(win, u'{author} '.format(**data), row, 1, attr)
|
||||
self.term.add_line(win, '{author} '.format(**data), row, 1, attr)
|
||||
|
||||
if data['flair']:
|
||||
attr = curses.A_BOLD | Color.YELLOW
|
||||
add_line(win, u'{flair} '.format(**data), attr=attr)
|
||||
self.term.add_line(win, '{flair} '.format(**data), attr=attr)
|
||||
|
||||
text, attr = get_arrow(data['likes'])
|
||||
add_line(win, text, attr=attr)
|
||||
add_line(win, u' {score} {created} '.format(**data))
|
||||
text, attr = self.term.get_arrow(data['likes'])
|
||||
self.term.add_line(win, text, attr=attr)
|
||||
self.term.add_line(win, ' {score} {created} '.format(**data))
|
||||
|
||||
if data['gold']:
|
||||
text, attr = get_gold()
|
||||
add_line(win, text, attr=attr)
|
||||
text, attr = self.term.guilded
|
||||
self.term.add_line(win, text, attr=attr)
|
||||
|
||||
for row, text in enumerate(data['split_body'], start=offset + 1):
|
||||
for row, text in enumerate(data['split_body'], start=offset+1):
|
||||
if row in valid_rows:
|
||||
add_line(win, text, row, 1)
|
||||
self.term.add_line(win, text, row, 1)
|
||||
|
||||
# Unfortunately vline() doesn't support custom color so we have to
|
||||
# build it one segment at a time.
|
||||
attr = Color.get_level(data['level'])
|
||||
x = 0
|
||||
for y in range(n_rows):
|
||||
x = 0
|
||||
# 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.term.addch(win, y, x, curses.ACS_VLINE, attr)
|
||||
|
||||
win.addch(y, x, curses.ACS_VLINE, attr)
|
||||
return attr | curses.ACS_VLINE
|
||||
|
||||
return (attr | curses.ACS_VLINE)
|
||||
|
||||
@staticmethod
|
||||
def draw_more_comments(win, data):
|
||||
def _draw_more_comments(self, win, data):
|
||||
|
||||
n_rows, n_cols = win.getmaxyx()
|
||||
n_cols -= 1
|
||||
|
||||
add_line(win, u'{body}'.format(**data), 0, 1)
|
||||
add_line(win, u' [{count}]'.format(**data), attr=curses.A_BOLD)
|
||||
self.term.add_line(win, '{body}'.format(**data), 0, 1)
|
||||
self.term.add_line(win, ' [{count}]'.format(**data), attr=curses.A_BOLD)
|
||||
|
||||
attr = Color.get_level(data['level'])
|
||||
win.addch(0, 0, curses.ACS_VLINE, attr)
|
||||
self.term.addch(win, 0, 0, curses.ACS_VLINE, attr)
|
||||
|
||||
return (attr | curses.ACS_VLINE)
|
||||
return attr | curses.ACS_VLINE
|
||||
|
||||
@staticmethod
|
||||
def draw_submission(win, data):
|
||||
def _draw_submission(self, win, data):
|
||||
|
||||
n_rows, n_cols = win.getmaxyx()
|
||||
n_cols -= 3 # one for each side of the border + one for offset
|
||||
|
||||
for row, text in enumerate(data['split_title'], start=1):
|
||||
add_line(win, text, row, 1, curses.A_BOLD)
|
||||
self.term.add_line(win, text, row, 1, curses.A_BOLD)
|
||||
|
||||
row = len(data['split_title']) + 1
|
||||
attr = curses.A_BOLD | Color.GREEN
|
||||
add_line(win, u'{author}'.format(**data), row, 1, attr)
|
||||
self.term.add_line(win, '{author}'.format(**data), row, 1, attr)
|
||||
attr = curses.A_BOLD | Color.YELLOW
|
||||
if data['flair']:
|
||||
add_line(win, u' {flair}'.format(**data), attr=attr)
|
||||
add_line(win, u' {created} {subreddit}'.format(**data))
|
||||
self.term.add_line(win, ' {flair}'.format(**data), attr=attr)
|
||||
self.term.add_line(win, ' {created} {subreddit}'.format(**data))
|
||||
|
||||
row = len(data['split_title']) + 2
|
||||
attr = curses.A_UNDERLINE | Color.BLUE
|
||||
add_line(win, u'{url}'.format(**data), row, 1, attr)
|
||||
self.term.add_line(win, '{url}'.format(**data), row, 1, attr)
|
||||
offset = len(data['split_title']) + 3
|
||||
|
||||
# Cut off text if there is not enough room to display the whole post
|
||||
@@ -235,20 +218,20 @@ class SubmissionPage(BasePage):
|
||||
split_text.append('(Not enough space to display)')
|
||||
|
||||
for row, text in enumerate(split_text, start=offset):
|
||||
add_line(win, text, row, 1)
|
||||
self.term.add_line(win, text, row, 1)
|
||||
|
||||
row = len(data['split_title']) + len(split_text) + 3
|
||||
add_line(win, u'{score} '.format(**data), row, 1)
|
||||
text, attr = get_arrow(data['likes'])
|
||||
add_line(win, text, attr=attr)
|
||||
add_line(win, u' {comments} '.format(**data))
|
||||
self.term.add_line(win, '{score} '.format(**data), row, 1)
|
||||
text, attr = self.term.get_arrow(data['likes'])
|
||||
self.term.add_line(win, text, attr=attr)
|
||||
self.term.add_line(win, ' {comments} '.format(**data))
|
||||
|
||||
if data['gold']:
|
||||
text, attr = get_gold()
|
||||
add_line(win, text, attr=attr)
|
||||
text, attr = self.term.gold
|
||||
self.term.add_line(win, text, attr=attr)
|
||||
|
||||
if data['nsfw']:
|
||||
text, attr = 'NSFW', (curses.A_BOLD | Color.RED)
|
||||
add_line(win, text, attr=attr)
|
||||
self.term.add_line(win, text, attr=attr)
|
||||
|
||||
win.border()
|
||||
|
||||
236
rtv/subreddit.py
236
rtv/subreddit.py
@@ -1,54 +1,40 @@
|
||||
import curses
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import time
|
||||
import logging
|
||||
import atexit
|
||||
import curses
|
||||
|
||||
import requests
|
||||
import six
|
||||
|
||||
from .exceptions import SubredditError, AccountError
|
||||
from .page import BasePage, Navigator, BaseController
|
||||
from . import docs
|
||||
from .content import SubredditContent
|
||||
from .page import Page, PageController, logged_in
|
||||
from .objects import Navigator, Color
|
||||
from .submission import SubmissionPage
|
||||
from .subscription import SubscriptionPage
|
||||
from .content import SubredditContent
|
||||
from .helpers import open_browser, open_editor
|
||||
from .docs import SUBMISSION_FILE
|
||||
from .history import load_history, save_history
|
||||
from .curses_helpers import (Color, LoadScreen, add_line, get_arrow, get_gold,
|
||||
show_notification, prompt_input)
|
||||
|
||||
__all__ = ['history', 'SubredditController', 'SubredditPage']
|
||||
_logger = logging.getLogger(__name__)
|
||||
history = load_history()
|
||||
from .terminal import Terminal
|
||||
|
||||
|
||||
@atexit.register
|
||||
def save_links():
|
||||
global history
|
||||
save_history(history)
|
||||
|
||||
|
||||
class SubredditController(BaseController):
|
||||
class SubredditController(PageController):
|
||||
character_map = {}
|
||||
|
||||
|
||||
class SubredditPage(BasePage):
|
||||
class SubredditPage(Page):
|
||||
|
||||
def __init__(self, stdscr, reddit, oauth, name):
|
||||
def __init__(self, reddit, term, config, oauth, name, url=None):
|
||||
"""
|
||||
Params:
|
||||
name (string): Name of subreddit to open
|
||||
url (string): Optional submission to load upon start
|
||||
"""
|
||||
super(SubredditPage, self).__init__(reddit, term, config, oauth)
|
||||
|
||||
self.content = SubredditContent.from_name(reddit, name, term.loader)
|
||||
self.controller = SubredditController(self)
|
||||
self.loader = LoadScreen(stdscr)
|
||||
self.oauth = oauth
|
||||
self.nav = Navigator(self.content.get)
|
||||
|
||||
content = SubredditContent.from_name(reddit, name, self.loader)
|
||||
super(SubredditPage, self).__init__(stdscr, reddit, content, oauth)
|
||||
|
||||
def loop(self):
|
||||
"Main control loop"
|
||||
|
||||
while True:
|
||||
self.draw()
|
||||
cmd = self.stdscr.getch()
|
||||
self.controller.trigger(cmd)
|
||||
if url:
|
||||
self.open_submission(url=url)
|
||||
|
||||
@SubredditController.register(curses.KEY_F5, 'r')
|
||||
def refresh_content(self, name=None, order=None):
|
||||
@@ -62,16 +48,10 @@ class SubredditPage(BasePage):
|
||||
if order == 'ignore':
|
||||
order = None
|
||||
|
||||
try:
|
||||
with self.term.loader():
|
||||
self.content = SubredditContent.from_name(
|
||||
self.reddit, name, self.loader, order=order)
|
||||
except AccountError:
|
||||
show_notification(self.stdscr, ['Not logged in'])
|
||||
except SubredditError:
|
||||
show_notification(self.stdscr, ['Invalid subreddit'])
|
||||
except requests.HTTPError:
|
||||
show_notification(self.stdscr, ['Could not reach subreddit'])
|
||||
else:
|
||||
self.reddit, name, self.term.loader, order=order)
|
||||
if not self.term.loader.exception:
|
||||
self.nav = Navigator(self.content.get)
|
||||
|
||||
@SubredditController.register('f')
|
||||
@@ -79,115 +59,114 @@ class SubredditPage(BasePage):
|
||||
"Open a prompt to search the given subreddit"
|
||||
|
||||
name = name or self.content.name
|
||||
prompt = 'Search {}:'.format(name)
|
||||
query = prompt_input(self.stdscr, prompt)
|
||||
if query is None:
|
||||
|
||||
query = self.term.prompt_input('Search {0}:'.format(name))
|
||||
if not query:
|
||||
return
|
||||
|
||||
try:
|
||||
with self.term.loader():
|
||||
self.content = SubredditContent.from_name(
|
||||
self.reddit, name, self.loader, query=query)
|
||||
except (IndexError, SubredditError): # if there are no submissions
|
||||
show_notification(self.stdscr, ['No results found'])
|
||||
else:
|
||||
self.reddit, name, self.term.loader, query=query)
|
||||
if not self.term.loader.exception:
|
||||
self.nav = Navigator(self.content.get)
|
||||
|
||||
@SubredditController.register('/')
|
||||
def prompt_subreddit(self):
|
||||
"Open a prompt to navigate to a different subreddit"
|
||||
prompt = 'Enter Subreddit: /r/'
|
||||
name = prompt_input(self.stdscr, prompt)
|
||||
|
||||
name = self.term.prompt_input('Enter Subreddit: /r/')
|
||||
if name is not None:
|
||||
self.refresh_content(name=name, order='ignore')
|
||||
|
||||
@SubredditController.register(curses.KEY_RIGHT, 'l')
|
||||
def open_submission(self):
|
||||
def open_submission(self, url=None):
|
||||
"Select the current submission to view posts"
|
||||
|
||||
data = self.content.get(self.nav.absolute_index)
|
||||
page = SubmissionPage(self.stdscr, self.reddit, self.oauth,
|
||||
url=data['permalink'])
|
||||
page.loop()
|
||||
if data['url_type'] == 'selfpost':
|
||||
global history
|
||||
history.add(data['url_full'])
|
||||
data = {}
|
||||
if url is None:
|
||||
data = self.content.get(self.nav.absolute_index)
|
||||
url = data['permalink']
|
||||
|
||||
@SubredditController.register(curses.KEY_ENTER, 10, 'o')
|
||||
with self.term.loader():
|
||||
page = SubmissionPage(
|
||||
self.reddit, self.term, self.config, self.oauth, url=url)
|
||||
if self.term.loader.exception:
|
||||
return
|
||||
|
||||
page.loop()
|
||||
|
||||
if data.get('url_type') in ('selfpost', 'x-post'):
|
||||
self.config.history.add(data['url_full'])
|
||||
|
||||
@SubredditController.register(curses.KEY_ENTER, Terminal.RETURN, 'o')
|
||||
def open_link(self):
|
||||
"Open a link with the webbrowser"
|
||||
data = self.content.get(self.nav.absolute_index)
|
||||
|
||||
url = data['url_full']
|
||||
global history
|
||||
history.add(url)
|
||||
if data['url_type'] in ['x-post', 'selfpost']:
|
||||
page = SubmissionPage(self.stdscr, self.reddit, self.oauth,
|
||||
url=url)
|
||||
page.loop()
|
||||
data = self.content.get(self.nav.absolute_index)
|
||||
if data['url_type'] in ('x-post', 'selfpost'):
|
||||
# Open links to other posts directly in RTV
|
||||
self.open_submission()
|
||||
else:
|
||||
open_browser(url)
|
||||
self.term.open_browser(data['url_full'])
|
||||
self.config.history.add(data['url_full'])
|
||||
|
||||
@SubredditController.register('c')
|
||||
@logged_in
|
||||
def post_submission(self):
|
||||
"Post a new submission to the given subreddit"
|
||||
|
||||
if not self.reddit.is_oauth_session():
|
||||
show_notification(self.stdscr, ['Not logged in'])
|
||||
# Check that the subreddit can be submitted to
|
||||
name = self.content.name
|
||||
if '+' in name or name in ('/r/all', '/r/front', '/r/me'):
|
||||
self.term.show_notification("Can't post to {0}".format(name))
|
||||
return
|
||||
|
||||
# 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 in ('all', 'front', 'me'):
|
||||
show_notification(self.stdscr, ['Invalid subreddit'])
|
||||
submission_info = docs.SUBMISSION_FILE.format(name=name)
|
||||
text = self.term.open_editor(submission_info)
|
||||
if not text or '\n' not in text:
|
||||
self.term.show_notification('Aborted')
|
||||
return
|
||||
|
||||
# Open the submission window
|
||||
submission_info = SUBMISSION_FILE.format(name=subreddit, content='')
|
||||
curses.endwin()
|
||||
submission_text = open_editor(submission_info)
|
||||
curses.doupdate()
|
||||
|
||||
# Validate the submission content
|
||||
if not submission_text:
|
||||
show_notification(self.stdscr, ['Aborted'])
|
||||
return
|
||||
if '\n' not in submission_text:
|
||||
show_notification(self.stdscr, ['No content'])
|
||||
title, content = text.split('\n', 1)
|
||||
with self.term.loader(message='Posting', delay=0):
|
||||
submission = self.reddit.submit(name, title, text=content)
|
||||
# Give reddit time to process the submission
|
||||
time.sleep(2.0)
|
||||
if self.term.loader.exception:
|
||||
return
|
||||
|
||||
title, content = submission_text.split('\n', 1)
|
||||
with self.safe_call as s:
|
||||
with self.loader(message='Posting', delay=0):
|
||||
post = self.reddit.submit(sub, title, text=content)
|
||||
time.sleep(2.0)
|
||||
# Open the newly created post
|
||||
s.catch = False
|
||||
page = SubmissionPage(self.stdscr, self.reddit, self.oauth,
|
||||
submission=post)
|
||||
page.loop()
|
||||
self.refresh_content()
|
||||
# Open the newly created post
|
||||
with self.term.loader():
|
||||
page = SubmissionPage(
|
||||
self.reddit, self.term, self.config, self.oauth,
|
||||
submission=submission)
|
||||
if self.term.loader.exception:
|
||||
return
|
||||
|
||||
page.loop()
|
||||
|
||||
self.refresh_content()
|
||||
|
||||
@SubredditController.register('s')
|
||||
@logged_in
|
||||
def open_subscriptions(self):
|
||||
"Open user subscriptions page"
|
||||
|
||||
if not self.reddit.is_oauth_session():
|
||||
show_notification(self.stdscr, ['Not logged in'])
|
||||
with self.term.loader():
|
||||
page = SubscriptionPage(
|
||||
self.reddit, self.term, self.config, self.oauth)
|
||||
if self.term.loader.exception:
|
||||
return
|
||||
|
||||
# Open subscriptions page
|
||||
page = SubscriptionPage(self.stdscr, self.reddit, self.oauth)
|
||||
page.loop()
|
||||
|
||||
# When user has chosen a subreddit in the subscriptions list,
|
||||
# When the user has chosen a subreddit in the subscriptions list,
|
||||
# refresh content with the selected subreddit
|
||||
if page.selected_subreddit_data is not None:
|
||||
self.refresh_content(name=page.selected_subreddit_data['name'])
|
||||
if page.subreddit_data is not None:
|
||||
self.refresh_content(name=page.subreddit_data['name'],
|
||||
order='ignore')
|
||||
|
||||
@staticmethod
|
||||
def draw_item(win, data, inverted=False):
|
||||
def _draw_item(self, win, data, inverted=False):
|
||||
|
||||
n_rows, n_cols = win.getmaxyx()
|
||||
n_cols -= 1 # Leave space for the cursor in the first column
|
||||
@@ -199,33 +178,36 @@ class SubredditPage(BasePage):
|
||||
n_title = len(data['split_title'])
|
||||
for row, text in enumerate(data['split_title'], start=offset):
|
||||
if row in valid_rows:
|
||||
add_line(win, text, row, 1, curses.A_BOLD)
|
||||
self.term.add_line(win, text, row, 1, curses.A_BOLD)
|
||||
|
||||
row = n_title + offset
|
||||
if row in valid_rows:
|
||||
seen = (data['url_full'] in history)
|
||||
seen = (data['url_full'] in self.config.history)
|
||||
link_color = Color.MAGENTA if seen else Color.BLUE
|
||||
attr = curses.A_UNDERLINE | link_color
|
||||
add_line(win, u'{url}'.format(**data), row, 1, attr)
|
||||
self.term.add_line(win, '{url}'.format(**data), row, 1, attr)
|
||||
|
||||
row = n_title + offset + 1
|
||||
if row in valid_rows:
|
||||
add_line(win, u'{score} '.format(**data), row, 1)
|
||||
text, attr = get_arrow(data['likes'])
|
||||
add_line(win, text, attr=attr)
|
||||
add_line(win, u' {created} {comments} '.format(**data))
|
||||
self.term.add_line(win, '{score} '.format(**data), row, 1)
|
||||
text, attr = self.term.get_arrow(data['likes'])
|
||||
self.term.add_line(win, text, attr=attr)
|
||||
self.term.add_line(win, ' {created} {comments} '.format(**data))
|
||||
|
||||
if data['gold']:
|
||||
text, attr = get_gold()
|
||||
add_line(win, text, attr=attr)
|
||||
text, attr = self.term.guilded
|
||||
self.term.add_line(win, text, attr=attr)
|
||||
|
||||
if data['nsfw']:
|
||||
text, attr = 'NSFW', (curses.A_BOLD | Color.RED)
|
||||
add_line(win, text, attr=attr)
|
||||
self.term.add_line(win, text, attr=attr)
|
||||
|
||||
row = n_title + offset + 2
|
||||
if row in valid_rows:
|
||||
add_line(win, u'{author}'.format(**data), row, 1, curses.A_BOLD)
|
||||
add_line(win, u' /r/{subreddit}'.format(**data), attr=Color.YELLOW)
|
||||
text = '{author}'.format(**data)
|
||||
self.term.add_line(win, text, row, 1, curses.A_BOLD)
|
||||
text = ' /r/{subreddit}'.format(**data)
|
||||
self.term.add_line(win, text, attr=Color.YELLOW)
|
||||
if data['flair']:
|
||||
add_line(win, u' {flair}'.format(**data), attr=Color.RED)
|
||||
text = ' {flair}'.format(**data)
|
||||
self.term.add_line(win, text, attr=Color.RED)
|
||||
@@ -1,66 +1,56 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import curses
|
||||
import logging
|
||||
|
||||
from .page import Page, PageController
|
||||
from .content import SubscriptionContent
|
||||
from .page import BasePage, Navigator, BaseController
|
||||
from .curses_helpers import (Color, LoadScreen, add_line)
|
||||
|
||||
__all__ = ['SubscriptionController', 'SubscriptionPage']
|
||||
_logger = logging.getLogger(__name__)
|
||||
from .objects import Color, Navigator
|
||||
from .terminal import Terminal
|
||||
|
||||
|
||||
class SubscriptionController(BaseController):
|
||||
class SubscriptionController(PageController):
|
||||
character_map = {}
|
||||
|
||||
|
||||
class SubscriptionPage(BasePage):
|
||||
class SubscriptionPage(Page):
|
||||
|
||||
def __init__(self, stdscr, reddit, oauth):
|
||||
def __init__(self, reddit, term, config, oauth):
|
||||
super(SubscriptionPage, self).__init__(reddit, term, config, oauth)
|
||||
|
||||
self.content = SubscriptionContent.from_user(reddit, term.loader)
|
||||
self.controller = SubscriptionController(self)
|
||||
self.loader = LoadScreen(stdscr)
|
||||
self.selected_subreddit_data = None
|
||||
|
||||
content = SubscriptionContent.from_user(reddit, self.loader)
|
||||
super(SubscriptionPage, self).__init__(stdscr, reddit, content, oauth)
|
||||
|
||||
def loop(self):
|
||||
"Main control loop"
|
||||
|
||||
self.active = True
|
||||
while self.active:
|
||||
self.draw()
|
||||
cmd = self.stdscr.getch()
|
||||
self.controller.trigger(cmd)
|
||||
self.nav = Navigator(self.content.get)
|
||||
self.subreddit_data = None
|
||||
|
||||
@SubscriptionController.register(curses.KEY_F5, 'r')
|
||||
def refresh_content(self, order=None):
|
||||
"Re-download all subscriptions and reset the page index"
|
||||
|
||||
# reddit.get_my_subreddits() does not support sorting by order
|
||||
if order:
|
||||
# reddit.get_my_subreddits() does not support sorting by order
|
||||
curses.flash()
|
||||
else:
|
||||
self.content = SubscriptionContent.from_user(self.reddit,
|
||||
self.loader)
|
||||
self.nav = Navigator(self.content.get)
|
||||
self.term.flash()
|
||||
return
|
||||
|
||||
@SubscriptionController.register(curses.KEY_ENTER, 10, curses.KEY_RIGHT)
|
||||
def store_selected_subreddit(self):
|
||||
self.content = SubscriptionContent.from_user(self.reddit,
|
||||
self.term.loader)
|
||||
self.nav = Navigator(self.content.get)
|
||||
|
||||
@SubscriptionController.register(curses.KEY_ENTER, Terminal.RETURN,
|
||||
curses.KEY_RIGHT, 'l')
|
||||
def select_subreddit(self):
|
||||
"Store the selected subreddit and return to the subreddit page"
|
||||
|
||||
self.selected_subreddit_data = self.content.get(
|
||||
self.nav.absolute_index)
|
||||
self.subreddit_data = self.content.get(self.nav.absolute_index)
|
||||
self.active = False
|
||||
|
||||
@SubscriptionController.register(curses.KEY_LEFT, 'h', 's')
|
||||
@SubscriptionController.register(curses.KEY_LEFT, Terminal.ESCAPE, 'h', 's')
|
||||
def close_subscriptions(self):
|
||||
"Close subscriptions and return to the subreddit page"
|
||||
|
||||
self.active = False
|
||||
|
||||
@staticmethod
|
||||
def draw_item(win, data, inverted=False):
|
||||
def _draw_item(self, win, data, inverted=False):
|
||||
n_rows, n_cols = win.getmaxyx()
|
||||
n_cols -= 1 # Leave space for the cursor in the first column
|
||||
|
||||
@@ -71,9 +61,9 @@ class SubscriptionPage(BasePage):
|
||||
row = offset
|
||||
if row in valid_rows:
|
||||
attr = curses.A_BOLD | Color.YELLOW
|
||||
add_line(win, u'{name}'.format(**data), row, 1, attr)
|
||||
self.term.add_line(win, '{name}'.format(**data), row, 1, attr)
|
||||
|
||||
row = offset + 1
|
||||
for row, text in enumerate(data['split_title'], start=row):
|
||||
if row in valid_rows:
|
||||
add_line(win, text, row, 1)
|
||||
self.term.add_line(win, text, row, 1)
|
||||
@@ -28,9 +28,10 @@
|
||||
{% if error == 'access_denied' %}
|
||||
<h1 style="color: red">Access Denied</h1><hr>
|
||||
<p><span style="font-weight: bold">Reddit Terminal Viewer</span> was denied access and will continue to operate in unauthenticated mode, you can close this window.
|
||||
{% elif error != 'placeholder' %}
|
||||
<h1 style="color: red">Error : {{ error }}</h1>
|
||||
{% elif (state == 'placeholder' or code == 'placeholder') %}
|
||||
{% elif error is not None %}
|
||||
<h1 style="color: red">Error</h1><hr>
|
||||
<p>{{ error }}</p>
|
||||
{% elif (state is None or code is None) %}
|
||||
<h1>Wait...</h1><hr>
|
||||
<p>This page is supposed to be a Reddit OAuth callback. You can't just come here hands in your pocket!</p>
|
||||
{% else %}
|
||||
|
||||
446
rtv/terminal.py
Normal file
446
rtv/terminal.py
Normal file
@@ -0,0 +1,446 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import codecs
|
||||
import curses
|
||||
import webbrowser
|
||||
import subprocess
|
||||
import curses.ascii
|
||||
from curses import textpad
|
||||
from contextlib import contextmanager
|
||||
from tempfile import NamedTemporaryFile
|
||||
|
||||
import six
|
||||
from kitchen.text.display import textual_width_chop
|
||||
|
||||
from .objects import LoadScreen, Color
|
||||
from .exceptions import EscapeInterrupt, ProgramError
|
||||
|
||||
|
||||
class Terminal(object):
|
||||
|
||||
MIN_HEIGHT = 10
|
||||
MIN_WIDTH = 20
|
||||
|
||||
# ASCII code
|
||||
ESCAPE = 27
|
||||
RETURN = 10
|
||||
|
||||
def __init__(self, stdscr, ascii=False):
|
||||
|
||||
self.stdscr = stdscr
|
||||
self.ascii = ascii
|
||||
self.loader = LoadScreen(self)
|
||||
self._display = None
|
||||
|
||||
@property
|
||||
def up_arrow(self):
|
||||
symbol = '^' if self.ascii else '▲'
|
||||
attr = curses.A_BOLD | Color.GREEN
|
||||
return symbol, attr
|
||||
|
||||
@property
|
||||
def down_arrow(self):
|
||||
symbol = 'v' if self.ascii else '▼'
|
||||
attr = curses.A_BOLD | Color.RED
|
||||
return symbol, attr
|
||||
|
||||
@property
|
||||
def neutral_arrow(self):
|
||||
symbol = 'o' if self.ascii else '•'
|
||||
attr = curses.A_BOLD
|
||||
return symbol, attr
|
||||
|
||||
@property
|
||||
def guilded(self):
|
||||
symbol = '*' if self.ascii else '✪'
|
||||
attr = curses.A_BOLD | Color.YELLOW
|
||||
return symbol, attr
|
||||
|
||||
@property
|
||||
def display(self):
|
||||
"""
|
||||
Use a number of methods to guess if the default webbrowser will open in
|
||||
the background as opposed to opening directly in the terminal.
|
||||
"""
|
||||
|
||||
if self._display is None:
|
||||
display = bool(os.environ.get("DISPLAY"))
|
||||
# Use the convention defined here to parse $BROWSER
|
||||
# https://docs.python.org/2/library/webbrowser.html
|
||||
console_browsers = ['www-browser', 'links', 'links2', 'elinks',
|
||||
'lynx', 'w3m']
|
||||
if "BROWSER" in os.environ:
|
||||
user_browser = os.environ["BROWSER"].split(os.pathsep)[0]
|
||||
if user_browser in console_browsers:
|
||||
display = False
|
||||
if webbrowser._tryorder:
|
||||
if webbrowser._tryorder[0] in console_browsers:
|
||||
display = False
|
||||
self._display = display
|
||||
return self._display
|
||||
|
||||
@staticmethod
|
||||
def flash():
|
||||
return curses.flash()
|
||||
|
||||
@staticmethod
|
||||
def addch(window, y, x, ch, attr):
|
||||
"""
|
||||
Curses addch() method that fixes a major bug in python 3.4.
|
||||
|
||||
See http://bugs.python.org/issue21088
|
||||
"""
|
||||
|
||||
if sys.version_info[:3] == (3, 4, 0):
|
||||
y, x = x, y
|
||||
|
||||
window.addch(y, x, ch, attr)
|
||||
|
||||
def getch(self):
|
||||
return self.stdscr.getch()
|
||||
|
||||
@staticmethod
|
||||
@contextmanager
|
||||
def suspend():
|
||||
"""
|
||||
Suspend curses in order to open another subprocess in the terminal.
|
||||
"""
|
||||
|
||||
try:
|
||||
curses.endwin()
|
||||
yield
|
||||
finally:
|
||||
curses.doupdate()
|
||||
|
||||
@contextmanager
|
||||
def no_delay(self):
|
||||
"""
|
||||
Temporarily turn off character delay mode. In this mode, getch will not
|
||||
block while waiting for input and will return -1 if no key has been
|
||||
pressed.
|
||||
"""
|
||||
|
||||
try:
|
||||
self.stdscr.nodelay(1)
|
||||
yield
|
||||
finally:
|
||||
self.stdscr.nodelay(0)
|
||||
|
||||
def get_arrow(self, likes):
|
||||
"""
|
||||
Curses does define constants for symbols (e.g. curses.ACS_BULLET).
|
||||
However, they rely on using the curses.addch() function, which has been
|
||||
found to be buggy and a general PITA to work with. By defining them as
|
||||
unicode points they can be added via the more reliable curses.addstr().
|
||||
http://bugs.python.org/issue21088
|
||||
"""
|
||||
|
||||
if likes is None:
|
||||
return self.neutral_arrow
|
||||
elif likes:
|
||||
return self.up_arrow
|
||||
else:
|
||||
return self.down_arrow
|
||||
|
||||
def clean(self, string, n_cols=None):
|
||||
"""
|
||||
Required reading!
|
||||
http://nedbatchelder.com/text/unipain.html
|
||||
|
||||
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 any of the code points are not valid ascii curses will
|
||||
throw a 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 curses, it will render correctly.
|
||||
|
||||
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 not be correct. If code points are passed to addnstr,
|
||||
curses will treat each code point as one character and will not account
|
||||
for wide 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:
|
||||
return ''
|
||||
|
||||
if self.ascii:
|
||||
if isinstance(string, six.binary_type):
|
||||
string = string.decode('utf-8')
|
||||
string = string.encode('ascii', 'replace')
|
||||
return string[:n_cols] if n_cols else string
|
||||
else:
|
||||
if n_cols:
|
||||
string = textual_width_chop(string, n_cols)
|
||||
if isinstance(string, six.text_type):
|
||||
string = string.encode('utf-8')
|
||||
return string
|
||||
|
||||
def add_line(self, window, text, row=None, col=None, attr=None):
|
||||
"""
|
||||
Unicode aware version of curses's built-in addnstr method.
|
||||
|
||||
Safely draws a line of text on the window starting at position
|
||||
(row, col). Checks the boundaries of the window and cuts off the text
|
||||
if it exceeds the length of the window.
|
||||
"""
|
||||
|
||||
# The following arg combos must be supported to conform with addnstr
|
||||
# (window, text)
|
||||
# (window, text, attr)
|
||||
# (window, text, row, col)
|
||||
# (window, text, row, col, attr)
|
||||
cursor_row, cursor_col = window.getyx()
|
||||
row = row if row is not None else cursor_row
|
||||
col = col if col is not None else cursor_col
|
||||
|
||||
max_rows, max_cols = window.getmaxyx()
|
||||
n_cols = max_cols - col - 1
|
||||
if n_cols <= 0:
|
||||
# Trying to draw outside of the screen bounds
|
||||
return
|
||||
|
||||
text = self.clean(text, n_cols)
|
||||
params = [] if attr is None else [attr]
|
||||
window.addstr(row, col, text, *params)
|
||||
|
||||
def show_notification(self, message, timeout=None):
|
||||
"""
|
||||
Overlay a message box on the center of the screen and wait for input.
|
||||
|
||||
Params:
|
||||
message (list or string): List of strings, one per line.
|
||||
timeout (float): Optional, maximum length of time that the message
|
||||
will be shown before disappearing.
|
||||
"""
|
||||
|
||||
if isinstance(message, six.string_types):
|
||||
message = [message]
|
||||
|
||||
n_rows, n_cols = self.stdscr.getmaxyx()
|
||||
|
||||
box_width = max(map(len, message)) + 2
|
||||
box_height = len(message) + 2
|
||||
|
||||
# Cut off the lines of the message that don't fit on the screen
|
||||
box_width = min(box_width, n_cols)
|
||||
box_height = min(box_height, n_rows)
|
||||
message = message[:box_height-2]
|
||||
|
||||
s_row = (n_rows - box_height) // 2
|
||||
s_col = (n_cols - box_width) // 2
|
||||
|
||||
window = curses.newwin(box_height, box_width, s_row, s_col)
|
||||
window.erase()
|
||||
window.border()
|
||||
|
||||
for index, line in enumerate(message, start=1):
|
||||
self.add_line(window, line, index, 1)
|
||||
window.refresh()
|
||||
|
||||
ch, start = -1, time.time()
|
||||
with self.no_delay():
|
||||
while timeout is None or time.time() - start < timeout:
|
||||
ch = self.getch()
|
||||
if ch != -1:
|
||||
break
|
||||
time.sleep(0.01)
|
||||
|
||||
window.clear()
|
||||
del window
|
||||
self.stdscr.touchwin()
|
||||
self.stdscr.refresh()
|
||||
|
||||
return ch
|
||||
|
||||
def open_browser(self, url):
|
||||
"""
|
||||
Open the given url using the default webbrowser. The preferred browser
|
||||
can specified with the $BROWSER environment variable. If not specified,
|
||||
python webbrowser will try to determine the default to use based on
|
||||
your system.
|
||||
|
||||
For browsers requiring an X display, we call
|
||||
webbrowser.open_new_tab(url) and redirect stdout/stderr to devnull.
|
||||
This is a workaround to stop firefox from spewing warning messages to
|
||||
the console. See http://bugs.python.org/issue22277 for a better
|
||||
description of the problem.
|
||||
|
||||
For console browsers (e.g. w3m), RTV will suspend and display the
|
||||
browser window within the same terminal. This mode is triggered either
|
||||
when
|
||||
|
||||
1. $BROWSER is set to a known console browser, or
|
||||
2. $DISPLAY is undefined, indicating that the terminal is running
|
||||
headless
|
||||
|
||||
There may be other cases where console browsers are opened (xdg-open?)
|
||||
but are not detected here.
|
||||
"""
|
||||
|
||||
if self.display:
|
||||
command = "import webbrowser; webbrowser.open_new_tab('%s')" % url
|
||||
args = [sys.executable, '-c', command]
|
||||
with open(os.devnull, 'ab+', 0) as null:
|
||||
subprocess.check_call(args, stdout=null, stderr=null)
|
||||
else:
|
||||
with self.suspend():
|
||||
webbrowser.open_new_tab(url)
|
||||
|
||||
def open_editor(self, data=''):
|
||||
"""
|
||||
Open a temporary file 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.
|
||||
"""
|
||||
|
||||
with NamedTemporaryFile(prefix='rtv-', suffix='.txt', mode='wb') as fp:
|
||||
fp.write(codecs.encode(data, 'utf-8'))
|
||||
fp.flush()
|
||||
editor = os.getenv('RTV_EDITOR') or os.getenv('EDITOR') or 'nano'
|
||||
|
||||
try:
|
||||
with self.suspend():
|
||||
subprocess.Popen([editor, fp.name]).wait()
|
||||
except OSError:
|
||||
raise ProgramError('Could not open file with %s' % editor)
|
||||
|
||||
# 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 text_input(self, window, allow_resize=False):
|
||||
"""
|
||||
Transform a window into a text box that will accept user input and loop
|
||||
until an escape sequence is entered.
|
||||
|
||||
If the escape key (27) is pressed, cancel the textbox and return None.
|
||||
Otherwise, the textbox will wait until it is full (^j, or a new line is
|
||||
entered on the bottom line) or the BEL key (^g) is pressed.
|
||||
"""
|
||||
|
||||
window.clear()
|
||||
|
||||
# Set cursor mode to 1 because 2 doesn't display on some terminals
|
||||
curses.curs_set(1)
|
||||
|
||||
# Keep insert_mode off to avoid the recursion error described here
|
||||
# http://bugs.python.org/issue13051
|
||||
textbox = textpad.Textbox(window)
|
||||
textbox.stripspaces = 0
|
||||
|
||||
def validate(ch):
|
||||
"Filters characters for special key sequences"
|
||||
if ch == self.ESCAPE:
|
||||
raise EscapeInterrupt()
|
||||
if (not allow_resize) and (ch == curses.KEY_RESIZE):
|
||||
raise EscapeInterrupt()
|
||||
# Fix backspace for iterm
|
||||
if ch == curses.ascii.DEL:
|
||||
ch = curses.KEY_BACKSPACE
|
||||
return ch
|
||||
|
||||
# Wrapping in an exception block so that we can distinguish when the
|
||||
# user hits the return character from when the user tries to back out
|
||||
# of the input.
|
||||
try:
|
||||
out = textbox.edit(validate=validate)
|
||||
if isinstance(out, six.binary_type):
|
||||
out = out.decode('utf-8')
|
||||
except EscapeInterrupt:
|
||||
out = None
|
||||
|
||||
curses.curs_set(0)
|
||||
return self.strip_textpad(out)
|
||||
|
||||
def prompt_input(self, prompt, key=False):
|
||||
"""
|
||||
Display a text prompt at the bottom of the screen.
|
||||
|
||||
Params:
|
||||
prompt (string): Text prompt that will be displayed
|
||||
key (bool): If true, grab a single keystroke instead of a full
|
||||
string. This can be faster than pressing enter for
|
||||
single key prompts (e.g. y/n?)
|
||||
"""
|
||||
|
||||
n_rows, n_cols = self.stdscr.getmaxyx()
|
||||
attr = curses.A_BOLD | Color.CYAN
|
||||
prompt = self.clean(prompt, n_cols - 1)
|
||||
window = self.stdscr.derwin(
|
||||
1, n_cols - len(prompt), n_rows - 1, len(prompt))
|
||||
window.attrset(attr)
|
||||
self.add_line(self.stdscr, prompt, n_rows-1, 0, attr)
|
||||
self.stdscr.refresh()
|
||||
if key:
|
||||
curses.curs_set(1)
|
||||
ch = self.getch()
|
||||
# We can't convert the character to unicode, because it may return
|
||||
# Invalid values for keys that don't map to unicode characters,
|
||||
# e.g. F1
|
||||
text = ch if ch != self.ESCAPE else None
|
||||
curses.curs_set(0)
|
||||
else:
|
||||
text = self.text_input(window)
|
||||
return text
|
||||
|
||||
def prompt_y_or_n(self, prompt):
|
||||
"""
|
||||
Wrapper around prompt_input for simple yes/no queries.
|
||||
"""
|
||||
|
||||
ch = self.prompt_input(prompt, key=True)
|
||||
if ch in (ord('Y'), ord('y')):
|
||||
return True
|
||||
elif ch in (ord('N'), ord('n'), None):
|
||||
return False
|
||||
else:
|
||||
self.flash()
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def strip_textpad(text):
|
||||
"""
|
||||
Attempt to intelligently strip excess whitespace from the output of a
|
||||
curses textpad.
|
||||
"""
|
||||
|
||||
if text is None:
|
||||
return text
|
||||
|
||||
# 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
|
||||
@@ -17,10 +17,12 @@ sys.path.insert(0, ROOT)
|
||||
import rtv
|
||||
from rtv import config
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
parser = config.build_parser()
|
||||
help = parser.format_help()
|
||||
help_sections = help.split('\n\n')
|
||||
help_text = parser.format_help()
|
||||
help_sections = help_text.split('\n\n')
|
||||
|
||||
data = {}
|
||||
print('Fetching version')
|
||||
@@ -53,7 +55,7 @@ def main():
|
||||
print('Fetching copyright')
|
||||
data['copyright'] = rtv.__copyright__
|
||||
# Escape dashes is all of the sections
|
||||
data = {k:v.replace('-', r'\-') for k,v in data.items()}
|
||||
data = {k: v.replace('-', r'\-') for k, v in data.items()}
|
||||
print('Reading from %s/rtv/templates/rtv.1.template' % ROOT)
|
||||
with open(os.path.join(ROOT, 'rtv/templates/rtv.1.template')) as fp:
|
||||
template = fp.read()
|
||||
|
||||
3
setup.py
3
setup.py
@@ -33,8 +33,7 @@ setuptools.setup(
|
||||
'Operating System :: POSIX',
|
||||
'Natural Language :: English',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Topic :: Terminals',
|
||||
'Topic :: Internet :: WWW/HTTP :: Dynamic Content :: Message Boards',
|
||||
'Topic :: Internet :: WWW/HTTP :: Dynamic Content :: News/Diary',
|
||||
|
||||
1384
tests/cassettes/test_content_submission_from_url.yaml
Normal file
1384
tests/cassettes/test_content_submission_from_url.yaml
Normal file
File diff suppressed because it is too large
Load Diff
171
tests/cassettes/test_content_submission_initialize.yaml
Normal file
171
tests/cassettes/test_content_submission_initialize.yaml
Normal file
@@ -0,0 +1,171 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Connection: [keep-alive]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://www.reddit.com/r/Python/comments/2xmo63/.json
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
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
|
||||
headers:
|
||||
CF-Cache-Status: [EXPIRED]
|
||||
CF-RAY: [24e5671acf611ea7-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Length: ['7630']
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:43:46 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Set-Cookie: ['__cfduid=dccd1bc55916440c54278def93fe461771449042226; expires=Thu,
|
||||
01-Dec-16 07:43:46 GMT; path=/; domain=.reddit.com; HttpOnly']
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
Vary: [Accept-Encoding]
|
||||
X-Moose: [majestic]
|
||||
access-control-allow-origin: ['*']
|
||||
access-control-expose-headers: ['X-Reddit-Tracking, X-Moose']
|
||||
cache-control: ['max-age=0, must-revalidate']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-reddit-tracking: ['https://pixel.redditmedia.com/pixel/of_destiny.png?v=4WAxfC8ixqjQvbb1X0%2BtFnNNghwyzsGSuyn6k3LYoBag9KyS4r1aE7zEdjNl2NW0xG4FZkQUvAg%3D']
|
||||
x-ua-compatible: [IE=edge]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
version: 1
|
||||
1685
tests/cassettes/test_content_submission_load_more_comments.yaml
Normal file
1685
tests/cassettes/test_content_submission_load_more_comments.yaml
Normal file
File diff suppressed because it is too large
Load Diff
99
tests/cassettes/test_content_subreddit.yaml
Normal file
99
tests/cassettes/test_content_subreddit.yaml
Normal file
@@ -0,0 +1,99 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Connection: [keep-alive]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://api.reddit.com/.json?limit=5
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
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
|
||||
PtmwQIZTG1WjPn78L15ilgJBPAAA
|
||||
headers:
|
||||
CF-RAY: [24e5678a0ffa11cb-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Length: ['3555']
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:44:04 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Set-Cookie: ['__cfduid=d59c0c7619ceea234dfd9ba30d14233cd1449042244; expires=Thu,
|
||||
01-Dec-16 07:44:04 GMT; path=/; domain=.reddit.com; HttpOnly']
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
Vary: [accept-encoding]
|
||||
X-Moose: [majestic]
|
||||
access-control-allow-origin: ['*']
|
||||
access-control-expose-headers: ['X-Reddit-Tracking, X-Moose']
|
||||
cache-control: ['max-age=0, must-revalidate']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-reddit-tracking: ['https://pixel.redditmedia.com/pixel/of_destiny.png?v=ppw10JokN%2F9DEfw0kHvlao9XX3HbNGIeOM0qSLUI2dYFrpGys5ppXWY6XhqrWAIQYk2FyqsY%2BNA%3D']
|
||||
x-ua-compatible: [IE=edge]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
version: 1
|
||||
2920
tests/cassettes/test_content_subreddit_from_name.yaml
Normal file
2920
tests/cassettes/test_content_subreddit_from_name.yaml
Normal file
File diff suppressed because it is too large
Load Diff
185
tests/cassettes/test_content_subreddit_initialize.yaml
Normal file
185
tests/cassettes/test_content_subreddit_initialize.yaml
Normal file
@@ -0,0 +1,185 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Connection: [keep-alive]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://api.reddit.com/r/python/top.json?limit=1024
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAD+hXlYC/+1dDXPbNtL+Kzi/N+ckY337S+ncZHpJ27ht0rx1rr13mhsWIiEJNkkw/LCidPrf
|
||||
330WoETJlqLIsmynvrlpLBIEdheLZxeLBfDHzrmOg52nYudHneU6HuzsiZ1A5pIe/bETmWAosyFe
|
||||
47k/1GGQqph+//bH5MO8M/NNYCKpUWQnU2G//macD02MEj0ZxyrwemN6FxdhSI8iFWjpqainUNMf
|
||||
f9KjrOilKgh0jhqmH6OuXH3IvWEehXj1jzD/6m+1mjh97v307beiVvvHIP8KDwN9IfxQZtk/3+1E
|
||||
wbud8nlS/pHlqYkH+JWHXwXpUzxrTB+K3IhEmSRUIh/KXARGBOpChSaJVJwLE4tfiXEzyoSMA3qV
|
||||
hGaMb37UcfHhqfgV38hUibEp0pkvM5UXSUYtSf88eyZemhHVrTJXUI5ruanRP2Jk0nMRGkP/0efq
|
||||
GZPHxL+L38X4NUwb1Z8TxlSEv0ikueXJ/hZvtE9dNSByTT5UqTgzPUG9KnwTKRAeETtChqmSwbgu
|
||||
/lXkAsUUMxHJeCzsZ33pqzyzMsErqk3omH7rTCQmy+viOxWrVIZEdl+JLC/6/br4qRfqgcy1ibM9
|
||||
Ykrin76MdDjeE/V6XZyQDOJ/yCj56n863a9QY66IHCIrl+dUS+EPhRRBKkk5fZGaIlfirMhyMVY5
|
||||
vpZhZkiy6Cuig7iSwh/KMFTxQNXFCyt+cK+n/TaVVUQ1VUXVoxZJKkPqmp6SqeyFVMn/qZwaGsoL
|
||||
aiTVKrBCyXWkiBfogAxHcuzk2aPOnWgDCJwyNNBUg84n/ZANSYJEcUnWpE8kCYoopkqtgJVIiH3R
|
||||
ahLTMs3qq2nEtzrN8j1oF1oqwkCcx8QX99+J8IuUBnIeOnXrjcXp6UsrJyJVzihuz3ywuk4vwlBE
|
||||
7hui7UJHe6LI8F0eFbZUMs4VUUu1sMj6IH0qpdqFzjSJVRSxzmtcUn1QfsEacgVn/OPUkNwmSpKx
|
||||
6k07ERxVOzHQ/b72i5BpGFDnMbWkZtSXbyeajX4mceOdSkn4ZkQcp+WQr6qk7Xn0QmqoYq1inzuG
|
||||
mEcLNJ7HeBUUfo4exqBlbVzEzQlJEHBGdKFXQAgrk/uSND8dW/JMnyoymZqMQLSM8W1SV/q0oPGF
|
||||
kqk4efGNe5iMaQikkR3LEkMWdcRKsRqSjkOv8ScNq5EYpDIZaj9rjHQwwAg/cYTRByzCtGAljEgr
|
||||
fep/wginKiOdD8V/an2TjmQasPJkdnAmZAH6BPHER2hGdVLxHMOYK7BDA0q1x9Ku9Ks5lwQLvQIo
|
||||
6ysxUk72JOSh7jMxsRrR+CNDFCswRg2ONOlkT/HIiQz17KT/F3XAKYpSj5EUIrDLjeiAVF33Mb6n
|
||||
EL/HqkIMkpISmWwSQFQchGCX+qev6WGi0khnmQU5orBGb0nDhiqWMaEfnmIERIaHQmzG9DEAcL4y
|
||||
a+5IsdK8kARhF/ShjknBwrJEQvAiBwpck0Sf18giqpgb5hZGJE8aHIsYp55lddCxNQg9glPxiyQN
|
||||
gGHrixfGp8Fge8CX1THwvtAEvH1YCtbXIb4nkZNo8lKbikwB8Lj6Sa0TUPNDUkLin+C6L9O6a4vf
|
||||
u7GF7rDjj0CSlC4D79QtpDjkmIzFL6/28HXoqLfK1DdhgPGLYTPEgI5z0j2qWAMm4hoh9oWWoTU1
|
||||
3NEADzIeQHGSpEVmxW0CC6jmRdKzBtuaa2vLF1hp/pvcEPzC36Wb8tp5KVV/Bq7MkyfWEXnyBMTc
|
||||
Jd8D/Nfof/j3CTsWT+6BO7G7HTfiCbyHJ/fEZ6j25H30DEA3uwG71vw/AbVPNmPrd69h40HXg0Gf
|
||||
Mei7mzfktve/dKttdemzTPTuX8w0Q0RL7TBsK/7IpkGGrBiQ7HMVeBmJZPqchJJ6qUroIUr/9l82
|
||||
ywR/yuO4xLQk+PL6odSp52y2e6E5ANIpPp51fbTcT03kubiIKzLQJAX8btIPmZLCX/DPPpkchZhK
|
||||
SPZ05okliSiTGWnItCZZkJ6laFB9GBaRRINzhGY+jRv62W7u44OEuu5iLuRCD1KvdVxpb6iDgGM6
|
||||
5YO4iDxSDCA8mm91j+lhTk32Yqk5+MIeTBmo8awU8gOv/X7YHOMdVam8kpiyWuAcM9ra3+82m4fd
|
||||
zlEdQqlI188yj2M381wvfk8DnoWEmqq9NxdVkrNST1VkLmTohFwRYA7vZqYo+nRaQGceoJ4e5GlR
|
||||
vrYScCUAKxI8QSiNtGHhoVEKtGG1pUFDwjPAN+UB+Eg3TewxOnqJIZ0Ye7nxAp0RiphRg9Uaw7JK
|
||||
WSwjyHcn73hTFfSJpYmYj7vd4/3WMYu5SLnrhnmeZE8bjdFoVLf9VyfSNknnTI/Njpf3hQT0EApU
|
||||
2Mh1HjIfZLCFbcraAjTlDIZtik2ca2pqdQhXH5mYTJOD/8d16wgTRoymVtK6OJdMOQOGk5lX5H4p
|
||||
t8PuoZNbYOOihSbLUOnmyATz4AEHxoq+OpKmhUrcSfCDhuifpJkrhFGDMxkPDJF8pnzurI0HU0vl
|
||||
r8xJbgVHL9rxPnO3JRwd1CLyFMc1f0j9ny3B06MWvtsMnB7ubRRMywf3FEWr7z8PRllZGnZweK0u
|
||||
ERESGSr4NFZO1GwGK7vN/f1Ot7sIKy+NwsZI9UIzaLSbrYNGoPxGs+WoqbW6tRlq1kbEF1yfaNW7
|
||||
4mdX4ZV41SUaDhztN4RXR60V4SqUvf1W3aS8kvRlwlRLN7fp7gVj0l7NU7V8nFgVWABUnTa+3AxQ
|
||||
AfMegGoDQAV14d86p+leUmRD+EwDmgsWPY/rOysQG0k9mgCpHs1lshVArFTCORBrHx8dW7+6AmIO
|
||||
wyZD01FTI3JqoAfhP0tPDfTUHD21WXrWhrHn09beUGtww77T+cuiJ9Ca+N62Jl6XrV2JceTLkjdr
|
||||
WbshjOu0V8S4PFXjYUHQln7h/thw2N0i0E3FugTi2piNbgjiunsPELcRiIOiNGisFUSB+pCEMuYg
|
||||
Pc0cvZDGKmSepGrool4roFupefMuWrt5fHAFus0OSOuTtdqNhAmtgYTaLAkEbaOajulpaNLrodsv
|
||||
zLaosI1AHdpEeK3S5pWwRq5bp+14uiFYax+vCGt3MGHnpaLJPhYXFq3K/YgId0ZzeixnDGUgpBik
|
||||
pkjQBzZEIINIx26l6RGiwgNjAuFg6LEYYZWACKUBpMKxSGSaI+gs04YvU9UvQhu1RZCWvlQIfSKe
|
||||
qRF8TAlxFq7zI05pA+8gjdx4G8z1TXyhY59XRhCEZ7qoi4sQgQxuy63gBKovsbRRBpipLSgXXv10
|
||||
yqFbG1F+bFcJ3pCSRvrc7AlEB2P9kdQiyYpch+IRwsx2zaFsiZciEImVOSGMEwMCsAFNORRJcCFf
|
||||
z5knVIb4L7HTJ6hnXcdCBFhkJkLdS2WqObovEcHFV74sJqsfhOH0oV3Ma0CW2ldY0bqg7khTk2bP
|
||||
OMlj3VXVqeaA+jugJmXs+l7rBJjYogLcjtvTGuaMYVtye75+rlM/VMEp7Ixa5voc4LvNuD6to70H
|
||||
32cD0XxWlsbQjDxWcI/GtcfDWcW+8qTHKGP9IEIZz6LMCg5QqYOXp3ftNeP561O6tms0C3eTxpaD
|
||||
L7yRjHBWRiXKlfhU5olgMRyImyMfIRsTGETPxIlbRpbcl4jz02MkKfAS+YDwE6i0KN5P/3NyvSkn
|
||||
7OD+OmHfEHcjhvsTslmcXcOZIDrzC15AF/YtrJCFdphHXsmWF0ZzJoF1xbG+zxbAWg8uEcMQSOSc
|
||||
sC0puEJnR6APdv16D23EWPBF7whSnlS9LzTMMWl33VEGCgbwvFmTpo1w9gXsBVQOK9GA0DQbC/zD
|
||||
X+UjrC31+4oJYZCV/lBRzQvcoDf0vYkRlNtD1sxMupzNJFJCZxlgBZYWmUmsvCOsvWNNPDVhyNwH
|
||||
F8aXyDexpbG0z4xD3VFLqkLJaScYFfEgH7q0ASXPY5Vl7GtcmPBC0TgDx9dKRvtr9zV6+FLH7t56
|
||||
h77j0bx1R6j4GLY5zWBLjpAcKWJpiQPU2mRaw4azGv6qDhArSYMTcZKxVx2oORke4lVC6j1tQyOf
|
||||
9nwmSjefydA92u+s5/msQeLaLg+3Uk8IO2YwixpCTh+mS5OGFvkiR82u4/SGfJHWqqkHBE7I2DIm
|
||||
quep9M8j0rv4yw55N/fPtwl5ZyYb9nUc62WwhzD1hlAPpD+A3gYi3tCTRmQ4F96LaJxK0lRPx551
|
||||
fjwkMNOrT+PdROPmZnqt5lGrPY93BHcLx2SD0xEcSbWSpOuh2Stbm3jlakMYyk3K3loGF2DYcavr
|
||||
qL8hDOuuCGF2WfPLxqzOvgq3iFm5jrwI8U+WygLMQnhpQ5iFnIYHzNoAZkFPGnmRxoj9pB5GS09m
|
||||
ysMcj3yglNS0X4SeTDSADIn/Xqu5AoKV+jeHYAct8mXmEQwe23RMNkiXrCq1uo1UJ+ajqRmZaV4r
|
||||
Wxu13hKL5dYmy2I5jf1Znb5F5OjrN9hlY/c2tJpIXLfhb98Eqi4e/cvERfbU7jZ5OYZg0bUiSGn0
|
||||
xI+vhLxus91pOnZvCPKOVoS8OxhBwh9SDFPVp7fOkOm6jgaFXbD9Zv/fR80P/6kn8cB+ubwMBzVk
|
||||
WfEVwZmTPqbu3EfU650PHTFINdYssBCBvSma5/RRuUeHJuUdXrKd7GzAIwjULuRi5k7WFZsSZCZ6
|
||||
yq3UiExir04POYF7eMNhTonQheJ9PSgHoqBXoAtU/Nb8L/2fCS8f2/1n+MDuTp8p3rqieBxcLte+
|
||||
VG6BcH4djq8VIlreN7yL5Q6J//epzH+vytk+Z+H+zgK1D1iKv4MJiOl27Hm7c84ZMFuy5z+oXi9c
|
||||
Nv9AyvKGbPlD9vNGgi6sIg1SdQ/RThMrm3VDVpsseaQ8rISUM5GeGsoL7bJclhvyUvHmDHnn8KC9
|
||||
ZuhlbULXNv7PMf5tWzYnByvnRmBzMu8tLmPTtq2rYzDdZvPoyLF8Q8b88P4a85davEnNIJXUyWm2
|
||||
J04mKx8Rr+zJANu1sTMTO18Zqw1vEebHY+zUDIxfQENsutRQ9jTH9fuM4EB7bAByX/IObol9jv45
|
||||
mYlIx9i9nRXphRrX62+HMj63n8U2Wo79hTAO//75R3sOzmULiD9m3JFSmW2tkYnPqW6r0r/+58cf
|
||||
/u/1d1O35NNludVL7snnmtlLYt69c+KFUFcTCUrekjEd2K2SWzKmX5+1OgeHS4zpBpcwUNWDMd2A
|
||||
MSUVaZA9co+wIhCbHBbKPVnFdDo1m09Yba2fr7EaWWsbyrdGPLf1YGXitcnF9MkCq9hq33CWxKoL
|
||||
E8QZ8SX97MsO7LUyyQHWLWHX/5ZS3Q58PWww2lBcD2rS4CHh5eQe0Lj0bFYU590rGvHkBlTXJoZq
|
||||
BUQrlW9+MtDe3z+8CtFmxmTj/f61wIlVUThuXI4Xp9M7bqYLEXzQC/nznAiSIk/DfSTDgcnsARLx
|
||||
Bb1maSHI9/d2vX3wagHE0WTHsXfLEHcHHf8Td5iRPdfnjeZ9+Jzra5sSnfoB+4k6FwOk8XIiDv0n
|
||||
llk+Rsf4CocdwRelXsmqKVOJyezxPzYFyFaL+nAgyAn5owmVUM8upVrxwSfwR90hKzNZ65/rcm+c
|
||||
wd3PZGz3CoZux/Q022d6i6ZnNNxftprUQeHNWB1U9WB1ru80Q0EaCQ8RDzpdGpfOwQq2pdSuOdvS
|
||||
7B51m1fZlhW85U/Qs7YluhoFro4bHXePm13HwQ2Zj879NR9f28ABS9bmZyOqIXqFDnMhcSgLgh2w
|
||||
7LbrgJj+UPnngFlewIvGoh/qwRDRjAWhHTgDQyIgdEh7aqjjR/AOOG4h8/LgKMmrAxqnfEU4Os8m
|
||||
s/LxWfQMi4Z8phhnovK6AlNig4lchaUE7gfVHClZ5q9j7xARevi02SRuXpkYBys6ssFveSLNCIGX
|
||||
IhH0ySEVpLZOCy5LbZg0ADH2/CtptyKBZBZgTF2BQxtxchambUNCRhUT3XXidiLQ6WFgEzFSxUyc
|
||||
cgmsyFy1tGRDRIVw0BZkJkVfjWCs0ow/IKMowyUSJ/4hAuISJwvyMYelCR27k9Cw3QdtVkKFyJ3N
|
||||
COlwHh/OslQx4baP/UKgZWAc6XyiHwnH9g9cwCLneFhmZqozyOdlv4+cwVxOt0YZanmMaDDzViRU
|
||||
BYq5HnGLUjhvKMTRY8qeFASa2Ag7peSzA4NrORebVX90wYOu35iuW/F+hmLvbkahd7ekyLfiVBYf
|
||||
Px5u83wn9HRCNfk6Z0/u5p3Lh1SljTiXrCgNqogUvmeCMfGGhQ5STAdwCGaQVnuAB48GsEcQscKu
|
||||
uokCzvudx63u/np+5zVIXdslPcF+EW5N2NaqyG83AzNuAtnQGiaXk10qKIT9NjjhmICypnlPjkUP
|
||||
h6cLfNujbsdJ6ZZ9279ATmfxUe9fbBEq+yE0yPCJQg8wuV2YrL7/XJwkLWnAyaL2LzTABQqVKiJd
|
||||
+6nxkrAY2FyLhFwKhIfVCqHfifLNwORxt3t0cHRl6LeS0FkqUqOk5FpI95t4DQ/yZ2buv6KsU9QE
|
||||
8ycsf8A15k/wS+vPUlnl5wZHb5Md8nGiAYMjTn2OZTVfdebcz+Mjx+ItY9wdnL+/1DhOY2/BNLA6
|
||||
F4MVsTF4kWk+gZtkrvoaGxoHyNmruv2RTUDIC+os8r3ddlAYMd4nSV1JneBOkxjXxa+T/eQ2d9Ae
|
||||
r65ze6sBsv9OBLUJmMIMB2dcB8gl5H0MyDtkgqzXnutgNhVyZlrrMh9mJn2VAqd+qpOcD71+ynPj
|
||||
SxkllWERBNS1JjBZZkLZINDQ2K7Ra0SSzEjacAeVZ42JnDyC2noynk072UCFzMyl3JRqP/LskTOj
|
||||
MR+adoydoAipedZRdhxJlGZyNEXB2XZ8+cF15shOxTiHdPee6ZGdMpZKg18zGrLBPmTxXLebbsmt
|
||||
GcptLivMSPjBt9m+b3ONKSBpSgP9C231pkMA495zA5MnVhiXq/g0TvPmfZrDcqPaGlO/zyZxbUfo
|
||||
jWtlDgD3KhCFKxYCdreu9GtaN7sfb1W/5i8wd7tofbCLmVsCubfPZYKjZc0SgNvgAeag/AHgrj95
|
||||
YzVpWDeiXKwMVHaem8STA0Vm2huqMMHkrcQSvUomYql983k7+63upaMz5xwS3ymSMY23Oh5/zVRc
|
||||
C7dOrdvmVjQce8KyJ8AePJQSw7Td6TNSIRFzNZJ1m82DjuPjhpBs1YPO7+QMbTYbH/fi8BIBe4g4
|
||||
WxniDpVMy0WmOrmKvE5ArzWfmKPzvYqr6A6umSwf4NY4e6INFndwoA71EO6F4krJx+b1Bs5Hxwvr
|
||||
NDfwOTZp2TMle+VtpS94dcme+If70VJc/hRBNTjF61qb1FgUu3dRBEJ8mvNbsltJss1U+R9MFpmP
|
||||
3y497BkfbMZsPZz1vBG/nJWkgXHk0ZDy+GS9WK2yuazUrnm71DrYXzfnZwkta1usfwEigBZldYvs
|
||||
UPvI0X1DdmjVw+jvoB2q2iB3dRtWvCXJNcvEUA+Ggr4sqBd8hYs2sTJlQney3DRrgOER+IYb4QrG
|
||||
WB0nWLuKxTfPX7z8RiS4LtEX52osHh3uk0PxAdWluAMKyRF8ABvnPWCtnbcuSZHxernLy9Shzse2
|
||||
DeD6TGap4cQvPowSl0UZd10f6R6SBXDQW0oGA9EkhJg52gJWIq4eWw8NmRPn+eBKzzRJFe45sDkT
|
||||
9qiBqqRoSGsYAFQ0Tvi2SMtuD6WjRHIbSvpDZpK8KAni7BZpKlwCJYm6vGYUd/6p2H2tBO4zxSHF
|
||||
yB/45z/r9sxMCGaaQKFCPrGPFwPd7aA9RbLhLkyxW4zjX3ycgu+bIs6f8XVblWucMRXNZB8LjSwv
|
||||
mYYaP3A5KewiCcHPS5EBgUQqR55lFZcO6phAF8F7DMNIUgOvxmJQqIyzMbiv8G9c3m4Y4U2R0L8R
|
||||
wv24HsyeKmytdHmPYb+IuRf5+GcGW3Q9q0h5WjNfmorV0or1V9Qtjx5bmbnO7DBfluDq8za7rxB2
|
||||
SDySthYx5OBua5zcqzpdjK00w16Azs7t8c1EzkQmUOWrQtGf6xHBG7pfgxHZ0FsZhLv3fPDtPgy6
|
||||
Gxx0t+OMd84+DLfojEfyfbLEEeeWNuOIP2z72owjDgVpTBTW/beEMdNbwSMvVWzOIz847h5eGSla
|
||||
wSNfhai1XfMpYtn/Tutd4KN3mi3HyQ356M177KOX5gcgOFI9cM3zHoerZ6aXCdyrarPHMuTkAmrI
|
||||
fFBpBmP7Pd7x/atIN+MrJFT09F1cu3pNHDrk4i64iAytNC6frTBfgn0dXrVeWLG9e3GgB3b/4Wyd
|
||||
cy+n1VUdqpnFf9ywDsPS0/AoiGs+d1pOA0pTq51FNg8YwiOjjHgndhn+/e+cEcwixWCOaYhAqovy
|
||||
Cab3WnMmNN+X7XNCX2Jyha2VIfWmxkC7VmTs5jt+WU9W3893GS+g36Dg0cDnSBnlb8f4t4qguUXj
|
||||
/608Ozej7HxZlvTDCtKd8wCgJXyhB85SkufKIw3EBR7RuFxPys51GK6QGD1RuPngXKd13FrTFfgs
|
||||
6tb2CTCeyySXAlcL9TGvc1BmG7h6r1632dzvOOZuyDu43ytJ72JBwIt5W4BNJ/iZFQSdiU54Pk7Y
|
||||
K7QV9AKLdoKrsICtdqcMZm+iUWRpA3PFsNHTcR1NINcqLWIs/+XGLNxn1nqMzCwsuLj7IfgGBlBj
|
||||
5+Ap/91PlcItV44yDiSwOQDao6AK6sLeYAUbkPCtyoImjiG2zIyGyONqPxYn2A2labJfppFiGw/X
|
||||
NWmQTxbIcYQhcrBo9D4TLgEso3+vY6E/T/guG2wdSePT+yXWWzHHxcdxj5MrtmSOaVzT/1udo+2Y
|
||||
44cJ+UbMMWtJg/SYrzy1AwYnw2cq48MPP22FJ3o2vz3p6Ohw4cX0y63wSkStbXzLQduwFXNaPt9f
|
||||
g6qvtLrH3aPjrmPmwerOW93vkc4radpjisEwX5hpnwHAq+eK4LzbyYbTMQL0cmAvP+Pc5teIcp/Z
|
||||
wPnrN69gHPoFb4go95aS12SZ2ROP7B846CmT4789XkDEt2QYXILyIjq/QbDc1eayHxCnVTbayiBP
|
||||
g7xCOLfI1JkQSd28pvS+MFSfdRjdkSjZ9AVnO3N6NpKJMgjjXKmkbNYZRJtVASW1oe+ZzbnlNVUc
|
||||
23ctINY9Y0zZjk64cPRBnqnia6R8KsZVu7UN+laR8Sa5TmmFDl/BQl2c8nx0soJGNpPzunnlpSoD
|
||||
FV9MfwooOE+7sVrDShCCNsd52bOWRrtGUbZtdwn3kBg/IT4fplC6ksXKcp5jvRRMRaKLIhkzEQYT
|
||||
253PAbkYoUlYKznwTyKOZJ6r9Jn4KSVtqDQJx2Ki36Ro+N1TSHz1MT8nZh2XALoi1vn1DrSeG3bs
|
||||
UG11jKHF6oDC72uPnnc7c6Pm3c7dHy3vdmZGybudcnTszowK8Eaj4d3OzY6C3aXa7/RkDVXfXUvF
|
||||
b8n3zc/bW/R9sWA8POPdhws83w0uReE+3QfPdwOeL+lIY4pE3hQcPSisFxM4nmGLfODFSbSKI+yU
|
||||
bt4RPmgfrbkytQ6Na/vFL1a2E4uc5MN9x+gNOcn3eeHKpc3iqJYLxkqZnYsTxPqRuiAQyhjjbBlO
|
||||
pHC38NlsBBcglIK6NBu6jcJuCaQ+k4s1PVmblICkkdsdNmhqkdfzdoglETRry3GyDWdPuIyO0CB3
|
||||
Y6881GcsFEk55HUKfENk6767D50TU/aQGeG+xnc5ojPS95F5gQ/QRwK967wLPJsw89Jm7zAEIyel
|
||||
LNAr8hxJNGyXlBMEDoB4xO3MJ8H5Q1z9zkX//fOPj8vVHwSAkL3DK0PMgeR7YLVfhDIV7wuFLZYn
|
||||
LPA+ib9XsCwTEFPgsAklvj8lf4w6JiFqnKOBx2S4kFJt25lJK0PIy6YjkeWdPakRRj/WRcSfIRDG
|
||||
OjA5EQgdsUcc+2HBu0ltO0y6TeP2Ebiqso0gFEqVOd/LaM/q4uswM3ypCZbESN9ynMvkn49Lb8lF
|
||||
1qiAj12rOZwwJ3uckuRaieA8cYqK7TXqDl+lOXrZNzWTBrg3Es2xprmFOx54Ltdm0pcum0VSk/0U
|
||||
LRrb2/RRIufOyFzkt/cUHBbWaFIdm4MET+bZzDjh847cR7wkOGavEv1OEB3qXtt2ZSrhillFclS4
|
||||
vvvum7eNNz+dvuWRqnAFjO2TwFQ7pDzLCLImsnCBJvlYYyRajd1JSiFpagHHrgFf0F4GM8mrdzqa
|
||||
lTty+dYZfc2F1BsDot3lAIROYx34ItBm9/ZRZncL6LL7xaPKpfnQEgjZvWHo2L05yLiladjZxTbv
|
||||
hAqLGLOaZSfBb3AF4iEhYEPzMFKSBg9Yj02K58bzKjMup1/z2+OPj7trXv20nJq151ZXWMxFk6hm
|
||||
09F+Q5OoVVcaaIyEMLYTROZL8zY+nyo1reKi3BJWHY34DLktYZWfFuN+/3g7UHW3Fku59VsDqur7
|
||||
z0UqUpEyOYjcIi+/8DL81DFcZ/ZKVwEtp2hzoHXc3W9dChOV+YhXjsVGu9k6aLTaIKmWmxqRVMsv
|
||||
aiCpViGpziNtvkPKwWbD7aKNbSfkYaHccihzuUvfkVv49hds+BiJk2ljC1DtsHnomLtlVLvJ0NBd
|
||||
gbKLpmpt82rtr1PClvT7V0VsPi7Bsw2GwHHy0d3BM/f+1hBtbdeLFaUR4JzFyZV9Hh/MSACHmUiZ
|
||||
80jDm88H+jS6TXRvLghO/zlaMxtkPSqvAjsnl+X49gLHMk4amuwk5ImZW93CHItPcqusmV2dr0mw
|
||||
fnDoGL8h5LvXQXHMzc8x09cZ8arTkCa5vQttCndYRYYkWZr5JsogUR5TbhJiGCIqwdseEWhITTxY
|
||||
FB18O1Rj9GdsCuwUpeLV1IZaoiu5CY8yKhQgiY9mzVlNjRW9V48nAQui0V18wxrR45iIrbia8pCd
|
||||
6yQZV1IlFpOGTP5+wYu9VFVP9oh/mWokI5VL1qZPk3mdIC4BfiUsbporHNlRWaOvtO5rrAq7ZOIK
|
||||
FeJfJE9ejC6rnu5J4ACcurpqG3QYmTSgPuHYF85pRzzFbZjEiSEcmeEqMCycHMt4Gz4t5TdpAWi1
|
||||
TDKRQSaljEgVygwDrsDXtb7esxXxQCwZJveIvR3mMzA0zar0u3uJ67b73LH885l4beriV2xWxVL2
|
||||
wiTeU7NXRuGIBL4tgFofcuRluuO1bI2jb9xl2IbCyrCcUVJq1ASEmSn4+aHdzQ0nF62dGztIdKAx
|
||||
8W7nemOFqmGxvNuZRIU3NRCo6pkBgFyMO6j4Jdu3ouVo/PoqPWWhqr+34/C22+/Ptujw/vDTC/WD
|
||||
TLFGvh1/t3W09+DwbsLhhaKUM3jqGfogHOMPO4A81vEVnNxS3+Y3Hh22W+s6uStTtrZj6ybuZeUV
|
||||
3GDQBBxf6cMilXvf8XVzPiy+kWTKMMDcu57qW/3F7z///H8bvnDk9sUAAA==
|
||||
headers:
|
||||
CF-RAY: [24e5676e721111c5-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Length: ['8479']
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:43:59 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Set-Cookie: ['__cfduid=d116e150f13bb5691702076a4b802a12a1449042239; expires=Thu,
|
||||
01-Dec-16 07:43:59 GMT; path=/; domain=.reddit.com; HttpOnly']
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
Vary: [accept-encoding]
|
||||
X-Moose: [majestic]
|
||||
access-control-allow-origin: ['*']
|
||||
access-control-expose-headers: ['X-Reddit-Tracking, X-Moose']
|
||||
cache-control: ['max-age=0, must-revalidate']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-reddit-tracking: ['https://pixel.redditmedia.com/pixel/of_destiny.png?v=bYdrnTcvwMFltcWm6CYr5oYjtOCh9D1teKC1G5fxD4ljTChBimcpnL8O5wbCSVp2gECe40qeDYU%3D']
|
||||
x-ua-compatible: [IE=edge]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
version: 1
|
||||
@@ -0,0 +1,31 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Connection: [keep-alive]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://api.reddit.com/r/invalidsubreddit7/top.json?limit=1024
|
||||
response:
|
||||
body: {string: "<html>\n <head>\n <title>302 Found</title>\n </head>\n <body>\n\
|
||||
\ <h1>302 Found</h1>\n The resource was found at <a href=\"https://api.reddit.com/subreddits/search.json?q=invalidsubreddit7\"\
|
||||
>https://api.reddit.com/subreddits/search.json?q=invalidsubreddit7</a>;\n\
|
||||
you should be redirected automatically.\n\n\n </body>\n</html>"}
|
||||
headers:
|
||||
CF-RAY: [24e5677aa46a1ea7-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Length: ['313']
|
||||
Content-Type: [text/html; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:44:02 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Set-Cookie: ['__cfduid=df3faf3331eff535be76b2182b9629ec01449042241; expires=Thu,
|
||||
01-Dec-16 07:44:01 GMT; path=/; domain=.reddit.com; HttpOnly']
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
X-Content-Type-Options: [nosniff]
|
||||
X-Moose: [majestic]
|
||||
cache-control: ['max-age=0, must-revalidate']
|
||||
location: ['https://api.reddit.com/subreddits/search.json?q=invalidsubreddit7']
|
||||
status: {code: 302, message: Found}
|
||||
version: 1
|
||||
1224
tests/cassettes/test_content_subreddit_load_more.yaml
Normal file
1224
tests/cassettes/test_content_subreddit_load_more.yaml
Normal file
File diff suppressed because it is too large
Load Diff
115
tests/cassettes/test_content_subreddit_me.yaml
Normal file
115
tests/cassettes/test_content_subreddit_me.yaml
Normal file
@@ -0,0 +1,115 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: !!binary |
|
||||
cmVkaXJlY3RfdXJpPWh0dHAlM0ElMkYlMkYxMjcuMC4wLjElM0E2NTAwMCUyRiZncmFudF90eXBl
|
||||
PXJlZnJlc2hfdG9rZW4mcmVmcmVzaF90b2tlbj0qKioqKioqKioq
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Authorization: ['**********']
|
||||
Connection: [keep-alive]
|
||||
Content-Length: ['122']
|
||||
Content-Type: [application/x-www-form-urlencoded]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: POST
|
||||
uri: https://api.reddit.com/api/v1/access_token/
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAAyWMuwrCQBBFf2XYWiGiBrH0UaQQG7UNm92Ljhp3mRmDQfx3iVYXDufct/MhQLW2
|
||||
dMPDLcnNZuWimEzm4zzfbKuwCNd2vdtvduWpOp5PdriPV5UbkfsFtfUZQ9XAC2TgeGUWaM3D27Qs
|
||||
ihE5DemvIbLRhdWS9MQRD2Prqe312QhiZFPKwp03tFD1ZygJfCRBTmKkvgPps2nZhtEg3IC6ZHCf
|
||||
L2mPdxLKAAAA
|
||||
headers:
|
||||
CF-RAY: [24e5680fc4e61ea7-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:44:25 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Set-Cookie: ['__cfduid=dfbfe38c66c15c17ee9c54aeac98936b11449042265; expires=Thu,
|
||||
01-Dec-16 07:44:25 GMT; path=/; domain=.reddit.com; HttpOnly']
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
X-Moose: [majestic]
|
||||
cache-control: ['max-age=0, must-revalidate']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Authorization: ['**********']
|
||||
Connection: [keep-alive]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://oauth.reddit.com/api/v1/me.json
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAA12QwWrDMBBEf0Xs2YTYuLTxZ5TSq5CtdbNE2k1XUhoI/fei1C5xjxp23ozmBkeX
|
||||
bHQUYDCzCwkbA+wiwmDgFb2n/IYaiV14J/xChcbApOgyehhM2/fd89O+Oxx2+8bAkTzaWSValVFy
|
||||
emBSsqmkM7K/G1d5QdmSpxXXtf2Kq9XE/68XiE/25DS6aqkQiRE5/2nVKxdU275sG3xI8Fslykao
|
||||
D/gMjGP9Zz23eD2TukzCMBguIdQ7HuVqJymcl7ha9YJKM6G3uBTOWnDFTHofMy33v1skEn4IWFao
|
||||
Id8/dZfx5JkBAAA=
|
||||
headers:
|
||||
CF-RAY: [24e5681c46d81e7d-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:44:27 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Set-Cookie: ['__cfduid=dcab57cae270bb2279df0c2f79274ab6a1449042267; expires=Thu,
|
||||
01-Dec-16 07:44:27 GMT; path=/; domain=.reddit.com; HttpOnly']
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
X-Moose: [majestic]
|
||||
cache-control: ['private, s-maxage=0, max-age=0, must-revalidate', 'max-age=0,
|
||||
must-revalidate']
|
||||
expires: ['-1']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-ratelimit-remaining: ['599.0']
|
||||
x-ratelimit-reset: ['333']
|
||||
x-ratelimit-used: ['1']
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Authorization: ['**********']
|
||||
Connection: [keep-alive]
|
||||
Cookie: [__cfduid=dcab57cae270bb2279df0c2f79274ab6a1449042267]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://oauth.reddit.com/user/RedditTerminalViewer/submitted.json?sort=new&t=all
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAA0XJwQ2AIAwF0FWaf2aCzuAGxgPaIo0ICeCJsLsXE48vb+CyLGDCYq1bPuEI4rsH
|
||||
08BdJPoWwZSflBzhiJakagbTujmCD13r37uGUvXznC840NRuXQAAAA==
|
||||
headers:
|
||||
CF-RAY: [24e56828075d1e7d-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:44:29 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
X-Moose: [majestic]
|
||||
cache-control: ['private, s-maxage=0, max-age=0, must-revalidate', 'max-age=0,
|
||||
must-revalidate']
|
||||
expires: ['-1']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-ratelimit-remaining: ['598.0']
|
||||
x-ratelimit-reset: ['331']
|
||||
x-ratelimit-used: ['2']
|
||||
x-reddit-tracking: ['https://pixel.redditmedia.com/pixel/of_destiny.png?v=lN0fUBJ0AoQtSibyqvlNLk6Y%2FE9HOSPds3XzLc0iY5w0g%2Fsj2RbviNMRCWuWOPbzHX2OfFnYnZUf7aVGbZweVdoFLCSciF2O']
|
||||
x-ua-compatible: [IE=edge]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
version: 1
|
||||
567
tests/cassettes/test_content_subreddit_multireddit.yaml
Normal file
567
tests/cassettes/test_content_subreddit_multireddit.yaml
Normal file
@@ -0,0 +1,567 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Connection: [keep-alive]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://api.reddit.com/r/python+linux/.json?limit=1024
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
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
|
||||
headers:
|
||||
CF-RAY: [24e567f7c9d60669-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Length: ['28537']
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:44:22 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Set-Cookie: ['__cfduid=d0550ee5a87863dc1a10e0f8979e182071449042261; expires=Thu,
|
||||
01-Dec-16 07:44:21 GMT; path=/; domain=.reddit.com; HttpOnly']
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
Vary: [accept-encoding]
|
||||
X-Moose: [majestic]
|
||||
access-control-allow-origin: ['*']
|
||||
access-control-expose-headers: ['X-Reddit-Tracking, X-Moose']
|
||||
cache-control: ['max-age=0, must-revalidate']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-reddit-tracking: ['https://pixel.redditmedia.com/pixel/of_destiny.png?v=H0HWQSiFoJkh3tOeOXSK7UwVX04aHyUzHsZP1ZjVw2j6e5F6XKWM3QO%2FCNEL%2B1n0XhTzPU23YLA%3D']
|
||||
x-ua-compatible: [IE=edge]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Connection: [keep-alive]
|
||||
Cookie: [__cfduid=d0550ee5a87863dc1a10e0f8979e182071449042261]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://api.reddit.com/r/a+b/.json?limit=1024
|
||||
response:
|
||||
body: {string: '{"error": 404}'}
|
||||
headers:
|
||||
CF-RAY: [24e568024a690669-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Length: ['14']
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:44:23 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
X-Moose: [majestic]
|
||||
access-control-allow-origin: ['*']
|
||||
access-control-expose-headers: ['X-Reddit-Tracking, X-Moose']
|
||||
cache-control: ['max-age=0, must-revalidate']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-reddit-tracking: ['https://pixel.redditmedia.com/pixel/of_destiny.png?v=ULKY%2F6vNuEtLn981hC1I4%2BUyQS3mH%2BNOiUBWiKMscP3Skg968mr%2Bbo2v0FeOuh75xsBg1Z0rmvY%3D']
|
||||
x-ua-compatible: [IE=edge]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 404, message: Not Found}
|
||||
version: 1
|
||||
2743
tests/cassettes/test_content_subscription.yaml
Normal file
2743
tests/cassettes/test_content_subscription.yaml
Normal file
File diff suppressed because it is too large
Load Diff
78
tests/cassettes/test_oauth_authorize.yaml
Normal file
78
tests/cassettes/test_oauth_authorize.yaml
Normal file
@@ -0,0 +1,78 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: !!binary |
|
||||
cmVkaXJlY3RfdXJpPWh0dHAlM0ElMkYlMkYxMjcuMC4wLjElM0E2NTAwMCUyRiZncmFudF90eXBl
|
||||
PXJlZnJlc2hfdG9rZW4mcmVmcmVzaF90b2tlbj0qKioqKioqKioq
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Authorization: ['**********']
|
||||
Connection: [keep-alive]
|
||||
Content-Length: ['122']
|
||||
Content-Type: [application/x-www-form-urlencoded]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: POST
|
||||
uri: https://api.reddit.com/api/v1/access_token/
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAAyWMTQuCUBBF/8rw1gVKJdGuoEWbIAj62MjTd6mh7MnMKGr038NaXTicc9/OlyVU
|
||||
c4sPvNyK3HyeLZM0XUxPcX3Y8fl63x9n2+bUPYdnurbNsMkubkLuF+TW1xirAl4gI0dXs0BzHt9m
|
||||
WZJMyGkZ/xoCG91ZLUpPHPAytp6qXptCEAKbUi3cekMFVX+DksAHEtRRjNS3IG2Kim0cLYULUBsN
|
||||
7vMF6g45KMoAAAA=
|
||||
headers:
|
||||
CF-RAY: [24e5687b6591012b-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:44:42 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Set-Cookie: ['__cfduid=dec07de54f5bcc3b4f496dc4a2de773461449042282; expires=Thu,
|
||||
01-Dec-16 07:44:42 GMT; path=/; domain=.reddit.com; HttpOnly']
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
X-Moose: [majestic]
|
||||
cache-control: ['max-age=0, must-revalidate']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Authorization: ['**********']
|
||||
Connection: [keep-alive]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://oauth.reddit.com/api/v1/me.json
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAA12QwWrDMBBEf0Xs2YTYuLTxZ5TSq5CtdbNE2k1XUhoI/fei1C5xjxp23ozmBkeX
|
||||
bHQUYDCzCwkbA+wiwmDgFb2n/IYaiV14J/xChcbApOgyehhM2/fd89O+Oxx2+8bAkTzaWSValVFy
|
||||
emBSsqmkM7K/G1d5QdmSpxXXtf2Kq9XE/68XiE/25DS6aqkQiRE5/2nVKxdU275sG3xI8Fslykao
|
||||
D/gMjGP9Zz23eD2TukzCMBguIdQ7HuVqJymcl7ha9YJKM6G3uBTOWnDFTHofMy33v1skEn4IWFao
|
||||
Id8/dZfx5JkBAAA=
|
||||
headers:
|
||||
CF-RAY: [24e56881fe1f2888-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:44:44 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Set-Cookie: ['__cfduid=d69b01e4f4e78cc083016d3974b83143f1449042283; expires=Thu,
|
||||
01-Dec-16 07:44:43 GMT; path=/; domain=.reddit.com; HttpOnly']
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
X-Moose: [majestic]
|
||||
cache-control: ['private, s-maxage=0, max-age=0, must-revalidate', 'max-age=0,
|
||||
must-revalidate']
|
||||
expires: ['-1']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-ratelimit-remaining: ['594.0']
|
||||
x-ratelimit-reset: ['316']
|
||||
x-ratelimit-used: ['6']
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
version: 1
|
||||
78
tests/cassettes/test_oauth_authorize_with_refresh_token.yaml
Normal file
78
tests/cassettes/test_oauth_authorize_with_refresh_token.yaml
Normal file
@@ -0,0 +1,78 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: !!binary |
|
||||
cmVkaXJlY3RfdXJpPWh0dHAlM0ElMkYlMkYxMjcuMC4wLjElM0E2NTAwMCUyRiZncmFudF90eXBl
|
||||
PXJlZnJlc2hfdG9rZW4mcmVmcmVzaF90b2tlbj0qKioqKioqKioq
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Authorization: ['**********']
|
||||
Connection: [keep-alive]
|
||||
Content-Length: ['122']
|
||||
Content-Type: [application/x-www-form-urlencoded]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: POST
|
||||
uri: https://api.reddit.com/api/v1/access_token/
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAAyWMwWrDMBAFf2XROQEbJ6bk2mI3EHBzbC9Gsl6TpTgSuxtTUfrvxenpwTDzfpyf
|
||||
JqiOlr5wcwdyu137VNX1ftsPL+m5Ow357fz+2eSu7oePvn3153B0G3KPYLSSsVYBXiArx3dmgY68
|
||||
vjVtVW3I6ZT+NUQ2urJakkIccTO2QnPRexDEyKaUhRdvmKHqL1AS+EiCnMRI/QLSe5jZ1tFJOICW
|
||||
ZHC/f8fwa1rKAAAA
|
||||
headers:
|
||||
CF-RAY: [24e5686084e51e7d-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:44:38 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Set-Cookie: ['__cfduid=d97dd5b69ae5538390d1e4ad773c2b04e1449042278; expires=Thu,
|
||||
01-Dec-16 07:44:38 GMT; path=/; domain=.reddit.com; HttpOnly']
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
X-Moose: [majestic]
|
||||
cache-control: ['max-age=0, must-revalidate']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Authorization: ['**********']
|
||||
Connection: [keep-alive]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://oauth.reddit.com/api/v1/me.json
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAA12QwWrDMBBEf0Xs2YTYuLTxZ5TSq5CtdbNE2k1XUhoI/fei1C5xjxp23ozmBkeX
|
||||
bHQUYDCzCwkbA+wiwmDgFb2n/IYaiV14J/xChcbApOgyehhM2/fd89O+Oxx2+8bAkTzaWSValVFy
|
||||
emBSsqmkM7K/G1d5QdmSpxXXtf2Kq9XE/68XiE/25DS6aqkQiRE5/2nVKxdU275sG3xI8Fslykao
|
||||
D/gMjGP9Zz23eD2TukzCMBguIdQ7HuVqJymcl7ha9YJKM6G3uBTOWnDFTHofMy33v1skEn4IWFao
|
||||
Id8/dZfx5JkBAAA=
|
||||
headers:
|
||||
CF-RAY: [24e5686b66a111a7-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:44:40 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Set-Cookie: ['__cfduid=dae4a6a80cbf9100c339be2eeca35c7bc1449042280; expires=Thu,
|
||||
01-Dec-16 07:44:40 GMT; path=/; domain=.reddit.com; HttpOnly']
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
X-Moose: [majestic]
|
||||
cache-control: ['private, s-maxage=0, max-age=0, must-revalidate', 'max-age=0,
|
||||
must-revalidate']
|
||||
expires: ['-1']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-ratelimit-remaining: ['595.0']
|
||||
x-ratelimit-reset: ['320']
|
||||
x-ratelimit-used: ['5']
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
version: 1
|
||||
115
tests/cassettes/test_page_authenticated.yaml
Normal file
115
tests/cassettes/test_page_authenticated.yaml
Normal file
@@ -0,0 +1,115 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: !!binary |
|
||||
cmVkaXJlY3RfdXJpPWh0dHAlM0ElMkYlMkYxMjcuMC4wLjElM0E2NTAwMCUyRiZncmFudF90eXBl
|
||||
PXJlZnJlc2hfdG9rZW4mcmVmcmVzaF90b2tlbj0qKioqKioqKioq
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Authorization: ['**********']
|
||||
Connection: [keep-alive]
|
||||
Content-Length: ['122']
|
||||
Content-Type: [application/x-www-form-urlencoded]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: POST
|
||||
uri: https://api.reddit.com/api/v1/access_token/
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAAyWM0UrDQBBFf2XY5wopJrH0sb5Iq2klgo9hs3ttB0k2zExCgvjvJfp04XDO/XE+
|
||||
BKg2lr7Ruz25PC932XZbPFT28nqy+uNp/joX/SU9V+Hw9tnPx/rdbcj9BY0tA9aqhRfIyjEPLNCG
|
||||
17fHMss25DSkfw2RjW6slmQhjuiNbaFu0bEVxMimNAhP3tBB1V+hJPCRBEMSI/UTSMe2Y1tHg3AL
|
||||
mpLB/d4BUZlC/MoAAAA=
|
||||
headers:
|
||||
CF-RAY: [24e568ab052f11c5-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:44:50 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Set-Cookie: ['__cfduid=d61ebc6182efabecafffcdd6f17eedc371449042290; expires=Thu,
|
||||
01-Dec-16 07:44:50 GMT; path=/; domain=.reddit.com; HttpOnly']
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
X-Moose: [majestic]
|
||||
cache-control: ['max-age=0, must-revalidate']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Authorization: ['**********']
|
||||
Connection: [keep-alive]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://oauth.reddit.com/api/v1/me.json
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAA12QwWrDMBBEf0Xs2YTYuLTxZ5TSq5CtdbNE2k1XUhoI/fei1C5xjxp23ozmBkeX
|
||||
bHQUYDCzCwkbA+wiwmDgFb2n/IYaiV14J/xChcbApOgyehhM2/fd89O+Oxx2+8bAkTzaWSValVFy
|
||||
emBSsqmkM7K/G1d5QdmSpxXXtf2Kq9XE/68XiE/25DS6aqkQiRE5/2nVKxdU275sG3xI8Fslykao
|
||||
D/gMjGP9Zz23eD2TukzCMBguIdQ7HuVqJymcl7ha9YJKM6G3uBTOWnDFTHofMy33v1skEn4IWFao
|
||||
Id8/dZfx5JkBAAA=
|
||||
headers:
|
||||
CF-RAY: [24e568b64b372888-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:44:52 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Set-Cookie: ['__cfduid=dbace6132db512e760a8db06293b0b3eb1449042292; expires=Thu,
|
||||
01-Dec-16 07:44:52 GMT; path=/; domain=.reddit.com; HttpOnly']
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
X-Moose: [majestic]
|
||||
cache-control: ['private, s-maxage=0, max-age=0, must-revalidate', 'max-age=0,
|
||||
must-revalidate']
|
||||
expires: ['-1']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-ratelimit-remaining: ['593.0']
|
||||
x-ratelimit-reset: ['308']
|
||||
x-ratelimit-used: ['7']
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Authorization: ['**********']
|
||||
Connection: [keep-alive]
|
||||
Cookie: [__cfduid=dbace6132db512e760a8db06293b0b3eb1449042292]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://oauth.reddit.com/message/unread/.json?limit=1
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAA0XJwQ2AIAwF0FWaf2aCzuAGxgPaIo0ICeCJsLsXE48vb+CyLGDCYq1bPuEI4rsH
|
||||
08BdJPoWwZSflBzhiJakagbTujmCD13r37uGUvXznC840NRuXQAAAA==
|
||||
headers:
|
||||
CF-RAY: [24e568c12b752888-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:44:54 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
X-Moose: [majestic]
|
||||
cache-control: ['private, s-maxage=0, max-age=0, must-revalidate', 'max-age=0,
|
||||
must-revalidate']
|
||||
expires: ['-1']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-ratelimit-remaining: ['592.0']
|
||||
x-ratelimit-reset: ['307']
|
||||
x-ratelimit-used: ['8']
|
||||
x-reddit-tracking: ['https://pixel.redditmedia.com/pixel/of_destiny.png?v=GiNcIZQuFEYlmAsD9NYmt4RztqwZuomXoyJ5rRJzDM8C62C1Y%2BLxZ8x02nBUmSzU1VDbrdFq0NTwBGV9usQLv1EScW%2By8pRf']
|
||||
x-ua-compatible: [IE=edge]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
version: 1
|
||||
248
tests/cassettes/test_submission_comment.yaml
Normal file
248
tests/cassettes/test_submission_comment.yaml
Normal file
@@ -0,0 +1,248 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: !!binary |
|
||||
cmVkaXJlY3RfdXJpPWh0dHAlM0ElMkYlMkYxMjcuMC4wLjElM0E2NTAwMCUyRiZncmFudF90eXBl
|
||||
PXJlZnJlc2hfdG9rZW4mcmVmcmVzaF90b2tlbj0qKioqKioqKioq
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Authorization: ['**********']
|
||||
Connection: [keep-alive]
|
||||
Content-Length: ['122']
|
||||
Content-Type: [application/x-www-form-urlencoded]
|
||||
Cookie: [__cfduid=d963647719488322ce24aaf79235c3d6e1449042300]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: POST
|
||||
uri: https://api.reddit.com/api/v1/access_token/
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAAyWMy2oCQRBFf6XotcIMURG3bmcjrrIa+nHRSjLTTVXZsRX/PUxcXTicc5/OxwjV
|
||||
0fI3Zncgt9ns9l3fb9fdfKxx/zvko38Mp+ErlL79nOr5+nlxK3L/wWitYKkCvEAWjnthgY68vH3s
|
||||
um5FTmN+a0hsdGW1LI04YTa2RlPTWxCkxKZUhKs3TFD1FygJfCJByWKkvoL0Fia2ZTQKB1DNBvf6
|
||||
A0kzhmXKAAAA
|
||||
headers:
|
||||
CF-RAY: [24e569196e1227fe-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:45:08 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
X-Moose: [majestic]
|
||||
cache-control: ['max-age=0, must-revalidate']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Authorization: ['**********']
|
||||
Connection: [keep-alive]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://oauth.reddit.com/api/v1/me.json
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAA12QwWrDMBBEf0Xs2YTYuLTxZ5TSq5CtdbNE2k1XUhoI/fei1C5xjxp23ozmBkeX
|
||||
bHQUYDCzCwkbA+wiwmDgFb2n/IYaiV14J/xChcbApOgyehhM2/fd89O+Oxx2+8bAkTzaWSValVFy
|
||||
emBSsqmkM7K/G1d5QdmSpxXXtf2Kq9XE/68XiE/25DS6aqkQiRE5/2nVKxdU275sG3xI8Fslykao
|
||||
D/gMjGP9Zz23eD2TukzCMBguIdQ7HuVqJymcl7ha9YJKM6G3uBTOWnDFTHofMy33v1skEn4IWFao
|
||||
Id8/dZfx5JkBAAA=
|
||||
headers:
|
||||
CF-RAY: [24e5692852e2288e-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:45:10 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Set-Cookie: ['__cfduid=dfdd374e9eea56b2249bf4ce8d4e817611449042310; expires=Thu,
|
||||
01-Dec-16 07:45:10 GMT; path=/; domain=.reddit.com; HttpOnly']
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
X-Moose: [majestic]
|
||||
cache-control: ['private, s-maxage=0, max-age=0, must-revalidate', 'max-age=0,
|
||||
must-revalidate']
|
||||
expires: ['-1']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-ratelimit-remaining: ['590.0']
|
||||
x-ratelimit-reset: ['290']
|
||||
x-ratelimit-used: ['10']
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Authorization: ['**********']
|
||||
Connection: [keep-alive]
|
||||
Cookie: [__cfduid=dfdd374e9eea56b2249bf4ce8d4e817611449042310]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://oauth.reddit.com/r/Python/comments/2xmo63/a_python_terminal_viewer_for_browsing_reddit/.json
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
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
|
||||
headers:
|
||||
CF-RAY: [24e56930d335288e-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Length: ['7632']
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:45:12 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
Vary: [accept-encoding]
|
||||
X-Moose: [majestic]
|
||||
cache-control: ['private, s-maxage=0, max-age=0, must-revalidate', 'max-age=0,
|
||||
must-revalidate']
|
||||
expires: ['-1']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-ratelimit-remaining: ['589.0']
|
||||
x-ratelimit-reset: ['289']
|
||||
x-ratelimit-used: ['11']
|
||||
x-reddit-tracking: ['https://pixel.redditmedia.com/pixel/of_destiny.png?v=Bzh2jK%2F5JKtFD80jsp5q7gytwuV0LY2xuBeEwR8znz4g%2FJqJKBsaRMA4%2BnJ49H71F%2B4ClKNNPbc%3D']
|
||||
x-ua-compatible: [IE=edge]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
version: 1
|
||||
249
tests/cassettes/test_submission_delete.yaml
Normal file
249
tests/cassettes/test_submission_delete.yaml
Normal file
@@ -0,0 +1,249 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: !!binary |
|
||||
cmVkaXJlY3RfdXJpPWh0dHAlM0ElMkYlMkYxMjcuMC4wLjElM0E2NTAwMCUyRiZncmFudF90eXBl
|
||||
PXJlZnJlc2hfdG9rZW4mcmVmcmVzaF90b2tlbj0qKioqKioqKioq
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Authorization: ['**********']
|
||||
Connection: [keep-alive]
|
||||
Content-Length: ['122']
|
||||
Content-Type: [application/x-www-form-urlencoded]
|
||||
Cookie: [__cfduid=d963647719488322ce24aaf79235c3d6e1449042300]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: POST
|
||||
uri: https://api.reddit.com/api/v1/access_token/
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAAyWMwYrCQBAFf6WZswvJbgxhby7KXoS9iNcwmXmsjcQZujshg/jvEj09KKre3fkQ
|
||||
oNpbuuLmvsk1TdtVdb39+Mn75fjXjeel7KZf5uYzWHvqjqk+uA25V9BbyVirAV4gK8eSWaA9r29f
|
||||
bVVtyGlIbw2RjS6slqQQR9yMrdBYdBoEMbIpZeHZG0ao+n8oCXwkQU5ipH4G6TSMbOtoEB5AczK4
|
||||
xxPWvTOCygAAAA==
|
||||
headers:
|
||||
CF-RAY: [24e5693f1554288e-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:45:14 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
X-Moose: [majestic]
|
||||
cache-control: ['max-age=0, must-revalidate']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Authorization: ['**********']
|
||||
Connection: [keep-alive]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://oauth.reddit.com/api/v1/me.json
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAA12QwWrDMBBEf0Xs2YTYuLTxZ5TSq5CtdbNE2k1XUhoI/fei1C5xjxp23ozmBkeX
|
||||
bHQUYDCzCwkbA+wiwmDgFb2n/IYaiV14J/xChcbApOgyehhM2/fd89O+Oxx2+8bAkTzaWSValVFy
|
||||
emBSsqmkM7K/G1d5QdmSpxXXtf2Kq9XE/68XiE/25DS6aqkQiRE5/2nVKxdU275sG3xI8Fslykao
|
||||
D/gMjGP9Zz23eD2TukzCMBguIdQ7HuVqJymcl7ha9YJKM6G3uBTOWnDFTHofMy33v1skEn4IWFao
|
||||
Id8/dZfx5JkBAAA=
|
||||
headers:
|
||||
CF-RAY: [24e5694ba1401ecb-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:45:16 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Set-Cookie: ['__cfduid=d106c081e048a4c399da689dddfb3797f1449042316; expires=Thu,
|
||||
01-Dec-16 07:45:16 GMT; path=/; domain=.reddit.com; HttpOnly']
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
X-Moose: [majestic]
|
||||
cache-control: ['private, s-maxage=0, max-age=0, must-revalidate', 'max-age=0,
|
||||
must-revalidate']
|
||||
expires: ['-1']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-ratelimit-remaining: ['588.0']
|
||||
x-ratelimit-reset: ['284']
|
||||
x-ratelimit-used: ['12']
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Authorization: ['**********']
|
||||
Connection: [keep-alive]
|
||||
Cookie: [__cfduid=d106c081e048a4c399da689dddfb3797f1449042316]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://oauth.reddit.com/r/Python/comments/2xmo63/a_python_terminal_viewer_for_browsing_reddit/.json
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
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
|
||||
AA==
|
||||
headers:
|
||||
CF-RAY: [24e5694e61591ecb-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Length: ['7639']
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:45:16 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
Vary: [accept-encoding]
|
||||
X-Moose: [majestic]
|
||||
cache-control: ['private, s-maxage=0, max-age=0, must-revalidate', 'max-age=0,
|
||||
must-revalidate']
|
||||
expires: ['-1']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-ratelimit-remaining: ['587.0']
|
||||
x-ratelimit-reset: ['284']
|
||||
x-ratelimit-used: ['13']
|
||||
x-reddit-tracking: ['https://pixel.redditmedia.com/pixel/of_destiny.png?v=2yjiYfnPd2byM5N5coy88KnkvDIRy87gGDPHOWbe%2FP5ePaWKOeJn3NNy5lf2rFhGOL1qr4VMvE4%3D']
|
||||
x-ua-compatible: [IE=edge]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
version: 1
|
||||
249
tests/cassettes/test_submission_edit.yaml
Normal file
249
tests/cassettes/test_submission_edit.yaml
Normal file
@@ -0,0 +1,249 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: !!binary |
|
||||
cmVkaXJlY3RfdXJpPWh0dHAlM0ElMkYlMkYxMjcuMC4wLjElM0E2NTAwMCUyRiZncmFudF90eXBl
|
||||
PXJlZnJlc2hfdG9rZW4mcmVmcmVzaF90b2tlbj0qKioqKioqKioq
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Authorization: ['**********']
|
||||
Connection: [keep-alive]
|
||||
Content-Length: ['122']
|
||||
Content-Type: [application/x-www-form-urlencoded]
|
||||
Cookie: [__cfduid=d963647719488322ce24aaf79235c3d6e1449042300]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: POST
|
||||
uri: https://api.reddit.com/api/v1/access_token/
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAAyWMsQrCQBAFf2W5WiFqDGqb0lYQq3DJPXSReMfuJvEU/12i1YNh5r2d7zqoNhbv
|
||||
eLgDubKsdsVqtV0iDedjf/GvNJzzaR/qqeZ1XW72084tyP2CxnLCXLXwApk5nokF2vD8tqmKYkFO
|
||||
u/jXENjoxmpRMnHAw9gy9VmHVhACm1ISHr2hh6q/QkngAwlSFCP1I0iHtmebRzvhFjRGg/t8AYx9
|
||||
Bq7KAAAA
|
||||
headers:
|
||||
CF-RAY: [24e569649f492816-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:45:20 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
X-Moose: [majestic]
|
||||
cache-control: ['max-age=0, must-revalidate']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Authorization: ['**********']
|
||||
Connection: [keep-alive]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://oauth.reddit.com/api/v1/me.json
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAA12QwWrDMBBEf0Xs2YTYuLTxZ5TSq5CtdbNE2k1XUhoI/fei1C5xjxp23ozmBkeX
|
||||
bHQUYDCzCwkbA+wiwmDgFb2n/IYaiV14J/xChcbApOgyehhM2/fd89O+Oxx2+8bAkTzaWSValVFy
|
||||
emBSsqmkM7K/G1d5QdmSpxXXtf2Kq9XE/68XiE/25DS6aqkQiRE5/2nVKxdU275sG3xI8Fslykao
|
||||
D/gMjGP9Zz23eD2TukzCMBguIdQ7HuVqJymcl7ha9YJKM6G3uBTOWnDFTHofMy33v1skEn4IWFao
|
||||
Id8/dZfx5JkBAAA=
|
||||
headers:
|
||||
CF-RAY: [24e56971a0f811a7-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:45:22 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Set-Cookie: ['__cfduid=d667511ab17e019fb769e680b9cab23071449042322; expires=Thu,
|
||||
01-Dec-16 07:45:22 GMT; path=/; domain=.reddit.com; HttpOnly']
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
X-Moose: [majestic]
|
||||
cache-control: ['private, s-maxage=0, max-age=0, must-revalidate', 'max-age=0,
|
||||
must-revalidate']
|
||||
expires: ['-1']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-ratelimit-remaining: ['586.0']
|
||||
x-ratelimit-reset: ['278']
|
||||
x-ratelimit-used: ['14']
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Authorization: ['**********']
|
||||
Connection: [keep-alive]
|
||||
Cookie: [__cfduid=d667511ab17e019fb769e680b9cab23071449042322]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://oauth.reddit.com/r/Python/comments/2xmo63/a_python_terminal_viewer_for_browsing_reddit/.json
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
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
|
||||
AA==
|
||||
headers:
|
||||
CF-RAY: [24e56974010611a7-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Length: ['7639']
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:45:22 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
Vary: [accept-encoding]
|
||||
X-Moose: [majestic]
|
||||
cache-control: ['private, s-maxage=0, max-age=0, must-revalidate', 'max-age=0,
|
||||
must-revalidate']
|
||||
expires: ['-1']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-ratelimit-remaining: ['585.0']
|
||||
x-ratelimit-reset: ['278']
|
||||
x-ratelimit-used: ['15']
|
||||
x-reddit-tracking: ['https://pixel.redditmedia.com/pixel/of_destiny.png?v=x7Hgtcci0o4lZvWWI68HSCYaPfSu8AoLGJymDPfSvXaVLHrXHOY314V%2FS7aiBGPeCNk%2FdOqa1ik%3D']
|
||||
x-ua-compatible: [IE=edge]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
version: 1
|
||||
339
tests/cassettes/test_submission_page_construct.yaml
Normal file
339
tests/cassettes/test_submission_page_construct.yaml
Normal file
@@ -0,0 +1,339 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Connection: [keep-alive]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://www.reddit.com/r/Python/comments/2xmo63/a_python_terminal_viewer_for_browsing_reddit.json
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
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
|
||||
headers:
|
||||
CF-Cache-Status: [EXPIRED]
|
||||
CF-RAY: [24e568cfaf801e77-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Length: ['7638']
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:44:56 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Set-Cookie: ['__cfduid=d74b6c79ddc42876e5cf9c8b498e180681449042296; expires=Thu,
|
||||
01-Dec-16 07:44:56 GMT; path=/; domain=.reddit.com; HttpOnly']
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
Vary: [Accept-Encoding]
|
||||
X-Moose: [majestic]
|
||||
access-control-allow-origin: ['*']
|
||||
access-control-expose-headers: ['X-Reddit-Tracking, X-Moose']
|
||||
cache-control: ['max-age=0, must-revalidate']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-reddit-tracking: ['https://pixel.redditmedia.com/pixel/of_destiny.png?v=C5eD%2BuAYBnEBQDixycLxKXNrKiWD6EyOaGFoO741H%2Bsy3o9p%2BEo2aG12QvmumoNBmrd07CEiKS4%3D']
|
||||
x-ua-compatible: [IE=edge]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Connection: [keep-alive]
|
||||
Cookie: [__cfduid=d74b6c79ddc42876e5cf9c8b498e180681449042296]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://www.reddit.com/r/Python/comments/2xmo63/a_python_terminal_viewer_for_browsing_reddit.json
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
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
|
||||
headers:
|
||||
CF-Cache-Status: [HIT]
|
||||
CF-RAY: [24e568dacfa21e77-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Length: ['7638']
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:44:58 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
Vary: [Accept-Encoding]
|
||||
X-Moose: [majestic]
|
||||
access-control-allow-origin: ['*']
|
||||
access-control-expose-headers: ['X-Reddit-Tracking, X-Moose']
|
||||
cache-control: ['max-age=0, must-revalidate']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-reddit-tracking: ['https://pixel.redditmedia.com/pixel/of_destiny.png?v=C5eD%2BuAYBnEBQDixycLxKXNrKiWD6EyOaGFoO741H%2Bsy3o9p%2BEo2aG12QvmumoNBmrd07CEiKS4%3D']
|
||||
x-ua-compatible: [IE=edge]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
version: 1
|
||||
340
tests/cassettes/test_submission_refresh.yaml
Normal file
340
tests/cassettes/test_submission_refresh.yaml
Normal file
@@ -0,0 +1,340 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Connection: [keep-alive]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://www.reddit.com/r/Python/comments/2xmo63.json
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
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
|
||||
sr/RAAA=
|
||||
headers:
|
||||
CF-Cache-Status: [EXPIRED]
|
||||
CF-RAY: [24e568e8522f11cb-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Length: ['7643']
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:45:00 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Set-Cookie: ['__cfduid=d963647719488322ce24aaf79235c3d6e1449042300; expires=Thu,
|
||||
01-Dec-16 07:45:00 GMT; path=/; domain=.reddit.com; HttpOnly']
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
Vary: [Accept-Encoding]
|
||||
X-Moose: [majestic]
|
||||
access-control-allow-origin: ['*']
|
||||
access-control-expose-headers: ['X-Reddit-Tracking, X-Moose']
|
||||
cache-control: ['max-age=0, must-revalidate']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-reddit-tracking: ['https://pixel.redditmedia.com/pixel/of_destiny.png?v=6lIDiYZTMgGMwfj8vOpnR3UYxhGFIIA9aSyQodiHoi%2B1VrKGsd9Ub3VR5u7SCY3M3kRksUJzoq4%3D']
|
||||
x-ua-compatible: [IE=edge]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Connection: [keep-alive]
|
||||
Cookie: [__cfduid=d963647719488322ce24aaf79235c3d6e1449042300]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://www.reddit.com/r/Python/comments/2xmo63/a_python_terminal_viewer_for_browsing_reddit/.json
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
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
|
||||
headers:
|
||||
CF-Cache-Status: [EXPIRED]
|
||||
CF-RAY: [24e568f3126611cb-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Length: ['7637']
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:45:02 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
Vary: [Accept-Encoding]
|
||||
X-Moose: [majestic]
|
||||
access-control-allow-origin: ['*']
|
||||
access-control-expose-headers: ['X-Reddit-Tracking, X-Moose']
|
||||
cache-control: ['max-age=0, must-revalidate']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-reddit-tracking: ['https://pixel.redditmedia.com/pixel/of_destiny.png?v=%2FI%2Bt4RjqqoY4TKM2Yom1PshslaAKuc8DxzlgITnz0cBvO7lleFhmymqgoKcNsIvy8kysr3udmUc%3D']
|
||||
x-ua-compatible: [IE=edge]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
version: 1
|
||||
77
tests/cassettes/test_submission_vote.yaml
Normal file
77
tests/cassettes/test_submission_vote.yaml
Normal file
@@ -0,0 +1,77 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: !!binary |
|
||||
cmVkaXJlY3RfdXJpPWh0dHAlM0ElMkYlMkYxMjcuMC4wLjElM0E2NTAwMCUyRiZncmFudF90eXBl
|
||||
PXJlZnJlc2hfdG9rZW4mcmVmcmVzaF90b2tlbj0qKioqKioqKioq
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Authorization: ['**********']
|
||||
Connection: [keep-alive]
|
||||
Content-Length: ['122']
|
||||
Content-Type: [application/x-www-form-urlencoded]
|
||||
Cookie: [__cfduid=d963647719488322ce24aaf79235c3d6e1449042300]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: POST
|
||||
uri: https://api.reddit.com/api/v1/access_token/
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAAyWMsQrCQBAFf2W5WiEhKmIpio0iCBZW4XL3MIvGC7tr8BD/XaLVg2HmvZ0PAaq1
|
||||
pRsebkVuNlssi7KcT9OhPLbnatNV23jfretLu7vl/cnrKbgJuV9QW+4xVg28QEaOV88CrXl8qxZF
|
||||
MSGnIf01RDZqWS1JJo54GFumLuuzEcTIptQLD97QQdVfoSTwkQR9EiP1A0ifTcc2jgbhBjQkg/t8
|
||||
AdrN+hbKAAAA
|
||||
headers:
|
||||
CF-RAY: [24e56900c7132888-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:45:04 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
X-Moose: [majestic]
|
||||
cache-control: ['max-age=0, must-revalidate']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Authorization: ['**********']
|
||||
Connection: [keep-alive]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://oauth.reddit.com/api/v1/me.json
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAA12QwWrDMBBEf0Xs2YTYuLTxZ5TSq5CtdbNE2k1XUhoI/fei1C5xjxp23ozmBkeX
|
||||
bHQUYDCzCwkbA+wiwmDgFb2n/IYaiV14J/xChcbApOgyehhM2/fd89O+Oxx2+8bAkTzaWSValVFy
|
||||
emBSsqmkM7K/G1d5QdmSpxXXtf2Kq9XE/68XiE/25DS6aqkQiRE5/2nVKxdU275sG3xI8Fslykao
|
||||
D/gMjGP9Zz23eD2TukzCMBguIdQ7HuVqJymcl7ha9YJKM6G3uBTOWnDFTHofMy33v1skEn4IWFao
|
||||
Id8/dZfx5JkBAAA=
|
||||
headers:
|
||||
CF-RAY: [24e5690dd21e2834-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:45:06 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Set-Cookie: ['__cfduid=d69f2e4e0722b7a1abec4c70f0a9db42d1449042306; expires=Thu,
|
||||
01-Dec-16 07:45:06 GMT; path=/; domain=.reddit.com; HttpOnly']
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
X-Moose: [majestic]
|
||||
cache-control: ['private, s-maxage=0, max-age=0, must-revalidate', 'max-age=0,
|
||||
must-revalidate']
|
||||
expires: ['-1']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-ratelimit-remaining: ['591.0']
|
||||
x-ratelimit-reset: ['294']
|
||||
x-ratelimit-used: ['9']
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
version: 1
|
||||
181
tests/cassettes/test_subreddit_open.yaml
Normal file
181
tests/cassettes/test_subreddit_open.yaml
Normal file
@@ -0,0 +1,181 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Connection: [keep-alive]
|
||||
Cookie: [__cfduid=dc348748e62d1cb7fa69806dc4fc6991c1449042326]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://www.reddit.com/r/Python/comments/3kestk/post_learning_questions_to_rlearnpython/.json
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
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
|
||||
9I6qwLQAAA==
|
||||
headers:
|
||||
CF-Cache-Status: [EXPIRED]
|
||||
CF-RAY: [24e569cb3b081213-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Length: ['8215']
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:45:36 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
Vary: [Accept-Encoding]
|
||||
X-Moose: [majestic]
|
||||
access-control-allow-origin: ['*']
|
||||
access-control-expose-headers: ['X-Reddit-Tracking, X-Moose']
|
||||
cache-control: ['max-age=0, must-revalidate']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-reddit-tracking: ['https://pixel.redditmedia.com/pixel/of_destiny.png?v=QCGURJLJvc4THMjF%2F%2Fvx844ubSVYYPJP%2BL%2BgFWarGm%2B2i2o4igfcGgf69xpsnqgo9A7iLkVNd9E%3D']
|
||||
x-ua-compatible: [IE=edge]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
version: 1
|
||||
2742
tests/cassettes/test_subreddit_open_subscriptions.yaml
Normal file
2742
tests/cassettes/test_subreddit_open_subscriptions.yaml
Normal file
File diff suppressed because it is too large
Load Diff
1247
tests/cassettes/test_subreddit_page_construct.yaml
Normal file
1247
tests/cassettes/test_subreddit_page_construct.yaml
Normal file
File diff suppressed because it is too large
Load Diff
2084
tests/cassettes/test_subreddit_post.yaml
Normal file
2084
tests/cassettes/test_subreddit_post.yaml
Normal file
File diff suppressed because it is too large
Load Diff
987
tests/cassettes/test_subreddit_prompt.yaml
Normal file
987
tests/cassettes/test_subreddit_prompt.yaml
Normal file
@@ -0,0 +1,987 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Connection: [keep-alive]
|
||||
Cookie: [__cfduid=dc348748e62d1cb7fa69806dc4fc6991c1449042326]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://api.reddit.com/top/.json?limit=1024
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
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
|
||||
headers:
|
||||
CF-RAY: [24e569bc645c1ea7-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Length: ['54243']
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:45:35 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
Vary: [accept-encoding]
|
||||
X-Moose: [majestic]
|
||||
access-control-allow-origin: ['*']
|
||||
access-control-expose-headers: ['X-Reddit-Tracking, X-Moose']
|
||||
cache-control: ['max-age=0, must-revalidate']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-reddit-tracking: ['https://pixel.redditmedia.com/pixel/of_destiny.png?v=g9dPP8ZNmgatiGERe2FC0zb0NCd%2F9Zd5mmZ%2BBnbF7NAeZQs%2B5wxtcOZxk0xvgAqYNNiS3%2BncbHY%3D']
|
||||
x-ua-compatible: [IE=edge]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
version: 1
|
||||
1223
tests/cassettes/test_subreddit_refresh.yaml
Normal file
1223
tests/cassettes/test_subreddit_refresh.yaml
Normal file
File diff suppressed because it is too large
Load Diff
298
tests/cassettes/test_subreddit_search.yaml
Normal file
298
tests/cassettes/test_subreddit_search.yaml
Normal file
@@ -0,0 +1,298 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Connection: [keep-alive]
|
||||
Cookie: [__cfduid=dc348748e62d1cb7fa69806dc4fc6991c1449042326]
|
||||
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
|
||||
method: GET
|
||||
uri: https://api.reddit.com/r/python/search/.json?restrict_sr=on&q=search+term
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
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
|
||||
+9//AwDluVgqLgEA
|
||||
headers:
|
||||
CF-RAY: [24e569afc5810294-SJC]
|
||||
Connection: [keep-alive]
|
||||
Content-Encoding: [gzip]
|
||||
Content-Length: ['14946']
|
||||
Content-Type: [application/json; charset=UTF-8]
|
||||
Date: ['Wed, 02 Dec 2015 07:45:32 GMT']
|
||||
Server: [cloudflare-nginx]
|
||||
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
|
||||
Vary: [accept-encoding]
|
||||
X-Moose: [majestic]
|
||||
access-control-allow-origin: ['*']
|
||||
access-control-expose-headers: ['X-Reddit-Tracking, X-Moose']
|
||||
cache-control: ['max-age=0, must-revalidate']
|
||||
x-content-type-options: [nosniff]
|
||||
x-frame-options: [SAMEORIGIN]
|
||||
x-reddit-tracking: ['https://pixel.redditmedia.com/pixel/of_destiny.png?v=onmi2HlExxjKlqXNeMPk33hyjq4k4I7oFbFEuSE%2FMBpTWdwvMnFq78kohzkD1RIsStVVrl7soRc%3D']
|
||||
x-ua-compatible: [IE=edge]
|
||||
x-xss-protection: [1; mode=block]
|
||||
status: {code: 200, message: OK}
|
||||
version: 1
|
||||
2743
tests/cassettes/test_subscription_close.yaml
Normal file
2743
tests/cassettes/test_subscription_close.yaml
Normal file
File diff suppressed because it is too large
Load Diff
2742
tests/cassettes/test_subscription_move.yaml
Normal file
2742
tests/cassettes/test_subscription_move.yaml
Normal file
File diff suppressed because it is too large
Load Diff
2743
tests/cassettes/test_subscription_page_construct.yaml
Normal file
2743
tests/cassettes/test_subscription_page_construct.yaml
Normal file
File diff suppressed because it is too large
Load Diff
2743
tests/cassettes/test_subscription_page_invalid.yaml
Normal file
2743
tests/cassettes/test_subscription_page_invalid.yaml
Normal file
File diff suppressed because it is too large
Load Diff
2742
tests/cassettes/test_subscription_refresh.yaml
Normal file
2742
tests/cassettes/test_subscription_refresh.yaml
Normal file
File diff suppressed because it is too large
Load Diff
2743
tests/cassettes/test_subscription_select.yaml
Normal file
2743
tests/cassettes/test_subscription_select.yaml
Normal file
File diff suppressed because it is too large
Load Diff
221
tests/conftest.py
Normal file
221
tests/conftest.py
Normal file
@@ -0,0 +1,221 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
import curses
|
||||
import logging
|
||||
from functools import partial
|
||||
|
||||
import praw
|
||||
import pytest
|
||||
from vcr import VCR
|
||||
from six.moves.urllib.parse import urlparse, parse_qs
|
||||
|
||||
from rtv.page import Page
|
||||
from rtv.oauth import OAuthHelper
|
||||
from rtv.config import Config
|
||||
from rtv.terminal import Terminal
|
||||
from rtv.subreddit import SubredditPage
|
||||
from rtv.submission import SubmissionPage
|
||||
from rtv.subscription import SubscriptionPage
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
|
||||
# Turn on autospec by default for convenience
|
||||
patch = partial(mock.patch, autospec=True)
|
||||
|
||||
# Turn on logging, but disable vcr from spamming
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
for name in ['vcr.matchers', 'vcr.stubs']:
|
||||
logging.getLogger(name).disabled = True
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
parser.addoption('--record-mode', dest='record_mode', default='none')
|
||||
parser.addoption('--refresh-token', dest='refresh_token',
|
||||
default='tests/refresh-token')
|
||||
|
||||
|
||||
class MockStdscr(mock.MagicMock):
|
||||
"""
|
||||
Extend mock to mimic curses.stdscr by keeping track of the terminal
|
||||
coordinates and allowing for the creation of subwindows with the same
|
||||
properties as stdscr.
|
||||
"""
|
||||
|
||||
def getyx(self):
|
||||
return self.y, self.x
|
||||
|
||||
def getmaxyx(self):
|
||||
return self.nlines, self.ncols
|
||||
|
||||
def derwin(self, *args):
|
||||
"""
|
||||
derwin()
|
||||
derwin(begin_y, begin_x)
|
||||
derwin(nlines, ncols, begin_y, begin_x)
|
||||
"""
|
||||
|
||||
if 'subwin' not in dir(self):
|
||||
self.attach_mock(MockStdscr(), 'subwin')
|
||||
|
||||
if len(args) == 0:
|
||||
nlines = self.nlines
|
||||
ncols = self.ncols
|
||||
elif len(args) == 2:
|
||||
nlines = self.nlines - args[0]
|
||||
ncols = self.ncols - args[1]
|
||||
else:
|
||||
nlines = min(self.nlines - args[2], args[0])
|
||||
ncols = min(self.ncols - args[3], args[1])
|
||||
|
||||
self.subwin.nlines = nlines
|
||||
self.subwin.ncols = ncols
|
||||
self.subwin.x = 0
|
||||
self.subwin.y = 0
|
||||
return self.subwin
|
||||
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
def vcr(request):
|
||||
|
||||
def auth_matcher(r1, r2):
|
||||
return (r1.headers.get('authorization') ==
|
||||
r2.headers.get('authorization'))
|
||||
|
||||
def uri_with_query_matcher(r1, r2):
|
||||
"URI matcher that allows query params to appear in any order"
|
||||
p1, p2 = urlparse(r1.uri), urlparse(r2.uri)
|
||||
return (p1[:3] == p2[:3] and
|
||||
parse_qs(p1.query, True) == parse_qs(p2.query, True))
|
||||
|
||||
# Use `none` to use the recorded requests, and `once` to delete existing
|
||||
# cassettes and re-record.
|
||||
record_mode = request.config.option.record_mode
|
||||
assert record_mode in ('once', 'none')
|
||||
|
||||
cassette_dir = os.path.join(os.path.dirname(__file__), 'cassettes')
|
||||
if not os.path.exists(cassette_dir):
|
||||
os.makedirs(cassette_dir)
|
||||
|
||||
# https://github.com/kevin1024/vcrpy/pull/196
|
||||
vcr = VCR(
|
||||
record_mode=request.config.option.record_mode,
|
||||
filter_headers=[('Authorization', '**********')],
|
||||
filter_post_data_parameters=[('refresh_token', '**********')],
|
||||
match_on=['method', 'uri_with_query', 'auth', 'body'],
|
||||
cassette_library_dir=cassette_dir)
|
||||
vcr.register_matcher('auth', auth_matcher)
|
||||
vcr.register_matcher('uri_with_query', uri_with_query_matcher)
|
||||
return vcr
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def refresh_token(request):
|
||||
if request.config.option.record_mode == 'none':
|
||||
return 'mock_refresh_token'
|
||||
else:
|
||||
return open(request.config.option.refresh_token).read()
|
||||
|
||||
|
||||
@pytest.yield_fixture()
|
||||
def config():
|
||||
with patch('rtv.config.Config.save_refresh_token'), \
|
||||
patch('rtv.config.Config.save_history'):
|
||||
yield Config()
|
||||
|
||||
|
||||
@pytest.yield_fixture()
|
||||
def stdscr():
|
||||
with patch('curses.initscr'), \
|
||||
patch('curses.echo'), \
|
||||
patch('curses.flash'), \
|
||||
patch('curses.endwin'), \
|
||||
patch('curses.newwin'), \
|
||||
patch('curses.noecho'), \
|
||||
patch('curses.cbreak'), \
|
||||
patch('curses.doupdate'), \
|
||||
patch('curses.nocbreak'), \
|
||||
patch('curses.curs_set'), \
|
||||
patch('curses.init_pair'), \
|
||||
patch('curses.color_pair'), \
|
||||
patch('curses.start_color'), \
|
||||
patch('curses.use_default_colors'):
|
||||
out = MockStdscr(nlines=40, ncols=80, x=0, y=0)
|
||||
curses.initscr.return_value = out
|
||||
curses.newwin.side_effect = lambda *args: out.derwin(*args)
|
||||
curses.color_pair.return_value = 23
|
||||
curses.ACS_VLINE = 0
|
||||
yield out
|
||||
|
||||
|
||||
@pytest.yield_fixture()
|
||||
def reddit(vcr, request):
|
||||
cassette_name = '%s.yaml' % request.node.name
|
||||
# Clear the cassette before running the test
|
||||
if request.config.option.record_mode == 'once':
|
||||
filename = os.path.join(vcr.cassette_library_dir, cassette_name)
|
||||
if os.path.exists(filename):
|
||||
os.remove(filename)
|
||||
|
||||
with vcr.use_cassette(cassette_name):
|
||||
with patch('praw.Reddit.get_access_information'):
|
||||
reddit = praw.Reddit(user_agent='rtv test suite',
|
||||
decode_html_entities=False,
|
||||
disable_update_check=True)
|
||||
if request.config.option.record_mode == 'none':
|
||||
# Turn off praw rate limiting when using cassettes
|
||||
reddit.config.api_request_delay = 0
|
||||
yield reddit
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def terminal(stdscr, config):
|
||||
term = Terminal(stdscr, ascii=config['ascii'])
|
||||
# Disable the python 3.4 addch patch so that the mock stdscr calls are
|
||||
# always made the same way
|
||||
term.addch = lambda window, *args: window.addch(*args)
|
||||
return term
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def oauth(reddit, terminal, config):
|
||||
return OAuthHelper(reddit, terminal, config)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def submission_page(reddit, terminal, config, oauth):
|
||||
submission = 'https://www.reddit.com/r/Python/comments/2xmo63'
|
||||
|
||||
with terminal.loader():
|
||||
page = SubmissionPage(reddit, terminal, config, oauth, url=submission)
|
||||
assert terminal.loader.exception is None
|
||||
page.draw()
|
||||
return page
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def subreddit_page(reddit, terminal, config, oauth):
|
||||
subreddit = '/r/python'
|
||||
|
||||
with terminal.loader():
|
||||
page = SubredditPage(reddit, terminal, config, oauth, subreddit)
|
||||
assert not terminal.loader.exception
|
||||
page.draw()
|
||||
return page
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def subscription_page(reddit, terminal, config, oauth, refresh_token):
|
||||
# Must be logged in to view your subscriptions
|
||||
config.refresh_token = refresh_token
|
||||
oauth.authorize()
|
||||
|
||||
with terminal.loader():
|
||||
page = SubscriptionPage(reddit, terminal, config, oauth)
|
||||
assert terminal.loader.exception is None
|
||||
page.draw()
|
||||
return page
|
||||
143
tests/test_config.py
Normal file
143
tests/test_config.py
Normal file
@@ -0,0 +1,143 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
import codecs
|
||||
from tempfile import NamedTemporaryFile
|
||||
|
||||
from rtv.config import Config
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
|
||||
|
||||
def test_config_interface():
|
||||
"Test setting and removing values"
|
||||
|
||||
config = Config(ascii=True)
|
||||
assert config['ascii'] is True
|
||||
config['ascii'] = False
|
||||
assert config['ascii'] is False
|
||||
config['ascii'] = True
|
||||
del config['ascii']
|
||||
assert config['ascii'] is False
|
||||
config.update(subreddit='cfb', new_value=2.0)
|
||||
assert config['subreddit'] == 'cfb'
|
||||
assert config['new_value'] == 2.0
|
||||
|
||||
|
||||
def test_config_from_args():
|
||||
"Ensure that command line arguments are parsed properly"
|
||||
|
||||
args = ['rtv',
|
||||
'-s', 'cfb',
|
||||
'-l', 'https://reddit.com/permalink •',
|
||||
'--log', 'logfile.log',
|
||||
'--ascii',
|
||||
'--non-persistent',
|
||||
'--clear-auth']
|
||||
|
||||
with mock.patch('sys.argv', ['rtv']):
|
||||
config = Config()
|
||||
config.from_args()
|
||||
assert config.config == {}
|
||||
|
||||
with mock.patch('sys.argv', args):
|
||||
config = Config()
|
||||
config.from_args()
|
||||
assert config['ascii'] is True
|
||||
assert config['subreddit'] == 'cfb'
|
||||
assert config['link'] == 'https://reddit.com/permalink •'
|
||||
assert config['log'] == 'logfile.log'
|
||||
assert config['ascii'] is True
|
||||
assert config['persistent'] is False
|
||||
assert config['clear_auth'] is True
|
||||
|
||||
|
||||
def test_config_from_file():
|
||||
"Ensure that config file arguments are parsed properly"
|
||||
|
||||
args = {
|
||||
'ascii': True,
|
||||
'persistent': False,
|
||||
'clear_auth': True,
|
||||
'log': 'logfile.log',
|
||||
'link': 'https://reddit.com/permalink •',
|
||||
'subreddit': 'cfb'}
|
||||
|
||||
with NamedTemporaryFile(suffix='.cfg') as fp:
|
||||
config = Config(config_file=fp.name)
|
||||
config.from_file()
|
||||
assert config.config == {}
|
||||
|
||||
rows = ['{0}={1}'.format(key, val) for key, val in args.items()]
|
||||
data = '\n'.join(['[rtv]'] + rows)
|
||||
fp.write(codecs.encode(data, 'utf-8'))
|
||||
fp.flush()
|
||||
config.from_file()
|
||||
assert config.config == args
|
||||
|
||||
|
||||
def test_config_refresh_token():
|
||||
"Ensure that the refresh token can be loaded, saved, and removed"
|
||||
|
||||
with NamedTemporaryFile(delete=False) as fp:
|
||||
config = Config(token_file=fp.name)
|
||||
|
||||
# Write a new token to the file
|
||||
config.refresh_token = 'secret_value'
|
||||
config.save_refresh_token()
|
||||
|
||||
# Load a valid token from the file
|
||||
config.refresh_token = None
|
||||
config.load_refresh_token()
|
||||
assert config.refresh_token == 'secret_value'
|
||||
|
||||
# Discard the token and delete the file
|
||||
config.delete_refresh_token()
|
||||
assert config.refresh_token is None
|
||||
assert not os.path.exists(fp.name)
|
||||
|
||||
# Saving should create a new file
|
||||
config.refresh_token = 'new_value'
|
||||
config.save_refresh_token()
|
||||
|
||||
# Which we can read back to verify
|
||||
config.refresh_token = None
|
||||
config.load_refresh_token()
|
||||
assert config.refresh_token == 'new_value'
|
||||
|
||||
# And delete again to clean up
|
||||
config.delete_refresh_token()
|
||||
assert not os.path.exists(fp.name)
|
||||
|
||||
# Loading from the non-existent file should return None
|
||||
config.refresh_token = 'secret_value'
|
||||
config.load_refresh_token()
|
||||
assert config.refresh_token is None
|
||||
|
||||
|
||||
def test_config_history():
|
||||
"Ensure that the history can be loaded and saved"
|
||||
|
||||
with NamedTemporaryFile(delete=False) as fp:
|
||||
config = Config(history_file=fp.name, history_size=3)
|
||||
|
||||
config.history.add('link1')
|
||||
config.history.add('link2')
|
||||
config.history.add('link3')
|
||||
config.history.add('link4')
|
||||
assert len(config.history) == 4
|
||||
|
||||
# Saving should only write the 3 most recent links
|
||||
config.save_history()
|
||||
config.load_history()
|
||||
assert len(config.history) == 3
|
||||
assert 'link1' not in config.history
|
||||
assert 'link4' in config.history
|
||||
|
||||
config.delete_history()
|
||||
assert len(config.history) == 0
|
||||
assert not os.path.exists(fp.name)
|
||||
287
tests/test_content.py
Normal file
287
tests/test_content.py
Normal file
@@ -0,0 +1,287 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import time
|
||||
from itertools import islice
|
||||
|
||||
import six
|
||||
import praw
|
||||
import pytest
|
||||
|
||||
from rtv.content import (
|
||||
Content, SubmissionContent, SubredditContent, SubscriptionContent)
|
||||
from rtv import exceptions
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
|
||||
|
||||
def test_content_humanize_timestamp():
|
||||
|
||||
timestamp = time.time() - 30
|
||||
assert Content.humanize_timestamp(timestamp) == '0min'
|
||||
assert Content.humanize_timestamp(timestamp, True) == 'moments ago'
|
||||
|
||||
timestamp = time.time() - 60 * 60 * 24 * 30.4 * 12
|
||||
assert Content.humanize_timestamp(timestamp) == '11month'
|
||||
assert Content.humanize_timestamp(timestamp, True) == '11 months ago'
|
||||
|
||||
timestamp = time.time() - 60 * 60 * 24 * 30.4 * 12 * 5
|
||||
assert Content.humanize_timestamp(timestamp) == '5yr'
|
||||
assert Content.humanize_timestamp(timestamp, True) == '5 years ago'
|
||||
|
||||
|
||||
def test_content_wrap_text():
|
||||
|
||||
text = 'four score\nand seven\n\n'
|
||||
assert Content.wrap_text(text, 6) == ['four', 'score', 'and', 'seven', '']
|
||||
assert Content.wrap_text(text, 15) == ['four score', 'and seven', '']
|
||||
assert Content.wrap_text('', 70) == []
|
||||
assert Content.wrap_text('\n\n\n\n', 70) == ['', '', '', '']
|
||||
|
||||
|
||||
def test_content_submission_initialize(reddit, terminal):
|
||||
|
||||
url = 'https://www.reddit.com/r/Python/comments/2xmo63/'
|
||||
submission = reddit.get_submission(url)
|
||||
content = SubmissionContent(submission, terminal.loader, indent_size=3,
|
||||
max_indent_level=4, order='top')
|
||||
assert content.indent_size == 3
|
||||
assert content.max_indent_level == 4
|
||||
assert content.order == 'top'
|
||||
assert content.name is not None
|
||||
|
||||
|
||||
def test_content_submission(reddit, terminal):
|
||||
|
||||
url = 'https://www.reddit.com/r/Python/comments/2xmo63/'
|
||||
submission = reddit.get_submission(url)
|
||||
content = SubmissionContent(submission, terminal.loader)
|
||||
|
||||
# Everything is loaded upon instantiation
|
||||
assert len(content._comment_data) == 45
|
||||
assert content.get(-1)['type'] == 'Submission'
|
||||
assert content.get(40)['type'] == 'Comment'
|
||||
|
||||
for data in content.iterate(-1, 1):
|
||||
assert all(k in data for k in ('object', 'n_rows', 'offset', 'type'))
|
||||
# All text should be converted to unicode by this point
|
||||
for val in data.values():
|
||||
assert not isinstance(val, six.binary_type)
|
||||
|
||||
# Out of bounds
|
||||
with pytest.raises(IndexError):
|
||||
content.get(-2)
|
||||
with pytest.raises(IndexError):
|
||||
content.get(50)
|
||||
|
||||
# Toggling the submission doesn't do anything
|
||||
content.toggle(-1)
|
||||
assert len(content._comment_data) == 45
|
||||
|
||||
# Toggling a comment hides its 3 children
|
||||
content.toggle(2)
|
||||
data = content.get(2)
|
||||
assert data['type'] == 'HiddenComment'
|
||||
assert data['count'] == 3
|
||||
assert data['level'] >= content.get(3)['level']
|
||||
assert len(content._comment_data) == 43
|
||||
|
||||
# Toggling again expands the children
|
||||
content.toggle(2)
|
||||
assert len(content._comment_data) == 45
|
||||
|
||||
|
||||
def test_content_submission_load_more_comments(reddit, terminal):
|
||||
|
||||
url = 'https://www.reddit.com/r/AskReddit/comments/2np694/'
|
||||
submission = reddit.get_submission(url)
|
||||
content = SubmissionContent(submission, terminal.loader)
|
||||
assert len(content._comment_data) == 391
|
||||
|
||||
# More comments load when toggled
|
||||
assert content.get(390)['type'] == 'MoreComments'
|
||||
content.toggle(390)
|
||||
assert len(content._comment_data) > 390
|
||||
assert content.get(390)['type'] == 'Comment'
|
||||
|
||||
|
||||
def test_content_submission_from_url(reddit, terminal):
|
||||
|
||||
url = 'https://www.reddit.com/r/AskReddit/comments/2np694/'
|
||||
SubmissionContent.from_url(reddit, url, terminal.loader)
|
||||
SubmissionContent.from_url(reddit, url, terminal.loader, order='new')
|
||||
|
||||
# Invalid sorting order doesn't raise an exception
|
||||
with terminal.loader():
|
||||
SubmissionContent.from_url(reddit, url, terminal.loader, order='fake')
|
||||
assert not terminal.loader.exception
|
||||
|
||||
# Invalid comment URL
|
||||
with terminal.loader():
|
||||
SubmissionContent.from_url(reddit, url[:-2], terminal.loader)
|
||||
assert isinstance(terminal.loader.exception, praw.errors.NotFound)
|
||||
|
||||
|
||||
def test_content_subreddit_initialize(reddit, terminal):
|
||||
|
||||
submissions = reddit.get_subreddit('python').get_top(limit=None)
|
||||
content = SubredditContent('python', submissions, terminal.loader, 'top')
|
||||
assert content.name == 'python'
|
||||
assert content.order == 'top'
|
||||
assert len(content._submission_data) == 1
|
||||
|
||||
|
||||
def test_content_subreddit_initialize_invalid(reddit, terminal):
|
||||
|
||||
submissions = reddit.get_subreddit('invalidsubreddit7').get_top(limit=None)
|
||||
with terminal.loader():
|
||||
SubredditContent('python', submissions, terminal.loader, 'top')
|
||||
assert isinstance(terminal.loader.exception, praw.errors.InvalidSubreddit)
|
||||
|
||||
|
||||
def test_content_subreddit(reddit, terminal):
|
||||
|
||||
submissions = reddit.get_front_page(limit=5)
|
||||
content = SubredditContent('front', submissions, terminal.loader)
|
||||
|
||||
# Submissions are loaded on demand, excluding for the first one
|
||||
assert len(content._submission_data) == 1
|
||||
assert content.get(0)['type'] == 'Submission'
|
||||
|
||||
for data in content.iterate(0, 1):
|
||||
assert all(k in data for k in ('object', 'n_rows', 'offset', 'type',
|
||||
'index', 'title', 'split_title'))
|
||||
# All text should be converted to unicode by this point
|
||||
for val in data.values():
|
||||
assert not isinstance(val, six.binary_type)
|
||||
|
||||
# Out of bounds
|
||||
with pytest.raises(IndexError):
|
||||
content.get(-1)
|
||||
with pytest.raises(IndexError):
|
||||
content.get(5)
|
||||
|
||||
|
||||
def test_content_subreddit_load_more(reddit, terminal):
|
||||
|
||||
submissions = reddit.get_front_page(limit=None)
|
||||
content = SubredditContent('front', submissions, terminal.loader)
|
||||
|
||||
assert content.get(50)['type'] == 'Submission'
|
||||
assert len(content._submission_data) == 51
|
||||
|
||||
for data in islice(content.iterate(0, 1, 70), 0, 50):
|
||||
assert all(k in data for k in ('object', 'n_rows', 'offset', 'type',
|
||||
'index', 'title', 'split_title'))
|
||||
# All text should be converted to unicode by this point
|
||||
for val in data.values():
|
||||
assert not isinstance(val, six.binary_type)
|
||||
|
||||
|
||||
def test_content_subreddit_from_name(reddit, terminal):
|
||||
|
||||
name = '/r/python'
|
||||
content = SubredditContent.from_name(reddit, name, terminal.loader)
|
||||
assert content.name == '/r/python'
|
||||
assert content.order is None
|
||||
|
||||
# Can submit without the /r/ and with the order in the name
|
||||
name = 'python/top/'
|
||||
content = SubredditContent.from_name(reddit, name, terminal.loader)
|
||||
assert content.name == '/r/python'
|
||||
assert content.order == 'top'
|
||||
|
||||
# Explicit order trumps implicit
|
||||
name = '/r/python/top'
|
||||
content = SubredditContent.from_name(
|
||||
reddit, name, terminal.loader, order='new')
|
||||
assert content.name == '/r/python'
|
||||
assert content.order == 'new'
|
||||
|
||||
# Invalid order raises an exception
|
||||
name = '/r/python/fake'
|
||||
with terminal.loader():
|
||||
SubredditContent.from_name(reddit, name, terminal.loader)
|
||||
assert isinstance(terminal.loader.exception, exceptions.SubredditError)
|
||||
|
||||
# Front page alias
|
||||
name = '/r/front/rising'
|
||||
content = SubredditContent.from_name(reddit, name, terminal.loader)
|
||||
assert content.name == '/r/front'
|
||||
assert content.order == 'rising'
|
||||
|
||||
# Queries
|
||||
SubredditContent.from_name(reddit, 'front', terminal.loader, query='pea')
|
||||
SubredditContent.from_name(reddit, 'python', terminal.loader, query='pea')
|
||||
|
||||
|
||||
def test_content_subreddit_multireddit(reddit, terminal):
|
||||
|
||||
name = '/r/python+linux'
|
||||
content = SubredditContent.from_name(reddit, name, terminal.loader)
|
||||
assert content.name == '/r/python+linux'
|
||||
|
||||
# Invalid multireddit
|
||||
name = '/r/a+b'
|
||||
with terminal.loader():
|
||||
SubredditContent.from_name(reddit, name, terminal.loader)
|
||||
assert isinstance(terminal.loader.exception, praw.errors.NotFound)
|
||||
|
||||
|
||||
def test_content_subreddit_me(reddit, oauth, refresh_token, terminal):
|
||||
|
||||
# Not logged in
|
||||
with terminal.loader():
|
||||
SubredditContent.from_name(reddit, '/r/me', terminal.loader)
|
||||
assert isinstance(terminal.loader.exception, exceptions.AccountError)
|
||||
|
||||
# Logged in
|
||||
oauth.config.refresh_token = refresh_token
|
||||
oauth.authorize()
|
||||
with terminal.loader():
|
||||
SubredditContent.from_name(reddit, 'me', terminal.loader)
|
||||
|
||||
# If there is no submitted content, an error should be raised
|
||||
if terminal.loader.exception:
|
||||
assert isinstance(terminal.loader.exception, exceptions.SubredditError)
|
||||
|
||||
|
||||
def test_content_subscription(reddit, oauth, refresh_token, terminal):
|
||||
|
||||
# Not logged in
|
||||
with terminal.loader():
|
||||
SubscriptionContent.from_user(reddit, terminal.loader)
|
||||
assert isinstance(
|
||||
terminal.loader.exception, praw.errors.LoginOrScopeRequired)
|
||||
|
||||
# Logged in
|
||||
oauth.config.refresh_token = refresh_token
|
||||
oauth.authorize()
|
||||
with terminal.loader():
|
||||
content = SubscriptionContent.from_user(reddit, terminal.loader)
|
||||
assert terminal.loader.exception is None
|
||||
|
||||
# These are static
|
||||
assert content.name == 'Subscriptions'
|
||||
assert content.order is None
|
||||
|
||||
# Validate content
|
||||
for data in content.iterate(0, 1, 70):
|
||||
assert all(k in data for k in ('object', 'n_rows', 'offset', 'type',
|
||||
'title', 'split_title'))
|
||||
# All text should be converted to unicode by this point
|
||||
for val in data.values():
|
||||
assert not isinstance(val, six.binary_type)
|
||||
|
||||
|
||||
def test_content_subscription_empty(terminal):
|
||||
|
||||
# Simulate an empty subscription generator
|
||||
subscriptions = iter([])
|
||||
|
||||
with terminal.loader():
|
||||
SubscriptionContent(subscriptions, terminal.loader)
|
||||
assert isinstance(terminal.loader.exception, exceptions.SubscriptionError)
|
||||
164
tests/test_oauth.py
Normal file
164
tests/test_oauth.py
Normal file
@@ -0,0 +1,164 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
|
||||
from tornado.web import Application
|
||||
from tornado.testing import AsyncHTTPTestCase
|
||||
from praw.errors import OAuthException
|
||||
|
||||
from rtv.oauth import OAuthHelper, OAuthHandler
|
||||
from rtv.config import TEMPLATE
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
|
||||
|
||||
class TestAuthHandler(AsyncHTTPTestCase):
|
||||
|
||||
def get_app(self):
|
||||
self.params = {}
|
||||
handler = [('/', OAuthHandler, {'params': self.params})]
|
||||
return Application(handler, template_path=TEMPLATE)
|
||||
|
||||
def test_no_callback(self):
|
||||
resp = self.fetch('/')
|
||||
assert resp.code == 200
|
||||
assert self.params['error'] is None
|
||||
assert 'Wait...' in resp.body.decode()
|
||||
|
||||
def test_access_denied(self):
|
||||
resp = self.fetch('/?error=access_denied')
|
||||
assert resp.code == 200
|
||||
assert self.params['error'] == 'access_denied'
|
||||
assert 'was denied access' in resp.body.decode()
|
||||
|
||||
def test_error(self):
|
||||
resp = self.fetch('/?error=fake')
|
||||
assert resp.code == 200
|
||||
assert self.params['error'] == 'fake'
|
||||
assert 'fake' in resp.body.decode()
|
||||
|
||||
def test_success(self):
|
||||
resp = self.fetch('/?state=fake_state&code=fake_code')
|
||||
assert resp.code == 200
|
||||
assert self.params['error'] is None
|
||||
assert self.params['state'] == 'fake_state'
|
||||
assert self.params['code'] == 'fake_code'
|
||||
assert 'Access Granted' in resp.body.decode()
|
||||
|
||||
|
||||
def test_oauth_terminal_non_mobile_authorize(reddit, terminal, config):
|
||||
|
||||
# Should direct to the desktop version if using a graphical browser
|
||||
reddit.config.API_PATHS['authorize'] = 'api/v1/authorize/'
|
||||
terminal._display = True
|
||||
oauth = OAuthHelper(reddit, terminal, config)
|
||||
assert '.compact' not in oauth.reddit.config.API_PATHS['authorize']
|
||||
|
||||
|
||||
def test_oauth_terminal_mobile_authorize(reddit, terminal, config):
|
||||
|
||||
# Should direct to the mobile version if using a terminal browser
|
||||
reddit.config.API_PATHS['authorize'] = 'api/v1/authorize/'
|
||||
terminal._display = False
|
||||
oauth = OAuthHelper(reddit, terminal, config)
|
||||
assert '.compact' in oauth.reddit.config.API_PATHS['authorize']
|
||||
|
||||
|
||||
def test_oauth_authorize_with_refresh_token(oauth, stdscr, refresh_token):
|
||||
|
||||
oauth.config.refresh_token = refresh_token
|
||||
oauth.authorize()
|
||||
assert oauth.http_server is None
|
||||
|
||||
# We should be able to handle an oauth failure
|
||||
with mock.patch.object(oauth.reddit, 'refresh_access_information'):
|
||||
exception = OAuthException('', '')
|
||||
oauth.reddit.refresh_access_information.side_effect = exception
|
||||
oauth.authorize()
|
||||
message = 'Invalid OAuth data'.encode('utf-8')
|
||||
stdscr.derwin().addstr.assert_called_with(1, 1, message)
|
||||
assert oauth.http_server is None
|
||||
|
||||
|
||||
def test_oauth_authorize(oauth, reddit, stdscr, refresh_token):
|
||||
|
||||
# Because we use `from .helpers import open_browser` we have to patch the
|
||||
# function in the destination oauth module and not the helpers module
|
||||
with mock.patch('uuid.UUID.hex', new_callable=mock.PropertyMock) as uuid, \
|
||||
mock.patch('rtv.terminal.Terminal.open_browser') as open_browser, \
|
||||
mock.patch('rtv.oauth.ioloop') as ioloop, \
|
||||
mock.patch('rtv.oauth.httpserver'), \
|
||||
mock.patch.object(oauth.reddit, 'user'), \
|
||||
mock.patch('time.sleep'):
|
||||
io = ioloop.IOLoop.current.return_value
|
||||
|
||||
# Valid authorization
|
||||
oauth.term._display = False
|
||||
params = {'state': 'uniqueid', 'code': 'secretcode', 'error': None}
|
||||
uuid.return_value = params['state']
|
||||
io.start.side_effect = lambda *_: oauth.params.update(**params)
|
||||
|
||||
oauth.authorize()
|
||||
assert not open_browser.called
|
||||
oauth.reddit.get_access_information.assert_called_with(
|
||||
reddit, params['code'])
|
||||
assert oauth.config.refresh_token is not None
|
||||
assert oauth.config.save_refresh_token.called
|
||||
stdscr.reset_mock()
|
||||
oauth.reddit.get_access_information.reset_mock()
|
||||
oauth.config.save_refresh_token.reset_mock()
|
||||
oauth.http_server = None
|
||||
|
||||
# The next authorization should skip the oauth process
|
||||
oauth.config.refresh_token = refresh_token
|
||||
oauth.authorize()
|
||||
assert oauth.reddit.user is not None
|
||||
assert oauth.http_server is None
|
||||
stdscr.reset_mock()
|
||||
|
||||
# Invalid state returned
|
||||
params = {'state': 'uniqueid', 'code': 'secretcode', 'error': None}
|
||||
oauth.config.refresh_token = None
|
||||
uuid.return_value = 'invalidcode'
|
||||
oauth.authorize()
|
||||
error_message = 'UUID mismatch'.encode('utf-8')
|
||||
stdscr.subwin.addstr.assert_any_call(1, 1, error_message)
|
||||
|
||||
# Valid authorization, terminal browser
|
||||
oauth.term._display = True
|
||||
params = {'state': 'uniqueid', 'code': 'secretcode', 'error': None}
|
||||
uuid.return_value = params['state']
|
||||
io.start.side_effect = lambda *_: oauth.params.update(**params)
|
||||
|
||||
oauth.authorize()
|
||||
assert open_browser.called
|
||||
oauth.reddit.get_access_information.assert_called_with(
|
||||
reddit, params['code'])
|
||||
assert oauth.config.refresh_token is not None
|
||||
assert oauth.config.save_refresh_token.called
|
||||
stdscr.reset_mock()
|
||||
oauth.reddit.get_access_information.reset_mock()
|
||||
oauth.config.refresh_token = None
|
||||
oauth.config.save_refresh_token.reset_mock()
|
||||
oauth.http_server = None
|
||||
|
||||
# Exceptions when logging in are handled correctly
|
||||
with mock.patch.object(oauth.reddit, 'get_access_information'):
|
||||
exception = OAuthException('', '')
|
||||
oauth.reddit.get_access_information.side_effect = exception
|
||||
oauth.authorize()
|
||||
message = 'Invalid OAuth data'.encode('utf-8')
|
||||
stdscr.derwin().addstr.assert_called_with(1, 1, message)
|
||||
assert not oauth.config.save_refresh_token.called
|
||||
|
||||
def test_oauth_clear_data(oauth):
|
||||
|
||||
oauth.config.refresh_token = 'secrettoken'
|
||||
oauth.reddit.refresh_token = 'secrettoken'
|
||||
oauth.clear_oauth_data()
|
||||
assert oauth.config.refresh_token is None
|
||||
assert oauth.reddit.refresh_token is None
|
||||
443
tests/test_objects.py
Normal file
443
tests/test_objects.py
Normal file
@@ -0,0 +1,443 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import time
|
||||
import curses
|
||||
|
||||
import pytest
|
||||
import requests
|
||||
|
||||
from rtv.objects import Color, Controller, Navigator, curses_session
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ascii', [True, False])
|
||||
def test_objects_load_screen(terminal, stdscr, ascii):
|
||||
terminal.ascii = ascii
|
||||
|
||||
# Ensure the thread is properly started/stopped
|
||||
with terminal.loader(delay=0, message=u'Hello', trail=u'...'):
|
||||
assert terminal.loader._animator.is_alive()
|
||||
assert not terminal.loader._is_running
|
||||
assert not terminal.loader._animator.is_alive()
|
||||
assert terminal.loader.exception is None
|
||||
assert stdscr.subwin.ncols == 10
|
||||
assert stdscr.subwin.nlines == 3
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ascii', [True, False])
|
||||
def test_objects_load_screen_exception_unhandled(terminal, stdscr, ascii):
|
||||
terminal.ascii = ascii
|
||||
|
||||
# Raising an exception should clean up the loader properly
|
||||
with pytest.raises(Exception):
|
||||
with terminal.loader(delay=0):
|
||||
assert terminal.loader._animator.is_alive()
|
||||
raise Exception()
|
||||
assert not terminal.loader._is_running
|
||||
assert not terminal.loader._animator.is_alive()
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ascii', [True, False])
|
||||
def test_objects_load_screen_exception_handled(terminal, stdscr, ascii):
|
||||
terminal.ascii = ascii
|
||||
|
||||
# Raising a handled exception should get stored on the loaders
|
||||
with terminal.loader(delay=0):
|
||||
assert terminal.loader._animator.is_alive()
|
||||
raise requests.ConnectionError()
|
||||
assert not terminal.loader._is_running
|
||||
assert not terminal.loader._animator.is_alive()
|
||||
assert isinstance(terminal.loader.exception, requests.ConnectionError)
|
||||
error_message = 'Connection Error'.encode('ascii' if ascii else 'utf-8')
|
||||
stdscr.subwin.addstr.assert_called_with(1, 1, error_message)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ascii', [True, False])
|
||||
def test_objects_load_screen_exception_not_caught(terminal, stdscr, ascii):
|
||||
terminal.ascii = ascii
|
||||
|
||||
with pytest.raises(KeyboardInterrupt):
|
||||
with terminal.loader(delay=0, catch_exception=False):
|
||||
assert terminal.loader._animator.is_alive()
|
||||
raise KeyboardInterrupt()
|
||||
assert not terminal.loader._is_running
|
||||
assert not terminal.loader._animator.is_alive()
|
||||
assert terminal.loader.exception is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ascii', [True, False])
|
||||
def test_objects_load_screen_keyboard_interrupt(terminal, stdscr, ascii):
|
||||
terminal.ascii = ascii
|
||||
|
||||
# Raising a KeyboardInterrupt should be also be stored
|
||||
with terminal.loader(delay=0):
|
||||
assert terminal.loader._animator.is_alive()
|
||||
raise KeyboardInterrupt()
|
||||
assert not terminal.loader._is_running
|
||||
assert not terminal.loader._animator.is_alive()
|
||||
assert isinstance(terminal.loader.exception, KeyboardInterrupt)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ascii', [True, False])
|
||||
def test_objects_load_screen_escape(terminal, stdscr, ascii):
|
||||
terminal.ascii = ascii
|
||||
|
||||
stdscr.getch.return_value = terminal.ESCAPE
|
||||
|
||||
# Pressing escape should trigger an interrupt during the delay section
|
||||
with mock.patch('os.kill') as kill:
|
||||
with terminal.loader():
|
||||
time.sleep(0.1)
|
||||
assert not terminal.loader._is_running
|
||||
assert not terminal.loader._animator.is_alive()
|
||||
assert kill.called
|
||||
|
||||
# As will as during the animation section
|
||||
with mock.patch('os.kill') as kill:
|
||||
with terminal.loader(delay=0):
|
||||
time.sleep(0.1)
|
||||
assert not terminal.loader._is_running
|
||||
assert not terminal.loader._animator.is_alive()
|
||||
assert kill.called
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ascii', [True, False])
|
||||
def test_objects_load_screen_initial_delay(terminal, stdscr, ascii):
|
||||
terminal.ascii = ascii
|
||||
|
||||
# If we don't reach the initial delay nothing should be drawn
|
||||
with terminal.loader(delay=0.1):
|
||||
time.sleep(0.05)
|
||||
assert not stdscr.subwin.addstr.called
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ascii', [True, False])
|
||||
def test_objects_load_screen_nested(terminal, ascii):
|
||||
terminal.ascii = ascii
|
||||
|
||||
with terminal.loader(message='Outer'):
|
||||
with terminal.loader(message='Inner'):
|
||||
raise requests.ConnectionError()
|
||||
assert False # Should never be reached
|
||||
|
||||
assert isinstance(terminal.loader.exception, requests.ConnectionError)
|
||||
assert terminal.loader.depth == 0
|
||||
assert not terminal.loader._is_running
|
||||
assert not terminal.loader._animator.is_alive()
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ascii', [True, False])
|
||||
def test_objects_load_screen_nested_complex(terminal, stdscr, ascii):
|
||||
terminal.ascii = ascii
|
||||
|
||||
with terminal.loader(message='Outer') as outer_loader:
|
||||
assert outer_loader.depth == 1
|
||||
|
||||
with terminal.loader(message='Inner') as inner_loader:
|
||||
assert inner_loader.depth == 2
|
||||
assert inner_loader._args[2] == 'Outer'
|
||||
|
||||
with terminal.loader():
|
||||
assert terminal.loader.depth == 2
|
||||
raise requests.ConnectionError()
|
||||
|
||||
assert False # Should never be reached
|
||||
|
||||
assert isinstance(terminal.loader.exception, requests.ConnectionError)
|
||||
assert terminal.loader.depth == 0
|
||||
assert not terminal.loader._is_running
|
||||
assert not terminal.loader._animator.is_alive()
|
||||
error_message = 'Connection Error'.encode('ascii' if ascii else 'utf-8')
|
||||
stdscr.subwin.addstr.assert_called_once_with(1, 1, error_message)
|
||||
|
||||
|
||||
def test_objects_color(stdscr):
|
||||
|
||||
colors = ['RED', 'GREEN', 'YELLOW', 'BLUE', 'MAGENTA', 'CYAN', 'WHITE']
|
||||
|
||||
# Check that all colors start with the default value
|
||||
for color in colors:
|
||||
assert getattr(Color, color) == curses.A_NORMAL
|
||||
|
||||
Color.init()
|
||||
assert curses.use_default_colors.called
|
||||
|
||||
# Check that all colors are populated
|
||||
for color in colors:
|
||||
assert getattr(Color, color) == 23
|
||||
|
||||
|
||||
def test_objects_curses_session(stdscr):
|
||||
|
||||
# Normal setup and cleanup
|
||||
with curses_session():
|
||||
pass
|
||||
assert curses.initscr.called
|
||||
assert curses.endwin.called
|
||||
curses.initscr.reset_mock()
|
||||
curses.endwin.reset_mock()
|
||||
|
||||
# Ensure cleanup runs if an error occurs
|
||||
with pytest.raises(KeyboardInterrupt):
|
||||
with curses_session():
|
||||
raise KeyboardInterrupt()
|
||||
assert curses.initscr.called
|
||||
assert curses.endwin.called
|
||||
curses.initscr.reset_mock()
|
||||
curses.endwin.reset_mock()
|
||||
|
||||
# But cleanup shouldn't run if stdscr was never instantiated
|
||||
curses.initscr.side_effect = KeyboardInterrupt
|
||||
with pytest.raises(KeyboardInterrupt):
|
||||
with curses_session():
|
||||
pass
|
||||
assert curses.initscr.called
|
||||
assert not curses.endwin.called
|
||||
curses.initscr.reset_mock()
|
||||
curses.endwin.reset_mock()
|
||||
|
||||
|
||||
def test_objects_controller():
|
||||
|
||||
class ControllerA(Controller):
|
||||
character_map = {}
|
||||
|
||||
class ControllerB(ControllerA):
|
||||
character_map = {}
|
||||
|
||||
class ControllerC(ControllerA):
|
||||
character_map = {}
|
||||
|
||||
@ControllerA.register('1')
|
||||
def call_page(_):
|
||||
return 'a1'
|
||||
|
||||
@ControllerA.register('2')
|
||||
def call_page(_):
|
||||
return 'a2'
|
||||
|
||||
@ControllerB.register('1')
|
||||
def call_page(_):
|
||||
return 'b1'
|
||||
|
||||
@ControllerC.register('2')
|
||||
def call_page(_):
|
||||
return 'c2'
|
||||
|
||||
controller_a = ControllerA(None)
|
||||
controller_b = ControllerB(None)
|
||||
controller_c = ControllerC(None)
|
||||
|
||||
assert controller_a.trigger('1') == 'a1'
|
||||
assert controller_a.trigger('2') == 'a2'
|
||||
assert controller_a.trigger('3') is None
|
||||
|
||||
assert controller_b.trigger('1') == 'b1'
|
||||
assert controller_b.trigger('2') == 'a2'
|
||||
assert controller_b.trigger('3') is None
|
||||
|
||||
assert controller_c.trigger('1') == 'a1'
|
||||
assert controller_c.trigger('2') == 'c2'
|
||||
assert controller_c.trigger('3') is None
|
||||
|
||||
|
||||
def test_objects_navigator_properties():
|
||||
|
||||
def valid_page_cb(_):
|
||||
return
|
||||
|
||||
nav = Navigator(valid_page_cb)
|
||||
assert nav.step == 1
|
||||
assert nav.position == (0, 0, False)
|
||||
assert nav.absolute_index == 0
|
||||
|
||||
nav = Navigator(valid_page_cb, 5, 2, True)
|
||||
assert nav.step == -1
|
||||
assert nav.position == (5, 2, True)
|
||||
assert nav.absolute_index == 3
|
||||
|
||||
|
||||
def test_objects_navigator_move():
|
||||
|
||||
def valid_page_cb(index):
|
||||
if index < 0 or index > 3:
|
||||
raise IndexError()
|
||||
|
||||
nav = Navigator(valid_page_cb)
|
||||
|
||||
# Try to scroll up past the first item
|
||||
valid, redraw = nav.move(-1, 2)
|
||||
assert not valid
|
||||
assert not redraw
|
||||
|
||||
# Scroll down
|
||||
valid, redraw = nav.move(1, 3)
|
||||
assert nav.page_index == 0
|
||||
assert nav.cursor_index == 1
|
||||
assert valid
|
||||
assert not redraw
|
||||
|
||||
# Scroll down, reach last item on the page and flip the screen
|
||||
valid, redraw = nav.move(1, 3)
|
||||
assert nav.page_index == 2
|
||||
assert nav.cursor_index == 0
|
||||
assert nav.inverted
|
||||
assert valid
|
||||
assert redraw
|
||||
|
||||
# Keep scrolling
|
||||
valid, redraw = nav.move(1, 3)
|
||||
assert nav.page_index == 3
|
||||
assert nav.cursor_index == 0
|
||||
assert nav.inverted
|
||||
assert valid
|
||||
assert redraw
|
||||
|
||||
# Reach the end of the page and stop
|
||||
valid, redraw = nav.move(1, 1)
|
||||
assert nav.page_index == 3
|
||||
assert nav.cursor_index == 0
|
||||
assert nav.inverted
|
||||
assert not valid
|
||||
assert not redraw
|
||||
|
||||
# Last item was large and takes up the whole screen, scroll back up and
|
||||
# flip the screen again
|
||||
valid, redraw = nav.move(-1, 1)
|
||||
assert nav.page_index == 2
|
||||
assert nav.cursor_index == 0
|
||||
assert not nav.inverted
|
||||
assert valid
|
||||
assert redraw
|
||||
|
||||
|
||||
def test_objects_navigator_move_new_submission():
|
||||
|
||||
def valid_page_cb(index):
|
||||
if index != -1:
|
||||
raise IndexError()
|
||||
|
||||
nav = Navigator(valid_page_cb, page_index=-1)
|
||||
|
||||
# Can't move up
|
||||
valid, redraw = nav.move(-1, 1)
|
||||
assert nav.page_index == -1
|
||||
assert nav.cursor_index == 0
|
||||
assert not nav.inverted
|
||||
assert not valid
|
||||
assert not redraw
|
||||
|
||||
# Can't move down
|
||||
valid, redraw = nav.move(1, 1)
|
||||
assert nav.page_index == -1
|
||||
assert nav.cursor_index == 0
|
||||
assert not nav.inverted
|
||||
assert not valid
|
||||
assert not redraw
|
||||
|
||||
|
||||
def test_objects_navigator_move_submission():
|
||||
|
||||
def valid_page_cb(index):
|
||||
if index < -1 or index > 4:
|
||||
raise IndexError()
|
||||
|
||||
nav = Navigator(valid_page_cb, page_index=-1)
|
||||
|
||||
# Can't move up
|
||||
valid, redraw = nav.move(-1, 2)
|
||||
assert nav.page_index == -1
|
||||
assert nav.cursor_index == 0
|
||||
assert not nav.inverted
|
||||
assert not valid
|
||||
assert not redraw
|
||||
|
||||
# Moving down jumps to the first comment
|
||||
valid, redraw = nav.move(1, 2)
|
||||
assert nav.page_index == 0
|
||||
assert nav.cursor_index == 0
|
||||
assert not nav.inverted
|
||||
assert valid
|
||||
assert redraw
|
||||
|
||||
# Moving down again inverts the screen
|
||||
valid, redraw = nav.move(1, 2)
|
||||
assert nav.page_index == 1
|
||||
assert nav.cursor_index == 0
|
||||
assert nav.inverted
|
||||
assert valid
|
||||
assert redraw
|
||||
|
||||
# Move up to the first comment
|
||||
valid, redraw = nav.move(-1, 2)
|
||||
assert nav.page_index == 0
|
||||
assert nav.cursor_index == 0
|
||||
assert not nav.inverted
|
||||
assert valid
|
||||
assert redraw
|
||||
|
||||
# Move up to the submission
|
||||
valid, redraw = nav.move(-1, 2)
|
||||
assert nav.page_index == -1
|
||||
assert nav.cursor_index == 0
|
||||
assert not nav.inverted
|
||||
assert valid
|
||||
assert redraw
|
||||
|
||||
|
||||
@pytest.mark.xfail(reason="Paging is still broken in several edge-cases")
|
||||
def test_objects_navigator_move_page():
|
||||
|
||||
def valid_page_cb(index):
|
||||
if index < 0 or index > 7:
|
||||
raise IndexError()
|
||||
|
||||
nav = Navigator(valid_page_cb, cursor_index=2)
|
||||
|
||||
# Can't move up
|
||||
valid, redraw = nav.move_page(-1, 5)
|
||||
assert nav.page_index == 0
|
||||
assert nav.cursor_index == 0
|
||||
assert not nav.inverted
|
||||
assert not valid
|
||||
assert not redraw
|
||||
|
||||
# Page down
|
||||
valid, redraw = nav.move_page(1, 5)
|
||||
assert nav.page_index == 4
|
||||
assert nav.cursor_index == 0
|
||||
assert nav.inverted
|
||||
assert valid
|
||||
assert redraw
|
||||
|
||||
# Page up
|
||||
valid, redraw = nav.move_page(-1, 3)
|
||||
assert nav.page_index == 2
|
||||
assert nav.cursor_index == 0
|
||||
assert not nav.inverted
|
||||
assert valid
|
||||
assert redraw
|
||||
|
||||
|
||||
def test_objects_navigator_flip():
|
||||
|
||||
def valid_page_cb(index):
|
||||
if index < 0 or index > 10:
|
||||
raise IndexError()
|
||||
|
||||
nav = Navigator(valid_page_cb)
|
||||
|
||||
nav.flip(5)
|
||||
assert nav.page_index == 5
|
||||
assert nav.cursor_index == 5
|
||||
assert nav.inverted
|
||||
|
||||
nav.flip(3)
|
||||
assert nav.page_index == 2
|
||||
assert nav.cursor_index == 3
|
||||
assert not nav.inverted
|
||||
126
tests/test_page.py
Normal file
126
tests/test_page.py
Normal file
@@ -0,0 +1,126 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import pytest
|
||||
|
||||
from rtv.page import Page, PageController, logged_in
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
|
||||
|
||||
def test_page_logged_in(terminal):
|
||||
|
||||
page = mock.MagicMock()
|
||||
page.term = terminal
|
||||
|
||||
@logged_in
|
||||
def func(page):
|
||||
raise RuntimeError()
|
||||
|
||||
# Logged in runs the function
|
||||
page.reddit.is_oauth_session.return_value = True
|
||||
with pytest.raises(RuntimeError):
|
||||
func(page)
|
||||
message = 'Not logged in'.encode('utf-8')
|
||||
with pytest.raises(AssertionError):
|
||||
terminal.stdscr.subwin.addstr.assert_called_with(1, 1, message)
|
||||
|
||||
# Logged out skips the function and displays a message
|
||||
page.reddit.is_oauth_session.return_value = False
|
||||
func(page)
|
||||
message = 'Not logged in'.encode('utf-8')
|
||||
terminal.stdscr.subwin.addstr.assert_called_with(1, 1, message)
|
||||
|
||||
|
||||
def test_page_unauthenticated(reddit, terminal, config, oauth):
|
||||
|
||||
page = Page(reddit, terminal, config, oauth)
|
||||
page.controller = PageController(page)
|
||||
with mock.patch.object(page, 'refresh_content'), \
|
||||
mock.patch.object(page, 'content'), \
|
||||
mock.patch.object(page, 'nav'), \
|
||||
mock.patch.object(page, 'draw'):
|
||||
|
||||
# Loop
|
||||
def func(ch):
|
||||
page.active = False
|
||||
with mock.patch.object(page, 'controller'):
|
||||
page.controller.trigger = mock.MagicMock(side_effect=func)
|
||||
page.loop()
|
||||
assert page.draw.called
|
||||
|
||||
# Quit, confirm
|
||||
terminal.stdscr.getch.return_value = ord('y')
|
||||
with mock.patch('sys.exit') as sys_exit:
|
||||
page.controller.trigger('q')
|
||||
assert sys_exit.called
|
||||
|
||||
# Quit, deny
|
||||
terminal.stdscr.getch.return_value = terminal.ESCAPE
|
||||
with mock.patch('sys.exit') as sys_exit:
|
||||
page.controller.trigger('q')
|
||||
assert not sys_exit.called
|
||||
|
||||
# Force quit
|
||||
terminal.stdscr.getch.return_value = terminal.ESCAPE
|
||||
with mock.patch('sys.exit') as sys_exit:
|
||||
page.controller.trigger('Q')
|
||||
assert sys_exit.called
|
||||
|
||||
# Show help
|
||||
page.controller.trigger('?')
|
||||
message = 'Basic Commands'.encode('utf-8')
|
||||
terminal.stdscr.subwin.addstr.assert_any_call(1, 1, message)
|
||||
|
||||
# Sort content
|
||||
page.controller.trigger('1')
|
||||
page.refresh_content.assert_called_with(order='hot')
|
||||
page.controller.trigger('2')
|
||||
page.refresh_content.assert_called_with(order='top')
|
||||
page.controller.trigger('3')
|
||||
page.refresh_content.assert_called_with(order='rising')
|
||||
page.controller.trigger('4')
|
||||
page.refresh_content.assert_called_with(order='new')
|
||||
page.controller.trigger('5')
|
||||
page.refresh_content.assert_called_with(order='controversial')
|
||||
|
||||
logged_in_methods = [
|
||||
'a', # Upvote
|
||||
'z', # Downvote
|
||||
'd', # Delete
|
||||
'e', # Edit
|
||||
'i', # Get inbox
|
||||
]
|
||||
for ch in logged_in_methods:
|
||||
page.controller.trigger(ch)
|
||||
message = 'Not logged in'.encode('utf-8')
|
||||
terminal.stdscr.subwin.addstr.assert_called_with(1, 1, message)
|
||||
terminal.stdscr.subwin.addstr.reset_mock()
|
||||
|
||||
|
||||
def test_page_authenticated(reddit, terminal, config, oauth, refresh_token):
|
||||
|
||||
page = Page(reddit, terminal, config, oauth)
|
||||
page.controller = PageController(page)
|
||||
config.refresh_token = refresh_token
|
||||
|
||||
# Login
|
||||
page.controller.trigger('u')
|
||||
assert reddit.is_oauth_session()
|
||||
|
||||
# Get inbox - Call the real method
|
||||
page.controller.trigger('i')
|
||||
|
||||
# Get inbox - Simulate no new messages
|
||||
reddit.get_unread = mock.Mock(return_value=[])
|
||||
page.controller.trigger('i')
|
||||
message = 'No New Messages'.encode('utf-8')
|
||||
terminal.stdscr.subwin.addstr.assert_called_with(1, 1, message)
|
||||
|
||||
# Logout
|
||||
terminal.stdscr.getch.return_value = ord('y')
|
||||
page.controller.trigger('u')
|
||||
assert not reddit.is_oauth_session()
|
||||
213
tests/test_submission.py
Normal file
213
tests/test_submission.py
Normal file
@@ -0,0 +1,213 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import curses
|
||||
|
||||
from rtv.submission import SubmissionPage
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
|
||||
|
||||
def test_submission_page_construct(reddit, terminal, config, oauth):
|
||||
window = terminal.stdscr.subwin
|
||||
url = ('https://www.reddit.com/r/Python/comments/2xmo63/'
|
||||
'a_python_terminal_viewer_for_browsing_reddit')
|
||||
|
||||
with terminal.loader():
|
||||
page = SubmissionPage(reddit, terminal, config, oauth, url=url)
|
||||
assert terminal.loader.exception is None
|
||||
|
||||
# Toggle the second comment so we can check the draw more comments method
|
||||
page.content.toggle(1)
|
||||
page.draw()
|
||||
|
||||
# Title
|
||||
title = url[:terminal.stdscr.ncols-1].encode('utf-8')
|
||||
window.addstr.assert_any_call(0, 0, title)
|
||||
|
||||
# Submission
|
||||
submission_data = page.content.get(-1)
|
||||
text = submission_data['title'].encode('utf-8')
|
||||
window.subwin.addstr.assert_any_call(1, 1, text, 2097152)
|
||||
assert window.subwin.border.called
|
||||
|
||||
# Comment
|
||||
comment_data = page.content.get(0)
|
||||
text = comment_data['split_body'][0].encode('utf-8')
|
||||
window.subwin.addstr.assert_any_call(1, 1, text)
|
||||
|
||||
# More Comments
|
||||
comment_data = page.content.get(1)
|
||||
text = comment_data['body'].encode('utf-8')
|
||||
window.subwin.addstr.assert_any_call(0, 1, text)
|
||||
|
||||
# Cursor should not be drawn when the page is first opened
|
||||
assert not window.subwin.chgat.called
|
||||
|
||||
# Reload with a smaller terminal window
|
||||
terminal.stdscr.ncols = 20
|
||||
terminal.stdscr.nlines = 10
|
||||
with terminal.loader():
|
||||
page = SubmissionPage(reddit, terminal, config, oauth, url=url)
|
||||
assert terminal.loader.exception is None
|
||||
page.draw()
|
||||
|
||||
|
||||
def test_submission_refresh(submission_page):
|
||||
|
||||
# Should be able to refresh content
|
||||
submission_page.refresh_content()
|
||||
|
||||
|
||||
def test_submission_unauthenticated(submission_page, terminal):
|
||||
|
||||
# Unauthenticated commands
|
||||
methods = [
|
||||
'a', # Upvote
|
||||
'z', # Downvote
|
||||
'c', # Comment
|
||||
'e', # Edit
|
||||
'd', # Delete
|
||||
]
|
||||
for ch in methods:
|
||||
submission_page.controller.trigger(ch)
|
||||
text = 'Not logged in'.encode('utf-8')
|
||||
terminal.stdscr.subwin.addstr.assert_called_with(1, 1, text)
|
||||
|
||||
|
||||
def test_submission_open(submission_page, terminal):
|
||||
|
||||
# Open the selected link with the web browser
|
||||
with mock.patch.object(terminal, 'open_browser'):
|
||||
submission_page.controller.trigger(terminal.RETURN)
|
||||
assert terminal.open_browser.called
|
||||
|
||||
|
||||
def test_submission_vote(submission_page, refresh_token):
|
||||
|
||||
# Log in
|
||||
submission_page.config.refresh_token = refresh_token
|
||||
submission_page.oauth.authorize()
|
||||
|
||||
# Test voting on the submission
|
||||
with mock.patch('praw.objects.Submission.upvote') as upvote, \
|
||||
mock.patch('praw.objects.Submission.downvote') as downvote, \
|
||||
mock.patch('praw.objects.Submission.clear_vote') as clear_vote:
|
||||
|
||||
data = submission_page.content.get(submission_page.nav.absolute_index)
|
||||
|
||||
# Upvote
|
||||
submission_page.controller.trigger('a')
|
||||
assert upvote.called
|
||||
assert data['likes'] is True
|
||||
|
||||
# Downvote
|
||||
submission_page.controller.trigger('z')
|
||||
assert downvote.called
|
||||
assert data['likes'] is False
|
||||
|
||||
# Clear vote
|
||||
submission_page.controller.trigger('z')
|
||||
assert clear_vote.called
|
||||
assert data['likes'] is None
|
||||
|
||||
# Upvote - exception
|
||||
upvote.side_effect = KeyboardInterrupt
|
||||
submission_page.controller.trigger('a')
|
||||
assert data['likes'] is None
|
||||
|
||||
# Downvote - exception
|
||||
downvote.side_effect = KeyboardInterrupt
|
||||
submission_page.controller.trigger('a')
|
||||
assert data['likes'] is None
|
||||
|
||||
|
||||
def test_submission_comment(submission_page, terminal, refresh_token):
|
||||
|
||||
# Log in
|
||||
submission_page.config.refresh_token = refresh_token
|
||||
submission_page.oauth.authorize()
|
||||
|
||||
# Leave a comment
|
||||
with mock.patch('praw.objects.Submission.add_comment') as add_comment, \
|
||||
mock.patch.object(terminal, 'open_editor') as open_editor, \
|
||||
mock.patch('time.sleep'):
|
||||
open_editor.return_value = 'comment text'
|
||||
|
||||
submission_page.controller.trigger('c')
|
||||
assert open_editor.called
|
||||
add_comment.assert_called_with('comment text')
|
||||
|
||||
|
||||
def test_submission_delete(submission_page, terminal, refresh_token):
|
||||
|
||||
# Log in
|
||||
submission_page.config.refresh_token = refresh_token
|
||||
submission_page.oauth.authorize()
|
||||
|
||||
# Can't delete the submission
|
||||
curses.flash.reset_mock()
|
||||
submission_page.controller.trigger('d')
|
||||
assert curses.flash.called
|
||||
|
||||
# Move down to the first comment
|
||||
with mock.patch.object(submission_page, 'clear_input_queue'):
|
||||
submission_page.controller.trigger('j')
|
||||
|
||||
# Try to delete the first comment - wrong author
|
||||
curses.flash.reset_mock()
|
||||
submission_page.controller.trigger('d')
|
||||
assert curses.flash.called
|
||||
|
||||
# Spoof the author and try to delete again
|
||||
data = submission_page.content.get(submission_page.nav.absolute_index)
|
||||
data['author'] = submission_page.reddit.user.name
|
||||
with mock.patch('praw.objects.Comment.delete') as delete, \
|
||||
mock.patch.object(terminal.stdscr, 'getch') as getch, \
|
||||
mock.patch('time.sleep'):
|
||||
getch.return_value = ord('y')
|
||||
submission_page.controller.trigger('d')
|
||||
assert delete.called
|
||||
|
||||
|
||||
def test_submission_edit(submission_page, terminal, refresh_token):
|
||||
|
||||
# Log in
|
||||
submission_page.config.refresh_token = refresh_token
|
||||
submission_page.oauth.authorize()
|
||||
|
||||
# Try to edit the submission - wrong author
|
||||
curses.flash.reset_mock()
|
||||
submission_page.controller.trigger('e')
|
||||
assert curses.flash.called
|
||||
|
||||
# Spoof the submission and try to edit again
|
||||
data = submission_page.content.get(submission_page.nav.absolute_index)
|
||||
data['author'] = submission_page.reddit.user.name
|
||||
with mock.patch('praw.objects.Submission.edit') as edit, \
|
||||
mock.patch.object(terminal, 'open_editor') as open_editor, \
|
||||
mock.patch('time.sleep'):
|
||||
open_editor.return_value = 'submission text'
|
||||
|
||||
submission_page.controller.trigger('e')
|
||||
assert open_editor.called
|
||||
edit.assert_called_with('submission text')
|
||||
|
||||
# Move down to the first comment
|
||||
with mock.patch.object(submission_page, 'clear_input_queue'):
|
||||
submission_page.controller.trigger('j')
|
||||
|
||||
# Spoof the author and edit the comment
|
||||
data = submission_page.content.get(submission_page.nav.absolute_index)
|
||||
data['author'] = submission_page.reddit.user.name
|
||||
with mock.patch('praw.objects.Comment.edit') as edit, \
|
||||
mock.patch.object(terminal, 'open_editor') as open_editor, \
|
||||
mock.patch('time.sleep'):
|
||||
open_editor.return_value = 'comment text'
|
||||
|
||||
submission_page.controller.trigger('e')
|
||||
assert open_editor.called
|
||||
edit.assert_called_with('comment text')
|
||||
172
tests/test_subreddit.py
Normal file
172
tests/test_subreddit.py
Normal file
@@ -0,0 +1,172 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from rtv.subreddit import SubredditPage
|
||||
from rtv.content import SubmissionContent
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
|
||||
|
||||
def test_subreddit_page_construct(reddit, terminal, config, oauth):
|
||||
window = terminal.stdscr.subwin
|
||||
|
||||
with terminal.loader():
|
||||
page = SubredditPage(reddit, terminal, config, oauth, '/r/python')
|
||||
assert terminal.loader.exception is None
|
||||
page.draw()
|
||||
|
||||
# Title
|
||||
title = '/r/python'.encode('utf-8')
|
||||
window.addstr.assert_any_call(0, 0, title)
|
||||
|
||||
# Submission
|
||||
text = page.content.get(0)['split_title'][0].encode('utf-8')
|
||||
window.subwin.addstr.assert_any_call(0, 1, text, 2097152)
|
||||
|
||||
# Cursor should have been drawn
|
||||
assert window.subwin.chgat.called
|
||||
|
||||
# Reload with a smaller terminal window
|
||||
terminal.stdscr.ncols = 20
|
||||
terminal.stdscr.nlines = 10
|
||||
with terminal.loader():
|
||||
page = SubredditPage(reddit, terminal, config, oauth, '/r/python')
|
||||
assert terminal.loader.exception is None
|
||||
page.draw()
|
||||
|
||||
|
||||
def test_subreddit_refresh(subreddit_page, terminal):
|
||||
|
||||
# Refresh the page with default values
|
||||
subreddit_page.controller.trigger('r')
|
||||
assert subreddit_page.content.order is None
|
||||
assert subreddit_page.content.name == '/r/python'
|
||||
assert terminal.loader.exception is None
|
||||
|
||||
# Refresh with the order in the name
|
||||
subreddit_page.refresh_content(name='/r/front/hot', order='ignore')
|
||||
assert subreddit_page.content.order == 'hot'
|
||||
assert subreddit_page.content.name == '/r/front'
|
||||
assert terminal.loader.exception is None
|
||||
|
||||
|
||||
def test_subreddit_search(subreddit_page, terminal):
|
||||
|
||||
# Search the current subreddit
|
||||
with mock.patch.object(terminal, 'prompt_input'):
|
||||
terminal.prompt_input.return_value = 'search term'
|
||||
subreddit_page.controller.trigger('f')
|
||||
assert subreddit_page.content.name == '/r/python'
|
||||
assert terminal.prompt_input.called
|
||||
assert not terminal.loader.exception
|
||||
|
||||
# Searching with an empty query shouldn't crash
|
||||
with mock.patch.object(terminal, 'prompt_input'):
|
||||
terminal.prompt_input.return_value = None
|
||||
subreddit_page.controller.trigger('f')
|
||||
assert not terminal.loader.exception
|
||||
|
||||
|
||||
def test_subreddit_prompt(subreddit_page, terminal):
|
||||
|
||||
# Prompt for a different subreddit
|
||||
with mock.patch.object(terminal, 'prompt_input'):
|
||||
terminal.prompt_input.return_value = 'front/top'
|
||||
subreddit_page.controller.trigger('/')
|
||||
assert subreddit_page.content.name == '/r/front'
|
||||
assert subreddit_page.content.order == 'top'
|
||||
assert not terminal.loader.exception
|
||||
|
||||
|
||||
def test_subreddit_open(subreddit_page, terminal, config):
|
||||
|
||||
# Open the selected submission
|
||||
data = subreddit_page.content.get(subreddit_page.nav.absolute_index)
|
||||
with mock.patch('rtv.submission.SubmissionPage.loop') as loop, \
|
||||
mock.patch.object(config.history, 'add'):
|
||||
data['url_type'] = 'selfpost'
|
||||
subreddit_page.controller.trigger('l')
|
||||
assert not terminal.loader.exception
|
||||
assert loop.called
|
||||
config.history.add.assert_called_with(data['url_full'])
|
||||
|
||||
# Open the selected link externally
|
||||
with mock.patch.object(terminal, 'open_browser'), \
|
||||
mock.patch.object(config.history, 'add'):
|
||||
data['url_type'] = 'external'
|
||||
subreddit_page.controller.trigger('o')
|
||||
assert terminal.open_browser.called
|
||||
config.history.add.assert_called_with(data['url_full'])
|
||||
|
||||
# Open the selected link within rtv
|
||||
with mock.patch.object(subreddit_page, 'open_submission'), \
|
||||
mock.patch.object(config.history, 'add'):
|
||||
data['url_type'] = 'selfpost'
|
||||
subreddit_page.controller.trigger('o')
|
||||
assert subreddit_page.open_submission.called
|
||||
|
||||
|
||||
def test_subreddit_unauthenticated(subreddit_page, terminal):
|
||||
|
||||
# Unauthenticated commands
|
||||
methods = [
|
||||
'a', # Upvote
|
||||
'z', # Downvote
|
||||
'c', # Post
|
||||
'e', # Edit
|
||||
'd', # Delete
|
||||
's', # Subscriptions
|
||||
]
|
||||
for ch in methods:
|
||||
subreddit_page.controller.trigger(ch)
|
||||
text = 'Not logged in'.encode('utf-8')
|
||||
terminal.stdscr.subwin.addstr.assert_called_with(1, 1, text)
|
||||
|
||||
|
||||
def test_subreddit_post(subreddit_page, terminal, reddit, refresh_token):
|
||||
|
||||
# Log in
|
||||
subreddit_page.config.refresh_token = refresh_token
|
||||
subreddit_page.oauth.authorize()
|
||||
|
||||
# Post a submission to an invalid subreddit
|
||||
subreddit_page.refresh_content('front')
|
||||
subreddit_page.controller.trigger('c')
|
||||
text = "Can't post to /r/front".encode('utf-8')
|
||||
terminal.stdscr.subwin.addstr.assert_called_with(1, 1, text)
|
||||
|
||||
# Post a submission with a title but with no body
|
||||
subreddit_page.refresh_content('python')
|
||||
with mock.patch.object(terminal, 'open_editor'):
|
||||
terminal.open_editor.return_value = 'title'
|
||||
subreddit_page.controller.trigger('c')
|
||||
text = "Aborted".encode('utf-8')
|
||||
terminal.stdscr.subwin.addstr.assert_called_with(1, 1, text)
|
||||
|
||||
# Post a fake submission
|
||||
url = 'https://www.reddit.com/r/Python/comments/2xmo63/'
|
||||
submission = reddit.get_submission(url)
|
||||
with mock.patch.object(terminal, 'open_editor'), \
|
||||
mock.patch.object(reddit, 'submit'), \
|
||||
mock.patch('rtv.page.Page.loop') as loop, \
|
||||
mock.patch('time.sleep'):
|
||||
terminal.open_editor.return_value = 'test\ncontent'
|
||||
reddit.submit.return_value = submission
|
||||
subreddit_page.controller.trigger('c')
|
||||
assert reddit.submit.called
|
||||
assert loop.called
|
||||
|
||||
|
||||
def test_subreddit_open_subscriptions(subreddit_page, refresh_token):
|
||||
|
||||
# Log in
|
||||
subreddit_page.config.refresh_token = refresh_token
|
||||
subreddit_page.oauth.authorize()
|
||||
|
||||
# Open a subscription
|
||||
with mock.patch('rtv.page.Page.loop') as loop:
|
||||
subreddit_page.controller.trigger('s')
|
||||
assert loop.called
|
||||
135
tests/test_subscription.py
Normal file
135
tests/test_subscription.py
Normal file
@@ -0,0 +1,135 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import curses
|
||||
|
||||
import praw
|
||||
|
||||
from rtv.subscription import SubscriptionPage
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
|
||||
|
||||
def test_subscription_page_construct(reddit, terminal, config, oauth,
|
||||
refresh_token):
|
||||
window = terminal.stdscr.subwin
|
||||
|
||||
# Can't load the page if not logged in
|
||||
with terminal.loader():
|
||||
SubscriptionPage(reddit, terminal, config, oauth)
|
||||
assert isinstance(
|
||||
terminal.loader.exception, praw.errors.LoginOrScopeRequired)
|
||||
|
||||
# Log in
|
||||
config.refresh_token = refresh_token
|
||||
oauth.authorize()
|
||||
|
||||
with terminal.loader():
|
||||
page = SubscriptionPage(reddit, terminal, config, oauth)
|
||||
assert terminal.loader.exception is None
|
||||
|
||||
page.draw()
|
||||
|
||||
# Header - Title
|
||||
title = 'Subscriptions'.encode('utf-8')
|
||||
window.addstr.assert_any_call(0, 0, title)
|
||||
|
||||
# Header - Name
|
||||
name = reddit.user.name.encode('utf-8')
|
||||
window.addstr.assert_any_call(0, 59, name)
|
||||
|
||||
# Cursor - 2 lines
|
||||
window.subwin.chgat.assert_any_call(0, 0, 1, 262144)
|
||||
window.subwin.chgat.assert_any_call(1, 0, 1, 262144)
|
||||
|
||||
# Reload with a smaller terminal window
|
||||
terminal.stdscr.ncols = 20
|
||||
terminal.stdscr.nlines = 10
|
||||
with terminal.loader():
|
||||
page = SubscriptionPage(reddit, terminal, config, oauth)
|
||||
assert terminal.loader.exception is None
|
||||
|
||||
page.draw()
|
||||
|
||||
|
||||
def test_subscription_refresh(subscription_page):
|
||||
|
||||
# Refresh content - invalid order
|
||||
subscription_page.controller.trigger('2')
|
||||
assert curses.flash.called
|
||||
curses.flash.reset_mock()
|
||||
|
||||
# Refresh content
|
||||
subscription_page.controller.trigger('r')
|
||||
assert not curses.flash.called
|
||||
|
||||
|
||||
def test_subscription_move(subscription_page):
|
||||
|
||||
# Test movement
|
||||
with mock.patch.object(subscription_page, 'clear_input_queue'):
|
||||
|
||||
# Move cursor to the bottom of the page
|
||||
while not curses.flash.called:
|
||||
subscription_page.controller.trigger('j')
|
||||
curses.flash.reset_mock()
|
||||
assert subscription_page.nav.inverted
|
||||
assert (subscription_page.nav.absolute_index ==
|
||||
len(subscription_page.content._subscription_data) - 1)
|
||||
|
||||
# And back to the top
|
||||
for i in range(subscription_page.nav.absolute_index):
|
||||
subscription_page.controller.trigger('k')
|
||||
assert not curses.flash.called
|
||||
assert subscription_page.nav.absolute_index == 0
|
||||
assert not subscription_page.nav.inverted
|
||||
|
||||
# Can't go up any further
|
||||
subscription_page.controller.trigger('k')
|
||||
assert curses.flash.called
|
||||
assert subscription_page.nav.absolute_index == 0
|
||||
assert not subscription_page.nav.inverted
|
||||
|
||||
# Page down should move the last item to the top
|
||||
n = len(subscription_page._subwindows)
|
||||
subscription_page.controller.trigger('n')
|
||||
assert subscription_page.nav.absolute_index == n - 1
|
||||
|
||||
# And page up should move back up, but possibly not to the first item
|
||||
subscription_page.controller.trigger('m')
|
||||
|
||||
|
||||
def test_subscription_select(subscription_page):
|
||||
|
||||
# Select a subreddit
|
||||
subscription_page.controller.trigger(curses.KEY_ENTER)
|
||||
assert subscription_page.subreddit_data is not None
|
||||
assert subscription_page.active is False
|
||||
|
||||
|
||||
def test_subscription_close(subscription_page):
|
||||
|
||||
# Close the subscriptions page
|
||||
subscription_page.subreddit_data = None
|
||||
subscription_page.active = None
|
||||
subscription_page.controller.trigger('h')
|
||||
assert subscription_page.subreddit_data is None
|
||||
assert subscription_page.active is False
|
||||
|
||||
|
||||
def test_subscription_page_invalid(subscription_page):
|
||||
|
||||
# Test that other commands don't crash
|
||||
methods = [
|
||||
'a', # Upvote
|
||||
'z', # Downvote
|
||||
'd', # Delete
|
||||
'e', # Edit
|
||||
]
|
||||
for ch in methods:
|
||||
curses.flash.reset_mock()
|
||||
subscription_page.controller.trigger(ch)
|
||||
assert curses.flash.called
|
||||
293
tests/test_terminal.py
Normal file
293
tests/test_terminal.py
Normal file
@@ -0,0 +1,293 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
import curses
|
||||
import codecs
|
||||
|
||||
import six
|
||||
import pytest
|
||||
|
||||
from rtv.docs import HELP, COMMENT_EDIT_FILE
|
||||
from rtv.objects import Color
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
|
||||
|
||||
def test_terminal_properties(terminal, config):
|
||||
|
||||
assert len(terminal.up_arrow) == 2
|
||||
assert isinstance(terminal.up_arrow[0], six.text_type)
|
||||
assert len(terminal.down_arrow) == 2
|
||||
assert isinstance(terminal.down_arrow[0], six.text_type)
|
||||
assert len(terminal.neutral_arrow) == 2
|
||||
assert isinstance(terminal.neutral_arrow[0], six.text_type)
|
||||
assert len(terminal.guilded) == 2
|
||||
assert isinstance(terminal.guilded[0], six.text_type)
|
||||
|
||||
terminal._display = None
|
||||
with mock.patch.dict('os.environ', {'DISPLAY': ''}):
|
||||
assert terminal.display is False
|
||||
|
||||
terminal._display = None
|
||||
with mock.patch.dict('os.environ', {'DISPLAY': ':0', 'BROWSER': 'w3m'}):
|
||||
assert terminal.display is False
|
||||
|
||||
terminal._display = None
|
||||
with mock.patch.dict('os.environ', {'DISPLAY': ':0', 'BROWSER': ''}), \
|
||||
mock.patch('webbrowser._tryorder'):
|
||||
assert terminal.display is True
|
||||
|
||||
assert terminal.get_arrow(None) is not None
|
||||
assert terminal.get_arrow(True) is not None
|
||||
assert terminal.get_arrow(False) is not None
|
||||
assert terminal.ascii == config['ascii']
|
||||
assert terminal.loader is not None
|
||||
|
||||
assert terminal.MIN_HEIGHT is not None
|
||||
assert terminal.MIN_WIDTH is not None
|
||||
|
||||
|
||||
def test_terminal_functions(terminal):
|
||||
|
||||
terminal.flash()
|
||||
assert curses.flash.called
|
||||
|
||||
terminal.getch()
|
||||
assert terminal.stdscr.getch.called
|
||||
|
||||
with pytest.raises(RuntimeError):
|
||||
with terminal.no_delay():
|
||||
raise RuntimeError()
|
||||
terminal.stdscr.nodelay.assert_any_call(0)
|
||||
terminal.stdscr.nodelay.assert_any_call(1)
|
||||
|
||||
curses.endwin.reset_mock()
|
||||
curses.doupdate.reset_mock()
|
||||
with terminal.suspend():
|
||||
pass
|
||||
assert curses.endwin.called
|
||||
assert curses.doupdate.called
|
||||
|
||||
curses.endwin.reset_mock()
|
||||
curses.doupdate.reset_mock()
|
||||
with pytest.raises(RuntimeError):
|
||||
with terminal.suspend():
|
||||
raise RuntimeError()
|
||||
assert curses.endwin.called
|
||||
assert curses.doupdate.called
|
||||
|
||||
terminal.addch(terminal.stdscr, 3, 5, 'ch', 'attr')
|
||||
terminal.stdscr.addch.assert_called_with(3, 5, 'ch', 'attr')
|
||||
|
||||
|
||||
def test_terminal_clean_ascii(terminal):
|
||||
|
||||
terminal.ascii = True
|
||||
|
||||
# unicode returns ascii
|
||||
text = terminal.clean('hello ❤')
|
||||
assert isinstance(text, six.binary_type)
|
||||
assert text.decode('ascii') == 'hello ?'
|
||||
|
||||
# utf-8 returns ascii
|
||||
text = terminal.clean('hello ❤'.encode('utf-8'))
|
||||
assert isinstance(text, six.binary_type)
|
||||
assert text.decode('ascii') == 'hello ?'
|
||||
|
||||
# ascii returns ascii
|
||||
text = terminal.clean('hello'.encode('ascii'))
|
||||
assert isinstance(text, six.binary_type)
|
||||
assert text.decode('ascii') == 'hello'
|
||||
|
||||
|
||||
def test_terminal_clean_unicode(terminal):
|
||||
|
||||
terminal.ascii = False
|
||||
|
||||
# unicode returns utf-8
|
||||
text = terminal.clean('hello ❤')
|
||||
assert isinstance(text, six.binary_type)
|
||||
assert text.decode('utf-8') == 'hello ❤'
|
||||
|
||||
# utf-8 returns utf-8
|
||||
text = terminal.clean('hello ❤'.encode('utf-8'))
|
||||
assert isinstance(text, six.binary_type)
|
||||
assert text.decode('utf-8') == 'hello ❤'
|
||||
|
||||
# ascii returns utf-8
|
||||
text = terminal.clean('hello'.encode('ascii'))
|
||||
assert isinstance(text, six.binary_type)
|
||||
assert text.decode('utf-8') == 'hello'
|
||||
|
||||
|
||||
def test_terminal_clean_ncols(terminal):
|
||||
|
||||
text = terminal.clean('hello', n_cols=5)
|
||||
assert text.decode('utf-8') == 'hello'
|
||||
|
||||
text = terminal.clean('hello', n_cols=4)
|
||||
assert text.decode('utf-8') == 'hell'
|
||||
|
||||
text = terminal.clean('hello', n_cols=10)
|
||||
assert text.decode('utf-8') == 'hello'
|
||||
|
||||
text = terminal.clean('hello', n_cols=9)
|
||||
assert text.decode('utf-8') == 'hell'
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ascii', [True, False])
|
||||
def test_terminal_add_line(terminal, stdscr, ascii):
|
||||
|
||||
terminal.ascii = ascii
|
||||
|
||||
terminal.add_line(stdscr, 'hello')
|
||||
assert stdscr.addstr.called_with(0, 0, 'hello'.encode('ascii'))
|
||||
stdscr.reset_mock()
|
||||
|
||||
# Text will be drawn, but cut off to fit on the screen
|
||||
terminal.add_line(stdscr, 'hello', row=3, col=75)
|
||||
assert stdscr.addstr.called_with((3, 75, 'hell'.encode('ascii')))
|
||||
stdscr.reset_mock()
|
||||
|
||||
# Outside of screen bounds, don't even try to draw the text
|
||||
terminal.add_line(stdscr, 'hello', col=79)
|
||||
assert not stdscr.addstr.called
|
||||
stdscr.reset_mock()
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ascii', [True, False])
|
||||
def test_show_notification(terminal, stdscr, ascii):
|
||||
|
||||
terminal.ascii = ascii
|
||||
|
||||
# The whole message should fit in 40x80
|
||||
text = HELP.strip().splitlines()
|
||||
terminal.show_notification(text)
|
||||
assert stdscr.subwin.nlines == len(text) + 2
|
||||
assert stdscr.subwin.ncols == 80
|
||||
assert stdscr.subwin.addstr.call_count == len(text)
|
||||
stdscr.reset_mock()
|
||||
|
||||
# The text should be trimmed to fit in 20x20
|
||||
stdscr.nlines, stdscr.ncols = 15, 20
|
||||
text = HELP.strip().splitlines()
|
||||
terminal.show_notification(text)
|
||||
assert stdscr.subwin.nlines == 15
|
||||
assert stdscr.subwin.ncols == 20
|
||||
assert stdscr.subwin.addstr.call_count == 13
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ascii', [True, False])
|
||||
def test_text_input(terminal, stdscr, ascii):
|
||||
|
||||
terminal.ascii = ascii
|
||||
stdscr.nlines = 1
|
||||
|
||||
# Text will be wrong because stdscr.inch() is not implemented
|
||||
# But we can at least tell if text was captured or not
|
||||
stdscr.getch.side_effect = [ord('h'), ord('i'), ord('!'), terminal.RETURN]
|
||||
assert isinstance(terminal.text_input(stdscr), six.text_type)
|
||||
|
||||
stdscr.getch.side_effect = [ord('b'), ord('y'), ord('e'), terminal.ESCAPE]
|
||||
assert terminal.text_input(stdscr) is None
|
||||
|
||||
stdscr.getch.side_effect = [ord('h'), curses.KEY_RESIZE, terminal.RETURN]
|
||||
assert terminal.text_input(stdscr, allow_resize=True) is not None
|
||||
|
||||
stdscr.getch.side_effect = [ord('h'), curses.KEY_RESIZE, terminal.RETURN]
|
||||
assert terminal.text_input(stdscr, allow_resize=False) is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ascii', [True, False])
|
||||
def test_prompt_input(terminal, stdscr, ascii):
|
||||
|
||||
terminal.ascii = ascii
|
||||
window = stdscr.derwin()
|
||||
|
||||
window.getch.side_effect = [ord('h'), ord('i'), terminal.RETURN]
|
||||
assert isinstance(terminal.prompt_input('hi'), six.text_type)
|
||||
|
||||
attr = Color.CYAN | curses.A_BOLD
|
||||
stdscr.addstr.assert_called_with(39, 0, 'hi'.encode('ascii'), attr)
|
||||
assert window.nlines == 1
|
||||
assert window.ncols == 78
|
||||
|
||||
window.getch.side_effect = [ord('b'), ord('y'), ord('e'), terminal.ESCAPE]
|
||||
assert terminal.prompt_input('hi') is None
|
||||
|
||||
stdscr.getch.side_effect = [ord('b'), ord('e'), terminal.RETURN]
|
||||
assert terminal.prompt_input('hi', key=True) == ord('b')
|
||||
|
||||
stdscr.getch.side_effect = [terminal.ESCAPE, ord('e'), ord('l')]
|
||||
assert terminal.prompt_input('hi', key=True) is None
|
||||
|
||||
|
||||
def test_prompt_y_or_n(terminal, stdscr):
|
||||
|
||||
stdscr.getch.side_effect = [ord('y'), ord('N'), terminal.ESCAPE, ord('a')]
|
||||
attr = Color.CYAN | curses.A_BOLD
|
||||
|
||||
# Press 'y'
|
||||
assert terminal.prompt_y_or_n('hi')
|
||||
stdscr.addstr.assert_called_with(39, 0, 'hi'.encode('ascii'), attr)
|
||||
assert not curses.flash.called
|
||||
|
||||
# Press 'N'
|
||||
assert not terminal.prompt_y_or_n('hi')
|
||||
stdscr.addstr.assert_called_with(39, 0, 'hi'.encode('ascii'), attr)
|
||||
assert not curses.flash.called
|
||||
|
||||
# Press Esc
|
||||
assert not terminal.prompt_y_or_n('hi')
|
||||
stdscr.addstr.assert_called_with(39, 0, 'hi'.encode('ascii'), attr)
|
||||
assert not curses.flash.called
|
||||
|
||||
# Press an invalid key
|
||||
assert not terminal.prompt_y_or_n('hi')
|
||||
stdscr.addstr.assert_called_with(39, 0, 'hi'.encode('ascii'), attr)
|
||||
assert curses.flash.called
|
||||
|
||||
|
||||
def test_open_editor(terminal):
|
||||
|
||||
comment = COMMENT_EDIT_FILE.format(content='#| This is a comment! ❤')
|
||||
data = {'filename': None}
|
||||
|
||||
def side_effect(args):
|
||||
data['filename'] = args[1]
|
||||
with codecs.open(data['filename'], 'r+', 'utf-8') as fp:
|
||||
assert fp.read() == comment
|
||||
fp.write('This is an amended comment! ❤')
|
||||
return mock.Mock()
|
||||
|
||||
with mock.patch('subprocess.Popen', autospec=True) as Popen:
|
||||
Popen.side_effect = side_effect
|
||||
|
||||
reply_text = terminal.open_editor(comment)
|
||||
assert reply_text == 'This is an amended comment! ❤'
|
||||
assert not os.path.isfile(data['filename'])
|
||||
assert curses.endwin.called
|
||||
assert curses.doupdate.called
|
||||
|
||||
|
||||
def test_open_browser(terminal):
|
||||
|
||||
url = 'http://www.test.com'
|
||||
|
||||
terminal._display = True
|
||||
with mock.patch('subprocess.check_call', autospec=True) as check_call:
|
||||
terminal.open_browser(url)
|
||||
assert check_call.called
|
||||
assert not curses.endwin.called
|
||||
assert not curses.doupdate.called
|
||||
|
||||
terminal._display = False
|
||||
with mock.patch('webbrowser.open_new_tab', autospec=True) as open_new_tab:
|
||||
terminal.open_browser(url)
|
||||
open_new_tab.assert_called_with(url)
|
||||
assert curses.endwin.called
|
||||
assert curses.doupdate.called
|
||||
Reference in New Issue
Block a user