Merge pull request #739 from croneter/fix-user

Fix Kodi profile switch not working correctly and PKC not exiting cleanly
This commit is contained in:
croneter 2019-02-22 15:45:46 +01:00 committed by GitHub
commit 5e77dfb71e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 36 deletions

View file

@ -7,7 +7,9 @@ from __future__ import absolute_import, division, unicode_literals
from logging import getLogger from logging import getLogger
from json import loads from json import loads
import copy import copy
import xbmc import xbmc
import xbmcgui
from .plex_db import PlexDB from .plex_db import PlexDB
from . import kodi_db from . import kodi_db
@ -16,11 +18,11 @@ from . import utils, timing, plex_functions as PF, playback
from . import json_rpc as js, playqueue as PQ, playlist_func as PL from . import json_rpc as js, playqueue as PQ, playlist_func as PL
from . import backgroundthread, app, variables as v from . import backgroundthread, app, variables as v
###############################################################################
LOG = getLogger('PLEX.kodimonitor') LOG = getLogger('PLEX.kodimonitor')
############################################################################### # "Start from beginning", "Play from beginning"
STRINGS = (utils.try_encode(utils.lang(12021)),
utils.try_encode(utils.lang(12023)))
class KodiMonitor(xbmc.Monitor): class KodiMonitor(xbmc.Monitor):
@ -530,3 +532,36 @@ def _clean_file_table():
LOG.debug('Database was locked, unable to clean file table') LOG.debug('Database was locked, unable to clean file table')
else: else:
LOG.debug('Done cleaning up Kodi file table') LOG.debug('Done cleaning up Kodi file table')
class ContextMonitor(backgroundthread.KillableThread):
"""
Detect the resume dialog for widgets. Could also be used to detect
external players (see Emby implementation)
Let's not register this thread because it won't quit due to
xbmc.getCondVisibility
It should still exit at some point due to xbmc.abortRequested
"""
def run(self):
LOG.info("----===## Starting ContextMonitor ##===----")
# app.APP.register_thread(self)
try:
self._run()
finally:
# app.APP.deregister_thread(self)
LOG.info("##===---- ContextMonitor Stopped ----===##")
def _run(self):
while not self.isCanceled():
# The following function will block if called while PKC should
# exit!
if xbmc.getCondVisibility('Window.IsVisible(DialogContextMenu.xml)'):
if xbmc.getInfoLabel('Control.GetLabel(1002)') in STRINGS:
# Remember that the item IS indeed resumable
control = int(xbmcgui.Window(10106).getFocusId())
app.PLAYSTATE.resume_playback = True if control == 1001 else False
else:
# Different context menu is displayed
app.PLAYSTATE.resume_playback = False
app.APP.monitor.waitForAbort(0.1)

View file

@ -4,7 +4,6 @@ from __future__ import absolute_import, division, unicode_literals
import logging import logging
import sys import sys
import xbmc import xbmc
import xbmcgui
from . import utils, clientinfo, timing from . import utils, clientinfo, timing
from . import initialsetup from . import initialsetup
@ -30,12 +29,8 @@ WINDOW_PROPERTIES = (
"pms_token", "plex_token", "plex_authenticated", "plex_restricteduser", "pms_token", "plex_token", "plex_authenticated", "plex_restricteduser",
"plex_allows_mediaDeletion", "plexkodiconnect.command", "plex_result") "plex_allows_mediaDeletion", "plexkodiconnect.command", "plex_result")
# "Start from beginning", "Play from beginning"
STRINGS = (utils.try_encode(utils.lang(12021)),
utils.try_encode(utils.lang(12023)))
class Service(object):
class Service():
ws = None ws = None
sync = None sync = None
plexcompanion = None plexcompanion = None
@ -91,10 +86,6 @@ class Service():
for prop in WINDOW_PROPERTIES: for prop in WINDOW_PROPERTIES:
utils.window(prop, clear=True) utils.window(prop, clear=True)
# To detect Kodi profile switches
utils.window('plex_kodiProfile',
value=utils.try_decode(xbmc.translatePath("special://profile")))
# Load/Reset PKC entirely - important for user/Kodi profile switch # Load/Reset PKC entirely - important for user/Kodi profile switch
# Clear video nodes properties # Clear video nodes properties
library_sync.VideoNodes().clearProperties() library_sync.VideoNodes().clearProperties()
@ -109,6 +100,7 @@ class Service():
self.setup = None self.setup = None
self.alexa = None self.alexa = None
self.playqueue = None self.playqueue = None
self.context_monitor = None
# Flags for other threads # Flags for other threads
self.connection_check_running = False self.connection_check_running = False
self.auth_running = False self.auth_running = False
@ -406,6 +398,9 @@ class Service():
# Some plumbing # Some plumbing
app.init() app.init()
app.APP.monitor = kodimonitor.KodiMonitor() app.APP.monitor = kodimonitor.KodiMonitor()
self.context_monitor = kodimonitor.ContextMonitor()
# Start immediately to catch user input even before auth
self.context_monitor.start()
app.APP.player = xbmc.Player() app.APP.player = xbmc.Player()
# Initialize the PKC playqueues # Initialize the PKC playqueues
PQ.init_playqueues() PQ.init_playqueues()
@ -423,13 +418,6 @@ class Service():
# Main PKC program loop # Main PKC program loop
while not self.isCanceled(): while not self.isCanceled():
# Check for Kodi profile change
if utils.window('plex_kodiProfile') != v.KODI_PROFILE:
# Profile change happened, terminate this thread and others
LOG.info("Kodi profile was: %s and changed to: %s. "
"Terminating old PlexKodiConnect thread.",
v.KODI_PROFILE, utils.window('plex_kodiProfile'))
break
# Check for PKC commands from other Python instances # Check for PKC commands from other Python instances
plex_command = utils.window('plexkodiconnect.command') plex_command = utils.window('plexkodiconnect.command')
@ -478,17 +466,6 @@ class Service():
app.APP.monitor.waitForAbort(0.1) app.APP.monitor.waitForAbort(0.1)
continue continue
# Detect the resume dialog for widgets. Could also be used to detect
# external players (see Emby implementation)
if xbmc.getCondVisibility('Window.IsVisible(DialogContextMenu.xml)'):
if xbmc.getInfoLabel('Control.GetLabel(1002)') in STRINGS:
# Remember that the item IS indeed resumable
control = int(xbmcgui.Window(10106).getFocusId())
app.PLAYSTATE.resume_playback = True if control == 1001 else False
else:
# Different context menu is displayed
app.PLAYSTATE.resume_playback = False
# Before proceeding, need to make sure: # Before proceeding, need to make sure:
# 1. Server is online # 1. Server is online
# 2. User is set # 2. User is set

View file

@ -48,6 +48,16 @@ class WebSocket(backgroundthread.KillableThread):
def run(self): def run(self):
LOG.info("----===## Starting %s ##===----", self.__class__.__name__) LOG.info("----===## Starting %s ##===----", self.__class__.__name__)
app.APP.register_thread(self) app.APP.register_thread(self)
try:
self._run()
finally:
# Close websocket connection on shutdown
if self.ws is not None:
self.ws.close()
app.APP.deregister_thread(self)
LOG.info("##===---- %s Stopped ----===##", self.__class__.__name__)
def _run(self):
counter = 0 counter = 0
while not self.isCanceled(): while not self.isCanceled():
# In the event the server goes offline # In the event the server goes offline
@ -133,11 +143,6 @@ class WebSocket(backgroundthread.KillableThread):
if self.ws is not None: if self.ws is not None:
self.ws.close() self.ws.close()
self.ws = None self.ws = None
# Close websocket connection on shutdown
if self.ws is not None:
self.ws.close()
app.APP.deregister_thread(self)
LOG.info("##===---- %s Stopped ----===##", self.__class__.__name__)
class PMS_Websocket(WebSocket): class PMS_Websocket(WebSocket):