Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-premailer for openSUSE:Factory checked in at 2022-10-06 07:42:13 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-premailer (Old) and /work/SRC/openSUSE:Factory/.python-premailer.new.2275 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-premailer" Thu Oct 6 07:42:13 2022 rev:2 rq:1008169 version:3.10.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-premailer/python-premailer.changes 2019-08-28 18:34:45.501291257 +0200 +++ /work/SRC/openSUSE:Factory/.python-premailer.new.2275/python-premailer.changes 2022-10-06 07:42:24.088713670 +0200 @@ -1,0 +2,21 @@ +Tue Oct 4 23:14:00 UTC 2022 - Yogalakshmi Arunachalam <yarunacha...@suse.com> + +- Update to version 3.10.0 + New option session=None to provide the session used for making http requests. + Bug fix: inlined styles are no longer sorted alphabetically. This preserves the input rule order so that premailer does not break style + precedence where order is significant, e.g. + div { + /* Padding on all sides is 10px. */ + padding-left: 5px; + padding: 10px; + } + div { + /* Padding on the left side is 5px, on other sides is 10px. */ + padding: 10px; + padding-left: 5px; + } + Prior to this fix premailer would swap the rules in the first example to look like the second. + + Other version change log https://github.com/peterbe/premailer/blob/master/CHANGES.rst + +------------------------------------------------------------------- Old: ---- premailer-3.6.1.tar.gz New: ---- premailer-3.10.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-premailer.spec ++++++ --- /var/tmp/diff_new_pack.WBLw1s/_old 2022-10-06 07:42:24.464714508 +0200 +++ /var/tmp/diff_new_pack.WBLw1s/_new 2022-10-06 07:42:24.468714516 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-premailer # -# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -12,22 +12,23 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-premailer -Version: 3.6.1 +Version: 3.10.0 Release: 0 License: Python-2.0 Summary: Turns CSS blocks into style attributes -Url: https://premailer.io +URL: https://premailer.io Group: Development/Languages/Python Source: https://files.pythonhosted.org/packages/source/p/premailer/premailer-%{version}.tar.gz -BuildRequires: python-rpm-macros BuildRequires: %{python_module devel} BuildRequires: %{python_module setuptools} BuildRequires: fdupes +BuildRequires: python-rpm-macros Requires: python-cachetools Requires: python-cssselect Requires: python-cssutils ++++++ premailer-3.6.1.tar.gz -> premailer-3.10.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/premailer-3.6.1/MANIFEST.in new/premailer-3.10.0/MANIFEST.in --- old/premailer-3.6.1/MANIFEST.in 2015-06-10 01:14:52.000000000 +0200 +++ new/premailer-3.10.0/MANIFEST.in 2020-05-07 14:36:09.000000000 +0200 @@ -1,2 +1,3 @@ include README.rst include LICENSE +recursive-include premailer/tests/* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/premailer-3.6.1/PKG-INFO new/premailer-3.10.0/PKG-INFO --- old/premailer-3.6.1/PKG-INFO 2019-08-24 05:40:54.000000000 +0200 +++ new/premailer-3.10.0/PKG-INFO 2021-08-02 22:32:51.823293200 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: premailer -Version: 3.6.1 +Version: 3.10.0 Summary: Turns CSS blocks into style attributes Home-page: http://github.com/peterbe/premailer Author: Peter Bengtsson @@ -33,10 +33,11 @@ `tox.ini <https://github.com/peterbe/premailer/blob/master/tox.ini>`__ makes sure premailer works in: - - Python 2.7 - Python 3.4 - Python 3.5 - Python 3.6 + - Python 3.7 + - Python 3.8 - PyPy Turns CSS blocks into style attributes @@ -84,7 +85,7 @@ Next, the most basic use is to use the shortcut function, like this: - :: + .. code:: python >>> from premailer import transform >>> print(transform(""" @@ -116,12 +117,13 @@ The ``transform`` shortcut function transforms the given HTML using the defaults for all options: - :: + .. code:: python base_url=None, # Optional URL prepended to all relative links (both stylesheets and internal) disable_link_rewrites=False, # Allow link rewrites (e.g. using base_url) preserve_internal_links=False, # Do not preserve links to named anchors when using base_url preserve_inline_attachments=True, # Preserve links with cid: scheme when base_url is specified + preserve_handlebar_syntax=False # Preserve handlebar syntax from being encoded exclude_pseudoclasses=True, # Ignore pseudoclasses when processing styles keep_style_tags=False, # Discard original style tag include_star_selectors=False, # Ignore star selectors when processing styles @@ -142,11 +144,13 @@ remove_unset_properties=True # Remove CSS properties if their value is unset when merged allow_network=True # allow network access to fetch linked css files allow_insecure_ssl=False # Don't allow unverified SSL certificates for external links + allow_loading_external_files=False # Allow loading any non-HTTP external file URL + session=None # Session used for http requests - supply your own for caching or to provide authentication For more advanced options, check out the code of the ``Premailer`` class and all its options in its constructor. - You can also use premailer from the command line by using his main + You can also use premailer from the command line by using its main module. :: @@ -184,6 +188,7 @@ --disable-validation Disable CSSParser validation of attributes and values --pretty Pretty-print the outputted HTML. --allow-insecure-ssl Skip SSL certificate verification for external URLs. + --allow-loading-external-files Allow opening any non-HTTP external file URL. A basic example: @@ -269,7 +274,7 @@ Certain HTML attributes are also created on the HTML if the CSS contains any ones that are easily translated into HTML attributes. For example, if you have this CSS: ``td { background-color:#eee; }`` then this is - transformed into ``style="background-color:#eee"`` AND as an HTML + transformed into ``style="background-color:#eee"`` and as an HTML attribute ``bgcolor="#eee"``. Having these extra attributes basically as a "back up" for really shit @@ -430,16 +435,16 @@ Classifier: License :: OSI Approved :: Python Software Foundation License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Communications Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Other/Nonlisted Topic Classifier: Topic :: Software Development :: Libraries :: Python Modules -Provides-Extra: test Provides-Extra: dev +Provides-Extra: test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/premailer-3.6.1/README.rst new/premailer-3.10.0/README.rst --- old/premailer-3.6.1/README.rst 2019-08-01 21:01:46.000000000 +0200 +++ new/premailer-3.10.0/README.rst 2021-08-02 22:24:41.000000000 +0200 @@ -25,10 +25,11 @@ `tox.ini <https://github.com/peterbe/premailer/blob/master/tox.ini>`__ makes sure premailer works in: -- Python 2.7 - Python 3.4 - Python 3.5 - Python 3.6 +- Python 3.7 +- Python 3.8 - PyPy Turns CSS blocks into style attributes @@ -76,7 +77,7 @@ Next, the most basic use is to use the shortcut function, like this: -:: +.. code:: python >>> from premailer import transform >>> print(transform(""" @@ -108,12 +109,13 @@ The ``transform`` shortcut function transforms the given HTML using the defaults for all options: -:: +.. code:: python base_url=None, # Optional URL prepended to all relative links (both stylesheets and internal) disable_link_rewrites=False, # Allow link rewrites (e.g. using base_url) preserve_internal_links=False, # Do not preserve links to named anchors when using base_url preserve_inline_attachments=True, # Preserve links with cid: scheme when base_url is specified + preserve_handlebar_syntax=False # Preserve handlebar syntax from being encoded exclude_pseudoclasses=True, # Ignore pseudoclasses when processing styles keep_style_tags=False, # Discard original style tag include_star_selectors=False, # Ignore star selectors when processing styles @@ -134,11 +136,13 @@ remove_unset_properties=True # Remove CSS properties if their value is unset when merged allow_network=True # allow network access to fetch linked css files allow_insecure_ssl=False # Don't allow unverified SSL certificates for external links + allow_loading_external_files=False # Allow loading any non-HTTP external file URL + session=None # Session used for http requests - supply your own for caching or to provide authentication For more advanced options, check out the code of the ``Premailer`` class and all its options in its constructor. -You can also use premailer from the command line by using his main +You can also use premailer from the command line by using its main module. :: @@ -176,6 +180,7 @@ --disable-validation Disable CSSParser validation of attributes and values --pretty Pretty-print the outputted HTML. --allow-insecure-ssl Skip SSL certificate verification for external URLs. + --allow-loading-external-files Allow opening any non-HTTP external file URL. A basic example: @@ -261,7 +266,7 @@ Certain HTML attributes are also created on the HTML if the CSS contains any ones that are easily translated into HTML attributes. For example, if you have this CSS: ``td { background-color:#eee; }`` then this is -transformed into ``style="background-color:#eee"`` AND as an HTML +transformed into ``style="background-color:#eee"`` and as an HTML attribute ``bgcolor="#eee"``. Having these extra attributes basically as a "back up" for really shit diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/premailer-3.6.1/premailer/__init__.py new/premailer-3.10.0/premailer/__init__.py --- old/premailer-3.6.1/premailer/__init__.py 2019-08-24 05:35:23.000000000 +0200 +++ new/premailer-3.10.0/premailer/__init__.py 2021-08-02 22:32:35.000000000 +0200 @@ -1,4 +1,3 @@ -from __future__ import absolute_import, unicode_literals from .premailer import Premailer, transform # noqa -__version__ = "3.6.1" +__version__ = "3.10.0" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/premailer-3.6.1/premailer/__main__.py new/premailer-3.10.0/premailer/__main__.py --- old/premailer-3.6.1/premailer/__main__.py 2019-08-01 21:01:46.000000000 +0200 +++ new/premailer-3.10.0/premailer/__main__.py 2021-06-01 03:35:03.000000000 +0200 @@ -1,4 +1,3 @@ -from __future__ import absolute_import, unicode_literals import sys import argparse @@ -156,6 +155,13 @@ help="Skip SSL certificate verification for external URLs.", ) + parser.add_argument( + "--allow-loading-external-files", + default=False, + action="store_true", + help="Allow opening any non-HTTP external file URL.", + ) + options = parser.parse_args(args) if options.disable_basic_attributes: @@ -181,6 +187,7 @@ disable_basic_attributes=options.disable_basic_attributes, disable_validation=options.disable_validation, allow_insecure_ssl=options.allow_insecure_ssl, + allow_loading_external_files=options.allow_loading_external_files, ) options.outfile.write( p.transform(encoding=options.encoding, pretty_print=options.pretty) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/premailer-3.6.1/premailer/merge_style.py new/premailer-3.10.0/premailer/merge_style.py --- old/premailer-3.6.1/premailer/merge_style.py 2019-08-24 05:35:23.000000000 +0200 +++ new/premailer-3.10.0/premailer/merge_style.py 2021-08-02 22:24:41.000000000 +0200 @@ -1,13 +1,6 @@ -from __future__ import absolute_import import cssutils import threading -from operator import itemgetter - -try: - from collections import OrderedDict -except ImportError: # pragma: no cover - # some old python 2.6 thing then, eh? - from ordereddict import OrderedDict +from collections import OrderedDict from premailer.cache import function_cache @@ -28,13 +21,10 @@ # The lock is required to avoid ``cssutils`` concurrency # issues documented in issue #65 with csstext_to_pairs._lock: - return sorted( - [ - (prop.name.strip(), format_value(prop)) - for prop in cssutils.parseStyle(csstext, validate=validate) - ], - key=itemgetter(0), - ) + return [ + (prop.name.strip(), format_value(prop)) + for prop in cssutils.parseStyle(csstext, validate=validate) + ] csstext_to_pairs._lock = threading.RLock() @@ -42,23 +32,23 @@ def merge_styles(inline_style, new_styles, classes, remove_unset_properties=False): """ - This will merge all new styles where the order is important - The last one will override the first - When that is done it will apply old inline style again - The old inline style is always important and override - all new ones. The inline style must be valid. - - Args: - inline_style(str): the old inline style of the element if there - is one - new_styles: a list of new styles, each element should be - a list of tuple - classes: a list of classes which maps new_styles, important! - remove_unset_properties(bool): Allow us to remove certain CSS - properties with rules that set their value to 'unset' + This will merge all new styles where the order is important + The last one will override the first + When that is done it will apply old inline style again + The old inline style is always important and override + all new ones. The inline style must be valid. + + Args: + inline_style(str): the old inline style of the element if there + is one + new_styles: a list of new styles, each element should be + a list of tuple + classes: a list of classes which maps new_styles, important! + remove_unset_properties(bool): Allow us to remove certain CSS + properties with rules that set their value to 'unset' - Returns: - str: the final style + Returns: + str: the final style """ # building classes styles = OrderedDict([("", OrderedDict())]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/premailer-3.6.1/premailer/premailer.py new/premailer-3.10.0/premailer/premailer.py --- old/premailer-3.6.1/premailer/premailer.py 2019-08-24 05:35:23.000000000 +0200 +++ new/premailer-3.10.0/premailer/premailer.py 2021-08-02 22:24:41.000000000 +0200 @@ -1,11 +1,11 @@ -from __future__ import absolute_import, print_function, unicode_literals - import codecs import operator import os import re -import sys import warnings +from collections import OrderedDict +from html import escape, unescape +from urllib.parse import urljoin, urlparse, unquote import cssutils import requests @@ -15,29 +15,6 @@ from premailer.cache import function_cache from premailer.merge_style import csstext_to_pairs, merge_styles -try: - from collections import OrderedDict -except ImportError: # pragma: no cover - # some old python 2.6 thing then, eh? - from ordereddict import OrderedDict - -if sys.version_info >= (3,): # pragma: no cover - # As in, Python 3 - from io import StringIO - from urllib.parse import urljoin, urlparse - - STR_TYPE = str -else: # Python 2 - try: - from cStringIO import StringIO - except ImportError: # pragma: no cover - from StringIO import StringIO - - StringIO = StringIO # shut up pyflakes - from urlparse import urljoin, urlparse - - STR_TYPE = basestring # NOQA - __all__ = ["PremailerError", "Premailer", "transform"] @@ -50,9 +27,12 @@ pass +class ExternalFileLoadingError(Exception): + pass + + def make_important(bulk): - """makes every property in a string !important. - """ + """makes every property in a string !important.""" return ";".join( "%s !important" % p if not p.endswith("!important") else p for p in bulk.split(";") @@ -60,8 +40,7 @@ def get_or_create_head(root): - """Ensures that `root` contains a <head> element and returns it. - """ + """Ensures that `root` contains a <head> element and returns it.""" head = _create_cssselector("head")(root) if not head: head = etree.Element("head") @@ -75,18 +54,18 @@ @function_cache() def _cache_parse_css_string(css_body, validate=True): """ - This function will cache the result from cssutils - It is a big gain when number of rules is big - Maximum cache entries are 1000. This is mainly for - protecting memory leak in case something gone wild. - Be aware that you can turn the cache off in Premailer - - Args: - css_body(str): css rules in string format - validate(bool): if cssutils should validate + This function will cache the result from cssutils + It is a big gain when number of rules is big + Maximum cache entries are 1000. This is mainly for + protecting memory leak in case something gone wild. + Be aware that you can turn the cache off in Premailer + + Args: + css_body(str): css rules in string format + validate(bool): if cssutils should validate - Returns: - cssutils.css.cssstylesheet.CSSStyleSheet + Returns: + cssutils.css.cssstylesheet.CSSStyleSheet """ return cssutils.parseString(css_body, validate=validate) @@ -98,8 +77,7 @@ def capitalize_float_margin(css_body): - """Capitalize float and margin CSS property names - """ + """Capitalize float and margin CSS property names""" def _capitalize_property(match): return "{0}:{1}{2}".format( @@ -140,6 +118,7 @@ disable_link_rewrites=False, preserve_internal_links=False, preserve_inline_attachments=True, + preserve_handlebar_syntax=False, exclude_pseudoclasses=True, keep_style_tags=False, include_star_selectors=False, @@ -160,6 +139,8 @@ remove_unset_properties=True, allow_network=True, allow_insecure_ssl=False, + allow_loading_external_files=False, + session=None, ): self.html = html self.base_url = base_url @@ -176,6 +157,7 @@ self.disable_link_rewrites = disable_link_rewrites self.preserve_internal_links = preserve_internal_links self.preserve_inline_attachments = preserve_inline_attachments + self.preserve_handlebar_syntax = preserve_handlebar_syntax self.exclude_pseudoclasses = exclude_pseudoclasses # whether to delete the <style> tag once it's been processed # this will always preserve the original css @@ -184,10 +166,10 @@ self.capitalize_float_margin = capitalize_float_margin # whether to process or ignore selectors like '* { foo:bar; }' self.include_star_selectors = include_star_selectors - if isinstance(external_styles, STR_TYPE): + if isinstance(external_styles, str): external_styles = [external_styles] self.external_styles = external_styles - if isinstance(css_text, STR_TYPE): + if isinstance(css_text, str): css_text = [css_text] self.css_text = css_text self.strip_important = strip_important @@ -203,6 +185,8 @@ self.remove_unset_properties = remove_unset_properties self.allow_network = allow_network self.allow_insecure_ssl = allow_insecure_ssl + self.allow_loading_external_files = allow_loading_external_files + self.session = session or requests if cssutils_logging_handler: cssutils.log.addHandler(cssutils_logging_handler) @@ -230,7 +214,7 @@ return "{0}:{1} !important".format(prop.name, prop.value) def join_css_properties(properties): - """ Accepts a list of cssutils Property objects and returns + """Accepts a list of cssutils Property objects and returns a semicolon delimitted string like 'color: red; font-size: 12px' """ return ";".join(format_css_property(prop) for prop in properties) @@ -333,6 +317,39 @@ else: parser = etree.HTMLParser() stripped = html.strip() + + # Escape all characters in handlebars in HTML attributes. + # Without this step, if handlebars were to include a character such as ", + # etree.fromstring() would not be able to differentiate the "'s in the value + # from the "'s for the attribute. + # -------------------------------------------------------------------------- + # Provided the input below: + # <a href="{{ "<Test>" }}"></a> + # -------------------------------------------------------------------------- + # Decoded result without preservation: + # <a href="%7B%7B%20">" }}"></a> + # Everything between the first two quotes were treated as the value of the + # attribute. Then, the characters between the second quote and the second + # > were treated as invalid attributes and discarded. Lastly, the value of + # the original attribute after the second and </a> were treated as the + # contents of the HTML tag. + # --- + # Result: + # <a href="%7B%7B%20">" }}"></a> + # -------------------------------------------------------------------------- + # Decoded result with preservation (prior to unescape() & unquote()): + # <a href="%7B%7B%20%22<Test>%22%20%7D%7D"></a> + # No value was lost in the encoding process. + # --- + # Result after unquote() and unescape(): + # <a href="{{ "<Test>" }}"></a> + if self.preserve_handlebar_syntax: + stripped = re.sub( + r'="{{(.*?)}}"', + lambda match: '="{{' + escape(match.groups()[0]) + '}}"', + stripped, + ) + tree = etree.fromstring(stripped, parser).getroottree() page = tree.getroot() # lxml inserts a doctype if none exists, so only include it in @@ -395,6 +412,10 @@ style.text = css_body else: style.text = self._css_rules_to_string(these_leftover) + + if self.strip_important: + style.text = _importants.sub("", style.text) + if self.method == "xml": style.text = etree.CDATA(style.text) @@ -538,18 +559,23 @@ out = _cdata_regex.sub( lambda m: "/*<![CDATA[*/%s/*]]>*/" % m.group(1), out ) - if self.strip_important: - out = _importants.sub("", out) + # Replace %xx escapes and HTML entities, within handlebars in HTML + # attributes, with their single-character equivalents. + if self.preserve_handlebar_syntax: + out = re.sub( + r'="%7B%7B(.+?)%7D%7D"', + lambda match: '="{{' + unescape(unquote(match.groups()[0])) + '}}"', + out, + ) return out def _load_external_url(self, url): - response = requests.get(url, verify=not self.allow_insecure_ssl) + response = self.session.get(url, verify=not self.allow_insecure_ssl) response.raise_for_status() return response.text def _load_external(self, url): - """loads an external stylesheet from a remote url or local path - """ + """loads an external stylesheet from a remote url or local path""" if url.startswith("//"): # then we have to rely on the base_url if self.base_url and "https://" in self.base_url: @@ -559,12 +585,16 @@ if url.startswith("http://") or url.startswith("https://"): css_body = self._load_external_url(url) + elif not self.allow_loading_external_files: + raise ExternalFileLoadingError( + "Unable to load external file {!r} because it's explicitly not allowed" + "".format(url) + ) else: stylefile = url + base_path = os.path.abspath(self.base_path or os.curdir) if not os.path.isabs(stylefile): - stylefile = os.path.abspath( - os.path.join(self.base_path or "", stylefile) - ) + stylefile = os.path.abspath(os.path.join(base_path, stylefile)) if os.path.exists(stylefile): with codecs.open(stylefile, encoding="utf-8") as f: css_body = f.read() @@ -633,8 +663,7 @@ element.attrib[key] = value def _css_rules_to_string(self, rules): - """given a list of css rules returns a css string - """ + """given a list of css rules returns a css string""" lines = [] for item in rules: if isinstance(item, tuple): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/premailer-3.6.1/premailer.egg-info/PKG-INFO new/premailer-3.10.0/premailer.egg-info/PKG-INFO --- old/premailer-3.6.1/premailer.egg-info/PKG-INFO 2019-08-24 05:40:54.000000000 +0200 +++ new/premailer-3.10.0/premailer.egg-info/PKG-INFO 2021-08-02 22:32:51.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: premailer -Version: 3.6.1 +Version: 3.10.0 Summary: Turns CSS blocks into style attributes Home-page: http://github.com/peterbe/premailer Author: Peter Bengtsson @@ -33,10 +33,11 @@ `tox.ini <https://github.com/peterbe/premailer/blob/master/tox.ini>`__ makes sure premailer works in: - - Python 2.7 - Python 3.4 - Python 3.5 - Python 3.6 + - Python 3.7 + - Python 3.8 - PyPy Turns CSS blocks into style attributes @@ -84,7 +85,7 @@ Next, the most basic use is to use the shortcut function, like this: - :: + .. code:: python >>> from premailer import transform >>> print(transform(""" @@ -116,12 +117,13 @@ The ``transform`` shortcut function transforms the given HTML using the defaults for all options: - :: + .. code:: python base_url=None, # Optional URL prepended to all relative links (both stylesheets and internal) disable_link_rewrites=False, # Allow link rewrites (e.g. using base_url) preserve_internal_links=False, # Do not preserve links to named anchors when using base_url preserve_inline_attachments=True, # Preserve links with cid: scheme when base_url is specified + preserve_handlebar_syntax=False # Preserve handlebar syntax from being encoded exclude_pseudoclasses=True, # Ignore pseudoclasses when processing styles keep_style_tags=False, # Discard original style tag include_star_selectors=False, # Ignore star selectors when processing styles @@ -142,11 +144,13 @@ remove_unset_properties=True # Remove CSS properties if their value is unset when merged allow_network=True # allow network access to fetch linked css files allow_insecure_ssl=False # Don't allow unverified SSL certificates for external links + allow_loading_external_files=False # Allow loading any non-HTTP external file URL + session=None # Session used for http requests - supply your own for caching or to provide authentication For more advanced options, check out the code of the ``Premailer`` class and all its options in its constructor. - You can also use premailer from the command line by using his main + You can also use premailer from the command line by using its main module. :: @@ -184,6 +188,7 @@ --disable-validation Disable CSSParser validation of attributes and values --pretty Pretty-print the outputted HTML. --allow-insecure-ssl Skip SSL certificate verification for external URLs. + --allow-loading-external-files Allow opening any non-HTTP external file URL. A basic example: @@ -269,7 +274,7 @@ Certain HTML attributes are also created on the HTML if the CSS contains any ones that are easily translated into HTML attributes. For example, if you have this CSS: ``td { background-color:#eee; }`` then this is - transformed into ``style="background-color:#eee"`` AND as an HTML + transformed into ``style="background-color:#eee"`` and as an HTML attribute ``bgcolor="#eee"``. Having these extra attributes basically as a "back up" for really shit @@ -430,16 +435,16 @@ Classifier: License :: OSI Approved :: Python Software Foundation License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Communications Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Other/Nonlisted Topic Classifier: Topic :: Software Development :: Libraries :: Python Modules -Provides-Extra: test Provides-Extra: dev +Provides-Extra: test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/premailer-3.6.1/premailer.egg-info/requires.txt new/premailer-3.10.0/premailer.egg-info/requires.txt --- old/premailer-3.6.1/premailer.egg-info/requires.txt 2019-08-24 05:40:54.000000000 +0200 +++ new/premailer-3.10.0/premailer.egg-info/requires.txt 2021-08-02 22:32:51.000000000 +0200 @@ -10,6 +10,7 @@ therapist black flake8 +wheel [test] nose diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/premailer-3.6.1/setup.py new/premailer-3.10.0/setup.py --- old/premailer-3.6.1/setup.py 2018-11-26 20:12:13.000000000 +0100 +++ new/premailer-3.10.0/setup.py 2021-04-12 17:48:07.000000000 +0200 @@ -1,7 +1,5 @@ -import codecs import os.path import re -import sys from setuptools import setup, find_packages @@ -12,7 +10,8 @@ def find_version(*file_paths): version_file_path = os.path.join(os.path.dirname(__file__), *file_paths) - version_file = codecs.open(version_file_path, encoding="utf-8").read() + with open(version_file_path) as f: + version_file = f.read() version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", version_file, re.M) if version_match: return version_match.group(1) @@ -21,11 +20,6 @@ install_requires = ["lxml", "cssselect", "cssutils", "requests", "cachetools"] -if sys.version_info >= (2, 6) and sys.version_info <= (2, 7): - # Python 2.6 is the oldest version we support and it - # needs some extra stuff - install_requires.extend(["argparse", "ordereddict"]) - tests_require = ["nose", "mock"] setup( @@ -46,11 +40,11 @@ "License :: OSI Approved :: Python Software Foundation License", "Operating System :: OS Independent", "Programming Language :: Python", - "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Communications", @@ -63,7 +57,7 @@ test_suite="nose.collector", tests_require=tests_require, extras_require={ - "dev": ["tox", "twine", "therapist", "black", "flake8"], + "dev": ["tox", "twine", "therapist", "black", "flake8", "wheel"], "test": tests_require, }, zip_safe=False,