We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Post-processor crashes
**Tried submitting this log through Medusa, but that feature doesn't work** (someone else already submitted that issue)

**Branch/Commit:** commit b16e0e5eb4ded727eebd2ab2cd9683ab597662f5 (HEAD -> master, origin/master, origin/HEAD)
**OS:** FreeNAS 11.0-U4
**What you did:** restarted Medusa, waited 10 minutes for the post-processor to kick in
**What happened:** exception generated; see below
**What you expected:** downloads should've been sorted into their destination directories
**Logs:**
```
2017-11-03 08:28:35 ERROR    POSTPROCESSOR :: [b16e0e5] Exception generated: 'ascii' codec can't encode character u'\u2019' in position 37: ordinal not in range(128)
Traceback (most recent call last):
  File "/usr/local/share/medusa/medusa/scheduler.py", line 93, in run
    self.action.run(self.force)
  File "/usr/local/share/medusa/medusa/auto_post_processor.py", line 57, in run
    process_tv.ProcessResult(app.TV_DOWNLOAD_DIR, app.PROCESS_METHOD).process(force=force)
  File "/usr/local/share/medusa/medusa/process_tv.py", line 162, in process
    ignore_subs=ignore_subs)
  File "/usr/local/share/medusa/medusa/process_tv.py", line 334, in process_files
    self.process_media(path, self.video_files, force, is_priority, ignore_subs)
  File "/usr/local/share/medusa/medusa/process_tv.py", line 535, in process_media
    self.result = processor.process()
  File "/usr/local/share/medusa/medusa/post_processor.py", line 1093, in process
    self._delete(cur_ep.location, associated_files=True)
  File "/usr/local/share/medusa/medusa/post_processor.py", line 330, in _delete
    file_list += self.list_associated_files(file_list[0], subfolders=True)
  File "/usr/local/share/medusa/medusa/post_processor.py", line 190, in list_associated_files
    processed_names += filter(None, (self._rar_basename(file_path, files),))
  File "/usr/local/share/medusa/medusa/post_processor.py", line 300, in _rar_basename
    for rar in rars:
  File "/usr/local/share/medusa/medusa/post_processor.py", line 298, in <genexpr>
    rars = (x for x in files if rarfile.is_rarfile(x))
  File "/usr/local/share/medusa/ext/rarfile.py", line 404, in is_rarfile
    return _get_rar_version(xfile) > 0
  File "/usr/local/share/medusa/ext/rarfile.py", line 389, in _get_rar_version
    with XFile(xfile) as fd:
  File "/usr/local/share/medusa/ext/rarfile.py", line 2401, in __init__
    self._fd = open(xfile, 'rb', bufsize)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 37: ordinal not in range(128)
```


--- 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/init/filesystem.py`
Content:
```
1 # coding=utf-8
2 """Replace core filesystem functions."""
3 
4 import glob
5 import io
6 import os
7 import shutil
8 import sys
9 import tarfile
10 
11 import tempfile # noqa # pylint: disable=unused-import
12 import certifi
13 
14 from six import binary_type, text_type
15 
16 
17 fs_encoding = sys.getfilesystemencoding()
18 
19 
20 def encode(value):
21     """Encode to bytes."""
22     return value.encode('utf-8' if os.name != 'nt' else fs_encoding)
23 
24 
25 def decode(value):
26     """Decode to unicode."""
27     # on windows the returned info from fs operations needs to be decoded using fs encoding
28     return text_type(value, 'utf-8' if os.name != 'nt' else fs_encoding)
29 
30 
31 def _handle_input(arg):
32     """Encode argument to utf-8 or fs encoding."""
33     # on windows the input params for fs operations needs to be encoded using fs encoding
34     return encode(arg) if isinstance(arg, text_type) else arg
35 
36 
37 def _handle_output_u(result):
38     """Convert result to unicode."""
39     if not result:
40         return result
41 
42     if isinstance(result, binary_type):
43         return decode(result)
44 
45     if isinstance(result, list) or isinstance(result, tuple):
46         return map(_handle_output_u, result)
47 
48     if isinstance(result, dict):
49         for k, v in result.items():
50             result[k] = _handle_output_u(v)
51         return result
52 
53     return result
54 
55 
56 def _handle_output_b(result):
57     """Convert result to binary."""
58     if not result:
59         return result
60 
61     if isinstance(result, text_type):
62         return encode(result)
63 
64     if isinstance(result, list) or isinstance(result, tuple):
65         return map(_handle_output_b, result)
66 
67     if isinstance(result, dict):
68         for k, v in result.items():
69             result[k] = _handle_output_b(v)
70         return result
71 
72     return result
73 
74 
75 def _varargs(*args):
76     """Encode var arguments to utf-8 or fs encoding."""
77     return [_handle_input(arg) for arg in args]
78 
79 
80 def _varkwargs(**kwargs):
81     """Encode var keyword  arguments to utf-8."""
82     return {k: _handle_input(arg) for k, arg in kwargs.items()}
83 
84 
85 def make_closure(f, handle_arg=None, handle_output=None):
86     """Apply an input handler and output handler to a function.
87 
88     Used to ensure UTF-8 encoding at input and output.
89     """
90     return patch_output(patch_input(f, handle_arg), handle_output)
91 
92 
93 def patch_input(f, handle_arg=None):
94     """Patch all args and kwargs of function f.
95 
96     If handle_arg is None, just return the original function.
97     """
98     def patched_input(*args, **kwargs):
99         return f(*[handle_arg(arg) for arg in args], **{k: handle_arg(arg) for k, arg in kwargs.items()})
100     return patched_input if callable(handle_arg) else f
101 
102 
103 def patch_output(f, handle_output=None):
104     """Patch the output of function f with the handle_output function.
105 
106     If handle_output is None, just return the original function.
107     """
108     def patched_output(*args, **kwargs):
109         return handle_output(f(*args, **kwargs))
110     return patched_output if callable(handle_output) else f
111 
112 
113 def initialize():
114     """Replace original functions if the fs encoding is not utf-8."""
115     if hasattr(sys, '_called_from_test'):
116         return
117 
118     affected_functions = {
119         certifi: ['where', 'old_where'],
120         glob: ['glob'],
121         io: ['open'],
122         os: ['access', 'chdir', 'listdir', 'makedirs', 'mkdir', 'remove',
123              'rename', 'renames', 'rmdir', 'stat', 'unlink', 'utime', 'walk'],
124         os.path: ['abspath', 'basename', 'dirname', 'exists', 'getctime', 'getmtime', 'getsize',
125                   'isabs', 'isdir', 'isfile', 'islink', 'join', 'normcase', 'normpath', 'realpath', 'relpath',
126                   'split', 'splitext'],
127         shutil: ['copyfile', 'copymode', 'move', 'rmtree'],
128         tarfile: ['is_tarfile'],
129     }
130 
131     # pyOpenSSL 0.14-1 bug: it can't handle unicode input.
132     # pyOpenSSL fix -> https://github.com/pyca/pyopenssl/pull/209
133     # Our bug: https://github.com/pymedusa/Medusa/issues/1422
134     handle_output_map = {
135         certifi: _handle_output_b
136     }
137 
138     if os.name != 'nt':
139         affected_functions[os].extend(['chmod', 'chown', 'link', 'statvfs', 'symlink'])
140 
141     if not fs_encoding or fs_encoding.lower() not in ('utf-8', 'mbcs'):
142         handle_input = _handle_input
143     else:
144         handle_input = None
145 
146     for k, v in affected_functions.items():
147         handle_output = handle_output_map.get(k, _handle_output_u)
148         for f in v:
149             setattr(k, f, make_closure(getattr(k, f), handle_input, handle_output))
150
```
--- 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()

```

diff --git a/medusa/init/filesystem.py b/medusa/init/filesystem.py
--- a/medusa/init/filesystem.py
+++ b/medusa/init/filesystem.py
@@ -7,10 +7,12 @@
 import shutil
 import sys
 import tarfile
-
 import tempfile # noqa # pylint: disable=unused-import
+
 import certifi
 
+import rarfile
+
 from six import binary_type, text_type
 
 
@@ -126,6 +128,7 @@
                   'split', 'splitext'],
         shutil: ['copyfile', 'copymode', 'move', 'rmtree'],
         tarfile: ['is_tarfile'],
+        rarfile: ['is_rarfile'],
     }
 
     # pyOpenSSL 0.14-1 bug: it can't handle unicode input.

{"golden_diff": "diff --git a/medusa/init/filesystem.py b/medusa/init/filesystem.py\n--- a/medusa/init/filesystem.py\n+++ b/medusa/init/filesystem.py\n@@ -7,10 +7,12 @@\n import shutil\n import sys\n import tarfile\n-\n import tempfile # noqa # pylint: disable=unused-import\n+\n import certifi\n \n+import rarfile\n+\n from six import binary_type, text_type\n \n \n@@ -126,6 +128,7 @@\n                   'split', 'splitext'],\n         shutil: ['copyfile', 'copymode', 'move', 'rmtree'],\n         tarfile: ['is_tarfile'],\n+        rarfile: ['is_rarfile'],\n     }\n \n     # pyOpenSSL 0.14-1 bug: it can't handle unicode input.\n", "issue": "Post-processor crashes\n**Tried submitting this log through Medusa, but that feature doesn't work** (someone else already submitted that issue)\r\n\r\n**Branch/Commit:** commit b16e0e5eb4ded727eebd2ab2cd9683ab597662f5 (HEAD -> master, origin/master, origin/HEAD)\r\n**OS:** FreeNAS 11.0-U4\r\n**What you did:** restarted Medusa, waited 10 minutes for the post-processor to kick in\r\n**What happened:** exception generated; see below\r\n**What you expected:** downloads should've been sorted into their destination directories\r\n**Logs:**\r\n```\r\n2017-11-03 08:28:35 ERROR    POSTPROCESSOR :: [b16e0e5] Exception generated: 'ascii' codec can't encode character u'\\u2019' in position 37: ordinal not in range(128)\r\nTraceback (most recent call last):\r\n  File \"/usr/local/share/medusa/medusa/scheduler.py\", line 93, in run\r\n    self.action.run(self.force)\r\n  File \"/usr/local/share/medusa/medusa/auto_post_processor.py\", line 57, in run\r\n    process_tv.ProcessResult(app.TV_DOWNLOAD_DIR, app.PROCESS_METHOD).process(force=force)\r\n  File \"/usr/local/share/medusa/medusa/process_tv.py\", line 162, in process\r\n    ignore_subs=ignore_subs)\r\n  File \"/usr/local/share/medusa/medusa/process_tv.py\", line 334, in process_files\r\n    self.process_media(path, self.video_files, force, is_priority, ignore_subs)\r\n  File \"/usr/local/share/medusa/medusa/process_tv.py\", line 535, in process_media\r\n    self.result = processor.process()\r\n  File \"/usr/local/share/medusa/medusa/post_processor.py\", line 1093, in process\r\n    self._delete(cur_ep.location, associated_files=True)\r\n  File \"/usr/local/share/medusa/medusa/post_processor.py\", line 330, in _delete\r\n    file_list += self.list_associated_files(file_list[0], subfolders=True)\r\n  File \"/usr/local/share/medusa/medusa/post_processor.py\", line 190, in list_associated_files\r\n    processed_names += filter(None, (self._rar_basename(file_path, files),))\r\n  File \"/usr/local/share/medusa/medusa/post_processor.py\", line 300, in _rar_basename\r\n    for rar in rars:\r\n  File \"/usr/local/share/medusa/medusa/post_processor.py\", line 298, in <genexpr>\r\n    rars = (x for x in files if rarfile.is_rarfile(x))\r\n  File \"/usr/local/share/medusa/ext/rarfile.py\", line 404, in is_rarfile\r\n    return _get_rar_version(xfile) > 0\r\n  File \"/usr/local/share/medusa/ext/rarfile.py\", line 389, in _get_rar_version\r\n    with XFile(xfile) as fd:\r\n  File \"/usr/local/share/medusa/ext/rarfile.py\", line 2401, in __init__\r\n    self._fd = open(xfile, 'rb', bufsize)\r\nUnicodeEncodeError: 'ascii' codec can't encode character u'\\u2019' in position 37: ordinal not in range(128)\r\n```\r\n\n", "before_files": [{"content": "# coding=utf-8\n\"\"\"Replace core filesystem functions.\"\"\"\n\nimport glob\nimport io\nimport os\nimport shutil\nimport sys\nimport tarfile\n\nimport tempfile # noqa # pylint: disable=unused-import\nimport certifi\n\nfrom six import binary_type, text_type\n\n\nfs_encoding = sys.getfilesystemencoding()\n\n\ndef encode(value):\n    \"\"\"Encode to bytes.\"\"\"\n    return value.encode('utf-8' if os.name != 'nt' else fs_encoding)\n\n\ndef decode(value):\n    \"\"\"Decode to unicode.\"\"\"\n    # on windows the returned info from fs operations needs to be decoded using fs encoding\n    return text_type(value, 'utf-8' if os.name != 'nt' else fs_encoding)\n\n\ndef _handle_input(arg):\n    \"\"\"Encode argument to utf-8 or fs encoding.\"\"\"\n    # on windows the input params for fs operations needs to be encoded using fs encoding\n    return encode(arg) if isinstance(arg, text_type) else arg\n\n\ndef _handle_output_u(result):\n    \"\"\"Convert result to unicode.\"\"\"\n    if not result:\n        return result\n\n    if isinstance(result, binary_type):\n        return decode(result)\n\n    if isinstance(result, list) or isinstance(result, tuple):\n        return map(_handle_output_u, result)\n\n    if isinstance(result, dict):\n        for k, v in result.items():\n            result[k] = _handle_output_u(v)\n        return result\n\n    return result\n\n\ndef _handle_output_b(result):\n    \"\"\"Convert result to binary.\"\"\"\n    if not result:\n        return result\n\n    if isinstance(result, text_type):\n        return encode(result)\n\n    if isinstance(result, list) or isinstance(result, tuple):\n        return map(_handle_output_b, result)\n\n    if isinstance(result, dict):\n        for k, v in result.items():\n            result[k] = _handle_output_b(v)\n        return result\n\n    return result\n\n\ndef _varargs(*args):\n    \"\"\"Encode var arguments to utf-8 or fs encoding.\"\"\"\n    return [_handle_input(arg) for arg in args]\n\n\ndef _varkwargs(**kwargs):\n    \"\"\"Encode var keyword  arguments to utf-8.\"\"\"\n    return {k: _handle_input(arg) for k, arg in kwargs.items()}\n\n\ndef make_closure(f, handle_arg=None, handle_output=None):\n    \"\"\"Apply an input handler and output handler to a function.\n\n    Used to ensure UTF-8 encoding at input and output.\n    \"\"\"\n    return patch_output(patch_input(f, handle_arg), handle_output)\n\n\ndef patch_input(f, handle_arg=None):\n    \"\"\"Patch all args and kwargs of function f.\n\n    If handle_arg is None, just return the original function.\n    \"\"\"\n    def patched_input(*args, **kwargs):\n        return f(*[handle_arg(arg) for arg in args], **{k: handle_arg(arg) for k, arg in kwargs.items()})\n    return patched_input if callable(handle_arg) else f\n\n\ndef patch_output(f, handle_output=None):\n    \"\"\"Patch the output of function f with the handle_output function.\n\n    If handle_output is None, just return the original function.\n    \"\"\"\n    def patched_output(*args, **kwargs):\n        return handle_output(f(*args, **kwargs))\n    return patched_output if callable(handle_output) else f\n\n\ndef initialize():\n    \"\"\"Replace original functions if the fs encoding is not utf-8.\"\"\"\n    if hasattr(sys, '_called_from_test'):\n        return\n\n    affected_functions = {\n        certifi: ['where', 'old_where'],\n        glob: ['glob'],\n        io: ['open'],\n        os: ['access', 'chdir', 'listdir', 'makedirs', 'mkdir', 'remove',\n             'rename', 'renames', 'rmdir', 'stat', 'unlink', 'utime', 'walk'],\n        os.path: ['abspath', 'basename', 'dirname', 'exists', 'getctime', 'getmtime', 'getsize',\n                  'isabs', 'isdir', 'isfile', 'islink', 'join', 'normcase', 'normpath', 'realpath', 'relpath',\n                  'split', 'splitext'],\n        shutil: ['copyfile', 'copymode', 'move', 'rmtree'],\n        tarfile: ['is_tarfile'],\n    }\n\n    # pyOpenSSL 0.14-1 bug: it can't handle unicode input.\n    # pyOpenSSL fix -> https://github.com/pyca/pyopenssl/pull/209\n    # Our bug: https://github.com/pymedusa/Medusa/issues/1422\n    handle_output_map = {\n        certifi: _handle_output_b\n    }\n\n    if os.name != 'nt':\n        affected_functions[os].extend(['chmod', 'chown', 'link', 'statvfs', 'symlink'])\n\n    if not fs_encoding or fs_encoding.lower() not in ('utf-8', 'mbcs'):\n        handle_input = _handle_input\n    else:\n        handle_input = None\n\n    for k, v in affected_functions.items():\n        handle_output = handle_output_map.get(k, _handle_output_u)\n        for f in v:\n            setattr(k, f, make_closure(getattr(k, f), handle_input, handle_output))\n", "path": "medusa/init/filesystem.py"}], "after_files": [{"content": "# coding=utf-8\n\"\"\"Replace core filesystem functions.\"\"\"\n\nimport glob\nimport io\nimport os\nimport shutil\nimport sys\nimport tarfile\nimport tempfile # noqa # pylint: disable=unused-import\n\nimport certifi\n\nimport rarfile\n\nfrom six import binary_type, text_type\n\n\nfs_encoding = sys.getfilesystemencoding()\n\n\ndef encode(value):\n    \"\"\"Encode to bytes.\"\"\"\n    return value.encode('utf-8' if os.name != 'nt' else fs_encoding)\n\n\ndef decode(value):\n    \"\"\"Decode to unicode.\"\"\"\n    # on windows the returned info from fs operations needs to be decoded using fs encoding\n    return text_type(value, 'utf-8' if os.name != 'nt' else fs_encoding)\n\n\ndef _handle_input(arg):\n    \"\"\"Encode argument to utf-8 or fs encoding.\"\"\"\n    # on windows the input params for fs operations needs to be encoded using fs encoding\n    return encode(arg) if isinstance(arg, text_type) else arg\n\n\ndef _handle_output_u(result):\n    \"\"\"Convert result to unicode.\"\"\"\n    if not result:\n        return result\n\n    if isinstance(result, binary_type):\n        return decode(result)\n\n    if isinstance(result, list) or isinstance(result, tuple):\n        return map(_handle_output_u, result)\n\n    if isinstance(result, dict):\n        for k, v in result.items():\n            result[k] = _handle_output_u(v)\n        return result\n\n    return result\n\n\ndef _handle_output_b(result):\n    \"\"\"Convert result to binary.\"\"\"\n    if not result:\n        return result\n\n    if isinstance(result, text_type):\n        return encode(result)\n\n    if isinstance(result, list) or isinstance(result, tuple):\n        return map(_handle_output_b, result)\n\n    if isinstance(result, dict):\n        for k, v in result.items():\n            result[k] = _handle_output_b(v)\n        return result\n\n    return result\n\n\ndef _varargs(*args):\n    \"\"\"Encode var arguments to utf-8 or fs encoding.\"\"\"\n    return [_handle_input(arg) for arg in args]\n\n\ndef _varkwargs(**kwargs):\n    \"\"\"Encode var keyword  arguments to utf-8.\"\"\"\n    return {k: _handle_input(arg) for k, arg in kwargs.items()}\n\n\ndef make_closure(f, handle_arg=None, handle_output=None):\n    \"\"\"Apply an input handler and output handler to a function.\n\n    Used to ensure UTF-8 encoding at input and output.\n    \"\"\"\n    return patch_output(patch_input(f, handle_arg), handle_output)\n\n\ndef patch_input(f, handle_arg=None):\n    \"\"\"Patch all args and kwargs of function f.\n\n    If handle_arg is None, just return the original function.\n    \"\"\"\n    def patched_input(*args, **kwargs):\n        return f(*[handle_arg(arg) for arg in args], **{k: handle_arg(arg) for k, arg in kwargs.items()})\n    return patched_input if callable(handle_arg) else f\n\n\ndef patch_output(f, handle_output=None):\n    \"\"\"Patch the output of function f with the handle_output function.\n\n    If handle_output is None, just return the original function.\n    \"\"\"\n    def patched_output(*args, **kwargs):\n        return handle_output(f(*args, **kwargs))\n    return patched_output if callable(handle_output) else f\n\n\ndef initialize():\n    \"\"\"Replace original functions if the fs encoding is not utf-8.\"\"\"\n    if hasattr(sys, '_called_from_test'):\n        return\n\n    affected_functions = {\n        certifi: ['where', 'old_where'],\n        glob: ['glob'],\n        io: ['open'],\n        os: ['access', 'chdir', 'listdir', 'makedirs', 'mkdir', 'remove',\n             'rename', 'renames', 'rmdir', 'stat', 'unlink', 'utime', 'walk'],\n        os.path: ['abspath', 'basename', 'dirname', 'exists', 'getctime', 'getmtime', 'getsize',\n                  'isabs', 'isdir', 'isfile', 'islink', 'join', 'normcase', 'normpath', 'realpath', 'relpath',\n                  'split', 'splitext'],\n        shutil: ['copyfile', 'copymode', 'move', 'rmtree'],\n        tarfile: ['is_tarfile'],\n        rarfile: ['is_rarfile'],\n    }\n\n    # pyOpenSSL 0.14-1 bug: it can't handle unicode input.\n    # pyOpenSSL fix -> https://github.com/pyca/pyopenssl/pull/209\n    # Our bug: https://github.com/pymedusa/Medusa/issues/1422\n    handle_output_map = {\n        certifi: _handle_output_b\n    }\n\n    if os.name != 'nt':\n        affected_functions[os].extend(['chmod', 'chown', 'link', 'statvfs', 'symlink'])\n\n    if not fs_encoding or fs_encoding.lower() not in ('utf-8', 'mbcs'):\n        handle_input = _handle_input\n    else:\n        handle_input = None\n\n    for k, v in affected_functions.items():\n        handle_output = handle_output_map.get(k, _handle_output_u)\n        for f in v:\n            setattr(k, f, make_closure(getattr(k, f), handle_input, handle_output))\n", "path": "medusa/init/filesystem.py"}]}