Account for string.encode() not allowing args
- E.g. Android TV
This commit is contained in:
parent
8848d5167d
commit
df38786638
18 changed files with 213 additions and 160 deletions
|
@ -10,13 +10,14 @@ import xbmc
|
||||||
import xbmcaddon
|
import xbmcaddon
|
||||||
import xbmcgui
|
import xbmcgui
|
||||||
|
|
||||||
|
import utils
|
||||||
|
|
||||||
addon_ = xbmcaddon.Addon(id='plugin.video.plexkodiconnect')
|
addon_ = xbmcaddon.Addon(id='plugin.video.plexkodiconnect')
|
||||||
addon_path = addon_.getAddonInfo('path').decode('utf-8')
|
addon_path = utils.tryDecode(addon_.getAddonInfo('path'))
|
||||||
base_resource = xbmc.translatePath(os.path.join(addon_path, 'resources', 'lib')).decode('utf-8')
|
base_resource = utils.tryDecode(xbmc.translatePath(os.path.join(addon_path, 'resources', 'lib')))
|
||||||
sys.path.append(base_resource)
|
sys.path.append(base_resource)
|
||||||
|
|
||||||
import artwork
|
import artwork
|
||||||
import utils
|
|
||||||
import clientinfo
|
import clientinfo
|
||||||
import downloadutils
|
import downloadutils
|
||||||
import librarysync
|
import librarysync
|
||||||
|
@ -36,8 +37,8 @@ def logMsg(msg, lvl=1):
|
||||||
#Kodi contextmenu item to configure the emby settings
|
#Kodi contextmenu item to configure the emby settings
|
||||||
#for now used to set ratings but can later be used to sync individual items etc.
|
#for now used to set ratings but can later be used to sync individual items etc.
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
itemid = xbmc.getInfoLabel("ListItem.DBID").decode("utf-8")
|
itemid = utils.tryDecode(xbmc.getInfoLabel("ListItem.DBID"))
|
||||||
itemtype = xbmc.getInfoLabel("ListItem.DBTYPE").decode("utf-8")
|
itemtype = utils.tryDecode(xbmc.getInfoLabel("ListItem.DBTYPE"))
|
||||||
|
|
||||||
emby = embyserver.Read_EmbyServer()
|
emby = embyserver.Read_EmbyServer()
|
||||||
|
|
||||||
|
|
11
default.py
11
default.py
|
@ -10,17 +10,18 @@ import xbmc
|
||||||
import xbmcaddon
|
import xbmcaddon
|
||||||
import xbmcgui
|
import xbmcgui
|
||||||
|
|
||||||
|
import utils
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
addon_ = xbmcaddon.Addon(id='plugin.video.plexkodiconnect')
|
addon_ = xbmcaddon.Addon(id='plugin.video.plexkodiconnect')
|
||||||
addon_path = addon_.getAddonInfo('path').decode('utf-8')
|
addon_path = utils.tryDecode(addon_.getAddonInfo('path'))
|
||||||
base_resource = xbmc.translatePath(os.path.join(addon_path, 'resources', 'lib')).decode('utf-8')
|
base_resource = utils.tryDecode(xbmc.translatePath(os.path.join(addon_path, 'resources', 'lib')))
|
||||||
sys.path.append(base_resource)
|
sys.path.append(base_resource)
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
import entrypoint
|
import entrypoint
|
||||||
import utils
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
@ -159,8 +160,8 @@ if ( __name__ == "__main__" ):
|
||||||
import pstats
|
import pstats
|
||||||
import random
|
import random
|
||||||
from time import gmtime, strftime
|
from time import gmtime, strftime
|
||||||
addonid = addon_.getAddonInfo('id').decode( 'utf-8' )
|
addonid = utils.tryDecode(addon_.getAddonInfo('id'))
|
||||||
datapath = os.path.join( xbmc.translatePath( "special://profile/" ).decode( 'utf-8' ), "addon_data", addonid )
|
datapath = os.path.join(utils.tryDecode(xbmc.translatePath( "special://profile/" )), "addon_data", addonid )
|
||||||
|
|
||||||
filename = os.path.join( datapath, strftime( "%Y%m%d%H%M%S",gmtime() ) + "-" + str( random.randrange(0,100000) ) + ".log" )
|
filename = os.path.join( datapath, strftime( "%Y%m%d%H%M%S",gmtime() ) + "-" + str( random.randrange(0,100000) ) + ".log" )
|
||||||
cProfile.run( 'Main()', filename )
|
cProfile.run( 'Main()', filename )
|
||||||
|
|
|
@ -482,8 +482,8 @@ class PlexAPI():
|
||||||
elif "Resource-Identifier:" in each:
|
elif "Resource-Identifier:" in each:
|
||||||
update['uuid'] = each.split(':')[1].strip()
|
update['uuid'] = each.split(':')[1].strip()
|
||||||
elif "Name:" in each:
|
elif "Name:" in each:
|
||||||
update['serverName'] = each.split(
|
update['serverName'] = utils.tryDecode(each.split(
|
||||||
':')[1].strip().decode('utf-8', 'replace')
|
':')[1].strip())
|
||||||
elif "Port:" in each:
|
elif "Port:" in each:
|
||||||
update['port'] = each.split(':')[1].strip()
|
update['port'] = each.split(':')[1].strip()
|
||||||
elif "Updated-At:" in each:
|
elif "Updated-At:" in each:
|
||||||
|
@ -807,7 +807,7 @@ class PlexAPI():
|
||||||
username = user['title']
|
username = user['title']
|
||||||
userlist.append(username)
|
userlist.append(username)
|
||||||
# To take care of non-ASCII usernames
|
# To take care of non-ASCII usernames
|
||||||
userlistCoded.append(username.encode('utf-8'))
|
userlistCoded.append(utils.tryEncode(username))
|
||||||
usernumber = len(userlist)
|
usernumber = len(userlist)
|
||||||
|
|
||||||
username = ''
|
username = ''
|
||||||
|
@ -1039,7 +1039,7 @@ class PlexAPI():
|
||||||
path = 'http://127.0.0.1:32400' + key
|
path = 'http://127.0.0.1:32400' + key
|
||||||
else: # internal path, add-on
|
else: # internal path, add-on
|
||||||
path = 'http://127.0.0.1:32400' + path + '/' + key
|
path = 'http://127.0.0.1:32400' + path + '/' + key
|
||||||
path = path.encode('utf8')
|
path = utils.tryEncode(path)
|
||||||
|
|
||||||
# This is bogus (note the extra path component) but ATV is stupid when it comes to caching images, it doesn't use querystrings.
|
# This is bogus (note the extra path component) but ATV is stupid when it comes to caching images, it doesn't use querystrings.
|
||||||
# Fortunately PMS is lenient...
|
# Fortunately PMS is lenient...
|
||||||
|
@ -1235,7 +1235,7 @@ class API():
|
||||||
res = None
|
res = None
|
||||||
if res is not None:
|
if res is not None:
|
||||||
try:
|
try:
|
||||||
res = unquote(res).decode('utf-8')
|
res = utils.tryDecode(unquote(res))
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
# Sometimes, Plex seems to have encoded in latin1
|
# Sometimes, Plex seems to have encoded in latin1
|
||||||
res = unquote(res).decode('latin1')
|
res = unquote(res).decode('latin1')
|
||||||
|
@ -1899,13 +1899,9 @@ class API():
|
||||||
url = 'http://api.themoviedb.org/3/search/%s' % media_type
|
url = 'http://api.themoviedb.org/3/search/%s' % media_type
|
||||||
parameters = {
|
parameters = {
|
||||||
'api_key': apiKey,
|
'api_key': apiKey,
|
||||||
'language': KODILANGUAGE
|
'language': KODILANGUAGE,
|
||||||
|
'query': utils.tryEncode(title)
|
||||||
}
|
}
|
||||||
try:
|
|
||||||
parameters['query'] = title.encode('utf-8', errors='ignore')
|
|
||||||
except TypeError:
|
|
||||||
# E.g. Android TV's python does NOT take arguments to encode
|
|
||||||
parameters['query'] = title.encode()
|
|
||||||
data = downloadutils.DownloadUtils().downloadUrl(
|
data = downloadutils.DownloadUtils().downloadUrl(
|
||||||
url,
|
url,
|
||||||
authenticate=False,
|
authenticate=False,
|
||||||
|
@ -2348,19 +2344,14 @@ class API():
|
||||||
# exist() needs a / or \ at the end to work for directories
|
# exist() needs a / or \ at the end to work for directories
|
||||||
if folder is False:
|
if folder is False:
|
||||||
# files
|
# files
|
||||||
check = True if xbmcvfs.exists(path.encode('utf-8')) == 1 \
|
check = xbmcvfs.exists(utils.tryEncode(path)) == 1
|
||||||
else False
|
|
||||||
else:
|
else:
|
||||||
# directories
|
# directories
|
||||||
if "\\" in path:
|
if "\\" in path:
|
||||||
# Add the missing backslash
|
# Add the missing backslash
|
||||||
check = True if \
|
check = xbmcvfs.exists(utils.tryEncode(path + "\\")) == 1
|
||||||
xbmcvfs.exists((path + "\\").encode('utf-8')) == 1 \
|
|
||||||
else False
|
|
||||||
else:
|
else:
|
||||||
check = True if \
|
check = xbmcvfs.exists(utils.tryEncode(path + "/")) == 1
|
||||||
xbmcvfs.exists((path + "/").encode('utf-8')) == 1 \
|
|
||||||
else False
|
|
||||||
|
|
||||||
if check is False:
|
if check is False:
|
||||||
if forceCheck is False:
|
if forceCheck is False:
|
||||||
|
|
|
@ -53,10 +53,10 @@ class Artwork():
|
||||||
|
|
||||||
def single_urlencode(self, text):
|
def single_urlencode(self, text):
|
||||||
|
|
||||||
text = urllib.urlencode({'blahblahblah':text.encode("utf-8")}) #urlencode needs a utf- string
|
text = urllib.urlencode({'blahblahblah': utils.tryEncode(text)}) #urlencode needs a utf- string
|
||||||
text = text[13:]
|
text = text[13:]
|
||||||
|
|
||||||
return text.decode("utf-8") #return the result again as unicode
|
return utils.tryDecode(text) #return the result again as unicode
|
||||||
|
|
||||||
def setKodiWebServerDetails(self):
|
def setKodiWebServerDetails(self):
|
||||||
# Get the Kodi webserver details - used to set the texture cache
|
# Get the Kodi webserver details - used to set the texture cache
|
||||||
|
@ -167,7 +167,7 @@ class Artwork():
|
||||||
string = xbmcaddon.Addon().getLocalizedString
|
string = xbmcaddon.Addon().getLocalizedString
|
||||||
|
|
||||||
if not xbmcgui.Dialog().yesno(
|
if not xbmcgui.Dialog().yesno(
|
||||||
"Image Texture Cache", string(39250).encode('utf-8')):
|
"Image Texture Cache", string(39250)):
|
||||||
return
|
return
|
||||||
|
|
||||||
self.logMsg("Doing Image Cache Sync", 1)
|
self.logMsg("Doing Image Cache Sync", 1)
|
||||||
|
@ -177,19 +177,23 @@ class Artwork():
|
||||||
|
|
||||||
# ask to rest all existing or not
|
# ask to rest all existing or not
|
||||||
if xbmcgui.Dialog().yesno(
|
if xbmcgui.Dialog().yesno(
|
||||||
"Image Texture Cache", string(39251).encode('utf-8'), ""):
|
"Image Texture Cache", string(39251), ""):
|
||||||
self.logMsg("Resetting all cache data first", 1)
|
self.logMsg("Resetting all cache data first", 1)
|
||||||
# Remove all existing textures first
|
# Remove all existing textures first
|
||||||
path = xbmc.translatePath("special://thumbnails/").decode('utf-8')
|
path = utils.tryDecode(xbmc.translatePath("special://thumbnails/"))
|
||||||
if utils.IfExists(path):
|
if utils.IfExists(path):
|
||||||
allDirs, allFiles = xbmcvfs.listdir(path)
|
allDirs, allFiles = xbmcvfs.listdir(path)
|
||||||
for dir in allDirs:
|
for dir in allDirs:
|
||||||
allDirs, allFiles = xbmcvfs.listdir(path+dir)
|
allDirs, allFiles = xbmcvfs.listdir(path+dir)
|
||||||
for file in allFiles:
|
for file in allFiles:
|
||||||
if os.path.supports_unicode_filenames:
|
if os.path.supports_unicode_filenames:
|
||||||
xbmcvfs.delete(os.path.join(path+dir.decode('utf-8'),file.decode('utf-8')))
|
xbmcvfs.delete(os.path.join(
|
||||||
|
path + utils.tryDecode(dir),
|
||||||
|
utils.tryDecode(file)))
|
||||||
else:
|
else:
|
||||||
xbmcvfs.delete(os.path.join(path.encode('utf-8')+dir,file))
|
xbmcvfs.delete(os.path.join(
|
||||||
|
utils.tryEncode(path) + dir,
|
||||||
|
file))
|
||||||
|
|
||||||
# remove all existing data from texture DB
|
# remove all existing data from texture DB
|
||||||
textureconnection = utils.kodiSQL('texture')
|
textureconnection = utils.kodiSQL('texture')
|
||||||
|
@ -467,7 +471,8 @@ class Artwork():
|
||||||
self.logMsg("Database is locked. Skip deletion process.", 1)
|
self.logMsg("Database is locked. Skip deletion process.", 1)
|
||||||
|
|
||||||
else: # Delete thumbnail as well as the entry
|
else: # Delete thumbnail as well as the entry
|
||||||
thumbnails = xbmc.translatePath("special://thumbnails/%s" % cachedurl).decode('utf-8')
|
thumbnails = utils.tryDecode(
|
||||||
|
xbmc.translatePath("special://thumbnails/%s" % cachedurl))
|
||||||
self.logMsg("Deleting cached thumbnail: %s" % thumbnails, 1)
|
self.logMsg("Deleting cached thumbnail: %s" % thumbnails, 1)
|
||||||
xbmcvfs.delete(thumbnails)
|
xbmcvfs.delete(thumbnails)
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ from uuid import uuid4
|
||||||
import xbmc
|
import xbmc
|
||||||
import xbmcaddon
|
import xbmcaddon
|
||||||
|
|
||||||
from utils import logging, window, settings
|
from utils import logging, window, settings, tryDecode
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
@ -67,8 +67,7 @@ class ClientInfo():
|
||||||
def getDeviceName(self):
|
def getDeviceName(self):
|
||||||
if settings('deviceNameOpt') == "false":
|
if settings('deviceNameOpt') == "false":
|
||||||
# Use Kodi's deviceName
|
# Use Kodi's deviceName
|
||||||
deviceName = xbmc.getInfoLabel(
|
deviceName = tryDecode(xbmc.getInfoLabel('System.FriendlyName'))
|
||||||
'System.FriendlyName').decode('utf-8')
|
|
||||||
else:
|
else:
|
||||||
deviceName = settings('deviceName')
|
deviceName = settings('deviceName')
|
||||||
deviceName = deviceName.replace("\"", "_")
|
deviceName = deviceName.replace("\"", "_")
|
||||||
|
|
|
@ -606,15 +606,15 @@ def getThemeMedia():
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
library = xbmc.translatePath(
|
library = utils.tryDecode(xbmc.translatePath(
|
||||||
"special://profile/addon_data/plugin.video.plexkodiconnect/library/").decode('utf-8')
|
"special://profile/addon_data/plugin.video.plexkodiconnect/library/"))
|
||||||
# Create library directory
|
# Create library directory
|
||||||
if not utils.IfExists(library):
|
if not utils.IfExists(library):
|
||||||
xbmcvfs.mkdir(library)
|
xbmcvfs.mkdir(library)
|
||||||
|
|
||||||
# Set custom path for user
|
# Set custom path for user
|
||||||
tvtunes_path = xbmc.translatePath(
|
tvtunes_path = utils.tryDecode(xbmc.translatePath(
|
||||||
"special://profile/addon_data/script.tvtunes/").decode('utf-8')
|
"special://profile/addon_data/script.tvtunes/"))
|
||||||
if xbmcvfs.exists(tvtunes_path):
|
if xbmcvfs.exists(tvtunes_path):
|
||||||
tvtunes = xbmcaddon.Addon(id="script.tvtunes")
|
tvtunes = xbmcaddon.Addon(id="script.tvtunes")
|
||||||
tvtunes.setSetting('custom_path_enable', "true")
|
tvtunes.setSetting('custom_path_enable', "true")
|
||||||
|
@ -644,7 +644,8 @@ def getThemeMedia():
|
||||||
for item in result['Items']:
|
for item in result['Items']:
|
||||||
itemId = item['Id']
|
itemId = item['Id']
|
||||||
folderName = item['Name']
|
folderName = item['Name']
|
||||||
folderName = utils.normalize_string(folderName.encode('utf-8'))
|
folderName = utils.normalize_string(
|
||||||
|
utils.tryEncode(folderName))
|
||||||
itemIds[itemId] = folderName
|
itemIds[itemId] = folderName
|
||||||
|
|
||||||
# Get paths for theme videos
|
# Get paths for theme videos
|
||||||
|
@ -670,7 +671,7 @@ def getThemeMedia():
|
||||||
playurl = putils.directPlay()
|
playurl = putils.directPlay()
|
||||||
else:
|
else:
|
||||||
playurl = putils.directStream()
|
playurl = putils.directStream()
|
||||||
pathstowrite += ('<file>%s</file>' % playurl.encode('utf-8'))
|
pathstowrite += ('<file>%s</file>' % utils.tryEncode(playurl))
|
||||||
|
|
||||||
# Check if the item has theme songs and add them
|
# Check if the item has theme songs and add them
|
||||||
url = "{server}/emby/Items/%s/ThemeSongs?format=json" % itemId
|
url = "{server}/emby/Items/%s/ThemeSongs?format=json" % itemId
|
||||||
|
@ -683,7 +684,7 @@ def getThemeMedia():
|
||||||
playurl = putils.directPlay()
|
playurl = putils.directPlay()
|
||||||
else:
|
else:
|
||||||
playurl = putils.directStream()
|
playurl = putils.directStream()
|
||||||
pathstowrite += ('<file>%s</file>' % playurl.encode('utf-8'))
|
pathstowrite += ('<file>%s</file>' % utils.tryEncode(playurl))
|
||||||
|
|
||||||
nfo_file.write(
|
nfo_file.write(
|
||||||
'<tvtunes>%s</tvtunes>' % pathstowrite
|
'<tvtunes>%s</tvtunes>' % pathstowrite
|
||||||
|
@ -700,7 +701,8 @@ def getThemeMedia():
|
||||||
for item in result['Items']:
|
for item in result['Items']:
|
||||||
itemId = item['Id']
|
itemId = item['Id']
|
||||||
folderName = item['Name']
|
folderName = item['Name']
|
||||||
folderName = utils.normalize_string(folderName.encode('utf-8'))
|
folderName = utils.normalize_string(
|
||||||
|
utils.tryEncode(folderName))
|
||||||
musicitemIds[itemId] = folderName
|
musicitemIds[itemId] = folderName
|
||||||
|
|
||||||
# Get paths
|
# Get paths
|
||||||
|
@ -731,7 +733,7 @@ def getThemeMedia():
|
||||||
playurl = putils.directPlay()
|
playurl = putils.directPlay()
|
||||||
else:
|
else:
|
||||||
playurl = putils.directStream()
|
playurl = putils.directStream()
|
||||||
pathstowrite += ('<file>%s</file>' % playurl.encode('utf-8'))
|
pathstowrite += ('<file>%s</file>' % utils.tryEncode(playurl))
|
||||||
|
|
||||||
nfo_file.write(
|
nfo_file.write(
|
||||||
'<tvtunes>%s</tvtunes>' % pathstowrite
|
'<tvtunes>%s</tvtunes>' % pathstowrite
|
||||||
|
@ -781,12 +783,16 @@ def BrowseContent(viewname, browse_type="", folderid=""):
|
||||||
if not folderid:
|
if not folderid:
|
||||||
views = PlexFunctions.GetPlexCollections()
|
views = PlexFunctions.GetPlexCollections()
|
||||||
for view in views:
|
for view in views:
|
||||||
if view.get("name") == viewname.decode('utf-8'):
|
if view.get("name") == utils.tryDecode(viewname):
|
||||||
folderid = view.get("id")
|
folderid = view.get("id")
|
||||||
break
|
break
|
||||||
|
|
||||||
if viewname is not None:
|
if viewname is not None:
|
||||||
utils.logMsg("BrowseContent","viewname: %s - type: %s - folderid: %s - filter: %s" %(viewname.decode('utf-8'), browse_type.decode('utf-8'), folderid.decode('utf-8'), filter_type.decode('utf-8')))
|
utils.logMsg("BrowseContent", "viewname: %s - type: %s - folderid: %s "
|
||||||
|
"- filter: %s" % (utils.tryDecode(viewname),
|
||||||
|
utils.tryDecode(browse_type),
|
||||||
|
utils.tryDecode(folderid),
|
||||||
|
utils.tryDecode(filter_type)))
|
||||||
#set the correct params for the content type
|
#set the correct params for the content type
|
||||||
#only proceed if we have a folderid
|
#only proceed if we have a folderid
|
||||||
if folderid:
|
if folderid:
|
||||||
|
@ -821,7 +827,11 @@ def BrowseContent(viewname, browse_type="", folderid=""):
|
||||||
li = createListItemFromEmbyItem(item,art,doUtils)
|
li = createListItemFromEmbyItem(item,art,doUtils)
|
||||||
if item.get("IsFolder") == True:
|
if item.get("IsFolder") == True:
|
||||||
#for folders we add an additional browse request, passing the folderId
|
#for folders we add an additional browse request, passing the folderId
|
||||||
path = "%s?id=%s&mode=browsecontent&type=%s&folderid=%s" % (sys.argv[0].decode('utf-8'), viewname.decode('utf-8'), browse_type.decode('utf-8'), item.get("Id").decode('utf-8'))
|
path = "%s?id=%s&mode=browsecontent&type=%s&folderid=%s" \
|
||||||
|
% (utils.tryDecode(sys.argv[0]),
|
||||||
|
utils.tryDecode(viewname),
|
||||||
|
utils.tryDecode(browse_type),
|
||||||
|
utils.tryDecode(item.get("Id")))
|
||||||
xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=path, listitem=li, isFolder=True)
|
xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=path, listitem=li, isFolder=True)
|
||||||
else:
|
else:
|
||||||
#playable item, set plugin path and mediastreams
|
#playable item, set plugin path and mediastreams
|
||||||
|
@ -1330,16 +1340,16 @@ def getVideoFiles(plexId, params):
|
||||||
# Careful, returns encoded strings!
|
# Careful, returns encoded strings!
|
||||||
dirs, files = xbmcvfs.listdir(path)
|
dirs, files = xbmcvfs.listdir(path)
|
||||||
for file in files:
|
for file in files:
|
||||||
file = path + file.decode('utf-8')
|
file = path + utils.tryDecode(file)
|
||||||
li = xbmcgui.ListItem(file, path=file)
|
li = xbmcgui.ListItem(file, path=file)
|
||||||
xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),
|
xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),
|
||||||
url=file.encode('utf-8'),
|
url=utils.tryEncode(file),
|
||||||
listitem=li)
|
listitem=li)
|
||||||
for dir in dirs:
|
for dir in dirs:
|
||||||
dir = path + dir.decode('utf-8')
|
dir = path + utils.tryDecode(dir)
|
||||||
li = xbmcgui.ListItem(dir, path=dir)
|
li = xbmcgui.ListItem(dir, path=dir)
|
||||||
xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),
|
xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),
|
||||||
url=dir.encode('utf-8'),
|
url=utils.tryEncode(dir),
|
||||||
listitem=li,
|
listitem=li,
|
||||||
isFolder=True)
|
isFolder=True)
|
||||||
else:
|
else:
|
||||||
|
@ -1367,7 +1377,8 @@ def getExtraFanArt(embyId,embyPath):
|
||||||
|
|
||||||
# We need to store the images locally for this to work
|
# We need to store the images locally for this to work
|
||||||
# because of the caching system in xbmc
|
# because of the caching system in xbmc
|
||||||
fanartDir = xbmc.translatePath("special://thumbnails/emby/%s/" % embyId).decode('utf-8')
|
fanartDir = utils.tryDecode(xbmc.translatePath(
|
||||||
|
"special://thumbnails/emby/%s/" % embyId))
|
||||||
|
|
||||||
if not xbmcvfs.exists(fanartDir):
|
if not xbmcvfs.exists(fanartDir):
|
||||||
# Download the images to the cache directory
|
# Download the images to the cache directory
|
||||||
|
@ -1383,7 +1394,9 @@ def getExtraFanArt(embyId,embyPath):
|
||||||
if os.path.supports_unicode_filenames:
|
if os.path.supports_unicode_filenames:
|
||||||
fanartFile = os.path.join(fanartDir, "fanart%s.jpg" % tag)
|
fanartFile = os.path.join(fanartDir, "fanart%s.jpg" % tag)
|
||||||
else:
|
else:
|
||||||
fanartFile = os.path.join(fanartDir.encode("utf-8"), "fanart%s.jpg" % tag.encode("utf-8"))
|
fanartFile = os.path.join(
|
||||||
|
utils.tryEncode(fanartDir),
|
||||||
|
"fanart%s.jpg" % utils.tryEncode(tag))
|
||||||
li = xbmcgui.ListItem(tag, path=fanartFile)
|
li = xbmcgui.ListItem(tag, path=fanartFile)
|
||||||
xbmcplugin.addDirectoryItem(
|
xbmcplugin.addDirectoryItem(
|
||||||
handle=int(sys.argv[1]),
|
handle=int(sys.argv[1]),
|
||||||
|
@ -1396,7 +1409,7 @@ def getExtraFanArt(embyId,embyPath):
|
||||||
# Use existing cached images
|
# Use existing cached images
|
||||||
dirs, files = xbmcvfs.listdir(fanartDir)
|
dirs, files = xbmcvfs.listdir(fanartDir)
|
||||||
for file in files:
|
for file in files:
|
||||||
fanartFile = os.path.join(fanartDir, file.decode('utf-8'))
|
fanartFile = os.path.join(fanartDir, utils.tryDecode(file))
|
||||||
li = xbmcgui.ListItem(file, path=fanartFile)
|
li = xbmcgui.ListItem(file, path=fanartFile)
|
||||||
xbmcplugin.addDirectoryItem(
|
xbmcplugin.addDirectoryItem(
|
||||||
handle=int(sys.argv[1]),
|
handle=int(sys.argv[1]),
|
||||||
|
@ -1458,7 +1471,11 @@ def BrowsePlexContent(viewid, mediatype="", nodetype=""):
|
||||||
# folderId
|
# folderId
|
||||||
li.setProperty('IsFolder', 'true')
|
li.setProperty('IsFolder', 'true')
|
||||||
li.setProperty('IsPlayable', 'false')
|
li.setProperty('IsPlayable', 'false')
|
||||||
path = "%s?id=%s&mode=browsecontent&type=%s&folderid=%s" % (sys.argv[0].decode('utf-8'), viewname.decode('utf-8'), type.decode('utf-8'), item.get("Id").decode('utf-8'))
|
path = "%s?id=%s&mode=browsecontent&type=%s&folderid=%s" \
|
||||||
|
% (utils.tryDecode(sys.argv[0]),
|
||||||
|
utils.tryDecode(viewname),
|
||||||
|
utils.tryDecode(type),
|
||||||
|
utils.tryDecode(item.get("Id")))
|
||||||
xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=path, listitem=li, isFolder=True)
|
xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=path, listitem=li, isFolder=True)
|
||||||
else:
|
else:
|
||||||
# playable item, set plugin path and mediastreams
|
# playable item, set plugin path and mediastreams
|
||||||
|
|
|
@ -432,7 +432,7 @@ class Movies(Items):
|
||||||
# Set plugin path and media flags using real filename
|
# Set plugin path and media flags using real filename
|
||||||
path = "plugin://plugin.video.plexkodiconnect.movies/"
|
path = "plugin://plugin.video.plexkodiconnect.movies/"
|
||||||
params = {
|
params = {
|
||||||
'filename': API.getKey().encode('utf-8'),
|
'filename': utils.tryEncode(API.getKey()),
|
||||||
'id': itemid,
|
'id': itemid,
|
||||||
'dbid': movieid,
|
'dbid': movieid,
|
||||||
'mode': "play"
|
'mode': "play"
|
||||||
|
@ -691,7 +691,7 @@ class MusicVideos(Items):
|
||||||
path = "plugin://plugin.video.plexkodiconnect.musicvideos/"
|
path = "plugin://plugin.video.plexkodiconnect.musicvideos/"
|
||||||
params = {
|
params = {
|
||||||
|
|
||||||
'filename': filename.encode('utf-8'),
|
'filename': utils.tryEncode(filename),
|
||||||
'id': itemid,
|
'id': itemid,
|
||||||
'dbid': mvideoid,
|
'dbid': mvideoid,
|
||||||
'mode': "play"
|
'mode': "play"
|
||||||
|
@ -1332,7 +1332,7 @@ class TVShows(Items):
|
||||||
filename = 'file_not_found'
|
filename = 'file_not_found'
|
||||||
path = "plugin://plugin.video.plexkodiconnect.tvshows/%s/" % seriesId
|
path = "plugin://plugin.video.plexkodiconnect.tvshows/%s/" % seriesId
|
||||||
params = {
|
params = {
|
||||||
'filename': filename.encode('utf-8'),
|
'filename': utils.tryEncode(filename),
|
||||||
'id': itemid,
|
'id': itemid,
|
||||||
'dbid': episodeid,
|
'dbid': episodeid,
|
||||||
'mode': "play"
|
'mode': "play"
|
||||||
|
|
|
@ -173,7 +173,7 @@ class KodiMonitor(xbmc.Monitor):
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
count += 1
|
count += 1
|
||||||
log("Currently playing file is: %s" % currentFile.decode('utf-8'), 1)
|
log("Currently playing file is: %s" % utils.tryDecode(currentFile), 1)
|
||||||
|
|
||||||
# Try to get a Kodi ID
|
# Try to get a Kodi ID
|
||||||
item = data.get('item')
|
item = data.get('item')
|
||||||
|
@ -217,7 +217,7 @@ class KodiMonitor(xbmc.Monitor):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Save currentFile for cleanup later and to be able to access refs
|
# Save currentFile for cleanup later and to be able to access refs
|
||||||
window('plex_lastPlayedFiled', value=currentFile.decode('utf-8'))
|
window('plex_lastPlayedFiled', value=utils.tryDecode(currentFile))
|
||||||
window('Plex_currently_playing_itemid', value=plexid)
|
window('Plex_currently_playing_itemid', value=plexid)
|
||||||
window("emby_%s.itemid" % currentFile, value=plexid)
|
window("emby_%s.itemid" % currentFile, value=plexid)
|
||||||
log('Finish playback startup', 1)
|
log('Finish playback startup', 1)
|
||||||
|
|
|
@ -1619,8 +1619,8 @@ class LibrarySync(Thread):
|
||||||
# Database does not exists
|
# Database does not exists
|
||||||
log("The current Kodi version is incompatible "
|
log("The current Kodi version is incompatible "
|
||||||
"to know which Kodi versions are supported.", -1)
|
"to know which Kodi versions are supported.", -1)
|
||||||
log('Current Kodi version: %s' % xbmc.getInfoLabel(
|
log('Current Kodi version: %s' % utils.tryDecode(
|
||||||
'System.BuildVersion').decode('utf-8'))
|
xbmc.getInfoLabel('System.BuildVersion')))
|
||||||
# "Current Kodi version is unsupported, cancel lib sync"
|
# "Current Kodi version is unsupported, cancel lib sync"
|
||||||
self.dialog.ok(heading=self.addonName,
|
self.dialog.ok(heading=self.addonName,
|
||||||
line1=string(39403))
|
line1=string(39403))
|
||||||
|
|
|
@ -32,7 +32,7 @@ def getRealFileName(filename, isTemp=False):
|
||||||
if os.path.supports_unicode_filenames:
|
if os.path.supports_unicode_filenames:
|
||||||
checkfile = filename
|
checkfile = filename
|
||||||
else:
|
else:
|
||||||
checkfile = filename.encode("utf-8")
|
checkfile = utils.tryEncode(filename)
|
||||||
|
|
||||||
# determine if our python module is able to access the file directly...
|
# determine if our python module is able to access the file directly...
|
||||||
if os.path.exists(checkfile):
|
if os.path.exists(checkfile):
|
||||||
|
@ -46,7 +46,7 @@ def getRealFileName(filename, isTemp=False):
|
||||||
else: filepart = filename.split("\\")[-1]
|
else: filepart = filename.split("\\")[-1]
|
||||||
tempfile = "special://temp/"+filepart
|
tempfile = "special://temp/"+filepart
|
||||||
xbmcvfs.copy(filename, tempfile)
|
xbmcvfs.copy(filename, tempfile)
|
||||||
filename = xbmc.translatePath(tempfile).decode("utf-8")
|
filename = utils.tryDecode(xbmc.translatePath(tempfile))
|
||||||
|
|
||||||
return (isTemp,filename)
|
return (isTemp,filename)
|
||||||
|
|
||||||
|
@ -242,7 +242,7 @@ def updateRatingToFile(rating, file):
|
||||||
else: filepart = file.split("\\")[-1]
|
else: filepart = file.split("\\")[-1]
|
||||||
tempfile = "special://temp/"+filepart
|
tempfile = "special://temp/"+filepart
|
||||||
xbmcvfs.copy(file, tempfile)
|
xbmcvfs.copy(file, tempfile)
|
||||||
tempfile = xbmc.translatePath(tempfile).decode("utf-8")
|
tempfile = utils.tryDecode(xbmc.translatePath(tempfile))
|
||||||
|
|
||||||
logMsg( "setting song rating: %s for filename: %s - using tempfile: %s" %(rating,file,tempfile))
|
logMsg( "setting song rating: %s for filename: %s - using tempfile: %s" %(rating,file,tempfile))
|
||||||
|
|
||||||
|
|
|
@ -75,14 +75,14 @@ class PlaybackUtils():
|
||||||
% item[0][0][0].attrib.get('key'), -1)
|
% item[0][0][0].attrib.get('key'), -1)
|
||||||
return xbmcplugin.setResolvedUrl(
|
return xbmcplugin.setResolvedUrl(
|
||||||
int(sys.argv[1]), False, listitem)
|
int(sys.argv[1]), False, listitem)
|
||||||
playurl = xml[0].attrib.get('key').encode('utf-8')
|
playurl = utils.tryEncode(xml[0].attrib.get('key'))
|
||||||
window('emby_%s.playmethod' % playurl, value='DirectStream')
|
window('emby_%s.playmethod' % playurl, value='DirectStream')
|
||||||
|
|
||||||
playmethod = window('emby_%s.playmethod' % playurl)
|
playmethod = window('emby_%s.playmethod' % playurl)
|
||||||
if playmethod == "Transcode":
|
if playmethod == "Transcode":
|
||||||
window('emby_%s.playmethod' % playurl, clear=True)
|
window('emby_%s.playmethod' % playurl, clear=True)
|
||||||
playurl = playutils.audioSubsPref(
|
playurl = utils.tryEncode(playutils.audioSubsPref(
|
||||||
listitem, playurl.decode('utf-8')).encode('utf-8')
|
listitem, utils.tryDecode(playurl)))
|
||||||
window('emby_%s.playmethod' % playurl, "Transcode")
|
window('emby_%s.playmethod' % playurl, "Transcode")
|
||||||
listitem.setPath(playurl)
|
listitem.setPath(playurl)
|
||||||
self.setProperties(playurl, listitem)
|
self.setProperties(playurl, listitem)
|
||||||
|
@ -195,8 +195,8 @@ class PlaybackUtils():
|
||||||
# For transcoding only, ask for audio/subs pref
|
# For transcoding only, ask for audio/subs pref
|
||||||
if window('emby_%s.playmethod' % playurl) == "Transcode":
|
if window('emby_%s.playmethod' % playurl) == "Transcode":
|
||||||
window('emby_%s.playmethod' % playurl, clear=True)
|
window('emby_%s.playmethod' % playurl, clear=True)
|
||||||
playurl = playutils.audioSubsPref(
|
playurl = utils.tryEncode(playutils.audioSubsPref(
|
||||||
listitem, playurl.decode('utf-8')).encode('utf-8')
|
listitem, utils.tryDecode(playurl)))
|
||||||
window('emby_%s.playmethod' % playurl, value="Transcode")
|
window('emby_%s.playmethod' % playurl, value="Transcode")
|
||||||
|
|
||||||
listitem.setPath(playurl)
|
listitem.setPath(playurl)
|
||||||
|
|
|
@ -72,7 +72,7 @@ class Player(xbmc.Player):
|
||||||
|
|
||||||
# Save currentFile for cleanup later and for references
|
# Save currentFile for cleanup later and for references
|
||||||
self.currentFile = currentFile
|
self.currentFile = currentFile
|
||||||
window('plex_lastPlayedFiled', value=currentFile.decode('utf-8'))
|
window('plex_lastPlayedFiled', value=utils.tryDecode(currentFile))
|
||||||
# We may need to wait for info to be set in kodi monitor
|
# We may need to wait for info to be set in kodi monitor
|
||||||
itemId = window("emby_%s.itemid" % currentFile)
|
itemId = window("emby_%s.itemid" % currentFile)
|
||||||
count = 0
|
count = 0
|
||||||
|
@ -87,7 +87,7 @@ class Player(xbmc.Player):
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
self.logMsg("ONPLAYBACK_STARTED: %s itemid: %s"
|
self.logMsg("ONPLAYBACK_STARTED: %s itemid: %s"
|
||||||
% (currentFile.decode('utf-8'), itemId), 0)
|
% (utils.tryDecode(currentFile), itemId), 0)
|
||||||
|
|
||||||
embyitem = "emby_%s" % currentFile
|
embyitem = "emby_%s" % currentFile
|
||||||
runtime = window("%s.runtime" % embyitem)
|
runtime = window("%s.runtime" % embyitem)
|
||||||
|
@ -399,7 +399,7 @@ class Player(xbmc.Player):
|
||||||
def onPlayBackPaused(self):
|
def onPlayBackPaused(self):
|
||||||
|
|
||||||
currentFile = self.currentFile
|
currentFile = self.currentFile
|
||||||
self.logMsg("PLAYBACK_PAUSED: %s" % currentFile.decode('utf-8'), 2)
|
self.logMsg("PLAYBACK_PAUSED: %s" % utils.tryDecode(currentFile), 2)
|
||||||
|
|
||||||
if self.played_info.get(currentFile):
|
if self.played_info.get(currentFile):
|
||||||
self.played_info[currentFile]['paused'] = True
|
self.played_info[currentFile]['paused'] = True
|
||||||
|
@ -409,7 +409,7 @@ class Player(xbmc.Player):
|
||||||
def onPlayBackResumed(self):
|
def onPlayBackResumed(self):
|
||||||
|
|
||||||
currentFile = self.currentFile
|
currentFile = self.currentFile
|
||||||
self.logMsg("PLAYBACK_RESUMED: %s" % currentFile.decode('utf-8'), 2)
|
self.logMsg("PLAYBACK_RESUMED: %s" % utils.tryDecode(currentFile), 2)
|
||||||
|
|
||||||
if self.played_info.get(currentFile):
|
if self.played_info.get(currentFile):
|
||||||
self.played_info[currentFile]['paused'] = False
|
self.played_info[currentFile]['paused'] = False
|
||||||
|
@ -419,7 +419,7 @@ class Player(xbmc.Player):
|
||||||
def onPlayBackSeek(self, time, seekOffset):
|
def onPlayBackSeek(self, time, seekOffset):
|
||||||
# Make position when seeking a bit more accurate
|
# Make position when seeking a bit more accurate
|
||||||
currentFile = self.currentFile
|
currentFile = self.currentFile
|
||||||
self.logMsg("PLAYBACK_SEEK: %s" % currentFile.decode('utf-8'), 2)
|
self.logMsg("PLAYBACK_SEEK: %s" % utils.tryDecode(currentFile), 2)
|
||||||
|
|
||||||
if self.played_info.get(currentFile):
|
if self.played_info.get(currentFile):
|
||||||
position = self.xbmcplayer.getTime()
|
position = self.xbmcplayer.getTime()
|
||||||
|
|
|
@ -45,13 +45,14 @@ class PlayUtils():
|
||||||
|
|
||||||
if playurl:
|
if playurl:
|
||||||
log("File is direct playing.", 1)
|
log("File is direct playing.", 1)
|
||||||
playurl = playurl.encode('utf-8')
|
playurl = utils.tryEncode(playurl)
|
||||||
# Set playmethod property
|
# Set playmethod property
|
||||||
window('emby_%s.playmethod' % playurl, "DirectPlay")
|
window('emby_%s.playmethod' % playurl, "DirectPlay")
|
||||||
|
|
||||||
elif self.isDirectStream():
|
elif self.isDirectStream():
|
||||||
self.logMsg("File is direct streaming.", 1)
|
self.logMsg("File is direct streaming.", 1)
|
||||||
playurl = self.API.getTranscodeVideoPath('DirectStream').encode('utf-8')
|
playurl = utils.tryEncode(
|
||||||
|
self.API.getTranscodeVideoPath('DirectStream'))
|
||||||
# Set playmethod property
|
# Set playmethod property
|
||||||
utils.window('emby_%s.playmethod' % playurl, "DirectStream")
|
utils.window('emby_%s.playmethod' % playurl, "DirectStream")
|
||||||
|
|
||||||
|
@ -62,9 +63,9 @@ class PlayUtils():
|
||||||
'videoResolution': self.getResolution(),
|
'videoResolution': self.getResolution(),
|
||||||
'videoQuality': '100'
|
'videoQuality': '100'
|
||||||
}
|
}
|
||||||
playurl = self.API.getTranscodeVideoPath(
|
playurl = utils.tryEncode(self.API.getTranscodeVideoPath(
|
||||||
'Transcode',
|
'Transcode',
|
||||||
quality=quality).encode('utf-8')
|
quality=quality))
|
||||||
# Set playmethod property
|
# Set playmethod property
|
||||||
window('emby_%s.playmethod' % playurl, value="Transcode")
|
window('emby_%s.playmethod' % playurl, value="Transcode")
|
||||||
|
|
||||||
|
@ -306,7 +307,7 @@ class PlayUtils():
|
||||||
|
|
||||||
#audioStreamsChannelsList[audioNum] = stream.attrib['channels']
|
#audioStreamsChannelsList[audioNum] = stream.attrib['channels']
|
||||||
audioStreamsList.append(index)
|
audioStreamsList.append(index)
|
||||||
audioStreams.append(track.encode('utf-8'))
|
audioStreams.append(utils.tryEncode(track))
|
||||||
audioNum += 1
|
audioNum += 1
|
||||||
|
|
||||||
# Subtitles
|
# Subtitles
|
||||||
|
@ -330,7 +331,7 @@ class PlayUtils():
|
||||||
downloadableStreams.append(index)
|
downloadableStreams.append(index)
|
||||||
|
|
||||||
subtitleStreamsList.append(index)
|
subtitleStreamsList.append(index)
|
||||||
subtitleStreams.append(track.encode('utf-8'))
|
subtitleStreams.append(utils.tryEncode(track))
|
||||||
subNum += 1
|
subNum += 1
|
||||||
|
|
||||||
if audioNum > 1:
|
if audioNum > 1:
|
||||||
|
@ -362,7 +363,7 @@ class PlayUtils():
|
||||||
% (self.server, selectSubsIndex)
|
% (self.server, selectSubsIndex)
|
||||||
url = self.API.addPlexHeadersToUrl(url)
|
url = self.API.addPlexHeadersToUrl(url)
|
||||||
self.logMsg("Downloadable sub: %s: %s" % (selectSubsIndex, url), 1)
|
self.logMsg("Downloadable sub: %s: %s" % (selectSubsIndex, url), 1)
|
||||||
listitem.setSubtitles([url.encode('utf-8')])
|
listitem.setSubtitles([utils.tryEncode(url)])
|
||||||
else:
|
else:
|
||||||
self.logMsg('Need to burn in subtitle %s' % selectSubsIndex, 1)
|
self.logMsg('Need to burn in subtitle %s' % selectSubsIndex, 1)
|
||||||
playurlprefs["subtitleStreamID"] = selectSubsIndex
|
playurlprefs["subtitleStreamID"] = selectSubsIndex
|
||||||
|
|
|
@ -247,8 +247,8 @@ class UserClient(threading.Thread):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Get /profile/addon_data
|
# Get /profile/addon_data
|
||||||
addondir = xbmc.translatePath(
|
addondir = utils.tryDecode(xbmc.translatePath(
|
||||||
self.addon.getAddonInfo('profile')).decode('utf-8')
|
self.addon.getAddonInfo('profile')))
|
||||||
hasSettings = xbmcvfs.exists("%ssettings.xml" % addondir)
|
hasSettings = xbmcvfs.exists("%ssettings.xml" % addondir)
|
||||||
|
|
||||||
# If there's no settings.xml
|
# If there's no settings.xml
|
||||||
|
|
|
@ -98,7 +98,7 @@ def IfExists(path):
|
||||||
|
|
||||||
Returns True if path exists, else false
|
Returns True if path exists, else false
|
||||||
"""
|
"""
|
||||||
dummyfile = os.path.join(path, 'dummyfile.txt').encode('utf-8')
|
dummyfile = tryEncode(os.path.join(path, 'dummyfile.txt'))
|
||||||
try:
|
try:
|
||||||
etree.ElementTree(etree.Element('test')).write(dummyfile)
|
etree.ElementTree(etree.Element('test')).write(dummyfile)
|
||||||
except:
|
except:
|
||||||
|
@ -272,7 +272,7 @@ def logMsg(title, msg, level=1):
|
||||||
except UnicodeEncodeError:
|
except UnicodeEncodeError:
|
||||||
try:
|
try:
|
||||||
xbmc.log("%s -> %s : %s" % (
|
xbmc.log("%s -> %s : %s" % (
|
||||||
title, func.co_name, msg.encode('utf-8')),
|
title, func.co_name, tryEncode(msg)),
|
||||||
level=kodiLevel[level])
|
level=kodiLevel[level])
|
||||||
except:
|
except:
|
||||||
xbmc.log("%s -> %s : %s" % (
|
xbmc.log("%s -> %s : %s" % (
|
||||||
|
@ -283,7 +283,7 @@ def logMsg(title, msg, level=1):
|
||||||
xbmc.log("%s -> %s" % (title, msg), level=kodiLevel[level])
|
xbmc.log("%s -> %s" % (title, msg), level=kodiLevel[level])
|
||||||
except UnicodeEncodeError:
|
except UnicodeEncodeError:
|
||||||
try:
|
try:
|
||||||
xbmc.log("%s -> %s" % (title, msg.encode('utf-8')),
|
xbmc.log("%s -> %s" % (title, tryEncode(msg)),
|
||||||
level=kodiLevel[level])
|
level=kodiLevel[level])
|
||||||
except:
|
except:
|
||||||
xbmc.log("%s -> %s " % (title, 'COULDNT LOG'),
|
xbmc.log("%s -> %s " % (title, 'COULDNT LOG'),
|
||||||
|
@ -301,16 +301,12 @@ def window(property, value=None, clear=False, windowid=10000):
|
||||||
WINDOW = xbmcgui.Window(windowid)
|
WINDOW = xbmcgui.Window(windowid)
|
||||||
|
|
||||||
#setproperty accepts both string and unicode but utf-8 strings are adviced by kodi devs because some unicode can give issues
|
#setproperty accepts both string and unicode but utf-8 strings are adviced by kodi devs because some unicode can give issues
|
||||||
'''if isinstance(property, unicode):
|
|
||||||
property = property.encode("utf-8")
|
|
||||||
if isinstance(value, unicode):
|
|
||||||
value = value.encode("utf-8")'''
|
|
||||||
if clear:
|
if clear:
|
||||||
WINDOW.clearProperty(property)
|
WINDOW.clearProperty(property)
|
||||||
elif value is not None:
|
elif value is not None:
|
||||||
WINDOW.setProperty(property, value.encode('utf-8'))
|
WINDOW.setProperty(property, tryEncode(value))
|
||||||
else:
|
else:
|
||||||
return WINDOW.getProperty(property).decode('utf-8')
|
return tryDecode(WINDOW.getProperty(property))
|
||||||
|
|
||||||
def settings(setting, value=None):
|
def settings(setting, value=None):
|
||||||
"""
|
"""
|
||||||
|
@ -323,10 +319,10 @@ def settings(setting, value=None):
|
||||||
|
|
||||||
if value is not None:
|
if value is not None:
|
||||||
# Takes string or unicode by default!
|
# Takes string or unicode by default!
|
||||||
addon.setSetting(setting, value.encode('utf-8'))
|
addon.setSetting(setting, tryEncode(value))
|
||||||
else:
|
else:
|
||||||
# Should return unicode by default, but just in case
|
# Should return unicode by default, but just in case
|
||||||
return addon.getSetting(setting).decode('utf-8')
|
return tryDecode(addon.getSetting(setting))
|
||||||
|
|
||||||
def language(stringid):
|
def language(stringid):
|
||||||
# Central string retrieval
|
# Central string retrieval
|
||||||
|
@ -337,11 +333,12 @@ def language(stringid):
|
||||||
def kodiSQL(media_type="video"):
|
def kodiSQL(media_type="video"):
|
||||||
|
|
||||||
if media_type == "emby":
|
if media_type == "emby":
|
||||||
dbPath = xbmc.translatePath("special://database/emby.db").decode('utf-8')
|
dbPath = tryDecode(xbmc.translatePath("special://database/emby.db"))
|
||||||
elif media_type == "music":
|
elif media_type == "music":
|
||||||
dbPath = getKodiMusicDBPath()
|
dbPath = getKodiMusicDBPath()
|
||||||
elif media_type == "texture":
|
elif media_type == "texture":
|
||||||
dbPath = xbmc.translatePath("special://database/Textures13.db").decode('utf-8')
|
dbPath = tryDecode(xbmc.translatePath(
|
||||||
|
"special://database/Textures13.db"))
|
||||||
else:
|
else:
|
||||||
dbPath = getKodiVideoDBPath()
|
dbPath = getKodiVideoDBPath()
|
||||||
|
|
||||||
|
@ -359,9 +356,9 @@ def getKodiVideoDBPath():
|
||||||
"17": 104 # Krypton
|
"17": 104 # Krypton
|
||||||
}
|
}
|
||||||
|
|
||||||
dbPath = xbmc.translatePath(
|
dbPath = tryDecode(xbmc.translatePath(
|
||||||
"special://database/MyVideos%s.db"
|
"special://database/MyVideos%s.db"
|
||||||
% dbVersion.get(xbmc.getInfoLabel('System.BuildVersion')[:2], "")).decode('utf-8')
|
% dbVersion.get(xbmc.getInfoLabel('System.BuildVersion')[:2], "")))
|
||||||
return dbPath
|
return dbPath
|
||||||
|
|
||||||
def getKodiMusicDBPath():
|
def getKodiMusicDBPath():
|
||||||
|
@ -375,9 +372,9 @@ def getKodiMusicDBPath():
|
||||||
"17": 60 # Krypton
|
"17": 60 # Krypton
|
||||||
}
|
}
|
||||||
|
|
||||||
dbPath = xbmc.translatePath(
|
dbPath = tryDecode(xbmc.translatePath(
|
||||||
"special://database/MyMusic%s.db"
|
"special://database/MyMusic%s.db"
|
||||||
% dbVersion.get(xbmc.getInfoLabel('System.BuildVersion')[:2], "")).decode('utf-8')
|
% dbVersion.get(xbmc.getInfoLabel('System.BuildVersion')[:2], "")))
|
||||||
return dbPath
|
return dbPath
|
||||||
|
|
||||||
def getScreensaver():
|
def getScreensaver():
|
||||||
|
@ -479,16 +476,20 @@ def reset():
|
||||||
if resp:
|
if resp:
|
||||||
logMsg("EMBY", "Resetting all cached artwork.", 0)
|
logMsg("EMBY", "Resetting all cached artwork.", 0)
|
||||||
# Remove all existing textures first
|
# Remove all existing textures first
|
||||||
path = xbmc.translatePath("special://thumbnails/").decode('utf-8')
|
path = tryDecode(xbmc.translatePath("special://thumbnails/"))
|
||||||
if xbmcvfs.exists(path):
|
if xbmcvfs.exists(path):
|
||||||
allDirs, allFiles = xbmcvfs.listdir(path)
|
allDirs, allFiles = xbmcvfs.listdir(path)
|
||||||
for dir in allDirs:
|
for dir in allDirs:
|
||||||
allDirs, allFiles = xbmcvfs.listdir(path+dir)
|
allDirs, allFiles = xbmcvfs.listdir(path+dir)
|
||||||
for file in allFiles:
|
for file in allFiles:
|
||||||
if os.path.supports_unicode_filenames:
|
if os.path.supports_unicode_filenames:
|
||||||
xbmcvfs.delete(os.path.join(path+dir.decode('utf-8'),file.decode('utf-8')))
|
xbmcvfs.delete(os.path.join(
|
||||||
|
path + tryDecode(dir),
|
||||||
|
tryDecode(file)))
|
||||||
else:
|
else:
|
||||||
xbmcvfs.delete(os.path.join(path.encode('utf-8')+dir,file))
|
xbmcvfs.delete(os.path.join(
|
||||||
|
tryEncode(path) + dir,
|
||||||
|
file))
|
||||||
|
|
||||||
# remove all existing data from texture DB
|
# remove all existing data from texture DB
|
||||||
connection = kodiSQL('texture')
|
connection = kodiSQL('texture')
|
||||||
|
@ -510,9 +511,9 @@ def reset():
|
||||||
if resp:
|
if resp:
|
||||||
# Delete the settings
|
# Delete the settings
|
||||||
addon = xbmcaddon.Addon()
|
addon = xbmcaddon.Addon()
|
||||||
addondir = xbmc.translatePath(addon.getAddonInfo('profile')).decode('utf-8')
|
addondir = tryDecode(xbmc.translatePath(addon.getAddonInfo('profile')))
|
||||||
dataPath = "%ssettings.xml" % addondir
|
dataPath = "%ssettings.xml" % addondir
|
||||||
xbmcvfs.delete(dataPath.encode('utf-8'))
|
xbmcvfs.delete(tryEncode(dataPath))
|
||||||
logMsg("PLEX", "Deleting: settings.xml", 1)
|
logMsg("PLEX", "Deleting: settings.xml", 1)
|
||||||
|
|
||||||
dialog.ok(
|
dialog.ok(
|
||||||
|
@ -567,7 +568,7 @@ def normalize_nodes(text):
|
||||||
# Remove dots from the last character as windows can not have directories
|
# Remove dots from the last character as windows can not have directories
|
||||||
# with dots at the end
|
# with dots at the end
|
||||||
text = text.rstrip('.')
|
text = text.rstrip('.')
|
||||||
text = unicodedata.normalize('NFKD', unicode(text, 'utf-8')).encode('ascii', 'ignore')
|
text = tryEncode(unicodedata.normalize('NFKD', unicode(text, 'utf-8')))
|
||||||
|
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
@ -586,7 +587,7 @@ def normalize_string(text):
|
||||||
# Remove dots from the last character as windows can not have directories
|
# Remove dots from the last character as windows can not have directories
|
||||||
# with dots at the end
|
# with dots at the end
|
||||||
text = text.rstrip('.')
|
text = text.rstrip('.')
|
||||||
text = unicodedata.normalize('NFKD', unicode(text, 'utf-8')).encode('ascii', 'ignore')
|
text = tryEncode(unicodedata.normalize('NFKD', unicode(text, 'utf-8')))
|
||||||
|
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
@ -611,7 +612,7 @@ def guisettingsXML():
|
||||||
"""
|
"""
|
||||||
Returns special://userdata/guisettings.xml as an etree xml root element
|
Returns special://userdata/guisettings.xml as an etree xml root element
|
||||||
"""
|
"""
|
||||||
path = xbmc.translatePath("special://profile/").decode('utf-8')
|
path = tryDecode(xbmc.translatePath("special://profile/"))
|
||||||
xmlpath = "%sguisettings.xml" % path
|
xmlpath = "%sguisettings.xml" % path
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -670,7 +671,7 @@ def advancedSettingsXML():
|
||||||
usetags : set to "false"
|
usetags : set to "false"
|
||||||
findremotethumbs : set to "false"
|
findremotethumbs : set to "false"
|
||||||
"""
|
"""
|
||||||
path = xbmc.translatePath("special://profile/").decode('utf-8')
|
path = tryDecode(xbmc.translatePath("special://profile/"))
|
||||||
xmlpath = "%sadvancedsettings.xml" % path
|
xmlpath = "%sadvancedsettings.xml" % path
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -700,7 +701,7 @@ def advancedSettingsXML():
|
||||||
|
|
||||||
def sourcesXML():
|
def sourcesXML():
|
||||||
# To make Master lock compatible
|
# To make Master lock compatible
|
||||||
path = xbmc.translatePath("special://profile/").decode('utf-8')
|
path = tryDecode(xbmc.translatePath("special://profile/"))
|
||||||
xmlpath = "%ssources.xml" % path
|
xmlpath = "%ssources.xml" % path
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -741,7 +742,7 @@ def sourcesXML():
|
||||||
|
|
||||||
def passwordsXML():
|
def passwordsXML():
|
||||||
# To add network credentials
|
# To add network credentials
|
||||||
path = xbmc.translatePath("special://userdata/").decode('utf-8')
|
path = tryDecode(xbmc.translatePath("special://userdata/"))
|
||||||
xmlpath = "%spasswords.xml" % path
|
xmlpath = "%spasswords.xml" % path
|
||||||
logMsg('passwordsXML', 'Path to passwords.xml: %s' % xmlpath, 1)
|
logMsg('passwordsXML', 'Path to passwords.xml: %s' % xmlpath, 1)
|
||||||
|
|
||||||
|
@ -852,7 +853,7 @@ def playlistXSP(mediatype, tagname, viewid, viewtype="", delete=False):
|
||||||
"""
|
"""
|
||||||
Feed with tagname as unicode
|
Feed with tagname as unicode
|
||||||
"""
|
"""
|
||||||
path = xbmc.translatePath("special://profile/playlists/video/").decode('utf-8')
|
path = tryDecode(xbmc.translatePath("special://profile/playlists/video/"))
|
||||||
if viewtype == "mixed":
|
if viewtype == "mixed":
|
||||||
plname = "%s - %s" % (tagname, mediatype)
|
plname = "%s - %s" % (tagname, mediatype)
|
||||||
xsppath = "%sPlex %s - %s.xsp" % (path, viewid, mediatype)
|
xsppath = "%sPlex %s - %s.xsp" % (path, viewid, mediatype)
|
||||||
|
@ -861,15 +862,15 @@ def playlistXSP(mediatype, tagname, viewid, viewtype="", delete=False):
|
||||||
xsppath = "%sPlex %s.xsp" % (path, viewid)
|
xsppath = "%sPlex %s.xsp" % (path, viewid)
|
||||||
|
|
||||||
# Create the playlist directory
|
# Create the playlist directory
|
||||||
if not xbmcvfs.exists(path.encode('utf-8')):
|
if not xbmcvfs.exists(tryEncode(path)):
|
||||||
logMsg("PLEX", "Creating directory: %s" % path, 1)
|
logMsg("PLEX", "Creating directory: %s" % path, 1)
|
||||||
xbmcvfs.mkdirs(path.encode('utf-8'))
|
xbmcvfs.mkdirs(tryEncode(path))
|
||||||
|
|
||||||
# Only add the playlist if it doesn't already exists
|
# Only add the playlist if it doesn't already exists
|
||||||
if xbmcvfs.exists(xsppath.encode('utf-8')):
|
if xbmcvfs.exists(tryEncode(xsppath)):
|
||||||
logMsg('Path %s does exist' % xsppath, 1)
|
logMsg('Path %s does exist' % xsppath, 1)
|
||||||
if delete:
|
if delete:
|
||||||
xbmcvfs.delete(xsppath.encode('utf-8'))
|
xbmcvfs.delete(tryEncode(xsppath))
|
||||||
logMsg("PLEX", "Successfully removed playlist: %s." % tagname, 1)
|
logMsg("PLEX", "Successfully removed playlist: %s." % tagname, 1)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -882,12 +883,12 @@ def playlistXSP(mediatype, tagname, viewid, viewtype="", delete=False):
|
||||||
}
|
}
|
||||||
logMsg("Plex", "Writing playlist file to: %s" % xsppath, 1)
|
logMsg("Plex", "Writing playlist file to: %s" % xsppath, 1)
|
||||||
try:
|
try:
|
||||||
f = xbmcvfs.File(xsppath.encode('utf-8'), 'wb')
|
f = xbmcvfs.File(tryEncode(xsppath), 'wb')
|
||||||
except:
|
except:
|
||||||
logMsg("Plex", "Failed to create playlist: %s" % xsppath, -1)
|
logMsg("Plex", "Failed to create playlist: %s" % xsppath, -1)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
f.write((
|
f.write(tryEncode(
|
||||||
'<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>\n'
|
'<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>\n'
|
||||||
'<smartplaylist type="%s">\n\t'
|
'<smartplaylist type="%s">\n\t'
|
||||||
'<name>Plex %s</name>\n\t'
|
'<name>Plex %s</name>\n\t'
|
||||||
|
@ -896,35 +897,61 @@ def playlistXSP(mediatype, tagname, viewid, viewtype="", delete=False):
|
||||||
'<value>%s</value>\n\t'
|
'<value>%s</value>\n\t'
|
||||||
'</rule>\n'
|
'</rule>\n'
|
||||||
'</smartplaylist>\n'
|
'</smartplaylist>\n'
|
||||||
% (itemtypes.get(mediatype, mediatype), plname, tagname))
|
% (itemtypes.get(mediatype, mediatype), plname, tagname)))
|
||||||
.encode('utf-8'))
|
|
||||||
f.close()
|
f.close()
|
||||||
logMsg("Plex", "Successfully added playlist: %s" % tagname)
|
logMsg("Plex", "Successfully added playlist: %s" % tagname)
|
||||||
|
|
||||||
def deletePlaylists():
|
def deletePlaylists():
|
||||||
|
|
||||||
# Clean up the playlists
|
# Clean up the playlists
|
||||||
path = xbmc.translatePath("special://profile/playlists/video/").decode('utf-8')
|
path = tryDecode(xbmc.translatePath("special://profile/playlists/video/"))
|
||||||
dirs, files = xbmcvfs.listdir(path.encode('utf-8'))
|
dirs, files = xbmcvfs.listdir(tryEncode(path))
|
||||||
for file in files:
|
for file in files:
|
||||||
if file.decode('utf-8').startswith('Plex'):
|
if tryDecode(file).startswith('Plex'):
|
||||||
xbmcvfs.delete(("%s%s" % (path, file.decode('utf-8'))).encode('utf-8'))
|
xbmcvfs.delete(tryEncode("%s%s" % (path, tryDecode(file))))
|
||||||
|
|
||||||
def deleteNodes():
|
def deleteNodes():
|
||||||
|
|
||||||
# Clean up video nodes
|
# Clean up video nodes
|
||||||
import shutil
|
import shutil
|
||||||
path = xbmc.translatePath("special://profile/library/video/").decode('utf-8')
|
path = tryDecode(xbmc.translatePath("special://profile/library/video/"))
|
||||||
dirs, files = xbmcvfs.listdir(path.encode('utf-8'))
|
dirs, files = xbmcvfs.listdir(tryEncode(path))
|
||||||
for dir in dirs:
|
for dir in dirs:
|
||||||
if dir.decode('utf-8').startswith('Plex'):
|
if tryDecode(dir).startswith('Plex'):
|
||||||
try:
|
try:
|
||||||
shutil.rmtree("%s%s" % (path, dir.decode('utf-8')))
|
shutil.rmtree("%s%s" % (path, tryDecode(dir)))
|
||||||
except:
|
except:
|
||||||
logMsg("PLEX", "Failed to delete directory: %s" % dir.decode('utf-8'))
|
logMsg("PLEX", "Failed to delete directory: %s"
|
||||||
|
% tryDecode(dir))
|
||||||
for file in files:
|
for file in files:
|
||||||
if file.decode('utf-8').startswith('plex'):
|
if tryDecode(file).startswith('plex'):
|
||||||
try:
|
try:
|
||||||
xbmcvfs.delete(("%s%s" % (path, file.decode('utf-8'))).encode('utf-8'))
|
xbmcvfs.delete(tryEncode("%s%s" % (path, tryDecode(file))))
|
||||||
except:
|
except:
|
||||||
logMsg("PLEX", "Failed to file: %s" % file.decode('utf-8'))
|
logMsg("PLEX", "Failed to file: %s" % tryDecode(file))
|
||||||
|
|
||||||
|
|
||||||
|
def tryEncode(uniString, encoding='utf-8'):
|
||||||
|
"""
|
||||||
|
Will try to encode uniString (in unicode) to encoding. This possibly
|
||||||
|
fails with e.g. Android TV's Python, which does not accept arguments for
|
||||||
|
string.encode()
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
uniString.encode(encoding, "ignore")
|
||||||
|
except TypeError:
|
||||||
|
uniString.encode()
|
||||||
|
return uniString
|
||||||
|
|
||||||
|
|
||||||
|
def tryDecode(string, encoding='utf-8'):
|
||||||
|
"""
|
||||||
|
Will try to decode string (encoded) using encoding. This possibly
|
||||||
|
fails with e.g. Android TV's Python, which does not accept arguments for
|
||||||
|
string.encode()
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
string.decode(encoding, "ignore")
|
||||||
|
except TypeError:
|
||||||
|
string.decode()
|
||||||
|
return string
|
||||||
|
|
|
@ -60,9 +60,10 @@ class VideoNodes(object):
|
||||||
else:
|
else:
|
||||||
dirname = viewid
|
dirname = viewid
|
||||||
|
|
||||||
path = xbmc.translatePath("special://profile/library/video/").decode('utf-8')
|
path = utils.tryDecode(xbmc.translatePath(
|
||||||
nodepath = xbmc.translatePath(
|
"special://profile/library/video/"))
|
||||||
"special://profile/library/video/Plex-%s/" % dirname).decode('utf-8')
|
nodepath = utils.tryDecode(xbmc.translatePath(
|
||||||
|
"special://profile/library/video/Plex-%s/" % dirname))
|
||||||
|
|
||||||
# Verify the video directory
|
# Verify the video directory
|
||||||
# KODI BUG
|
# KODI BUG
|
||||||
|
@ -70,20 +71,22 @@ class VideoNodes(object):
|
||||||
# so try creating a file
|
# so try creating a file
|
||||||
if utils.IfExists(path) is False:
|
if utils.IfExists(path) is False:
|
||||||
shutil.copytree(
|
shutil.copytree(
|
||||||
src=xbmc.translatePath("special://xbmc/system/library/video").decode('utf-8'),
|
src=utils.tryDecode(xbmc.translatePath(
|
||||||
dst=xbmc.translatePath("special://profile/library/video").decode('utf-8'))
|
"special://xbmc/system/library/video")),
|
||||||
|
dst=utils.tryDecode(xbmc.translatePath(
|
||||||
|
"special://profile/library/video")))
|
||||||
|
|
||||||
# Create the node directory
|
# Create the node directory
|
||||||
if mediatype != "photo":
|
if mediatype != "photo":
|
||||||
if utils.IfExists(nodepath) is False:
|
if utils.IfExists(nodepath) is False:
|
||||||
# folder does not exist yet
|
# folder does not exist yet
|
||||||
self.logMsg('Creating folder %s' % nodepath, 1)
|
self.logMsg('Creating folder %s' % nodepath, 1)
|
||||||
xbmcvfs.mkdirs(nodepath.encode('utf-8'))
|
xbmcvfs.mkdirs(utils.tryEncode(nodepath))
|
||||||
if delete:
|
if delete:
|
||||||
dirs, files = xbmcvfs.listdir(nodepath.encode('utf-8'))
|
dirs, files = xbmcvfs.listdir(utils.tryEncode(nodepath))
|
||||||
for file in files:
|
for file in files:
|
||||||
xbmcvfs.delete(
|
xbmcvfs.delete(utils.tryEncode(
|
||||||
(nodepath + file.decode('utf-8')).encode('utf-8'))
|
(nodepath + utils.tryDecode(file))))
|
||||||
|
|
||||||
self.logMsg("Sucessfully removed videonode: %s."
|
self.logMsg("Sucessfully removed videonode: %s."
|
||||||
% tagname, 1)
|
% tagname, 1)
|
||||||
|
@ -273,7 +276,7 @@ class VideoNodes(object):
|
||||||
# To do: add our photos nodes to kodi picture sources somehow
|
# To do: add our photos nodes to kodi picture sources somehow
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if xbmcvfs.exists(nodeXML.encode('utf-8')):
|
if xbmcvfs.exists(utils.tryEncode(nodeXML)):
|
||||||
# Don't recreate xml if already exists
|
# Don't recreate xml if already exists
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -357,9 +360,10 @@ class VideoNodes(object):
|
||||||
|
|
||||||
window = utils.window
|
window = utils.window
|
||||||
|
|
||||||
tagname = tagname.encode('utf-8')
|
tagname = utils.tryEncode(tagname)
|
||||||
cleantagname = utils.normalize_nodes(tagname)
|
cleantagname = utils.normalize_nodes(tagname)
|
||||||
nodepath = xbmc.translatePath("special://profile/library/video/").decode('utf-8')
|
nodepath = utils.tryDecode(xbmc.translatePath(
|
||||||
|
"special://profile/library/video/"))
|
||||||
nodeXML = "%splex_%s.xml" % (nodepath, cleantagname)
|
nodeXML = "%splex_%s.xml" % (nodepath, cleantagname)
|
||||||
path = "library://video/plex_%s.xml" % cleantagname
|
path = "library://video/plex_%s.xml" % cleantagname
|
||||||
windowpath = "ActivateWindow(Video,%s,return)" % path
|
windowpath = "ActivateWindow(Video,%s,return)" % path
|
||||||
|
@ -368,8 +372,10 @@ class VideoNodes(object):
|
||||||
if not xbmcvfs.exists(nodepath):
|
if not xbmcvfs.exists(nodepath):
|
||||||
# We need to copy over the default items
|
# We need to copy over the default items
|
||||||
shutil.copytree(
|
shutil.copytree(
|
||||||
src=xbmc.translatePath("special://xbmc/system/library/video").decode('utf-8'),
|
src=utils.tryDecode(xbmc.translatePath(
|
||||||
dst=xbmc.translatePath("special://profile/library/video").decode('utf-8'))
|
"special://xbmc/system/library/video")),
|
||||||
|
dst=utils.tryDecode(xbmc.translatePath(
|
||||||
|
"special://profile/library/video")))
|
||||||
xbmcvfs.exists(path)
|
xbmcvfs.exists(path)
|
||||||
|
|
||||||
labels = {
|
labels = {
|
||||||
|
|
|
@ -46,6 +46,8 @@ import logging
|
||||||
import traceback
|
import traceback
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
import utils
|
||||||
|
|
||||||
"""
|
"""
|
||||||
websocket python client.
|
websocket python client.
|
||||||
=========================
|
=========================
|
||||||
|
@ -286,7 +288,7 @@ class ABNF(object):
|
||||||
opcode: operation code. please see OPCODE_XXX.
|
opcode: operation code. please see OPCODE_XXX.
|
||||||
"""
|
"""
|
||||||
if opcode == ABNF.OPCODE_TEXT and isinstance(data, unicode):
|
if opcode == ABNF.OPCODE_TEXT and isinstance(data, unicode):
|
||||||
data = data.encode("utf-8")
|
data = utils.tryEncode(data)
|
||||||
# mask must be set if send data from client
|
# mask must be set if send data from client
|
||||||
return ABNF(1, 0, 0, 0, opcode, 1, data)
|
return ABNF(1, 0, 0, 0, opcode, 1, data)
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,15 @@ import xbmc
|
||||||
import xbmcaddon
|
import xbmcaddon
|
||||||
import xbmcgui
|
import xbmcgui
|
||||||
|
|
||||||
|
import utils
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
_addon = xbmcaddon.Addon(id='plugin.video.plexkodiconnect')
|
_addon = xbmcaddon.Addon(id='plugin.video.plexkodiconnect')
|
||||||
addon_path = _addon.getAddonInfo('path').decode('utf-8')
|
addon_path = utils.tryDecode(_addon.getAddonInfo('path'))
|
||||||
base_resource = xbmc.translatePath(os.path.join(addon_path, 'resources', 'lib')).decode('utf-8')
|
base_resource = utils.tryDecode(xbmc.translatePath(os.path.join(
|
||||||
|
addon_path,
|
||||||
|
'resources',
|
||||||
|
'lib')))
|
||||||
sys.path.append(base_resource)
|
sys.path.append(base_resource)
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
@ -26,7 +30,6 @@ import initialsetup
|
||||||
import kodimonitor
|
import kodimonitor
|
||||||
import librarysync
|
import librarysync
|
||||||
import player
|
import player
|
||||||
import utils
|
|
||||||
import videonodes
|
import videonodes
|
||||||
import websocket_client as wsc
|
import websocket_client as wsc
|
||||||
import downloadutils
|
import downloadutils
|
||||||
|
|
Loading…
Reference in a new issue