From cc79e9d27f1e29b26ec6d4fd56c55e72832d999a Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Fri, 12 Dec 2014 19:35:35 +1100 Subject: [PATCH 01/21] Try to ensure the chrome window is activated on linux, some desktop managers don't always show it over XBMC full screen --- default.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) mode change 100644 => 100755 default.py diff --git a/default.py b/default.py old mode 100644 new mode 100755 index f12aabe..d68f0d4 --- a/default.py +++ b/default.py @@ -4,6 +4,7 @@ import sys import re import os +import time import subprocess import xbmcplugin import xbmcgui @@ -155,7 +156,14 @@ def showSite(url, stopPlayback, kiosk, userAgent): else: xbmc.executebuiltin('XBMC.Notification(Info:,'+str(translation(30005))+'!,5000)') addon.openSettings() - + return + timeout = time.time() + 5 + while time.time() < timeout: + windows = subprocess.check_output(['wmctrl', '-l']) + if "Google Chrome" in windows: + subprocess.Popen(['wmctrl', '-a', "Google Chrome"]) + break + xbmc.sleep(500) def removeSite(title): os.remove(os.path.join(siteFolder, getFileName(title)+".link")) From 243bd12f901776a10f6d8593b00eb316a03e265c Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Fri, 12 Dec 2014 19:38:16 +1100 Subject: [PATCH 02/21] Add option to pass userDataDir through to plugin (at launch) to specify path to custom chrome -user-data-dir --- default.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/default.py b/default.py index d68f0d4..7d48ece 100755 --- a/default.py +++ b/default.py @@ -256,6 +256,9 @@ def addSiteDir(name, url, mode, iconimage, stopPlayback, kiosk): stopPlayback = urllib.unquote_plus(params.get('stopPlayback', 'no')) kiosk = urllib.unquote_plus(params.get('kiosk', 'yes')) userAgent = urllib.unquote_plus(params.get('userAgent', '')) +userDataDir = urllib.unquote_plus(params.get('userDataDir', '')) +if userDataDir: + profileFolder = userDataDir if mode == 'addSite': From dc9fcc64cd45852118b22c68d6f12e7e6d7b1143 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Sat, 13 Dec 2014 09:35:39 +1100 Subject: [PATCH 03/21] Add extra support to code ensuring chrome is on top on linux Fix user-data-dir plugin arg option --- addon.xml | 3 ++- default.py | 33 ++++++++++++++++++++++++++++----- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/addon.xml b/addon.xml index 028e6e5..c8f60dc 100644 --- a/addon.xml +++ b/addon.xml @@ -1,7 +1,8 @@ - + + executable diff --git a/default.py b/default.py index 7d48ece..ac6ba97 100755 --- a/default.py +++ b/default.py @@ -37,6 +37,15 @@ youtubeUrl = "http://www.youtube.com/leanback" vimeoUrl = "http://www.vimeo.com/couchmode" +trace_on = False +try: + pass + # import pydevd + # #pydevd.set_pm_excepthook() + # pydevd.settrace('192.168.0.16', port=51381, stdoutToServer=True, stderrToServer=True) + # trace_on = True +except BaseException as ex: + pass def index(): files = os.listdir(siteFolder) @@ -157,8 +166,18 @@ def showSite(url, stopPlayback, kiosk, userAgent): xbmc.executebuiltin('XBMC.Notification(Info:,'+str(translation(30005))+'!,5000)') addon.openSettings() return - timeout = time.time() + 5 - while time.time() < timeout: + + # Ensure chrome is active window + def currentActiveWindow(): + # xprop -id $(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2) _NET_WM_NAME + current_window_id = subprocess.check_output(['xprop', '-root', '32x', '\'\t$0\'', '_NET_ACTIVE_WINDOW']) + current_window_id = current_window_id.strip("'").split()[1] + current_window_name = subprocess.check_output(['xprop', '-id', current_window_id, "_NET_WM_NAME"]) + current_window_name = current_window_name.strip().split(" = ")[1].strip('"') + return current_window_name + + timeout = time.time() + 10 + while time.time() < timeout and "chrome" not in currentActiveWindow().lower(): windows = subprocess.check_output(['wmctrl', '-l']) if "Google Chrome" in windows: subprocess.Popen(['wmctrl', '-a', "Google Chrome"]) @@ -256,9 +275,10 @@ def addSiteDir(name, url, mode, iconimage, stopPlayback, kiosk): stopPlayback = urllib.unquote_plus(params.get('stopPlayback', 'no')) kiosk = urllib.unquote_plus(params.get('kiosk', 'yes')) userAgent = urllib.unquote_plus(params.get('userAgent', '')) -userDataDir = urllib.unquote_plus(params.get('userDataDir', '')) -if userDataDir: - profileFolder = userDataDir +profileFolderParam = urllib.unquote_plus(params.get('profileFolder', '')) +if profileFolderParam: + useOwnProfile = True + profileFolder = profileFolderParam if mode == 'addSite': @@ -271,3 +291,6 @@ def addSiteDir(name, url, mode, iconimage, stopPlayback, kiosk): editSite(url) else: index() + +if trace_on: + pydevd.stoptrace() From 677c245ed09fe4313b0dfa7c76340e2151a72d97 Mon Sep 17 00:00:00 2001 From: Jason Pell Date: Wed, 17 Dec 2014 11:44:57 +1100 Subject: [PATCH 04/21] added git ignore for pydev --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b90f8fc --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.project +.pydevproject +.settings + +*.pyo From 54fc5d7f0f0f1f8c290466dc100e8574de0f1f00 Mon Sep 17 00:00:00 2001 From: Jason Pell Date: Wed, 17 Dec 2014 12:24:32 +1100 Subject: [PATCH 05/21] fixed newlines and made executable --- script.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 script.sh diff --git a/script.sh b/script.sh old mode 100644 new mode 100755 From cd9f08593eed1c929ace65a452f6cb7e01726247 Mon Sep 17 00:00:00 2001 From: Jason Pell Date: Wed, 17 Dec 2014 12:24:52 +1100 Subject: [PATCH 06/21] fixed some issues with the current window def --- default.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/default.py b/default.py index ac6ba97..34baae3 100755 --- a/default.py +++ b/default.py @@ -173,17 +173,23 @@ def currentActiveWindow(): current_window_id = subprocess.check_output(['xprop', '-root', '32x', '\'\t$0\'', '_NET_ACTIVE_WINDOW']) current_window_id = current_window_id.strip("'").split()[1] current_window_name = subprocess.check_output(['xprop', '-id', current_window_id, "_NET_WM_NAME"]) - current_window_name = current_window_name.strip().split(" = ")[1].strip('"') - return current_window_name + if "not found" not in current_window_name: + current_window_name = current_window_name.strip().split(" = ")[1].strip('"') + return current_window_name; + else: + return "" + + try: + timeout = time.time() + 10 + while time.time() < timeout and "chrome" not in currentActiveWindow().lower(): + windows = subprocess.check_output(['wmctrl', '-l']) + if "Google Chrome" in windows: + subprocess.Popen(['wmctrl', '-a', "Google Chrome"]) + break + xbmc.sleep(500) + except OSError: + pass - timeout = time.time() + 10 - while time.time() < timeout and "chrome" not in currentActiveWindow().lower(): - windows = subprocess.check_output(['wmctrl', '-l']) - if "Google Chrome" in windows: - subprocess.Popen(['wmctrl', '-a', "Google Chrome"]) - break - xbmc.sleep(500) - def removeSite(title): os.remove(os.path.join(siteFolder, getFileName(title)+".link")) xbmc.executebuiltin("Container.Refresh") From 29b3aad7b7e18f5fe3c1435e90e1edfcb58cf852 Mon Sep 17 00:00:00 2001 From: Jason Pell Date: Wed, 17 Dec 2014 12:27:35 +1100 Subject: [PATCH 07/21] added lirc script and made it the default for use custom script --- browser.sh | 35 +++++++++++++++++++++++++++ netflix.lirc | 54 ++++++++++++++++++++++++++++++++++++++++++ resources/settings.xml | 2 +- 3 files changed, 90 insertions(+), 1 deletion(-) create mode 100755 browser.sh create mode 100644 netflix.lirc diff --git a/browser.sh b/browser.sh new file mode 100755 index 0000000..7ab69f1 --- /dev/null +++ b/browser.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +# Prevent loading two or more tabs due to LIRC still being enabled in XBMC / KODI +CHROME_STARTED=`ps -ef | grep google | grep chrome | grep -v "grep" | wc -l` +if [ $CHROME_STARTED -gt 0 ]; then + exit 1; +fi + +# lets find out if irxevent actually exist before we try to call them. +command -v irxevent >/dev/null 2>&1 +IRXEVENT=$? + +if [ $IRXEVENT -eq 0 ]; then + killall irxevent >/dev/null 2>&1 +fi + +# http://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +if [ $IRXEVENT -eq 0 ]; then + irxevent -d $DIR/netflix.lirc & +else + echo "irxevent is not installed, can't do remote control" +fi + +/usr/bin/google-chrome "$@" & +CHROME_PID=$! + +# wait for google-chrome to be killed before killing irxevent below. +wait $CHROME_PID + +if [ $IRXEVENT -eq 0 ]; then + killall irxevent >/dev/null 2>&1 +fi + diff --git a/netflix.lirc b/netflix.lirc new file mode 100644 index 0000000..6975734 --- /dev/null +++ b/netflix.lirc @@ -0,0 +1,54 @@ +#### BEGIN CurrentWindow - NETFLIX CONTROLS +begin + prog = irxevent + button = KEY_PAUSE + repeat = 0 + config = Key space Focus CurrentWindow +end +begin + prog = irxevent + button = KEY_PLAY + repeat = 0 + config = Key space Focus CurrentWindow +end +begin + prog = irxevent + button = KEY_UP + config = Key Up Focus CurrentWindow +end +begin + prog = irxevent + button = KEY_DOWN + config = Key Down Focus CurrentWindow +end +begin + prog = irxevent + button = KEY_LEFT + config = Key Left Focus CurrentWindow +end +begin + prog = irxevent + button = KEY_RIGHT + config = Key Right Focus CurrentWindow +end +begin + prog = irxevent + button = KEY_STOP + repeat = 0 + config = Key ctrl-w Focus CurrentWindow +end +begin + prog = irxevent + button = KEY_REWIND + repeat = 0 + config = Key shift-left Focus CurrentWindow +end +begin + prog = irxevent + button = KEY_FORWARD + repeat = 0 + config = Key shift-right Focus CurrentWindow +end + +#### END CurrentWindow - NETFLIX CONTROLS + diff --git a/resources/settings.xml b/resources/settings.xml index d903a65..09e0a95 100644 --- a/resources/settings.xml +++ b/resources/settings.xml @@ -1,5 +1,5 @@ - + From f82fc6669f05b96a0ef94367029510ca1ffb9ce2 Mon Sep 17 00:00:00 2001 From: Jason Pell Date: Wed, 17 Dec 2014 12:56:36 +1100 Subject: [PATCH 08/21] added debug support --- browser.sh | 1 + default.py | 7 ++++++- resources/language/English/strings.xml | 1 + resources/language/German/strings.xml | 1 + resources/settings.xml | 1 + 5 files changed, 10 insertions(+), 1 deletion(-) diff --git a/browser.sh b/browser.sh index 7ab69f1..fc51a89 100755 --- a/browser.sh +++ b/browser.sh @@ -33,3 +33,4 @@ if [ $IRXEVENT -eq 0 ]; then killall irxevent >/dev/null 2>&1 fi +exit 0 diff --git a/default.py b/default.py index 34baae3..c195c74 100755 --- a/default.py +++ b/default.py @@ -22,6 +22,7 @@ useOwnProfile = addon.getSetting("useOwnProfile") == "true" useCustomPath = addon.getSetting("useCustomPath") == "true" customPath = xbmc.translatePath(addon.getSetting("customPath")) +debug = addon.getSetting("debug") == "true" userDataFolder = xbmc.translatePath("special://profile/addon_data/"+addonID) profileFolder = os.path.join(userDataFolder, 'profile') @@ -122,7 +123,11 @@ def getFullPath(path, url, useKiosk, userAgent): kiosk = '--kiosk ' if userAgent: userAgent = '--user-agent="'+userAgent+'" ' - return '"'+path+'" '+profile+userAgent+'--start-maximized --disable-translate --disable-new-tab-first-run --no-default-browser-check --no-first-run '+kiosk+'"'+url+'"' + + fullPath = '"'+path+'" '+profile+userAgent+'--start-maximized --disable-translate --disable-new-tab-first-run --no-default-browser-check --no-first-run '+kiosk+'"'+url+'"' + if debug: + print "Full Path: " + fullPath + return fullPath; def showSite(url, stopPlayback, kiosk, userAgent): diff --git a/resources/language/English/strings.xml b/resources/language/English/strings.xml index a295cf9..76cdfe9 100644 --- a/resources/language/English/strings.xml +++ b/resources/language/English/strings.xml @@ -12,4 +12,5 @@ Chrome/script path Use own user profile (Could take some time on first start) Use kiosk mode? + Debug diff --git a/resources/language/German/strings.xml b/resources/language/German/strings.xml index f7d3ff3..50025e3 100644 --- a/resources/language/German/strings.xml +++ b/resources/language/German/strings.xml @@ -9,4 +9,5 @@ Benutzerdefinierten Chrome/Skript Pfad nutzen Chrome/Skript Pfad Eigenes Nutzerprofil nutzen (Kann beim ersten Start etwas dauern) + Debugprotokollierung diff --git a/resources/settings.xml b/resources/settings.xml index 09e0a95..5663866 100644 --- a/resources/settings.xml +++ b/resources/settings.xml @@ -1,4 +1,5 @@ + From 841f4c071fd7f7e9599550517421e7c7b6b043e7 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Sun, 28 Dec 2014 11:04:06 +1100 Subject: [PATCH 09/21] Update to showSite() to launch without going via shell and retain pid of process Fixes and improvements to ensure launched chrome is brought to front and activated on OS X and Linux. Linux still requires testing. --- default.py | 118 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 75 insertions(+), 43 deletions(-) diff --git a/default.py b/default.py index c195c74..2950b9a 100755 --- a/default.py +++ b/default.py @@ -131,70 +131,102 @@ def getFullPath(path, url, useKiosk, userAgent): def showSite(url, stopPlayback, kiosk, userAgent): + chrome_path = "" if stopPlayback == "yes": xbmc.Player().stop() if osWin: path = 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe' path64 = 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe' if useCustomPath and os.path.exists(customPath): - fullUrl = getFullPath(customPath, url, kiosk, userAgent) - subprocess.Popen(fullUrl, shell=False) + chrome_path = customPath elif os.path.exists(path): - fullUrl = getFullPath(path, url, kiosk, userAgent) - subprocess.Popen(fullUrl, shell=False) + chrome_path = path elif os.path.exists(path64): - fullUrl = getFullPath(path64, url, kiosk, userAgent) - subprocess.Popen(fullUrl, shell=False) - else: - xbmc.executebuiltin('XBMC.Notification(Info:,'+str(translation(30005))+'!,5000)') - addon.openSettings() + chrome_path = path64 elif osOsx: path = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" if useCustomPath and os.path.exists(customPath): - fullUrl = getFullPath(customPath, url, kiosk, userAgent) - subprocess.Popen(fullUrl, shell=True) + chrome_path = customPath elif os.path.exists(path): - fullUrl = getFullPath(path, url, kiosk, userAgent) - subprocess.Popen(fullUrl, shell=True) - else: - xbmc.executebuiltin('XBMC.Notification(Info:,'+str(translation(30005))+'!,5000)') - addon.openSettings() + chrome_path = path elif osLinux: path = "/usr/bin/google-chrome" if useCustomPath and os.path.exists(customPath): - fullUrl = getFullPath(customPath, url, kiosk, userAgent) - subprocess.Popen(fullUrl, shell=True) + chrome_path = customPath elif os.path.exists(path): - fullUrl = getFullPath(path, url, kiosk, userAgent) - subprocess.Popen(fullUrl, shell=True) - else: - xbmc.executebuiltin('XBMC.Notification(Info:,'+str(translation(30005))+'!,5000)') - addon.openSettings() - return - - # Ensure chrome is active window - def currentActiveWindow(): - # xprop -id $(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2) _NET_WM_NAME - current_window_id = subprocess.check_output(['xprop', '-root', '32x', '\'\t$0\'', '_NET_ACTIVE_WINDOW']) - current_window_id = current_window_id.strip("'").split()[1] - current_window_name = subprocess.check_output(['xprop', '-id', current_window_id, "_NET_WM_NAME"]) - if "not found" not in current_window_name: - current_window_name = current_window_name.strip().split(" = ")[1].strip('"') - return current_window_name; - else: - return "" - + chrome_path = path + + if chrome_path: + fullUrl = getFullPath(chrome_path, url, kiosk, userAgent) + proc = subprocess.Popen(fullUrl, shell=False) + bringChromeToFront(proc.pid) + else: + xbmc.executebuiltin('XBMC.Notification(Info:,'+str(translation(30005))+'!,5000)') + addon.openSettings() + + +def bringChromeToFront(pid): + if osLinux: + # Ensure chrome is active window + def currentActiveWindowLinux(): + name = "" + try: + # xprop -id $(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2) _NET_WM_NAME + current_window_id = subprocess.check_output(['xprop', '-root', '32x', '\'\t$0\'', '_NET_ACTIVE_WINDOW']) + current_window_id = current_window_id.strip("'").split()[1] + current_window_name = subprocess.check_output(['xprop', '-id', current_window_id, "_NET_WM_NAME"]) + if "not found" not in current_window_name and "failed request" not in current_window_name: + current_window_name = current_window_name.strip().split(" = ")[1].strip('"') + name = current_window_name + except OSError: + pass + return name + + def findWid(): + wid = None + match = re.compile("(0x[0-9A-F]+?)").findall(subprocess.check_output(['xprop','-root','_NET_CLIENT_LIST'])) + if match: + for id in match: + wpid = subprocess.check_output(['xprop','-id',id,'_NET_WM_PID']) + wname = subprocess.check_output(['xprop','-id',id,'WM_NAME']) + if str(pid) in wpid: + wid = id + return wid + try: timeout = time.time() + 10 - while time.time() < timeout and "chrome" not in currentActiveWindow().lower(): - windows = subprocess.check_output(['wmctrl', '-l']) - if "Google Chrome" in windows: - subprocess.Popen(['wmctrl', '-a', "Google Chrome"]) + while time.time() < timeout and "chrome" not in currentActiveWindowLinux().lower(): + #windows = subprocess.check_output(['wmctrl', '-l']) + #if "Google Chrome" in windows: + wid = findWid() + if wid: + try: + subprocess.Popen(['wmctrl', '-a', '-i', wid]) + except OSError: + subprocess.Popen(['xdotool', 'windowraise', wid]) + # else: + # subprocess.Popen(['wmctrl', '-a', "Google Chrome"]) break xbmc.sleep(500) - except OSError: + except (OSError, subprocess.CalledProcessError): pass - + + elif osOsx: + timeout = time.time() + 10 + while time.time() < timeout: + xbmc.sleep(500) + applescript_switch_chrome = """tell application "System Events" + set frontmost of the first process whose unix id is %d to true + end tell""" % pid + try: + subprocess.Popen(['osascript', '-e', applescript_switch_chrome]) + break + except subprocess.CalledProcessError: + pass + elif osWin: + # TODO: find out if this is needed, and if so how to implement + pass + def removeSite(title): os.remove(os.path.join(siteFolder, getFileName(title)+".link")) xbmc.executebuiltin("Container.Refresh") From 8b497f84bfb063e1e5bf874ed96fafdcb2991aa6 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Sun, 28 Dec 2014 11:04:53 +1100 Subject: [PATCH 10/21] Fix for fullscreen/kiosk issue on linux where it takes full screen but leave black bars down side/bottom due to not maximising underlying surface. Load url via a temp black background file to minimise white flashing at chrome startup. Not perfect on OSX during maximising to fullscreen phase. --- default.py | 51 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/default.py b/default.py index 2950b9a..4b29e61 100755 --- a/default.py +++ b/default.py @@ -42,7 +42,6 @@ try: pass # import pydevd - # #pydevd.set_pm_excepthook() # pydevd.settrace('192.168.0.16', port=51381, stdoutToServer=True, stderrToServer=True) # trace_on = True except BaseException as ex: @@ -117,17 +116,55 @@ def getFileName(title): def getFullPath(path, url, useKiosk, userAgent): profile = "" if useOwnProfile: - profile = '--user-data-dir="'+profileFolder+'" ' + profile = '--user-data-dir='+profileFolder + if useKiosk=="yes" and osLinux: + import fileinput + # On Linux, chrome kiosk leavs black bars on side/bottom of screen due to an incorrect working size. + # We can fix the preferences directly + # cat $prefs |perl -pe "s/\"work_area_bottom.*/\"work_area_bottom\": $(xrandr | grep \* | cut -d' ' -f4 | cut -d'x' -f2),/" > $prefs + # cat $prefs |perl -pe "s/\"work_area_right.*/\"work_area_right\": $(xrandr | grep \* | cut -d' ' -f4 | cut -d'x' -f1),/" > $prefs + try: + width, height = 0,0 + xrandr = subprocess.check_output(['xrandr']).split('\n') + for line in xrandr: + match = re.compile('([0-9]+?)x([0-9]+?).+?\*.+?').findall(line) + if match: + width = int(match[0]) + height = int(match[1]) + + prefs = os.path.join(profileFolder, 'Default', 'Preferences') + # space for non existing controls. Not sure why it needs it, but it does on my setup + top_margin = 30 + for line in fileinput.input(prefs, inplace=True): + line = re.sub('"top": [0-9]+?,', '"top": %d,' % top_margin, line) + line = re.sub('"bottom": [0-9]+?,', '"bottom": %d,' % height-top_margin, line) + line = re.sub('"work_area_bottom": [0-9]+?,', '"work_area_bottom": %d,' % height, line) + line = re.sub('"work_area_right": [0-9]+?,', '"work_area_right": %d,' % width, line) + print line + except: + xbmc.log("Can't update chrome resolution") + + # Flashing a white screen on switching to chrome looks bad, so I'll use a temp html file with black background + # to redirect to our desired location. + black_background = os.path.join(userDataFolder, "black.html") + with open(black_background, "w") as launch: + launch.write('' % url) + kiosk = "" if useKiosk=="yes": - kiosk = '--kiosk ' + kiosk = '--kiosk' if userAgent: - userAgent = '--user-agent="'+userAgent+'" ' + userAgent = '--user-agent="'+userAgent+'"' - fullPath = '"'+path+'" '+profile+userAgent+'--start-maximized --disable-translate --disable-new-tab-first-run --no-default-browser-check --no-first-run '+kiosk+'"'+url+'"' + #fullPath = '"'+path+'" '+profile+userAgent+'--start-maximized --disable-translate --disable-new-tab-first-run --no-default-browser-check --no-first-run '+kiosk+'"'+black_background+'"' + fullPath = [path, profile, userAgent, '--start-maximized','--disable-translate','--disable-new-tab-first-run','--no-default-browser-check','--no-first-run', kiosk, black_background] if debug: - print "Full Path: " + fullPath - return fullPath; + print "Full Path:" + strpath = "" + for arg in fullPath: + strpath += " " + arg + print strpath + return fullPath def showSite(url, stopPlayback, kiosk, userAgent): From ec76e476bdc648fb61a4c02ef1c138e47b58f934 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Mon, 29 Dec 2014 18:43:59 +1100 Subject: [PATCH 11/21] Fixes to linux functionality for bringToFront() --- default.py | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/default.py b/default.py index 4b29e61..d4fcbd1 100755 --- a/default.py +++ b/default.py @@ -41,9 +41,9 @@ trace_on = False try: pass - # import pydevd - # pydevd.settrace('192.168.0.16', port=51381, stdoutToServer=True, stderrToServer=True) - # trace_on = True + import pydevd + pydevd.settrace('192.168.0.16', port=51381, stdoutToServer=True, stderrToServer=True) + trace_on = True except BaseException as ex: pass @@ -211,7 +211,7 @@ def currentActiveWindowLinux(): # xprop -id $(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2) _NET_WM_NAME current_window_id = subprocess.check_output(['xprop', '-root', '32x', '\'\t$0\'', '_NET_ACTIVE_WINDOW']) current_window_id = current_window_id.strip("'").split()[1] - current_window_name = subprocess.check_output(['xprop', '-id', current_window_id, "_NET_WM_NAME"]) + current_window_name = subprocess.check_output(['xprop', '-id', current_window_id, "WM_NAME"]) if "not found" not in current_window_name and "failed request" not in current_window_name: current_window_name = current_window_name.strip().split(" = ")[1].strip('"') name = current_window_name @@ -221,28 +221,31 @@ def currentActiveWindowLinux(): def findWid(): wid = None - match = re.compile("(0x[0-9A-F]+?)").findall(subprocess.check_output(['xprop','-root','_NET_CLIENT_LIST'])) + match = re.compile("(0x[0-9A-Fa-f]+)").findall(subprocess.check_output(['xprop','-root','_NET_CLIENT_LIST'])) if match: for id in match: - wpid = subprocess.check_output(['xprop','-id',id,'_NET_WM_PID']) - wname = subprocess.check_output(['xprop','-id',id,'WM_NAME']) - if str(pid) in wpid: - wid = id + try: + wpid = subprocess.check_output(['xprop','-id',id,'_NET_WM_PID']) + wname = subprocess.check_output(['xprop','-id',id,'WM_NAME']) + if str(pid) in wpid: + wid = id + except (OSError, subprocess.CalledProcessError): pass return wid try: timeout = time.time() + 10 - while time.time() < timeout and "chrome" not in currentActiveWindowLinux().lower(): + while time.time() < timeout:# and "chrome" not in currentActiveWindowLinux().lower(): #windows = subprocess.check_output(['wmctrl', '-l']) #if "Google Chrome" in windows: wid = findWid() if wid: try: subprocess.Popen(['wmctrl', '-a', '-i', wid]) - except OSError: - subprocess.Popen(['xdotool', 'windowraise', wid]) - # else: - # subprocess.Popen(['wmctrl', '-a', "Google Chrome"]) + except (OSError, subprocess.CalledProcessError): + try: + subprocess.Popen(['xdotool', 'windowraise', wid]) + except (OSError, subprocess.CalledProcessError): + xbmc.log("Please install wmctrl or xdotool") break xbmc.sleep(500) except (OSError, subprocess.CalledProcessError): From 55cecfdfad3a58693c87192076144f15563b730b Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Thu, 8 Jan 2015 07:47:09 +1100 Subject: [PATCH 12/21] Fixes to linux code for bringing the chrome window to front --- default.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/default.py b/default.py index d4fcbd1..4acbd18 100755 --- a/default.py +++ b/default.py @@ -41,9 +41,9 @@ trace_on = False try: pass - import pydevd - pydevd.settrace('192.168.0.16', port=51381, stdoutToServer=True, stderrToServer=True) - trace_on = True + # import pydevd + # pydevd.settrace('192.168.0.16', port=51381, stdoutToServer=True, stderrToServer=True) + # trace_on = True except BaseException as ex: pass @@ -240,10 +240,10 @@ def findWid(): wid = findWid() if wid: try: - subprocess.Popen(['wmctrl', '-a', '-i', wid]) + subprocess.Popen(['wmctrl', '-i', '-a', wid]) except (OSError, subprocess.CalledProcessError): try: - subprocess.Popen(['xdotool', 'windowraise', wid]) + subprocess.Popen(['xdotool', 'windowactivate', wid]) except (OSError, subprocess.CalledProcessError): xbmc.log("Please install wmctrl or xdotool") break From e4c26f0407578f5110629972685e6f959068f686 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Sat, 10 Jan 2015 10:28:55 +1100 Subject: [PATCH 13/21] Fixes to chrome window size / black bars on some linux --- addon.xml | 2 +- default.py | 32 +++++++++++++++++++++----------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/addon.xml b/addon.xml index c8f60dc..9647e81 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + diff --git a/default.py b/default.py index 4acbd18..0b02417 100755 --- a/default.py +++ b/default.py @@ -118,7 +118,6 @@ def getFullPath(path, url, useKiosk, userAgent): if useOwnProfile: profile = '--user-data-dir='+profileFolder if useKiosk=="yes" and osLinux: - import fileinput # On Linux, chrome kiosk leavs black bars on side/bottom of screen due to an incorrect working size. # We can fix the preferences directly # cat $prefs |perl -pe "s/\"work_area_bottom.*/\"work_area_bottom\": $(xrandr | grep \* | cut -d' ' -f4 | cut -d'x' -f2),/" > $prefs @@ -127,20 +126,31 @@ def getFullPath(path, url, useKiosk, userAgent): width, height = 0,0 xrandr = subprocess.check_output(['xrandr']).split('\n') for line in xrandr: - match = re.compile('([0-9]+?)x([0-9]+?).+?\*.+?').findall(line) + match = re.compile('([0-9]+)x([0-9]+).+?\*.+?').findall(line) if match: - width = int(match[0]) - height = int(match[1]) - + width = int(match[0][0]) + height = int(match[0][1]) + break prefs = os.path.join(profileFolder, 'Default', 'Preferences') # space for non existing controls. Not sure why it needs it, but it does on my setup top_margin = 30 - for line in fileinput.input(prefs, inplace=True): - line = re.sub('"top": [0-9]+?,', '"top": %d,' % top_margin, line) - line = re.sub('"bottom": [0-9]+?,', '"bottom": %d,' % height-top_margin, line) - line = re.sub('"work_area_bottom": [0-9]+?,', '"work_area_bottom": %d,' % height, line) - line = re.sub('"work_area_right": [0-9]+?,', '"work_area_right": %d,' % width, line) - print line + + with open(prefs, "rb+") as prefsfile: + import json + prefsdata = json.load(prefsfile) + prefs_browser = prefsdata.get('browser', {}) + prefs_window_placement = prefs_browser.get('window_placement', {}) + prefs_window_placement['always_on_top'] = True + prefs_window_placement['top'] = top_margin + prefs_window_placement['bottom'] = height-top_margin + prefs_window_placement['work_area_bottom'] = height + prefs_window_placement['work_area_right'] = width + prefsdata['browser'] = prefs_browser + prefsdata['browser']['window_placement'] = prefs_window_placement + prefsfile.seek(0) + prefsfile.truncate(0) + json.dump(prefsdata, prefsfile, indent=4, separators=(',', ': ')) + except: xbmc.log("Can't update chrome resolution") From 2bcad68ab1cff750386d1c0c4e1180924c6b32a2 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Sat, 10 Jan 2015 16:34:33 +1100 Subject: [PATCH 14/21] Version 1.1.3 --- addon.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addon.xml b/addon.xml index 9647e81..0a03ce0 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + From 01187f4f5538e6c9f9301af970b5021e85d62d4d Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Sat, 10 Jan 2015 17:11:38 +1100 Subject: [PATCH 15/21] Add creationflags for windows as per: http://forum.kodi.tv/showthread.php?tid=211574&pid=1875256#pid1875256 --- addon.xml | 2 +- default.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/addon.xml b/addon.xml index 0a03ce0..ca17bb3 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + diff --git a/default.py b/default.py index 0b02417..63c5649 100755 --- a/default.py +++ b/default.py @@ -179,9 +179,11 @@ def getFullPath(path, url, useKiosk, userAgent): def showSite(url, stopPlayback, kiosk, userAgent): chrome_path = "" + creationflags = 0 if stopPlayback == "yes": xbmc.Player().stop() if osWin: + creationflags = subprocess.CREATE_NEW_PROCESS_GROUP path = 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe' path64 = 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe' if useCustomPath and os.path.exists(customPath): @@ -205,7 +207,7 @@ def showSite(url, stopPlayback, kiosk, userAgent): if chrome_path: fullUrl = getFullPath(chrome_path, url, kiosk, userAgent) - proc = subprocess.Popen(fullUrl, shell=False) + proc = subprocess.Popen(fullUrl, shell=False, creationflags=creationflags, close_fds = True) bringChromeToFront(proc.pid) else: xbmc.executebuiltin('XBMC.Notification(Info:,'+str(translation(30005))+'!,5000)') From cb4f910e8f32f0414db3d17af16ea02feaf00189 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Tue, 13 Jan 2015 21:01:36 +1100 Subject: [PATCH 16/21] Remove empty arguments from subprocess as on Windows they cause an extra tab to be openned. --- addon.xml | 2 +- default.py | 12 +++++++----- user_debug.py.example | 4 ++++ 3 files changed, 12 insertions(+), 6 deletions(-) mode change 100755 => 100644 default.py create mode 100644 user_debug.py.example diff --git a/addon.xml b/addon.xml index ca17bb3..0a03ce0 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + diff --git a/default.py b/default.py old mode 100755 new mode 100644 index 63c5649..5541e4b --- a/default.py +++ b/default.py @@ -40,12 +40,10 @@ trace_on = False try: - pass - # import pydevd - # pydevd.settrace('192.168.0.16', port=51381, stdoutToServer=True, stderrToServer=True) - # trace_on = True + import user_debug + trace_on = user_debug.enable_pydev() except BaseException as ex: - pass + pass def index(): files = os.listdir(siteFolder) @@ -168,6 +166,10 @@ def getFullPath(path, url, useKiosk, userAgent): #fullPath = '"'+path+'" '+profile+userAgent+'--start-maximized --disable-translate --disable-new-tab-first-run --no-default-browser-check --no-first-run '+kiosk+'"'+black_background+'"' fullPath = [path, profile, userAgent, '--start-maximized','--disable-translate','--disable-new-tab-first-run','--no-default-browser-check','--no-first-run', kiosk, black_background] + for idx in range(0,len(fullPath))[::-1]: + if not fullPath[idx]: + del fullPath[idx] + if debug: print "Full Path:" strpath = "" diff --git a/user_debug.py.example b/user_debug.py.example new file mode 100644 index 0000000..214ce04 --- /dev/null +++ b/user_debug.py.example @@ -0,0 +1,4 @@ +def enable_pydev(): + import pydevd + pydevd.settrace('192.168.0.16', port=51381, stdoutToServer=True, stderrToServer=True) + return True From 151cf6a45cb6f66f9e29d82beefd4e797cde029a Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Tue, 13 Jan 2015 21:02:27 +1100 Subject: [PATCH 17/21] Add ignore for user_debug.py --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index b90f8fc..1c9689e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .project .pydevproject .settings - +user_debug.py *.pyo From 688c4cd7e9bf1cb812fde8fa70ce76254e332c71 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Wed, 14 Jan 2015 00:13:48 +1100 Subject: [PATCH 18/21] Fix for when user_debug isn't used --- default.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/default.py b/default.py index 5541e4b..788b1f3 100644 --- a/default.py +++ b/default.py @@ -40,9 +40,12 @@ trace_on = False try: + with open(os.path.join(addonPath,'user_debug.py'),'a'): # touch file + pass import user_debug trace_on = user_debug.enable_pydev() -except BaseException as ex: +except (ImportError, AttributeError) as ex: + xbmc.log("Debug Disable") pass def index(): From a4004a90a7fa8da222f4a959a0dee263f7b28889 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Wed, 14 Jan 2015 00:21:03 +1100 Subject: [PATCH 19/21] version 1.1.4 --- addon.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addon.xml b/addon.xml index 0a03ce0..e4a900c 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + From f67110ba017b1456498f1e807e746cdf93cc29e8 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Fri, 23 Jan 2015 18:32:46 +1100 Subject: [PATCH 20/21] Change creation flags for windows to not rely on (missing) definition in subprocess module --- default.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/default.py b/default.py index 788b1f3..59c962c 100644 --- a/default.py +++ b/default.py @@ -188,7 +188,7 @@ def showSite(url, stopPlayback, kiosk, userAgent): if stopPlayback == "yes": xbmc.Player().stop() if osWin: - creationflags = subprocess.CREATE_NEW_PROCESS_GROUP + creationflags = 0x00000008 # DETACHED_PROCESS https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863(v=vs.85).aspx path = 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe' path64 = 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe' if useCustomPath and os.path.exists(customPath): From 708eff683321637c893a9f5483045393f049d0a9 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Fri, 23 Jan 2015 18:36:46 +1100 Subject: [PATCH 21/21] version 1.1.5 --- addon.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addon.xml b/addon.xml index e4a900c..f0ab2d1 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - +