Adding tests and some minor tweaks to structure.
This commit is contained in:
@@ -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):
|
||||
"""
|
||||
|
||||
@@ -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):
|
||||
"""
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user