mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2024-12-26 02:36:10 +00:00
Add webservice for playback prep
This commit is contained in:
parent
257a2e72c9
commit
5db5372db5
2 changed files with 182 additions and 0 deletions
|
@ -18,6 +18,7 @@ from client import get_device_id
|
||||||
from objects import Actions, PlaylistWorker, on_play, on_update, special_listener
|
from objects import Actions, PlaylistWorker, on_play, on_update, special_listener
|
||||||
from helper import _, settings, window, dialog, event, api, JSONRPC
|
from helper import _, settings, window, dialog, event, api, JSONRPC
|
||||||
from emby import Emby
|
from emby import Emby
|
||||||
|
from webservice import WebService
|
||||||
|
|
||||||
#################################################################################################
|
#################################################################################################
|
||||||
|
|
||||||
|
@ -37,6 +38,8 @@ class Monitor(xbmc.Monitor):
|
||||||
self.device_id = get_device_id()
|
self.device_id = get_device_id()
|
||||||
self.listener = Listener(self)
|
self.listener = Listener(self)
|
||||||
self.listener.start()
|
self.listener.start()
|
||||||
|
self.webservice = WebService()
|
||||||
|
self.webservice.start()
|
||||||
xbmc.Monitor.__init__(self)
|
xbmc.Monitor.__init__(self)
|
||||||
|
|
||||||
def onScanStarted(self, library):
|
def onScanStarted(self, library):
|
||||||
|
|
179
resources/lib/webservice.py
Normal file
179
resources/lib/webservice.py
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
#################################################################################################
|
||||||
|
|
||||||
|
import SimpleHTTPServer
|
||||||
|
import BaseHTTPServer
|
||||||
|
import logging
|
||||||
|
import httplib
|
||||||
|
import threading
|
||||||
|
import urlparse
|
||||||
|
import urllib
|
||||||
|
|
||||||
|
import xbmc
|
||||||
|
import xbmcvfs
|
||||||
|
|
||||||
|
#################################################################################################
|
||||||
|
|
||||||
|
PORT = 57578
|
||||||
|
LOG = logging.getLogger("EMBY."+__name__)
|
||||||
|
|
||||||
|
#################################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
class WebService(threading.Thread):
|
||||||
|
|
||||||
|
''' Run a webservice to trigger playback.
|
||||||
|
Inspired from script.skin.helper.service by marcelveldt.
|
||||||
|
'''
|
||||||
|
stop_thread = False
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
threading.Thread.__init__(self)
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
|
||||||
|
''' Called when the thread needs to stop
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
conn = httplib.HTTPConnection("127.0.0.1:%d" % PORT)
|
||||||
|
conn.request("QUIT", "/")
|
||||||
|
conn.getresponse()
|
||||||
|
self.stop_thread = True
|
||||||
|
except Exception as error:
|
||||||
|
LOG.exception(error)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
|
||||||
|
''' Called to start the webservice.
|
||||||
|
'''
|
||||||
|
LOG.info("--->[ webservice/%s ]", PORT)
|
||||||
|
|
||||||
|
try:
|
||||||
|
server = StoppableHttpServer(('127.0.0.1', PORT), StoppableHttpRequestHandler)
|
||||||
|
server.serve_forever()
|
||||||
|
except Exception as error:
|
||||||
|
|
||||||
|
if '10053' not in error: # ignore host diconnected errors
|
||||||
|
LOG.exception(error)
|
||||||
|
|
||||||
|
LOG.info("---<[ webservice ]")
|
||||||
|
|
||||||
|
|
||||||
|
class Request(object):
|
||||||
|
|
||||||
|
''' Attributes from urlsplit that this class also sets
|
||||||
|
'''
|
||||||
|
uri_attrs = ('scheme', 'netloc', 'path', 'query', 'fragment')
|
||||||
|
|
||||||
|
def __init__(self, uri, headers, rfile=None):
|
||||||
|
|
||||||
|
self.uri = uri
|
||||||
|
self.headers = headers
|
||||||
|
parsed = urlparse.urlsplit(uri)
|
||||||
|
|
||||||
|
for i, attr in enumerate(self.uri_attrs):
|
||||||
|
setattr(self, attr, parsed[i])
|
||||||
|
|
||||||
|
try:
|
||||||
|
body_len = int(self.headers.get('Content-length', 0))
|
||||||
|
except ValueError:
|
||||||
|
body_len = 0
|
||||||
|
|
||||||
|
self.body = rfile.read(body_len) if body_len and rfile else None
|
||||||
|
|
||||||
|
|
||||||
|
class StoppableHttpServer(BaseHTTPServer.HTTPServer):
|
||||||
|
|
||||||
|
''' Http server that reacts to self.stop flag.
|
||||||
|
'''
|
||||||
|
def serve_forever(self):
|
||||||
|
|
||||||
|
''' Handle one request at a time until stopped.
|
||||||
|
'''
|
||||||
|
self.stop = False
|
||||||
|
|
||||||
|
while not self.stop:
|
||||||
|
|
||||||
|
self.handle_request()
|
||||||
|
xbmc.sleep(100)
|
||||||
|
|
||||||
|
|
||||||
|
class StoppableHttpRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
|
||||||
|
|
||||||
|
''' http request handler with QUIT stopping the server
|
||||||
|
'''
|
||||||
|
raw_requestline = ""
|
||||||
|
|
||||||
|
def __init__(self, request, client_address, server):
|
||||||
|
try:
|
||||||
|
SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self, request, client_address, server)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def do_QUIT(self):
|
||||||
|
|
||||||
|
''' send 200 OK response, and set server.stop to True
|
||||||
|
'''
|
||||||
|
self.send_response(200)
|
||||||
|
self.end_headers()
|
||||||
|
self.server.stop = True
|
||||||
|
|
||||||
|
def parse_request(self):
|
||||||
|
|
||||||
|
''' Modify here to workaround unencoded requests.
|
||||||
|
'''
|
||||||
|
retval = SimpleHTTPServer.SimpleHTTPRequestHandler.parse_request(self)
|
||||||
|
self.request = Request(self.path, self.headers, self.rfile)
|
||||||
|
|
||||||
|
return retval
|
||||||
|
|
||||||
|
def do_HEAD(self):
|
||||||
|
|
||||||
|
''' Called on HEAD requests
|
||||||
|
'''
|
||||||
|
self.handle_request(True)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def get_params(self):
|
||||||
|
|
||||||
|
''' Get the params
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
params = dict(urlparse.parse_qsl(self.path[1:]))
|
||||||
|
except Exception:
|
||||||
|
params = {}
|
||||||
|
|
||||||
|
return params
|
||||||
|
|
||||||
|
def handle_request(self, headers_only=False):
|
||||||
|
|
||||||
|
''' Send headers and reponse
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
params = self.get_params()
|
||||||
|
LOG.info("Webservice called with params: %s", params)
|
||||||
|
|
||||||
|
path = ("plugin://plugin.video.emby?mode=play&id=%s&dbid=%s&filename=%s"
|
||||||
|
% (params.get('Id'), params.get('KodiId'), params.get('Name')))
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header('Content-type', 'text/html')
|
||||||
|
self.send_header('Content-Length', len(path))
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(path.encode('utf-8'))
|
||||||
|
|
||||||
|
except Exception as error:
|
||||||
|
|
||||||
|
LOG.exception(error)
|
||||||
|
self.send_error(500, 'Exception occurred: %s' % error)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def do_GET(self):
|
||||||
|
|
||||||
|
''' Called on GET requests
|
||||||
|
'''
|
||||||
|
self.handle_request()
|
||||||
|
|
||||||
|
return
|
Loading…
Reference in a new issue