|
@@ -39,7 +39,8 @@ class __PlayServer__(object):
|
|
|
self._episode_id = 0
|
|
|
self._started = False
|
|
|
self._last_progress = None
|
|
|
-
|
|
|
+ self._exit_requested = False
|
|
|
+ self._running_since = 0
|
|
|
self._times = {}
|
|
|
self._player = xbmc.Player()
|
|
|
|
|
@@ -55,7 +56,7 @@ class __PlayServer__(object):
|
|
|
self.__play_progress__(__episode_id__)
|
|
|
|
|
|
def __play_progress__(self, __episode_id__):
|
|
|
- if not __episode_id__:
|
|
|
+ if not __episode_id__ or not (__episode_id__ in self._times):
|
|
|
return
|
|
|
|
|
|
current = self._times[__episode_id__]
|
|
@@ -67,7 +68,8 @@ class __PlayServer__(object):
|
|
|
|
|
|
def __play_end__(self, __episode_id__):
|
|
|
self._started = False
|
|
|
- if not __episode_id__:
|
|
|
+
|
|
|
+ if not __episode_id__ or not (__episode_id__ in self._times):
|
|
|
return
|
|
|
|
|
|
current = self._times[__episode_id__]
|
|
@@ -89,7 +91,10 @@ class __PlayServer__(object):
|
|
|
|
|
|
request = __client_socket__.recv(1024)
|
|
|
|
|
|
- matches = re.search(r"^([^\s]+) /([^/]+)(?:/([^/]+))?/ HTTP", request, re.IGNORECASE | re.MULTILINE)
|
|
|
+ if not request:
|
|
|
+ return False
|
|
|
+
|
|
|
+ matches = re.search(r"^([^\s]+) /([^/]+)(?:/([^/]+))?/[^\s]* HTTP", request, re.IGNORECASE | re.MULTILINE)
|
|
|
if matches:
|
|
|
output("[SERVER-" + str(self._port) + "] Request: %s" % str([matches.group(i + 1) for i in xrange(len(matches.groups()))]))
|
|
|
|
|
@@ -98,14 +103,19 @@ class __PlayServer__(object):
|
|
|
|
|
|
if method == "HEAD":
|
|
|
if command == "play":
|
|
|
- __client_socket__.send('HTTP/1.1 200 OK\r\nContent-Type: application/octet-stream\r\nConnection: close\r\n\r\n')
|
|
|
+ __client_socket__.send("HTTP/1.1 200 OK\r\nContent-Type: application/octet-stream\r\nConnection: close\r\n\r\n")
|
|
|
|
|
|
else:
|
|
|
if command == "exit":
|
|
|
- pass
|
|
|
+ __client_socket__.send("HTTP/1.1 200 OK\r\nContent-Length: 2\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\nOK")
|
|
|
+ self._exit_requested = True
|
|
|
+ output("[SERVER-" + str(self._port) + "] Playserver will be closed")
|
|
|
+ self._running = False
|
|
|
+ return True
|
|
|
|
|
|
elif command == "play":
|
|
|
read_settings()
|
|
|
+ check_settings()
|
|
|
|
|
|
episode_id = matches.group(3)
|
|
|
|
|
@@ -119,11 +129,12 @@ class __PlayServer__(object):
|
|
|
raise Exception("Got no episode url")
|
|
|
|
|
|
self._episode_id = episode_id
|
|
|
- __client_socket__.send('HTTP/1.1 301 Moved Permanently\r\nLocation: %s\r\nConnection: close\r\n\r\n' % episode_url)
|
|
|
+ __client_socket__.send("HTTP/1.1 301 Moved Permanently\r\nLocation: %s\r\nConnection: close\r\n\r\n" % episode_url)
|
|
|
|
|
|
except Exception as e:
|
|
|
- output("[SERVER-" + str(self._port) + "] Client Error: %s" % traceback.format_exc())
|
|
|
- __client_socket__.send('HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n')
|
|
|
+ self._running = False
|
|
|
+ output("[SERVER-" + str(self._port) + "] Client Play Error: %s" % traceback.format_exc())
|
|
|
+ __client_socket__.send("HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n")
|
|
|
|
|
|
PLUGIN.notify("Fehler beim Abspielen!")
|
|
|
|
|
@@ -140,7 +151,8 @@ class __PlayServer__(object):
|
|
|
|
|
|
return True
|
|
|
|
|
|
- except Exception as e:
|
|
|
+ except:
|
|
|
+ self._running = False
|
|
|
output("[SERVER-" + str(self._port) + "] Client Error: %s" % traceback.format_exc())
|
|
|
return False
|
|
|
|
|
@@ -148,10 +160,6 @@ class __PlayServer__(object):
|
|
|
__client_socket__.close()
|
|
|
|
|
|
def __cleanup__(self):
|
|
|
- #ifdef DEBUG
|
|
|
- PLUGIN.notify("Server %s closed" % self._port)
|
|
|
- #endif
|
|
|
-
|
|
|
self._thread = None
|
|
|
self._running = False
|
|
|
self._port = None
|
|
@@ -204,9 +212,51 @@ class __PlayServer__(object):
|
|
|
else:
|
|
|
do_end()
|
|
|
|
|
|
+ @staticmethod
|
|
|
+ def __save__(port, created):
|
|
|
+ server_storage = get_storage("server")
|
|
|
+ server_storage["created"] = created
|
|
|
+ server_storage["port"] = port
|
|
|
+ server_storage.sync()
|
|
|
+
|
|
|
def __callback__(self):
|
|
|
server = None
|
|
|
monitor = None
|
|
|
+
|
|
|
+ port = None
|
|
|
+
|
|
|
+ try:
|
|
|
+ server_storage = get_storage("server")
|
|
|
+ if not (server_storage is None or not ("port" in server_storage)):
|
|
|
+ created = int(server_storage["created"])
|
|
|
+ port = int(server_storage["port"])
|
|
|
+
|
|
|
+ if not port or time.time() - created > 60 * 60:
|
|
|
+ port = None
|
|
|
+ self.__save__(0, 0)
|
|
|
+
|
|
|
+ except:
|
|
|
+ pass
|
|
|
+
|
|
|
+ if port:
|
|
|
+ try:
|
|
|
+ # Try to reach current running Server
|
|
|
+ if socket.create_connection(("127.0.0.1", port), timeout=5):
|
|
|
+ self._port = port
|
|
|
+
|
|
|
+ output("[SERVER-" + str(self._port) + "] Playserver reached at %s" % port)
|
|
|
+
|
|
|
+ return True
|
|
|
+
|
|
|
+ raise Exception("")
|
|
|
+
|
|
|
+ except:
|
|
|
+ port = None
|
|
|
+ output("[SERVER-" + str(self._port) + "] Playserver not reachable")
|
|
|
+
|
|
|
+ output("[SERVER-" + str(self._port) + "] Need to create Playserver")
|
|
|
+
|
|
|
+ last_file = None
|
|
|
try:
|
|
|
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
|
try:
|
|
@@ -214,18 +264,6 @@ class __PlayServer__(object):
|
|
|
except Exception as e:
|
|
|
output("[SERVER-" + str(self._port) + "] Startup Error: %s" % traceback.format_exc())
|
|
|
|
|
|
- """
|
|
|
- try:
|
|
|
- # Try to reset current running Server
|
|
|
- client = socket.create_connection(("127.0.0.1", 0))
|
|
|
- if client:
|
|
|
- client.send("GET /reset/ HTTP/1.1\r\n\r\n")
|
|
|
- client.close()
|
|
|
-
|
|
|
- except Exception as e:
|
|
|
- PLUGIN.notify("Video konnte nicht abgespielt werden!")
|
|
|
- """
|
|
|
-
|
|
|
return False
|
|
|
|
|
|
# Setup socket
|
|
@@ -234,13 +272,6 @@ class __PlayServer__(object):
|
|
|
except:
|
|
|
output("[SERVER-" + str(self._port) + "] Failed to set SO_REUSEADDR: %s" % traceback.format_exc())
|
|
|
|
|
|
- """
|
|
|
- try:
|
|
|
- server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
|
|
|
- except:
|
|
|
- output("[SERVER-"+str(self._port)+"] Failed to set SO_REUSEPORT: %s" % traceback.format_exc())
|
|
|
- """
|
|
|
-
|
|
|
try:
|
|
|
server.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
|
|
except:
|
|
@@ -251,9 +282,12 @@ class __PlayServer__(object):
|
|
|
addr = server.getsockname()
|
|
|
self._running = True
|
|
|
self._port = addr[1]
|
|
|
+
|
|
|
+ self.__save__(self._port, time.time())
|
|
|
+
|
|
|
output("[SERVER-" + str(self._port) + "] Started")
|
|
|
- last_action = time.time()
|
|
|
|
|
|
+ failed = 0
|
|
|
monitor = xbmc.Monitor()
|
|
|
while True:
|
|
|
client_sock = None
|
|
@@ -266,9 +300,16 @@ class __PlayServer__(object):
|
|
|
pass
|
|
|
except Exception as e:
|
|
|
output("[SERVER-" + str(self._port) + "] Error: %s" % traceback.format_exc())
|
|
|
+ failed += 1
|
|
|
+ if failed > 10:
|
|
|
+ self.__save__(0, 0)
|
|
|
+ raise Exception("Too many errors")
|
|
|
+
|
|
|
xbmc.sleep(100)
|
|
|
continue
|
|
|
|
|
|
+ failed = 0
|
|
|
+
|
|
|
if client_sock:
|
|
|
output("[SERVER-" + str(self._port) + "] Got client! %s" % str(address))
|
|
|
|
|
@@ -280,7 +321,6 @@ class __PlayServer__(object):
|
|
|
client_handler.start()
|
|
|
|
|
|
output("[SERVER-" + str(self._port) + "] Client thread started!")
|
|
|
- last_action = time.time() + 5
|
|
|
|
|
|
except Exception as e:
|
|
|
output("[SERVER-" + str(self._port) + "] Error: %s" % traceback.format_exc())
|
|
@@ -290,17 +330,12 @@ class __PlayServer__(object):
|
|
|
is_playing = self._player.isPlayingVideo()
|
|
|
if is_playing:
|
|
|
current_file = self._player.getPlayingFile()
|
|
|
- if current_file and ("127.0.0.1:%s" % self._port in current_file):
|
|
|
- last_action = time.time()
|
|
|
-
|
|
|
- diff = time.time() - last_action
|
|
|
|
|
|
- aborted = monitor.abortRequested() > 0
|
|
|
- output("[SERVER-" + str(self._port) + "] Last action: %s - Abort: %s - %s" % (diff, aborted, current_file))
|
|
|
+ aborted = monitor.abortRequested() > 0 or not self._running or self._exit_requested
|
|
|
+ output("[SERVER-" + str(self._port) + "] Idle abort: %s / file: %s" % (aborted, current_file))
|
|
|
|
|
|
- self.__track__(diff > 10.0 or aborted)
|
|
|
-
|
|
|
- if diff > 10.0 or aborted:
|
|
|
+ self.__track__(aborted)
|
|
|
+ if aborted:
|
|
|
break
|
|
|
|
|
|
return True
|
|
@@ -314,6 +349,21 @@ class __PlayServer__(object):
|
|
|
if server:
|
|
|
output("[SERVER-" + str(self._port) + "] Closed")
|
|
|
|
|
|
+ is_playing = self._player.isPlayingVideo()
|
|
|
+ current_file = None
|
|
|
+ if is_playing:
|
|
|
+ current_file = self._player.getPlayingFile()
|
|
|
+ if current_file and "127.0.0.1:%s/play/" % self._port in current_file:
|
|
|
+ output("[SERVER-" + str(self._port) + "] Also stop Player")
|
|
|
+
|
|
|
+ xbmc.executebuiltin("PlayerControl(stop)")
|
|
|
+
|
|
|
+ else:
|
|
|
+ current_file = None
|
|
|
+
|
|
|
+ if self._exit_requested or DEBUG:
|
|
|
+ PLUGIN.notify("Playserver wurde beendet")
|
|
|
+
|
|
|
try:
|
|
|
if server:
|
|
|
server.close()
|
|
@@ -321,7 +371,7 @@ class __PlayServer__(object):
|
|
|
pass
|
|
|
|
|
|
monitor = None
|
|
|
-
|
|
|
+ self.__save__(0, 0)
|
|
|
self.__cleanup__()
|
|
|
|
|
|
@property
|