parent
60759ba625
commit
b2cd6e1156
9 changed files with 181 additions and 246 deletions
|
@ -39,11 +39,11 @@ import xml.etree.ElementTree as etree
|
||||||
from re import compile as re_compile, sub
|
from re import compile as re_compile, sub
|
||||||
from json import dumps
|
from json import dumps
|
||||||
from urllib import urlencode, quote_plus, unquote
|
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
|
import xbmcgui
|
||||||
from xbmc import sleep, executebuiltin
|
from xbmc import sleep, executebuiltin
|
||||||
from xbmcvfs import exists, mkdirs
|
|
||||||
|
|
||||||
import clientinfo as client
|
import clientinfo as client
|
||||||
from downloadutils import DownloadUtils
|
from downloadutils import DownloadUtils
|
||||||
|
@ -2113,11 +2113,14 @@ class API():
|
||||||
if fanarttvimage not in data:
|
if fanarttvimage not in data:
|
||||||
continue
|
continue
|
||||||
for entry in data[fanarttvimage]:
|
for entry in data[fanarttvimage]:
|
||||||
if fanartcount < maxfanarts:
|
if entry.get("url") is None:
|
||||||
if exists(entry.get("url")):
|
continue
|
||||||
allartworks['Backdrop'].append(
|
if fanartcount > maxfanarts:
|
||||||
entry.get("url", "").replace(' ', '%20'))
|
break
|
||||||
fanartcount += 1
|
if exists(tryEncode(entry['url'])):
|
||||||
|
allartworks['Backdrop'].append(
|
||||||
|
entry['url'].replace(' ', '%20'))
|
||||||
|
fanartcount += 1
|
||||||
return allartworks
|
return allartworks
|
||||||
|
|
||||||
def getSetArtwork(self, parentInfo=False):
|
def getSetArtwork(self, parentInfo=False):
|
||||||
|
@ -2184,7 +2187,7 @@ class API():
|
||||||
# Get additional info (filename / languages)
|
# Get additional info (filename / languages)
|
||||||
filename = None
|
filename = None
|
||||||
if 'file' in entry[0].attrib:
|
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 of audio streams
|
||||||
languages = []
|
languages = []
|
||||||
for stream in entry[0]:
|
for stream in entry[0]:
|
||||||
|
@ -2339,8 +2342,8 @@ class API():
|
||||||
Returns the path to the downloaded subtitle or None
|
Returns the path to the downloaded subtitle or None
|
||||||
"""
|
"""
|
||||||
if not exists(v.EXTERNAL_SUBTITLE_TEMP_PATH):
|
if not exists(v.EXTERNAL_SUBTITLE_TEMP_PATH):
|
||||||
mkdirs(v.EXTERNAL_SUBTITLE_TEMP_PATH)
|
makedirs(v.EXTERNAL_SUBTITLE_TEMP_PATH)
|
||||||
path = os_path.join(v.EXTERNAL_SUBTITLE_TEMP_PATH, filename)
|
path = join(v.EXTERNAL_SUBTITLE_TEMP_PATH, filename)
|
||||||
r = DownloadUtils().downloadUrl(url, return_response=True)
|
r = DownloadUtils().downloadUrl(url, return_response=True)
|
||||||
try:
|
try:
|
||||||
r.status_code
|
r.status_code
|
||||||
|
|
|
@ -4,16 +4,16 @@
|
||||||
import logging
|
import logging
|
||||||
from json import dumps, loads
|
from json import dumps, loads
|
||||||
import requests
|
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 urllib import quote_plus, unquote
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from Queue import Queue, Empty
|
from Queue import Queue, Empty
|
||||||
|
|
||||||
from xbmc import executeJSONRPC, sleep, translatePath
|
from xbmc import executeJSONRPC, sleep, translatePath
|
||||||
from xbmcvfs import listdir, delete
|
|
||||||
|
|
||||||
from utils import window, settings, language as lang, kodiSQL, tryEncode, \
|
from utils import window, settings, language as lang, kodiSQL, tryEncode, \
|
||||||
tryDecode, IfExists, ThreadMethods, ThreadMethodsAdditionalStop, dialog
|
ThreadMethods, ThreadMethodsAdditionalStop, dialog
|
||||||
|
|
||||||
# Disable annoying requests warnings
|
# Disable annoying requests warnings
|
||||||
import requests.packages.urllib3
|
import requests.packages.urllib3
|
||||||
|
@ -228,30 +228,21 @@ class Artwork():
|
||||||
if dialog('yesno', "Image Texture Cache", lang(39251)):
|
if dialog('yesno', "Image Texture Cache", lang(39251)):
|
||||||
log.info("Resetting all cache data first")
|
log.info("Resetting all cache data first")
|
||||||
# Remove all existing textures first
|
# Remove all existing textures first
|
||||||
path = tryDecode(translatePath("special://thumbnails/"))
|
path = translatePath("special://thumbnails/")
|
||||||
if IfExists(path):
|
if exists(path):
|
||||||
allDirs, allFiles = listdir(path)
|
rmtree(path, ignore_errors=True)
|
||||||
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))
|
|
||||||
|
|
||||||
# remove all existing data from texture DB
|
# remove all existing data from texture DB
|
||||||
connection = kodiSQL('texture')
|
connection = kodiSQL('texture')
|
||||||
cursor = connection.cursor()
|
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()
|
rows = cursor.fetchall()
|
||||||
for row in rows:
|
for row in rows:
|
||||||
tableName = row[0]
|
tableName = row[0]
|
||||||
if tableName != "version":
|
if tableName != "version":
|
||||||
cursor.execute("DELETE FROM " + tableName)
|
query = "DELETE FROM ?"
|
||||||
|
cursor.execute(query, (tableName,))
|
||||||
connection.commit()
|
connection.commit()
|
||||||
connection.close()
|
connection.close()
|
||||||
|
|
||||||
|
@ -259,7 +250,8 @@ class Artwork():
|
||||||
connection = kodiSQL('video')
|
connection = kodiSQL('video')
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
# dont include actors
|
# 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()
|
result = cursor.fetchall()
|
||||||
total = len(result)
|
total = len(result)
|
||||||
log.info("Image cache sync about to process %s video images" % total)
|
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):
|
def addArtwork(self, artwork, kodiId, mediaType, cursor):
|
||||||
# Kodi conversion table
|
# Kodi conversion table
|
||||||
kodiart = {
|
kodiart = {
|
||||||
|
|
||||||
'Primary': ["thumb", "poster"],
|
'Primary': ["thumb", "poster"],
|
||||||
'Banner': "banner",
|
'Banner': "banner",
|
||||||
'Logo': "clearlogo",
|
'Logo': "clearlogo",
|
||||||
|
@ -307,7 +298,6 @@ class Artwork():
|
||||||
backdropsNumber = len(backdrops)
|
backdropsNumber = len(backdrops)
|
||||||
|
|
||||||
query = ' '.join((
|
query = ' '.join((
|
||||||
|
|
||||||
"SELECT url",
|
"SELECT url",
|
||||||
"FROM art",
|
"FROM art",
|
||||||
"WHERE media_id = ?",
|
"WHERE media_id = ?",
|
||||||
|
@ -320,7 +310,6 @@ class Artwork():
|
||||||
if len(rows) > backdropsNumber:
|
if len(rows) > backdropsNumber:
|
||||||
# More backdrops in database. Delete extra fanart.
|
# More backdrops in database. Delete extra fanart.
|
||||||
query = ' '.join((
|
query = ' '.join((
|
||||||
|
|
||||||
"DELETE FROM art",
|
"DELETE FROM art",
|
||||||
"WHERE media_id = ?",
|
"WHERE media_id = ?",
|
||||||
"AND media_type = ?",
|
"AND media_type = ?",
|
||||||
|
@ -339,7 +328,7 @@ class Artwork():
|
||||||
cursor=cursor)
|
cursor=cursor)
|
||||||
|
|
||||||
if backdropsNumber > 1:
|
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
|
index += 1
|
||||||
except TypeError:
|
except TypeError:
|
||||||
index = 1
|
index = 1
|
||||||
|
@ -438,14 +427,10 @@ class Artwork():
|
||||||
log.info("Could not find cached url.")
|
log.info("Could not find cached url.")
|
||||||
else:
|
else:
|
||||||
# Delete thumbnail as well as the entry
|
# Delete thumbnail as well as the entry
|
||||||
thumbnails = tryDecode(
|
path = translatePath("special://thumbnails/%s" % cachedurl)
|
||||||
translatePath("special://thumbnails/%s" % cachedurl))
|
log.debug("Deleting cached thumbnail: %s" % path)
|
||||||
log.debug("Deleting cached thumbnail: %s" % thumbnails)
|
if exists(path):
|
||||||
try:
|
rmtree(path, ignore_errors=True)
|
||||||
delete(thumbnails)
|
|
||||||
except Exception as e:
|
|
||||||
log.error('Could not delete cached artwork %s. Error: %s'
|
|
||||||
% (thumbnails, e))
|
|
||||||
cursor.execute("DELETE FROM texture WHERE url = ?", (url,))
|
cursor.execute("DELETE FROM texture WHERE url = ?", (url,))
|
||||||
connection.commit()
|
connection.commit()
|
||||||
finally:
|
finally:
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
###############################################################################
|
###############################################################################
|
||||||
import logging
|
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 sys import argv
|
||||||
from urllib import urlencode
|
from urllib import urlencode
|
||||||
|
|
||||||
|
@ -9,8 +11,8 @@ import xbmcplugin
|
||||||
from xbmc import sleep, executebuiltin, translatePath
|
from xbmc import sleep, executebuiltin, translatePath
|
||||||
from xbmcgui import ListItem
|
from xbmcgui import ListItem
|
||||||
|
|
||||||
from utils import window, settings, language as lang, dialog, tryDecode,\
|
from utils import window, settings, language as lang, dialog, tryEncode, \
|
||||||
tryEncode, CatchExceptions, JSONRPC
|
CatchExceptions, JSONRPC
|
||||||
import downloadutils
|
import downloadutils
|
||||||
|
|
||||||
from PlexFunctions import GetPlexMetadata, GetPlexSectionResults, \
|
from PlexFunctions import GetPlexMetadata, GetPlexSectionResults, \
|
||||||
|
@ -486,6 +488,7 @@ def getVideoFiles(plexId, params):
|
||||||
except:
|
except:
|
||||||
log.error('Could not get file path for item %s' % plexId)
|
log.error('Could not get file path for item %s' % plexId)
|
||||||
return xbmcplugin.endOfDirectory(HANDLE)
|
return xbmcplugin.endOfDirectory(HANDLE)
|
||||||
|
path = tryEncode(path)
|
||||||
# Assign network protocol
|
# Assign network protocol
|
||||||
if path.startswith('\\\\'):
|
if path.startswith('\\\\'):
|
||||||
path = path.replace('\\\\', 'smb://')
|
path = path.replace('\\\\', 'smb://')
|
||||||
|
@ -493,28 +496,25 @@ def getVideoFiles(plexId, params):
|
||||||
# Plex returns Windows paths as e.g. 'c:\slfkjelf\slfje\file.mkv'
|
# Plex returns Windows paths as e.g. 'c:\slfkjelf\slfje\file.mkv'
|
||||||
elif '\\' in path:
|
elif '\\' in path:
|
||||||
path = path.replace('\\', '\\\\')
|
path = path.replace('\\', '\\\\')
|
||||||
# Directory only, get rid of filename (!! exists() needs / or \ at end)
|
# Directory only, get rid of filename
|
||||||
path = path.replace(os_path.basename(path), '')
|
path = path.replace(basename(path), '')
|
||||||
# Only proceed if we can access this folder
|
if exists(path):
|
||||||
import xbmcvfs
|
for root, dirs, files in walk(path):
|
||||||
if xbmcvfs.exists(path):
|
for directory in dirs:
|
||||||
# Careful, returns encoded strings!
|
item_path = join(root, directory)
|
||||||
dirs, files = xbmcvfs.listdir(path)
|
li = ListItem(item_path, path=item_path)
|
||||||
for file in files:
|
xbmcplugin.addDirectoryItem(handle=HANDLE,
|
||||||
file = path + tryDecode(file)
|
url=item_path,
|
||||||
li = ListItem(file, path=file)
|
listitem=li,
|
||||||
xbmcplugin.addDirectoryItem(handle=HANDLE,
|
isFolder=True)
|
||||||
url=tryEncode(file),
|
for file in files:
|
||||||
listitem=li)
|
item_path = join(root, file)
|
||||||
for dir in dirs:
|
li = ListItem(item_path, path=item_path)
|
||||||
dir = path + tryDecode(dir)
|
xbmcplugin.addDirectoryItem(handle=HANDLE,
|
||||||
li = ListItem(dir, path=dir)
|
url=file,
|
||||||
xbmcplugin.addDirectoryItem(handle=HANDLE,
|
listitem=li)
|
||||||
url=tryEncode(dir),
|
|
||||||
listitem=li,
|
|
||||||
isFolder=True)
|
|
||||||
else:
|
else:
|
||||||
log.warn('Kodi cannot access folder %s' % path)
|
log.error('Kodi cannot access folder %s' % path)
|
||||||
xbmcplugin.endOfDirectory(HANDLE)
|
xbmcplugin.endOfDirectory(HANDLE)
|
||||||
|
|
||||||
|
|
||||||
|
@ -525,7 +525,6 @@ def getExtraFanArt(plexid, plexPath):
|
||||||
will be called by skinhelper script to get the extrafanart
|
will be called by skinhelper script to get the extrafanart
|
||||||
for tvshows we get the plexid just from the path
|
for tvshows we get the plexid just from the path
|
||||||
"""
|
"""
|
||||||
import xbmcvfs
|
|
||||||
log.debug('Called with plexid: %s, plexPath: %s' % (plexid, plexPath))
|
log.debug('Called with plexid: %s, plexPath: %s' % (plexid, plexPath))
|
||||||
if not plexid:
|
if not plexid:
|
||||||
if "plugin.video.plexkodiconnect" in plexPath:
|
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
|
# 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 = tryDecode(translatePath(
|
fanartDir = translatePath("special://thumbnails/plex/%s/" % plexid)
|
||||||
"special://thumbnails/plex/%s/" % plexid))
|
if not exists(fanartDir):
|
||||||
if not xbmcvfs.exists(fanartDir):
|
|
||||||
# Download the images to the cache directory
|
# Download the images to the cache directory
|
||||||
xbmcvfs.mkdirs(tryEncode(fanartDir))
|
makedirs(fanartDir)
|
||||||
xml = GetPlexMetadata(plexid)
|
xml = GetPlexMetadata(plexid)
|
||||||
if xml is None:
|
if xml is None:
|
||||||
log.error('Could not download metadata for %s' % plexid)
|
log.error('Could not download metadata for %s' % plexid)
|
||||||
|
@ -550,29 +548,23 @@ def getExtraFanArt(plexid, plexPath):
|
||||||
backdrops = api.getAllArtwork()['Backdrop']
|
backdrops = api.getAllArtwork()['Backdrop']
|
||||||
for count, backdrop in enumerate(backdrops):
|
for count, backdrop in enumerate(backdrops):
|
||||||
# Same ordering as in artwork
|
# Same ordering as in artwork
|
||||||
if os_path.supports_unicode_filenames:
|
fanartFile = join(fanartDir, "fanart%.3d.jpg" % count)
|
||||||
fanartFile = os_path.join(fanartDir,
|
|
||||||
"fanart%.3d.jpg" % count)
|
|
||||||
else:
|
|
||||||
fanartFile = os_path.join(
|
|
||||||
tryEncode(fanartDir),
|
|
||||||
tryEncode("fanart%.3d.jpg" % count))
|
|
||||||
li = ListItem("%.3d" % count, path=fanartFile)
|
li = ListItem("%.3d" % count, path=fanartFile)
|
||||||
xbmcplugin.addDirectoryItem(
|
xbmcplugin.addDirectoryItem(
|
||||||
handle=HANDLE,
|
handle=HANDLE,
|
||||||
url=fanartFile,
|
url=fanartFile,
|
||||||
listitem=li)
|
listitem=li)
|
||||||
xbmcvfs.copy(backdrop, fanartFile)
|
copyfile(backdrop, fanartFile)
|
||||||
else:
|
else:
|
||||||
log.info("Found cached backdrop.")
|
log.info("Found cached backdrop.")
|
||||||
# Use existing cached images
|
# Use existing cached images
|
||||||
dirs, files = xbmcvfs.listdir(fanartDir)
|
for root, dirs, files in walk(fanartDir):
|
||||||
for file in files:
|
for file in files:
|
||||||
fanartFile = os_path.join(fanartDir, tryDecode(file))
|
fanartFile = join(root, file)
|
||||||
li = ListItem(file, path=fanartFile)
|
li = ListItem(file, path=fanartFile)
|
||||||
xbmcplugin.addDirectoryItem(handle=HANDLE,
|
xbmcplugin.addDirectoryItem(handle=HANDLE,
|
||||||
url=fanartFile,
|
url=fanartFile,
|
||||||
listitem=li)
|
listitem=li)
|
||||||
xbmcplugin.endOfDirectory(HANDLE)
|
xbmcplugin.endOfDirectory(HANDLE)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
import Queue
|
import Queue
|
||||||
from random import shuffle
|
from random import shuffle
|
||||||
|
from os.path import exists
|
||||||
|
|
||||||
import xbmc
|
import xbmc
|
||||||
import xbmcgui
|
import xbmcgui
|
||||||
import xbmcvfs
|
|
||||||
|
|
||||||
from utils import window, settings, getUnixTimestamp, sourcesXML,\
|
from utils import window, settings, getUnixTimestamp, sourcesXML,\
|
||||||
ThreadMethods, ThreadMethodsAdditionalStop, LogTime, getScreensaver,\
|
ThreadMethods, ThreadMethodsAdditionalStop, LogTime, getScreensaver,\
|
||||||
|
@ -1505,7 +1503,7 @@ class LibrarySync(Thread):
|
||||||
# Also runs when first installed
|
# Also runs when first installed
|
||||||
# Verify the video database can be found
|
# Verify the video database can be found
|
||||||
videoDb = v.DB_VIDEO_PATH
|
videoDb = v.DB_VIDEO_PATH
|
||||||
if not xbmcvfs.exists(videoDb):
|
if not exists(videoDb):
|
||||||
# Database does not exists
|
# Database does not exists
|
||||||
log.error("The current Kodi version is incompatible "
|
log.error("The current Kodi version is incompatible "
|
||||||
"to know which Kodi versions are supported.")
|
"to know which Kodi versions are supported.")
|
||||||
|
|
|
@ -3,14 +3,15 @@
|
||||||
###############################################################################
|
###############################################################################
|
||||||
import logging
|
import logging
|
||||||
import threading
|
import threading
|
||||||
|
from os.path import exists
|
||||||
|
|
||||||
import xbmc
|
import xbmc
|
||||||
import xbmcgui
|
import xbmcgui
|
||||||
import xbmcaddon
|
import xbmcaddon
|
||||||
import xbmcvfs
|
|
||||||
|
|
||||||
from utils import window, settings, language as lang, ThreadMethods, \
|
from utils import window, settings, language as lang, ThreadMethods, \
|
||||||
tryDecode, ThreadMethodsAdditionalSuspend
|
ThreadMethodsAdditionalSuspend
|
||||||
import downloadutils
|
import downloadutils
|
||||||
|
|
||||||
import PlexAPI
|
import PlexAPI
|
||||||
|
@ -209,9 +210,8 @@ class UserClient(threading.Thread):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Get /profile/addon_data
|
# Get /profile/addon_data
|
||||||
addondir = tryDecode(xbmc.translatePath(
|
addondir = xbmc.translatePath(self.addon.getAddonInfo('profile'))
|
||||||
self.addon.getAddonInfo('profile')))
|
hasSettings = exists("%ssettings.xml" % addondir)
|
||||||
hasSettings = xbmcvfs.exists("%ssettings.xml" % addondir)
|
|
||||||
|
|
||||||
# If there's no settings.xml
|
# If there's no settings.xml
|
||||||
if not hasSettings:
|
if not hasSettings:
|
||||||
|
|
|
@ -13,12 +13,13 @@ from unicodedata import normalize
|
||||||
import xml.etree.ElementTree as etree
|
import xml.etree.ElementTree as etree
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from calendar import timegm
|
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 xbmc
|
||||||
import xbmcaddon
|
import xbmcaddon
|
||||||
import xbmcgui
|
import xbmcgui
|
||||||
import xbmcvfs
|
|
||||||
|
|
||||||
from variables import DB_VIDEO_PATH, DB_MUSIC_PATH, DB_TEXTURE_PATH, \
|
from variables import DB_VIDEO_PATH, DB_MUSIC_PATH, DB_TEXTURE_PATH, \
|
||||||
DB_PLEX_PATH
|
DB_PLEX_PATH
|
||||||
|
@ -198,27 +199,6 @@ def DateToKodi(stamp):
|
||||||
return localdate
|
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):
|
def IntFromStr(string):
|
||||||
"""
|
"""
|
||||||
Returns an int from string or the int 0 if something happened
|
Returns an int from string or the int 0 if something happened
|
||||||
|
@ -362,24 +342,14 @@ def reset():
|
||||||
line1=language(39602)):
|
line1=language(39602)):
|
||||||
log.info("Resetting all cached artwork.")
|
log.info("Resetting all cached artwork.")
|
||||||
# Remove all existing textures first
|
# Remove all existing textures first
|
||||||
path = tryDecode(xbmc.translatePath("special://thumbnails/"))
|
path = xbmc.translatePath("special://thumbnails/")
|
||||||
if xbmcvfs.exists(path):
|
if exists(path):
|
||||||
allDirs, allFiles = xbmcvfs.listdir(path)
|
rmtree(path, ignore_errors=True)
|
||||||
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))
|
|
||||||
# remove all existing data from texture DB
|
# remove all existing data from texture DB
|
||||||
connection = kodiSQL('texture')
|
connection = kodiSQL('texture')
|
||||||
cursor = connection.cursor()
|
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()
|
rows = cursor.fetchall()
|
||||||
for row in rows:
|
for row in rows:
|
||||||
tableName = row[0]
|
tableName = row[0]
|
||||||
|
@ -398,10 +368,10 @@ def reset():
|
||||||
line1=language(39603)):
|
line1=language(39603)):
|
||||||
# Delete the settings
|
# Delete the settings
|
||||||
addon = xbmcaddon.Addon()
|
addon = xbmcaddon.Addon()
|
||||||
addondir = tryDecode(xbmc.translatePath(addon.getAddonInfo('profile')))
|
addondir = xbmc.translatePath(addon.getAddonInfo('profile'))
|
||||||
dataPath = "%ssettings.xml" % addondir
|
dataPath = "%ssettings.xml" % addondir
|
||||||
log.info("Deleting: settings.xml")
|
log.info("Deleting: settings.xml")
|
||||||
xbmcvfs.delete(tryEncode(dataPath))
|
remove(dataPath)
|
||||||
|
|
||||||
# Kodi will now restart to apply the changes.
|
# Kodi will now restart to apply the changes.
|
||||||
dialog('ok',
|
dialog('ok',
|
||||||
|
@ -664,12 +634,13 @@ def sourcesXML():
|
||||||
|
|
||||||
def passwordsXML():
|
def passwordsXML():
|
||||||
# To add network credentials
|
# To add network credentials
|
||||||
path = tryDecode(xbmc.translatePath("special://userdata/"))
|
path = xbmc.translatePath("special://userdata/")
|
||||||
xmlpath = "%spasswords.xml" % path
|
xmlpath = "%spasswords.xml" % path
|
||||||
|
|
||||||
try:
|
try:
|
||||||
xmlparse = etree.parse(xmlpath)
|
xmlparse = etree.parse(xmlpath)
|
||||||
except: # Document is blank or missing
|
except:
|
||||||
|
# Document is blank or missing
|
||||||
root = etree.Element('passwords')
|
root = etree.Element('passwords')
|
||||||
skipFind = True
|
skipFind = True
|
||||||
else:
|
else:
|
||||||
|
@ -753,8 +724,6 @@ def passwordsXML():
|
||||||
etree.SubElement(path, 'from', attrib={'pathversion': "1"}).text = "smb://%s/" % server
|
etree.SubElement(path, 'from', attrib={'pathversion': "1"}).text = "smb://%s/" % server
|
||||||
topath = "smb://%s:%s@%s/" % (user, password, server)
|
topath = "smb://%s:%s@%s/" % (user, password, server)
|
||||||
etree.SubElement(path, 'to', attrib={'pathversion': "1"}).text = topath
|
etree.SubElement(path, 'to', attrib={'pathversion': "1"}).text = topath
|
||||||
# Force Kodi to see the credentials without restarting
|
|
||||||
xbmcvfs.exists(topath)
|
|
||||||
|
|
||||||
# Add credentials
|
# Add credentials
|
||||||
settings('networkCreds', value="%s" % server)
|
settings('networkCreds', value="%s" % server)
|
||||||
|
@ -762,7 +731,8 @@ def passwordsXML():
|
||||||
# Prettify and write to file
|
# Prettify and write to file
|
||||||
try:
|
try:
|
||||||
indent(root)
|
indent(root)
|
||||||
except: pass
|
except:
|
||||||
|
pass
|
||||||
etree.ElementTree(root).write(xmlpath)
|
etree.ElementTree(root).write(xmlpath)
|
||||||
|
|
||||||
# dialog.notification(
|
# dialog.notification(
|
||||||
|
@ -776,7 +746,7 @@ def playlistXSP(mediatype, tagname, viewid, viewtype="", delete=False):
|
||||||
"""
|
"""
|
||||||
Feed with tagname as unicode
|
Feed with tagname as unicode
|
||||||
"""
|
"""
|
||||||
path = tryDecode(xbmc.translatePath("special://profile/playlists/video/"))
|
path = 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)
|
||||||
|
@ -785,20 +755,20 @@ 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(tryEncode(path)):
|
if not exists(path):
|
||||||
log.info("Creating directory: %s" % path)
|
log.info("Creating directory: %s" % path)
|
||||||
xbmcvfs.mkdirs(tryEncode(path))
|
makedirs(path)
|
||||||
|
|
||||||
# Only add the playlist if it doesn't already exists
|
# 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)
|
log.info('Path %s does exist' % xsppath)
|
||||||
if delete:
|
if delete:
|
||||||
xbmcvfs.delete(tryEncode(xsppath))
|
remove(xsppath)
|
||||||
log.info("Successfully removed playlist: %s." % tagname)
|
log.info("Successfully removed playlist: %s." % tagname)
|
||||||
|
|
||||||
return
|
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 = {
|
itemtypes = {
|
||||||
'homevideos': 'movies',
|
'homevideos': 'movies',
|
||||||
'movie': 'movies',
|
'movie': 'movies',
|
||||||
|
@ -806,51 +776,39 @@ def playlistXSP(mediatype, tagname, viewid, viewtype="", delete=False):
|
||||||
}
|
}
|
||||||
log.info("Writing playlist file to: %s" % xsppath)
|
log.info("Writing playlist file to: %s" % xsppath)
|
||||||
try:
|
try:
|
||||||
f = xbmcvfs.File(tryEncode(xsppath), 'wb')
|
with open(xsppath, 'wb'):
|
||||||
except:
|
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("Failed to create playlist: %s" % xsppath)
|
||||||
|
log.error(e)
|
||||||
return
|
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)
|
log.info("Successfully added playlist: %s" % tagname)
|
||||||
|
|
||||||
def deletePlaylists():
|
def deletePlaylists():
|
||||||
|
|
||||||
# Clean up the playlists
|
# Clean up the playlists
|
||||||
path = tryDecode(xbmc.translatePath("special://profile/playlists/video/"))
|
path = xbmc.translatePath("special://profile/playlists/video/")
|
||||||
dirs, files = xbmcvfs.listdir(tryEncode(path))
|
for root, _, files in walk(path):
|
||||||
for file in files:
|
for file in files:
|
||||||
if tryDecode(file).startswith('Plex'):
|
if file.startswith('Plex'):
|
||||||
xbmcvfs.delete(tryEncode("%s%s" % (path, tryDecode(file))))
|
remove(join(root, file))
|
||||||
|
|
||||||
def deleteNodes():
|
def deleteNodes():
|
||||||
|
|
||||||
# Clean up video nodes
|
# Clean up video nodes
|
||||||
import shutil
|
path = xbmc.translatePath("special://profile/library/video/")
|
||||||
path = tryDecode(xbmc.translatePath("special://profile/library/video/"))
|
for root, dirs, _ in walk(path):
|
||||||
dirs, files = xbmcvfs.listdir(tryEncode(path))
|
for directory in dirs:
|
||||||
for dir in dirs:
|
if directory.startswith('Plex-'):
|
||||||
if tryDecode(dir).startswith('Plex'):
|
rmtree(join(root, directory))
|
||||||
try:
|
break
|
||||||
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))
|
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
import xbmc
|
import xbmc
|
||||||
from xbmcaddon import Addon
|
from xbmcaddon import Addon
|
||||||
|
|
||||||
|
# Paths are in string, not unicode!
|
||||||
|
|
||||||
|
|
||||||
def tryDecode(string, encoding='utf-8'):
|
def tryDecode(string, encoding='utf-8'):
|
||||||
"""
|
"""
|
||||||
|
@ -27,7 +29,7 @@ ADDON_VERSION = _ADDON.getAddonInfo('version')
|
||||||
KODILANGUAGE = xbmc.getLanguage(xbmc.ISO_639_1)
|
KODILANGUAGE = xbmc.getLanguage(xbmc.ISO_639_1)
|
||||||
KODIVERSION = int(xbmc.getInfoLabel("System.BuildVersion")[:2])
|
KODIVERSION = int(xbmc.getInfoLabel("System.BuildVersion")[:2])
|
||||||
KODILONGVERSION = xbmc.getInfoLabel('System.BuildVersion')
|
KODILONGVERSION = xbmc.getInfoLabel('System.BuildVersion')
|
||||||
KODI_PROFILE = tryDecode(xbmc.translatePath("special://profile"))
|
KODI_PROFILE = xbmc.translatePath("special://profile")
|
||||||
|
|
||||||
if xbmc.getCondVisibility('system.platform.osx'):
|
if xbmc.getCondVisibility('system.platform.osx'):
|
||||||
PLATFORM = "MacOSX"
|
PLATFORM = "MacOSX"
|
||||||
|
@ -68,8 +70,8 @@ _DB_VIDEO_VERSION = {
|
||||||
17: 107, # Krypton
|
17: 107, # Krypton
|
||||||
18: 107 # Leia
|
18: 107 # Leia
|
||||||
}
|
}
|
||||||
DB_VIDEO_PATH = tryDecode(xbmc.translatePath(
|
DB_VIDEO_PATH = xbmc.translatePath(
|
||||||
"special://database/MyVideos%s.db" % _DB_VIDEO_VERSION[KODIVERSION]))
|
"special://database/MyVideos%s.db" % _DB_VIDEO_VERSION[KODIVERSION])
|
||||||
|
|
||||||
_DB_MUSIC_VERSION = {
|
_DB_MUSIC_VERSION = {
|
||||||
13: 46, # Gotham
|
13: 46, # Gotham
|
||||||
|
@ -79,8 +81,8 @@ _DB_MUSIC_VERSION = {
|
||||||
17: 60, # Krypton
|
17: 60, # Krypton
|
||||||
18: 60 # Leia
|
18: 60 # Leia
|
||||||
}
|
}
|
||||||
DB_MUSIC_PATH = tryDecode(xbmc.translatePath(
|
DB_MUSIC_PATH = xbmc.translatePath(
|
||||||
"special://database/MyMusic%s.db" % _DB_MUSIC_VERSION[KODIVERSION]))
|
"special://database/MyMusic%s.db" % _DB_MUSIC_VERSION[KODIVERSION])
|
||||||
|
|
||||||
_DB_TEXTURE_VERSION = {
|
_DB_TEXTURE_VERSION = {
|
||||||
13: 13, # Gotham
|
13: 13, # Gotham
|
||||||
|
@ -90,13 +92,13 @@ _DB_TEXTURE_VERSION = {
|
||||||
17: 13, # Krypton
|
17: 13, # Krypton
|
||||||
18: 13 # Leia
|
18: 13 # Leia
|
||||||
}
|
}
|
||||||
DB_TEXTURE_PATH = tryDecode(xbmc.translatePath(
|
DB_TEXTURE_PATH = xbmc.translatePath(
|
||||||
"special://database/Textures%s.db" % _DB_TEXTURE_VERSION[KODIVERSION]))
|
"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(
|
EXTERNAL_SUBTITLE_TEMP_PATH = xbmc.translatePath(
|
||||||
"special://profile/addon_data/%s/temp/" % ADDON_ID))
|
"special://profile/addon_data/%s/temp/" % ADDON_ID)
|
||||||
|
|
||||||
|
|
||||||
# Multiply Plex time by this factor to receive Kodi time
|
# Multiply Plex time by this factor to receive Kodi time
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import shutil
|
from shutil import copytree
|
||||||
import xml.etree.ElementTree as etree
|
import xml.etree.ElementTree as etree
|
||||||
|
|
||||||
import xbmc
|
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, \
|
from utils import window, settings, language as lang, tryEncode, indent, \
|
||||||
tryEncode, indent, normalize_nodes
|
normalize_nodes
|
||||||
import variables as v
|
import variables as v
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
@ -18,6 +17,7 @@ import variables as v
|
||||||
log = logging.getLogger("PLEX."+__name__)
|
log = logging.getLogger("PLEX."+__name__)
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
# Paths are strings, NOT unicode!
|
||||||
|
|
||||||
|
|
||||||
class VideoNodes(object):
|
class VideoNodes(object):
|
||||||
|
@ -61,36 +61,30 @@ class VideoNodes(object):
|
||||||
else:
|
else:
|
||||||
dirname = viewid
|
dirname = viewid
|
||||||
|
|
||||||
path = tryDecode(xbmc.translatePath(
|
# Returns strings
|
||||||
"special://profile/library/video/"))
|
path = xbmc.translatePath("special://profile/library/video/")
|
||||||
nodepath = tryDecode(xbmc.translatePath(
|
nodepath = xbmc.translatePath(
|
||||||
"special://profile/library/video/Plex-%s/" % dirname))
|
"special://profile/library/video/Plex-%s/" % dirname)
|
||||||
|
|
||||||
if delete:
|
if delete:
|
||||||
dirs, files = xbmcvfs.listdir(tryEncode(nodepath))
|
files = [f for f in listdir(nodepath) if isfile(join(nodepath, f))]
|
||||||
for file in files:
|
for file in files:
|
||||||
xbmcvfs.delete(tryEncode(
|
remove(nodepath + file)
|
||||||
(nodepath + tryDecode(file))))
|
|
||||||
log.info("Sucessfully removed videonode: %s." % tagname)
|
log.info("Sucessfully removed videonode: %s." % tagname)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Verify the video directory
|
# Verify the video directory
|
||||||
# KODI BUG
|
if exists(path) is False:
|
||||||
# Kodi caches the result of exists for directories
|
copytree(
|
||||||
# so try creating a file
|
src=xbmc.translatePath("special://xbmc/system/library/video"),
|
||||||
if IfExists(path) is False:
|
dst=xbmc.translatePath("special://profile/library/video"))
|
||||||
shutil.copytree(
|
|
||||||
src=tryDecode(xbmc.translatePath(
|
|
||||||
"special://xbmc/system/library/video")),
|
|
||||||
dst=tryDecode(xbmc.translatePath(
|
|
||||||
"special://profile/library/video")))
|
|
||||||
|
|
||||||
# Create the node directory
|
# Create the node directory
|
||||||
if mediatype != "photos":
|
if mediatype != "photos":
|
||||||
if IfExists(nodepath) is False:
|
if exists(nodepath) is False:
|
||||||
# folder does not exist yet
|
# folder does not exist yet
|
||||||
log.debug('Creating folder %s' % nodepath)
|
log.debug('Creating folder %s' % nodepath)
|
||||||
xbmcvfs.mkdirs(tryEncode(nodepath))
|
makedirs(nodepath)
|
||||||
|
|
||||||
# Create index entry
|
# Create index entry
|
||||||
nodeXML = "%sindex.xml" % nodepath
|
nodeXML = "%sindex.xml" % nodepath
|
||||||
|
@ -103,23 +97,29 @@ class VideoNodes(object):
|
||||||
|
|
||||||
if mediatype == "photos":
|
if mediatype == "photos":
|
||||||
path = "plugin://plugin.video.plexkodiconnect?mode=browseplex&key=/library/sections/%s&id=%s" % (viewid, viewid)
|
path = "plugin://plugin.video.plexkodiconnect?mode=browseplex&key=/library/sections/%s&id=%s" % (viewid, viewid)
|
||||||
|
|
||||||
window('Plex.nodes.%s.index' % indexnumber, value=path)
|
window('Plex.nodes.%s.index' % indexnumber, value=path)
|
||||||
|
|
||||||
# Root
|
# Root
|
||||||
if not mediatype == "photos":
|
if not mediatype == "photos":
|
||||||
if viewtype == "mixed":
|
if viewtype == "mixed":
|
||||||
specialtag = "%s-%s" % (tagname, mediatype)
|
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:
|
else:
|
||||||
root = self.commonRoot(order=0, label=tagname, tagname=tagname, roottype=0)
|
root = self.commonRoot(order=0,
|
||||||
|
label=tagname,
|
||||||
|
tagname=tagname,
|
||||||
|
roottype=0)
|
||||||
try:
|
try:
|
||||||
indent(root)
|
indent(root)
|
||||||
except: pass
|
except:
|
||||||
|
pass
|
||||||
etree.ElementTree(root).write(nodeXML)
|
etree.ElementTree(root).write(nodeXML)
|
||||||
|
|
||||||
nodetypes = {
|
nodetypes = {
|
||||||
|
|
||||||
'1': "all",
|
'1': "all",
|
||||||
'2': "recent",
|
'2': "recent",
|
||||||
'3': "recentepisodes",
|
'3': "recentepisodes",
|
||||||
|
@ -255,7 +255,7 @@ class VideoNodes(object):
|
||||||
path = 'plugin://plugin.video.plexkodiconnect?mode=browseplex&key=/library/sections/%s/folder' % viewid
|
path = 'plugin://plugin.video.plexkodiconnect?mode=browseplex&key=/library/sections/%s/folder' % viewid
|
||||||
else:
|
else:
|
||||||
path = "library://video/Plex-%s/%s_%s.xml" % (dirname, viewid, nodetype)
|
path = "library://video/Plex-%s/%s_%s.xml" % (dirname, viewid, nodetype)
|
||||||
|
|
||||||
if mediatype == "photos":
|
if mediatype == "photos":
|
||||||
windowpath = "ActivateWindow(Pictures,%s,return)" % path
|
windowpath = "ActivateWindow(Pictures,%s,return)" % path
|
||||||
else:
|
else:
|
||||||
|
@ -264,7 +264,7 @@ class VideoNodes(object):
|
||||||
windowpath = "ActivateWindow(Videos,%s,return)" % path
|
windowpath = "ActivateWindow(Videos,%s,return)" % path
|
||||||
else:
|
else:
|
||||||
windowpath = "ActivateWindow(Video,%s,return)" % path
|
windowpath = "ActivateWindow(Video,%s,return)" % path
|
||||||
|
|
||||||
if nodetype == "all":
|
if nodetype == "all":
|
||||||
|
|
||||||
if viewtype == "mixed":
|
if viewtype == "mixed":
|
||||||
|
@ -288,8 +288,8 @@ class VideoNodes(object):
|
||||||
# to be created.
|
# to be created.
|
||||||
# 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(tryEncode(nodeXML)):
|
if exists(nodeXML):
|
||||||
# Don't recreate xml if already exists
|
# Don't recreate xml if already exists
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -370,15 +370,14 @@ class VideoNodes(object):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
indent(root)
|
indent(root)
|
||||||
except: pass
|
except:
|
||||||
|
pass
|
||||||
etree.ElementTree(root).write(nodeXML)
|
etree.ElementTree(root).write(nodeXML)
|
||||||
|
|
||||||
def singleNode(self, indexnumber, tagname, mediatype, itemtype):
|
def singleNode(self, indexnumber, tagname, mediatype, itemtype):
|
||||||
|
|
||||||
tagname = tryEncode(tagname)
|
tagname = tryEncode(tagname)
|
||||||
cleantagname = normalize_nodes(tagname)
|
cleantagname = normalize_nodes(tagname)
|
||||||
nodepath = tryDecode(xbmc.translatePath(
|
nodepath = xbmc.translatePath("special://profile/library/video/")
|
||||||
"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
|
||||||
if v.KODIVERSION >= 17:
|
if v.KODIVERSION >= 17:
|
||||||
|
@ -388,17 +387,13 @@ class VideoNodes(object):
|
||||||
windowpath = "ActivateWindow(Video,%s,return)" % path
|
windowpath = "ActivateWindow(Video,%s,return)" % path
|
||||||
|
|
||||||
# Create the video node directory
|
# Create the video node directory
|
||||||
if not xbmcvfs.exists(nodepath):
|
if not exists(nodepath):
|
||||||
# We need to copy over the default items
|
# We need to copy over the default items
|
||||||
shutil.copytree(
|
copytree(
|
||||||
src=tryDecode(xbmc.translatePath(
|
src=xbmc.translatePath("special://xbmc/system/library/video"),
|
||||||
"special://xbmc/system/library/video")),
|
dst=xbmc.translatePath("special://profile/library/video"))
|
||||||
dst=tryDecode(xbmc.translatePath(
|
|
||||||
"special://profile/library/video")))
|
|
||||||
xbmcvfs.exists(path)
|
|
||||||
|
|
||||||
labels = {
|
labels = {
|
||||||
|
|
||||||
'Favorite movies': 30180,
|
'Favorite movies': 30180,
|
||||||
'Favorite tvshows': 30181,
|
'Favorite tvshows': 30181,
|
||||||
'channels': 30173
|
'channels': 30173
|
||||||
|
@ -410,12 +405,15 @@ class VideoNodes(object):
|
||||||
window('%s.content' % embynode, value=path)
|
window('%s.content' % embynode, value=path)
|
||||||
window('%s.type' % embynode, value=itemtype)
|
window('%s.type' % embynode, value=itemtype)
|
||||||
|
|
||||||
if xbmcvfs.exists(nodeXML):
|
if exists(nodeXML):
|
||||||
# Don't recreate xml if already exists
|
# Don't recreate xml if already exists
|
||||||
return
|
return
|
||||||
|
|
||||||
if itemtype == "channels":
|
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"
|
etree.SubElement(root, 'path').text = "plugin://plugin.video.plexkodiconnect/?id=0&mode=channels"
|
||||||
else:
|
else:
|
||||||
root = self.commonRoot(order=1, label=label, tagname=tagname)
|
root = self.commonRoot(order=1, label=label, tagname=tagname)
|
||||||
|
@ -425,7 +423,8 @@ class VideoNodes(object):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
indent(root)
|
indent(root)
|
||||||
except: pass
|
except:
|
||||||
|
pass
|
||||||
etree.ElementTree(root).write(nodeXML)
|
etree.ElementTree(root).write(nodeXML)
|
||||||
|
|
||||||
def clearProperties(self):
|
def clearProperties(self):
|
||||||
|
@ -433,7 +432,6 @@ class VideoNodes(object):
|
||||||
log.info("Clearing nodes properties.")
|
log.info("Clearing nodes properties.")
|
||||||
plexprops = window('Plex.nodes.total')
|
plexprops = window('Plex.nodes.total')
|
||||||
propnames = [
|
propnames = [
|
||||||
|
|
||||||
"index","path","title","content",
|
"index","path","title","content",
|
||||||
"inprogress.content","inprogress.title",
|
"inprogress.content","inprogress.title",
|
||||||
"inprogress.content","inprogress.path",
|
"inprogress.content","inprogress.path",
|
||||||
|
|
|
@ -164,12 +164,11 @@ class Service():
|
||||||
counter = 0
|
counter = 0
|
||||||
while not monitor.abortRequested():
|
while not monitor.abortRequested():
|
||||||
|
|
||||||
if tryDecode(window('plex_kodiProfile')) != kodiProfile:
|
if window('plex_kodiProfile') != kodiProfile:
|
||||||
# Profile change happened, terminate this thread and others
|
# Profile change happened, terminate this thread and others
|
||||||
log.warn("Kodi profile was: %s and changed to: %s. "
|
log.warn("Kodi profile was: %s and changed to: %s. "
|
||||||
"Terminating old PlexKodiConnect thread."
|
"Terminating old PlexKodiConnect thread."
|
||||||
% (kodiProfile,
|
% (kodiProfile, window('plex_kodiProfile')))
|
||||||
tryDecode(window('plex_kodiProfile'))))
|
|
||||||
break
|
break
|
||||||
|
|
||||||
# Before proceeding, need to make sure:
|
# Before proceeding, need to make sure:
|
||||||
|
|
Loading…
Reference in a new issue