Prettify
This commit is contained in:
parent
406c2b9f63
commit
ca8ad96a05
19 changed files with 301 additions and 362 deletions
|
@ -32,7 +32,7 @@ sys_path.append(_base_resource)
|
|||
###############################################################################
|
||||
|
||||
import entrypoint
|
||||
from utils import window, reset, passwordsXML, language as lang, dialog, \
|
||||
from utils import window, reset, passwords_xml, language as lang, dialog, \
|
||||
plex_command
|
||||
from pickler import unpickle_me, pickl_window
|
||||
from PKC_listitem import convert_PKC_to_listitem
|
||||
|
@ -115,7 +115,7 @@ class Main():
|
|||
entrypoint.resetAuth()
|
||||
|
||||
elif mode == 'passwords':
|
||||
passwordsXML()
|
||||
passwords_xml()
|
||||
|
||||
elif mode == 'switchuser':
|
||||
entrypoint.switchPlexUser()
|
||||
|
|
|
@ -40,8 +40,8 @@ from xbmcvfs import exists
|
|||
|
||||
import clientinfo as client
|
||||
from downloadutils import DownloadUtils as DU
|
||||
from utils import window, settings, language as lang, tryDecode, tryEncode, \
|
||||
DateToKodi, exists_dir, slugify, dialog
|
||||
from utils import window, settings, language as lang, try_decode, try_encode, \
|
||||
unix_date_to_kodi, exists_dir, slugify, dialog
|
||||
import PlexFunctions as PF
|
||||
import plexdb_functions as plexdb
|
||||
import variables as v
|
||||
|
@ -139,7 +139,7 @@ class API():
|
|||
ans = None
|
||||
if ans is not None:
|
||||
try:
|
||||
ans = tryDecode(unquote(ans))
|
||||
ans = try_decode(unquote(ans))
|
||||
except UnicodeDecodeError:
|
||||
# Sometimes, Plex seems to have encoded in latin1
|
||||
ans = unquote(ans).decode('latin1')
|
||||
|
@ -167,7 +167,7 @@ class API():
|
|||
self.item[0][0].attrib['key']))
|
||||
# Attach Plex id to url to let it be picked up by our playqueue agent
|
||||
# later
|
||||
return tryEncode('%s&plex_id=%s' % (path, self.getRatingKey()))
|
||||
return try_encode('%s&plex_id=%s' % (path, self.getRatingKey()))
|
||||
|
||||
def getTVShowPath(self):
|
||||
"""
|
||||
|
@ -194,7 +194,7 @@ class API():
|
|||
"""
|
||||
res = self.item.attrib.get('addedAt')
|
||||
if res is not None:
|
||||
res = DateToKodi(res)
|
||||
res = unix_date_to_kodi(res)
|
||||
else:
|
||||
res = '2000-01-01 10:00:00'
|
||||
return res
|
||||
|
@ -231,7 +231,7 @@ class API():
|
|||
played = True if playcount else False
|
||||
|
||||
try:
|
||||
lastPlayedDate = DateToKodi(int(item['lastViewedAt']))
|
||||
lastPlayedDate = unix_date_to_kodi(int(item['lastViewedAt']))
|
||||
except (KeyError, ValueError):
|
||||
lastPlayedDate = None
|
||||
|
||||
|
@ -884,7 +884,7 @@ class API():
|
|||
parameters = {
|
||||
'api_key': apiKey,
|
||||
'language': v.KODILANGUAGE,
|
||||
'query': tryEncode(title)
|
||||
'query': try_encode(title)
|
||||
}
|
||||
data = DU().downloadUrl(url,
|
||||
authenticate=False,
|
||||
|
@ -1196,12 +1196,12 @@ class API():
|
|||
languages.append(stream.attrib['language'])
|
||||
languages = ', '.join(languages)
|
||||
if filename:
|
||||
option = tryEncode(filename)
|
||||
option = try_encode(filename)
|
||||
if languages:
|
||||
if option:
|
||||
option = '%s (%s): ' % (option, tryEncode(languages))
|
||||
option = '%s (%s): ' % (option, try_encode(languages))
|
||||
else:
|
||||
option = '%s: ' % tryEncode(languages)
|
||||
option = '%s: ' % try_encode(languages)
|
||||
if 'videoResolution' in entry.attrib:
|
||||
option = '%s%sp ' % (option,
|
||||
entry.attrib.get('videoResolution'))
|
||||
|
@ -1544,7 +1544,7 @@ class API():
|
|||
# exist() needs a / or \ at the end to work for directories
|
||||
if folder is False:
|
||||
# files
|
||||
check = exists(tryEncode(path))
|
||||
check = exists(try_encode(path))
|
||||
else:
|
||||
# directories
|
||||
if "\\" in path:
|
||||
|
@ -1640,7 +1640,7 @@ class API():
|
|||
plexitem = "plex_%s" % playurl
|
||||
window('%s.runtime' % plexitem, value=str(userdata['Runtime']))
|
||||
window('%s.type' % plexitem, value=itemtype)
|
||||
state.PLEX_IDS[tryDecode(playurl)] = self.getRatingKey()
|
||||
state.PLEX_IDS[try_decode(playurl)] = self.getRatingKey()
|
||||
# window('%s.itemid' % plexitem, value=self.getRatingKey())
|
||||
window('%s.playcount' % plexitem, value=str(userdata['PlayCount']))
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ from threading import Thread
|
|||
from xbmc import sleep
|
||||
|
||||
from downloadutils import DownloadUtils as DU
|
||||
from utils import settings, tryEncode, tryDecode
|
||||
from utils import settings, try_encode, try_decode
|
||||
from variables import PLEX_TO_KODI_TIMEFACTOR
|
||||
import plex_tv
|
||||
|
||||
|
@ -306,11 +306,11 @@ def _plex_gdm():
|
|||
}
|
||||
for line in response['data'].split('\n'):
|
||||
if 'Content-Type:' in line:
|
||||
pms['product'] = tryDecode(line.split(':')[1].strip())
|
||||
pms['product'] = try_decode(line.split(':')[1].strip())
|
||||
elif 'Host:' in line:
|
||||
pms['baseURL'] = line.split(':')[1].strip()
|
||||
elif 'Name:' in line:
|
||||
pms['name'] = tryDecode(line.split(':')[1].strip())
|
||||
pms['name'] = try_decode(line.split(':')[1].strip())
|
||||
elif 'Port:' in line:
|
||||
pms['port'] = line.split(':')[1].strip()
|
||||
elif 'Resource-Identifier:' in line:
|
||||
|
@ -820,7 +820,7 @@ def transcode_image_path(key, AuthToken, path, width, height):
|
|||
path = 'http://127.0.0.1:32400' + key
|
||||
else: # internal path, add-on
|
||||
path = 'http://127.0.0.1:32400' + path + '/' + key
|
||||
path = tryEncode(path)
|
||||
path = try_encode(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...
|
||||
|
|
|
@ -12,8 +12,8 @@ import requests
|
|||
from xbmc import sleep, translatePath
|
||||
from xbmcvfs import exists
|
||||
|
||||
from utils import window, settings, language as lang, kodiSQL, tryEncode, \
|
||||
thread_methods, dialog, exists_dir, tryDecode
|
||||
from utils import window, settings, language as lang, kodi_sql, try_encode, \
|
||||
thread_methods, dialog, exists_dir, try_decode
|
||||
import state
|
||||
|
||||
# Disable annoying requests warnings
|
||||
|
@ -134,13 +134,13 @@ 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/"))
|
||||
path = try_decode(translatePath("special://thumbnails/"))
|
||||
if exists_dir(path):
|
||||
rmtree(path, ignore_errors=True)
|
||||
self.restoreCacheDirectories()
|
||||
|
||||
# remove all existing data from texture DB
|
||||
connection = kodiSQL('texture')
|
||||
connection = kodi_sql('texture')
|
||||
cursor = connection.cursor()
|
||||
query = 'SELECT tbl_name FROM sqlite_master WHERE type=?'
|
||||
cursor.execute(query, ('table', ))
|
||||
|
@ -153,7 +153,7 @@ class Artwork():
|
|||
connection.close()
|
||||
|
||||
# Cache all entries in video DB
|
||||
connection = kodiSQL('video')
|
||||
connection = kodi_sql('video')
|
||||
cursor = connection.cursor()
|
||||
# dont include actors
|
||||
query = "SELECT url FROM art WHERE media_type != ?"
|
||||
|
@ -166,7 +166,7 @@ class Artwork():
|
|||
for url in result:
|
||||
self.cacheTexture(url[0])
|
||||
# Cache all entries in music DB
|
||||
connection = kodiSQL('music')
|
||||
connection = kodi_sql('music')
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("SELECT url FROM art")
|
||||
result = cursor.fetchall()
|
||||
|
@ -179,7 +179,7 @@ class Artwork():
|
|||
def cacheTexture(self, url):
|
||||
# Cache a single image url to the texture cache
|
||||
if url and self.enableTextureCache:
|
||||
self.queue.put(double_urlencode(tryEncode(url)))
|
||||
self.queue.put(double_urlencode(try_encode(url)))
|
||||
|
||||
def addArtwork(self, artwork, kodiId, mediaType, cursor):
|
||||
# Kodi conversion table
|
||||
|
@ -323,7 +323,7 @@ class Artwork():
|
|||
|
||||
def deleteCachedArtwork(self, url):
|
||||
# Only necessary to remove and apply a new backdrop or poster
|
||||
connection = kodiSQL('texture')
|
||||
connection = kodi_sql('texture')
|
||||
cursor = connection.cursor()
|
||||
try:
|
||||
cursor.execute("SELECT cachedurl FROM texture WHERE url = ?",
|
||||
|
@ -336,7 +336,7 @@ class Artwork():
|
|||
path = translatePath("special://thumbnails/%s" % cachedurl)
|
||||
LOG.debug("Deleting cached thumbnail: %s" % path)
|
||||
if exists(path):
|
||||
rmtree(tryDecode(path), ignore_errors=True)
|
||||
rmtree(try_decode(path), ignore_errors=True)
|
||||
cursor.execute("DELETE FROM texture WHERE url = ?", (url,))
|
||||
connection.commit()
|
||||
finally:
|
||||
|
@ -347,4 +347,4 @@ class Artwork():
|
|||
LOG.info("Restoring cache directories...")
|
||||
paths = ("","0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","Video","plex")
|
||||
for p in paths:
|
||||
makedirs(tryDecode(translatePath("special://thumbnails/%s" % p)))
|
||||
makedirs(try_decode(translatePath("special://thumbnails/%s" % p)))
|
||||
|
|
|
@ -11,8 +11,8 @@ import xbmcplugin
|
|||
from xbmc import sleep, executebuiltin, translatePath
|
||||
from xbmcgui import ListItem
|
||||
|
||||
from utils import window, settings, language as lang, dialog, tryEncode, \
|
||||
CatchExceptions, exists_dir, plex_command, tryDecode
|
||||
from utils import window, settings, language as lang, dialog, try_encode, \
|
||||
CatchExceptions, exists_dir, plex_command, try_decode
|
||||
import downloadutils
|
||||
|
||||
from PlexFunctions import GetPlexMetadata, GetPlexSectionResults, \
|
||||
|
@ -53,11 +53,11 @@ def chooseServer():
|
|||
if not __LogOut():
|
||||
return
|
||||
|
||||
from utils import deletePlaylists, deleteNodes
|
||||
from utils import delete_playlists, delete_nodes
|
||||
# First remove playlists
|
||||
deletePlaylists()
|
||||
delete_playlists()
|
||||
# Remove video nodes
|
||||
deleteNodes()
|
||||
delete_nodes()
|
||||
|
||||
# Log in again
|
||||
__LogIn()
|
||||
|
@ -175,10 +175,10 @@ def switchPlexUser():
|
|||
return
|
||||
|
||||
# First remove playlists of old user
|
||||
from utils import deletePlaylists, deleteNodes
|
||||
deletePlaylists()
|
||||
from utils import delete_playlists, delete_nodes
|
||||
delete_playlists()
|
||||
# Remove video nodes
|
||||
deleteNodes()
|
||||
delete_nodes()
|
||||
__LogIn()
|
||||
|
||||
|
||||
|
@ -455,14 +455,14 @@ def getVideoFiles(plexId, params):
|
|||
if exists_dir(path):
|
||||
for root, dirs, files in walk(path):
|
||||
for directory in dirs:
|
||||
item_path = tryEncode(join(root, directory))
|
||||
item_path = try_encode(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 = tryEncode(join(root, file))
|
||||
item_path = try_encode(join(root, file))
|
||||
li = ListItem(item_path, path=item_path)
|
||||
xbmcplugin.addDirectoryItem(handle=HANDLE,
|
||||
url=file,
|
||||
|
@ -490,7 +490,7 @@ 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(
|
||||
fanartDir = try_decode(translatePath(
|
||||
"special://thumbnails/plex/%s/" % plexid))
|
||||
if not exists_dir(fanartDir):
|
||||
# Download the images to the cache directory
|
||||
|
@ -504,19 +504,19 @@ def getExtraFanArt(plexid, plexPath):
|
|||
backdrops = api.getAllArtwork()['Backdrop']
|
||||
for count, backdrop in enumerate(backdrops):
|
||||
# Same ordering as in artwork
|
||||
fanartFile = tryEncode(join(fanartDir, "fanart%.3d.jpg" % count))
|
||||
fanartFile = try_encode(join(fanartDir, "fanart%.3d.jpg" % count))
|
||||
li = ListItem("%.3d" % count, path=fanartFile)
|
||||
xbmcplugin.addDirectoryItem(
|
||||
handle=HANDLE,
|
||||
url=fanartFile,
|
||||
listitem=li)
|
||||
copyfile(backdrop, tryDecode(fanartFile))
|
||||
copyfile(backdrop, try_decode(fanartFile))
|
||||
else:
|
||||
log.info("Found cached backdrop.")
|
||||
# Use existing cached images
|
||||
for root, dirs, files in walk(fanartDir):
|
||||
for file in files:
|
||||
fanartFile = tryEncode(join(root, file))
|
||||
fanartFile = try_encode(join(root, file))
|
||||
li = ListItem(file, path=fanartFile)
|
||||
xbmcplugin.addDirectoryItem(handle=HANDLE,
|
||||
url=fanartFile,
|
||||
|
|
|
@ -6,7 +6,7 @@ import xml.etree.ElementTree as etree
|
|||
|
||||
from xbmc import executebuiltin, translatePath
|
||||
|
||||
from utils import settings, window, language as lang, tryEncode, tryDecode, \
|
||||
from utils import settings, window, language as lang, try_encode, try_decode, \
|
||||
XmlKodiSetting, reboot_kodi, dialog
|
||||
from migration import check_migration
|
||||
from downloadutils import DownloadUtils as DU
|
||||
|
@ -76,7 +76,7 @@ def reload_pkc():
|
|||
set_webserver()
|
||||
# To detect Kodi profile switches
|
||||
window('plex_kodiProfile',
|
||||
value=tryDecode(translatePath("special://profile")))
|
||||
value=try_decode(translatePath("special://profile")))
|
||||
getDeviceId()
|
||||
# Initialize the PKC playqueues
|
||||
PQ.init_playqueues()
|
||||
|
@ -355,7 +355,7 @@ class InitialSetup(object):
|
|||
dialog('ok',
|
||||
lang(29999),
|
||||
'%s %s' % (lang(39214),
|
||||
tryEncode(server['name'])))
|
||||
try_encode(server['name'])))
|
||||
return
|
||||
else:
|
||||
return
|
||||
|
@ -610,8 +610,8 @@ class InitialSetup(object):
|
|||
line1=lang(39029),
|
||||
line2=lang(39030)):
|
||||
LOG.debug("Presenting network credentials dialog.")
|
||||
from utils import passwordsXML
|
||||
passwordsXML()
|
||||
from utils import passwords_xml
|
||||
passwords_xml()
|
||||
# Disable Plex music?
|
||||
if dialog('yesno', heading=lang(29999), line1=lang(39016)):
|
||||
LOG.debug("User opted to disable Plex music library.")
|
||||
|
|
|
@ -6,7 +6,7 @@ from ntpath import dirname
|
|||
from datetime import datetime
|
||||
|
||||
from artwork import Artwork
|
||||
from utils import window, kodiSQL, CatchExceptions
|
||||
from utils import window, kodi_sql, CatchExceptions
|
||||
import plexdb_functions as plexdb
|
||||
import kodidb_functions as kodidb
|
||||
|
||||
|
@ -43,9 +43,9 @@ class Items(object):
|
|||
"""
|
||||
Open DB connections and cursors
|
||||
"""
|
||||
self.plexconn = kodiSQL('plex')
|
||||
self.plexconn = kodi_sql('plex')
|
||||
self.plexcursor = self.plexconn.cursor()
|
||||
self.kodiconn = kodiSQL('video')
|
||||
self.kodiconn = kodi_sql('video')
|
||||
self.kodicursor = self.kodiconn.cursor()
|
||||
self.plex_db = plexdb.Plex_DB_Functions(self.plexcursor)
|
||||
self.kodi_db = kodidb.Kodidb_Functions(self.kodicursor)
|
||||
|
@ -1273,10 +1273,10 @@ class Music(Items):
|
|||
OVERWRITE this method, because we need to open another DB.
|
||||
Open DB connections and cursors
|
||||
"""
|
||||
self.plexconn = kodiSQL('plex')
|
||||
self.plexconn = kodi_sql('plex')
|
||||
self.plexcursor = self.plexconn.cursor()
|
||||
# Here it is, not 'video' but 'music'
|
||||
self.kodiconn = kodiSQL('music')
|
||||
self.kodiconn = kodi_sql('music')
|
||||
self.kodicursor = self.kodiconn.cursor()
|
||||
self.plex_db = plexdb.Plex_DB_Functions(self.plexcursor)
|
||||
self.kodi_db = kodidb.Kodidb_Functions(self.kodicursor)
|
||||
|
|
|
@ -5,7 +5,7 @@ from logging import getLogger
|
|||
from ntpath import dirname
|
||||
|
||||
import artwork
|
||||
from utils import kodiSQL
|
||||
from utils import kodi_sql
|
||||
import variables as v
|
||||
|
||||
###############################################################################
|
||||
|
@ -30,7 +30,7 @@ class GetKodiDB():
|
|||
self.db_type = db_type
|
||||
|
||||
def __enter__(self):
|
||||
self.kodiconn = kodiSQL(self.db_type)
|
||||
self.kodiconn = kodi_sql(self.db_type)
|
||||
kodi_db = Kodidb_Functions(self.kodiconn.cursor())
|
||||
return kodi_db
|
||||
|
||||
|
|
|
@ -8,10 +8,10 @@ from random import shuffle
|
|||
import xbmc
|
||||
from xbmcvfs import exists
|
||||
|
||||
from utils import window, settings, getUnixTimestamp, \
|
||||
thread_methods, create_actor_db_index, dialog, LogTime, playlistXSP,\
|
||||
language as lang, DateToKodi, reset, tryDecode, deletePlaylists, \
|
||||
deleteNodes, tryEncode, compare_version
|
||||
from utils import window, settings, unix_timestamp, thread_methods, \
|
||||
create_actor_db_index, dialog, LogTime, playlist_xsp, language as lang, \
|
||||
unix_date_to_kodi, reset, try_decode, delete_playlists, delete_nodes, \
|
||||
try_encode, compare_version
|
||||
import downloadutils
|
||||
import itemtypes
|
||||
import plexdb_functions as plexdb
|
||||
|
@ -155,7 +155,7 @@ class LibrarySync(Thread):
|
|||
log.debug('No timestamp; using 0')
|
||||
|
||||
# Set the timer
|
||||
koditime = getUnixTimestamp()
|
||||
koditime = unix_timestamp()
|
||||
# Toggle watched state
|
||||
scrobble(plexId, 'watched')
|
||||
# Let the PMS process this first!
|
||||
|
@ -329,7 +329,7 @@ class LibrarySync(Thread):
|
|||
# Create playlist for the video library
|
||||
if (foldername not in playlists and
|
||||
mediatype in (v.PLEX_TYPE_MOVIE, v.PLEX_TYPE_SHOW)):
|
||||
playlistXSP(mediatype, foldername, folderid, viewtype)
|
||||
playlist_xsp(mediatype, foldername, folderid, viewtype)
|
||||
playlists.append(foldername)
|
||||
# Create the video node
|
||||
if (foldername not in nodes and
|
||||
|
@ -371,7 +371,7 @@ class LibrarySync(Thread):
|
|||
# The tag could be a combined view. Ensure there's
|
||||
# no other tags with the same name before deleting
|
||||
# playlist.
|
||||
playlistXSP(mediatype,
|
||||
playlist_xsp(mediatype,
|
||||
current_viewname,
|
||||
folderid,
|
||||
current_viewtype,
|
||||
|
@ -388,7 +388,7 @@ class LibrarySync(Thread):
|
|||
# Added new playlist
|
||||
if (foldername not in playlists and mediatype in
|
||||
(v.PLEX_TYPE_MOVIE, v.PLEX_TYPE_SHOW)):
|
||||
playlistXSP(mediatype,
|
||||
playlist_xsp(mediatype,
|
||||
foldername,
|
||||
folderid,
|
||||
viewtype)
|
||||
|
@ -414,7 +414,7 @@ class LibrarySync(Thread):
|
|||
if mediatype != v.PLEX_TYPE_ARTIST:
|
||||
if (foldername not in playlists and mediatype in
|
||||
(v.PLEX_TYPE_MOVIE, v.PLEX_TYPE_SHOW)):
|
||||
playlistXSP(mediatype,
|
||||
playlist_xsp(mediatype,
|
||||
foldername,
|
||||
folderid,
|
||||
viewtype)
|
||||
|
@ -1102,7 +1102,7 @@ class LibrarySync(Thread):
|
|||
"""
|
||||
self.videoLibUpdate = False
|
||||
self.musicLibUpdate = False
|
||||
now = getUnixTimestamp()
|
||||
now = unix_timestamp()
|
||||
deleteListe = []
|
||||
for i, item in enumerate(self.itemsToProcess):
|
||||
if self.thread_stopped() or self.thread_suspended():
|
||||
|
@ -1220,7 +1220,7 @@ class LibrarySync(Thread):
|
|||
'state': status,
|
||||
'type': typus,
|
||||
'ratingKey': str(item['itemID']),
|
||||
'timestamp': getUnixTimestamp(),
|
||||
'timestamp': unix_timestamp(),
|
||||
'attempt': 0
|
||||
})
|
||||
elif typus in (v.PLEX_TYPE_MOVIE,
|
||||
|
@ -1237,7 +1237,7 @@ class LibrarySync(Thread):
|
|||
'state': status,
|
||||
'type': typus,
|
||||
'ratingKey': plex_id,
|
||||
'timestamp': getUnixTimestamp(),
|
||||
'timestamp': unix_timestamp(),
|
||||
'attempt': 0
|
||||
})
|
||||
|
||||
|
@ -1276,7 +1276,7 @@ class LibrarySync(Thread):
|
|||
'state': None, # Don't need a state here
|
||||
'type': kodi_info[5],
|
||||
'ratingKey': plex_id,
|
||||
'timestamp': getUnixTimestamp(),
|
||||
'timestamp': unix_timestamp(),
|
||||
'attempt': 0
|
||||
})
|
||||
|
||||
|
@ -1386,7 +1386,7 @@ class LibrarySync(Thread):
|
|||
resume,
|
||||
session['duration'],
|
||||
session['file_id'],
|
||||
DateToKodi(getUnixTimestamp()))
|
||||
unix_date_to_kodi(unix_timestamp()))
|
||||
|
||||
def fanartSync(self, refresh=False):
|
||||
"""
|
||||
|
@ -1430,9 +1430,9 @@ class LibrarySync(Thread):
|
|||
window('plex_dbScan', value="true")
|
||||
state.DB_SCAN = True
|
||||
# First remove playlists
|
||||
deletePlaylists()
|
||||
delete_playlists()
|
||||
# Remove video nodes
|
||||
deleteNodes()
|
||||
delete_nodes()
|
||||
# Kick off refresh
|
||||
if self.maintainViews() is True:
|
||||
# Ran successfully
|
||||
|
@ -1549,11 +1549,11 @@ class LibrarySync(Thread):
|
|||
# Also runs when first installed
|
||||
# Verify the video database can be found
|
||||
videoDb = v.DB_VIDEO_PATH
|
||||
if not exists(tryEncode(videoDb)):
|
||||
if not exists(try_encode(videoDb)):
|
||||
# Database does not exists
|
||||
log.error("The current Kodi version is incompatible "
|
||||
"to know which Kodi versions are supported.")
|
||||
log.error('Current Kodi version: %s' % tryDecode(
|
||||
log.error('Current Kodi version: %s' % try_decode(
|
||||
xbmc.getInfoLabel('System.BuildVersion')))
|
||||
# "Current Kodi version is unsupported, cancel lib sync"
|
||||
dialog('ok', heading='{plex}', line1=lang(39403))
|
||||
|
@ -1562,10 +1562,10 @@ class LibrarySync(Thread):
|
|||
state.DB_SCAN = True
|
||||
window('plex_dbScan', value="true")
|
||||
log.info("Db version: %s" % settings('dbCreatedWithVersion'))
|
||||
lastTimeSync = getUnixTimestamp()
|
||||
lastTimeSync = unix_timestamp()
|
||||
# Initialize time offset Kodi - PMS
|
||||
self.syncPMStime()
|
||||
lastSync = getUnixTimestamp()
|
||||
lastSync = unix_timestamp()
|
||||
if settings('FanartTV') == 'true':
|
||||
# Start getting additional missing artwork
|
||||
with plexdb.Get_Plex_DB() as plex_db:
|
||||
|
@ -1579,8 +1579,8 @@ class LibrarySync(Thread):
|
|||
'refresh': True
|
||||
})
|
||||
log.info('Refreshing video nodes and playlists now')
|
||||
deletePlaylists()
|
||||
deleteNodes()
|
||||
delete_playlists()
|
||||
delete_nodes()
|
||||
log.info("Initial start-up full sync starting")
|
||||
librarySync = fullSync()
|
||||
window('plex_dbScan', clear=True)
|
||||
|
@ -1604,7 +1604,7 @@ class LibrarySync(Thread):
|
|||
self.triage_lib_scans()
|
||||
self.force_dialog = False
|
||||
continue
|
||||
now = getUnixTimestamp()
|
||||
now = unix_timestamp()
|
||||
# Standard syncs - don't force-show dialogs
|
||||
self.force_dialog = False
|
||||
if (now - lastSync > FULL_SYNC_INTERVALL and
|
||||
|
|
|
@ -12,7 +12,7 @@ LEVELS = {
|
|||
###############################################################################
|
||||
|
||||
|
||||
def tryEncode(uniString, encoding='utf-8'):
|
||||
def try_encode(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
|
||||
|
@ -43,5 +43,5 @@ class LogHandler(logging.StreamHandler):
|
|||
try:
|
||||
xbmc.log(self.format(record), level=LEVELS[record.levelno])
|
||||
except UnicodeEncodeError:
|
||||
xbmc.log(tryEncode(self.format(record)),
|
||||
xbmc.log(try_encode(self.format(record)),
|
||||
level=LEVELS[record.levelno])
|
||||
|
|
|
@ -18,7 +18,7 @@ from playutils import PlayUtils
|
|||
from PKC_listitem import PKC_ListItem
|
||||
from pickler import pickle_me, Playback_Successful
|
||||
import json_rpc as js
|
||||
from utils import settings, dialog, language as lang, tryEncode
|
||||
from utils import settings, dialog, language as lang, try_encode
|
||||
from plexbmchelper.subscribers import LOCKER
|
||||
import variables as v
|
||||
import state
|
||||
|
@ -167,7 +167,7 @@ def _prep_playlist_stack(xml):
|
|||
path = ('plugin://plugin.video.plexkodiconnect?%s'
|
||||
% urlencode(params))
|
||||
listitem = api.CreateListItemFromPlexItem()
|
||||
listitem.setPath(tryEncode(path))
|
||||
listitem.setPath(try_encode(path))
|
||||
else:
|
||||
# Will add directly via the Kodi DB
|
||||
path = None
|
||||
|
@ -244,7 +244,7 @@ def conclude_playback(playqueue, pos):
|
|||
playurl = playutils.getPlayUrl()
|
||||
else:
|
||||
playurl = item.file
|
||||
listitem.setPath(tryEncode(playurl))
|
||||
listitem.setPath(try_encode(playurl))
|
||||
if item.playmethod in ('DirectStream', 'DirectPlay'):
|
||||
listitem.setSubtitles(api.externalSubs())
|
||||
else:
|
||||
|
@ -322,14 +322,14 @@ def process_indirect(key, offset, resolve=True):
|
|||
return
|
||||
playurl = xml[0].attrib['key']
|
||||
item.file = playurl
|
||||
listitem.setPath(tryEncode(playurl))
|
||||
listitem.setPath(try_encode(playurl))
|
||||
playqueue.items.append(item)
|
||||
if resolve is True:
|
||||
result.listitem = listitem
|
||||
pickle_me(result)
|
||||
else:
|
||||
thread = Thread(target=Player().play,
|
||||
args={'item': tryEncode(playurl),
|
||||
args={'item': try_encode(playurl),
|
||||
'listitem': listitem})
|
||||
thread.setDaemon(True)
|
||||
LOG.info('Done initializing PKC playback, starting Kodi player')
|
||||
|
|
|
@ -8,7 +8,7 @@ from re import compile as re_compile
|
|||
|
||||
import plexdb_functions as plexdb
|
||||
from downloadutils import DownloadUtils as DU
|
||||
from utils import tryEncode, escape_html
|
||||
from utils import try_encode, escape_html
|
||||
from PlexAPI import API
|
||||
from PlexFunctions import GetPlexMetadata
|
||||
import json_rpc as js
|
||||
|
@ -60,7 +60,7 @@ class PlaylistObjectBaseclase(object):
|
|||
continue
|
||||
if isinstance(getattr(self, key), (str, unicode)):
|
||||
answ += '\'%s\': \'%s\', ' % (key,
|
||||
tryEncode(getattr(self, key)))
|
||||
try_encode(getattr(self, key)))
|
||||
else:
|
||||
# e.g. int
|
||||
answ += '\'%s\': %s, ' % (key, str(getattr(self, key)))
|
||||
|
@ -168,7 +168,7 @@ class Playlist_Item(object):
|
|||
continue
|
||||
if isinstance(getattr(self, key), (str, unicode)):
|
||||
answ += '\'%s\': \'%s\', ' % (key,
|
||||
tryEncode(getattr(self, key)))
|
||||
try_encode(getattr(self, key)))
|
||||
else:
|
||||
# e.g. int
|
||||
answ += '\'%s\': %s, ' % (key, str(getattr(self, key)))
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
from logging import getLogger
|
||||
from downloadutils import DownloadUtils as DU
|
||||
|
||||
from utils import window, settings, language as lang, dialog, tryEncode
|
||||
from utils import window, settings, language as lang, dialog, try_encode
|
||||
import variables as v
|
||||
|
||||
###############################################################################
|
||||
|
@ -274,7 +274,7 @@ class PlayUtils():
|
|||
codec,
|
||||
channellayout)
|
||||
audio_streams_list.append(index)
|
||||
audio_streams.append(tryEncode(track))
|
||||
audio_streams.append(try_encode(track))
|
||||
audio_numb += 1
|
||||
|
||||
# Subtitles
|
||||
|
@ -306,7 +306,7 @@ class PlayUtils():
|
|||
"%s%s" % (window('pms_server'),
|
||||
stream.attrib['key']))
|
||||
downloadable_streams.append(index)
|
||||
download_subs.append(tryEncode(path))
|
||||
download_subs.append(try_encode(path))
|
||||
else:
|
||||
track = "%s (%s)" % (track, lang(39710)) # burn-in
|
||||
if stream.attrib.get('selected') == '1' and downloadable:
|
||||
|
@ -315,7 +315,7 @@ class PlayUtils():
|
|||
default_sub = index
|
||||
|
||||
subtitle_streams_list.append(index)
|
||||
subtitle_streams.append(tryEncode(track))
|
||||
subtitle_streams.append(try_encode(track))
|
||||
sub_num += 1
|
||||
|
||||
if audio_numb > 1:
|
||||
|
|
|
@ -4,7 +4,7 @@ from logging import getLogger
|
|||
from xbmc import sleep, executebuiltin
|
||||
|
||||
from downloadutils import DownloadUtils as DU
|
||||
from utils import dialog, language as lang, settings, tryEncode
|
||||
from utils import dialog, language as lang, settings, try_encode
|
||||
import variables as v
|
||||
import state
|
||||
|
||||
|
@ -39,7 +39,7 @@ def choose_home_user(token):
|
|||
username = user['title']
|
||||
userlist.append(username)
|
||||
# To take care of non-ASCII usernames
|
||||
userlist_coded.append(tryEncode(username))
|
||||
userlist_coded.append(try_encode(username))
|
||||
usernumber = len(userlist)
|
||||
username = ''
|
||||
usertoken = ''
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
###############################################################################
|
||||
from logging import getLogger
|
||||
|
||||
from utils import kodiSQL
|
||||
from utils import kodi_sql
|
||||
import variables as v
|
||||
|
||||
###############################################################################
|
||||
|
@ -22,7 +22,7 @@ class Get_Plex_DB():
|
|||
and the db gets closed
|
||||
"""
|
||||
def __enter__(self):
|
||||
self.plexconn = kodiSQL('plex')
|
||||
self.plexconn = kodi_sql('plex')
|
||||
return Plex_DB_Functions(self.plexconn.cursor())
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Various functions and decorators for PKC
|
||||
"""
|
||||
###############################################################################
|
||||
from logging import getLogger
|
||||
from cProfile import Profile
|
||||
|
@ -7,7 +9,7 @@ from pstats import Stats
|
|||
from sqlite3 import connect, OperationalError
|
||||
from datetime import datetime, timedelta
|
||||
from StringIO import StringIO
|
||||
from time import localtime, strftime, strptime
|
||||
from time import localtime, strftime
|
||||
from unicodedata import normalize
|
||||
import xml.etree.ElementTree as etree
|
||||
from functools import wraps, partial
|
||||
|
@ -21,12 +23,13 @@ import xbmc
|
|||
import xbmcaddon
|
||||
import xbmcgui
|
||||
from xbmcvfs import exists, delete
|
||||
|
||||
import variables as v
|
||||
import state
|
||||
|
||||
###############################################################################
|
||||
|
||||
log = getLogger("PLEX."+__name__)
|
||||
LOG = getLogger("PLEX." + __name__)
|
||||
|
||||
WINDOW = xbmcgui.Window(10000)
|
||||
ADDON = xbmcaddon.Addon(id='plugin.video.plexkodiconnect')
|
||||
|
@ -46,7 +49,8 @@ def reboot_kodi(message=None):
|
|||
dialog('ok', heading='{plex}', line1=message)
|
||||
xbmc.executebuiltin('RestartApp')
|
||||
|
||||
def window(property, value=None, clear=False, windowid=10000):
|
||||
|
||||
def window(prop, value=None, clear=False, windowid=10000):
|
||||
"""
|
||||
Get or set window property - thread safe!
|
||||
|
||||
|
@ -60,11 +64,11 @@ def window(property, value=None, clear=False, windowid=10000):
|
|||
win = WINDOW
|
||||
|
||||
if clear:
|
||||
win.clearProperty(property)
|
||||
win.clearProperty(prop)
|
||||
elif value is not None:
|
||||
win.setProperty(tryEncode(property), tryEncode(value))
|
||||
win.setProperty(try_encode(prop), try_encode(value))
|
||||
else:
|
||||
return tryDecode(win.getProperty(property))
|
||||
return try_decode(win.getProperty(prop))
|
||||
|
||||
|
||||
def plex_command(key, value):
|
||||
|
@ -90,10 +94,10 @@ def settings(setting, value=None):
|
|||
addon = xbmcaddon.Addon(id='plugin.video.plexkodiconnect')
|
||||
if value is not None:
|
||||
# Takes string or unicode by default!
|
||||
addon.setSetting(tryEncode(setting), tryEncode(value))
|
||||
addon.setSetting(try_encode(setting), try_encode(value))
|
||||
else:
|
||||
# Should return unicode by default, but just in case
|
||||
return tryDecode(addon.getSetting(setting))
|
||||
return try_decode(addon.getSetting(setting))
|
||||
|
||||
|
||||
def exists_dir(path):
|
||||
|
@ -104,24 +108,26 @@ def exists_dir(path):
|
|||
Feed with encoded string or unicode
|
||||
"""
|
||||
if v.KODIVERSION >= 17:
|
||||
answ = exists(tryEncode(path))
|
||||
answ = exists(try_encode(path))
|
||||
else:
|
||||
dummyfile = join(tryDecode(path), 'dummyfile.txt')
|
||||
dummyfile = join(try_decode(path), 'dummyfile.txt')
|
||||
try:
|
||||
with open(dummyfile, 'w') as f:
|
||||
f.write('text')
|
||||
with open(dummyfile, 'w') as filer:
|
||||
filer.write('text')
|
||||
except IOError:
|
||||
# folder does not exist yet
|
||||
answ = 0
|
||||
else:
|
||||
# Folder exists. Delete file again.
|
||||
delete(tryEncode(dummyfile))
|
||||
delete(try_encode(dummyfile))
|
||||
answ = 1
|
||||
return answ
|
||||
|
||||
|
||||
def language(stringid):
|
||||
# Central string retrieval
|
||||
"""
|
||||
Central string retrieval from strings.po
|
||||
"""
|
||||
return ADDON.getLocalizedString(stringid)
|
||||
|
||||
|
||||
|
@ -236,7 +242,7 @@ def kodi_time_to_millis(time):
|
|||
return ret
|
||||
|
||||
|
||||
def tryEncode(uniString, encoding='utf-8'):
|
||||
def try_encode(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
|
||||
|
@ -252,7 +258,7 @@ def tryEncode(uniString, encoding='utf-8'):
|
|||
return uniString
|
||||
|
||||
|
||||
def tryDecode(string, encoding='utf-8'):
|
||||
def try_decode(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
|
||||
|
@ -295,7 +301,7 @@ def escape_html(string):
|
|||
return string
|
||||
|
||||
|
||||
def DateToKodi(stamp):
|
||||
def unix_date_to_kodi(stamp):
|
||||
"""
|
||||
converts a Unix time stamp (seconds passed sinceJanuary 1 1970) to a
|
||||
propper, human-readable time stamp used by Kodi
|
||||
|
@ -313,49 +319,42 @@ def DateToKodi(stamp):
|
|||
return localdate
|
||||
|
||||
|
||||
def IntFromStr(string):
|
||||
"""
|
||||
Returns an int from string or the int 0 if something happened
|
||||
"""
|
||||
try:
|
||||
result = int(string)
|
||||
except:
|
||||
result = 0
|
||||
return result
|
||||
|
||||
|
||||
def getUnixTimestamp(secondsIntoTheFuture=None):
|
||||
def unix_timestamp(seconds_into_the_future=None):
|
||||
"""
|
||||
Returns a Unix time stamp (seconds passed since January 1 1970) for NOW as
|
||||
an integer.
|
||||
|
||||
Optionally, pass secondsIntoTheFuture: positive int's will result in a
|
||||
Optionally, pass seconds_into_the_future: positive int's will result in a
|
||||
future timestamp, negative the past
|
||||
"""
|
||||
if secondsIntoTheFuture:
|
||||
future = datetime.utcnow() + timedelta(seconds=secondsIntoTheFuture)
|
||||
if seconds_into_the_future:
|
||||
future = datetime.utcnow() + timedelta(seconds=seconds_into_the_future)
|
||||
else:
|
||||
future = datetime.utcnow()
|
||||
return timegm(future.timetuple())
|
||||
|
||||
|
||||
def kodiSQL(media_type="video"):
|
||||
def kodi_sql(media_type=None):
|
||||
"""
|
||||
Open a connection to the Kodi database.
|
||||
media_type: 'video' (standard if not passed), 'plex', 'music', 'texture'
|
||||
"""
|
||||
if media_type == "plex":
|
||||
dbPath = v.DB_PLEX_PATH
|
||||
db_path = v.DB_PLEX_PATH
|
||||
elif media_type == "music":
|
||||
dbPath = v.DB_MUSIC_PATH
|
||||
db_path = v.DB_MUSIC_PATH
|
||||
elif media_type == "texture":
|
||||
dbPath = v.DB_TEXTURE_PATH
|
||||
db_path = v.DB_TEXTURE_PATH
|
||||
else:
|
||||
dbPath = v.DB_VIDEO_PATH
|
||||
return connect(dbPath, timeout=60.0)
|
||||
db_path = v.DB_VIDEO_PATH
|
||||
return connect(db_path, timeout=60.0)
|
||||
|
||||
|
||||
def create_actor_db_index():
|
||||
"""
|
||||
Index the "actors" because we got a TON - speed up SELECT and WHEN
|
||||
"""
|
||||
conn = kodiSQL('video')
|
||||
conn = kodi_sql('video')
|
||||
cursor = conn.cursor()
|
||||
try:
|
||||
cursor.execute("""
|
||||
|
@ -370,6 +369,10 @@ def create_actor_db_index():
|
|||
|
||||
|
||||
def reset():
|
||||
"""
|
||||
User navigated to the PKC settings, Advanced, and wants to reset the Kodi
|
||||
database and possibly PKC entirely
|
||||
"""
|
||||
# Are you sure you want to reset your local Kodi database?
|
||||
if not dialog('yesno',
|
||||
heading='{plex} %s ' % language(30132),
|
||||
|
@ -380,7 +383,7 @@ def reset():
|
|||
plex_command('STOP_SYNC', 'True')
|
||||
count = 10
|
||||
while window('plex_dbScan') == "true":
|
||||
log.debug("Sync is running, will retry: %s..." % count)
|
||||
LOG.debug("Sync is running, will retry: %s...", count)
|
||||
count -= 1
|
||||
if count == 0:
|
||||
# Could not stop the database from running. Please try again later.
|
||||
|
@ -391,14 +394,14 @@ def reset():
|
|||
xbmc.sleep(1000)
|
||||
|
||||
# Clean up the playlists
|
||||
deletePlaylists()
|
||||
delete_playlists()
|
||||
|
||||
# Clean up the video nodes
|
||||
deleteNodes()
|
||||
delete_nodes()
|
||||
|
||||
# Wipe the kodi databases
|
||||
log.info("Resetting the Kodi video database.")
|
||||
connection = kodiSQL('video')
|
||||
LOG.info("Resetting the Kodi video database.")
|
||||
connection = kodi_sql('video')
|
||||
cursor = connection.cursor()
|
||||
cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"')
|
||||
rows = cursor.fetchall()
|
||||
|
@ -410,8 +413,8 @@ def reset():
|
|||
cursor.close()
|
||||
|
||||
if settings('enableMusic') == "true":
|
||||
log.info("Resetting the Kodi music database.")
|
||||
connection = kodiSQL('music')
|
||||
LOG.info("Resetting the Kodi music database.")
|
||||
connection = kodi_sql('music')
|
||||
cursor = connection.cursor()
|
||||
cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"')
|
||||
rows = cursor.fetchall()
|
||||
|
@ -423,8 +426,8 @@ def reset():
|
|||
cursor.close()
|
||||
|
||||
# Wipe the Plex database
|
||||
log.info("Resetting the Plex database.")
|
||||
connection = kodiSQL('plex')
|
||||
LOG.info("Resetting the Plex database.")
|
||||
connection = kodi_sql('plex')
|
||||
cursor = connection.cursor()
|
||||
cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"')
|
||||
rows = cursor.fetchall()
|
||||
|
@ -441,21 +444,21 @@ def reset():
|
|||
if dialog('yesno',
|
||||
heading='{plex} %s ' % language(30132),
|
||||
line1=language(39602)):
|
||||
log.info("Resetting all cached artwork.")
|
||||
LOG.info("Resetting all cached artwork.")
|
||||
# Remove all existing textures first
|
||||
path = xbmc.translatePath("special://thumbnails/")
|
||||
if exists(path):
|
||||
rmtree(tryDecode(path), ignore_errors=True)
|
||||
rmtree(try_decode(path), ignore_errors=True)
|
||||
# remove all existing data from texture DB
|
||||
connection = kodiSQL('texture')
|
||||
connection = kodi_sql('texture')
|
||||
cursor = connection.cursor()
|
||||
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 %s" % tableName)
|
||||
table_name = row[0]
|
||||
if table_name != "version":
|
||||
cursor.execute("DELETE FROM %s" % table_name)
|
||||
connection.commit()
|
||||
cursor.close()
|
||||
|
||||
|
@ -469,44 +472,36 @@ def reset():
|
|||
line1=language(39603)):
|
||||
# Delete the settings
|
||||
addon = xbmcaddon.Addon()
|
||||
addondir = tryDecode(xbmc.translatePath(addon.getAddonInfo('profile')))
|
||||
dataPath = "%ssettings.xml" % addondir
|
||||
log.info("Deleting: settings.xml")
|
||||
remove(dataPath)
|
||||
addondir = try_decode(xbmc.translatePath(addon.getAddonInfo('profile')))
|
||||
LOG.info("Deleting: settings.xml")
|
||||
remove("%ssettings.xml" % addondir)
|
||||
reboot_kodi()
|
||||
|
||||
|
||||
def profiling(sortby="cumulative"):
|
||||
# Will print results to Kodi log
|
||||
"""
|
||||
Will print results to Kodi log. Must be enabled in the Python source code
|
||||
"""
|
||||
def decorator(func):
|
||||
"""
|
||||
decorator construct
|
||||
"""
|
||||
def wrapper(*args, **kwargs):
|
||||
|
||||
pr = Profile()
|
||||
|
||||
pr.enable()
|
||||
"""
|
||||
wrapper construct
|
||||
"""
|
||||
profile = Profile()
|
||||
profile.enable()
|
||||
result = func(*args, **kwargs)
|
||||
pr.disable()
|
||||
|
||||
s = StringIO()
|
||||
ps = Stats(pr, stream=s).sort_stats(sortby)
|
||||
ps.print_stats()
|
||||
log.info(s.getvalue())
|
||||
|
||||
profile.disable()
|
||||
string_io = StringIO()
|
||||
stats = Stats(profile, stream=string_io).sort_stats(sortby)
|
||||
stats.print_stats()
|
||||
LOG.info(string_io.getvalue())
|
||||
return result
|
||||
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
def convertdate(date):
|
||||
try:
|
||||
date = datetime.strptime(date, "%Y-%m-%dT%H:%M:%SZ")
|
||||
except TypeError:
|
||||
# TypeError: attribute of type 'NoneType' is not callable
|
||||
# Known Kodi/python error
|
||||
date = datetime(*(strptime(date, "%Y-%m-%dT%H:%M:%SZ")[0:6]))
|
||||
|
||||
return date
|
||||
|
||||
|
||||
def compare_version(current, minimum):
|
||||
"""
|
||||
|
@ -515,38 +510,36 @@ def compare_version(current, minimum):
|
|||
|
||||
Input strings: e.g. "1.2.3"; always with Major, Minor and Patch!
|
||||
"""
|
||||
log.info("current DB: %s minimum DB: %s" % (current, minimum))
|
||||
LOG.info("current DB: %s minimum DB: %s", current, minimum)
|
||||
try:
|
||||
currMajor, currMinor, currPatch = current.split(".")
|
||||
curr_major, curr_minor, curr_patch = current.split(".")
|
||||
except ValueError:
|
||||
# there WAS no current DB, e.g. deleted.
|
||||
return True
|
||||
minMajor, minMinor, minPatch = minimum.split(".")
|
||||
currMajor = int(currMajor)
|
||||
currMinor = int(currMinor)
|
||||
currPatch = int(currPatch)
|
||||
minMajor = int(minMajor)
|
||||
minMinor = int(minMinor)
|
||||
minPatch = int(minPatch)
|
||||
min_major, min_minor, min_patch = minimum.split(".")
|
||||
curr_major = int(curr_major)
|
||||
curr_minor = int(curr_minor)
|
||||
curr_patch = int(curr_patch)
|
||||
min_major = int(min_major)
|
||||
min_minor = int(min_minor)
|
||||
min_patch = int(min_patch)
|
||||
|
||||
if currMajor > minMajor:
|
||||
if curr_major > min_major:
|
||||
return True
|
||||
elif currMajor < minMajor:
|
||||
elif curr_major < min_major:
|
||||
return False
|
||||
|
||||
if currMinor > minMinor:
|
||||
if curr_minor > min_minor:
|
||||
return True
|
||||
elif currMinor < minMinor:
|
||||
return False
|
||||
|
||||
if currPatch >= minPatch:
|
||||
return True
|
||||
else:
|
||||
elif curr_minor < min_minor:
|
||||
return False
|
||||
return curr_patch >= min_patch
|
||||
|
||||
|
||||
def normalize_nodes(text):
|
||||
# For video nodes
|
||||
"""
|
||||
For video nodes
|
||||
"""
|
||||
text = text.replace(":", "")
|
||||
text = text.replace("/", "-")
|
||||
text = text.replace("\\", "-")
|
||||
|
@ -561,13 +554,15 @@ 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 = tryEncode(normalize('NFKD', unicode(text, 'utf-8')))
|
||||
text = try_encode(normalize('NFKD', unicode(text, 'utf-8')))
|
||||
|
||||
return text
|
||||
|
||||
|
||||
def normalize_string(text):
|
||||
# For theme media, do not modify unless
|
||||
# modified in TV Tunes
|
||||
"""
|
||||
For theme media, do not modify unless modified in TV Tunes
|
||||
"""
|
||||
text = text.replace(":", "")
|
||||
text = text.replace("/", "-")
|
||||
text = text.replace("\\", "-")
|
||||
|
@ -580,7 +575,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 = tryEncode(normalize('NFKD', unicode(text, 'utf-8')))
|
||||
text = try_encode(normalize('NFKD', unicode(text, 'utf-8')))
|
||||
|
||||
return text
|
||||
|
||||
|
@ -595,8 +590,8 @@ def indent(elem, level=0):
|
|||
elem.text = i + " "
|
||||
if not elem.tail or not elem.tail.strip():
|
||||
elem.tail = i
|
||||
for elem in elem:
|
||||
indent(elem, level+1)
|
||||
for item in elem:
|
||||
indent(item, level+1)
|
||||
if not elem.tail or not elem.tail.strip():
|
||||
elem.tail = i
|
||||
else:
|
||||
|
@ -604,30 +599,6 @@ def indent(elem, level=0):
|
|||
elem.tail = i
|
||||
|
||||
|
||||
def guisettingsXML():
|
||||
"""
|
||||
Returns special://userdata/guisettings.xml as an etree xml root element
|
||||
"""
|
||||
path = tryDecode(xbmc.translatePath("special://profile/"))
|
||||
xmlpath = "%sguisettings.xml" % path
|
||||
|
||||
try:
|
||||
xmlparse = etree.parse(xmlpath)
|
||||
except IOError:
|
||||
# Document is blank or missing
|
||||
root = etree.Element('settings')
|
||||
except etree.ParseError:
|
||||
log.error('Error parsing %s' % xmlpath)
|
||||
# "Kodi cannot parse {0}. PKC will not function correctly. Please visit
|
||||
# {1} and correct your file!"
|
||||
dialog('ok', language(29999), language(39716).format(
|
||||
'guisettings.xml', 'http://kodi.wiki/view/userdata'))
|
||||
return
|
||||
else:
|
||||
root = xmlparse.getroot()
|
||||
return root
|
||||
|
||||
|
||||
class XmlKodiSetting(object):
|
||||
"""
|
||||
Used to load a Kodi XML settings file from special://profile as an etree
|
||||
|
@ -670,7 +641,7 @@ class XmlKodiSetting(object):
|
|||
except IOError:
|
||||
# Document is blank or missing
|
||||
if self.force_create is False:
|
||||
log.debug('%s does not seem to exist; not creating', self.path)
|
||||
LOG.debug('%s does not seem to exist; not creating', self.path)
|
||||
# This will abort __enter__
|
||||
self.__exit__(IOError, None, None)
|
||||
# Create topmost xml entry
|
||||
|
@ -678,7 +649,7 @@ class XmlKodiSetting(object):
|
|||
element=etree.Element(self.top_element))
|
||||
self.write_xml = True
|
||||
except etree.ParseError:
|
||||
log.error('Error parsing %s', self.path)
|
||||
LOG.error('Error parsing %s', self.path)
|
||||
# "Kodi cannot parse {0}. PKC will not function correctly. Please
|
||||
# visit {1} and correct your file!"
|
||||
dialog('ok', language(29999), language(39716).format(
|
||||
|
@ -775,7 +746,7 @@ class XmlKodiSetting(object):
|
|||
elif old.attrib != attrib:
|
||||
already_set = False
|
||||
if already_set is True:
|
||||
log.debug('Element has already been found')
|
||||
LOG.debug('Element has already been found')
|
||||
return old
|
||||
# Need to set new setting, indeed
|
||||
self.write_xml = True
|
||||
|
@ -790,34 +761,35 @@ class XmlKodiSetting(object):
|
|||
return element
|
||||
|
||||
|
||||
def passwordsXML():
|
||||
# To add network credentials
|
||||
path = tryDecode(xbmc.translatePath("special://userdata/"))
|
||||
def passwords_xml():
|
||||
"""
|
||||
To add network credentials to Kodi's password xml
|
||||
"""
|
||||
path = try_decode(xbmc.translatePath("special://userdata/"))
|
||||
xmlpath = "%spasswords.xml" % path
|
||||
dialog = xbmcgui.Dialog()
|
||||
|
||||
try:
|
||||
xmlparse = etree.parse(xmlpath)
|
||||
except IOError:
|
||||
# Document is blank or missing
|
||||
root = etree.Element('passwords')
|
||||
skipFind = True
|
||||
skip_find = True
|
||||
except etree.ParseError:
|
||||
log.error('Error parsing %s' % xmlpath)
|
||||
LOG.error('Error parsing %s', xmlpath)
|
||||
# "Kodi cannot parse {0}. PKC will not function correctly. Please visit
|
||||
# {1} and correct your file!"
|
||||
dialog.ok(language(29999), language(39716).format(
|
||||
dialog('ok', language(29999), language(39716).format(
|
||||
'passwords.xml', 'http://forum.kodi.tv/'))
|
||||
return
|
||||
else:
|
||||
root = xmlparse.getroot()
|
||||
skipFind = False
|
||||
skip_find = False
|
||||
|
||||
credentials = settings('networkCreds')
|
||||
if credentials:
|
||||
# Present user with options
|
||||
option = dialog.select(
|
||||
"Modify/Remove network credentials", ["Modify", "Remove"])
|
||||
option = dialog('select',
|
||||
"Modify/Remove network credentials",
|
||||
["Modify", "Remove"])
|
||||
|
||||
if option < 0:
|
||||
# User cancelled dialog
|
||||
|
@ -825,76 +797,86 @@ def passwordsXML():
|
|||
|
||||
elif option == 1:
|
||||
# User selected remove
|
||||
success = False
|
||||
for paths in root.getiterator('passwords'):
|
||||
for path in paths:
|
||||
if path.find('.//from').text == "smb://%s/" % credentials:
|
||||
paths.remove(path)
|
||||
log.info("Successfully removed credentials for: %s"
|
||||
% credentials)
|
||||
LOG.info("Successfully removed credentials for: %s",
|
||||
credentials)
|
||||
etree.ElementTree(root).write(xmlpath,
|
||||
encoding="UTF-8")
|
||||
break
|
||||
else:
|
||||
log.error("Failed to find saved server: %s in passwords.xml"
|
||||
% credentials)
|
||||
|
||||
success = True
|
||||
if not success:
|
||||
LOG.error("Failed to find saved server: %s in passwords.xml",
|
||||
credentials)
|
||||
dialog('notification',
|
||||
heading='{plex}',
|
||||
message="%s not found" % credentials,
|
||||
icon='{warning}',
|
||||
sound=False)
|
||||
return
|
||||
settings('networkCreds', value="")
|
||||
xbmcgui.Dialog().notification(
|
||||
heading='PlexKodiConnect',
|
||||
dialog('notification',
|
||||
heading='{plex}',
|
||||
message="%s removed from passwords.xml" % credentials,
|
||||
icon="special://home/addons/plugin.video.plexkodiconnect/icon.png",
|
||||
time=1000,
|
||||
icon='{plex}',
|
||||
sound=False)
|
||||
return
|
||||
|
||||
elif option == 0:
|
||||
# User selected to modify
|
||||
server = dialog.input("Modify the computer name or ip address", credentials)
|
||||
server = dialog('input',
|
||||
"Modify the computer name or ip address",
|
||||
credentials)
|
||||
if not server:
|
||||
return
|
||||
else:
|
||||
# No credentials added
|
||||
dialog.ok(
|
||||
heading="Network credentials",
|
||||
line1= (
|
||||
"Input the server name or IP address as indicated in your plex library paths. "
|
||||
'For example, the server name: \\\\SERVER-PC\\path\\ or smb://SERVER-PC/path is "SERVER-PC".'))
|
||||
server = dialog.input("Enter the server name or IP address")
|
||||
dialog('ok',
|
||||
"Network credentials",
|
||||
'Input the server name or IP address as indicated in your plex '
|
||||
'library paths. For example, the server name: '
|
||||
'\\\\SERVER-PC\\path\\ or smb://SERVER-PC/path is SERVER-PC')
|
||||
server = dialog('input', "Enter the server name or IP address")
|
||||
if not server:
|
||||
return
|
||||
server = quote_plus(server)
|
||||
|
||||
# Network username
|
||||
user = dialog.input("Enter the network username")
|
||||
user = dialog('input', "Enter the network username")
|
||||
if not user:
|
||||
return
|
||||
user = quote_plus(user)
|
||||
# Network password
|
||||
password = dialog.input("Enter the network password",
|
||||
password = dialog('input',
|
||||
"Enter the network password",
|
||||
'', # Default input
|
||||
xbmcgui.INPUT_ALPHANUM,
|
||||
xbmcgui.ALPHANUM_HIDE_INPUT)
|
||||
type='{alphanum}',
|
||||
option='{hide}')
|
||||
# Need to url-encode the password
|
||||
password = quote_plus(password)
|
||||
# Add elements. Annoying etree bug where findall hangs forever
|
||||
if skipFind is False:
|
||||
skipFind = True
|
||||
if skip_find is False:
|
||||
skip_find = True
|
||||
for path in root.findall('.//path'):
|
||||
if path.find('.//from').text.lower() == "smb://%s/" % server.lower():
|
||||
# Found the server, rewrite credentials
|
||||
path.find('.//to').text = "smb://%s:%s@%s/" % (user, password, server)
|
||||
skipFind = False
|
||||
path.find('.//to').text = ("smb://%s:%s@%s/"
|
||||
% (user, password, server))
|
||||
skip_find = False
|
||||
break
|
||||
if skipFind:
|
||||
if skip_find:
|
||||
# Server not found, add it.
|
||||
path = etree.SubElement(root, 'path')
|
||||
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)
|
||||
etree.SubElement(path, 'to', attrib={'pathversion': "1"}).text = topath
|
||||
|
||||
# Add credentials
|
||||
settings('networkCreds', value="%s" % server)
|
||||
log.info("Added server: %s to passwords.xml" % server)
|
||||
LOG.info("Added server: %s to passwords.xml", server)
|
||||
# Prettify and write to file
|
||||
try:
|
||||
indent(root)
|
||||
|
@ -902,19 +884,12 @@ def passwordsXML():
|
|||
pass
|
||||
etree.ElementTree(root).write(xmlpath, encoding="UTF-8")
|
||||
|
||||
# dialog.notification(
|
||||
# heading="PlexKodiConnect",
|
||||
# message="Added to passwords.xml",
|
||||
# icon="special://home/addons/plugin.video.plexkodiconnect/icon.png",
|
||||
# time=5000,
|
||||
# sound=False)
|
||||
|
||||
|
||||
def playlistXSP(mediatype, tagname, viewid, viewtype="", delete=False):
|
||||
def playlist_xsp(mediatype, tagname, viewid, viewtype="", delete=False):
|
||||
"""
|
||||
Feed with tagname as unicode
|
||||
"""
|
||||
path = tryDecode(xbmc.translatePath("special://profile/playlists/video/"))
|
||||
path = try_decode(xbmc.translatePath("special://profile/playlists/video/"))
|
||||
if viewtype == "mixed":
|
||||
plname = "%s - %s" % (tagname, mediatype)
|
||||
xsppath = "%sPlex %s - %s.xsp" % (path, viewid, mediatype)
|
||||
|
@ -923,16 +898,16 @@ def playlistXSP(mediatype, tagname, viewid, viewtype="", delete=False):
|
|||
xsppath = "%sPlex %s.xsp" % (path, viewid)
|
||||
|
||||
# Create the playlist directory
|
||||
if not exists(tryEncode(path)):
|
||||
log.info("Creating directory: %s" % path)
|
||||
if not exists(try_encode(path)):
|
||||
LOG.info("Creating directory: %s", path)
|
||||
makedirs(path)
|
||||
|
||||
# Only add the playlist if it doesn't already exists
|
||||
if exists(tryEncode(xsppath)):
|
||||
log.info('Path %s does exist' % xsppath)
|
||||
if exists(try_encode(xsppath)):
|
||||
LOG.info('Path %s does exist', xsppath)
|
||||
if delete:
|
||||
remove(xsppath)
|
||||
log.info("Successfully removed playlist: %s." % tagname)
|
||||
LOG.info("Successfully removed playlist: %s.", tagname)
|
||||
return
|
||||
|
||||
# Using write process since there's no guarantee the xml declaration works
|
||||
|
@ -942,9 +917,9 @@ def playlistXSP(mediatype, tagname, viewid, viewtype="", delete=False):
|
|||
'movie': 'movies',
|
||||
'show': 'tvshows'
|
||||
}
|
||||
log.info("Writing playlist file to: %s" % xsppath)
|
||||
with open(xsppath, 'wb') as f:
|
||||
f.write(tryEncode(
|
||||
LOG.info("Writing playlist file to: %s", xsppath)
|
||||
with open(xsppath, 'wb') as filer:
|
||||
filer.write(try_encode(
|
||||
'<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>\n'
|
||||
'<smartplaylist type="%s">\n\t'
|
||||
'<name>Plex %s</name>\n\t'
|
||||
|
@ -954,20 +929,24 @@ def playlistXSP(mediatype, tagname, viewid, viewtype="", delete=False):
|
|||
'</rule>\n'
|
||||
'</smartplaylist>\n'
|
||||
% (itemtypes.get(mediatype, mediatype), plname, tagname)))
|
||||
log.info("Successfully added playlist: %s" % tagname)
|
||||
LOG.info("Successfully added playlist: %s", tagname)
|
||||
|
||||
|
||||
def deletePlaylists():
|
||||
# Clean up the playlists
|
||||
path = tryDecode(xbmc.translatePath("special://profile/playlists/video/"))
|
||||
def delete_playlists():
|
||||
"""
|
||||
Clean up the playlists
|
||||
"""
|
||||
path = try_decode(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
|
||||
path = tryDecode(xbmc.translatePath("special://profile/library/video/"))
|
||||
def delete_nodes():
|
||||
"""
|
||||
Clean up video nodes
|
||||
"""
|
||||
path = try_decode(xbmc.translatePath("special://profile/library/video/"))
|
||||
for root, dirs, _ in walk(path):
|
||||
for directory in dirs:
|
||||
if directory.startswith('Plex-'):
|
||||
|
@ -993,9 +972,9 @@ def CatchExceptions(warnuser=False):
|
|||
try:
|
||||
return func(*args, **kwargs)
|
||||
except Exception as e:
|
||||
log.error('%s has crashed. Error: %s' % (func.__name__, e))
|
||||
LOG.error('%s has crashed. Error: %s', func.__name__, e)
|
||||
import traceback
|
||||
log.error("Traceback:\n%s" % traceback.format_exc())
|
||||
LOG.error("Traceback:\n%s", traceback.format_exc())
|
||||
if warnuser:
|
||||
window('plex_scancrashed', value='true')
|
||||
return
|
||||
|
@ -1012,8 +991,8 @@ def LogTime(func):
|
|||
starttotal = datetime.now()
|
||||
result = func(*args, **kwargs)
|
||||
elapsedtotal = datetime.now() - starttotal
|
||||
log.info('It took %s to run the function %s'
|
||||
% (elapsedtotal, func.__name__))
|
||||
LOG.info('It took %s to run the function %s',
|
||||
elapsedtotal, func.__name__)
|
||||
return result
|
||||
return wrapper
|
||||
|
||||
|
@ -1117,43 +1096,3 @@ class Lock_Function(object):
|
|||
result = func(*args, **kwargs)
|
||||
return result
|
||||
return wrapper
|
||||
|
||||
###############################################################################
|
||||
# UNUSED METHODS
|
||||
|
||||
|
||||
# def changePlayState(itemType, kodiId, playCount, lastplayed):
|
||||
# """
|
||||
# YET UNUSED
|
||||
|
||||
# kodiId: int or str
|
||||
# playCount: int or str
|
||||
# lastplayed: str or int unix timestamp
|
||||
# """
|
||||
# lastplayed = DateToKodi(lastplayed)
|
||||
|
||||
# kodiId = int(kodiId)
|
||||
# playCount = int(playCount)
|
||||
# method = {
|
||||
# 'movie': ' VideoLibrary.SetMovieDetails',
|
||||
# 'episode': 'VideoLibrary.SetEpisodeDetails',
|
||||
# 'musicvideo': ' VideoLibrary.SetMusicVideoDetails', # TODO
|
||||
# 'show': 'VideoLibrary.SetTVShowDetails', # TODO
|
||||
# '': 'AudioLibrary.SetAlbumDetails', # TODO
|
||||
# '': 'AudioLibrary.SetArtistDetails', # TODO
|
||||
# 'track': 'AudioLibrary.SetSongDetails'
|
||||
# }
|
||||
# params = {
|
||||
# 'movie': {
|
||||
# 'movieid': kodiId,
|
||||
# 'playcount': playCount,
|
||||
# 'lastplayed': lastplayed
|
||||
# },
|
||||
# 'episode': {
|
||||
# 'episodeid': kodiId,
|
||||
# 'playcount': playCount,
|
||||
# 'lastplayed': lastplayed
|
||||
# }
|
||||
# }
|
||||
# result = jsonrpc(method[itemType]).execute(params[itemType])
|
||||
# log.debug("JSON result was: %s" % result)
|
||||
|
|
|
@ -6,7 +6,7 @@ from xbmcaddon import Addon
|
|||
# For any file operations with KODI function, use encoded strings!
|
||||
|
||||
|
||||
def tryDecode(string, encoding='utf-8'):
|
||||
def try_decode(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
|
||||
|
@ -37,7 +37,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 = try_decode(xbmc.translatePath("special://profile"))
|
||||
|
||||
if xbmc.getCondVisibility('system.platform.osx'):
|
||||
PLATFORM = "MacOSX"
|
||||
|
@ -56,7 +56,7 @@ elif xbmc.getCondVisibility('system.platform.android'):
|
|||
else:
|
||||
PLATFORM = "Unknown"
|
||||
|
||||
DEVICENAME = tryDecode(_ADDON.getSetting('deviceName'))
|
||||
DEVICENAME = try_decode(_ADDON.getSetting('deviceName'))
|
||||
DEVICENAME = DEVICENAME.replace(":", "")
|
||||
DEVICENAME = DEVICENAME.replace("/", "-")
|
||||
DEVICENAME = DEVICENAME.replace("\\", "-")
|
||||
|
@ -86,7 +86,7 @@ _DB_VIDEO_VERSION = {
|
|||
17: 107, # Krypton
|
||||
18: 108 # Leia
|
||||
}
|
||||
DB_VIDEO_PATH = tryDecode(xbmc.translatePath(
|
||||
DB_VIDEO_PATH = try_decode(xbmc.translatePath(
|
||||
"special://database/MyVideos%s.db" % _DB_VIDEO_VERSION[KODIVERSION]))
|
||||
|
||||
_DB_MUSIC_VERSION = {
|
||||
|
@ -97,7 +97,7 @@ _DB_MUSIC_VERSION = {
|
|||
17: 60, # Krypton
|
||||
18: 62 # Leia
|
||||
}
|
||||
DB_MUSIC_PATH = tryDecode(xbmc.translatePath(
|
||||
DB_MUSIC_PATH = try_decode(xbmc.translatePath(
|
||||
"special://database/MyMusic%s.db" % _DB_MUSIC_VERSION[KODIVERSION]))
|
||||
|
||||
_DB_TEXTURE_VERSION = {
|
||||
|
@ -108,12 +108,12 @@ _DB_TEXTURE_VERSION = {
|
|||
17: 13, # Krypton
|
||||
18: 13 # Leia
|
||||
}
|
||||
DB_TEXTURE_PATH = tryDecode(xbmc.translatePath(
|
||||
DB_TEXTURE_PATH = try_decode(xbmc.translatePath(
|
||||
"special://database/Textures%s.db" % _DB_TEXTURE_VERSION[KODIVERSION]))
|
||||
|
||||
DB_PLEX_PATH = tryDecode(xbmc.translatePath("special://database/plex.db"))
|
||||
DB_PLEX_PATH = try_decode(xbmc.translatePath("special://database/plex.db"))
|
||||
|
||||
EXTERNAL_SUBTITLE_TEMP_PATH = tryDecode(xbmc.translatePath(
|
||||
EXTERNAL_SUBTITLE_TEMP_PATH = try_decode(xbmc.translatePath(
|
||||
"special://profile/addon_data/%s/temp/" % ADDON_ID))
|
||||
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@ from os import makedirs
|
|||
import xbmc
|
||||
from xbmcvfs import exists
|
||||
|
||||
from utils import window, settings, language as lang, tryEncode, indent, \
|
||||
normalize_nodes, exists_dir, tryDecode
|
||||
from utils import window, settings, language as lang, try_encode, indent, \
|
||||
normalize_nodes, exists_dir, try_decode
|
||||
import variables as v
|
||||
|
||||
###############################################################################
|
||||
|
@ -62,9 +62,9 @@ class VideoNodes(object):
|
|||
dirname = viewid
|
||||
|
||||
# Returns strings
|
||||
path = tryDecode(xbmc.translatePath(
|
||||
path = try_decode(xbmc.translatePath(
|
||||
"special://profile/library/video/"))
|
||||
nodepath = tryDecode(xbmc.translatePath(
|
||||
nodepath = try_decode(xbmc.translatePath(
|
||||
"special://profile/library/video/Plex-%s/" % dirname))
|
||||
|
||||
if delete:
|
||||
|
@ -77,9 +77,9 @@ class VideoNodes(object):
|
|||
# Verify the video directory
|
||||
if not exists_dir(path):
|
||||
copytree(
|
||||
src=tryDecode(xbmc.translatePath(
|
||||
src=try_decode(xbmc.translatePath(
|
||||
"special://xbmc/system/library/video")),
|
||||
dst=tryDecode(xbmc.translatePath(
|
||||
dst=try_decode(xbmc.translatePath(
|
||||
"special://profile/library/video")))
|
||||
|
||||
# Create the node directory
|
||||
|
@ -292,7 +292,7 @@ class VideoNodes(object):
|
|||
# To do: add our photos nodes to kodi picture sources somehow
|
||||
continue
|
||||
|
||||
if exists(tryEncode(nodeXML)):
|
||||
if exists(try_encode(nodeXML)):
|
||||
# Don't recreate xml if already exists
|
||||
continue
|
||||
|
||||
|
@ -378,9 +378,9 @@ class VideoNodes(object):
|
|||
etree.ElementTree(root).write(nodeXML, encoding="UTF-8")
|
||||
|
||||
def singleNode(self, indexnumber, tagname, mediatype, itemtype):
|
||||
tagname = tryEncode(tagname)
|
||||
cleantagname = tryDecode(normalize_nodes(tagname))
|
||||
nodepath = tryDecode(xbmc.translatePath(
|
||||
tagname = try_encode(tagname)
|
||||
cleantagname = try_decode(normalize_nodes(tagname))
|
||||
nodepath = try_decode(xbmc.translatePath(
|
||||
"special://profile/library/video/"))
|
||||
nodeXML = "%splex_%s.xml" % (nodepath, cleantagname)
|
||||
path = "library://video/plex_%s.xml" % cleantagname
|
||||
|
@ -394,9 +394,9 @@ class VideoNodes(object):
|
|||
if not exists_dir(nodepath):
|
||||
# We need to copy over the default items
|
||||
copytree(
|
||||
src=tryDecode(xbmc.translatePath(
|
||||
src=try_decode(xbmc.translatePath(
|
||||
"special://xbmc/system/library/video")),
|
||||
dst=tryDecode(xbmc.translatePath(
|
||||
dst=try_decode(xbmc.translatePath(
|
||||
"special://profile/library/video")))
|
||||
|
||||
labels = {
|
||||
|
@ -411,7 +411,7 @@ class VideoNodes(object):
|
|||
window('%s.content' % embynode, value=path)
|
||||
window('%s.type' % embynode, value=itemtype)
|
||||
|
||||
if exists(tryEncode(nodeXML)):
|
||||
if exists(try_encode(nodeXML)):
|
||||
# Don't recreate xml if already exists
|
||||
return
|
||||
|
||||
|
|
|
@ -292,7 +292,7 @@ class ABNF(object):
|
|||
opcode: operation code. please see OPCODE_XXX.
|
||||
"""
|
||||
if opcode == ABNF.OPCODE_TEXT and isinstance(data, unicode):
|
||||
data = utils.tryEncode(data)
|
||||
data = utils.try_encode(data)
|
||||
# mask must be set if send data from client
|
||||
return ABNF(1, 0, 0, 0, opcode, 1, data)
|
||||
|
||||
|
|
Loading…
Reference in a new issue