Merge branch 'hotfixes'
This commit is contained in:
commit
473bf6f5ed
15 changed files with 120 additions and 99 deletions
|
@ -1,5 +1,5 @@
|
||||||
[![stable version](https://img.shields.io/badge/stable_version-1.8.9-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.8.9-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.8.9-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.8.10-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)
|
||||||
|
|
15
addon.xml
15
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.8.9" provider-name="croneter">
|
<addon id="plugin.video.plexkodiconnect" name="PlexKodiConnect" version="1.8.10" 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" />
|
||||||
|
@ -59,7 +59,18 @@
|
||||||
<summary lang="da_DK">Indbygget Integration af Plex i Kodi</summary>
|
<summary lang="da_DK">Indbygget Integration af Plex i Kodi</summary>
|
||||||
<description lang="da_DK">Tilslut Kodi til din Plex Media Server. Dette plugin forudsætter, at du administrere alle dine videoer med Plex (og ikke med Kodi). Du kan miste data som allerede er gemt i Kodi video og musik-databaser (dette plugin ændrer direkte i dem). Brug på eget ansvar!</description>
|
<description lang="da_DK">Tilslut Kodi til din Plex Media Server. Dette plugin forudsætter, at du administrere alle dine videoer med Plex (og ikke med Kodi). Du kan miste data som allerede er gemt i Kodi video og musik-databaser (dette plugin ændrer direkte i dem). Brug på eget ansvar!</description>
|
||||||
<disclaimer lang="da_DK">Brug på eget ansvar</disclaimer>
|
<disclaimer lang="da_DK">Brug på eget ansvar</disclaimer>
|
||||||
<news>version 1.8.9
|
<news>version 1.8.10 (beta only):
|
||||||
|
- Vastly improve sync speed for music
|
||||||
|
- Never show library sync dialog if media is playing
|
||||||
|
- Improvements to sync dialog
|
||||||
|
- Fix stop synching if path not found
|
||||||
|
- Resume aborted sync on PKC settings change
|
||||||
|
- Don't quit library sync if failed repeatedly
|
||||||
|
- Verify path for every Plex library on install sync
|
||||||
|
- More descriptive downloadable subtitles
|
||||||
|
- More code fixes and optimization
|
||||||
|
|
||||||
|
version 1.8.9
|
||||||
- Fix playback not starting in some circumstances
|
- Fix playback not starting in some circumstances
|
||||||
- Deactivate some annoying popups on install
|
- Deactivate some annoying popups on install
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,14 @@
|
||||||
|
version 1.8.10 (beta only):
|
||||||
|
- Vastly improve sync speed for music
|
||||||
|
- Never show library sync dialog if media is playing
|
||||||
|
- Improvements to sync dialog
|
||||||
|
- Fix stop synching if path not found
|
||||||
|
- Resume aborted sync on PKC settings change
|
||||||
|
- Don't quit library sync if failed repeatedly
|
||||||
|
- Verify path for every Plex library on install sync
|
||||||
|
- More descriptive downloadable subtitles
|
||||||
|
- More code fixes and optimization
|
||||||
|
|
||||||
version 1.8.9
|
version 1.8.9
|
||||||
- Fix playback not starting in some circumstances
|
- Fix playback not starting in some circumstances
|
||||||
- Deactivate some annoying popups on install
|
- Deactivate some annoying popups on install
|
||||||
|
|
|
@ -2357,11 +2357,11 @@ class API():
|
||||||
# ext = stream.attrib.get('format')
|
# ext = stream.attrib.get('format')
|
||||||
if key:
|
if key:
|
||||||
# We do know the language - temporarily download
|
# We do know the language - temporarily download
|
||||||
if stream.attrib.get('languageCode') is not None:
|
if stream.attrib.get('language') is not None:
|
||||||
path = self.download_external_subtitles(
|
path = self.download_external_subtitles(
|
||||||
"{server}%s" % key,
|
"{server}%s" % key,
|
||||||
"subtitle%02d.%s.%s" % (fileindex,
|
"subtitle%02d.%s.%s" % (fileindex,
|
||||||
stream.attrib['languageCode'],
|
stream.attrib['language'],
|
||||||
stream.attrib['codec']))
|
stream.attrib['codec']))
|
||||||
fileindex += 1
|
fileindex += 1
|
||||||
# We don't know the language - no need to download
|
# We don't know the language - no need to download
|
||||||
|
@ -2589,7 +2589,7 @@ class API():
|
||||||
elif window('replaceSMB') == 'true':
|
elif window('replaceSMB') == 'true':
|
||||||
if path.startswith('\\\\'):
|
if path.startswith('\\\\'):
|
||||||
path = 'smb:' + path.replace('\\', '/')
|
path = 'smb:' + path.replace('\\', '/')
|
||||||
if ((window('plex_pathverified') == 'true' and forceCheck is False) or
|
if ((state.PATH_VERIFIED and forceCheck is False) or
|
||||||
omitCheck is True):
|
omitCheck is True):
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
@ -2617,12 +2617,12 @@ class API():
|
||||||
if self.askToValidate(path):
|
if self.askToValidate(path):
|
||||||
state.STOP_SYNC = True
|
state.STOP_SYNC = True
|
||||||
path = None
|
path = None
|
||||||
window('plex_pathverified', value='true')
|
state.PATH_VERIFIED = True
|
||||||
else:
|
else:
|
||||||
path = None
|
path = None
|
||||||
elif forceCheck is False:
|
elif forceCheck is False:
|
||||||
if window('plex_pathverified') != 'true':
|
# Only set the flag if we were not force-checking the path
|
||||||
window('plex_pathverified', value='true')
|
state.PATH_VERIFIED = True
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def askToValidate(self, url):
|
def askToValidate(self, url):
|
||||||
|
|
|
@ -126,8 +126,9 @@ def double_urldecode(text):
|
||||||
return unquote(unquote(text))
|
return unquote(unquote(text))
|
||||||
|
|
||||||
|
|
||||||
@thread_methods(add_stops=['STOP_SYNC'],
|
@thread_methods(add_suspends=['SUSPEND_LIBRARY_THREAD',
|
||||||
add_suspends=['SUSPEND_LIBRARY_THREAD', 'DB_SCAN'])
|
'DB_SCAN',
|
||||||
|
'STOP_SYNC'])
|
||||||
class Image_Cache_Thread(Thread):
|
class Image_Cache_Thread(Thread):
|
||||||
xbmc_host = 'localhost'
|
xbmc_host = 'localhost'
|
||||||
xbmc_port, xbmc_username, xbmc_password = setKodiWebServerDetails()
|
xbmc_port, xbmc_username, xbmc_password = setKodiWebServerDetails()
|
||||||
|
|
|
@ -1729,7 +1729,7 @@ class Music(Items):
|
||||||
if album is None or album == 401:
|
if album is None or album == 401:
|
||||||
log.error('Could not download album, abort')
|
log.error('Could not download album, abort')
|
||||||
return
|
return
|
||||||
self.add_updateAlbum(album[0])
|
self.add_updateAlbum(album[0], children=[item])
|
||||||
plex_dbalbum = plex_db.getItem_byId(plex_albumId)
|
plex_dbalbum = plex_db.getItem_byId(plex_albumId)
|
||||||
try:
|
try:
|
||||||
albumid = plex_dbalbum[0]
|
albumid = plex_dbalbum[0]
|
||||||
|
|
|
@ -47,6 +47,11 @@ class KodiMonitor(Monitor):
|
||||||
"""
|
"""
|
||||||
Monitor the PKC settings for changes made by the user
|
Monitor the PKC settings for changes made by the user
|
||||||
"""
|
"""
|
||||||
|
log.debug('PKC settings change detected')
|
||||||
|
# Assume that the user changed the settings so that we can now find the
|
||||||
|
# path to all media files
|
||||||
|
state.STOP_SYNC = False
|
||||||
|
state.PATH_VERIFIED = False
|
||||||
# settings: window-variable
|
# settings: window-variable
|
||||||
items = {
|
items = {
|
||||||
'logLevel': 'plex_logLevel',
|
'logLevel': 'plex_logLevel',
|
||||||
|
|
|
@ -17,8 +17,9 @@ log = getLogger("PLEX."+__name__)
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
@thread_methods(add_suspends=['SUSPEND_LIBRARY_THREAD', 'DB_SCAN'],
|
@thread_methods(add_suspends=['SUSPEND_LIBRARY_THREAD',
|
||||||
add_stops=['STOP_SYNC'])
|
'DB_SCAN',
|
||||||
|
'STOP_SYNC'])
|
||||||
class Process_Fanart_Thread(Thread):
|
class Process_Fanart_Thread(Thread):
|
||||||
"""
|
"""
|
||||||
Threaded download of additional fanart in the background
|
Threaded download of additional fanart in the background
|
||||||
|
|
|
@ -16,7 +16,7 @@ log = getLogger("PLEX."+__name__)
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
@thread_methods(add_stops=['SUSPEND_LIBRARY_THREAD'])
|
@thread_methods(add_stops=['SUSPEND_LIBRARY_THREAD', 'STOP_SYNC'])
|
||||||
class Threaded_Get_Metadata(Thread):
|
class Threaded_Get_Metadata(Thread):
|
||||||
"""
|
"""
|
||||||
Threaded download of Plex XML metadata for a certain library item.
|
Threaded download of Plex XML metadata for a certain library item.
|
||||||
|
@ -115,17 +115,9 @@ class Threaded_Get_Metadata(Thread):
|
||||||
except (TypeError, IndexError, AttributeError):
|
except (TypeError, IndexError, AttributeError):
|
||||||
log.error('Could not get children for Plex id %s'
|
log.error('Could not get children for Plex id %s'
|
||||||
% item['itemId'])
|
% item['itemId'])
|
||||||
else:
|
|
||||||
item['children'] = []
|
item['children'] = []
|
||||||
for child in children_xml:
|
else:
|
||||||
child_xml = GetPlexMetadata(child.attrib['ratingKey'])
|
item['children'] = children_xml
|
||||||
try:
|
|
||||||
child_xml[0].attrib
|
|
||||||
except (TypeError, IndexError, AttributeError):
|
|
||||||
log.error('Could not get child for Plex id %s'
|
|
||||||
% child.attrib['ratingKey'])
|
|
||||||
else:
|
|
||||||
item['children'].append(child_xml[0])
|
|
||||||
|
|
||||||
# place item into out queue
|
# place item into out queue
|
||||||
out_queue.put(item)
|
out_queue.put(item)
|
||||||
|
|
|
@ -15,7 +15,7 @@ log = getLogger("PLEX."+__name__)
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
@thread_methods(add_stops=['SUSPEND_LIBRARY_THREAD'])
|
@thread_methods(add_stops=['SUSPEND_LIBRARY_THREAD', 'STOP_SYNC'])
|
||||||
class Threaded_Process_Metadata(Thread):
|
class Threaded_Process_Metadata(Thread):
|
||||||
"""
|
"""
|
||||||
Not yet implemented for more than 1 thread - if ever. Only to be called by
|
Not yet implemented for more than 1 thread - if ever. Only to be called by
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
from threading import Thread, Lock
|
from threading import Thread, Lock
|
||||||
|
|
||||||
from xbmc import sleep
|
from xbmc import sleep, Player
|
||||||
|
from xbmcgui import DialogProgressBG
|
||||||
|
|
||||||
from utils import thread_methods, language as lang
|
from utils import thread_methods, language as lang
|
||||||
|
|
||||||
|
@ -18,18 +19,17 @@ LOCK = Lock()
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
@thread_methods(add_stops=['SUSPEND_LIBRARY_THREAD'])
|
@thread_methods(add_stops=['SUSPEND_LIBRARY_THREAD', 'STOP_SYNC'])
|
||||||
class Threaded_Show_Sync_Info(Thread):
|
class Threaded_Show_Sync_Info(Thread):
|
||||||
"""
|
"""
|
||||||
Threaded class to show the Kodi statusbar of the metadata download.
|
Threaded class to show the Kodi statusbar of the metadata download.
|
||||||
|
|
||||||
Input:
|
Input:
|
||||||
dialog xbmcgui.DialogProgressBG() object to show progress
|
|
||||||
total: Total number of items to get
|
total: Total number of items to get
|
||||||
|
item_type:
|
||||||
"""
|
"""
|
||||||
def __init__(self, dialog, total, item_type):
|
def __init__(self, total, item_type):
|
||||||
self.total = total
|
self.total = total
|
||||||
self.dialog = dialog
|
|
||||||
self.item_type = item_type
|
self.item_type = item_type
|
||||||
Thread.__init__(self)
|
Thread.__init__(self)
|
||||||
|
|
||||||
|
@ -51,14 +51,15 @@ class Threaded_Show_Sync_Info(Thread):
|
||||||
log.debug('Show sync info thread started')
|
log.debug('Show sync info thread started')
|
||||||
# cache local variables because it's faster
|
# cache local variables because it's faster
|
||||||
total = self.total
|
total = self.total
|
||||||
dialog = self.dialog
|
dialog = DialogProgressBG('dialoglogProgressBG')
|
||||||
thread_stopped = self.thread_stopped
|
thread_stopped = self.thread_stopped
|
||||||
dialog.create("%s %s: %s %s"
|
dialog.create("%s %s: %s %s"
|
||||||
% (lang(39714), self.item_type, str(total), lang(39715)))
|
% (lang(39714), self.item_type, str(total), lang(39715)))
|
||||||
|
player = Player()
|
||||||
|
|
||||||
total = 2 * total
|
total = 2 * total
|
||||||
totalProgress = 0
|
totalProgress = 0
|
||||||
while thread_stopped() is False:
|
while thread_stopped() is False and not player.isPlaying():
|
||||||
with LOCK:
|
with LOCK:
|
||||||
get_progress = GET_METADATA_COUNT
|
get_progress = GET_METADATA_COUNT
|
||||||
process_progress = PROCESS_METADATA_COUNT
|
process_progress = PROCESS_METADATA_COUNT
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
###############################################################################
|
###############################################################################
|
||||||
import logging
|
from logging import getLogger
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
import Queue
|
import Queue
|
||||||
from random import shuffle
|
from random import shuffle
|
||||||
|
|
||||||
import xbmc
|
import xbmc
|
||||||
import xbmcgui
|
|
||||||
from xbmcvfs import exists
|
from xbmcvfs import exists
|
||||||
|
|
||||||
from utils import window, settings, getUnixTimestamp, sourcesXML,\
|
from utils import window, settings, getUnixTimestamp, sourcesXML,\
|
||||||
|
@ -33,13 +32,12 @@ import state
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
log = logging.getLogger("PLEX."+__name__)
|
log = getLogger("PLEX."+__name__)
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
@thread_methods(add_stops=['STOP_SYNC'],
|
@thread_methods(add_suspends=['SUSPEND_LIBRARY_THREAD', 'STOP_SYNC'])
|
||||||
add_suspends=['SUSPEND_LIBRARY_THREAD'])
|
|
||||||
class LibrarySync(Thread):
|
class LibrarySync(Thread):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
|
@ -63,7 +61,7 @@ class LibrarySync(Thread):
|
||||||
|
|
||||||
self.user = userclient.UserClient()
|
self.user = userclient.UserClient()
|
||||||
self.vnodes = videonodes.VideoNodes()
|
self.vnodes = videonodes.VideoNodes()
|
||||||
self.dialog = xbmcgui.Dialog()
|
self.xbmcplayer = xbmc.Player()
|
||||||
|
|
||||||
self.syncThreadNumber = int(settings('syncThreadNumber'))
|
self.syncThreadNumber = int(settings('syncThreadNumber'))
|
||||||
self.installSyncDone = settings('SyncInstallRunDone') == 'true'
|
self.installSyncDone = settings('SyncInstallRunDone') == 'true'
|
||||||
|
@ -94,23 +92,23 @@ class LibrarySync(Thread):
|
||||||
|
|
||||||
forced: always show popup, even if user setting to off
|
forced: always show popup, even if user setting to off
|
||||||
"""
|
"""
|
||||||
if settings('dbSyncIndicator') != 'true':
|
if self.xbmcplayer.isPlaying():
|
||||||
|
# Don't show any dialog if media is playing
|
||||||
|
return
|
||||||
|
if window('dbSyncIndicator') != 'true':
|
||||||
if not forced:
|
if not forced:
|
||||||
return
|
return
|
||||||
if icon == "plex":
|
if icon == "plex":
|
||||||
self.dialog.notification(
|
dialog('notification',
|
||||||
lang(29999),
|
heading='{plex}',
|
||||||
message,
|
message=message,
|
||||||
"special://home/addons/plugin.video.plexkodiconnect/icon.png",
|
icon='{plex}',
|
||||||
5000,
|
sound=False)
|
||||||
False)
|
|
||||||
elif icon == "error":
|
elif icon == "error":
|
||||||
self.dialog.notification(
|
dialog('notification',
|
||||||
lang(29999),
|
heading='{plex}',
|
||||||
message,
|
message=message,
|
||||||
xbmcgui.NOTIFICATION_ERROR,
|
type='{error}')
|
||||||
7000,
|
|
||||||
True)
|
|
||||||
|
|
||||||
def syncPMStime(self):
|
def syncPMStime(self):
|
||||||
"""
|
"""
|
||||||
|
@ -298,11 +296,9 @@ class LibrarySync(Thread):
|
||||||
|
|
||||||
# Do the processing
|
# Do the processing
|
||||||
for itemtype in process:
|
for itemtype in process:
|
||||||
if self.thread_stopped():
|
if (self.thread_stopped() or
|
||||||
xbmc.executebuiltin('InhibitIdleShutdown(false)')
|
self.thread_suspended() or
|
||||||
setScreensaver(value=screensaver)
|
not process[itemtype]()):
|
||||||
return False
|
|
||||||
if not process[itemtype]():
|
|
||||||
xbmc.executebuiltin('InhibitIdleShutdown(false)')
|
xbmc.executebuiltin('InhibitIdleShutdown(false)')
|
||||||
setScreensaver(value=screensaver)
|
setScreensaver(value=screensaver)
|
||||||
return False
|
return False
|
||||||
|
@ -317,13 +313,13 @@ class LibrarySync(Thread):
|
||||||
setScreensaver(value=screensaver)
|
setScreensaver(value=screensaver)
|
||||||
if window('plex_scancrashed') == 'true':
|
if window('plex_scancrashed') == 'true':
|
||||||
# Show warning if itemtypes.py crashed at some point
|
# Show warning if itemtypes.py crashed at some point
|
||||||
self.dialog.ok(lang(29999), lang(39408))
|
dialog('ok', heading='{plex}', line1=lang(39408))
|
||||||
window('plex_scancrashed', clear=True)
|
window('plex_scancrashed', clear=True)
|
||||||
elif window('plex_scancrashed') == '401':
|
elif window('plex_scancrashed') == '401':
|
||||||
window('plex_scancrashed', clear=True)
|
window('plex_scancrashed', clear=True)
|
||||||
if state.PMS_STATUS not in ('401', 'Auth'):
|
if state.PMS_STATUS not in ('401', 'Auth'):
|
||||||
# Plex server had too much and returned ERROR
|
# Plex server had too much and returned ERROR
|
||||||
self.dialog.ok(lang(29999), lang(39409))
|
dialog('ok', heading='{plex}', line1=lang(39409))
|
||||||
|
|
||||||
# Path hack, so Kodis Information screen works
|
# Path hack, so Kodis Information screen works
|
||||||
with kodidb.GetKodiDB('video') as kodi_db:
|
with kodidb.GetKodiDB('video') as kodi_db:
|
||||||
|
@ -477,7 +473,7 @@ class LibrarySync(Thread):
|
||||||
log.info('Detected new Music library - restarting now')
|
log.info('Detected new Music library - restarting now')
|
||||||
# 'New Plex music library detected. Sorry, but we need to
|
# 'New Plex music library detected. Sorry, but we need to
|
||||||
# restart Kodi now due to the changes made.'
|
# restart Kodi now due to the changes made.'
|
||||||
dialog('ok', lang(29999), lang(39711))
|
dialog('ok', heading='{plex}', line1=lang(39711))
|
||||||
from xbmc import executebuiltin
|
from xbmc import executebuiltin
|
||||||
executebuiltin('RestartApp')
|
executebuiltin('RestartApp')
|
||||||
return False
|
return False
|
||||||
|
@ -740,11 +736,7 @@ class LibrarySync(Thread):
|
||||||
threads.append(thread)
|
threads.append(thread)
|
||||||
# Start one thread to show sync progress ONLY for new PMS items
|
# Start one thread to show sync progress ONLY for new PMS items
|
||||||
if self.new_items_only is True and window('dbSyncIndicator') == 'true':
|
if self.new_items_only is True and window('dbSyncIndicator') == 'true':
|
||||||
dialog = xbmcgui.DialogProgressBG()
|
thread = sync_info.Threaded_Show_Sync_Info(itemNumber, itemType)
|
||||||
thread = sync_info.Threaded_Show_Sync_Info(
|
|
||||||
dialog,
|
|
||||||
itemNumber,
|
|
||||||
itemType)
|
|
||||||
thread.setDaemon(True)
|
thread.setDaemon(True)
|
||||||
thread.start()
|
thread.start()
|
||||||
threads.append(thread)
|
threads.append(thread)
|
||||||
|
@ -803,7 +795,9 @@ class LibrarySync(Thread):
|
||||||
# PROCESS MOVIES #####
|
# PROCESS MOVIES #####
|
||||||
self.updatelist = []
|
self.updatelist = []
|
||||||
for view in views:
|
for view in views:
|
||||||
if self.thread_stopped():
|
if self.installSyncDone is not True:
|
||||||
|
state.PATH_VERIFIED = False
|
||||||
|
if self.thread_stopped() or self.thread_suspended():
|
||||||
return False
|
return False
|
||||||
# Get items per view
|
# Get items per view
|
||||||
viewId = view['id']
|
viewId = view['id']
|
||||||
|
@ -821,10 +815,9 @@ class LibrarySync(Thread):
|
||||||
viewName,
|
viewName,
|
||||||
viewId)
|
viewId)
|
||||||
self.GetAndProcessXMLs(itemType)
|
self.GetAndProcessXMLs(itemType)
|
||||||
log.info("Processed view")
|
|
||||||
# Update viewstate for EVERY item
|
# Update viewstate for EVERY item
|
||||||
for view in views:
|
for view in views:
|
||||||
if self.thread_stopped():
|
if self.thread_stopped() or self.thread_suspended():
|
||||||
return False
|
return False
|
||||||
self.PlexUpdateWatched(view['id'], itemType)
|
self.PlexUpdateWatched(view['id'], itemType)
|
||||||
|
|
||||||
|
@ -896,7 +889,9 @@ class LibrarySync(Thread):
|
||||||
# PROCESS TV Shows #####
|
# PROCESS TV Shows #####
|
||||||
self.updatelist = []
|
self.updatelist = []
|
||||||
for view in views:
|
for view in views:
|
||||||
if self.thread_stopped():
|
if self.installSyncDone is not True:
|
||||||
|
state.PATH_VERIFIED = False
|
||||||
|
if self.thread_stopped() or self.thread_suspended():
|
||||||
return False
|
return False
|
||||||
# Get items per view
|
# Get items per view
|
||||||
viewId = view['id']
|
viewId = view['id']
|
||||||
|
@ -925,7 +920,7 @@ class LibrarySync(Thread):
|
||||||
# PROCESS TV Seasons #####
|
# PROCESS TV Seasons #####
|
||||||
# Cycle through tv shows
|
# Cycle through tv shows
|
||||||
for tvShowId in allPlexTvShowsId:
|
for tvShowId in allPlexTvShowsId:
|
||||||
if self.thread_stopped():
|
if self.thread_stopped() or self.thread_suspended():
|
||||||
return False
|
return False
|
||||||
# Grab all seasons to tvshow from PMS
|
# Grab all seasons to tvshow from PMS
|
||||||
seasons = GetAllPlexChildren(tvShowId)
|
seasons = GetAllPlexChildren(tvShowId)
|
||||||
|
@ -950,7 +945,7 @@ class LibrarySync(Thread):
|
||||||
# PROCESS TV Episodes #####
|
# PROCESS TV Episodes #####
|
||||||
# Cycle through tv shows
|
# Cycle through tv shows
|
||||||
for view in views:
|
for view in views:
|
||||||
if self.thread_stopped():
|
if self.thread_stopped() or self.thread_suspended():
|
||||||
return False
|
return False
|
||||||
# Grab all episodes to tvshow from PMS
|
# Grab all episodes to tvshow from PMS
|
||||||
episodes = GetAllPlexLeaves(view['id'])
|
episodes = GetAllPlexLeaves(view['id'])
|
||||||
|
@ -985,7 +980,7 @@ class LibrarySync(Thread):
|
||||||
|
|
||||||
# Update viewstate:
|
# Update viewstate:
|
||||||
for view in views:
|
for view in views:
|
||||||
if self.thread_stopped():
|
if self.thread_stopped() or self.thread_suspended():
|
||||||
return False
|
return False
|
||||||
self.PlexUpdateWatched(view['id'], itemType)
|
self.PlexUpdateWatched(view['id'], itemType)
|
||||||
|
|
||||||
|
@ -1022,7 +1017,7 @@ class LibrarySync(Thread):
|
||||||
for kind in (v.PLEX_TYPE_ARTIST,
|
for kind in (v.PLEX_TYPE_ARTIST,
|
||||||
v.PLEX_TYPE_ALBUM,
|
v.PLEX_TYPE_ALBUM,
|
||||||
v.PLEX_TYPE_SONG):
|
v.PLEX_TYPE_SONG):
|
||||||
if self.thread_stopped():
|
if self.thread_stopped() or self.thread_suspended():
|
||||||
return False
|
return False
|
||||||
log.debug("Start processing music %s" % kind)
|
log.debug("Start processing music %s" % kind)
|
||||||
self.allKodiElementsId = {}
|
self.allKodiElementsId = {}
|
||||||
|
@ -1039,7 +1034,7 @@ class LibrarySync(Thread):
|
||||||
|
|
||||||
# Update viewstate for EVERY item
|
# Update viewstate for EVERY item
|
||||||
for view in views:
|
for view in views:
|
||||||
if self.thread_stopped():
|
if self.thread_stopped() or self.thread_suspended():
|
||||||
return False
|
return False
|
||||||
self.PlexUpdateWatched(view['id'], itemType)
|
self.PlexUpdateWatched(view['id'], itemType)
|
||||||
|
|
||||||
|
@ -1064,7 +1059,9 @@ class LibrarySync(Thread):
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
for view in views:
|
for view in views:
|
||||||
if self.thread_stopped():
|
if self.installSyncDone is not True:
|
||||||
|
state.PATH_VERIFIED = False
|
||||||
|
if self.thread_stopped() or self.thread_suspended():
|
||||||
return False
|
return False
|
||||||
# Get items per view
|
# Get items per view
|
||||||
itemsXML = GetPlexSectionResults(view['id'], args=urlArgs)
|
itemsXML = GetPlexSectionResults(view['id'], args=urlArgs)
|
||||||
|
@ -1139,7 +1136,7 @@ class LibrarySync(Thread):
|
||||||
now = getUnixTimestamp()
|
now = getUnixTimestamp()
|
||||||
deleteListe = []
|
deleteListe = []
|
||||||
for i, item in enumerate(self.itemsToProcess):
|
for i, item in enumerate(self.itemsToProcess):
|
||||||
if self.thread_stopped():
|
if self.thread_stopped() or self.thread_suspended():
|
||||||
# Chances are that Kodi gets shut down
|
# Chances are that Kodi gets shut down
|
||||||
break
|
break
|
||||||
if item['state'] == 9:
|
if item['state'] == 9:
|
||||||
|
@ -1404,7 +1401,7 @@ class LibrarySync(Thread):
|
||||||
import traceback
|
import traceback
|
||||||
log.error("Traceback:\n%s" % traceback.format_exc())
|
log.error("Traceback:\n%s" % traceback.format_exc())
|
||||||
# Library sync thread has crashed
|
# Library sync thread has crashed
|
||||||
self.dialog.ok(lang(29999), lang(39400))
|
dialog('ok', heading='{plex}', line1=lang(39400))
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def run_internal(self):
|
def run_internal(self):
|
||||||
|
@ -1422,14 +1419,11 @@ class LibrarySync(Thread):
|
||||||
lastProcessing = 0
|
lastProcessing = 0
|
||||||
oneDay = 60*60*24
|
oneDay = 60*60*24
|
||||||
|
|
||||||
xbmcplayer = xbmc.Player()
|
|
||||||
|
|
||||||
# Link to Websocket queue
|
# Link to Websocket queue
|
||||||
queue = self.mgr.ws.queue
|
queue = self.mgr.ws.queue
|
||||||
|
|
||||||
startupComplete = False
|
startupComplete = False
|
||||||
self.views = []
|
self.views = []
|
||||||
errorcount = 0
|
|
||||||
|
|
||||||
log.info("---===### Starting LibrarySync ###===---")
|
log.info("---===### Starting LibrarySync ###===---")
|
||||||
|
|
||||||
|
@ -1459,13 +1453,15 @@ class LibrarySync(Thread):
|
||||||
log.warn("Db version out of date: %s minimum version "
|
log.warn("Db version out of date: %s minimum version "
|
||||||
"required: %s" % (currentVersion, minVersion))
|
"required: %s" % (currentVersion, minVersion))
|
||||||
# DB out of date. Proceed to recreate?
|
# DB out of date. Proceed to recreate?
|
||||||
resp = self.dialog.yesno(heading=lang(29999),
|
resp = dialog('yesno',
|
||||||
line1=lang(39401))
|
heading=lang(29999),
|
||||||
|
line1=lang(39401))
|
||||||
if not resp:
|
if not resp:
|
||||||
log.warn("Db version out of date! USER IGNORED!")
|
log.warn("Db version out of date! USER IGNORED!")
|
||||||
# PKC may not work correctly until reset
|
# PKC may not work correctly until reset
|
||||||
self.dialog.ok(heading=lang(29999),
|
dialog('ok',
|
||||||
line1=(lang(29999) + lang(39402)))
|
heading='{plex}',
|
||||||
|
line1=lang(29999) + lang(39402))
|
||||||
else:
|
else:
|
||||||
reset()
|
reset()
|
||||||
break
|
break
|
||||||
|
@ -1483,7 +1479,7 @@ class LibrarySync(Thread):
|
||||||
log.error('Current Kodi version: %s' % tryDecode(
|
log.error('Current Kodi version: %s' % tryDecode(
|
||||||
xbmc.getInfoLabel('System.BuildVersion')))
|
xbmc.getInfoLabel('System.BuildVersion')))
|
||||||
# "Current Kodi version is unsupported, cancel lib sync"
|
# "Current Kodi version is unsupported, cancel lib sync"
|
||||||
self.dialog.ok(heading=lang(29999), line1=lang(39403))
|
dialog('ok', heading='{plex}', line1=lang(39403))
|
||||||
break
|
break
|
||||||
# Run start up sync
|
# Run start up sync
|
||||||
state.DB_SCAN = True
|
state.DB_SCAN = True
|
||||||
|
@ -1520,14 +1516,6 @@ class LibrarySync(Thread):
|
||||||
installSyncDone = True
|
installSyncDone = True
|
||||||
else:
|
else:
|
||||||
log.error("Initial start-up full sync unsuccessful")
|
log.error("Initial start-up full sync unsuccessful")
|
||||||
errorcount += 1
|
|
||||||
if errorcount > 2:
|
|
||||||
log.error("Startup full sync failed. Stopping sync")
|
|
||||||
# "Startup syncing process failed repeatedly"
|
|
||||||
# "Please restart"
|
|
||||||
self.dialog.ok(heading=lang(29999),
|
|
||||||
line1=lang(39404))
|
|
||||||
break
|
|
||||||
|
|
||||||
# Currently no db scan, so we can start a new scan
|
# Currently no db scan, so we can start a new scan
|
||||||
elif state.DB_SCAN is False:
|
elif state.DB_SCAN is False:
|
||||||
|
@ -1544,7 +1532,7 @@ class LibrarySync(Thread):
|
||||||
window('plex_dbScan', clear=True)
|
window('plex_dbScan', clear=True)
|
||||||
state.DB_SCAN = False
|
state.DB_SCAN = False
|
||||||
# Full library sync finished
|
# Full library sync finished
|
||||||
self.showKodiNote(lang(39407), forced=False)
|
self.showKodiNote(lang(39407), forced=True)
|
||||||
# Reset views was requested from somewhere else
|
# Reset views was requested from somewhere else
|
||||||
elif window('plex_runLibScan') == "views":
|
elif window('plex_runLibScan') == "views":
|
||||||
log.info('Refresh playlist and nodes requested, starting')
|
log.info('Refresh playlist and nodes requested, starting')
|
||||||
|
@ -1575,8 +1563,9 @@ class LibrarySync(Thread):
|
||||||
window('plex_runLibScan', clear=True)
|
window('plex_runLibScan', clear=True)
|
||||||
# Only look for missing fanart (No)
|
# Only look for missing fanart (No)
|
||||||
# or refresh all fanart (Yes)
|
# or refresh all fanart (Yes)
|
||||||
self.fanartSync(refresh=self.dialog.yesno(
|
self.fanartSync(refresh=dialog(
|
||||||
heading=lang(29999),
|
'yesno',
|
||||||
|
heading='{plex}',
|
||||||
line1=lang(39223),
|
line1=lang(39223),
|
||||||
nolabel=lang(39224),
|
nolabel=lang(39224),
|
||||||
yeslabel=lang(39225)))
|
yeslabel=lang(39225)))
|
||||||
|
@ -1591,7 +1580,7 @@ class LibrarySync(Thread):
|
||||||
else:
|
else:
|
||||||
now = getUnixTimestamp()
|
now = getUnixTimestamp()
|
||||||
if (now - lastSync > fullSyncInterval and
|
if (now - lastSync > fullSyncInterval and
|
||||||
not xbmcplayer.isPlaying()):
|
not self.xbmcplayer.isPlaying()):
|
||||||
lastSync = now
|
lastSync = now
|
||||||
log.info('Doing scheduled full library scan')
|
log.info('Doing scheduled full library scan')
|
||||||
state.DB_SCAN = True
|
state.DB_SCAN = True
|
||||||
|
|
|
@ -10,6 +10,8 @@ STOP_PKC = False
|
||||||
SUSPEND_LIBRARY_THREAD = False
|
SUSPEND_LIBRARY_THREAD = False
|
||||||
# Set if user decided to cancel sync
|
# Set if user decided to cancel sync
|
||||||
STOP_SYNC = False
|
STOP_SYNC = False
|
||||||
|
# Could we access the paths?
|
||||||
|
PATH_VERIFIED = False
|
||||||
# Set if a Plex-Kodi DB sync is being done - along with
|
# Set if a Plex-Kodi DB sync is being done - along with
|
||||||
# window('plex_dbScan') set to 'true'
|
# window('plex_dbScan') set to 'true'
|
||||||
DB_SCAN = False
|
DB_SCAN = False
|
||||||
|
|
|
@ -140,6 +140,15 @@ def dialog(typus, *args, **kwargs):
|
||||||
Displays xbmcgui Dialog. Pass a string as typus:
|
Displays xbmcgui Dialog. Pass a string as typus:
|
||||||
'yesno', 'ok', 'notification', 'input', 'select', 'numeric'
|
'yesno', 'ok', 'notification', 'input', 'select', 'numeric'
|
||||||
|
|
||||||
|
kwargs:
|
||||||
|
heading='{plex}' title bar (here PlexKodiConnect)
|
||||||
|
message=lang(30128), Actual dialog content. Don't use with OK
|
||||||
|
line1=str(), For 'OK' and 'yesno' dialogs use line1...line3!
|
||||||
|
time=5000,
|
||||||
|
sound=True,
|
||||||
|
nolabel=str(), For 'yesno' dialogs
|
||||||
|
yeslabel=str(), For 'yesno' dialogs
|
||||||
|
|
||||||
Icons:
|
Icons:
|
||||||
icon='{plex}' Display Plex standard icon
|
icon='{plex}' Display Plex standard icon
|
||||||
icon='{info}' xbmcgui.NOTIFICATION_INFO
|
icon='{info}' xbmcgui.NOTIFICATION_INFO
|
||||||
|
|
|
@ -30,8 +30,7 @@ sys_path.append(_base_resource)
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
from utils import settings, window, language as lang, dialog, tryEncode, \
|
from utils import settings, window, language as lang, dialog, tryDecode
|
||||||
tryDecode
|
|
||||||
from userclient import UserClient
|
from userclient import UserClient
|
||||||
import initialsetup
|
import initialsetup
|
||||||
from kodimonitor import KodiMonitor
|
from kodimonitor import KodiMonitor
|
||||||
|
|
Loading…
Reference in a new issue