Adding tests and some minor tweaks to structure.

This commit is contained in:
Michael Lazar
2018-10-01 00:45:09 -04:00
parent 67fb93b2ef
commit e4cced27eb
5 changed files with 158 additions and 49 deletions

View File

@@ -8,6 +8,7 @@ from datetime import datetime
from timeit import default_timer as timer
import six
from bs4 import BeautifulSoup
from kitchen.text.display import wrap
from . import exceptions
@@ -317,6 +318,22 @@ class Content(object):
out.extend(lines)
return out
@staticmethod
def extract_links(html):
"""
Extract a list of hyperlinks from an HTMl document.
"""
links = []
soup = BeautifulSoup(html, 'html.parser')
for link in soup.findAll('a'):
href = link.get('href')
if not href:
continue
if href.startswith('/'):
href = 'https://www.reddit.com' + href
links.append({'text': link.text, 'href': href})
return links
class SubmissionContent(Content):
"""

View File

@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from bs4 import BeautifulSoup
import re
import time
@@ -139,12 +138,11 @@ class SubmissionPage(Page):
@SubmissionController.register(Command('SUBMISSION_OPEN_IN_BROWSER'))
def open_link(self):
"""
Open the selected link
Open the link contained in the selected item.
Prompt user to choose which link to open if additional links
are mentioned at the item.
If there is more than one link contained in the item, prompt the user
to choose which link to open.
"""
data = self.get_selected_item()
if data['type'] == 'Submission':
opened_link = self.prompt_and_open_link(data)
@@ -156,29 +154,25 @@ class SubmissionPage(Page):
self.term.flash()
def prompt_and_open_link(self, data):
links = [{'text': 'Permalink', 'href': data['permalink']}]
if data['html']:
links += self.get_links_in_html(data['html'])
if len(links) > 1:
link = self.term.prompt_user_to_select_link(links)
elif 'url_full' in data and data['url_full']:
url_full = data.get('url_full')
if url_full and url_full != data['permalink']:
# The item is a link-only submission that won't contain text
link = data['url_full']
else:
link = data['permalink']
extracted_links = self.content.extract_links(data['html'])
if not extracted_links:
# Only one selection to choose from, so just pick it
link = data['permalink']
else:
# Let the user decide which link to open
links = [{'text': 'Permalink', 'href': data['permalink']}]
links += extracted_links
link = self.term.prompt_user_to_select_link(links)
if link is not None:
self.term.open_link(link)
return link
def get_links_in_html(self, html):
links = []
soup = BeautifulSoup(html)
for link in soup.findAll('a'):
link = {'text': link.text, 'href': link.get('href')}
if link['href'].startswith('/'):
link['href'] = 'https://www.reddit.com' + link['href']
links.append(link)
return links
@SubmissionController.register(Command('SUBMISSION_OPEN_IN_PAGER'))
def open_pager(self):
"""

View File

@@ -355,9 +355,16 @@ class Terminal(object):
return ch
def prompt_user_to_select_link(self, links):
"""
Prompt the user to select a link from a list to open.
Return the link that was selected, or ``None`` if no link was selected.
"""
link_pages = self.get_link_pages(links)
for link_page in link_pages:
text = self.get_link_page_text(link_page)
for n, link_page in enumerate(link_pages, start=1):
text = 'Select a link to open (page {} of {}):\n\n'
text = text.format(n, len(link_pages))
text += self.get_link_page_text(link_page)
if link_page is not link_pages[-1]:
text += '[9] next page...'
@@ -371,7 +378,14 @@ class Terminal(object):
return None
return link_page[choice - 1]['href']
def get_link_pages(self, links):
@staticmethod
def get_link_pages(links):
"""
Given a list of links, separate them into pages that can be displayed
to the user and navigated using the 1-9 number keys. The last page
can contain up to 9 links, and all other pages can contain up to 8
links.
"""
link_pages = []
i = 0
while i < len(links):
@@ -385,13 +399,16 @@ class Terminal(object):
link_pages.append(link_page)
return link_pages
def get_link_page_text(self, link_page):
text = 'Open link:\n'
@staticmethod
def get_link_page_text(link_page):
"""
Construct the dialog box to display a list of links to the user.
"""
text = ''
for i, link in enumerate(link_page):
capped_link_text = (link['text'] if len(link['text']) <= 20
else link['text'][:19] + '')
text += '[{}] [{}]({})\n'.format(
i + 1, capped_link_text, link['href'])
text += '[{}] [{}]({})\n'.format(i + 1, capped_link_text, link['href'])
return text
def open_link(self, url):