__init__.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. # GNU MediaGoblin -- federated, autonomous media hosting
  2. # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
  3. #
  4. # This program is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU Affero General Public License as published by
  6. # the Free Software Foundation, either version 3 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU Affero General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU Affero General Public License
  15. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. from __future__ import unicode_literals
  17. import logging
  18. import re
  19. from mediagoblin import meddleware
  20. _log = logging.getLogger(__name__)
  21. class TrimWhiteSpaceMeddleware(meddleware.BaseMeddleware):
  22. _setup_plugin_called = 0
  23. RE_MULTI_WHITESPACE = re.compile(b'(\s)\s+', re.M)
  24. def process_response(self, request, response):
  25. """Perform very naive html tidying by removing multiple whitespaces"""
  26. # werkzeug.BaseResponse has no content_type attr, this comes via
  27. # werkzeug.wrappers.CommonRequestDescriptorsMixin (part of
  28. # wrappers.Response)
  29. if getattr(response ,'content_type', None) != 'text/html':
  30. return
  31. # This is a tad more complex than needed to be able to handle
  32. # response.data and response.body, depending on whether we have
  33. # a werkzeug Resonse or a webob one. Let's kill webob soon!
  34. if hasattr(response, 'body') and not hasattr(response, 'data'):
  35. # Old-style webob Response object.
  36. # TODO: Remove this once we transition away from webob
  37. resp_attr = 'body'
  38. else:
  39. resp_attr = 'data'
  40. # Don't flatten iterator to list when we fudge the response body
  41. # (see werkzeug.Response documentation)
  42. response.implicit_sequence_conversion = False
  43. # Set the tidied text. Very naive tidying for now, just strip all
  44. # subsequent whitespaces (this preserves most newlines)
  45. setattr(response, resp_attr, re.sub(
  46. TrimWhiteSpaceMeddleware.RE_MULTI_WHITESPACE, br'\1',
  47. getattr(response, resp_attr)))
  48. @classmethod
  49. def setup_plugin(cls):
  50. """Set up this meddleware as a plugin during 'setup' hook"""
  51. global _log
  52. if cls._setup_plugin_called:
  53. _log.info('Trim whitespace plugin was already set up.')
  54. return
  55. _log.debug('Trim whitespace plugin set up.')
  56. cls._setup_plugin_called += 1
  57. # Append ourselves to the list of enabled Meddlewares
  58. meddleware.ENABLED_MEDDLEWARE.append(
  59. '{0}:{1}'.format(cls.__module__, cls.__name__))
  60. hooks = {
  61. 'setup': TrimWhiteSpaceMeddleware.setup_plugin
  62. }