01-arcadia.patch 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. --- contrib/python/Flask/py2/flask/helpers.py (index)
  2. +++ contrib/python/Flask/py2/flask/helpers.py (working tree)
  3. @@ -21,7 +21,7 @@ from threading import RLock
  4. from time import time
  5. from zlib import adler32
  6. -from jinja2 import FileSystemLoader
  7. +from jinja2 import ChoiceLoader, FileSystemLoader, ResourceLoader
  8. from werkzeug.datastructures import Headers
  9. from werkzeug.exceptions import BadRequest
  10. from werkzeug.exceptions import NotFound
  11. @@ -974,6 +974,13 @@ class _PackageBoundObject(object):
  12. def __init__(self, import_name, template_folder=None, root_path=None):
  13. self.import_name = import_name
  14. +
  15. + package_name = import_name
  16. + self.module_loader = pkgutil.find_loader(import_name)
  17. + if self.module_loader and not self.module_loader.is_package(import_name):
  18. + package_name = package_name.rsplit('.', 1)[0]
  19. + self._builtin_resource_prefix = package_name.replace('.', '/')
  20. +
  21. self.template_folder = template_folder
  22. if root_path is None:
  23. @@ -1041,7 +1048,10 @@ class _PackageBoundObject(object):
  24. .. versionadded:: 0.5
  25. """
  26. if self.template_folder is not None:
  27. - return FileSystemLoader(os.path.join(self.root_path, self.template_folder))
  28. + return ChoiceLoader([
  29. + FileSystemLoader(os.path.join(self.root_path, self.template_folder)),
  30. + ResourceLoader(os.path.join(self._builtin_resource_prefix, self.template_folder), self.module_loader),
  31. + ])
  32. def get_send_file_max_age(self, filename):
  33. """Provides default cache_timeout for the :func:`send_file` functions.
  34. @@ -1080,9 +1090,26 @@ class _PackageBoundObject(object):
  35. # Ensure get_send_file_max_age is called in all cases.
  36. # Here, we ensure get_send_file_max_age is called for Blueprints.
  37. cache_timeout = self.get_send_file_max_age(filename)
  38. - return send_from_directory(
  39. - self.static_folder, filename, cache_timeout=cache_timeout
  40. - )
  41. + try:
  42. + return send_from_directory(
  43. + self.static_folder, filename, cache_timeout=cache_timeout
  44. + )
  45. + except NotFound:
  46. + if self.module_loader is None:
  47. + raise
  48. + from io import BytesIO
  49. + path = os.path.join(self._builtin_resource_prefix, self._static_folder, filename)
  50. + try:
  51. + data = self.module_loader.get_data(path)
  52. + except IOError:
  53. + raise NotFound
  54. + mimetype = mimetypes.guess_type(filename)[0]
  55. + fobj = BytesIO(data)
  56. + # Note: in case of uWSGI, might also need to set
  57. + # `wsgi-disable-file-wrapper = true`
  58. + # because, otherwise, uwsgi expects a `fileno` on it.
  59. + return send_file(fobj, mimetype=mimetype,
  60. + cache_timeout=cache_timeout, conditional=True)
  61. def open_resource(self, resource, mode="rb"):
  62. """Opens a resource from the application's resource folder. To see