Interrupt sleep if Kodi exits. Use Monitor's Player()
This commit is contained in:
parent
fff791e3d1
commit
6fe0e23f53
22 changed files with 70 additions and 83 deletions
|
@ -32,6 +32,8 @@ class App(object):
|
||||||
self.command_pipeline_queue = Queue.Queue()
|
self.command_pipeline_queue = Queue.Queue()
|
||||||
# Websocket_client queue to communicate with librarysync
|
# Websocket_client queue to communicate with librarysync
|
||||||
self.websocket_queue = Queue.Queue()
|
self.websocket_queue = Queue.Queue()
|
||||||
|
# xbmc.Monitor() instance from kodimonitor.py
|
||||||
|
self.monitor = None
|
||||||
|
|
||||||
def load_settings(self):
|
def load_settings(self):
|
||||||
# Number of items to fetch and display in widgets
|
# Number of items to fetch and display in widgets
|
||||||
|
|
|
@ -4,7 +4,6 @@ from __future__ import absolute_import, division, unicode_literals
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
from urllib import quote_plus, unquote
|
from urllib import quote_plus, unquote
|
||||||
import requests
|
import requests
|
||||||
import xbmc
|
|
||||||
|
|
||||||
from .kodi_db import KodiVideoDB, KodiMusicDB, KodiTextureDB
|
from .kodi_db import KodiVideoDB, KodiMusicDB, KodiTextureDB
|
||||||
from . import app, backgroundthread, utils
|
from . import app, backgroundthread, utils
|
||||||
|
@ -59,7 +58,7 @@ class ImageCachingThread(backgroundthread.KillableThread):
|
||||||
# Abort was requested while waiting. We should exit
|
# Abort was requested while waiting. We should exit
|
||||||
LOG.info("---===### Stopped ImageCachingThread ###===---")
|
LOG.info("---===### Stopped ImageCachingThread ###===---")
|
||||||
return
|
return
|
||||||
xbmc.sleep(1000)
|
app.APP.monitor.waitForAbort(1)
|
||||||
cache_url(url)
|
cache_url(url)
|
||||||
LOG.info("---===### Stopped ImageCachingThread ###===---")
|
LOG.info("---===### Stopped ImageCachingThread ###===---")
|
||||||
|
|
||||||
|
@ -95,7 +94,7 @@ def cache_url(url):
|
||||||
'over-loaded. Sleep %s seconds before trying '
|
'over-loaded. Sleep %s seconds before trying '
|
||||||
'again to download %s',
|
'again to download %s',
|
||||||
2**sleeptime, double_urldecode(url))
|
2**sleeptime, double_urldecode(url))
|
||||||
xbmc.sleep((2**sleeptime) * 1000)
|
app.APP.monitor.waitForAbort((2**sleeptime))
|
||||||
sleeptime += 1
|
sleeptime += 1
|
||||||
continue
|
continue
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
|
|
|
@ -7,7 +7,7 @@ import Queue
|
||||||
import heapq
|
import heapq
|
||||||
import xbmc
|
import xbmc
|
||||||
|
|
||||||
from . import utils
|
from . import utils, app
|
||||||
from Queue import Empty
|
from Queue import Empty
|
||||||
|
|
||||||
LOG = getLogger('PLEX.' + __name__)
|
LOG = getLogger('PLEX.' + __name__)
|
||||||
|
@ -253,7 +253,7 @@ class NonstoppingBackgroundWorker(BackgroundWorker):
|
||||||
self._queue.task_done()
|
self._queue.task_done()
|
||||||
self._task = None
|
self._task = None
|
||||||
except Queue.Empty:
|
except Queue.Empty:
|
||||||
xbmc.sleep(50)
|
app.APP.monitor.waitForAbort(0.05)
|
||||||
|
|
||||||
def working(self):
|
def working(self):
|
||||||
return self._working
|
return self._working
|
||||||
|
|
|
@ -63,7 +63,7 @@ class ContextMenu(object):
|
||||||
if self._selected_option in (OPTIONS['Delete'],
|
if self._selected_option in (OPTIONS['Delete'],
|
||||||
OPTIONS['Refresh']):
|
OPTIONS['Refresh']):
|
||||||
LOG.info("refreshing container")
|
LOG.info("refreshing container")
|
||||||
xbmc.sleep(500)
|
app.APP.monitor.waitForAbort(0.5)
|
||||||
xbmc.executebuiltin('Container.Refresh')
|
xbmc.executebuiltin('Container.Refresh')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -9,7 +9,7 @@ from logging import getLogger
|
||||||
from sys import argv
|
from sys import argv
|
||||||
from urllib import urlencode
|
from urllib import urlencode
|
||||||
import xbmcplugin
|
import xbmcplugin
|
||||||
from xbmc import sleep, executebuiltin
|
from xbmc import sleep
|
||||||
from xbmcgui import ListItem
|
from xbmcgui import ListItem
|
||||||
|
|
||||||
from . import utils
|
from . import utils
|
||||||
|
|
|
@ -13,7 +13,7 @@ from xbmcgui import Window
|
||||||
from .plex_db import PlexDB
|
from .plex_db import PlexDB
|
||||||
from . import kodi_db
|
from . import kodi_db
|
||||||
from .downloadutils import DownloadUtils as DU
|
from .downloadutils import DownloadUtils as DU
|
||||||
from . import utils, timing, plex_functions as PF, playback, initialsetup
|
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
|
||||||
|
|
||||||
|
@ -133,11 +133,11 @@ class KodiMonitor(xbmc.Monitor):
|
||||||
utils.window('plex_online', value="sleep")
|
utils.window('plex_online', value="sleep")
|
||||||
elif method == "System.OnWake":
|
elif method == "System.OnWake":
|
||||||
# Allow network to wake up
|
# Allow network to wake up
|
||||||
xbmc.sleep(10000)
|
self.waitForAbort(10)
|
||||||
utils.window('plex_online', value="false")
|
utils.window('plex_online', value="false")
|
||||||
elif method == "GUI.OnScreensaverDeactivated":
|
elif method == "GUI.OnScreensaverDeactivated":
|
||||||
if utils.settings('dbSyncScreensaver') == "true":
|
if utils.settings('dbSyncScreensaver') == "true":
|
||||||
xbmc.sleep(5000)
|
self.waitForAbort(5)
|
||||||
utils.plex_command('RUN_LIB_SCAN', 'full')
|
utils.plex_command('RUN_LIB_SCAN', 'full')
|
||||||
elif method == "System.OnQuit":
|
elif method == "System.OnQuit":
|
||||||
LOG.info('Kodi OnQuit detected - shutting down')
|
LOG.info('Kodi OnQuit detected - shutting down')
|
||||||
|
@ -267,7 +267,7 @@ class KodiMonitor(xbmc.Monitor):
|
||||||
# start as Kodi updates this info very late!! Might get previous
|
# start as Kodi updates this info very late!! Might get previous
|
||||||
# element otherwise
|
# element otherwise
|
||||||
self._already_slept = True
|
self._already_slept = True
|
||||||
xbmc.sleep(1000)
|
self.waitForAbort(1)
|
||||||
try:
|
try:
|
||||||
json_item = js.get_item(playerid)
|
json_item = js.get_item(playerid)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -422,7 +422,7 @@ class SpecialMonitor(backgroundthread.KillableThread):
|
||||||
pass
|
pass
|
||||||
# TODO: start polling PMS for playlist changes
|
# TODO: start polling PMS for playlist changes
|
||||||
# Optionally: poll PMS continuously with custom intervall
|
# Optionally: poll PMS continuously with custom intervall
|
||||||
xbmc.sleep(200)
|
app.APP.monitor.waitForAbort(0.2)
|
||||||
LOG.info("#====---- Special Monitor Stopped ----====#")
|
LOG.info("#====---- Special Monitor Stopped ----====#")
|
||||||
|
|
||||||
|
|
||||||
|
@ -525,7 +525,7 @@ def _clean_file_table():
|
||||||
This function tries for at most 5 seconds to clean the file table.
|
This function tries for at most 5 seconds to clean the file table.
|
||||||
"""
|
"""
|
||||||
LOG.debug('Start cleaning Kodi files table')
|
LOG.debug('Start cleaning Kodi files table')
|
||||||
xbmc.sleep(2000)
|
app.APP.monitor.waitForAbort(2)
|
||||||
with kodi_db.KodiVideoDB() as kodidb_1:
|
with kodi_db.KodiVideoDB() as kodidb_1:
|
||||||
with kodi_db.KodiVideoDB() as kodidb_2:
|
with kodi_db.KodiVideoDB() as kodidb_2:
|
||||||
for file_id in kodidb_1.obsolete_file_ids():
|
for file_id in kodidb_1.obsolete_file_ids():
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
# -*- 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 logging import getLogger
|
||||||
import xbmc
|
|
||||||
|
|
||||||
from . import common
|
from . import common
|
||||||
from ..plex_api import API
|
from ..plex_api import API
|
||||||
|
@ -62,7 +61,7 @@ class FanartThread(backgroundthread.KillableThread):
|
||||||
if self.isSuspended():
|
if self.isSuspended():
|
||||||
if self.isCanceled():
|
if self.isCanceled():
|
||||||
return
|
return
|
||||||
xbmc.sleep(1000)
|
app.APP.monitor.waitForAbort(1)
|
||||||
LOG.info('FanartThread finished')
|
LOG.info('FanartThread finished')
|
||||||
self.callback(finished)
|
self.callback(finished)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
# -*- 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 logging import getLogger
|
||||||
import xbmc
|
|
||||||
|
|
||||||
from .get_metadata import GetMetadataTask, reset_collections
|
from .get_metadata import GetMetadataTask, reset_collections
|
||||||
from .process_metadata import InitNewSection, UpdateLastSync, ProcessMetadata
|
from .process_metadata import InitNewSection, UpdateLastSync, ProcessMetadata
|
||||||
|
@ -120,7 +119,7 @@ class FullSync(common.libsync_mixin):
|
||||||
continue
|
continue
|
||||||
LOG.debug('Waiting for download threads to finish')
|
LOG.debug('Waiting for download threads to finish')
|
||||||
while self.threader.threader.working():
|
while self.threader.threader.working():
|
||||||
xbmc.sleep(100)
|
app.APP.monitor.waitForAbort(0.1)
|
||||||
LOG.debug('Waiting for processing thread to finish section')
|
LOG.debug('Waiting for processing thread to finish section')
|
||||||
self.queue.join()
|
self.queue.join()
|
||||||
reset_collections()
|
reset_collections()
|
||||||
|
|
|
@ -3,9 +3,7 @@
|
||||||
from __future__ import absolute_import, division, unicode_literals
|
from __future__ import absolute_import, division, unicode_literals
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
|
|
||||||
import xbmc
|
from .. import plex_functions as PF, utils, timing, variables as v, app
|
||||||
|
|
||||||
from .. import plex_functions as PF, utils, timing, variables as v
|
|
||||||
|
|
||||||
LOG = getLogger('PLEX.sync.time')
|
LOG = getLogger('PLEX.sync.time')
|
||||||
|
|
||||||
|
@ -88,7 +86,7 @@ def sync_pms_time():
|
||||||
# Toggle watched state
|
# Toggle watched state
|
||||||
PF.scrobble(plex_id, 'watched')
|
PF.scrobble(plex_id, 'watched')
|
||||||
# Let the PMS process this first!
|
# Let the PMS process this first!
|
||||||
xbmc.sleep(1000)
|
app.APP.monitor.waitForAbort(1)
|
||||||
# Get updated metadata
|
# Get updated metadata
|
||||||
xml = PF.GetPlexMetadata(plex_id)
|
xml = PF.GetPlexMetadata(plex_id)
|
||||||
# Toggle watched state back
|
# Toggle watched state back
|
||||||
|
|
|
@ -6,7 +6,6 @@ Used to kick off Kodi playback
|
||||||
from __future__ import absolute_import, division, unicode_literals
|
from __future__ import absolute_import, division, unicode_literals
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from xbmc import Player, sleep
|
|
||||||
|
|
||||||
from .plex_api import API
|
from .plex_api import API
|
||||||
from .plex_db import PlexDB
|
from .plex_db import PlexDB
|
||||||
|
@ -209,7 +208,7 @@ def _playback_init(plex_id, plex_type, playqueue, pos):
|
||||||
# Sleep a bit to let setResolvedUrl do its thing - bit ugly
|
# Sleep a bit to let setResolvedUrl do its thing - bit ugly
|
||||||
sleep_timer = 0
|
sleep_timer = 0
|
||||||
while not app.PLAYSTATE.pkc_caused_stop_done:
|
while not app.PLAYSTATE.pkc_caused_stop_done:
|
||||||
sleep(50)
|
app.APP.monitor.waitForAbort(0.05)
|
||||||
sleep_timer += 1
|
sleep_timer += 1
|
||||||
if sleep_timer > 100:
|
if sleep_timer > 100:
|
||||||
break
|
break
|
||||||
|
@ -505,7 +504,7 @@ def process_indirect(key, offset, resolve=True):
|
||||||
result.listitem = listitem
|
result.listitem = listitem
|
||||||
pickler.pickle_me(result)
|
pickler.pickle_me(result)
|
||||||
else:
|
else:
|
||||||
thread = Thread(target=Player().play,
|
thread = Thread(target=app.APP.monitor.xmbcplayer.play,
|
||||||
args={'item': utils.try_encode(playurl),
|
args={'item': utils.try_encode(playurl),
|
||||||
'listitem': listitem})
|
'listitem': listitem})
|
||||||
thread.setDaemon(True)
|
thread.setDaemon(True)
|
||||||
|
@ -547,12 +546,11 @@ def threaded_playback(kodi_playlist, startpos, offset):
|
||||||
"""
|
"""
|
||||||
Seek immediately after kicking off playback is not reliable.
|
Seek immediately after kicking off playback is not reliable.
|
||||||
"""
|
"""
|
||||||
player = Player()
|
app.APP.monitor.xmbcplayer.play(kodi_playlist, None, False, startpos)
|
||||||
player.play(kodi_playlist, None, False, startpos)
|
|
||||||
if offset and offset != '0':
|
if offset and offset != '0':
|
||||||
i = 0
|
i = 0
|
||||||
while not player.isPlaying():
|
while not app.APP.monitor.xmbcplayer.isPlaying():
|
||||||
sleep(100)
|
app.APP.monitor.waitForAbort(0.1)
|
||||||
i += 1
|
i += 1
|
||||||
if i > 100:
|
if i > 100:
|
||||||
LOG.error('Could not seek to %s', offset)
|
LOG.error('Could not seek to %s', offset)
|
||||||
|
|
|
@ -9,8 +9,7 @@ from ..watchdog import events
|
||||||
from ..watchdog.observers import Observer
|
from ..watchdog.observers import Observer
|
||||||
from ..watchdog.utils.bricks import OrderedSetQueue
|
from ..watchdog.utils.bricks import OrderedSetQueue
|
||||||
|
|
||||||
from .. import path_ops
|
from .. import path_ops, variables as v, app
|
||||||
from .. import variables as v
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
LOG = getLogger('PLEX.playlists.common')
|
LOG = getLogger('PLEX.playlists.common')
|
||||||
|
|
||||||
|
@ -171,7 +170,7 @@ class PlaylistObserver(Observer):
|
||||||
try:
|
try:
|
||||||
new_event, new_watch = event_queue.get(block=False)
|
new_event, new_watch = event_queue.get(block=False)
|
||||||
except Queue.Empty:
|
except Queue.Empty:
|
||||||
time.sleep(0.2)
|
app.APP.monitor.waitForAbort(0.2)
|
||||||
else:
|
else:
|
||||||
event_queue.task_done()
|
event_queue.task_done()
|
||||||
start = time.time()
|
start = time.time()
|
||||||
|
|
|
@ -87,7 +87,7 @@ def init_playqueue_from_plex_children(plex_id, transient_token=None):
|
||||||
PL.add_item_to_playlist(playqueue, i, plex_id=api.plex_id())
|
PL.add_item_to_playlist(playqueue, i, plex_id=api.plex_id())
|
||||||
playqueue.plex_transient_token = transient_token
|
playqueue.plex_transient_token = transient_token
|
||||||
LOG.debug('Firing up Kodi player')
|
LOG.debug('Firing up Kodi player')
|
||||||
xbmc.Player().play(playqueue.kodi_pl, None, False, 0)
|
app.APP.xbmcplayer.play(playqueue.kodi_pl, None, False, 0)
|
||||||
return playqueue
|
return playqueue
|
||||||
|
|
||||||
|
|
||||||
|
@ -197,7 +197,7 @@ class PlayqueueMonitor(backgroundthread.KillableThread):
|
||||||
while self.isSuspended():
|
while self.isSuspended():
|
||||||
if self.isCanceled():
|
if self.isCanceled():
|
||||||
break
|
break
|
||||||
xbmc.sleep(1000)
|
app.APP.monitor.waitForAbort(1)
|
||||||
with app.APP.lock_playqueues:
|
with app.APP.lock_playqueues:
|
||||||
for playqueue in PLAYQUEUES:
|
for playqueue in PLAYQUEUES:
|
||||||
kodi_pl = js.playlist_get_items(playqueue.playlistid)
|
kodi_pl = js.playlist_get_items(playqueue.playlistid)
|
||||||
|
@ -211,5 +211,5 @@ class PlayqueueMonitor(backgroundthread.KillableThread):
|
||||||
# compare old and new playqueue
|
# compare old and new playqueue
|
||||||
self._compare_playqueues(playqueue, kodi_pl)
|
self._compare_playqueues(playqueue, kodi_pl)
|
||||||
playqueue.old_kodi_pl = list(kodi_pl)
|
playqueue.old_kodi_pl = list(kodi_pl)
|
||||||
xbmc.sleep(200)
|
app.APP.monitor.waitForAbort(0.2)
|
||||||
LOG.info("----===## PlayqueueMonitor stopped ##===----")
|
LOG.info("----===## PlayqueueMonitor stopped ##===----")
|
||||||
|
|
|
@ -9,7 +9,7 @@ from threading import Thread
|
||||||
from Queue import Empty
|
from Queue import Empty
|
||||||
from socket import SHUT_RDWR
|
from socket import SHUT_RDWR
|
||||||
from urllib import urlencode
|
from urllib import urlencode
|
||||||
from xbmc import sleep, executebuiltin, Player
|
from xbmc import executebuiltin
|
||||||
|
|
||||||
from .plexbmchelper import listener, plexgdm, subscribers, httppersist
|
from .plexbmchelper import listener, plexgdm, subscribers, httppersist
|
||||||
from .plex_api import API
|
from .plex_api import API
|
||||||
|
@ -76,8 +76,6 @@ class PlexCompanion(backgroundthread.KillableThread):
|
||||||
self.client = plexgdm.plexgdm()
|
self.client = plexgdm.plexgdm()
|
||||||
self.client.clientDetails()
|
self.client.clientDetails()
|
||||||
LOG.debug("Registration string is:\n%s", self.client.getClientDetails())
|
LOG.debug("Registration string is:\n%s", self.client.getClientDetails())
|
||||||
# kodi player instance
|
|
||||||
self.player = Player()
|
|
||||||
self.httpd = False
|
self.httpd = False
|
||||||
self.subscription_manager = None
|
self.subscription_manager = None
|
||||||
super(PlexCompanion, self).__init__()
|
super(PlexCompanion, self).__init__()
|
||||||
|
@ -177,14 +175,14 @@ class PlexCompanion(backgroundthread.KillableThread):
|
||||||
if 'audioStreamID' in data:
|
if 'audioStreamID' in data:
|
||||||
index = playqueue.items[pos].kodi_stream_index(
|
index = playqueue.items[pos].kodi_stream_index(
|
||||||
data['audioStreamID'], 'audio')
|
data['audioStreamID'], 'audio')
|
||||||
self.player.setAudioStream(index)
|
app.APP.monitor.xbmcplayer.setAudioStream(index)
|
||||||
elif 'subtitleStreamID' in data:
|
elif 'subtitleStreamID' in data:
|
||||||
if data['subtitleStreamID'] == '0':
|
if data['subtitleStreamID'] == '0':
|
||||||
self.player.showSubtitles(False)
|
app.APP.monitor.xbmcplayer.showSubtitles(False)
|
||||||
else:
|
else:
|
||||||
index = playqueue.items[pos].kodi_stream_index(
|
index = playqueue.items[pos].kodi_stream_index(
|
||||||
data['subtitleStreamID'], 'subtitle')
|
data['subtitleStreamID'], 'subtitle')
|
||||||
self.player.setSubtitleStream(index)
|
app.APP.monitor.xbmcplayer.setSubtitleStream(index)
|
||||||
else:
|
else:
|
||||||
LOG.error('Unknown setStreams command: %s', data)
|
LOG.error('Unknown setStreams command: %s', data)
|
||||||
|
|
||||||
|
@ -269,7 +267,7 @@ class PlexCompanion(backgroundthread.KillableThread):
|
||||||
# Start up instances
|
# Start up instances
|
||||||
request_mgr = httppersist.RequestMgr()
|
request_mgr = httppersist.RequestMgr()
|
||||||
subscription_manager = subscribers.SubscriptionMgr(request_mgr,
|
subscription_manager = subscribers.SubscriptionMgr(request_mgr,
|
||||||
self.player)
|
app.APP.monitor.xbmcplayer)
|
||||||
self.subscription_manager = subscription_manager
|
self.subscription_manager = subscription_manager
|
||||||
|
|
||||||
if utils.settings('plexCompanion') == 'true':
|
if utils.settings('plexCompanion') == 'true':
|
||||||
|
@ -288,7 +286,7 @@ class PlexCompanion(backgroundthread.KillableThread):
|
||||||
LOG.error("Unable to start PlexCompanion. Traceback:")
|
LOG.error("Unable to start PlexCompanion. Traceback:")
|
||||||
import traceback
|
import traceback
|
||||||
LOG.error(traceback.print_exc())
|
LOG.error(traceback.print_exc())
|
||||||
sleep(3000)
|
app.APP.monitor.waitForAbort(3)
|
||||||
if start_count == 3:
|
if start_count == 3:
|
||||||
LOG.error("Error: Unable to start web helper.")
|
LOG.error("Error: Unable to start web helper.")
|
||||||
httpd = False
|
httpd = False
|
||||||
|
@ -308,7 +306,7 @@ class PlexCompanion(backgroundthread.KillableThread):
|
||||||
while self.isSuspended():
|
while self.isSuspended():
|
||||||
if self.isCanceled():
|
if self.isCanceled():
|
||||||
break
|
break
|
||||||
sleep(1000)
|
app.APP.monitor.waitForAbort(1)
|
||||||
try:
|
try:
|
||||||
message_count += 1
|
message_count += 1
|
||||||
if httpd:
|
if httpd:
|
||||||
|
@ -347,6 +345,6 @@ class PlexCompanion(backgroundthread.KillableThread):
|
||||||
app.APP.companion_queue.task_done()
|
app.APP.companion_queue.task_done()
|
||||||
# Don't sleep
|
# Don't sleep
|
||||||
continue
|
continue
|
||||||
sleep(50)
|
app.APP.monitor.waitForAbort(0.05)
|
||||||
subscription_manager.signal_stop()
|
subscription_manager.signal_stop()
|
||||||
client.stop_all()
|
client.stop_all()
|
||||||
|
|
|
@ -8,10 +8,9 @@ from urlparse import urlparse, parse_qsl
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from time import time
|
from time import time
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from xbmc import sleep
|
|
||||||
|
|
||||||
from .downloadutils import DownloadUtils as DU
|
from .downloadutils import DownloadUtils as DU
|
||||||
from . import backgroundthread, utils, plex_tv, variables as v
|
from . import backgroundthread, utils, plex_tv, variables as v, app
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
LOG = getLogger('PLEX.plex_functions')
|
LOG = getLogger('PLEX.plex_functions')
|
||||||
|
@ -388,7 +387,7 @@ def _pms_list_from_plex_tv(token):
|
||||||
thread.start()
|
thread.start()
|
||||||
threads.append(thread)
|
threads.append(thread)
|
||||||
else:
|
else:
|
||||||
sleep(50)
|
app.APP.monitor.waitForAbort(0.05)
|
||||||
# wait for requests being answered
|
# wait for requests being answered
|
||||||
for thread in threads:
|
for thread in threads:
|
||||||
thread.join()
|
thread.join()
|
||||||
|
@ -616,7 +615,7 @@ class DownloadGen(object):
|
||||||
self._download_chunk(
|
self._download_chunk(
|
||||||
start=self.current + (self.cache_factor - 1) * CONTAINERSIZE)
|
start=self.current + (self.cache_factor - 1) * CONTAINERSIZE)
|
||||||
return child
|
return child
|
||||||
sleep(100)
|
app.APP.monitor.waitForAbort(0.1)
|
||||||
if not len(self.pending_counter) and not len(self.xml):
|
if not len(self.pending_counter) and not len(self.xml):
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
LOG.debug('Waiting for download to finish')
|
LOG.debug('Waiting for download to finish')
|
||||||
|
|
|
@ -4,7 +4,6 @@ from __future__ import absolute_import, division, unicode_literals
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
import xbmc
|
|
||||||
|
|
||||||
from .downloadutils import DownloadUtils as DU
|
from .downloadutils import DownloadUtils as DU
|
||||||
from . import utils, app
|
from . import utils, app
|
||||||
|
@ -181,12 +180,12 @@ class PinLogin(object):
|
||||||
try:
|
try:
|
||||||
token = xml.find('auth_token').text
|
token = xml.find('auth_token').text
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
time.sleep(self.POLL_INTERVAL)
|
app.APP.monitor.waitForAbort(self.POLL_INTERVAL)
|
||||||
continue
|
continue
|
||||||
if token:
|
if token:
|
||||||
self.token = token
|
self.token = token
|
||||||
break
|
break
|
||||||
time.sleep(self.POLL_INTERVAL)
|
app.APP.monitor.waitForAbort(self.POLL_INTERVAL)
|
||||||
if self._callback:
|
if self._callback:
|
||||||
self._callback(self.token, self.xml)
|
self._callback(self.token, self.xml)
|
||||||
if self.token:
|
if self.token:
|
||||||
|
@ -256,7 +255,7 @@ def _sign_in_with_pin():
|
||||||
LOG.debug('Pin login aborted')
|
LOG.debug('Pin login aborted')
|
||||||
pinlogin.abort()
|
pinlogin.abort()
|
||||||
return
|
return
|
||||||
xbmc.sleep(100)
|
app.APP.monitor.waitForAbort(0.1)
|
||||||
if not pinlogin.expired:
|
if not pinlogin.expired:
|
||||||
if pinlogin.xml:
|
if pinlogin.xml:
|
||||||
pin_login_window.setLinking()
|
pin_login_window.setLinking()
|
||||||
|
|
|
@ -15,12 +15,11 @@ from .. import companion
|
||||||
from .. import json_rpc as js
|
from .. import json_rpc as js
|
||||||
from .. import clientinfo
|
from .. import clientinfo
|
||||||
from .. import variables as v
|
from .. import variables as v
|
||||||
|
from .. import app
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
LOG = getLogger('PLEX.listener')
|
LOG = getLogger('PLEX.listener')
|
||||||
PLAYER = xbmc.Player()
|
|
||||||
MONITOR = xbmc.Monitor()
|
|
||||||
|
|
||||||
# Hack we need in order to keep track of the open connections from Plex Web
|
# Hack we need in order to keep track of the open connections from Plex Web
|
||||||
CLIENT_DICT = {}
|
CLIENT_DICT = {}
|
||||||
|
@ -130,20 +129,20 @@ class MyHandler(BaseHTTPRequestHandler):
|
||||||
# Only reply if there is indeed something playing
|
# Only reply if there is indeed something playing
|
||||||
# Otherwise, all clients seem to keep connection open
|
# Otherwise, all clients seem to keep connection open
|
||||||
if params.get('wait') == '1':
|
if params.get('wait') == '1':
|
||||||
MONITOR.waitForAbort(0.95)
|
app.APP.monitor.waitForAbort(0.95)
|
||||||
if self.client_address[0] not in CLIENT_DICT:
|
if self.client_address[0] not in CLIENT_DICT:
|
||||||
CLIENT_DICT[self.client_address[0]] = []
|
CLIENT_DICT[self.client_address[0]] = []
|
||||||
tracker = CLIENT_DICT[self.client_address[0]]
|
tracker = CLIENT_DICT[self.client_address[0]]
|
||||||
tracker.append(self.client_address[1])
|
tracker.append(self.client_address[1])
|
||||||
while (not PLAYER.isPlaying() and
|
while (not app.APP.monitor.xbmcplayer.isPlaying() and
|
||||||
not MONITOR.abortRequested() and
|
not app.APP.monitor.abortRequested() and
|
||||||
sub_mgr.stop_sent_to_web and not
|
sub_mgr.stop_sent_to_web and not
|
||||||
(len(tracker) >= 4 and
|
(len(tracker) >= 4 and
|
||||||
tracker[0] == self.client_address[1])):
|
tracker[0] == self.client_address[1])):
|
||||||
# Keep at most 3 connections open, then drop the first one
|
# Keep at most 3 connections open, then drop the first one
|
||||||
# Doesn't need to be thread-save
|
# Doesn't need to be thread-save
|
||||||
# Silly stuff really
|
# Silly stuff really
|
||||||
MONITOR.waitForAbort(1)
|
app.APP.monitor.waitForAbort(1)
|
||||||
# Let PKC know that we're releasing this connection
|
# Let PKC know that we're releasing this connection
|
||||||
tracker.pop(0)
|
tracker.pop(0)
|
||||||
msg = sub_mgr.msg(js.get_players()).format(
|
msg = sub_mgr.msg(js.get_players()).format(
|
||||||
|
|
|
@ -28,11 +28,9 @@ import logging
|
||||||
import socket
|
import socket
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
from xbmc import sleep
|
|
||||||
|
|
||||||
from ..downloadutils import DownloadUtils as DU
|
from ..downloadutils import DownloadUtils as DU
|
||||||
from .. import utils, app
|
from .. import utils, app, variables as v
|
||||||
from .. import variables as v
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
@ -172,7 +170,7 @@ class plexgdm:
|
||||||
|
|
||||||
log.debug("Sending registration data HTTP/1.0 200 OK")
|
log.debug("Sending registration data HTTP/1.0 200 OK")
|
||||||
self.client_registered = True
|
self.client_registered = True
|
||||||
sleep(500)
|
app.APP.monitor.waitForAbort(0.5)
|
||||||
log.info("Client Update loop stopped")
|
log.info("Client Update loop stopped")
|
||||||
# When we are finished, then send a final goodbye message to
|
# When we are finished, then send a final goodbye message to
|
||||||
# deregister cleanly.
|
# deregister cleanly.
|
||||||
|
@ -286,7 +284,7 @@ class plexgdm:
|
||||||
if discovery_count > self.discovery_interval:
|
if discovery_count > self.discovery_interval:
|
||||||
self.discover()
|
self.discover()
|
||||||
discovery_count = 0
|
discovery_count = 0
|
||||||
sleep(500)
|
app.APP.monitor.waitForAbort(0.5)
|
||||||
|
|
||||||
def start_discovery(self, daemon=False):
|
def start_discovery(self, daemon=False):
|
||||||
if not self._discovery_is_running:
|
if not self._discovery_is_running:
|
||||||
|
|
|
@ -79,7 +79,6 @@ class Service():
|
||||||
utils.window('plex_kodiProfile',
|
utils.window('plex_kodiProfile',
|
||||||
value=utils.try_decode(xbmc.translatePath("special://profile")))
|
value=utils.try_decode(xbmc.translatePath("special://profile")))
|
||||||
|
|
||||||
self.monitor = xbmc.Monitor()
|
|
||||||
# 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
|
||||||
from .library_sync import videonodes
|
from .library_sync import videonodes
|
||||||
|
@ -100,7 +99,7 @@ class Service():
|
||||||
i = 0
|
i = 0
|
||||||
while app.SYNC.db_scan:
|
while app.SYNC.db_scan:
|
||||||
i += 1
|
i += 1
|
||||||
xbmc.sleep(50)
|
app.APP.monitor.waitForAbort(0.05)
|
||||||
if i > 100:
|
if i > 100:
|
||||||
LOG.error('Could not stop library sync, aborting log-out')
|
LOG.error('Could not stop library sync, aborting log-out')
|
||||||
# Failed to reset PMS and plex.tv connects. Try to restart Kodi
|
# Failed to reset PMS and plex.tv connects. Try to restart Kodi
|
||||||
|
@ -238,6 +237,7 @@ class Service():
|
||||||
# if profile switch happens more than once.
|
# if profile switch happens more than once.
|
||||||
app.init()
|
app.init()
|
||||||
# Some plumbing
|
# Some plumbing
|
||||||
|
app.APP.monitor = kodimonitor.KodiMonitor()
|
||||||
artwork.IMAGE_CACHING_SUSPENDS = [
|
artwork.IMAGE_CACHING_SUSPENDS = [
|
||||||
app.SYNC.suspend_library_thread,
|
app.SYNC.suspend_library_thread,
|
||||||
app.SYNC.stop_sync,
|
app.SYNC.stop_sync,
|
||||||
|
@ -325,7 +325,7 @@ class Service():
|
||||||
if utils.window('plex_online') == "true":
|
if utils.window('plex_online') == "true":
|
||||||
# Plex server is online
|
# Plex server is online
|
||||||
if app.CONN.pms_status == 'Stop':
|
if app.CONN.pms_status == 'Stop':
|
||||||
xbmc.sleep(500)
|
app.APP.monitor.waitForAbort(0.05)
|
||||||
continue
|
continue
|
||||||
elif app.CONN.pms_status == '401':
|
elif app.CONN.pms_status == '401':
|
||||||
# Unauthorized access, revoke token
|
# Unauthorized access, revoke token
|
||||||
|
@ -352,7 +352,7 @@ class Service():
|
||||||
sound=False)
|
sound=False)
|
||||||
# Start monitoring kodi events
|
# Start monitoring kodi events
|
||||||
if not self.kodimonitor_running:
|
if not self.kodimonitor_running:
|
||||||
self.kodimonitor_running = kodimonitor.KodiMonitor()
|
self.kodimonitor_running = True
|
||||||
self.specialmonitor.start()
|
self.specialmonitor.start()
|
||||||
# Start the Websocket Client
|
# Start the Websocket Client
|
||||||
if not self.ws_running:
|
if not self.ws_running:
|
||||||
|
@ -429,7 +429,7 @@ class Service():
|
||||||
# Hence resume threads
|
# Hence resume threads
|
||||||
app.SYNC.suspend_library_thread = False
|
app.SYNC.suspend_library_thread = False
|
||||||
|
|
||||||
if self.monitor.waitForAbort(0.05):
|
if app.APP.monitor.waitForAbort(0.05):
|
||||||
# Abort was requested while waiting. We should exit
|
# Abort was requested while waiting. We should exit
|
||||||
break
|
break
|
||||||
# Tell all threads to terminate (e.g. several lib sync threads)
|
# Tell all threads to terminate (e.g. several lib sync threads)
|
||||||
|
|
|
@ -231,7 +231,7 @@ class Sync(backgroundthread.KillableThread):
|
||||||
# Abort was requested while waiting. We should exit
|
# Abort was requested while waiting. We should exit
|
||||||
LOG.info("###===--- Sync Thread Stopped ---===###")
|
LOG.info("###===--- Sync Thread Stopped ---===###")
|
||||||
return
|
return
|
||||||
xbmc.sleep(1000)
|
app.APP.monitor.waitForAbort(1)
|
||||||
|
|
||||||
if not install_sync_done:
|
if not install_sync_done:
|
||||||
# Very FIRST sync ever upon installation or reset of Kodi DB
|
# Very FIRST sync ever upon installation or reset of Kodi DB
|
||||||
|
@ -257,7 +257,7 @@ class Sync(backgroundthread.KillableThread):
|
||||||
self.start_image_cache_thread()
|
self.start_image_cache_thread()
|
||||||
else:
|
else:
|
||||||
LOG.error('Initial start-up full sync unsuccessful')
|
LOG.error('Initial start-up full sync unsuccessful')
|
||||||
xbmc.sleep(1000)
|
app.APP.monitor.waitForAbort(1)
|
||||||
self.force_dialog = False
|
self.force_dialog = False
|
||||||
xbmc.executebuiltin('InhibitIdleShutdown(false)')
|
xbmc.executebuiltin('InhibitIdleShutdown(false)')
|
||||||
|
|
||||||
|
@ -279,7 +279,7 @@ class Sync(backgroundthread.KillableThread):
|
||||||
self.start_image_cache_thread()
|
self.start_image_cache_thread()
|
||||||
else:
|
else:
|
||||||
LOG.info('Startup sync has not yet been successful')
|
LOG.info('Startup sync has not yet been successful')
|
||||||
xbmc.sleep(1000)
|
app.APP.monitor.waitForAbort(1)
|
||||||
|
|
||||||
# Currently no db scan, so we could start a new scan
|
# Currently no db scan, so we could start a new scan
|
||||||
elif app.SYNC.db_scan is False:
|
elif app.SYNC.db_scan is False:
|
||||||
|
@ -320,9 +320,9 @@ class Sync(backgroundthread.KillableThread):
|
||||||
library_sync.store_websocket_message(message)
|
library_sync.store_websocket_message(message)
|
||||||
queue.task_done()
|
queue.task_done()
|
||||||
# Sleep just a bit
|
# Sleep just a bit
|
||||||
xbmc.sleep(10)
|
app.APP.monitor.waitForAbort(0.01)
|
||||||
continue
|
continue
|
||||||
xbmc.sleep(100)
|
app.APP.monitor.waitForAbort(0.1)
|
||||||
# Shut down playlist monitoring
|
# Shut down playlist monitoring
|
||||||
if playlist_monitor:
|
if playlist_monitor:
|
||||||
playlist_monitor.stop()
|
playlist_monitor.stop()
|
||||||
|
|
|
@ -43,12 +43,11 @@ import uuid
|
||||||
import hashlib
|
import hashlib
|
||||||
import base64
|
import base64
|
||||||
import threading
|
import threading
|
||||||
import time
|
|
||||||
import logging
|
import logging
|
||||||
import traceback
|
import traceback
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from . import utils
|
from . import utils, app
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
@ -821,7 +820,7 @@ class WebSocketApp(object):
|
||||||
def _send_ping(self, interval):
|
def _send_ping(self, interval):
|
||||||
while True:
|
while True:
|
||||||
for _ in range(interval):
|
for _ in range(interval):
|
||||||
time.sleep(1)
|
app.APP.monitor.waitForAbort(1)
|
||||||
if not self.keep_running:
|
if not self.keep_running:
|
||||||
return
|
return
|
||||||
self.sock.ping()
|
self.sock.ping()
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
from json import loads
|
from json import loads
|
||||||
from ssl import CERT_NONE
|
from ssl import CERT_NONE
|
||||||
from xbmc import sleep
|
|
||||||
|
|
||||||
from . import backgroundthread, websocket, utils, companion, app, variables as v
|
from . import backgroundthread, websocket, utils, companion, app, variables as v
|
||||||
|
|
||||||
|
@ -60,7 +59,7 @@ class WebSocket(backgroundthread.KillableThread):
|
||||||
LOG.info("##===---- %s Stopped ----===##",
|
LOG.info("##===---- %s Stopped ----===##",
|
||||||
self.__class__.__name__)
|
self.__class__.__name__)
|
||||||
return
|
return
|
||||||
sleep(1000)
|
app.APP.monitor.waitForAbort(1)
|
||||||
try:
|
try:
|
||||||
self.process(*self.receive(self.ws))
|
self.process(*self.receive(self.ws))
|
||||||
except websocket.WebSocketTimeoutException:
|
except websocket.WebSocketTimeoutException:
|
||||||
|
@ -86,12 +85,12 @@ class WebSocket(backgroundthread.KillableThread):
|
||||||
LOG.info('%s: Repeated IOError detected. Stopping now',
|
LOG.info('%s: Repeated IOError detected. Stopping now',
|
||||||
self.__class__.__name__)
|
self.__class__.__name__)
|
||||||
break
|
break
|
||||||
sleep(1000)
|
app.APP.monitor.waitForAbort(1)
|
||||||
except websocket.WebSocketTimeoutException:
|
except websocket.WebSocketTimeoutException:
|
||||||
LOG.info("%s: Timeout while connecting, trying again",
|
LOG.info("%s: Timeout while connecting, trying again",
|
||||||
self.__class__.__name__)
|
self.__class__.__name__)
|
||||||
self.ws = None
|
self.ws = None
|
||||||
sleep(1000)
|
app.APP.monitor.waitForAbort(1)
|
||||||
except websocket.WebSocketException as e:
|
except websocket.WebSocketException as e:
|
||||||
LOG.info('%s: WebSocketException: %s',
|
LOG.info('%s: WebSocketException: %s',
|
||||||
self.__class__.__name__, e)
|
self.__class__.__name__, e)
|
||||||
|
@ -103,7 +102,7 @@ class WebSocket(backgroundthread.KillableThread):
|
||||||
'Stopping now', self.__class__.__name__)
|
'Stopping now', self.__class__.__name__)
|
||||||
break
|
break
|
||||||
self.ws = None
|
self.ws = None
|
||||||
sleep(1000)
|
app.APP.monitor.waitForAbort(1)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.error('%s: Unknown exception encountered when '
|
LOG.error('%s: Unknown exception encountered when '
|
||||||
'connecting: %s', self.__class__.__name__, e)
|
'connecting: %s', self.__class__.__name__, e)
|
||||||
|
@ -111,7 +110,7 @@ class WebSocket(backgroundthread.KillableThread):
|
||||||
LOG.error("%s: Traceback:\n%s",
|
LOG.error("%s: Traceback:\n%s",
|
||||||
self.__class__.__name__, traceback.format_exc())
|
self.__class__.__name__, traceback.format_exc())
|
||||||
self.ws = None
|
self.ws = None
|
||||||
sleep(1000)
|
app.APP.monitor.waitForAbort(1)
|
||||||
else:
|
else:
|
||||||
counter = 0
|
counter = 0
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
@ -7,6 +7,8 @@ import time
|
||||||
import threading
|
import threading
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
from .. import app
|
||||||
|
|
||||||
MONITOR = None
|
MONITOR = None
|
||||||
|
|
||||||
|
|
||||||
|
@ -918,7 +920,7 @@ class PropertyTimer():
|
||||||
|
|
||||||
def _wait(self):
|
def _wait(self):
|
||||||
while not xbmc.abortRequested and time.time() < self._endTime:
|
while not xbmc.abortRequested and time.time() < self._endTime:
|
||||||
xbmc.sleep(100)
|
app.APP.monitor.waitForAbort(0.1)
|
||||||
if xbmc.abortRequested:
|
if xbmc.abortRequested:
|
||||||
return
|
return
|
||||||
if self._endTime == 0:
|
if self._endTime == 0:
|
||||||
|
|
Loading…
Reference in a new issue