prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Just published jobs with global limits get prematurely completed due to missing metrics.
  
  
  </issue>
  <code>
  [start of snippets/base/management/commands/update_jobs.py]
  1 from datetime import datetime, timedelta
  2 
  3 from django.contrib.auth import get_user_model
  4 from django.core.management.base import BaseCommand
  5 from django.db import transaction
  6 from django.db.models import F, Q
  7 
  8 from snippets.base.models import Job
  9 
  10 
  11 class Command(BaseCommand):
  12     args = "(no args)"
  13     help = "Update Jobs"
  14 
  15     @transaction.atomic
  16     def handle(self, *args, **options):
  17         now = datetime.utcnow()
  18         user = get_user_model().objects.get_or_create(username='snippets_bot')[0]
  19         count_total_completed = 0
  20 
  21         # Publish Scheduled Jobs with `publish_start` before now or without
  22         # publish_start.
  23         jobs = Job.objects.filter(status=Job.SCHEDULED).filter(
  24             Q(publish_start__lte=now) | Q(publish_start=None)
  25         )
  26         count_published = jobs.count()
  27         for job in jobs:
  28             job.change_status(
  29                 status=Job.PUBLISHED,
  30                 user=user,
  31                 reason='Published start date reached.',
  32             )
  33 
  34         # Disable Published Jobs with `publish_end` before now.
  35         jobs = Job.objects.filter(status=Job.PUBLISHED, publish_end__lte=now)
  36         count_publication_end = jobs.count()
  37         count_total_completed += count_publication_end
  38 
  39         for job in jobs:
  40             job.change_status(
  41                 status=Job.COMPLETED,
  42                 user=user,
  43                 reason='Publication end date reached.',
  44             )
  45 
  46         # Disable Jobs that reached Impression, Click or Block limits.
  47         count_limit = {}
  48         for limit in ['impressions', 'clicks', 'blocks']:
  49             jobs = (Job.objects
  50                     .filter(status=Job.PUBLISHED)
  51                     .exclude(**{f'limit_{limit}': 0})
  52                     .filter(**{f'limit_{limit}__lte': F(f'metric_{limit}')}))
  53             for job in jobs:
  54                 job.change_status(
  55                     status=Job.COMPLETED,
  56                     user=user,
  57                     reason=f'Limit reached: {limit}.',
  58                 )
  59 
  60             count_limit[limit] = jobs.count()
  61             count_total_completed += count_limit[limit]
  62 
  63         # Disable Jobs that have Impression, Click or Block limits but don't
  64         # have metrics data for at least 24h. This is to handle cases where the
  65         # Metrics Pipeline is broken.
  66         yesterday = datetime.utcnow() - timedelta(days=1)
  67         jobs = (Job.objects
  68                 .filter(status=Job.PUBLISHED)
  69                 .exclude(limit_impressions=0, limit_clicks=0, limit_blocks=0)
  70                 .filter(metric_last_update__lt=yesterday))
  71         for job in jobs:
  72             job.change_status(
  73                 status=Job.COMPLETED,
  74                 user=user,
  75                 reason=f'Premature termination due to missing metrics.',
  76             )
  77         count_premature_termination = jobs.count()
  78         count_total_completed += count_premature_termination
  79 
  80         count_running = Job.objects.filter(status=Job.PUBLISHED).count()
  81 
  82         self.stdout.write(
  83             f'Jobs Published: {count_published}\n'
  84             f'Jobs Completed: {count_total_completed}\n'
  85             f'  - Reached Publication End Date: {count_publication_end}\n'
  86             f'  - Reached Impressions Limit: {count_limit["impressions"]}\n'
  87             f'  - Reached Clicks Limit: {count_limit["clicks"]}\n'
  88             f'  - Reached Blocks Limit: {count_limit["blocks"]}\n'
  89             f'  - Premature Termination due to missing metrics: {count_premature_termination}\n'
  90             f'Total Jobs Running: {count_running}\n'
  91         )
  92
  [end of snippets/base/management/commands/update_jobs.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/snippets/base/management/commands/update_jobs.py b/snippets/base/management/commands/update_jobs.py
  --- a/snippets/base/management/commands/update_jobs.py
  +++ b/snippets/base/management/commands/update_jobs.py
  @@ -67,6 +67,8 @@
           jobs = (Job.objects
                   .filter(status=Job.PUBLISHED)
                   .exclude(limit_impressions=0, limit_clicks=0, limit_blocks=0)
  +                # Exclude Jobs with limits which haven't been updated once yet.
  +                .exclude(metric_last_update='1970-01-01')
                   .filter(metric_last_update__lt=yesterday))
           for job in jobs:
               job.change_status(
  
verification_info: {"golden_diff": "diff --git a/snippets/base/management/commands/update_jobs.py b/snippets/base/management/commands/update_jobs.py\n--- a/snippets/base/management/commands/update_jobs.py\n+++ b/snippets/base/management/commands/update_jobs.py\n@@ -67,6 +67,8 @@\n         jobs = (Job.objects\n                 .filter(status=Job.PUBLISHED)\n                 .exclude(limit_impressions=0, limit_clicks=0, limit_blocks=0)\n+                # Exclude Jobs with limits which haven't been updated once yet.\n+                .exclude(metric_last_update='1970-01-01')\n                 .filter(metric_last_update__lt=yesterday))\n         for job in jobs:\n             job.change_status(\n", "issue": "Just published jobs with global limits get prematurely completed due to missing metrics.\n\n", "before_files": [{"content": "from datetime import datetime, timedelta\n\nfrom django.contrib.auth import get_user_model\nfrom django.core.management.base import BaseCommand\nfrom django.db import transaction\nfrom django.db.models import F, Q\n\nfrom snippets.base.models import Job\n\n\nclass Command(BaseCommand):\n    args = \"(no args)\"\n    help = \"Update Jobs\"\n\n    @transaction.atomic\n    def handle(self, *args, **options):\n        now = datetime.utcnow()\n        user = get_user_model().objects.get_or_create(username='snippets_bot')[0]\n        count_total_completed = 0\n\n        # Publish Scheduled Jobs with `publish_start` before now or without\n        # publish_start.\n        jobs = Job.objects.filter(status=Job.SCHEDULED).filter(\n            Q(publish_start__lte=now) | Q(publish_start=None)\n        )\n        count_published = jobs.count()\n        for job in jobs:\n            job.change_status(\n                status=Job.PUBLISHED,\n                user=user,\n                reason='Published start date reached.',\n            )\n\n        # Disable Published Jobs with `publish_end` before now.\n        jobs = Job.objects.filter(status=Job.PUBLISHED, publish_end__lte=now)\n        count_publication_end = jobs.count()\n        count_total_completed += count_publication_end\n\n        for job in jobs:\n            job.change_status(\n                status=Job.COMPLETED,\n                user=user,\n                reason='Publication end date reached.',\n            )\n\n        # Disable Jobs that reached Impression, Click or Block limits.\n        count_limit = {}\n        for limit in ['impressions', 'clicks', 'blocks']:\n            jobs = (Job.objects\n                    .filter(status=Job.PUBLISHED)\n                    .exclude(**{f'limit_{limit}': 0})\n                    .filter(**{f'limit_{limit}__lte': F(f'metric_{limit}')}))\n            for job in jobs:\n                job.change_status(\n                    status=Job.COMPLETED,\n                    user=user,\n                    reason=f'Limit reached: {limit}.',\n                )\n\n            count_limit[limit] = jobs.count()\n            count_total_completed += count_limit[limit]\n\n        # Disable Jobs that have Impression, Click or Block limits but don't\n        # have metrics data for at least 24h. This is to handle cases where the\n        # Metrics Pipeline is broken.\n        yesterday = datetime.utcnow() - timedelta(days=1)\n        jobs = (Job.objects\n                .filter(status=Job.PUBLISHED)\n                .exclude(limit_impressions=0, limit_clicks=0, limit_blocks=0)\n                .filter(metric_last_update__lt=yesterday))\n        for job in jobs:\n            job.change_status(\n                status=Job.COMPLETED,\n                user=user,\n                reason=f'Premature termination due to missing metrics.',\n            )\n        count_premature_termination = jobs.count()\n        count_total_completed += count_premature_termination\n\n        count_running = Job.objects.filter(status=Job.PUBLISHED).count()\n\n        self.stdout.write(\n            f'Jobs Published: {count_published}\\n'\n            f'Jobs Completed: {count_total_completed}\\n'\n            f'  - Reached Publication End Date: {count_publication_end}\\n'\n            f'  - Reached Impressions Limit: {count_limit[\"impressions\"]}\\n'\n            f'  - Reached Clicks Limit: {count_limit[\"clicks\"]}\\n'\n            f'  - Reached Blocks Limit: {count_limit[\"blocks\"]}\\n'\n            f'  - Premature Termination due to missing metrics: {count_premature_termination}\\n'\n            f'Total Jobs Running: {count_running}\\n'\n        )\n", "path": "snippets/base/management/commands/update_jobs.py"}]}