Kodi plugin to to play various online streams (mostly Latvian)

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. # -*- coding: utf-8 -*-
  2. """
  3. kodiswift.module
  4. -----------------
  5. This module contains the Module Class.
  6. :copyright: (c) 2012 by Jonathan Beluch
  7. :license: GPLv3, see LICENSE for more details.
  8. """
  9. from __future__ import absolute_import
  10. from kodiswift import setup_log
  11. from kodiswift.xbmcmixin import XBMCMixin
  12. __all__ = ['Module']
  13. class Module(XBMCMixin):
  14. """Modules are basically mini plugins except they don't have any
  15. functionality until they are registered with a Plugin.
  16. """
  17. def __init__(self, namespace):
  18. # Get rid of package prefixes
  19. self._namespace = namespace.split('.')[-1]
  20. self._view_functions = {}
  21. self._routes = []
  22. self._register_funcs = []
  23. self._plugin = None
  24. self._url_prefix = None
  25. self._log = setup_log(namespace)
  26. @property
  27. def plugin(self):
  28. """Returns the plugin this module is registered to, or
  29. Returns:
  30. kodiswift.Plugin:
  31. Raises:
  32. RuntimeError: If not registered
  33. """
  34. if self._plugin is None:
  35. raise RuntimeError('Module must be registered in order to call'
  36. 'this method.')
  37. return self._plugin
  38. @plugin.setter
  39. def plugin(self, value):
  40. self._plugin = value
  41. @property
  42. def cache_path(self):
  43. """Returns the module's cache_path."""
  44. return self.plugin.storage_path
  45. @property
  46. def addon(self):
  47. """Returns the module's addon"""
  48. return self.plugin.addon
  49. @property
  50. def added_items(self):
  51. """Returns this module's added_items"""
  52. return self.plugin.added_items
  53. @property
  54. def handle(self):
  55. """Returns this module's handle"""
  56. return self.plugin.handle
  57. @property
  58. def request(self):
  59. """Returns the current request"""
  60. return self.plugin.request
  61. @property
  62. def log(self):
  63. """Returns the registered plugin's log."""
  64. return self._log
  65. @property
  66. def url_prefix(self):
  67. """Sets or gets the url prefix of the module.
  68. Raises an Exception if this module is not registered with a
  69. Plugin.
  70. Returns:
  71. str:
  72. Raises:
  73. RuntimeError:
  74. """
  75. if self._url_prefix is None:
  76. raise RuntimeError(
  77. 'Module must be registered in order to call this method.')
  78. return self._url_prefix
  79. @url_prefix.setter
  80. def url_prefix(self, value):
  81. self._url_prefix = value
  82. @property
  83. def register_funcs(self):
  84. return self._register_funcs
  85. def route(self, url_rule, name=None, options=None):
  86. """A decorator to add a route to a view. name is used to
  87. differentiate when there are multiple routes for a given view."""
  88. def decorator(func):
  89. """Adds a url rule for the provided function"""
  90. view_name = name or func.__name__
  91. self.add_url_rule(url_rule, func, name=view_name, options=options)
  92. return func
  93. return decorator
  94. def url_for(self, endpoint, explicit=False, **items):
  95. """Returns a valid Kodi plugin URL for the given endpoint name.
  96. endpoint can be the literal name of a function, or it can
  97. correspond to the name keyword arguments passed to the route
  98. decorator.
  99. Currently, view names must be unique across all plugins and
  100. modules. There are not namespace prefixes for modules.
  101. """
  102. # TODO: Enable items to be passed with keywords of other var names
  103. # such as endpoing and explicit
  104. # TODO: Figure out how to handle the case where a module wants to
  105. # call a parent plugin view.
  106. if not explicit and not endpoint.startswith(self._namespace):
  107. endpoint = '%s.%s' % (self._namespace, endpoint)
  108. return self._plugin.url_for(endpoint, **items)
  109. def add_url_rule(self, url_rule, view_func, name, options=None):
  110. """This method adds a URL rule for routing purposes. The
  111. provided name can be different from the view function name if
  112. desired. The provided name is what is used in url_for to build
  113. a URL.
  114. The route decorator provides the same functionality.
  115. """
  116. name = '%s.%s' % (self._namespace, name)
  117. def register_rule(plugin, url_prefix):
  118. """Registers a url rule for the provided plugin and
  119. url_prefix.
  120. """
  121. full_url_rule = url_prefix + url_rule
  122. plugin.add_url_rule(full_url_rule, view_func, name, options)
  123. # Delay actual registration of the url rule until this module is
  124. # registered with a plugin
  125. self._register_funcs.append(register_rule)