prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Free Mobile SMS notification failed
  Hi, 
  I recently update Medusa, and since then, I didn't receive any SMS for started/finished downloads
  
  On the error log file I have this:
  ```
  2019-06-22 15:42:51 ERROR    Thread_2 :: [74c3f12] Exception generated: can't concat str to bytes
  Traceback (most recent call last):
    File "C:\Medusa\Medusa\medusa\server\web\core\base.py", line 261, in async_call
      result = function(**kwargs)
    File "C:\Medusa\Medusa\medusa\server\web\home\handler.py", line 300, in testFreeMobile
      result, message = notifiers.freemobile_notifier.test_notify(freemobile_id, freemobile_apikey)
    File "C:\Medusa\Medusa\medusa\notifiers\freemobile.py", line 30, in test_notify
      return self._notifyFreeMobile('Test', 'This is a test notification from Medusa', cust_id, apiKey, force=True)
    File "C:\Medusa\Medusa\medusa\notifiers\freemobile.py", line 120, in _notifyFreeMobile
      return self._sendFreeMobileSMS(title, message, cust_id, apiKey)
    File "C:\Medusa\Medusa\medusa\notifiers\freemobile.py", line 51, in _sendFreeMobileSMS
      msg_quoted = quote(title.encode('utf-8') + ': ' + msg.encode('utf-8'))
  TypeError: can't concat str to bytes
  ```
  My Free Mobile customer ID and my Free Mobile API Key are still the same..
  
  Thanks in advance for any help you may provide.
  Regards.
  
  --- 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/notifiers/freemobile.py`
  Content:
  ```
  1 # coding=utf-8
  2 
  3 from __future__ import unicode_literals
  4 
  5 import logging
  6 from builtins import object
  7 
  8 from medusa import app
  9 from medusa.common import (
  10     NOTIFY_DOWNLOAD,
  11     NOTIFY_GIT_UPDATE,
  12     NOTIFY_GIT_UPDATE_TEXT,
  13     NOTIFY_LOGIN,
  14     NOTIFY_LOGIN_TEXT,
  15     NOTIFY_SUBTITLE_DOWNLOAD,
  16     notifyStrings,
  17 )
  18 from medusa.logger.adapters.style import BraceAdapter
  19 
  20 from requests.compat import quote
  21 
  22 from six.moves.urllib.request import Request, urlopen
  23 
  24 log = BraceAdapter(logging.getLogger(__name__))
  25 log.logger.addHandler(logging.NullHandler())
  26 
  27 
  28 class Notifier(object):
  29     def test_notify(self, cust_id=None, apiKey=None):
  30         return self._notifyFreeMobile('Test', 'This is a test notification from Medusa', cust_id, apiKey, force=True)
  31 
  32     def _sendFreeMobileSMS(self, title, msg, cust_id=None, apiKey=None):
  33         """
  34         Send a SMS notification
  35 
  36         msg: The message to send (unicode)
  37         title: The title of the message
  38         userKey: The pushover user id to send the message to (or to subscribe with)
  39 
  40         return: True if the message succeeded, False otherwise
  41         """
  42         if cust_id is None:
  43             cust_id = app.FREEMOBILE_ID
  44         if apiKey is None:
  45             apiKey = app.FREEMOBILE_APIKEY
  46 
  47         log.debug(u'Free Mobile in use with API KEY: {0}', apiKey)
  48 
  49         # build up the URL and parameters
  50         msg = msg.strip()
  51         msg_quoted = quote(title.encode('utf-8') + ': ' + msg.encode('utf-8'))
  52         URL = 'https://smsapi.free-mobile.fr/sendmsg?user=' + cust_id + '&pass=' + apiKey + '&msg=' + msg_quoted
  53 
  54         req = Request(URL)
  55         # send the request to Free Mobile
  56         try:
  57             urlopen(req)
  58         except IOError as e:
  59             if hasattr(e, 'code'):
  60                 error_message = {
  61                     400: 'Missing parameter(s).',
  62                     402: 'Too much SMS sent in a short time.',
  63                     403: 'API service is not enabled in your account or ID / API key is incorrect.',
  64                     500: 'Server error. Please retry in few moment.',
  65                 }
  66                 message = error_message.get(e.code)
  67                 if message:
  68                     log.error(message)
  69                     return False, message
  70         except Exception as e:
  71             message = u'Error while sending SMS: {0}'.format(e)
  72             log.error(message)
  73             return False, message
  74 
  75         message = 'Free Mobile SMS successful.'
  76         log.info(message)
  77         return True, message
  78 
  79     def notify_snatch(self, title, message):
  80         if app.FREEMOBILE_NOTIFY_ONSNATCH:
  81             self._notifyFreeMobile(title, message)
  82 
  83     def notify_download(self, ep_obj, title=notifyStrings[NOTIFY_DOWNLOAD]):
  84         if app.FREEMOBILE_NOTIFY_ONDOWNLOAD:
  85             self._notifyFreeMobile(title, ep_obj.pretty_name_with_quality())
  86 
  87     def notify_subtitle_download(self, ep_obj, lang, title=notifyStrings[NOTIFY_SUBTITLE_DOWNLOAD]):
  88         if app.FREEMOBILE_NOTIFY_ONSUBTITLEDOWNLOAD:
  89             self._notifyFreeMobile(title, ep_obj.pretty_name() + ': ' + lang)
  90 
  91     def notify_git_update(self, new_version='??'):
  92         if app.USE_FREEMOBILE:
  93             update_text = notifyStrings[NOTIFY_GIT_UPDATE_TEXT]
  94             title = notifyStrings[NOTIFY_GIT_UPDATE]
  95             self._notifyFreeMobile(title, update_text + new_version)
  96 
  97     def notify_login(self, ipaddress=''):
  98         if app.USE_FREEMOBILE:
  99             update_text = notifyStrings[NOTIFY_LOGIN_TEXT]
  100             title = notifyStrings[NOTIFY_LOGIN]
  101             self._notifyFreeMobile(title, update_text.format(ipaddress))
  102 
  103     def _notifyFreeMobile(self, title, message, cust_id=None, apiKey=None, force=False):  # pylint: disable=too-many-arguments
  104         """
  105         Sends a SMS notification
  106 
  107         title: The title of the notification to send
  108         message: The message string to send
  109         cust_id: Your Free Mobile customer ID
  110         apikey: Your Free Mobile API key
  111         force: Enforce sending, for instance for testing
  112         """
  113 
  114         if not app.USE_FREEMOBILE and not force:
  115             log.debug(u'Notification for Free Mobile not enabled, skipping this notification')
  116             return False, 'Disabled'
  117 
  118         log.debug(u'Sending a SMS for {0}', message)
  119 
  120         return self._sendFreeMobileSMS(title, message, cust_id, apiKey)
  121
  ```
  --- 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/notifiers/freemobile.py b/medusa/notifiers/freemobile.py
  --- a/medusa/notifiers/freemobile.py
  +++ b/medusa/notifiers/freemobile.py
  @@ -3,7 +3,6 @@
   from __future__ import unicode_literals
   
   import logging
  -from builtins import object
   
   from medusa import app
   from medusa.common import (
  @@ -47,9 +46,13 @@
           log.debug(u'Free Mobile in use with API KEY: {0}', apiKey)
   
           # build up the URL and parameters
  -        msg = msg.strip()
  -        msg_quoted = quote(title.encode('utf-8') + ': ' + msg.encode('utf-8'))
  -        URL = 'https://smsapi.free-mobile.fr/sendmsg?user=' + cust_id + '&pass=' + apiKey + '&msg=' + msg_quoted
  +        msg = '{0}: {1}'.format(title, msg.strip())
  +        msg_quoted = quote(msg.encode('utf-8'))
  +        URL = 'https://smsapi.free-mobile.fr/sendmsg?user={user}&pass={api_key}&msg={msg}'.format(
  +            user=cust_id,
  +            api_key=apiKey,
  +            msg=msg_quoted,
  +        )
   
           req = Request(URL)
           # send the request to Free Mobile
  
verification_info: {"golden_diff": "diff --git a/medusa/notifiers/freemobile.py b/medusa/notifiers/freemobile.py\n--- a/medusa/notifiers/freemobile.py\n+++ b/medusa/notifiers/freemobile.py\n@@ -3,7 +3,6 @@\n from __future__ import unicode_literals\n \n import logging\n-from builtins import object\n \n from medusa import app\n from medusa.common import (\n@@ -47,9 +46,13 @@\n         log.debug(u'Free Mobile in use with API KEY: {0}', apiKey)\n \n         # build up the URL and parameters\n-        msg = msg.strip()\n-        msg_quoted = quote(title.encode('utf-8') + ': ' + msg.encode('utf-8'))\n-        URL = 'https://smsapi.free-mobile.fr/sendmsg?user=' + cust_id + '&pass=' + apiKey + '&msg=' + msg_quoted\n+        msg = '{0}: {1}'.format(title, msg.strip())\n+        msg_quoted = quote(msg.encode('utf-8'))\n+        URL = 'https://smsapi.free-mobile.fr/sendmsg?user={user}&pass={api_key}&msg={msg}'.format(\n+            user=cust_id,\n+            api_key=apiKey,\n+            msg=msg_quoted,\n+        )\n \n         req = Request(URL)\n         # send the request to Free Mobile\n", "issue": "Free Mobile SMS notification failed\nHi, \r\nI recently update Medusa, and since then, I didn't receive any SMS for started/finished downloads\r\n\r\nOn the error log file I have this:\r\n```\r\n2019-06-22 15:42:51 ERROR    Thread_2 :: [74c3f12] Exception generated: can't concat str to bytes\r\nTraceback (most recent call last):\r\n  File \"C:\\Medusa\\Medusa\\medusa\\server\\web\\core\\base.py\", line 261, in async_call\r\n    result = function(**kwargs)\r\n  File \"C:\\Medusa\\Medusa\\medusa\\server\\web\\home\\handler.py\", line 300, in testFreeMobile\r\n    result, message = notifiers.freemobile_notifier.test_notify(freemobile_id, freemobile_apikey)\r\n  File \"C:\\Medusa\\Medusa\\medusa\\notifiers\\freemobile.py\", line 30, in test_notify\r\n    return self._notifyFreeMobile('Test', 'This is a test notification from Medusa', cust_id, apiKey, force=True)\r\n  File \"C:\\Medusa\\Medusa\\medusa\\notifiers\\freemobile.py\", line 120, in _notifyFreeMobile\r\n    return self._sendFreeMobileSMS(title, message, cust_id, apiKey)\r\n  File \"C:\\Medusa\\Medusa\\medusa\\notifiers\\freemobile.py\", line 51, in _sendFreeMobileSMS\r\n    msg_quoted = quote(title.encode('utf-8') + ': ' + msg.encode('utf-8'))\r\nTypeError: can't concat str to bytes\r\n```\r\nMy Free Mobile customer ID and my Free Mobile API Key are still the same..\r\n\r\nThanks in advance for any help you may provide.\r\nRegards.\n", "before_files": [{"content": "# coding=utf-8\n\nfrom __future__ import unicode_literals\n\nimport logging\nfrom builtins import object\n\nfrom medusa import app\nfrom medusa.common import (\n    NOTIFY_DOWNLOAD,\n    NOTIFY_GIT_UPDATE,\n    NOTIFY_GIT_UPDATE_TEXT,\n    NOTIFY_LOGIN,\n    NOTIFY_LOGIN_TEXT,\n    NOTIFY_SUBTITLE_DOWNLOAD,\n    notifyStrings,\n)\nfrom medusa.logger.adapters.style import BraceAdapter\n\nfrom requests.compat import quote\n\nfrom six.moves.urllib.request import Request, urlopen\n\nlog = BraceAdapter(logging.getLogger(__name__))\nlog.logger.addHandler(logging.NullHandler())\n\n\nclass Notifier(object):\n    def test_notify(self, cust_id=None, apiKey=None):\n        return self._notifyFreeMobile('Test', 'This is a test notification from Medusa', cust_id, apiKey, force=True)\n\n    def _sendFreeMobileSMS(self, title, msg, cust_id=None, apiKey=None):\n        \"\"\"\n        Send a SMS notification\n\n        msg: The message to send (unicode)\n        title: The title of the message\n        userKey: The pushover user id to send the message to (or to subscribe with)\n\n        return: True if the message succeeded, False otherwise\n        \"\"\"\n        if cust_id is None:\n            cust_id = app.FREEMOBILE_ID\n        if apiKey is None:\n            apiKey = app.FREEMOBILE_APIKEY\n\n        log.debug(u'Free Mobile in use with API KEY: {0}', apiKey)\n\n        # build up the URL and parameters\n        msg = msg.strip()\n        msg_quoted = quote(title.encode('utf-8') + ': ' + msg.encode('utf-8'))\n        URL = 'https://smsapi.free-mobile.fr/sendmsg?user=' + cust_id + '&pass=' + apiKey + '&msg=' + msg_quoted\n\n        req = Request(URL)\n        # send the request to Free Mobile\n        try:\n            urlopen(req)\n        except IOError as e:\n            if hasattr(e, 'code'):\n                error_message = {\n                    400: 'Missing parameter(s).',\n                    402: 'Too much SMS sent in a short time.',\n                    403: 'API service is not enabled in your account or ID / API key is incorrect.',\n                    500: 'Server error. Please retry in few moment.',\n                }\n                message = error_message.get(e.code)\n                if message:\n                    log.error(message)\n                    return False, message\n        except Exception as e:\n            message = u'Error while sending SMS: {0}'.format(e)\n            log.error(message)\n            return False, message\n\n        message = 'Free Mobile SMS successful.'\n        log.info(message)\n        return True, message\n\n    def notify_snatch(self, title, message):\n        if app.FREEMOBILE_NOTIFY_ONSNATCH:\n            self._notifyFreeMobile(title, message)\n\n    def notify_download(self, ep_obj, title=notifyStrings[NOTIFY_DOWNLOAD]):\n        if app.FREEMOBILE_NOTIFY_ONDOWNLOAD:\n            self._notifyFreeMobile(title, ep_obj.pretty_name_with_quality())\n\n    def notify_subtitle_download(self, ep_obj, lang, title=notifyStrings[NOTIFY_SUBTITLE_DOWNLOAD]):\n        if app.FREEMOBILE_NOTIFY_ONSUBTITLEDOWNLOAD:\n            self._notifyFreeMobile(title, ep_obj.pretty_name() + ': ' + lang)\n\n    def notify_git_update(self, new_version='??'):\n        if app.USE_FREEMOBILE:\n            update_text = notifyStrings[NOTIFY_GIT_UPDATE_TEXT]\n            title = notifyStrings[NOTIFY_GIT_UPDATE]\n            self._notifyFreeMobile(title, update_text + new_version)\n\n    def notify_login(self, ipaddress=''):\n        if app.USE_FREEMOBILE:\n            update_text = notifyStrings[NOTIFY_LOGIN_TEXT]\n            title = notifyStrings[NOTIFY_LOGIN]\n            self._notifyFreeMobile(title, update_text.format(ipaddress))\n\n    def _notifyFreeMobile(self, title, message, cust_id=None, apiKey=None, force=False):  # pylint: disable=too-many-arguments\n        \"\"\"\n        Sends a SMS notification\n\n        title: The title of the notification to send\n        message: The message string to send\n        cust_id: Your Free Mobile customer ID\n        apikey: Your Free Mobile API key\n        force: Enforce sending, for instance for testing\n        \"\"\"\n\n        if not app.USE_FREEMOBILE and not force:\n            log.debug(u'Notification for Free Mobile not enabled, skipping this notification')\n            return False, 'Disabled'\n\n        log.debug(u'Sending a SMS for {0}', message)\n\n        return self._sendFreeMobileSMS(title, message, cust_id, apiKey)\n", "path": "medusa/notifiers/freemobile.py"}], "after_files": [{"content": "# coding=utf-8\n\nfrom __future__ import unicode_literals\n\nimport logging\n\nfrom medusa import app\nfrom medusa.common import (\n    NOTIFY_DOWNLOAD,\n    NOTIFY_GIT_UPDATE,\n    NOTIFY_GIT_UPDATE_TEXT,\n    NOTIFY_LOGIN,\n    NOTIFY_LOGIN_TEXT,\n    NOTIFY_SUBTITLE_DOWNLOAD,\n    notifyStrings,\n)\nfrom medusa.logger.adapters.style import BraceAdapter\n\nfrom requests.compat import quote\n\nfrom six.moves.urllib.request import Request, urlopen\n\nlog = BraceAdapter(logging.getLogger(__name__))\nlog.logger.addHandler(logging.NullHandler())\n\n\nclass Notifier(object):\n    def test_notify(self, cust_id=None, apiKey=None):\n        return self._notifyFreeMobile('Test', 'This is a test notification from Medusa', cust_id, apiKey, force=True)\n\n    def _sendFreeMobileSMS(self, title, msg, cust_id=None, apiKey=None):\n        \"\"\"\n        Send a SMS notification\n\n        msg: The message to send (unicode)\n        title: The title of the message\n        userKey: The pushover user id to send the message to (or to subscribe with)\n\n        return: True if the message succeeded, False otherwise\n        \"\"\"\n        if cust_id is None:\n            cust_id = app.FREEMOBILE_ID\n        if apiKey is None:\n            apiKey = app.FREEMOBILE_APIKEY\n\n        log.debug(u'Free Mobile in use with API KEY: {0}', apiKey)\n\n        # build up the URL and parameters\n        msg = '{0}: {1}'.format(title, msg.strip())\n        msg_quoted = quote(msg.encode('utf-8'))\n        URL = 'https://smsapi.free-mobile.fr/sendmsg?user={user}&pass={api_key}&msg={msg}'.format(\n            user=cust_id,\n            api_key=apiKey,\n            msg=msg_quoted,\n        )\n\n        req = Request(URL)\n        # send the request to Free Mobile\n        try:\n            urlopen(req)\n        except IOError as e:\n            if hasattr(e, 'code'):\n                error_message = {\n                    400: 'Missing parameter(s).',\n                    402: 'Too much SMS sent in a short time.',\n                    403: 'API service is not enabled in your account or ID / API key is incorrect.',\n                    500: 'Server error. Please retry in few moment.',\n                }\n                message = error_message.get(e.code)\n                if message:\n                    log.error(message)\n                    return False, message\n        except Exception as e:\n            message = u'Error while sending SMS: {0}'.format(e)\n            log.error(message)\n            return False, message\n\n        message = 'Free Mobile SMS successful.'\n        log.info(message)\n        return True, message\n\n    def notify_snatch(self, title, message):\n        if app.FREEMOBILE_NOTIFY_ONSNATCH:\n            self._notifyFreeMobile(title, message)\n\n    def notify_download(self, ep_obj, title=notifyStrings[NOTIFY_DOWNLOAD]):\n        if app.FREEMOBILE_NOTIFY_ONDOWNLOAD:\n            self._notifyFreeMobile(title, ep_obj.pretty_name_with_quality())\n\n    def notify_subtitle_download(self, ep_obj, lang, title=notifyStrings[NOTIFY_SUBTITLE_DOWNLOAD]):\n        if app.FREEMOBILE_NOTIFY_ONSUBTITLEDOWNLOAD:\n            self._notifyFreeMobile(title, ep_obj.pretty_name() + ': ' + lang)\n\n    def notify_git_update(self, new_version='??'):\n        if app.USE_FREEMOBILE:\n            update_text = notifyStrings[NOTIFY_GIT_UPDATE_TEXT]\n            title = notifyStrings[NOTIFY_GIT_UPDATE]\n            self._notifyFreeMobile(title, update_text + new_version)\n\n    def notify_login(self, ipaddress=''):\n        if app.USE_FREEMOBILE:\n            update_text = notifyStrings[NOTIFY_LOGIN_TEXT]\n            title = notifyStrings[NOTIFY_LOGIN]\n            self._notifyFreeMobile(title, update_text.format(ipaddress))\n\n    def _notifyFreeMobile(self, title, message, cust_id=None, apiKey=None, force=False):  # pylint: disable=too-many-arguments\n        \"\"\"\n        Sends a SMS notification\n\n        title: The title of the notification to send\n        message: The message string to send\n        cust_id: Your Free Mobile customer ID\n        apikey: Your Free Mobile API key\n        force: Enforce sending, for instance for testing\n        \"\"\"\n\n        if not app.USE_FREEMOBILE and not force:\n            log.debug(u'Notification for Free Mobile not enabled, skipping this notification')\n            return False, 'Disabled'\n\n        log.debug(u'Sending a SMS for {0}', message)\n\n        return self._sendFreeMobileSMS(title, message, cust_id, apiKey)\n", "path": "medusa/notifiers/freemobile.py"}]}