Merge branch 'develop' into translations
This commit is contained in:
commit
4cbb1dc7bc
21 changed files with 226 additions and 108 deletions
|
@ -1,5 +1,5 @@
|
||||||
[![stable version](https://img.shields.io/badge/stable_version-1.7.7-blue.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect/bin/repository.plexkodiconnect/repository.plexkodiconnect-1.0.0.zip)
|
[![stable version](https://img.shields.io/badge/stable_version-1.7.7-blue.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect/bin/repository.plexkodiconnect/repository.plexkodiconnect-1.0.0.zip)
|
||||||
[![beta version](https://img.shields.io/badge/beta_version-1.7.12-red.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect_BETA/bin-BETA/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.0.zip)
|
[![beta version](https://img.shields.io/badge/beta_version-1.7.17-red.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect_BETA/bin-BETA/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.0.zip)
|
||||||
|
|
||||||
[![Installation](https://img.shields.io/badge/wiki-installation-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/Installation)
|
[![Installation](https://img.shields.io/badge/wiki-installation-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/Installation)
|
||||||
[![FAQ](https://img.shields.io/badge/wiki-FAQ-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/faq)
|
[![FAQ](https://img.shields.io/badge/wiki-FAQ-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/faq)
|
||||||
|
|
29
addon.xml
29
addon.xml
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<addon id="plugin.video.plexkodiconnect" name="PlexKodiConnect" version="1.7.12" provider-name="croneter">
|
<addon id="plugin.video.plexkodiconnect" name="PlexKodiConnect" version="1.7.17" provider-name="croneter">
|
||||||
<requires>
|
<requires>
|
||||||
<import addon="xbmc.python" version="2.1.0"/>
|
<import addon="xbmc.python" version="2.1.0"/>
|
||||||
<import addon="script.module.requests" version="2.3.0" />
|
<import addon="script.module.requests" version="2.3.0" />
|
||||||
|
@ -44,7 +44,32 @@
|
||||||
<disclaimer lang="nl_NL">Gebruik op eigen risico</disclaimer>
|
<disclaimer lang="nl_NL">Gebruik op eigen risico</disclaimer>
|
||||||
<disclaimer lang="zh_TW">使用風險由您自己承擔</disclaimer>
|
<disclaimer lang="zh_TW">使用風險由您自己承擔</disclaimer>
|
||||||
<disclaimer lang="es_ES">Usar a su propio riesgo</disclaimer>
|
<disclaimer lang="es_ES">Usar a su propio riesgo</disclaimer>
|
||||||
<news>version 1.7.12 (beta only)
|
<news>version 1.7.17 (beta only)
|
||||||
|
- Don't add media by other add-ons to queue
|
||||||
|
- Fix KeyError for Plex Companion
|
||||||
|
- Repace Kodi mkdirs with os.makedirs
|
||||||
|
- Use xbmcvfs exists instead of os.path.exists
|
||||||
|
|
||||||
|
version 1.7.16 (beta only)
|
||||||
|
- Fix PKC complaining about files not found
|
||||||
|
- Fix multiple subtitles per language not showing
|
||||||
|
- Update Czech translation
|
||||||
|
- Fix too many arguments when marking 100% watched
|
||||||
|
- More small fixes
|
||||||
|
|
||||||
|
version 1.7.15 (beta only)
|
||||||
|
- Fix companion for "Playback via PMS"
|
||||||
|
- Change sleeping behavior for playqueue client
|
||||||
|
- Plex Companion: add itemType to playstate
|
||||||
|
- Less logging
|
||||||
|
|
||||||
|
version 1.7.14 (beta only)
|
||||||
|
- Fix TypeError, but for real now
|
||||||
|
|
||||||
|
version 1.7.13 (beta only)
|
||||||
|
- Fix TypeError with AdvancedSettings.xml missing
|
||||||
|
|
||||||
|
version 1.7.12 (beta only)
|
||||||
- Major music overhaul: Direct Paths should now work! Many thanks @Memesa for the pointers! Don't forget to reset your database
|
- Major music overhaul: Direct Paths should now work! Many thanks @Memesa for the pointers! Don't forget to reset your database
|
||||||
- Some Plex Companion fixes
|
- Some Plex Companion fixes
|
||||||
- Fix UnicodeDecodeError on user switch
|
- Fix UnicodeDecodeError on user switch
|
||||||
|
|
|
@ -1,3 +1,28 @@
|
||||||
|
version 1.7.17 (beta only)
|
||||||
|
- Don't add media by other add-ons to queue
|
||||||
|
- Fix KeyError for Plex Companion
|
||||||
|
- Repace Kodi mkdirs with os.makedirs
|
||||||
|
- Use xbmcvfs exists instead of os.path.exists
|
||||||
|
|
||||||
|
version 1.7.16 (beta only)
|
||||||
|
- Fix PKC complaining about files not found
|
||||||
|
- Fix multiple subtitles per language not showing
|
||||||
|
- Update Czech translation
|
||||||
|
- Fix too many arguments when marking 100% watched
|
||||||
|
- More small fixes
|
||||||
|
|
||||||
|
version 1.7.15 (beta only)
|
||||||
|
- Fix companion for "Playback via PMS"
|
||||||
|
- Change sleeping behavior for playqueue client
|
||||||
|
- Plex Companion: add itemType to playstate
|
||||||
|
- Less logging
|
||||||
|
|
||||||
|
version 1.7.14 (beta only)
|
||||||
|
- Fix TypeError, but for real now
|
||||||
|
|
||||||
|
version 1.7.13 (beta only)
|
||||||
|
- Fix TypeError with AdvancedSettings.xml missing
|
||||||
|
|
||||||
version 1.7.12 (beta only)
|
version 1.7.12 (beta only)
|
||||||
- Major music overhaul: Direct Paths should now work! Many thanks @Memesa for the pointers! Don't forget to reset your database
|
- Major music overhaul: Direct Paths should now work! Many thanks @Memesa for the pointers! Don't forget to reset your database
|
||||||
- Some Plex Companion fixes
|
- Some Plex Companion fixes
|
||||||
|
|
|
@ -1899,3 +1899,23 @@ msgstr ""
|
||||||
msgctxt "#39711"
|
msgctxt "#39711"
|
||||||
msgid "New Plex music library detected. Sorry, but we need to restart Kodi now due to the changes made."
|
msgid "New Plex music library detected. Sorry, but we need to restart Kodi now due to the changes made."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
# Shown during sync process
|
||||||
|
msgctxt "#39712"
|
||||||
|
msgid "downloaded"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
# Shown during sync process
|
||||||
|
msgctxt "#39713"
|
||||||
|
msgid "processed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
# Shown during sync process
|
||||||
|
msgctxt "#39714"
|
||||||
|
msgid "Sync"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
# Shown during sync process
|
||||||
|
msgctxt "#39715"
|
||||||
|
msgid "items"
|
||||||
|
msgstr ""
|
||||||
|
|
|
@ -1,21 +1,13 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
###############################################################################
|
###############################################################################
|
||||||
import logging
|
|
||||||
|
|
||||||
from xbmcgui import ListItem
|
from xbmcgui import ListItem
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
log = logging.getLogger("PLEX."+__name__)
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
|
|
||||||
def convert_PKC_to_listitem(PKC_listitem):
|
def convert_PKC_to_listitem(PKC_listitem):
|
||||||
"""
|
"""
|
||||||
Insert a PKC_listitem and you will receive a valid XBMC listitem
|
Insert a PKC_listitem and you will receive a valid XBMC listitem
|
||||||
"""
|
"""
|
||||||
data = PKC_listitem.data
|
data = PKC_listitem.data
|
||||||
log.debug('data is: %s' % data)
|
|
||||||
listitem = ListItem(label=data.get('label'),
|
listitem = ListItem(label=data.get('label'),
|
||||||
label2=data.get('label2'),
|
label2=data.get('label2'),
|
||||||
path=data.get('path'))
|
path=data.get('path'))
|
||||||
|
|
|
@ -39,16 +39,17 @@ 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.path import basename, join, exists
|
from os.path import basename, join
|
||||||
from os import makedirs
|
from os import makedirs
|
||||||
|
|
||||||
import xbmcgui
|
import xbmcgui
|
||||||
from xbmc import sleep, executebuiltin
|
from xbmc import sleep, executebuiltin
|
||||||
|
from xbmcvfs import exists
|
||||||
|
|
||||||
import clientinfo as client
|
import clientinfo as client
|
||||||
from downloadutils import DownloadUtils
|
from downloadutils import DownloadUtils
|
||||||
from utils import window, settings, language as lang, tryDecode, tryEncode, \
|
from utils import window, settings, language as lang, tryDecode, tryEncode, \
|
||||||
DateToKodi
|
DateToKodi, exists_dir
|
||||||
from PlexFunctions import PMSHttpsEnabled
|
from PlexFunctions import PMSHttpsEnabled
|
||||||
import plexdb_functions as plexdb
|
import plexdb_functions as plexdb
|
||||||
import variables as v
|
import variables as v
|
||||||
|
@ -2117,7 +2118,6 @@ class API():
|
||||||
continue
|
continue
|
||||||
if fanartcount > maxfanarts:
|
if fanartcount > maxfanarts:
|
||||||
break
|
break
|
||||||
if exists(tryEncode(entry['url'])):
|
|
||||||
allartworks['Backdrop'].append(
|
allartworks['Backdrop'].append(
|
||||||
entry['url'].replace(' ', '%20'))
|
entry['url'].replace(' ', '%20'))
|
||||||
fanartcount += 1
|
fanartcount += 1
|
||||||
|
@ -2303,6 +2303,7 @@ class API():
|
||||||
except (TypeError, KeyError, IndexError):
|
except (TypeError, KeyError, IndexError):
|
||||||
return
|
return
|
||||||
kodiindex = 0
|
kodiindex = 0
|
||||||
|
fileindex = 0
|
||||||
for stream in mediastreams:
|
for stream in mediastreams:
|
||||||
# Since plex returns all possible tracks together, have to pull
|
# Since plex returns all possible tracks together, have to pull
|
||||||
# only external subtitles - only for these a 'key' exists
|
# only external subtitles - only for these a 'key' exists
|
||||||
|
@ -2318,8 +2319,10 @@ class API():
|
||||||
if stream.attrib.get('languageCode') is not None:
|
if stream.attrib.get('languageCode') is not None:
|
||||||
path = self.download_external_subtitles(
|
path = self.download_external_subtitles(
|
||||||
"{server}%s" % key,
|
"{server}%s" % key,
|
||||||
"subtitle.%s.%s" % (stream.attrib['languageCode'],
|
"subtitle%02d.%s.%s" % (fileindex,
|
||||||
|
stream.attrib['languageCode'],
|
||||||
stream.attrib['codec']))
|
stream.attrib['codec']))
|
||||||
|
fileindex += 1
|
||||||
# We don't know the language - no need to download
|
# We don't know the language - no need to download
|
||||||
else:
|
else:
|
||||||
path = self.addPlexCredentialsToUrl(
|
path = self.addPlexCredentialsToUrl(
|
||||||
|
@ -2341,7 +2344,7 @@ 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_dir(v.EXTERNAL_SUBTITLE_TEMP_PATH):
|
||||||
makedirs(v.EXTERNAL_SUBTITLE_TEMP_PATH)
|
makedirs(v.EXTERNAL_SUBTITLE_TEMP_PATH)
|
||||||
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)
|
||||||
|
@ -2541,16 +2544,22 @@ class API():
|
||||||
# exist() needs a / or \ at the end to work for directories
|
# exist() needs a / or \ at the end to work for directories
|
||||||
if folder is False:
|
if folder is False:
|
||||||
# files
|
# files
|
||||||
check = exists(tryEncode(path)) == 1
|
check = exists(tryEncode(path))
|
||||||
else:
|
else:
|
||||||
# directories
|
# directories
|
||||||
if "\\" in path:
|
if "\\" in path:
|
||||||
|
if not path.endswith('\\'):
|
||||||
# Add the missing backslash
|
# Add the missing backslash
|
||||||
check = exists(tryEncode(path + "\\")) == 1
|
check = exists_dir(tryEncode(path + "\\"))
|
||||||
else:
|
else:
|
||||||
check = exists(tryEncode(path + "/")) == 1
|
check = exists_dir(tryEncode(path))
|
||||||
|
else:
|
||||||
|
if not path.endswith('/'):
|
||||||
|
check = exists_dir(tryEncode(path + "/"))
|
||||||
|
else:
|
||||||
|
check = exists_dir(tryEncode(path))
|
||||||
|
|
||||||
if check is False:
|
if not check:
|
||||||
if forceCheck is False:
|
if forceCheck is False:
|
||||||
# Validate the path is correct with user intervention
|
# Validate the path is correct with user intervention
|
||||||
if self.askToValidate(path):
|
if self.askToValidate(path):
|
||||||
|
|
|
@ -4,16 +4,16 @@
|
||||||
import logging
|
import logging
|
||||||
from json import dumps, loads
|
from json import dumps, loads
|
||||||
import requests
|
import requests
|
||||||
from os.path import exists
|
|
||||||
from shutil import rmtree
|
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 exists
|
||||||
|
|
||||||
from utils import window, settings, language as lang, kodiSQL, tryEncode, \
|
from utils import window, settings, language as lang, kodiSQL, tryEncode, \
|
||||||
ThreadMethods, ThreadMethodsAdditionalStop, dialog
|
ThreadMethods, ThreadMethodsAdditionalStop, dialog, exists_dir
|
||||||
|
|
||||||
# Disable annoying requests warnings
|
# Disable annoying requests warnings
|
||||||
import requests.packages.urllib3
|
import requests.packages.urllib3
|
||||||
|
@ -229,7 +229,7 @@ class Artwork():
|
||||||
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 = translatePath("special://thumbnails/")
|
path = translatePath("special://thumbnails/")
|
||||||
if exists(path):
|
if exists_dir(path):
|
||||||
rmtree(path, ignore_errors=True)
|
rmtree(path, ignore_errors=True)
|
||||||
|
|
||||||
# remove all existing data from texture DB
|
# remove all existing data from texture DB
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
import logging
|
import logging
|
||||||
from shutil import copyfile
|
from shutil import copyfile
|
||||||
from os import walk, makedirs
|
from os import walk, makedirs
|
||||||
from os.path import basename, join, exists
|
from os.path import basename, join
|
||||||
from sys import argv
|
from sys import argv
|
||||||
from urllib import urlencode
|
from urllib import urlencode
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ from xbmc import sleep, executebuiltin, translatePath
|
||||||
from xbmcgui import ListItem
|
from xbmcgui import ListItem
|
||||||
|
|
||||||
from utils import window, settings, language as lang, dialog, tryEncode, \
|
from utils import window, settings, language as lang, dialog, tryEncode, \
|
||||||
CatchExceptions, JSONRPC
|
CatchExceptions, JSONRPC, exists_dir
|
||||||
import downloadutils
|
import downloadutils
|
||||||
|
|
||||||
from PlexFunctions import GetPlexMetadata, GetPlexSectionResults, \
|
from PlexFunctions import GetPlexMetadata, GetPlexSectionResults, \
|
||||||
|
@ -74,7 +74,7 @@ def togglePlexTV():
|
||||||
if settings('plexToken'):
|
if settings('plexToken'):
|
||||||
log.info('Reseting plex.tv credentials in settings')
|
log.info('Reseting plex.tv credentials in settings')
|
||||||
settings('plexLogin', value="")
|
settings('plexLogin', value="")
|
||||||
settings('plexToken', value=""),
|
settings('plexToken', value="")
|
||||||
settings('plexid', value="")
|
settings('plexid', value="")
|
||||||
settings('plexHomeSize', value="1")
|
settings('plexHomeSize', value="1")
|
||||||
settings('plexAvatar', value="")
|
settings('plexAvatar', value="")
|
||||||
|
@ -498,7 +498,7 @@ def getVideoFiles(plexId, params):
|
||||||
path = path.replace('\\', '\\\\')
|
path = path.replace('\\', '\\\\')
|
||||||
# Directory only, get rid of filename
|
# Directory only, get rid of filename
|
||||||
path = path.replace(basename(path), '')
|
path = path.replace(basename(path), '')
|
||||||
if exists(path):
|
if exists_dir(path):
|
||||||
for root, dirs, files in walk(path):
|
for root, dirs, files in walk(path):
|
||||||
for directory in dirs:
|
for directory in dirs:
|
||||||
item_path = join(root, directory)
|
item_path = join(root, directory)
|
||||||
|
@ -513,6 +513,7 @@ def getVideoFiles(plexId, params):
|
||||||
xbmcplugin.addDirectoryItem(handle=HANDLE,
|
xbmcplugin.addDirectoryItem(handle=HANDLE,
|
||||||
url=file,
|
url=file,
|
||||||
listitem=li)
|
listitem=li)
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
log.error('Kodi cannot access folder %s' % path)
|
log.error('Kodi cannot access folder %s' % path)
|
||||||
xbmcplugin.endOfDirectory(HANDLE)
|
xbmcplugin.endOfDirectory(HANDLE)
|
||||||
|
@ -536,7 +537,7 @@ 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 = translatePath("special://thumbnails/plex/%s/" % plexid)
|
fanartDir = translatePath("special://thumbnails/plex/%s/" % plexid)
|
||||||
if not exists(fanartDir):
|
if not exists_dir(fanartDir):
|
||||||
# Download the images to the cache directory
|
# Download the images to the cache directory
|
||||||
makedirs(fanartDir)
|
makedirs(fanartDir)
|
||||||
xml = GetPlexMetadata(plexid)
|
xml = GetPlexMetadata(plexid)
|
||||||
|
|
|
@ -402,11 +402,11 @@ class InitialSetup():
|
||||||
|
|
||||||
# Get current Kodi video cache setting
|
# Get current Kodi video cache setting
|
||||||
cache, _ = advancedsettings_xml(['cache', 'memorysize'])
|
cache, _ = advancedsettings_xml(['cache', 'memorysize'])
|
||||||
if cache is not None:
|
if cache is None:
|
||||||
cache = str(cache.text)
|
|
||||||
else:
|
|
||||||
# Kodi default cache
|
# Kodi default cache
|
||||||
cache = '20971520'
|
cache = '20971520'
|
||||||
|
else:
|
||||||
|
cache = str(cache.text)
|
||||||
log.info('Current Kodi video memory cache in bytes: %s' % cache)
|
log.info('Current Kodi video memory cache in bytes: %s' % cache)
|
||||||
settings('kodi_video_cache', value=cache)
|
settings('kodi_video_cache', value=cache)
|
||||||
|
|
||||||
|
|
|
@ -165,7 +165,7 @@ class Items(object):
|
||||||
'Mark item played at %s percent.'
|
'Mark item played at %s percent.'
|
||||||
% (item['ratingKey'], str(complete), MARK_PLAYED_AT), 1)
|
% (item['ratingKey'], str(complete), MARK_PLAYED_AT), 1)
|
||||||
if complete >= MARK_PLAYED_AT:
|
if complete >= MARK_PLAYED_AT:
|
||||||
log.info('Marking as completely watched in Kodi', 1)
|
log.info('Marking as completely watched in Kodi')
|
||||||
sleep(500)
|
sleep(500)
|
||||||
try:
|
try:
|
||||||
item['viewCount'] += 1
|
item['viewCount'] += 1
|
||||||
|
@ -1189,7 +1189,6 @@ class TVShows(Items):
|
||||||
v.KODI_TYPE_SEASON)
|
v.KODI_TYPE_SEASON)
|
||||||
for season in seasons:
|
for season in seasons:
|
||||||
self.removeSeason(season[1])
|
self.removeSeason(season[1])
|
||||||
else:
|
|
||||||
# Delete plex season entries
|
# Delete plex season entries
|
||||||
plex_db.removeItems_byParentId(showid,
|
plex_db.removeItems_byParentId(showid,
|
||||||
v.KODI_TYPE_SEASON)
|
v.KODI_TYPE_SEASON)
|
||||||
|
@ -1208,11 +1207,9 @@ class TVShows(Items):
|
||||||
seasonid, v.KODI_TYPE_EPISODE)
|
seasonid, v.KODI_TYPE_EPISODE)
|
||||||
for episode in season_episodes:
|
for episode in season_episodes:
|
||||||
self.removeEpisode(episode[1], episode[2])
|
self.removeEpisode(episode[1], episode[2])
|
||||||
else:
|
|
||||||
# Remove plex episodes
|
# Remove plex episodes
|
||||||
plex_db.removeItems_byParentId(seasonid,
|
plex_db.removeItems_byParentId(seasonid,
|
||||||
v.KODI_TYPE_EPISODE)
|
v.KODI_TYPE_EPISODE)
|
||||||
else:
|
|
||||||
# Remove plex seasons
|
# Remove plex seasons
|
||||||
plex_db.removeItems_byParentId(kodiid,
|
plex_db.removeItems_byParentId(kodiid,
|
||||||
v.KODI_TYPE_SEASON)
|
v.KODI_TYPE_SEASON)
|
||||||
|
@ -1228,7 +1225,6 @@ class TVShows(Items):
|
||||||
v.KODI_TYPE_EPISODE)
|
v.KODI_TYPE_EPISODE)
|
||||||
for episode in season_episodes:
|
for episode in season_episodes:
|
||||||
self.removeEpisode(episode[1], episode[2])
|
self.removeEpisode(episode[1], episode[2])
|
||||||
else:
|
|
||||||
# Remove plex episodes
|
# Remove plex episodes
|
||||||
plex_db.removeItems_byParentId(kodiid, v.KODI_TYPE_EPISODE)
|
plex_db.removeItems_byParentId(kodiid, v.KODI_TYPE_EPISODE)
|
||||||
|
|
||||||
|
|
|
@ -1409,9 +1409,8 @@ class Kodidb_Functions():
|
||||||
ID = 'idEpisode'
|
ID = 'idEpisode'
|
||||||
elif kodi_type == v.KODI_TYPE_SONG:
|
elif kodi_type == v.KODI_TYPE_SONG:
|
||||||
ID = 'idSong'
|
ID = 'idSong'
|
||||||
query = ('''UPDATE %s SET userrating = ? WHERE %s = ?'''
|
query = '''UPDATE ? SET userrating = ? WHERE ? = ?'''
|
||||||
% (kodi_type, ID))
|
self.cursor.execute(query, (kodi_type, userrating, ID, kodi_id))
|
||||||
self.cursor.execute(query, (userrating, kodi_id))
|
|
||||||
|
|
||||||
def create_entry_uniqueid(self):
|
def create_entry_uniqueid(self):
|
||||||
self.cursor.execute(
|
self.cursor.execute(
|
||||||
|
|
|
@ -54,9 +54,8 @@ class Threaded_Show_Sync_Info(Thread):
|
||||||
total = self.total
|
total = self.total
|
||||||
dialog = self.dialog
|
dialog = self.dialog
|
||||||
threadStopped = self.threadStopped
|
threadStopped = self.threadStopped
|
||||||
dialog.create("%s: Sync %s: %s items"
|
dialog.create("%s %s: %s %s"
|
||||||
% (lang(29999), self.item_type, str(total)),
|
% (lang(39714), self.item_type, str(total), lang(39715)))
|
||||||
"Starting")
|
|
||||||
|
|
||||||
total = 2 * total
|
total = 2 * total
|
||||||
totalProgress = 0
|
totalProgress = 0
|
||||||
|
@ -71,9 +70,11 @@ class Threaded_Show_Sync_Info(Thread):
|
||||||
except ZeroDivisionError:
|
except ZeroDivisionError:
|
||||||
percentage = 0
|
percentage = 0
|
||||||
dialog.update(percentage,
|
dialog.update(percentage,
|
||||||
message="%s downloaded. %s processed: %s"
|
message="%s %s. %s %s: %s"
|
||||||
% (get_progress,
|
% (get_progress,
|
||||||
|
lang(39712),
|
||||||
process_progress,
|
process_progress,
|
||||||
|
lang(39713),
|
||||||
viewName))
|
viewName))
|
||||||
# Sleep for x milliseconds
|
# Sleep for x milliseconds
|
||||||
sleep(200)
|
sleep(200)
|
||||||
|
|
|
@ -4,10 +4,10 @@ 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
|
||||||
|
from xbmcvfs import exists
|
||||||
|
|
||||||
from utils import window, settings, getUnixTimestamp, sourcesXML,\
|
from utils import window, settings, getUnixTimestamp, sourcesXML,\
|
||||||
ThreadMethods, ThreadMethodsAdditionalStop, LogTime, getScreensaver,\
|
ThreadMethods, ThreadMethodsAdditionalStop, LogTime, getScreensaver,\
|
||||||
|
@ -297,15 +297,6 @@ class LibrarySync(Thread):
|
||||||
}
|
}
|
||||||
if self.enableMusic:
|
if self.enableMusic:
|
||||||
process['music'] = self.PlexMusic
|
process['music'] = self.PlexMusic
|
||||||
if self.direct_paths is True:
|
|
||||||
if music.set_excludefromscan_music_folders() is True:
|
|
||||||
log.info('Detected new Music library - restarting now')
|
|
||||||
# 'New Plex music library detected. Sorry, but we need to
|
|
||||||
# restart Kodi now due to the changes made.'
|
|
||||||
dialog('ok', lang(29999), lang(39711))
|
|
||||||
from xbmc import executebuiltin
|
|
||||||
executebuiltin('RestartApp')
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Do the processing
|
# Do the processing
|
||||||
for itemtype in process:
|
for itemtype in process:
|
||||||
|
@ -483,6 +474,16 @@ class LibrarySync(Thread):
|
||||||
"""
|
"""
|
||||||
Compare the views to Plex
|
Compare the views to Plex
|
||||||
"""
|
"""
|
||||||
|
if self.direct_paths is True:
|
||||||
|
if music.set_excludefromscan_music_folders() is True:
|
||||||
|
log.info('Detected new Music library - restarting now')
|
||||||
|
# 'New Plex music library detected. Sorry, but we need to
|
||||||
|
# restart Kodi now due to the changes made.'
|
||||||
|
dialog('ok', lang(29999), lang(39711))
|
||||||
|
from xbmc import executebuiltin
|
||||||
|
executebuiltin('RestartApp')
|
||||||
|
return False
|
||||||
|
|
||||||
self.views = []
|
self.views = []
|
||||||
vnodes = self.vnodes
|
vnodes = self.vnodes
|
||||||
|
|
||||||
|
|
|
@ -200,7 +200,7 @@ class PlaybackUtils():
|
||||||
playqueue,
|
playqueue,
|
||||||
self.currentPosition+1,
|
self.currentPosition+1,
|
||||||
convert_PKC_to_listitem(listitem),
|
convert_PKC_to_listitem(listitem),
|
||||||
playurl,
|
file=playurl,
|
||||||
kodi_item={'id': kodi_id, 'type': kodi_type})
|
kodi_item={'id': kodi_id, 'type': kodi_type})
|
||||||
else:
|
else:
|
||||||
# Full metadata$
|
# Full metadata$
|
||||||
|
|
|
@ -75,6 +75,7 @@ class Playqueue_Object(Playlist_Object_Baseclase):
|
||||||
class Playlist_Item(object):
|
class Playlist_Item(object):
|
||||||
ID = None # Plex playlist/playqueue id, e.g. playQueueItemID
|
ID = None # Plex playlist/playqueue id, e.g. playQueueItemID
|
||||||
plex_id = None # Plex unique item id, "ratingKey"
|
plex_id = None # Plex unique item id, "ratingKey"
|
||||||
|
plex_type = None # Plex type, e.g. 'movie', 'clip'
|
||||||
plex_UUID = None # Plex librarySectionUUID
|
plex_UUID = None # Plex librarySectionUUID
|
||||||
kodi_id = None # Kodi unique kodi id (unique only within type!)
|
kodi_id = None # Kodi unique kodi id (unique only within type!)
|
||||||
kodi_type = None # Kodi type: 'movie'
|
kodi_type = None # Kodi type: 'movie'
|
||||||
|
@ -102,20 +103,22 @@ def playlist_item_from_kodi(kodi_item):
|
||||||
"""
|
"""
|
||||||
item = Playlist_Item()
|
item = Playlist_Item()
|
||||||
item.kodi_id = kodi_item.get('id')
|
item.kodi_id = kodi_item.get('id')
|
||||||
|
item.kodi_type = kodi_item.get('type')
|
||||||
if item.kodi_id:
|
if item.kodi_id:
|
||||||
with plexdb.Get_Plex_DB() as plex_db:
|
with plexdb.Get_Plex_DB() as plex_db:
|
||||||
plex_dbitem = plex_db.getItem_byKodiId(kodi_item['id'],
|
plex_dbitem = plex_db.getItem_byKodiId(kodi_item['id'],
|
||||||
kodi_item['type'])
|
kodi_item['type'])
|
||||||
try:
|
try:
|
||||||
item.plex_id = plex_dbitem[0]
|
item.plex_id = plex_dbitem[0]
|
||||||
|
item.plex_type = plex_dbitem[2]
|
||||||
item.plex_UUID = plex_dbitem[0] # we dont need the uuid yet :-)
|
item.plex_UUID = plex_dbitem[0] # we dont need the uuid yet :-)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
item.file = kodi_item.get('file')
|
item.file = kodi_item.get('file')
|
||||||
if item.file is not None and item.plex_id is None:
|
if item.plex_id is None and item.file is not None:
|
||||||
item.plex_id = dict(
|
query = dict(parse_qsl(urlsplit(item.file).query))
|
||||||
parse_qsl(urlsplit(item.file).query)).get('plex_id')
|
item.plex_id = query.get('plex_id')
|
||||||
item.kodi_type = kodi_item.get('type')
|
item.plex_type = query.get('itemType')
|
||||||
if item.plex_id is None:
|
if item.plex_id is None:
|
||||||
item.uri = 'library://whatever/item/%s' % quote(item.file, safe='')
|
item.uri = 'library://whatever/item/%s' % quote(item.file, safe='')
|
||||||
else:
|
else:
|
||||||
|
@ -137,6 +140,7 @@ def playlist_item_from_plex(plex_id):
|
||||||
with plexdb.Get_Plex_DB() as plex_db:
|
with plexdb.Get_Plex_DB() as plex_db:
|
||||||
plex_dbitem = plex_db.getItem_byId(plex_id)
|
plex_dbitem = plex_db.getItem_byId(plex_id)
|
||||||
try:
|
try:
|
||||||
|
item.plex_type = plex_dbitem[5]
|
||||||
item.kodi_id = plex_dbitem[0]
|
item.kodi_id = plex_dbitem[0]
|
||||||
item.kodi_type = plex_dbitem[4]
|
item.kodi_type = plex_dbitem[4]
|
||||||
except:
|
except:
|
||||||
|
@ -155,6 +159,7 @@ def playlist_item_from_xml(playlist, xml_video_element):
|
||||||
item = Playlist_Item()
|
item = Playlist_Item()
|
||||||
api = API(xml_video_element)
|
api = API(xml_video_element)
|
||||||
item.plex_id = api.getRatingKey()
|
item.plex_id = api.getRatingKey()
|
||||||
|
item.plex_type = api.getType()
|
||||||
item.ID = xml_video_element.attrib['%sItemID' % playlist.kind]
|
item.ID = xml_video_element.attrib['%sItemID' % playlist.kind]
|
||||||
item.guid = xml_video_element.attrib.get('guid')
|
item.guid = xml_video_element.attrib.get('guid')
|
||||||
if item.guid is not None:
|
if item.guid is not None:
|
||||||
|
@ -314,8 +319,6 @@ def add_item_to_PMS_playlist(playlist, pos, plex_id=None, kodi_item=None):
|
||||||
|
|
||||||
WILL ALSO UPDATE OUR PLAYLISTS
|
WILL ALSO UPDATE OUR PLAYLISTS
|
||||||
"""
|
"""
|
||||||
log.debug('Adding new item plex_id: %s, kodi_item: %s on the Plex side at '
|
|
||||||
'position %s for %s' % (plex_id, kodi_item, pos, playlist))
|
|
||||||
if plex_id:
|
if plex_id:
|
||||||
try:
|
try:
|
||||||
item = playlist_item_from_plex(plex_id)
|
item = playlist_item_from_plex(plex_id)
|
||||||
|
@ -532,9 +535,10 @@ def add_listitem_to_Kodi_playlist(playlist, pos, listitem, file,
|
||||||
# We need to add this to our internal queue as well
|
# We need to add this to our internal queue as well
|
||||||
if xml_video_element is not None:
|
if xml_video_element is not None:
|
||||||
item = playlist_item_from_xml(playlist, xml_video_element)
|
item = playlist_item_from_xml(playlist, xml_video_element)
|
||||||
item.file = file
|
|
||||||
else:
|
else:
|
||||||
item = playlist_item_from_kodi(kodi_item)
|
item = playlist_item_from_kodi(kodi_item)
|
||||||
|
if file is not None:
|
||||||
|
item.file = file
|
||||||
playlist.items.insert(pos, item)
|
playlist.items.insert(pos, item)
|
||||||
log.debug('Done inserting for %s' % playlist)
|
log.debug('Done inserting for %s' % playlist)
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ log = logging.getLogger("PLEX."+__name__)
|
||||||
|
|
||||||
# Lock used for playqueue manipulations
|
# Lock used for playqueue manipulations
|
||||||
lock = RLock()
|
lock = RLock()
|
||||||
|
PLUGIN = 'plugin://%s' % v.ADDON_ID
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
@ -147,11 +148,19 @@ class Playqueue(Thread):
|
||||||
log.debug('Comparing new Kodi playqueue %s with our play queue %s'
|
log.debug('Comparing new Kodi playqueue %s with our play queue %s'
|
||||||
% (new, old))
|
% (new, old))
|
||||||
for i, new_item in enumerate(new):
|
for i, new_item in enumerate(new):
|
||||||
|
if (new_item['file'].startswith('plugin://') and
|
||||||
|
not new_item['file'].startswith(PLUGIN)):
|
||||||
|
# Ignore new media added by other addons
|
||||||
|
continue
|
||||||
for j, old_item in enumerate(old):
|
for j, old_item in enumerate(old):
|
||||||
if self.threadStopped():
|
if self.threadStopped():
|
||||||
# Chances are that we got an empty Kodi playlist due to
|
# Chances are that we got an empty Kodi playlist due to
|
||||||
# Kodi exit
|
# Kodi exit
|
||||||
return
|
return
|
||||||
|
if (old_item['file'].startswith('plugin://') and
|
||||||
|
not old_item['file'].startswith(PLUGIN)):
|
||||||
|
# Ignore media by other addons
|
||||||
|
continue
|
||||||
if new_item.get('id') is None:
|
if new_item.get('id') is None:
|
||||||
identical = old_item.file == new_item['file']
|
identical = old_item.file == new_item['file']
|
||||||
else:
|
else:
|
||||||
|
@ -206,5 +215,9 @@ class Playqueue(Thread):
|
||||||
# compare old and new playqueue
|
# compare old and new playqueue
|
||||||
self._compare_playqueues(playqueue, kodi_playqueue)
|
self._compare_playqueues(playqueue, kodi_playqueue)
|
||||||
playqueue.old_kodi_pl = list(kodi_playqueue)
|
playqueue.old_kodi_pl = list(kodi_playqueue)
|
||||||
sleep(50)
|
# Still sleep a bit so Kodi does not become
|
||||||
|
# unresponsive
|
||||||
|
sleep(10)
|
||||||
|
continue
|
||||||
|
sleep(200)
|
||||||
log.info("----===## PlayQueue client stopped ##===----")
|
log.info("----===## PlayQueue client stopped ##===----")
|
||||||
|
|
|
@ -122,7 +122,9 @@ class SubscriptionManager:
|
||||||
ret += ' shuffle="%s"' % info['shuffle']
|
ret += ' shuffle="%s"' % info['shuffle']
|
||||||
ret += ' mute="%s"' % self.mute
|
ret += ' mute="%s"' % self.mute
|
||||||
ret += ' repeat="%s"' % info['repeat']
|
ret += ' repeat="%s"' % info['repeat']
|
||||||
|
ret += ' itemType="%s"' % info['itemType']
|
||||||
# Might need an update in the future
|
# Might need an update in the future
|
||||||
|
if ptype == 'video':
|
||||||
ret += ' subtitleStreamID="-1"'
|
ret += ' subtitleStreamID="-1"'
|
||||||
ret += ' audioStreamID="-1"'
|
ret += ' audioStreamID="-1"'
|
||||||
|
|
||||||
|
@ -225,7 +227,8 @@ class SubscriptionManager:
|
||||||
props = self.js.jsonrpc(
|
props = self.js.jsonrpc(
|
||||||
"Player.GetProperties",
|
"Player.GetProperties",
|
||||||
{"playerid": playerid,
|
{"playerid": playerid,
|
||||||
"properties": ["time",
|
"properties": ["type",
|
||||||
|
"time",
|
||||||
"totaltime",
|
"totaltime",
|
||||||
"speed",
|
"speed",
|
||||||
"shuffled",
|
"shuffled",
|
||||||
|
@ -244,12 +247,13 @@ class SubscriptionManager:
|
||||||
{"playerid": playerid,
|
{"playerid": playerid,
|
||||||
"properties": ["position"]})['position']
|
"properties": ["position"]})['position']
|
||||||
try:
|
try:
|
||||||
info['playQueueItemID'] = playqueue.items[pos].ID
|
info['playQueueItemID'] = playqueue.items[pos].ID or 'null'
|
||||||
info['guid'] = playqueue.items[pos].guid
|
info['guid'] = playqueue.items[pos].guid or 'null'
|
||||||
info['playQueueID'] = playqueue.ID
|
info['playQueueID'] = playqueue.ID or 'null'
|
||||||
info['playQueueVersion'] = playqueue.version
|
info['playQueueVersion'] = playqueue.version or 'null'
|
||||||
|
info['itemType'] = playqueue.items[pos].plex_type or 'null'
|
||||||
except:
|
except:
|
||||||
pass
|
info['itemType'] = props.get('type') or 'null'
|
||||||
except:
|
except:
|
||||||
import traceback
|
import traceback
|
||||||
log.error("Traceback:\n%s" % traceback.format_exc())
|
log.error("Traceback:\n%s" % traceback.format_exc())
|
||||||
|
|
|
@ -258,10 +258,11 @@ class Plex_DB_Functions():
|
||||||
|
|
||||||
def getItem_byKodiId(self, kodi_id, kodi_type):
|
def getItem_byKodiId(self, kodi_id, kodi_type):
|
||||||
"""
|
"""
|
||||||
Returns the tuple (plex_id, parent_id) for kodi_id and kodi_type
|
Returns the tuple (plex_id, parent_id, plex_type) for kodi_id and
|
||||||
|
kodi_type
|
||||||
"""
|
"""
|
||||||
query = '''
|
query = '''
|
||||||
SELECT plex_id, parent_id
|
SELECT plex_id, parent_id, plex_type
|
||||||
FROM plex
|
FROM plex
|
||||||
WHERE kodi_id = ?
|
WHERE kodi_id = ?
|
||||||
AND kodi_type = ?
|
AND kodi_type = ?
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
###############################################################################
|
###############################################################################
|
||||||
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
|
||||||
|
from xbmcvfs import exists
|
||||||
|
|
||||||
|
|
||||||
from utils import window, settings, language as lang, ThreadMethods, \
|
from utils import window, settings, language as lang, ThreadMethods, \
|
||||||
|
@ -211,10 +211,9 @@ class UserClient(threading.Thread):
|
||||||
|
|
||||||
# Get /profile/addon_data
|
# Get /profile/addon_data
|
||||||
addondir = xbmc.translatePath(self.addon.getAddonInfo('profile'))
|
addondir = xbmc.translatePath(self.addon.getAddonInfo('profile'))
|
||||||
hasSettings = exists("%ssettings.xml" % addondir)
|
|
||||||
|
|
||||||
# If there's no settings.xml
|
# If there's no settings.xml
|
||||||
if not hasSettings:
|
if not exists("%ssettings.xml" % addondir):
|
||||||
log.error("Error, no settings.xml found.")
|
log.error("Error, no settings.xml found.")
|
||||||
self.auth = False
|
self.auth = False
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -13,17 +13,18 @@ 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.path import exists, join
|
from os.path import join
|
||||||
from os import remove, makedirs, walk
|
from os import remove, walk, makedirs
|
||||||
from shutil import rmtree
|
from shutil import rmtree
|
||||||
from urllib import quote_plus
|
from urllib import quote_plus
|
||||||
|
|
||||||
import xbmc
|
import xbmc
|
||||||
import xbmcaddon
|
import xbmcaddon
|
||||||
import xbmcgui
|
import xbmcgui
|
||||||
|
from xbmcvfs import exists, delete
|
||||||
|
|
||||||
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, KODI_PROFILE
|
DB_PLEX_PATH, KODI_PROFILE, KODIVERSION
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
@ -91,6 +92,30 @@ def settings(setting, value=None):
|
||||||
return tryDecode(addon.getSetting(setting))
|
return tryDecode(addon.getSetting(setting))
|
||||||
|
|
||||||
|
|
||||||
|
def exists_dir(path):
|
||||||
|
"""
|
||||||
|
Safe way to check whether the directory path exists already (broken in Kodi
|
||||||
|
<17)
|
||||||
|
|
||||||
|
Feed with encoded string
|
||||||
|
"""
|
||||||
|
if KODIVERSION >= 17:
|
||||||
|
answ = exists(path)
|
||||||
|
else:
|
||||||
|
dummyfile = join(path, 'dummyfile.txt')
|
||||||
|
try:
|
||||||
|
with open(dummyfile, 'w') as f:
|
||||||
|
f.write('text')
|
||||||
|
except IOError:
|
||||||
|
# folder does not exist yet
|
||||||
|
answ = 0
|
||||||
|
else:
|
||||||
|
# Folder exists. Delete file again.
|
||||||
|
delete(dummyfile)
|
||||||
|
answ = 1
|
||||||
|
return answ
|
||||||
|
|
||||||
|
|
||||||
def language(stringid):
|
def language(stringid):
|
||||||
# Central string retrieval
|
# Central string retrieval
|
||||||
return ADDON.getLocalizedString(stringid)
|
return ADDON.getLocalizedString(stringid)
|
||||||
|
@ -322,7 +347,7 @@ def reset():
|
||||||
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)
|
cursor.execute("DELETE FROM ?", (tablename,))
|
||||||
connection.commit()
|
connection.commit()
|
||||||
cursor.close()
|
cursor.close()
|
||||||
|
|
||||||
|
@ -335,7 +360,7 @@ def reset():
|
||||||
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)
|
cursor.execute("DELETE FROM ?", (tablename, ))
|
||||||
connection.commit()
|
connection.commit()
|
||||||
cursor.close()
|
cursor.close()
|
||||||
|
|
||||||
|
@ -348,7 +373,7 @@ def reset():
|
||||||
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)
|
cursor.execute("DELETE FROM ?", (tablename, ))
|
||||||
cursor.execute('DROP table IF EXISTS plex')
|
cursor.execute('DROP table IF EXISTS plex')
|
||||||
cursor.execute('DROP table IF EXISTS view')
|
cursor.execute('DROP table IF EXISTS view')
|
||||||
connection.commit()
|
connection.commit()
|
||||||
|
@ -372,7 +397,7 @@ def reset():
|
||||||
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)
|
cursor.execute("DELETE FROM ?", (tableName, ))
|
||||||
connection.commit()
|
connection.commit()
|
||||||
cursor.close()
|
cursor.close()
|
||||||
|
|
||||||
|
@ -542,8 +567,10 @@ def __setSubElement(element, subelement):
|
||||||
def advancedsettings_xml(node_list, new_value=None, attrib=None,
|
def advancedsettings_xml(node_list, new_value=None, attrib=None,
|
||||||
force_create=False):
|
force_create=False):
|
||||||
"""
|
"""
|
||||||
Returns the etree element for nodelist (if it exists) and the tree. None if
|
Returns
|
||||||
not set
|
etree element, tree
|
||||||
|
or
|
||||||
|
None, None
|
||||||
|
|
||||||
node_list is a list of node names starting from the outside, ignoring the
|
node_list is a list of node names starting from the outside, ignoring the
|
||||||
outter advancedsettings. Example nodelist=['video', 'busydialogdelayms']
|
outter advancedsettings. Example nodelist=['video', 'busydialogdelayms']
|
||||||
|
@ -576,7 +603,7 @@ def advancedsettings_xml(node_list, new_value=None, attrib=None,
|
||||||
# Document is blank or missing
|
# Document is blank or missing
|
||||||
if new_value is None and attrib is None and force_create is False:
|
if new_value is None and attrib is None and force_create is False:
|
||||||
log.debug('Could not parse advancedsettings.xml, returning None')
|
log.debug('Could not parse advancedsettings.xml, returning None')
|
||||||
return
|
return None, None
|
||||||
# Create topmost xml entry
|
# Create topmost xml entry
|
||||||
tree = etree.ElementTree(element=etree.Element('advancedsettings'))
|
tree = etree.ElementTree(element=etree.Element('advancedsettings'))
|
||||||
root = tree.getroot()
|
root = tree.getroot()
|
||||||
|
|
|
@ -3,13 +3,14 @@
|
||||||
import logging
|
import logging
|
||||||
from shutil import copytree
|
from shutil import copytree
|
||||||
import xml.etree.ElementTree as etree
|
import xml.etree.ElementTree as etree
|
||||||
|
from os import remove, listdir, makedirs
|
||||||
|
from os.path import isfile, join
|
||||||
|
|
||||||
import xbmc
|
import xbmc
|
||||||
from os import remove, makedirs, listdir
|
from xbmcvfs import exists
|
||||||
from os.path import exists, isfile, join
|
|
||||||
|
|
||||||
from utils import window, settings, language as lang, tryEncode, indent, \
|
from utils import window, settings, language as lang, tryEncode, indent, \
|
||||||
normalize_nodes
|
normalize_nodes, exists_dir
|
||||||
import variables as v
|
import variables as v
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
@ -74,14 +75,14 @@ class VideoNodes(object):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Verify the video directory
|
# Verify the video directory
|
||||||
if exists(path) is False:
|
if not exists_dir(path):
|
||||||
copytree(
|
copytree(
|
||||||
src=xbmc.translatePath("special://xbmc/system/library/video"),
|
src=xbmc.translatePath("special://xbmc/system/library/video"),
|
||||||
dst=xbmc.translatePath("special://profile/library/video"))
|
dst=xbmc.translatePath("special://profile/library/video"))
|
||||||
|
|
||||||
# Create the node directory
|
# Create the node directory
|
||||||
if mediatype != "photos":
|
if mediatype != "photos":
|
||||||
if exists(nodepath) is False:
|
if not exists_dir(nodepath):
|
||||||
# folder does not exist yet
|
# folder does not exist yet
|
||||||
log.debug('Creating folder %s' % nodepath)
|
log.debug('Creating folder %s' % nodepath)
|
||||||
makedirs(nodepath)
|
makedirs(nodepath)
|
||||||
|
@ -387,7 +388,7 @@ 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 exists(nodepath):
|
if not exists_dir(nodepath):
|
||||||
# We need to copy over the default items
|
# We need to copy over the default items
|
||||||
copytree(
|
copytree(
|
||||||
src=xbmc.translatePath("special://xbmc/system/library/video"),
|
src=xbmc.translatePath("special://xbmc/system/library/video"),
|
||||||
|
|
Loading…
Reference in a new issue