Merge branch 'beta-version'

This commit is contained in:
croneter 2018-09-02 20:44:45 +02:00
commit f591c6e4de
8 changed files with 56 additions and 38 deletions

View file

@ -1,5 +1,5 @@
[![stable version](https://img.shields.io/badge/stable_version-2.3.10-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.3.12-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.11-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.12-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.3.11" provider-name="croneter"> <addon id="plugin.video.plexkodiconnect" name="PlexKodiConnect" version="2.3.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" />
@ -73,7 +73,12 @@
<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.3.11 (beta only): <news>version 2.3.12:
- Fix Kodi hanging if media stream selection is aborted
- Fix potential sync crash
- Revert "Fix Kodi crash by committing to DB frequently"
version 2.3.11 (beta only):
- Fix Kodi crash by committing to DB frequently - Fix Kodi crash by committing to DB frequently
version 2.3.10: version 2.3.10:

View file

@ -1,3 +1,8 @@
version 2.3.12:
- Fix Kodi hanging if media stream selection is aborted
- Fix potential sync crash
- Revert "Fix Kodi crash by committing to DB frequently"
version 2.3.11 (beta only): version 2.3.11 (beta only):
- Fix Kodi crash by committing to DB frequently - Fix Kodi crash by committing to DB frequently

View file

@ -804,20 +804,24 @@ class TVShows(Items):
seasonid = self.kodi_db.add_season(showid, season) seasonid = self.kodi_db.add_season(showid, season)
# GET THE FILE AND PATH ##### # GET THE FILE AND PATH #####
do_indirect = not state.DIRECT_PATHS
if state.DIRECT_PATHS: if state.DIRECT_PATHS:
playurl = api.file_path(force_first_media=True) playurl = api.file_path(force_first_media=True)
playurl = api.validate_playurl(playurl, v.PLEX_TYPE_EPISODE) if playurl is None:
if "\\" in playurl: do_indirect = True
# Local path
filename = playurl.rsplit("\\", 1)[1]
else: else:
# Network share playurl = api.validate_playurl(playurl, v.PLEX_TYPE_EPISODE)
filename = playurl.rsplit("/", 1)[1] if "\\" in playurl:
path = playurl.replace(filename, "") # Local path
parent_path_id = self.kodi_db.parent_path_id(path) filename = playurl.rsplit("\\", 1)[1]
pathid = self.kodi_db.add_video_path(path, else:
id_parent_path=parent_path_id) # Network share
else: filename = playurl.rsplit("/", 1)[1]
path = playurl.replace(filename, "")
parent_path_id = self.kodi_db.parent_path_id(path)
pathid = self.kodi_db.add_video_path(path,
id_parent_path=parent_path_id)
if do_indirect:
# Set plugin path - do NOT use "intermediate" paths for the show # Set plugin path - do NOT use "intermediate" paths for the show
# as with direct paths! # as with direct paths!
filename = api.file_name(force_first_media=True) filename = api.file_name(force_first_media=True)

View file

@ -12,11 +12,6 @@ from . import sync_info
############################################################################### ###############################################################################
LOG = getLogger("PLEX." + __name__) LOG = getLogger("PLEX." + __name__)
# Commit to DB happens only after leaving respective itemtypes context manager
# with item_fct() as item_class:
# After how many items shall we additionally commit? Otherwise, Kodi
# crashes if we sync thousands of items without a single commit.
COMMIT_AFTER_N_ITEMS = 1000
############################################################################### ###############################################################################
@ -62,12 +57,14 @@ class ThreadedProcessMetadata(Thread):
LOG.debug('Processing thread started') LOG.debug('Processing thread started')
# Constructs the method name, e.g. itemtypes.Movies # Constructs the method name, e.g. itemtypes.Movies
item_fct = getattr(itemtypes, self.item_class) item_fct = getattr(itemtypes, self.item_class)
n = 0 # cache local variables because it's faster
queue = self.queue
stopped = self.stopped
with item_fct() as item_class: with item_fct() as item_class:
while self.stopped() is False: while stopped() is False:
# grabs item from queue # grabs item from queue
try: try:
item = self.queue.get(block=False) item = queue.get(block=False)
except Empty: except Empty:
sleep(20) sleep(20)
continue continue
@ -86,11 +83,6 @@ class ThreadedProcessMetadata(Thread):
with sync_info.LOCK: with sync_info.LOCK:
sync_info.PROCESS_METADATA_COUNT += 1 sync_info.PROCESS_METADATA_COUNT += 1
sync_info.PROCESSING_VIEW_NAME = item['title'] sync_info.PROCESSING_VIEW_NAME = item['title']
n += 1 queue.task_done()
if n == COMMIT_AFTER_N_ITEMS:
n = 0
item_class.plexconn.commit()
item_class.kodiconn.commit()
self.queue.task_done()
self.terminate_now() self.terminate_now()
LOG.debug('Processing thread terminated') LOG.debug('Processing thread terminated')

View file

@ -413,6 +413,11 @@ def _conclude_playback(playqueue, pos):
else: else:
api = None api = None
playurl = item.file playurl = item.file
if not playurl:
LOG.info('Did not get a playurl, aborting playback silently')
state.RESUME_PLAYBACK = False
pickler.pickle_me(result)
return
listitem.setPath(utils.try_encode(playurl)) listitem.setPath(utils.try_encode(playurl))
if item.playmethod == 'DirectStream': if item.playmethod == 'DirectStream':
listitem.setSubtitles(api.cache_external_subs()) listitem.setSubtitles(api.cache_external_subs())

View file

@ -24,12 +24,11 @@ class PlayUtils():
def getPlayUrl(self): def getPlayUrl(self):
""" """
Returns the playurl for the part Returns the playurl [unicode] for the part or returns None.
(movie might consist of several files) (movie might consist of several files)
playurl is in unicode!
""" """
self.api.mediastream_number() if self.api.mediastream_number() is None:
return
playurl = self.isDirectPlay() playurl = self.isDirectPlay()
if playurl is not None: if playurl is not None:
LOG.info("File is direct playing.") LOG.info("File is direct playing.")
@ -232,8 +231,9 @@ class PlayUtils():
stream by a PUT request to the PMS stream by a PUT request to the PMS
""" """
# Set media and part where we're at # Set media and part where we're at
if self.api.mediastream is None: if (self.api.mediastream is None and
self.api.mediastream_number() self.api.mediastream_number() is None):
return
try: try:
mediastreams = self.api.plex_media_streams() mediastreams = self.api.plex_media_streams()
except (TypeError, IndexError): except (TypeError, IndexError):

View file

@ -203,7 +203,8 @@ class API(object):
files are present for the same PMS item files are present for the same PMS item
""" """
if self.mediastream is None and force_first_media is False: if self.mediastream is None and force_first_media is False:
self.mediastream_number() if self.mediastream_number() is None:
return
try: try:
if force_first_media is False: if force_first_media is False:
ans = self.item[self.mediastream][self.part].attrib['file'] ans = self.item[self.mediastream][self.part].attrib['file']
@ -1294,6 +1295,9 @@ class API(object):
Returns the Media stream as an int (mostly 0). Will let the user choose Returns the Media stream as an int (mostly 0). Will let the user choose
if several media streams are present for a PMS item (if settings are if several media streams are present for a PMS item (if settings are
set accordingly) set accordingly)
Returns None if the user aborted selection (leaving self.mediastream at
its default of None)
""" """
# How many streams do we have? # How many streams do we have?
count = 0 count = 0
@ -1345,6 +1349,9 @@ class API(object):
option = utils.try_encode(option.strip()) option = utils.try_encode(option.strip())
dialoglist.append(option) dialoglist.append(option)
media = utils.dialog('select', 'Select stream', dialoglist) media = utils.dialog('select', 'Select stream', dialoglist)
if media == -1:
LOG.info('User cancelled media stream selection')
return
else: else:
media = 0 media = 0
self.mediastream = media self.mediastream = media
@ -1371,8 +1378,8 @@ class API(object):
TODO: mediaIndex TODO: mediaIndex
""" """
if self.mediastream is None: if self.mediastream is None and self.mediastream_number() is None:
self.mediastream_number() return
if quality is None: if quality is None:
quality = {} quality = {}
xargs = clientinfo.getXArgsDeviceInfo() xargs = clientinfo.getXArgsDeviceInfo()