diff --git a/premailer/premailer.py b/premailer/premailer.py index 293b8d3..2addeaf 100644 --- a/premailer/premailer.py +++ b/premailer/premailer.py @@ -1,8 +1,5 @@ from __future__ import absolute_import, unicode_literals, print_function -from io import BytesIO # Yes, there is an io module in Python 2 -import cgi import codecs -import gzip import operator import os import re @@ -16,7 +13,6 @@ import sys if sys.version_info >= (3,): # pragma: no cover # As in, Python 3 from io import StringIO - from urllib.request import urlopen from urllib.parse import urljoin, urlparse STR_TYPE = str else: # Python 2 @@ -25,11 +21,11 @@ else: # Python 2 except ImportError: # pragma: no cover from StringIO import StringIO StringIO = StringIO # shut up pyflakes - from urllib2 import urlopen from urlparse import urljoin, urlparse STR_TYPE = basestring # NOQA import cssutils +import requests from lxml import etree from lxml.cssselect import CSSSelector from premailer.merge_style import merge_styles, csstext_to_pairs @@ -473,16 +469,7 @@ class Premailer(object): return out def _load_external_url(self, url): - r = urlopen(url) - _, params = cgi.parse_header(r.headers.get('Content-Type', '')) - encoding = params.get('charset', 'utf-8') - if 'gzip' in r.info().get('Content-Encoding', ''): - buf = BytesIO(r.read()) - f = gzip.GzipFile(fileobj=buf) - out = f.read().decode(encoding) - else: - out = r.read().decode(encoding) - return out + return requests.get(url).text def _load_external(self, url): """loads an external stylesheet from a remote url or local path diff --git a/premailer/tests/test_premailer.py b/premailer/tests/test_premailer.py index 271b5bc..69f5bdb 100644 --- a/premailer/tests/test_premailer.py +++ b/premailer/tests/test_premailer.py @@ -9,8 +9,7 @@ if sys.version_info >= (3, ): # As in, Python 3 else: # Python 2 from urllib2 import urlopen urlopen = urlopen # shut up pyflakes -from io import BytesIO, StringIO # Yes, the is an io lib in py2.x -import gzip +from io import StringIO # Yes, the is an io lib in py2.x from nose.tools import eq_, ok_, assert_raises import mock @@ -53,31 +52,10 @@ def provide_input(content): sys.stdin = StringIO(content) -class MockResponse: +class MockResponse(object): - def __init__(self, content, gzip=False): - self.content = content - self.headers = {} - self.gzip = gzip - - def info(self): - if self.gzip: - return {'Content-Encoding': 'gzip'} - else: - return {} - - def read(self): - if self.gzip: - out = BytesIO() - # If we didn't have to support python 2.6 we could instead do: - # with gzip.GzipFile(fileobj=out, mode="w") as f: - # ... - f = gzip.GzipFile(fileobj=out, mode="w") - f.write(self.content) - f.close() - return out.getvalue() - else: - return self.content + def __init__(self, content): + self.text = content def compare_html(one, two): @@ -1768,29 +1746,17 @@ ent:"" !important;display:block !important} compare_html(expect_html, result_html) - @mock.patch('premailer.premailer.urlopen') - def test_load_external_url(self, mocked_url_open): + @mock.patch('premailer.premailer.requests') + def test_load_external_url(self, mocked_requests): 'Test premailer.premailer.Premailer._load_external_url' - faux_response = b'This is not a response' + faux_response = 'This is not a response' faux_uri = 'https://example.com/site.css' - mocked_url_open.return_value = MockResponse(faux_response) + mocked_requests.get.return_value = MockResponse(faux_response) p = premailer.premailer.Premailer('

A paragraph

') r = p._load_external_url(faux_uri) - mocked_url_open.assert_called_once_with(faux_uri) - eq_(faux_response.decode('utf-8'), r) - - @mock.patch('premailer.premailer.urlopen') - def test_load_external_url_gzip(self, mocked_url_open): - 'Test premailer.premailer.Premailer._load_external_url with gzip' - faux_response = b'This is not a response' - faux_uri = 'http://example.com/site.css' - mocked_url_open.return_value = MockResponse(faux_response, True) - p = premailer.premailer.Premailer('

A paragraph

') - r = p._load_external_url(faux_uri) - - mocked_url_open.assert_called_once_with(faux_uri) - eq_(faux_response.decode('utf-8'), r) + mocked_requests.get.assert_called_once_with(faux_uri) + eq_(faux_response, r) def test_css_text(self): """Test handling css_text passed as a string""" diff --git a/setup.py b/setup.py index ec19d69..abad1b9 100644 --- a/setup.py +++ b/setup.py @@ -32,6 +32,7 @@ install_requires = [ 'lxml', 'cssselect', 'cssutils', + 'requests', ] if sys.version_info >= (2, 6) and sys.version_info <= (2, 7): # Python 2.6 is the oldest version we support and it