prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  kodiupdate: support updating multiple Kodi instances
  Pretty straitforward ask, it would be nice if when running beets using the Kodi update client that you could enter multiple clients
  
  syntax would be something to the tune of ...
  
  kodi:
      host: x.x.x.x
      port: 8080
      user: user
      pwd: password
  kodi:
      host: x.x.x.x
      port: 8080
      user: user
      pwd: password
  kodi:
      host: x.x.x.x
      port: 8080
      user: user
      pwd: password
  can this please be implemented
  
  </issue>
  <code>
  [start of beetsplug/kodiupdate.py]
  1 # This file is part of beets.
  2 # Copyright 2017, Pauli Kettunen.
  3 #
  4 # Permission is hereby granted, free of charge, to any person obtaining
  5 # a copy of this software and associated documentation files (the
  6 # "Software"), to deal in the Software without restriction, including
  7 # without limitation the rights to use, copy, modify, merge, publish,
  8 # distribute, sublicense, and/or sell copies of the Software, and to
  9 # permit persons to whom the Software is furnished to do so, subject to
  10 # the following conditions:
  11 #
  12 # The above copyright notice and this permission notice shall be
  13 # included in all copies or substantial portions of the Software.
  14 
  15 """Updates a Kodi library whenever the beets library is changed.
  16 This is based on the Plex Update plugin.
  17 
  18 Put something like the following in your config.yaml to configure:
  19     kodi:
  20         host: localhost
  21         port: 8080
  22         user: user
  23         pwd: secret
  24 """
  25 
  26 import requests
  27 from beets import config
  28 from beets.plugins import BeetsPlugin
  29 
  30 
  31 def update_kodi(host, port, user, password):
  32     """Sends request to the Kodi api to start a library refresh.
  33     """
  34     url = f"http://{host}:{port}/jsonrpc"
  35 
  36     """Content-Type: application/json is mandatory
  37     according to the kodi jsonrpc documentation"""
  38 
  39     headers = {'Content-Type': 'application/json'}
  40 
  41     # Create the payload. Id seems to be mandatory.
  42     payload = {'jsonrpc': '2.0', 'method': 'AudioLibrary.Scan', 'id': 1}
  43     r = requests.post(
  44         url,
  45         auth=(user, password),
  46         json=payload,
  47         headers=headers)
  48 
  49     return r
  50 
  51 
  52 class KodiUpdate(BeetsPlugin):
  53     def __init__(self):
  54         super().__init__()
  55 
  56         # Adding defaults.
  57         config['kodi'].add({
  58             'host': 'localhost',
  59             'port': 8080,
  60             'user': 'kodi',
  61             'pwd': 'kodi'})
  62 
  63         config['kodi']['pwd'].redact = True
  64         self.register_listener('database_change', self.listen_for_db_change)
  65 
  66     def listen_for_db_change(self, lib, model):
  67         """Listens for beets db change and register the update"""
  68         self.register_listener('cli_exit', self.update)
  69 
  70     def update(self, lib):
  71         """When the client exists try to send refresh request to Kodi server.
  72         """
  73         self._log.info('Requesting a Kodi library update...')
  74 
  75         # Try to send update request.
  76         try:
  77             r = update_kodi(
  78                 config['kodi']['host'].get(),
  79                 config['kodi']['port'].get(),
  80                 config['kodi']['user'].get(),
  81                 config['kodi']['pwd'].get())
  82             r.raise_for_status()
  83 
  84         except requests.exceptions.RequestException as e:
  85             self._log.warning('Kodi update failed: {0}',
  86                               str(e))
  87             return
  88 
  89         json = r.json()
  90         if json.get('result') != 'OK':
  91             self._log.warning('Kodi update failed: JSON response was {0!r}',
  92                               json)
  93             return
  94 
  95         self._log.info('Kodi update triggered')
  96
  [end of beetsplug/kodiupdate.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/beetsplug/kodiupdate.py b/beetsplug/kodiupdate.py
  --- a/beetsplug/kodiupdate.py
  +++ b/beetsplug/kodiupdate.py
  @@ -54,11 +54,12 @@
           super().__init__()
   
           # Adding defaults.
  -        config['kodi'].add({
  +        config['kodi'].add([{
               'host': 'localhost',
               'port': 8080,
               'user': 'kodi',
  -            'pwd': 'kodi'})
  +            'pwd': 'kodi'
  +        }])
   
           config['kodi']['pwd'].redact = True
           self.register_listener('database_change', self.listen_for_db_change)
  @@ -72,24 +73,34 @@
           """
           self._log.info('Requesting a Kodi library update...')
   
  -        # Try to send update request.
  -        try:
  -            r = update_kodi(
  -                config['kodi']['host'].get(),
  -                config['kodi']['port'].get(),
  -                config['kodi']['user'].get(),
  -                config['kodi']['pwd'].get())
  -            r.raise_for_status()
  -
  -        except requests.exceptions.RequestException as e:
  -            self._log.warning('Kodi update failed: {0}',
  -                              str(e))
  -            return
  -
  -        json = r.json()
  -        if json.get('result') != 'OK':
  -            self._log.warning('Kodi update failed: JSON response was {0!r}',
  -                              json)
  -            return
  -
  -        self._log.info('Kodi update triggered')
  +        kodi = config['kodi'].get()
  +
  +        # Backwards compatibility in case not configured as an array
  +        if not isinstance(kodi, list):
  +            kodi = [kodi]
  +
  +        for instance in kodi:
  +            # Try to send update request.
  +            try:
  +                r = update_kodi(
  +                    instance['host'],
  +                    instance['port'],
  +                    instance['user'],
  +                    instance['pwd']
  +                )
  +                r.raise_for_status()
  +
  +                json = r.json()
  +                if json.get('result') != 'OK':
  +                    self._log.warning(
  +                        'Kodi update failed: JSON response was {0!r}', json
  +                    )
  +                    continue
  +
  +                self._log.info(
  +                    'Kodi update triggered for {0}:{1}',
  +                    instance['host'], instance['port']
  +                )
  +            except requests.exceptions.RequestException as e:
  +                self._log.warning('Kodi update failed: {0}', str(e))
  +                continue
  
verification_info: {"golden_diff": "diff --git a/beetsplug/kodiupdate.py b/beetsplug/kodiupdate.py\n--- a/beetsplug/kodiupdate.py\n+++ b/beetsplug/kodiupdate.py\n@@ -54,11 +54,12 @@\n         super().__init__()\n \n         # Adding defaults.\n-        config['kodi'].add({\n+        config['kodi'].add([{\n             'host': 'localhost',\n             'port': 8080,\n             'user': 'kodi',\n-            'pwd': 'kodi'})\n+            'pwd': 'kodi'\n+        }])\n \n         config['kodi']['pwd'].redact = True\n         self.register_listener('database_change', self.listen_for_db_change)\n@@ -72,24 +73,34 @@\n         \"\"\"\n         self._log.info('Requesting a Kodi library update...')\n \n-        # Try to send update request.\n-        try:\n-            r = update_kodi(\n-                config['kodi']['host'].get(),\n-                config['kodi']['port'].get(),\n-                config['kodi']['user'].get(),\n-                config['kodi']['pwd'].get())\n-            r.raise_for_status()\n-\n-        except requests.exceptions.RequestException as e:\n-            self._log.warning('Kodi update failed: {0}',\n-                              str(e))\n-            return\n-\n-        json = r.json()\n-        if json.get('result') != 'OK':\n-            self._log.warning('Kodi update failed: JSON response was {0!r}',\n-                              json)\n-            return\n-\n-        self._log.info('Kodi update triggered')\n+        kodi = config['kodi'].get()\n+\n+        # Backwards compatibility in case not configured as an array\n+        if not isinstance(kodi, list):\n+            kodi = [kodi]\n+\n+        for instance in kodi:\n+            # Try to send update request.\n+            try:\n+                r = update_kodi(\n+                    instance['host'],\n+                    instance['port'],\n+                    instance['user'],\n+                    instance['pwd']\n+                )\n+                r.raise_for_status()\n+\n+                json = r.json()\n+                if json.get('result') != 'OK':\n+                    self._log.warning(\n+                        'Kodi update failed: JSON response was {0!r}', json\n+                    )\n+                    continue\n+\n+                self._log.info(\n+                    'Kodi update triggered for {0}:{1}',\n+                    instance['host'], instance['port']\n+                )\n+            except requests.exceptions.RequestException as e:\n+                self._log.warning('Kodi update failed: {0}', str(e))\n+                continue\n", "issue": "kodiupdate: support updating multiple Kodi instances\nPretty straitforward ask, it would be nice if when running beets using the Kodi update client that you could enter multiple clients\r\n\r\nsyntax would be something to the tune of ...\r\n\r\nkodi:\r\n    host: x.x.x.x\r\n    port: 8080\r\n    user: user\r\n    pwd: password\r\nkodi:\r\n    host: x.x.x.x\r\n    port: 8080\r\n    user: user\r\n    pwd: password\r\nkodi:\r\n    host: x.x.x.x\r\n    port: 8080\r\n    user: user\r\n    pwd: password\r\ncan this please be implemented\n", "before_files": [{"content": "# This file is part of beets.\n# Copyright 2017, Pauli Kettunen.\n#\n# Permission is hereby granted, free of charge, to any person obtaining\n# a copy of this software and associated documentation files (the\n# \"Software\"), to deal in the Software without restriction, including\n# without limitation the rights to use, copy, modify, merge, publish,\n# distribute, sublicense, and/or sell copies of the Software, and to\n# permit persons to whom the Software is furnished to do so, subject to\n# the following conditions:\n#\n# The above copyright notice and this permission notice shall be\n# included in all copies or substantial portions of the Software.\n\n\"\"\"Updates a Kodi library whenever the beets library is changed.\nThis is based on the Plex Update plugin.\n\nPut something like the following in your config.yaml to configure:\n    kodi:\n        host: localhost\n        port: 8080\n        user: user\n        pwd: secret\n\"\"\"\n\nimport requests\nfrom beets import config\nfrom beets.plugins import BeetsPlugin\n\n\ndef update_kodi(host, port, user, password):\n    \"\"\"Sends request to the Kodi api to start a library refresh.\n    \"\"\"\n    url = f\"http://{host}:{port}/jsonrpc\"\n\n    \"\"\"Content-Type: application/json is mandatory\n    according to the kodi jsonrpc documentation\"\"\"\n\n    headers = {'Content-Type': 'application/json'}\n\n    # Create the payload. Id seems to be mandatory.\n    payload = {'jsonrpc': '2.0', 'method': 'AudioLibrary.Scan', 'id': 1}\n    r = requests.post(\n        url,\n        auth=(user, password),\n        json=payload,\n        headers=headers)\n\n    return r\n\n\nclass KodiUpdate(BeetsPlugin):\n    def __init__(self):\n        super().__init__()\n\n        # Adding defaults.\n        config['kodi'].add({\n            'host': 'localhost',\n            'port': 8080,\n            'user': 'kodi',\n            'pwd': 'kodi'})\n\n        config['kodi']['pwd'].redact = True\n        self.register_listener('database_change', self.listen_for_db_change)\n\n    def listen_for_db_change(self, lib, model):\n        \"\"\"Listens for beets db change and register the update\"\"\"\n        self.register_listener('cli_exit', self.update)\n\n    def update(self, lib):\n        \"\"\"When the client exists try to send refresh request to Kodi server.\n        \"\"\"\n        self._log.info('Requesting a Kodi library update...')\n\n        # Try to send update request.\n        try:\n            r = update_kodi(\n                config['kodi']['host'].get(),\n                config['kodi']['port'].get(),\n                config['kodi']['user'].get(),\n                config['kodi']['pwd'].get())\n            r.raise_for_status()\n\n        except requests.exceptions.RequestException as e:\n            self._log.warning('Kodi update failed: {0}',\n                              str(e))\n            return\n\n        json = r.json()\n        if json.get('result') != 'OK':\n            self._log.warning('Kodi update failed: JSON response was {0!r}',\n                              json)\n            return\n\n        self._log.info('Kodi update triggered')\n", "path": "beetsplug/kodiupdate.py"}]}