Merge branch 'refs/heads/fuzeman-feature/dev_plex' into develop

This commit is contained in:
Ruud committed 2013-09-24 22:37:46 +02:00
commit 2b0a70355a
2 files changed
+162 -56

No files matched your search

+7 -2
View File
@@ -18,9 +18,14 @@ config = [{
}, },
{ {
'name': 'host', 'name': 'host',
'label': 'Media Server',
'default': 'localhost', 'default': 'localhost',
'description': 'Default should be on localhost', 'description': 'Hostname/IP, default localhost'
'advanced': True, },
{
'name': 'clients',
'default': '',
'description': 'Comma separated list of client names\'s (computer names). Top right when you start Plex'
}, },
{ {
'name': 'on_snatch', 'name': 'on_snatch',
+155 -54
View File
@@ -1,79 +1,184 @@
from couchpotato.core.event import addEvent from couchpotato.core.event import addEvent
from couchpotato.core.helpers.encoding import tryUrlencode from couchpotato.core.helpers.encoding import tryUrlencode
from couchpotato.core.helpers.variable import cleanHost, splitString from couchpotato.core.helpers.variable import cleanHost
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
from couchpotato.core.notifications.base import Notification from couchpotato.core.notifications.base import Notification
from urllib2 import URLError from datetime import datetime
from urlparse import urlparse from urlparse import urlparse
from xml.dom import minidom from xml.dom import minidom
import json
import requests
import traceback import traceback
try:
import xml.etree.cElementTree as etree
except ImportError:
import xml.etree.ElementTree as etree
log = CPLog(__name__) log = CPLog(__name__)
class Plex(Notification): class Plex(Notification):
client_update_time = 5 * 60
http_time_between_calls = 0
def __init__(self): def __init__(self):
super(Plex, self).__init__() super(Plex, self).__init__()
self.clients = {}
self.clients_updated = None
addEvent('renamer.after', self.addToLibrary) addEvent('renamer.after', self.addToLibrary)
def addToLibrary(self, message = None, group = None): def updateClients(self, force = False):
if not self.conf('media_server'):
log.warning("Plex media server hostname is required")
return
since_update = ((datetime.now() - self.clients_updated).total_seconds())\
if self.clients_updated is not None else None
if force or self.clients_updated is None or since_update > self.client_update_time:
self.clients = {}
data = self.urlopen('%s/clients' % self.createHost(self.conf('media_server'), port = 32400))
client_result = etree.fromstring(data)
clients = [x.strip().lower() for x in self.conf('clients').split(',')]
for server in client_result.findall('Server'):
if server.get('name').lower() in clients:
clients.remove(server.get('name').lower())
protocol = server.get('protocol', 'xbmchttp')
if protocol in ['xbmcjson', 'xbmchttp']:
self.clients[server.get('name')] = {
'name': server.get('name'),
'address': server.get('address'),
'port': server.get('port'),
'protocol': protocol
}
if len(clients) > 0:
log.info2('Unable to find plex clients: %s', ', '.join(clients))
log.info2('Found hosts: %s', ', '.join(self.clients.keys()))
self.clients_updated = datetime.now()
def addToLibrary(self, message = None, group = {}):
if self.isDisabled(): return if self.isDisabled(): return
if not group: group = {}
log.info('Sending notification to Plex') log.info('Sending notification to Plex')
hosts = self.getHosts(port = 32400)
for host in hosts: source_type = ['movie']
base_url = '%s/library/sections' % self.createHost(self.conf('media_server'), port = 32400)
refresh_url = '%s/%%s/refresh' % base_url
source_type = ['movie'] try:
base_url = '%s/library/sections' % host sections_xml = self.urlopen(base_url)
refresh_url = '%s/%%s/refresh' % base_url xml_sections = minidom.parseString(sections_xml)
sections = xml_sections.getElementsByTagName('Directory')
try: for s in sections:
sections_xml = self.urlopen(base_url) if s.getAttribute('type') in source_type:
xml_sections = minidom.parseString(sections_xml) url = refresh_url % s.getAttribute('key')
sections = xml_sections.getElementsByTagName('Directory') x = self.urlopen(url)
for s in sections: except:
if s.getAttribute('type') in source_type: log.error('Plex library update failed for %s, Media Server not running: %s',
url = refresh_url % s.getAttribute('key') (self.conf('media_server'), traceback.format_exc(1)))
self.urlopen(url) return False
except:
log.error('Plex library update failed for %s, Media Server not running: %s', (host, traceback.format_exc(1)))
return False
return True return True
def notify(self, message = '', data = None, listener = None): def sendHTTP(self, command, client):
if not data: data = {} url = 'http://%s:%s/xbmcCmds/xbmcHttp/?%s' % (
client['address'],
client['port'],
tryUrlencode(command)
)
hosts = self.getHosts(port = 3000)
successful = 0
for host in hosts:
if self.send({'command': 'ExecBuiltIn', 'parameter': 'Notification(CouchPotato, %s)' % message}, host):
successful += 1
return successful == len(hosts)
def send(self, command, host):
url = '%s/xbmcCmds/xbmcHttp/?%s' % (host, tryUrlencode(command))
headers = {} headers = {}
try: try:
self.urlopen(url, headers = headers, show_error = False) self.urlopen(url, headers = headers, timeout = 3, show_error = False)
except URLError: except Exception, err:
log.error("Couldn't sent command to Plex, probably just running Media Server") log.error("Couldn't sent command to Plex: %s", err)
return False
except:
log.error("Couldn't sent command to Plex: %s", traceback.format_exc())
return False return False
log.info('Plex notification to %s successful.', host)
return True return True
def notifyHTTP(self, message = '', data = {}, listener = None):
total = 0
successful = 0
data = {
'command': 'ExecBuiltIn',
'parameter': 'Notification(CouchPotato, %s)' % message
}
for name, client in self.clients.items():
if client['protocol'] == 'xbmchttp':
total += 1
if self.sendHTTP(data, client):
successful += 1
return successful == total
def sendJSON(self, method, params, client):
log.debug('sendJSON("%s", %s, %s)', (method, params, client))
url = 'http://%s:%s/jsonrpc' % (
client['address'],
client['port']
)
headers = {
'Content-Type': 'application/json'
}
request = {
'id':1,
'jsonrpc': '2.0',
'method': method,
'params': params
}
try:
requests.post(url, headers = headers, timeout = 3, data = json.dumps(request))
except Exception, err:
log.error("Couldn't sent command to Plex: %s", err)
return False
return True
def notifyJSON(self, message = '', data = {}, listener = None):
total = 0
successful = 0
params = {
'title': 'CouchPotato',
'message': message
}
for name, client in self.clients.items():
if client['protocol'] == 'xbmcjson':
total += 1
if self.sendJSON('GUI.ShowNotification', params, client):
successful += 1
return successful == total
def notify(self, message = '', data = {}, listener = None, force = False):
self.updateClients(force)
http_result = self.notifyHTTP(message, data, listener)
json_result = self.notifyJSON(message, data, listener)
return http_result and json_result
def test(self, **kwargs): def test(self, **kwargs):
test_type = self.testNotifyName() test_type = self.testNotifyName()
@@ -83,7 +188,8 @@ class Plex(Notification):
success = self.notify( success = self.notify(
message = self.test_message, message = self.test_message,
data = {}, data = {},
listener = 'test' listener = 'test',
force = True
) )
success2 = self.addToLibrary() success2 = self.addToLibrary()
@@ -91,17 +197,12 @@ class Plex(Notification):
'success': success or success2 'success': success or success2
} }
def getHosts(self, port = None): def createHost(self, host, port = None):
raw_hosts = splitString(self.conf('host')) h = cleanHost(host)
hosts = [] p = urlparse(h)
h = h.rstrip('/')
if port and not p.port:
h += ':%s' % port
for h in raw_hosts: return h
h = cleanHost(h)
p = urlparse(h)
h = h.rstrip('/')
if port and not p.port:
h += ':%s' % port
hosts.append(h)
return hosts