示例#1
0
def listen():
    # 1. create connection to redis
    redis = RedisClient()
    try:
        for msg in ssdp.listen():
            # 2. Write JSON to redis pubsub channel
            json_str = json.dumps(msg)
            pub_ret = redis.publish('upnp-tools:ssdp', json_str.encode())
    finally:
        redis.close()
示例#2
0
 def do_GET(self):
     # want to split path into path?params
     parts = urllib.parse.urlsplit(self.path)
     path = parts.path
     if path == '/':
         self.sendfile('index.html', 'text/html; charset=utf-8')
     elif path == '/main.js':
         self.sendfile('main.js', 'application/javascript; charset=utf-8')
     elif path == '/main.css':
         self.sendfile('main.css', 'text/css; charset=utf-8')
     elif path == '/api/discover':
         # switch to 1.1 to get the browser to believe the chunked transfer
         # encoding
         old_proto = self.protocol_version
         self.protocol_version = 'HTTP/1.1'
         try:
             self.send_response(HTTPStatus.OK)
             self.send_header('Content-Type', 'application/x-json-stream')
             self.send_header('Cache-Control', 'no-cache')
             self.send_header('Transfer-Encoding', 'chunked')
             self.end_headers()
             if self.headers['ST']:
                 st = self.headers['ST']
             else:
                 st = 'ssdp:all'
             for svc in ssdp.discover_stream(st):
                 # convert to json
                 chunk = (json.dumps(svc) + '\n').encode('utf-8')
                 self.write_chunk(chunk)
             # chunked encoding requires us to send an empty chunk at the
             # end
             self.write_chunk(b'')
         finally:
             self.protocol_version = old_proto
     elif path == '/api/description' or path == '/api/scpd':
         params = urllib.parse.parse_qs(parts.query)
         if 'location' not in params:
             self.respond_simple(
                 HTTPStatus.BAD_REQUEST,
                 'location query parameter is required but was missing',
             )
             return
         location = params['location'][0]
         print('location =', location)
         parts = urllib.parse.urlsplit(location)
         conn = http.client.HTTPConnection(parts.netloc)
         print('parts.path =', parts.path)
         rpath = self.path_and_query(location)
         print('rpath =', rpath)
         # Sky+ boxes reject our requests unless using this specific
         # User-Agent string
         conn.request(
             'GET',
             rpath,
             headers={
                 'User-Agent': 'SKY_skyplus',
                 'Accept-Language': 'en'
             },
         )
         try:
             f = conn.getresponse()
             self.send_response(HTTPStatus(f.status))
             self.send_header('Content-Type', f.getheader('Content-Type'))
             if f.getheader('Content-Length'):
                 self.send_header('Content-Length',
                                  f.getheader('Content-Length'))
             self.end_headers()
             shutil.copyfileobj(f, self.wfile)
         finally:
             conn.close()
     elif path == '/api/notifications':
         redis = RedisClient()
         try:
             self.protocol_version = 'HTTP/1.1'
             self.send_response(HTTPStatus.OK)
             self.send_header('Content-Type', 'text/event-stream')
             self.send_header('Cache-Control', 'no-cache')
             self.end_headers()
             for json_bytes in redis.subscribe('upnp-tools:ssdp'):
                 self.wfile.write(b'data: ' + json_bytes + b'\r\n\r\n')
         finally:
             redis.close()
     else:
         self.respond_simple(HTTPStatus.NOT_FOUND,
                             'Cannot find ' + self.path)