Improve sync resiliance and GDM discovery

Improve sync resiliance to bad connections (e.g. behind a firewall)
This commit is contained in:
tomkat83 2016-03-08 17:41:07 +01:00
parent e5e6f2208e
commit e635f43845
4 changed files with 67 additions and 17 deletions

View file

@ -55,7 +55,7 @@ import re
import json import json
from urllib import urlencode, quote_plus from urllib import urlencode, quote_plus
from PlexFunctions import PlexToKodiTimefactor from PlexFunctions import PlexToKodiTimefactor, PMSHttpsEnabled
try: try:
import xml.etree.cElementTree as etree import xml.etree.cElementTree as etree
@ -630,6 +630,12 @@ class PlexAPI():
self.getPMSListFromMyPlex(ATV_udid, authtoken) self.getPMSListFromMyPlex(ATV_udid, authtoken)
# all servers - update enableGzip # all servers - update enableGzip
for uuid_id in self.g_PMS.get(ATV_udid, {}): for uuid_id in self.g_PMS.get(ATV_udid, {}):
# Ping to check whether we need HTTPs or HTTP
url = (self.getPMSProperty(ATV_udid, uuid_id, 'ip') + ':'
+ self.getPMSProperty(ATV_udid, uuid_id, 'port'))
if PMSHttpsEnabled(url):
self.logMsg('PMS %s talks HTTPS' % uuid_id, 1)
self.updatePMSProperty(ATV_udid, uuid_id, 'scheme', 'https')
# enable Gzip if not on same host, local&remote PMS depending # enable Gzip if not on same host, local&remote PMS depending
# on setting # on setting
enableGzip = (not self.getPMSProperty(ATV_udid, uuid_id, 'ip') == IP_self) \ enableGzip = (not self.getPMSProperty(ATV_udid, uuid_id, 'ip') == IP_self) \

View file

@ -347,3 +347,24 @@ def getPlexRepeat(kodiRepeat):
'all': '2' # does this work?!? 'all': '2' # does this work?!?
} }
return plexRepeat.get(kodiRepeat) return plexRepeat.get(kodiRepeat)
def PMSHttpsEnabled(url):
"""
Returns True if the PMS wants to talk https, False otherwise
With with e.g. url=192.168.0.1:32400 (NO http/https)
This is done by GET /identity (returns an error if https is enabled and we
are trying to use http)
"""
xml = downloadutils.DownloadUtils().downloadUrl('http://%s/identity' % url)
try:
# received a valid XML - http connection is possible
xml.attrib
logMsg('PMSHttpsEnabled', 'PMS on %s talks HTTP' % url, 1)
return False
except:
# couldn't get an xml - switch to https traffic
logMsg('PMSHttpsEnabled', 'PMS on %s talks HTTPS' % url, 1)
return True

View file

@ -40,10 +40,11 @@ class ThreadedGetMetadata(Thread):
the downloaded metadata XMLs as etree objects the downloaded metadata XMLs as etree objects
lock Lock(), used for counting where we are lock Lock(), used for counting where we are
""" """
def __init__(self, queue, out_queue, lock): def __init__(self, queue, out_queue, lock, processlock):
self.queue = queue self.queue = queue
self.out_queue = out_queue self.out_queue = out_queue
self.lock = lock self.lock = lock
self.processlock = processlock
Thread.__init__(self) Thread.__init__(self)
def run(self): def run(self):
@ -51,8 +52,10 @@ class ThreadedGetMetadata(Thread):
queue = self.queue queue = self.queue
out_queue = self.out_queue out_queue = self.out_queue
lock = self.lock lock = self.lock
processlock = self.processlock
threadStopped = self.threadStopped threadStopped = self.threadStopped
global getMetadataCount global getMetadataCount
global processMetadataCount
while threadStopped() is False: while threadStopped() is False:
# grabs Plex item from queue # grabs Plex item from queue
try: try:
@ -66,9 +69,13 @@ class ThreadedGetMetadata(Thread):
if plexXML is None: if plexXML is None:
# Did not receive a valid XML - skip that item for now # Did not receive a valid XML - skip that item for now
self.logMsg("Could not get metadata for %s. " self.logMsg("Could not get metadata for %s. "
"Skipping that item for now", -1) "Skipping that item for now"
% updateItem['itemId'], -1)
# Increase BOTH counters - since metadata won't be processed
with lock: with lock:
getMetadataCount += 1 getMetadataCount += 1
with processlock:
processMetadataCount += 1
queue.task_done() queue.task_done()
continue continue
@ -119,20 +126,20 @@ class ThreadedProcessMetadata(Thread):
except Queue.Empty: except Queue.Empty:
xbmc.sleep(100) xbmc.sleep(100)
continue continue
# Do the work; lock to be sure we've only got 1 Thread # Do the work
plexitem = updateItem['XML'] plexitem = updateItem['XML']
method = updateItem['method'] method = updateItem['method']
viewName = updateItem['viewName'] viewName = updateItem['viewName']
viewId = updateItem['viewId'] viewId = updateItem['viewId']
title = updateItem['title'] title = updateItem['title']
itemSubFkt = getattr(item, method) itemSubFkt = getattr(item, method)
with lock:
# Get the one child entry in the xml and process # Get the one child entry in the xml and process
for child in plexitem: for child in plexitem:
itemSubFkt(child, itemSubFkt(child,
viewtag=viewName, viewtag=viewName,
viewid=viewId) viewid=viewId)
# Keep track of where we are at # Keep track of where we are at
with lock:
processMetadataCount += 1 processMetadataCount += 1
processingViewName = title processingViewName = title
# signals to queue job is done # signals to queue job is done
@ -728,7 +735,8 @@ class LibrarySync(Thread):
for i in range(min(self.syncThreadNumber, itemNumber)): for i in range(min(self.syncThreadNumber, itemNumber)):
thread = ThreadedGetMetadata(getMetadataQueue, thread = ThreadedGetMetadata(getMetadataQueue,
processMetadataQueue, processMetadataQueue,
getMetadataLock) getMetadataLock,
processMetadataLock)
thread.setDaemon(True) thread.setDaemon(True)
thread.start() thread.start()
threads.append(thread) threads.append(thread)

View file

@ -31,7 +31,10 @@ import re
import threading import threading
import time import time
import urllib2 import urllib2
import downloadutils import downloadutils
from PlexFunctions import PMSHttpsEnabled
class plexgdm: class plexgdm:
@ -56,6 +59,7 @@ class plexgdm:
self.discovery_complete = False self.discovery_complete = False
self.client_registered = False self.client_registered = False
self.debug = debug self.debug = debug
self.download = downloadutils.DownloadUtils().downloadUrl
def __printDebug(self, message, level=1): def __printDebug(self, message, level=1):
if self.debug: if self.debug:
@ -139,13 +143,19 @@ class plexgdm:
try: try:
media_server=self.server_list[0]['server'] media_server=self.server_list[0]['server']
media_port=self.server_list[0]['port'] media_port=self.server_list[0]['port']
scheme = self.server_list[0]['protocol']
self.__printDebug("Checking server [%s] on port [%s]" % (media_server, media_port) ,2) self.__printDebug("Checking server [%s] on port [%s]" % (media_server, media_port) ,2)
client_result = downloadutils.DownloadUtils().downloadUrl( client_result = self.download(
'http://%s:%s/clients' % (media_server, media_port)) '%s://%s:%s/clients' % (scheme, media_server, media_port))
# f = urllib2.urlopen('http://%s:%s/clients' % (media_server, media_port)) # f = urllib2.urlopen('http://%s:%s/clients' % (media_server, media_port))
# client_result = f.read() # client_result = f.read()
if self.client_id in str(client_result): registered = False
for client in client_result:
if (client.attrib.get('machineIdentifier') ==
self.client_id):
registered = True
if registered:
self.__printDebug("Client registration successful",1) self.__printDebug("Client registration successful",1)
self.__printDebug("Client data is: %s" % client_result, 3) self.__printDebug("Client data is: %s" % client_result, 3)
return True return True
@ -208,7 +218,6 @@ class plexgdm:
if "200 OK" in response.get('data'): if "200 OK" in response.get('data'):
for each in response.get('data').split('\r\n'): for each in response.get('data').split('\r\n'):
update['discovery'] = "auto" update['discovery'] = "auto"
update['owned']='1' update['owned']='1'
update['master']= 1 update['master']= 1
@ -230,6 +239,12 @@ class plexgdm:
elif "Server-Class:" in each: elif "Server-Class:" in each:
update['class'] = each.split(':')[1].strip() update['class'] = each.split(':')[1].strip()
# Quickly test if we need https
if PMSHttpsEnabled(
'%s:%s' % (update['server'], update['port'])):
update['protocol'] = 'https'
else:
update['protocol'] = 'http'
discovered_servers.append(update) discovered_servers.append(update)
self.server_list = discovered_servers self.server_list = discovered_servers
@ -239,7 +254,7 @@ class plexgdm:
else: else:
self.__printDebug("Number of servers Discovered: %s" % len(self.server_list),1) self.__printDebug("Number of servers Discovered: %s" % len(self.server_list),1)
for items in self.server_list: for items in self.server_list:
self.__printDebug("Server Discovered: %s" % items['serverName'] ,2) self.__printDebug("Server Discovered: %s" % items, 2)
def setInterval(self, interval): def setInterval(self, interval):