prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Can't submit new team after changing image.
  Can't believe this didn't come up yet. I noticed this while exploring [create.json.spt](https://github.com/gratipay/gratipay.com/blob/master/www/teams/create.json.spt) which inspires the new [edit.json.spt](https://github.com/gratipay/gratipay.com/pull/3923/files#diff-6). 
  
  The way it is written right now, we first write the team details to the db (with a unique generated `slug`) and _then_ try to save the team image. If a user uploads an image of size  > 1Mb or an image which is not a jpg or png, the team creation won't be successful as far as the user is concerned and he'll resubmit the team application form with an appropriate image. But when he does again, we would have already created a slug for that team name resulting in a misleading message of `Sorry, there is already a team using <slug>.` when in fact the `slug` was created because we wrote the team details to the db first.
  
  
  </issue>
  <code>
  [start of gratipay/utils/images.py]
  1 import zipfile
  2 from cStringIO import StringIO
  3 
  4 import requests
  5 
  6 def imgize(image, image_type):
  7     large = None
  8     small = None
  9     crops = requests.post( 'http://gip.rocks/v1',
  10                            data=image,
  11                            headers={'Content-Type': image_type}
  12             )
  13     if crops.status_code == 200:
  14         zf = zipfile.ZipFile(StringIO(crops.content))
  15         large = zf.open('160').read()
  16         small = zf.open('48').read()
  17 
  18     return crops.status_code, large, small
  [end of gratipay/utils/images.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/gratipay/utils/images.py b/gratipay/utils/images.py
  --- a/gratipay/utils/images.py
  +++ b/gratipay/utils/images.py
  @@ -8,11 +8,22 @@
       small = None
       crops = requests.post( 'http://gip.rocks/v1',
                              data=image,
  -                           headers={'Content-Type': image_type}
  -            )
  +                           headers={'Content-Type': image_type})
  +
       if crops.status_code == 200:
           zf = zipfile.ZipFile(StringIO(crops.content))
           large = zf.open('160').read()
           small = zf.open('48').read()
  +        return large, small
  +    elif crops.status_code == 413:
  +        raise ImageTooLarge
  +    elif crops.status_code == 415:
  +        raise InvalidImageType
  +    else:
  +        raise UnknownImageError
  +
  +class ImageTooLarge(Exception): pass
  +
  +class InvalidImageType(Exception): pass
   
  -    return crops.status_code, large, small
  \ No newline at end of file
  +class UnknownImageError(Exception): pass
  
verification_info: {"golden_diff": "diff --git a/gratipay/utils/images.py b/gratipay/utils/images.py\n--- a/gratipay/utils/images.py\n+++ b/gratipay/utils/images.py\n@@ -8,11 +8,22 @@\n     small = None\n     crops = requests.post( 'http://gip.rocks/v1',\n                            data=image,\n-                           headers={'Content-Type': image_type}\n-            )\n+                           headers={'Content-Type': image_type})\n+\n     if crops.status_code == 200:\n         zf = zipfile.ZipFile(StringIO(crops.content))\n         large = zf.open('160').read()\n         small = zf.open('48').read()\n+        return large, small\n+    elif crops.status_code == 413:\n+        raise ImageTooLarge\n+    elif crops.status_code == 415:\n+        raise InvalidImageType\n+    else:\n+        raise UnknownImageError\n+\n+class ImageTooLarge(Exception): pass\n+\n+class InvalidImageType(Exception): pass\n \n-    return crops.status_code, large, small\n\\ No newline at end of file\n+class UnknownImageError(Exception): pass\n", "issue": "Can't submit new team after changing image.\nCan't believe this didn't come up yet. I noticed this while exploring [create.json.spt](https://github.com/gratipay/gratipay.com/blob/master/www/teams/create.json.spt) which inspires the new [edit.json.spt](https://github.com/gratipay/gratipay.com/pull/3923/files#diff-6). \n\nThe way it is written right now, we first write the team details to the db (with a unique generated `slug`) and _then_ try to save the team image. If a user uploads an image of size  > 1Mb or an image which is not a jpg or png, the team creation won't be successful as far as the user is concerned and he'll resubmit the team application form with an appropriate image. But when he does again, we would have already created a slug for that team name resulting in a misleading message of `Sorry, there is already a team using <slug>.` when in fact the `slug` was created because we wrote the team details to the db first.\n\n", "before_files": [{"content": "import zipfile\nfrom cStringIO import StringIO\n\nimport requests\n\ndef imgize(image, image_type):\n    large = None\n    small = None\n    crops = requests.post( 'http://gip.rocks/v1',\n                           data=image,\n                           headers={'Content-Type': image_type}\n            )\n    if crops.status_code == 200:\n        zf = zipfile.ZipFile(StringIO(crops.content))\n        large = zf.open('160').read()\n        small = zf.open('48').read()\n\n    return crops.status_code, large, small", "path": "gratipay/utils/images.py"}]}