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
from urllib import urlencode, quote_plus
from PlexFunctions import PlexToKodiTimefactor
from PlexFunctions import PlexToKodiTimefactor, PMSHttpsEnabled
try:
import xml.etree.cElementTree as etree
@ -630,6 +630,12 @@ class PlexAPI():
self.getPMSListFromMyPlex(ATV_udid, authtoken)
# all servers - update enableGzip
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
# on setting
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?!?
}
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
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.out_queue = out_queue
self.lock = lock
self.processlock = processlock
Thread.__init__(self)
def run(self):
@ -51,8 +52,10 @@ class ThreadedGetMetadata(Thread):
queue = self.queue
out_queue = self.out_queue
lock = self.lock
processlock = self.processlock
threadStopped = self.threadStopped
global getMetadataCount
global processMetadataCount
while threadStopped() is False:
# grabs Plex item from queue
try:
@ -66,9 +69,13 @@ class ThreadedGetMetadata(Thread):
if plexXML is None:
# Did not receive a valid XML - skip that item for now
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:
getMetadataCount += 1
with processlock:
processMetadataCount += 1
queue.task_done()
continue
@ -119,20 +126,20 @@ class ThreadedProcessMetadata(Thread):
except Queue.Empty:
xbmc.sleep(100)
continue
# Do the work; lock to be sure we've only got 1 Thread
# Do the work
plexitem = updateItem['XML']
method = updateItem['method']
viewName = updateItem['viewName']
viewId = updateItem['viewId']
title = updateItem['title']
itemSubFkt = getattr(item, method)
# Get the one child entry in the xml and process
for child in plexitem:
itemSubFkt(child,
viewtag=viewName,
viewid=viewId)
# Keep track of where we are at
with lock:
# Get the one child entry in the xml and process
for child in plexitem:
itemSubFkt(child,
viewtag=viewName,
viewid=viewId)
# Keep track of where we are at
processMetadataCount += 1
processingViewName = title
# signals to queue job is done
@ -728,7 +735,8 @@ class LibrarySync(Thread):
for i in range(min(self.syncThreadNumber, itemNumber)):
thread = ThreadedGetMetadata(getMetadataQueue,
processMetadataQueue,
getMetadataLock)
getMetadataLock,
processMetadataLock)
thread.setDaemon(True)
thread.start()
threads.append(thread)

View file

@ -31,7 +31,10 @@ import re
import threading
import time
import urllib2
import downloadutils
from PlexFunctions import PMSHttpsEnabled
class plexgdm:
@ -56,6 +59,7 @@ class plexgdm:
self.discovery_complete = False
self.client_registered = False
self.debug = debug
self.download = downloadutils.DownloadUtils().downloadUrl
def __printDebug(self, message, level=1):
if self.debug:
@ -139,13 +143,19 @@ class plexgdm:
try:
media_server=self.server_list[0]['server']
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)
client_result = downloadutils.DownloadUtils().downloadUrl(
'http://%s:%s/clients' % (media_server, media_port))
client_result = self.download(
'%s://%s:%s/clients' % (scheme, media_server, media_port))
# f = urllib2.urlopen('http://%s:%s/clients' % (media_server, media_port))
# 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 data is: %s" % client_result, 3)
return True
@ -208,7 +218,6 @@ class plexgdm:
if "200 OK" in response.get('data'):
for each in response.get('data').split('\r\n'):
update['discovery'] = "auto"
update['owned']='1'
update['master']= 1
@ -230,7 +239,13 @@ class plexgdm:
elif "Server-Class:" in each:
update['class'] = each.split(':')[1].strip()
discovered_servers.append(update)
# 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)
self.server_list = discovered_servers
@ -239,7 +254,7 @@ class plexgdm:
else:
self.__printDebug("Number of servers Discovered: %s" % len(self.server_list),1)
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):