Merge branch 'develop'
This commit is contained in:
commit
3d4e51e587
10 changed files with 199 additions and 47 deletions
|
@ -7,13 +7,13 @@
|
||||||
**Installation in Kodi**
|
**Installation in Kodi**
|
||||||
|
|
||||||
1. You might want to uninstall everything else Plex related first, e.g. PlexBMC and PlexBMC Helper. Starting with a fresh Kodi install might be a good idea. Be sure to use a "normal", unmodded Skin in Kodi.
|
1. You might want to uninstall everything else Plex related first, e.g. PlexBMC and PlexBMC Helper. Starting with a fresh Kodi install might be a good idea. Be sure to use a "normal", unmodded Skin in Kodi.
|
||||||
If you're updating, you might also want to do a complete reset of the plugin: Settings -> Advanced -> "Performe full DB reset". Choose "Yes" for everything.
|
If you're updating, you might also want to do a complete reset of the plugin: Settings -> Advanced -> "Perform full DB reset". Choose "Yes" for all questions.
|
||||||
2. Simply fire up Kodi and Install from ZIP from here on.
|
2. Simply fire up Kodi and Install from ZIP from here on.
|
||||||
3. Install the 2 needed dependencies first (be sure to NOT download the sources but the additional release files): https://github.com/croneter/plugin.video.plexkodiconnect.tvshows/releases/tag/1.0.0 and https://github.com/croneter/plugin.video.plexkodiconnect.movies/releases/tag/1.0.0
|
3. Install the 2 needed dependencies first (be sure to NOT download the sources but the additional release files): https://github.com/croneter/plugin.video.plexkodiconnect.tvshows/releases/ and https://github.com/croneter/plugin.video.plexkodiconnect.movies/releases/
|
||||||
5. Then install PlexKodiConnect, again the additional release file from here: https://github.com/croneter/PlexKodiConnect/releases/
|
5. Then install PlexKodiConnect, again the additional release file from here: https://github.com/croneter/PlexKodiConnect/releases/
|
||||||
6. Within a few seconds you should be prompted to log into plex.tv. This is mandatory for Plex Home, otherwise you can skip. If nothing happens, try to restart Kodi
|
6. Within a few seconds you should be prompted to log into plex.tv. This is mandatory for Plex Home, otherwise you can skip. If nothing happens, try to restart Kodi
|
||||||
7. Once you're succesfully authenticated to your Plex server, the initial sync will start.
|
7. Once you're succesfully authenticated to your Plex server, the initial sync will start.
|
||||||
8. The first sync of the Plex server to local Kodi database may take a LONG time. With my setup (~400 movies, ~600 episodes, couple of Test music albums and a very powerful NAS), sync take approximately 5 minutes.
|
8. The first sync of the Plex server to local Kodi database may take a LONG time. With my setup (~400 movies, ~600 episodes, couple of Test music albums and a very powerful NAS), sync takes approximately 5 minutes.
|
||||||
9. Once the full sync is done, you can browse your media in Kodi, syncs will be automatically done in the background.
|
9. Once the full sync is done, you can browse your media in Kodi, syncs will be automatically done in the background.
|
||||||
10. Restart!
|
10. Restart!
|
||||||
|
|
||||||
|
@ -62,6 +62,8 @@ Guess what, this is BETA. Currently these features are working:
|
||||||
- Pictures
|
- Pictures
|
||||||
- Watch Later
|
- Watch Later
|
||||||
- Music Videos
|
- Music Videos
|
||||||
|
- Playlists
|
||||||
|
- Play directly from SMB paths ("\\\\server\\Plex\\movie.mkv" on Windows) instead of HTTP ("192.168.1.1:32400")
|
||||||
- TV Shows Theme Music (ultra-low prio)
|
- TV Shows Theme Music (ultra-low prio)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<addon id="plugin.video.plexkodiconnect"
|
<addon id="plugin.video.plexkodiconnect"
|
||||||
name="PlexKodiConnect"
|
name="PlexKodiConnect"
|
||||||
version="1.0.5"
|
version="1.0.6"
|
||||||
provider-name="croneter">
|
provider-name="croneter">
|
||||||
<requires>
|
<requires>
|
||||||
<import addon="xbmc.python" version="2.1.0"/>
|
<import addon="xbmc.python" version="2.1.0"/>
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
version 1.0.6
|
||||||
|
- Enable traceback and dump XMLs of failed PMS items in the log for lib sync
|
||||||
|
- Optimize notifications for library syncs
|
||||||
|
- Manually trigger full library scan from settings
|
||||||
|
- Merge with MediaBrowser/master up until db4cb448b0e4fd82662f8b82a800d8da8ea33688
|
||||||
|
|
||||||
|
|
||||||
version 1.0.5
|
version 1.0.5
|
||||||
- Catch exceptions in itemtypes and log them
|
- Catch exceptions in itemtypes and log them
|
||||||
- Slightly increased download timeouts
|
- Slightly increased download timeouts
|
||||||
|
|
|
@ -51,6 +51,7 @@ if __name__ == '__main__':
|
||||||
embycursor = embyconn.cursor()
|
embycursor = embyconn.cursor()
|
||||||
emby_db = embydb.Embydb_Functions(embycursor)
|
emby_db = embydb.Embydb_Functions(embycursor)
|
||||||
item = emby_db.getItem_byKodiId(itemid, itemtype)
|
item = emby_db.getItem_byKodiId(itemid, itemtype)
|
||||||
|
embycursor.close()
|
||||||
if item: embyid = item[0]
|
if item: embyid = item[0]
|
||||||
|
|
||||||
logMsg("Contextmenu opened for embyid: %s - itemtype: %s" %(embyid,itemtype))
|
logMsg("Contextmenu opened for embyid: %s - itemtype: %s" %(embyid,itemtype))
|
||||||
|
|
17
default.py
17
default.py
|
@ -8,6 +8,7 @@ import urlparse
|
||||||
|
|
||||||
import xbmc
|
import xbmc
|
||||||
import xbmcaddon
|
import xbmcaddon
|
||||||
|
import xbmcgui
|
||||||
|
|
||||||
#################################################################################################
|
#################################################################################################
|
||||||
|
|
||||||
|
@ -66,7 +67,8 @@ class Main:
|
||||||
'companion': entrypoint.plexCompanion,
|
'companion': entrypoint.plexCompanion,
|
||||||
'switchuser': entrypoint.switchPlexUser,
|
'switchuser': entrypoint.switchPlexUser,
|
||||||
'deviceid': entrypoint.resetDeviceId,
|
'deviceid': entrypoint.resetDeviceId,
|
||||||
'reConnect': entrypoint.reConnect
|
'reConnect': entrypoint.reConnect,
|
||||||
|
'delete': entrypoint.deleteItem
|
||||||
}
|
}
|
||||||
|
|
||||||
if "/extrafanart" in sys.argv[0]:
|
if "/extrafanart" in sys.argv[0]:
|
||||||
|
@ -108,7 +110,18 @@ class Main:
|
||||||
if mode == "settings":
|
if mode == "settings":
|
||||||
xbmc.executebuiltin('Addon.OpenSettings(plugin.video.plexkodiconnect)')
|
xbmc.executebuiltin('Addon.OpenSettings(plugin.video.plexkodiconnect)')
|
||||||
elif mode in ("manualsync", "repair"):
|
elif mode in ("manualsync", "repair"):
|
||||||
entrypoint.RunLibScan(mode)
|
if utils.window('emby_online') != "true":
|
||||||
|
# Server is not online, do not run the sync
|
||||||
|
xbmcgui.Dialog().ok(heading="PlexKodiConnect",
|
||||||
|
line1=("Unable to run the sync, the add-on is not "
|
||||||
|
"connected to the Emby server."))
|
||||||
|
utils.logMsg("PLEX", "Not connected to the emby server.", 1)
|
||||||
|
return
|
||||||
|
|
||||||
|
else:
|
||||||
|
utils.logMsg("PLEX", "Requesting full library scan", 1)
|
||||||
|
utils.window('plex_runLibScan', value="full")
|
||||||
|
|
||||||
elif mode == "texturecache":
|
elif mode == "texturecache":
|
||||||
import artwork
|
import artwork
|
||||||
artwork.Artwork().FullTextureCacheSync()
|
artwork.Artwork().FullTextureCacheSync()
|
||||||
|
|
|
@ -405,5 +405,7 @@
|
||||||
<string id="39404">Startup syncing process failed repeatedly. Try restarting Kodi. Stopping Sync for now.</string>
|
<string id="39404">Startup syncing process failed repeatedly. Try restarting Kodi. Stopping Sync for now.</string>
|
||||||
<string id="39405">Plex playlists/nodes refreshed</string>
|
<string id="39405">Plex playlists/nodes refreshed</string>
|
||||||
<string id="39406">Plex playlists/nodes refresh failed</string>
|
<string id="39406">Plex playlists/nodes refresh failed</string>
|
||||||
|
<string id="39407">Full library sync finished</string>
|
||||||
|
<string id="39408">Sync had to skip some items because they could not be processed. Please post your Kodi logs to the Plex forum.</string>
|
||||||
|
|
||||||
</strings>
|
</strings>
|
||||||
|
|
|
@ -337,5 +337,7 @@
|
||||||
<string id="39404">Der Startup Synchronisations-Prozess der Plex Bibliotheken ist mehrmals fehlgeschlagen. Bitte Kodi neu starten. Synch wird jetzt gestoppt.</string>
|
<string id="39404">Der Startup Synchronisations-Prozess der Plex Bibliotheken ist mehrmals fehlgeschlagen. Bitte Kodi neu starten. Synch wird jetzt gestoppt.</string>
|
||||||
<string id="39405">Plex Playlisten/Nodes aktualisiert</string>
|
<string id="39405">Plex Playlisten/Nodes aktualisiert</string>
|
||||||
<string id="39406">Plex Playlisten/Nodes Aktualisierung fehlgeschlagen</string>
|
<string id="39406">Plex Playlisten/Nodes Aktualisierung fehlgeschlagen</string>
|
||||||
|
<string id="39407">Plex Bibliotheken aktualisiert</string>
|
||||||
|
<string id="39408">Einige Plex Einträge mussten übersprungen werden, da sie nicht verarbeitet werden konnten. Bitte teilen Sie Ihr Kodi log im Plex Forum.</string>
|
||||||
|
|
||||||
</strings>
|
</strings>
|
||||||
|
|
|
@ -285,6 +285,56 @@ def resetDeviceId():
|
||||||
line1=language(33033))
|
line1=language(33033))
|
||||||
xbmc.executebuiltin('RestartApp')
|
xbmc.executebuiltin('RestartApp')
|
||||||
|
|
||||||
|
##### Delete Item
|
||||||
|
def deleteItem():
|
||||||
|
|
||||||
|
# Serves as a keymap action
|
||||||
|
if xbmc.getInfoLabel('ListItem.Property(embyid)'): # If we already have the embyid
|
||||||
|
embyid = xbmc.getInfoLabel('ListItem.Property(embyid)')
|
||||||
|
else:
|
||||||
|
dbid = xbmc.getInfoLabel('ListItem.DBID')
|
||||||
|
itemtype = xbmc.getInfoLabel('ListItem.DBTYPE')
|
||||||
|
|
||||||
|
if not itemtype:
|
||||||
|
|
||||||
|
if xbmc.getCondVisibility('Container.Content(albums)'):
|
||||||
|
itemtype = "album"
|
||||||
|
elif xbmc.getCondVisibility('Container.Content(artists)'):
|
||||||
|
itemtype = "artist"
|
||||||
|
elif xbmc.getCondVisibility('Container.Content(songs)'):
|
||||||
|
itemtype = "song"
|
||||||
|
elif xbmc.getCondVisibility('Container.Content(pictures)'):
|
||||||
|
itemtype = "picture"
|
||||||
|
else:
|
||||||
|
utils.logMsg("EMBY delete", "Unknown type, unable to proceed.", 1)
|
||||||
|
return
|
||||||
|
|
||||||
|
embyconn = utils.kodiSQL('emby')
|
||||||
|
embycursor = embyconn.cursor()
|
||||||
|
emby_db = embydb.Embydb_Functions(embycursor)
|
||||||
|
item = emby_db.getItem_byKodiId(dbid, itemtype)
|
||||||
|
embycursor.close()
|
||||||
|
|
||||||
|
try:
|
||||||
|
embyid = item[0]
|
||||||
|
except TypeError:
|
||||||
|
utils.logMsg("EMBY delete", "Unknown embyId, unable to proceed.", 1)
|
||||||
|
return
|
||||||
|
|
||||||
|
if utils.settings('skipContextMenu') != "true":
|
||||||
|
resp = xbmcgui.Dialog().yesno(
|
||||||
|
heading="Confirm delete",
|
||||||
|
line1=("Delete file from Emby Server? This will "
|
||||||
|
"also delete the file(s) from disk!"))
|
||||||
|
if not resp:
|
||||||
|
utils.logMsg("EMBY delete", "User skipped deletion for: %s." % embyid, 1)
|
||||||
|
return
|
||||||
|
|
||||||
|
doUtils = downloadutils.DownloadUtils()
|
||||||
|
url = "{server}/emby/Items/%s?format=json" % embyid
|
||||||
|
utils.logMsg("EMBY delete", "Deleting request: %s" % embyid, 0)
|
||||||
|
doUtils.downloadUrl(url, type="DELETE")
|
||||||
|
|
||||||
##### ADD ADDITIONAL USERS #####
|
##### ADD ADDITIONAL USERS #####
|
||||||
def addUser():
|
def addUser():
|
||||||
|
|
||||||
|
|
|
@ -287,10 +287,18 @@ class Movies(Items):
|
||||||
try:
|
try:
|
||||||
self.run_add_update(item, viewtag, viewid)
|
self.run_add_update(item, viewtag, viewid)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
utils.window('emby_dbScan', clear=True)
|
|
||||||
self.logMsg('itemtypes.py for movies has crashed for item %s. '
|
self.logMsg('itemtypes.py for movies has crashed for item %s. '
|
||||||
'Error:' % item.attrib.get('ratingKey', None), -1)
|
'Error:' % item.attrib.get('ratingKey', None), -1)
|
||||||
self.logMsg(e, -1)
|
self.logMsg(e, -1)
|
||||||
|
import traceback
|
||||||
|
self.logMsg("Traceback:\n%s" % traceback.format_exc(), 0)
|
||||||
|
self.logMsg('The item xml is:', -1)
|
||||||
|
try:
|
||||||
|
import xml.etree.cElementTree as etree
|
||||||
|
except ImportError:
|
||||||
|
import xml.etree.ElementTree as etree
|
||||||
|
etree.dump(item)
|
||||||
|
utils.window('plex_scancrashed', value='true')
|
||||||
# skip this item for now
|
# skip this item for now
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -920,10 +928,18 @@ class TVShows(Items):
|
||||||
try:
|
try:
|
||||||
self.run_add_update(item, viewtag, viewid)
|
self.run_add_update(item, viewtag, viewid)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
utils.window('emby_dbScan', clear=True)
|
|
||||||
self.logMsg('itemtypes.py for tv show has crashed for item %s. '
|
self.logMsg('itemtypes.py for tv show has crashed for item %s. '
|
||||||
'Error:' % item.attrib.get('ratingKey', None), -1)
|
'Error:' % item.attrib.get('ratingKey', None), -1)
|
||||||
self.logMsg(e, -1)
|
self.logMsg(e, -1)
|
||||||
|
import traceback
|
||||||
|
self.logMsg("Traceback:\n%s" % traceback.format_exc(), 0)
|
||||||
|
self.logMsg('The item xml is:', -1)
|
||||||
|
try:
|
||||||
|
import xml.etree.cElementTree as etree
|
||||||
|
except ImportError:
|
||||||
|
import xml.etree.ElementTree as etree
|
||||||
|
etree.dump(item)
|
||||||
|
utils.window('plex_scancrashed', value='true')
|
||||||
# skip this item for now
|
# skip this item for now
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -1117,10 +1133,18 @@ class TVShows(Items):
|
||||||
try:
|
try:
|
||||||
self.run_add_updateSeason(item, viewtag, viewid)
|
self.run_add_updateSeason(item, viewtag, viewid)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
utils.window('emby_dbScan', clear=True)
|
|
||||||
self.logMsg('itemtypes.py for tv seasons has crashed for item %s. '
|
self.logMsg('itemtypes.py for tv seasons has crashed for item %s. '
|
||||||
'Error:' % item.attrib.get('ratingKey', None), -1)
|
'Error:' % item.attrib.get('ratingKey', None), -1)
|
||||||
self.logMsg(e, -1)
|
self.logMsg(e, -1)
|
||||||
|
import traceback
|
||||||
|
self.logMsg("Traceback:\n%s" % traceback.format_exc(), 0)
|
||||||
|
self.logMsg('The item xml is:', -1)
|
||||||
|
try:
|
||||||
|
import xml.etree.cElementTree as etree
|
||||||
|
except ImportError:
|
||||||
|
import xml.etree.ElementTree as etree
|
||||||
|
etree.dump(item)
|
||||||
|
utils.window('plex_scancrashed', value='true')
|
||||||
# skip this item for now
|
# skip this item for now
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -1162,10 +1186,18 @@ class TVShows(Items):
|
||||||
try:
|
try:
|
||||||
self.run_add_updateEpisode(item, viewtag, viewid)
|
self.run_add_updateEpisode(item, viewtag, viewid)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
utils.window('emby_dbScan', clear=True)
|
|
||||||
self.logMsg('itemtypes.py for tv episode has crashed for item %s. '
|
self.logMsg('itemtypes.py for tv episode has crashed for item %s. '
|
||||||
'Error:' % item.attrib.get('ratingKey', None), -1)
|
'Error:' % item.attrib.get('ratingKey', None), -1)
|
||||||
self.logMsg(e, -1)
|
self.logMsg(e, -1)
|
||||||
|
import traceback
|
||||||
|
self.logMsg("Traceback:\n%s" % traceback.format_exc(), 0)
|
||||||
|
self.logMsg('The item xml is:', -1)
|
||||||
|
try:
|
||||||
|
import xml.etree.cElementTree as etree
|
||||||
|
except ImportError:
|
||||||
|
import xml.etree.ElementTree as etree
|
||||||
|
etree.dump(item)
|
||||||
|
utils.window('plex_scancrashed', value='true')
|
||||||
# skip this item for now
|
# skip this item for now
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -1642,11 +1674,19 @@ class Music(Items):
|
||||||
try:
|
try:
|
||||||
self.run_add_updateArtist(item, viewtag, viewid, artisttype)
|
self.run_add_updateArtist(item, viewtag, viewid, artisttype)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
utils.window('emby_dbScan', clear=True)
|
|
||||||
self.logMsg('itemtypes.py for music artist has crashed for '
|
self.logMsg('itemtypes.py for music artist has crashed for '
|
||||||
'item %s. Error:'
|
'item %s. Error:'
|
||||||
% item.attrib.get('ratingKey', None), -1)
|
% item.attrib.get('ratingKey', None), -1)
|
||||||
self.logMsg(e, -1)
|
self.logMsg(e, -1)
|
||||||
|
import traceback
|
||||||
|
self.logMsg("Traceback:\n%s" % traceback.format_exc(), 0)
|
||||||
|
self.logMsg('The item xml is:', -1)
|
||||||
|
try:
|
||||||
|
import xml.etree.cElementTree as etree
|
||||||
|
except ImportError:
|
||||||
|
import xml.etree.ElementTree as etree
|
||||||
|
etree.dump(item)
|
||||||
|
utils.window('plex_scancrashed', value='true')
|
||||||
# skip this item for now
|
# skip this item for now
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -1738,11 +1778,19 @@ class Music(Items):
|
||||||
try:
|
try:
|
||||||
self.run_add_updateAlbum(item, viewtag, viewid)
|
self.run_add_updateAlbum(item, viewtag, viewid)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
utils.window('emby_dbScan', clear=True)
|
|
||||||
self.logMsg('itemtypes.py for music album has crashed for '
|
self.logMsg('itemtypes.py for music album has crashed for '
|
||||||
'item %s. Error:'
|
'item %s. Error:'
|
||||||
% item.attrib.get('ratingKey', None), -1)
|
% item.attrib.get('ratingKey', None), -1)
|
||||||
self.logMsg(e, -1)
|
self.logMsg(e, -1)
|
||||||
|
import traceback
|
||||||
|
self.logMsg("Traceback:\n%s" % traceback.format_exc(), 0)
|
||||||
|
self.logMsg('The item xml is:', -1)
|
||||||
|
try:
|
||||||
|
import xml.etree.cElementTree as etree
|
||||||
|
except ImportError:
|
||||||
|
import xml.etree.ElementTree as etree
|
||||||
|
etree.dump(item)
|
||||||
|
utils.window('plex_scancrashed', value='true')
|
||||||
# skip this item for now
|
# skip this item for now
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -1936,11 +1984,19 @@ class Music(Items):
|
||||||
try:
|
try:
|
||||||
self.run_add_updateSong(item, viewtag, viewid)
|
self.run_add_updateSong(item, viewtag, viewid)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
utils.window('emby_dbScan', clear=True)
|
|
||||||
self.logMsg('itemtypes.py for music song has crashed for '
|
self.logMsg('itemtypes.py for music song has crashed for '
|
||||||
'item %s. Error:'
|
'item %s. Error:'
|
||||||
% item.attrib.get('ratingKey', None), -1)
|
% item.attrib.get('ratingKey', None), -1)
|
||||||
self.logMsg(e, -1)
|
self.logMsg(e, -1)
|
||||||
|
import traceback
|
||||||
|
self.logMsg("Traceback:\n%s" % traceback.format_exc(), 0)
|
||||||
|
self.logMsg('The item xml is:', -1)
|
||||||
|
try:
|
||||||
|
import xml.etree.cElementTree as etree
|
||||||
|
except ImportError:
|
||||||
|
import xml.etree.ElementTree as etree
|
||||||
|
etree.dump(item)
|
||||||
|
utils.window('plex_scancrashed', value='true')
|
||||||
# skip this item for now
|
# skip this item for now
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ class ThreadedGetMetadata(Thread):
|
||||||
# Did not receive a valid XML - skip that item for now
|
# Did not receive a valid XML - skip that item for now
|
||||||
self.logMsg("Could not get metadata for %s. "
|
self.logMsg("Could not get metadata for %s. "
|
||||||
"Skipping that item for now"
|
"Skipping that item for now"
|
||||||
% updateItem['itemId'], -1)
|
% updateItem['itemId'], 0)
|
||||||
# Increase BOTH counters - since metadata won't be processed
|
# Increase BOTH counters - since metadata won't be processed
|
||||||
with lock:
|
with lock:
|
||||||
getMetadataCount += 1
|
getMetadataCount += 1
|
||||||
|
@ -223,8 +223,8 @@ class LibrarySync(Thread):
|
||||||
self.user = userclient.UserClient()
|
self.user = userclient.UserClient()
|
||||||
self.emby = embyserver.Read_EmbyServer()
|
self.emby = embyserver.Read_EmbyServer()
|
||||||
self.vnodes = videonodes.VideoNodes()
|
self.vnodes = videonodes.VideoNodes()
|
||||||
self.syncThreadNumber = int(utils.settings('syncThreadNumber'))
|
|
||||||
|
|
||||||
|
self.syncThreadNumber = int(utils.settings('syncThreadNumber'))
|
||||||
self.installSyncDone = True if \
|
self.installSyncDone = True if \
|
||||||
utils.settings('SyncInstallRunDone') == 'true' else False
|
utils.settings('SyncInstallRunDone') == 'true' else False
|
||||||
self.showDbSync = True if \
|
self.showDbSync = True if \
|
||||||
|
@ -236,18 +236,30 @@ class LibrarySync(Thread):
|
||||||
|
|
||||||
Thread.__init__(self)
|
Thread.__init__(self)
|
||||||
|
|
||||||
def showKodiNote(self, message, forced=False):
|
def showKodiNote(self, message, forced=False, icon="plex"):
|
||||||
"""
|
"""
|
||||||
Shows a Kodi popup, if user selected to do so. Pass message in unicode
|
Shows a Kodi popup, if user selected to do so. Pass message in unicode
|
||||||
or string
|
or string
|
||||||
|
|
||||||
|
icon: "plex": shows Plex icon
|
||||||
|
"error": shows Kodi error icon
|
||||||
"""
|
"""
|
||||||
if not (self.showDbSync or forced):
|
if not (self.showDbSync or forced):
|
||||||
return
|
return
|
||||||
|
if icon == "plex":
|
||||||
xbmcgui.Dialog().notification(
|
xbmcgui.Dialog().notification(
|
||||||
heading=self.addonName,
|
heading=self.addonName,
|
||||||
message=message,
|
message=message,
|
||||||
icon="special://home/addons/plugin.video.plexkodiconnect/icon.png",
|
icon="special://home/addons/plugin.video.plexkodiconnect/icon.png",
|
||||||
|
time=5000,
|
||||||
sound=False)
|
sound=False)
|
||||||
|
elif icon == "error":
|
||||||
|
xbmcgui.Dialog().notification(
|
||||||
|
heading=self.addonName,
|
||||||
|
message=message,
|
||||||
|
icon=xbmcgui.NOTIFICATION_ERROR,
|
||||||
|
time=7000,
|
||||||
|
sound=True)
|
||||||
|
|
||||||
def fastSync(self):
|
def fastSync(self):
|
||||||
"""
|
"""
|
||||||
|
@ -307,7 +319,8 @@ class LibrarySync(Thread):
|
||||||
elif self.updatelist[0]['itemType'] == 'Music':
|
elif self.updatelist[0]['itemType'] == 'Music':
|
||||||
self.updateKodiMusicLib = True
|
self.updateKodiMusicLib = True
|
||||||
self.GetAndProcessXMLs(
|
self.GetAndProcessXMLs(
|
||||||
PlexFunctions.GetItemClassFromType(plexType))
|
PlexFunctions.GetItemClassFromType(plexType),
|
||||||
|
showProgress=False)
|
||||||
self.updatelist = []
|
self.updatelist = []
|
||||||
|
|
||||||
# Update userdata
|
# Update userdata
|
||||||
|
@ -327,6 +340,10 @@ class LibrarySync(Thread):
|
||||||
|
|
||||||
# Reset and return
|
# Reset and return
|
||||||
self.allPlexElementsId = {}
|
self.allPlexElementsId = {}
|
||||||
|
# Show warning if itemtypes.py crashed at some point
|
||||||
|
if utils.window('plex_scancrashed') == 'true':
|
||||||
|
xbmcgui.Dialog().ok(self.addonName, self.__language__(39408))
|
||||||
|
utils.window('plex_scancrashed', clear=True)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def saveLastSync(self):
|
def saveLastSync(self):
|
||||||
|
@ -400,6 +417,10 @@ class LibrarySync(Thread):
|
||||||
utils.window('emby_initialScan', clear=True)
|
utils.window('emby_initialScan', clear=True)
|
||||||
xbmc.executebuiltin('InhibitIdleShutdown(false)')
|
xbmc.executebuiltin('InhibitIdleShutdown(false)')
|
||||||
utils.setScreensaver(value=screensaver)
|
utils.setScreensaver(value=screensaver)
|
||||||
|
# Show warning if itemtypes.py crashed at some point
|
||||||
|
if utils.window('plex_scancrashed') == 'true':
|
||||||
|
xbmcgui.Dialog().ok(self.addonName, self.__language__(39408))
|
||||||
|
utils.window('plex_scancrashed', clear=True)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def processView(self, folderItem, kodi_db, emby_db, totalnodes):
|
def processView(self, folderItem, kodi_db, emby_db, totalnodes):
|
||||||
|
@ -698,7 +719,7 @@ class LibrarySync(Thread):
|
||||||
'viewId': viewId,
|
'viewId': viewId,
|
||||||
'title': title})
|
'title': title})
|
||||||
|
|
||||||
def GetAndProcessXMLs(self, itemType):
|
def GetAndProcessXMLs(self, itemType, showProgress=True):
|
||||||
"""
|
"""
|
||||||
Downloads all XMLs for itemType (e.g. Movies, TV-Shows). Processes them
|
Downloads all XMLs for itemType (e.g. Movies, TV-Shows). Processes them
|
||||||
by then calling itemtypes.<itemType>()
|
by then calling itemtypes.<itemType>()
|
||||||
|
@ -706,6 +727,7 @@ class LibrarySync(Thread):
|
||||||
Input:
|
Input:
|
||||||
itemType: 'Movies', 'TVShows', ...
|
itemType: 'Movies', 'TVShows', ...
|
||||||
self.updatelist
|
self.updatelist
|
||||||
|
showProgress If False, NEVER shows sync progress
|
||||||
"""
|
"""
|
||||||
# Some logging, just in case.
|
# Some logging, just in case.
|
||||||
self.logMsg("self.updatelist: %s" % self.updatelist, 2)
|
self.logMsg("self.updatelist: %s" % self.updatelist, 2)
|
||||||
|
@ -750,6 +772,7 @@ class LibrarySync(Thread):
|
||||||
threads.append(thread)
|
threads.append(thread)
|
||||||
self.logMsg("Processing thread spawned", 1)
|
self.logMsg("Processing thread spawned", 1)
|
||||||
# Start one thread to show sync progress
|
# Start one thread to show sync progress
|
||||||
|
if showProgress:
|
||||||
if self.showDbSync:
|
if self.showDbSync:
|
||||||
dialog = xbmcgui.DialogProgressBG()
|
dialog = xbmcgui.DialogProgressBG()
|
||||||
thread = ThreadedShowSyncInfo(
|
thread = ThreadedShowSyncInfo(
|
||||||
|
@ -1229,6 +1252,8 @@ class LibrarySync(Thread):
|
||||||
fullSync(manualrun=True)
|
fullSync(manualrun=True)
|
||||||
window('emby_dbScan', clear=True)
|
window('emby_dbScan', clear=True)
|
||||||
count = 0
|
count = 0
|
||||||
|
# Full library sync finished
|
||||||
|
self.showKodiNote(string(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('Refresh playlist and nodes requested, starting', 0)
|
log('Refresh playlist and nodes requested, starting', 0)
|
||||||
|
@ -1244,22 +1269,14 @@ class LibrarySync(Thread):
|
||||||
# Ran successfully
|
# Ran successfully
|
||||||
log("Refresh playlists/nodes completed", 0)
|
log("Refresh playlists/nodes completed", 0)
|
||||||
# "Plex playlists/nodes refreshed"
|
# "Plex playlists/nodes refreshed"
|
||||||
dialog.notification(
|
self.showKodiNote(string(39405), forced=True)
|
||||||
heading=self.addonName,
|
|
||||||
message=string(39405),
|
|
||||||
icon="special://home/addons/plugin.video.plexkodiconnect/icon.png",
|
|
||||||
time=3000,
|
|
||||||
sound=True)
|
|
||||||
else:
|
else:
|
||||||
# Failed
|
# Failed
|
||||||
log("Refresh playlists/nodes failed", -1)
|
log("Refresh playlists/nodes failed", -1)
|
||||||
# "Plex playlists/nodes refresh failed"
|
# "Plex playlists/nodes refresh failed"
|
||||||
dialog.notification(
|
self.showKodiNote(string(39406),
|
||||||
heading=self.addonName,
|
forced=True,
|
||||||
message=string(39406),
|
icon="error")
|
||||||
icon=xbmcgui.NOTIFICATION_ERROR,
|
|
||||||
time=3000,
|
|
||||||
sound=True)
|
|
||||||
window('emby_dbScan', clear=True)
|
window('emby_dbScan', clear=True)
|
||||||
elif enableBackgroundSync:
|
elif enableBackgroundSync:
|
||||||
# Run full lib scan approx every 30min
|
# Run full lib scan approx every 30min
|
||||||
|
@ -1269,6 +1286,8 @@ class LibrarySync(Thread):
|
||||||
log('Running background full lib scan', 0)
|
log('Running background full lib scan', 0)
|
||||||
fullSync(manualrun=True)
|
fullSync(manualrun=True)
|
||||||
window('emby_dbScan', clear=True)
|
window('emby_dbScan', clear=True)
|
||||||
|
# Full library sync finished
|
||||||
|
self.showKodiNote(string(39407), forced=False)
|
||||||
# Run fast sync otherwise (ever second or so)
|
# Run fast sync otherwise (ever second or so)
|
||||||
else:
|
else:
|
||||||
window('emby_dbScan', value="true")
|
window('emby_dbScan', value="true")
|
||||||
|
|
Loading…
Reference in a new issue