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 xbmcgui
import utils
addon_ = xbmcaddon.Addon(id='plugin.video.plexkodiconnect')
addon_path = addon_.getAddonInfo('path').decode('utf-8')
base_resource = xbmc.translatePath(os.path.join(addon_path, 'resources', 'lib')).decode('utf-8')
addon_path = utils.tryDecode(addon_.getAddonInfo('path'))
base_resource = utils.tryDecode(xbmc.translatePath(os.path.join(addon_path, 'resources', 'lib')))
sys.path.append(base_resource)
import artwork
import utils
import clientinfo
import downloadutils
import librarysync
@ -36,8 +37,8 @@ def logMsg(msg, lvl=1):
#Kodi contextmenu item to configure the emby settings
#for now used to set ratings but can later be used to sync individual items etc.
if __name__ == '__main__':
itemid = xbmc.getInfoLabel("ListItem.DBID").decode("utf-8")
itemtype = xbmc.getInfoLabel("ListItem.DBTYPE").decode("utf-8")
itemid = utils.tryDecode(xbmc.getInfoLabel("ListItem.DBID"))
itemtype = utils.tryDecode(xbmc.getInfoLabel("ListItem.DBTYPE"))
emby = embyserver.Read_EmbyServer()

View File

@ -10,17 +10,18 @@ import xbmc
import xbmcaddon
import xbmcgui
import utils
###############################################################################
addon_ = xbmcaddon.Addon(id='plugin.video.plexkodiconnect')
addon_path = addon_.getAddonInfo('path').decode('utf-8')
base_resource = xbmc.translatePath(os.path.join(addon_path, 'resources', 'lib')).decode('utf-8')
addon_path = utils.tryDecode(addon_.getAddonInfo('path'))
base_resource = utils.tryDecode(xbmc.translatePath(os.path.join(addon_path, 'resources', 'lib')))
sys.path.append(base_resource)
###############################################################################
import entrypoint
import utils
###############################################################################
@ -159,8 +160,8 @@ if ( __name__ == "__main__" ):
import pstats
import random
from time import gmtime, strftime
addonid = addon_.getAddonInfo('id').decode( 'utf-8' )
datapath = os.path.join( xbmc.translatePath( "special://profile/" ).decode( 'utf-8' ), "addon_data", addonid )
addonid = utils.tryDecode(addon_.getAddonInfo('id'))
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" )
cProfile.run( 'Main()', filename )

View File

@ -482,8 +482,8 @@ class PlexAPI():
elif "Resource-Identifier:" in each:
update['uuid'] = each.split(':')[1].strip()
elif "Name:" in each:
update['serverName'] = each.split(
':')[1].strip().decode('utf-8', 'replace')
update['serverName'] = utils.tryDecode(each.split(
':')[1].strip())
elif "Port:" in each:
update['port'] = each.split(':')[1].strip()
elif "Updated-At:" in each:
@ -807,7 +807,7 @@ class PlexAPI():
username = user['title']
userlist.append(username)
# To take care of non-ASCII usernames
userlistCoded.append(username.encode('utf-8'))
userlistCoded.append(utils.tryEncode(username))
usernumber = len(userlist)
username = ''
@ -1039,7 +1039,7 @@ class PlexAPI():
path = 'http://127.0.0.1:32400' + key
else: # internal path, add-on
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.
# Fortunately PMS is lenient...
@ -1235,7 +1235,7 @@ class API():
res = None
if res is not None:
try:
res = unquote(res).decode('utf-8')
res = utils.tryDecode(unquote(res))
except UnicodeDecodeError:
# Sometimes, Plex seems to have encoded in latin1
res = unquote(res).decode('latin1')
@ -1899,13 +1899,9 @@ class API():
url = 'http://api.themoviedb.org/3/search/%s' % media_type
parameters = {
'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(
url,
authenticate=False,
@ -2348,19 +2344,14 @@ class API():
# exist() needs a / or \ at the end to work for directories
if folder is False:
# files
check = True if xbmcvfs.exists(path.encode('utf-8')) == 1 \
else False
check = xbmcvfs.exists(utils.tryEncode(path)) == 1
else:
# directories
if "\\" in path:
# Add the missing backslash
check = True if \
xbmcvfs.exists((path + "\\").encode('utf-8')) == 1 \
else False
check = xbmcvfs.exists(utils.tryEncode(path + "\\")) == 1
else:
check = True if \
xbmcvfs.exists((path + "/").encode('utf-8')) == 1 \
else False
check = xbmcvfs.exists(utils.tryEncode(path + "/")) == 1
if check is False:
if forceCheck is False:

View File

@ -53,10 +53,10 @@ class Artwork():
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:]
return text.decode("utf-8") #return the result again as unicode
return utils.tryDecode(text) #return the result again as unicode
def setKodiWebServerDetails(self):
# Get the Kodi webserver details - used to set the texture cache
@ -167,7 +167,7 @@ class Artwork():
string = xbmcaddon.Addon().getLocalizedString
if not xbmcgui.Dialog().yesno(
"Image Texture Cache", string(39250).encode('utf-8')):
"Image Texture Cache", string(39250)):
return
self.logMsg("Doing Image Cache Sync", 1)
@ -177,19 +177,23 @@ class Artwork():
# ask to rest all existing or not
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)
# Remove all existing textures first
path = xbmc.translatePath("special://thumbnails/").decode('utf-8')
path = utils.tryDecode(xbmc.translatePath("special://thumbnails/"))
if utils.IfExists(path):
allDirs, allFiles = xbmcvfs.listdir(path)
for dir in allDirs:
allDirs, allFiles = xbmcvfs.listdir(path+dir)
for file in allFiles:
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:
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
textureconnection = utils.kodiSQL('texture')
@ -467,7 +471,8 @@ class Artwork():
self.logMsg("Database is locked. Skip deletion process.", 1)
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)
xbmcvfs.delete(thumbnails)

View File

@ -7,7 +7,7 @@ from uuid import uuid4
import xbmc
import xbmcaddon
from utils import logging, window, settings
from utils import logging, window, settings, tryDecode
###############################################################################
@ -67,8 +67,7 @@ class ClientInfo():
def getDeviceName(self):
if settings('deviceNameOpt') == "false":
# Use Kodi's deviceName
deviceName = xbmc.getInfoLabel(
'System.FriendlyName').decode('utf-8')
deviceName = tryDecode(xbmc.getInfoLabel('System.FriendlyName'))
else:
deviceName = settings('deviceName')
deviceName = deviceName.replace("\"", "_")

View File

@ -606,15 +606,15 @@ def getThemeMedia():
else:
return
library = xbmc.translatePath(
"special://profile/addon_data/plugin.video.plexkodiconnect/library/").decode('utf-8')
library = utils.tryDecode(xbmc.translatePath(
"special://profile/addon_data/plugin.video.plexkodiconnect/library/"))
# Create library directory
if not utils.IfExists(library):
xbmcvfs.mkdir(library)
# Set custom path for user
tvtunes_path = xbmc.translatePath(
"special://profile/addon_data/script.tvtunes/").decode('utf-8')
tvtunes_path = utils.tryDecode(xbmc.translatePath(
"special://profile/addon_data/script.tvtunes/"))
if xbmcvfs.exists(tvtunes_path):
tvtunes = xbmcaddon.Addon(id="script.tvtunes")
tvtunes.setSetting('custom_path_enable', "true")
@ -644,7 +644,8 @@ def getThemeMedia():
for item in result['Items']:
itemId = item['Id']
folderName = item['Name']
folderName = utils.normalize_string(folderName.encode('utf-8'))
folderName = utils.normalize_string(
utils.tryEncode(folderName))
itemIds[itemId] = folderName
# Get paths for theme videos
@ -670,8 +671,8 @@ def getThemeMedia():
playurl = putils.directPlay()
else:
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
url = "{server}/emby/Items/%s/ThemeSongs?format=json" % itemId
result = doUtils.downloadUrl(url)
@ -683,7 +684,7 @@ def getThemeMedia():
playurl = putils.directPlay()
else:
playurl = putils.directStream()
pathstowrite += ('<file>%s</file>' % playurl.encode('utf-8'))
pathstowrite += ('<file>%s</file>' % utils.tryEncode(playurl))
nfo_file.write(
'<tvtunes>%s</tvtunes>' % pathstowrite
@ -700,7 +701,8 @@ def getThemeMedia():
for item in result['Items']:
itemId = item['Id']
folderName = item['Name']
folderName = utils.normalize_string(folderName.encode('utf-8'))
folderName = utils.normalize_string(
utils.tryEncode(folderName))
musicitemIds[itemId] = folderName
# Get paths
@ -731,7 +733,7 @@ def getThemeMedia():
playurl = putils.directPlay()
else:
playurl = putils.directStream()
pathstowrite += ('<file>%s</file>' % playurl.encode('utf-8'))
pathstowrite += ('<file>%s</file>' % utils.tryEncode(playurl))
nfo_file.write(
'<tvtunes>%s</tvtunes>' % pathstowrite
@ -781,12 +783,16 @@ def BrowseContent(viewname, browse_type="", folderid=""):
if not folderid:
views = PlexFunctions.GetPlexCollections()
for view in views:
if view.get("name") == viewname.decode('utf-8'):
if view.get("name") == utils.tryDecode(viewname):
folderid = view.get("id")
break
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
#only proceed if we have a folderid
if folderid:
@ -821,7 +827,11 @@ def BrowseContent(viewname, browse_type="", folderid=""):
li = createListItemFromEmbyItem(item,art,doUtils)
if item.get("IsFolder") == True:
#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)
else:
#playable item, set plugin path and mediastreams
@ -1330,16 +1340,16 @@ def getVideoFiles(plexId, params):
# Careful, returns encoded strings!
dirs, files = xbmcvfs.listdir(path)
for file in files:
file = path + file.decode('utf-8')
file = path + utils.tryDecode(file)
li = xbmcgui.ListItem(file, path=file)
xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),
url=file.encode('utf-8'),
url=utils.tryEncode(file),
listitem=li)
for dir in dirs:
dir = path + dir.decode('utf-8')
dir = path + utils.tryDecode(dir)
li = xbmcgui.ListItem(dir, path=dir)
xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),
url=dir.encode('utf-8'),
url=utils.tryEncode(dir),
listitem=li,
isFolder=True)
else:
@ -1367,7 +1377,8 @@ def getExtraFanArt(embyId,embyPath):
# We need to store the images locally for this to work
# 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):
# Download the images to the cache directory
@ -1383,7 +1394,9 @@ def getExtraFanArt(embyId,embyPath):
if os.path.supports_unicode_filenames:
fanartFile = os.path.join(fanartDir, "fanart%s.jpg" % tag)
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)
xbmcplugin.addDirectoryItem(
handle=int(sys.argv[1]),
@ -1396,7 +1409,7 @@ def getExtraFanArt(embyId,embyPath):
# Use existing cached images
dirs, files = xbmcvfs.listdir(fanartDir)
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)
xbmcplugin.addDirectoryItem(
handle=int(sys.argv[1]),
@ -1458,7 +1471,11 @@ def BrowsePlexContent(viewid, mediatype="", nodetype=""):
# folderId
li.setProperty('IsFolder', 'true')
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)
else:
# 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
path = "plugin://plugin.video.plexkodiconnect.movies/"
params = {
'filename': API.getKey().encode('utf-8'),
'filename': utils.tryEncode(API.getKey()),
'id': itemid,
'dbid': movieid,
'mode': "play"
@ -691,7 +691,7 @@ class MusicVideos(Items):
path = "plugin://plugin.video.plexkodiconnect.musicvideos/"
params = {
'filename': filename.encode('utf-8'),
'filename': utils.tryEncode(filename),
'id': itemid,
'dbid': mvideoid,
'mode': "play"
@ -1332,7 +1332,7 @@ class TVShows(Items):
filename = 'file_not_found'
path = "plugin://plugin.video.plexkodiconnect.tvshows/%s/" % seriesId
params = {
'filename': filename.encode('utf-8'),
'filename': utils.tryEncode(filename),
'id': itemid,
'dbid': episodeid,
'mode': "play"

View File

@ -173,7 +173,7 @@ class KodiMonitor(xbmc.Monitor):
return
else:
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
item = data.get('item')
@ -217,7 +217,7 @@ class KodiMonitor(xbmc.Monitor):
return
# 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("emby_%s.itemid" % currentFile, value=plexid)
log('Finish playback startup', 1)

View File

@ -1619,8 +1619,8 @@ class LibrarySync(Thread):
# Database does not exists
log("The current Kodi version is incompatible "
"to know which Kodi versions are supported.", -1)
log('Current Kodi version: %s' % xbmc.getInfoLabel(
'System.BuildVersion').decode('utf-8'))
log('Current Kodi version: %s' % utils.tryDecode(
xbmc.getInfoLabel('System.BuildVersion')))
# "Current Kodi version is unsupported, cancel lib sync"
self.dialog.ok(heading=self.addonName,
line1=string(39403))

View File

@ -32,7 +32,7 @@ def getRealFileName(filename, isTemp=False):
if os.path.supports_unicode_filenames:
checkfile = filename
else:
checkfile = filename.encode("utf-8")
checkfile = utils.tryEncode(filename)
# determine if our python module is able to access the file directly...
if os.path.exists(checkfile):
@ -46,7 +46,7 @@ def getRealFileName(filename, isTemp=False):
else: filepart = filename.split("\\")[-1]
tempfile = "special://temp/"+filepart
xbmcvfs.copy(filename, tempfile)
filename = xbmc.translatePath(tempfile).decode("utf-8")
filename = utils.tryDecode(xbmc.translatePath(tempfile))
return (isTemp,filename)
@ -242,7 +242,7 @@ def updateRatingToFile(rating, file):
else: filepart = file.split("\\")[-1]
tempfile = "special://temp/"+filepart
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))

View File

@ -75,14 +75,14 @@ class PlaybackUtils():
% item[0][0][0].attrib.get('key'), -1)
return xbmcplugin.setResolvedUrl(
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')
playmethod = window('emby_%s.playmethod' % playurl)
if playmethod == "Transcode":
window('emby_%s.playmethod' % playurl, clear=True)
playurl = playutils.audioSubsPref(
listitem, playurl.decode('utf-8')).encode('utf-8')
playurl = utils.tryEncode(playutils.audioSubsPref(
listitem, utils.tryDecode(playurl)))
window('emby_%s.playmethod' % playurl, "Transcode")
listitem.setPath(playurl)
self.setProperties(playurl, listitem)
@ -195,8 +195,8 @@ class PlaybackUtils():
# For transcoding only, ask for audio/subs pref
if window('emby_%s.playmethod' % playurl) == "Transcode":
window('emby_%s.playmethod' % playurl, clear=True)
playurl = playutils.audioSubsPref(
listitem, playurl.decode('utf-8')).encode('utf-8')
playurl = utils.tryEncode(playutils.audioSubsPref(
listitem, utils.tryDecode(playurl)))
window('emby_%s.playmethod' % playurl, value="Transcode")
listitem.setPath(playurl)

View File

@ -72,7 +72,7 @@ class Player(xbmc.Player):
# Save currentFile for cleanup later and for references
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
itemId = window("emby_%s.itemid" % currentFile)
count = 0
@ -87,7 +87,7 @@ class Player(xbmc.Player):
count += 1
self.logMsg("ONPLAYBACK_STARTED: %s itemid: %s"
% (currentFile.decode('utf-8'), itemId), 0)
% (utils.tryDecode(currentFile), itemId), 0)
embyitem = "emby_%s" % currentFile
runtime = window("%s.runtime" % embyitem)
@ -399,7 +399,7 @@ class Player(xbmc.Player):
def onPlayBackPaused(self):
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):
self.played_info[currentFile]['paused'] = True
@ -409,7 +409,7 @@ class Player(xbmc.Player):
def onPlayBackResumed(self):
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):
self.played_info[currentFile]['paused'] = False
@ -419,7 +419,7 @@ class Player(xbmc.Player):
def onPlayBackSeek(self, time, seekOffset):
# Make position when seeking a bit more accurate
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):
position = self.xbmcplayer.getTime()

View File

@ -45,13 +45,14 @@ class PlayUtils():
if playurl:
log("File is direct playing.", 1)
playurl = playurl.encode('utf-8')
playurl = utils.tryEncode(playurl)
# Set playmethod property
window('emby_%s.playmethod' % playurl, "DirectPlay")
elif self.isDirectStream():
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
utils.window('emby_%s.playmethod' % playurl, "DirectStream")
@ -62,9 +63,9 @@ class PlayUtils():
'videoResolution': self.getResolution(),
'videoQuality': '100'
}
playurl = self.API.getTranscodeVideoPath(
playurl = utils.tryEncode(self.API.getTranscodeVideoPath(
'Transcode',
quality=quality).encode('utf-8')
quality=quality))
# Set playmethod property
window('emby_%s.playmethod' % playurl, value="Transcode")
@ -306,7 +307,7 @@ class PlayUtils():
#audioStreamsChannelsList[audioNum] = stream.attrib['channels']
audioStreamsList.append(index)
audioStreams.append(track.encode('utf-8'))
audioStreams.append(utils.tryEncode(track))
audioNum += 1
# Subtitles
@ -330,7 +331,7 @@ class PlayUtils():
downloadableStreams.append(index)
subtitleStreamsList.append(index)
subtitleStreams.append(track.encode('utf-8'))
subtitleStreams.append(utils.tryEncode(track))
subNum += 1
if audioNum > 1:
@ -362,7 +363,7 @@ class PlayUtils():
% (self.server, selectSubsIndex)
url = self.API.addPlexHeadersToUrl(url)
self.logMsg("Downloadable sub: %s: %s" % (selectSubsIndex, url), 1)
listitem.setSubtitles([url.encode('utf-8')])
listitem.setSubtitles([utils.tryEncode(url)])
else:
self.logMsg('Need to burn in subtitle %s' % selectSubsIndex, 1)
playurlprefs["subtitleStreamID"] = selectSubsIndex

View File

@ -247,8 +247,8 @@ class UserClient(threading.Thread):
return False
# Get /profile/addon_data
addondir = xbmc.translatePath(
self.addon.getAddonInfo('profile')).decode('utf-8')
addondir = utils.tryDecode(xbmc.translatePath(
self.addon.getAddonInfo('profile')))
hasSettings = xbmcvfs.exists("%ssettings.xml" % addondir)
# If there's no settings.xml

View File

@ -98,7 +98,7 @@ def IfExists(path):
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:
etree.ElementTree(etree.Element('test')).write(dummyfile)
except:
@ -272,7 +272,7 @@ def logMsg(title, msg, level=1):
except UnicodeEncodeError:
try:
xbmc.log("%s -> %s : %s" % (
title, func.co_name, msg.encode('utf-8')),
title, func.co_name, tryEncode(msg)),
level=kodiLevel[level])
except:
xbmc.log("%s -> %s : %s" % (
@ -283,7 +283,7 @@ def logMsg(title, msg, level=1):
xbmc.log("%s -> %s" % (title, msg), level=kodiLevel[level])
except UnicodeEncodeError:
try:
xbmc.log("%s -> %s" % (title, msg.encode('utf-8')),
xbmc.log("%s -> %s" % (title, tryEncode(msg)),
level=kodiLevel[level])
except:
xbmc.log("%s -> %s " % (title, 'COULDNT LOG'),
@ -301,16 +301,12 @@ def window(property, value=None, clear=False, windowid=10000):
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
'''if isinstance(property, unicode):
property = property.encode("utf-8")
if isinstance(value, unicode):
value = value.encode("utf-8")'''
if clear:
WINDOW.clearProperty(property)
elif value is not None:
WINDOW.setProperty(property, value.encode('utf-8'))
WINDOW.setProperty(property, tryEncode(value))
else:
return WINDOW.getProperty(property).decode('utf-8')
return tryDecode(WINDOW.getProperty(property))
def settings(setting, value=None):
"""
@ -323,10 +319,10 @@ def settings(setting, value=None):
if value is not None:
# Takes string or unicode by default!
addon.setSetting(setting, value.encode('utf-8'))
addon.setSetting(setting, tryEncode(value))
else:
# Should return unicode by default, but just in case
return addon.getSetting(setting).decode('utf-8')
return tryDecode(addon.getSetting(setting))
def language(stringid):
# Central string retrieval
@ -337,11 +333,12 @@ def language(stringid):
def kodiSQL(media_type="video"):
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":
dbPath = getKodiMusicDBPath()
elif media_type == "texture":
dbPath = xbmc.translatePath("special://database/Textures13.db").decode('utf-8')
dbPath = tryDecode(xbmc.translatePath(
"special://database/Textures13.db"))
else:
dbPath = getKodiVideoDBPath()
@ -359,9 +356,9 @@ def getKodiVideoDBPath():
"17": 104 # Krypton
}
dbPath = xbmc.translatePath(
"special://database/MyVideos%s.db"
% dbVersion.get(xbmc.getInfoLabel('System.BuildVersion')[:2], "")).decode('utf-8')
dbPath = tryDecode(xbmc.translatePath(
"special://database/MyVideos%s.db"
% dbVersion.get(xbmc.getInfoLabel('System.BuildVersion')[:2], "")))
return dbPath
def getKodiMusicDBPath():
@ -375,9 +372,9 @@ def getKodiMusicDBPath():
"17": 60 # Krypton
}
dbPath = xbmc.translatePath(
"special://database/MyMusic%s.db"
% dbVersion.get(xbmc.getInfoLabel('System.BuildVersion')[:2], "")).decode('utf-8')
dbPath = tryDecode(xbmc.translatePath(
"special://database/MyMusic%s.db"
% dbVersion.get(xbmc.getInfoLabel('System.BuildVersion')[:2], "")))
return dbPath
def getScreensaver():
@ -479,16 +476,20 @@ def reset():
if resp:
logMsg("EMBY", "Resetting all cached artwork.", 0)
# Remove all existing textures first
path = xbmc.translatePath("special://thumbnails/").decode('utf-8')
path = tryDecode(xbmc.translatePath("special://thumbnails/"))
if xbmcvfs.exists(path):
allDirs, allFiles = xbmcvfs.listdir(path)
for dir in allDirs:
allDirs, allFiles = xbmcvfs.listdir(path+dir)
for file in allFiles:
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:
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
connection = kodiSQL('texture')
@ -510,9 +511,9 @@ def reset():
if resp:
# Delete the settings
addon = xbmcaddon.Addon()
addondir = xbmc.translatePath(addon.getAddonInfo('profile')).decode('utf-8')
addondir = tryDecode(xbmc.translatePath(addon.getAddonInfo('profile')))
dataPath = "%ssettings.xml" % addondir
xbmcvfs.delete(dataPath.encode('utf-8'))
xbmcvfs.delete(tryEncode(dataPath))
logMsg("PLEX", "Deleting: settings.xml", 1)
dialog.ok(
@ -567,7 +568,7 @@ def normalize_nodes(text):
# Remove dots from the last character as windows can not have directories
# with dots at the end
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
@ -586,7 +587,7 @@ def normalize_string(text):
# Remove dots from the last character as windows can not have directories
# with dots at the end
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
@ -611,7 +612,7 @@ def guisettingsXML():
"""
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
try:
@ -670,7 +671,7 @@ def advancedSettingsXML():
usetags : 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
try:
@ -700,7 +701,7 @@ def advancedSettingsXML():
def sourcesXML():
# To make Master lock compatible
path = xbmc.translatePath("special://profile/").decode('utf-8')
path = tryDecode(xbmc.translatePath("special://profile/"))
xmlpath = "%ssources.xml" % path
try:
@ -741,7 +742,7 @@ def sourcesXML():
def passwordsXML():
# To add network credentials
path = xbmc.translatePath("special://userdata/").decode('utf-8')
path = tryDecode(xbmc.translatePath("special://userdata/"))
xmlpath = "%spasswords.xml" % path
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
"""
path = xbmc.translatePath("special://profile/playlists/video/").decode('utf-8')
path = tryDecode(xbmc.translatePath("special://profile/playlists/video/"))
if viewtype == "mixed":
plname = "%s - %s" % (tagname, 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)
# 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)
xbmcvfs.mkdirs(path.encode('utf-8'))
xbmcvfs.mkdirs(tryEncode(path))
# 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)
if delete:
xbmcvfs.delete(xsppath.encode('utf-8'))
xbmcvfs.delete(tryEncode(xsppath))
logMsg("PLEX", "Successfully removed playlist: %s." % tagname, 1)
return
@ -882,12 +883,12 @@ def playlistXSP(mediatype, tagname, viewid, viewtype="", delete=False):
}
logMsg("Plex", "Writing playlist file to: %s" % xsppath, 1)
try:
f = xbmcvfs.File(xsppath.encode('utf-8'), 'wb')
f = xbmcvfs.File(tryEncode(xsppath), 'wb')
except:
logMsg("Plex", "Failed to create playlist: %s" % xsppath, -1)
return
else:
f.write((
f.write(tryEncode(
'<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>\n'
'<smartplaylist type="%s">\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'
'</rule>\n'
'</smartplaylist>\n'
% (itemtypes.get(mediatype, mediatype), plname, tagname))
.encode('utf-8'))
% (itemtypes.get(mediatype, mediatype), plname, tagname)))
f.close()
logMsg("Plex", "Successfully added playlist: %s" % tagname)
def deletePlaylists():
# Clean up the playlists
path = xbmc.translatePath("special://profile/playlists/video/").decode('utf-8')
dirs, files = xbmcvfs.listdir(path.encode('utf-8'))
path = tryDecode(xbmc.translatePath("special://profile/playlists/video/"))
dirs, files = xbmcvfs.listdir(tryEncode(path))
for file in files:
if file.decode('utf-8').startswith('Plex'):
xbmcvfs.delete(("%s%s" % (path, file.decode('utf-8'))).encode('utf-8'))
if tryDecode(file).startswith('Plex'):
xbmcvfs.delete(tryEncode("%s%s" % (path, tryDecode(file))))
def deleteNodes():
# Clean up video nodes
import shutil
path = xbmc.translatePath("special://profile/library/video/").decode('utf-8')
dirs, files = xbmcvfs.listdir(path.encode('utf-8'))
path = tryDecode(xbmc.translatePath("special://profile/library/video/"))
dirs, files = xbmcvfs.listdir(tryEncode(path))
for dir in dirs:
if dir.decode('utf-8').startswith('Plex'):
if tryDecode(dir).startswith('Plex'):
try:
shutil.rmtree("%s%s" % (path, dir.decode('utf-8')))
shutil.rmtree("%s%s" % (path, tryDecode(dir)))
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:
if file.decode('utf-8').startswith('plex'):
if tryDecode(file).startswith('plex'):
try:
xbmcvfs.delete(("%s%s" % (path, file.decode('utf-8'))).encode('utf-8'))
xbmcvfs.delete(tryEncode("%s%s" % (path, tryDecode(file))))
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:
dirname = viewid
path = xbmc.translatePath("special://profile/library/video/").decode('utf-8')
nodepath = xbmc.translatePath(
"special://profile/library/video/Plex-%s/" % dirname).decode('utf-8')
path = utils.tryDecode(xbmc.translatePath(
"special://profile/library/video/"))
nodepath = utils.tryDecode(xbmc.translatePath(
"special://profile/library/video/Plex-%s/" % dirname))
# Verify the video directory
# KODI BUG
@ -70,20 +71,22 @@ class VideoNodes(object):
# so try creating a file
if utils.IfExists(path) is False:
shutil.copytree(
src=xbmc.translatePath("special://xbmc/system/library/video").decode('utf-8'),
dst=xbmc.translatePath("special://profile/library/video").decode('utf-8'))
src=utils.tryDecode(xbmc.translatePath(
"special://xbmc/system/library/video")),
dst=utils.tryDecode(xbmc.translatePath(
"special://profile/library/video")))
# Create the node directory
if mediatype != "photo":
if utils.IfExists(nodepath) is False:
# folder does not exist yet
self.logMsg('Creating folder %s' % nodepath, 1)
xbmcvfs.mkdirs(nodepath.encode('utf-8'))
xbmcvfs.mkdirs(utils.tryEncode(nodepath))
if delete:
dirs, files = xbmcvfs.listdir(nodepath.encode('utf-8'))
dirs, files = xbmcvfs.listdir(utils.tryEncode(nodepath))
for file in files:
xbmcvfs.delete(
(nodepath + file.decode('utf-8')).encode('utf-8'))
xbmcvfs.delete(utils.tryEncode(
(nodepath + utils.tryDecode(file))))
self.logMsg("Sucessfully removed videonode: %s."
% tagname, 1)
@ -273,7 +276,7 @@ class VideoNodes(object):
# To do: add our photos nodes to kodi picture sources somehow
continue
if xbmcvfs.exists(nodeXML.encode('utf-8')):
if xbmcvfs.exists(utils.tryEncode(nodeXML)):
# Don't recreate xml if already exists
continue
@ -357,19 +360,22 @@ class VideoNodes(object):
window = utils.window
tagname = tagname.encode('utf-8')
tagname = utils.tryEncode(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)
path = "library://video/plex_%s.xml" % cleantagname
windowpath = "ActivateWindow(Video,%s,return)" % path
# Create the video node directory
if not xbmcvfs.exists(nodepath):
# We need to copy over the default items
shutil.copytree(
src=xbmc.translatePath("special://xbmc/system/library/video").decode('utf-8'),
dst=xbmc.translatePath("special://profile/library/video").decode('utf-8'))
src=utils.tryDecode(xbmc.translatePath(
"special://xbmc/system/library/video")),
dst=utils.tryDecode(xbmc.translatePath(
"special://profile/library/video")))
xbmcvfs.exists(path)
labels = {

View File

@ -46,6 +46,8 @@ import logging
import traceback
import sys
import utils
"""
websocket python client.
=========================
@ -286,7 +288,7 @@ class ABNF(object):
opcode: operation code. please see OPCODE_XXX.
"""
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
return ABNF(1, 0, 0, 0, opcode, 1, data)

View File

@ -11,11 +11,15 @@ import xbmc
import xbmcaddon
import xbmcgui
import utils
###############################################################################
_addon = xbmcaddon.Addon(id='plugin.video.plexkodiconnect')
addon_path = _addon.getAddonInfo('path').decode('utf-8')
base_resource = xbmc.translatePath(os.path.join(addon_path, 'resources', 'lib')).decode('utf-8')
addon_path = utils.tryDecode(_addon.getAddonInfo('path'))
base_resource = utils.tryDecode(xbmc.translatePath(os.path.join(
addon_path,
'resources',
'lib')))
sys.path.append(base_resource)
###############################################################################
@ -26,7 +30,6 @@ import initialsetup
import kodimonitor
import librarysync
import player
import utils
import videonodes
import websocket_client as wsc
import downloadutils