Play images and video from Synology PhotoStation server

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. # -*- coding: utf-8 -*-
  2. try:
  3. import wingdbstub
  4. except:
  5. pass
  6. import os,os.path,sys, urllib, urlparse
  7. #import xbmc, xbmcgui, xbmcplugin, xbmcvfs, xbmcaddon
  8. from kodiswift import Plugin, ListItem, storage
  9. from kodiswift import xbmc, xbmcgui, xbmcplugin, xbmcvfs, xbmcaddon, CLI_MODE, SortMethod
  10. from resources.lib import photostation_api
  11. plugin = Plugin()
  12. handle = sys.argv[1]
  13. view_mode = plugin.get_setting("view_mode",str)
  14. server = plugin.get_setting("server", str)
  15. user = plugin.get_setting("user", str)
  16. password = plugin.get_setting("password", str)
  17. page_size = plugin.get_setting("page_size", str)
  18. page_size = -1 if page_size == "All" else int(page_size)
  19. sorting = plugin.get_setting("sorting", str)
  20. order = plugin.get_setting("order", str)
  21. video_quality = plugin.get_setting("video_quality", str)
  22. picture_quality = plugin.get_setting("picture_quality", str)
  23. thumbnail_quality = plugin.get_setting("thumbnail_quality", str)
  24. play_next = plugin.get_setting("play_next", bool)
  25. start_page = plugin.get_setting("start_page", str)
  26. ps = photostation_api.PhotoStationAPI("http://home.blue.lv/photo")
  27. try:
  28. ps.login(user, password)
  29. except Exception as e:
  30. print "Error while logging %s/%s"%(user,password)
  31. plugin.notify(str(e),"",10000)
  32. prefix = ""
  33. @plugin.route(".+" )
  34. def main():
  35. # plugin://xxx/
  36. global prefix
  37. prefix = "%s://%s/"%(plugin.request.scheme,plugin.request.netloc)
  38. data = plugin.request.url.replace(prefix,"")
  39. data = urllib.unquote(data)
  40. #default_oid = "album_323031372f323031372d30312d313320536c69646f73616e61"
  41. default_oid = "" #start_page
  42. if not data:
  43. data = default_oid
  44. oid = plugin.request.path[1:]
  45. if not oid:
  46. oid = default_oid
  47. qs = dict(urlparse.parse_qsl(plugin.request.query_string))
  48. if not "page" in qs:
  49. page = 1
  50. else:
  51. page = int(qs["page"])
  52. if not oid or oid.startswith("album") or oid.startswith("category"):
  53. plugin.set_content("images")
  54. content = []
  55. if not oid:
  56. categories = ps.get_categories()["categories"]
  57. for cat in categories:
  58. if cat["hidden"]:
  59. continue
  60. data2 = prefix + cat["id"]
  61. label = cat["name"]
  62. item = xbmcgui.ListItem(label, "", "", "", data2)
  63. item.setInfo("Image", {"title":label})
  64. item.setProperty("is_folder", "true")
  65. item.setProperty("url", data2)
  66. #items.append(item)
  67. xbmcplugin.addDirectoryItem(handle=plugin.handle, url=data2, listitem=item, isFolder=True)
  68. offset = 0 if page_size == -1 else (page - 1) * page_size
  69. limit = -1 if page_size == -1 else page_size
  70. if "category" in oid:
  71. content = ps.get_category_list(oid)
  72. else:
  73. content = ps.get_album_list(oid, offset=offset, limit=limit, sort_by=sorting, sort_direction=order )
  74. items = []
  75. for f in content["items"]:
  76. label = f["info"]["title"]
  77. label2 = f["additional"]["file_location"] if "file_location" in f["additional"] else ""
  78. type = f["type"]
  79. oid2 = f["id"]
  80. is_playable = "true" if type in ("video","photo") else ""
  81. is_folder = "" if type in ("video","photo") else "true"
  82. thumb_quality = thumbnail_quality if thumbnail_quality in f["thumbnail_status"] else "small"
  83. thumb_url = ps.get_thumb_url(f["id"],thumb_quality)
  84. #thumb_url = urllib.quote(thumb_url, ":/")
  85. data2 = prefix+f["id"]
  86. if type=="album":
  87. nfiles = int(f["additional"]["item_count"]["photo"]) + int(f["additional"]["item_count"]["video"]) if "item_count" in f["additional"] else None
  88. suf = "\n(%s)" % nfiles if nfiles else ""
  89. label2 = "%s photos, %s videos"%(f["additional"]["item_count"]["photo"],f["additional"]["item_count"]["video"]) if "item_count" in f["additional"] else ""
  90. label = label + suf
  91. li_type = "video" # pictures
  92. tags = {
  93. #"title":f["info"]["title"],
  94. "title": label,
  95. #"picturepath":f["additional"]["file_location"]
  96. "label": label,
  97. "plotline":f["additional"]["file_location"] + "\n" + label2 if "file_location" in f["additional"] else "",
  98. "plot":f["additional"]["file_location"] + "\n" + label2 if "file_location" in f["additional"] else "",
  99. "path": f["info"]["sharepath"] if "sharepath" in f["additional"] else "",
  100. }
  101. elif type == "photo":
  102. label = label + "\n" + f["info"]["takendate"]
  103. label2 = f["info"]["takendate"]
  104. image_url = ps.get_photo_url(oid2) if picture_quality == "original" else ps.get_thumb_url(oid2, picture_quality)
  105. data2 = image_url
  106. #print "image_url=", data2
  107. #data2 = urllib.quote(data2, ":/")
  108. li_type = "pictures"
  109. tags = {
  110. "title": label2, #f["info"]["title"],
  111. "date": f["info"]["takendate"],
  112. "picturepath": f["additional"]["file_location"],
  113. "exif:resolution": "%s,%s" % (f["info"]["resolutionx"], f["info"]["resolutiony"]),
  114. #"exif:path": f["additional"]["file_location"],
  115. #"exif:name": f["info"]["name"],
  116. #"exif:filename": f["additional"]["file_location"],
  117. #"exif:"
  118. # TODO pārejie EXIF u.c. dati
  119. }
  120. elif type=="video":
  121. label = label + "\n" + f["info"]["takendate"]
  122. label2 = f["info"]["takendate"]
  123. li_type = 'video'
  124. tags = {
  125. "title": label ,
  126. "plot": f["additional"]["file_location"],
  127. #TODO
  128. }
  129. if play_next:
  130. data2 = data2 + "&album=" + oid if "?" in data2 else data2 + "?album=" + oid
  131. #data2 = urllib.quote(data2, ":/")
  132. is_playable = ""
  133. else:
  134. if video_quality == "original":
  135. quality_id = ""
  136. else:
  137. quality_id = f["additional"]["video_quality"][0]["id"]
  138. data2 = ps.get_video_url(oid2, quality_id)
  139. #data2 = urllib.quote(data2, ":/")
  140. item = xbmcgui.ListItem(label=label, label2=label2, path=data2)
  141. item.setArt({
  142. "thumb": thumb_url,
  143. "icon": thumb_url,
  144. "fanart": thumb_url,
  145. })
  146. item.setInfo(li_type, tags)
  147. item.setProperty("is_folder", is_folder)
  148. item.setProperty('IsPlayable', is_playable)
  149. item.setProperty("url", data2)
  150. #items.append(item)
  151. xbmcplugin.addDirectoryItem(handle=plugin.handle, url=data2, listitem=item, isFolder=True if is_folder=="true" else False,
  152. totalItems=len(content["items"]))
  153. if page_size <> -1 and len(content["items"]) == page_size:
  154. data2 = prefix+oid+"?page=%s" % (page+1)
  155. #data2 = urllib.quote(data2, ":/")
  156. item = xbmcgui.ListItem("Next", "", "", "", data2)
  157. item.setInfo("Image", {"title":"Next"})
  158. item.setProperty("is_folder", "false")
  159. item.setProperty("url", data2)
  160. #items.append(item)
  161. xbmcplugin.addDirectoryItem(handle=plugin.handle, url=data2, listitem=item, isFolder=True,
  162. totalItems=len(content["items"]))
  163. view_mode_id = get_view_mode(view_mode)
  164. xbmc.executebuiltin('Container.SetViewMode(%s)' % view_mode_id)
  165. #sort_methods = [SortMethod.FILE, SortMethod.DATE, SortMethod.DATE_TAKEN]
  166. #xbmcplugin.addSortMethod( plugin.handle, sortMethod=xbmcplugin.SORT_METHOD_GENRE )
  167. xbmcplugin.endOfDirectory(plugin.handle, succeeded=True, updateListing=False, cacheToDisc=True)
  168. #return plugin.finish(items, sort_methods=None, view_mode=view_mode_id, cache_to_disc=True, update_listing=False)
  169. elif oid.startswith("photo"):
  170. print "play_photo ", oid
  171. try:
  172. url = ps.get_thumb_url(oid,"large")
  173. #thumb_url = ps.get_thumb_url(oid,"smalll")
  174. #js = ps.get_photo_info(oid)
  175. #title = js["info"]["name"]
  176. except Exception,e:
  177. plugin.notify(str(e),"",10000)
  178. return None
  179. print "set_resolved_url", url
  180. plugin.set_resolved_url(url)
  181. elif oid.startswith("video"):
  182. if play_next and "album" in qs: # play playlist
  183. print "play_playlist", data, qs
  184. album_id = qs["album"]
  185. try:
  186. items = ps.get_album_list(album_id)
  187. except Exception,e:
  188. plugin.notify(str(e),"",10000)
  189. return None
  190. if items:
  191. play_playlist(items["items"], oid)
  192. return None
  193. else:
  194. plugin.notify("No items found!",10000)
  195. return None
  196. else: # play one video
  197. print "play_video"
  198. try:
  199. streams = ps.get_video_streams(oid)
  200. js = ps.get_photo_info(oid)
  201. except Exception,e:
  202. plugin.notify(str(e),"",10000)
  203. return None
  204. if streams:
  205. play_video(streams)
  206. return None
  207. else:
  208. plugin.notify("No streams found!",10000)
  209. return None
  210. def get_view_mode(vm):
  211. modes = {
  212. "skin.estuary": {
  213. "None": None,
  214. "List": 50,
  215. "Poster": 51,
  216. "IconWall":52 ,
  217. "Shift": 53,
  218. "InfoWall": 54,
  219. "WideList": 55,
  220. "Wall": 500,
  221. "Banner": 501,
  222. "FanArt": 502
  223. }
  224. }
  225. skin = xbmc.getSkinDir()
  226. if skin in modes and vm in modes[skin]:
  227. view_mode = modes[skin][vm]
  228. else:
  229. view_mode = 500
  230. return view_mode
  231. def play_playlist(items, oid):
  232. playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
  233. playlist.clear()
  234. pos = -1
  235. i = 0
  236. for f in items:
  237. if f["type"] in ("album","photo"):
  238. continue
  239. label = f["info"]["name"] + "\n" + f["info"]["takendate"]
  240. label2 = f["additional"]["file_location"]
  241. type = f["type"]
  242. oid2 = f["id"]
  243. if oid == oid2:
  244. pos = i
  245. #is_playable = True if type in ("video","photo") else False
  246. is_folder = False if type in ("video","photo") else True
  247. thumb_quality = thumbnail_quality if thumbnail_quality in f["thumbnail_status"] else "small"
  248. thumb_url = ps.get_thumb_url(f["id"],thumb_quality)
  249. data2 = prefix+f["id"]
  250. item = xbmcgui.ListItem(label, label2, path=data2)
  251. item.setArt({
  252. "thumb": thumb_url,
  253. "icon": thumb_url,
  254. "fanart": thumb_url,
  255. })
  256. item.setLabel2(label2)
  257. item.setInfo(
  258. 'video', {
  259. "title": label,
  260. "plot": f["additional"]["file_location"],
  261. #TODO
  262. }
  263. )
  264. if video_quality == "original":
  265. quality_id = ""
  266. else:
  267. quality_id = f["additional"]["video_quality"][0]["id"]
  268. data2 = ps.get_video_url(oid2, quality_id)
  269. #data2 = urllib.quote(data2, ":/")
  270. item.setProperty("is_folder", "")
  271. item.setProperty('IsPlayable', 'true')
  272. #item.setPath(data2)
  273. item.setProperty("url", data2)
  274. playlist.add(data2, item)
  275. i += 1
  276. xbmc.Player().play(playlist, startpos=pos)
  277. def play_video(streams):
  278. stream = streams[0]
  279. subfiles = []
  280. print "play_video ",stream["url"]
  281. item = ListItem(label=stream["name"], thumbnail=stream["img"], path=stream["url"])
  282. item.set_info("video",{"plot":stream["desc"]})
  283. item.is_folder = False
  284. #item.set_is_playable(True)
  285. #plugin.play_video(item)
  286. item2 = xbmcgui.ListItem("label", "label2", path=stream["url"])
  287. item2.setProperty('IsPlayable', 'true')
  288. xbmc.Player().play(item=stream["url"], listitem=item2)
  289. #xbmcplugin.setResolvedUrl(plugin.handle, True, listitem=item2)
  290. if __name__ == '__main__':
  291. if CLI_MODE:
  292. from kodiswift.cli.cli import main as start
  293. start()
  294. else:
  295. plugin.run()