Play images and video from Synology PhotoStation server

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. # -*- coding: utf-8 -*-
  2. """
  3. kodiswift.listitem
  4. ------------------
  5. This module contains the ListItem class, which acts as a wrapper
  6. for xbmcgui.ListItem.
  7. :copyright: (c) 2012 by Jonathan Beluch
  8. :license: GPLv3, see LICENSE for more details.
  9. """
  10. from __future__ import absolute_import
  11. import warnings
  12. from kodiswift import xbmcgui
  13. __all__ = ['ListItem']
  14. class ListItem(object):
  15. """A wrapper for the xbmcgui.ListItem class. The class keeps track
  16. of any set properties that xbmcgui doesn't expose getters for.
  17. """
  18. def __init__(self, label=None, label2=None, icon=None, thumbnail=None,
  19. path=None):
  20. """Defaults are an emtpy string since xbmcgui.ListItem will not
  21. accept None.
  22. """
  23. self._listitem = xbmcgui.ListItem(label=label, label2=label2, path=path)
  24. # The docs have the thumbnail property set as thumb
  25. # http://mirrors.kodi.tv/docs/python-docs/16.x-jarvis/xbmcgui.html#ListItem-setArt
  26. self._art = {'icon': icon, 'thumb': thumbnail}
  27. self._icon = icon
  28. self._path = path
  29. self._thumbnail = thumbnail
  30. self._context_menu_items = []
  31. self._played = False
  32. self._playable = False
  33. self.is_folder = True
  34. def get_context_menu_items(self):
  35. """Returns the list of currently set context_menu items."""
  36. return self._context_menu_items
  37. def add_context_menu_items(self, items, replace_items=False):
  38. """Adds context menu items. If replace_items is True all
  39. previous context menu items will be removed.
  40. """
  41. for label, action in items:
  42. assert isinstance(label, basestring)
  43. assert isinstance(action, basestring)
  44. if replace_items:
  45. self._context_menu_items = []
  46. self._context_menu_items.extend(items)
  47. self._listitem.addContextMenuItems(items, replace_items)
  48. @property
  49. def label(self):
  50. """
  51. Returns:
  52. str:
  53. """
  54. return self._listitem.getLabel()
  55. @label.setter
  56. def label(self, value):
  57. """
  58. Args:
  59. value (str):
  60. """
  61. self._listitem.setLabel(value)
  62. def get_label(self):
  63. warnings.warn('get_label is deprecated, use label property',
  64. DeprecationWarning)
  65. return self.label
  66. def set_label(self, value):
  67. warnings.warn('set_label is deprecated, use label property',
  68. DeprecationWarning)
  69. return self._listitem.setLabel(value)
  70. @property
  71. def label2(self):
  72. return self._listitem.getLabel2()
  73. @label2.setter
  74. def label2(self, value):
  75. self._listitem.setLabel2(value)
  76. def get_label2(self):
  77. warnings.warn('get_label2 is deprecated, use label2 property',
  78. DeprecationWarning)
  79. return self.label2
  80. def set_label2(self, value):
  81. warnings.warn('set_label2 is deprecated, use label2 property',
  82. DeprecationWarning)
  83. return self._listitem.setLabel2(value)
  84. @property
  85. def selected(self):
  86. return self._listitem.isSelected()
  87. @selected.setter
  88. def selected(self, value):
  89. self._listitem.select(value)
  90. def is_selected(self):
  91. warnings.warn('is_selected is deprecated, use selected property',
  92. DeprecationWarning)
  93. return self._listitem.isSelected()
  94. def select(self, selected_status=True):
  95. warnings.warn('select is deprecated, use selected property',
  96. DeprecationWarning)
  97. return self._listitem.select(selected_status)
  98. @property
  99. def icon(self):
  100. return self._art.get('icon')
  101. @icon.setter
  102. def icon(self, value):
  103. self._art['icon'] = value
  104. self._listitem.setArt(self._art)
  105. def get_icon(self):
  106. warnings.warn('get_icon is deprecated, use icon property',
  107. DeprecationWarning)
  108. return self.icon
  109. def set_icon(self, icon):
  110. warnings.warn('set_icon is deprecated, use icon property',
  111. DeprecationWarning)
  112. self.icon = icon
  113. return self.icon
  114. @property
  115. def thumbnail(self):
  116. return self._art.get('thumb')
  117. @thumbnail.setter
  118. def thumbnail(self, value):
  119. self._art['thumb'] = value
  120. self._listitem.setArt(self._art)
  121. def get_thumbnail(self):
  122. warnings.warn('get_thumbnail is deprecated, use thumbnail property',
  123. DeprecationWarning)
  124. return self.thumbnail
  125. def set_thumbnail(self, thumbnail):
  126. warnings.warn('set_thumbnail is deprecated, use thumbnail property',
  127. DeprecationWarning)
  128. self.thumbnail = thumbnail
  129. return self.thumbnail
  130. @property
  131. def poster(self):
  132. return self._art.get('poster')
  133. @poster.setter
  134. def poster(self, value):
  135. self._art['poster'] = value
  136. self._listitem.setArt(self._art)
  137. @property
  138. def path(self):
  139. return self._path
  140. @path.setter
  141. def path(self, value):
  142. self._path = value
  143. self._listitem.setPath(value)
  144. def get_path(self):
  145. warnings.warn('get_path is deprecated, use path property',
  146. DeprecationWarning)
  147. return self._path
  148. def set_path(self, path):
  149. warnings.warn('set_path is deprecated, use path property',
  150. DeprecationWarning)
  151. self._path = path
  152. return self._listitem.setPath(path)
  153. @property
  154. def playable(self):
  155. return self._playable
  156. @playable.setter
  157. def playable(self, value):
  158. self._playable = value
  159. is_playable = 'true' if self._playable else 'false'
  160. self.set_property('isPlayable', is_playable)
  161. def get_is_playable(self):
  162. warnings.warn('get_is_playable is deprecated, use playable property',
  163. DeprecationWarning)
  164. return self._playable
  165. def set_is_playable(self, is_playable):
  166. warnings.warn('set_is_playable is deprecated, use playable property',
  167. DeprecationWarning)
  168. self._playable = is_playable
  169. value = 'false'
  170. if is_playable:
  171. value = 'true'
  172. self.set_property('isPlayable', value)
  173. @property
  174. def played(self):
  175. return self._played
  176. @played.setter
  177. def played(self, value):
  178. self._played = value
  179. def set_played(self, was_played):
  180. """Sets the played status of the listitem.
  181. Used to differentiate between a resolved video versus a playable item.
  182. Has no effect on Kodi, it is strictly used for kodiswift.
  183. """
  184. warnings.warn('set_played is deprecated, use played property',
  185. DeprecationWarning)
  186. self._played = was_played
  187. def get_played(self):
  188. warnings.warn('get_played is deprecated, use played property',
  189. DeprecationWarning)
  190. return self._played
  191. @property
  192. def art(self):
  193. return self._art
  194. @art.setter
  195. def art(self, value):
  196. self._art = value
  197. self._listitem.setArt(value)
  198. def set_art(self, value):
  199. self._art = value
  200. self._listitem.setArt(value)
  201. def set_info(self, info_type, info_labels):
  202. """Sets the listitem's info"""
  203. return self._listitem.setInfo(info_type, info_labels)
  204. def get_property(self, key):
  205. """Returns the property associated with the given key"""
  206. return self._listitem.getProperty(key)
  207. def set_property(self, key, value):
  208. """Sets a property for the given key and value"""
  209. return self._listitem.setProperty(key, value)
  210. def add_stream_info(self, stream_type, stream_values):
  211. """Adds stream details"""
  212. return self._listitem.addStreamInfo(stream_type, stream_values)
  213. def as_tuple(self):
  214. """Returns a tuple of list item properties:
  215. (path, the wrapped xbmcgui.ListItem, is_folder)
  216. """
  217. return self.path, self._listitem, self.is_folder
  218. def as_xbmc_listitem(self):
  219. """Returns the wrapped xbmcgui.ListItem"""
  220. return self._listitem
  221. @classmethod
  222. def from_dict(cls, label=None, label2=None, icon=None, thumbnail=None,
  223. path=None, selected=None, info=None, properties=None,
  224. context_menu=None, replace_context_menu=False,
  225. is_playable=None, info_type='video', stream_info=None,
  226. **kwargs):
  227. """A ListItem constructor for setting a lot of properties not
  228. available in the regular __init__ method. Useful to collect all
  229. the properties in a dict and then use the **dct to call this
  230. method.
  231. """
  232. # TODO(Sinap): Should this just use **kwargs? or should art be a dict?
  233. listitem = cls(label, label2, path=path)
  234. listitem.art = {
  235. 'icon': icon,
  236. 'thumb': thumbnail,
  237. 'poster': kwargs.get('poster'),
  238. 'banner': kwargs.get('banner'),
  239. 'fanart': kwargs.get('fanart'),
  240. 'landscape': kwargs.get('landscape'),
  241. }
  242. if selected is not None:
  243. listitem.selected = selected
  244. if info:
  245. listitem.set_info(info_type, info)
  246. if is_playable:
  247. listitem.playable = True
  248. listitem.is_folder = False # III
  249. if properties:
  250. # Need to support existing tuples, but prefer to have a dict for
  251. # properties.
  252. if hasattr(properties, 'items'):
  253. properties = properties.items()
  254. for key, val in properties:
  255. listitem.set_property(key, val)
  256. if stream_info:
  257. for stream_type, stream_values in stream_info.items():
  258. listitem.add_stream_info(stream_type, stream_values)
  259. if context_menu:
  260. listitem.add_context_menu_items(context_menu, replace_context_menu)
  261. return listitem
  262. def __eq__(self, other):
  263. if not isinstance(other, ListItem):
  264. raise NotImplementedError
  265. self_props = (self.label, self.label2, self.art, self.path,
  266. self.playable, self.selected, self.played,)
  267. other_props = (other.label, other.label2, other.art, other.path,
  268. other.playable, other.selected, other.played,)
  269. return self_props == other_props
  270. def __str__(self):
  271. return ('%s (%s)' % (self.label, self.path)).encode('utf-8')
  272. def __repr__(self):
  273. return ("<ListItem '%s'>" % self.label).encode('utf-8')