Comments are now forced to sort by "hot" in all cases.

This commit is contained in:
Michael Lazar
2015-03-18 00:46:36 -07:00
parent fd9cbd8841
commit 52c7c0730d
5 changed files with 113 additions and 109 deletions

View File

@@ -50,7 +50,7 @@ def humanize_timestamp(utc_timestamp, verbose=False):
return ('%d years ago' % years) if verbose else ('%dyr' % years) return ('%d years ago' % years) if verbose else ('%dyr' % years)
@contextmanager @contextmanager
def default_loader(self): def default_loader():
yield yield
class BaseContent(object): class BaseContent(object):
@@ -85,6 +85,8 @@ class BaseContent(object):
retval = [] retval = []
while stack: while stack:
item = stack.pop(0) item = stack.pop(0)
if isinstance(item, praw.objects.MoreComments) and (item.count==0):
continue
nested = getattr(item, 'replies', None) nested = getattr(item, 'replies', None)
if nested: if nested:
for n in nested: for n in nested:
@@ -104,11 +106,6 @@ class BaseContent(object):
data['object'] = comment data['object'] = comment
data['level'] = comment.nested_level data['level'] = comment.nested_level
if getattr(comment.submission, 'author'):
sub_author = comment.submission.author.name
else:
sub_author = '[deleted]'
if isinstance(comment, praw.objects.MoreComments): if isinstance(comment, praw.objects.MoreComments):
data['type'] = 'MoreComments' data['type'] = 'MoreComments'
data['count'] = comment.count data['count'] = comment.count
@@ -119,7 +116,7 @@ class BaseContent(object):
data['created'] = humanize_timestamp(comment.created_utc) data['created'] = humanize_timestamp(comment.created_utc)
data['score'] = '{} pts'.format(comment.score) data['score'] = '{} pts'.format(comment.score)
data['author'] = (comment.author.name if getattr(comment, 'author') else '[deleted]') data['author'] = (comment.author.name if getattr(comment, 'author') else '[deleted]')
data['is_author'] = (data['author'] == sub_author) data['is_author'] = (data['author'] == getattr(comment.submission, 'author'))
data['flair'] = (comment.author_flair_text if comment.author_flair_text else '') data['flair'] = (comment.author_flair_text if comment.author_flair_text else '')
data['likes'] = comment.likes data['likes'] = comment.likes
@@ -170,11 +167,11 @@ class SubmissionContent(BaseContent):
self.max_indent_level = max_indent_level self.max_indent_level = max_indent_level
self._loader = loader self._loader = loader
self._submission = submission self._submission = submission
self._submission_data = None
self._comment_data = None
self.name = None
self.reset() self._submission_data = self.strip_praw_submission(self._submission)
self.name = self._submission_data['permalink']
comments = self.flatten_comments(self._submission.comments)
self._comment_data = [self.strip_praw_comment(c) for c in comments]
@classmethod @classmethod
def from_url( def from_url(
@@ -187,22 +184,12 @@ class SubmissionContent(BaseContent):
try: try:
with loader(): with loader():
submission = reddit.get_submission(url) submission = reddit.get_submission(url, comment_sort='hot')
except praw.errors.APIException: except praw.errors.APIException:
raise SubmissionURLError(url) raise SubmissionURLError(url)
return cls(submission, loader, indent_size, max_indent_level) return cls(submission, loader, indent_size, max_indent_level)
def reset(self):
with self._loader():
self._submission.refresh()
self._submission_data = self.strip_praw_submission(self._submission)
self.name = self._submission_data['permalink']
comments = self.flatten_comments(self._submission.comments)
self._comment_data = [self.strip_praw_comment(c) for c in comments]
def get(self, index, n_cols=70): def get(self, index, n_cols=70):
""" """
Grab the `i`th submission, with the title field formatted to fit inside Grab the `i`th submission, with the title field formatted to fit inside
@@ -269,7 +256,7 @@ class SubmissionContent(BaseContent):
elif data['type'] == 'MoreComments': elif data['type'] == 'MoreComments':
with self._loader(): with self._loader():
comments = data['object'].comments() comments = data['object'].comments(update=False)
comments = self.flatten_comments(comments, root_level=data['level']) comments = self.flatten_comments(comments, root_level=data['level'])
comment_data = [self.strip_praw_comment(c) for c in comments] comment_data = [self.strip_praw_comment(c) for c in comments]
self._comment_data[index:index+1] = comment_data self._comment_data[index:index+1] = comment_data

View File

@@ -3,7 +3,8 @@ import sys
from .content import SubmissionContent from .content import SubmissionContent
from .page import BasePage from .page import BasePage
from .utils import LoadScreen, Color, Symbol, display_help, open_browser from .utils import Color, Symbol, display_help
from .workers import LoadScreen, open_browser
class SubmissionPage(BasePage): class SubmissionPage(BasePage):
@@ -80,7 +81,8 @@ class SubmissionPage(BasePage):
def refresh_content(self): def refresh_content(self):
self.content.reset() url = self.content.name
self.content = SubmissionContent.from_url(self.reddit, url, self.loader)
self.nav.page_index, self.nav.cursor_index = -1, 0 self.nav.page_index, self.nav.cursor_index = -1, 0
self.nav.inverted = False self.nav.inverted = False

View File

@@ -7,8 +7,8 @@ from .errors import SubredditNameError
from .page import BasePage from .page import BasePage
from .submission import SubmissionPage from .submission import SubmissionPage
from .content import SubredditContent from .content import SubredditContent
from .utils import (LoadScreen, Symbol, Color, text_input, display_message, from .utils import Symbol, Color, text_input, display_message, display_help
display_help, open_browser) from .workers import LoadScreen, open_browser
# Used to keep track of browsing history across the current session # Used to keep track of browsing history across the current session
_opened_links = set() _opened_links = set()
@@ -108,7 +108,7 @@ class SubredditPage(BasePage):
"Select the current submission to view posts" "Select the current submission to view posts"
data = self.content.get(self.nav.absolute_index) data = self.content.get(self.nav.absolute_index)
page = SubmissionPage(self.stdscr, self.reddit, submission=data['object']) page = SubmissionPage(self.stdscr, self.reddit, url=data['permalink'])
page.loop() page.loop()
if data['url'] == 'selfpost': if data['url'] == 'selfpost':

View File

@@ -1,9 +1,5 @@
import os import os
import sys
import subprocess
import curses import curses
import time
import threading
from curses import textpad, ascii from curses import textpad, ascii
from contextlib import contextmanager from contextlib import contextmanager
@@ -193,82 +189,6 @@ def display_help(stdscr):
help_msgs = HELP.split("\n") help_msgs = HELP.split("\n")
display_message(stdscr, help_msgs) display_message(stdscr, help_msgs)
class LoadScreen(object):
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='...'):
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):
# Delay before starting animation to avoid wasting resources if the
# wait time is very short
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)
def open_browser(url):
"""
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.
"""
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)
@contextmanager @contextmanager
def curses_session(): def curses_session():
@@ -316,4 +236,4 @@ def curses_session():
stdscr.keypad(0) stdscr.keypad(0)
curses.echo() curses.echo()
curses.nocbreak() curses.nocbreak()
curses.endwin() curses.endwin()

95
rtv/workers.py Normal file
View File

@@ -0,0 +1,95 @@
import time
import sys
import os
import threading
import subprocess
def open_browser(url):
"""
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.
"""
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)
class LoadScreen(object):
"""
Display a loading dialog while waiting for a blocking action to complete.
This class spins off a seperate 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='...'):
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()
# Check for timeout error
def animate(self, delay, interval, message, trail):
# Delay before starting animation to avoid wasting resources if the
# wait time is very short
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)