We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Re-generate all bundles with Distribution changes after Timestamp


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `snippets/base/management/commands/generate_bundles.py`
Content:
```
1 import os
2 import json
3 import itertools
4 from datetime import datetime
5 
6 import brotli
7 from product_details import product_details
8 
9 from django.conf import settings
10 from django.core.files.base import ContentFile
11 from django.core.management.base import BaseCommand
12 from django.db.models import Q
13 from django.core.files.storage import default_storage
14 
15 from snippets.base.models import DistributionBundle, Job
16 
17 
18 class Command(BaseCommand):
19     args = '(no args)'
20     help = 'Generate bundles'
21 
22     def add_arguments(self, parser):
23         # Named (optional) arguments
24         parser.add_argument(
25             '--timestamp',
26             help='Parse Jobs last modified after <timestamp>',
27         )
28 
29     def handle(self, *args, **options):
30         if not options['timestamp']:
31             self.stdout.write('Generating all bundles.')
32             total_jobs = Job.objects.all()
33         else:
34             self.stdout.write(
35                 'Generating bundles with Jobs modified on or after {}'.format(options['timestamp'])
36             )
37             total_jobs = Job.objects.filter(snippet__modified__gte=options['timestamp'])
38 
39         if not total_jobs:
40             self.stdout.write('Nothing to do…')
41             return
42 
43         self.stdout.write('Processing bundles…')
44 
45         combinations_to_process = set(
46             itertools.chain.from_iterable(
47                 itertools.product(
48                     job.channels,
49                     job.snippet.locale.code.strip(',').split(',')
50                 )
51                 for job in total_jobs
52             )
53         )
54         distribution_bundles_to_process = DistributionBundle.objects.filter(
55             distributions__jobs__in=total_jobs
56         ).distinct().order_by('id')
57 
58         for distribution_bundle in distribution_bundles_to_process:
59             distributions = distribution_bundle.distributions.all()
60 
61             for channel, locale in combinations_to_process:
62                 additional_jobs = []
63                 if channel == 'nightly' and settings.NIGHTLY_INCLUDES_RELEASE:
64                     additional_jobs = Job.objects.filter(
65                         status=Job.PUBLISHED).filter(**{
66                             'targets__on_release': True,
67                             'distribution__in': distributions,
68                         })
69 
70                 channel_jobs = Job.objects.filter(
71                     status=Job.PUBLISHED).filter(
72                         Q(**{
73                             'targets__on_{}'.format(channel): True,
74                             'distribution__in': distributions,
75                         }))
76 
77                 all_jobs = Job.objects.filter(
78                     Q(id__in=additional_jobs) | Q(id__in=channel_jobs)
79                 )
80 
81                 locales_to_process = [
82                     key.lower() for key in product_details.languages.keys()
83                     if key.lower().startswith(locale)
84                 ]
85 
86                 for locale_to_process in locales_to_process:
87                     filename = 'Firefox/{channel}/{locale}/{distribution}.json'.format(
88                         channel=channel,
89                         locale=locale_to_process,
90                         distribution=distribution_bundle.code_name,
91                     )
92                     filename = os.path.join(settings.MEDIA_BUNDLES_PREGEN_ROOT, filename)
93                     full_locale = ',{},'.format(locale_to_process.lower())
94                     splitted_locale = ',{},'.format(locale_to_process.lower().split('-', 1)[0])
95                     bundle_jobs = all_jobs.filter(
96                         Q(snippet__locale__code__contains=splitted_locale) |
97                         Q(snippet__locale__code__contains=full_locale)).distinct()
98 
99                     # If DistributionBundle is not enabled, or if there are no
100                     # Published Jobs for the channel / locale / distribution
101                     # combination, delete the current bundle file if it exists.
102                     if not distribution_bundle.enabled or not bundle_jobs.exists():
103                         if default_storage.exists(filename):
104                             self.stdout.write('Removing {}'.format(filename))
105                             default_storage.delete(filename)
106                         continue
107 
108                     data = []
109                     channel_job_ids = list(channel_jobs.values_list('id', flat=True))
110                     for job in bundle_jobs:
111                         if job.id in channel_job_ids:
112                             render = job.render()
113                         else:
114                             render = job.render(always_eval_to_false=True)
115                         data.append(render)
116 
117                     bundle_content = json.dumps({
118                         'messages': data,
119                         'metadata': {
120                             'generated_at': datetime.utcnow().isoformat(),
121                             'number_of_snippets': len(data),
122                             'channel': channel,
123                         }
124                     })
125 
126                     # Convert str to bytes.
127                     if isinstance(bundle_content, str):
128                         bundle_content = bundle_content.encode('utf-8')
129 
130                     if settings.BUNDLE_BROTLI_COMPRESS:
131                         content_file = ContentFile(brotli.compress(bundle_content))
132                         content_file.content_encoding = 'br'
133                     else:
134                         content_file = ContentFile(bundle_content)
135 
136                     default_storage.save(filename, content_file)
137                     self.stdout.write(self.style.SUCCESS('Writing bundle {}'.format(filename)))
138
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/snippets/base/management/commands/generate_bundles.py b/snippets/base/management/commands/generate_bundles.py
--- a/snippets/base/management/commands/generate_bundles.py
+++ b/snippets/base/management/commands/generate_bundles.py
@@ -34,7 +34,10 @@
             self.stdout.write(
                 'Generating bundles with Jobs modified on or after {}'.format(options['timestamp'])
             )
-            total_jobs = Job.objects.filter(snippet__modified__gte=options['timestamp'])
+            total_jobs = Job.objects.filter(
+                Q(snippet__modified__gte=options['timestamp']) |
+                Q(distribution__distributionbundle__modified__gte=options['timestamp'])
+            ).distinct()
 
         if not total_jobs:
             self.stdout.write('Nothing to do…')

{"golden_diff": "diff --git a/snippets/base/management/commands/generate_bundles.py b/snippets/base/management/commands/generate_bundles.py\n--- a/snippets/base/management/commands/generate_bundles.py\n+++ b/snippets/base/management/commands/generate_bundles.py\n@@ -34,7 +34,10 @@\n             self.stdout.write(\n                 'Generating bundles with Jobs modified on or after {}'.format(options['timestamp'])\n             )\n-            total_jobs = Job.objects.filter(snippet__modified__gte=options['timestamp'])\n+            total_jobs = Job.objects.filter(\n+                Q(snippet__modified__gte=options['timestamp']) |\n+                Q(distribution__distributionbundle__modified__gte=options['timestamp'])\n+            ).distinct()\n \n         if not total_jobs:\n             self.stdout.write('Nothing to do\u2026')\n", "issue": "Re-generate all bundles with Distribution changes after Timestamp\n\n", "before_files": [{"content": "import os\nimport json\nimport itertools\nfrom datetime import datetime\n\nimport brotli\nfrom product_details import product_details\n\nfrom django.conf import settings\nfrom django.core.files.base import ContentFile\nfrom django.core.management.base import BaseCommand\nfrom django.db.models import Q\nfrom django.core.files.storage import default_storage\n\nfrom snippets.base.models import DistributionBundle, Job\n\n\nclass Command(BaseCommand):\n    args = '(no args)'\n    help = 'Generate bundles'\n\n    def add_arguments(self, parser):\n        # Named (optional) arguments\n        parser.add_argument(\n            '--timestamp',\n            help='Parse Jobs last modified after <timestamp>',\n        )\n\n    def handle(self, *args, **options):\n        if not options['timestamp']:\n            self.stdout.write('Generating all bundles.')\n            total_jobs = Job.objects.all()\n        else:\n            self.stdout.write(\n                'Generating bundles with Jobs modified on or after {}'.format(options['timestamp'])\n            )\n            total_jobs = Job.objects.filter(snippet__modified__gte=options['timestamp'])\n\n        if not total_jobs:\n            self.stdout.write('Nothing to do\u2026')\n            return\n\n        self.stdout.write('Processing bundles\u2026')\n\n        combinations_to_process = set(\n            itertools.chain.from_iterable(\n                itertools.product(\n                    job.channels,\n                    job.snippet.locale.code.strip(',').split(',')\n                )\n                for job in total_jobs\n            )\n        )\n        distribution_bundles_to_process = DistributionBundle.objects.filter(\n            distributions__jobs__in=total_jobs\n        ).distinct().order_by('id')\n\n        for distribution_bundle in distribution_bundles_to_process:\n            distributions = distribution_bundle.distributions.all()\n\n            for channel, locale in combinations_to_process:\n                additional_jobs = []\n                if channel == 'nightly' and settings.NIGHTLY_INCLUDES_RELEASE:\n                    additional_jobs = Job.objects.filter(\n                        status=Job.PUBLISHED).filter(**{\n                            'targets__on_release': True,\n                            'distribution__in': distributions,\n                        })\n\n                channel_jobs = Job.objects.filter(\n                    status=Job.PUBLISHED).filter(\n                        Q(**{\n                            'targets__on_{}'.format(channel): True,\n                            'distribution__in': distributions,\n                        }))\n\n                all_jobs = Job.objects.filter(\n                    Q(id__in=additional_jobs) | Q(id__in=channel_jobs)\n                )\n\n                locales_to_process = [\n                    key.lower() for key in product_details.languages.keys()\n                    if key.lower().startswith(locale)\n                ]\n\n                for locale_to_process in locales_to_process:\n                    filename = 'Firefox/{channel}/{locale}/{distribution}.json'.format(\n                        channel=channel,\n                        locale=locale_to_process,\n                        distribution=distribution_bundle.code_name,\n                    )\n                    filename = os.path.join(settings.MEDIA_BUNDLES_PREGEN_ROOT, filename)\n                    full_locale = ',{},'.format(locale_to_process.lower())\n                    splitted_locale = ',{},'.format(locale_to_process.lower().split('-', 1)[0])\n                    bundle_jobs = all_jobs.filter(\n                        Q(snippet__locale__code__contains=splitted_locale) |\n                        Q(snippet__locale__code__contains=full_locale)).distinct()\n\n                    # If DistributionBundle is not enabled, or if there are no\n                    # Published Jobs for the channel / locale / distribution\n                    # combination, delete the current bundle file if it exists.\n                    if not distribution_bundle.enabled or not bundle_jobs.exists():\n                        if default_storage.exists(filename):\n                            self.stdout.write('Removing {}'.format(filename))\n                            default_storage.delete(filename)\n                        continue\n\n                    data = []\n                    channel_job_ids = list(channel_jobs.values_list('id', flat=True))\n                    for job in bundle_jobs:\n                        if job.id in channel_job_ids:\n                            render = job.render()\n                        else:\n                            render = job.render(always_eval_to_false=True)\n                        data.append(render)\n\n                    bundle_content = json.dumps({\n                        'messages': data,\n                        'metadata': {\n                            'generated_at': datetime.utcnow().isoformat(),\n                            'number_of_snippets': len(data),\n                            'channel': channel,\n                        }\n                    })\n\n                    # Convert str to bytes.\n                    if isinstance(bundle_content, str):\n                        bundle_content = bundle_content.encode('utf-8')\n\n                    if settings.BUNDLE_BROTLI_COMPRESS:\n                        content_file = ContentFile(brotli.compress(bundle_content))\n                        content_file.content_encoding = 'br'\n                    else:\n                        content_file = ContentFile(bundle_content)\n\n                    default_storage.save(filename, content_file)\n                    self.stdout.write(self.style.SUCCESS('Writing bundle {}'.format(filename)))\n", "path": "snippets/base/management/commands/generate_bundles.py"}], "after_files": [{"content": "import os\nimport json\nimport itertools\nfrom datetime import datetime\n\nimport brotli\nfrom product_details import product_details\n\nfrom django.conf import settings\nfrom django.core.files.base import ContentFile\nfrom django.core.management.base import BaseCommand\nfrom django.db.models import Q\nfrom django.core.files.storage import default_storage\n\nfrom snippets.base.models import DistributionBundle, Job\n\n\nclass Command(BaseCommand):\n    args = '(no args)'\n    help = 'Generate bundles'\n\n    def add_arguments(self, parser):\n        # Named (optional) arguments\n        parser.add_argument(\n            '--timestamp',\n            help='Parse Jobs last modified after <timestamp>',\n        )\n\n    def handle(self, *args, **options):\n        if not options['timestamp']:\n            self.stdout.write('Generating all bundles.')\n            total_jobs = Job.objects.all()\n        else:\n            self.stdout.write(\n                'Generating bundles with Jobs modified on or after {}'.format(options['timestamp'])\n            )\n            total_jobs = Job.objects.filter(\n                Q(snippet__modified__gte=options['timestamp']) |\n                Q(distribution__distributionbundle__modified__gte=options['timestamp'])\n            ).distinct()\n\n        if not total_jobs:\n            self.stdout.write('Nothing to do\u2026')\n            return\n\n        self.stdout.write('Processing bundles\u2026')\n\n        combinations_to_process = set(\n            itertools.chain.from_iterable(\n                itertools.product(\n                    job.channels,\n                    job.snippet.locale.code.strip(',').split(',')\n                )\n                for job in total_jobs\n            )\n        )\n        distribution_bundles_to_process = DistributionBundle.objects.filter(\n            distributions__jobs__in=total_jobs\n        ).distinct().order_by('id')\n\n        for distribution_bundle in distribution_bundles_to_process:\n            distributions = distribution_bundle.distributions.all()\n\n            for channel, locale in combinations_to_process:\n                additional_jobs = []\n                if channel == 'nightly' and settings.NIGHTLY_INCLUDES_RELEASE:\n                    additional_jobs = Job.objects.filter(\n                        status=Job.PUBLISHED).filter(**{\n                            'targets__on_release': True,\n                            'distribution__in': distributions,\n                        })\n\n                channel_jobs = Job.objects.filter(\n                    status=Job.PUBLISHED).filter(\n                        Q(**{\n                            'targets__on_{}'.format(channel): True,\n                            'distribution__in': distributions,\n                        }))\n\n                all_jobs = Job.objects.filter(\n                    Q(id__in=additional_jobs) | Q(id__in=channel_jobs)\n                )\n\n                locales_to_process = [\n                    key.lower() for key in product_details.languages.keys()\n                    if key.lower().startswith(locale)\n                ]\n\n                for locale_to_process in locales_to_process:\n                    filename = 'Firefox/{channel}/{locale}/{distribution}.json'.format(\n                        channel=channel,\n                        locale=locale_to_process,\n                        distribution=distribution_bundle.code_name,\n                    )\n                    filename = os.path.join(settings.MEDIA_BUNDLES_PREGEN_ROOT, filename)\n                    full_locale = ',{},'.format(locale_to_process.lower())\n                    splitted_locale = ',{},'.format(locale_to_process.lower().split('-', 1)[0])\n                    bundle_jobs = all_jobs.filter(\n                        Q(snippet__locale__code__contains=splitted_locale) |\n                        Q(snippet__locale__code__contains=full_locale)).distinct()\n\n                    # If DistributionBundle is not enabled, or if there are no\n                    # Published Jobs for the channel / locale / distribution\n                    # combination, delete the current bundle file if it exists.\n                    if not distribution_bundle.enabled or not bundle_jobs.exists():\n                        if default_storage.exists(filename):\n                            self.stdout.write('Removing {}'.format(filename))\n                            default_storage.delete(filename)\n                        continue\n\n                    data = []\n                    channel_job_ids = list(channel_jobs.values_list('id', flat=True))\n                    for job in bundle_jobs:\n                        if job.id in channel_job_ids:\n                            render = job.render()\n                        else:\n                            render = job.render(always_eval_to_false=True)\n                        data.append(render)\n\n                    bundle_content = json.dumps({\n                        'messages': data,\n                        'metadata': {\n                            'generated_at': datetime.utcnow().isoformat(),\n                            'number_of_snippets': len(data),\n                            'channel': channel,\n                        }\n                    })\n\n                    # Convert str to bytes.\n                    if isinstance(bundle_content, str):\n                        bundle_content = bundle_content.encode('utf-8')\n\n                    if settings.BUNDLE_BROTLI_COMPRESS:\n                        content_file = ContentFile(brotli.compress(bundle_content))\n                        content_file.content_encoding = 'br'\n                    else:\n                        content_file = ContentFile(bundle_content)\n\n                    default_storage.save(filename, content_file)\n                    self.stdout.write(self.style.SUCCESS('Writing bundle {}'.format(filename)))\n", "path": "snippets/base/management/commands/generate_bundles.py"}]}