prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Kodi API has been changed in v18 (Leia) such that HTTP POST is required
  <!---
  Before opening an issue, verify:
  
  - Is this a feature request? Post it on https://feathub.com/Flexget/Flexget
  - Did you recently upgrade? Look at the Change Log and Upgrade Actions to make sure that you don't need to make any changes to your config https://flexget.com/ChangeLog https://flexget.com/UpgradeActions
  - Are you running FlexGet as a daemon? Stop it completely and then start it again https://flexget.com/CLI/daemon
  - Did you search to see if the issue already exists? https://github.com/Flexget/Flexget/issues
  - Did you fill out the issue template as completely as possible?
  
  The issue template is here because it helps to ensure you submitted all the necessary information the first time, and allows us to more quickly review issues. Please fill it out correctly and do not ignore it, no matter how irrelevant you think it may be. Thanks in advance for your help with this!
  --->
  ### Expected behaviour:
  <!---
  Please don't just say "it doesn't crash" or "it works". Explain what the expected result is.
  --->
  Updates should work
  ### Actual behaviour:
  Error message: `JSONRPC failed. Error -32099: Bad client permission`
  ### Steps to reproduce:
  - Step 1: Call a kodi library scan from a task
  
  #### Config:
  ```
  kodi_library:
    action: scan
    category: video
    url: http://192.168.1.214
    port: 80
  ```
  
  ### Details
  The kodi API has been changed in v18 Leia and up. In the old API, all requests were HTTP GET (even API calls that update/mutate state). They've finally updated the API to require HTTP POST for updates, but they've completely failed to update the API version or even provide sensible error messages.
  
  https://forum.kodi.tv/showthread.php?tid=324598
  https://discuss.flexget.com/t/kodi-plugin-not-working-on-kodi-18/4196
  
  **NOTE**: I no longer use Kodi, so I'm simply creating an issue based on a forum post to keep track of the issue in case other users begin to experience it.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `flexget/plugins/services/kodi_library.py`
  Content:
  ```
  1 from __future__ import unicode_literals, division, absolute_import
  2 from builtins import *  # noqa pylint: disable=unused-import, redefined-builtin
  3 
  4 import logging
  5 import json
  6 
  7 from flexget import plugin
  8 from flexget.event import event
  9 from flexget.utils.requests import RequestException
  10 
  11 log = logging.getLogger('kodi_library')
  12 
  13 JSON_URI = '/jsonrpc'
  14 
  15 
  16 class KodiLibrary(object):
  17     schema = {
  18         'type': 'object',
  19         'properties': {
  20             'action': {'type': 'string', 'enum': ['clean', 'scan']},
  21             'category': {'type': 'string', 'enum': ['audio', 'video']},
  22             'url': {'type': 'string', 'format': 'url'},
  23             'port': {'type': 'integer', 'default': 8080},
  24             'username': {'type': 'string'},
  25             'password': {'type': 'string'},
  26             'only_on_accepted': {'type': 'boolean', 'default': True}
  27         },
  28         'required': ['url', 'action', 'category'],
  29         'additionalProperties': False,
  30     }
  31 
  32     @plugin.priority(-255)
  33     def on_task_exit(self, task, config):
  34         if task.accepted or not config['only_on_accepted']:
  35             # make the url without trailing slash
  36             base_url = config['url'][:-1] if config['url'].endswith('/') else config['url']
  37             base_url += ':{0}'.format(config['port'])
  38 
  39             url = base_url + JSON_URI
  40             # create the params
  41             json_params = {"id": 1, "jsonrpc": "2.0",
  42                            'method': '{category}Library.{action}'.format(category=config['category'].title(),
  43                                                                          action=config['action'].title())}
  44             params = {'request': json.dumps(json_params)}
  45             log.debug('Sending request params %s', params)
  46 
  47             try:
  48                 r = task.requests.get(url, params=params, auth=(config.get('username'), config.get('password'))).json()
  49                 if r.get('result') == 'OK':
  50                     log.info('Successfully sent a %s request for the %s library', config['action'], config['category'])
  51                 else:
  52                     if r.get('error'):
  53                         log.error('Kodi JSONRPC failed. Error %s: %s', r['error']['code'], r['error']['message'])
  54                     else:
  55                         # this should never happen as Kodi say they follow the JSON-RPC 2.0 spec
  56                         log.debug('Received error response %s', json.dumps(r))
  57                         log.error('Kodi JSONRPC failed with unrecognized message: %s', json.dumps(r))
  58             except RequestException as e:
  59                 raise plugin.PluginError('Failed to send request to Kodi: %s' % e.args[0])
  60         else:
  61             log.info('No entries were accepted. No request is sent.')
  62 
  63 
  64 @event('plugin.register')
  65 def register_plugin():
  66     plugin.register(KodiLibrary, 'kodi_library', api_ver=2)
  67
  ```
  --- 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/flexget/plugins/services/kodi_library.py b/flexget/plugins/services/kodi_library.py
  --- a/flexget/plugins/services/kodi_library.py
  +++ b/flexget/plugins/services/kodi_library.py
  @@ -38,14 +38,13 @@
   
               url = base_url + JSON_URI
               # create the params
  -            json_params = {"id": 1, "jsonrpc": "2.0",
  -                           'method': '{category}Library.{action}'.format(category=config['category'].title(),
  -                                                                         action=config['action'].title())}
  -            params = {'request': json.dumps(json_params)}
  +            params = {"id": 1, "jsonrpc": "2.0",
  +                      'method': '{category}Library.{action}'.format(category=config['category'].title(),
  +                                                                    action=config['action'].title())}
               log.debug('Sending request params %s', params)
   
               try:
  -                r = task.requests.get(url, params=params, auth=(config.get('username'), config.get('password'))).json()
  +                r = task.requests.post(url, json=params, auth=(config.get('username'), config.get('password'))).json()
                   if r.get('result') == 'OK':
                       log.info('Successfully sent a %s request for the %s library', config['action'], config['category'])
                   else:
  
verification_info: {"golden_diff": "diff --git a/flexget/plugins/services/kodi_library.py b/flexget/plugins/services/kodi_library.py\n--- a/flexget/plugins/services/kodi_library.py\n+++ b/flexget/plugins/services/kodi_library.py\n@@ -38,14 +38,13 @@\n \n             url = base_url + JSON_URI\n             # create the params\n-            json_params = {\"id\": 1, \"jsonrpc\": \"2.0\",\n-                           'method': '{category}Library.{action}'.format(category=config['category'].title(),\n-                                                                         action=config['action'].title())}\n-            params = {'request': json.dumps(json_params)}\n+            params = {\"id\": 1, \"jsonrpc\": \"2.0\",\n+                      'method': '{category}Library.{action}'.format(category=config['category'].title(),\n+                                                                    action=config['action'].title())}\n             log.debug('Sending request params %s', params)\n \n             try:\n-                r = task.requests.get(url, params=params, auth=(config.get('username'), config.get('password'))).json()\n+                r = task.requests.post(url, json=params, auth=(config.get('username'), config.get('password'))).json()\n                 if r.get('result') == 'OK':\n                     log.info('Successfully sent a %s request for the %s library', config['action'], config['category'])\n                 else:\n", "issue": "Kodi API has been changed in v18 (Leia) such that HTTP POST is required\n<!---\r\nBefore opening an issue, verify:\r\n\r\n- Is this a feature request? Post it on https://feathub.com/Flexget/Flexget\r\n- Did you recently upgrade? Look at the Change Log and Upgrade Actions to make sure that you don't need to make any changes to your config https://flexget.com/ChangeLog https://flexget.com/UpgradeActions\r\n- Are you running FlexGet as a daemon? Stop it completely and then start it again https://flexget.com/CLI/daemon\r\n- Did you search to see if the issue already exists? https://github.com/Flexget/Flexget/issues\r\n- Did you fill out the issue template as completely as possible?\r\n\r\nThe issue template is here because it helps to ensure you submitted all the necessary information the first time, and allows us to more quickly review issues. Please fill it out correctly and do not ignore it, no matter how irrelevant you think it may be. Thanks in advance for your help with this!\r\n--->\r\n### Expected behaviour:\r\n<!---\r\nPlease don't just say \"it doesn't crash\" or \"it works\". Explain what the expected result is.\r\n--->\r\nUpdates should work\r\n### Actual behaviour:\r\nError message: `JSONRPC failed. Error -32099: Bad client permission`\r\n### Steps to reproduce:\r\n- Step 1: Call a kodi library scan from a task\r\n\r\n#### Config:\r\n```\r\nkodi_library:\r\n  action: scan\r\n  category: video\r\n  url: http://192.168.1.214\r\n  port: 80\r\n```\r\n\r\n### Details\r\nThe kodi API has been changed in v18 Leia and up. In the old API, all requests were HTTP GET (even API calls that update/mutate state). They've finally updated the API to require HTTP POST for updates, but they've completely failed to update the API version or even provide sensible error messages.\r\n\r\nhttps://forum.kodi.tv/showthread.php?tid=324598\r\nhttps://discuss.flexget.com/t/kodi-plugin-not-working-on-kodi-18/4196\r\n\r\n**NOTE**: I no longer use Kodi, so I'm simply creating an issue based on a forum post to keep track of the issue in case other users begin to experience it.\n", "before_files": [{"content": "from __future__ import unicode_literals, division, absolute_import\nfrom builtins import *  # noqa pylint: disable=unused-import, redefined-builtin\n\nimport logging\nimport json\n\nfrom flexget import plugin\nfrom flexget.event import event\nfrom flexget.utils.requests import RequestException\n\nlog = logging.getLogger('kodi_library')\n\nJSON_URI = '/jsonrpc'\n\n\nclass KodiLibrary(object):\n    schema = {\n        'type': 'object',\n        'properties': {\n            'action': {'type': 'string', 'enum': ['clean', 'scan']},\n            'category': {'type': 'string', 'enum': ['audio', 'video']},\n            'url': {'type': 'string', 'format': 'url'},\n            'port': {'type': 'integer', 'default': 8080},\n            'username': {'type': 'string'},\n            'password': {'type': 'string'},\n            'only_on_accepted': {'type': 'boolean', 'default': True}\n        },\n        'required': ['url', 'action', 'category'],\n        'additionalProperties': False,\n    }\n\n    @plugin.priority(-255)\n    def on_task_exit(self, task, config):\n        if task.accepted or not config['only_on_accepted']:\n            # make the url without trailing slash\n            base_url = config['url'][:-1] if config['url'].endswith('/') else config['url']\n            base_url += ':{0}'.format(config['port'])\n\n            url = base_url + JSON_URI\n            # create the params\n            json_params = {\"id\": 1, \"jsonrpc\": \"2.0\",\n                           'method': '{category}Library.{action}'.format(category=config['category'].title(),\n                                                                         action=config['action'].title())}\n            params = {'request': json.dumps(json_params)}\n            log.debug('Sending request params %s', params)\n\n            try:\n                r = task.requests.get(url, params=params, auth=(config.get('username'), config.get('password'))).json()\n                if r.get('result') == 'OK':\n                    log.info('Successfully sent a %s request for the %s library', config['action'], config['category'])\n                else:\n                    if r.get('error'):\n                        log.error('Kodi JSONRPC failed. Error %s: %s', r['error']['code'], r['error']['message'])\n                    else:\n                        # this should never happen as Kodi say they follow the JSON-RPC 2.0 spec\n                        log.debug('Received error response %s', json.dumps(r))\n                        log.error('Kodi JSONRPC failed with unrecognized message: %s', json.dumps(r))\n            except RequestException as e:\n                raise plugin.PluginError('Failed to send request to Kodi: %s' % e.args[0])\n        else:\n            log.info('No entries were accepted. No request is sent.')\n\n\n@event('plugin.register')\ndef register_plugin():\n    plugin.register(KodiLibrary, 'kodi_library', api_ver=2)\n", "path": "flexget/plugins/services/kodi_library.py"}], "after_files": [{"content": "from __future__ import unicode_literals, division, absolute_import\nfrom builtins import *  # noqa pylint: disable=unused-import, redefined-builtin\n\nimport logging\nimport json\n\nfrom flexget import plugin\nfrom flexget.event import event\nfrom flexget.utils.requests import RequestException\n\nlog = logging.getLogger('kodi_library')\n\nJSON_URI = '/jsonrpc'\n\n\nclass KodiLibrary(object):\n    schema = {\n        'type': 'object',\n        'properties': {\n            'action': {'type': 'string', 'enum': ['clean', 'scan']},\n            'category': {'type': 'string', 'enum': ['audio', 'video']},\n            'url': {'type': 'string', 'format': 'url'},\n            'port': {'type': 'integer', 'default': 8080},\n            'username': {'type': 'string'},\n            'password': {'type': 'string'},\n            'only_on_accepted': {'type': 'boolean', 'default': True}\n        },\n        'required': ['url', 'action', 'category'],\n        'additionalProperties': False,\n    }\n\n    @plugin.priority(-255)\n    def on_task_exit(self, task, config):\n        if task.accepted or not config['only_on_accepted']:\n            # make the url without trailing slash\n            base_url = config['url'][:-1] if config['url'].endswith('/') else config['url']\n            base_url += ':{0}'.format(config['port'])\n\n            url = base_url + JSON_URI\n            # create the params\n            params = {\"id\": 1, \"jsonrpc\": \"2.0\",\n                      'method': '{category}Library.{action}'.format(category=config['category'].title(),\n                                                                    action=config['action'].title())}\n            log.debug('Sending request params %s', params)\n\n            try:\n                r = task.requests.post(url, json=params, auth=(config.get('username'), config.get('password'))).json()\n                if r.get('result') == 'OK':\n                    log.info('Successfully sent a %s request for the %s library', config['action'], config['category'])\n                else:\n                    if r.get('error'):\n                        log.error('Kodi JSONRPC failed. Error %s: %s', r['error']['code'], r['error']['message'])\n                    else:\n                        # this should never happen as Kodi say they follow the JSON-RPC 2.0 spec\n                        log.debug('Received error response %s', json.dumps(r))\n                        log.error('Kodi JSONRPC failed with unrecognized message: %s', json.dumps(r))\n            except RequestException as e:\n                raise plugin.PluginError('Failed to send request to Kodi: %s' % e.args[0])\n        else:\n            log.info('No entries were accepted. No request is sent.')\n\n\n@event('plugin.register')\ndef register_plugin():\n    plugin.register(KodiLibrary, 'kodi_library', api_ver=2)\n", "path": "flexget/plugins/services/kodi_library.py"}]}