Fix for Windows usernames with non-ASCII chars

- Fixes #286
This commit is contained in:
tomkat83 2017-05-20 20:24:47 +02:00
parent b0d1fcfe8a
commit ad5744f435
8 changed files with 76 additions and 75 deletions

View file

@ -2553,14 +2553,14 @@ class API():
if "\\" in path:
if not path.endswith('\\'):
# Add the missing backslash
check = exists_dir(tryEncode(path + "\\"))
check = exists_dir(path + "\\")
else:
check = exists_dir(tryEncode(path))
check = exists_dir(path)
else:
if not path.endswith('/'):
check = exists_dir(tryEncode(path + "/"))
check = exists_dir(path + "/")
else:
check = exists_dir(tryEncode(path))
check = exists_dir(path)
if not check:
if forceCheck is False:

View file

@ -13,7 +13,7 @@ from xbmc import executeJSONRPC, sleep, translatePath
from xbmcvfs import exists
from utils import window, settings, language as lang, kodiSQL, tryEncode, \
thread_methods, dialog, exists_dir
thread_methods, dialog, exists_dir, tryDecode
# Disable annoying requests warnings
import requests.packages.urllib3
@ -222,7 +222,7 @@ class Artwork():
if dialog('yesno', "Image Texture Cache", lang(39251)):
log.info("Resetting all cache data first")
# Remove all existing textures first
path = translatePath("special://thumbnails/")
path = tryDecode(translatePath("special://thumbnails/"))
if exists_dir(path):
rmtree(path, ignore_errors=True)
@ -423,7 +423,7 @@ class Artwork():
path = translatePath("special://thumbnails/%s" % cachedurl)
log.debug("Deleting cached thumbnail: %s" % path)
if exists(path):
rmtree(path, ignore_errors=True)
rmtree(tryDecode(path), ignore_errors=True)
cursor.execute("DELETE FROM texture WHERE url = ?", (url,))
connection.commit()
finally:

View file

@ -12,7 +12,7 @@ from xbmc import sleep, executebuiltin, translatePath
from xbmcgui import ListItem
from utils import window, settings, language as lang, dialog, tryEncode, \
CatchExceptions, JSONRPC, exists_dir, plex_command
CatchExceptions, JSONRPC, exists_dir, plex_command, tryDecode
import downloadutils
from PlexFunctions import GetPlexMetadata, GetPlexSectionResults, \
@ -489,7 +489,6 @@ def getVideoFiles(plexId, params):
except:
log.error('Could not get file path for item %s' % plexId)
return xbmcplugin.endOfDirectory(HANDLE)
path = tryEncode(path)
# Assign network protocol
if path.startswith('\\\\'):
path = path.replace('\\\\', 'smb://')
@ -502,14 +501,14 @@ def getVideoFiles(plexId, params):
if exists_dir(path):
for root, dirs, files in walk(path):
for directory in dirs:
item_path = join(root, directory)
item_path = tryEncode(join(root, directory))
li = ListItem(item_path, path=item_path)
xbmcplugin.addDirectoryItem(handle=HANDLE,
url=item_path,
listitem=li,
isFolder=True)
for file in files:
item_path = join(root, file)
item_path = tryEncode(join(root, file))
li = ListItem(item_path, path=item_path)
xbmcplugin.addDirectoryItem(handle=HANDLE,
url=file,
@ -537,7 +536,8 @@ def getExtraFanArt(plexid, plexPath):
# We need to store the images locally for this to work
# because of the caching system in xbmc
fanartDir = translatePath("special://thumbnails/plex/%s/" % plexid)
fanartDir = tryDecode(translatePath(
"special://thumbnails/plex/%s/" % plexid))
if not exists_dir(fanartDir):
# Download the images to the cache directory
makedirs(fanartDir)
@ -550,19 +550,19 @@ def getExtraFanArt(plexid, plexPath):
backdrops = api.getAllArtwork()['Backdrop']
for count, backdrop in enumerate(backdrops):
# Same ordering as in artwork
fanartFile = join(fanartDir, "fanart%.3d.jpg" % count)
fanartFile = tryEncode(join(fanartDir, "fanart%.3d.jpg" % count))
li = ListItem("%.3d" % count, path=fanartFile)
xbmcplugin.addDirectoryItem(
handle=HANDLE,
url=fanartFile,
listitem=li)
copyfile(backdrop, fanartFile)
copyfile(backdrop, tryDecode(fanartFile))
else:
log.info("Found cached backdrop.")
# Use existing cached images
for root, dirs, files in walk(fanartDir):
for file in files:
fanartFile = join(root, file)
fanartFile = tryEncode(join(root, file))
li = ListItem(file, path=fanartFile)
xbmcplugin.addDirectoryItem(handle=HANDLE,
url=fanartFile,

View file

@ -12,7 +12,7 @@ from xbmcvfs import exists
from utils import window, settings, getUnixTimestamp, sourcesXML,\
thread_methods, create_actor_db_index, dialog, LogTime, getScreensaver,\
setScreensaver, playlistXSP, language as lang, DateToKodi, reset,\
tryDecode, deletePlaylists, deleteNodes
tryDecode, deletePlaylists, deleteNodes, tryEncode
import downloadutils
import itemtypes
import plexdb_functions as plexdb
@ -1507,7 +1507,7 @@ class LibrarySync(Thread):
# Also runs when first installed
# Verify the video database can be found
videoDb = v.DB_VIDEO_PATH
if not exists(videoDb):
if not exists(tryEncode(videoDb)):
# Database does not exists
log.error("The current Kodi version is incompatible "
"to know which Kodi versions are supported.")

View file

@ -111,12 +111,12 @@ def exists_dir(path):
Safe way to check whether the directory path exists already (broken in Kodi
<17)
Feed with encoded string
Feed with encoded string or unicode
"""
if KODIVERSION >= 17:
answ = exists(path)
answ = exists(tryEncode(path))
else:
dummyfile = join(path, 'dummyfile.txt')
dummyfile = join(tryDecode(path), 'dummyfile.txt')
try:
with open(dummyfile, 'w') as f:
f.write('text')
@ -125,7 +125,7 @@ def exists_dir(path):
answ = 0
else:
# Folder exists. Delete file again.
delete(dummyfile)
delete(tryEncode(dummyfile))
answ = 1
return answ
@ -401,7 +401,7 @@ def reset():
# Remove all existing textures first
path = xbmc.translatePath("special://thumbnails/")
if exists(path):
rmtree(path, ignore_errors=True)
rmtree(tryDecode(path), ignore_errors=True)
# remove all existing data from texture DB
connection = kodiSQL('texture')
cursor = connection.cursor()
@ -425,7 +425,7 @@ def reset():
line1=language(39603)):
# Delete the settings
addon = xbmcaddon.Addon()
addondir = xbmc.translatePath(addon.getAddonInfo('profile'))
addondir = tryDecode(xbmc.translatePath(addon.getAddonInfo('profile')))
dataPath = "%ssettings.xml" % addondir
log.info("Deleting: settings.xml")
remove(dataPath)
@ -688,7 +688,7 @@ def sourcesXML():
def passwordsXML():
# To add network credentials
path = xbmc.translatePath("special://userdata/")
path = tryDecode(xbmc.translatePath("special://userdata/"))
xmlpath = "%spasswords.xml" % path
try:
@ -801,7 +801,7 @@ def playlistXSP(mediatype, tagname, viewid, viewtype="", delete=False):
"""
Feed with tagname as unicode
"""
path = xbmc.translatePath("special://profile/playlists/video/")
path = tryDecode(xbmc.translatePath("special://profile/playlists/video/"))
if viewtype == "mixed":
plname = "%s - %s" % (tagname, mediatype)
xsppath = "%sPlex %s - %s.xsp" % (path, viewid, mediatype)
@ -810,12 +810,12 @@ def playlistXSP(mediatype, tagname, viewid, viewtype="", delete=False):
xsppath = "%sPlex %s.xsp" % (path, viewid)
# Create the playlist directory
if not exists(path):
if not exists(tryEncode(path)):
log.info("Creating directory: %s" % path)
makedirs(path)
# Only add the playlist if it doesn't already exists
if exists(xsppath):
if exists(tryEncode(xsppath)):
log.info('Path %s does exist' % xsppath)
if delete:
remove(xsppath)
@ -830,28 +830,22 @@ def playlistXSP(mediatype, tagname, viewid, viewtype="", delete=False):
'show': 'tvshows'
}
log.info("Writing playlist file to: %s" % xsppath)
try:
with open(xsppath, 'wb'):
tryEncode(
'<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>\n'
'<smartplaylist type="%s">\n\t'
'<name>Plex %s</name>\n\t'
'<match>all</match>\n\t'
'<rule field="tag" operator="is">\n\t\t'
'<value>%s</value>\n\t'
'</rule>\n'
'</smartplaylist>\n'
% (itemtypes.get(mediatype, mediatype), plname, tagname))
except Exception as e:
log.error("Failed to create playlist: %s" % xsppath)
import traceback
log.exception("Traceback:\n%s" % traceback.format_exc())
return
with open(xsppath, 'wb'):
tryEncode(
'<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>\n'
'<smartplaylist type="%s">\n\t'
'<name>Plex %s</name>\n\t'
'<match>all</match>\n\t'
'<rule field="tag" operator="is">\n\t\t'
'<value>%s</value>\n\t'
'</rule>\n'
'</smartplaylist>\n'
% (itemtypes.get(mediatype, mediatype), plname, tagname))
log.info("Successfully added playlist: %s" % tagname)
def deletePlaylists():
# Clean up the playlists
path = xbmc.translatePath("special://profile/playlists/video/")
path = tryDecode(xbmc.translatePath("special://profile/playlists/video/"))
for root, _, files in walk(path):
for file in files:
if file.startswith('Plex'):
@ -859,7 +853,7 @@ def deletePlaylists():
def deleteNodes():
# Clean up video nodes
path = xbmc.translatePath("special://profile/library/video/")
path = tryDecode(xbmc.translatePath("special://profile/library/video/"))
for root, dirs, _ in walk(path):
for directory in dirs:
if directory.startswith('Plex-'):

View file

@ -2,7 +2,8 @@
import xbmc
from xbmcaddon import Addon
# Paths are in string, not unicode!
# Paths are in unicode, otherwise Windows will throw fits
# For any file operations with KODI function, use encoded strings!
def tryDecode(string, encoding='utf-8'):
@ -29,7 +30,7 @@ ADDON_VERSION = _ADDON.getAddonInfo('version')
KODILANGUAGE = xbmc.getLanguage(xbmc.ISO_639_1)
KODIVERSION = int(xbmc.getInfoLabel("System.BuildVersion")[:2])
KODILONGVERSION = xbmc.getInfoLabel('System.BuildVersion')
KODI_PROFILE = xbmc.translatePath("special://profile")
KODI_PROFILE = tryDecode(xbmc.translatePath("special://profile"))
if xbmc.getCondVisibility('system.platform.osx'):
PLATFORM = "MacOSX"
@ -70,8 +71,8 @@ _DB_VIDEO_VERSION = {
17: 107, # Krypton
18: 108 # Leia
}
DB_VIDEO_PATH = xbmc.translatePath(
"special://database/MyVideos%s.db" % _DB_VIDEO_VERSION[KODIVERSION])
DB_VIDEO_PATH = tryDecode(xbmc.translatePath(
"special://database/MyVideos%s.db" % _DB_VIDEO_VERSION[KODIVERSION]))
_DB_MUSIC_VERSION = {
13: 46, # Gotham
@ -81,8 +82,8 @@ _DB_MUSIC_VERSION = {
17: 60, # Krypton
18: 62 # Leia
}
DB_MUSIC_PATH = xbmc.translatePath(
"special://database/MyMusic%s.db" % _DB_MUSIC_VERSION[KODIVERSION])
DB_MUSIC_PATH = tryDecode(xbmc.translatePath(
"special://database/MyMusic%s.db" % _DB_MUSIC_VERSION[KODIVERSION]))
_DB_TEXTURE_VERSION = {
13: 13, # Gotham
@ -92,13 +93,13 @@ _DB_TEXTURE_VERSION = {
17: 13, # Krypton
18: 13 # Leia
}
DB_TEXTURE_PATH = xbmc.translatePath(
"special://database/Textures%s.db" % _DB_TEXTURE_VERSION[KODIVERSION])
DB_TEXTURE_PATH = tryDecode(xbmc.translatePath(
"special://database/Textures%s.db" % _DB_TEXTURE_VERSION[KODIVERSION]))
DB_PLEX_PATH = xbmc.translatePath("special://database/plex.db")
DB_PLEX_PATH = tryDecode(xbmc.translatePath("special://database/plex.db"))
EXTERNAL_SUBTITLE_TEMP_PATH = xbmc.translatePath(
"special://profile/addon_data/%s/temp/" % ADDON_ID)
EXTERNAL_SUBTITLE_TEMP_PATH = tryDecode(xbmc.translatePath(
"special://profile/addon_data/%s/temp/" % ADDON_ID))
# Multiply Plex time by this factor to receive Kodi time

View file

@ -3,14 +3,13 @@
import logging
from shutil import copytree
import xml.etree.ElementTree as etree
from os import remove, listdir, makedirs
from os.path import isfile, join
from os import makedirs
import xbmc
from xbmcvfs import exists
from utils import window, settings, language as lang, tryEncode, indent, \
normalize_nodes, exists_dir
normalize_nodes, exists_dir, tryDecode
import variables as v
###############################################################################
@ -63,9 +62,10 @@ class VideoNodes(object):
dirname = viewid
# Returns strings
path = xbmc.translatePath("special://profile/library/video/")
nodepath = xbmc.translatePath(
"special://profile/library/video/Plex-%s/" % dirname)
path = tryDecode(xbmc.translatePath(
"special://profile/library/video/"))
nodepath = tryDecode(xbmc.translatePath(
"special://profile/library/video/Plex-%s/" % dirname))
if delete:
if exists_dir(nodepath):
@ -77,8 +77,10 @@ class VideoNodes(object):
# Verify the video directory
if not exists_dir(path):
copytree(
src=xbmc.translatePath("special://xbmc/system/library/video"),
dst=xbmc.translatePath("special://profile/library/video"))
src=tryDecode(xbmc.translatePath(
"special://xbmc/system/library/video")),
dst=tryDecode(xbmc.translatePath(
"special://profile/library/video")))
# Create the node directory
if mediatype != "photos":
@ -290,7 +292,7 @@ class VideoNodes(object):
# To do: add our photos nodes to kodi picture sources somehow
continue
if exists(nodeXML):
if exists(tryEncode(nodeXML)):
# Don't recreate xml if already exists
continue
@ -377,8 +379,9 @@ class VideoNodes(object):
def singleNode(self, indexnumber, tagname, mediatype, itemtype):
tagname = tryEncode(tagname)
cleantagname = normalize_nodes(tagname)
nodepath = xbmc.translatePath("special://profile/library/video/")
cleantagname = tryDecode(normalize_nodes(tagname))
nodepath = tryDecode(xbmc.translatePath(
"special://profile/library/video/"))
nodeXML = "%splex_%s.xml" % (nodepath, cleantagname)
path = "library://video/plex_%s.xml" % cleantagname
if v.KODIVERSION >= 17:
@ -391,8 +394,10 @@ class VideoNodes(object):
if not exists_dir(nodepath):
# We need to copy over the default items
copytree(
src=xbmc.translatePath("special://xbmc/system/library/video"),
dst=xbmc.translatePath("special://profile/library/video"))
src=tryDecode(xbmc.translatePath(
"special://xbmc/system/library/video")),
dst=tryDecode(xbmc.translatePath(
"special://profile/library/video")))
labels = {
'Favorite movies': 30180,
@ -406,7 +411,7 @@ class VideoNodes(object):
window('%s.content' % embynode, value=path)
window('%s.type' % embynode, value=itemtype)
if exists(nodeXML):
if exists(tryEncode(nodeXML)):
# Don't recreate xml if already exists
return

View file

@ -30,7 +30,8 @@ sys_path.append(_base_resource)
###############################################################################
from utils import settings, window, language as lang, dialog, tryEncode
from utils import settings, window, language as lang, dialog, tryEncode, \
tryDecode
from userclient import UserClient
import initialsetup
from kodimonitor import KodiMonitor
@ -86,7 +87,7 @@ class Service():
window('plex_logLevel', value=str(logLevel))
window('plex_kodiProfile',
value=translatePath("special://profile"))
value=tryDecode(translatePath("special://profile")))
window('plex_context',
value='true' if settings('enableContext') == "true" else "")
window('fetch_pms_item_number',
@ -170,12 +171,12 @@ class Service():
counter = 0
while not __stop_PKC():
if tryEncode(window('plex_kodiProfile')) != kodiProfile:
if window('plex_kodiProfile') != kodiProfile:
# Profile change happened, terminate this thread and others
log.warn("Kodi profile was: %s and changed to: %s. "
"Terminating old PlexKodiConnect thread."
% (kodiProfile,
tryEncode(window('plex_kodiProfile'))))
window('plex_kodiProfile')))
break
# Before proceeding, need to make sure: