prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Use `django-storages`'s manifest files class
  `django-storages` already implemented the manifest files class (see https://github.com/jschneier/django-storages/issues/733#issuecomment-989005340) so we can use it directly and remove our override for this in:
  
  https://github.com/readthedocs/readthedocs.org/blob/933c316f5228423f9f871b3da858a01491f79925/readthedocs/storage/s3_storage.py#L55-L61
  
  </issue>
  <code>
  [start of readthedocs/storage/s3_storage.py]
  1 """
  2 AWS S3 Storage backends.
  3 
  4 We override the backends provided by django-storages to add some small pieces
  5 that we need to make our project to work as we want. For example, using
  6 ManifestFilesMixin for static files and OverrideHostnameMixin to make it work
  7 in our Docker Development environment.
  8 """
  9 
  10 # Disable abstract method because we are not overriding all the methods
  11 # pylint: disable=abstract-method
  12 from django.conf import settings
  13 from django.contrib.staticfiles.storage import ManifestFilesMixin
  14 from django.core.exceptions import ImproperlyConfigured
  15 from storages.backends.s3boto3 import S3Boto3Storage
  16 
  17 from readthedocs.builds.storage import BuildMediaStorageMixin
  18 
  19 from .mixins import OverrideHostnameMixin, S3PrivateBucketMixin
  20 
  21 
  22 class S3BuildMediaStorage(BuildMediaStorageMixin, OverrideHostnameMixin, S3Boto3Storage):
  23 
  24     """An AWS S3 Storage backend for build artifacts."""
  25 
  26     bucket_name = getattr(settings, 'S3_MEDIA_STORAGE_BUCKET', None)
  27     override_hostname = getattr(settings, 'S3_MEDIA_STORAGE_OVERRIDE_HOSTNAME', None)
  28 
  29     def __init__(self, *args, **kwargs):
  30         super().__init__(*args, **kwargs)
  31 
  32         if not self.bucket_name:
  33             raise ImproperlyConfigured(
  34                 'AWS S3 not configured correctly. '
  35                 'Ensure S3_MEDIA_STORAGE_BUCKET is defined.',
  36             )
  37 
  38 
  39 class S3BuildCommandsStorage(S3PrivateBucketMixin, S3Boto3Storage):
  40 
  41     """An AWS S3 Storage backend for build commands."""
  42 
  43     bucket_name = getattr(settings, 'S3_BUILD_COMMANDS_STORAGE_BUCKET', None)
  44 
  45     def __init__(self, *args, **kwargs):
  46         super().__init__(*args, **kwargs)
  47 
  48         if not self.bucket_name:
  49             raise ImproperlyConfigured(
  50                 'AWS S3 not configured correctly. '
  51                 'Ensure S3_BUILD_COMMANDS_STORAGE_BUCKET is defined.',
  52             )
  53 
  54 
  55 class S3StaticStorage(OverrideHostnameMixin, ManifestFilesMixin, S3Boto3Storage):
  56 
  57     """
  58     An AWS S3 Storage backend for static media.
  59 
  60     * Uses Django's ManifestFilesMixin to have unique file paths (eg. core.a6f5e2c.css)
  61     """
  62 
  63     bucket_name = getattr(settings, 'S3_STATIC_STORAGE_BUCKET', None)
  64     override_hostname = getattr(settings, 'S3_STATIC_STORAGE_OVERRIDE_HOSTNAME', None)
  65 
  66     def __init__(self, *args, **kwargs):
  67         super().__init__(*args, **kwargs)
  68 
  69         if not self.bucket_name:
  70             raise ImproperlyConfigured(
  71                 'AWS S3 not configured correctly. '
  72                 'Ensure S3_STATIC_STORAGE_BUCKET is defined.',
  73             )
  74 
  75         self.bucket_acl = 'public-read'
  76         self.default_acl = 'public-read'
  77         self.querystring_auth = False
  78 
  79 
  80 class S3BuildEnvironmentStorage(S3PrivateBucketMixin, BuildMediaStorageMixin, S3Boto3Storage):
  81 
  82     bucket_name = getattr(settings, 'S3_BUILD_ENVIRONMENT_STORAGE_BUCKET', None)
  83 
  84     def __init__(self, *args, **kwargs):
  85         super().__init__(*args, **kwargs)
  86 
  87         if not self.bucket_name:
  88             raise ImproperlyConfigured(
  89                 'AWS S3 not configured correctly. '
  90                 'Ensure S3_BUILD_ENVIRONMENT_STORAGE_BUCKET is defined.',
  91             )
  92 
  93 
  94 class S3BuildToolsStorage(S3PrivateBucketMixin, BuildMediaStorageMixin, S3Boto3Storage):
  95 
  96     bucket_name = getattr(settings, 'S3_BUILD_TOOLS_STORAGE_BUCKET', None)
  97 
  98     def __init__(self, *args, **kwargs):
  99         super().__init__(*args, **kwargs)
  100 
  101         if not self.bucket_name:
  102             raise ImproperlyConfigured(
  103                 'AWS S3 not configured correctly. '
  104                 'Ensure S3_BUILD_TOOLS_STORAGE_BUCKET is defined.',
  105             )
  106
  [end of readthedocs/storage/s3_storage.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/readthedocs/storage/s3_storage.py b/readthedocs/storage/s3_storage.py
  --- a/readthedocs/storage/s3_storage.py
  +++ b/readthedocs/storage/s3_storage.py
  @@ -10,9 +10,8 @@
   # Disable abstract method because we are not overriding all the methods
   # pylint: disable=abstract-method
   from django.conf import settings
  -from django.contrib.staticfiles.storage import ManifestFilesMixin
   from django.core.exceptions import ImproperlyConfigured
  -from storages.backends.s3boto3 import S3Boto3Storage
  +from storages.backends.s3boto3 import S3Boto3Storage, S3ManifestStaticStorage
   
   from readthedocs.builds.storage import BuildMediaStorageMixin
   
  @@ -52,7 +51,11 @@
               )
   
   
  -class S3StaticStorage(OverrideHostnameMixin, ManifestFilesMixin, S3Boto3Storage):
  +class S3StaticStorage(
  +    OverrideHostnameMixin,
  +    S3ManifestStaticStorage,
  +    S3Boto3Storage
  +):  # pylint: disable=too-many-ancestors
   
       """
       An AWS S3 Storage backend for static media.
  
verification_info: {"golden_diff": "diff --git a/readthedocs/storage/s3_storage.py b/readthedocs/storage/s3_storage.py\n--- a/readthedocs/storage/s3_storage.py\n+++ b/readthedocs/storage/s3_storage.py\n@@ -10,9 +10,8 @@\n # Disable abstract method because we are not overriding all the methods\n # pylint: disable=abstract-method\n from django.conf import settings\n-from django.contrib.staticfiles.storage import ManifestFilesMixin\n from django.core.exceptions import ImproperlyConfigured\n-from storages.backends.s3boto3 import S3Boto3Storage\n+from storages.backends.s3boto3 import S3Boto3Storage, S3ManifestStaticStorage\n \n from readthedocs.builds.storage import BuildMediaStorageMixin\n \n@@ -52,7 +51,11 @@\n             )\n \n \n-class S3StaticStorage(OverrideHostnameMixin, ManifestFilesMixin, S3Boto3Storage):\n+class S3StaticStorage(\n+    OverrideHostnameMixin,\n+    S3ManifestStaticStorage,\n+    S3Boto3Storage\n+):  # pylint: disable=too-many-ancestors\n \n     \"\"\"\n     An AWS S3 Storage backend for static media.\n", "issue": "Use `django-storages`'s manifest files class\n`django-storages` already implemented the manifest files class (see https://github.com/jschneier/django-storages/issues/733#issuecomment-989005340) so we can use it directly and remove our override for this in:\r\n\r\nhttps://github.com/readthedocs/readthedocs.org/blob/933c316f5228423f9f871b3da858a01491f79925/readthedocs/storage/s3_storage.py#L55-L61\n", "before_files": [{"content": "\"\"\"\nAWS S3 Storage backends.\n\nWe override the backends provided by django-storages to add some small pieces\nthat we need to make our project to work as we want. For example, using\nManifestFilesMixin for static files and OverrideHostnameMixin to make it work\nin our Docker Development environment.\n\"\"\"\n\n# Disable abstract method because we are not overriding all the methods\n# pylint: disable=abstract-method\nfrom django.conf import settings\nfrom django.contrib.staticfiles.storage import ManifestFilesMixin\nfrom django.core.exceptions import ImproperlyConfigured\nfrom storages.backends.s3boto3 import S3Boto3Storage\n\nfrom readthedocs.builds.storage import BuildMediaStorageMixin\n\nfrom .mixins import OverrideHostnameMixin, S3PrivateBucketMixin\n\n\nclass S3BuildMediaStorage(BuildMediaStorageMixin, OverrideHostnameMixin, S3Boto3Storage):\n\n    \"\"\"An AWS S3 Storage backend for build artifacts.\"\"\"\n\n    bucket_name = getattr(settings, 'S3_MEDIA_STORAGE_BUCKET', None)\n    override_hostname = getattr(settings, 'S3_MEDIA_STORAGE_OVERRIDE_HOSTNAME', None)\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\n        if not self.bucket_name:\n            raise ImproperlyConfigured(\n                'AWS S3 not configured correctly. '\n                'Ensure S3_MEDIA_STORAGE_BUCKET is defined.',\n            )\n\n\nclass S3BuildCommandsStorage(S3PrivateBucketMixin, S3Boto3Storage):\n\n    \"\"\"An AWS S3 Storage backend for build commands.\"\"\"\n\n    bucket_name = getattr(settings, 'S3_BUILD_COMMANDS_STORAGE_BUCKET', None)\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\n        if not self.bucket_name:\n            raise ImproperlyConfigured(\n                'AWS S3 not configured correctly. '\n                'Ensure S3_BUILD_COMMANDS_STORAGE_BUCKET is defined.',\n            )\n\n\nclass S3StaticStorage(OverrideHostnameMixin, ManifestFilesMixin, S3Boto3Storage):\n\n    \"\"\"\n    An AWS S3 Storage backend for static media.\n\n    * Uses Django's ManifestFilesMixin to have unique file paths (eg. core.a6f5e2c.css)\n    \"\"\"\n\n    bucket_name = getattr(settings, 'S3_STATIC_STORAGE_BUCKET', None)\n    override_hostname = getattr(settings, 'S3_STATIC_STORAGE_OVERRIDE_HOSTNAME', None)\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\n        if not self.bucket_name:\n            raise ImproperlyConfigured(\n                'AWS S3 not configured correctly. '\n                'Ensure S3_STATIC_STORAGE_BUCKET is defined.',\n            )\n\n        self.bucket_acl = 'public-read'\n        self.default_acl = 'public-read'\n        self.querystring_auth = False\n\n\nclass S3BuildEnvironmentStorage(S3PrivateBucketMixin, BuildMediaStorageMixin, S3Boto3Storage):\n\n    bucket_name = getattr(settings, 'S3_BUILD_ENVIRONMENT_STORAGE_BUCKET', None)\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\n        if not self.bucket_name:\n            raise ImproperlyConfigured(\n                'AWS S3 not configured correctly. '\n                'Ensure S3_BUILD_ENVIRONMENT_STORAGE_BUCKET is defined.',\n            )\n\n\nclass S3BuildToolsStorage(S3PrivateBucketMixin, BuildMediaStorageMixin, S3Boto3Storage):\n\n    bucket_name = getattr(settings, 'S3_BUILD_TOOLS_STORAGE_BUCKET', None)\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\n        if not self.bucket_name:\n            raise ImproperlyConfigured(\n                'AWS S3 not configured correctly. '\n                'Ensure S3_BUILD_TOOLS_STORAGE_BUCKET is defined.',\n            )\n", "path": "readthedocs/storage/s3_storage.py"}]}