Account for string.encode() not allowing args

- E.g. Android TV
This commit is contained in:
tomkat83 2016-05-07 13:15:02 +02:00
parent 8848d5167d
commit df38786638
18 changed files with 213 additions and 160 deletions

View file

@ -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()

View file

@ -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 )

View file

@ -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:

View file

@ -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)

View file

@ -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("\"", "_")

View file

@ -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

View file

@ -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"

View file

@ -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)

View file

@ -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))

View file

@ -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))

View file

@ -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)

View file

@ -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()

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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 = {

View file

@ -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)

View file

@ -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