diff --git a/compressor/parser/beautifulsoup.py b/compressor/parser/beautifulsoup.py index 85a50cc..e896606 100644 --- a/compressor/parser/beautifulsoup.py +++ b/compressor/parser/beautifulsoup.py @@ -1,20 +1,23 @@ from __future__ import absolute_import -from compressor.exceptions import ParserError -from compressor.parser import ParserBase +from django.core.exceptions import ImproperlyConfigured from django.utils.encoding import smart_unicode -class BeautifulSoupParser(ParserBase): - _soup = None +from compressor.exceptions import ParserError +from compressor.parser import ParserBase +from compressor.utils.cache import cached_property - @property + +class BeautifulSoupParser(ParserBase): + + @cached_property def soup(self): - if self._soup is None: - try: - from BeautifulSoup import BeautifulSoup - except ImportError, e: - raise ParserError("Error while initializing Parser: %s" % e) - self._soup = BeautifulSoup(self.content) - return self._soup + try: + from BeautifulSoup import BeautifulSoup + return BeautifulSoup(self.content) + except ImportError, err: + raise ImproperlyConfigured("Error while importing BeautifulSoup: %s" % err) + except Exception, err: + raise ParserError("Error while initializing Parser: %s" % err) def css_elems(self): return self.soup.findAll({'link': True, 'style': True}) diff --git a/compressor/parser/html5lib.py b/compressor/parser/html5lib.py index d30d8cd..ee6aaa6 100644 --- a/compressor/parser/html5lib.py +++ b/compressor/parser/html5lib.py @@ -1,43 +1,40 @@ from __future__ import absolute_import +from django.utils.encoding import smart_unicode +from django.core.exceptions import ImproperlyConfigured + from compressor.exceptions import ParserError from compressor.parser import ParserBase -from django.utils.encoding import smart_unicode +from compressor.utils.cache import cached_property -try: - import html5lib -except ImortError: - html5lib = None - -def _serialize(el): - fragment = html5lib.treebuilders.simpletree.DocumentFragment() - fragment.appendChild(el) - return html5lib.serialize(fragment, quote_attr_values=True, - omit_optional_tags=False) - -def _find(tree, *names): - for node in tree.childNodes: - if node.type == 5 and node.name in names: - yield node class Html5LibParser(ParserBase): - _html = None - @property + def _serialize(self, elem): + fragment = html5lib.treebuilders.simpletree.DocumentFragment() + fragment.appendChild(elem) + return html5lib.serialize(fragment, + quote_attr_values=True, omit_optional_tags=False) + + def _find(self, *names): + for node in self.html.childNodes: + if node.type == 5 and node.name in names: + yield node + + @cached_property def html(self): - if self._html is None: - try: - import html5lib - self._html = html5lib.parseFragment(self.content) - except Exception, e: - raise ParserError("Error while initializing Parser: %s" % e) - return self._html - + try: + import html5lib + return html5lib.parseFragment(self.content) + except ImortError, err: + raise ImproperlyConfigured("Error while importing html5lib: %s" % err) + except Exception, err: + raise ParserError("Error while initializing Parser: %s" % err) def css_elems(self): - return _find(self.html, 'style', 'link') + return self._find('style', 'link') def js_elems(self): - return _find(self.html, 'script') + return self._find('script') def elem_attribs(self, elem): return elem.attributes @@ -49,4 +46,4 @@ class Html5LibParser(ParserBase): return elem.name def elem_str(self, elem): - return smart_unicode(_serialize(elem)) + return smart_unicode(self._serialize(elem)) diff --git a/compressor/parser/lxml.py b/compressor/parser/lxml.py index a831b4e..f781878 100644 --- a/compressor/parser/lxml.py +++ b/compressor/parser/lxml.py @@ -1,28 +1,31 @@ from __future__ import absolute_import -from compressor.exceptions import ParserError -from compressor.parser import ParserBase - +from django.core.exceptions import ImproperlyConfigured from django.utils.encoding import smart_unicode -class LxmlParser(ParserBase): - _tree = None +from compressor.exceptions import ParserError +from compressor.parser import ParserBase +from compressor.utils.cache import cached_property - @property + +class LxmlParser(ParserBase): + + @cached_property def tree(self): - if self._tree is None: + content = '%s' % self.content + try: + from lxml.html import fromstring, soupparser + from lxml.etree import tostring + tree = fromstring(content) try: - from lxml import html - from lxml.etree import tostring - except ImportError, e: - raise ParserError("Error while initializing Parser: %s" % e) - else: - content = '%s' % self.content - self._tree = html.fromstring(content) - try: - ignore = tostring(self._tree, encoding=unicode) - except UnicodeDecodeError: - self._tree = html.soupparser.fromstring(content) - return self._tree + ignore = tostring(tree, encoding=unicode) + except UnicodeDecodeError: + tree = soupparser.fromstring(content) + except ImportError, err: + raise ImproperlyConfigured("Error while importing lxml: %s" % err) + except Exception, err: + raise ParserError("Error while initializing Parser: %s" % err) + else: + return tree def css_elems(self): return self.tree.xpath('link[@rel="stylesheet"]|style')