prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  ImageView Example Crashes when Image Not Found
  ## Expected Behavior
  <!--- If you're describing a bug, tell us what you expect to happen. -->
  The image view example to render
  If the imageview widget does not find an image file, it should print a warning instead of crashing.
  Also, test coverage shows 100% for imageview widget `toga/widgets/imageview.py`, consider adding a test case for image not found.
  
  <!--- If you're requesting a new feature, tell us why you'd like this feature. -->
  
  ## Current Behavior
  <!--- If you're describing a bug, what currently happens? -->
  ```
  (venv) robert@robert-VirtualBox:~/staging/toga/examples/imageview$ python -m imageview
  [GTK+] Not implemented: Widget.set_hidden()
  resources/brutus.png
  [GTK+] Not implemented: Widget.set_hidden()
  Traceback (most recent call last):
    File "/home/robert/staging/toga/src/gtk/toga_gtk/app.py", line 67, in startup
      self.interface.startup()
    File "/home/robert/staging/toga/examples/imageview/imageview/app.py", line 19, in startup
      imageview_from_path = toga.ImageView(image_from_path)
    File "/home/robert/staging/toga/src/core/toga/widgets/imageview.py", line 23, in __init__
      self.image = image
    File "/home/robert/staging/toga/src/core/toga/widgets/imageview.py", line 33, in image
      self._impl.set_image(self._image)
    File "/home/robert/staging/toga/src/gtk/toga_gtk/widgets/imageview.py", line 33, in set_image
      self._original_pixbuf = GdkPixbuf.Pixbuf.new_from_file(os.path.join(toga.App.app_dir, self.image.path))
  GLib.Error: g-file-error-quark: Failed to open file '/home/robert/staging/toga/examples/imageview/imageview/resources/brutus.png': No such file or directory (4)
  ^C
  ```
  I have my local checkout of toga installed the following and seems to have the new location of brutus.png from 2d95b16 (#521) 
  pip install -e src/core
  pip install -e src/dummy
  pip install -e src/gtk
  
  ```
  (venv) robert@robert-VirtualBox:~/staging/toga/examples/imageview$ ls -la /home/robert/staging/toga/examples/imageview/imageview/resources/brutus.png
  ls: cannot access '/home/robert/staging/toga/examples/imageview/imageview/resources/brutus.png': No such file or directory
  (venv) robert@robert-VirtualBox:~/staging/toga/examples/imageview$ ls -la /home/robert/staging/toga/examples/imageview/resources/brutus.png
  -rw-r--r-- 1 robert robert 5469 May 28 07:26 /home/robert/staging/toga/examples/imageview/resources/brutus.png
  (venv) robert@robert-VirtualBox:~/staging/toga/examples/imageview$ 
  ```
  ## Steps to reproduce
  <!--- Provide a set of steps describing how to reproduce this bug. If you have a live example, provide the link below -->
  1.Setup Linux environment following instructions here:
  https://toga.readthedocs.io/en/latest/how-to/contribute.html
  
  2. cd imageview
  
  3. python -m imageview
  
  ## Your Environment
  <!--- Provide details on your current environment you found the bug in -->
  
  * Python Version (list the specific version number)
  Python 3.6.5
  
  * Operating System and Version (select from the following and list the specific version number; if your OS is not listed, list that as well)
  
    - [ ] macOS - version: 
    - [ x] Linux - distro:   - version: Ubuntu_18_04
    - [ ] Windows - version:
    - [ ] Other - name:  - version:
  
  * Toga Target (the type of app you are trying to generate)
   
    - [ ] android
    - [ ] cocoa
    - [ ] django 
    - [x ] gtk
    - [ ] iOS
    - [ ] tvOS
    - [ ] watchOS
    - [ ] winforms 
    - [ ] win32
    - [ ] Other (please specify)
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `src/gtk/toga_gtk/widgets/imageview.py`
  Content:
  ```
  1 import os
  2 from urllib.request import Request, urlopen
  3 
  4 from gi.repository import GdkPixbuf, Gio, Gtk
  5 
  6 import toga
  7 
  8 from .base import Widget
  9 
  10 
  11 class ImageView(Widget):
  12 
  13     def create(self):
  14         self.native = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
  15         self._image = Gtk.Image()
  16         self.native.add(self._image)
  17         self.native.interface = self.interface
  18 
  19     def get_image(self):
  20         return self.image
  21 
  22     def set_image(self, image):
  23         self.image = image
  24 
  25         if self.image.path.startswith(('http://', 'https://')):
  26             request = Request(self.image.path, headers={'User-Agent': ''})
  27             with urlopen(request) as result:
  28                 input_stream = Gio.MemoryInputStream.new_from_data(result.read(), None)
  29                 self._original_pixbuf = GdkPixbuf.Pixbuf.new_from_stream(input_stream, None)
  30         elif os.path.isabs(self.image.path):
  31             self._original_pixbuf = GdkPixbuf.Pixbuf.new_from_file(self.image.path)
  32         else:
  33             self._original_pixbuf = GdkPixbuf.Pixbuf.new_from_file(os.path.join(toga.App.app_dir, self.image.path))
  34 
  35         self.rehint()
  36 
  37     def rehint(self):
  38         height, width = self._resize_max(
  39                 original_height=self._original_pixbuf.get_height(),
  40                 original_width=self._original_pixbuf.get_width(),
  41                 max_height=self.native.get_allocated_height(),
  42                 max_width=self.native.get_allocated_width())
  43 
  44         pixbuf = self._original_pixbuf.scale_simple(width, height, GdkPixbuf.InterpType.BILINEAR)
  45         self._image.set_from_pixbuf(pixbuf)
  46 
  47     @staticmethod
  48     def _resize_max(original_height, original_width, max_height, max_width):
  49 
  50         # Check to make sure all dimensions have valid sizes
  51         if min(original_height, original_width, max_height, max_width) <= 0:
  52             return 1, 1
  53 
  54         width_ratio = max_width/original_width
  55         height_ratio = max_height/original_height
  56 
  57         height = original_height * width_ratio
  58         if height <= max_height:
  59             width = original_width * width_ratio
  60         else:
  61             height = original_height * height_ratio
  62             width = original_width * height_ratio
  63 
  64         return int(height), int(width)
  65
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/src/gtk/toga_gtk/widgets/imageview.py b/src/gtk/toga_gtk/widgets/imageview.py
  --- a/src/gtk/toga_gtk/widgets/imageview.py
  +++ b/src/gtk/toga_gtk/widgets/imageview.py
  @@ -27,11 +27,11 @@
               with urlopen(request) as result:
                   input_stream = Gio.MemoryInputStream.new_from_data(result.read(), None)
                   self._original_pixbuf = GdkPixbuf.Pixbuf.new_from_stream(input_stream, None)
  -        elif os.path.isabs(self.image.path):
  -            self._original_pixbuf = GdkPixbuf.Pixbuf.new_from_file(self.image.path)
  +        full_image_path = self.image.path if os.path.isabs(self.image.path) else os.path.join(toga.App.app_dir, self.image.path)
  +        if os.path.isfile(full_image_path):
  +            self._original_pixbuf = GdkPixbuf.Pixbuf.new_from_file
           else:
  -            self._original_pixbuf = GdkPixbuf.Pixbuf.new_from_file(os.path.join(toga.App.app_dir, self.image.path))
  -
  +            raise ValueError("No image file available at ", path)
           self.rehint()
   
       def rehint(self):
  
verification_info: {"golden_diff": "diff --git a/src/gtk/toga_gtk/widgets/imageview.py b/src/gtk/toga_gtk/widgets/imageview.py\n--- a/src/gtk/toga_gtk/widgets/imageview.py\n+++ b/src/gtk/toga_gtk/widgets/imageview.py\n@@ -27,11 +27,11 @@\n             with urlopen(request) as result:\n                 input_stream = Gio.MemoryInputStream.new_from_data(result.read(), None)\n                 self._original_pixbuf = GdkPixbuf.Pixbuf.new_from_stream(input_stream, None)\n-        elif os.path.isabs(self.image.path):\n-            self._original_pixbuf = GdkPixbuf.Pixbuf.new_from_file(self.image.path)\n+        full_image_path = self.image.path if os.path.isabs(self.image.path) else os.path.join(toga.App.app_dir, self.image.path)\n+        if os.path.isfile(full_image_path):\n+            self._original_pixbuf = GdkPixbuf.Pixbuf.new_from_file\n         else:\n-            self._original_pixbuf = GdkPixbuf.Pixbuf.new_from_file(os.path.join(toga.App.app_dir, self.image.path))\n-\n+            raise ValueError(\"No image file available at \", path)\n         self.rehint()\n \n     def rehint(self):\n", "issue": "ImageView Example Crashes when Image Not Found\n## Expected Behavior\r\n<!--- If you're describing a bug, tell us what you expect to happen. -->\r\nThe image view example to render\r\nIf the imageview widget does not find an image file, it should print a warning instead of crashing.\r\nAlso, test coverage shows 100% for imageview widget `toga/widgets/imageview.py`, consider adding a test case for image not found.\r\n\r\n<!--- If you're requesting a new feature, tell us why you'd like this feature. -->\r\n\r\n## Current Behavior\r\n<!--- If you're describing a bug, what currently happens? -->\r\n```\r\n(venv) robert@robert-VirtualBox:~/staging/toga/examples/imageview$ python -m imageview\r\n[GTK+] Not implemented: Widget.set_hidden()\r\nresources/brutus.png\r\n[GTK+] Not implemented: Widget.set_hidden()\r\nTraceback (most recent call last):\r\n  File \"/home/robert/staging/toga/src/gtk/toga_gtk/app.py\", line 67, in startup\r\n    self.interface.startup()\r\n  File \"/home/robert/staging/toga/examples/imageview/imageview/app.py\", line 19, in startup\r\n    imageview_from_path = toga.ImageView(image_from_path)\r\n  File \"/home/robert/staging/toga/src/core/toga/widgets/imageview.py\", line 23, in __init__\r\n    self.image = image\r\n  File \"/home/robert/staging/toga/src/core/toga/widgets/imageview.py\", line 33, in image\r\n    self._impl.set_image(self._image)\r\n  File \"/home/robert/staging/toga/src/gtk/toga_gtk/widgets/imageview.py\", line 33, in set_image\r\n    self._original_pixbuf = GdkPixbuf.Pixbuf.new_from_file(os.path.join(toga.App.app_dir, self.image.path))\r\nGLib.Error: g-file-error-quark: Failed to open file '/home/robert/staging/toga/examples/imageview/imageview/resources/brutus.png': No such file or directory (4)\r\n^C\r\n```\r\nI have my local checkout of toga installed the following and seems to have the new location of brutus.png from 2d95b16 (#521) \r\npip install -e src/core\r\npip install -e src/dummy\r\npip install -e src/gtk\r\n\r\n```\r\n(venv) robert@robert-VirtualBox:~/staging/toga/examples/imageview$ ls -la /home/robert/staging/toga/examples/imageview/imageview/resources/brutus.png\r\nls: cannot access '/home/robert/staging/toga/examples/imageview/imageview/resources/brutus.png': No such file or directory\r\n(venv) robert@robert-VirtualBox:~/staging/toga/examples/imageview$ ls -la /home/robert/staging/toga/examples/imageview/resources/brutus.png\r\n-rw-r--r-- 1 robert robert 5469 May 28 07:26 /home/robert/staging/toga/examples/imageview/resources/brutus.png\r\n(venv) robert@robert-VirtualBox:~/staging/toga/examples/imageview$ \r\n```\r\n## Steps to reproduce\r\n<!--- Provide a set of steps describing how to reproduce this bug. If you have a live example, provide the link below -->\r\n1.Setup Linux environment following instructions here:\r\nhttps://toga.readthedocs.io/en/latest/how-to/contribute.html\r\n\r\n2. cd imageview\r\n\r\n3. python -m imageview\r\n\r\n## Your Environment\r\n<!--- Provide details on your current environment you found the bug in -->\r\n\r\n* Python Version (list the specific version number)\r\nPython 3.6.5\r\n\r\n* Operating System and Version (select from the following and list the specific version number; if your OS is not listed, list that as well)\r\n\r\n  - [ ] macOS - version: \r\n  - [ x] Linux - distro:   - version: Ubuntu_18_04\r\n  - [ ] Windows - version:\r\n  - [ ] Other - name:  - version:\r\n\r\n* Toga Target (the type of app you are trying to generate)\r\n \r\n  - [ ] android\r\n  - [ ] cocoa\r\n  - [ ] django \r\n  - [x ] gtk\r\n  - [ ] iOS\r\n  - [ ] tvOS\r\n  - [ ] watchOS\r\n  - [ ] winforms \r\n  - [ ] win32\r\n  - [ ] Other (please specify)\r\n\n", "before_files": [{"content": "import os\nfrom urllib.request import Request, urlopen\n\nfrom gi.repository import GdkPixbuf, Gio, Gtk\n\nimport toga\n\nfrom .base import Widget\n\n\nclass ImageView(Widget):\n\n    def create(self):\n        self.native = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)\n        self._image = Gtk.Image()\n        self.native.add(self._image)\n        self.native.interface = self.interface\n\n    def get_image(self):\n        return self.image\n\n    def set_image(self, image):\n        self.image = image\n\n        if self.image.path.startswith(('http://', 'https://')):\n            request = Request(self.image.path, headers={'User-Agent': ''})\n            with urlopen(request) as result:\n                input_stream = Gio.MemoryInputStream.new_from_data(result.read(), None)\n                self._original_pixbuf = GdkPixbuf.Pixbuf.new_from_stream(input_stream, None)\n        elif os.path.isabs(self.image.path):\n            self._original_pixbuf = GdkPixbuf.Pixbuf.new_from_file(self.image.path)\n        else:\n            self._original_pixbuf = GdkPixbuf.Pixbuf.new_from_file(os.path.join(toga.App.app_dir, self.image.path))\n\n        self.rehint()\n\n    def rehint(self):\n        height, width = self._resize_max(\n                original_height=self._original_pixbuf.get_height(),\n                original_width=self._original_pixbuf.get_width(),\n                max_height=self.native.get_allocated_height(),\n                max_width=self.native.get_allocated_width())\n\n        pixbuf = self._original_pixbuf.scale_simple(width, height, GdkPixbuf.InterpType.BILINEAR)\n        self._image.set_from_pixbuf(pixbuf)\n\n    @staticmethod\n    def _resize_max(original_height, original_width, max_height, max_width):\n\n        # Check to make sure all dimensions have valid sizes\n        if min(original_height, original_width, max_height, max_width) <= 0:\n            return 1, 1\n\n        width_ratio = max_width/original_width\n        height_ratio = max_height/original_height\n\n        height = original_height * width_ratio\n        if height <= max_height:\n            width = original_width * width_ratio\n        else:\n            height = original_height * height_ratio\n            width = original_width * height_ratio\n\n        return int(height), int(width)\n", "path": "src/gtk/toga_gtk/widgets/imageview.py"}], "after_files": [{"content": "import os\nfrom urllib.request import Request, urlopen\n\nfrom gi.repository import GdkPixbuf, Gio, Gtk\n\nimport toga\n\nfrom .base import Widget\n\n\nclass ImageView(Widget):\n\n    def create(self):\n        self.native = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)\n        self._image = Gtk.Image()\n        self.native.add(self._image)\n        self.native.interface = self.interface\n\n    def get_image(self):\n        return self.image\n\n    def set_image(self, image):\n        self.image = image\n\n        if self.image.path.startswith(('http://', 'https://')):\n            request = Request(self.image.path, headers={'User-Agent': ''})\n            with urlopen(request) as result:\n                input_stream = Gio.MemoryInputStream.new_from_data(result.read(), None)\n                self._original_pixbuf = GdkPixbuf.Pixbuf.new_from_stream(input_stream, None)\n        full_image_path = self.image.path if os.path.isabs(self.image.path) else os.path.join(toga.App.app_dir, self.image.path)\n        if os.path.isfile(full_image_path):\n            self._original_pixbuf = GdkPixbuf.Pixbuf.new_from_file\n        else:\n            raise ValueError(\"No image file available at \", path)\n        self.rehint()\n\n    def rehint(self):\n        height, width = self._resize_max(\n                original_height=self._original_pixbuf.get_height(),\n                original_width=self._original_pixbuf.get_width(),\n                max_height=self.native.get_allocated_height(),\n                max_width=self.native.get_allocated_width())\n\n        pixbuf = self._original_pixbuf.scale_simple(width, height, GdkPixbuf.InterpType.BILINEAR)\n        self._image.set_from_pixbuf(pixbuf)\n\n    @staticmethod\n    def _resize_max(original_height, original_width, max_height, max_width):\n\n        # Check to make sure all dimensions have valid sizes\n        if min(original_height, original_width, max_height, max_width) <= 0:\n            return 1, 1\n\n        width_ratio = max_width/original_width\n        height_ratio = max_height/original_height\n\n        height = original_height * width_ratio\n        if height <= max_height:\n            width = original_width * width_ratio\n        else:\n            height = original_height * height_ratio\n            width = original_width * height_ratio\n\n        return int(height), int(width)\n", "path": "src/gtk/toga_gtk/widgets/imageview.py"}]}