Merge branch 'beta-version'
This commit is contained in:
commit
d8386c4cc0
6 changed files with 83 additions and 71 deletions
|
@ -1,5 +1,5 @@
|
|||
[![stable version](https://img.shields.io/badge/stable_version-2.3.3-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.3.3-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.3.4-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)
|
||||
[![FAQ](https://img.shields.io/badge/wiki-FAQ-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/faq)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<addon id="plugin.video.plexkodiconnect" name="PlexKodiConnect" version="2.3.3" provider-name="croneter">
|
||||
<addon id="plugin.video.plexkodiconnect" name="PlexKodiConnect" version="2.3.4" provider-name="croneter">
|
||||
<requires>
|
||||
<import addon="xbmc.python" version="2.1.0"/>
|
||||
<import addon="script.module.requests" version="2.9.1" />
|
||||
|
@ -73,7 +73,10 @@
|
|||
<summary lang="uk_UA">Нативна інтеграція Plex в Kodi</summary>
|
||||
<description lang="uk_UA">Підключає Kodi до серверу Plex. Цей плагін передбачає, що ви керуєте всіма своїми відео за допомогою Plex (і ніяк не Kodi). Ви можете втратити дані, які вже зберігаються у відео та музичних БД Kodi (оскільки цей плагін безпосередньо їх змінює). Використовуйте на свій страх і ризик!</description>
|
||||
<disclaimer lang="uk_UA">Використовуйте на свій ризик</disclaimer>
|
||||
<news>version 2.3.3:
|
||||
<news>version 2.3.4 (beta only):
|
||||
- Fix playback sometimes not starting and UnicodeEncodeError for logging
|
||||
|
||||
version 2.3.3:
|
||||
- Choose trailer if several are present (DB reset required)
|
||||
|
||||
version 2.3.2:
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
version 2.3.4 (beta only):
|
||||
- Fix playback sometimes not starting and UnicodeEncodeError for logging
|
||||
|
||||
version 2.3.3:
|
||||
- Choose trailer if several are present (DB reset required)
|
||||
|
||||
|
|
|
@ -38,9 +38,11 @@ def config():
|
|||
class LogHandler(logging.StreamHandler):
|
||||
def __init__(self):
|
||||
logging.StreamHandler.__init__(self)
|
||||
self.setFormatter(logging.Formatter(fmt="%(name)s: %(message)s"))
|
||||
self.setFormatter(logging.Formatter(fmt=b"%(name)s: %(message)s"))
|
||||
|
||||
def emit(self, record):
|
||||
if isinstance(record.msg, unicode):
|
||||
record.msg = record.msg.encode('utf-8')
|
||||
try:
|
||||
xbmc.log(self.format(record), level=LEVELS[record.levelno])
|
||||
except UnicodeEncodeError:
|
||||
|
|
|
@ -33,36 +33,7 @@ class PlaylistError(Exception):
|
|||
pass
|
||||
|
||||
|
||||
class PlaylistObjectBaseclase(object):
|
||||
"""
|
||||
Base class
|
||||
"""
|
||||
def __init__(self):
|
||||
self.id = None
|
||||
self.type = None
|
||||
|
||||
def __repr__(self):
|
||||
"""
|
||||
Print the playlist, e.g. to log. Returns unicode
|
||||
"""
|
||||
answ = '{\'%s\': {\'id\': %s, ' % (self.__class__.__name__, self.id)
|
||||
# For some reason, can't use dir directly
|
||||
for key in self.__dict__:
|
||||
if key in ('id', 'kodi_pl'):
|
||||
continue
|
||||
if isinstance(getattr(self, key), str):
|
||||
answ += '\'%s\': \'%s\', ' % (key,
|
||||
utils.try_decode(getattr(self,
|
||||
key)))
|
||||
elif isinstance(getattr(self, key), unicode):
|
||||
answ += '\'%s\': \'%s\', ' % (key, getattr(self, key))
|
||||
else:
|
||||
# e.g. int
|
||||
answ += '\'%s\': %s, ' % (key, unicode(getattr(self, key)))
|
||||
return answ + '}}'
|
||||
|
||||
|
||||
class Playqueue_Object(PlaylistObjectBaseclase):
|
||||
class Playqueue_Object(object):
|
||||
"""
|
||||
PKC object to represent PMS playQueues and Kodi playlist for queueing
|
||||
|
||||
|
@ -85,6 +56,8 @@ class Playqueue_Object(PlaylistObjectBaseclase):
|
|||
kind = 'playQueue'
|
||||
|
||||
def __init__(self):
|
||||
self.id = None
|
||||
self.type = None
|
||||
self.playlistid = None
|
||||
self.kodi_pl = None
|
||||
self.items = []
|
||||
|
@ -104,7 +77,25 @@ class Playqueue_Object(PlaylistObjectBaseclase):
|
|||
# To keep track if Kodi playback was initiated from a Kodi playlist
|
||||
# There are a couple of pitfalls, unfortunately...
|
||||
self.kodi_playlist_playback = False
|
||||
PlaylistObjectBaseclase.__init__(self)
|
||||
|
||||
def __repr__(self):
|
||||
answ = ("{{"
|
||||
"'playlistid': {self.playlistid}, "
|
||||
"'id': {self.id}, "
|
||||
"'version': {self.version}, "
|
||||
"'type': '{self.type}', "
|
||||
"'selectedItemID': {self.selectedItemID}, "
|
||||
"'selectedItemOffset': {self.selectedItemOffset}, "
|
||||
"'shuffled': {self.shuffled}, "
|
||||
"'repeat': {self.repeat}, "
|
||||
"'kodi_playlist_playback': {self.kodi_playlist_playback}, "
|
||||
"'pkc_edit': {self.pkc_edit}, ".format(self=self))
|
||||
answ = answ.encode('utf-8')
|
||||
# Since list.__repr__ will return string, not unicode
|
||||
return answ + b"'items': {self.items}}}".format(self=self)
|
||||
|
||||
def __str__(self):
|
||||
return self.__repr__()
|
||||
|
||||
def is_pkc_clear(self):
|
||||
"""
|
||||
|
@ -181,28 +172,27 @@ class Playlist_Item(object):
|
|||
self.force_transcode = False
|
||||
|
||||
def __repr__(self):
|
||||
"""
|
||||
Print the playlist item, e.g. to log. Returns unicode
|
||||
"""
|
||||
answ = ('{\'%s\': {\'id\': \'%s\', \'plex_id\': \'%s\', '
|
||||
% (self.__class__.__name__, self.id, self.plex_id))
|
||||
for key in self.__dict__:
|
||||
if key in ('id', 'plex_id', 'xml'):
|
||||
continue
|
||||
if isinstance(getattr(self, key), str):
|
||||
answ += '\'%s\': \'%s\', ' % (key,
|
||||
utils.try_decode(getattr(self,
|
||||
key)))
|
||||
elif isinstance(getattr(self, key), unicode):
|
||||
answ += '\'%s\': \'%s\', ' % (key, getattr(self, key))
|
||||
else:
|
||||
# e.g. int
|
||||
answ += '\'%s\': %s, ' % (key, unicode(getattr(self, key)))
|
||||
if self.xml is None:
|
||||
answ += '\'xml\': None}}'
|
||||
else:
|
||||
answ += '\'xml\': \'%s\'}}' % self.xml.tag
|
||||
return answ
|
||||
answ = ("{{"
|
||||
"'id': {self.id}, "
|
||||
"'plex_id': {self.plex_id}, "
|
||||
"'plex_type': '{self.plex_type}', "
|
||||
"'plex_uuid': '{self.plex_uuid}', "
|
||||
"'kodi_id': {self.kodi_id}, "
|
||||
"'kodi_type': '{self.kodi_type}', "
|
||||
"'file': '{self.file}', "
|
||||
"'uri': '{self.uri}', "
|
||||
"'guid': '{self.guid}', "
|
||||
"'playmethod': '{self.playmethod}', "
|
||||
"'playcount': {self.playcount}, "
|
||||
"'offset': {self.offset}, "
|
||||
"'force_transcode': {self.force_transcode}, "
|
||||
"'part': {self.part}, ".format(self=self))
|
||||
answ = answ.encode('utf-8')
|
||||
# etree xml.__repr__() could return string, not unicode
|
||||
return answ + b"'xml': \"{self.xml}\"}}".format(self=self)
|
||||
|
||||
def __str__(self):
|
||||
return self.__repr__()
|
||||
|
||||
def plex_stream_index(self, kodi_stream_index, stream_type):
|
||||
"""
|
||||
|
@ -412,12 +402,13 @@ def get_playlist_details_from_xml(playlist, xml):
|
|||
|
||||
Raises PlaylistError if something went wrong.
|
||||
"""
|
||||
playlist.id = xml.get('%sID' % playlist.kind)
|
||||
playlist.version = xml.get('%sVersion' % playlist.kind)
|
||||
playlist.shuffled = xml.get('%sShuffled' % playlist.kind)
|
||||
playlist.selectedItemID = xml.get('%sSelectedItemID' % playlist.kind)
|
||||
playlist.id = xml.get('%sID' % playlist.kind).decode('utf-8')
|
||||
playlist.version = xml.get('%sVersion' % playlist.kind).decode('utf-8')
|
||||
playlist.shuffled = xml.get('%sShuffled' % playlist.kind).decode('utf-8')
|
||||
playlist.selectedItemID = xml.get(
|
||||
'%sSelectedItemID' % playlist.kind).decode('utf-8')
|
||||
playlist.selectedItemOffset = xml.get(
|
||||
'%sSelectedItemOffset' % playlist.kind)
|
||||
'%sSelectedItemOffset' % playlist.kind).decode('utf-8')
|
||||
LOG.debug('Updated playlist from xml: %s', playlist)
|
||||
|
||||
|
||||
|
@ -781,4 +772,4 @@ def get_plextype_from_xml(xml):
|
|||
except (TypeError, IndexError, AttributeError):
|
||||
LOG.error('Could not get plex metadata for plex id %s', plex_id)
|
||||
return
|
||||
return new_xml[0].attrib.get('type')
|
||||
return new_xml[0].attrib.get('type').decode('utf-8')
|
||||
|
|
|
@ -53,6 +53,19 @@ LOG = getLogger('PLEX.plex_api')
|
|||
###############################################################################
|
||||
|
||||
|
||||
def _unicode_or_none(value):
|
||||
"""
|
||||
Tries to decode value to unicode. Returns None if this fails
|
||||
"""
|
||||
try:
|
||||
return value.decode('utf-8')
|
||||
except TypeError:
|
||||
# e.g. Android TV's Python
|
||||
return value.decode()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
||||
class API(object):
|
||||
"""
|
||||
API(item)
|
||||
|
@ -77,9 +90,10 @@ class API(object):
|
|||
|
||||
def plex_type(self):
|
||||
"""
|
||||
Returns the type of media, e.g. 'movie' or 'clip' for trailers
|
||||
Returns the type of media, e.g. 'movie' or 'clip' for trailers as
|
||||
Unicode or None.
|
||||
"""
|
||||
return self.item.get('type')
|
||||
return _unicode_or_none(self.item.get('type'))
|
||||
|
||||
def playlist_type(self):
|
||||
"""
|
||||
|
@ -104,9 +118,9 @@ class API(object):
|
|||
|
||||
def plex_id(self):
|
||||
"""
|
||||
Returns the Plex ratingKey such as '246922' as a string or None
|
||||
Returns the Plex ratingKey such as '246922' as Unicode or None
|
||||
"""
|
||||
return self.item.get('ratingKey')
|
||||
return _unicode_or_none(self.item.get('ratingKey'))
|
||||
|
||||
def path(self, force_first_media=True, force_addon=False,
|
||||
direct_paths=None):
|
||||
|
@ -664,12 +678,11 @@ class API(object):
|
|||
def item_id(self):
|
||||
"""
|
||||
Returns current playQueueItemID or if unsuccessful the playListItemID
|
||||
as Unicode.
|
||||
If not found, None is returned
|
||||
"""
|
||||
answ = self.item.get('playQueueItemID')
|
||||
if answ is None:
|
||||
answ = self.item.get('playListItemID')
|
||||
return answ
|
||||
return _unicode_or_none(self.item.get('playQueueItemID') or
|
||||
self.item.get('playListItemID'))
|
||||
|
||||
def _data_from_part_or_media(self, key):
|
||||
"""
|
||||
|
|
Loading…
Reference in a new issue