Avoid xbmcvfs entirely; use encoded paths

- Fixes #286
This commit is contained in:
tomkat83 2017-05-03 20:30:33 +02:00
parent 60759ba625
commit b2cd6e1156
9 changed files with 181 additions and 246 deletions

View file

@ -39,11 +39,11 @@ import xml.etree.ElementTree as etree
from re import compile as re_compile, sub
from json import dumps
from urllib import urlencode, quote_plus, unquote
from os import path as os_path
from os.path import basename, join, exists
from os import makedirs
import xbmcgui
from xbmc import sleep, executebuiltin
from xbmcvfs import exists, mkdirs
import clientinfo as client
from downloadutils import DownloadUtils
@ -2113,11 +2113,14 @@ class API():
if fanarttvimage not in data:
continue
for entry in data[fanarttvimage]:
if fanartcount < maxfanarts:
if exists(entry.get("url")):
allartworks['Backdrop'].append(
entry.get("url", "").replace(' ', '%20'))
fanartcount += 1
if entry.get("url") is None:
continue
if fanartcount > maxfanarts:
break
if exists(tryEncode(entry['url'])):
allartworks['Backdrop'].append(
entry['url'].replace(' ', '%20'))
fanartcount += 1
return allartworks
def getSetArtwork(self, parentInfo=False):
@ -2184,7 +2187,7 @@ class API():
# Get additional info (filename / languages)
filename = None
if 'file' in entry[0].attrib:
filename = os_path.basename(entry[0].attrib['file'])
filename = basename(entry[0].attrib['file'])
# Languages of audio streams
languages = []
for stream in entry[0]:
@ -2339,8 +2342,8 @@ class API():
Returns the path to the downloaded subtitle or None
"""
if not exists(v.EXTERNAL_SUBTITLE_TEMP_PATH):
mkdirs(v.EXTERNAL_SUBTITLE_TEMP_PATH)
path = os_path.join(v.EXTERNAL_SUBTITLE_TEMP_PATH, filename)
makedirs(v.EXTERNAL_SUBTITLE_TEMP_PATH)
path = join(v.EXTERNAL_SUBTITLE_TEMP_PATH, filename)
r = DownloadUtils().downloadUrl(url, return_response=True)
try:
r.status_code

View file

@ -4,16 +4,16 @@
import logging
from json import dumps, loads
import requests
from os import path as os_path
from os.path import exists
from shutil import rmtree
from urllib import quote_plus, unquote
from threading import Thread
from Queue import Queue, Empty
from xbmc import executeJSONRPC, sleep, translatePath
from xbmcvfs import listdir, delete
from utils import window, settings, language as lang, kodiSQL, tryEncode, \
tryDecode, IfExists, ThreadMethods, ThreadMethodsAdditionalStop, dialog
ThreadMethods, ThreadMethodsAdditionalStop, dialog
# Disable annoying requests warnings
import requests.packages.urllib3
@ -228,30 +228,21 @@ class Artwork():
if dialog('yesno', "Image Texture Cache", lang(39251)):
log.info("Resetting all cache data first")
# Remove all existing textures first
path = tryDecode(translatePath("special://thumbnails/"))
if IfExists(path):
allDirs, allFiles = listdir(path)
for dir in allDirs:
allDirs, allFiles = listdir(path+dir)
for file in allFiles:
if os_path.supports_unicode_filenames:
delete(os_path.join(
path + tryDecode(dir),
tryDecode(file)))
else:
delete(os_path.join(
tryEncode(path) + dir,
file))
path = translatePath("special://thumbnails/")
if exists(path):
rmtree(path, ignore_errors=True)
# remove all existing data from texture DB
connection = kodiSQL('texture')
cursor = connection.cursor()
cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"')
query = 'SELECT tbl_name FROM sqlite_master WHERE type=?'
cursor.execute(query, ('table', ))
rows = cursor.fetchall()
for row in rows:
tableName = row[0]
if tableName != "version":
cursor.execute("DELETE FROM " + tableName)
query = "DELETE FROM ?"
cursor.execute(query, (tableName,))
connection.commit()
connection.close()
@ -259,7 +250,8 @@ class Artwork():
connection = kodiSQL('video')
cursor = connection.cursor()
# dont include actors
cursor.execute("SELECT url FROM art WHERE media_type != 'actor'")
query = "SELECT url FROM art WHERE media_type != ?"
cursor.execute(query, ('actor', ))
result = cursor.fetchall()
total = len(result)
log.info("Image cache sync about to process %s video images" % total)
@ -286,7 +278,6 @@ class Artwork():
def addArtwork(self, artwork, kodiId, mediaType, cursor):
# Kodi conversion table
kodiart = {
'Primary': ["thumb", "poster"],
'Banner': "banner",
'Logo': "clearlogo",
@ -307,7 +298,6 @@ class Artwork():
backdropsNumber = len(backdrops)
query = ' '.join((
"SELECT url",
"FROM art",
"WHERE media_id = ?",
@ -320,7 +310,6 @@ class Artwork():
if len(rows) > backdropsNumber:
# More backdrops in database. Delete extra fanart.
query = ' '.join((
"DELETE FROM art",
"WHERE media_id = ?",
"AND media_type = ?",
@ -339,7 +328,7 @@ class Artwork():
cursor=cursor)
if backdropsNumber > 1:
try: # Will only fail on the first try, str to int.
try: # Will only fail on the first try, str to int.
index += 1
except TypeError:
index = 1
@ -438,14 +427,10 @@ class Artwork():
log.info("Could not find cached url.")
else:
# Delete thumbnail as well as the entry
thumbnails = tryDecode(
translatePath("special://thumbnails/%s" % cachedurl))
log.debug("Deleting cached thumbnail: %s" % thumbnails)
try:
delete(thumbnails)
except Exception as e:
log.error('Could not delete cached artwork %s. Error: %s'
% (thumbnails, e))
path = translatePath("special://thumbnails/%s" % cachedurl)
log.debug("Deleting cached thumbnail: %s" % path)
if exists(path):
rmtree(path, ignore_errors=True)
cursor.execute("DELETE FROM texture WHERE url = ?", (url,))
connection.commit()
finally:

View file

@ -1,7 +1,9 @@
# -*- coding: utf-8 -*-
###############################################################################
import logging
from os import path as os_path
from shutil import copyfile
from os import walk, makedirs
from os.path import basename, join, exists
from sys import argv
from urllib import urlencode
@ -9,8 +11,8 @@ import xbmcplugin
from xbmc import sleep, executebuiltin, translatePath
from xbmcgui import ListItem
from utils import window, settings, language as lang, dialog, tryDecode,\
tryEncode, CatchExceptions, JSONRPC
from utils import window, settings, language as lang, dialog, tryEncode, \
CatchExceptions, JSONRPC
import downloadutils
from PlexFunctions import GetPlexMetadata, GetPlexSectionResults, \
@ -486,6 +488,7 @@ 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://')
@ -493,28 +496,25 @@ def getVideoFiles(plexId, params):
# Plex returns Windows paths as e.g. 'c:\slfkjelf\slfje\file.mkv'
elif '\\' in path:
path = path.replace('\\', '\\\\')
# Directory only, get rid of filename (!! exists() needs / or \ at end)
path = path.replace(os_path.basename(path), '')
# Only proceed if we can access this folder
import xbmcvfs
if xbmcvfs.exists(path):
# Careful, returns encoded strings!
dirs, files = xbmcvfs.listdir(path)
for file in files:
file = path + tryDecode(file)
li = ListItem(file, path=file)
xbmcplugin.addDirectoryItem(handle=HANDLE,
url=tryEncode(file),
listitem=li)
for dir in dirs:
dir = path + tryDecode(dir)
li = ListItem(dir, path=dir)
xbmcplugin.addDirectoryItem(handle=HANDLE,
url=tryEncode(dir),
listitem=li,
isFolder=True)
# Directory only, get rid of filename
path = path.replace(basename(path), '')
if exists(path):
for root, dirs, files in walk(path):
for directory in dirs:
item_path = 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)
li = ListItem(item_path, path=item_path)
xbmcplugin.addDirectoryItem(handle=HANDLE,
url=file,
listitem=li)
else:
log.warn('Kodi cannot access folder %s' % path)
log.error('Kodi cannot access folder %s' % path)
xbmcplugin.endOfDirectory(HANDLE)
@ -525,7 +525,6 @@ def getExtraFanArt(plexid, plexPath):
will be called by skinhelper script to get the extrafanart
for tvshows we get the plexid just from the path
"""
import xbmcvfs
log.debug('Called with plexid: %s, plexPath: %s' % (plexid, plexPath))
if not plexid:
if "plugin.video.plexkodiconnect" in plexPath:
@ -536,11 +535,10 @@ def getExtraFanArt(plexid, plexPath):
# We need to store the images locally for this to work
# because of the caching system in xbmc
fanartDir = tryDecode(translatePath(
"special://thumbnails/plex/%s/" % plexid))
if not xbmcvfs.exists(fanartDir):
fanartDir = translatePath("special://thumbnails/plex/%s/" % plexid)
if not exists(fanartDir):
# Download the images to the cache directory
xbmcvfs.mkdirs(tryEncode(fanartDir))
makedirs(fanartDir)
xml = GetPlexMetadata(plexid)
if xml is None:
log.error('Could not download metadata for %s' % plexid)
@ -550,29 +548,23 @@ def getExtraFanArt(plexid, plexPath):
backdrops = api.getAllArtwork()['Backdrop']
for count, backdrop in enumerate(backdrops):
# Same ordering as in artwork
if os_path.supports_unicode_filenames:
fanartFile = os_path.join(fanartDir,
"fanart%.3d.jpg" % count)
else:
fanartFile = os_path.join(
tryEncode(fanartDir),
tryEncode("fanart%.3d.jpg" % count))
fanartFile = join(fanartDir, "fanart%.3d.jpg" % count)
li = ListItem("%.3d" % count, path=fanartFile)
xbmcplugin.addDirectoryItem(
handle=HANDLE,
url=fanartFile,
listitem=li)
xbmcvfs.copy(backdrop, fanartFile)
copyfile(backdrop, fanartFile)
else:
log.info("Found cached backdrop.")
# Use existing cached images
dirs, files = xbmcvfs.listdir(fanartDir)
for file in files:
fanartFile = os_path.join(fanartDir, tryDecode(file))
li = ListItem(file, path=fanartFile)
xbmcplugin.addDirectoryItem(handle=HANDLE,
url=fanartFile,
listitem=li)
for root, dirs, files in walk(fanartDir):
for file in files:
fanartFile = join(root, file)
li = ListItem(file, path=fanartFile)
xbmcplugin.addDirectoryItem(handle=HANDLE,
url=fanartFile,
listitem=li)
xbmcplugin.endOfDirectory(HANDLE)

View file

@ -1,15 +1,13 @@
# -*- coding: utf-8 -*-
###############################################################################
import logging
from threading import Thread
import Queue
from random import shuffle
from os.path import exists
import xbmc
import xbmcgui
import xbmcvfs
from utils import window, settings, getUnixTimestamp, sourcesXML,\
ThreadMethods, ThreadMethodsAdditionalStop, LogTime, getScreensaver,\
@ -1505,7 +1503,7 @@ class LibrarySync(Thread):
# Also runs when first installed
# Verify the video database can be found
videoDb = v.DB_VIDEO_PATH
if not xbmcvfs.exists(videoDb):
if not exists(videoDb):
# Database does not exists
log.error("The current Kodi version is incompatible "
"to know which Kodi versions are supported.")

View file

@ -3,14 +3,15 @@
###############################################################################
import logging
import threading
from os.path import exists
import xbmc
import xbmcgui
import xbmcaddon
import xbmcvfs
from utils import window, settings, language as lang, ThreadMethods, \
tryDecode, ThreadMethodsAdditionalSuspend
ThreadMethodsAdditionalSuspend
import downloadutils
import PlexAPI
@ -209,9 +210,8 @@ class UserClient(threading.Thread):
return False
# Get /profile/addon_data
addondir = tryDecode(xbmc.translatePath(
self.addon.getAddonInfo('profile')))
hasSettings = xbmcvfs.exists("%ssettings.xml" % addondir)
addondir = xbmc.translatePath(self.addon.getAddonInfo('profile'))
hasSettings = exists("%ssettings.xml" % addondir)
# If there's no settings.xml
if not hasSettings:

View file

@ -13,12 +13,13 @@ from unicodedata import normalize
import xml.etree.ElementTree as etree
from functools import wraps
from calendar import timegm
from os import path as os_path
from os.path import exists, join
from os import remove, makedirs, walk
from shutil import rmtree
import xbmc
import xbmcaddon
import xbmcgui
import xbmcvfs
from variables import DB_VIDEO_PATH, DB_MUSIC_PATH, DB_TEXTURE_PATH, \
DB_PLEX_PATH
@ -198,27 +199,6 @@ def DateToKodi(stamp):
return localdate
def IfExists(path):
"""
Kodi's xbmcvfs.exists is broken - it caches the results for directories.
path: path to a directory (with a slash at the end)
Returns True if path exists, else false
"""
dummyfile = tryEncode(os_path.join(path, 'dummyfile.txt'))
try:
etree.ElementTree(etree.Element('test')).write(dummyfile)
except:
# folder does not exist yet
answer = False
else:
# Folder exists. Delete file again.
xbmcvfs.delete(dummyfile)
answer = True
return answer
def IntFromStr(string):
"""
Returns an int from string or the int 0 if something happened
@ -362,24 +342,14 @@ def reset():
line1=language(39602)):
log.info("Resetting all cached artwork.")
# Remove all existing textures first
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 + tryDecode(dir),
tryDecode(file)))
else:
xbmcvfs.delete(os_path.join(
tryEncode(path) + dir,
file))
path = xbmc.translatePath("special://thumbnails/")
if exists(path):
rmtree(path, ignore_errors=True)
# remove all existing data from texture DB
connection = kodiSQL('texture')
cursor = connection.cursor()
cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"')
query = 'SELECT tbl_name FROM sqlite_master WHERE type=?'
cursor.execute(query, ("table", ))
rows = cursor.fetchall()
for row in rows:
tableName = row[0]
@ -398,10 +368,10 @@ def reset():
line1=language(39603)):
# Delete the settings
addon = xbmcaddon.Addon()
addondir = tryDecode(xbmc.translatePath(addon.getAddonInfo('profile')))
addondir = xbmc.translatePath(addon.getAddonInfo('profile'))
dataPath = "%ssettings.xml" % addondir
log.info("Deleting: settings.xml")
xbmcvfs.delete(tryEncode(dataPath))
remove(dataPath)
# Kodi will now restart to apply the changes.
dialog('ok',
@ -664,12 +634,13 @@ def sourcesXML():
def passwordsXML():
# To add network credentials
path = tryDecode(xbmc.translatePath("special://userdata/"))
path = xbmc.translatePath("special://userdata/")
xmlpath = "%spasswords.xml" % path
try:
xmlparse = etree.parse(xmlpath)
except: # Document is blank or missing
except:
# Document is blank or missing
root = etree.Element('passwords')
skipFind = True
else:
@ -753,8 +724,6 @@ def passwordsXML():
etree.SubElement(path, 'from', attrib={'pathversion': "1"}).text = "smb://%s/" % server
topath = "smb://%s:%s@%s/" % (user, password, server)
etree.SubElement(path, 'to', attrib={'pathversion': "1"}).text = topath
# Force Kodi to see the credentials without restarting
xbmcvfs.exists(topath)
# Add credentials
settings('networkCreds', value="%s" % server)
@ -762,7 +731,8 @@ def passwordsXML():
# Prettify and write to file
try:
indent(root)
except: pass
except:
pass
etree.ElementTree(root).write(xmlpath)
# dialog.notification(
@ -776,7 +746,7 @@ def playlistXSP(mediatype, tagname, viewid, viewtype="", delete=False):
"""
Feed with tagname as unicode
"""
path = tryDecode(xbmc.translatePath("special://profile/playlists/video/"))
path = xbmc.translatePath("special://profile/playlists/video/")
if viewtype == "mixed":
plname = "%s - %s" % (tagname, mediatype)
xsppath = "%sPlex %s - %s.xsp" % (path, viewid, mediatype)
@ -785,20 +755,20 @@ def playlistXSP(mediatype, tagname, viewid, viewtype="", delete=False):
xsppath = "%sPlex %s.xsp" % (path, viewid)
# Create the playlist directory
if not xbmcvfs.exists(tryEncode(path)):
if not exists(path):
log.info("Creating directory: %s" % path)
xbmcvfs.mkdirs(tryEncode(path))
makedirs(path)
# Only add the playlist if it doesn't already exists
if xbmcvfs.exists(tryEncode(xsppath)):
if exists(xsppath):
log.info('Path %s does exist' % xsppath)
if delete:
xbmcvfs.delete(tryEncode(xsppath))
remove(xsppath)
log.info("Successfully removed playlist: %s." % tagname)
return
# Using write process since there's no guarantee the xml declaration works with etree
# Using write process since there's no guarantee the xml declaration works
# with etree
itemtypes = {
'homevideos': 'movies',
'movie': 'movies',
@ -806,51 +776,39 @@ def playlistXSP(mediatype, tagname, viewid, viewtype="", delete=False):
}
log.info("Writing playlist file to: %s" % xsppath)
try:
f = xbmcvfs.File(tryEncode(xsppath), 'wb')
except:
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)
log.error(e)
return
else:
f.write(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)))
f.close()
log.info("Successfully added playlist: %s" % tagname)
def deletePlaylists():
# Clean up the playlists
path = tryDecode(xbmc.translatePath("special://profile/playlists/video/"))
dirs, files = xbmcvfs.listdir(tryEncode(path))
for file in files:
if tryDecode(file).startswith('Plex'):
xbmcvfs.delete(tryEncode("%s%s" % (path, tryDecode(file))))
path = xbmc.translatePath("special://profile/playlists/video/")
for root, _, files in walk(path):
for file in files:
if file.startswith('Plex'):
remove(join(root, file))
def deleteNodes():
# Clean up video nodes
import shutil
path = tryDecode(xbmc.translatePath("special://profile/library/video/"))
dirs, files = xbmcvfs.listdir(tryEncode(path))
for dir in dirs:
if tryDecode(dir).startswith('Plex'):
try:
shutil.rmtree("%s%s" % (path, tryDecode(dir)))
except:
log.error("Failed to delete directory: %s" % tryDecode(dir))
for file in files:
if tryDecode(file).startswith('plex'):
try:
xbmcvfs.delete(tryEncode("%s%s" % (path, tryDecode(file))))
except:
log.error("Failed to file: %s" % tryDecode(file))
path = xbmc.translatePath("special://profile/library/video/")
for root, dirs, _ in walk(path):
for directory in dirs:
if directory.startswith('Plex-'):
rmtree(join(root, directory))
break
###############################################################################

View file

@ -2,6 +2,8 @@
import xbmc
from xbmcaddon import Addon
# Paths are in string, not unicode!
def tryDecode(string, encoding='utf-8'):
"""
@ -27,7 +29,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 = tryDecode(xbmc.translatePath("special://profile"))
KODI_PROFILE = xbmc.translatePath("special://profile")
if xbmc.getCondVisibility('system.platform.osx'):
PLATFORM = "MacOSX"
@ -68,8 +70,8 @@ _DB_VIDEO_VERSION = {
17: 107, # Krypton
18: 107 # Leia
}
DB_VIDEO_PATH = tryDecode(xbmc.translatePath(
"special://database/MyVideos%s.db" % _DB_VIDEO_VERSION[KODIVERSION]))
DB_VIDEO_PATH = xbmc.translatePath(
"special://database/MyVideos%s.db" % _DB_VIDEO_VERSION[KODIVERSION])
_DB_MUSIC_VERSION = {
13: 46, # Gotham
@ -79,8 +81,8 @@ _DB_MUSIC_VERSION = {
17: 60, # Krypton
18: 60 # Leia
}
DB_MUSIC_PATH = tryDecode(xbmc.translatePath(
"special://database/MyMusic%s.db" % _DB_MUSIC_VERSION[KODIVERSION]))
DB_MUSIC_PATH = xbmc.translatePath(
"special://database/MyMusic%s.db" % _DB_MUSIC_VERSION[KODIVERSION])
_DB_TEXTURE_VERSION = {
13: 13, # Gotham
@ -90,13 +92,13 @@ _DB_TEXTURE_VERSION = {
17: 13, # Krypton
18: 13 # Leia
}
DB_TEXTURE_PATH = tryDecode(xbmc.translatePath(
"special://database/Textures%s.db" % _DB_TEXTURE_VERSION[KODIVERSION]))
DB_TEXTURE_PATH = xbmc.translatePath(
"special://database/Textures%s.db" % _DB_TEXTURE_VERSION[KODIVERSION])
DB_PLEX_PATH = tryDecode(xbmc.translatePath("special://database/plex.db"))
DB_PLEX_PATH = xbmc.translatePath("special://database/plex.db")
EXTERNAL_SUBTITLE_TEMP_PATH = tryDecode(xbmc.translatePath(
"special://profile/addon_data/%s/temp/" % ADDON_ID))
EXTERNAL_SUBTITLE_TEMP_PATH = xbmc.translatePath(
"special://profile/addon_data/%s/temp/" % ADDON_ID)
# Multiply Plex time by this factor to receive Kodi time

View file

@ -1,16 +1,15 @@
# -*- coding: utf-8 -*-
###############################################################################
import logging
import shutil
from shutil import copytree
import xml.etree.ElementTree as etree
import xbmc
import xbmcvfs
from os import remove, makedirs, listdir
from os.path import exists, isfile, join
from utils import window, settings, language as lang, IfExists, tryDecode, \
tryEncode, indent, normalize_nodes
from utils import window, settings, language as lang, tryEncode, indent, \
normalize_nodes
import variables as v
###############################################################################
@ -18,6 +17,7 @@ import variables as v
log = logging.getLogger("PLEX."+__name__)
###############################################################################
# Paths are strings, NOT unicode!
class VideoNodes(object):
@ -61,36 +61,30 @@ class VideoNodes(object):
else:
dirname = viewid
path = tryDecode(xbmc.translatePath(
"special://profile/library/video/"))
nodepath = tryDecode(xbmc.translatePath(
"special://profile/library/video/Plex-%s/" % dirname))
# Returns strings
path = xbmc.translatePath("special://profile/library/video/")
nodepath = xbmc.translatePath(
"special://profile/library/video/Plex-%s/" % dirname)
if delete:
dirs, files = xbmcvfs.listdir(tryEncode(nodepath))
files = [f for f in listdir(nodepath) if isfile(join(nodepath, f))]
for file in files:
xbmcvfs.delete(tryEncode(
(nodepath + tryDecode(file))))
remove(nodepath + file)
log.info("Sucessfully removed videonode: %s." % tagname)
return
# Verify the video directory
# KODI BUG
# Kodi caches the result of exists for directories
# so try creating a file
if IfExists(path) is False:
shutil.copytree(
src=tryDecode(xbmc.translatePath(
"special://xbmc/system/library/video")),
dst=tryDecode(xbmc.translatePath(
"special://profile/library/video")))
if exists(path) is False:
copytree(
src=xbmc.translatePath("special://xbmc/system/library/video"),
dst=xbmc.translatePath("special://profile/library/video"))
# Create the node directory
if mediatype != "photos":
if IfExists(nodepath) is False:
if exists(nodepath) is False:
# folder does not exist yet
log.debug('Creating folder %s' % nodepath)
xbmcvfs.mkdirs(tryEncode(nodepath))
makedirs(nodepath)
# Create index entry
nodeXML = "%sindex.xml" % nodepath
@ -103,23 +97,29 @@ class VideoNodes(object):
if mediatype == "photos":
path = "plugin://plugin.video.plexkodiconnect?mode=browseplex&key=/library/sections/%s&id=%s" % (viewid, viewid)
window('Plex.nodes.%s.index' % indexnumber, value=path)
# Root
if not mediatype == "photos":
if viewtype == "mixed":
specialtag = "%s-%s" % (tagname, mediatype)
root = self.commonRoot(order=0, label=specialtag, tagname=tagname, roottype=0)
root = self.commonRoot(order=0,
label=specialtag,
tagname=tagname,
roottype=0)
else:
root = self.commonRoot(order=0, label=tagname, tagname=tagname, roottype=0)
root = self.commonRoot(order=0,
label=tagname,
tagname=tagname,
roottype=0)
try:
indent(root)
except: pass
except:
pass
etree.ElementTree(root).write(nodeXML)
nodetypes = {
'1': "all",
'2': "recent",
'3': "recentepisodes",
@ -255,7 +255,7 @@ class VideoNodes(object):
path = 'plugin://plugin.video.plexkodiconnect?mode=browseplex&key=/library/sections/%s/folder' % viewid
else:
path = "library://video/Plex-%s/%s_%s.xml" % (dirname, viewid, nodetype)
if mediatype == "photos":
windowpath = "ActivateWindow(Pictures,%s,return)" % path
else:
@ -264,7 +264,7 @@ class VideoNodes(object):
windowpath = "ActivateWindow(Videos,%s,return)" % path
else:
windowpath = "ActivateWindow(Video,%s,return)" % path
if nodetype == "all":
if viewtype == "mixed":
@ -288,8 +288,8 @@ class VideoNodes(object):
# to be created.
# To do: add our photos nodes to kodi picture sources somehow
continue
if xbmcvfs.exists(tryEncode(nodeXML)):
if exists(nodeXML):
# Don't recreate xml if already exists
continue
@ -370,15 +370,14 @@ class VideoNodes(object):
try:
indent(root)
except: pass
except:
pass
etree.ElementTree(root).write(nodeXML)
def singleNode(self, indexnumber, tagname, mediatype, itemtype):
tagname = tryEncode(tagname)
cleantagname = normalize_nodes(tagname)
nodepath = tryDecode(xbmc.translatePath(
"special://profile/library/video/"))
nodepath = xbmc.translatePath("special://profile/library/video/")
nodeXML = "%splex_%s.xml" % (nodepath, cleantagname)
path = "library://video/plex_%s.xml" % cleantagname
if v.KODIVERSION >= 17:
@ -388,17 +387,13 @@ class VideoNodes(object):
windowpath = "ActivateWindow(Video,%s,return)" % path
# Create the video node directory
if not xbmcvfs.exists(nodepath):
if not exists(nodepath):
# We need to copy over the default items
shutil.copytree(
src=tryDecode(xbmc.translatePath(
"special://xbmc/system/library/video")),
dst=tryDecode(xbmc.translatePath(
"special://profile/library/video")))
xbmcvfs.exists(path)
copytree(
src=xbmc.translatePath("special://xbmc/system/library/video"),
dst=xbmc.translatePath("special://profile/library/video"))
labels = {
'Favorite movies': 30180,
'Favorite tvshows': 30181,
'channels': 30173
@ -410,12 +405,15 @@ class VideoNodes(object):
window('%s.content' % embynode, value=path)
window('%s.type' % embynode, value=itemtype)
if xbmcvfs.exists(nodeXML):
if exists(nodeXML):
# Don't recreate xml if already exists
return
if itemtype == "channels":
root = self.commonRoot(order=1, label=label, tagname=tagname, roottype=2)
root = self.commonRoot(order=1,
label=label,
tagname=tagname,
roottype=2)
etree.SubElement(root, 'path').text = "plugin://plugin.video.plexkodiconnect/?id=0&mode=channels"
else:
root = self.commonRoot(order=1, label=label, tagname=tagname)
@ -425,7 +423,8 @@ class VideoNodes(object):
try:
indent(root)
except: pass
except:
pass
etree.ElementTree(root).write(nodeXML)
def clearProperties(self):
@ -433,7 +432,6 @@ class VideoNodes(object):
log.info("Clearing nodes properties.")
plexprops = window('Plex.nodes.total')
propnames = [
"index","path","title","content",
"inprogress.content","inprogress.title",
"inprogress.content","inprogress.path",

View file

@ -164,12 +164,11 @@ class Service():
counter = 0
while not monitor.abortRequested():
if tryDecode(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,
tryDecode(window('plex_kodiProfile'))))
% (kodiProfile, window('plex_kodiProfile')))
break
# Before proceeding, need to make sure: