Merge pull request #796 from croneter/beta-version

Bump master
This commit is contained in:
croneter 2019-03-26 18:53:27 +01:00 committed by GitHub
commit 0373029238
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 102 additions and 37 deletions

View file

@ -1,5 +1,5 @@
[![stable version](https://img.shields.io/badge/stable_version-2.7.8-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-2.7.9-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.7.8-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.7.9-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.7.8" provider-name="croneter"> <addon id="plugin.video.plexkodiconnect" name="PlexKodiConnect" version="2.7.9" 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" />
@ -77,7 +77,13 @@
<summary lang="uk_UA">Нативна інтеграція Plex в Kodi</summary> <summary lang="uk_UA">Нативна інтеграція Plex в Kodi</summary>
<description lang="uk_UA">Підключає Kodi до серверу Plex. Цей плагін передбачає, що ви керуєте всіма своїми відео за допомогою Plex (і ніяк не Kodi). Ви можете втратити дані, які вже зберігаються у відео та музичних БД Kodi (оскільки цей плагін безпосередньо їх змінює). Використовуйте на свій страх і ризик!</description> <description lang="uk_UA">Підключає Kodi до серверу Plex. Цей плагін передбачає, що ви керуєте всіма своїми відео за допомогою Plex (і ніяк не Kodi). Ви можете втратити дані, які вже зберігаються у відео та музичних БД Kodi (оскільки цей плагін безпосередньо їх змінює). Використовуйте на свій страх і ризик!</description>
<disclaimer lang="uk_UA">Використовуйте на свій ризик</disclaimer> <disclaimer lang="uk_UA">Використовуйте на свій ризик</disclaimer>
<news>version 2.7.8: <news>version 2.7.9:
- Wait for PKC to authorize before loading widgets
- Fix UnicodeDecodeError for libraries with non-ASCII paths
- Fix TypeError on Kodi start
- Fix Kodi Masterlock for nfs paths (requires restart)
version 2.7.8:
- Fix widgets not working in some cases like NVidia Shield - Fix widgets not working in some cases like NVidia Shield
- Fix appending of show title, season and episode number - Fix appending of show title, season and episode number
- Fix node paths for skins - Fix node paths for skins

View file

@ -1,3 +1,9 @@
version 2.7.9:
- Wait for PKC to authorize before loading widgets
- Fix UnicodeDecodeError for libraries with non-ASCII paths
- Fix TypeError on Kodi start
- Fix Kodi Masterlock for nfs paths (requires restart)
version 2.7.8: version 2.7.8:
- Fix widgets not working in some cases like NVidia Shield - Fix widgets not working in some cases like NVidia Shield
- Fix appending of show title, season and episode number - Fix appending of show title, season and episode number

View file

@ -57,6 +57,30 @@ def guess_content_type():
return content_type return content_type
def _wait_for_auth():
"""
Call to be sure that PKC is authenticated, e.g. for widgets on Kodi startup.
Will wait for at most 30s, then fail if not authenticated. Will set
xbmcplugin.endOfDirectory(int(argv[1]), False) if failed
WARNING - this will potentially stall the shutdown of Kodi since we cannot
poll xbmc.Monitor().abortRequested() or waitForAbort() or
xbmc.abortRequested
"""
counter = 0
startupdelay = int(utils.settings('startupDelay') or 0)
# Wait for <startupdelay in seconds> + 10 seconds at most
startupdelay = 10 * startupdelay + 100
while utils.window('plex_authenticated') != 'true':
counter += 1
if counter == startupdelay:
LOG.error('Aborting view, we were not authenticated for PMS')
xbmcplugin.endOfDirectory(int(sys.argv[1]), False)
return False
xbmc.sleep(100)
return True
def directory_item(label, path, folder=True): def directory_item(label, path, folder=True):
""" """
Adds a xbmcplugin.addDirectoryItem() directory itemlistitem Adds a xbmcplugin.addDirectoryItem() directory itemlistitem
@ -228,6 +252,8 @@ def get_video_files(plex_id, params):
if plex_id is None: if plex_id is None:
LOG.info('No Plex ID found, abort getting Extras') LOG.info('No Plex ID found, abort getting Extras')
return xbmcplugin.endOfDirectory(int(sys.argv[1])) return xbmcplugin.endOfDirectory(int(sys.argv[1]))
if not _wait_for_auth():
return xbmcplugin.endOfDirectory(int(sys.argv[1]), False)
app.init(entrypoint=True) app.init(entrypoint=True)
item = PF.GetPlexMetadata(plex_id) item = PF.GetPlexMetadata(plex_id)
try: try:
@ -285,6 +311,8 @@ def extra_fanart(plex_id, plex_path):
# because of the caching system in xbmc # because of the caching system in xbmc
fanart_dir = path_ops.translate_path("special://thumbnails/plex/%s/" fanart_dir = path_ops.translate_path("special://thumbnails/plex/%s/"
% plex_id) % plex_id)
if not _wait_for_auth():
return xbmcplugin.endOfDirectory(int(sys.argv[1]), False)
if not path_ops.exists(fanart_dir): if not path_ops.exists(fanart_dir):
# Download the images to the cache directory # Download the images to the cache directory
path_ops.makedirs(fanart_dir) path_ops.makedirs(fanart_dir)
@ -329,6 +357,8 @@ def playlists(content_type):
""" """
content_type = content_type or guess_content_type() content_type = content_type or guess_content_type()
LOG.debug('Listing Plex %s playlists', content_type) LOG.debug('Listing Plex %s playlists', content_type)
if not _wait_for_auth():
return xbmcplugin.endOfDirectory(int(sys.argv[1]), False)
app.init(entrypoint=True) app.init(entrypoint=True)
from .playlists.pms import all_playlists from .playlists.pms import all_playlists
xml = all_playlists() xml = all_playlists()
@ -352,6 +382,8 @@ def hub(content_type):
""" """
content_type = content_type or guess_content_type() content_type = content_type or guess_content_type()
LOG.debug('Showing Plex Hub entries for %s', content_type) LOG.debug('Showing Plex Hub entries for %s', content_type)
if not _wait_for_auth():
return xbmcplugin.endOfDirectory(int(sys.argv[1]), False)
app.init(entrypoint=True) app.init(entrypoint=True)
xml = PF.get_plex_hub() xml = PF.get_plex_hub()
try: try:
@ -385,6 +417,8 @@ def watchlater():
""" """
Listing for plex.tv Watch Later section (if signed in to plex.tv) Listing for plex.tv Watch Later section (if signed in to plex.tv)
""" """
if not _wait_for_auth():
return xbmcplugin.endOfDirectory(int(sys.argv[1]), False)
if utils.window('plex_token') == '': if utils.window('plex_token') == '':
LOG.error('No watch later - not signed in to plex.tv') LOG.error('No watch later - not signed in to plex.tv')
return xbmcplugin.endOfDirectory(int(sys.argv[1]), False) return xbmcplugin.endOfDirectory(int(sys.argv[1]), False)
@ -412,6 +446,8 @@ def browse_plex(key=None, plex_type=None, section_id=None, synched=True,
""" """
LOG.debug('Browsing to key %s, section %s, plex_type: %s, synched: %s, ' LOG.debug('Browsing to key %s, section %s, plex_type: %s, synched: %s, '
'prompt "%s"', key, section_id, plex_type, synched, prompt) 'prompt "%s"', key, section_id, plex_type, synched, prompt)
if not _wait_for_auth():
return xbmcplugin.endOfDirectory(int(sys.argv[1]), False)
app.init(entrypoint=True) app.init(entrypoint=True)
if prompt: if prompt:
prompt = utils.dialog('input', prompt) prompt = utils.dialog('input', prompt)
@ -429,6 +465,7 @@ def browse_plex(key=None, plex_type=None, section_id=None, synched=True,
except AttributeError: except AttributeError:
LOG.error('Could not browse to key %s, section %s', LOG.error('Could not browse to key %s, section %s',
key, section_id) key, section_id)
return
show_listing(xml, plex_type, section_id, synched, key) show_listing(xml, plex_type, section_id, synched, key)
@ -436,6 +473,8 @@ def extras(plex_id):
""" """
Lists all extras for plex_id Lists all extras for plex_id
""" """
if not _wait_for_auth():
return xbmcplugin.endOfDirectory(int(sys.argv[1]), False)
app.init(entrypoint=True) app.init(entrypoint=True)
xml = PF.GetPlexMetadata(plex_id) xml = PF.GetPlexMetadata(plex_id)
try: try:

View file

@ -466,6 +466,31 @@ class InitialSetup(object):
server['machineIdentifier'], server['ip'], server['port'], server['machineIdentifier'], server['ip'], server['port'],
server['scheme']) server['scheme'])
@staticmethod
def _add_sources(root, extension):
changed = False
count = 2
for source in root.findall('.//path'):
if source.text == extension:
count -= 1
if count == 0:
# sources already set
break
else:
# Missing smb:// occurences, re-add.
changed = True
for _ in range(0, count):
source = etree.SubElement(root, 'source')
etree.SubElement(
source,
'name').text = "PlexKodiConnect Masterlock Hack"
etree.SubElement(
source,
'path',
{'pathversion': "1"}).text = extension
etree.SubElement(source, 'allowsharing').text = "true"
return changed
def setup(self): def setup(self):
""" """
Initial setup. Run once upon startup. Initial setup. Run once upon startup.
@ -507,28 +532,13 @@ class InitialSetup(object):
with utils.XmlKodiSetting('sources.xml', with utils.XmlKodiSetting('sources.xml',
force_create=True, force_create=True,
top_element='sources') as xml: top_element='sources') as xml:
root = xml.set_setting(['video']) changed = False
count = 2 for extension in ('smb://', 'nfs://'):
for source in root.findall('.//path'): root = xml.set_setting(['video'])
if source.text == "smb://": changed = self._add_sources(root, extension) or changed
count -= 1 if changed:
if count == 0: xml.write_xml = True
# sources already set reboot = True
break
else:
# Missing smb:// occurences, re-add.
for _ in range(0, count):
source = etree.SubElement(root, 'source')
etree.SubElement(
source,
'name').text = "PlexKodiConnect Masterlock Hack"
etree.SubElement(
source,
'path',
{'pathversion': "1"}).text = "smb://"
etree.SubElement(source, 'allowsharing').text = "true"
if reboot is False:
reboot = xml.write_xml
except utils.ParseError: except utils.ParseError:
pass pass

View file

@ -57,24 +57,28 @@ def process_method_on_list(method_to_run, items):
def get_clean_image(image): def get_clean_image(image):
'''helper to strip all kodi tags/formatting of an image path/url''' '''
helper to strip all kodi tags/formatting of an image path/url
Pass in either unicode or str; returns unicode
'''
if not image: if not image:
return "" return ""
if "music@" in image: if not isinstance(image, str):
image = image.encode('utf-8')
if b"music@" in image:
# fix for embedded images # fix for embedded images
thumbcache = xbmc.getCacheThumbName(image).replace(".tbn", ".jpg") thumbcache = xbmc.getCacheThumbName(image)
thumbcache = "special://thumbnails/%s/%s" % (thumbcache[0], thumbcache) thumbcache = thumbcache.replace(b".tbn", b".jpg")
thumbcache = b"special://thumbnails/%s/%s" % (thumbcache[0], thumbcache)
if not xbmcvfs.exists(thumbcache): if not xbmcvfs.exists(thumbcache):
xbmcvfs.copy(image, thumbcache) xbmcvfs.copy(image, thumbcache)
image = thumbcache image = thumbcache
if image and "image://" in image: if image and b"image://" in image:
image = image.replace("image://", "") image = image.replace(b"image://", b"")
image = urllib.unquote(image.encode("utf-8")) image = urllib.unquote(image)
if image.endswith("/"): if image.endswith(b"/"):
image = image[:-1] image = image[:-1]
if not isinstance(image, unicode): return image.decode('utf-8')
image = image.decode("utf8")
return image
def generate_item(xml_element): def generate_item(xml_element):