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:
commit
3b1efb2c30
2 files changed
+152
-62
No files matched your search
Regular → Executable
+7
-3
@@ -17,10 +17,14 @@ config = [{
|
|||||||
'type': 'enabler',
|
'type': 'enabler',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'host',
|
'name': 'media_server',
|
||||||
'default': 'localhost',
|
'default': 'localhost',
|
||||||
'description': 'Default should be on localhost',
|
'description': 'Media server hostname'
|
||||||
'advanced': True,
|
},
|
||||||
|
{
|
||||||
|
'name': 'clients',
|
||||||
|
'default': '',
|
||||||
|
'description': 'Comma separated list of client names\'s (computer names).'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'on_snatch',
|
'name': 'on_snatch',
|
||||||
|
|||||||
Regular → Executable
+145
-59
@@ -1,79 +1,179 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
import json
|
||||||
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 urllib2 import URLError
|
||||||
from urlparse import urlparse
|
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
import traceback
|
import traceback
|
||||||
|
import requests
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
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 = {}
|
||||||
|
|
||||||
|
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 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 = 'http://%s:32400/library/sections' % self.conf('media_server')
|
||||||
|
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 send_http(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 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):
|
def test(self, **kwargs):
|
||||||
|
|
||||||
test_type = self.testNotifyName()
|
test_type = self.testNotifyName()
|
||||||
@@ -81,27 +181,13 @@ class Plex(Notification):
|
|||||||
log.info('Sending test to %s', test_type)
|
log.info('Sending test to %s', test_type)
|
||||||
|
|
||||||
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()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'success': success or success2
|
'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
|
|
||||||
Reference in new issue
Block a user