Merge pull request #1322 from croneter/beta-version

Bump master
This commit is contained in:
croneter 2021-01-31 17:53:32 +01:00 committed by GitHub
commit e5585aec44
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 79 additions and 67 deletions

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.12.10" provider-name="croneter"> <addon id="plugin.video.plexkodiconnect" name="PlexKodiConnect" version="2.12.12" 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" />
@ -83,7 +83,17 @@
<summary lang="lt_LT">Natūralioji „Plex“ integracija į „Kodi“</summary> <summary lang="lt_LT">Natūralioji „Plex“ integracija į „Kodi“</summary>
<description lang="lt_LT">Prijunkite „Kodi“ prie „Plex Medija Serverio“. Šiame papildinyje daroma prielaida, kad valdote visus savo vaizdo įrašus naudodami „Plex“ (ir nė vieno su „Kodi“). Galite prarasti jau saugomus „Kodi“ vaizdo įrašų ir muzikos duomenų bazių duomenis (kadangi šis papildinys juos tiesiogiai pakeičia). Naudokite savo pačių rizika!</description> <description lang="lt_LT">Prijunkite „Kodi“ prie „Plex Medija Serverio“. Šiame papildinyje daroma prielaida, kad valdote visus savo vaizdo įrašus naudodami „Plex“ (ir nė vieno su „Kodi“). Galite prarasti jau saugomus „Kodi“ vaizdo įrašų ir muzikos duomenų bazių duomenis (kadangi šis papildinys juos tiesiogiai pakeičia). Naudokite savo pačių rizika!</description>
<disclaimer lang="lt_LT">Naudokite savo pačių rizika</disclaimer> <disclaimer lang="lt_LT">Naudokite savo pačių rizika</disclaimer>
<news>version 2.12.10: <news>version 2.12.12:
- Hopefully fix rare case when sync would get stuck indefinitely
- Fix ValueError: invalid literal for int() for invalid dates sent by Plex
- version 2.12.11 for everyone
version 2.12.11 (beta only):
- Fix PKC not auto-picking audio/subtitle stream when transcoding
- Fix ValueError when deleting a music album
- Fix OSError: Invalid argument when Plex returns an invalid timestamp
version 2.12.10:
- Fix pictures from Plex picture libraries not working/displaying - Fix pictures from Plex picture libraries not working/displaying
version 2.12.9: version 2.12.9:

View file

@ -1,3 +1,13 @@
version 2.12.12:
- Hopefully fix rare case when sync would get stuck indefinitely
- Fix ValueError: invalid literal for int() for invalid dates sent by Plex
- version 2.12.11 for everyone
version 2.12.11 (beta only):
- Fix PKC not auto-picking audio/subtitle stream when transcoding
- Fix ValueError when deleting a music album
- Fix OSError: Invalid argument when Plex returns an invalid timestamp
version 2.12.10: version 2.12.10:
- Fix pictures from Plex picture libraries not working/displaying - Fix pictures from Plex picture libraries not working/displaying

View file

@ -630,7 +630,7 @@ msgstr ""
# PKC Settings - Playback # PKC Settings - Playback
msgctxt "#30541" msgctxt "#30541"
msgid "Don't ask to pick a certain stream/quality" msgid "Transcoding: Auto-pick audio and subtitle stream using Plex defaults"
msgstr "" msgstr ""
# PKC Settings - Playback # PKC Settings - Playback

View file

@ -136,6 +136,11 @@ class ProcessingQueue(Queue.Queue, object):
return self._current_queue._qsize() if self._current_queue else 0 return self._current_queue._qsize() if self._current_queue else 0
def _total_qsize(self): def _total_qsize(self):
"""
This method is BROKEN as it can lead to a deadlock when a single item
from the current section takes longer to download then any new items
coming in
"""
return sum(q._qsize() for q in self._queues) if self._queues else 0 return sum(q._qsize() for q in self._queues) if self._queues else 0
def put(self, item, block=True, timeout=None): def put(self, item, block=True, timeout=None):
@ -147,16 +152,16 @@ class ProcessingQueue(Queue.Queue, object):
try: try:
if self.maxsize > 0: if self.maxsize > 0:
if not block: if not block:
if self._total_qsize() == self.maxsize: if self._qsize() == self.maxsize:
raise Queue.Full raise Queue.Full
elif timeout is None: elif timeout is None:
while self._total_qsize() == self.maxsize: while self._qsize() == self.maxsize:
self.not_full.wait() self.not_full.wait()
elif timeout < 0: elif timeout < 0:
raise ValueError("'timeout' must be a non-negative number") raise ValueError("'timeout' must be a non-negative number")
else: else:
endtime = _time() + timeout endtime = _time() + timeout
while self._total_qsize() == self.maxsize: while self._qsize() == self.maxsize:
remaining = endtime - _time() remaining = endtime - _time()
if remaining <= 0.0: if remaining <= 0.0:
raise Queue.Full raise Queue.Full

View file

@ -135,7 +135,6 @@ class MusicMixin(object):
''' '''
Remove an album Remove an album
''' '''
self.kodidb.delete_album_from_discography(kodi_id)
if v.KODIVERSION < 18: if v.KODIVERSION < 18:
self.kodidb.delete_album_from_album_genre(kodi_id) self.kodidb.delete_album_from_album_genre(kodi_id)
self.kodidb.remove_album(kodi_id) self.kodidb.remove_album(kodi_id)
@ -353,11 +352,6 @@ class Album(MusicMixin, ItemBase):
timing.unix_date_to_kodi(self.last_sync), timing.unix_date_to_kodi(self.last_sync),
'album') 'album')
self.kodidb.add_albumartist(artist_id, kodi_id, api.artist_name()) self.kodidb.add_albumartist(artist_id, kodi_id, api.artist_name())
if v.KODIVERSION < 18:
self.kodidb.add_discography(artist_id, name, api.year())
self.kodidb.add_music_genres(kodi_id,
api.genres(),
v.KODI_TYPE_ALBUM)
if app.SYNC.artwork: if app.SYNC.artwork:
self.kodidb.modify_artwork(artworks, self.kodidb.modify_artwork(artworks,
kodi_id, kodi_id,

View file

@ -106,26 +106,6 @@ class KodiMusicDB(common.KodiDBBase):
self.cursor.execute('DELETE FROM song_artist WHERE idSong = ?', self.cursor.execute('DELETE FROM song_artist WHERE idSong = ?',
(song_id, )) (song_id, ))
@db.catch_operationalerrors
def delete_album_from_discography(self, album_id):
"""
Removes the album with id album_id from the table discography
"""
# Need to get the album name as a string first!
self.cursor.execute('SELECT strAlbum, iYear FROM album WHERE idAlbum = ? LIMIT 1',
(album_id, ))
try:
name, year = self.cursor.fetchone()
except TypeError:
return
self.cursor.execute('SELECT idArtist FROM album_artist WHERE idAlbum = ? LIMIT 1',
(album_id, ))
artist = self.cursor.fetchone()
if not artist:
return
self.cursor.execute('DELETE FROM discography WHERE idArtist = ? AND strAlbum = ? AND strYear = ?',
(artist[0], name, year))
@db.catch_operationalerrors @db.catch_operationalerrors
def delete_song_from_song_genre(self, song_id): def delete_song_from_song_genre(self, song_id):
""" """
@ -352,16 +332,6 @@ class KodiMusicDB(common.KodiDBBase):
VALUES (?, ?, ?) VALUES (?, ?, ?)
''', (artist_id, kodi_id, artistname)) ''', (artist_id, kodi_id, artistname))
@db.catch_operationalerrors
def add_discography(self, artist_id, albumname, year):
self.cursor.execute('''
INSERT OR REPLACE INTO discography(
idArtist,
strAlbum,
strYear)
VALUES (?, ?, ?)
''', (artist_id, albumname, year))
@db.catch_operationalerrors @db.catch_operationalerrors
def add_music_genres(self, kodiid, genres, mediatype): def add_music_genres(self, kodiid, genres, mediatype):
""" """
@ -656,5 +626,3 @@ class KodiMusicDB(common.KodiDBBase):
(kodi_id, )) (kodi_id, ))
self.cursor.execute('DELETE FROM song_artist WHERE idArtist = ?', self.cursor.execute('DELETE FROM song_artist WHERE idArtist = ?',
(kodi_id, )) (kodi_id, ))
self.cursor.execute('DELETE FROM discography WHERE idArtist = ?',
(kodi_id, ))

View file

@ -41,8 +41,8 @@ class FillMetadataQueue(common.LibrarySyncMixin,
plex_id = int(xml.get('ratingKey')) plex_id = int(xml.get('ratingKey'))
checksum = int('{}{}'.format( checksum = int('{}{}'.format(
plex_id, plex_id,
xml.get('updatedAt', abs(int(xml.get('updatedAt',
xml.get('addedAt', '1541572987')).replace('-', ''))) xml.get('addedAt', '1541572987'))))))
if (not self.repair and if (not self.repair and
plexdb.checksum(plex_id, section.plex_type) == checksum): plexdb.checksum(plex_id, section.plex_type) == checksum):
continue continue

View file

@ -349,8 +349,14 @@ def audio_subtitle_prefs(api, item):
action_type='PUT', action_type='PUT',
parameters=args) parameters=args)
return True return True
return setup_transcoding_audio_subtitle_prefs(mediastreams, part_id)
def setup_transcoding_audio_subtitle_prefs(mediastreams, part_id):
audio_streams_list = [] audio_streams_list = []
audio_streams = [] audio_streams = []
audio_default = None
subtitle_default = None
subtitle_streams_list = [] subtitle_streams_list = []
# "Don't burn-in any subtitle" # "Don't burn-in any subtitle"
subtitle_streams = ['1 %s' % utils.lang(39706)] subtitle_streams = ['1 %s' % utils.lang(39706)]
@ -379,6 +385,8 @@ def audio_subtitle_prefs(api, item):
utils.lang(39707), # unknown utils.lang(39707), # unknown
codec, codec,
channellayout) channellayout)
if stream.get('default'):
audio_default = audio_numb
audio_streams_list.append(index) audio_streams_list.append(index)
audio_streams.append(track.encode('utf-8')) audio_streams.append(track.encode('utf-8'))
audio_numb += 1 audio_numb += 1
@ -391,7 +399,6 @@ def audio_subtitle_prefs(api, item):
continue continue
# Subtitle is available within the video file # Subtitle is available within the video file
# Burn in the subtitle, if user chooses to do so # Burn in the subtitle, if user chooses to do so
default = stream.get('default')
forced = stream.get('forced') forced = stream.get('forced')
try: try:
track = '{} {}'.format(sub_num + 1, track = '{} {}'.format(sub_num + 1,
@ -400,7 +407,8 @@ def audio_subtitle_prefs(api, item):
track = '{} {} ({})'.format(sub_num + 1, track = '{} {} ({})'.format(sub_num + 1,
utils.lang(39707), # unknown utils.lang(39707), # unknown
stream.get('codec')) stream.get('codec'))
if default: if stream.get('default'):
subtitle_default = sub_num
track = "%s - %s" % (track, utils.lang(39708)) # Default track = "%s - %s" % (track, utils.lang(39708)) # Default
if forced: if forced:
track = "%s - %s" % (track, utils.lang(39709)) # Forced track = "%s - %s" % (track, utils.lang(39709)) # Forced
@ -410,10 +418,14 @@ def audio_subtitle_prefs(api, item):
sub_num += 1 sub_num += 1
if audio_numb > 1: if audio_numb > 1:
resp = utils.dialog('select', utils.lang(33013), audio_streams) # "Transcoding: Auto-pick audio and subtitle stream using Plex defaults"
if resp == -1: if utils.settings('bestQuality') == 'true' and audio_default is not None:
LOG.info('User aborted dialog to select audio stream') resp = audio_default
return else:
resp = utils.dialog('select', utils.lang(33013), audio_streams)
if resp == -1:
LOG.info('User aborted dialog to select audio stream')
return
args = { args = {
'audioStreamID': audio_streams_list[resp], 'audioStreamID': audio_streams_list[resp],
'allParts': 1 'allParts': 1
@ -428,18 +440,22 @@ def audio_subtitle_prefs(api, item):
# Otherwise, the PMS might pick-up the last one # Otherwise, the PMS might pick-up the last one
LOG.info('No subtitles to burn-in') LOG.info('No subtitles to burn-in')
else: else:
resp = utils.dialog('select', utils.lang(33014), subtitle_streams) # "Transcoding: Auto-pick audio and subtitle stream using Plex defaults"
if resp == -1: if utils.settings('bestQuality') == 'true' and subtitle_default is not None:
LOG.info('User aborted dialog to select subtitle stream') resp = subtitle_default
return
elif resp == 0:
# User did not select a subtitle or backed out of the dialog
LOG.info('User chose to not burn-in any subtitles')
else: else:
LOG.info('User chose to burn-in subtitle %s: %s', resp = utils.dialog('select', utils.lang(33014), subtitle_streams)
select_subs_index, if resp == -1:
subtitle_streams[resp].decode('utf-8')) LOG.info('User aborted dialog to select subtitle stream')
select_subs_index = subtitle_streams_list[resp - 1] return
elif resp == 0:
# User did not select a subtitle or backed out of the dialog
LOG.info('User chose to not burn-in any subtitles')
else:
LOG.info('User chose to burn-in subtitle %s: %s',
select_subs_index,
subtitle_streams[resp].decode('utf-8'))
select_subs_index = subtitle_streams_list[resp - 1]
# Now prep the PMS for our choice # Now prep the PMS for our choice
args = { args = {
'subtitleStreamID': select_subs_index, 'subtitleStreamID': select_subs_index,

View file

@ -231,8 +231,8 @@ class Base(object):
addedAt is used. addedAt is used.
""" """
return int('%s%s' % (self.xml.get('ratingKey'), return int('%s%s' % (self.xml.get('ratingKey'),
self.xml.get('updatedAt') or abs(int(self.xml.get('updatedAt') or
self.xml.get('addedAt', '1541572987'))) self.xml.get('addedAt', '1541572987')))))
def title(self): def title(self):
""" """

View file

@ -1,9 +1,12 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals from __future__ import absolute_import, division, unicode_literals
from logging import getLogger
from datetime import datetime, timedelta from datetime import datetime, timedelta
from time import localtime, strftime from time import localtime, strftime
LOG = getLogger('PLEX.timing')
EPOCH = datetime.utcfromtimestamp(0) EPOCH = datetime.utcfromtimestamp(0)
@ -29,7 +32,13 @@ def unix_date_to_kodi(unix_kodi_time):
Output: Y-m-d h:m:s = 2009-04-05 23:16:04 Output: Y-m-d h:m:s = 2009-04-05 23:16:04
""" """
return strftime('%Y-%m-%d %H:%M:%S', localtime(float(unix_kodi_time))) try:
return strftime('%Y-%m-%d %H:%M:%S', localtime(float(unix_kodi_time)))
except Exception:
LOG.exception('Received an illegal timestamp from Plex: %s. '
'Using 1970-01-01 12:00:00',
unix_kodi_time)
return '1970-01-01 12:00:00'
def plex_date_to_kodi(plex_timestamp): def plex_date_to_kodi(plex_timestamp):

View file

@ -120,7 +120,7 @@
<setting id="audioBoost" type="slider" label="39001" default="0" range="0,10,100" option="int"/> <setting id="audioBoost" type="slider" label="39001" default="0" range="0,10,100" option="int"/>
<setting id="subtitleSize" label="39002" type="slider" option="int" range="0,30,300" default="100" /> <setting id="subtitleSize" label="39002" type="slider" option="int" range="0,30,300" default="100" />
<setting id="force_transcode_pix" type="bool" label="30545" default="false" /> <setting id="force_transcode_pix" type="bool" label="30545" default="false" />
<setting id="bestQuality" type="bool" label="30541" default="false" /> <setting id="bestQuality" type="bool" label="30541" default="false" /><!-- Transcoding: Auto-pick audio and subtitle stream using Plex defaults -->
<setting id="bestTrailer" type="bool" label="30542" default="true" /> <setting id="bestTrailer" type="bool" label="30542" default="true" />
<setting type="sep" /> <setting type="sep" />
<setting id="offerDelete" type="bool" label="30114" default="false" visible="false"/> <setting id="offerDelete" type="bool" label="30114" default="false" visible="false"/>