PlexKodiConnect/resources/lib/library_sync/get_metadata.py

123 lines
4.5 KiB
Python
Raw Normal View History

2017-04-03 01:02:41 +10:00
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals
2017-04-03 01:02:41 +10:00
from logging import getLogger
from threading import Thread
from Queue import Empty
from xbmc import sleep
2018-06-22 03:24:37 +10:00
from .. import utils
from .. import plex_functions as PF
from . import sync_info
2017-04-03 01:02:41 +10:00
###############################################################################
LOG = getLogger("PLEX." + __name__)
2017-04-03 01:02:41 +10:00
###############################################################################
2018-06-22 03:24:37 +10:00
@utils.thread_methods(add_stops=['SUSPEND_LIBRARY_THREAD',
'STOP_SYNC',
'SUSPEND_SYNC'])
class ThreadedGetMetadata(Thread):
2017-04-03 01:02:41 +10:00
"""
Threaded download of Plex XML metadata for a certain library item.
Fills the out_queue with the downloaded etree XML objects
Input:
queue Queue.Queue() object that you'll need to fill up
with plex_ids
2017-04-03 01:02:41 +10:00
out_queue Queue() object where this thread will store
the downloaded metadata XMLs as etree objects
"""
def __init__(self, queue, out_queue):
self.queue = queue
self.out_queue = out_queue
Thread.__init__(self)
def terminate_now(self):
"""
Needed to terminate this thread, because there might be items left in
the queue which could cause other threads to hang
"""
while not self.queue.empty():
# Still try because remaining item might have been taken
try:
self.queue.get(block=False)
except Empty:
sleep(10)
continue
else:
self.queue.task_done()
2018-02-12 00:57:39 +11:00
if self.stopped():
2017-04-03 01:02:41 +10:00
# Shutdown from outside requested; purge out_queue as well
while not self.out_queue.empty():
# Still try because remaining item might have been taken
try:
self.out_queue.get(block=False)
except Empty:
sleep(10)
continue
else:
self.out_queue.task_done()
def run(self):
"""
Do the work
"""
LOG.debug('Starting get metadata thread')
2017-04-03 01:02:41 +10:00
# cache local variables because it's faster
queue = self.queue
out_queue = self.out_queue
2018-02-12 00:57:39 +11:00
stopped = self.stopped
while stopped() is False:
2017-04-03 01:02:41 +10:00
# grabs Plex item from queue
try:
item = queue.get(block=False)
# Empty queue
except Empty:
sleep(20)
continue
# Download Metadata
2018-06-22 03:24:37 +10:00
xml = PF.GetPlexMetadata(item['plex_id'])
2017-04-03 01:02:41 +10:00
if xml is None:
# Did not receive a valid XML - skip that item for now
LOG.error("Could not get metadata for %s. Skipping that item "
"for now", item['plex_id'])
2017-04-03 01:02:41 +10:00
# Increase BOTH counters - since metadata won't be processed
with sync_info.LOCK:
sync_info.GET_METADATA_COUNT += 1
sync_info.PROCESS_METADATA_COUNT += 1
queue.task_done()
continue
elif xml == 401:
LOG.error('HTTP 401 returned by PMS. Too much strain? '
2017-04-03 01:02:41 +10:00
'Cancelling sync for now')
2018-06-22 03:24:37 +10:00
utils.window('plex_scancrashed', value='401')
2017-04-03 01:02:41 +10:00
# Kill remaining items in queue (for main thread to cont.)
queue.task_done()
break
item['xml'] = xml
2017-04-03 01:02:41 +10:00
if item.get('get_children') is True:
2018-06-22 03:24:37 +10:00
children_xml = PF.GetAllPlexChildren(item['plex_id'])
2017-04-03 01:02:41 +10:00
try:
children_xml[0].attrib
except (TypeError, IndexError, AttributeError):
LOG.error('Could not get children for Plex id %s',
item['plex_id'])
2017-04-03 01:02:41 +10:00
item['children'] = []
2017-08-20 00:49:29 +10:00
else:
item['children'] = children_xml
2017-04-03 01:02:41 +10:00
# place item into out queue
out_queue.put(item)
# Keep track of where we are at
with sync_info.LOCK:
sync_info.GET_METADATA_COUNT += 1
# signals to queue job is done
queue.task_done()
# Empty queue in case PKC was shut down (main thread hangs otherwise)
self.terminate_now()
LOG.debug('Get metadata thread terminated')