Implement compact look and feel.

This comes with the addition of adding a reference to the config in
SubredditPage objects, which breaks a lot of tests. Thoroughly discussed
in #3.
This commit is contained in:
John Helmert
2019-06-28 17:24:26 -05:00
parent d793781089
commit 6508131212
3 changed files with 141 additions and 24 deletions

View File

@@ -12,6 +12,7 @@ from bs4 import BeautifulSoup
from kitchen.text.display import wrap
from . import exceptions
from .config import Config
from .packages import praw
from .packages.praw.errors import InvalidSubreddit
from .packages.praw.helpers import normalize_url
@@ -563,18 +564,23 @@ class SubredditContent(Content):
list for repeat access.
"""
def __init__(self, name, submissions, loader, order=None,
max_title_rows=4, query=None, filter_nsfw=False):
def __init__(self, config, name, submissions, loader, order=None,
query=None, filter_nsfw=False):
self.config = config
self.name = name
self.order = order
self.query = query
self.max_title_rows = max_title_rows
self.filter_nsfw = filter_nsfw
self._loader = loader
self._submissions = submissions
self._submission_data = []
if self.config['look_and_feel'] == 'compact':
self.max_title_rows = 1
else:
self.max_title_rows = 4
# Verify that content exists for the given submission generator.
# This is necessary because PRAW loads submissions lazily, and
# there is is no other way to check things like multireddits that
@@ -588,7 +594,7 @@ class SubredditContent(Content):
raise exceptions.NoSubmissionsError(full_name)
@classmethod
def from_name(cls, reddit, name, loader, order=None, query=None):
def from_name(cls, reddit, config, name, loader, order=None, query=None):
"""
Params:
reddit (praw.Reddit): Instance of the reddit api.
@@ -796,7 +802,7 @@ class SubredditContent(Content):
filter_nsfw = (reddit.user and reddit.user.over_18 is False)
# We made it!
return cls(display_name, submissions, loader, order=display_order,
return cls(config, display_name, submissions, loader, order=display_order,
query=query, filter_nsfw=filter_nsfw)
@property
@@ -847,17 +853,22 @@ class SubredditContent(Content):
data = self.strip_praw_comment(submission)
data['index'] = len(self._submission_data) + 1
# Add the post number to the beginning of the title
data['title'] = '{0}. {1}'.format(data['index'], data['title'])
# Add the post number to the beginning of the title if necessary
if self.config['look_and_feel'] != 'compact':
data['title'] = '{0}. {1}'.format(data['index'], data['title'])
self._submission_data.append(data)
# Modifies the original dict, faster than copying
data = self._submission_data[index]
data['split_title'] = self.wrap_text(data['title'], width=n_cols)
if len(data['split_title']) > self.max_title_rows:
data['split_title'] = data['split_title'][:self.max_title_rows-1]
data['split_title'].append('(Not enough space to display)')
data['n_rows'] = len(data['split_title']) + 3
if self.config['look_and_feel'] == 'compact':
data['n_rows'] = 2
else:
data['split_title'] = self.wrap_text(data['title'], width=n_cols)
data['n_rows'] = len(data['split_title']) + 3
data['h_offset'] = 0
return data

View File

@@ -28,7 +28,7 @@ class SubredditPage(Page):
super(SubredditPage, self).__init__(reddit, term, config, oauth)
self.controller = SubredditController(self, keymap=config.keymap)
self.content = SubredditContent.from_name(reddit, name, term.loader)
self.content = SubredditContent.from_name(reddit, self.config, name, term.loader)
self.nav = Navigator(self.content.get)
self.toggled_subreddit = None
@@ -68,7 +68,8 @@ class SubredditPage(Page):
with self.term.loader('Refreshing page'):
self.content = SubredditContent.from_name(
self.reddit, name, self.term.loader, order=order, query=query)
self.reddit, self.config, name,
self.term.loader, order=order, query=query)
if not self.term.loader.exception:
self.nav = Navigator(self.content.get)
@@ -133,7 +134,7 @@ class SubredditPage(Page):
with self.term.loader('Searching'):
self.content = SubredditContent.from_name(
self.reddit, name, self.term.loader, query=query)
self.reddit, self.config, name, self.term.loader, query=query)
if not self.term.loader.exception:
self.nav = Navigator(self.content.get)
@@ -233,36 +234,36 @@ class SubredditPage(Page):
with self.term.loader('Hiding'):
data['object'].hide()
data['hidden'] = True
def _draw_item(self, win, data, inverted):
n_rows, n_cols = win.getmaxyx()
n_cols -= 1 # Leave space for the cursor in the first column
# Handle the case where the window is not large enough to fit the data.
valid_rows = range(0, n_rows)
offset = 0 if not inverted else -(data['n_rows'] - n_rows)
def _draw_item_default(self, win, data, n_rows, n_cols, valid_rows, offset):
"""
Draw items with default look and feel
"""
n_title = len(data['split_title'])
if data['url_full'] in self.config.history:
attr = self.term.attr('SubmissionTitleSeen')
else:
attr = self.term.attr('SubmissionTitle')
for row, text in enumerate(data['split_title'], start=offset):
if row in valid_rows:
self.term.add_line(win, text, row, 1, attr)
row = n_title + offset
if data['url_full'] in self.config.history:
attr = self.term.attr('LinkSeen')
else:
attr = self.term.attr('Link')
if row in valid_rows:
self.term.add_line(win, '{url}'.format(**data), row, 1, attr)
row = n_title + offset + 1
if row in valid_rows:
if row in valid_rows:
attr = self.term.attr('Score')
self.term.add_line(win, '{score}'.format(**data), row, 1, attr)
self.term.add_space(win)
@@ -311,6 +312,7 @@ class SubredditPage(Page):
self.term.add_line(win, 'NSFW', attr=attr)
row = n_title + offset + 2
if row in valid_rows:
attr = self.term.attr('SubmissionAuthor')
self.term.add_line(win, '{author}'.format(**data), row, 1, attr)
@@ -324,6 +326,103 @@ class SubredditPage(Page):
self.term.add_space(win)
self.term.add_line(win, '{flair}'.format(**data), attr=attr)
def _draw_item_compact(self, win, data, n_rows, n_cols, valid_rows, offset):
"""
Draw items with compact look and feel
"""
if data['url_full'] in self.config.history:
sub_attr = self.term.attr('SubmissionTitleSeen')
else:
sub_attr = self.term.attr('SubmissionTitle')
if offset in valid_rows:
self.term.add_line(win, '{title}'.format(**data), offset, 1, attr=sub_attr)
offset += 1 # Next row
if offset in valid_rows:
sep_attr = self.term.attr('Separator')
self.term.add_line(win, '<', offset, 1, attr=sep_attr)
self.term.add_line(win, '{index}'.format(**data), offset, attr=sub_attr)
self.term.add_line(win, '|', offset, attr=sep_attr)
# Seems that praw doesn't give us raw numbers for score and comment
# count, so we have to cut off the extraneous characters
attr = self.term.attr('Score')
self.term.add_line(win, '{0}'.format(data['score'][:-4]), offset, attr=attr)
arrow, attr = self.term.get_arrow(data['likes'])
self.term.add_line(win, arrow, attr=attr)
if data['comments'] is not None:
self.term.add_line(win, '|', offset, attr=sep_attr)
attr = self.term.attr('CommentCount')
self.term.add_line(win, '{0}C'.format(data['comments'][:-9]), attr=attr)
self.term.add_line(win, '>', offset, attr=sep_attr)
self.term.add_space(win)
attr = self.term.attr('Created')
self.term.add_line(win, '{created}{edited}'.format(**data), attr=attr)
self.term.add_space(win)
attr = self.term.attr('SubmissionAuthor')
self.term.add_line(win, '{author}'.format(**data), offset, attr=attr)
self.term.add_space(win)
attr = self.term.attr('SubmissionSubreddit')
self.term.add_line(win, '/r/{subreddit}'.format(**data), attr=attr)
if data['saved']:
attr = self.term.attr('Saved')
self.term.add_space(win)
self.term.add_line(win, '[saved]', attr=attr)
if data['hidden']:
attr = self.term.attr('Hidden')
self.term.add_space(win)
self.term.add_line(win, '[hidden]', attr=attr)
if data['stickied']:
attr = self.term.attr('Stickied')
self.term.add_space(win)
self.term.add_line(win, '[stickied]', attr=attr)
if data['gold']:
attr = self.term.attr('Gold')
self.term.add_space(win)
count = 'x{}'.format(data['gold']) if data['gold'] > 1 else ''
text = self.term.gilded + count
self.term.add_line(win, text, attr=attr)
if data['nsfw']:
attr = self.term.attr('NSFW')
self.term.add_space(win)
self.term.add_line(win, 'NSFW', attr=attr)
if data['flair']:
attr = self.term.attr('SubmissionFlair')
self.term.add_space(win)
self.term.add_line(win, '{flair}'.format(**data), attr=attr)
def _draw_item(self, win, data, inverted):
n_rows, n_cols = win.getmaxyx()
n_cols -= 1 # Leave space for the cursor in the first column
# Handle the case where the window is not large enough to fit the data.
valid_rows = range(0, n_rows)
offset = 0 if not inverted else - (data['n_rows'] - n_rows)
if self.config['look_and_feel'] == 'compact':
self._draw_item_compact(win, data, n_rows, n_cols, valid_rows, offset)
else:
self._draw_item_default(win, data, n_rows, n_cols, valid_rows, offset)
attr = self.term.attr('CursorBlock')
for y in range(n_rows):
self.term.addch(win, y, 0, str(' '), attr)

View File

@@ -58,6 +58,13 @@ max_comment_cols = 120
; Hide username if logged in, display "Logged in" instead
hide_username = False
; Set the look and feel. Default allows posts to be spread across 4 lines,
; while compact reduces it to 2 lines. Compact reduces the vertical space
; the cost of horizontal space - the title won't be wrapped to the next
; line.
; look_and_feel = default
; look_and_feel = compact
; Color theme, use "tuir --list-themes" to view a list of valid options.
; This can be an absolute filepath, or the name of a theme file that has
; been installed into either the custom of default theme paths.