Merge branch 'feature/dev_plex' of git://github.com/fuzeman/CouchPotatoServer into fuzeman-feature/dev_plex

Conflicts:
	couchpotato/core/notifications/plex/main.py
This commit is contained in:
Ruud
2013-09-24 21:35:36 +02:00
2 changed files with 152 additions and 62 deletions
+7 -3
View File
@@ -17,10 +17,14 @@ config = [{
'type': 'enabler',
},
{
'name': 'host',
'name': 'media_server',
'default': 'localhost',
'description': 'Default should be on localhost',
'advanced': True,
'description': 'Media server hostname'
},
{
'name': 'clients',
'default': '',
'description': 'Comma separated list of client names\'s (computer names).'
},
{
'name': 'on_snatch',
+145 -59
View File
@@ -1,79 +1,179 @@
from datetime import datetime
import json
from couchpotato.core.event import addEvent
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.notifications.base import Notification
from urllib2 import URLError
from urlparse import urlparse
from xml.dom import minidom
import traceback
import requests
try:
import xml.etree.cElementTree as etree
except ImportError:
import xml.etree.ElementTree as etree
log = CPLog(__name__)
class Plex(Notification):
client_update_time = 5 * 60
def __init__(self):
super(Plex, self).__init__()
self.clients = {}
self.clients_updated = None
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 = {}
client_result = etree.fromstring(self.urlopen('http://%s:32400/clients' % self.conf('media_server')))
hosts = [x.strip().lower() for x in self.conf('clients').split(',')]
for server in client_result.findall('Server'):
if server.get('name').lower() in hosts:
hosts.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(hosts) > 0:
log.warning('unable to find some plex hosts: %s', ', '.join(hosts))
log.info('found hosts: %s', ', '.join(self.clients.keys()))
self.clients_updated = datetime.now()
def addToLibrary(self, message=None, group={}):
if self.isDisabled(): return
if not group: group = {}
log.info('Sending notification to Plex')
hosts = self.getHosts(port = 32400)
for host in hosts:
source_type = ['movie']
base_url = 'http://%s:32400/library/sections' % self.conf('media_server')
refresh_url = '%s/%%s/refresh' % base_url
source_type = ['movie']
base_url = '%s/library/sections' % host
refresh_url = '%s/%%s/refresh' % base_url
try:
sections_xml = self.urlopen(base_url)
xml_sections = minidom.parseString(sections_xml)
sections = xml_sections.getElementsByTagName('Directory')
try:
sections_xml = self.urlopen(base_url)
xml_sections = minidom.parseString(sections_xml)
sections = xml_sections.getElementsByTagName('Directory')
for s in sections:
if s.getAttribute('type') in source_type:
url = refresh_url % s.getAttribute('key')
x = self.urlopen(url)
for s in sections:
if s.getAttribute('type') in source_type:
url = refresh_url % s.getAttribute('key')
self.urlopen(url)
except:
log.error('Plex library update failed for %s, Media Server not running: %s', (host, traceback.format_exc(1)))
return False
except:
log.error('Plex library update failed for %s, Media Server not running: %s',
(self.conf('media_server'), traceback.format_exc(1)))
return False
return True
def notify(self, message = '', data = None, listener = None):
if not data: data = {}
def send_http(self, command, client):
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 = {}
try:
self.urlopen(url, headers = headers, show_error = False)
except URLError:
log.error("Couldn't sent command to Plex, probably just running Media Server")
return False
except:
log.error("Couldn't sent command to Plex: %s", traceback.format_exc())
self.urlopen(url, headers=headers, timeout=3, show_error=False)
except Exception, err:
log.error("Couldn't sent command to Plex: %s", err)
return False
log.info('Plex notification to %s successful.', host)
return True
def notify_http(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.send_http(data, client):
successful += 1
return successful == total
def send_json(self, method, params, client):
log.debug('send_json("%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 notify_json(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.send_json('GUI.ShowNotification', params, client):
successful += 1
return successful == total
def notify(self, message='', data={}, listener=None, force=False):
self.updateClients(force)
http_result = self.notify_http(message, data, listener)
json_result = self.notify_json(message, data, listener)
return http_result and json_result
def test(self, **kwargs):
test_type = self.testNotifyName()
@@ -81,27 +181,13 @@ class Plex(Notification):
log.info('Sending test to %s', test_type)
success = self.notify(
message = self.test_message,
data = {},
listener = 'test'
message=self.test_message,
data={},
listener='test',
force=True
)
success2 = self.addToLibrary()
return {
'success': success or success2
}
def getHosts(self, port = None):
raw_hosts = splitString(self.conf('host'))
hosts = []
for h in raw_hosts:
h = cleanHost(h)
p = urlparse(h)
h = h.rstrip('/')
if port and not p.port:
h += ':%s' % port
hosts.append(h)
return hosts