|  | @@ -40,6 +40,7 @@ class __PlayServer__(object):
 | 
	
		
			
				|  |  |          self._started = False
 | 
	
		
			
				|  |  |          self._last_progress = None
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        self._running_since = 0
 | 
	
		
			
				|  |  |          self._times = {}
 | 
	
		
			
				|  |  |          self._player = xbmc.Player()
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -89,6 +90,9 @@ class __PlayServer__(object):
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              request = __client_socket__.recv(1024)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +            if not request:
 | 
	
		
			
				|  |  | +                return False
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |              matches = re.search(r"^([^\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 +102,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")
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                        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 +128,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 +150,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 +159,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 +211,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 +263,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 +271,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 +281,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 +299,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 +320,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 +329,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))
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                self.__track__(diff > 10.0 or aborted)
 | 
	
		
			
				|  |  | +                aborted = monitor.abortRequested() > 0 or not self._running
 | 
	
		
			
				|  |  | +                output("[SERVER-" + str(self._port) + "] Idle abort: %s / file: %s" % (aborted, current_file))
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                if diff > 10.0 or aborted:
 | 
	
		
			
				|  |  | +                self.__track__(aborted)
 | 
	
		
			
				|  |  | +                if aborted:
 | 
	
		
			
				|  |  |                      break
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              return True
 | 
	
	
		
			
				|  | @@ -314,6 +348,23 @@ 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
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            #ifdef DEBUG
 | 
	
		
			
				|  |  | +            if server:
 | 
	
		
			
				|  |  | +                PLUGIN.notify("Playserver %s closed" % self._port)
 | 
	
		
			
				|  |  | +            #endif
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |              try:
 | 
	
		
			
				|  |  |                  if server:
 | 
	
		
			
				|  |  |                      server.close()
 | 
	
	
		
			
				|  | @@ -321,7 +372,7 @@ class __PlayServer__(object):
 | 
	
		
			
				|  |  |                  pass
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              monitor = None
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +            self.__save__(0, 0)
 | 
	
		
			
				|  |  |              self.__cleanup__()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @property
 |