Advertisement
Guest User

Untitled

a guest
Aug 5th, 2015
273
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.97 KB | None | 0 0
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. import urllib
  4. import sys
  5. import re
  6. import os
  7. import time
  8. import subprocess
  9. import xbmcplugin
  10. import xbmcgui
  11. import xbmcaddon
  12.  
  13.  
  14. addon = xbmcaddon.Addon()
  15. pluginhandle = int(sys.argv[1])
  16. addonID = addon.getAddonInfo('id')
  17. addonPath = addon.getAddonInfo('path')
  18. translation = addon.getLocalizedString
  19. osWin = xbmc.getCondVisibility('system.platform.windows')
  20. osOsx = xbmc.getCondVisibility('system.platform.osx')
  21. osLinux = xbmc.getCondVisibility('system.platform.linux')
  22. useOwnProfile = addon.getSetting("useOwnProfile") == "true"
  23. useCustomPath = addon.getSetting("useCustomPath") == "true"
  24. customPath = xbmc.translatePath(addon.getSetting("customPath"))
  25. debug = addon.getSetting("debug") == "true"
  26.  
  27. userDataFolder = xbmc.translatePath("special://profile/addon_data/"+addonID)
  28. profileFolder = os.path.join(userDataFolder, 'profile')
  29. siteFolder = os.path.join(userDataFolder, 'sites')
  30.  
  31. if not os.path.isdir(userDataFolder):
  32. os.mkdir(userDataFolder)
  33. if not os.path.isdir(profileFolder):
  34. os.mkdir(profileFolder)
  35. if not os.path.isdir(siteFolder):
  36. os.mkdir(siteFolder)
  37.  
  38. youtubeUrl = "http://www.youtube.com/tv"
  39. vimeoUrl = "http://www.vimeo.com/couchmode"
  40.  
  41. trace_on = False
  42. try:
  43. with open(os.path.join(addonPath,'user_debug.py'),'a'): # touch file
  44. pass
  45. import user_debug
  46. trace_on = user_debug.enable_pydev()
  47. except (ImportError, AttributeError) as ex:
  48. xbmc.log("Debug Disable")
  49. pass
  50.  
  51. def index():
  52. files = os.listdir(siteFolder)
  53. for file in files:
  54. if file.endswith(".link"):
  55. fh = open(os.path.join(siteFolder, file), 'r')
  56. title = ""
  57. url = ""
  58. thumb = ""
  59. kiosk = "yes"
  60. incognito = "no"
  61. stopPlayback = "no"
  62. for line in fh.readlines():
  63. entry = line[:line.find("=")]
  64. content = line[line.find("=")+1:]
  65. if entry == "title":
  66. title = content.strip()
  67. elif entry == "url":
  68. url = content.strip()
  69. elif entry == "thumb":
  70. thumb = content.strip()
  71. elif entry == "kiosk":
  72. kiosk = content.strip()
  73. elif entry == "incognito":
  74. incognito = content.strip()
  75. elif entry == "stopPlayback":
  76. stopPlayback = content.strip()
  77. fh.close()
  78. addSiteDir(title, url, 'showSite', thumb, stopPlayback, kiosk)
  79. addDir("[B]- "+translation(30001)+"[/B]", "", 'addSite', "")
  80. xbmcplugin.endOfDirectory(pluginhandle)
  81.  
  82.  
  83. def addSite(site="", title=""):
  84. if site:
  85. filename = getFileName(title)
  86. content = "title="+title+"\nurl="+site+"\nthumb=DefaultFolder.png\nstopPlayback=no\nkiosk=yes"
  87. fh = open(os.path.join(siteFolder, filename+".link"), 'w')
  88. fh.write(content)
  89. fh.close()
  90. else:
  91. keyboard = xbmc.Keyboard('', translation(30003))
  92. keyboard.doModal()
  93. if keyboard.isConfirmed() and keyboard.getText():
  94. title = keyboard.getText()
  95. keyboard = xbmc.Keyboard('http://', translation(30004))
  96. keyboard.doModal()
  97. if keyboard.isConfirmed() and keyboard.getText():
  98. url = keyboard.getText()
  99. keyboard = xbmc.Keyboard('no', translation(30009))
  100. keyboard.doModal()
  101. if keyboard.isConfirmed() and keyboard.getText():
  102. stopPlayback = keyboard.getText()
  103. keyboard = xbmc.Keyboard('yes', translation(30016))
  104. keyboard.doModal()
  105. if keyboard.isConfirmed() and keyboard.getText():
  106. kiosk = keyboard.getText()
  107. content = "title="+title+"\nurl="+url+"\nthumb=DefaultFolder.png\nstopPlayback="+stopPlayback+"\nkiosk="+kiosk
  108. fh = open(os.path.join(siteFolder, getFileName(title)+".link"), 'w')
  109. fh.write(content)
  110. fh.close()
  111. xbmc.executebuiltin("Container.Refresh")
  112.  
  113.  
  114. def getFileName(title):
  115. return (''.join(c for c in unicode(title, 'utf-8') if c not in '/\\:?"*|<>')).strip()
  116.  
  117.  
  118. def getFullPath(path, url, useKiosk, userAgent):
  119. profile = ""
  120. if useOwnProfile:
  121. profile = '--user-data-dir='+profileFolder
  122. if useKiosk=="yes" and osLinux:
  123. # On Linux, chrome kiosk leavs black bars on side/bottom of screen due to an incorrect working size.
  124. # We can fix the preferences directly
  125. # cat $prefs |perl -pe "s/\"work_area_bottom.*/\"work_area_bottom\": $(xrandr | grep \* | cut -d' ' -f4 | cut -d'x' -f2),/" > $prefs
  126. # cat $prefs |perl -pe "s/\"work_area_right.*/\"work_area_right\": $(xrandr | grep \* | cut -d' ' -f4 | cut -d'x' -f1),/" > $prefs
  127. try:
  128. width, height = 0,0
  129. xrandr = subprocess.check_output(['xrandr']).split('\n')
  130. for line in xrandr:
  131. match = re.compile('([0-9]+)x([0-9]+).+?\*.+?').findall(line)
  132. if match:
  133. width = int(match[0][0])
  134. height = int(match[0][1])
  135. break
  136. prefs = os.path.join(profileFolder, 'Default', 'Preferences')
  137. # space for non existing controls. Not sure why it needs it, but it does on my setup
  138. top_margin = 0
  139.  
  140. with open(prefs, "rb+") as prefsfile:
  141. import json
  142. prefsdata = json.load(prefsfile)
  143. prefs_browser = prefsdata.get('browser', {})
  144. prefs_window_placement = prefs_browser.get('window_placement', {})
  145. prefs_window_placement['always_on_top'] = True
  146. prefs_window_placement['top'] = top_margin
  147. prefs_window_placement['bottom'] = height-top_margin
  148. prefs_window_placement['work_area_bottom'] = height
  149. prefs_window_placement['work_area_right'] = width
  150. prefsdata['browser'] = prefs_browser
  151. prefsdata['browser']['window_placement'] = prefs_window_placement
  152. prefsfile.seek(0)
  153. prefsfile.truncate(0)
  154. json.dump(prefsdata, prefsfile, indent=4, separators=(',', ': '))
  155.  
  156. except:
  157. xbmc.log("Can't update chrome resolution")
  158.  
  159. # Flashing a white screen on switching to chrome looks bad, so I'll use a temp html file with black background
  160. # to redirect to our desired location.
  161. black_background = os.path.join(userDataFolder, "black.html")
  162. with open(black_background, "w") as launch:
  163. launch.write('<html><body style="background:black"><script>window.location.href = "%s";</script></body></html>' % url)
  164.  
  165. kiosk = ""
  166. if useKiosk=="yes":
  167. kiosk = '--kiosk'
  168. if useIncognito=="yes":
  169. incognito = '--incognito'
  170. if userAgent:
  171. userAgent = '--user-agent="'+userAgent+'"'
  172.  
  173. #fullPath = '"'+path+'" '+profile+userAgent+'--start-maximized --disable-translate --disable-new-tab-first-run --no-default-browser-check --no-first-run '+kiosk+'"'+black_background+'"'
  174. fullPath = [path, profile, userAgent, '--start-maximized','--disable-translate','--disable-new-tab-first-run','--no-default-browser-check','--no-first-run', kiosk, black_background]
  175. for idx in range(0,len(fullPath))[::-1]:
  176. if not fullPath[idx]:
  177. del fullPath[idx]
  178.  
  179. if debug:
  180. print "Full Path:"
  181. strpath = ""
  182. for arg in fullPath:
  183. strpath += " " + arg
  184. print strpath
  185. return fullPath
  186.  
  187.  
  188. def showSite(url, stopPlayback, kiosk, userAgent):
  189. chrome_path = ""
  190. creationflags = 0
  191. if stopPlayback == "yes":
  192. xbmc.Player().stop()
  193. if osWin:
  194. creationflags = subprocess.CREATE_NEW_PROCESS_GROUP
  195. path = 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'
  196. path64 = 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe'
  197. if useCustomPath and os.path.exists(customPath):
  198. chrome_path = customPath
  199. elif os.path.exists(path):
  200. chrome_path = path
  201. elif os.path.exists(path64):
  202. chrome_path = path64
  203. elif osOsx:
  204. path = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
  205. if useCustomPath and os.path.exists(customPath):
  206. chrome_path = customPath
  207. elif os.path.exists(path):
  208. chrome_path = path
  209. elif osLinux:
  210. path = "/usr/bin/google-chrome"
  211. if useCustomPath and os.path.exists(customPath):
  212. chrome_path = customPath
  213. elif os.path.exists(path):
  214. chrome_path = path
  215.  
  216. if chrome_path:
  217. fullUrl = getFullPath(chrome_path, url, kiosk, userAgent)
  218. proc = subprocess.Popen(fullUrl, shell=False, creationflags=creationflags, close_fds = True)
  219. bringChromeToFront(proc.pid)
  220. else:
  221. xbmc.executebuiltin('XBMC.Notification(Info:,'+str(translation(30005))+'!,5000)')
  222. addon.openSettings()
  223.  
  224.  
  225. def bringChromeToFront(pid):
  226. if osLinux:
  227. # Ensure chrome is active window
  228. def currentActiveWindowLinux():
  229. name = ""
  230. try:
  231. # xprop -id $(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2) _NET_WM_NAME
  232. current_window_id = subprocess.check_output(['xprop', '-root', '32x', '\'\t$0\'', '_NET_ACTIVE_WINDOW'])
  233. current_window_id = current_window_id.strip("'").split()[1]
  234. current_window_name = subprocess.check_output(['xprop', '-id', current_window_id, "WM_NAME"])
  235. if "not found" not in current_window_name and "failed request" not in current_window_name:
  236. current_window_name = current_window_name.strip().split(" = ")[1].strip('"')
  237. name = current_window_name
  238. except OSError:
  239. pass
  240. return name
  241.  
  242. def findWid():
  243. wid = None
  244. match = re.compile("(0x[0-9A-Fa-f]+)").findall(subprocess.check_output(['xprop','-root','_NET_CLIENT_LIST']))
  245. if match:
  246. for id in match:
  247. try:
  248. wpid = subprocess.check_output(['xprop','-id',id,'_NET_WM_PID'])
  249. wname = subprocess.check_output(['xprop','-id',id,'WM_NAME'])
  250. if str(pid) in wpid:
  251. wid = id
  252. except (OSError, subprocess.CalledProcessError): pass
  253. return wid
  254.  
  255. try:
  256. timeout = time.time() + 10
  257. while time.time() < timeout:# and "chrome" not in currentActiveWindowLinux().lower():
  258. #windows = subprocess.check_output(['wmctrl', '-l'])
  259. #if "Google Chrome" in windows:
  260. wid = findWid()
  261. if wid:
  262. try:
  263. subprocess.Popen(['wmctrl', '-i', '-a', wid])
  264. except (OSError, subprocess.CalledProcessError):
  265. try:
  266. subprocess.Popen(['xdotool', 'windowactivate', wid])
  267. except (OSError, subprocess.CalledProcessError):
  268. xbmc.log("Please install wmctrl or xdotool")
  269. break
  270. xbmc.sleep(500)
  271. except (OSError, subprocess.CalledProcessError):
  272. pass
  273.  
  274. elif osOsx:
  275. timeout = time.time() + 10
  276. while time.time() < timeout:
  277. xbmc.sleep(500)
  278. applescript_switch_chrome = """tell application "System Events"
  279. set frontmost of the first process whose unix id is %d to true
  280. end tell""" % pid
  281. try:
  282. subprocess.Popen(['osascript', '-e', applescript_switch_chrome])
  283. break
  284. except subprocess.CalledProcessError:
  285. pass
  286. elif osWin:
  287. # TODO: find out if this is needed, and if so how to implement
  288. pass
  289.  
  290. def removeSite(title):
  291. os.remove(os.path.join(siteFolder, getFileName(title)+".link"))
  292. xbmc.executebuiltin("Container.Refresh")
  293.  
  294.  
  295. def editSite(title):
  296. filenameOld = getFileName(title)
  297. file = os.path.join(siteFolder, filenameOld+".link")
  298. fh = open(file, 'r')
  299. title = ""
  300. url = ""
  301. kiosk = "yes"
  302. incognito = "no"
  303. thumb = "DefaultFolder.png"
  304. stopPlayback = "no"
  305. for line in fh.readlines():
  306. entry = line[:line.find("=")]
  307. content = line[line.find("=")+1:]
  308. if entry == "title":
  309. title = content.strip()
  310. elif entry == "url":
  311. url = content.strip()
  312. elif entry == "kiosk":
  313. kiosk = content.strip()
  314. elif entry == "incognito":
  315. incognito = content.strip()
  316. elif entry == "thumb":
  317. thumb = content.strip()
  318. elif entry == "stopPlayback":
  319. stopPlayback = content.strip()
  320. fh.close()
  321.  
  322. oldTitle = title
  323. keyboard = xbmc.Keyboard(title, translation(30003))
  324. keyboard.doModal()
  325. if keyboard.isConfirmed() and keyboard.getText():
  326. title = keyboard.getText()
  327. keyboard = xbmc.Keyboard(url, translation(30004))
  328. keyboard.doModal()
  329. if keyboard.isConfirmed() and keyboard.getText():
  330. url = keyboard.getText()
  331. keyboard = xbmc.Keyboard(stopPlayback, translation(30009))
  332. keyboard.doModal()
  333. if keyboard.isConfirmed() and keyboard.getText():
  334. stopPlayback = keyboard.getText()
  335. keyboard = xbmc.Keyboard(kiosk, translation(30016))
  336. keyboard.doModal()
  337. if keyboard.isConfirmed() and keyboard.getText():
  338. kiosk = keyboard.getText()
  339. content = "title="+title+"\nurl="+url+"\nthumb="+thumb+"\nstopPlayback="+stopPlayback+"\nkiosk="+kiosk
  340. fh = open(os.path.join(siteFolder, getFileName(title)+".link"), 'w')
  341. fh.write(content)
  342. fh.close()
  343. if title != oldTitle:
  344. os.remove(os.path.join(siteFolder, filenameOld+".link"))
  345. xbmc.executebuiltin("Container.Refresh")
  346.  
  347.  
  348. def parameters_string_to_dict(parameters):
  349. paramDict = {}
  350. if parameters:
  351. paramPairs = parameters[1:].split("&")
  352. for paramsPair in paramPairs:
  353. paramSplits = paramsPair.split('=')
  354. if (len(paramSplits)) == 2:
  355. paramDict[paramSplits[0]] = paramSplits[1]
  356. return paramDict
  357.  
  358.  
  359. def addDir(name, url, mode, iconimage, stopPlayback="", kiosk="", incognito=""):
  360. u = sys.argv[0]+"?url="+urllib.quote_plus(url)+"&mode="+urllib.quote_plus(mode)+"&stopPlayback="+urllib.quote_plus(stopPlayback)+"&kiosk="+urllib.quote_plus(kiosk)+"&incognito="+urllib.quote_plus(incognito)
  361. ok = True
  362. liz = xbmcgui.ListItem(name, iconImage="DefaultFolder.png", thumbnailImage=iconimage)
  363. liz.setInfo(type="Video", infoLabels={"Title": name})
  364. ok = xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=u, listitem=liz, isFolder=True)
  365. return ok
  366.  
  367.  
  368. def addSiteDir(name, url, mode, iconimage, stopPlayback, kiosk, incognito):
  369. u = sys.argv[0]+"?url="+urllib.quote_plus(url)+"&mode="+urllib.quote_plus(mode)+"&stopPlayback="+urllib.quote_plus(stopPlayback)+"&kiosk="+urllib.quote_plus(kiosk)+"&incognito="+urllib.quote_plus(incognito)
  370. ok = True
  371. liz = xbmcgui.ListItem(name, iconImage="DefaultFolder.png", thumbnailImage=iconimage)
  372. liz.setInfo(type="Video", infoLabels={"Title": name})
  373. liz.addContextMenuItems([(translation(30006), 'RunPlugin(plugin://'+addonID+'/?mode=editSite&url='+urllib.quote_plus(name)+')',), (translation(30002), 'RunPlugin(plugin://'+addonID+'/?mode=removeSite&url='+urllib.quote_plus(name)+')',)])
  374. ok = xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=u, listitem=liz, isFolder=True)
  375. return ok
  376.  
  377. params = parameters_string_to_dict(sys.argv[2])
  378. mode = urllib.unquote_plus(params.get('mode', ''))
  379. name = urllib.unquote_plus(params.get('name', ''))
  380. url = urllib.unquote_plus(params.get('url', ''))
  381. stopPlayback = urllib.unquote_plus(params.get('stopPlayback', 'no'))
  382. kiosk = urllib.unquote_plus(params.get('kiosk', 'yes'))
  383. incognito = urllib.unquote_plus(params.get('incognito', 'no'))
  384. userAgent = urllib.unquote_plus(params.get('userAgent', ''))
  385. profileFolderParam = urllib.unquote_plus(params.get('profileFolder', ''))
  386. if profileFolderParam:
  387. useOwnProfile = True
  388. profileFolder = profileFolderParam
  389.  
  390.  
  391. if mode == 'addSite':
  392. addSite()
  393. elif mode == 'showSite':
  394. showSite(url, stopPlayback, kiosk, userAgent, incognito)
  395. elif mode == 'removeSite':
  396. removeSite(url)
  397. elif mode == 'editSite':
  398. editSite(url)
  399. else:
  400. index()
  401.  
  402. if trace_on:
  403. pydevd.stoptrace()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement