Merge branch 'master' into playlists
This commit is contained in:
commit
136461160f
8 changed files with 59 additions and 62 deletions
|
@ -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.28-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.29-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)
|
||||||
|
|
11
addon.xml
11
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="2.0.28" provider-name="croneter">
|
<addon id="plugin.video.plexkodiconnect" name="PlexKodiConnect" version="2.0.29" 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,14 @@
|
||||||
<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.28 (beta only):
|
<news>version 2.0.29 (beta only):
|
||||||
|
- 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
|
||||||
|
- Include Plex Home username in "Log-out Plex Home user"
|
||||||
|
- Direct paths: Don't download PMS sections twice
|
||||||
|
- Less logging
|
||||||
|
|
||||||
|
version 2.0.28 (beta only):
|
||||||
- Fix endless reboots if Plex music library missing
|
- Fix endless reboots if Plex music library missing
|
||||||
- Fix Plex Companion failing leading to PMS connection loss
|
- Fix Plex Companion failing leading to PMS connection loss
|
||||||
- Fix PKC add-on setting user changes not saving
|
- Fix PKC add-on setting user changes not saving
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
version 2.0.29 (beta only):
|
||||||
|
- 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
|
||||||
|
- Include Plex Home username in "Log-out Plex Home user"
|
||||||
|
- Direct paths: Don't download PMS sections twice
|
||||||
|
- Less logging
|
||||||
|
|
||||||
version 2.0.28 (beta only):
|
version 2.0.28 (beta only):
|
||||||
- Fix endless reboots if Plex music library missing
|
- Fix endless reboots if Plex music library missing
|
||||||
- Fix Plex Companion failing leading to PMS connection loss
|
- Fix Plex Companion failing leading to PMS connection loss
|
||||||
|
|
|
@ -146,7 +146,7 @@ def doMainListing(content_type=None):
|
||||||
addDirectoryItem(lang(30173),
|
addDirectoryItem(lang(30173),
|
||||||
"plugin://%s?mode=channels" % v.ADDON_ID)
|
"plugin://%s?mode=channels" % v.ADDON_ID)
|
||||||
# Plex user switch
|
# Plex user switch
|
||||||
addDirectoryItem(lang(39200),
|
addDirectoryItem('%s%s' % (lang(39200), settings('username')),
|
||||||
"plugin://%s?mode=switchuser" % v.ADDON_ID)
|
"plugin://%s?mode=switchuser" % v.ADDON_ID)
|
||||||
|
|
||||||
# some extra entries for settings and stuff
|
# some extra entries for settings and stuff
|
||||||
|
|
|
@ -678,7 +678,7 @@ class KodiDBMethods(object):
|
||||||
self.cursor.execute(query, (path,))
|
self.cursor.execute(query, (path,))
|
||||||
path_ids = self.cursor.fetchall()
|
path_ids = self.cursor.fetchall()
|
||||||
if len(path_ids) != 1:
|
if len(path_ids) != 1:
|
||||||
LOG.error('Found wrong number of path ids: %s for path %s, abort',
|
LOG.debug('Found wrong number of path ids: %s for path %s, abort',
|
||||||
path_ids, path)
|
path_ids, path)
|
||||||
return
|
return
|
||||||
query = '''
|
query = '''
|
||||||
|
|
|
@ -434,10 +434,6 @@ class LibrarySync(Thread):
|
||||||
"""
|
"""
|
||||||
Compare the views to Plex
|
Compare the views to Plex
|
||||||
"""
|
"""
|
||||||
if state.DIRECT_PATHS is True and state.ENABLE_MUSIC is True:
|
|
||||||
# Will reboot Kodi is new library detected
|
|
||||||
music.excludefromscan_music_folders()
|
|
||||||
|
|
||||||
self.views = []
|
self.views = []
|
||||||
vnodes = self.vnodes
|
vnodes = self.vnodes
|
||||||
|
|
||||||
|
@ -448,6 +444,9 @@ class LibrarySync(Thread):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
LOG.error("Error download PMS views, abort maintain_views")
|
LOG.error("Error download PMS views, abort maintain_views")
|
||||||
return False
|
return False
|
||||||
|
if state.DIRECT_PATHS is True and state.ENABLE_MUSIC is True:
|
||||||
|
# Will reboot Kodi is new library detected
|
||||||
|
music.excludefromscan_music_folders(xml=sections)
|
||||||
|
|
||||||
self.nodes = {
|
self.nodes = {
|
||||||
v.PLEX_TYPE_MOVIE: [],
|
v.PLEX_TYPE_MOVIE: [],
|
||||||
|
@ -1606,6 +1605,9 @@ class LibrarySync(Thread):
|
||||||
state.DB_SCAN = True
|
state.DB_SCAN = True
|
||||||
window('plex_dbScan', value="true")
|
window('plex_dbScan', value="true")
|
||||||
LOG.info('Doing initial sync on Kodi startup')
|
LOG.info('Doing initial sync on Kodi startup')
|
||||||
|
if state.SUSPEND_SYNC:
|
||||||
|
LOG.warning('Forcing startup sync even if Kodi is playing')
|
||||||
|
state.SUSPEND_SYNC = False
|
||||||
if self.full_sync():
|
if self.full_sync():
|
||||||
initial_sync_done = True
|
initial_sync_done = True
|
||||||
last_sync = utils.unix_timestamp()
|
last_sync = utils.unix_timestamp()
|
||||||
|
|
|
@ -4,7 +4,6 @@ from re import compile as re_compile
|
||||||
from xml.etree.ElementTree import ParseError
|
from xml.etree.ElementTree import ParseError
|
||||||
|
|
||||||
from utils import XmlKodiSetting, reboot_kodi, language as lang
|
from utils import XmlKodiSetting, reboot_kodi, language as lang
|
||||||
from PlexFunctions import get_plex_sections
|
|
||||||
from PlexAPI import API
|
from PlexAPI import API
|
||||||
import variables as v
|
import variables as v
|
||||||
|
|
||||||
|
@ -15,21 +14,15 @@ REGEX_MUSICPATH = re_compile(r'''^\^(.+)\$$''')
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
def excludefromscan_music_folders():
|
def excludefromscan_music_folders(xml):
|
||||||
"""
|
"""
|
||||||
Gets a complete list of paths for music libraries from the PMS. Sets them
|
Gets a complete list of paths for music libraries from the PMS. Sets them
|
||||||
to be excluded in the advancedsettings.xml from being scanned by Kodi.
|
to be excluded in the advancedsettings.xml from being scanned by Kodi.
|
||||||
Existing keys will be replaced
|
Existing keys will be replaced
|
||||||
|
xml: etree XML PMS answer containing all library sections
|
||||||
|
|
||||||
Reboots Kodi if new library detected
|
Reboots Kodi if new library detected
|
||||||
"""
|
"""
|
||||||
xml = get_plex_sections()
|
|
||||||
try:
|
|
||||||
xml[0].attrib
|
|
||||||
except (TypeError, IndexError, AttributeError):
|
|
||||||
LOG.error('Could not get Plex sections')
|
|
||||||
return
|
|
||||||
# Build paths
|
|
||||||
paths = []
|
paths = []
|
||||||
reboot = False
|
reboot = False
|
||||||
api = API(item=None)
|
api = API(item=None)
|
||||||
|
@ -46,8 +39,8 @@ def excludefromscan_music_folders():
|
||||||
try:
|
try:
|
||||||
with XmlKodiSetting('advancedsettings.xml',
|
with XmlKodiSetting('advancedsettings.xml',
|
||||||
force_create=True,
|
force_create=True,
|
||||||
top_element='advancedsettings') as xml:
|
top_element='advancedsettings') as xml_file:
|
||||||
parent = xml.set_setting(['audio', 'excludefromscan'])
|
parent = xml_file.set_setting(['audio', 'excludefromscan'])
|
||||||
for path in paths:
|
for path in paths:
|
||||||
for element in parent:
|
for element in parent:
|
||||||
if element.text == path:
|
if element.text == path:
|
||||||
|
@ -55,14 +48,15 @@ def excludefromscan_music_folders():
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
LOG.info('New Plex music library detected: %s', path)
|
LOG.info('New Plex music library detected: %s', path)
|
||||||
xml.set_setting(['audio', 'excludefromscan', 'regexp'],
|
xml_file.set_setting(['audio', 'excludefromscan', 'regexp'],
|
||||||
value=path, append=True)
|
value=path,
|
||||||
|
append=True)
|
||||||
if paths:
|
if paths:
|
||||||
# We only need to reboot if we ADD new paths!
|
# We only need to reboot if we ADD new paths!
|
||||||
reboot = xml.write_xml
|
reboot = xml_file.write_xml
|
||||||
# Delete obsolete entries
|
# Delete obsolete entries
|
||||||
# Make sure we're not saving an empty audio-excludefromscan
|
# Make sure we're not saving an empty audio-excludefromscan
|
||||||
xml.write_xml = reboot
|
xml_file.write_xml = reboot
|
||||||
for element in parent:
|
for element in parent:
|
||||||
for path in paths:
|
for path in paths:
|
||||||
if element.text == path:
|
if element.text == path:
|
||||||
|
@ -71,10 +65,9 @@ def excludefromscan_music_folders():
|
||||||
LOG.info('Deleting music library from advancedsettings: %s',
|
LOG.info('Deleting music library from advancedsettings: %s',
|
||||||
element.text)
|
element.text)
|
||||||
parent.remove(element)
|
parent.remove(element)
|
||||||
xml.write_xml = True
|
xml_file.write_xml = True
|
||||||
except (ParseError, IOError):
|
except (ParseError, IOError):
|
||||||
LOG.error('Could not adjust advancedsettings.xml')
|
LOG.error('Could not adjust advancedsettings.xml')
|
||||||
reboot = False
|
|
||||||
if reboot is True:
|
if reboot is True:
|
||||||
# '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.'
|
||||||
|
|
|
@ -179,43 +179,39 @@ class PlayqueueMonitor(Thread):
|
||||||
elif identical:
|
elif identical:
|
||||||
LOG.debug('Detected playqueue item %s moved to position %s',
|
LOG.debug('Detected playqueue item %s moved to position %s',
|
||||||
i + j, i)
|
i + j, i)
|
||||||
with LOCK:
|
PL.move_playlist_item(playqueue, i + j, i)
|
||||||
PL.move_playlist_item(playqueue, i + j, i)
|
|
||||||
del old[j], index[j]
|
del old[j], index[j]
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
LOG.debug('Detected new Kodi element at position %s: %s ',
|
LOG.debug('Detected new Kodi element at position %s: %s ',
|
||||||
i, new_item)
|
i, new_item)
|
||||||
with LOCK:
|
try:
|
||||||
try:
|
if playqueue.id is None:
|
||||||
if playqueue.id is None:
|
PL.init_plex_playqueue(playqueue, kodi_item=new_item)
|
||||||
PL.init_plex_playqueue(playqueue,
|
|
||||||
kodi_item=new_item)
|
|
||||||
else:
|
|
||||||
PL.add_item_to_plex_playqueue(playqueue,
|
|
||||||
i,
|
|
||||||
kodi_item=new_item)
|
|
||||||
except PL.PlaylistError:
|
|
||||||
# Could not add the element
|
|
||||||
pass
|
|
||||||
except IndexError:
|
|
||||||
# This is really a hack - happens when using Addon Paths
|
|
||||||
# and repeatedly starting the same element. Kodi will
|
|
||||||
# then not pass kodi id nor file path AND will also not
|
|
||||||
# start-up playback. Hence kodimonitor kicks off
|
|
||||||
# playback. Also see kodimonitor.py - _playlist_onadd()
|
|
||||||
pass
|
|
||||||
else:
|
else:
|
||||||
for j in range(i, len(index)):
|
PL.add_item_to_plex_playqueue(playqueue,
|
||||||
index[j] += 1
|
i,
|
||||||
|
kodi_item=new_item)
|
||||||
|
except PL.PlaylistError:
|
||||||
|
# Could not add the element
|
||||||
|
pass
|
||||||
|
except IndexError:
|
||||||
|
# This is really a hack - happens when using Addon Paths
|
||||||
|
# and repeatedly starting the same element. Kodi will then
|
||||||
|
# not pass kodi id nor file path AND will also not
|
||||||
|
# start-up playback. Hence kodimonitor kicks off playback.
|
||||||
|
# Also see kodimonitor.py - _playlist_onadd()
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
for j in range(i, len(index)):
|
||||||
|
index[j] += 1
|
||||||
for i in reversed(index):
|
for i in reversed(index):
|
||||||
if self.stopped():
|
if self.stopped():
|
||||||
# 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
|
||||||
LOG.debug('Detected deletion of playqueue element at pos %s', i)
|
LOG.debug('Detected deletion of playqueue element at pos %s', i)
|
||||||
with LOCK:
|
PL.delete_playlist_item_from_PMS(playqueue, i)
|
||||||
PL.delete_playlist_item_from_PMS(playqueue, i)
|
|
||||||
LOG.debug('Done comparing playqueues')
|
LOG.debug('Done comparing playqueues')
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
@ -227,8 +223,6 @@ class PlayqueueMonitor(Thread):
|
||||||
if stopped():
|
if stopped():
|
||||||
break
|
break
|
||||||
sleep(1000)
|
sleep(1000)
|
||||||
work = []
|
|
||||||
# Detect changed playqueues first, do the work afterwards
|
|
||||||
with LOCK:
|
with LOCK:
|
||||||
for playqueue in PLAYQUEUES:
|
for playqueue in PLAYQUEUES:
|
||||||
kodi_pl = js.playlist_get_items(playqueue.playlistid)
|
kodi_pl = js.playlist_get_items(playqueue.playlistid)
|
||||||
|
@ -238,15 +232,9 @@ class PlayqueueMonitor(Thread):
|
||||||
# Only initialize if directly fired up using direct
|
# Only initialize if directly fired up using direct
|
||||||
# paths. Otherwise let default.py do its magic
|
# paths. Otherwise let default.py do its magic
|
||||||
LOG.debug('Not yet initiating playback')
|
LOG.debug('Not yet initiating playback')
|
||||||
elif playqueue.pkc_edit:
|
|
||||||
playqueue.pkc_edit = False
|
|
||||||
LOG.debug('PKC edited the playqueue - skipping')
|
|
||||||
else:
|
else:
|
||||||
# We do need to update our playqueues
|
# compare old and new playqueue
|
||||||
work.append((playqueue, kodi_pl))
|
self._compare_playqueues(playqueue, kodi_pl)
|
||||||
playqueue.old_kodi_pl = kodi_pl
|
playqueue.old_kodi_pl = list(kodi_pl)
|
||||||
# Now do the work - LOCK individual playqueue edits
|
|
||||||
for playqueue, kodi_pl in work:
|
|
||||||
self._compare_playqueues(playqueue, kodi_pl)
|
|
||||||
sleep(200)
|
sleep(200)
|
||||||
LOG.info("----===## PlayqueueMonitor stopped ##===----")
|
LOG.info("----===## PlayqueueMonitor stopped ##===----")
|
||||||
|
|
Loading…
Reference in a new issue