prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  TypeError with Form Login Plugin
  ### Expected behaviour:
  
  Task runs without generating error.
  ### Actual behaviour:
  
  Task runs and generates the following error
  
  ```
  TypeError: must be unicode, not str
  ```
  ### Steps to reproduce:
  - Step 1: Install latest version of Flexget using virtualenv
  - Step 2: pip install mechanize
  - Step 3: Create config.yml
  - Step 4: flexget --test execute
  #### Config:
  
  ```
  tasks:
    test task:
      form:
        url: http://example.com/login.php
        username: email address
        password: password
      html:
        url: http://example.com/
  ```
  #### Log:
  
  Crash:
  
  ```
  2016-08-16 11:40 DEBUG    manager       test task       Traceback:
  Traceback (most recent call last):
    File "/home/username/flexget/local/lib/python2.7/site-packages/flexget/task.py", line 444, in __run_plugin
      return method(*args, **kwargs)
    File "/home/username/flexget/local/lib/python2.7/site-packages/flexget/event.py", line 23, in __call__
      return self.func(*args, **kwargs)
    File "/home/username/flexget/local/lib/python2.7/site-packages/flexget/plugins/plugin_formlogin.py", line 73, in on_task_start
      f.write(br.response().get_data())
  TypeError: must be unicode, not str
  2016-08-16 11:40 WARNING  task          test task       Aborting task (plugin: form)
  2016-08-16 11:40 DEBUG    task_queue                    task test task aborted: TaskAbort(reason=BUG: Unhandled error in plugin form: must be unicode, not str, silent=False)
  ```
  
  Full log.
  
  ```
  http://pastebin.com/yBRqhYjR
  ```
  ### Additional information:
  - Flexget Version: 2.2.20
  - Python Version: 2.7.9
  - Installation method: Virtualenv
  - OS and version: Debian 8
  
  
  --- 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/plugin_formlogin.py`
  Content:
  ```
  1 from __future__ import unicode_literals, division, absolute_import
  2 from builtins import *  # pylint: disable=unused-import, redefined-builtin
  3 
  4 import logging
  5 import os
  6 import socket
  7 
  8 from flexget import plugin
  9 from flexget.event import event
  10 
  11 log = logging.getLogger('formlogin')
  12 
  13 
  14 class FormLogin(object):
  15     """
  16     Login on form
  17     """
  18 
  19     schema = {
  20         'type': 'object',
  21         'properties': {
  22             'url': {'type': 'string', 'format': 'url'},
  23             'username': {'type': 'string'},
  24             'password': {'type': 'string'},
  25             'userfield': {'type': 'string'},
  26             'passfield': {'type': 'string'}
  27         },
  28         'required': ['url', 'username', 'password'],
  29         'additionalProperties': False
  30     }
  31 
  32     def on_task_start(self, task, config):
  33         try:
  34             from mechanize import Browser
  35         except ImportError:
  36             raise plugin.PluginError('mechanize required (python module), please install it.', log)
  37 
  38         userfield = config.get('userfield', 'username')
  39         passfield = config.get('passfield', 'password')
  40 
  41         url = config['url']
  42         username = config['username']
  43         password = config['password']
  44 
  45         br = Browser()
  46         br.set_handle_robots(False)
  47         try:
  48             br.open(url)
  49         except Exception:
  50             # TODO: improve error handling
  51             raise plugin.PluginError('Unable to post login form', log)
  52 
  53         # br.set_debug_redirects(True)
  54         # br.set_debug_responses(True)
  55         # br.set_debug_http(True)
  56 
  57         try:
  58             for form in br.forms():
  59                 loginform = form
  60 
  61                 try:
  62                     loginform[userfield] = username
  63                     loginform[passfield] = password
  64                     break
  65                 except Exception:
  66                     pass
  67             else:
  68                 received = os.path.join(task.manager.config_base, 'received')
  69                 if not os.path.isdir(received):
  70                     os.mkdir(received)
  71                 filename = os.path.join(received, '%s.formlogin.html' % task.name)
  72                 with open(filename, 'w') as f:
  73                     f.write(br.response().get_data())
  74                 log.critical('I have saved the login page content to %s for you to view' % filename)
  75                 raise plugin.PluginError('Unable to find login fields', log)
  76         except socket.timeout:
  77             raise plugin.PluginError('Timed out on url %s' % url)
  78 
  79         br.form = loginform
  80 
  81         br.submit()
  82 
  83         cookiejar = br._ua_handlers["_cookies"].cookiejar
  84 
  85         # Add cookiejar to our requests session
  86         task.requests.add_cookiejar(cookiejar)
  87 
  88 
  89 @event('plugin.register')
  90 def register_plugin():
  91     plugin.register(FormLogin, 'form', api_ver=2)
  92
  ```
  --- 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/plugin_formlogin.py b/flexget/plugins/plugin_formlogin.py
  --- a/flexget/plugins/plugin_formlogin.py
  +++ b/flexget/plugins/plugin_formlogin.py
  @@ -2,6 +2,7 @@
   from builtins import *  # pylint: disable=unused-import, redefined-builtin
   
   import logging
  +import io
   import os
   import socket
   
  @@ -69,7 +70,7 @@
                   if not os.path.isdir(received):
                       os.mkdir(received)
                   filename = os.path.join(received, '%s.formlogin.html' % task.name)
  -                with open(filename, 'w') as f:
  +                with io.open(filename, 'wb') as f:
                       f.write(br.response().get_data())
                   log.critical('I have saved the login page content to %s for you to view' % filename)
                   raise plugin.PluginError('Unable to find login fields', log)
  
verification_info: {"golden_diff": "diff --git a/flexget/plugins/plugin_formlogin.py b/flexget/plugins/plugin_formlogin.py\n--- a/flexget/plugins/plugin_formlogin.py\n+++ b/flexget/plugins/plugin_formlogin.py\n@@ -2,6 +2,7 @@\n from builtins import *  # pylint: disable=unused-import, redefined-builtin\n \n import logging\n+import io\n import os\n import socket\n \n@@ -69,7 +70,7 @@\n                 if not os.path.isdir(received):\n                     os.mkdir(received)\n                 filename = os.path.join(received, '%s.formlogin.html' % task.name)\n-                with open(filename, 'w') as f:\n+                with io.open(filename, 'wb') as f:\n                     f.write(br.response().get_data())\n                 log.critical('I have saved the login page content to %s for you to view' % filename)\n                 raise plugin.PluginError('Unable to find login fields', log)\n", "issue": "TypeError with Form Login Plugin\n### Expected behaviour:\n\nTask runs without generating error.\n### Actual behaviour:\n\nTask runs and generates the following error\n\n```\nTypeError: must be unicode, not str\n```\n### Steps to reproduce:\n- Step 1: Install latest version of Flexget using virtualenv\n- Step 2: pip install mechanize\n- Step 3: Create config.yml\n- Step 4: flexget --test execute\n#### Config:\n\n```\ntasks:\n  test task:\n    form:\n      url: http://example.com/login.php\n      username: email address\n      password: password\n    html:\n      url: http://example.com/\n```\n#### Log:\n\nCrash:\n\n```\n2016-08-16 11:40 DEBUG    manager       test task       Traceback:\nTraceback (most recent call last):\n  File \"/home/username/flexget/local/lib/python2.7/site-packages/flexget/task.py\", line 444, in __run_plugin\n    return method(*args, **kwargs)\n  File \"/home/username/flexget/local/lib/python2.7/site-packages/flexget/event.py\", line 23, in __call__\n    return self.func(*args, **kwargs)\n  File \"/home/username/flexget/local/lib/python2.7/site-packages/flexget/plugins/plugin_formlogin.py\", line 73, in on_task_start\n    f.write(br.response().get_data())\nTypeError: must be unicode, not str\n2016-08-16 11:40 WARNING  task          test task       Aborting task (plugin: form)\n2016-08-16 11:40 DEBUG    task_queue                    task test task aborted: TaskAbort(reason=BUG: Unhandled error in plugin form: must be unicode, not str, silent=False)\n```\n\nFull log.\n\n```\nhttp://pastebin.com/yBRqhYjR\n```\n### Additional information:\n- Flexget Version: 2.2.20\n- Python Version: 2.7.9\n- Installation method: Virtualenv\n- OS and version: Debian 8\n\n", "before_files": [{"content": "from __future__ import unicode_literals, division, absolute_import\nfrom builtins import *  # pylint: disable=unused-import, redefined-builtin\n\nimport logging\nimport os\nimport socket\n\nfrom flexget import plugin\nfrom flexget.event import event\n\nlog = logging.getLogger('formlogin')\n\n\nclass FormLogin(object):\n    \"\"\"\n    Login on form\n    \"\"\"\n\n    schema = {\n        'type': 'object',\n        'properties': {\n            'url': {'type': 'string', 'format': 'url'},\n            'username': {'type': 'string'},\n            'password': {'type': 'string'},\n            'userfield': {'type': 'string'},\n            'passfield': {'type': 'string'}\n        },\n        'required': ['url', 'username', 'password'],\n        'additionalProperties': False\n    }\n\n    def on_task_start(self, task, config):\n        try:\n            from mechanize import Browser\n        except ImportError:\n            raise plugin.PluginError('mechanize required (python module), please install it.', log)\n\n        userfield = config.get('userfield', 'username')\n        passfield = config.get('passfield', 'password')\n\n        url = config['url']\n        username = config['username']\n        password = config['password']\n\n        br = Browser()\n        br.set_handle_robots(False)\n        try:\n            br.open(url)\n        except Exception:\n            # TODO: improve error handling\n            raise plugin.PluginError('Unable to post login form', log)\n\n        # br.set_debug_redirects(True)\n        # br.set_debug_responses(True)\n        # br.set_debug_http(True)\n\n        try:\n            for form in br.forms():\n                loginform = form\n\n                try:\n                    loginform[userfield] = username\n                    loginform[passfield] = password\n                    break\n                except Exception:\n                    pass\n            else:\n                received = os.path.join(task.manager.config_base, 'received')\n                if not os.path.isdir(received):\n                    os.mkdir(received)\n                filename = os.path.join(received, '%s.formlogin.html' % task.name)\n                with open(filename, 'w') as f:\n                    f.write(br.response().get_data())\n                log.critical('I have saved the login page content to %s for you to view' % filename)\n                raise plugin.PluginError('Unable to find login fields', log)\n        except socket.timeout:\n            raise plugin.PluginError('Timed out on url %s' % url)\n\n        br.form = loginform\n\n        br.submit()\n\n        cookiejar = br._ua_handlers[\"_cookies\"].cookiejar\n\n        # Add cookiejar to our requests session\n        task.requests.add_cookiejar(cookiejar)\n\n\n@event('plugin.register')\ndef register_plugin():\n    plugin.register(FormLogin, 'form', api_ver=2)\n", "path": "flexget/plugins/plugin_formlogin.py"}], "after_files": [{"content": "from __future__ import unicode_literals, division, absolute_import\nfrom builtins import *  # pylint: disable=unused-import, redefined-builtin\n\nimport logging\nimport io\nimport os\nimport socket\n\nfrom flexget import plugin\nfrom flexget.event import event\n\nlog = logging.getLogger('formlogin')\n\n\nclass FormLogin(object):\n    \"\"\"\n    Login on form\n    \"\"\"\n\n    schema = {\n        'type': 'object',\n        'properties': {\n            'url': {'type': 'string', 'format': 'url'},\n            'username': {'type': 'string'},\n            'password': {'type': 'string'},\n            'userfield': {'type': 'string'},\n            'passfield': {'type': 'string'}\n        },\n        'required': ['url', 'username', 'password'],\n        'additionalProperties': False\n    }\n\n    def on_task_start(self, task, config):\n        try:\n            from mechanize import Browser\n        except ImportError:\n            raise plugin.PluginError('mechanize required (python module), please install it.', log)\n\n        userfield = config.get('userfield', 'username')\n        passfield = config.get('passfield', 'password')\n\n        url = config['url']\n        username = config['username']\n        password = config['password']\n\n        br = Browser()\n        br.set_handle_robots(False)\n        try:\n            br.open(url)\n        except Exception:\n            # TODO: improve error handling\n            raise plugin.PluginError('Unable to post login form', log)\n\n        # br.set_debug_redirects(True)\n        # br.set_debug_responses(True)\n        # br.set_debug_http(True)\n\n        try:\n            for form in br.forms():\n                loginform = form\n\n                try:\n                    loginform[userfield] = username\n                    loginform[passfield] = password\n                    break\n                except Exception:\n                    pass\n            else:\n                received = os.path.join(task.manager.config_base, 'received')\n                if not os.path.isdir(received):\n                    os.mkdir(received)\n                filename = os.path.join(received, '%s.formlogin.html' % task.name)\n                with io.open(filename, 'wb') as f:\n                    f.write(br.response().get_data())\n                log.critical('I have saved the login page content to %s for you to view' % filename)\n                raise plugin.PluginError('Unable to find login fields', log)\n        except socket.timeout:\n            raise plugin.PluginError('Timed out on url %s' % url)\n\n        br.form = loginform\n\n        br.submit()\n\n        cookiejar = br._ua_handlers[\"_cookies\"].cookiejar\n\n        # Add cookiejar to our requests session\n        task.requests.add_cookiejar(cookiejar)\n\n\n@event('plugin.register')\ndef register_plugin():\n    plugin.register(FormLogin, 'form', api_ver=2)\n", "path": "flexget/plugins/plugin_formlogin.py"}]}