prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Update PMS library not working
  Hi,
  
  All boxes from Notifications -> Plex Media server are completed with the correct information (token, user, password, server ip:port) and I`m receiving the blue box with (error trying to update plex).
  What is surprisingly, when using the Test Plex Media Server, the test is ok even if the Token field is empty.
  
  Error received:
  Thread_2 :: [] PLEX: Unauthorized. Please set TOKEN or USERNAME and PASSWORD in Plex settings
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `medusa/server/api/v2/notifications.py`
  Content:
  ```
  1 # coding=utf-8
  2 """Request handler for notifications data."""
  3 from __future__ import unicode_literals
  4 
  5 
  6 import logging
  7 import re
  8 
  9 from medusa import app, notifiers, ui
  10 from medusa.logger.adapters.style import BraceAdapter
  11 from medusa.server.api.v2.base import BaseRequestHandler
  12 from medusa.tv.series import Series, SeriesIdentifier
  13 
  14 log = BraceAdapter(logging.getLogger(__name__))
  15 log.logger.addHandler(logging.NullHandler())
  16 
  17 
  18 class NotificationsHandler(BaseRequestHandler):
  19     """Notifications data request handler."""
  20 
  21     #: resource name
  22     name = 'notifications'
  23     #: identifier
  24     identifier = ('resource', r'\w+')
  25     #: path param
  26     path_param = ('path_param', r'\w+')
  27     #: allowed HTTP methods
  28     allowed_methods = ('GET', 'POST')
  29 
  30     def post(self, resource, path_param=None):
  31         """Post Notifications actions for a specific external source.
  32 
  33         :param resource: a resource name
  34         :param path_param:
  35         :type path_param: str
  36         """
  37         if resource is None:
  38             return self._bad_request('You must provide a notifications resource name')
  39 
  40         available_resources = (
  41             'kodi', 'plexserver', 'plexhome', 'emby', 'nmj', 'nmjv2', 'trakt'
  42         )
  43 
  44         if resource not in available_resources:
  45             return self._bad_request(f"Resource must be one of {', '.join(available_resources)}")
  46 
  47         # Convert 'camelCase' to 'resource_snake_case'
  48         resource_function_name = resource + '_' + re.sub('([A-Z]+)', r'_\1', path_param).lower()
  49         resource_function = getattr(self, resource_function_name, None)
  50 
  51         if resource_function is None:
  52             log.error('Unable to get function "{func}" for resource "{resource}"',
  53                       {'func': resource_function_name, 'resource': path_param})
  54             return self._bad_request('{key} is a invalid resource'.format(key=path_param))
  55 
  56         return resource_function()
  57 
  58     def kodi_update(self):
  59         """Update kodi's show library."""
  60         if app.KODI_UPDATE_ONLYFIRST:
  61             host = app.KODI_HOST[0].strip()
  62         else:
  63             host = ', '.join(app.KODI_HOST)
  64 
  65         if notifiers.kodi_notifier.update_library():
  66             ui.notifications.message(f'Library update command sent to KODI host(s): {host}')
  67         else:
  68             ui.notifications.error(f'Unable to contact one or more KODI host(s): {host}')
  69 
  70         return self._created()
  71 
  72     def emby_update(self):
  73         """Update emby's show library."""
  74         show_slug = self.get_argument('showslug', '')
  75         show = None
  76 
  77         if show_slug:
  78             show_identifier = SeriesIdentifier.from_slug(show_slug)
  79             if not show_identifier:
  80                 return self._bad_request('Invalid show slug')
  81 
  82             show = Series.find_by_identifier(show_identifier)
  83             if not show:
  84                 return self._not_found('Series not found')
  85 
  86         if notifiers.emby_notifier.update_library(show):
  87             ui.notifications.message(f'Library update command sent to Emby host: {app.EMBY_HOST}')
  88         else:
  89             ui.notifications.error(f'Unable to contact Emby host: {app.EMBY_HOST}')
  90 
  91         return self._created()
  92 
  93     def plex_update(self):
  94         """Update plex's show library."""
  95         if None is notifiers.plex_notifier.update_library():
  96             ui.notifications.message(
  97                 'Library update command sent to Plex Media Server host: {host}'.format(host=', '.join(app.PLEX_SERVER_HOST)))
  98         else:
  99             ui.notifications.error('Unable to contact Plex Media Server host: {host}'.format(host=', '.join(app.PLEX_SERVER_HOST)))
  100 
  101         return self._created()
  102
  ```
  --- 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/medusa/server/api/v2/notifications.py b/medusa/server/api/v2/notifications.py
  --- a/medusa/server/api/v2/notifications.py
  +++ b/medusa/server/api/v2/notifications.py
  @@ -38,7 +38,7 @@
               return self._bad_request('You must provide a notifications resource name')
   
           available_resources = (
  -            'kodi', 'plexserver', 'plexhome', 'emby', 'nmj', 'nmjv2', 'trakt'
  +            'kodi', 'plexserver', 'plexhome', 'emby', 'nmj', 'nmjv2', 'trakt', 'plex'
           )
   
           if resource not in available_resources:
  @@ -92,10 +92,10 @@
   
       def plex_update(self):
           """Update plex's show library."""
  -        if None is notifiers.plex_notifier.update_library():
  +        if not notifiers.plex_notifier.update_library():
               ui.notifications.message(
  -                'Library update command sent to Plex Media Server host: {host}'.format(host=', '.join(app.PLEX_SERVER_HOST)))
  +                f"Library update command sent to Plex Media Server host: {', '.join(app.PLEX_SERVER_HOST)}")
           else:
  -            ui.notifications.error('Unable to contact Plex Media Server host: {host}'.format(host=', '.join(app.PLEX_SERVER_HOST)))
  +            ui.notifications.error(f"Unable to contact Plex Media Server host: {', '.join(app.PLEX_SERVER_HOST)}")
   
           return self._created()
  
verification_info: {"golden_diff": "diff --git a/medusa/server/api/v2/notifications.py b/medusa/server/api/v2/notifications.py\n--- a/medusa/server/api/v2/notifications.py\n+++ b/medusa/server/api/v2/notifications.py\n@@ -38,7 +38,7 @@\n             return self._bad_request('You must provide a notifications resource name')\n \n         available_resources = (\n-            'kodi', 'plexserver', 'plexhome', 'emby', 'nmj', 'nmjv2', 'trakt'\n+            'kodi', 'plexserver', 'plexhome', 'emby', 'nmj', 'nmjv2', 'trakt', 'plex'\n         )\n \n         if resource not in available_resources:\n@@ -92,10 +92,10 @@\n \n     def plex_update(self):\n         \"\"\"Update plex's show library.\"\"\"\n-        if None is notifiers.plex_notifier.update_library():\n+        if not notifiers.plex_notifier.update_library():\n             ui.notifications.message(\n-                'Library update command sent to Plex Media Server host: {host}'.format(host=', '.join(app.PLEX_SERVER_HOST)))\n+                f\"Library update command sent to Plex Media Server host: {', '.join(app.PLEX_SERVER_HOST)}\")\n         else:\n-            ui.notifications.error('Unable to contact Plex Media Server host: {host}'.format(host=', '.join(app.PLEX_SERVER_HOST)))\n+            ui.notifications.error(f\"Unable to contact Plex Media Server host: {', '.join(app.PLEX_SERVER_HOST)}\")\n \n         return self._created()\n", "issue": "Update PMS library not working\nHi,\r\n\r\nAll boxes from Notifications -> Plex Media server are completed with the correct information (token, user, password, server ip:port) and I`m receiving the blue box with (error trying to update plex).\r\nWhat is surprisingly, when using the Test Plex Media Server, the test is ok even if the Token field is empty.\r\n\r\nError received:\r\nThread_2 :: [] PLEX: Unauthorized. Please set TOKEN or USERNAME and PASSWORD in Plex settings\n", "before_files": [{"content": "# coding=utf-8\n\"\"\"Request handler for notifications data.\"\"\"\nfrom __future__ import unicode_literals\n\n\nimport logging\nimport re\n\nfrom medusa import app, notifiers, ui\nfrom medusa.logger.adapters.style import BraceAdapter\nfrom medusa.server.api.v2.base import BaseRequestHandler\nfrom medusa.tv.series import Series, SeriesIdentifier\n\nlog = BraceAdapter(logging.getLogger(__name__))\nlog.logger.addHandler(logging.NullHandler())\n\n\nclass NotificationsHandler(BaseRequestHandler):\n    \"\"\"Notifications data request handler.\"\"\"\n\n    #: resource name\n    name = 'notifications'\n    #: identifier\n    identifier = ('resource', r'\\w+')\n    #: path param\n    path_param = ('path_param', r'\\w+')\n    #: allowed HTTP methods\n    allowed_methods = ('GET', 'POST')\n\n    def post(self, resource, path_param=None):\n        \"\"\"Post Notifications actions for a specific external source.\n\n        :param resource: a resource name\n        :param path_param:\n        :type path_param: str\n        \"\"\"\n        if resource is None:\n            return self._bad_request('You must provide a notifications resource name')\n\n        available_resources = (\n            'kodi', 'plexserver', 'plexhome', 'emby', 'nmj', 'nmjv2', 'trakt'\n        )\n\n        if resource not in available_resources:\n            return self._bad_request(f\"Resource must be one of {', '.join(available_resources)}\")\n\n        # Convert 'camelCase' to 'resource_snake_case'\n        resource_function_name = resource + '_' + re.sub('([A-Z]+)', r'_\\1', path_param).lower()\n        resource_function = getattr(self, resource_function_name, None)\n\n        if resource_function is None:\n            log.error('Unable to get function \"{func}\" for resource \"{resource}\"',\n                      {'func': resource_function_name, 'resource': path_param})\n            return self._bad_request('{key} is a invalid resource'.format(key=path_param))\n\n        return resource_function()\n\n    def kodi_update(self):\n        \"\"\"Update kodi's show library.\"\"\"\n        if app.KODI_UPDATE_ONLYFIRST:\n            host = app.KODI_HOST[0].strip()\n        else:\n            host = ', '.join(app.KODI_HOST)\n\n        if notifiers.kodi_notifier.update_library():\n            ui.notifications.message(f'Library update command sent to KODI host(s): {host}')\n        else:\n            ui.notifications.error(f'Unable to contact one or more KODI host(s): {host}')\n\n        return self._created()\n\n    def emby_update(self):\n        \"\"\"Update emby's show library.\"\"\"\n        show_slug = self.get_argument('showslug', '')\n        show = None\n\n        if show_slug:\n            show_identifier = SeriesIdentifier.from_slug(show_slug)\n            if not show_identifier:\n                return self._bad_request('Invalid show slug')\n\n            show = Series.find_by_identifier(show_identifier)\n            if not show:\n                return self._not_found('Series not found')\n\n        if notifiers.emby_notifier.update_library(show):\n            ui.notifications.message(f'Library update command sent to Emby host: {app.EMBY_HOST}')\n        else:\n            ui.notifications.error(f'Unable to contact Emby host: {app.EMBY_HOST}')\n\n        return self._created()\n\n    def plex_update(self):\n        \"\"\"Update plex's show library.\"\"\"\n        if None is notifiers.plex_notifier.update_library():\n            ui.notifications.message(\n                'Library update command sent to Plex Media Server host: {host}'.format(host=', '.join(app.PLEX_SERVER_HOST)))\n        else:\n            ui.notifications.error('Unable to contact Plex Media Server host: {host}'.format(host=', '.join(app.PLEX_SERVER_HOST)))\n\n        return self._created()\n", "path": "medusa/server/api/v2/notifications.py"}], "after_files": [{"content": "# coding=utf-8\n\"\"\"Request handler for notifications data.\"\"\"\nfrom __future__ import unicode_literals\n\n\nimport logging\nimport re\n\nfrom medusa import app, notifiers, ui\nfrom medusa.logger.adapters.style import BraceAdapter\nfrom medusa.server.api.v2.base import BaseRequestHandler\nfrom medusa.tv.series import Series, SeriesIdentifier\n\nlog = BraceAdapter(logging.getLogger(__name__))\nlog.logger.addHandler(logging.NullHandler())\n\n\nclass NotificationsHandler(BaseRequestHandler):\n    \"\"\"Notifications data request handler.\"\"\"\n\n    #: resource name\n    name = 'notifications'\n    #: identifier\n    identifier = ('resource', r'\\w+')\n    #: path param\n    path_param = ('path_param', r'\\w+')\n    #: allowed HTTP methods\n    allowed_methods = ('GET', 'POST')\n\n    def post(self, resource, path_param=None):\n        \"\"\"Post Notifications actions for a specific external source.\n\n        :param resource: a resource name\n        :param path_param:\n        :type path_param: str\n        \"\"\"\n        if resource is None:\n            return self._bad_request('You must provide a notifications resource name')\n\n        available_resources = (\n            'kodi', 'plexserver', 'plexhome', 'emby', 'nmj', 'nmjv2', 'trakt', 'plex'\n        )\n\n        if resource not in available_resources:\n            return self._bad_request(f\"Resource must be one of {', '.join(available_resources)}\")\n\n        # Convert 'camelCase' to 'resource_snake_case'\n        resource_function_name = resource + '_' + re.sub('([A-Z]+)', r'_\\1', path_param).lower()\n        resource_function = getattr(self, resource_function_name, None)\n\n        if resource_function is None:\n            log.error('Unable to get function \"{func}\" for resource \"{resource}\"',\n                      {'func': resource_function_name, 'resource': path_param})\n            return self._bad_request('{key} is a invalid resource'.format(key=path_param))\n\n        return resource_function()\n\n    def kodi_update(self):\n        \"\"\"Update kodi's show library.\"\"\"\n        if app.KODI_UPDATE_ONLYFIRST:\n            host = app.KODI_HOST[0].strip()\n        else:\n            host = ', '.join(app.KODI_HOST)\n\n        if notifiers.kodi_notifier.update_library():\n            ui.notifications.message(f'Library update command sent to KODI host(s): {host}')\n        else:\n            ui.notifications.error(f'Unable to contact one or more KODI host(s): {host}')\n\n        return self._created()\n\n    def emby_update(self):\n        \"\"\"Update emby's show library.\"\"\"\n        show_slug = self.get_argument('showslug', '')\n        show = None\n\n        if show_slug:\n            show_identifier = SeriesIdentifier.from_slug(show_slug)\n            if not show_identifier:\n                return self._bad_request('Invalid show slug')\n\n            show = Series.find_by_identifier(show_identifier)\n            if not show:\n                return self._not_found('Series not found')\n\n        if notifiers.emby_notifier.update_library(show):\n            ui.notifications.message(f'Library update command sent to Emby host: {app.EMBY_HOST}')\n        else:\n            ui.notifications.error(f'Unable to contact Emby host: {app.EMBY_HOST}')\n\n        return self._created()\n\n    def plex_update(self):\n        \"\"\"Update plex's show library.\"\"\"\n        if not notifiers.plex_notifier.update_library():\n            ui.notifications.message(\n                f\"Library update command sent to Plex Media Server host: {', '.join(app.PLEX_SERVER_HOST)}\")\n        else:\n            ui.notifications.error(f\"Unable to contact Plex Media Server host: {', '.join(app.PLEX_SERVER_HOST)}\")\n\n        return self._created()\n", "path": "medusa/server/api/v2/notifications.py"}]}