Plex plugin to to play various online streams (mostly Latvian).

bootstrap.py 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import errno
  2. import os
  3. import config
  4. BUNDLED_PLUGINS_PATH_KEY = 'PLEXBUNDLEDPLUGINSPATH'
  5. LOCAL_APP_DATA_KEY = 'PLEXLOCALAPPDATA'
  6. framework_dir_template = os.path.join('Framework.bundle', 'Contents')
  7. plugins_path_template = os.path.join(framework_dir_template, 'Resources', 'Versions', '%i', 'Python')
  8. shared_libs_path_template = os.path.join(framework_dir_template, 'Resources', 'Platforms', 'Shared', 'Libraries')
  9. framework_versions = [2, 1, 0]
  10. plugin_bundle_path_template = ['Plex Media Server', 'Plug-ins', '.bundle', 'Contents']
  11. plugin_bundle_key = 2
  12. # Raise error if in the environment variable key is not set or its value is not a directory.
  13. def validate_directory(key):
  14. if not os.environ[key]:
  15. raise ValueError('Environment variable %s is empty' % key)
  16. elif not os.path.isdir(os.environ[key]):
  17. raise OSError(errno.ENOTDIR, os.strerror(errno.ENOENT), os.environ[key])
  18. # Determine whether the path in the argument is a framework version path and returns it, or None.
  19. def pick_framework_path(path_arg):
  20. if not path_arg.endswith('Python'):
  21. return None
  22. for version in framework_versions:
  23. path = plugins_path_template % version
  24. if path_arg.endswith(path):
  25. return path
  26. return None
  27. # Find the current plugin bundle directory based on assumption that the current file is in some of its subdirectories.
  28. def find_bundle_directory(path_arg):
  29. if not __file__.startswith(path_arg):
  30. raise ValueError('File path (%s) expected to start with %s' % (__file__, path_arg))
  31. bundle_parts = [path_arg.rstrip(os.sep)]
  32. parts = __file__[len(path_arg):].split(os.sep)
  33. for index, actual_name in enumerate(parts):
  34. if index >= len(plugin_bundle_path_template):
  35. break
  36. expected_name = plugin_bundle_path_template[index]
  37. if index != plugin_bundle_key and actual_name != expected_name:
  38. raise ValueError('Unexpected directory name in %s, expected %s' % (__file__, actual_name))
  39. elif index == plugin_bundle_key and not actual_name.endswith(expected_name):
  40. raise ValueError('Unexpected directory name in %s, expected to end with %s' % (__file__, actual_name))
  41. if index <= plugin_bundle_key:
  42. bundle_parts.append(actual_name)
  43. return os.path.join(*bundle_parts)
  44. # Try autodetect `PLEXLOCALAPPDATA` environment variable if not already set.
  45. if LOCAL_APP_DATA_KEY not in os.environ:
  46. def find_plex_local_app_data_path():
  47. if 'LOCALAPPDATA' not in os.environ:
  48. raise KeyError('Environment variable %s is not set' % 'LOCALAPPDATA')
  49. return os.environ['LOCALAPPDATA'] + os.sep
  50. os.environ[LOCAL_APP_DATA_KEY] = find_plex_local_app_data_path()
  51. validate_directory(LOCAL_APP_DATA_KEY)
  52. # Try autodetect `PLEXBUNDLEDPLUGINSPATH` environment variable if not already set.
  53. if BUNDLED_PLUGINS_PATH_KEY not in os.environ:
  54. def find_plex_bundled_plugins_path():
  55. for sys_path in os.sys.path:
  56. path = pick_framework_path(sys_path)
  57. if path is not None:
  58. bundle_path = sys_path[:-len(path)]
  59. return bundle_path.rstrip(os.sep)
  60. os.environ[BUNDLED_PLUGINS_PATH_KEY] = find_plex_bundled_plugins_path()
  61. validate_directory(BUNDLED_PLUGINS_PATH_KEY)
  62. # Add shared libraries path if not already added.
  63. def setup_shared_libs_path(bundled_plugins_path):
  64. path = os.path.join(bundled_plugins_path, shared_libs_path_template)
  65. if path not in os.sys.path:
  66. os.sys.path.append(path)
  67. setup_shared_libs_path(os.environ[BUNDLED_PLUGINS_PATH_KEY])
  68. # Remove and re-add framework paths in `sys.path` as they may have been added in the wrong order.
  69. def setup_framework_paths(bundled_plugins_path):
  70. def make_framework_path(version):
  71. return os.path.join(bundled_plugins_path, plugins_path_template) % version
  72. version_index = 0
  73. for path_index, sys_path in enumerate(os.sys.path):
  74. if version_index not in framework_versions:
  75. break
  76. path = pick_framework_path(sys_path)
  77. if path is not None:
  78. os.sys.path[path_index] = make_framework_path(framework_versions[version_index])
  79. version_index += 1
  80. for version_index in range(version_index, len(framework_versions)):
  81. os.sys.path.append(make_framework_path(framework_versions[version_index]))
  82. setup_framework_paths(os.environ[BUNDLED_PLUGINS_PATH_KEY])
  83. # Set module variables useful for framework initialization inside test case.
  84. #bbundle_directory = find_bundle_directory(os.environ[LOCAL_APP_DATA_KEY])
  85. bundle_directory = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
  86. framework_directory = os.path.join(os.environ[BUNDLED_PLUGINS_PATH_KEY], plugins_path_template, '..')
  87. framework_directory = os.path.abspath(framework_directory) % 2
  88. # Import subsystem to install some built-ins required by framework.
  89. import subsystem