diff --git a/code/Managed Software Center/Managed Software Center/MunkiItems.py b/code/Managed Software Center/Managed Software Center/MunkiItems.py index 3e434700..dc5bcd69 100644 --- a/code/Managed Software Center/Managed Software Center/MunkiItems.py +++ b/code/Managed Software Center/Managed Software Center/MunkiItems.py @@ -26,7 +26,7 @@ import munki from operator import itemgetter from urllib import quote, unquote -from HTMLParser import HTMLParseError +from HTMLParser import HTMLParser, HTMLParseError from Foundation import * from AppKit import * @@ -235,6 +235,91 @@ def convertIconToPNG(app_name, destination_path, desired_size): return False +class MSUHTMLFilter(HTMLParser): + '''Filters HTML and HTML fragments for use inside description paragraphs''' + # ignore everything inside one of these tags + ignore_elements = ['script', 'style', 'head', 'table', 'form'] + # preserve these tags + preserve_tags = ['a', 'b', 'i', 'strong', 'em', 'small', 'sub', 'sup', 'ins', + 'del', 'mark', 'span', 'br'] + # transform these tags + transform_starttags = { 'ul': '
', + 'ol': '
', + 'li': '  • ', + 'h1': '', + 'h2': '', + 'h3': '', + 'h4': '', + 'h5': '', + 'h6': '', + 'p': ''} + transform_endtags = { 'ul': '
', + 'ol': '
', + 'li': '
', + 'h1': '

', + 'h2': '

', + 'h3': '

', + 'h4': '

', + 'h5': '

', + 'h6': '

', + 'p': '
'} + # track the currently-ignored element if any + current_ignore_element = None + # track the number of tags we found + tag_count = 0 + # store our filtered/transformed html fragment + filtered_html = u'' + + def handle_starttag(self, tag, attrs): + self.tag_count += 1 + if not self.current_ignore_element: + if tag in self.ignore_elements: + self.current_ignore_element = tag + elif tag in self.transform_starttags: + self.filtered_html += self.transform_starttags[tag] + elif tag in self.preserve_tags: + self.filtered_html += self.get_starttag_text() + + def handle_endtag(self, tag): + if tag == self.current_ignore_element: + self.current_ignore_element = None + elif not self.current_ignore_element: + if tag in self.transform_endtags: + self.filtered_html += self.transform_endtags[tag] + elif tag in self.preserve_tags: + self.filtered_html += u'' % tag + + def handle_data(self, data): + if not self.current_ignore_element: + self.filtered_html += data + + def handle_entityref(self, name): + if not self.current_ignore_element: + # add the entity reference as-is + self.filtered_html += u'&%s;' % name + + def handle_charref(self, name): + if not self.current_ignore_element: + # just pass on unmodified + self.filtered_html += name + + +def filtered_html(text): + '''Returns filtered HTML for use in description paragraphs''' + parser = MSUHTMLFilter() + parser.feed(text) + if parser.tag_count: + # found at least one html tag, so this is probably HTML + return parser.filtered_html + else: + # might be plain text, so we should escape a few entities and + # add
for line breaks + text = text.replace('&', '&') + text = text.replace('<', '<') + text = text.replace('>', '>') + return text.replace('\n', '
\n') + + class SelfService(object): '''An object to wrap interactions with the SelfServiceManifest''' def __init__(self): @@ -304,9 +389,10 @@ class GenericItem(dict): self['developer'] = self.guess_developer() if self.get('description'): try: - self['raw_description'] = msulib.filtered_html(self['description']) + self['raw_description'] = filtered_html(self['description']) except HTMLParseError, err: - self['raw_description'] = 'Invalid HTML in description for %s' % self['display_name'] + self['raw_description'] = ( + 'Invalid HTML in description for %s' % self['display_name']) del(self['description']) if not 'raw_description' in self: self['raw_description'] = u'' diff --git a/code/Managed Software Center/Managed Software Center/msulib.py b/code/Managed Software Center/Managed Software Center/msulib.py index 537331b5..b94d1bf3 100644 --- a/code/Managed Software Center/Managed Software Center/msulib.py +++ b/code/Managed Software Center/Managed Software Center/msulib.py @@ -24,8 +24,6 @@ import sys import shutil -from HTMLParser import HTMLParser - from Foundation import * from AppKit import * @@ -33,90 +31,6 @@ import munki _html_dir = None -class MSUHTMLFilter(HTMLParser): - '''Filters HTML and HTML fragments for use inside description paragraphs''' - # ignore everything inside one of these tags - ignore_elements = ['script', 'style', 'head', 'table', 'form'] - # preserve these tags - preserve_tags = ['a', 'b', 'i', 'strong', 'em', 'small', 'sub', 'sup', 'ins', - 'del', 'mark', 'span', 'br'] - # transform these tags - transform_starttags = { 'ul': '
', - 'ol': '
', - 'li': '  • ', - 'h1': '', - 'h2': '', - 'h3': '', - 'h4': '', - 'h5': '', - 'h6': '', - 'p': ''} - transform_endtags = { 'ul': '
', - 'ol': '
', - 'li': '
', - 'h1': '

', - 'h2': '

', - 'h3': '

', - 'h4': '

', - 'h5': '

', - 'h6': '

', - 'p': '
'} - # track the currently-ignored element if any - current_ignore_element = None - # track the number of tags we found - tag_count = 0 - # store our filtered/transformed html fragment - filtered_html = u'' - - def handle_starttag(self, tag, attrs): - self.tag_count += 1 - if not self.current_ignore_element: - if tag in self.ignore_elements: - self.current_ignore_element = tag - elif tag in self.transform_starttags: - self.filtered_html += self.transform_starttags[tag] - elif tag in self.preserve_tags: - self.filtered_html += self.get_starttag_text() - - def handle_endtag(self, tag): - if tag == self.current_ignore_element: - self.current_ignore_element = None - elif not self.current_ignore_element: - if tag in self.transform_endtags: - self.filtered_html += self.transform_endtags[tag] - elif tag in self.preserve_tags: - self.filtered_html += u'' % tag - - def handle_data(self, data): - if not self.current_ignore_element: - self.filtered_html += data - - def handle_entityref(self, name): - if not self.current_ignore_element: - # add the entity reference as-is - self.filtered_html += u'&%s;' % name - - def handle_charref(self, name): - if not self.current_ignore_element: - # just pass on unmodified - self.filtered_html += name - - -def filtered_html(text): - '''Returns filtered HTML for use in description paragraphs''' - parser = MSUHTMLFilter() - parser.feed(text) - if parser.tag_count: - # found at least one html tag, so this is probably HTML - return parser.filtered_html - else: - # might be plain text, so we should escape a few entities and - # add
for line breaks - text = text.replace('&', '&') - text = text.replace('<', '<') - text = text.replace('>', '>') - return text.replace('\n', '
\n') - def updateCountMessage(count): '''Return a localized message describing the count of updates to install'''