diff --git a/rtv/content.py b/rtv/content.py index 3b542f1..a10d808 100644 --- a/rtv/content.py +++ b/rtv/content.py @@ -148,6 +148,7 @@ class Content(object): data['type'] = 'Comment' data['level'] = comment.nested_level data['body'] = comment.body + data['html'] = comment.body_html data['created'] = cls.humanize_timestamp(comment.created_utc) data['score'] = '{0} pts'.format( '-' if comment.score_hidden else comment.score) @@ -217,6 +218,7 @@ class Content(object): data['type'] = 'Submission' data['title'] = sub.title data['text'] = sub.selftext + data['html'] = sub.selftext_html data['created'] = cls.humanize_timestamp(sub.created_utc) data['created_long'] = cls.humanize_timestamp(sub.created_utc, True) data['comments'] = '{0} comments'.format(sub.num_comments) diff --git a/rtv/submission_page.py b/rtv/submission_page.py index 5d11876..6c70c0f 100644 --- a/rtv/submission_page.py +++ b/rtv/submission_page.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals +from bs4 import BeautifulSoup import re import time @@ -138,18 +139,46 @@ class SubmissionPage(Page): @SubmissionController.register(Command('SUBMISSION_OPEN_IN_BROWSER')) def open_link(self): """ - Open the selected item with the web browser + Open the selected link + + Prompt user to choose which link to open if additional links + are mentioned at the item. """ data = self.get_selected_item() if data['type'] == 'Submission': - self.term.open_link(data['url_full']) - self.config.history.add(data['url_full']) + opened_link = self.prompt_and_open_link(data) + if opened_link is not None: + self.config.history.add(opened_link) elif data['type'] == 'Comment' and data['permalink']: - self.term.open_browser(data['permalink']) + self.prompt_and_open_link(data) else: 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']: + link = data['url_full'] + else: + link = data['permalink'] + 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): """ diff --git a/rtv/terminal.py b/rtv/terminal.py index 6d241d8..b81eebc 100644 --- a/rtv/terminal.py +++ b/rtv/terminal.py @@ -354,6 +354,46 @@ class Terminal(object): return ch + def prompt_user_to_select_link(self, links): + link_pages = self.get_link_pages(links) + for link_page in link_pages: + text = self.get_link_page_text(link_page) + if link_page is not link_pages[-1]: + text += '[9] next page...' + + try: + choice = int(chr(self.show_notification(text))) + except ValueError: + return None + if link_page is not link_pages[-1] and choice == 9: + continue + elif choice == 0 or choice > len(link_page): + return None + return link_page[choice - 1]['href'] + + def get_link_pages(self, links): + link_pages = [] + i = 0 + while i < len(links): + link_page = [] + while i < len(links) and len(link_page) < 8: + link_page.append(links[i]) + i += 1 + if i == len(links) - 1: + link_page.append(links[i]) + i += 1 + link_pages.append(link_page) + return link_pages + + def get_link_page_text(self, link_page): + text = 'Open link:\n' + 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']) + return text + def open_link(self, url): """ Open a media link using the definitions from the user's mailcap file.