Repository: pymedusa/Medusa

Issue:
Update to 0.2.9 makes medusa fail to start ext/adba no module named configparser
**Describe the bug**
I upgraded to 0.2.9 from 0.2.8 and Medusa would no longer start. The problem seems to be 
related to adba. It tries to load an external module configparser import ConfigParser but it fails
to find the module and exits.

**To Reproduce**
Start medusa after upgrading to 0.2.9

**Expected behavior**
Medusa should start as usual instead of failing and exiting.

**Medusa (please complete the following information):**
 - OS: archlinux 4.18.5
 - Branch: master
 - Commit:  db3d9d7

**Logs:**

```
Sep 07 08:07:56 norm env[30534]:   File "/opt/Medusa/medusa/scene_exceptions.py", line 13, in <module>
Sep 07 08:07:56 norm env[30534]:     import adba
Sep 07 08:07:56 norm env[30534]:   File "/opt/Medusa/ext/adba/__init__.py", line 27, in <module>
Sep 07 08:07:56 norm env[30534]:     from configparser import ConfigParser
Sep 07 08:07:56 norm env[30534]:   File "/opt/Medusa/ext/configparser.py", line 12, in <module>
Sep 07 08:07:56 norm env[30534]:     from backports.configparser import (
Sep 07 08:07:56 norm env[30534]: ImportError: No module named configparser
Sep 07 08:07:56 norm systemd[882]: medusa.service: Control process exited, code=exited status=1
Sep 07 08:07:56 norm systemd[882]: medusa.service: Failed with result 'exit-code'.
Sep 07 08:07:56 norm systemd[882]: Failed to start Medusa user service.


Sep 07 08:07:56 norm env[30534]: Traceback (most recent call last):
Sep 07 08:07:56 norm env[30534]:   File "/opt/Medusa/start.py", line 6, in <module>
Sep 07 08:07:56 norm env[30534]:     from medusa.__main__ import main
Sep 07 08:07:56 norm env[30534]:   File "/opt/Medusa/medusa/__main__.py", line 67, in <module>
Sep 07 08:07:56 norm env[30534]:     from medusa import (
Sep 07 08:07:56 norm env[30534]:   File "/opt/Medusa/medusa/name_cache.py", line 12, in <module>
Sep 07 08:07:56 norm env[30534]:     from medusa.scene_exceptions import (
Sep 07 08:07:56 norm env[30534]:   File "/opt/Medusa/medusa/scene_exceptions.py", line 13, in <module>
Sep 07 08:07:56 norm env[30534]:     import adba
Sep 07 08:07:56 norm env[30534]:   File "/opt/Medusa/ext/adba/__init__.py", line 27, in <module>
Sep 07 08:07:56 norm env[30534]:     from configparser import ConfigParser
Sep 07 08:07:56 norm env[30534]:   File "/opt/Medusa/ext/configparser.py", line 12, in <module>
Sep 07 08:07:56 norm env[30534]:     from backports.configparser import (
Sep 07 08:07:56 norm env[30534]: ImportError: No module named configparser
Sep 07 08:07:56 norm systemd[882]: medusa.service: Control process exited, code=exited status=1
Sep 07 08:07:56 norm systemd[882]: medusa.service: Failed with result 'exit-code'.

```
</details>

**Additional context**

I'm guessing the problem is related to this adba commit:

https://github.com/pymedusa/Medusa/pull/4822






Discussion:
@sharkykh eeh i included backports? 
How do you start medusa?
Whats you python version? 
@p0psicles Possibly related... Old `pyc` files?
https://github.com/pymedusa/Medusa/issues/3184
I start medusa as a systemd user service. Python version is 2.7.15

Not old pyc files (I moved my old install directory and cloned a brand new directory to test before I posted the issue...that had the same problem, so then I checked out the previous release and everything works again)
Here is the unit file that I use to launch Medusa as a systemd user service. You can see the options that I pass to Medusa in the ExecStart line, in case that is relevant to the issue.

[Unit]
Description=Medusa user service
Wants=network-online.target
After=network-online.target

[Service]

Type=forking
GuessMainPID=no
ExecStart=/usr/bin/env python2 /opt/Medusa/start.py --quiet --nolaunch --daemon --datadir %h/.medusa

[Install]
WantedBy=default.target

I was just able to reproduce... kind of.

I removed `ext/backports/__init__.py`, and then `cd`'d to `ext/` and tried to import:

```
@ /dev/medusa
$ rm ext/backports/__init__.py
$ cd ext/
$ python -c "import configparser"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "configparser.py", line 12, in <module>
    from backports.configparser import (
ImportError: No module named configparser
```

@jtwill 
1. Can you check that file? `ext/backports/__init__.py`
Contents should be:
```py
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
```
2. Try `/usr/bin/python2 /opt/Medusa/start.py [args]` (remove `/env `)... It's a long shot though
I git cloned a new copy from Master and then checked the file:

```
$ cat /opt/Medusa/ext/backports/__init__.py 
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
```

Looks okay to me. I changed my systemd unit file as shown:

```
[Unit]
Description=Medusa user service
Wants=network-online.target
After=network-online.target

[Service]

Type=forking
GuessMainPID=no
#ExecStart=/usr/bin/env python2 /opt/Medusa/start.py --quiet --nolaunch --daemon --datadir %h/.medusa
ExecStart=/usr/bin/python2.7 /opt/Medusa/start.py --quiet --nolaunch --daemon --datadir %h/.medusa

[Install]
WantedBy=default.target

```

Same problem, here is the systemd log on attempted start:

```
-- Unit UNIT has begun starting up.
Sep 07 18:01:04 norm python2.7[6088]: Traceback (most recent call last):
Sep 07 18:01:04 norm python2.7[6088]:   File "/opt/Medusa/start.py", line 6, in <module>
Sep 07 18:01:04 norm python2.7[6088]:     from medusa.__main__ import main
Sep 07 18:01:04 norm python2.7[6088]:   File "/opt/Medusa/medusa/__main__.py", line 67, in <module>
Sep 07 18:01:04 norm python2.7[6088]:     from medusa import (
Sep 07 18:01:04 norm python2.7[6088]:   File "/opt/Medusa/medusa/name_cache.py", line 12, in <module>
Sep 07 18:01:04 norm python2.7[6088]:     from medusa.scene_exceptions import (
Sep 07 18:01:04 norm python2.7[6088]:   File "/opt/Medusa/medusa/scene_exceptions.py", line 13, in <module>
Sep 07 18:01:04 norm python2.7[6088]:     import adba
Sep 07 18:01:04 norm python2.7[6088]:   File "/opt/Medusa/ext/adba/__init__.py", line 27, in <module>
Sep 07 18:01:04 norm python2.7[6088]:     from configparser import ConfigParser
Sep 07 18:01:04 norm python2.7[6088]:   File "/opt/Medusa/ext/configparser.py", line 12, in <module>
Sep 07 18:01:04 norm python2.7[6088]:     from backports.configparser import (
Sep 07 18:01:04 norm python2.7[6088]: ImportError: No module named configparser
Sep 07 18:01:04 norm systemd[882]: medusa.service: Control process exited, code=exited status=1
Sep 07 18:01:04 norm systemd[882]: medusa.service: Failed with result 'exit-code'.
Sep 07 18:01:04 norm systemd[882]: Failed to start Medusa user service.
-- Subject: Unit UNIT has failed

```


I also tried launching it from the command line, to eliminate any unknown systemd interactions. Same error:

```
$ /usr/bin/python2 "/opt/Medusa/start.py" --quiet --nolaunch --datadir "/home/user/.medusa"
Traceback (most recent call last):
  File "/opt/Medusa/start.py", line 6, in <module>
    from medusa.__main__ import main
  File "/opt/Medusa/medusa/__main__.py", line 67, in <module>
    from medusa import (
  File "/opt/Medusa/medusa/name_cache.py", line 12, in <module>
    from medusa.scene_exceptions import (
  File "/opt/Medusa/medusa/scene_exceptions.py", line 13, in <module>
    import adba
  File "/opt/Medusa/ext/adba/__init__.py", line 27, in <module>
    from configparser import ConfigParser
  File "/opt/Medusa/ext/configparser.py", line 12, in <module>
    from backports.configparser import (
ImportError: No module named configparser
```


Resolving patch:
diff --git a/ext/backports/__init__.py b/ext/backports/__init__.py
deleted file mode 100644
--- a/ext/backports/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-from pkgutil import extend_path
-__path__ = extend_path(__path__, __name__)
diff --git a/medusa/init/__init__.py b/medusa/init/__init__.py
--- a/medusa/init/__init__.py
+++ b/medusa/init/__init__.py
@@ -8,6 +8,7 @@
 import mimetypes
 import os
 import shutil
+import site
 import sys
 
 
@@ -46,8 +47,39 @@ def _ext_lib_location():
 
 
 def _configure_syspath():
-    sys.path.insert(1, _lib_location())
-    sys.path.insert(1, _ext_lib_location())
+    """Add the vendored libraries into `sys.path`."""
+    # Note: These paths will be inserted into `sys.path` in reverse order (LIFO)
+    # So the last path on this list will be inserted as the first path on `sys.path`
+    # right after the current working dir.
+    # For example: [ cwd, pathN, ..., path1, path0, <rest_of_sys.path> ]
+
+    paths_to_insert = [
+        _lib_location(),
+        _ext_lib_location()
+    ]
+
+    if sys.version_info[0] == 2:
+        # Add Python 2-only vendored libraries
+        paths_to_insert.extend([
+            # path_to_lib2,
+            # path_to_ext2
+        ])
+    elif sys.version_info[0] == 3:
+        # Add Python 3-only vendored libraries
+        paths_to_insert.extend([
+            # path_to_lib3,
+            # path_to_ext3
+        ])
+
+    # Insert paths into `sys.path` and handle `.pth` files
+    # Inspired by: https://bugs.python.org/issue7744
+    for dirpath in paths_to_insert:
+        # Clear `sys.path`
+        sys.path, remainder = sys.path[:1], sys.path[1:]
+        # Add directory as a site-packages directory and handle `.pth` files
+        site.addsitedir(dirpath)
+        # Restore rest of `sys.path`
+        sys.path.extend(remainder)
 
 
 def _register_utf8_codec():


Test patch: