Improve sync resiliance and GDM discovery
Improve sync resiliance to bad connections (e.g. behind a firewall)
This commit is contained in:
parent
e5e6f2208e
commit
e635f43845
4 changed files with 67 additions and 17 deletions
|
@ -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) \
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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):
|
||||||
|
|
Loading…
Reference in a new issue