From 14bbb49460bd48c351bbd04421dce2b3d5b56f1a Mon Sep 17 00:00:00 2001 From: codesoap Date: Sun, 12 Aug 2018 19:37:03 +0200 Subject: [PATCH 1/7] Issue #593: Allow opening links Give the user the ability to open links, that are mentioned in comments and submissions. --- rtv/content.py | 2 ++ rtv/submission_page.py | 48 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/rtv/content.py b/rtv/content.py index f174e39..eeed309 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['body_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['text_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 5cbc5ad..e317365 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,59 @@ 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.open_submission_or_permalink_or_mentioned_link(data) self.config.history.add(data['url_full']) elif data['type'] == 'Comment' and data['permalink']: - self.term.open_browser(data['permalink']) + self.open_submission_or_permalink_or_mentioned_link(data) else: self.term.flash() + def open_submission_or_permalink_or_mentioned_link(self, data): + links_in_data = [] + if 'body_html' in data and data['body_html']: + links_in_data = self.get_links_in_html(data['body_html']) + elif 'text_html' in data and data['text_html']: + links_in_data = self.get_links_in_html(data['text_html']) + + if links_in_data: + self.prompt_user_and_open_selected_link(data, links_in_data) + elif 'url_full' in data and data['url_full']: + self.term.open_link(data['url_full']) + else: + self.term.open_browser(data['permalink']) + + 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 + + def prompt_user_and_open_selected_link(self, data, links): + text = 'Open link:\n' + text += ('[1] Permalink to this %s\n' % (data['type'].lower(),)) + for i, link in enumerate(links[:8]): + text += '[%s] [%s](%s)\n' % (i + 2, link['text'], link['href']) + try: + choice = int(chr(self.term.show_notification(text))) + except ValueError: + return + if choice == 1: + self.term.open_browser(data['permalink']) + elif choice - 2 < len(links): + self.term.open_link(links[choice - 2]['href']) + @SubmissionController.register(Command('SUBMISSION_OPEN_IN_PAGER')) def open_pager(self): """ From 7e3788df0ce49e7380dec45b6277c86c2427f674 Mon Sep 17 00:00:00 2001 From: codesoap Date: Sun, 19 Aug 2018 11:59:03 +0200 Subject: [PATCH 2/7] Use the same name for the html field everywhere --- rtv/content.py | 4 ++-- rtv/submission_page.py | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/rtv/content.py b/rtv/content.py index eeed309..c1a247c 100644 --- a/rtv/content.py +++ b/rtv/content.py @@ -148,7 +148,7 @@ class Content(object): data['type'] = 'Comment' data['level'] = comment.nested_level data['body'] = comment.body - data['body_html'] = comment.body_html + 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) @@ -218,7 +218,7 @@ class Content(object): data['type'] = 'Submission' data['title'] = sub.title data['text'] = sub.selftext - data['text_html'] = sub.selftext_html + 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 e317365..32c9bf1 100644 --- a/rtv/submission_page.py +++ b/rtv/submission_page.py @@ -156,10 +156,8 @@ class SubmissionPage(Page): def open_submission_or_permalink_or_mentioned_link(self, data): links_in_data = [] - if 'body_html' in data and data['body_html']: - links_in_data = self.get_links_in_html(data['body_html']) - elif 'text_html' in data and data['text_html']: - links_in_data = self.get_links_in_html(data['text_html']) + if data['html']: + links_in_data = self.get_links_in_html(data['html']) if links_in_data: self.prompt_user_and_open_selected_link(data, links_in_data) From dceea8a5a31ac43d9c0848ab65a26550f0902b0b Mon Sep 17 00:00:00 2001 From: codesoap Date: Sun, 19 Aug 2018 15:20:31 +0200 Subject: [PATCH 3/7] Treat the item's permalink as a regular link Also fix some string formatting along the way. --- rtv/submission_page.py | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/rtv/submission_page.py b/rtv/submission_page.py index 32c9bf1..92da123 100644 --- a/rtv/submission_page.py +++ b/rtv/submission_page.py @@ -155,16 +155,15 @@ class SubmissionPage(Page): self.term.flash() def open_submission_or_permalink_or_mentioned_link(self, data): - links_in_data = [] + links = [{'text': 'Permalink', 'href': data['permalink']}] if data['html']: - links_in_data = self.get_links_in_html(data['html']) - - if links_in_data: - self.prompt_user_and_open_selected_link(data, links_in_data) + links += self.get_links_in_html(data['html']) + if len(links) > 1: + self.prompt_user_and_open_selected_link(links) elif 'url_full' in data and data['url_full']: self.term.open_link(data['url_full']) else: - self.term.open_browser(data['permalink']) + self.term.open_link(data['permalink']) def get_links_in_html(self, html): links = [] @@ -176,19 +175,19 @@ class SubmissionPage(Page): links.append(link) return links - def prompt_user_and_open_selected_link(self, data, links): + def prompt_user_and_open_selected_link(self, links): text = 'Open link:\n' - text += ('[1] Permalink to this %s\n' % (data['type'].lower(),)) - for i, link in enumerate(links[:8]): - text += '[%s] [%s](%s)\n' % (i + 2, link['text'], link['href']) + for i, link in enumerate(links[:9]): + capped_link_text = (link['text'] if len(link['text']) <= 20 + else link['text'][:19] + '…') + text += '[{}] [{}]({})\n'.format( + i+1, capped_link_text, link['href']) try: choice = int(chr(self.term.show_notification(text))) except ValueError: return - if choice == 1: - self.term.open_browser(data['permalink']) - elif choice - 2 < len(links): - self.term.open_link(links[choice - 2]['href']) + if choice <= len(links): + self.term.open_link(links[choice - 1]['href']) @SubmissionController.register(Command('SUBMISSION_OPEN_IN_PAGER')) def open_pager(self): From d79e56fd20c81ac21617394839814c0ac11cc1b1 Mon Sep 17 00:00:00 2001 From: codesoap Date: Sun, 19 Aug 2018 20:18:59 +0200 Subject: [PATCH 4/7] Rename function for opening the link of an item --- rtv/submission_page.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rtv/submission_page.py b/rtv/submission_page.py index 92da123..9db6653 100644 --- a/rtv/submission_page.py +++ b/rtv/submission_page.py @@ -147,14 +147,14 @@ class SubmissionPage(Page): data = self.get_selected_item() if data['type'] == 'Submission': - self.open_submission_or_permalink_or_mentioned_link(data) + self.prompt_and_open_link(data) self.config.history.add(data['url_full']) elif data['type'] == 'Comment' and data['permalink']: - self.open_submission_or_permalink_or_mentioned_link(data) + self.prompt_and_open_link(data) else: self.term.flash() - def open_submission_or_permalink_or_mentioned_link(self, data): + def prompt_and_open_link(self, data): links = [{'text': 'Permalink', 'href': data['permalink']}] if data['html']: links += self.get_links_in_html(data['html']) From cec9744702099f8ca8a72e3901da76e077bdfa9c Mon Sep 17 00:00:00 2001 From: codesoap Date: Sun, 19 Aug 2018 20:34:07 +0200 Subject: [PATCH 5/7] Move function for opening links into terminal.py --- rtv/submission_page.py | 16 +--------------- rtv/terminal.py | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/rtv/submission_page.py b/rtv/submission_page.py index 9db6653..1ab9fef 100644 --- a/rtv/submission_page.py +++ b/rtv/submission_page.py @@ -159,7 +159,7 @@ class SubmissionPage(Page): if data['html']: links += self.get_links_in_html(data['html']) if len(links) > 1: - self.prompt_user_and_open_selected_link(links) + self.term.prompt_user_and_open_selected_link(links) elif 'url_full' in data and data['url_full']: self.term.open_link(data['url_full']) else: @@ -175,20 +175,6 @@ class SubmissionPage(Page): links.append(link) return links - def prompt_user_and_open_selected_link(self, links): - text = 'Open link:\n' - for i, link in enumerate(links[:9]): - capped_link_text = (link['text'] if len(link['text']) <= 20 - else link['text'][:19] + '…') - text += '[{}] [{}]({})\n'.format( - i+1, capped_link_text, link['href']) - try: - choice = int(chr(self.term.show_notification(text))) - except ValueError: - return - if choice <= len(links): - self.term.open_link(links[choice - 1]['href']) - @SubmissionController.register(Command('SUBMISSION_OPEN_IN_PAGER')) def open_pager(self): """ diff --git a/rtv/terminal.py b/rtv/terminal.py index 94cd7a7..1f714a4 100644 --- a/rtv/terminal.py +++ b/rtv/terminal.py @@ -354,6 +354,20 @@ class Terminal(object): return ch + def prompt_user_and_open_selected_link(self, links): + text = 'Open link:\n' + for i, link in enumerate(links[:9]): + capped_link_text = (link['text'] if len(link['text']) <= 20 + else link['text'][:19] + '…') + text += '[{}] [{}]({})\n'.format( + i+1, capped_link_text, link['href']) + try: + choice = int(chr(self.show_notification(text))) + except ValueError: + return + if choice <= len(links): + self.open_link(links[choice - 1]['href']) + def open_link(self, url): """ Open a media link using the definitions from the user's mailcap file. From b8a5d28aa74610089f64d863189a483a553c67b1 Mon Sep 17 00:00:00 2001 From: codesoap Date: Sat, 25 Aug 2018 19:12:13 +0200 Subject: [PATCH 6/7] Enable link selection, with more than 8 links --- rtv/terminal.py | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/rtv/terminal.py b/rtv/terminal.py index 1f714a4..6c4cca8 100644 --- a/rtv/terminal.py +++ b/rtv/terminal.py @@ -355,18 +355,45 @@ class Terminal(object): return ch def prompt_user_and_open_selected_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 + if link_page is not link_pages[-1] and choice == 9: + continue + elif choice == 0 or choice > len(link_page): + return + self.open_link(link_page[choice - 1]['href']) + return + + 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(links[:9]): + 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']) - try: - choice = int(chr(self.show_notification(text))) - except ValueError: - return - if choice <= len(links): - self.open_link(links[choice - 1]['href']) + i + 1, capped_link_text, link['href']) + return text def open_link(self, url): """ From 5fcd7e517a58539e94f9165eca16ff555b34e6a5 Mon Sep 17 00:00:00 2001 From: codesoap Date: Sat, 25 Aug 2018 21:30:08 +0200 Subject: [PATCH 7/7] Save the correct link in the history --- rtv/submission_page.py | 14 +++++++++----- rtv/terminal.py | 9 ++++----- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/rtv/submission_page.py b/rtv/submission_page.py index 1ab9fef..d637d19 100644 --- a/rtv/submission_page.py +++ b/rtv/submission_page.py @@ -147,8 +147,9 @@ class SubmissionPage(Page): data = self.get_selected_item() if data['type'] == 'Submission': - self.prompt_and_open_link(data) - 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.prompt_and_open_link(data) else: @@ -159,11 +160,14 @@ class SubmissionPage(Page): if data['html']: links += self.get_links_in_html(data['html']) if len(links) > 1: - self.term.prompt_user_and_open_selected_link(links) + link = self.term.prompt_user_to_select_link(links) elif 'url_full' in data and data['url_full']: - self.term.open_link(data['url_full']) + link = data['url_full'] else: - self.term.open_link(data['permalink']) + link = data['permalink'] + if link is not None: + self.term.open_link(link) + return link def get_links_in_html(self, html): links = [] diff --git a/rtv/terminal.py b/rtv/terminal.py index 6c4cca8..ca50cd1 100644 --- a/rtv/terminal.py +++ b/rtv/terminal.py @@ -354,7 +354,7 @@ class Terminal(object): return ch - def prompt_user_and_open_selected_link(self, links): + 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) @@ -364,13 +364,12 @@ class Terminal(object): try: choice = int(chr(self.show_notification(text))) except ValueError: - return + return None if link_page is not link_pages[-1] and choice == 9: continue elif choice == 0 or choice > len(link_page): - return - self.open_link(link_page[choice - 1]['href']) - return + return None + return link_page[choice - 1]['href'] def get_link_pages(self, links): link_pages = []