Fighting with mailcap
This commit is contained in:
@@ -59,6 +59,9 @@ def build_parser():
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--copy-config', dest='copy_config', action='store_const', const=True,
|
'--copy-config', dest='copy_config', action='store_const', const=True,
|
||||||
help='Copy the default configuration to {HOME}/.config/rtv/rtv.cfg')
|
help='Copy the default configuration to {HOME}/.config/rtv/rtv.cfg')
|
||||||
|
parser.add_argument(
|
||||||
|
'--enable-media', dest='enable_media', action='store_const', const=True,
|
||||||
|
help='Open external links using programs defined in the mailcap config')
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import re
|
import re
|
||||||
import mimetypes
|
import mimetypes
|
||||||
from html.parser import HTMLParser
|
|
||||||
|
|
||||||
|
from six.moves.html_parser import HTMLParser
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
|
||||||
@@ -116,7 +116,8 @@ class ImgurHandler(BaseHandler):
|
|||||||
def get_mimetype(url):
|
def get_mimetype(url):
|
||||||
imgur_page = requests.get(url)
|
imgur_page = requests.get(url)
|
||||||
try:
|
try:
|
||||||
ImgurHTMLParser().feed(imgur_page.text)
|
# convert_charrefs will be true by default in python 3.5
|
||||||
|
ImgurHTMLParser(convert_charrefs=True).feed(imgur_page.text)
|
||||||
except HTMLParsed as data:
|
except HTMLParsed as data:
|
||||||
# We found a link
|
# We found a link
|
||||||
url = data.data
|
url = data.data
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ clear_auth = False
|
|||||||
; Maximum number of opened links that will be saved in the history file.
|
; Maximum number of opened links that will be saved in the history file.
|
||||||
history_size = 200
|
history_size = 200
|
||||||
|
|
||||||
|
; Open external links using programs defined in the mailcap config.
|
||||||
|
enable_media = True
|
||||||
|
|
||||||
################
|
################
|
||||||
# OAuth Settings
|
# OAuth Settings
|
||||||
################
|
################
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ class SubredditPage(Page):
|
|||||||
self.open_submission(url=data['url_full'])
|
self.open_submission(url=data['url_full'])
|
||||||
self.config.history.add(data['url_full'])
|
self.config.history.add(data['url_full'])
|
||||||
else:
|
else:
|
||||||
self.term.open_browser(data['url_full'])
|
self.term.open_link(data['url_full'])
|
||||||
self.config.history.add(data['url_full'])
|
self.config.history.add(data['url_full'])
|
||||||
|
|
||||||
@SubredditController.register(Command('SUBREDDIT_POST'))
|
@SubredditController.register(Command('SUBREDDIT_POST'))
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import time
|
|||||||
import codecs
|
import codecs
|
||||||
import curses
|
import curses
|
||||||
import logging
|
import logging
|
||||||
|
import mailcap
|
||||||
import tempfile
|
import tempfile
|
||||||
import webbrowser
|
import webbrowser
|
||||||
import subprocess
|
import subprocess
|
||||||
@@ -19,8 +20,10 @@ import six
|
|||||||
from kitchen.text.display import textual_width_chop
|
from kitchen.text.display import textual_width_chop
|
||||||
|
|
||||||
from . import exceptions
|
from . import exceptions
|
||||||
|
from . import mime_handlers
|
||||||
from .objects import LoadScreen, Color
|
from .objects import LoadScreen, Color
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Added in python 3.4+
|
# Added in python 3.4+
|
||||||
from html import unescape
|
from html import unescape
|
||||||
@@ -49,6 +52,9 @@ class Terminal(object):
|
|||||||
self.loader = LoadScreen(self)
|
self.loader = LoadScreen(self)
|
||||||
self._display = None
|
self._display = None
|
||||||
|
|
||||||
|
# TODO: Load from custom location
|
||||||
|
self._mailcap_dict = mailcap.getcaps()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def up_arrow(self):
|
def up_arrow(self):
|
||||||
symbol = '^' if self.config['ascii'] else '▲'
|
symbol = '^' if self.config['ascii'] else '▲'
|
||||||
@@ -304,6 +310,49 @@ class Terminal(object):
|
|||||||
|
|
||||||
return ch
|
return ch
|
||||||
|
|
||||||
|
def open_link(self, url):
|
||||||
|
|
||||||
|
_logger.info('Opening link %s', url)
|
||||||
|
if not self.config['enable_media']:
|
||||||
|
return self.open_browser(url)
|
||||||
|
|
||||||
|
command = None
|
||||||
|
for handler in mime_handlers.handlers:
|
||||||
|
if handler.pattern.match(url):
|
||||||
|
modified_url, content_type = handler.get_mimetype(url)
|
||||||
|
_logger.info('MIME type: %s', content_type)
|
||||||
|
_logger.info('Modified url: %s', modified_url)
|
||||||
|
if not content_type or content_type == 'text/html':
|
||||||
|
# Could not figure out the Content-Type
|
||||||
|
return self.open_browser(modified_url)
|
||||||
|
|
||||||
|
# http://bugs.python.org/issue14977
|
||||||
|
command, entry = mailcap.findmatch(
|
||||||
|
self._mailcap_dict, content_type, filename=modified_url)
|
||||||
|
if not entry:
|
||||||
|
_logger.info('Could not find a valid mailcap entry')
|
||||||
|
return self.open_browser(modified_url)
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
|
with self.loader('Opening page in a new window', delay=0):
|
||||||
|
args = [command]
|
||||||
|
_logger.info('Running command: %s', args)
|
||||||
|
# Non-blocking, run with a full shell to support pipes
|
||||||
|
p = subprocess.Popen(
|
||||||
|
args, shell=True, universal_newlines=True,
|
||||||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
# Wait a little while to make sure that the command doesn't exit
|
||||||
|
# with an error. This isn't perfect, but it should be good enough
|
||||||
|
# to catch invalid commands.
|
||||||
|
time.sleep(1.0)
|
||||||
|
code = p.poll()
|
||||||
|
if code is not None and code != 0:
|
||||||
|
stdout, stderr = p.communicate()
|
||||||
|
_logger.warning(stderr)
|
||||||
|
raise exceptions.BrowserError(
|
||||||
|
'Program exited with status=%s' % code)
|
||||||
|
|
||||||
def open_browser(self, url):
|
def open_browser(self, url):
|
||||||
"""
|
"""
|
||||||
Open the given url using the default webbrowser. The preferred browser
|
Open the given url using the default webbrowser. The preferred browser
|
||||||
@@ -346,7 +395,7 @@ class Terminal(object):
|
|||||||
break # Success
|
break # Success
|
||||||
elif code is not None:
|
elif code is not None:
|
||||||
raise exceptions.BrowserError(
|
raise exceptions.BrowserError(
|
||||||
'Browser exited with status=%s' % code)
|
'Program exited with status=%s' % code)
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
else:
|
else:
|
||||||
raise exceptions.BrowserError(
|
raise exceptions.BrowserError(
|
||||||
|
|||||||
Reference in New Issue
Block a user