Merge branch 'master' into playlists

This commit is contained in:
Croneter 2018-06-07 17:41:46 +02:00
commit c5ca8910d7
8 changed files with 62 additions and 34 deletions

View file

@ -1,5 +1,5 @@
[![stable version](https://img.shields.io/badge/stable_version-1.8.18-blue.svg?maxAge=60&style=flat) ](https://github.com/croneter/binary_repo/raw/master/stable/repository.plexkodiconnect/repository.plexkodiconnect-1.0.2.zip) [![stable version](https://img.shields.io/badge/stable_version-1.8.18-blue.svg?maxAge=60&style=flat) ](https://github.com/croneter/binary_repo/raw/master/stable/repository.plexkodiconnect/repository.plexkodiconnect-1.0.2.zip)
[![beta version](https://img.shields.io/badge/beta_version-2.0.29-red.svg?maxAge=60&style=flat) ](https://github.com/croneter/binary_repo/raw/master/beta/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.2.zip) [![beta version](https://img.shields.io/badge/beta_version-2.0.30-red.svg?maxAge=60&style=flat) ](https://github.com/croneter/binary_repo/raw/master/beta/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.2.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)

View file

@ -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="2.0.29" provider-name="croneter"> <addon id="plugin.video.plexkodiconnect" name="PlexKodiConnect" version="2.0.30" 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.9.1" /> <import addon="script.module.requests" version="2.9.1" />
@ -67,7 +67,13 @@
<summary lang="ru_RU">Нативная интеграция сервера Plex в Kodi</summary> <summary lang="ru_RU">Нативная интеграция сервера Plex в Kodi</summary>
<description lang="ru_RU">Подключите Kodi к своему серверу Plex. Плагин предполагает что вы управляете своими видео с помощью Plex (а не в Kodi). Вы можете потерять текущие базы данных музыки и видео в Kodi (так как плагин напрямую их изменяет). Используйте на свой страх и риск</description> <description lang="ru_RU">Подключите Kodi к своему серверу Plex. Плагин предполагает что вы управляете своими видео с помощью Plex (а не в Kodi). Вы можете потерять текущие базы данных музыки и видео в Kodi (так как плагин напрямую их изменяет). Используйте на свой страх и риск</description>
<disclaimer lang="ru_RU">Используйте на свой страх и риск</disclaimer> <disclaimer lang="ru_RU">Используйте на свой страх и риск</disclaimer>
<news>version 2.0.29 (beta only): <news>version 2.0.30 (beta only):
- Fix resume for On Deck widget for direct paths
- Fix DB reset on Startup if PMS connection fails
- Fix searching for PMS if there is no internet connection
- Fix context menu missing "Delete item from PMS"
version 2.0.29 (beta only):
- Fix a racing condition leading to e.g. Plex Companion not working as intended - Fix a racing condition leading to e.g. Plex Companion not working as intended
- Force a sync on startup even if Kodi is playing something - Force a sync on startup even if Kodi is playing something
- Include Plex Home username in "Log-out Plex Home user" - Include Plex Home username in "Log-out Plex Home user"

View file

@ -1,3 +1,9 @@
version 2.0.30 (beta only):
- Fix resume for On Deck widget for direct paths
- Fix DB reset on Startup if PMS connection fails
- Fix searching for PMS if there is no internet connection
- Fix context menu missing "Delete item from PMS"
version 2.0.29 (beta only): version 2.0.29 (beta only):
- Fix a racing condition leading to e.g. Plex Companion not working as intended - Fix a racing condition leading to e.g. Plex Companion not working as intended
- Force a sync on startup even if Kodi is playing something - Force a sync on startup even if Kodi is playing something

View file

@ -112,15 +112,20 @@ class API(object):
""" """
return self.item.get('ratingKey') return self.item.get('ratingKey')
def path(self, force_first_media=True, force_addon=False): def path(self, force_first_media=True, force_addon=False,
direct_paths=None):
""" """
Returns a "fully qualified path": add-on paths or direct paths Returns a "fully qualified path": add-on paths or direct paths
depending on the current settings. Will NOT valide the playurl depending on the current settings. Will NOT valide the playurl
Returns unicode or None if something went wrong. Returns unicode or None if something went wrong.
Pass direct_path=True if you're calling from another Plex python
instance - because otherwise direct paths will evaluate to False!
""" """
direct_paths = direct_paths or state.DIRECT_PATHS
filename = self.file_path(force_first_media=force_first_media) filename = self.file_path(force_first_media=force_first_media)
if (not state.DIRECT_PATHS or force_addon if (not direct_paths or force_addon or
or self.plex_type() == v.PLEX_TYPE_CLIP): self.plex_type() == v.PLEX_TYPE_CLIP):
if filename and '/' in filename: if filename and '/' in filename:
filename = filename.rsplit('/', 1) filename = filename.rsplit('/', 1)
elif filename: elif filename:

View file

@ -330,7 +330,7 @@ def _pms_list_from_plex_tv(token):
xml.attrib xml.attrib
except AttributeError: except AttributeError:
LOG.error('Could not get list of PMS from plex.tv') LOG.error('Could not get list of PMS from plex.tv')
return return []
from Queue import Queue from Queue import Queue
queue = Queue() queue = Queue()

View file

@ -529,40 +529,45 @@ def getOnDeck(viewid, mediatype, tagname, limit):
xbmcplugin.setContent(HANDLE, 'episodes') xbmcplugin.setContent(HANDLE, 'episodes')
append_show_title = settings('OnDeckTvAppendShow') == 'true' append_show_title = settings('OnDeckTvAppendShow') == 'true'
append_sxxexx = settings('OnDeckTvAppendSeason') == 'true' append_sxxexx = settings('OnDeckTvAppendSeason') == 'true'
directpaths = settings('useDirectPaths') == 'true'
if settings('OnDeckTVextended') == 'false': if settings('OnDeckTVextended') == 'false':
# Chances are that this view is used on Kodi startup # Chances are that this view is used on Kodi startup
# Wait till we've connected to a PMS. At most 30s # Wait till we've connected to a PMS. At most 30s
counter = 0 counter = 0
while window('plex_authenticated') != 'true': while window('plex_authenticated') != 'true':
counter += 1 counter += 1
if counter >= 300: if counter == 300:
log.error('Aborting On Deck view, we were not authenticated ' log.error('Aborting On Deck view, we were not authenticated '
'for the PMS') 'for the PMS')
return xbmcplugin.endOfDirectory(HANDLE, False) xbmcplugin.endOfDirectory(HANDLE, False)
return
sleep(100) sleep(100)
xml = downloadutils.DownloadUtils().downloadUrl( xml = downloadutils.DownloadUtils().downloadUrl(
'{server}/library/sections/%s/onDeck' % viewid) '{server}/library/sections/%s/onDeck' % viewid)
if xml in (None, 401): if xml in (None, 401):
log.error('Could not download PMS xml for view %s' % viewid) log.error('Could not download PMS xml for view %s' % viewid)
return xbmcplugin.endOfDirectory(HANDLE) xbmcplugin.endOfDirectory(HANDLE, False)
limitcounter = 0 return
direct_paths = settings('useDirectPaths') == '1'
counter = 0
for item in xml: for item in xml:
api = API(item) api = API(item)
listitem = api.create_listitem( listitem = api.create_listitem(
append_show_title=append_show_title, append_show_title=append_show_title,
append_sxxexx=append_sxxexx) append_sxxexx=append_sxxexx)
url = api.path() if api.resume_point():
listitem.setProperty('resumetime', str(api.resume_point()))
path = api.path(force_first_media=False, direct_paths=direct_paths)
xbmcplugin.addDirectoryItem( xbmcplugin.addDirectoryItem(
handle=HANDLE, handle=HANDLE,
url=url, url=path,
listitem=listitem) listitem=listitem)
limitcounter += 1 counter += 1
if limitcounter == limit: if counter == limit:
break break
return xbmcplugin.endOfDirectory( xbmcplugin.endOfDirectory(
handle=HANDLE, handle=HANDLE,
cacheToDisc=settings('enableTextureCache') == 'true') cacheToDisc=settings('enableTextureCache') == 'true')
return
# if the addon is called with nextup parameter, # if the addon is called with nextup parameter,
# we return the nextepisodes list of the given tagname # we return the nextepisodes list of the given tagname
@ -661,8 +666,9 @@ def watchlater():
log.info('Displaying watch later plex.tv items') log.info('Displaying watch later plex.tv items')
xbmcplugin.setContent(HANDLE, 'movies') xbmcplugin.setContent(HANDLE, 'movies')
direct_paths = settings('useDirectPaths') == '1'
for item in xml: for item in xml:
__build_item(item) __build_item(item, direct_paths)
xbmcplugin.endOfDirectory( xbmcplugin.endOfDirectory(
handle=HANDLE, handle=HANDLE,
@ -715,12 +721,13 @@ def browse_plex(key=None, plex_section_id=None):
artists = False artists = False
albums = False albums = False
musicvideos = False musicvideos = False
direct_paths = settings('useDirectPaths') == '1'
for item in xml: for item in xml:
if item.tag == 'Directory': if item.tag == 'Directory':
__build_folder(item, plex_section_id=plex_section_id) __build_folder(item, plex_section_id=plex_section_id)
else: else:
typus = item.attrib.get('type') typus = item.attrib.get('type')
__build_item(item) __build_item(item, direct_paths)
if typus == v.PLEX_TYPE_PHOTO: if typus == v.PLEX_TYPE_PHOTO:
photos = True photos = True
elif typus == v.PLEX_TYPE_MOVIE: elif typus == v.PLEX_TYPE_MOVIE:
@ -803,7 +810,7 @@ def __build_folder(xml_element, plex_section_id=None):
listitem=listitem) listitem=listitem)
def __build_item(xml_element): def __build_item(xml_element, direct_paths):
api = API(xml_element) api = API(xml_element)
listitem = api.create_listitem() listitem = api.create_listitem()
resume = api.resume_point() resume = api.resume_point()
@ -820,7 +827,7 @@ def __build_item(xml_element):
elif api.plex_type() == v.PLEX_TYPE_PHOTO: elif api.plex_type() == v.PLEX_TYPE_PHOTO:
url = api.get_picture_path() url = api.get_picture_path()
else: else:
url = api.path() url = api.path(direct_paths=direct_paths)
if api.resume_point(): if api.resume_point():
listitem.setProperty('resumetime', str(api.resume_point())) listitem.setProperty('resumetime', str(api.resume_point()))
xbmcplugin.addDirectoryItem(handle=HANDLE, xbmcplugin.addDirectoryItem(handle=HANDLE,

View file

@ -128,10 +128,9 @@ def _write_pms_settings(url, token):
return return
for entry in xml: for entry in xml:
if entry.attrib.get('id', '') == 'allowMediaDeletion': if entry.attrib.get('id', '') == 'allowMediaDeletion':
settings('plex_allows_mediaDeletion', value = 'true' if entry.get('value', '1') == '1' else 'false'
value=entry.attrib.get('value', 'true')) settings('plex_allows_mediaDeletion', value=value)
window('plex_allows_mediaDeletion', window('plex_allows_mediaDeletion', value=value)
value=entry.attrib.get('value', 'true'))
class InitialSetup(object): class InitialSetup(object):

View file

@ -434,9 +434,6 @@ class LibrarySync(Thread):
""" """
Compare the views to Plex Compare the views to Plex
""" """
self.views = []
vnodes = self.vnodes
# Get views # Get views
sections = PF.get_plex_sections() sections = PF.get_plex_sections()
try: try:
@ -447,6 +444,8 @@ class LibrarySync(Thread):
if state.DIRECT_PATHS is True and state.ENABLE_MUSIC is True: if state.DIRECT_PATHS is True and state.ENABLE_MUSIC is True:
# Will reboot Kodi is new library detected # Will reboot Kodi is new library detected
music.excludefromscan_music_folders(xml=sections) music.excludefromscan_music_folders(xml=sections)
self.views = []
vnodes = self.vnodes
self.nodes = { self.nodes = {
v.PLEX_TYPE_MOVIE: [], v.PLEX_TYPE_MOVIE: [],
@ -1528,10 +1527,6 @@ class LibrarySync(Thread):
LOG.info("Db version: %s", settings('dbCreatedWithVersion')) LOG.info("Db version: %s", settings('dbCreatedWithVersion'))
LOG.info('Refreshing video nodes and playlists now') LOG.info('Refreshing video nodes and playlists now')
# Completely refresh Kodi playlists and video nodes
utils.delete_playlists()
utils.delete_nodes()
self.maintain_views()
# Setup the paths for addon-paths (even when using direct paths) # Setup the paths for addon-paths (even when using direct paths)
with kodidb.GetKodiDB('video') as kodi_db: with kodidb.GetKodiDB('video') as kodi_db:
kodi_db.setup_path_table() kodi_db.setup_path_table()
@ -1557,7 +1552,12 @@ class LibrarySync(Thread):
last_time_sync = utils.unix_timestamp() last_time_sync = utils.unix_timestamp()
LOG.info('Initial start-up full sync starting') LOG.info('Initial start-up full sync starting')
xbmc.executebuiltin('InhibitIdleShutdown(true)') xbmc.executebuiltin('InhibitIdleShutdown(true)')
if self.full_sync(): # Completely refresh Kodi playlists and video nodes
utils.delete_playlists()
utils.delete_nodes()
if not self.maintain_views():
LOG.error('Initial maintain_views not successful')
elif self.full_sync():
LOG.info('Initial start-up full sync successful') LOG.info('Initial start-up full sync successful')
settings('SyncInstallRunDone', value='true') settings('SyncInstallRunDone', value='true')
self.install_sync_done = True self.install_sync_done = True
@ -1608,7 +1608,12 @@ class LibrarySync(Thread):
if state.SUSPEND_SYNC: if state.SUSPEND_SYNC:
LOG.warning('Forcing startup sync even if Kodi is playing') LOG.warning('Forcing startup sync even if Kodi is playing')
state.SUSPEND_SYNC = False state.SUSPEND_SYNC = False
if self.full_sync(): # Completely refresh Kodi playlists and video nodes
utils.delete_playlists()
utils.delete_nodes()
if not self.maintain_views():
LOG.info('Initial maintain_views on startup unsuccessful')
elif self.full_sync():
initial_sync_done = True initial_sync_done = True
last_sync = utils.unix_timestamp() last_sync = utils.unix_timestamp()
LOG.info('Done initial sync on Kodi startup') LOG.info('Done initial sync on Kodi startup')